Merge tag 'v4.2.1' into chinwag-4.2

This commit is contained in:
Mike Barnes 2023-10-16 13:17:53 +11:00
commit 3d68228417
142 changed files with 2265 additions and 1664 deletions

View file

@ -289,10 +289,6 @@ RSpec/MultipleMemoizedHelpers:
RSpec/NestedGroups:
Max: 6
RSpec/PendingWithoutReason:
Exclude:
- 'spec/models/account_spec.rb'
# This cop supports unsafe autocorrection (--autocorrect-all).
Rails/ApplicationController:
Exclude:

View file

@ -2,6 +2,46 @@
All notable changes to this project will be documented in this file.
## [4.2.1] - 2023-10-10
### Added
- Add redirection on `/deck` URLs for logged-out users ([ClearlyClaire](https://github.com/mastodon/mastodon/pull/27128))
- Add support for v4.2.0 migrations to `tootctl maintenance fix-duplicates` ([ClearlyClaire](https://github.com/mastodon/mastodon/pull/27147))
### Changed
- Change some worker lock TTLs to be shorter-lived ([ClearlyClaire](https://github.com/mastodon/mastodon/pull/27246))
- Change user archive export allowed period from 7 days to 6 days ([suddjian](https://github.com/mastodon/mastodon/pull/27200))
### Fixed
- Fix duplicate reports being sent when reporting some remote posts ([ClearlyClaire](https://github.com/mastodon/mastodon/pull/27355))
- Fix clicking on already-opened thread post scrolling to the top of the thread ([ClearlyClaire](https://github.com/mastodon/mastodon/pull/27331), [ClearlyClaire](https://github.com/mastodon/mastodon/pull/27338), [ClearlyClaire](https://github.com/mastodon/mastodon/pull/27350))
- Fix some remote posts getting truncated ([ClearlyClaire](https://github.com/mastodon/mastodon/pull/27307))
- Fix some cases of infinite scroll code trying to fetch inaccessible posts in a loop ([ClearlyClaire](https://github.com/mastodon/mastodon/pull/27286))
- Fix `Vary` headers not being set on some redirects ([ClearlyClaire](https://github.com/mastodon/mastodon/pull/27272))
- Fix mentions being matched in some URL query strings ([mjankowski](https://github.com/mastodon/mastodon/pull/25656))
- Fix unexpected linebreak in version string in the Web UI ([vmstan](https://github.com/mastodon/mastodon/pull/26986))
- Fix double scroll bars in some columns in advanced interface ([ClearlyClaire](https://github.com/mastodon/mastodon/pull/27187))
- Fix boosts of local users being filtered in account timelines ([ClearlyClaire](https://github.com/mastodon/mastodon/pull/27204))
- Fix multiple instances of the trend refresh scheduler sometimes running at once ([ClearlyClaire](https://github.com/mastodon/mastodon/pull/27253))
- Fix importer returning negative row estimates ([jgillich](https://github.com/mastodon/mastodon/pull/27258))
- Fix incorrectly keeping outdated update notices absent from the API endpoint ([ClearlyClaire](https://github.com/mastodon/mastodon/pull/27021))
- Fix import progress not updating on certain failures ([ClearlyClaire](https://github.com/mastodon/mastodon/pull/27247))
- Fix websocket connections being incorrectly decremented twice on errors ([ThisIsMissEm](https://github.com/mastodon/mastodon/pull/27238))
- Fix explore prompt appearing because of posts being received out of order ([ClearlyClaire](https://github.com/mastodon/mastodon/pull/27211))
- Fix explore prompt sometimes showing up when the home TL is loading ([ClearlyClaire](https://github.com/mastodon/mastodon/pull/27062))
- Fix link handling of mentions in user profiles when logged out ([ClearlyClaire](https://github.com/mastodon/mastodon/pull/27185))
- Fix filtering audit log for entries about disabling 2FA ([ClearlyClaire](https://github.com/mastodon/mastodon/pull/27186))
- Fix notification toasts not respecting reduce-motion ([c960657](https://github.com/mastodon/mastodon/pull/27178))
- Fix retention dashboard not displaying correct month ([vmstan](https://github.com/mastodon/mastodon/pull/27180))
- Fix tIME chunk not being properly removed from PNG uploads ([TheEssem](https://github.com/mastodon/mastodon/pull/27111))
- Fix division by zero in video in bitrate computation code ([ClearlyClaire](https://github.com/mastodon/mastodon/pull/27129))
- Fix inefficient queries in “Follows and followers” as well as several admin pages ([ClearlyClaire](https://github.com/mastodon/mastodon/pull/27116), [ClearlyClaire](https://github.com/mastodon/mastodon/pull/27306))
- Fix ActiveRecord using two connection pools when no replica is defined ([ClearlyClaire](https://github.com/mastodon/mastodon/pull/27061))
- Fix the search documentation URL in system checks ([renchap](https://github.com/mastodon/mastodon/pull/27036))
## [4.2.0] - 2023-09-21
The following changelog entries focus on changes visible to users, administrators, client developers or federated software developers, but there has also been a lot of code modernization, refactoring, and tooling work, in particular by [@danielmbrasil](https://github.com/danielmbrasil), [@mjankowski](https://github.com/mjankowski), [@nschonni](https://github.com/nschonni), [@renchap](https://github.com/renchap), and [@takayamaki](https://github.com/takayamaki).

View file

@ -691,7 +691,7 @@ GEM
rubyzip (>= 1.2.2, < 3.0)
websocket (~> 1.0)
semantic_range (3.0.0)
sidekiq (6.5.9)
sidekiq (6.5.10)
connection_pool (>= 2.2.5, < 3)
rack (~> 2.0)
redis (>= 4.5.0, < 5)

View file

@ -15,6 +15,7 @@ A "vulnerability in Mastodon" is a vulnerability in the code distributed through
| Version | Supported |
| ------- | ---------------- |
| 4.2.x | Yes |
| 4.1.x | Yes |
| 4.0.x | Until 2023-10-31 |
| 3.5.x | Until 2023-12-31 |

View file

@ -4,10 +4,10 @@ module WebAppControllerConcern
extend ActiveSupport::Concern
included do
prepend_before_action :redirect_unauthenticated_to_permalinks!
before_action :set_app_body_class
vary_by 'Accept, Accept-Language, Cookie'
before_action :redirect_unauthenticated_to_permalinks!
before_action :set_app_body_class
end
def skip_csrf_meta_tags?
@ -22,7 +22,9 @@ module WebAppControllerConcern
return if user_signed_in? && current_account.moved_to_account_id.nil?
redirect_path = PermalinkRedirector.new(request.path).redirect_path
return if redirect_path.blank?
redirect_to(redirect_path) if redirect_path.present?
expires_in(15.seconds, public: true, stale_while_revalidate: 30.seconds, stale_if_error: 1.day) unless user_signed_in?
redirect_to(redirect_path)
end
end

View file

@ -3,7 +3,6 @@
class FollowerAccountsController < ApplicationController
include AccountControllerConcern
include SignatureVerification
include WebAppControllerConcern
vary_by -> { public_fetch_mode? ? 'Accept, Accept-Language, Cookie' : 'Accept, Accept-Language, Cookie, Signature' }

View file

@ -3,7 +3,6 @@
class FollowingAccountsController < ApplicationController
include AccountControllerConcern
include SignatureVerification
include WebAppControllerConcern
vary_by -> { public_fetch_mode? ? 'Accept, Accept-Language, Cookie' : 'Accept, Accept-Language, Cookie, Signature' }

View file

@ -1,11 +1,24 @@
# frozen_string_literal: true
module DatabaseHelper
def replica_enabled?
ENV['REPLICA_DB_NAME'] || ENV.fetch('REPLICA_DATABASE_URL', nil)
end
module_function :replica_enabled?
def with_read_replica(&block)
ApplicationRecord.connected_to(role: :reading, prevent_writes: true, &block)
if replica_enabled?
ApplicationRecord.connected_to(role: :reading, prevent_writes: true, &block)
else
yield
end
end
def with_primary(&block)
ApplicationRecord.connected_to(role: :writing, &block)
if replica_enabled?
ApplicationRecord.connected_to(role: :writing, &block)
else
yield
end
end
end

View file

@ -147,6 +147,10 @@ export const openURL = (value, history, onFailure) => (dispatch, getState) => {
const signedIn = !!getState().getIn(['meta', 'me']);
if (!signedIn) {
if (onFailure) {
onFailure();
}
return;
}

View file

@ -45,6 +45,21 @@ describe('computeHashtagBarForStatus', () => {
);
});
it('does not truncate the contents when the last child is a text node', () => {
const status = createStatus(
'this is a #<a class="zrl" href="https://example.com/search?tag=test">test</a>. Some more text',
['test'],
);
const { hashtagsInBar, statusContentProps } =
computeHashtagBarForStatus(status);
expect(hashtagsInBar).toEqual([]);
expect(statusContentProps.statusContent).toMatchInlineSnapshot(
`"this is a #<a class="zrl" href="https://example.com/search?tag=test">test</a>. Some more text"`,
);
});
it('extract tags from the last line', () => {
const status = createStatus(
'<p>Simple text</p><p><a href="test">#hashtag</a></p>',

View file

@ -9,11 +9,12 @@ import api from 'mastodon/api';
import { roundTo10 } from 'mastodon/utils/numbers';
const dateForCohort = cohort => {
const timeZone = 'UTC';
switch(cohort.frequency) {
case 'day':
return <FormattedDate value={cohort.period} month='long' day='2-digit' />;
return <FormattedDate value={cohort.period} month='long' day='2-digit' timeZone={timeZone} />;
default:
return <FormattedDate value={cohort.period} month='long' year='numeric' />;
return <FormattedDate value={cohort.period} month='long' year='numeric' timeZone={timeZone} />;
}
};

View file

@ -22,12 +22,6 @@ export default class Column extends PureComponent {
scrollable = document.scrollingElement;
} else {
scrollable = this.node.querySelector('.scrollable');
// Some columns have nested `.scrollable` containers, with the outer one
// being a wrapper while the actual scrollable content is deeper.
if (scrollable.classList.contains('scrollable--flex')) {
scrollable = scrollable?.querySelector('.scrollable') || scrollable;
}
}
if (!scrollable) {

View file

@ -109,7 +109,7 @@ export function computeHashtagBarForStatus(status: StatusLike): {
const lastChild = template.content.lastChild;
if (!lastChild) return defaultResult;
if (!lastChild || lastChild.nodeType === Node.TEXT_NODE) return defaultResult;
template.content.removeChild(lastChild);
const contentWithoutLastLine = template;

View file

@ -73,7 +73,7 @@ class ScrollableList extends PureComponent {
const clientHeight = this.getClientHeight();
const offset = scrollHeight - scrollTop - clientHeight;
if (400 > offset && this.props.onLoadMore && this.props.hasMore && !this.props.isLoading) {
if (scrollTop > 0 && offset < 400 && this.props.onLoadMore && this.props.hasMore && !this.props.isLoading) {
this.props.onLoadMore();
}

View file

@ -67,47 +67,45 @@ class Explore extends PureComponent {
<Search />
</div>
<div className='scrollable scrollable--flex' data-nosnippet>
{isSearching ? (
<SearchResults />
) : (
<>
<div className='account__section-headline'>
<NavLink exact to='/explore'>
<FormattedMessage tagName='div' id='explore.trending_statuses' defaultMessage='Posts' />
{isSearching ? (
<SearchResults />
) : (
<>
<div className='account__section-headline'>
<NavLink exact to='/explore'>
<FormattedMessage tagName='div' id='explore.trending_statuses' defaultMessage='Posts' />
</NavLink>
<NavLink exact to='/explore/tags'>
<FormattedMessage tagName='div' id='explore.trending_tags' defaultMessage='Hashtags' />
</NavLink>
{signedIn && (
<NavLink exact to='/explore/suggestions'>
<FormattedMessage tagName='div' id='explore.suggested_follows' defaultMessage='People' />
</NavLink>
)}
<NavLink exact to='/explore/tags'>
<FormattedMessage tagName='div' id='explore.trending_tags' defaultMessage='Hashtags' />
</NavLink>
<NavLink exact to='/explore/links'>
<FormattedMessage tagName='div' id='explore.trending_links' defaultMessage='News' />
</NavLink>
</div>
{signedIn && (
<NavLink exact to='/explore/suggestions'>
<FormattedMessage tagName='div' id='explore.suggested_follows' defaultMessage='People' />
</NavLink>
)}
<Switch>
<Route path='/explore/tags' component={Tags} />
<Route path='/explore/links' component={Links} />
<Route path='/explore/suggestions' component={Suggestions} />
<Route exact path={['/explore', '/explore/posts', '/search']}>
<Statuses multiColumn={multiColumn} />
</Route>
</Switch>
<NavLink exact to='/explore/links'>
<FormattedMessage tagName='div' id='explore.trending_links' defaultMessage='News' />
</NavLink>
</div>
<Switch>
<Route path='/explore/tags' component={Tags} />
<Route path='/explore/links' component={Links} />
<Route path='/explore/suggestions' component={Suggestions} />
<Route exact path={['/explore', '/explore/posts', '/search']}>
<Statuses multiColumn={multiColumn} />
</Route>
</Switch>
<Helmet>
<title>{intl.formatMessage(messages.title)}</title>
<meta name='robots' content={isSearching ? 'noindex' : 'all'} />
</Helmet>
</>
)}
</div>
<Helmet>
<title>{intl.formatMessage(messages.title)}</title>
<meta name='robots' content={isSearching ? 'noindex' : 'all'} />
</Helmet>
</>
)}
</Column>
);
}

View file

@ -52,7 +52,7 @@ class Links extends PureComponent {
}
return (
<div className='explore__links'>
<div className='explore__links scrollable' data-nosnippet>
{banner}
{isLoading ? (<LoadingIndicator />) : links.map((link, i) => (

View file

@ -204,7 +204,7 @@ class Results extends PureComponent {
<button onClick={this.handleSelectStatuses} className={type === 'statuses' ? 'active' : undefined}><FormattedMessage id='search_results.statuses' defaultMessage='Posts' /></button>
</div>
<div className='explore__search-results'>
<div className='explore__search-results' data-nosnippet>
<ScrollableList
scrollKey='search-results'
isLoading={isLoading}

View file

@ -42,7 +42,7 @@ class Suggestions extends PureComponent {
}
return (
<div className='explore__suggestions'>
<div className='explore__suggestions scrollable' data-nosnippet>
{isLoading ? <LoadingIndicator /> : suggestions.map(suggestion => (
<AccountCard key={suggestion.get('account')} id={suggestion.get('account')} />
))}

View file

@ -51,7 +51,7 @@ class Tags extends PureComponent {
}
return (
<div className='explore__links'>
<div className='scrollable explore__links' data-nosnippet>
{banner}
{isLoading ? (<LoadingIndicator />) : hashtags.map(hashtag => (

View file

@ -169,32 +169,30 @@ const Firehose = ({ feedType, multiColumn }) => {
<ColumnSettings />
</ColumnHeader>
<div className='scrollable scrollable--flex'>
<div className='account__section-headline'>
<NavLink exact to='/public/local'>
<FormattedMessage tagName='div' id='firehose.local' defaultMessage='This server' />
</NavLink>
<div className='account__section-headline'>
<NavLink exact to='/public/local'>
<FormattedMessage tagName='div' id='firehose.local' defaultMessage='This server' />
</NavLink>
<NavLink exact to='/public/remote'>
<FormattedMessage tagName='div' id='firehose.remote' defaultMessage='Other servers' />
</NavLink>
<NavLink exact to='/public/remote'>
<FormattedMessage tagName='div' id='firehose.remote' defaultMessage='Other servers' />
</NavLink>
<NavLink exact to='/public'>
<FormattedMessage tagName='div' id='firehose.all' defaultMessage='All' />
</NavLink>
</div>
<StatusListContainer
prepend={prependBanner}
timelineId={`${feedType}${onlyMedia ? ':media' : ''}`}
onLoadMore={handleLoadMore}
trackScroll
scrollKey='firehose'
emptyMessage={emptyMessage}
bindToDocument={!multiColumn}
/>
<NavLink exact to='/public'>
<FormattedMessage tagName='div' id='firehose.all' defaultMessage='All' />
</NavLink>
</div>
<StatusListContainer
prepend={prependBanner}
timelineId={`${feedType}${onlyMedia ? ':media' : ''}`}
onLoadMore={handleLoadMore}
trackScroll
scrollKey='firehose'
emptyMessage={emptyMessage}
bindToDocument={!multiColumn}
/>
<Helmet>
<title>{intl.formatMessage(messages.title)}</title>
<meta name='robots' content='noindex' />

View file

@ -39,8 +39,17 @@ const getHomeFeedSpeed = createSelector([
], (statusIds, pendingStatusIds, statusMap) => {
const recentStatusIds = pendingStatusIds.size > 0 ? pendingStatusIds : statusIds;
const statuses = recentStatusIds.filter(id => id !== null).map(id => statusMap.get(id)).filter(status => status?.get('account') !== me).take(20);
const oldest = new Date(statuses.getIn([statuses.size - 1, 'created_at'], 0));
const newest = new Date(statuses.getIn([0, 'created_at'], 0));
if (statuses.isEmpty()) {
return {
gap: 0,
newest: new Date(0),
};
}
const datetimes = statuses.map(status => status.get('created_at', 0));
const oldest = new Date(datetimes.min());
const newest = new Date(datetimes.max());
const averageGap = (newest - oldest) / (1000 * (statuses.size + 1)); // Average gap between posts on first page in seconds
return {
@ -55,8 +64,10 @@ const homeTooSlow = createSelector([
getHomeFeedSpeed,
], (isLoading, isPartial, speed) =>
!isLoading && !isPartial // Only if the home feed has finished loading
&& (speed.gap > (30 * 60) // If the average gap between posts is more than 20 minutes
|| (Date.now() - speed.newest) > (1000 * 3600)) // If the most recent post is from over an hour ago
&& (
(speed.gap > (30 * 60) // If the average gap between posts is more than 30 minutes
|| (Date.now() - speed.newest) > (1000 * 3600)) // If the most recent post is from over an hour ago
)
);
const mapStateToProps = state => ({

View file

@ -220,6 +220,8 @@ class Status extends ImmutablePureComponent {
componentDidMount () {
attachFullscreenListener(this.onFullScreenChange);
this._scrollStatusIntoView();
}
UNSAFE_componentWillReceiveProps (nextProps) {
@ -579,10 +581,10 @@ class Status extends ImmutablePureComponent {
this.node = c;
};
componentDidUpdate (prevProps) {
const { status, ancestorsIds, multiColumn } = this.props;
_scrollStatusIntoView () {
const { status, multiColumn } = this.props;
if (status && (ancestorsIds.size > prevProps.ancestorsIds.size || prevProps.status?.get('id') !== status.get('id'))) {
if (status) {
window.requestAnimationFrame(() => {
this.node?.querySelector('.detailed-status__wrapper')?.scrollIntoView(true);
@ -599,6 +601,14 @@ class Status extends ImmutablePureComponent {
}
}
componentDidUpdate (prevProps) {
const { status, ancestorsIds } = this.props;
if (status && (ancestorsIds.size > prevProps.ancestorsIds.size || prevProps.status?.get('id') !== status.get('id'))) {
this._scrollStatusIntoView();
}
}
componentWillUnmount () {
detachFullscreenListener(this.onFullScreenChange);
}
@ -607,6 +617,22 @@ class Status extends ImmutablePureComponent {
this.setState({ fullscreen: isFullscreen() });
};
shouldUpdateScroll = (prevRouterProps, { location }) => {
// Do not change scroll when opening a modal
if (location.state?.mastodonModalKey !== prevRouterProps?.location?.state?.mastodonModalKey) {
return false;
}
// Scroll to focused post if it is loaded
const child = this.node?.querySelector('.detailed-status__wrapper');
if (child) {
return [0, child.offsetTop];
}
// Do not scroll otherwise, `componentDidUpdate` will take care of that
return false;
};
render () {
let ancestors, descendants;
const { isLoading, status, ancestorsIds, descendantsIds, intl, domain, multiColumn, pictureInPicture } = this.props;
@ -660,7 +686,7 @@ class Status extends ImmutablePureComponent {
)}
/>
<ScrollContainer scrollKey='thread'>
<ScrollContainer scrollKey='thread' shouldUpdateScroll={this.shouldUpdateScroll}>
<div className={classNames('scrollable', { fullscreen })} ref={this.setRef}>
{ancestors}

View file

@ -100,7 +100,7 @@ class LinkFooter extends PureComponent {
{DividingCircle}
<a href={source_url} rel='noopener noreferrer' target='_blank'><FormattedMessage id='footer.source_code' defaultMessage='View source code' /></a>
{DividingCircle}
v{version}
<span class='version'>v{version}</span>
</p>
</div>
);

View file

@ -26,7 +26,7 @@
"account.domain_blocked": "Блокиран домейн",
"account.edit_profile": "Редактиране на профила",
"account.enable_notifications": "Известяване при публикуване от @{name}",
"account.endorse": "Характеристика на профила",
"account.endorse": "Представи в профила",
"account.featured_tags.last_status_at": "Последна публикация на {date}",
"account.featured_tags.last_status_never": "Няма публикации",
"account.featured_tags.title": "Главни хаштагове на {name}",
@ -393,7 +393,7 @@
"media_gallery.toggle_visible": "Скриване на {number, plural, one {изображение} other {изображения}}",
"moved_to_account_banner.text": "Вашият акаунт {disabledAccount} сега е изключен, защото се преместихте в {movedToAccount}.",
"mute_modal.duration": "Времетраене",
"mute_modal.hide_notifications": "Скривате ли известията от потребителя?",
"mute_modal.hide_notifications": "Скриване на известия от този потребител?",
"mute_modal.indefinite": "Неопределено",
"navigation_bar.about": "Относно",
"navigation_bar.advanced_interface": "Отваряне в разширен уебинтерфейс",

View file

@ -190,6 +190,7 @@
"conversation.open": "কথপোকথন দেখান",
"conversation.with": "{names} এর সঙ্গে",
"copypaste.copied": "অনুলিপিকৃত",
"copypaste.copy_to_clipboard": "ক্লিপবোর্ডে কপি করুন",
"directory.federated": "পরিচিত ফেডিভারসের থেকে",
"directory.local": "শুধু {domain} থেকে",
"directory.new_arrivals": "নতুন আগত",

View file

@ -321,7 +321,7 @@
"interaction_modal.login.action": "Torna a l'inici",
"interaction_modal.login.prompt": "Domini del teu servidor domèstic, p.ex. mastodon.social",
"interaction_modal.no_account_yet": "No a Mastodon?",
"interaction_modal.on_another_server": "En un servidor diferent",
"interaction_modal.on_another_server": "A un altre servidor",
"interaction_modal.on_this_server": "En aquest servidor",
"interaction_modal.sign_in": "No has iniciat sessió en aquest servidor. On tens el teu compte?",
"interaction_modal.sign_in_hint": "Ajuda: Aquesta és la web on vas registrar-te. Si no ho recordes, mira el correu electrònic de benvinguda en la teva safata d'entrada. També pots introduïr el teu nom d'usuari complet! (per ex. @Mastodon@mastodon.social)",
@ -391,7 +391,7 @@
"load_pending": "{count, plural, one {# element nou} other {# elements nous}}",
"loading_indicator.label": "Es carrega...",
"media_gallery.toggle_visible": "{number, plural, one {Amaga la imatge} other {Amaga les imatges}}",
"moved_to_account_banner.text": "El teu compte {disabledAccount} està actualment desactivat perquè l'has traslladat a {movedToAccount}.",
"moved_to_account_banner.text": "El teu compte {disabledAccount} està desactivat perquè l'has mogut a {movedToAccount}.",
"mute_modal.duration": "Durada",
"mute_modal.hide_notifications": "Amagar les notificacions d'aquest usuari?",
"mute_modal.indefinite": "Indefinit",
@ -426,8 +426,8 @@
"notification.admin.sign_up": "{name} s'ha registrat",
"notification.favourite": "{name} ha afavorit el teu tut",
"notification.follow": "{name} et segueix",
"notification.follow_request": "{name} ha sol·licitat seguir-te",
"notification.mention": "{name} t'ha mencionat",
"notification.follow_request": "{name} ha sol·licitat de seguir-te",
"notification.mention": "{name} t'ha esmentat",
"notification.own_poll": "La teva enquesta ha finalitzat",
"notification.poll": "Ha finalitzat una enquesta en què has votat",
"notification.reblog": "{name} t'ha impulsat",
@ -451,7 +451,7 @@
"notifications.column_settings.show": "Mostra a la columna",
"notifications.column_settings.sound": "Reprodueix so",
"notifications.column_settings.status": "Nous tuts:",
"notifications.column_settings.unread_notifications.category": "Notificacions no llegides",
"notifications.column_settings.unread_notifications.category": "Notificacions pendents de llegir",
"notifications.column_settings.unread_notifications.highlight": "Destaca les notificacions no llegides",
"notifications.column_settings.update": "Edicions:",
"notifications.filter.all": "Totes",
@ -473,25 +473,25 @@
"onboarding.action.back": "Porta'm enrere",
"onboarding.actions.back": "Porta'm enrere",
"onboarding.actions.go_to_explore": "Mira què és tendència",
"onboarding.actions.go_to_home": "Vés a la teva línia de temps inici",
"onboarding.actions.go_to_home": "Ves a la teva línia de temps",
"onboarding.compose.template": "Hola Mastodon!",
"onboarding.follows.empty": "Malauradament, cap resultat pot ser mostrat ara mateix. Pots provar de fer servir la cerca o visitar la pàgina Explora per a trobar gent a qui seguir o provar-ho de nou més tard.",
"onboarding.follows.lead": "Tu tens cura de la teva línia de temps inici. Com més gent segueixis, més activa i interessant serà. Aquests perfils poden ser un bon punt d'inici—sempre pots acabar deixant-los de seguir!",
"onboarding.follows.title": "Popular a Mastodon",
"onboarding.follows.lead": "La teva línia de temps inici només està a les teves mans. Com més gent segueixis, més activa i interessant serà. Aquests perfils poden ser un bon punt d'inici—sempre pots acabar deixant de seguir-los!:",
"onboarding.follows.title": "Personalitza la pantalla d'inci",
"onboarding.share.lead": "Permet que la gent sàpiga com trobar-te a Mastodon!",
"onboarding.share.message": "Sóc {username} a #Mastodon! Vine i segueix-me a {url}",
"onboarding.share.next_steps": "Possibles passes següents:",
"onboarding.share.title": "Comparteix el teu perfil",
"onboarding.start.lead": "El teu nou compte a Mastodon ja està preparat. Aquí tens com en pots treure tot el suc:",
"onboarding.start.lead": "El teu nou compte ja està preparat a Mastodon, la xarxa social on tu—no un algorisme—té tot el control. Aquí tens com en pots treure tot el suc:",
"onboarding.start.skip": "Vols saltar-te tota la resta?",
"onboarding.start.title": "Llestos!",
"onboarding.steps.follow_people.body": "Tu tens cura de la teva línia de temps. Omple-la de gent interessant.",
"onboarding.steps.follow_people.title": "{count, plural, zero {No segueixes cap persona} one {Segeueixes ona persona} other {Segueixes # persones}}",
"onboarding.steps.publish_status.body": "Saluda el món.",
"onboarding.steps.follow_people.body": "Mastodon va de seguir a gent interessant.",
"onboarding.steps.follow_people.title": "Personalitza la pantalla d'inci",
"onboarding.steps.publish_status.body": "Saluda al món amb text, fotos, vídeos o enquestes {emoji}",
"onboarding.steps.publish_status.title": "Fes el teu primer tut",
"onboarding.steps.setup_profile.body": "És més fàcil que altres interaccionin amb tu si tens un perfil complet.",
"onboarding.steps.setup_profile.body": "És més fàcil que altres interactuïn amb tu si tens un perfil complet.",
"onboarding.steps.setup_profile.title": "Personalitza el perfil",
"onboarding.steps.share_profile.body": "Permet als teus amics de saber com trobar-te a Mastodon!",
"onboarding.steps.share_profile.body": "Fer saber als teus amics com trobar-te a Mastodon",
"onboarding.steps.share_profile.title": "Comparteix el teu perfil",
"onboarding.tips.2fa": "<strong>Ho sabies?</strong> Pots securitzar el teu compte activant l'autenticació de doble factor en la configuració del teu perfil. Funciona amb qualsevol aplicació TOTP de la teva elecció, no cal número de telèfon!",
"onboarding.tips.accounts_from_other_servers": "<strong>Ho sabies?</strong> Com Mastodon és descentralitzat, et pots trobar amb perfils que són a servidors diferents del teu. I, tanmateix, també hi pots interactuar sense cap problema! El servidor és la segona part del seu nom d'usuari!",

View file

@ -114,7 +114,7 @@
"column.directory": "Prozkoumat profily",
"column.domain_blocks": "Blokované domény",
"column.favourites": "Oblíbené",
"column.firehose": "Živé kanály l",
"column.firehose": "Živé kanály",
"column.follow_requests": "Žádosti o sledování",
"column.home": "Domů",
"column.lists": "Seznamy",
@ -585,6 +585,7 @@
"search.quick_action.open_url": "Otevřít URL v Mastodonu",
"search.quick_action.status_search": "Příspěvky odpovídající {x}",
"search.search_or_paste": "Hledat nebo vložit URL",
"search_popout.full_text_search_disabled_message": "Nedostupné na {domain}.",
"search_popout.language_code": "Kód jazyka podle ISO",
"search_popout.options": "Možnosti hledání",
"search_popout.quick_actions": "Rychlé akce",

View file

@ -143,7 +143,7 @@
"compose_form.hashtag_warning": "Dieser Beitrag wird unter keinem Hashtag sichtbar sein, weil er nicht öffentlich ist. Nur öffentliche Beiträge können nach Hashtags durchsucht werden.",
"compose_form.lock_disclaimer": "Dein Profil ist nicht {locked}. Andere können dir folgen und deine Beiträge sehen, die nur für Follower bestimmt sind.",
"compose_form.lock_disclaimer.lock": "geschützt",
"compose_form.placeholder": "Was gibt's Neues?",
"compose_form.placeholder": "Was gibts Neues?",
"compose_form.poll.add_option": "Auswahl",
"compose_form.poll.duration": "Umfragedauer",
"compose_form.poll.option_placeholder": "{number}. Auswahl",
@ -286,7 +286,7 @@
"footer.source_code": "Quellcode anzeigen",
"footer.status": "Status",
"generic.saved": "Gespeichert",
"getting_started.heading": "Auf geht's!",
"getting_started.heading": "Auf gehts!",
"hashtag.column_header.tag_mode.all": "und {additional}",
"hashtag.column_header.tag_mode.any": "oder {additional}",
"hashtag.column_header.tag_mode.none": "ohne {additional}",
@ -360,7 +360,7 @@
"keyboard_shortcuts.requests": "Liste der Follower-Anfragen aufrufen",
"keyboard_shortcuts.search": "Suchleiste fokussieren",
"keyboard_shortcuts.spoilers": "Feld für Inhaltswarnung anzeigen/ausblenden",
"keyboard_shortcuts.start": "„Auf geht's!“ öffnen",
"keyboard_shortcuts.start": "„Auf gehts!“ öffnen",
"keyboard_shortcuts.toggle_hidden": "Beitragstext hinter der Inhaltswarnung anzeigen/ausblenden",
"keyboard_shortcuts.toggle_sensitivity": "Medien anzeigen/ausblenden",
"keyboard_shortcuts.toot": "Neuen Beitrag erstellen",
@ -383,7 +383,7 @@
"lists.new.create": "Neue Liste erstellen",
"lists.new.title_placeholder": "Titel der neuen Liste",
"lists.replies_policy.followed": "Alle folgenden Profile",
"lists.replies_policy.list": "Mitglieder*innen der Liste",
"lists.replies_policy.list": "Mitglieder der Liste",
"lists.replies_policy.none": "Niemanden",
"lists.replies_policy.title": "Antworten anzeigen für:",
"lists.search": "Suche nach Leuten, denen du folgst",

View file

@ -590,6 +590,7 @@
"search.quick_action.open_url": "Open URL in Mastodon",
"search.quick_action.status_search": "Posts matching {x}",
"search.search_or_paste": "Search or paste URL",
"search_popout.full_text_search_disabled_message": "Unavailable on {domain}.",
"search_popout.language_code": "ISO language code",
"search_popout.options": "Search options",
"search_popout.quick_actions": "Quick actions",

View file

@ -113,6 +113,7 @@
"column.direct": "Privataj mencioj",
"column.directory": "Foliumi la profilojn",
"column.domain_blocks": "Blokitaj domajnoj",
"column.favourites": "Stelumoj",
"column.firehose": "Vivantaj fluoj",
"column.follow_requests": "Petoj de sekvado",
"column.home": "Hejmo",
@ -136,6 +137,7 @@
"compose.language.search": "Serĉi lingvojn...",
"compose.published.body": "Afiŝo publikigita.",
"compose.published.open": "Malfermi",
"compose.saved.body": "Afiŝo konservita.",
"compose_form.direct_message_warning_learn_more": "Lerni pli",
"compose_form.encryption_warning": "La afiŝoj en Mastodon ne estas tutvoje ĉifritaj. Ne kunhavigu tiklajn informojn ĉe Mastodon.",
"compose_form.hashtag_warning": "Ĉi tiu afiŝo ne estos listigita en neniu kradvorto ĉar ĝi ne estas publika. Nur publikaj afiŝoj povas esti serĉitaj per kradvortoj.",
@ -180,6 +182,7 @@
"confirmations.mute.explanation": "Tio kaŝos la mesaĝojn de la uzanto kaj la mesaĝojn kiuj mencias rin, sed ri ankoraŭ rajtos vidi viajn mesaĝojn kaj sekvi vin.",
"confirmations.mute.message": "Ĉu vi certas, ke vi volas silentigi {name}?",
"confirmations.redraft.confirm": "Forigi kaj reskribi",
"confirmations.redraft.message": "Ĉu vi certas ke vi volas forigi tiun afiŝon kaj reskribi ĝin? Ĉiuj diskonigoj kaj stelumoj estos perditaj, kaj respondoj al la originala mesaĝo estos senparentaj.",
"confirmations.reply.confirm": "Respondi",
"confirmations.reply.message": "Respondi nun anstataŭigos la skribatan afiŝon. Ĉu vi certas, ke vi volas daŭrigi?",
"confirmations.unfollow.confirm": "Ne plu sekvi",
@ -548,6 +551,7 @@
"search.search_or_paste": "Serĉu aŭ algluu URL-on",
"search_popout.quick_actions": "Rapidaj agoj",
"search_popout.recent": "Lastaj serĉoj",
"search_popout.user": "uzanto",
"search_results.accounts": "Profiloj",
"search_results.all": "Ĉiuj",
"search_results.hashtags": "Kradvortoj",

View file

@ -302,8 +302,8 @@
"hashtag.follow": "Seguir etiqueta",
"hashtag.unfollow": "Dejar de seguir etiqueta",
"hashtags.and_other": "…y {count, plural, other {# más}}",
"home.actions.go_to_explore": "Mirá qué está en tendencia",
"home.actions.go_to_suggestions": "Encontrá cuentas para seguir",
"home.actions.go_to_explore": "Ver qué está en tendencia",
"home.actions.go_to_suggestions": "Encontrar cuentas para seguir",
"home.column_settings.basic": "Básico",
"home.column_settings.show_reblogs": "Mostrar adhesiones",
"home.column_settings.show_replies": "Mostrar respuestas",

View file

@ -379,7 +379,7 @@
"lists.delete": "Borrar lista",
"lists.edit": "Editar lista",
"lists.edit.submit": "Cambiar título",
"lists.exclusive": "Ocultar estas publicaciones en inicio",
"lists.exclusive": "Ocultar estas publicaciones de inicio",
"lists.new.create": "Añadir lista",
"lists.new.title_placeholder": "Título de la nueva lista",
"lists.replies_policy.followed": "Cualquier usuario seguido",

View file

@ -15,13 +15,13 @@
"account.add_or_remove_from_list": "افزودن یا برداشتن از سیاهه‌ها",
"account.badges.bot": "روبات",
"account.badges.group": "گروه",
"account.block": "مسدود کردن @{name}",
"account.block_domain": "مسدود کردن دامنهٔ {domain}",
"account.block": "انسداد @{name}",
"account.block_domain": "انسداد دامنهٔ {domain}",
"account.block_short": "انسداد",
"account.blocked": "مسدود شده",
"account.blocked": "مسدود",
"account.browse_more_on_origin_server": "مرور بیش‌تر روی نمایهٔ اصلی",
"account.cancel_follow_request": "رد کردن درخواست پی‌گیری",
"account.direct": "خصوصی از @{name} نام ببرید",
"account.direct": "اشارهٔ خصوصی به @{name}",
"account.disable_notifications": "آگاه کردن من هنگام فرسته‌های @{name} را متوقّف کن",
"account.domain_blocked": "دامنه مسدود شد",
"account.edit_profile": "ویرایش نمایه",
@ -46,7 +46,7 @@
"account.link_verified_on": "مالکیت این پیوند در {date} بررسی شد",
"account.locked_info": "این حساب خصوصی است. صاحبش تصمیم می‌گیرد که چه کسی پی‌گیرش باشد.",
"account.media": "رسانه",
"account.mention": "نام‌بردن از @{name}",
"account.mention": "اشاره به @{name}",
"account.moved_to": "{name} نشان داده که حساب جدیدش این است:",
"account.mute": "خموشاندن @{name}",
"account.mute_notifications_short": "خموشی آگاهی‌ها",
@ -110,7 +110,7 @@
"column.blocks": "کاربران مسدود شده",
"column.bookmarks": "نشانک‌ها",
"column.community": "خط زمانی محلّی",
"column.direct": "خصوصی نام ببرید",
"column.direct": "اشاره‌های خصوصی",
"column.directory": "مرور نمایه‌ها",
"column.domain_blocks": "دامنه‌های مسدود شده",
"column.favourites": "برگزیده‌ها",
@ -137,6 +137,7 @@
"compose.language.search": "جست‌وجوی زبان‌ها…",
"compose.published.body": "فرسته منتشر شد.",
"compose.published.open": "گشودن",
"compose.saved.body": "فرسته ذخیره شد.",
"compose_form.direct_message_warning_learn_more": "بیشتر بدانید",
"compose_form.encryption_warning": "فرسته‌های ماستودون رمزگذاری سرتاسری نشده‌اند. هیچ اطّلاعات حساسی را روی ماستودون هم‌رسانی نکنید.",
"compose_form.hashtag_warning": "از آن‌جا که این فرسته عمومی نیست زیر هیچ برچسبی سیاهه نخواهد شد. تنها فرسته‌های عمومی می‌توانند با برچسب جست‌وجو شوند.",
@ -147,7 +148,7 @@
"compose_form.poll.duration": "مدت نظرسنجی",
"compose_form.poll.option_placeholder": "گزینهٔ {number}",
"compose_form.poll.remove_option": "برداشتن این گزینه",
"compose_form.poll.switch_to_multiple": بدیل به نظرسنجی چندگزینه‌ای",
"compose_form.poll.switch_to_multiple": غییر نظرسنجی برای اجازه به چندین گزینه",
"compose_form.poll.switch_to_single": "تبدیل به نظرسنجی تک‌گزینه‌ای",
"compose_form.publish": "انتشار",
"compose_form.publish_form": "انتشار",
@ -160,8 +161,8 @@
"compose_form.spoiler.unmarked": "افزودن هشدار محتوا",
"compose_form.spoiler_placeholder": "هشدارتان را این‌جا بنویسید",
"confirmation_modal.cancel": "لغو",
"confirmations.block.block_and_report": "مسدود کردن و گزارش",
"confirmations.block.confirm": "مسدود کردن",
"confirmations.block.block_and_report": "انسداد و گزارش",
"confirmations.block.confirm": "انسداد",
"confirmations.block.message": "مطمئنید که می‌خواهید {name} را مسدود کنید؟",
"confirmations.cancel_follow_request.confirm": "رد کردن درخواست",
"confirmations.cancel_follow_request.message": "مطمئنید که می خواهید درخواست پی‌گیری {name} را لغو کنید؟",
@ -171,7 +172,7 @@
"confirmations.delete_list.message": "مطمئنید می‌خواهید این سیاهه را برای همیشه حذف کنید؟",
"confirmations.discard_edit_media.confirm": "دور انداختن",
"confirmations.discard_edit_media.message": "تغییرات ذخیره نشده‌ای در توضیحات یا پیش‌نمایش رسانه دارید. همگی نادیده گرفته شوند؟",
"confirmations.domain_block.confirm": "مسدود کردن تمام دامنه",
"confirmations.domain_block.confirm": "انسداد تمام دامنه",
"confirmations.domain_block.message": "آیا جدی جدی می‌خواهید تمام دامنهٔ {domain} را مسدود کنید؟ در بیشتر موارد مسدود کردن یا خموشاندن چند حساب خاص کافی است و توصیه می‌شود. پس از این کار شما هیچ محتوایی را از این دامنه در خط زمانی عمومی یا آگاهی‌هایتان نخواهید دید. پی‌گیرانتان از این دامنه هم برداشته خواهند شد.",
"confirmations.edit.confirm": "ویرایش",
"confirmations.edit.message": "در صورت ویرایش، پیامی که در حال نوشتنش بودید از بین خواهد رفت. می‌خواهید ادامه دهید؟",
@ -181,6 +182,7 @@
"confirmations.mute.explanation": "این کار فرسته‌های آن‌ها و فرسته‌هایی را که از آن‌ها نام برده پنهان می‌کند، ولی آن‌ها همچنان اجازه دارند فرسته‌های شما را ببینند و شما را پی‌گیری کنند.",
"confirmations.mute.message": "مطمئنید می‌خواهید {name} را بخموشانید؟",
"confirmations.redraft.confirm": "حذف و بازنویسی",
"confirmations.redraft.message": "مطمئنید که می‌خواهید این فرسته را حذف کنید و از نو بنویسید؟ با این کار تقویت‌ها و پسندهایش از دست رفته و پاسخ‌ها به آن بی‌مرجع می‌شود.",
"confirmations.reply.confirm": "پاسخ",
"confirmations.reply.message": "اگر الان پاسخ دهید، چیزی که در حال نوشتنش بودید پاک خواهد شد. می‌خواهید ادامه دهید؟",
"confirmations.unfollow.confirm": "پی‌نگرفتن",
@ -294,16 +296,23 @@
"hashtag.column_settings.tag_mode.any": "هرکدام از این‌ها",
"hashtag.column_settings.tag_mode.none": "هیچ‌کدام از این‌ها",
"hashtag.column_settings.tag_toggle": "افزودن برچسب‌هایی بیشتر به این ستون",
"hashtag.counter_by_accounts": "{count, plural, one {{counter} مشارکت کننده} other {{counter} مشارکت کننده}}",
"hashtag.counter_by_uses": "{count, plural, one {{counter} فرسته} other {{counter} فرسته}}",
"hashtag.counter_by_uses_today": "{count, plural, one {{counter} فرسته} other {{counter} فرسته}} امروز",
"hashtag.follow": "پی‌گرفتن برچسب",
"hashtag.unfollow": "پی‌نگرفتن برچسب",
"hashtags.and_other": "…و {count, plural, other {# بیش‌تر}}",
"home.actions.go_to_explore": "ببینید چه داغ است",
"home.actions.go_to_suggestions": "یافتن افراد برای پی‌گیری",
"home.column_settings.basic": "پایه‌ای",
"home.column_settings.show_reblogs": "نمایش تقویت‌ها",
"home.column_settings.show_replies": "نمایش پاسخ‌ها",
"home.explore_prompt.body": "خوراک خانگیتان ترکیبی از فرسته‌ها از برچسب‌هایی که برای پی‌گیری گزیده‌اید، افرادی که پی می‌گیرید و فرسته‌هایی که تقویت می‌کنند را خواهد داشت. اگر خیلی خلوت به نظر می‌رسد،‌ شاید بخواهید:",
"home.explore_prompt.title": "این پایگاه خانگیتان در ماستودون است.",
"home.hide_announcements": "نهفتن اعلامیه‌ها",
"home.pending_critical_update.body": "لطفاً کارساز ماستودونتان را در نخستین فرصت به‌روز کنید!",
"home.pending_critical_update.link": "دیدن به‌روز رسانی‌ها",
"home.pending_critical_update.title": "به‌روز رسانی امنیتی بحرانی موجود است!",
"home.show_announcements": "نمایش اعلامیه‌ها",
"interaction_modal.description.favourite": "با حسابی روی ماستودون می‌توانید این فرسته را برگزیده تا نگارنده بداند قدردانش هستید و برای آینده ذخیره‌اش می‌کنید.",
"interaction_modal.description.follow": "با حسابی روی ماستودون می‌توانید {name} را برای دریافت فرسته‌هایش در خوراک خانگیتان دنبال کنید.",
@ -314,6 +323,8 @@
"interaction_modal.no_account_yet": "در ماستودون نیست؟",
"interaction_modal.on_another_server": "روی کارسازی دیگر",
"interaction_modal.on_this_server": "روی این کارساز",
"interaction_modal.sign_in": "شما در این کارساز وارد نشده‌اید. حسابتان کجا میزبانی شده؟",
"interaction_modal.sign_in_hint": "نکته: میزبانتان، پایگاه وبیست که رویش ثبت‌نام کرده‌اید. اگر به خاطر نمی‌آورید، به رایانامهٔ خوش‌آمد در صندوق ورودیتان بنگرید. همچنین می‌توانید نام کاربری کاملتان (چون @Mastodon@mastodon.social) را وارد کنید!",
"interaction_modal.title.favourite": "فرسته‌های برگزیدهٔ {name}",
"interaction_modal.title.follow": "پیگیری {name}",
"interaction_modal.title.reblog": "تقویت فرستهٔ {name}",
@ -327,9 +338,10 @@
"keyboard_shortcuts.column": "برای تمرکز روی یک فرسته در یکی از ستون‌ها",
"keyboard_shortcuts.compose": "تمرکز روی محیط نوشتن",
"keyboard_shortcuts.description": "توضیح",
"keyboard_shortcuts.direct": از کردن ستون اشاره‌های خصوصی",
"keyboard_shortcuts.direct": رای گشودن ستون اشاره‌های خصوصی",
"keyboard_shortcuts.down": "پایین بردن در سیاهه",
"keyboard_shortcuts.enter": "گشودن فرسته",
"keyboard_shortcuts.favourite": "پسندیدن فرسته",
"keyboard_shortcuts.favourites": "گشودن فهرست برگزیده‌ها",
"keyboard_shortcuts.federated": "گشودن خط زمانی همگانی",
"keyboard_shortcuts.heading": "میان‌برهای صفحه‌کلید",
@ -337,7 +349,7 @@
"keyboard_shortcuts.hotkey": "میان‌بر",
"keyboard_shortcuts.legend": "نمایش این نشانه",
"keyboard_shortcuts.local": "گشودن خط زمانی محلّی",
"keyboard_shortcuts.mention": "نام‌بردن نویسنده",
"keyboard_shortcuts.mention": "اشاره به نویسنده",
"keyboard_shortcuts.muted": "گشودن فهرست کاربران خموش",
"keyboard_shortcuts.my_profile": "گشودن نمایه‌تان",
"keyboard_shortcuts.notifications": "گشودن ستون آگاهی‌ها",
@ -361,7 +373,7 @@
"lightbox.previous": "قبلی",
"limited_account_hint.action": "به هر روی نمایه نشان داده شود",
"limited_account_hint.title": "این نمایه از سوی ناظم‌های {domain} پنهان شده.",
"link_preview.author": "بر اساس {name}",
"link_preview.author": "از {name}",
"lists.account.add": "افزودن به سیاهه",
"lists.account.remove": "برداشتن از سیاهه",
"lists.delete": "حذف سیاهه",
@ -402,6 +414,7 @@
"navigation_bar.lists": "سیاهه‌ها",
"navigation_bar.logout": "خروج",
"navigation_bar.mutes": "کاربران خموشانده",
"navigation_bar.opened_in_classic_interface": "فرسته‌ها، حساب‌ها و دیگر صفحه‌های خاص به طور پیش‌گزیده در میانای وب کلاسیک گشوده می‌شوند.",
"navigation_bar.personal": "شخصی",
"navigation_bar.pins": "فرسته‌های سنجاق شده",
"navigation_bar.preferences": "ترجیحات",
@ -411,11 +424,11 @@
"not_signed_in_indicator.not_signed_in": "برای دسترسی به این منبع باید وارد شوید.",
"notification.admin.report": "{name}، {target} را گزارش داد",
"notification.admin.sign_up": "{name} ثبت نام کرد",
"notification.favourite": "{name} نوشتهٔ شما را پسندید",
"notification.favourite": "{name} فرسته‌تان را برگزید",
"notification.follow": "{name} پی‌گیرتان شد",
"notification.follow_request": "{name} می‌خواهد پی‌گیر شما باشد",
"notification.mention": "{name} از شما نام برد",
"notification.own_poll": "نظرسنجی شما به پایان رسید",
"notification.follow_request": "{name} درخواست پی‌گیریتان را داد",
"notification.mention": "{name} به شما اشاره کرد",
"notification.own_poll": "نظرسنجیتان پایان یافت",
"notification.poll": "نظرسنجی‌ای که در آن رأی دادید به پایان رسیده است",
"notification.reblog": "{name} فرسته‌تان را تقویت کرد",
"notification.status": "{name} چیزی فرستاد",
@ -431,7 +444,7 @@
"notifications.column_settings.filter_bar.show_bar": "نمایش نوار پالایه",
"notifications.column_settings.follow": "پی‌گیرندگان جدید:",
"notifications.column_settings.follow_request": "درخواست‌های جدید پی‌گیری:",
"notifications.column_settings.mention": "نام‌بردنها:",
"notifications.column_settings.mention": "اشارهها:",
"notifications.column_settings.poll": "نتایج نظرسنجی:",
"notifications.column_settings.push": "آگاهی‌های ارسالی",
"notifications.column_settings.reblog": "تقویت‌ها:",
@ -445,7 +458,7 @@
"notifications.filter.boosts": "تقویت‌ها",
"notifications.filter.favourites": "برگزیده‌ها",
"notifications.filter.follows": "پی‌گرفتگان",
"notifications.filter.mentions": "نام‌بردنها",
"notifications.filter.mentions": "اشارهها",
"notifications.filter.polls": "نتایج نظرسنجی",
"notifications.filter.statuses": "به‌روز رسانی‌ها از کسانی که پی‌گیرشانید",
"notifications.grant_permission": "اعطای مجوز.",
@ -480,10 +493,10 @@
"onboarding.steps.setup_profile.title": "Customize your profile",
"onboarding.steps.share_profile.body": "Let your friends know how to find you on Mastodon!",
"onboarding.steps.share_profile.title": "Share your profile",
"onboarding.tips.2fa": "<strong>آیا میدانستید؟</strong> شما می‌توانید با رفتن به تنظیمات حساب و فعال کردن احراز هویت دوعاملی، حساب خود را ایمن کنید؟ این قابلیت با هر نرم‌افزار TOTP دلخواه شما کار مي‌کند و نیازی به شماره تلفن ندارد!",
"onboarding.tips.accounts_from_other_servers": "<strong>آیا می‌دانستید؟</strong> چون ماستودون نامتمرکز است، بعضی از پروفایل‌هایی که با آنها برخورد می‌کنید درواقع روی کارساز هایی متفاوت از کارساز شما میزبانی می‌شوند. و شما همچنان می‌توانید با آنها به شکل راحت و روان تعامل کنید! کارساز آن‌ها در نیمه دوم نام کاربری‌شان است!",
"onboarding.tips.migration": "<strong>آیا می‌دانستید؟</strong> اگر احساس می‌کنید {domain} انتخاب کارساز خوبی برای آینده‌تان نیست، می‌توانید بدون از دست دادن پیگیرهایتان به یک کارساز ماستودون دیگر مهاجرت کنید. شما حتی می‌توانید کارساز خودتان را میزبانی کنید!",
"onboarding.tips.verification": "<strong>آیا می‌دانستید؟</strong> شما می‌توانید حساب خود را با قراردادن پیوندی به نمایه ماستودون‌تان روی وبسایت خود، و اضافه کردن وبسایت‌تان به نمایه خود تایید کنید. بدون نیاز به هیچ کارمزد یا سندی!",
"onboarding.tips.2fa": "<strong>آیا می‌دانستید؟</strong> می‌توانید با پریایی هویت‌سنجی دو عاملی در تنظیمات حساب، حسابتان را ایمن کنید؟ این قابلیت با هر نرم‌افزار TOTP دلخواه کار کرده و نیازی به شماره تلفن ندارد!",
"onboarding.tips.accounts_from_other_servers": "<strong>آیا می‌دانستید؟</strong> از آن‌جا که ماستودون نامتمرکز است، برخی نمایه‌ها که به آن‌ها برمی‌خورید روی کارسازهایی متفاوت از شما میزبانی می‌شوند و باز هم می‌توانید بدون مشکل با آن‌ها تعامل داشته باشید! کارسازشان در نیمه دوم نام کاربریشان است!",
"onboarding.tips.migration": "<strong>آیا می‌دانستید؟</strong> اگر احساس می‌کنید {domain} انتخاب کارساز خوبی برای آینده‌تان نیست، می‌توانید بدون از دست دادن پیگیرهایتان به کارساز ماستودون دیگری مهاجرت کنید. حتا می‌توانید کارساز خودتان را میزبانی کنید!",
"onboarding.tips.verification": "<strong>آیا می‌دانستید؟</strong> می‌توانید حسابتان را با گذاشتن پیوندی به نمایهٔ ماستودونتان روی پایگاه وب خود و افزودن پایگاه وبتان به نمایه‌تان تأیید کنید. بدون نیاز به هیچ کارمزد یا سندی!",
"password_confirmation.exceeds_maxlength": "تأییدیه گذرواژه از حداکثر طول گذرواژه بیشتر است",
"password_confirmation.mismatching": "تایید گذرواژه با گذرواژه مطابقت ندارد",
"picture_in_picture.restore": "برگرداندن",
@ -523,8 +536,9 @@
"relative_time.seconds": "{number} ثانیه",
"relative_time.today": "امروز",
"reply_indicator.cancel": "لغو",
"report.block": "مسدود کردن",
"report.block": "انسداد",
"report.block_explanation": "شما فرسته‌هایشان را نخواهید دید. آن‌ها نمی‌توانند فرسته‌هایتان را ببینند یا شما را پی‌بگیرند. آنها می‌توانند بگویند که مسدود شده‌اند.",
"report.categories.legal": "حقوقی",
"report.categories.other": "غیره",
"report.categories.spam": "هرزنامه",
"report.categories.violation": "محتوا یک یا چند قانون کارساز را نقض می‌کند",
@ -576,12 +590,18 @@
"search.quick_action.open_url": "باز کردن پیوند در ماستودون",
"search.quick_action.status_search": "فرسته‌های جور با {x}",
"search.search_or_paste": "جست‌وجو یا جایگذاری نشانی",
"search_popout.full_text_search_disabled_message": "روی {domain} موجود نیست.",
"search_popout.language_code": "کد زبان ایزو",
"search_popout.options": "گزینه‌های جست‌وجو",
"search_popout.quick_actions": "کنش‌های سریع",
"search_popout.recent": "جست‌وجوهای اخیر",
"search_popout.specific_date": "تاریخ مشخص",
"search_popout.user": "کاربر",
"search_results.accounts": "نمایه‌ها",
"search_results.all": "همه",
"search_results.hashtags": "برچسب‌ها",
"search_results.nothing_found": "چیزی برای این عبارت جست‌وجو یافت نشد",
"search_results.see_all": "دیدن همه",
"search_results.statuses": "فرسته‌ها",
"search_results.title": "جست‌وجو برای {q}",
"server_banner.about_active_users": "افرادی که در ۳۰ روز گذشته از این کارساز استفاده کرده‌اند (کاربران فعّال ماهانه)",
@ -597,15 +617,15 @@
"status.admin_account": "گشودن واسط مدیریت برای @{name}",
"status.admin_domain": "گشودن واسط مدیریت برای {domain}",
"status.admin_status": "گشودن این فرسته در واسط مدیریت",
"status.block": "مسدود کردن @{name}",
"status.block": "انسداد @{name}",
"status.bookmark": "نشانک",
"status.cancel_reblog_private": "ناتقویت",
"status.cannot_reblog": "این فرسته قابل تقویت نیست",
"status.copy": "رونوشت از پیوند فرسته",
"status.delete": "حذف",
"status.detailed_status": "نمایش کامل گفتگو",
"status.direct": "خصوصی به @{name} اشاره کنید",
"status.direct_indicator": "اشاره خصوصی",
"status.direct": "اشارهٔ خصوصی به @{name}",
"status.direct_indicator": "اشارهٔ خصوصی",
"status.edit": "ویرایش",
"status.edited": "ویرایش شده در {date}",
"status.edited_x_times": "{count, plural, one {{count} مرتبه} other {{count} مرتبه}} ویرایش شد",
@ -620,7 +640,7 @@
"status.media.open": "کلیک برای گشودن",
"status.media.show": "کلیک برای نمایش",
"status.media_hidden": "رسانهٔ نهفته",
"status.mention": "نام‌بردن از @{name}",
"status.mention": "اشاره به @{name}",
"status.more": "بیشتر",
"status.mute": "خموشاندن @{name}",
"status.mute_conversation": "خموشاندن گفت‌وگو",

View file

@ -1,9 +1,9 @@
{
"about.blocks": "Moderoidut palvelimet",
"about.contact": "Yhteystiedot:",
"about.blocks": "Valvotut palvelimet",
"about.contact": "Yhteydenotto:",
"about.disclaimer": "Mastodon on vapaa avoimen lähdekoodin ohjelmisto ja Mastodon gGmbH:n tavaramerkki.",
"about.domain_blocks.no_reason_available": "Syytä ei ole ilmoitettu",
"about.domain_blocks.preamble": "Yleisesti Mastodonin avulla voidaan tarkastella minkä tahansa muun fediverse-palvelinten sisältöä ja vuorovaikuttaa eri palvelinten käyttäjien kanssa. Nämä ovat tälle palvelimelle määritetyt poikkeukset.",
"about.domain_blocks.preamble": "Mastodonin avulla voidaan yleensä tarkastella minkä tahansa fediversumiin kuuluvan palvelimen sisältöä ja vuorovaikuttaa eri palvelinten käyttäjien kanssa. Nämä ovat tälle palvelimelle määritetyt poikkeukset.",
"about.domain_blocks.silenced.explanation": "Et yleensä näe tämän palvelimen profiileja ja sisältöä, jollet erityisesti etsi juuri sitä tai liity siihen seuraamalla.",
"about.domain_blocks.silenced.title": "Rajoitettu",
"about.domain_blocks.suspended.explanation": "Mitään tämän palvelimen tietoja ei käsitellä, tallenneta tai vaihdeta, mikä tekee vuorovaikutuksesta ja viestinnästä sen käyttäjien kanssa mahdotonta.",
@ -16,7 +16,7 @@
"account.badges.bot": "Botti",
"account.badges.group": "Ryhmä",
"account.block": "Estä @{name}",
"account.block_domain": "Estä palvelu {domain}",
"account.block_domain": "Estä verkkotunnus {domain}",
"account.block_short": "Estä",
"account.blocked": "Estetty",
"account.browse_more_on_origin_server": "Selaile lisää alkuperäisellä palvelimella",
@ -25,11 +25,11 @@
"account.disable_notifications": "Lopeta ilmoittamasta minulle, kun @{name} julkaisee",
"account.domain_blocked": "Verkkotunnus estetty",
"account.edit_profile": "Muokkaa profiilia",
"account.enable_notifications": "Ilmoita kun käyttäjä @{name} julkaisee viestin",
"account.enable_notifications": "Ilmoita minulle, kun @{name} julkaisee",
"account.endorse": "Suosittele profiilissasi",
"account.featured_tags.last_status_at": "Viimeisin viesti {date}",
"account.featured_tags.last_status_never": "Ei viestejä",
"account.featured_tags.title": "Käyttäjän {name} esillä olevat aihetunnisteet",
"account.featured_tags.last_status_at": "Viimeisin julkaisu {date}",
"account.featured_tags.last_status_never": "Ei julkaisuja",
"account.featured_tags.title": "Käyttäjän {name} esille nostetut aihetunnisteet",
"account.follow": "Seuraa",
"account.followers": "seuraaja(t)",
"account.followers.empty": "Kukaan ei seuraa tätä käyttäjää vielä.",
@ -54,21 +54,21 @@
"account.muted": "Mykistetty",
"account.no_bio": "Kuvausta ei ole annettu.",
"account.open_original_page": "Avaa alkuperäinen sivu",
"account.posts": "viesti(t)",
"account.posts_with_replies": "Viestit ja vastaukset",
"account.posts": "Julkaisut",
"account.posts_with_replies": "Julkaisut ja vastaukset",
"account.report": "Raportoi @{name}",
"account.requested": "Odottaa hyväksyntää. Peruuta seuraamispyyntö klikkaamalla",
"account.requested": "Odottaa hyväksyntää. Peruuta seuraamispyyntö napsauttamalla",
"account.requested_follow": "{name} on pyytänyt lupaa seurata sinua",
"account.share": "Jaa käyttäjän @{name} profiili",
"account.show_reblogs": "Näytä tehostukset käyttäjältä @{name}",
"account.statuses_counter": "{count, plural, one {{counter} viesti} other {{counter} viestiä}}",
"account.show_reblogs": "Näytä käyttäjän @{name} tehostukset",
"account.statuses_counter": "{count, plural, one {{counter} julkaisu} other {{counter} julkaisua}}",
"account.unblock": "Poista esto: @{name}",