Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Upstream 20240424 #726

Merged
merged 23 commits into from
Apr 24, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
23 commits
Select commit Hold shift + click to select a range
2ec9bff
Fix Rubocop `Rails/UniqueValidationWithoutIndex` cop (#27461)
mjankowski Apr 22, 2024
223936c
Update eslint (non-major) to v7.7.0 (#30026)
renovate[bot] Apr 22, 2024
88f9468
Update peter-evans/create-pull-request action to v6.0.4 (#30025)
renovate[bot] Apr 22, 2024
3e21af3
Update dependency @types/react to v18.2.79 (#30024)
renovate[bot] Apr 22, 2024
24e67c4
Update dependency postcss-preset-env to v9.5.8 (#30018)
renovate[bot] Apr 22, 2024
a15139b
Fix intermittent order based failure in `UpdateStatusService` spec (#…
mjankowski Apr 22, 2024
18737aa
Rely on dotenv autoload instead of explicit call (#30007)
mjankowski Apr 22, 2024
3655fb6
New Crowdin Translations (automated) (#30014)
github-actions[bot] Apr 22, 2024
75163d9
Fixed rendering error on /start when not logged in (#30023)
timothyjrogers Apr 22, 2024
1ca6ff8
Fixed crash when supplying FFMPEG_BINARY environment variable (#30022)
timothyjrogers Apr 22, 2024
56b095e
Update Gemfile.lock ruby and bundler versions (#30011)
mjankowski Apr 22, 2024
ffbbf74
Limit `http` gem version to 5.1.x series (#30010)
mjankowski Apr 22, 2024
33e8297
Use shared `form` partial for `admin/domain_blocks` views (#29609)
mjankowski Apr 22, 2024
2ef098d
Revert "Rely on dotenv autoload instead of explicit call (#30007)" (#…
ClearlyClaire Apr 22, 2024
483fabf
Update dependency http to '~> 5.2.0' (#30027)
renovate[bot] Apr 22, 2024
1471c0d
Update dependency rubocop to v1.63.3 (#30031)
renovate[bot] Apr 23, 2024
91c7406
Update dependency postcss-preset-env to v9.5.9 (#30029)
renovate[bot] Apr 23, 2024
d754b15
New Crowdin Translations (automated) (#30034)
github-actions[bot] Apr 23, 2024
049b159
Add read:me OAuth 2.0 scope, allowing more limited access to user dat…
ThisIsMissEm Apr 23, 2024
a239904
Fix string interpolation for software updates admin mailer (#30035)
ClearlyClaire Apr 23, 2024
32ead51
Add material design icons to admin/settings views (#27780)
mjankowski Apr 23, 2024
3f68875
Move JS source from `packs` to `entrypoints` (#30037)
mjankowski Apr 23, 2024
32a8f36
Merge remote-tracking branch 'parent/main' into upstream-20240424
kmycode Apr 23, 2024
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
9 changes: 0 additions & 9 deletions .rubocop_todo.yml
Original file line number Diff line number Diff line change
Expand Up @@ -57,15 +57,6 @@ Rails/OutputSafety:
Exclude:
- 'config/initializers/simple_form.rb'

# Configuration parameters: Include.
# Include: app/models/**/*.rb
Rails/UniqueValidationWithoutIndex:
Exclude:
- 'app/models/account_alias.rb'
- 'app/models/custom_filter_status.rb'
- 'app/models/identity.rb'
- 'app/models/webauthn_credential.rb'

# This cop supports unsafe autocorrection (--autocorrect-all).
# Configuration parameters: AllowedMethods, AllowedPatterns.
# AllowedMethods: ==, equal?, eql?
Expand Down
2 changes: 1 addition & 1 deletion Gemfile
Original file line number Diff line number Diff line change
Expand Up @@ -54,7 +54,7 @@ gem 'fast_blank', '~> 1.0'
gem 'fastimage'
gem 'hiredis', '~> 0.6'
gem 'htmlentities', '~> 4.3'
gem 'http', '~> 5.1'
gem 'http', '~> 5.2.0'
gem 'http_accept_language', '~> 2.1'
gem 'httplog', '~> 1.6.2'
gem 'i18n', '1.14.1' # TODO: Remove version when resolved: https://github.com/glebm/i18n-tasks/issues/552 / https://github.com/ruby-i18n/i18n/pull/688
Expand Down
15 changes: 8 additions & 7 deletions Gemfile.lock
Original file line number Diff line number Diff line change
Expand Up @@ -318,11 +318,12 @@ GEM
hiredis (0.6.3)
hkdf (0.3.0)
htmlentities (4.3.4)
http (5.1.1)
http (5.2.0)
addressable (~> 2.8)
base64 (~> 0.1)
http-cookie (~> 1.0)
http-form_data (~> 2.2)
llhttp-ffi (~> 0.4.0)
llhttp-ffi (~> 0.5.0)
http-cookie (1.0.5)
domain_name (~> 0.5)
http-form_data (2.3.0)
Expand Down Expand Up @@ -403,7 +404,7 @@ GEM
railties (>= 5.2)
rexml
link_header (0.0.8)
llhttp-ffi (0.4.0)
llhttp-ffi (0.5.0)
ffi-compiler (~> 1.0)
rake (~> 13.0)
lograge (0.14.0)
Expand Down Expand Up @@ -643,7 +644,7 @@ GEM
rspec-mocks (~> 3.0)
sidekiq (>= 5, < 8)
rspec-support (3.13.1)
rubocop (1.63.2)
rubocop (1.63.3)
json (~> 2.3)
language_server-protocol (>= 3.17.0)
parallel (~> 1.10)
Expand Down Expand Up @@ -860,7 +861,7 @@ DEPENDENCIES
hcaptcha (~> 7.1)
hiredis (~> 0.6)
htmlentities (~> 4.3)
http (~> 5.1)
http (~> 5.2.0)
http_accept_language (~> 2.1)
httplog (~> 1.6.2)
i18n (= 1.14.1)
Expand Down Expand Up @@ -951,7 +952,7 @@ DEPENDENCIES
xorcist (~> 1.1)

RUBY VERSION
ruby 3.2.2p53
ruby 3.2.3p157

BUNDLED WITH
2.5.7
2.5.9
2 changes: 1 addition & 1 deletion app/controllers/api/v1/accounts/credentials_controller.rb
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
# frozen_string_literal: true

class Api::V1::Accounts::CredentialsController < Api::BaseController
before_action -> { doorkeeper_authorize! :read, :'read:accounts' }, except: [:update]
before_action -> { doorkeeper_authorize! :read, :'read:accounts', :'read:me' }, except: [:update]
before_action -> { doorkeeper_authorize! :write, :'write:accounts' }, only: [:update]
before_action :require_user!

Expand Down
8 changes: 8 additions & 0 deletions app/helpers/application_helper.rb
Original file line number Diff line number Diff line change
Expand Up @@ -115,6 +115,14 @@ def fa_icon(icon, attributes = {})
content_tag(:i, nil, attributes.merge(class: class_names.join(' ')))
end

def material_symbol(icon, attributes = {})
inline_svg_tag(
"400-24px/#{icon}.svg",
class: %w(icon).concat(attributes[:class].to_s.split),
role: :img
)
end

def check_icon
inline_svg_tag 'check.svg'
end
Expand Down
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
77 changes: 40 additions & 37 deletions app/javascript/mastodon/features/onboarding/index.jsx
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,7 @@ import EditNoteIcon from '@/material-icons/400-24px/edit_note.svg?react';
import PersonAddIcon from '@/material-icons/400-24px/person_add.svg?react';
import { focusCompose } from 'mastodon/actions/compose';
import { Icon } from 'mastodon/components/icon';
import { NotSignedInIndicator } from 'mastodon/components/not_signed_in_indicator';
import Column from 'mastodon/features/ui/components/column';
import { enableLocalTimeline, me } from 'mastodon/initial_state';
import { useAppSelector } from 'mastodon/store';
Expand All @@ -42,49 +43,51 @@ const Onboarding = () => {

return (
<Column>
<Switch>
<Route path='/start' exact>
<div className='scrollable privacy-policy'>
<div className='column-title'>
<img src={illustration} alt='' className='onboarding__illustration' />
<h3><FormattedMessage id='onboarding.start.title' defaultMessage="You've made it!" /></h3>
<p><FormattedMessage id='onboarding.start.lead' defaultMessage="Your new Mastodon account is ready to go. Here's how you can make the most of it:" /></p>
</div>

<div className='onboarding__steps'>
<Step to='/start/profile' completed={(!account.get('avatar').endsWith('missing.png')) || (account.get('display_name').length > 0 && account.get('note').length > 0)} icon='address-book-o' iconComponent={AccountCircleIcon} label={<FormattedMessage id='onboarding.steps.setup_profile.title' defaultMessage='Customize your profile' />} description={<FormattedMessage id='onboarding.steps.setup_profile.body' defaultMessage='Others are more likely to interact with you with a filled out profile.' />} />
<Step to='/start/follows' completed={(account.get('following_count') * 1) >= 1} icon='user-plus' iconComponent={PersonAddIcon} label={<FormattedMessage id='onboarding.steps.follow_people.title' defaultMessage='Find at least {count, plural, one {one person} other {# people}} to follow' values={{ count: 7 }} />} description={<FormattedMessage id='onboarding.steps.follow_people.body' defaultMessage="You curate your own home feed. Let's fill it with interesting people." />} />
<Step onClick={handleComposeClick} completed={(account.get('statuses_count') * 1) >= 1} icon='pencil-square-o' iconComponent={EditNoteIcon} label={<FormattedMessage id='onboarding.steps.publish_status.title' defaultMessage='Make your first post' />} description={<FormattedMessage id='onboarding.steps.publish_status.body' defaultMessage='Say hello to the world.' values={{ emoji: <img className='emojione' alt='🐘' src={`${assetHost}/emoji/1f418.svg`} /> }} />} />
<Step to='/start/share' icon='copy' iconComponent={ContentCopyIcon} label={<FormattedMessage id='onboarding.steps.share_profile.title' defaultMessage='Share your profile' />} description={<FormattedMessage id='onboarding.steps.share_profile.body' defaultMessage='Let your friends know how to find you on Mastodon!' />} />
</div>

<p className='onboarding__lead'><FormattedMessage id='onboarding.start.skip' defaultMessage="Don't need help getting started?" /></p>
{account ? (
<Switch>
<Route path='/start' exact>
<div className='scrollable privacy-policy'>
<div className='column-title'>
<img src={illustration} alt='' className='onboarding__illustration' />
<h3><FormattedMessage id='onboarding.start.title' defaultMessage="You've made it!" /></h3>
<p><FormattedMessage id='onboarding.start.lead' defaultMessage="Your new Mastodon account is ready to go. Here's how you can make the most of it:" /></p>
</div>

<div className='onboarding__steps'>
<Step to='/start/profile' completed={(!account.get('avatar').endsWith('missing.png')) || (account.get('display_name').length > 0 && account.get('note').length > 0)} icon='address-book-o' iconComponent={AccountCircleIcon} label={<FormattedMessage id='onboarding.steps.setup_profile.title' defaultMessage='Customize your profile' />} description={<FormattedMessage id='onboarding.steps.setup_profile.body' defaultMessage='Others are more likely to interact with you with a filled out profile.' />} />
<Step to='/start/follows' completed={(account.get('following_count') * 1) >= 1} icon='user-plus' iconComponent={PersonAddIcon} label={<FormattedMessage id='onboarding.steps.follow_people.title' defaultMessage='Find at least {count, plural, one {one person} other {# people}} to follow' values={{ count: 7 }} />} description={<FormattedMessage id='onboarding.steps.follow_people.body' defaultMessage="You curate your own home feed. Let's fill it with interesting people." />} />
<Step onClick={handleComposeClick} completed={(account.get('statuses_count') * 1) >= 1} icon='pencil-square-o' iconComponent={EditNoteIcon} label={<FormattedMessage id='onboarding.steps.publish_status.title' defaultMessage='Make your first post' />} description={<FormattedMessage id='onboarding.steps.publish_status.body' defaultMessage='Say hello to the world.' values={{ emoji: <img className='emojione' alt='🐘' src={`${assetHost}/emoji/1f418.svg`} /> }} />} />
<Step to='/start/share' icon='copy' iconComponent={ContentCopyIcon} label={<FormattedMessage id='onboarding.steps.share_profile.title' defaultMessage='Share your profile' />} description={<FormattedMessage id='onboarding.steps.share_profile.body' defaultMessage='Let your friends know how to find you on Mastodon!' />} />
</div>

<p className='onboarding__lead'><FormattedMessage id='onboarding.start.skip' defaultMessage="Don't need help getting started?" /></p>

<div className='onboarding__links'>
<Link to='/explore' className='onboarding__link'>
<FormattedMessage id='onboarding.actions.go_to_explore' defaultMessage='Take me to trending' />
<Icon icon={ArrowRightAltIcon} />
</Link>

<div className='onboarding__links'>
<Link to='/explore' className='onboarding__link'>
<FormattedMessage id='onboarding.actions.go_to_explore' defaultMessage='Take me to trending' />
<Icon icon={ArrowRightAltIcon} />
</Link>
{enableLocalTimeline && (
<Link to='/public/local/fixed' className='onboarding__link'>
<FormattedMessage id='onboarding.actions.go_to_local_timeline' defaultMessage='See posts from local' />
<Icon icon={ArrowRightAltIcon} />
</Link>
)}

{enableLocalTimeline && (
<Link to='/public/local/fixed' className='onboarding__link'>
<FormattedMessage id='onboarding.actions.go_to_local_timeline' defaultMessage='See posts from local' />
<Link to='/home' className='onboarding__link'>
<FormattedMessage id='onboarding.actions.go_to_home' defaultMessage='Take me to my home feed' />
<Icon icon={ArrowRightAltIcon} />
</Link>
)}

<Link to='/home' className='onboarding__link'>
<FormattedMessage id='onboarding.actions.go_to_home' defaultMessage='Take me to my home feed' />
<Icon icon={ArrowRightAltIcon} />
</Link>
</div>
</div>
</div>
</Route>
</Route>

<Route path='/start/profile' component={Profile} />
<Route path='/start/follows' component={Follows} />
<Route path='/start/share' component={Share} />
</Switch>
<Route path='/start/profile' component={Profile} />
<Route path='/start/follows' component={Follows} />
<Route path='/start/share' component={Share} />
</Switch>
) : <NotSignedInIndicator />}

<Helmet>
<meta name='robots' content='noindex' />
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -307,7 +307,7 @@ class DetailedStatus extends ImmutablePureComponent {
<span className='detailed-status__favorites'>
<AnimatedNumber value={status.get('status_referred_by_count')} />
</span>
<FormattedMessage id='status.status_references' defaultMessage='{count, plural, one {quote} other {quotes}}' values={{ count: status.get('status_referred_by_count') }} />
<FormattedMessage id='status.quotes' defaultMessage='{count, plural, one {quote} other {quotes}}' values={{ count: status.get('status_referred_by_count') }} />
</Link>
);
} else {
Expand All @@ -316,7 +316,7 @@ class DetailedStatus extends ImmutablePureComponent {
<span className='detailed-status__favorites'>
<AnimatedNumber value={status.get('status_referred_by_count')} />
</span>
<FormattedMessage id='status.status_references' defaultMessage='{count, plural, one {quote} other {quotes}}' values={{ count: status.get('status_referred_by_count') }} />
<FormattedMessage id='status.quotes' defaultMessage='{count, plural, one {quote} other {quotes}}' values={{ count: status.get('status_referred_by_count') }} />
</a>
);
}
Expand Down
1 change: 1 addition & 0 deletions app/javascript/mastodon/locales/be.json
Original file line number Diff line number Diff line change
Expand Up @@ -297,6 +297,7 @@
"filter_modal.select_filter.subtitle": "Скарыстайцеся існуючай катэгорыяй або стварыце новую",
"filter_modal.select_filter.title": "Фільтраваць гэты допіс",
"filter_modal.title.status": "Фільтраваць допіс",
"filtered_notifications_banner.mentions": "{count, plural, one {згадванне} few {згадванні} many {згадванняў} other {згадвання}}",
"filtered_notifications_banner.pending_requests": "Апавяшчэнні ад {count, plural, =0 {# людзей якіх} one {# чалавека якіх} few {# чалавек якіх} many {# людзей якіх} other {# чалавека якіх}} вы магчыма ведаеце",
"filtered_notifications_banner.title": "Адфільтраваныя апавяшчэнні",
"firehose.all": "Усе",
Expand Down
2 changes: 1 addition & 1 deletion app/javascript/mastodon/locales/en.json
Original file line number Diff line number Diff line change
Expand Up @@ -900,6 +900,7 @@
"status.pinned": "Pinned post",
"status.quote": "Quote",
"status.quote_filtered": "This quote is filtered because of muting, blocking or domain blocking",
"status.quotes": "{count, plural, one {quote} other {quotes}}",
"status.read_more": "Read more",
"status.reblog": "Boost",
"status.reblog_private": "Boost with original visibility",
Expand All @@ -922,7 +923,6 @@
"status.show_more": "Show more",
"status.show_more_all": "Show more for all",
"status.show_original": "Show original",
"status.status_references": "{count, plural, one {quote} other {quotes}}",
"status.title.with_attachments": "{user} posted {attachmentCount, plural, one {an attachment} other {{attachmentCount} attachments}}",
"status.translate": "Translate",
"status.translated_from_with": "Translated from {lang} using {provider}",
Expand Down
2 changes: 1 addition & 1 deletion app/javascript/mastodon/locales/es.json
Original file line number Diff line number Diff line change
Expand Up @@ -642,7 +642,7 @@
"report.statuses.subtitle": "Selecciona todos los que correspondan",
"report.statuses.title": "¿Hay alguna publicación que respalde este informe?",
"report.submit": "Enviar",
"report.target": "Reportando",
"report.target": "Reportando {target}",
"report.thanks.take_action": "Aquí están tus opciones para controlar lo que ves en Mastodon:",
"report.thanks.take_action_actionable": "Mientras revisamos esto, puedes tomar medidas contra @{name}:",
"report.thanks.title": "¿No quieres esto?",
Expand Down
14 changes: 7 additions & 7 deletions app/javascript/mastodon/locales/fi.json
Original file line number Diff line number Diff line change
Expand Up @@ -298,19 +298,19 @@
"filter_modal.select_filter.title": "Suodata tämä julkaisu",
"filter_modal.title.status": "Suodata julkaisu",
"filtered_notifications_banner.mentions": "{count, plural, one {maininta} other {mainintaa}}",
"filtered_notifications_banner.pending_requests": "Ilmoitukset {count, plural, =0 {ei keltään} one {yhdeltä henkilöltä} other {# henkilöltä}}, jonka saatat tuntea",
"filtered_notifications_banner.pending_requests": "Sinulle on ilmoituksia mahdollisesti tuntemiltasi henkilöiltä seuraavasti: {count, plural, =0 {Ei keltään} one {Yhdeltä henkilöltä} other {# henkilöltä}}",
"filtered_notifications_banner.title": "Suodatetut ilmoitukset",
"firehose.all": "Kaikki",
"firehose.local": "Tämä palvelin",
"firehose.remote": "Muut palvelimet",
"follow_request.authorize": "Valtuuta",
"follow_request.reject": "Hylkää",
"follow_requests.unlocked_explanation": "Vaikkei tiliäsi ole lukittu, palvelimen {domain} ylläpito on arvioinut, että saatat olla halukas tarkistamaan nämä seuraamispyynnöt erikseen.",
"follow_suggestions.curated_suggestion": "Ylläpidon valinta",
"follow_suggestions.curated_suggestion": "Ehdotus ylläpidolta",
"follow_suggestions.dismiss": "Älä näytä uudelleen",
"follow_suggestions.hints.featured": "Tämän profiilin on valinnut palvelimen {domain} tiimi.",
"follow_suggestions.hints.friends_of_friends": "Tämä profiili on suosittu seuraamiesi henkilöiden parissa.",
"follow_suggestions.hints.most_followed": "Tämä profiili on yksi seuratuimmista palvelimella {domain}.",
"follow_suggestions.hints.friends_of_friends": "Seuraamasi käyttäjät suosivat tätä profiilia.",
"follow_suggestions.hints.most_followed": "Tämä profiili on palvelimen {domain} seuratuimpia.",
"follow_suggestions.hints.most_interactions": "Tämä profiili on viime aikoina saanut paljon huomiota palvelimella {domain}.",
"follow_suggestions.hints.similar_to_recently_followed": "Tämä profiili on samankaltainen kuin profiilit, joita olet viimeksi seurannut.",
"follow_suggestions.personalized_suggestion": "Mukautettu ehdotus",
Expand Down Expand Up @@ -473,10 +473,10 @@
"notification.poll": "Kysely, johon osallistuit, on päättynyt",
"notification.reblog": "{name} tehosti julkaisuasi",
"notification.relationships_severance_event": "Menetettiin yhteydet palvelimeen {name}",
"notification.relationships_severance_event.account_suspension": "Palvelimen {from} ylläpitäjä on jäädyttänyt verkkotunnuksen {target}, minkä takia et voi enää vastaanottaa heidän päivityksiään tai olla vuorovaikutuksessa heidän kanssaan.",
"notification.relationships_severance_event.domain_block": "Palvelimen {from} ylläpitäjä on estänyt verkkotunnuksen {target}, mukaan lukien {followersCount} seuraajistasi ja {followingCount, plural, one {# seuratuistasi} other {# seuratuistasi}}.",
"notification.relationships_severance_event.account_suspension": "Palvelimen {from} ylläpitäjä on jäädyttänyt palvelimen {target} vuorovaikutuksen. Enää et voi siis vastaanottaa päivityksiä heiltä tai olla yhteyksissä heidän kanssaan.",
"notification.relationships_severance_event.domain_block": "Palvelimen {from} ylläpitäjä on estänyt palvelimen {target} vuorovaikutuksen – mukaan lukien {followersCount} seuraajistasi ja {followingCount, plural, one {# seuratuistasi} other {# seuratuistasi}}.",
"notification.relationships_severance_event.learn_more": "Lue lisää",
"notification.relationships_severance_event.user_domain_block": "Olet estänyt verkkotunnuksen {target}, mikä poisti {followersCount} seuraajistasi ja {followingCount, plural, one {# seuratuistasi} other {# seuratuistasi}}.",
"notification.relationships_severance_event.user_domain_block": "Olet estänyt palvelimen {target}, mikä poisti {followersCount} seuraajistasi ja {followingCount, plural, one {# seuratuistasi} other {# seuratuistasi}}.",
"notification.status": "{name} julkaisi juuri",
"notification.update": "{name} muokkasi julkaisua",
"notification_requests.accept": "Hyväksy",
Expand Down
4 changes: 2 additions & 2 deletions app/javascript/mastodon/locales/fr.json
Original file line number Diff line number Diff line change
Expand Up @@ -550,10 +550,10 @@
"onboarding.share.message": "Je suis {username} sur #Mastodon ! Suivez-moi sur {url}",
"onboarding.share.next_steps": "Étapes suivantes possibles :",
"onboarding.share.title": "Partager votre profil",
"onboarding.start.lead": "Your new Mastodon account is ready to go. Here's how you can make the most of it:",
"onboarding.start.lead": "Vous faites désormais partie de Mastodon, une plateforme de médias sociaux unique et décentralisée où c'est vous, et non un algorithme, qui créez votre propre expérience. Nous allons vous aider à vous lancer dans cette nouvelle frontière sociale :",
"onboarding.start.skip": "Vous n’avez donc pas besoin d’aide pour commencer ?",
"onboarding.start.title": "Vous avez réussi !",
"onboarding.steps.follow_people.body": "You curate your own feed. Lets fill it with interesting people.",
"onboarding.steps.follow_people.body": "Suivre des personnes intéressantes, c'est la raison d'être de Mastodon.",
"onboarding.steps.follow_people.title": "Personnaliser votre flux principal",
"onboarding.steps.publish_status.body": "Dites bonjour au monde avec du texte, des photos, des vidéos ou des sondages {emoji}",
"onboarding.steps.publish_status.title": "Rédigez votre premier message",
Expand Down
Loading
Loading