diff --git a/.github/ISSUE_TEMPLATE/2.server_bug_report.yml b/.github/ISSUE_TEMPLATE/2.server_bug_report.yml index 743c32b79e..baf95e2857 100644 --- a/.github/ISSUE_TEMPLATE/2.server_bug_report.yml +++ b/.github/ISSUE_TEMPLATE/2.server_bug_report.yml @@ -59,7 +59,7 @@ body: 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. v4.0.4) + - Ruby version: (from `ruby --version`, eg. v4.0.5) - Node.js version: (from `node --version`, eg. v22.16.0) validations: required: false diff --git a/.github/ISSUE_TEMPLATE/3.troubleshooting.yml b/.github/ISSUE_TEMPLATE/3.troubleshooting.yml index ebd8485071..ea1963abc2 100644 --- a/.github/ISSUE_TEMPLATE/3.troubleshooting.yml +++ b/.github/ISSUE_TEMPLATE/3.troubleshooting.yml @@ -60,7 +60,7 @@ body: value: | Please at least include those informations: - Operating system: (eg. Ubuntu 24.04.2) - - Ruby version: (from `ruby --version`, eg. v4.0.4) + - Ruby version: (from `ruby --version`, eg. v4.0.5) - Node.js version: (from `node --version`, eg. v22.16.0) validations: required: false diff --git a/.github/actions/setup-ruby/action.yml b/.github/actions/setup-ruby/action.yml index aaf6dc752a..f26448f9ed 100644 --- a/.github/actions/setup-ruby/action.yml +++ b/.github/actions/setup-ruby/action.yml @@ -23,7 +23,7 @@ runs: ${{ inputs.additional-system-dependencies }} - name: Set up Ruby - uses: ruby/setup-ruby@6aaa311d81eba98ae12eaffbcb63296ace0efcde # v1 + uses: ruby/setup-ruby@afeafc3d1ab54a631816aba4c914a0081c12ff2f # v1 with: ruby-version: ${{ inputs.ruby-version }} bundler-cache: true diff --git a/.github/workflows/bundler-audit.yml b/.github/workflows/bundler-audit.yml index 797dd5687e..b58fe60056 100644 --- a/.github/workflows/bundler-audit.yml +++ b/.github/workflows/bundler-audit.yml @@ -31,7 +31,7 @@ jobs: uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6 - name: Set up Ruby - uses: ruby/setup-ruby@6aaa311d81eba98ae12eaffbcb63296ace0efcde # v1 + uses: ruby/setup-ruby@afeafc3d1ab54a631816aba4c914a0081c12ff2f # v1 with: bundler-cache: true diff --git a/.github/workflows/lint-haml.yml b/.github/workflows/lint-haml.yml index a2e6065237..ff18689c05 100644 --- a/.github/workflows/lint-haml.yml +++ b/.github/workflows/lint-haml.yml @@ -34,7 +34,7 @@ jobs: uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6 - name: Set up Ruby - uses: ruby/setup-ruby@6aaa311d81eba98ae12eaffbcb63296ace0efcde # v1 + uses: ruby/setup-ruby@afeafc3d1ab54a631816aba4c914a0081c12ff2f # v1 with: bundler-cache: true diff --git a/.github/workflows/lint-ruby.yml b/.github/workflows/lint-ruby.yml index b939ecf5ac..8095c40724 100644 --- a/.github/workflows/lint-ruby.yml +++ b/.github/workflows/lint-ruby.yml @@ -36,7 +36,7 @@ jobs: uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6 - name: Set up Ruby - uses: ruby/setup-ruby@6aaa311d81eba98ae12eaffbcb63296ace0efcde # v1 + uses: ruby/setup-ruby@afeafc3d1ab54a631816aba4c914a0081c12ff2f # v1 with: bundler-cache: true diff --git a/.ruby-version b/.ruby-version index c5106e6d13..7636e75650 100644 --- a/.ruby-version +++ b/.ruby-version @@ -1 +1 @@ -4.0.4 +4.0.5 diff --git a/Dockerfile b/Dockerfile index feb5b34b80..6f44c4c3e1 100644 --- a/Dockerfile +++ b/Dockerfile @@ -13,7 +13,7 @@ ARG BASE_REGISTRY="docker.io" # Ruby image to use for base image, change with [--build-arg RUBY_VERSION="4.0.x"] # renovate: datasource=docker depName=docker.io/ruby -ARG RUBY_VERSION="4.0.4" +ARG RUBY_VERSION="4.0.5" # # Node.js version to use in base image, change with [--build-arg NODE_MAJOR_VERSION="22"] # renovate: datasource=node-version depName=node ARG NODE_MAJOR_VERSION="24" diff --git a/Gemfile.lock b/Gemfile.lock index 70872eff96..62d049d033 100644 --- a/Gemfile.lock +++ b/Gemfile.lock @@ -1097,7 +1097,7 @@ DEPENDENCIES xorcist (~> 1.1) RUBY VERSION - ruby 4.0.4 + ruby 4.0.5 BUNDLED WITH 4.0.11 diff --git a/README.md b/README.md index e4b25b1716..7d468abbd2 100644 --- a/README.md +++ b/README.md @@ -75,7 +75,7 @@ Mastodon is a **free, open-source social network server** based on [ActivityPub] - **Ruby** 3.3+ - **PostgreSQL** 14+ - **Redis** 7.0+ -- **Node.js** 20+ +- **Node.js** 22+ - **FFmpeg** 5.1+ This repository includes deployment configurations for **Docker and docker-compose**, as well as for other environments like Heroku and Scalingo. For Helm charts, reference the [mastodon/chart repository](https://github.com/mastodon/chart). A [**standalone** installation guide](https://docs.joinmastodon.org/admin/install/) is available in the main documentation. diff --git a/Vagrantfile b/Vagrantfile index e2d703fac2..df91fceea4 100644 --- a/Vagrantfile +++ b/Vagrantfile @@ -12,7 +12,7 @@ sudo apt-add-repository 'deb https://dl.yarnpkg.com/debian/ stable main' # Add repo for NodeJS sudo mkdir -p /etc/apt/keyrings curl -fsSL https://deb.nodesource.com/gpgkey/nodesource-repo.gpg.key | sudo gpg --dearmor -o /etc/apt/keyrings/nodesource.gpg -NODE_MAJOR=20 +NODE_MAJOR=24 echo "deb [signed-by=/etc/apt/keyrings/nodesource.gpg] https://deb.nodesource.com/node_$NODE_MAJOR.x nodistro main" | sudo tee /etc/apt/sources.list.d/nodesource.list sudo apt-get update diff --git a/app/controllers/api/v1_alpha/collections_controller.rb b/app/controllers/api/v1_alpha/collections_controller.rb index 4e15b65ff5..1ca1cd6923 100644 --- a/app/controllers/api/v1_alpha/collections_controller.rb +++ b/app/controllers/api/v1_alpha/collections_controller.rb @@ -28,10 +28,9 @@ class Api::V1Alpha::CollectionsController < Api::BaseController cache_if_unauthenticated! authorize @account, :index_collections? - presenter = CollectionsPresenter.new(collections: @collections) - render json: presenter, serializer: REST::CollectionsWithAccountPreviewsSerializer + render json: @collections, each_serializer: REST::CollectionSerializer, adapter: :json rescue Mastodon::NotPermittedError - render json: { collections: [], partial_accounts: [] } + render json: { collections: [] } end def show @@ -74,7 +73,6 @@ class Api::V1Alpha::CollectionsController < Api::BaseController def set_collections @collections = @account.collections .with_tag - .preload(top_items: :account) .order(created_at: :desc) .offset(offset_param) .limit(limit_param(DEFAULT_COLLECTIONS_LIMIT)) diff --git a/app/helpers/admin/filter_helper.rb b/app/helpers/admin/filter_helper.rb index 40806a4515..a3dd83ecca 100644 --- a/app/helpers/admin/filter_helper.rb +++ b/app/helpers/admin/filter_helper.rb @@ -20,8 +20,9 @@ module Admin::FilterHelper def filter_link_to(text, link_to_params, link_class_params = link_to_params) new_url = filtered_url_for(link_to_params) new_class = filtered_url_for(link_class_params) + is_selected = selected?(link_class_params) - link_to text, new_url, class: filter_link_class(new_class) + link_to text, new_url, class: filter_link_class(new_class), 'aria-current': (is_selected ? 'true' : nil) end def table_link_to(icon, text, path, **options) diff --git a/app/javascript/mastodon/actions/compose.js b/app/javascript/mastodon/actions/compose.js index 1f8c934a55..d5f8ff1ea6 100644 --- a/app/javascript/mastodon/actions/compose.js +++ b/app/javascript/mastodon/actions/compose.js @@ -99,7 +99,7 @@ export const ensureComposeIsVisible = (getState) => { export function setComposeToStatus(status, text, spoiler_text) { return (dispatch, getState) => { - const maxOptions = getState().server.getIn(['server', 'configuration', 'polls', 'max_options']); + const maxOptions = getState().server.server.item?.configuration.polls.max_options; dispatch({ type: COMPOSE_SET_STATUS, diff --git a/app/javascript/mastodon/actions/server.js b/app/javascript/mastodon/actions/server.js deleted file mode 100644 index c291eb772a..0000000000 --- a/app/javascript/mastodon/actions/server.js +++ /dev/null @@ -1,139 +0,0 @@ -import api from '../api'; - -import { importFetchedAccount } from './importer'; - -export const SERVER_FETCH_REQUEST = 'Server_FETCH_REQUEST'; -export const SERVER_FETCH_SUCCESS = 'Server_FETCH_SUCCESS'; -export const SERVER_FETCH_FAIL = 'Server_FETCH_FAIL'; - -export const SERVER_TRANSLATION_LANGUAGES_FETCH_REQUEST = 'SERVER_TRANSLATION_LANGUAGES_FETCH_REQUEST'; -export const SERVER_TRANSLATION_LANGUAGES_FETCH_SUCCESS = 'SERVER_TRANSLATION_LANGUAGES_FETCH_SUCCESS'; -export const SERVER_TRANSLATION_LANGUAGES_FETCH_FAIL = 'SERVER_TRANSLATION_LANGUAGES_FETCH_FAIL'; - -export const EXTENDED_DESCRIPTION_REQUEST = 'EXTENDED_DESCRIPTION_REQUEST'; -export const EXTENDED_DESCRIPTION_SUCCESS = 'EXTENDED_DESCRIPTION_SUCCESS'; -export const EXTENDED_DESCRIPTION_FAIL = 'EXTENDED_DESCRIPTION_FAIL'; - -export const SERVER_DOMAIN_BLOCKS_FETCH_REQUEST = 'SERVER_DOMAIN_BLOCKS_FETCH_REQUEST'; -export const SERVER_DOMAIN_BLOCKS_FETCH_SUCCESS = 'SERVER_DOMAIN_BLOCKS_FETCH_SUCCESS'; -export const SERVER_DOMAIN_BLOCKS_FETCH_FAIL = 'SERVER_DOMAIN_BLOCKS_FETCH_FAIL'; - -export const fetchServer = () => (dispatch, getState) => { - if (getState().getIn(['server', 'server', 'isLoading'])) { - return; - } - - dispatch(fetchServerRequest()); - - api() - .get('/api/v2/instance').then(({ data }) => { - // Only import the account if it doesn't already exist, - // because the API is cached even for logged in users. - const account = data.contact.account; - if (account) { - const existingAccount = getState().getIn(['accounts', account.id]); - if (!existingAccount) { - dispatch(importFetchedAccount(account)); - } - } - dispatch(fetchServerSuccess(data)); - }).catch(err => dispatch(fetchServerFail(err))); -}; - -const fetchServerRequest = () => ({ - type: SERVER_FETCH_REQUEST, -}); - -const fetchServerSuccess = server => ({ - type: SERVER_FETCH_SUCCESS, - server, -}); - -const fetchServerFail = error => ({ - type: SERVER_FETCH_FAIL, - error, -}); - -export const fetchServerTranslationLanguages = () => (dispatch) => { - dispatch(fetchServerTranslationLanguagesRequest()); - - api() - .get('/api/v1/instance/translation_languages').then(({ data }) => { - dispatch(fetchServerTranslationLanguagesSuccess(data)); - }).catch(err => dispatch(fetchServerTranslationLanguagesFail(err))); -}; - -const fetchServerTranslationLanguagesRequest = () => ({ - type: SERVER_TRANSLATION_LANGUAGES_FETCH_REQUEST, -}); - -const fetchServerTranslationLanguagesSuccess = translationLanguages => ({ - type: SERVER_TRANSLATION_LANGUAGES_FETCH_SUCCESS, - translationLanguages, -}); - -const fetchServerTranslationLanguagesFail = error => ({ - type: SERVER_TRANSLATION_LANGUAGES_FETCH_FAIL, - error, -}); - -export const fetchExtendedDescription = () => (dispatch, getState) => { - if (getState().getIn(['server', 'extendedDescription', 'isLoading'])) { - return; - } - - dispatch(fetchExtendedDescriptionRequest()); - - api() - .get('/api/v1/instance/extended_description') - .then(({ data }) => dispatch(fetchExtendedDescriptionSuccess(data))) - .catch(err => dispatch(fetchExtendedDescriptionFail(err))); -}; - -const fetchExtendedDescriptionRequest = () => ({ - type: EXTENDED_DESCRIPTION_REQUEST, -}); - -const fetchExtendedDescriptionSuccess = description => ({ - type: EXTENDED_DESCRIPTION_SUCCESS, - description, -}); - -const fetchExtendedDescriptionFail = error => ({ - type: EXTENDED_DESCRIPTION_FAIL, - error, -}); - -export const fetchDomainBlocks = () => (dispatch, getState) => { - if (getState().getIn(['server', 'domainBlocks', 'isLoading'])) { - return; - } - - dispatch(fetchDomainBlocksRequest()); - - api() - .get('/api/v1/instance/domain_blocks') - .then(({ data }) => dispatch(fetchDomainBlocksSuccess(true, data))) - .catch(err => { - if (err.response.status === 404) { - dispatch(fetchDomainBlocksSuccess(false, [])); - } else { - dispatch(fetchDomainBlocksFail(err)); - } - }); -}; - -const fetchDomainBlocksRequest = () => ({ - type: SERVER_DOMAIN_BLOCKS_FETCH_REQUEST, -}); - -const fetchDomainBlocksSuccess = (isAvailable, blocks) => ({ - type: SERVER_DOMAIN_BLOCKS_FETCH_SUCCESS, - isAvailable, - blocks, -}); - -const fetchDomainBlocksFail = error => ({ - type: SERVER_DOMAIN_BLOCKS_FETCH_FAIL, - error, -}); diff --git a/app/javascript/mastodon/actions/server.ts b/app/javascript/mastodon/actions/server.ts new file mode 100644 index 0000000000..4e4795c123 --- /dev/null +++ b/app/javascript/mastodon/actions/server.ts @@ -0,0 +1,34 @@ +import { + apiGetInstance, + apiGetExtendedDescription, + apiGetDomainBlocks, + apiGetTranslationLanguages, +} from 'mastodon/api/instance'; +import { createDataLoadingThunk } from 'mastodon/store/typed_functions'; + +import { importFetchedAccount } from './importer'; + +export const fetchServer = createDataLoadingThunk( + 'server/fetch', + () => apiGetInstance(), + (instance, { dispatch }) => { + if (instance.contact.account) { + dispatch(importFetchedAccount(instance.contact.account)); + } + }, +); + +export const fetchExtendedDescription = createDataLoadingThunk( + 'server/extended_description', + () => apiGetExtendedDescription(), +); + +export const fetchServerTranslationLanguages = createDataLoadingThunk( + 'server/translation_languages', + () => apiGetTranslationLanguages(), +); + +export const fetchDomainBlocks = createDataLoadingThunk( + 'server/domain_blocks', + () => apiGetDomainBlocks(), +); diff --git a/app/javascript/mastodon/actions/statuses.js b/app/javascript/mastodon/actions/statuses.js index d714ed3849..109d676bfb 100644 --- a/app/javascript/mastodon/actions/statuses.js +++ b/app/javascript/mastodon/actions/statuses.js @@ -111,7 +111,7 @@ export function fetchStatusFail(id, error, skipLoading, parentQuotePostId) { export function redraft(status, raw_text, quoted_status_id = null) { return (dispatch, getState) => { - const maxOptions = getState().server.getIn(['server', 'configuration', 'polls', 'max_options']); + const maxOptions = getState().server.server.item?.configuration.polls.max_options; dispatch({ type: REDRAFT, diff --git a/app/javascript/mastodon/api/instance.ts b/app/javascript/mastodon/api/instance.ts index 764e8daab2..b3f04f12d1 100644 --- a/app/javascript/mastodon/api/instance.ts +++ b/app/javascript/mastodon/api/instance.ts @@ -2,6 +2,10 @@ import { apiRequestGet } from 'mastodon/api'; import type { ApiTermsOfServiceJSON, ApiPrivacyPolicyJSON, + ApiInstanceJSON, + ApiExtendedDescriptionJSON, + ApiTranslationLanguagesJSON, + ApiDomainBlockJSON, } from 'mastodon/api_types/instance'; export const apiGetTermsOfService = (version?: string) => @@ -13,3 +17,17 @@ export const apiGetTermsOfService = (version?: string) => export const apiGetPrivacyPolicy = () => apiRequestGet('v1/instance/privacy_policy'); + +export const apiGetInstance = () => + apiRequestGet('v2/instance'); + +export const apiGetExtendedDescription = () => + apiRequestGet('v1/instance/extended_description'); + +export const apiGetTranslationLanguages = () => + apiRequestGet( + 'v1/instance/translation_languages', + ); + +export const apiGetDomainBlocks = () => + apiRequestGet('v1/instance/domain_blocks'); diff --git a/app/javascript/mastodon/api_types/instance.ts b/app/javascript/mastodon/api_types/instance.ts index 3a29684b70..361dade4c7 100644 --- a/app/javascript/mastodon/api_types/instance.ts +++ b/app/javascript/mastodon/api_types/instance.ts @@ -1,3 +1,5 @@ +import type { ApiAccountJSON } from './accounts'; + export interface ApiTermsOfServiceJSON { effective_date: string; effective: boolean; @@ -9,3 +11,136 @@ export interface ApiPrivacyPolicyJSON { updated_at: string; content: string; } + +interface ApiBaseRuleJSON { + text: string; + hint: string; +} + +export interface ApiRuleJSON { + id: string; + text: string; + hint: string; + translations?: Record; +} + +export interface ApiExtendedDescriptionJSON { + updated_at: string; + content: string; +} + +export interface ApiDomainBlockJSON { + domain: string; + digest: string; + severity: string; + comment: string; +} + +export type ApiTranslationLanguagesJSON = Record; + +export interface ApiInstanceJSON { + domain: string; + title: string; + version: string; + source_url: string; + description: string; + languages: string[]; + usage: { + users: { + active_month: number; + }; + }; + thumbnail: { + url: string; + blurhash?: string; + description: string; + versions?: Record; + }; + contact: { + email: string | null; + account: ApiAccountJSON | null; + }; + api_versions: { + mastodon: number; + }; + registrations: { + enabled: boolean; + approval_required: boolean; + reason_required: boolean | null; + message: string | null; + min_age: string | null; + url: string | null; + }; + rules: ApiRuleJSON[]; + configuration: { + urls: { + streaming: string; + status: string | null; + about: string; + privacy_policy: string | null; + terms_of_service: string | null; + }; + + vapid: { + public_key: string; + }; + + accounts: { + max_display_name_length: number; + max_note_length: number; + max_avatar_description_length: number; + max_header_description_length: number; + max_featured_tags: number; + max_pinned_statuses: number; + max_profile_fields: number; + profile_field_name_limit: number; + profile_field_value_limit: number; + }; + + statuses: { + max_characters: number; + max_media_attachments: number; + characters_reserved_per_url: number; + }; + + media_attachments: { + description_limit: number; + image_matrix_limit: number; + image_size_limit: number; + supported_mime_types: string[]; + video_frame_rate_limit: number; + video_matrix_limit: number; + video_size_limit: number; + }; + + polls: { + max_options: number; + max_characters_per_option: number; + min_expiration: number; + max_expiration: number; + }; + + translation: { + enabled: boolean; + }; + + timeline_access: { + live_feeds: { + local: string; + remote: string; + }; + + hashtag_feeds: { + local: string; + remote: string; + }; + + trending_link_feeds: { + local: string; + remote: string; + }; + }; + + limited_federation: boolean; + }; +} diff --git a/app/javascript/mastodon/components/server_banner.jsx b/app/javascript/mastodon/components/server_banner.jsx index 939a92b281..b5484a1a37 100644 --- a/app/javascript/mastodon/components/server_banner.jsx +++ b/app/javascript/mastodon/components/server_banner.jsx @@ -22,7 +22,7 @@ const messages = defineMessages({ }); const mapStateToProps = state => ({ - server: state.getIn(['server', 'server']), + server: state.server.server, }); class ServerBanner extends PureComponent { @@ -40,7 +40,7 @@ class ServerBanner extends PureComponent { render () { const { server, intl } = this.props; - const isLoading = server.get('isLoading'); + const isLoading = server.isLoading; return (
@@ -50,8 +50,8 @@ class ServerBanner extends PureComponent { @@ -66,14 +66,14 @@ class ServerBanner extends PureComponent {
- ) : server.get('description')} + ) : server.item?.description}

- +
@@ -87,7 +87,7 @@ class ServerBanner extends PureComponent { ) : ( <> - +
diff --git a/app/javascript/mastodon/components/status.jsx b/app/javascript/mastodon/components/status.jsx index c909f9f0b1..808f4d73bf 100644 --- a/app/javascript/mastodon/components/status.jsx +++ b/app/javascript/mastodon/components/status.jsx @@ -556,7 +556,7 @@ class Status extends ImmutablePureComponent { ).find((item) => compareUrls(item.get('url'), cardUrl)); if (taggedCollection) { - media = ; + media = ; } else { media = ( + ); } } diff --git a/app/javascript/mastodon/components/status/handled_link.tsx b/app/javascript/mastodon/components/status/handled_link.tsx index 55d3c95435..9f0adc2ab6 100644 --- a/app/javascript/mastodon/components/status/handled_link.tsx +++ b/app/javascript/mastodon/components/status/handled_link.tsx @@ -4,7 +4,6 @@ import type { ComponentProps, FC } from 'react'; import classNames from 'classnames'; import { Link } from 'react-router-dom'; -import type { ApiCollectionJSON } from '@/mastodon/api_types/collections'; import type { ApiMentionJSON } from '@/mastodon/api_types/statuses'; import { getCollectionPath } from '@/mastodon/features/collections/utils'; import type { OnElementHandler } from '@/mastodon/utils/html'; @@ -15,7 +14,7 @@ export interface HandledLinkProps { prevText?: string; hashtagAccountId?: string; mention?: Pick; - collection?: Pick; + collectionId?: string; } export const HandledLink: FC> = ({ @@ -24,7 +23,7 @@ export const HandledLink: FC> = ({ prevText, hashtagAccountId, mention, - collection, + collectionId, className, children, ...props @@ -61,11 +60,11 @@ export const HandledLink: FC> = ({ {children} ); - } else if (collection) { + } else if (collectionId) { return ( {children} @@ -98,15 +97,18 @@ export const HandledLink: FC> = ({ export const useElementHandledLink = ({ hashtagAccountId, + hrefToCollectionId: hrefToCollection, hrefToMention, }: { hashtagAccountId?: string; + hrefToCollectionId?: (href: string) => string | undefined; hrefToMention?: (href: string) => ApiMentionJSON | undefined; } = {}) => { const onElement = useCallback( (element, { key, ...props }, children) => { if (element instanceof HTMLAnchorElement) { const mention = hrefToMention?.(element.href); + const collectionId = hrefToCollection?.(element.href); return ( {children} @@ -123,7 +126,7 @@ export const useElementHandledLink = ({ } return undefined; }, - [hashtagAccountId, hrefToMention], + [hashtagAccountId, hrefToCollection, hrefToMention], ); return { onElement }; }; diff --git a/app/javascript/mastodon/components/status_content.jsx b/app/javascript/mastodon/components/status_content.jsx index 920bdbf14e..4d9ae4fa3f 100644 --- a/app/javascript/mastodon/components/status_content.jsx +++ b/app/javascript/mastodon/components/status_content.jsx @@ -69,7 +69,7 @@ class TranslateButton extends PureComponent { } const mapStateToProps = state => ({ - languages: state.getIn(['server', 'translationLanguages', 'items']), + languages: state.server.translationLanguages.items, }); class StatusContent extends PureComponent { @@ -170,7 +170,7 @@ class StatusContent extends PureComponent { text={element.innerText} hashtagAccountId={this.props.status.getIn(['account', 'id'])} mention={mention?.toJSON()} - collection={taggedCollection?.toJSON()} + collectionId={taggedCollection?.get('id')} key={key} > {children} diff --git a/app/javascript/mastodon/features/about/components/rules.tsx b/app/javascript/mastodon/features/about/components/rules.tsx index 52339329fe..e8bde723ca 100644 --- a/app/javascript/mastodon/features/about/components/rules.tsx +++ b/app/javascript/mastodon/features/about/components/rules.tsx @@ -5,7 +5,6 @@ import type { IntlShape } from 'react-intl'; import { defineMessages, FormattedMessage, useIntl } from 'react-intl'; import { createSelector } from '@reduxjs/toolkit'; -import type { List as ImmutableList } from 'immutable'; import type { SelectItem } from '@/mastodon/components/dropdown_selector'; import { Select } from '@/mastodon/components/form_fields'; @@ -123,14 +122,13 @@ export const RulesSection: FC = ({ isLoading = false }) => { }; const selectRules = (state: RootState) => { - const rules = state.server.getIn([ - 'server', - 'rules', - ]) as ImmutableList | null; + const rules = state.server.server.item?.rules; + if (!rules) { return []; } - return rules.toJS() as Rule[]; + + return rules; }; const rulesSelector = createSelector( diff --git a/app/javascript/mastodon/features/about/index.jsx b/app/javascript/mastodon/features/about/index.jsx index 9814032cac..85b76aee32 100644 --- a/app/javascript/mastodon/features/about/index.jsx +++ b/app/javascript/mastodon/features/about/index.jsx @@ -18,6 +18,7 @@ import { LinkFooter} from 'mastodon/features/ui/components/link_footer'; import { Section } from './components/section'; import { RulesSection } from './components/rules'; +import { getColumnSkipLinkId } from '../ui/components/skip_links'; const messages = defineMessages({ title: { id: 'column.about', defaultMessage: 'About' }, @@ -41,10 +42,10 @@ const severityMessages = { }; const mapStateToProps = state => ({ - server: state.getIn(['server', 'server']), + server: state.server.server, locale: state.getIn(['meta', 'locale']), - extendedDescription: state.getIn(['server', 'extendedDescription']), - domainBlocks: state.getIn(['server', 'domainBlocks']), + extendedDescription: state.server.extendedDescription, + domainBlocks: state.server.domainBlocks, }); class About extends PureComponent { @@ -76,21 +77,21 @@ class About extends PureComponent { render () { const { multiColumn, intl, server, extendedDescription, domainBlocks, locale } = this.props; - const isLoading = server.get('isLoading'); + const isLoading = server.isLoading; return ( -
+
`${value} ${key.replace('@', '')}`).join(', ')} + alt={server.item?.thumbnail.description ?? ''} + blurhash={server.item?.thumbnail.blurhash} + src={server.item?.thumbnail.url} + srcSet={Object.keys(server.item?.thumbnail.versions ?? {}).map((key) => `${server.item?.thumbnail.versions && server.item.thumbnail.versions[key]} ${key.replace('@', '')}`).join(', ')} className='about__header__hero' /> -

{isLoading ? : server.get('domain')}

+

{isLoading ? : server.domain}

Mastodon }} />

@@ -98,7 +99,7 @@ class About extends PureComponent {

- +

@@ -106,12 +107,12 @@ class About extends PureComponent {
- {extendedDescription.get('isLoading') ? ( + {extendedDescription.isLoading ? ( <>
@@ -121,10 +122,10 @@ class About extends PureComponent {
- ) : (extendedDescription.get('content')?.length > 0 ? ( + ) : (extendedDescription.item?.content?.length > 0 ? (
) : (

@@ -134,26 +135,26 @@ class About extends PureComponent {
- {domainBlocks.get('isLoading') ? ( + {domainBlocks.isLoading ? ( <>
- ) : (domainBlocks.get('isAvailable') ? ( + ) : (domainBlocks.isAvailable ? ( <>

- {domainBlocks.get('items').size > 0 && ( + {domainBlocks.items.length > 0 && (
- {domainBlocks.get('items').map(block => ( -
+ {domainBlocks.items.map(block => ( +
-
{block.get('domain')}
- {intl.formatMessage(severityMessages[block.get('severity')].title)} +
{block.domain}
+ {intl.formatMessage(severityMessages[block.severity].title)}
-

{(block.get('comment') || '').length > 0 ? block.get('comment') : }

+

{(block.comment ?? '').length > 0 ? block.comment : }

))}
@@ -164,7 +165,7 @@ class About extends PureComponent { ))}
- +

diff --git a/app/javascript/mastodon/features/account_edit/featured_tags.tsx b/app/javascript/mastodon/features/account_edit/featured_tags.tsx index 5fc602208d..fedfde62e3 100644 --- a/app/javascript/mastodon/features/account_edit/featured_tags.tsx +++ b/app/javascript/mastodon/features/account_edit/featured_tags.tsx @@ -37,10 +37,7 @@ const selectTags = createAppSelector( [ (state) => state.profileEdit, (state) => - state.server.getIn( - ['server', 'accounts', 'max_featured_tags'], - 10, - ) as number, + state.server.server.item?.configuration.accounts.max_featured_tags ?? 0, ], (profileEdit, maxTags) => ({ tags: profileEdit.profile?.featuredTags ?? [], diff --git a/app/javascript/mastodon/features/account_edit/index.tsx b/app/javascript/mastodon/features/account_edit/index.tsx index 0199c3efa4..d00473043e 100644 --- a/app/javascript/mastodon/features/account_edit/index.tsx +++ b/app/javascript/mastodon/features/account_edit/index.tsx @@ -133,12 +133,7 @@ export const AccountEdit: FC = () => { const maxFieldCount = useAppSelector( (state) => - (state.server.getIn([ - 'server', - 'configuration', - 'accounts', - 'max_profile_fields', - ]) as number | undefined) ?? 4, + state.server.server.item?.configuration.accounts.max_profile_fields ?? 4, ); const handleOpenModal = useCallback( diff --git a/app/javascript/mastodon/features/account_edit/modals/bio_modal.tsx b/app/javascript/mastodon/features/account_edit/modals/bio_modal.tsx index ff4febeebb..8d286dedce 100644 --- a/app/javascript/mastodon/features/account_edit/modals/bio_modal.tsx +++ b/app/javascript/mastodon/features/account_edit/modals/bio_modal.tsx @@ -36,13 +36,7 @@ export const BioModal: FC = ({ onClose }) => { ); const [newBio, setNewBio] = useState(bio ?? ''); const maxLength = useAppSelector( - (state) => - state.server.getIn([ - 'server', - 'configuration', - 'accounts', - 'max_note_length', - ]) as number | undefined, + (state) => state.server.server.item?.configuration.accounts.max_note_length, ); const dispatch = useAppDispatch(); diff --git a/app/javascript/mastodon/features/account_edit/modals/fields_modals.tsx b/app/javascript/mastodon/features/account_edit/modals/fields_modals.tsx index 98324cf4dd..9fc26ac525 100644 --- a/app/javascript/mastodon/features/account_edit/modals/fields_modals.tsx +++ b/app/javascript/mastodon/features/account_edit/modals/fields_modals.tsx @@ -9,8 +9,6 @@ import type { FC, FocusEventHandler } from 'react'; import { defineMessages, FormattedMessage, useIntl } from 'react-intl'; -import type { Map as ImmutableMap } from 'immutable'; - import { closeModal } from '@/mastodon/actions/modal'; import { Button } from '@/mastodon/components/button'; import type { FieldStatus } from '@/mastodon/components/form_fields'; @@ -97,15 +95,10 @@ const messages = defineMessages({ // We have two different values- the hard limit set by the server, // and the soft limit for mobile display. const selectFieldLimits = createAppSelector( - [ - (state) => - state.server.getIn(['server', 'configuration', 'accounts']) as - | ImmutableMap - | undefined, - ], + [(state) => state.server.server.item?.configuration.accounts], (accounts) => ({ - nameLimit: accounts?.get('profile_field_name_limit'), - valueLimit: accounts?.get('profile_field_value_limit'), + nameLimit: accounts?.profile_field_name_limit, + valueLimit: accounts?.profile_field_value_limit, }), ); diff --git a/app/javascript/mastodon/features/account_edit/modals/image_alt.tsx b/app/javascript/mastodon/features/account_edit/modals/image_alt.tsx index d9d014f792..61f5d5ffdd 100644 --- a/app/javascript/mastodon/features/account_edit/modals/image_alt.tsx +++ b/app/javascript/mastodon/features/account_edit/modals/image_alt.tsx @@ -84,15 +84,8 @@ export const ImageAltTextField: FC<{ }> = ({ imageSrc, altText, onChange, hideTip }) => { const altLimit = useAppSelector( (state) => - state.server.getIn( - [ - 'server', - 'configuration', - 'accounts', - 'max_header_description_length', - ], - 150, - ) as number, + state.server.server.item?.configuration.accounts + .max_header_description_length ?? 0, ); const handleChange: ChangeEventHandler = useCallback( diff --git a/app/javascript/mastodon/features/account_edit/modals/name_modal.tsx b/app/javascript/mastodon/features/account_edit/modals/name_modal.tsx index 07779a02a7..de42977140 100644 --- a/app/javascript/mastodon/features/account_edit/modals/name_modal.tsx +++ b/app/javascript/mastodon/features/account_edit/modals/name_modal.tsx @@ -33,12 +33,7 @@ export const NameModal: FC = ({ onClose }) => { ); const maxLength = useAppSelector( (state) => - state.server.getIn([ - 'server', - 'configuration', - 'accounts', - 'max_display_name_length', - ]) as number | undefined, + state.server.server.item?.configuration.accounts.max_display_name_length, ); const [newName, setNewName] = useState(displayName ?? ''); diff --git a/app/javascript/mastodon/features/account_featured/components/empty_message.tsx b/app/javascript/mastodon/features/account_featured/components/empty_message.tsx index 19ced4ce23..aa1dc4078e 100644 --- a/app/javascript/mastodon/features/account_featured/components/empty_message.tsx +++ b/app/javascript/mastodon/features/account_featured/components/empty_message.tsx @@ -2,14 +2,15 @@ import { useCallback } from 'react'; import { FormattedMessage } from 'react-intl'; -import { useParams } from 'react-router'; import { Link } from 'react-router-dom'; import { openModal } from '@/mastodon/actions/modal'; import { Button } from '@/mastodon/components/button'; +import { DisplayName } from '@/mastodon/components/display_name'; import { EmptyState } from '@/mastodon/components/empty_state'; import { LimitedAccountHint } from '@/mastodon/components/limited_account_hint'; import { areCollectionsEnabled } from '@/mastodon/features/collections/utils'; +import { useAccount } from '@/mastodon/hooks/useAccount'; import { useCurrentAccountId } from '@/mastodon/hooks/useAccountId'; import { useAppDispatch } from '@/mastodon/store'; @@ -28,8 +29,8 @@ export const EmptyMessage: React.FC = ({ blockedBy, withoutAddCollectionButton, }) => { - const { acct } = useParams<{ acct?: string }>(); const me = useCurrentAccountId(); + const account = useAccount(accountId); const dispatch = useAppDispatch(); @@ -116,12 +117,12 @@ export const EmptyMessage: React.FC = ({ /> ); } else { - if (acct) { + if (account) { title = ( }} /> ); } else { diff --git a/app/javascript/mastodon/features/account_timeline/modals/join_modal.tsx b/app/javascript/mastodon/features/account_timeline/modals/join_modal.tsx index e5401fbebe..40e2b82bca 100644 --- a/app/javascript/mastodon/features/account_timeline/modals/join_modal.tsx +++ b/app/javascript/mastodon/features/account_timeline/modals/join_modal.tsx @@ -31,7 +31,7 @@ const selectServerName = createAppSelector( [ (state) => state.accounts, (_, accountId: string) => accountId, - (state) => state.server.getIn(['server', 'domain']) as string | undefined, + (state) => state.server.server.item?.domain, ], (accounts, accountId, serverDomain) => { const acct = accounts.getIn([accountId, 'acct']) as string | undefined; diff --git a/app/javascript/mastodon/features/collections/components/collection_lockup.tsx b/app/javascript/mastodon/features/collections/components/collection_lockup.tsx index c79de4f61e..e16d49e792 100644 --- a/app/javascript/mastodon/features/collections/components/collection_lockup.tsx +++ b/app/javascript/mastodon/features/collections/components/collection_lockup.tsx @@ -47,6 +47,7 @@ export interface CollectionLockupProps { withTimestamp?: boolean; sideContent?: React.ReactNode; className?: string; + headingLevel?: 'h2' | 'h3' | 'h4'; } export const CollectionLockup: React.FC = ({ @@ -54,6 +55,7 @@ export const CollectionLockup: React.FC = ({ withAuthorHandle = true, withTimestamp, sideContent, + headingLevel = 'h3', className, }) => { const { id, name } = collection; @@ -70,7 +72,7 @@ export const CollectionLockup: React.FC = ({ sideContent={sideContent} > { - const shareMessage = isOwnCollection - ? intl.formatMessage(messages.shareTextOwn, { - link: collectionLink, - }) - : intl.formatMessage(messages.shareTextOther, { - link: collectionLink, - }); + let shareMessage = isOwnCollection + ? intl.formatMessage(messages.shareTextOwn) + : intl.formatMessage(messages.shareTextOther); + shareMessage += `\n\n${collectionLink}`; onClose(); dispatch(changeCompose(shareMessage)); @@ -93,7 +92,7 @@ export const CollectionShareModal: React.FC<{ />
- +
{ this.textareaRef.current.setSelectionRange(selectionStart, selectionEnd); this.textareaRef.current.focus(); - this.setState({ highlighted: true }); - this.timeout = setTimeout(() => this.setState({ highlighted: false }), 700); }).catch(console.error); } else if(prevProps.isSubmitting && !this.props.isSubmitting) { this.textareaRef.current.focus(); @@ -252,7 +246,6 @@ class ComposeForm extends ImmutablePureComponent { render () { const { intl, onPaste, onDrop, autoFocus, withoutNavigation, maxChars, isSubmitting } = this.props; - const { highlighted } = this.state; return (
@@ -260,7 +253,7 @@ class ComposeForm extends ImmutablePureComponent { {!withoutNavigation && } -
+
diff --git a/app/javascript/mastodon/features/compose/containers/compose_form_container.js b/app/javascript/mastodon/features/compose/containers/compose_form_container.js index 4ace6d934d..c5cffff10d 100644 --- a/app/javascript/mastodon/features/compose/containers/compose_form_container.js +++ b/app/javascript/mastodon/features/compose/containers/compose_form_container.js @@ -58,7 +58,7 @@ const mapStateToProps = state => ({ && !state.getIn(['settings', 'dismissed_banners', PRIVATE_QUOTE_MODAL_ID]), isInReply: state.getIn(['compose', 'in_reply_to']) !== null, lang: state.getIn(['compose', 'language']), - maxChars: state.getIn(['server', 'server', 'configuration', 'statuses', 'max_characters'], 500), + maxChars: state.getIn(['server', 'server', 'item', 'configuration', 'statuses', 'max_characters'], 500), }); const mapDispatchToProps = (dispatch, props) => ({ diff --git a/app/javascript/mastodon/features/getting_started/index.tsx b/app/javascript/mastodon/features/getting_started/index.tsx index f4f66f1404..84c786fa06 100644 --- a/app/javascript/mastodon/features/getting_started/index.tsx +++ b/app/javascript/mastodon/features/getting_started/index.tsx @@ -13,7 +13,7 @@ const GettingStarted: React.FC = () => { - + diff --git a/app/javascript/mastodon/features/home_timeline/components/inline_follow_suggestions.tsx b/app/javascript/mastodon/features/home_timeline/components/inline_follow_suggestions.tsx index d7c463c5cc..e48fd19c3b 100644 --- a/app/javascript/mastodon/features/home_timeline/components/inline_follow_suggestions.tsx +++ b/app/javascript/mastodon/features/home_timeline/components/inline_follow_suggestions.tsx @@ -212,12 +212,12 @@ export const InlineFollowSuggestions: React.FC<{ hidden?: boolean }> = ({ tabIndex={-1} > <div className='inline-follow-suggestions__header'> - <h3 id={uniqueId}> + <h2 id={uniqueId} className='inline-follow-suggestions__title'> <FormattedMessage id='follow_suggestions.who_to_follow' defaultMessage='Who to follow' /> - </h3> + </h2> <div className='inline-follow-suggestions__header__actions'> <button className='link-button' onClick={handleDismiss} type='button'> diff --git a/app/javascript/mastodon/features/interaction_modal/index.tsx b/app/javascript/mastodon/features/interaction_modal/index.tsx index a4ba40c069..ef1d3e1111 100644 --- a/app/javascript/mastodon/features/interaction_modal/index.tsx +++ b/app/javascript/mastodon/features/interaction_modal/index.tsx @@ -419,9 +419,7 @@ const InteractionModal: React.FC<{ }> = ({ accountId, url, intent }) => { const dispatch = useAppDispatch(); const signupUrl = useAppSelector( - (state) => - (state.server.getIn(['server', 'registrations', 'url'], null) || - '/auth/sign_up') as string, + (state) => state.server.server.item?.registrations.url ?? '/auth/sign_up', ); const account = useAppSelector((state) => state.accounts.get(accountId)); const name = <DisplayName account={account} variant='simple' />; diff --git a/app/javascript/mastodon/features/navigation_panel/components/collapsible_panel.tsx b/app/javascript/mastodon/features/navigation_panel/components/collapsible_panel.tsx index 39a7899596..217e15b5ee 100644 --- a/app/javascript/mastodon/features/navigation_panel/components/collapsible_panel.tsx +++ b/app/javascript/mastodon/features/navigation_panel/components/collapsible_panel.tsx @@ -36,7 +36,7 @@ export const CollapsiblePanel: React.FC<{ }, [setExpanded]); return ( - <div className='navigation-panel__list-panel'> + <li className='navigation-panel__list-panel'> <div className='navigation-panel__list-panel__header'> <ColumnLink transparent @@ -64,7 +64,7 @@ export const CollapsiblePanel: React.FC<{ } title={expanded ? collapseTitle : expandTitle} onClick={handleClick} - aria-controls={`${accessibilityId}-content`} + ariaControls={`${accessibilityId}-content`} /> </> )} @@ -80,6 +80,6 @@ export const CollapsiblePanel: React.FC<{ {children} </div> )} - </div> + </li> ); }; diff --git a/app/javascript/mastodon/features/navigation_panel/components/sign_in_banner.tsx b/app/javascript/mastodon/features/navigation_panel/components/sign_in_banner.tsx index ebcb532bb4..f9cf4cb28f 100644 --- a/app/javascript/mastodon/features/navigation_panel/components/sign_in_banner.tsx +++ b/app/javascript/mastodon/features/navigation_panel/components/sign_in_banner.tsx @@ -20,10 +20,7 @@ export const SignInBanner: React.FC = () => { let signupButton: React.ReactNode; const signupUrl = useAppSelector( - (state) => - (state.server.getIn(['server', 'registrations', 'url'], null) as - | string - | null) ?? '/auth/sign_up', + (state) => state.server.server.item?.registrations.url ?? '/auth/sign_up', ); if (sso_redirect) { diff --git a/app/javascript/mastodon/features/navigation_panel/components/trends.tsx b/app/javascript/mastodon/features/navigation_panel/components/trends.tsx index f51bb2ed9f..8e8f1e47e1 100644 --- a/app/javascript/mastodon/features/navigation_panel/components/trends.tsx +++ b/app/javascript/mastodon/features/navigation_panel/components/trends.tsx @@ -37,21 +37,21 @@ export const Trends: React.FC = () => { } return ( - <div className='navigation-panel__portal'> + <aside className='navigation-panel__portal'> <div className='getting-started__trends'> - <h4> + <h2 className='getting-started__trends-heading'> <Link to={'/explore/tags'}> <FormattedMessage id='trends.trending_now' defaultMessage='Trending now' /> </Link> - </h4> + </h2> {trends.take(4).map((hashtag) => ( <Hashtag key={hashtag.get('name') as string} hashtag={hashtag} /> ))} </div> - </div> + </aside> ); }; diff --git a/app/javascript/mastodon/features/navigation_panel/index.tsx b/app/javascript/mastodon/features/navigation_panel/index.tsx index 33a2a43a70..3d038c22dd 100644 --- a/app/javascript/mastodon/features/navigation_panel/index.tsx +++ b/app/javascript/mastodon/features/navigation_panel/index.tsx @@ -249,124 +249,150 @@ export const NavigationPanel: React.FC<{ multiColumn?: boolean }> = ({ {banner && <div className='navigation-panel__banner'>{banner}</div>} - <div className='navigation-panel__menu'> + <ul className='navigation-panel__menu'> {signedIn && ( <> {!multiColumn && ( - <ColumnLink - to='/publish' - icon='plus' - iconComponent={AddIcon} - activeIconComponent={AddIcon} - text={intl.formatMessage(messages.compose)} - className='button navigation-panel__compose-button' - /> + <li> + <ColumnLink + to='/publish' + icon='plus' + iconComponent={AddIcon} + activeIconComponent={AddIcon} + text={intl.formatMessage(messages.compose)} + className='button navigation-panel__compose-button' + /> + </li> )} - <ColumnLink - transparent - to='/home' - icon='home' - iconComponent={HomeIcon} - activeIconComponent={HomeActiveIcon} - text={intl.formatMessage(messages.home)} - /> + <li> + <ColumnLink + transparent + to='/home' + icon='home' + iconComponent={HomeIcon} + activeIconComponent={HomeActiveIcon} + text={intl.formatMessage(messages.home)} + /> + </li> </> )} {trendsEnabled && ( - <ColumnLink - transparent - to='/explore' - icon='explore' - iconComponent={TrendingUpIcon} - text={intl.formatMessage(messages.explore)} - /> + <li> + <ColumnLink + transparent + to='/explore' + icon='explore' + iconComponent={TrendingUpIcon} + text={intl.formatMessage(messages.explore)} + /> + </li> )} {(canViewFeed(signedIn, permissions, localLiveFeedAccess) || canViewFeed(signedIn, permissions, remoteLiveFeedAccess)) && ( - <ColumnLink - transparent - to={ - canViewFeed(signedIn, permissions, localLiveFeedAccess) - ? '/public/local' - : '/public/remote' - } - icon='globe' - iconComponent={PublicIcon} - isActive={isFirehoseActive} - text={intl.formatMessage( - canViewFeed(signedIn, permissions, localLiveFeedAccess) && - canViewFeed(signedIn, permissions, remoteLiveFeedAccess) - ? messages.firehose - : messages.firehose_singular, - )} - /> + <li> + <ColumnLink + transparent + to={ + canViewFeed(signedIn, permissions, localLiveFeedAccess) + ? '/public/local' + : '/public/remote' + } + icon='globe' + iconComponent={PublicIcon} + isActive={isFirehoseActive} + text={intl.formatMessage( + canViewFeed(signedIn, permissions, localLiveFeedAccess) && + canViewFeed(signedIn, permissions, remoteLiveFeedAccess) + ? messages.firehose + : messages.firehose_singular, + )} + /> + </li> )} {signedIn && ( <> - <NotificationsLink /> + <li> + <NotificationsLink /> + </li> - <FollowRequestsLink /> + <li> + <FollowRequestsLink /> + </li> - <AnnualReportNavItem /> + <li> + <AnnualReportNavItem /> + </li> - <hr /> + <li role='separator' /> <ListPanel /> <FollowedTagsPanel /> - <ColumnLink - transparent - to='/favourites' - icon='star' - iconComponent={StarIcon} - activeIconComponent={StarActiveIcon} - text={intl.formatMessage(messages.favourites)} - /> - <ColumnLink - transparent - to='/bookmarks' - icon='bookmarks' - iconComponent={BookmarksIcon} - activeIconComponent={BookmarksActiveIcon} - text={intl.formatMessage(messages.bookmarks)} - /> - {areCollectionsEnabled() && ( + <li> <ColumnLink transparent - to={`/@${account?.acct}/collections`} - icon='collections' - iconComponent={CollectionsIcon} - activeIconComponent={CollectionsActiveIcon} - text={intl.formatMessage(messages.collections)} + to='/favourites' + icon='star' + iconComponent={StarIcon} + activeIconComponent={StarActiveIcon} + text={intl.formatMessage(messages.favourites)} /> + </li> + <li> + <ColumnLink + transparent + to='/bookmarks' + icon='bookmarks' + iconComponent={BookmarksIcon} + activeIconComponent={BookmarksActiveIcon} + text={intl.formatMessage(messages.bookmarks)} + /> + </li> + {areCollectionsEnabled() && ( + <li> + <ColumnLink + transparent + to={`/@${account?.acct}/collections`} + icon='collections' + iconComponent={CollectionsIcon} + activeIconComponent={CollectionsActiveIcon} + text={intl.formatMessage(messages.collections)} + /> + </li> )} - <ColumnLink - transparent - to='/conversations' - icon='at' - iconComponent={AlternateEmailIcon} - text={intl.formatMessage(messages.direct)} - /> + <li> + <ColumnLink + transparent + to='/conversations' + icon='at' + iconComponent={AlternateEmailIcon} + text={intl.formatMessage(messages.direct)} + /> + </li> - <hr /> + <li role='separator' /> - <ColumnLink - transparent - href='/settings/preferences' - icon='cog' - iconComponent={SettingsIcon} - text={intl.formatMessage(messages.preferences)} - /> + <li> + <ColumnLink + transparent + href='/settings/preferences' + icon='cog' + iconComponent={SettingsIcon} + text={intl.formatMessage(messages.preferences)} + /> + </li> - <MoreLink /> + <li> + <MoreLink /> + </li> </> )} - <div className='navigation-panel__legal'> + <li className='navigation-panel__legal'> <ColumnLink transparent to='/about' @@ -374,16 +400,16 @@ export const NavigationPanel: React.FC<{ multiColumn?: boolean }> = ({ iconComponent={InfoIcon} text={intl.formatMessage(messages.about)} /> - </div> + </li> {!signedIn && ( - <div className='navigation-panel__sign-in-banner'> + <li className='navigation-panel__sign-in-banner'> <hr /> {disabledAccountId ? <DisabledAccountBanner /> : <SignInBanner />} - </div> + </li> )} - </div> + </ul> <div className='flex-spacer' /> diff --git a/app/javascript/mastodon/features/notifications_v2/components/embedded_status_content.tsx b/app/javascript/mastodon/features/notifications_v2/components/embedded_status_content.tsx index 7312a94a30..f012ce4074 100644 --- a/app/javascript/mastodon/features/notifications_v2/components/embedded_status_content.tsx +++ b/app/javascript/mastodon/features/notifications_v2/components/embedded_status_content.tsx @@ -1,6 +1,6 @@ import { useCallback, useMemo } from 'react'; -import type { List } from 'immutable'; +import type { List, Map } from 'immutable'; import { EmojiHTML } from '@/mastodon/components/emoji/html'; import { useElementHandledLink } from '@/mastodon/components/status/handled_link'; @@ -23,8 +23,19 @@ export const EmbeddedStatusContent: React.FC<{ }, [mentions], ); + const hrefToCollection = useCallback( + (href: string) => { + const collections = status.get('tagged_collections') as List< + Map<'url' | 'id', string> + >; + const collection = collections.find((item) => item.get('url') === href); + return collection?.get('id'); + }, + [status], + ); const htmlHandlers = useElementHandledLink({ hashtagAccountId: status.get('account') as string | undefined, + hrefToCollectionId: hrefToCollection, hrefToMention, }); diff --git a/app/javascript/mastodon/features/notifications_v2/components/notification_admin_report.tsx b/app/javascript/mastodon/features/notifications_v2/components/notification_admin_report.tsx index 03f047fb7f..a3da581f88 100644 --- a/app/javascript/mastodon/features/notifications_v2/components/notification_admin_report.tsx +++ b/app/javascript/mastodon/features/notifications_v2/components/notification_admin_report.tsx @@ -106,10 +106,10 @@ export const NotificationAdminReport: React.FC<{ <div className='notification-group__main'> <div className='notification-group__main__header'> - <div className='notification-group__main__header__label'> + <h2 className='notification-group__main__header__label'> {message} <RelativeTimestamp timestamp={report.created_at} /> - </div> + </h2> </div> {report.comment.length > 0 && ( diff --git a/app/javascript/mastodon/features/notifications_v2/components/notification_collection.tsx b/app/javascript/mastodon/features/notifications_v2/components/notification_collection.tsx index 10466b5d3d..9c8d3832b7 100644 --- a/app/javascript/mastodon/features/notifications_v2/components/notification_collection.tsx +++ b/app/javascript/mastodon/features/notifications_v2/components/notification_collection.tsx @@ -46,7 +46,7 @@ export const NotificationCollection: React.FC<{ <div className='notification-group__main'> <div className='notification-group__main__header'> - <div className='notification-group__main__header__label'> + <h2 className='notification-group__main__header__label'> {type === 'added_to_collection' && ( <FormattedMessage id='notification.added_to_collection' @@ -79,7 +79,7 @@ export const NotificationCollection: React.FC<{ }} /> )} - </div> + </h2> </div> <CollectionPreviewCard collection={collection} /> diff --git a/app/javascript/mastodon/features/notifications_v2/components/notification_group_with_status.tsx b/app/javascript/mastodon/features/notifications_v2/components/notification_group_with_status.tsx index 8035493283..8377e8465b 100644 --- a/app/javascript/mastodon/features/notifications_v2/components/notification_group_with_status.tsx +++ b/app/javascript/mastodon/features/notifications_v2/components/notification_group_with_status.tsx @@ -125,7 +125,7 @@ export const NotificationGroupWithStatus: React.FC<{ )} </div> - <div className='notification-group__main__header__label'> + <h2 className='notification-group__main__header__label'> <span>{label}</span> {timestamp && ( <> @@ -135,7 +135,7 @@ export const NotificationGroupWithStatus: React.FC<{ <RelativeTimestamp timestamp={timestamp} /> </> )} - </div> + </h2> </div> {statusId && ( diff --git a/app/javascript/mastodon/features/notifications_v2/components/notification_with_status.tsx b/app/javascript/mastodon/features/notifications_v2/components/notification_with_status.tsx index 68c62232da..6a110c1425 100644 --- a/app/javascript/mastodon/features/notifications_v2/components/notification_with_status.tsx +++ b/app/javascript/mastodon/features/notifications_v2/components/notification_with_status.tsx @@ -101,12 +101,12 @@ export const NotificationWithStatus: React.FC<{ )} tabIndex={0} > - <div className='notification-ungrouped__header'> + <h2 className='notification-ungrouped__header'> <div className='notification-ungrouped__header__icon'> <Icon icon={icon} id={iconId} /> </div> <span>{label}</span> - </div> + </h2> <StatusQuoteManager id={statusId} diff --git a/app/javascript/mastodon/features/status/components/detailed_status.tsx b/app/javascript/mastodon/features/status/components/detailed_status.tsx index 0dec921343..ba0ce8b8c5 100644 --- a/app/javascript/mastodon/features/status/components/detailed_status.tsx +++ b/app/javascript/mastodon/features/status/components/detailed_status.tsx @@ -272,7 +272,12 @@ export const DetailedStatus: React.FC<{ ); if (taggedCollection) { - media = <CollectionPreviewCard collection={taggedCollection.toJS()} />; + media = ( + <CollectionPreviewCard + collection={taggedCollection.toJS()} + headingLevel='h2' + /> + ); } else { media = ( <Card @@ -286,7 +291,10 @@ export const DetailedStatus: React.FC<{ const firstLinkedCollection = status.get('tagged_collections').first(); if (firstLinkedCollection) { media = ( - <CollectionPreviewCard collection={firstLinkedCollection.toJS()} /> + <CollectionPreviewCard + collection={firstLinkedCollection.toJS()} + headingLevel='h2' + /> ); } } diff --git a/app/javascript/mastodon/features/ui/components/compose_panel.tsx b/app/javascript/mastodon/features/ui/components/compose_panel.tsx index cc55ff4cef..838d1510ec 100644 --- a/app/javascript/mastodon/features/ui/components/compose_panel.tsx +++ b/app/javascript/mastodon/features/ui/components/compose_panel.tsx @@ -51,7 +51,7 @@ export const ComposePanel: React.FC = () => { {signedIn && !hideComposer && <ComposeFormContainer singleColumn />} {signedIn && hideComposer && <div className='compose-form' />} - <LinkFooter multiColumn={!singleColumn} /> + <LinkFooter context={singleColumn ? 'default' : 'multi-column'} /> </div> ); }; diff --git a/app/javascript/mastodon/features/ui/components/link_footer.module.scss b/app/javascript/mastodon/features/ui/components/link_footer.module.scss new file mode 100644 index 0000000000..f2b094744e --- /dev/null +++ b/app/javascript/mastodon/features/ui/components/link_footer.module.scss @@ -0,0 +1,61 @@ +.wrapper { + z-index: 1; + flex: 0 0 auto; + display: flex; + flex-direction: column; + gap: 20px; + font-size: 13px; + color: var(--color-text-secondary); + + &[data-context='default'] { + padding: 20px 0; + } + + &[data-context='multi-column'] { + padding: 15px; + } + + &[data-context='about'] { + margin-top: 60px; + text-align: center; + font-size: 15px; + line-height: 22px; + + @media screen and (width >= 1175px) { + display: none; + } + } +} + +.heading { + display: inline; + margin-inline-end: 0.3em; + font-weight: 500; +} + +.list { + display: inline; + + li { + display: inline; + + &:not(:last-child)::after { + content: ' · '; + } + } + + a { + color: var(--color-text-secondary); + text-decoration: underline; + + &:hover, + &:focus, + &:active { + text-decoration: none; + } + } +} + +.version { + white-space: nowrap; +} diff --git a/app/javascript/mastodon/features/ui/components/link_footer.tsx b/app/javascript/mastodon/features/ui/components/link_footer.tsx index df153b2258..1f4ee7cde9 100644 --- a/app/javascript/mastodon/features/ui/components/link_footer.tsx +++ b/app/javascript/mastodon/features/ui/components/link_footer.tsx @@ -11,94 +11,110 @@ import { termsOfServiceEnabled, } from 'mastodon/initial_state'; -const DividingCircle: React.FC = () => <span aria-hidden>{' · '}</span>; +import classes from './link_footer.module.scss'; export const LinkFooter: React.FC<{ - multiColumn: boolean; -}> = ({ multiColumn }) => { + context?: 'default' | 'multi-column' | 'about'; +}> = ({ context = 'default' }) => { + const multiColumn = context === 'multi-column'; + return ( - <div className='link-footer'> - <p> - <strong>{domain}</strong>:{' '} - <Link to='/about' target={multiColumn ? '_blank' : undefined}> - <FormattedMessage - id='footer.about_this_server' - defaultMessage='About' - /> - </Link> - {statusPageUrl && ( - <> - <DividingCircle /> - <a href={statusPageUrl} target='_blank' rel='noopener'> - <FormattedMessage id='footer.status' defaultMessage='Status' /> - </a> - </> - )} - {canProfileDirectory && ( - <> - <DividingCircle /> - <Link to='/directory'> + <footer className={classes.wrapper} data-context={context}> + <section> + <h2 className={classes.heading}>{`${domain}:`}</h2> + <ul className={classes.list}> + <li> + <Link to='/about' target={multiColumn ? '_blank' : undefined}> <FormattedMessage - id='footer.directory' - defaultMessage='Profiles directory' + id='footer.about_this_server' + defaultMessage='About' /> </Link> - </> - )} - <DividingCircle /> - <Link - to='/privacy-policy' - target={multiColumn ? '_blank' : undefined} - rel='privacy-policy' - > - <FormattedMessage - id='footer.privacy_policy' - defaultMessage='Privacy policy' - /> - </Link> - {termsOfServiceEnabled && ( - <> - <DividingCircle /> + </li> + {statusPageUrl && ( + <li> + <a href={statusPageUrl} target='_blank' rel='noopener'> + <FormattedMessage id='footer.status' defaultMessage='Status' /> + </a> + </li> + )} + {canProfileDirectory && ( + <li> + <Link to='/directory'> + <FormattedMessage + id='footer.directory' + defaultMessage='Profiles directory' + /> + </Link> + </li> + )} + <li> <Link - to='/terms-of-service' + to='/privacy-policy' target={multiColumn ? '_blank' : undefined} - rel='terms-of-service' + rel='privacy-policy' > <FormattedMessage - id='footer.terms_of_service' - defaultMessage='Terms of service' + id='footer.privacy_policy' + defaultMessage='Privacy policy' /> </Link> - </> - )} - </p> - - <p> - <strong>Mastodon</strong>:{' '} - <a href='https://joinmastodon.org' target='_blank' rel='noopener'> - <FormattedMessage id='footer.about' defaultMessage='About' /> - </a> - <DividingCircle /> - <a href='https://joinmastodon.org/apps' target='_blank' rel='noopener'> - <FormattedMessage id='footer.get_app' defaultMessage='Get the app' /> - </a> - <DividingCircle /> - <Link to='/keyboard-shortcuts'> - <FormattedMessage - id='footer.keyboard_shortcuts' - defaultMessage='Keyboard shortcuts' - /> - </Link> - <DividingCircle /> - <a href={source_url} rel='noopener' target='_blank'> - <FormattedMessage - id='footer.source_code' - defaultMessage='View source code' - /> - </a> - <DividingCircle /> - <span className='version'>v{version}</span> - </p> - </div> + </li> + {termsOfServiceEnabled && ( + <li> + <Link + to='/terms-of-service' + target={multiColumn ? '_blank' : undefined} + rel='terms-of-service' + > + <FormattedMessage + id='footer.terms_of_service' + defaultMessage='Terms of service' + /> + </Link> + </li> + )} + </ul> + </section> + <section> + <h2 className={classes.heading}>Mastodon:</h2> + <ul className={classes.list}> + <li> + <a href='https://joinmastodon.org' target='_blank' rel='noopener'> + <FormattedMessage id='footer.about' defaultMessage='About' /> + </a> + </li> + <li> + <a + href='https://joinmastodon.org/apps' + target='_blank' + rel='noopener' + > + <FormattedMessage + id='footer.get_app' + defaultMessage='Get the app' + /> + </a> + </li> + <li> + <Link to='/keyboard-shortcuts'> + <FormattedMessage + id='footer.keyboard_shortcuts' + defaultMessage='Keyboard shortcuts' + /> + </Link> + </li> + <li> + <a href={source_url} rel='noopener' target='_blank'> + <FormattedMessage + id='footer.source_code' + defaultMessage='View source code' + /> + </a> + </li> + <li className={classes.version}>v{version}</li> + </ul> + </section> + </footer> ); }; diff --git a/app/javascript/mastodon/features/ui/components/navigation_bar.tsx b/app/javascript/mastodon/features/ui/components/navigation_bar.tsx index def1835c3e..ec45e395b2 100644 --- a/app/javascript/mastodon/features/ui/components/navigation_bar.tsx +++ b/app/javascript/mastodon/features/ui/components/navigation_bar.tsx @@ -84,10 +84,7 @@ const NotificationsButton = () => { const LoginOrSignUp: React.FC = () => { const dispatch = useAppDispatch(); const signupUrl = useAppSelector( - (state) => - (state.server.getIn(['server', 'registrations', 'url'], null) as - | string - | null) ?? '/auth/sign_up', + (state) => state.server.server.item?.registrations.url ?? '/auth/sign_up', ); const openClosedRegistrationsModal = useCallback(() => { @@ -95,7 +92,7 @@ const LoginOrSignUp: React.FC = () => { }, [dispatch]); useEffect(() => { - dispatch(fetchServer()); + void dispatch(fetchServer()); }, [dispatch]); if (sso_redirect) { diff --git a/app/javascript/mastodon/features/ui/components/report_collection_modal.tsx b/app/javascript/mastodon/features/ui/components/report_collection_modal.tsx index 945d6f0534..6e9492226d 100644 --- a/app/javascript/mastodon/features/ui/components/report_collection_modal.tsx +++ b/app/javascript/mastodon/features/ui/components/report_collection_modal.tsx @@ -52,7 +52,7 @@ export const ReportCollectionModal: React.FC<{ const account = useAccount(account_id); useEffect(() => { - dispatch(fetchServer()); + void dispatch(fetchServer()); }, [dispatch]); const [submitState, setSubmitState] = useState< diff --git a/app/javascript/mastodon/locales/ar.json b/app/javascript/mastodon/locales/ar.json index 260b7de741..b35f29e6b0 100644 --- a/app/javascript/mastodon/locales/ar.json +++ b/app/javascript/mastodon/locales/ar.json @@ -42,6 +42,9 @@ "account.familiar_followers_two": "يتبعه {name1} و {name2}", "account.featured": "معروض", "account.featured.accounts": "ملفات شخصية", + "account.featured.collections": "المجموعات", + "account.featured.new_collection": "مجموعة جديدة", + "account.field_overflow": "عرض المحتوى الكامل", "account.filters.all": "جميع الأنشطة", "account.filters.boosts_toggle": "اعرض المعاد نشرها", "account.filters.posts_boosts": "المنشورات والمعاد نشرها", @@ -66,6 +69,16 @@ "account.go_to_profile": "اذهب إلى الملف الشخصي", "account.hide_reblogs": "إخفاء المعاد نشرها مِن @{name}", "account.in_memoriam": "في الذكرى.", + "account.join_modal.day": "يوم", + "account.join_modal.me": "انضممت إلى {server} في", + "account.join_modal.me_anniversary": "ذكرى سنوية سعيدة! لقد انضممت إلى {server} في", + "account.join_modal.me_today": "إنه يومك الأول على {server}!", + "account.join_modal.other": "انضمّ {name} إلى {server} في", + "account.join_modal.other_today": "إنه اليوم الأول لـ{name} على {server}!", + "account.join_modal.share.celebrate": "مشاركة منشور احتفالي", + "account.join_modal.share.intro": "مشاركة منشور تعريفي", + "account.join_modal.share.welcome": "مشاركة منشور ترحيبي", + "account.join_modal.years": "{number, plural, zero {أقل من سنة} one {سنة واحدة} two {سنتَين} few {سنوات} many {سنة} other {سنة}}", "account.joined_short": "انضم في", "account.languages": "تغيير اللغات المشترَك فيها", "account.last_active": "آخر نشاط", diff --git a/app/javascript/mastodon/locales/be.json b/app/javascript/mastodon/locales/be.json index 10a644a1ea..71cb3a553f 100644 --- a/app/javascript/mastodon/locales/be.json +++ b/app/javascript/mastodon/locales/be.json @@ -86,6 +86,7 @@ "account.locked_info": "Гэты ўліковы запіс пазначаны як схаваны. Уладальнік сам вырашае, хто можа падпісвацца на яго.", "account.media": "Медыя", "account.mention": "Згадаць @{name}", + "account.menu.add_to_collection": "Дадаць у калекцыю…", "account.menu.add_to_list": "Дадаць у спіс…", "account.menu.block": "Заблакіраваць профіль", "account.menu.block_domain": "Заблакіраваць {domain}", @@ -366,12 +367,13 @@ "collection.share_modal.share_via_system": "Падзяліцца ў…", "collection.share_modal.title": "Падзяліцца калекцыяй", "collection.share_modal.title_new": "Падзяліцеся сваёй калекцыяй!", - "collection.share_template_other": "Глядзі, якая класная калекцыя: {link}", - "collection.share_template_own": "Глядзі, у мяне новая калекцыя: {link}", + "collection.share_template_other": "Глядзі, якая класная калекцыя:", + "collection.share_template_own": "Глядзі, у мяне новая калекцыя:", "collections.account_count": "{count, plural,one {# уліковы запіс} few {# уліковыя запісы} other {# уліковых запісаў}}", "collections.accounts.empty_description": "Дадайце да {count} уліковых запісаў", "collections.accounts.empty_editor_title": "У гэтай калекцыі пакуль нікога няма", "collections.accounts.empty_title": "Гэтая калекцыя пустая", + "collections.add_to_collection": "Дадаць {name} у калекцыі", "collections.block_collection_owner": "Заблакіраваць профіль", "collections.by_account": "ад {account_handle}", "collections.collection_description": "Апісанне", @@ -394,6 +396,7 @@ "collections.detail.loading": "Загружаецца калекцыя…", "collections.detail.revoke_inclusion": "Прыбраць сябе", "collections.detail.sensitive_content": "Адчувальнае змесціва", + "collections.detail.sensitive_note": "Апісанне і ўліковыя запісы могуць не пасаваць усім гледачам.", "collections.detail.share": "Падзяліцца гэтай калекцыяй", "collections.detail.you_are_in_this_collection": "Вас уключылі ў гэтую калекцыю", "collections.edit_details": "Рэдагаваць падрабязнасці", @@ -424,6 +427,11 @@ "collections.search_accounts_max_reached": "Вы дадалі максімальную колькасць уліковых запісаў", "collections.sensitive": "Адчувальная", "collections.share_short": "Абагуліць", + "collections.sort_alphabetical": "Алфавіце", + "collections.sort_by": "Сартаваць па:", + "collections.sort_date_added": "Даце дадавання", + "collections.sort_last_active": "Апошняй актыўнасці", + "collections.sort_most_followers": "Колькасці падпісчыкаў", "collections.suggestions.can_not_add": "Немагчыма дадаць", "collections.suggestions.can_not_add_desc": "Магчыма, гэтыя ўліковыя запісы схаваныя ад рэкамендацый або знаходзяцца на серверы, які не падтрымлівае калекцыі.", "collections.suggestions.must_follow": "Патрабуецца падпіска", @@ -635,6 +643,7 @@ "empty_column.blocks": "Вы яшчэ нікога не заблакіравалі.", "empty_column.bookmarked_statuses": "У Вашых закладках яшчэ няма допісаў. Калі Вы дадасце закладку, яна з’явіцца тут.", "empty_column.collections.featured_in": "Вас пакуль не дадалі ў ніякія калекцыі.", + "empty_column.collections.featured_in_undiscoverable": "Каб людзі маглі дадаваць Вас у калекцыі, Вам трэба даць ім дазвол знаходзіць Вас у <link>Налады > Прыватнасць і пошук</link>", "empty_column.community": "Мясцовая стужка пустая. Напішыце нешта публічнае, каб разварушыць справу!", "empty_column.direct": "Пакуль у Вас няма асабістых згадванняў. Калі Вы дашляце або атрымаеце штосьці, яно з’явіцца тут.", "empty_column.disabled_feed": "Гэта стужка была адключаная Вашымі адміністратарамі сервера.", diff --git a/app/javascript/mastodon/locales/cy.json b/app/javascript/mastodon/locales/cy.json index 503b5051cd..2a9a6e723c 100644 --- a/app/javascript/mastodon/locales/cy.json +++ b/app/javascript/mastodon/locales/cy.json @@ -366,8 +366,6 @@ "collection.share_modal.share_via_system": "Rhannwch i…", "collection.share_modal.title": "Rhannu casgliad", "collection.share_modal.title_new": "Rhannwch eich casgliad newydd!", - "collection.share_template_other": "Edrychwch ar y casgliad trawiadol hwn: {link}", - "collection.share_template_own": "Edrychwch ar fy nghasgliad newydd: {link}", "collections.account_count": "{count, plural, one {# cyfrif} other {# cyfrif}}", "collections.accounts.empty_description": "Ychwanegu hyd at {count} cyfrif", "collections.accounts.empty_editor_title": "Does neb yn y casgliad hwn eto", diff --git a/app/javascript/mastodon/locales/da.json b/app/javascript/mastodon/locales/da.json index f8b95beee1..93b6dddbf9 100644 --- a/app/javascript/mastodon/locales/da.json +++ b/app/javascript/mastodon/locales/da.json @@ -86,6 +86,7 @@ "account.locked_info": "Denne kontos fortrolighedsstatus er sat til låst. Ejeren bedømmer manuelt, hvem der kan følge vedkommende.", "account.media": "Medier", "account.mention": "Nævn @{name}", + "account.menu.add_to_collection": "Føj til samling…", "account.menu.add_to_list": "Føj til liste…", "account.menu.block": "Blokér konto", "account.menu.block_domain": "Blokér {domain}", @@ -366,12 +367,13 @@ "collection.share_modal.share_via_system": "Del med…", "collection.share_modal.title": "Del samling", "collection.share_modal.title_new": "Del din nye samling!", - "collection.share_template_other": "Tjek denne seje samling: {link}", - "collection.share_template_own": "Tjek min nye samling: {link}", + "collection.share_template_other": "Tjek denne seje samling:", + "collection.share_template_own": "Tjek min nye samling:", "collections.account_count": "{count, plural, one {# konto} other {# konti}}", "collections.accounts.empty_description": "Tilføj op til {count} konti", "collections.accounts.empty_editor_title": "Ingen er i denne samling endnu", "collections.accounts.empty_title": "Denne samling er tom", + "collections.add_to_collection": "Tilføj {name} til samlinger", "collections.block_collection_owner": "Blokér konto", "collections.by_account": "af {account_handle}", "collections.collection_description": "Beskrivelse", diff --git a/app/javascript/mastodon/locales/de.json b/app/javascript/mastodon/locales/de.json index 89247972e5..14c4f48171 100644 --- a/app/javascript/mastodon/locales/de.json +++ b/app/javascript/mastodon/locales/de.json @@ -86,6 +86,7 @@ "account.locked_info": "Die Privatsphäre dieses Kontos wurde auf „geschützt“ gesetzt. Die Person bestimmt manuell, wer ihrem Profil folgen darf.", "account.media": "Medien", "account.mention": "@{name} erwähnen", + "account.menu.add_to_collection": "Einer Sammlung hinzufügen …", "account.menu.add_to_list": "Einer Liste hinzufügen …", "account.menu.block": "Konto blockieren", "account.menu.block_domain": "{domain} blockieren", @@ -366,12 +367,13 @@ "collection.share_modal.share_via_system": "Teilen …", "collection.share_modal.title": "Sammlung teilen", "collection.share_modal.title_new": "Teile deine neue Sammlung!", - "collection.share_template_other": "Seht euch diese coole Sammlung an: {link}", - "collection.share_template_own": "Seht euch meine neue Sammlung an: {link}", + "collection.share_template_other": "Seht euch diese coole Sammlung an:", + "collection.share_template_own": "Seht euch meine neue Sammlung an:", "collections.account_count": "{count, plural, one {# Konto} other {# Konten}}", "collections.accounts.empty_description": "Füge bis zu {count} Konten hinzu", "collections.accounts.empty_editor_title": "Noch befindet sich niemand in dieser Sammlung", "collections.accounts.empty_title": "Diese Sammlung ist leer", + "collections.add_to_collection": "{name} einer Sammlung hinzufügen", "collections.block_collection_owner": "Konto blockieren", "collections.by_account": "von {account_handle}", "collections.collection_description": "Beschreibung", @@ -426,7 +428,7 @@ "collections.sensitive": "Inhaltswarnung", "collections.share_short": "Teilen", "collections.sort_alphabetical": "Alphabetisch", - "collections.sort_by": "Sortierung:", + "collections.sort_by": "Sortieren nach:", "collections.sort_date_added": "Datum des Hinzufügens", "collections.sort_last_active": "Neueste Aktivität", "collections.sort_most_followers": "Followerzahl", diff --git a/app/javascript/mastodon/locales/el.json b/app/javascript/mastodon/locales/el.json index 0a451968a8..c1d0390320 100644 --- a/app/javascript/mastodon/locales/el.json +++ b/app/javascript/mastodon/locales/el.json @@ -86,7 +86,8 @@ "account.locked_info": "Η κατάσταση απορρήτου αυτού του λογαριασμού έχει ρυθμιστεί σε κλειδωμένη. Ο ιδιοκτήτης ελέγχει χειροκίνητα ποιος μπορεί να τον ακολουθήσει.", "account.media": "Πολυμέσα", "account.mention": "Επισήμανση @{name}", - "account.menu.add_to_list": "Προσθήκη στη λίστα…", + "account.menu.add_to_collection": "Προσθήκη σε συλλογή…", + "account.menu.add_to_list": "Προσθήκη σε λίστα…", "account.menu.block": "Αποκλεισμός λογαριασμού", "account.menu.block_domain": "Αποκλεισμός {domain}", "account.menu.copied": "Αντιγραφή συνδέσμου λογαριασμού στο πρόχειρο", @@ -366,12 +367,13 @@ "collection.share_modal.share_via_system": "Κοινοποίηση σε…", "collection.share_modal.title": "Κοινοποίηση συλλογής", "collection.share_modal.title_new": "Μοιραστείτε τη νέα σας συλλογή!", - "collection.share_template_other": "Δείτε αυτή την ωραία συλλογή: {link}", - "collection.share_template_own": "Δείτε τη νέα μου συλλογή: {link}", + "collection.share_template_other": "Δείτε αυτή την ωραία συλλογή:", + "collection.share_template_own": "Δείτε τη νέα μου συλλογή:", "collections.account_count": "{count, plural, one {# λογαριασμός} other {# λογαριασμοί}}", "collections.accounts.empty_description": "Προσθέστε μέχρι και {count} λογαριασμούς", "collections.accounts.empty_editor_title": "Κανείς δεν είναι ακόμη σε αυτήν τη συλλογή", "collections.accounts.empty_title": "Αυτή η συλλογή είναι κενή", + "collections.add_to_collection": "Προσθήκη {name} σε συλλογές", "collections.block_collection_owner": "Αποκλεισμός λογαριασμού", "collections.by_account": "από {account_handle}", "collections.collection_description": "Περιγραφή", @@ -990,7 +992,7 @@ "notifications.clear_title": "Εκκαθάριση ειδοποιήσεων;", "notifications.column_settings.admin.report": "Νέες αναφορές:", "notifications.column_settings.admin.sign_up": "Νέες εγγραφές:", - "notifications.column_settings.alert": "Ειδοποιήσεις επιφάνειας εργασίας", + "notifications.column_settings.alert": "Ειδοποιήσεις για υπολογιστή", "notifications.column_settings.favourite": "Αγαπημένα:", "notifications.column_settings.filter_bar.advanced": "Εμφάνιση όλων των κατηγοριών", "notifications.column_settings.filter_bar.category": "Μπάρα γρήγορου φίλτρου", @@ -1018,9 +1020,9 @@ "notifications.grant_permission": "Χορήγηση άδειας.", "notifications.group": "{count} ειδοποιήσεις", "notifications.mark_as_read": "Σήμανε όλες τις ειδοποιήσεις ως αναγνωσμένες", - "notifications.permission_denied": "Οι ειδοποιήσεις στην επιφάνεια εργασίας δεν είναι διαθέσιμες διότι έχει απορριφθεί κάποιο προηγούμενο αίτημα άδειας", - "notifications.permission_denied_alert": "Δεν είναι δυνατή η ενεργοποίηση των ειδοποιήσεων της επιφάνειας εργασίας, καθώς η άδεια του προγράμματος περιήγησης έχει απορριφθεί νωρίτερα", - "notifications.permission_required": "Οι ειδοποιήσεις δεν είναι διαθέσιμες επειδή δεν έχει δοθεί η απαιτούμενη άδεια.", + "notifications.permission_denied": "Οι ειδοποιήσεις για υπολογιστή δεν είναι διαθέσιμες διότι έχει απορριφθεί κάποιο προηγούμενο αίτημα άδειας", + "notifications.permission_denied_alert": "Δεν είναι δυνατή η ενεργοποίηση των ειδοποιήσεων για υπολογιστή, καθώς η άδεια του προγράμματος περιήγησης έχει απορριφθεί προηγουμένων", + "notifications.permission_required": "Οι ειδοποιήσεις για υπολογιστή δεν είναι διαθέσιμες επειδή δεν έχει δοθεί η απαιτούμενη άδεια.", "notifications.policy.accept": "Αποδοχή", "notifications.policy.accept_hint": "Εμφάνιση στις ειδοποιήσεις", "notifications.policy.drop": "Αγνόηση", @@ -1038,8 +1040,8 @@ "notifications.policy.filter_private_mentions_hint": "Φιλτράρισμα εκτός αν είναι απάντηση σε δική σου επισήμανση ή αν ακολουθείς τον αποστολέα", "notifications.policy.filter_private_mentions_title": "Μη συναινετικές ιδιωτικές επισημάνσεις", "notifications.policy.title": "Διαχείριση ειδοποιήσεων από…", - "notifications_permission_banner.enable": "Ενεργοποίηση ειδοποιήσεων επιφάνειας εργασίας", - "notifications_permission_banner.how_to_control": "Για να λαμβάνεις ειδοποιήσεις όταν το Mastodon δεν είναι ανοιχτό, ενεργοποίησε τις ειδοποιήσεις επιφάνειας εργασίας. Μπορείς να ελέγξεις με ακρίβεια ποιοι τύποι αλληλεπιδράσεων δημιουργούν ειδοποιήσεις επιφάνειας εργασίας μέσω του κουμπιού {icon} μόλις ενεργοποιηθούν.", + "notifications_permission_banner.enable": "Ενεργοποίηση ειδοποιήσεων για υπολογιστή", + "notifications_permission_banner.how_to_control": "Για να λαμβάνεις ειδοποιήσεις όταν το Mastodon δεν είναι ανοιχτό, ενεργοποίησε τις ειδοποιήσεις για υπολογιστή. Μπορείς να ελέγξεις με ακρίβεια ποιοι τύποι αλληλεπιδράσεων δημιουργούν ειδοποιήσεις για υπολογιστή μέσω του κουμπιού {icon} μόλις ενεργοποιηθούν.", "notifications_permission_banner.title": "Μη χάσεις στιγμή", "onboarding.follows.back": "Πίσω", "onboarding.follows.empty": "Δυστυχώς, δεν μπορούν να εμφανιστούν αποτελέσματα αυτή τη στιγμή. Μπορείς να προσπαθήσεις να χρησιμοποιήσεις την αναζήτηση ή να περιηγηθείς στη σελίδα εξερεύνησης για να βρεις άτομα να ακολουθήσεις ή να δοκιμάσεις ξανά αργότερα.", @@ -1296,7 +1298,7 @@ "status.uncached_media_warning": "Μη διαθέσιμη προεπισκόπηση", "status.unmute_conversation": "Άρση σίγασης συνομιλίας", "status.unpin": "Ξεκαρφίτσωσε από το προφίλ", - "subscribed_languages.lead": "Μόνο αναρτήσεις σε επιλεγμένες γλώσσες θα εμφανίζονται στην αρχική σου και θα παραθέτονται ροές μετά την αλλαγή. Επέλεξε καμία για να λαμβάνεις αναρτήσεις σε όλες τις γλώσσες.", + "subscribed_languages.lead": "Μόνο αναρτήσεις στις επιλεγμένες γλώσσες θα εμφανίζονται στην αρχική σου και στις ροές λίστας μετά την αλλαγή. Επέλεξε καμία για να λαμβάνεις αναρτήσεις σε όλες τις γλώσσες.", "subscribed_languages.save": "Αποθήκευση αλλαγών", "subscribed_languages.target": "Αλλαγή εγγεγραμμένων γλωσσών για {target}", "tabs_bar.home": "Αρχική", diff --git a/app/javascript/mastodon/locales/en-GB.json b/app/javascript/mastodon/locales/en-GB.json index 0e40b4c0a9..04146f847f 100644 --- a/app/javascript/mastodon/locales/en-GB.json +++ b/app/javascript/mastodon/locales/en-GB.json @@ -366,8 +366,6 @@ "collection.share_modal.share_via_system": "Share to…", "collection.share_modal.title": "Share collection", "collection.share_modal.title_new": "Share your new collection!", - "collection.share_template_other": "Check out this cool collection: {link}", - "collection.share_template_own": "Check out my new collection: {link}", "collections.account_count": "{count, plural, one {# account} other {# accounts}}", "collections.accounts.empty_description": "Add up to {count} accounts", "collections.accounts.empty_editor_title": "No one is in this collection yet", diff --git a/app/javascript/mastodon/locales/en.json b/app/javascript/mastodon/locales/en.json index c372422988..057b235576 100644 --- a/app/javascript/mastodon/locales/en.json +++ b/app/javascript/mastodon/locales/en.json @@ -367,8 +367,8 @@ "collection.share_modal.share_via_system": "Share to…", "collection.share_modal.title": "Share collection", "collection.share_modal.title_new": "Share your new collection!", - "collection.share_template_other": "Check out this cool collection: {link}", - "collection.share_template_own": "Check out my new collection: {link}", + "collection.share_template_other": "Check out this cool collection:", + "collection.share_template_own": "Check out my new collection:", "collections.account_count": "{count, plural, one {# account} other {# accounts}}", "collections.accounts.empty_description": "Add up to {count} accounts", "collections.accounts.empty_editor_title": "No one is in this collection yet", diff --git a/app/javascript/mastodon/locales/es-AR.json b/app/javascript/mastodon/locales/es-AR.json index 24c292e1d6..fddee1f6d4 100644 --- a/app/javascript/mastodon/locales/es-AR.json +++ b/app/javascript/mastodon/locales/es-AR.json @@ -86,6 +86,7 @@ "account.locked_info": "Esta cuenta es privada. El propietario manualmente revisa quién puede seguirle.", "account.media": "Medios", "account.mention": "Mencionar a @{name}", + "account.menu.add_to_collection": "Agregar a la colección…", "account.menu.add_to_list": "Añadir a lista…", "account.menu.block": "Bloquear cuenta", "account.menu.block_domain": "Bloquear a {domain}", @@ -366,12 +367,13 @@ "collection.share_modal.share_via_system": "Compartir en…", "collection.share_modal.title": "Compartir colección", "collection.share_modal.title_new": "¡Compartí tu nueva colección!", - "collection.share_template_other": "¡Mirá qué copada está esta colección! {link}", - "collection.share_template_own": "Mirá mi nueva colección: {link}", + "collection.share_template_other": "Fijate qué copada es esta colección:", + "collection.share_template_own": "Revisá mi nueva colección:", "collections.account_count": "{count, plural, one {# hora} other {# horas}}", "collections.accounts.empty_description": "Agregá hasta {count} cuentas", "collections.accounts.empty_editor_title": "Todavía no hay nadie en esta colección", "collections.accounts.empty_title": "Esta colección está vacía", + "collections.add_to_collection": "Agregar {name} a las colecciones", "collections.block_collection_owner": "Bloquear cuenta", "collections.by_account": "por {account_handle}", "collections.collection_description": "Descripción", diff --git a/app/javascript/mastodon/locales/es-MX.json b/app/javascript/mastodon/locales/es-MX.json index 91e298b6ba..6714d97b23 100644 --- a/app/javascript/mastodon/locales/es-MX.json +++ b/app/javascript/mastodon/locales/es-MX.json @@ -86,6 +86,7 @@ "account.locked_info": "El estado de privacidad de esta cuenta está configurado como bloqueado. El propietario revisa manualmente quién puede seguirlo.", "account.media": "Multimedia", "account.mention": "Mencionar a @{name}", + "account.menu.add_to_collection": "Añadir a colección…", "account.menu.add_to_list": "Añadir a lista…", "account.menu.block": "Bloquear cuenta", "account.menu.block_domain": "Bloquear {domain}", @@ -366,12 +367,13 @@ "collection.share_modal.share_via_system": "Compartir con…", "collection.share_modal.title": "Compartir la colección", "collection.share_modal.title_new": "¡Comparte tu nueva colección!", - "collection.share_template_other": "Echa un vistazo a esta increíble colección: {link}", - "collection.share_template_own": "Echa un vistazo a mi nueva colección: {link}", + "collection.share_template_other": "Mira esta colección tan chula:", + "collection.share_template_own": "Mira mi nueva colección:", "collections.account_count": "{count, plural,one {# cuenta} other {# cuentas}}", "collections.accounts.empty_description": "Añade hasta {count} cuentas", "collections.accounts.empty_editor_title": "No hay nadie en esta colección todavía", "collections.accounts.empty_title": "Esta colección está vacía", + "collections.add_to_collection": "Añadir a {name} a colecciones", "collections.block_collection_owner": "Bloquer cuenta", "collections.by_account": "de {account_handle}", "collections.collection_description": "Descripción", @@ -394,7 +396,7 @@ "collections.detail.loading": "Cargando colección…", "collections.detail.revoke_inclusion": "Excluirme", "collections.detail.sensitive_content": "Contenido sensible", - "collections.detail.sensitive_note": "La descripción y cuentas pueden no ser adecuadas para todas las personas.", + "collections.detail.sensitive_note": "Es posible que la descripción y las cuentas no sean aptas para todos las personas.", "collections.detail.share": "Compartir esta colección", "collections.detail.you_are_in_this_collection": "Apareces en esta colección", "collections.edit_details": "Editar detalles", @@ -641,7 +643,7 @@ "empty_column.blocks": "Aún no has bloqueado a ningún usuario.", "empty_column.bookmarked_statuses": "Aún no tienes ninguna publicación guardada como marcador. Cuando guardes una, se mostrará aquí.", "empty_column.collections.featured_in": "Aún no te han añadido a ninguna colección.", - "empty_column.collections.featured_in_undiscoverable": "Para que la gente pueda añadirte a colecciones, debes permitir ser destacado en algoritmos de descubrimiento desde <link>Preferencias > Privacidad y alcance</link>", + "empty_column.collections.featured_in_undiscoverable": "Para que los usuarios puedan añadirte a sus colecciones, debes habilitar la opción de aparecer en las experiencias de descubrimiento desde <link>Preferencias > Privacidad y alcance</link>", "empty_column.community": "La cronología local está vacía. ¡Escribe algo públicamente para ponerla en marcha!", "empty_column.direct": "Aún no tienes ninguna mención privada. Cuando envíes o recibas una, aparecerá aquí.", "empty_column.disabled_feed": "Esta cronología fue desactivada por los administradores de tu servidor.", diff --git a/app/javascript/mastodon/locales/es.json b/app/javascript/mastodon/locales/es.json index 778590c012..283da08a4f 100644 --- a/app/javascript/mastodon/locales/es.json +++ b/app/javascript/mastodon/locales/es.json @@ -86,6 +86,7 @@ "account.locked_info": "El estado de privacidad de esta cuenta está configurado como bloqueado. El proprietario debe revisar manualmente quien puede seguirle.", "account.media": "Multimedia", "account.mention": "Mencionar a @{name}", + "account.menu.add_to_collection": "Añadir a colección…", "account.menu.add_to_list": "Añadir a lista…", "account.menu.block": "Bloquear cuenta", "account.menu.block_domain": "Bloquear {domain}", @@ -366,12 +367,13 @@ "collection.share_modal.share_via_system": "Compartir con…", "collection.share_modal.title": "Compartir la colección", "collection.share_modal.title_new": "¡Comparte tu nueva colección!", - "collection.share_template_other": "Echa un vistazo a esta fantástica colección: {link}", - "collection.share_template_own": "Echa un vistazo a mi nueva colección: {link}", + "collection.share_template_other": "Mira esta colección tan chula:", + "collection.share_template_own": "Mira mi nueva colección:", "collections.account_count": "{count, plural, one {# cuenta} other {# cuentas}}", "collections.accounts.empty_description": "Añade hasta {count} cuentas", "collections.accounts.empty_editor_title": "No hay nadie en esta colección todavía", "collections.accounts.empty_title": "Esta colección está vacía", + "collections.add_to_collection": "Añadir {name} a colecciones", "collections.block_collection_owner": "Bloquear cuenta", "collections.by_account": "de {account_handle}", "collections.collection_description": "Descripción", @@ -425,9 +427,9 @@ "collections.search_accounts_max_reached": "Has añadido el número máximo de cuentas", "collections.sensitive": "Sensible", "collections.share_short": "Compartir", - "collections.sort_alphabetical": "Alfabético", - "collections.sort_by": "Orden:", - "collections.sort_date_added": "Añadido a fecha", + "collections.sort_alphabetical": "Alfabéticamente", + "collections.sort_by": "Ordenar por:", + "collections.sort_date_added": "Fecha de inclusión", "collections.sort_last_active": "Última actividad", "collections.sort_most_followers": "Más seguidores", "collections.suggestions.can_not_add": "No puede ser añadida", diff --git a/app/javascript/mastodon/locales/et.json b/app/javascript/mastodon/locales/et.json index b665358523..959cdcba59 100644 --- a/app/javascript/mastodon/locales/et.json +++ b/app/javascript/mastodon/locales/et.json @@ -86,6 +86,7 @@ "account.locked_info": "Selle konto privaatsusolek on „lukustatud“. Omanik vaatab üle, kes teda jälgida saab.", "account.media": "Meedium", "account.mention": "Maini kasutajat @{name}", + "account.menu.add_to_collection": "Lisa kogumikku…", "account.menu.add_to_list": "Lisa loendisse…", "account.menu.block": "Blokeeri kasutajakonto", "account.menu.block_domain": "Blokeeri {domain}", @@ -147,7 +148,7 @@ "account.unmute": "Lõpeta {name} kasutaja summutamine", "account.unmute_notifications_short": "Lõpeta teavituste summutamine", "account.unmute_short": "Lõpeta summutamine", - "account_edit.advanced_settings.bot_hint": "Teavita teisi, et sel kontol tehakse peamiselt automatiseeritud toiminguid ja seda ei pruugita jälgida", + "account_edit.advanced_settings.bot_hint": "Teavita teisi, et sel kasutajakontol tehakse peamiselt automatiseeritud toiminguid ja seda ei pruugita jälgida", "account_edit.advanced_settings.bot_label": "Automatiseeritud kasutajakonto", "account_edit.advanced_settings.title": "Täpsemad seadistused", "account_edit.bio.add_label": "Lisa elulugu", @@ -227,7 +228,7 @@ "account_edit.profile_tab.show_relations.description": "Näitab sinu profiilis teistele kasutajatele kontosid, mida jälgid ning su jälgijaid. Inimesed saavad endiselt näha, kas sa neid jälgid.", "account_edit.profile_tab.show_relations.title": "Näita „Jälgijad“ ja „Jälgib“", "account_edit.profile_tab.subtitle": "Kohanda, kuidas su profiili näidatakse.", - "account_edit.profile_tab.title": "Profiili näitamise seaded", + "account_edit.profile_tab.title": "Profiili näitamise seadistused", "account_edit.save": "Salvesta", "account_edit.upload_modal.back": "Tagasi", "account_edit.upload_modal.done": "Valmis", @@ -365,13 +366,14 @@ "collection.share_modal.share_via_post": "Postita Mastodonis", "collection.share_modal.share_via_system": "Jaga kohas…", "collection.share_modal.title": "Jaga kogumikku", - "collection.share_modal.title_new": "Jaga oma ut kogumikku!", - "collection.share_template_other": "Vaata seda lahedat kogumikku: {link}", - "collection.share_template_own": "Vaata mu uut kogumikku: {link}", + "collection.share_modal.title_new": "Jaga oma uut kogumikku!", + "collection.share_template_other": "Vaata seda lahedat kogumikku:", + "collection.share_template_own": "Vaata minu uut kogumikku:", "collections.account_count": "{count, plural, one {# kasutajakonto} other {# kasutajakontot}}", - "collections.accounts.empty_description": "Lisa kuni {count} kontot", + "collections.accounts.empty_description": "Lisa kuni {count} kasutajakontot", "collections.accounts.empty_editor_title": "Selles kogumikus pole veel kedagi", "collections.accounts.empty_title": "See kogumik on tühi", + "collections.add_to_collection": "Lisa „{name}“ kogumikku", "collections.block_collection_owner": "Konto blokeerimine", "collections.by_account": "{account_handle} poolt", "collections.collection_description": "Kirjeldus", @@ -383,7 +385,7 @@ "collections.content_warning": "Sisuhoiatus", "collections.continue": "Jätka", "collections.copy_link": "Kopeeri link", - "collections.copy_link_confirmation": "Kogumiku link kopeeriti lõikelauale", + "collections.copy_link_confirmation": "Kogumiku link on kopeeritud lõikelauale", "collections.create.accounts_title": "Kes saavad olema selles kogumikus?", "collections.create.basic_details_title": "Põhiandmed", "collections.create.steps": "Samm {step}/{total}", @@ -422,7 +424,7 @@ "collections.revoke_inclusion.confirmation": "Oled eemaldatud \"{collection}\"-st", "collections.revoke_inclusion.error": "Oli viga, palun proovi hiljem uuesti.", "collections.search_accounts_label": "Otsi kontot, mida lisada", - "collections.search_accounts_max_reached": "Oled lisanud maksimumarv kontosid", + "collections.search_accounts_max_reached": "Oled lisanud maksimumarvu kontosid", "collections.sensitive": "Tundlik", "collections.share_short": "Jaga", "collections.sort_alphabetical": "Tähestikuline", @@ -462,17 +464,17 @@ "column.list_members": "Halda loendi liikmeid", "column.lists": "Loetelud", "column.mutes": "Summutatud kasutajad", - "column.notifications": "Teated", + "column.notifications": "Teavitused", "column.other_collections": "Kasutaja {name} kogumikud", "column.pins": "Esiletõstetud postitused", - "column.public": "Föderatiivne ajajoon", + "column.public": "Födereeritud ajajoon", "column.your_collections": "Sinu kogumikud", "column_back_button.label": "Tagasi", - "column_header.hide_settings": "Peida sätted", + "column_header.hide_settings": "Peida seadistused", "column_header.moveLeft_settings": "Liiguta tulp vasakule", "column_header.moveRight_settings": "Liiguta tulp paremale", "column_header.pin": "Kinnita", - "column_header.show_settings": "Näita sätteid", + "column_header.show_settings": "Näita seadistusi", "column_header.unpin": "Eemalda kinnitus", "column_search.cancel": "Tühista", "combobox.close_results": "Sulge tulemused", @@ -532,7 +534,7 @@ "confirmations.follow_to_list.message": "Pead jälgima kasutajat {name}, et lisada teda loetellu.", "confirmations.follow_to_list.title": "Jälgida kasutajat?", "confirmations.hide_featured_tab.confirm": "Peida vahekaart", - "confirmations.hide_featured_tab.intro": "Saad seda igal ajal muuta menüüs <i>Profiili muutmine > Profiili vahekaardi seaded</i>.", + "confirmations.hide_featured_tab.intro": "Saad seda igal ajal muuta menüüs <i>Profiili muutmine > Profiili vahekaardi seadistused</i>.", "confirmations.hide_featured_tab.message": "See peidab vahekaardi serveri {serverName} kasutajatel ja teistel serveritel, kus kasutatakse Mastodoni uusimat versiooni. Muudel serveritel võib kuvamine erineda.", "confirmations.hide_featured_tab.title": "Kas peidame vahekaardi „Esiletõstetud“?", "confirmations.logout.confirm": "Välju", @@ -586,7 +588,7 @@ "directory.local": "Ainult domeenilt {domain}", "directory.new_arrivals": "Uustulijad", "directory.recently_active": "Hiljuti aktiivne", - "disabled_account_banner.account_settings": "Kontosätted", + "disabled_account_banner.account_settings": "Kasutajakonto seadistused", "disabled_account_banner.text": "Su konto {disabledAccount} on hetkel keelatud.", "dismissable_banner.community_timeline": "Need on kõige viimased avalikud postitused inimestelt, kelle kontosid majutab {domain}.", "dismissable_banner.dismiss": "Sulge", @@ -641,6 +643,7 @@ "empty_column.blocks": "Blokeeritud kasutajaid pole.", "empty_column.bookmarked_statuses": "Järjehoidjatesse pole veel lisatud postitusi. Kui lisad mõne, näed neid siin.", "empty_column.collections.featured_in": "Sind pole lisatud veel ühtegi kogumikku.", + "empty_column.collections.featured_in_undiscoverable": "Selleks, et kasutajad saaks sind lisada kogumikesse, pead sa seadistustest lubama tuvastamise ja esiletõstmise siit: <link>Eelistused > Privaatsus ja ulatus</link>", "empty_column.community": "Kohalik ajajoon on tühi. Kirjuta midagi avalikult, et pall veerema ajada!", "empty_column.direct": "Sul pole veel ühtegi privaatset mainimist. Kui saadad või saad mõne, ilmuvad need siin.", "empty_column.disabled_feed": "See infovoog on serveri peakasutajate poolt välja lülitatud.", @@ -683,7 +686,7 @@ "filter_modal.added.expired_explanation": "Selle filtri kategooria on aegunud. pead muutma aegumiskuupäeva, kui tahad, et filter kehtiks.", "filter_modal.added.expired_title": "Aegunud filter!", "filter_modal.added.review_and_configure": "Et vaadata üle ja täpsemalt seadistada seda filtrikategooriat, mine lehele {settings_link}.", - "filter_modal.added.review_and_configure_title": "Filtrite sätted", + "filter_modal.added.review_and_configure_title": "Filtrite seadistused", "filter_modal.added.settings_link": "sätete leht", "filter_modal.added.short_explanation": "See postitus on lisatud järgmisesse filtrikategooriasse: {title}.", "filter_modal.added.title": "Filter lisatud!", @@ -743,7 +746,7 @@ "hashtag.column_header.tag_mode.all": "ja {additional}", "hashtag.column_header.tag_mode.any": "või teemaviide {additional}", "hashtag.column_header.tag_mode.none": "ilma teemaviiteta {additional}", - "hashtag.column_settings.select.no_options_message": "Soovitusi ei leitud", + "hashtag.column_settings.select.no_options_message": "Soovitusi ei leidu", "hashtag.column_settings.select.placeholder": "Sisesta teemaviited…", "hashtag.column_settings.tag_mode.all": "Kõik need", "hashtag.column_settings.tag_mode.any": "Mõni neist", @@ -989,23 +992,23 @@ "notifications.clear_title": "Tühjenda teavitus?", "notifications.column_settings.admin.report": "Uued teavitused:", "notifications.column_settings.admin.sign_up": "Uued kasutajad:", - "notifications.column_settings.alert": "Töölauateated", + "notifications.column_settings.alert": "Teavitused töölaual", "notifications.column_settings.favourite": "Lemmikud:", "notifications.column_settings.filter_bar.advanced": "Näita kõiki kategooriaid", "notifications.column_settings.filter_bar.category": "Kiirfiltri riba", "notifications.column_settings.follow": "Uued jälgijad:", "notifications.column_settings.follow_request": "Uued jälgimistaotlused:", - "notifications.column_settings.group": "Grupp", + "notifications.column_settings.group": "Grupeeri", "notifications.column_settings.mention": "Mainimised:", "notifications.column_settings.poll": "Küsitluse tulemused:", - "notifications.column_settings.push": "Push teated", + "notifications.column_settings.push": "Tõuketeavitused", "notifications.column_settings.quote": "Tsitaadid:", "notifications.column_settings.reblog": "Jagamised:", "notifications.column_settings.show": "Kuva tulbas", - "notifications.column_settings.sound": "Mängi heli", + "notifications.column_settings.sound": "Esita heli", "notifications.column_settings.status": "Uued postitused:", - "notifications.column_settings.unread_notifications.category": "Lugemata teated", - "notifications.column_settings.unread_notifications.highlight": "Tõsta esile lugemata teated", + "notifications.column_settings.unread_notifications.category": "Lugemata teavitused", + "notifications.column_settings.unread_notifications.highlight": "Tõsta lugemata teavitused esile", "notifications.column_settings.update": "Muudatused:", "notifications.filter.all": "Kõik", "notifications.filter.boosts": "Jagamised", diff --git a/app/javascript/mastodon/locales/fa.json b/app/javascript/mastodon/locales/fa.json index 482ea05165..3310a49495 100644 --- a/app/javascript/mastodon/locales/fa.json +++ b/app/javascript/mastodon/locales/fa.json @@ -366,8 +366,6 @@ "collection.share_modal.share_via_system": "هم‌رسانی در…", "collection.share_modal.title": "هم‌رسانی مجموعه", "collection.share_modal.title_new": "هم‌رسانی مجموعهٔ جدیدتان!", - "collection.share_template_other": "این مجموعهٔ باحال رو ببینید: {link}", - "collection.share_template_own": "مجموعهٔ جدیدم رو ببینید: {link}", "collections.account_count": "{count, plural, one {# حساب} other {# حساب}}", "collections.accounts.empty_description": "افزودن تا {count} حساب", "collections.accounts.empty_editor_title": "هنوز کسی در این مجموعه نیست", diff --git a/app/javascript/mastodon/locales/fi.json b/app/javascript/mastodon/locales/fi.json index 8e968d3f50..de63948162 100644 --- a/app/javascript/mastodon/locales/fi.json +++ b/app/javascript/mastodon/locales/fi.json @@ -86,6 +86,7 @@ "account.locked_info": "Tilin yksityisyystilaksi on määritetty lukittu. Tilin omistaja arvioi erikseen, kuka voi seurata häntä.", "account.media": "Media", "account.mention": "Mainitse @{name}", + "account.menu.add_to_collection": "Lisää kokoelmaan…", "account.menu.add_to_list": "Lisää listaan…", "account.menu.block": "Estä tili", "account.menu.block_domain": "Estä {domain}", @@ -366,12 +367,13 @@ "collection.share_modal.share_via_system": "Jaa kohteeseen…", "collection.share_modal.title": "Jaa kokoelma", "collection.share_modal.title_new": "Jaa uusi kokoelmasi!", - "collection.share_template_other": "Katso tämä siisti kokoelma: {link}", - "collection.share_template_own": "Katso uusi kokoelmani: {link}", + "collection.share_template_other": "Katso tämä siisti kokoelma:", + "collection.share_template_own": "Katso uusi kokoelmani:", "collections.account_count": "{count, plural, one {# tili} other {# tiliä}}", "collections.accounts.empty_description": "Lisää enintään {count} tiliä", "collections.accounts.empty_editor_title": "Kukaan ei ole vielä tässä kokoelmassa", "collections.accounts.empty_title": "Tämä kokoelma on tyhjä", + "collections.add_to_collection": "Lisää {name} kokoelmiin", "collections.block_collection_owner": "Estä tili", "collections.by_account": "koonnut {account_handle}", "collections.collection_description": "Kuvaus", diff --git a/app/javascript/mastodon/locales/fo.json b/app/javascript/mastodon/locales/fo.json index bd03f205e7..8268e44354 100644 --- a/app/javascript/mastodon/locales/fo.json +++ b/app/javascript/mastodon/locales/fo.json @@ -265,8 +265,6 @@ "collection.share_modal.share_via_system": "Deil til…", "collection.share_modal.title": "Deil savn", "collection.share_modal.title_new": "Deil títt nýggja savn!", - "collection.share_template_other": "Hygg at hesum kula savninum: {link}", - "collection.share_template_own": "Hygg at mínum nýggja savni: {link}", "collections.account_count": "{count, plural, one {# konta} other {# kontur}}", "collections.accounts.empty_title": "Hetta savnið er tómt", "collections.collection_description": "Lýsing", diff --git a/app/javascript/mastodon/locales/fr-CA.json b/app/javascript/mastodon/locales/fr-CA.json index ac4a76f4fc..a2969fe6f8 100644 --- a/app/javascript/mastodon/locales/fr-CA.json +++ b/app/javascript/mastodon/locales/fr-CA.json @@ -86,6 +86,7 @@ "account.locked_info": "Le statut de confidentialité de ce compte est privé. Son propriétaire vérifie manuellement qui peut le/la suivre.", "account.media": "Média", "account.mention": "Mentionner @{name}", + "account.menu.add_to_collection": "Ajouter à une collection…", "account.menu.add_to_list": "Ajouter à la liste…", "account.menu.block": "Bloquer le compte", "account.menu.block_domain": "Bloquer {domain}", @@ -366,12 +367,13 @@ "collection.share_modal.share_via_system": "Partager avec…", "collection.share_modal.title": "Partager la collection", "collection.share_modal.title_new": "Partager votre nouvelle collection !", - "collection.share_template_other": "Découvrez cette collection incroyable : {link}", - "collection.share_template_own": "Découvrez ma nouvelle collection : {link}", + "collection.share_template_other": "Découvrez cette collection incroyable :", + "collection.share_template_own": "Découvrez ma nouvelle collection :", "collections.account_count": "{count, plural, one {# compte} other {# comptes}}", "collections.accounts.empty_description": "Ajoutez jusqu'à {count} comptes", "collections.accounts.empty_editor_title": "Il n'y a personne dans cette collection", "collections.accounts.empty_title": "Cette collection est vide", + "collections.add_to_collection": "Ajouter {name} aux collections", "collections.block_collection_owner": "Bloquer le compte", "collections.by_account": "par {account_handle}", "collections.collection_description": "Description", @@ -394,6 +396,7 @@ "collections.detail.loading": "Chargement de la collection…", "collections.detail.revoke_inclusion": "Me retirer", "collections.detail.sensitive_content": "Contenu sensible", + "collections.detail.sensitive_note": "La description et les comptes peuvent ne pas convenir à tous les publics.", "collections.detail.share": "Partager la collection", "collections.detail.you_are_in_this_collection": "Vous faites partie de cette collection", "collections.edit_details": "Modifier les détails", @@ -424,6 +427,11 @@ "collections.search_accounts_max_reached": "Vous avez ajouté le nombre maximum de comptes", "collections.sensitive": "Sensible", "collections.share_short": "Partager", + "collections.sort_alphabetical": "Alphabétique", + "collections.sort_by": "Trier par :", + "collections.sort_date_added": "Date d'ajout", + "collections.sort_last_active": "Dernière activité", + "collections.sort_most_followers": "Nombre d'abonné·e·s", "collections.suggestions.can_not_add": "Ne peut pas être ajouté", "collections.suggestions.can_not_add_desc": "Ces comptes peuvent avoir choisi de ne pas être découverts, ou ils peuvent être sur un serveur qui ne supporte pas les collections.", "collections.suggestions.must_follow": "Vous devez d'abord suivre", diff --git a/app/javascript/mastodon/locales/fr.json b/app/javascript/mastodon/locales/fr.json index e183d96cf5..9fa3189420 100644 --- a/app/javascript/mastodon/locales/fr.json +++ b/app/javascript/mastodon/locales/fr.json @@ -86,6 +86,7 @@ "account.locked_info": "Ce compte est privé. Son ou sa propriétaire approuve manuellement qui peut le suivre.", "account.media": "Médias", "account.mention": "Mentionner @{name}", + "account.menu.add_to_collection": "Ajouter à une collection…", "account.menu.add_to_list": "Ajouter à la liste…", "account.menu.block": "Bloquer le compte", "account.menu.block_domain": "Bloquer {domain}", @@ -366,12 +367,13 @@ "collection.share_modal.share_via_system": "Partager avec…", "collection.share_modal.title": "Partager la collection", "collection.share_modal.title_new": "Partager votre nouvelle collection !", - "collection.share_template_other": "Découvrez cette collection incroyable : {link}", - "collection.share_template_own": "Découvrez ma nouvelle collection : {link}", + "collection.share_template_other": "Découvrez cette collection incroyable :", + "collection.share_template_own": "Découvrez ma nouvelle collection :", "collections.account_count": "{count, plural, one {# compte} other {# comptes}}", "collections.accounts.empty_description": "Ajoutez jusqu'à {count} comptes", "collections.accounts.empty_editor_title": "Il n'y a personne dans cette collection", "collections.accounts.empty_title": "Cette collection est vide", + "collections.add_to_collection": "Ajouter {name} aux collections", "collections.block_collection_owner": "Bloquer le compte", "collections.by_account": "par {account_handle}", "collections.collection_description": "Description", @@ -394,6 +396,7 @@ "collections.detail.loading": "Chargement de la collection…", "collections.detail.revoke_inclusion": "Me retirer", "collections.detail.sensitive_content": "Contenu sensible", + "collections.detail.sensitive_note": "La description et les comptes peuvent ne pas convenir à tous les publics.", "collections.detail.share": "Partager la collection", "collections.detail.you_are_in_this_collection": "Vous faites partie de cette collection", "collections.edit_details": "Modifier les détails", @@ -424,6 +427,11 @@ "collections.search_accounts_max_reached": "Vous avez ajouté le nombre maximum de comptes", "collections.sensitive": "Sensible", "collections.share_short": "Partager", + "collections.sort_alphabetical": "Alphabétique", + "collections.sort_by": "Trier par :", + "collections.sort_date_added": "Date d'ajout", + "collections.sort_last_active": "Dernière activité", + "collections.sort_most_followers": "Nombre d'abonné·e·s", "collections.suggestions.can_not_add": "Ne peut pas être ajouté", "collections.suggestions.can_not_add_desc": "Ces comptes peuvent avoir choisi de ne pas être découverts, ou ils peuvent être sur un serveur qui ne supporte pas les collections.", "collections.suggestions.must_follow": "Vous devez d'abord suivre", diff --git a/app/javascript/mastodon/locales/ga.json b/app/javascript/mastodon/locales/ga.json index a337394d34..81ab906c87 100644 --- a/app/javascript/mastodon/locales/ga.json +++ b/app/javascript/mastodon/locales/ga.json @@ -86,6 +86,7 @@ "account.locked_info": "Tá an socrú príobháideachais don cuntas seo curtha go 'faoi ghlas'. Déanann an t-úinéir léirmheas ar cén daoine atá ceadaithe an cuntas leanúint.", "account.media": "Meáin", "account.mention": "Luaigh @{name}", + "account.menu.add_to_collection": "Cuir leis an mbailiúchán…", "account.menu.add_to_list": "Cuir leis an liosta…", "account.menu.block": "Cuntas blocáilte", "account.menu.block_domain": "Blocáil {domain}", @@ -366,12 +367,11 @@ "collection.share_modal.share_via_system": "Comhroinn le…", "collection.share_modal.title": "Comhroinn bailiúchán", "collection.share_modal.title_new": "Roinn do bhailiúchán nua!", - "collection.share_template_other": "Féach ar an mbailiúchán fionnuar seo: {link}", - "collection.share_template_own": "Féach ar mo bhailiúchán nua: {link}", "collections.account_count": "{count, plural, one {# cuntas} two {# cuntais} few {# cuntais} many {# cuntais} other {# cuntais}}", "collections.accounts.empty_description": "Cuir suas le {count} cuntas leis", "collections.accounts.empty_editor_title": "Níl aon duine sa bhailiúchán seo fós", "collections.accounts.empty_title": "Tá an bailiúchán seo folamh", + "collections.add_to_collection": "Cuir {name} le bailiúcháin", "collections.block_collection_owner": "Cuntas blocáilte", "collections.by_account": "le {account_handle}", "collections.collection_description": "Cur síos", @@ -394,6 +394,7 @@ "collections.detail.loading": "Ag lódáil an bhailiúcháin…", "collections.detail.revoke_inclusion": "Bain mé", "collections.detail.sensitive_content": "Ábhar íogair", + "collections.detail.sensitive_note": "B’fhéidir nach mbeidh an cur síos agus na cuntais oiriúnach do gach lucht féachana.", "collections.detail.share": "Comhroinn an bailiúchán seo", "collections.detail.you_are_in_this_collection": "Tá tú le feiceáil sa bhailiúchán seo", "collections.edit_details": "Cuir sonraí in eagar", @@ -424,6 +425,11 @@ "collections.search_accounts_max_reached": "Tá an líon uasta cuntas curtha leis agat", "collections.sensitive": "Íogair", "collections.share_short": "Comhroinn", + "collections.sort_alphabetical": "Aibítre", + "collections.sort_by": "Sórtáil de réir:", + "collections.sort_date_added": "Dáta curtha leis", + "collections.sort_last_active": "Gníomhach deireanach", + "collections.sort_most_followers": "An chuid is mó leanúna", "collections.suggestions.can_not_add": "Ní féidir a chur leis", "collections.suggestions.can_not_add_desc": "B’fhéidir gur roghnaigh na cuntais seo gan a bheith san fhionnachtain, nó b’fhéidir go bhfuil siad ar fhreastalaí nach dtacaíonn le bailiúcháin.", "collections.suggestions.must_follow": "Ní mór leanúint ar dtús", @@ -635,6 +641,7 @@ "empty_column.blocks": "Níl aon úsáideoir bactha agat fós.", "empty_column.bookmarked_statuses": "Níl aon phostáil leabharmharcaithe agat fós. Nuair a dhéanann tú leabharmharc, beidh sé le feiceáil anseo.", "empty_column.collections.featured_in": "Níor cuireadh le haon bhailiúchán thú go fóill.", + "empty_column.collections.featured_in_undiscoverable": "Chun go mbeidh daoine in ann tú a chur le bailiúcháin, ní mór duit cead a thabhairt duit a bheith le feiceáil i dtaithí fionnachtana ó <link>Sainroghanna > Príobháideacht agus raon feidhme</link>", "empty_column.community": "Tá an amlíne áitiúil folamh. Foilsigh rud éigin go poiblí le tús a chur le cúrsaí!", "empty_column.direct": "Níl aon tagairtí príobháideacha agat fós. Nuair a sheolann tú nó a gheobhaidh tú ceann, beidh sé le feiceáil anseo.", "empty_column.disabled_feed": "Tá an fotha seo díchumasaithe ag riarthóirí do fhreastalaí.", diff --git a/app/javascript/mastodon/locales/gd.json b/app/javascript/mastodon/locales/gd.json index 5616c5fb60..d240a15ea5 100644 --- a/app/javascript/mastodon/locales/gd.json +++ b/app/javascript/mastodon/locales/gd.json @@ -361,8 +361,6 @@ "collection.share_modal.share_via_system": "Co-roinn gu…", "collection.share_modal.title": "Co-roinn an cruinneachadh", "collection.share_modal.title_new": "Co-roinn an cruinneachadh ùr agad!", - "collection.share_template_other": "Thoir sùil air an deagh-chruinneachadh seo: {link}", - "collection.share_template_own": "Thoir sùil air a’ chruinneachadh ùr agam: {link}", "collections.account_count": "{count, plural, one {# chunntas} two {# chunntas} few {# cunntasan} other {# cunntas}}", "collections.accounts.empty_editor_title": "Chan eil neach sam bith sa chruinneachadh seo fhathast", "collections.accounts.empty_title": "Tha an an cruinneachadh seo falamh", diff --git a/app/javascript/mastodon/locales/gl.json b/app/javascript/mastodon/locales/gl.json index e2a5175e39..216a6d1d1e 100644 --- a/app/javascript/mastodon/locales/gl.json +++ b/app/javascript/mastodon/locales/gl.json @@ -86,6 +86,7 @@ "account.locked_info": "Esta é unha conta privada. A propietaria revisa de xeito manual quen pode seguila.", "account.media": "Multimedia", "account.mention": "Mencionar @{name}", + "account.menu.add_to_collection": "Engadir á coleción…", "account.menu.add_to_list": "Engadir á lista…", "account.menu.block": "Bloquear conta", "account.menu.block_domain": "Bloquear a {domain}", @@ -366,12 +367,11 @@ "collection.share_modal.share_via_system": "Compartir con…", "collection.share_modal.title": "Compartir colección", "collection.share_modal.title_new": "Comparte a túa nova colección!", - "collection.share_template_other": "Mira que colección máis boa: {link}", - "collection.share_template_own": "Mira a miña nova colección: {link}", "collections.account_count": "{count, plural, one {# conta} other {# contas}}", "collections.accounts.empty_description": "Engade ate {count} contas", "collections.accounts.empty_editor_title": "Aínda non hai ninguén nesta colección", "collections.accounts.empty_title": "A colección está baleira", + "collections.add_to_collection": "Engadir a {name} ás coleccións", "collections.block_collection_owner": "Bloquear conta", "collections.by_account": "de {account_handle}", "collections.collection_description": "Descrición", @@ -425,6 +425,11 @@ "collections.search_accounts_max_reached": "Acadaches o máximo de contas permitidas", "collections.sensitive": "Sensible", "collections.share_short": "Compartir", + "collections.sort_alphabetical": "Alfabética", + "collections.sort_by": "Orde por:", + "collections.sort_date_added": "Data de alta", + "collections.sort_last_active": "Última actividade", + "collections.sort_most_followers": "Con máis seguidoras", "collections.suggestions.can_not_add": "Non se pode engadir", "collections.suggestions.can_not_add_desc": "Estas contas optaron por poder ser engadidas, ou pode que estean nun servidor que aínda non é compatible coas coleccións.", "collections.suggestions.must_follow": "Primeiro tes que seguila", diff --git a/app/javascript/mastodon/locales/he.json b/app/javascript/mastodon/locales/he.json index f8923bd78a..af6e2cbdbc 100644 --- a/app/javascript/mastodon/locales/he.json +++ b/app/javascript/mastodon/locales/he.json @@ -86,6 +86,7 @@ "account.locked_info": "החשבון הזה הוגדר כנעול. צריך לקבל אישור כדי לעקוב אחריו.", "account.media": "מדיה", "account.mention": "אזכור של @{name}", + "account.menu.add_to_collection": "הוספה לאוסף…", "account.menu.add_to_list": "הוספה לרשימה…", "account.menu.block": "חסימת חשבון", "account.menu.block_domain": "חסימת {domain}", @@ -366,12 +367,11 @@ "collection.share_modal.share_via_system": "לשתף אל…", "collection.share_modal.title": "שיתוף אוסף", "collection.share_modal.title_new": "שתפו את האוסף החדש שלכם!", - "collection.share_template_other": "הציצו על האוסף המעניין הזה: {link}", - "collection.share_template_own": "הציצו על האוסף החדש שלי: {link}", "collections.account_count": "{count, plural, one {חשבון אחד} other {# חשבונות}}", "collections.accounts.empty_description": "להוסיף עד ל־{count} חשבונות", "collections.accounts.empty_editor_title": "אוסף זה ריק כרגע", "collections.accounts.empty_title": "האוסף הזה ריק", + "collections.add_to_collection": "להוסיף את {name} לאוספים", "collections.block_collection_owner": "חסימת חשבון", "collections.by_account": "מאת {account_handle}", "collections.collection_description": "תיאור", @@ -394,6 +394,7 @@ "collections.detail.loading": "טוען אוסף…", "collections.detail.revoke_inclusion": "הסירוני", "collections.detail.sensitive_content": "תוכן רגיש", + "collections.detail.sensitive_note": "התיאור והחשבונות עשויים שלא להתאים לכל הצופיםות.", "collections.detail.share": "שיתוף אוסף", "collections.detail.you_are_in_this_collection": "אתם מופיעים באוסף זה", "collections.edit_details": "עריכת פרטים", @@ -424,6 +425,11 @@ "collections.search_accounts_max_reached": "הגעת למספר החשבונות המירבי", "collections.sensitive": "רגיש", "collections.share_short": "שיתוף", + "collections.sort_alphabetical": "בסדר האלפבית", + "collections.sort_by": "מיין לפי:", + "collections.sort_date_added": "תאריך הוספה", + "collections.sort_last_active": "פעילות אחרונה", + "collections.sort_most_followers": "מירב העוקבים", "collections.suggestions.can_not_add": "לא ניתן להוסיף", "collections.suggestions.can_not_add_desc": "חשבונות אלו כנראה ביקשו לא להכלל ב\"תגליות\" או שהם משתמשים בשרת שאינו תומך באוספים.", "collections.suggestions.must_follow": "יש לעקוב תחילה", @@ -635,6 +641,7 @@ "empty_column.blocks": "עדיין לא חסמתם משתמשים אחרים.", "empty_column.bookmarked_statuses": "אין עדיין הודעות שחיבבת. כשתחבב את הראשונה, היא תופיע כאן.", "empty_column.collections.featured_in": "עוד לא הוסיפו אותך לאף אוסף.", + "empty_column.collections.featured_in_undiscoverable": "כדי שאחרים יוכלו להוסיפך לאוספים, עליך לאפשר להופיע ב\"תגליות\" תחת <link>העדפות > פרטיות ומידת חשיפה</link>", "empty_column.community": "פיד השרת המקומי ריק. יש לפרסם משהו כדי שדברים יתרחילו להתגלגל!", "empty_column.direct": "אין לך שום הודעות פרטיות עדיין. כשתשלחו או תקבלו אחת, היא תופיע כאן.", "empty_column.disabled_feed": "פיד זה נחסם לשימוש על ידי מנהלי השרת שלך.", diff --git a/app/javascript/mastodon/locales/hu.json b/app/javascript/mastodon/locales/hu.json index 8d68aad1ee..5f421e7fde 100644 --- a/app/javascript/mastodon/locales/hu.json +++ b/app/javascript/mastodon/locales/hu.json @@ -86,6 +86,7 @@ "account.locked_info": "Ennek a fióknak zárolt a láthatósága. A tulajdonos kézzel engedélyezi, hogy ki követheti őt.", "account.media": "Média", "account.mention": "@{name} említése", + "account.menu.add_to_collection": "Hozzáadás gyűjteményhez…", "account.menu.add_to_list": "Hozzáadás listához…", "account.menu.block": "Fiók letiltása", "account.menu.block_domain": "{domain} letiltása", @@ -366,12 +367,13 @@ "collection.share_modal.share_via_system": "Megosztás…", "collection.share_modal.title": "Gyűjtemény megosztása", "collection.share_modal.title_new": "Oszd meg az új gyűjteményedet!", - "collection.share_template_other": "Nézd meg ezt a gyűjteményt: {link}", - "collection.share_template_own": "Nézd meg az új gyűjteményemet: {link}", + "collection.share_template_other": "Nézd meg ezt a gyűjteményt:", + "collection.share_template_own": "Nézd meg az új gyűjteményemet:", "collections.account_count": "{count, plural, one {# fiók} other {# fiók}}", "collections.accounts.empty_description": "Adj hozzá legfeljebb {count} fiókot", "collections.accounts.empty_editor_title": "Még senki sincs ebben a gyűjteményben", "collections.accounts.empty_title": "Ez a gyűjtemény üres", + "collections.add_to_collection": "{name} hozzáadása gyűjteményekhez", "collections.block_collection_owner": "Fiók letiltása", "collections.by_account": "szerző: {account_handle}", "collections.collection_description": "Leírás", @@ -394,6 +396,7 @@ "collections.detail.loading": "Gyűjtemény betöltése…", "collections.detail.revoke_inclusion": "Saját magam eltávolítása", "collections.detail.sensitive_content": "Kényes tartalom", + "collections.detail.sensitive_note": "A leírás és a fiókok lehet, hogy nem minden megtekintő számára megfelelőek.", "collections.detail.share": "Gyűjtemény megosztása", "collections.detail.you_are_in_this_collection": "Kiemeltek téged ebben a gyűjteményhez", "collections.edit_details": "Részletek szerkesztése", @@ -424,6 +427,11 @@ "collections.search_accounts_max_reached": "Elérte a hozzáadott fiókok maximális számát", "collections.sensitive": "Érzékeny", "collections.share_short": "Megosztás", + "collections.sort_alphabetical": "Betűrendben", + "collections.sort_by": "Rendezés:", + "collections.sort_date_added": "Hozzáadás dátuma", + "collections.sort_last_active": "Utoljára aktív", + "collections.sort_most_followers": "Legtöbb követő", "collections.suggestions.can_not_add": "Nem adható hozzá", "collections.suggestions.can_not_add_desc": "Ezek a fiókok lehet, hogy a felfedezés kikapcsolását kérték, vagy olyan kiszolgálón lehetnek, mely nem támogatja a gyűjteményeket.", "collections.suggestions.must_follow": "Először követni kell", diff --git a/app/javascript/mastodon/locales/io.json b/app/javascript/mastodon/locales/io.json index c287c20279..5c318f09b4 100644 --- a/app/javascript/mastodon/locales/io.json +++ b/app/javascript/mastodon/locales/io.json @@ -199,8 +199,6 @@ "collection.share_modal.share_via_system": "Kunhavigez ad…", "collection.share_modal.title": "Kunhavigez kolektajo", "collection.share_modal.title_new": "Kunhavigez vua nova kolektajo!", - "collection.share_template_other": "Videz ca splendida kolektajo: {link}", - "collection.share_template_own": "Videz mia nova kolektajo: {link}", "collections.content_warning": "Kontenajaverto", "collections.create.accounts_title": "Quan vu estalos en ca kolektajo?", "collections.detail.share": "Kunhavigez ca kolektajo", diff --git a/app/javascript/mastodon/locales/is.json b/app/javascript/mastodon/locales/is.json index 0923724f9e..2ffafd985b 100644 --- a/app/javascript/mastodon/locales/is.json +++ b/app/javascript/mastodon/locales/is.json @@ -366,8 +366,6 @@ "collection.share_modal.share_via_system": "Deila með…", "collection.share_modal.title": "Deila safni", "collection.share_modal.title_new": "Deildu nýja safninu þínu!", - "collection.share_template_other": "Kíktu á þetta áhugaverða safn: {link}", - "collection.share_template_own": "Kíktu á nýja safnið mitt: {link}", "collections.account_count": "{count, plural, one {# aðgangur} other {# aðgangar}}", "collections.accounts.empty_description": "Bættu við allt að {count} aðgöngum", "collections.accounts.empty_editor_title": "Enginn er enn í þessu safni", diff --git a/app/javascript/mastodon/locales/it.json b/app/javascript/mastodon/locales/it.json index 7f81f07c7e..9364e9bafb 100644 --- a/app/javascript/mastodon/locales/it.json +++ b/app/javascript/mastodon/locales/it.json @@ -86,6 +86,7 @@ "account.locked_info": "Lo stato della privacy di questo profilo è impostato a bloccato. Il proprietario revisiona manualmente chi può seguirlo.", "account.media": "Media", "account.mention": "Menziona @{name}", + "account.menu.add_to_collection": "Aggiungi alla collezione…", "account.menu.add_to_list": "Aggiungi alla lista…", "account.menu.block": "Blocca l'account", "account.menu.block_domain": "Blocca {domain}", @@ -366,12 +367,11 @@ "collection.share_modal.share_via_system": "Condividi con…", "collection.share_modal.title": "Condividi la collezione", "collection.share_modal.title_new": "Condividi la tua nuova collezione!", - "collection.share_template_other": "Dai un'occhiata a questa fantastica collezione: {link}", - "collection.share_template_own": "Dai un'occhiata alla mia collezione: {link}", "collections.account_count": "{count, plural, one {# account} other {# account}}", "collections.accounts.empty_description": "Aggiungi fino a {count} account", "collections.accounts.empty_editor_title": "Nessuno è ancora in questa collezione", "collections.accounts.empty_title": "Questa collezione è vuota", + "collections.add_to_collection": "Aggiungi {name} alle collezioni", "collections.block_collection_owner": "Blocca l'account", "collections.by_account": "di {account_handle}", "collections.collection_description": "Descrizione", @@ -425,6 +425,11 @@ "collections.search_accounts_max_reached": "Hai aggiunto il numero massimo di account", "collections.sensitive": "Sensibile", "collections.share_short": "Condividi", + "collections.sort_alphabetical": "Ordine alfabetico", + "collections.sort_by": "Ordina per:", + "collections.sort_date_added": "Data aggiunta", + "collections.sort_last_active": "Ultima attività", + "collections.sort_most_followers": "Più follower", "collections.suggestions.can_not_add": "Non può essere aggiunto", "collections.suggestions.can_not_add_desc": "Questi account potrebbero aver scelto di non essere scoperti, oppure potrebbero trovarsi su un server che non supporta le collezioni.", "collections.suggestions.must_follow": "Devi prima seguire", @@ -762,7 +767,7 @@ "hints.profiles.see_more_posts": "Vedi altri post su {domain}", "home.column_settings.show_quotes": "Mostra le citazioni", "home.column_settings.show_reblogs": "Mostra le condivisioni", - "home.column_settings.show_replies": "Mostra risposte", + "home.column_settings.show_replies": "Mostra le risposte", "home.hide_announcements": "Nascondi annunci", "home.pending_critical_update.body": "Ti preghiamo di aggiornare il tuo server di Mastodon, il prima possibile!", "home.pending_critical_update.link": "Visualizza aggiornamenti", @@ -935,7 +940,7 @@ "notification.follow_request.name_and_others": "{name} e {count, plural, one {# altro} other {altri #}} hanno richiesto di seguirti", "notification.label.mention": "Menziona", "notification.label.private_mention": "Menzione privata", - "notification.label.private_reply": "Rispondi in privato", + "notification.label.private_reply": "Risposta in privato", "notification.label.quote": "{name} ha citato il tuo post", "notification.label.reply": "Rispondi", "notification.mention": "Menziona", @@ -952,7 +957,7 @@ "notification.own_poll": "Il tuo sondaggio è terminato", "notification.poll": "Un sondaggio in cui hai votato è terminato", "notification.quoted_update": "{name} ha modificato un post che hai citato", - "notification.reblog": "{name} ha rebloggato il tuo post", + "notification.reblog": "{name} ha condiviso il tuo post", "notification.reblog.name_and_others_with_link": "{name} e <a>{count, plural, one {# altro} other {altri #}}</a> hanno condiviso il tuo post", "notification.relationships_severance_event": "Connessioni perse con {name}", "notification.relationships_severance_event.account_suspension": "Un amministratore da {from} ha sospeso {target}, il che significa che non puoi più ricevere aggiornamenti da loro o interagire con loro.", @@ -1267,7 +1272,7 @@ "status.reblog_or_quote": "Condividi o cita", "status.reblog_private": "Condividi di nuovo con i tuoi follower", "status.reblogged_by": "{name} ha condiviso", - "status.reblogs.empty": "Ancora nessuno ha rebloggato questo post. Quando qualcuno lo farà, apparirà qui.", + "status.reblogs.empty": "Nessuno ha ancora condiviso questo post. Quando qualcuno lo farà, comparirà qui.", "status.reblogs_count": "{count, plural, one {{counter} condivisione} other {{counter} condivisioni}}", "status.redraft": "Elimina e riscrivi", "status.remove_bookmark": "Rimuovi segnalibro", diff --git a/app/javascript/mastodon/locales/ja.json b/app/javascript/mastodon/locales/ja.json index b8f10e5a76..f8d67407b2 100644 --- a/app/javascript/mastodon/locales/ja.json +++ b/app/javascript/mastodon/locales/ja.json @@ -181,8 +181,6 @@ "collection.share_modal.share_via_system": "共有…", "collection.share_modal.title": "コレクションを共有", "collection.share_modal.title_new": "新しいコレクションを共有しよう!", - "collection.share_template_other": "この素敵なコレクションを見てみてください: {link}", - "collection.share_template_own": "私の新しいコレクションを見てみてください: {link}", "collections.accounts.empty_title": "このコレクションは空です", "collections.by_account": "{account_handle} による", "collections.collection_description": "詳細", diff --git a/app/javascript/mastodon/locales/nan-TW.json b/app/javascript/mastodon/locales/nan-TW.json index 0da1f615d3..450e931288 100644 --- a/app/javascript/mastodon/locales/nan-TW.json +++ b/app/javascript/mastodon/locales/nan-TW.json @@ -366,8 +366,6 @@ "collection.share_modal.share_via_system": "分享kàu……", "collection.share_modal.title": "分享收藏", "collection.share_modal.title_new": "分享lí ê新收藏!", - "collection.share_template_other": "緊看覓chit ê時行ê收藏:{link}", - "collection.share_template_own": "緊看覓我ê收藏:{link}", "collections.account_count": "{count, plural, other {# ê口座}}", "collections.accounts.empty_description": "加上tsē {count} ê口座", "collections.accounts.empty_editor_title": "Tsit ê 收藏內底iáu無半ê lâng", diff --git a/app/javascript/mastodon/locales/nl.json b/app/javascript/mastodon/locales/nl.json index e4301e2799..0c2a59a19c 100644 --- a/app/javascript/mastodon/locales/nl.json +++ b/app/javascript/mastodon/locales/nl.json @@ -86,6 +86,7 @@ "account.locked_info": "De privacystatus van dit account is ingesteld op vergrendeld. De eigenaar beoordeelt handmatig wie diegene kan volgen.", "account.media": "Media", "account.mention": "@{name} vermelden", + "account.menu.add_to_collection": "Aan verzameling toevoegen…", "account.menu.add_to_list": "Aan lijst toevoegen…", "account.menu.block": "Account blokkeren", "account.menu.block_domain": "{domain} blokkeren", @@ -366,12 +367,11 @@ "collection.share_modal.share_via_system": "Delen met…", "collection.share_modal.title": "Verzameling delen", "collection.share_modal.title_new": "Je nieuwe verzameling delen!", - "collection.share_template_other": "Bekijk deze coole verzameling: {link}", - "collection.share_template_own": "Bekijk mijn nieuwe verzameling: {link}", "collections.account_count": "{count, plural, one {# account} other {# accounts}}", "collections.accounts.empty_description": "Tot {count} accounts toevoegen", "collections.accounts.empty_editor_title": "Er is nog nog niemand in deze verzameling", "collections.accounts.empty_title": "Deze verzameling is leeg", + "collections.add_to_collection": "Voeg {name} aan verzamelingen toe", "collections.block_collection_owner": "Account blokkeren", "collections.by_account": "door {account_handle}", "collections.collection_description": "Omschrijving", @@ -425,6 +425,11 @@ "collections.search_accounts_max_reached": "Je hebt het maximum aantal accounts toegevoegd", "collections.sensitive": "Gevoelig", "collections.share_short": "Delen", + "collections.sort_alphabetical": "Alfabetisch", + "collections.sort_by": "Sortering:", + "collections.sort_date_added": "Datum toegevoegd", + "collections.sort_last_active": "Laatst actief", + "collections.sort_most_followers": "Meeste volgers", "collections.suggestions.can_not_add": "Kan niet worden toegevoegd", "collections.suggestions.can_not_add_desc": "Deze accounts willen mogelijk niet worden uitgelicht, of ze bevinden zich op een server die geen verzamelingen ondersteunt.", "collections.suggestions.must_follow": "Moeten eerst gevolgd worden", diff --git a/app/javascript/mastodon/locales/nn.json b/app/javascript/mastodon/locales/nn.json index 09b8eb1e9f..d90d4d48d5 100644 --- a/app/javascript/mastodon/locales/nn.json +++ b/app/javascript/mastodon/locales/nn.json @@ -361,8 +361,6 @@ "collection.share_modal.share_via_system": "Del med…", "collection.share_modal.title": "Del ei samling", "collection.share_modal.title_new": "Del den nye samlinga di!", - "collection.share_template_other": "Sjekk denne samlinga: {link}", - "collection.share_template_own": "Sjekk den nye samlinga mi: {link}", "collections.account_count": "{count, plural, one {# konto} other {# kontoar}}", "collections.accounts.empty_title": "Denne samlinga er tom", "collections.by_account": "av {account_handle}", diff --git a/app/javascript/mastodon/locales/pt-BR.json b/app/javascript/mastodon/locales/pt-BR.json index c966e05936..e6e97aea18 100644 --- a/app/javascript/mastodon/locales/pt-BR.json +++ b/app/javascript/mastodon/locales/pt-BR.json @@ -44,7 +44,7 @@ "account.featured.accounts": "Perfis", "account.featured.collections": "Coleções", "account.featured.new_collection": "Nova coleção", - "account.field_overflow": "Exibir conteúdo inteiro", + "account.field_overflow": "Exibir conteúdo completo", "account.filters.all": "Toda atividade", "account.filters.boosts_toggle": "Exibir impulsos", "account.filters.posts_boosts": "Publicações e impulsos", @@ -70,13 +70,13 @@ "account.hide_reblogs": "Ocultar impulsos de @{name}", "account.in_memoriam": "In Memoriam.", "account.join_modal.day": "Dia", - "account.join_modal.me": "Você juntou-se à {server} em", - "account.join_modal.me_anniversary": "Feliz Fediversário! Você juntou-se à {server} em", + "account.join_modal.me": "Você está em {server} desde", + "account.join_modal.me_anniversary": "Feliz Fediversário! Você está em {server} desde", "account.join_modal.me_today": "É seu primeiro dia em {server}!", - "account.join_modal.other": "{name} juntou-se à {server} em", + "account.join_modal.other": "{name} está em {server} desde", "account.join_modal.other_today": "Este é o primeiro dia de {name} em {server}!", "account.join_modal.share.celebrate": "Compartilhar publicação comemorativa", - "account.join_modal.share.intro": "Compartilhar publicação de introdução", + "account.join_modal.share.intro": "Compartilhar publicação de apresentação", "account.join_modal.share.welcome": "Compartilhar publicação de boas-vindas", "account.join_modal.years": "{number, plural, one {ano} other {anos}}", "account.joined_short": "Entrou", @@ -86,6 +86,7 @@ "account.locked_info": "Trancado. Seguir requer aprovação manual do perfil.", "account.media": "Mídia", "account.mention": "Mencionar @{name}", + "account.menu.add_to_collection": "Adicionar à coleção…", "account.menu.add_to_list": "Adicionar à lista…", "account.menu.block": "Bloquear conta", "account.menu.block_domain": "Bloquear {domain}", @@ -103,7 +104,7 @@ "account.menu.show_reblogs": "Exibir impulsos na timeline", "account.menu.unblock": "Desbloquear conta", "account.menu.unblock_domain": "Desbloquear {domain}", - "account.menu.unmute": "Deixar de silenciar a conta", + "account.menu.unmute": "Dessilenciar conta", "account.moved_to": "{name} indicou que sua nova conta agora é:", "account.mute": "Silenciar @{name}", "account.mute_notifications_short": "Silenciar notificações", @@ -111,22 +112,22 @@ "account.muted": "Silenciado", "account.mutual": "Vocês se seguem", "account.name.copy": "Copiar usuário", - "account.name.help.domain": "{domain} é o servidor que hospeda o perfil e publicações do usuário.", + "account.name.help.domain": "{domain} é o servidor que hospeda este perfil e suas publicações.", "account.name.help.domain_self": "{domain} é o servidor que hospeda seu perfil e suas publicações.", - "account.name.help.footer": "Assim como você pode enviar e-mails para outras pessoas usando endereços de e-mail diferentes, você pode interagir com usuários em outros servidores do Mastodon, e com qualquer um dos outros aplicativos do Fediverso.", - "account.name.help.header": "Um nome de usuário é como um e-mail", - "account.name.help.username": "{username} é o usuário desta conta em seu próprio servidor. Alguém do mesmo servidor talvez possua o mesmo usuário.", - "account.name.help.username_self": "{username} é seu usuário neste servidor. Alguém em outro servidor talvez possua o mesmo usuário.", + "account.name.help.footer": "Assim como pode enviar e-mails para pessoas usando diferentes provedores de e-mail, você pode interagir com pessoas em outros servidor do Mastodon, e com qualquer um em outros apps da Fediverse.", + "account.name.help.header": "Um nome de usuário é como um endereço de email", + "account.name.help.username": "{username} é o nome de usuário desta conta no servidor dela. Alguém em outro servidor pode ter o mesmo nome de usuário.", + "account.name.help.username_self": "{username} é seu nome de usuário neste servidor. Alguém em outro servidor pode ter o mesmo nome de usuário.", "account.name_info": "O que isso quer dizer?", "account.no_bio": "Nenhuma descrição fornecida.", - "account.node_modal.callout": "Notas pessoais são visíveis somente para você.", + "account.node_modal.callout": "Notas pessoais são visíveis apenas para você.", "account.node_modal.edit_title": "Editar nota pessoal", - "account.node_modal.error_unknown": "Não foi possível salvar nota", + "account.node_modal.error_unknown": "Não foi possível salvar a nota", "account.node_modal.field_label": "Nota Pessoal", "account.node_modal.save": "Salvar", "account.node_modal.title": "Adicionar nota pessoal", "account.note.edit_button": "Editar", - "account.note.title": "Nota pessoal (visível só para você)", + "account.note.title": "Nota pessoal (visível apenas para você)", "account.open_original_page": "Abrir a página original", "account.pending": "Pendente", "account.posts": "Publicações", @@ -137,7 +138,7 @@ "account.show_reblogs": "Mostrar impulsos de @{name}", "account.statuses_counter": "{count, plural, one {{counter} publicação} other {{counter} publicações}}", "account.timeline.pinned": "Fixado", - "account.timeline.pinned.view_all": "Ver publicações fixadas", + "account.timeline.pinned.view_all": "Ver todas as publicações fixadas", "account.unblock": "Desbloquear @{name}", "account.unblock_domain": "Desbloquear domínio {domain}", "account.unblock_domain_short": "Desbloquear", @@ -147,50 +148,50 @@ "account.unmute": "Dessilenciar @{name}", "account.unmute_notifications_short": "Ativar som de notificações", "account.unmute_short": "Desativar silêncio", - "account_edit.advanced_settings.bot_hint": "Alertar a todos que a conta realiza ações automáticas que talvez não sejam monitoradas", - "account_edit.advanced_settings.bot_label": "Conta automática", - "account_edit.advanced_settings.title": "Opções avançadas", + "account_edit.advanced_settings.bot_hint": "Alertar a outros que a conta realiza ações automáticas que talvez não sejam monitoradas", + "account_edit.advanced_settings.bot_label": "Conta automatizada", + "account_edit.advanced_settings.title": "Configurações avançadas", "account_edit.bio.add_label": "Adicionar biografia", "account_edit.bio.edit_label": "Editar biografia", - "account_edit.bio.placeholder": "Escreva uma curta introdução para ajudar os outros a identificarem você.", + "account_edit.bio.placeholder": "Insira uma breve apresentação para ajudar os outros a lhe identificarem.", "account_edit.bio.title": "Biografia", "account_edit.bio_modal.add_title": "Adicionar biografia", "account_edit.bio_modal.edit_title": "Editar biografia", "account_edit.column_button": "Concluído", "account_edit.column_title": "Editar perfil", - "account_edit.custom_fields.add_label": "Novo espaço", - "account_edit.custom_fields.edit_label": "Editar espaço", - "account_edit.custom_fields.placeholder": "Adicione seus pronomes, links externos ou qualquer coisa que deseja compartilhar.", - "account_edit.custom_fields.reorder_button": "Reordenar espaços", - "account_edit.custom_fields.tip_content": "Você pode adicionar credibilidade facilmente a sua conta ao verificar qualquer link para seus sites.", - "account_edit.custom_fields.tip_title": "Dica: Adicionando links verificados", - "account_edit.custom_fields.title": "Espaços personalizados", - "account_edit.custom_fields.verified_hint": "Como adicionar um link verificado?", - "account_edit.display_name.add_label": "Adicionar nome de exibição", + "account_edit.custom_fields.add_label": "Acrescentar campo", + "account_edit.custom_fields.edit_label": "Editar campo", + "account_edit.custom_fields.placeholder": "Insira seus pronomes, links externos ou qualquer coisa que queira compartilhar.", + "account_edit.custom_fields.reorder_button": "Reordenar campos", + "account_edit.custom_fields.tip_content": "Você pode facilmente dar credibilidade à sua conta Mastodon verificando os links para os seus sites.", + "account_edit.custom_fields.tip_title": "Dica: Adicionar links verificados", + "account_edit.custom_fields.title": "Campos personalizados", + "account_edit.custom_fields.verified_hint": "Como adiciono um link verificado?", + "account_edit.display_name.add_label": "Acrescentar nome de exibição", "account_edit.display_name.edit_label": "Editar nome de exibição", - "account_edit.display_name.placeholder": "O nome de exibição é como seu nome aparece em seu perfil e em timelines.", + "account_edit.display_name.placeholder": "Seu nome de exibição é a forma com que seu nome aparece em seu perfil e em suas linhas do tempo.", "account_edit.display_name.title": "Nome de exibição", - "account_edit.featured_hashtags.edit_label": "Adicionar tags", - "account_edit.featured_hashtags.placeholder": "Ajude todos a identificarem, e acessarem rapidamente seus tópicos favoritos.", - "account_edit.featured_hashtags.title": "Tags em destaque", - "account_edit.field_actions.delete": "Remover espaço", - "account_edit.field_actions.edit": "Editar espaço", - "account_edit.field_delete_modal.confirm": "Deseja mesmo excluir este espaço? Esta ação não pode ser desfeita.", + "account_edit.featured_hashtags.edit_label": "Acrescentar hashtags", + "account_edit.featured_hashtags.placeholder": "Ajude outros a identificar e ter acesso rápido a seus tópicos favoritos.", + "account_edit.featured_hashtags.title": "Hashtags em destaque", + "account_edit.field_actions.delete": "Remover campo", + "account_edit.field_actions.edit": "Editar campo", + "account_edit.field_delete_modal.confirm": "Tem certeza que deseja excluir este campo personalizado? Esta ação não pode ser desfeita.", "account_edit.field_delete_modal.delete_button": "Excluir", "account_edit.field_delete_modal.title": "Remover espaço?", "account_edit.field_edit_modal.add_title": "Adicionar espaço", "account_edit.field_edit_modal.discard_confirm": "Descartar", "account_edit.field_edit_modal.discard_message": "Você possui alterações não salvas. Deseja mesmo descartá-las?", - "account_edit.field_edit_modal.edit_title": "Editar campo personalizado", - "account_edit.field_edit_modal.length_warning": "Limite de caracteres recomendados ultrapassado. Usuários em telefones podem não conseguir ver o espaço completo.", - "account_edit.field_edit_modal.link_emoji_warning": "Recomendamos não utilizar emojis personalizados combinados com URLs. Campos personalizados contendo ambos serão exibidos apenas como texto em vez de link, para evitar confusão dos usuários.", - "account_edit.field_edit_modal.name_hint": "Ex. \"Site pessoal\"", - "account_edit.field_edit_modal.name_label": "Descrição", - "account_edit.field_edit_modal.url_warning": "Para adicionar um link, inclua {protocol} no início.", + "account_edit.field_edit_modal.edit_title": "Editar espaço", + "account_edit.field_edit_modal.length_warning": "Limite de caracteres excedido. Usuários móveis talvez não consigam ver seus espaços por inteiro.", + "account_edit.field_edit_modal.link_emoji_warning": "Recomendamos não usar emojis personalizados com URLs. Espaços contendo ambos serão exibidos apenas como um texto invés de um link para evitar confusão.", + "account_edit.field_edit_modal.name_hint": "p. e.x.: “Site pessoal”", + "account_edit.field_edit_modal.name_label": "Rótulo", + "account_edit.field_edit_modal.url_warning": "Para adicionar links, inclua {protocol} no início.", "account_edit.field_edit_modal.value_hint": "Ex.: \"https://example.me\"", "account_edit.field_edit_modal.value_label": "Valor", - "account_edit.field_reorder_modal.drag_cancel": "O arrasto foi cancelado. O campo \"{item}\" foi descartado.", - "account_edit.field_reorder_modal.drag_end": "O campo \"{item}\" foi descartado.", + "account_edit.field_reorder_modal.drag_cancel": "Arraste cancelado. O campo \"{item}\" foi solto.", + "account_edit.field_reorder_modal.drag_end": "O campo \"{item}\" foi solto.", "account_edit.field_reorder_modal.drag_instructions": "Para reordenar campos personalizados, pressione espaço ou enter. Enquanto arrasta, utilize as teclas de seta para mover o campo para cima ou para baixo. Pressione espaço ou enter novamente para colocar o campo em sua nova posição, ou pressione 'Esc' para cancelar.", "account_edit.field_reorder_modal.drag_move": "Campo \"{item}\" foi movido.", "account_edit.field_reorder_modal.drag_over": "Campo \"{item}\" foi movido para \"{over}\".", @@ -201,62 +202,62 @@ "account_edit.image_alt_modal.details_content": "FAÇA: <ul><li> Descreva-se como retratado/a</li><li>Utilize linguagem em terceira pessoa (p. ex.: \"Alex\" em vez de \"eu\")</li><li>Seja sucinto/a — algumas palavras costumam ser o suficiente</li></ul> NÃO FAÇA: <ul><li>Comece com \"Foto de\" — é redundante para leitores de tela</li></ul> EXEMPLO:<ul><li>\"Alex vestindo uma camisa verde e óvulos\"</li></ul>", "account_edit.image_alt_modal.details_title": "Dicas: Texto alternativo para fotos", "account_edit.image_alt_modal.edit_title": "Editar texto alternativo", - "account_edit.image_alt_modal.text_hint": "Texto alternativo ajuda leitores de tela a entender seu conteúdo.", + "account_edit.image_alt_modal.text_hint": "Texto alternativo ajuda susuários de leitores de tela a entender seu conteúdo.", "account_edit.image_alt_modal.text_label": "Texto alternativo", "account_edit.image_delete_modal.confirm": "Tem certeza de que deseja excluir esta imagem? Esta ação não pode ser desfeita.", - "account_edit.image_delete_modal.delete_button": "Deletar", - "account_edit.image_delete_modal.title": "Deletar imagem?", - "account_edit.image_edit.add_button": "Adicionar imagem", - "account_edit.image_edit.alt_add_button": "Adicionar texto alternativo", + "account_edit.image_delete_modal.delete_button": "Excluir", + "account_edit.image_delete_modal.title": "Excluir imagem?", + "account_edit.image_edit.add_button": "Inserir imagem", + "account_edit.image_edit.alt_add_button": "Inserir texto alternativo", "account_edit.image_edit.alt_edit_button": "Editar texto alternativo", "account_edit.image_edit.remove_button": "Remover imagem", "account_edit.image_edit.replace_button": "Substituir imagem", - "account_edit.item_list.delete": "Deletar {name}", + "account_edit.item_list.delete": "Excluir {name}", "account_edit.item_list.edit": "Editar {name}", "account_edit.name_modal.add_title": "Inserir nome de exibição", "account_edit.name_modal.edit_title": "Editar nome de exibição", "account_edit.profile_tab.button_label": "Personalizar", - "account_edit.profile_tab.hint.description": "Essas configurações definem o que os usuários veem no {server} nos apps oficiais, mas podem não se aplicar a usuários em servidores e apps de terceiros.", - "account_edit.profile_tab.hint.title": "Exibições divergem", + "account_edit.profile_tab.hint.description": "Essas configurações definem o que os usuários veem no {server} através dos aplicativos oficiais, mas podem não se aplicar a usuários em servidores e aplicativos de terceiros.", + "account_edit.profile_tab.hint.title": "A exibição pode variar", "account_edit.profile_tab.show_featured.description": "'Em Destaque' é uma aba opcional onde você pode exibir outras contas.", - "account_edit.profile_tab.show_featured.title": "Mostrar aba \"Destaque\"", - "account_edit.profile_tab.show_media.description": "\"Mídia\" é uma aba opcional que mostra seus posts, contendo imagens ou vídeos.", - "account_edit.profile_tab.show_media.title": "Mostrar aba \"Mídia\"", - "account_edit.profile_tab.show_media_replies.description": "Quando ativa, a aba Mídia mostra seus posts e respostas nos posts de outras pessoas.", - "account_edit.profile_tab.show_media_replies.title": "Incluir respostas na aba \"Mídia\"", - "account_edit.profile_tab.show_relations.description": "Exibe contas que segue e seguidores para outros usuários no seu perfil. As pessoas poderão ainda ver se você está as seguindo.", + "account_edit.profile_tab.show_featured.title": "Exibir aba 'Em destaque'", + "account_edit.profile_tab.show_media.description": "'Mídia' é uma aba opcional que mostra suas publicações contendo imagens ou vídeos.", + "account_edit.profile_tab.show_media.title": "Exibir aba 'Mídia'", + "account_edit.profile_tab.show_media_replies.description": "Se ativa, a aba Mídia mostrará ambas suas publicações e respostas a outras pessoas.", + "account_edit.profile_tab.show_media_replies.title": "Incluir respostas na aba 'Mídia'", + "account_edit.profile_tab.show_relations.description": "Exibe em seu perfil as contas que segue e seguidores para outros usuários. As pessoas poderão ainda ver se você as segue.", "account_edit.profile_tab.show_relations.title": "Exibir 'Seguidores' e 'Seguindo'", - "account_edit.profile_tab.subtitle": "Customizar como seu perfil é exibido.", + "account_edit.profile_tab.subtitle": "Personalize como seu perfil é exibido.", "account_edit.profile_tab.title": "Configurações de exibição do perfil", "account_edit.save": "Salvar", "account_edit.upload_modal.back": "Voltar", "account_edit.upload_modal.done": "Concluído", "account_edit.upload_modal.next": "Próximo", - "account_edit.upload_modal.step_crop.zoom": "Aproximar", - "account_edit.upload_modal.step_upload.button": "Procurar arquivos", + "account_edit.upload_modal.step_crop.zoom": "Ampliar", + "account_edit.upload_modal.step_upload.button": "Buscar arquivos", "account_edit.upload_modal.step_upload.dragging": "Solte para enviar", "account_edit.upload_modal.step_upload.header": "Escolha uma imagem", - "account_edit.upload_modal.step_upload.hint": "WEBP, formatos GIF ou JPG, até {limit}MB.{br} imagem será redimensionada para {width}x{height}px.", + "account_edit.upload_modal.step_upload.hint": "Formato .webp, .png, .gif ou .jpg, até {limit}MB.{br}A imagem será redimensionada para {width}x{height}px.", "account_edit.upload_modal.title_add.avatar": "Adicionar foto de perfil", "account_edit.upload_modal.title_add.header": "Adicionar foto de capa", "account_edit.upload_modal.title_replace.avatar": "Substituir foto de perfil", "account_edit.upload_modal.title_replace.header": "Substituir foto de capa", "account_edit.verified_modal.details": "Dê credibilidade ao seu perfil do Mastodon, verificando links para sites pessoais. Veja como funciona:", - "account_edit.verified_modal.invisible_link.details": "Adicione o link para seu HTML do site. A parte importante é rel=\"eu\" onde previne falsificação de identidade em sites com conteúdo gerado por usuários. Você pode até mesmo usar um link tag no HTML da página ao invés de {tag}, mas o HTML deve ser acessível sem a execução do JavaScript.", - "account_edit.verified_modal.invisible_link.summary": "Como posso tornar o link invisível?", + "account_edit.verified_modal.invisible_link.details": "Adicione o link ao cabeçalho. A parte importante é rel=\"me\" que impede personificação em sites com conteúdo gerado por usuários. Você pode usar um rótulo de link no cabeçalho em vez de {tag}, porém o HTML deverá ser acessível sem precisar de JavaScript.", + "account_edit.verified_modal.invisible_link.summary": "Como tornar o link invisível?", "account_edit.verified_modal.step1.header": "Copie o código HTML abaixo e cole no cabeçalho do seu site", "account_edit.verified_modal.step2.details": "Se já adicionou seu site como um campo personalizado, deverá excluí-lo e adicioná-lo novamente para acionar a verificação.", "account_edit.verified_modal.step2.header": "Adicione seu site como um campo personalizado", "account_edit.verified_modal.title": "Como adicionar um link verificado", "account_edit_tags.add_tag": "Adicionar #{tagName}", - "account_edit_tags.column_title": "Editar Tags", + "account_edit_tags.column_title": "Editar rótulos", "account_edit_tags.help_text": "Hashtags em destaque ajudam os usuários a descobrir e interagir com seu perfil. Elas aparecem como filtros na visualização de Atividade da sua página de Perfil.", "account_edit_tags.max_tags_reached": "Você atingiu o número máximo de hashtags em destaque.", "account_edit_tags.search_placeholder": "Insira uma hashtag…", "account_edit_tags.suggestions": "Sugestões:", "account_edit_tags.tag_status_count": "{count, plural, one {# publicação} other {# publicações}}", - "account_list.hidden_notice": "Isto é apenas visível a ti. Para mostrar essa lista aos outros, vá a <link>{page} > {modal} > {field}</link>.", - "account_list.total": "{total, plural,one {#conta}other {#contas}}", + "account_list.hidden_notice": "Isto é visível somente para você. Para exibir para todos, vá a <link>{page} > {modal} > {field}</link>.", + "account_list.total": "{total, plural, one {# conta} other {# contas}}", "admin.dashboard.daily_retention": "Taxa de retenção de usuários por dia, após a inscrição", "admin.dashboard.monthly_retention": "Taxa de retenção de usuários por mês, após a inscrição", "admin.dashboard.retention.average": "Média", @@ -277,17 +278,17 @@ "alt_text_modal.change_thumbnail": "Alterar miniatura", "alt_text_modal.describe_for_people_with_hearing_impairments": "Descreva isto para pessoas com deficiências auditivas…", "alt_text_modal.describe_for_people_with_visual_impairments": "Descreva isto para pessoas com deficiências visuais…", - "alt_text_modal.done": "Feito", + "alt_text_modal.done": "Concluído", "announcement.announcement": "Anúncio", "annual_report.announcement.action_build": "Gerar meu Wrapstodon", - "annual_report.announcement.action_dismiss": "Não, obrigado/a", + "annual_report.announcement.action_dismiss": "Não, obrigado", "annual_report.announcement.action_view": "Ver meu Wrapstodon", "annual_report.announcement.description": "Descubra mais sobre seu engajamento no Mastodon ao longo do último ano.", "annual_report.announcement.title": "Chegou o Wrapstodon de {year}", "annual_report.nav_item.badge": "Novo", - "annual_report.shared_page.donate": "Doe", + "annual_report.shared_page.donate": "Doar", "annual_report.shared_page.footer": "Criado com {heart} pela equipe do Mastodon", - "annual_report.shared_page.footer_server_info": "{username} utiliza {domain}, uma das várias comunidades baseadas no Mastodon.", + "annual_report.shared_page.footer_server_info": "{username} usa {domain}, uma de muitas comunidades baseadas no Mastodon.", "annual_report.summary.archetype.booster.desc_public": "{name} se manteve na caça por publicações para impulsionar, amplificando outros criadores com uma mira perfeita.", "annual_report.summary.archetype.booster.desc_self": "Você se manteve na caça por publicações para impulsionar, amplificando outros criadores com uma mira perfeita.", "annual_report.summary.archetype.booster.name": "O Arqueiro", @@ -362,20 +363,19 @@ "closed_registrations_modal.preamble": "O Mastodon é descentralizado, não importa onde você criou a sua conta, será possível seguir e interagir com qualquer pessoa neste servidor. Você pode até mesmo criar o seu próprio servidor!", "closed_registrations_modal.title": "Inscrevendo-se no Mastodon", "collection.share_modal.share_link_label": "Compartilhar link", - "collection.share_modal.share_via_post": "Postar no Mastodon", + "collection.share_modal.share_via_post": "Publicar no Mastodon", "collection.share_modal.share_via_system": "Enviar para…", "collection.share_modal.title": "Compartilhar coleção", "collection.share_modal.title_new": "Compartilhe sua nova coleção!", - "collection.share_template_other": "Confira esta coleção incrível: {link}", - "collection.share_template_own": "Confira minha nova coleção: {link}", "collections.account_count": "{count, plural, one {# conta} other {# conta}}", "collections.accounts.empty_description": "Adicione até {count} contas", "collections.accounts.empty_editor_title": "Ainda não há ninguém nesta coleção", "collections.accounts.empty_title": "Esta coleção está vazia", + "collections.add_to_collection": "Adicionar {name} à coleção", "collections.block_collection_owner": "Bloquear conta", "collections.by_account": "por {account_handle}", "collections.collection_description": "Descrição", - "collections.collection_language": "Língua", + "collections.collection_language": "Idioma", "collections.collection_language_none": "Nenhum", "collections.collection_name": "Nome", "collections.collection_topic": "Tópico", @@ -388,17 +388,17 @@ "collections.create.basic_details_title": "Detalhes básicos", "collections.create.steps": "Passo {step}/{total}", "collections.create_collection": "Criar coleção", - "collections.delete_collection": "Eliminar coleção", + "collections.delete_collection": "Excluir coleção", "collections.description_length_hint": "Limite de 100 caracteres", "collections.detail.author_added_you_on_date": "{author} te adicionou em {date}", "collections.detail.loading": "Carregando coleção…", "collections.detail.revoke_inclusion": "Remover-me", "collections.detail.sensitive_content": "Conteúdo sensível", - "collections.detail.sensitive_note": "A descrição e as contas talvez possam não ser adequadas para todos.", + "collections.detail.sensitive_note": "A descrição e as contas podem não ser adequadas para todos os públicos.", "collections.detail.share": "Compartilhar esta coleção", "collections.detail.you_are_in_this_collection": "Você aparece nesta coleção", "collections.edit_details": "Editar detalhes", - "collections.error_loading_collections": "Houve um erro ao tentar carregar essas coleções.", + "collections.error_loading_collections": "Houve um erro ao tentar carregar estas coleções.", "collections.hidden_accounts_description": "Você bloqueou ou silencilou {count, plural, one{este usuário} other {estes usuários}}", "collections.hidden_accounts_link": "{count, plural, one {# conta oculta} other {# contas ocultas}}", "collections.hints.accounts_counter": "{count}/{max} contas", @@ -491,7 +491,7 @@ "compose.saved.body": "Publicação salva.", "compose_form.direct_message_warning_learn_more": "Saiba mais", "compose_form.encryption_warning": "As publicações no Mastodon não são criptografadas de ponta-a-ponta. Não compartilhe nenhuma informação sensível no Mastodon.", - "compose_form.hashtag_warning": "Esta publicação não será exibida sob nenhuma hashtag, já que não é pública. Apenas postagens públicas podem ser pesquisadas por meio de hashtags.", + "compose_form.hashtag_warning": "Esta publicação não será exibida sob nenhuma hashtag, já que não é pública. Apenas publicações públicas podem ser pesquisadas por meio de hashtags.", "compose_form.lock_disclaimer": "Seu perfil não está {locked}. Qualquer um pode te seguir e ver as suas publicações privadas.", "compose_form.lock_disclaimer.lock": "trancado", "compose_form.placeholder": "No que você está pensando?", @@ -513,9 +513,9 @@ "confirmations.delete.confirm": "Excluir", "confirmations.delete.message": "Você tem certeza de que deseja excluir esta publicação?", "confirmations.delete.title": "Excluir publicação?", - "confirmations.delete_collection.confirm": "Deletar", + "confirmations.delete_collection.confirm": "Excluir", "confirmations.delete_collection.message": "Esta ação não pode ser desfeita.", - "confirmations.delete_collection.title": "Deletar \"{name}\"?", + "confirmations.delete_collection.title": "Excluir \"{name}\"?", "confirmations.delete_list.confirm": "Excluir", "confirmations.delete_list.message": "Você tem certeza de que deseja excluir esta lista?", "confirmations.delete_list.title": "Excluir lista?", @@ -559,7 +559,7 @@ "confirmations.remove_from_followers.message": "{name} vai parar de te seguir. Tem certeza de que deseja continuar?", "confirmations.remove_from_followers.title": "Remover seguidor?", "confirmations.revoke_collection_inclusion.confirm": "Remover-me", - "confirmations.revoke_collection_inclusion.message": "Esta ação é permanente e o curador não poderá adicionar-lhe de volta à coleção mais tarde.", + "confirmations.revoke_collection_inclusion.message": "Esta ação é permanente e o curador não poderá lhe adicionar de volta à coleção mais tarde.", "confirmations.revoke_collection_inclusion.title": "Remover-se desta coleção?", "confirmations.revoke_quote.confirm": "Remover publicação", "confirmations.revoke_quote.message": "Esta ação não pode ser desfeita.", @@ -595,7 +595,7 @@ "domain_block_modal.block_account_instead": "Bloquear @{name} em vez disso", "domain_block_modal.they_can_interact_with_old_posts": "Pessoas deste servidor podem interagir com suas publicações antigas.", "domain_block_modal.they_cant_follow": "Ninguém deste servidor pode lhe seguir.", - "domain_block_modal.they_wont_know": "Eles não saberão que foram bloqueados.", + "domain_block_modal.they_wont_know": "O/A usuário/a não saberá que foi bloqueado/a.", "domain_block_modal.title": "Bloquear domínio?", "domain_block_modal.you_will_lose_num_followers": "Você perderá {followersCount, plural, one {{followersCountDisplay} seguidor} other {{followersCountDisplay} seguidores}} e {followingCount, plural, one {{followingCountDisplay} pessoa que você segue} other {{followingCountDisplay} pessoas que você segue}}.", "domain_block_modal.you_will_lose_relationships": "Você irá perder todos os seguidores e pessoas que você segue neste servidor.", diff --git a/app/javascript/mastodon/locales/pt-PT.json b/app/javascript/mastodon/locales/pt-PT.json index b74440dbb7..7ca9401f9a 100644 --- a/app/javascript/mastodon/locales/pt-PT.json +++ b/app/javascript/mastodon/locales/pt-PT.json @@ -345,8 +345,6 @@ "collection.share_modal.share_via_system": "Compartilhar com…", "collection.share_modal.title": "Partilhar coleção", "collection.share_modal.title_new": "Partilhe a sua nova coleção!", - "collection.share_template_other": "Veja esta coleção interessante: {link}", - "collection.share_template_own": "Veja a minha nova coleção: {link}", "collections.account_count": "{count, plural, one {# conta} other {# contas}}", "collections.accounts.empty_description": "Adicione até {count} contas", "collections.accounts.empty_editor_title": "Ainda não há ninguém nesta coleção", diff --git a/app/javascript/mastodon/locales/ru.json b/app/javascript/mastodon/locales/ru.json index dc57dc7d4d..edd0f8f617 100644 --- a/app/javascript/mastodon/locales/ru.json +++ b/app/javascript/mastodon/locales/ru.json @@ -342,8 +342,6 @@ "collection.share_modal.share_via_system": "Поделиться…", "collection.share_modal.title": "Поделиться подборкой", "collection.share_modal.title_new": "Поделитесь вашей новой подборкой!", - "collection.share_template_other": "Зацените эту замечательную подборку: {link}", - "collection.share_template_own": "Зацените мою новую подборку: {link}", "collections.account_count": "{count, plural, one {# пользователь} few {# пользователя} other {# пользователей}}", "collections.accounts.empty_description": "Вы можете добавить максимум {count} пользователей", "collections.accounts.empty_editor_title": "В этой подборке пока никого нет", diff --git a/app/javascript/mastodon/locales/sq.json b/app/javascript/mastodon/locales/sq.json index 2cbed2a77e..6e11e0e94e 100644 --- a/app/javascript/mastodon/locales/sq.json +++ b/app/javascript/mastodon/locales/sq.json @@ -86,6 +86,7 @@ "account.locked_info": "Gjendja e privatësisë së kësaj llogarie është caktuar si e kyçur. I zoti merr dorazi në shqyrtim cilët mund ta ndjekin.", "account.media": "Media", "account.mention": "Përmendni @{name}", + "account.menu.add_to_collection": "Shtoni në koleksion…", "account.menu.add_to_list": "Shtoni në listë…", "account.menu.block": "Bllokoje llogarinë", "account.menu.block_domain": "Bllokoje {domain}", @@ -361,12 +362,13 @@ "collection.share_modal.share_via_system": "Ndajeni me të tjerë në…", "collection.share_modal.title": "Ndani koleksionin me të tjerë", "collection.share_modal.title_new": "Ndani me të tjerë koleksionin tuaj të ri!", - "collection.share_template_other": "Shihni këtë koleksion të hijshëm: {link}", - "collection.share_template_own": "Shihni koleksionin tim të ri: {link}", + "collection.share_template_other": "Shihni këtë koleksion të hijshëm:", + "collection.share_template_own": "Shihni koleksionin tim të ri:", "collections.account_count": "{count, plural, one {# llogari} other {# llogari}}", "collections.accounts.empty_description": "Shtoni deri në {count} llogari", "collections.accounts.empty_editor_title": "Në këtë koleksion s’ka ende njeri", "collections.accounts.empty_title": "Ky koleksion është i zbrazët", + "collections.add_to_collection": "Shtoje {name} te koleksione", "collections.block_collection_owner": "Bllokoje llogarinë", "collections.by_account": "nga {account_handle}", "collections.collection_description": "Përshkrim", diff --git a/app/javascript/mastodon/locales/sv.json b/app/javascript/mastodon/locales/sv.json index 8e4b006dbe..10a037a9c6 100644 --- a/app/javascript/mastodon/locales/sv.json +++ b/app/javascript/mastodon/locales/sv.json @@ -366,8 +366,6 @@ "collection.share_modal.share_via_system": "Dela med…", "collection.share_modal.title": "Dela samling", "collection.share_modal.title_new": "Dela din nya samling!", - "collection.share_template_other": "Kolla in denna coola samling: {link}", - "collection.share_template_own": "Kolla in min nya samling: {link}", "collections.account_count": "{count, plural, one {# konto} other {# konton}}", "collections.accounts.empty_description": "Lägg till upp till {count} konton", "collections.accounts.empty_editor_title": "Ingen finns i denna samling ännu", diff --git a/app/javascript/mastodon/locales/tr.json b/app/javascript/mastodon/locales/tr.json index 432df8f9b0..e7930a84f9 100644 --- a/app/javascript/mastodon/locales/tr.json +++ b/app/javascript/mastodon/locales/tr.json @@ -86,6 +86,7 @@ "account.locked_info": "Bu hesabın gizlilik durumu gizli olarak ayarlanmış. Sahibi, onu kimin takip edebileceğini elle onaylıyor.", "account.media": "Medya", "account.mention": "@{name} kişisinden bahset", + "account.menu.add_to_collection": "Koleksiyona ekle…", "account.menu.add_to_list": "Listeye ekle…", "account.menu.block": "Hesabı engelle", "account.menu.block_domain": "{domain} alan adını engelle", @@ -366,12 +367,11 @@ "collection.share_modal.share_via_system": "Paylaş…", "collection.share_modal.title": "Koleksiyonu paylaş", "collection.share_modal.title_new": "Yeni koleksiyonunuzu paylaşın!", - "collection.share_template_other": "Bu harika koleksiyona göz atın: {link}", - "collection.share_template_own": "Yeni koleksiyonuma göz atın: {link}", "collections.account_count": "{count, plural, one {# hesap} other {# hesap}}", "collections.accounts.empty_description": "{count} hesap ekleyebilirsiniz", "collections.accounts.empty_editor_title": "Koleksiyonda henüz kimse yok", "collections.accounts.empty_title": "Bu koleksiyon boş", + "collections.add_to_collection": "{name} kişisini koleksiyonlara ekle", "collections.block_collection_owner": "Hesabı engelle", "collections.by_account": "Hazırlayan: {account_handle}", "collections.collection_description": "Açıklama", diff --git a/app/javascript/mastodon/locales/vi.json b/app/javascript/mastodon/locales/vi.json index d7494ea5a7..5dccafb2af 100644 --- a/app/javascript/mastodon/locales/vi.json +++ b/app/javascript/mastodon/locales/vi.json @@ -86,6 +86,7 @@ "account.locked_info": "Đây là tài khoản riêng tư. Chủ tài khoản tự mình xét duyệt các yêu cầu theo dõi.", "account.media": "Phương tiện", "account.mention": "Nhắc đến @{name}", + "account.menu.add_to_collection": "Thêm vào gói khởi đầu…", "account.menu.add_to_list": "Thêm vào danh sách", "account.menu.block": "Chặn tài khoản", "account.menu.block_domain": "Chặn {domain}", @@ -366,12 +367,13 @@ "collection.share_modal.share_via_system": "Chia sẻ qua…", "collection.share_modal.title": "Chia sẻ gói khởi đầu", "collection.share_modal.title_new": "Chia sẻ gói khởi đầu mới của bạn!", - "collection.share_template_other": "Xem ngay gói khởi đầu tuyệt vời này: {link}", - "collection.share_template_own": "Xem ngay gói khởi đầu mới của tôi: {link}", + "collection.share_template_other": "Xem ngay gói khởi đầu tuyệt vời này:", + "collection.share_template_own": "Xem ngay gói khởi đầu mới của tôi:", "collections.account_count": "{count, plural, other {# tài khoản}}", "collections.accounts.empty_description": "Thêm tối đa {count} tài khoản", "collections.accounts.empty_editor_title": "Chưa có ai trong gói khởi đầu này", "collections.accounts.empty_title": "Gói khởi đầu này trống", + "collections.add_to_collection": "Thêm {name} vào gói khởi đầu", "collections.block_collection_owner": "Chặn tài khoản", "collections.by_account": "bởi {account_handle}", "collections.collection_description": "Mô tả", diff --git a/app/javascript/mastodon/locales/zh-CN.json b/app/javascript/mastodon/locales/zh-CN.json index 1162db4e94..03237b2cbe 100644 --- a/app/javascript/mastodon/locales/zh-CN.json +++ b/app/javascript/mastodon/locales/zh-CN.json @@ -86,6 +86,7 @@ "account.locked_info": "此账号已锁嘟。账号所有人会手动审核新关注者。", "account.media": "媒体", "account.mention": "提及 @{name}", + "account.menu.add_to_collection": "加入收藏列表…", "account.menu.add_to_list": "添加到列表…", "account.menu.block": "屏蔽账号", "account.menu.block_domain": "屏蔽 {domain}", @@ -366,12 +367,13 @@ "collection.share_modal.share_via_system": "分享到…", "collection.share_modal.title": "分享收藏列表", "collection.share_modal.title_new": "分享你的新收藏列表!", - "collection.share_template_other": "发现了个收藏列表,来看看:{link}", - "collection.share_template_own": "我的新收藏列表,来看看:{link}", + "collection.share_template_other": "发现了个收藏列表,来看看:", + "collection.share_template_own": "我的新收藏列表,来看看:", "collections.account_count": "{count, plural, other {# 个账号}}", "collections.accounts.empty_description": "添加最多 {count} 个账号", "collections.accounts.empty_editor_title": "此收藏列表中暂无用户", "collections.accounts.empty_title": "收藏列表为空", + "collections.add_to_collection": "将 {name} 添加到收藏列表", "collections.block_collection_owner": "屏蔽账号", "collections.by_account": "由 {account_handle}", "collections.collection_description": "说明", diff --git a/app/javascript/mastodon/locales/zh-TW.json b/app/javascript/mastodon/locales/zh-TW.json index c4e5fd849d..8295c69991 100644 --- a/app/javascript/mastodon/locales/zh-TW.json +++ b/app/javascript/mastodon/locales/zh-TW.json @@ -86,6 +86,7 @@ "account.locked_info": "此帳號的隱私狀態被設為鎖定。該擁有者會手動審核能跟隨此帳號的人。", "account.media": "媒體", "account.mention": "提及 @{name}", + "account.menu.add_to_collection": "加入至收藏名單...", "account.menu.add_to_list": "新增至列表...", "account.menu.block": "封鎖帳號", "account.menu.block_domain": "封鎖 {domain}", @@ -366,12 +367,13 @@ "collection.share_modal.share_via_system": "分享至...", "collection.share_modal.title": "分享收藏名單", "collection.share_modal.title_new": "分享您的新收藏名單!", - "collection.share_template_other": "來看看這個酷酷的收藏名單:{link}", - "collection.share_template_own": "來看看我的新收藏名單:{link}", + "collection.share_template_other": "來看看這個酷酷的收藏名單:", + "collection.share_template_own": "來看看我的新收藏名單:", "collections.account_count": "{count, plural, other {# 個帳號}}", "collections.accounts.empty_description": "加入最多 {count} 個帳號", "collections.accounts.empty_editor_title": "此收藏名單尚未有任何人", "collections.accounts.empty_title": "此收藏名單是空的", + "collections.add_to_collection": "將 {name} 加入至收藏名單", "collections.block_collection_owner": "封鎖帳號", "collections.by_account": "來自 {account_handle}", "collections.collection_description": "說明", diff --git a/app/javascript/mastodon/models/server.ts b/app/javascript/mastodon/models/server.ts new file mode 100644 index 0000000000..0a01a56962 --- /dev/null +++ b/app/javascript/mastodon/models/server.ts @@ -0,0 +1,21 @@ +import type { + ApiInstanceJSON, + ApiExtendedDescriptionJSON, + ApiDomainBlockJSON, +} from 'mastodon/api_types/instance'; + +export type Server = ApiInstanceJSON; + +export const createServerFromServerJSON = (obj: ApiInstanceJSON): Server => obj; + +export type ExtendedDescription = ApiExtendedDescriptionJSON; + +export const createExtendedDescriptionFromServerJSON = ( + obj: ApiExtendedDescriptionJSON, +): ExtendedDescription => obj; + +export type DomainBlock = ApiDomainBlockJSON; + +export const createDomainBlockFromServerJSON = ( + obj: ApiDomainBlockJSON, +): DomainBlock => obj; diff --git a/app/javascript/mastodon/reducers/index.ts b/app/javascript/mastodon/reducers/index.ts index c3bc5792ac..2d2c8fbab5 100644 --- a/app/javascript/mastodon/reducers/index.ts +++ b/app/javascript/mastodon/reducers/index.ts @@ -30,7 +30,7 @@ import { pollsReducer } from './polls'; import push_notifications from './push_notifications'; import { relationshipsReducer } from './relationships'; import { searchReducer } from './search'; -import server from './server'; +import { serverReducer } from './server'; import settings from './settings'; import { sliceReducers } from './slices'; import status_lists from './status_lists'; @@ -58,7 +58,7 @@ const reducers = { relationships: relationshipsReducer, settings, push_notifications, - server, + server: serverReducer, contexts: contextsReducer, compose: composeReducer, search: searchReducer, diff --git a/app/javascript/mastodon/reducers/server.js b/app/javascript/mastodon/reducers/server.js deleted file mode 100644 index 2bbf0f9a30..0000000000 --- a/app/javascript/mastodon/reducers/server.js +++ /dev/null @@ -1,63 +0,0 @@ -import { Map as ImmutableMap, List as ImmutableList, fromJS } from 'immutable'; - -import { - SERVER_FETCH_REQUEST, - SERVER_FETCH_SUCCESS, - SERVER_FETCH_FAIL, - SERVER_TRANSLATION_LANGUAGES_FETCH_REQUEST, - SERVER_TRANSLATION_LANGUAGES_FETCH_SUCCESS, - SERVER_TRANSLATION_LANGUAGES_FETCH_FAIL, - EXTENDED_DESCRIPTION_REQUEST, - EXTENDED_DESCRIPTION_SUCCESS, - EXTENDED_DESCRIPTION_FAIL, - SERVER_DOMAIN_BLOCKS_FETCH_REQUEST, - SERVER_DOMAIN_BLOCKS_FETCH_SUCCESS, - SERVER_DOMAIN_BLOCKS_FETCH_FAIL, -} from 'mastodon/actions/server'; - -const initialState = ImmutableMap({ - server: ImmutableMap({ - isLoading: false, - }), - - extendedDescription: ImmutableMap({ - isLoading: false, - }), - - domainBlocks: ImmutableMap({ - isLoading: false, - isAvailable: true, - items: ImmutableList(), - }), -}); - -export default function server(state = initialState, action) { - switch (action.type) { - case SERVER_FETCH_REQUEST: - return state.setIn(['server', 'isLoading'], true); - case SERVER_FETCH_SUCCESS: - return state.set('server', fromJS(action.server)).setIn(['server', 'isLoading'], false); - case SERVER_FETCH_FAIL: - return state.setIn(['server', 'isLoading'], false); - case SERVER_TRANSLATION_LANGUAGES_FETCH_REQUEST: - return state.setIn(['translationLanguages', 'isLoading'], true); - case SERVER_TRANSLATION_LANGUAGES_FETCH_SUCCESS: - return state.setIn(['translationLanguages', 'items'], fromJS(action.translationLanguages)).setIn(['translationLanguages', 'isLoading'], false); - case SERVER_TRANSLATION_LANGUAGES_FETCH_FAIL: - return state.setIn(['translationLanguages', 'isLoading'], false); - case EXTENDED_DESCRIPTION_REQUEST: - return state.setIn(['extendedDescription', 'isLoading'], true); - case EXTENDED_DESCRIPTION_SUCCESS: - return state.set('extendedDescription', fromJS(action.description)).setIn(['extendedDescription', 'isLoading'], false); - case EXTENDED_DESCRIPTION_FAIL: - return state.setIn(['extendedDescription', 'isLoading'], false); - case SERVER_DOMAIN_BLOCKS_FETCH_REQUEST: - return state.setIn(['domainBlocks', 'isLoading'], true); - case SERVER_DOMAIN_BLOCKS_FETCH_SUCCESS: - return state.setIn(['domainBlocks', 'items'], fromJS(action.blocks)).setIn(['domainBlocks', 'isLoading'], false).setIn(['domainBlocks', 'isAvailable'], action.isAvailable); - case SERVER_DOMAIN_BLOCKS_FETCH_FAIL: - return state.setIn(['domainBlocks', 'isLoading'], false); - default: - return state; - } -} diff --git a/app/javascript/mastodon/reducers/server.ts b/app/javascript/mastodon/reducers/server.ts new file mode 100644 index 0000000000..92cec39af0 --- /dev/null +++ b/app/javascript/mastodon/reducers/server.ts @@ -0,0 +1,127 @@ +import { createReducer } from '@reduxjs/toolkit'; + +import { + fetchServer, + fetchServerTranslationLanguages, + fetchExtendedDescription, + fetchDomainBlocks, +} from 'mastodon/actions/server'; +import type { + Server, + ExtendedDescription, + DomainBlock, +} from 'mastodon/models/server'; +import { + createServerFromServerJSON, + createExtendedDescriptionFromServerJSON, + createDomainBlockFromServerJSON, +} from 'mastodon/models/server'; + +interface State { + server: { + isLoading: boolean; + item?: Server; + }; + + extendedDescription: { + isLoading: boolean; + item?: ExtendedDescription; + }; + + translationLanguages: { + isLoading: boolean; + item?: Record<string, string[]>; + }; + + domainBlocks: { + isLoading: boolean; + isAvailable: boolean; + items: DomainBlock[]; + }; +} + +const initialState: State = { + server: { + isLoading: false, + item: undefined, + }, + + extendedDescription: { + isLoading: false, + item: undefined, + }, + + translationLanguages: { + isLoading: false, + item: undefined, + }, + + domainBlocks: { + isLoading: false, + isAvailable: true, + items: [], + }, +}; + +export const serverReducer = createReducer(initialState, (builder) => { + builder.addCase(fetchServer.pending, (state) => { + state.server.isLoading = true; + }); + + builder.addCase(fetchServer.fulfilled, (state, action) => { + state.server.item = createServerFromServerJSON(action.payload); + state.server.isLoading = false; + }); + + builder.addCase(fetchServer.rejected, (state) => { + state.server.isLoading = false; + }); + + builder.addCase(fetchExtendedDescription.pending, (state) => { + state.extendedDescription.isLoading = true; + }); + + builder.addCase(fetchExtendedDescription.fulfilled, (state, action) => { + state.extendedDescription.item = createExtendedDescriptionFromServerJSON( + action.payload, + ); + state.extendedDescription.isLoading = false; + }); + + builder.addCase(fetchExtendedDescription.rejected, (state) => { + state.extendedDescription.isLoading = false; + }); + + builder.addCase(fetchServerTranslationLanguages.pending, (state) => { + state.translationLanguages.isLoading = true; + }); + + builder.addCase( + fetchServerTranslationLanguages.fulfilled, + (state, action) => { + state.translationLanguages.item = action.payload; + state.translationLanguages.isLoading = false; + }, + ); + + builder.addCase(fetchServerTranslationLanguages.rejected, (state) => { + state.translationLanguages.isLoading = false; + }); + + builder.addCase(fetchDomainBlocks.pending, (state) => { + state.domainBlocks.isLoading = true; + }); + + builder.addCase(fetchDomainBlocks.fulfilled, (state, action) => { + state.domainBlocks.items = action.payload.map((obj) => + createDomainBlockFromServerJSON(obj), + ); + state.domainBlocks.isLoading = false; + state.domainBlocks.isAvailable = true; + }); + + builder.addCase(fetchDomainBlocks.rejected, (state) => { + state.domainBlocks.isLoading = false; + state.domainBlocks.isAvailable = false; + }); +}); diff --git a/app/javascript/mastodon/reducers/slices/profile_edit.ts b/app/javascript/mastodon/reducers/slices/profile_edit.ts index 2437352fbd..bc463ac1bd 100644 --- a/app/javascript/mastodon/reducers/slices/profile_edit.ts +++ b/app/javascript/mastodon/reducers/slices/profile_edit.ts @@ -282,12 +282,8 @@ export const updateField = createAppAsyncThunk( throw new Error('Profile fields not found'); } - const maxFields = getState().server.getIn([ - 'server', - 'configuration', - 'accounts', - 'max_fields', - ]) as number | undefined; + const maxFields = + getState().server.server.item?.configuration.accounts.max_profile_fields; if (maxFields && fields.length >= maxFields && !arg.id) { throw new Error('Maximum number of profile fields reached'); } diff --git a/app/javascript/styles/mastodon/_mixins.scss b/app/javascript/styles/mastodon/_mixins.scss index c92c8d8cee..afc52329f2 100644 --- a/app/javascript/styles/mastodon/_mixins.scss +++ b/app/javascript/styles/mastodon/_mixins.scss @@ -1,5 +1,4 @@ @mixin search-input { - outline: 0; box-sizing: border-box; width: 100%; box-shadow: none; @@ -11,6 +10,10 @@ font-size: 17px; line-height: normal; margin: 0; + outline: var(--outline-focus-default); + outline-color: transparent; + outline-offset: -1px; + transition: outline-color 0.15s ease-out; } @mixin search-popout { diff --git a/app/javascript/styles/mastodon/admin.scss b/app/javascript/styles/mastodon/admin.scss index fc730d0c22..1ed02feb66 100644 --- a/app/javascript/styles/mastodon/admin.scss +++ b/app/javascript/styles/mastodon/admin.scss @@ -136,6 +136,11 @@ $content-width: 840px; transition: all 100ms linear; transition-property: color, background-color; } + + &:focus-visible { + outline: var(--outline-focus-default); + outline-offset: -2px; + } } ul { @@ -1903,6 +1908,28 @@ a.sparkline { } } +.navigation-skip-link { + position: fixed; + z-index: 100; + margin: 10px; + padding: 10px 16px; + border-radius: 10px; + font-size: 15px; + color: var(--color-text-primary); + background: var(--color-bg-primary); + box-shadow: var(--dropdown-shadow); + + /* Hide visually when not focused */ + &:not(:focus-within) { + width: 1px; + height: 1px; + margin: 0; + padding: 0; + clip-path: inset(50%); + overflow: hidden; + } +} + .section-skip-link { float: right; diff --git a/app/javascript/styles/mastodon/components.scss b/app/javascript/styles/mastodon/components.scss index 6ff8e73b9c..25265433fa 100644 --- a/app/javascript/styles/mastodon/components.scss +++ b/app/javascript/styles/mastodon/components.scss @@ -541,13 +541,15 @@ body > [data-popper-placement] { flex: 0 1 auto; border-radius: 4px; border: 1px solid var(--color-border-primary); - transition: border-color 300ms linear; position: relative; background: var(--color-bg-secondary); + outline: var(--outline-focus-default); + outline-color: transparent; + outline-offset: -1px; + transition: outline-color 0.15s ease-out; - &.active { - transition: none; - border-color: var(--color-border-brand); + &:has(textarea:focus) { + outline-color: var(--color-border-brand); } } @@ -595,8 +597,15 @@ body > [data-popper-placement] { .autosuggest-input { flex: 1 1 auto; - border: 1px solid var(--color-border-primary); - border-width: 1px 0; + border-block: 1px solid var(--color-border-primary); + padding-block: 1px; + transition: border-color 0.15s ease-out; + + &:focus-within { + padding-block: 0; + border-color: var(--color-border-brand); + border-block-width: 2px; + } } } @@ -621,7 +630,7 @@ body > [data-popper-placement] { } .spoiler-input__input { - padding: 12px 12px - 5px; + padding: 11px 7px; background: var(--color-bg-brand-softest); color: var(--color-text-brand); } @@ -2741,6 +2750,7 @@ a.account__display-name { font-size: 14px; line-height: 20px; font-weight: 500; + outline-offset: 0; .display-name__account { font-size: 14px; @@ -3655,7 +3665,11 @@ a.account__display-name { .compose-panel { width: 285px; - margin-top: 10px; + margin-top: 8px; + + // Padding prevents focus outlines from being cut off + margin-inline-start: -2px; + padding: 2px; display: flex; flex-direction: column; height: calc(100% - 10px); @@ -3750,16 +3764,6 @@ a.account__display-name { margin-bottom: 12px; } - .getting-started__trends h4 { - padding: 10px 12px; - padding-inline-start: 16px; - } - - .getting-started__trends .trends__item { - padding: 10px 12px; - padding-inline-start: 16px; - } - @media screen and (height <= 930px) { &__portal .trends__item:nth-child(n + 5) { display: none; @@ -3787,7 +3791,8 @@ a.account__display-name { .navigation-panel, .compose-panel { - hr { + hr, + li[role='separator'] { flex: 0 0 auto; border: 0; background: transparent; @@ -4125,25 +4130,30 @@ a.account__display-name { border: 1px solid var(--color-border-primary); border-top: 0; + &__trends-heading { + border-bottom: 1px solid var(--color-border-primary); + padding: 10px; + font-size: 12px; + text-transform: uppercase; + font-weight: 500; + + .navigation-panel & { + padding: 10px 12px; + padding-inline-start: 16px; + } + + a { + color: var(--color-text-secondary); + text-decoration: none; + } + } + &__trends { flex: 0 1 auto; opacity: 1; animation: fade 150ms linear; margin-top: 10px; - h4 { - border-bottom: 1px solid var(--color-border-primary); - padding: 10px; - font-size: 12px; - text-transform: uppercase; - font-weight: 500; - - a { - color: var(--color-text-secondary); - text-decoration: none; - } - } - .trends__item { border-bottom: 0; padding: 10px; @@ -4151,6 +4161,11 @@ a.account__display-name { &__current { color: var(--color-text-secondary); } + + .navigation-panel & { + padding: 10px 12px; + padding-inline-start: 16px; + } } } } @@ -5827,7 +5842,7 @@ a.status-card { display: none; position: absolute; inset-inline-start: 0; - margin-top: -2px; + margin-top: 1px; width: 100%; background: var(--color-bg-primary); border: 1px solid var(--color-border-primary); @@ -5922,14 +5937,8 @@ a.status-card { } } - &.active { - .search__input { - border-radius: 4px 4px 0 0; - } - - .search__popout { - display: block; - } + &.active .search__popout { + display: block; } } @@ -5941,14 +5950,8 @@ a.status-card { padding-inline-start: 16px + 15px + 8px; line-height: normal; - &::-moz-focus-inner { - border: 0; - } - - &::-moz-focus-inner, - &:focus, - &:active { - outline: 0 !important; + &:focus { + outline-color: var(--color-border-brand); } } @@ -9216,6 +9219,10 @@ noscript { display: flex; align-items: center; + &:has(input:focus) { + outline-color: var(--color-border-brand); + } + input { background: transparent; color: inherit; @@ -9244,7 +9251,7 @@ noscript { } .search__popout { - margin-top: -1px; + margin-top: 1px; padding-top: 5px; padding-bottom: 5px; border: 1px solid var(--color-border-primary); @@ -9257,10 +9264,6 @@ noscript { &.expanded .search__popout { display: block; } - - &.expanded &__input { - border-radius: 4px 4px 0 0; - } } &__choices { @@ -9635,41 +9638,6 @@ noscript { } } -.link-footer { - flex: 0 0 auto; - padding-top: 20px; - z-index: 1; - font-size: 13px; - - .column & { - padding: 15px; - } - - p { - color: var(--color-text-secondary); - margin-bottom: 20px; - - .version { - white-space: nowrap; - } - - strong { - font-weight: 500; - } - - a { - color: var(--color-text-secondary); - text-decoration: underline; - - &:hover, - &:focus, - &:active { - text-decoration: none; - } - } - } -} - .about { padding: 20px; border-top: 1px solid var(--color-border-primary); @@ -9806,18 +9774,6 @@ noscript { } } - .link-footer { - padding: 0; - margin-top: 60px; - text-align: center; - font-size: 15px; - line-height: 22px; - - @media screen and (min-width: $no-gap-breakpoint) { - display: none; - } - } - .account { padding: 0; border: 0; @@ -10121,18 +10077,18 @@ noscript { background: var(--color-bg-brand-softest); } + &__title { + font-size: 15px; + line-height: 22px; + font-weight: 500; + } + &__header { display: flex; align-items: center; justify-content: space-between; padding: 0 16px; - h3 { - font-size: 15px; - line-height: 22px; - font-weight: 500; - } - &__actions { display: flex; align-items: center; diff --git a/app/javascript/styles/mastodon/emoji_picker.scss b/app/javascript/styles/mastodon/emoji_picker.scss index 2d1e03d7b9..baf9995342 100644 --- a/app/javascript/styles/mastodon/emoji_picker.scss +++ b/app/javascript/styles/mastodon/emoji_picker.scss @@ -114,10 +114,9 @@ border: 0; } - &:active, &:focus { - outline: none !important; - border-width: 1px !important; + outline: var(--outline-focus-default); + outline-offset: -1px; } &::-webkit-search-cancel-button { @@ -141,10 +140,12 @@ &:disabled { cursor: default; pointer-events: none; + color: var(--color-text-secondary); } svg { fill: currentColor; + opacity: 1 !important; } } diff --git a/app/models/collection.rb b/app/models/collection.rb index 547079e11d..ac76331659 100644 --- a/app/models/collection.rb +++ b/app/models/collection.rb @@ -5,7 +5,6 @@ # Table name: collections # # id :bigint(8) not null, primary key -# deleted_at :datetime # description :text # description_html :text # discoverable :boolean not null @@ -32,7 +31,6 @@ class Collection < ApplicationRecord has_many :collection_items, dependent: :delete_all has_many :accepted_collection_items, -> { accepted }, class_name: 'CollectionItem', inverse_of: :collection # rubocop:disable Rails/HasManyOrHasOneDependent - has_many :top_items, -> { top_items }, class_name: 'CollectionItem', inverse_of: :collection # rubocop:disable Rails/HasManyOrHasOneDependent has_many :collection_reports, dependent: :delete_all validates :name, presence: true @@ -66,11 +64,15 @@ class Collection < ApplicationRecord !local? end - def items_for(account = nil) - result = collection_items.with_accounts - result = account == self.account ? result.pending_or_accepted : result.accepted - result = result.not_blocked_by(account) unless account.nil? - result + def items_for(account = nil, include_accounts: false) + @items_for ||= {} + @items_for[account] ||= begin + result = collection_items + result = result.with_accounts if include_accounts + result = account == self.account ? result.pending_or_accepted : result.accepted + result = result.not_blocked_by(account) unless account.nil? + result + end end def tag_name diff --git a/app/models/collection_item.rb b/app/models/collection_item.rb index 7ecb28ddb8..f37e67e8fd 100644 --- a/app/models/collection_item.rb +++ b/app/models/collection_item.rb @@ -43,19 +43,10 @@ class CollectionItem < ApplicationRecord scope :ordered, -> { order(position: :asc) } scope :with_accounts, -> { includes(account: [:account_stat, :user]) } - scope :not_blocked_by, ->(account) { where.not(accounts: { id: account.blocking }) } + scope :not_blocked_by, ->(account) { joins(:account).where.not(accounts: { id: account.blocking }) } scope :local, -> { joins(:collection).merge(Collection.local) } scope :accepted_partial, ->(account) { joins(:account).merge(Account.local).accepted.where(uri: nil, account_id: account.id) } scope :pending_or_accepted, -> { where(state: [:pending, :accepted]) } - scope :top_items, lambda { |limit = 4| - subquery = where('collection_items.collection_id = collections.id') - .accepted.ordered.limit(limit) - .arel.lateral('top_items') - collection_query = Collection - .select('top_items.*') - .from([Collection.arel_table, subquery]) - from(collection_query, 'collection_items') - } def with_local_account? account&.local? diff --git a/app/models/media_attachment.rb b/app/models/media_attachment.rb index 8c7be03856..025b0ed514 100644 --- a/app/models/media_attachment.rb +++ b/app/models/media_attachment.rb @@ -205,7 +205,7 @@ class MediaAttachment < ApplicationRecord remotable_attachment :thumbnail, IMAGE_LIMIT, suppress_errors: true, download_on_assign: false validates :account, presence: true - validates :description, length: { maximum: MAX_DESCRIPTION_LENGTH } + validates :description, length: { maximum: MAX_DESCRIPTION_LENGTH }, if: :local? validates :file, presence: true, if: :local? validates :thumbnail, absence: true, if: -> { local? && !audio_or_video? } diff --git a/app/presenters/collections_presenter.rb b/app/presenters/collections_presenter.rb deleted file mode 100644 index e97d872769..0000000000 --- a/app/presenters/collections_presenter.rb +++ /dev/null @@ -1,11 +0,0 @@ -# frozen_string_literal: true - -class CollectionsPresenter < ActiveModelSerializers::Model - attributes :collections - - def accounts - owners = collections.map(&:account) - top_accounts = collections.flat_map { |c| c.top_items.map(&:account) } - (owners + top_accounts).uniq - end -end diff --git a/app/serializers/rest/collection_with_accounts_serializer.rb b/app/serializers/rest/collection_with_accounts_serializer.rb index be0b955022..ea7602776b 100644 --- a/app/serializers/rest/collection_with_accounts_serializer.rb +++ b/app/serializers/rest/collection_with_accounts_serializer.rb @@ -10,6 +10,6 @@ class REST::CollectionWithAccountsSerializer < ActiveModel::Serializer end def accounts - [object.account] + object.collection_items.filter_map(&:account) + [object.account] + object.items_for(current_user&.account, include_accounts: true).map(&:account) end end diff --git a/app/serializers/rest/collections_with_account_previews_serializer.rb b/app/serializers/rest/collections_with_account_previews_serializer.rb deleted file mode 100644 index 95216ea649..0000000000 --- a/app/serializers/rest/collections_with_account_previews_serializer.rb +++ /dev/null @@ -1,10 +0,0 @@ -# frozen_string_literal: true - -class REST::CollectionsWithAccountPreviewsSerializer < ActiveModel::Serializer - has_many :collections, serializer: REST::CollectionSerializer - has_many :partial_accounts, serializer: REST::PartialAccountSerializer - - def partial_accounts - object.accounts - end -end diff --git a/app/views/layouts/admin.html.haml b/app/views/layouts/admin.html.haml index 0fc4eadd02..3fb98e5151 100644 --- a/app/views/layouts/admin.html.haml +++ b/app/views/layouts/admin.html.haml @@ -6,8 +6,9 @@ - content_for :body_classes, 'admin' - content_for :content do + %a.navigation-skip-link{ href: '#content' }= t('admin.skip_to_content') .admin-wrapper - .sidebar-wrapper + %nav.sidebar-wrapper .sidebar-wrapper__inner .sidebar = link_to root_path do @@ -24,7 +25,7 @@ = render_navigation - .content-wrapper + %main.content-wrapper#content .content .content__heading - if content_for?(:heading) diff --git a/app/views/settings/preferences/appearance/show.html.haml b/app/views/settings/preferences/appearance/show.html.haml index 6439fd666c..b85a393376 100644 --- a/app/views/settings/preferences/appearance/show.html.haml +++ b/app/views/settings/preferences/appearance/show.html.haml @@ -41,17 +41,16 @@ label_method: ->(contrast) { I18n.t("contrast.#{contrast}", default: contrast) }, wrapper: :with_label, required: false - - .fields-group - = f.simple_fields_for :settings, current_user.settings do |ff| - = ff.input :'web.emoji_style', - collection: user_settings_collection('web.emoji_style'), - include_blank: false, - hint: I18n.t('simple_form.hints.defaults.setting_emoji_style'), - label: I18n.t('simple_form.labels.defaults.setting_emoji_style'), - label_method: ->(emoji_style) { I18n.t("emoji_styles.#{emoji_style}", default: emoji_style) }, - wrapper: :with_label, - required: false + .input.horizontal-options + = ff.input :'web.emoji_style', + as: :radio_buttons, + collection: user_settings_collection('web.emoji_style'), + include_blank: false, + hint: I18n.t('simple_form.hints.defaults.setting_emoji_style'), + label: I18n.t('simple_form.labels.defaults.setting_emoji_style'), + label_method: ->(emoji_style) { I18n.t("emoji_styles.#{emoji_style}", default: emoji_style) }, + wrapper: :with_label, + required: false - unless I18n.locale == :en .flash-message.translation-prompt diff --git a/config/locales/activerecord.pt-BR.yml b/config/locales/activerecord.pt-BR.yml index 7d4223725a..391856fc6f 100644 --- a/config/locales/activerecord.pt-BR.yml +++ b/config/locales/activerecord.pt-BR.yml @@ -45,7 +45,7 @@ pt-BR: import: attributes: data: - malformed: está malformado + malformed: está mal formado list_account: attributes: account_id: @@ -67,17 +67,17 @@ pt-BR: blocked: usa provedor de e-mail não permitido unreachable: parece não existir role_id: - elevated: não pode ser maior que a sua função atual + elevated: não pode ser maior que seu cargo atual user_role: attributes: permissions_as_keys: - dangerous: incluir permissões que não são seguras para a função base - elevated: não pode incluir permissões que a sua função atual não possui - own_role: não pode ser alterado com sua função atual + dangerous: incluir permissões que não são seguras para o cargo base + elevated: não pode incluir permissões que o seu cargo atual não possui + own_role: não pode ser alterado com seu cargo atual position: - elevated: não pode ser maior do que sua função atual - own_role: não pode ser alterado com sua função atual + elevated: não pode ser maior do que seu cargo atual + own_role: não pode ser alterado com seu cargo atual webhook: attributes: events: - invalid_permissions: não pode incluir eventos que você não tem permissão para + invalid_permissions: não pode incluir eventos para os quais você não tem permissão diff --git a/config/locales/be.yml b/config/locales/be.yml index d61b89e5b9..244857c6dd 100644 --- a/config/locales/be.yml +++ b/config/locales/be.yml @@ -357,6 +357,7 @@ be: back_to_report: Назад да старонкі скаргі batch: add_to_report: 'Дадаць да скаргі #%{id}' + remove_from_report: Выдаліць са справаздачы report: Скарга collection_title: Калекцыя %{name} contents: Змесціва @@ -1010,6 +1011,7 @@ be: site_uploads: delete: Выдаліць запампаваны файл destroyed_msg: Загрузка сайту паспяхова выдалена! + skip_to_content: Перайсці да змесціва software_updates: critical_update: Крытычна - зрабіце абнаўленне як мага хутчэй description: Рэкамендуецца падтрымліваць усталёўку Mastodon у актуальным стане, каб карыстацца апошнімі выпраўленнямі і магчымасцямі. Акрамя таго, часам вельмі важна своечасова абнаўляць Mastodon, каб пазбегнуць праблем з бяспекай. Па гэтых прычынах Mastodon правярае наяўнасць абнаўленняў кожныя 30 хвілін і паведамляе вам пра гэта ў адпаведнасці з вашымі наладамі апавяшчэнняў па электроннай пошце. diff --git a/config/locales/da.yml b/config/locales/da.yml index fe4cc0bba0..8bbc546ad6 100644 --- a/config/locales/da.yml +++ b/config/locales/da.yml @@ -979,6 +979,7 @@ da: site_uploads: delete: Slet uploadet fil destroyed_msg: Websteds-upload blev slettet! + skip_to_content: Gå til indhold software_updates: critical_update: Kritisk – opdatér hurtigst muligt description: Det anbefales at holde din Mastodon-installation opdateret for at drage fordel af de nyeste fejlrettelser og funktioner. Desuden er det nogle gange afgørende at opdatere Mastodon rettidigt for at undgå sikkerhedsproblemer. Af disse grunde tjekker Mastodon for opdateringer hvert 30. minut og giver dig besked i henhold til dine præferencer for e-mail-notifikationer. diff --git a/config/locales/de.yml b/config/locales/de.yml index f9346bfa79..4d20c15528 100644 --- a/config/locales/de.yml +++ b/config/locales/de.yml @@ -979,6 +979,7 @@ de: site_uploads: delete: Hochgeladene Datei löschen destroyed_msg: Upload erfolgreich gelöscht! + skip_to_content: Zum Inhalt wechseln software_updates: critical_update: Kritisch — bitte zügig aktualisieren description: Es wird empfohlen, deine Mastodon-Installation auf dem aktuellen Stand zu halten, um von den neuesten Fehlerkorrekturen und Funktionen zu profitieren. Darüber hinaus ist es wichtig, Mastodon zeitnah zu aktualisieren, um Sicherheitslücken zu schließen. Aus diesen Gründen prüft Mastodon alle 30 Minuten auf Updates und du wirst deinen Einstellungen entsprechend per E-Mail informiert. diff --git a/config/locales/doorkeeper.pt-BR.yml b/config/locales/doorkeeper.pt-BR.yml index 922936dd30..1e4efbea78 100644 --- a/config/locales/doorkeeper.pt-BR.yml +++ b/config/locales/doorkeeper.pt-BR.yml @@ -176,21 +176,21 @@ pt-BR: read:accounts: ver informações das contas read:blocks: ver seus bloqueados read:bookmarks: ver seus salvos - read:favourites: veja seus favoritos + read:favourites: ver seus favoritos read:filters: ver seus filtros read:follows: ver quem você segue read:lists: ver suas listas read:mutes: ver seus silenciados read:notifications: ver suas notificações read:reports: ver suas denúncias - read:search: buscar em seu nome + read:search: buscar em seu lugar read:statuses: ver todos os toots write: alterar todos os dados da sua conta write:accounts: alterar seu perfil write:blocks: bloquear contas e domínios write:bookmarks: salvar toots write:conversations: silenciar e excluir conversas - write:favourites: publicações favoritas + write:favourites: favoritar publicações write:filters: criar filtros write:follows: seguir pessoas write:lists: criar listas diff --git a/config/locales/el.yml b/config/locales/el.yml index af7b3e7daf..ce46ac37a7 100644 --- a/config/locales/el.yml +++ b/config/locales/el.yml @@ -279,10 +279,10 @@ el: destroy_unavailable_domain_html: Ο/Η %{name} ξανάρχισε να τροφοδοτεί το domain %{target} destroy_user_role_html: Ο/Η %{name} διέγραψε τον ρόλο του %{target} destroy_username_block_html: "%{name} αφαίρεσε κανόνα για ονόματα χρηστών που περιέχουν %{target}" - disable_2fa_user_html: Ο/Η %{name} απενεργοποίησε την απαίτηση για ταυτοποίηση δύο παραγόντων για τον χρήστη %{target} + disable_2fa_user_html: Ο/Η %{name} απενεργοποίησε την απαίτηση για πιστοποίηση δύο παραγόντων για τον χρήστη %{target} disable_custom_emoji_html: Ο/Η %{name} απενεργοποίησε το emoji %{target} disable_relay_html: Ο χρήστης %{name} απενεργοποίησε το relay %{target} - disable_sign_in_token_auth_user_html: Ο χρήστης %{name} απενεργοποίησε την ταυτοποίηση χαρακτηριστικού μέσω e-mail για %{target} + disable_sign_in_token_auth_user_html: Ο/Η %{name} απενεργοποίησε την πιστοποίηση διακριτικού μέσω email για τον χρήστη %{target} disable_user_html: Ο/Η %{name} απενεργοποίησε τη σύνδεση για τον χρήστη %{target} enable_custom_emoji_html: Ο/Η %{name} ενεργοποίησε το emoji %{target} enable_relay_html: Ο χρήστης %{name} ενεργοποίησε το relay %{target} @@ -883,7 +883,7 @@ el: manage_taxonomies: Διαχείριση Ταξινομιών manage_taxonomies_description: Επιτρέπει στους χρήστες να εξετάζουν το δημοφιλές περιεχόμενο και να ενημερώνουν τις ρυθμίσεις ετικέτας manage_user_access: Διαχείριση Πρόσβασης Χρήστη - manage_user_access_description: Επιτρέπει στους χρήστες να απενεργοποιούν την ταυτοποίηση δύο παραγόντων άλλων χρηστών, να αλλάξουν τη διεύθυνση ηλεκτρονικού ταχυδρομείου τους και να επαναφέρουν τον κωδικό πρόσβασής τους + manage_user_access_description: Επιτρέπει στους χρήστες να απενεργοποιούν την πιστοποίηση δύο παραγόντων άλλων χρηστών, να αλλάξουν τη διεύθυνση ηλεκτρονικού ταχυδρομείου τους και να επαναφέρουν τον κωδικό πρόσβασής τους manage_users: Διαχείριση Χρηστών manage_users_description: Επιτρέπει στους χρήστες να βλέπουν τις λεπτομέρειες άλλων χρηστών και να εκτελούν ενέργειες συντονισμού εναντίον τους manage_webhooks: Διαχείριση Webhooks @@ -974,11 +974,12 @@ el: authorized_fetch: Απαίτηση ταυτόποιησης από διακομιστές σε ομοσπονδία authorized_fetch_hint: Η απαίτηση ελέγχου ταυτότητας από ομοσπονδιακούς διακομιστές επιτρέπει την αυστηρότερη επιβολή αποκλεισμού τόσο σε επίπεδο χρήστη όσο και σε επίπεδο διακομιστή. Ωστόσο, αυτό έχει το κόστος στην απόδοσης μειώνει την εμβέλεια των απαντήσεών σας και μπορεί να δημιουργήσει προβλήματα συμβατότητας με ορισμένες ομοσπονδιακές υπηρεσίες. Επιπλέον, αυτό δεν θα εμποδίσει τους αφοσιωμένους ηθοποιούς να ανακτήσουν τις δημόσιες αναρτήσεις και τους λογαριασμούς σας. authorized_fetch_overridden_hint: Προς το παρόν, δε μπορείς να αλλάξεις αυτή την ρύθμιση επειδή παρακάμπτεται από μια μεταβλητή περιβάλλοντος. - federation_authentication: Επιβολή ομοσπονδιακής ταυτοποίησης + federation_authentication: Επιβολή ομοσπονδιακής πιστοποίησης title: Ρυθμίσεις διακομιστή site_uploads: delete: Διαγραφή μεταφορτωμένου αρχείου destroyed_msg: Η μεταφόρτωση ιστότοπου διαγράφηκε επιτυχώς! + skip_to_content: Μετάβαση στο περιεχόμενο software_updates: critical_update: Κρίσιμο - παρακαλώ ενημέρωσε γρήγορα description: Συνιστάται να διατηρείς την εγκατάσταση του Mastodon ενημερωμένη για να επωφεληθείς από τις πιο πρόσφατες διορθώσεις και δυνατότητες. Επιπλέον, μερικές φορές είναι κρίσιμο να ενημερώσεις το Mastodon εγκαίρως για να αποφύγεις προβλήματα ασφαλείας. Για αυτούς τους λόγους, το Mastodon ελέγχει για ενημερώσεις κάθε 30 λεπτά και θα σε ειδοποιεί σύμφωνα με τις προτιμήσεις ειδοποίησης μέσω email. @@ -1347,7 +1348,7 @@ el: dont_have_your_security_key: Δεν έχεις κλειδί ασφαλείας; forgot_password: Ξέχασες το συνθηματικό σου; invalid_reset_password_token: Το διακριτικό επαναφοράς συνθηματικού είναι άκυρο ή ληγμένο. Παρακαλώ αιτήσου νέο. - link_to_otp: Γράψε τον κωδικό ταυτοποίησης 2 παραγόντων από το τηλέφωνό σου ή τον κωδικό επαναφοράς + link_to_otp: Γράψε τον κωδικό πιστοποίησης δύο παραγόντων από το τηλέφωνό σου ή τον κωδικό επαναφοράς link_to_webauth: Χρήση συσκευής κλειδιού ασφαλείας log_in_with: Σύνδεση με login: Σύνδεση @@ -1752,7 +1753,7 @@ el: limit: Έχεις φτάσει το μέγιστο αριθμό λιστών login_activities: authentication_methods: - otp: εφαρμογή ταυτοποίησης δύο παραγόντων + otp: εφαρμογή πιστοποίησης δύο παραγόντων password: συνθηματικό sign_in_token: κωδικός ασφαλείας email webauthn: κλειδιά ασφαλείας @@ -1887,7 +1888,7 @@ el: trillion: Τρις otp_authentication: code_hint: Για να συνεχίσεις, γράψε τον κωδικό που δημιούργησε η εφαρμογή πιστοποίησης - description_html: Αν ενεργοποιήσεις την <strong>ταυτοποίηση δύο παραγόντων</strong> χρησιμοποιώντας εφαρμογή ταυτοποίησης, για να συνδεθείς θα πρέπει να έχεις το τηλέφωνό σου, που θα σου δημιουργήσει κλειδιά εισόδου για να τα εισάγεις. + description_html: Αν ενεργοποιήσεις την <strong>πιστοποίηση δύο παραγόντων</strong> χρησιμοποιώντας εφαρμογή πιστοποίησης, για να συνδεθείς θα πρέπει να έχεις το τηλέφωνό σου, που θα σου δημιουργήσει κλειδιά εισόδου για να τα εισάγεις. enable: Ενεργοποίηση instructions_html: "<strong>Σάρωσε αυτόν τον κωδικό QR με την εφαρμογή Google Authenticator ή κάποια άλλη αντίστοιχη στο τηλέφωνό σου</strong>. Από εδώ και στο εξής, η εφαρμογή θα δημιουργεί κλειδιά που θα πρέπει να εισάγεις όταν συνδέεσαι." manual_instructions: 'Αν δεν μπορείς να σαρώσεις τον κωδικό QR και χρειάζεσαι να τον εισάγεις χειροκίνητα, ορίστε η μυστική φράση σε μορφή κειμένου:' @@ -2170,7 +2171,7 @@ el: two_factor_authentication: add: Προσθήκη disable: Απενεργοποίηση 2FA - disabled_success: Η ταυτοποίηση δύο παραγόντων απενεργοποιήθηκε επιτυχώς + disabled_success: Η πιστοποίηση δύο παραγόντων απενεργοποιήθηκε επιτυχώς edit: Επεξεργασία enabled: Η πιστοποίηση 2 παραγόντων είναι ενεργοποιημένη enabled_success: Η πιστοποίηση 2 παραγόντων ενεργοποιήθηκε επιτυχώς @@ -2231,13 +2232,13 @@ el: details: 'Εδώ είναι οι λεπτομέρειες της προσπάθειας σύνδεσης:' explanation: Κάποιος έχει προσπαθήσει να εισέλθει στον λογαριασμό σου, αλλά παρείχε έναν μη έγκυρο δεύτερο παράγοντα ελέγχου ταυτότητας. further_actions_html: Αν δεν ήσουν εσύ, σου συνιστούμε να %{action} αμέσως, καθώς μπορεί να έχει εκτεθεί. - subject: Αποτυχία ταυτοποίησης δεύτερου παράγοντα + subject: Αποτυχία πιστοποίησης δεύτερου παράγοντα title: Αποτυχία ελέγχου ταυτότητας δεύτερου παράγοντα suspicious_sign_in: change_password: άλλαξε τον κωδικό πρόσβασής σου details: 'Εδώ είναι οι λεπτομέρειες της σύνδεσης:' explanation: Εντοπίσαμε μια σύνδεση στο λογαριασμό σου από μια νέα διεύθυνση IP. - further_actions_html: Αν δεν ήσουν εσύ, σας συνιστούμε να %{action} αμέσως και να ενεργοποιήσεις τον έλεγχο ταυτοποίησης δύο παραγόντων για να διατηρήσεις τον λογαριασμό σου ασφαλή. + further_actions_html: Αν δεν ήσουν εσύ, σου συνιστούμε να %{action} αμέσως και να ενεργοποιήσεις την πιστοποίηση δύο παραγόντων για να διατηρήσεις τον λογαριασμό σου ασφαλή. subject: Ο λογαριασμός σου έχει συνδεθεί από μια νέα διεύθυνση IP title: Μια νέα σύνδεση terms_of_service_changed: @@ -2352,7 +2353,7 @@ el: nickname_hint: Βάλε το ψευδώνυμο του νέου κλειδιού ασφαλείας σου not_enabled: Δεν έχεις ενεργοποιήσει το WebAuthn ακόμη not_supported: Αυτό το πρόγραμμα περιήγησης δεν υποστηρίζει κλειδιά ασφαλείας - otp_required: Για να χρησιμοποιήσεις κλειδιά ασφαλείας, ενεργοποίησε πρώτα την ταυτοποίηση δύο παραγόντων. + otp_required: Για να χρησιμοποιήσεις κλειδιά ασφαλείας, ενεργοποίησε πρώτα την πιστοποίηση δύο παραγόντων. registered_on: Εγγραφή στις %{date} wrapstodon: description: Δείτε πώς ο/η %{name} χρησιμοποίησε το Mastodon φέτος! diff --git a/config/locales/en.yml b/config/locales/en.yml index 41c80e39d0..2ed8dd1c1a 100644 --- a/config/locales/en.yml +++ b/config/locales/en.yml @@ -979,6 +979,7 @@ en: site_uploads: delete: Delete uploaded file destroyed_msg: Site upload successfully deleted! + skip_to_content: Skip to content software_updates: critical_update: Critical — please update quickly description: It is recommended to keep your Mastodon installation up to date to benefit from the latest fixes and features. Moreover, it is sometimes critical to update Mastodon in a timely manner to avoid security issues. For these reasons, Mastodon checks for updates every 30 minutes, and will notify you according to your email notification preferences. diff --git a/config/locales/es-AR.yml b/config/locales/es-AR.yml index 4602a66e72..e8838d5e2c 100644 --- a/config/locales/es-AR.yml +++ b/config/locales/es-AR.yml @@ -979,6 +979,7 @@ es-AR: site_uploads: delete: Eliminar archivo subido destroyed_msg: "¡Subida al sitio eliminada exitosamente!" + skip_to_content: Saltar al contenido software_updates: critical_update: Crítica — por favor, actualizá cuanto antes description: Se recomienda mantener actualizada tu instalación de Mastodon para beneficiarte de las últimas correcciones y funciones. Además, a veces es crítico actualizar Mastodon inmediatamente para evitar problemas de seguridad. Por estas razones, Mastodon comprueba si hay actualizaciones cada 30 minutos, y te notificará de acuerdo a tu configuración de notificaciones por correo electrónico. diff --git a/config/locales/es-MX.yml b/config/locales/es-MX.yml index 726169afda..e7e3a1d0f7 100644 --- a/config/locales/es-MX.yml +++ b/config/locales/es-MX.yml @@ -979,6 +979,7 @@ es-MX: site_uploads: delete: Eliminar archivo subido destroyed_msg: "¡Carga del sitio eliminada con éxito!" + skip_to_content: Ir al contenido software_updates: critical_update: Crítico — por favor actualiza rápidamente description: Se recomienda mantener tu instalación de Mastodon actualizada para beneficiarte de las últimas correcciones y características. Además, a veces es crítico actualizar Mastodon a tiempo para evitar problemas de seguridad. Por estas razones, Mastodon busca actualizaciones cada 30 minutos, y le notificará de acuerdo a sus preferencias de notificación por correo electrónico. diff --git a/config/locales/es.yml b/config/locales/es.yml index 46a3e87fd8..c234628964 100644 --- a/config/locales/es.yml +++ b/config/locales/es.yml @@ -979,6 +979,7 @@ es: site_uploads: delete: Eliminar archivo subido destroyed_msg: "¡Carga del sitio eliminada con éxito!" + skip_to_content: Ir al contenido software_updates: critical_update: Crítica— por favor actualiza rápidamente description: Se recomienda mantener actualizada tu instalación de Mastodon para beneficiarte de las últimas correcciones y características. Además, a veces es crítico actualizar Mastodon de manera oportuna para evitar problemas de seguridad. Por estas razones, Mastodon comprueba si hay actualizaciones cada 30 minutos, y te notificará de acuerdo a tus preferencias de notificación por correo electrónico. diff --git a/config/locales/et.yml b/config/locales/et.yml index eec699edc5..5c20dd2f6e 100644 --- a/config/locales/et.yml +++ b/config/locales/et.yml @@ -979,6 +979,7 @@ et: site_uploads: delete: Kustuta üleslaetud fail destroyed_msg: Üleslaetud fail edukalt kustutatud! + skip_to_content: Hüppa sisuni software_updates: critical_update: Kriitiline — uuenda kiiresti description: Soovitatav on hoida oma Mastodoni paigaldus ajakohasena, et saada kasu viimastest parandustest ja funktsioonidest. Lisaks sellele on mõnikord oluline Mastodoni õigeaegne uuendamine, et vältida turvaprobleeme. Neil põhjustel kontrollib Mastodon uuendusi iga 30 minuti järel ja teavitab vastavalt sinu e-posti teavitamise eelistustele. diff --git a/config/locales/fi.yml b/config/locales/fi.yml index c8026caaac..2f4ecc5bcd 100644 --- a/config/locales/fi.yml +++ b/config/locales/fi.yml @@ -971,6 +971,7 @@ fi: site_uploads: delete: Poista lähetetty tiedosto destroyed_msg: Sivustolatauksen poisto onnistui! + skip_to_content: Siirry sisältöön software_updates: critical_update: Kriittinen – päivitä viivyttelemättä description: On suositeltavaa pitää Mastodon-asennus ajantasaisena ja siten hyödyntää uusimpia korjauksia sekä ominaisuuksia. Lisäksi joskus on ratkaisevan tärkeää päivittää Mastodon ajoissa tietoturvaongelmien välttämiseksi. Näistä syistä Mastodon tarkistaa päivitykset 30 minuutin välein, ja ilmoittaa sinulle sähköposti-ilmoitusasetustesi mukaisesti. diff --git a/config/locales/fr-CA.yml b/config/locales/fr-CA.yml index cd6c848a21..11791c5d9d 100644 --- a/config/locales/fr-CA.yml +++ b/config/locales/fr-CA.yml @@ -349,6 +349,7 @@ fr-CA: back_to_report: Retour à la page du signalement batch: add_to_report: 'Ajouter au signalement #%{id}' + remove_from_report: Retirer du signalement report: Signaler collection_title: Collection par %{name} contents: Contenu @@ -978,6 +979,7 @@ fr-CA: site_uploads: delete: Supprimer le fichier téléversé destroyed_msg: Téléversement sur le site supprimé avec succès ! + skip_to_content: Accéder au contenu software_updates: critical_update: Critique — veuillez mettre à jour au plus vite description: Il est recommandé de maintenir votre installation de Mastodon à jour afin de bénéficier des derniers correctifs et fonctionnalités. Par ailleurs, il est parfois critique de mettre à jour Mastodon rapidement de manière à éviter les incidents relatifs à la sécurité. Pour ces raisons, Mastodon examine la disponibilté des mises à jour toutes les 30 minutes, et vous en avisera en fonction de vos préférences de notification par courriel. diff --git a/config/locales/fr.yml b/config/locales/fr.yml index ddf63b0147..5e88e2d1c1 100644 --- a/config/locales/fr.yml +++ b/config/locales/fr.yml @@ -349,6 +349,7 @@ fr: back_to_report: Retour à la page du signalement batch: add_to_report: 'Ajouter au signalement #%{id}' + remove_from_report: Retirer du signalement report: Signaler collection_title: Collection par %{name} contents: Contenu @@ -978,6 +979,7 @@ fr: site_uploads: delete: Supprimer le fichier téléversé destroyed_msg: Téléversement sur le site supprimé avec succès ! + skip_to_content: Accéder au contenu software_updates: critical_update: Critique — veuillez mettre à jour au plus vite description: Il est recommandé de maintenir votre installation de Mastodon à jour afin de bénéficier des derniers correctifs et fonctionnalités. Par ailleurs, il est parfois critique de mettre à jour Mastodon rapidement de manière à éviter les incidents relatifs à la sécurité. Pour ces raisons, Mastodon examine la disponibilté des mises à jour toutes les 30 minutes, et vous en avisera en fonction de vos préférences de notification par courriel. diff --git a/config/locales/ga.yml b/config/locales/ga.yml index 0dec8d025c..7b3eb3c13c 100644 --- a/config/locales/ga.yml +++ b/config/locales/ga.yml @@ -361,6 +361,7 @@ ga: back_to_report: Ar ais chuig leathanach na tuarascála batch: add_to_report: 'Cuir le tuarascáil #%{id}' + remove_from_report: Bain den tuarascáil report: Tuairisc collection_title: Bailiúchán le %{name} contents: Ábhar diff --git a/config/locales/gl.yml b/config/locales/gl.yml index 58bbcea077..33f1a2ec22 100644 --- a/config/locales/gl.yml +++ b/config/locales/gl.yml @@ -186,11 +186,11 @@ gl: confirm_user: Confirmar usuaria create_account_warning: Crear aviso create_announcement: Crear anuncio - create_canonical_email_block: Crear Bloqueo de Correo + create_canonical_email_block: Crear bloqueo de correo create_custom_emoji: Crear emoticonas personalizadas create_domain_allow: Crear Dominio Permitido create_domain_block: Crear bloquedo do Dominio - create_email_domain_block: Crear Bloqueo de Dominio do correo + create_email_domain_block: Crear bloqueo de dominio do correo create_ip_block: Crear regra IP create_relay: Crear Repetidor create_unavailable_domain: Crear dominio Non dispoñible @@ -213,11 +213,11 @@ gl: disable_2fa_user: Desactivar 2FA disable_custom_emoji: Desactivar emoticona personalizada disable_relay: Desactivar Repetidor - disable_sign_in_token_auth_user: Desactivar Autenticación por Token no Correo para a Usuaria + disable_sign_in_token_auth_user: Desactivar autenticación cun token no correo da usuaria disable_user: Desactivar usuaria enable_custom_emoji: Activar emoticona personalizada enable_relay: Activar Repetidor - enable_sign_in_token_auth_user: Activar Autenticación con Token no Correo para a Usuaria + enable_sign_in_token_auth_user: Activar a autenticación cun token no correo da usuaria enable_user: Activar usuaria memorialize_account: Transformar en conta conmemorativa promote_user: Promover usuaria @@ -241,7 +241,7 @@ gl: update_custom_emoji: Actualizar emoticona personalizada update_domain_block: Actualizar bloqueo do dominio update_ip_block: Actualizar regra IP - update_report: Actualización da denuncia + update_report: Actualizar a denuncia update_status: Actualizar publicación update_user_role: Actualizar Rol update_username_block: Actualizar regra para Identificadores @@ -349,6 +349,7 @@ gl: back_to_report: Volver á páxina da denuncia batch: add_to_report: 'Engadir á denuncia #%{id}' + remove_from_report: Retirar da denuncia report: Denunciar collection_title: Colección de %{name} contents: Contido diff --git a/config/locales/he.yml b/config/locales/he.yml index afb5ee59e5..724e702e64 100644 --- a/config/locales/he.yml +++ b/config/locales/he.yml @@ -357,6 +357,7 @@ he: back_to_report: חזרה לעמוד הדיווח batch: add_to_report: להוסיף לדו"ח מספר %{id} + remove_from_report: הסרה מהדוח report: דווח collection_title: אוספים מאת %{name} contents: תוכן diff --git a/config/locales/hu.yml b/config/locales/hu.yml index 601b767e90..6f12ea2f22 100644 --- a/config/locales/hu.yml +++ b/config/locales/hu.yml @@ -349,6 +349,7 @@ hu: back_to_report: Vissza a bejelentés oldalra batch: add_to_report: 'Hozzáadás ehhez a jelentéshez: #%{id}' + remove_from_report: Eltávolítás a bejelentésből report: Jelentés collection_title: "%{name} gyűjteménye" contents: Tartalom @@ -978,6 +979,7 @@ hu: site_uploads: delete: Feltöltött fájl törlése destroyed_msg: Sikeresen töröltük a site feltöltését! + skip_to_content: Ugrás a tartalomhoz software_updates: critical_update: Kritikus - frissíts gyorsan description: Javasolt, hogy a Mastodon telepítésed naprakész legyen, hogy kihasználhasd a legújabb javításokat és funkciókat. Ezenkívül néha különösen fontos a Mastodon időben történő frissítése a biztonsági problémák elkerülése érdekében. Ezen okok miatt a Mastodon 30 percenként ellenőrzi a frissítéseket és az e-mail-értesítési beállításoknak megfelelően értesítést küld. diff --git a/config/locales/it.yml b/config/locales/it.yml index 2b408b057f..f322309911 100644 --- a/config/locales/it.yml +++ b/config/locales/it.yml @@ -1862,7 +1862,7 @@ it: quoted_update: subject: "%{name} ha modificato un post che hai citato" reblog: - body: 'Il tuo status è stato condiviso da %{name}:' + body: 'Il tuo post è stato condiviso da %{name}:' subject: "%{name} ha condiviso il tuo status" title: Nuova condivisione severed_relationships: @@ -2112,7 +2112,7 @@ it: exceptions: Eccezioni explanation: L'eliminazione automatica viene eseguita con bassa priorità. Potrebbe verificarsi un ritardo tra il raggiungimento della soglia di età e la rimozione. ignore_favs: Ignora preferiti - ignore_reblogs: Ignora condivisioni + ignore_reblogs: Ignora le condivisioni interaction_exceptions: Eccezioni basate sulle interazioni interaction_exceptions_explanation: I post che superano temporaneamente la soglia dei preferiti o delle condivisioni potrebbero essere conservati anche se in seguito vengono diminuiti. keep_direct: Conserva messaggi diretti @@ -2139,7 +2139,7 @@ it: min_age_label: Soglia di età min_favs: Conserva i post preferiti più di min_favs_hint: Non cancella nessuno dei tuoi post che ha ricevuto almeno questo numero di preferiti. Lascia vuoto per cancellare i post indipendentemente dal loro numero di preferiti - min_reblogs: Conserva i post condivisi più di + min_reblogs: Mantieni i post condivisi almeno 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: sensitive_content: Materiale sensibile diff --git a/config/locales/pt-BR.yml b/config/locales/pt-BR.yml index cfbd4db0d4..e9cddeac98 100644 --- a/config/locales/pt-BR.yml +++ b/config/locales/pt-BR.yml @@ -15,7 +15,7 @@ pt-BR: following: one: Seguindo other: Seguindo - instance_actor_flash: Esta conta é um ator virtual usado para representar o próprio servidor e não um usuário individual. É utilizada para fins de federação e não deve ser suspensa. + instance_actor_flash: Esta conta é um agente virtual usado para representar o próprio servidor e não um usuário individual. É utilizada para fins de federação e não deve ser suspensa. last_active: última atividade link_verified_on: A propriedade do link foi verificada em %{date} nothing_here: Nada aqui! @@ -51,11 +51,11 @@ pt-BR: submit: Alterar e-mail title: Alterar e-mail para %{username} change_role: - changed_msg: Função alterada com sucesso! - edit_roles: Gerenciar funções do usuário + changed_msg: Cargo alterado com sucesso! + edit_roles: Gerenciar cargos do usuário label: Alterar função - no_role: Nenhuma função - title: Alterar função para %{username} + no_role: Nenhum cargo + title: Alterar cargo de %{username} collections: Coleções confirm: Confirmar confirmed: Confirmado @@ -92,17 +92,17 @@ pt-BR: remote: Remoto title: Localização login_status: Situação da conta - media_attachments: Mídias anexadas + media_attachments: Anexos de mídia memorialize: Converter em memorial memorialized: Convertidas em memorial memorialized_msg: A conta de %{username} foi transformada em uma conta memorial moderation: - active: Ativo - all: Todos + active: Ativa + all: Todas disabled: Desativado pending: Pendente silenced: Limitado - suspended: Suspendido + suspended: Suspenso title: Moderação moderation_notes: Notas de moderação most_recent_activity: Atividade mais recente @@ -111,12 +111,12 @@ pt-BR: no_limits_imposed: Sem limite imposto no_role_assigned: Sem cargo not_subscribed: Não inscrito - pending: Revisão pendente + pending: Pendente de revisão perform_full_suspension: Suspender previous_strikes: Avisos anteriores previous_strikes_description_html: one: Esta conta tem <strong>um</strong> aviso. - other: Esta conta tem <strong>%{count}</strong> ataques. + other: Esta conta tem <strong>%{count}</strong> avisos. promote: Promover protocol: Protocolo public: Público @@ -158,8 +158,8 @@ pt-BR: strikes: Avisos anteriores subscribe: Inscrever-se suspend: Suspender - suspended: Suspendido - suspension_irreversible: Os dados desta conta foram excluídos de forma irreversível. Você pode remover a suspensão da conta para torná-la utilizável, mas ela não recuperará nenhum dado que ela possuía anteriormente. + suspended: Suspenso + suspension_irreversible: Os dados desta conta foram excluídos de forma irreversível. Você pode remover a suspensão da conta para torná-la utilizável, mas isto não recuperará nenhum dado que ela possuía anteriormente. suspension_reversible_hint_html: A conta foi suspensa e os dados serão totalmente removidos em %{date}. Até lá, a conta pode ser restaurada sem nenhum efeito negativo. Se você deseja remover todos os dados da conta imediatamente, você pode fazer isso abaixo. title: Contas unblock_email: Desbloquear endereço de e-mail @@ -167,7 +167,7 @@ pt-BR: unconfirmed_email: E-mail não confirmado undo_sensitized: Desfazer sensível undo_silenced: Desfazer silêncio - undo_suspension: Desbanir + undo_suspension: Desfazer suspensão unsilenced_msg: As limitações da conta de %{username} foram removidas unsubscribe: Cancelar inscrição unsuspended_msg: A suspensão da conta de %{username} foi removida @@ -175,7 +175,7 @@ pt-BR: view_domain: Ver resumo para o domínio warn: Notificar web: Web - whitelisted: Permitido + whitelisted: Permitido para federação action_logs: action_types: approve_appeal: Aprovar revisão @@ -194,7 +194,7 @@ pt-BR: create_ip_block: Criar regra de IP create_relay: Criar Retransmissão create_unavailable_domain: Criar domínio indisponível - create_user_role: Criar cargo + create_user_role: Criar função create_username_block: Criar regra de usuário demote_user: Rebaixar usuário destroy_announcement: Excluir anúncio @@ -208,7 +208,7 @@ pt-BR: destroy_relay: Excluir Retransmissão destroy_status: Excluir publicação destroy_unavailable_domain: Excluir domínio indisponível - destroy_user_role: Destruir cargo + destroy_user_role: Destruir função destroy_username_block: Excluir regra de usuário disable_2fa_user: Desativar autenticação de dois fatores disable_custom_emoji: Desativar emoji personalizado @@ -327,7 +327,7 @@ pt-BR: edit: title: Editar anúncio empty: Sem anúncios. - live: Ao vivo + live: No ar new: create: Criar anúncio title: Novo anúncio @@ -341,7 +341,7 @@ pt-BR: scheduled_msg: Anúncio agendado para publicação! title: Anúncios unpublish: Cancelar publicação - unpublished_msg: Anúncio desfeito! + unpublished_msg: Anúncio retirado do ar! updated_msg: Anúncio atualizado! collections: accounts: Contas @@ -545,10 +545,10 @@ pt-BR: purged_msg: Todos os dados de inscrições via email estão sendo apagados. roles: accounts: Contas - edit_role: Editar função + edit_role: Editar cargo empty: - hint: Ninguém ter permissão para usar este recurso. - no_roles_added: Nenhuma função adicionada + hint: Ninguém tem permissão para usar este recurso. + no_roles_added: Nenhum cargo adicionado lead: As contas com os seguintes cargos podem ativar este recurso em seus perfis. manage_roles: Gerenciar cargos role_name: Nome do cargo @@ -842,7 +842,7 @@ pt-BR: moderation: Moderação special: Especial delete: Excluir - description_html: Com as <strong>funções de usuário</strong>, você pode personalizar quais funções e áreas do Mastodon seus usuários podem acessar. + description_html: Com os <strong>cargos de usuário</strong>, você pode personalizar quais funções e áreas do Mastodon seus usuários podem acessar. edit: Editar cargo '%{name}' everyone: Permissões padrão everyone_full_description_html: Este é o <strong>cargo base</strong> que afeta <strong>todos os usuários</strong>, mesmo aqueles sem um cargo atribuído. Todos os outros cargos herdam as permissões dele. @@ -851,14 +851,14 @@ pt-BR: other: "%{count} permissões" privileges: administrator: Administrador - administrator_description: Usuários com essa permissão irão ignorar todas as permissões + administrator_description: Usuários com essa permissão irão contornar todas as permissões delete_user_data: Apagar Dados de Usuário delete_user_data_description: Permitir aos usuários apagar os dados de outros usuários instantaneamente invite_bypass_approval: Convidar usuário sem revisão - invite_bypass_approval_description: Permitir pessoas convidadas para esse servidor por esses usuários para dispensar aprovação por moderação + invite_bypass_approval_description: Permitir que pessoas convidadas para esse servidor por esses usuários não precisem de aprovação da moderação invite_users: Convidar Usuários invite_users_description: Permite que os usuários convidem novas pessoas para o servidor - manage_announcements: Gerenciar Avisos + manage_announcements: Gerenciar anúncios manage_announcements_description: Permite aos usuários gerenciar anúncios no servidor manage_appeals: Gerenciar revisões manage_appeals_description: Permite aos usuários visualizar as revisões das decisões da moderação @@ -979,6 +979,7 @@ pt-BR: site_uploads: delete: Excluir arquivo enviado destroyed_msg: Upload do site excluído com sucesso! + skip_to_content: Pular para o conteúdo software_updates: critical_update: Crítico — por favor, atualize rapidamente description: É recomendável que você mantenha a instalação do Mastodon atualizada para se beneficiar das correções e das novas funcionalidades. Além disso, às vezes é imprescindível atualizar o Mastodon rapidamente para evitar problemas de segurança. Por esses motivos, o Mastodon verifica se há atualizações a cada 30 minutos e notificará você de acordo com as suas preferências de notificação por e-mail. diff --git a/config/locales/ru.yml b/config/locales/ru.yml index 1b7cb9a6e6..03c8e02581 100644 --- a/config/locales/ru.yml +++ b/config/locales/ru.yml @@ -2140,8 +2140,7 @@ ru: subject: Сервисное объявление title: Сервисное объявление %{domain} appeal_approved: - action: Настройки аккаунта - explanation: Апелляция на разблокировку против вашей учетной записи %{strike_date}, которую вы подали на %{appeal_date}, была одобрена. Ваша учетная запись снова на хорошем счету. + action: Настройки учётной записи subject: Ваше обжалование от %{date} была одобрено subtitle: Ваш аккаунт снова с хорошей репутацией. title: Обжалование одобрено @@ -2192,54 +2191,63 @@ ru: reason: 'Причина:' statuses: 'Цитируемые посты:' subject: - delete_statuses: Опубликованные вами с учётной записи %{acct} посты были удалены - disable: Ваша учётная запись %{acct} заморожена - mark_statuses_as_sensitive: Ваши сообщения в %{acct} были отмечены как деликатные + delete_statuses: Посты в вашей учётной записи %{acct} были удалены + disable: Ваша учётная запись %{acct} была заморожена + mark_statuses_as_sensitive: Посты в вашей учётной записи %{acct} были отмечены как содержимое деликатного характера none: "%{acct} вынесено предупреждение" - sensitive: Ваши сообщения в %{acct} будут отмечены с этого момента как деликатные - silence: На учётную запись %{acct} наложены ограничения + sensitive: Ваша учётная запись %{acct} получила отметку «деликатного содержания» + silence: Ваша учётная запись %{acct} была ограничена suspend: Ваша учётная запись %{acct} была заблокирована title: - delete_statuses: Ваши посты удалены + delete_statuses: Посты удалены disable: Учётная запись заморожена - mark_statuses_as_sensitive: Посты, отмеченные как деликатные + mark_statuses_as_sensitive: Посты отмечены как содержимое деликатного характера none: Предупреждение - sensitive: Учетная запись отмечена как деликатная - silence: На учётную запись наложены ограничения + sensitive: Учётная запись получила отметку «деликатного содержания» + silence: Учётная запись ограничена suspend: Учётная запись заблокирована welcome: - apps_android_action: Скачать на Google Play - apps_ios_action: Скачать в App Store - apps_step: Загрузите наши официальные приложения. + apps_android_action: Установить из Google Play + apps_ios_action: Установить из App Store + apps_step: Установите наши официальные приложения. apps_title: Приложения Mastodon - checklist_subtitle: 'Давайте начнем знакомство с этим новым социальным рубежом:' - edit_profile_action: Персонализация - edit_profile_title: Персонализируйте свой профиль + checklist_subtitle: 'Вот несколько шагов, чтобы освоиться на новом рубеже:' + checklist_title: С чего начать + edit_profile_action: В профиль + edit_profile_step: С заполненным профилем вы получите больше взаимодействий. + edit_profile_title: Создайте профиль explanation: Вот несколько советов для новичков feature_action: Подробнее - feature_control: Вы сами знаете, что хотите видеть в своей ленте. Никаких алгоритмов или рекламы, чтобы тратить ваше время. Следите за любым человеком на любом сервере Mastodon с одного аккаунта и получайте его сообщения в хронологическом порядке, а также сделайте свой уголок интернета немного больше похожим на себя. - feature_creativity: Mastodon поддерживает аудио-, видео- и фотопосты, описания доступности, опросы, предупреждения о содержании, анимированные аватары, пользовательские emojis, управление обрезкой миниатюр и многое другое, чтобы помочь вам выразить себя в Интернете. Публикуете ли вы свои работы, музыку или подкаст, Mastodon всегда готов помочь вам. - feature_creativity_title: Непревзойденная креативность - feature_moderation: Mastodon возвращает принятие решений в ваши руки. Каждый сервер создает свои собственные правила и нормы, которые соблюдаются локально, а не сверху вниз, как в корпоративных социальных сетях, что позволяет наиболее гибко реагировать на потребности различных групп людей. Присоединяйтесь к серверу с правилами, с которыми вы согласны, или создайте свой собственный. - feature_moderation_title: Модерирование, каким оно должно быть - follow_title: Персонализируйте свою домашнюю ленту + feature_audience: Mastodon предоставляет уникальную возможность управлять своей аудиторией без посредников. Если вы разместите сервер Mastodon на собственной инфраструктуре, никто другой кроме вас не будет его контролировать, при этом вы сможете подписываться на пользователей с любых других серверов Mastodon, а они смогут подписаться на вас. + feature_audience_title: Формируйте свою аудиторию с уверенностью + feature_control: Вы сами лучше всех знаете, что вы хотите видеть в своей домашней ленте. Здесь нет алгоритмов и рекламы, которые бы тратили ваше время. С учётной записью на одном сервере вы можете подписываться на пользователей с любых других серверов Mastodon и получать от них новые посты в хронологическом порядке. Так вы можете немного приблизиться к тому, чтобы сделать этот уголок интернета по-настоящему своим. + feature_control_title: Управляйте своей лентой + feature_creativity: В Mastodon можно прикреплять к постам аудио, видео и фото, добавлять описания для людей с ограничениями зрения и слуха, создавать опросы, использовать предупреждения о содержании, анимированные аватары и необычные эмодзи, редактировать область предпросмотра изображения — всё это и многое другое для того, чтобы помочь вам выразить себя в интернете. Публикуете ли вы своё творчество, музыку или подкаст, Mastodon вам в этом пригодится. + feature_creativity_title: Несравненная креативность + feature_moderation: Mastodon возвращает принятие решений в ваши руки. В отличие от принадлежащих корпорациям социальных сетей, в которых правила спускаются сверху, каждый сервер Mastodon устанавливает свои локальные правила и нормы и следит за их соблюдением, что позволяет наиболее гибко реагировать на потребности различных групп людей. Присоединяйтесь к серверу с правилами, с которыми вы согласны, или создайте свой собственный. + feature_moderation_title: Модерация, какой она должна быть + follow_action: Подписаться + follow_step: Подписывайтесь на интересных людей — в этом суть Mastodon. + follow_title: Наполните свою домашнюю ленту + follows_subtitle: Подпишитесь на популярных пользователей follows_title: На кого подписаться + follows_view_more: К другим рекомендуемым профилям hashtags_recent_count: few: "%{people} человека за последние 2 дня" many: "%{people} человек за последние 2 дня" one: "%{people} человек за последние 2 дня" - other: "%{people} человек за последние 2 дня" - hashtags_subtitle: Изучите, что было в тренде за последние 2 дня - hashtags_title: Популярные хэштеги - hashtags_view_more: Посмотреть другие трендовые хэштеги - post_action: Составить - post_step: Поприветствуйте мир с помощью текста, фотографий, видео или опросов. - post_title: Сделайте свой первый пост - share_step: Пусть ваши друзья знают, как найти вас на Mastodon. + other: "%{people} человека за последние 2 дня" + hashtags_subtitle: Посмотрите, что обсуждали за последние 2 дня + hashtags_title: Актуальные хештеги + hashtags_view_more: К другим актуальным хештегам + post_action: Написать + post_step: Поздоровайтесь с миром с помощью текста, фото, видео или опросов. + post_title: Опубликуйте свой первый пост + share_step: Расскажите своим друзьям, как найти вас в Mastodon. share_title: Поделитесь своим профилем Mastodon sign_in_action: Войти subject: Добро пожаловать в Mastodon - title: Добро пожаловать на борт, %{name}! + title: Добро пожаловать на сервер, %{name}! users: follow_limit_reached: Вы можете подписаться не больше чем на %{limit} человек go_to_sso_account_settings: Перейти к настройкам сторонних аккаунтов учетной записи diff --git a/config/locales/simple_form.el.yml b/config/locales/simple_form.el.yml index 1ccd054a33..346b9e320f 100644 --- a/config/locales/simple_form.el.yml +++ b/config/locales/simple_form.el.yml @@ -66,7 +66,7 @@ el: setting_display_media_show_all: Εμφάνιση όλων των πολυμέσων χωρίς προειδοποίηση, συμπεριλαμβανομένων των πολυμέσων που σημαίνονται ως ευαίσθητα setting_emoji_style: Πώς να εμφανίσετε emojis. Το "Αυτόματο" θα προσπαθήσει να χρησιμοποιήσει εγγενή emoji, αλλά πέφτει πίσω στο Twemoji για προγράμματα περιήγησης παλαιού τύπου. setting_quick_boosting_html: Όταν ενεργοποιηθεί, κάνοντας κλικ στο εικονίδιο %{boost_icon} Ενίσχυση θα ενισχύσει αμέσως αντί να ανοίξει το αναπτυσσόμενο μενού ενίσχυσης/παράθεσης. Μετακινεί την ενέργεια παράθεσης στο μενού %{options_icon} (Επιλογές). - setting_system_scrollbars_ui: Ισχύει μόνο για προγράμματα περιήγησης υπολογιστή με βάση το Safari και το Chrome + setting_system_scrollbars_ui: Ισχύει μόνο για προγράμματα περιήγησης για υπολογιστή με βάση το Safari και το Chrome setting_use_blurhash: Οι διαβαθμίσεις βασίζονται στα χρώματα του κρυμμένου πολυμέσου αλλά θολώνουν τις λεπτομέρειες setting_use_pending_items: Εμφάνιση ενημερώσεων ροής μετά από κλικ αντί για αυτόματη κύλιση της ροής username: Μπορείς να χρησιμοποιήσεις γράμματα, αριθμούς και κάτω παύλες @@ -82,8 +82,8 @@ el: action: Επιλέξτε ποια ενέργεια θα εκτελεστεί όταν μια ανάρτηση αντιστοιχεί με το φίλτρο actions: blur: Απόκρυψη πολυμέσων πίσω από μια προειδοποίηση, χωρίς να κρύβεται το ίδιο το κείμενο - hide: Πλήρης αποκρυψη του φιλτραρισμένου περιεχομένου, συμπεριφέρεται σαν να μην υπήρχε - warn: Απόκρυψη φιλτραρισμένου περιεχομένου πίσω από μια προειδοποίηση που αναφέρει τον τίτλο του φίλτρου + hide: Πλήρης απόκρυψη του φιλτραρισμένου περιεχομένου, συμπεριφέρεται σαν να μην υπήρχε + warn: Απόκρυψη φιλτραρισμένου περιεχομένου πίσω από μια προειδοποίηση που επισημαίνει τον τίτλο του φίλτρου form_admin_settings: activity_api_enabled: Καταμέτρηση τοπικά δημοσιευμένων αναρτήσεων, ενεργών χρηστών και νέων εγγραφών σε εβδομαδιαία πακέτα app_icon: WEBP, PNG, GIF ή JPG. Παρακάμπτει το προεπιλεγμένο εικονίδιο εφαρμογής σε κινητές συσκευές με προσαρμοσμένο εικονίδιο. diff --git a/config/locales/sq.yml b/config/locales/sq.yml index db9bc4a0ab..2580b34850 100644 --- a/config/locales/sq.yml +++ b/config/locales/sq.yml @@ -968,6 +968,7 @@ sq: site_uploads: delete: Fshi kartelën e ngarkuar destroyed_msg: Ngarkimi në sajt u fshi me sukses! + skip_to_content: Hidhu te lënda software_updates: critical_update: Kritik — ju lutemi, përditësojeni pa humbur kohë description: Rekomandohet ta mbani të përditësuar instalimin tuaj të Mastodon-it, që të përfitoni nga ndreqjet dhe veçoritë më të reja. Për më tej, ndonjëherë është kritike të përditësohet Mastodon-i në kohën e duhur, për të shmangur probleme sigurie. Për këto arsye, Mastodon-i kontrollon për përditësime çdo 30 minuta dhe do t’ju njoftojë, sipas parapëlqimeve tuaja për njoftime me email. diff --git a/config/locales/vi.yml b/config/locales/vi.yml index 5f809e9d39..edc0eaed02 100644 --- a/config/locales/vi.yml +++ b/config/locales/vi.yml @@ -963,6 +963,7 @@ vi: site_uploads: delete: Xóa tệp đã tải lên destroyed_msg: Đã xóa tệp tải lên thành công! + skip_to_content: Đến nội dung chính software_updates: critical_update: Quan trọng — vui lòng cập nhật sớm description: Bạn nên cập nhật Mastodon phiên bản mới nhất để được hưởng lợi từ các bản sửa lỗi và thêm tính năng mới. Nhất là để tránh các vấn đề bảo mật. Vì những lý do này, Mastodon sẽ kiểm tra các bản cập nhật 30 phút một lần và sẽ thông báo cho bạn theo tùy chọn thông báo qua email của bạn. diff --git a/config/locales/zh-CN.yml b/config/locales/zh-CN.yml index e618265348..f1d56319dc 100644 --- a/config/locales/zh-CN.yml +++ b/config/locales/zh-CN.yml @@ -963,6 +963,7 @@ zh-CN: site_uploads: delete: 删除已上传的文件 destroyed_msg: 站点上传的文件已经成功删除! + skip_to_content: 跳转到内容 software_updates: critical_update: 紧急 — 请尽快更新 description: 建议你及时更新Mastodon实例,以便获得最新修复和功能。此外,为避免安全问题,有时及时更新Mastodon是至关重要的。出于这些原因,Mastodon每30分钟检查一次更新,并根据你的邮件通知偏好向你发送通知。 diff --git a/config/locales/zh-TW.yml b/config/locales/zh-TW.yml index c85a032b4f..0a14e2f487 100644 --- a/config/locales/zh-TW.yml +++ b/config/locales/zh-TW.yml @@ -965,6 +965,7 @@ zh-TW: site_uploads: delete: 刪除上傳的檔案 destroyed_msg: 成功刪除站台的上傳項目! + skip_to_content: 跳轉至內容 software_updates: critical_update: 重要 — 請儘速升級 description: 建議將您的 Mastodon 伺服器升級至最新狀態,以獲得最新錯誤修正及功能更新。此外,即時更新 Mastodon 以避免偶發之安全問題非常重要。因此,Mastodon 每 30 分鐘將檢查一次更新,並依據您的電子郵件通知設定通知您。 diff --git a/lib/sanitize_ext/sanitize_config.rb b/lib/sanitize_ext/sanitize_config.rb index 6bf5b1ef68..1b216afb6b 100644 --- a/lib/sanitize_ext/sanitize_config.rb +++ b/lib/sanitize_ext/sanitize_config.rb @@ -117,6 +117,7 @@ class Sanitize elements: %w(p br span a abbr del s pre blockquote code b strong u sub sup i em h1 h2 h3 h4 h5 ul ol li ruby rt rp), attributes: { + :all => %w(lang), 'a' => %w(href rel class title translate), 'abbr' => %w(title), 'span' => %w(class translate), diff --git a/package.json b/package.json index 64adf78346..e60f612045 100644 --- a/package.json +++ b/package.json @@ -3,7 +3,7 @@ "license": "AGPL-3.0-or-later", "packageManager": "yarn@4.14.1", "engines": { - "node": ">=20" + "node": ">=22" }, "workspaces": [ ".", @@ -178,7 +178,7 @@ "fake-indexeddb": "^6.0.1", "globals": "^17.3.0", "husky": "^9.0.11", - "lint-staged": "^16.2.6", + "lint-staged": "^17.0.0", "msw": "^2.12.1", "msw-storybook-addon": "^2.0.6", "oxfmt": "^0.47.0", diff --git a/spec/lib/activitypub/activity/create_spec.rb b/spec/lib/activitypub/activity/create_spec.rb index 60cda50ed2..335b5f26d0 100644 --- a/spec/lib/activitypub/activity/create_spec.rb +++ b/spec/lib/activitypub/activity/create_spec.rb @@ -658,19 +658,19 @@ RSpec.describe ActivityPub::Activity::Create do type: 'Document', mediaType: 'image/png', url: 'http://example.com/attachment.png', - name: '*' * MediaAttachment::MAX_DESCRIPTION_LENGTH, + name: '*' * (MediaAttachment::MAX_DESCRIPTION_HARD_LENGTH_LIMIT + 5), }, ] ) end - it 'creates status' do + it 'creates status with truncated description' do expect { subject.perform }.to change(sender.statuses, :count).by(1) status = sender.statuses.first expect(status).to_not be_nil - expect(status.media_attachments.map(&:description)).to include('*' * MediaAttachment::MAX_DESCRIPTION_LENGTH) + expect(status.media_attachments.map(&:description)).to include('*' * MediaAttachment::MAX_DESCRIPTION_HARD_LENGTH_LIMIT) end end @@ -682,19 +682,19 @@ RSpec.describe ActivityPub::Activity::Create do type: 'Document', mediaType: 'image/png', url: 'http://example.com/attachment.png', - summary: '*' * MediaAttachment::MAX_DESCRIPTION_LENGTH, + summary: '*' * (MediaAttachment::MAX_DESCRIPTION_HARD_LENGTH_LIMIT + 5), }, ] ) end - it 'creates status' do + it 'creates status with truncated description' do expect { subject.perform }.to change(sender.statuses, :count).by(1) status = sender.statuses.first expect(status).to_not be_nil - expect(status.media_attachments.map(&:description)).to include('*' * MediaAttachment::MAX_DESCRIPTION_LENGTH) + expect(status.media_attachments.map(&:description)).to include('*' * MediaAttachment::MAX_DESCRIPTION_HARD_LENGTH_LIMIT) end end diff --git a/spec/models/collection_spec.rb b/spec/models/collection_spec.rb index 0a04473d56..67b51fdcea 100644 --- a/spec/models/collection_spec.rb +++ b/spec/models/collection_spec.rb @@ -124,6 +124,28 @@ RSpec.describe Collection do expect(subject.items_for(account)).to match_array(accepted_items + [pending_item]) end end + + context 'when `include_accounts` is set to `true`' do + it 'preloads accounts' do + items = subject.items_for(include_accounts: true).to_a + + expect { items.first.account }.to_not execute_queries + end + end + + context 'when called multiple times' do + let(:account) { subject.account } + + it 'memoizes results' do + subject.items_for.to_a + + expect { subject.items_for.to_a }.to_not execute_queries + + expect { subject.items_for(account).to_a }.to execute_queries + + expect { subject.items_for(account).to_a }.to_not execute_queries + end + end end describe '#tag_name=' do @@ -199,16 +221,4 @@ RSpec.describe Collection do expect(subject.to_log_permalink).to eq ActivityPub::TagManager.instance.uri_for(subject) end end - - describe '#top_items' do - let(:collection) { Fabricate(:collection) } - - before do - 5.times { |i| Fabricate(:collection_item, collection:, position: i + 1) } - end - - it 'returns the topmost four items' do - expect(collection.top_items.map(&:position)).to contain_exactly(1, 2, 3, 4) - end - end end diff --git a/spec/presenters/collections_presenter_spec.rb b/spec/presenters/collections_presenter_spec.rb deleted file mode 100644 index 7207637481..0000000000 --- a/spec/presenters/collections_presenter_spec.rb +++ /dev/null @@ -1,48 +0,0 @@ -# frozen_string_literal: true - -require 'rails_helper' - -RSpec.describe CollectionsPresenter do - subject { described_class.new(collections:) } - - let(:collection_owner_one) { Fabricate(:account) } - let(:collection_owner_two) { Fabricate(:account) } - let(:collection_one) do - Fabricate(:collection, - account: collection_owner_one, - name: 'Exquisite follows') - end - let(:collection_two) do - Fabricate(:collection, - account: collection_owner_two, - name: 'Excellent people') - end - let(:collections) { [collection_one, collection_two] } - - describe '#accounts' do - context 'when collections do not have any items' do - it 'includes only the collection owners' do - expect(subject.accounts).to contain_exactly(collection_owner_one, collection_owner_two) - end - end - - context 'when collections include accounts' do - let(:accounts) { Fabricate.times(3, :account) } - - before do - accounts[0..1].each { |a| Fabricate(:collection_item, collection: collection_one, account: a) } - accounts[1..2].each { |a| Fabricate(:collection_item, collection: collection_two, account: a) } - end - - it 'includes collection owners and unique preview accounts' do - expect(subject.accounts).to contain_exactly( - collection_owner_one, - collection_owner_two, - accounts[0], - accounts[1], - accounts[2] - ) - end - end - end -end diff --git a/spec/serializers/rest/collections_with_account_previews_serializer_spec.rb b/spec/serializers/rest/collections_with_account_previews_serializer_spec.rb deleted file mode 100644 index 3d65f6c99d..0000000000 --- a/spec/serializers/rest/collections_with_account_previews_serializer_spec.rb +++ /dev/null @@ -1,45 +0,0 @@ -# frozen_string_literal: true - -require 'rails_helper' - -RSpec.describe REST::CollectionsWithAccountPreviewsSerializer do - subject do - serialized_record_json(presenter, described_class, options: { - scope_name: :current_user, scope: nil - }) - end - - let(:collection_owner_one) { Fabricate(:account) } - let(:collection_owner_two) { Fabricate(:account) } - let(:featured_account) { Fabricate(:account) } - let(:collection_one) do - Fabricate(:collection, - account: collection_owner_one, - name: 'Exquisite follows') - end - let(:collection_two) do - Fabricate(:collection, - account: collection_owner_two, - name: 'Excellent people') - end - let(:collections) { [collection_one, collection_two] } - let(:presenter) { CollectionsPresenter.new(collections:) } - - before do - Fabricate(:collection_item, collection: collection_one, account: featured_account) - end - - it 'includes collections and partial accounts with the expected attributes' do - expect(subject).to include({ - 'collections' => [ - a_hash_including({ 'name' => 'Exquisite follows' }), - a_hash_including({ 'name' => 'Excellent people' }), - ], - 'partial_accounts' => [ - a_hash_including({ 'id' => collection_owner_one.id.to_s }), - a_hash_including({ 'id' => collection_owner_two.id.to_s }), - a_hash_including({ 'id' => featured_account.id.to_s }), - ], - }) - end -end diff --git a/streaming/package.json b/streaming/package.json index 8308c47032..a8ebc63b78 100644 --- a/streaming/package.json +++ b/streaming/package.json @@ -3,7 +3,7 @@ "license": "AGPL-3.0-or-later", "packageManager": "yarn@4.14.1", "engines": { - "node": ">=20" + "node": ">=22" }, "description": "Mastodon's Streaming Server", "private": true, diff --git a/yarn.lock b/yarn.lock index 2aee507a18..f01ab7f7c1 100644 --- a/yarn.lock +++ b/yarn.lock @@ -3002,7 +3002,7 @@ __metadata: intl-messageformat: "npm:^11.0.0" js-yaml: "npm:^4.1.0" lande: "npm:^1.0.10" - lint-staged: "npm:^16.2.6" + lint-staged: "npm:^17.0.0" lodash: "npm:^4.17.21" marky: "npm:^1.2.5" msw: "npm:^2.12.1" @@ -6153,10 +6153,10 @@ __metadata: languageName: node linkType: hard -"ansi-styles@npm:^6.1.0, ansi-styles@npm:^6.2.1": - version: 6.2.1 - resolution: "ansi-styles@npm:6.2.1" - checksum: 10c0/5d1ec38c123984bcedd996eac680d548f31828bd679a66db2bdf11844634dde55fec3efa9c6bb1d89056a5e79c1ac540c4c784d592ea1d25028a92227d2f2d5c +"ansi-styles@npm:^6.1.0, ansi-styles@npm:^6.2.1, ansi-styles@npm:^6.2.3": + version: 6.2.3 + resolution: "ansi-styles@npm:6.2.3" + checksum: 10c0/23b8a4ce14e18fb854693b95351e286b771d23d8844057ed2e7d083cd3e708376c3323707ec6a24365f7d7eda3ca00327fe04092e29e551499ec4c8b7bfac868 languageName: node linkType: hard @@ -6865,13 +6865,13 @@ __metadata: languageName: node linkType: hard -"cli-truncate@npm:^5.0.0": - version: 5.1.0 - resolution: "cli-truncate@npm:5.1.0" +"cli-truncate@npm:^5.2.0": + version: 5.2.0 + resolution: "cli-truncate@npm:5.2.0" dependencies: - slice-ansi: "npm:^7.1.0" - string-width: "npm:^8.0.0" - checksum: 10c0/388a4c9813372fb82ef3958af9bcf233419e80f4f435386cc83666ba85c9ccfdaa4dd6e47a9fde8f70b1e2b485cfc5da97bc899ce4f3b24ed04933a2f878f7d6 + slice-ansi: "npm:^8.0.0" + string-width: "npm:^8.2.0" + checksum: 10c0/0d4ec94702ca85b64522ac93633837fb5ea7db17b79b1322a60f6045e6ae2b8cd7bd4c1d19ac7d1f9e10e3bbda1112e172e439b68c02b785ee00da8d6a5c5471 languageName: node linkType: hard @@ -6948,7 +6948,7 @@ __metadata: languageName: node linkType: hard -"colorette@npm:^2.0.20, colorette@npm:^2.0.7": +"colorette@npm:^2.0.7": version: 2.0.20 resolution: "colorette@npm:2.0.20" checksum: 10c0/e94116ff33b0ff56f3b83b9ace895e5bf87c2a7a47b3401b8c3f3226e050d5ef76cf4072fb3325f9dc24d1698f9b730baf4e05eeaf861d74a1883073f4c98a40 @@ -6964,13 +6964,6 @@ __metadata: languageName: node linkType: hard -"commander@npm:^14.0.3": - version: 14.0.3 - resolution: "commander@npm:14.0.3" - checksum: 10c0/755652564bbf56ff2ff083313912b326450d3f8d8c85f4b71416539c9a05c3c67dbd206821ca72635bf6b160e2afdefcb458e86b317827d5cb333b69ce7f1a24 - languageName: node - linkType: hard - "commander@npm:^2.20.0": version: 2.20.3 resolution: "commander@npm:2.20.3" @@ -8455,10 +8448,10 @@ __metadata: languageName: node linkType: hard -"eventemitter3@npm:^5.0.1": - version: 5.0.1 - resolution: "eventemitter3@npm:5.0.1" - checksum: 10c0/4ba5c00c506e6c786b4d6262cfbce90ddc14c10d4667e5c83ae993c9de88aa856033994dd2b35b83e8dc1170e224e66a319fa80adc4c32adcd2379bbc75da814 +"eventemitter3@npm:^5.0.4": + version: 5.0.4 + resolution: "eventemitter3@npm:5.0.4" + checksum: 10c0/575b8cac8d709e1473da46f8f15ef311b57ff7609445a7c71af5cd42598583eee6f098fa7a593e30f27e94b8865642baa0689e8fa97c016f742abdb3b1bf6d9a languageName: node linkType: hard @@ -8889,10 +8882,10 @@ __metadata: languageName: node linkType: hard -"get-east-asian-width@npm:^1.0.0, get-east-asian-width@npm:^1.5.0": - version: 1.5.0 - resolution: "get-east-asian-width@npm:1.5.0" - checksum: 10c0/bff8bbc8d81790b9477f7aa55b1806b9f082a8dc1359fff7bd8b96939622c86b729685afc2bfeb22def1fc6ef1e5228e4d87dd4e6da60bc43a5edfb03c4ee167 +"get-east-asian-width@npm:^1.0.0, get-east-asian-width@npm:^1.3.1, get-east-asian-width@npm:^1.5.0": + version: 1.6.0 + resolution: "get-east-asian-width@npm:1.6.0" + checksum: 10c0/7e72e9550fd49ca5b246f9af6bb2afc129c96412845ff6556b3274fd44817a381702ca17028efe9866b261a3d44254cbf21e6c90cf05b4b61675630af776d431 languageName: node linkType: hard @@ -9725,12 +9718,12 @@ __metadata: languageName: node linkType: hard -"is-fullwidth-code-point@npm:^5.0.0": - version: 5.0.0 - resolution: "is-fullwidth-code-point@npm:5.0.0" +"is-fullwidth-code-point@npm:^5.0.0, is-fullwidth-code-point@npm:^5.1.0": + version: 5.1.0 + resolution: "is-fullwidth-code-point@npm:5.1.0" dependencies: - get-east-asian-width: "npm:^1.0.0" - checksum: 10c0/cd591b27d43d76b05fa65ed03eddce57a16e1eca0b7797ff7255de97019bcaf0219acfc0c4f7af13319e13541f2a53c0ace476f442b13267b9a6a7568f2b65c8 + get-east-asian-width: "npm:^1.3.1" + checksum: 10c0/c1172c2e417fb73470c56c431851681591f6a17233603a9e6f94b7ba870b2e8a5266506490573b607fb1081318589372034aa436aec07b465c2029c0bc7f07a4 languageName: node linkType: hard @@ -10516,33 +10509,34 @@ __metadata: languageName: node linkType: hard -"lint-staged@npm:^16.2.6": - version: 16.4.0 - resolution: "lint-staged@npm:16.4.0" +"lint-staged@npm:^17.0.0": + version: 17.0.5 + resolution: "lint-staged@npm:17.0.5" dependencies: - commander: "npm:^14.0.3" - listr2: "npm:^9.0.5" - picomatch: "npm:^4.0.3" + listr2: "npm:^10.2.1" + picomatch: "npm:^4.0.4" string-argv: "npm:^0.3.2" - tinyexec: "npm:^1.0.4" - yaml: "npm:^2.8.2" + tinyexec: "npm:^1.1.2" + yaml: "npm:^2.8.4" + dependenciesMeta: + yaml: + optional: true bin: lint-staged: bin/lint-staged.js - checksum: 10c0/67625a49a2a01368c7df2da7e553567a79c4b261d9faf3436e00fc3a2f9c4bbe7295909012c47b3d9029e269fd7d7469901a5120573527a032f15797aa497c26 + checksum: 10c0/6ecf2024744147ea768dbd550c0c47f04b295f07d30e5ecb5e375c18d8fc24d4bfa897042f4aabd7c3510054ad5bbbb51fa36e60e8dca853e31f9876ef9a3726 languageName: node linkType: hard -"listr2@npm:^9.0.5": - version: 9.0.5 - resolution: "listr2@npm:9.0.5" +"listr2@npm:^10.2.1": + version: 10.2.1 + resolution: "listr2@npm:10.2.1" dependencies: - cli-truncate: "npm:^5.0.0" - colorette: "npm:^2.0.20" - eventemitter3: "npm:^5.0.1" + cli-truncate: "npm:^5.2.0" + eventemitter3: "npm:^5.0.4" log-update: "npm:^6.1.0" rfdc: "npm:^1.4.1" - wrap-ansi: "npm:^9.0.0" - checksum: 10c0/46448d1ba0addc9d71aeafd05bb8e86ded9641ccad930ac302c2bd2ad71580375604743e18586fcb8f11906edf98e8e17fca75ba0759947bf275d381f68e311d + wrap-ansi: "npm:^10.0.0" + checksum: 10c0/a381a7aaef2e8625e6e882835ef446d14306c8fa371b56c4499cf23ece86f84922008af11962bfba5411b51589e02d280bea2b820451a2efad89ebf78bbe68a4 languageName: node linkType: hard @@ -14113,6 +14107,16 @@ __metadata: languageName: node linkType: hard +"slice-ansi@npm:^8.0.0": + version: 8.0.0 + resolution: "slice-ansi@npm:8.0.0" + dependencies: + ansi-styles: "npm:^6.2.3" + is-fullwidth-code-point: "npm:^5.1.0" + checksum: 10c0/0ce4aa91febb7cea4a00c2c27bb820fa53b6d2862ce0f80f7120134719f7914fc416b0ed966cf35250a3169e152916392f35917a2d7cad0fcc5d8b841010fa9a + languageName: node + linkType: hard + "smart-buffer@npm:^4.2.0": version: 4.2.0 resolution: "smart-buffer@npm:4.2.0" @@ -14417,7 +14421,7 @@ __metadata: languageName: node linkType: hard -"string-width@npm:^8.0.0, string-width@npm:^8.2.0": +"string-width@npm:^8.2.0": version: 8.2.1 resolution: "string-width@npm:8.2.1" dependencies: @@ -14942,7 +14946,7 @@ __metadata: languageName: node linkType: hard -"tinyexec@npm:^1.0.2, tinyexec@npm:^1.0.4": +"tinyexec@npm:^1.0.2, tinyexec@npm:^1.1.2": version: 1.1.2 resolution: "tinyexec@npm:1.1.2" checksum: 10c0/9e0ef6c001ce54688cf16833a02f70a339276219ca947b88930b124267de2cffc764ff44e87e7369384b1d75ab63491465412cbbdf06f2437956b9ab66ab4491 @@ -16283,6 +16287,17 @@ __metadata: languageName: node linkType: hard +"wrap-ansi@npm:^10.0.0": + version: 10.0.0 + resolution: "wrap-ansi@npm:10.0.0" + dependencies: + ansi-styles: "npm:^6.2.3" + string-width: "npm:^8.2.0" + strip-ansi: "npm:^7.1.2" + checksum: 10c0/6b163457630fe6d1c72aeed283a7410b2cc7487312df8b0ce96df3fbd64a2a7c948856ea97c25148c848627587c5c7945be474d8e723ab6011bb0756a53a9e89 + languageName: node + linkType: hard + "wrap-ansi@npm:^6.2.0": version: 6.2.0 resolution: "wrap-ansi@npm:6.2.0" @@ -16422,12 +16437,12 @@ __metadata: languageName: node linkType: hard -"yaml@npm:^2.8.2": - version: 2.8.4 - resolution: "yaml@npm:2.8.4" +"yaml@npm:^2.8.4": + version: 2.9.0 + resolution: "yaml@npm:2.9.0" bin: yaml: bin.mjs - checksum: 10c0/0a33a1fa28d4bc79f61a12ec7ef7a2bce0ce5f8e80c6eaecfb4a0c88c08767dd1ede372b6a3bcd70891213b8c9f3169b355c97e77026d3b3459e10d2cccaef1e + checksum: 10c0/f340718df45e97a9551b9bf9dac61c80050bc464513b710debfb5067c380c8472e3b67809cffacb4ab5ffb5e66ef9310816c88b05f371cec60abfedd8c88e0a2 languageName: node linkType: hard