about summary refs log tree commit diff
path: root/app
diff options
context:
space:
mode:
Diffstat (limited to 'app')
-rw-r--r--app/javascript/mastodon/components/dropdown_menu.js8
-rw-r--r--app/javascript/mastodon/components/status_action_bar.js2
-rw-r--r--app/javascript/mastodon/features/status/components/action_bar.js2
-rw-r--r--app/javascript/mastodon/features/status/components/card.js36
-rw-r--r--app/javascript/mastodon/features/status/components/detailed_status.js2
-rw-r--r--app/javascript/mastodon/features/ui/components/image_loader.js4
-rw-r--r--app/javascript/mastodon/features/ui/components/media_modal.js2
-rw-r--r--app/javascript/mastodon/locales/ca.json28
-rw-r--r--app/javascript/mastodon/locales/zh-CN.json4
-rw-r--r--app/javascript/mastodon/reducers/contexts.js13
-rw-r--r--app/javascript/mastodon/reducers/statuses.js19
-rw-r--r--app/javascript/styles/mastodon/components.scss11
-rw-r--r--app/views/stream_entries/show.html.haml2
13 files changed, 77 insertions, 56 deletions
diff --git a/app/javascript/mastodon/components/dropdown_menu.js b/app/javascript/mastodon/components/dropdown_menu.js
index 3a3ebf487..43dc0d6e3 100644
--- a/app/javascript/mastodon/components/dropdown_menu.js
+++ b/app/javascript/mastodon/components/dropdown_menu.js
@@ -110,7 +110,7 @@ export default class Dropdown extends React.PureComponent {
     icon: PropTypes.string.isRequired,
     items: PropTypes.array.isRequired,
     size: PropTypes.number.isRequired,
-    ariaLabel: PropTypes.string,
+    title: PropTypes.string,
     disabled: PropTypes.bool,
     status: ImmutablePropTypes.map,
     isUserTouching: PropTypes.func,
@@ -120,7 +120,7 @@ export default class Dropdown extends React.PureComponent {
   };
 
   static defaultProps = {
-    ariaLabel: 'Menu',
+    title: 'Menu',
   };
 
   state = {
@@ -186,14 +186,14 @@ export default class Dropdown extends React.PureComponent {
   }
 
   render () {
-    const { icon, items, size, ariaLabel, disabled } = this.props;
+    const { icon, items, size, title, disabled } = this.props;
     const { expanded } = this.state;
 
     return (
       <div onKeyDown={this.handleKeyDown}>
         <IconButton
           icon={icon}
-          title={ariaLabel}
+          title={title}
           active={expanded}
           disabled={disabled}
           size={size}
diff --git a/app/javascript/mastodon/components/status_action_bar.js b/app/javascript/mastodon/components/status_action_bar.js
index 7021c198e..cd59c7845 100644
--- a/app/javascript/mastodon/components/status_action_bar.js
+++ b/app/javascript/mastodon/components/status_action_bar.js
@@ -179,7 +179,7 @@ export default class StatusActionBar extends ImmutablePureComponent {
         {shareButton}
 
         <div className='status__action-bar-dropdown'>
-          <DropdownMenuContainer disabled={anonymousAccess} status={status} items={menu} icon='ellipsis-h' size={18} direction='right' ariaLabel={intl.formatMessage(messages.more)} />
+          <DropdownMenuContainer disabled={anonymousAccess} status={status} items={menu} icon='ellipsis-h' size={18} direction='right' title={intl.formatMessage(messages.more)} />
         </div>
       </div>
     );
diff --git a/app/javascript/mastodon/features/status/components/action_bar.js b/app/javascript/mastodon/features/status/components/action_bar.js
index 7b65420d0..99834df6c 100644
--- a/app/javascript/mastodon/features/status/components/action_bar.js
+++ b/app/javascript/mastodon/features/status/components/action_bar.js
@@ -120,7 +120,7 @@ export default class ActionBar extends React.PureComponent {
         {shareButton}
 
         <div className='detailed-status__action-bar-dropdown'>
-          <DropdownMenuContainer size={18} icon='ellipsis-h' items={menu} direction='left' ariaLabel='More' />
+          <DropdownMenuContainer size={18} icon='ellipsis-h' items={menu} direction='left' title='More' />
         </div>
       </div>
     );
diff --git a/app/javascript/mastodon/features/status/components/card.js b/app/javascript/mastodon/features/status/components/card.js
index bb83374b9..680bf63ab 100644
--- a/app/javascript/mastodon/features/status/components/card.js
+++ b/app/javascript/mastodon/features/status/components/card.js
@@ -1,5 +1,6 @@
 import React from 'react';
 import PropTypes from 'prop-types';
+import Immutable from 'immutable';
 import ImmutablePropTypes from 'react-immutable-proptypes';
 import punycode from 'punycode';
 import classnames from 'classnames';
@@ -24,6 +25,7 @@ export default class Card extends React.PureComponent {
   static propTypes = {
     card: ImmutablePropTypes.map,
     maxDescription: PropTypes.number,
+    onOpenMedia: PropTypes.func.isRequired,
   };
 
   static defaultProps = {
@@ -34,6 +36,27 @@ export default class Card extends React.PureComponent {
     width: 0,
   };
 
+  handlePhotoClick = () => {
+    const { card, onOpenMedia } = this.props;
+
+    onOpenMedia(
+      Immutable.fromJS([
+        {
+          type: 'image',
+          url: card.get('url'),
+          description: card.get('title'),
+          meta: {
+            original: {
+              width: card.get('width'),
+              height: card.get('height'),
+            },
+          },
+        },
+      ]),
+      0
+    );
+  };
+
   renderLink () {
     const { card, maxDescription } = this.props;
 
@@ -73,9 +96,16 @@ export default class Card extends React.PureComponent {
     const { card } = this.props;
 
     return (
-      <a href={card.get('url')} className='status-card-photo' target='_blank' rel='noopener'>
-        <img src={card.get('url')} alt={card.get('title')} width={card.get('width')} height={card.get('height')} />
-      </a>
+      <img
+        className='status-card-photo'
+        onClick={this.handlePhotoClick}
+        role='button'
+        tabIndex='0'
+        src={card.get('url')}
+        alt={card.get('title')}
+        width={card.get('width')}
+        height={card.get('height')}
+      />
     );
   }
 
diff --git a/app/javascript/mastodon/features/status/components/detailed_status.js b/app/javascript/mastodon/features/status/components/detailed_status.js
index 81f71749b..abdb9a3f6 100644
--- a/app/javascript/mastodon/features/status/components/detailed_status.js
+++ b/app/javascript/mastodon/features/status/components/detailed_status.js
@@ -73,7 +73,7 @@ export default class DetailedStatus extends ImmutablePureComponent {
         );
       }
     } else if (status.get('spoiler_text').length === 0) {
-      media = <CardContainer statusId={status.get('id')} />;
+      media = <CardContainer onOpenMedia={this.props.onOpenMedia} statusId={status.get('id')} />;
     }
 
     if (status.get('application')) {
diff --git a/app/javascript/mastodon/features/ui/components/image_loader.js b/app/javascript/mastodon/features/ui/components/image_loader.js
index aad594380..e3e7197c5 100644
--- a/app/javascript/mastodon/features/ui/components/image_loader.js
+++ b/app/javascript/mastodon/features/ui/components/image_loader.js
@@ -7,7 +7,7 @@ export default class ImageLoader extends React.PureComponent {
   static propTypes = {
     alt: PropTypes.string,
     src: PropTypes.string.isRequired,
-    previewSrc: PropTypes.string.isRequired,
+    previewSrc: PropTypes.string,
     width: PropTypes.number,
     height: PropTypes.number,
   }
@@ -47,7 +47,7 @@ export default class ImageLoader extends React.PureComponent {
     this.removeEventListeners();
     this.setState({ loading: true, error: false });
     Promise.all([
-      this.loadPreviewCanvas(props),
+      props.previewSrc && this.loadPreviewCanvas(props),
       this.hasSize() && this.loadOriginalImage(props),
     ].filter(Boolean))
       .then(() => {
diff --git a/app/javascript/mastodon/features/ui/components/media_modal.js b/app/javascript/mastodon/features/ui/components/media_modal.js
index f41a83089..02591a51f 100644
--- a/app/javascript/mastodon/features/ui/components/media_modal.js
+++ b/app/javascript/mastodon/features/ui/components/media_modal.js
@@ -92,7 +92,7 @@ export default class MediaModal extends ImmutablePureComponent {
       const height = image.getIn(['meta', 'original', 'height']) || null;
 
       if (image.get('type') === 'image') {
-        return <ImageLoader previewSrc={image.get('preview_url')} src={image.get('url')} width={width} height={height} alt={image.get('description')} key={image.get('preview_url')} />;
+        return <ImageLoader previewSrc={image.get('preview_url')} src={image.get('url')} width={width} height={height} alt={image.get('description')} key={image.get('url')} />;
       } else if (image.get('type') === 'gifv') {
         return <ExtendedVideoPlayer src={image.get('url')} muted controls={false} width={width} height={height} key={image.get('preview_url')} alt={image.get('description')} />;
       }
diff --git a/app/javascript/mastodon/locales/ca.json b/app/javascript/mastodon/locales/ca.json
index d8c2cc3e5..7ffdbfe5a 100644
--- a/app/javascript/mastodon/locales/ca.json
+++ b/app/javascript/mastodon/locales/ca.json
@@ -9,18 +9,18 @@
   "account.follows_you": "et segueix",
   "account.media": "Media",
   "account.mention": "Esmentar @{name}",
-  "account.moved_to": "{name} has moved to:",
+  "account.moved_to": "{name} s'ha mogut a:",
   "account.mute": "Silenciar @{name}",
-  "account.mute_notifications": "Mute notifications from @{name}",
+  "account.mute_notifications": "Notificacions desactivades de @{name}",
   "account.posts": "Publicacions",
   "account.report": "Informe @{name}",
-  "account.requested": "Esperant aprovació",
+  "account.requested": "Esperant aprovació. Clic per a cancel·lar la petició de seguiment",
   "account.share": "Compartir el perfil de @{name}",
   "account.unblock": "Desbloquejar @{name}",
   "account.unblock_domain": "Mostra {domain}",
   "account.unfollow": "Deixar de seguir",
   "account.unmute": "Treure silenci de @{name}",
-  "account.unmute_notifications": "Unmute notifications from @{name}",
+  "account.unmute_notifications": "Activar notificacions de @{name}",
   "account.view_full_profile": "Veure el perfil complet",
   "boost_modal.combo": "Pots premer {combo} per saltar-te això el proper cop",
   "bundle_column_error.body": "S'ha produït un error en carregar aquest component.",
@@ -54,7 +54,7 @@
   "compose_form.publish_loud": "{publish}!",
   "compose_form.sensitive": "Marcar multimèdia com a sensible",
   "compose_form.spoiler": "Amagar text darrera l'advertència",
-  "compose_form.spoiler_placeholder": "Advertència de contingut",
+  "compose_form.spoiler_placeholder": "Escriu l'advertència aquí",
   "confirmation_modal.cancel": "Cancel·lar",
   "confirmations.block.confirm": "Bloquejar",
   "confirmations.block.message": "Estàs segur que vols bloquejar {name}?",
@@ -67,7 +67,7 @@
   "confirmations.unfollow.confirm": "Deixar de seguir",
   "confirmations.unfollow.message": "Estàs segur que vols deixar de seguir {name}?",
   "embed.instructions": "Incrusta aquest estat al lloc web copiant el codi a continuació.",
-  "embed.preview": "A continuació s'explica com:",
+  "embed.preview": "Aquí tenim quin aspecte tindrá:",
   "emoji_button.activity": "Activitat",
   "emoji_button.custom": "Personalitzat",
   "emoji_button.flags": "Flags",
@@ -99,7 +99,7 @@
   "home.column_settings.advanced": "Avançat",
   "home.column_settings.basic": "Bàsic",
   "home.column_settings.filter_regex": "Filtrar per expressió regular",
-  "home.column_settings.show_reblogs": "Mostrar 'boosts'",
+  "home.column_settings.show_reblogs": "Mostrar impulsos",
   "home.column_settings.show_replies": "Mostrar respostes",
   "home.settings": "Ajustos de columna",
   "lightbox.close": "Tancar",
@@ -108,7 +108,7 @@
   "loading_indicator.label": "Carregant...",
   "media_gallery.toggle_visible": "Alternar visibilitat",
   "missing_indicator.label": "No trobat",
-  "mute_modal.hide_notifications": "Hide notifications from this user?",
+  "mute_modal.hide_notifications": "Amagar notificacions d'aquest usuari?",
   "navigation_bar.blocks": "Usuaris bloquejats",
   "navigation_bar.community_timeline": "Línia de temps Local",
   "navigation_bar.edit_profile": "Editar perfil",
@@ -132,7 +132,7 @@
   "notifications.column_settings.mention": "Mencions:",
   "notifications.column_settings.push": "Push notificacions",
   "notifications.column_settings.push_meta": "Aquest dispositiu",
-  "notifications.column_settings.reblog": "Boosts:",
+  "notifications.column_settings.reblog": "Impulsos:",
   "notifications.column_settings.show": "Mostrar en la columna",
   "notifications.column_settings.sound": "Reproduïr so",
   "onboarding.done": "Fet",
@@ -164,11 +164,11 @@
   "privacy.public.short": "Públic",
   "privacy.unlisted.long": "No publicar en línies de temps públiques",
   "privacy.unlisted.short": "No llistat",
-  "relative_time.days": "fa {number} jorns",
+  "relative_time.days": "fa {number} dies",
   "relative_time.hours": "fa {number} hores",
   "relative_time.just_now": "ara",
-  "relative_time.minutes": "fa {number} minutes",
-  "relative_time.seconds": "fa {number} segondes",
+  "relative_time.minutes": "fa {number} minuts",
+  "relative_time.seconds": "fa {number} segons",
   "reply_indicator.cancel": "Cancel·lar",
   "report.placeholder": "Comentaris addicionals",
   "report.submit": "Enviar",
@@ -192,7 +192,7 @@
   "status.mute_conversation": "Silenciar conversació",
   "status.open": "Ampliar aquest estat",
   "status.pin": "Fixat en el perfil",
-  "status.reblog": "Boost",
+  "status.reblog": "Impuls",
   "status.reblogged_by": "{name} ha retootejat",
   "status.reply": "Respondre",
   "status.replyAll": "Respondre al tema",
@@ -209,7 +209,7 @@
   "tabs_bar.home": "Inici",
   "tabs_bar.local_timeline": "Local",
   "tabs_bar.notifications": "Notificacions",
-  "ui.beforeunload": "Your draft will be lost if you leave Mastodon.",
+  "ui.beforeunload": "El vostre esborrany es perdrà si sortiu de Mastodon.",
   "upload_area.title": "Arrossega i deixa anar per carregar",
   "upload_button.label": "Afegir multimèdia",
   "upload_form.description": "Descriure els problemes visuals",
diff --git a/app/javascript/mastodon/locales/zh-CN.json b/app/javascript/mastodon/locales/zh-CN.json
index a820b9790..1c2c97067 100644
--- a/app/javascript/mastodon/locales/zh-CN.json
+++ b/app/javascript/mastodon/locales/zh-CN.json
@@ -9,7 +9,7 @@
   "account.follows_you": "关注了你",
   "account.media": "媒体",
   "account.mention": "提及 @{name}",
-  "account.moved_to": "{name} has moved to:",
+  "account.moved_to": "{name} 已经迁移到:",
   "account.mute": "隐藏 @{name}",
   "account.mute_notifications": "隐藏来自 @{name} 的通知",
   "account.posts": "嘟文",
@@ -86,7 +86,7 @@
   "empty_column.hashtag": "这个话题标签下暂时没有内容。",
   "empty_column.home": "你还没有关注任何用户。快看看{public},向其他用户搭讪吧。",
   "empty_column.home.public_timeline": "公共时间轴",
-  "empty_column.list": "There is nothing in this list yet.",
+  "empty_column.list": "这个列表中暂时没有内容。",
   "empty_column.notifications": "你还没有收到过通知信息,快向其他用户搭讪吧。",
   "empty_column.public": "这里神马都没有!写一些公开的嘟文,或者关注其他实例的用户,这里就会有嘟文出现了哦!",
   "follow_request.authorize": "同意",
diff --git a/app/javascript/mastodon/reducers/contexts.js b/app/javascript/mastodon/reducers/contexts.js
index 64d584a01..fe8308d0c 100644
--- a/app/javascript/mastodon/reducers/contexts.js
+++ b/app/javascript/mastodon/reducers/contexts.js
@@ -1,3 +1,7 @@
+import {
+  ACCOUNT_BLOCK_SUCCESS,
+  ACCOUNT_MUTE_SUCCESS,
+} from '../actions/accounts';
 import { CONTEXT_FETCH_SUCCESS } from '../actions/statuses';
 import { TIMELINE_DELETE, TIMELINE_CONTEXT_UPDATE } from '../actions/timelines';
 import { Map as ImmutableMap, List as ImmutableList } from 'immutable';
@@ -31,6 +35,12 @@ const deleteFromContexts = (state, id) => {
   return state;
 };
 
+const filterContexts = (state, relationship) => {
+  return state.map(
+    statuses => statuses.filter(
+      status => status.get('account') !== relationship.id));
+};
+
 const updateContext = (state, status, references) => {
   return state.update('descendants', map => {
     references.forEach(parentId => {
@@ -49,6 +59,9 @@ const updateContext = (state, status, references) => {
 
 export default function contexts(state = initialState, action) {
   switch(action.type) {
+  case ACCOUNT_BLOCK_SUCCESS:
+  case ACCOUNT_MUTE_SUCCESS:
+    return filterContexts(state, action.relationship);
   case CONTEXT_FETCH_SUCCESS:
     return normalizeContext(state, action.id, action.ancestors, action.descendants);
   case TIMELINE_DELETE:
diff --git a/app/javascript/mastodon/reducers/statuses.js b/app/javascript/mastodon/reducers/statuses.js
index b1fb4c5da..5120b2b67 100644
--- a/app/javascript/mastodon/reducers/statuses.js
+++ b/app/javascript/mastodon/reducers/statuses.js
@@ -23,10 +23,6 @@ import {
   TIMELINE_EXPAND_SUCCESS,
 } from '../actions/timelines';
 import {
-  ACCOUNT_BLOCK_SUCCESS,
-  ACCOUNT_MUTE_SUCCESS,
-} from '../actions/accounts';
-import {
   NOTIFICATIONS_UPDATE,
   NOTIFICATIONS_REFRESH_SUCCESS,
   NOTIFICATIONS_EXPAND_SUCCESS,
@@ -88,18 +84,6 @@ const deleteStatus = (state, id, references) => {
   return state.delete(id);
 };
 
-const filterStatuses = (state, relationship) => {
-  state.forEach(status => {
-    if (status.get('account') !== relationship.id) {
-      return;
-    }
-
-    state = deleteStatus(state, status.get('id'), state.filter(item => item.get('reblog') === status.get('id')));
-  });
-
-  return state;
-};
-
 const initialState = ImmutableMap();
 
 export default function statuses(state = initialState, action) {
@@ -139,9 +123,6 @@ export default function statuses(state = initialState, action) {
     return normalizeStatuses(state, action.statuses);
   case TIMELINE_DELETE:
     return deleteStatus(state, action.id, action.references);
-  case ACCOUNT_BLOCK_SUCCESS:
-  case ACCOUNT_MUTE_SUCCESS:
-    return filterStatuses(state, action.relationship);
   default:
     return state;
   }
diff --git a/app/javascript/styles/mastodon/components.scss b/app/javascript/styles/mastodon/components.scss
index b70769e18..f4ad66271 100644
--- a/app/javascript/styles/mastodon/components.scss
+++ b/app/javascript/styles/mastodon/components.scss
@@ -2182,15 +2182,12 @@ button.icon-button.active i.fa-retweet {
 }
 
 .status-card-photo {
+  cursor: zoom-in;
   display: block;
   text-decoration: none;
-
-  img {
-    display: block;
-    width: 100%;
-    height: auto;
-    margin: 0;
-  }
+  width: 100%;
+  height: auto;
+  margin: 0;
 }
 
 .status-card-video {
diff --git a/app/views/stream_entries/show.html.haml b/app/views/stream_entries/show.html.haml
index 428069931..786a4c0a8 100644
--- a/app/views/stream_entries/show.html.haml
+++ b/app/views/stream_entries/show.html.haml
@@ -8,7 +8,7 @@
 
   = opengraph 'og:site_name', site_title
   = opengraph 'og:type', 'article'
-  = opengraph 'og:title', "#{@account.username} on #{site_hostname}"
+  = opengraph 'og:title', "#{@account.display_name} on #{site_hostname}"
   = opengraph 'og:url', account_stream_entry_url(@account, @stream_entry)
 
   = render 'stream_entries/og_description', activity: @stream_entry.activity