From 42573b76f1ed4ec64a961441b14631c341b752b4 Mon Sep 17 00:00:00 2001 From: ThibG Date: Thu, 23 Aug 2018 00:27:58 +0200 Subject: [PATCH 01/18] Do not crash if remote custom emoji does not define updated date (fixes #8376) (#8377) --- app/lib/activitypub/activity/create.rb | 2 +- app/services/activitypub/process_account_service.rb | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/app/lib/activitypub/activity/create.rb b/app/lib/activitypub/activity/create.rb index 00479fd9a..79efc95d3 100644 --- a/app/lib/activitypub/activity/create.rb +++ b/app/lib/activitypub/activity/create.rb @@ -107,7 +107,7 @@ class ActivityPub::Activity::Create < ActivityPub::Activity updated = tag['updated'] emoji = CustomEmoji.find_by(shortcode: shortcode, domain: @account.domain) - return unless emoji.nil? || emoji.updated_at >= updated + return unless emoji.nil? || image_url != emoji.image_remote_url || (updated && emoji.updated_at >= updated) emoji ||= CustomEmoji.new(domain: @account.domain, shortcode: shortcode, uri: uri) emoji.image_remote_url = image_url diff --git a/app/services/activitypub/process_account_service.rb b/app/services/activitypub/process_account_service.rb index 7f95678b0..ac19bf933 100644 --- a/app/services/activitypub/process_account_service.rb +++ b/app/services/activitypub/process_account_service.rb @@ -226,7 +226,7 @@ class ActivityPub::ProcessAccountService < BaseService updated = tag['updated'] emoji = CustomEmoji.find_by(shortcode: shortcode, domain: @account.domain) - return unless emoji.nil? || emoji.updated_at >= updated + return unless emoji.nil? || image_url != emoji.image_remote_url || (updated && emoji.updated_at >= updated) emoji ||= CustomEmoji.new(domain: @account.domain, shortcode: shortcode, uri: uri) emoji.image_remote_url = image_url From 3cf0cc74351f406bc179ec9f4f325ce7952def53 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Marcin=20Miko=C5=82ajczak?= Date: Thu, 23 Aug 2018 00:28:23 +0200 Subject: [PATCH 02/18] i18n: Update Polish translation (#8378) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: Marcin Mikołajczak --- config/locales/pl.yml | 14 ++++++++++++-- 1 file changed, 12 insertions(+), 2 deletions(-) diff --git a/config/locales/pl.yml b/config/locales/pl.yml index 7047efd1d..e844df699 100644 --- a/config/locales/pl.yml +++ b/config/locales/pl.yml @@ -30,10 +30,14 @@ pl: other_instances: Lista instancji privacy_policy: Polityka prywatności source_code: Kod źródłowy - status_count_after: wpisów + status_count_after: + one: wpisu + other: wpisów status_count_before: Są autorami terms: Zasady użytkowania - user_count_after: użytkowników + user_count_after: + one: użytkownik + other: użytkowników user_count_before: Z serwera korzysta what_is_mastodon: Czym jest Mastodon? accounts: @@ -413,6 +417,12 @@ pl: last_delivery: Ostatnio doręczono title: WebSub topic: Temat + suspensions: + bad_acct_msg: Zawartość potwierdzenia nie zgadza się. Czy próbujesz zawiesić właściwe konto? + hint_html: 'Aby potwierdzić zawieszenie konta, wprowadź %{value} w poniższe pole:' + proceed: Przejdź + title: Zawieś %{acct} + warning_html: 'Zawieszenie konta będzie skutkowało nieodwracalnym usunięciem danych z tego konta, wliczając:' title: Administracja admin_mailer: new_report: From b48e67fe1d6a5b651a4fae961f9323b4feca72e6 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Marcin=20Miko=C5=82ajczak?= Date: Thu, 23 Aug 2018 12:06:02 +0200 Subject: [PATCH 03/18] i18n: fix Polish translation (#8380) --- config/locales/pl.yml | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/config/locales/pl.yml b/config/locales/pl.yml index e844df699..236b9d897 100644 --- a/config/locales/pl.yml +++ b/config/locales/pl.yml @@ -31,13 +31,15 @@ pl: privacy_policy: Polityka prywatności source_code: Kod źródłowy status_count_after: + few: wpisów + many: wpisów one: wpisu - other: wpisów status_count_before: Są autorami terms: Zasady użytkowania user_count_after: + few: użytkowników + many: użytkowników one: użytkownik - other: użytkowników user_count_before: Z serwera korzysta what_is_mastodon: Czym jest Mastodon? accounts: From d1c2c917d9685879d9c5cd203e416a8ef796f1e1 Mon Sep 17 00:00:00 2001 From: Sylvhem Date: Thu, 23 Aug 2018 12:43:03 +0200 Subject: [PATCH 04/18] Major update for the French translation (#8348) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit * Corrige la traduction des filtres Corrige les erreurs de traduction présentes sur l’écran de contrôle des filtres. Fix the translation mistakes made on the filters' control screen. * Remplace « malvoyants » par « malvoyant·e·s » Harmonise la traduction en remplaçant « malvoyants » par sa forme épicène. Harmonize the translation by replacing "malvoyants" (visually impaired) by its epicene form. * Remplace « interface-utilisateur » par « interface utilisateur·ice » Corrige une erreur d’orthographe et harmonise la traduction en utilisant la forme épicène. Fix a spelling mistake and harmonize the translation by using the epicen form. * Traduction de chaînes manquantes Traduits des chaînes manquantes. Translate missing strings. * Diverses corrections Diverses corrections concernant l’orthographe, les formulations employées et les conventions utilisées. Various fix regarding spelling, used wordings and used conventions. * Remplace « ' » par « ’ » Retire de la traduction les apostrophes droites « ' » (U+0027) au profit des apostrophes typographiques « ’ » (U+2019). En typographie française, les apostrophes typographiques sont utilisées à la place des apostrophes droites. La traduction était jusqu’ici incohérente et utilisait les deux. Remove from the translation all the vertical apostrophes (U+0027) in favor of the curly ones (U+2019). In French typography, typographic apostrophes are used instead of vertical ones. The translation was incoherent and used both. * Remplace « ... » par « … » Remplace les séries de trois points par le caractère dédié « … » (U+2026). Replace all the series of three dots by the dedicated character "…" (U+2026). * Ajout d’espaces insécables Ajoute des espaces insécables suivant les régles nécessaires en typographie française. Add non-breaking spaces following rules of French typography. * Traduction de la nouvelle politique de confidentialité Traduction de la nouvelle politique de confidentalité. Translation of the new privacy policy. * Modifications basées sur les retours Modifie la traduction en se basant sur les premiers retours. Diverses corrections orthographiques et typographiques. Fix the translation based on feedback. Various modifications both on spelling and typography. * Change « non-listé » en « non listé » Renome le niveau de confidentialité en « non listé ». Rename the confidentiality level to "non listé". * Modifications basées sur les retours Modifie la traduction en se basant sur les premiers retours. Diverses corrections orthographiques et typographiques. Fix the translation based on feedback. Various modifications both on spelling and typography. * i18n-tasks normalize --- app/javascript/mastodon/locales/fr.json | 48 ++-- config/locales/devise.fr.yml | 22 +- config/locales/doorkeeper.fr.yml | 12 +- config/locales/fr.yml | 293 ++++++++++++++++-------- config/locales/simple_form.fr.yml | 26 +-- 5 files changed, 252 insertions(+), 149 deletions(-) diff --git a/app/javascript/mastodon/locales/fr.json b/app/javascript/mastodon/locales/fr.json index 79ce01c05..835b1af65 100644 --- a/app/javascript/mastodon/locales/fr.json +++ b/app/javascript/mastodon/locales/fr.json @@ -22,7 +22,7 @@ "account.posts": "Pouets", "account.posts_with_replies": "Pouets et réponses", "account.report": "Signaler", - "account.requested": "En attente d'approbation. Cliquez pour annuler la requête", + "account.requested": "En attente d’approbation. Cliquez pour annuler la requête", "account.share": "Partager le profil de @{name}", "account.show_reblogs": "Afficher les partages de @{name}", "account.unblock": "Débloquer", @@ -32,7 +32,7 @@ "account.unmute": "Ne plus masquer", "account.unmute_notifications": "Réactiver les notifications de @{name}", "account.view_full_profile": "Afficher le profil complet", - "alert.unexpected.message": "Une erreur non-attendue s'est produite.", + "alert.unexpected.message": "Une erreur non attendue s’est produite.", "alert.unexpected.title": "Oups !", "boost_modal.combo": "Vous pouvez appuyer sur {combo} pour pouvoir passer ceci, la prochaine fois", "bundle_column_error.body": "Une erreur s’est produite lors du chargement de ce composant.", @@ -62,9 +62,9 @@ "column_header.unpin": "Retirer", "column_subheading.settings": "Paramètres", "community.column_settings.media_only": "Média uniquement", - "compose_form.direct_message_warning": "Ce pouet sera uniquement envoyé qu'aux personnes mentionnées. Cependant, l'administration de votre instance et des instances réceptrices pourront inspecter ce message.", + "compose_form.direct_message_warning": "Ce pouet sera uniquement envoyé aux personnes mentionnées. Cependant, l’administration de votre instance et des instances réceptrices pourront inspecter ce message.", "compose_form.direct_message_warning_learn_more": "En savoir plus", - "compose_form.hashtag_warning": "Ce pouet ne sera pas listé dans les recherches par hashtag car sa visibilité est réglée sur \"non-listé\". Seuls les pouets avec une visibilité \"publique\" peuvent être recherchés par hashtag.", + "compose_form.hashtag_warning": "Ce pouet ne sera pas listé dans les recherches par hashtag car sa visibilité est réglée sur \"non listé\". Seuls les pouets avec une visibilité \"publique\" peuvent être recherchés par hashtag.", "compose_form.lock_disclaimer": "Votre compte n’est pas {locked}. Tout le monde peut vous suivre et voir vos pouets privés.", "compose_form.lock_disclaimer.lock": "verrouillé", "compose_form.placeholder": "Qu’avez-vous en tête ?", @@ -73,7 +73,7 @@ "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", - "compose_form.spoiler.unmarked": "Le texte n'est pas caché", + "compose_form.spoiler.unmarked": "Le texte n’est pas caché", "compose_form.spoiler_placeholder": "Écrivez ici votre avertissement", "confirmation_modal.cancel": "Annuler", "confirmations.block.confirm": "Bloquer", @@ -83,11 +83,11 @@ "confirmations.delete_list.confirm": "Supprimer", "confirmations.delete_list.message": "Êtes-vous sûr de vouloir supprimer définitivement cette liste ?", "confirmations.domain_block.confirm": "Masquer le domaine entier", - "confirmations.domain_block.message": "Êtes-vous vraiment, vraiment sûr⋅e de vouloir bloquer {domain} en entier ? Dans la plupart des cas, quelques blocages ou masquages ciblés sont suffisants et préférables. Vous ne verrez plus de contenu provenant de ce domaine ni dans vos lignes de temps publiques, ni dans vos notifications. Vos suiveurs utilisant ce domaine seront retirés.", + "confirmations.domain_block.message": "Êtes-vous vraiment, vraiment sûr⋅e de vouloir bloquer {domain} en entier ? Dans la plupart des cas, quelques blocages ou masquages ciblés sont suffisants et préférables. Vous ne verrez plus de contenu provenant de ce domaine, ni dans fils publics, ni dans vos notifications. Vos abonné·e·s utilisant ce domaine seront retiré·e·s.", "confirmations.mute.confirm": "Masquer", "confirmations.mute.message": "Confirmez-vous le masquage de {name} ?", "confirmations.redraft.confirm": "Effacer et ré-écrire", - "confirmations.redraft.message": "Êtes vous sûr de vouloir effacer ce statut pour le ré-écrire ? Vous perdrez toutes ses réponses, ses repartages et ses mises en favori.", + "confirmations.redraft.message": "Êtes-vous sûr·e de vouloir effacer ce statut pour le ré-écrire ? Vous perdrez toutes ses réponses, ses repartages et ses mises en favori.", "confirmations.unfollow.confirm": "Ne plus suivre", "confirmations.unfollow.message": "Voulez-vous arrêter de suivre {name} ?", "embed.instructions": "Intégrez ce statut à votre site en copiant le code ci-dessous.", @@ -98,7 +98,7 @@ "emoji_button.food": "Nourriture & Boisson", "emoji_button.label": "Insérer un émoji", "emoji_button.nature": "Nature", - "emoji_button.not_found": "Pas d'emojis !! (╯°□°)╯︵ ┻━┻", + "emoji_button.not_found": "Pas d’émoji !! (╯°□°)╯︵ ┻━┻", "emoji_button.objects": "Objets", "emoji_button.people": "Personnages", "emoji_button.recent": "Fréquemment utilisés", @@ -107,11 +107,11 @@ "emoji_button.symbols": "Symboles", "emoji_button.travel": "Lieux & Voyages", "empty_column.community": "Le fil public local est vide. Écrivez donc quelque chose pour le remplir !", - "empty_column.direct": "Vous n'avez pas encore de messages directs. Lorsque vous en enverrez ou recevrez un, il s'affichera ici.", + "empty_column.direct": "Vous n’avez pas encore de messages directs. Lorsque vous en enverrez ou recevrez un, il s’affichera ici.", "empty_column.hashtag": "Il n’y a encore aucun contenu associé à ce hashtag.", "empty_column.home": "Vous ne suivez personne. Visitez {public} ou utilisez la recherche pour trouver d’autres personnes à suivre.", "empty_column.home.public_timeline": "le fil public", - "empty_column.list": "Il n'y a rien dans cette liste pour l'instant. Dès que des personnes de cette liste publierons de nouveaux statuts, ils apparaîtront ici.", + "empty_column.list": "Il n’y a rien dans cette liste pour l’instant. Dès que des personnes de cette liste publieront de nouveaux statuts, ils apparaîtront ici.", "empty_column.notifications": "Vous n’avez pas encore de notification. Interagissez avec d’autres personnes pour débuter la conversation.", "empty_column.public": "Il n’y a rien ici ! Écrivez quelque chose publiquement, ou bien suivez manuellement des personnes d’autres instances pour remplir le fil public", "follow_request.authorize": "Accepter", @@ -129,7 +129,7 @@ "home.column_settings.show_replies": "Afficher les réponses", "keyboard_shortcuts.back": "revenir en arrière", "keyboard_shortcuts.boost": "partager", - "keyboard_shortcuts.column": "focaliser un statut dans l'une des colonnes", + "keyboard_shortcuts.column": "focaliser un statut dans l’une des colonnes", "keyboard_shortcuts.compose": "pour centrer la zone de rédaction", "keyboard_shortcuts.description": "Description", "keyboard_shortcuts.down": "pour descendre dans la liste", @@ -138,8 +138,8 @@ "keyboard_shortcuts.heading": "Raccourcis clavier", "keyboard_shortcuts.hotkey": "Raccourci", "keyboard_shortcuts.legend": "pour afficher cette légende", - "keyboard_shortcuts.mention": "pour mentionner l'auteur", - "keyboard_shortcuts.profile": "pour ouvrir le profil de l'auteur", + "keyboard_shortcuts.mention": "pour mentionner l’auteur·rice", + "keyboard_shortcuts.profile": "pour ouvrir le profil de l’auteur·rice", "keyboard_shortcuts.reply": "pour répondre", "keyboard_shortcuts.search": "pour cibler la recherche", "keyboard_shortcuts.toggle_hidden": "pour afficher/cacher un texte derrière CW", @@ -202,12 +202,12 @@ "onboarding.next": "Suivant", "onboarding.page_five.public_timelines": "Le fil public global affiche les messages de toutes les personnes suivies par les membres de {domain}. Le fil public local est identique, mais se limite aux membres de {domain}.", "onboarding.page_four.home": "L’accueil affiche les messages des personnes que vous suivez.", - "onboarding.page_four.notifications": "La colonne de notification vous avertit lors d'une interaction avec vous.", + "onboarding.page_four.notifications": "La colonne de notification vous avertit lors d’une interaction avec vous.", "onboarding.page_one.federation": "Mastodon est un réseau de serveurs indépendants qui se joignent pour former un réseau social plus vaste. Nous appelons ces serveurs des instances.", "onboarding.page_one.full_handle": "Votre identifiant complet", - "onboarding.page_one.handle_hint": "C'est ce que vos amis devront rechercher.", + "onboarding.page_one.handle_hint": "C’est ce que vos ami·e·s devront rechercher.", "onboarding.page_one.welcome": "Bienvenue sur Mastodon !", - "onboarding.page_six.admin": "L’administrateur⋅ice de votre instance est {admin}.", + "onboarding.page_six.admin": "Votre instance est administrée par {admin}.", "onboarding.page_six.almost_done": "Nous y sommes presque…", "onboarding.page_six.appetoot": "Bon appouétit !", "onboarding.page_six.apps_available": "De nombreuses {apps} sont disponibles pour iOS, Android et autres.", @@ -220,14 +220,14 @@ "onboarding.page_two.compose": "Écrivez depuis la colonne de composition. Vous pouvez ajouter des images, changer les réglages de confidentialité, et ajouter des avertissements de contenu (Content Warning) grâce aux icônes en dessous.", "onboarding.skip": "Passer", "privacy.change": "Ajuster la confidentialité du message", - "privacy.direct.long": "N'envoyer qu'aux personnes mentionnées", + "privacy.direct.long": "N’envoyer qu’aux personnes mentionnées", "privacy.direct.short": "Direct", "privacy.private.long": "Seul⋅e⋅s vos abonné⋅e⋅s verront vos statuts", "privacy.private.short": "Abonné⋅e⋅s uniquement", "privacy.public.long": "Afficher dans les fils publics", "privacy.public.short": "Public", "privacy.unlisted.long": "Ne pas afficher dans les fils publics", - "privacy.unlisted.short": "Non-listé", + "privacy.unlisted.short": "Non listé", "regeneration_indicator.label": "Chargement…", "regeneration_indicator.sublabel": "Le flux de votre page principale est en cours de préparation !", "relative_time.days": "{number} j", @@ -237,8 +237,8 @@ "relative_time.seconds": "{number} s", "reply_indicator.cancel": "Annuler", "report.forward": "Transférer à {target}", - "report.forward_hint": "Le compte provient d'un autre serveur. Envoyez également une copie anonyme du rapport ?", - "report.hint": "Le rapport sera envoyé aux modérateurs de votre instance. Vous pouvez expliquer pourquoi vous signalez le compte ci-dessous :", + "report.forward_hint": "Le compte provient d’un autre serveur. Envoyez également une copie anonyme du rapport ?", + "report.hint": "Le rapport sera envoyé aux modérateur·rice·s de votre instance. Vous pouvez expliquer pourquoi vous signalez le compte ci-dessous :", "report.placeholder": "Commentaires additionnels", "report.submit": "Envoyer", "report.target": "Signalement", @@ -272,7 +272,7 @@ "status.pin": "Épingler sur le profil", "status.pinned": "Pouet épinglé", "status.reblog": "Partager", - "status.reblog_private": "Booster vers l'audience originale", + "status.reblog_private": "Booster vers l’audience originale", "status.reblogged_by": "{name} a partagé :", "status.redraft": "Effacer et ré-écrire", "status.reply": "Répondre", @@ -292,16 +292,16 @@ "tabs_bar.local_timeline": "Fil public local", "tabs_bar.notifications": "Notifications", "tabs_bar.search": "Chercher", - "trends.count_by_accounts": "{count} {rawCount, plural, one {person} other {people}} discutent", + "trends.count_by_accounts": "{count} {rawCount, plural, one {personne} other {personnes}} discutent", "ui.beforeunload": "Votre brouillon sera perdu si vous quittez Mastodon.", "upload_area.title": "Glissez et déposez pour envoyer", "upload_button.label": "Joindre un média", - "upload_form.description": "Décrire pour les malvoyants", + "upload_form.description": "Décrire pour les malvoyant·e·s", "upload_form.focus": "Recadrer", "upload_form.undo": "Supprimer", "upload_progress.label": "Envoi en cours…", "video.close": "Fermer la vidéo", - "video.exit_fullscreen": "Quitter plein écran", + "video.exit_fullscreen": "Quitter le plein écran", "video.expand": "Agrandir la vidéo", "video.fullscreen": "Plein écran", "video.hide": "Masquer la vidéo", diff --git a/config/locales/devise.fr.yml b/config/locales/devise.fr.yml index 7e10f83b4..e9c98a63f 100644 --- a/config/locales/devise.fr.yml +++ b/config/locales/devise.fr.yml @@ -17,30 +17,30 @@ fr: unconfirmed: Vous devez valider votre compte pour continuer. mailer: confirmation_instructions: - action: Vérifier l'adresse courriel - explanation: Vous avez créé un compte sur %{host} avec cette adresse courriel. Vous êtes à un clic de l'activer. Si ce n'était pas vous, veuillez ignorer ce courriel. - extra_html: S'il vous plaît, consultez également 1les règles de l'instance 2 et 3nos termes de service 4. + action: Vérifier l’adresse courriel + explanation: Vous avez créé un compte sur %{host} avec cette adresse courriel. Vous êtes à un clic de l’activer. Si ce n’était pas vous, veuillez ignorer ce courriel. + extra_html: Merci de consultez également les règles de l’instance et nos conditions d’utilisation. subject: Merci de confirmer votre inscription sur %{instance} - title: Vérifier l'adresse courriel + title: Vérifier l’adresse courriel email_changed: - explanation: 'L''adresse courriel de votre compte est en cours de modification pour devenir :' - extra: Si vous n'avez pas changé votre adresse courriel, il est probable que quelqu'un ait eu accès à votre compte. Veuillez changer votre mot de passe immédiatement ou contacter l'administrateur de l'instance si vous êtes bloqué hors de votre compte. + explanation: 'L’adresse courriel de votre compte est en cours de modification pour devenir :' + extra: Si vous n’avez pas changé votre adresse courriel, il est probable que quelqu’un ait eu accès à votre compte. Veuillez changer votre mot de passe immédiatement ou contacter l’administrateur·rice de l’instance si vous êtes bloqué·e hors de votre compte. subject: 'Mastodon : Courriel modifié' title: Nouvelle adresse courriel password_change: explanation: Le mot de passe de votre compte a été changé. - extra: Si vous n'avez pas changé votre mot de passe, il est probable que quelqu'un ait eu accès à votre compte. Veuillez changer votre mot de passe immédiatement ou contacter l'administrateur de l'instance si vous êtes bloqué hors de votre compte. + extra: Si vous n’avez pas changé votre mot de passe, il est probable que quelqu’un ait eu accès à votre compte. Veuillez changer votre mot de passe immédiatement ou contacter l’administrateur·rice de l’instance si vous êtes bloqué·e hors de votre compte. subject: Votre mot de passe a été modifié avec succès title: Mot de passe modifié reconfirmation_instructions: explanation: Confirmez la nouvelle adresse pour changer votre courriel. - extra: Si ce changement n' a pas été initié par vous, veuillez ignorer ce courriel. L'adresse courriel du compte Mastodon ne changera pas tant que vous n'aurez pas cliqué sur le lien ci-dessus. - subject: 'Mastodon : Confirmez l''email pour %{instance}' - title: Vérifier l'adresse courriel + extra: Si ce changement n’a pas été initié par vous, veuillez ignorer ce courriel. L’adresse courriel du compte Mastodon ne changera pas tant que vous n’aurez pas cliqué sur le lien ci-dessus. + subject: 'Mastodon : Confirmez l’adresse pour %{instance}' + title: Vérifier l’adresse courriel reset_password_instructions: action: Modifier le mot de passe explanation: Vous avez demandé un nouveau mot de passe pour votre compte. - extra: Si vous ne l'avez pas demandé, veuillez ignorer ce courriel. Votre mot de passe ne changera pas tant que vous n'aurez pas cliqué sur le lien ci-dessus et que vous n'en aurez pas créé un nouveau. + extra: Si vous ne l’avez pas demandé, veuillez ignorer ce courriel. Votre mot de passe ne changera pas tant que vous n’aurez pas cliqué sur le lien ci-dessus et que vous n’en aurez pas créé un nouveau. subject: Instructions pour changer votre mot de passe title: Réinitialisation du mot de passe unlock_instructions: diff --git a/config/locales/doorkeeper.fr.yml b/config/locales/doorkeeper.fr.yml index e8668ba82..eae691659 100644 --- a/config/locales/doorkeeper.fr.yml +++ b/config/locales/doorkeeper.fr.yml @@ -7,7 +7,7 @@ fr: redirect_uri: L’URL de redirection scope: Portée scopes: Étendues - website: Site web de l'application + website: Site web de l’application errors: models: doorkeeper/application: @@ -64,7 +64,7 @@ fr: prompt: Autoriser %{client_name} à utiliser votre compte ? title: Autorisation requise show: - title: Copiez ce code d'autorisation et collez-le dans l'application. + title: Copiez ce code d’autorisation et collez-le dans l’application. authorized_applications: buttons: revoke: Annuler @@ -119,12 +119,12 @@ fr: push: recevoir vos notifications read: lire toutes les données de votre compte read:accounts: voir les informations du compte - read:blocks: voir vos bloqués + read:blocks: voir vos bloquages read:favourites: voir vos favoris read:filters: voir vos filtres read:follows: voir vos suivis read:lists: voir vos listes - read:mutes: voir vos silenciés + read:mutes: voir vos masquages read:notifications: voir vos notifications read:reports: voir vos rapports read:search: rechercher en votre nom @@ -137,7 +137,7 @@ fr: write:follows: suivre les gens write:lists: créer des listes write:media: téléverser des fichiers-média - write:mutes: silencier des gens et des conversations + write:mutes: masquer des gens et des conversations write:notifications: nettoyer vos notifications - write:reports: rapporter d'autres personnes + write:reports: rapporter d’autres personnes write:statuses: publier des statuts diff --git a/config/locales/fr.yml b/config/locales/fr.yml index b563405bd..cf8ceb247 100644 --- a/config/locales/fr.yml +++ b/config/locales/fr.yml @@ -4,7 +4,7 @@ fr: about_hashtag_html: Figurent ci-dessous les pouets tagués avec #%{hashtag}. Vous pouvez interagir avec eux si vous avez un compte n’importe où dans le Fediverse. about_mastodon_html: Mastodon est un réseau social utilisant des formats ouverts et des logiciels libres. Comme le courriel, il est décentralisé. about_this: À propos - administered_by: 'Administré par :' + administered_by: 'Administrée par :' api: API apps: Applications mobiles closed_registrations: Les inscriptions sont actuellement fermées sur cette instance. Cependant, vous pouvez trouver une autre instance sur laquelle vous créer un compte et à partir de laquelle vous pourrez accéder au même réseau. @@ -20,7 +20,7 @@ fr: humane_approach_title: Une approche plus humaine not_a_product_body: Mastodon n’est pas un réseau commercial. Ici, pas de publicités, pas de prospection de données et pas d’environnements fermés. Il n’y existe aucune autorité centrale. not_a_product_title: Vous êtes une personne, pas un produit - real_conversation_body: Avec 500 caractères à votre disposition, une grande granularité en termes de diffusion et la possibilité de masquer vos messages derrières des avertissements, vous êtes libre de vous exprimer de la manière qui vous plaît. + real_conversation_body: Avec 500 caractères à votre disposition, une grande granularité en termes de diffusion et la possibilité de masquer vos messages derrière des avertissements, vous êtes libre de vous exprimer de la manière qui vous plaît. real_conversation_title: Construit pour de vraies conversations within_reach_body: Grâce à l’existence d’un environnement API accueillant pour les développeur·se·s, de multiples applications pour iOS, Android et d’autres plateformes vous permettent de rester en contact avec vos ami·e·s où que vous soyez. within_reach_title: Toujours à portée de main @@ -37,16 +37,19 @@ fr: user_count_before: Abrite what_is_mastodon: Qu’est-ce que Mastodon ? accounts: - choices_html: 'Sélection de %{name} :' + choices_html: "%{name} recommande :" follow: Suivre followers: Abonné⋅e⋅s following: Abonnements + joined: Inscrit·e en %{date} media: Médias - moved_html: "%{name} a changé de compte pour %{new_profile_link} :" + moved_html: "%{name} a changé de compte pour %{new_profile_link} :" network_hidden: Cette information n’est pas disponible nothing_here: Rien à voir ici ! people_followed_by: Personnes suivies par %{name} people_who_follow: Personnes qui suivent %{name} + pin_errors: + following: Vous devez être déjà abonné·e à la personne que vous désirez recommander posts: Statuts posts_with_replies: Statuts & réponses reserved_username: Ce nom d’utilisateur⋅ice est réservé @@ -66,7 +69,7 @@ fr: avatar: Avatar by_domain: Domaine change_email: - changed_msg: Courriel du compte modifié avec succès ! + changed_msg: Courriel du compte modifié avec succès ! current_email: Courriel actuel label: Modifier le courriel new_email: Nouveau courriel @@ -121,11 +124,11 @@ fr: public: Publique push_subscription_expires: Expiration de l’abonnement PuSH redownload: Rafraîchir les avatars - remove_avatar: Supprimer l'avatar + remove_avatar: Supprimer l’avatar resend_confirmation: - already_confirmed: Cet utilisateur est déjà confirmé + already_confirmed: Cet·te utilisateur·ice est déjà confirmé·e send: Renvoyer un courriel de confirmation - success: Email de confirmation envoyé avec succès ! + success: Courriel de confirmation envoyé avec succès ! reset: Réinitialiser reset_password: Réinitialiser le mot de passe resubscribe: Se réabonner @@ -154,35 +157,36 @@ fr: web: Web action_logs: actions: - assigned_to_self_report: "%{name} s'est assigné le signalement de %{target} à eux-même" - change_email_user: "%{name} a modifié l'adresse de courriel de l'utilisateur %{target}" - confirm_user: "%{name} adresse courriel confirmée de l'utilisateur %{target}" - create_custom_emoji: "%{name} a importé de nouveaux emoji %{target}" + assigned_to_self_report: "%{name} s’est assigné·e le signalement de %{target}" + change_email_user: "%{name} a modifié l’adresse de courriel de l’utilisateur·rice %{target}" + confirm_user: "%{name} adresse courriel confirmée de l’utilisateur·ice %{target}" + create_custom_emoji: "%{name} a importé de nouveaux émojis %{target}" create_domain_block: "%{name} a bloqué le domaine %{target}" create_email_domain_block: "%{name} a mis le domaine du courriel %{target} sur liste noire" - demote_user: "%{name} a rétrogradé l'utilisateur %{target}" + demote_user: "%{name} a rétrogradé l’utilisateur·ice %{target}" destroy_domain_block: "%{name} a débloqué le domaine %{target}" destroy_email_domain_block: "%{name} a mis le domaine du courriel %{target} sur liste blanche" destroy_status: "%{name} a enlevé le statut de %{target}" - disable_2fa_user: "%{name} a désactivé l'authentification à deux facteurs pour l'utilisateur %{target}" - disable_custom_emoji: "%{name} a désactivé l'emoji %{target}" - disable_user: "%{name} a désactivé le login pour l'utilisateur %{target}" - enable_custom_emoji: "%{name} a activé l'emoji %{target}" - enable_user: "%{name} a activé le login pour l'utilisateur %{target}" + disable_2fa_user: "%{name} a désactivé l’authentification à deux facteurs pour l’utilisateur·ice %{target}" + disable_custom_emoji: "%{name} a désactivé l’émoji %{target}" + disable_user: "%{name} a désactivé le login pour l’utilisateur·ice %{target}" + enable_custom_emoji: "%{name} a activé l’émoji %{target}" + enable_user: "%{name} a activé le login pour l’utilisateur·ice %{target}" memorialize_account: "%{name} a transformé le compte de %{target} en une page de mémorial" - promote_user: "%{name} a promu l'utilisateur %{target}" - remove_avatar_user: "%{name} a supprimé l'avatar de %{target}'s" - reopen_report: "%{name} a ré-ouvert le signalement %{target}" + promote_user: "%{name} a promu l’utilisateur·ice %{target}" + remove_avatar_user: "%{name} a supprimé l’avatar de %{target}" + reopen_report: "%{name} a rouvert le signalement %{target}" reset_password_user: "%{name} a réinitialisé le mot de passe de %{target}" resolve_report: "%{name} a résolu la dénonciation de %{target}" silence_account: "%{name} a mis le compte %{target} en mode silence" suspend_account: "%{name} a suspendu le compte %{target}" - unassigned_report: "%{name} a dés-assigné le signalement %{target}" + unassigned_report: "%{name} a désassigné le signalement %{target}" unsilence_account: "%{name} a mis fin au mode silence de %{target}" unsuspend_account: "%{name} a réactivé le compte de %{target}" - update_custom_emoji: "%{name} a mis à jour l'emoji %{target}" + update_custom_emoji: "%{name} a mis à jour l’émoji %{target}" update_status: "%{name} a mis à jour le statut de %{target}" - title: Journal d'audit + deleted_status: "(statut supprimé)" + title: Journal d’audit custom_emojis: by_domain: Domaine copied_msg: Copie locale de l’émoji créée avec succès ! @@ -203,29 +207,32 @@ fr: overwrite: Réécrire shortcode: Raccourci shortcode_hint: Au moins deux caractères, seulement des caractères alphanumériques ou des tirets bas - title: Émoji personnalisés + title: Émojis personnalisés unlisted: Délisté - update_failed_msg: N'a pas pu mettre à jour cet emoji - updated_msg: Emoji mis à jour avec succès ! + update_failed_msg: N’a pas pu mettre à jour cet émoji + updated_msg: Émoji mis à jour avec succès ! upload: Téléverser dashboard: + backlog: tâches en attente config: Configuration - feature_invites: Liens d'invitation + feature_deletions: Suppressions de comptes + feature_invites: Liens d’invitation feature_registrations: Inscriptions feature_relay: Relais de fédération features: Fonctionnalités hidden_service: Fédération avec des services cachés - recent_users: Utilisateurs récents - search: Recherche texte-plein - single_user_mode: Mode utilisateur unique + open_reports: signalements non résolus + recent_users: Utilisateur·rice·s récent·e·s + search: Recherche plein texte + single_user_mode: Mode utilisateur·ice unique software: Logiciel - space: Utilisation d'espace + space: Espace utilisé title: Tableau de bord - total_users: utilisateurs au total + total_users: utilisateur·rice·s au total trends: Tendances week_interactions: interactions cette semaine - week_users_active: actif cette semaine - week_users_new: utilisateurs cette semaine + week_users_active: actif·ve·s cette semaine + week_users_new: utilisateur·rice·s cette semaine domain_blocks: add_new: Ajouter created_msg: Le blocage de domaine est désormais activé @@ -284,20 +291,22 @@ fr: title: Invitations relays: add_new: Ajouter un nouveau relais + description_html: Un relai de fédération est un serveur intermédiaire qui échange de grandes quantités de pouets entre les serveurs qui publient dessus et ceux qui y sont abonnés. Il peut aider les petites et moyennes instances à découvrir du contenu sur le fediverse, ce qui normalement nécessiterait que les membres locaux suivent des gens inscrits sur des serveurs distants. + enable_hint: Une fois activé, votre serveur souscrira à tous les pouets publics présents sur ce relais et y enverra ses propres pouets publics. inbox_url: URL de relais setup: Paramétrer une connexion de relais status: Statut title: Relais report_notes: - created_msg: Note de signalement créée avec succès ! - destroyed_msg: Note de signalement effacée avec succès ! + created_msg: Note de signalement créée avec succès ! + destroyed_msg: Note de signalement effacée avec succès ! reports: account: note: note report: signaler action_taken_by: Intervention de are_you_sure: Êtes vous certain⋅e ? - assign_to_self: Me l'assigner + assign_to_self: Me l’assigner assigned: Modérateur assigné comment: none: Aucun @@ -317,7 +326,7 @@ fr: reported_account: Compte signalé reported_by: Signalé par resolved: Résolus - resolved_msg: Signalement résolu avec succès ! + resolved_msg: Signalement résolu avec succès ! silence_account: Masquer le compte status: Statut suspend_account: Suspendre le compte @@ -329,20 +338,23 @@ fr: view: Voir settings: activity_api_enabled: - desc_html: Nombre de statuts affichés localement, d'utilisateurs actifs et de nouveaux enregistrements dans les registres hebdomadaires - title: Publier des statistiques agrégées sur l'activité des utilisateurs + desc_html: Nombre de statuts affichés localement, d’utilisateur·ice·s actif·ve·s et de nouveaux enregistrements dans les registres hebdomadaires + title: Publier des statistiques agrégées sur l’activité des utilisateur·ice·s bootstrap_timeline_accounts: - desc_html: Séparez les noms d’utilisateur·ice par des virgules. Ne fonctionne qu’avec des comptes locaux et non-verrouillés. Si laissé vide, tous les administrateur⋅ice⋅s locaux sont sélectionné⋅e⋅s. + desc_html: Séparez les noms d’utilisateur·ice par des virgules. Ne fonctionne qu’avec des comptes locaux et non verrouillés. Si laissé vide, tous les administrateur⋅ice⋅s locaux sont sélectionné⋅e⋅s. title: Abonnements par défaut pour les nouveaux·elles utilisateur·ice·s contact_information: email: Entrez une adresse courriel publique username: Entrez un nom d’utilisateur⋅ice hero: - desc_html: Affichée sur la page d'accueil. Au moins 600x100px recommandé. Lorsqu'elle n'est pas définie, se rabat sur la vignette de l'instance - title: Image d'en-tête + desc_html: Affichée sur la page d’accueil. Au moins 600x100px recommandé. Lorsqu’elle n’est pas définie, se rabat sur la vignette de l’instance + title: Image d’en-tête peers_api_enabled: desc_html: Noms des domaines que cette instance a découvert dans le fediverse title: Publier la liste des instances découvertes + preview_sensitive_media: + desc_html: Les liens de prévisualisation sur les autres sites web afficheront une vignette même si le média est sensible + title: Afficher les médias sensibles dans les prévisualisations OpenGraph registrations: closed_message: desc_html: Affiché sur la page d’accueil lorsque les inscriptions sont fermées
Vous pouvez utiliser des balises HTML @@ -357,19 +369,20 @@ fr: desc_html: Autoriser tout le monde à créer un compte title: Ouvrir les inscriptions show_known_fediverse_at_about_page: - desc_html: Lorsque l'option est activée, les pouets provenant de toutes les instances connues sont affichés dans la prévisualisation. Si non, seuls les pouets locaux sont affichés. + desc_html: Lorsque l’option est activée, les pouets provenant de toutes les instances connues sont affichés dans la prévisualisation. Sinon, seuls les pouets locaux sont affichés. title: Afficher le fediverse connu dans la prévisualisation du fil show_staff_badge: - desc_html: Montrer un badge de responsable sur une page utilisateur + desc_html: Montrer un badge de responsable sur une page utilisateur·ice title: Montrer un badge de responsable site_description: - desc_html: Paragraphe introductif sur la page d'accueil. Décrivez ce qui rend spécifique ce serveur Mastodon et toute autre chose importante. Vous pouvez utiliser des balises HTML, en particulier <a> et <em>. + desc_html: Paragraphe introductif sur la page d’accueil. Décrivez ce qui rend spécifique ce serveur Mastodon et toute autre chose importante. Vous pouvez utiliser des balises HTML, en particulier <a> et <em>. title: Description du site site_description_extended: desc_html: Affichée sur la page d’informations complémentaires du site
Vous pouvez utiliser des balises HTML title: Description étendue du site site_short_description: - title: Description courte de l'instance + desc_html: Affichée dans la barre latérale et dans les méta-tags. Décrivez ce qui rend spécifique ce serveur Mastodon en un seul paragraphe. Si laissée vide, la description de l’instance sera affiché par défaut. + title: Description courte de l’instance site_terms: desc_html: Affichée sur la page des conditions d’utilisation du site
Vous pouvez utiliser des balises HTML title: Politique de confidentialité @@ -391,6 +404,7 @@ fr: media: title: Médias no_media: Aucun média + no_status_selected: Aucun statut n’a été modifié car aucun n’a été sélectionné title: État du compte with_media: avec médias subscriptions: @@ -404,13 +418,13 @@ fr: admin_mailer: new_report: body: "%{reporter} a signalé %{target}" - body_remote: Quelqu'un de %{domain} a signalé %{target} + body_remote: Quelqu’un de %{domain} a signalé %{target} subject: Nouveau signalement sur %{instance} (#%{id}) application_mailer: notification_preferences: Modifier les préférences de courriel salutation: "%{name}," settings: 'Changer les préférences courriel : %{link}' - view: 'Voir :' + view: 'Voir :' view_profile: Voir le profil view_status: Afficher le statut applications: @@ -440,7 +454,7 @@ fr: cas: CAS saml: SAML register: S’inscrire - register_elsewhere: S'inscrire sur un autre serveur + register_elsewhere: S’inscrire sur un autre serveur resend_confirmation: Envoyer à nouveau les consignes de confirmation reset_password: Réinitialiser le mot de passe security: Sécurité @@ -449,8 +463,8 @@ fr: already_following: Vous suivez déjà ce compte error: Malheureusement, il y a eu une erreur en cherchant les détails du compte distant follow: Suivre - follow_request: 'Vous avez demandé à suivre :' - following: 'Youpi ! Vous suivez  :' + follow_request: 'Vous avez demandé à suivre :' + following: 'Youpi ! Vous suivez  :' post_follow: close: Ou bien, vous pouvez fermer cette fenêtre. return: Afficher le profil de l’utilisateur⋅ice @@ -476,7 +490,7 @@ fr: description_html: Cela va supprimer votre compte et le désactiver de manière permanente et irréversible. Votre nom d’utilisateur⋅ice restera réservé afin d’éviter la confusion. proceed: Supprimer compte success_msg: Votre compte a été supprimé avec succès - warning_html: Seule la suppression du contenu depuis cette instance est garantie. Le contenu qui a été partagé est susceptible de laisser des traces. Les serveurs hors-lignes ainsi que ceux n’étant plus abonnés à vos publications ne mettront pas leur base de données à jour. + warning_html: Seule la suppression du contenu depuis cette instance est garantie. Le contenu qui a été partagé est susceptible de laisser des traces. Les serveurs hors-ligne ainsi que ceux n’étant plus abonnés à vos publications ne mettront pas leur base de données à jour. warning_title: Disponibilité du contenu disséminé errors: '403': Vous n’avez pas accès à cette page. @@ -489,13 +503,13 @@ fr: '500': content: Nous sommes désolé·e·s, mais quelque chose s’est mal passé de notre côté. title: Cette page n’est pas correcte - noscript_html: Pour utiliser Mastodon, veuillez activer JavaScript. Sinon, essayez l'une des applications natives pour Mastodon pour votre plate-forme. + noscript_html: Pour utiliser Mastodon, veuillez activer JavaScript. Sinon, essayez l’une des applications natives pour Mastodon pour votre plate-forme. exports: archive_takeout: date: Date download: Télécharger votre archive hint_html: Vous pouvez demander une archive de vos pouets et médias téléversés. Les données exportées seront au format ActivityPub, lisible par tout logiciel compatible. Vous pouvez demander une archive tous les 7 jours. - in_progress: Élaboration de votre archive.... + in_progress: Création de votre archive… request: Demandez vos archives size: Taille blocks: Vous bloquez @@ -505,12 +519,15 @@ fr: storage: Médias stockés filters: contexts: - home: Ligne de temps personnelle + home: Accueil notifications: Notifications - public: Lignes de temps public + public: Fils publics thread: Conversations edit: - title: Filtre d'édition + title: Éditer le filtre + errors: + invalid_context: Contexte invalide ou insuffisant + invalid_irreversible: Le filtrage irréversible ne fonctionne que pour l’accueil et les notifications index: delete: Effacer title: Filtres @@ -559,7 +576,7 @@ fr: '86400': 1 jour expires_in_prompt: Jamais generate: Générer - invited_by: 'Vous avez été invité par :' + invited_by: 'Vous avez été invité·e par :' max_uses: one: 1 usage other: "%{count} usages" @@ -577,26 +594,26 @@ fr: images_and_video: Impossible de joindre une vidéo à un statut contenant déjà des images too_many: Impossible de joindre plus de 4 fichiers migrations: - acct: utilisateur@domaine du nouveau compte - currently_redirecting: 'Votre profile va être redirigé vers :' + acct: profil@domaine du nouveau compte + currently_redirecting: 'Votre profile va être redirigé vers :' proceed: Enregistrer - updated_msg: Les paramètres de votre migration de compte ont été mis à jour avec succès ! + updated_msg: Les paramètres de votre migration de compte ont été mis à jour avec succès ! moderation: title: Modération notification_mailer: digest: action: Voir toutes les notifications - body: 'Voici ce que vous avez raté sur ${instance} depuis votre dernière visite le %{since} :' - mention: "%{name} vous a mentionné⋅e dans :" + body: 'Voici ce que vous avez raté sur ${instance} depuis votre dernière visite le %{since} :' + mention: "%{name} vous a mentionné⋅e dans :" new_followers_summary: one: Vous avez un⋅e nouvel⋅le abonné⋅e ! Youpi ! other: Vous avez %{count} nouveaux⋅elles abonné⋅e·s ! Incroyable ! subject: one: "Une nouvelle notification depuis votre dernière visite \U0001F418" other: "%{count} nouvelles notifications depuis votre dernière visite \U0001F418" - title: Pendant votre absence... + title: Pendant votre absence… favourite: - body: "%{name} a ajouté votre post à ses favoris :" + body: "%{name} a ajouté votre post à ses favoris :" subject: "%{name} a ajouté votre post à ses favoris" title: Nouveau favori follow: @@ -604,17 +621,17 @@ fr: subject: "%{name} vous suit" title: Nouvel·le abonné·e follow_request: - action: Gérer les demandes d'abonnement + action: Gérer les demandes d’abonnement body: "%{name} a demandé à vous suivre" subject: 'Abonné⋅es en attente : %{name}' - title: Nouvelle demande d'abonnement + title: Nouvelle demande d’abonnement mention: action: Répondre - body: "%{name} vous a mentionné⋅e dans :" + body: "%{name} vous a mentionné⋅e dans :" subject: "%{name} vous a mentionné·e" title: Nouvelle mention reblog: - body: "%{name} a partagé votre statut :" + body: "%{name} a partagé votre statut :" subject: "%{name} a partagé votre statut" title: Nouveau partage number: @@ -640,10 +657,14 @@ fr: publishing: Publication web: Web remote_follow: - acct: Entrez votre pseudo@instance depuis lequel vous voulez suivre cet·te utilisateur⋅ice + acct: Entrez l’adresse profil@instance depuis laquelle vous voulez vous abonner missing_resource: L’URL de redirection n’a pas pu être trouvée - proceed: Continuez pour suivre - prompt: 'Vous allez suivre :' + no_account_html: Vous n’avez pas de compte ? Vous pouvez vous inscrire ici + proceed: Confirmer l’abonnement + prompt: 'Vous allez suivre :' + remote_interaction: + proceed: Confirmer l’interaction + prompt: 'Vous désirez interagir avec ce pouet :' remote_unfollow: error: Erreur title: Titre @@ -706,7 +727,7 @@ fr: your_apps: Vos applications statuses: attached: - description: 'Attaché : %{attached}' + description: 'Attaché : %{attached}' image: one: "%{count} image" other: "%{count} images" @@ -714,10 +735,10 @@ fr: one: "%{count} vidéo" other: "%{count} vidéos" boosted_from_html: Repartagé depuis %{acct_link} - content_warning: 'Attention au contenu : %{warning}' + content_warning: 'Avertissement sur le contenu : %{warning}' disallowed_hashtags: - one: 'contient un hashtag désactivé : %{tags}' - other: 'contient les hashtag désactivés : %{tags}' + one: 'contient un hashtag désactivé : %{tags}' + other: 'contient les hashtags désactivés : %{tags}' language_detection: Détecter automatiquement la langue open_in_web: Ouvrir sur le web over_character_limit: limite de caractères dépassée de %{max} caractères @@ -727,6 +748,7 @@ fr: private: Les statuts non-publics ne peuvent pas être épinglés reblog: Un partage ne peut pas être épinglé show_more: Afficher plus + sign_in_to_participate: Inscrivez-vous pour prendre part à la conversation title: '%{name} : "%{quote}"' visibilities: private: Abonné⋅e⋅s uniquement @@ -740,7 +762,88 @@ fr: reblogged: a partagé sensitive_content: Contenu sensible terms: - title: "%{instance} Conditions d’utilisations et politique de confidentialité" + body_html: | +

Politique de confidentialité

+

Quelles informations collectons-nous ?

+ +
    +
  • Informations de base sur votre compte : Si vous vous inscrivez sur ce serveur, il vous sera demandé de rentrer un identifiant, une adresse électronique et un mot de passe. Vous pourrez également ajouter des informations additionnelles sur votre profil, telles qu’un nom public et une biographie, ainsi que téléverser une image de profil et une image d’en-tête. Vos identifiant, nom public, biographie, image de profil et image d’en-tête seront toujours affichés publiquement.
  • +
  • Posts, liste d’abonnements et autres informations publiques : La liste de vos abonnements ainsi que la liste de vos abonné·e·s sont publiques. Quand vous postez un message, la date et l’heure d’envoi ainsi que le nom de l’application utilisée pour sa transmission sont enregistré·e·s. Des médias, tels que des images ou des vidéos, peuvent être joints aux messages. Les posts publics et non listés sont affichés publiquement. Quand vous mettez en avant un post sur votre profil, ce post est également affiché publiquement. Vos messages sont délivrés à vos abonné·e·s, ce qui, dans certains cas, signifie qu’ils sont délivrés à des serveurs tiers et que ces derniers en stockent une copie. Quand vous supprimer un post, il est probable que vos abonné·e·s en soient informé·e·s. Partager un message ou le marquer comme favori est toujours une action publique.
  • +
  • Posts directs et abonné·e·s uniquement : Tous les posts sont stockés et traités par le serveur. Les messages abonné·e·s uniquement ne sont transmis qu’à vos abonné·e·s et aux personnes mentionnées dans le corps du message, tandis que les messages directs ne sont transmis qu’aux personnes mentionnées. Dans certains cas, cela signifie qu’ils sont délivrés à des serveurs tiers et que ces derniers en stockent une copie. Nous faisons un effort de bonne fois pour en limiter l’accès uniquement aux personnes autorisées, mais ce n’est pas nécessairement le cas des autres serveurs. Il est donc très important que vous vérifiiez les serveurs auxquels appartiennent vos abonné·e·s. Il vous est possible d’activer une option dans les paramètres afin d’approuver et de rejeter manuellement les nouveaux·lles abonné·e·s. Gardez s’il-vous-plaît en mémoire que les opérateur·rice·s du serveur ainsi que celles et ceux de n’importe quel serveur récepteur peuvent voir ces messages et qu’il est possible pour les destinataires de faire des captures d’écran, de copier et plus généralement de repartager ces messages. Ne partager aucune information sensible à l’aide de Mastodon.
  • +
  • IP et autres métadonnées : Quand vous vous connectez, nous enregistrons votre adresse IP ainsi que le nom de votre navigateur web. Toutes les sessions enregistrées peuvent être consultées dans les paramètres, afin que vous puissiez les surveiller et éventuellement les révoquer. La dernière adresse IP utilisée est conservée pour une durée de 12 mois. Nous sommes également susceptibles de conserver les journaux du serveur, ce qui inclut l’adresse IP de chaque requête reçue.
  • +
+ +
+ +

Que faisons-nous des informations que nous collectons ?

+ +

Toutes les informations que nous collectons sur vous peuvent être utilisées d’une des manières suivantes :

+ +
    +
  • Pour vous fournir les fonctionnalités de base de Mastodon. Vous ne pouvez interagir avec le contenu des autres et poster votre propre contenu que lorsque vous êtes connecté·e. Par exemple, vous pouvez vous abonner à plusieurs autres comptes pour voir l’ensemble de leurs posts dans votre fil d’accueil personnalisé.
  • +
  • Pour aider à la modération de la communauté, par exemple, comparer votre adresse IP à d’autres afin de déterminer si un bannissement a été contourné ou si une autre violation aux règles a été commise.
  • +
  • L’adresse électronique que vous nous avez fournie peut être utilisée pour vous envoyez des informations, des notifications lorsque d’autres personnes interagissent avec votre contenu ou vous envoient des messages, pour répondre à des demandes de votre part ainsi que pour tout autres requêtes ou questions.
  • +
+ +
+ +

Comment protégeons-nous vos informations ?

+ +

Nous mettons en œuvre une variété de mesures de sécurité afin de garantir la sécurité de vos informations personnelles quand vous les saisissez, les soumettez et les consultez. Entre autres choses, votre session de navigation ainsi que le trafic entre votre application et l’API sont sécurisés à l’aide de TLS tandis que votre mot de passe est haché en utilisant un puissant algorithme à sens unique. Vous pouvez également activer l’authentification à deux facteurs pour sécuriser encore plus l’accès à votre compte.

+ +
+ +

Quelle est notre politique de conservation des données ?

+ +

Nous ferons un effort de bonne foi :

+ +
    +
  • Pour ne pas conserver plus de 90 jours les journaux systèmes contenant les adresses IP de toutes les requêtes reçues par ce serveur.
  • +
  • Pour ne pas conserver plus de 12 mois les adresses IP associées aux utilisateur·ice·s enregistré·e·s.
  • +
+ +

Vous pouvez demander une archive de votre contenu, incluant vos posts, vos médias joints, votre image de profil et votre image d’en-tête.

+ +

Vous pouvez, à n’importe quel moment, supprimer votre compte de manière définitive.

+ +
+ +

Utilisons-nous des témoins de connexion ?

+ +

Oui. Les témoins de connexion sont de petits fichiers qu’un site ou un service transféres sur le disque dur de votre ordinateur via votre navigateur web (si vous l’avez autorisé). Ces témoins permettent au site de reconnaître votre navigateur et de, dans le cas où vous possédez un compte, de vous associer avec ce dernier.

+ +

Nous utilisons les témoins de connexion comme un moyen de comprendre et de nous souvenir de vos préférences pour vos prochaines visites.

+ +
+ +

Divulguons-nous des informations à des tierces parties ?

+ +

Nous ne vendons, n’échangeons ou ne transférons d’une quelque manière que soit des informations permettant de vous identifier personnellement. Cela n’inclut pas les tierces parties de confiance qui nous aident à opérer ce site, à conduire nos activités commerciales ou à vous servir, tant qu’elles acceptent de garder ces informations confidentielles. Nous sommes également susceptibles de partager vos informations quand nous pensons que c’est nécessaire pour nous conformer à la loi, pour appliquer les politiques de notre site ainsi que pour défendre nos droits, notre propriété, notre sécurité et celles et ceux d’autres personnes.

+ +

Votre contenu public peut être téléchargé par d’autres serveurs du réseau. Dans le cas où vos abonné·e·s et vos destinataires résideraient sur des serveurs différents du vôtre, vos posts publics et abonné·e·s uniquement peuvent être délivrés vers les serveurs de vos abonné·e·s tandis que vos messages directs sont délivrés aux serveurs de vos destinataires.

+ +

Quand vous autorisez une application à utiliser votre compte, en fonction de l’étendue des permissions que vous approuvez, il est possible qu’elle puisse accéder aux informations publiques de votre profil, votre liste d’abonnements, votre liste d’abonné·e·s, vos listes, tout vos posts et vos favoris. Les applications ne peuvent en aucun cas accéder à votre adresse électronique et à votre mot de passe.

+ +
+ +

Utilisation de ce site par les enfants

+ +

Si ce serveur est situé dans dans l’UE ou l’EEE : Notre site, produits et services sont tous destinés à des personnes âgées de 16 ans ou plus. Si vous avez moins de 16 ans, en application du RGPD (Règlement Général sur la Protection des Données), merci de ne pas utiliser ce site.

+ +

Si ce serveur est situé dans aux États-Unis d’Amérique : Notre site, produits et services sont tous destinés à des personnes âgées de 13 ans ou plus. Si vous avez moins de 13 ans, en application du COPPA (Children's Online Privacy Protection Act), merci de ne pas utiliser ce site.

+ +

Les exigences légales peuvent être différentes si ce serveur se trouve dans une autre juridiction.

+ +
+ +

Modifications de notre politique de confidentialité

+ +

Dans le cas où nous déciderions de changer notre politique de confidentialité, nous posterons les modifications sur cette page.

+ +

Ce document est publié sous lincence CC-BY-SA. Il a été mis à jours pour la dernière fois le 7 mars 2018.

+ +

Originellement adapté de la politique de confidentialité de Discourse.

+ title: "%{instance} Conditions d’utilisation et politique de confidentialité" themes: contrast: Contraste élevé default: Mastodon @@ -758,8 +861,8 @@ fr: enabled_success: Identification à deux facteurs activée avec succès generate_recovery_codes: Générer les codes de récupération instructions_html: "Scannez ce QR code grâce à Google Authenticator, Authy ou une application similaire sur votre téléphone. Désormais, cette application génèrera des jetons que vous devrez saisir à chaque connexion." - lost_recovery_codes: Les codes de récupération vous permettent de retrouver les accès à votre comptre si vous perdez votre téléphone. Si vous perdez vos codes de récupération, vous pouvez les générer à nouveau ici. Vos anciens codes de récupération seront invalidés. - manual_instructions: 'Si vous ne pouvez pas scanner ce QR code et devez l’entrer manuellement, voici le secret en clair :' + lost_recovery_codes: Les codes de récupération vous permettent de retrouver les accès à votre compte si vous perdez votre téléphone. Si vous perdez vos codes de récupération, vous pouvez les générer à nouveau ici. Vos anciens codes de récupération seront invalidés. + manual_instructions: 'Si vous ne pouvez pas scanner ce QR code et devez l’entrer manuellement, voici le secret en clair :' recovery_codes: Codes de récupération recovery_codes_regenerated: Codes de récupération régénérés avec succès recovery_instructions_html: Si vous perdez l’accès à votre téléphone, vous pouvez utiliser un des codes de récupération ci-dessous pour retrouver l’accès à votre compte. Conservez les codes de récupération en sécurité. Par exemple, en les imprimant et en les stockant avec vos autres documents importants. @@ -767,30 +870,30 @@ fr: wrong_code: Les codes entrés sont incorrects ! L’heure du serveur et celle de votre appareil sont-elles correctes ? user_mailer: backup_ready: - explanation: Vous avez demandé une sauvegarde complète de votre compte Mastodon. Elle est maintenant prête à être téléchargée ! + explanation: Vous avez demandé une sauvegarde complète de votre compte Mastodon. Elle est maintenant prête à être téléchargée ! subject: Votre archive est prête à être téléchargée - title: Retrait de l'archive + title: Récupération de l’archive welcome: edit_profile_action: Configuration du profil - edit_profile_step: Vous pouvez personnaliser votre profil en téléchargeant un avatar, une image d'en-tête, en changeant votre pseudo et plus encore. Si vous souhaitez examiner les nouveaux abonnés avant qu'ils ne soient autorisés à vous suivre, vous pouvez verrouiller votre compte. + edit_profile_step: Vous pouvez personnaliser votre profil en téléchargeant un avatar, une image d’en-tête, en changeant votre pseudo et plus encore. Si vous souhaitez examiner les nouveaux·lles abonné·e·s avant qu’il·elle·s ne soient autorisé·e·s à vous suivre, vous pouvez verrouiller votre compte. explanation: Voici quelques conseils pour vous aider à démarrer final_action: Commencer à publier - final_step: 'Commencez à poster ! Même sans abonné·es, vos messages publics peuvent être vus par d''autres, par exemple sur la chronologie locale et dans les hashtags. Vous pouvez vous présenter sur le hashtag #introductions.' - full_handle: Votre pleine maîtrise - full_handle_hint: C'est ce que vous diriez à vos amis pour qu'ils puissent vous envoyer un message ou vous suivre à partir d'une autre instance. + final_step: 'Commencez à poster ! Même sans abonné·e·s, vos messages publics peuvent être vus par d’autres, par exemple sur le fil public local et dans les hashtags. Vous pouvez vous présenter sur le hashtag #introductions.' + full_handle: Votre identifiant complet + full_handle_hint: C’est ce que vous diriez à vos ami·e·s pour qu’il·elle·s puissent vous envoyer un message ou vous suivre à partir d’une autre instance. review_preferences_action: Modifier les préférences - review_preferences_step: Assurez-vous de définir vos préférences, telles que les courriels que vous aimeriez recevoir ou le niveau de confidentialité auquel vous aimeriez que vos messages soient soumis par défaut. Si vous n'avez pas le mal des transports, vous pouvez choisir d'activer la lecture automatique GIF. + review_preferences_step: Assurez-vous de définir vos préférences, telles que les courriels que vous aimeriez recevoir ou le niveau de confidentialité auquel vous aimeriez que vos messages soient soumis par défaut. Si vous n’avez pas le mal des transports, vous pouvez choisir d’activer la lecture automatique des GIF. subject: Bienvenue sur Mastodon - tip_bridge_html: Si vous venez de Twitter, vous pouvez retrouver vos amis sur Mastodon en utilisant le bridge app. Cela ne fonctionne que s'ils ont aussi utilisé cette application ! - tip_federated_timeline: La chronologie fédérée est une vue en direct du réseau Mastodon. Mais elle n'inclut que les personnes auxquelles vos voisin·es sont abonné·es, donc elle n'est pas complète. - tip_following: Vous suivez les administrateurs et administratrices de votre serveur par défaut. Pour trouver d'autres personnes intéressantes, consultez les chronologies locales et fédérées. - tip_local_timeline: La chronologie locale est une vue des personnes sur %{instance}. Ce sont vos voisines et voisins immédiats ! - tip_mobile_webapp: Si votre navigateur mobile vous propose d'ajouter Mastodon à votre écran d'accueil, vous pouvez recevoir des notifications. Il agit comme une application native de bien des façons ! + tip_bridge_html: Si vous venez de Twitter, vous pouvez retrouver vos ami·e·s sur Mastodon en utilisant l’application de mise en relation. Cela ne fonctionne que s’il·elle·s ont aussi utilisé cette application ! + tip_federated_timeline: La fil public global est une vue en direct du réseau Mastodon. Mais elle n’inclut que les personnes auxquelles vos voisin·es sont abonné·e·s, donc elle n’est pas complète. + tip_following: Vous suivez les administrateur·rice·s de votre serveur par défaut. Pour trouver d’autres personnes intéressantes, consultez les fils publics local et global. + tip_local_timeline: Le fil public local est une vue des personnes sur %{instance}. Ce sont vos voisines et voisins immédiats ! + tip_mobile_webapp: Si votre navigateur mobile vous propose d’ajouter Mastodon à votre écran d’accueil, vous pouvez recevoir des notifications. Il agit comme une application native de bien des façons ! tips: Astuces - title: Bienvenue à bord, %{name} ! + title: Bienvenue à bord, %{name} ! users: invalid_email: L’adresse courriel est invalide invalid_otp_token: Le code d’authentification à deux facteurs est invalide otp_lost_help_html: Si vous perdez accès aux deux, vous pouvez contacter %{email} seamless_external_login: Vous êtes connecté via un service externe, donc les paramètres concernant le mot de passe et le courriel ne sont pas disponibles. - signed_in_as: 'Connecté·e en tant que :' + signed_in_as: 'Connecté·e en tant que :' diff --git a/config/locales/simple_form.fr.yml b/config/locales/simple_form.fr.yml index a023faf92..b08f4aa9b 100644 --- a/config/locales/simple_form.fr.yml +++ b/config/locales/simple_form.fr.yml @@ -3,34 +3,34 @@ fr: simple_form: hints: defaults: - autofollow: Les personnes qui s'inscrivent grâce à l'invitation vous suivront automatiquement + autofollow: Les personnes qui s’inscrivent grâce à l’invitation vous suivront automatiquement avatar: Au format PNG, GIF ou JPG. 2 Mo maximum. Sera réduit à %{dimensions}px bot: Ce compte exécute principalement des actions automatisées et pourrait ne pas être surveillé - context: Un ou plusieurs contextes où le filtre devrait s'appliquer + context: Un ou plusieurs contextes où le filtre devrait s’appliquer digest: Uniquement envoyé après une longue période d’inactivité et uniquement si vous avez reçu des messages personnels pendant votre absence display_name: one: 1 caractère restant other: %{count} caractères restants - fields: Vous pouvez avoir jusqu'à 4 éléments affichés en tant que tableau sur votre profil + fields: Vous pouvez avoir jusqu’à 4 éléments affichés en tant que tableau sur votre profil header: Au format PNG, GIF ou JPG. 2 Mo maximum. Sera réduit à %{dimensions}px - inbox_url: Copiez l'URL depuis la page d'accueil du relais que vous souhaitez utiliser + inbox_url: Copiez l’URL depuis la page d’accueil du relais que vous souhaitez utiliser irreversible: Les pouets filtrés disparaîtront irrémédiablement, même si le filtre est supprimé plus tard - locale: La langue de l'interface-utilisateur, des courriels, et des notifications + locale: La langue de l’interface, des courriels et des notifications locked: Vous devrez approuver chaque abonné⋅e et vos statuts ne s’afficheront qu’à vos abonné⋅es note: one: 1 caractère restant other: %{count} caractères restants - phrase: Sera trouvé sans que la case ou l'avertissement de contenu du pouet soit pris en compte - scopes: À quelles APIs l'application sera autorisée à accéder. Si vous sélectionnez un périmètre de haut-niveau, vous n'avez pas besoin de sélectionner les individuels. - setting_default_language: La langue de vos pouets peut être détectée automatiquement, mais ça n'est pas toujours pertinent + phrase: Sera trouvé sans que la case ou l’avertissement de contenu du pouet soit pris en compte + scopes: À quelles APIs l’application sera autorisée à accéder. Si vous sélectionnez un périmètre de haut-niveau, vous n’avez pas besoin de sélectionner les individuels. + setting_default_language: La langue de vos pouets peut être détectée automatiquement, mais ça n’est pas toujours pertinent setting_hide_network: Ceux que vous suivez et ceux qui vous suivent ne seront pas affichés sur votre profil setting_noindex: Affecte votre profil public ainsi que vos statuts setting_theme: Affecte l’apparence de Mastodon quand vous êtes connecté·e depuis n’importe quel appareil. - whole_word: Lorsque le mot-clef ou la phrase-clef est uniquement alphanumérique, ça sera uniquement appliqué s'il correspond au mot entier + whole_word: Lorsque le mot-clef ou la phrase-clef est uniquement alphanumérique, ça sera uniquement appliqué s’il correspond au mot entier imports: data: Un fichier CSV généré par une autre instance de Mastodon sessions: - otp: 'Entrez le code d’authentification à deux facteurs généré par votre téléphone ou utilisez un de vos codes de récupération :' + otp: 'Entrez le code d’authentification à deux facteurs généré par votre téléphone ou utilisez un de vos codes de récupération :' user: chosen_languages: Lorsque coché, seuls les pouets dans les langues sélectionnées seront affichés sur les fils publics labels: @@ -55,9 +55,9 @@ fr: header: Image d’en-tête inbox_url: URL de la boîte de relais irreversible: Supprimer plutôt que de cacher - locale: Langue de l'interface + locale: Langue de l’interface locked: Verrouiller le compte - max_uses: Nombre maximum d'utilisations + max_uses: Nombre maximum d’utilisations new_password: Nouveau mot de passe note: Présentation otp_attempt: Code d’identification à deux facteurs @@ -79,7 +79,7 @@ fr: severity: Sévérité type: Type d’import username: Identifiant - username_or_email: Nom d'utilisateur ou courriel + username_or_email: Nom d’utilisateur·ice ou courriel whole_word: Mot entier interactions: must_be_follower: Masquer les notifications des personnes qui ne vous suivent pas From 6cb3514d64ec24b164484f4eb84363b96746d5d6 Mon Sep 17 00:00:00 2001 From: Jakub Mendyk Date: Thu, 23 Aug 2018 14:17:35 +0200 Subject: [PATCH 05/18] Add ability to change an instance default theme from the administration panel (#7092) (#8381) * Add default_settings class method to ScopedSettings ScopedSettings was extended to use value of unscoped setting instead of only using defaults set in config/settings.yml for selected settings. This adds possibility for admins to set default values of users' settings, for example default theme (as requested in #7092). * Add ability to change an instance default theme Closes #7092 --- app/controllers/admin/settings_controller.rb | 1 + app/controllers/application_controller.rb | 2 +- app/lib/settings/scoped_settings.rb | 15 +++++++-- app/models/form/admin_settings.rb | 2 ++ app/views/admin/settings/edit.html.haml | 1 + .../application_controller_spec.rb | 33 +++++++++++++++++++ 6 files changed, 51 insertions(+), 3 deletions(-) diff --git a/app/controllers/admin/settings_controller.rb b/app/controllers/admin/settings_controller.rb index 3234b194f..23e0444d0 100644 --- a/app/controllers/admin/settings_controller.rb +++ b/app/controllers/admin/settings_controller.rb @@ -16,6 +16,7 @@ module Admin timeline_preview show_staff_badge bootstrap_timeline_accounts + theme thumbnail hero min_invite_role diff --git a/app/controllers/application_controller.rb b/app/controllers/application_controller.rb index eafe27047..7ddd26ec0 100644 --- a/app/controllers/application_controller.rb +++ b/app/controllers/application_controller.rb @@ -95,7 +95,7 @@ class ApplicationController < ActionController::Base end def current_theme - return Setting.default_settings['theme'] unless Themes.instance.names.include? current_user&.setting_theme + return Setting.theme unless Themes.instance.names.include? current_user&.setting_theme current_user.setting_theme end diff --git a/app/lib/settings/scoped_settings.rb b/app/lib/settings/scoped_settings.rb index de4af3009..5ee30825d 100644 --- a/app/lib/settings/scoped_settings.rb +++ b/app/lib/settings/scoped_settings.rb @@ -2,6 +2,10 @@ module Settings class ScopedSettings + DEFAULTING_TO_UNSCOPED = %w( + theme + ).freeze + def initialize(object) @object = object end @@ -50,15 +54,22 @@ module Settings Rails.cache.fetch(Setting.cache_key(key, @object)) do db_val = thing_scoped.find_by(var: key.to_s) if db_val - default_value = Setting.default_settings[key] + default_value = ScopedSettings.default_settings[key] return default_value.with_indifferent_access.merge!(db_val.value) if default_value.is_a?(Hash) db_val.value else - Setting.default_settings[key] + ScopedSettings.default_settings[key] end end end + class << self + def default_settings + defaulting = DEFAULTING_TO_UNSCOPED.map { |k| [k, Setting[k]] }.to_h + Setting.default_settings.merge!(defaulting) + end + end + protected def thing_scoped diff --git a/app/models/form/admin_settings.rb b/app/models/form/admin_settings.rb index 010cf7fc3..db46cda7b 100644 --- a/app/models/form/admin_settings.rb +++ b/app/models/form/admin_settings.rb @@ -30,6 +30,8 @@ class Form::AdminSettings :show_staff_badge=, :bootstrap_timeline_accounts, :bootstrap_timeline_accounts=, + :theme, + :theme=, :min_invite_role, :min_invite_role=, :activity_api_enabled, diff --git a/app/views/admin/settings/edit.html.haml b/app/views/admin/settings/edit.html.haml index fda6b00f4..b5aa176a2 100644 --- a/app/views/admin/settings/edit.html.haml +++ b/app/views/admin/settings/edit.html.haml @@ -15,6 +15,7 @@ %hr/ .fields-group + = f.input :theme, collection: Themes.instance.names, label_method: lambda { |theme| I18n.t("themes.#{theme}", default: theme) }, wrapper: :with_label, include_blank: false = f.input :thumbnail, as: :file, wrapper: :with_block_label, label: t('admin.settings.thumbnail.title'), hint: t('admin.settings.thumbnail.desc_html') = f.input :hero, as: :file, wrapper: :with_block_label, label: t('admin.settings.hero.title'), hint: t('admin.settings.hero.desc_html') diff --git a/spec/controllers/application_controller_spec.rb b/spec/controllers/application_controller_spec.rb index c6c78d3f7..d158625e6 100644 --- a/spec/controllers/application_controller_spec.rb +++ b/spec/controllers/application_controller_spec.rb @@ -92,6 +92,39 @@ describe ApplicationController, type: :controller do end end + describe 'helper_method :current_theme' do + it 'returns "default" when theme wasn\'t changed in admin settings' do + allow(Setting).to receive(:default_settings).and_return({'theme' => 'default'}) + + expect(controller.view_context.current_theme).to eq 'default' + end + + it 'returns instances\'s theme when user is not signed in' do + allow(Setting).to receive(:[]).with('theme').and_return 'contrast' + + expect(controller.view_context.current_theme).to eq 'contrast' + end + + it 'returns instances\'s default theme when user didn\'t set theme' do + current_user = Fabricate(:user) + sign_in current_user + + allow(Setting).to receive(:[]).with('theme').and_return 'contrast' + + expect(controller.view_context.current_theme).to eq 'contrast' + end + + it 'returns user\'s theme when it is set' do + current_user = Fabricate(:user) + current_user.settings['theme'] = 'mastodon-light' + sign_in current_user + + allow(Setting).to receive(:[]).with('theme').and_return 'contrast' + + expect(controller.view_context.current_theme).to eq 'mastodon-light' + end + end + context 'ActionController::RoutingError' do subject do routes.draw { get 'routing_error' => 'anonymous#routing_error' } From 63484ee17a857ad0c4c33f196bfa8d825621c509 Mon Sep 17 00:00:00 2001 From: ThibG Date: Thu, 23 Aug 2018 16:39:22 +0200 Subject: [PATCH 06/18] Do not check for file existence when serializing ActivityPub actor (#8386) When serializing an ActivityPub actor, Mastodon checks for the existence of the avatar/header files. This is not necessary, only check if avatar/header is set. https://github.com/thoughtbot/paperclip/blob/fd8bf49d3895de2904b43f95d11af0736fbd0f5b/README.md#checking-a-file-exists --- app/serializers/activitypub/actor_serializer.rb | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/app/serializers/activitypub/actor_serializer.rb b/app/serializers/activitypub/actor_serializer.rb index 41c9aa44e..5054bd683 100644 --- a/app/serializers/activitypub/actor_serializer.rb +++ b/app/serializers/activitypub/actor_serializer.rb @@ -93,11 +93,11 @@ class ActivityPub::ActorSerializer < ActiveModel::Serializer end def avatar_exists? - object.avatar.exists? + object.avatar? end def header_exists? - object.header.exists? + object.header? end def manually_approves_followers From 66dbb59aa16981643e3bfa3f94d441bc3166eab3 Mon Sep 17 00:00:00 2001 From: Eugen Rochko Date: Thu, 23 Aug 2018 17:26:21 +0200 Subject: [PATCH 07/18] Add aria-label to column regions (#8390) Fix #4485 --- app/javascript/mastodon/components/column.js | 5 +- .../features/community_timeline/index.js | 2 +- .../mastodon/features/compose/index.js | 3 +- .../features/direct_timeline/index.js | 2 +- .../features/favourited_statuses/index.js | 2 +- .../features/getting_started/index.js | 3 +- .../features/hashtag_timeline/index.js | 2 +- .../mastodon/features/home_timeline/index.js | 2 +- .../mastodon/features/list_timeline/index.js | 2 +- .../mastodon/features/notifications/index.js | 2 +- .../features/public_timeline/index.js | 2 +- .../standalone/community_timeline/index.js | 2 +- .../standalone/public_timeline/index.js | 2 +- .../mastodon/features/status/index.js | 3 +- .../mastodon/features/trends/index.js | 66 ------------------- 15 files changed, 19 insertions(+), 81 deletions(-) delete mode 100644 app/javascript/mastodon/features/trends/index.js diff --git a/app/javascript/mastodon/components/column.js b/app/javascript/mastodon/components/column.js index e81236d26..d45387463 100644 --- a/app/javascript/mastodon/components/column.js +++ b/app/javascript/mastodon/components/column.js @@ -7,6 +7,7 @@ export default class Column extends React.PureComponent { static propTypes = { children: PropTypes.node, + label: PropTypes.string, }; scrollTop () { @@ -40,10 +41,10 @@ export default class Column extends React.PureComponent { } render () { - const { children } = this.props; + const { label, children } = this.props; return ( -
+
{children}
); diff --git a/app/javascript/mastodon/features/community_timeline/index.js b/app/javascript/mastodon/features/community_timeline/index.js index 1cd5cf157..48d2b3f68 100644 --- a/app/javascript/mastodon/features/community_timeline/index.js +++ b/app/javascript/mastodon/features/community_timeline/index.js @@ -105,7 +105,7 @@ export default class CommunityTimeline extends React.PureComponent { const pinned = !!columnId; return ( - + ({ @@ -95,7 +96,7 @@ export default class Compose extends React.PureComponent { } return ( -
+
{header} {(multiColumn || isSearchPage) && } diff --git a/app/javascript/mastodon/features/direct_timeline/index.js b/app/javascript/mastodon/features/direct_timeline/index.js index 2181c75b6..dd289ce56 100644 --- a/app/javascript/mastodon/features/direct_timeline/index.js +++ b/app/javascript/mastodon/features/direct_timeline/index.js @@ -76,7 +76,7 @@ export default class DirectTimeline extends React.PureComponent { const pinned = !!columnId; return ( - + + ({ @@ -115,7 +116,7 @@ export default class GettingStarted extends ImmutablePureComponent { } return ( - + {multiColumn &&

- )} - /> - -
- {trends && trends.map(hashtag => )} -
- - ); - } - -} From 885711afb97b772f7c970ed16e17de799a74c923 Mon Sep 17 00:00:00 2001 From: Eugen Rochko Date: Thu, 23 Aug 2018 18:28:59 +0200 Subject: [PATCH 08/18] Fix off-by-one error in aria-posinset (#8388) Fix #8191 --- .../mastodon/components/intersection_observer_article.js | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/app/javascript/mastodon/components/intersection_observer_article.js b/app/javascript/mastodon/components/intersection_observer_article.js index e2ce9ec96..de2203a4b 100644 --- a/app/javascript/mastodon/components/intersection_observer_article.js +++ b/app/javascript/mastodon/components/intersection_observer_article.js @@ -109,7 +109,7 @@ export default class IntersectionObserverArticle extends React.Component { return (
+
{children && React.cloneElement(children, { hidden: false })}
); From 69ba8f063c43139f811a747a3c17feadd29d423a Mon Sep 17 00:00:00 2001 From: Eugen Rochko Date: Thu, 23 Aug 2018 19:11:41 +0200 Subject: [PATCH 09/18] When registrations closed, link "Sign up" to joinmastodon.org (#8395) Fix #8393 --- app/views/auth/shared/_links.html.haml | 2 +- app/views/layouts/public.html.haml | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/app/views/auth/shared/_links.html.haml b/app/views/auth/shared/_links.html.haml index 08b385092..516c625a6 100644 --- a/app/views/auth/shared/_links.html.haml +++ b/app/views/auth/shared/_links.html.haml @@ -3,7 +3,7 @@ %li= link_to t('auth.login'), new_session_path(resource_name) - if devise_mapping.registerable? && controller_name != 'registrations' - %li= link_to t('auth.register'), new_registration_path(resource_name) + %li= link_to t('auth.register'), open_registrations? ? new_registration_path(resource_name) : 'https://joinmastodon.org/#getting-started' - if devise_mapping.recoverable? && controller_name != 'passwords' && controller_name != 'registrations' %li= link_to t('auth.forgot_password'), new_password_path(resource_name) diff --git a/app/views/layouts/public.html.haml b/app/views/layouts/public.html.haml index ca9dac8bb..6bf7efb23 100644 --- a/app/views/layouts/public.html.haml +++ b/app/views/layouts/public.html.haml @@ -14,7 +14,7 @@ = link_to t('settings.back'), root_url, class: 'nav-link nav-button webapp-btn' - else = link_to t('auth.login'), new_user_session_path, class: 'webapp-btn nav-link nav-button' - = link_to t('auth.register'), new_user_registration_path, class: 'webapp-btn nav-link nav-button' + = link_to t('auth.register'), open_registrations? ? new_user_registration_path : 'https://joinmastodon.org/#getting-started', class: 'webapp-btn nav-link nav-button' .container= yield From 5b5ae018241441192f2a83284856133299f57388 Mon Sep 17 00:00:00 2001 From: Eugen Rochko Date: Thu, 23 Aug 2018 19:20:49 +0200 Subject: [PATCH 10/18] Update light theme (#8392) Fix #8209 Fix #7566 --- .../styles/mastodon-light/diff.scss | 88 +++++++++++++++++++ 1 file changed, 88 insertions(+) diff --git a/app/javascript/styles/mastodon-light/diff.scss b/app/javascript/styles/mastodon-light/diff.scss index 84ccd326e..ac161a004 100644 --- a/app/javascript/styles/mastodon-light/diff.scss +++ b/app/javascript/styles/mastodon-light/diff.scss @@ -169,6 +169,10 @@ color: $white; } +.dropdown-menu__separator { + border-bottom-color: lighten($ui-base-color, 12%); +} + // Change the background colors of modals .actions-modal, .boost-modal, @@ -281,3 +285,87 @@ } } } + +.flash-message { + box-shadow: none; + + &.notice { + background: rgba($success-green, 0.5); + color: lighten($success-green, 12%); + } + + &.alert { + background: rgba($error-red, 0.5); + color: lighten($error-red, 12%); + } +} + +.simple_form, +.table-form { + .warning { + box-shadow: none; + background: rgba($error-red, 0.5); + text-shadow: none; + } +} + +.status__content, +.reply-indicator__content { + a { + color: $highlight-text-color; + } +} + +.button.logo-button { + color: $white; + + svg path:first-child { + fill: $white; + } +} + +.public-layout { + .header, + .public-account-header, + .public-account-bio { + box-shadow: none; + } + + .header { + background: lighten($ui-base-color, 12%); + } + + .public-account-header { + &__image { + background: lighten($ui-base-color, 12%); + + &::after { + box-shadow: none; + } + } + + &__tabs { + &__name { + h1, + h1 small { + color: $white; + } + } + } + } +} + +.account__section-headline a.active::after { + border-color: transparent transparent $white; +} + +.hero-widget, +.box-widget, +.contact-widget, +.landing-page__information.contact-widget, +.moved-account-widget, +.memoriam-widget, +.activity-stream, +.nothing-here { + box-shadow: none; +} From 43b8df3228291a879170be4da84db63eeacdf144 Mon Sep 17 00:00:00 2001 From: ThibG Date: Thu, 23 Aug 2018 20:43:27 +0200 Subject: [PATCH 11/18] Update state when opened dropdown is unmounted (fixes #8397) (#8398) --- app/javascript/mastodon/components/dropdown_menu.js | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/app/javascript/mastodon/components/dropdown_menu.js b/app/javascript/mastodon/components/dropdown_menu.js index e83f724e9..a5cf6479b 100644 --- a/app/javascript/mastodon/components/dropdown_menu.js +++ b/app/javascript/mastodon/components/dropdown_menu.js @@ -226,6 +226,12 @@ export default class Dropdown extends React.PureComponent { return this.target; } + componentWillUnmount = () => { + if (this.state.id === this.props.openDropdownId) { + this.handleClose(); + } + } + render () { const { icon, items, size, title, disabled, dropdownPlacement, openDropdownId } = this.props; const open = this.state.id === openDropdownId; From 248df68c36a2f1ffd9c214afe7d1b0c62b4a5f27 Mon Sep 17 00:00:00 2001 From: Eugen Rochko Date: Thu, 23 Aug 2018 20:56:57 +0200 Subject: [PATCH 12/18] Give focused status a sensible aria-label for screen readers (#8387) * Give focused status a sensible aria-label for screen readers Fix #8192 * Use content warning in aria-label unless expanded --- app/javascript/mastodon/components/status.js | 28 ++++++++++++++++--- .../mastodon/features/status/index.js | 3 +- 2 files changed, 26 insertions(+), 5 deletions(-) diff --git a/app/javascript/mastodon/components/status.js b/app/javascript/mastodon/components/status.js index e653906f1..9a3fd3576 100644 --- a/app/javascript/mastodon/components/status.js +++ b/app/javascript/mastodon/components/status.js @@ -8,7 +8,7 @@ import DisplayName from './display_name'; import StatusContent from './status_content'; import StatusActionBar from './status_action_bar'; import AttachmentList from './attachment_list'; -import { FormattedMessage } from 'react-intl'; +import { injectIntl, FormattedMessage } from 'react-intl'; import ImmutablePureComponent from 'react-immutable-pure-component'; import { MediaGallery, Video } from '../features/ui/util/async-components'; import { HotKeys } from 'react-hotkeys'; @@ -18,6 +18,24 @@ import classNames from 'classnames'; // to use the progress bar to show download progress import Bundle from '../features/ui/components/bundle'; +export const textForScreenReader = (intl, status, rebloggedByText = false, expanded = false) => { + const displayName = status.getIn(['account', 'display_name']); + + const values = [ + displayName.length === 0 ? status.getIn(['account', 'acct']).split('@')[0] : displayName, + status.get('spoiler_text') && !expanded ? status.get('spoiler_text') : status.get('search_index').slice(status.get('spoiler_text').length), + intl.formatDate(status.get('created_at'), { hour: '2-digit', minute: '2-digit', month: 'short', day: 'numeric' }), + status.getIn(['account', 'acct']), + ]; + + if (rebloggedByText) { + values.push(rebloggedByText); + } + + return values.join(', '); +}; + +@injectIntl export default class Status extends ImmutablePureComponent { static contextTypes = { @@ -138,9 +156,9 @@ export default class Status extends ImmutablePureComponent { render () { let media = null; - let statusAvatar, prepend; + let statusAvatar, prepend, rebloggedByText; - const { hidden, featured } = this.props; + const { intl, hidden, featured } = this.props; let { status, account, ...other } = this.props; @@ -189,6 +207,8 @@ export default class Status extends ImmutablePureComponent {

); + rebloggedByText = intl.formatMessage({ id: 'status.reblogged_by', defaultMessage: '{name} boosted' }, { name: status.getIn(['account', 'acct']) }); + account = status.get('account'); status = status.get('reblog'); } @@ -248,7 +268,7 @@ export default class Status extends ImmutablePureComponent { return ( -
+
{prepend}
diff --git a/app/javascript/mastodon/features/status/index.js b/app/javascript/mastodon/features/status/index.js index 98b321dbd..45e36e3eb 100644 --- a/app/javascript/mastodon/features/status/index.js +++ b/app/javascript/mastodon/features/status/index.js @@ -43,6 +43,7 @@ import ImmutablePureComponent from 'react-immutable-pure-component'; import { HotKeys } from 'react-hotkeys'; import { boostModal, deleteModal } from '../../initial_state'; import { attachFullscreenListener, detachFullscreenListener, isFullscreen } from '../ui/util/fullscreen'; +import { textForScreenReader } from '../../components/status'; const messages = defineMessages({ deleteConfirm: { id: 'confirmations.delete.confirm', defaultMessage: 'Delete' }, @@ -418,7 +419,7 @@ export default class Status extends ImmutablePureComponent { {ancestors} -
+
Date: Thu, 23 Aug 2018 21:21:15 +0200 Subject: [PATCH 13/18] Preserve hashtag casing in web UI hashtag history (#8394) Fix #8241 --- app/javascript/mastodon/actions/compose.js | 8 ++++---- app/javascript/mastodon/reducers/compose.js | 2 +- 2 files changed, 5 insertions(+), 5 deletions(-) diff --git a/app/javascript/mastodon/actions/compose.js b/app/javascript/mastodon/actions/compose.js index fe3e831d5..6d975cd1e 100644 --- a/app/javascript/mastodon/actions/compose.js +++ b/app/javascript/mastodon/actions/compose.js @@ -130,7 +130,7 @@ export function submitCompose() { 'Idempotency-Key': getState().getIn(['compose', 'idempotencyKey']), }, }).then(function (response) { - dispatch(insertIntoTagHistory(response.data.tags)); + dispatch(insertIntoTagHistory(response.data.tags, status)); dispatch(submitComposeSuccess({ ...response.data })); // To make the app more responsive, immediately get the status into the columns @@ -390,13 +390,13 @@ export function hydrateCompose() { }; } -function insertIntoTagHistory(tags) { +function insertIntoTagHistory(recognizedTags, text) { return (dispatch, getState) => { const state = getState(); const oldHistory = state.getIn(['compose', 'tagHistory']); const me = state.getIn(['meta', 'me']); - const names = tags.map(({ name }) => name); - const intersectedOldHistory = oldHistory.filter(name => !names.includes(name)); + const names = recognizedTags.map(tag => text.match(new RegExp(`#${tag.name}`, 'i'))[0].slice(1)); + const intersectedOldHistory = oldHistory.filter(name => names.findIndex(newName => newName.toLowerCase() === name.toLowerCase()) === -1); names.push(...intersectedOldHistory.toJS()); diff --git a/app/javascript/mastodon/reducers/compose.js b/app/javascript/mastodon/reducers/compose.js index 552f659c9..67d55f66f 100644 --- a/app/javascript/mastodon/reducers/compose.js +++ b/app/javascript/mastodon/reducers/compose.js @@ -131,7 +131,7 @@ const updateSuggestionTags = (state, token) => { return state.merge({ suggestions: state.get('tagHistory') - .filter(tag => tag.startsWith(prefix)) + .filter(tag => tag.toLowerCase().startsWith(prefix.toLowerCase())) .slice(0, 4) .map(tag => '#' + tag), suggestion_token: token, From 7786e1357bbe456243679c91f88679cdd260fa8f Mon Sep 17 00:00:00 2001 From: ThibG Date: Thu, 23 Aug 2018 21:44:27 +0200 Subject: [PATCH 14/18] Only display web push notifications after API call (fixes #7902) (#8396) * Only display web push notifications after API call (fixes #7902) * Decode then truncate instead of truncating then decoding in webpush serializer --- .../service_worker/web_push_notifications.js | 20 ++++++++++--------- .../web/notification_serializer.rb | 4 ++-- 2 files changed, 13 insertions(+), 11 deletions(-) diff --git a/app/javascript/mastodon/service_worker/web_push_notifications.js b/app/javascript/mastodon/service_worker/web_push_notifications.js index 3318bbadc..d61d916b1 100644 --- a/app/javascript/mastodon/service_worker/web_push_notifications.js +++ b/app/javascript/mastodon/service_worker/web_push_notifications.js @@ -80,15 +80,7 @@ const handlePush = (event) => { // Placeholder until more information can be loaded event.waitUntil( - notify({ - title, - body, - icon, - tag: notification_id, - timestamp: new Date(), - badge: '/badge.png', - data: { access_token, preferred_locale, url: '/web/notifications' }, - }).then(() => fetchFromApi(`/api/v1/notifications/${notification_id}`, 'get', access_token)).then(notification => { + fetchFromApi(`/api/v1/notifications/${notification_id}`, 'get', access_token).then(notification => { const options = {}; options.title = formatMessage(`notification.${notification.type}`, preferred_locale, { name: notification.account.display_name.length > 0 ? notification.account.display_name : notification.account.username }); @@ -112,6 +104,16 @@ const handlePush = (event) => { } return notify(options); + }).catch(() => { + return notify({ + title, + body, + icon, + tag: notification_id, + timestamp: new Date(), + badge: '/badge.png', + data: { access_token, preferred_locale, url: '/web/notifications' }, + }); }) ); }; diff --git a/app/serializers/web/notification_serializer.rb b/app/serializers/web/notification_serializer.rb index 43ba4d92a..ee83ec8b2 100644 --- a/app/serializers/web/notification_serializer.rb +++ b/app/serializers/web/notification_serializer.rb @@ -33,7 +33,7 @@ class Web::NotificationSerializer < ActiveModel::Serializer end def body - str = truncate(strip_tags(object.target_status&.spoiler_text&.presence || object.target_status&.text || object.from_account.note), length: 140) - HTMLEntities.new.decode(str.to_str) # Do not encode entities, since this value will not be used in HTML + str = strip_tags(object.target_status&.spoiler_text&.presence || object.target_status&.text || object.from_account.note) + truncate(HTMLEntities.new.decode(str.to_str), length: 140) # Do not encode entities, since this value will not be used in HTML end end From 9d58daac6c860b599f8c266b8bb10c6170220dd3 Mon Sep 17 00:00:00 2001 From: Eugen Rochko Date: Thu, 23 Aug 2018 21:51:56 +0200 Subject: [PATCH 15/18] Fix regression when suspending not from report (#8400) Regression from #8353 --- app/controllers/admin/suspensions_controller.rb | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/app/controllers/admin/suspensions_controller.rb b/app/controllers/admin/suspensions_controller.rb index 0c7bdad9e..f9bbf36fb 100644 --- a/app/controllers/admin/suspensions_controller.rb +++ b/app/controllers/admin/suspensions_controller.rb @@ -14,7 +14,7 @@ module Admin @suspension = Form::AdminSuspensionConfirmation.new(suspension_params) if suspension_params[:acct] == @account.acct - resolve_report! if suspension_params[:report_id] + resolve_report! if suspension_params[:report_id].present? perform_suspend! mark_reports_resolved! redirect_to admin_accounts_path From 2f34b747b3f765a37d7b23e70de42005c0b62f58 Mon Sep 17 00:00:00 2001 From: Eugen Rochko Date: Thu, 23 Aug 2018 23:26:29 +0200 Subject: [PATCH 16/18] Allow mods to disable login, improve message when login disabled (#8329) * Allow moderators to disable/enable login * Instead of rejecting login, show forbidden error when login disabled Avoid confusion because when login is rejected, the message is that the account is not activated, which is wrong. * Fix tests --- app/controllers/api/base_controller.rb | 2 ++ app/controllers/application_controller.rb | 6 +++--- app/controllers/auth/sessions_controller.rb | 2 +- app/models/user.rb | 4 ---- app/policies/user_policy.rb | 4 ++-- spec/models/user_spec.rb | 2 +- 6 files changed, 9 insertions(+), 11 deletions(-) diff --git a/app/controllers/api/base_controller.rb b/app/controllers/api/base_controller.rb index 770a69921..0b3735087 100644 --- a/app/controllers/api/base_controller.rb +++ b/app/controllers/api/base_controller.rb @@ -7,6 +7,8 @@ class Api::BaseController < ApplicationController include RateLimitHeaders skip_before_action :store_current_location + skip_before_action :check_user_permissions + protect_from_forgery with: :null_session rescue_from ActiveRecord::RecordInvalid, Mastodon::ValidationError do |e| diff --git a/app/controllers/application_controller.rb b/app/controllers/application_controller.rb index 7ddd26ec0..d266fa1bd 100644 --- a/app/controllers/application_controller.rb +++ b/app/controllers/application_controller.rb @@ -24,7 +24,7 @@ class ApplicationController < ActionController::Base rescue_from Mastodon::NotPermittedError, with: :forbidden before_action :store_current_location, except: :raise_not_found, unless: :devise_controller? - before_action :check_suspension, if: :user_signed_in? + before_action :check_user_permissions, if: :user_signed_in? def raise_not_found raise ActionController::RoutingError, "No route matches #{params[:unmatched_route]}" @@ -48,8 +48,8 @@ class ApplicationController < ActionController::Base forbidden unless current_user&.staff? end - def check_suspension - forbidden if current_user.account.suspended? + def check_user_permissions + forbidden if current_user.disabled? || current_user.account.suspended? end def after_sign_out_path_for(_resource_or_scope) diff --git a/app/controllers/auth/sessions_controller.rb b/app/controllers/auth/sessions_controller.rb index 2e721160b..62b4a6377 100644 --- a/app/controllers/auth/sessions_controller.rb +++ b/app/controllers/auth/sessions_controller.rb @@ -6,7 +6,7 @@ class Auth::SessionsController < Devise::SessionsController layout 'auth' skip_before_action :require_no_authentication, only: [:create] - skip_before_action :check_suspension, only: [:destroy] + skip_before_action :check_user_permissions, only: [:destroy] prepend_before_action :authenticate_with_two_factor, if: :two_factor_enabled?, only: [:create] before_action :set_instance_presenter, only: [:new] before_action :set_body_classes diff --git a/app/models/user.rb b/app/models/user.rb index a2cf2565f..75b7e9e7c 100644 --- a/app/models/user.rb +++ b/app/models/user.rb @@ -216,10 +216,6 @@ class User < ApplicationRecord save! end - def active_for_authentication? - super && !disabled? - end - def setting_default_privacy settings.default_privacy || (account.locked? ? 'private' : 'public') end diff --git a/app/policies/user_policy.rb b/app/policies/user_policy.rb index dabdf707a..57af5c61c 100644 --- a/app/policies/user_policy.rb +++ b/app/policies/user_policy.rb @@ -18,11 +18,11 @@ class UserPolicy < ApplicationPolicy end def enable? - admin? + staff? end def disable? - admin? && !record.admin? + staff? && !record.admin? end def promote? diff --git a/spec/models/user_spec.rb b/spec/models/user_spec.rb index 93a6c26fb..015e90edc 100644 --- a/spec/models/user_spec.rb +++ b/spec/models/user_spec.rb @@ -512,7 +512,7 @@ RSpec.describe User, type: :model do context 'when user is confirmed' do let(:confirmed_at) { Time.zone.now } - it { is_expected.to be false } + it { is_expected.to be true } end context 'when user is not confirmed' do From 23752639b20abd26eefb199172da9fc3ceae172e Mon Sep 17 00:00:00 2001 From: Eugen Rochko Date: Thu, 23 Aug 2018 23:30:57 +0200 Subject: [PATCH 17/18] Bump version to 2.5.0rc1 (#8356) --- lib/mastodon/version.rb | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/lib/mastodon/version.rb b/lib/mastodon/version.rb index 093485111..a490478cd 100644 --- a/lib/mastodon/version.rb +++ b/lib/mastodon/version.rb @@ -9,11 +9,11 @@ module Mastodon end def minor - 4 + 5 end def patch - 3 + 0 end def pre @@ -21,7 +21,7 @@ module Mastodon end def flags - '' + 'rc1' end def to_a From a2cabf3f4af9271d8bfdb13c1ae2b7a8b4e6fb88 Mon Sep 17 00:00:00 2001 From: Eugen Rochko Date: Fri, 24 Aug 2018 04:33:27 +0200 Subject: [PATCH 18/18] Add admin custom CSS setting (#8399) Fix #3894 --- app/controllers/admin/settings_controller.rb | 1 + app/controllers/custom_css_controller.rb | 10 ++++++++++ app/javascript/styles/mastodon/forms.scss | 11 +++++++++++ app/models/form/admin_settings.rb | 2 ++ app/presenters/instance_presenter.rb | 2 +- app/views/admin/settings/edit.html.haml | 2 +- app/views/layouts/application.html.haml | 3 +++ config/routes.rb | 1 + 8 files changed, 30 insertions(+), 2 deletions(-) create mode 100644 app/controllers/custom_css_controller.rb diff --git a/app/controllers/admin/settings_controller.rb b/app/controllers/admin/settings_controller.rb index 23e0444d0..7d38f76ae 100644 --- a/app/controllers/admin/settings_controller.rb +++ b/app/controllers/admin/settings_controller.rb @@ -24,6 +24,7 @@ module Admin peers_api_enabled show_known_fediverse_at_about_page preview_sensitive_media + custom_css ).freeze BOOLEAN_SETTINGS = %w( diff --git a/app/controllers/custom_css_controller.rb b/app/controllers/custom_css_controller.rb new file mode 100644 index 000000000..31e501609 --- /dev/null +++ b/app/controllers/custom_css_controller.rb @@ -0,0 +1,10 @@ +# frozen_string_literal: true + +class CustomCssController < ApplicationController + before_action :set_cache_headers + + def show + skip_session! + render plain: Setting.custom_css || '', content_type: 'text/css' + end +end diff --git a/app/javascript/styles/mastodon/forms.scss b/app/javascript/styles/mastodon/forms.scss index 020be5ad2..144b4a519 100644 --- a/app/javascript/styles/mastodon/forms.scss +++ b/app/javascript/styles/mastodon/forms.scss @@ -621,3 +621,14 @@ code { .scope-danger { color: $warning-red; } + +.form_admin_settings_site_short_description, +.form_admin_settings_site_description, +.form_admin_settings_site_extended_description, +.form_admin_settings_site_terms, +.form_admin_settings_custom_css, +.form_admin_settings_closed_registrations_message { + textarea { + font-family: 'mastodon-font-monospace', monospace; + } +} diff --git a/app/models/form/admin_settings.rb b/app/models/form/admin_settings.rb index db46cda7b..9fef7da97 100644 --- a/app/models/form/admin_settings.rb +++ b/app/models/form/admin_settings.rb @@ -42,6 +42,8 @@ class Form::AdminSettings :show_known_fediverse_at_about_page=, :preview_sensitive_media, :preview_sensitive_media=, + :custom_css, + :custom_css=, to: Setting ) end diff --git a/app/presenters/instance_presenter.rb b/app/presenters/instance_presenter.rb index 31365b646..a4e4af889 100644 --- a/app/presenters/instance_presenter.rb +++ b/app/presenters/instance_presenter.rb @@ -14,7 +14,7 @@ class InstancePresenter ) def contact_account - Account.find_local(Setting.site_contact_username) + Account.find_local(Setting.site_contact_username.gsub(/\A@/, '')) end def user_count diff --git a/app/views/admin/settings/edit.html.haml b/app/views/admin/settings/edit.html.haml index b5aa176a2..f40edc35a 100644 --- a/app/views/admin/settings/edit.html.haml +++ b/app/views/admin/settings/edit.html.haml @@ -49,7 +49,7 @@ .fields-group = f.input :site_extended_description, wrapper: :with_block_label, as: :text, label: t('admin.settings.site_description_extended.title'), hint: t('admin.settings.site_description_extended.desc_html'), input_html: { rows: 8 } = f.input :site_terms, wrapper: :with_block_label, as: :text, label: t('admin.settings.site_terms.title'), hint: t('admin.settings.site_terms.desc_html'), input_html: { rows: 8 } - + = f.input :custom_css, wrapper: :with_block_label, as: :text, input_html: { rows: 8 }, label: t('admin.settings.custom_css.title'), hint: t('admin.settings.custom_css.desc_html') %hr/ .fields-group diff --git a/app/views/layouts/application.html.haml b/app/views/layouts/application.html.haml index df898d5a2..68a903197 100755 --- a/app/views/layouts/application.html.haml +++ b/app/views/layouts/application.html.haml @@ -19,6 +19,9 @@ = javascript_pack_tag "locale_#{I18n.locale}", integrity: true, crossorigin: 'anonymous' = csrf_meta_tags + - if Setting.custom_css.present? + = stylesheet_link_tag custom_css_path, media: 'all' + = yield :header_tags - body_classes ||= @body_classes || '' diff --git a/config/routes.rb b/config/routes.rb index 80a8b7b4c..0e54157dc 100644 --- a/config/routes.rb +++ b/config/routes.rb @@ -23,6 +23,7 @@ Rails.application.routes.draw do get '.well-known/webfinger', to: 'well_known/webfinger#show', as: :webfinger get 'manifest', to: 'manifests#show', defaults: { format: 'json' } get 'intent', to: 'intents#show' + get 'custom.css', to: 'custom_css#show', as: :custom_css devise_scope :user do get '/invite/:invite_code', to: 'auth/registrations#new', as: :public_invite