From e742bff19b609c2ac43f87d62cd2ed948471d5a0 Mon Sep 17 00:00:00 2001 From: jeroenpraat <41594439+jeroenpraat@users.noreply.github.com> Date: Sun, 5 May 2019 21:33:24 +0200 Subject: 1 NL string update (#10709) * 1 NL string update No that weblate isn't used anymore, it would be fine if, or the english strings are update, or there is somewhere an explanation how to generate new strings for a language * Update nl.json --- app/javascript/mastodon/locales/nl.json | 1 + 1 file changed, 1 insertion(+) (limited to 'app/javascript') diff --git a/app/javascript/mastodon/locales/nl.json b/app/javascript/mastodon/locales/nl.json index 96e39356b..497a11d5c 100644 --- a/app/javascript/mastodon/locales/nl.json +++ b/app/javascript/mastodon/locales/nl.json @@ -77,6 +77,7 @@ "compose_form.poll.remove_option": "Deze keuze verwijderen", "compose_form.publish": "Toot", "compose_form.publish_loud": "{publish}!", + "compose_form.sensitive.hide": "Media als gevoelig markeren", "compose_form.sensitive.marked": "Media is als gevoelig gemarkeerd", "compose_form.sensitive.unmarked": "Media is niet als gevoelig gemarkeerd", "compose_form.spoiler.marked": "Tekst is achter een waarschuwing verborgen", -- cgit From 1eb14ef7740001e897d5f2d7976cbb643800f428 Mon Sep 17 00:00:00 2001 From: mayaeh Date: Mon, 6 May 2019 04:34:32 +0900 Subject: i18n: Update Japanese translations (#10706) * Update Japanese translations. run yarn manage:translations This commit includes translations by some users that were done at the transifex. * Reduce translation text because it becomes two lines. --- .../mastodon/locales/defaultMessages.json | 25 +++++++++++++++------- app/javascript/mastodon/locales/en.json | 3 ++- app/javascript/mastodon/locales/ja.json | 3 ++- config/locales/devise.ja.yml | 2 +- config/locales/ja.yml | 25 +++++++++++----------- 5 files changed, 35 insertions(+), 23 deletions(-) (limited to 'app/javascript') diff --git a/app/javascript/mastodon/locales/defaultMessages.json b/app/javascript/mastodon/locales/defaultMessages.json index e7b4b479a..11b6dd854 100644 --- a/app/javascript/mastodon/locales/defaultMessages.json +++ b/app/javascript/mastodon/locales/defaultMessages.json @@ -180,10 +180,6 @@ { "defaultMessage": "Media hidden", "id": "status.media_hidden" - }, - { - "defaultMessage": "Click to view", - "id": "status.sensitive_toggle" } ], "path": "app/javascript/mastodon/components/media_gallery.json" @@ -1096,6 +1092,10 @@ { "defaultMessage": "Media is not marked as sensitive", "id": "compose_form.sensitive.unmarked" + }, + { + "defaultMessage": "Mark media as sensitive", + "id": "compose_form.sensitive.hide" } ], "path": "app/javascript/mastodon/features/compose/containers/sensitive_button_container.json" @@ -2249,6 +2249,10 @@ { "defaultMessage": "Next", "id": "lightbox.next" + }, + { + "defaultMessage": "View context", + "id": "lightbox.view_context" } ], "path": "app/javascript/mastodon/features/ui/components/media_modal.json" @@ -2341,6 +2345,15 @@ ], "path": "app/javascript/mastodon/features/ui/components/upload_area.json" }, + { + "descriptors": [ + { + "defaultMessage": "View context", + "id": "lightbox.view_context" + } + ], + "path": "app/javascript/mastodon/features/ui/components/video_modal.json" + }, { "descriptors": [ { @@ -2395,10 +2408,6 @@ { "defaultMessage": "Media hidden", "id": "status.media_hidden" - }, - { - "defaultMessage": "Click to view", - "id": "status.sensitive_toggle" } ], "path": "app/javascript/mastodon/features/video/index.json" diff --git a/app/javascript/mastodon/locales/en.json b/app/javascript/mastodon/locales/en.json index baed4939c..272f22088 100644 --- a/app/javascript/mastodon/locales/en.json +++ b/app/javascript/mastodon/locales/en.json @@ -77,6 +77,7 @@ "compose_form.poll.remove_option": "Remove this choice", "compose_form.publish": "Toot", "compose_form.publish_loud": "{publish}!", + "compose_form.sensitive.hide": "Mark media as sensitive", "compose_form.sensitive.marked": "Media is marked as sensitive", "compose_form.sensitive.unmarked": "Media is not marked as sensitive", "compose_form.spoiler.marked": "Text is hidden behind warning", @@ -209,6 +210,7 @@ "lightbox.close": "Close", "lightbox.next": "Next", "lightbox.previous": "Previous", + "lightbox.view_context": "View context", "lists.account.add": "Add to list", "lists.account.remove": "Remove from list", "lists.delete": "Delete list", @@ -340,7 +342,6 @@ "status.reply": "Reply", "status.replyAll": "Reply to thread", "status.report": "Report @{name}", - "status.sensitive_toggle": "Click to view", "status.sensitive_warning": "Sensitive content", "status.share": "Share", "status.show_less": "Show less", diff --git a/app/javascript/mastodon/locales/ja.json b/app/javascript/mastodon/locales/ja.json index f80988d0d..c9e7a7b90 100644 --- a/app/javascript/mastodon/locales/ja.json +++ b/app/javascript/mastodon/locales/ja.json @@ -77,6 +77,7 @@ "compose_form.poll.remove_option": "この項目を削除", "compose_form.publish": "トゥート", "compose_form.publish_loud": "{publish}!", + "compose_form.sensitive.hide": "メディアを閲覧注意にする", "compose_form.sensitive.marked": "メディアに閲覧注意が設定されています", "compose_form.sensitive.unmarked": "メディアに閲覧注意が設定されていません", "compose_form.spoiler.marked": "閲覧注意が設定されています", @@ -209,6 +210,7 @@ "lightbox.close": "閉じる", "lightbox.next": "次", "lightbox.previous": "前", + "lightbox.view_context": "トゥートを表示", "lists.account.add": "リストに追加", "lists.account.remove": "リストから外す", "lists.delete": "リストを削除", @@ -340,7 +342,6 @@ "status.reply": "返信", "status.replyAll": "全員に返信", "status.report": "@{name}さんを通報", - "status.sensitive_toggle": "クリックして表示", "status.sensitive_warning": "閲覧注意", "status.share": "共有", "status.show_less": "隠す", diff --git a/config/locales/devise.ja.yml b/config/locales/devise.ja.yml index 3dac63050..b9f2fb8a6 100644 --- a/config/locales/devise.ja.yml +++ b/config/locales/devise.ja.yml @@ -12,7 +12,7 @@ ja: last_attempt: あと1回失敗するとアカウントがロックされます。 locked: アカウントはロックされました。 not_found_in_database: "%{authentication_keys}かパスワードが誤っています。" - pending: あなたのアカウントはまだ審査中です。 + pending: あなたのアカウントはまだ承認待ちです。 timeout: セッションの有効期限が切れました。続行するには再度ログインしてください。 unauthenticated: 続行するにはログインするか、アカウントを作成してください。 unconfirmed: 続行するにはメールアドレスを確認する必要があります。 diff --git a/config/locales/ja.yml b/config/locales/ja.yml index 545146145..4087e299c 100644 --- a/config/locales/ja.yml +++ b/config/locales/ja.yml @@ -20,7 +20,7 @@ ja: extended_description_html: |

ルールを書くのに適した場所

詳細説明が設定されていません。

- federation_hint_html: "%{instance} にアカウントがあればどの互換性のあるサーバーのユーザーでもフォローできるでしょう。" + federation_hint_html: "%{instance} のアカウントひとつでどんなMastodon互換サーバーのユーザーでもフォローできるでしょう。" generic_description: "%{domain} は、Mastodon サーバーの一つです" get_apps: モバイルアプリを試す hosted_on: Mastodon hosted on %{domain} @@ -269,6 +269,7 @@ ja: created_msg: ドメインブロック処理を完了しました destroyed_msg: ドメインブロックを外しました domain: ドメイン + existing_domain_block_html: 既に%{name}に対しより厳しい制限を課しています 。まずはそれを解除する必要があります。 new: create: ブロックを作成 hint: ドメインブロックはデータベース中のアカウント項目の作成を妨げませんが、遡って自動的に指定されたモデレーションをそれらのアカウントに適用します。 @@ -659,7 +660,7 @@ ja: i_am_html: I am %{username} on %{service}. identity: Identity inactive: 非アクティブ - publicize_checkbox: 'そしてこれをトゥートしてください:' + publicize_checkbox: 'そしてこれをトゥートします:' publicize_toot: 'It is proven! I am %{username} on %{service}: %{url}' status: 認証状態 view_proof: 証明を表示 @@ -1049,21 +1050,21 @@ ja: suspend: アカウントが停止されました welcome: edit_profile_action: プロフィールを設定 - edit_profile_step: アバター画像やヘッダー画像をアップロードしたり、表示名やその他プロフィールを変更しカスタマイズすることができます。新しいフォロワーからのフォローを許可する前に検討したい場合、アカウントを承認制にすることができます。 + edit_profile_step: アイコンやヘッダーの画像をアップロードしたり、表示名を変更したりして、自分のプロフィールをカスタマイズすることができます。また、誰かからの新規フォローを許可する前にその人の様子を見ておきたい場合、アカウントを承認制にすることもできます。 explanation: 始めるにあたってのアドバイスです final_action: 始めましょう - final_step: 'さあ始めましょう! たとえフォロワーがいなくても、あなたの公開した投稿はローカルタイムラインやハッシュタグなどで誰かの目に止まるかもしれません。自己紹介をしたい時は #introductions ハッシュタグを使うといいかもしれません。' - full_handle: あなたの正式なユーザー名 - full_handle_hint: これは別のサーバーからフォローしてもらったりメッセージのやり取りをする際に、友達に伝えるといいでしょう。 + final_step: 'さあ、始めましょう! たとえフォロワーがまだいなくても、あなたの公開した投稿はローカルタイムラインやハッシュタグなどを通じて誰かの目にとまるはずです。自己紹介をしたいときには #introductions ハッシュタグが便利かもしれません。' + full_handle: あなたの正式なユーザーID + full_handle_hint: 別のサーバーの友達とフォローやメッセージをやり取りする際には、これを伝えることになります。 review_preferences_action: 設定の変更 - review_preferences_step: 受け取りたいメールや投稿の公開範囲などの設定を必ず行ってください。不快でないならアニメーション GIF の自動再生を有効にすることもできます。 + review_preferences_step: 受け取りたいメールの種類や投稿のデフォルト公開範囲など、ユーザー設定を必ず済ませておきましょう。目が回らない自信があるなら、アニメーション GIF を自動再生する設定もご検討ください。 subject: Mastodon へようこそ - tip_federated_timeline: 連合タイムラインは Mastodon ネットワークの流れを見られるものです。ただしあなたと同じサーバーの人がフォローしている人だけが含まれるので、それが全てではありません。 - tip_following: 標準では自動でサーバーの管理者をフォローしています。もっと興味のある人たちを見つけるには、ローカルタイムラインと連合タイムラインを確認してください。 - tip_local_timeline: ローカルタイムラインは %{instance} にいる人々の流れを見られるものです。彼らはあなたと同じサーバーにいる隣人のようなものです! - tip_mobile_webapp: もしモバイル端末のブラウザで Mastodon をホーム画面に追加できる場合、プッシュ通知を受け取ることができます。それはまるでネイティブアプリのように動作します! + tip_federated_timeline: 連合タイムラインは、Mastodon ネットワークによる巨大流しそうめんです。ただし、あなたの「隣人」達がフォローしている人々だけが流れてくる場所なので、決してそこに全てがあるわけではありません。 + tip_following: 最初は、サーバーの管理者をフォローした状態になっています。もっと興味のある人たちを見つけるには、ローカルタイムラインと連合タイムラインを確認してみましょう。 + tip_local_timeline: ローカルタイムラインには、%{instance} にいる人々が流しそうめんのごとく流れてきます。彼らはあなたと同じサーバーに暮らす、愛すべき隣人です! + tip_mobile_webapp: お使いのモバイル端末で、ブラウザから Mastodon をホーム画面に追加できますか? もし追加できる場合、プッシュ通知の受け取りなど、まるで「普通の」アプリのような機能が楽しめます! tips: 豆知識 - title: ようこそ、%{name} ! + title: ようこそ、%{name}! users: follow_limit_reached: あなたは現在 %{limit} 人以上フォローできません invalid_email: メールアドレスが無効です -- cgit From b2f5b1045fd84b692721bf44652d569d63d17657 Mon Sep 17 00:00:00 2001 From: ThibG Date: Mon, 6 May 2019 05:33:56 +0200 Subject: Add description on hover in media gallery (#10713) --- .../mastodon/features/account_gallery/components/media_item.js | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) (limited to 'app/javascript') diff --git a/app/javascript/mastodon/features/account_gallery/components/media_item.js b/app/javascript/mastodon/features/account_gallery/components/media_item.js index 5643e6449..f44e20939 100644 --- a/app/javascript/mastodon/features/account_gallery/components/media_item.js +++ b/app/javascript/mastodon/features/account_gallery/components/media_item.js @@ -88,6 +88,7 @@ export default class MediaItem extends ImmutablePureComponent { const width = `${Math.floor((displayWidth - 4) / 3) - 4}px`; const height = width; const status = attachment.get('status'); + const title = status.get('spoiler_text') || attachment.get('description'); let thumbnail = ''; @@ -133,7 +134,7 @@ export default class MediaItem extends ImmutablePureComponent { return (
- + {visible && thumbnail} -- cgit From 7562602df8a889ed70efede52bed86e2d1bf8a5d Mon Sep 17 00:00:00 2001 From: spla Date: Mon, 6 May 2019 17:55:37 +0200 Subject: i18n Update Catalan translation (#10719) * Updated Catalan strings * Update ca.yml * Update ca.yml * Update ca.yml * Update ca.yml * Update ca.yml * Update ca.yml * Update ca.yml * Update simple_form.ca.yml * Update simple_form.ca.yml * Update simple_form.ca.yml * bundle exec i18n-tasks * Update ca.json * Update simple_form.ca.yml * i18n: Update Catalan translations * i18n: Update Catalan translations * i18n: Update Catalan translations * i18n: Update Catalan translations * i18n: Update Catalan translations * i18n: Update Catalan translations * i18n: Update Catalan translations * i18n: Update Catalan translations * i18n: Update Catalan translations * i18n: Update Catalan translation * i18n Update Catalan translation --- app/javascript/mastodon/locales/ca.json | 9 +++++---- config/locales/ca.yml | 9 +++++---- 2 files changed, 10 insertions(+), 8 deletions(-) (limited to 'app/javascript') diff --git a/app/javascript/mastodon/locales/ca.json b/app/javascript/mastodon/locales/ca.json index 18dd56d0d..0cafb1120 100644 --- a/app/javascript/mastodon/locales/ca.json +++ b/app/javascript/mastodon/locales/ca.json @@ -17,7 +17,7 @@ "account.hide_reblogs": "Amaga els impulsos de @{name}", "account.link_verified_on": "La propietat d'aquest enllaç es va verificar el dia {date}", "account.locked_info": "Aquest estat de privadesa del compte està definit com a bloquejat. El propietari revisa manualment qui pot seguir-lo.", - "account.media": "Media", + "account.media": "Mèdia", "account.mention": "Esmentar @{name}", "account.moved_to": "{name} s'ha mogut a:", "account.mute": "Silencia @{name}", @@ -77,6 +77,7 @@ "compose_form.poll.remove_option": "Elimina aquesta opció", "compose_form.publish": "Toot", "compose_form.publish_loud": "{publish}!", + "compose_form.sensitive.hide": "Marcar mèdia com a sensible", "compose_form.sensitive.marked": "Mèdia marcat com a sensible", "compose_form.sensitive.unmarked": "Mèdia no està marcat com a sensible", "compose_form.spoiler.marked": "Text es ocult sota l'avís", @@ -85,7 +86,7 @@ "confirmation_modal.cancel": "Cancel·la", "confirmations.block.block_and_report": "Block & Report", "confirmations.block.confirm": "Bloca", - "confirmations.block.message": "Estàs segur que vols blocar {name}?", + "confirmations.block.message": "Estàs segur que vols bloquejar a {name}?", "confirmations.delete.confirm": "Suprimeix", "confirmations.delete.message": "Estàs segur que vols suprimir aquest estat?", "confirmations.delete_list.confirm": "Suprimeix", @@ -125,7 +126,7 @@ "empty_column.favourited_statuses": "Encara no tens cap toot favorit. Quan en tinguis, apareixerà aquí.", "empty_column.favourites": "Encara ningú ha marcat aquest toot com a favorit. Quan algú ho faci, apareixera aquí.", "empty_column.follow_requests": "Encara no teniu cap petició de seguiment. Quan rebeu una, apareixerà aquí.", - "empty_column.hashtag": "Encara no hi ha res amb aquesta etiqueta.", + "empty_column.hashtag": "Encara no hi ha res en aquesta etiqueta.", "empty_column.home": "Encara no segueixes ningú. Visita {public} o fes cerca per començar i conèixer altres usuaris.", "empty_column.home.public_timeline": "la línia de temps pública", "empty_column.list": "Encara no hi ha res en aquesta llista. Quan els membres d'aquesta llista publiquin nous estats, apareixeran aquí.", @@ -209,6 +210,7 @@ "lightbox.close": "Tancar", "lightbox.next": "Següent", "lightbox.previous": "Anterior", + "lightbox.view_context": "Veure el context", "lists.account.add": "Afegir a la llista", "lists.account.remove": "Treure de la llista", "lists.delete": "Delete list", @@ -340,7 +342,6 @@ "status.reply": "Respondre", "status.replyAll": "Respondre al tema", "status.report": "Informar sobre @{name}", - "status.sensitive_toggle": "Clic per veure", "status.sensitive_warning": "Contingut sensible", "status.share": "Compartir", "status.show_less": "Mostra menys", diff --git a/config/locales/ca.yml b/config/locales/ca.yml index 6169767da..e76182bf4 100644 --- a/config/locales/ca.yml +++ b/config/locales/ca.yml @@ -269,6 +269,7 @@ ca: created_msg: El bloqueig de domini ara s'està processant destroyed_msg: El bloqueig de domini s'ha desfet domain: Domini + existing_domain_block_html: Ja has imposat uns limits més estrictes a %{name}, l'hauries de desbloquejar-lo primer. new: create: Crea un bloqueig hint: El bloqueig de domini no impedirà la creació de nous comptes en la base de dades, però s'aplicaran de manera retroactiva mètodes de moderació específics sobre aquests comptes. @@ -655,7 +656,7 @@ ca: invalid_token: Els tokens de Keybase són hashs de signatures i han de tenir 66 caràcters hexadecimals verification_failed: Keybase no reconeix aquest token com a signatura del usuari de Keybase %{kb_username}. Si us plau prova des de Keybase. wrong_user: No es pot crear una prova per a %{proving} mentre es connectava com a %{current}. Inicia sessió com a %{proving} i prova de nou. - explanation_html: Aquí pots connectar criptogràficament les teves altres identitats com ara el teu perfil de Keybase. Això permet que altres persones t'envïin missatges xifrats i continguts de confiança que els hi enviess. + explanation_html: Aquí pots connectar criptogràficament les teves altres identitats com ara el teu perfil de Keybase. Això permet que altres persones t'envïin missatges xifrats i confiar en el contingut que els hi envies. i_am_html: Sóc %{username} a %{service}. identity: Identitat inactive: Inactiu @@ -675,7 +676,7 @@ ca: blocking: Llista de blocats domain_blocking: Llistat de dominis bloquejats following: Llista de seguits - muting: Llista d'apagats + muting: Llista de silenciats upload: Carregar in_memoriam_html: En Memòria. invites: @@ -778,7 +779,7 @@ ca: preferences: languages: Llengues other: Altre - publishing: Publicació + publishing: Publicant web: Web relationships: activity: Activitat del compte @@ -922,7 +923,7 @@ ca: sensitive_content: Contingut sensible terms: body_html: | -

Privacy Policy

+

Política de Privacitat

Quina informació recollim?

    -- cgit From 5c82d660d11d38c2f13c6c8a4f1c60f62f6176cb Mon Sep 17 00:00:00 2001 From: nzws Date: Wed, 8 May 2019 06:53:58 +0900 Subject: Fix some colors of high contrast theme (#10711) * Fix "nothing here" text color of high contrast * Fix counter border color of high contrast --- app/javascript/styles/contrast/diff.scss | 8 ++++++++ 1 file changed, 8 insertions(+) (limited to 'app/javascript') diff --git a/app/javascript/styles/contrast/diff.scss b/app/javascript/styles/contrast/diff.scss index 8429103b8..f78e60597 100644 --- a/app/javascript/styles/contrast/diff.scss +++ b/app/javascript/styles/contrast/diff.scss @@ -67,3 +67,11 @@ text-decoration: none; } } + +.nothing-here { + color: $darker-text-color; +} + +.public-layout .public-account-header__tabs__tabs .counter.active::after { + border-bottom: 4px solid $ui-highlight-color; +} -- cgit From 09eea46631c99792e6e3b59ee20253827fd87ade Mon Sep 17 00:00:00 2001 From: Jeong Arm Date: Thu, 9 May 2019 01:01:33 +0900 Subject: Bring back crossed eye icon on gallery (#10715) --- .../features/account_gallery/components/media_item.js | 11 +++++++++++ app/javascript/styles/mastodon/components.scss | 8 ++++++++ 2 files changed, 19 insertions(+) (limited to 'app/javascript') diff --git a/app/javascript/mastodon/features/account_gallery/components/media_item.js b/app/javascript/mastodon/features/account_gallery/components/media_item.js index f44e20939..2609b96ff 100644 --- a/app/javascript/mastodon/features/account_gallery/components/media_item.js +++ b/app/javascript/mastodon/features/account_gallery/components/media_item.js @@ -2,6 +2,7 @@ import React from 'react'; import PropTypes from 'prop-types'; import ImmutablePropTypes from 'react-immutable-proptypes'; import ImmutablePureComponent from 'react-immutable-pure-component'; +import Icon from 'mastodon/components/icon'; import { autoPlayGif, displayMedia } from 'mastodon/initial_state'; import classNames from 'classnames'; import { decode } from 'blurhash'; @@ -91,6 +92,7 @@ export default class MediaItem extends ImmutablePureComponent { const title = status.get('spoiler_text') || attachment.get('description'); let thumbnail = ''; + let icon; if (attachment.get('type') === 'unknown') { // Skip @@ -132,11 +134,20 @@ export default class MediaItem extends ImmutablePureComponent { ); } + if (!visible) { + icon = ( + + + + ); + } + return ( ); diff --git a/app/javascript/styles/mastodon/components.scss b/app/javascript/styles/mastodon/components.scss index cf8fa9392..0da3ed909 100644 --- a/app/javascript/styles/mastodon/components.scss +++ b/app/javascript/styles/mastodon/components.scss @@ -4829,6 +4829,14 @@ a.status-card.compact:hover { border-radius: 4px; overflow: hidden; margin: 2px; + + &__icons { + position: absolute; + top: 50%; + left: 50%; + transform: translate(-50%, -50%); + font-size: 24px; + } } .notification__filter-bar, -- cgit From 0402c52f28b73824d7c81c702a16d39fd97808cf Mon Sep 17 00:00:00 2001 From: Maciek Baron Date: Thu, 9 May 2019 21:03:32 +0100 Subject: Improve poll link accessibility (#10720) * Add distinction between hover and active/focus states * Resolves #10198 --- app/javascript/styles/mastodon/polls.scss | 9 ++++++--- 1 file changed, 6 insertions(+), 3 deletions(-) (limited to 'app/javascript') diff --git a/app/javascript/styles/mastodon/polls.scss b/app/javascript/styles/mastodon/polls.scss index d8bc5473a..37c454a78 100644 --- a/app/javascript/styles/mastodon/polls.scss +++ b/app/javascript/styles/mastodon/polls.scss @@ -114,11 +114,14 @@ text-decoration: underline; font-size: inherit; - &:hover, - &:focus, - &:active { + &:hover { text-decoration: none; } + + &:active, + &:focus { + background-color: rgba($dark-text-color, .1); + } } .button { -- cgit From f2be71c2931e0d0b8f1ec05f50bd7d791c420c91 Mon Sep 17 00:00:00 2001 From: ThibG Date: Thu, 9 May 2019 22:10:27 +0200 Subject: Add emoji suggestions to CW and poll option fields (#10555) * Refactor selectComposeSuggestion so that different paths can be updated * Add suggestions in CW field * Add emoji suggestion to poll options * Attempt to fix CSS * Hide suggestions by default They will be enabled if the input has focus --- app/javascript/mastodon/actions/compose.js | 3 +- .../mastodon/components/autosuggest_input.js | 229 +++++++++++++++++++++ .../mastodon/components/autosuggest_textarea.js | 12 +- .../features/compose/components/compose_form.js | 28 ++- .../features/compose/components/poll_form.js | 34 ++- .../compose/containers/compose_form_container.js | 4 +- .../compose/containers/poll_form_container.js | 19 ++ app/javascript/mastodon/reducers/compose.js | 14 +- app/javascript/styles/mastodon/components.scss | 1 + app/javascript/styles/mastodon/polls.scss | 8 +- 10 files changed, 328 insertions(+), 24 deletions(-) create mode 100644 app/javascript/mastodon/components/autosuggest_input.js (limited to 'app/javascript') diff --git a/app/javascript/mastodon/actions/compose.js b/app/javascript/mastodon/actions/compose.js index 0ee663766..94062f2be 100644 --- a/app/javascript/mastodon/actions/compose.js +++ b/app/javascript/mastodon/actions/compose.js @@ -383,7 +383,7 @@ export function readyComposeSuggestionsAccounts(token, accounts) { }; }; -export function selectComposeSuggestion(position, token, suggestion) { +export function selectComposeSuggestion(position, token, suggestion, path) { return (dispatch, getState) => { let completion, startPosition; @@ -405,6 +405,7 @@ export function selectComposeSuggestion(position, token, suggestion) { position: startPosition, token, completion, + path, }); }; }; diff --git a/app/javascript/mastodon/components/autosuggest_input.js b/app/javascript/mastodon/components/autosuggest_input.js new file mode 100644 index 000000000..bb8ab60db --- /dev/null +++ b/app/javascript/mastodon/components/autosuggest_input.js @@ -0,0 +1,229 @@ +import React from 'react'; +import AutosuggestAccountContainer from '../features/compose/containers/autosuggest_account_container'; +import AutosuggestEmoji from './autosuggest_emoji'; +import ImmutablePropTypes from 'react-immutable-proptypes'; +import PropTypes from 'prop-types'; +import { isRtl } from '../rtl'; +import ImmutablePureComponent from 'react-immutable-pure-component'; +import classNames from 'classnames'; +import { List as ImmutableList } from 'immutable'; + +const textAtCursorMatchesToken = (str, caretPosition, searchTokens) => { + let word; + + let left = str.slice(0, caretPosition).search(/\S+$/); + let right = str.slice(caretPosition).search(/\s/); + + if (right < 0) { + word = str.slice(left); + } else { + word = str.slice(left, right + caretPosition); + } + + if (!word || word.trim().length < 3 || searchTokens.indexOf(word[0]) === -1) { + return [null, null]; + } + + word = word.trim().toLowerCase(); + + if (word.length > 0) { + return [left + 1, word]; + } else { + return [null, null]; + } +}; + +export default class AutosuggestInput extends ImmutablePureComponent { + + static propTypes = { + value: PropTypes.string, + suggestions: ImmutablePropTypes.list, + disabled: PropTypes.bool, + placeholder: PropTypes.string, + onSuggestionSelected: PropTypes.func.isRequired, + onSuggestionsClearRequested: PropTypes.func.isRequired, + onSuggestionsFetchRequested: PropTypes.func.isRequired, + onChange: PropTypes.func.isRequired, + onKeyUp: PropTypes.func, + onKeyDown: PropTypes.func, + autoFocus: PropTypes.bool, + className: PropTypes.string, + id: PropTypes.string, + searchTokens: PropTypes.list, + maxLength: PropTypes.number, + }; + + static defaultProps = { + autoFocus: true, + searchTokens: ImmutableList(['@', ':', '#']), + }; + + state = { + suggestionsHidden: true, + focused: false, + selectedSuggestion: 0, + lastToken: null, + tokenStart: 0, + }; + + onChange = (e) => { + const [ tokenStart, token ] = textAtCursorMatchesToken(e.target.value, e.target.selectionStart, this.props.searchTokens); + + if (token !== null && this.state.lastToken !== token) { + this.setState({ lastToken: token, selectedSuggestion: 0, tokenStart }); + this.props.onSuggestionsFetchRequested(token); + } else if (token === null) { + this.setState({ lastToken: null }); + this.props.onSuggestionsClearRequested(); + } + + this.props.onChange(e); + } + + onKeyDown = (e) => { + const { suggestions, disabled } = this.props; + const { selectedSuggestion, suggestionsHidden } = this.state; + + if (disabled) { + e.preventDefault(); + return; + } + + if (e.which === 229 || e.isComposing) { + // Ignore key events during text composition + // e.key may be a name of the physical key even in this case (e.x. Safari / Chrome on Mac) + return; + } + + switch(e.key) { + case 'Escape': + if (suggestions.size === 0 || suggestionsHidden) { + document.querySelector('.ui').parentElement.focus(); + } else { + e.preventDefault(); + this.setState({ suggestionsHidden: true }); + } + + break; + case 'ArrowDown': + if (suggestions.size > 0 && !suggestionsHidden) { + e.preventDefault(); + this.setState({ selectedSuggestion: Math.min(selectedSuggestion + 1, suggestions.size - 1) }); + } + + break; + case 'ArrowUp': + if (suggestions.size > 0 && !suggestionsHidden) { + e.preventDefault(); + this.setState({ selectedSuggestion: Math.max(selectedSuggestion - 1, 0) }); + } + + break; + case 'Enter': + case 'Tab': + // Select suggestion + if (this.state.lastToken !== null && suggestions.size > 0 && !suggestionsHidden) { + e.preventDefault(); + e.stopPropagation(); + this.props.onSuggestionSelected(this.state.tokenStart, this.state.lastToken, suggestions.get(selectedSuggestion)); + } + + break; + } + + if (e.defaultPrevented || !this.props.onKeyDown) { + return; + } + + this.props.onKeyDown(e); + } + + onBlur = () => { + this.setState({ suggestionsHidden: true, focused: false }); + } + + onFocus = () => { + this.setState({ focused: true }); + } + + onSuggestionClick = (e) => { + const suggestion = this.props.suggestions.get(e.currentTarget.getAttribute('data-index')); + e.preventDefault(); + this.props.onSuggestionSelected(this.state.tokenStart, this.state.lastToken, suggestion); + this.input.focus(); + } + + componentWillReceiveProps (nextProps) { + if (nextProps.suggestions !== this.props.suggestions && nextProps.suggestions.size > 0 && this.state.suggestionsHidden && this.state.focused) { + this.setState({ suggestionsHidden: false }); + } + } + + setInput = (c) => { + this.input = c; + } + + renderSuggestion = (suggestion, i) => { + const { selectedSuggestion } = this.state; + let inner, key; + + if (typeof suggestion === 'object') { + inner = ; + key = suggestion.id; + } else if (suggestion[0] === '#') { + inner = suggestion; + key = suggestion; + } else { + inner = ; + key = suggestion; + } + + return ( +
    + {inner} +
    + ); + } + + render () { + const { value, suggestions, disabled, placeholder, onKeyUp, autoFocus, className, id, maxLength } = this.props; + const { suggestionsHidden } = this.state; + const style = { direction: 'ltr' }; + + if (isRtl(value)) { + style.direction = 'rtl'; + } + + return ( +
    + + +
    + {suggestions.map(this.renderSuggestion)} +
    +
    + ); + } + +} diff --git a/app/javascript/mastodon/components/autosuggest_textarea.js b/app/javascript/mastodon/components/autosuggest_textarea.js index a4f5cf50c..f3fb7fa8b 100644 --- a/app/javascript/mastodon/components/autosuggest_textarea.js +++ b/app/javascript/mastodon/components/autosuggest_textarea.js @@ -55,7 +55,8 @@ export default class AutosuggestTextarea extends ImmutablePureComponent { }; state = { - suggestionsHidden: false, + suggestionsHidden: true, + focused: false, selectedSuggestion: 0, lastToken: null, tokenStart: 0, @@ -134,7 +135,11 @@ export default class AutosuggestTextarea extends ImmutablePureComponent { } onBlur = () => { - this.setState({ suggestionsHidden: true }); + this.setState({ suggestionsHidden: true, focused: false }); + } + + onFocus = () => { + this.setState({ focused: true }); } onSuggestionClick = (e) => { @@ -145,7 +150,7 @@ export default class AutosuggestTextarea extends ImmutablePureComponent { } componentWillReceiveProps (nextProps) { - if (nextProps.suggestions !== this.props.suggestions && nextProps.suggestions.size > 0 && this.state.suggestionsHidden) { + if (nextProps.suggestions !== this.props.suggestions && nextProps.suggestions.size > 0 && this.state.suggestionsHidden && this.state.focused) { this.setState({ suggestionsHidden: false }); } } @@ -207,6 +212,7 @@ export default class AutosuggestTextarea extends ImmutablePureComponent { onChange={this.onChange} onKeyDown={this.onKeyDown} onKeyUp={onKeyUp} + onFocus={this.onFocus} onBlur={this.onBlur} onPaste={this.onPaste} style={style} diff --git a/app/javascript/mastodon/features/compose/components/compose_form.js b/app/javascript/mastodon/features/compose/components/compose_form.js index 2b9da20d7..cf82ef5a8 100644 --- a/app/javascript/mastodon/features/compose/components/compose_form.js +++ b/app/javascript/mastodon/features/compose/components/compose_form.js @@ -5,6 +5,7 @@ import ImmutablePropTypes from 'react-immutable-proptypes'; import PropTypes from 'prop-types'; import ReplyIndicatorContainer from '../containers/reply_indicator_container'; import AutosuggestTextarea from '../../../components/autosuggest_textarea'; +import AutosuggestInput from '../../../components/autosuggest_input'; import PollButtonContainer from '../containers/poll_button_container'; import UploadButtonContainer from '../containers/upload_button_container'; import { defineMessages, injectIntl } from 'react-intl'; @@ -102,7 +103,11 @@ class ComposeForm extends ImmutablePureComponent { } onSuggestionSelected = (tokenStart, token, value) => { - this.props.onSuggestionSelected(tokenStart, token, value); + this.props.onSuggestionSelected(tokenStart, token, value, ['text']); + } + + onSpoilerSuggestionSelected = (tokenStart, token, value) => { + this.props.onSuggestionSelected(tokenStart, token, value, ['spoiler_text']); } handleChangeSpoilerText = (e) => { @@ -135,7 +140,7 @@ class ComposeForm extends ImmutablePureComponent { this.autosuggestTextarea.textarea.focus(); } else if (this.props.spoiler !== prevProps.spoiler) { if (this.props.spoiler) { - this.spoilerText.focus(); + this.spoilerText.input.focus(); } else { this.autosuggestTextarea.textarea.focus(); } @@ -178,10 +183,21 @@ class ComposeForm extends ImmutablePureComponent {
    - +
    diff --git a/app/javascript/mastodon/features/compose/components/poll_form.js b/app/javascript/mastodon/features/compose/components/poll_form.js index 383e37eb6..211601d52 100644 --- a/app/javascript/mastodon/features/compose/components/poll_form.js +++ b/app/javascript/mastodon/features/compose/components/poll_form.js @@ -5,6 +5,7 @@ import ImmutablePureComponent from 'react-immutable-pure-component'; import { defineMessages, injectIntl, FormattedMessage } from 'react-intl'; import IconButton from 'mastodon/components/icon_button'; import Icon from 'mastodon/components/icon'; +import AutosuggestInput from 'mastodon/components/autosuggest_input'; import classNames from 'classnames'; const messages = defineMessages({ @@ -27,6 +28,10 @@ class Option extends React.PureComponent { onChange: PropTypes.func.isRequired, onRemove: PropTypes.func.isRequired, onToggleMultiple: PropTypes.func.isRequired, + suggestions: ImmutablePropTypes.list, + onClearSuggestions: PropTypes.func.isRequired, + onFetchSuggestions: PropTypes.func.isRequired, + onSuggestionSelected: PropTypes.func.isRequired, intl: PropTypes.object.isRequired, }; @@ -38,12 +43,25 @@ class Option extends React.PureComponent { this.props.onRemove(this.props.index); }; + handleToggleMultiple = e => { this.props.onToggleMultiple(); e.preventDefault(); e.stopPropagation(); }; + onSuggestionsClearRequested = () => { + this.props.onClearSuggestions(); + } + + onSuggestionsFetchRequested = (token) => { + this.props.onFetchSuggestions(token); + } + + onSuggestionSelected = (tokenStart, token, value) => { + this.props.onSuggestionSelected(tokenStart, token, value, ['poll', 'options', this.props.index]); + } + render () { const { isPollMultiple, title, index, intl } = this.props; @@ -57,12 +75,16 @@ class Option extends React.PureComponent { tabIndex='0' /> - @@ -87,6 +109,10 @@ class PollForm extends ImmutablePureComponent { onAddOption: PropTypes.func.isRequired, onRemoveOption: PropTypes.func.isRequired, onChangeSettings: PropTypes.func.isRequired, + suggestions: ImmutablePropTypes.list, + onClearSuggestions: PropTypes.func.isRequired, + onFetchSuggestions: PropTypes.func.isRequired, + onSuggestionSelected: PropTypes.func.isRequired, intl: PropTypes.object.isRequired, }; @@ -103,7 +129,7 @@ class PollForm extends ImmutablePureComponent { }; render () { - const { options, expiresIn, isMultiple, onChangeOption, onRemoveOption, intl } = this.props; + const { options, expiresIn, isMultiple, onChangeOption, onRemoveOption, intl, ...other } = this.props; if (!options) { return null; @@ -112,7 +138,7 @@ class PollForm extends ImmutablePureComponent { return (
      - {options.map((title, i) =>
    diff --git a/app/javascript/mastodon/features/compose/containers/compose_form_container.js b/app/javascript/mastodon/features/compose/containers/compose_form_container.js index f9f1fba36..93a468388 100644 --- a/app/javascript/mastodon/features/compose/containers/compose_form_container.js +++ b/app/javascript/mastodon/features/compose/containers/compose_form_container.js @@ -45,8 +45,8 @@ const mapDispatchToProps = (dispatch) => ({ dispatch(fetchComposeSuggestions(token)); }, - onSuggestionSelected (position, token, suggestion) { - dispatch(selectComposeSuggestion(position, token, suggestion)); + onSuggestionSelected (position, token, suggestion, path) { + dispatch(selectComposeSuggestion(position, token, suggestion, path)); }, onChangeSpoilerText (checked) { diff --git a/app/javascript/mastodon/features/compose/containers/poll_form_container.js b/app/javascript/mastodon/features/compose/containers/poll_form_container.js index da795a291..1401371d0 100644 --- a/app/javascript/mastodon/features/compose/containers/poll_form_container.js +++ b/app/javascript/mastodon/features/compose/containers/poll_form_container.js @@ -1,8 +1,14 @@ import { connect } from 'react-redux'; import PollForm from '../components/poll_form'; import { addPollOption, removePollOption, changePollOption, changePollSettings } from '../../../actions/compose'; +import { + clearComposeSuggestions, + fetchComposeSuggestions, + selectComposeSuggestion, +} from '../../../actions/compose'; const mapStateToProps = state => ({ + suggestions: state.getIn(['compose', 'suggestions']), options: state.getIn(['compose', 'poll', 'options']), expiresIn: state.getIn(['compose', 'poll', 'expires_in']), isMultiple: state.getIn(['compose', 'poll', 'multiple']), @@ -24,6 +30,19 @@ const mapDispatchToProps = dispatch => ({ onChangeSettings(expiresIn, isMultiple) { dispatch(changePollSettings(expiresIn, isMultiple)); }, + + onClearSuggestions () { + dispatch(clearComposeSuggestions()); + }, + + onFetchSuggestions (token) { + dispatch(fetchComposeSuggestions(token)); + }, + + onSuggestionSelected (position, token, accountId, path) { + dispatch(selectComposeSuggestion(position, token, accountId, path)); + }, + }); export default connect(mapStateToProps, mapDispatchToProps)(PollForm); diff --git a/app/javascript/mastodon/reducers/compose.js b/app/javascript/mastodon/reducers/compose.js index b45def281..39cc5bd81 100644 --- a/app/javascript/mastodon/reducers/compose.js +++ b/app/javascript/mastodon/reducers/compose.js @@ -131,13 +131,15 @@ function removeMedia(state, mediaId) { }); }; -const insertSuggestion = (state, position, token, completion) => { +const insertSuggestion = (state, position, token, completion, path) => { return state.withMutations(map => { - map.update('text', oldText => `${oldText.slice(0, position)}${completion} ${oldText.slice(position + token.length)}`); + map.updateIn(path, oldText => `${oldText.slice(0, position)}${completion} ${oldText.slice(position + token.length)}`); map.set('suggestion_token', null); - map.update('suggestions', ImmutableList(), list => list.clear()); - map.set('focusDate', new Date()); - map.set('caretPosition', position + completion.length + 1); + map.set('suggestions', ImmutableList()); + if (path.length === 1 && path[0] === 'text') { + map.set('focusDate', new Date()); + map.set('caretPosition', position + completion.length + 1); + } map.set('idempotencyKey', uuid()); }); }; @@ -304,7 +306,7 @@ export default function compose(state = initialState, action) { case COMPOSE_SUGGESTIONS_READY: return state.set('suggestions', ImmutableList(action.accounts ? action.accounts.map(item => item.id) : action.emojis)).set('suggestion_token', action.token); case COMPOSE_SUGGESTION_SELECT: - return insertSuggestion(state, action.position, action.token, action.completion); + return insertSuggestion(state, action.position, action.token, action.completion, action.path); case COMPOSE_SUGGESTION_TAGS_UPDATE: return updateSuggestionTags(state, action.token); case COMPOSE_TAG_HISTORY_UPDATE: diff --git a/app/javascript/styles/mastodon/components.scss b/app/javascript/styles/mastodon/components.scss index 0da3ed909..e8c5f70f5 100644 --- a/app/javascript/styles/mastodon/components.scss +++ b/app/javascript/styles/mastodon/components.scss @@ -319,6 +319,7 @@ } .autosuggest-textarea, + .autosuggest-input, .spoiler-input { position: relative; } diff --git a/app/javascript/styles/mastodon/polls.scss b/app/javascript/styles/mastodon/polls.scss index 37c454a78..0d55afda4 100644 --- a/app/javascript/styles/mastodon/polls.scss +++ b/app/javascript/styles/mastodon/polls.scss @@ -37,11 +37,14 @@ display: none; } + .autossugest-input { + flex: 1 1 auto; + } + input[type=text] { display: block; box-sizing: border-box; - flex: 1 1 auto; - width: 20px; + width: 100%; font-size: 14px; color: $inverted-text-color; display: block; @@ -64,6 +67,7 @@ &.editable { display: flex; align-items: center; + overflow: visible; } } -- cgit From fe8a8f779e36e25286b6a7ddc7bcd08e2a4e2890 Mon Sep 17 00:00:00 2001 From: Aurélien Reeves Date: Thu, 9 May 2019 22:39:27 +0200 Subject: Add confirm modal for unboosting toots (#10287) [#3815] Display the boost modal also when unboosting toots. --- app/javascript/mastodon/containers/status_container.js | 16 ++++++++-------- .../mastodon/features/ui/components/boost_modal.js | 4 +++- 2 files changed, 11 insertions(+), 9 deletions(-) (limited to 'app/javascript') diff --git a/app/javascript/mastodon/containers/status_container.js b/app/javascript/mastodon/containers/status_container.js index 0fce674e2..86324b846 100644 --- a/app/javascript/mastodon/containers/status_container.js +++ b/app/javascript/mastodon/containers/status_container.js @@ -69,18 +69,18 @@ const mapDispatchToProps = (dispatch, { intl }) => ({ }, onModalReblog (status) { - dispatch(reblog(status)); + if (status.get('reblogged')) { + dispatch(unreblog(status)); + } else { + dispatch(reblog(status)); + } }, onReblog (status, e) { - if (status.get('reblogged')) { - dispatch(unreblog(status)); + if (e.shiftKey || !boostModal) { + this.onModalReblog(status); } else { - if (e.shiftKey || !boostModal) { - this.onModalReblog(status); - } else { - dispatch(openModal('BOOST', { status, onReblog: this.onModalReblog })); - } + dispatch(openModal('BOOST', { status, onReblog: this.onModalReblog })); } }, diff --git a/app/javascript/mastodon/features/ui/components/boost_modal.js b/app/javascript/mastodon/features/ui/components/boost_modal.js index 920e93d40..4c39a60e7 100644 --- a/app/javascript/mastodon/features/ui/components/boost_modal.js +++ b/app/javascript/mastodon/features/ui/components/boost_modal.js @@ -11,6 +11,7 @@ import ImmutablePureComponent from 'react-immutable-pure-component'; import Icon from 'mastodon/components/icon'; const messages = defineMessages({ + cancel_reblog: { id: 'status.cancel_reblog_private', defaultMessage: 'Unboost' }, reblog: { id: 'status.reblog', defaultMessage: 'Boost' }, }); @@ -51,6 +52,7 @@ class BoostModal extends ImmutablePureComponent { render () { const { status, intl } = this.props; + const buttonText = status.get('reblogged') ? messages.cancel_reblog : messages.reblog; return (
    @@ -76,7 +78,7 @@ class BoostModal extends ImmutablePureComponent {
    Shift + }} />
    -
    ); -- cgit From 6dc9baad2a0993bfec2612d4d85496b47725c219 Mon Sep 17 00:00:00 2001 From: ThibG Date: Fri, 10 May 2019 17:59:57 +0200 Subject: Change icon and label depending on whether media is marked as sensitive (#10748) * Change icon and label depending on whether media is marked as sensitive * WiP use a checkbox --- .../containers/sensitive_button_container.js | 17 +++++++++--- app/javascript/styles/mastodon/components.scss | 31 +++++++++++++++++++--- 2 files changed, 41 insertions(+), 7 deletions(-) (limited to 'app/javascript') diff --git a/app/javascript/mastodon/features/compose/containers/sensitive_button_container.js b/app/javascript/mastodon/features/compose/containers/sensitive_button_container.js index 50612b086..7073f76c2 100644 --- a/app/javascript/mastodon/features/compose/containers/sensitive_button_container.js +++ b/app/javascript/mastodon/features/compose/containers/sensitive_button_container.js @@ -4,7 +4,6 @@ import PropTypes from 'prop-types'; import classNames from 'classnames'; import { changeComposeSensitivity } from 'mastodon/actions/compose'; import { injectIntl, defineMessages, FormattedMessage } from 'react-intl'; -import Icon from 'mastodon/components/icon'; const messages = defineMessages({ marked: { id: 'compose_form.sensitive.marked', defaultMessage: 'Media is marked as sensitive' }, @@ -38,9 +37,19 @@ class SensitiveButton extends React.PureComponent { return (
    - +
    ); } diff --git a/app/javascript/styles/mastodon/components.scss b/app/javascript/styles/mastodon/components.scss index e8c5f70f5..834563ee9 100644 --- a/app/javascript/styles/mastodon/components.scss +++ b/app/javascript/styles/mastodon/components.scss @@ -268,9 +268,34 @@ padding: 10px; padding-top: 0; - .icon-button { - font-size: 14px; - font-weight: 500; + font-size: 14px; + font-weight: 500; + + &.active { + color: $highlight-text-color; + } + + input[type=checkbox] { + display: none; + } + + .checkbox { + display: inline-block; + position: relative; + border: 1px solid $ui-primary-color; + box-sizing: border-box; + width: 18px; + height: 18px; + flex: 0 0 auto; + margin-right: 10px; + top: -1px; + border-radius: 4px; + vertical-align: middle; + + &.active { + border-color: $highlight-text-color; + background: $highlight-text-color; + } } } -- cgit From d25e358f9fd991beb506fc2e76d2cebe2c4d8fc9 Mon Sep 17 00:00:00 2001 From: Alix Rossi Date: Fri, 10 May 2019 18:09:34 +0200 Subject: i18n: Update Corsican translations (#10746) * i18n: Update Corsican translations * Update co.yml * Fix a translation in co.yml --- app/javascript/mastodon/locales/co.json | 3 ++- config/locales/co.yml | 3 ++- 2 files changed, 4 insertions(+), 2 deletions(-) (limited to 'app/javascript') diff --git a/app/javascript/mastodon/locales/co.json b/app/javascript/mastodon/locales/co.json index 016be39b3..335706af7 100644 --- a/app/javascript/mastodon/locales/co.json +++ b/app/javascript/mastodon/locales/co.json @@ -77,6 +77,7 @@ "compose_form.poll.remove_option": "Toglie sta scelta", "compose_form.publish": "Toot", "compose_form.publish_loud": "{publish}!", + "compose_form.sensitive.hide": "Indicà u media cum'è sensibile", "compose_form.sensitive.marked": "Media indicatu cum'è sensibile", "compose_form.sensitive.unmarked": "Media micca indicatu cum'è sensibile", "compose_form.spoiler.marked": "Testu piattatu daret'à un'avertimentu", @@ -209,6 +210,7 @@ "lightbox.close": "Chjudà", "lightbox.next": "Siguente", "lightbox.previous": "Pricidente", + "lightbox.view_context": "Vede u cuntestu", "lists.account.add": "Aghjunghje à a lista", "lists.account.remove": "Toglie di a lista", "lists.delete": "Supprime a lista", @@ -340,7 +342,6 @@ "status.reply": "Risponde", "status.replyAll": "Risponde à tutti", "status.report": "Palisà @{name}", - "status.sensitive_toggle": "Cliccate per vede", "status.sensitive_warning": "Cuntinutu sensibile", "status.share": "Sparte", "status.show_less": "Ripiegà", diff --git a/config/locales/co.yml b/config/locales/co.yml index 8c1a13e54..22ee4b0ce 100644 --- a/config/locales/co.yml +++ b/config/locales/co.yml @@ -81,7 +81,7 @@ co: destroyed_msg: Nota di muderazione sguassata! accounts: approve: Appruvà - approve_all: Appruvà tutti + approve_all: Appruvà tuttu are_you_sure: Site sicuru·a? avatar: Ritrattu di prufile by_domain: Duminiu @@ -877,6 +877,7 @@ co: migrate: Migrazione di u contu notifications: Nutificazione preferences: Priferenze + profile: Prufile relationships: Abbunamenti è abbunati two_factor_authentication: Identificazione à dui fattori statuses: -- cgit From 775ee63b71752a05fefa8070d8fba704006c598d Mon Sep 17 00:00:00 2001 From: Alix Rossi Date: Fri, 10 May 2019 18:09:47 +0200 Subject: i18n: Update French translations (#10747) * Update French JSON * i18n: Update fr.yml * i18n: Update simple_form.fr.yml * Update simple_form.fr.yml * Update fr.yml --- app/javascript/mastodon/locales/fr.json | 3 ++- config/locales/fr.yml | 6 ++++++ config/locales/simple_form.fr.yml | 1 + 3 files changed, 9 insertions(+), 1 deletion(-) (limited to 'app/javascript') diff --git a/app/javascript/mastodon/locales/fr.json b/app/javascript/mastodon/locales/fr.json index 58f3ce147..090f15bea 100644 --- a/app/javascript/mastodon/locales/fr.json +++ b/app/javascript/mastodon/locales/fr.json @@ -77,6 +77,7 @@ "compose_form.poll.remove_option": "Supprimer ce choix", "compose_form.publish": "Pouet", "compose_form.publish_loud": "{publish} !", + "compose_form.sensitive.hide": "Marquer le média comme sensible", "compose_form.sensitive.marked": "Média marqué comme sensible", "compose_form.sensitive.unmarked": "Média non marqué comme sensible", "compose_form.spoiler.marked": "Le texte est caché derrière un avertissement", @@ -209,6 +210,7 @@ "lightbox.close": "Fermer", "lightbox.next": "Suivant", "lightbox.previous": "Précédent", + "lightbox.view_context": "Voir le contexte", "lists.account.add": "Ajouter à la liste", "lists.account.remove": "Supprimer de la liste", "lists.delete": "Effacer la liste", @@ -340,7 +342,6 @@ "status.reply": "Répondre", "status.replyAll": "Répondre au fil", "status.report": "Signaler @{name}", - "status.sensitive_toggle": "Cliquer pour afficher", "status.sensitive_warning": "Contenu sensible", "status.share": "Partager", "status.show_less": "Replier", diff --git a/config/locales/fr.yml b/config/locales/fr.yml index b969fda08..e76fdf99e 100644 --- a/config/locales/fr.yml +++ b/config/locales/fr.yml @@ -26,6 +26,8 @@ fr: hosted_on: Serveur Mastodon hébergée par %{domain} learn_more: En savoir plus privacy_policy: Politique de vie privée + see_whats_happening: Voir ce qui se passe + server_stats: 'Statistiques du serveur :' source_code: Code source status_count_after: one: Statut @@ -66,6 +68,7 @@ fr: admin: Admin bot: Robot moderator: Modérateur·trice + unavailable: Profil non disponible unfollow: Ne plus suivre admin: account_actions: @@ -77,6 +80,8 @@ fr: delete: Supprimer destroyed_msg: Note de modération supprimée avec succès ! accounts: + approve: Approuver + approve_all: Tout approuver are_you_sure: Êtes-vous certain⋅e ? avatar: Avatar by_domain: Domaine @@ -868,6 +873,7 @@ fr: featured_tags: Hashtags mis en avant identity_proofs: Preuves d’identité import: Import de données + import_and_export: Import et export migrate: Migration de compte notifications: Notifications preferences: Préférences diff --git a/config/locales/simple_form.fr.yml b/config/locales/simple_form.fr.yml index 98c802abb..1ce97639c 100644 --- a/config/locales/simple_form.fr.yml +++ b/config/locales/simple_form.fr.yml @@ -128,6 +128,7 @@ fr: follow: Envoyer un courriel lorsque quelqu’un me suit follow_request: Envoyer un courriel lorsque quelqu’un demande à me suivre mention: Envoyer un courriel lorsque quelqu’un me mentionne + pending_account: Envoyer un courriel lorsqu'un nouveau compte est en attente d'approbation reblog: Envoyer un courriel lorsque quelqu’un partage mes statuts report: Envoyer un courriel lorsqu’un nouveau rapport est soumis 'no': Non -- cgit From 96f0747afe346f2aee358d842f8f9f77638c27a9 Mon Sep 17 00:00:00 2001 From: Aurélien Reeves Date: Thu, 9 May 2019 22:39:27 +0200 Subject: [Glitch] Add confirm modal for unboosting toots Port fe8a8f779e36e25286b6a7ddc7bcd08e2a4e2890 to glitch-soc Signed-off-by: Thibaut Girka --- .../flavours/glitch/containers/status_container.js | 16 ++++++++-------- .../glitch/features/ui/components/boost_modal.js | 4 +++- 2 files changed, 11 insertions(+), 9 deletions(-) (limited to 'app/javascript') diff --git a/app/javascript/flavours/glitch/containers/status_container.js b/app/javascript/flavours/glitch/containers/status_container.js index 60636feb4..98dc5bb87 100644 --- a/app/javascript/flavours/glitch/containers/status_container.js +++ b/app/javascript/flavours/glitch/containers/status_container.js @@ -88,18 +88,18 @@ const mapDispatchToProps = (dispatch, { intl }) => ({ }, onModalReblog (status) { - dispatch(reblog(status)); + if (status.get('reblogged')) { + dispatch(unreblog(status)); + } else { + dispatch(reblog(status)); + } }, onReblog (status, e) { - if (status.get('reblogged')) { - dispatch(unreblog(status)); + if (e.shiftKey || !boostModal) { + this.onModalReblog(status); } else { - if (e.shiftKey || !boostModal) { - this.onModalReblog(status); - } else { - dispatch(openModal('BOOST', { status, onReblog: this.onModalReblog })); - } + dispatch(openModal('BOOST', { status, onReblog: this.onModalReblog })); } }, diff --git a/app/javascript/flavours/glitch/features/ui/components/boost_modal.js b/app/javascript/flavours/glitch/features/ui/components/boost_modal.js index 0a914dce2..ce7ec2479 100644 --- a/app/javascript/flavours/glitch/features/ui/components/boost_modal.js +++ b/app/javascript/flavours/glitch/features/ui/components/boost_modal.js @@ -10,6 +10,7 @@ import DisplayName from 'flavours/glitch/components/display_name'; import ImmutablePureComponent from 'react-immutable-pure-component'; const messages = defineMessages({ + cancel_reblog: { id: 'status.cancel_reblog_private', defaultMessage: 'Unboost' }, reblog: { id: 'status.reblog', defaultMessage: 'Boost' }, }); @@ -52,6 +53,7 @@ export default class BoostModal extends ImmutablePureComponent { render () { const { status, intl } = this.props; + const buttonText = status.get('reblogged') ? messages.cancel_reblog : messages.reblog; return (
    @@ -77,7 +79,7 @@ export default class BoostModal extends ImmutablePureComponent {
    Shift + }} />
    -
    ); -- cgit From 78ff7e382103b1489e204d8fc3e02790a7d90b8d Mon Sep 17 00:00:00 2001 From: nzws Date: Wed, 8 May 2019 06:53:58 +0900 Subject: [Glitch] Fix some colors of high contrast theme Signed-off-by: Thibaut Girka --- app/javascript/flavours/glitch/styles/contrast/diff.scss | 8 ++++++++ 1 file changed, 8 insertions(+) (limited to 'app/javascript') diff --git a/app/javascript/flavours/glitch/styles/contrast/diff.scss b/app/javascript/flavours/glitch/styles/contrast/diff.scss index 8429103b8..f78e60597 100644 --- a/app/javascript/flavours/glitch/styles/contrast/diff.scss +++ b/app/javascript/flavours/glitch/styles/contrast/diff.scss @@ -67,3 +67,11 @@ text-decoration: none; } } + +.nothing-here { + color: $darker-text-color; +} + +.public-layout .public-account-header__tabs__tabs .counter.active::after { + border-bottom: 4px solid $ui-highlight-color; +} -- cgit From 14d855c42985503b525f1a77d00fada3bd15b96f Mon Sep 17 00:00:00 2001 From: Maciek Baron Date: Thu, 9 May 2019 21:03:32 +0100 Subject: [Glitch] Improve poll link accessibility Port 0402c52f28b73824d7c81c702a16d39fd97808cf to glitch-soc Signed-off-by: Thibaut Girka --- app/javascript/flavours/glitch/styles/polls.scss | 9 ++++++--- 1 file changed, 6 insertions(+), 3 deletions(-) (limited to 'app/javascript') diff --git a/app/javascript/flavours/glitch/styles/polls.scss b/app/javascript/flavours/glitch/styles/polls.scss index 315fd5782..50bb45e7c 100644 --- a/app/javascript/flavours/glitch/styles/polls.scss +++ b/app/javascript/flavours/glitch/styles/polls.scss @@ -118,11 +118,14 @@ text-decoration: underline; font-size: inherit; - &:hover, - &:focus, - &:active { + &:hover { text-decoration: none; } + + &:active, + &:focus { + background-color: rgba($dark-text-color, .1); + } } .button { -- cgit From 6d44f2441bf2aa14d11e481d9d2cfe82a74d81ed Mon Sep 17 00:00:00 2001 From: ThibG Date: Sat, 11 May 2019 06:46:43 +0200 Subject: Add toot source to delete result to ease Delete & Redraft (#10669) * Return Status with raw text in raw_content when deleting a status * Use raw content if available on delete & redraft * Rename raw_content to text; do not serialize formatted content when source is requested --- app/controllers/api/v1/statuses_controller.rb | 2 +- app/javascript/mastodon/actions/statuses.js | 7 ++++--- app/javascript/mastodon/reducers/compose.js | 2 +- app/serializers/rest/status_serializer.rb | 9 ++++++++- 4 files changed, 14 insertions(+), 6 deletions(-) (limited to 'app/javascript') diff --git a/app/controllers/api/v1/statuses_controller.rb b/app/controllers/api/v1/statuses_controller.rb index f9506971a..b0e134554 100644 --- a/app/controllers/api/v1/statuses_controller.rb +++ b/app/controllers/api/v1/statuses_controller.rb @@ -65,7 +65,7 @@ class Api::V1::StatusesController < Api::BaseController RemovalWorker.perform_async(@status.id) - render_empty + render json: @status, serializer: REST::StatusSerializer, source_requested: true end private diff --git a/app/javascript/mastodon/actions/statuses.js b/app/javascript/mastodon/actions/statuses.js index 1794538e2..3916b9ac1 100644 --- a/app/javascript/mastodon/actions/statuses.js +++ b/app/javascript/mastodon/actions/statuses.js @@ -131,10 +131,11 @@ export function fetchStatusFail(id, error, skipLoading) { }; }; -export function redraft(status) { +export function redraft(status, raw_text) { return { type: REDRAFT, status, + raw_text, }; }; @@ -148,13 +149,13 @@ export function deleteStatus(id, router, withRedraft = false) { dispatch(deleteStatusRequest(id)); - api(getState).delete(`/api/v1/statuses/${id}`).then(() => { + api(getState).delete(`/api/v1/statuses/${id}`).then(response => { evictStatus(id); dispatch(deleteStatusSuccess(id)); dispatch(deleteFromTimelines(id)); if (withRedraft) { - dispatch(redraft(status)); + dispatch(redraft(status, response.data.text)); if (!getState().getIn(['compose', 'mounted'])) { router.push('/statuses/new'); diff --git a/app/javascript/mastodon/reducers/compose.js b/app/javascript/mastodon/reducers/compose.js index 39cc5bd81..85cbdfb17 100644 --- a/app/javascript/mastodon/reducers/compose.js +++ b/app/javascript/mastodon/reducers/compose.js @@ -331,7 +331,7 @@ export default function compose(state = initialState, action) { })); case REDRAFT: return state.withMutations(map => { - map.set('text', unescapeHTML(expandMentions(action.status))); + map.set('text', action.raw_content || unescapeHTML(expandMentions(action.status))); map.set('in_reply_to', action.status.get('in_reply_to_id')); map.set('privacy', action.status.get('visibility')); map.set('media_attachments', action.status.get('media_attachments')); diff --git a/app/serializers/rest/status_serializer.rb b/app/serializers/rest/status_serializer.rb index 106777b6e..c9b76cb16 100644 --- a/app/serializers/rest/status_serializer.rb +++ b/app/serializers/rest/status_serializer.rb @@ -3,7 +3,7 @@ class REST::StatusSerializer < ActiveModel::Serializer attributes :id, :created_at, :in_reply_to_id, :in_reply_to_account_id, :sensitive, :spoiler_text, :visibility, :language, - :uri, :content, :url, :replies_count, :reblogs_count, + :uri, :url, :replies_count, :reblogs_count, :favourites_count attribute :favourited, if: :current_user? @@ -11,6 +11,9 @@ class REST::StatusSerializer < ActiveModel::Serializer attribute :muted, if: :current_user? attribute :pinned, if: :pinnable? + attribute :content, unless: :source_requested? + attribute :text, if: :source_requested? + belongs_to :reblog, serializer: REST::StatusSerializer belongs_to :application, if: :show_application? belongs_to :account, serializer: REST::AccountSerializer @@ -105,6 +108,10 @@ class REST::StatusSerializer < ActiveModel::Serializer %w(public unlisted).include?(object.visibility) end + def source_requested? + instance_options[:source_requested] + end + def ordered_mentions object.active_mentions.to_a.sort_by(&:id) end -- cgit From 3ea5c045d712713535f130e4c462a00845946dda Mon Sep 17 00:00:00 2001 From: Thibaut Girka Date: Fri, 10 May 2019 13:59:41 +0200 Subject: Use a checkbox for the “Mark media as sensitive” composer button MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Fixes #1039 --- .../containers/sensitive_button_container.js | 17 +++++++++--- .../glitch/styles/components/composer.scss | 32 ++++++++++++++++++++-- 2 files changed, 42 insertions(+), 7 deletions(-) (limited to 'app/javascript') diff --git a/app/javascript/flavours/glitch/features/compose/containers/sensitive_button_container.js b/app/javascript/flavours/glitch/features/compose/containers/sensitive_button_container.js index 8f163979f..fa1ae8821 100644 --- a/app/javascript/flavours/glitch/features/compose/containers/sensitive_button_container.js +++ b/app/javascript/flavours/glitch/features/compose/containers/sensitive_button_container.js @@ -4,7 +4,6 @@ import PropTypes from 'prop-types'; import classNames from 'classnames'; import { changeComposeSensitivity } from 'flavours/glitch/actions/compose'; import { injectIntl, defineMessages, FormattedMessage } from 'react-intl'; -import Icon from 'flavours/glitch/components/icon'; const messages = defineMessages({ marked: { id: 'compose_form.sensitive.marked', defaultMessage: 'Media is marked as sensitive' }, @@ -42,9 +41,19 @@ class SensitiveButton extends React.PureComponent { return (
    - +
    ); } diff --git a/app/javascript/flavours/glitch/styles/components/composer.scss b/app/javascript/flavours/glitch/styles/components/composer.scss index 86041da20..bb333d35f 100644 --- a/app/javascript/flavours/glitch/styles/components/composer.scss +++ b/app/javascript/flavours/glitch/styles/components/composer.scss @@ -61,9 +61,35 @@ padding: 10px; padding-top: 0; - .icon-button { - font-size: 14px; - font-weight: 500; + font-size: 14px; + font-weight: 500; + + &.active { + color: $highlight-text-color; + } + + input[type=checkbox] { + display: none; + } + + .checkbox { + display: inline-block; + position: relative; + border: 1px solid $ui-primary-color; + box-sizing: border-box; + width: 18px; + height: 18px; + flex: 0 0 auto; + margin-left: 5px; + margin-right: 10px; + top: -1px; + border-radius: 4px; + vertical-align: middle; + + &.active { + border-color: $highlight-text-color; + background: $highlight-text-color; + } } } -- cgit From 93085c273ced0b57cde40406d2044abd2a1ce48c Mon Sep 17 00:00:00 2001 From: ThibG Date: Sat, 11 May 2019 06:46:43 +0200 Subject: [Glitch] Use raw content if available on Delete & Redraft Port front-end changes from 6d44f2441bf2aa14d11e481d9d2cfe82a74d81ed to glitch-soc --- app/javascript/flavours/glitch/actions/statuses.js | 7 ++++--- app/javascript/flavours/glitch/reducers/compose.js | 2 +- 2 files changed, 5 insertions(+), 4 deletions(-) (limited to 'app/javascript') diff --git a/app/javascript/flavours/glitch/actions/statuses.js b/app/javascript/flavours/glitch/actions/statuses.js index 4eabc4be0..550fe510f 100644 --- a/app/javascript/flavours/glitch/actions/statuses.js +++ b/app/javascript/flavours/glitch/actions/statuses.js @@ -71,10 +71,11 @@ export function fetchStatusFail(id, error, skipLoading) { }; }; -export function redraft(status) { +export function redraft(status, raw_text) { return { type: REDRAFT, status, + raw_text, }; }; @@ -88,12 +89,12 @@ export function deleteStatus(id, router, withRedraft = false) { dispatch(deleteStatusRequest(id)); - api(getState).delete(`/api/v1/statuses/${id}`).then(() => { + api(getState).delete(`/api/v1/statuses/${id}`).then(response => { dispatch(deleteStatusSuccess(id)); dispatch(deleteFromTimelines(id)); if (withRedraft) { - dispatch(redraft(status)); + dispatch(redraft(status, response.data.text)); if (!getState().getIn(['compose', 'mounted'])) { router.push('/statuses/new'); diff --git a/app/javascript/flavours/glitch/reducers/compose.js b/app/javascript/flavours/glitch/reducers/compose.js index 009e1fee7..bc1785a48 100644 --- a/app/javascript/flavours/glitch/reducers/compose.js +++ b/app/javascript/flavours/glitch/reducers/compose.js @@ -426,7 +426,7 @@ export default function compose(state = initialState, action) { return state.mergeIn(['doodle'], action.options); case REDRAFT: return state.withMutations(map => { - map.set('text', unescapeHTML(expandMentions(action.status))); + map.set('text', action.raw_text || unescapeHTML(expandMentions(action.status))); map.set('in_reply_to', action.status.get('in_reply_to_id')); map.set('privacy', action.status.get('visibility')); map.set('media_attachments', action.status.get('media_attachments')); -- cgit