mirror of
https://github.com/glitch-soc/mastodon.git
synced 2025-12-13 07:49:29 +00:00
Compare commits
40 Commits
v4.5.0-rc.
...
v4.5.0
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
4684d5e69b | ||
|
|
3ca92c4ae2 | ||
|
|
81b1a34d96 | ||
|
|
26c78392f8 | ||
|
|
caecc88247 | ||
|
|
bed4ca26e2 | ||
|
|
5d108e95d7 | ||
|
|
8a2d38a47b | ||
|
|
048430f4e8 | ||
|
|
d45b4db1d7 | ||
|
|
ef3a95affc | ||
|
|
3e6a9371b0 | ||
|
|
7ab0cfd637 | ||
|
|
b33bcc8be6 | ||
|
|
cdad6ee0c9 | ||
|
|
2d958cb909 | ||
|
|
949f15e200 | ||
|
|
105a2d64a7 | ||
|
|
1c17990413 | ||
|
|
0a8f96d3be | ||
|
|
1ec8e42dbb | ||
|
|
7ea3c6a039 | ||
|
|
e91c764590 | ||
|
|
cfdd9396c0 | ||
|
|
ba498ae779 | ||
|
|
5bae08d1ff | ||
|
|
5253527ec4 | ||
|
|
0b50789c5b | ||
|
|
a978e37f4c | ||
|
|
dd708298a8 | ||
|
|
449eb03f11 | ||
|
|
1baede0a7c | ||
|
|
a7ecfc1ca5 | ||
|
|
e62baacfc1 | ||
|
|
b5a6feb3bf | ||
|
|
05964f571b | ||
|
|
16a54f7158 | ||
|
|
6d53ca63d6 | ||
|
|
93acfdd7d3 | ||
|
|
a209b8e544 |
4
.github/workflows/build-releases.yml
vendored
4
.github/workflows/build-releases.yml
vendored
@@ -20,7 +20,7 @@ jobs:
|
||||
# Only tag with latest when ran against the latest stable branch
|
||||
# This needs to be updated after each minor version release
|
||||
flavor: |
|
||||
latest=${{ startsWith(github.ref, 'refs/tags/v4.3.') }}
|
||||
latest=${{ startsWith(github.ref, 'refs/tags/v4.5.') }}
|
||||
tags: |
|
||||
type=pep440,pattern={{raw}}
|
||||
type=pep440,pattern=v{{major}}.{{minor}}
|
||||
@@ -37,7 +37,7 @@ jobs:
|
||||
# Only tag with latest when ran against the latest stable branch
|
||||
# This needs to be updated after each minor version release
|
||||
flavor: |
|
||||
latest=${{ startsWith(github.ref, 'refs/tags/v4.3.') }}
|
||||
latest=${{ startsWith(github.ref, 'refs/tags/v4.5.') }}
|
||||
tags: |
|
||||
type=pep440,pattern={{raw}}
|
||||
type=pep440,pattern=v{{major}}.{{minor}}
|
||||
|
||||
21
CHANGELOG.md
21
CHANGELOG.md
@@ -2,17 +2,18 @@
|
||||
|
||||
All notable changes to this project will be documented in this file.
|
||||
|
||||
## [4.5.0] - UNRELEASED
|
||||
## [4.5.0] - 2025-11-06
|
||||
|
||||
### Added
|
||||
|
||||
- **Add support for allowing and authoring quotes** (#35355, #35578, #35614, #35618, #35624, #35626, #35652, #35629, #35665, #35653, #35670, #35677, #35690, #35697, #35689, #35699, #35700, #35701, #35709, #35714, #35713, #35715, #35725, #35749, #35769, #35780, #35762, #35804, #35808, #35805, #35819, #35824, #35828, #35822, #35835, #35865, #35860, #35832, #35891, #35894, #35895, #35820, #35917, #35924, #35925, #35914, #35930, #35941, #35939, #35948, #35955, #35967, #35990, #35991, #35975, #35971, #36002, #35986, #36031, #36034, #36038, #36054, #36052, #36055, #36065, #36068, #36083, #36087, #36080, #36091, #36090, #36118, #36119, #36128, #36094, #36129, #36138, #36132, #36151, #36158, #36171, #36194, #36220, #36169, #36130, #36249, #36153, #36299, #36291, #36301, #36315, #36317, #36364, #36383, #36381, #36459, #36464, #36461, #36516, #36528, #36549, #36550 and #36559 by @ChaosExAnima, @ClearlyClaire, @Lycolia, @diondiondion, and @tribela)\
|
||||
- **Add support for allowing and authoring quotes** (#35355, #35578, #35614, #35618, #35624, #35626, #35652, #35629, #35665, #35653, #35670, #35677, #35690, #35697, #35689, #35699, #35700, #35701, #35709, #35714, #35713, #35715, #35725, #35749, #35769, #35780, #35762, #35804, #35808, #35805, #35819, #35824, #35828, #35822, #35835, #35865, #35860, #35832, #35891, #35894, #35895, #35820, #35917, #35924, #35925, #35914, #35930, #35941, #35939, #35948, #35955, #35967, #35990, #35991, #35975, #35971, #36002, #35986, #36031, #36034, #36038, #36054, #36052, #36055, #36065, #36068, #36083, #36087, #36080, #36091, #36090, #36118, #36119, #36128, #36094, #36129, #36138, #36132, #36151, #36158, #36171, #36194, #36220, #36169, #36130, #36249, #36153, #36299, #36291, #36301, #36315, #36317, #36364, #36383, #36381, #36459, #36464, #36461, #36516, #36528, #36549, #36550, #36559, #36693, #36704, #36690, #36689, #36696, #36721, #36695 and #36736 by @ChaosExAnima, @ClearlyClaire, @Lycolia, @diondiondion, and @tribela)\
|
||||
This includes a revamp of the composer interface.\
|
||||
See https://blog.joinmastodon.org/2025/09/introducing-quote-posts/ for a user-centric overview of the feature, and https://docs.joinmastodon.org/client/quotes/ for API documentation.
|
||||
- **Add support for fetching and refreshing replies to the web UI** (#35210, #35496, #35575, #35500, #35577, #35602, #35603, #35654, #36141, #36237, #36172, #36256, #36271, #36334, #36382, #36239, #36484, #36481, #36583, #36627 and #36547 by @ClearlyClaire, @diondiondion, @Gargron and @renchap)
|
||||
- **Add ability to block words in usernames** (#35407, #35655, and #35806 by @ClearlyClaire and @Gargron)
|
||||
- Add ability to individually disable local or remote feeds for visitors or logged-in users `disabled` value to server setting for live and topic feeds, as well as user permission to bypass that (#36338, #36467, #36497, #36563, #36577, #36585, and #36607 by @ClearlyClaire)\
|
||||
This splits the `timeline_preview` setting into four more granular settings controlling live feeds and topic (hashtag, trending link) feeds, with 3 values each: `public`, `authenticated`, `disabled`.\
|
||||
- Add ability to individually disable local or remote feeds for visitors or logged-in users `disabled` value to server setting for live and topic feeds, as well as user permission to bypass that (#36338, #36467, #36497, #36563, #36577, #36585, #36607 and #36703 by @ClearlyClaire)\
|
||||
This splits the `timeline_preview` setting into four more granular settings controlling live feeds and topic (hashtag, trending link) feeds.\
|
||||
The setting for local topic feeds has 2 values: `public` and `authenticated`. Every other setting has 3 values: `public`, `authenticated`, `disabled`.\
|
||||
When `disabled`, users with the “View live and topic feeds” will still be able to view them.
|
||||
- Add support for displaying of quote posts in Moderator UI (#35964 by @ThisIsMissEm)
|
||||
- Add support for displaying link previews for Admin UI (#35958 by @ThisIsMissEm)
|
||||
@@ -20,21 +21,22 @@ All notable changes to this project will be documented in this file.
|
||||
- Add support for `Update` activities on converted object types (#36322 by @ClearlyClaire)
|
||||
- Add support for dynamic viewport height (#36272 by @e1berd)
|
||||
- Add support for numeric-based URIs for new local accounts (#32724, #36304, #36316, and #36365 by @ClearlyClaire)
|
||||
- Add default visualizer for audio upload without poster (#36734 by @ChaosExAnima)
|
||||
- Add Traditional Mongolian to posting languages (#36196 by @shimon1024)
|
||||
- Add example post with manual quote approval policy to `dev:populate_sample_data` (#36099 by @ClearlyClaire)
|
||||
- Add server-side support for handling posts with a quote policy allowing followers to quote (#36093 and #36127 by @ClearlyClaire)
|
||||
- Add schema.org markup to SEO-enabled posts (#36075 by @Gargron)
|
||||
- Add migration to fill unset default quote policy based on default post privacy (#36041 by @ClearlyClaire)
|
||||
- Add “Posting defaults” setting page, moving existing settings from “Other” (#35896, #36033, #35966, #35969, and #36084 by @ClearlyClaire and @diondiondion)
|
||||
- Added emoji from Twemoji v16 (#36501 and #36530 by @ChaosExAnima)
|
||||
- Add feature to select custom emoji rendering (#35229, #35282, #35253, #35424, #35473, #35483, #35505, #35568, #35605, #35659, #35664, #35739, #35985, #36051, #36071, #36137, #36165, #36248, #36262, #36275, #36293, #36341, #36342, #36366, #36377, #36378, #36385, #36393, #36397, #36403, #36413, #36410, #36454, #36402, #36503, #36502, #36532, #36603, #36409, #36638 and #36750 by @ChaosExAnima, @ClearlyClaire and @braddunbar)\
|
||||
This also completely reworks the processing and rendering of emojis and server-rendered HTML in statuses and other places.
|
||||
- Add support for exposing conversation context for new public conversations according to FEP-7888 (#35959 and #36064 by @ClearlyClaire and @jesseplusplus)
|
||||
- Add digest re-check before removing followers in synchronization mechanism (#34273 by @ClearlyClaire)
|
||||
- Add “Posting defaults” setting page, moving existing settings from “Other” (#35896, #36033, #35966, #35969, and #36084 by @ClearlyClaire and @diondiondion)
|
||||
- Add support for displaying Valkey version on admin dashboard (#35785 by @ykzts)
|
||||
- Add delivery failure tracking and handling to FASP jobs (#35625, #35628, and #35723 by @oneiros)
|
||||
- Add example of quote post with a preview card to development sample data (#35616 by @ClearlyClaire)
|
||||
- Add second set of blocked text that applies to accounts regardless of account age for spam-blocking (#35563 by @ClearlyClaire)
|
||||
- Added emoji from Twemoji v16 (#36501 and #36530 by @ChaosExAnima)
|
||||
- Add feature to select custom emoji rendering (#35229, #35282, #35253, #35424, #35473, #35483, #35505, #35568, #35605, #35659, #35664, #35739, #35985, #36051, #36071, #36137, #36165, #36248, #36262, #36275, #36293, #36341, #36342, #36366, #36377, #36378, #36385, #36393, #36397, #36403, #36413, #36410, #36454, #36402, #36503, #36502, #36532, #36603, #36409 and #36638 by @ChaosExAnima, @ClearlyClaire and @braddunbar)\
|
||||
This also completely reworks the processing and rendering of emojis and server-rendered HTML in statuses and other places.
|
||||
|
||||
### Changed
|
||||
|
||||
@@ -44,6 +46,8 @@ All notable changes to this project will be documented in this file.
|
||||
- Change display of blocked and muted quoted users (#36619 by @ClearlyClaire)\
|
||||
This adds `blocked_account`, `blocked_domain` and `muted_account` values to the `state` attribute of `Quote` and `ShallowQuote` REST API entities.
|
||||
- Change submitting an empty post to show an error rather than failing silently (#36650 by @diondiondion)
|
||||
- Change "Privacy and reach" settings from "Public profile" to their own top-level category (#27294 by @ChaelCodes)
|
||||
- Change number of times quote verification is retried to better deal with temporary failures (#36698 by @ClearlyClaire)
|
||||
- Change display of content warnings in Admin UI (#35935 by @ThisIsMissEm)
|
||||
- Change styling of column banners (#36531 by @ClearlyClaire)
|
||||
- Change recommended Node version to 24 (LTS) (#36539 by @renchap)
|
||||
@@ -75,6 +79,7 @@ All notable changes to this project will be documented in this file.
|
||||
- Fix URL comparison for mentions in case of empty path (#36613 and #36626 by @ClearlyClaire)
|
||||
- Fix hashtags not being picked up when full-width hash sign is used (#36103 and #36625 by @ClearlyClaire and @Gargron)
|
||||
- Fix layout of severed relationships when purged events are listed (#36593 by @mejofi)
|
||||
- Fix Skeleton placeholders being animated when setting to reduce animations is enabled (#36716 by @ClearlyClaire)
|
||||
- Fix vacuum tasks being interrupted by a single batch failure (#36606 by @Gargron)
|
||||
- Fix handling of unreachable network error for search services (#36587 by @mjankowski)
|
||||
- Fix bookmarks export when a bookmarked status is soft-deleted (#36576 by @ClearlyClaire)
|
||||
|
||||
14
Gemfile.lock
14
Gemfile.lock
@@ -128,7 +128,7 @@ GEM
|
||||
blurhash (0.1.8)
|
||||
bootsnap (1.18.6)
|
||||
msgpack (~> 1.2)
|
||||
brakeman (7.0.2)
|
||||
brakeman (7.1.1)
|
||||
racc
|
||||
browser (6.2.0)
|
||||
builder (3.3.0)
|
||||
@@ -224,7 +224,7 @@ GEM
|
||||
mail (~> 2.7)
|
||||
email_validator (2.2.4)
|
||||
activemodel
|
||||
erb (5.1.1)
|
||||
erb (5.1.3)
|
||||
erubi (1.13.1)
|
||||
et-orbi (1.4.0)
|
||||
tzinfo
|
||||
@@ -337,7 +337,7 @@ GEM
|
||||
activesupport (>= 3.0)
|
||||
nokogiri (>= 1.6)
|
||||
io-console (0.8.1)
|
||||
irb (1.15.2)
|
||||
irb (1.15.3)
|
||||
pp (>= 0.6.0)
|
||||
rdoc (>= 4.0.0)
|
||||
reline (>= 0.4.2)
|
||||
@@ -621,7 +621,7 @@ GEM
|
||||
activesupport (>= 3.0.0)
|
||||
raabro (1.4.0)
|
||||
racc (1.8.1)
|
||||
rack (3.2.3)
|
||||
rack (3.2.4)
|
||||
rack-attack (6.8.0)
|
||||
rack (>= 1.0, < 4)
|
||||
rack-cors (3.0.0)
|
||||
@@ -691,7 +691,7 @@ GEM
|
||||
readline (~> 0.0)
|
||||
rdf-normalize (0.7.0)
|
||||
rdf (~> 3.3)
|
||||
rdoc (6.15.0)
|
||||
rdoc (6.15.1)
|
||||
erb
|
||||
psych (>= 4.0.0)
|
||||
tsort
|
||||
@@ -791,7 +791,7 @@ GEM
|
||||
ruby-vips (2.2.5)
|
||||
ffi (~> 1.12)
|
||||
logger
|
||||
rubyzip (3.2.1)
|
||||
rubyzip (3.2.2)
|
||||
rufus-scheduler (3.9.2)
|
||||
fugit (~> 1.1, >= 1.11.1)
|
||||
safety_net_attestation (0.5.0)
|
||||
@@ -805,7 +805,7 @@ GEM
|
||||
securerandom (0.4.1)
|
||||
shoulda-matchers (6.5.0)
|
||||
activesupport (>= 5.2.0)
|
||||
sidekiq (8.0.8)
|
||||
sidekiq (8.0.9)
|
||||
connection_pool (>= 2.5.0)
|
||||
json (>= 2.9.0)
|
||||
logger (>= 1.6.2)
|
||||
|
||||
@@ -16,6 +16,6 @@ A "vulnerability in Mastodon" is a vulnerability in the code distributed through
|
||||
| Version | Supported |
|
||||
| ------- | ---------------- |
|
||||
| 4.4.x | Yes |
|
||||
| 4.3.x | Yes |
|
||||
| 4.3.x | Until 2026-05-06 |
|
||||
| 4.2.x | Until 2026-01-08 |
|
||||
| < 4.2 | No |
|
||||
|
||||
@@ -9,7 +9,7 @@ class ActivityPub::QuoteAuthorizationsController < ActivityPub::BaseController
|
||||
before_action :set_quote_authorization
|
||||
|
||||
def show
|
||||
expires_in 30.seconds, public: true if @quote.status.distributable? && public_fetch_mode?
|
||||
expires_in 30.seconds, public: true if @quote.quoted_status.distributable? && public_fetch_mode?
|
||||
render json: @quote, serializer: ActivityPub::QuoteAuthorizationSerializer, adapter: ActivityPub::Adapter, content_type: 'application/activity+json'
|
||||
end
|
||||
|
||||
@@ -23,7 +23,7 @@ class ActivityPub::QuoteAuthorizationsController < ActivityPub::BaseController
|
||||
@quote = Quote.accepted.where(quoted_account: @account).find(params[:id])
|
||||
return not_found unless @quote.status.present? && @quote.quoted_status.present?
|
||||
|
||||
authorize @quote.status, :show?
|
||||
authorize @quote.quoted_status, :show?
|
||||
rescue Mastodon::NotPermittedError
|
||||
not_found
|
||||
end
|
||||
|
||||
@@ -58,7 +58,6 @@ export const COMPOSE_ADVANCED_OPTIONS_CHANGE = 'COMPOSE_ADVANCED_OPTIONS_CHANGE'
|
||||
export const COMPOSE_SENSITIVITY_CHANGE = 'COMPOSE_SENSITIVITY_CHANGE';
|
||||
export const COMPOSE_SPOILERNESS_CHANGE = 'COMPOSE_SPOILERNESS_CHANGE';
|
||||
export const COMPOSE_SPOILER_TEXT_CHANGE = 'COMPOSE_SPOILER_TEXT_CHANGE';
|
||||
export const COMPOSE_VISIBILITY_CHANGE = 'COMPOSE_VISIBILITY_CHANGE';
|
||||
export const COMPOSE_COMPOSING_CHANGE = 'COMPOSE_COMPOSING_CHANGE';
|
||||
export const COMPOSE_CONTENT_TYPE_CHANGE = 'COMPOSE_CONTENT_TYPE_CHANGE';
|
||||
export const COMPOSE_LANGUAGE_CHANGE = 'COMPOSE_LANGUAGE_CHANGE';
|
||||
@@ -825,13 +824,6 @@ export function changeComposeSpoilerText(text) {
|
||||
};
|
||||
}
|
||||
|
||||
export function changeComposeVisibility(value) {
|
||||
return {
|
||||
type: COMPOSE_VISIBILITY_CHANGE,
|
||||
value,
|
||||
};
|
||||
}
|
||||
|
||||
export function insertEmojiCompose(position, emoji, needsSpace) {
|
||||
return {
|
||||
type: COMPOSE_EMOJI_INSERT,
|
||||
|
||||
@@ -13,10 +13,11 @@ import {
|
||||
} from 'flavours/glitch/store/typed_functions';
|
||||
|
||||
import type { ApiQuotePolicy } from '../api_types/quotes';
|
||||
import type { Status } from '../models/status';
|
||||
import type { Status, StatusVisibility } from '../models/status';
|
||||
import type { RootState } from '../store';
|
||||
|
||||
import { showAlert } from './alerts';
|
||||
import { focusCompose } from './compose';
|
||||
import { changeCompose, focusCompose } from './compose';
|
||||
import { importFetchedStatuses } from './importer';
|
||||
import { openModal } from './modal';
|
||||
|
||||
@@ -41,6 +42,10 @@ const messages = defineMessages({
|
||||
id: 'quote_error.unauthorized',
|
||||
defaultMessage: 'You are not authorized to quote this post.',
|
||||
},
|
||||
quoteErrorPrivateMention: {
|
||||
id: 'quote_error.private_mentions',
|
||||
defaultMessage: 'Quoting is not allowed with direct mentions.',
|
||||
},
|
||||
});
|
||||
|
||||
type SimulatedMediaAttachmentJSON = ApiMediaAttachmentJSON & {
|
||||
@@ -67,6 +72,39 @@ const simulateModifiedApiResponse = (
|
||||
return data;
|
||||
};
|
||||
|
||||
export const changeComposeVisibility = createAppThunk(
|
||||
'compose/visibility_change',
|
||||
(visibility: StatusVisibility, { dispatch, getState }) => {
|
||||
if (visibility !== 'direct') {
|
||||
return visibility;
|
||||
}
|
||||
|
||||
const state = getState();
|
||||
const quotedStatusId = state.compose.get('quoted_status_id') as
|
||||
| string
|
||||
| null;
|
||||
if (!quotedStatusId) {
|
||||
return visibility;
|
||||
}
|
||||
|
||||
// Remove the quoted status
|
||||
dispatch(quoteComposeCancel());
|
||||
const quotedStatus = state.statuses.get(quotedStatusId) as Status | null;
|
||||
if (!quotedStatus) {
|
||||
return visibility;
|
||||
}
|
||||
|
||||
// Append the quoted status URL to the compose text
|
||||
const url = quotedStatus.get('url') as string;
|
||||
const text = state.compose.get('text') as string;
|
||||
if (!text.includes(url)) {
|
||||
const newText = text.trim() ? `${text}\n\n${url}` : url;
|
||||
dispatch(changeCompose(newText));
|
||||
}
|
||||
return visibility;
|
||||
},
|
||||
);
|
||||
|
||||
export const changeUploadCompose = createDataLoadingThunk(
|
||||
'compose/changeUpload',
|
||||
async (
|
||||
@@ -130,6 +168,8 @@ export const quoteComposeByStatus = createAppThunk(
|
||||
|
||||
if (composeState.get('id')) {
|
||||
dispatch(showAlert({ message: messages.quoteErrorEdit }));
|
||||
} else if (composeState.get('privacy') === 'direct') {
|
||||
dispatch(showAlert({ message: messages.quoteErrorPrivateMention }));
|
||||
} else if (composeState.get('poll')) {
|
||||
dispatch(showAlert({ message: messages.quoteErrorPoll }));
|
||||
} else if (
|
||||
@@ -173,6 +213,17 @@ export const quoteComposeById = createAppThunk(
|
||||
},
|
||||
);
|
||||
|
||||
const composeStateForbidsLink = (composeState: RootState['compose']) => {
|
||||
return (
|
||||
composeState.get('quoted_status_id') ||
|
||||
composeState.get('is_submitting') ||
|
||||
composeState.get('poll') ||
|
||||
composeState.get('is_uploading') ||
|
||||
composeState.get('id') ||
|
||||
composeState.get('privacy') === 'direct'
|
||||
);
|
||||
};
|
||||
|
||||
export const pasteLinkCompose = createDataLoadingThunk(
|
||||
'compose/pasteLink',
|
||||
async ({ url }: { url: string }) => {
|
||||
@@ -183,15 +234,12 @@ export const pasteLinkCompose = createDataLoadingThunk(
|
||||
limit: 2,
|
||||
});
|
||||
},
|
||||
(data, { dispatch, getState }) => {
|
||||
(data, { dispatch, getState, requestId }) => {
|
||||
const composeState = getState().compose;
|
||||
|
||||
if (
|
||||
composeState.get('quoted_status_id') ||
|
||||
composeState.get('is_submitting') ||
|
||||
composeState.get('poll') ||
|
||||
composeState.get('is_uploading') ||
|
||||
composeState.get('id')
|
||||
composeStateForbidsLink(composeState) ||
|
||||
composeState.get('fetching_link') !== requestId // Request has been cancelled
|
||||
)
|
||||
return;
|
||||
|
||||
@@ -207,6 +255,17 @@ export const pasteLinkCompose = createDataLoadingThunk(
|
||||
dispatch(quoteComposeById(data.statuses[0].id));
|
||||
}
|
||||
},
|
||||
{
|
||||
useLoadingBar: false,
|
||||
condition: (_, { getState }) =>
|
||||
!getState().compose.get('fetching_link') &&
|
||||
!composeStateForbidsLink(getState().compose),
|
||||
},
|
||||
);
|
||||
|
||||
// Ideally this would cancel the action and the HTTP request, but this is good enough
|
||||
export const cancelPasteLinkCompose = createAction(
|
||||
'compose/cancelPasteLinkCompose',
|
||||
);
|
||||
|
||||
export const quoteComposeCancel = createAction('compose/quoteComposeCancel');
|
||||
|
||||
@@ -49,6 +49,7 @@ export const StatusBanner: React.FC<{
|
||||
|
||||
<button
|
||||
ref={buttonRef}
|
||||
type='button'
|
||||
className='link-button'
|
||||
onClick={onClick}
|
||||
aria-describedby={descriptionId}
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
import { useEffect, useRef, useCallback, useState, useId } from 'react';
|
||||
import { useEffect, useRef, useCallback, useState } from 'react';
|
||||
|
||||
import { defineMessages, useIntl, FormattedMessage } from 'react-intl';
|
||||
|
||||
@@ -22,6 +22,8 @@ import { useAudioVisualizer } from 'flavours/glitch/hooks/useAudioVisualizer';
|
||||
import { displayMedia, useBlurhash } from 'flavours/glitch/initial_state';
|
||||
import { playerSettings } from 'flavours/glitch/settings';
|
||||
|
||||
import { AudioVisualizer } from './visualizer';
|
||||
|
||||
const messages = defineMessages({
|
||||
play: { id: 'video.play', defaultMessage: 'Play' },
|
||||
pause: { id: 'video.pause', defaultMessage: 'Pause' },
|
||||
@@ -116,7 +118,6 @@ export const Audio: React.FC<{
|
||||
const seekRef = useRef<HTMLDivElement>(null);
|
||||
const volumeRef = useRef<HTMLDivElement>(null);
|
||||
const hoverTimeoutRef = useRef<ReturnType<typeof setTimeout> | null>();
|
||||
const accessibilityId = useId();
|
||||
|
||||
const { audioContextRef, sourceRef, gainNodeRef, playAudio, pauseAudio } =
|
||||
useAudioContext({ audioElementRef: audioRef });
|
||||
@@ -538,19 +539,6 @@ export const Audio: React.FC<{
|
||||
[togglePlay, toggleMute],
|
||||
);
|
||||
|
||||
const springForBand0 = useSpring({
|
||||
to: { r: 50 + (frequencyBands[0] ?? 0) * 10 },
|
||||
config: config.wobbly,
|
||||
});
|
||||
const springForBand1 = useSpring({
|
||||
to: { r: 50 + (frequencyBands[1] ?? 0) * 10 },
|
||||
config: config.wobbly,
|
||||
});
|
||||
const springForBand2 = useSpring({
|
||||
to: { r: 50 + (frequencyBands[2] ?? 0) * 10 },
|
||||
config: config.wobbly,
|
||||
});
|
||||
|
||||
const progress = Math.min((currentTime / loadedDuration) * 100, 100);
|
||||
const effectivelyMuted = muted || volume === 0;
|
||||
|
||||
@@ -641,81 +629,7 @@ export const Audio: React.FC<{
|
||||
</div>
|
||||
|
||||
<div className='audio-player__controls__play'>
|
||||
<svg
|
||||
className='audio-player__visualizer'
|
||||
viewBox='0 0 124 124'
|
||||
xmlns='http://www.w3.org/2000/svg'
|
||||
>
|
||||
<animated.circle
|
||||
opacity={0.5}
|
||||
cx={57}
|
||||
cy={62.5}
|
||||
r={springForBand0.r}
|
||||
fill='var(--player-accent-color)'
|
||||
/>
|
||||
<animated.circle
|
||||
opacity={0.5}
|
||||
cx={65}
|
||||
cy={57.5}
|
||||
r={springForBand1.r}
|
||||
fill='var(--player-accent-color)'
|
||||
/>
|
||||
<animated.circle
|
||||
opacity={0.5}
|
||||
cx={63}
|
||||
cy={66.5}
|
||||
r={springForBand2.r}
|
||||
fill='var(--player-accent-color)'
|
||||
/>
|
||||
|
||||
<g clipPath={`url(#${accessibilityId}-clip)`}>
|
||||
<rect
|
||||
x={14}
|
||||
y={14}
|
||||
width={96}
|
||||
height={96}
|
||||
fill={`url(#${accessibilityId}-pattern)`}
|
||||
/>
|
||||
<rect
|
||||
x={14}
|
||||
y={14}
|
||||
width={96}
|
||||
height={96}
|
||||
fill='var(--player-background-color'
|
||||
opacity={0.45}
|
||||
/>
|
||||
</g>
|
||||
|
||||
<defs>
|
||||
<pattern
|
||||
id={`${accessibilityId}-pattern`}
|
||||
patternContentUnits='objectBoundingBox'
|
||||
width='1'
|
||||
height='1'
|
||||
>
|
||||
<use href={`#${accessibilityId}-image`} />
|
||||
</pattern>
|
||||
|
||||
<clipPath id={`${accessibilityId}-clip`}>
|
||||
<rect
|
||||
x={14}
|
||||
y={14}
|
||||
width={96}
|
||||
height={96}
|
||||
rx={48}
|
||||
fill='white'
|
||||
/>
|
||||
</clipPath>
|
||||
|
||||
<image
|
||||
id={`${accessibilityId}-image`}
|
||||
href={poster}
|
||||
width={1}
|
||||
height={1}
|
||||
preserveAspectRatio='none'
|
||||
/>
|
||||
</defs>
|
||||
</svg>
|
||||
<AudioVisualizer frequencyBands={frequencyBands} poster={poster} />
|
||||
|
||||
<button
|
||||
type='button'
|
||||
|
||||
100
app/javascript/flavours/glitch/features/audio/visualizer.tsx
Normal file
100
app/javascript/flavours/glitch/features/audio/visualizer.tsx
Normal file
@@ -0,0 +1,100 @@
|
||||
import { useId } from 'react';
|
||||
import type { FC } from 'react';
|
||||
|
||||
import { animated, config, useSpring } from '@react-spring/web';
|
||||
|
||||
interface AudioVisualizerProps {
|
||||
frequencyBands?: number[];
|
||||
poster?: string;
|
||||
}
|
||||
|
||||
export const AudioVisualizer: FC<AudioVisualizerProps> = ({
|
||||
frequencyBands = [],
|
||||
poster,
|
||||
}) => {
|
||||
const accessibilityId = useId();
|
||||
|
||||
const springForBand0 = useSpring({
|
||||
to: { r: 50 + (frequencyBands[0] ?? 0) * 10 },
|
||||
config: config.wobbly,
|
||||
});
|
||||
const springForBand1 = useSpring({
|
||||
to: { r: 50 + (frequencyBands[1] ?? 0) * 10 },
|
||||
config: config.wobbly,
|
||||
});
|
||||
const springForBand2 = useSpring({
|
||||
to: { r: 50 + (frequencyBands[2] ?? 0) * 10 },
|
||||
config: config.wobbly,
|
||||
});
|
||||
|
||||
return (
|
||||
<svg
|
||||
className='audio-player__visualizer'
|
||||
viewBox='0 0 124 124'
|
||||
xmlns='http://www.w3.org/2000/svg'
|
||||
>
|
||||
<animated.circle
|
||||
opacity={0.5}
|
||||
cx={57}
|
||||
cy={62.5}
|
||||
r={springForBand0.r}
|
||||
fill='var(--player-accent-color)'
|
||||
/>
|
||||
<animated.circle
|
||||
opacity={0.5}
|
||||
cx={65}
|
||||
cy={57.5}
|
||||
r={springForBand1.r}
|
||||
fill='var(--player-accent-color)'
|
||||
/>
|
||||
<animated.circle
|
||||
opacity={0.5}
|
||||
cx={63}
|
||||
cy={66.5}
|
||||
r={springForBand2.r}
|
||||
fill='var(--player-accent-color)'
|
||||
/>
|
||||
|
||||
<g clipPath={`url(#${accessibilityId}-clip)`}>
|
||||
<rect
|
||||
x={14}
|
||||
y={14}
|
||||
width={96}
|
||||
height={96}
|
||||
fill={`url(#${accessibilityId}-pattern)`}
|
||||
/>
|
||||
<rect
|
||||
x={14}
|
||||
y={14}
|
||||
width={96}
|
||||
height={96}
|
||||
fill='var(--player-background-color'
|
||||
opacity={0.45}
|
||||
/>
|
||||
</g>
|
||||
|
||||
<defs>
|
||||
<pattern
|
||||
id={`${accessibilityId}-pattern`}
|
||||
patternContentUnits='objectBoundingBox'
|
||||
width='1'
|
||||
height='1'
|
||||
>
|
||||
<use href={`#${accessibilityId}-image`} />
|
||||
</pattern>
|
||||
|
||||
<clipPath id={`${accessibilityId}-clip`}>
|
||||
<rect x={14} y={14} width={96} height={96} rx={48} fill='white' />
|
||||
</clipPath>
|
||||
|
||||
<image
|
||||
id={`${accessibilityId}-image`}
|
||||
href={poster}
|
||||
width={1}
|
||||
height={1}
|
||||
preserveAspectRatio='none'
|
||||
/>
|
||||
</defs>
|
||||
</svg>
|
||||
);
|
||||
};
|
||||
@@ -155,7 +155,11 @@ class ComposeForm extends ImmutablePureComponent {
|
||||
return;
|
||||
}
|
||||
|
||||
this.props.onSubmit(missingAltTextModal && this.props.missingAltText && this.props.privacy !== 'direct', overridePrivacy);
|
||||
this.props.onSubmit({
|
||||
missingAltTextModal: missingAltTextModal && this.props.missingAltText && this.props.privacy !== 'direct',
|
||||
quoteToPrivate: this.props.quoteToPrivate,
|
||||
overridePrivacy,
|
||||
});
|
||||
|
||||
if (e) {
|
||||
e.preventDefault();
|
||||
|
||||
@@ -0,0 +1,48 @@
|
||||
import { useCallback } from 'react';
|
||||
import type { FC } from 'react';
|
||||
|
||||
import { defineMessages, useIntl } from 'react-intl';
|
||||
|
||||
import { cancelPasteLinkCompose } from '@/flavours/glitch/actions/compose_typed';
|
||||
import { useAppDispatch } from '@/flavours/glitch/store';
|
||||
import CancelFillIcon from '@/material-icons/400-24px/cancel-fill.svg?react';
|
||||
import { DisplayName } from 'flavours/glitch/components/display_name';
|
||||
import { IconButton } from 'flavours/glitch/components/icon_button';
|
||||
import { Skeleton } from 'flavours/glitch/components/skeleton';
|
||||
|
||||
const messages = defineMessages({
|
||||
quote_cancel: { id: 'status.quote.cancel', defaultMessage: 'Cancel quote' },
|
||||
});
|
||||
|
||||
export const QuotePlaceholder: FC = () => {
|
||||
const intl = useIntl();
|
||||
const dispatch = useAppDispatch();
|
||||
const handleQuoteCancel = useCallback(() => {
|
||||
dispatch(cancelPasteLinkCompose());
|
||||
}, [dispatch]);
|
||||
|
||||
return (
|
||||
<div className='status__quote'>
|
||||
<div className='status'>
|
||||
<div className='status__info'>
|
||||
<div className='status__avatar'>
|
||||
<Skeleton width='32px' height='32px' />
|
||||
</div>
|
||||
<div className='status__display-name'>
|
||||
<DisplayName />
|
||||
</div>
|
||||
<IconButton
|
||||
onClick={handleQuoteCancel}
|
||||
className='status__quote-cancel'
|
||||
title={intl.formatMessage(messages.quote_cancel)}
|
||||
icon='cancel-fill'
|
||||
iconComponent={CancelFillIcon}
|
||||
/>
|
||||
</div>
|
||||
<div className='status__content'>
|
||||
<Skeleton />
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
);
|
||||
};
|
||||
@@ -7,11 +7,17 @@ import { quoteComposeCancel } from '@/flavours/glitch/actions/compose_typed';
|
||||
import { QuotedStatus } from '@/flavours/glitch/components/status_quoted';
|
||||
import { useAppDispatch, useAppSelector } from '@/flavours/glitch/store';
|
||||
|
||||
import { QuotePlaceholder } from './quote_placeholder';
|
||||
|
||||
export const ComposeQuotedStatus: FC = () => {
|
||||
const quotedStatusId = useAppSelector(
|
||||
(state) => state.compose.get('quoted_status_id') as string | null,
|
||||
);
|
||||
|
||||
const isFetchingLink = useAppSelector(
|
||||
(state) => !!state.compose.get('fetching_link'),
|
||||
);
|
||||
|
||||
const isEditing = useAppSelector((state) => !!state.compose.get('id'));
|
||||
|
||||
const quote = useMemo(
|
||||
@@ -30,7 +36,9 @@ export const ComposeQuotedStatus: FC = () => {
|
||||
dispatch(quoteComposeCancel());
|
||||
}, [dispatch]);
|
||||
|
||||
if (!quote) {
|
||||
if (isFetchingLink && !quote) {
|
||||
return <QuotePlaceholder />;
|
||||
} else if (!quote) {
|
||||
return null;
|
||||
}
|
||||
|
||||
|
||||
@@ -10,6 +10,7 @@ import { useSortable } from '@dnd-kit/sortable';
|
||||
import { CSS } from '@dnd-kit/utilities';
|
||||
|
||||
import CloseIcon from '@/material-icons/400-20px/close.svg?react';
|
||||
import SoundIcon from '@/material-icons/400-24px/audio.svg?react';
|
||||
import EditIcon from '@/material-icons/400-24px/edit.svg?react';
|
||||
import WarningIcon from '@/material-icons/400-24px/warning.svg?react';
|
||||
import { undoUploadCompose } from 'flavours/glitch/actions/compose';
|
||||
@@ -17,7 +18,18 @@ import { openModal } from 'flavours/glitch/actions/modal';
|
||||
import { Blurhash } from 'flavours/glitch/components/blurhash';
|
||||
import { Icon } from 'flavours/glitch/components/icon';
|
||||
import type { MediaAttachment } from 'flavours/glitch/models/media_attachment';
|
||||
import { useAppDispatch, useAppSelector } from 'flavours/glitch/store';
|
||||
import {
|
||||
createAppSelector,
|
||||
useAppDispatch,
|
||||
useAppSelector,
|
||||
} from 'flavours/glitch/store';
|
||||
|
||||
import { AudioVisualizer } from '../../audio/visualizer';
|
||||
|
||||
const selectUserAvatar = createAppSelector(
|
||||
[(state) => state.accounts, (state) => state.meta.get('me') as string],
|
||||
(accounts, myId) => accounts.get(myId)?.avatar_static,
|
||||
);
|
||||
|
||||
export const Upload: React.FC<{
|
||||
id: string;
|
||||
@@ -38,6 +50,7 @@ export const Upload: React.FC<{
|
||||
const sensitive = useAppSelector(
|
||||
(state) => state.compose.get('sensitive') as boolean,
|
||||
);
|
||||
const userAvatar = useAppSelector(selectUserAvatar);
|
||||
|
||||
const handleUndoClick = useCallback(() => {
|
||||
dispatch(undoUploadCompose(id));
|
||||
@@ -67,6 +80,8 @@ export const Upload: React.FC<{
|
||||
transform: CSS.Transform.toString(transform),
|
||||
transition,
|
||||
};
|
||||
const preview_url = media.get('preview_url') as string | null;
|
||||
const blurhash = media.get('blurhash') as string | null;
|
||||
|
||||
return (
|
||||
<div
|
||||
@@ -85,17 +100,19 @@ export const Upload: React.FC<{
|
||||
<div
|
||||
className='compose-form__upload__thumbnail'
|
||||
style={{
|
||||
backgroundImage: !sensitive
|
||||
? `url(${media.get('preview_url') as string})`
|
||||
: undefined,
|
||||
backgroundImage:
|
||||
!sensitive && preview_url ? `url(${preview_url})` : undefined,
|
||||
backgroundPosition: `${x}% ${y}%`,
|
||||
}}
|
||||
>
|
||||
{sensitive && (
|
||||
<Blurhash
|
||||
hash={media.get('blurhash') as string}
|
||||
className='compose-form__upload__preview'
|
||||
/>
|
||||
{sensitive && blurhash && (
|
||||
<Blurhash hash={blurhash} className='compose-form__upload__preview' />
|
||||
)}
|
||||
{!sensitive && !preview_url && (
|
||||
<div className='compose-form__upload__visualizer'>
|
||||
<AudioVisualizer poster={userAvatar} />
|
||||
<Icon id='sound' icon={SoundIcon} />
|
||||
</div>
|
||||
)}
|
||||
|
||||
<div className='compose-form__upload__actions'>
|
||||
|
||||
@@ -5,8 +5,10 @@ import { defineMessages, useIntl } from 'react-intl';
|
||||
|
||||
import classNames from 'classnames';
|
||||
|
||||
import { changeComposeVisibility } from '@/flavours/glitch/actions/compose';
|
||||
import { setComposeQuotePolicy } from '@/flavours/glitch/actions/compose_typed';
|
||||
import {
|
||||
changeComposeVisibility,
|
||||
setComposeQuotePolicy,
|
||||
} from '@/flavours/glitch/actions/compose_typed';
|
||||
import { openModal } from '@/flavours/glitch/actions/modal';
|
||||
import type { ApiQuotePolicy } from '@/flavours/glitch/api_types/quotes';
|
||||
import type { StatusVisibility } from '@/flavours/glitch/api_types/statuses';
|
||||
|
||||
@@ -12,6 +12,7 @@ import {
|
||||
} from 'flavours/glitch/actions/compose';
|
||||
import { pasteLinkCompose } from 'flavours/glitch/actions/compose_typed';
|
||||
import { openModal } from 'flavours/glitch/actions/modal';
|
||||
import { PRIVATE_QUOTE_MODAL_ID } from 'flavours/glitch/features/ui/components/confirmation_modals/private_quote_notify';
|
||||
import { privacyPreference } from 'flavours/glitch/utils/privacy_preference';
|
||||
|
||||
import ComposeForm from '../components/compose_form';
|
||||
@@ -52,6 +53,10 @@ const mapStateToProps = state => ({
|
||||
isUploading: state.getIn(['compose', 'is_uploading']),
|
||||
anyMedia: state.getIn(['compose', 'media_attachments']).size > 0,
|
||||
missingAltText: state.getIn(['compose', 'media_attachments']).some(media => ['image', 'gifv'].includes(media.get('type')) && (media.get('description') ?? '').length === 0),
|
||||
quoteToPrivate:
|
||||
!!state.getIn(['compose', 'quoted_status_id'])
|
||||
&& state.getIn(['compose', 'privacy']) === 'private'
|
||||
&& !state.getIn(['settings', 'dismissed_banners', PRIVATE_QUOTE_MODAL_ID]),
|
||||
isInReply: state.getIn(['compose', 'in_reply_to']) !== null,
|
||||
lang: state.getIn(['compose', 'language']),
|
||||
sideArm: sideArmPrivacy(state),
|
||||
@@ -65,12 +70,17 @@ const mapDispatchToProps = (dispatch, props) => ({
|
||||
dispatch(changeCompose(text));
|
||||
},
|
||||
|
||||
onSubmit (missingAltText, overridePrivacy = null) {
|
||||
onSubmit ({ missingAltText, quoteToPrivate, overridePrivacy = null }) {
|
||||
if (missingAltText) {
|
||||
dispatch(openModal({
|
||||
modalType: 'CONFIRM_MISSING_ALT_TEXT',
|
||||
modalProps: { overridePrivacy },
|
||||
}));
|
||||
} else if (quoteToPrivate) {
|
||||
dispatch(openModal({
|
||||
modalType: 'CONFIRM_PRIVATE_QUOTE_NOTIFY',
|
||||
modalProps: {},
|
||||
}));
|
||||
} else {
|
||||
dispatch(submitCompose(overridePrivacy, (status) => {
|
||||
if (props.redirectOnSuccess) {
|
||||
|
||||
@@ -1,8 +1,7 @@
|
||||
import { connect } from 'react-redux';
|
||||
|
||||
import { changeComposeVisibility } from '../../../actions/compose';
|
||||
import { openModal, closeModal } from '../../../actions/modal';
|
||||
import { isUserTouching } from '../../../is_mobile';
|
||||
import { changeComposeVisibility } from '@/flavours/glitch/actions/compose_typed';
|
||||
|
||||
import PrivacyDropdown from '../components/privacy_dropdown';
|
||||
|
||||
const mapStateToProps = state => ({
|
||||
|
||||
@@ -1,11 +1,13 @@
|
||||
import { useEffect, useState } from 'react';
|
||||
import type { FC } from 'react';
|
||||
import { useEffect, useState } from 'react';
|
||||
|
||||
import { FormattedDate, FormattedMessage } from 'react-intl';
|
||||
|
||||
import { dismissAnnouncement } from '@/flavours/glitch/actions/announcements';
|
||||
import type { ApiAnnouncementJSON } from '@/flavours/glitch/api_types/announcements';
|
||||
import { AnimateEmojiProvider } from '@/flavours/glitch/components/emoji/context';
|
||||
import { EmojiHTML } from '@/flavours/glitch/components/emoji/html';
|
||||
import { useAppDispatch } from '@/flavours/glitch/store';
|
||||
|
||||
import { ReactionsBar } from './reactions';
|
||||
|
||||
@@ -22,13 +24,23 @@ export const Announcement: FC<AnnouncementProps> = ({
|
||||
announcement,
|
||||
selected,
|
||||
}) => {
|
||||
const [unread, setUnread] = useState(!announcement.read);
|
||||
const { read, id } = announcement;
|
||||
|
||||
// Dismiss announcement when it becomes active.
|
||||
const dispatch = useAppDispatch();
|
||||
useEffect(() => {
|
||||
// Only update `unread` marker once the announcement is out of view
|
||||
if (!selected && unread !== !announcement.read) {
|
||||
setUnread(!announcement.read);
|
||||
if (selected && !read) {
|
||||
dispatch(dismissAnnouncement(id));
|
||||
}
|
||||
}, [announcement.read, selected, unread]);
|
||||
}, [selected, id, dispatch, read]);
|
||||
|
||||
// But visually show the announcement as read only when it goes out of view.
|
||||
const [unread, setUnread] = useState(!read);
|
||||
useEffect(() => {
|
||||
if (!selected && unread !== !read) {
|
||||
setUnread(!read);
|
||||
}
|
||||
}, [selected, unread, read]);
|
||||
|
||||
return (
|
||||
<AnimateEmojiProvider className='announcements__item'>
|
||||
|
||||
@@ -329,6 +329,12 @@ class Status extends ImmutablePureComponent {
|
||||
dispatch(openModal({ modalType: 'COMPOSE_PRIVACY', modalProps: { statusId, onChange: handleChange } }));
|
||||
};
|
||||
|
||||
handleQuote = (status) => {
|
||||
const { dispatch } = this.props;
|
||||
|
||||
dispatch(quoteComposeById(status.get('id')));
|
||||
};
|
||||
|
||||
handleEditClick = (status) => {
|
||||
const { dispatch, askReplyConfirmation } = this.props;
|
||||
|
||||
@@ -659,6 +665,7 @@ class Status extends ImmutablePureComponent {
|
||||
onDelete={this.handleDeleteClick}
|
||||
onRevokeQuote={this.handleRevokeQuoteClick}
|
||||
onQuotePolicyChange={this.handleQuotePolicyChange}
|
||||
onQuote={this.handleQuote}
|
||||
onEdit={this.handleEditClick}
|
||||
onDirect={this.handleDirectClick}
|
||||
onMention={this.handleMentionClick}
|
||||
|
||||
@@ -26,6 +26,7 @@ export const ConfirmationModal: React.FC<
|
||||
onSecondary?: () => void;
|
||||
onConfirm: () => void;
|
||||
closeWhenConfirm?: boolean;
|
||||
extraContent?: React.ReactNode;
|
||||
} & BaseConfirmationModalProps
|
||||
> = ({
|
||||
title,
|
||||
@@ -37,6 +38,7 @@ export const ConfirmationModal: React.FC<
|
||||
secondary,
|
||||
onSecondary,
|
||||
closeWhenConfirm = true,
|
||||
extraContent,
|
||||
}) => {
|
||||
const handleClick = useCallback(() => {
|
||||
if (closeWhenConfirm) {
|
||||
@@ -57,6 +59,8 @@ export const ConfirmationModal: React.FC<
|
||||
<div className='safety-action-modal__confirmation'>
|
||||
<h1>{title}</h1>
|
||||
{message && <p>{message}</p>}
|
||||
|
||||
{extraContent}
|
||||
</div>
|
||||
</div>
|
||||
|
||||
|
||||
@@ -0,0 +1,88 @@
|
||||
import { forwardRef, useCallback, useState } from 'react';
|
||||
|
||||
import { defineMessages, FormattedMessage, useIntl } from 'react-intl';
|
||||
|
||||
import { submitCompose } from '@/flavours/glitch/actions/compose';
|
||||
import { changeSetting } from '@/flavours/glitch/actions/settings';
|
||||
import { CheckBox } from '@/flavours/glitch/components/check_box';
|
||||
import { useAppDispatch } from '@/flavours/glitch/store';
|
||||
|
||||
import { ConfirmationModal } from './confirmation_modal';
|
||||
import type { BaseConfirmationModalProps } from './confirmation_modal';
|
||||
import classes from './styles.module.css';
|
||||
|
||||
export const PRIVATE_QUOTE_MODAL_ID = 'quote/private_notify';
|
||||
|
||||
const messages = defineMessages({
|
||||
title: {
|
||||
id: 'confirmations.private_quote_notify.title',
|
||||
defaultMessage: 'Share with followers and mentioned users?',
|
||||
},
|
||||
message: {
|
||||
id: 'confirmations.private_quote_notify.message',
|
||||
defaultMessage:
|
||||
'The person you are quoting and other mentions ' +
|
||||
"will be notified and will be able to view your post, even if they're not following you.",
|
||||
},
|
||||
confirm: {
|
||||
id: 'confirmations.private_quote_notify.confirm',
|
||||
defaultMessage: 'Publish post',
|
||||
},
|
||||
cancel: {
|
||||
id: 'confirmations.private_quote_notify.cancel',
|
||||
defaultMessage: 'Back to editing',
|
||||
},
|
||||
});
|
||||
|
||||
export const PrivateQuoteNotify = forwardRef<
|
||||
HTMLDivElement,
|
||||
BaseConfirmationModalProps
|
||||
>(
|
||||
(
|
||||
{ onClose },
|
||||
// eslint-disable-next-line @typescript-eslint/no-unused-vars
|
||||
_ref,
|
||||
) => {
|
||||
const intl = useIntl();
|
||||
|
||||
const [dismiss, setDismissed] = useState(false);
|
||||
const handleDismissToggle = useCallback(() => {
|
||||
setDismissed((prev) => !prev);
|
||||
}, []);
|
||||
|
||||
const dispatch = useAppDispatch();
|
||||
const handleConfirm = useCallback(() => {
|
||||
dispatch(submitCompose());
|
||||
if (dismiss) {
|
||||
dispatch(
|
||||
changeSetting(['dismissed_banners', PRIVATE_QUOTE_MODAL_ID], true),
|
||||
);
|
||||
}
|
||||
}, [dismiss, dispatch]);
|
||||
|
||||
return (
|
||||
<ConfirmationModal
|
||||
title={intl.formatMessage(messages.title)}
|
||||
message={intl.formatMessage(messages.message)}
|
||||
confirm={intl.formatMessage(messages.confirm)}
|
||||
cancel={intl.formatMessage(messages.cancel)}
|
||||
onConfirm={handleConfirm}
|
||||
onClose={onClose}
|
||||
extraContent={
|
||||
<label className={classes.checkbox_wrapper}>
|
||||
<CheckBox
|
||||
value='hide'
|
||||
checked={dismiss}
|
||||
onChange={handleDismissToggle}
|
||||
/>{' '}
|
||||
<FormattedMessage
|
||||
id='confirmations.private_quote_notify.do_not_show_again'
|
||||
defaultMessage="Don't show me this message again"
|
||||
/>
|
||||
</label>
|
||||
}
|
||||
/>
|
||||
);
|
||||
},
|
||||
);
|
||||
PrivateQuoteNotify.displayName = 'PrivateQuoteNotify';
|
||||
@@ -0,0 +1,7 @@
|
||||
.checkbox_wrapper {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
gap: 0.5rem;
|
||||
margin: 1rem 0;
|
||||
cursor: pointer;
|
||||
}
|
||||
@@ -51,6 +51,7 @@ import MediaModal from './media_modal';
|
||||
import { ModalPlaceholder } from './modal_placeholder';
|
||||
import VideoModal from './video_modal';
|
||||
import { VisibilityModal } from './visibility_modal';
|
||||
import { PrivateQuoteNotify } from './confirmation_modals/private_quote_notify';
|
||||
|
||||
export const MODAL_COMPONENTS = {
|
||||
'MEDIA': () => Promise.resolve({ default: MediaModal }),
|
||||
@@ -72,6 +73,7 @@ export const MODAL_COMPONENTS = {
|
||||
'CONFIRM_LOG_OUT': () => Promise.resolve({ default: ConfirmLogOutModal }),
|
||||
'CONFIRM_FOLLOW_TO_LIST': () => Promise.resolve({ default: ConfirmFollowToListModal }),
|
||||
'CONFIRM_MISSING_ALT_TEXT': () => Promise.resolve({ default: ConfirmMissingAltTextModal }),
|
||||
'CONFIRM_PRIVATE_QUOTE_NOTIFY': () => Promise.resolve({ default: PrivateQuoteNotify }),
|
||||
'CONFIRM_REVOKE_QUOTE': () => Promise.resolve({ default: ConfirmRevokeQuoteModal }),
|
||||
'CONFIRM_QUIET_QUOTE': () => Promise.resolve({ default: QuietPostQuoteInfoModal }),
|
||||
'MUTE': MuteModal,
|
||||
|
||||
@@ -128,9 +128,12 @@ export const VisibilityModal: FC<VisibilityModalProps> = forwardRef(
|
||||
const disableVisibility = !!statusId;
|
||||
const disableQuotePolicy =
|
||||
visibility === 'private' || visibility === 'direct';
|
||||
const disablePublicVisibilities: boolean = useAppSelector(
|
||||
const disablePublicVisibilities = useAppSelector(
|
||||
selectDisablePublicVisibilities,
|
||||
);
|
||||
const isQuotePost = useAppSelector(
|
||||
(state) => state.compose.get('quoted_status_id') !== null,
|
||||
);
|
||||
|
||||
const visibilityItems = useMemo<SelectItem<StatusVisibility>[]>(() => {
|
||||
const items: SelectItem<StatusVisibility>[] = [
|
||||
@@ -315,6 +318,21 @@ export const VisibilityModal: FC<VisibilityModalProps> = forwardRef(
|
||||
id={quoteDescriptionId}
|
||||
/>
|
||||
</div>
|
||||
|
||||
{isQuotePost && visibility === 'direct' && (
|
||||
<div className='visibility-modal__quote-warning'>
|
||||
<FormattedMessage
|
||||
id='visibility_modal.direct_quote_warning.title'
|
||||
defaultMessage="Quotes can't be embedded in private mentions"
|
||||
tagName='h3'
|
||||
/>
|
||||
<FormattedMessage
|
||||
id='visibility_modal.direct_quote_warning.text'
|
||||
defaultMessage='If you save the current settings, the embedded quote will be converted to a link.'
|
||||
tagName='p'
|
||||
/>
|
||||
</div>
|
||||
)}
|
||||
</div>
|
||||
<div className='dialog-modal__content__actions'>
|
||||
<Button onClick={onClose} secondary>
|
||||
|
||||
@@ -37,7 +37,7 @@ interface InitialStateMeta {
|
||||
streaming_api_base_url: string;
|
||||
local_live_feed_access: 'public' | 'authenticated' | 'disabled';
|
||||
remote_live_feed_access: 'public' | 'authenticated' | 'disabled';
|
||||
local_topic_feed_access: 'public' | 'authenticated' | 'disabled';
|
||||
local_topic_feed_access: 'public' | 'authenticated';
|
||||
remote_topic_feed_access: 'public' | 'authenticated' | 'disabled';
|
||||
title: string;
|
||||
show_trends: boolean;
|
||||
|
||||
@@ -1,11 +1,14 @@
|
||||
import { Map as ImmutableMap, List as ImmutableList, OrderedSet as ImmutableOrderedSet, fromJS } from 'immutable';
|
||||
|
||||
import {
|
||||
changeComposeVisibility,
|
||||
changeUploadCompose,
|
||||
quoteCompose,
|
||||
quoteComposeCancel,
|
||||
setComposeQuotePolicy,
|
||||
} from 'flavours/glitch/actions/compose_typed';
|
||||
pasteLinkCompose,
|
||||
cancelPasteLinkCompose,
|
||||
} from '@/flavours/glitch/actions/compose_typed';
|
||||
import { timelineDelete } from 'flavours/glitch/actions/timelines_typed';
|
||||
|
||||
import {
|
||||
@@ -39,7 +42,6 @@ import {
|
||||
COMPOSE_SENSITIVITY_CHANGE,
|
||||
COMPOSE_SPOILERNESS_CHANGE,
|
||||
COMPOSE_SPOILER_TEXT_CHANGE,
|
||||
COMPOSE_VISIBILITY_CHANGE,
|
||||
COMPOSE_LANGUAGE_CHANGE,
|
||||
COMPOSE_COMPOSING_CHANGE,
|
||||
COMPOSE_CONTENT_TYPE_CHANGE,
|
||||
@@ -119,6 +121,7 @@ const initialState = ImmutableMap({
|
||||
quoted_status_id: null,
|
||||
quote_policy: 'public',
|
||||
default_quote_policy: 'public', // Set in hydration.
|
||||
fetching_link: null,
|
||||
});
|
||||
|
||||
const initialPoll = ImmutableMap({
|
||||
@@ -391,7 +394,11 @@ const calculateProgress = (loaded, total) => Math.min(Math.round((loaded / total
|
||||
|
||||
/** @type {import('@reduxjs/toolkit').Reducer<typeof initialState>} */
|
||||
export const composeReducer = (state = initialState, action) => {
|
||||
if (changeUploadCompose.fulfilled.match(action)) {
|
||||
if (changeComposeVisibility.match(action)) {
|
||||
return state
|
||||
.set('privacy', action.payload)
|
||||
.set('idempotencyKey', uuid());
|
||||
} else if (changeUploadCompose.fulfilled.match(action)) {
|
||||
return state
|
||||
.set('is_changing_upload', false)
|
||||
.update('media_attachments', list => list.map(item => {
|
||||
@@ -407,15 +414,27 @@ export const composeReducer = (state = initialState, action) => {
|
||||
return state.set('is_changing_upload', false);
|
||||
} else if (quoteCompose.match(action)) {
|
||||
const status = action.payload;
|
||||
const isDirect = state.get('privacy') === 'direct';
|
||||
return state
|
||||
.set('quoted_status_id', status.get('id'))
|
||||
.set('quoted_status_id', isDirect ? null : status.get('id'))
|
||||
.set('spoiler', status.get('sensitive'))
|
||||
.set('spoiler_text', status.get('spoiler_text'))
|
||||
.update('privacy', (visibility) => ['public', 'unlisted'].includes(visibility) && status.get('visibility') === 'private' ? 'private' : visibility);
|
||||
.update('privacy', (visibility) => {
|
||||
if (['public', 'unlisted'].includes(visibility) && status.get('visibility') === 'private') {
|
||||
return 'private';
|
||||
}
|
||||
return visibility;
|
||||
});
|
||||
} else if (quoteComposeCancel.match(action)) {
|
||||
return state.set('quoted_status_id', null);
|
||||
} else if (setComposeQuotePolicy.match(action)) {
|
||||
return state.set('quote_policy', action.payload);
|
||||
} else if (pasteLinkCompose.pending.match(action)) {
|
||||
return state.set('fetching_link', action.meta.requestId);
|
||||
} else if (pasteLinkCompose.fulfilled.match(action) || pasteLinkCompose.rejected.match(action)) {
|
||||
return action.meta.requestId === state.get('fetching_link') ? state.set('fetching_link', null) : state;
|
||||
} else if (cancelPasteLinkCompose.match(action)) {
|
||||
return state.set('fetching_link', null);
|
||||
}
|
||||
|
||||
switch(action.type) {
|
||||
@@ -462,10 +481,6 @@ export const composeReducer = (state = initialState, action) => {
|
||||
return state
|
||||
.set('spoiler_text', action.text)
|
||||
.set('idempotencyKey', uuid());
|
||||
case COMPOSE_VISIBILITY_CHANGE:
|
||||
return state
|
||||
.set('privacy', action.value)
|
||||
.set('idempotencyKey', uuid());
|
||||
case COMPOSE_CONTENT_TYPE_CHANGE:
|
||||
return state
|
||||
.set('content_type', action.value)
|
||||
|
||||
@@ -42,7 +42,7 @@ interface AppThunkConfig {
|
||||
}
|
||||
export type AppThunkApi = Pick<
|
||||
GetThunkAPI<AppThunkConfig>,
|
||||
'getState' | 'dispatch'
|
||||
'getState' | 'dispatch' | 'requestId'
|
||||
>;
|
||||
|
||||
interface AppThunkOptions<Arg> {
|
||||
@@ -60,7 +60,7 @@ type AppThunk<Arg = void, Returned = void> = (
|
||||
|
||||
type AppThunkCreator<Arg = void, Returned = void, ExtraArg = unknown> = (
|
||||
arg: Arg,
|
||||
api: AppThunkApi,
|
||||
api: Pick<AppThunkApi, 'getState' | 'dispatch'>,
|
||||
extra?: ExtraArg,
|
||||
) => Returned;
|
||||
|
||||
@@ -143,10 +143,10 @@ export function createAsyncThunk<Arg = void, Returned = void>(
|
||||
name,
|
||||
async (
|
||||
arg: Arg,
|
||||
{ getState, dispatch, fulfillWithValue, rejectWithValue },
|
||||
{ getState, dispatch, requestId, fulfillWithValue, rejectWithValue },
|
||||
) => {
|
||||
try {
|
||||
const result = await creator(arg, { dispatch, getState });
|
||||
const result = await creator(arg, { dispatch, getState, requestId });
|
||||
|
||||
return fulfillWithValue(result, {
|
||||
useLoadingBar: options.useLoadingBar,
|
||||
@@ -280,10 +280,11 @@ export function createDataLoadingThunk<
|
||||
|
||||
return createAsyncThunk<Args, Returned>(
|
||||
name,
|
||||
async (arg, { getState, dispatch }) => {
|
||||
async (arg, { getState, dispatch, requestId }) => {
|
||||
const data = await loadData(arg, {
|
||||
dispatch,
|
||||
getState,
|
||||
requestId,
|
||||
});
|
||||
|
||||
if (!onData) return data as Returned;
|
||||
@@ -291,6 +292,7 @@ export function createDataLoadingThunk<
|
||||
const result = await onData(data, {
|
||||
dispatch,
|
||||
getState,
|
||||
requestId,
|
||||
discardLoadData: discardLoadDataInPayload,
|
||||
actionArg: arg,
|
||||
});
|
||||
|
||||
@@ -1330,6 +1330,10 @@ a.sparkline {
|
||||
line-height: 1;
|
||||
width: 100%;
|
||||
animation: skeleton 1.2s ease-in-out infinite;
|
||||
|
||||
.reduce-motion & {
|
||||
animation: none;
|
||||
}
|
||||
}
|
||||
|
||||
@keyframes skeleton {
|
||||
|
||||
@@ -775,16 +775,43 @@
|
||||
padding: 8px;
|
||||
}
|
||||
|
||||
&__preview {
|
||||
&__preview,
|
||||
&__visualizer {
|
||||
position: absolute;
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
border-radius: 6px;
|
||||
z-index: -1;
|
||||
top: 0;
|
||||
}
|
||||
|
||||
&__preview {
|
||||
border-radius: 6px;
|
||||
inset-inline-start: 0;
|
||||
}
|
||||
|
||||
&__visualizer {
|
||||
padding: 16px;
|
||||
box-sizing: border-box;
|
||||
|
||||
.audio-player__visualizer {
|
||||
margin: 0 auto;
|
||||
display: block;
|
||||
height: 100%;
|
||||
}
|
||||
|
||||
.icon {
|
||||
position: absolute;
|
||||
top: 50%;
|
||||
inset-inline-start: 50%;
|
||||
transform: translate(-50%, -50%);
|
||||
opacity: 0.75;
|
||||
color: var(--player-foreground-color);
|
||||
filter: var(--overlay-icon-shadow);
|
||||
width: 48px;
|
||||
height: 48px;
|
||||
}
|
||||
}
|
||||
|
||||
&__thumbnail {
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
@@ -5980,6 +6007,34 @@ a.status-card {
|
||||
}
|
||||
}
|
||||
|
||||
.visibility-modal {
|
||||
&__quote-warning {
|
||||
color: var(--nested-card-text);
|
||||
background:
|
||||
/* This is a bit of a silly hack for layering two background colours
|
||||
* since --nested-card-background is too transparent for a tooltip */
|
||||
linear-gradient(
|
||||
var(--nested-card-background),
|
||||
var(--nested-card-background)
|
||||
),
|
||||
linear-gradient(var(--background-color), var(--background-color));
|
||||
border: var(--nested-card-border);
|
||||
padding: 16px;
|
||||
border-radius: 4px;
|
||||
|
||||
h3 {
|
||||
font-weight: 500;
|
||||
margin-bottom: 4px;
|
||||
color: $darker-text-color;
|
||||
}
|
||||
|
||||
p {
|
||||
font-size: 0.8em;
|
||||
color: $dark-text-color;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
.visibility-dropdown {
|
||||
&__overlay[data-popper-placement] {
|
||||
z-index: 9999;
|
||||
|
||||
@@ -56,7 +56,6 @@ export const COMPOSE_UNMOUNT = 'COMPOSE_UNMOUNT';
|
||||
export const COMPOSE_SENSITIVITY_CHANGE = 'COMPOSE_SENSITIVITY_CHANGE';
|
||||
export const COMPOSE_SPOILERNESS_CHANGE = 'COMPOSE_SPOILERNESS_CHANGE';
|
||||
export const COMPOSE_SPOILER_TEXT_CHANGE = 'COMPOSE_SPOILER_TEXT_CHANGE';
|
||||
export const COMPOSE_VISIBILITY_CHANGE = 'COMPOSE_VISIBILITY_CHANGE';
|
||||
export const COMPOSE_COMPOSING_CHANGE = 'COMPOSE_COMPOSING_CHANGE';
|
||||
export const COMPOSE_LANGUAGE_CHANGE = 'COMPOSE_LANGUAGE_CHANGE';
|
||||
|
||||
@@ -796,13 +795,6 @@ export function changeComposeSpoilerText(text) {
|
||||
};
|
||||
}
|
||||
|
||||
export function changeComposeVisibility(value) {
|
||||
return {
|
||||
type: COMPOSE_VISIBILITY_CHANGE,
|
||||
value,
|
||||
};
|
||||
}
|
||||
|
||||
export function insertEmojiCompose(position, emoji, needsSpace) {
|
||||
return {
|
||||
type: COMPOSE_EMOJI_INSERT,
|
||||
|
||||
@@ -13,10 +13,11 @@ import {
|
||||
} from 'mastodon/store/typed_functions';
|
||||
|
||||
import type { ApiQuotePolicy } from '../api_types/quotes';
|
||||
import type { Status } from '../models/status';
|
||||
import type { Status, StatusVisibility } from '../models/status';
|
||||
import type { RootState } from '../store';
|
||||
|
||||
import { showAlert } from './alerts';
|
||||
import { focusCompose } from './compose';
|
||||
import { changeCompose, focusCompose } from './compose';
|
||||
import { importFetchedStatuses } from './importer';
|
||||
import { openModal } from './modal';
|
||||
|
||||
@@ -41,6 +42,10 @@ const messages = defineMessages({
|
||||
id: 'quote_error.unauthorized',
|
||||
defaultMessage: 'You are not authorized to quote this post.',
|
||||
},
|
||||
quoteErrorPrivateMention: {
|
||||
id: 'quote_error.private_mentions',
|
||||
defaultMessage: 'Quoting is not allowed with direct mentions.',
|
||||
},
|
||||
});
|
||||
|
||||
type SimulatedMediaAttachmentJSON = ApiMediaAttachmentJSON & {
|
||||
@@ -67,6 +72,39 @@ const simulateModifiedApiResponse = (
|
||||
return data;
|
||||
};
|
||||
|
||||
export const changeComposeVisibility = createAppThunk(
|
||||
'compose/visibility_change',
|
||||
(visibility: StatusVisibility, { dispatch, getState }) => {
|
||||
if (visibility !== 'direct') {
|
||||
return visibility;
|
||||
}
|
||||
|
||||
const state = getState();
|
||||
const quotedStatusId = state.compose.get('quoted_status_id') as
|
||||
| string
|
||||
| null;
|
||||
if (!quotedStatusId) {
|
||||
return visibility;
|
||||
}
|
||||
|
||||
// Remove the quoted status
|
||||
dispatch(quoteComposeCancel());
|
||||
const quotedStatus = state.statuses.get(quotedStatusId) as Status | null;
|
||||
if (!quotedStatus) {
|
||||
return visibility;
|
||||
}
|
||||
|
||||
// Append the quoted status URL to the compose text
|
||||
const url = quotedStatus.get('url') as string;
|
||||
const text = state.compose.get('text') as string;
|
||||
if (!text.includes(url)) {
|
||||
const newText = text.trim() ? `${text}\n\n${url}` : url;
|
||||
dispatch(changeCompose(newText));
|
||||
}
|
||||
return visibility;
|
||||
},
|
||||
);
|
||||
|
||||
export const changeUploadCompose = createDataLoadingThunk(
|
||||
'compose/changeUpload',
|
||||
async (
|
||||
@@ -130,6 +168,8 @@ export const quoteComposeByStatus = createAppThunk(
|
||||
|
||||
if (composeState.get('id')) {
|
||||
dispatch(showAlert({ message: messages.quoteErrorEdit }));
|
||||
} else if (composeState.get('privacy') === 'direct') {
|
||||
dispatch(showAlert({ message: messages.quoteErrorPrivateMention }));
|
||||
} else if (composeState.get('poll')) {
|
||||
dispatch(showAlert({ message: messages.quoteErrorPoll }));
|
||||
} else if (
|
||||
@@ -173,6 +213,17 @@ export const quoteComposeById = createAppThunk(
|
||||
},
|
||||
);
|
||||
|
||||
const composeStateForbidsLink = (composeState: RootState['compose']) => {
|
||||
return (
|
||||
composeState.get('quoted_status_id') ||
|
||||
composeState.get('is_submitting') ||
|
||||
composeState.get('poll') ||
|
||||
composeState.get('is_uploading') ||
|
||||
composeState.get('id') ||
|
||||
composeState.get('privacy') === 'direct'
|
||||
);
|
||||
};
|
||||
|
||||
export const pasteLinkCompose = createDataLoadingThunk(
|
||||
'compose/pasteLink',
|
||||
async ({ url }: { url: string }) => {
|
||||
@@ -183,15 +234,12 @@ export const pasteLinkCompose = createDataLoadingThunk(
|
||||
limit: 2,
|
||||
});
|
||||
},
|
||||
(data, { dispatch, getState }) => {
|
||||
(data, { dispatch, getState, requestId }) => {
|
||||
const composeState = getState().compose;
|
||||
|
||||
if (
|
||||
composeState.get('quoted_status_id') ||
|
||||
composeState.get('is_submitting') ||
|
||||
composeState.get('poll') ||
|
||||
composeState.get('is_uploading') ||
|
||||
composeState.get('id')
|
||||
composeStateForbidsLink(composeState) ||
|
||||
composeState.get('fetching_link') !== requestId // Request has been cancelled
|
||||
)
|
||||
return;
|
||||
|
||||
@@ -207,6 +255,17 @@ export const pasteLinkCompose = createDataLoadingThunk(
|
||||
dispatch(quoteComposeById(data.statuses[0].id));
|
||||
}
|
||||
},
|
||||
{
|
||||
useLoadingBar: false,
|
||||
condition: (_, { getState }) =>
|
||||
!getState().compose.get('fetching_link') &&
|
||||
!composeStateForbidsLink(getState().compose),
|
||||
},
|
||||
);
|
||||
|
||||
// Ideally this would cancel the action and the HTTP request, but this is good enough
|
||||
export const cancelPasteLinkCompose = createAction(
|
||||
'compose/cancelPasteLinkCompose',
|
||||
);
|
||||
|
||||
export const quoteComposeCancel = createAction('compose/quoteComposeCancel');
|
||||
|
||||
@@ -49,6 +49,7 @@ export const StatusBanner: React.FC<{
|
||||
|
||||
<button
|
||||
ref={buttonRef}
|
||||
type='button'
|
||||
className='link-button'
|
||||
onClick={onClick}
|
||||
aria-describedby={descriptionId}
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
import { useEffect, useRef, useCallback, useState, useId } from 'react';
|
||||
import { useEffect, useRef, useCallback, useState } from 'react';
|
||||
|
||||
import { defineMessages, useIntl, FormattedMessage } from 'react-intl';
|
||||
|
||||
@@ -22,6 +22,8 @@ import { useAudioVisualizer } from 'mastodon/hooks/useAudioVisualizer';
|
||||
import { displayMedia, useBlurhash } from 'mastodon/initial_state';
|
||||
import { playerSettings } from 'mastodon/settings';
|
||||
|
||||
import { AudioVisualizer } from './visualizer';
|
||||
|
||||
const messages = defineMessages({
|
||||
play: { id: 'video.play', defaultMessage: 'Play' },
|
||||
pause: { id: 'video.pause', defaultMessage: 'Pause' },
|
||||
@@ -116,7 +118,6 @@ export const Audio: React.FC<{
|
||||
const seekRef = useRef<HTMLDivElement>(null);
|
||||
const volumeRef = useRef<HTMLDivElement>(null);
|
||||
const hoverTimeoutRef = useRef<ReturnType<typeof setTimeout> | null>();
|
||||
const accessibilityId = useId();
|
||||
|
||||
const { audioContextRef, sourceRef, gainNodeRef, playAudio, pauseAudio } =
|
||||
useAudioContext({ audioElementRef: audioRef });
|
||||
@@ -538,19 +539,6 @@ export const Audio: React.FC<{
|
||||
[togglePlay, toggleMute],
|
||||
);
|
||||
|
||||
const springForBand0 = useSpring({
|
||||
to: { r: 50 + (frequencyBands[0] ?? 0) * 10 },
|
||||
config: config.wobbly,
|
||||
});
|
||||
const springForBand1 = useSpring({
|
||||
to: { r: 50 + (frequencyBands[1] ?? 0) * 10 },
|
||||
config: config.wobbly,
|
||||
});
|
||||
const springForBand2 = useSpring({
|
||||
to: { r: 50 + (frequencyBands[2] ?? 0) * 10 },
|
||||
config: config.wobbly,
|
||||
});
|
||||
|
||||
const progress = Math.min((currentTime / loadedDuration) * 100, 100);
|
||||
const effectivelyMuted = muted || volume === 0;
|
||||
|
||||
@@ -641,81 +629,7 @@ export const Audio: React.FC<{
|
||||
</div>
|
||||
|
||||
<div className='audio-player__controls__play'>
|
||||
<svg
|
||||
className='audio-player__visualizer'
|
||||
viewBox='0 0 124 124'
|
||||
xmlns='http://www.w3.org/2000/svg'
|
||||
>
|
||||
<animated.circle
|
||||
opacity={0.5}
|
||||
cx={57}
|
||||
cy={62.5}
|
||||
r={springForBand0.r}
|
||||
fill='var(--player-accent-color)'
|
||||
/>
|
||||
<animated.circle
|
||||
opacity={0.5}
|
||||
cx={65}
|
||||
cy={57.5}
|
||||
r={springForBand1.r}
|
||||
fill='var(--player-accent-color)'
|
||||
/>
|
||||
<animated.circle
|
||||
opacity={0.5}
|
||||
cx={63}
|
||||
cy={66.5}
|
||||
r={springForBand2.r}
|
||||
fill='var(--player-accent-color)'
|
||||
/>
|
||||
|
||||
<g clipPath={`url(#${accessibilityId}-clip)`}>
|
||||
<rect
|
||||
x={14}
|
||||
y={14}
|
||||
width={96}
|
||||
height={96}
|
||||
fill={`url(#${accessibilityId}-pattern)`}
|
||||
/>
|
||||
<rect
|
||||
x={14}
|
||||
y={14}
|
||||
width={96}
|
||||
height={96}
|
||||
fill='var(--player-background-color'
|
||||
opacity={0.45}
|
||||
/>
|
||||
</g>
|
||||
|
||||
<defs>
|
||||
<pattern
|
||||
id={`${accessibilityId}-pattern`}
|
||||
patternContentUnits='objectBoundingBox'
|
||||
width='1'
|
||||
height='1'
|
||||
>
|
||||
<use href={`#${accessibilityId}-image`} />
|
||||
</pattern>
|
||||
|
||||
<clipPath id={`${accessibilityId}-clip`}>
|
||||
<rect
|
||||
x={14}
|
||||
y={14}
|
||||
width={96}
|
||||
height={96}
|
||||
rx={48}
|
||||
fill='white'
|
||||
/>
|
||||
</clipPath>
|
||||
|
||||
<image
|
||||
id={`${accessibilityId}-image`}
|
||||
href={poster}
|
||||
width={1}
|
||||
height={1}
|
||||
preserveAspectRatio='none'
|
||||
/>
|
||||
</defs>
|
||||
</svg>
|
||||
<AudioVisualizer frequencyBands={frequencyBands} poster={poster} />
|
||||
|
||||
<button
|
||||
type='button'
|
||||
|
||||
100
app/javascript/mastodon/features/audio/visualizer.tsx
Normal file
100
app/javascript/mastodon/features/audio/visualizer.tsx
Normal file
@@ -0,0 +1,100 @@
|
||||
import { useId } from 'react';
|
||||
import type { FC } from 'react';
|
||||
|
||||
import { animated, config, useSpring } from '@react-spring/web';
|
||||
|
||||
interface AudioVisualizerProps {
|
||||
frequencyBands?: number[];
|
||||
poster?: string;
|
||||
}
|
||||
|
||||
export const AudioVisualizer: FC<AudioVisualizerProps> = ({
|
||||
frequencyBands = [],
|
||||
poster,
|
||||
}) => {
|
||||
const accessibilityId = useId();
|
||||
|
||||
const springForBand0 = useSpring({
|
||||
to: { r: 50 + (frequencyBands[0] ?? 0) * 10 },
|
||||
config: config.wobbly,
|
||||
});
|
||||
const springForBand1 = useSpring({
|
||||
to: { r: 50 + (frequencyBands[1] ?? 0) * 10 },
|
||||
config: config.wobbly,
|
||||
});
|
||||
const springForBand2 = useSpring({
|
||||
to: { r: 50 + (frequencyBands[2] ?? 0) * 10 },
|
||||
config: config.wobbly,
|
||||
});
|
||||
|
||||
return (
|
||||
<svg
|
||||
className='audio-player__visualizer'
|
||||
viewBox='0 0 124 124'
|
||||
xmlns='http://www.w3.org/2000/svg'
|
||||
>
|
||||
<animated.circle
|
||||
opacity={0.5}
|
||||
cx={57}
|
||||
cy={62.5}
|
||||
r={springForBand0.r}
|
||||
fill='var(--player-accent-color)'
|
||||
/>
|
||||
<animated.circle
|
||||
opacity={0.5}
|
||||
cx={65}
|
||||
cy={57.5}
|
||||
r={springForBand1.r}
|
||||
fill='var(--player-accent-color)'
|
||||
/>
|
||||
<animated.circle
|
||||
opacity={0.5}
|
||||
cx={63}
|
||||
cy={66.5}
|
||||
r={springForBand2.r}
|
||||
fill='var(--player-accent-color)'
|
||||
/>
|
||||
|
||||
<g clipPath={`url(#${accessibilityId}-clip)`}>
|
||||
<rect
|
||||
x={14}
|
||||
y={14}
|
||||
width={96}
|
||||
height={96}
|
||||
fill={`url(#${accessibilityId}-pattern)`}
|
||||
/>
|
||||
<rect
|
||||
x={14}
|
||||
y={14}
|
||||
width={96}
|
||||
height={96}
|
||||
fill='var(--player-background-color'
|
||||
opacity={0.45}
|
||||
/>
|
||||
</g>
|
||||
|
||||
<defs>
|
||||
<pattern
|
||||
id={`${accessibilityId}-pattern`}
|
||||
patternContentUnits='objectBoundingBox'
|
||||
width='1'
|
||||
height='1'
|
||||
>
|
||||
<use href={`#${accessibilityId}-image`} />
|
||||
</pattern>
|
||||
|
||||
<clipPath id={`${accessibilityId}-clip`}>
|
||||
<rect x={14} y={14} width={96} height={96} rx={48} fill='white' />
|
||||
</clipPath>
|
||||
|
||||
<image
|
||||
id={`${accessibilityId}-image`}
|
||||
href={poster}
|
||||
width={1}
|
||||
height={1}
|
||||
preserveAspectRatio='none'
|
||||
/>
|
||||
</defs>
|
||||
</svg>
|
||||
);
|
||||
};
|
||||
@@ -140,7 +140,10 @@ class ComposeForm extends ImmutablePureComponent {
|
||||
return;
|
||||
}
|
||||
|
||||
this.props.onSubmit(missingAltTextModal && this.props.missingAltText && this.props.privacy !== 'direct');
|
||||
this.props.onSubmit({
|
||||
missingAltText: missingAltTextModal && this.props.missingAltText && this.props.privacy !== 'direct',
|
||||
quoteToPrivate: this.props.quoteToPrivate,
|
||||
});
|
||||
|
||||
if (e) {
|
||||
e.preventDefault();
|
||||
|
||||
@@ -0,0 +1,48 @@
|
||||
import { useCallback } from 'react';
|
||||
import type { FC } from 'react';
|
||||
|
||||
import { defineMessages, useIntl } from 'react-intl';
|
||||
|
||||
import { cancelPasteLinkCompose } from '@/mastodon/actions/compose_typed';
|
||||
import { useAppDispatch } from '@/mastodon/store';
|
||||
import CancelFillIcon from '@/material-icons/400-24px/cancel-fill.svg?react';
|
||||
import { DisplayName } from 'mastodon/components/display_name';
|
||||
import { IconButton } from 'mastodon/components/icon_button';
|
||||
import { Skeleton } from 'mastodon/components/skeleton';
|
||||
|
||||
const messages = defineMessages({
|
||||
quote_cancel: { id: 'status.quote.cancel', defaultMessage: 'Cancel quote' },
|
||||
});
|
||||
|
||||
export const QuotePlaceholder: FC = () => {
|
||||
const intl = useIntl();
|
||||
const dispatch = useAppDispatch();
|
||||
const handleQuoteCancel = useCallback(() => {
|
||||
dispatch(cancelPasteLinkCompose());
|
||||
}, [dispatch]);
|
||||
|
||||
return (
|
||||
<div className='status__quote'>
|
||||
<div className='status'>
|
||||
<div className='status__info'>
|
||||
<div className='status__avatar'>
|
||||
<Skeleton width='32px' height='32px' />
|
||||
</div>
|
||||
<div className='status__display-name'>
|
||||
<DisplayName />
|
||||
</div>
|
||||
<IconButton
|
||||
onClick={handleQuoteCancel}
|
||||
className='status__quote-cancel'
|
||||
title={intl.formatMessage(messages.quote_cancel)}
|
||||
icon='cancel-fill'
|
||||
iconComponent={CancelFillIcon}
|
||||
/>
|
||||
</div>
|
||||
<div className='status__content'>
|
||||
<Skeleton />
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
);
|
||||
};
|
||||
@@ -7,11 +7,17 @@ import { quoteComposeCancel } from '@/mastodon/actions/compose_typed';
|
||||
import { QuotedStatus } from '@/mastodon/components/status_quoted';
|
||||
import { useAppDispatch, useAppSelector } from '@/mastodon/store';
|
||||
|
||||
import { QuotePlaceholder } from './quote_placeholder';
|
||||
|
||||
export const ComposeQuotedStatus: FC = () => {
|
||||
const quotedStatusId = useAppSelector(
|
||||
(state) => state.compose.get('quoted_status_id') as string | null,
|
||||
);
|
||||
|
||||
const isFetchingLink = useAppSelector(
|
||||
(state) => !!state.compose.get('fetching_link'),
|
||||
);
|
||||
|
||||
const isEditing = useAppSelector((state) => !!state.compose.get('id'));
|
||||
|
||||
const quote = useMemo(
|
||||
@@ -30,7 +36,9 @@ export const ComposeQuotedStatus: FC = () => {
|
||||
dispatch(quoteComposeCancel());
|
||||
}, [dispatch]);
|
||||
|
||||
if (!quote) {
|
||||
if (isFetchingLink && !quote) {
|
||||
return <QuotePlaceholder />;
|
||||
} else if (!quote) {
|
||||
return null;
|
||||
}
|
||||
|
||||
|
||||
@@ -10,6 +10,7 @@ import { useSortable } from '@dnd-kit/sortable';
|
||||
import { CSS } from '@dnd-kit/utilities';
|
||||
|
||||
import CloseIcon from '@/material-icons/400-20px/close.svg?react';
|
||||
import SoundIcon from '@/material-icons/400-24px/audio.svg?react';
|
||||
import EditIcon from '@/material-icons/400-24px/edit.svg?react';
|
||||
import WarningIcon from '@/material-icons/400-24px/warning.svg?react';
|
||||
import { undoUploadCompose } from 'mastodon/actions/compose';
|
||||
@@ -17,7 +18,18 @@ import { openModal } from 'mastodon/actions/modal';
|
||||
import { Blurhash } from 'mastodon/components/blurhash';
|
||||
import { Icon } from 'mastodon/components/icon';
|
||||
import type { MediaAttachment } from 'mastodon/models/media_attachment';
|
||||
import { useAppDispatch, useAppSelector } from 'mastodon/store';
|
||||
import {
|
||||
createAppSelector,
|
||||
useAppDispatch,
|
||||
useAppSelector,
|
||||
} from 'mastodon/store';
|
||||
|
||||
import { AudioVisualizer } from '../../audio/visualizer';
|
||||
|
||||
const selectUserAvatar = createAppSelector(
|
||||
[(state) => state.accounts, (state) => state.meta.get('me') as string],
|
||||
(accounts, myId) => accounts.get(myId)?.avatar_static,
|
||||
);
|
||||
|
||||
export const Upload: React.FC<{
|
||||
id: string;
|
||||
@@ -38,6 +50,7 @@ export const Upload: React.FC<{
|
||||
const sensitive = useAppSelector(
|
||||
(state) => state.compose.get('spoiler') as boolean,
|
||||
);
|
||||
const userAvatar = useAppSelector(selectUserAvatar);
|
||||
|
||||
const handleUndoClick = useCallback(() => {
|
||||
dispatch(undoUploadCompose(id));
|
||||
@@ -67,6 +80,8 @@ export const Upload: React.FC<{
|
||||
transform: CSS.Transform.toString(transform),
|
||||
transition,
|
||||
};
|
||||
const preview_url = media.get('preview_url') as string | null;
|
||||
const blurhash = media.get('blurhash') as string | null;
|
||||
|
||||
return (
|
||||
<div
|
||||
@@ -85,17 +100,19 @@ export const Upload: React.FC<{
|
||||
<div
|
||||
className='compose-form__upload__thumbnail'
|
||||
style={{
|
||||
backgroundImage: !sensitive
|
||||
? `url(${media.get('preview_url') as string})`
|
||||
: undefined,
|
||||
backgroundImage:
|
||||
!sensitive && preview_url ? `url(${preview_url})` : undefined,
|
||||
backgroundPosition: `${x}% ${y}%`,
|
||||
}}
|
||||
>
|
||||
{sensitive && (
|
||||
<Blurhash
|
||||
hash={media.get('blurhash') as string}
|
||||
className='compose-form__upload__preview'
|
||||
/>
|
||||
{sensitive && blurhash && (
|
||||
<Blurhash hash={blurhash} className='compose-form__upload__preview' />
|
||||
)}
|
||||
{!sensitive && !preview_url && (
|
||||
<div className='compose-form__upload__visualizer'>
|
||||
<AudioVisualizer poster={userAvatar} />
|
||||
<Icon id='sound' icon={SoundIcon} />
|
||||
</div>
|
||||
)}
|
||||
|
||||
<div className='compose-form__upload__actions'>
|
||||
|
||||
@@ -5,8 +5,10 @@ import { defineMessages, useIntl } from 'react-intl';
|
||||
|
||||
import classNames from 'classnames';
|
||||
|
||||
import { changeComposeVisibility } from '@/mastodon/actions/compose';
|
||||
import { setComposeQuotePolicy } from '@/mastodon/actions/compose_typed';
|
||||
import {
|
||||
changeComposeVisibility,
|
||||
setComposeQuotePolicy,
|
||||
} from '@/mastodon/actions/compose_typed';
|
||||
import { openModal } from '@/mastodon/actions/modal';
|
||||
import type { ApiQuotePolicy } from '@/mastodon/api_types/quotes';
|
||||
import type { StatusVisibility } from '@/mastodon/api_types/statuses';
|
||||
|
||||
@@ -12,6 +12,7 @@ import {
|
||||
} from 'mastodon/actions/compose';
|
||||
import { pasteLinkCompose } from 'mastodon/actions/compose_typed';
|
||||
import { openModal } from 'mastodon/actions/modal';
|
||||
import { PRIVATE_QUOTE_MODAL_ID } from 'mastodon/features/ui/components/confirmation_modals/private_quote_notify';
|
||||
|
||||
import ComposeForm from '../components/compose_form';
|
||||
|
||||
@@ -32,6 +33,10 @@ const mapStateToProps = state => ({
|
||||
isUploading: state.getIn(['compose', 'is_uploading']),
|
||||
anyMedia: state.getIn(['compose', 'media_attachments']).size > 0,
|
||||
missingAltText: state.getIn(['compose', 'media_attachments']).some(media => ['image', 'gifv'].includes(media.get('type')) && (media.get('description') ?? '').length === 0),
|
||||
quoteToPrivate:
|
||||
!!state.getIn(['compose', 'quoted_status_id'])
|
||||
&& state.getIn(['compose', 'privacy']) === 'private'
|
||||
&& !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),
|
||||
@@ -43,12 +48,17 @@ const mapDispatchToProps = (dispatch, props) => ({
|
||||
dispatch(changeCompose(text));
|
||||
},
|
||||
|
||||
onSubmit (missingAltText) {
|
||||
onSubmit ({ missingAltText, quoteToPrivate }) {
|
||||
if (missingAltText) {
|
||||
dispatch(openModal({
|
||||
modalType: 'CONFIRM_MISSING_ALT_TEXT',
|
||||
modalProps: {},
|
||||
}));
|
||||
} else if (quoteToPrivate) {
|
||||
dispatch(openModal({
|
||||
modalType: 'CONFIRM_PRIVATE_QUOTE_NOTIFY',
|
||||
modalProps: {},
|
||||
}));
|
||||
} else {
|
||||
dispatch(submitCompose((status) => {
|
||||
if (props.redirectOnSuccess) {
|
||||
|
||||
@@ -1,8 +1,7 @@
|
||||
import { connect } from 'react-redux';
|
||||
|
||||
import { changeComposeVisibility } from '../../../actions/compose';
|
||||
import { openModal, closeModal } from '../../../actions/modal';
|
||||
import { isUserTouching } from '../../../is_mobile';
|
||||
import { changeComposeVisibility } from '@/mastodon/actions/compose_typed';
|
||||
|
||||
import PrivacyDropdown from '../components/privacy_dropdown';
|
||||
|
||||
const mapStateToProps = state => ({
|
||||
|
||||
@@ -1,11 +1,13 @@
|
||||
import { useEffect, useState } from 'react';
|
||||
import type { FC } from 'react';
|
||||
import { useEffect, useState } from 'react';
|
||||
|
||||
import { FormattedDate, FormattedMessage } from 'react-intl';
|
||||
|
||||
import { dismissAnnouncement } from '@/mastodon/actions/announcements';
|
||||
import type { ApiAnnouncementJSON } from '@/mastodon/api_types/announcements';
|
||||
import { AnimateEmojiProvider } from '@/mastodon/components/emoji/context';
|
||||
import { EmojiHTML } from '@/mastodon/components/emoji/html';
|
||||
import { useAppDispatch } from '@/mastodon/store';
|
||||
|
||||
import { ReactionsBar } from './reactions';
|
||||
|
||||
@@ -22,13 +24,23 @@ export const Announcement: FC<AnnouncementProps> = ({
|
||||
announcement,
|
||||
selected,
|
||||
}) => {
|
||||
const [unread, setUnread] = useState(!announcement.read);
|
||||
const { read, id } = announcement;
|
||||
|
||||
// Dismiss announcement when it becomes active.
|
||||
const dispatch = useAppDispatch();
|
||||
useEffect(() => {
|
||||
// Only update `unread` marker once the announcement is out of view
|
||||
if (!selected && unread !== !announcement.read) {
|
||||
setUnread(!announcement.read);
|
||||
if (selected && !read) {
|
||||
dispatch(dismissAnnouncement(id));
|
||||
}
|
||||
}, [announcement.read, selected, unread]);
|
||||
}, [selected, id, dispatch, read]);
|
||||
|
||||
// But visually show the announcement as read only when it goes out of view.
|
||||
const [unread, setUnread] = useState(!read);
|
||||
useEffect(() => {
|
||||
if (!selected && unread !== !read) {
|
||||
setUnread(!read);
|
||||
}
|
||||
}, [selected, unread, read]);
|
||||
|
||||
return (
|
||||
<AnimateEmojiProvider className='announcements__item'>
|
||||
|
||||
@@ -299,6 +299,12 @@ class Status extends ImmutablePureComponent {
|
||||
dispatch(openModal({ modalType: 'COMPOSE_PRIVACY', modalProps: { statusId, onChange: handleChange } }));
|
||||
};
|
||||
|
||||
handleQuote = (status) => {
|
||||
const { dispatch } = this.props;
|
||||
|
||||
dispatch(quoteComposeById(status.get('id')));
|
||||
};
|
||||
|
||||
handleEditClick = (status) => {
|
||||
const { dispatch, askReplyConfirmation } = this.props;
|
||||
|
||||
@@ -625,6 +631,7 @@ class Status extends ImmutablePureComponent {
|
||||
onDelete={this.handleDeleteClick}
|
||||
onRevokeQuote={this.handleRevokeQuoteClick}
|
||||
onQuotePolicyChange={this.handleQuotePolicyChange}
|
||||
onQuote={this.handleQuote}
|
||||
onEdit={this.handleEditClick}
|
||||
onDirect={this.handleDirectClick}
|
||||
onMention={this.handleMentionClick}
|
||||
|
||||
@@ -18,6 +18,7 @@ export const ConfirmationModal: React.FC<
|
||||
onSecondary?: () => void;
|
||||
onConfirm: () => void;
|
||||
closeWhenConfirm?: boolean;
|
||||
extraContent?: React.ReactNode;
|
||||
} & BaseConfirmationModalProps
|
||||
> = ({
|
||||
title,
|
||||
@@ -29,6 +30,7 @@ export const ConfirmationModal: React.FC<
|
||||
secondary,
|
||||
onSecondary,
|
||||
closeWhenConfirm = true,
|
||||
extraContent,
|
||||
}) => {
|
||||
const handleClick = useCallback(() => {
|
||||
if (closeWhenConfirm) {
|
||||
@@ -49,6 +51,8 @@ export const ConfirmationModal: React.FC<
|
||||
<div className='safety-action-modal__confirmation'>
|
||||
<h1>{title}</h1>
|
||||
{message && <p>{message}</p>}
|
||||
|
||||
{extraContent}
|
||||
</div>
|
||||
</div>
|
||||
|
||||
|
||||
@@ -0,0 +1,88 @@
|
||||
import { forwardRef, useCallback, useState } from 'react';
|
||||
|
||||
import { defineMessages, FormattedMessage, useIntl } from 'react-intl';
|
||||
|
||||
import { submitCompose } from '@/mastodon/actions/compose';
|
||||
import { changeSetting } from '@/mastodon/actions/settings';
|
||||
import { CheckBox } from '@/mastodon/components/check_box';
|
||||
import { useAppDispatch } from '@/mastodon/store';
|
||||
|
||||
import { ConfirmationModal } from './confirmation_modal';
|
||||
import type { BaseConfirmationModalProps } from './confirmation_modal';
|
||||
import classes from './styles.module.css';
|
||||
|
||||
export const PRIVATE_QUOTE_MODAL_ID = 'quote/private_notify';
|
||||
|
||||
const messages = defineMessages({
|
||||
title: {
|
||||
id: 'confirmations.private_quote_notify.title',
|
||||
defaultMessage: 'Share with followers and mentioned users?',
|
||||
},
|
||||
message: {
|
||||
id: 'confirmations.private_quote_notify.message',
|
||||
defaultMessage:
|
||||
'The person you are quoting and other mentions ' +
|
||||
"will be notified and will be able to view your post, even if they're not following you.",
|
||||
},
|
||||
confirm: {
|
||||
id: 'confirmations.private_quote_notify.confirm',
|
||||
defaultMessage: 'Publish post',
|
||||
},
|
||||
cancel: {
|
||||
id: 'confirmations.private_quote_notify.cancel',
|
||||
defaultMessage: 'Back to editing',
|
||||
},
|
||||
});
|
||||
|
||||
export const PrivateQuoteNotify = forwardRef<
|
||||
HTMLDivElement,
|
||||
BaseConfirmationModalProps
|
||||
>(
|
||||
(
|
||||
{ onClose },
|
||||
// eslint-disable-next-line @typescript-eslint/no-unused-vars
|
||||
_ref,
|
||||
) => {
|
||||
const intl = useIntl();
|
||||
|
||||
const [dismiss, setDismissed] = useState(false);
|
||||
const handleDismissToggle = useCallback(() => {
|
||||
setDismissed((prev) => !prev);
|
||||
}, []);
|
||||
|
||||
const dispatch = useAppDispatch();
|
||||
const handleConfirm = useCallback(() => {
|
||||
dispatch(submitCompose());
|
||||
if (dismiss) {
|
||||
dispatch(
|
||||
changeSetting(['dismissed_banners', PRIVATE_QUOTE_MODAL_ID], true),
|
||||
);
|
||||
}
|
||||
}, [dismiss, dispatch]);
|
||||
|
||||
return (
|
||||
<ConfirmationModal
|
||||
title={intl.formatMessage(messages.title)}
|
||||
message={intl.formatMessage(messages.message)}
|
||||
confirm={intl.formatMessage(messages.confirm)}
|
||||
cancel={intl.formatMessage(messages.cancel)}
|
||||
onConfirm={handleConfirm}
|
||||
onClose={onClose}
|
||||
extraContent={
|
||||
<label className={classes.checkbox_wrapper}>
|
||||
<CheckBox
|
||||
value='hide'
|
||||
checked={dismiss}
|
||||
onChange={handleDismissToggle}
|
||||
/>{' '}
|
||||
<FormattedMessage
|
||||
id='confirmations.private_quote_notify.do_not_show_again'
|
||||
defaultMessage="Don't show me this message again"
|
||||
/>
|
||||
</label>
|
||||
}
|
||||
/>
|
||||
);
|
||||
},
|
||||
);
|
||||
PrivateQuoteNotify.displayName = 'PrivateQuoteNotify';
|
||||
@@ -0,0 +1,7 @@
|
||||
.checkbox_wrapper {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
gap: 0.5rem;
|
||||
margin: 1rem 0;
|
||||
cursor: pointer;
|
||||
}
|
||||
@@ -47,6 +47,7 @@ import MediaModal from './media_modal';
|
||||
import { ModalPlaceholder } from './modal_placeholder';
|
||||
import VideoModal from './video_modal';
|
||||
import { VisibilityModal } from './visibility_modal';
|
||||
import { PrivateQuoteNotify } from './confirmation_modals/private_quote_notify';
|
||||
|
||||
export const MODAL_COMPONENTS = {
|
||||
'MEDIA': () => Promise.resolve({ default: MediaModal }),
|
||||
@@ -66,6 +67,7 @@ export const MODAL_COMPONENTS = {
|
||||
'CONFIRM_LOG_OUT': () => Promise.resolve({ default: ConfirmLogOutModal }),
|
||||
'CONFIRM_FOLLOW_TO_LIST': () => Promise.resolve({ default: ConfirmFollowToListModal }),
|
||||
'CONFIRM_MISSING_ALT_TEXT': () => Promise.resolve({ default: ConfirmMissingAltTextModal }),
|
||||
'CONFIRM_PRIVATE_QUOTE_NOTIFY': () => Promise.resolve({ default: PrivateQuoteNotify }),
|
||||
'CONFIRM_REVOKE_QUOTE': () => Promise.resolve({ default: ConfirmRevokeQuoteModal }),
|
||||
'CONFIRM_QUIET_QUOTE': () => Promise.resolve({ default: QuietPostQuoteInfoModal }),
|
||||
'MUTE': MuteModal,
|
||||
|
||||
@@ -128,9 +128,12 @@ export const VisibilityModal: FC<VisibilityModalProps> = forwardRef(
|
||||
const disableVisibility = !!statusId;
|
||||
const disableQuotePolicy =
|
||||
visibility === 'private' || visibility === 'direct';
|
||||
const disablePublicVisibilities: boolean = useAppSelector(
|
||||
const disablePublicVisibilities = useAppSelector(
|
||||
selectDisablePublicVisibilities,
|
||||
);
|
||||
const isQuotePost = useAppSelector(
|
||||
(state) => state.compose.get('quoted_status_id') !== null,
|
||||
);
|
||||
|
||||
const visibilityItems = useMemo<SelectItem<StatusVisibility>[]>(() => {
|
||||
const items: SelectItem<StatusVisibility>[] = [
|
||||
@@ -315,6 +318,21 @@ export const VisibilityModal: FC<VisibilityModalProps> = forwardRef(
|
||||
id={quoteDescriptionId}
|
||||
/>
|
||||
</div>
|
||||
|
||||
{isQuotePost && visibility === 'direct' && (
|
||||
<div className='visibility-modal__quote-warning'>
|
||||
<FormattedMessage
|
||||
id='visibility_modal.direct_quote_warning.title'
|
||||
defaultMessage="Quotes can't be embedded in private mentions"
|
||||
tagName='h3'
|
||||
/>
|
||||
<FormattedMessage
|
||||
id='visibility_modal.direct_quote_warning.text'
|
||||
defaultMessage='If you save the current settings, the embedded quote will be converted to a link.'
|
||||
tagName='p'
|
||||
/>
|
||||
</div>
|
||||
)}
|
||||
</div>
|
||||
<div className='dialog-modal__content__actions'>
|
||||
<Button onClick={onClose} secondary>
|
||||
|
||||
@@ -35,7 +35,7 @@ interface InitialStateMeta {
|
||||
streaming_api_base_url: string;
|
||||
local_live_feed_access: 'public' | 'authenticated' | 'disabled';
|
||||
remote_live_feed_access: 'public' | 'authenticated' | 'disabled';
|
||||
local_topic_feed_access: 'public' | 'authenticated' | 'disabled';
|
||||
local_topic_feed_access: 'public' | 'authenticated';
|
||||
remote_topic_feed_access: 'public' | 'authenticated' | 'disabled';
|
||||
title: string;
|
||||
show_trends: boolean;
|
||||
|
||||
@@ -247,6 +247,7 @@
|
||||
"confirmations.missing_alt_text.secondary": "Усё адно апублікаваць",
|
||||
"confirmations.missing_alt_text.title": "Дадаць альтэрнатыўны тэкст?",
|
||||
"confirmations.mute.confirm": "Ігнараваць",
|
||||
"confirmations.private_quote_notify.cancel": "Звяртацца да рэдагавання",
|
||||
"confirmations.quiet_post_quote_info.dismiss": "Не нагадваць зноў",
|
||||
"confirmations.quiet_post_quote_info.got_it": "Зразумела",
|
||||
"confirmations.quiet_post_quote_info.message": "Калі будзеце цытаваць ціхі публічны допіс, Ваш допіс будзе схаваны ад трэндавых стужак.",
|
||||
|
||||
@@ -192,6 +192,7 @@
|
||||
"community.column_settings.local_only": "Només local",
|
||||
"community.column_settings.media_only": "Només contingut",
|
||||
"community.column_settings.remote_only": "Només remot",
|
||||
"compose.error.blank_post": "La publicació no pot estar en blanc.",
|
||||
"compose.language.change": "Canvia d'idioma",
|
||||
"compose.language.search": "Cerca idiomes...",
|
||||
"compose.published.body": "Tut publicat.",
|
||||
@@ -749,7 +750,9 @@
|
||||
"privacy.unlisted.short": "Públic silenciós",
|
||||
"privacy_policy.last_updated": "Darrera actualització {date}",
|
||||
"privacy_policy.title": "Política de Privacitat",
|
||||
"quote_error.edit": "No es poden afegir cites en editar una publicació.",
|
||||
"quote_error.poll": "Amb les enquestes no es permeten cites.",
|
||||
"quote_error.private_mentions": "Amb mencions directes no es permeten cites.",
|
||||
"quote_error.quote": "Només es permet una cita alhora.",
|
||||
"quote_error.unauthorized": "No se us permet de citar aquesta publicació.",
|
||||
"quote_error.upload": "Amb media adjunts no es permeten cites.",
|
||||
@@ -871,6 +874,7 @@
|
||||
"status.contains_quote": "Conté una cita",
|
||||
"status.context.loading": "Es carreguen més respostes",
|
||||
"status.context.loading_error": "No s'han pogut carregar respostes noves",
|
||||
"status.context.loading_success": "S'han carregat les noves respostes",
|
||||
"status.context.more_replies_found": "S'han trobat més respostes",
|
||||
"status.context.retry": "Torna-ho a provar",
|
||||
"status.context.show": "Mostra",
|
||||
@@ -902,9 +906,12 @@
|
||||
"status.pin": "Fixa en el perfil",
|
||||
"status.quote": "Cita",
|
||||
"status.quote.cancel": "Canceŀlar la citació",
|
||||
"status.quote_error.blocked_account_hint.title": "Aquesta publicació està amagada perquè heu blocat a @{name}.",
|
||||
"status.quote_error.blocked_domain_hint.title": "Aquesta publicació està amagada perquè heu blocat a {domain}.",
|
||||
"status.quote_error.filtered": "No es mostra a causa d'un dels vostres filtres",
|
||||
"status.quote_error.limited_account_hint.action": "Mostra-la igualment",
|
||||
"status.quote_error.limited_account_hint.title": "Aquest perfil l'han amagat els moderadors de {domain}.",
|
||||
"status.quote_error.muted_account_hint.title": "Aquesta publicació està amagada perquè heu silenciat a @{name}.",
|
||||
"status.quote_error.not_available": "Publicació no disponible",
|
||||
"status.quote_error.pending_approval": "Publicació pendent",
|
||||
"status.quote_error.pending_approval_popout.body": "A Mastodon pots controlar si algú et pot citar. Aquesta publicació està pendent mentre esperem l'aprovació de l'autor original.",
|
||||
@@ -1003,6 +1010,7 @@
|
||||
"visibility_modal.helper.direct_quoting": "No es poden citar mencions privades fetes a Mastondon.",
|
||||
"visibility_modal.helper.private_quoting": "No es poden citar publicacions fetes a Mastodon només per a seguidors.",
|
||||
"visibility_modal.helper.unlisted_quoting": "Quan la gent et citi les seves publicacions estaran amagades de les línies de temps de tendències.",
|
||||
"visibility_modal.instructions": "Controleu qui pot interactuar amb aquesta publicació. També podeu aplicar la configuració a totes les publicacions futures navegant a <link>Preferències > Valors per defecte de publicació</link>.",
|
||||
"visibility_modal.privacy_label": "Visibilitat",
|
||||
"visibility_modal.quote_followers": "Només seguidors",
|
||||
"visibility_modal.quote_label": "Qui pot citar",
|
||||
|
||||
@@ -194,6 +194,7 @@
|
||||
"community.column_settings.local_only": "Pouze místní",
|
||||
"community.column_settings.media_only": "Pouze média",
|
||||
"community.column_settings.remote_only": "Pouze vzdálené",
|
||||
"compose.error.blank_post": "Příspěvek nemůže být prázdný.",
|
||||
"compose.language.change": "Změnit jazyk",
|
||||
"compose.language.search": "Prohledat jazyky...",
|
||||
"compose.published.body": "Příspěvek zveřejněn.",
|
||||
@@ -246,6 +247,11 @@
|
||||
"confirmations.missing_alt_text.secondary": "Přesto odeslat",
|
||||
"confirmations.missing_alt_text.title": "Přidat popisek?",
|
||||
"confirmations.mute.confirm": "Skrýt",
|
||||
"confirmations.private_quote_notify.cancel": "Zpět k úpravám",
|
||||
"confirmations.private_quote_notify.confirm": "Publikovat příspěvek",
|
||||
"confirmations.private_quote_notify.do_not_show_again": "Nezobrazujte mi znovu tuto zprávu",
|
||||
"confirmations.private_quote_notify.message": "Osoba, kterou citujete, a další zmínění budou upozorněni a budou moci si zobrazit váš příspěvek, i pokud vás nesledují.",
|
||||
"confirmations.private_quote_notify.title": "Sdílet se sledujícími a zmíněnými uživateli?",
|
||||
"confirmations.quiet_post_quote_info.dismiss": "Znovu nepřípomínat",
|
||||
"confirmations.quiet_post_quote_info.got_it": "Rozumím",
|
||||
"confirmations.quiet_post_quote_info.message": "Při citování ztišeného veřejného příspěvku, váš příspěvek bude skrytý z os populárních příspěvků.",
|
||||
@@ -758,6 +764,7 @@
|
||||
"privacy_policy.title": "Zásady ochrany osobních údajů",
|
||||
"quote_error.edit": "Citáty nemohou být přidány při úpravě příspěvku.",
|
||||
"quote_error.poll": "Citování není u dotazníků povoleno.",
|
||||
"quote_error.private_mentions": "Citování není povoleno s přímými zmínkami.",
|
||||
"quote_error.quote": "Je povoleno citovat pouze jednou.",
|
||||
"quote_error.unauthorized": "Nemáte oprávnění citovat tento příspěvek.",
|
||||
"quote_error.upload": "Není povoleno citovat s přílohami.",
|
||||
@@ -1011,6 +1018,8 @@
|
||||
"video.volume_down": "Snížit hlasitost",
|
||||
"video.volume_up": "Zvýšit hlasitost",
|
||||
"visibility_modal.button_title": "Nastavit viditelnost",
|
||||
"visibility_modal.direct_quote_warning.text": "Pokud uložíte aktuální nastavení, vložená citace bude převedena na odkaz.",
|
||||
"visibility_modal.direct_quote_warning.title": "Citace nemohou být vloženy do soukromých zmínek",
|
||||
"visibility_modal.header": "Viditelnost a interakce",
|
||||
"visibility_modal.helper.direct_quoting": "Soukromé zmínky, které jsou vytvořeny na Mastodonu, nemohou být citovány ostatními.",
|
||||
"visibility_modal.helper.privacy_editing": "Viditelnost nelze změnit po publikování příspěvku.",
|
||||
|
||||
@@ -173,6 +173,8 @@
|
||||
"column.edit_list": "Golygu rhestr",
|
||||
"column.favourites": "Ffefrynnau",
|
||||
"column.firehose": "Ffrydiau byw",
|
||||
"column.firehose_local": "Ffrwd fyw ar gyfer y gweinydd hwn",
|
||||
"column.firehose_singular": "Ffrwd fyw",
|
||||
"column.follow_requests": "Ceisiadau dilyn",
|
||||
"column.home": "Cartref",
|
||||
"column.list_members": "Rheoli aelodau rhestr",
|
||||
@@ -192,6 +194,7 @@
|
||||
"community.column_settings.local_only": "Lleol yn unig",
|
||||
"community.column_settings.media_only": "Cyfryngau yn unig",
|
||||
"community.column_settings.remote_only": "Pell yn unig",
|
||||
"compose.error.blank_post": "Gall postiad ddim bod yn wag.",
|
||||
"compose.language.change": "Newid iaith",
|
||||
"compose.language.search": "Chwilio ieithoedd...",
|
||||
"compose.published.body": "Postiad wedi ei gyhoeddi.",
|
||||
@@ -909,9 +912,12 @@
|
||||
"status.pin": "Pinio ar y proffil",
|
||||
"status.quote": "Dyfynnu",
|
||||
"status.quote.cancel": "Diddymu'r dyfyniad",
|
||||
"status.quote_error.blocked_account_hint.title": "Mae'r postiad hwn wedi'i guddio oherwydd eich bod wedi rhwystro @{name}.",
|
||||
"status.quote_error.blocked_domain_hint.title": "Mae'r postiad hwn wedi'i guddio oherwydd eich bod wedi rhwystro {domain}.",
|
||||
"status.quote_error.filtered": "Wedi'i guddio oherwydd un o'ch hidlwyr",
|
||||
"status.quote_error.limited_account_hint.action": "Dangos beth bynnag",
|
||||
"status.quote_error.limited_account_hint.title": "Mae'r cyfrif hwn wedi'i guddio gan gymedrolwyr {domain}.",
|
||||
"status.quote_error.muted_account_hint.title": "Mae'r postiad hwn wedi'i guddio oherwydd eich bod wedi mudo @{name}.",
|
||||
"status.quote_error.not_available": "Postiad ddim ar gael",
|
||||
"status.quote_error.pending_approval": "Postiad yn yr arfaeth",
|
||||
"status.quote_error.pending_approval_popout.body": "Ar Mastodon, gallwch reoli os yw rhywun yn gallu eich dyfynnu. Mae'r postiad hwn yn cael ei ddal nôl tra'n bod yn cael cymeradwyaeth yr awdur gwreiddiol.",
|
||||
|
||||
@@ -247,6 +247,11 @@
|
||||
"confirmations.missing_alt_text.secondary": "Læg op alligevel",
|
||||
"confirmations.missing_alt_text.title": "Tilføj alt-tekst?",
|
||||
"confirmations.mute.confirm": "Skjul",
|
||||
"confirmations.private_quote_notify.cancel": "Tilbage til redigering",
|
||||
"confirmations.private_quote_notify.confirm": "Offentliggør indlæg",
|
||||
"confirmations.private_quote_notify.do_not_show_again": "Vis ikke denne besked igen",
|
||||
"confirmations.private_quote_notify.message": "Den person, du citerer og andre omtalte vil blive underrettet, og vil være i stand til at se dit indlæg, selv om de ikke følger dig.",
|
||||
"confirmations.private_quote_notify.title": "Del med følgere og omtalte brugere?",
|
||||
"confirmations.quiet_post_quote_info.dismiss": "Påmind mig ikke igen",
|
||||
"confirmations.quiet_post_quote_info.got_it": "Forstået",
|
||||
"confirmations.quiet_post_quote_info.message": "Når du citerer et stille offentligt indlæg, vil dit indlæg blive skjult fra trendtidslinjer.",
|
||||
@@ -282,7 +287,7 @@
|
||||
"directory.recently_active": "Aktive for nyligt",
|
||||
"disabled_account_banner.account_settings": "Kontoindstillinger",
|
||||
"disabled_account_banner.text": "Din konto {disabledAccount} er pt. deaktiveret.",
|
||||
"dismissable_banner.community_timeline": "Disse er de seneste offentlige indlæg fra personer med konti hostet af {domain}.",
|
||||
"dismissable_banner.community_timeline": "Dette er de seneste offentlige indlæg fra personer med konti hostet af {domain}.",
|
||||
"dismissable_banner.dismiss": "Afvis",
|
||||
"dismissable_banner.public_timeline": "Dette er de seneste offentlige indlæg fra personer på fediverset, som folk på {domain} følger.",
|
||||
"domain_block_modal.block": "Blokér server",
|
||||
@@ -759,6 +764,7 @@
|
||||
"privacy_policy.title": "Privatlivspolitik",
|
||||
"quote_error.edit": "Citater kan ikke tilføjes ved redigering af et indlæg.",
|
||||
"quote_error.poll": "Citering ikke tilladt i afstemninger.",
|
||||
"quote_error.private_mentions": "Citering er ikke tilladt med direkte omtaler.",
|
||||
"quote_error.quote": "Kun ét citat ad gangen er tilladt.",
|
||||
"quote_error.unauthorized": "Du har ikke tilladelse til at citere dette indlæg.",
|
||||
"quote_error.upload": "Citering ikke tilladt ved medievedhæftninger.",
|
||||
@@ -1012,6 +1018,8 @@
|
||||
"video.volume_down": "Lydstyrke ned",
|
||||
"video.volume_up": "Lydstyrke op",
|
||||
"visibility_modal.button_title": "Indstil synlighed",
|
||||
"visibility_modal.direct_quote_warning.text": "Hvis du gemmer de aktuelle indstillinger, vil det indlejrede citat blive konverteret til et link.",
|
||||
"visibility_modal.direct_quote_warning.title": "Citater kan ikke indlejres i private omtaler",
|
||||
"visibility_modal.header": "Synlighed og interaktion",
|
||||
"visibility_modal.helper.direct_quoting": "Private omtaler forfattet på Mastodon kan ikke citeres af andre.",
|
||||
"visibility_modal.helper.privacy_editing": "Synlighed kan ikke ændres, efter at et indlæg er offentliggjort.",
|
||||
|
||||
@@ -247,6 +247,11 @@
|
||||
"confirmations.missing_alt_text.secondary": "Trotzdem veröffentlichen",
|
||||
"confirmations.missing_alt_text.title": "Bildbeschreibung hinzufügen?",
|
||||
"confirmations.mute.confirm": "Stummschalten",
|
||||
"confirmations.private_quote_notify.cancel": "Zurück zum Bearbeiten",
|
||||
"confirmations.private_quote_notify.confirm": "Beitrag veröffentlichen",
|
||||
"confirmations.private_quote_notify.do_not_show_again": "Diesen Hinweis nicht mehr anzeigen",
|
||||
"confirmations.private_quote_notify.message": "Dein Beitrag wird von dem zitierten sowie den erwähnten Profilen gesehen werden können, auch wenn sie dir nicht folgen.",
|
||||
"confirmations.private_quote_notify.title": "Mit Followern und erwähnten Profilen teilen?",
|
||||
"confirmations.quiet_post_quote_info.dismiss": "Nicht mehr anzeigen",
|
||||
"confirmations.quiet_post_quote_info.got_it": "Verstanden",
|
||||
"confirmations.quiet_post_quote_info.message": "Beim Zitieren eines Beitrags mit der Sichtbarkeit „Öffentlich (still)“ wird dein zitierter Beitrag ebenfalls nicht in den Trends und öffentlichen Timelines angezeigt.",
|
||||
@@ -759,6 +764,7 @@
|
||||
"privacy_policy.title": "Datenschutzerklärung",
|
||||
"quote_error.edit": "Beim Bearbeiten eines Beitrags können keine Zitate hinzugefügt werden.",
|
||||
"quote_error.poll": "Zitieren ist bei Umfragen nicht gestattet.",
|
||||
"quote_error.private_mentions": "Das Zitieren ist bei privaten Erwähnungen nicht erlaubt.",
|
||||
"quote_error.quote": "Es ist jeweils nur ein Zitat zulässig.",
|
||||
"quote_error.unauthorized": "Du bist nicht berechtigt, diesen Beitrag zu zitieren.",
|
||||
"quote_error.upload": "Zitieren ist mit Medien-Anhängen nicht möglich.",
|
||||
@@ -1012,6 +1018,8 @@
|
||||
"video.volume_down": "Leiser",
|
||||
"video.volume_up": "Lauter",
|
||||
"visibility_modal.button_title": "Sichtbarkeit festlegen",
|
||||
"visibility_modal.direct_quote_warning.text": "Wenn diese Einstellungen gespeichert werden, wird das eingebettete Zitat in einen Link umgewandelt.",
|
||||
"visibility_modal.direct_quote_warning.title": "Zitate können in privaten Erwähnungen nicht eingebettet werden",
|
||||
"visibility_modal.header": "Sichtbarkeit und Interaktion",
|
||||
"visibility_modal.helper.direct_quoting": "Private Erwähnungen, die auf Mastodon verfasst wurden, können nicht von anderen zitiert werden.",
|
||||
"visibility_modal.helper.privacy_editing": "Die Sichtbarkeit eines bereits veröffentlichten Beitrags kann nachträglich nicht mehr geändert werden.",
|
||||
|
||||
@@ -194,6 +194,7 @@
|
||||
"community.column_settings.local_only": "Τοπικά μόνο",
|
||||
"community.column_settings.media_only": "Μόνο πολυμέσα",
|
||||
"community.column_settings.remote_only": "Απομακρυσμένα μόνο",
|
||||
"compose.error.blank_post": "Η ανάρτηση δεν μπορεί να είναι κενή.",
|
||||
"compose.language.change": "Αλλαγή γλώσσας",
|
||||
"compose.language.search": "Αναζήτηση γλωσσών...",
|
||||
"compose.published.body": "Η ανάρτηση δημοσιεύτηκε.",
|
||||
@@ -246,6 +247,11 @@
|
||||
"confirmations.missing_alt_text.secondary": "Δημοσίευση όπως και να ΄χει",
|
||||
"confirmations.missing_alt_text.title": "Προσθήκη εναλλακτικού κειμένου;",
|
||||
"confirmations.mute.confirm": "Αποσιώπηση",
|
||||
"confirmations.private_quote_notify.cancel": "Πίσω στην επεξεργασία",
|
||||
"confirmations.private_quote_notify.confirm": "Δημοσίευση ανάρτησης",
|
||||
"confirmations.private_quote_notify.do_not_show_again": "Να μην εμφανιστεί ξανά αυτό το μήνυμα",
|
||||
"confirmations.private_quote_notify.message": "Το άτομο που παραθέτετε και άλλες επισημάνσεις θα ειδοποιηθούν και θα μπορούν να δουν την ανάρτησή σας, ακόμη και αν δεν σας ακολουθούν.",
|
||||
"confirmations.private_quote_notify.title": "Κοινοποίηση με τους ακολούθους και τους επισημασμένους χρήστες;",
|
||||
"confirmations.quiet_post_quote_info.dismiss": "Μη μου το ξαναθυμίσεις",
|
||||
"confirmations.quiet_post_quote_info.got_it": "Το κατάλαβα",
|
||||
"confirmations.quiet_post_quote_info.message": "Όταν παραθέτετε μια ήσυχη δημόσια ανάρτηση, η ανάρτηση σας θα είναι κρυμμένη από τις δημοφιλείς ροές.",
|
||||
@@ -758,6 +764,7 @@
|
||||
"privacy_policy.title": "Πολιτική Απορρήτου",
|
||||
"quote_error.edit": "Δεν μπορούν να προστεθούν παραθέσεις κατά την επεξεργασία μιας ανάρτησης.",
|
||||
"quote_error.poll": "Η παράθεση δεν επιτρέπεται με δημοσκοπήσεις.",
|
||||
"quote_error.private_mentions": "Η παράθεση δεν επιτρέπεται με άμεσες επισημάνσεις.",
|
||||
"quote_error.quote": "Επιτρέπεται μόνο μία παράθεση τη φορά.",
|
||||
"quote_error.unauthorized": "Δεν είστε εξουσιοδοτημένοι να παραθέσετε αυτή την ανάρτηση.",
|
||||
"quote_error.upload": "Η παράθεση δεν επιτρέπεται με συνημμένα πολυμέσων.",
|
||||
@@ -1011,6 +1018,8 @@
|
||||
"video.volume_down": "Μείωση έντασης",
|
||||
"video.volume_up": "Αύξηση έντασης",
|
||||
"visibility_modal.button_title": "Ορισμός ορατότητας",
|
||||
"visibility_modal.direct_quote_warning.text": "Εάν αποθηκεύσετε τις τρέχουσες ρυθμίσεις, η ενσωματωμένη παράθεση θα μετατραπεί σε σύνδεσμο.",
|
||||
"visibility_modal.direct_quote_warning.title": "Οι παραθέσεις δεν μπορούν να ενσωματωθούν σε ιδιωτικές επισημάνσεις",
|
||||
"visibility_modal.header": "Ορατότητα και αλληλεπίδραση",
|
||||
"visibility_modal.helper.direct_quoting": "Ιδιωτικές αναφορές που έχουν συνταχθεί στο Mastodon δεν μπορούν να γίνουν παράθεση από άλλους.",
|
||||
"visibility_modal.helper.privacy_editing": "Η ορατότητα δεν μπορεί να αλλάξει μετά τη δημοσίευση μιας ανάρτησης.",
|
||||
|
||||
@@ -247,6 +247,11 @@
|
||||
"confirmations.missing_alt_text.secondary": "Post anyway",
|
||||
"confirmations.missing_alt_text.title": "Add alt text?",
|
||||
"confirmations.mute.confirm": "Mute",
|
||||
"confirmations.private_quote_notify.cancel": "Back to editing",
|
||||
"confirmations.private_quote_notify.confirm": "Publish post",
|
||||
"confirmations.private_quote_notify.do_not_show_again": "Don't show me this message again",
|
||||
"confirmations.private_quote_notify.message": "The person you are quoting and other mentions will be notified and will be able to view your post, even if they're not following you.",
|
||||
"confirmations.private_quote_notify.title": "Share with followers and mentioned users?",
|
||||
"confirmations.quiet_post_quote_info.dismiss": "Don't remind me again",
|
||||
"confirmations.quiet_post_quote_info.got_it": "Got it",
|
||||
"confirmations.quiet_post_quote_info.message": "When quoting a quiet public post, your post will be hidden from trending timelines.",
|
||||
@@ -759,6 +764,7 @@
|
||||
"privacy_policy.title": "Privacy Policy",
|
||||
"quote_error.edit": "Quotes cannot be added when editing a post.",
|
||||
"quote_error.poll": "Quoting is not allowed with polls.",
|
||||
"quote_error.private_mentions": "Quoting is not allowed with direct mentions.",
|
||||
"quote_error.quote": "Only one quote at a time is allowed.",
|
||||
"quote_error.unauthorized": "You are not authorized to quote this post.",
|
||||
"quote_error.upload": "Quoting is not allowed with media attachments.",
|
||||
@@ -1012,6 +1018,8 @@
|
||||
"video.volume_down": "Volume down",
|
||||
"video.volume_up": "Volume up",
|
||||
"visibility_modal.button_title": "Set visibility",
|
||||
"visibility_modal.direct_quote_warning.text": "If you save the current settings, the embedded quote will be converted to a link.",
|
||||
"visibility_modal.direct_quote_warning.title": "Quotes can't be embedded in private mentions",
|
||||
"visibility_modal.header": "Visibility and interaction",
|
||||
"visibility_modal.helper.direct_quoting": "Private mentions authored on Mastodon can't be quoted by others.",
|
||||
"visibility_modal.helper.privacy_editing": "Visibility can't be changed after a post is published.",
|
||||
|
||||
@@ -39,6 +39,7 @@
|
||||
"account.featured_tags.last_status_never": "Neniu afiŝo",
|
||||
"account.follow": "Sekvi",
|
||||
"account.follow_back": "Sekvu reen",
|
||||
"account.follow_back_short": "Sekvu reen",
|
||||
"account.followers": "Sekvantoj",
|
||||
"account.followers.empty": "Ankoraŭ neniu sekvas ĉi tiun uzanton.",
|
||||
"account.followers_counter": "{count, plural, one{{counter} sekvanto} other {{counter} sekvantoj}}",
|
||||
|
||||
@@ -247,6 +247,11 @@
|
||||
"confirmations.missing_alt_text.secondary": "Enviar de todos modos",
|
||||
"confirmations.missing_alt_text.title": "¿Agregar texto alternativo?",
|
||||
"confirmations.mute.confirm": "Silenciar",
|
||||
"confirmations.private_quote_notify.cancel": "Volver a editar",
|
||||
"confirmations.private_quote_notify.confirm": "Enviar mensaje",
|
||||
"confirmations.private_quote_notify.do_not_show_again": "No mostrarme este mensaje de nuevo",
|
||||
"confirmations.private_quote_notify.message": "La cuenta a la que estás citando y otras menciones serán notificadas y podrán ver tu mensaje, incluso si no te están siguiendo.",
|
||||
"confirmations.private_quote_notify.title": "¿Compartir con seguidores y usuarios mencionados?",
|
||||
"confirmations.quiet_post_quote_info.dismiss": "No recordar de nuevo",
|
||||
"confirmations.quiet_post_quote_info.got_it": "Entendido",
|
||||
"confirmations.quiet_post_quote_info.message": "Al citar un mensaje público pero silencioso, tu mensaje se ocultará de las líneas temporales de tendencias.",
|
||||
@@ -759,6 +764,7 @@
|
||||
"privacy_policy.title": "Política de privacidad",
|
||||
"quote_error.edit": "Las citas no se pueden agregar al editar un mensaje.",
|
||||
"quote_error.poll": "No se permite citar encuestas.",
|
||||
"quote_error.private_mentions": "No se permite citar con menciones directas.",
|
||||
"quote_error.quote": "Solo se permite una cita a la vez.",
|
||||
"quote_error.unauthorized": "No tenés autorización para citar este mensaje.",
|
||||
"quote_error.upload": "No se permite citar con archivos multimedia.",
|
||||
@@ -1012,6 +1018,8 @@
|
||||
"video.volume_down": "Bajar volumen",
|
||||
"video.volume_up": "Subir volumen",
|
||||
"visibility_modal.button_title": "Establecer visibilidad",
|
||||
"visibility_modal.direct_quote_warning.text": "Si guardás la configuración actual, la cita insertada se convertirá en un enlace.",
|
||||
"visibility_modal.direct_quote_warning.title": "Las citas no pueden ser insertadas en menciones privadas",
|
||||
"visibility_modal.header": "Visibilidad e interacción",
|
||||
"visibility_modal.helper.direct_quoting": "Las menciones privadas redactadas en Mastodon no pueden ser citadas por otras cuentas.",
|
||||
"visibility_modal.helper.privacy_editing": "La visibilidad no se puede cambiar después de que se haya enviado un mensaje.",
|
||||
|
||||
@@ -42,7 +42,7 @@
|
||||
"account.follow": "Seguir",
|
||||
"account.follow_back": "Seguir también",
|
||||
"account.follow_back_short": "Seguir también",
|
||||
"account.follow_request": "Solicitud de seguimiento",
|
||||
"account.follow_request": "Solicitar seguimiento",
|
||||
"account.follow_request_cancel": "Cancelar solicitud",
|
||||
"account.follow_request_cancel_short": "Cancelar",
|
||||
"account.follow_request_short": "Solicitar",
|
||||
@@ -173,8 +173,8 @@
|
||||
"column.edit_list": "Editar lista",
|
||||
"column.favourites": "Favoritos",
|
||||
"column.firehose": "Cronologías",
|
||||
"column.firehose_local": "Cronología para este servidor",
|
||||
"column.firehose_singular": "Cronología",
|
||||
"column.firehose_local": "Feed en vivo para este servidor",
|
||||
"column.firehose_singular": "Feed en vivo",
|
||||
"column.follow_requests": "Solicitudes de seguimiento",
|
||||
"column.home": "Inicio",
|
||||
"column.list_members": "Administrar miembros de la lista",
|
||||
@@ -194,7 +194,7 @@
|
||||
"community.column_settings.local_only": "Solo local",
|
||||
"community.column_settings.media_only": "Solo media",
|
||||
"community.column_settings.remote_only": "Solo remoto",
|
||||
"compose.error.blank_post": "El mensaje no puede estar en blanco.",
|
||||
"compose.error.blank_post": "La publicación no puede estar vacía.",
|
||||
"compose.language.change": "Cambiar idioma",
|
||||
"compose.language.search": "Buscar idiomas...",
|
||||
"compose.published.body": "Publicado.",
|
||||
@@ -247,6 +247,11 @@
|
||||
"confirmations.missing_alt_text.secondary": "Publicar de todas maneras",
|
||||
"confirmations.missing_alt_text.title": "¿Añadir texto alternativo?",
|
||||
"confirmations.mute.confirm": "Silenciar",
|
||||
"confirmations.private_quote_notify.cancel": "Seguir editando",
|
||||
"confirmations.private_quote_notify.confirm": "Publicar",
|
||||
"confirmations.private_quote_notify.do_not_show_again": "No mostrar este mensaje de nuevo",
|
||||
"confirmations.private_quote_notify.message": "Tu publicación será notificada y podrá ser vista por la persona a la que mencionas y otras menciones, aún si no te siguen.",
|
||||
"confirmations.private_quote_notify.title": "¿Compartir con seguidores y usuarios mencionados?",
|
||||
"confirmations.quiet_post_quote_info.dismiss": "No me lo recuerdes otra vez",
|
||||
"confirmations.quiet_post_quote_info.got_it": "Entendido",
|
||||
"confirmations.quiet_post_quote_info.message": "Al citar una publicación pública discreta, tu publicación se ocultará de las cronologías de tendencias.",
|
||||
@@ -264,8 +269,8 @@
|
||||
"confirmations.unblock.title": "¿Desbloquear a {name}?",
|
||||
"confirmations.unfollow.confirm": "Dejar de seguir",
|
||||
"confirmations.unfollow.title": "¿Dejar de seguir a {name}?",
|
||||
"confirmations.withdraw_request.confirm": "Retirar solicitud",
|
||||
"confirmations.withdraw_request.title": "¿Retirar solicitud de seguimiento a {name}?",
|
||||
"confirmations.withdraw_request.confirm": "Cancelar solicitud",
|
||||
"confirmations.withdraw_request.title": "¿Cancelar solicitud para seguir a {name}?",
|
||||
"content_warning.hide": "Ocultar publicación",
|
||||
"content_warning.show": "Mostrar de todos modos",
|
||||
"content_warning.show_more": "Mostrar más",
|
||||
@@ -336,7 +341,7 @@
|
||||
"empty_column.bookmarked_statuses": "Aún no tienes ninguna publicación guardada como marcador. Cuando guardes una, se mostrará aquí.",
|
||||
"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 menciones privadas. Cuando envíes o recibas una, aparecerán aquí.",
|
||||
"empty_column.disabled_feed": "Esta cronología ha sido desactivada por los administradores del servidor.",
|
||||
"empty_column.disabled_feed": "Este feed fue desactivado por los administradores de tu servidor.",
|
||||
"empty_column.domain_blocks": "Todavía no hay dominios ocultos.",
|
||||
"empty_column.explore_statuses": "Nada es tendencia en este momento. ¡Revisa más tarde!",
|
||||
"empty_column.favourited_statuses": "Todavía no tienes publicaciones favoritas. Cuando le des favorito a una publicación se mostrarán acá.",
|
||||
@@ -757,8 +762,9 @@
|
||||
"privacy.unlisted.short": "Pública, pero discreta",
|
||||
"privacy_policy.last_updated": "Actualizado por última vez {date}",
|
||||
"privacy_policy.title": "Política de Privacidad",
|
||||
"quote_error.edit": "No se pueden añadir citas cuando se edita una publicación.",
|
||||
"quote_error.edit": "No se pueden añadir citas mientras un post está siendo editado.",
|
||||
"quote_error.poll": "No se permite citar encuestas.",
|
||||
"quote_error.private_mentions": "Citar no está disponible sin menciones directas.",
|
||||
"quote_error.quote": "Solo se permite una cita a la vez.",
|
||||
"quote_error.unauthorized": "No estás autorizado a citar esta publicación.",
|
||||
"quote_error.upload": "No se permite citar con archivos multimedia.",
|
||||
@@ -880,7 +886,7 @@
|
||||
"status.contains_quote": "Contiene cita",
|
||||
"status.context.loading": "Cargando más respuestas",
|
||||
"status.context.loading_error": "No se pudieron cargar nuevas respuestas",
|
||||
"status.context.loading_success": "Cargadas nuevas respuestas",
|
||||
"status.context.loading_success": "Nuevas respuestas cargadas",
|
||||
"status.context.more_replies_found": "Se han encontrado más respuestas",
|
||||
"status.context.retry": "Reintentar",
|
||||
"status.context.show": "Mostrar",
|
||||
@@ -912,7 +918,7 @@
|
||||
"status.pin": "Fijar",
|
||||
"status.quote": "Citar",
|
||||
"status.quote.cancel": "Cancelar cita",
|
||||
"status.quote_error.blocked_account_hint.title": "Esta publicación está oculta porque has bloqueado a @{name}.",
|
||||
"status.quote_error.blocked_account_hint.title": "Esta publicación se ocultó porque bloqueaste a @{name}.",
|
||||
"status.quote_error.blocked_domain_hint.title": "Esta publicación está oculta porque has bloqueado @{domain}.",
|
||||
"status.quote_error.filtered": "Oculto debido a uno de tus filtros",
|
||||
"status.quote_error.limited_account_hint.action": "Mostrar de todas formas",
|
||||
@@ -1012,6 +1018,8 @@
|
||||
"video.volume_down": "Bajar el volumen",
|
||||
"video.volume_up": "Subir el volumen",
|
||||
"visibility_modal.button_title": "Establece la visibilidad",
|
||||
"visibility_modal.direct_quote_warning.text": "Si guardas la siguiente configuración, se mostrará un enlace en vez de la cita incrustada.",
|
||||
"visibility_modal.direct_quote_warning.title": "No se pueden incrustar citas en menciones privadas",
|
||||
"visibility_modal.header": "Visibilidad e interacción",
|
||||
"visibility_modal.helper.direct_quoting": "Las menciones privadas creadas en Mastodon no pueden ser citadas por otros.",
|
||||
"visibility_modal.helper.privacy_editing": "La visibilidad no se puede cambiar después de que se haya hecho una publicación.",
|
||||
|
||||
@@ -247,6 +247,11 @@
|
||||
"confirmations.missing_alt_text.secondary": "Publicar de todos modos",
|
||||
"confirmations.missing_alt_text.title": "¿Deseas añadir texto alternativo?",
|
||||
"confirmations.mute.confirm": "Silenciar",
|
||||
"confirmations.private_quote_notify.cancel": "Volver a editar",
|
||||
"confirmations.private_quote_notify.confirm": "Publicar",
|
||||
"confirmations.private_quote_notify.do_not_show_again": "No mostrar este mensaje de nuevo",
|
||||
"confirmations.private_quote_notify.message": "La persona a la que estás citando y otras mencionadas serán notificadas y podrán ver tu publicación, incluso si no te siguen.",
|
||||
"confirmations.private_quote_notify.title": "¿Compartir con seguidores y usuarios mencionados?",
|
||||
"confirmations.quiet_post_quote_info.dismiss": "No me lo vuelvas a recordar",
|
||||
"confirmations.quiet_post_quote_info.got_it": "Entendido",
|
||||
"confirmations.quiet_post_quote_info.message": "Cuando cites una publicación pública silenciosa, tu publicación se ocultará de las cronologías de tendencias.",
|
||||
@@ -759,6 +764,7 @@
|
||||
"privacy_policy.title": "Política de Privacidad",
|
||||
"quote_error.edit": "No se pueden añadir citas cuando se edita una publicación.",
|
||||
"quote_error.poll": "No es posible citar encuestas.",
|
||||
"quote_error.private_mentions": "No se permite citar con menciones privadas.",
|
||||
"quote_error.quote": "Solo se permite una cita a la vez.",
|
||||
"quote_error.unauthorized": "No tienes permiso para citar esta publicación.",
|
||||
"quote_error.upload": "No se permite citar con archivos multimedia.",
|
||||
@@ -1012,6 +1018,8 @@
|
||||
"video.volume_down": "Bajar volumen",
|
||||
"video.volume_up": "Subir volumen",
|
||||
"visibility_modal.button_title": "Configura la visibilidad",
|
||||
"visibility_modal.direct_quote_warning.text": "Si guardas la configuración actual, la cita incrustada se convertirá en un enlace.",
|
||||
"visibility_modal.direct_quote_warning.title": "No se pueden incluir citas en menciones privadas",
|
||||
"visibility_modal.header": "Visibilidad e interacciones",
|
||||
"visibility_modal.helper.direct_quoting": "Las menciones privadas publicadas en Mastodon no pueden ser citadas por otros usuarios.",
|
||||
"visibility_modal.helper.privacy_editing": "La visibilidad no se puede cambiar después de que se haya hecho una publicación.",
|
||||
|
||||
@@ -64,10 +64,10 @@
|
||||
"account.media": "Meedia",
|
||||
"account.mention": "Maini @{name}",
|
||||
"account.moved_to": "{name} on teada andnud, et ta uus konto on nüüd:",
|
||||
"account.mute": "Vaigista @{name}",
|
||||
"account.mute_notifications_short": "Vaigista teavitused",
|
||||
"account.mute_short": "Vaigista",
|
||||
"account.muted": "Vaigistatud",
|
||||
"account.mute": "Summuta @{name}",
|
||||
"account.mute_notifications_short": "Summuta teavitused",
|
||||
"account.mute_short": "Summuta",
|
||||
"account.muted": "Summutatud",
|
||||
"account.muting": "Summutatud konto",
|
||||
"account.mutual": "Te jälgite teineteist",
|
||||
"account.no_bio": "Kirjeldust pole lisatud.",
|
||||
@@ -87,9 +87,9 @@
|
||||
"account.unblock_short": "Eemalda blokeering",
|
||||
"account.unendorse": "Ära kuva profiilil",
|
||||
"account.unfollow": "Jälgid",
|
||||
"account.unmute": "Ära vaigista @{name}",
|
||||
"account.unmute_notifications_short": "Tühista teadete vaigistamine",
|
||||
"account.unmute_short": "Lõpeta vaigistamine",
|
||||
"account.unmute": "Lõpeta {name} kasutaja summutamine",
|
||||
"account.unmute_notifications_short": "Lõpeta teavituste summutamine",
|
||||
"account.unmute_short": "Lõpeta summutamine",
|
||||
"account_note.placeholder": "Klõpsa märke lisamiseks",
|
||||
"admin.dashboard.daily_retention": "Kasutajate päevane allesjäämine peale registreerumist",
|
||||
"admin.dashboard.monthly_retention": "Kasutajate kuine allesjäämine peale registreerumist",
|
||||
@@ -173,11 +173,13 @@
|
||||
"column.edit_list": "Muuda loendit",
|
||||
"column.favourites": "Lemmikud",
|
||||
"column.firehose": "Postitused reaalajas",
|
||||
"column.firehose_local": "Selle serveri sisuvoog reaalajas",
|
||||
"column.firehose_singular": "Postitused reaalajas",
|
||||
"column.follow_requests": "Jälgimistaotlused",
|
||||
"column.home": "Kodu",
|
||||
"column.list_members": "Halda loendi liikmeid",
|
||||
"column.lists": "Loetelud",
|
||||
"column.mutes": "Vaigistatud kasutajad",
|
||||
"column.mutes": "Summutatud kasutajad",
|
||||
"column.notifications": "Teated",
|
||||
"column.pins": "Kinnitatud postitused",
|
||||
"column.public": "Föderatiivne ajajoon",
|
||||
@@ -192,6 +194,7 @@
|
||||
"community.column_settings.local_only": "Ainult kohalik",
|
||||
"community.column_settings.media_only": "Ainult meedia",
|
||||
"community.column_settings.remote_only": "Ainult kaug",
|
||||
"compose.error.blank_post": "Postitus ei saa jääda tühjaks.",
|
||||
"compose.language.change": "Muuda keelt",
|
||||
"compose.language.search": "Otsi keeli...",
|
||||
"compose.published.body": "Postitus tehtud.",
|
||||
@@ -243,7 +246,12 @@
|
||||
"confirmations.missing_alt_text.message": "Sinu postituses on ilma alt-tekstita meediat. Kirjelduse lisamine aitab su sisu muuta ligipääsetavaks rohkematele inimestele.",
|
||||
"confirmations.missing_alt_text.secondary": "Postita siiski",
|
||||
"confirmations.missing_alt_text.title": "Lisada alt-tekst?",
|
||||
"confirmations.mute.confirm": "Vaigista",
|
||||
"confirmations.mute.confirm": "Summuta",
|
||||
"confirmations.private_quote_notify.cancel": "Tagasi muutmise juurde",
|
||||
"confirmations.private_quote_notify.confirm": "Avalda postitus",
|
||||
"confirmations.private_quote_notify.do_not_show_again": "Ära kuva enam seda sõnumit uuesti",
|
||||
"confirmations.private_quote_notify.message": "Nii see, keda sa tsiteerid, kui need, keda mainid, saavad asjakohase teavituse ja võivad vaadata sinu postitust ka siis, kui nad pole sinu jälgijad.",
|
||||
"confirmations.private_quote_notify.title": "Kas jagad jälgijate ja mainitud kasutajatega?",
|
||||
"confirmations.quiet_post_quote_info.dismiss": "Ära tuleta enam meelde",
|
||||
"confirmations.quiet_post_quote_info.got_it": "Sain aru",
|
||||
"confirmations.quiet_post_quote_info.message": "Vaikse, aga avaliku postituse tsiteerimisel sinu postitus on peidetud populaarsust koguvatel ajajoontel.",
|
||||
@@ -287,7 +295,7 @@
|
||||
"domain_block_modal.they_can_interact_with_old_posts": "Inimesed sellest serverist saavad suhestuda sinu vanade postitustega.",
|
||||
"domain_block_modal.they_cant_follow": "Sellest serverist ei saa keegi sind jälgida.",
|
||||
"domain_block_modal.they_wont_know": "Nad ei tea, et nad on blokeeritud.",
|
||||
"domain_block_modal.title": "Blokeerida domeen?",
|
||||
"domain_block_modal.title": "Kas blokeerid domeeni?",
|
||||
"domain_block_modal.you_will_lose_num_followers": "Sult kaob {followersCount, plural, one {{followersCountDisplay} jälgija} other {{followersCountDisplay} jälgijat}} ja {followingCount, plural, one {{followingCountDisplay} inimene} other {{followingCountDisplay} inimest}}, keda sa ise jälgid.",
|
||||
"domain_block_modal.you_will_lose_relationships": "Sa kaotad kõik oma jälgijad ja inimesed, kes sind jälgivad sellest serverist.",
|
||||
"domain_block_modal.you_wont_see_posts": "Sa ei näe selle serveri kasutajate postitusi ega teavitusi.",
|
||||
@@ -343,7 +351,7 @@
|
||||
"empty_column.hashtag": "Selle sildi all ei ole ühtegi postitust.",
|
||||
"empty_column.home": "Su koduajajoon on tühi. Jälgi rohkemaid inimesi, et seda täita {suggestions}",
|
||||
"empty_column.list": "Siin loetelus pole veel midagi. Kui loetelu liikmed teevad uusi postitusi, näed neid siin.",
|
||||
"empty_column.mutes": "Sa pole veel ühtegi kasutajat vaigistanud.",
|
||||
"empty_column.mutes": "Sa pole veel ühtegi kasutajat summutanud.",
|
||||
"empty_column.notification_requests": "Kõik tühi! Siin pole mitte midagi. Kui saad uusi teavitusi, ilmuvad need siin vastavalt sinu seadistustele.",
|
||||
"empty_column.notifications": "Ei ole veel teateid. Kui keegi suhtleb sinuga, näed seda siin.",
|
||||
"empty_column.public": "Siin pole midagi! Kirjuta midagi avalikku või jälgi ise kasutajaid täitmaks seda ruumi",
|
||||
@@ -431,7 +439,7 @@
|
||||
"hashtag.counter_by_uses_today": "{count, plural, one {{counter} postitust} other {{counter} postitust}} täna",
|
||||
"hashtag.feature": "Tõsta profiilis esile",
|
||||
"hashtag.follow": "Jälgi silti",
|
||||
"hashtag.mute": "Vaigista @#{hashtag}",
|
||||
"hashtag.mute": "Summuta teemaviide @#{hashtag}",
|
||||
"hashtag.unfeature": "Ära tõsta profiilis esile",
|
||||
"hashtag.unfollow": "Lõpeta sildi jälgimine",
|
||||
"hashtags.and_other": "…ja {count, plural, one {}other {# veel}}",
|
||||
@@ -491,7 +499,7 @@
|
||||
"keyboard_shortcuts.load_more": "Fookus „Laadi veel“ nupule",
|
||||
"keyboard_shortcuts.local": "Ava kohalik ajajoon",
|
||||
"keyboard_shortcuts.mention": "Maini autorit",
|
||||
"keyboard_shortcuts.muted": "Ava vaigistatud kasutajate loetelu",
|
||||
"keyboard_shortcuts.muted": "Ava summutatud kasutajate loetelu",
|
||||
"keyboard_shortcuts.my_profile": "Ava oma profiil",
|
||||
"keyboard_shortcuts.notifications": "Ava teadete veerg",
|
||||
"keyboard_shortcuts.open_media": "Ava meedia",
|
||||
@@ -552,11 +560,11 @@
|
||||
"moved_to_account_banner.text": "Kontot {disabledAccount} ei ole praegu võimalik kasutada, sest kolisid kontole {movedToAccount}.",
|
||||
"mute_modal.hide_from_notifications": "Peida teavituste hulgast",
|
||||
"mute_modal.hide_options": "Peida valikud",
|
||||
"mute_modal.indefinite": "Kuni eemaldan neilt vaigistuse",
|
||||
"mute_modal.indefinite": "Kuni eemaldan neilt summutamise",
|
||||
"mute_modal.show_options": "Kuva valikud",
|
||||
"mute_modal.they_can_mention_and_follow": "Ta saab sind mainida ja sind jälgida, kuid sa ei näe teda.",
|
||||
"mute_modal.they_wont_know": "Ta ei tea, et ta on vaigistatud.",
|
||||
"mute_modal.title": "Vaigistada kasutaja?",
|
||||
"mute_modal.they_wont_know": "Ta ei tea, et ta on summutatud.",
|
||||
"mute_modal.title": "Kas summutad kasutaja?",
|
||||
"mute_modal.you_wont_see_mentions": "Sa ei näe postitusi, mis teda mainivad.",
|
||||
"mute_modal.you_wont_see_posts": "Ta näeb jätkuvalt sinu postitusi, kuid sa ei näe tema omi.",
|
||||
"navigation_bar.about": "Teave",
|
||||
@@ -569,7 +577,7 @@
|
||||
"navigation_bar.direct": "Privaatsed mainimised",
|
||||
"navigation_bar.domain_blocks": "Peidetud domeenid",
|
||||
"navigation_bar.favourites": "Lemmikud",
|
||||
"navigation_bar.filters": "Vaigistatud sõnad",
|
||||
"navigation_bar.filters": "Summutatud sõnad",
|
||||
"navigation_bar.follow_requests": "Jälgimistaotlused",
|
||||
"navigation_bar.followed_tags": "Jälgitavad märksõnad",
|
||||
"navigation_bar.follows_and_followers": "Jälgitavad ja jälgijad",
|
||||
@@ -580,7 +588,7 @@
|
||||
"navigation_bar.logout": "Logi välja",
|
||||
"navigation_bar.moderation": "Modereerimine",
|
||||
"navigation_bar.more": "Lisavalikud",
|
||||
"navigation_bar.mutes": "Vaigistatud kasutajad",
|
||||
"navigation_bar.mutes": "Summutatud kasutajad",
|
||||
"navigation_bar.opened_in_classic_interface": "Postitused, kontod ja teised spetsiaalsed lehed avatakse vaikimisi klassikalises veebiliideses.",
|
||||
"navigation_bar.preferences": "Eelistused",
|
||||
"navigation_bar.privacy_and_reach": "Privaatsus ja ulatus",
|
||||
@@ -756,6 +764,7 @@
|
||||
"privacy_policy.title": "Isikuandmete kaitse",
|
||||
"quote_error.edit": "Postituse muutmisel ei saa tsitaati lisada.",
|
||||
"quote_error.poll": "Tsiteerimine pole küsitlustes lubatud.",
|
||||
"quote_error.private_mentions": "Tsiteerimine pole otsemainimiste puhul lubatud.",
|
||||
"quote_error.quote": "Korraga on lubatud vaid üks tsitaat.",
|
||||
"quote_error.unauthorized": "Sul pole õigust seda postitust tsiteerida.",
|
||||
"quote_error.upload": "Tsiteerimine pole manuste puhul lubatud.",
|
||||
@@ -794,8 +803,8 @@
|
||||
"report.comment.title": "Kas arvad, et on veel midagi, mida me peaks teadma?",
|
||||
"report.forward": "Edasta ka {target} domeeni",
|
||||
"report.forward_hint": "See kasutaja on teisest serverist. Kas saadan anonümiseeritud koopia sellest teatest sinna ka?",
|
||||
"report.mute": "Vaigista",
|
||||
"report.mute_explanation": "Sa ei näe tema postitusi. Ta võib ikka sind jälgida ja su postitusi näha. Ta ei saa teada, et ta on vaigistatud.",
|
||||
"report.mute": "Summuta",
|
||||
"report.mute_explanation": "Sa ei näe tema postitusi. Ta võib ikka sind jälgida ja su postitusi näha. Ta ei saa teada, et ta on summutatud.",
|
||||
"report.next": "Järgmine",
|
||||
"report.placeholder": "Lisaks kommentaarid",
|
||||
"report.reasons.dislike": "Mulle ei meeldi see",
|
||||
@@ -903,15 +912,18 @@
|
||||
"status.media_hidden": "Meedia peidetud",
|
||||
"status.mention": "Maini @{name}'i",
|
||||
"status.more": "Veel",
|
||||
"status.mute": "Vaigista @{name}",
|
||||
"status.mute_conversation": "Vaigista vestlus",
|
||||
"status.mute": "Summuta @{name}",
|
||||
"status.mute_conversation": "Summuta vestlus",
|
||||
"status.open": "Laienda postitus",
|
||||
"status.pin": "Kinnita profiilile",
|
||||
"status.quote": "Tsiteeri",
|
||||
"status.quote.cancel": "Katkesta tsiteerimine",
|
||||
"status.quote_error.blocked_account_hint.title": "Kuna sa oled blokeerinud kasutaja @{name}, siis see postitus on peidetud.",
|
||||
"status.quote_error.blocked_domain_hint.title": "Kuna sa oled blokeerinud domeeni @{domain}, siis see postitus on peidetud.",
|
||||
"status.quote_error.filtered": "Peidetud mõne kasutatud filtri tõttu",
|
||||
"status.quote_error.limited_account_hint.action": "Näita ikkagi",
|
||||
"status.quote_error.limited_account_hint.title": "See profiil on peidetud {domain} serveri moderaatorite poolt.",
|
||||
"status.quote_error.muted_account_hint.title": "Kuna sa oled summutanud kasutaja @{name}, siis see postitus on peidetud.",
|
||||
"status.quote_error.not_available": "Postitus pole saadaval",
|
||||
"status.quote_error.pending_approval": "Postitus on ootel",
|
||||
"status.quote_error.pending_approval_popout.body": "Mastodonis saad sa kontrollida seda, kes võib sind tsiteerida. See postitus on seni ootel, kuni pole algse autori kinnitust tsiteerimisele.",
|
||||
@@ -953,7 +965,7 @@
|
||||
"status.translate": "Tõlgi",
|
||||
"status.translated_from_with": "Tõlgitud {lang} keelest kasutades teenust {provider}",
|
||||
"status.uncached_media_warning": "Eelvaade pole saadaval",
|
||||
"status.unmute_conversation": "Ära vaigista vestlust",
|
||||
"status.unmute_conversation": "Lõpeta vestluse summutamine",
|
||||
"status.unpin": "Eemalda profiilile kinnitus",
|
||||
"subscribed_languages.lead": "Pärast muudatust näed koduvaates ja loetelude ajajoontel postitusi valitud keeltes. Ära vali midagi, kui tahad näha postitusi kõikides keeltes.",
|
||||
"subscribed_languages.save": "Salvesta muudatused",
|
||||
@@ -997,15 +1009,17 @@
|
||||
"video.expand": "Suurenda video",
|
||||
"video.fullscreen": "Täisekraan",
|
||||
"video.hide": "Peida video",
|
||||
"video.mute": "Vaigista",
|
||||
"video.mute": "Summuta",
|
||||
"video.pause": "Paus",
|
||||
"video.play": "Mängi",
|
||||
"video.skip_backward": "Keri tagasi",
|
||||
"video.skip_forward": "Keri edasi",
|
||||
"video.unmute": "Lõpeta vaigistamine",
|
||||
"video.unmute": "Lõpeta summutamine",
|
||||
"video.volume_down": "Heli vaiksemaks",
|
||||
"video.volume_up": "Heli valjemaks",
|
||||
"visibility_modal.button_title": "Muuda nähtavust",
|
||||
"visibility_modal.direct_quote_warning.text": "Kui sa need seadistused salvestad, siis lõimitud tsitaat muutub lingiks.",
|
||||
"visibility_modal.direct_quote_warning.title": "Tsitaate ei saa privaatse mainimise puhul lõimida",
|
||||
"visibility_modal.header": "Nähtavus ja kasutus",
|
||||
"visibility_modal.helper.direct_quoting": "Ainult mainituile mõeldud Mastodoni postitusi ei saa teiste poolt tsiteerida.",
|
||||
"visibility_modal.helper.privacy_editing": "Nähtavust ei saa peale postituse avaldamist muuta.",
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
{
|
||||
"about.blocks": "کارسازهای نظارت شده",
|
||||
"about.contact": "تماس:",
|
||||
"about.default_locale": "پیشفرض",
|
||||
"about.default_locale": "پیشگزیده",
|
||||
"about.disclaimer": "ماستودون نرمافزار آزاد و نشان تجاری یک شرکت غیر انتفاعی با مسئولیت محدود آلمانی است.",
|
||||
"about.domain_blocks.no_reason_available": "دلیلی موجود نیست",
|
||||
"about.domain_blocks.preamble": "ماستودون عموماً میگذارد محتوا را از از هر کارساز دیگری در دنیای شبکههای اجتماعی غیرمتمرکز دیده و با آنان برهمکنش داشته باشید. اینها استثناهایی هستند که روی این کارساز خاص وضع شدهاند.",
|
||||
@@ -28,18 +28,24 @@
|
||||
"account.disable_notifications": "آگاه کردن من هنگام فرستههای @{name} را متوقّف کن",
|
||||
"account.domain_blocking": "دامنهٔ مسدود کرده",
|
||||
"account.edit_profile": "ویرایش نمایه",
|
||||
"account.edit_profile_short": "ویرایش",
|
||||
"account.enable_notifications": "هنگام فرستههای @{name} مرا آگاه کن",
|
||||
"account.endorse": "معرّفی در نمایه",
|
||||
"account.familiar_followers_many": "پیگرفته از سوی {name1}، {name2} و {othersCount, plural,one {یکی دیگر از پیگرفتههایتان} other {# نفر دیگر از پیگرفتههایتان}}",
|
||||
"account.familiar_followers_one": "پیگرفته از سوی {name1}",
|
||||
"account.familiar_followers_two": "پیگرفته از سوی {name1} و {name2}",
|
||||
"account.featured": " پیشنهادی",
|
||||
"account.featured": "پیشنهادی",
|
||||
"account.featured.accounts": "نمایهها",
|
||||
"account.featured.hashtags": "برچسبها",
|
||||
"account.featured_tags.last_status_at": "آخرین فرسته در {date}",
|
||||
"account.featured_tags.last_status_never": "بدون فرسته",
|
||||
"account.follow": "پیگرفتن",
|
||||
"account.follow_back": "پیگیری متقابل",
|
||||
"account.follow_back_short": "پیگیری متقابل",
|
||||
"account.follow_request": "درخواست پیگیری",
|
||||
"account.follow_request_cancel": "لغو درخواست",
|
||||
"account.follow_request_cancel_short": "لغو",
|
||||
"account.follow_request_short": "درخواست",
|
||||
"account.followers": "پیگیرندگان",
|
||||
"account.followers.empty": "هنوز کسی پیگیر این کاربر نیست.",
|
||||
"account.followers_counter": "{count, plural, one {{counter} پیگیرنده} other {{counter} پیگیرنده}}",
|
||||
@@ -167,6 +173,8 @@
|
||||
"column.edit_list": "ویرایش سیاهه",
|
||||
"column.favourites": "برگزیدهها",
|
||||
"column.firehose": "خوراکهای زنده",
|
||||
"column.firehose_local": "خوراک زندهٔ این کارساز",
|
||||
"column.firehose_singular": "خوراک زنده",
|
||||
"column.follow_requests": "درخواستهای پیگیری",
|
||||
"column.home": "خانه",
|
||||
"column.list_members": "مدیریت اعضای سیاهه",
|
||||
@@ -186,6 +194,7 @@
|
||||
"community.column_settings.local_only": "فقط محلی",
|
||||
"community.column_settings.media_only": "فقط رسانه",
|
||||
"community.column_settings.remote_only": "تنها دوردست",
|
||||
"compose.error.blank_post": "فرسته نمیتواند خالی باشد",
|
||||
"compose.language.change": "تغییر زبان",
|
||||
"compose.language.search": "جستوجوی زبانها...",
|
||||
"compose.published.body": "فرسته منتشر شد.",
|
||||
@@ -238,6 +247,10 @@
|
||||
"confirmations.missing_alt_text.secondary": "به هر حال پست کن",
|
||||
"confirmations.missing_alt_text.title": "متن جایگزین اضافه شود؟",
|
||||
"confirmations.mute.confirm": "خموش",
|
||||
"confirmations.quiet_post_quote_info.dismiss": "دیگر یادآوری نشود",
|
||||
"confirmations.quiet_post_quote_info.got_it": "گرفتم",
|
||||
"confirmations.quiet_post_quote_info.message": "هنگام نقل کردن فرستهٔ عمومی ساکت، فرستهتان از خطهای زمانی داغ پنهان خواهد بود.",
|
||||
"confirmations.quiet_post_quote_info.title": "نقل کردن فرستههای عمومی ساکت",
|
||||
"confirmations.redraft.confirm": "حذف و بازنویسی",
|
||||
"confirmations.redraft.message": "مطمئنید که میخواهید این فرسته را حذف کنید و از نو بنویسید؟ با این کار تقویتها و پسندهایش از دست رفته و پاسخها به آن بیمرجع میشود.",
|
||||
"confirmations.redraft.title": "حذف و پیشنویسی دوبارهٔ فرسته؟",
|
||||
@@ -247,7 +260,12 @@
|
||||
"confirmations.revoke_quote.confirm": "حذف فرسته",
|
||||
"confirmations.revoke_quote.message": "این اقدام قابل بازگشت نیست.",
|
||||
"confirmations.revoke_quote.title": "آیا فرسته را حذف کنم؟",
|
||||
"confirmations.unblock.confirm": "رفع انسداد",
|
||||
"confirmations.unblock.title": "رفع انسداد {name}؟",
|
||||
"confirmations.unfollow.confirm": "پینگرفتن",
|
||||
"confirmations.unfollow.title": "ناپیگیری {name}؟",
|
||||
"confirmations.withdraw_request.confirm": "انصراف از درخواست",
|
||||
"confirmations.withdraw_request.title": "انصراف از درخواست پیگیری {name}؟",
|
||||
"content_warning.hide": "نهفتن فرسته",
|
||||
"content_warning.show": "در هر صورت نشان داده شود",
|
||||
"content_warning.show_more": "نمایش بیشتر",
|
||||
@@ -318,6 +336,7 @@
|
||||
"empty_column.bookmarked_statuses": "هنوز هیچ فرستهٔ نشانهگذاری شدهای ندارید. هنگامی که فرستهای را نشانهگذاری کنید، اینجا نشان داده خواهد شد.",
|
||||
"empty_column.community": "خط زمانی محلی خالیست. چیزی نوشته تا چرخش بچرخد!",
|
||||
"empty_column.direct": "هنوز هیچ اشاره خصوصیای ندارید. هنگامی که چنین پیامی بگیرید یا بفرستید اینجا نشان داده خواهد شد.",
|
||||
"empty_column.disabled_feed": "این خوراک به دست مدیران کارسازتان از کار انداخته شده.",
|
||||
"empty_column.domain_blocks": "هنوز هیچ دامنهای مسدود نشده است.",
|
||||
"empty_column.explore_statuses": "الآن چیزی پرطرفدار نیست. بعداً دوباره بررسی کنید!",
|
||||
"empty_column.favourited_statuses": "شما هنوز هیچ فرستهای را نپسندیدهاید. هنگامی که فرستهای را بپسندید، اینجا نشان داده خواهد شد.",
|
||||
@@ -446,10 +465,12 @@
|
||||
"ignore_notifications_modal.private_mentions_title": "چشمپوشی از نامبریهای خصوصی ناخواسته؟",
|
||||
"info_button.label": "راهنما",
|
||||
"info_button.what_is_alt_text": "<h1>متن جایگزین چیست؟</h1> <p>متن جایگزین توضیحات تصویری را برای افراد دارای اختلالات بینایی، اتصالات با پهنای باند کم یا کسانی که به دنبال زمینه اضافی هستند ارائه می دهد.</p> <p>با نوشتن متن جایگزین واضح، مختصر و عینی می توانید دسترسی و درک را برای همه بهبود بخشید.</p> <ul> <li>عناصر مهم را ضبط کنید</li> <li>متن را در تصاویر خلاصه کنید</li> <li>از ساختار جمله منظم استفاده کنید</li> <li>از اطلاعات اضافی خودداری کنید</li> <li>روی روندها و یافته های کلیدی در تصاویر پیچیده (مانند نمودارها یا نقشه ها) تمرکز کنید.</li> </ul>",
|
||||
"interaction_modal.action": "برای تعامل با فرستهٔ {name} باید به حسابتان روی هر کارساز ماستودونی که استفاده میکنید وارد شوید.",
|
||||
"interaction_modal.go": "برو",
|
||||
"interaction_modal.no_account_yet": "هنوز حساب کاربری ندارید؟",
|
||||
"interaction_modal.on_another_server": "روی کارسازی دیگر",
|
||||
"interaction_modal.on_this_server": "روی این کارساز",
|
||||
"interaction_modal.title": "ورود برای ادامه",
|
||||
"interaction_modal.username_prompt": "به عنوان مثال {example}",
|
||||
"intervals.full.days": "{number, plural, one {# روز} other {# روز}}",
|
||||
"intervals.full.hours": "{number, plural, one {# ساعت} other {# ساعت}}",
|
||||
@@ -470,6 +491,7 @@
|
||||
"keyboard_shortcuts.home": "گشودن خط زمانی خانگی",
|
||||
"keyboard_shortcuts.hotkey": "میانبر",
|
||||
"keyboard_shortcuts.legend": "نمایش این نشانه",
|
||||
"keyboard_shortcuts.load_more": "تمرکز روی دکمهٔ «بار کردن بیشتر»",
|
||||
"keyboard_shortcuts.local": "گشودن خط زمانی محلی",
|
||||
"keyboard_shortcuts.mention": "اشاره به نویسنده",
|
||||
"keyboard_shortcuts.muted": "گشودن فهرست کاربران خموش",
|
||||
@@ -478,6 +500,7 @@
|
||||
"keyboard_shortcuts.open_media": "گشودن رسانه",
|
||||
"keyboard_shortcuts.pinned": "گشودن سیاههٔ فرستههای سنجاق شده",
|
||||
"keyboard_shortcuts.profile": "گشودن نمایهٔ نویسنده",
|
||||
"keyboard_shortcuts.quote": "نقل فرسته",
|
||||
"keyboard_shortcuts.reply": "پاسخ به فرسته",
|
||||
"keyboard_shortcuts.requests": "گشودن سیاههٔ درخواستهای پیگیری",
|
||||
"keyboard_shortcuts.search": "تمرکز روی نوار جستوجو",
|
||||
@@ -606,6 +629,7 @@
|
||||
"notification.moderation_warning.action_suspend": "حسابتان معلّق شده.",
|
||||
"notification.own_poll": "نظرسنجیتان پایان یافت",
|
||||
"notification.poll": "نظرسنجیای که در آن رأی دادید به پایان رسید",
|
||||
"notification.quoted_update": "{name} فرستهای که نقل کردید را ویراست",
|
||||
"notification.reblog": "{name} فرستهتان را تقویت کرد",
|
||||
"notification.reblog.name_and_others_with_link": "{name} و <a>{count, plural, one {# نفر دیگر} other {# نفر دیگر}}</a> فرستهتان را تقویت کردند",
|
||||
"notification.relationships_severance_event": "قطع ارتباط با {name}",
|
||||
@@ -621,7 +645,7 @@
|
||||
"notification_requests.confirm_accept_multiple.message": "در حال پذیرش {count, plural,one {یک}other {#}} درخواست آگاهی هستید. مطمئنید که میخواهید ادامه دهید؟",
|
||||
"notification_requests.confirm_accept_multiple.title": "پذیرش درخواستهای آگاهی؟",
|
||||
"notification_requests.confirm_dismiss_multiple.button": "رد {count, plural,one {درخواست} other {درخواستها}}",
|
||||
"notification_requests.confirm_dismiss_multiple.message": "شما در شرف رد کردن {count, plural, one {یک درخواست آگاهی} other {درخواست آگاهی}} هستید. دیگر نمی توانید به راحتی به {count, plural, one {آن} other {آنها}} دسترسی پیدا کنید. آیا مطمئن هستید که می خواهید ادامه دهید؟",
|
||||
"notification_requests.confirm_dismiss_multiple.message": "دارید {count, plural, one {یک درخواست آگاهی} other {# درخواست آگاهی}} را رد میکنید که دیگر نمی توانید به راحتی به {count, plural, one {آن} other {آنها}} دسترسی پیدا کنید. مطمئنید که میخواهید ادامه دهید؟",
|
||||
"notification_requests.confirm_dismiss_multiple.title": "رد کردن درخواستهای آگاهی؟",
|
||||
"notification_requests.dismiss": "دورانداختن",
|
||||
"notification_requests.dismiss_multiple": "{count, plural, one {دورانداختن درخواست…} other {دورانداختن درخواستها…}}",
|
||||
@@ -725,10 +749,19 @@
|
||||
"privacy.private.short": "پیگیرندگان",
|
||||
"privacy.public.long": "هرکسی در و بیرون از ماستودون",
|
||||
"privacy.public.short": "عمومی",
|
||||
"privacy.quote.anyone": "{visibility}، هرکسی میتواند نقل کند",
|
||||
"privacy.quote.disabled": "{visibility}، نقلها از کار افتاده",
|
||||
"privacy.quote.limited": "{visibility}، نقلها محدود شده",
|
||||
"privacy.unlisted.additional": "درست مثل عمومی رفتار میکند؛ جز این که فرسته در برچسبها یا خوراکهای زنده، کشف یا جستوجوی ماستودون ظاهر نخواهد شد. حتا اگر کلیّت نمایهتان اجازه داده باشد.",
|
||||
"privacy.unlisted.long": "نهفته از نتیجههای جستوجوی ماستودون و خطهای زمانی داغ و عمومی",
|
||||
"privacy.unlisted.short": "عمومی ساکت",
|
||||
"privacy_policy.last_updated": "آخرین بهروز رسانی در {date}",
|
||||
"privacy_policy.title": "سیاست محرمانگی",
|
||||
"quote_error.edit": "هنگام ویراستن فرسته نمیتوان نقلی افزود.",
|
||||
"quote_error.poll": "نقل نظرسنجیها مجاز نیست.",
|
||||
"quote_error.quote": "در هر زمان تنها یک نقل مجاز است.",
|
||||
"quote_error.unauthorized": "مجاز به نقل این فرسته نیستید.",
|
||||
"quote_error.upload": "نقل پیوستهای رسانهای مجاز نیست.",
|
||||
"recommended": "پیشنهادشده",
|
||||
"refresh": "نوسازی",
|
||||
"regeneration_indicator.please_stand_by": "لطفا منتظر باشید.",
|
||||
@@ -744,6 +777,9 @@
|
||||
"relative_time.minutes": "{number} دقیقه",
|
||||
"relative_time.seconds": "{number} ثانیه",
|
||||
"relative_time.today": "امروز",
|
||||
"remove_quote_hint.button_label": "گرفتم",
|
||||
"remove_quote_hint.message": "میتوانید این کار را از {icon} فهرست گزینهها انجام دهید.",
|
||||
"remove_quote_hint.title": "میخواهید فرستهٔ نقل شدهتان را بردارید؟",
|
||||
"reply_indicator.attachments": "{count, plural, one {# پیوست} other {# پیوست}}",
|
||||
"reply_indicator.cancel": "لغو",
|
||||
"reply_indicator.poll": "نظرسنجی",
|
||||
@@ -835,13 +871,23 @@
|
||||
"status.admin_account": "گشودن واسط مدیریت برای @{name}",
|
||||
"status.admin_domain": "گشودن واسط مدیریت برای {domain}",
|
||||
"status.admin_status": "گشودن این فرسته در واسط مدیریت",
|
||||
"status.all_disabled": "تقویتها و نقلها از کار افتادهاند",
|
||||
"status.block": "انسداد @{name}",
|
||||
"status.bookmark": "نشانک",
|
||||
"status.cancel_reblog_private": "ناتقویت",
|
||||
"status.cannot_quote": "مجاز به نقل این فرسته نیستید",
|
||||
"status.cannot_reblog": "این فرسته قابل تقویت نیست",
|
||||
"status.contains_quote": "دارای نقل",
|
||||
"status.context.loading": "بار کردن پاسخهای بیشتر",
|
||||
"status.context.loading_error": "نتوانست پاسخهای بیشتری بار کند",
|
||||
"status.context.loading_success": "پاسخهای جدید بار شدند",
|
||||
"status.context.more_replies_found": "پاسخهای بیشتری پیدا شد",
|
||||
"status.context.retry": "تلاش دوباره",
|
||||
"status.context.show": "نمایش",
|
||||
"status.continued_thread": "رشتهٔ دنباله دار",
|
||||
"status.copy": "رونوشت از پیوند فرسته",
|
||||
"status.delete": "حذف",
|
||||
"status.delete.success": "فرسته حذف شد",
|
||||
"status.detailed_status": "نمایش کامل گفتگو",
|
||||
"status.direct": "اشارهٔ خصوصی به @{name}",
|
||||
"status.direct_indicator": "اشارهٔ خصوصی",
|
||||
@@ -866,24 +912,43 @@
|
||||
"status.pin": "سنجاق به نمایه",
|
||||
"status.quote": "نقلقول",
|
||||
"status.quote.cancel": "لغو نقل",
|
||||
"status.quote_error.blocked_account_hint.title": "این فرسته نهفته است چرا که @{name} را مسدود کردهاید.",
|
||||
"status.quote_error.blocked_domain_hint.title": "این فرسته نهفته است چرا که {domain} را مسدود کردهاید.",
|
||||
"status.quote_error.filtered": "نهفته بنا بر یکی از پالایههایتان",
|
||||
"status.quote_error.limited_account_hint.action": "نمایش به هر روی",
|
||||
"status.quote_error.limited_account_hint.title": "این حساب به دست ناظمهای {domain} پنهان شده.",
|
||||
"status.quote_error.muted_account_hint.title": "این فرسته نهفته است چرا که @{name} را خموش کردهاید.",
|
||||
"status.quote_error.not_available": "فرسته در دسترس نیست",
|
||||
"status.quote_error.pending_approval": "فرسته منتظر",
|
||||
"status.quote_error.pending_approval_popout.body": "روی ماستودون میتوان افراد مجاز به نقل را واپایید. این فرسته تا زمان گرفتن تأییده از نگارندهٔ اصلی معلّق است.",
|
||||
"status.quote_error.revoked": "فرسته به دست نگارنده برداشته شد",
|
||||
"status.quote_followers_only": "تنها پیگیران میتوانند این فرسته را نقل کنند",
|
||||
"status.quote_manual_review": "نگارنده به صورت دستی بررسی خواهد کرد",
|
||||
"status.quote_noun": "نقل",
|
||||
"status.quote_policy_change": "تغییر کسانی که میتوانند نقل کنند",
|
||||
"status.quote_post_author": "فرستهای از @{name} نقل شد",
|
||||
"status.quote_private": "فرستههای خصوصی نمیتوانند نقل شوند",
|
||||
"status.quotes": "{count, plural, one {نقل} other {نقل}}",
|
||||
"status.quotes.empty": "هنوز کسی این فرسته را نقل نکرده. وقتی کسی چنین کند اینجا نشان داده خواهد شد.",
|
||||
"status.quotes.local_other_disclaimer": "نقلهایی که به دست نگارنده رد شده باشند نشان داده نخواهند شد.",
|
||||
"status.quotes.remote_other_disclaimer": "تنها نقلها از {domain} تضمین نمایش در اینجا را دارند. نقلهای رد شده به دست نگاره نشان داده نخواهند شد.",
|
||||
"status.read_more": "بیشتر بخوانید",
|
||||
"status.reblog": "تقویت",
|
||||
"status.reblog_or_quote": "نقل یا تقویت",
|
||||
"status.reblog_private": "همرسانی دوباره با پیگیرانتان",
|
||||
"status.reblogged_by": "{name} تقویت کرد",
|
||||
"status.reblogs": "{count, plural, one {تقویت} other {تقویت}}",
|
||||
"status.reblogs.empty": "هنوز هیچ کسی این فرسته را تقویت نکرده است. وقتی کسی چنین کاری کند، اینجا نمایش داده خواهد شد.",
|
||||
"status.redraft": "حذف و بازنویسی",
|
||||
"status.remove_bookmark": "برداشتن نشانک",
|
||||
"status.remove_favourite": "حذف از موارد دلخواه",
|
||||
"status.remove_quote": "برداشتن",
|
||||
"status.replied_in_thread": "در رشته پاسخ داده",
|
||||
"status.replied_to": "به {name} پاسخ داد",
|
||||
"status.reply": "پاسخ",
|
||||
"status.replyAll": "پاسخ به رشته",
|
||||
"status.report": "گزارش @{name}",
|
||||
"status.request_quote": "درخواست نقل",
|
||||
"status.revoke_quote": "حذف فرستهام از فرسته @{name}",
|
||||
"status.sensitive_warning": "محتوای حساس",
|
||||
"status.share": "همرسانی",
|
||||
@@ -922,6 +987,7 @@
|
||||
"upload_button.label": "افزودن تصاویر، ویدیو یا یک پروندهٔ صوتی",
|
||||
"upload_error.limit": "از حد مجاز بارگذاری پرونده فراتر رفتید.",
|
||||
"upload_error.poll": "بارگذاری پرونده در نظرسنجیها مجاز نیست.",
|
||||
"upload_error.quote": "بارگذاری پرونده در نقلها محاز نیست.",
|
||||
"upload_form.drag_and_drop.instructions": "برای دریافت پیوست رسانه، space را فشار دهید یا وارد کنید. در حین کشیدن، از کلیدهای جهت دار برای حرکت دادن پیوست رسانه در هر جهت معین استفاده کنید. برای رها کردن ضمیمه رسانه در موقعیت جدید خود، مجدداً space یا enter را فشار دهید، یا برای لغو، escape را فشار دهید.",
|
||||
"upload_form.drag_and_drop.on_drag_cancel": "کشیدن لغو شد. پیوست رسانه {item} حذف شد.",
|
||||
"upload_form.drag_and_drop.on_drag_end": "پیوست رسانه {item} حذف شد.",
|
||||
@@ -947,8 +1013,16 @@
|
||||
"video.volume_up": "افزایش حجم صدا",
|
||||
"visibility_modal.button_title": "تنظیم نمایانی",
|
||||
"visibility_modal.header": "نمایانی و برهمکنش",
|
||||
"visibility_modal.helper.direct_quoting": "اشارههای خصوصی روی ماستودون نیمتوانند به دست دیگران نقل شوند.",
|
||||
"visibility_modal.helper.privacy_editing": "پس از انتشار فرسته نمیتوان نمایانی را تغییر داد.",
|
||||
"visibility_modal.helper.privacy_private_self_quote": "خودنقلی فرستههای خصوصی نمیتواند عمومی شود.",
|
||||
"visibility_modal.helper.private_quoting": "فرستهّای فقط پیگیران روی ماستودون نمیتوانند به دست دیگران نقل شوند.",
|
||||
"visibility_modal.helper.unlisted_quoting": "هنگامی که افراد نقلتان میکنند فرستهشان هم از خطزمانیهای داغ پنهان خواهد بود.",
|
||||
"visibility_modal.instructions": "واپایش کسانی که میتوانند با این فرسته تعامل داشته باشند. میتواند با رفتن به <link>ترجیحات > پیشگزیدهها فرستادن</link> تنظیمات را به همهٔ فرستههای آینده نیز اعمال کنید.",
|
||||
"visibility_modal.privacy_label": "نمایانی",
|
||||
"visibility_modal.quote_followers": "فقط پیگیرندگان",
|
||||
"visibility_modal.quote_label": "چهکسی میتواند نقل کند",
|
||||
"visibility_modal.quote_nobody": "فقط من",
|
||||
"visibility_modal.quote_public": "هرکسی",
|
||||
"visibility_modal.save": "ذخیره"
|
||||
}
|
||||
|
||||
@@ -247,6 +247,11 @@
|
||||
"confirmations.missing_alt_text.secondary": "Julkaise silti",
|
||||
"confirmations.missing_alt_text.title": "Lisätäänkö vaihtoehtoinen teksti?",
|
||||
"confirmations.mute.confirm": "Mykistä",
|
||||
"confirmations.private_quote_notify.cancel": "Takaisin muokkaukseen",
|
||||
"confirmations.private_quote_notify.confirm": "Julkaise",
|
||||
"confirmations.private_quote_notify.do_not_show_again": "Älä näytä tätä viestiä uudelleen",
|
||||
"confirmations.private_quote_notify.message": "Lainaamasi käyttäjä ja muut mainitut saavat ilmoituksen ja voivat tarkastella julkaisuasi, vaikka he eivät seuraisi sinua.",
|
||||
"confirmations.private_quote_notify.title": "Jaetaanko seuraajien ja mainittujen käyttäjien kanssa?",
|
||||
"confirmations.quiet_post_quote_info.dismiss": "Älä muistuta minua uudelleen",
|
||||
"confirmations.quiet_post_quote_info.got_it": "Selvä",
|
||||
"confirmations.quiet_post_quote_info.message": "Kun lainaat vaivihkaa julkisia julkaisuja, oma julkaisusi piilotetaan suosittujen julkaisujen aikajanoilta.",
|
||||
@@ -759,6 +764,7 @@
|
||||
"privacy_policy.title": "Tietosuojakäytäntö",
|
||||
"quote_error.edit": "Lainauksia ei voi lisätä julkaisua muokattaessa.",
|
||||
"quote_error.poll": "Äänestysten lainaaminen ei ole sallittua.",
|
||||
"quote_error.private_mentions": "Lainaaminen ei ole sallittua yksityismaininnoissa.",
|
||||
"quote_error.quote": "Vain yksi lainaus kerrallaan on sallittu.",
|
||||
"quote_error.unauthorized": "Sinulla ei ole valtuuksia lainata tätä julkaisua.",
|
||||
"quote_error.upload": "Medialiitteiden lainaaminen ei ole sallittua.",
|
||||
@@ -1012,6 +1018,8 @@
|
||||
"video.volume_down": "Vähennä äänenvoimakkuutta",
|
||||
"video.volume_up": "Lisää äänenvoimakkuutta",
|
||||
"visibility_modal.button_title": "Aseta näkyvyys",
|
||||
"visibility_modal.direct_quote_warning.text": "Jos tallennat nykyiset asetukset, upotettu lainaus muunnetaan linkiksi.",
|
||||
"visibility_modal.direct_quote_warning.title": "Lainauksia ei voi upottaa yksityismainintoihin",
|
||||
"visibility_modal.header": "Näkyvyys ja vuorovaikutus",
|
||||
"visibility_modal.helper.direct_quoting": "Muut eivät voi lainata Mastodonissa kirjoitettuja yksityismainintoja.",
|
||||
"visibility_modal.helper.privacy_editing": "Näkyvyyttä ei voi muuttaa julkaisun jälkeen.",
|
||||
|
||||
@@ -194,6 +194,7 @@
|
||||
"community.column_settings.local_only": "Einans lokalt",
|
||||
"community.column_settings.media_only": "Einans miðlar",
|
||||
"community.column_settings.remote_only": "Einans útifrá",
|
||||
"compose.error.blank_post": "Postar kunnu ikki vera blankir.",
|
||||
"compose.language.change": "Skift mál",
|
||||
"compose.language.search": "Leita eftir málum...",
|
||||
"compose.published.body": "Postur útgivin.",
|
||||
@@ -246,6 +247,11 @@
|
||||
"confirmations.missing_alt_text.secondary": "Posta allíkavæl",
|
||||
"confirmations.missing_alt_text.title": "Legg alternativan tekst afturat?",
|
||||
"confirmations.mute.confirm": "Doyv",
|
||||
"confirmations.private_quote_notify.cancel": "Aftur til rættingar",
|
||||
"confirmations.private_quote_notify.confirm": "Útgev post",
|
||||
"confirmations.private_quote_notify.do_not_show_again": "Ikki vísa hesi boðini aftur",
|
||||
"confirmations.private_quote_notify.message": "Persónurin, sum tú siterar, og onnur, sum eru nevnd, verða kunnaði og kunnu síggja postin hjá tær, sjálvt um tey ikki fylgja tær.",
|
||||
"confirmations.private_quote_notify.title": "Deil við fylgjarum og nevndum brúkarum?",
|
||||
"confirmations.quiet_post_quote_info.dismiss": "Ikki minna meg á tað aftur",
|
||||
"confirmations.quiet_post_quote_info.got_it": "Eg skilji",
|
||||
"confirmations.quiet_post_quote_info.message": "Tá tú siterar ein stillan almennan post, verður posturin hjá tær fjaldur frá tíðarlinjum, ið vísa vælumtóktar postar.",
|
||||
@@ -758,6 +764,7 @@
|
||||
"privacy_policy.title": "Privatlívspolitikkur",
|
||||
"quote_error.edit": "Sitatir kunnu ikki leggjast afturat tá tú rættar ein post.",
|
||||
"quote_error.poll": "Tað er ikki loyvt at sitera spurnarkanningar.",
|
||||
"quote_error.private_mentions": "Sitering er ikki loyvd við beinleiðis umrøðum.",
|
||||
"quote_error.quote": "Bara ein sitering er loyvd í senn.",
|
||||
"quote_error.unauthorized": "Tú hevur ikki rættindi at sitera hendan postin.",
|
||||
"quote_error.upload": "Sitering er ikki loyvd um miðlar eru viðheftir.",
|
||||
@@ -1011,6 +1018,8 @@
|
||||
"video.volume_down": "Minka ljóðstyrki",
|
||||
"video.volume_up": "Øk um ljóðstyrki",
|
||||
"visibility_modal.button_title": "Set sýni",
|
||||
"visibility_modal.direct_quote_warning.text": "Um tú goymir verandi stillingar, verður innskotna sitatið umskapað til eitt leinki.",
|
||||
"visibility_modal.direct_quote_warning.title": "Sitatir kunnu ikki innskjótast í privatar umrøður",
|
||||
"visibility_modal.header": "Sýni og samvirkni",
|
||||
"visibility_modal.helper.direct_quoting": "Privatar umrøður, sum eru skrivaðar á Mastodon, kunnu ikki siterast av øðrum.",
|
||||
"visibility_modal.helper.privacy_editing": "Sýni kann ikki broytast eftir, at ein postur er útgivin.",
|
||||
|
||||
@@ -28,6 +28,7 @@
|
||||
"account.disable_notifications": "Ne plus me notifier quand @{name} publie",
|
||||
"account.domain_blocking": "Bloquer domaine",
|
||||
"account.edit_profile": "Modifier le profil",
|
||||
"account.edit_profile_short": "Modifier",
|
||||
"account.enable_notifications": "Me notifier quand @{name} publie",
|
||||
"account.endorse": "Inclure sur profil",
|
||||
"account.familiar_followers_many": "Suivi par {name1},{name2}, et {othersCount, plural,one {une personne connue} other {# autres personnel connues}}",
|
||||
@@ -40,6 +41,11 @@
|
||||
"account.featured_tags.last_status_never": "Aucune publication",
|
||||
"account.follow": "Suivre",
|
||||
"account.follow_back": "Suivre en retour",
|
||||
"account.follow_back_short": "Suivre en retour",
|
||||
"account.follow_request": "Demande d’abonnement",
|
||||
"account.follow_request_cancel": "Annuler la demande",
|
||||
"account.follow_request_cancel_short": "Annuler",
|
||||
"account.follow_request_short": "Requête",
|
||||
"account.followers": "abonné·e·s",
|
||||
"account.followers.empty": "Personne ne suit ce compte pour l'instant.",
|
||||
"account.followers_counter": "{count, plural, one {{counter} abonné·e} other {{counter} abonné·e·s}}",
|
||||
@@ -167,6 +173,8 @@
|
||||
"column.edit_list": "Modifier la liste",
|
||||
"column.favourites": "Favoris",
|
||||
"column.firehose": "Flux en direct",
|
||||
"column.firehose_local": "Flux en direct pour ce serveur",
|
||||
"column.firehose_singular": "Flux en direct",
|
||||
"column.follow_requests": "Demande d'abonnement",
|
||||
"column.home": "Accueil",
|
||||
"column.list_members": "Gérer les membres de la liste",
|
||||
@@ -186,6 +194,7 @@
|
||||
"community.column_settings.local_only": "Local seulement",
|
||||
"community.column_settings.media_only": "Média seulement",
|
||||
"community.column_settings.remote_only": "À distance seulement",
|
||||
"compose.error.blank_post": "Le message ne peut être laissé vide.",
|
||||
"compose.language.change": "Changer de langue",
|
||||
"compose.language.search": "Rechercher des langues…",
|
||||
"compose.published.body": "Publiée.",
|
||||
@@ -327,6 +336,7 @@
|
||||
"empty_column.bookmarked_statuses": "Vous n'avez pas de publications parmi vos signets. Lorsque vous en ajouterez une, elle apparaîtra ici.",
|
||||
"empty_column.community": "Le fil local est vide. Écrivez donc quelque chose pour le remplir!",
|
||||
"empty_column.direct": "Vous n'avez pas encore de mentions privées. Quand vous en envoyez ou en recevez, elles apparaîtront ici.",
|
||||
"empty_column.disabled_feed": "Ce flux a été désactivé par les administrateur·rice·s de votre serveur.",
|
||||
"empty_column.domain_blocks": "Il n’y a aucun domaine bloqué pour le moment.",
|
||||
"empty_column.explore_statuses": "Rien n'est en tendance présentement. Revenez plus tard!",
|
||||
"empty_column.favourited_statuses": "Vous n’avez pas encore de publications favorites. Lorsque vous en ajouterez une, elle apparaîtra ici.",
|
||||
@@ -747,6 +757,7 @@
|
||||
"privacy.unlisted.short": "Public discret",
|
||||
"privacy_policy.last_updated": "Dernière mise à jour {date}",
|
||||
"privacy_policy.title": "Politique de confidentialité",
|
||||
"quote_error.edit": "Les citations ne peuvent pas être ajoutés lors de l'édition d'un message.",
|
||||
"quote_error.poll": "Les citations ne sont pas autorisées avec les sondages.",
|
||||
"quote_error.quote": "Une seule citation à la fois est autorisée.",
|
||||
"quote_error.unauthorized": "Vous n'êtes pas autorisé⋅e à citer cette publication.",
|
||||
@@ -869,6 +880,7 @@
|
||||
"status.contains_quote": "Contient la citation",
|
||||
"status.context.loading": "Chargement de réponses supplémentaires",
|
||||
"status.context.loading_error": "Impossible de charger les nouvelles réponses",
|
||||
"status.context.loading_success": "Nouvelles réponses ont été chargées",
|
||||
"status.context.more_replies_found": "Plus de réponses trouvées",
|
||||
"status.context.retry": "Réessayer",
|
||||
"status.context.show": "Montrer",
|
||||
@@ -900,9 +912,12 @@
|
||||
"status.pin": "Épingler sur profil",
|
||||
"status.quote": "Citer",
|
||||
"status.quote.cancel": "Annuler la citation",
|
||||
"status.quote_error.blocked_account_hint.title": "Ce message est masqué car vous avez bloqué @{name}.",
|
||||
"status.quote_error.blocked_domain_hint.title": "Ce message est masqué car vous avez bloqué {domain}.",
|
||||
"status.quote_error.filtered": "Caché en raison de l'un de vos filtres",
|
||||
"status.quote_error.limited_account_hint.action": "Afficher quand même",
|
||||
"status.quote_error.limited_account_hint.title": "Ce profil a été masqué par la modération de {domain}.",
|
||||
"status.quote_error.muted_account_hint.title": "Ce message est masqué car vous avez Mis en sourdine @{name}.",
|
||||
"status.quote_error.not_available": "Publication non disponible",
|
||||
"status.quote_error.pending_approval": "Publication en attente",
|
||||
"status.quote_error.pending_approval_popout.body": "Sur Mastodon, vous pouvez contrôler si quelqu'un peut vous citer. Ce message est en attente pendant que nous recevons l'approbation de l'auteur original.",
|
||||
|
||||
@@ -28,6 +28,7 @@
|
||||
"account.disable_notifications": "Ne plus me notifier quand @{name} publie quelque chose",
|
||||
"account.domain_blocking": "Bloquer domaine",
|
||||
"account.edit_profile": "Modifier le profil",
|
||||
"account.edit_profile_short": "Modifier",
|
||||
"account.enable_notifications": "Me notifier quand @{name} publie quelque chose",
|
||||
"account.endorse": "Recommander sur votre profil",
|
||||
"account.familiar_followers_many": "Suivi par {name1},{name2}, et {othersCount, plural,one {une personne connue} other {# autres personnel connues}}",
|
||||
@@ -40,6 +41,11 @@
|
||||
"account.featured_tags.last_status_never": "Aucun message",
|
||||
"account.follow": "Suivre",
|
||||
"account.follow_back": "Suivre en retour",
|
||||
"account.follow_back_short": "Suivre en retour",
|
||||
"account.follow_request": "Demande d’abonnement",
|
||||
"account.follow_request_cancel": "Annuler la demande",
|
||||
"account.follow_request_cancel_short": "Annuler",
|
||||
"account.follow_request_short": "Requête",
|
||||
"account.followers": "Abonné·e·s",
|
||||
"account.followers.empty": "Personne ne suit cet·te utilisateur·rice pour l’instant.",
|
||||
"account.followers_counter": "{count, plural, one {{counter} abonné·e} other {{counter} abonné·e·s}}",
|
||||
@@ -167,6 +173,8 @@
|
||||
"column.edit_list": "Modifier la liste",
|
||||
"column.favourites": "Favoris",
|
||||
"column.firehose": "Flux en direct",
|
||||
"column.firehose_local": "Flux en direct pour ce serveur",
|
||||
"column.firehose_singular": "Flux en direct",
|
||||
"column.follow_requests": "Demandes d'abonnement",
|
||||
"column.home": "Accueil",
|
||||
"column.list_members": "Gérer les membres de la liste",
|
||||
@@ -186,6 +194,7 @@
|
||||
"community.column_settings.local_only": "Local seulement",
|
||||
"community.column_settings.media_only": "Média uniquement",
|
||||
"community.column_settings.remote_only": "Distant seulement",
|
||||
"compose.error.blank_post": "Le message ne peut être laissé vide.",
|
||||
"compose.language.change": "Changer de langue",
|
||||
"compose.language.search": "Rechercher des langues...",
|
||||
"compose.published.body": "Message Publié.",
|
||||
@@ -327,6 +336,7 @@
|
||||
"empty_column.bookmarked_statuses": "Vous n'avez pas de message en marque-page. Lorsque vous en ajouterez un, il apparaîtra ici.",
|
||||
"empty_column.community": "Le fil public local est vide. Écrivez donc quelque chose pour le remplir !",
|
||||
"empty_column.direct": "Vous n'avez pas encore de mentions privées. Quand vous en enverrez ou recevrez, elles apparaîtront ici.",
|
||||
"empty_column.disabled_feed": "Ce flux a été désactivé par les administrateur·rice·s de votre serveur.",
|
||||
"empty_column.domain_blocks": "Il n’y a aucun domaine bloqué pour le moment.",
|
||||
"empty_column.explore_statuses": "Rien n'est en tendance pour le moment. Revenez plus tard !",
|
||||
"empty_column.favourited_statuses": "Vous n’avez pas encore de message en favori. Lorsque vous en ajouterez un, il apparaîtra ici.",
|
||||
@@ -747,6 +757,7 @@
|
||||
"privacy.unlisted.short": "Public discret",
|
||||
"privacy_policy.last_updated": "Dernière mise à jour {date}",
|
||||
"privacy_policy.title": "Politique de confidentialité",
|
||||
"quote_error.edit": "Les citations ne peuvent pas être ajoutés lors de l'édition d'un message.",
|
||||
"quote_error.poll": "Les citations ne sont pas autorisées avec les sondages.",
|
||||
"quote_error.quote": "Une seule citation à la fois est autorisée.",
|
||||
"quote_error.unauthorized": "Vous n'êtes pas autorisé⋅e à citer cette publication.",
|
||||
@@ -869,6 +880,7 @@
|
||||
"status.contains_quote": "Contient la citation",
|
||||
"status.context.loading": "Chargement de réponses supplémentaires",
|
||||
"status.context.loading_error": "Impossible de charger les nouvelles réponses",
|
||||
"status.context.loading_success": "Nouvelles réponses ont été chargées",
|
||||
"status.context.more_replies_found": "Plus de réponses trouvées",
|
||||
"status.context.retry": "Réessayer",
|
||||
"status.context.show": "Montrer",
|
||||
@@ -900,9 +912,12 @@
|
||||
"status.pin": "Épingler sur le profil",
|
||||
"status.quote": "Citer",
|
||||
"status.quote.cancel": "Annuler la citation",
|
||||
"status.quote_error.blocked_account_hint.title": "Ce message est masqué car vous avez bloqué @{name}.",
|
||||
"status.quote_error.blocked_domain_hint.title": "Ce message est masqué car vous avez bloqué {domain}.",
|
||||
"status.quote_error.filtered": "Caché en raison de l'un de vos filtres",
|
||||
"status.quote_error.limited_account_hint.action": "Afficher quand même",
|
||||
"status.quote_error.limited_account_hint.title": "Ce profil a été masqué par la modération de {domain}.",
|
||||
"status.quote_error.muted_account_hint.title": "Ce message est masqué car vous avez Mis en sourdine @{name}.",
|
||||
"status.quote_error.not_available": "Publication non disponible",
|
||||
"status.quote_error.pending_approval": "Publication en attente",
|
||||
"status.quote_error.pending_approval_popout.body": "Sur Mastodon, vous pouvez contrôler si quelqu'un peut vous citer. Ce message est en attente pendant que nous recevons l'approbation de l'auteur original.",
|
||||
|
||||
@@ -194,6 +194,7 @@
|
||||
"community.column_settings.local_only": "Áitiúil amháin",
|
||||
"community.column_settings.media_only": "Meáin Amháin",
|
||||
"community.column_settings.remote_only": "Cian amháin",
|
||||
"compose.error.blank_post": "Ní féidir an post a fhágáil bán.",
|
||||
"compose.language.change": "Athraigh teanga",
|
||||
"compose.language.search": "Cuardaigh teangacha...",
|
||||
"compose.published.body": "Post foilsithe.",
|
||||
@@ -246,6 +247,11 @@
|
||||
"confirmations.missing_alt_text.secondary": "Post ar aon nós",
|
||||
"confirmations.missing_alt_text.title": "Cuir téacs alt leis?",
|
||||
"confirmations.mute.confirm": "Balbhaigh",
|
||||
"confirmations.private_quote_notify.cancel": "Ar ais chuig an eagarthóireacht",
|
||||
"confirmations.private_quote_notify.confirm": "Foilsigh an post",
|
||||
"confirmations.private_quote_notify.do_not_show_again": "Ná taispeáin an teachtaireacht seo dom arís",
|
||||
"confirmations.private_quote_notify.message": "Cuirfear an duine atá á lua agat agus luanna eile ar an eolas agus beidh siad in ann do phost a fheiceáil, fiú mura bhfuil siad ag leanúint thú.",
|
||||
"confirmations.private_quote_notify.title": "Roinn le leantóirí agus úsáideoirí a luadh?",
|
||||
"confirmations.quiet_post_quote_info.dismiss": "Ná cuir i gcuimhne dom arís",
|
||||
"confirmations.quiet_post_quote_info.got_it": "Tuigim é",
|
||||
"confirmations.quiet_post_quote_info.message": "Agus post poiblí ciúin á lua, beidh do phost i bhfolach ó amlínte treochta.",
|
||||
@@ -758,6 +764,7 @@
|
||||
"privacy_policy.title": "Polasaí príobháideachais",
|
||||
"quote_error.edit": "Ní féidir Sleachta a chur leis agus post á chur in eagar.",
|
||||
"quote_error.poll": "Ní cheadaítear lua le pobalbhreitheanna.",
|
||||
"quote_error.private_mentions": "Ní cheadaítear lua le tagairtí díreacha.",
|
||||
"quote_error.quote": "Ní cheadaítear ach luachan amháin ag an am.",
|
||||
"quote_error.unauthorized": "Níl údarás agat an post seo a lua.",
|
||||
"quote_error.upload": "Ní cheadaítear lua a dhéanamh le ceangaltáin sna meáin.",
|
||||
@@ -1011,6 +1018,8 @@
|
||||
"video.volume_down": "Toirt síos",
|
||||
"video.volume_up": "Toirt suas",
|
||||
"visibility_modal.button_title": "Socraigh infheictheacht",
|
||||
"visibility_modal.direct_quote_warning.text": "Má shábhálann tú na socruithe reatha, déanfar an luachan leabaithe a thiontú ina nasc.",
|
||||
"visibility_modal.direct_quote_warning.title": "Ní féidir luachana a leabú i luanna príobháideacha",
|
||||
"visibility_modal.header": "Infheictheacht agus idirghníomhaíocht",
|
||||
"visibility_modal.helper.direct_quoting": "Ní féidir le daoine eile tráchtanna príobháideacha a scríobhadh ar Mastodon a lua.",
|
||||
"visibility_modal.helper.privacy_editing": "Ní féidir infheictheacht a athrú tar éis post a fhoilsiú.",
|
||||
|
||||
@@ -194,6 +194,7 @@
|
||||
"community.column_settings.local_only": "Feadhainn ionadail a-mhàin",
|
||||
"community.column_settings.media_only": "Meadhanan a-mhàin",
|
||||
"community.column_settings.remote_only": "Feadhainn chèin a-mhàin",
|
||||
"compose.error.blank_post": "Chan urrrainn dho phost a bhith bàn.",
|
||||
"compose.language.change": "Atharraich an cànan",
|
||||
"compose.language.search": "Lorg cànan…",
|
||||
"compose.published.body": "Chaidh am post fhoillseachadh.",
|
||||
@@ -246,6 +247,11 @@
|
||||
"confirmations.missing_alt_text.secondary": "Postaich e co-dhiù",
|
||||
"confirmations.missing_alt_text.title": "A bheil thu airson roghainn teacsa a chur ris?",
|
||||
"confirmations.mute.confirm": "Mùch",
|
||||
"confirmations.private_quote_notify.cancel": "Till dhan deasachadh",
|
||||
"confirmations.private_quote_notify.confirm": "Foillsich am post",
|
||||
"confirmations.private_quote_notify.do_not_show_again": "Na seall an teachdaireachd seo a-rithist dhomh",
|
||||
"confirmations.private_quote_notify.message": "Cuiridh sinn brath dhan neach a tha thu a’ luaidh ’s do na daoine eile le iomradh orra agus chì iad am post agad fiù mur eil iad ’gad leantainn.",
|
||||
"confirmations.private_quote_notify.title": "A bheil thu airson a cho-roinneadh leis an luchd-leantainn ’s na cleachdaichean le iomradh orra?",
|
||||
"confirmations.quiet_post_quote_info.dismiss": "Na cuiribh seo ’nam chuimhne a-rithist",
|
||||
"confirmations.quiet_post_quote_info.got_it": "Tha mi agaibh",
|
||||
"confirmations.quiet_post_quote_info.message": "Nuair a luaidheas tu post a tha poblach ach sàmhach, thèid am post agad fhalach o loidhnichean-ama nan treandaichean.",
|
||||
@@ -748,7 +754,7 @@
|
||||
"privacy.private.short": "Luchd-leantainn",
|
||||
"privacy.public.long": "Duine sam bith taobh a-staigh no a-muigh Mhastodon",
|
||||
"privacy.public.short": "Poblach",
|
||||
"privacy.quote.anyone": "{visibility}, luaidhean fosgailte",
|
||||
"privacy.quote.anyone": "{visibility}, luaidh fosgailte",
|
||||
"privacy.quote.disabled": "{visibility}, luaidh à comas",
|
||||
"privacy.quote.limited": "{visibility}, luaidh cuingichte",
|
||||
"privacy.unlisted.additional": "Tha seo coltach ris an fhaicsinneachd phoblach ach cha nochd am post air loidhnichean-ama an t-saoghail phoblaich, nan tagaichean hais no an rùrachaidh no ann an toraidhean luirg Mhastodon fiù ’s ma thug thu ro-aonta airson sin seachad.",
|
||||
@@ -758,6 +764,7 @@
|
||||
"privacy_policy.title": "Poileasaidh prìobhaideachd",
|
||||
"quote_error.edit": "Chan urrainn dhut luaidh a chur ris nuair a bhios tu ri deasachadh puist.",
|
||||
"quote_error.poll": "Chan fhaod thu luaidh a chur an cois cunntais-bheachd.",
|
||||
"quote_error.private_mentions": "Chan fhaod thu luaidh a chur an cois iomraidh phrìobhaidich.",
|
||||
"quote_error.quote": "Chan eil taic ach ri aon luaidh aig an aon àm.",
|
||||
"quote_error.unauthorized": "Chan fhaod thu am post seo a luaidh.",
|
||||
"quote_error.upload": "Chan fhaod thu meadhan a chur ri luaidh.",
|
||||
@@ -1011,6 +1018,8 @@
|
||||
"video.volume_down": "Lùghdaich an fhuaim",
|
||||
"video.volume_up": "Cuir an fhuaim an àirde",
|
||||
"visibility_modal.button_title": "Suidhich an fhaicsinneachd",
|
||||
"visibility_modal.direct_quote_warning.text": "Ma shàbhaileas tu na roghainnean làithreach, thèid ceangal a dhèanamh dhen luaidh leabaichte.",
|
||||
"visibility_modal.direct_quote_warning.title": "Chan urrainn dhut luaidh a leabachadh ann an iomradh prìobhaideach",
|
||||
"visibility_modal.header": "Faicsinneachd ⁊ eadar-ghabhail",
|
||||
"visibility_modal.helper.direct_quoting": "Chan urrainn do chàch iomraidhean prìobhaideach a chaidh a sgrìobhadh le Mastodon a luaidh.",
|
||||
"visibility_modal.helper.privacy_editing": "Chan urrainn dhut faicsinneachd puist atharrachadh às dhèidh fhoillseachadh.",
|
||||
|
||||
@@ -194,6 +194,7 @@
|
||||
"community.column_settings.local_only": "Só local",
|
||||
"community.column_settings.media_only": "Só multimedia",
|
||||
"community.column_settings.remote_only": "Só remoto",
|
||||
"compose.error.blank_post": "A publicación non pode estar baleira.",
|
||||
"compose.language.change": "Elixe o idioma",
|
||||
"compose.language.search": "Buscar idiomas...",
|
||||
"compose.published.body": "Mensaxe publicada.",
|
||||
@@ -246,6 +247,11 @@
|
||||
"confirmations.missing_alt_text.secondary": "Publicar igualmente",
|
||||
"confirmations.missing_alt_text.title": "Engadir texto descritivo?",
|
||||
"confirmations.mute.confirm": "Acalar",
|
||||
"confirmations.private_quote_notify.cancel": "Volver á edición",
|
||||
"confirmations.private_quote_notify.confirm": "Publicar publicación",
|
||||
"confirmations.private_quote_notify.do_not_show_again": "Non me volvas a mostrar esta mensaxe",
|
||||
"confirmations.private_quote_notify.message": "A persoa que estás a citar e outras contas mencionadas serán notificadas e poderán ver a túa publicación, incluso se non te seguen.",
|
||||
"confirmations.private_quote_notify.title": "Compartir coas seguidoras e coas usuarias mencionadas?",
|
||||
"confirmations.quiet_post_quote_info.dismiss": "Non lembrarmo máis",
|
||||
"confirmations.quiet_post_quote_info.got_it": "Entendido",
|
||||
"confirmations.quiet_post_quote_info.message": "Ao citar unha publicación pública limitada a túa publicación non aparecerá nas cronoloxías de tendencias.",
|
||||
@@ -758,6 +764,7 @@
|
||||
"privacy_policy.title": "Política de Privacidade",
|
||||
"quote_error.edit": "Non se poden engadir citas ao editar unha publicación.",
|
||||
"quote_error.poll": "Non se permite citar as enquisas.",
|
||||
"quote_error.private_mentions": "As citas non están permitidas nas mencións directas.",
|
||||
"quote_error.quote": "Só se permite citar unha vez.",
|
||||
"quote_error.unauthorized": "Non tes permiso para citar esta publicación.",
|
||||
"quote_error.upload": "As citas non están permitidas para anexos multimedia.",
|
||||
@@ -911,9 +918,12 @@
|
||||
"status.pin": "Fixar no perfil",
|
||||
"status.quote": "Citar",
|
||||
"status.quote.cancel": "Cancelar a cita",
|
||||
"status.quote_error.blocked_account_hint.title": "A publicación está oculta porque bloqueaches a @{name}.",
|
||||
"status.quote_error.blocked_domain_hint.title": "A publicación está oculta porque bloqueaches {domain}.",
|
||||
"status.quote_error.filtered": "Oculto debido a un dos teus filtros",
|
||||
"status.quote_error.limited_account_hint.action": "Mostrar igualmente",
|
||||
"status.quote_error.limited_account_hint.title": "A moderación de {domain} ocultou esta conta.",
|
||||
"status.quote_error.muted_account_hint.title": "A publicación está oculta porque silenciaches a @{name}.",
|
||||
"status.quote_error.not_available": "Publicación non dispoñible",
|
||||
"status.quote_error.pending_approval": "Publicación pendente",
|
||||
"status.quote_error.pending_approval_popout.body": "En Mastodon podes establecer se permites que te citen. Esta publicación queda pendente á espera de que a persoa autora orixinal o autorice.",
|
||||
@@ -1008,6 +1018,8 @@
|
||||
"video.volume_down": "Baixar volume",
|
||||
"video.volume_up": "Subir volume",
|
||||
"visibility_modal.button_title": "Establece a visibilidade",
|
||||
"visibility_modal.direct_quote_warning.text": "Se gardas os axustes actuais a cita incluída vaise converter nunha ligazón.",
|
||||
"visibility_modal.direct_quote_warning.title": "As citas non se poden incluír nas mencións privadas",
|
||||
"visibility_modal.header": "Visibilidade e interaccións",
|
||||
"visibility_modal.helper.direct_quoting": "As mencións privadas creadas con Mastodon non poden ser citadas.",
|
||||
"visibility_modal.helper.privacy_editing": "Non se pode cambiar a visibilidade unha vez foi publicada.",
|
||||
|
||||
@@ -247,6 +247,11 @@
|
||||
"confirmations.missing_alt_text.secondary": "לפרסם בכל זאת",
|
||||
"confirmations.missing_alt_text.title": "להוסיף מלל חלופי?",
|
||||
"confirmations.mute.confirm": "להשתיק",
|
||||
"confirmations.private_quote_notify.cancel": "חזרה לעריכה",
|
||||
"confirmations.private_quote_notify.confirm": "פרסום ההודעה",
|
||||
"confirmations.private_quote_notify.do_not_show_again": "אל תראה לי הודעה זו שוב",
|
||||
"confirmations.private_quote_notify.message": "המצוטט ומאוזכרים אחרים יקבלו התראה ויוכלו לקרוא את ההודעה שלך, אפילו אם אינם עוקבים אחריך.",
|
||||
"confirmations.private_quote_notify.title": "לשתף עם עוקבים ומאוזכרים?",
|
||||
"confirmations.quiet_post_quote_info.dismiss": "אל תזכיר לי שוב",
|
||||
"confirmations.quiet_post_quote_info.got_it": "הבנתי",
|
||||
"confirmations.quiet_post_quote_info.message": "כשמצטטים הודעה ציבורית שקטה, גם ההודעה המצטטת תוסתר מחלון הנושאים החמים.",
|
||||
@@ -759,6 +764,7 @@
|
||||
"privacy_policy.title": "מדיניות פרטיות",
|
||||
"quote_error.edit": "לא ניתן להוסיף ציטוטים בשלב עריכת ההודעה.",
|
||||
"quote_error.poll": "לא ניתן לכלול משאל כאשר מחברים הודעת ציטוט.",
|
||||
"quote_error.private_mentions": "ציטוט אינו אפשרי בהודעות פרטיות.",
|
||||
"quote_error.quote": "רק ציטוט אחד מותר בכל הודעה.",
|
||||
"quote_error.unauthorized": "אין לך הרשאה לצטט את ההודעה הזו.",
|
||||
"quote_error.upload": "ציטוט הכולל מדיה אינו אפשרי.",
|
||||
@@ -1012,6 +1018,8 @@
|
||||
"video.volume_down": "הנמכת עוצמת השמע",
|
||||
"video.volume_up": "הגברת עוצמת שמע",
|
||||
"visibility_modal.button_title": "בחירת רמת חשיפה",
|
||||
"visibility_modal.direct_quote_warning.text": "אם תשמרו את ההעדפות הנוכחיות, הציטוט המוטמע יהפוך לקישור.",
|
||||
"visibility_modal.direct_quote_warning.title": "לא ניתן להטמיע ציטוטים בהודעות פרטיות",
|
||||
"visibility_modal.header": "חשיפה והידוּד (אינטראקציה)",
|
||||
"visibility_modal.helper.direct_quoting": "איזכורים פרטיים שנוצרו במסטודון חסומים מציטוט על ידי אחרים.",
|
||||
"visibility_modal.helper.privacy_editing": "רמת החשיפה של ההודעה לא ניתנת לשינוי אחרי הפרסום.",
|
||||
|
||||
@@ -247,6 +247,11 @@
|
||||
"confirmations.missing_alt_text.secondary": "Közzététel mindenképpen",
|
||||
"confirmations.missing_alt_text.title": "Helyettesítő szöveg hozzáadása?",
|
||||
"confirmations.mute.confirm": "Némítás",
|
||||
"confirmations.private_quote_notify.cancel": "Vissza a szerkesztéshez",
|
||||
"confirmations.private_quote_notify.confirm": "Bejegyzés közzététele",
|
||||
"confirmations.private_quote_notify.do_not_show_again": "Ne jelenítse meg újra ezt az üzenetet",
|
||||
"confirmations.private_quote_notify.message": "Akit idézel, és a többi megemlített értesítve lesz, és megtekinthetik a bejegyzésed, még akkor is, ha nem követnek.",
|
||||
"confirmations.private_quote_notify.title": "Megosztás a követőkkel és a megemlített felhasználókkal?",
|
||||
"confirmations.quiet_post_quote_info.dismiss": "Ne emlékeztessen újra",
|
||||
"confirmations.quiet_post_quote_info.got_it": "Rendben",
|
||||
"confirmations.quiet_post_quote_info.message": "Ha csendes nyilvános bejegyzést idézel, akkor a bejegyzés el lesz rejtve a felkapottak idővonalairól.",
|
||||
@@ -1012,6 +1017,8 @@
|
||||
"video.volume_down": "Hangerő le",
|
||||
"video.volume_up": "Hangerő fel",
|
||||
"visibility_modal.button_title": "Láthatóság beállítása",
|
||||
"visibility_modal.direct_quote_warning.text": "Ha mented a jelenlegi beállításokat, akkor a beágyazott idézet hivatkozássá lesz alakítva.",
|
||||
"visibility_modal.direct_quote_warning.title": "Idézetek nem ágyazhatóak be privát említésekbe",
|
||||
"visibility_modal.header": "Láthatóság és interakció",
|
||||
"visibility_modal.helper.direct_quoting": "A Mastodonon készült privát említéseket mások nem idézhetik.",
|
||||
"visibility_modal.helper.privacy_editing": "A láthatóság nem módosítható a bejegyzés közzététele után.",
|
||||
|
||||
@@ -247,6 +247,11 @@
|
||||
"confirmations.missing_alt_text.secondary": "Birta samt",
|
||||
"confirmations.missing_alt_text.title": "Bæta við hjálpartexta?",
|
||||
"confirmations.mute.confirm": "Þagga",
|
||||
"confirmations.private_quote_notify.cancel": "Til baka í breytingar",
|
||||
"confirmations.private_quote_notify.confirm": "Birta færslu",
|
||||
"confirmations.private_quote_notify.do_not_show_again": "Ekki birta þessi skilaboð aftur",
|
||||
"confirmations.private_quote_notify.message": "Sá sem vitnað er í og aðrir sem minnst er á verða látin vita og munu geta skoðað færsluna þína, jafnvel þótt viðkomandi fylgist ekki með þér.",
|
||||
"confirmations.private_quote_notify.title": "Deila með fylgjendum og þeim sem minnst er á?",
|
||||
"confirmations.quiet_post_quote_info.dismiss": "Ekki minna mig aftur á þetta",
|
||||
"confirmations.quiet_post_quote_info.got_it": "Náði því",
|
||||
"confirmations.quiet_post_quote_info.message": "Þegar þú vitnar í hljóðláta opinbera færslu, verður færslan þín ekki birt á vinsældatímalínum.",
|
||||
@@ -759,6 +764,7 @@
|
||||
"privacy_policy.title": "Persónuverndarstefna",
|
||||
"quote_error.edit": "Ekki er hægt að bæta við tilvitnunum þegar færslum er breytt.",
|
||||
"quote_error.poll": "Ekki er leyft að vitna í kannanir.",
|
||||
"quote_error.private_mentions": "Tilvitnanir eru ekki leyfðar í beinu einkaspjalli.",
|
||||
"quote_error.quote": "Einungis ein tilvitnun er leyfð í einu.",
|
||||
"quote_error.unauthorized": "Þú hefur ekki heimild til að vitna í þessa færslu.",
|
||||
"quote_error.upload": "Ekki er leyft að vitna í myndviðhengi.",
|
||||
@@ -1012,6 +1018,8 @@
|
||||
"video.volume_down": "Lækka hljóðstyrk",
|
||||
"video.volume_up": "Hækka hljóðstyrk",
|
||||
"visibility_modal.button_title": "Stilla sýnileika",
|
||||
"visibility_modal.direct_quote_warning.text": "Ef þú vistar þessa stillingu, þá verður ívöfnu tilvitnuninni breytt í tengil.",
|
||||
"visibility_modal.direct_quote_warning.title": "Ekki er hægt að ívefja tilvitnanir í beinu einkaspjalli",
|
||||
"visibility_modal.header": "Sýnileiki og gagnvirkni",
|
||||
"visibility_modal.helper.direct_quoting": "Ekki er hægt að vitna í einkaspjall sem skrifað er á Mastodon.",
|
||||
"visibility_modal.helper.privacy_editing": "Ekki er hægt að breyta sýnileika færslu eftir að hún hefur verið birt.",
|
||||
|
||||
@@ -172,7 +172,9 @@
|
||||
"column.domain_blocks": "Domini bloccati",
|
||||
"column.edit_list": "Modifica lista",
|
||||
"column.favourites": "Preferiti",
|
||||
"column.firehose": "Feed dal vivo",
|
||||
"column.firehose": "Feed in diretta",
|
||||
"column.firehose_local": "Feed in diretta per questo server",
|
||||
"column.firehose_singular": "Feed in diretta",
|
||||
"column.follow_requests": "Richieste di seguirti",
|
||||
"column.home": "Home",
|
||||
"column.list_members": "Gestisci i membri della lista",
|
||||
@@ -192,6 +194,7 @@
|
||||
"community.column_settings.local_only": "Solo Locale",
|
||||
"community.column_settings.media_only": "Solo Media",
|
||||
"community.column_settings.remote_only": "Solo Remoto",
|
||||
"compose.error.blank_post": "Il post non può essere vuoto.",
|
||||
"compose.language.change": "Cambia la lingua",
|
||||
"compose.language.search": "Cerca lingue...",
|
||||
"compose.published.body": "Post pubblicato.",
|
||||
@@ -244,6 +247,11 @@
|
||||
"confirmations.missing_alt_text.secondary": "Pubblica comunque",
|
||||
"confirmations.missing_alt_text.title": "Aggiungere testo alternativo?",
|
||||
"confirmations.mute.confirm": "Silenzia",
|
||||
"confirmations.private_quote_notify.cancel": "Torna a modificare",
|
||||
"confirmations.private_quote_notify.confirm": "Pubblica il post",
|
||||
"confirmations.private_quote_notify.do_not_show_again": "Non mostrarmi più questo messaggio",
|
||||
"confirmations.private_quote_notify.message": "La persona che stai citando e le altre persone menzionate riceveranno una notifica e potranno visualizzare il tuo post, anche se non ti stanno seguendo.",
|
||||
"confirmations.private_quote_notify.title": "Condividere con i seguaci e gli utenti menzionati?",
|
||||
"confirmations.quiet_post_quote_info.dismiss": "Non ricordarmelo più",
|
||||
"confirmations.quiet_post_quote_info.got_it": "Ho capito",
|
||||
"confirmations.quiet_post_quote_info.message": "Quando citi un post pubblico silenzioso, il tuo post verrà nascosto dalle timeline di tendenza.",
|
||||
@@ -575,8 +583,8 @@
|
||||
"navigation_bar.follows_and_followers": "Seguiti e seguaci",
|
||||
"navigation_bar.import_export": "Importa ed esporta",
|
||||
"navigation_bar.lists": "Liste",
|
||||
"navigation_bar.live_feed_local": "Feed live (locale)",
|
||||
"navigation_bar.live_feed_public": "Feed live (pubblico)",
|
||||
"navigation_bar.live_feed_local": "Feed in diretta (locale)",
|
||||
"navigation_bar.live_feed_public": "Feed in diretta (pubblico)",
|
||||
"navigation_bar.logout": "Disconnettiti",
|
||||
"navigation_bar.moderation": "Moderazione",
|
||||
"navigation_bar.more": "Altro",
|
||||
@@ -756,6 +764,7 @@
|
||||
"privacy_policy.title": "Politica sulla Privacy",
|
||||
"quote_error.edit": "Le citazioni non possono essere aggiunte quando si modifica un post.",
|
||||
"quote_error.poll": "Nei sondaggi non sono consentite le citazioni.",
|
||||
"quote_error.private_mentions": "Le citazioni non sono consentite con le menzioni dirette.",
|
||||
"quote_error.quote": "È consentita una sola citazione alla volta.",
|
||||
"quote_error.unauthorized": "Non sei autorizzato a citare questo post.",
|
||||
"quote_error.upload": "Le citazioni non sono consentite con gli allegati multimediali.",
|
||||
@@ -909,9 +918,12 @@
|
||||
"status.pin": "Fissa in cima sul profilo",
|
||||
"status.quote": "Cita",
|
||||
"status.quote.cancel": "Annulla la citazione",
|
||||
"status.quote_error.blocked_account_hint.title": "Questo post è nascosto perché hai bloccato @{name}.",
|
||||
"status.quote_error.blocked_domain_hint.title": "Questo post è nascosto perché hai bloccato @{domain}.",
|
||||
"status.quote_error.filtered": "Nascosto a causa di uno dei tuoi filtri",
|
||||
"status.quote_error.limited_account_hint.action": "Mostra comunque",
|
||||
"status.quote_error.limited_account_hint.title": "Questo profilo è stato nascosto dai moderatori di {domain}.",
|
||||
"status.quote_error.muted_account_hint.title": "Questo post è nascosto perché hai silenziato @{name}.",
|
||||
"status.quote_error.not_available": "Post non disponibile",
|
||||
"status.quote_error.pending_approval": "Post in attesa",
|
||||
"status.quote_error.pending_approval_popout.body": "Su Mastodon, puoi controllare se qualcuno può citarti. Questo post è in attesa dell'approvazione dell'autore originale.",
|
||||
@@ -1006,6 +1018,8 @@
|
||||
"video.volume_down": "Abbassa volume",
|
||||
"video.volume_up": "Alza volume",
|
||||
"visibility_modal.button_title": "Imposta la visibilità",
|
||||
"visibility_modal.direct_quote_warning.text": "Se si salvano le impostazioni correnti, la citazione incorporata verrà convertita in un collegamento.",
|
||||
"visibility_modal.direct_quote_warning.title": "Le citazioni non possono essere incorporate in menzioni private",
|
||||
"visibility_modal.header": "Visibilità e interazione",
|
||||
"visibility_modal.helper.direct_quoting": "Le menzioni private scritte su Mastodon non possono essere citate da altri.",
|
||||
"visibility_modal.helper.privacy_editing": "La visibilità non può essere modificata dopo la pubblicazione di un post.",
|
||||
|
||||
@@ -40,6 +40,11 @@
|
||||
"account.featured_tags.last_status_never": "投稿がありません",
|
||||
"account.follow": "フォロー",
|
||||
"account.follow_back": "フォローバック",
|
||||
"account.follow_back_short": "フォローバック",
|
||||
"account.follow_request": "フォローリクエスト",
|
||||
"account.follow_request_cancel": "リクエストをキャンセル",
|
||||
"account.follow_request_cancel_short": "キャンセル",
|
||||
"account.follow_request_short": "リクエスト",
|
||||
"account.followers": "フォロワー",
|
||||
"account.followers.empty": "まだ誰もフォローしていません。",
|
||||
"account.followers_counter": "{count, plural, other {{counter} フォロワー}}",
|
||||
@@ -247,7 +252,12 @@
|
||||
"confirmations.remove_from_followers.title": "フォロワーを削除しますか?",
|
||||
"confirmations.revoke_quote.confirm": "投稿を削除",
|
||||
"confirmations.revoke_quote.title": "投稿を削除しますか?",
|
||||
"confirmations.unblock.confirm": "ブロック解除",
|
||||
"confirmations.unblock.title": "@{name}さんのブロックを解除しますか?",
|
||||
"confirmations.unfollow.confirm": "フォロー解除",
|
||||
"confirmations.unfollow.title": "{name} さんのフォローを解除しますか?",
|
||||
"confirmations.withdraw_request.confirm": "リクエスト取り消し",
|
||||
"confirmations.withdraw_request.title": "{name} さんのフォローリクエストを取り消しますか?",
|
||||
"content_warning.hide": "内容を隠す",
|
||||
"content_warning.show": "承知して表示",
|
||||
"content_warning.show_more": "続きを表示",
|
||||
@@ -317,6 +327,7 @@
|
||||
"empty_column.bookmarked_statuses": "まだ何もブックマーク登録していません。ブックマーク登録するとここに表示されます。",
|
||||
"empty_column.community": "ローカルタイムラインはまだ使われていません。何か書いてみましょう!",
|
||||
"empty_column.direct": "非公開の返信はまだありません。非公開でやりとりをするとここに表示されます。",
|
||||
"empty_column.disabled_feed": "このフィードはサーバー管理者によって無効にされています。",
|
||||
"empty_column.domain_blocks": "ブロックしているドメインはありません。",
|
||||
"empty_column.explore_statuses": "まだ何もありません。後で確認してください。",
|
||||
"empty_column.favourited_statuses": "お気に入りの投稿はまだありません。お気に入りに登録すると、ここに表示されます。",
|
||||
@@ -841,6 +852,7 @@
|
||||
"status.cancel_reblog_private": "ブースト解除",
|
||||
"status.cannot_quote": "この投稿は引用できません",
|
||||
"status.cannot_reblog": "この投稿はブーストできません",
|
||||
"status.context.retry": "リトライ",
|
||||
"status.continued_thread": "続きのスレッド",
|
||||
"status.copy": "投稿へのリンクをコピー",
|
||||
"status.delete": "削除",
|
||||
@@ -872,7 +884,10 @@
|
||||
"status.quote_error.filtered": "あなたのフィルター設定によって非表示になっています",
|
||||
"status.quote_error.pending_approval": "承認待ちの投稿",
|
||||
"status.quote_noun": "引用",
|
||||
"status.quote_post_author": "{name} の投稿を引用",
|
||||
"status.quote_private": "非公開の投稿は引用できません",
|
||||
"status.quotes": "{count, plural, other {引用}}",
|
||||
"status.quotes.local_other_disclaimer": "投稿者が拒否した引用は表示されません。",
|
||||
"status.read_more": "もっと見る",
|
||||
"status.reblog": "ブースト",
|
||||
"status.reblog_or_quote": "ブーストか引用",
|
||||
@@ -888,6 +903,7 @@
|
||||
"status.reply": "返信",
|
||||
"status.replyAll": "全員に返信",
|
||||
"status.report": "@{name}さんを通報",
|
||||
"status.revoke_quote": "{name} さんの投稿から自分の投稿を削除",
|
||||
"status.sensitive_warning": "閲覧注意",
|
||||
"status.share": "共有",
|
||||
"status.show_less_all": "全て隠す",
|
||||
@@ -925,6 +941,7 @@
|
||||
"upload_button.label": "メディアを追加 (複数の画像または1つの動画か音声ファイル)",
|
||||
"upload_error.limit": "アップロードできる上限を超えています。",
|
||||
"upload_error.poll": "アンケートではファイルをアップロードできません。",
|
||||
"upload_error.quote": "引用ではファイルをアップロードできません。",
|
||||
"upload_form.drag_and_drop.instructions": "メディア添付ファイルを選択するには、スペースキーまたはエンターキーを押してください。ドラッグ中は、矢印キーを使ってメディア添付ファイルを任意の方向に移動できます。再度スペースキーまたはエンターキーを押すと新しい位置にメディア添付ファイルをドロップできます。キャンセルするにはエスケープキーを押してください。",
|
||||
"upload_form.drag_and_drop.on_drag_cancel": "ドラッグがキャンセルされました。メディア添付ファイル {item} がドロップされました。",
|
||||
"upload_form.drag_and_drop.on_drag_end": "メディア添付ファイル {item} がドロップされました。",
|
||||
@@ -949,6 +966,11 @@
|
||||
"video.volume_down": "音量を下げる",
|
||||
"video.volume_up": "音量を上げる",
|
||||
"visibility_modal.button_title": "公開範囲の設定",
|
||||
"visibility_modal.header": "公開範囲と引用",
|
||||
"visibility_modal.helper.direct_quoting": "Mastodon で作成された非公開の返信は他人から引用できません。",
|
||||
"visibility_modal.helper.private_quoting": "Mastodon で作成されたフォロワーのみの投稿は他人から引用できません。",
|
||||
"visibility_modal.helper.unlisted_quoting": "誰かがあなたを引用すると、その投稿もトレンドから非表示になります。",
|
||||
"visibility_modal.instructions": "この投稿の公開・引用範囲を設定します。また、<link>「デフォルトの投稿設定」</link>から今後の投稿の範囲を設定可能です。",
|
||||
"visibility_modal.privacy_label": "公開範囲",
|
||||
"visibility_modal.quote_followers": "フォロワーのみ",
|
||||
"visibility_modal.quote_label": "引用できるユーザー",
|
||||
|
||||
@@ -24,6 +24,7 @@
|
||||
"account.direct": "Bder-d @{name} weḥd-s",
|
||||
"account.disable_notifications": "Ḥbes ur iyi-d-ttazen ara ilɣa mi ara d-isuffeɣ @{name}",
|
||||
"account.edit_profile": "Ẓreg amaɣnu",
|
||||
"account.edit_profile_short": "Ẓreg",
|
||||
"account.enable_notifications": "Azen-iyi-d ilɣa mi ara d-isuffeɣ @{name}",
|
||||
"account.endorse": "Welleh fell-as deg umaɣnu-inek",
|
||||
"account.familiar_followers_many": "Yeṭṭafaṛ-it {name1} d {name2}, akked {othersCount, plural, one {yiwen nniḍen i tessneḍ} other {# nniḍen i tessneḍ}}",
|
||||
@@ -35,6 +36,9 @@
|
||||
"account.featured_tags.last_status_never": "Ulac tisuffaɣ",
|
||||
"account.follow": "Ḍfer",
|
||||
"account.follow_back": "Ḍfer-it ula d kečč·mm",
|
||||
"account.follow_request_cancel": "Semmet asuter",
|
||||
"account.follow_request_cancel_short": "Semmet",
|
||||
"account.follow_request_short": "Asuter",
|
||||
"account.followers": "Imeḍfaren",
|
||||
"account.followers.empty": "Ar tura, ulac yiwen i yeṭṭafaṛen amseqdac-agi.",
|
||||
"account.followers_counter": "{count, plural, one {{counter} n umḍfar} other {{counter} n yimeḍfaren}}",
|
||||
@@ -193,7 +197,11 @@
|
||||
"confirmations.remove_from_followers.confirm": "Kkes aneḍfar",
|
||||
"confirmations.revoke_quote.confirm": "Kkes tasuffeɣt",
|
||||
"confirmations.revoke_quote.title": "Kkes tasuffeɣt?",
|
||||
"confirmations.unblock.confirm": "Serreḥ",
|
||||
"confirmations.unblock.title": "Serreḥ i {name}?",
|
||||
"confirmations.unfollow.confirm": "Ur ḍḍafaṛ ara",
|
||||
"confirmations.unfollow.title": "Ḥbes aḍfar n {name}?",
|
||||
"confirmations.withdraw_request.confirm": "Agwi asuter",
|
||||
"content_warning.hide": "Ffer tasuffeɣt",
|
||||
"content_warning.show": "Ssken-d akken tebɣu tili",
|
||||
"content_warning.show_more": "Sken-d ugar",
|
||||
@@ -456,6 +464,7 @@
|
||||
"notification.follow": "iṭṭafar-ik·em-id {name}",
|
||||
"notification.follow.name_and_others": "{name} akked <a>{count, plural, one {# nniḍen} other {# nniḍen}}</a> iḍfeṛ-k·m-id",
|
||||
"notification.follow_request": "{name} yessuter-d ad k·m-yeḍfeṛ",
|
||||
"notification.follow_request.name_and_others": "{name} d {count, plural, one {# nnayeḍ} other {# nniḍen}} yessuter-d ad k·kem-yeḍfer",
|
||||
"notification.label.mention": "Abdar",
|
||||
"notification.label.private_mention": "Abdar uslig",
|
||||
"notification.label.private_reply": "Tiririt tusligt",
|
||||
@@ -646,6 +655,9 @@
|
||||
"status.bookmark": "Creḍ",
|
||||
"status.cancel_reblog_private": "Sefsex beṭṭu",
|
||||
"status.cannot_reblog": "Tasuffeɣt-a ur tezmir ara ad tettwabḍu tikelt-nniḍen",
|
||||
"status.contains_quote": "Yegber tanebdurt",
|
||||
"status.context.loading": "Aɛebbi n tririyin nniḍen",
|
||||
"status.context.more_replies_found": "Ugar n tririyin ttwafent",
|
||||
"status.context.retry": "Ɛreḍ tikkelt nniḍen",
|
||||
"status.context.show": "Sken-d",
|
||||
"status.continued_thread": "Asqerdec yettkemmil",
|
||||
|
||||
@@ -247,6 +247,9 @@
|
||||
"confirmations.missing_alt_text.secondary": "그냥 게시하기",
|
||||
"confirmations.missing_alt_text.title": "대체 텍스트를 추가할까요? ",
|
||||
"confirmations.mute.confirm": "뮤트",
|
||||
"confirmations.private_quote_notify.cancel": "편집으로 돌아가기",
|
||||
"confirmations.private_quote_notify.confirm": "게시",
|
||||
"confirmations.private_quote_notify.do_not_show_again": "이 메시지를 다시 표시하지 않음",
|
||||
"confirmations.quiet_post_quote_info.dismiss": "다시 보지 않기",
|
||||
"confirmations.quiet_post_quote_info.got_it": "알겠습니다",
|
||||
"confirmations.quiet_post_quote_info.message": "조용한 공개 게시물을 인용하면 그 게시물은 유행 타임라인에서 나타나지 않을 것입니다.",
|
||||
@@ -758,6 +761,7 @@
|
||||
"privacy_policy.title": "개인정보처리방침",
|
||||
"quote_error.edit": "게시물을 수정하면서 인용을 추가할 수 없습니다.",
|
||||
"quote_error.poll": "인용과 투표를 함께 사용할 수 없습니다.",
|
||||
"quote_error.private_mentions": "인용과 개인 멘션을 함께 사용할 수 없습니다.",
|
||||
"quote_error.quote": "한 번의 인용만 허용됩니다.",
|
||||
"quote_error.unauthorized": "이 게시물을 인용할 권한이 없습니다.",
|
||||
"quote_error.upload": "인용과 미디어 첨부를 함께 사용할 수 없습니다.",
|
||||
|
||||
@@ -173,6 +173,8 @@
|
||||
"column.edit_list": "編輯列單",
|
||||
"column.favourites": "Siōng kah意",
|
||||
"column.firehose": "Tsit-má ê動態",
|
||||
"column.firehose_local": "Tsit ê服侍器tsit-má ê動態",
|
||||
"column.firehose_singular": "Tsit-má ê動態",
|
||||
"column.follow_requests": "跟tuè請求",
|
||||
"column.home": "頭頁",
|
||||
"column.list_members": "管理列單ê成員",
|
||||
@@ -192,6 +194,7 @@
|
||||
"community.column_settings.local_only": "Kan-ta展示本地ê",
|
||||
"community.column_settings.media_only": "Kan-ta展示媒體",
|
||||
"community.column_settings.remote_only": "Kan-ta展示遠距離ê",
|
||||
"compose.error.blank_post": "PO文bē當空白。",
|
||||
"compose.language.change": "換語言",
|
||||
"compose.language.search": "Tshiau-tshuē語言……",
|
||||
"compose.published.body": "成功PO文。",
|
||||
@@ -908,9 +911,12 @@
|
||||
"status.open": "Kā PO文展開",
|
||||
"status.quote": "引用",
|
||||
"status.quote.cancel": "取消引用",
|
||||
"status.quote_error.blocked_account_hint.title": "因為lí有封鎖 @{name},tsit篇PO文受khàm掉。",
|
||||
"status.quote_error.blocked_domain_hint.title": "因為lí有封鎖 {domain},tsit篇PO文受khàm掉。",
|
||||
"status.quote_error.filtered": "Lí所設定ê過濾器kā tse khàm起來",
|
||||
"status.quote_error.limited_account_hint.action": "Iáu是顯示",
|
||||
"status.quote_error.limited_account_hint.title": "Tsit ê口座予 {domain} ê管理員tshàng起來ah。",
|
||||
"status.quote_error.muted_account_hint.title": "因為lí有消音 @{name},tsit篇PO文受khàm掉。",
|
||||
"status.quote_error.not_available": "PO文bē當看",
|
||||
"status.quote_error.pending_approval": "PO文當咧送",
|
||||
"status.quote_error.pending_approval_popout.body": "佇Mastodon,lí ē當控制PO文kám beh hōo lâng引用。Tsit篇PO文teh等原文作者允准。",
|
||||
|
||||
@@ -194,6 +194,7 @@
|
||||
"community.column_settings.local_only": "Alleen lokaal",
|
||||
"community.column_settings.media_only": "Alleen media",
|
||||
"community.column_settings.remote_only": "Alleen andere servers",
|
||||
"compose.error.blank_post": "Bericht mag niet leeg zijn.",
|
||||
"compose.language.change": "Taal veranderen",
|
||||
"compose.language.search": "Talen zoeken...",
|
||||
"compose.published.body": "Bericht gepubliceerd.",
|
||||
@@ -246,6 +247,11 @@
|
||||
"confirmations.missing_alt_text.secondary": "Toch plaatsen",
|
||||
"confirmations.missing_alt_text.title": "Alt-tekst toevoegen?",
|
||||
"confirmations.mute.confirm": "Negeren",
|
||||
"confirmations.private_quote_notify.cancel": "Terug naar bewerken",
|
||||
"confirmations.private_quote_notify.confirm": "Bericht plaatsen",
|
||||
"confirmations.private_quote_notify.do_not_show_again": "Dit bericht niet meer aan mij tonen",
|
||||
"confirmations.private_quote_notify.message": "De persoon die je citeert en andere vermelde personen krijgen een melding en kunnen jouw bericht bekijken, zelfs als ze je niet volgen.",
|
||||
"confirmations.private_quote_notify.title": "Met volgers en vermelde gebruikers delen?",
|
||||
"confirmations.quiet_post_quote_info.dismiss": "Herinner me er niet nogmaals aan",
|
||||
"confirmations.quiet_post_quote_info.got_it": "Begrepen",
|
||||
"confirmations.quiet_post_quote_info.message": "Wanneer je een minder openbaar bericht citeert, verschijnt jouw bericht niet onder trends.",
|
||||
@@ -741,7 +747,7 @@
|
||||
"poll.votes": "{votes, plural, one {# stem} other {# stemmen}}",
|
||||
"poll_button.add_poll": "Peiling toevoegen",
|
||||
"poll_button.remove_poll": "Peiling verwijderen",
|
||||
"privacy.change": "Privacy voor een bericht aanpassen",
|
||||
"privacy.change": "Privacy van dit bericht aanpassen",
|
||||
"privacy.direct.long": "Alleen voor mensen die specifiek in het bericht worden vermeld",
|
||||
"privacy.direct.short": "Privébericht",
|
||||
"privacy.private.long": "Alleen jouw volgers",
|
||||
@@ -911,9 +917,12 @@
|
||||
"status.pin": "Aan profielpagina vastmaken",
|
||||
"status.quote": "Citeren",
|
||||
"status.quote.cancel": "Citeren annuleren",
|
||||
"status.quote_error.blocked_account_hint.title": "Dit bericht is verborgen, omdat jij @{name} hebt geblokkeerd.",
|
||||
"status.quote_error.blocked_domain_hint.title": "Dit bericht is verborgen, omdat jij alles van {domain} hebt geblokkeerd.",
|
||||
"status.quote_error.filtered": "Verborgen door een van je filters",
|
||||
"status.quote_error.limited_account_hint.action": "Alsnog tonen",
|
||||
"status.quote_error.limited_account_hint.title": "Dit account is door de moderatoren van {domain} verborgen.",
|
||||
"status.quote_error.muted_account_hint.title": "Dit bericht is verborgen, omdat jij @{name} hebt genegeerd.",
|
||||
"status.quote_error.not_available": "Bericht niet beschikbaar",
|
||||
"status.quote_error.pending_approval": "Bericht in afwachting van goedkeuring",
|
||||
"status.quote_error.pending_approval_popout.body": "Op Mastodon kun je bepalen of iemand je mag citeren. Dit bericht is in afwachting van de goedkeuring van de oorspronkelijke auteur.",
|
||||
@@ -1008,6 +1017,8 @@
|
||||
"video.volume_down": "Volume omlaag",
|
||||
"video.volume_up": "Volume omhoog",
|
||||
"visibility_modal.button_title": "Privacy instellen",
|
||||
"visibility_modal.direct_quote_warning.text": "Wanneer je de huidige instellingen opslaat wordt het citaat in een link veranderd.",
|
||||
"visibility_modal.direct_quote_warning.title": "Privéberichten kunnen geen citaten bevatten",
|
||||
"visibility_modal.header": "Zichtbaarheid en interactie",
|
||||
"visibility_modal.helper.direct_quoting": "Privéberichten afkomstig van Mastodon kunnen niet door anderen worden geciteerd.",
|
||||
"visibility_modal.helper.privacy_editing": "De zichtbaarheid kan niet meer worden gewijzigd nadat een bericht is gepubliceerd.",
|
||||
|
||||
@@ -173,6 +173,8 @@
|
||||
"column.edit_list": "Rediger liste",
|
||||
"column.favourites": "Favorittar",
|
||||
"column.firehose": "Tidslinjer",
|
||||
"column.firehose_local": "Direktestraum for denne tenaren",
|
||||
"column.firehose_singular": "Direktestraum",
|
||||
"column.follow_requests": "Fylgjeførespurnadar",
|
||||
"column.home": "Heim",
|
||||
"column.list_members": "Administrer medlemer på lista",
|
||||
@@ -192,6 +194,7 @@
|
||||
"community.column_settings.local_only": "Berre lokalt",
|
||||
"community.column_settings.media_only": "Berre media",
|
||||
"community.column_settings.remote_only": "Berre eksternt",
|
||||
"compose.error.blank_post": "Innlegg kan ikkje vera tomme.",
|
||||
"compose.language.change": "Byt språk",
|
||||
"compose.language.search": "Søk språk...",
|
||||
"compose.published.body": "Innlegg publisert.",
|
||||
@@ -244,6 +247,11 @@
|
||||
"confirmations.missing_alt_text.secondary": "Publiser likevel",
|
||||
"confirmations.missing_alt_text.title": "Legg til alternativ tekst?",
|
||||
"confirmations.mute.confirm": "Demp",
|
||||
"confirmations.private_quote_notify.cancel": "Tilbake til redigeringa",
|
||||
"confirmations.private_quote_notify.confirm": "Legg ut innlegget",
|
||||
"confirmations.private_quote_notify.do_not_show_again": "Ikkje vis dette fleire gonger",
|
||||
"confirmations.private_quote_notify.message": "Personen du siterer, og andre som er nemnde i innlegget, vil få varsel og kan sjå innlegget ditt, sjølv om dei ikkje fylgjer deg.",
|
||||
"confirmations.private_quote_notify.title": "Del med fylgjarar og folk som er nemnde?",
|
||||
"confirmations.quiet_post_quote_info.dismiss": "Ikkje minn meg på det att",
|
||||
"confirmations.quiet_post_quote_info.got_it": "Greitt",
|
||||
"confirmations.quiet_post_quote_info.message": "Når du siterer eit stille offentleg innlegg, blir innlegget ditt gøymt frå offentlege populære tidsliner.",
|
||||
@@ -333,6 +341,7 @@
|
||||
"empty_column.bookmarked_statuses": "Du har ikkje lagra noko bokmerke enno. Når du set bokmerke på eit innlegg, dukkar det opp her.",
|
||||
"empty_column.community": "Den lokale tidslina er tom. Skriv noko offentleg å få ballen til å rulle!",
|
||||
"empty_column.direct": "Du har ingen private omtaler enda. Etter du har sendt eller mottatt en, så vil den dukke opp her.",
|
||||
"empty_column.disabled_feed": "Administratorane på tenaren din har skrudd av denne straumen.",
|
||||
"empty_column.domain_blocks": "Det er ingen blokkerte domene enno.",
|
||||
"empty_column.explore_statuses": "Ingenting er populært nett no. Prøv att seinare!",
|
||||
"empty_column.favourited_statuses": "Du har ingen favoritt-statusar ennå. Når du merkjer ein som favoritt, dukkar han opp her.",
|
||||
@@ -755,6 +764,7 @@
|
||||
"privacy_policy.title": "Personvernsreglar",
|
||||
"quote_error.edit": "Du kan ikkje leggja til sitat når du redigerer eit innlegg.",
|
||||
"quote_error.poll": "Du kan ikkje sitera meiningsmålingar.",
|
||||
"quote_error.private_mentions": "Du kan ikkje sitera direkteomtaler.",
|
||||
"quote_error.quote": "Det er berre lov med eitt sitat om gongen.",
|
||||
"quote_error.unauthorized": "Du har ikkje løyve til å sitera dette innlegget.",
|
||||
"quote_error.upload": "Du kan ikkje sitera medievedlegg.",
|
||||
@@ -908,9 +918,12 @@
|
||||
"status.pin": "Fest på profil",
|
||||
"status.quote": "Siter",
|
||||
"status.quote.cancel": "Avbryt siteringa",
|
||||
"status.quote_error.blocked_account_hint.title": "Dette innlegget er gøymt fordi du har blokkert @{name}.",
|
||||
"status.quote_error.blocked_domain_hint.title": "Dette innlegget er gøymt fordi du har blokkert {domain}.",
|
||||
"status.quote_error.filtered": "Gøymt på grunn av eitt av filtra dine",
|
||||
"status.quote_error.limited_account_hint.action": "Vis likevel",
|
||||
"status.quote_error.limited_account_hint.title": "Denne kontoen har vorte skjult av moderatorane på {domain}.",
|
||||
"status.quote_error.muted_account_hint.title": "Dette innlegget er gøymt fordi du har dempa @{name}.",
|
||||
"status.quote_error.not_available": "Innlegget er ikkje tilgjengeleg",
|
||||
"status.quote_error.pending_approval": "Innlegget ventar",
|
||||
"status.quote_error.pending_approval_popout.body": "På Mastodon kan du kontrollera om folk får sitera deg. Innlegget ditt ventar medan me ventar på at opphavspersonen godkjenner det.",
|
||||
@@ -1005,6 +1018,8 @@
|
||||
"video.volume_down": "Volum ned",
|
||||
"video.volume_up": "Volum opp",
|
||||
"visibility_modal.button_title": "Vel vising",
|
||||
"visibility_modal.direct_quote_warning.text": "Viss du lagrar innstillingane, vil det innebygde sitatet bli omgjort til lenke.",
|
||||
"visibility_modal.direct_quote_warning.title": "Du kan ikkje byggja inn sitat i direkteomtaler",
|
||||
"visibility_modal.header": "Vising og samhandling",
|
||||
"visibility_modal.helper.direct_quoting": "Private omtalar som er skrivne på Mastodon kan ikkje siterast av andre.",
|
||||
"visibility_modal.helper.privacy_editing": "Du kan ikkje endra korleis eit innlegg viser når du har lagt det ut.",
|
||||
|
||||
@@ -173,6 +173,8 @@
|
||||
"column.edit_list": "Editar lista",
|
||||
"column.favourites": "Favoritos",
|
||||
"column.firehose": "Feeds ao vivo",
|
||||
"column.firehose_local": "Transmissão ao vivo deste servidor",
|
||||
"column.firehose_singular": "Transmissão ao vivo",
|
||||
"column.follow_requests": "Seguidores pendentes",
|
||||
"column.home": "Página inicial",
|
||||
"column.list_members": "Gerenciar membros da lista",
|
||||
@@ -192,6 +194,7 @@
|
||||
"community.column_settings.local_only": "Somente local",
|
||||
"community.column_settings.media_only": "Somente mídia",
|
||||
"community.column_settings.remote_only": "Somente global",
|
||||
"compose.error.blank_post": "A postagem não pode estar em branco.",
|
||||
"compose.language.change": "Alterar idioma",
|
||||
"compose.language.search": "Pesquisar idiomas...",
|
||||
"compose.published.body": "Publicado.",
|
||||
@@ -909,9 +912,12 @@
|
||||
"status.pin": "Fixar",
|
||||
"status.quote": "Citar",
|
||||
"status.quote.cancel": "Cancelar citação",
|
||||
"status.quote_error.blocked_account_hint.title": "Esta publicação está oculta porque você bloqueou @{name}.",
|
||||
"status.quote_error.blocked_domain_hint.title": "Esta publicação está oculta porque você bloqueou {domain}.",
|
||||
"status.quote_error.filtered": "Oculto devido a um dos seus filtros",
|
||||
"status.quote_error.limited_account_hint.action": "Mostrar mesmo assim",
|
||||
"status.quote_error.limited_account_hint.title": "Esta conta foi oculta pelos moderadores do {domain}.",
|
||||
"status.quote_error.muted_account_hint.title": "Esta publicação está oculta porque você silenciou @{name}.",
|
||||
"status.quote_error.not_available": "Publicação indisponível",
|
||||
"status.quote_error.pending_approval": "Publicação pendente",
|
||||
"status.quote_error.pending_approval_popout.body": "No Mastodon, você pode controlar se alguém pode citar você. Esta publicação está pendente enquanto estamos recebendo a aprovação do autor original.",
|
||||
|
||||
@@ -247,6 +247,11 @@
|
||||
"confirmations.missing_alt_text.secondary": "Publicar mesmo assim",
|
||||
"confirmations.missing_alt_text.title": "Adicionar texto alternativo?",
|
||||
"confirmations.mute.confirm": "Ocultar",
|
||||
"confirmations.private_quote_notify.cancel": "Voltar à edição",
|
||||
"confirmations.private_quote_notify.confirm": "Publicar",
|
||||
"confirmations.private_quote_notify.do_not_show_again": "Não mostrar novamente esta mensagem",
|
||||
"confirmations.private_quote_notify.message": "A pessoa que está a citar e outras mencionadas serão notificadas e poderão ver a sua publicação, mesmo que não o sigam.",
|
||||
"confirmations.private_quote_notify.title": "Partilhar com seguidores e utilizadores mencionados?",
|
||||
"confirmations.quiet_post_quote_info.dismiss": "Não me relembre novamente",
|
||||
"confirmations.quiet_post_quote_info.got_it": "Entendido",
|
||||
"confirmations.quiet_post_quote_info.message": "Ao citar uma publicação não listada, a sua publicação não será exibida nos destaques.",
|
||||
@@ -759,6 +764,7 @@
|
||||
"privacy_policy.title": "Política de privacidade",
|
||||
"quote_error.edit": "Não é possível adicionar citações ao editar uma publicação.",
|
||||
"quote_error.poll": "Não é permitido citar sondagens.",
|
||||
"quote_error.private_mentions": "A citação não é permitida em menções privadas.",
|
||||
"quote_error.quote": "Apenas é permitida uma citação de cada vez.",
|
||||
"quote_error.unauthorized": "Não está autorizado a citar esta publicação.",
|
||||
"quote_error.upload": "Não é permitida a citação com anexos de multimédia.",
|
||||
@@ -1012,6 +1018,8 @@
|
||||
"video.volume_down": "Diminuir volume",
|
||||
"video.volume_up": "Aumentar volume",
|
||||
"visibility_modal.button_title": "Definir visibilidade",
|
||||
"visibility_modal.direct_quote_warning.text": "Se guardar as definições atuais, a citação incorporada será convertida numa hiperligação.",
|
||||
"visibility_modal.direct_quote_warning.title": "Citações não podem ser incorporadas em menções privadas",
|
||||
"visibility_modal.header": "Visibilidade e interação",
|
||||
"visibility_modal.helper.direct_quoting": "As menções privadas criadas no Mastodon não podem ser citadas por outras pessoas.",
|
||||
"visibility_modal.helper.privacy_editing": "A visibilidade não pode ser alterada após a publicação ser publicada.",
|
||||
|
||||
@@ -190,6 +190,7 @@
|
||||
"community.column_settings.local_only": "Vetëm vendore",
|
||||
"community.column_settings.media_only": "Vetëm Media",
|
||||
"community.column_settings.remote_only": "Vetëm të largëta",
|
||||
"compose.error.blank_post": "Postimi s’mund të jetë i zbrazët.",
|
||||
"compose.language.change": "Ndryshoni gjuhën",
|
||||
"compose.language.search": "Kërkoni te gjuhët…",
|
||||
"compose.published.body": "Postimi u botua.",
|
||||
@@ -242,6 +243,11 @@
|
||||
"confirmations.missing_alt_text.secondary": "Postoje, sido qoftë",
|
||||
"confirmations.missing_alt_text.title": "Të shtohet tekst alternativ?",
|
||||
"confirmations.mute.confirm": "Heshtoje",
|
||||
"confirmations.private_quote_notify.cancel": "Mbrapsht te përpunimi",
|
||||
"confirmations.private_quote_notify.confirm": "Botoje postimin",
|
||||
"confirmations.private_quote_notify.do_not_show_again": "Mos ma shfaq prapë këtë mesazh",
|
||||
"confirmations.private_quote_notify.message": "Personi që citoni dhe përmendje të tjera do të njoftohen dhe do të jenë në gjendje të shohin postimin tuaj, edhe pse nuk ju ndjekin.",
|
||||
"confirmations.private_quote_notify.title": "T’u shfaqet ndjekësve dhe përdoruesve të përmendur?",
|
||||
"confirmations.quiet_post_quote_info.dismiss": "Mos ma kujto më",
|
||||
"confirmations.quiet_post_quote_info.got_it": "E mora vesh",
|
||||
"confirmations.quiet_post_quote_info.message": "Kur citoni një postim publik të heshtuar, postimi juaj do të kalohet i fshehur te rrjedha kohore e gjërave në modë.",
|
||||
@@ -754,6 +760,7 @@
|
||||
"privacy_policy.title": "Rregulla Privatësie",
|
||||
"quote_error.edit": "Kur përpunohet një postim, s’mund të shtohen citime.",
|
||||
"quote_error.poll": "Me pyetësorët nuk lejohet citim.",
|
||||
"quote_error.private_mentions": "Citimi nuk lejohet me përmendje të drejtpërdrejta.",
|
||||
"quote_error.quote": "Lejohet vetëm një citim në herë.",
|
||||
"quote_error.unauthorized": "S’jen i autorizuar ta citoni këtë postim.",
|
||||
"quote_error.upload": "Me bashkëngjitjet media nuk lejohet citim.",
|
||||
@@ -1007,6 +1014,8 @@
|
||||
"video.volume_down": "Ulje volumi",
|
||||
"video.volume_up": "Ngritje volumi",
|
||||
"visibility_modal.button_title": "Caktoni dukshmëri",
|
||||
"visibility_modal.direct_quote_warning.text": "Nëse ruani rregullimet e tanishme, citimi i trupëzuar do të shndërrohet në një lidhje.",
|
||||
"visibility_modal.direct_quote_warning.title": "Citimet s’mund të trupëzohen në përmendje private",
|
||||
"visibility_modal.header": "Dukshmëri dhe ndërveprim",
|
||||
"visibility_modal.helper.direct_quoting": "Përmendje private të krijuara në Mastodon s’mund të citohen nga të tjerë.",
|
||||
"visibility_modal.helper.privacy_editing": "Dukshmëria s’mund të ndryshohet pasi postimi botohet.",
|
||||
|
||||
@@ -24,7 +24,7 @@
|
||||
"account.blocking": "Engelleme",
|
||||
"account.cancel_follow_request": "Takip isteğini geri çek",
|
||||
"account.copy": "Gönderi bağlantısını kopyala",
|
||||
"account.direct": "@{name} kullanıcısına özel olarak değin",
|
||||
"account.direct": "@{name} kullanıcısından özel olarak bahset",
|
||||
"account.disable_notifications": "@{name} kişisinin gönderi bildirimlerini kapat",
|
||||
"account.domain_blocking": "Alan adını engelleme",
|
||||
"account.edit_profile": "Profili düzenle",
|
||||
@@ -247,6 +247,11 @@
|
||||
"confirmations.missing_alt_text.secondary": "Yine de gönder",
|
||||
"confirmations.missing_alt_text.title": "Alternatif metin ekle?",
|
||||
"confirmations.mute.confirm": "Sessize al",
|
||||
"confirmations.private_quote_notify.cancel": "Düzenlemeye dön",
|
||||
"confirmations.private_quote_notify.confirm": "Gönderiyi yayınla",
|
||||
"confirmations.private_quote_notify.do_not_show_again": "Bu iletiyi bana tekrar gösterme",
|
||||
"confirmations.private_quote_notify.message": "Alıntı yaptığınız kişi ve diğer bahsedilen kişiler, sizi takip etmiyor olsalar bile bildirim alacak ve gönderinizi görüntüleyebileceklerdir.",
|
||||
"confirmations.private_quote_notify.title": "Takipçiler ve bahsedilen kullanıcılarla paylaş?",
|
||||
"confirmations.quiet_post_quote_info.dismiss": "Bana bir daha hatırlatma",
|
||||
"confirmations.quiet_post_quote_info.got_it": "Anladım",
|
||||
"confirmations.quiet_post_quote_info.message": "Sessiz bir genel gönderiyi alıntıladığınızda, gönderiniz öne çıkan zaman çizelgelerinden gizlenir.",
|
||||
@@ -759,6 +764,7 @@
|
||||
"privacy_policy.title": "Gizlilik Politikası",
|
||||
"quote_error.edit": "Gönderi düzenlenirken alıntılar eklenemez.",
|
||||
"quote_error.poll": "Anketlerde alıntıya izin verilmez.",
|
||||
"quote_error.private_mentions": "Doğrudan atıfta bulunarak alıntı yapma izni yoktur.",
|
||||
"quote_error.quote": "Bir seferde tek bir alıntıya izin var.",
|
||||
"quote_error.unauthorized": "Bu gönderiyi alıntılamaya yetkiniz yok.",
|
||||
"quote_error.upload": "Medya eklentilerini alıntılamaya izin yok.",
|
||||
@@ -1012,6 +1018,8 @@
|
||||
"video.volume_down": "Sesi kıs",
|
||||
"video.volume_up": "Sesi yükselt",
|
||||
"visibility_modal.button_title": "Görünürlüğü ayarla",
|
||||
"visibility_modal.direct_quote_warning.text": "Mevcut ayarları kaydederseniz, gömülü alıntı bir bağlantıya dönüştürülür.",
|
||||
"visibility_modal.direct_quote_warning.title": "Alıntılar özel bahsetmelere eklenemez",
|
||||
"visibility_modal.header": "Görünürlük ve etkileşim",
|
||||
"visibility_modal.helper.direct_quoting": "Mastodon'da özel değiniler başkaları tarafından alıntılanamaz.",
|
||||
"visibility_modal.helper.privacy_editing": "Gönderi yayınlandıktan sonra görünürlük değiştirilemez.",
|
||||
|
||||
@@ -247,6 +247,11 @@
|
||||
"confirmations.missing_alt_text.secondary": "Đăng luôn",
|
||||
"confirmations.missing_alt_text.title": "Thêm văn bản thay thế?",
|
||||
"confirmations.mute.confirm": "Ẩn",
|
||||
"confirmations.private_quote_notify.cancel": "Quay lại chỉnh sửa",
|
||||
"confirmations.private_quote_notify.confirm": "Đăng tút",
|
||||
"confirmations.private_quote_notify.do_not_show_again": "Không hiện thông báo này nữa",
|
||||
"confirmations.private_quote_notify.message": "Người mà bạn trích dẫn và những người được bạn nhắc đến khác sẽ được thông báo và có thể xem tút của bạn, ngay cả khi họ không theo dõi bạn.",
|
||||
"confirmations.private_quote_notify.title": "Chia sẻ với người được nhắc đến và người theo dõi?",
|
||||
"confirmations.quiet_post_quote_info.dismiss": "Không nhắc lại nữa",
|
||||
"confirmations.quiet_post_quote_info.got_it": "Đã hiểu",
|
||||
"confirmations.quiet_post_quote_info.message": "Khi trích dẫn một tút hạn chế, tút của bạn sẽ bị ẩn khỏi dòng thời gian thịnh hành.",
|
||||
@@ -759,6 +764,7 @@
|
||||
"privacy_policy.title": "Chính sách bảo mật",
|
||||
"quote_error.edit": "Không thể thêm trích dẫn khi sửa tút.",
|
||||
"quote_error.poll": "Không thể trích dẫn vốt.",
|
||||
"quote_error.private_mentions": "Không thể trích dẫn với lượt nhắc trực tiếp.",
|
||||
"quote_error.quote": "Chỉ được trích dẫn một lần.",
|
||||
"quote_error.unauthorized": "Bạn không được cấp quyền trích dẫn tút này.",
|
||||
"quote_error.upload": "Không thể trích dẫn với media đính kèm.",
|
||||
@@ -1012,6 +1018,8 @@
|
||||
"video.volume_down": "Giảm âm lượng",
|
||||
"video.volume_up": "Tăng âm lượng",
|
||||
"visibility_modal.button_title": "Thay đổi quyền riêng tư",
|
||||
"visibility_modal.direct_quote_warning.text": "Nếu bạn lưu cài đặt hiện tại, trích dẫn được nhúng sẽ được chuyển đổi thành liên kết.",
|
||||
"visibility_modal.direct_quote_warning.title": "Không thể nhúng trích dẫn vào Nhắn Riêng",
|
||||
"visibility_modal.header": "Hiển thị và tương tác",
|
||||
"visibility_modal.helper.direct_quoting": "Nhắn riêng trên Mastodon không thể được người khác trích dẫn.",
|
||||
"visibility_modal.helper.privacy_editing": "Không thể thay đổi chế độ hiển thị sau khi một tút đã đăng.",
|
||||
|
||||
@@ -247,6 +247,11 @@
|
||||
"confirmations.missing_alt_text.secondary": "就这样发布",
|
||||
"confirmations.missing_alt_text.title": "添加替代文本?",
|
||||
"confirmations.mute.confirm": "隐藏",
|
||||
"confirmations.private_quote_notify.cancel": "返回编辑",
|
||||
"confirmations.private_quote_notify.confirm": "发布嘟文",
|
||||
"confirmations.private_quote_notify.do_not_show_again": "不再显示此消息",
|
||||
"confirmations.private_quote_notify.message": "您所引用与提及的用户将收到通知且能够查看你的嘟文,即便这些用户没有关注您。",
|
||||
"confirmations.private_quote_notify.title": "是否和关注者和提及的用户分享此内容?",
|
||||
"confirmations.quiet_post_quote_info.dismiss": "不再提醒",
|
||||
"confirmations.quiet_post_quote_info.got_it": "明白了",
|
||||
"confirmations.quiet_post_quote_info.message": "当你引用悄悄公开的嘟文时,你的嘟文会从热门时间线上隐藏。",
|
||||
@@ -292,7 +297,7 @@
|
||||
"domain_block_modal.they_wont_know": "对方不会知道自己被屏蔽。",
|
||||
"domain_block_modal.title": "确定要屏蔽此域名?",
|
||||
"domain_block_modal.you_will_lose_num_followers": "你将失去 {followersCount, plural, other {{followersCountDisplay} 名关注者}}和 {followingCount, plural, other {{followingCountDisplay} 名关注}}。",
|
||||
"domain_block_modal.you_will_lose_relationships": "你将丢失该站点上的所有关注与关注者。",
|
||||
"domain_block_modal.you_will_lose_relationships": "你将丢失该站点上的全部关注与关注者。",
|
||||
"domain_block_modal.you_wont_see_posts": "你将不会看到此服务器上用户的嘟文或通知。",
|
||||
"domain_pill.activitypub_lets_connect": "它可以让你与不同社交应用上的人交流互动,而不仅限于 Mastodon。",
|
||||
"domain_pill.activitypub_like_language": "ActivityPub 好比 Mastodon 与其它社交网络交流时使用的语言。",
|
||||
@@ -305,7 +310,7 @@
|
||||
"domain_pill.who_they_are": "用户名可以表明用户的身份和其所在站点,这样你就可以通过<button>基于 ActivityPub 的平台</button>在社交网络和人们互动。",
|
||||
"domain_pill.who_you_are": "用户名可以表明你的身份和你所在的站点,这样人们就可以通过<button>基于 ActivityPub 的平台</button>在社交网络与你互动。",
|
||||
"domain_pill.your_handle": "你的用户名:",
|
||||
"domain_pill.your_server": "你的数字家园,你的所有嘟文都在此存储。不喜欢这里吗?你可以随时迁移到其它服务器,并带上你的关注者。",
|
||||
"domain_pill.your_server": "你的数字家园,你的全部嘟文都在此存储。不喜欢这里吗?你可以随时迁移到其它服务器,并带上你的关注者。",
|
||||
"domain_pill.your_username": "你在此服务器上的唯一标识。不同服务器上可能存在相同用户名的用户。",
|
||||
"dropdown.empty": "选项",
|
||||
"embed.instructions": "复制下列代码以在你的网站中嵌入此嘟文。",
|
||||
@@ -336,7 +341,7 @@
|
||||
"empty_column.bookmarked_statuses": "你还没有给任何嘟文添加书签。添加书签后的嘟文会显示在这里。",
|
||||
"empty_column.community": "本站时间线还没有内容,写点什么并公开发布,让它活跃起来吧!",
|
||||
"empty_column.direct": "你还未使用过私下提及。当你发出或者收到私下提及时,它将显示在此。",
|
||||
"empty_column.disabled_feed": "此动态已被您的服务器管理员禁用。",
|
||||
"empty_column.disabled_feed": "此动态已被你的服务器管理员禁用。",
|
||||
"empty_column.domain_blocks": "暂且没有被屏蔽的站点。",
|
||||
"empty_column.explore_statuses": "目前没有热门内容,稍后再来看看吧!",
|
||||
"empty_column.favourited_statuses": "你没有喜欢过任何嘟文。喜欢过的嘟文会显示在这里。",
|
||||
@@ -665,9 +670,9 @@
|
||||
"notifications.column_settings.admin.sign_up": "新注册:",
|
||||
"notifications.column_settings.alert": "桌面通知",
|
||||
"notifications.column_settings.favourite": "喜欢:",
|
||||
"notifications.column_settings.filter_bar.advanced": "显示所有类别",
|
||||
"notifications.column_settings.filter_bar.advanced": "显示全部类别",
|
||||
"notifications.column_settings.filter_bar.category": "快速筛选栏",
|
||||
"notifications.column_settings.follow": "新粉丝:",
|
||||
"notifications.column_settings.follow": "新关注者:",
|
||||
"notifications.column_settings.follow_request": "新关注请求:",
|
||||
"notifications.column_settings.group": "分组",
|
||||
"notifications.column_settings.mention": "提及:",
|
||||
@@ -759,6 +764,7 @@
|
||||
"privacy_policy.title": "隐私政策",
|
||||
"quote_error.edit": "编辑嘟文时无法添加引用。",
|
||||
"quote_error.poll": "不允许引用投票嘟文。",
|
||||
"quote_error.private_mentions": "不允许引用私下提及嘟文。",
|
||||
"quote_error.quote": "一次只能引用一条嘟文。",
|
||||
"quote_error.unauthorized": "你没有权限引用此嘟文。",
|
||||
"quote_error.upload": "不允许引用有媒体附件的嘟文。",
|
||||
@@ -811,9 +817,9 @@
|
||||
"report.reasons.spam_description": "恶意链接、虚假互动或重复回复",
|
||||
"report.reasons.violation": "违反服务器规则",
|
||||
"report.reasons.violation_description": "你清楚它违反了特定的规则",
|
||||
"report.rules.subtitle": "选择所有适用选项",
|
||||
"report.rules.subtitle": "选择全部适用选项",
|
||||
"report.rules.title": "违反了哪些规则?",
|
||||
"report.statuses.subtitle": "选择所有适用选项",
|
||||
"report.statuses.subtitle": "选择全部适用选项",
|
||||
"report.statuses.title": "是否有任何嘟文可以支持这一报告?",
|
||||
"report.submit": "提交",
|
||||
"report.target": "举报 {target}",
|
||||
@@ -864,7 +870,7 @@
|
||||
"server_banner.is_one_of_many": "{domain} 是可用于参与联邦宇宙的众多独立 Mastodon 站点之一。",
|
||||
"server_banner.server_stats": "服务器统计数据:",
|
||||
"sign_in_banner.create_account": "创建账号",
|
||||
"sign_in_banner.follow_anyone": "关注联邦宇宙中的任何人,并按时间顺序查看所有内容。没有算法、广告或诱导链接。",
|
||||
"sign_in_banner.follow_anyone": "关注联邦宇宙中的任何人,并按时间顺序查看全部内容。没有算法、广告或诱导链接。",
|
||||
"sign_in_banner.mastodon_is": "Mastodon 是了解最新动态的最佳途径。",
|
||||
"sign_in_banner.sign_in": "登录",
|
||||
"sign_in_banner.sso_redirect": "登录或注册",
|
||||
@@ -961,7 +967,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": "主页",
|
||||
@@ -1012,13 +1018,15 @@
|
||||
"video.volume_down": "音量减小",
|
||||
"video.volume_up": "提高音量",
|
||||
"visibility_modal.button_title": "设置可见性",
|
||||
"visibility_modal.direct_quote_warning.text": "如果你保存当前设置,引用的嘟文将被转换为链接。",
|
||||
"visibility_modal.direct_quote_warning.title": "引用嘟文无法嵌入到私下提及中",
|
||||
"visibility_modal.header": "可见性和互动",
|
||||
"visibility_modal.helper.direct_quoting": "Mastodon上发布的私下提及无法被他人引用。",
|
||||
"visibility_modal.helper.privacy_editing": "嘟文发布后便无法更改可见性。",
|
||||
"visibility_modal.helper.privacy_private_self_quote": "自我引用的私人嘟文无法设置为公开。",
|
||||
"visibility_modal.helper.private_quoting": "Mastodon上发布的仅限关注者可见的嘟文无法被他人引用。",
|
||||
"visibility_modal.helper.unlisted_quoting": "当其他人引用你时,他们的嘟文也会从热门时间线上隐藏。",
|
||||
"visibility_modal.instructions": "控制谁可以和此嘟文互动。你也可以前往<link>偏好设置 > 发布默认值</link>将此设置应用到所有未来发布的嘟文。",
|
||||
"visibility_modal.instructions": "控制谁可以和此嘟文互动。你也可以前往<link>偏好设置 > 发布默认值</link>将此设置应用到全部未来发布的嘟文。",
|
||||
"visibility_modal.privacy_label": "可见性",
|
||||
"visibility_modal.quote_followers": "仅关注者",
|
||||
"visibility_modal.quote_label": "谁可以引用",
|
||||
|
||||
@@ -28,6 +28,7 @@
|
||||
"account.disable_notifications": "當 @{name} 發文時不要再通知我",
|
||||
"account.domain_blocking": "封鎖網域",
|
||||
"account.edit_profile": "修改個人檔案",
|
||||
"account.edit_profile_short": "編輯",
|
||||
"account.enable_notifications": "當 @{name} 發文時通知我",
|
||||
"account.endorse": "在個人檔案中推薦對方",
|
||||
"account.familiar_followers_many": "{name1}、{name2} 及{othersCount, plural, other {你認識的 # 人}}已追蹤",
|
||||
@@ -40,12 +41,18 @@
|
||||
"account.featured_tags.last_status_never": "暫無文章",
|
||||
"account.follow": "關注",
|
||||
"account.follow_back": "追蹤對方",
|
||||
"account.follow_back_short": "追蹤對方",
|
||||
"account.follow_request": "追蹤請求",
|
||||
"account.follow_request_cancel": "取消請求",
|
||||
"account.follow_request_cancel_short": "取消",
|
||||
"account.follow_request_short": "請求",
|
||||
"account.followers": "追蹤者",
|
||||
"account.followers.empty": "尚未有人追蹤這位使用者。",
|
||||
"account.followers_counter": "{count, plural, other {{counter} 個追蹤者}}",
|
||||
"account.followers_you_know_counter": "你認識的 {counter} 人",
|
||||
"account.following": "正在追蹤",
|
||||
"account.follows.empty": "這位使用者尚未追蹤任何人。",
|
||||
"account.follows_you": "正追蹤你",
|
||||
"account.go_to_profile": "前往個人檔案",
|
||||
"account.hide_reblogs": "隱藏 @{name} 的轉推",
|
||||
"account.in_memoriam": "謹此悼念。",
|
||||
@@ -60,10 +67,13 @@
|
||||
"account.mute_notifications_short": "靜音通知",
|
||||
"account.mute_short": "靜音",
|
||||
"account.muted": "靜音",
|
||||
"account.muting": "靜音",
|
||||
"account.mutual": "你們已互相追蹤",
|
||||
"account.no_bio": "未提供描述。",
|
||||
"account.open_original_page": "打開原始頁面",
|
||||
"account.posts": "帖文",
|
||||
"account.posts_with_replies": "帖文與回覆",
|
||||
"account.remove_from_followers": "移除追蹤者{name}",
|
||||
"account.report": "檢舉 @{name}",
|
||||
"account.requested_follow": "{name} 要求追蹤你",
|
||||
"account.share": "分享 @{name} 的個人檔案",
|
||||
@@ -130,8 +140,11 @@
|
||||
"column.direct": "私人提及",
|
||||
"column.directory": "瀏覽個人資料",
|
||||
"column.domain_blocks": "封鎖的服務站",
|
||||
"column.edit_list": "編輯列表",
|
||||
"column.favourites": "最愛",
|
||||
"column.firehose": "即時動態",
|
||||
"column.firehose_local": "本伺服器的即時動態",
|
||||
"column.firehose_singular": "即時動態",
|
||||
"column.follow_requests": "追蹤請求",
|
||||
"column.home": "主頁",
|
||||
"column.lists": "列表",
|
||||
@@ -182,15 +195,28 @@
|
||||
"confirmations.delete_list.confirm": "刪除",
|
||||
"confirmations.delete_list.message": "你確定要永久刪除這列表嗎?",
|
||||
"confirmations.delete_list.title": "刪除列表?",
|
||||
"confirmations.discard_draft.post.title": "要捨棄文章的草稿?",
|
||||
"confirmations.discard_edit_media.confirm": "捨棄",
|
||||
"confirmations.discard_edit_media.message": "您在媒體描述或預覽有尚未儲存的變更。確定要捨棄它們嗎?",
|
||||
"confirmations.follow_to_list.title": "追蹤使用者?",
|
||||
"confirmations.logout.confirm": "登出",
|
||||
"confirmations.logout.message": "確定要登出嗎?",
|
||||
"confirmations.logout.title": "登出?",
|
||||
"confirmations.missing_alt_text.confirm": "新增替代文字",
|
||||
"confirmations.missing_alt_text.message": "你的貼文尚未附上替代文字。新增描述有助更多人存取其內容。",
|
||||
"confirmations.mute.confirm": "靜音",
|
||||
"confirmations.quiet_post_quote_info.dismiss": "不再提醒",
|
||||
"confirmations.quiet_post_quote_info.got_it": "知道了",
|
||||
"confirmations.redraft.confirm": "刪除並編輯",
|
||||
"confirmations.redraft.message": "你確定要移除並重新起草這篇帖文嗎?你將會失去最愛和轉推,而回覆也會與原始帖文斷開連接。",
|
||||
"confirmations.revoke_quote.message": "此操作無法還原。",
|
||||
"confirmations.revoke_quote.title": "移除貼文?",
|
||||
"confirmations.unblock.confirm": "解除封鎖",
|
||||
"confirmations.unblock.title": "解除封鎖 {name}?",
|
||||
"confirmations.unfollow.confirm": "取消追蹤",
|
||||
"confirmations.unfollow.title": "取消追蹤 {name}?",
|
||||
"confirmations.withdraw_request.confirm": "撤回請求",
|
||||
"confirmations.withdraw_request.title": "撤回追蹤{name}的請求?",
|
||||
"content_warning.hide": "隱藏嘟文",
|
||||
"content_warning.show": "仍要顯示",
|
||||
"content_warning.show_more": "顯示更多",
|
||||
@@ -432,6 +458,8 @@
|
||||
"navigation_bar.follows_and_followers": "追蹤及追蹤者",
|
||||
"navigation_bar.import_export": "匯入及匯出",
|
||||
"navigation_bar.lists": "列表",
|
||||
"navigation_bar.live_feed_local": "即時動態(本地)",
|
||||
"navigation_bar.live_feed_public": "即時動態(公開)",
|
||||
"navigation_bar.logout": "登出",
|
||||
"navigation_bar.more": "更多",
|
||||
"navigation_bar.mutes": "靜音名單",
|
||||
|
||||
@@ -247,6 +247,11 @@
|
||||
"confirmations.missing_alt_text.secondary": "仍要發嘟",
|
||||
"confirmations.missing_alt_text.title": "是否新增 ALT 說明文字?",
|
||||
"confirmations.mute.confirm": "靜音",
|
||||
"confirmations.private_quote_notify.cancel": "返回至編輯",
|
||||
"confirmations.private_quote_notify.confirm": "發表嘟文",
|
||||
"confirmations.private_quote_notify.do_not_show_again": "不再顯示此訊息",
|
||||
"confirmations.private_quote_notify.message": "您所引用與提及之使用者將被通知且能檢視您的嘟文,即便他們並無跟隨您。",
|
||||
"confirmations.private_quote_notify.title": "是否和跟隨者與提及使用者分享此內容?",
|
||||
"confirmations.quiet_post_quote_info.dismiss": "不要再提醒我",
|
||||
"confirmations.quiet_post_quote_info.got_it": "了解",
|
||||
"confirmations.quiet_post_quote_info.message": "當引用不於公開時間軸顯示之嘟文時,您的嘟文將自熱門時間軸隱藏。",
|
||||
@@ -605,8 +610,8 @@
|
||||
"notification.annual_report.view": "檢視 #Wrapstodon",
|
||||
"notification.favourite": "{name} 已將您的嘟文加入最愛",
|
||||
"notification.favourite.name_and_others_with_link": "{name} 與<a>{count, plural, other {其他 # 個人}}</a>已將您的嘟文加入最愛",
|
||||
"notification.favourite_pm": "{name} 將您的私人提及加入最愛",
|
||||
"notification.favourite_pm.name_and_others_with_link": "{name} 與<a>{count, plural, other {其他 # 個人}}</a>已將您的私人提及加入最愛",
|
||||
"notification.favourite_pm": "{name} 將您的私訊加入最愛",
|
||||
"notification.favourite_pm.name_and_others_with_link": "{name} 與<a>{count, plural, other {其他 # 個人}}</a>已將您的私訊加入最愛",
|
||||
"notification.follow": "{name} 已跟隨您",
|
||||
"notification.follow.name_and_others": "{name} 與<a>{count, plural, other {其他 # 個人}}</a>已跟隨您",
|
||||
"notification.follow_request": "{name} 要求跟隨您",
|
||||
@@ -759,6 +764,7 @@
|
||||
"privacy_policy.title": "隱私權政策",
|
||||
"quote_error.edit": "編輯嘟文時無法新增引用嘟文。",
|
||||
"quote_error.poll": "無法引用投票嘟文。",
|
||||
"quote_error.private_mentions": "無法引用私訊嘟文。",
|
||||
"quote_error.quote": "一次僅能引用一則嘟文。",
|
||||
"quote_error.unauthorized": "您不被授權允許引用此嘟文。",
|
||||
"quote_error.upload": "無法引用多媒體內容嘟文。",
|
||||
@@ -1012,8 +1018,10 @@
|
||||
"video.volume_down": "降低音量",
|
||||
"video.volume_up": "提高音量",
|
||||
"visibility_modal.button_title": "設定可見性",
|
||||
"visibility_modal.direct_quote_warning.text": "若您儲存目前設定,引用嘟文將被轉為連結。",
|
||||
"visibility_modal.direct_quote_warning.title": "引用嘟文無法被內嵌於私訊中",
|
||||
"visibility_modal.header": "可見性與互動",
|
||||
"visibility_modal.helper.direct_quoting": "Mastodon 上發佈之私人提及嘟文無法被其他使用者引用。",
|
||||
"visibility_modal.helper.direct_quoting": "Mastodon 上發佈之私訊嘟文無法被其他使用者引用。",
|
||||
"visibility_modal.helper.privacy_editing": "嘟文發布後無法變更可見性。",
|
||||
"visibility_modal.helper.privacy_private_self_quote": "自我引用之私嘟無法設為公開可見。",
|
||||
"visibility_modal.helper.private_quoting": "Mastodon 上發佈之僅限跟隨者嘟文無法被其他使用者引用。",
|
||||
|
||||
@@ -1,11 +1,14 @@
|
||||
import { Map as ImmutableMap, List as ImmutableList, OrderedSet as ImmutableOrderedSet, fromJS } from 'immutable';
|
||||
|
||||
import {
|
||||
changeComposeVisibility,
|
||||
changeUploadCompose,
|
||||
quoteCompose,
|
||||
quoteComposeCancel,
|
||||
setComposeQuotePolicy,
|
||||
} from 'mastodon/actions/compose_typed';
|
||||
pasteLinkCompose,
|
||||
cancelPasteLinkCompose,
|
||||
} from '@/mastodon/actions/compose_typed';
|
||||
import { timelineDelete } from 'mastodon/actions/timelines_typed';
|
||||
|
||||
import {
|
||||
@@ -38,7 +41,6 @@ import {
|
||||
COMPOSE_SENSITIVITY_CHANGE,
|
||||
COMPOSE_SPOILERNESS_CHANGE,
|
||||
COMPOSE_SPOILER_TEXT_CHANGE,
|
||||
COMPOSE_VISIBILITY_CHANGE,
|
||||
COMPOSE_LANGUAGE_CHANGE,
|
||||
COMPOSE_COMPOSING_CHANGE,
|
||||
COMPOSE_EMOJI_INSERT,
|
||||
@@ -93,6 +95,7 @@ const initialState = ImmutableMap({
|
||||
quoted_status_id: null,
|
||||
quote_policy: 'public',
|
||||
default_quote_policy: 'public', // Set in hydration.
|
||||
fetching_link: null,
|
||||
});
|
||||
|
||||
const initialPoll = ImmutableMap({
|
||||
@@ -315,7 +318,11 @@ const calculateProgress = (loaded, total) => Math.min(Math.round((loaded / total
|
||||
|
||||
/** @type {import('@reduxjs/toolkit').Reducer<typeof initialState>} */
|
||||
export const composeReducer = (state = initialState, action) => {
|
||||
if (changeUploadCompose.fulfilled.match(action)) {
|
||||
if (changeComposeVisibility.match(action)) {
|
||||
return state
|
||||
.set('privacy', action.payload)
|
||||
.set('idempotencyKey', uuid());
|
||||
} else if (changeUploadCompose.fulfilled.match(action)) {
|
||||
return state
|
||||
.set('is_changing_upload', false)
|
||||
.update('media_attachments', list => list.map(item => {
|
||||
@@ -331,15 +338,27 @@ export const composeReducer = (state = initialState, action) => {
|
||||
return state.set('is_changing_upload', false);
|
||||
} else if (quoteCompose.match(action)) {
|
||||
const status = action.payload;
|
||||
const isDirect = state.get('privacy') === 'direct';
|
||||
return state
|
||||
.set('quoted_status_id', status.get('id'))
|
||||
.set('quoted_status_id', isDirect ? null : status.get('id'))
|
||||
.set('spoiler', status.get('sensitive'))
|
||||
.set('spoiler_text', status.get('spoiler_text'))
|
||||
.update('privacy', (visibility) => ['public', 'unlisted'].includes(visibility) && status.get('visibility') === 'private' ? 'private' : visibility);
|
||||
.update('privacy', (visibility) => {
|
||||
if (['public', 'unlisted'].includes(visibility) && status.get('visibility') === 'private') {
|
||||
return 'private';
|
||||
}
|
||||
return visibility;
|
||||
});
|
||||
} else if (quoteComposeCancel.match(action)) {
|
||||
return state.set('quoted_status_id', null);
|
||||
} else if (setComposeQuotePolicy.match(action)) {
|
||||
return state.set('quote_policy', action.payload);
|
||||
} else if (pasteLinkCompose.pending.match(action)) {
|
||||
return state.set('fetching_link', action.meta.requestId);
|
||||
} else if (pasteLinkCompose.fulfilled.match(action) || pasteLinkCompose.rejected.match(action)) {
|
||||
return action.meta.requestId === state.get('fetching_link') ? state.set('fetching_link', null) : state;
|
||||
} else if (cancelPasteLinkCompose.match(action)) {
|
||||
return state.set('fetching_link', null);
|
||||
}
|
||||
|
||||
switch(action.type) {
|
||||
@@ -383,10 +402,6 @@ export const composeReducer = (state = initialState, action) => {
|
||||
return state
|
||||
.set('spoiler_text', action.text)
|
||||
.set('idempotencyKey', uuid());
|
||||
case COMPOSE_VISIBILITY_CHANGE:
|
||||
return state
|
||||
.set('privacy', action.value)
|
||||
.set('idempotencyKey', uuid());
|
||||
case COMPOSE_CHANGE:
|
||||
return state
|
||||
.set('text', action.text)
|
||||
|
||||
@@ -42,7 +42,7 @@ interface AppThunkConfig {
|
||||
}
|
||||
export type AppThunkApi = Pick<
|
||||
GetThunkAPI<AppThunkConfig>,
|
||||
'getState' | 'dispatch'
|
||||
'getState' | 'dispatch' | 'requestId'
|
||||
>;
|
||||
|
||||
interface AppThunkOptions<Arg> {
|
||||
@@ -60,7 +60,7 @@ type AppThunk<Arg = void, Returned = void> = (
|
||||
|
||||
type AppThunkCreator<Arg = void, Returned = void, ExtraArg = unknown> = (
|
||||
arg: Arg,
|
||||
api: AppThunkApi,
|
||||
api: Pick<AppThunkApi, 'getState' | 'dispatch'>,
|
||||
extra?: ExtraArg,
|
||||
) => Returned;
|
||||
|
||||
@@ -143,10 +143,10 @@ export function createAsyncThunk<Arg = void, Returned = void>(
|
||||
name,
|
||||
async (
|
||||
arg: Arg,
|
||||
{ getState, dispatch, fulfillWithValue, rejectWithValue },
|
||||
{ getState, dispatch, requestId, fulfillWithValue, rejectWithValue },
|
||||
) => {
|
||||
try {
|
||||
const result = await creator(arg, { dispatch, getState });
|
||||
const result = await creator(arg, { dispatch, getState, requestId });
|
||||
|
||||
return fulfillWithValue(result, {
|
||||
useLoadingBar: options.useLoadingBar,
|
||||
@@ -280,10 +280,11 @@ export function createDataLoadingThunk<
|
||||
|
||||
return createAsyncThunk<Args, Returned>(
|
||||
name,
|
||||
async (arg, { getState, dispatch }) => {
|
||||
async (arg, { getState, dispatch, requestId }) => {
|
||||
const data = await loadData(arg, {
|
||||
dispatch,
|
||||
getState,
|
||||
requestId,
|
||||
});
|
||||
|
||||
if (!onData) return data as Returned;
|
||||
@@ -291,6 +292,7 @@ export function createDataLoadingThunk<
|
||||
const result = await onData(data, {
|
||||
dispatch,
|
||||
getState,
|
||||
requestId,
|
||||
discardLoadData: discardLoadDataInPayload,
|
||||
actionArg: arg,
|
||||
});
|
||||
|
||||
1
app/javascript/material-icons/400-24px/audio.svg
Normal file
1
app/javascript/material-icons/400-24px/audio.svg
Normal file
@@ -0,0 +1 @@
|
||||
<svg xmlns="http://www.w3.org/2000/svg" height="24px" viewBox="0 -960 960 960" width="24px" fill="currentColor"><path d="M280-240v-480h80v480h-80ZM440-80v-800h80v800h-80ZM120-400v-160h80v160h-80Zm480 160v-480h80v480h-80Zm160-160v-160h80v160h-80Z"/></svg>
|
||||
|
After Width: | Height: | Size: 254 B |
@@ -1325,6 +1325,10 @@ a.sparkline {
|
||||
line-height: 1;
|
||||
width: 100%;
|
||||
animation: skeleton 1.2s ease-in-out infinite;
|
||||
|
||||
.reduce-motion & {
|
||||
animation: none;
|
||||
}
|
||||
}
|
||||
|
||||
@keyframes skeleton {
|
||||
|
||||
@@ -775,16 +775,43 @@
|
||||
padding: 8px;
|
||||
}
|
||||
|
||||
&__preview {
|
||||
&__preview,
|
||||
&__visualizer {
|
||||
position: absolute;
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
border-radius: 6px;
|
||||
z-index: -1;
|
||||
top: 0;
|
||||
}
|
||||
|
||||
&__preview {
|
||||
border-radius: 6px;
|
||||
inset-inline-start: 0;
|
||||
}
|
||||
|
||||
&__visualizer {
|
||||
padding: 16px;
|
||||
box-sizing: border-box;
|
||||
|
||||
.audio-player__visualizer {
|
||||
margin: 0 auto;
|
||||
display: block;
|
||||
height: 100%;
|
||||
}
|
||||
|
||||
.icon {
|
||||
position: absolute;
|
||||
top: 50%;
|
||||
inset-inline-start: 50%;
|
||||
transform: translate(-50%, -50%);
|
||||
opacity: 0.75;
|
||||
color: var(--player-foreground-color);
|
||||
filter: var(--overlay-icon-shadow);
|
||||
width: 48px;
|
||||
height: 48px;
|
||||
}
|
||||
}
|
||||
|
||||
&__thumbnail {
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
@@ -5743,6 +5770,34 @@ a.status-card {
|
||||
}
|
||||
}
|
||||
|
||||
.visibility-modal {
|
||||
&__quote-warning {
|
||||
color: var(--nested-card-text);
|
||||
background:
|
||||
/* This is a bit of a silly hack for layering two background colours
|
||||
* since --nested-card-background is too transparent for a tooltip */
|
||||
linear-gradient(
|
||||
var(--nested-card-background),
|
||||
var(--nested-card-background)
|
||||
),
|
||||
linear-gradient(var(--background-color), var(--background-color));
|
||||
border: var(--nested-card-border);
|
||||
padding: 16px;
|
||||
border-radius: 4px;
|
||||
|
||||
h3 {
|
||||
font-weight: 500;
|
||||
margin-bottom: 4px;
|
||||
color: $darker-text-color;
|
||||
}
|
||||
|
||||
p {
|
||||
font-size: 0.8em;
|
||||
color: $dark-text-color;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
.visibility-dropdown {
|
||||
&__overlay[data-popper-placement] {
|
||||
z-index: 9999;
|
||||
|
||||
@@ -102,6 +102,7 @@ class Form::AdminSettings
|
||||
DOMAIN_BLOCK_AUDIENCES = %w(disabled users all).freeze
|
||||
REGISTRATION_MODES = %w(open approved none).freeze
|
||||
FEED_ACCESS_MODES = %w(public authenticated disabled).freeze
|
||||
ALTERNATE_FEED_ACCESS_MODES = %w(public authenticated).freeze
|
||||
LANDING_PAGE = %w(trends about local_feed).freeze
|
||||
|
||||
attr_accessor(*KEYS)
|
||||
@@ -114,7 +115,7 @@ class Form::AdminSettings
|
||||
validates :show_domain_blocks_rationale, inclusion: { in: DOMAIN_BLOCK_AUDIENCES }, if: -> { defined?(@show_domain_blocks_rationale) }
|
||||
validates :local_live_feed_access, inclusion: { in: FEED_ACCESS_MODES }, if: -> { defined?(@local_live_feed_access) }
|
||||
validates :remote_live_feed_access, inclusion: { in: FEED_ACCESS_MODES }, if: -> { defined?(@remote_live_feed_access) }
|
||||
validates :local_topic_feed_access, inclusion: { in: FEED_ACCESS_MODES }, if: -> { defined?(@local_topic_feed_access) }
|
||||
validates :local_topic_feed_access, inclusion: { in: ALTERNATE_FEED_ACCESS_MODES }, if: -> { defined?(@local_topic_feed_access) }
|
||||
validates :remote_topic_feed_access, inclusion: { in: FEED_ACCESS_MODES }, if: -> { defined?(@remote_topic_feed_access) }
|
||||
validates :media_cache_retention_period, :content_cache_retention_period, :backups_retention_period, numericality: { only_integer: true }, allow_blank: true, if: -> { defined?(@media_cache_retention_period) || defined?(@content_cache_retention_period) || defined?(@backups_retention_period) }
|
||||
validates :min_age, numericality: { only_integer: true }, allow_blank: true, if: -> { defined?(@min_age) }
|
||||
|
||||
@@ -96,6 +96,7 @@ class PostStatusService < BaseService
|
||||
@status = @account.statuses.new(status_attributes)
|
||||
process_mentions_service.call(@status, save_records: false)
|
||||
safeguard_mentions!(@status)
|
||||
safeguard_private_mention_quote!(@status)
|
||||
attach_quote!(@status)
|
||||
|
||||
antispam = Antispam.new(@status)
|
||||
@@ -108,6 +109,16 @@ class PostStatusService < BaseService
|
||||
end
|
||||
end
|
||||
|
||||
def safeguard_private_mention_quote!(status)
|
||||
return if @quoted_status.nil? || @visibility.to_sym != :direct
|
||||
|
||||
# The mentions array test here is awkward because the relationship is not persisted at this time
|
||||
return if @quoted_status.account_id == @account.id || status.mentions.to_a.any? { |mention| mention.account_id == @quoted_status.account_id && !mention.silent }
|
||||
|
||||
status.errors.add(:base, I18n.t('statuses.errors.quoted_user_not_mentioned'))
|
||||
raise ActiveRecord::RecordInvalid, status
|
||||
end
|
||||
|
||||
def attach_quote!(status)
|
||||
return if @quoted_status.nil?
|
||||
|
||||
@@ -130,6 +141,7 @@ class PostStatusService < BaseService
|
||||
|
||||
def schedule_status!
|
||||
status_for_validation = @account.statuses.build(status_attributes)
|
||||
safeguard_private_mention_quote!(status_for_validation)
|
||||
|
||||
antispam = Antispam.new(status_for_validation)
|
||||
antispam.local_preflight_check!
|
||||
|
||||
@@ -46,7 +46,7 @@
|
||||
.fields-row
|
||||
.fields-row__column.fields-row__column-6.fields-group
|
||||
= f.input :local_topic_feed_access,
|
||||
collection: f.object.class::FEED_ACCESS_MODES,
|
||||
collection: f.object.class::ALTERNATE_FEED_ACCESS_MODES,
|
||||
include_blank: false,
|
||||
label_method: ->(mode) { I18n.t("admin.settings.feed_access.modes.#{mode}") },
|
||||
wrapper: :with_label
|
||||
|
||||
@@ -2,8 +2,7 @@
|
||||
= t('privacy.title')
|
||||
|
||||
- content_for :heading do
|
||||
%h2= t('settings.profile')
|
||||
= render partial: 'settings/shared/profile_navigation'
|
||||
%h2= t('privacy.title')
|
||||
|
||||
= simple_form_for @account, url: settings_privacy_path do |f|
|
||||
= render 'shared/error_messages', object: @account
|
||||
|
||||
@@ -2,6 +2,5 @@
|
||||
= render_navigation renderer: :links do |primary|
|
||||
:ruby
|
||||
primary.item :edit_profile, safe_join([material_symbol('person'), t('settings.edit_profile')]), settings_profile_path
|
||||
primary.item :privacy_reach, safe_join([material_symbol('lock'), t('privacy.title')]), settings_privacy_path
|
||||
primary.item :verification, safe_join([material_symbol('check'), t('verification.verification')]), settings_verification_path
|
||||
primary.item :featured_tags, safe_join([material_symbol('tag'), t('settings.featured_tags')]), settings_featured_tags_path
|
||||
|
||||
@@ -5,7 +5,7 @@ class ActivityPub::RefetchAndVerifyQuoteWorker
|
||||
include ExponentialBackoff
|
||||
include JsonLdHelper
|
||||
|
||||
sidekiq_options queue: 'pull', retry: 3
|
||||
sidekiq_options queue: 'pull', retry: 5
|
||||
|
||||
def perform(quote_id, quoted_uri, options = {})
|
||||
quote = Quote.find(quote_id)
|
||||
|
||||
@@ -2015,6 +2015,7 @@ be:
|
||||
errors:
|
||||
in_reply_not_found: Здаецца, допіс, на які вы спрабуеце адказаць, не існуе.
|
||||
quoted_status_not_found: Выглядае, што допісу, які Вы спрабуеце цытаваць, не існуе.
|
||||
quoted_user_not_mentioned: Немагчыма цытаваць незгаданага карыстальніка ў допісе прыватнага згадвання.
|
||||
over_character_limit: перавышаная колькасць сімвалаў у %{max}
|
||||
pin_errors:
|
||||
direct: Допісы, бачныя толькі згаданым карыстальнікам, нельга замацаваць
|
||||
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user