From 26ab702304138be6a03eb7c428ac8b0f93cef114 Mon Sep 17 00:00:00 2001 From: asria-jp Date: Wed, 2 Aug 2017 11:49:25 +0900 Subject: [PATCH 01/32] Update Japanese Translation (authorize_follow) (#4481) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit * Update Japanese Translation * preserve "Unfortunately"("残念ながら") preserve "Unfortunately"("残念ながら") --- config/locales/ja.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/config/locales/ja.yml b/config/locales/ja.yml index fa8f4566c9..d87e77ffbd 100644 --- a/config/locales/ja.yml +++ b/config/locales/ja.yml @@ -234,7 +234,7 @@ ja: reset_password: パスワードを再発行 set_new_password: 新しいパスワード authorize_follow: - error: 残念ながら、リモートアカウントにエラーが発生しました。 + error: 残念ながら、リモートアカウント情報の取得中にエラーが発生しました。 follow: フォロー follow_request: 'あなたは以下のアカウントにフォローリクエストを送信しました:' following: '成功! あなたは現在以下のアカウントをフォローしています:' From 8c0e78ae436de7d24f808f28ee2ab6facb0451db Mon Sep 17 00:00:00 2001 From: Komic Date: Wed, 2 Aug 2017 06:31:49 +0200 Subject: [PATCH 02/32] fr.json update (#4492) --- app/javascript/mastodon/locales/fr.json | 16 ++++++++-------- 1 file changed, 8 insertions(+), 8 deletions(-) diff --git a/app/javascript/mastodon/locales/fr.json b/app/javascript/mastodon/locales/fr.json index ad9060d25b..f3f0d04635 100644 --- a/app/javascript/mastodon/locales/fr.json +++ b/app/javascript/mastodon/locales/fr.json @@ -13,7 +13,7 @@ "account.posts": "Statuts", "account.report": "Signaler", "account.requested": "Invitation envoyée", - "account.share": "Share @{name}'s profile", + "account.share": "Partager le profil de @{name}", "account.unblock": "Débloquer", "account.unblock_domain": "Ne plus masquer {domain}", "account.unfollow": "Ne plus suivre", @@ -35,11 +35,11 @@ "column.notifications": "Notifications", "column.public": "Fil public global", "column_back_button.label": "Retour", - "column_header.hide_settings": "Hide settings", - "column_header.moveLeft_settings": "Move column to the left", - "column_header.moveRight_settings": "Move column to the right", + "column_header.hide_settings": "Masquer les paramètres", + "column_header.moveLeft_settings": "Déplacer la colonne vers la gauche", + "column_header.moveRight_settings": "Déplacer la colonne vers la droite", "column_header.pin": "Épingler", - "column_header.show_settings": "Show settings", + "column_header.show_settings": "Afficher les paramètres", "column_header.unpin": "Retirer", "column_subheading.navigation": "Navigation", "column_subheading.settings": "Paramètres", @@ -94,8 +94,8 @@ "home.column_settings.show_replies": "Afficher les réponses", "home.settings": "Paramètres de la colonne", "lightbox.close": "Fermer", - "lightbox.next": "Next", - "lightbox.previous": "Previous", + "lightbox.next": "Suivant", + "lightbox.previous": "Précédent", "loading_indicator.label": "Chargement…", "media_gallery.toggle_visible": "Modifier la visibilité", "missing_indicator.label": "Non trouvé", @@ -175,7 +175,7 @@ "status.report": "Signaler @{name}", "status.sensitive_toggle": "Cliquer pour afficher", "status.sensitive_warning": "Contenu sensible", - "status.share": "Share", + "status.share": "Partager", "status.show_less": "Replier", "status.show_more": "Déplier", "status.unmute_conversation": "Ne plus masquer la conversation", From ac5373681420dacbe9655da20c303aaa33644e7c Mon Sep 17 00:00:00 2001 From: Sorin Davidoi Date: Wed, 2 Aug 2017 13:09:09 +0200 Subject: [PATCH 03/32] fix(status_list): Use correct keys for keyboard navigation (#4487) --- app/javascript/mastodon/components/status_list.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/app/javascript/mastodon/components/status_list.js b/app/javascript/mastodon/components/status_list.js index e945e878c9..ca443c286a 100644 --- a/app/javascript/mastodon/components/status_list.js +++ b/app/javascript/mastodon/components/status_list.js @@ -105,7 +105,7 @@ export default class StatusList extends ImmutablePureComponent { } handleKeyDown = (e) => { - if (['PageDown', 'PageUp', 'End', 'Home'].includes(e.key)) { + if (['PageDown', 'PageUp'].includes(e.key) || (e.ctrlKey && ['End', 'Home'].includes(e.key))) { const article = (() => { switch (e.key) { case 'PageDown': From 94e233e7b2921044754babc82b5448ac2e3bfd23 Mon Sep 17 00:00:00 2001 From: unarist Date: Wed, 2 Aug 2017 20:09:37 +0900 Subject: [PATCH 04/32] Fix column-back-button style for some browsers (#4484) Use `text-align: unset` instead of `text-align: start` which Edge doesn't support for now. Also remove default margin on Safari. --- app/javascript/styles/components.scss | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/app/javascript/styles/components.scss b/app/javascript/styles/components.scss index 34e4b2e72d..9174f51124 100644 --- a/app/javascript/styles/components.scss +++ b/app/javascript/styles/components.scss @@ -1590,8 +1590,9 @@ flex: 0 0 auto; font-size: 16px; border: 0; - text-align: start; + text-align: unset; padding: 15px; + margin: 0; z-index: 3; &:hover { From 9ba7d526a0712afa073c6901bf2e69bae0dfab26 Mon Sep 17 00:00:00 2001 From: TheKinrar Date: Wed, 2 Aug 2017 14:54:33 +0200 Subject: [PATCH 05/32] Don't normalize invalid domain names (#4499) Fixes #4496 --- app/lib/formatter.rb | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/app/lib/formatter.rb b/app/lib/formatter.rb index 7b89305ac5..cacc0364fd 100644 --- a/app/lib/formatter.rb +++ b/app/lib/formatter.rb @@ -104,7 +104,7 @@ class Formatter html_attrs = { target: '_blank', rel: 'nofollow noopener' } Twitter::Autolink.send(:link_to_text, entity, link_html(entity[:url]), normalized_url, html_attrs) - rescue Addressable::URI::InvalidURIError + rescue Addressable::URI::InvalidURIError, IDN::Idna::IdnaError encode(entity[:url]) end From 09e86ef90b1e220bca54b5b3cb270d7672237c13 Mon Sep 17 00:00:00 2001 From: MIYAGI Hikaru Date: Thu, 3 Aug 2017 04:05:17 +0900 Subject: [PATCH 06/32] make number of comparison in emojify() fewer (#4500) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit fix style "©"削除処理をemojione_lightに移動 --- app/javascript/mastodon/emoji.js | 48 ++++++++++------------- app/javascript/mastodon/emojione_light.js | 2 + 2 files changed, 23 insertions(+), 27 deletions(-) diff --git a/app/javascript/mastodon/emoji.js b/app/javascript/mastodon/emoji.js index 5695c86dd3..a41dfdd1d2 100644 --- a/app/javascript/mastodon/emoji.js +++ b/app/javascript/mastodon/emoji.js @@ -3,34 +3,28 @@ import Trie from 'substring-trie'; const trie = new Trie(Object.keys(unicodeMapping)); -const excluded = ['™', '©', '®']; - -function emojify(str) { - // This walks through the string from start to end, ignoring any tags (

,
, etc.) - // and replacing valid unicode strings - // that _aren't_ within tags with an version. - // The goal is to be the same as an emojione.regUnicode replacement, but faster. - let i = -1; - let insideTag = false; - let match; - while (++i < str.length) { - const char = str.charAt(i); - if (insideTag && char === '>') { - insideTag = false; - } else if (char === '<') { - insideTag = true; - } else if (!insideTag && (match = trie.search(str.substring(i)))) { - const unicodeStr = match; - if (unicodeStr in unicodeMapping && excluded.indexOf(unicodeStr) === -1) { - const [filename, shortCode] = unicodeMapping[unicodeStr]; - const alt = unicodeStr; - const replacement = `${alt}`; - str = str.substring(0, i) + replacement + str.substring(i + unicodeStr.length); - i += (replacement.length - unicodeStr.length); // jump ahead the length we've added to the string - } +const emojify = str => { + let rtn = ''; + for (;;) { + let match, i = 0; + while (i < str.length && str[i] !== '<' && !(match = trie.search(str.slice(i)))) { + i += str.codePointAt(i) < 65536 ? 1 : 2; + } + if (i === str.length) + break; + else if (str[i] === '<') { + let tagend = str.indexOf('>', i + 1) + 1; + if (!tagend) + break; + rtn += str.slice(0, tagend); + str = str.slice(tagend); + } else { + const [filename, shortCode] = unicodeMapping[match]; + rtn += str.slice(0, i) + `${match}`; + str = str.slice(i + match.length); } } - return str; -} + return rtn + str; +}; export default emojify; diff --git a/app/javascript/mastodon/emojione_light.js b/app/javascript/mastodon/emojione_light.js index 985e9dbcb3..0d07d012f0 100644 --- a/app/javascript/mastodon/emojione_light.js +++ b/app/javascript/mastodon/emojione_light.js @@ -4,8 +4,10 @@ const emojione = require('emojione'); const mappedUnicode = emojione.mapUnicodeToShort(); +const excluded = ['®', '©', '™']; module.exports.unicodeMapping = Object.keys(emojione.jsEscapeMap) + .filter(c => !excluded.includes(c)) .map(unicodeStr => [unicodeStr, mappedUnicode[emojione.jsEscapeMap[unicodeStr]]]) .map(([unicodeStr, shortCode]) => ({ [unicodeStr]: [emojione.emojioneList[shortCode].fname, shortCode.slice(1, shortCode.length - 1)] })) .reduce((x, y) => Object.assign(x, y), { }); From dfcd2834f9589bda573eb133057588f351f570b5 Mon Sep 17 00:00:00 2001 From: nullkal Date: Fri, 4 Aug 2017 00:45:45 +0900 Subject: [PATCH 07/32] Redirect to PasswordController#new when reset_password_token is invalid (#4506) --- app/controllers/auth/passwords_controller.rb | 15 +++++++++++ config/locales/en.yml | 1 + .../auth/passwords_controller_spec.rb | 25 +++++++++++++++++++ 3 files changed, 41 insertions(+) diff --git a/app/controllers/auth/passwords_controller.rb b/app/controllers/auth/passwords_controller.rb index 54ee1c39c0..171b997dc4 100644 --- a/app/controllers/auth/passwords_controller.rb +++ b/app/controllers/auth/passwords_controller.rb @@ -1,5 +1,20 @@ # frozen_string_literal: true class Auth::PasswordsController < Devise::PasswordsController + before_action :check_validity_of_reset_password_token, only: :edit + layout 'auth' + + private + + def check_validity_of_reset_password_token + unless reset_password_token_is_valid? + flash[:error] = I18n.t('auth.invalid_reset_password_token') + redirect_to new_password_path(resource_name) + end + end + + def reset_password_token_is_valid? + resource_class.with_reset_password_token(params[:reset_password_token]).present? + end end diff --git a/config/locales/en.yml b/config/locales/en.yml index 90b4fe82bc..1d092d20c0 100644 --- a/config/locales/en.yml +++ b/config/locales/en.yml @@ -234,6 +234,7 @@ en: resend_confirmation: Resend confirmation instructions reset_password: Reset password set_new_password: Set new password + invalid_reset_password_token: Password reset link is invalid or expired. Please try again. authorize_follow: error: Unfortunately, there was an error looking up the remote account follow: Follow diff --git a/spec/controllers/auth/passwords_controller_spec.rb b/spec/controllers/auth/passwords_controller_spec.rb index 60b225efae..992d2e29d2 100644 --- a/spec/controllers/auth/passwords_controller_spec.rb +++ b/spec/controllers/auth/passwords_controller_spec.rb @@ -3,6 +3,8 @@ require 'rails_helper' describe Auth::PasswordsController, type: :controller do + include Devise::Test::ControllerHelpers + describe 'GET #new' do it 'returns http success' do @request.env['devise.mapping'] = Devise.mappings[:user] @@ -10,4 +12,27 @@ describe Auth::PasswordsController, type: :controller do expect(response).to have_http_status(:success) end end + + describe 'GET #edit' do + let(:user) { Fabricate(:user) } + + before do + request.env['devise.mapping'] = Devise.mappings[:user] + @token = user.send_reset_password_instructions + end + + context 'with valid reset_password_token' do + it 'returns http success' do + get :edit, params: { reset_password_token: @token } + expect(response).to have_http_status(:success) + end + end + + context 'with invalid reset_password_token' do + it 'redirects to #new' do + get :edit, params: { reset_password_token: 'some_invalid_value' } + expect(response).to redirect_to subject.new_password_path(subject.send(:resource_name)) + end + end + end end From fae71b653a7481a5f06d071e74d4a9e4b7f9952a Mon Sep 17 00:00:00 2001 From: Yamagishi Kazutoshi Date: Fri, 4 Aug 2017 00:46:49 +0900 Subject: [PATCH 08/32] Enable cache for babel-loader (#4505) --- .travis.yml | 1 + config/webpack/loaders/babel.js | 3 +++ 2 files changed, 4 insertions(+) diff --git a/.travis.yml b/.travis.yml index 4d4dc08930..d5b51fcb0c 100644 --- a/.travis.yml +++ b/.travis.yml @@ -6,6 +6,7 @@ cache: - node_modules - public/assets - public/packs-test + - tmp/cache/babel-loader dist: trusty sudo: required diff --git a/config/webpack/loaders/babel.js b/config/webpack/loaders/babel.js index a1992a450a..3177d964ac 100644 --- a/config/webpack/loaders/babel.js +++ b/config/webpack/loaders/babel.js @@ -1,3 +1,5 @@ +const { resolve } = require('path'); + module.exports = { test: /\.js$/, // include react-intl because transform-react-remove-prop-types needs to apply to it @@ -8,5 +10,6 @@ module.exports = { loader: 'babel-loader', options: { forceEnv: process.env.NODE_ENV || 'development', + cacheDirectory: resolve(__dirname, '..', '..', '..', 'tmp', 'cache', 'babel-loader'), }, }; From 0bbd5789b51c9187ecdff19423536f921fab3f9e Mon Sep 17 00:00:00 2001 From: m4sk1n Date: Thu, 3 Aug 2017 17:49:53 +0200 Subject: [PATCH 09/32] i18n: Update Polish translation (#4479) * i18n: Update Polish translation * Update Polish translation --- config/locales/pl.yml | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) diff --git a/config/locales/pl.yml b/config/locales/pl.yml index a30092d505..63e0849df1 100644 --- a/config/locales/pl.yml +++ b/config/locales/pl.yml @@ -109,12 +109,14 @@ pl: hint: Blokada domen nie zabroni tworzenia wpisów kont w bazie danych, ale pozwoli na automatyczną moderację kont do nich należących. severity: desc_html: "Wyciszenie uczyni wpisy użytkownika widoczne tylko dla osób, które go śledzą. Zawieszenie spowoduje usunięcie całej zawartości dodanej przez użytkownika." + noop: Nic nie rób silence: Wycisz suspend: Zawieś title: Nowa blokada domen reject_media: Odrzucaj pliki multimedialne reject_media_hint: Usuwa przechowywane lokalnie pliki multimedialne i nie pozwala na ich pobieranie. Nieprzydatne przy zawieszeniu severities: + noop: Nic nie rób silence: Wycisz suspend: Zawieś severity: Priorytet @@ -213,6 +215,7 @@ pl: body: Użytkownik %{reporter} zgłosił %{target} subject: Nowe zgłoszenie na %{instance} (#%{id}) application_mailer: + salutation: '%{name},' settings: 'Zmień ustawienia powiadamiania: %{link}' signature: Powiadomienie Mastodona z instancji %{instance} view: 'Zobacz:' @@ -336,8 +339,8 @@ pl: body: "%{name} poprosił o możliwość śledzenia Cię" subject: 'Prośba o możliwość śledzenia: %{name}' mention: - body: "%{name} wspomniał Cię w:" - subject: "%{name} Cię wspomniał" + body: "%{name} wspomniał o Tobie w:" + subject: "%{name} wspomniał o Tobie" reblog: body: 'Twój wpis został podbity przez %{name}:' subject: Twój wpis został podbity przez %{name} From ab60aa226617c62161bf56d1bb45cea76cfb8403 Mon Sep 17 00:00:00 2001 From: Yamagishi Kazutoshi Date: Fri, 4 Aug 2017 01:04:36 +0900 Subject: [PATCH 10/32] Use GNU libiconv in Nokogiri (#4494) System default libiconv of Alpine Linux only supports some charset (e.g. UTF-8). Therefore, the preview card of the page which is not UTF-8 will be broken in the Docker environment. Using GNU libiconv! --- Dockerfile | 22 +++++++++++++++++----- 1 file changed, 17 insertions(+), 5 deletions(-) diff --git a/Dockerfile b/Dockerfile index ef139dcec4..93a8ffd0b4 100644 --- a/Dockerfile +++ b/Dockerfile @@ -7,6 +7,9 @@ ENV UID=991 GID=991 \ RAILS_SERVE_STATIC_FILES=true \ RAILS_ENV=production NODE_ENV=production +ARG LIBICONV_VERSION=1.15 +ARG LIBICONV_DOWNLOAD_SHA256=ccf536620a45458d26ba83887a983b96827001e92a13847b45e4925cc8913178 + EXPOSE 3000 4000 WORKDIR /mastodon @@ -18,8 +21,7 @@ RUN echo "@edge https://nl.alpinelinux.org/alpine/edge/main" >> /etc/apk/reposit build-base \ icu-dev \ libidn-dev \ - libxml2-dev \ - libxslt-dev \ + libtool \ postgresql-dev \ protobuf-dev \ python \ @@ -32,8 +34,6 @@ RUN echo "@edge https://nl.alpinelinux.org/alpine/edge/main" >> /etc/apk/reposit imagemagick@edge \ libidn \ libpq \ - libxml2 \ - libxslt \ nodejs-npm@edge \ nodejs@edge \ protobuf \ @@ -41,11 +41,23 @@ RUN echo "@edge https://nl.alpinelinux.org/alpine/edge/main" >> /etc/apk/reposit tini \ yarn@edge \ && update-ca-certificates \ + && wget -O libiconv.tar.gz "http://ftp.gnu.org/pub/gnu/libiconv/libiconv-$LIBICONV_VERSION.tar.gz" \ + && echo "$LIBICONV_DOWNLOAD_SHA256 *libiconv.tar.gz" | sha256sum -c - \ + && mkdir -p /tmp/src \ + && tar -xzf libiconv.tar.gz -C /tmp/src \ + && rm libiconv.tar.gz \ + && cd /tmp/src/libiconv-$LIBICONV_VERSION \ + && ./configure --prefix=/usr/local \ + && make \ + && make install \ + && libtool --finish /usr/local/lib \ + && cd /mastodon \ && rm -rf /tmp/* /var/cache/apk/* COPY Gemfile Gemfile.lock package.json yarn.lock /mastodon/ -RUN bundle install --deployment --without test development \ +RUN bundle config build.nokogiri --with-iconv-lib=/usr/local/lib --with-iconv-include=/usr/local/include \ + && bundle install --deployment --without test development \ && yarn --ignore-optional --pure-lockfile COPY . /mastodon From 76da330155848e56225033f7e713473658599dd3 Mon Sep 17 00:00:00 2001 From: Jeroen Date: Fri, 4 Aug 2017 00:16:25 +0200 Subject: [PATCH 11/32] Dutch strings: typo (#4489) --- config/locales/nl.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/config/locales/nl.yml b/config/locales/nl.yml index e65658d8b6..272a71eed1 100644 --- a/config/locales/nl.yml +++ b/config/locales/nl.yml @@ -220,7 +220,7 @@ nl: applications: invalid_url: De opgegeven URL is ongeldig auth: - agreement_html: Wanneer je op registeren klikt ga je akkoord met onze gebruikersvoorwaarden en ons privacybeleid. + agreement_html: Wanneer je op registreren klikt ga je akkoord met onze gebruikersvoorwaarden en ons privacybeleid. change_password: Beveiliging delete_account: Account verwijderen delete_account_html: Wanneer je jouw account graag wilt verwijderen, kan je dat hier doen. We vragen jou daar om een bevestiging. From 724be2d5feb328acc11ce3d23287b8250049dd40 Mon Sep 17 00:00:00 2001 From: Eugen Rochko Date: Fri, 4 Aug 2017 04:42:28 +0200 Subject: [PATCH 12/32] Ignore some locale keys that can but do not need to be translated (#4515) --- config/i18n-tasks.yml | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/config/i18n-tasks.yml b/config/i18n-tasks.yml index f2bb220a6d..849e8116aa 100644 --- a/config/i18n-tasks.yml +++ b/config/i18n-tasks.yml @@ -42,7 +42,9 @@ ignore_missing: - 'simple_form.{error_notification,required}.:' - 'errors.messages.*' - 'activerecord.errors.models.doorkeeper/*' - + - 'sessions.{browsers,platforms}.*' + - 'terms.body_html' + - 'application_mailer.salutation' ignore_unused: - 'activemodel.errors.*' - 'activerecord.attributes.*' From 400616813e6012780b97c5a297797ee50fd2072a Mon Sep 17 00:00:00 2001 From: Krzysztof Jurewicz Date: Fri, 4 Aug 2017 15:43:28 +0200 Subject: [PATCH 13/32] Fix some mistakes in Polish translation (#4495) --- app/javascript/mastodon/locales/pl.json | 6 +++--- config/locales/devise.pl.yml | 10 +++++----- config/locales/doorkeeper.pl.yml | 2 +- config/locales/pl.yml | 10 +++++----- 4 files changed, 14 insertions(+), 14 deletions(-) diff --git a/app/javascript/mastodon/locales/pl.json b/app/javascript/mastodon/locales/pl.json index c42721f647..542230f112 100644 --- a/app/javascript/mastodon/locales/pl.json +++ b/app/javascript/mastodon/locales/pl.json @@ -73,7 +73,7 @@ "emoji_button.search": "Szukaj...", "emoji_button.symbols": "Symbole", "emoji_button.travel": "Podróże i miejsca", - "empty_column.community": "Lokalna oś czasu jest pusta. Napisz coś publicznie, aby odbić piłeczkę!", + "empty_column.community": "Lokalna oś czasu jest pusta. Napisz coś publicznie, aby zagaić!", "empty_column.hashtag": "Nie ma postów oznaczonych tym hashtagiem. Możesz napisać pierwszy!", "empty_column.home": "Nie śledzisz nikogo. Odwiedź publiczną oś czasu lub użyj wyszukiwarki, aby znaleźć interesujące Cię profile.", "empty_column.home.inactivity": "Strumień jest pusty. Jeżeli nie było Cię tu ostatnio, zostanie on wypełniony wkrótce.", @@ -159,7 +159,7 @@ "report.target": "Zgłaszanie {target}", "search.placeholder": "Szukaj", "search_results.total": "{count, number} {count, plural, one {wynik} more {wyniki}}", - "standalone.public_title": "Spojrzenie wgłąb…", + "standalone.public_title": "Spojrzenie w głąb…", "status.cannot_reblog": "Ten post nie może zostać podbity", "status.delete": "Usuń", "status.favourite": "Ulubione", @@ -178,7 +178,7 @@ "status.share": "Udostępnij", "status.show_less": "Pokaż mniej", "status.show_more": "Pokaż więcej", - "status.unmute_conversation": "Cofnij wyciezenie konwersacji", + "status.unmute_conversation": "Cofnij wyciszenie konwersacji", "tabs_bar.compose": "Napisz", "tabs_bar.federated_timeline": "Globalne", "tabs_bar.home": "Strona główna", diff --git a/config/locales/devise.pl.yml b/config/locales/devise.pl.yml index 1c692f7a87..d537efc6eb 100644 --- a/config/locales/devise.pl.yml +++ b/config/locales/devise.pl.yml @@ -12,9 +12,9 @@ pl: last_attempt: Masz jeszcze jedną próbę; Twoje konto zostanie zablokowane jeśli się nie powiedzie. locked: Twoje konto zostało zablokowane. not_found_in_database: Nieprawidłowy %{authentication_keys} lub hasło. - timeout: Twoja sesja wygasła. Zaloguj się ponownie aby kontynuować.. - unauthenticated: Zapisz się lub zaloguj aby kontynuować. - unconfirmed: Zweryfikuj adres e-mail aby kontynuować. + timeout: Twoja sesja wygasła. Zaloguj się ponownie, aby kontynuować.. + unauthenticated: Zapisz się lub zaloguj, aby kontynuować. + unconfirmed: Zweryfikuj adres e-mail, aby kontynuować. mailer: confirmation_instructions: subject: 'Mastodon: Instrukcje weryfikacji adresu e-mail' @@ -38,7 +38,7 @@ pl: signed_up: Twoje konto zostało utworzone. Witamy! signed_up_but_inactive: Twoje konto zostało utworzone. Nie mogliśmy Cię jednak zalogować, ponieważ konto nie zostało jeszcze aktywowane. signed_up_but_locked: Twoje konto zostało utworzone. Nie mogliśmy Cię jednak zalogować, ponieważ konto jest zablokowane. - signed_up_but_unconfirmed: Na Twój adres e-mail została wysłana wiadomosć z odnośnikiem potwierdzającym. Kliknij w odnośnik aby aktywować konto. Jeżeli nie otrzymano wiadomości, sprawdź folder ze spamem. + signed_up_but_unconfirmed: Na Twój adres e-mail została wysłana wiadomosć z odnośnikiem potwierdzającym. Kliknij w odnośnik, aby aktywować konto. Jeżeli nie otrzymano wiadomości, sprawdź folder ze spamem. update_needs_confirmation: Konto zostało zaktualizowane, musimy jednak zweryfikować Twój nowy adres e-mail. Została na niego wysłana wiadomość z odnośnikiem potwierdzającym. Jeżeli nie otrzymano wiadomości, sprawdź folder ze spamem. updated: Konto zostało zaktualizowane. sessions: @@ -48,7 +48,7 @@ pl: unlocks: send_instructions: W ciągu kilku minut otrzymasz wiadomość e-mail z instrukcjami odblokowania konta. Jeżeli nie otrzymano wiadomości, sprawdź folder ze spamem. send_paranoid_instructions: Jeśli Twoje konto istnieje, instrukcje odblokowania go otrzymasz w wiadomości e-mail w ciągu kilku minut. Jeżeli nie otrzymano wiadomości, sprawdź folder ze spamem. - unlocked: Twoje konto zostało odblokowane. Zaloguj się aby kontynuować. + unlocked: Twoje konto zostało odblokowane. Zaloguj się, aby kontynuować. errors: messages: already_confirmed: był już potwierdzony, spróbuj się zalogować diff --git a/config/locales/doorkeeper.pl.yml b/config/locales/doorkeeper.pl.yml index 8103c45616..72b967e354 100644 --- a/config/locales/doorkeeper.pl.yml +++ b/config/locales/doorkeeper.pl.yml @@ -31,7 +31,7 @@ pl: help: native_redirect_uri: Użyj %{native_redirect_uri} do lokalnych testów redirect_uri: Jeden adres na linię tekstu - scopes: Rozdziel zakresy (scopes) spacjami. Zostaw puste aby użyć domyślnych zakresów. + scopes: Rozdziel zakresy (scopes) spacjami. Zostaw puste, aby użyć domyślnych zakresów. index: callback_url: URL wywołania zwrotnego (callback) name: Nazwa diff --git a/config/locales/pl.yml b/config/locales/pl.yml index 63e0849df1..bfd6b90915 100644 --- a/config/locales/pl.yml +++ b/config/locales/pl.yml @@ -177,8 +177,8 @@ pl: desc_html: Akapit wprowadzający, widoczny na stronie głównej i znacznikach meta. Możesz korzystać z tagów HTML, w szczególności <a> i <em>. title: Opis instancji site_description_extended: - desc_html: Dobre miejsce na zasady użytkowania, wprowadzenie i inne rzeczy, które wyróżniają tą instancję. Możesz korzystać z tagów HTML - title: Niestandrdowy opis strony + desc_html: Dobre miejsce na zasady użytkowania, wprowadzenie i inne rzeczy, które wyróżniają tę instancję. Możesz korzystać z tagów HTML + title: Niestandardowy opis strony site_terms: desc_html: Miejsce na własną politykę prywatności, zasady użytkowania i inne unormowania prawne. Możesz używać tagów HTML title: Niestandardowe zasady użytkowania @@ -240,7 +240,7 @@ pl: follow_request: 'Wysłano prośbę o pozwolenie na śledzenie:' following: 'Pomyślnie! Od teraz śledzisz:' post_follow: - close: Ewentualnie, możesz po prostu zamknąć tą stronę. + close: Ewentualnie, możesz po prostu zamknąć tę stronę. return: Powróć do strony użytkownika web: Przejdź do sieci prompt_html: 'Ty (%{self}) chcesz śledzić:' @@ -265,10 +265,10 @@ pl: description_html: Ta opcja usunie bezpowrotnie i nieodwracalnie całą zawartość konta i zdezaktywuje je. Twoja nazwa użytkownika pozostanie zarezerwowana, aby zapobiec nadużyciom. proceed: Usuń konto success_msg: Twoje konto zostało pomyślnie usunięte - warning_html: Możemy usunąć zawartość jedynie w obrębie tej instancji. Zawartość udostępniona publicznie pozostawia trwałe ślady. Serwery niepodłączone do sieci, bądź nieśledzące Twoich aktualizacji mogą zachować Twoje dane. + warning_html: Możemy usunąć zawartość jedynie w obrębie tej instancji. Zawartość udostępniona publicznie pozostawia trwałe ślady. Serwery niepodłączone do sieci bądź nieśledzące Twoich aktualizacji mogą zachować Twoje dane. warning_title: Dostępność usuniętej zawartości errors: - '403': Nie masz uprawnień, aby wyświetlić tą stronę. + '403': Nie masz uprawnień, aby wyświetlić tę stronę. '404': Strona, którą próbujesz odwiedzić, nie istnieje. '410': Strona, którą próbujesz odwiedzić, już nie istnieje. '422': From 9d1f8b9d6af1d384a4dd68bc6353a2fde5735b33 Mon Sep 17 00:00:00 2001 From: Akihiko Odaki Date: Sat, 5 Aug 2017 01:57:46 +0900 Subject: [PATCH 14/32] Scroll columns area to right when children property is changed (#4517) The feature to pin column could hide the rightmost column, which is specified with children property of ColumnsArea. The user is likely to see the column when the property changed, so scroll the area in such cases. --- app/javascript/mastodon/components/column.js | 2 +- .../mastodon/features/ui/components/column.js | 2 +- .../features/ui/components/columns_area.js | 14 ++++++++++++-- app/javascript/mastodon/scroll.js | 11 ++++++----- 4 files changed, 20 insertions(+), 9 deletions(-) diff --git a/app/javascript/mastodon/components/column.js b/app/javascript/mastodon/components/column.js index 93f1d6260b..05a7c14369 100644 --- a/app/javascript/mastodon/components/column.js +++ b/app/javascript/mastodon/components/column.js @@ -1,7 +1,7 @@ import React from 'react'; import PropTypes from 'prop-types'; import detectPassiveEvents from 'detect-passive-events'; -import scrollTop from '../scroll'; +import { scrollTop } from '../scroll'; export default class Column extends React.PureComponent { diff --git a/app/javascript/mastodon/features/ui/components/column.js b/app/javascript/mastodon/features/ui/components/column.js index aea102aac5..9031c16fc2 100644 --- a/app/javascript/mastodon/features/ui/components/column.js +++ b/app/javascript/mastodon/features/ui/components/column.js @@ -2,7 +2,7 @@ import React from 'react'; import ColumnHeader from './column_header'; import PropTypes from 'prop-types'; import { debounce } from 'lodash'; -import scrollTop from '../../../scroll'; +import { scrollTop } from '../../../scroll'; import { isMobile } from '../../../is_mobile'; export default class Column extends React.PureComponent { diff --git a/app/javascript/mastodon/features/ui/components/columns_area.js b/app/javascript/mastodon/features/ui/components/columns_area.js index 63bd1b0212..7652d67a08 100644 --- a/app/javascript/mastodon/features/ui/components/columns_area.js +++ b/app/javascript/mastodon/features/ui/components/columns_area.js @@ -12,6 +12,8 @@ import ColumnLoading from './column_loading'; import BundleColumnError from './bundle_column_error'; import { Compose, Notifications, HomeTimeline, CommunityTimeline, PublicTimeline, HashtagTimeline, FavouritedStatuses } from '../../ui/util/async-components'; +import { scrollRight } from '../../../scroll'; + const componentMap = { 'COMPOSE': Compose, 'HOME': HomeTimeline, @@ -49,9 +51,13 @@ export default class ColumnsArea extends ImmutablePureComponent { this.setState({ shouldAnimate: true }); } - componentDidUpdate() { + componentDidUpdate(prevProps) { this.lastIndex = getIndex(this.context.router.history.location.pathname); this.setState({ shouldAnimate: true }); + + if (this.props.children !== prevProps.children) { + scrollRight(this.node); + } } handleSwipe = (index) => { @@ -74,6 +80,10 @@ export default class ColumnsArea extends ImmutablePureComponent { } } + setRef = (node) => { + this.node = node; + } + renderView = (link, index) => { const columnIndex = getIndex(this.context.router.history.location.pathname); const title = this.props.intl.formatMessage({ id: link.props['data-preview-title-id'] }); @@ -114,7 +124,7 @@ export default class ColumnsArea extends ImmutablePureComponent { } return ( -

+
{columns.map(column => { const params = column.get('params', null) === null ? null : column.get('params').toJS(); diff --git a/app/javascript/mastodon/scroll.js b/app/javascript/mastodon/scroll.js index c089d37db8..44f95b17f0 100644 --- a/app/javascript/mastodon/scroll.js +++ b/app/javascript/mastodon/scroll.js @@ -1,9 +1,9 @@ const easingOutQuint = (x, t, b, c, d) => c * ((t = t / d - 1) * t * t * t * t + 1) + b; -const scrollTop = (node) => { +const scroll = (node, key, target) => { const startTime = Date.now(); - const offset = node.scrollTop; - const targetY = -offset; + const offset = node[key]; + const gap = target - offset; const duration = 1000; let interrupt = false; @@ -15,7 +15,7 @@ const scrollTop = (node) => { return; } - node.scrollTop = easingOutQuint(0, elapsed, offset, targetY, duration); + node[key] = easingOutQuint(0, elapsed, offset, gap, duration); requestAnimationFrame(step); }; @@ -26,4 +26,5 @@ const scrollTop = (node) => { }; }; -export default scrollTop; +export const scrollRight = (node) => scroll(node, 'scrollLeft', node.scrollWidth); +export const scrollTop = (node) => scroll(node, 'scrollTop', 0); From 029786442a80ad73e1ec7a696a2b7f3dbbfbc10c Mon Sep 17 00:00:00 2001 From: Quent-in Date: Sat, 5 Aug 2017 01:31:27 +0200 Subject: [PATCH 15/32] l10n update Occitan (#4522) Salutation mailer + invalid reset link. --- config/locales/oc.yml | 2 ++ 1 file changed, 2 insertions(+) diff --git a/config/locales/oc.yml b/config/locales/oc.yml index d9a5892876..3e1cc3b6f8 100644 --- a/config/locales/oc.yml +++ b/config/locales/oc.yml @@ -214,6 +214,7 @@ oc: body: "%{reporter} a senhalat %{target}" subject: Novèl senhalament per %{instance} (#%{id}) application_mailer: + salutation: '%{name},' settings: 'Cambiar las preferéncias de corrièl : %{link}' signature: Notificacion de Mastodon sus %{instance} view: 'Veire :' @@ -232,6 +233,7 @@ oc: resend_confirmation: Tornar mandar las instruccions de confirmacion reset_password: Reïnicializar lo senhal set_new_password: Picar un nòu senhal + invalid_reset_password_token: Ligam de reïnicializacion invalid o acabat. Tornatz ensajar se vos plai. authorize_follow: error: O planhèm, i a agut una error al moment de cercar lo compte follow: Sègre From df605f0f8ba795a10cf67095429bfeb7c362b7c9 Mon Sep 17 00:00:00 2001 From: Eugen Rochko Date: Sat, 5 Aug 2017 04:24:58 +0200 Subject: [PATCH 16/32] Add "signed in as" header to some pages (#4523) --- app/controllers/application_controller.rb | 4 ++ .../authorize_follows_controller.rb | 2 +- app/controllers/remote_follow_controller.rb | 2 +- app/javascript/styles/basics.scss | 2 +- app/javascript/styles/containers.scss | 54 ++++++++++++++++++- app/javascript/styles/forms.scss | 2 +- app/views/authorize_follows/show.html.haml | 9 ++-- app/views/layouts/modal.html.haml | 16 ++++++ config/application.rb | 2 +- config/initializers/doorkeeper.rb | 5 ++ config/locales/ar.yml | 1 - config/locales/bg.yml | 1 - config/locales/ca.yml | 1 - config/locales/de.yml | 1 - config/locales/en.yml | 6 +-- config/locales/eo.yml | 1 - config/locales/es.yml | 1 - config/locales/fa.yml | 7 ++- config/locales/fi.yml | 1 - config/locales/fr.yml | 1 - config/locales/he.yml | 1 - config/locales/hr.yml | 1 - config/locales/id.yml | 1 - config/locales/io.yml | 1 - config/locales/it.yml | 1 - config/locales/ja.yml | 1 - config/locales/ko.yml | 1 - config/locales/nl.yml | 11 ++-- config/locales/no.yml | 1 - config/locales/oc.yml | 3 +- config/locales/pl.yml | 3 +- config/locales/pt-BR.yml | 1 - config/locales/ru.yml | 7 ++- config/locales/th.yml | 1 - config/locales/tr.yml | 1 - config/locales/uk.yml | 1 - config/locales/zh-CN.yml | 1 - config/locales/zh-HK.yml | 1 - config/locales/zh-TW.yml | 1 - .../auth/sessions_controller_spec.rb | 4 +- 40 files changed, 105 insertions(+), 57 deletions(-) create mode 100644 app/views/layouts/modal.html.haml diff --git a/app/controllers/application_controller.rb b/app/controllers/application_controller.rb index b3c2db02b3..0b40fb05b7 100644 --- a/app/controllers/application_controller.rb +++ b/app/controllers/application_controller.rb @@ -43,6 +43,10 @@ class ApplicationController < ActionController::Base forbidden if current_user.account.suspended? end + def after_sign_out_path_for(_resource_or_scope) + new_user_session_path + end + protected def forbidden diff --git a/app/controllers/authorize_follows_controller.rb b/app/controllers/authorize_follows_controller.rb index dccd1c2090..78b5641836 100644 --- a/app/controllers/authorize_follows_controller.rb +++ b/app/controllers/authorize_follows_controller.rb @@ -1,7 +1,7 @@ # frozen_string_literal: true class AuthorizeFollowsController < ApplicationController - layout 'public' + layout 'modal' before_action :authenticate_user! diff --git a/app/controllers/remote_follow_controller.rb b/app/controllers/remote_follow_controller.rb index 2988231b1d..48b026aa5a 100644 --- a/app/controllers/remote_follow_controller.rb +++ b/app/controllers/remote_follow_controller.rb @@ -1,7 +1,7 @@ # frozen_string_literal: true class RemoteFollowController < ApplicationController - layout 'public' + layout 'modal' before_action :set_account before_action :gone, if: :suspended_account? diff --git a/app/javascript/styles/basics.scss b/app/javascript/styles/basics.scss index 182ea36a43..4e51b555ca 100644 --- a/app/javascript/styles/basics.scss +++ b/app/javascript/styles/basics.scss @@ -47,7 +47,7 @@ body { padding: 0; } - @media screen and (max-width: 360px) { + @media screen and (max-width: 400px) { padding-bottom: 0; } } diff --git a/app/javascript/styles/containers.scss b/app/javascript/styles/containers.scss index 7dcf2c0062..d366a46ecd 100644 --- a/app/javascript/styles/containers.scss +++ b/app/javascript/styles/containers.scss @@ -13,8 +13,9 @@ margin: 100px auto; margin-bottom: 50px; - @media screen and (max-width: 360px) { + @media screen and (max-width: 400px) { margin: 30px auto; + margin-bottom: 20px; } h1 { @@ -42,3 +43,54 @@ } } } + +.account-header { + width: 400px; + margin: 0 auto; + display: flex; + font-size: 13px; + line-height: 18px; + box-sizing: border-box; + padding: 20px 0; + padding-bottom: 0; + margin-bottom: -30px; + margin-top: 40px; + + @media screen and (max-width: 400px) { + width: 100%; + margin: 0; + margin-bottom: 10px; + padding: 20px; + padding-bottom: 0; + } + + .avatar { + width: 40px; + height: 40px; + margin-right: 8px; + + img { + width: 100%; + height: 100%; + display: block; + margin: 0; + border-radius: 4px; + } + } + + .name { + flex: 1 1 auto; + color: $ui-secondary-color; + + .username { + display: block; + font-weight: 500; + } + } + + .logout-link { + display: block; + font-size: 32px; + line-height: 40px; + } +} diff --git a/app/javascript/styles/forms.scss b/app/javascript/styles/forms.scss index cffb6f1972..62094e98ee 100644 --- a/app/javascript/styles/forms.scss +++ b/app/javascript/styles/forms.scss @@ -317,7 +317,7 @@ code { } .flash-message { - background: $ui-base-color; + background: lighten($ui-base-color, 8%); color: $ui-primary-color; border-radius: 4px; padding: 15px 10px; diff --git a/app/views/authorize_follows/show.html.haml b/app/views/authorize_follows/show.html.haml index 3b60df0580..f7a8f72d20 100644 --- a/app/views/authorize_follows/show.html.haml +++ b/app/views/authorize_follows/show.html.haml @@ -3,10 +3,9 @@ .form-container .follow-prompt - %h2= t('authorize_follow.prompt_html', self: current_account.username) - = render 'card', account: @account - = form_tag authorize_follow_path, method: :post, class: 'simple_form' do - = hidden_field_tag :acct, @account.acct - = button_tag t('authorize_follow.follow'), type: :submit + - unless current_account.following?(@account) + = form_tag authorize_follow_path, method: :post, class: 'simple_form' do + = hidden_field_tag :acct, @account.acct + = button_tag t('authorize_follow.follow'), type: :submit diff --git a/app/views/layouts/modal.html.haml b/app/views/layouts/modal.html.haml new file mode 100644 index 0000000000..a819e098d6 --- /dev/null +++ b/app/views/layouts/modal.html.haml @@ -0,0 +1,16 @@ +- content_for :header_tags do + = javascript_pack_tag 'public', integrity: true, crossorigin: 'anonymous' + +- content_for :content do + - if user_signed_in? + .account-header + .avatar= image_tag current_account.avatar.url(:original) + .name + = t 'users.signed_in_as' + %span.username @#{current_account.local_username_and_domain} + = link_to destroy_user_session_path, method: :delete, class: 'logout-link icon-button' do + = fa_icon 'sign-out' + + .container= yield + += render template: 'layouts/application' diff --git a/config/application.rb b/config/application.rb index 6bd47cd6c7..b6ce741477 100644 --- a/config/application.rb +++ b/config/application.rb @@ -81,7 +81,7 @@ module Mastodon config.middleware.use Rack::Deflater config.to_prepare do - Doorkeeper::AuthorizationsController.layout 'public' + Doorkeeper::AuthorizationsController.layout 'modal' Doorkeeper::AuthorizedApplicationsController.layout 'admin' Doorkeeper::Application.send :include, ApplicationExtension end diff --git a/config/initializers/doorkeeper.rb b/config/initializers/doorkeeper.rb index b618bf344d..056a3651a6 100644 --- a/config/initializers/doorkeeper.rb +++ b/config/initializers/doorkeeper.rb @@ -34,6 +34,11 @@ Doorkeeper.configure do # https://github.com/doorkeeper-gem/doorkeeper#custom-access-token-generator # access_token_generator "::Doorkeeper::JWT" + # The controller Doorkeeper::ApplicationController inherits from. + # Defaults to ActionController::Base. + # https://github.com/doorkeeper-gem/doorkeeper#custom-base-controller + base_controller 'ApplicationController' + # Reuse access token for the same resource owner within an application (disabled by default) # Rationale: https://github.com/doorkeeper-gem/doorkeeper/issues/383 reuse_access_token diff --git a/config/locales/ar.yml b/config/locales/ar.yml index ec051591ab..575c5114c2 100644 --- a/config/locales/ar.yml +++ b/config/locales/ar.yml @@ -43,7 +43,6 @@ ar: authorize_follow: error: Unfortunately, there was an error looking up the remote account follow: إتبع - prompt_html: 'You (%{self}) have requested to follow:' title: إتباع %{acct} datetime: distance_in_words: diff --git a/config/locales/bg.yml b/config/locales/bg.yml index 65ff5c0251..e7c3e1ef64 100644 --- a/config/locales/bg.yml +++ b/config/locales/bg.yml @@ -43,7 +43,6 @@ bg: authorize_follow: error: Възникна грешка в откриването на потребителя follow: Последвай - prompt_html: "(%{self}), молбата ти беше изпратена до:" title: Последвай %{acct} datetime: distance_in_words: diff --git a/config/locales/ca.yml b/config/locales/ca.yml index 725b120ec3..a9f9e4c932 100644 --- a/config/locales/ca.yml +++ b/config/locales/ca.yml @@ -185,7 +185,6 @@ ca: authorize_follow: error: Malauradament, ha ocorregut un error buscant el compte remot follow: Seguir - prompt_html: 'Tú (%{self}) has solicitat seguir:' title: Seguir %{acct} datetime: distance_in_words: diff --git a/config/locales/de.yml b/config/locales/de.yml index 87c5fa67a0..1f3675f477 100644 --- a/config/locales/de.yml +++ b/config/locales/de.yml @@ -166,7 +166,6 @@ de: authorize_follow: error: Das Profil konnte nicht geladen werden follow: Folgen - prompt_html: 'Du (%{self}) möchtest dieser Person folgen:' title: "%{acct} folgen" datetime: distance_in_words: diff --git a/config/locales/en.yml b/config/locales/en.yml index 1d092d20c0..d3f3d4f71e 100644 --- a/config/locales/en.yml +++ b/config/locales/en.yml @@ -215,7 +215,7 @@ en: body: "%{reporter} has reported %{target}" subject: New report for %{instance} (#%{id}) application_mailer: - salutation: '%{name},' + salutation: "%{name}," settings: 'Change e-mail preferences: %{link}' signature: Mastodon notifications from %{instance} view: 'View:' @@ -228,13 +228,13 @@ en: delete_account_html: If you wish to delete your account, you can proceed here. You will be asked for confirmation. didnt_get_confirmation: Didn't receive confirmation instructions? forgot_password: Forgot your password? + invalid_reset_password_token: Password reset link is invalid or expired. Please try again. login: Log in logout: Logout register: Sign up resend_confirmation: Resend confirmation instructions reset_password: Reset password set_new_password: Set new password - invalid_reset_password_token: Password reset link is invalid or expired. Please try again. authorize_follow: error: Unfortunately, there was an error looking up the remote account follow: Follow @@ -244,7 +244,6 @@ en: close: Or, you can just close this window. return: Return to the user's profile web: Go to web - prompt_html: 'You (%{self}) have requested to follow:' title: Follow %{acct} datetime: distance_in_words: @@ -524,3 +523,4 @@ en: users: invalid_email: The e-mail address is invalid invalid_otp_token: Invalid two-factor code + signed_in_as: 'Signed in as:' diff --git a/config/locales/eo.yml b/config/locales/eo.yml index 6673b6516a..f8b5ec0acf 100644 --- a/config/locales/eo.yml +++ b/config/locales/eo.yml @@ -42,7 +42,6 @@ eo: authorize_follow: error: Bedaŭrinde, okazis eraro provante konsulti la foran konton follow: Sekvi - prompt_html: 'Vi (%{self}) petis sekvi:' title: Sekvi %{acct} datetime: distance_in_words: diff --git a/config/locales/es.yml b/config/locales/es.yml index 89e2828d0b..d2d1de14f8 100644 --- a/config/locales/es.yml +++ b/config/locales/es.yml @@ -43,7 +43,6 @@ es: authorize_follow: error: Desafortunadamente, ha ocurrido un error buscando la cuenta remota follow: Seguir - prompt_html: 'Tú (%{self}) has solicitado seguir:' title: Seguir %{acct} datetime: distance_in_words: diff --git a/config/locales/fa.yml b/config/locales/fa.yml index eb66a9c410..a947cabd98 100644 --- a/config/locales/fa.yml +++ b/config/locales/fa.yml @@ -212,10 +212,10 @@ fa: title: مدیریت admin_mailer: new_report: - body: "کاربر %{reporter} کاربر %{target} را گزارش داد" + body: کاربر %{reporter} کاربر %{target} را گزارش داد subject: گزارش تازه‌ای برای %{instance} (#%{id}) application_mailer: - salutation: '%{name},' + salutation: "%{name}," settings: 'تغییر تنظیمات ایمیل: %{link}' signature: اعلان‌های ماستدون از %{instance} view: 'نمایش:' @@ -243,7 +243,6 @@ fa: close: یا این پنجره را ببندید. return: به نمایهٔ این کاربر بازگردید web: رفتن به وب - prompt_html: 'شما (%{self}) می‌خواهید این حساب را پی بگیرید:' title: پیگیری %{acct} datetime: distance_in_words: @@ -500,7 +499,7 @@ fa:

این نوشته تحت اجازه‌نامهٔ CC-BY-SA قرار دارد. تاریخ آخرین به‌روزرسانی آن ۱۰ خرداد ۱۳۹۲ است.

این نوشته اقتباسی است از سیاست رازداری Discourse.

- title: "شرایط استفاده و سیاست رازداری %{instance}" + title: شرایط استفاده و سیاست رازداری %{instance} time: formats: default: "%d %b %Y, %H:%M" diff --git a/config/locales/fi.yml b/config/locales/fi.yml index 23c844741c..b748f71846 100644 --- a/config/locales/fi.yml +++ b/config/locales/fi.yml @@ -42,7 +42,6 @@ fi: authorize_follow: error: Valitettavasti tapahtui virhe etätilin haussa. follow: Seuraa - prompt_html: 'Sinä (%{self}) olet pyytänyt lupaa seurata:' title: Seuraa %{acct} datetime: distance_in_words: diff --git a/config/locales/fr.yml b/config/locales/fr.yml index 7fde60a2be..04ab0253a8 100644 --- a/config/locales/fr.yml +++ b/config/locales/fr.yml @@ -235,7 +235,6 @@ fr: close: Ou bien, vous pouvez fermer cette fenêtre. return: Retour au profil de l'utilisateur⋅trice web: Retour à l'interface web - prompt_html: 'Vous (%{self}) avez demandé à suivre :' title: Suivre %{acct} datetime: distance_in_words: diff --git a/config/locales/he.yml b/config/locales/he.yml index 7772e6a76e..f04e8ad621 100644 --- a/config/locales/he.yml +++ b/config/locales/he.yml @@ -177,7 +177,6 @@ he: authorize_follow: error: למרבה הצער, היתה שגיאה בחיפוש החשבון המרוחק follow: לעקוב - prompt_html: 'בקשת מעקב ממך (%{self}) אחרי:' title: לעקוב אחרי %{acct} datetime: distance_in_words: diff --git a/config/locales/hr.yml b/config/locales/hr.yml index 2d43fcad81..52a8bd35f8 100644 --- a/config/locales/hr.yml +++ b/config/locales/hr.yml @@ -43,7 +43,6 @@ hr: authorize_follow: error: Nažalost, došlo je do greške looking up the remote račun follow: Slijedi - prompt_html: 'Ti si (%{self}) poslao zahtjev za sljeđenje:' title: Slijedi %{acct} datetime: distance_in_words: diff --git a/config/locales/id.yml b/config/locales/id.yml index 0d5937cfbb..c76b3d6bbe 100644 --- a/config/locales/id.yml +++ b/config/locales/id.yml @@ -168,7 +168,6 @@ id: authorize_follow: error: Sayangnya, ada error saat melihat akun remote follow: Ikuti - prompt_html: 'Anda (%{self}) telah diminta untuk mengikuti:' title: Mengikuti %{acct} datetime: distance_in_words: diff --git a/config/locales/io.yml b/config/locales/io.yml index c9abd57110..112771ee4f 100644 --- a/config/locales/io.yml +++ b/config/locales/io.yml @@ -166,7 +166,6 @@ io: authorize_follow: error: Regretinde, eventis eraro probante konsultar la fora konto follow: Sequar - prompt_html: 'Tu (%{self}) demandis sequar:' title: Sequar %{acct} datetime: distance_in_words: diff --git a/config/locales/it.yml b/config/locales/it.yml index de96825890..75d56362a6 100644 --- a/config/locales/it.yml +++ b/config/locales/it.yml @@ -43,7 +43,6 @@ it: authorize_follow: error: Sfortunatamente c'è stato un errore nel consultare l'account remoto follow: Segui - prompt_html: 'Tu, (%{self}), hai richiesto di seguire:' title: Segui %{acct} datetime: distance_in_words: diff --git a/config/locales/ja.yml b/config/locales/ja.yml index d87e77ffbd..2d3bda336c 100644 --- a/config/locales/ja.yml +++ b/config/locales/ja.yml @@ -242,7 +242,6 @@ ja: close: またはこのウィンドウを閉じます return: ユーザーのプロフィールに戻る web: Web を開く - prompt_html: 'あなた(%{self})は以下のアカウントのフォローをリクエストしました:' title: "%{acct} をフォロー" datetime: distance_in_words: diff --git a/config/locales/ko.yml b/config/locales/ko.yml index aae0e62e72..f3bde5bbb0 100644 --- a/config/locales/ko.yml +++ b/config/locales/ko.yml @@ -189,7 +189,6 @@ ko: authorize_follow: error: 리모트 팔로우 도중 오류가 발생했습니다. follow: 팔로우 - prompt_html: '나(%{self}) 는 아래 계정의 팔로우를 요청했습니다:' title: "%{acct} 를 팔로우" datetime: distance_in_words: diff --git a/config/locales/nl.yml b/config/locales/nl.yml index 272a71eed1..6562767a95 100644 --- a/config/locales/nl.yml +++ b/config/locales/nl.yml @@ -106,7 +106,7 @@ nl: domain: Domein new: create: Blokkade aanmaken - hint: Een domeinblokkade voorkomt niet dat accountgegevens van dit domein aan de database worden toegevoegd, maar dat er met terugwerkende kracht en automatisch bepaalde moderatiemethoden op deze accounts worden toegepast. + hint: Een domeinblokkade voorkomt niet dat accountgegevens van dit domein aan de database worden toegevoegd, maar dat er met terugwerkende kracht en automatisch bepaalde moderatiemethoden op deze accounts worden toegepast. severity: desc_html: "Negeren zorgt ervoor dat berichten van accounts van dit domein voor iedereen onzichtbaar zijn, behalve als een account wordt gevolgd. Opschorten zorgt ervoor dat alle berichten, media en profielgegevens van accounts van dit domein worden verwijderd. Gebruik Geen wanneer je alleen mediabestanden wilt weigeren." noop: Geen @@ -129,7 +129,7 @@ nl: suspend: Alle opgeschorste accounts van dit domein niet meer opschorten title: Domeinblokkade voor %{domain} ongedaan maken undo: Ongedaan maken - title: Domeinblokkades + title: Domeinblokkades undo: Ongedaan maken instances: account_count: Bekende accounts @@ -169,7 +169,7 @@ nl: title: Bericht wanneer registratie is uitgeschakeld deletion: desc_html: Toestaan dat iedereen hun eigen account kan verwijderen - title: Verwijderen account toestaan + title: Verwijderen account toestaan open: desc_html: Toestaan dat iedereen een account kan registereren title: Open registratie @@ -241,7 +241,6 @@ nl: close: Of je kan dit venster gewoon sluiten. return: Ga terug naar het profiel van de gebruiker web: Ga naar de webapp - prompt_html: 'Je (%{self}) hebt toestemming gevraagd om iemand te mogen volgen:' title: Volg %{acct} datetime: distance_in_words: @@ -307,7 +306,7 @@ nl: following: Volglijst muting: Negeerlijst upload: Uploaden - landing_strip_html: %{name} is een gebruiker op %{link_to_root_path}. Je kunt deze volgen en ermee communiceren als je ergens in deze fediverse een account hebt. + landing_strip_html: "%{name} is een gebruiker op %{link_to_root_path}. Je kunt deze volgen en ermee communiceren als je ergens in deze fediverse een account hebt." landing_strip_signup_html: Als je dat niet hebt, kun je je hier registreren. media_attachments: validations: @@ -510,7 +509,7 @@ nl: generate_recovery_codes: Herstelcodes genereren instructions_html: "Scan deze QR-code in Google Authenticator of een soortgelijke app op jouw mobiele telefoon. Van nu af aan genereert deze app aanmeldcodes die je bij het aanmelden moet invoeren." lost_recovery_codes: Met herstelcodes kun je toegang tot jouw account krijgen wanneer je jouw telefoon bent kwijtgeraakt. Wanneer je jouw herstelcodes bent kwijtgeraakt, kan je ze hier opnieuw genereren. Jouw oude herstelcodes zijn daarna ongeldig. - manual_instructions: 'Hieronder vind je de geheime code in platte tekst. Voor het geval je de QR-code niet kunt scannen en het handmatig moet invoeren.' + manual_instructions: Hieronder vind je de geheime code in platte tekst. Voor het geval je de QR-code niet kunt scannen en het handmatig moet invoeren. recovery_codes: Herstelcodes back-uppen recovery_codes_regenerated: Opnieuw genereren herstelcodes geslaagd recovery_instructions_html: Wanneer je ooit de toegang verliest tot jouw telefoon, kan je met behulp van een van de herstelcodes hieronder opnieuw toegang krijgen tot jouw account. Zorg ervoor dat je de herstelcodes op een veilige plek bewaard. (Je kunt ze bijvoorbeeld printen en ze samen met andere belangrijke documenten bewaren.) diff --git a/config/locales/no.yml b/config/locales/no.yml index b2e5773de0..996ea1d97f 100644 --- a/config/locales/no.yml +++ b/config/locales/no.yml @@ -170,7 +170,6 @@ authorize_follow: error: Uheldigvis så skjedde det en feil da vi prøvde å få tak i en bruker fra en annen instans. follow: Følg - prompt_html: 'Du (%{self}) har spurt om å følge:' title: Følg %{acct} datetime: distance_in_words: diff --git a/config/locales/oc.yml b/config/locales/oc.yml index 3e1cc3b6f8..784a70213e 100644 --- a/config/locales/oc.yml +++ b/config/locales/oc.yml @@ -31,7 +31,7 @@ oc: status_count_after: estatuts status_count_before: qu’an escrich user_count_after: personas - user_count_before: Ostal de + user_count_before: Ostal de what_is_mastodon: Qu’es Mastodon ? accounts: follow: Sègre @@ -243,7 +243,6 @@ oc: close: O podètz tampar aquesta fenèstra. return: Tornar al perfil web: Tornar a l’interfàcia Web - prompt_html: 'Avètz (%{self}) demandat de sègre :' title: Sègre %{acct} date: abbr_day_names: diff --git a/config/locales/pl.yml b/config/locales/pl.yml index bfd6b90915..05abf9291a 100644 --- a/config/locales/pl.yml +++ b/config/locales/pl.yml @@ -215,7 +215,7 @@ pl: body: Użytkownik %{reporter} zgłosił %{target} subject: Nowe zgłoszenie na %{instance} (#%{id}) application_mailer: - salutation: '%{name},' + salutation: "%{name}," settings: 'Zmień ustawienia powiadamiania: %{link}' signature: Powiadomienie Mastodona z instancji %{instance} view: 'Zobacz:' @@ -243,7 +243,6 @@ pl: close: Ewentualnie, możesz po prostu zamknąć tę stronę. return: Powróć do strony użytkownika web: Przejdź do sieci - prompt_html: 'Ty (%{self}) chcesz śledzić:' title: Śledź %{acct} datetime: distance_in_words: diff --git a/config/locales/pt-BR.yml b/config/locales/pt-BR.yml index 68b1c549ce..6dec2b50a6 100644 --- a/config/locales/pt-BR.yml +++ b/config/locales/pt-BR.yml @@ -169,7 +169,6 @@ pt-BR: authorize_follow: error: Infelizmente houve um erro olhando uma conta remota follow: Seguir - prompt_html: 'Você (%{self}) pediu pra seguir:' title: Seguir %{acct} datetime: distance_in_words: diff --git a/config/locales/ru.yml b/config/locales/ru.yml index 348f670b57..0156f0e95f 100644 --- a/config/locales/ru.yml +++ b/config/locales/ru.yml @@ -162,7 +162,6 @@ ru: authorize_follow: error: К сожалению, при поиске удаленного аккаунта возникла ошибка follow: Подписаться - prompt_html: 'Вы (%{self}) запросили подписку:' title: Подписаться на %{acct} datetime: distance_in_words: @@ -269,14 +268,14 @@ ru: truncate: "…" push_notifications: favourite: - title: "Ваш статус понравился %{name}" + title: Ваш статус понравился %{name} follow: title: "%{name} теперь подписан(а) на Вас" mention: action_boost: Продвинуть action_expand: Развернуть action_favourite: Нравится - title: "Вас упомянул(а) %{name}" + title: Вас упомянул(а) %{name} reblog: title: "%{name} продвинул(а) Ваш статус" subscribed: @@ -351,7 +350,7 @@ ru: reblogged: продвинул(а) sensitive_content: Чувствительный контент terms: - title: "Условия обслуживания и политика конфиденциальности %{instance}" + title: Условия обслуживания и политика конфиденциальности %{instance} time: formats: default: "%b %d, %Y, %H:%M" diff --git a/config/locales/th.yml b/config/locales/th.yml index 801f4886fa..9d08879282 100644 --- a/config/locales/th.yml +++ b/config/locales/th.yml @@ -170,7 +170,6 @@ th: authorize_follow: error: Unfortunately, there was an error looking up the remote account follow: ติดตาม - prompt_html: 'คุณ (%{self}) ขอติดตาม:' title: ติดตาม %{acct} datetime: distance_in_words: diff --git a/config/locales/tr.yml b/config/locales/tr.yml index ac378090c7..91ef9544cf 100644 --- a/config/locales/tr.yml +++ b/config/locales/tr.yml @@ -169,7 +169,6 @@ tr: authorize_follow: error: Uzak hesap aranırken bir hata oluştu. follow: Takip et - prompt_html: 'Siz (%{self}) bu kullanıcıyı takip etmek istiyor musunuz?:' title: "%{acct}'i takip et" datetime: distance_in_words: diff --git a/config/locales/uk.yml b/config/locales/uk.yml index 22fff6961d..4d12ddf4e8 100644 --- a/config/locales/uk.yml +++ b/config/locales/uk.yml @@ -160,7 +160,6 @@ uk: authorize_follow: error: На жаль, при пошуку віддаленого аккаунту виникла помилка follow: Підписатися - prompt_html: 'Ви (%{self}) запитали про підписку:' title: Підписатися на %{acct} datetime: distance_in_words: diff --git a/config/locales/zh-CN.yml b/config/locales/zh-CN.yml index 5018b48b80..0672202a21 100644 --- a/config/locales/zh-CN.yml +++ b/config/locales/zh-CN.yml @@ -176,7 +176,6 @@ zh-CN: authorize_follow: error: 对不起,寻找这个跨站用户时出错 follow: 关注 - prompt_html: 你 (%{self}) 正准备关注︰ title: 关注 %{acct} datetime: distance_in_words: diff --git a/config/locales/zh-HK.yml b/config/locales/zh-HK.yml index 40087ed532..9d6c74008a 100644 --- a/config/locales/zh-HK.yml +++ b/config/locales/zh-HK.yml @@ -169,7 +169,6 @@ zh-HK: authorize_follow: error: 對不起,尋找這個跨站用戶的過程發生錯誤 follow: 關注 - prompt_html: 你 (%{self}) 正準備關注︰ title: 關注 %{acct} datetime: distance_in_words: diff --git a/config/locales/zh-TW.yml b/config/locales/zh-TW.yml index 0ea3457c7e..7065acf9ab 100644 --- a/config/locales/zh-TW.yml +++ b/config/locales/zh-TW.yml @@ -140,7 +140,6 @@ zh-TW: authorize_follow: error: 對不起,尋找這個跨站使用者的過程發生錯誤 follow: 關注 - prompt_html: 您 (%{self}) 正準備關注︰ title: 關注 %{acct} datetime: distance_in_words: diff --git a/spec/controllers/auth/sessions_controller_spec.rb b/spec/controllers/auth/sessions_controller_spec.rb index 06fdbaabc3..88f0a4734d 100644 --- a/spec/controllers/auth/sessions_controller_spec.rb +++ b/spec/controllers/auth/sessions_controller_spec.rb @@ -28,7 +28,7 @@ RSpec.describe Auth::SessionsController, type: :controller do sign_in(user, scope: :user) delete :destroy - expect(response).to redirect_to(root_path) + expect(response).to redirect_to(new_user_session_path) end end @@ -38,7 +38,7 @@ RSpec.describe Auth::SessionsController, type: :controller do sign_in(user, scope: :user) delete :destroy - expect(response).to redirect_to(root_path) + expect(response).to redirect_to(new_user_session_path) end end end From 61a06eb328aa8c43487fcfd2529b9699b357b8c3 Mon Sep 17 00:00:00 2001 From: Eugen Rochko Date: Sat, 5 Aug 2017 15:29:52 +0200 Subject: [PATCH 17/32] Update goldfinger to 2.0.1, see tootsuite/goldfinger#5 (#4527) --- Gemfile.lock | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/Gemfile.lock b/Gemfile.lock index e5fd3506a3..e2430d153f 100644 --- a/Gemfile.lock +++ b/Gemfile.lock @@ -165,7 +165,7 @@ GEM ruby-progressbar (~> 1.4) globalid (0.4.0) activesupport (>= 4.2.0) - goldfinger (2.0.0) + goldfinger (2.0.1) addressable (~> 2.5) http (~> 2.2) nokogiri (~> 1.8) @@ -264,7 +264,7 @@ GEM mini_portile2 (~> 2.2.0) nokogumbo (1.4.13) nokogiri - oj (3.2.0) + oj (3.3.4) openssl (2.0.4) orm_adapter (0.5.0) ostatus2 (2.0.1) @@ -590,4 +590,4 @@ RUBY VERSION ruby 2.4.1p111 BUNDLED WITH - 1.15.2 + 1.15.3 From 5ee45fa5715af356f422a3b768359a52d94f4b79 Mon Sep 17 00:00:00 2001 From: MitarashiDango Date: Sun, 6 Aug 2017 03:33:41 +0900 Subject: [PATCH 18/32] fix columns_area.js (#4528) --- app/javascript/mastodon/features/ui/components/columns_area.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/app/javascript/mastodon/features/ui/components/columns_area.js b/app/javascript/mastodon/features/ui/components/columns_area.js index 7652d67a08..47d5a2e20b 100644 --- a/app/javascript/mastodon/features/ui/components/columns_area.js +++ b/app/javascript/mastodon/features/ui/components/columns_area.js @@ -55,7 +55,7 @@ export default class ColumnsArea extends ImmutablePureComponent { this.lastIndex = getIndex(this.context.router.history.location.pathname); this.setState({ shouldAnimate: true }); - if (this.props.children !== prevProps.children) { + if (this.props.children !== prevProps.children && !this.props.singleColumn) { scrollRight(this.node); } } From 021a83ead41276389129481f1118a3d48f399755 Mon Sep 17 00:00:00 2001 From: Quent-in Date: Sun, 6 Aug 2017 01:10:53 +0200 Subject: [PATCH 19/32] l10n OC - Added #4523 "signed in as" (#4529) Neutral form used. --- config/locales/oc.yml | 1 + 1 file changed, 1 insertion(+) diff --git a/config/locales/oc.yml b/config/locales/oc.yml index 784a70213e..6c3f95823a 100644 --- a/config/locales/oc.yml +++ b/config/locales/oc.yml @@ -580,3 +580,4 @@ oc: users: invalid_email: L’adreça de corrièl es invalida invalid_otp_token: Còdi d’autentificacion en dos temps invalid + signed_in_as: 'Session a' From 5eba129b0f5cbbf579011a512ef2e08f6e1e6854 Mon Sep 17 00:00:00 2001 From: Daigo 3 Dango Date: Sun, 6 Aug 2017 01:14:11 +0000 Subject: [PATCH 20/32] Translate 'Signed in as' into Japanese (#4530) --- config/locales/ja.yml | 1 + 1 file changed, 1 insertion(+) diff --git a/config/locales/ja.yml b/config/locales/ja.yml index 2d3bda336c..05c7122341 100644 --- a/config/locales/ja.yml +++ b/config/locales/ja.yml @@ -521,3 +521,4 @@ ja: users: invalid_email: メールアドレスが無効です invalid_otp_token: 二段階認証コードが間違っています + signed_in_as: '下記でログイン中:' From d1d465347a21886ae1d0e10055a210c4d7060631 Mon Sep 17 00:00:00 2001 From: Komic Date: Sun, 6 Aug 2017 10:36:10 +0200 Subject: [PATCH 21/32] fr.yml update (#4531) Translation for https://github.com/tootsuite/mastodon/pull/4523 --- config/locales/fr.yml | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/config/locales/fr.yml b/config/locales/fr.yml index 04ab0253a8..bff6114ff8 100644 --- a/config/locales/fr.yml +++ b/config/locales/fr.yml @@ -220,6 +220,7 @@ fr: delete_account_html: Si vous désirez supprimer votre compte, vous pouvez cliquer ici. Il vous sera demandé de confirmer cette action. didnt_get_confirmation: Vous n’avez pas reçu les consignes de confirmation ? forgot_password: Mot de passe oublié ? + invalid_reset_password_token: Le lien de réinitialisation du mot de passe est invalide ou a expiré. Merci de réessayer. login: Se connecter logout: Se déconnecter register: S’inscrire @@ -277,7 +278,7 @@ fr: blocks: Vous bloquez csv: CSV follows: Vous suivez - mutes: Vous faites taire + mutes: Vous masquez storage: Médias stockés followers: domain: Domaine @@ -304,7 +305,7 @@ fr: types: blocking: Liste d’utilisateur⋅ice⋅s bloqué⋅es following: Liste d’utilisateur⋅ice⋅s suivi⋅es - muting: Liste d’utilisateur⋅ice⋅s que vous faites taire + muting: Liste d’utilisateur⋅ice⋅s que vous masquez upload: Importer landing_strip_html: %{name} utilise %{link_to_root_path}. Vous pouvez le/la suivre et interagir si vous possédez un compte quelque part dans le "fediverse". landing_strip_signup_html: Si ce n’est pas le cas, vous pouvez en créer un ici. @@ -450,3 +451,4 @@ fr: users: invalid_email: L’adresse courriel est invalide invalid_otp_token: Le code d’authentification à deux facteurs est invalide + signed_in_as: 'Connecté•e en tant que:' From 71384b2ef915c3c4e8fe15a464a33afecb5a723e Mon Sep 17 00:00:00 2001 From: Komic Date: Sun, 6 Aug 2017 14:52:12 +0200 Subject: [PATCH 22/32] Fix #4531 (#4533) wrong character, sorry about that~ --- config/locales/fr.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/config/locales/fr.yml b/config/locales/fr.yml index bff6114ff8..d7aa414971 100644 --- a/config/locales/fr.yml +++ b/config/locales/fr.yml @@ -451,4 +451,4 @@ fr: users: invalid_email: L’adresse courriel est invalide invalid_otp_token: Le code d’authentification à deux facteurs est invalide - signed_in_as: 'Connecté•e en tant que:' + signed_in_as: 'Connecté·e en tant que :' From e7a5a188efc86fb5f2a37dc306bcc3f8cfc6302e Mon Sep 17 00:00:00 2001 From: Masoud Abkenar Date: Sun, 6 Aug 2017 23:50:20 +0200 Subject: [PATCH 23/32] i18n: update Persian translation (#4540) --- app/javascript/mastodon/locales/fa.json | 4 ++-- config/locales/fa.yml | 10 +++++----- config/locales/simple_form.fa.yml | 2 +- 3 files changed, 8 insertions(+), 8 deletions(-) diff --git a/app/javascript/mastodon/locales/fa.json b/app/javascript/mastodon/locales/fa.json index d2682ef12a..5ada62f934 100644 --- a/app/javascript/mastodon/locales/fa.json +++ b/app/javascript/mastodon/locales/fa.json @@ -1,7 +1,7 @@ { "account.block": "مسدودسازی @{name}", "account.block_domain": "پنهان‌سازی همه چیز از سرور {domain}", - "account.disclaimer_full": "Information below may reflect the user's profile incompletely.", + "account.disclaimer_full": "اطلاعات زیر ممکن است نمایهٔ این کاربر را به تمامی نشان ندهد.", "account.edit_profile": "ویرایش نمایه", "account.follow": "پی بگیرید", "account.followers": "پیگیران", @@ -13,7 +13,7 @@ "account.posts": "نوشته‌ها", "account.report": "گزارش @{name}", "account.requested": "در انتظار پذیرش", - "account.share": "Share @{name}'s profile", + "account.share": "هم‌رسانی نمایهٔ @{name}", "account.unblock": "رفع انسداد @{name}", "account.unblock_domain": "رفع پنهان‌سازی از {domain}", "account.unfollow": "پایان پیگیری", diff --git a/config/locales/fa.yml b/config/locales/fa.yml index a947cabd98..0c575e23e2 100644 --- a/config/locales/fa.yml +++ b/config/locales/fa.yml @@ -2,7 +2,7 @@ fa: about: about_mastodon_html: ماستدون (Mastodon) یک شبکهٔ اجتماعی است که بر اساس پروتکل‌های آزاد وب و نرم‌افزارهای آزاد و کدباز ساخته شده است. این شبکه مانند ایمیل غیرمتمرکز است. - about_this: درباره. + about_this: درباره closed_registrations: ثبت‌نام روی این سرور هم‌اینک فعال نیست. اما شما می‌توانید سرور دیگری بیابید و با حسابی که آن‌جا می‌سازید دقیقاً به همین شبکه دسترسی داشته باشید. contact: تماس contact_missing: تعیین نشده @@ -20,11 +20,11 @@ fa: not_a_product_title: شما یک انسان هستید، نه یک محصول real_conversation_body: با ۵۰۰ نویسه برای هر نوشته و با پشتیبانی از هشدارهای موردی برای نوشته‌ها و تصاویر، می‌توانید خود را همان گونه که می‌خواهید ابراز کنید. real_conversation_title: برای گفتگوهای واقعی - within_reach_body: اپ‌های متنوع برای iOS، اندروید، و سیستم‌های دیگر به خاطر وحود یک اکوسیستم API دوستانه برای برنامه‌نویسان. از همه جا با دوستان خود ارتباط داشته باشید. + within_reach_body: اپ‌های متنوع برای iOS، اندروید، و سیستم‌های دیگر به خاطر وجود یک اکوسیستم API دوستانه برای برنامه‌نویسان. از همه جا با دوستان خود ارتباط داشته باشید. within_reach_title: همیشه در دسترس find_another_instance: یافتن سرورهای دیگر generic_description: "%{domain} یک سرور روی شبکه است" - hosted_on: ماستدون میزبانی‌شده روی %{domain} + hosted_on: ماستدون، میزبانی‌شده روی %{domain} learn_more: بیشتر بدانید other_instances: فهرست سرورها source_code: کدهای منبع @@ -432,7 +432,7 @@ fa: sensitive_content: محتوای حساس terms: body_html: | -

Privacy Policy

+

سیاست رازداری (Privacy Policy)

ما چه اطلاعاتی را گردآوری می‌کنیم؟

@@ -450,7 +450,7 @@ fa:
  • برای شخصی‌سازی تجربهٔ کاربری شما — ما به کمک اطلاعات شما بهتر می‌توانیم نیازهای شما را برآورده کنیم.
  • برای بهتر کردن سایت — ما پیوسته می‌کوشیم تا خدمات این سایت را به کمک اطلاعات و بازخوردی که از شما می‌گیریم بهتر کنیم.
  • برای بهتر کردن خدمات به کاربران — ما به کمک اطلاعات شما به طور مؤثرتری می‌توانیم به درخواست‌های پشتیبانی شما پاسخ دهیم.
  • -
  • برای فرستادن ایمیل‌های دوره‌ای — ما گاهی به نشانی ایمیلی که وارد کرده‌اید نامه می‌فرستیم تا درخواست‌های شما پاسخ دهیم یا شما را در جریان پاسخ دیگران به شما قرار دهیم.
  • +
  • برای فرستادن ایمیل‌های دوره‌ای — ما گاهی به نشانی ایمیلی که وارد کرده‌اید نامه می‌فرستیم تا به درخواست‌های شما پاسخ دهیم یا شما را در جریان پاسخ دیگران به شما قرار دهیم.
  • ما چگونه از اطلاعات شما محافظت می‌کنیم؟

    diff --git a/config/locales/simple_form.fa.yml b/config/locales/simple_form.fa.yml index 71a9d6e1fc..dd72a19bda 100644 --- a/config/locales/simple_form.fa.yml +++ b/config/locales/simple_form.fa.yml @@ -40,7 +40,7 @@ fa: setting_boost_modal: نمایش پیغام تأیید پیش از بازبوقیدن setting_default_privacy: حریم خصوصی نوشته‌ها setting_default_sensitive: همیشه تصاویر را به عنوان حساس علامت بزن - setting_delete_modal: پیش از پاک کردن یک بوق پیغام تأیید نشان بده + setting_delete_modal: پیش از پاک کردن یک نوشته پیغام تأیید نشان بده setting_noindex: درخواست از موتورهای جستجو برای لغو فهرست‌سازی setting_system_font_ui: به‌کاربردن قلم پیش‌فرض سیستم setting_unfollow_modal: نمایش پیغام تأیید پیش از لغو پیگیری دیگران From 41c3389d76e3f34bd77ff474dfb4298d5a390dc1 Mon Sep 17 00:00:00 2001 From: Eugen Rochko Date: Sun, 6 Aug 2017 23:53:25 +0200 Subject: [PATCH 24/32] Bump to 1.5.1 --- lib/mastodon/version.rb | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/lib/mastodon/version.rb b/lib/mastodon/version.rb index aeb5492dc6..381e9aac92 100644 --- a/lib/mastodon/version.rb +++ b/lib/mastodon/version.rb @@ -13,7 +13,7 @@ module Mastodon end def patch - 0 + 1 end def pre From 87f10d476cf7a05bc60851c93e3c051eca8c357e Mon Sep 17 00:00:00 2001 From: Yamagishi Kazutoshi Date: Mon, 7 Aug 2017 21:41:21 +0900 Subject: [PATCH 25/32] Set false to animated options for thumbnail processor (#4547) Resolve #3199 Fix the aspect ratio of animated GIF whose background is transparent. --- app/models/concerns/account_avatar.rb | 2 +- app/models/concerns/account_header.rb | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/app/models/concerns/account_avatar.rb b/app/models/concerns/account_avatar.rb index a6527a85bc..b0ec689a73 100644 --- a/app/models/concerns/account_avatar.rb +++ b/app/models/concerns/account_avatar.rb @@ -8,7 +8,7 @@ module AccountAvatar class_methods do def avatar_styles(file) styles = { original: '120x120#' } - styles[:static] = { format: 'png' } if file.content_type == 'image/gif' + styles[:static] = { animated: false } if file.content_type == 'image/gif' styles end diff --git a/app/models/concerns/account_header.rb b/app/models/concerns/account_header.rb index 4ba9212a25..542e25abe2 100644 --- a/app/models/concerns/account_header.rb +++ b/app/models/concerns/account_header.rb @@ -8,7 +8,7 @@ module AccountHeader class_methods do def header_styles(file) styles = { original: '700x335#' } - styles[:static] = { format: 'png' } if file.content_type == 'image/gif' + styles[:static] = { animated: false } if file.content_type == 'image/gif' styles end From 3363a05539c0c774fca4651755e6423fe131d205 Mon Sep 17 00:00:00 2001 From: m4sk1n Date: Mon, 7 Aug 2017 14:55:25 +0200 Subject: [PATCH 26/32] i18n: Update Polish translation (#4545) --- config/locales/pl.yml | 2 ++ 1 file changed, 2 insertions(+) diff --git a/config/locales/pl.yml b/config/locales/pl.yml index 05abf9291a..415c3b9931 100644 --- a/config/locales/pl.yml +++ b/config/locales/pl.yml @@ -228,6 +228,7 @@ pl: delete_account_html: Jeżeli chcesz usunąć konto, przejdź tutaj. Otrzymasz prośbę o potwierdzenie. didnt_get_confirmation: Nie otrzymałeś instrukcji weryfikacji? forgot_password: Nie pamiętasz hasła? + invalid_reset_password_token: Token do resetowania hasła jest nieprawidłowy lub utracił ważność. Spróbuj uzyskać nowy. login: Zaloguj się logout: Wyloguj się register: Rejestracja @@ -526,3 +527,4 @@ pl: users: invalid_email: Adres e-mail jest niepoprawny invalid_otp_token: Kod uwierzytelniający jest niepoprawny + signed_in_as: 'Zalogowany jako:' From 47579ec58ce984acc9f194f8cb145abd88d0ea19 Mon Sep 17 00:00:00 2001 From: m4sk1n Date: Mon, 7 Aug 2017 17:20:21 +0200 Subject: [PATCH 27/32] It makes no sense to try using invalid or expired link again (#4521) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: Marcin Mikołajczak --- config/locales/en.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/config/locales/en.yml b/config/locales/en.yml index d3f3d4f71e..1fa0de90b2 100644 --- a/config/locales/en.yml +++ b/config/locales/en.yml @@ -228,7 +228,7 @@ en: delete_account_html: If you wish to delete your account, you can proceed here. You will be asked for confirmation. didnt_get_confirmation: Didn't receive confirmation instructions? forgot_password: Forgot your password? - invalid_reset_password_token: Password reset link is invalid or expired. Please try again. + invalid_reset_password_token: Password reset token is invalid or expired. Please request a new one. login: Log in logout: Logout register: Sign up From 5d408fd9aa76f9ef3d559a377bccbcece998fbfa Mon Sep 17 00:00:00 2001 From: Thomas Leister Date: Mon, 7 Aug 2017 18:55:07 +0200 Subject: [PATCH 28/32] [Docker] Add multicore support to "make" and "bundler" (#4544) * Let make and bundler use multiple cores * Adds -j option to bundle install instead of bundle config --- Dockerfile | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/Dockerfile b/Dockerfile index 93a8ffd0b4..398628a488 100644 --- a/Dockerfile +++ b/Dockerfile @@ -48,7 +48,7 @@ RUN echo "@edge https://nl.alpinelinux.org/alpine/edge/main" >> /etc/apk/reposit && rm libiconv.tar.gz \ && cd /tmp/src/libiconv-$LIBICONV_VERSION \ && ./configure --prefix=/usr/local \ - && make \ + && make -j$(getconf _NPROCESSORS_ONLN)\ && make install \ && libtool --finish /usr/local/lib \ && cd /mastodon \ @@ -57,7 +57,7 @@ RUN echo "@edge https://nl.alpinelinux.org/alpine/edge/main" >> /etc/apk/reposit COPY Gemfile Gemfile.lock package.json yarn.lock /mastodon/ RUN bundle config build.nokogiri --with-iconv-lib=/usr/local/lib --with-iconv-include=/usr/local/include \ - && bundle install --deployment --without test development \ + && bundle install -j$(getconf _NPROCESSORS_ONLN) --deployment --without test development \ && yarn --ignore-optional --pure-lockfile COPY . /mastodon From 22db9472253f6ffcfed254f7a406a58b53e80cfe Mon Sep 17 00:00:00 2001 From: Yamagishi Kazutoshi Date: Tue, 8 Aug 2017 01:55:36 +0900 Subject: [PATCH 29/32] Update dependencies for Ruby (#4543) * Update twitter-text to version 1.14.7 * Update tilt to version 2.0.8 * Update statsd-instrument to version 2.1.4 * Update sidekiq to version 5.0.4 * Update sidekiq-scheduler to version 2.1.8 * Update sidekiq-unique-jobs to version 5.0.9 * Update redis-activesupport to version 5.0.3 * Update rails-settings-cached to version v0.6.6 * Update pkg-config to version 1.2.4 * Update parallel_tests to version 2.14.2 * Update jsonapi-renderer to version 0.1.3 * Update i18n-tasks to version 0.9.16 * Update httplog to version 0.99.7 * Update fabrication to version 2.16.2 * Update bootsnap to version 1.1.2 * Update aws-sigv4 to version 1.0.1 * Update aws-sdk-core to version 2.10.21 * Update hashdiff to version 0.3.5 * Update rails to version 5.1.3 --- Gemfile.lock | 114 +++++++++++++++++++++++++-------------------------- 1 file changed, 57 insertions(+), 57 deletions(-) diff --git a/Gemfile.lock b/Gemfile.lock index e2430d153f..7a4dbab851 100644 --- a/Gemfile.lock +++ b/Gemfile.lock @@ -1,25 +1,25 @@ GEM remote: https://rubygems.org/ specs: - actioncable (5.1.2) - actionpack (= 5.1.2) + actioncable (5.1.3) + actionpack (= 5.1.3) nio4r (~> 2.0) websocket-driver (~> 0.6.1) - actionmailer (5.1.2) - actionpack (= 5.1.2) - actionview (= 5.1.2) - activejob (= 5.1.2) + actionmailer (5.1.3) + actionpack (= 5.1.3) + actionview (= 5.1.3) + activejob (= 5.1.3) mail (~> 2.5, >= 2.5.4) rails-dom-testing (~> 2.0) - actionpack (5.1.2) - actionview (= 5.1.2) - activesupport (= 5.1.2) + actionpack (5.1.3) + actionview (= 5.1.3) + activesupport (= 5.1.3) rack (~> 2.0) rack-test (~> 0.6.3) rails-dom-testing (~> 2.0) rails-html-sanitizer (~> 1.0, >= 1.0.2) - actionview (5.1.2) - activesupport (= 5.1.2) + actionview (5.1.3) + activesupport (= 5.1.3) builder (~> 3.1) erubi (~> 1.4) rails-dom-testing (~> 2.0) @@ -30,16 +30,16 @@ GEM case_transform (>= 0.2) jsonapi-renderer (>= 0.1.1.beta1, < 0.2) active_record_query_trace (1.5.4) - activejob (5.1.2) - activesupport (= 5.1.2) + activejob (5.1.3) + activesupport (= 5.1.3) globalid (>= 0.3.6) - activemodel (5.1.2) - activesupport (= 5.1.2) - activerecord (5.1.2) - activemodel (= 5.1.2) - activesupport (= 5.1.2) + activemodel (5.1.3) + activesupport (= 5.1.3) + activerecord (5.1.3) + activemodel (= 5.1.3) + activesupport (= 5.1.3) arel (~> 8.0) - activesupport (5.1.2) + activesupport (5.1.3) concurrent-ruby (~> 1.0, >= 1.0.2) i18n (~> 0.7) minitest (~> 5.1) @@ -57,14 +57,14 @@ GEM encryptor (~> 3.0.0) av (0.9.0) cocaine (~> 0.5.3) - aws-sdk (2.10.6) - aws-sdk-resources (= 2.10.6) - aws-sdk-core (2.10.6) + aws-sdk (2.10.21) + aws-sdk-resources (= 2.10.21) + aws-sdk-core (2.10.21) aws-sigv4 (~> 1.0) jmespath (~> 1.0) - aws-sdk-resources (2.10.6) - aws-sdk-core (= 2.10.6) - aws-sigv4 (1.0.0) + aws-sdk-resources (2.10.21) + aws-sdk-core (= 2.10.21) + aws-sigv4 (1.0.1) bcrypt (3.1.11) better_errors (2.1.1) coderay (>= 1.0.0) @@ -72,7 +72,7 @@ GEM rack (>= 0.9.0) binding_of_caller (0.7.2) debug_inspector (>= 0.0.1) - bootsnap (1.1.1) + bootsnap (1.1.2) msgpack (~> 1.0) brakeman (3.6.2) browser (2.4.0) @@ -155,7 +155,7 @@ GEM et-orbi (1.0.5) tzinfo execjs (2.7.0) - fabrication (2.16.1) + fabrication (2.16.2) faker (1.7.3) i18n (~> 0.5) fast_blank (1.0.0) @@ -179,7 +179,7 @@ GEM activesupport (>= 4.0.1) hamlit (>= 1.2.0) railties (>= 4.0.1) - hashdiff (0.3.4) + hashdiff (0.3.5) highline (1.7.8) hiredis (0.6.1) hkdf (0.3.0) @@ -194,11 +194,11 @@ GEM http-form_data (1.0.3) http_accept_language (2.1.1) http_parser.rb (0.6.0) - httplog (0.99.4) + httplog (0.99.7) colorize rack - i18n (0.8.4) - i18n-tasks (0.9.15) + i18n (0.8.6) + i18n-tasks (0.9.16) activesupport (>= 4.0.2) ast (>= 2.1.0) easy_translate (>= 0.5.0) @@ -211,7 +211,7 @@ GEM idn-ruby (0.1.0) jmespath (1.3.1) json (2.1.0) - jsonapi-renderer (0.1.2) + jsonapi-renderer (0.1.3) jwt (1.5.6) kaminari (1.0.1) activesupport (>= 4.1.0) @@ -253,7 +253,7 @@ GEM mime-types-data (3.2016.0521) mimemagic (0.3.2) mini_portile2 (2.2.0) - minitest (5.10.2) + minitest (5.10.3) msgpack (1.1.0) multi_json (1.12.1) net-scp (1.2.1) @@ -283,14 +283,14 @@ GEM av (~> 0.9.0) paperclip (>= 2.5.2) parallel (1.11.2) - parallel_tests (2.14.1) + parallel_tests (2.14.2) parallel parser (2.4.0.0) ast (~> 2.2) pg (0.21.0) pghero (1.7.0) activerecord - pkg-config (1.2.3) + pkg-config (1.2.4) powerpack (0.1.1) pry (0.10.4) coderay (~> 1.1.0) @@ -313,17 +313,17 @@ GEM rack-test (0.6.3) rack (>= 1.0) rack-timeout (0.4.2) - rails (5.1.2) - actioncable (= 5.1.2) - actionmailer (= 5.1.2) - actionpack (= 5.1.2) - actionview (= 5.1.2) - activejob (= 5.1.2) - activemodel (= 5.1.2) - activerecord (= 5.1.2) - activesupport (= 5.1.2) - bundler (>= 1.3.0, < 2.0) - railties (= 5.1.2) + rails (5.1.3) + actioncable (= 5.1.3) + actionmailer (= 5.1.3) + actionpack (= 5.1.3) + actionview (= 5.1.3) + activejob (= 5.1.3) + activemodel (= 5.1.3) + activerecord (= 5.1.3) + activesupport (= 5.1.3) + bundler (>= 1.3.0) + railties (= 5.1.3) sprockets-rails (>= 2.0.0) rails-controller-testing (1.0.2) actionpack (~> 5.x, >= 5.0.1) @@ -337,11 +337,11 @@ GEM rails-i18n (5.0.4) i18n (~> 0.7) railties (~> 5.0) - rails-settings-cached (0.6.5) + rails-settings-cached (0.6.6) rails (>= 4.2.0) - railties (5.1.2) - actionpack (= 5.1.2) - activesupport (= 5.1.2) + railties (5.1.3) + actionpack (= 5.1.3) + activesupport (= 5.1.3) method_source rake (>= 0.8.7) thor (>= 0.18.1, < 2.0) @@ -353,7 +353,7 @@ GEM actionpack (>= 4.0, < 6) redis-rack (>= 1, < 3) redis-store (>= 1.1.0, < 1.4.0) - redis-activesupport (5.0.2) + redis-activesupport (5.0.3) activesupport (>= 3, < 6) redis-store (~> 1.3.0) redis-namespace (1.5.3) @@ -413,7 +413,7 @@ GEM scss_lint (0.54.0) rake (>= 0.9, < 13) sass (~> 3.4.20) - sidekiq (5.0.3) + sidekiq (5.0.4) concurrent-ruby (~> 1.0) connection_pool (~> 2.2, >= 2.2.0) rack-protection (>= 1.5.0) @@ -421,12 +421,12 @@ GEM sidekiq-bulk (0.1.1) activesupport sidekiq - sidekiq-scheduler (2.1.7) + sidekiq-scheduler (2.1.8) redis (~> 3) rufus-scheduler (~> 3.2) sidekiq (>= 3) tilt (>= 1.4.0) - sidekiq-unique-jobs (5.0.8) + sidekiq-unique-jobs (5.0.9) sidekiq (>= 4.0, <= 6.0) thor (~> 0) simple-navigation (4.0.5) @@ -450,15 +450,15 @@ GEM sshkit (1.13.1) net-scp (>= 1.1.2) net-ssh (>= 2.8.0) - statsd-instrument (2.1.2) + statsd-instrument (2.1.4) temple (0.8.0) terminal-table (1.8.0) unicode-display_width (~> 1.1, >= 1.1.1) thor (0.19.4) thread (0.2.2) thread_safe (0.3.6) - tilt (2.0.7) - twitter-text (1.14.6) + tilt (2.0.8) + twitter-text (1.14.7) unf (~> 0.1.0) tzinfo (1.2.3) thread_safe (~> 0.1) From 594234740788a51fa528152343eb50dc1c6ca093 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ond=C5=99ej=20Hru=C5=A1ka?= Date: Mon, 7 Aug 2017 19:44:55 +0200 Subject: [PATCH 30/32] Refactor Avatar and AvatarOverlay to have 'account' as prop instead of src and staticSrc (#4526) * Refactored Avatar and AvatarOverlay (DRY) to have 'account' as prop. Also removed animate attribute from compose navigation bar, which should have never been there. Added test for avatar overlay. * fix broken tests * god dammit another bug in tests! travis please let this pass * formatting in avatar overlay --- app/javascript/mastodon/components/account.js | 2 +- app/javascript/mastodon/components/avatar.js | 9 +++-- .../mastodon/components/avatar_overlay.js | 12 +++---- app/javascript/mastodon/components/status.js | 4 +-- .../compose/components/autosuggest_account.js | 2 +- .../compose/components/navigation_bar.js | 2 +- .../compose/components/reply_indicator.js | 2 +- .../components/account_authorize.js | 2 +- .../status/components/detailed_status.js | 2 +- .../features/ui/components/actions_modal.js | 2 +- .../features/ui/components/boost_modal.js | 2 +- spec/javascript/components/avatar.test.js | 30 +++++++++++++--- .../components/avatar_overlay.test.js | 34 +++++++++++++++++++ 13 files changed, 82 insertions(+), 23 deletions(-) create mode 100644 spec/javascript/components/avatar_overlay.test.js diff --git a/app/javascript/mastodon/components/account.js b/app/javascript/mastodon/components/account.js index b6ca0661fb..69cc63d106 100644 --- a/app/javascript/mastodon/components/account.js +++ b/app/javascript/mastodon/components/account.js @@ -70,7 +70,7 @@ export default class Account extends ImmutablePureComponent {
    -
    +
    diff --git a/app/javascript/mastodon/components/avatar.js b/app/javascript/mastodon/components/avatar.js index 4f81706576..f7c484ee3a 100644 --- a/app/javascript/mastodon/components/avatar.js +++ b/app/javascript/mastodon/components/avatar.js @@ -1,11 +1,11 @@ import React from 'react'; import PropTypes from 'prop-types'; +import ImmutablePropTypes from 'react-immutable-proptypes'; export default class Avatar extends React.PureComponent { static propTypes = { - src: PropTypes.string.isRequired, - staticSrc: PropTypes.string, + account: ImmutablePropTypes.map.isRequired, size: PropTypes.number.isRequired, style: PropTypes.object, animate: PropTypes.bool, @@ -33,9 +33,12 @@ export default class Avatar extends React.PureComponent { } render () { - const { src, size, staticSrc, animate, inline } = this.props; + const { account, size, animate, inline } = this.props; const { hovering } = this.state; + const src = account.get('avatar'); + const staticSrc = account.get('avatar_static'); + let className = 'account__avatar'; if (inline) { diff --git a/app/javascript/mastodon/components/avatar_overlay.js b/app/javascript/mastodon/components/avatar_overlay.js index de43e0ef51..f5d67b34e8 100644 --- a/app/javascript/mastodon/components/avatar_overlay.js +++ b/app/javascript/mastodon/components/avatar_overlay.js @@ -1,22 +1,22 @@ import React from 'react'; -import PropTypes from 'prop-types'; +import ImmutablePropTypes from 'react-immutable-proptypes'; export default class AvatarOverlay extends React.PureComponent { static propTypes = { - staticSrc: PropTypes.string.isRequired, - overlaySrc: PropTypes.string.isRequired, + account: ImmutablePropTypes.map.isRequired, + friend: ImmutablePropTypes.map.isRequired, }; render() { - const { staticSrc, overlaySrc } = this.props; + const { account, friend } = this.props; const baseStyle = { - backgroundImage: `url(${staticSrc})`, + backgroundImage: `url(${account.get('avatar_static')})`, }; const overlayStyle = { - backgroundImage: `url(${overlaySrc})`, + backgroundImage: `url(${friend.get('avatar_static')})`, }; return ( diff --git a/app/javascript/mastodon/components/status.js b/app/javascript/mastodon/components/status.js index ceb512d960..25879c4973 100644 --- a/app/javascript/mastodon/components/status.js +++ b/app/javascript/mastodon/components/status.js @@ -228,9 +228,9 @@ export default class Status extends ImmutablePureComponent { } if (account === undefined || account === null) { - statusAvatar = ; + statusAvatar = ; }else{ - statusAvatar = ; + statusAvatar = ; } return ( diff --git a/app/javascript/mastodon/features/compose/components/autosuggest_account.js b/app/javascript/mastodon/features/compose/components/autosuggest_account.js index ebfa3c247b..e7de3716ba 100644 --- a/app/javascript/mastodon/features/compose/components/autosuggest_account.js +++ b/app/javascript/mastodon/features/compose/components/autosuggest_account.js @@ -15,7 +15,7 @@ export default class AutosuggestAccount extends ImmutablePureComponent { return (
    -
    +
    ); diff --git a/app/javascript/mastodon/features/compose/components/navigation_bar.js b/app/javascript/mastodon/features/compose/components/navigation_bar.js index cd2dd8f616..7f346854ce 100644 --- a/app/javascript/mastodon/features/compose/components/navigation_bar.js +++ b/app/javascript/mastodon/features/compose/components/navigation_bar.js @@ -19,7 +19,7 @@ export default class NavigationBar extends ImmutablePureComponent {
    {this.props.account.get('acct')} - +
    diff --git a/app/javascript/mastodon/features/compose/components/reply_indicator.js b/app/javascript/mastodon/features/compose/components/reply_indicator.js index da00e46c51..35a9b4b1b4 100644 --- a/app/javascript/mastodon/features/compose/components/reply_indicator.js +++ b/app/javascript/mastodon/features/compose/components/reply_indicator.js @@ -51,7 +51,7 @@ export default class ReplyIndicator extends ImmutablePureComponent {
    -
    +
    diff --git a/app/javascript/mastodon/features/follow_requests/components/account_authorize.js b/app/javascript/mastodon/features/follow_requests/components/account_authorize.js index 566953ddd6..66fa5c235c 100644 --- a/app/javascript/mastodon/features/follow_requests/components/account_authorize.js +++ b/app/javascript/mastodon/features/follow_requests/components/account_authorize.js @@ -32,7 +32,7 @@ export default class AccountAuthorize extends ImmutablePureComponent {
    -
    +
    diff --git a/app/javascript/mastodon/features/status/components/detailed_status.js b/app/javascript/mastodon/features/status/components/detailed_status.js index 619957dbe7..940a2699b7 100644 --- a/app/javascript/mastodon/features/status/components/detailed_status.js +++ b/app/javascript/mastodon/features/status/components/detailed_status.js @@ -59,7 +59,7 @@ export default class DetailedStatus extends ImmutablePureComponent { return (
    -
    +
    diff --git a/app/javascript/mastodon/features/ui/components/actions_modal.js b/app/javascript/mastodon/features/ui/components/actions_modal.js index cc0620d1c4..3d40033be1 100644 --- a/app/javascript/mastodon/features/ui/components/actions_modal.js +++ b/app/javascript/mastodon/features/ui/components/actions_modal.js @@ -46,7 +46,7 @@ export default class ActionsModal extends ImmutablePureComponent {
    - +
    diff --git a/app/javascript/mastodon/features/ui/components/boost_modal.js b/app/javascript/mastodon/features/ui/components/boost_modal.js index 6c80a10844..0e9592c977 100644 --- a/app/javascript/mastodon/features/ui/components/boost_modal.js +++ b/app/javascript/mastodon/features/ui/components/boost_modal.js @@ -62,7 +62,7 @@ export default class BoostModal extends ImmutablePureComponent {
    - +
    diff --git a/spec/javascript/components/avatar.test.js b/spec/javascript/components/avatar.test.js index 03b71dc9d9..ee40812caf 100644 --- a/spec/javascript/components/avatar.test.js +++ b/spec/javascript/components/avatar.test.js @@ -1,20 +1,42 @@ import { expect } from 'chai'; import { render } from 'enzyme'; +import { fromJS } from 'immutable'; import React from 'react'; import Avatar from '../../../app/javascript/mastodon/components/avatar'; describe('', () => { - const src = '/path/to/image.jpg'; + const account = fromJS({ + username: 'alice', + acct: 'alice', + display_name: 'Alice', + avatar: '/animated/alice.gif', + avatar_static: '/static/alice.jpg', + }); const size = 100; - const wrapper = render(); + const animated = render(); + const still = render(); + // Autoplay it('renders a div element with the given src as background', () => { - expect(wrapper.find('div')).to.have.style('background-image', `url(${src})`); + expect(animated.find('div')).to.have.style('background-image', `url(${account.get('avatar')})`); }); it('renders a div element of the given size', () => { ['width', 'height'].map((attr) => { - expect(wrapper.find('div')).to.have.style(attr, `${size}px`); + expect(animated.find('div')).to.have.style(attr, `${size}px`); }); }); + + // Still + it('renders a div element with the given static src as background if not autoplay', () => { + expect(still.find('div')).to.have.style('background-image', `url(${account.get('avatar_static')})`); + }); + + it('renders a div element of the given size if not autoplay', () => { + ['width', 'height'].map((attr) => { + expect(still.find('div')).to.have.style(attr, `${size}px`); + }); + }); + + // TODO add autoplay test if possible }); diff --git a/spec/javascript/components/avatar_overlay.test.js b/spec/javascript/components/avatar_overlay.test.js new file mode 100644 index 0000000000..a8f0e13d52 --- /dev/null +++ b/spec/javascript/components/avatar_overlay.test.js @@ -0,0 +1,34 @@ +import { expect } from 'chai'; +import { render } from 'enzyme'; +import { fromJS } from 'immutable'; +import React from 'react'; +import AvatarOverlay from '../../../app/javascript/mastodon/components/avatar_overlay'; + +describe('', () => { + const account = fromJS({ + username: 'alice', + acct: 'alice', + display_name: 'Alice', + avatar: '/animated/alice.gif', + avatar_static: '/static/alice.jpg', + }); + const friend = fromJS({ + username: 'eve', + acct: 'eve@blackhat.lair', + display_name: 'Evelyn', + avatar: '/animated/eve.gif', + avatar_static: '/static/eve.jpg', + }); + + const overlay = render(); + + it('renders account static src as base of overlay avatar', () => { + expect(overlay.find('.account__avatar-overlay-base')) + .to.have.style('background-image', `url(${account.get('avatar_static')})`); + }); + + it('renders friend static src as overlay of overlay avatar', () => { + expect(overlay.find('.account__avatar-overlay-overlay')) + .to.have.style('background-image', `url(${friend.get('avatar_static')})`); + }); +}); From 8eb6d171e690e013eb2881478cfa1fd50b4ba705 Mon Sep 17 00:00:00 2001 From: Sorin Davidoi Date: Mon, 7 Aug 2017 20:32:03 +0200 Subject: [PATCH 31/32] feat: Cache status height to avoid expensive renders (#4439) * feat: Cache status height to avoid expensive renders * feat: Escape content and emojify in reducers * fix(css): Remove backface-visibility: hidden from .scrollable * fix(statuses): Avoid creating DOMParses inside a loop --- app/javascript/mastodon/actions/statuses.js | 17 ++++++++++++ .../mastodon/components/display_name.js | 7 ++--- app/javascript/mastodon/components/status.js | 26 +++++++++---------- .../mastodon/components/status_content.js | 6 ++--- .../mastodon/containers/status_container.js | 6 ++++- .../features/account/components/header.js | 13 +++------- .../compose/components/reply_indicator.js | 3 +-- .../components/account_authorize.js | 3 +-- .../notifications/components/notification.js | 7 ++--- .../report/components/status_check_box.js | 3 +-- app/javascript/mastodon/features/ui/index.js | 4 +++ app/javascript/mastodon/reducers/accounts.js | 6 +++++ app/javascript/mastodon/reducers/statuses.js | 26 ++++++++++++++++++- app/javascript/styles/components.scss | 1 - .../components/display_name.test.js | 12 +-------- 15 files changed, 83 insertions(+), 57 deletions(-) diff --git a/app/javascript/mastodon/actions/statuses.js b/app/javascript/mastodon/actions/statuses.js index 2204e0b14a..0b5e72c171 100644 --- a/app/javascript/mastodon/actions/statuses.js +++ b/app/javascript/mastodon/actions/statuses.js @@ -23,6 +23,9 @@ export const STATUS_UNMUTE_REQUEST = 'STATUS_UNMUTE_REQUEST'; export const STATUS_UNMUTE_SUCCESS = 'STATUS_UNMUTE_SUCCESS'; export const STATUS_UNMUTE_FAIL = 'STATUS_UNMUTE_FAIL'; +export const STATUS_SET_HEIGHT = 'STATUS_SET_HEIGHT'; +export const STATUSES_CLEAR_HEIGHT = 'STATUSES_CLEAR_HEIGHT'; + export function fetchStatusRequest(id, skipLoading) { return { type: STATUS_FETCH_REQUEST, @@ -215,3 +218,17 @@ export function unmuteStatusFail(id, error) { error, }; }; + +export function setStatusHeight (id, height) { + return { + type: STATUS_SET_HEIGHT, + id, + height, + }; +}; + +export function clearStatusesHeight () { + return { + type: STATUSES_CLEAR_HEIGHT, + }; +}; diff --git a/app/javascript/mastodon/components/display_name.js b/app/javascript/mastodon/components/display_name.js index dc3665a2b0..2cf84f8f4a 100644 --- a/app/javascript/mastodon/components/display_name.js +++ b/app/javascript/mastodon/components/display_name.js @@ -1,7 +1,5 @@ import React from 'react'; import ImmutablePropTypes from 'react-immutable-proptypes'; -import escapeTextContentForBrowser from 'escape-html'; -import emojify from '../emoji'; export default class DisplayName extends React.PureComponent { @@ -10,12 +8,11 @@ export default class DisplayName extends React.PureComponent { }; render () { - const displayName = this.props.account.get('display_name').length === 0 ? this.props.account.get('username') : this.props.account.get('display_name'); - const displayNameHTML = { __html: emojify(escapeTextContentForBrowser(displayName)) }; + const displayNameHtml = { __html: this.props.account.get('display_name_html') }; return ( - @{this.props.account.get('acct')} + @{this.props.account.get('acct')} ); } diff --git a/app/javascript/mastodon/components/status.js b/app/javascript/mastodon/components/status.js index 25879c4973..38a4aafc18 100644 --- a/app/javascript/mastodon/components/status.js +++ b/app/javascript/mastodon/components/status.js @@ -8,8 +8,6 @@ import DisplayName from './display_name'; import StatusContent from './status_content'; import StatusActionBar from './status_action_bar'; import { FormattedMessage } from 'react-intl'; -import emojify from '../emoji'; -import escapeTextContentForBrowser from 'escape-html'; import ImmutablePureComponent from 'react-immutable-pure-component'; import scheduleIdleTask from '../features/ui/util/schedule_idle_task'; import { MediaGallery, VideoPlayer } from '../features/ui/util/async-components'; @@ -36,6 +34,7 @@ export default class Status extends ImmutablePureComponent { onOpenMedia: PropTypes.func, onOpenVideo: PropTypes.func, onBlock: PropTypes.func, + onHeightChange: PropTypes.func, me: PropTypes.number, boostModal: PropTypes.bool, autoPlayGif: PropTypes.bool, @@ -47,7 +46,6 @@ export default class Status extends ImmutablePureComponent { state = { isExpanded: false, - isIntersecting: true, // assume intersecting until told otherwise isHidden: false, // set to true in requestIdleCallback to trigger un-render } @@ -108,6 +106,10 @@ export default class Status extends ImmutablePureComponent { if (this.node && this.node.children.length !== 0) { // save the height of the fully-rendered element this.height = getRectFromEntry(entry).height; + + if (this.props.onHeightChange) { + this.props.onHeightChange(this.props.status, this.height); + } } this.setState((prevState) => { @@ -179,9 +181,13 @@ export default class Status extends ImmutablePureComponent { return null; } - if (!isIntersecting && isHidden) { + const hasIntersectionObserverWrapper = !!this.props.intersectionObserverWrapper; + const isHiddenForSure = isIntersecting === false && isHidden; + const visibilityUnknownButHeightIsCached = isIntersecting === undefined && status.has('height'); + + if (hasIntersectionObserverWrapper && (isHiddenForSure || visibilityUnknownButHeightIsCached)) { return ( -
    +
    {status.getIn(['account', 'display_name']) || status.getIn(['account', 'username'])} {status.get('content')}
    @@ -189,19 +195,13 @@ export default class Status extends ImmutablePureComponent { } if (status.get('reblog', null) !== null && typeof status.get('reblog') === 'object') { - let displayName = status.getIn(['account', 'display_name']); - - if (displayName.length === 0) { - displayName = status.getIn(['account', 'username']); - } - - const displayNameHTML = { __html: emojify(escapeTextContentForBrowser(displayName)) }; + const display_name_html = { __html: status.getIn(['account', 'display_name_html']) }; return (
    -
    }} /> + }} />
    diff --git a/app/javascript/mastodon/components/status_content.js b/app/javascript/mastodon/components/status_content.js index fdf7aa531f..2069f971cc 100644 --- a/app/javascript/mastodon/components/status_content.js +++ b/app/javascript/mastodon/components/status_content.js @@ -1,8 +1,6 @@ import React from 'react'; import ImmutablePropTypes from 'react-immutable-proptypes'; -import escapeTextContentForBrowser from 'escape-html'; import PropTypes from 'prop-types'; -import emojify from '../emoji'; import { isRtl } from '../rtl'; import { FormattedMessage } from 'react-intl'; import Permalink from './permalink'; @@ -119,8 +117,8 @@ export default class StatusContent extends React.PureComponent { const hidden = this.props.onExpandedToggle ? !this.props.expanded : this.state.hidden; - const content = { __html: emojify(status.get('content')) }; - const spoilerContent = { __html: emojify(escapeTextContentForBrowser(status.get('spoiler_text', ''))) }; + const content = { __html: status.get('contentHtml') }; + const spoilerContent = { __html: status.get('spoilerHtml') }; const directionStyle = { direction: 'ltr' }; const classNames = classnames('status__content', { 'status__content--with-action': this.props.onClick && this.context.router, diff --git a/app/javascript/mastodon/containers/status_container.js b/app/javascript/mastodon/containers/status_container.js index 438ecfe431..b150165aae 100644 --- a/app/javascript/mastodon/containers/status_container.js +++ b/app/javascript/mastodon/containers/status_container.js @@ -16,7 +16,7 @@ import { blockAccount, muteAccount, } from '../actions/accounts'; -import { muteStatus, unmuteStatus, deleteStatus } from '../actions/statuses'; +import { muteStatus, unmuteStatus, deleteStatus, setStatusHeight } from '../actions/statuses'; import { initReport } from '../actions/reports'; import { openModal } from '../actions/modal'; import { defineMessages, injectIntl, FormattedMessage } from 'react-intl'; @@ -124,6 +124,10 @@ const mapDispatchToProps = (dispatch, { intl }) => ({ } }, + onHeightChange (status, height) { + dispatch(setStatusHeight(status.get('id'), height)); + }, + }); export default injectIntl(connect(makeMapStateToProps, mapDispatchToProps)(Status)); diff --git a/app/javascript/mastodon/features/account/components/header.js b/app/javascript/mastodon/features/account/components/header.js index 40567d17ca..8f4dd352d1 100644 --- a/app/javascript/mastodon/features/account/components/header.js +++ b/app/javascript/mastodon/features/account/components/header.js @@ -1,8 +1,6 @@ import React from 'react'; import ImmutablePropTypes from 'react-immutable-proptypes'; import PropTypes from 'prop-types'; -import emojify from '../../../emoji'; -import escapeTextContentForBrowser from 'escape-html'; import { defineMessages, injectIntl, FormattedMessage } from 'react-intl'; import IconButton from '../../../components/icon_button'; import Motion from 'react-motion/lib/Motion'; @@ -92,15 +90,10 @@ export default class Header extends ImmutablePureComponent { return null; } - let displayName = account.get('display_name'); let info = ''; let actionBtn = ''; let lockedIcon = ''; - if (displayName.length === 0) { - displayName = account.get('username'); - } - if (me !== account.get('id') && account.getIn(['relationship', 'followed_by'])) { info = ; } @@ -125,15 +118,15 @@ export default class Header extends ImmutablePureComponent { lockedIcon = ; } - const content = { __html: emojify(account.get('note')) }; - const displayNameHTML = { __html: emojify(escapeTextContentForBrowser(displayName)) }; + const content = { __html: account.get('note_emojified') }; + const displayNameHtml = { __html: account.get('display_name_html') }; return (
    - + @{account.get('acct')} {lockedIcon}
    diff --git a/app/javascript/mastodon/features/compose/components/reply_indicator.js b/app/javascript/mastodon/features/compose/components/reply_indicator.js index 35a9b4b1b4..7672440b49 100644 --- a/app/javascript/mastodon/features/compose/components/reply_indicator.js +++ b/app/javascript/mastodon/features/compose/components/reply_indicator.js @@ -4,7 +4,6 @@ import PropTypes from 'prop-types'; import Avatar from '../../../components/avatar'; import IconButton from '../../../components/icon_button'; import DisplayName from '../../../components/display_name'; -import emojify from '../../../emoji'; import { defineMessages, injectIntl } from 'react-intl'; import ImmutablePureComponent from 'react-immutable-pure-component'; @@ -43,7 +42,7 @@ export default class ReplyIndicator extends ImmutablePureComponent { return null; } - const content = { __html: emojify(status.get('content')) }; + const content = { __html: status.get('contentHtml') }; return (
    diff --git a/app/javascript/mastodon/features/follow_requests/components/account_authorize.js b/app/javascript/mastodon/features/follow_requests/components/account_authorize.js index 66fa5c235c..4fc5638d95 100644 --- a/app/javascript/mastodon/features/follow_requests/components/account_authorize.js +++ b/app/javascript/mastodon/features/follow_requests/components/account_authorize.js @@ -4,7 +4,6 @@ import ImmutablePropTypes from 'react-immutable-proptypes'; import Permalink from '../../../components/permalink'; import Avatar from '../../../components/avatar'; import DisplayName from '../../../components/display_name'; -import emojify from '../../../emoji'; import IconButton from '../../../components/icon_button'; import { defineMessages, injectIntl } from 'react-intl'; import ImmutablePureComponent from 'react-immutable-pure-component'; @@ -26,7 +25,7 @@ export default class AccountAuthorize extends ImmutablePureComponent { render () { const { intl, account, onAuthorize, onReject } = this.props; - const content = { __html: emojify(account.get('note')) }; + const content = { __html: account.get('note_emojified') }; return (
    diff --git a/app/javascript/mastodon/features/notifications/components/notification.js b/app/javascript/mastodon/features/notifications/components/notification.js index 9d631644a0..2992185fd1 100644 --- a/app/javascript/mastodon/features/notifications/components/notification.js +++ b/app/javascript/mastodon/features/notifications/components/notification.js @@ -4,8 +4,6 @@ import StatusContainer from '../../../containers/status_container'; import AccountContainer from '../../../containers/account_container'; import { FormattedMessage } from 'react-intl'; import Permalink from '../../../components/permalink'; -import emojify from '../../../emoji'; -import escapeTextContentForBrowser from 'escape-html'; import ImmutablePureComponent from 'react-immutable-pure-component'; export default class Notification extends ImmutablePureComponent { @@ -67,9 +65,8 @@ export default class Notification extends ImmutablePureComponent { render () { const { notification } = this.props; const account = notification.get('account'); - const displayName = account.get('display_name').length > 0 ? account.get('display_name') : account.get('username'); - const displayNameHTML = { __html: emojify(escapeTextContentForBrowser(displayName)) }; - const link = ; + const displayNameHtml = { __html: account.get('display_name_html') }; + const link = ; switch(notification.get('type')) { case 'follow': diff --git a/app/javascript/mastodon/features/report/components/status_check_box.js b/app/javascript/mastodon/features/report/components/status_check_box.js index 6a1a84c28c..cc92322011 100644 --- a/app/javascript/mastodon/features/report/components/status_check_box.js +++ b/app/javascript/mastodon/features/report/components/status_check_box.js @@ -1,7 +1,6 @@ import React from 'react'; import PropTypes from 'prop-types'; import ImmutablePropTypes from 'react-immutable-proptypes'; -import emojify from '../../../emoji'; import Toggle from 'react-toggle'; export default class StatusCheckBox extends React.PureComponent { @@ -15,7 +14,7 @@ export default class StatusCheckBox extends React.PureComponent { render () { const { status, checked, onToggle, disabled } = this.props; - const content = { __html: emojify(status.get('content')) }; + const content = { __html: status.get('contentHtml') }; if (status.get('reblog')) { return null; diff --git a/app/javascript/mastodon/features/ui/index.js b/app/javascript/mastodon/features/ui/index.js index b6307dd4cf..a791f89473 100644 --- a/app/javascript/mastodon/features/ui/index.js +++ b/app/javascript/mastodon/features/ui/index.js @@ -12,6 +12,7 @@ import { debounce } from 'lodash'; import { uploadCompose } from '../../actions/compose'; import { refreshHomeTimeline } from '../../actions/timelines'; import { refreshNotifications } from '../../actions/notifications'; +import { clearStatusesHeight } from '../../actions/statuses'; import { WrappedSwitch, WrappedRoute } from './util/react_router_helpers'; import UploadArea from './components/upload_area'; import ColumnsAreaContainer from './containers/columns_area_container'; @@ -66,6 +67,9 @@ export default class UI extends React.PureComponent { }; handleResize = debounce(() => { + // The cached heights are no longer accurate, invalidate + this.props.dispatch(clearStatusesHeight()); + this.setState({ width: window.innerWidth }); }, 500, { trailing: true, diff --git a/app/javascript/mastodon/reducers/accounts.js b/app/javascript/mastodon/reducers/accounts.js index 4d7c3adc97..6442d13bef 100644 --- a/app/javascript/mastodon/reducers/accounts.js +++ b/app/javascript/mastodon/reducers/accounts.js @@ -44,7 +44,9 @@ import { FAVOURITED_STATUSES_EXPAND_SUCCESS, } from '../actions/favourites'; import { STORE_HYDRATE } from '../actions/store'; +import emojify from '../emoji'; import { Map as ImmutableMap, fromJS } from 'immutable'; +import escapeTextContentForBrowser from 'escape-html'; const normalizeAccount = (state, account) => { account = { ...account }; @@ -53,6 +55,10 @@ const normalizeAccount = (state, account) => { delete account.following_count; delete account.statuses_count; + const displayName = account.display_name.length === 0 ? account.username : account.display_name; + account.display_name_html = emojify(escapeTextContentForBrowser(displayName)); + account.note_emojified = emojify(account.note); + return state.set(account.id, fromJS(account)); }; diff --git a/app/javascript/mastodon/reducers/statuses.js b/app/javascript/mastodon/reducers/statuses.js index b1b1d0988e..3e40b0b424 100644 --- a/app/javascript/mastodon/reducers/statuses.js +++ b/app/javascript/mastodon/reducers/statuses.js @@ -13,6 +13,8 @@ import { CONTEXT_FETCH_SUCCESS, STATUS_MUTE_SUCCESS, STATUS_UNMUTE_SUCCESS, + STATUS_SET_HEIGHT, + STATUSES_CLEAR_HEIGHT, } from '../actions/statuses'; import { TIMELINE_REFRESH_SUCCESS, @@ -33,7 +35,11 @@ import { FAVOURITED_STATUSES_EXPAND_SUCCESS, } from '../actions/favourites'; import { SEARCH_FETCH_SUCCESS } from '../actions/search'; +import emojify from '../emoji'; import { Map as ImmutableMap, fromJS } from 'immutable'; +import escapeTextContentForBrowser from 'escape-html'; + +const domParser = new DOMParser(); const normalizeStatus = (state, status) => { if (!status) { @@ -49,7 +55,9 @@ const normalizeStatus = (state, status) => { } const searchContent = [status.spoiler_text, status.content].join(' ').replace(/
    /g, '\n').replace(/<\/p>

    /g, '\n\n'); - normalStatus.search_index = new DOMParser().parseFromString(searchContent, 'text/html').documentElement.textContent; + normalStatus.search_index = domParser.parseFromString(searchContent, 'text/html').documentElement.textContent; + normalStatus.contentHtml = emojify(normalStatus.content); + normalStatus.spoilerHtml = emojify(escapeTextContentForBrowser(normalStatus.spoiler_text || '')); return state.update(status.id, ImmutableMap(), map => map.mergeDeep(fromJS(normalStatus))); }; @@ -82,6 +90,18 @@ const filterStatuses = (state, relationship) => { return state; }; +const setHeight = (state, id, height) => { + return state.update(id, ImmutableMap(), map => map.set('height', height)); +}; + +const clearHeights = (state) => { + state.forEach(status => { + state = state.deleteIn([status.get('id'), 'height']); + }); + + return state; +}; + const initialState = ImmutableMap(); export default function statuses(state = initialState, action) { @@ -120,6 +140,10 @@ export default function statuses(state = initialState, action) { return deleteStatus(state, action.id, action.references); case ACCOUNT_BLOCK_SUCCESS: return filterStatuses(state, action.relationship); + case STATUS_SET_HEIGHT: + return setHeight(state, action.id, action.height); + case STATUSES_CLEAR_HEIGHT: + return clearHeights(state); default: return state; } diff --git a/app/javascript/styles/components.scss b/app/javascript/styles/components.scss index 9174f51124..77b06b2d0d 100644 --- a/app/javascript/styles/components.scss +++ b/app/javascript/styles/components.scss @@ -1572,7 +1572,6 @@ overflow-y: scroll; overflow-x: hidden; flex: 1 1 auto; - backface-visibility: hidden; -webkit-overflow-scrolling: touch; @supports(display: grid) { // hack to fix Chrome <57 contain: strict; diff --git a/spec/javascript/components/display_name.test.js b/spec/javascript/components/display_name.test.js index ad9288d4df..ab484cf3e2 100644 --- a/spec/javascript/components/display_name.test.js +++ b/spec/javascript/components/display_name.test.js @@ -9,19 +9,9 @@ describe('', () => { const account = fromJS({ username: 'bar', acct: 'bar@baz', - display_name: 'Foo', + display_name_html: '

    Foo

    ', }); const wrapper = render(); expect(wrapper).to.have.text('Foo @bar@baz'); }); - - it('renders the username + account name if display name is empty', () => { - const account = fromJS({ - username: 'bar', - acct: 'bar@baz', - display_name: '', - }); - const wrapper = render(); - expect(wrapper).to.have.text('bar @bar@baz'); - }); }); From a3e53bd442752f210db2025f2dfc45e7599354c2 Mon Sep 17 00:00:00 2001 From: Lynx Kotoura Date: Tue, 8 Aug 2017 03:33:06 +0900 Subject: [PATCH 32/32] Adjust tags and accounts page (#4534) * Adjust tag and accounts page * Remove units from 0px paddings --- app/javascript/styles/accounts.scss | 4 ++-- app/javascript/styles/compact_header.scss | 8 +++++++- app/javascript/styles/containers.scss | 2 +- app/views/tags/show.html.haml | 1 + 4 files changed, 11 insertions(+), 4 deletions(-) diff --git a/app/javascript/styles/accounts.scss b/app/javascript/styles/accounts.scss index 99eb5ebea8..66da75828f 100644 --- a/app/javascript/styles/accounts.scss +++ b/app/javascript/styles/accounts.scss @@ -9,7 +9,7 @@ overflow: hidden; position: relative; - @media screen and (max-width: 700px) { + @media screen and (max-width: 740px) { border-radius: 0; box-shadow: none; } @@ -272,7 +272,7 @@ display: flex; flex-wrap: wrap; - @media screen and (max-width: 700px) { + @media screen and (max-width: 740px) { border-radius: 0; box-shadow: none; } diff --git a/app/javascript/styles/compact_header.scss b/app/javascript/styles/compact_header.scss index 27a67135f1..cf12fcfec3 100644 --- a/app/javascript/styles/compact_header.scss +++ b/app/javascript/styles/compact_header.scss @@ -3,9 +3,15 @@ font-size: 24px; line-height: 28px; color: $ui-primary-color; - overflow: hidden; font-weight: 500; margin-bottom: 20px; + padding: 0 10px; + overflow-wrap: break-word; + + @media screen and (max-width: 740px) { + text-align: center; + padding: 20px 10px 0; + } a { color: inherit; diff --git a/app/javascript/styles/containers.scss b/app/javascript/styles/containers.scss index d366a46ecd..536f4e5a15 100644 --- a/app/javascript/styles/containers.scss +++ b/app/javascript/styles/containers.scss @@ -3,7 +3,7 @@ margin: 0 auto; margin-top: 40px; - @media screen and (max-width: 700px) { + @media screen and (max-width: 740px) { width: 100%; margin: 0; } diff --git a/app/views/tags/show.html.haml b/app/views/tags/show.html.haml index 15bf714c28..8cd2f1825f 100644 --- a/app/views/tags/show.html.haml +++ b/app/views/tags/show.html.haml @@ -4,6 +4,7 @@ .compact-header %h1< = link_to site_title, root_path + %br %small ##{@tag.name} - if @statuses.empty?