about summary refs log tree commit diff
path: root/app/javascript
diff options
context:
space:
mode:
Diffstat (limited to 'app/javascript')
-rw-r--r--app/javascript/mastodon/actions/alerts.js4
-rw-r--r--app/javascript/mastodon/actions/compose.js38
-rw-r--r--app/javascript/mastodon/components/intersection_observer_article.js2
-rw-r--r--app/javascript/mastodon/containers/compose_container.js3
-rw-r--r--app/javascript/mastodon/features/compose/components/upload_button.js2
-rw-r--r--app/javascript/mastodon/features/getting_started/index.js2
-rw-r--r--app/javascript/mastodon/features/introduction/index.js2
-rw-r--r--app/javascript/mastodon/features/public_timeline/index.js2
-rw-r--r--app/javascript/mastodon/features/ui/components/report_modal.js2
-rw-r--r--app/javascript/mastodon/features/ui/index.js2
-rw-r--r--app/javascript/mastodon/locales/defaultMessages.json19
-rw-r--r--app/javascript/mastodon/locales/en.json7
-rw-r--r--app/javascript/mastodon/locales/ja.json9
-rw-r--r--app/javascript/mastodon/locales/pl.json1
-rw-r--r--app/javascript/mastodon/utils/resize_image.js2
-rw-r--r--app/javascript/styles/mastodon/accounts.scss4
-rw-r--r--app/javascript/styles/mastodon/admin.scss7
-rw-r--r--app/javascript/styles/mastodon/components.scss2
-rw-r--r--app/javascript/styles/mastodon/widgets.scss7
19 files changed, 81 insertions, 36 deletions
diff --git a/app/javascript/mastodon/actions/alerts.js b/app/javascript/mastodon/actions/alerts.js
index 3f5d7ef46..50cd48a9e 100644
--- a/app/javascript/mastodon/actions/alerts.js
+++ b/app/javascript/mastodon/actions/alerts.js
@@ -22,7 +22,7 @@ export function clearAlert() {
   };
 };
 
-export function showAlert(title, message) {
+export function showAlert(title = messages.unexpectedTitle, message = messages.unexpectedMessage) {
   return {
     type: ALERT_SHOW,
     title,
@@ -44,6 +44,6 @@ export function showAlertForError(error) {
     return showAlert(title, message);
   } else {
     console.error(error);
-    return showAlert(messages.unexpectedTitle, messages.unexpectedMessage);
+    return showAlert();
   }
 }
diff --git a/app/javascript/mastodon/actions/compose.js b/app/javascript/mastodon/actions/compose.js
index a4352faab..0be2a5cd4 100644
--- a/app/javascript/mastodon/actions/compose.js
+++ b/app/javascript/mastodon/actions/compose.js
@@ -8,6 +8,8 @@ import resizeImage from '../utils/resize_image';
 import { importFetchedAccounts } from './importer';
 import { updateTimeline } from './timelines';
 import { showAlertForError } from './alerts';
+import { showAlert } from './alerts';
+import { defineMessages } from 'react-intl';
 
 let cancelFetchComposeSuggestionsAccounts;
 
@@ -49,6 +51,10 @@ export const COMPOSE_UPLOAD_CHANGE_REQUEST     = 'COMPOSE_UPLOAD_UPDATE_REQUEST'
 export const COMPOSE_UPLOAD_CHANGE_SUCCESS     = 'COMPOSE_UPLOAD_UPDATE_SUCCESS';
 export const COMPOSE_UPLOAD_CHANGE_FAIL        = 'COMPOSE_UPLOAD_UPDATE_FAIL';
 
+const messages = defineMessages({
+  uploadErrorLimit: { id: 'upload_error.limit', defaultMessage: 'File upload limit exceeded.' },
+});
+
 export function changeCompose(text) {
   return {
     type: COMPOSE_CHANGE,
@@ -184,20 +190,32 @@ export function submitComposeFail(error) {
 
 export function uploadCompose(files) {
   return function (dispatch, getState) {
-    if (getState().getIn(['compose', 'media_attachments']).size > 3) {
+    const uploadLimit = 4;
+    const media  = getState().getIn(['compose', 'media_attachments']);
+    const total = Array.from(files).reduce((a, v) => a + v.size, 0);
+    const progress = new Array(files.length).fill(0);
+
+    if (files.length + media.size > uploadLimit) {
+      dispatch(showAlert(undefined, messages.uploadErrorLimit));
       return;
     }
-
     dispatch(uploadComposeRequest());
 
-    resizeImage(files[0]).then(file => {
-      const data = new FormData();
-      data.append('file', file);
-
-      return api(getState).post('/api/v1/media', data, {
-        onUploadProgress: ({ loaded, total }) => dispatch(uploadComposeProgress(loaded, total)),
-      }).then(({ data }) => dispatch(uploadComposeSuccess(data)));
-    }).catch(error => dispatch(uploadComposeFail(error)));
+    for (const [i, f] of Array.from(files).entries()) {
+      if (media.size + i > 3) break;
+
+      resizeImage(f).then(file => {
+        const data = new FormData();
+        data.append('file', file);
+
+        return api(getState).post('/api/v1/media', data, {
+          onUploadProgress: function({ loaded }){
+            progress[i] = loaded;
+            dispatch(uploadComposeProgress(progress.reduce((a, v) => a + v, 0), total));
+          },
+        }).then(({ data }) => dispatch(uploadComposeSuccess(data)));
+      }).catch(error => dispatch(uploadComposeFail(error)));
+    };
   };
 };
 
diff --git a/app/javascript/mastodon/components/intersection_observer_article.js b/app/javascript/mastodon/components/intersection_observer_article.js
index de2203a4b..e453730ba 100644
--- a/app/javascript/mastodon/components/intersection_observer_article.js
+++ b/app/javascript/mastodon/components/intersection_observer_article.js
@@ -65,7 +65,7 @@ export default class IntersectionObserverArticle extends React.Component {
   }
 
   updateStateAfterIntersection = (prevState) => {
-    if (prevState.isIntersecting && !this.entry.isIntersecting) {
+    if (prevState.isIntersecting !== false && !this.entry.isIntersecting) {
       scheduleIdleTask(this.hideIfNotIntersecting);
     }
     return {
diff --git a/app/javascript/mastodon/containers/compose_container.js b/app/javascript/mastodon/containers/compose_container.js
index 5ee1d2f14..7bc7bbaa4 100644
--- a/app/javascript/mastodon/containers/compose_container.js
+++ b/app/javascript/mastodon/containers/compose_container.js
@@ -7,6 +7,7 @@ import { IntlProvider, addLocaleData } from 'react-intl';
 import { getLocale } from '../locales';
 import Compose from '../features/standalone/compose';
 import initialState from '../initial_state';
+import { fetchCustomEmojis } from '../actions/custom_emojis';
 
 const { localeData, messages } = getLocale();
 addLocaleData(localeData);
@@ -17,6 +18,8 @@ if (initialState) {
   store.dispatch(hydrateStore(initialState));
 }
 
+store.dispatch(fetchCustomEmojis());
+
 export default class TimelineContainer extends React.PureComponent {
 
   static propTypes = {
diff --git a/app/javascript/mastodon/features/compose/components/upload_button.js b/app/javascript/mastodon/features/compose/components/upload_button.js
index b6fe770ea..db55ad70b 100644
--- a/app/javascript/mastodon/features/compose/components/upload_button.js
+++ b/app/javascript/mastodon/features/compose/components/upload_button.js
@@ -63,7 +63,7 @@ class UploadButton extends ImmutablePureComponent {
             key={resetFileKey}
             ref={this.setRef}
             type='file'
-            multiple={false}
+            multiple
             accept={acceptContentTypes.toArray().join(',')}
             onChange={this.handleChange}
             disabled={disabled}
diff --git a/app/javascript/mastodon/features/getting_started/index.js b/app/javascript/mastodon/features/getting_started/index.js
index e277a73c7..e1f84de27 100644
--- a/app/javascript/mastodon/features/getting_started/index.js
+++ b/app/javascript/mastodon/features/getting_started/index.js
@@ -160,7 +160,7 @@ class GettingStarted extends ImmutablePureComponent {
               {invitesEnabled && <li><a href='/invites' target='_blank'><FormattedMessage id='getting_started.invite' defaultMessage='Invite people' /></a> · </li>}
               {multiColumn && <li><Link to='/keyboard-shortcuts'><FormattedMessage id='navigation_bar.keyboard_shortcuts' defaultMessage='Hotkeys' /></Link> · </li>}
               <li><a href='/auth/edit'><FormattedMessage id='getting_started.security' defaultMessage='Security' /></a> · </li>
-              <li><a href='/about/more' target='_blank'><FormattedMessage id='navigation_bar.info' defaultMessage='About this instance' /></a> · </li>
+              <li><a href='/about/more' target='_blank'><FormattedMessage id='navigation_bar.info' defaultMessage='About this server' /></a> · </li>
               <li><a href='https://joinmastodon.org/apps' target='_blank'><FormattedMessage id='navigation_bar.apps' defaultMessage='Mobile apps' /></a> · </li>
               <li><a href='/terms' target='_blank'><FormattedMessage id='getting_started.terms' defaultMessage='Terms of service' /></a> · </li>
               <li><a href='/settings/applications' target='_blank'><FormattedMessage id='getting_started.developers' defaultMessage='Developers' /></a> · </li>
diff --git a/app/javascript/mastodon/features/introduction/index.js b/app/javascript/mastodon/features/introduction/index.js
index e712b2f7d..754477bb9 100644
--- a/app/javascript/mastodon/features/introduction/index.js
+++ b/app/javascript/mastodon/features/introduction/index.js
@@ -89,7 +89,7 @@ const FrameInteractions = ({ onNext }) => (
     </div>
 
     <div className='introduction__action'>
-      <button className='button' onClick={onNext}><FormattedMessage id='introduction.interactions.action' defaultMessage='Finish tutorial!' /></button>
+      <button className='button' onClick={onNext}><FormattedMessage id='introduction.interactions.action' defaultMessage='Finish toot-orial!' /></button>
     </div>
   </div>
 );
diff --git a/app/javascript/mastodon/features/public_timeline/index.js b/app/javascript/mastodon/features/public_timeline/index.js
index d640033eb..2b7d9c56f 100644
--- a/app/javascript/mastodon/features/public_timeline/index.js
+++ b/app/javascript/mastodon/features/public_timeline/index.js
@@ -124,7 +124,7 @@ class PublicTimeline extends React.PureComponent {
           onLoadMore={this.handleLoadMore}
           trackScroll={!pinned}
           scrollKey={`public_timeline-${columnId}`}
-          emptyMessage={<FormattedMessage id='empty_column.public' defaultMessage='There is nothing here! Write something publicly, or manually follow users from other instances to fill it up' />}
+          emptyMessage={<FormattedMessage id='empty_column.public' defaultMessage='There is nothing here! Write something publicly, or manually follow users from other servers to fill it up' />}
           shouldUpdateScroll={shouldUpdateScroll}
         />
       </Column>
diff --git a/app/javascript/mastodon/features/ui/components/report_modal.js b/app/javascript/mastodon/features/ui/components/report_modal.js
index bc6b18664..2e41f784d 100644
--- a/app/javascript/mastodon/features/ui/components/report_modal.js
+++ b/app/javascript/mastodon/features/ui/components/report_modal.js
@@ -97,7 +97,7 @@ class ReportModal extends ImmutablePureComponent {
 
         <div className='report-modal__container'>
           <div className='report-modal__comment'>
-            <p><FormattedMessage id='report.hint' defaultMessage='The report will be sent to your instance moderators. You can provide an explanation of why you are reporting this account below:' /></p>
+            <p><FormattedMessage id='report.hint' defaultMessage='The report will be sent to your server moderators. You can provide an explanation of why you are reporting this account below:' /></p>
 
             <textarea
               className='setting-text light'
diff --git a/app/javascript/mastodon/features/ui/index.js b/app/javascript/mastodon/features/ui/index.js
index f01c2bf24..93e45678f 100644
--- a/app/javascript/mastodon/features/ui/index.js
+++ b/app/javascript/mastodon/features/ui/index.js
@@ -263,7 +263,7 @@ class UI extends React.PureComponent {
     this.setState({ draggingOver: false });
     this.dragTargets = [];
 
-    if (e.dataTransfer && e.dataTransfer.files.length === 1) {
+    if (e.dataTransfer && e.dataTransfer.files.length >= 1) {
       this.props.dispatch(uploadCompose(e.dataTransfer.files));
     }
   }
diff --git a/app/javascript/mastodon/locales/defaultMessages.json b/app/javascript/mastodon/locales/defaultMessages.json
index 60f481076..eb3a7bbde 100644
--- a/app/javascript/mastodon/locales/defaultMessages.json
+++ b/app/javascript/mastodon/locales/defaultMessages.json
@@ -15,6 +15,15 @@
   {
     "descriptors": [
       {
+        "defaultMessage": "File upload limit exceeded.",
+        "id": "upload_error.limit"
+      }
+    ],
+    "path": "app/javascript/mastodon/actions/compose.json"
+  },
+  {
+    "descriptors": [
+      {
         "defaultMessage": "{name} mentioned you",
         "id": "notification.mention"
       },
@@ -1275,7 +1284,7 @@
         "id": "getting_started.security"
       },
       {
-        "defaultMessage": "About this instance",
+        "defaultMessage": "About this server",
         "id": "navigation_bar.info"
       },
       {
@@ -1448,7 +1457,7 @@
         "id": "introduction.interactions.favourite.text"
       },
       {
-        "defaultMessage": "Finish tutorial!",
+        "defaultMessage": "Finish toot-orial!",
         "id": "introduction.interactions.action"
       }
     ],
@@ -1828,7 +1837,7 @@
         "id": "column.public"
       },
       {
-        "defaultMessage": "There is nothing here! Write something publicly, or manually follow users from other instances to fill it up",
+        "defaultMessage": "There is nothing here! Write something publicly, or manually follow users from other servers to fill it up",
         "id": "empty_column.public"
       }
     ],
@@ -2188,7 +2197,7 @@
         "id": "report.target"
       },
       {
-        "defaultMessage": "The report will be sent to your instance moderators. You can provide an explanation of why you are reporting this account below:",
+        "defaultMessage": "The report will be sent to your server moderators. You can provide an explanation of why you are reporting this account below:",
         "id": "report.hint"
       },
       {
@@ -2298,4 +2307,4 @@
     ],
     "path": "app/javascript/mastodon/features/video/index.json"
   }
-]
\ No newline at end of file
+]
diff --git a/app/javascript/mastodon/locales/en.json b/app/javascript/mastodon/locales/en.json
index 3bb157aeb..b079f256d 100644
--- a/app/javascript/mastodon/locales/en.json
+++ b/app/javascript/mastodon/locales/en.json
@@ -132,7 +132,7 @@
   "empty_column.lists": "You don't have any lists yet. When you create one, it will show up here.",
   "empty_column.mutes": "You haven't muted any users yet.",
   "empty_column.notifications": "You don't have any notifications yet. Interact with others to start the conversation.",
-  "empty_column.public": "There is nothing here! Write something publicly, or manually follow users from other instances to fill it up",
+  "empty_column.public": "There is nothing here! Write something publicly, or manually follow users from other servers to fill it up",
   "follow_request.authorize": "Authorize",
   "follow_request.reject": "Reject",
   "getting_started.developers": "Developers",
@@ -228,7 +228,7 @@
   "navigation_bar.favourites": "Favourites",
   "navigation_bar.filters": "Muted words",
   "navigation_bar.follow_requests": "Follow requests",
-  "navigation_bar.info": "About this instance",
+  "navigation_bar.info": "About this server",
   "navigation_bar.keyboard_shortcuts": "Hotkeys",
   "navigation_bar.lists": "Lists",
   "navigation_bar.misc": "Misc",
@@ -281,7 +281,7 @@
   "reply_indicator.cancel": "Cancel",
   "report.forward": "Forward to {target}",
   "report.forward_hint": "The account is from another server. Send an anonymized copy of the report there as well?",
-  "report.hint": "The report will be sent to your instance moderators. You can provide an explanation of why you are reporting this account below:",
+  "report.hint": "The report will be sent to your server moderators. You can provide an explanation of why you are reporting this account below:",
   "report.placeholder": "Additional comments",
   "report.submit": "Submit",
   "report.target": "Reporting {target}",
@@ -347,6 +347,7 @@
   "ui.beforeunload": "Your draft will be lost if you leave Mastodon.",
   "upload_area.title": "Drag & drop to upload",
   "upload_button.label": "Add media (JPEG, PNG, GIF, WebM, MP4, MOV)",
+  "upload_error.limit": "File upload limit exceeded.",
   "upload_form.description": "Describe for the visually impaired",
   "upload_form.focus": "Change preview",
   "upload_form.undo": "Delete",
diff --git a/app/javascript/mastodon/locales/ja.json b/app/javascript/mastodon/locales/ja.json
index e0cba7764..4bcc11d70 100644
--- a/app/javascript/mastodon/locales/ja.json
+++ b/app/javascript/mastodon/locales/ja.json
@@ -132,7 +132,7 @@
   "empty_column.lists": "まだリストがありません。リストを作るとここに表示されます。",
   "empty_column.mutes": "まだ誰もミュートしていません。",
   "empty_column.notifications": "まだ通知がありません。他の人とふれ合って会話を始めましょう。",
-  "empty_column.public": "ここにはまだ何もありません! 公開で何かを投稿したり、他のインスタンスのユーザーをフォローしたりしていっぱいにしましょう",
+  "empty_column.public": "ここにはまだ何もありません! 公開で何かを投稿したり、他のサーバーのユーザーをフォローしたりしていっぱいにしましょう",
   "follow_request.authorize": "許可",
   "follow_request.reject": "拒否",
   "getting_started.developers": "開発",
@@ -228,7 +228,7 @@
   "navigation_bar.favourites": "お気に入り",
   "navigation_bar.filters": "フィルター設定",
   "navigation_bar.follow_requests": "フォローリクエスト",
-  "navigation_bar.info": "このインスタンスについて",
+  "navigation_bar.info": "このサーバーについて",
   "navigation_bar.keyboard_shortcuts": "ホットキー",
   "navigation_bar.lists": "リスト",
   "navigation_bar.logout": "ログアウト",
@@ -280,8 +280,8 @@
   "relative_time.seconds": "{number}秒前",
   "reply_indicator.cancel": "キャンセル",
   "report.forward": "{target} に転送する",
-  "report.forward_hint": "このアカウントは別のインスタンスに所属しています。通報内容を匿名で転送しますか?",
-  "report.hint": "通報内容はあなたのインスタンスのモデレーターへ送信されます。通報理由を入力してください。:",
+  "report.forward_hint": "このアカウントは別のサーバーに所属しています。通報内容を匿名で転送しますか?",
+  "report.hint": "通報内容はあなたのサーバーのモデレーターへ送信されます。通報理由を入力してください。:",
   "report.placeholder": "追加コメント",
   "report.submit": "通報する",
   "report.target": "{target}さんを通報する",
@@ -347,6 +347,7 @@
   "ui.beforeunload": "Mastodonから離れると送信前の投稿は失われます。",
   "upload_area.title": "ドラッグ&ドロップでアップロード",
   "upload_button.label": "メディアを追加 (JPEG, PNG, GIF, WebM, MP4, MOV)",
+  "upload_error.limit": "アップロードできる上限を超えています。",
   "upload_form.description": "視覚障害者のための説明",
   "upload_form.focus": "焦点",
   "upload_form.undo": "削除",
diff --git a/app/javascript/mastodon/locales/pl.json b/app/javascript/mastodon/locales/pl.json
index 9f78c430f..e9e0c768d 100644
--- a/app/javascript/mastodon/locales/pl.json
+++ b/app/javascript/mastodon/locales/pl.json
@@ -347,6 +347,7 @@
   "ui.beforeunload": "Utracisz tworzony wpis, jeżeli opuścisz Mastodona.",
   "upload_area.title": "Przeciągnij i upuść aby wysłać",
   "upload_button.label": "Dodaj zawartość multimedialną (JPEG, PNG, GIF, WebM, MP4, MOV)",
+  "upload_error.limit": "Przekroczono limit plików do wysłania.",
   "upload_form.description": "Wprowadź opis dla niewidomych i niedowidzących",
   "upload_form.focus": "Dopasuj podgląd",
   "upload_form.undo": "Usuń",
diff --git a/app/javascript/mastodon/utils/resize_image.js b/app/javascript/mastodon/utils/resize_image.js
index d1608094f..bbdbc865e 100644
--- a/app/javascript/mastodon/utils/resize_image.js
+++ b/app/javascript/mastodon/utils/resize_image.js
@@ -31,7 +31,7 @@ const loadImage = inputFile => new Promise((resolve, reject) => {
 });
 
 const getOrientation = (img, type = 'image/png') => new Promise(resolve => {
-  if (type !== 'image/jpeg') {
+  if (!['image/jpeg', 'image/webp'].includes(type)) {
     resolve(1);
     return;
   }
diff --git a/app/javascript/styles/mastodon/accounts.scss b/app/javascript/styles/mastodon/accounts.scss
index 63a5c61b8..f4f458cf4 100644
--- a/app/javascript/styles/mastodon/accounts.scss
+++ b/app/javascript/styles/mastodon/accounts.scss
@@ -288,3 +288,7 @@
     border-bottom: 0;
   }
 }
+
+.directory__tag .trends__item__current {
+  width: auto;
+}
diff --git a/app/javascript/styles/mastodon/admin.scss b/app/javascript/styles/mastodon/admin.scss
index 4e969601b..4dbbaa1e8 100644
--- a/app/javascript/styles/mastodon/admin.scss
+++ b/app/javascript/styles/mastodon/admin.scss
@@ -153,10 +153,15 @@ $content-width: 840px;
       font-weight: 500;
     }
 
-    .directory__tag a {
+    .directory__tag > a,
+    .directory__tag > div {
       box-shadow: none;
     }
 
+    .directory__tag .table-action-link .fa {
+      color: inherit;
+    }
+
     .directory__tag h4 {
       font-size: 18px;
       font-weight: 700;
diff --git a/app/javascript/styles/mastodon/components.scss b/app/javascript/styles/mastodon/components.scss
index 8c1115e76..e29abf4f3 100644
--- a/app/javascript/styles/mastodon/components.scss
+++ b/app/javascript/styles/mastodon/components.scss
@@ -638,7 +638,6 @@
   font-weight: 400;
   overflow: hidden;
   text-overflow: ellipsis;
-  white-space: pre-wrap;
   padding-top: 2px;
   color: $primary-text-color;
 
@@ -662,6 +661,7 @@
 
   p {
     margin-bottom: 20px;
+    white-space: pre-wrap;
 
     &:last-child {
       margin-bottom: 0;
diff --git a/app/javascript/styles/mastodon/widgets.scss b/app/javascript/styles/mastodon/widgets.scss
index c97337e4e..1eaf30c5b 100644
--- a/app/javascript/styles/mastodon/widgets.scss
+++ b/app/javascript/styles/mastodon/widgets.scss
@@ -269,7 +269,8 @@
     box-sizing: border-box;
     margin-bottom: 10px;
 
-    a {
+    & > a,
+    & > div {
       display: flex;
       align-items: center;
       justify-content: space-between;
@@ -279,7 +280,9 @@
       text-decoration: none;
       color: inherit;
       box-shadow: 0 0 15px rgba($base-shadow-color, 0.2);
+    }
 
+    & > a {
       &:hover,
       &:active,
       &:focus {
@@ -287,7 +290,7 @@
       }
     }
 
-    &.active a {
+    &.active > a {
       background: $ui-highlight-color;
       cursor: default;
     }