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/flavours/glitch/actions/compose.js8
-rw-r--r--app/javascript/flavours/glitch/actions/timelines.js7
-rw-r--r--app/javascript/flavours/glitch/components/scrollable_list.js6
-rw-r--r--app/javascript/flavours/glitch/components/status_list.js2
-rw-r--r--app/javascript/flavours/glitch/features/account/components/header.js4
-rw-r--r--app/javascript/flavours/glitch/features/account_gallery/index.js19
-rw-r--r--app/javascript/flavours/glitch/features/composer/index.js16
-rw-r--r--app/javascript/flavours/glitch/reducers/notifications.js2
-rw-r--r--app/javascript/flavours/glitch/reducers/timelines.js6
-rw-r--r--app/javascript/flavours/glitch/styles/forms.scss1
-rw-r--r--app/javascript/mastodon/actions/compose.js6
-rw-r--r--app/javascript/mastodon/actions/timelines.js7
-rw-r--r--app/javascript/mastodon/components/scrollable_list.js11
-rw-r--r--app/javascript/mastodon/components/status_list.js2
-rw-r--r--app/javascript/mastodon/features/account/components/header.js2
-rw-r--r--app/javascript/mastodon/features/account_gallery/index.js19
-rw-r--r--app/javascript/mastodon/features/followers/index.js1
-rw-r--r--app/javascript/mastodon/features/following/index.js1
-rw-r--r--app/javascript/mastodon/locales/ar.json19
-rw-r--r--app/javascript/mastodon/locales/ast.json3
-rw-r--r--app/javascript/mastodon/locales/bg.json1
-rw-r--r--app/javascript/mastodon/locales/ca.json21
-rw-r--r--app/javascript/mastodon/locales/co.json19
-rw-r--r--app/javascript/mastodon/locales/cs.json27
-rw-r--r--app/javascript/mastodon/locales/cy.json1
-rw-r--r--app/javascript/mastodon/locales/da.json3
-rw-r--r--app/javascript/mastodon/locales/de.json25
-rw-r--r--app/javascript/mastodon/locales/defaultMessages.json4
-rw-r--r--app/javascript/mastodon/locales/el.json25
-rw-r--r--app/javascript/mastodon/locales/eo.json77
-rw-r--r--app/javascript/mastodon/locales/es.json1
-rw-r--r--app/javascript/mastodon/locales/eu.json21
-rw-r--r--app/javascript/mastodon/locales/fa.json1
-rw-r--r--app/javascript/mastodon/locales/fi.json1
-rw-r--r--app/javascript/mastodon/locales/fr.json19
-rw-r--r--app/javascript/mastodon/locales/gl.json23
-rw-r--r--app/javascript/mastodon/locales/he.json1
-rw-r--r--app/javascript/mastodon/locales/hr.json1
-rw-r--r--app/javascript/mastodon/locales/hu.json1
-rw-r--r--app/javascript/mastodon/locales/hy.json1
-rw-r--r--app/javascript/mastodon/locales/id.json1
-rw-r--r--app/javascript/mastodon/locales/io.json1
-rw-r--r--app/javascript/mastodon/locales/it.json19
-rw-r--r--app/javascript/mastodon/locales/ja.json3
-rw-r--r--app/javascript/mastodon/locales/ka.json1
-rw-r--r--app/javascript/mastodon/locales/ko.json1
-rw-r--r--app/javascript/mastodon/locales/ms.json1
-rw-r--r--app/javascript/mastodon/locales/nl.json21
-rw-r--r--app/javascript/mastodon/locales/no.json1
-rw-r--r--app/javascript/mastodon/locales/oc.json28
-rw-r--r--app/javascript/mastodon/locales/pt-BR.json23
-rw-r--r--app/javascript/mastodon/locales/pt.json1
-rw-r--r--app/javascript/mastodon/locales/ro.json1
-rw-r--r--app/javascript/mastodon/locales/ru.json1
-rw-r--r--app/javascript/mastodon/locales/sk.json41
-rw-r--r--app/javascript/mastodon/locales/sl.json1
-rw-r--r--app/javascript/mastodon/locales/sr-Latn.json1
-rw-r--r--app/javascript/mastodon/locales/sr.json1
-rw-r--r--app/javascript/mastodon/locales/sv.json1
-rw-r--r--app/javascript/mastodon/locales/ta.json1
-rw-r--r--app/javascript/mastodon/locales/te.json1
-rw-r--r--app/javascript/mastodon/locales/th.json1
-rw-r--r--app/javascript/mastodon/locales/tr.json1
-rw-r--r--app/javascript/mastodon/locales/uk.json1
-rw-r--r--app/javascript/mastodon/locales/zh-CN.json1
-rw-r--r--app/javascript/mastodon/locales/zh-HK.json1
-rw-r--r--app/javascript/mastodon/locales/zh-TW.json1
-rw-r--r--app/javascript/mastodon/reducers/timelines.js6
-rw-r--r--app/javascript/styles/mastodon/forms.scss1
69 files changed, 330 insertions, 248 deletions
diff --git a/app/javascript/flavours/glitch/actions/compose.js b/app/javascript/flavours/glitch/actions/compose.js
index 58f2b3786..d53d26924 100644
--- a/app/javascript/flavours/glitch/actions/compose.js
+++ b/app/javascript/flavours/glitch/actions/compose.js
@@ -116,7 +116,7 @@ export function directCompose(account, router) {
   };
 };
 
-export function submitCompose() {
+export function submitCompose(routerHistory) {
   return function (dispatch, getState) {
     let status = getState().getIn(['compose', 'text'], '');
     let media  = getState().getIn(['compose', 'media_attachments']);
@@ -158,6 +158,12 @@ export function submitCompose() {
         }
       };
 
+      if (routerHistory && routerHistory.location.pathname === '/statuses/new'
+          && window.history.state
+          && !getState().getIn(['compose', 'advanced_options', 'threaded_mode'])) {
+        routerHistory.goBack();
+      }
+
       insertIfOnline('home');
 
       if (response.data.in_reply_to_id === null && response.data.visibility === 'public') {
diff --git a/app/javascript/flavours/glitch/actions/timelines.js b/app/javascript/flavours/glitch/actions/timelines.js
index ffd259d5f..d13d66516 100644
--- a/app/javascript/flavours/glitch/actions/timelines.js
+++ b/app/javascript/flavours/glitch/actions/timelines.js
@@ -54,11 +54,13 @@ export function expandTimeline(timelineId, path, params = {}, done = noOp) {
       params.since_id = timeline.getIn(['items', 0]);
     }
 
+    const isLoadingRecent = !!params.since_id;
+
     dispatch(expandTimelineRequest(timelineId, isLoadingMore));
 
     api(getState).get(path, { params }).then(response => {
       const next = getLinks(response).refs.find(link => link.rel === 'next');
-      dispatch(expandTimelineSuccess(timelineId, response.data, next ? next.uri : null, response.code === 206, isLoadingMore));
+      dispatch(expandTimelineSuccess(timelineId, response.data, next ? next.uri : null, response.code === 206, isLoadingRecent, isLoadingMore));
       done();
     }).catch(error => {
       dispatch(expandTimelineFail(timelineId, error, isLoadingMore));
@@ -85,13 +87,14 @@ export function expandTimelineRequest(timeline, isLoadingMore) {
   };
 };
 
-export function expandTimelineSuccess(timeline, statuses, next, partial, isLoadingMore) {
+export function expandTimelineSuccess(timeline, statuses, next, partial, isLoadingRecent, isLoadingMore) {
   return {
     type: TIMELINE_EXPAND_SUCCESS,
     timeline,
     statuses,
     next,
     partial,
+    isLoadingRecent,
     skipLoading: !isLoadingMore,
   };
 };
diff --git a/app/javascript/flavours/glitch/components/scrollable_list.js b/app/javascript/flavours/glitch/components/scrollable_list.js
index a05d49829..bd922462e 100644
--- a/app/javascript/flavours/glitch/components/scrollable_list.js
+++ b/app/javascript/flavours/glitch/components/scrollable_list.js
@@ -164,7 +164,7 @@ export default class ScrollableList extends PureComponent {
     const { fullscreen } = this.state;
     const childrenCount = React.Children.count(children);
 
-    const loadMore     = (hasMore && childrenCount > 0 && onLoadMore) ? <LoadMore visible={!isLoading} onClick={this.handleLoadMore} /> : null;
+    const loadMore     = (hasMore && onLoadMore) ? <LoadMore visible={!isLoading} onClick={this.handleLoadMore} /> : null;
     let scrollableArea = null;
 
     if (showLoading) {
@@ -179,7 +179,7 @@ export default class ScrollableList extends PureComponent {
           </div>
         </div>
       );
-    } else if (isLoading || childrenCount > 0 || !emptyMessage) {
+    } else if (isLoading || childrenCount > 0 || hasMore || !emptyMessage) {
       scrollableArea = (
         <div className={classNames('scrollable', { fullscreen })} ref={this.setRef}>
           <div role='feed' className='item-list'>
@@ -204,7 +204,7 @@ export default class ScrollableList extends PureComponent {
       );
     } else {
       scrollableArea = (
-        <div className={classNames('scrollable', { fullscreen })} ref={this.setRef} style={{ flex: '1 1 auto', display: 'flex', flexDirection: 'column' }}>
+        <div className={classNames('scrollable scrollable--flex', { fullscreen })} ref={this.setRef}>
           {alwaysPrepend && prepend}
 
           <div className='empty-column-indicator'>
diff --git a/app/javascript/flavours/glitch/components/status_list.js b/app/javascript/flavours/glitch/components/status_list.js
index 68cd608b9..5249af76d 100644
--- a/app/javascript/flavours/glitch/components/status_list.js
+++ b/app/javascript/flavours/glitch/components/status_list.js
@@ -55,7 +55,7 @@ export default class StatusList extends ImmutablePureComponent {
   }
 
   handleLoadOlder = debounce(() => {
-    this.props.onLoadMore(this.props.statusIds.last());
+    this.props.onLoadMore(this.props.statusIds.size > 0 ? this.props.statusIds.last() : undefined);
   }, 300, { leading: true })
 
   _selectChild (index) {
diff --git a/app/javascript/flavours/glitch/features/account/components/header.js b/app/javascript/flavours/glitch/features/account/components/header.js
index f0d36947d..dc5b1447b 100644
--- a/app/javascript/flavours/glitch/features/account/components/header.js
+++ b/app/javascript/flavours/glitch/features/account/components/header.js
@@ -7,7 +7,7 @@ import ImmutablePureComponent from 'react-immutable-pure-component';
 import Avatar from 'flavours/glitch/components/avatar';
 import IconButton from 'flavours/glitch/components/icon_button';
 
-import { me } from 'flavours/glitch/util/initial_state';
+import { autoPlayGif, me } from 'flavours/glitch/util/initial_state';
 import classNames from 'classnames';
 
 const messages = defineMessages({
@@ -108,7 +108,7 @@ export default class Header extends ImmutablePureComponent {
 
     return (
       <div className='account__header__wrapper'>
-        <div className={classNames('account__header', { inactive: !!account.get('moved') })} style={{ backgroundImage: `url(${account.get('header')})` }}>
+        <div className={classNames('account__header', { inactive: !!account.get('moved') })} style={{ backgroundImage: `url(${autoPlayGif ? account.get('header') : account.get('header_static')})` }}>
           <div>
             <a
               href={account.get('url')}
diff --git a/app/javascript/flavours/glitch/features/account_gallery/index.js b/app/javascript/flavours/glitch/features/account_gallery/index.js
index 53b906d16..3f61af0e8 100644
--- a/app/javascript/flavours/glitch/features/account_gallery/index.js
+++ b/app/javascript/flavours/glitch/features/account_gallery/index.js
@@ -35,7 +35,7 @@ class LoadMoreMedia extends ImmutablePureComponent {
     return (
       <LoadMore
         disabled={this.props.disabled}
-        onLoadMore={this.handleLoadMore}
+        onClick={this.handleLoadMore}
       />
     );
   }
@@ -67,7 +67,7 @@ export default class AccountGallery extends ImmutablePureComponent {
 
   handleScrollToBottom = () => {
     if (this.props.hasMore) {
-      this.handleLoadMore(this.props.medias.last().getIn(['status', 'id']));
+      this.handleLoadMore(this.props.medias.size > 0 ? this.props.medias.last().getIn(['status', 'id']) : undefined);
     }
   }
 
@@ -107,8 +107,8 @@ export default class AccountGallery extends ImmutablePureComponent {
       );
     }
 
-    if (!isLoading && medias.size > 0 && hasMore) {
-      loadOlder = <LoadMore onClick={this.handleLoadOlder} />;
+    if (hasMore) {
+      loadOlder = <LoadMore visible={!isLoading} onClick={this.handleLoadOlder} />;
     }
 
     return (
@@ -116,14 +116,15 @@ export default class AccountGallery extends ImmutablePureComponent {
         <ColumnBackButton />
 
         <ScrollContainer scrollKey='account_gallery' shouldUpdateScroll={this.shouldUpdateScroll}>
-          <div className='scrollable' onScroll={this.handleScroll}>
+          <div className='scrollable scrollable--flex' onScroll={this.handleScroll}>
             <HeaderContainer accountId={this.props.params.accountId} />
 
-            <div className='account-gallery__container'>
+            <div role='feed' className='account-gallery__container'>
               {medias.map((media, index) => media === null ? (
                 <LoadMoreMedia
                   key={'more:' + medias.getIn(index + 1, 'id')}
                   maxId={index > 0 ? medias.getIn(index - 1, 'id') : null}
+                  onLoadMore={this.handleLoadMore}
                 />
               ) : (
                 <MediaItem
@@ -133,6 +134,12 @@ export default class AccountGallery extends ImmutablePureComponent {
               ))}
               {loadOlder}
             </div>
+
+            {isLoading && medias.size === 0 && (
+              <div className='scrollable__append'>
+                <LoadingIndicator />
+              </div>
+            )}
           </div>
         </ScrollContainer>
       </Column>
diff --git a/app/javascript/flavours/glitch/features/composer/index.js b/app/javascript/flavours/glitch/features/composer/index.js
index 029b11a36..40eae1f53 100644
--- a/app/javascript/flavours/glitch/features/composer/index.js
+++ b/app/javascript/flavours/glitch/features/composer/index.js
@@ -159,15 +159,15 @@ const mapDispatchToProps = (dispatch, { intl }) => ({
   onSelectSuggestion(position, token, suggestion) {
     dispatch(selectComposeSuggestion(position, token, suggestion));
   },
-  onMediaDescriptionConfirm() {
+  onMediaDescriptionConfirm(routerHistory) {
     dispatch(openModal('CONFIRM', {
       message: intl.formatMessage(messages.missingDescriptionMessage),
       confirm: intl.formatMessage(messages.missingDescriptionConfirm),
-      onConfirm: () => dispatch(submitCompose()),
+      onConfirm: () => dispatch(submitCompose(routerHistory)),
     }));
   },
-  onSubmit() {
-    dispatch(submitCompose());
+  onSubmit(routerHistory) {
+    dispatch(submitCompose(routerHistory));
   },
   onUndoUpload(id) {
     dispatch(undoUploadCompose(id));
@@ -256,9 +256,9 @@ const handlers = {
           inputs[firstWithoutDescription].focus();
         }
       }
-      onMediaDescriptionConfirm();
+      onMediaDescriptionConfirm(this.context.router ? this.context.router.history : null);
     } else if (onSubmit) {
-      onSubmit();
+      onSubmit(this.context.router ? this.context.router.history : null);
     }
   },
 
@@ -563,6 +563,10 @@ Composer.propTypes = {
   onMediaDescriptionConfirm: PropTypes.func,
 };
 
+Composer.contextTypes = {
+  router: PropTypes.object,
+};
+
 //  Connecting and export.
 export { Composer as WrappedComponent };
 export default wrap(Composer, mapStateToProps, mapDispatchToProps, true);
diff --git a/app/javascript/flavours/glitch/reducers/notifications.js b/app/javascript/flavours/glitch/reducers/notifications.js
index 0b816e85e..b65c51f32 100644
--- a/app/javascript/flavours/glitch/reducers/notifications.js
+++ b/app/javascript/flavours/glitch/reducers/notifications.js
@@ -96,7 +96,7 @@ const expandNormalizedNotifications = (state, notifications, next) => {
     }
 
     if (!next) {
-      mutable.set('hasMore', true);
+      mutable.set('hasMore', false);
     }
 
     mutable.set('isLoading', false);
diff --git a/app/javascript/flavours/glitch/reducers/timelines.js b/app/javascript/flavours/glitch/reducers/timelines.js
index 844a0580f..a9eaae26e 100644
--- a/app/javascript/flavours/glitch/reducers/timelines.js
+++ b/app/javascript/flavours/glitch/reducers/timelines.js
@@ -25,10 +25,10 @@ const initialTimeline = ImmutableMap({
   items: ImmutableList(),
 });
 
-const expandNormalizedTimeline = (state, timeline, statuses, next, isPartial) => {
+const expandNormalizedTimeline = (state, timeline, statuses, next, isPartial, isLoadingRecent) => {
   return state.update(timeline, initialTimeline, map => map.withMutations(mMap => {
     mMap.set('isLoading', false);
-    if (!next) mMap.set('hasMore', false);
+    if (!next && !isLoadingRecent) mMap.set('hasMore', false);
 
     if (!statuses.isEmpty()) {
       mMap.update('items', ImmutableList(), oldIds => {
@@ -116,7 +116,7 @@ export default function timelines(state = initialState, action) {
   case TIMELINE_EXPAND_FAIL:
     return state.update(action.timeline, initialTimeline, map => map.set('isLoading', false));
   case TIMELINE_EXPAND_SUCCESS:
-    return expandNormalizedTimeline(state, action.timeline, fromJS(action.statuses), action.next, action.partial);
+    return expandNormalizedTimeline(state, action.timeline, fromJS(action.statuses), action.next, action.partial, action.isLoadingRecent);
   case TIMELINE_UPDATE:
     return updateTimeline(state, action.timeline, fromJS(action.status));
   case TIMELINE_DELETE:
diff --git a/app/javascript/flavours/glitch/styles/forms.scss b/app/javascript/flavours/glitch/styles/forms.scss
index 4f96204f2..6132dd1ae 100644
--- a/app/javascript/flavours/glitch/styles/forms.scss
+++ b/app/javascript/flavours/glitch/styles/forms.scss
@@ -420,6 +420,7 @@ code {
     border: 1px solid darken($ui-base-color, 14%);
     border-radius: 4px;
     padding: 10px;
+    padding-right: 30px;
     height: 41px;
   }
 
diff --git a/app/javascript/mastodon/actions/compose.js b/app/javascript/mastodon/actions/compose.js
index 86d83122f..1c7f14b5e 100644
--- a/app/javascript/mastodon/actions/compose.js
+++ b/app/javascript/mastodon/actions/compose.js
@@ -144,7 +144,11 @@ export function submitCompose(routerHistory) {
 
       if (response.data.visibility === 'direct' && getState().getIn(['conversations', 'mounted']) <= 0 && routerHistory) {
         routerHistory.push('/timelines/direct');
-      } else if (response.data.visibility !== 'direct') {
+      } else if (routerHistory && routerHistory.location.pathname === '/statuses/new' && window.history.state) {
+        routerHistory.goBack();
+      }
+
+      if (response.data.visibility !== 'direct') {
         insertIfOnline('home');
       }
 
diff --git a/app/javascript/mastodon/actions/timelines.js b/app/javascript/mastodon/actions/timelines.js
index 215adc4ea..6e7bd027c 100644
--- a/app/javascript/mastodon/actions/timelines.js
+++ b/app/javascript/mastodon/actions/timelines.js
@@ -74,12 +74,14 @@ export function expandTimeline(timelineId, path, params = {}, done = noOp) {
       params.since_id = timeline.getIn(['items', 0]);
     }
 
+    const isLoadingRecent = !!params.since_id;
+
     dispatch(expandTimelineRequest(timelineId, isLoadingMore));
 
     api(getState).get(path, { params }).then(response => {
       const next = getLinks(response).refs.find(link => link.rel === 'next');
       dispatch(importFetchedStatuses(response.data));
-      dispatch(expandTimelineSuccess(timelineId, response.data, next ? next.uri : null, response.code === 206, isLoadingMore));
+      dispatch(expandTimelineSuccess(timelineId, response.data, next ? next.uri : null, response.code === 206, isLoadingRecent, isLoadingMore));
       done();
     }).catch(error => {
       dispatch(expandTimelineFail(timelineId, error, isLoadingMore));
@@ -112,13 +114,14 @@ export function expandTimelineRequest(timeline, isLoadingMore) {
   };
 };
 
-export function expandTimelineSuccess(timeline, statuses, next, partial, isLoadingMore) {
+export function expandTimelineSuccess(timeline, statuses, next, partial, isLoadingRecent, isLoadingMore) {
   return {
     type: TIMELINE_EXPAND_SUCCESS,
     timeline,
     statuses,
     next,
     partial,
+    isLoadingRecent,
     skipLoading: !isLoadingMore,
   };
 };
diff --git a/app/javascript/mastodon/components/scrollable_list.js b/app/javascript/mastodon/components/scrollable_list.js
index ab4e7d59c..774c8835d 100644
--- a/app/javascript/mastodon/components/scrollable_list.js
+++ b/app/javascript/mastodon/components/scrollable_list.js
@@ -30,7 +30,6 @@ export default class ScrollableList extends PureComponent {
     hasMore: PropTypes.bool,
     prepend: PropTypes.node,
     alwaysPrepend: PropTypes.bool,
-    alwaysShowScrollbar: PropTypes.bool,
     emptyMessage: PropTypes.node,
     children: PropTypes.node,
   };
@@ -206,11 +205,11 @@ export default class ScrollableList extends PureComponent {
   }
 
   render () {
-    const { children, scrollKey, trackScroll, shouldUpdateScroll, showLoading, isLoading, hasMore, prepend, alwaysPrepend, alwaysShowScrollbar, emptyMessage, onLoadMore } = this.props;
+    const { children, scrollKey, trackScroll, shouldUpdateScroll, showLoading, isLoading, hasMore, prepend, alwaysPrepend, emptyMessage, onLoadMore } = this.props;
     const { fullscreen } = this.state;
     const childrenCount = React.Children.count(children);
 
-    const loadMore     = (hasMore && childrenCount > 0 && onLoadMore) ? <LoadMore visible={!isLoading} onClick={this.handleLoadMore} /> : null;
+    const loadMore     = (hasMore && onLoadMore) ? <LoadMore visible={!isLoading} onClick={this.handleLoadMore} /> : null;
     let scrollableArea = null;
 
     if (showLoading) {
@@ -225,7 +224,7 @@ export default class ScrollableList extends PureComponent {
           </div>
         </div>
       );
-    } else if (isLoading || childrenCount > 0 || !emptyMessage) {
+    } else if (isLoading || childrenCount > 0 || hasMore || !emptyMessage) {
       scrollableArea = (
         <div className={classNames('scrollable', { fullscreen })} ref={this.setRef} onMouseMove={this.handleMouseMove}>
           <div role='feed' className='item-list'>
@@ -249,10 +248,8 @@ export default class ScrollableList extends PureComponent {
         </div>
       );
     } else {
-      const scrollable = alwaysShowScrollbar;
-
       scrollableArea = (
-        <div className={classNames({ scrollable, fullscreen })} ref={this.setRef} style={{ flex: '1 1 auto', display: 'flex', flexDirection: 'column' }}>
+        <div className={classNames('scrollable scrollable--flex', { fullscreen })} ref={this.setRef}>
           {alwaysPrepend && prepend}
 
           <div className='empty-column-indicator'>
diff --git a/app/javascript/mastodon/components/status_list.js b/app/javascript/mastodon/components/status_list.js
index 01cc05661..e417f9a2b 100644
--- a/app/javascript/mastodon/components/status_list.js
+++ b/app/javascript/mastodon/components/status_list.js
@@ -55,7 +55,7 @@ export default class StatusList extends ImmutablePureComponent {
   }
 
   handleLoadOlder = debounce(() => {
-    this.props.onLoadMore(this.props.statusIds.last());
+    this.props.onLoadMore(this.props.statusIds.size > 0 ? this.props.statusIds.last() : undefined);
   }, 300, { leading: true })
 
   _selectChild (index) {
diff --git a/app/javascript/mastodon/features/account/components/header.js b/app/javascript/mastodon/features/account/components/header.js
index 8604e7167..2ab25cde4 100644
--- a/app/javascript/mastodon/features/account/components/header.js
+++ b/app/javascript/mastodon/features/account/components/header.js
@@ -158,7 +158,7 @@ class Header extends ImmutablePureComponent {
     const badge           = account.get('bot') ? (<div className='roles'><div className='account-role bot'><FormattedMessage id='account.badges.bot' defaultMessage='Bot' /></div></div>) : null;
 
     return (
-      <div className={classNames('account__header', { inactive: !!account.get('moved') })} style={{ backgroundImage: `url(${account.get('header')})` }}>
+      <div className={classNames('account__header', { inactive: !!account.get('moved') })} style={{ backgroundImage: `url(${autoPlayGif ? account.get('header') : account.get('header_static')})` }}>
         <div>
           <Avatar account={account} />
 
diff --git a/app/javascript/mastodon/features/account_gallery/index.js b/app/javascript/mastodon/features/account_gallery/index.js
index 32cb5ebdc..0d66868ed 100644
--- a/app/javascript/mastodon/features/account_gallery/index.js
+++ b/app/javascript/mastodon/features/account_gallery/index.js
@@ -36,7 +36,7 @@ class LoadMoreMedia extends ImmutablePureComponent {
     return (
       <LoadMore
         disabled={this.props.disabled}
-        onLoadMore={this.handleLoadMore}
+        onClick={this.handleLoadMore}
       />
     );
   }
@@ -68,7 +68,7 @@ class AccountGallery extends ImmutablePureComponent {
 
   handleScrollToBottom = () => {
     if (this.props.hasMore) {
-      this.handleLoadMore(this.props.medias.last().getIn(['status', 'id']));
+      this.handleLoadMore(this.props.medias.size > 0 ? this.props.medias.last().getIn(['status', 'id']) : undefined);
     }
   }
 
@@ -103,8 +103,8 @@ class AccountGallery extends ImmutablePureComponent {
       );
     }
 
-    if (!isLoading && medias.size > 0 && hasMore) {
-      loadOlder = <LoadMore onClick={this.handleLoadOlder} />;
+    if (hasMore) {
+      loadOlder = <LoadMore visible={!isLoading} onClick={this.handleLoadOlder} />;
     }
 
     return (
@@ -112,14 +112,15 @@ class AccountGallery extends ImmutablePureComponent {
         <ColumnBackButton />
 
         <ScrollContainer scrollKey='account_gallery' shouldUpdateScroll={shouldUpdateScroll}>
-          <div className='scrollable' onScroll={this.handleScroll}>
+          <div className='scrollable scrollable--flex' onScroll={this.handleScroll}>
             <HeaderContainer accountId={this.props.params.accountId} />
 
-            <div className='account-gallery__container'>
+            <div role='feed' className='account-gallery__container'>
               {medias.map((media, index) => media === null ? (
                 <LoadMoreMedia
                   key={'more:' + medias.getIn(index + 1, 'id')}
                   maxId={index > 0 ? medias.getIn(index - 1, 'id') : null}
+                  onLoadMore={this.handleLoadMore}
                 />
               ) : (
                 <MediaItem
@@ -129,6 +130,12 @@ class AccountGallery extends ImmutablePureComponent {
               ))}
               {loadOlder}
             </div>
+
+            {isLoading && medias.size === 0 && (
+              <div className='scrollable__append'>
+                <LoadingIndicator />
+              </div>
+            )}
           </div>
         </ScrollContainer>
       </Column>
diff --git a/app/javascript/mastodon/features/followers/index.js b/app/javascript/mastodon/features/followers/index.js
index b9ca7f3dd..ce56f270c 100644
--- a/app/javascript/mastodon/features/followers/index.js
+++ b/app/javascript/mastodon/features/followers/index.js
@@ -73,7 +73,6 @@ class Followers extends ImmutablePureComponent {
           shouldUpdateScroll={shouldUpdateScroll}
           prepend={<HeaderContainer accountId={this.props.params.accountId} hideTabs />}
           alwaysPrepend
-          alwaysShowScrollbar
           emptyMessage={emptyMessage}
         >
           {accountIds.map(id =>
diff --git a/app/javascript/mastodon/features/following/index.js b/app/javascript/mastodon/features/following/index.js
index b3e160240..bda0438a0 100644
--- a/app/javascript/mastodon/features/following/index.js
+++ b/app/javascript/mastodon/features/following/index.js
@@ -73,7 +73,6 @@ class Following extends ImmutablePureComponent {
           shouldUpdateScroll={shouldUpdateScroll}
           prepend={<HeaderContainer accountId={this.props.params.accountId} hideTabs />}
           alwaysPrepend
-          alwaysShowScrollbar
           emptyMessage={emptyMessage}
         >
           {accountIds.map(id =>
diff --git a/app/javascript/mastodon/locales/ar.json b/app/javascript/mastodon/locales/ar.json
index 2d73f84e0..798c7bfd8 100644
--- a/app/javascript/mastodon/locales/ar.json
+++ b/app/javascript/mastodon/locales/ar.json
@@ -1,5 +1,5 @@
 {
-  "account.add_or_remove_from_list": "Add or Remove from lists",
+  "account.add_or_remove_from_list": "اضافو أو حذف مِن القوائم",
   "account.badges.bot": "روبوت",
   "account.block": "حظر @{name}",
   "account.block_domain": "إخفاء كل شيئ قادم من إسم النطاق {domain}",
@@ -17,6 +17,7 @@
   "account.follows_you": "يتابعك",
   "account.hide_reblogs": "إخفاء ترقيات @{name}",
   "account.link_verified_on": "تم التحقق مِن مالك هذا الرابط بتاريخ {date}",
+  "account.locked_info": "This account privacy status is set to locked. The owner manually reviews who can follow them.",
   "account.media": "وسائط",
   "account.mention": "أُذكُر @{name}",
   "account.moved_to": "{name} إنتقل إلى :",
@@ -112,7 +113,7 @@
   "emoji_button.search_results": "نتائج البحث",
   "emoji_button.symbols": "رموز",
   "emoji_button.travel": "أماكن و أسفار",
-  "empty_column.account_timeline": "No toots here!",
+  "empty_column.account_timeline": "ليس هناك تبويقات!",
   "empty_column.blocks": "لم تقم بحظر أي مستخدِم بعد.",
   "empty_column.community": "الخط الزمني المحلي فارغ. أكتب شيئا ما للعامة كبداية !",
   "empty_column.direct": "لم تتلق أية رسالة خاصة مباشِرة بعد. سوف يتم عرض الرسائل المباشرة هنا إن قمت بإرسال واحدة أو تلقيت البعض منها.",
@@ -138,12 +139,12 @@
   "getting_started.open_source_notice": "ماستدون برنامج مفتوح المصدر. يمكنك المساهمة، أو الإبلاغ عن تقارير الأخطاء، على جيت هب {github}.",
   "getting_started.security": "الأمان",
   "getting_started.terms": "شروط الخدمة",
-  "hashtag.column_header.tag_mode.all": "and {additional}",
-  "hashtag.column_header.tag_mode.any": "or {additional}",
-  "hashtag.column_header.tag_mode.none": "without {additional}",
-  "hashtag.column_settings.tag_mode.all": "All of these",
-  "hashtag.column_settings.tag_mode.any": "Any of these",
-  "hashtag.column_settings.tag_mode.none": "None of these",
+  "hashtag.column_header.tag_mode.all": "و {additional}",
+  "hashtag.column_header.tag_mode.any": "أو {additional}",
+  "hashtag.column_header.tag_mode.none": "بدون {additional}",
+  "hashtag.column_settings.tag_mode.all": "كلها",
+  "hashtag.column_settings.tag_mode.any": "أي كان مِن هذه",
+  "hashtag.column_settings.tag_mode.none": "لا شيء مِن هذه",
   "hashtag.column_settings.tag_toggle": "Include additional tags in this column",
   "home.column_settings.basic": "أساسية",
   "home.column_settings.show_reblogs": "عرض الترقيات",
@@ -321,7 +322,7 @@
   "status.show_less_all": "طي الكل",
   "status.show_more": "أظهر المزيد",
   "status.show_more_all": "توسيع الكل",
-  "status.show_thread": "Show thread",
+  "status.show_thread": "الكشف عن المحادثة",
   "status.unmute_conversation": "فك الكتم عن المحادثة",
   "status.unpin": "فك التدبيس من الملف الشخصي",
   "suggestions.dismiss": "إلغاء الإقتراح",
diff --git a/app/javascript/mastodon/locales/ast.json b/app/javascript/mastodon/locales/ast.json
index e22c46e9e..bb6d5c167 100644
--- a/app/javascript/mastodon/locales/ast.json
+++ b/app/javascript/mastodon/locales/ast.json
@@ -17,6 +17,7 @@
   "account.follows_you": "Síguete",
   "account.hide_reblogs": "Hide boosts from @{name}",
   "account.link_verified_on": "Ownership of this link was checked on {date}",
+  "account.locked_info": "This account privacy status is set to locked. The owner manually reviews who can follow them.",
   "account.media": "Media",
   "account.mention": "Mentar a @{name}",
   "account.moved_to": "{name} has moved to:",
@@ -208,7 +209,7 @@
   "navigation_bar.follow_requests": "Solicitúes de siguimientu",
   "navigation_bar.info": "Tocante a esta instancia",
   "navigation_bar.keyboard_shortcuts": "Atayos",
-  "navigation_bar.lists": "Lists",
+  "navigation_bar.lists": "Llistes",
   "navigation_bar.logout": "Zarrar sesión",
   "navigation_bar.mutes": "Usuarios silenciaos",
   "navigation_bar.personal": "Personal",
diff --git a/app/javascript/mastodon/locales/bg.json b/app/javascript/mastodon/locales/bg.json
index 1a5a70593..c82fd8c81 100644
--- a/app/javascript/mastodon/locales/bg.json
+++ b/app/javascript/mastodon/locales/bg.json
@@ -17,6 +17,7 @@
   "account.follows_you": "Твой последовател",
   "account.hide_reblogs": "Hide boosts from @{name}",
   "account.link_verified_on": "Ownership of this link was checked on {date}",
+  "account.locked_info": "This account privacy status is set to locked. The owner manually reviews who can follow them.",
   "account.media": "Media",
   "account.mention": "Споменаване",
   "account.moved_to": "{name} has moved to:",
diff --git a/app/javascript/mastodon/locales/ca.json b/app/javascript/mastodon/locales/ca.json
index bc1fd8950..e4e9f183d 100644
--- a/app/javascript/mastodon/locales/ca.json
+++ b/app/javascript/mastodon/locales/ca.json
@@ -1,5 +1,5 @@
 {
-  "account.add_or_remove_from_list": "Add or Remove from lists",
+  "account.add_or_remove_from_list": "Afegir o Treure de les llistes",
   "account.badges.bot": "Bot",
   "account.block": "Bloca @{name}",
   "account.block_domain": "Amaga-ho tot de {domain}",
@@ -17,6 +17,7 @@
   "account.follows_you": "Et segueix",
   "account.hide_reblogs": "Amaga els impulsos de @{name}",
   "account.link_verified_on": "La propietat d'aquest enllaç es va verificar el dia {date}",
+  "account.locked_info": "Aquest estat de privadesa del compte està definit com a bloquejat. El propietari revisa manualment qui pot seguir-lo.",
   "account.media": "Media",
   "account.mention": "Esmentar @{name}",
   "account.moved_to": "{name} s'ha mogut a:",
@@ -112,7 +113,7 @@
   "emoji_button.search_results": "Resultats de la cerca",
   "emoji_button.symbols": "Símbols",
   "emoji_button.travel": "Viatges i Llocs",
-  "empty_column.account_timeline": "No toots here!",
+  "empty_column.account_timeline": "No hi ha toots aquí!",
   "empty_column.blocks": "Encara no has bloquejat cap usuari.",
   "empty_column.community": "La línia de temps local és buida. Escriu alguna cosa públicament per fer rodar la pilota!",
   "empty_column.direct": "Encara no tens missatges directes. Quan enviïs o rebis un, es mostrarà aquí.",
@@ -138,12 +139,12 @@
   "getting_started.open_source_notice": "Mastodon és un programari de codi obert. Pots contribuir o informar de problemes a GitHub a {github}.",
   "getting_started.security": "Seguretat",
   "getting_started.terms": "Termes del servei",
-  "hashtag.column_header.tag_mode.all": "and {additional}",
-  "hashtag.column_header.tag_mode.any": "or {additional}",
-  "hashtag.column_header.tag_mode.none": "without {additional}",
-  "hashtag.column_settings.tag_mode.all": "All of these",
-  "hashtag.column_settings.tag_mode.any": "Any of these",
-  "hashtag.column_settings.tag_mode.none": "None of these",
+  "hashtag.column_header.tag_mode.all": "i {additional}",
+  "hashtag.column_header.tag_mode.any": "o {additional}",
+  "hashtag.column_header.tag_mode.none": "sense {additional}",
+  "hashtag.column_settings.tag_mode.all": "Tots aquests",
+  "hashtag.column_settings.tag_mode.any": "Qualsevol d’aquests",
+  "hashtag.column_settings.tag_mode.none": "Cap d’aquests",
   "hashtag.column_settings.tag_toggle": "Include additional tags in this column",
   "home.column_settings.basic": "Bàsic",
   "home.column_settings.show_reblogs": "Mostrar impulsos",
@@ -321,11 +322,11 @@
   "status.show_less_all": "Mostra menys per a tot",
   "status.show_more": "Mostra més",
   "status.show_more_all": "Mostra més per a tot",
-  "status.show_thread": "Show thread",
+  "status.show_thread": "Mostra el fil",
   "status.unmute_conversation": "Activar conversació",
   "status.unpin": "Deslliga del perfil",
   "suggestions.dismiss": "Descartar suggeriment",
-  "suggestions.header": "És possible que t’interessi…",
+  "suggestions.header": "És possible que estiguis interessat en…",
   "tabs_bar.federated_timeline": "Federada",
   "tabs_bar.home": "Inici",
   "tabs_bar.local_timeline": "Local",
diff --git a/app/javascript/mastodon/locales/co.json b/app/javascript/mastodon/locales/co.json
index 45bf0dc43..1d8d61a7a 100644
--- a/app/javascript/mastodon/locales/co.json
+++ b/app/javascript/mastodon/locales/co.json
@@ -1,5 +1,5 @@
 {
-  "account.add_or_remove_from_list": "Add or Remove from lists",
+  "account.add_or_remove_from_list": "Aghjustà o toglie da e liste",
   "account.badges.bot": "Bot",
   "account.block": "Bluccà @{name}",
   "account.block_domain": "Piattà tuttu da {domain}",
@@ -17,6 +17,7 @@
   "account.follows_you": "Vi seguita",
   "account.hide_reblogs": "Piattà spartere da @{name}",
   "account.link_verified_on": "A prupietà di stu ligame hè stata verificata u {date}",
+  "account.locked_info": "U statutu di vita privata di u contu hè chjosu. U pruprietariu esamina manualmente e dumande d'abbunamentu.",
   "account.media": "Media",
   "account.mention": "Mintuvà @{name}",
   "account.moved_to": "{name} hè partutu nant'à:",
@@ -112,7 +113,7 @@
   "emoji_button.search_results": "Risultati di a cerca",
   "emoji_button.symbols": "Simbuli",
   "emoji_button.travel": "Lochi è Viaghju",
-  "empty_column.account_timeline": "No toots here!",
+  "empty_column.account_timeline": "Nisun statutu quì!",
   "empty_column.blocks": "Per avà ùn avete bluccatu manc'un utilizatore.",
   "empty_column.community": "Ùn c'hè nunda indè a linea lucale. Scrivete puru qualcosa!",
   "empty_column.direct": "Ùn avete ancu nisun missaghju direttu. S'è voi mandate o ricevete unu, u vidarete quì.",
@@ -138,12 +139,12 @@
   "getting_started.open_source_notice": "Mastodon ghjè un lugiziale liberu. Pudete cuntribuisce à u codice o a traduzione, o palisà un bug, nant'à GitHub: {github}.",
   "getting_started.security": "Sicurità",
   "getting_started.terms": "Cundizione di u serviziu",
-  "hashtag.column_header.tag_mode.all": "and {additional}",
-  "hashtag.column_header.tag_mode.any": "or {additional}",
-  "hashtag.column_header.tag_mode.none": "without {additional}",
-  "hashtag.column_settings.tag_mode.all": "All of these",
-  "hashtag.column_settings.tag_mode.any": "Any of these",
-  "hashtag.column_settings.tag_mode.none": "None of these",
+  "hashtag.column_header.tag_mode.all": "è {additional}",
+  "hashtag.column_header.tag_mode.any": "o {additional}",
+  "hashtag.column_header.tag_mode.none": "senza {additional}",
+  "hashtag.column_settings.tag_mode.all": "Tutti quessi",
+  "hashtag.column_settings.tag_mode.any": "Unu di quessi",
+  "hashtag.column_settings.tag_mode.none": "Nisunu di quessi",
   "hashtag.column_settings.tag_toggle": "Include additional tags in this column",
   "home.column_settings.basic": "Bàsichi",
   "home.column_settings.show_reblogs": "Vede e spartere",
@@ -321,7 +322,7 @@
   "status.show_less_all": "Ripiegà tuttu",
   "status.show_more": "Slibrà",
   "status.show_more_all": "Slibrà tuttu",
-  "status.show_thread": "Show thread",
+  "status.show_thread": "Vede u filu",
   "status.unmute_conversation": "Ùn piattà più a cunversazione",
   "status.unpin": "Spuntarulà da u prufile",
   "suggestions.dismiss": "Righjittà a pruposta",
diff --git a/app/javascript/mastodon/locales/cs.json b/app/javascript/mastodon/locales/cs.json
index 80fab00c3..0d7f42656 100644
--- a/app/javascript/mastodon/locales/cs.json
+++ b/app/javascript/mastodon/locales/cs.json
@@ -1,5 +1,5 @@
 {
-  "account.add_or_remove_from_list": "Add or Remove from lists",
+  "account.add_or_remove_from_list": "Přidat nebo odstranit ze seznamů",
   "account.badges.bot": "Robot",
   "account.block": "Zablokovat uživatele @{name}",
   "account.block_domain": "Skrýt vše z {domain}",
@@ -17,6 +17,7 @@
   "account.follows_you": "Sleduje vás",
   "account.hide_reblogs": "Skrýt boosty od uživatele @{name}",
   "account.link_verified_on": "Vlastnictví tohoto odkazu bylo zkontrolováno {date}",
+  "account.locked_info": "Stav soukromí tohoto účtu je nastaven na zamčeno. Jeho vlastník ručně posuzuje, kdo ho může sledovat.",
   "account.media": "Média",
   "account.mention": "Zmínit uživatele @{name}",
   "account.moved_to": "{name} se přesunul/a na:",
@@ -112,7 +113,7 @@
   "emoji_button.search_results": "Výsledky hledání",
   "emoji_button.symbols": "Symboly",
   "emoji_button.travel": "Cestování a místa",
-  "empty_column.account_timeline": "No toots here!",
+  "empty_column.account_timeline": "Tady nejsou žádné tooty!",
   "empty_column.blocks": "Ještě jste nezablokoval/a žádného uživatele.",
   "empty_column.community": "Místní časová osa je prázdná. Napište něco veřejně a rozhýbejte to tu!",
   "empty_column.direct": "Ještě nemáte žádné přímé zprávy. Pokud nějakou pošlete nebo dostanete, zobrazí se zde.",
@@ -138,13 +139,13 @@
   "getting_started.open_source_notice": "Mastodon je otevřený software. Na GitHubu k němu můžete přispět nebo nahlásit chyby: {github}.",
   "getting_started.security": "Zabezpečení",
   "getting_started.terms": "Podmínky používání",
-  "hashtag.column_header.tag_mode.all": "and {additional}",
-  "hashtag.column_header.tag_mode.any": "or {additional}",
-  "hashtag.column_header.tag_mode.none": "without {additional}",
-  "hashtag.column_settings.tag_mode.all": "All of these",
-  "hashtag.column_settings.tag_mode.any": "Any of these",
-  "hashtag.column_settings.tag_mode.none": "None of these",
-  "hashtag.column_settings.tag_toggle": "Include additional tags in this column",
+  "hashtag.column_header.tag_mode.all": "a {additional}",
+  "hashtag.column_header.tag_mode.any": "nebo {additional}",
+  "hashtag.column_header.tag_mode.none": "bez {additional}",
+  "hashtag.column_settings.tag_mode.all": "Všechny z těchto",
+  "hashtag.column_settings.tag_mode.any": "Jakékoliv z těchto",
+  "hashtag.column_settings.tag_mode.none": "Žádné z těchto",
+  "hashtag.column_settings.tag_toggle": "Zahrnout v tomto sloupci dodatečné hashtagy",
   "home.column_settings.basic": "Základní",
   "home.column_settings.show_reblogs": "Zobrazit boosty",
   "home.column_settings.show_replies": "Zobrazit odpovědi",
@@ -173,7 +174,7 @@
   "keyboard_shortcuts.profile": "k otevření autorova profilu",
   "keyboard_shortcuts.reply": "k odpovězení",
   "keyboard_shortcuts.requests": "k otevření seznamu požadavků o sledování",
-  "keyboard_shortcuts.search": "k zaměření na vyhledávání",
+  "keyboard_shortcuts.search": "k zaměření na hledání",
   "keyboard_shortcuts.start": "k otevření sloupce „začínáme“",
   "keyboard_shortcuts.toggle_hidden": "k zobrazení/skrytí textu za varováním o obsahu",
   "keyboard_shortcuts.toot": "k napsání úplně nového tootu",
@@ -188,7 +189,7 @@
   "lists.edit": "Upravit seznam",
   "lists.new.create": "Přidat seznam",
   "lists.new.title_placeholder": "Název nového seznamu",
-  "lists.search": "Hledejte mezi uživateli, které sledujete",
+  "lists.search": "Hledejte mezi lidmi, které sledujete",
   "lists.subheading": "Vaše seznamy",
   "loading_indicator.label": "Načítám...",
   "media_gallery.toggle_visible": "Přepínat viditelnost",
@@ -276,7 +277,7 @@
   "report.submit": "Odeslat",
   "report.target": "Nahlásit {target}",
   "search.placeholder": "Hledat",
-  "search_popout.search_format": "Pokročilé vyhledávání",
+  "search_popout.search_format": "Pokročilé hledání",
   "search_popout.tips.full_text": "Jednoduchý textový výpis příspěvků, které jste napsal/a, oblíbil/a si, boostnul/a, nebo v nich byl/a zmíněn/a, včetně odpovídajících přezdívek, zobrazovaných jmen a hashtagů.",
   "search_popout.tips.hashtag": "hashtag",
   "search_popout.tips.status": "příspěvek",
@@ -321,7 +322,7 @@
   "status.show_less_all": "Zobrazit méně pro všechny",
   "status.show_more": "Zobrazit více",
   "status.show_more_all": "Zobrazit více pro všechny",
-  "status.show_thread": "Show thread",
+  "status.show_thread": "Zobrazit vlákno",
   "status.unmute_conversation": "Přestat ignorovat konverzaci",
   "status.unpin": "Odepnout z profilu",
   "suggestions.dismiss": "Odmítnout návrh",
diff --git a/app/javascript/mastodon/locales/cy.json b/app/javascript/mastodon/locales/cy.json
index 4047b54d6..b1fb76934 100644
--- a/app/javascript/mastodon/locales/cy.json
+++ b/app/javascript/mastodon/locales/cy.json
@@ -17,6 +17,7 @@
   "account.follows_you": "Yn eich dilyn chi",
   "account.hide_reblogs": "Cuddio bwstiau o @{name}",
   "account.link_verified_on": "Gwiriwyd perchnogaeth y ddolen yma ar {date}",
+  "account.locked_info": "This account privacy status is set to locked. The owner manually reviews who can follow them.",
   "account.media": "Cyfryngau",
   "account.mention": "Crybwyll @{name}",
   "account.moved_to": "Mae @{name} wedi symud i:",
diff --git a/app/javascript/mastodon/locales/da.json b/app/javascript/mastodon/locales/da.json
index 133f9e696..8fb002ae8 100644
--- a/app/javascript/mastodon/locales/da.json
+++ b/app/javascript/mastodon/locales/da.json
@@ -1,5 +1,5 @@
 {
-  "account.add_or_remove_from_list": "Add or Remove from lists",
+  "account.add_or_remove_from_list": "Tilføj eller fjern fra lister",
   "account.badges.bot": "Robot",
   "account.block": "Bloker @{name}",
   "account.block_domain": "Skjul alt fra {domain}",
@@ -17,6 +17,7 @@
   "account.follows_you": "Følger dig",
   "account.hide_reblogs": "Skjul fremhævelserne fra @{name}",
   "account.link_verified_on": "Ejerskabet af dette link blev tjekket den %{date}",
+  "account.locked_info": "This account privacy status is set to locked. The owner manually reviews who can follow them.",
   "account.media": "Medie",
   "account.mention": "Nævn @{name}",
   "account.moved_to": "{name} er flyttet til:",
diff --git a/app/javascript/mastodon/locales/de.json b/app/javascript/mastodon/locales/de.json
index 6bba6114e..5ac95122f 100644
--- a/app/javascript/mastodon/locales/de.json
+++ b/app/javascript/mastodon/locales/de.json
@@ -1,10 +1,10 @@
 {
-  "account.add_or_remove_from_list": "Add or Remove from lists",
+  "account.add_or_remove_from_list": "Hinzufügen oder Entfernen von Listen",
   "account.badges.bot": "Bot",
   "account.block": "@{name} blockieren",
   "account.block_domain": "Alles von {domain} verstecken",
   "account.blocked": "Blockiert",
-  "account.direct": "Direct Message @{name}",
+  "account.direct": "Direktnachricht an @{name}",
   "account.disclaimer_full": "Das Profil wird möglicherweise unvollständig wiedergegeben.",
   "account.domain_blocked": "Domain versteckt",
   "account.edit_profile": "Profil bearbeiten",
@@ -17,6 +17,7 @@
   "account.follows_you": "Folgt dir",
   "account.hide_reblogs": "Geteilte Beiträge von @{name} verbergen",
   "account.link_verified_on": "Besitz dieses Links wurde geprüft am {date}",
+  "account.locked_info": "This account privacy status is set to locked. The owner manually reviews who can follow them.",
   "account.media": "Medien",
   "account.mention": "@{name} erwähnen",
   "account.moved_to": "{name} ist umgezogen auf:",
@@ -112,7 +113,7 @@
   "emoji_button.search_results": "Suchergebnisse",
   "emoji_button.symbols": "Symbole",
   "emoji_button.travel": "Reisen und Orte",
-  "empty_column.account_timeline": "No toots here!",
+  "empty_column.account_timeline": "Keine Beiträge!",
   "empty_column.blocks": "Du hast keine Profile blockiert.",
   "empty_column.community": "Die lokale Zeitleiste ist leer. Schreibe einen öffentlichen Beitrag, um den Ball ins Rollen zu bringen!",
   "empty_column.direct": "Du hast noch keine Direktnachrichten erhalten. Wenn du eine sendest oder empfängst, wird sie hier zu sehen sein.",
@@ -138,12 +139,12 @@
   "getting_started.open_source_notice": "Mastodon ist quelloffene Software. Du kannst auf GitHub unter {github} dazu beitragen oder Probleme melden.",
   "getting_started.security": "Sicherheit",
   "getting_started.terms": "Nutzungsbedingungen",
-  "hashtag.column_header.tag_mode.all": "and {additional}",
-  "hashtag.column_header.tag_mode.any": "or {additional}",
-  "hashtag.column_header.tag_mode.none": "without {additional}",
-  "hashtag.column_settings.tag_mode.all": "All of these",
-  "hashtag.column_settings.tag_mode.any": "Any of these",
-  "hashtag.column_settings.tag_mode.none": "None of these",
+  "hashtag.column_header.tag_mode.all": "und {additional}",
+  "hashtag.column_header.tag_mode.any": "oder {additional}",
+  "hashtag.column_header.tag_mode.none": "ohne {additional}",
+  "hashtag.column_settings.tag_mode.all": "All diese",
+  "hashtag.column_settings.tag_mode.any": "Eine von diesen",
+  "hashtag.column_settings.tag_mode.none": "Keine von diesen",
   "hashtag.column_settings.tag_toggle": "Include additional tags in this column",
   "home.column_settings.basic": "Einfach",
   "home.column_settings.show_reblogs": "Geteilte Beiträge anzeigen",
@@ -321,11 +322,11 @@
   "status.show_less_all": "Zeige weniger für alles",
   "status.show_more": "Mehr anzeigen",
   "status.show_more_all": "Zeige mehr für alles",
-  "status.show_thread": "Show thread",
+  "status.show_thread": "Zeige Thread",
   "status.unmute_conversation": "Stummschaltung von Thread aufheben",
   "status.unpin": "Vom Profil lösen",
-  "suggestions.dismiss": "Dismiss suggestion",
-  "suggestions.header": "You might be interested in…",
+  "suggestions.dismiss": "Hinweis ausblenden",
+  "suggestions.header": "Du bist vielleicht interessiert in…",
   "tabs_bar.federated_timeline": "Föderation",
   "tabs_bar.home": "Startseite",
   "tabs_bar.local_timeline": "Lokal",
diff --git a/app/javascript/mastodon/locales/defaultMessages.json b/app/javascript/mastodon/locales/defaultMessages.json
index 57988fbd8..1015aba1b 100644
--- a/app/javascript/mastodon/locales/defaultMessages.json
+++ b/app/javascript/mastodon/locales/defaultMessages.json
@@ -644,6 +644,10 @@
         "id": "account.link_verified_on"
       },
       {
+        "defaultMessage": "This account privacy status is set to locked. The owner manually reviews who can follow them.",
+        "id": "account.locked_info"
+      },
+      {
         "defaultMessage": "Follows you",
         "id": "account.follows_you"
       },
diff --git a/app/javascript/mastodon/locales/el.json b/app/javascript/mastodon/locales/el.json
index ba332be3f..468a4c728 100644
--- a/app/javascript/mastodon/locales/el.json
+++ b/app/javascript/mastodon/locales/el.json
@@ -1,5 +1,5 @@
 {
-  "account.add_or_remove_from_list": "Add or Remove from lists",
+  "account.add_or_remove_from_list": "Προσθήκη ή αφαίρεση από λίστες",
   "account.badges.bot": "Μποτ",
   "account.block": "Απόκλεισε τον/την @{name}",
   "account.block_domain": "Απόκρυψε τα πάντα από το {domain}",
@@ -17,6 +17,7 @@
   "account.follows_you": "Σε ακολουθεί",
   "account.hide_reblogs": "Απόκρυψη προωθήσεων από @{name}",
   "account.link_verified_on": "Η ιδιοκτησία αυτού του συνδέσμου εκλέχθηκε την {date}",
+  "account.locked_info": "Η κατάσταση απορρήτου αυτού του λογαριασμού είναι κλειδωμένη. Ο ιδιοκτήτης επιβεβαιώνει χειροκίνητα ποιος μπορεί να τον ακολουθήσει.",
   "account.media": "Πολυμέσα",
   "account.mention": "Ανάφερε @{name}",
   "account.moved_to": "{name} μεταφέρθηκε στο:",
@@ -112,7 +113,7 @@
   "emoji_button.search_results": "Αποτελέσματα αναζήτησης",
   "emoji_button.symbols": "Σύμβολα",
   "emoji_button.travel": "Ταξίδια & Τοποθεσίες",
-  "empty_column.account_timeline": "No toots here!",
+  "empty_column.account_timeline": "Δεν έχει τουτ εδώ!",
   "empty_column.blocks": "Δεν έχεις αποκλείσει κανέναν χρήστη ακόμα.",
   "empty_column.community": "Η τοπική ροή είναι κενή. Γράψε κάτι δημόσιο παραμύθι ν' αρχινίσει!",
   "empty_column.direct": "Δεν έχεις προσωπικά μηνύματα ακόμα. Όταν στείλεις ή λάβεις κανένα, θα εμφανιστεί εδώ.",
@@ -138,12 +139,12 @@
   "getting_started.open_source_notice": "Το Mastodon είναι ελεύθερο λογισμικό. Μπορείς να συνεισφέρεις ή να αναφέρεις ζητήματα στο GitHub στο {github}.",
   "getting_started.security": "Ασφάλεια",
   "getting_started.terms": "Όροι χρήσης",
-  "hashtag.column_header.tag_mode.all": "and {additional}",
-  "hashtag.column_header.tag_mode.any": "or {additional}",
-  "hashtag.column_header.tag_mode.none": "without {additional}",
-  "hashtag.column_settings.tag_mode.all": "All of these",
-  "hashtag.column_settings.tag_mode.any": "Any of these",
-  "hashtag.column_settings.tag_mode.none": "None of these",
+  "hashtag.column_header.tag_mode.all": "και {additional}",
+  "hashtag.column_header.tag_mode.any": "ή {additional}",
+  "hashtag.column_header.tag_mode.none": "χωρίς {additional}",
+  "hashtag.column_settings.tag_mode.all": "Όλα αυτα",
+  "hashtag.column_settings.tag_mode.any": "Οποιοδήποτε από αυτά",
+  "hashtag.column_settings.tag_mode.none": "Κανένα από αυτά",
   "hashtag.column_settings.tag_toggle": "Include additional tags in this column",
   "home.column_settings.basic": "Βασικά",
   "home.column_settings.show_reblogs": "Εμφάνιση προωθήσεων",
@@ -233,7 +234,7 @@
   "notifications.group": "{count} ειδοποιήσεις",
   "onboarding.done": "Όλα έτοιμα",
   "onboarding.next": "Επόμενο",
-  "onboarding.page_five.public_timelines": "Η τοπική ροή δείχνει τις δημόσιες δημοσιεύσεις από όσους εδρεύουν στον κόμβο {domain}. Η ομοσπονδιακή ροή δείχνει τις δημόσιες δημοσιεύσεις εκείνων που οι χρήστες του {domain} ακολουθούν. Αυτές οι είναι Δημόσιες Ροές, ένας ωραίος τρόπος να ανακαλύψεις καινούριους ανθρώπους.",
+  "onboarding.page_five.public_timelines": "Η τοπική ροή δείχνει τις δημόσιες δημοσιεύσεις από όσους εδρεύουν στον κόμβο {domain}. Η ομοσπονδιακή ροή δείχνει τις δημόσιες δημοσιεύσεις εκείνων που οι χρήστες του {domain} ακολουθούν. Αυτές είναι οι Δημόσιες Ροές, ένας ωραίος τρόπος να ανακαλύψεις καινούριους ανθρώπους.",
   "onboarding.page_four.home": "Η αρχική ροή δείχνει καταστάσεις από ανθρώπους που ακολουθείς.",
   "onboarding.page_four.notifications": "Η στήλη ειδοποιήσεων δείχνει πότε κάποιος αλληλεπιδράει μαζί σου.",
   "onboarding.page_one.federation": "Το Mastodon είναι ένα δίκτυο ανεξάρτητων εξυπηρετητών (servers) που συνεργάζονται δημιουργώντας ένα μεγαλύτερο κοινωνικό δίκτυο. Τους εξυπηρετητές αυτούς τους λέμε κόμβους.",
@@ -321,11 +322,11 @@
   "status.show_less_all": "Δείξε λιγότερα για όλα",
   "status.show_more": "Δείξε περισσότερα",
   "status.show_more_all": "Δείξε περισσότερα για όλα",
-  "status.show_thread": "Show thread",
+  "status.show_thread": "Εμφάνιση νήματος",
   "status.unmute_conversation": "Διέκοψε την αποσιώπηση της συζήτησης",
   "status.unpin": "Ξεκαρφίτσωσε από το προφίλ",
-  "suggestions.dismiss": "Dismiss suggestion",
-  "suggestions.header": "You might be interested in…",
+  "suggestions.dismiss": "Απόρριψη πρότασης",
+  "suggestions.header": "Ίσως να ενδιαφέρεσαι για…",
   "tabs_bar.federated_timeline": "Ομοσπονδιακή",
   "tabs_bar.home": "Αρχική",
   "tabs_bar.local_timeline": "Τοπικά",
diff --git a/app/javascript/mastodon/locales/eo.json b/app/javascript/mastodon/locales/eo.json
index f7a303cdd..37304d8d1 100644
--- a/app/javascript/mastodon/locales/eo.json
+++ b/app/javascript/mastodon/locales/eo.json
@@ -1,5 +1,5 @@
 {
-  "account.add_or_remove_from_list": "Add or Remove from lists",
+  "account.add_or_remove_from_list": "Aldoni al aŭ forigi el listoj",
   "account.badges.bot": "Roboto",
   "account.block": "Bloki @{name}",
   "account.block_domain": "Kaŝi ĉion de {domain}",
@@ -11,12 +11,13 @@
   "account.endorse": "Montri en profilo",
   "account.follow": "Sekvi",
   "account.followers": "Sekvantoj",
-  "account.followers.empty": "No one follows this user yet.",
+  "account.followers.empty": "Neniu ankoraŭ sekvas ĉi tiun uzanton.",
   "account.follows": "Sekvatoj",
-  "account.follows.empty": "This user doesn't follow anyone yet.",
+  "account.follows.empty": "Ĉi tiu uzanto ne ankoraŭ sekvas iun.",
   "account.follows_you": "Sekvas vin",
   "account.hide_reblogs": "Kaŝi diskonigojn de @{name}",
-  "account.link_verified_on": "Ownership of this link was checked on {date}",
+  "account.link_verified_on": "Proprieto de ĉi tiu ligilo estis kontrolita je {date}",
+  "account.locked_info": "This account privacy status is set to locked. The owner manually reviews who can follow them.",
   "account.media": "Aŭdovidaĵoj",
   "account.mention": "Mencii @{name}",
   "account.moved_to": "{name} moviĝis al:",
@@ -91,9 +92,9 @@
   "confirmations.mute.confirm": "Silentigi",
   "confirmations.mute.message": "Ĉu vi certas, ke vi volas silentigi {name}?",
   "confirmations.redraft.confirm": "Forigi kaj reskribi",
-  "confirmations.redraft.message": "Ĉu vi certas, ke vi volas forigi tiun mesaĝon kaj reskribi ĝin? Vi perdos ĉiujn respondojn, diskonigojn kaj stelumojn ligitajn al ĝi.",
-  "confirmations.reply.confirm": "Reply",
-  "confirmations.reply.message": "Replying now will overwrite the message you are currently composing. Are you sure you want to proceed?",
+  "confirmations.redraft.message": "Ĉu vi certas ke vi volas forigi tiun mesaĝon kaj reskribi ĝin? Ĉiuj diskonigoj kaj stelumoj estos perditaj, kaj respondoj al la originala mesaĝo estos orfigitaj.",
+  "confirmations.reply.confirm": "Respondi",
+  "confirmations.reply.message": "Respondi nun anstataŭigos la mesaĝon ke vi aktuale skribas. Ĉu vi certas ke vi volas daŭrigi?",
   "confirmations.unfollow.confirm": "Ne plu sekvi",
   "confirmations.unfollow.message": "Ĉu vi certas, ke vi volas ĉesi sekvi {name}?",
   "embed.instructions": "Enkorpigu ĉi tiun mesaĝon en vian retejon per kopio de la suba kodo.",
@@ -112,20 +113,20 @@
   "emoji_button.search_results": "Serĉaj rezultoj",
   "emoji_button.symbols": "Simboloj",
   "emoji_button.travel": "Vojaĝoj kaj lokoj",
-  "empty_column.account_timeline": "No toots here!",
-  "empty_column.blocks": "You haven't blocked any users yet.",
+  "empty_column.account_timeline": "Neniu mesaĝo ĉi tie!",
+  "empty_column.blocks": "Vi ne ankoraŭ blokis iun uzanton.",
   "empty_column.community": "La loka tempolinio estas malplena. Skribu ion por plenigi ĝin!",
   "empty_column.direct": "Vi ankoraŭ ne havas rektan mesaĝon. Kiam vi sendos aŭ ricevos iun, ĝi aperos ĉi tie.",
-  "empty_column.domain_blocks": "There are no hidden domains yet.",
-  "empty_column.favourited_statuses": "You don't have any favourite toots yet. When you favourite one, it will show up here.",
-  "empty_column.favourites": "No one has favourited this toot yet. When someone does, they will show up here.",
-  "empty_column.follow_requests": "You don't have any follow requests yet. When you receive one, it will show up here.",
+  "empty_column.domain_blocks": "Ankoraŭ estas neniu domajno blokita.",
+  "empty_column.favourited_statuses": "Vi ne ankoraŭ havas iun stelumitan mesaĝon. Kiam vi stelumos iun, tiu aperos ĉi tie.",
+  "empty_column.favourites": "Neniu ankoraŭ stelumis ĉi tiun mesaĝon. Kiam iu faros ĝin, tiu aperos ĉi tie.",
+  "empty_column.follow_requests": "Vi ne ankoraŭ havas iun peton de sekvado. Kiam vi ricevos unu, ĝi aperos ĉi tie.",
   "empty_column.hashtag": "Ankoraŭ estas nenio per ĉi tiu kradvorto.",
   "empty_column.home": "Via hejma tempolinio estas malplena! Vizitu {public} aŭ uzu la serĉilon por renkonti aliajn uzantojn.",
   "empty_column.home.public_timeline": "la publikan tempolinion",
   "empty_column.list": "Ankoraŭ estas nenio en ĉi tiu listo. Kiam membroj de ĉi tiu listo afiŝos novajn mesaĝojn, ili aperos ĉi tie.",
   "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.mutes": "Vi ne ankoraŭ silentigis iun uzanton.",
   "empty_column.notifications": "Vi ankoraŭ ne havas sciigojn. Interagu kun aliaj por komenci konversacion.",
   "empty_column.public": "Estas nenio ĉi tie! Publike skribu ion, aŭ mane sekvu uzantojn de aliaj nodoj por plenigi la publikan tempolinion",
   "follow_request.authorize": "Rajtigi",
@@ -141,40 +142,40 @@
   "hashtag.column_header.tag_mode.all": "and {additional}",
   "hashtag.column_header.tag_mode.any": "or {additional}",
   "hashtag.column_header.tag_mode.none": "without {additional}",
-  "hashtag.column_settings.tag_mode.all": "All of these",
-  "hashtag.column_settings.tag_mode.any": "Any of these",
-  "hashtag.column_settings.tag_mode.none": "None of these",
+  "hashtag.column_settings.tag_mode.all": "Ĉiuj",
+  "hashtag.column_settings.tag_mode.any": "Iu ajn",
+  "hashtag.column_settings.tag_mode.none": "Neniu",
   "hashtag.column_settings.tag_toggle": "Include additional tags in this column",
   "home.column_settings.basic": "Bazaj agordoj",
   "home.column_settings.show_reblogs": "Montri diskonigojn",
   "home.column_settings.show_replies": "Montri respondojn",
   "keyboard_shortcuts.back": "por reveni",
-  "keyboard_shortcuts.blocked": "to open blocked users list",
+  "keyboard_shortcuts.blocked": "por malfermi la liston de blokitaj uzantoj",
   "keyboard_shortcuts.boost": "por diskonigi",
   "keyboard_shortcuts.column": "por fokusigi mesaĝon en unu el la kolumnoj",
   "keyboard_shortcuts.compose": "por fokusigi la tekstujon",
   "keyboard_shortcuts.description": "Priskribo",
-  "keyboard_shortcuts.direct": "to open direct messages column",
+  "keyboard_shortcuts.direct": "por malfermi la kolumnon de rektaj mesaĝoj",
   "keyboard_shortcuts.down": "por iri suben en la listo",
   "keyboard_shortcuts.enter": "por malfermi mesaĝon",
   "keyboard_shortcuts.favourite": "por stelumi",
-  "keyboard_shortcuts.favourites": "to open favourites list",
-  "keyboard_shortcuts.federated": "to open federated timeline",
+  "keyboard_shortcuts.favourites": "por malfermi la liston de stelumoj",
+  "keyboard_shortcuts.federated": "por malfermi la frataran tempolinion",
   "keyboard_shortcuts.heading": "Klavaraj mallongigoj",
-  "keyboard_shortcuts.home": "to open home timeline",
+  "keyboard_shortcuts.home": "por malfermi la hejman tempolinion",
   "keyboard_shortcuts.hotkey": "Rapidklavo",
   "keyboard_shortcuts.legend": "por montri ĉi tiun noton",
-  "keyboard_shortcuts.local": "to open local timeline",
+  "keyboard_shortcuts.local": "por malfermi la lokan tempolinion",
   "keyboard_shortcuts.mention": "por mencii la aŭtoron",
-  "keyboard_shortcuts.muted": "to open muted users list",
-  "keyboard_shortcuts.my_profile": "to open your profile",
-  "keyboard_shortcuts.notifications": "to open notifications column",
-  "keyboard_shortcuts.pinned": "to open pinned toots list",
+  "keyboard_shortcuts.muted": "por malfermi la liston de silentigitaj uzantoj",
+  "keyboard_shortcuts.my_profile": "por malfermi vian profilon",
+  "keyboard_shortcuts.notifications": "por malfermi la kolumnon de sciigoj",
+  "keyboard_shortcuts.pinned": "por malfermi la liston de alpinglitaj mesaĝoj",
   "keyboard_shortcuts.profile": "por malfermi la profilon de la aŭtoro",
   "keyboard_shortcuts.reply": "por respondi",
-  "keyboard_shortcuts.requests": "to open follow requests list",
+  "keyboard_shortcuts.requests": "por malfermi la liston de petoj de sekvado",
   "keyboard_shortcuts.search": "por fokusigi la serĉilon",
-  "keyboard_shortcuts.start": "to open \"get started\" column",
+  "keyboard_shortcuts.start": "por malfermi la kolumnon «por komenci»",
   "keyboard_shortcuts.toggle_hidden": "por montri/kaŝi tekston malantaŭ enhava averto",
   "keyboard_shortcuts.toot": "por komenci tute novan mesaĝon",
   "keyboard_shortcuts.unfocus": "por malfokusigi la tekstujon aŭ la serĉilon",
@@ -195,10 +196,10 @@
   "missing_indicator.label": "Ne trovita",
   "missing_indicator.sublabel": "Ĉi tiu elemento ne estis trovita",
   "mute_modal.hide_notifications": "Ĉu vi volas kaŝi la sciigojn el ĉi tiu uzanto?",
-  "navigation_bar.apps": "Mobile apps",
+  "navigation_bar.apps": "Telefonaj aplikaĵoj",
   "navigation_bar.blocks": "Blokitaj uzantoj",
   "navigation_bar.community_timeline": "Loka tempolinio",
-  "navigation_bar.compose": "Compose new toot",
+  "navigation_bar.compose": "Redakti novan mesaĝon",
   "navigation_bar.direct": "Rektaj mesaĝoj",
   "navigation_bar.discover": "Esplori",
   "navigation_bar.domain_blocks": "Kaŝitaj domajnoj",
@@ -291,7 +292,7 @@
   "status.cancel_reblog_private": "Eksdiskonigi",
   "status.cannot_reblog": "Ĉi tiu mesaĝo ne diskonigeblas",
   "status.delete": "Forigi",
-  "status.detailed_status": "Detailed conversation view",
+  "status.detailed_status": "Detala konversacia vido",
   "status.direct": "Rekte mesaĝi @{name}",
   "status.embed": "Enkorpigi",
   "status.favourite": "Stelumi",
@@ -305,11 +306,11 @@
   "status.open": "Grandigi",
   "status.pin": "Alpingli profile",
   "status.pinned": "Alpinglita mesaĝo",
-  "status.read_more": "Read more",
+  "status.read_more": "Legi pli",
   "status.reblog": "Diskonigi",
   "status.reblog_private": "Diskonigi al la originala atentaro",
   "status.reblogged_by": "{name} diskonigis",
-  "status.reblogs.empty": "No one has boosted this toot yet. When someone does, they will show up here.",
+  "status.reblogs.empty": "Neniu ankoraŭ diskonigis ĉi tiun mesaĝon. Kiam iu faris ĝin, tiu aperos ĉi tie.",
   "status.redraft": "Forigi kaj reskribi",
   "status.reply": "Respondi",
   "status.replyAll": "Respondi al la fadeno",
@@ -321,11 +322,11 @@
   "status.show_less_all": "Malgrandigi ĉiujn",
   "status.show_more": "Grandigi",
   "status.show_more_all": "Grandigi ĉiujn",
-  "status.show_thread": "Show thread",
+  "status.show_thread": "Montri fadenon",
   "status.unmute_conversation": "Malsilentigi konversacion",
   "status.unpin": "Depingli de profilo",
-  "suggestions.dismiss": "Dismiss suggestion",
-  "suggestions.header": "You might be interested in…",
+  "suggestions.dismiss": "Forigi la proponon",
+  "suggestions.header": "Vi povus interesiĝi pri…",
   "tabs_bar.federated_timeline": "Fratara tempolinio",
   "tabs_bar.home": "Hejmo",
   "tabs_bar.local_timeline": "Loka tempolinio",
@@ -334,7 +335,7 @@
   "trends.count_by_accounts": "{count} {rawCount, pluraj, unu {person} alia(j) {people}} parolas",
   "ui.beforeunload": "Via malneto perdiĝos se vi eliras de Mastodon.",
   "upload_area.title": "Altreni kaj lasi por alŝuti",
-  "upload_button.label": "Aldoni aŭdovidaĵon",
+  "upload_button.label": "Aldoni aŭdovidaĵon (JPEG, PNG, GIF, WebM, MP4, MOV)",
   "upload_form.description": "Priskribi por misvidantaj homoj",
   "upload_form.focus": "Stuci",
   "upload_form.undo": "Forigi",
diff --git a/app/javascript/mastodon/locales/es.json b/app/javascript/mastodon/locales/es.json
index 7b8cfe3f3..e05d7e010 100644
--- a/app/javascript/mastodon/locales/es.json
+++ b/app/javascript/mastodon/locales/es.json
@@ -17,6 +17,7 @@
   "account.follows_you": "Te sigue",
   "account.hide_reblogs": "Ocultar retoots de @{name}",
   "account.link_verified_on": "Ownership of this link was checked on {date}",
+  "account.locked_info": "This account privacy status is set to locked. The owner manually reviews who can follow them.",
   "account.media": "Media",
   "account.mention": "Mencionar a @{name}",
   "account.moved_to": "{name} se ha mudado a:",
diff --git a/app/javascript/mastodon/locales/eu.json b/app/javascript/mastodon/locales/eu.json
index 8ce3b9ba3..de4197604 100644
--- a/app/javascript/mastodon/locales/eu.json
+++ b/app/javascript/mastodon/locales/eu.json
@@ -1,5 +1,5 @@
 {
-  "account.add_or_remove_from_list": "Add or Remove from lists",
+  "account.add_or_remove_from_list": "Gehitu edo kendu zerrendetatik",
   "account.badges.bot": "Bot",
   "account.block": "Blokeatu @{name}",
   "account.block_domain": "Ezkutatu {domain} domeinuko guztia",
@@ -17,6 +17,7 @@
   "account.follows_you": "Jarraitzen dizu",
   "account.hide_reblogs": "Ezkutatu @{name}(r)en bultzadak",
   "account.link_verified_on": "Esteka honen jabetzaren egiaztaketa data: {date}",
+  "account.locked_info": "Kontu honen pribatutasun egoera blokeatuta gisa ezarri da. Jabeak eskuz erabakitzen du nork jarraitu diezaioken.",
   "account.media": "Media",
   "account.mention": "Aipatu @{name}",
   "account.moved_to": "{name} hona lekualdatu da:",
@@ -112,7 +113,7 @@
   "emoji_button.search_results": "Bilaketaren emaitzak",
   "emoji_button.symbols": "Sinboloak",
   "emoji_button.travel": "Bidaiak eta tokiak",
-  "empty_column.account_timeline": "No toots here!",
+  "empty_column.account_timeline": "Ez dago toot-ik hemen!",
   "empty_column.blocks": "Ez duzu erabiltzailerik blokeatu oraindik.",
   "empty_column.community": "Denbora-lerro lokala hutsik dago. Idatzi zerbait publikoki pilota biraka jartzeko!",
   "empty_column.direct": "Ez duzu mezu zuzenik oraindik. Baten bat bidali edo jasotzen duzunean, hemen agertuko da.",
@@ -138,12 +139,12 @@
   "getting_started.open_source_notice": "Mastodon software librea da. Ekarpenak egin ditzakezu edo akatsen berri eman GitHub bidez: {github}.",
   "getting_started.security": "Segurtasuna",
   "getting_started.terms": "Erabilera baldintzak",
-  "hashtag.column_header.tag_mode.all": "and {additional}",
-  "hashtag.column_header.tag_mode.any": "or {additional}",
-  "hashtag.column_header.tag_mode.none": "without {additional}",
-  "hashtag.column_settings.tag_mode.all": "All of these",
-  "hashtag.column_settings.tag_mode.any": "Any of these",
-  "hashtag.column_settings.tag_mode.none": "None of these",
+  "hashtag.column_header.tag_mode.all": "eta {osagarria}",
+  "hashtag.column_header.tag_mode.any": "edo {osagarria}",
+  "hashtag.column_header.tag_mode.none": "gabe {osagarria}",
+  "hashtag.column_settings.tag_mode.all": "Hauetako guztiak",
+  "hashtag.column_settings.tag_mode.any": "Hautako edozein",
+  "hashtag.column_settings.tag_mode.none": "Hauetako bat ere ez",
   "hashtag.column_settings.tag_toggle": "Include additional tags in this column",
   "home.column_settings.basic": "Oinarrizkoa",
   "home.column_settings.show_reblogs": "Erakutsi bultzadak",
@@ -315,13 +316,13 @@
   "status.replyAll": "Erantzun harian",
   "status.report": "Salatu @{name}",
   "status.sensitive_toggle": "Egin klik ikusteko",
-  "status.sensitive_warning": "Eduki hunkigarria",
+  "status.sensitive_warning": "Kontuz: Eduki hunkigarria",
   "status.share": "Partekatu",
   "status.show_less": "Erakutsi gutxiago",
   "status.show_less_all": "Erakutsi denetarik gutxiago",
   "status.show_more": "Erakutsi gehiago",
   "status.show_more_all": "Erakutsi denetarik gehiago",
-  "status.show_thread": "Show thread",
+  "status.show_thread": "Erakutsi haria",
   "status.unmute_conversation": "Desmututu elkarrizketa",
   "status.unpin": "Desfinkatu profiletik",
   "suggestions.dismiss": "Errefusatu proposamena",
diff --git a/app/javascript/mastodon/locales/fa.json b/app/javascript/mastodon/locales/fa.json
index befdb3804..4e00b4f2f 100644
--- a/app/javascript/mastodon/locales/fa.json
+++ b/app/javascript/mastodon/locales/fa.json
@@ -17,6 +17,7 @@
   "account.follows_you": "پیگیر شماست",
   "account.hide_reblogs": "پنهان کردن بازبوق‌های @{name}",
   "account.link_verified_on": "مالکیت این نشانی در تایخ {date} بررسی شد",
+  "account.locked_info": "This account privacy status is set to locked. The owner manually reviews who can follow them.",
   "account.media": "عکس و ویدیو",
   "account.mention": "نام‌بردن از @{name}",
   "account.moved_to": "{name} منتقل شده است به:",
diff --git a/app/javascript/mastodon/locales/fi.json b/app/javascript/mastodon/locales/fi.json
index bb1725533..a9de659e0 100644
--- a/app/javascript/mastodon/locales/fi.json
+++ b/app/javascript/mastodon/locales/fi.json
@@ -17,6 +17,7 @@
   "account.follows_you": "Seuraa sinua",
   "account.hide_reblogs": "Piilota buustaukset käyttäjältä @{name}",
   "account.link_verified_on": "Tämän linkin omistaja tarkistettiin {date}",
+  "account.locked_info": "This account privacy status is set to locked. The owner manually reviews who can follow them.",
   "account.media": "Media",
   "account.mention": "Mainitse @{name}",
   "account.moved_to": "{name} on muuttanut instanssiin:",
diff --git a/app/javascript/mastodon/locales/fr.json b/app/javascript/mastodon/locales/fr.json
index 85cafb18c..38fe07abd 100644
--- a/app/javascript/mastodon/locales/fr.json
+++ b/app/javascript/mastodon/locales/fr.json
@@ -1,5 +1,5 @@
 {
-  "account.add_or_remove_from_list": "Add or Remove from lists",
+  "account.add_or_remove_from_list": "Ajouter ou retirer des listes",
   "account.badges.bot": "Bot",
   "account.block": "Bloquer @{name}",
   "account.block_domain": "Tout masquer venant de {domain}",
@@ -17,6 +17,7 @@
   "account.follows_you": "Vous suit",
   "account.hide_reblogs": "Masquer les partages de @{name}",
   "account.link_verified_on": "La propriété de ce lien a été vérifiée le {date}",
+  "account.locked_info": "Ce compte est verrouillé. Son propriétaire approuve manuellement qui peut le ou la suivre.",
   "account.media": "Média",
   "account.mention": "Mentionner",
   "account.moved_to": "{name} a déménagé vers :",
@@ -112,7 +113,7 @@
   "emoji_button.search_results": "Résultats de la recherche",
   "emoji_button.symbols": "Symboles",
   "emoji_button.travel": "Lieux & Voyages",
-  "empty_column.account_timeline": "No toots here!",
+  "empty_column.account_timeline": "Aucun pouet ici !",
   "empty_column.blocks": "Vous n’avez bloqué aucun utilisateur pour le moment.",
   "empty_column.community": "Le fil public local est vide. Écrivez donc quelque chose pour le remplir !",
   "empty_column.direct": "Vous n’avez pas encore de messages directs. Lorsque vous en enverrez ou recevrez un, il s’affichera ici.",
@@ -138,12 +139,12 @@
   "getting_started.open_source_notice": "Mastodon est un logiciel libre. Vous pouvez contribuer et envoyer vos commentaires et rapports de bogues via {github} sur GitHub.",
   "getting_started.security": "Sécurité",
   "getting_started.terms": "Conditions d’utilisation",
-  "hashtag.column_header.tag_mode.all": "and {additional}",
-  "hashtag.column_header.tag_mode.any": "or {additional}",
-  "hashtag.column_header.tag_mode.none": "without {additional}",
-  "hashtag.column_settings.tag_mode.all": "All of these",
-  "hashtag.column_settings.tag_mode.any": "Any of these",
-  "hashtag.column_settings.tag_mode.none": "None of these",
+  "hashtag.column_header.tag_mode.all": "et {additional}",
+  "hashtag.column_header.tag_mode.any": "ou {additional}",
+  "hashtag.column_header.tag_mode.none": "sans {additional}",
+  "hashtag.column_settings.tag_mode.all": "Tous ces éléments",
+  "hashtag.column_settings.tag_mode.any": "Au moins un de ces éléments",
+  "hashtag.column_settings.tag_mode.none": "Aucun de ces éléments",
   "hashtag.column_settings.tag_toggle": "Include additional tags in this column",
   "home.column_settings.basic": "Basique",
   "home.column_settings.show_reblogs": "Afficher les partages",
@@ -321,7 +322,7 @@
   "status.show_less_all": "Tout replier",
   "status.show_more": "Déplier",
   "status.show_more_all": "Tout déplier",
-  "status.show_thread": "Show thread",
+  "status.show_thread": "Afficher le fil",
   "status.unmute_conversation": "Ne plus masquer la conversation",
   "status.unpin": "Retirer du profil",
   "suggestions.dismiss": "Rejeter la suggestion",
diff --git a/app/javascript/mastodon/locales/gl.json b/app/javascript/mastodon/locales/gl.json
index f2a8aec3a..02c27602f 100644
--- a/app/javascript/mastodon/locales/gl.json
+++ b/app/javascript/mastodon/locales/gl.json
@@ -1,5 +1,5 @@
 {
-  "account.add_or_remove_from_list": "Add or Remove from lists",
+  "account.add_or_remove_from_list": "Engadir ou Eliminar das listas",
   "account.badges.bot": "Bot",
   "account.block": "Bloquear @{name}",
   "account.block_domain": "Ocultar calquer contido de {domain}",
@@ -17,6 +17,7 @@
   "account.follows_you": "Séguena",
   "account.hide_reblogs": "Ocultar repeticións de @{name}",
   "account.link_verified_on": "A propiedade de esta ligazón foi comprobada en {date}",
+  "account.locked_info": "O estado da intimidade de esta conta estableceuse en pechado. A persoa dona da conta revisa quen pode seguila.",
   "account.media": "Medios",
   "account.mention": "Mencionar @{name}",
   "account.moved_to": "{name} marchou a:",
@@ -99,7 +100,7 @@
   "embed.instructions": "Copie o código inferior para incrustar no seu sitio web este estado.",
   "embed.preview": "Así será mostrado:",
   "emoji_button.activity": "Actividade",
-  "emoji_button.custom": "Personalizado",
+  "emoji_button.custom": "Persoalizado",
   "emoji_button.flags": "Marcas",
   "emoji_button.food": "Comida e Bebida",
   "emoji_button.label": "Insertar emoji",
@@ -112,7 +113,7 @@
   "emoji_button.search_results": "Resultados da busca",
   "emoji_button.symbols": "Símbolos",
   "emoji_button.travel": "Viaxes e Lugares",
-  "empty_column.account_timeline": "No toots here!",
+  "empty_column.account_timeline": "Sen toots por aquí!",
   "empty_column.blocks": "Non bloqueou ningunha usuaria polo de agora.",
   "empty_column.community": "A liña temporal local está baldeira. Escriba algo de xeito público para que rule!",
   "empty_column.direct": "Aínda non ten mensaxes directas. Cando envíe ou reciba unha, aparecerá aquí.",
@@ -138,12 +139,12 @@
   "getting_started.open_source_notice": "Mastodon é software de código aberto. Pode contribuír ou informar de fallos en GitHub en {github}.",
   "getting_started.security": "Seguridade",
   "getting_started.terms": "Termos do servizo",
-  "hashtag.column_header.tag_mode.all": "and {additional}",
-  "hashtag.column_header.tag_mode.any": "or {additional}",
-  "hashtag.column_header.tag_mode.none": "without {additional}",
-  "hashtag.column_settings.tag_mode.all": "All of these",
-  "hashtag.column_settings.tag_mode.any": "Any of these",
-  "hashtag.column_settings.tag_mode.none": "None of these",
+  "hashtag.column_header.tag_mode.all": "e {additional}",
+  "hashtag.column_header.tag_mode.any": "ou {additional}",
+  "hashtag.column_header.tag_mode.none": "sen {additional}",
+  "hashtag.column_settings.tag_mode.all": "Todos estos",
+  "hashtag.column_settings.tag_mode.any": "Calquera de estos",
+  "hashtag.column_settings.tag_mode.none": "Ningún de estos",
   "hashtag.column_settings.tag_toggle": "Include additional tags in this column",
   "home.column_settings.basic": "Básico",
   "home.column_settings.show_reblogs": "Mostrar repeticións",
@@ -211,7 +212,7 @@
   "navigation_bar.lists": "Listas",
   "navigation_bar.logout": "Sair",
   "navigation_bar.mutes": "Usuarias acaladas",
-  "navigation_bar.personal": "Personal",
+  "navigation_bar.personal": "Persoal",
   "navigation_bar.pins": "Mensaxes fixadas",
   "navigation_bar.preferences": "Preferencias",
   "navigation_bar.public_timeline": "Liña temporal federada",
@@ -321,7 +322,7 @@
   "status.show_less_all": "Mostrar menos para todas",
   "status.show_more": "Mostrar máis",
   "status.show_more_all": "Mostrar máis para todas",
-  "status.show_thread": "Show thread",
+  "status.show_thread": "Mostrar fío",
   "status.unmute_conversation": "Non acalar a conversa",
   "status.unpin": "Despegar do perfil",
   "suggestions.dismiss": "Rexeitar suxestión",
diff --git a/app/javascript/mastodon/locales/he.json b/app/javascript/mastodon/locales/he.json
index 3bcd825ae..9c891e2e8 100644
--- a/app/javascript/mastodon/locales/he.json
+++ b/app/javascript/mastodon/locales/he.json
@@ -17,6 +17,7 @@
   "account.follows_you": "במעקב אחריך",
   "account.hide_reblogs": "להסתיר הידהודים מאת @{name}",
   "account.link_verified_on": "Ownership of this link was checked on {date}",
+  "account.locked_info": "This account privacy status is set to locked. The owner manually reviews who can follow them.",
   "account.media": "מדיה",
   "account.mention": "אזכור של @{name}",
   "account.moved_to": "החשבון {name} הועבר אל:",
diff --git a/app/javascript/mastodon/locales/hr.json b/app/javascript/mastodon/locales/hr.json
index 33d2b3e37..ef6d482c1 100644
--- a/app/javascript/mastodon/locales/hr.json
+++ b/app/javascript/mastodon/locales/hr.json
@@ -17,6 +17,7 @@
   "account.follows_you": "te slijedi",
   "account.hide_reblogs": "Hide boosts from @{name}",
   "account.link_verified_on": "Ownership of this link was checked on {date}",
+  "account.locked_info": "This account privacy status is set to locked. The owner manually reviews who can follow them.",
   "account.media": "Media",
   "account.mention": "Spomeni @{name}",
   "account.moved_to": "{name} has moved to:",
diff --git a/app/javascript/mastodon/locales/hu.json b/app/javascript/mastodon/locales/hu.json
index 51d65f98c..85a513904 100644
--- a/app/javascript/mastodon/locales/hu.json
+++ b/app/javascript/mastodon/locales/hu.json
@@ -17,6 +17,7 @@
   "account.follows_you": "Követnek téged",
   "account.hide_reblogs": "Rejtsd el a tülkölést @{name}-tól/től",
   "account.link_verified_on": "Ownership of this link was checked on {date}",
+  "account.locked_info": "This account privacy status is set to locked. The owner manually reviews who can follow them.",
   "account.media": "Média",
   "account.mention": "@{name} említése",
   "account.moved_to": "{name} átköltözött:",
diff --git a/app/javascript/mastodon/locales/hy.json b/app/javascript/mastodon/locales/hy.json
index 76c96ff03..63a93b156 100644
--- a/app/javascript/mastodon/locales/hy.json
+++ b/app/javascript/mastodon/locales/hy.json
@@ -17,6 +17,7 @@
   "account.follows_you": "Հետեւում է քեզ",
   "account.hide_reblogs": "Թաքցնել @{name}֊ի տարածածները",
   "account.link_verified_on": "Ownership of this link was checked on {date}",
+  "account.locked_info": "This account privacy status is set to locked. The owner manually reviews who can follow them.",
   "account.media": "Մեդիա",
   "account.mention": "Նշել @{name}֊ին",
   "account.moved_to": "{name}֊ը տեղափոխվել է՝",
diff --git a/app/javascript/mastodon/locales/id.json b/app/javascript/mastodon/locales/id.json
index 5280d96c2..eed96f869 100644
--- a/app/javascript/mastodon/locales/id.json
+++ b/app/javascript/mastodon/locales/id.json
@@ -17,6 +17,7 @@
   "account.follows_you": "Mengikuti anda",
   "account.hide_reblogs": "Sembunyikan boosts dari @{name}",
   "account.link_verified_on": "Ownership of this link was checked on {date}",
+  "account.locked_info": "This account privacy status is set to locked. The owner manually reviews who can follow them.",
   "account.media": "Media",
   "account.mention": "Balasan @{name}",
   "account.moved_to": "{name} telah pindah ke:",
diff --git a/app/javascript/mastodon/locales/io.json b/app/javascript/mastodon/locales/io.json
index a8a162d82..a31cc12cb 100644
--- a/app/javascript/mastodon/locales/io.json
+++ b/app/javascript/mastodon/locales/io.json
@@ -17,6 +17,7 @@
   "account.follows_you": "Sequas tu",
   "account.hide_reblogs": "Hide boosts from @{name}",
   "account.link_verified_on": "Ownership of this link was checked on {date}",
+  "account.locked_info": "This account privacy status is set to locked. The owner manually reviews who can follow them.",
   "account.media": "Media",
   "account.mention": "Mencionar @{name}",
   "account.moved_to": "{name} has moved to:",
diff --git a/app/javascript/mastodon/locales/it.json b/app/javascript/mastodon/locales/it.json
index 7907909c5..2c1b59be9 100644
--- a/app/javascript/mastodon/locales/it.json
+++ b/app/javascript/mastodon/locales/it.json
@@ -1,5 +1,5 @@
 {
-  "account.add_or_remove_from_list": "Add or Remove from lists",
+  "account.add_or_remove_from_list": "Aggiungi o togli dalle liste",
   "account.badges.bot": "Bot",
   "account.block": "Blocca @{name}",
   "account.block_domain": "Nascondi tutto da {domain}",
@@ -17,6 +17,7 @@
   "account.follows_you": "Ti segue",
   "account.hide_reblogs": "Nascondi condivisioni da @{name}",
   "account.link_verified_on": "La proprietà di questo link è stata controllata il {date}",
+  "account.locked_info": "Il livello di privacy di questo account è impostato a \"bloccato\". Il proprietario esamina manualmente le richieste di seguirlo.",
   "account.media": "Media",
   "account.mention": "Menziona @{name}",
   "account.moved_to": "{name} si è trasferito su:",
@@ -112,7 +113,7 @@
   "emoji_button.search_results": "Risultati della ricerca",
   "emoji_button.symbols": "Simboli",
   "emoji_button.travel": "Viaggi e luoghi",
-  "empty_column.account_timeline": "No toots here!",
+  "empty_column.account_timeline": "Non ci sono toot qui!",
   "empty_column.blocks": "Non hai ancora bloccato nessun utente.",
   "empty_column.community": "La timeline locale è vuota. Condividi qualcosa pubblicamente per dare inizio alla festa!",
   "empty_column.direct": "Non hai ancora nessun messaggio diretto. Quando ne manderai o riceverai qualcuno, apparirà qui.",
@@ -138,12 +139,12 @@
   "getting_started.open_source_notice": "Mastodon è un software open source. Puoi contribuire o segnalare errori su GitHub all'indirizzo {github}.",
   "getting_started.security": "Sicurezza",
   "getting_started.terms": "Condizioni del servizio",
-  "hashtag.column_header.tag_mode.all": "and {additional}",
-  "hashtag.column_header.tag_mode.any": "or {additional}",
-  "hashtag.column_header.tag_mode.none": "without {additional}",
-  "hashtag.column_settings.tag_mode.all": "All of these",
-  "hashtag.column_settings.tag_mode.any": "Any of these",
-  "hashtag.column_settings.tag_mode.none": "None of these",
+  "hashtag.column_header.tag_mode.all": "e {additional}",
+  "hashtag.column_header.tag_mode.any": "o {additional}",
+  "hashtag.column_header.tag_mode.none": "senza {additional}",
+  "hashtag.column_settings.tag_mode.all": "Tutti questi",
+  "hashtag.column_settings.tag_mode.any": "Uno o più di questi",
+  "hashtag.column_settings.tag_mode.none": "Nessuno di questi",
   "hashtag.column_settings.tag_toggle": "Include additional tags in this column",
   "home.column_settings.basic": "Semplice",
   "home.column_settings.show_reblogs": "Mostra post condivisi",
@@ -321,7 +322,7 @@
   "status.show_less_all": "Mostra meno per tutti",
   "status.show_more": "Mostra di più",
   "status.show_more_all": "Mostra di più per tutti",
-  "status.show_thread": "Show thread",
+  "status.show_thread": "Mostra thread",
   "status.unmute_conversation": "Annulla silenzia conversazione",
   "status.unpin": "Non fissare in cima al profilo",
   "suggestions.dismiss": "Elimina suggerimento",
diff --git a/app/javascript/mastodon/locales/ja.json b/app/javascript/mastodon/locales/ja.json
index 06fe71e6b..4e8862201 100644
--- a/app/javascript/mastodon/locales/ja.json
+++ b/app/javascript/mastodon/locales/ja.json
@@ -17,6 +17,7 @@
   "account.follows_you": "フォローされています",
   "account.hide_reblogs": "@{name}さんからのブーストを非表示",
   "account.link_verified_on": "このリンクの所有権は{date}に確認されました",
+  "account.locked_info": "このアカウントは承認制に設定されています。フォローするには所有者の確認が必要です。",
   "account.media": "メディア",
   "account.mention": "@{name}さんにトゥート",
   "account.moved_to": "{name}さんは引っ越しました:",
@@ -139,7 +140,7 @@
   "getting_started.find_friends": "Twitterの友達を探す",
   "getting_started.heading": "スタート",
   "getting_started.invite": "招待",
-  "getting_started.open_source_notice": "Mastodonはオープンソースソフトウェアです。誰でもGitHub({github})から開発に参加したり、問題を報告したりできます。",
+  "getting_started.open_source_notice": "Mastodonはオープンソースソフトウェアです。誰でもGitHub ( {github} ) から開発に参加したり、問題を報告したりできます。",
   "getting_started.security": "セキュリティ",
   "getting_started.terms": "プライバシーポリシー",
   "hashtag.column_header.tag_mode.all": "と {additional}",
diff --git a/app/javascript/mastodon/locales/ka.json b/app/javascript/mastodon/locales/ka.json
index cbb639136..07129594f 100644
--- a/app/javascript/mastodon/locales/ka.json
+++ b/app/javascript/mastodon/locales/ka.json
@@ -17,6 +17,7 @@
   "account.follows_you": "მოგყვებათ",
   "account.hide_reblogs": "დაიმალოს ბუსტები @{name}-სგან",
   "account.link_verified_on": "Ownership of this link was checked on {date}",
+  "account.locked_info": "This account privacy status is set to locked. The owner manually reviews who can follow them.",
   "account.media": "მედია",
   "account.mention": "ასახელეთ @{name}",
   "account.moved_to": "{name} გადავიდა:",
diff --git a/app/javascript/mastodon/locales/ko.json b/app/javascript/mastodon/locales/ko.json
index cd481b9e5..b445823e7 100644
--- a/app/javascript/mastodon/locales/ko.json
+++ b/app/javascript/mastodon/locales/ko.json
@@ -17,6 +17,7 @@
   "account.follows_you": "날 팔로우합니다",
   "account.hide_reblogs": "@{name}의 부스트를 숨기기",
   "account.link_verified_on": "{date}에 이 링크의 소유권이 확인 됨",
+  "account.locked_info": "This account privacy status is set to locked. The owner manually reviews who can follow them.",
   "account.media": "미디어",
   "account.mention": "@{name}에게 글쓰기",
   "account.moved_to": "{name}는 계정을 이동했습니다:",
diff --git a/app/javascript/mastodon/locales/ms.json b/app/javascript/mastodon/locales/ms.json
index 3e243b743..d5176b01d 100644
--- a/app/javascript/mastodon/locales/ms.json
+++ b/app/javascript/mastodon/locales/ms.json
@@ -17,6 +17,7 @@
   "account.follows_you": "Follows you",
   "account.hide_reblogs": "Hide boosts from @{name}",
   "account.link_verified_on": "Ownership of this link was checked on {date}",
+  "account.locked_info": "This account privacy status is set to locked. The owner manually reviews who can follow them.",
   "account.media": "Media",
   "account.mention": "Mention @{name}",
   "account.moved_to": "{name} has moved to:",
diff --git a/app/javascript/mastodon/locales/nl.json b/app/javascript/mastodon/locales/nl.json
index d8dea93d6..0af479355 100644
--- a/app/javascript/mastodon/locales/nl.json
+++ b/app/javascript/mastodon/locales/nl.json
@@ -1,5 +1,5 @@
 {
-  "account.add_or_remove_from_list": "Add or Remove from lists",
+  "account.add_or_remove_from_list": "Toevoegen of verwijderen vanuit lijsten",
   "account.badges.bot": "Bot",
   "account.block": "Blokkeer @{name}",
   "account.block_domain": "Verberg alles van {domain}",
@@ -17,6 +17,7 @@
   "account.follows_you": "Volgt jou",
   "account.hide_reblogs": "Verberg boosts van @{name}",
   "account.link_verified_on": "Eigendom van deze link is gecontroleerd op {date}",
+  "account.locked_info": "De privacystatus van dit account is op besloten gezet. De eigenaar bepaalt handmatig wie hen kan volgen.",
   "account.media": "Media",
   "account.mention": "Vermeld @{name}",
   "account.moved_to": "{name} is verhuisd naar:",
@@ -112,7 +113,7 @@
   "emoji_button.search_results": "Zoekresultaten",
   "emoji_button.symbols": "Symbolen",
   "emoji_button.travel": "Reizen en plekken",
-  "empty_column.account_timeline": "No toots here!",
+  "empty_column.account_timeline": "Hier zijn geen toots!",
   "empty_column.blocks": "Jij hebt nog geen enkele gebruiker geblokkeerd.",
   "empty_column.community": "De lokale tijdlijn is nog leeg. Toot iets in het openbaar om de bal aan het rollen te krijgen!",
   "empty_column.direct": "Je hebt nog geen directe berichten. Wanneer je er een verzend of ontvangt, zijn deze hier te zien.",
@@ -138,12 +139,12 @@
   "getting_started.open_source_notice": "Mastodon is vrije software. Je kunt bijdragen of problemen melden op GitHub via {github}.",
   "getting_started.security": "Beveiliging",
   "getting_started.terms": "Voorwaarden",
-  "hashtag.column_header.tag_mode.all": "and {additional}",
-  "hashtag.column_header.tag_mode.any": "or {additional}",
-  "hashtag.column_header.tag_mode.none": "without {additional}",
-  "hashtag.column_settings.tag_mode.all": "All of these",
-  "hashtag.column_settings.tag_mode.any": "Any of these",
-  "hashtag.column_settings.tag_mode.none": "None of these",
+  "hashtag.column_header.tag_mode.all": "en {additional}",
+  "hashtag.column_header.tag_mode.any": "of {additional}",
+  "hashtag.column_header.tag_mode.none": "zonder {additional}",
+  "hashtag.column_settings.tag_mode.all": "Allemaal",
+  "hashtag.column_settings.tag_mode.any": "Een van deze",
+  "hashtag.column_settings.tag_mode.none": "Geen van deze",
   "hashtag.column_settings.tag_toggle": "Include additional tags in this column",
   "home.column_settings.basic": "Algemeen",
   "home.column_settings.show_reblogs": "Boosts tonen",
@@ -209,7 +210,7 @@
   "navigation_bar.info": "Over deze server",
   "navigation_bar.keyboard_shortcuts": "Sneltoetsen",
   "navigation_bar.lists": "Lijsten",
-  "navigation_bar.logout": "Afmelden",
+  "navigation_bar.logout": "Uitloggen",
   "navigation_bar.mutes": "Genegeerde gebruikers",
   "navigation_bar.personal": "Persoonlijk",
   "navigation_bar.pins": "Vastgezette toots",
@@ -321,7 +322,7 @@
   "status.show_less_all": "Alles minder tonen",
   "status.show_more": "Meer tonen",
   "status.show_more_all": "Alles meer tonen",
-  "status.show_thread": "Show thread",
+  "status.show_thread": "Gesprek tonen",
   "status.unmute_conversation": "Gesprek niet langer negeren",
   "status.unpin": "Van profielpagina losmaken",
   "suggestions.dismiss": "Suggestie verwerpen",
diff --git a/app/javascript/mastodon/locales/no.json b/app/javascript/mastodon/locales/no.json
index ea4e76de4..39c236564 100644
--- a/app/javascript/mastodon/locales/no.json
+++ b/app/javascript/mastodon/locales/no.json
@@ -17,6 +17,7 @@
   "account.follows_you": "Følger deg",
   "account.hide_reblogs": "Skjul fremhevinger fra @{name}",
   "account.link_verified_on": "Ownership of this link was checked on {date}",
+  "account.locked_info": "This account privacy status is set to locked. The owner manually reviews who can follow them.",
   "account.media": "Media",
   "account.mention": "Nevn @{name}",
   "account.moved_to": "{name} har flyttet til:",
diff --git a/app/javascript/mastodon/locales/oc.json b/app/javascript/mastodon/locales/oc.json
index a94e0336d..072781e77 100644
--- a/app/javascript/mastodon/locales/oc.json
+++ b/app/javascript/mastodon/locales/oc.json
@@ -150,32 +150,32 @@
   "home.column_settings.show_reblogs": "Mostrar los partatges",
   "home.column_settings.show_replies": "Mostrar las responsas",
   "keyboard_shortcuts.back": "anar enrèire",
-  "keyboard_shortcuts.blocked": "per dobrir la lista d’utilizaires blocats",
+  "keyboard_shortcuts.blocked": "dobrir la lista d’utilizaires blocats",
   "keyboard_shortcuts.boost": "partejar",
   "keyboard_shortcuts.column": "centrar un estatut a una colomna",
   "keyboard_shortcuts.compose": "anar al camp tèxte",
-  "keyboard_shortcuts.description": "Descripcion",
-  "keyboard_shortcuts.direct": "per dobrir la colomna de messatges dirèctes",
+  "keyboard_shortcuts.description": "descripcion",
+  "keyboard_shortcuts.direct": "dobrir la colomna de messatges dirèctes",
   "keyboard_shortcuts.down": "far davalar dins la lista",
   "keyboard_shortcuts.enter": "dobrir los estatuts",
   "keyboard_shortcuts.favourite": "apondre als favorits",
-  "keyboard_shortcuts.favourites": "per dobrir la lista de favorits",
-  "keyboard_shortcuts.federated": "per dobrir lo flux public global",
+  "keyboard_shortcuts.favourites": "dobrir la lista de favorits",
+  "keyboard_shortcuts.federated": "dobrir lo flux public global",
   "keyboard_shortcuts.heading": "Acorchis clavièr",
-  "keyboard_shortcuts.home": "per dobrir lo flux public local",
+  "keyboard_shortcuts.home": "dobrir lo flux public local",
   "keyboard_shortcuts.hotkey": "Acorchis",
   "keyboard_shortcuts.legend": "mostrar aquesta legenda",
-  "keyboard_shortcuts.local": "per dobrir lo flux public local",
+  "keyboard_shortcuts.local": "dobrir lo flux public local",
   "keyboard_shortcuts.mention": "mencionar l’autor",
-  "keyboard_shortcuts.muted": "per dobrir la lista dels utilizaires silenciats",
-  "keyboard_shortcuts.my_profile": "per dobrir vòstre perfil",
-  "keyboard_shortcuts.notifications": "per dobrir la colomna de notificacions",
-  "keyboard_shortcuts.pinned": "per dobrir la lista dels tuts penjats",
-  "keyboard_shortcuts.profile": "per dobrir lo perfil de l’autor",
+  "keyboard_shortcuts.muted": "dobrir la lista dels utilizaires silenciats",
+  "keyboard_shortcuts.my_profile": "dobrir vòstre perfil",
+  "keyboard_shortcuts.notifications": "dobrir la colomna de notificacions",
+  "keyboard_shortcuts.pinned": "dobrir la lista dels tuts penjats",
+  "keyboard_shortcuts.profile": "dobrir lo perfil de l’autor",
   "keyboard_shortcuts.reply": "respondre",
-  "keyboard_shortcuts.requests": "per dorbir la lista de demanda d’abonament",
+  "keyboard_shortcuts.requests": "dorbir la lista de demanda d’abonament",
   "keyboard_shortcuts.search": "anar a la recèrca",
-  "keyboard_shortcuts.start": "per dobrir la colomna «Per començar»",
+  "keyboard_shortcuts.start": "dobrir la colomna « Per començar »",
   "keyboard_shortcuts.toggle_hidden": "mostrar/amagar lo tèxte dels avertiments",
   "keyboard_shortcuts.toot": "començar un estatut tot novèl",
   "keyboard_shortcuts.unfocus": "quitar lo camp tèxte/de recèrca",
diff --git a/app/javascript/mastodon/locales/pt-BR.json b/app/javascript/mastodon/locales/pt-BR.json
index 61811c53d..31c581aad 100644
--- a/app/javascript/mastodon/locales/pt-BR.json
+++ b/app/javascript/mastodon/locales/pt-BR.json
@@ -1,5 +1,5 @@
 {
-  "account.add_or_remove_from_list": "Add or Remove from lists",
+  "account.add_or_remove_from_list": "Adicionar ou remover de listas",
   "account.badges.bot": "Robô",
   "account.block": "Bloquear @{name}",
   "account.block_domain": "Esconder tudo de {domain}",
@@ -17,6 +17,7 @@
   "account.follows_you": "Segue você",
   "account.hide_reblogs": "Esconder compartilhamentos de @{name}",
   "account.link_verified_on": "A posse desse link foi verificada em {date}",
+  "account.locked_info": "Essa conta está trancada. Se você a seguir sua solicitação será revisada manualmente.",
   "account.media": "Mídia",
   "account.mention": "Mencionar @{name}",
   "account.moved_to": "{name} se mudou para:",
@@ -112,7 +113,7 @@
   "emoji_button.search_results": "Resultados da busca",
   "emoji_button.symbols": "Símbolos",
   "emoji_button.travel": "Viagens & Lugares",
-  "empty_column.account_timeline": "No toots here!",
+  "empty_column.account_timeline": "Não há toots aqui!",
   "empty_column.blocks": "Você ainda não bloqueou nenhum usuário.",
   "empty_column.community": "A timeline local está vazia. Escreva algo publicamente para começar!",
   "empty_column.direct": "Você não tem nenhuma mensagem direta ainda. Quando você enviar ou receber uma, as mensagens aparecerão por aqui.",
@@ -138,12 +139,12 @@
   "getting_started.open_source_notice": "Mastodon é um software de código aberto. Você pode contribuir ou reportar problemas na página do GitHub do projeto: {github}.",
   "getting_started.security": "Segurança",
   "getting_started.terms": "Termos de serviço",
-  "hashtag.column_header.tag_mode.all": "and {additional}",
-  "hashtag.column_header.tag_mode.any": "or {additional}",
-  "hashtag.column_header.tag_mode.none": "without {additional}",
-  "hashtag.column_settings.tag_mode.all": "All of these",
-  "hashtag.column_settings.tag_mode.any": "Any of these",
-  "hashtag.column_settings.tag_mode.none": "None of these",
+  "hashtag.column_header.tag_mode.all": "e {additional}",
+  "hashtag.column_header.tag_mode.any": "ou {additional}",
+  "hashtag.column_header.tag_mode.none": "sem {additional}",
+  "hashtag.column_settings.tag_mode.all": "Todas essas",
+  "hashtag.column_settings.tag_mode.any": "Qualquer uma dessas",
+  "hashtag.column_settings.tag_mode.none": "Nenhuma dessas",
   "hashtag.column_settings.tag_toggle": "Include additional tags in this column",
   "home.column_settings.basic": "Básico",
   "home.column_settings.show_reblogs": "Mostrar compartilhamentos",
@@ -321,11 +322,11 @@
   "status.show_less_all": "Mostrar menos para todas as mensagens",
   "status.show_more": "Mostrar mais",
   "status.show_more_all": "Mostrar mais para todas as mensagens",
-  "status.show_thread": "Show thread",
+  "status.show_thread": "Mostrar sequência",
   "status.unmute_conversation": "Desativar silêncio desta conversa",
   "status.unpin": "Desafixar do perfil",
-  "suggestions.dismiss": "Dismiss suggestion",
-  "suggestions.header": "You might be interested in…",
+  "suggestions.dismiss": "Ignorar a sugestão",
+  "suggestions.header": "Você pode se interessar por…",
   "tabs_bar.federated_timeline": "Global",
   "tabs_bar.home": "Página inicial",
   "tabs_bar.local_timeline": "Local",
diff --git a/app/javascript/mastodon/locales/pt.json b/app/javascript/mastodon/locales/pt.json
index c03001080..cf56df025 100644
--- a/app/javascript/mastodon/locales/pt.json
+++ b/app/javascript/mastodon/locales/pt.json
@@ -17,6 +17,7 @@
   "account.follows_you": "É teu seguidor",
   "account.hide_reblogs": "Esconder partilhas de @{name}",
   "account.link_verified_on": "Ownership of this link was checked on {date}",
+  "account.locked_info": "This account privacy status is set to locked. The owner manually reviews who can follow them.",
   "account.media": "Media",
   "account.mention": "Mencionar @{name}",
   "account.moved_to": "{name} mudou a sua conta para:",
diff --git a/app/javascript/mastodon/locales/ro.json b/app/javascript/mastodon/locales/ro.json
index fc196e820..d262b57b7 100644
--- a/app/javascript/mastodon/locales/ro.json
+++ b/app/javascript/mastodon/locales/ro.json
@@ -17,6 +17,7 @@
   "account.follows_you": "Te urmărește",
   "account.hide_reblogs": "Ascunde redistribuirile de la @{name}",
   "account.link_verified_on": "Ownership of this link was checked on {date}",
+  "account.locked_info": "This account privacy status is set to locked. The owner manually reviews who can follow them.",
   "account.media": "Media",
   "account.mention": "Menționează @{name}",
   "account.moved_to": "{name} a fost mutat la:",
diff --git a/app/javascript/mastodon/locales/ru.json b/app/javascript/mastodon/locales/ru.json
index 3e2979c1b..b1eb76afb 100644
--- a/app/javascript/mastodon/locales/ru.json
+++ b/app/javascript/mastodon/locales/ru.json
@@ -17,6 +17,7 @@
   "account.follows_you": "Подписан(а) на Вас",
   "account.hide_reblogs": "Скрыть продвижения от @{name}",
   "account.link_verified_on": "Ownership of this link was checked on {date}",
+  "account.locked_info": "This account privacy status is set to locked. The owner manually reviews who can follow them.",
   "account.media": "Медиа",
   "account.mention": "Упомянуть",
   "account.moved_to": "Ищите {name} здесь:",
diff --git a/app/javascript/mastodon/locales/sk.json b/app/javascript/mastodon/locales/sk.json
index e03cdef89..7b14118a3 100644
--- a/app/javascript/mastodon/locales/sk.json
+++ b/app/javascript/mastodon/locales/sk.json
@@ -1,5 +1,5 @@
 {
-  "account.add_or_remove_from_list": "Add or Remove from lists",
+  "account.add_or_remove_from_list": "Pridaj, alebo odstráň zo zoznamov",
   "account.badges.bot": "Bot",
   "account.block": "Blokuj @{name}",
   "account.block_domain": "Ukry všetko z {domain}",
@@ -13,10 +13,11 @@
   "account.followers": "Sledujúci",
   "account.followers.empty": "Tohto užívateľa ešte nikto nenásleduje.",
   "account.follows": "Následuje",
-  "account.follows.empty": "Tento užívateľ ešte nikoho nenásleduje.",
+  "account.follows.empty": "Tento užívateľ tu ešte nikoho nenásleduje.",
   "account.follows_you": "Následuje ťa",
   "account.hide_reblogs": "Skryť povýšenia od @{name}",
   "account.link_verified_on": "Vlastníctvo tohto odkazu bolo skontrolované {date}",
+  "account.locked_info": "Stav súkromia pre tento účet je nastavený na zamknutý. Jeho vlastník sám prehodnocuje, kto ho môže sledovať.",
   "account.media": "Médiá",
   "account.mention": "Spomeň @{name}",
   "account.moved_to": "{name} sa presunul/a na:",
@@ -24,7 +25,7 @@
   "account.mute_notifications": "Stĺmiť oboznámenia od @{name}",
   "account.muted": "Utíšený/á",
   "account.posts": "Hlášky",
-  "account.posts_with_replies": "Príspevky s odpoveďami",
+  "account.posts_with_replies": "Hlášky s odpoveďami",
   "account.report": "Nahlás @{name}",
   "account.requested": "Čaká na schválenie. Kliknite pre zrušenie žiadosti",
   "account.share": "Zdieľať @{name} profil",
@@ -55,7 +56,7 @@
   "column.lists": "Zoznamy",
   "column.mutes": "Ignorovaní užívatelia",
   "column.notifications": "Oboznámenia",
-  "column.pins": "Pripnuté príspevky",
+  "column.pins": "Pripnuté hlášky",
   "column.public": "Federovaná časová os",
   "column_back_button.label": "Späť",
   "column_header.hide_settings": "Skryť nastavenia",
@@ -112,7 +113,7 @@
   "emoji_button.search_results": "Nájdené",
   "emoji_button.symbols": "Symboly",
   "emoji_button.travel": "Cestovanie a miesta",
-  "empty_column.account_timeline": "No toots here!",
+  "empty_column.account_timeline": "Niesú tu žiadne príspevky!",
   "empty_column.blocks": "Ešte si nikoho nezablokoval/a.",
   "empty_column.community": "Lokálna časová os je prázdna. Napíšte niečo, aby sa to tu začalo hýbať!",
   "empty_column.direct": "Ešte nemáš žiadne súkromné správy. Keď nejakú pošleš, alebo dostaneš, ukáže sa tu.",
@@ -138,12 +139,12 @@
   "getting_started.open_source_notice": "Mastodon je softvér s otvoreným kódom. Nahlásiť chyby, alebo prispievať môžeš na GitHube v {github}.",
   "getting_started.security": "Zabezpečenie",
   "getting_started.terms": "Podmienky prevozu",
-  "hashtag.column_header.tag_mode.all": "and {additional}",
-  "hashtag.column_header.tag_mode.any": "or {additional}",
-  "hashtag.column_header.tag_mode.none": "without {additional}",
-  "hashtag.column_settings.tag_mode.all": "All of these",
-  "hashtag.column_settings.tag_mode.any": "Any of these",
-  "hashtag.column_settings.tag_mode.none": "None of these",
+  "hashtag.column_header.tag_mode.all": "a {additional}",
+  "hashtag.column_header.tag_mode.any": "alebo {additional}",
+  "hashtag.column_header.tag_mode.none": "bez {additional}",
+  "hashtag.column_settings.tag_mode.all": "Všetky tieto",
+  "hashtag.column_settings.tag_mode.any": "Hociktorý z týchto",
+  "hashtag.column_settings.tag_mode.none": "Žiaden z týchto",
   "hashtag.column_settings.tag_toggle": "Include additional tags in this column",
   "home.column_settings.basic": "Základné",
   "home.column_settings.show_reblogs": "Zobraziť povýšené",
@@ -193,8 +194,8 @@
   "loading_indicator.label": "Načítam...",
   "media_gallery.toggle_visible": "Zapnúť/Vypnúť viditeľnosť",
   "missing_indicator.label": "Nenájdené",
-  "missing_indicator.sublabel": "Tento zdroj sa nepodarilo nájsť",
-  "mute_modal.hide_notifications": "Skryť notifikácie od tohoto užívateľa?",
+  "missing_indicator.sublabel": "Tento zdroj sa ešte nepodarilo nájsť",
+  "mute_modal.hide_notifications": "Skryť oboznámenia od tohoto užívateľa?",
   "navigation_bar.apps": "Mobilné aplikácie",
   "navigation_bar.blocks": "Blokovaní užívatelia",
   "navigation_bar.community_timeline": "Lokálna časová os",
@@ -233,7 +234,7 @@
   "notifications.group": "{count} oznámenia",
   "onboarding.done": "Koniec",
   "onboarding.next": "Ďalej",
-  "onboarding.page_five.public_timelines": "Lokálna časová os zobrazuje verejné správy od všetkých na {domain}. Federovaná časová os zobrazuje verejné správy od všetkých tých, čo následujú užívatrľov {domain} z iných serverov. Tieto sú takzvané Verejné Časové Osi, výborná možnosť ako nájsť a spoznať nových ľudí.",
+  "onboarding.page_five.public_timelines": "Lokálna časová os zobrazuje verejné správy od všetkých na {domain}. Federovaná časová os zobrazuje verejné správy od všetkých tých, čo následujú užívateľov {domain} z iných serverov. Tieto sú takzvané Verejné Časové Osi, výborná možnosť ako nájsť a spoznať nových ľudí.",
   "onboarding.page_four.home": "Domovská časová os zobrazí správy od ľudí ktorých sledujete.",
   "onboarding.page_four.notifications": "Stĺpec s notifikáciami zobrazí keď budete s niekým komunikovať.",
   "onboarding.page_one.federation": "Mastodon je sieť nezávislých serverov, spojením ktorých vzniká jedna veľká federovaná sociálna sieť.",
@@ -284,8 +285,8 @@
   "search_popout.tips.user": "používateľ",
   "search_results.accounts": "Ľudia",
   "search_results.hashtags": "Haštagy",
-  "search_results.statuses": "Príspevky",
-  "search_results.total": "{count, number} {count, plural, jeden {výsledok} ostatné {výsledky}}",
+  "search_results.statuses": "Hlášky",
+  "search_results.total": "{count, number} {count, plural, one {výsledok} many {výsledkov} other {výsledky}}",
   "standalone.public_title": "Náhľad dovnútra...",
   "status.block": "Blokovať @{name}",
   "status.cancel_reblog_private": "Nezdieľaj",
@@ -321,9 +322,9 @@
   "status.show_less_all": "Všetkým ukáž menej",
   "status.show_more": "Ukáž viac",
   "status.show_more_all": "Všetkým ukáž viac",
-  "status.show_thread": "Show thread",
-  "status.unmute_conversation": "Prestať ignorovať konverzáciu",
-  "status.unpin": "Odopnúť z profilu",
+  "status.show_thread": "Ukáž diskusné vlákno",
+  "status.unmute_conversation": "Prestaň ignorovať konverzáciu",
+  "status.unpin": "Odopni z profilu",
   "suggestions.dismiss": "Zavrhni návrh",
   "suggestions.header": "Mohlo by ťa zaujímať…",
   "tabs_bar.federated_timeline": "Federovaná",
@@ -331,7 +332,7 @@
   "tabs_bar.local_timeline": "Lokálna",
   "tabs_bar.notifications": "Notifikácie",
   "tabs_bar.search": "Hľadaj",
-  "trends.count_by_accounts": "{count} {rawCount, viacerí, jeden {person} iní {people}} diskutujú",
+  "trends.count_by_accounts": "{count} {rawCount, plural, one {človek vraví} other {ľudia vravia}}",
   "ui.beforeunload": "Čo máš rozpísané sa stratí, ak opustíš Mastodon.",
   "upload_area.title": "Pretiahni a pusť pre nahratie",
   "upload_button.label": "Pridať médiálny súbor (JPEG, PNG, GIF, WebM, MP4, MOV)",
diff --git a/app/javascript/mastodon/locales/sl.json b/app/javascript/mastodon/locales/sl.json
index 080ab8ffc..b85769f96 100644
--- a/app/javascript/mastodon/locales/sl.json
+++ b/app/javascript/mastodon/locales/sl.json
@@ -17,6 +17,7 @@
   "account.follows_you": "Ti sledi",
   "account.hide_reblogs": "Skrij sunke od @{name}",
   "account.link_verified_on": "Lastništvo te povezave je bilo preverjeno {date}",
+  "account.locked_info": "This account privacy status is set to locked. The owner manually reviews who can follow them.",
   "account.media": "Mediji",
   "account.mention": "Omeni @{name}",
   "account.moved_to": "{name} se je premaknil na:",
diff --git a/app/javascript/mastodon/locales/sr-Latn.json b/app/javascript/mastodon/locales/sr-Latn.json
index feaeb95c1..6bc84adc3 100644
--- a/app/javascript/mastodon/locales/sr-Latn.json
+++ b/app/javascript/mastodon/locales/sr-Latn.json
@@ -17,6 +17,7 @@
   "account.follows_you": "Prati Vas",
   "account.hide_reblogs": "Sakrij podrške koje daje korisnika @{name}",
   "account.link_verified_on": "Ownership of this link was checked on {date}",
+  "account.locked_info": "This account privacy status is set to locked. The owner manually reviews who can follow them.",
   "account.media": "Mediji",
   "account.mention": "Pomeni korisnika @{name}",
   "account.moved_to": "{name} se pomerio na:",
diff --git a/app/javascript/mastodon/locales/sr.json b/app/javascript/mastodon/locales/sr.json
index 7e3c3f213..a6dc1fc06 100644
--- a/app/javascript/mastodon/locales/sr.json
+++ b/app/javascript/mastodon/locales/sr.json
@@ -17,6 +17,7 @@
   "account.follows_you": "Прати Вас",
   "account.hide_reblogs": "Сакриј подршке које даје корисника @{name}",
   "account.link_verified_on": "Ownership of this link was checked on {date}",
+  "account.locked_info": "This account privacy status is set to locked. The owner manually reviews who can follow them.",
   "account.media": "Медији",
   "account.mention": "Помени корисника @{name}",
   "account.moved_to": "{name} се померио на:",
diff --git a/app/javascript/mastodon/locales/sv.json b/app/javascript/mastodon/locales/sv.json
index 6910b181d..940f49c78 100644
--- a/app/javascript/mastodon/locales/sv.json
+++ b/app/javascript/mastodon/locales/sv.json
@@ -17,6 +17,7 @@
   "account.follows_you": "Följer dig",
   "account.hide_reblogs": "Dölj knuffar från @{name}",
   "account.link_verified_on": "Ownership of this link was checked on {date}",
+  "account.locked_info": "This account privacy status is set to locked. The owner manually reviews who can follow them.",
   "account.media": "Media",
   "account.mention": "Nämna @{name}",
   "account.moved_to": "{name} har flyttat till:",
diff --git a/app/javascript/mastodon/locales/ta.json b/app/javascript/mastodon/locales/ta.json
index 3e243b743..d5176b01d 100644
--- a/app/javascript/mastodon/locales/ta.json
+++ b/app/javascript/mastodon/locales/ta.json
@@ -17,6 +17,7 @@
   "account.follows_you": "Follows you",
   "account.hide_reblogs": "Hide boosts from @{name}",
   "account.link_verified_on": "Ownership of this link was checked on {date}",
+  "account.locked_info": "This account privacy status is set to locked. The owner manually reviews who can follow them.",
   "account.media": "Media",
   "account.mention": "Mention @{name}",
   "account.moved_to": "{name} has moved to:",
diff --git a/app/javascript/mastodon/locales/te.json b/app/javascript/mastodon/locales/te.json
index e5cfe4240..86616ff42 100644
--- a/app/javascript/mastodon/locales/te.json
+++ b/app/javascript/mastodon/locales/te.json
@@ -17,6 +17,7 @@
   "account.follows_you": "మిమ్మల్ని అనుసరిస్తున్నారు",
   "account.hide_reblogs": "@{name} నుంచి బూస్ట్ లను దాచిపెట్టు",
   "account.link_verified_on": "ఈ లంకె యొక్క యాజమాన్యం {date}న పరీక్షించబడింది",
+  "account.locked_info": "This account privacy status is set to locked. The owner manually reviews who can follow them.",
   "account.media": "మీడియా",
   "account.mention": "@{name}ను ప్రస్తావించు",
   "account.moved_to": "{name} ఇక్కడికి మారారు:",
diff --git a/app/javascript/mastodon/locales/th.json b/app/javascript/mastodon/locales/th.json
index a85cc63dc..92dd29871 100644
--- a/app/javascript/mastodon/locales/th.json
+++ b/app/javascript/mastodon/locales/th.json
@@ -17,6 +17,7 @@
   "account.follows_you": "Follows you",
   "account.hide_reblogs": "Hide boosts from @{name}",
   "account.link_verified_on": "Ownership of this link was checked on {date}",
+  "account.locked_info": "This account privacy status is set to locked. The owner manually reviews who can follow them.",
   "account.media": "Media",
   "account.mention": "Mention @{name}",
   "account.moved_to": "{name} has moved to:",
diff --git a/app/javascript/mastodon/locales/tr.json b/app/javascript/mastodon/locales/tr.json
index e1d0f33c4..64a6204aa 100644
--- a/app/javascript/mastodon/locales/tr.json
+++ b/app/javascript/mastodon/locales/tr.json
@@ -17,6 +17,7 @@
   "account.follows_you": "Seni takip ediyor",
   "account.hide_reblogs": "Hide boosts from @{name}",
   "account.link_verified_on": "Ownership of this link was checked on {date}",
+  "account.locked_info": "This account privacy status is set to locked. The owner manually reviews who can follow them.",
   "account.media": "Media",
   "account.mention": "Bahset @{name}",
   "account.moved_to": "{name} has moved to:",
diff --git a/app/javascript/mastodon/locales/uk.json b/app/javascript/mastodon/locales/uk.json
index 08c30833b..c75940c25 100644
--- a/app/javascript/mastodon/locales/uk.json
+++ b/app/javascript/mastodon/locales/uk.json
@@ -17,6 +17,7 @@
   "account.follows_you": "Підписаний(-а) на Вас",
   "account.hide_reblogs": "Сховати передмухи від @{name}",
   "account.link_verified_on": "Ownership of this link was checked on {date}",
+  "account.locked_info": "This account privacy status is set to locked. The owner manually reviews who can follow them.",
   "account.media": "Медіа",
   "account.mention": "Згадати @{name}",
   "account.moved_to": "{name} переїхав на:",
diff --git a/app/javascript/mastodon/locales/zh-CN.json b/app/javascript/mastodon/locales/zh-CN.json
index e24910153..da5cf4798 100644
--- a/app/javascript/mastodon/locales/zh-CN.json
+++ b/app/javascript/mastodon/locales/zh-CN.json
@@ -17,6 +17,7 @@
   "account.follows_you": "关注了你",
   "account.hide_reblogs": "隐藏来自 @{name} 的转嘟",
   "account.link_verified_on": "Ownership of this link was checked on {date}",
+  "account.locked_info": "This account privacy status is set to locked. The owner manually reviews who can follow them.",
   "account.media": "媒体",
   "account.mention": "提及 @{name}",
   "account.moved_to": "{name} 已经迁移到:",
diff --git a/app/javascript/mastodon/locales/zh-HK.json b/app/javascript/mastodon/locales/zh-HK.json
index 7e1d4c73b..16e803d92 100644
--- a/app/javascript/mastodon/locales/zh-HK.json
+++ b/app/javascript/mastodon/locales/zh-HK.json
@@ -17,6 +17,7 @@
   "account.follows_you": "關注你",
   "account.hide_reblogs": "隱藏 @{name} 的轉推",
   "account.link_verified_on": "Ownership of this link was checked on {date}",
+  "account.locked_info": "This account privacy status is set to locked. The owner manually reviews who can follow them.",
   "account.media": "媒體",
   "account.mention": "提及 @{name}",
   "account.moved_to": "{name} 已經遷移到:",
diff --git a/app/javascript/mastodon/locales/zh-TW.json b/app/javascript/mastodon/locales/zh-TW.json
index 4261c9345..d2256c259 100644
--- a/app/javascript/mastodon/locales/zh-TW.json
+++ b/app/javascript/mastodon/locales/zh-TW.json
@@ -17,6 +17,7 @@
   "account.follows_you": "關注你",
   "account.hide_reblogs": "隱藏來自 @{name} 的轉推",
   "account.link_verified_on": "Ownership of this link was checked on {date}",
+  "account.locked_info": "This account privacy status is set to locked. The owner manually reviews who can follow them.",
   "account.media": "媒體",
   "account.mention": "提到 @{name}",
   "account.moved_to": "{name} 已經移至:",
diff --git a/app/javascript/mastodon/reducers/timelines.js b/app/javascript/mastodon/reducers/timelines.js
index 664d65151..beab2ea03 100644
--- a/app/javascript/mastodon/reducers/timelines.js
+++ b/app/javascript/mastodon/reducers/timelines.js
@@ -26,10 +26,10 @@ const initialTimeline = ImmutableMap({
   items: ImmutableList(),
 });
 
-const expandNormalizedTimeline = (state, timeline, statuses, next, isPartial) => {
+const expandNormalizedTimeline = (state, timeline, statuses, next, isPartial, isLoadingRecent) => {
   return state.update(timeline, initialTimeline, map => map.withMutations(mMap => {
     mMap.set('isLoading', false);
-    if (!next) mMap.set('hasMore', false);
+    if (!next && !isLoadingRecent) mMap.set('hasMore', false);
 
     if (!statuses.isEmpty()) {
       mMap.update('items', ImmutableList(), oldIds => {
@@ -126,7 +126,7 @@ export default function timelines(state = initialState, action) {
   case TIMELINE_EXPAND_FAIL:
     return state.update(action.timeline, initialTimeline, map => map.set('isLoading', false));
   case TIMELINE_EXPAND_SUCCESS:
-    return expandNormalizedTimeline(state, action.timeline, fromJS(action.statuses), action.next, action.partial);
+    return expandNormalizedTimeline(state, action.timeline, fromJS(action.statuses), action.next, action.partial, action.isLoadingRecent);
   case TIMELINE_UPDATE:
     return updateTimeline(state, action.timeline, fromJS(action.status));
   case TIMELINE_DELETE:
diff --git a/app/javascript/styles/mastodon/forms.scss b/app/javascript/styles/mastodon/forms.scss
index 4f96204f2..6132dd1ae 100644
--- a/app/javascript/styles/mastodon/forms.scss
+++ b/app/javascript/styles/mastodon/forms.scss
@@ -420,6 +420,7 @@ code {
     border: 1px solid darken($ui-base-color, 14%);
     border-radius: 4px;
     padding: 10px;
+    padding-right: 30px;
     height: 41px;
   }