From 6edd40448285c71a222f49429afe48626b78e575 Mon Sep 17 00:00:00 2001 From: Matt Jankowski Date: Wed, 19 Jul 2023 02:44:16 -0400 Subject: [PATCH 01/94] Cleanup unused portions of statuses/status partial (#26045) --- .haml-lint_todo.yml | 9 +- app/helpers/statuses_helper.rb | 27 ------ app/views/statuses/_status.html.haml | 63 +------------- config/locales/an.yml | 3 - config/locales/ar.yml | 3 - config/locales/be.yml | 3 - config/locales/bg.yml | 3 - config/locales/br.yml | 3 - config/locales/ca.yml | 3 - config/locales/ckb.yml | 3 - config/locales/co.yml | 3 - config/locales/cs.yml | 3 - config/locales/cy.yml | 3 - config/locales/da.yml | 3 - config/locales/de.yml | 3 - config/locales/el.yml | 3 - config/locales/en-GB.yml | 3 - config/locales/en.yml | 3 - config/locales/eo.yml | 3 - config/locales/es-AR.yml | 3 - config/locales/es-MX.yml | 3 - config/locales/es.yml | 3 - config/locales/et.yml | 3 - config/locales/eu.yml | 3 - config/locales/fa.yml | 3 - config/locales/fi.yml | 3 - config/locales/fo.yml | 3 - config/locales/fr-QC.yml | 3 - config/locales/fr.yml | 3 - config/locales/fy.yml | 3 - config/locales/ga.yml | 1 - config/locales/gd.yml | 3 - config/locales/gl.yml | 3 - config/locales/he.yml | 3 - config/locales/hr.yml | 1 - config/locales/hu.yml | 3 - config/locales/hy.yml | 3 - config/locales/id.yml | 3 - config/locales/io.yml | 3 - config/locales/is.yml | 3 - config/locales/it.yml | 3 - config/locales/ja.yml | 3 - config/locales/ka.yml | 3 - config/locales/kab.yml | 2 - config/locales/kk.yml | 3 - config/locales/ko.yml | 3 - config/locales/ku.yml | 3 - config/locales/lt.yml | 3 - config/locales/lv.yml | 3 - config/locales/ms.yml | 2 - config/locales/my.yml | 3 - config/locales/nl.yml | 3 - config/locales/nn.yml | 3 - config/locales/no.yml | 3 - config/locales/oc.yml | 3 - config/locales/pl.yml | 3 - config/locales/pt-BR.yml | 3 - config/locales/pt-PT.yml | 3 - config/locales/ro.yml | 3 - config/locales/ru.yml | 3 - config/locales/sc.yml | 3 - config/locales/sco.yml | 3 - config/locales/si.yml | 3 - config/locales/sk.yml | 3 - config/locales/sl.yml | 3 - config/locales/sq.yml | 3 - config/locales/sr-Latn.yml | 3 - config/locales/sr.yml | 3 - config/locales/sv.yml | 3 - config/locales/th.yml | 3 - config/locales/tr.yml | 3 - config/locales/uk.yml | 3 - config/locales/vi.yml | 3 - config/locales/zh-CN.yml | 3 - config/locales/zh-HK.yml | 3 - config/locales/zh-TW.yml | 3 - spec/helpers/statuses_helper_spec.rb | 125 --------------------------- 77 files changed, 6 insertions(+), 431 deletions(-) diff --git a/.haml-lint_todo.yml b/.haml-lint_todo.yml index 26599fcc7be47d..6cb38fcc233a34 100644 --- a/.haml-lint_todo.yml +++ b/.haml-lint_todo.yml @@ -1,13 +1,13 @@ # This configuration was generated by # `haml-lint --auto-gen-config` -# on 2023-07-18 11:56:05 -0400 using Haml-Lint version 0.48.0. +# on 2023-07-18 12:15:07 -0400 using Haml-Lint version 0.48.0. # The point is for the user to remove these configuration records # one by one as the lints are removed from the code base. # Note that changes in the inspected code, or installation of new # versions of Haml-Lint, may require this file to be generated again. linters: - # Offense count: 959 + # Offense count: 950 LineLength: enabled: false @@ -15,7 +15,7 @@ linters: UnnecessaryStringOutput: enabled: false - # Offense count: 63 + # Offense count: 62 RuboCop: enabled: false @@ -26,7 +26,7 @@ linters: - 'app/views/admin/reports/show.html.haml' - 'app/views/disputes/strikes/show.html.haml' - # Offense count: 40 + # Offense count: 32 InstanceVariables: exclude: - 'app/views/admin/reports/_actions.html.haml' @@ -38,7 +38,6 @@ linters: - 'app/views/invites/_form.html.haml' - 'app/views/relationships/_account.html.haml' - 'app/views/shared/_og.html.haml' - - 'app/views/statuses/_status.html.haml' # Offense count: 3 IdNames: diff --git a/app/helpers/statuses_helper.rb b/app/helpers/statuses_helper.rb index f1f1ea872e914e..286c53d834e03d 100644 --- a/app/helpers/statuses_helper.rb +++ b/app/helpers/statuses_helper.rb @@ -65,33 +65,6 @@ def stream_link_target embedded_view? ? '_blank' : nil end - def style_classes(status, is_predecessor, is_successor, include_threads) - classes = ['entry'] - classes << 'entry-predecessor' if is_predecessor - classes << 'entry-reblog' if status.reblog? - classes << 'entry-successor' if is_successor - classes << 'entry-center' if include_threads - classes.join(' ') - end - - def microformats_classes(status, is_direct_parent, is_direct_child) - classes = [] - classes << 'p-in-reply-to' if is_direct_parent - classes << 'p-repost-of' if status.reblog? && is_direct_parent - classes << 'p-comment' if is_direct_child - classes.join(' ') - end - - def microformats_h_class(status, is_predecessor, is_successor, include_threads) - if is_predecessor || status.reblog? || is_successor - 'h-cite' - elsif include_threads - '' - else - 'h-entry' - end - end - def fa_visibility_icon(status) case status.visibility when 'public' diff --git a/app/views/statuses/_status.html.haml b/app/views/statuses/_status.html.haml index afeb55fafda824..bf51b5ff7da3d6 100644 --- a/app/views/statuses/_status.html.haml +++ b/app/views/statuses/_status.html.haml @@ -1,61 +1,2 @@ -:ruby - pinned ||= false - include_threads ||= false - is_predecessor ||= false - is_successor ||= false - direct_reply_id ||= false - parent_id ||= false - is_direct_parent = direct_reply_id == status.id - is_direct_child = parent_id == status.in_reply_to_id - centered ||= include_threads && !is_predecessor && !is_successor - h_class = microformats_h_class(status, is_predecessor, is_successor, include_threads) - style_classes = style_classes(status, is_predecessor, is_successor, include_threads) - mf_classes = microformats_classes(status, is_direct_parent, is_direct_child) - entry_classes = "#{h_class} #{mf_classes} #{style_classes}" - -- if status.reply? && include_threads - - if @next_ancestor - .entry{ class: entry_classes } - = link_to_older ActivityPub::TagManager.instance.url_for(@next_ancestor) - - = render partial: 'statuses/status', collection: @ancestors, as: :status, locals: { is_predecessor: true, direct_reply_id: status.in_reply_to_id } - -.entry{ class: entry_classes } - - - if status.reblog? - .status__prepend - .status__prepend-icon-wrapper - %i.status__prepend-icon.fa.fa-fw.fa-retweet - %span - = link_to ActivityPub::TagManager.instance.url_for(status.account), class: 'status__display-name muted' do - %bdi - %strong.emojify= display_name(status.account, custom_emojify: true) - = t('stream_entries.reblogged') - - elsif pinned - .status__prepend - .status__prepend-icon-wrapper - %i.status__prepend-icon.fa.fa-fw.fa-thumb-tack - %span - = t('stream_entries.pinned') - - = render (centered ? 'statuses/detailed_status' : 'statuses/simple_status'), status: status.proper, hide_show_thread: is_predecessor || is_successor - -- if include_threads - - if @since_descendant_thread_id - .entry{ class: entry_classes } - = link_to_newer short_account_status_url(status.account.username, status, max_descendant_thread_id: @since_descendant_thread_id + 1) - - @descendant_threads.each do |thread| - = render partial: 'statuses/status', collection: thread[:statuses], as: :status, locals: { is_successor: true, parent_id: status.id } - - - if thread[:next_status] - .entry{ class: entry_classes } - = link_to_newer ActivityPub::TagManager.instance.url_for(thread[:next_status]) - - if @next_descendant_thread - .entry{ class: entry_classes } - = link_to_newer short_account_status_url(status.account.username, status, since_descendant_thread_id: @max_descendant_thread_id - 1) - -- if include_threads && !embedded_view? && !user_signed_in? - .entry{ class: entry_classes } - = link_to_login class: 'load-more load-gap' do - = fa_icon 'comments' - = t('statuses.sign_in_to_participate') +.entry + = render (centered ? 'statuses/detailed_status' : 'statuses/simple_status'), status: status.proper, hide_show_thread: false diff --git a/config/locales/an.yml b/config/locales/an.yml index c07eefdeb06803..d643c556b633ec 100644 --- a/config/locales/an.yml +++ b/config/locales/an.yml @@ -1488,7 +1488,6 @@ an: show_newer: Amostrar mas recients show_older: Amostrar mas antigos show_thread: Amostrar discusión - sign_in_to_participate: Rechistra-te pa participar en a conversación title: "%{name}: «%{quote}»" visibilities: direct: Directa @@ -1533,8 +1532,6 @@ an: min_reblogs: Mantener publicacions reblogueadas mas de min_reblogs_hint: No borra garra d'as publicacions que haigan estau reblogueadas mas d'este numero de vegadas. Deixa en blanco pa eliminar publicacions sin importar lo numero de reblogueos stream_entries: - pinned: Publicación fixada - reblogged: retutau sensitive_content: Conteniu sensible strikes: errors: diff --git a/config/locales/ar.yml b/config/locales/ar.yml index 062421a6fdf971..538b040203db57 100644 --- a/config/locales/ar.yml +++ b/config/locales/ar.yml @@ -1623,7 +1623,6 @@ ar: show_newer: إظهار أحدث show_older: إظهار أقدم show_thread: اعرض خيط المحادثة - sign_in_to_participate: قم بتسجيل الدخول للمشاركة في هذه المحادثة title: '%{name}: "%{quote}"' visibilities: direct: مباشرة @@ -1669,8 +1668,6 @@ ar: min_reblogs: إبقاء المشاركات المعززة أكثر من min_reblogs_hint: لن تُحذف أي من منشوراتك التي أعيد مشاركتها أكثر من هذا العدد من المرات. اتركه فارغاً لحذف المنشورات بغض النظر عن عدد إعادات المشاركة stream_entries: - pinned: منشور مثبّت - reblogged: شارَكَه sensitive_content: محتوى حساس strikes: errors: diff --git a/config/locales/be.yml b/config/locales/be.yml index ca84b0e9f9438a..712f0bacdb3e4f 100644 --- a/config/locales/be.yml +++ b/config/locales/be.yml @@ -1698,7 +1698,6 @@ be: show_newer: Паказаць навейшыя show_older: Паказаць старэйшыя show_thread: Паказаць ланцуг - sign_in_to_participate: Зарэгіструйцеся каб удзельнічаць у абмеркаванні title: '%{name}: "%{quote}"' visibilities: direct: Асабіста @@ -1744,8 +1743,6 @@ be: min_reblogs: Захаваць допісы, якія пашырылі хаця б min_reblogs_hint: Не выдаляе вашыя допісы, якія пашырыла прынамсі вызначаная колькасць людзей. Пакіньце гэтае поле пустым, каб допісы выдаляліся незалежна ад гэтай колькасці stream_entries: - pinned: Замацаваны допіс - reblogged: пашыраны sensitive_content: Далікатны змест strikes: errors: diff --git a/config/locales/bg.yml b/config/locales/bg.yml index a21af0b7eee5cd..8c530cedb1360e 100644 --- a/config/locales/bg.yml +++ b/config/locales/bg.yml @@ -1634,7 +1634,6 @@ bg: show_newer: Показване на по-нови show_older: Показване на по-стари show_thread: Показване на нишката - sign_in_to_participate: Влезте, за да участвате в разговора title: "%{name}: „%{quote}“" visibilities: direct: Директно @@ -1680,8 +1679,6 @@ bg: min_reblogs: Запазване на публикации с поне толкова споделяния min_reblogs_hint: Не се изтриват ваши публикации, споделени поне толкова пъти. Оставете празно, за да изтриете публикациите независимо от техния брой споделяния stream_entries: - pinned: Закачена публикация - reblogged: подсилено sensitive_content: Деликатно съдържание strikes: errors: diff --git a/config/locales/br.yml b/config/locales/br.yml index 0e79acbfb798fa..f1d9d11904bb53 100644 --- a/config/locales/br.yml +++ b/config/locales/br.yml @@ -502,9 +502,6 @@ br: '604800': 1 sizhunvezh '63113904': 2 vloavezh '7889238': 3 months - stream_entries: - pinned: Toud spilhennet - reblogged: en·he deus skignet themes: default: Mastodoñ (Teñval) mastodon-light: Mastodoñ (Sklaer) diff --git a/config/locales/ca.yml b/config/locales/ca.yml index 9655627e7adbd7..fc82484f42ac4c 100644 --- a/config/locales/ca.yml +++ b/config/locales/ca.yml @@ -1634,7 +1634,6 @@ ca: show_newer: Mostra els més nous show_older: Mostra els més vells show_thread: Mostra el fil - sign_in_to_participate: Inicia la sessió per participar a la conversa title: '%{name}: "%{quote}"' visibilities: direct: Directe @@ -1680,8 +1679,6 @@ ca: min_reblogs: Mantenir les publicacions impulsades més de min_reblogs_hint: No suprimeix cap de les teves publicacions que s'hagin impulsat més que aquest nombre de vegades. Deixa-ho en blanc per a suprimir les publicacions independentment del nombre d'impulsos que tinguin. stream_entries: - pinned: Publicació fixada - reblogged: ha impulsat sensitive_content: Contingut sensible strikes: errors: diff --git a/config/locales/ckb.yml b/config/locales/ckb.yml index f52ea312e0506b..ad0af9a3d0f797 100644 --- a/config/locales/ckb.yml +++ b/config/locales/ckb.yml @@ -996,7 +996,6 @@ ckb: show_newer: نوێتر پیشان بدە show_older: پیشاندانی کۆنتر show_thread: نیشاندانی ڕشتە - sign_in_to_participate: بچۆ ژوورەوە بۆ بەشداریکردن لە گفتوگۆکەدا visibilities: private: شوێنکەوتوانی تەنها private_long: تەنها بۆ شوێنکەوتوانی پیشان بدە @@ -1005,8 +1004,6 @@ ckb: unlisted: پێرست نەبووە unlisted_long: هەموو کەس دەتوانێت بیبینێت، بەڵام لە هێڵی کاتی گشتی دا نەریزراوە stream_entries: - pinned: توتی چەسپکراو - reblogged: بەهێزکردن sensitive_content: ناوەڕۆکی هەستیار tags: does_not_match_previous_name: لەگەڵ ناوی پێشوو یەک ناگرێتەوە diff --git a/config/locales/co.yml b/config/locales/co.yml index d4197debd43678..ebd7ab66499054 100644 --- a/config/locales/co.yml +++ b/config/locales/co.yml @@ -983,7 +983,6 @@ co: show_newer: Vede i più ricenti show_older: Vede i più anziani show_thread: Vede u filu - sign_in_to_participate: Cunnettatevi per participà à a cunversazione title: '%{name}: "%{quote}"' visibilities: direct: Direttu @@ -1021,8 +1020,6 @@ co: min_reblogs: Cunservà i statuti spartuti più di min_reblogs_hint: Ùn sguassa micca i vostri statuti chì anu ricevuti più chì stu numeru di spartere. Lasciate viotu per sguassà i statuti senza piglià in contu u numaru di spartere stream_entries: - pinned: Statutu puntarulatu - reblogged: hà spartutu sensitive_content: Cuntenutu sensibile tags: does_not_match_previous_name: ùn currisponde micca à l'anzianu nome diff --git a/config/locales/cs.yml b/config/locales/cs.yml index 74bf33b0d332f2..b32a0c69f2a628 100644 --- a/config/locales/cs.yml +++ b/config/locales/cs.yml @@ -1642,7 +1642,6 @@ cs: show_newer: Zobrazit novější show_older: Zobrazit starší show_thread: Zobrazit vlákno - sign_in_to_participate: Chcete-li se zúčastnit této konverzace, přihlaste se title: "%{name}: „%{quote}“" visibilities: direct: Přímé @@ -1688,8 +1687,6 @@ cs: min_reblogs: Zachovat příspěvky boostnuté alespoň min_reblogs_hint: Nesmaže žádný z vašich příspěvků, který byl boostnut alespoň tolikrát. Ponechte prázdné pro mazání příspěvků bez ohledu na počet jejich boostnutí stream_entries: - pinned: Připnutý příspěvek - reblogged: boostnul sensitive_content: Citlivý obsah strikes: errors: diff --git a/config/locales/cy.yml b/config/locales/cy.yml index 25360a65d32cb3..be0c2737d5b8cd 100644 --- a/config/locales/cy.yml +++ b/config/locales/cy.yml @@ -1762,7 +1762,6 @@ cy: show_newer: Dangos y diweddaraf show_older: Dangos pethau hŷn show_thread: Dangos trywydd - sign_in_to_participate: Mengofnodwch i gymryd rhan yn y sgwrs title: '%{name}: "%{quote}"' visibilities: direct: Uniongyrchol @@ -1808,8 +1807,6 @@ cy: min_reblogs: Cadw postiadau wedi eu hybu o leiaf min_reblogs_hint: Nid yw'n dileu unrhyw un o'ch postiadau sydd wedi cael eu hybu o leiaf y nifer hwn o weithiau. Gadewch yn wag i ddileu postiadau waeth beth fo'u nifer o hybiadau stream_entries: - pinned: Postiad wedi'i binio - reblogged: hybwyd sensitive_content: Cynnwys sensitif strikes: errors: diff --git a/config/locales/da.yml b/config/locales/da.yml index 192a367ef1de37..da41e7ac58ab65 100644 --- a/config/locales/da.yml +++ b/config/locales/da.yml @@ -1634,7 +1634,6 @@ da: show_newer: Vis nyere show_older: Vis ældre show_thread: Vis tråd - sign_in_to_participate: Log ind for at deltage i konversationen title: '%{name}: "%{quote}"' visibilities: direct: Direkte @@ -1680,8 +1679,6 @@ da: min_reblogs: Behold indlæg boostet mindst min_reblogs_hint: Sletter ingen egne indlæg, som er boostet flere end dette antal gange. Lad stå tomt for at ignorere denne tærskel under sletning stream_entries: - pinned: Fastgjort indlæg - reblogged: boostet sensitive_content: Sensitivt indhold strikes: errors: diff --git a/config/locales/de.yml b/config/locales/de.yml index 606607b24109f8..56dcd3da64df20 100644 --- a/config/locales/de.yml +++ b/config/locales/de.yml @@ -1634,7 +1634,6 @@ de: show_newer: Neuere anzeigen show_older: Ältere anzeigen show_thread: Thread anzeigen - sign_in_to_participate: Melde dich an, um an der Unterhaltung teilzunehmen title: "%{name}: „%{quote}“" visibilities: direct: Direktnachricht @@ -1680,8 +1679,6 @@ de: min_reblogs: Beiträge behalten, die mindestens so oft geteilt wurden min_reblogs_hint: Löscht keine Beiträge, die mindestens so oft geteilt worden sind. Lass das Feld leer, um alle Beiträge – unabhängig der Anzahl an geteilten Beiträgen – zu löschen stream_entries: - pinned: Angehefteter Beitrag - reblogged: teilte sensitive_content: Inhaltswarnung strikes: errors: diff --git a/config/locales/el.yml b/config/locales/el.yml index 7a38c0e7b55426..024be1551ba3a4 100644 --- a/config/locales/el.yml +++ b/config/locales/el.yml @@ -1570,7 +1570,6 @@ el: show_newer: Εμφάνιση νεότερων show_older: Εμφάνιση παλαιότερων show_thread: Εμφάνιση νήματος - sign_in_to_participate: Συνδέσου για να συμμετάσχεις στη συζήτηση title: '%{name}: "%{quote}"' visibilities: direct: Άμεση @@ -1616,8 +1615,6 @@ el: min_reblogs: Διατήρηση αναρτήσεων που έχουν ενισχυθεί τουλάχιστον min_reblogs_hint: Δεν διαγράφει καμία από τις δημοσιεύσεις σας που έχει λάβει τουλάχιστον αυτόν τον αριθμό ενισχύσεων. Αφήστε κενό για να διαγράψετε δημοσιεύσεις ανεξάρτητα από τον αριθμό των ενισχύσεων stream_entries: - pinned: Καρφιτσωμένη ανάρτηση - reblogged: ενισχύθηκε sensitive_content: Ευαίσθητο περιεχόμενο strikes: errors: diff --git a/config/locales/en-GB.yml b/config/locales/en-GB.yml index b6a1003d875ef3..1f06ad078ba26f 100644 --- a/config/locales/en-GB.yml +++ b/config/locales/en-GB.yml @@ -1634,7 +1634,6 @@ en-GB: show_newer: Show newer show_older: Show older show_thread: Show thread - sign_in_to_participate: Sign in to participate in the conversation title: '%{name}: "%{quote}"' visibilities: direct: Direct @@ -1680,8 +1679,6 @@ en-GB: min_reblogs: Keep posts boosted at least min_reblogs_hint: Doesn't delete any of your posts that has been boosted at least this number of times. Leave blank to delete posts regardless of their number of boosts stream_entries: - pinned: Pinned post - reblogged: boosted sensitive_content: Sensitive content strikes: errors: diff --git a/config/locales/en.yml b/config/locales/en.yml index 83ba4b0408eb8b..526525eab06879 100644 --- a/config/locales/en.yml +++ b/config/locales/en.yml @@ -1635,7 +1635,6 @@ en: show_newer: Show newer show_older: Show older show_thread: Show thread - sign_in_to_participate: Login to participate in the conversation title: '%{name}: "%{quote}"' visibilities: direct: Direct @@ -1681,8 +1680,6 @@ en: min_reblogs: Keep posts boosted at least min_reblogs_hint: Doesn't delete any of your posts that has been boosted at least this number of times. Leave blank to delete posts regardless of their number of boosts stream_entries: - pinned: Pinned post - reblogged: boosted sensitive_content: Sensitive content strikes: errors: diff --git a/config/locales/eo.yml b/config/locales/eo.yml index 159ea141e3babe..16b688270360e8 100644 --- a/config/locales/eo.yml +++ b/config/locales/eo.yml @@ -1589,7 +1589,6 @@ eo: show_newer: Montri pli novajn show_older: Montri pli malnovajn show_thread: Montri la mesaĝaron - sign_in_to_participate: Ensalutu por partopreni la konversacion title: "%{name}: “%{quote}”" visibilities: direct: Rekta @@ -1635,8 +1634,6 @@ eo: min_reblogs: Konservi diskonitajn mesaĝojn almenau min_reblogs_hint: Oni ne forigas viajn afiŝojn kiuj estas diskonigitaj almenaŭ ĉi tiun nombron da fojoj. Lasu malplena por forigi afiŝojn sendepende de iliaj nombroj da diskonigoj stream_entries: - pinned: Fiksita afiŝo - reblogged: diskonigita sensitive_content: Tikla enhavo strikes: errors: diff --git a/config/locales/es-AR.yml b/config/locales/es-AR.yml index e4f9b47076641c..5fe0ef4f776e79 100644 --- a/config/locales/es-AR.yml +++ b/config/locales/es-AR.yml @@ -1634,7 +1634,6 @@ es-AR: show_newer: Mostrar más recientes show_older: Mostrar más antiguos show_thread: Mostrar hilo - sign_in_to_participate: Iniciá sesión para participar en la conversación title: '%{name}: "%{quote}"' visibilities: direct: Directo @@ -1680,8 +1679,6 @@ es-AR: min_reblogs: Conservar adhesiones de por lo menos min_reblogs_hint: No elimina ninguno de tus mensajes que haya recibido más de esta cantidad de adhesiones. Dejá en blanco para eliminar mensajes independientemente de su número de adhesiones. stream_entries: - pinned: Mensaje fijado - reblogged: adhirió a este mensaje sensitive_content: Contenido sensible strikes: errors: diff --git a/config/locales/es-MX.yml b/config/locales/es-MX.yml index e6d1e87ad65e05..a733189f414c8b 100644 --- a/config/locales/es-MX.yml +++ b/config/locales/es-MX.yml @@ -1634,7 +1634,6 @@ es-MX: show_newer: Mostrar más recientes show_older: Mostrar más antiguos show_thread: Mostrar discusión - sign_in_to_participate: Regístrate para participar en la conversación title: "%{name}: «%{quote}»" visibilities: direct: Directa @@ -1680,8 +1679,6 @@ es-MX: min_reblogs: Mantener publicaciones reblogueadas más de min_reblogs_hint: No borra ninguna de las publicaciones que hayan sido reblogueadas más de este número de veces. Deja en blanco para eliminar publicaciones sin importar el número de reblogueos stream_entries: - pinned: Toot fijado - reblogged: retooteado sensitive_content: Contenido sensible strikes: errors: diff --git a/config/locales/es.yml b/config/locales/es.yml index 85ce2a6cbf2e12..b9ddeaed0e3be2 100644 --- a/config/locales/es.yml +++ b/config/locales/es.yml @@ -1634,7 +1634,6 @@ es: show_newer: Mostrar más recientes show_older: Mostrar más antiguos show_thread: Mostrar discusión - sign_in_to_participate: Inicia sesión para participar en la conversación title: "%{name}: «%{quote}»" visibilities: direct: Directa @@ -1680,8 +1679,6 @@ es: min_reblogs: Mantener publicaciones reblogueadas más de min_reblogs_hint: No borra ninguna de las publicaciones que hayan sido reblogueadas más de este número de veces. Deja en blanco para eliminar publicaciones sin importar el número de reblogueos stream_entries: - pinned: Publicación fijada - reblogged: impulsó sensitive_content: Contenido sensible strikes: errors: diff --git a/config/locales/et.yml b/config/locales/et.yml index cb110b75c80f95..9d5508dcf31c20 100644 --- a/config/locales/et.yml +++ b/config/locales/et.yml @@ -1634,7 +1634,6 @@ et: show_newer: Uuemate kuvamine show_older: Vanemate kuvamine show_thread: Kuva lõim - sign_in_to_participate: Logi sisse, et liituda vestlusega title: '%{name}: "%{quote}"' visibilities: direct: Otsene @@ -1682,8 +1681,6 @@ et: min_reblogs: Säilita postitused jagatud vähemalt min_reblogs_hint: Ei kustuta postitusi, kui need on jagatud vähemalt nii mitu korda. Tühjaks jättes kustuvad postitused olenemata jagamistest stream_entries: - pinned: Kinnitatud postitus - reblogged: jagatud sensitive_content: Tundlik sisu strikes: errors: diff --git a/config/locales/eu.yml b/config/locales/eu.yml index 2b6bd17a435b91..0cf19a6636da77 100644 --- a/config/locales/eu.yml +++ b/config/locales/eu.yml @@ -1592,7 +1592,6 @@ eu: show_newer: Erakutsi berriagoak show_older: Erakutsi zaharragoak show_thread: Erakutsi haria - sign_in_to_participate: Eman izena elkarrizketan parte hartzeko title: '%{name}: "%{quote}"' visibilities: direct: Zuzena @@ -1638,8 +1637,6 @@ eu: min_reblogs: Mantendu bultzada kopuru hau duten bidalketak min_reblogs_hint: Gutxienez bultzada kopuru hau jaso duten zure bidalketak ez dira ezabatuko. Hutsik utziz gero bultzada kopurua ez da kontuan hartuko bidalketak ezabatzean stream_entries: - pinned: Finkatutako bidalketa - reblogged: "(r)en bultzada" sensitive_content: 'Kontuz: Eduki hunkigarria' strikes: errors: diff --git a/config/locales/fa.yml b/config/locales/fa.yml index c3f9cd2dbaf53a..ae7cb3cdafc47f 100644 --- a/config/locales/fa.yml +++ b/config/locales/fa.yml @@ -1403,7 +1403,6 @@ fa: show_newer: نمایش جدیدتر show_older: نمایش قدیمی‌تر show_thread: نمایش رشته - sign_in_to_participate: برای شرکت در گفتگو وارد حساب خود شوید title: "%{name}: «%{quote}»" visibilities: direct: مستقیم @@ -1449,8 +1448,6 @@ fa: min_reblogs: نگه داشتن فرسته‌هایی با تقویت بیش از min_reblogs_hint: هیچ یک از فرسته‌هایتان را که بیش از این تعداد تقویت شده باشند، حذف نمی‌کند. برای حذف فرسته‌ها فارغ از تعداد تقویت‌هایشان، خالی بگذارید stream_entries: - pinned: نوشته‌های ثابت - reblogged: تقویت شده sensitive_content: محتوای حساس strikes: errors: diff --git a/config/locales/fi.yml b/config/locales/fi.yml index 71c1b4bad85803..f9ec015c74930e 100644 --- a/config/locales/fi.yml +++ b/config/locales/fi.yml @@ -1634,7 +1634,6 @@ fi: show_newer: Näytä uudemmat show_older: Näytä vanhempi show_thread: Näytä ketju - sign_in_to_participate: Kirjaudu osallistuaksesi keskusteluun title: "%{name}: ”%{quote}”" visibilities: direct: Suoraan @@ -1680,8 +1679,6 @@ fi: min_reblogs: Pidä viestit tehostettuna vähintään min_reblogs_hint: Ei poista yhtään viestiäsi, jota on tehostettu vähintään näin monta kertaa. Jätä tyhjäksi poistaaksesi viestejä riippumatta niiden tehosteiden määrästä stream_entries: - pinned: Kiinnitetty tuuttaus - reblogged: tehosti sensitive_content: Arkaluontoista sisältöä strikes: errors: diff --git a/config/locales/fo.yml b/config/locales/fo.yml index 05a0df9155da9f..e11cc10b30899c 100644 --- a/config/locales/fo.yml +++ b/config/locales/fo.yml @@ -1634,7 +1634,6 @@ fo: show_newer: Vís nýggjari show_older: Vís eldri show_thread: Vís tráð - sign_in_to_participate: Rita inn fyri at luttaka í samrøðuni title: '%{name}: "%{quote}"' visibilities: direct: Beinleiðis @@ -1680,8 +1679,6 @@ fo: min_reblogs: Varðveit postar, sum eru stimbraðir í minsta lagi min_reblogs_hint: Strikar ikki postar hjá tær, sum eru stimbraðir í minsta lagi so ofta. Lat vera blankt, um postar skulu strikast óansæð, hvussu ofta teir eru stimbraðir stream_entries: - pinned: Festir postar - reblogged: stimbraður sensitive_content: Viðkvæmt innihald strikes: errors: diff --git a/config/locales/fr-QC.yml b/config/locales/fr-QC.yml index 2f6cb826f4ed80..056433a721df69 100644 --- a/config/locales/fr-QC.yml +++ b/config/locales/fr-QC.yml @@ -1634,7 +1634,6 @@ fr-QC: show_newer: Plus récents show_older: Plus anciens show_thread: Afficher le fil de discussion - sign_in_to_participate: Inscrivez-vous pour prendre part à la conversation title: "%{name} : « %{quote} »" visibilities: direct: Direct @@ -1680,8 +1679,6 @@ fr-QC: min_reblogs: Conserver les messages partagés au moins min_reblogs_hint: Ne supprime aucun de vos messages qui ont été partagés au moins ce nombre de fois. Laisser vide pour supprimer les messages indépendamment de leur nombre de partages stream_entries: - pinned: Message épinglé - reblogged: a partagé sensitive_content: Contenu sensible strikes: errors: diff --git a/config/locales/fr.yml b/config/locales/fr.yml index 91b977be11a482..a64d8edc04aa17 100644 --- a/config/locales/fr.yml +++ b/config/locales/fr.yml @@ -1634,7 +1634,6 @@ fr: show_newer: Plus récents show_older: Plus anciens show_thread: Afficher le fil de discussion - sign_in_to_participate: Inscrivez-vous pour prendre part à la conversation title: "%{name} : « %{quote} »" visibilities: direct: Direct @@ -1680,8 +1679,6 @@ fr: min_reblogs: Conserver les messages partagés au moins min_reblogs_hint: Ne supprime aucun de vos messages qui ont été partagés au moins ce nombre de fois. Laisser vide pour supprimer les messages indépendamment de leur nombre de partages stream_entries: - pinned: Message épinglé - reblogged: a partagé sensitive_content: Contenu sensible strikes: errors: diff --git a/config/locales/fy.yml b/config/locales/fy.yml index b9dd6e191d9cd7..77d41e09193b19 100644 --- a/config/locales/fy.yml +++ b/config/locales/fy.yml @@ -1634,7 +1634,6 @@ fy: show_newer: Nijere toane show_older: Aldere toane show_thread: Petear toane - sign_in_to_participate: Meld jo oan om oan dit petear mei te dwaan title: '%{name}: "%{quote}"' visibilities: direct: Direkt @@ -1680,8 +1679,6 @@ fy: min_reblogs: Berjochten dy’t op syn minst safolle kear boost binne behâlde min_reblogs_hint: Smyt gjin berjochten dy’t op syn minst safolle kear boost binne fuort. Lit leech om berjochten likefolle it tal boosts fuort te smiten stream_entries: - pinned: Fêstsette berjocht - reblogged: boostte sensitive_content: Gefoelige ynhâld strikes: errors: diff --git a/config/locales/ga.yml b/config/locales/ga.yml index 61dfe46f93b4bc..acb0868cf4779a 100644 --- a/config/locales/ga.yml +++ b/config/locales/ga.yml @@ -501,7 +501,6 @@ ga: '63113904': 2 bhliain '7889238': 3 mhí stream_entries: - pinned: Postáil pionnáilte sensitive_content: Ábhar íogair two_factor_authentication: edit: Cuir in eagar diff --git a/config/locales/gd.yml b/config/locales/gd.yml index c0bace8c387013..7ff820c296d528 100644 --- a/config/locales/gd.yml +++ b/config/locales/gd.yml @@ -1698,7 +1698,6 @@ gd: show_newer: Seall feadhainn as ùire show_older: Seall feadhainn as sine show_thread: Seall an snàithlean - sign_in_to_participate: Clàraich a-steach a ghabhail pàirt sa chòmhradh title: "%{name}: “%{quote}”" visibilities: direct: Dìreach @@ -1744,8 +1743,6 @@ gd: min_reblogs: Cùm na tha ’ga bhrosnachadh le co-dhiù min_reblogs_hint: Cha dèid gin dhe na postaichean agad a sguabadh às a tha ’gam brosnachadh an àireamh de thursan seo air a char as lugha. Fàg seo bàn airson postaichean a sguabadh às ge b’ e co mheud turas a tha iad ’gam brosnachadh stream_entries: - pinned: Post prìnichte - reblogged: "’ga bhrosnachadh" sensitive_content: Susbaint fhrionasach strikes: errors: diff --git a/config/locales/gl.yml b/config/locales/gl.yml index d1ae49dcb134c7..abde828b33a5fa 100644 --- a/config/locales/gl.yml +++ b/config/locales/gl.yml @@ -1634,7 +1634,6 @@ gl: show_newer: Mostrar o máis novo show_older: Mostrar o máis vello show_thread: Amosar fío - sign_in_to_participate: Accede e participa na conversa title: '%{name}: "%{quote}"' visibilities: direct: Directa @@ -1680,8 +1679,6 @@ gl: min_reblogs: Manter publicacións promovidas máis de min_reblogs_hint: Non elimina ningunha das túas publicacións se foron promovidas máis deste número de veces. Deixa en branco para eliminar publicacións independentemente do seu número de promocións stream_entries: - pinned: Publicación fixada - reblogged: promoveu sensitive_content: Contido sensible strikes: errors: diff --git a/config/locales/he.yml b/config/locales/he.yml index b51fc795e19cb1..ead8feb8f35b05 100644 --- a/config/locales/he.yml +++ b/config/locales/he.yml @@ -1698,7 +1698,6 @@ he: show_newer: הצג חדשים יותר show_older: הצג ישנים יותר show_thread: הצג שרשור - sign_in_to_participate: הכנס כדי להשתתף בשיחה title: '%{name}: "%{quote}"' visibilities: direct: ישיר @@ -1744,8 +1743,6 @@ he: min_reblogs: שמור הודעות מהודהדות לפחות min_reblogs_hint: לא מוחק מי מהודעותיך שקיבלו לפחות את המספר הזה של הדהודים. להשאיר ריק כדי למחוק הודעות ללא קשר למספר ההדהודים שקיבלו stream_entries: - pinned: הודעה נעוצה - reblogged: הודהד sensitive_content: תוכן רגיש strikes: errors: diff --git a/config/locales/hr.yml b/config/locales/hr.yml index 3b6d81ad0a8b3a..a35c8efc627058 100644 --- a/config/locales/hr.yml +++ b/config/locales/hr.yml @@ -207,7 +207,6 @@ hr: public: Javno unlisted: Neprikazano stream_entries: - reblogged: boostano sensitive_content: Osjetljivi sadržaj two_factor_authentication: disable: Onemogući 2FA diff --git a/config/locales/hu.yml b/config/locales/hu.yml index 28f7bc4a8d1733..10b5ae3d7fd987 100644 --- a/config/locales/hu.yml +++ b/config/locales/hu.yml @@ -1634,7 +1634,6 @@ hu: show_newer: Újabbak mutatása show_older: Régebbiek mutatása show_thread: Szál mutatása - sign_in_to_participate: Bejelentkezés a beszélgetésben részvételhez title: "%{name}: „%{quote}”" visibilities: direct: Közvetlen @@ -1680,8 +1679,6 @@ hu: min_reblogs: Bejegyzések megtartása, melyeket többször toltak meg, mint min_reblogs_hint: Egyetlen olyan bejegyzésedet sem törli, melyet ennél többször toltak meg. Hagyd üresen, hogy a megtolások számától függetlenül töröljük a bejegyzéseket stream_entries: - pinned: Kitűzött bejegyzés - reblogged: megtolta sensitive_content: Kényes tartalom strikes: errors: diff --git a/config/locales/hy.yml b/config/locales/hy.yml index 83f01b475123f0..b924217af59dd5 100644 --- a/config/locales/hy.yml +++ b/config/locales/hy.yml @@ -802,7 +802,6 @@ hy: show_newer: Ցուցադրել նորերը show_older: Ցուցադրել հները show_thread: Բացել շղթան - sign_in_to_participate: Մուտք գործէք՝ զրոյցին միանալու համար title: '%{name}: "%{quote}"' visibilities: direct: Հասցէագրուած @@ -824,8 +823,6 @@ hy: '63113904': 2 տարի '7889238': 3 ամիս stream_entries: - pinned: Ամրացուած գրառում - reblogged: տարածուած sensitive_content: Կասկածելի բովանդակութիւն themes: contrast: Mastodon (բարձր կոնտրաստով) diff --git a/config/locales/id.yml b/config/locales/id.yml index 437d150c3ee21e..5eb453cc9463ea 100644 --- a/config/locales/id.yml +++ b/config/locales/id.yml @@ -1448,7 +1448,6 @@ id: show_newer: Tampilkan lebih baru show_older: Tampilkan lebih lama show_thread: Tampilkan utas - sign_in_to_participate: Masuk untuk mengikuti percakapan title: '%{name}: "%{quote}"' visibilities: direct: Langsung @@ -1493,8 +1492,6 @@ id: min_reblogs: Simpan kiriman yang di-boost lebih dari min_reblogs_hint: Tidak menghapus kiriman Anda yang di-boost lebih dari sekian kali. Kosongkan bila ingin menghapus kiriman tanpa peduli jumlah boost-nya stream_entries: - pinned: Kiriman tersemat - reblogged: di-boost-kan sensitive_content: Konten sensitif strikes: errors: diff --git a/config/locales/io.yml b/config/locales/io.yml index 11cb5e15902d4c..1873fdaee56a7a 100644 --- a/config/locales/io.yml +++ b/config/locales/io.yml @@ -1437,7 +1437,6 @@ io: show_newer: Montrez plu nova kozo show_older: Montrez plu olda kozo show_thread: Montrez postaro - sign_in_to_participate: Registrez por partoprenar en konverso title: '%{name}: "%{quote}"' visibilities: direct: Direta @@ -1482,8 +1481,6 @@ io: min_reblogs: Retenez bustita posti mine min_reblogs_hint: Ne efacas irga vua posti quo bustigesos mine ca foyoquanto. Restez quale vakua por efacar posti sen suciar olia foyoquanto stream_entries: - pinned: Pinglagita posto - reblogged: diskonocigita sensitive_content: Titiliva kontenajo strikes: errors: diff --git a/config/locales/is.yml b/config/locales/is.yml index 74a4b59ab3b984..4306321e97f99d 100644 --- a/config/locales/is.yml +++ b/config/locales/is.yml @@ -1638,7 +1638,6 @@ is: show_newer: Sýna nýrri show_older: Sýna eldri show_thread: Birta þráð - sign_in_to_participate: Skráðu þig inn til að taka þátt í samtalinu title: "%{name}: „%{quote}‟" visibilities: direct: Beint @@ -1684,8 +1683,6 @@ is: min_reblogs: Halda færslum sem eru endurbirtar oftar en min_reblogs_hint: Eyðir ekki þínum eigin færslum sem endurbirtar hafa verið þetta oft. Skildu þetta eftir autt til að eyða færslum burtséð frá fjölda endurbirtinga stream_entries: - pinned: Fest færsla - reblogged: endurbirt sensitive_content: Viðkvæmt efni strikes: errors: diff --git a/config/locales/it.yml b/config/locales/it.yml index 1703b9f4deb3cb..ad73707c26305d 100644 --- a/config/locales/it.yml +++ b/config/locales/it.yml @@ -1636,7 +1636,6 @@ it: show_newer: Mostra più nuovi show_older: Mostra più vecchi show_thread: Mostra thread - sign_in_to_participate: Accedi per partecipare alla conversazione title: '%{name}: "%{quote}"' visibilities: direct: Diretto @@ -1682,8 +1681,6 @@ it: min_reblogs: Conserva i post condivisi più di min_reblogs_hint: Non cancella nessuno dei tuoi post che è stato condiviso più di questo numero di volte. Lascia vuoto per cancellare i post indipendentemente dal loro numero di condivisioni stream_entries: - pinned: Post fissato in cima - reblogged: condiviso sensitive_content: Materiale sensibile strikes: errors: diff --git a/config/locales/ja.yml b/config/locales/ja.yml index 54c146579e47c4..14a8584e70d51d 100644 --- a/config/locales/ja.yml +++ b/config/locales/ja.yml @@ -1602,7 +1602,6 @@ ja: show_newer: 新しいものを表示 show_older: 古いものを表示 show_thread: スレッドを表示 - sign_in_to_participate: ログインして会話に参加 title: '%{name}: "%{quote}"' visibilities: direct: ダイレクト @@ -1648,8 +1647,6 @@ ja: min_reblogs: ブーストの基準値 min_reblogs_hint: この数以上、ブーストされた投稿を削除せずに残します。空白にしておくと、ブーストされた数に関わらず投稿を削除します。 stream_entries: - pinned: 固定された投稿 - reblogged: さんがブースト sensitive_content: 閲覧注意 strikes: errors: diff --git a/config/locales/ka.yml b/config/locales/ka.yml index ccc80747ead5ba..59e412b90d5df3 100644 --- a/config/locales/ka.yml +++ b/config/locales/ka.yml @@ -457,7 +457,6 @@ ka: ownership: სხვისი ტუტი ვერ აიპინება reblog: ბუსტი ვერ აიპინება show_more: მეტის ჩვენება - sign_in_to_participate: საუბარში მონაწილეობისთვის გაიარეთ ავტორიზაცია visibilities: private: მხოლოდ-მიმდევრები private_long: აჩვენე მხოლოდ მიმდევრებს @@ -466,8 +465,6 @@ ka: unlisted: ჩამოუთვლელი unlisted_long: ხედავს ყველა, მაგრამ არ ჩანს საჯარო თაიმლაინებში stream_entries: - pinned: აპინული ტუტი - reblogged: გაზრდილი sensitive_content: მგრძნობიარე კონტენტი themes: contrast: მაღალი კონტრასტი diff --git a/config/locales/kab.yml b/config/locales/kab.yml index 62b07ca6060c1a..74fd7b3a84fa19 100644 --- a/config/locales/kab.yml +++ b/config/locales/kab.yml @@ -713,7 +713,6 @@ kab: show_more: Ssken-d ugar show_newer: Ssken-d timaynutin show_thread: Ssken-d lxiḍ - sign_in_to_participate: Qqen i waken ad tzeddiḍ deg udiwenni title: '%{name} : "%{quote}"' visibilities: direct: Usrid @@ -733,7 +732,6 @@ kab: '63113904': 2 n yiseggasen '7889238': 3 n wayyuren stream_entries: - pinned: Tijewwiqt yettwasentḍen sensitive_content: Agbur amḥulfu themes: contrast: Maṣṭudun (agnil awriran) diff --git a/config/locales/kk.yml b/config/locales/kk.yml index fdd284d607f7ab..a38c9407d7eb17 100644 --- a/config/locales/kk.yml +++ b/config/locales/kk.yml @@ -691,7 +691,6 @@ kk: vote: Дауыс беру show_more: Тағы әкел show_thread: Тақырыпты көрсет - sign_in_to_participate: Сұхбатқа қатысу үшін кіріңіз visibilities: private: Тек оқырмандарға private_long: Тек оқырмандарға ғана көрінеді @@ -700,8 +699,6 @@ kk: unlisted: Тізімге енбеген unlisted_long: Бәрі көре алады, бірақ ашық тізімдерге ене алмайды stream_entries: - pinned: Жабыстырылған жазба - reblogged: бөлісті sensitive_content: Нәзік мазмұн tags: does_not_match_previous_name: алдыңғы атқа сәйкес келмейді diff --git a/config/locales/ko.yml b/config/locales/ko.yml index 7263241ead8a4a..1e9b5a28e04955 100644 --- a/config/locales/ko.yml +++ b/config/locales/ko.yml @@ -1604,7 +1604,6 @@ ko: show_newer: 새로운 것 표시 show_older: 오래된 것 표시 show_thread: 글타래 보기 - sign_in_to_participate: 대화에 참여 위해 로그인 하기 title: '%{name}: "%{quote}"' visibilities: direct: 다이렉트 @@ -1650,8 +1649,6 @@ ko: min_reblogs: 해당 횟수 이상 부스트된 게시물 유지 min_reblogs_hint: 이 횟수 이상의 부스트가 된 게시물은 삭제하지 않습니다. 부스트 수와 관계없이 게시물을 지우고 싶다면 공백으로 두세요 stream_entries: - pinned: 고정된 게시물 - reblogged: 님이 부스트 했습니다 sensitive_content: 민감한 내용 strikes: errors: diff --git a/config/locales/ku.yml b/config/locales/ku.yml index cb80611d79709a..7c639c634035ab 100644 --- a/config/locales/ku.yml +++ b/config/locales/ku.yml @@ -1482,7 +1482,6 @@ ku: show_newer: Nûtirîn nîşan bide show_older: Kevntirîn nîşan bide show_thread: Mijarê nîşan bide - sign_in_to_participate: Ji bo tevlî sohbetê bibî xwe tomar bike title: "%{name}%{quote}" visibilities: direct: Rasterast @@ -1527,8 +1526,6 @@ ku: min_reblogs: Şandiyên ku bêtir hatine bilindkirin veşêre min_reblogs_hint: Şandî ku ji ji vê hejmarê bêtir bilindkirin wergirtibe nayê jêbirin. Vala bihêle da ku şandiyan jê bibî tevlî ku çiqas hezkirin wergirtibe stream_entries: - pinned: Şandiya derzîkirî - reblogged: bilindkirî sensitive_content: Naveroka hestiyarî strikes: errors: diff --git a/config/locales/lt.yml b/config/locales/lt.yml index 1c97675e9e7946..8732d3f2b9b329 100644 --- a/config/locales/lt.yml +++ b/config/locales/lt.yml @@ -458,7 +458,6 @@ lt: ownership: Kitų vartotojų toot'ai negali būti prisegti reblog: Pakeltos žinutės negali būti prisegtos show_more: Daugiau - sign_in_to_participate: Prisijunkite jeigu norite dalyvauti pokalbyje visibilities: private: Tik sekėjams private_long: Rodyti tik sekėjams @@ -467,8 +466,6 @@ lt: unlisted: Neįtrauktas į sąrašus unlisted_long: Matyti gali visi, tačiau nėra įtraukta į viešas laiko juostas stream_entries: - pinned: Prisegtas toot'as - reblogged: pakeltas sensitive_content: Jautrus turinys themes: contrast: Mastodon (Didelio Kontrasto) diff --git a/config/locales/lv.yml b/config/locales/lv.yml index b6cee2333ec8dd..a74b7d62caefb7 100644 --- a/config/locales/lv.yml +++ b/config/locales/lv.yml @@ -1625,7 +1625,6 @@ lv: show_newer: Nekad nerādīt show_older: Rādīt senākus show_thread: Rādīt tematu - sign_in_to_participate: Lai piedalītos sarunā, pieraksties title: "%{name}: “%{quote}”" visibilities: direct: Tiešs @@ -1671,8 +1670,6 @@ lv: min_reblogs: Saglabāt ziņas izceltas vismaz min_reblogs_hint: Neizdzēš nevienu no tavām ziņām, kas ir izceltas vismaz tik reižu. Atstāj tukšu, lai dzēstu ziņas neatkarīgi no to izcēlumu skaita stream_entries: - pinned: Piespraustā ziņa - reblogged: izceltie sensitive_content: Sensitīvs saturs strikes: errors: diff --git a/config/locales/ms.yml b/config/locales/ms.yml index 81b2ef31854473..e9e6c70cc447a5 100644 --- a/config/locales/ms.yml +++ b/config/locales/ms.yml @@ -942,7 +942,6 @@ ms: edited_at_html: Disunting %{date} poll: vote: Undi - sign_in_to_participate: Daftar masuk untuk menyertai perbualan visibilities: direct: Terus private: Pengikut sahaja @@ -968,7 +967,6 @@ ms: '7889238': 3 bulan min_favs: Simpan hantaran digemarkan sekurang-kurangnya stream_entries: - pinned: Hantaran disemat sensitive_content: Kandungan sensitif strikes: errors: diff --git a/config/locales/my.yml b/config/locales/my.yml index 634ba94ec2deb2..b47c1f43009f3d 100644 --- a/config/locales/my.yml +++ b/config/locales/my.yml @@ -1602,7 +1602,6 @@ my: show_newer: ပို့စ်အသစ်များပြရန် show_older: ပို့စ်အဟောင်းများပြရန် show_thread: Thread ကို ပြပါ - sign_in_to_participate: စကားဝိုင်းတွင် ပါဝင်ရန် အကောင့်ဝင်ပါ title: '%{name}: "%{quote}"' visibilities: direct: တိုက်ရိုက် @@ -1648,8 +1647,6 @@ my: min_reblogs: အနည်းဆုံးအားဖြင့် Boost လုပ်ထားသည့်ပို့စ်များကို သိမ်းဆည်းပါ min_reblogs_hint: အနည်းဆုံး ဤအကြိမ်အရေအတွက်ကို မြှင့်တင်ထားသည့် သင့်ပို့စ်များကို မဖျက်ပါ။ ၎င်းတို့၏ မြှင့်တင်မှုအရေအတွက်ကို မခွဲခြားဘဲ ပို့စ်များကို ဖျက်ရန် ချန်ထားပါ stream_entries: - pinned: ပင်တွဲထားသောပို့စ် - reblogged: Boost လုပ်ခဲ့သည် sensitive_content: သတိထားရသော အကြောင်းအရာ strikes: errors: diff --git a/config/locales/nl.yml b/config/locales/nl.yml index 78df226358c513..3c192dd3e6041d 100644 --- a/config/locales/nl.yml +++ b/config/locales/nl.yml @@ -1634,7 +1634,6 @@ nl: show_newer: Nieuwere tonen show_older: Oudere tonen show_thread: Gesprek tonen - sign_in_to_participate: Log in om deel te nemen aan het gesprek title: '%{name}: "%{quote}"' visibilities: direct: Privébericht @@ -1680,8 +1679,6 @@ nl: min_reblogs: Berichten die minstens zoveel keer zijn geboost behouden min_reblogs_hint: Verwijdert geen berichten die tenminste zoveel keer zijn geboost. Laat leeg om berichten ongeacht het aantal boosts te verwijderen stream_entries: - pinned: Vastgemaakt bericht - reblogged: boostte sensitive_content: Gevoelige inhoud strikes: errors: diff --git a/config/locales/nn.yml b/config/locales/nn.yml index a7dc4ac1d50a6e..05151bc5f7ee16 100644 --- a/config/locales/nn.yml +++ b/config/locales/nn.yml @@ -1609,7 +1609,6 @@ nn: show_newer: Vis nyere show_older: Vis eldre show_thread: Vis tråden - sign_in_to_participate: Logg inn for å verta med i samtalen title: "%{name}: «%{quote}»" visibilities: direct: Direkte @@ -1655,8 +1654,6 @@ nn: min_reblogs: Behold innlegg fremhevet av minst min_reblogs_hint: Sletter ikke noen av dine innlegg som har blitt fremhevet minst dette antall ganger. La stå tom for å slette innlegg uavhengig av antall fremhevinger stream_entries: - pinned: Festa tut - reblogged: framheva sensitive_content: Ømtolig innhald strikes: errors: diff --git a/config/locales/no.yml b/config/locales/no.yml index ea544a1b26270b..7ab60e588c800e 100644 --- a/config/locales/no.yml +++ b/config/locales/no.yml @@ -1556,7 +1556,6 @@ show_newer: Vis nyere show_older: Vis eldre show_thread: Vis tråden - sign_in_to_participate: Logg på for å delta i samtalen title: "%{name}: «%{quote}»" visibilities: direct: Direkte @@ -1602,8 +1601,6 @@ min_reblogs: Behold innlegg fremhevet av minst min_reblogs_hint: Sletter ikke noen av dine innlegg som har blitt fremhevet minst dette antall ganger. La stå tom for å slette innlegg uavhengig av antall fremhevinger stream_entries: - pinned: Festet innlegg - reblogged: fremhevet sensitive_content: Følsomt innhold strikes: errors: diff --git a/config/locales/oc.yml b/config/locales/oc.yml index 93908ca1eef93b..b8672456280e1a 100644 --- a/config/locales/oc.yml +++ b/config/locales/oc.yml @@ -890,7 +890,6 @@ oc: show_newer: Veire mai recents show_older: Veire mai ancians show_thread: Mostrar lo fil - sign_in_to_participate: Inscrivètz-vos per participar a la conversacion title: '%{name} : "%{quote}"' visibilities: direct: Dirècte @@ -933,8 +932,6 @@ oc: min_reblogs: Gardar las publicacions partejadas al mens min_reblogs_hint: Suprimís pas vòstras publicacions qu’an agut aqueste nombre de partiment. Daissar blanc per suprimir las publicacions sens far cas als partiments stream_entries: - pinned: Tut penjat - reblogged: a partejat sensitive_content: Contengut sensible tags: does_not_match_previous_name: correspond pas al nom precedent diff --git a/config/locales/pl.yml b/config/locales/pl.yml index 5bbae3efc510a4..5f4b57e296142a 100644 --- a/config/locales/pl.yml +++ b/config/locales/pl.yml @@ -1698,7 +1698,6 @@ pl: show_newer: Pokaż nowsze show_older: Pokaż starsze show_thread: Pokaż wątek - sign_in_to_participate: Zaloguj się, aby udzielić się w tej konwersacji title: '%{name}: "%{quote}"' visibilities: direct: Bezpośredni @@ -1744,8 +1743,6 @@ pl: min_reblogs: Utrzymuj posty wzmocnione więcej niż min_reblogs_hint: Nie usuwa żadnego z Twoich wpisów, które zostały wzmocnione więcej niż tyle razy. Pozostaw puste, aby usunąć posty bez względu na ich liczbę wzmocnień stream_entries: - pinned: Przypięty wpis - reblogged: podbił sensitive_content: Wrażliwa zawartość strikes: errors: diff --git a/config/locales/pt-BR.yml b/config/locales/pt-BR.yml index dd783aafcc3cb6..b38596cd1facd9 100644 --- a/config/locales/pt-BR.yml +++ b/config/locales/pt-BR.yml @@ -1634,7 +1634,6 @@ pt-BR: show_newer: Mostrar mais recentes show_older: Mostrar mais antigos show_thread: Mostrar conversa - sign_in_to_participate: Entre para participar dessa conversa title: '%{name}: "%{quote}"' visibilities: direct: Direto @@ -1680,8 +1679,6 @@ pt-BR: min_reblogs: Manter publicações impulsionadas por ao menos min_reblogs_hint: Não exclui publicações que receberam pelo menos esta quantidade de impulsos. Deixe em branco para excluir publicações independentemente da quantidade de impulsos stream_entries: - pinned: Toot fixado - reblogged: deu boost sensitive_content: Conteúdo sensível strikes: errors: diff --git a/config/locales/pt-PT.yml b/config/locales/pt-PT.yml index f8a5d2bff8047a..379f1ecd90de66 100644 --- a/config/locales/pt-PT.yml +++ b/config/locales/pt-PT.yml @@ -1634,7 +1634,6 @@ pt-PT: show_newer: Mostrar mais recentes show_older: Mostrar mais antigos show_thread: Mostrar conversa - sign_in_to_participate: Inicie a sessão para participar na conversa title: '%{name}: "%{quote}"' visibilities: direct: Direto @@ -1680,8 +1679,6 @@ pt-PT: min_reblogs: Manter as publicações reforçadas mais de min_reblogs_hint: Não apaga nenhuma das suas publicações que tenha sido partilhada mais do que este número de vezes. Deixe em branco para apagar as publicações, independentemente do número de partilhas stream_entries: - pinned: Publicação afixada - reblogged: reforçada sensitive_content: Conteúdo problemático strikes: errors: diff --git a/config/locales/ro.yml b/config/locales/ro.yml index 121a7d9095309b..587e7d390ccfaa 100644 --- a/config/locales/ro.yml +++ b/config/locales/ro.yml @@ -679,7 +679,6 @@ ro: vote: Votează show_more: Arată mai mult show_thread: Arată discuția - sign_in_to_participate: Conectează-te pentru a participa la conversație visibilities: private: Doar urmăritorii private_long: Arată doar urmăritorilor @@ -687,8 +686,6 @@ ro: unlisted: Nelistat unlisted_long: Toată lumea poate vedea, dar nu este listată pe fluxurile publice stream_entries: - pinned: Postare fixată - reblogged: impulsionată sensitive_content: Conținut sensibil tags: does_not_match_previous_name: nu se potrivește cu numele anterior diff --git a/config/locales/ru.yml b/config/locales/ru.yml index 75d0bc64dcdc6f..fe698c06298a7e 100644 --- a/config/locales/ru.yml +++ b/config/locales/ru.yml @@ -1674,7 +1674,6 @@ ru: show_newer: Показать более новое show_older: Показать старые show_thread: Открыть обсуждение - sign_in_to_participate: Войдите, чтобы принять участие в дискуссии title: '%{name}: "%{quote}"' visibilities: direct: Адресованный @@ -1720,8 +1719,6 @@ ru: min_reblogs: Порог продвижений min_reblogs_hint: Не удаляет ваши посты, количество продвижений которых достигло указанного выше значения. Оставьте поле пустым, чтобы удалять посты независимо от количества продвижений. stream_entries: - pinned: Закреплённый пост - reblogged: продвинул(а) sensitive_content: Содержимое деликатного характера strikes: errors: diff --git a/config/locales/sc.yml b/config/locales/sc.yml index 00142f0c4c35ea..bbbdd5d258e8c7 100644 --- a/config/locales/sc.yml +++ b/config/locales/sc.yml @@ -931,7 +931,6 @@ sc: show_newer: Ammustra is prus noos show_older: Ammustra is prus betzos show_thread: Ammustra su tema - sign_in_to_participate: Identìfica·ti pro partetzipare in s'arresonada title: '%{name}: "%{quote}"' visibilities: direct: Deretu @@ -952,8 +951,6 @@ sc: '63113904': 2 annos '7889238': 3 meses stream_entries: - pinned: Tut apicadu - reblogged: cumpartzidu sensitive_content: Cuntenutu sensìbile tags: does_not_match_previous_name: non cointzidet cun su nòmine anteriore diff --git a/config/locales/sco.yml b/config/locales/sco.yml index 09ef5c0dfdf610..4922303e121fd0 100644 --- a/config/locales/sco.yml +++ b/config/locales/sco.yml @@ -1472,7 +1472,6 @@ sco: show_newer: Shaw newer show_older: Shaw aulder show_thread: Shaw threid - sign_in_to_participate: Sign in fir tae tak pairt in the conversation title: '%{name}: "%{quote}"' visibilities: direct: Direck @@ -1517,8 +1516,6 @@ sco: min_reblogs: Keep posts heezed at least min_reblogs_hint: Disnae delete onie o yer posts thit's been heezed at least this nummer o times. Lea blank fir tae delete posts regairdless o their number o heezes stream_entries: - pinned: Preent post - reblogged: heezed sensitive_content: Sensitive content strikes: errors: diff --git a/config/locales/si.yml b/config/locales/si.yml index a8b5c44a11895f..974728a0582b51 100644 --- a/config/locales/si.yml +++ b/config/locales/si.yml @@ -1265,7 +1265,6 @@ si: show_newer: අලුත්ම පෙන්වන්න show_older: පැරණි පෙන්වන්න show_thread: නූල් පෙන්වන්න - sign_in_to_participate: සංවාදයට සහභාගී වීමට පුරන්න title: '%{name}: "%{quote}"' visibilities: direct: සෘජු @@ -1310,8 +1309,6 @@ si: min_reblogs: අඩුම තරමේ පෝස්ට් බූස්ට් කරගෙන තියාගන්න min_reblogs_hint: අඩුම තරමින් මෙම වාර ගණන වැඩි කර ඇති ඔබගේ පළ කිරීම් කිසිවක් මකා නොදමන්න. බූස්ට් ගණන නොතකා පළ කිරීම් මැකීමට හිස්ව තබන්න stream_entries: - pinned: ඇමිණූ ලිපිය - reblogged: ඉහල නැංවීය sensitive_content: සංවේදී අන්තර්ගතයකි strikes: errors: diff --git a/config/locales/sk.yml b/config/locales/sk.yml index 6b74ec50fbac5d..2838d864895589 100644 --- a/config/locales/sk.yml +++ b/config/locales/sk.yml @@ -1124,7 +1124,6 @@ sk: vote: Hlasuj show_more: Ukáž viac show_thread: Ukáž diskusné vlákno - sign_in_to_participate: Prihlás sa pre zapojenie do diskusie title: '%{name}: „%{quote}"' visibilities: private: Iba pre sledovateľov @@ -1138,8 +1137,6 @@ sk: keep_pinned_hint: Nevymaže žiadne s tvojich pripnutých príspevkov keep_self_bookmark: Ponechaj príspevky, ktoré sú záložkami stream_entries: - pinned: Pripnutý príspevok - reblogged: vyzdvihli sensitive_content: Senzitívny obsah tags: does_not_match_previous_name: nezhoduje sa s predošlým názvom diff --git a/config/locales/sl.yml b/config/locales/sl.yml index cc0197394c79e7..2f6e3551d8146a 100644 --- a/config/locales/sl.yml +++ b/config/locales/sl.yml @@ -1659,7 +1659,6 @@ sl: show_newer: Pokaži novejše show_older: Pokaži starejše show_thread: Pokaži nit - sign_in_to_participate: Prijavite se, če želite sodelovati v pogovoru title: "%{name}: »%{quote}«" visibilities: direct: Neposredno @@ -1705,8 +1704,6 @@ sl: min_reblogs: Obdrži objave izpostavljene vsaj min_reblogs_hint: Ne izbriše nobene od vaših objav, ki je bila vsaj tolikokrat podprta. Pustite prazno, če želite izbrisati objave ne glede na število izpostavitev stream_entries: - pinned: Pripeta objava - reblogged: izpostavljeno sensitive_content: Občutljiva vsebina strikes: errors: diff --git a/config/locales/sq.yml b/config/locales/sq.yml index 6655eaafdb0971..7994029c2fb566 100644 --- a/config/locales/sq.yml +++ b/config/locales/sq.yml @@ -1634,7 +1634,6 @@ sq: show_newer: Shfaq më të reja show_older: Shfaq më të vjetra show_thread: Shfaq rrjedhën - sign_in_to_participate: Bëni hyrjen, që të merrni pjesë te biseda title: '%{name}: "%{quote}"' visibilities: direct: I drejtpërdrejtë @@ -1680,8 +1679,6 @@ sq: min_reblogs: Mbaji postimet e përforcuara më shumë se min_reblogs_hint: Nuk fshihet ndonjë nga postimet tuaja që kanë marrë më shumë se sa ky numër përforcimesh. Lëreni të zbrazët për të fshirë postimet, pavarësisht të numrit të përforcimeve për to stream_entries: - pinned: Mesazh i fiksuar - reblogged: të përforcuara sensitive_content: Lëndë rezervat strikes: errors: diff --git a/config/locales/sr-Latn.yml b/config/locales/sr-Latn.yml index 4dd587d35944bb..3c055392b8f9ff 100644 --- a/config/locales/sr-Latn.yml +++ b/config/locales/sr-Latn.yml @@ -1666,7 +1666,6 @@ sr-Latn: show_newer: Nikad ne prikazuj show_older: Prikaži starije show_thread: Prikaži niz - sign_in_to_participate: Prijavite se da učestvujete u razgovoru title: "%{name}: „%{quote}”" visibilities: direct: Direktno @@ -1712,8 +1711,6 @@ sr-Latn: min_reblogs: Zadrži objave podržane barem min_reblogs_hint: Ne briše nijednu vašu objavu koja je bila podržana najmanje ovoliko puta. Ostavite prazno za brisanje objava bez obzira na njihov broj podržavanja stream_entries: - pinned: Zakačena objava - reblogged: podržano sensitive_content: Osetljiv sadržaj strikes: errors: diff --git a/config/locales/sr.yml b/config/locales/sr.yml index f2a82a479bfdef..132e9468b7dcc7 100644 --- a/config/locales/sr.yml +++ b/config/locales/sr.yml @@ -1666,7 +1666,6 @@ sr: show_newer: Никад не приказуј show_older: Прикажи старије show_thread: Прикажи низ - sign_in_to_participate: Пријавите се да учествујете у разговору title: "%{name}: „%{quote}”" visibilities: direct: Директно @@ -1712,8 +1711,6 @@ sr: min_reblogs: Задржи објаве подржане барем min_reblogs_hint: Не брише ниједну вашу објаву која је била подржана најмање оволико пута. Оставите празно за брисање објава без обзира на њихов број подржавања stream_entries: - pinned: Закачена објава - reblogged: подржано sensitive_content: Осетљив садржај strikes: errors: diff --git a/config/locales/sv.yml b/config/locales/sv.yml index 655f011c92d9ce..5836d21bfb8dcd 100644 --- a/config/locales/sv.yml +++ b/config/locales/sv.yml @@ -1570,7 +1570,6 @@ sv: show_newer: Visa nyare show_older: Visa äldre show_thread: Visa tråd - sign_in_to_participate: Logga in för att delta i konversationen title: '%{name}: "%{quote}"' visibilities: direct: Direkt @@ -1616,8 +1615,6 @@ sv: min_reblogs: Behåll boostade inlägg i minst min_reblogs_hint: Raderar inte något av dina inlägg som har blivit boostat minst detta antal gånger. Lämna tomt för att radera inlägg oavsett antal boostar stream_entries: - pinned: Fäst inlägg - reblogged: boostad sensitive_content: Känsligt innehåll strikes: errors: diff --git a/config/locales/th.yml b/config/locales/th.yml index 71a85eebfcc2d6..2ceadc9b0f9af7 100644 --- a/config/locales/th.yml +++ b/config/locales/th.yml @@ -1602,7 +1602,6 @@ th: show_newer: แสดงที่ใหม่กว่า show_older: แสดงที่เก่ากว่า show_thread: แสดงกระทู้ - sign_in_to_participate: เข้าสู่ระบบเพื่อเข้าร่วมการสนทนา title: '%{name}: "%{quote}"' visibilities: direct: โดยตรง @@ -1648,8 +1647,6 @@ th: min_reblogs: เก็บโพสต์ที่ได้รับการดันอย่างน้อย min_reblogs_hint: ไม่ลบโพสต์ใดก็ตามของคุณที่ได้รับจำนวนครั้งการดันอย่างน้อยเท่านี้ เว้นว่างไว้เพื่อลบโพสต์โดยไม่คำนึงถึงจำนวนการดันของโพสต์ stream_entries: - pinned: โพสต์ที่ปักหมุด - reblogged: ดันแล้ว sensitive_content: เนื้อหาที่ละเอียดอ่อน strikes: errors: diff --git a/config/locales/tr.yml b/config/locales/tr.yml index 1718ae6be8f5bb..71b76c89345ee4 100644 --- a/config/locales/tr.yml +++ b/config/locales/tr.yml @@ -1634,7 +1634,6 @@ tr: show_newer: Yenileri göster show_older: Eskileri göster show_thread: Konuyu göster - sign_in_to_participate: Sohbete katılmak için oturum açın title: '%{name}: "%{quote}"' visibilities: direct: Doğrudan @@ -1680,8 +1679,6 @@ tr: min_reblogs: Şundan daha fazla teşvik edilen gönderileri sakla min_reblogs_hint: Bu belirtilenden daha fazla teşvik edilen gönderilerinizin herhangi birini silmez. Teşvik sayısından bağımsız olarak gönderilerin silinmesi için burayı boş bırakın stream_entries: - pinned: Sabitlenmiş gönderi - reblogged: boostladı sensitive_content: Hassas içerik strikes: errors: diff --git a/config/locales/uk.yml b/config/locales/uk.yml index fdbd602e78f100..b0df7108feeac9 100644 --- a/config/locales/uk.yml +++ b/config/locales/uk.yml @@ -1698,7 +1698,6 @@ uk: show_newer: Показати новіші show_older: Показати давніші show_thread: Відкрити обговорення - sign_in_to_participate: Увійдіть для участі в бесіді title: '%{name}: "%{quote}"' visibilities: direct: Особисто @@ -1744,8 +1743,6 @@ uk: min_reblogs: Залишати дописи, поширені більше ніж min_reblogs_hint: Не видаляти ваших дописів, що були поширені більш ніж вказану кількість разів. Залиште порожнім, щоб видаляти дописи, попри кількість їхніх поширень stream_entries: - pinned: Закріплений допис - reblogged: поширив sensitive_content: Дражливий зміст strikes: errors: diff --git a/config/locales/vi.yml b/config/locales/vi.yml index f241c102d735bd..7a64be31ede3b3 100644 --- a/config/locales/vi.yml +++ b/config/locales/vi.yml @@ -1602,7 +1602,6 @@ vi: show_newer: Mới hơn show_older: Cũ hơn show_thread: Trích nguyên văn - sign_in_to_participate: Đăng nhập để trả lời tút này title: '%{name}: "%{quote}"' visibilities: direct: Nhắn riêng @@ -1648,8 +1647,6 @@ vi: min_reblogs: Giữ những tút đã đăng lại lâu hơn min_reblogs_hint: Những tút có lượt đăng lại nhiều hơn số này sẽ không bị xóa. Để trống nếu bạn muốn xóa hết stream_entries: - pinned: Tút đã ghim - reblogged: đăng lại sensitive_content: NSFW strikes: errors: diff --git a/config/locales/zh-CN.yml b/config/locales/zh-CN.yml index 910ec367338dcc..8f7c7a5ce65cab 100644 --- a/config/locales/zh-CN.yml +++ b/config/locales/zh-CN.yml @@ -1602,7 +1602,6 @@ zh-CN: show_newer: 显示更新内容 show_older: 显示更早内容 show_thread: 显示全部对话 - sign_in_to_participate: 登录以加入对话 title: "%{name}:“%{quote}”" visibilities: direct: 私信 @@ -1648,8 +1647,6 @@ zh-CN: min_reblogs: 保留如下嘟文:转嘟数超过 min_reblogs_hint: 转嘟数超过该阈值的的嘟文不会被删除。如果留空,则无论嘟文获得多少转嘟,都将被删除。 stream_entries: - pinned: 置顶嘟文 - reblogged: 转嘟 sensitive_content: 敏感内容 strikes: errors: diff --git a/config/locales/zh-HK.yml b/config/locales/zh-HK.yml index 354b20e0273ce9..37023eede7b7aa 100644 --- a/config/locales/zh-HK.yml +++ b/config/locales/zh-HK.yml @@ -1507,7 +1507,6 @@ zh-HK: show_newer: 顯示較新嘟文 show_older: 顯示較舊嘟文 show_thread: 顯示討論串 - sign_in_to_participate: 登入以加入討論 title: "%{name}:「%{quote}」" visibilities: direct: 私人訊息 @@ -1553,8 +1552,6 @@ zh-HK: min_reblogs: 保留超過嘟文轉嘟門檻 min_reblogs_hint: 如果您嘟文已收到超過轉嘟門檻則不會刪除。留白表示不論轉嘟數量皆刪除嘟文。 stream_entries: - pinned: 置頂文章 - reblogged: 轉推 sensitive_content: 敏感內容 strikes: errors: diff --git a/config/locales/zh-TW.yml b/config/locales/zh-TW.yml index 0565329cf605ea..349970cd4740ed 100644 --- a/config/locales/zh-TW.yml +++ b/config/locales/zh-TW.yml @@ -1606,7 +1606,6 @@ zh-TW: show_newer: 顯示較新嘟文 show_older: 顯示較舊嘟文 show_thread: 顯示討論串 - sign_in_to_participate: 登入以加入討論 title: "%{name}:「%{quote}」" visibilities: direct: 私訊 @@ -1652,8 +1651,6 @@ zh-TW: min_reblogs: 保留超過嘟文轉嘟門檻 min_reblogs_hint: 如果您嘟文已收到超過轉嘟門檻則不會刪除。留白表示不論轉嘟數量皆刪除該嘟文。 stream_entries: - pinned: 釘選嘟文 - reblogged: 轉嘟 sensitive_content: 敏感內容 strikes: errors: diff --git a/spec/helpers/statuses_helper_spec.rb b/spec/helpers/statuses_helper_spec.rb index b7824ca6044477..c67e1f3f2b301a 100644 --- a/spec/helpers/statuses_helper_spec.rb +++ b/spec/helpers/statuses_helper_spec.rb @@ -114,129 +114,4 @@ def set_embedded_view params[:controller] = StatusesHelper::EMBEDDED_CONTROLLER params[:action] = StatusesHelper::EMBEDDED_ACTION end - - describe '#style_classes' do - it do - status = instance_double(Status, reblog?: false) - classes = helper.style_classes(status, false, false, false) - - expect(classes).to eq 'entry' - end - - it do - status = instance_double(Status, reblog?: true) - classes = helper.style_classes(status, false, false, false) - - expect(classes).to eq 'entry entry-reblog' - end - - it do - status = instance_double(Status, reblog?: false) - classes = helper.style_classes(status, true, false, false) - - expect(classes).to eq 'entry entry-predecessor' - end - - it do - status = instance_double(Status, reblog?: false) - classes = helper.style_classes(status, false, true, false) - - expect(classes).to eq 'entry entry-successor' - end - - it do - status = instance_double(Status, reblog?: false) - classes = helper.style_classes(status, false, false, true) - - expect(classes).to eq 'entry entry-center' - end - - it do - status = instance_double(Status, reblog?: true) - classes = helper.style_classes(status, true, true, true) - - expect(classes).to eq 'entry entry-predecessor entry-reblog entry-successor entry-center' - end - end - - describe '#microformats_classes' do - it do - status = instance_double(Status, reblog?: false) - classes = helper.microformats_classes(status, false, false) - - expect(classes).to eq '' - end - - it do - status = instance_double(Status, reblog?: false) - classes = helper.microformats_classes(status, true, false) - - expect(classes).to eq 'p-in-reply-to' - end - - it do - status = instance_double(Status, reblog?: false) - classes = helper.microformats_classes(status, false, true) - - expect(classes).to eq 'p-comment' - end - - it do - status = instance_double(Status, reblog?: true) - classes = helper.microformats_classes(status, true, false) - - expect(classes).to eq 'p-in-reply-to p-repost-of' - end - - it do - status = instance_double(Status, reblog?: true) - classes = helper.microformats_classes(status, true, true) - - expect(classes).to eq 'p-in-reply-to p-repost-of p-comment' - end - end - - describe '#microformats_h_class' do - it do - status = instance_double(Status, reblog?: false) - css_class = helper.microformats_h_class(status, false, false, false) - - expect(css_class).to eq 'h-entry' - end - - it do - status = instance_double(Status, reblog?: true) - css_class = helper.microformats_h_class(status, false, false, false) - - expect(css_class).to eq 'h-cite' - end - - it do - status = instance_double(Status, reblog?: false) - css_class = helper.microformats_h_class(status, true, false, false) - - expect(css_class).to eq 'h-cite' - end - - it do - status = instance_double(Status, reblog?: false) - css_class = helper.microformats_h_class(status, false, true, false) - - expect(css_class).to eq 'h-cite' - end - - it do - status = instance_double(Status, reblog?: false) - css_class = helper.microformats_h_class(status, false, false, true) - - expect(css_class).to eq '' - end - - it do - status = instance_double(Status, reblog?: true) - css_class = helper.microformats_h_class(status, true, true, true) - - expect(css_class).to eq 'h-cite' - end - end end From 4c18928a931c8dc149fa3e0bd7de8ce4f6242715 Mon Sep 17 00:00:00 2001 From: Christian Schmidt Date: Wed, 19 Jul 2023 09:02:30 +0200 Subject: [PATCH 02/94] Wrong count in response when removing favourite/reblog (#24365) Co-authored-by: Claire --- .../api/v1/statuses/favourites_controller.rb | 5 ++- .../api/v1/statuses/reblogs_controller.rb | 7 +++- app/javascript/mastodon/reducers/statuses.js | 21 ++++++++-- .../status_relationships_presenter.rb | 3 +- app/serializers/rest/status_serializer.rb | 38 +++++++++++++------ .../v1/statuses/reblogs_controller_spec.rb | 6 +++ .../api/v1/statuses/favourites_spec.rb | 12 ++++++ 7 files changed, 73 insertions(+), 19 deletions(-) diff --git a/app/controllers/api/v1/statuses/favourites_controller.rb b/app/controllers/api/v1/statuses/favourites_controller.rb index 2e21ce6a061801..f3428e3df4f710 100644 --- a/app/controllers/api/v1/statuses/favourites_controller.rb +++ b/app/controllers/api/v1/statuses/favourites_controller.rb @@ -17,13 +17,16 @@ def destroy if fav @status = fav.status + count = [@status.favourites_count - 1, 0].max UnfavouriteWorker.perform_async(current_account.id, @status.id) else @status = Status.find(params[:status_id]) + count = @status.favourites_count authorize @status, :show? end - render json: @status, serializer: REST::StatusSerializer, relationships: StatusRelationshipsPresenter.new([@status], current_account.id, favourites_map: { @status.id => false }) + relationships = StatusRelationshipsPresenter.new([@status], current_account.id, favourites_map: { @status.id => false }, attributes_map: { @status.id => { favourites_count: count } }) + render json: @status, serializer: REST::StatusSerializer, relationships: relationships rescue Mastodon::NotPermittedError not_found end diff --git a/app/controllers/api/v1/statuses/reblogs_controller.rb b/app/controllers/api/v1/statuses/reblogs_controller.rb index e3769437b78cd3..3ca623117813e7 100644 --- a/app/controllers/api/v1/statuses/reblogs_controller.rb +++ b/app/controllers/api/v1/statuses/reblogs_controller.rb @@ -24,15 +24,18 @@ def destroy if @status authorize @status, :unreblog? + @reblog = @status.reblog + count = [@reblog.reblogs_count - 1, 0].max @status.discard RemovalWorker.perform_async(@status.id) - @reblog = @status.reblog else @reblog = Status.find(params[:status_id]) + count = @reblog.reblogs_count authorize @reblog, :show? end - render json: @reblog, serializer: REST::StatusSerializer, relationships: StatusRelationshipsPresenter.new([@status], current_account.id, reblogs_map: { @reblog.id => false }) + relationships = StatusRelationshipsPresenter.new([@status], current_account.id, reblogs_map: { @reblog.id => false }, attributes_map: { @reblog.id => { reblogs_count: count } }) + render json: @reblog, serializer: REST::StatusSerializer, relationships: relationships rescue Mastodon::NotPermittedError not_found end diff --git a/app/javascript/mastodon/reducers/statuses.js b/app/javascript/mastodon/reducers/statuses.js index 3c3d3d7114fc9d..683fe848f776cd 100644 --- a/app/javascript/mastodon/reducers/statuses.js +++ b/app/javascript/mastodon/reducers/statuses.js @@ -5,11 +5,16 @@ import { normalizeStatusTranslation } from '../actions/importer/normalizer'; import { REBLOG_REQUEST, REBLOG_FAIL, + UNREBLOG_REQUEST, + UNREBLOG_FAIL, FAVOURITE_REQUEST, FAVOURITE_FAIL, - UNFAVOURITE_SUCCESS, + UNFAVOURITE_REQUEST, + UNFAVOURITE_FAIL, BOOKMARK_REQUEST, BOOKMARK_FAIL, + UNBOOKMARK_REQUEST, + UNBOOKMARK_FAIL, } from '../actions/interactions'; import { STATUS_MUTE_SUCCESS, @@ -72,18 +77,28 @@ export default function statuses(state = initialState, action) { return importStatuses(state, action.statuses); case FAVOURITE_REQUEST: return state.setIn([action.status.get('id'), 'favourited'], true); - case UNFAVOURITE_SUCCESS: - return state.updateIn([action.status.get('id'), 'favourites_count'], x => Math.max(0, x - 1)); case FAVOURITE_FAIL: return state.get(action.status.get('id')) === undefined ? state : state.setIn([action.status.get('id'), 'favourited'], false); + case UNFAVOURITE_REQUEST: + return state.setIn([action.status.get('id'), 'favourited'], false); + case UNFAVOURITE_FAIL: + return state.get(action.status.get('id')) === undefined ? state : state.setIn([action.status.get('id'), 'favourited'], true); case BOOKMARK_REQUEST: return state.get(action.status.get('id')) === undefined ? state : state.setIn([action.status.get('id'), 'bookmarked'], true); case BOOKMARK_FAIL: return state.get(action.status.get('id')) === undefined ? state : state.setIn([action.status.get('id'), 'bookmarked'], false); + case UNBOOKMARK_REQUEST: + return state.get(action.status.get('id')) === undefined ? state : state.setIn([action.status.get('id'), 'bookmarked'], false); + case UNBOOKMARK_FAIL: + return state.get(action.status.get('id')) === undefined ? state : state.setIn([action.status.get('id'), 'bookmarked'], true); case REBLOG_REQUEST: return state.setIn([action.status.get('id'), 'reblogged'], true); case REBLOG_FAIL: return state.get(action.status.get('id')) === undefined ? state : state.setIn([action.status.get('id'), 'reblogged'], false); + case UNREBLOG_REQUEST: + return state.setIn([action.status.get('id'), 'reblogged'], false); + case UNREBLOG_FAIL: + return state.get(action.status.get('id')) === undefined ? state : state.setIn([action.status.get('id'), 'reblogged'], true); case STATUS_MUTE_SUCCESS: return state.setIn([action.id, 'muted'], true); case STATUS_UNMUTE_SUCCESS: diff --git a/app/presenters/status_relationships_presenter.rb b/app/presenters/status_relationships_presenter.rb index 50d1fb31bdf048..5d53040fb25407 100644 --- a/app/presenters/status_relationships_presenter.rb +++ b/app/presenters/status_relationships_presenter.rb @@ -4,7 +4,7 @@ class StatusRelationshipsPresenter PINNABLE_VISIBILITIES = %w(public unlisted private).freeze attr_reader :reblogs_map, :favourites_map, :mutes_map, :pins_map, - :bookmarks_map, :filters_map + :bookmarks_map, :filters_map, :attributes_map def initialize(statuses, current_account_id = nil, **options) if current_account_id.nil? @@ -26,6 +26,7 @@ def initialize(statuses, current_account_id = nil, **options) @bookmarks_map = Status.bookmarks_map(status_ids, current_account_id).merge(options[:bookmarks_map] || {}) @mutes_map = Status.mutes_map(conversation_ids, current_account_id).merge(options[:mutes_map] || {}) @pins_map = Status.pins_map(pinnable_status_ids, current_account_id).merge(options[:pins_map] || {}) + @attributes_map = options[:attributes_map] || {} end end diff --git a/app/serializers/rest/status_serializer.rb b/app/serializers/rest/status_serializer.rb index e0b8f32a68f6b7..d32621541aeb8b 100644 --- a/app/serializers/rest/status_serializer.rb +++ b/app/serializers/rest/status_serializer.rb @@ -81,49 +81,57 @@ def url ActivityPub::TagManager.instance.url_for(object) end + def reblogs_count + relationships&.attributes_map&.dig(object.id, :reblogs_count) || object.reblogs_count + end + + def favourites_count + relationships&.attributes_map&.dig(object.id, :favourites_count) || object.favourites_count + end + def favourited - if instance_options && instance_options[:relationships] - instance_options[:relationships].favourites_map[object.id] || false + if relationships + relationships.favourites_map[object.id] || false else current_user.account.favourited?(object) end end def reblogged - if instance_options && instance_options[:relationships] - instance_options[:relationships].reblogs_map[object.id] || false + if relationships + relationships.reblogs_map[object.id] || false else current_user.account.reblogged?(object) end end def muted - if instance_options && instance_options[:relationships] - instance_options[:relationships].mutes_map[object.conversation_id] || false + if relationships + relationships.mutes_map[object.conversation_id] || false else current_user.account.muting_conversation?(object.conversation) end end def bookmarked - if instance_options && instance_options[:relationships] - instance_options[:relationships].bookmarks_map[object.id] || false + if relationships + relationships.bookmarks_map[object.id] || false else current_user.account.bookmarked?(object) end end def pinned - if instance_options && instance_options[:relationships] - instance_options[:relationships].pins_map[object.id] || false + if relationships + relationships.pins_map[object.id] || false else current_user.account.pinned?(object) end end def filtered - if instance_options && instance_options[:relationships] - instance_options[:relationships].filters_map[object.id] || [] + if relationships + relationships.filters_map[object.id] || [] else current_user.account.status_matches_filters(object) end @@ -144,6 +152,12 @@ def ordered_mentions object.active_mentions.to_a.sort_by(&:id) end + private + + def relationships + instance_options && instance_options[:relationships] + end + class ApplicationSerializer < ActiveModel::Serializer attributes :name, :website diff --git a/spec/controllers/api/v1/statuses/reblogs_controller_spec.rb b/spec/controllers/api/v1/statuses/reblogs_controller_spec.rb index 6eac02b232db18..16ce95dc22bc66 100644 --- a/spec/controllers/api/v1/statuses/reblogs_controller_spec.rb +++ b/spec/controllers/api/v1/statuses/reblogs_controller_spec.rb @@ -10,6 +10,12 @@ let(:token) { Fabricate(:accessible_access_token, resource_owner_id: user.id, scopes: 'write:statuses', application: app) } context 'with an oauth token' do + around do |example| + Sidekiq::Testing.fake! do + example.run + end + end + before do allow(controller).to receive(:doorkeeper_token) { token } end diff --git a/spec/requests/api/v1/statuses/favourites_spec.rb b/spec/requests/api/v1/statuses/favourites_spec.rb index 021b8806edca7d..ac5e86f297074c 100644 --- a/spec/requests/api/v1/statuses/favourites_spec.rb +++ b/spec/requests/api/v1/statuses/favourites_spec.rb @@ -77,6 +77,12 @@ let(:status) { Fabricate(:status) } + around do |example| + Sidekiq::Testing.fake! do + example.run + end + end + it_behaves_like 'forbidden for wrong scope', 'read read:favourites' context 'with public status' do @@ -88,6 +94,9 @@ subject expect(response).to have_http_status(200) + expect(user.account.favourited?(status)).to be true + + UnfavouriteWorker.drain expect(user.account.favourited?(status)).to be false end @@ -110,6 +119,9 @@ subject expect(response).to have_http_status(200) + expect(user.account.favourited?(status)).to be true + + UnfavouriteWorker.drain expect(user.account.favourited?(status)).to be false end From b848ba3867d64056945f9b4f137a6ac94597b264 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Misty=20De=20M=C3=A9o?= Date: Wed, 19 Jul 2023 00:02:49 -0700 Subject: [PATCH 03/94] Paperclip: add support for Azure blob storage (#23607) --- Gemfile | 1 + Gemfile.lock | 17 ++++++++++++++++ app/helpers/application_helper.rb | 2 +- .../initializers/content_security_policy.rb | 1 + config/initializers/paperclip.rb | 20 +++++++++++++++++++ 5 files changed, 40 insertions(+), 1 deletion(-) diff --git a/Gemfile b/Gemfile index 074697066475d7..fcd10c5f9b6294 100644 --- a/Gemfile +++ b/Gemfile @@ -18,6 +18,7 @@ gem 'aws-sdk-s3', '~> 1.123', require: false gem 'fog-core', '<= 2.4.0' gem 'fog-openstack', '~> 0.3', require: false gem 'kt-paperclip', '~> 7.2' +gem 'md-paperclip-azure', '~> 2.2', require: false gem 'blurhash', '~> 0.1' gem 'active_model_serializers', '~> 0.10' diff --git a/Gemfile.lock b/Gemfile.lock index a75746355a5bec..63a9388ee2ca5d 100644 --- a/Gemfile.lock +++ b/Gemfile.lock @@ -118,6 +118,14 @@ GEM aws-sigv4 (~> 1.6) aws-sigv4 (1.6.0) aws-eventstream (~> 1, >= 1.0.2) + azure-storage-blob (2.0.3) + azure-storage-common (~> 2.0) + nokogiri (~> 1, >= 1.10.8) + azure-storage-common (2.0.4) + faraday (~> 1.0) + faraday_middleware (~> 1.0, >= 1.0.0.rc1) + net-http-persistent (~> 4.0) + nokogiri (~> 1, >= 1.10.8) bcrypt (3.1.18) better_errors (2.10.1) erubi (>= 1.0.0) @@ -261,6 +269,8 @@ GEM faraday-patron (1.0.0) faraday-rack (1.0.0) faraday-retry (1.0.3) + faraday_middleware (1.2.0) + faraday (~> 1.0) fast_blank (1.0.1) fastimage (2.2.7) ffi (1.15.5) @@ -410,6 +420,10 @@ GEM mario-redis-lock (1.2.1) redis (>= 3.0.5) matrix (0.4.2) + md-paperclip-azure (2.2.0) + addressable (~> 2.5) + azure-storage-blob (~> 2.0.1) + hashie (~> 5.0) memory_profiler (1.0.1) method_source (1.0.0) mime-types (3.4.1) @@ -423,6 +437,8 @@ GEM multipart-post (2.3.0) net-http (0.3.2) uri + net-http-persistent (4.0.2) + connection_pool (~> 2.2) net-imap (0.3.6) date net-protocol @@ -822,6 +838,7 @@ DEPENDENCIES link_header (~> 0.0) lograge (~> 0.12) mario-redis-lock (~> 1.2) + md-paperclip-azure (~> 2.2) memory_profiler mime-types (~> 3.4.1) net-http (~> 0.3.2) diff --git a/app/helpers/application_helper.rb b/app/helpers/application_helper.rb index 281219186f8860..5f9d7e7c484c2d 100644 --- a/app/helpers/application_helper.rb +++ b/app/helpers/application_helper.rb @@ -235,6 +235,6 @@ def prerender_custom_emojis(html, custom_emojis, other_options = {}) private def storage_host_var - ENV.fetch('S3_ALIAS_HOST', nil) || ENV.fetch('S3_CLOUDFRONT_HOST', nil) + ENV.fetch('S3_ALIAS_HOST', nil) || ENV.fetch('S3_CLOUDFRONT_HOST', nil) || ENV.fetch('AZURE_ALIAS_HOST', nil) end end diff --git a/config/initializers/content_security_policy.rb b/config/initializers/content_security_policy.rb index adc9adcc3197d2..4cc9c204db3479 100644 --- a/config/initializers/content_security_policy.rb +++ b/config/initializers/content_security_policy.rb @@ -15,6 +15,7 @@ def host_to_url(str) media_host = host_to_url(ENV['S3_ALIAS_HOST']) media_host ||= host_to_url(ENV['S3_CLOUDFRONT_HOST']) +media_host ||= host_to_url(ENV['AZURE_ALIAS_HOST']) media_host ||= host_to_url(ENV['S3_HOSTNAME']) if ENV['S3_ENABLED'] == 'true' media_host ||= assets_host diff --git a/config/initializers/paperclip.rb b/config/initializers/paperclip.rb index f2da410dbe947d..12d8d69341bdd1 100644 --- a/config/initializers/paperclip.rb +++ b/config/initializers/paperclip.rb @@ -131,6 +131,26 @@ def copy_to_local_file(style, local_dest_path) fog_host: ENV['SWIFT_OBJECT_URL'], fog_public: true ) +elsif ENV['AZURE_ENABLED'] == 'true' + require 'paperclip-azure' + + Paperclip::Attachment.default_options.merge!( + storage: :azure, + azure_options: { + protocol: 'https', + }, + azure_credentials: { + storage_account_name: ENV['AZURE_STORAGE_ACCOUNT'], + storage_access_key: ENV['AZURE_STORAGE_ACCESS_KEY'], + container: ENV['AZURE_CONTAINER_NAME'], + } + ) + if ENV.has_key?('AZURE_ALIAS_HOST') + Paperclip::Attachment.default_options.merge!( + url: ':azure_alias_url', + azure_host_alias: ENV['AZURE_ALIAS_HOST'] + ) + end else Paperclip::Attachment.default_options.merge!( storage: :filesystem, From 586b1c9dca07c894af4248f59c847e7a3bf6d786 Mon Sep 17 00:00:00 2001 From: Stanislas Signoud Date: Thu, 20 Jul 2023 14:46:02 +0200 Subject: [PATCH 04/94] Fix a missing redirection on getting-started in multi column mode (#26070) --- app/javascript/mastodon/features/ui/index.jsx | 1 + 1 file changed, 1 insertion(+) diff --git a/app/javascript/mastodon/features/ui/index.jsx b/app/javascript/mastodon/features/ui/index.jsx index 420f0aa69344f2..55ccde72f5f464 100644 --- a/app/javascript/mastodon/features/ui/index.jsx +++ b/app/javascript/mastodon/features/ui/index.jsx @@ -184,6 +184,7 @@ class SwitchingColumnsArea extends PureComponent { {singleColumn ? : null} {singleColumn && pathName.startsWith('/deck/') ? : null} + {!singleColumn && pathName === '/getting-started' ? : null} From df05ece265ab699c856ec62682c920deaf449a49 Mon Sep 17 00:00:00 2001 From: Matt Jankowski Date: Thu, 20 Jul 2023 09:13:06 -0400 Subject: [PATCH 05/94] Fix haml-lint Rubocop `Style/NumericPredicate` cop (#26040) --- .haml-lint_todo.yml | 6 +++--- app/views/notification_mailer/_status.html.haml | 2 +- app/views/statuses/_poll.html.haml | 2 +- 3 files changed, 5 insertions(+), 5 deletions(-) diff --git a/.haml-lint_todo.yml b/.haml-lint_todo.yml index 6cb38fcc233a34..7c476be8012e37 100644 --- a/.haml-lint_todo.yml +++ b/.haml-lint_todo.yml @@ -1,13 +1,13 @@ # This configuration was generated by # `haml-lint --auto-gen-config` -# on 2023-07-18 12:15:07 -0400 using Haml-Lint version 0.48.0. +# on 2023-07-19 06:41:20 -0400 using Haml-Lint version 0.48.0. # The point is for the user to remove these configuration records # one by one as the lints are removed from the code base. # Note that changes in the inspected code, or installation of new # versions of Haml-Lint, may require this file to be generated again. linters: - # Offense count: 950 + # Offense count: 951 LineLength: enabled: false @@ -15,7 +15,7 @@ linters: UnnecessaryStringOutput: enabled: false - # Offense count: 62 + # Offense count: 59 RuboCop: enabled: false diff --git a/app/views/notification_mailer/_status.html.haml b/app/views/notification_mailer/_status.html.haml index 4ea3d2c45e1edb..c85253ac084798 100644 --- a/app/views/notification_mailer/_status.html.haml +++ b/app/views/notification_mailer/_status.html.haml @@ -33,7 +33,7 @@ .auto-dir = status_content_format(status) - - if status.ordered_media_attachments.size > 0 + - if status.ordered_media_attachments.size.positive? %p - status.ordered_media_attachments.each do |a| - if status.local? diff --git a/app/views/statuses/_poll.html.haml b/app/views/statuses/_poll.html.haml index 21870af44602b1..b537eb48cac0b0 100644 --- a/app/views/statuses/_poll.html.haml +++ b/app/views/statuses/_poll.html.haml @@ -8,7 +8,7 @@ - poll.loaded_options.each_with_index do |option, index| %li - if show_results - - percent = total_votes_count > 0 ? 100 * option.votes_count / total_votes_count : 0 + - percent = total_votes_count.positive? ? 100 * option.votes_count / total_votes_count : 0 %label.poll__option>< %span.poll__number>< = "#{percent.round}%" From cabe1ea5609a14d80aba8068f82a721067b48380 Mon Sep 17 00:00:00 2001 From: gunchleoc Date: Thu, 20 Jul 2023 15:17:40 +0200 Subject: [PATCH 06/94] Change casing for 'Server Settings' string (#26011) --- config/locales/en.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/config/locales/en.yml b/config/locales/en.yml index 526525eab06879..9e54c2d8dd7506 100644 --- a/config/locales/en.yml +++ b/config/locales/en.yml @@ -770,7 +770,7 @@ en: approved: Approval required for sign up none: Nobody can sign up open: Anyone can sign up - title: Server Settings + title: Server settings site_uploads: delete: Delete uploaded file destroyed_msg: Site upload successfully deleted! From 285a3df56c70cc82e82b18b3c6ae471bdac7b442 Mon Sep 17 00:00:00 2001 From: Matt Jankowski Date: Thu, 20 Jul 2023 09:50:50 -0400 Subject: [PATCH 07/94] Move localized subject mailer shared example to separate file (#25889) --- spec/mailers/notification_mailer_spec.rb | 13 ------------- spec/mailers/user_mailer_spec.rb | 13 ------------- spec/support/examples/mailers.rb | 14 ++++++++++++++ 3 files changed, 14 insertions(+), 26 deletions(-) create mode 100644 spec/support/examples/mailers.rb diff --git a/spec/mailers/notification_mailer_spec.rb b/spec/mailers/notification_mailer_spec.rb index 3efb97cb1870fb..636c2d42576006 100644 --- a/spec/mailers/notification_mailer_spec.rb +++ b/spec/mailers/notification_mailer_spec.rb @@ -8,19 +8,6 @@ let(:foreign_status) { Fabricate(:status, account: sender, text: 'The body of the foreign status') } let(:own_status) { Fabricate(:status, account: receiver.account, text: 'The body of the own status') } - shared_examples 'localized subject' do |*args, **kwrest| - it 'renders subject localized for the locale of the receiver' do - locale = :de - receiver.update!(locale: locale) - expect(mail.subject).to eq I18n.t(*args, **kwrest.merge(locale: locale)) - end - - it 'renders subject localized for the default locale if the locale of the receiver is unavailable' do - receiver.update!(locale: nil) - expect(mail.subject).to eq I18n.t(*args, **kwrest.merge(locale: I18n.default_locale)) - end - end - describe 'mention' do let(:mention) { Mention.create!(account: receiver.account, status: foreign_status) } let(:notification) { Notification.create!(account: receiver.account, activity: mention) } diff --git a/spec/mailers/user_mailer_spec.rb b/spec/mailers/user_mailer_spec.rb index 3c42a2bb7a38bc..5affa66e078eab 100644 --- a/spec/mailers/user_mailer_spec.rb +++ b/spec/mailers/user_mailer_spec.rb @@ -5,19 +5,6 @@ describe UserMailer do let(:receiver) { Fabricate(:user) } - shared_examples 'localized subject' do |*args, **kwrest| - it 'renders subject localized for the locale of the receiver' do - locale = :de - receiver.update!(locale: locale) - expect(mail.subject).to eq I18n.t(*args, **kwrest.merge(locale: locale)) - end - - it 'renders subject localized for the default locale if the locale of the receiver is unavailable' do - receiver.update!(locale: nil) - expect(mail.subject).to eq I18n.t(*args, **kwrest.merge(locale: I18n.default_locale)) - end - end - describe 'confirmation_instructions' do let(:mail) { described_class.confirmation_instructions(receiver, 'spec') } diff --git a/spec/support/examples/mailers.rb b/spec/support/examples/mailers.rb new file mode 100644 index 00000000000000..213e873b4e18e7 --- /dev/null +++ b/spec/support/examples/mailers.rb @@ -0,0 +1,14 @@ +# frozen_string_literal: true + +shared_examples 'localized subject' do |*args, **kwrest| + it 'renders subject localized for the locale of the receiver' do + locale = :de + receiver.update!(locale: locale) + expect(mail.subject).to eq I18n.t(*args, **kwrest.merge(locale: locale)) + end + + it 'renders subject localized for the default locale if the locale of the receiver is unavailable' do + receiver.update!(locale: nil) + expect(mail.subject).to eq I18n.t(*args, **kwrest.merge(locale: I18n.default_locale)) + end +end From a5842df123e8950b803ddcca0e0d909e938fb05a Mon Sep 17 00:00:00 2001 From: Matt Jankowski Date: Thu, 20 Jul 2023 11:03:39 -0400 Subject: [PATCH 08/94] Fix haml-lint Rubocop `Lint/UnusedBlockArguments` cop (#26039) --- .haml-lint_todo.yml | 4 ++-- app/views/admin/reports/index.html.haml | 2 +- app/views/settings/applications/_fields.html.haml | 4 ++-- 3 files changed, 5 insertions(+), 5 deletions(-) diff --git a/.haml-lint_todo.yml b/.haml-lint_todo.yml index 7c476be8012e37..6d2aa0641f59dd 100644 --- a/.haml-lint_todo.yml +++ b/.haml-lint_todo.yml @@ -1,6 +1,6 @@ # This configuration was generated by # `haml-lint --auto-gen-config` -# on 2023-07-19 06:41:20 -0400 using Haml-Lint version 0.48.0. +# on 2023-07-20 09:47:50 -0400 using Haml-Lint version 0.48.0. # The point is for the user to remove these configuration records # one by one as the lints are removed from the code base. # Note that changes in the inspected code, or installation of new @@ -15,7 +15,7 @@ linters: UnnecessaryStringOutput: enabled: false - # Offense count: 59 + # Offense count: 57 RuboCop: enabled: false diff --git a/app/views/admin/reports/index.html.haml b/app/views/admin/reports/index.html.haml index 248718a73de4ca..e94847d674e824 100644 --- a/app/views/admin/reports/index.html.haml +++ b/app/views/admin/reports/index.html.haml @@ -27,7 +27,7 @@ %button.button= t('admin.accounts.search') = link_to t('admin.accounts.reset'), admin_reports_path, class: 'button negative' -- @reports.group_by(&:target_account_id).each do |target_account_id, reports| +- @reports.group_by(&:target_account_id).each do |_target_account_id, reports| - target_account = reports.first.target_account .report-card .report-card__profile diff --git a/app/views/settings/applications/_fields.html.haml b/app/views/settings/applications/_fields.html.haml index f4deb5b6ffefab..4f5077d83102b5 100644 --- a/app/views/settings/applications/_fields.html.haml +++ b/app/views/settings/applications/_fields.html.haml @@ -14,5 +14,5 @@ %label= t('activerecord.attributes.doorkeeper/application.scopes') %span.hint= t('simple_form.hints.defaults.scopes') - - Doorkeeper.configuration.scopes.group_by { |s| s.split(':').first }.each do |k, v| - = f.input :scopes, label: false, hint: false, collection: v.sort, wrapper: :with_block_label, include_blank: false, label_method: ->(scope) { safe_join([content_tag(:samp, scope, class: class_for_scope(scope)), content_tag(:span, t("doorkeeper.scopes.#{scope}"), class: 'hint')]) }, selected: f.object.scopes.all, required: false, as: :check_boxes, collection_wrapper_tag: 'ul', item_wrapper_tag: 'li' + - Doorkeeper.configuration.scopes.group_by { |s| s.split(':').first }.each do |_key, value| + = f.input :scopes, label: false, hint: false, collection: value.sort, wrapper: :with_block_label, include_blank: false, label_method: ->(scope) { safe_join([content_tag(:samp, scope, class: class_for_scope(scope)), content_tag(:span, t("doorkeeper.scopes.#{scope}"), class: 'hint')]) }, selected: f.object.scopes.all, required: false, as: :check_boxes, collection_wrapper_tag: 'ul', item_wrapper_tag: 'li' From 1cceb62afd809d832b0000caeff89c6117652129 Mon Sep 17 00:00:00 2001 From: Matt Jankowski Date: Thu, 20 Jul 2023 11:31:34 -0400 Subject: [PATCH 09/94] Fix `Lint/Void` cop (#25922) --- .rubocop_todo.yml | 6 ------ spec/services/resolve_account_service_spec.rb | 5 ----- 2 files changed, 11 deletions(-) diff --git a/.rubocop_todo.yml b/.rubocop_todo.yml index 960d548f0639d6..32fb99b77229be 100644 --- a/.rubocop_todo.yml +++ b/.rubocop_todo.yml @@ -127,12 +127,6 @@ Lint/UselessAssignment: - 'spec/services/resolve_url_service_spec.rb' - 'spec/views/statuses/show.html.haml_spec.rb' -# This cop supports safe autocorrection (--autocorrect). -# Configuration parameters: CheckForMethodsWithNoSideEffects. -Lint/Void: - Exclude: - - 'spec/services/resolve_account_service_spec.rb' - # Configuration parameters: AllowedMethods, AllowedPatterns, CountRepeatedAttributes. Metrics/AbcSize: Max: 150 diff --git a/spec/services/resolve_account_service_spec.rb b/spec/services/resolve_account_service_spec.rb index ed22a8147aa452..f446d0ca6da5bd 100644 --- a/spec/services/resolve_account_service_spec.rb +++ b/spec/services/resolve_account_service_spec.rb @@ -209,11 +209,6 @@ fail_occurred = false return_values = Concurrent::Array.new - # Preload classes that throw circular dependency errors in threads - Account - TagManager - DomainBlock - threads = Array.new(5) do Thread.new do true while wait_for_start From 1e3b19230a48174acf524cf1a9f5a498e220ea7d Mon Sep 17 00:00:00 2001 From: Claire Date: Thu, 20 Jul 2023 18:23:48 +0200 Subject: [PATCH 10/94] Add stricter protocol fields validation for accounts (#25937) --- app/models/account.rb | 7 +++ .../activitypub/process_account_service.rb | 2 +- spec/fabricators/account_fabricator.rb | 1 + spec/lib/account_reach_finder_spec.rb | 14 +++--- .../lib/activitypub/activity/announce_spec.rb | 4 +- spec/lib/activitypub/activity/update_spec.rb | 49 +++++++++++++------ .../activitypub/linked_data_signature_spec.rb | 2 +- spec/lib/activitypub/tag_manager_spec.rb | 2 +- spec/models/account_spec.rb | 4 +- spec/services/delete_account_service_spec.rb | 32 ++++++++++-- spec/services/resolve_url_service_spec.rb | 4 +- spec/services/suspend_account_service_spec.rb | 4 +- .../unsuspend_account_service_spec.rb | 4 +- .../distribute_poll_update_worker_spec.rb | 2 +- .../activitypub/distribution_worker_spec.rb | 4 +- .../activitypub/fetch_replies_worker_spec.rb | 2 +- .../move_distribution_worker_spec.rb | 4 +- .../status_update_distribution_worker_spec.rb | 2 +- .../update_distribution_worker_spec.rb | 2 +- 19 files changed, 96 insertions(+), 49 deletions(-) diff --git a/app/models/account.rb b/app/models/account.rb index aa2cb395db4c4f..1edc15972d5eaf 100644 --- a/app/models/account.rb +++ b/app/models/account.rb @@ -89,12 +89,19 @@ class Account < ApplicationRecord # Remote user validations, also applies to internal actors validates :username, format: { with: USERNAME_ONLY_RE }, if: -> { (!local? || actor_type == 'Application') && will_save_change_to_username? } + # Remote user validations + validates :uri, presence: true, unless: :local?, on: :create + # Local user validations validates :username, format: { with: /\A[a-z0-9_]+\z/i }, length: { maximum: 30 }, if: -> { local? && will_save_change_to_username? && actor_type != 'Application' } validates_with UnreservedUsernameValidator, if: -> { local? && will_save_change_to_username? && actor_type != 'Application' } validates :display_name, length: { maximum: 30 }, if: -> { local? && will_save_change_to_display_name? } validates :note, note_length: { maximum: 500 }, if: -> { local? && will_save_change_to_note? } validates :fields, length: { maximum: 4 }, if: -> { local? && will_save_change_to_fields? } + validates :uri, absence: true, if: :local?, on: :create + validates :inbox_url, absence: true, if: :local?, on: :create + validates :shared_inbox_url, absence: true, if: :local?, on: :create + validates :followers_url, absence: true, if: :local?, on: :create scope :remote, -> { where.not(domain: nil) } scope :local, -> { where(domain: nil) } diff --git a/app/services/activitypub/process_account_service.rb b/app/services/activitypub/process_account_service.rb index 8d49527b39f792..c116fab733d431 100644 --- a/app/services/activitypub/process_account_service.rb +++ b/app/services/activitypub/process_account_service.rb @@ -79,7 +79,7 @@ def create_account set_immediate_protocol_attributes! - @account.save + @account.save! end def update_account diff --git a/spec/fabricators/account_fabricator.rb b/spec/fabricators/account_fabricator.rb index 6ffbba5849aab7..534b8ae843ddd0 100644 --- a/spec/fabricators/account_fabricator.rb +++ b/spec/fabricators/account_fabricator.rb @@ -13,5 +13,6 @@ suspended_at { |attrs| attrs[:suspended] ? Time.now.utc : nil } silenced_at { |attrs| attrs[:silenced] ? Time.now.utc : nil } user { |attrs| attrs[:domain].nil? ? Fabricate.build(:user, account: nil) : nil } + uri { |attrs| attrs[:domain].nil? ? '' : "https://#{attrs[:domain]}/users/#{attrs[:username]}" } discoverable true end diff --git a/spec/lib/account_reach_finder_spec.rb b/spec/lib/account_reach_finder_spec.rb index 7c6c20968f4717..e5d85656a200c4 100644 --- a/spec/lib/account_reach_finder_spec.rb +++ b/spec/lib/account_reach_finder_spec.rb @@ -5,15 +5,15 @@ RSpec.describe AccountReachFinder do let(:account) { Fabricate(:account) } - let(:ap_follower_example_com) { Fabricate(:account, protocol: :activitypub, inbox_url: 'https://example.com/inbox-1') } - let(:ap_follower_example_org) { Fabricate(:account, protocol: :activitypub, inbox_url: 'https://example.org/inbox-2') } - let(:ap_follower_with_shared) { Fabricate(:account, protocol: :activitypub, inbox_url: 'https://foo.bar/users/a/inbox', shared_inbox_url: 'https://foo.bar/inbox') } + let(:ap_follower_example_com) { Fabricate(:account, protocol: :activitypub, inbox_url: 'https://example.com/inbox-1', domain: 'example.com') } + let(:ap_follower_example_org) { Fabricate(:account, protocol: :activitypub, inbox_url: 'https://example.org/inbox-2', domain: 'example.org') } + let(:ap_follower_with_shared) { Fabricate(:account, protocol: :activitypub, inbox_url: 'https://foo.bar/users/a/inbox', domain: 'foo.bar', shared_inbox_url: 'https://foo.bar/inbox') } - let(:ap_mentioned_with_shared) { Fabricate(:account, protocol: :activitypub, inbox_url: 'https://foo.bar/users/b/inbox', shared_inbox_url: 'https://foo.bar/inbox') } - let(:ap_mentioned_example_com) { Fabricate(:account, protocol: :activitypub, inbox_url: 'https://example.com/inbox-3') } - let(:ap_mentioned_example_org) { Fabricate(:account, protocol: :activitypub, inbox_url: 'https://example.org/inbox-4') } + let(:ap_mentioned_with_shared) { Fabricate(:account, protocol: :activitypub, inbox_url: 'https://foo.bar/users/b/inbox', domain: 'foo.bar', shared_inbox_url: 'https://foo.bar/inbox') } + let(:ap_mentioned_example_com) { Fabricate(:account, protocol: :activitypub, inbox_url: 'https://example.com/inbox-3', domain: 'example.com') } + let(:ap_mentioned_example_org) { Fabricate(:account, protocol: :activitypub, inbox_url: 'https://example.org/inbox-4', domain: 'example.org') } - let(:unrelated_account) { Fabricate(:account, protocol: :activitypub, inbox_url: 'https://example.com/unrelated-inbox') } + let(:unrelated_account) { Fabricate(:account, protocol: :activitypub, inbox_url: 'https://example.com/unrelated-inbox', domain: 'example.com') } before do ap_follower_example_com.follow!(account) diff --git a/spec/lib/activitypub/activity/announce_spec.rb b/spec/lib/activitypub/activity/announce_spec.rb index 365861bcd8d78a..8ad892975d13c5 100644 --- a/spec/lib/activitypub/activity/announce_spec.rb +++ b/spec/lib/activitypub/activity/announce_spec.rb @@ -5,7 +5,7 @@ RSpec.describe ActivityPub::Activity::Announce do subject { described_class.new(json, sender) } - let(:sender) { Fabricate(:account, followers_url: 'http://example.com/followers', uri: 'https://example.com/actor') } + let(:sender) { Fabricate(:account, followers_url: 'http://example.com/followers', uri: 'https://example.com/actor', domain: 'example.com') } let(:recipient) { Fabricate(:account) } let(:status) { Fabricate(:status, account: recipient) } @@ -114,7 +114,7 @@ context 'when the sender is relayed' do subject { described_class.new(json, sender, relayed_through_actor: relay_account) } - let!(:relay_account) { Fabricate(:account, inbox_url: 'https://relay.example.com/inbox') } + let!(:relay_account) { Fabricate(:account, inbox_url: 'https://relay.example.com/inbox', domain: 'relay.example.com') } let!(:relay) { Fabricate(:relay, inbox_url: 'https://relay.example.com/inbox') } let(:object_json) { 'https://example.com/actor/hello-world' } diff --git a/spec/lib/activitypub/activity/update_spec.rb b/spec/lib/activitypub/activity/update_spec.rb index f77279c0284fd1..87e96d2d1b12cb 100644 --- a/spec/lib/activitypub/activity/update_spec.rb +++ b/spec/lib/activitypub/activity/update_spec.rb @@ -5,22 +5,38 @@ RSpec.describe ActivityPub::Activity::Update do subject { described_class.new(json, sender) } - let!(:sender) { Fabricate(:account) } - - before do - sender.update!(uri: ActivityPub::TagManager.instance.uri_for(sender)) - end + let!(:sender) { Fabricate(:account, domain: 'example.com', inbox_url: 'https://example.com/foo/inbox', outbox_url: 'https://example.com/foo/outbox') } describe '#perform' do context 'with an Actor object' do - let(:modified_sender) do - sender.tap do |modified_sender| - modified_sender.display_name = 'Totally modified now' - end - end - let(:actor_json) do - ActiveModelSerializers::SerializableResource.new(modified_sender, serializer: ActivityPub::ActorSerializer, adapter: ActivityPub::Adapter).as_json + { + '@context': [ + 'https://www.w3.org/ns/activitystreams', + 'https://w3id.org/security/v1', + { + manuallyApprovesFollowers: 'as:manuallyApprovesFollowers', + toot: 'http://joinmastodon.org/ns#', + featured: { '@id': 'toot:featured', '@type': '@id' }, + featuredTags: { '@id': 'toot:featuredTags', '@type': '@id' }, + }, + ], + id: sender.uri, + type: 'Person', + following: 'https://example.com/users/dfsdf/following', + followers: 'https://example.com/users/dfsdf/followers', + inbox: sender.inbox_url, + outbox: sender.outbox_url, + featured: 'https://example.com/users/dfsdf/featured', + featuredTags: 'https://example.com/users/dfsdf/tags', + preferredUsername: sender.username, + name: 'Totally modified now', + publicKey: { + id: "#{sender.uri}#main-key", + owner: sender.uri, + publicKeyPem: sender.public_key, + }, + } end let(:json) do @@ -28,7 +44,7 @@ '@context': 'https://www.w3.org/ns/activitystreams', id: 'foo', type: 'Update', - actor: ActivityPub::TagManager.instance.uri_for(sender), + actor: sender.uri, object: actor_json, }.with_indifferent_access end @@ -38,6 +54,7 @@ stub_request(:get, actor_json[:followers]).to_return(status: 404) stub_request(:get, actor_json[:following]).to_return(status: 404) stub_request(:get, actor_json[:featured]).to_return(status: 404) + stub_request(:get, actor_json[:featuredTags]).to_return(status: 404) subject.perform end @@ -49,17 +66,17 @@ context 'with a Question object' do let!(:at_time) { Time.now.utc } - let!(:status) { Fabricate(:status, account: sender, poll: Poll.new(account: sender, options: %w(Bar Baz), cached_tallies: [0, 0], expires_at: at_time + 5.days)) } + let!(:status) { Fabricate(:status, uri: 'https://example.com/statuses/poll', account: sender, poll: Poll.new(account: sender, options: %w(Bar Baz), cached_tallies: [0, 0], expires_at: at_time + 5.days)) } let(:json) do { '@context': 'https://www.w3.org/ns/activitystreams', id: 'foo', type: 'Update', - actor: ActivityPub::TagManager.instance.uri_for(sender), + actor: sender.uri, object: { type: 'Question', - id: ActivityPub::TagManager.instance.uri_for(status), + id: status.uri, content: 'Foo', endTime: (at_time + 5.days).iso8601, oneOf: [ diff --git a/spec/lib/activitypub/linked_data_signature_spec.rb b/spec/lib/activitypub/linked_data_signature_spec.rb index 619d6df12472b5..6a6ad1a706430a 100644 --- a/spec/lib/activitypub/linked_data_signature_spec.rb +++ b/spec/lib/activitypub/linked_data_signature_spec.rb @@ -7,7 +7,7 @@ subject { described_class.new(json) } - let!(:sender) { Fabricate(:account, uri: 'http://example.com/alice') } + let!(:sender) { Fabricate(:account, uri: 'http://example.com/alice', domain: 'example.com') } let(:raw_json) do { diff --git a/spec/lib/activitypub/tag_manager_spec.rb b/spec/lib/activitypub/tag_manager_spec.rb index 596e91e95480e6..2bff125a6ae952 100644 --- a/spec/lib/activitypub/tag_manager_spec.rb +++ b/spec/lib/activitypub/tag_manager_spec.rb @@ -139,7 +139,7 @@ end it 'returns the remote account by matching URI without fragment part' do - account = Fabricate(:account, uri: 'https://example.com/123') + account = Fabricate(:account, uri: 'https://example.com/123', domain: 'example.com') expect(subject.uri_to_resource('https://example.com/123#456', Account)).to eq account end diff --git a/spec/models/account_spec.rb b/spec/models/account_spec.rb index d473a819e7f7ae..cf593349a7aefb 100644 --- a/spec/models/account_spec.rb +++ b/spec/models/account_spec.rb @@ -963,12 +963,12 @@ context 'when is remote' do it 'does not generate keys' do key = OpenSSL::PKey::RSA.new(1024).public_key - account = described_class.create!(domain: 'remote', username: Faker::Internet.user_name(separators: ['_']), public_key: key.to_pem) + account = described_class.create!(domain: 'remote', uri: 'https://remote/actor', username: Faker::Internet.user_name(separators: ['_']), public_key: key.to_pem) expect(account.keypair.params).to eq key.params end it 'normalizes domain' do - account = described_class.create!(domain: 'にゃん', username: Faker::Internet.user_name(separators: ['_'])) + account = described_class.create!(domain: 'にゃん', uri: 'https://xn--r9j5b5b/actor', username: Faker::Internet.user_name(separators: ['_'])) expect(account.domain).to eq 'xn--r9j5b5b' end end diff --git a/spec/services/delete_account_service_spec.rb b/spec/services/delete_account_service_spec.rb index 61e5c3c9b6bb14..68ab491e4eae7c 100644 --- a/spec/services/delete_account_service_spec.rb +++ b/spec/services/delete_account_service_spec.rb @@ -65,8 +65,8 @@ stub_request(:post, 'https://bob.com/inbox').to_return(status: 201) end - let!(:remote_alice) { Fabricate(:account, inbox_url: 'https://alice.com/inbox', protocol: :activitypub) } - let!(:remote_bob) { Fabricate(:account, inbox_url: 'https://bob.com/inbox', protocol: :activitypub) } + let!(:remote_alice) { Fabricate(:account, inbox_url: 'https://alice.com/inbox', domain: 'alice.com', protocol: :activitypub) } + let!(:remote_bob) { Fabricate(:account, inbox_url: 'https://bob.com/inbox', domain: 'bob.com', protocol: :activitypub) } include_examples 'common behavior' do let!(:account) { Fabricate(:account) } @@ -87,12 +87,34 @@ end include_examples 'common behavior' do - let!(:account) { Fabricate(:account, inbox_url: 'https://bob.com/inbox', protocol: :activitypub) } + let!(:account) { Fabricate(:account, inbox_url: 'https://bob.com/inbox', protocol: :activitypub, domain: 'bob.com') } let!(:local_follower) { Fabricate(:account) } - it 'sends a reject follow to follower inboxes' do + it 'sends expected activities to followed and follower inboxes' do subject - expect(a_request(:post, account.inbox_url)).to have_been_made.once + + expect(a_request(:post, account.inbox_url).with( + body: + hash_including({ + 'type' => 'Reject', + 'object' => hash_including({ + 'type' => 'Follow', + 'actor' => account.uri, + 'object' => ActivityPub::TagManager.instance.uri_for(local_follower), + }), + }) + )).to have_been_made.once + + expect(a_request(:post, account.inbox_url).with( + body: hash_including({ + 'type' => 'Undo', + 'object' => hash_including({ + 'type' => 'Follow', + 'actor' => ActivityPub::TagManager.instance.uri_for(local_follower), + 'object' => account.uri, + }), + }) + )).to have_been_made.once end end end diff --git a/spec/services/resolve_url_service_spec.rb b/spec/services/resolve_url_service_spec.rb index 99761b6c73aa98..7991aa6ef14383 100644 --- a/spec/services/resolve_url_service_spec.rb +++ b/spec/services/resolve_url_service_spec.rb @@ -8,7 +8,7 @@ describe '#call' do it 'returns nil when there is no resource url' do url = 'http://example.com/missing-resource' - known_account = Fabricate(:account, uri: url) + known_account = Fabricate(:account, uri: url, domain: 'example.com') service = instance_double(FetchResourceService) allow(FetchResourceService).to receive(:new).and_return service @@ -20,7 +20,7 @@ it 'returns known account on temporary error' do url = 'http://example.com/missing-resource' - known_account = Fabricate(:account, uri: url) + known_account = Fabricate(:account, uri: url, domain: 'example.com') service = instance_double(FetchResourceService) allow(FetchResourceService).to receive(:new).and_return service diff --git a/spec/services/suspend_account_service_spec.rb b/spec/services/suspend_account_service_spec.rb index f9206b7ea21a7e..7cdbc873e3e7ce 100644 --- a/spec/services/suspend_account_service_spec.rb +++ b/spec/services/suspend_account_service_spec.rb @@ -44,8 +44,8 @@ def match_update_actor_request(req, account) include_examples 'common behavior' do let!(:account) { Fabricate(:account) } - let!(:remote_follower) { Fabricate(:account, uri: 'https://alice.com', inbox_url: 'https://alice.com/inbox', protocol: :activitypub) } - let!(:remote_reporter) { Fabricate(:account, uri: 'https://bob.com', inbox_url: 'https://bob.com/inbox', protocol: :activitypub) } + let!(:remote_follower) { Fabricate(:account, uri: 'https://alice.com', inbox_url: 'https://alice.com/inbox', protocol: :activitypub, domain: 'alice.com') } + let!(:remote_reporter) { Fabricate(:account, uri: 'https://bob.com', inbox_url: 'https://bob.com/inbox', protocol: :activitypub, domain: 'bob.com') } let!(:report) { Fabricate(:report, account: remote_reporter, target_account: account) } before do diff --git a/spec/services/unsuspend_account_service_spec.rb b/spec/services/unsuspend_account_service_spec.rb index 7ef2630aeb1ab8..3c13d5bd395da4 100644 --- a/spec/services/unsuspend_account_service_spec.rb +++ b/spec/services/unsuspend_account_service_spec.rb @@ -38,8 +38,8 @@ def match_update_actor_request(req, account) include_examples 'with common context' do let!(:account) { Fabricate(:account) } - let!(:remote_follower) { Fabricate(:account, uri: 'https://alice.com', inbox_url: 'https://alice.com/inbox', protocol: :activitypub) } - let!(:remote_reporter) { Fabricate(:account, uri: 'https://bob.com', inbox_url: 'https://bob.com/inbox', protocol: :activitypub) } + let!(:remote_follower) { Fabricate(:account, uri: 'https://alice.com', inbox_url: 'https://alice.com/inbox', protocol: :activitypub, domain: 'alice.com') } + let!(:remote_reporter) { Fabricate(:account, uri: 'https://bob.com', inbox_url: 'https://bob.com/inbox', protocol: :activitypub, domain: 'bob.com') } let!(:report) { Fabricate(:report, account: remote_reporter, target_account: account) } before do diff --git a/spec/workers/activitypub/distribute_poll_update_worker_spec.rb b/spec/workers/activitypub/distribute_poll_update_worker_spec.rb index 947acab3bcf3a4..0bdbf639032405 100644 --- a/spec/workers/activitypub/distribute_poll_update_worker_spec.rb +++ b/spec/workers/activitypub/distribute_poll_update_worker_spec.rb @@ -6,7 +6,7 @@ subject { described_class.new } let(:account) { Fabricate(:account) } - let(:follower) { Fabricate(:account, protocol: :activitypub, inbox_url: 'http://example.com') } + let(:follower) { Fabricate(:account, protocol: :activitypub, inbox_url: 'http://example.com', domain: 'example.com') } let(:poll) { Fabricate(:poll, account: account) } let!(:status) { Fabricate(:status, account: account, poll: poll) } diff --git a/spec/workers/activitypub/distribution_worker_spec.rb b/spec/workers/activitypub/distribution_worker_spec.rb index 06d6ac73831452..d8803f6b8a94cb 100644 --- a/spec/workers/activitypub/distribution_worker_spec.rb +++ b/spec/workers/activitypub/distribution_worker_spec.rb @@ -6,7 +6,7 @@ subject { described_class.new } let(:status) { Fabricate(:status) } - let(:follower) { Fabricate(:account, protocol: :activitypub, inbox_url: 'http://example.com') } + let(:follower) { Fabricate(:account, protocol: :activitypub, inbox_url: 'http://example.com', domain: 'example.com') } describe '#perform' do before do @@ -36,7 +36,7 @@ end context 'with direct status' do - let(:mentioned_account) { Fabricate(:account, protocol: :activitypub, inbox_url: 'https://foo.bar/inbox') } + let(:mentioned_account) { Fabricate(:account, protocol: :activitypub, inbox_url: 'https://foo.bar/inbox', domain: 'foo.bar') } before do status.update(visibility: :direct) diff --git a/spec/workers/activitypub/fetch_replies_worker_spec.rb b/spec/workers/activitypub/fetch_replies_worker_spec.rb index 91ef3c4b928fd7..ff4d049a269ed9 100644 --- a/spec/workers/activitypub/fetch_replies_worker_spec.rb +++ b/spec/workers/activitypub/fetch_replies_worker_spec.rb @@ -5,7 +5,7 @@ describe ActivityPub::FetchRepliesWorker do subject { described_class.new } - let(:account) { Fabricate(:account, uri: 'https://example.com/user/1') } + let(:account) { Fabricate(:account, domain: 'example.com') } let(:status) { Fabricate(:status, account: account) } let(:payload) do diff --git a/spec/workers/activitypub/move_distribution_worker_spec.rb b/spec/workers/activitypub/move_distribution_worker_spec.rb index 4df6b2f161ba8a..b8601f78cf3943 100644 --- a/spec/workers/activitypub/move_distribution_worker_spec.rb +++ b/spec/workers/activitypub/move_distribution_worker_spec.rb @@ -6,8 +6,8 @@ subject { described_class.new } let(:migration) { Fabricate(:account_migration) } - let(:follower) { Fabricate(:account, protocol: :activitypub, inbox_url: 'http://example.com') } - let(:blocker) { Fabricate(:account, protocol: :activitypub, inbox_url: 'http://example2.com') } + let(:follower) { Fabricate(:account, protocol: :activitypub, inbox_url: 'http://example.com', domain: 'example.com') } + let(:blocker) { Fabricate(:account, protocol: :activitypub, inbox_url: 'http://example2.com', domain: 'example2.com') } describe '#perform' do before do diff --git a/spec/workers/activitypub/status_update_distribution_worker_spec.rb b/spec/workers/activitypub/status_update_distribution_worker_spec.rb index cf55a461d8b985..c500bac9591848 100644 --- a/spec/workers/activitypub/status_update_distribution_worker_spec.rb +++ b/spec/workers/activitypub/status_update_distribution_worker_spec.rb @@ -6,7 +6,7 @@ subject { described_class.new } let(:status) { Fabricate(:status, text: 'foo') } - let(:follower) { Fabricate(:account, protocol: :activitypub, inbox_url: 'http://example.com') } + let(:follower) { Fabricate(:account, protocol: :activitypub, inbox_url: 'http://example.com', domain: 'example.com') } describe '#perform' do before do diff --git a/spec/workers/activitypub/update_distribution_worker_spec.rb b/spec/workers/activitypub/update_distribution_worker_spec.rb index 7b1e6ff543e52b..d0eeda43bfa214 100644 --- a/spec/workers/activitypub/update_distribution_worker_spec.rb +++ b/spec/workers/activitypub/update_distribution_worker_spec.rb @@ -6,7 +6,7 @@ subject { described_class.new } let(:account) { Fabricate(:account) } - let(:follower) { Fabricate(:account, protocol: :activitypub, inbox_url: 'http://example.com') } + let(:follower) { Fabricate(:account, protocol: :activitypub, inbox_url: 'http://example.com', domain: 'example.com') } describe '#perform' do before do From 4ea041fe6781d815a5ab832d2866b34b161acef1 Mon Sep 17 00:00:00 2001 From: Renaud Chaput Date: Fri, 21 Jul 2023 10:46:12 +0200 Subject: [PATCH 11/94] Improve the bug report templates (#25621) --- .github/ISSUE_TEMPLATE/1.bug_report.yml | 56 -------------- .github/ISSUE_TEMPLATE/1.web_bug_report.yml | 76 +++++++++++++++++++ .../ISSUE_TEMPLATE/2.server_bug_report.yml | 65 ++++++++++++++++ ...ture_request.yml => 3.feature_request.yml} | 0 4 files changed, 141 insertions(+), 56 deletions(-) delete mode 100644 .github/ISSUE_TEMPLATE/1.bug_report.yml create mode 100644 .github/ISSUE_TEMPLATE/1.web_bug_report.yml create mode 100644 .github/ISSUE_TEMPLATE/2.server_bug_report.yml rename .github/ISSUE_TEMPLATE/{2.feature_request.yml => 3.feature_request.yml} (100%) diff --git a/.github/ISSUE_TEMPLATE/1.bug_report.yml b/.github/ISSUE_TEMPLATE/1.bug_report.yml deleted file mode 100644 index 22f51f7bdfc592..00000000000000 --- a/.github/ISSUE_TEMPLATE/1.bug_report.yml +++ /dev/null @@ -1,56 +0,0 @@ -name: Bug Report -description: If something isn't working as expected -labels: [bug] -body: - - type: markdown - attributes: - value: | - Make sure that you are submitting a new bug that was not previously reported or already fixed. - - Please use a concise and distinct title for the issue. - - type: textarea - attributes: - label: Steps to reproduce the problem - description: What were you trying to do? - value: | - 1. - 2. - 3. - ... - validations: - required: true - - type: input - attributes: - label: Expected behaviour - description: What should have happened? - validations: - required: true - - type: input - attributes: - label: Actual behaviour - description: What happened? - validations: - required: true - - type: textarea - attributes: - label: Detailed description - validations: - required: false - - type: textarea - attributes: - label: Specifications - description: | - What version or commit hash of Mastodon did you find this bug in? - - If a front-end issue, what browser and operating systems were you using? - placeholder: | - Mastodon 3.5.3 (or Edge) - Ruby 2.7.6 (or v3.1.2) - Node.js 16.18.0 - - Google Chrome 106.0.5249.119 - Firefox 105.0.3 - - etc... - validations: - required: true diff --git a/.github/ISSUE_TEMPLATE/1.web_bug_report.yml b/.github/ISSUE_TEMPLATE/1.web_bug_report.yml new file mode 100644 index 00000000000000..20e27d103cdb07 --- /dev/null +++ b/.github/ISSUE_TEMPLATE/1.web_bug_report.yml @@ -0,0 +1,76 @@ +name: Bug Report (Web Interface) +description: If you are using Mastodon's web interface and something is not working as expected +labels: [bug, 'status/to triage', 'area/web interface'] +body: + - type: markdown + attributes: + value: | + Make sure that you are submitting a new bug that was not previously reported or already fixed. + + Please use a concise and distinct title for the issue. + - type: textarea + attributes: + label: Steps to reproduce the problem + description: What were you trying to do? + value: | + 1. + 2. + 3. + ... + validations: + required: true + - type: input + attributes: + label: Expected behaviour + description: What should have happened? + validations: + required: true + - type: input + attributes: + label: Actual behaviour + description: What happened? + validations: + required: true + - type: textarea + attributes: + label: Detailed description + validations: + required: false + - type: input + attributes: + label: Mastodon instance + description: The address of the Mastodon instance where you experienced the issue + placeholder: mastodon.social + validations: + required: true + - type: input + attributes: + label: Mastodon version + description: | + This is displayed at the bottom of the About page, eg. `v4.1.2+nightly-20230627` + placeholder: v4.1.2 + validations: + required: true + - type: input + attributes: + label: Browser name and version + description: | + What browser are you using when getting this bug? Please specify the version as well. + placeholder: Firefox 105.0.3 + validations: + required: true + - type: input + attributes: + label: Operating system + description: | + What OS are you running? Please specify the version as well. + placeholder: macOS 13.4.1 + validations: + required: true + - type: textarea + attributes: + label: Technical details + description: | + Any additional technical details you may have. This can include the full error log, inspector's output… + validations: + required: false diff --git a/.github/ISSUE_TEMPLATE/2.server_bug_report.yml b/.github/ISSUE_TEMPLATE/2.server_bug_report.yml new file mode 100644 index 00000000000000..49d5f57209fd80 --- /dev/null +++ b/.github/ISSUE_TEMPLATE/2.server_bug_report.yml @@ -0,0 +1,65 @@ +name: Bug Report (server / API) +description: | + If something is not working as expected, but is not from using the web interface. +labels: [bug, 'status/to triage'] +body: + - type: markdown + attributes: + value: | + Make sure that you are submitting a new bug that was not previously reported or already fixed. + + Please use a concise and distinct title for the issue. + - type: textarea + attributes: + label: Steps to reproduce the problem + description: What were you trying to do? + value: | + 1. + 2. + 3. + ... + validations: + required: true + - type: input + attributes: + label: Expected behaviour + description: What should have happened? + validations: + required: true + - type: input + attributes: + label: Actual behaviour + description: What happened? + validations: + required: true + - type: textarea + attributes: + label: Detailed description + validations: + required: false + - type: input + attributes: + label: Mastodon instance + description: The address of the Mastodon instance where you experienced the issue + placeholder: mastodon.social + validations: + required: false + - type: input + attributes: + label: Mastodon version + description: | + This is displayed at the bottom of the About page, eg. `v4.1.2+nightly-20230627` + placeholder: v4.1.2 + validations: + required: false + - type: textarea + attributes: + label: Technical details + description: | + Any additional technical details you may have, like logs or error traces + value: | + If this is happening on your own Mastodon server, please fill out those: + - Ruby version: (from `ruby --version`, eg. v3.1.2) + - Node.js version: (from `node --version`, eg. v18.16.0) + validations: + required: false diff --git a/.github/ISSUE_TEMPLATE/2.feature_request.yml b/.github/ISSUE_TEMPLATE/3.feature_request.yml similarity index 100% rename from .github/ISSUE_TEMPLATE/2.feature_request.yml rename to .github/ISSUE_TEMPLATE/3.feature_request.yml From 42698b4c5c4f33b50e47e271eb37e0aba3e08147 Mon Sep 17 00:00:00 2001 From: Renaud Chaput Date: Fri, 21 Jul 2023 11:14:26 +0200 Subject: [PATCH 12/94] Fix the crossorigin attribute (#26096) --- app/views/layouts/application.html.haml | 2 +- app/views/layouts/embedded.html.haml | 2 +- app/views/shared/_web_app.html.haml | 6 +++--- config/webpack/shared.js | 1 + lib/webpacker/helper_extensions.rb | 9 ++++++++- 5 files changed, 14 insertions(+), 6 deletions(-) diff --git a/app/views/layouts/application.html.haml b/app/views/layouts/application.html.haml index f2d7af4961e666..4fe2f18bfb13be 100755 --- a/app/views/layouts/application.html.haml +++ b/app/views/layouts/application.html.haml @@ -29,7 +29,7 @@ = stylesheet_pack_tag 'common', media: 'all', crossorigin: 'anonymous' = stylesheet_pack_tag current_theme, media: 'all', crossorigin: 'anonymous' = javascript_pack_tag 'common', crossorigin: 'anonymous' - = preload_pack_asset "locale/#{I18n.locale}-json.js", crossorigin: 'anonymous' + = preload_pack_asset "locale/#{I18n.locale}-json.js" = csrf_meta_tags unless skip_csrf_meta_tags? %meta{ name: 'style-nonce', content: request.content_security_policy_nonce } diff --git a/app/views/layouts/embedded.html.haml b/app/views/layouts/embedded.html.haml index 53e1fd7932f8fc..d8aa522d8007e1 100644 --- a/app/views/layouts/embedded.html.haml +++ b/app/views/layouts/embedded.html.haml @@ -14,7 +14,7 @@ = stylesheet_pack_tag 'common', media: 'all', crossorigin: 'anonymous' = stylesheet_pack_tag Setting.default_settings['theme'], media: 'all', crossorigin: 'anonymous' = javascript_pack_tag 'common', integrity: true, crossorigin: 'anonymous' - = preload_pack_asset "locale/#{I18n.locale}-json.js", crossorigin: 'anonymous' + = preload_pack_asset "locale/#{I18n.locale}-json.js" = render_initial_state = javascript_pack_tag 'public', integrity: true, crossorigin: 'anonymous' %body.embed diff --git a/app/views/shared/_web_app.html.haml b/app/views/shared/_web_app.html.haml index 9a1c3dc0bf432c..e9ca541691db53 100644 --- a/app/views/shared/_web_app.html.haml +++ b/app/views/shared/_web_app.html.haml @@ -1,8 +1,8 @@ - content_for :header_tags do - if user_signed_in? - = preload_pack_asset 'features/compose.js', crossorigin: 'anonymous' - = preload_pack_asset 'features/home_timeline.js', crossorigin: 'anonymous' - = preload_pack_asset 'features/notifications.js', crossorigin: 'anonymous' + = preload_pack_asset 'features/compose.js' + = preload_pack_asset 'features/home_timeline.js' + = preload_pack_asset 'features/notifications.js' %meta{ name: 'initialPath', content: request.path } %meta{ name: 'applicationServerKey', content: Rails.configuration.x.vapid_public_key } diff --git a/config/webpack/shared.js b/config/webpack/shared.js index bb6ae74c336f84..3b69282d538fb4 100644 --- a/config/webpack/shared.js +++ b/config/webpack/shared.js @@ -34,6 +34,7 @@ module.exports = { chunkFilename: 'js/[name]-[chunkhash].chunk.js', hotUpdateChunkFilename: 'js/[id]-[hash].hot-update.js', hashFunction: 'sha256', + crossOriginLoading: 'anonymous', path: output.path, publicPath: output.publicPath, }, diff --git a/lib/webpacker/helper_extensions.rb b/lib/webpacker/helper_extensions.rb index 8f46d763132b5d..3872e3d86dae3a 100644 --- a/lib/webpacker/helper_extensions.rb +++ b/lib/webpacker/helper_extensions.rb @@ -13,7 +13,14 @@ def stylesheet_pack_tag(name, **options) def preload_pack_asset(name, **options) src, integrity = current_webpacker_instance.manifest.lookup!(name, with_integrity: true) - preload_link_tag(src, options.merge(integrity: integrity)) + + # This attribute will only work if the assets are on a different domain. + # And Webpack will (correctly) only add it in this case, so we need to conditionally set it here + # otherwise the preloaded request and the real request will have different crossorigin values + # and the preloaded file wont be loaded + crossorigin = 'anonymous' if Rails.configuration.action_controller.asset_host.present? + + preload_link_tag(src, options.merge(integrity: integrity, crossorigin: crossorigin)) end end From 5cbc402687a99511b8fa20b1541a774c0428be16 Mon Sep 17 00:00:00 2001 From: Claire Date: Fri, 21 Jul 2023 11:30:53 +0200 Subject: [PATCH 13/94] Fix replica being used even if not explicitly defined (#26074) --- app/models/application_record.rb | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/app/models/application_record.rb b/app/models/application_record.rb index 23e0af3a2a6a2c..efff5cdad55df3 100644 --- a/app/models/application_record.rb +++ b/app/models/application_record.rb @@ -5,7 +5,7 @@ class ApplicationRecord < ActiveRecord::Base include Remotable - connects_to database: { writing: :primary, reading: :read } + connects_to database: { writing: :primary, reading: ENV['DB_REPLICA_NAME'] || ENV['READ_DATABASE_URL'] ? :read : :primary } class << self def update_index(_type_name, *_args, &_block) From 144a406d332b034caa812ade2629df03ed4898d7 Mon Sep 17 00:00:00 2001 From: Claire Date: Fri, 21 Jul 2023 13:13:16 +0200 Subject: [PATCH 14/94] Clean up unused application records (#24871) --- .rubocop_todo.yml | 1 + app/lib/application_extension.rb | 2 + app/lib/vacuum/applications_vacuum.rb | 10 +++++ app/workers/scheduler/vacuum_scheduler.rb | 5 +++ spec/lib/vacuum/applications_vacuum_spec.rb | 48 +++++++++++++++++++++ 5 files changed, 66 insertions(+) create mode 100644 app/lib/vacuum/applications_vacuum.rb create mode 100644 spec/lib/vacuum/applications_vacuum_spec.rb diff --git a/.rubocop_todo.yml b/.rubocop_todo.yml index 32fb99b77229be..71e8623ec5c802 100644 --- a/.rubocop_todo.yml +++ b/.rubocop_todo.yml @@ -289,6 +289,7 @@ RSpec/LetSetup: - 'spec/controllers/oauth/tokens_controller_spec.rb' - 'spec/controllers/settings/imports_controller_spec.rb' - 'spec/lib/activitypub/activity/delete_spec.rb' + - 'spec/lib/vacuum/applications_vacuum_spec.rb' - 'spec/lib/vacuum/preview_cards_vacuum_spec.rb' - 'spec/models/account_spec.rb' - 'spec/models/account_statuses_cleanup_policy_spec.rb' diff --git a/app/lib/application_extension.rb b/app/lib/application_extension.rb index 4de69c1eaddb24..fb442e2c2d2fca 100644 --- a/app/lib/application_extension.rb +++ b/app/lib/application_extension.rb @@ -4,6 +4,8 @@ module ApplicationExtension extend ActiveSupport::Concern included do + has_many :created_users, class_name: 'User', foreign_key: 'created_by_application_id', inverse_of: :created_by_application + validates :name, length: { maximum: 60 } validates :website, url: true, length: { maximum: 2_000 }, if: :website? validates :redirect_uri, length: { maximum: 2_000 } diff --git a/app/lib/vacuum/applications_vacuum.rb b/app/lib/vacuum/applications_vacuum.rb new file mode 100644 index 00000000000000..ba88655f167c25 --- /dev/null +++ b/app/lib/vacuum/applications_vacuum.rb @@ -0,0 +1,10 @@ +# frozen_string_literal: true + +class Vacuum::ApplicationsVacuum + def perform + Doorkeeper::Application.where(owner_id: nil) + .where.missing(:created_users, :access_tokens, :access_grants) + .where(created_at: ...1.day.ago) + .in_batches.delete_all + end +end diff --git a/app/workers/scheduler/vacuum_scheduler.rb b/app/workers/scheduler/vacuum_scheduler.rb index 9e884caefdb176..9c040f6e474de4 100644 --- a/app/workers/scheduler/vacuum_scheduler.rb +++ b/app/workers/scheduler/vacuum_scheduler.rb @@ -22,6 +22,7 @@ def vacuum_operations preview_cards_vacuum, backups_vacuum, access_tokens_vacuum, + applications_vacuum, feeds_vacuum, imports_vacuum, ] @@ -55,6 +56,10 @@ def imports_vacuum Vacuum::ImportsVacuum.new end + def applications_vacuum + Vacuum::ApplicationsVacuum.new + end + def content_retention_policy ContentRetentionPolicy.current end diff --git a/spec/lib/vacuum/applications_vacuum_spec.rb b/spec/lib/vacuum/applications_vacuum_spec.rb new file mode 100644 index 00000000000000..d30311ab134a4a --- /dev/null +++ b/spec/lib/vacuum/applications_vacuum_spec.rb @@ -0,0 +1,48 @@ +# frozen_string_literal: true + +require 'rails_helper' + +RSpec.describe Vacuum::ApplicationsVacuum do + subject { described_class.new } + + describe '#perform' do + let!(:app1) { Fabricate(:application, created_at: 1.month.ago) } + let!(:app2) { Fabricate(:application, created_at: 1.month.ago) } + let!(:app3) { Fabricate(:application, created_at: 1.month.ago) } + let!(:app4) { Fabricate(:application, created_at: 1.month.ago, owner: Fabricate(:user)) } + let!(:app5) { Fabricate(:application, created_at: 1.month.ago) } + let!(:app6) { Fabricate(:application, created_at: 1.hour.ago) } + + let!(:active_access_token) { Fabricate(:access_token, application: app1) } + let!(:active_access_grant) { Fabricate(:access_grant, application: app2) } + let!(:user) { Fabricate(:user, created_by_application: app3) } + + before do + subject.perform + end + + it 'does not delete applications with valid access tokens' do + expect { app1.reload }.to_not raise_error + end + + it 'does not delete applications with valid access grants' do + expect { app2.reload }.to_not raise_error + end + + it 'does not delete applications that were used to create users' do + expect { app3.reload }.to_not raise_error + end + + it 'does not delete owned applications' do + expect { app4.reload }.to_not raise_error + end + + it 'does not delete applications registered less than a day ago' do + expect { app6.reload }.to_not raise_error + end + + it 'deletes unused applications' do + expect { app5.reload }.to raise_error ActiveRecord::RecordNotFound + end + end +end From e4ea80d8089110790bf11f7d4021dbe7b6a866de Mon Sep 17 00:00:00 2001 From: Claire Date: Fri, 21 Jul 2023 13:14:30 +0200 Subject: [PATCH 15/94] Change thread view to scroll to the selected post rather than the post being replied to (#24685) --- .../mastodon/features/status/index.jsx | 34 +++++++++---------- 1 file changed, 16 insertions(+), 18 deletions(-) diff --git a/app/javascript/mastodon/features/status/index.jsx b/app/javascript/mastodon/features/status/index.jsx index e5f91071e90b43..4f58c7d2fd0b2e 100644 --- a/app/javascript/mastodon/features/status/index.jsx +++ b/app/javascript/mastodon/features/status/index.jsx @@ -196,8 +196,8 @@ class Status extends ImmutablePureComponent { dispatch: PropTypes.func.isRequired, status: ImmutablePropTypes.map, isLoading: PropTypes.bool, - ancestorsIds: ImmutablePropTypes.list, - descendantsIds: ImmutablePropTypes.list, + ancestorsIds: ImmutablePropTypes.list.isRequired, + descendantsIds: ImmutablePropTypes.list.isRequired, intl: PropTypes.object.isRequired, askReplyConfirmation: PropTypes.bool, multiColumn: PropTypes.bool, @@ -224,14 +224,9 @@ class Status extends ImmutablePureComponent { UNSAFE_componentWillReceiveProps (nextProps) { if (nextProps.params.statusId !== this.props.params.statusId && nextProps.params.statusId) { - this._scrolledIntoView = false; this.props.dispatch(fetchStatus(nextProps.params.statusId)); } - if (nextProps.params.statusId && nextProps.ancestorsIds.size > this.props.ancestorsIds.size) { - this._scrolledIntoView = false; - } - if (nextProps.status && nextProps.status.get('id') !== this.state.loadedStatusId) { this.setState({ showMedia: defaultMediaVisibility(nextProps.status), loadedStatusId: nextProps.status.get('id') }); } @@ -584,20 +579,23 @@ class Status extends ImmutablePureComponent { this.node = c; }; - componentDidUpdate () { - if (this._scrolledIntoView) { - return; - } - - const { status, ancestorsIds } = this.props; - - if (status && ancestorsIds && ancestorsIds.size > 0) { - const element = this.node.querySelectorAll('.focusable')[ancestorsIds.size - 1]; + componentDidUpdate (prevProps) { + const { status, ancestorsIds, multiColumn } = this.props; + if (status && (ancestorsIds.size > prevProps.ancestorsIds.size || prevProps.status?.get('id') !== status.get('id'))) { window.requestAnimationFrame(() => { - element.scrollIntoView(true); + this.node?.querySelector('.detailed-status__wrapper')?.scrollIntoView(true); + + // In the single-column interface, `scrollIntoView` will put the post behind the header, + // so compensate for that. + if (!multiColumn) { + const offset = document.querySelector('.column-header__wrapper')?.getBoundingClientRect()?.bottom; + if (offset) { + const scrollingElement = document.scrollingElement || document.body; + scrollingElement.scrollBy(0, -offset); + } + } }); - this._scrolledIntoView = true; } } From 934c7b33d1d33e3e12a7bb12f654b5d8eed0d51b Mon Sep 17 00:00:00 2001 From: Claire Date: Fri, 21 Jul 2023 13:17:43 +0200 Subject: [PATCH 16/94] Change default KeyGenerator digest to SHA1 to fix cookies in rolling upgrades (#26023) --- config/initializers/cookie_rotator.rb | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) diff --git a/config/initializers/cookie_rotator.rb b/config/initializers/cookie_rotator.rb index 349c363f145090..b829b1a90b7296 100644 --- a/config/initializers/cookie_rotator.rb +++ b/config/initializers/cookie_rotator.rb @@ -1,5 +1,10 @@ # frozen_string_literal: true +# TODO: Remove after 4.2.0 +Rails.application.configure do + config.active_support.key_generator_hash_digest_class = OpenSSL::Digest::SHA1 +end + Rails.application.config.after_initialize do Rails.application.config.action_dispatch.cookies_rotations.tap do |cookies| authenticated_encrypted_cookie_salt = Rails.application.config.action_dispatch.authenticated_encrypted_cookie_salt @@ -7,8 +12,9 @@ secret_key_base = Rails.application.secret_key_base + # TODO: Switch to SHA1 after 4.2.0 key_generator = ActiveSupport::KeyGenerator.new( - secret_key_base, iterations: 1000, hash_digest_class: OpenSSL::Digest::SHA1 + secret_key_base, iterations: 1000, hash_digest_class: OpenSSL::Digest::SHA256 ) key_len = ActiveSupport::MessageEncryptor.key_len From 59478a1b46e934c75ad27f1270d9b9411de3f185 Mon Sep 17 00:00:00 2001 From: Trevor Wolf Date: Fri, 21 Jul 2023 21:20:14 +1000 Subject: [PATCH 17/94] change focus ui for keyboard only input (#25935) --- .../mastodon/components/dropdown_menu.jsx | 2 +- .../compose/components/navigation_bar.jsx | 21 +++-- app/javascript/styles/mastodon/basics.scss | 15 +++- .../styles/mastodon/components.scss | 83 +++++-------------- app/javascript/styles/mastodon/variables.scss | 4 + 5 files changed, 51 insertions(+), 74 deletions(-) diff --git a/app/javascript/mastodon/components/dropdown_menu.jsx b/app/javascript/mastodon/components/dropdown_menu.jsx index 0416df5d45f2ad..fd66310e856ee6 100644 --- a/app/javascript/mastodon/components/dropdown_menu.jsx +++ b/app/javascript/mastodon/components/dropdown_menu.jsx @@ -297,7 +297,7 @@ export default class Dropdown extends PureComponent { onKeyPress: this.handleKeyPress, }) : ( - - {this.props.account.get('acct')} + + {username}
- - @{this.props.account.get('acct')} - - - + + + @{username} + + + + + +
-
diff --git a/app/javascript/styles/mastodon/basics.scss b/app/javascript/styles/mastodon/basics.scss index ff00c797c8e4dc..234c703f23c574 100644 --- a/app/javascript/styles/mastodon/basics.scss +++ b/app/javascript/styles/mastodon/basics.scss @@ -161,15 +161,22 @@ body { } } -button { - font-family: inherit; - cursor: pointer; - +a { &:focus { + border-radius: 4px; + outline: $ui-button-icon-focus-outline; + } + + &:focus:not(:focus-visible) { outline: none; } } +button { + font-family: inherit; + cursor: pointer; +} + .app-holder { &, & > div, diff --git a/app/javascript/styles/mastodon/components.scss b/app/javascript/styles/mastodon/components.scss index beff07daa450ca..d08cb28038c9b8 100644 --- a/app/javascript/styles/mastodon/components.scss +++ b/app/javascript/styles/mastodon/components.scss @@ -74,6 +74,10 @@ background-color: $ui-button-focus-background-color; } + &:focus { + outline: $ui-button-icon-focus-outline; + } + &--destructive { &:active, &:focus, @@ -98,16 +102,6 @@ transition: none; } - &::-moz-focus-inner { - border: 0; - } - - &::-moz-focus-inner, - &:focus, - &:active { - outline: 0 !important; - } - &.button-secondary { color: $ui-button-secondary-color; background: transparent; @@ -197,7 +191,7 @@ border-radius: 4px; background: transparent; cursor: pointer; - transition: all 100ms ease-in; + transition: all 100ms ease-out; transition-property: background-color, color; text-decoration: none; @@ -209,14 +203,12 @@ &:hover, &:active, &:focus { - color: lighten($action-button-color, 7%); - background-color: rgba($action-button-color, 0.15); - transition: all 200ms ease-out; - transition-property: background-color, color; + color: lighten($action-button-color, 20%); + background-color: $ui-button-icon-hover-background-color; } &:focus { - background-color: rgba($action-button-color, 0.3); + outline: $ui-button-icon-focus-outline; } &.disabled { @@ -225,20 +217,6 @@ cursor: default; } - &.active { - color: $highlight-text-color; - } - - &::-moz-focus-inner { - border: 0; - } - - &::-moz-focus-inner, - &:focus, - &:active { - outline: 0 !important; - } - &.inverted { color: $lighter-text-color; @@ -246,11 +224,11 @@ &:active, &:focus { color: darken($lighter-text-color, 7%); - background-color: rgba($lighter-text-color, 0.15); + background-color: $ui-button-icon-hover-background-color; } &:focus { - background-color: rgba($lighter-text-color, 0.3); + outline: $ui-button-icon-focus-outline; } &.disabled { @@ -305,7 +283,6 @@ font-size: 11px; padding: 0 3px; line-height: 27px; - outline: 0; transition: all 100ms ease-in; transition-property: background-color, color; @@ -313,13 +290,13 @@ &:active, &:focus { color: darken($lighter-text-color, 7%); - background-color: rgba($lighter-text-color, 0.15); + background-color: $ui-button-icon-hover-background-color; transition: all 200ms ease-out; transition-property: background-color, color; } &:focus { - background-color: rgba($lighter-text-color, 0.3); + outline: $ui-button-icon-focus-outline; } &.disabled { @@ -331,16 +308,6 @@ &.active { color: $highlight-text-color; } - - &::-moz-focus-inner { - border: 0; - } - - &::-moz-focus-inner, - &:focus, - &:active { - outline: 0 !important; - } } body > [data-popper-placement] { @@ -728,7 +695,6 @@ body > [data-popper-placement] { flex: 0 0 auto; .compose-form__publish-button-wrapper { - overflow: hidden; padding-top: 15px; } } @@ -1929,13 +1895,6 @@ a.account__display-name { .navigation-bar__actions { position: relative; - .icon-button.close { - position: absolute; - pointer-events: none; - transform: scale(0, 1) translate(-100%, 0); - opacity: 0; - } - .compose__action-bar .icon-button { pointer-events: auto; transform: scale(1, 1) translate(0, 0); @@ -1945,19 +1904,21 @@ a.account__display-name { } .navigation-bar__profile { + display: flex; + flex-direction: column; flex: 1 1 auto; line-height: 20px; - overflow: hidden; } .navigation-bar__profile-account { - display: block; + display: inline; font-weight: 500; overflow: hidden; text-overflow: ellipsis; } .navigation-bar__profile-edit { + display: inline; color: inherit; text-decoration: none; } @@ -4740,11 +4701,6 @@ a.status-card.compact:hover { outline: 0; cursor: pointer; - &:active, - &:focus { - outline: 0 !important; - } - img { filter: grayscale(100%); opacity: 0.8; @@ -4760,6 +4716,13 @@ a.status-card.compact:hover { img { opacity: 1; filter: none; + border-radius: 100%; + } + } + + &:focus { + img { + outline: $ui-button-icon-focus-outline; } } } diff --git a/app/javascript/styles/mastodon/variables.scss b/app/javascript/styles/mastodon/variables.scss index 68db9d5fc00bfa..e89dd5d3ab0e01 100644 --- a/app/javascript/styles/mastodon/variables.scss +++ b/app/javascript/styles/mastodon/variables.scss @@ -5,6 +5,7 @@ $red-600: #b7253d !default; // Deep Carmine $red-500: #df405a !default; // Cerise $blurple-600: #563acc; // Iris $blurple-500: #6364ff; // Brand purple +$blurple-400: #7477fd; // Medium slate blue $blurple-300: #858afa; // Faded Blue $grey-600: #4e4c5a; // Trout $grey-100: #dadaf3; // Topaz @@ -56,6 +57,9 @@ $ui-button-tertiary-focus-color: $white !default; $ui-button-destructive-background-color: $red-500 !default; $ui-button-destructive-focus-background-color: $red-600 !default; +$ui-button-icon-focus-outline: solid 2px $blurple-400 !default; +$ui-button-icon-hover-background-color: rgba(140, 141, 255, 40%) !default; + // Variables for texts $primary-text-color: $white !default; $darker-text-color: $ui-primary-color !default; From 14fad603845dedda87300516a90d78b3b69133df Mon Sep 17 00:00:00 2001 From: Claire Date: Fri, 21 Jul 2023 13:20:53 +0200 Subject: [PATCH 18/94] Use username as display name for suspended users or users with blank display names (#25276) --- app/serializers/activitypub/actor_serializer.rb | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/app/serializers/activitypub/actor_serializer.rb b/app/serializers/activitypub/actor_serializer.rb index e6dd8040e9e630..36397857f01de4 100644 --- a/app/serializers/activitypub/actor_serializer.rb +++ b/app/serializers/activitypub/actor_serializer.rb @@ -99,7 +99,7 @@ def discoverable end def name - object.suspended? ? '' : object.display_name + object.suspended? ? object.username : (object.display_name.presence || object.username) end def summary From e5f1000ad1c2817a62617f78ed21983bd4b38487 Mon Sep 17 00:00:00 2001 From: Claire Date: Fri, 21 Jul 2023 13:34:15 +0200 Subject: [PATCH 19/94] Fix CSP headers being unintendedly wide (#26105) --- .../initializers/content_security_policy.rb | 2 +- spec/requests/content_security_policy_spec.rb | 27 +++++++++++++++++++ 2 files changed, 28 insertions(+), 1 deletion(-) create mode 100644 spec/requests/content_security_policy_spec.rb diff --git a/config/initializers/content_security_policy.rb b/config/initializers/content_security_policy.rb index 4cc9c204db3479..98c4f541f3ae3a 100644 --- a/config/initializers/content_security_policy.rb +++ b/config/initializers/content_security_policy.rb @@ -5,7 +5,7 @@ # https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/Content-Security-Policy def host_to_url(str) - "http#{Rails.configuration.x.use_https ? 's' : ''}://#{str}".split('/').first if str.present? + "http#{Rails.configuration.x.use_https ? 's' : ''}://#{str.split('/').first}" if str.present? end base_host = Rails.configuration.x.web_domain diff --git a/spec/requests/content_security_policy_spec.rb b/spec/requests/content_security_policy_spec.rb new file mode 100644 index 00000000000000..7eb27d61d615ca --- /dev/null +++ b/spec/requests/content_security_policy_spec.rb @@ -0,0 +1,27 @@ +# frozen_string_literal: true + +require 'rails_helper' + +describe 'Content-Security-Policy' do + it 'sets the expected CSP headers' do + allow(SecureRandom).to receive(:base64).with(16).and_return('ZbA+JmE7+bK8F5qvADZHuQ==') + + get '/' + expect(response.headers['Content-Security-Policy'].split(';').map(&:strip)).to contain_exactly( + "base-uri 'none'", + "default-src 'none'", + "frame-ancestors 'none'", + "font-src 'self' https://cb6e6126.ngrok.io", + "img-src 'self' https: data: blob: https://cb6e6126.ngrok.io", + "style-src 'self' https://cb6e6126.ngrok.io 'nonce-ZbA+JmE7+bK8F5qvADZHuQ=='", + "media-src 'self' https: data: https://cb6e6126.ngrok.io", + "frame-src 'self' https:", + "manifest-src 'self' https://cb6e6126.ngrok.io", + "form-action 'self'", + "child-src 'self' blob: https://cb6e6126.ngrok.io", + "worker-src 'self' blob: https://cb6e6126.ngrok.io", + "connect-src 'self' data: blob: https://cb6e6126.ngrok.io https://cb6e6126.ngrok.io ws://localhost:4000", + "script-src 'self' https://cb6e6126.ngrok.io 'wasm-unsafe-eval'" + ) + end +end From 5b457961fc1189a71599dc6c06b3f159b195a455 Mon Sep 17 00:00:00 2001 From: Claire Date: Fri, 21 Jul 2023 14:21:10 +0200 Subject: [PATCH 20/94] Fix linting issue (#26106) --- spec/lib/vacuum/applications_vacuum_spec.rb | 30 ++++++++++----------- 1 file changed, 15 insertions(+), 15 deletions(-) diff --git a/spec/lib/vacuum/applications_vacuum_spec.rb b/spec/lib/vacuum/applications_vacuum_spec.rb index d30311ab134a4a..57a222aafc8589 100644 --- a/spec/lib/vacuum/applications_vacuum_spec.rb +++ b/spec/lib/vacuum/applications_vacuum_spec.rb @@ -6,43 +6,43 @@ subject { described_class.new } describe '#perform' do - let!(:app1) { Fabricate(:application, created_at: 1.month.ago) } - let!(:app2) { Fabricate(:application, created_at: 1.month.ago) } - let!(:app3) { Fabricate(:application, created_at: 1.month.ago) } - let!(:app4) { Fabricate(:application, created_at: 1.month.ago, owner: Fabricate(:user)) } - let!(:app5) { Fabricate(:application, created_at: 1.month.ago) } - let!(:app6) { Fabricate(:application, created_at: 1.hour.ago) } + let!(:app_with_token) { Fabricate(:application, created_at: 1.month.ago) } + let!(:app_with_grant) { Fabricate(:application, created_at: 1.month.ago) } + let!(:app_with_signup) { Fabricate(:application, created_at: 1.month.ago) } + let!(:app_with_owner) { Fabricate(:application, created_at: 1.month.ago, owner: Fabricate(:user)) } + let!(:unused_app) { Fabricate(:application, created_at: 1.month.ago) } + let!(:recent_app) { Fabricate(:application, created_at: 1.hour.ago) } - let!(:active_access_token) { Fabricate(:access_token, application: app1) } - let!(:active_access_grant) { Fabricate(:access_grant, application: app2) } - let!(:user) { Fabricate(:user, created_by_application: app3) } + let!(:active_access_token) { Fabricate(:access_token, application: app_with_token) } + let!(:active_access_grant) { Fabricate(:access_grant, application: app_with_grant) } + let!(:user) { Fabricate(:user, created_by_application: app_with_signup) } before do subject.perform end it 'does not delete applications with valid access tokens' do - expect { app1.reload }.to_not raise_error + expect { app_with_token.reload }.to_not raise_error end it 'does not delete applications with valid access grants' do - expect { app2.reload }.to_not raise_error + expect { app_with_grant.reload }.to_not raise_error end it 'does not delete applications that were used to create users' do - expect { app3.reload }.to_not raise_error + expect { app_with_signup.reload }.to_not raise_error end it 'does not delete owned applications' do - expect { app4.reload }.to_not raise_error + expect { app_with_owner.reload }.to_not raise_error end it 'does not delete applications registered less than a day ago' do - expect { app6.reload }.to_not raise_error + expect { recent_app.reload }.to_not raise_error end it 'deletes unused applications' do - expect { app5.reload }.to raise_error ActiveRecord::RecordNotFound + expect { unused_app.reload }.to raise_error ActiveRecord::RecordNotFound end end end From 217ef7f2aff08575c505368199f059c3c9d79df5 Mon Sep 17 00:00:00 2001 From: gunchleoc Date: Fri, 21 Jul 2023 19:09:13 +0200 Subject: [PATCH 21/94] Replace 'favourite' by 'favorite' for American English (#26009) --- .../mastodon/components/status_action_bar.jsx | 2 +- .../mastodon/containers/status_container.jsx | 2 +- .../features/account/components/header.jsx | 2 +- .../compose/components/action_bar.jsx | 2 +- .../mastodon/features/explore/statuses.jsx | 2 +- .../features/favourited_statuses/index.jsx | 4 +-- .../mastodon/features/favourites/index.jsx | 2 +- .../features/getting_started/index.jsx | 2 +- .../features/interaction_modal/index.jsx | 6 ++-- .../features/keyboard_shortcuts/index.jsx | 4 +-- .../components/column_settings.jsx | 2 +- .../notifications/components/filter_bar.jsx | 2 +- .../notifications/components/notification.jsx | 4 +-- .../picture_in_picture/components/footer.jsx | 2 +- .../features/status/components/action_bar.jsx | 2 +- .../containers/detailed_status_container.js | 2 +- .../mastodon/features/status/index.jsx | 2 +- .../ui/components/navigation_panel.jsx | 2 +- .../features/ui/components/sign_in_banner.jsx | 2 +- app/javascript/mastodon/locales/en.json | 32 +++++++++---------- config/locales/doorkeeper.en.yml | 6 ++-- 21 files changed, 43 insertions(+), 43 deletions(-) diff --git a/app/javascript/mastodon/components/status_action_bar.jsx b/app/javascript/mastodon/components/status_action_bar.jsx index b713c98c68690c..5d441c10c256b4 100644 --- a/app/javascript/mastodon/components/status_action_bar.jsx +++ b/app/javascript/mastodon/components/status_action_bar.jsx @@ -31,7 +31,7 @@ const messages = defineMessages({ reblog_private: { id: 'status.reblog_private', defaultMessage: 'Boost with original visibility' }, cancel_reblog_private: { id: 'status.cancel_reblog_private', defaultMessage: 'Unboost' }, cannot_reblog: { id: 'status.cannot_reblog', defaultMessage: 'This post cannot be boosted' }, - favourite: { id: 'status.favourite', defaultMessage: 'Favourite' }, + favourite: { id: 'status.favourite', defaultMessage: 'Favorite' }, bookmark: { id: 'status.bookmark', defaultMessage: 'Bookmark' }, removeBookmark: { id: 'status.remove_bookmark', defaultMessage: 'Remove bookmark' }, open: { id: 'status.open', defaultMessage: 'Expand this status' }, diff --git a/app/javascript/mastodon/containers/status_container.jsx b/app/javascript/mastodon/containers/status_container.jsx index 8b3d8b46b7e57a..536765e1370b98 100644 --- a/app/javascript/mastodon/containers/status_container.jsx +++ b/app/javascript/mastodon/containers/status_container.jsx @@ -54,7 +54,7 @@ const messages = defineMessages({ deleteConfirm: { id: 'confirmations.delete.confirm', defaultMessage: 'Delete' }, deleteMessage: { id: 'confirmations.delete.message', defaultMessage: 'Are you sure you want to delete this status?' }, redraftConfirm: { id: 'confirmations.redraft.confirm', defaultMessage: 'Delete & redraft' }, - redraftMessage: { id: 'confirmations.redraft.message', defaultMessage: 'Are you sure you want to delete this status and re-draft it? Favourites and boosts will be lost, and replies to the original post will be orphaned.' }, + redraftMessage: { id: 'confirmations.redraft.message', defaultMessage: 'Are you sure you want to delete this status and re-draft it? Favorites and boosts will be lost, and replies to the original post will be orphaned.' }, replyConfirm: { id: 'confirmations.reply.confirm', defaultMessage: 'Reply' }, replyMessage: { id: 'confirmations.reply.message', defaultMessage: 'Replying now will overwrite the message you are currently composing. Are you sure you want to proceed?' }, editConfirm: { id: 'confirmations.edit.confirm', defaultMessage: 'Edit' }, diff --git a/app/javascript/mastodon/features/account/components/header.jsx b/app/javascript/mastodon/features/account/components/header.jsx index ececb86c083c61..aea73175778426 100644 --- a/app/javascript/mastodon/features/account/components/header.jsx +++ b/app/javascript/mastodon/features/account/components/header.jsx @@ -48,7 +48,7 @@ const messages = defineMessages({ pins: { id: 'navigation_bar.pins', defaultMessage: 'Pinned posts' }, preferences: { id: 'navigation_bar.preferences', defaultMessage: 'Preferences' }, follow_requests: { id: 'navigation_bar.follow_requests', defaultMessage: 'Follow requests' }, - favourites: { id: 'navigation_bar.favourites', defaultMessage: 'Favourites' }, + favourites: { id: 'navigation_bar.favourites', defaultMessage: 'Favorites' }, lists: { id: 'navigation_bar.lists', defaultMessage: 'Lists' }, followed_tags: { id: 'navigation_bar.followed_tags', defaultMessage: 'Followed hashtags' }, blocks: { id: 'navigation_bar.blocks', defaultMessage: 'Blocked users' }, diff --git a/app/javascript/mastodon/features/compose/components/action_bar.jsx b/app/javascript/mastodon/features/compose/components/action_bar.jsx index ac84014e48dbec..7d119215e69f17 100644 --- a/app/javascript/mastodon/features/compose/components/action_bar.jsx +++ b/app/javascript/mastodon/features/compose/components/action_bar.jsx @@ -12,7 +12,7 @@ const messages = defineMessages({ pins: { id: 'navigation_bar.pins', defaultMessage: 'Pinned posts' }, preferences: { id: 'navigation_bar.preferences', defaultMessage: 'Preferences' }, follow_requests: { id: 'navigation_bar.follow_requests', defaultMessage: 'Follow requests' }, - favourites: { id: 'navigation_bar.favourites', defaultMessage: 'Favourites' }, + favourites: { id: 'navigation_bar.favourites', defaultMessage: 'Favorites' }, lists: { id: 'navigation_bar.lists', defaultMessage: 'Lists' }, followed_tags: { id: 'navigation_bar.followed_tags', defaultMessage: 'Followed hashtags' }, blocks: { id: 'navigation_bar.blocks', defaultMessage: 'Blocked users' }, diff --git a/app/javascript/mastodon/features/explore/statuses.jsx b/app/javascript/mastodon/features/explore/statuses.jsx index 043492fb89e410..f32a4a5368c6d1 100644 --- a/app/javascript/mastodon/features/explore/statuses.jsx +++ b/app/javascript/mastodon/features/explore/statuses.jsx @@ -47,7 +47,7 @@ class Statuses extends PureComponent { return ( <> - + ({ @@ -74,7 +74,7 @@ class Favourites extends ImmutablePureComponent { const { intl, statusIds, columnId, multiColumn, hasMore, isLoading } = this.props; const pinned = !!columnId; - const emptyMessage = ; + const emptyMessage = ; return ( diff --git a/app/javascript/mastodon/features/favourites/index.jsx b/app/javascript/mastodon/features/favourites/index.jsx index 57911c3a147c99..bfde78708eb466 100644 --- a/app/javascript/mastodon/features/favourites/index.jsx +++ b/app/javascript/mastodon/features/favourites/index.jsx @@ -61,7 +61,7 @@ class Favourites extends ImmutablePureComponent { ); } - const emptyMessage = ; + const emptyMessage = ; return ( diff --git a/app/javascript/mastodon/features/getting_started/index.jsx b/app/javascript/mastodon/features/getting_started/index.jsx index 85fd6f12092660..f0cd70d7a14006 100644 --- a/app/javascript/mastodon/features/getting_started/index.jsx +++ b/app/javascript/mastodon/features/getting_started/index.jsx @@ -32,7 +32,7 @@ const messages = defineMessages({ bookmarks: { id: 'navigation_bar.bookmarks', defaultMessage: 'Bookmarks' }, preferences: { id: 'navigation_bar.preferences', defaultMessage: 'Preferences' }, follow_requests: { id: 'navigation_bar.follow_requests', defaultMessage: 'Follow requests' }, - favourites: { id: 'navigation_bar.favourites', defaultMessage: 'Favourites' }, + favourites: { id: 'navigation_bar.favourites', defaultMessage: 'Favorites' }, blocks: { id: 'navigation_bar.blocks', defaultMessage: 'Blocked users' }, domain_blocks: { id: 'navigation_bar.domain_blocks', defaultMessage: 'Blocked domains' }, mutes: { id: 'navigation_bar.mutes', defaultMessage: 'Muted users' }, diff --git a/app/javascript/mastodon/features/interaction_modal/index.jsx b/app/javascript/mastodon/features/interaction_modal/index.jsx index 0f17a0896a8847..4722c130e75fe2 100644 --- a/app/javascript/mastodon/features/interaction_modal/index.jsx +++ b/app/javascript/mastodon/features/interaction_modal/index.jsx @@ -116,8 +116,8 @@ class InteractionModal extends PureComponent { break; case 'favourite': icon = ; - title = ; - actionDescription = ; + title = ; + actionDescription = ; break; case 'follow': icon = ; @@ -158,7 +158,7 @@ class InteractionModal extends PureComponent {

-

+

diff --git a/app/javascript/mastodon/features/keyboard_shortcuts/index.jsx b/app/javascript/mastodon/features/keyboard_shortcuts/index.jsx index ce4c6015b01d5e..3dc21f7e8e73ec 100644 --- a/app/javascript/mastodon/features/keyboard_shortcuts/index.jsx +++ b/app/javascript/mastodon/features/keyboard_shortcuts/index.jsx @@ -54,7 +54,7 @@ class KeyboardShortcuts extends ImmutablePureComponent { f - + b @@ -138,7 +138,7 @@ class KeyboardShortcuts extends ImmutablePureComponent { g+f - + g+p diff --git a/app/javascript/mastodon/features/notifications/components/column_settings.jsx b/app/javascript/mastodon/features/notifications/components/column_settings.jsx index 7f8e88f0807d26..09154f257ada5b 100644 --- a/app/javascript/mastodon/features/notifications/components/column_settings.jsx +++ b/app/javascript/mastodon/features/notifications/components/column_settings.jsx @@ -109,7 +109,7 @@ export default class ColumnSettings extends PureComponent {
- +
diff --git a/app/javascript/mastodon/features/notifications/components/filter_bar.jsx b/app/javascript/mastodon/features/notifications/components/filter_bar.jsx index 92cdfa57b6ee0c..773fe9a8f85f38 100644 --- a/app/javascript/mastodon/features/notifications/components/filter_bar.jsx +++ b/app/javascript/mastodon/features/notifications/components/filter_bar.jsx @@ -7,7 +7,7 @@ import { Icon } from 'mastodon/components/icon'; const tooltips = defineMessages({ mentions: { id: 'notifications.filter.mentions', defaultMessage: 'Mentions' }, - favourites: { id: 'notifications.filter.favourites', defaultMessage: 'Favourites' }, + favourites: { id: 'notifications.filter.favourites', defaultMessage: 'Favorites' }, boosts: { id: 'notifications.filter.boosts', defaultMessage: 'Boosts' }, polls: { id: 'notifications.filter.polls', defaultMessage: 'Poll results' }, follows: { id: 'notifications.filter.follows', defaultMessage: 'Follows' }, diff --git a/app/javascript/mastodon/features/notifications/components/notification.jsx b/app/javascript/mastodon/features/notifications/components/notification.jsx index 044e6969e69648..43c5e85cef8618 100644 --- a/app/javascript/mastodon/features/notifications/components/notification.jsx +++ b/app/javascript/mastodon/features/notifications/components/notification.jsx @@ -20,7 +20,7 @@ import FollowRequestContainer from '../containers/follow_request_container'; import Report from './report'; const messages = defineMessages({ - favourite: { id: 'notification.favourite', defaultMessage: '{name} favourited your status' }, + favourite: { id: 'notification.favourite', defaultMessage: '{name} favorited your status' }, follow: { id: 'notification.follow', defaultMessage: '{name} followed you' }, ownPoll: { id: 'notification.own_poll', defaultMessage: 'Your poll has ended' }, poll: { id: 'notification.poll', defaultMessage: 'A poll you have voted in has ended' }, @@ -198,7 +198,7 @@ class Notification extends ImmutablePureComponent {
- +
diff --git a/app/javascript/mastodon/features/picture_in_picture/components/footer.jsx b/app/javascript/mastodon/features/picture_in_picture/components/footer.jsx index c167d93dce2b6b..a368962b93911a 100644 --- a/app/javascript/mastodon/features/picture_in_picture/components/footer.jsx +++ b/app/javascript/mastodon/features/picture_in_picture/components/footer.jsx @@ -23,7 +23,7 @@ const messages = defineMessages({ reblog_private: { id: 'status.reblog_private', defaultMessage: 'Boost with original visibility' }, cancel_reblog_private: { id: 'status.cancel_reblog_private', defaultMessage: 'Unboost' }, cannot_reblog: { id: 'status.cannot_reblog', defaultMessage: 'This post cannot be boosted' }, - favourite: { id: 'status.favourite', defaultMessage: 'Favourite' }, + favourite: { id: 'status.favourite', defaultMessage: 'Favorite' }, replyConfirm: { id: 'confirmations.reply.confirm', defaultMessage: 'Reply' }, replyMessage: { id: 'confirmations.reply.message', defaultMessage: 'Replying now will overwrite the message you are currently composing. Are you sure you want to proceed?' }, open: { id: 'status.open', defaultMessage: 'Expand this status' }, diff --git a/app/javascript/mastodon/features/status/components/action_bar.jsx b/app/javascript/mastodon/features/status/components/action_bar.jsx index 0bacf29654f29e..198afd29df1e1d 100644 --- a/app/javascript/mastodon/features/status/components/action_bar.jsx +++ b/app/javascript/mastodon/features/status/components/action_bar.jsx @@ -25,7 +25,7 @@ const messages = defineMessages({ reblog_private: { id: 'status.reblog_private', defaultMessage: 'Boost with original visibility' }, cancel_reblog_private: { id: 'status.cancel_reblog_private', defaultMessage: 'Unboost' }, cannot_reblog: { id: 'status.cannot_reblog', defaultMessage: 'This post cannot be boosted' }, - favourite: { id: 'status.favourite', defaultMessage: 'Favourite' }, + favourite: { id: 'status.favourite', defaultMessage: 'Favorite' }, bookmark: { id: 'status.bookmark', defaultMessage: 'Bookmark' }, more: { id: 'status.more', defaultMessage: 'More' }, mute: { id: 'status.mute', defaultMessage: 'Mute @{name}' }, diff --git a/app/javascript/mastodon/features/status/containers/detailed_status_container.js b/app/javascript/mastodon/features/status/containers/detailed_status_container.js index 57d5f61c855e13..3e1f8d4d299237 100644 --- a/app/javascript/mastodon/features/status/containers/detailed_status_container.js +++ b/app/javascript/mastodon/features/status/containers/detailed_status_container.js @@ -36,7 +36,7 @@ const messages = defineMessages({ deleteConfirm: { id: 'confirmations.delete.confirm', defaultMessage: 'Delete' }, deleteMessage: { id: 'confirmations.delete.message', defaultMessage: 'Are you sure you want to delete this status?' }, redraftConfirm: { id: 'confirmations.redraft.confirm', defaultMessage: 'Delete & redraft' }, - redraftMessage: { id: 'confirmations.redraft.message', defaultMessage: 'Are you sure you want to delete this status and re-draft it? Favourites and boosts will be lost, and replies to the original post will be orphaned.' }, + redraftMessage: { id: 'confirmations.redraft.message', defaultMessage: 'Are you sure you want to delete this status and re-draft it? Favorites and boosts will be lost, and replies to the original post will be orphaned.' }, replyConfirm: { id: 'confirmations.reply.confirm', defaultMessage: 'Reply' }, replyMessage: { id: 'confirmations.reply.message', defaultMessage: 'Replying now will overwrite the message you are currently composing. Are you sure you want to proceed?' }, }); diff --git a/app/javascript/mastodon/features/status/index.jsx b/app/javascript/mastodon/features/status/index.jsx index 4f58c7d2fd0b2e..1713d94eb5e148 100644 --- a/app/javascript/mastodon/features/status/index.jsx +++ b/app/javascript/mastodon/features/status/index.jsx @@ -72,7 +72,7 @@ const messages = defineMessages({ deleteConfirm: { id: 'confirmations.delete.confirm', defaultMessage: 'Delete' }, deleteMessage: { id: 'confirmations.delete.message', defaultMessage: 'Are you sure you want to delete this status?' }, redraftConfirm: { id: 'confirmations.redraft.confirm', defaultMessage: 'Delete & redraft' }, - redraftMessage: { id: 'confirmations.redraft.message', defaultMessage: 'Are you sure you want to delete this status and re-draft it? Favourites and boosts will be lost, and replies to the original post will be orphaned.' }, + redraftMessage: { id: 'confirmations.redraft.message', defaultMessage: 'Are you sure you want to delete this status and re-draft it? Favorites and boosts will be lost, and replies to the original post will be orphaned.' }, revealAll: { id: 'status.show_more_all', defaultMessage: 'Show more for all' }, hideAll: { id: 'status.show_less_all', defaultMessage: 'Show less for all' }, statusTitleWithAttachments: { id: 'status.title.with_attachments', defaultMessage: '{user} posted {attachmentCount, plural, one {an attachment} other {# attachments}}' }, diff --git a/app/javascript/mastodon/features/ui/components/navigation_panel.jsx b/app/javascript/mastodon/features/ui/components/navigation_panel.jsx index ab5c78246f9eaa..d36abf8f17bba1 100644 --- a/app/javascript/mastodon/features/ui/components/navigation_panel.jsx +++ b/app/javascript/mastodon/features/ui/components/navigation_panel.jsx @@ -23,7 +23,7 @@ const messages = defineMessages({ explore: { id: 'explore.title', defaultMessage: 'Explore' }, firehose: { id: 'column.firehose', defaultMessage: 'Live feeds' }, direct: { id: 'navigation_bar.direct', defaultMessage: 'Private mentions' }, - favourites: { id: 'navigation_bar.favourites', defaultMessage: 'Favourites' }, + favourites: { id: 'navigation_bar.favourites', defaultMessage: 'Favorites' }, bookmarks: { id: 'navigation_bar.bookmarks', defaultMessage: 'Bookmarks' }, lists: { id: 'navigation_bar.lists', defaultMessage: 'Lists' }, preferences: { id: 'navigation_bar.preferences', defaultMessage: 'Preferences' }, diff --git a/app/javascript/mastodon/features/ui/components/sign_in_banner.jsx b/app/javascript/mastodon/features/ui/components/sign_in_banner.jsx index abae34f7fd9ca0..e44b797692e914 100644 --- a/app/javascript/mastodon/features/ui/components/sign_in_banner.jsx +++ b/app/javascript/mastodon/features/ui/components/sign_in_banner.jsx @@ -35,7 +35,7 @@ const SignInBanner = () => { return (
-

+

{signupButton}
diff --git a/app/javascript/mastodon/locales/en.json b/app/javascript/mastodon/locales/en.json index 8c85cb7bea9c55..c62f485534e272 100644 --- a/app/javascript/mastodon/locales/en.json +++ b/app/javascript/mastodon/locales/en.json @@ -113,7 +113,7 @@ "column.direct": "Private mentions", "column.directory": "Browse profiles", "column.domain_blocks": "Blocked domains", - "column.favourites": "Favourites", + "column.favourites": "Favorites", "column.firehose": "Live feeds", "column.follow_requests": "Follow requests", "column.home": "Home", @@ -181,7 +181,7 @@ "confirmations.mute.explanation": "This will hide posts from them and posts mentioning them, but it will still allow them to see your posts and follow you.", "confirmations.mute.message": "Are you sure you want to mute {name}?", "confirmations.redraft.confirm": "Delete & redraft", - "confirmations.redraft.message": "Are you sure you want to delete this post and re-draft it? Favourites and boosts will be lost, and replies to the original post will be orphaned.", + "confirmations.redraft.message": "Are you sure you want to delete this post and re-draft it? Favorites and boosts will be lost, and replies to the original post will be orphaned.", "confirmations.reply.confirm": "Reply", "confirmations.reply.message": "Replying now will overwrite the message you are currently composing. Are you sure you want to proceed?", "confirmations.unfollow.confirm": "Unfollow", @@ -202,7 +202,7 @@ "dismissable_banner.community_timeline": "These are the most recent public posts from people whose accounts are hosted by {domain}.", "dismissable_banner.dismiss": "Dismiss", "dismissable_banner.explore_links": "These are news stories being shared the most on the social web today. Newer news stories posted by more different people are ranked higher.", - "dismissable_banner.explore_statuses": "These are posts from across the social web that are gaining traction today. Newer posts with more boosts and favourites are ranked higher.", + "dismissable_banner.explore_statuses": "These are posts from across the social web that are gaining traction today. Newer posts with more boosts and favorites are ranked higher.", "dismissable_banner.explore_tags": "These are hashtags that are gaining traction on the social web today. Hashtags that are used by more different people are ranked higher.", "dismissable_banner.public_timeline": "These are the most recent public posts from people on the social web that people on {domain} follow.", "embed.instructions": "Embed this post on your website by copying the code below.", @@ -231,8 +231,8 @@ "empty_column.direct": "You don't have any private mentions yet. When you send or receive one, it will show up here.", "empty_column.domain_blocks": "There are no blocked domains yet.", "empty_column.explore_statuses": "Nothing is trending right now. Check back later!", - "empty_column.favourited_statuses": "You don't have any favourite posts yet. When you favourite one, it will show up here.", - "empty_column.favourites": "No one has favourited this post yet. When someone does, they will show up here.", + "empty_column.favourited_statuses": "You don't have any favorite posts yet. When you favorite one, it will show up here.", + "empty_column.favourites": "No one has favorited this post yet. When someone does, they will show up here.", "empty_column.follow_requests": "You don't have any follow requests yet. When you receive one, it will show up here.", "empty_column.followed_tags": "You have not followed any hashtags yet. When you do, they will show up here.", "empty_column.hashtag": "There is nothing in this hashtag yet.", @@ -307,15 +307,15 @@ "home.explore_prompt.title": "This is your home base within Mastodon.", "home.hide_announcements": "Hide announcements", "home.show_announcements": "Show announcements", - "interaction_modal.description.favourite": "With an account on Mastodon, you can favourite this post to let the author know you appreciate it and save it for later.", + "interaction_modal.description.favourite": "With an account on Mastodon, you can favorite this post to let the author know you appreciate it and save it for later.", "interaction_modal.description.follow": "With an account on Mastodon, you can follow {name} to receive their posts in your home feed.", "interaction_modal.description.reblog": "With an account on Mastodon, you can boost this post to share it with your own followers.", "interaction_modal.description.reply": "With an account on Mastodon, you can respond to this post.", "interaction_modal.on_another_server": "On a different server", "interaction_modal.on_this_server": "On this server", - "interaction_modal.other_server_instructions": "Copy and paste this URL into the search field of your favourite Mastodon app or the web interface of your Mastodon server.", + "interaction_modal.other_server_instructions": "Copy and paste this URL into the search field of your favorite Mastodon app or the web interface of your Mastodon server.", "interaction_modal.preamble": "Since Mastodon is decentralized, you can use your existing account hosted by another Mastodon server or compatible platform if you don't have an account on this one.", - "interaction_modal.title.favourite": "Favourite {name}'s post", + "interaction_modal.title.favourite": "Favorite {name}'s post", "interaction_modal.title.follow": "Follow {name}", "interaction_modal.title.reblog": "Boost {name}'s post", "interaction_modal.title.reply": "Reply to {name}'s post", @@ -331,8 +331,8 @@ "keyboard_shortcuts.direct": "to open private mentions column", "keyboard_shortcuts.down": "Move down in the list", "keyboard_shortcuts.enter": "Open post", - "keyboard_shortcuts.favourite": "Favourite post", - "keyboard_shortcuts.favourites": "Open favourites list", + "keyboard_shortcuts.favourite": "Favorite post", + "keyboard_shortcuts.favourites": "Open favorites list", "keyboard_shortcuts.federated": "Open federated timeline", "keyboard_shortcuts.heading": "Keyboard shortcuts", "keyboard_shortcuts.home": "Open home timeline", @@ -395,7 +395,7 @@ "navigation_bar.domain_blocks": "Blocked domains", "navigation_bar.edit_profile": "Edit profile", "navigation_bar.explore": "Explore", - "navigation_bar.favourites": "Favourites", + "navigation_bar.favourites": "Favorites", "navigation_bar.filters": "Muted words", "navigation_bar.follow_requests": "Follow requests", "navigation_bar.followed_tags": "Followed hashtags", @@ -412,7 +412,7 @@ "not_signed_in_indicator.not_signed_in": "You need to login to access this resource.", "notification.admin.report": "{name} reported {target}", "notification.admin.sign_up": "{name} signed up", - "notification.favourite": "{name} favourited your post", + "notification.favourite": "{name} favorited your post", "notification.follow": "{name} followed you", "notification.follow_request": "{name} has requested to follow you", "notification.mention": "{name} mentioned you", @@ -426,7 +426,7 @@ "notifications.column_settings.admin.report": "New reports:", "notifications.column_settings.admin.sign_up": "New sign-ups:", "notifications.column_settings.alert": "Desktop notifications", - "notifications.column_settings.favourite": "Favourites:", + "notifications.column_settings.favourite": "Favorites:", "notifications.column_settings.filter_bar.advanced": "Display all categories", "notifications.column_settings.filter_bar.category": "Quick filter bar", "notifications.column_settings.filter_bar.show_bar": "Show filter bar", @@ -444,7 +444,7 @@ "notifications.column_settings.update": "Edits:", "notifications.filter.all": "All", "notifications.filter.boosts": "Boosts", - "notifications.filter.favourites": "Favourites", + "notifications.filter.favourites": "Favourits", "notifications.filter.follows": "Follows", "notifications.filter.mentions": "Mentions", "notifications.filter.polls": "Poll results", @@ -595,7 +595,7 @@ "server_banner.server_stats": "Server stats:", "sign_in_banner.create_account": "Create account", "sign_in_banner.sign_in": "Login", - "sign_in_banner.text": "Login to follow profiles or hashtags, favourite, share and reply to posts. You can also interact from your account on a different server.", + "sign_in_banner.text": "Login to follow profiles or hashtags, favorite, share and reply to posts. You can also interact from your account on a different server.", "status.admin_account": "Open moderation interface for @{name}", "status.admin_domain": "Open moderation interface for {domain}", "status.admin_status": "Open this post in the moderation interface", @@ -612,7 +612,7 @@ "status.edited": "Edited {date}", "status.edited_x_times": "Edited {count, plural, one {{count} time} other {{count} times}}", "status.embed": "Embed", - "status.favourite": "Favourite", + "status.favourite": "Favorite", "status.filter": "Filter this post", "status.filtered": "Filtered", "status.hide": "Hide post", diff --git a/config/locales/doorkeeper.en.yml b/config/locales/doorkeeper.en.yml index a28f91c0e08dba..0432a5e3fb04cc 100644 --- a/config/locales/doorkeeper.en.yml +++ b/config/locales/doorkeeper.en.yml @@ -127,7 +127,7 @@ en: bookmarks: Bookmarks conversations: Conversations crypto: End-to-end encryption - favourites: Favourites + favourites: Favorites filters: Filters follow: Follows, Mutes and Blocks follows: Follows @@ -170,7 +170,7 @@ en: read:accounts: see accounts information read:blocks: see your blocks read:bookmarks: see your bookmarks - read:favourites: see your favourites + read:favourites: see your favorites read:filters: see your filters read:follows: see your follows read:lists: see your lists @@ -184,7 +184,7 @@ en: write:blocks: block accounts and domains write:bookmarks: bookmark posts write:conversations: mute and delete conversations - write:favourites: favourite posts + write:favourites: favorite posts write:filters: create filters write:follows: follow people write:lists: create lists From 296ec6cf57bb4f5cbf152c0083f38b1c96930391 Mon Sep 17 00:00:00 2001 From: Christian Schmidt Date: Fri, 21 Jul 2023 21:12:57 +0200 Subject: [PATCH 22/94] Override default Action Mailer `preview_path` (#26110) --- config/application.rb | 2 ++ 1 file changed, 2 insertions(+) diff --git a/config/application.rb b/config/application.rb index aa0f80cd088f47..6f21efa8db42f1 100644 --- a/config/application.rb +++ b/config/application.rb @@ -192,7 +192,9 @@ class Application < Rails::Application # config.autoload_paths += Dir[Rails.root.join('app', 'api', '*')] config.active_job.queue_adapter = :sidekiq + config.action_mailer.deliver_later_queue_name = 'mailers' + config.action_mailer.preview_path = Rails.root.join('spec', 'mailers', 'previews') # We use our own middleware for this config.public_file_server.enabled = false From 1b4cf0eba0699fa6b033139d4fce9891519c2f85 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=D0=BD=D0=B0=D0=B1?= Date: Fri, 21 Jul 2023 21:13:20 +0200 Subject: [PATCH 23/94] Favourits -> Favorites (#26109) --- app/javascript/mastodon/locales/en.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/app/javascript/mastodon/locales/en.json b/app/javascript/mastodon/locales/en.json index c62f485534e272..cf4e802eb4d9b9 100644 --- a/app/javascript/mastodon/locales/en.json +++ b/app/javascript/mastodon/locales/en.json @@ -444,7 +444,7 @@ "notifications.column_settings.update": "Edits:", "notifications.filter.all": "All", "notifications.filter.boosts": "Boosts", - "notifications.filter.favourites": "Favourits", + "notifications.filter.favourites": "Favorites", "notifications.filter.follows": "Follows", "notifications.filter.mentions": "Mentions", "notifications.filter.polls": "Poll results", From f2c683336bb27bc457b779e5e0c35cc21b2b45af Mon Sep 17 00:00:00 2001 From: Claire Date: Fri, 21 Jul 2023 21:23:14 +0200 Subject: [PATCH 24/94] Bump version to v4.1.5 (#26108) --- CHANGELOG.md | 20 ++++++++++++++++++++ docker-compose.yml | 6 +++--- lib/mastodon/version.rb | 2 +- 3 files changed, 24 insertions(+), 4 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 5383d426b6cd48..c49b1927351932 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -2,6 +2,26 @@ All notable changes to this project will be documented in this file. +## [4.1.5] - 2023-07-21 + +### Added + +- Add check preventing Sidekiq workers from running with Makara configured ([ClearlyClaire](https://github.com/mastodon/mastodon/pull/25850)) + +### Changed + +- Change request timeout handling to use a longer deadline ([ClearlyClaire](https://github.com/mastodon/mastodon/pull/26055)) + +### Fixed + +- Fix moderation interface for remote instances with a .zip TLD ([ClearlyClaire](https://github.com/mastodon/mastodon/pull/25885)) +- Fix remote accounts being possibly persisted to database with incomplete protocol values ([ClearlyClaire](https://github.com/mastodon/mastodon/pull/25886)) +- Fix trending publishers table not rendering correctly on narrow screens ([vmstan](https://github.com/mastodon/mastodon/pull/25945)) + +### Security + +- Fix CSP headers being unintentionally wide ([ClearlyClaire](https://github.com/mastodon/mastodon/pull/26105)) + ## [4.1.4] - 2023-07-07 ### Fixed diff --git a/docker-compose.yml b/docker-compose.yml index f603c2f7e2e6a8..e3fa9ae1e2e507 100644 --- a/docker-compose.yml +++ b/docker-compose.yml @@ -56,7 +56,7 @@ services: web: build: . - image: ghcr.io/mastodon/mastodon + image: ghcr.io/mastodon/mastodon:v4.1.5 restart: always env_file: .env.production command: bash -c "rm -f /mastodon/tmp/pids/server.pid; bundle exec rails s -p 3000" @@ -77,7 +77,7 @@ services: streaming: build: . - image: ghcr.io/mastodon/mastodon + image: ghcr.io/mastodon/mastodon:v4.1.5 restart: always env_file: .env.production command: node ./streaming @@ -95,7 +95,7 @@ services: sidekiq: build: . - image: ghcr.io/mastodon/mastodon + image: ghcr.io/mastodon/mastodon:v4.1.5 restart: always env_file: .env.production command: bundle exec sidekiq diff --git a/lib/mastodon/version.rb b/lib/mastodon/version.rb index cbec893e02f7fe..17af0c051ab386 100644 --- a/lib/mastodon/version.rb +++ b/lib/mastodon/version.rb @@ -13,7 +13,7 @@ def minor end def patch - 4 + 5 end def flags From 0078e7e760a94d30ff02e0fc6db11b01311b8b90 Mon Sep 17 00:00:00 2001 From: Claire Date: Sat, 22 Jul 2023 20:42:31 +0200 Subject: [PATCH 25/94] Fix incorrect connect timeout in outgoing requests (#26116) --- app/lib/request.rb | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/app/lib/request.rb b/app/lib/request.rb index 7386015d6dd069..c7aafbd4fc9ca9 100644 --- a/app/lib/request.rb +++ b/app/lib/request.rb @@ -284,11 +284,11 @@ def open(host, *args) end until socks.empty? - _, available_socks, = IO.select(nil, socks, nil, Request::TIMEOUT[:connect]) + _, available_socks, = IO.select(nil, socks, nil, Request::TIMEOUT[:connect_timeout]) if available_socks.nil? socks.each(&:close) - raise HTTP::TimeoutError, "Connect timed out after #{Request::TIMEOUT[:connect]} seconds" + raise HTTP::TimeoutError, "Connect timed out after #{Request::TIMEOUT[:connect_timeout]} seconds" end available_socks.each do |sock| From db310f383d5730f3245f5f9f361ad09d63b0a3ef Mon Sep 17 00:00:00 2001 From: mogaminsk Date: Sun, 23 Jul 2023 22:57:57 +0900 Subject: [PATCH 26/94] Fix missing translation strings for importing lists (#26120) --- config/i18n-tasks.yml | 4 ++-- config/locales/en.yml | 4 ++++ 2 files changed, 6 insertions(+), 2 deletions(-) diff --git a/config/i18n-tasks.yml b/config/i18n-tasks.yml index b3bb336ed27bd6..d0677b80fb41e0 100644 --- a/config/i18n-tasks.yml +++ b/config/i18n-tasks.yml @@ -65,8 +65,8 @@ ignore_unused: - 'move_handler.carry_{mutes,blocks}_over_text' - 'admin_mailer.*.subject' - 'notification_mailer.*' - - 'imports.overwrite_preambles.{following,blocking,muting,domain_blocking,bookmarks}_html' - - 'imports.preambles.{following,blocking,muting,domain_blocking,bookmarks}_html' + - 'imports.overwrite_preambles.{following,blocking,muting,domain_blocking,bookmarks,lists}_html' + - 'imports.preambles.{following,blocking,muting,domain_blocking,bookmarks,lists}_html' - 'mail_subscriptions.unsubscribe.emails.*' - 'preferences.other' # some locales are missing other keys, therefore leading i18n-tasks to detect `preferences` as plural and not finding use diff --git a/config/locales/en.yml b/config/locales/en.yml index 9e54c2d8dd7506..d31da272841867 100644 --- a/config/locales/en.yml +++ b/config/locales/en.yml @@ -1278,12 +1278,14 @@ en: bookmarks_html: You are about to replace your bookmarks with up to %{total_items} posts from %{filename}. domain_blocking_html: You are about to replace your domain block list with up to %{total_items} domains from %{filename}. following_html: You are about to follow up to %{total_items} accounts from %{filename} and stop following anyone else. + lists_html: You are about to replace your lists with contents of %{filename}. Up to %{total_items} accounts will be added to new lists. muting_html: You are about to replace your list of muted accounts with up to %{total_items} accounts from %{filename}. preambles: blocking_html: You are about to block up to %{total_items} accounts from %{filename}. bookmarks_html: You are about to add up to %{total_items} posts from %{filename} to your bookmarks. domain_blocking_html: You are about to block up to %{total_items} domains from %{filename}. following_html: You are about to follow up to %{total_items} accounts from %{filename}. + lists_html: You are about to add up to %{total_items} accounts from %{filename} to your lists. New lists will be created if there is no list to add to. muting_html: You are about to mute up to %{total_items} accounts from %{filename}. preface: You can import data that you have exported from another server, such as a list of the people you are following or blocking. recent_imports: Recent imports @@ -1300,6 +1302,7 @@ en: bookmarks: Importing bookmarks domain_blocking: Importing blocked domains following: Importing followed accounts + lists: Importing lists muting: Importing muted accounts type: Import type type_groups: @@ -1310,6 +1313,7 @@ en: bookmarks: Bookmarks domain_blocking: Domain blocking list following: Following list + lists: Lists muting: Muting list upload: Upload invites: From 3abe0fc5c850bf6ac625e168b33d92641a534700 Mon Sep 17 00:00:00 2001 From: Christian Schmidt Date: Sun, 23 Jul 2023 15:58:19 +0200 Subject: [PATCH 27/94] Use valid email address for first account (#26114) --- db/seeds/04_admin.rb | 1 + 1 file changed, 1 insertion(+) diff --git a/db/seeds/04_admin.rb b/db/seeds/04_admin.rb index ec0287a45453fa..c9b0369c9f3281 100644 --- a/db/seeds/04_admin.rb +++ b/db/seeds/04_admin.rb @@ -2,6 +2,7 @@ if Rails.env.development? domain = ENV['LOCAL_DOMAIN'] || Rails.configuration.x.local_domain + domain = domain.gsub(/:\d+$/, '') admin = Account.where(username: 'admin').first_or_initialize(username: 'admin') admin.save(validate: false) From 67016dd29db51e640544806e972d0031829a09e3 Mon Sep 17 00:00:00 2001 From: Nick Schonning Date: Sun, 23 Jul 2023 11:48:16 -0400 Subject: [PATCH 28/94] Update haml-lint 0.49.1 (#26118) --- Gemfile.lock | 2 +- app/views/admin/announcements/index.html.haml | 1 - app/views/admin/custom_emojis/index.html.haml | 1 - app/views/admin/ip_blocks/index.html.haml | 1 - app/views/admin/relays/index.html.haml | 1 - app/views/admin/roles/edit.html.haml | 1 - app/views/settings/applications/show.html.haml | 1 - 7 files changed, 1 insertion(+), 7 deletions(-) diff --git a/Gemfile.lock b/Gemfile.lock index 63a9388ee2ca5d..bc4f3522bb3041 100644 --- a/Gemfile.lock +++ b/Gemfile.lock @@ -307,7 +307,7 @@ GEM activesupport (>= 5.1) haml (>= 4.0.6) railties (>= 5.1) - haml_lint (0.48.0) + haml_lint (0.49.1) haml (>= 4.0, < 6.2) parallel (~> 1.10) rainbow diff --git a/app/views/admin/announcements/index.html.haml b/app/views/admin/announcements/index.html.haml index ce520f59d3ac0e..72227b04577a04 100644 --- a/app/views/admin/announcements/index.html.haml +++ b/app/views/admin/announcements/index.html.haml @@ -19,4 +19,3 @@ = render partial: 'announcement', collection: @announcements = paginate @announcements - diff --git a/app/views/admin/custom_emojis/index.html.haml b/app/views/admin/custom_emojis/index.html.haml index 6ded4b43326dc5..eb41563ee631ef 100644 --- a/app/views/admin/custom_emojis/index.html.haml +++ b/app/views/admin/custom_emojis/index.html.haml @@ -85,4 +85,3 @@ = render partial: 'custom_emoji', collection: @custom_emojis, locals: { f: f } = paginate @custom_emojis - diff --git a/app/views/admin/ip_blocks/index.html.haml b/app/views/admin/ip_blocks/index.html.haml index d5b983de9ec079..675c0aaad0e86d 100644 --- a/app/views/admin/ip_blocks/index.html.haml +++ b/app/views/admin/ip_blocks/index.html.haml @@ -25,4 +25,3 @@ = render partial: 'ip_block', collection: @ip_blocks, locals: { f: f } = paginate @ip_blocks - diff --git a/app/views/admin/relays/index.html.haml b/app/views/admin/relays/index.html.haml index 1636a53f8521df..47f8d6f360416a 100644 --- a/app/views/admin/relays/index.html.haml +++ b/app/views/admin/relays/index.html.haml @@ -17,4 +17,3 @@ %th %tbody = render @relays - diff --git a/app/views/admin/roles/edit.html.haml b/app/views/admin/roles/edit.html.haml index 659ccb8dceb06e..5688b69b1fdee0 100644 --- a/app/views/admin/roles/edit.html.haml +++ b/app/views/admin/roles/edit.html.haml @@ -5,4 +5,3 @@ = link_to t('admin.roles.delete'), admin_role_path(@role), method: :delete, data: { confirm: t('admin.accounts.are_you_sure') }, class: 'button button--destructive' if can?(:destroy, @role) = render partial: 'form' - diff --git a/app/views/settings/applications/show.html.haml b/app/views/settings/applications/show.html.haml index 466a8ba340c61c..be1d13eae6fdf7 100644 --- a/app/views/settings/applications/show.html.haml +++ b/app/views/settings/applications/show.html.haml @@ -28,4 +28,3 @@ .actions = f.button :button, t('generic.save_changes'), type: :submit - From cfd50f30bb5dda4dd90e1ad01f3e62c99135c36f Mon Sep 17 00:00:00 2001 From: Eugen Rochko Date: Sun, 23 Jul 2023 17:55:13 +0200 Subject: [PATCH 29/94] Fix focus and hover styles in web UI (#26125) --- .../intersection_observer_article.jsx | 4 +- .../styles/mastodon/components.scss | 74 ++++++++++--------- 2 files changed, 42 insertions(+), 36 deletions(-) diff --git a/app/javascript/mastodon/components/intersection_observer_article.jsx b/app/javascript/mastodon/components/intersection_observer_article.jsx index 7b03ffb88e7d49..8efa969f9bff56 100644 --- a/app/javascript/mastodon/components/intersection_observer_article.jsx +++ b/app/javascript/mastodon/components/intersection_observer_article.jsx @@ -114,7 +114,7 @@ export default class IntersectionObserverArticle extends Component { aria-setsize={listLength} style={{ height: `${this.height || cachedHeight}px`, opacity: 0, overflow: 'hidden' }} data-id={id} - tabIndex={0} + tabIndex={-1} > {children && cloneElement(children, { hidden: true })} @@ -122,7 +122,7 @@ export default class IntersectionObserverArticle extends Component { } return ( -
+
{children && cloneElement(children, { hidden: false })}
); diff --git a/app/javascript/styles/mastodon/components.scss b/app/javascript/styles/mastodon/components.scss index d08cb28038c9b8..bb0febaaeff104 100644 --- a/app/javascript/styles/mastodon/components.scss +++ b/app/javascript/styles/mastodon/components.scss @@ -74,7 +74,7 @@ background-color: $ui-button-focus-background-color; } - &:focus { + &:focus-visible { outline: $ui-button-icon-focus-outline; } @@ -191,8 +191,6 @@ border-radius: 4px; background: transparent; cursor: pointer; - transition: all 100ms ease-out; - transition-property: background-color, color; text-decoration: none; a { @@ -203,11 +201,11 @@ &:hover, &:active, &:focus { - color: lighten($action-button-color, 20%); - background-color: $ui-button-icon-hover-background-color; + color: lighten($action-button-color, 7%); + background-color: rgba($action-button-color, 0.15); } - &:focus { + &:focus-visible { outline: $ui-button-icon-focus-outline; } @@ -224,10 +222,10 @@ &:active, &:focus { color: darken($lighter-text-color, 7%); - background-color: $ui-button-icon-hover-background-color; + background-color: rgba($lighter-text-color, 0.15); } - &:focus { + &:focus-visible { outline: $ui-button-icon-focus-outline; } @@ -239,6 +237,13 @@ &.active { color: $highlight-text-color; + &:hover, + &:active, + &:focus { + color: $highlight-text-color; + background-color: transparent; + } + &.disabled { color: lighten($highlight-text-color, 13%); } @@ -283,19 +288,15 @@ font-size: 11px; padding: 0 3px; line-height: 27px; - transition: all 100ms ease-in; - transition-property: background-color, color; &:hover, &:active, &:focus { color: darken($lighter-text-color, 7%); - background-color: $ui-button-icon-hover-background-color; - transition: all 200ms ease-out; - transition-property: background-color, color; + background-color: rgba($lighter-text-color, 0.15); } - &:focus { + &:focus-visible { outline: $ui-button-icon-focus-outline; } @@ -307,6 +308,13 @@ &.active { color: $highlight-text-color; + + &:hover, + &:active, + &:focus { + color: $highlight-text-color; + background-color: transparent; + } } } @@ -1975,7 +1983,7 @@ a.account__display-name { font-size: inherit; line-height: inherit; - &:focus { + &:focus-visible { outline: 1px dotted; } } @@ -3838,7 +3846,6 @@ a.status-card.compact:hover { position: relative; z-index: 2; outline: 0; - overflow: hidden; & > button { margin: 0; @@ -3853,6 +3860,10 @@ a.status-card.compact:hover { overflow: hidden; white-space: nowrap; flex: 1; + + &:focus-visible { + outline: $ui-button-icon-focus-outline; + } } & > .column-header__back-button { @@ -3893,10 +3904,18 @@ a.status-card.compact:hover { font-size: 16px; padding: 0 15px; + &:last-child { + border-start-end-radius: 4px; + } + &:hover { color: lighten($darker-text-color, 4%); } + &:focus-visible { + outline: $ui-button-icon-focus-outline; + } + &.active { color: $primary-text-color; background: lighten($ui-base-color, 4%); @@ -4542,7 +4561,7 @@ a.status-card.compact:hover { .emoji-picker-dropdown__menu { background: $simple-background-color; position: relative; - box-shadow: 4px 4px 6px rgba($base-shadow-color, 0.4); + box-shadow: var(--dropdown-shadow); border-radius: 4px; margin-top: 5px; z-index: 2; @@ -4720,7 +4739,7 @@ a.status-card.compact:hover { } } - &:focus { + &:focus-visible { img { outline: $ui-button-icon-focus-outline; } @@ -4734,7 +4753,7 @@ a.status-card.compact:hover { .privacy-dropdown__dropdown { background: $simple-background-color; - box-shadow: 2px 4px 15px rgba($base-shadow-color, 0.4); + box-shadow: var(--dropdown-shadow); border-radius: 4px; overflow: hidden; z-index: 2; @@ -4811,19 +4830,6 @@ a.status-card.compact:hover { .privacy-dropdown__value { background: $simple-background-color; border-radius: 4px 4px 0 0; - box-shadow: 0 -4px 4px rgba($base-shadow-color, 0.1); - - .icon-button { - transition: none; - } - - &.active { - background: $ui-highlight-color; - - .icon-button { - color: $primary-text-color; - } - } } &.top .privacy-dropdown__value { @@ -4832,14 +4838,14 @@ a.status-card.compact:hover { .privacy-dropdown__dropdown { display: block; - box-shadow: 2px 4px 6px rgba($base-shadow-color, 0.1); + box-shadow: var(--dropdown-shadow); } } .language-dropdown { &__dropdown { background: $simple-background-color; - box-shadow: 2px 4px 15px rgba($base-shadow-color, 0.4); + box-shadow: var(--dropdown-shadow); border-radius: 4px; overflow: hidden; z-index: 2; From 5e8cbb5f82ab0df0de80539650a6e55d7cf7a3a5 Mon Sep 17 00:00:00 2001 From: Eugen Rochko Date: Sun, 23 Jul 2023 17:55:20 +0200 Subject: [PATCH 30/94] Remove back button from bookmarks, favourites and lists screens in web UI (#26126) --- app/javascript/mastodon/features/bookmarked_statuses/index.jsx | 1 - app/javascript/mastodon/features/favourited_statuses/index.jsx | 1 - app/javascript/mastodon/features/lists/index.jsx | 2 +- 3 files changed, 1 insertion(+), 3 deletions(-) diff --git a/app/javascript/mastodon/features/bookmarked_statuses/index.jsx b/app/javascript/mastodon/features/bookmarked_statuses/index.jsx index 936dee12e351e9..b0c90a43026739 100644 --- a/app/javascript/mastodon/features/bookmarked_statuses/index.jsx +++ b/app/javascript/mastodon/features/bookmarked_statuses/index.jsx @@ -86,7 +86,6 @@ class Bookmarks extends ImmutablePureComponent { onClick={this.handleHeaderClick} pinned={pinned} multiColumn={multiColumn} - showBackButton /> - + From 4d01d1a1eeef7a851b77def9c5bfc2ce4d7a271c Mon Sep 17 00:00:00 2001 From: Eugen Rochko Date: Mon, 24 Jul 2023 13:46:55 +0200 Subject: [PATCH 31/94] Remove 16:9 cropping from web UI (#26132) --- .../mastodon/components/media_gallery.jsx | 15 +- .../picture_in_picture_placeholder.jsx | 5 +- app/javascript/mastodon/components/status.jsx | 50 +++-- .../status/components/detailed_status.jsx | 28 ++- .../features/ui/components/media_modal.jsx | 1 + .../features/ui/components/video_modal.jsx | 1 + .../mastodon/features/video/index.jsx | 176 +++++++++--------- app/javascript/mastodon/initial_state.js | 2 - .../styles/mastodon/components.scss | 23 +-- app/models/concerns/has_user_settings.rb | 4 - app/models/user_settings.rb | 1 - app/serializers/initial_state_serializer.rb | 2 - .../preferences/appearance/show.html.haml | 5 - config/locales/an.yml | 1 - config/locales/ar.yml | 1 - config/locales/ast.yml | 1 - config/locales/be.yml | 1 - config/locales/bg.yml | 1 - config/locales/ca.yml | 1 - config/locales/ckb.yml | 1 - config/locales/co.yml | 1 - config/locales/cs.yml | 1 - config/locales/cy.yml | 1 - config/locales/da.yml | 1 - config/locales/de.yml | 1 - config/locales/el.yml | 1 - config/locales/en-GB.yml | 1 - config/locales/en.yml | 1 - config/locales/eo.yml | 1 - config/locales/es-AR.yml | 1 - config/locales/es-MX.yml | 1 - config/locales/es.yml | 1 - config/locales/et.yml | 1 - config/locales/eu.yml | 1 - config/locales/fa.yml | 1 - config/locales/fi.yml | 1 - config/locales/fo.yml | 1 - config/locales/fr-QC.yml | 1 - config/locales/fr.yml | 1 - config/locales/fy.yml | 1 - config/locales/gd.yml | 1 - config/locales/gl.yml | 1 - config/locales/he.yml | 1 - config/locales/hu.yml | 1 - config/locales/id.yml | 1 - config/locales/io.yml | 1 - config/locales/is.yml | 1 - config/locales/it.yml | 1 - config/locales/ja.yml | 1 - config/locales/kk.yml | 1 - config/locales/ko.yml | 1 - config/locales/ku.yml | 1 - config/locales/lv.yml | 1 - config/locales/my.yml | 1 - config/locales/nl.yml | 1 - config/locales/nn.yml | 1 - config/locales/no.yml | 1 - config/locales/oc.yml | 1 - config/locales/pl.yml | 1 - config/locales/pt-BR.yml | 1 - config/locales/pt-PT.yml | 1 - config/locales/ro.yml | 1 - config/locales/ru.yml | 1 - config/locales/sc.yml | 1 - config/locales/sco.yml | 1 - config/locales/si.yml | 1 - config/locales/simple_form.an.yml | 1 - config/locales/simple_form.ar.yml | 1 - config/locales/simple_form.ast.yml | 1 - config/locales/simple_form.be.yml | 1 - config/locales/simple_form.bg.yml | 1 - config/locales/simple_form.ca.yml | 1 - config/locales/simple_form.ckb.yml | 1 - config/locales/simple_form.co.yml | 1 - config/locales/simple_form.cs.yml | 1 - config/locales/simple_form.cy.yml | 1 - config/locales/simple_form.da.yml | 1 - config/locales/simple_form.de.yml | 1 - config/locales/simple_form.el.yml | 1 - config/locales/simple_form.en-GB.yml | 1 - config/locales/simple_form.en.yml | 1 - config/locales/simple_form.eo.yml | 1 - config/locales/simple_form.es-AR.yml | 1 - config/locales/simple_form.es-MX.yml | 1 - config/locales/simple_form.es.yml | 1 - config/locales/simple_form.et.yml | 1 - config/locales/simple_form.eu.yml | 1 - config/locales/simple_form.fa.yml | 1 - config/locales/simple_form.fi.yml | 1 - config/locales/simple_form.fo.yml | 1 - config/locales/simple_form.fr-QC.yml | 1 - config/locales/simple_form.fr.yml | 1 - config/locales/simple_form.fy.yml | 1 - config/locales/simple_form.gd.yml | 1 - config/locales/simple_form.gl.yml | 1 - config/locales/simple_form.he.yml | 1 - config/locales/simple_form.hu.yml | 1 - config/locales/simple_form.hy.yml | 1 - config/locales/simple_form.id.yml | 1 - config/locales/simple_form.io.yml | 1 - config/locales/simple_form.is.yml | 1 - config/locales/simple_form.it.yml | 1 - config/locales/simple_form.ja.yml | 1 - config/locales/simple_form.kk.yml | 1 - config/locales/simple_form.ko.yml | 1 - config/locales/simple_form.ku.yml | 1 - config/locales/simple_form.lv.yml | 1 - config/locales/simple_form.my.yml | 1 - config/locales/simple_form.nl.yml | 1 - config/locales/simple_form.nn.yml | 1 - config/locales/simple_form.no.yml | 1 - config/locales/simple_form.oc.yml | 1 - config/locales/simple_form.pl.yml | 1 - config/locales/simple_form.pt-BR.yml | 1 - config/locales/simple_form.pt-PT.yml | 1 - config/locales/simple_form.ro.yml | 1 - config/locales/simple_form.ru.yml | 1 - config/locales/simple_form.sc.yml | 1 - config/locales/simple_form.sco.yml | 1 - config/locales/simple_form.si.yml | 1 - config/locales/simple_form.sk.yml | 1 - config/locales/simple_form.sl.yml | 1 - config/locales/simple_form.sq.yml | 1 - config/locales/simple_form.sr-Latn.yml | 1 - config/locales/simple_form.sr.yml | 1 - config/locales/simple_form.sv.yml | 1 - config/locales/simple_form.th.yml | 1 - config/locales/simple_form.tr.yml | 1 - config/locales/simple_form.uk.yml | 1 - config/locales/simple_form.vi.yml | 1 - config/locales/simple_form.zh-CN.yml | 1 - config/locales/simple_form.zh-HK.yml | 1 - config/locales/simple_form.zh-TW.yml | 1 - config/locales/sk.yml | 1 - config/locales/sl.yml | 1 - config/locales/sq.yml | 1 - config/locales/sr-Latn.yml | 1 - config/locales/sr.yml | 1 - config/locales/sv.yml | 1 - config/locales/th.yml | 1 - config/locales/tr.yml | 1 - config/locales/uk.yml | 1 - config/locales/vi.yml | 1 - config/locales/zh-CN.yml | 1 - config/locales/zh-HK.yml | 1 - config/locales/zh-TW.yml | 1 - 146 files changed, 160 insertions(+), 286 deletions(-) diff --git a/app/javascript/mastodon/components/media_gallery.jsx b/app/javascript/mastodon/components/media_gallery.jsx index e3c0065c95b0a1..0b633a5b4082e6 100644 --- a/app/javascript/mastodon/components/media_gallery.jsx +++ b/app/javascript/mastodon/components/media_gallery.jsx @@ -12,7 +12,7 @@ import { debounce } from 'lodash'; import { Blurhash } from 'mastodon/components/blurhash'; -import { autoPlayGif, cropImages, displayMedia, useBlurhash } from '../initial_state'; +import { autoPlayGif, displayMedia, useBlurhash } from '../initial_state'; import { IconButton } from './icon_button'; @@ -209,7 +209,6 @@ class MediaGallery extends PureComponent { static propTypes = { sensitive: PropTypes.bool, - standalone: PropTypes.bool, media: ImmutablePropTypes.list.isRequired, lang: PropTypes.string, size: PropTypes.object, @@ -223,10 +222,6 @@ class MediaGallery extends PureComponent { onToggleVisibility: PropTypes.func, }; - static defaultProps = { - standalone: false, - }; - state = { visible: this.props.visible !== undefined ? this.props.visible : (displayMedia !== 'hide_all' && !this.props.sensitive || displayMedia === 'show_all'), width: this.props.defaultWidth, @@ -295,7 +290,7 @@ class MediaGallery extends PureComponent { } render () { - const { media, lang, intl, sensitive, defaultWidth, standalone, autoplay } = this.props; + const { media, lang, intl, sensitive, defaultWidth, autoplay } = this.props; const { visible } = this.state; const width = this.state.width || defaultWidth; @@ -303,16 +298,16 @@ class MediaGallery extends PureComponent { const style = {}; - if (this.isFullSizeEligible() && (standalone || !cropImages)) { + if (this.isFullSizeEligible()) { style.aspectRatio = `${this.props.media.getIn([0, 'meta', 'small', 'aspect'])}`; } else { - style.aspectRatio = '16 / 9'; + style.aspectRatio = '3 / 2'; } const size = media.take(4).size; const uncached = media.every(attachment => attachment.get('type') === 'unknown'); - if (standalone && this.isFullSizeEligible()) { + if (this.isFullSizeEligible()) { children = ; } else { children = media.take(4).map((attachment, i) => ); diff --git a/app/javascript/mastodon/components/picture_in_picture_placeholder.jsx b/app/javascript/mastodon/components/picture_in_picture_placeholder.jsx index 756a97722483b7..c65bd494f358ae 100644 --- a/app/javascript/mastodon/components/picture_in_picture_placeholder.jsx +++ b/app/javascript/mastodon/components/picture_in_picture_placeholder.jsx @@ -12,6 +12,7 @@ class PictureInPicturePlaceholder extends PureComponent { static propTypes = { dispatch: PropTypes.func.isRequired, + aspectRatio: PropTypes.string, }; handleClick = () => { @@ -20,8 +21,10 @@ class PictureInPicturePlaceholder extends PureComponent { }; render () { + const { aspectRatio } = this.props; + return ( -
+
diff --git a/app/javascript/mastodon/components/status.jsx b/app/javascript/mastodon/components/status.jsx index 8f188a638c3d10..37951d57828633 100644 --- a/app/javascript/mastodon/components/status.jsx +++ b/app/javascript/mastodon/components/status.jsx @@ -19,7 +19,6 @@ import Bundle from '../features/ui/components/bundle'; import { MediaGallery, Video, Audio } from '../features/ui/util/async-components'; import { displayMedia } from '../initial_state'; -import AttachmentList from './attachment_list'; import { Avatar } from './avatar'; import { AvatarOverlay } from './avatar_overlay'; import { DisplayName } from './display_name'; @@ -191,17 +190,35 @@ class Status extends ImmutablePureComponent { this.props.onTranslate(this._properStatus()); }; - renderLoadingMediaGallery () { - return
; - } + getAttachmentAspectRatio () { + const attachments = this._properStatus().get('media_attachments'); - renderLoadingVideoPlayer () { - return
; + if (attachments.getIn([0, 'type']) === 'video') { + return `${attachments.getIn([0, 'meta', 'original', 'width'])} / ${attachments.getIn([0, 'meta', 'original', 'height'])}`; + } else if (attachments.getIn([0, 'type']) === 'audio') { + return '16 / 9'; + } else { + return (attachments.size === 1 && attachments.getIn([0, 'meta', 'small', 'aspect'])) ? attachments.getIn([0, 'meta', 'small', 'aspect']) : '3 / 2' + } } - renderLoadingAudioPlayer () { - return
; - } + renderLoadingMediaGallery = () => { + return ( +
+ ); + }; + + renderLoadingVideoPlayer = () => { + return ( +
+ ); + }; + + renderLoadingAudioPlayer = () => { + return ( +
+ ); + }; handleOpenVideo = (options) => { const status = this._properStatus(); @@ -426,18 +443,11 @@ class Status extends ImmutablePureComponent { } if (pictureInPicture.get('inUse')) { - media = ; + media = ; } else if (status.get('media_attachments').size > 0) { const language = status.getIn(['translation', 'language']) || status.get('language'); - if (this.props.muted) { - media = ( - - ); - } else if (status.getIn(['media_attachments', 0, 'type']) === 'audio') { + if (status.getIn(['media_attachments', 0, 'type']) === 'audio') { const attachment = status.getIn(['media_attachments', 0]); const description = attachment.getIn(['translation', 'description']) || attachment.get('description'); @@ -475,11 +485,11 @@ class Status extends ImmutablePureComponent { ); } - } else if (status.get('spoiler_text').length === 0 && status.get('card') && !this.props.muted) { + } else if (status.get('spoiler_text').length === 0 && status.get('card')) { media = ( ; + media = ; } else if (status.get('media_attachments').size > 0) { if (status.getIn(['media_attachments', 0, 'type']) === 'audio') { const attachment = status.getIn(['media_attachments', 0]); @@ -167,13 +189,13 @@ class DetailedStatus extends ImmutablePureComponent {