Merge branch 'master' into glitch-soc/merge-upstream

Conflicts:
	app/views/layouts/application.html.haml

Edited:
        app/helpers/application_helper.rb
        app/views/admin/domain_blocks/new.html.haml

Conflict wasn't really one, just two changes too close to one another.
Edition was to adapt the class names for themes to class names for
skins and flavours.

Also edited app/views/admin/domain_blocks/new.html.haml to strip the
duplicate admin pack inclusion thing.
main
Thibaut Girka 6 years ago
commit 36393e1d2b

@ -136,8 +136,8 @@ SMTP_FROM_ADDRESS=notifications@${APP_NAME}.nanoapp.io
# Defaults to 60 seconds. Set to 0 to disable
# SWIFT_CACHE_TTL=
# Optional alias for S3 if you want to use Cloudfront or Cloudflare in front
# S3_CLOUDFRONT_HOST=
# Optional alias for S3 (e.g. to serve files on a custom domain, possibly using Cloudfront or Cloudflare)
# S3_ALIAS_HOST=
# Streaming API integration
# STREAMING_API_BASE_URL=

@ -134,8 +134,8 @@ SMTP_FROM_ADDRESS=notifications@example.com
# Defaults to 60 seconds. Set to 0 to disable
# SWIFT_CACHE_TTL=
# Optional alias for S3 if you want to use Cloudfront or Cloudflare in front
# S3_CLOUDFRONT_HOST=
# Optional alias for S3 (e.g. to serve files on a custom domain, possibly using Cloudfront or Cloudflare)
# S3_ALIAS_HOST=
# Streaming API integration
# STREAMING_API_BASE_URL=

@ -41,7 +41,7 @@ gem 'omniauth-cas', '~> 1.1'
gem 'omniauth-saml', '~> 1.10'
gem 'omniauth', '~> 1.2'
gem 'doorkeeper', '~> 4.4'
gem 'doorkeeper', '~> 5.0'
gem 'fast_blank', '~> 1.0'
gem 'fastimage'
gem 'goldfinger', '~> 2.1'

@ -174,14 +174,14 @@ GEM
devise (~> 4.0)
railties (< 5.3)
rotp (~> 2.0)
devise_pam_authenticatable2 (9.1.0)
devise_pam_authenticatable2 (9.1.1)
devise (>= 4.0.0)
rpam2 (~> 4.0)
diff-lcs (1.3)
docile (1.3.0)
domain_name (0.5.20180417)
unf (>= 0.0.5, < 1.0.0)
doorkeeper (4.4.2)
doorkeeper (5.0.0)
railties (>= 4.2)
dotenv (2.2.2)
dotenv-rails (2.2.2)
@ -672,7 +672,7 @@ DEPENDENCIES
devise (~> 4.4)
devise-two-factor (~> 3.0)
devise_pam_authenticatable2 (~> 9.1)
doorkeeper (~> 4.4)
doorkeeper (~> 5.0)
dotenv-rails (~> 2.2, < 2.3)
fabrication (~> 2.20)
faker (~> 1.8)

@ -27,11 +27,6 @@ module ApplicationHelper
Setting.open_deletion
end
def add_rtl_body_class(other_classes)
other_classes = "#{other_classes} rtl" if locale_direction == 'rtl'
other_classes
end
def locale_direction
if [:ar, :fa, :he].include?(I18n.locale)
'rtl'
@ -77,4 +72,14 @@ module ApplicationHelper
def react_component(name, props = {})
content_tag(:div, nil, data: { component: name.to_s.camelcase, props: Oj.dump(props) })
end
def body_classes
output = (@body_classes || '').split(' ')
output << "flavour-#{current_flavour.parameterize}"
output << "skin-#{current_skin.parameterize}"
output << 'system-font' if current_account&.user&.setting_system_font_ui
output << current_account&.user&.setting_reduce_motion ? 'reduce-motion' : 'no-reduce-motion'
output << 'rtl' if locale_direction == 'rtl'
output.reject(&:blank?).join(' ')
end
end

@ -41,3 +41,10 @@ delegate(document, '.media-spoiler-hide-button', 'click', () => {
element.click();
});
});
delegate(document, '#domain_block_severity', 'change', ({ target }) => {
const rejectMediaDiv = document.querySelector('.input.with_label.domain_block_reject_media');
if (rejectMediaDiv) {
rejectMediaDiv.style.display = (target.value === 'suspend') ? 'none' : 'block';
}
});

@ -50,6 +50,7 @@ export default class ExtendedVideoPlayer extends React.PureComponent {
role='button'
tabIndex='0'
aria-label={alt}
title={alt}
muted={muted}
controls={controls}
loop={!controls}

@ -154,6 +154,7 @@ class Item extends React.PureComponent {
<video
className='media-gallery__item-gifv-thumbnail'
aria-label={attachment.get('description')}
title={attachment.get('description')}
role='application'
src={attachment.get('url')}
onClick={this.handleClick}

@ -230,6 +230,7 @@ export default class Status extends ImmutablePureComponent {
<Component
preview={video.get('preview_url')}
src={video.get('url')}
alt={video.get('description')}
width={239}
height={110}
inline

@ -34,7 +34,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? You will lose all replies, boosts and favourites to it.' },
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.' },
blockConfirm: { id: 'confirmations.block.confirm', defaultMessage: 'Block' },
});

@ -104,7 +104,9 @@ export default class Header extends ImmutablePureComponent {
}
if (me !== account.get('id')) {
if (account.getIn(['relationship', 'requested'])) {
if (!account.get('relationship')) { // Wait until the relationship is loaded
actionBtn = '';
} else if (account.getIn(['relationship', 'requested'])) {
actionBtn = (
<div className='account--action-button'>
<IconButton size={26} active icon='hourglass' title={intl.formatMessage(messages.requested)} onClick={this.props.onFollow} />

@ -7,7 +7,7 @@ import ImmutablePureComponent from 'react-immutable-pure-component';
import ImmutablePropTypes from 'react-immutable-proptypes';
const messages = defineMessages({
upload: { id: 'upload_button.label', defaultMessage: 'Add media' },
upload: { id: 'upload_button.label', defaultMessage: 'Add media (JPEG, PNG, GIF, WebM, MP4)' },
});
const makeMapStateToProps = () => {

@ -36,6 +36,7 @@ export default class StatusCheckBox extends React.PureComponent {
<Component
preview={video.get('preview_url')}
src={video.get('url')}
alt={video.get('description')}
width={239}
height={110}
inline

@ -60,6 +60,7 @@ export default class DetailedStatus extends ImmutablePureComponent {
<Video
preview={video.get('preview_url')}
src={video.get('url')}
alt={video.get('description')}
width={300}
height={150}
inline

@ -49,7 +49,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? You will lose all replies, boosts and favourites to it.' },
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.' },
blockConfirm: { id: 'confirmations.block.confirm', defaultMessage: 'Block' },
revealAll: { id: 'status.show_more_all', defaultMessage: 'Show more for all' },
hideAll: { id: 'status.show_less_all', defaultMessage: 'Show less for all' },

@ -315,6 +315,7 @@ export default class Video extends React.PureComponent {
role='button'
tabIndex='0'
aria-label={alt}
title={alt}
width={width}
height={height}
onClick={this.togglePlay}

@ -165,6 +165,7 @@
"navigation_bar.apps": "Mobile apps",
"navigation_bar.blocks": "الحسابات المحجوبة",
"navigation_bar.community_timeline": "الخيط العام المحلي",
"navigation_bar.compose": "Compose new toot",
"navigation_bar.direct": "الرسائل المباشِرة",
"navigation_bar.discover": "إكتشف",
"navigation_bar.domain_blocks": "النطاقات المخفية",
@ -258,6 +259,7 @@
"status.cancel_reblog_private": "إلغاء الترقية",
"status.cannot_reblog": "تعذرت ترقية هذا المنشور",
"status.delete": "إحذف",
"status.detailed_status": "Detailed conversation view",
"status.direct": "رسالة خاصة إلى @{name}",
"status.embed": "إدماج",
"status.favourite": "أضف إلى المفضلة",

@ -165,6 +165,7 @@
"navigation_bar.apps": "Mobile apps",
"navigation_bar.blocks": "Blocked users",
"navigation_bar.community_timeline": "Local timeline",
"navigation_bar.compose": "Compose new toot",
"navigation_bar.direct": "Direct messages",
"navigation_bar.discover": "Discover",
"navigation_bar.domain_blocks": "Hidden domains",
@ -258,6 +259,7 @@
"status.cancel_reblog_private": "Unboost",
"status.cannot_reblog": "This post cannot be boosted",
"status.delete": "Delete",
"status.detailed_status": "Detailed conversation view",
"status.direct": "Direct message @{name}",
"status.embed": "Embed",
"status.favourite": "Favourite",

@ -165,6 +165,7 @@
"navigation_bar.apps": "Mobile apps",
"navigation_bar.blocks": "Blocked users",
"navigation_bar.community_timeline": "Local timeline",
"navigation_bar.compose": "Compose new toot",
"navigation_bar.direct": "Direct messages",
"navigation_bar.discover": "Discover",
"navigation_bar.domain_blocks": "Hidden domains",
@ -258,6 +259,7 @@
"status.cancel_reblog_private": "Unboost",
"status.cannot_reblog": "This post cannot be boosted",
"status.delete": "Изтриване",
"status.detailed_status": "Detailed conversation view",
"status.direct": "Direct message @{name}",
"status.embed": "Embed",
"status.favourite": "Предпочитани",

@ -165,6 +165,7 @@
"navigation_bar.apps": "Mobile apps",
"navigation_bar.blocks": "Usuaris bloquejats",
"navigation_bar.community_timeline": "Línia de temps Local",
"navigation_bar.compose": "Compose new toot",
"navigation_bar.direct": "Missatges directes",
"navigation_bar.discover": "Descobreix",
"navigation_bar.domain_blocks": "Dominis ocults",
@ -258,6 +259,7 @@
"status.cancel_reblog_private": "Desfer l'impuls",
"status.cannot_reblog": "Aquesta publicació no pot ser retootejada",
"status.delete": "Esborrar",
"status.detailed_status": "Detailed conversation view",
"status.direct": "Missatge directe @{name}",
"status.embed": "Incrustar",
"status.favourite": "Favorit",

@ -165,6 +165,7 @@
"navigation_bar.apps": "Mobile apps",
"navigation_bar.blocks": "Utilizatori bluccati",
"navigation_bar.community_timeline": "Linea pubblica lucale",
"navigation_bar.compose": "Compose new toot",
"navigation_bar.direct": "Missaghji diretti",
"navigation_bar.discover": "Scopre",
"navigation_bar.domain_blocks": "Duminii piattati",
@ -258,6 +259,7 @@
"status.cancel_reblog_private": "Ùn sparte più",
"status.cannot_reblog": "Stu statutu ùn pò micca esse spartutu",
"status.delete": "Toglie",
"status.detailed_status": "Detailed conversation view",
"status.direct": "Mandà un missaghju @{name}",
"status.embed": "Integrà",
"status.favourite": "Aghjunghje à i favuriti",

@ -162,9 +162,10 @@
"missing_indicator.label": "Nenalezeno",
"missing_indicator.sublabel": "Tento zdroj se nepodařilo najít",
"mute_modal.hide_notifications": "Skrýt oznámení před tímto uživatelem?",
"navigation_bar.apps": "Mobile apps",
"navigation_bar.apps": "Mobilní aplikace",
"navigation_bar.blocks": "Blokovaní uživatelé",
"navigation_bar.community_timeline": "Místní časová osa",
"navigation_bar.compose": "Compose new toot",
"navigation_bar.direct": "Přímé zprávy",
"navigation_bar.discover": "Objevujte",
"navigation_bar.domain_blocks": "Skryté domény",
@ -258,6 +259,7 @@
"status.cancel_reblog_private": "Zrušit boost",
"status.cannot_reblog": "Tento příspěvek nemůže být boostnutý",
"status.delete": "Delete",
"status.detailed_status": "Detailed conversation view",
"status.direct": "Poslat přímou zprávu uživateli @{name}",
"status.embed": "Vložit",
"status.favourite": "Oblíbit",

@ -20,7 +20,7 @@
"account.mute_notifications": "Dæmp notifikationer fra @{name}",
"account.muted": "Dæmpet",
"account.posts": "Trut",
"account.posts_with_replies": "Trut samt svar",
"account.posts_with_replies": "Trut og svar",
"account.report": "Rapporter @{name}",
"account.requested": "Afventer godkendelse. Tryk for at annullere følgeanmodning",
"account.share": "Del @{name}s profil",
@ -51,7 +51,7 @@
"column.lists": "Lister",
"column.mutes": "Dæmpede brugere",
"column.notifications": "Notifikationer",
"column.pins": "Fastgjorte toots",
"column.pins": "Fastgjorte trut",
"column.public": "Fælles tidslinje",
"column_back_button.label": "Tilbage",
"column_header.hide_settings": "Skjul indstillinger",
@ -61,7 +61,7 @@
"column_header.show_settings": "Vis indstillinger",
"column_header.unpin": "Fastgør ikke længere",
"column_subheading.settings": "Indstillinger",
"community.column_settings.media_only": "Kun multimedier",
"community.column_settings.media_only": "Kun medie",
"compose_form.direct_message_warning": "Dette trut vil kun blive sendt til de nævnte brugere.",
"compose_form.direct_message_warning_learn_more": "Lær mere",
"compose_form.hashtag_warning": "Dette trut vil ikke blive vist under noget hashtag da det ikke er listet. Kun offentlige trut kan blive vist under søgninger med hashtags.",
@ -70,8 +70,8 @@
"compose_form.placeholder": "Hvad har du på hjertet?",
"compose_form.publish": "Trut",
"compose_form.publish_loud": "{publish}!",
"compose_form.sensitive.marked": "Multimedie er markeret som værende følsomt",
"compose_form.sensitive.unmarked": "Multimediet er ikke markeret som værende følsomt",
"compose_form.sensitive.marked": "Medie er markeret som værende følsomt",
"compose_form.sensitive.unmarked": "Mediet er ikke markeret som værende følsomt",
"compose_form.spoiler.marked": "Teksten er skjult bag en advarsel",
"compose_form.spoiler.unmarked": "Teksten er ikke skjult",
"compose_form.spoiler_placeholder": "Skriv din advarsel her",
@ -162,9 +162,10 @@
"missing_indicator.label": "Ikke fundet",
"missing_indicator.sublabel": "Denne ressource kunne ikke blive fundet",
"mute_modal.hide_notifications": "Skjul notifikationer fra denne bruger?",
"navigation_bar.apps": "Mobile apps",
"navigation_bar.apps": "Mobil apps",
"navigation_bar.blocks": "Blokerede brugere",
"navigation_bar.community_timeline": "Lokal tidslinje",
"navigation_bar.compose": "Compose new toot",
"navigation_bar.direct": "Direkte beskeder",
"navigation_bar.discover": "Opdag",
"navigation_bar.domain_blocks": "Skjulte domæner",
@ -258,12 +259,13 @@
"status.cancel_reblog_private": "Fremhæv ikke længere",
"status.cannot_reblog": "Denne post kan ikke fremhæves",
"status.delete": "Slet",
"status.detailed_status": "Detailed conversation view",
"status.direct": "Send direkte besked til @{name}",
"status.embed": "Indlejre",
"status.favourite": "Favorit",
"status.filtered": "Filtreret",
"status.load_more": "Indlæs mere",
"status.media_hidden": "Multimedia skjult",
"status.media_hidden": "Medie skjult",
"status.mention": "Nævn @{name}",
"status.more": "Mere",
"status.mute": "Dæmp @{name}",

@ -165,6 +165,7 @@
"navigation_bar.apps": "Mobile apps",
"navigation_bar.blocks": "Blockierte Profile",
"navigation_bar.community_timeline": "Lokale Zeitleiste",
"navigation_bar.compose": "Compose new toot",
"navigation_bar.direct": "Direktnachrichten",
"navigation_bar.discover": "Entdecken",
"navigation_bar.domain_blocks": "Versteckte Domains",
@ -258,6 +259,7 @@
"status.cancel_reblog_private": "Nicht mehr teilen",
"status.cannot_reblog": "Dieser Beitrag kann nicht geteilt werden",
"status.delete": "Löschen",
"status.detailed_status": "Detailed conversation view",
"status.direct": "Direktnachricht @{name}",
"status.embed": "Einbetten",
"status.favourite": "Favorisieren",

@ -390,7 +390,7 @@
"id": "confirmations.redraft.confirm"
},
{
"defaultMessage": "Are you sure you want to delete this status and re-draft it? You will lose all replies, boosts and favourites to it.",
"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.",
"id": "confirmations.redraft.message"
},
{
@ -1019,6 +1019,10 @@
{
"defaultMessage": "Logout",
"id": "navigation_bar.logout"
},
{
"defaultMessage": "Compose new toot",
"id": "navigation_bar.compose"
}
],
"path": "app/javascript/mastodon/features/compose/index.json"
@ -1636,7 +1640,7 @@
"id": "confirmations.redraft.confirm"
},
{
"defaultMessage": "Are you sure you want to delete this status and re-draft it? You will lose all replies, boosts and favourites to it.",
"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.",
"id": "confirmations.redraft.message"
},
{
@ -1651,6 +1655,10 @@
"defaultMessage": "Show less for all",
"id": "status.show_less_all"
},
{
"defaultMessage": "Detailed conversation view",
"id": "status.detailed_status"
},
{
"defaultMessage": "Are you sure you want to block {name}?",
"id": "confirmations.block.message"

@ -165,6 +165,7 @@
"navigation_bar.apps": "Mobile apps",
"navigation_bar.blocks": "Αποκλεισμένοι χρήστες",
"navigation_bar.community_timeline": "Τοπική ροή",
"navigation_bar.compose": "Compose new toot",
"navigation_bar.direct": "Προσωπικά μηνύματα",
"navigation_bar.discover": "Ανακάλυψη",
"navigation_bar.domain_blocks": "Κρυμμένοι τομείς",
@ -258,6 +259,7 @@
"status.cancel_reblog_private": "Ακύρωσε την προώθηση",
"status.cannot_reblog": "Αυτή η δημοσίευση δεν μπορεί να προωθηθεί",
"status.delete": "Διαγραφή",
"status.detailed_status": "Detailed conversation view",
"status.direct": "Προσωπικό μήνυμα προς @{name}",
"status.embed": "Ενσωμάτωσε",
"status.favourite": "Σημείωσε ως αγαπημένο",

@ -91,7 +91,7 @@
"confirmations.mute.confirm": "Mute",
"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 status and re-draft it? You will lose all replies, boosts and favourites to it.",
"confirmations.redraft.message": "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.",
"confirmations.unfollow.confirm": "Unfollow",
"confirmations.unfollow.message": "Are you sure you want to unfollow {name}?",
"embed.instructions": "Embed this status on your website by copying the code below.",
@ -169,6 +169,7 @@
"navigation_bar.apps": "Mobile apps",
"navigation_bar.blocks": "Blocked users",
"navigation_bar.community_timeline": "Local timeline",
"navigation_bar.compose": "Compose new toot",
"navigation_bar.direct": "Direct messages",
"navigation_bar.discover": "Discover",
"navigation_bar.domain_blocks": "Hidden domains",
@ -263,6 +264,7 @@
"status.cancel_reblog_private": "Unboost",
"status.cannot_reblog": "This post cannot be boosted",
"status.delete": "Delete",
"status.detailed_status": "Detailed conversation view",
"status.direct": "Direct message @{name}",
"status.embed": "Embed",
"status.favourite": "Favourite",
@ -300,7 +302,7 @@
"trends.count_by_accounts": "{count} {rawCount, plural, one {person} other {people}} talking",
"ui.beforeunload": "Your draft will be lost if you leave Mastodon.",
"upload_area.title": "Drag & drop to upload",
"upload_button.label": "Add media",
"upload_button.label": "Add media (JPEG, PNG, GIF, WebM, MP4)",
"upload_form.description": "Describe for the visually impaired",
"upload_form.focus": "Crop",
"upload_form.undo": "Delete",

@ -165,6 +165,7 @@
"navigation_bar.apps": "Mobile apps",
"navigation_bar.blocks": "Blokitaj uzantoj",
"navigation_bar.community_timeline": "Loka tempolinio",
"navigation_bar.compose": "Compose new toot",
"navigation_bar.direct": "Rektaj mesaĝoj",
"navigation_bar.discover": "Esplori",
"navigation_bar.domain_blocks": "Kaŝitaj domajnoj",
@ -258,6 +259,7 @@
"status.cancel_reblog_private": "Eksdiskonigi",
"status.cannot_reblog": "Ĉi tiu mesaĝo ne diskonigeblas",
"status.delete": "Forigi",
"status.detailed_status": "Detailed conversation view",
"status.direct": "Rekte mesaĝi @{name}",
"status.embed": "Enkorpigi",
"status.favourite": "Stelumi",

@ -165,6 +165,7 @@
"navigation_bar.apps": "Mobile apps",
"navigation_bar.blocks": "Usuarios bloqueados",
"navigation_bar.community_timeline": "Historia local",
"navigation_bar.compose": "Compose new toot",
"navigation_bar.direct": "Direct messages",
"navigation_bar.discover": "Discover",
"navigation_bar.domain_blocks": "Hidden domains",
@ -258,6 +259,7 @@
"status.cancel_reblog_private": "Unboost",
"status.cannot_reblog": "Este toot no puede retootearse",
"status.delete": "Borrar",
"status.detailed_status": "Detailed conversation view",
"status.direct": "Direct message @{name}",
"status.embed": "Incrustado",
"status.favourite": "Favorito",

@ -165,6 +165,7 @@
"navigation_bar.apps": "Mobile apps",
"navigation_bar.blocks": "Blokeatutako erabiltzaileak",
"navigation_bar.community_timeline": "Denbora-lerro lokala",
"navigation_bar.compose": "Compose new toot",
"navigation_bar.direct": "Mezu zuzenak",
"navigation_bar.discover": "Aurkitu",
"navigation_bar.domain_blocks": "Ezkutatutako domeinuak",
@ -258,6 +259,7 @@
"status.cancel_reblog_private": "Kendu bultzada",
"status.cannot_reblog": "Mezu honi ezin zaio bultzada eman",
"status.delete": "Ezabatu",
"status.detailed_status": "Detailed conversation view",
"status.direct": "Mezu zuzena @{name}(r)i",
"status.embed": "Txertatu",
"status.favourite": "Gogokoa",

@ -165,6 +165,7 @@
"navigation_bar.apps": "Mobile apps",
"navigation_bar.blocks": "کاربران مسدودشده",
"navigation_bar.community_timeline": "نوشته‌های محلی",
"navigation_bar.compose": "Compose new toot",
"navigation_bar.direct": "پیغام‌های خصوصی",
"navigation_bar.discover": "گشت و گذار",
"navigation_bar.domain_blocks": "دامین‌های پنهان‌شده",
@ -258,6 +259,7 @@
"status.cancel_reblog_private": "حذف بازبوق",
"status.cannot_reblog": "این نوشته را نمی‌شود بازبوقید",
"status.delete": "پاک‌کردن",
"status.detailed_status": "Detailed conversation view",
"status.direct": "پیغام مستقیم به @{name}",
"status.embed": "جاگذاری",
"status.favourite": "پسندیدن",

@ -165,6 +165,7 @@
"navigation_bar.apps": "Mobile apps",
"navigation_bar.blocks": "Estetyt käyttäjät",
"navigation_bar.community_timeline": "Paikallinen aikajana",
"navigation_bar.compose": "Compose new toot",
"navigation_bar.direct": "Viestit",
"navigation_bar.discover": "Discover",
"navigation_bar.domain_blocks": "Piilotetut verkkotunnukset",
@ -258,6 +259,7 @@
"status.cancel_reblog_private": "Peru buustaus",
"status.cannot_reblog": "Tätä julkaisua ei voi buustata",
"status.delete": "Poista",
"status.detailed_status": "Detailed conversation view",
"status.direct": "Viesti käyttäjälle @{name}",
"status.embed": "Upota",
"status.favourite": "Tykkää",

@ -87,7 +87,7 @@
"confirmations.mute.confirm": "Masquer",
"confirmations.mute.message": "Confirmez-vous le masquage de {name}?",
"confirmations.redraft.confirm": "Effacer et ré-écrire",
"confirmations.redraft.message": "Êtes-vous sûr·e de vouloir effacer ce statut pour le ré-écrire? Vous perdrez toutes ses réponses, ses repartages et ses mises en favori.",
"confirmations.redraft.message": "Êtes-vous sûr·e de vouloir effacer ce statut pour le ré-écrire? Ses partages ainsi que ses mises en favori seront perdu·e·s et ses réponses seront orphelines.",
"confirmations.unfollow.confirm": "Ne plus suivre",
"confirmations.unfollow.message": "Voulez-vous arrêter de suivre {name}?",
"embed.instructions": "Intégrez ce statut à votre site en copiant le code ci-dessous.",
@ -162,9 +162,10 @@
"missing_indicator.label": "Non trouvé",
"missing_indicator.sublabel": "Ressource introuvable",
"mute_modal.hide_notifications": "Masquer les notifications de cette personne?",
"navigation_bar.apps": "Mobile apps",
"navigation_bar.apps": "Applications mobiles",
"navigation_bar.blocks": "Comptes bloqués",
"navigation_bar.community_timeline": "Fil public local",
"navigation_bar.compose": "Compose new toot",
"navigation_bar.direct": "Messages directs",
"navigation_bar.discover": "Découvrir",
"navigation_bar.domain_blocks": "Domaines cachés",
@ -258,6 +259,7 @@
"status.cancel_reblog_private": "Dé-booster",
"status.cannot_reblog": "Cette publication ne peut être boostée",
"status.delete": "Effacer",
"status.detailed_status": "Detailed conversation view",
"status.direct": "Envoyer un message direct à @{name}",
"status.embed": "Intégrer",
"status.favourite": "Ajouter aux favoris",

@ -165,6 +165,7 @@
"navigation_bar.apps": "Mobile apps",
"navigation_bar.blocks": "Usuarias bloqueadas",
"navigation_bar.community_timeline": "Liña temporal local",
"navigation_bar.compose": "Compose new toot",
"navigation_bar.direct": "Mensaxes directas",
"navigation_bar.discover": "Discover",
"navigation_bar.domain_blocks": "Dominios agochados",
@ -258,6 +259,7 @@
"status.cancel_reblog_private": "Non promover",
"status.cannot_reblog": "Esta mensaxe non pode ser promovida",
"status.delete": "Eliminar",
"status.detailed_status": "Detailed conversation view",
"status.direct": "Mensaxe directa @{name}",
"status.embed": "Incrustar",
"status.favourite": "Favorita",

@ -165,6 +165,7 @@
"navigation_bar.apps": "Mobile apps",
"navigation_bar.blocks": "חסימות",
"navigation_bar.community_timeline": "ציר זמן מקומי",
"navigation_bar.compose": "Compose new toot",
"navigation_bar.direct": "Direct messages",
"navigation_bar.discover": "Discover",
"navigation_bar.domain_blocks": "Hidden domains",
@ -258,6 +259,7 @@
"status.cancel_reblog_private": "Unboost",
"status.cannot_reblog": "לא ניתן להדהד הודעה זו",
"status.delete": "מחיקה",
"status.detailed_status": "Detailed conversation view",
"status.direct": "Direct message @{name}",
"status.embed": "הטמעה",
"status.favourite": "חיבוב",

@ -165,6 +165,7 @@
"navigation_bar.apps": "Mobile apps",
"navigation_bar.blocks": "Blokirani korisnici",
"navigation_bar.community_timeline": "Lokalni timeline",
"navigation_bar.compose": "Compose new toot",
"navigation_bar.direct": "Direct messages",
"navigation_bar.discover": "Discover",
"navigation_bar.domain_blocks": "Hidden domains",
@ -258,6 +259,7 @@
"status.cancel_reblog_private": "Unboost",
"status.cannot_reblog": "Ovaj post ne može biti boostan",
"status.delete": "Obriši",
"status.detailed_status": "Detailed conversation view",
"status.direct": "Direct message @{name}",
"status.embed": "Embed",
"status.favourite": "Označi omiljenim",

@ -165,6 +165,7 @@
"navigation_bar.apps": "Mobile apps",
"navigation_bar.blocks": "Tiltott felhasználók",
"navigation_bar.community_timeline": "Helyi idővonal",
"navigation_bar.compose": "Compose new toot",
"navigation_bar.direct": "Direct messages",
"navigation_bar.discover": "Discover",
"navigation_bar.domain_blocks": "Hidden domains",
@ -258,6 +259,7 @@
"status.cancel_reblog_private": "Unboost",
"status.cannot_reblog": "Ezen státusz nem rebloggolható",
"status.delete": "Törlés",
"status.detailed_status": "Detailed conversation view",
"status.direct": "Direct message @{name}",
"status.embed": "Beágyaz",
"status.favourite": "Kedvenc",

@ -165,6 +165,7 @@
"navigation_bar.apps": "Mobile apps",
"navigation_bar.blocks": "Արգելափակված օգտատերեր",
"navigation_bar.community_timeline": "Տեղական հոսք",
"navigation_bar.compose": "Compose new toot",
"navigation_bar.direct": "Direct messages",
"navigation_bar.discover": "Discover",
"navigation_bar.domain_blocks": "Hidden domains",
@ -258,6 +259,7 @@
"status.cancel_reblog_private": "Unboost",
"status.cannot_reblog": "Այս թութը չի կարող տարածվել",
"status.delete": "Ջնջել",
"status.detailed_status": "Detailed conversation view",
"status.direct": "Direct message @{name}",
"status.embed": "Ներդնել",
"status.favourite": "Հավանել",

@ -165,6 +165,7 @@
"navigation_bar.apps": "Mobile apps",
"navigation_bar.blocks": "Pengguna diblokir",
"navigation_bar.community_timeline": "Linimasa lokal",
"navigation_bar.compose": "Compose new toot",
"navigation_bar.direct": "Direct messages",
"navigation_bar.discover": "Discover",
"navigation_bar.domain_blocks": "Hidden domains",
@ -258,6 +259,7 @@
"status.cancel_reblog_private": "Unboost",
"status.cannot_reblog": "This post cannot be boosted",
"status.delete": "Hapus",
"status.detailed_status": "Detailed conversation view",
"status.direct": "Direct message @{name}",
"status.embed": "Embed",
"status.favourite": "Difavoritkan",

@ -165,6 +165,7 @@
"navigation_bar.apps": "Mobile apps",
"navigation_bar.blocks": "Blokusita uzeri",
"navigation_bar.community_timeline": "Lokala tempolineo",
"navigation_bar.compose": "Compose new toot",
"navigation_bar.direct": "Direct messages",
"navigation_bar.discover": "Discover",
"navigation_bar.domain_blocks": "Hidden domains",
@ -258,6 +259,7 @@
"status.cancel_reblog_private": "Unboost",
"status.cannot_reblog": "This post cannot be boosted",
"status.delete": "Efacar",
"status.detailed_status": "Detailed conversation view",
"status.direct": "Direct message @{name}",
"status.embed": "Embed",
"status.favourite": "Favorizar",

@ -165,6 +165,7 @@
"navigation_bar.apps": "Mobile apps",
"navigation_bar.blocks": "Utenti bloccati",
"navigation_bar.community_timeline": "Timeline locale",
"navigation_bar.compose": "Compose new toot",
"navigation_bar.direct": "Messaggi diretti",
"navigation_bar.discover": "Scopri",
"navigation_bar.domain_blocks": "Domini nascosti",
@ -258,6 +259,7 @@
"status.cancel_reblog_private": "Annulla condivisione",
"status.cannot_reblog": "Questo post non può essere condiviso",
"status.delete": "Elimina",
"status.detailed_status": "Detailed conversation view",
"status.direct": "Messaggio diretto @{name}",
"status.embed": "Incorpora",
"status.favourite": "Apprezzato",

@ -166,9 +166,10 @@
"missing_indicator.label": "見つかりません",
"missing_indicator.sublabel": "見つかりませんでした",
"mute_modal.hide_notifications": "このユーザーからの通知を隠しますか?",
"navigation_bar.apps": "Mobile apps",
"navigation_bar.apps": "アプリ",
"navigation_bar.blocks": "ブロックしたユーザー",
"navigation_bar.community_timeline": "ローカルタイムライン",
"navigation_bar.compose": "Compose new toot",
"navigation_bar.direct": "ダイレクトメッセージ",
"navigation_bar.discover": "見つける",
"navigation_bar.domain_blocks": "非表示にしたドメイン",
@ -263,6 +264,7 @@
"status.cancel_reblog_private": "ブースト解除",
"status.cannot_reblog": "この投稿はブーストできません",
"status.delete": "削除",
"status.detailed_status": "Detailed conversation view",
"status.direct": "@{name}さんにダイレクトメッセージ",
"status.embed": "埋め込み",
"status.favourite": "お気に入り",

@ -165,6 +165,7 @@
"navigation_bar.apps": "Mobile apps",
"navigation_bar.blocks": "დაბლოკილი მომხმარებლები",
"navigation_bar.community_timeline": "ლოკალური თაიმლაინი",
"navigation_bar.compose": "Compose new toot",
"navigation_bar.direct": "პირდაპირი წერილები",
"navigation_bar.discover": "აღმოაჩინე",
"navigation_bar.domain_blocks": "დამალული დომენები",
@ -258,6 +259,7 @@
"status.cancel_reblog_private": "ბუსტის მოშორება",
"status.cannot_reblog": "ეს პოსტი ვერ დაიბუსტება",
"status.delete": "წაშლა",
"status.detailed_status": "Detailed conversation view",
"status.direct": "პირდაპირი წერილი @{name}-ს",
"status.embed": "ჩართვა",
"status.favourite": "ფავორიტი",

@ -7,7 +7,7 @@
"account.disclaimer_full": "여기 있는 정보는 유저의 프로파일을 정확히 반영하지 못 할 수도 있습니다.",
"account.domain_blocked": "도메인 숨겨짐",
"account.edit_profile": "프로필 편집",
"account.endorse": "Feature on profile",
"account.endorse": "프로필에 나타내기",
"account.follow": "팔로우",
"account.followers": "팔로워",
"account.follows": "팔로우",
@ -27,7 +27,7 @@
"account.show_reblogs": "@{name}의 부스트 보기",
"account.unblock": "차단 해제",
"account.unblock_domain": "{domain} 숨김 해제",
"account.unendorse": "Don't feature on profile",
"account.unendorse": "프로필에 나타내지 않기",
"account.unfollow": "팔로우 해제",
"account.unmute": "뮤트 해제",
"account.unmute_notifications": "@{name}의 알림 뮤트 해제",
@ -162,9 +162,10 @@
"missing_indicator.label": "찾을 수 없습니다",
"missing_indicator.sublabel": "이 리소스를 찾을 수 없었습니다",
"mute_modal.hide_notifications": "이 사용자로부터의 알림을 뮤트하시겠습니까?",
"navigation_bar.apps": "Mobile apps",
"navigation_bar.apps": "모바일 앱",
"navigation_bar.blocks": "차단한 사용자",
"navigation_bar.community_timeline": "로컬 타임라인",
"navigation_bar.compose": "Compose new toot",
"navigation_bar.direct": "다이렉트 메시지",
"navigation_bar.discover": "발견하기",
"navigation_bar.domain_blocks": "숨겨진 도메인",
@ -258,6 +259,7 @@
"status.cancel_reblog_private": "부스트 취소",
"status.cannot_reblog": "이 포스트는 부스트 할 수 없습니다",
"status.delete": "삭제",
"status.detailed_status": "Detailed conversation view",
"status.direct": "@{name}에게 다이렉트 메시지",
"status.embed": "공유하기",
"status.favourite": "즐겨찾기",

@ -165,6 +165,7 @@
"navigation_bar.apps": "Mobile apps",
"navigation_bar.blocks": "Geblokkeerde gebruikers",
"navigation_bar.community_timeline": "Lokale tijdlijn",
"navigation_bar.compose": "Compose new toot",
"navigation_bar.direct": "Directe berichten",
"navigation_bar.discover": "Ontdekken",
"navigation_bar.domain_blocks": "Verborgen domeinen",
@ -258,6 +259,7 @@
"status.cancel_reblog_private": "Niet langer boosten",
"status.cannot_reblog": "Deze toot kan niet geboost worden",
"status.delete": "Verwijderen",
"status.detailed_status": "Detailed conversation view",
"status.direct": "Directe toot @{name}",
"status.embed": "Embed",
"status.favourite": "Favoriet",

@ -165,6 +165,7 @@
"navigation_bar.apps": "Mobile apps",
"navigation_bar.blocks": "Blokkerte brukere",
"navigation_bar.community_timeline": "Lokal tidslinje",
"navigation_bar.compose": "Compose new toot",
"navigation_bar.direct": "Direct messages",
"navigation_bar.discover": "Discover",
"navigation_bar.domain_blocks": "Hidden domains",
@ -258,6 +259,7 @@
"status.cancel_reblog_private": "Unboost",
"status.cannot_reblog": "Denne posten kan ikke fremheves",
"status.delete": "Slett",
"status.detailed_status": "Detailed conversation view",
"status.direct": "Direct message @{name}",
"status.embed": "Bygge inn",
"status.favourite": "Lik",

@ -7,7 +7,7 @@
"account.disclaimer_full": "Aquelas informacions de perfil pòdon èsser incomplètas.",
"account.domain_blocked": "Domeni amagat",
"account.edit_profile": "Modificar lo perfil",
"account.endorse": "Feature on profile",
"account.endorse": "Mostrar pel perfil",
"account.follow": "Sègre",
"account.followers": "Seguidors",
"account.follows": "Abonaments",
@ -27,7 +27,7 @@
"account.show_reblogs": "Mostrar los partatges de @{name}",
"account.unblock": "Desblocar @{name}",
"account.unblock_domain": "Desblocar {domain}",
"account.unendorse": "Don't feature on profile",
"account.unendorse": "Mostrar pas pel perfil",
"account.unfollow": "Quitar de sègre",
"account.unmute": "Quitar de rescondre @{name}",
"account.unmute_notifications": "Mostrar las notificacions de @{name}",
@ -139,7 +139,7 @@
"keyboard_shortcuts.hotkey": "Acorchis",
"keyboard_shortcuts.legend": "mostrar aquesta legenda",
"keyboard_shortcuts.mention": "mencionar lautor",
"keyboard_shortcuts.profile": "to open author's profile",
"keyboard_shortcuts.profile": "per dobrir lo perfil de lautor",
"keyboard_shortcuts.reply": "respondre",
"keyboard_shortcuts.search": "anar a la recèrca",
"keyboard_shortcuts.toggle_hidden": "mostrar/amagar lo tèxte dels avertiments",
@ -162,9 +162,10 @@
"missing_indicator.label": "Pas trobat",
"missing_indicator.sublabel": "Aquesta ressorsa es pas estada trobada",
"mute_modal.hide_notifications": "Rescondre las notificacions daquesta persona?",
"navigation_bar.apps": "Mobile apps",
"navigation_bar.apps": "Aplicacions mobil",
"navigation_bar.blocks": "Personas blocadas",
"navigation_bar.community_timeline": "Flux public local",
"navigation_bar.compose": "Compose new toot",
"navigation_bar.direct": "Messatges dirèctes",
"navigation_bar.discover": "Trobar",
"navigation_bar.domain_blocks": "Domenis resconduts",
@ -258,6 +259,7 @@
"status.cancel_reblog_private": "Quitar de partejar",
"status.cannot_reblog": "Aqueste estatut pòt pas èsser partejat",
"status.delete": "Escafar",
"status.detailed_status": "Detailed conversation view",
"status.direct": "Messatge per @{name}",
"status.embed": "Embarcar",
"status.favourite": "Apondre als favorits",

@ -169,6 +169,7 @@
"navigation_bar.apps": "Mobile apps",
"navigation_bar.blocks": "Zablokowani użytkownicy",
"navigation_bar.community_timeline": "Lokalna oś czasu",
"navigation_bar.compose": "Compose new toot",
"navigation_bar.direct": "Wiadomości bezpośrednie",
"navigation_bar.discover": "Odkrywaj",
"navigation_bar.domain_blocks": "Ukryte domeny",
@ -263,6 +264,7 @@
"status.cancel_reblog_private": "Cofnij podbicie",
"status.cannot_reblog": "Ten wpis nie może zostać podbity",
"status.delete": "Usuń",
"status.detailed_status": "Detailed conversation view",
"status.direct": "Wyślij wiadomość bezpośrednią do @{name}",
"status.embed": "Osadź",
"status.favourite": "Dodaj do ulubionych",

@ -7,7 +7,7 @@
"account.disclaimer_full": "As informações abaixo podem refletir o perfil do usuário de maneira incompleta.",
"account.domain_blocked": "Domínio escondido",
"account.edit_profile": "Editar perfil",
"account.endorse": "Feature on profile",
"account.endorse": "Destacar no perfil",
"account.follow": "Seguir",
"account.followers": "Seguidores",
"account.follows": "Segue",
@ -27,7 +27,7 @@
"account.show_reblogs": "Mostra compartilhamentos de @{name}",
"account.unblock": "Desbloquear @{name}",
"account.unblock_domain": "Desbloquear {domain}",
"account.unendorse": "Don't feature on profile",
"account.unendorse": "Não destacar no perfil",
"account.unfollow": "Deixar de seguir",
"account.unmute": "Não silenciar @{name}",
"account.unmute_notifications": "Retirar silêncio das notificações vindas de @{name}",
@ -162,9 +162,10 @@
"missing_indicator.label": "Não encontrado",
"missing_indicator.sublabel": "Esse recurso não pôde ser encontrado",
"mute_modal.hide_notifications": "Esconder notificações deste usuário?",
"navigation_bar.apps": "Mobile apps",
"navigation_bar.apps": "Apps",
"navigation_bar.blocks": "Usuários bloqueados",
"navigation_bar.community_timeline": "Local",
"navigation_bar.compose": "Compose new toot",
"navigation_bar.direct": "Mensagens diretas",
"navigation_bar.discover": "Descobrir",
"navigation_bar.domain_blocks": "Domínios escondidos",
@ -258,6 +259,7 @@
"status.cancel_reblog_private": "Desfazer compartilhamento",
"status.cannot_reblog": "Esta postagem não pode ser compartilhada",
"status.delete": "Excluir",
"status.detailed_status": "Detailed conversation view",
"status.direct": "Enviar mensagem direta a @{name}",
"status.embed": "Incorporar",
"status.favourite": "Adicionar aos favoritos",

@ -165,6 +165,7 @@
"navigation_bar.apps": "Mobile apps",
"navigation_bar.blocks": "Utilizadores bloqueados",
"navigation_bar.community_timeline": "Local",
"navigation_bar.compose": "Compose new toot",
"navigation_bar.direct": "Direct messages",
"navigation_bar.discover": "Discover",
"navigation_bar.domain_blocks": "Hidden domains",
@ -258,6 +259,7 @@
"status.cancel_reblog_private": "Unboost",
"status.cannot_reblog": "Este post não pode ser partilhado",
"status.delete": "Eliminar",
"status.detailed_status": "Detailed conversation view",
"status.direct": "Direct message @{name}",
"status.embed": "Incorporar",
"status.favourite": "Adicionar aos favoritos",

@ -165,6 +165,7 @@
"navigation_bar.apps": "Mobile apps",
"navigation_bar.blocks": "Список блокировки",
"navigation_bar.community_timeline": "Локальная лента",
"navigation_bar.compose": "Compose new toot",
"navigation_bar.direct": "Личные сообщения",
"navigation_bar.discover": "Изучайте",
"navigation_bar.domain_blocks": "Скрытые домены",
@ -258,6 +259,7 @@
"status.cancel_reblog_private": "Не продвигать",
"status.cannot_reblog": "Этот статус не может быть продвинут",
"status.delete": "Удалить",
"status.detailed_status": "Detailed conversation view",
"status.direct": "Написать @{name}",
"status.embed": "Встроить",
"status.favourite": "Нравится",

@ -165,6 +165,7 @@
"navigation_bar.apps": "Mobile apps",
"navigation_bar.blocks": "Blokovaní užívatelia",
"navigation_bar.community_timeline": "Lokálna časová os",
"navigation_bar.compose": "Compose new toot",
"navigation_bar.direct": "Súkromné správy",
"navigation_bar.discover": "Objavuj",
"navigation_bar.domain_blocks": "Skryté domény",
@ -258,6 +259,7 @@
"status.cancel_reblog_private": "Nezdieľaj",
"status.cannot_reblog": "Tento príspevok nemôže byť re-tootnutý",
"status.delete": "Zmazať",
"status.detailed_status": "Detailed conversation view",
"status.direct": "Súkromná správa @{name}",
"status.embed": "Vložiť",
"status.favourite": "Páči sa mi",

@ -165,6 +165,7 @@
"navigation_bar.apps": "Mobile apps",
"navigation_bar.blocks": "Blocked users",
"navigation_bar.community_timeline": "Local timeline",
"navigation_bar.compose": "Compose new toot",
"navigation_bar.direct": "Direct messages",
"navigation_bar.discover": "Discover",
"navigation_bar.domain_blocks": "Hidden domains",
@ -258,6 +259,7 @@
"status.cancel_reblog_private": "Unboost",
"status.cannot_reblog": "This post cannot be boosted",
"status.delete": "Delete",
"status.detailed_status": "Detailed conversation view",
"status.direct": "Direct message @{name}",
"status.embed": "Embed",
"status.favourite": "Favourite",

@ -165,6 +165,7 @@
"navigation_bar.apps": "Mobile apps",
"navigation_bar.blocks": "Blokirani korisnici",
"navigation_bar.community_timeline": "Lokalna lajna",
"navigation_bar.compose": "Compose new toot",
"navigation_bar.direct": "Direct messages",
"navigation_bar.discover": "Discover",
"navigation_bar.domain_blocks": "Hidden domains",
@ -258,6 +259,7 @@
"status.cancel_reblog_private": "Unboost",
"status.cannot_reblog": "Ovaj status ne može da se podrži",
"status.delete": "Obriši",
"status.detailed_status": "Detailed conversation view",
"status.direct": "Direct message @{name}",
"status.embed": "Ugradi na sajt",
"status.favourite": "Omiljeno",

@ -165,6 +165,7 @@
"navigation_bar.apps": "Mobile apps",
"navigation_bar.blocks": "Блокирани корисници",
"navigation_bar.community_timeline": "Локална лајна",
"navigation_bar.compose": "Compose new toot",
"navigation_bar.direct": "Direct messages",
"navigation_bar.discover": "Discover",
"navigation_bar.domain_blocks": "Hidden domains",
@ -258,6 +259,7 @@
"status.cancel_reblog_private": "Unboost",
"status.cannot_reblog": "Овај статус не може да се подржи",
"status.delete": "Обриши",
"status.detailed_status": "Detailed conversation view",
"status.direct": "Direct message @{name}",
"status.embed": "Угради на сајт",
"status.favourite": "Омиљено",

@ -165,6 +165,7 @@
"navigation_bar.apps": "Mobile apps",
"navigation_bar.blocks": "Blockerade användare",
"navigation_bar.community_timeline": "Lokal tidslinje",
"navigation_bar.compose": "Compose new toot",
"navigation_bar.direct": "Direktmeddelanden",
"navigation_bar.discover": "Upptäck",
"navigation_bar.domain_blocks": "Dolda domäner",
@ -258,6 +259,7 @@
"status.cancel_reblog_private": "Ta bort knuff",
"status.cannot_reblog": "Detta inlägg kan inte knuffas",
"status.delete": "Ta bort",
"status.detailed_status": "Detailed conversation view",
"status.direct": "Direktmeddela @{name}",
"status.embed": "Bädda in",
"status.favourite": "Favorit",

@ -165,6 +165,7 @@
"navigation_bar.apps": "Mobile apps",
"navigation_bar.blocks": "బ్లాక్ చేయబడిన వినియోగదారులు",
"navigation_bar.community_timeline": "స్థానిక కాలక్రమం",
"navigation_bar.compose": "Compose new toot",
"navigation_bar.direct": "ప్రత్యక్ష సందేశాలు",
"navigation_bar.discover": "కనుగొను",
"navigation_bar.domain_blocks": "దాచిన డొమైన్లు",
@ -258,6 +259,7 @@
"status.cancel_reblog_private": "బూస్ట్ను తొలగించు",
"status.cannot_reblog": "ఈ పోస్ట్ను బూస్ట్ చేయడం సాధ్యం కాదు",
"status.delete": "తొలగించు",
"status.detailed_status": "Detailed conversation view",
"status.direct": "@{name}కు నేరుగా సందేశం పంపు",
"status.embed": "ఎంబెడ్",
"status.favourite": "ఇష్టపడు",

@ -165,6 +165,7 @@
"navigation_bar.apps": "Mobile apps",
"navigation_bar.blocks": "Blocked users",
"navigation_bar.community_timeline": "Local timeline",
"navigation_bar.compose": "Compose new toot",
"navigation_bar.direct": "Direct messages",
"navigation_bar.discover": "Discover",
"navigation_bar.domain_blocks": "Hidden domains",
@ -258,6 +259,7 @@
"status.cancel_reblog_private": "Unboost",
"status.cannot_reblog": "This post cannot be boosted",
"status.delete": "Delete",
"status.detailed_status": "Detailed conversation view",
"status.direct": "Direct message @{name}",
"status.embed": "Embed",
"status.favourite": "Favourite",

@ -165,6 +165,7 @@
"navigation_bar.apps": "Mobile apps",
"navigation_bar.blocks": "Engellenen kullanıcılar",
"navigation_bar.community_timeline": "Yerel zaman tüneli",
"navigation_bar.compose": "Compose new toot",
"navigation_bar.direct": "Direct messages",
"navigation_bar.discover": "Discover",
"navigation_bar.domain_blocks": "Hidden domains",
@ -258,6 +259,7 @@
"status.cancel_reblog_private": "Unboost",
"status.cannot_reblog": "Bu gönderi boost edilemez",
"status.delete": "Sil",
"status.detailed_status": "Detailed conversation view",
"status.direct": "Direct message @{name}",
"status.embed": "Embed",
"status.favourite": "Favorilere ekle",

@ -165,6 +165,7 @@
"navigation_bar.apps": "Mobile apps",
"navigation_bar.blocks": "Заблоковані користувачі",
"navigation_bar.community_timeline": "Локальна стрічка",
"navigation_bar.compose": "Compose new toot",
"navigation_bar.direct": "Прямі повідомлення",
"navigation_bar.discover": "Знайти",
"navigation_bar.domain_blocks": "Приховані домени",
@ -258,6 +259,7 @@
"status.cancel_reblog_private": "Unboost",
"status.cannot_reblog": "Цей допис не може бути передмухнутий",
"status.delete": "Видалити",
"status.detailed_status": "Detailed conversation view",
"status.direct": "Direct message @{name}",
"status.embed": "Embed",
"status.favourite": "Подобається",

@ -165,6 +165,7 @@
"navigation_bar.apps": "Mobile apps",
"navigation_bar.blocks": "已屏蔽的用户",
"navigation_bar.community_timeline": "本站时间轴",
"navigation_bar.compose": "Compose new toot",
"navigation_bar.direct": "私信",
"navigation_bar.discover": "发现",
"navigation_bar.domain_blocks": "已屏蔽的网站",
@ -258,6 +259,7 @@
"status.cancel_reblog_private": "取消转嘟",
"status.cannot_reblog": "无法转嘟这条嘟文",
"status.delete": "删除",
"status.detailed_status": "Detailed conversation view",
"status.direct": "发送私信给 @{name}",
"status.embed": "嵌入",
"status.favourite": "收藏",

@ -165,6 +165,7 @@
"navigation_bar.apps": "Mobile apps",
"navigation_bar.blocks": "被你封鎖的用戶",
"navigation_bar.community_timeline": "本站時間軸",
"navigation_bar.compose": "Compose new toot",
"navigation_bar.direct": "個人訊息",
"navigation_bar.discover": "探索",
"navigation_bar.domain_blocks": "隱藏的服務站",
@ -258,6 +259,7 @@
"status.cancel_reblog_private": "取消轉推",
"status.cannot_reblog": "這篇文章無法被轉推",
"status.delete": "刪除",
"status.detailed_status": "Detailed conversation view",
"status.direct": "私訊 @{name}",
"status.embed": "鑲嵌",
"status.favourite": "收藏",

@ -165,6 +165,7 @@
"navigation_bar.apps": "Mobile apps",
"navigation_bar.blocks": "封鎖的使用者",
"navigation_bar.community_timeline": "本地時間軸",
"navigation_bar.compose": "Compose new toot",
"navigation_bar.direct": "私訊",
"navigation_bar.discover": "探索",
"navigation_bar.domain_blocks": "隱藏的站點",
@ -258,6 +259,7 @@
"status.cancel_reblog_private": "取消轉嘟",
"status.cannot_reblog": "這篇嘟文無法被轉嘟",
"status.delete": "刪除",
"status.detailed_status": "Detailed conversation view",
"status.direct": "發送私訊給 @{name}",
"status.embed": "嵌入",
"status.favourite": "最愛",

@ -63,7 +63,10 @@ function main() {
.catch(error => console.error(error));
}
new Rellax('.parallax', { speed: -1 });
const parallaxComponents = document.querySelectorAll('.parallax');
if (parallaxComponents.length > 0 ) {
new Rellax('.parallax', { speed: -1 });
}
const history = createHistory();
const detailedStatuses = document.querySelectorAll('.public-layout .detailed-status');

@ -104,7 +104,9 @@ class ActivityPub::Activity
def crawl_links(status)
return if status.spoiler_text?
LinkCrawlWorker.perform_async(status.id)
# Spread out crawling randomly to avoid DDoSing the link
LinkCrawlWorker.perform_in(rand(1..59).seconds, status.id)
end
def distribute_to_followers(status)

@ -48,7 +48,7 @@ class ActivityPub::Activity::Create < ActivityPub::Activity
account: @account,
text: text_from_content || '',
language: detected_language,
spoiler_text: @object['summary'] || '',
spoiler_text: text_from_summary || '',
created_at: @object['published'],
override_timestamps: @options[:override_timestamps],
reply: @object['inReplyTo'].present?,
@ -193,6 +193,14 @@ class ActivityPub::Activity::Create < ActivityPub::Activity
end
end
def text_from_summary
if @object['summary'].present?
@object['summary']
elsif summary_language_map?
@object['summaryMap'].values.first
end
end
def text_from_name
if @object['name'].present?
@object['name']
@ -206,6 +214,8 @@ class ActivityPub::Activity::Create < ActivityPub::Activity
@object['contentMap'].keys.first
elsif name_language_map?
@object['nameMap'].keys.first
elsif summary_language_map?
@object['summaryMap'].keys.first
elsif supported_object_type?
LanguageDetector.instance.detect(text_from_content, @account)
end
@ -223,6 +233,10 @@ class ActivityPub::Activity::Create < ActivityPub::Activity
end
end
def summary_language_map?
@object['summaryMap'].is_a?(Hash) && !@object['summaryMap'].empty?
end
def content_language_map?
@object['contentMap'].is_a?(Hash) && !@object['contentMap'].empty?
end

@ -14,7 +14,7 @@
- unless status.proper.media_attachments.empty?
- if status.proper.media_attachments.first.video?
- video = status.proper.media_attachments.first
= react_component :video, src: video.file.url(:original), preview: video.file.url(:small), sensitive: status.proper.sensitive? && !current_account&.user&.setting_display_sensitive_media, width: 610, height: 343, inline: true
= react_component :video, src: video.file.url(:original), preview: video.file.url(:small), sensitive: status.proper.sensitive? && !current_account&.user&.setting_display_sensitive_media, width: 610, height: 343, inline: true, alt: video.description
- else
= react_component :media_gallery, height: 343, sensitive: status.proper.sensitive? && !current_account&.user&.setting_display_sensitive_media, 'autoPlayGif': current_account&.user&.setting_auto_play_gif, media: status.proper.media_attachments.map { |a| ActiveModelSerializers::SerializableResource.new(a, serializer: REST::MediaAttachmentSerializer).as_json }

@ -30,9 +30,5 @@
= render partial: 'layouts/theme', object: @core
= render partial: 'layouts/theme', object: @theme
- body_classes ||= @body_classes || ''
- body_classes += ' system-font' if current_account&.user&.setting_system_font_ui
- body_classes += current_account&.user&.setting_reduce_motion ? ' reduce-motion' : ' no-reduce-motion'
%body{ class: add_rtl_body_class(body_classes) }
%body{ class: body_classes }
= content_for?(:content) ? yield(:content) : yield

@ -21,7 +21,7 @@
- if !status.media_attachments.empty?
- if status.media_attachments.first.video?
- video = status.media_attachments.first
= react_component :video, src: video.file.url(:original), preview: video.file.url(:small), sensitive: status.sensitive? && !current_account&.user&.setting_display_sensitive_media, width: 670, height: 380, detailed: true, inline: true
= react_component :video, src: video.file.url(:original), preview: video.file.url(:small), sensitive: status.sensitive? && !current_account&.user&.setting_display_sensitive_media, width: 670, height: 380, detailed: true, inline: true, alt: video.description
- else
= react_component :media_gallery, height: 380, sensitive: status.sensitive? && !current_account&.user&.setting_display_sensitive_media, standalone: true, 'autoPlayGif': current_account&.user&.setting_auto_play_gif, 'reduceMotion': current_account&.user&.setting_reduce_motion, media: status.media_attachments.map { |a| ActiveModelSerializers::SerializableResource.new(a, serializer: REST::MediaAttachmentSerializer).as_json }
- elsif status.preview_cards.first

@ -25,7 +25,7 @@
- unless status.media_attachments.empty?
- if status.media_attachments.first.video?
- video = status.media_attachments.first
= react_component :video, src: video.file.url(:original), preview: video.file.url(:small), sensitive: status.sensitive? && !current_account&.user&.setting_display_sensitive_media, width: 610, height: 343, inline: true
= react_component :video, src: video.file.url(:original), preview: video.file.url(:small), sensitive: status.sensitive? && !current_account&.user&.setting_display_sensitive_media, width: 610, height: 343, inline: true, alt: video.description
- else
= react_component :media_gallery, height: 343, sensitive: status.sensitive? && !current_account&.user&.setting_display_sensitive_media, 'autoPlayGif': current_account&.user&.setting_auto_play_gif, media: status.media_attachments.map { |a| ActiveModelSerializers::SerializableResource.new(a, serializer: REST::MediaAttachmentSerializer).as_json }

@ -6,7 +6,7 @@ class Maintenance::DestroyMediaWorker
sidekiq_options queue: 'pull'
def perform(media_attachment_id)
media = MediaAttachment.find(media_attachment_id)
media = media_attachment_id.is_a?(MediaAttachment) ? media_attachment_id : MediaAttachment.find(media_attachment_id)
media.destroy
rescue ActiveRecord::RecordNotFound
true

@ -6,7 +6,7 @@ class Maintenance::RedownloadAccountMediaWorker
sidekiq_options queue: 'pull', retry: false
def perform(account_id)
account = Account.find(account_id)
account = account_id.is_a?(Account) ? account_id : Account.find(account_id)
account.reset_avatar!
account.reset_header!
account.save

@ -6,7 +6,7 @@ class Maintenance::UncacheMediaWorker
sidekiq_options queue: 'pull'
def perform(media_attachment_id)
media = MediaAttachment.find(media_attachment_id)
media = media_attachment_id.is_a?(MediaAttachment) ? media_attachment_id : MediaAttachment.find(media_attachment_id)
return if media.file.blank?

@ -3,7 +3,7 @@
class Scheduler::BackupCleanupScheduler
include Sidekiq::Worker
sidekiq_options unique: :until_executed
sidekiq_options unique: :until_executed, retry: 0
def perform
old_backups.reorder(nil).find_each(&:destroy!)

@ -3,7 +3,7 @@
class Scheduler::DoorkeeperCleanupScheduler
include Sidekiq::Worker
sidekiq_options unique: :until_executed
sidekiq_options unique: :until_executed, retry: 0
def perform
Doorkeeper::AccessToken.where('revoked_at IS NOT NULL').where('revoked_at < NOW()').delete_all

@ -3,7 +3,7 @@
class Scheduler::EmailScheduler
include Sidekiq::Worker
sidekiq_options unique: :until_executed
sidekiq_options unique: :until_executed, retry: 0
def perform
eligible_users.reorder(nil).find_each do |user|

@ -3,7 +3,7 @@
class Scheduler::FeedCleanupScheduler
include Sidekiq::Worker
sidekiq_options unique: :until_executed
sidekiq_options unique: :until_executed, retry: 0
def perform
clean_home_feeds!

@ -5,7 +5,7 @@ class Scheduler::IpCleanupScheduler
RETENTION_PERIOD = 1.year
sidekiq_options unique: :until_executed
sidekiq_options unique: :until_executed, retry: 0
def perform
time_ago = RETENTION_PERIOD.ago

@ -3,7 +3,7 @@
class Scheduler::MediaCleanupScheduler
include Sidekiq::Worker
sidekiq_options unique: :until_executed
sidekiq_options unique: :until_executed, retry: 0
def perform
unattached_media.find_each(&:destroy)

@ -3,7 +3,7 @@
class Scheduler::SubscriptionsCleanupScheduler
include Sidekiq::Worker
sidekiq_options unique: :until_executed
sidekiq_options unique: :until_executed, retry: 0
def perform
Subscription.expired.in_batches.delete_all

@ -3,7 +3,7 @@
class Scheduler::SubscriptionsScheduler
include Sidekiq::Worker
sidekiq_options unique: :until_executed
sidekiq_options unique: :until_executed, retry: 0
def perform
Pubsubhubbub::SubscribeWorker.push_bulk(expiring_accounts.pluck(:id))

@ -3,7 +3,7 @@
class Scheduler::UserCleanupScheduler
include Sidekiq::Worker
sidekiq_options unique: :until_executed
sidekiq_options unique: :until_executed, retry: 0
def perform
User.where('confirmed_at is NULL AND confirmation_sent_at <= ?', 2.days.ago).reorder(nil).find_in_batches do |batch|

@ -0,0 +1,4 @@
#!/usr/bin/env ruby
APP_PATH = File.expand_path('../config/application', __dir__)
require_relative '../lib/cli'
Mastodon::CLI.start(ARGV)

@ -47,10 +47,10 @@ if ENV['S3_ENABLED'] == 'true'
Paperclip::Attachment.default_options[:url] = ':s3_path_url'
end
if ENV.has_key?('S3_CLOUDFRONT_HOST')
if ENV.has_key?('S3_ALIAS_HOST') || ENV.has_key?('S3_CLOUDFRONT_HOST')
Paperclip::Attachment.default_options.merge!(
url: ':s3_alias_url',
s3_host_alias: ENV['S3_CLOUDFRONT_HOST']
s3_host_alias: ENV['S3_ALIAS_HOST'] || ENV['S3_CLOUDFRONT_HOST']
)
end
elsif ENV['SWIFT_ENABLED'] == 'true'

@ -414,6 +414,9 @@ cs:
last_delivery: Poslední doručení
title: WebSub
topic: Téma
suspensions:
proceed: Pokračovat
title: Suspendovat účet %{acct}
title: Administrace
admin_mailer:
new_report:

@ -91,7 +91,9 @@ da:
unknown: Adgangs-beviset er ugyldigt
resource_owner_authenticator_not_configured: Ressource ejeren kunne ikke blive fundet grundet Doorkeeper.configure.resource_owner_authenticator ikke er konfigureret.
server_error: Autoriserings serveren blev mødt med en uventet betingelse der forhindrede den i at færdiggøre anmodningen.
temporarily_unavailable: Autoriserings serveren er på nuværende tidspunkt ikke i stand til at håndtere anmodningen grundet midlertidig overlast eller serveren er ved at blive opdateret.
unauthorized_client: Klienten er ikke godkendt til at udføre denne anmodning ved at bruge denne metode.
unsupported_grant_type: Autoriserings typen understøttes ikke af autoriserings serveren.
unsupported_response_type: Godkendelses serveren understøtter ikke denne type respons.
flash:
applications:

@ -350,6 +350,9 @@ en:
contact_information:
email: Business e-mail
username: Contact username
custom_css:
desc_html: Modify the look with CSS loaded on every page
title: Custom CSS
hero:
desc_html: Displayed on the frontpage. At least 600x100px recommended. When not set, falls back to instance thumbnail
title: Hero image

@ -30,10 +30,14 @@ ja:
other_instances: 他のインスタンス
privacy_policy: プライバシーポリシー
source_code: ソースコード
status_count_after: トゥート
status_count_after:
one: トゥート
other: トゥート
status_count_before: トゥート数
terms: 利用規約
user_count_after:
user_count_after:
one:
other:
user_count_before: ユーザー数
what_is_mastodon: Mastodon とは?
accounts:
@ -49,7 +53,7 @@ ja:
people_followed_by: "%{name} さんがフォロー中のアカウント"
people_who_follow: "%{name} さんをフォロー中のアカウント"
pin_errors:
following: 推薦したい人はあなたが既にフォローしている必要があります
following: おすすめしたい人はあなたが既にフォローしている必要があります
posts: トゥート
posts_with_replies: トゥートと返信
reserved_username: このユーザー名は予約されています
@ -185,7 +189,7 @@ ja:
unsuspend_account: "%{name} さんが %{target} さんの停止を解除しました"
update_custom_emoji: "%{name} さんがカスタム絵文字 %{target} を更新しました"
update_status: "%{name} さんが %{target} さんの投稿を更新しました"
deleted_status: "(削除されました)"
deleted_status: "(削除)"
title: 操作履歴
custom_emojis:
by_domain: ドメイン
@ -414,6 +418,12 @@ ja:
last_delivery: 最終配送
title: WebSub
topic: トピック
suspensions:
bad_acct_msg: 値が一致しませんでした。停止しようとしているアカウントに間違いはありませんか?
hint_html: 'アカウントの停止を確認するには、以下のフィールドに %{value} と入力してください:'
proceed: 完全に活動停止させる
title: "%{acct} を停止"
warning_html: 'このアカウントを停止すると、このアカウントから次のようなデータが<strong>不可逆的に</strong>削除されます:'
title: 管理
admin_mailer:
new_report:
@ -645,7 +655,6 @@ ja:
quadrillion: Q
thousand: K
trillion: T
unit: ''
pagination:
newer: 新しいトゥート
next:
@ -868,7 +877,7 @@ ja:
recovery_codes_regenerated: リカバリーコードが再生成されました
recovery_instructions_html: 携帯電話を紛失した場合、以下の内どれかのリカバリーコードを使用してアカウントへアクセスすることができます。<strong>リカバリーコードは大切に保全してください。</strong>たとえば印刷してほかの重要な書類と一緒に保管することができます。
setup: 初期設定
wrong_code: コードが間違っています。サーバー上の時間とデバイス上の時間が一致していることを確認してください。
wrong_code: コードが間違っています。サーバー上の時間とデバイス上の時間が一致していますか?
user_mailer:
backup_ready:
explanation: Mastodonアカウントのアーカイブを受け付けました。今すぐダウンロードできます

@ -6,6 +6,7 @@ ka:
about_this: შესახებ
administered_by: 'ადმინისტრატორი:'
api: აპი
apps: მობილური აპლიკაციები
closed_registrations: რეგისტრაციები ამჟამად ინსტანციაზე დახურულია. თუმცა! ანგარიშის შესაქმნელად შეგიძლიათ იპოვოთ სხვა ინსტანცია და იმავე ქსელზე იქონიოთ წვდომა იქიდან.
contact: კონტაქტი
contact_missing: არაა დაყენებული
@ -281,6 +282,7 @@ ka:
search: ძებნა
title: ცნობილი ინსტანციები
invites:
deactivate_all: ყველას დეაქტივაცია
filter:
all: ყველა
available: ხელმისაწვდომი
@ -660,6 +662,9 @@ ka:
no_account_html: არ გაქვთ ანგარიში? შეგიძლიათ <a href='%{sign_up_path}' target='_blank'>დარეგისტრირდეთ აქ</a>
proceed: გააგრძელეთ გასაყოლად
prompt: 'თქვენ გაჰყვებით:'
remote_interaction:
proceed: გააგრძელეთ ურთიერთქმედება
prompt: 'თქვენ გსურთ ურთიერთქმედება ამ ტუტთან:'
remote_unfollow:
error: შეცდომა
title: სათაური
@ -743,6 +748,7 @@ ka:
private: არა-საჯარო ტუტი ვერ აიპინება
reblog: ბუსტი ვერ აიპინება
show_more: მეტის ჩვენება
sign_in_to_participate: საუბარში მონაწილეობისთვის გაიარეთ ავტორიზაცია
title: '%{name}: "%{quote}"'
visibilities:
private: მხოლოდ-მიმდევრები

@ -640,7 +640,7 @@ ko:
publishing: 퍼블리싱
web:
remote_follow:
acct: 아이디@도메인을 입력해 주십시오
acct: 당신이 사용하는 아이디@도메인을 입력해 주십시오
missing_resource: 리디렉션 대상을 찾을 수 없습니다
no_account_html: 계정이 없나요? <a href='%{sign_up_path}' target='_blank'>여기에서 가입 할 수 있습니다</a>
proceed: 팔로우 하기

@ -30,7 +30,7 @@ fr:
imports:
data: Un fichier CSV généré par une autre instance de Mastodon
sessions:
otp: 'Entrez le code dauthentification à deux facteurs généré par votre téléphone ou utilisez un de vos codes de récupération:'
otp: 'Entrez le code dauthentification à deux facteurs généré par l''application de votre téléphone ou utilisez un de vos codes de récupération:'
user:
chosen_languages: Lorsque coché, seuls les pouets dans les langues sélectionnées seront affichés sur les fils publics
labels:

@ -23,8 +23,8 @@ try {
let attachmentHost;
if (process.env.S3_ENABLED === 'true') {
if (process.env.S3_CLOUDFRONT_HOST) {
attachmentHost = process.env.S3_CLOUDFRONT_HOST;
if (process.env.S3_ALIAS_HOST || process.env.S3_CLOUDFRONT_HOST) {
attachmentHost = process.env.S3_ALIAS_HOST || process.env.S3_CLOUDFRONT_HOST;
} else {
attachmentHost = process.env.S3_HOSTNAME || `s3-${process.env.S3_REGION || 'us-east-1'}.amazonaws.com`;
}

@ -0,0 +1,11 @@
# frozen_string_literal: true
require 'thor'
require_relative 'mastodon/media_cli'
module Mastodon
class CLI < Thor
desc 'media SUBCOMMAND ...ARGS', 'manage media files'
subcommand 'media', Mastodon::MediaCLI
end
end

@ -0,0 +1,47 @@
# frozen_string_literal: true
require_relative '../../config/boot'
require_relative '../../config/environment'
# rubocop:disable Rails/Output
module Mastodon
class MediaCLI < Thor
option :days, type: :numeric, default: 7
option :background, type: :boolean, default: false
desc 'remove', 'remove remote media files'
long_desc <<-DESC
Removes locally cached copies of media attachments from other servers.
The --days option specifies how old media attachments have to be before
they are removed. It defaults to 7 days.
With the --background option, instead of deleting the files sequentially,
they will be queued into Sidekiq and the command will exit as soon as
possible. In Sidekiq they will be processed with higher concurrency, but
it may impact other operations of the Mastodon server, and it may overload
the underlying file storage.
DESC
def remove
time_ago = options[:days].days.ago
queued = 0
MediaAttachment.where.not(remote_url: '').where.not(file_file_name: nil).where('created_at < ?', time_ago).select(:id).reorder(nil).find_in_batches do |media_attachments|
if options[:background]
queued += media_attachments.size
Maintenance::UncacheMediaWorker.push_bulk(media_attachments.map(&:id))
else
media_attachments.each do |m|
Maintenance::UncacheMediaWorker.new.perform(m)
print '.'
end
end
end
puts
puts "Scheduled the deletion of #{queued} media attachments" if options[:background]
end
end
end
# rubocop:enable Rails/Output

@ -222,7 +222,7 @@ namespace :mastodon do
end
if prompt.yes?('Do you want to access the uploaded files from your own domain?')
env['S3_CLOUDFRONT_HOST'] = prompt.ask('Domain for uploaded files:') do |q|
env['S3_ALIAS_HOST'] = prompt.ask('Domain for uploaded files:') do |q|
q.required true
q.default "files.#{env['LOCAL_DOMAIN']}"
q.modify :strip
@ -512,14 +512,9 @@ namespace :mastodon do
desc 'Remove cached remote media attachments that are older than NUM_DAYS. By default 7 (week)'
task remove_remote: :environment do
time_ago = ENV.fetch('NUM_DAYS') { 7 }.to_i.days.ago
nb_media_attachments = 0
MediaAttachment.where.not(remote_url: '').where.not(file_file_name: nil).where('created_at < ?', time_ago).select(:id).reorder(nil).find_in_batches do |media_attachments|
nb_media_attachments += media_attachments.length
Maintenance::UncacheMediaWorker.push_bulk(media_attachments.map(&:id))
end
puts "Scheduled the deletion of #{nb_media_attachments} media attachments"
require_relative '../mastodon/media_cli'
cli = Mastodon::MediaCLI.new([], days: ENV['NUM_DAYS'] || 7)
cli.invoke(:remove)
end
desc 'Set unknown attachment type for remote-only attachments'

@ -17,7 +17,7 @@ describe ApplicationHelper do
end
end
describe 'add_rtl_body_class' do
describe 'locale_direction' do
around do |example|
current_locale = I18n.locale
example.run
@ -26,22 +26,22 @@ describe ApplicationHelper do
it 'adds rtl body class if locale is Arabic' do
I18n.locale = :ar
expect(helper.add_rtl_body_class('other classes')).to eq 'other classes rtl'
expect(helper.locale_direction).to eq 'rtl'
end
it 'adds rtl body class if locale is Farsi' do
I18n.locale = :fa
expect(helper.add_rtl_body_class('other classes')).to eq 'other classes rtl'
expect(helper.locale_direction).to eq 'rtl'
end
it 'adds rtl if locale is Hebrew' do
I18n.locale = :he
expect(helper.add_rtl_body_class('other classes')).to eq 'other classes rtl'
expect(helper.locale_direction).to eq 'rtl'
end
it 'does not add rtl if locale is Thai' do
I18n.locale = :th
expect(helper.add_rtl_body_class('other classes')).to eq 'other classes'
expect(helper.locale_direction).to_not eq 'rtl'
end
end

@ -9,6 +9,7 @@ const log = require('npmlog');
const url = require('url');
const WebSocket = require('uws');
const uuid = require('uuid');
const fs = require('fs');
const env = process.env.NODE_ENV || 'development';
@ -70,6 +71,9 @@ const redisUrlToClient = (defaultConfig, redisUrl) => {
const numWorkers = +process.env.STREAMING_CLUSTER_NUM || (env === 'development' ? 1 : Math.max(os.cpus().length - 1, 1));
const startMaster = () => {
if (!process.env.SOCKET && process.env.PORT && isNaN(+process.env.PORT)) {
log.warn('UNIX domain socket is now supported by using SOCKET. Please migrate from PORT hack.');
}
log.info(`Starting streaming API server master with ${numWorkers} workers`);
};
@ -448,6 +452,12 @@ const startWorker = (workerId) => {
app.use(setRequestId);
app.use(setRemoteAddress);
app.use(allowCrossDomain);
app.get('/api/v1/streaming/health', (req, res) => {
res.writeHead(200, { 'Content-Type': 'text/plain' });
res.end('OK');
});
app.use(authenticationMiddleware);
app.use(errorMiddleware);
@ -574,9 +584,16 @@ const startWorker = (workerId) => {
});
}, 30000);
server.listen(process.env.PORT || 4000, process.env.BIND || '0.0.0.0', () => {
log.info(`Worker ${workerId} now listening on ${server.address().address}:${server.address().port}`);
});
if (process.env.SOCKET || process.env.PORT && isNaN(+process.env.PORT)) {
server.listen(process.env.SOCKET || process.env.PORT, () => {
fs.chmodSync(server.address(), 0o666);
log.info(`Worker ${workerId} now listening on ${server.address()}`);
});
} else {
server.listen(+process.env.PORT || 4000, process.env.BIND || '0.0.0.0', () => {
log.info(`Worker ${workerId} now listening on ${server.address().address}:${server.address().port}`);
});
}
const onExit = () => {
log.info(`Worker ${workerId} exiting, bye bye`);

Loading…
Cancel
Save