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 26599fcc7b..6cb38fcc23 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 f1f1ea872e..286c53d834 100644 --- a/app/helpers/statuses_helper.rb +++ b/app/helpers/statuses_helper.rb @@ -65,33 +65,6 @@ module StatusesHelper 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 afeb55fafd..bf51b5ff7d 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 c07eefdeb0..d643c556b6 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 062421a6fd..538b040203 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 ca84b0e9f9..712f0bacdb 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 a21af0b7ee..8c530cedb1 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 0e79acbfb7..f1d9d11904 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 9655627e7a..fc82484f42 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 f52ea312e0..ad0af9a3d0 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 d4197debd4..ebd7ab6649 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 74bf33b0d3..b32a0c69f2 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 25360a65d3..be0c2737d5 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 192a367ef1..da41e7ac58 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 606607b241..56dcd3da64 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 7a38c0e7b5..024be1551b 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 b6a1003d87..1f06ad078b 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 83ba4b0408..526525eab0 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 159ea141e3..16b6882703 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 e4f9b47076..5fe0ef4f77 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 e6d1e87ad6..a733189f41 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 85ce2a6cbf..b9ddeaed0e 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 cb110b75c8..9d5508dcf3 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 2b6bd17a43..0cf19a6636 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 c3f9cd2dba..ae7cb3cdaf 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 71c1b4bad8..f9ec015c74 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 05a0df9155..e11cc10b30 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 2f6cb826f4..056433a721 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 91b977be11..a64d8edc04 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 b9dd6e191d..77d41e0919 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 61dfe46f93..acb0868cf4 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 c0bace8c38..7ff820c296 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 d1ae49dcb1..abde828b33 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 b51fc795e1..ead8feb8f3 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 3b6d81ad0a..a35c8efc62 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 28f7bc4a8d..10b5ae3d7f 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 83f01b4751..b924217af5 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 437d150c3e..5eb453cc94 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 11cb5e1590..1873fdaee5 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 74a4b59ab3..4306321e97 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 1703b9f4de..ad73707c26 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 54c146579e..14a8584e70 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 ccc80747ea..59e412b90d 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 62b07ca606..74fd7b3a84 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 fdd284d607..a38c9407d7 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 7263241ead..1e9b5a28e0 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 cb80611d79..7c639c6340 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 1c97675e9e..8732d3f2b9 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 b6cee2333e..a74b7d62ca 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 81b2ef3185..e9e6c70cc4 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 634ba94ec2..b47c1f4300 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 78df226358..3c192dd3e6 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 a7dc4ac1d5..05151bc5f7 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 ea544a1b26..7ab60e588c 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 93908ca1ee..b867245628 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 5bbae3efc5..5f4b57e296 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 dd783aafcc..b38596cd1f 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 f8a5d2bff8..379f1ecd90 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 121a7d9095..587e7d390c 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 75d0bc64dc..fe698c0629 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 00142f0c4c..bbbdd5d258 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 09ef5c0dfd..4922303e12 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 a8b5c44a11..974728a058 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 6b74ec50fb..2838d86489 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 cc0197394c..2f6e3551d8 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 6655eaafdb..7994029c2f 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 4dd587d359..3c055392b8 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 f2a82a479b..132e9468b7 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 655f011c92..5836d21bfb 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 71a85eebfc..2ceadc9b0f 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 1718ae6be8..71b76c8934 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 fdbd602e78..b0df7108fe 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 f241c102d7..7a64be31ed 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 910ec36733..8f7c7a5ce6 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 354b20e027..37023eede7 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 0565329cf6..349970cd47 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 b7824ca604..c67e1f3f2b 100644 --- a/spec/helpers/statuses_helper_spec.rb +++ b/spec/helpers/statuses_helper_spec.rb @@ -114,129 +114,4 @@ describe StatusesHelper do 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 2e21ce6a06..f3428e3df4 100644 --- a/app/controllers/api/v1/statuses/favourites_controller.rb +++ b/app/controllers/api/v1/statuses/favourites_controller.rb @@ -17,13 +17,16 @@ class Api::V1::Statuses::FavouritesController < Api::BaseController 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 e3769437b7..3ca6231178 100644 --- a/app/controllers/api/v1/statuses/reblogs_controller.rb +++ b/app/controllers/api/v1/statuses/reblogs_controller.rb @@ -24,15 +24,18 @@ class Api::V1::Statuses::ReblogsController < Api::BaseController 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 3c3d3d7114..683fe848f7 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 50d1fb31bd..5d53040fb2 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 @@ class StatusRelationshipsPresenter @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 e0b8f32a68..d32621541a 100644 --- a/app/serializers/rest/status_serializer.rb +++ b/app/serializers/rest/status_serializer.rb @@ -81,49 +81,57 @@ class REST::StatusSerializer < ActiveModel::Serializer 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 @@ class REST::StatusSerializer < ActiveModel::Serializer 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 6eac02b232..16ce95dc22 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 @@ describe Api::V1::Statuses::ReblogsController do 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 021b8806ed..ac5e86f297 100644 --- a/spec/requests/api/v1/statuses/favourites_spec.rb +++ b/spec/requests/api/v1/statuses/favourites_spec.rb @@ -77,6 +77,12 @@ RSpec.describe 'Favourites' do 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 @@ RSpec.describe 'Favourites' do 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 @@ RSpec.describe 'Favourites' do 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 0746970664..fcd10c5f9b 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 a75746355a..63a9388ee2 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 281219186f..5f9d7e7c48 100644 --- a/app/helpers/application_helper.rb +++ b/app/helpers/application_helper.rb @@ -235,6 +235,6 @@ module ApplicationHelper 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 adc9adcc31..4cc9c204db 100644 --- a/config/initializers/content_security_policy.rb +++ b/config/initializers/content_security_policy.rb @@ -15,6 +15,7 @@ assets_host ||= host_to_url(base_host) 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 f2da410dbe..12d8d69341 100644 --- a/config/initializers/paperclip.rb +++ b/config/initializers/paperclip.rb @@ -131,6 +131,26 @@ elsif ENV['SWIFT_ENABLED'] == 'true' 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 420f0aa693..55ccde72f5 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 6cb38fcc23..7c476be801 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 4ea3d2c45e..c85253ac08 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 21870af446..b537eb48ca 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 526525eab0..9e54c2d8dd 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 3efb97cb18..636c2d4257 100644 --- a/spec/mailers/notification_mailer_spec.rb +++ b/spec/mailers/notification_mailer_spec.rb @@ -8,19 +8,6 @@ RSpec.describe NotificationMailer do 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 3c42a2bb7a..5affa66e07 100644 --- a/spec/mailers/user_mailer_spec.rb +++ b/spec/mailers/user_mailer_spec.rb @@ -5,19 +5,6 @@ require 'rails_helper' 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 0000000000..213e873b4e --- /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 7c476be801..6d2aa0641f 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 248718a73d..e94847d674 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 f4deb5b6ff..4f5077d831 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 960d548f06..32fb99b772 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 ed22a8147a..f446d0ca6d 100644 --- a/spec/services/resolve_account_service_spec.rb +++ b/spec/services/resolve_account_service_spec.rb @@ -209,11 +209,6 @@ RSpec.describe ResolveAccountService, type: :service do 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 aa2cb395db..1edc15972d 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 8d49527b39..c116fab733 100644 --- a/app/services/activitypub/process_account_service.rb +++ b/app/services/activitypub/process_account_service.rb @@ -79,7 +79,7 @@ class ActivityPub::ProcessAccountService < BaseService 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 6ffbba5849..534b8ae843 100644 --- a/spec/fabricators/account_fabricator.rb +++ b/spec/fabricators/account_fabricator.rb @@ -13,5 +13,6 @@ Fabricator(:account) do 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 7c6c20968f..e5d85656a2 100644 --- a/spec/lib/account_reach_finder_spec.rb +++ b/spec/lib/account_reach_finder_spec.rb @@ -5,15 +5,15 @@ require 'rails_helper' 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 365861bcd8..8ad892975d 100644 --- a/spec/lib/activitypub/activity/announce_spec.rb +++ b/spec/lib/activitypub/activity/announce_spec.rb @@ -5,7 +5,7 @@ require 'rails_helper' 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 @@ RSpec.describe ActivityPub::Activity::Announce do 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 f77279c028..87e96d2d1b 100644 --- a/spec/lib/activitypub/activity/update_spec.rb +++ b/spec/lib/activitypub/activity/update_spec.rb @@ -5,22 +5,38 @@ require 'rails_helper' 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 @@ RSpec.describe ActivityPub::Activity::Update do '@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 @@ RSpec.describe ActivityPub::Activity::Update do 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 @@ RSpec.describe ActivityPub::Activity::Update do 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 619d6df124..6a6ad1a706 100644 --- a/spec/lib/activitypub/linked_data_signature_spec.rb +++ b/spec/lib/activitypub/linked_data_signature_spec.rb @@ -7,7 +7,7 @@ RSpec.describe ActivityPub::LinkedDataSignature do 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 596e91e954..2bff125a6a 100644 --- a/spec/lib/activitypub/tag_manager_spec.rb +++ b/spec/lib/activitypub/tag_manager_spec.rb @@ -139,7 +139,7 @@ RSpec.describe ActivityPub::TagManager do 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 d473a819e7..cf593349a7 100644 --- a/spec/models/account_spec.rb +++ b/spec/models/account_spec.rb @@ -963,12 +963,12 @@ RSpec.describe Account do 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 61e5c3c9b6..68ab491e4e 100644 --- a/spec/services/delete_account_service_spec.rb +++ b/spec/services/delete_account_service_spec.rb @@ -65,8 +65,8 @@ RSpec.describe DeleteAccountService, type: :service do 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 @@ RSpec.describe DeleteAccountService, type: :service do 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 99761b6c73..7991aa6ef1 100644 --- a/spec/services/resolve_url_service_spec.rb +++ b/spec/services/resolve_url_service_spec.rb @@ -8,7 +8,7 @@ describe ResolveURLService, type: :service do 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 @@ describe ResolveURLService, type: :service do 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 f9206b7ea2..7cdbc873e3 100644 --- a/spec/services/suspend_account_service_spec.rb +++ b/spec/services/suspend_account_service_spec.rb @@ -44,8 +44,8 @@ RSpec.describe SuspendAccountService, type: :service do 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 7ef2630aeb..3c13d5bd39 100644 --- a/spec/services/unsuspend_account_service_spec.rb +++ b/spec/services/unsuspend_account_service_spec.rb @@ -38,8 +38,8 @@ RSpec.describe UnsuspendAccountService, type: :service do 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 947acab3bc..0bdbf63903 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 @@ describe ActivityPub::DistributePollUpdateWorker do 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 06d6ac7383..d8803f6b8a 100644 --- a/spec/workers/activitypub/distribution_worker_spec.rb +++ b/spec/workers/activitypub/distribution_worker_spec.rb @@ -6,7 +6,7 @@ describe ActivityPub::DistributionWorker do 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 @@ describe ActivityPub::DistributionWorker do 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 91ef3c4b92..ff4d049a26 100644 --- a/spec/workers/activitypub/fetch_replies_worker_spec.rb +++ b/spec/workers/activitypub/fetch_replies_worker_spec.rb @@ -5,7 +5,7 @@ require 'rails_helper' 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 4df6b2f161..b8601f78cf 100644 --- a/spec/workers/activitypub/move_distribution_worker_spec.rb +++ b/spec/workers/activitypub/move_distribution_worker_spec.rb @@ -6,8 +6,8 @@ describe ActivityPub::MoveDistributionWorker do 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 cf55a461d8..c500bac959 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 @@ describe ActivityPub::StatusUpdateDistributionWorker do 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 7b1e6ff543..d0eeda43bf 100644 --- a/spec/workers/activitypub/update_distribution_worker_spec.rb +++ b/spec/workers/activitypub/update_distribution_worker_spec.rb @@ -6,7 +6,7 @@ describe ActivityPub::UpdateDistributionWorker do 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 22f51f7bdf..0000000000 --- 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 0000000000..20e27d103c --- /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 0000000000..49d5f57209 --- /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 f2d7af4961..4fe2f18bfb 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 53e1fd7932..d8aa522d80 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 9a1c3dc0bf..e9ca541691 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 bb6ae74c33..3b69282d53 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 8f46d76313..3872e3d86d 100644 --- a/lib/webpacker/helper_extensions.rb +++ b/lib/webpacker/helper_extensions.rb @@ -13,7 +13,14 @@ module Webpacker::HelperExtensions 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 23e0af3a2a..efff5cdad5 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 32fb99b772..71e8623ec5 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 4de69c1ead..fb442e2c2d 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 0000000000..ba88655f16 --- /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 9e884caefd..9c040f6e47 100644 --- a/app/workers/scheduler/vacuum_scheduler.rb +++ b/app/workers/scheduler/vacuum_scheduler.rb @@ -22,6 +22,7 @@ class Scheduler::VacuumScheduler preview_cards_vacuum, backups_vacuum, access_tokens_vacuum, + applications_vacuum, feeds_vacuum, imports_vacuum, ] @@ -55,6 +56,10 @@ class Scheduler::VacuumScheduler 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 0000000000..d30311ab13 --- /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 e5f91071e9..4f58c7d2fd 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 349c363f14..b829b1a90b 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 @@ Rails.application.config.after_initialize do 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 | 19 +++-- app/javascript/styles/mastodon/basics.scss | 15 +++- .../styles/mastodon/components.scss | 83 +++++-------------- app/javascript/styles/mastodon/variables.scss | 4 + 5 files changed, 50 insertions(+), 73 deletions(-) diff --git a/app/javascript/mastodon/components/dropdown_menu.jsx b/app/javascript/mastodon/components/dropdown_menu.jsx index 0416df5d45..fd66310e85 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 ff00c797c8..234c703f23 100644 --- a/app/javascript/styles/mastodon/basics.scss +++ b/app/javascript/styles/mastodon/basics.scss @@ -161,13 +161,20 @@ body { } } +a { + &:focus { + border-radius: 4px; + outline: $ui-button-icon-focus-outline; + } + + &:focus:not(:focus-visible) { + outline: none; + } +} + button { font-family: inherit; cursor: pointer; - - &:focus { - outline: none; - } } .app-holder { diff --git a/app/javascript/styles/mastodon/components.scss b/app/javascript/styles/mastodon/components.scss index beff07daa4..d08cb28038 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 68db9d5fc0..e89dd5d3ab 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 e6dd8040e9..36397857f0 100644 --- a/app/serializers/activitypub/actor_serializer.rb +++ b/app/serializers/activitypub/actor_serializer.rb @@ -99,7 +99,7 @@ class ActivityPub::ActorSerializer < ActivityPub::Serializer 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 4cc9c204db..98c4f541f3 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 0000000000..7eb27d61d6 --- /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 d30311ab13..57a222aafc 100644 --- a/spec/lib/vacuum/applications_vacuum_spec.rb +++ b/spec/lib/vacuum/applications_vacuum_spec.rb @@ -6,43 +6,43 @@ 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!(: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 b713c98c68..5d441c10c2 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 8b3d8b46b7..536765e137 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 ececb86c08..aea7317577 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 ac84014e48..7d119215e6 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 043492fb89..f32a4a5368 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 57911c3a14..bfde78708e 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 85fd6f1209..f0cd70d7a1 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 0f17a0896a..4722c130e7 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 ce4c6015b0..3dc21f7e8e 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 7f8e88f080..09154f257a 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 92cdfa57b6..773fe9a8f8 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 044e6969e6..43c5e85cef 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 c167d93dce..a368962b93 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 0bacf29654..198afd29df 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 57d5f61c85..3e1f8d4d29 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 4f58c7d2fd..1713d94eb5 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 ab5c78246f..d36abf8f17 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 abae34f7fd..e44b797692 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 8c85cb7bea..c62f485534 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 a28f91c0e0..0432a5e3fb 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 aa0f80cd08..6f21efa8db 100644 --- a/config/application.rb +++ b/config/application.rb @@ -192,7 +192,9 @@ module Mastodon # 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 c62f485534..cf4e802eb4 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 5383d426b6..c49b192735 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 f603c2f7e2..e3fa9ae1e2 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 cbec893e02..17af0c051a 100644 --- a/lib/mastodon/version.rb +++ b/lib/mastodon/version.rb @@ -13,7 +13,7 @@ module Mastodon 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 7386015d6d..c7aafbd4fc 100644 --- a/app/lib/request.rb +++ b/app/lib/request.rb @@ -284,11 +284,11 @@ class Request 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 b3bb336ed2..d0677b80fb 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 9e54c2d8dd..d31da27284 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 ec0287a454..c9b0369c9f 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 63a9388ee2..bc4f3522bb 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 ce520f59d3..72227b0457 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 6ded4b4332..eb41563ee6 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 d5b983de9e..675c0aaad0 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 1636a53f85..47f8d6f360 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 659ccb8dce..5688b69b1f 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 466a8ba340..be1d13eae6 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 7b03ffb88e..8efa969f9b 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 d08cb28038..bb0febaaef 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 936dee12e3..b0c90a4302 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 | 172 +++++++++--------- 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, 158 insertions(+), 284 deletions(-) diff --git a/app/javascript/mastodon/components/media_gallery.jsx b/app/javascript/mastodon/components/media_gallery.jsx index e3c0065c95..0b633a5b40 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 756a977224..c65bd494f3 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 8f188a638c..37951d5782 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'); + + 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' + } } - renderLoadingVideoPlayer () { - return
; - } + renderLoadingMediaGallery = () => { + return ( +
+ ); + }; - renderLoadingAudioPlayer () { - 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 {