Merge commit '93f3c724aea4efe874054b2f546fff91f0bf731b' into glitch-soc/merge-upstream

Conflicts:
- `spec/system/settings/preferences/appearance_spec.rb`:
  Upstream tests for changing themes in there, but glitch-soc has
  its own place for that.
  Updated upstream's change while skipping the theme test.
pull/2955/head
Claire 2025-01-27 18:19:09 +01:00
commit fcc5262f60
193 changed files with 2153 additions and 673 deletions

View File

@ -10,6 +10,7 @@ services:
RAILS_ENV: development
NODE_ENV: development
BIND: 0.0.0.0
BOOTSNAP_CACHE_DIR: /tmp
REDIS_HOST: redis
REDIS_PORT: '6379'
DB_HOST: db

View File

@ -1,7 +1,7 @@
# syntax=docker/dockerfile:1.12
# This file is designed for production server deployment, not local development work
# For a containerized local dev environment, see: https://github.com/mastodon/mastodon/blob/main/README.md#docker
# For a containerized local dev environment, see: https://github.com/mastodon/mastodon/blob/main/docs/DEVELOPMENT.md#docker
# Please see https://docs.docker.com/engine/reference/builder for information about
# the extended buildx capabilities used in this file.

View File

@ -100,6 +100,8 @@ gem 'json-ld'
gem 'json-ld-preloaded', '~> 3.2'
gem 'rdf-normalize', '~> 0.5'
gem 'prometheus_exporter', '~> 2.2', require: false
gem 'opentelemetry-api', '~> 1.4.0'
group :opentelemetry do

View File

@ -557,7 +557,7 @@ GEM
opentelemetry-api (~> 1.0)
orm_adapter (0.5.0)
ostruct (0.6.1)
ox (2.14.20)
ox (2.14.21)
bigdecimal (>= 3.0)
parallel (1.26.3)
parser (3.3.7.0)
@ -580,6 +580,8 @@ GEM
net-smtp
premailer (~> 1.7, >= 1.7.9)
prettyprint (0.2.0)
prometheus_exporter (2.2.0)
webrick
propshaft (1.1.0)
actionpack (>= 7.0.0)
activesupport (>= 7.0.0)
@ -984,6 +986,7 @@ DEPENDENCIES
pg (~> 1.5)
pghero
premailer-rails
prometheus_exporter (~> 2.2)
propshaft
public_suffix (~> 6.0)
puma (~> 6.3)

View File

@ -34,7 +34,8 @@ module Admin
end
def resource_params
params.require(:admin_account_action).permit(:type, :report_id, :warning_preset_id, :text, :send_email_notification, :include_statuses)
params
.expect(admin_account_action: [:type, :report_id, :warning_preset_id, :text, :send_email_notification, :include_statuses])
end
end
end

View File

@ -29,10 +29,8 @@ module Admin
private
def resource_params
params.require(:account_moderation_note).permit(
:content,
:target_account_id
)
params
.expect(account_moderation_note: [:content, :target_account_id])
end
def set_account_moderation_note

View File

@ -158,7 +158,8 @@ module Admin
end
def form_account_batch_params
params.require(:form_account_batch).permit(:action, account_ids: [])
params
.expect(form_account_batch: [:action, account_ids: []])
end
def action_from_button

View File

@ -84,6 +84,7 @@ class Admin::AnnouncementsController < Admin::BaseController
end
def resource_params
params.require(:announcement).permit(:text, :scheduled_at, :starts_at, :ends_at, :all_day)
params
.expect(announcement: [:text, :scheduled_at, :starts_at, :ends_at, :all_day])
end
end

View File

@ -41,9 +41,8 @@ module Admin
end
def resource_params
params.require(:user).permit(
:unconfirmed_email
)
params
.expect(user: [:unconfirmed_email])
end
end
end

View File

@ -47,7 +47,8 @@ module Admin
private
def resource_params
params.require(:custom_emoji).permit(:shortcode, :image, :visible_in_picker)
params
.expect(custom_emoji: [:shortcode, :image, :visible_in_picker])
end
def filtered_custom_emojis
@ -77,7 +78,8 @@ module Admin
end
def form_custom_emoji_batch_params
params.require(:form_custom_emoji_batch).permit(:action, :category_id, :category_name, custom_emoji_ids: [])
params
.expect(form_custom_emoji_batch: [:action, :category_id, :category_name, custom_emoji_ids: []])
end
end
end

View File

@ -37,6 +37,7 @@ class Admin::DomainAllowsController < Admin::BaseController
end
def resource_params
params.require(:domain_allow).permit(:domain)
params
.expect(domain_allow: [:domain])
end
end

View File

@ -25,7 +25,9 @@ module Admin
rescue Mastodon::NotPermittedError
flash[:alert] = I18n.t('admin.domain_blocks.not_permitted')
else
redirect_to admin_instances_path(limited: '1'), notice: I18n.t('admin.domain_blocks.created_msg')
flash[:notice] = I18n.t('admin.domain_blocks.created_msg')
ensure
redirect_to admin_instances_path(limited: '1')
end
def new
@ -114,7 +116,12 @@ module Admin
end
def form_domain_block_batch_params
params.require(:form_domain_block_batch).permit(domain_blocks_attributes: [:enabled, :domain, :severity, :reject_media, :reject_reports, :private_comment, :public_comment, :obfuscate])
params
.expect(
form_domain_block_batch: [
domain_blocks_attributes: [[:enabled, :domain, :severity, :reject_media, :reject_reports, :private_comment, :public_comment, :obfuscate]],
]
)
end
def action_from_button

View File

@ -62,11 +62,13 @@ module Admin
end
def resource_params
params.require(:email_domain_block).permit(:domain, :allow_with_approval, other_domains: [])
params
.expect(email_domain_block: [:domain, :allow_with_approval, other_domains: []])
end
def form_email_domain_block_batch_params
params.require(:form_email_domain_block_batch).permit(email_domain_block_ids: [])
params
.expect(form_email_domain_block_batch: [email_domain_block_ids: []])
end
def action_from_button

View File

@ -37,7 +37,8 @@ module Admin
end
def form_account_batch_params
params.require(:form_account_batch).permit(:action, account_ids: [])
params
.expect(form_account_batch: [:action, account_ids: []])
end
def filter_params

View File

@ -39,7 +39,8 @@ module Admin
private
def resource_params
params.require(:invite).permit(:max_uses, :expires_in)
params
.expect(invite: [:max_uses, :expires_in])
end
def filtered_invites

View File

@ -44,7 +44,8 @@ module Admin
private
def resource_params
params.require(:ip_block).permit(:ip, :severity, :comment, :expires_in)
params
.expect(ip_block: [:ip, :severity, :comment, :expires_in])
end
def action_from_button
@ -52,7 +53,8 @@ module Admin
end
def form_ip_block_batch_params
params.require(:form_ip_block_batch).permit(ip_block_ids: [])
params
.expect(form_ip_block_batch: [ip_block_ids: []])
end
end
end

View File

@ -57,7 +57,8 @@ module Admin
end
def resource_params
params.require(:relay).permit(:inbox_url)
params
.expect(relay: [:inbox_url])
end
def warn_signatures_not_enabled!

View File

@ -47,10 +47,8 @@ module Admin
end
def resource_params
params.require(:report_note).permit(
:content,
:report_id
)
params
.expect(report_note: [:content, :report_id])
end
def set_report_note

View File

@ -61,7 +61,8 @@ module Admin
end
def resource_params
params.require(:user_role).permit(:name, :color, :highlighted, :position, permissions_as_keys: [])
params
.expect(user_role: [:name, :color, :highlighted, :position, permissions_as_keys: []])
end
end
end

View File

@ -53,7 +53,8 @@ module Admin
end
def resource_params
params.require(:rule).permit(:text, :hint, :priority)
params
.expect(rule: [:text, :hint, :priority])
end
end
end

View File

@ -28,7 +28,8 @@ module Admin
end
def settings_params
params.require(:form_admin_settings).permit(*Form::AdminSettings::KEYS)
params
.expect(form_admin_settings: [*Form::AdminSettings::KEYS])
end
end
end

View File

@ -39,7 +39,8 @@ module Admin
helper_method :batched_ordered_status_edits
def admin_status_batch_action_params
params.require(:admin_status_batch_action).permit(status_ids: [])
params
.expect(admin_status_batch_action: [status_ids: []])
end
def after_create_redirect_path

View File

@ -37,7 +37,8 @@ module Admin
end
def tag_params
params.require(:tag).permit(:name, :display_name, :trendable, :usable, :listable)
params
.expect(tag: [:name, :display_name, :trendable, :usable, :listable])
end
def filtered_tags

View File

@ -31,6 +31,7 @@ class Admin::TermsOfService::DraftsController < Admin::BaseController
end
def resource_params
params.require(:terms_of_service).permit(:text, :changelog)
params
.expect(terms_of_service: [:text, :changelog])
end
end

View File

@ -32,6 +32,7 @@ class Admin::TermsOfService::GeneratesController < Admin::BaseController
end
def resource_params
params.require(:terms_of_service_generator).permit(*TermsOfService::Generator::VARIABLES)
params
.expect(terms_of_service_generator: [*TermsOfService::Generator::VARIABLES])
end
end

View File

@ -31,7 +31,8 @@ class Admin::Trends::Links::PreviewCardProvidersController < Admin::BaseControll
end
def trends_preview_card_provider_batch_params
params.require(:trends_preview_card_provider_batch).permit(:action, preview_card_provider_ids: [])
params
.expect(trends_preview_card_provider_batch: [:action, preview_card_provider_ids: []])
end
def action_from_button

View File

@ -31,7 +31,8 @@ class Admin::Trends::LinksController < Admin::BaseController
end
def trends_preview_card_batch_params
params.require(:trends_preview_card_batch).permit(:action, preview_card_ids: [])
params
.expect(trends_preview_card_batch: [:action, preview_card_ids: []])
end
def action_from_button

View File

@ -31,7 +31,8 @@ class Admin::Trends::StatusesController < Admin::BaseController
end
def trends_status_batch_params
params.require(:trends_status_batch).permit(:action, status_ids: [])
params
.expect(trends_status_batch: [:action, status_ids: []])
end
def action_from_button

View File

@ -31,7 +31,8 @@ class Admin::Trends::TagsController < Admin::BaseController
end
def trends_tag_batch_params
params.require(:trends_tag_batch).permit(:action, tag_ids: [])
params
.expect(trends_tag_batch: [:action, tag_ids: []])
end
def action_from_button

View File

@ -28,7 +28,8 @@ module Admin
end
def resource_params
params.require(:user).permit(:role_id)
params
.expect(user: [:role_id])
end
end
end

View File

@ -52,7 +52,8 @@ module Admin
end
def warning_preset_params
params.require(:account_warning_preset).permit(:title, :text)
params
.expect(account_warning_preset: [:title, :text])
end
end
end

View File

@ -74,7 +74,8 @@ module Admin
end
def resource_params
params.require(:webhook).permit(:url, :template, events: [])
params
.expect(webhook: [:url, :template, events: []])
end
end
end

View File

@ -73,7 +73,7 @@ class Auth::SessionsController < Devise::SessionsController
end
def user_params
params.require(:user).permit(:email, :password, :otp_attempt, credential: {})
params.expect(user: [:email, :password, :otp_attempt, credential: {}])
end
def after_sign_in_path_for(resource)

View File

@ -24,6 +24,6 @@ module Admin::ExportControllerConcern
end
def import_params
params.require(:admin_import).permit(:data)
params.expect(admin_import: [:data])
end
end

View File

@ -58,6 +58,6 @@ module ChallengableConcern
end
def challenge_params
params.require(:form_challenge).permit(:current_password, :return_to)
params.expect(form_challenge: [:current_password, :return_to])
end
end

View File

@ -34,7 +34,7 @@ class Filters::StatusesController < ApplicationController
end
def status_filter_batch_action_params
params.require(:form_status_filter_batch_action).permit(status_filter_ids: [])
params.expect(form_status_filter_batch_action: [status_filter_ids: []])
end
def action_from_button

View File

@ -36,7 +36,7 @@ class RelationshipsController < ApplicationController
end
def form_account_batch_params
params.require(:form_account_batch).permit(:action, account_ids: [])
params.expect(form_account_batch: [:action, account_ids: []])
end
def following_relationship?

View File

@ -60,16 +60,12 @@ class Settings::ApplicationsController < Settings::BaseController
end
def application_params
params.require(:doorkeeper_application).permit(
:name,
:redirect_uri,
:scopes,
:website
)
params
.expect(doorkeeper_application: [:name, :redirect_uri, :scopes, :website])
end
def prepare_scopes
scopes = params.fetch(:doorkeeper_application, {}).fetch(:scopes, nil)
scopes = application_params.fetch(:doorkeeper_application, {}).fetch(:scopes, nil)
params[:doorkeeper_application][:scopes] = scopes.join(' ') if scopes.is_a? Array
end
end

View File

@ -19,6 +19,6 @@ class Settings::Preferences::BaseController < Settings::BaseController
end
def user_params
params.require(:user).permit(:locale, :time_zone, chosen_languages: [], settings_attributes: UserSettings.keys)
params.expect(user: [:locale, :time_zone, chosen_languages: [], settings_attributes: UserSettings.keys])
end
end

View File

@ -38,7 +38,7 @@ module Settings
private
def confirmation_params
params.require(:form_two_factor_confirmation).permit(:otp_attempt)
params.expect(form_two_factor_confirmation: [:otp_attempt])
end
def prepare_two_factor_form

View File

@ -18,7 +18,7 @@ class Settings::VerificationsController < Settings::BaseController
private
def account_params
params.require(:account).permit(:attribution_domains).tap do |params|
params.expect(account: [:attribution_domains]).tap do |params|
params[:attribution_domains] = params[:attribution_domains].split if params[:attribution_domains]
end
end

View File

@ -145,7 +145,6 @@ class Item extends PureComponent {
srcSet={srcSet}
sizes={sizes}
alt={description}
title={description}
lang={lang}
style={{ objectPosition: `${x}% ${y}%` }}
onLoad={this.handleImageLoad}
@ -167,7 +166,6 @@ class Item extends PureComponent {
<video
className='media-gallery__item-gifv-thumbnail'
aria-label={description}
title={description}
lang={lang}
role='application'
src={attachment.get('url')}

View File

@ -93,7 +93,6 @@ export const MediaItem: React.FC<{
<img
src={previewUrl || avatarUrl}
alt={description}
title={description}
lang={lang}
onLoad={handleImageLoad}
/>
@ -113,7 +112,6 @@ export const MediaItem: React.FC<{
<img
src={previewUrl}
alt={description}
title={description}
lang={lang}
style={{ objectPosition: `${x}% ${y}%` }}
onLoad={handleImageLoad}
@ -131,7 +129,6 @@ export const MediaItem: React.FC<{
<video
className='media-gallery__item-gifv-thumbnail'
aria-label={description}
title={description}
lang={lang}
src={fullUrl}
onMouseEnter={handleMouseEnter}

View File

@ -0,0 +1,81 @@
import { useState, useRef, useCallback, useId } from 'react';
import { FormattedMessage, useIntl, defineMessages } from 'react-intl';
import classNames from 'classnames';
import Overlay from 'react-overlays/Overlay';
import QuestionMarkIcon from '@/material-icons/400-24px/question_mark.svg?react';
import { Icon } from 'mastodon/components/icon';
const messages = defineMessages({
help: { id: 'info_button.label', defaultMessage: 'Help' },
});
export const InfoButton: React.FC = () => {
const intl = useIntl();
const [open, setOpen] = useState(false);
const triggerRef = useRef<HTMLButtonElement>(null);
const accessibilityId = useId();
const handleClick = useCallback(() => {
setOpen(!open);
}, [open, setOpen]);
return (
<>
<button
type='button'
className={classNames('help-button', { active: open })}
ref={triggerRef}
onClick={handleClick}
aria-expanded={open}
aria-controls={accessibilityId}
aria-label={intl.formatMessage(messages.help)}
>
<Icon id='' icon={QuestionMarkIcon} />
</button>
<Overlay
show={open}
rootClose
placement='top'
onHide={handleClick}
offset={[5, 5]}
target={triggerRef}
>
{({ props }) => (
<div
{...props}
className='dialog-modal__popout prose dropdown-animation'
id={accessibilityId}
>
<FormattedMessage
id='info_button.what_is_alt_text'
defaultMessage='<h1>What is alt text?</h1>
<p>Alt text provides image descriptions for people with vision impairments, low-bandwidth connections, or those seeking extra context.</p>
<p>You can improve accessibility and understanding for everyone by writing clear, concise, and objective alt text.</p>
<ul>
<li>Capture important elements</li>
<li>Summarize text in images</li>
<li>Use regular sentence structure</li>
<li>Avoid redundant information</li>
<li>Focus on trends and key findings in complex visuals (like diagrams or maps)</li>
</ul>'
values={{
h1: (node) => <h1>{node}</h1>,
p: (node) => <p>{node}</p>,
ul: (node) => <ul>{node}</ul>,
li: (node) => <li>{node}</li>,
}}
/>
</div>
)}
</Overlay>
</>
);
};

View File

@ -36,6 +36,8 @@ import type { MediaAttachment } from 'mastodon/models/media_attachment';
import { useAppSelector, useAppDispatch } from 'mastodon/store';
import { assetHost } from 'mastodon/utils/config';
import { InfoButton } from './components/info_button';
const messages = defineMessages({
placeholderVisual: {
id: 'alt_text_modal.describe_for_people_with_visual_impairments',
@ -504,6 +506,13 @@ export const AltTextModal = forwardRef<ModalRef, Props & Partial<RestoreProps>>(
</div>
<div className='input__toolbar'>
<CharacterCounter
max={MAX_LENGTH}
text={isDetecting ? '' : description}
/>
<div className='spacer' />
<button
className='link-button'
onClick={handleDetectClick}
@ -515,10 +524,7 @@ export const AltTextModal = forwardRef<ModalRef, Props & Partial<RestoreProps>>(
/>
</button>
<CharacterCounter
max={MAX_LENGTH}
text={isDetecting ? '' : description}
/>
<InfoButton />
</div>
</div>
</form>

View File

@ -14,7 +14,6 @@ import AutosuggestInput from '../../../components/autosuggest_input';
import AutosuggestTextarea from '../../../components/autosuggest_textarea';
import { Button } from '../../../components/button';
import EmojiPickerDropdown from '../containers/emoji_picker_dropdown_container';
import LanguageDropdown from '../containers/language_dropdown_container';
import PollButtonContainer from '../containers/poll_button_container';
import PrivacyDropdownContainer from '../containers/privacy_dropdown_container';
import SpoilerButtonContainer from '../containers/spoiler_button_container';
@ -24,6 +23,7 @@ import { countableText } from '../util/counter';
import { CharacterCounter } from './character_counter';
import { EditIndicator } from './edit_indicator';
import { LanguageDropdown } from './language_dropdown';
import { NavigationBar } from './navigation_bar';
import { PollForm } from "./poll_form";
import { ReplyIndicator } from './reply_indicator';

View File

@ -1,330 +0,0 @@
import PropTypes from 'prop-types';
import { PureComponent } from 'react';
import { injectIntl, defineMessages } from 'react-intl';
import classNames from 'classnames';
import { supportsPassiveEvents } from 'detect-passive-events';
import fuzzysort from 'fuzzysort';
import Overlay from 'react-overlays/Overlay';
import CancelIcon from '@/material-icons/400-24px/cancel-fill.svg?react';
import SearchIcon from '@/material-icons/400-24px/search.svg?react';
import TranslateIcon from '@/material-icons/400-24px/translate.svg?react';
import { Icon } from 'mastodon/components/icon';
import { languages as preloadedLanguages } from 'mastodon/initial_state';
const messages = defineMessages({
changeLanguage: { id: 'compose.language.change', defaultMessage: 'Change language' },
search: { id: 'compose.language.search', defaultMessage: 'Search languages...' },
clear: { id: 'emoji_button.clear', defaultMessage: 'Clear' },
});
const listenerOptions = supportsPassiveEvents ? { passive: true, capture: true } : true;
class LanguageDropdownMenu extends PureComponent {
static propTypes = {
value: PropTypes.string.isRequired,
guess: PropTypes.string,
frequentlyUsedLanguages: PropTypes.arrayOf(PropTypes.string).isRequired,
onClose: PropTypes.func.isRequired,
onChange: PropTypes.func.isRequired,
languages: PropTypes.arrayOf(PropTypes.arrayOf(PropTypes.string)),
intl: PropTypes.object,
};
static defaultProps = {
languages: preloadedLanguages,
};
state = {
searchValue: '',
};
handleDocumentClick = e => {
if (this.node && !this.node.contains(e.target)) {
this.props.onClose();
e.stopPropagation();
}
};
componentDidMount () {
document.addEventListener('click', this.handleDocumentClick, { capture: true });
document.addEventListener('touchend', this.handleDocumentClick, listenerOptions);
// Because of https://github.com/react-bootstrap/react-bootstrap/issues/2614 we need
// to wait for a frame before focusing
requestAnimationFrame(() => {
if (this.node) {
const element = this.node.querySelector('input[type="search"]');
if (element) element.focus();
}
});
}
componentWillUnmount () {
document.removeEventListener('click', this.handleDocumentClick, { capture: true });
document.removeEventListener('touchend', this.handleDocumentClick, listenerOptions);
}
setRef = c => {
this.node = c;
};
setListRef = c => {
this.listNode = c;
};
handleSearchChange = ({ target }) => {
this.setState({ searchValue: target.value });
};
search () {
const { languages, value, frequentlyUsedLanguages, guess } = this.props;
const { searchValue } = this.state;
if (searchValue === '') {
return [...languages].sort((a, b) => {
if (guess && a[0] === guess) { // Push guessed language higher than current selection
return -1;
} else if (guess && b[0] === guess) {
return 1;
} else if (a[0] === value) { // Push current selection to the top of the list
return -1;
} else if (b[0] === value) {
return 1;
} else {
// Sort according to frequently used languages
const indexOfA = frequentlyUsedLanguages.indexOf(a[0]);
const indexOfB = frequentlyUsedLanguages.indexOf(b[0]);
return ((indexOfA > -1 ? indexOfA : Infinity) - (indexOfB > -1 ? indexOfB : Infinity));
}
});
}
return fuzzysort.go(searchValue, languages, {
keys: ['0', '1', '2'],
limit: 5,
threshold: -10000,
}).map(result => result.obj);
}
handleClick = e => {
const value = e.currentTarget.getAttribute('data-index');
e.preventDefault();
this.props.onClose();
this.props.onChange(value);
};
handleKeyDown = e => {
const { onClose } = this.props;
const index = Array.from(this.listNode.childNodes).findIndex(node => node === e.currentTarget);
let element = null;
switch(e.key) {
case 'Escape':
onClose();
break;
case ' ':
case 'Enter':
this.handleClick(e);
break;
case 'ArrowDown':
element = this.listNode.childNodes[index + 1] || this.listNode.firstChild;
break;
case 'ArrowUp':
element = this.listNode.childNodes[index - 1] || this.listNode.lastChild;
break;
case 'Tab':
if (e.shiftKey) {
element = this.listNode.childNodes[index - 1] || this.listNode.lastChild;
} else {
element = this.listNode.childNodes[index + 1] || this.listNode.firstChild;
}
break;
case 'Home':
element = this.listNode.firstChild;
break;
case 'End':
element = this.listNode.lastChild;
break;
}
if (element) {
element.focus();
e.preventDefault();
e.stopPropagation();
}
};
handleSearchKeyDown = e => {
const { onChange, onClose } = this.props;
const { searchValue } = this.state;
let element = null;
switch(e.key) {
case 'Tab':
case 'ArrowDown':
element = this.listNode.firstChild;
if (element) {
element.focus();
e.preventDefault();
e.stopPropagation();
}
break;
case 'Enter':
element = this.listNode.firstChild;
if (element) {
onChange(element.getAttribute('data-index'));
onClose();
}
break;
case 'Escape':
if (searchValue !== '') {
e.preventDefault();
this.handleClear();
}
break;
}
};
handleClear = () => {
this.setState({ searchValue: '' });
};
renderItem = lang => {
const { value } = this.props;
return (
<div key={lang[0]} role='option' tabIndex={0} data-index={lang[0]} className={classNames('language-dropdown__dropdown__results__item', { active: lang[0] === value })} aria-selected={lang[0] === value} onClick={this.handleClick} onKeyDown={this.handleKeyDown}>
<span className='language-dropdown__dropdown__results__item__native-name' lang={lang[0]}>{lang[2]}</span> <span className='language-dropdown__dropdown__results__item__common-name'>({lang[1]})</span>
</div>
);
};
render () {
const { intl } = this.props;
const { searchValue } = this.state;
const isSearching = searchValue !== '';
const results = this.search();
return (
<div ref={this.setRef}>
<div className='emoji-mart-search'>
<input type='search' value={searchValue} onChange={this.handleSearchChange} onKeyDown={this.handleSearchKeyDown} placeholder={intl.formatMessage(messages.search)} />
<button type='button' className='emoji-mart-search-icon' disabled={!isSearching} aria-label={intl.formatMessage(messages.clear)} onClick={this.handleClear}><Icon icon={!isSearching ? SearchIcon : CancelIcon} /></button>
</div>
<div className='language-dropdown__dropdown__results emoji-mart-scroll' role='listbox' ref={this.setListRef}>
{results.map(this.renderItem)}
</div>
</div>
);
}
}
class LanguageDropdown extends PureComponent {
static propTypes = {
value: PropTypes.string,
frequentlyUsedLanguages: PropTypes.arrayOf(PropTypes.string),
guess: PropTypes.string,
intl: PropTypes.object.isRequired,
onChange: PropTypes.func,
};
state = {
open: false,
placement: 'bottom',
};
handleToggle = () => {
if (this.state.open && this.activeElement) {
this.activeElement.focus({ preventScroll: true });
}
this.setState({ open: !this.state.open });
};
handleClose = () => {
if (this.state.open && this.activeElement) {
this.activeElement.focus({ preventScroll: true });
}
this.setState({ open: false });
};
handleChange = value => {
const { onChange } = this.props;
onChange(value);
};
setTargetRef = c => {
this.target = c;
};
findTarget = () => {
return this.target;
};
handleOverlayEnter = (state) => {
this.setState({ placement: state.placement });
};
render () {
const { value, guess, intl, frequentlyUsedLanguages } = this.props;
const { open, placement } = this.state;
const current = preloadedLanguages.find(lang => lang[0] === value) ?? [];
return (
<div ref={this.setTargetRef} onKeyDown={this.handleKeyDown}>
<button
type='button'
title={intl.formatMessage(messages.changeLanguage)}
aria-expanded={open}
onClick={this.handleToggle}
onMouseDown={this.handleMouseDown}
onKeyDown={this.handleButtonKeyDown}
className={classNames('dropdown-button', { active: open, warning: guess !== '' && guess !== value })}
>
<Icon icon={TranslateIcon} />
<span className='dropdown-button__label'>{current[2] ?? value}</span>
</button>
<Overlay show={open} offset={[5, 5]} placement={placement} flip target={this.findTarget} popperConfig={{ strategy: 'fixed', onFirstUpdate: this.handleOverlayEnter }}>
{({ props, placement }) => (
<div {...props}>
<div className={`dropdown-animation language-dropdown__dropdown ${placement}`} >
<LanguageDropdownMenu
value={value}
guess={guess}
frequentlyUsedLanguages={frequentlyUsedLanguages}
onClose={this.handleClose}
onChange={this.handleChange}
intl={intl}
/>
</div>
</div>
)}
</Overlay>
</div>
);
}
}
export default injectIntl(LanguageDropdown);

View File

@ -0,0 +1,427 @@
import { useCallback, useRef, useState, useEffect, useMemo } from 'react';
import { useIntl, defineMessages } from 'react-intl';
import classNames from 'classnames';
import { createSelector } from '@reduxjs/toolkit';
import { Map as ImmutableMap } from 'immutable';
import fuzzysort from 'fuzzysort';
import Overlay from 'react-overlays/Overlay';
import type { State, Placement } from 'react-overlays/usePopper';
import CancelIcon from '@/material-icons/400-24px/cancel-fill.svg?react';
import SearchIcon from '@/material-icons/400-24px/search.svg?react';
import TranslateIcon from '@/material-icons/400-24px/translate.svg?react';
import { changeComposeLanguage } from 'mastodon/actions/compose';
import { Icon } from 'mastodon/components/icon';
import { languages as preloadedLanguages } from 'mastodon/initial_state';
import type { RootState } from 'mastodon/store';
import { useAppSelector, useAppDispatch } from 'mastodon/store';
import { debouncedGuess } from '../util/language_detection';
const messages = defineMessages({
changeLanguage: {
id: 'compose.language.change',
defaultMessage: 'Change language',
},
search: {
id: 'compose.language.search',
defaultMessage: 'Search languages...',
},
clear: { id: 'emoji_button.clear', defaultMessage: 'Clear' },
});
type Language = [string, string, string];
const getFrequentlyUsedLanguages = createSelector(
[
(state: RootState) =>
(state.settings as ImmutableMap<string, unknown>).get(
'frequentlyUsedLanguages',
ImmutableMap(),
) as ImmutableMap<string, number>,
],
(languageCounters) =>
languageCounters
.keySeq()
.sort(
(a, b) =>
(languageCounters.get(a) ?? 0) - (languageCounters.get(b) ?? 0),
)
.reverse()
.toArray(),
);
const LanguageDropdownMenu: React.FC<{
value: string;
guess?: string;
onClose: () => void;
onChange: (arg0: string) => void;
}> = ({ value, guess, onClose, onChange }) => {
const languages = preloadedLanguages as Language[];
const intl = useIntl();
const [searchValue, setSearchValue] = useState('');
const nodeRef = useRef<HTMLDivElement>(null);
const listNodeRef = useRef<HTMLDivElement>(null);
const frequentlyUsedLanguages = useAppSelector(getFrequentlyUsedLanguages);
const handleSearchChange = useCallback(
({ target }: React.ChangeEvent<HTMLInputElement>) => {
setSearchValue(target.value);
},
[setSearchValue],
);
const handleClick = useCallback(
(e: React.MouseEvent | React.KeyboardEvent) => {
const value = e.currentTarget.getAttribute('data-index');
if (!value) {
return;
}
e.preventDefault();
onClose();
onChange(value);
},
[onClose, onChange],
);
const handleKeyDown = useCallback(
(e: React.KeyboardEvent) => {
if (!listNodeRef.current) {
return;
}
const index = Array.from(listNodeRef.current.childNodes).findIndex(
(node) => node === e.currentTarget,
);
let element = null;
switch (e.key) {
case 'Escape':
onClose();
break;
case ' ':
case 'Enter':
handleClick(e);
break;
case 'ArrowDown':
element =
listNodeRef.current.childNodes[index + 1] ??
listNodeRef.current.firstChild;
break;
case 'ArrowUp':
element =
listNodeRef.current.childNodes[index - 1] ??
listNodeRef.current.lastChild;
break;
case 'Tab':
if (e.shiftKey) {
element =
listNodeRef.current.childNodes[index - 1] ??
listNodeRef.current.lastChild;
} else {
element =
listNodeRef.current.childNodes[index + 1] ??
listNodeRef.current.firstChild;
}
break;
case 'Home':
element = listNodeRef.current.firstChild;
break;
case 'End':
element = listNodeRef.current.lastChild;
break;
}
if (element && element instanceof HTMLElement) {
element.focus();
e.preventDefault();
e.stopPropagation();
}
},
[onClose, handleClick],
);
const handleSearchKeyDown = useCallback(
(e: React.KeyboardEvent) => {
let element = null;
if (!listNodeRef.current) {
return;
}
switch (e.key) {
case 'Tab':
case 'ArrowDown':
element = listNodeRef.current.firstChild;
if (element && element instanceof HTMLElement) {
element.focus();
e.preventDefault();
e.stopPropagation();
}
break;
case 'Enter':
element = listNodeRef.current.firstChild;
if (element && element instanceof HTMLElement) {
const value = element.getAttribute('data-index');
if (value) {
onChange(value);
onClose();
}
}
break;
case 'Escape':
if (searchValue !== '') {
e.preventDefault();
setSearchValue('');
}
break;
}
},
[setSearchValue, onChange, onClose, searchValue],
);
const handleClear = useCallback(() => {
setSearchValue('');
}, [setSearchValue]);
const isSearching = searchValue !== '';
useEffect(() => {
const handleDocumentClick = (e: MouseEvent) => {
if (
nodeRef.current &&
e.target instanceof HTMLElement &&
!nodeRef.current.contains(e.target)
) {
onClose();
e.stopPropagation();
}
};
document.addEventListener('click', handleDocumentClick, { capture: true });
// Because of https://github.com/react-bootstrap/react-bootstrap/issues/2614 we need
// to wait for a frame before focusing
requestAnimationFrame(() => {
if (nodeRef.current) {
const element = nodeRef.current.querySelector<HTMLInputElement>(
'input[type="search"]',
);
if (element) element.focus();
}
});
return () => {
document.removeEventListener('click', handleDocumentClick);
};
}, [onClose]);
const results = useMemo(() => {
if (searchValue === '') {
return [...languages].sort((a, b) => {
if (guess && a[0] === guess) {
// Push guessed language higher than current selection
return -1;
} else if (guess && b[0] === guess) {
return 1;
} else if (a[0] === value) {
// Push current selection to the top of the list
return -1;
} else if (b[0] === value) {
return 1;
} else {
// Sort according to frequently used languages
const indexOfA = frequentlyUsedLanguages.indexOf(a[0]);
const indexOfB = frequentlyUsedLanguages.indexOf(b[0]);
return (
(indexOfA > -1 ? indexOfA : Infinity) -
(indexOfB > -1 ? indexOfB : Infinity)
);
}
});
}
return fuzzysort
.go(searchValue, languages, {
keys: ['0', '1', '2'],
limit: 5,
threshold: -10000,
})
.map((result) => result.obj);
}, [searchValue, languages, guess, frequentlyUsedLanguages, value]);
return (
<div ref={nodeRef}>
<div className='emoji-mart-search'>
<input
type='search'
value={searchValue}
onChange={handleSearchChange}
onKeyDown={handleSearchKeyDown}
placeholder={intl.formatMessage(messages.search)}
/>
<button
type='button'
className='emoji-mart-search-icon'
disabled={!isSearching}
aria-label={intl.formatMessage(messages.clear)}
onClick={handleClear}
>
<Icon id='' icon={!isSearching ? SearchIcon : CancelIcon} />
</button>
</div>
<div
className='language-dropdown__dropdown__results emoji-mart-scroll'
role='listbox'
ref={listNodeRef}
>
{results.map((lang) => (
<div
key={lang[0]}
role='option'
tabIndex={0}
data-index={lang[0]}
className={classNames(
'language-dropdown__dropdown__results__item',
{ active: lang[0] === value },
)}
aria-selected={lang[0] === value}
onClick={handleClick}
onKeyDown={handleKeyDown}
>
<span
className='language-dropdown__dropdown__results__item__native-name'
lang={lang[0]}
>
{lang[2]}
</span>{' '}
<span className='language-dropdown__dropdown__results__item__common-name'>
({lang[1]})
</span>
</div>
))}
</div>
</div>
);
};
export const LanguageDropdown: React.FC = () => {
const [open, setOpen] = useState(false);
const [placement, setPlacement] = useState<Placement | undefined>('bottom');
const [guess, setGuess] = useState('');
const activeElementRef = useRef<HTMLElement | null>(null);
const targetRef = useRef(null);
const intl = useIntl();
const dispatch = useAppDispatch();
const value = useAppSelector(
(state) => state.compose.get('language') as string,
);
const text = useAppSelector((state) => state.compose.get('text') as string);
const current =
(preloadedLanguages as Language[]).find((lang) => lang[0] === value) ?? [];
const handleMouseDown = useCallback(() => {
if (!open && document.activeElement instanceof HTMLElement) {
activeElementRef.current = document.activeElement;
}
}, [open]);
const handleToggle = useCallback(() => {
if (open && activeElementRef.current)
activeElementRef.current.focus({ preventScroll: true });
setOpen(!open);
}, [open, setOpen]);
const handleClose = useCallback(() => {
if (open && activeElementRef.current)
activeElementRef.current.focus({ preventScroll: true });
setOpen(false);
}, [open, setOpen]);
const handleChange = useCallback(
(value: string) => {
dispatch(changeComposeLanguage(value));
},
[dispatch],
);
const handleOverlayEnter = useCallback(
(state: Partial<State>) => {
setPlacement(state.placement);
},
[setPlacement],
);
useEffect(() => {
if (text.length > 20) {
debouncedGuess(text, setGuess);
} else {
setGuess('');
}
}, [text, setGuess]);
return (
<div ref={targetRef}>
<button
type='button'
title={intl.formatMessage(messages.changeLanguage)}
aria-expanded={open}
onClick={handleToggle}
onMouseDown={handleMouseDown}
className={classNames('dropdown-button', {
active: open,
warning: guess !== '' && guess !== value,
})}
>
<Icon id='' icon={TranslateIcon} />
<span className='dropdown-button__label'>{current[2] ?? value}</span>
</button>
<Overlay
show={open}
offset={[5, 5]}
placement={placement}
flip
target={targetRef}
popperConfig={{ strategy: 'fixed', onFirstUpdate: handleOverlayEnter }}
>
{({ props, placement }) => (
<div {...props}>
<div
className={`dropdown-animation language-dropdown__dropdown ${placement}`}
>
<LanguageDropdownMenu
value={value}
guess={guess}
onClose={handleClose}
onChange={handleChange}
/>
</div>
</div>
)}
</Overlay>
</div>
);
};

View File

@ -1,23 +1,7 @@
import { createSelector } from '@reduxjs/toolkit';
import { Map as ImmutableMap } from 'immutable';
import { connect } from 'react-redux';
import lande from 'lande';
import { debounce } from 'lodash';
import { changeComposeLanguage } from 'mastodon/actions/compose';
import LanguageDropdown from '../components/language_dropdown';
import { urlRegex } from '../util/url_regex';
const getFrequentlyUsedLanguages = createSelector([
state => state.getIn(['settings', 'frequentlyUsedLanguages'], ImmutableMap()),
], languageCounters => (
languageCounters.keySeq()
.sort((a, b) => languageCounters.get(a) - languageCounters.get(b))
.reverse()
.toArray()
));
import { urlRegex } from './url_regex';
const ISO_639_MAP = {
afr: 'af', // Afrikaans
@ -72,47 +56,21 @@ const ISO_639_MAP = {
vie: 'vi', // Vietnamese
};
const debouncedLande = debounce((text) => {
const guessLanguage = (text) => {
text = text
.replace(urlRegex, '')
.replace(/(^|[^/\w])@(([a-z0-9_]+)@[a-z0-9.-]+[a-z0-9]+)/ig, '');
if (text.length <= 20)
return undefined;
return lande(text);
}, 500, { trailing: true });
const detectedLanguage = createSelector([
state => state.getIn(['compose', 'text']),
], text => {
if (text.length > 20) {
const guesses = debouncedLande(text);
if (!guesses)
return '';
const [lang, confidence] = guesses[0];
if (confidence > 0.8) {
const [lang, confidence] = lande(text)[0];
if (confidence > 0.8)
return ISO_639_MAP[lang];
}
}
return '';
});
};
const mapStateToProps = state => ({
frequentlyUsedLanguages: getFrequentlyUsedLanguages(state),
value: state.getIn(['compose', 'language']),
guess: detectedLanguage(state),
});
const mapDispatchToProps = dispatch => ({
onChange (value) {
dispatch(changeComposeLanguage(value));
},
});
export default connect(mapStateToProps, mapDispatchToProps)(LanguageDropdown);
export const debouncedGuess = debounce((text, setGuess) => {
setGuess(guessLanguage(text));
}, 500, { leading: true, trailing: true });

View File

@ -55,11 +55,11 @@ export const Card = ({ id, source }) => {
</div>
<div className='explore__suggestions__card__body'>
<Link to={`/@${account.get('acct')}`}><Avatar account={account} size={48} /></Link>
<Link to={`/@${account.get('acct')}`} data-hover-card-account={account.id}><Avatar account={account} size={48} /></Link>
<div className='explore__suggestions__card__body__main'>
<div className='explore__suggestions__card__body__main__name-button'>
<Link className='explore__suggestions__card__body__main__name-button__name' to={`/@${account.get('acct')}`}><DisplayName account={account} /></Link>
<Link className='explore__suggestions__card__body__main__name-button__name' to={`/@${account.get('acct')}`} data-hover-card-account={account.id}><DisplayName account={account} /></Link>
<IconButton iconComponent={CloseIcon} onClick={handleDismiss} title={intl.formatMessage(messages.dismiss)} />
<FollowButton accountId={account.get('id')} />
</div>

View File

@ -145,13 +145,13 @@ const Card: React.FC<{
/>
<div className='inline-follow-suggestions__body__scrollable__card__avatar'>
<Link to={`/@${account?.acct}`}>
<Link to={`/@${account?.acct}`} data-hover-card-account={account?.id}>
<Avatar account={account} size={72} />
</Link>
</div>
<div className='inline-follow-suggestions__body__scrollable__card__text-stack'>
<Link to={`/@${account?.acct}`}>
<Link to={`/@${account?.acct}`} data-hover-card-account={account?.id}>
<DisplayName account={account} />
</Link>
{firstVerifiedField ? (

View File

@ -85,6 +85,7 @@
"alert.unexpected.message": "لقد طرأ خطأ غير متوقّع.",
"alert.unexpected.title": "المعذرة!",
"alt_text_badge.title": "نص بديل",
"alt_text_modal.cancel": "إلغاء",
"announcement.announcement": "إعلان",
"annual_report.summary.archetype.booster": "The cool-hunter",
"attachments_list.unprocessed": "(غير معالَج)",
@ -120,13 +121,16 @@
"column.blocks": "المُستَخدِمون المَحظورون",
"column.bookmarks": "الفواصل المرجعية",
"column.community": "الخيط الزمني المحلي",
"column.create_list": "إنشاء القائمة",
"column.direct": "الإشارات الخاصة",
"column.directory": "تَصَفُّحُ المَلفات الشخصية",
"column.domain_blocks": "النطاقات المحظورة",
"column.edit_list": "تعديل القائمة",
"column.favourites": "المفضلة",
"column.firehose": "الموجزات الحية",
"column.follow_requests": "طلبات المتابعة",
"column.home": "الرئيسية",
"column.list_members": "إدارة أعضاء القائمة",
"column.lists": "القوائم",
"column.mutes": "المُستَخدِمون المَكتومون",
"column.notifications": "الإشعارات",
@ -139,6 +143,7 @@
"column_header.pin": "تثبيت",
"column_header.show_settings": "إظهار الإعدادات",
"column_header.unpin": "إلغاء التَّثبيت",
"column_search.cancel": "إلغاء",
"column_subheading.settings": "الإعدادات",
"community.column_settings.local_only": "المحلي فقط",
"community.column_settings.media_only": "الوسائط فقط",
@ -157,6 +162,7 @@
"compose_form.poll.duration": "مُدَّة اِستطلاع الرأي",
"compose_form.poll.multiple": "متعدد الخيارات",
"compose_form.poll.option_placeholder": "الخيار {number}",
"compose_form.poll.single": "خيار واحد",
"compose_form.poll.switch_to_multiple": "تغيِير الاستطلاع للسماح باِخيارات مُتعدِّدة",
"compose_form.poll.switch_to_single": "تغيِير الاستطلاع للسماح باِخيار واحد فقط",
"compose_form.poll.type": "الطراز",
@ -195,6 +201,7 @@
"confirmations.unfollow.title": "إلغاء متابعة المستخدم؟",
"content_warning.hide": "إخفاء المنشور",
"content_warning.show": "إظهار على أي حال",
"content_warning.show_more": "إظهار المزيد",
"conversation.delete": "احذف المحادثة",
"conversation.mark_as_read": "اعتبرها كمقروءة",
"conversation.open": "اعرض المحادثة",
@ -325,6 +332,7 @@
"footer.privacy_policy": "سياسة الخصوصية",
"footer.source_code": "الاطلاع على الشفرة المصدرية",
"footer.status": "الحالة",
"footer.terms_of_service": "شروط الخدمة",
"generic.saved": "تم الحفظ",
"getting_started.heading": "استعدّ للبدء",
"hashtag.column_header.tag_mode.all": "و {additional}",
@ -358,6 +366,7 @@
"ignore_notifications_modal.ignore": "تجاهل الإشعارات",
"ignore_notifications_modal.limited_accounts_title": "تجاهل الإشعارات من الحسابات التي هي تحت الإشراف؟",
"ignore_notifications_modal.new_accounts_title": "تجاهل الإشعارات الصادرة من الحسابات الجديدة؟",
"interaction_modal.no_account_yet": "لا تملك حساباً بعد؟",
"interaction_modal.on_another_server": "على خادم مختلف",
"interaction_modal.on_this_server": "على هذا الخادم",
"interaction_modal.title.favourite": "إضافة منشور {name} إلى المفضلة",
@ -408,11 +417,21 @@
"limited_account_hint.title": "تم إخفاء هذا الملف الشخصي من قبل مشرفي {domain}.",
"link_preview.author": "مِن {name}",
"link_preview.more_from_author": "المزيد من {name}",
"lists.add_member": "إضافة",
"lists.add_to_list": "إضافة إلى القائمة",
"lists.add_to_lists": "إضافة {name} إلى القوائم",
"lists.create": "إنشاء",
"lists.create_list": "إنشاء قائمة",
"lists.delete": "احذف القائمة",
"lists.done": "تمّ",
"lists.edit": "عدّل القائمة",
"lists.exclusive": "إخفاء الأعضاء في الصفحة الرئيسية",
"lists.remove_member": "إزالة",
"lists.replies_policy.followed": "أي مستخدم متابَع",
"lists.replies_policy.list": "أعضاء القائمة",
"lists.replies_policy.none": "لا أحد",
"lists.save": "حفظ",
"lists.search": "بحث",
"load_pending": "{count, plural, one {# عنصر جديد} other {# عناصر جديدة}}",
"loading_indicator.label": "جاري التحميل…",
"media_gallery.hide": "إخفاء",
@ -464,7 +483,7 @@
"notification.label.private_reply": "رد خاص",
"notification.label.reply": "ردّ",
"notification.mention": "إشارة",
"notification.mentioned_you": "{name} mentioned you",
"notification.mentioned_you": "أشارَ إليك {name}",
"notification.moderation-warning.learn_more": "اعرف المزيد",
"notification.moderation_warning": "لقد تلقيت تحذيرًا بالإشراف",
"notification.moderation_warning.action_delete_statuses": "تم حذف بعض من منشوراتك.",
@ -740,6 +759,7 @@
"subscribed_languages.target": "تغيير اللغات المشتركة لـ {target}",
"tabs_bar.home": "الرئيسية",
"tabs_bar.notifications": "الإشعارات",
"terms_of_service.title": "شروط الخدمة",
"time_remaining.days": "{number, plural, one {# يوم} other {# أيام}} متبقية",
"time_remaining.hours": "{number, plural, one {# ساعة} other {# ساعات}} متبقية",
"time_remaining.minutes": "{number, plural, one {# دقيقة} other {# دقائق}} متبقية",

View File

@ -86,6 +86,13 @@
"alert.unexpected.message": "Възникна неочаквана грешка.",
"alert.unexpected.title": "Опаа!",
"alt_text_badge.title": "Алтернативен текст",
"alt_text_modal.add_alt_text": "Добавяне на алтернативен текст",
"alt_text_modal.add_text_from_image": "Добавяне на текст от образ",
"alt_text_modal.cancel": "Отказ",
"alt_text_modal.change_thumbnail": "Промяна на миниобраза",
"alt_text_modal.describe_for_people_with_hearing_impairments": "Опишете това за хора със слухови увреждания…",
"alt_text_modal.describe_for_people_with_visual_impairments": "Опишете това за хора със зрителни увреждания…",
"alt_text_modal.done": "Готово",
"announcement.announcement": "Оповестяване",
"annual_report.summary.archetype.booster": "Якият подсилвател",
"annual_report.summary.archetype.lurker": "Дебнещото",
@ -407,6 +414,8 @@
"ignore_notifications_modal.not_followers_title": "Пренебрегвате ли известията от хора, които не са ви последвали?",
"ignore_notifications_modal.not_following_title": "Пренебрегвате ли известията от хора, които не сте последвали?",
"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.favourite": "Трябва да направите любимо от акаунта си, за да продължите.",
"interaction_modal.action.follow": "Трябва да последвате от акаунта си, за да продължите.",
"interaction_modal.action.reblog": "Трябва да разпространите нечий блог от акаунта си, за да продължите.",

View File

@ -90,8 +90,8 @@
"alt_text_modal.add_text_from_image": "Afegiu text d'una imatge",
"alt_text_modal.cancel": "Cancel·la",
"alt_text_modal.change_thumbnail": "Canvia la miniatura",
"alt_text_modal.describe_for_people_with_hearing_impairments": "Descriu això per a persones amb problemes d'audició…",
"alt_text_modal.describe_for_people_with_visual_impairments": "Descriu això per a persones amb problemes visuals…",
"alt_text_modal.describe_for_people_with_hearing_impairments": "Descriviu això per a persones amb problemes d'audició…",
"alt_text_modal.describe_for_people_with_visual_impairments": "Descriviu això per a persones amb problemes visuals…",
"alt_text_modal.done": "Fet",
"announcement.announcement": "Anunci",
"annual_report.summary.archetype.booster": "Sempre a la moda",
@ -414,6 +414,7 @@
"ignore_notifications_modal.not_followers_title": "Voleu ignorar les notificacions de qui no us segueix?",
"ignore_notifications_modal.not_following_title": "Voleu ignorar les notificacions de qui no seguiu?",
"ignore_notifications_modal.private_mentions_title": "Voleu ignorar les notificacions de mencions privades no sol·licitades?",
"info_button.label": "Ajuda",
"interaction_modal.action.favourite": "Per a continuar heu d'afavorir des del vostre compte.",
"interaction_modal.action.follow": "Per a continuar heu de seguir des del vostre compte.",
"interaction_modal.action.reblog": "Per a continuar heu d'impulsar des del vostre compte.",

View File

@ -414,6 +414,8 @@
"ignore_notifications_modal.not_followers_title": "Ignorér notifikationer fra folk, som ikke er følgere?",
"ignore_notifications_modal.not_following_title": "Ignorér notifikationer fra folk, man ikke følger?",
"ignore_notifications_modal.private_mentions_title": "Ignorér notifikationer fra uopfordrede Private omtaler?",
"info_button.label": "Hjælp",
"info_button.what_is_alt_text": "<h1>Hvad er alt-tekst?</h1> <p>Alt-tekst leverer billedbeskrivelser til folk med synsnedsættelser, lav båndbredde-forbindelser eller med ønske om ekstra kontekst.</p> <p>Tilgængelighed og forståelse kan forbedres for alle ved at skrive klar, kortfattet og objektiv alt-tekst.</p> <ul> <li>Fang vigtige elementer</li> <li>Opsummér tekst i billeder</li> <li>Brug almindelig sætningsstruktur</li> <li>Undgå overflødig information</li> <li>Fokusér på tendenser og centrale resultater i kompleks grafik (såsom diagrammer eller kort)</li> </ul>",
"interaction_modal.action.favourite": "For at fortsætte, skal man vælge Gør til favorit fra sin konto.",
"interaction_modal.action.follow": "For at fortsætte, skal man vælge Følg fra sin konto.",
"interaction_modal.action.reblog": "For at fortsætte, skal man vælge Genblog fra sin konto.",

View File

@ -4,7 +4,7 @@
"about.disclaimer": "Mastodon ist eine freie, quelloffene Software und eine Marke der Mastodon gGmbH.",
"about.domain_blocks.no_reason_available": "Grund unbekannt",
"about.domain_blocks.preamble": "Mastodon erlaubt es dir grundsätzlich, alle Inhalte von allen Nutzer*innen auf allen Servern im Fediverse zu sehen und mit ihnen zu interagieren. Für diesen Server gibt es aber ein paar Ausnahmen.",
"about.domain_blocks.silenced.explanation": "Alle Inhalte und Profile dieses Servers werden zunächst nicht angezeigt. Du kannst die Profile und Inhalte aber dennoch sehen, wenn du explizit nach diesen suchst oder diesen folgst.",
"about.domain_blocks.silenced.explanation": "Standardmäßig werden von diesem Server keine Inhalte oder Profile angezeigt. Du kannst die Profile und Inhalte aber dennoch sehen, wenn du explizit nach diesen suchst oder diesen folgst.",
"about.domain_blocks.silenced.title": "Stummgeschaltet",
"about.domain_blocks.suspended.explanation": "Es werden keine Daten von diesem Server verarbeitet, gespeichert oder ausgetauscht, sodass eine Interaktion oder Kommunikation mit Nutzer*innen dieses Servers nicht möglich ist.",
"about.domain_blocks.suspended.title": "Gesperrt",
@ -42,8 +42,8 @@
"account.hide_reblogs": "Geteilte Beiträge von @{name} ausblenden",
"account.in_memoriam": "Zum Andenken.",
"account.joined_short": "Mitglied seit",
"account.languages": "Ausgewählte Sprachen ändern",
"account.link_verified_on": "Das Profil mit dieser E-Mail-Adresse wurde bereits am {date} bestätigt",
"account.languages": "Sprache ändern.",
"account.link_verified_on": "Das Profil mit dieser E-Mail-Adresse wurde bereits am {date} verifiziert",
"account.locked_info": "Die Privatsphäre dieses Kontos wurde auf „geschützt“ gesetzt. Die Person bestimmt manuell, wer ihrem Profil folgen darf.",
"account.media": "Medien",
"account.mention": "@{name} erwähnen",
@ -63,7 +63,7 @@
"account.share": "Profil von @{name} teilen",
"account.show_reblogs": "Geteilte Beiträge von @{name} anzeigen",
"account.statuses_counter": "{count, plural, one {{counter} Beitrag} other {{counter} Beiträge}}",
"account.unblock": "Blockierung von @{name} aufheben",
"account.unblock": "{name} nicht mehr blockieren",
"account.unblock_domain": "Blockierung von {domain} aufheben",
"account.unblock_short": "Blockierung aufheben",
"account.unendorse": "Im Profil nicht mehr empfehlen",
@ -72,12 +72,12 @@
"account.unmute_notifications_short": "Stummschaltung der Benachrichtigungen aufheben",
"account.unmute_short": "Stummschaltung aufheben",
"account_note.placeholder": "Klicken, um Notiz hinzuzufügen",
"admin.dashboard.daily_retention": "Verweildauer der Benutzer*innen pro Tag nach der Registrierung",
"admin.dashboard.monthly_retention": "Verweildauer der Benutzer*innen pro Monat nach der Registrierung",
"admin.dashboard.daily_retention": "Verweildauer der Nutzer*innen pro Tag nach der Registrierung",
"admin.dashboard.monthly_retention": "Verweildauer der Nutzer*innen pro Monat nach der Registrierung",
"admin.dashboard.retention.average": "Durchschnitt",
"admin.dashboard.retention.cohort": "Monat der Registrierung",
"admin.dashboard.retention.cohort_size": "Neue Konten",
"admin.impact_report.instance_accounts": "Kontenprofile, die dadurch gelöscht würden",
"admin.impact_report.instance_accounts": "Profilkonten, die dadurch gelöscht würden",
"admin.impact_report.instance_followers": "Follower, die unsere Nutzer*innen verlieren würden",
"admin.impact_report.instance_follows": "Follower, die deren Nutzer*innen verlieren würden",
"admin.impact_report.title": "Zusammenfassung der Auswirkung",
@ -414,6 +414,8 @@
"ignore_notifications_modal.not_followers_title": "Benachrichtigungen von Profilen ignorieren, die dir nicht folgen?",
"ignore_notifications_modal.not_following_title": "Benachrichtigungen von Profilen ignorieren, denen du nicht folgst?",
"ignore_notifications_modal.private_mentions_title": "Benachrichtigungen von unerwünschten privaten Erwähnungen ignorieren?",
"info_button.label": "Hilfe",
"info_button.what_is_alt_text": "<h1>Was ist Alt-Text?</h1> <p>Alt-Text bietet Bildbeschreibungen für Personen mit einer Sehschwäche, einer schlechten Internetverbindung und für alle, die zusätzlichen Kontext möchten.</p> <p>Du kannst die Zugänglichkeit und die Verständlichkeit für alle verbessern, indem du eine klare, genaue und objektive Bildbeschreibung hinzufügst.</p> <ul> <li>Erfasse wichtige Elemente</li> <li>Fasse Text in Bildern zusammen</li> <li>Verwende einen korrekten Satzbau</li> <li>Vermeide unwichtige Informationen</li> <li>Konzentriere dich bei komplexen Darstellungen (z. B. Diagramme oder Karten) auf Trends und wichtige Erkenntnisse</li> </ul>",
"interaction_modal.action.favourite": "Du musst von deinem Konto aus favorisieren, um fortzufahren.",
"interaction_modal.action.follow": "Du musst von deinem Konto aus folgen, um fortzufahren.",
"interaction_modal.action.reblog": "Du musst von deinem Konto aus teilen, um fortzufahren.",

View File

@ -86,6 +86,13 @@
"alert.unexpected.message": "Προέκυψε απροσδόκητο σφάλμα.",
"alert.unexpected.title": "Ουπς!",
"alt_text_badge.title": "Εναλλακτικό κείμενο",
"alt_text_modal.add_alt_text": "Προσθήκη εναλλακτικού κειμένου",
"alt_text_modal.add_text_from_image": "Προσθήκη κειμένου από εικόνα",
"alt_text_modal.cancel": "Ακύρωση",
"alt_text_modal.change_thumbnail": "Αλλαγή μικρογραφίας",
"alt_text_modal.describe_for_people_with_hearing_impairments": "Περιέγραψε αυτό για άτομα με προβλήματα ακοής…",
"alt_text_modal.describe_for_people_with_visual_impairments": "Περιέγραψε αυτό για άτομα με προβλήματα όρασης…",
"alt_text_modal.done": "Ολοκληρώθηκε",
"announcement.announcement": "Ανακοίνωση",
"annual_report.summary.archetype.booster": "Ο κυνηγός των φοβερών",
"annual_report.summary.archetype.lurker": "Ο διακριτικός",
@ -407,6 +414,8 @@
"ignore_notifications_modal.not_followers_title": "Αγνόηση ειδοποιήσεων από άτομα που δε σας ακολουθούν;",
"ignore_notifications_modal.not_following_title": "Αγνόηση ειδοποιήσεων από άτομα που δεν ακολουθείς;",
"ignore_notifications_modal.private_mentions_title": "Αγνόηση ειδοποιήσεων από μη ζητηθείσες ιδιωτικές αναφορές;",
"info_button.label": "Βοήθεια",
"info_button.what_is_alt_text": "Το εναλλακτικό κείμενο παρέχει περιγραφές εικόνας για άτομα με προβλήματα όρασης, διαδικτυακές συνδέσεις χαμηλής ταχύτητας ή για άτομα που αναζητούν επιπλέον περιεχόμενο.\\n\\nΜπορείς να βελτιώσεις την προσβασιμότητα και την κατανόηση για όλους, γράφοντας σαφές, συνοπτικό και αντικειμενικό εναλλακτικό κείμενο.\\n\\n<ul><li>Κατέγραψε σημαντικά στοιχεία</li>\\n<li>Συνόψισε το κείμενο στις εικόνες</li>\\n<li>Χρησιμοποίησε δομή κανονικής πρότασης</li>\\n<li>Απέφυγε περιττές πληροφορίες</li>\\n<li>Εστίασε στις τάσεις και τα βασικά ευρήματα σε σύνθετα οπτικά στοιχεία (όπως διαγράμματα ή χάρτες)</li></ul>",
"interaction_modal.action.favourite": "Για να συνεχίσεις, θα πρέπει να αγαπήσεις από τον λογαριασμό σου.",
"interaction_modal.action.follow": "Για να συνεχίσεις, θα πρέπει να ακολουθήσεις από τον λογαριασμό σου.",
"interaction_modal.action.reblog": "Για να συνεχίσεις, θα πρέπει να αναδημοσιεύσεις από τον λογαριασμό σου.",
@ -457,6 +466,7 @@
"keyboard_shortcuts.toggle_hidden": "Εμφάνιση/απόκρυψη κειμένου πίσω από το CW",
"keyboard_shortcuts.toggle_sensitivity": "Εμφάνιση/απόκρυψη πολυμέσων",
"keyboard_shortcuts.toot": "Δημιουργία νέας ανάρτησης",
"keyboard_shortcuts.translate": "να μεταφράσει μια δημοσίευση",
"keyboard_shortcuts.unfocus": "Αποεστίαση του πεδίου σύνθεσης/αναζήτησης",
"keyboard_shortcuts.up": "Μετακίνηση προς τα πάνω στη λίστα",
"lightbox.close": "Κλείσιμο",
@ -836,6 +846,7 @@
"status.reblogs.empty": "Κανείς δεν ενίσχυσε αυτή την ανάρτηση ακόμα. Μόλις το κάνει κάποιος, θα εμφανιστεί εδώ.",
"status.redraft": "Σβήσε & ξαναγράψε",
"status.remove_bookmark": "Αφαίρεση σελιδοδείκτη",
"status.remove_favourite": "Κατάργηση από τα αγαπημένα",
"status.replied_in_thread": "Απαντήθηκε σε νήμα",
"status.replied_to": "Απάντησε στον {name}",
"status.reply": "Απάντησε",

View File

@ -86,6 +86,13 @@
"alert.unexpected.message": "An unexpected error occurred.",
"alert.unexpected.title": "Oops!",
"alt_text_badge.title": "Alt text",
"alt_text_modal.add_alt_text": "Add alt text",
"alt_text_modal.add_text_from_image": "Add text from image",
"alt_text_modal.cancel": "Cancel",
"alt_text_modal.change_thumbnail": "Change thumbnail",
"alt_text_modal.describe_for_people_with_hearing_impairments": "Describe this for people with hearing impairments…",
"alt_text_modal.describe_for_people_with_visual_impairments": "Describe this for people with visual impairments…",
"alt_text_modal.done": "Done",
"announcement.announcement": "Announcement",
"annual_report.summary.archetype.booster": "The cool-hunter",
"annual_report.summary.archetype.lurker": "The lurker",
@ -407,6 +414,8 @@
"ignore_notifications_modal.not_followers_title": "Ignore notifications from people not following you?",
"ignore_notifications_modal.not_following_title": "Ignore notifications from people you don't follow?",
"ignore_notifications_modal.private_mentions_title": "Ignore notifications from unsolicited Private Mentions?",
"info_button.label": "Help",
"info_button.what_is_alt_text": "<h1>What is alt text?</h1> <p>Alt text provides image descriptions for people with vision impairments, low-bandwidth connections, or those seeking extra context.</p> <p>You can improve accessibility and understanding for everyone by writing clear, concise, and objective alt text.</p> <ul> <li>Capture important elements</li> <li>Summarise text in images</li> <li>Use regular sentence structure</li> <li>Avoid redundant information</li> <li>Focus on trends and key findings in complex visuals (like diagrams or maps)</li> </ul>",
"interaction_modal.action.favourite": "To continue, you need to favourite from your account.",
"interaction_modal.action.follow": "To continue, you need to follow from your account.",
"interaction_modal.action.reblog": "To continue, you need to reblog from your account.",

View File

@ -414,6 +414,8 @@
"ignore_notifications_modal.not_followers_title": "Ignore notifications from people not following you?",
"ignore_notifications_modal.not_following_title": "Ignore notifications from people you don't follow?",
"ignore_notifications_modal.private_mentions_title": "Ignore notifications from unsolicited Private Mentions?",
"info_button.label": "Help",
"info_button.what_is_alt_text": "<h1>What is alt text?</h1> <p>Alt text provides image descriptions for people with vision impairments, low-bandwidth connections, or those seeking extra context.</p> <p>You can improve accessibility and understanding for everyone by writing clear, concise, and objective alt text.</p> <ul> <li>Capture important elements</li> <li>Summarize text in images</li> <li>Use regular sentence structure</li> <li>Avoid redundant information</li> <li>Focus on trends and key findings in complex visuals (like diagrams or maps)</li> </ul>",
"interaction_modal.action.favourite": "To continue, you need to favorite from your account.",
"interaction_modal.action.follow": "To continue, you need to follow from your account.",
"interaction_modal.action.reblog": "To continue, you need to reblog from your account.",

View File

@ -414,6 +414,8 @@
"ignore_notifications_modal.not_followers_title": "Ĉu ignori sciigojn de homoj, kiuj ne sekvas vin?",
"ignore_notifications_modal.not_following_title": "Ĉu ignori sciigojn de homoj, kiujn vi ne sekvas?",
"ignore_notifications_modal.private_mentions_title": "Ĉu ignori sciigojn de nepetitaj privataj mencioj?",
"info_button.label": "Helpo",
"info_button.what_is_alt_text": "<h1>Kio estas la alternativa teksto?</h1> <p>La alternativa teksto ofertas priskribojn de la bildoj por individuoj kun vidaj malfacilaĵoj, konektoj kun malalta larĝa bando aŭ kiuj serĉas plian kuntekston.</p> <p>Vi povas plibonigi alireblecon kaj komprenon por ĉiuj per skribado de klaraj, koncizaj, kaj objektivaj alternativaj tekstoj.</p><ul><li>Kaptu gravajn elementojn.</li><li> Resumu tekston en bildoj.</li> <li>Uzu regulan frazstrukturon.</li> <li>Evitu redundan informon.</li><li>Fokusu sur tendencoj kaj ĉefaj trovoj en kompleksaj visualoj (kiel diagramoj aŭ mapoj).</li></ul>",
"interaction_modal.action.favourite": "Por daŭrigi, vi devas stelumi el via konto.",
"interaction_modal.action.follow": "Por daŭrigi, vi devas sekvi el via konto.",
"interaction_modal.action.reblog": "Por daŭrigi, vi devas diskonigi el via konto.",

View File

@ -414,6 +414,8 @@
"ignore_notifications_modal.not_followers_title": "¿Ignorar notificaciones de cuentas que no te siguen?",
"ignore_notifications_modal.not_following_title": "¿Ignorar notificaciones de cuentas a las que no seguís?",
"ignore_notifications_modal.private_mentions_title": "¿Ignorar notificaciones de menciones privadas no solicitadas?",
"info_button.label": "Ayuda",
"info_button.what_is_alt_text": "<h1>¿Qué es el texto alternativo?</h1> <p>El texto alternativo proporciona descripciones de las imágenes para personas con dificultades visuales, conexiones con escaso ancho de banda o que buscan un contexto adicional.</p> <p>Podés mejorar la accesibilidad y la comprensión para todos escribiendo un texto alternativo claro, conciso y objetivo.</p> <ul><li>Captura los elementos importantes.</li><li>Resumí el texto en imágenes.</li><li>Usá una estructura de frases normal.</li><li>Evitá la información redundante.</li><li>Focalizate en las tendencias y conclusiones clave de los elementos visuales complejos (como diagramas o mapas).</li></ul>",
"interaction_modal.action.favourite": "Para continuar, tenés que marcar como favorito desde tu cuenta.",
"interaction_modal.action.follow": "Para continuar, tenés que seguir desde tu cuenta.",
"interaction_modal.action.reblog": "Para continuar, tenés que adherir desde tu cuenta.",

View File

@ -414,6 +414,8 @@
"ignore_notifications_modal.not_followers_title": "¿Ignorar notificaciones de personas que no te siguen?",
"ignore_notifications_modal.not_following_title": "¿Ignorar notificaciones de personas a las que no sigues?",
"ignore_notifications_modal.private_mentions_title": "¿Ignorar notificaciones de menciones privadas no solicitadas?",
"info_button.label": "Ayuda",
"info_button.what_is_alt_text": "<h1>¿Qué es el texto alternativo?</h1> <p>El texto alternativo ofrece descripciones de las imágenes para individuos con dificultades visuales, conexiones de bajo ancho de banda o que buscan un contexto adicional.</p> <p>Puedes mejorar la accesibilidad y la comprensión para todos redactando un texto alternativo claro, breve y objetivo.</p> <ul><li>Captura los elementos clave.</li><li>Resume el texto en imágenes.</li><li>Utiliza una estructura de oraciones estándar.</li><li>Evita la información repetitiva.</li><li>Enfócate en las tendencias y conclusiones principales de los elementos visuales complejos (como gráficos o mapas).</li></ul>",
"interaction_modal.action.favourite": "Para continuar, debes marcar como favorito desde tu cuenta.",
"interaction_modal.action.follow": "Para continuar, debes seguir desde tu cuenta.",
"interaction_modal.action.reblog": "Para continuar, debes impulsar desde tu cuenta.",

View File

@ -414,6 +414,8 @@
"ignore_notifications_modal.not_followers_title": "¿Ignorar notificaciones de personas que no te siguen?",
"ignore_notifications_modal.not_following_title": "¿Ignorar notificaciones de personas a las que no sigues?",
"ignore_notifications_modal.private_mentions_title": "¿Ignorar notificaciones de menciones privadas no solicitadas?",
"info_button.label": "Ayuda",
"info_button.what_is_alt_text": "<h1>¿Qué es el texto alternativo?</h1> <p>El texto alternativo proporciona descripciones de las imágenes para personas con problemas de visión, conexiones con poco ancho de banda o que buscan un contexto adicional.</p> <p>Puedes mejorar la accesibilidad y la comprensión para todos escribiendo un texto alternativo claro, conciso y objetivo.</p> <ul><li>Captura los elementos importantes.</li><li>Resume el texto en imágenes.</li><li>Usa una estructura de frases normal.</li><li>Evita la información redundante.</li><li>Céntrate en las tendencias y conclusiones clave de los elementos visuales complejos (como diagramas o mapas).</li></ul>",
"interaction_modal.action.favourite": "Para continuar, tienes que marcar como favorito desde tu cuenta.",
"interaction_modal.action.follow": "Para continuar, tienes que seguir desde tu cuenta.",
"interaction_modal.action.reblog": "Para continuar, tienes que impulsar desde tu cuenta.",

View File

@ -86,6 +86,13 @@
"alert.unexpected.message": "Tekkis ootamatu viga.",
"alert.unexpected.title": "Oih!",
"alt_text_badge.title": "Alternatiivtekst",
"alt_text_modal.add_alt_text": "Lisa alt-tekst",
"alt_text_modal.add_text_from_image": "Lisa tekst pildilt",
"alt_text_modal.cancel": "Tühista",
"alt_text_modal.change_thumbnail": "Muuda pisipilti",
"alt_text_modal.describe_for_people_with_hearing_impairments": "Kirjelda seda kuulmispuudega inimeste jaoks…",
"alt_text_modal.describe_for_people_with_visual_impairments": "Kirjelda seda nägemispuudega inimeste jaoks…",
"alt_text_modal.done": "Valmis",
"announcement.announcement": "Teadaanne",
"annual_report.summary.archetype.booster": "Ägesisu küttija",
"annual_report.summary.archetype.lurker": "Hiilija",
@ -407,6 +414,8 @@
"ignore_notifications_modal.not_followers_title": "Ignoreeri inimeste teavitusi, kes sind ei jälgi?",
"ignore_notifications_modal.not_following_title": "Ignoreeri inimeste teavitusi, keda sa ei jälgi?",
"ignore_notifications_modal.private_mentions_title": "Ignoreeri soovimatute eraviisiliste mainimiste teateid?",
"info_button.label": "Abi",
"info_button.what_is_alt_text": "<h1>Mis on alt-tekst?</h1> <p>Alt-tekst pakub pildi kirjeldust nägemispuudega inimeste jaoks või neile, kel on aeglane internet või neile, kes otsivad lisaselgitust</p> <p>Saad parandada ligipääsetavust ja mõistmist kõigi jaoks, kirjutades selge, lühida ja objektiivse alt-teksti.</p> <ul> <li>Lisa tähtsad elemendid</li> <li>Tee pildil olevast tekstist kokkuvõte</li> <li>Kasuta reeglipärast lausestruktuuri</li> <li>Väldi ebaolulist infot</li> <li>Keskendu keerukate vaadete puhul (näiteks diagrammid ja kaardid) puhul trendidele ja põhiseostele</li> </ul>",
"interaction_modal.action.favourite": "Jätkamiseks pead oma konto alt lemmikuks märkima.",
"interaction_modal.action.follow": "Jätkamiseks pead oma konto alt lemmikuks märkima.",
"interaction_modal.action.reblog": "Jätkamiseks pead jagama oma konto alt.",
@ -457,6 +466,7 @@
"keyboard_shortcuts.toggle_hidden": "Näita/peida teksti hoiatuse taga",
"keyboard_shortcuts.toggle_sensitivity": "Näita/peida meediat",
"keyboard_shortcuts.toot": "Alusta uut postitust",
"keyboard_shortcuts.translate": "postituse tõlkimiseks",
"keyboard_shortcuts.unfocus": "Fookus tekstialalt/otsingult ära",
"keyboard_shortcuts.up": "Liigu loetelus üles",
"lightbox.close": "Sulge",

View File

@ -86,12 +86,18 @@
"alert.unexpected.message": "Ustekabeko errore bat gertatu da.",
"alert.unexpected.title": "Ene!",
"alt_text_badge.title": "Testu alternatiboa",
"alt_text_modal.add_alt_text": "Gehitu ordezko testua",
"alt_text_modal.add_text_from_image": "Gehitu testua iruditik",
"alt_text_modal.cancel": "Utzi",
"alt_text_modal.change_thumbnail": "Aldatu koadro txikia",
"alt_text_modal.done": "Egina",
"announcement.announcement": "Iragarpena",
"annual_report.summary.followers.followers": "jarraitzaileak",
"annual_report.summary.followers.total": "{count} guztira",
"annual_report.summary.highlighted_post.by_favourites": "egindako bidalketa gogokoena",
"annual_report.summary.highlighted_post.by_reblogs": "egindako bidalketa zabalduena",
"annual_report.summary.highlighted_post.by_replies": "erantzun gehien izan dituen bidalketa",
"annual_report.summary.highlighted_post.possessive": "{name}-(r)ena",
"annual_report.summary.most_used_app.most_used_app": "app erabiliena",
"annual_report.summary.most_used_hashtag.most_used_hashtag": "traola erabiliena",
"annual_report.summary.most_used_hashtag.none": "Bat ere ez",
@ -120,6 +126,7 @@
"bundle_column_error.routing.body": "Eskatutako orria ezin izan da aurkitu. Ziur helbide-barrako URLa zuzena dela?",
"bundle_column_error.routing.title": "404",
"bundle_modal_error.close": "Itxi",
"bundle_modal_error.message": "Zerbait okerra gertatu da pantaila hau kargatzean.",
"bundle_modal_error.retry": "Saiatu berriro",
"closed_registrations.other_server_instructions": "Mastodon deszentralizatua denez, beste kontu bat sortu dezakezu beste zerbitzari batean eta honekin komunikatu.",
"closed_registrations_modal.description": "Une honetan ezin da konturik sortu {domain} zerbitzarian, baina kontuan izan Mastodon erabiltzeko ez duzula zertan konturik izan zehazki {domain} zerbitzarian.",

View File

@ -101,7 +101,7 @@
"annual_report.summary.archetype.replier": "پاسخگو",
"annual_report.summary.followers.followers": "دنبال کننده",
"annual_report.summary.followers.total": "در مجموع {count}",
"annual_report.summary.here_it_is": "بازبینی {year}تان:",
"annual_report.summary.here_it_is": "بازبینی {year} تان:",
"annual_report.summary.highlighted_post.by_favourites": "پرپسندترین فرسته",
"annual_report.summary.highlighted_post.by_reblogs": "پرتقویت‌ترین فرسته",
"annual_report.summary.highlighted_post.by_replies": "پرپاسخ‌ترین فرسته",
@ -175,7 +175,7 @@
"community.column_settings.media_only": "فقط رسانه",
"community.column_settings.remote_only": "تنها دوردست",
"compose.language.change": "تغییر زبان",
"compose.language.search": "جست‌وجوی زبان‌ها",
"compose.language.search": "جست‌وجوی زبان‌ها...",
"compose.published.body": "فرسته منتشر شد.",
"compose.published.open": "گشودن",
"compose.saved.body": "فرسته ذخیره شد.",
@ -256,7 +256,7 @@
"domain_block_modal.they_cant_follow": "هیچ‌کسی از این کارساز نمی‌تواند پیتان بگیرد.",
"domain_block_modal.they_wont_know": "نخواهند دانست که مسدود شده‌اند.",
"domain_block_modal.title": "انسداد دامنه؟",
"domain_block_modal.you_will_lose_num_followers": "تعداد {followersCount, plural,other {{followersCount}}} پی‌گیرنده و {followingCount, plural,other {{followingCount}}} شخص پی‌گرفته شده را از دست خواهید داد.",
"domain_block_modal.you_will_lose_num_followers": "شما {followersCount, plural, one {{followersCountDisplay} پی‌گیرنده} other {{followersCountDisplay} پی‌گیرنده}} و {followingCount, plural, one {{followingCountDisplay} فرد پی‌گرفته‌شده} other {{followingCountDisplay} فرد پی‌گرفته‌شده}} را از دست خواهید داد.",
"domain_block_modal.you_will_lose_relationships": "شما تمام پیگیرکنندگان و افرادی که از این کارساز پیگیری می‌کنید را از دست خواهید داد.",
"domain_block_modal.you_wont_see_posts": "فرسته‌ها یا آگاهی‌ها از کاربران روی این کارساز را نخواهید دید.",
"domain_pill.activitypub_lets_connect": "این به شما اجازه می‌دهد تا نه تنها در ماستودون، بلکه در برنامه‌های اجتماعی مختلف نیز با افراد ارتباط برقرار کرده و تعامل داشته باشید.",
@ -304,7 +304,7 @@
"empty_column.follow_requests": "شما هنوز هیچ درخواست پی‌گیری‌ای ندارید. هنگامی که چنین درخواستی بگیرید، این‌جا نشان داده خواهد شد.",
"empty_column.followed_tags": "شما هیچ برچسبی را پی‌نگرفتید. هنگامی که برچسبی را پی‌گیری کنید اینجا نمایان می‌شوند.",
"empty_column.hashtag": "هنوز هیچ چیزی در این برچسب نیست.",
"empty_column.home": "خط زمانی خانگیتان خالی است! برای پر کردنش، افراد بیشتری را پی بگیرید. {suggestions}",
"empty_column.home": "خط زمانی خانگیتان خالی است! برای پر کردنش، افراد بیشتری را پی بگیرید.",
"empty_column.list": "هنوز چیزی در این سیاهه نیست. هنگامی که اعضایش فرسته‌های جدیدی بفرستند، این‌جا ظاهر خواهند شد.",
"empty_column.mutes": "هنوز هیچ کاربری را خموش نکرده‌اید.",
"empty_column.notification_requests": "همه چیز تمیز است! هیچ‌چیزی این‌جا نیست. هنگامی که آگاهی‌های جدیدی دریافت کنید، بسته به تنظیماتتان این‌جا ظاهر خواهند شد.",
@ -414,6 +414,8 @@
"ignore_notifications_modal.not_followers_title": "چشم‌پوشی از آگاهی‌های افرادی که پیتان نمی‌گیرند؟",
"ignore_notifications_modal.not_following_title": "چشم‌پوشی از آگاهی‌های افرادی که پیشان نمی‌گیرید؟",
"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.favourite": "برای ادامه، باید از حساب خود به دلخواه انتخاب کنید.",
"interaction_modal.action.follow": "برای ادامه، باید از حساب کاربری خود دنبال کنید.",
"interaction_modal.action.reblog": "برای ادامه، باید از حساب خود مجددا بلاگ کنید.",
@ -551,7 +553,7 @@
"notification.admin.report_statuses_other": "{name}، {target} را گزارش داد",
"notification.admin.sign_up": "{name} ثبت نام کرد",
"notification.admin.sign_up.name_and_others": "{name} و {count, plural, one {# نفر دیگر} other {# نفر دیگر}} ثبت‌نام کردند",
"notification.annual_report.message": "آمار #Wrapstodon {year}تان منتظر است! لحظه‌های به یاد ماندنی و نقاط پررنگ سال را روی ماستودون رونمایی کنید!",
"notification.annual_report.message": "آمار #Wrapstodon {year} تان منتظر است! لحظه‌های به یاد ماندنی و نقاط پررنگ سال را روی ماستودون رونمایی کنید!",
"notification.annual_report.view": "دیدن #Wrapstodon",
"notification.favourite": "{name} فرسته‌تان را برگزید",
"notification.favourite.name_and_others_with_link": "{name} و <a>{count, plural, one {# نفر دیگر} other {# نفر دیگر}}</a> فرسته‌تان را برگزیدند",
@ -799,7 +801,7 @@
"server_banner.is_one_of_many": "{domain} یکی از بسیاری از سرورهای مستقل ماستودون است که می توانید از آن برای شرکت در fediverse استفاده کنید.",
"server_banner.server_stats": "آمار کارساز:",
"sign_in_banner.create_account": "ایجاد حساب",
"sign_in_banner.follow_anyone": "هر کسی را در سراسر fediverse دنبال کنید و همه را به ترتیب زمانی ببینید. هیچ الگوریتم، تبلیغات یا طعمه کلیکی در چشم نیست.",
"sign_in_banner.follow_anyone": "هر کسی را در سراسر فدیورس دنبال کنید و همه را به ترتیب زمانی ببینید. هیچ الگوریتم، تبلیغات یا طعمه کلیکی در چشم نیست.",
"sign_in_banner.mastodon_is": "ماستودون بهترین راه برای پیگیری اتفاقات است.",
"sign_in_banner.sign_in": "ورود",
"sign_in_banner.sso_redirect": "ورود یا ثبت نام",
@ -888,7 +890,7 @@
"upload_form.drag_and_drop.on_drag_over": "پیوست رسانه {item} منتقل شد.",
"upload_form.drag_and_drop.on_drag_start": "پیوست رسانه {item} برداشته شد.",
"upload_form.edit": "ویرایش",
"upload_progress.label": "در حال بارگذاری",
"upload_progress.label": "در حال بارگذاری...",
"upload_progress.processing": "در حال پردازش…",
"username.taken": "این نام کاربری گرفته شده. نام دیگری امتحان کنید",
"video.close": "بستن ویدیو",

View File

@ -86,6 +86,13 @@
"alert.unexpected.message": "Tapahtui odottamaton virhe.",
"alert.unexpected.title": "Hups!",
"alt_text_badge.title": "Vaihtoehtoinen teksti",
"alt_text_modal.add_alt_text": "Lisää vaihtoehtoinen teksti",
"alt_text_modal.add_text_from_image": "Lisää teksti kuvasta",
"alt_text_modal.cancel": "Peruuta",
"alt_text_modal.change_thumbnail": "Vaihda pikkukuva",
"alt_text_modal.describe_for_people_with_hearing_impairments": "Kuvaile tätä kuulovammallisille ihmisille…",
"alt_text_modal.describe_for_people_with_visual_impairments": "Kuvaile tätä näkövammallisille ihmisille…",
"alt_text_modal.done": "Valmis",
"announcement.announcement": "Tiedote",
"annual_report.summary.archetype.booster": "Tehostaja",
"annual_report.summary.archetype.lurker": "Lymyilijä",
@ -407,6 +414,8 @@
"ignore_notifications_modal.not_followers_title": "Sivuutetaanko ilmoitukset käyttäjiltä, jotka eivät seuraa sinua?",
"ignore_notifications_modal.not_following_title": "Sivuutetaanko ilmoitukset käyttäjiltä, joita et seuraa?",
"ignore_notifications_modal.private_mentions_title": "Sivuutetaanko ilmoitukset pyytämättömistä yksityismaininnoista?",
"info_button.label": "Ohje",
"info_button.what_is_alt_text": "<h1>Mikä vaihtoehtoinen teksti on?</h1> <p>Vaihtoehtoinen teksti tarjoaa kuvauksen kuvista ihmisille, joilla on näkövamma tai matalan kaistanleveyden yhteys tai jotka kaipaavat lisäkontekstia.</p> <p>Voit parantaa saavutettavuutta ja ymmärrettävyyttä kaikkien näkökulmasta kirjoittamalla selkeän, tiiviin ja objektiivisen vaihtoehtoisen tekstin.</p> <ul> <li>Ota mukaan tärkeät elementit</li> <li>Tiivistä kuvissa oleva teksti</li> <li>Käytä tavallisia lauserakenteita</li> <li>Vältä turhaa tietoa</li> <li>Keskity trendeihin ja keskeisiin tuloksiin monimutkaisissa visuaalisissa esityksissä (kuten kaavioissa tai kartoissa)</li> </ul>",
"interaction_modal.action.favourite": "Jotta voit jatkaa, sinun tulee lisätä julkaisu suosikiksesi omalta tililtäsi.",
"interaction_modal.action.follow": "Jotta voit jatkaa, sinun tulee seurata käyttäjää omalta tililtäsi.",
"interaction_modal.action.reblog": "Jotta voit jatkaa, sinun tulee uudelleenjulkaista omalta tililtäsi.",

View File

@ -414,6 +414,8 @@
"ignore_notifications_modal.not_followers_title": "Lat sum um tú ikki sær fráboðanir frá fólki, sum ikki fylgja tær?",
"ignore_notifications_modal.not_following_title": "Lat sum um tú ikki sær fráboðanir frá fólki, sum tú ikki fylgir?",
"ignore_notifications_modal.private_mentions_title": "Lat sum um tú ikki sær fráboðanir frá óbiðnum privatum umrøðum?",
"info_button.label": "Hjálp",
"info_button.what_is_alt_text": "<h1>Hvat er alt tekstur?</h1> <p>Alt tekstur lýsir myndir fyri fólki, sum síggja illa, ella sum hava ringt net samband ella tey, sum vilja vita meira um samanhangin.</p> <p>Tú kanst bøta um atkomuna og fatanina hjá øllum við at skriva kláran, stuttan og objektivan alt tekst.</p> <ul> <li>Fanga týdningarmikil element</li> <li>Samanfata tekst í myndum</li> <li>Brúka reglubundnan setningsbygnað</li> <li>Lat vera við at siga ting upp í saman</li> <li>Fokusera á rák og høvuðsúrslit í kompleksum myndum (sosum diagrammir og kort)</li> </ul>",
"interaction_modal.action.favourite": "Fyri at halda fram, so mást tú yndismerkja frá tínari kontu.",
"interaction_modal.action.follow": "Fyri at halda fram, mást tú fylgja frá tínari kontu.",
"interaction_modal.action.reblog": "Fyri at halda fram, mást tú endurblogga frá tínari kontu.",

View File

@ -414,6 +414,8 @@
"ignore_notifications_modal.not_followers_title": "Ignorer les notifications provenant des personnes qui ne vous suivent pas ?",
"ignore_notifications_modal.not_following_title": "Ignorer les notifications provenant des personnes que vous ne suivez pas ?",
"ignore_notifications_modal.private_mentions_title": "Ignorer les notifications issues des mentions privées non sollicitées ?",
"info_button.label": "Aide",
"info_button.what_is_alt_text": "<h1>Qu'est-ce que le texte alternatif ?</h1> <p>Un texte alternatif fournit une description de l'image aux personnes avec un handicap visuel ou une connexion limitée ou qui souhaitent avoir un contexte supplémentaire.</p> <p>Vous pouvez améliorer l'accessibilité et la compression de tout le monde en écrivant un texte alternatif clair, concis et objectif.</p> <ul> <li>Identifiez les éléments importants</li> <li>Résumez le texte présent à l'image</li> <li>Utilisez une structure de phrase normale</li> <li>Évitez les informations redondantes</li> <li>Pour les visuels complexes (tels que les diagrammes ou les cartes), indiquez les tendances ou points-clés</li> </ul>",
"interaction_modal.action.favourite": "Pour continuer, vous devez ajouter en favori depuis votre compte.",
"interaction_modal.action.follow": "Pour continuer, vous devez suivre depuis votre compte.",
"interaction_modal.action.reblog": "Pour continuer, vous devez booster depuis votre compte.",

View File

@ -414,6 +414,8 @@
"ignore_notifications_modal.not_followers_title": "Ignorer les notifications provenant des personnes qui ne vous suivent pas ?",
"ignore_notifications_modal.not_following_title": "Ignorer les notifications provenant des personnes que vous ne suivez pas ?",
"ignore_notifications_modal.private_mentions_title": "Ignorer les notifications issues des mentions privées non sollicitées ?",
"info_button.label": "Aide",
"info_button.what_is_alt_text": "<h1>Qu'est-ce que le texte alternatif ?</h1> <p>Un texte alternatif fournit une description de l'image aux personnes avec un handicap visuel ou une connexion limitée ou qui souhaitent avoir un contexte supplémentaire.</p> <p>Vous pouvez améliorer l'accessibilité et la compression de tout le monde en écrivant un texte alternatif clair, concis et objectif.</p> <ul> <li>Identifiez les éléments importants</li> <li>Résumez le texte présent à l'image</li> <li>Utilisez une structure de phrase normale</li> <li>Évitez les informations redondantes</li> <li>Pour les visuels complexes (tels que les diagrammes ou les cartes), indiquez les tendances ou points-clés</li> </ul>",
"interaction_modal.action.favourite": "Pour continuer, vous devez ajouter en favori depuis votre compte.",
"interaction_modal.action.follow": "Pour continuer, vous devez suivre depuis votre compte.",
"interaction_modal.action.reblog": "Pour continuer, vous devez booster depuis votre compte.",
@ -549,7 +551,7 @@
"notification.admin.report_account_other": "{name} a signalé {count, plural, one {un message} other {# messages}} depuis {target}",
"notification.admin.report_statuses": "{name} a signalé {target} pour {category}",
"notification.admin.report_statuses_other": "{name} a signalé {target}",
"notification.admin.sign_up": "{name} s'est inscrit",
"notification.admin.sign_up": "{name} s'est inscrit·e",
"notification.admin.sign_up.name_and_others": "{name} et {count, plural, one {# autre} other {# autres}} se sont inscrit",
"notification.annual_report.message": "Votre {year} #Wrapstodon attend ! Dévoilez les moments forts et mémorables de votre année sur Mastodon !",
"notification.annual_report.view": "Voir #Wrapstodon",

View File

@ -414,6 +414,8 @@
"ignore_notifications_modal.not_followers_title": "Ignorar notificacións de persoas que non te seguen?",
"ignore_notifications_modal.not_following_title": "Ignorar notificacións de persoas que non segues?",
"ignore_notifications_modal.private_mentions_title": "Ignorar notificacións de Mencións Privadas non solicitadas?",
"info_button.label": "Axuda",
"info_button.what_is_alt_text": "<h1>Que é o Texto Alternativo?</h1> <p>O Text Alt proporciona a descrición das imaxes para as persoas con deficiencias visuais, conexións a internet de baixa calidade ou para engadir contexto ás mesmas.</p> <p>Podes mellorar a accesibilidade e a comprensión da publicación ao escribir un texto alternativo claro, conciso e obxectivo.</p> <ul> <li>Identifica os elementos importantes</li> <li>Inclúe o texto que apareza nas imaxes</li> <li>Utiliza sintaxe estándar nas frases</li> <li>Evita información redundante</li> <li>Céntrate nos elementos principais cando sexan imaxes complexas (como diagramas ou mapas)</li> </ul>",
"interaction_modal.action.favourite": "Para continuar, debes favorecer desde a túa conta.",
"interaction_modal.action.follow": "Para continuar, debes facer seguimento desde a túa conta.",
"interaction_modal.action.reblog": "Para continuar, debes promover desde a túa conta.",

View File

@ -414,6 +414,8 @@
"ignore_notifications_modal.not_followers_title": "להתעלם מהתראות מא.נשים שאינם עוקביך?",
"ignore_notifications_modal.not_following_title": "להתעלם מהתראות מא.נשים שאינם נעקביך?",
"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.favourite": "כדי להמשיך, עליך לחבב מחשבונך.",
"interaction_modal.action.follow": "כדי להמשיך, עליך לעקוב מחשבונך.",
"interaction_modal.action.reblog": "כדי להמשיך, עליך להדהד מחשבונך.",

View File

@ -86,6 +86,13 @@
"alert.unexpected.message": "Váratlan hiba történt.",
"alert.unexpected.title": "Hoppá!",
"alt_text_badge.title": "Helyettesítő szöveg",
"alt_text_modal.add_alt_text": "Helyettesítő szöveg hozzáadása",
"alt_text_modal.add_text_from_image": "Szöveg hozzáadása a képből",
"alt_text_modal.cancel": "Mégse",
"alt_text_modal.change_thumbnail": "Bélyegkép megváltoztatása",
"alt_text_modal.describe_for_people_with_hearing_impairments": "Írd le a hallássérültek számára…",
"alt_text_modal.describe_for_people_with_visual_impairments": "Írd le a látássérültek számára…",
"alt_text_modal.done": "Kész",
"announcement.announcement": "Közlemény",
"annual_report.summary.archetype.booster": "A cool-vadász",
"annual_report.summary.archetype.lurker": "A settenkedő",
@ -407,6 +414,8 @@
"ignore_notifications_modal.not_followers_title": "Nem követőktől érkező értesítések figyelmen kívül hagyása?",
"ignore_notifications_modal.not_following_title": "Nem követettektől érkező értesítések figyelmen kívül hagyása?",
"ignore_notifications_modal.private_mentions_title": "Figyelmen kívül hagyod a kéretlen privát említéseket?",
"info_button.label": "Súgó",
"info_button.what_is_alt_text": "<h1>Mi az alternatív szöveg?</h1> <p>Az alternatív szöveg képleírást biztosít a látássérültek, az alacsony sávszélességű kapcsolatokkal rendelkezők, illetve a bővebb kontextust keresők számára.</p> <p>Az egyértelmű, tömör és objektív alternatív szöveg megírásával mindenki számára akadálymentesebb és könnyebben érthető lesz.</p> <ul> <li>Rögzítsd a fontos elemeket.</li> <li>Foglald össze szövegesen a képeket.</li> <li>Használj szabályos mondatszerkezetet.</li> <li>Kerüld a felesleges információkat.</li> <li>Összetett vizuális ábrákon (például diagramokon vagy térképeken) összpontosíts a trendekre és a legfontosabb megállapításokra.</li> </ul>",
"interaction_modal.action.favourite": "A folytatáshoz a fiókodból kell kedvencnek jelölnöd.",
"interaction_modal.action.follow": "A folytatáshoz a fiókodból kell követned.",
"interaction_modal.action.reblog": "A folytatáshoz a fiókodból kell megosztanod.",

View File

@ -89,6 +89,7 @@
"alt_text_modal.add_text_from_image": "Adder texto ab imagine",
"alt_text_modal.cancel": "Cancellar",
"alt_text_modal.change_thumbnail": "Cambiar le miniatura",
"alt_text_modal.done": "Preste",
"announcement.announcement": "Annuncio",
"annual_report.summary.archetype.booster": "Le impulsator",
"annual_report.summary.archetype.lurker": "Le lector",

View File

@ -86,6 +86,13 @@
"alert.unexpected.message": "Upp kom óvænt villa.",
"alert.unexpected.title": "Úbbs!",
"alt_text_badge.title": "Hjálpartexti mynda",
"alt_text_modal.add_alt_text": "Bæta við hjálpartexta",
"alt_text_modal.add_text_from_image": "Bæta við texta úr mynd",
"alt_text_modal.cancel": "Hætta við",
"alt_text_modal.change_thumbnail": "Skipta um smámynd",
"alt_text_modal.describe_for_people_with_hearing_impairments": "Lýstu þessu fyrir fólk með skerta heyrn…",
"alt_text_modal.describe_for_people_with_visual_impairments": "Lýstu þessu fyrir fólk með skerta sjón…",
"alt_text_modal.done": "Lokið",
"announcement.announcement": "Auglýsing",
"annual_report.summary.archetype.booster": "Svali gaurinn",
"annual_report.summary.archetype.lurker": "Lurkurinn",
@ -407,6 +414,8 @@
"ignore_notifications_modal.not_followers_title": "Hunsa tilkynningar frá fólki sem fylgist ekki með þér?",
"ignore_notifications_modal.not_following_title": "Hunsa tilkynningar frá fólki sem þú fylgist ekki með?",
"ignore_notifications_modal.private_mentions_title": "Hunsa tilkynningar frá óumbeðnum tilvísunum í einkaspjalli?",
"info_button.label": "Hjálp",
"info_button.what_is_alt_text": "<h1>Hvað er alt-texti?</h1> <p>Hjálpartexti eða ALT-myndatexti inniheldur lýsingu á myndefni fyrir fólk með ýmsar gerðir sjónskerðingar, fyrir tengingar með litla bandbreidd, eða til að gefa nánara samhengi fyrir myndefni.</p><p>Þú getur með þessu bætt almennt aðgengi og aukið skilning á efni sem þú birtir með því að skrifa skýran, skorinortan og hlutlægan alt-texta til vara.</p><ul><li>Lýstu mikilvægum atriðum</li>\\n<li>Hafðu yfirlit með þeim texta sem sést í myndum</li><li>Notaðu eðlilega setningaskipan</li><li>Forðastu óþarfar upplýsingar</li><li>Leggðu áherslu á aðalatriði í flóknu myndefni (eins og línuritum eða landakortum)</li></ul>",
"interaction_modal.action.favourite": "Til að halda áfram þarftu að setja eitthvað í eftirlæti, verandi inni á aðgangnum þínum.",
"interaction_modal.action.follow": "Til að halda áfram þarftu að fylgjast með einhverjum, verandi inni á aðgangnum þínum.",
"interaction_modal.action.reblog": "Til að halda áfram þarftu að endurbirta frá einhverjum, verandi inni á aðgangnum þínum.",

View File

@ -1,6 +1,6 @@
{
"about.blocks": "Server moderati",
"about.contact": "Contatto:",
"about.contact": "Contatti:",
"about.disclaimer": "Mastodon è un software libero e open-source e un marchio di Mastodon gGmbH.",
"about.domain_blocks.no_reason_available": "Motivo non disponibile",
"about.domain_blocks.preamble": "Mastodon, generalmente, ti consente di visualizzare i contenuti e interagire con gli utenti da qualsiasi altro server nel fediverso. Queste sono le eccezioni che sono state fatte su questo particolare server.",
@ -39,7 +39,7 @@
"account.following_counter": "{count, plural, one {{counter} segui} other {{counter} segui}}",
"account.follows.empty": "Questo utente non segue ancora nessuno.",
"account.go_to_profile": "Vai al profilo",
"account.hide_reblogs": "Nascondi potenziamenti da @{name}",
"account.hide_reblogs": "Nascondi condivisioni da @{name}",
"account.in_memoriam": "In memoria.",
"account.joined_short": "Iscritto",
"account.languages": "Modifica le lingue d'iscrizione",
@ -61,7 +61,7 @@
"account.requested": "In attesa d'approvazione. Clicca per annullare la richiesta di seguire",
"account.requested_follow": "{name} ha richiesto di seguirti",
"account.share": "Condividi il profilo di @{name}",
"account.show_reblogs": "Mostra potenziamenti da @{name}",
"account.show_reblogs": "Mostra condivisioni da @{name}",
"account.statuses_counter": "{count, plural, one {{counter} post} other {{counter} post}}",
"account.unblock": "Sblocca @{name}",
"account.unblock_domain": "Sblocca il dominio {domain}",
@ -414,6 +414,8 @@
"ignore_notifications_modal.not_followers_title": "Ignorare le notifiche delle persone che non ti seguono?",
"ignore_notifications_modal.not_following_title": "Ignorare le notifiche delle persone che non segui?",
"ignore_notifications_modal.private_mentions_title": "Ignorare le notifiche provenienti da menzioni private indesiderate?",
"info_button.label": "Aiuto",
"info_button.what_is_alt_text": "<h1>Cos'è il testo alternativo?</h1> <p>Il testo alternativo fornisce descrizioni delle immagini per le persone con disturbi della vista, connessioni a bassa larghezza di banda o per coloro che cercano un contesto aggiuntivo.</p> <p>È possibile migliorare l'accessibilità e la comprensione per tutti scrivendo un testo alt chiaro, conciso e obiettivo.</p> <ul> <li>Cattura elementi importanti</li> <li>Riassume il testo nelle immagini</li> <li>Usa la struttura delle frasi regolari</li> <li>Evita le informazioni ridondanti</li> <li>Concentrati sulle tendenze e i risultati chiave in immagini complesse (come diagrammi o mappe)</li> </ul>",
"interaction_modal.action.favourite": "Per continuare, devi aggiungere ai preferiti il tuo account.",
"interaction_modal.action.follow": "Per continuare, devi seguire dal tuo account.",
"interaction_modal.action.reblog": "Per continuare, devi condividere dal tuo account.",
@ -696,7 +698,7 @@
"privacy.private.short": "Follower",
"privacy.public.long": "Chiunque dentro e fuori Mastodon",
"privacy.public.short": "Pubblico",
"privacy.unlisted.additional": "Si comporta esattamente come pubblico, tranne per il fatto che il post non verrà visualizzato nei feed live o negli hashtag, nell'esplorazione o nella ricerca Mastodon, anche se hai attivato l'attivazione a livello di account.",
"privacy.unlisted.additional": "",
"privacy.unlisted.long": "Meno fanfare algoritmiche",
"privacy.unlisted.short": "Pubblico silenzioso",
"privacy_policy.last_updated": "Ultimo aggiornamento {date}",

View File

@ -86,6 +86,10 @@
"alert.unexpected.message": "不明なエラーが発生しました。",
"alert.unexpected.title": "エラー!",
"alt_text_badge.title": "代替テキスト",
"alt_text_modal.add_alt_text": "代替テキストを追加",
"alt_text_modal.cancel": "キャンセル",
"alt_text_modal.change_thumbnail": "サムネイルを変更",
"alt_text_modal.done": "完了",
"announcement.announcement": "お知らせ",
"annual_report.summary.archetype.booster": "トレンドハンター",
"annual_report.summary.archetype.lurker": "ROM専",
@ -407,6 +411,8 @@
"ignore_notifications_modal.not_followers_title": "本当に「フォローされていないアカウントからの通知」を無視するようにしますか?",
"ignore_notifications_modal.not_following_title": "本当に「フォローしていないアカウントからの通知」を無視するようにしますか?",
"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.favourite": "お気に入り登録はあなたのアカウントがあるサーバーで行う必要があります。",
"interaction_modal.action.follow": "ユーザーをフォローするには、あなたのアカウントがあるサーバーからフォローする必要があります。",
"interaction_modal.action.reblog": "投稿をブーストするには、あなたのアカウントがあるサーバーでブーストする必要があります。",
@ -836,6 +842,7 @@
"status.reblogs.empty": "まだ誰もブーストしていません。ブーストされるとここに表示されます。",
"status.redraft": "削除して下書きに戻す",
"status.remove_bookmark": "ブックマークを削除",
"status.remove_favourite": "お気に入りから削除",
"status.replied_in_thread": "ほかのユーザーへ",
"status.replied_to": "{name}さんへの返信",
"status.reply": "返信",

View File

@ -74,7 +74,10 @@
"alert.unexpected.message": "Yeḍra-d unezri ur netturaǧu ara.",
"alert.unexpected.title": "Ayhuh!",
"alt_text_badge.title": "Aḍris asegzan",
"alt_text_modal.cancel": "Semmet",
"alt_text_modal.done": "Immed",
"announcement.announcement": "Ulɣu",
"annual_report.summary.most_used_hashtag.none": "Ula yiwen",
"audio.hide": "Ffer amesli",
"block_modal.show_less": "Ssken-d drus",
"block_modal.show_more": "Ssken-d ugar",
@ -100,9 +103,11 @@
"column.blocks": "Imiḍanen yettusḥebsen",
"column.bookmarks": "Ticraḍ",
"column.community": "Tasuddemt tadigant",
"column.create_list": "Snulfu-d tabdart",
"column.direct": "Tabdarin tusligin",
"column.directory": "Inig deg imeɣna",
"column.domain_blocks": "Taɣulin yeffren",
"column.edit_list": "Ẓreg tabdart",
"column.favourites": "Imenyafen",
"column.follow_requests": "Isuturen n teḍfeṛt",
"column.home": "Agejdan",
@ -165,6 +170,7 @@
"confirmations.unfollow.message": "Tetḥeqqeḍ belli tebɣiḍ ur teṭafaṛeḍ ara {name}?",
"content_warning.hide": "Ffer tasuffeɣt",
"content_warning.show": "Ssken-d akken tebɣu tili",
"content_warning.show_more": "Sken-d ugar",
"conversation.delete": "Kkes adiwenni",
"conversation.mark_as_read": "Creḍ yettwaɣṛa",
"conversation.open": "Ssken adiwenni",
@ -325,11 +331,20 @@
"link_preview.author": "S-ɣur {name}",
"link_preview.more_from_author": "Ugar sɣur {name}",
"link_preview.shares": "{count, plural, one {{counter} n tsuffeɣt} other {{counter} n tsuffaɣ}}",
"lists.add_member": "Rnu",
"lists.add_to_list": "Rnu ɣer tebdart",
"lists.add_to_lists": "Rnu {name} ɣer tebdarin",
"lists.create": "Snulfu-d",
"lists.delete": "Kkes tabdart",
"lists.edit": "Ẓreg tabdart",
"lists.list_name": "Isem n tebdart",
"lists.new_list_name": "Isem n tebdart tamaynut",
"lists.remove_member": "Kkes",
"lists.replies_policy.followed": "Kra n useqdac i yettwaḍefren",
"lists.replies_policy.list": "Iɛeggalen n tebdart",
"lists.replies_policy.none": "Ula yiwen·t",
"lists.save": "Sekles",
"lists.search": "Nadi",
"load_pending": "{count, plural, one {# n uferdis amaynut} other {# n yiferdisen imaynuten}}",
"loading_indicator.label": "Yessalay-d …",
"media_gallery.hide": "Seggelmes",
@ -399,6 +414,7 @@
"notifications.column_settings.filter_bar.category": "Iri n usizdeg uzrib",
"notifications.column_settings.follow": "Imeḍfaṛen imaynuten:",
"notifications.column_settings.follow_request": "Isuturen imaynuten n teḍfeṛt:",
"notifications.column_settings.group": "Agraw",
"notifications.column_settings.mention": "Abdar:",
"notifications.column_settings.poll": "Igemmaḍ n usenqed:",
"notifications.column_settings.push": "Alɣuten yettudemmren",
@ -429,6 +445,9 @@
"notifications.policy.filter_private_mentions_title": "Abdar uslig ur yettwasferken ara",
"notifications_permission_banner.enable": "Rmed alɣuten n tnarit",
"notifications_permission_banner.title": "Ur zeggel acemma",
"onboarding.follows.back": "Uɣal",
"onboarding.follows.done": "Immed",
"onboarding.follows.search": "Nadi",
"onboarding.profile.display_name": "Isem ara d-yettwaskanen",
"onboarding.profile.display_name_hint": "Isem-ik·im ummid neɣ isem-ik·im n uqeṣṣer…",
"onboarding.profile.note": "Tameddurt",
@ -524,6 +543,7 @@
"search_results.accounts": "Imeɣna",
"search_results.all": "Akk",
"search_results.hashtags": "Ihacṭagen",
"search_results.no_results": "Ulac igemmaḍ.",
"search_results.see_all": "Wali-ten akk",
"search_results.statuses": "Tisuffaɣ",
"server_banner.active_users": "iseqdacen urmiden",

View File

@ -86,6 +86,13 @@
"alert.unexpected.message": "예상하지 못한 에러가 발생했습니다.",
"alert.unexpected.title": "앗!",
"alt_text_badge.title": "대체 문구",
"alt_text_modal.add_alt_text": "대체 텍스트 추가",
"alt_text_modal.add_text_from_image": "이미지에서 텍스트 추가",
"alt_text_modal.cancel": "취소",
"alt_text_modal.change_thumbnail": "썸네일 변경",
"alt_text_modal.describe_for_people_with_hearing_impairments": "청력 장애가 있는 사람들을 위한 설명을 작성하세요…",
"alt_text_modal.describe_for_people_with_visual_impairments": "시각 장애가 있는 사람들을 위한 설명을 작성하세요…",
"alt_text_modal.done": "완료",
"announcement.announcement": "공지사항",
"annual_report.summary.archetype.booster": "연쇄부스트마",
"annual_report.summary.archetype.lurker": "은둔자",
@ -407,6 +414,13 @@
"ignore_notifications_modal.not_followers_title": "나를 팔로우하지 않는 사람들의 알림을 무시할까요?",
"ignore_notifications_modal.not_following_title": "내가 팔로우하지 않는 사람들의 알림을 무시할까요?",
"ignore_notifications_modal.private_mentions_title": "요청하지 않은 개인 멘션 알림을 무시할까요?",
"interaction_modal.action.favourite": "계속하려면 내 계정으로 즐겨찾기해야 합니다.",
"interaction_modal.action.follow": "계속하려면 내 계정으로 팔로우해야 합니다.",
"interaction_modal.action.reblog": "계속하려면 내 계정으로 리블로그해야 합니다.",
"interaction_modal.action.reply": "계속하려면 내 계정으로 답장해야 합니다.",
"interaction_modal.action.vote": "계속하려면 내 계정으로 투표해야 합니다.",
"interaction_modal.go": "이동",
"interaction_modal.no_account_yet": "아직 계정이 없나요?",
"interaction_modal.on_another_server": "다른 서버에",
"interaction_modal.on_this_server": "이 서버에서",
"interaction_modal.title.favourite": "{name} 님의 게시물을 좋아하기",
@ -830,6 +844,7 @@
"status.reblogs.empty": "아직 아무도 이 게시물을 부스트하지 않았습니다. 부스트 한 사람들이 여기에 표시 됩니다.",
"status.redraft": "지우고 다시 쓰기",
"status.remove_bookmark": "북마크 삭제",
"status.remove_favourite": "즐겨찾기에서 제거",
"status.replied_in_thread": "글타래에 답장",
"status.replied_to": "{name} 님에게",
"status.reply": "답장",

View File

@ -86,6 +86,13 @@
"alert.unexpected.message": "Įvyko netikėta klaida.",
"alert.unexpected.title": "Ups!",
"alt_text_badge.title": "Alternatyvus tekstas",
"alt_text_modal.add_alt_text": "Pridėti alternatyvųjį tekstą",
"alt_text_modal.add_text_from_image": "Pridėti tekstą iš vaizdo",
"alt_text_modal.cancel": "Atšaukti",
"alt_text_modal.change_thumbnail": "Keisti miniatiūrą",
"alt_text_modal.describe_for_people_with_hearing_impairments": "Aprašykite tai klausos negalią turintiems asmenims…",
"alt_text_modal.describe_for_people_with_visual_impairments": "Aprašykite tai regos sutrikimų turintiems asmenims…",
"alt_text_modal.done": "Atlikta",
"announcement.announcement": "Skelbimas",
"annual_report.summary.archetype.booster": "Šaunus medžiotojas",
"annual_report.summary.archetype.lurker": "Stebėtojas",
@ -287,7 +294,7 @@
"empty_column.community": "Vietinė laiko skalė yra tuščia. Parašyk ką nors viešai, kad pradėtum sąveikauti.",
"empty_column.direct": "Dar neturi jokių privačių paminėjimų. Kai išsiųsi arba gausi vieną iš jų, jis bus rodomas čia.",
"empty_column.domain_blocks": "Kol kas nėra užblokuotų serverių.",
"empty_column.explore_statuses": "Šiuo metu niekas nėra tendencinga. Patikrink vėliau!",
"empty_column.explore_statuses": "Šiuo metu niekas nėra tendencinga. Patikrinkite vėliau!",
"empty_column.favourited_statuses": "Dar neturi mėgstamų įrašų. Kai vieną iš jų pamėgsi, jis bus rodomas čia.",
"empty_column.favourites": "Šio įrašo dar niekas nepamėgo. Kai kas nors tai padarys, jie bus rodomi čia.",
"empty_column.follow_requests": "Dar neturi jokių sekimo prašymų. Kai gausi tokį prašymą, jis bus rodomas čia.",
@ -403,6 +410,8 @@
"ignore_notifications_modal.not_followers_title": "Ignoruoti pranešimus iš žmonių, kurie tave neseka?",
"ignore_notifications_modal.not_following_title": "Ignoruoti pranešimus iš žmonių, kuriuos neseki?",
"ignore_notifications_modal.private_mentions_title": "Ignoruoti pranešimus iš neprašytų privačių paminėjimų?",
"info_button.label": "Žinynas",
"info_button.what_is_alt_text": "<h1>Kas yra alternatyvusis tekstas?</h1> <p>Alternatyvusis tekstas pateikia vaizdų aprašymus asmenims su regos sutrikimais, turintiems mažo pralaidumo ryšį arba ieškantiems papildomo konteksto.</p> <p>Galite pagerinti prieinamumą ir suprantamumą visiems, jei parašysite aiškų, glaustą ir objektyvų alternatyvųjį tekstą.</p> <ul> <li>Užfiksuokite svarbiausius elementus.</li> <li>Apibendrinkite tekstą vaizduose.</li> <li>Naudokite įprasta sakinio struktūrą.</li> <li>Venkite nereikalingos informacijos.</li> <li>Sutelkite dėmesį į tendencijas ir pagrindines išvadas sudėtinguose vaizdiniuose (tokiuose kaip diagramos ar žemėlapiai).</li> </ul>",
"interaction_modal.action.favourite": "Kad tęstumėte, turite pamėgti iš savo paskyros.",
"interaction_modal.action.follow": "Kad tęstumėte, turite sekti iš savo paskyros.",
"interaction_modal.action.reblog": "Kad tęstumėte, turite pasidalinti iš savo paskyros.",
@ -707,7 +716,7 @@
"report.categories.violation": "Turinys pažeidžia vieną ar daugiau serverio taisyklių",
"report.category.subtitle": "Pasirink geriausią atitikmenį.",
"report.category.title": "Papasakok mums, kas vyksta su šiuo {type}",
"report.category.title_account": "profilis",
"report.category.title_account": "profiliu",
"report.category.title_status": "įrašas",
"report.close": "Atlikta",
"report.comment.title": "Ar yra dar kas nors, ką, tavo manymu, turėtume žinoti?",

View File

@ -414,6 +414,8 @@
"ignore_notifications_modal.not_followers_title": "Meldingen negeren van mensen die jou niet volgen?",
"ignore_notifications_modal.not_following_title": "Meldingen negeren van mensen die je niet volgt?",
"ignore_notifications_modal.private_mentions_title": "Meldingen negeren van ongevraagde privéberichten?",
"info_button.label": "Help",
"info_button.what_is_alt_text": "<h1>Wat is alt-tekst?</h1> <p>Alt-tekst biedt beschrijvingen van afbeeldingen voor mensen met een visuele beperking, voor verbindingen met lage internetsnelheid of mensen die op zoek zijn naar extra context.</p> <p>Je kunt de toegankelijkheid en de begrijpelijkheid voor iedereen verbeteren door heldere, beknopte en objectieve alt-teksten te schrijven.</p> <ul> <li>Leg belangrijke elementen vast</li> <li>Tekst in afbeeldingen samenvatten</li> <li>Een eenvoudige zinsbouw gebruiken</li> <li>Overbodige informatie vermijden</li> <li>Voor complexe diagrammen of kaarten alleen op trends en belangrijke bevindingen focussen</li> </ul>",
"interaction_modal.action.favourite": "Om verder te gaan, moet je vanaf je eigen account als favoriet markeren.",
"interaction_modal.action.follow": "Om verder te gaan, moet je vanaf je eigen account volgen.",
"interaction_modal.action.reblog": "Om verder te gaan, moet je vanaf je eigen account boosten.",

View File

@ -86,6 +86,13 @@
"alert.unexpected.message": "Wystąpił nieoczekiwany błąd.",
"alert.unexpected.title": "Ups!",
"alt_text_badge.title": "Tekst alternatywny",
"alt_text_modal.add_alt_text": "Dodaj tekst alternatywny",
"alt_text_modal.add_text_from_image": "Dodaj tekst z obrazu",
"alt_text_modal.cancel": "Anuluj",
"alt_text_modal.change_thumbnail": "Zmień miniaturę",
"alt_text_modal.describe_for_people_with_hearing_impairments": "Opisz to dla osób z wadą słuchu…",
"alt_text_modal.describe_for_people_with_visual_impairments": "Opisz to dla osób z wadą wzroku…",
"alt_text_modal.done": "Gotowe",
"announcement.announcement": "Ogłoszenie",
"annual_report.summary.archetype.booster": "Łowca treści",
"annual_report.summary.archetype.lurker": "Czyhający",
@ -103,6 +110,7 @@
"annual_report.summary.most_used_hashtag.most_used_hashtag": "najczęściej używany hashtag",
"annual_report.summary.most_used_hashtag.none": "Brak",
"annual_report.summary.new_posts.new_posts": "nowe wpisy",
"annual_report.summary.percentile.text": "<topLabel>Plasuje Cię w czołówce</topLabel><percentage></percentage><bottomLabel> użytkowników {domain}.</bottomLabel>",
"annual_report.summary.percentile.we_wont_tell_bernie": "Nie powiemy Berniemu.",
"annual_report.summary.thanks": "Dziękujemy, że jesteś częścią Mastodona!",
"attachments_list.unprocessed": "(nieprzetworzone)",
@ -408,6 +416,10 @@
"ignore_notifications_modal.private_mentions_title": "Ignoruj powiadomienia o nieproszonych wzmiankach prywatnych?",
"interaction_modal.action.favourite": "Aby kontynuować, musisz dodać do ulubionych na swoim koncie.",
"interaction_modal.action.follow": "Aby kontynuować, musisz obserwować ze swojego konta.",
"interaction_modal.action.reblog": "Aby kontynuować, musisz podać dalej ze swojego konta.",
"interaction_modal.action.reply": "Aby kontynuować, musisz odpowiedzieć ze swojego konta.",
"interaction_modal.action.vote": "Aby kontynuować, musisz zagłosować ze swojego konta.",
"interaction_modal.go": "Dalej",
"interaction_modal.no_account_yet": "Nie masz jeszcze konta?",
"interaction_modal.on_another_server": "Na innym serwerze",
"interaction_modal.on_this_server": "Na tym serwerze",
@ -452,6 +464,7 @@
"keyboard_shortcuts.toggle_hidden": "aby wyświetlić lub ukryć wpis spod CW",
"keyboard_shortcuts.toggle_sensitivity": "Pokaż/ukryj multimedia",
"keyboard_shortcuts.toot": "Stwórz nowy post",
"keyboard_shortcuts.translate": "Aby przetłumaczyć post",
"keyboard_shortcuts.unfocus": "aby opuścić pole wyszukiwania/pisania",
"keyboard_shortcuts.up": "aby przejść na górę listy",
"lightbox.close": "Zamknij",
@ -690,6 +703,8 @@
"privacy_policy.title": "Polityka prywatności",
"recommended": "Zalecane",
"refresh": "Odśwież",
"regeneration_indicator.please_stand_by": "Proszę czekać.",
"regeneration_indicator.preparing_your_home_feed": "Przygotowywanie Twojego kanału wiadomości...",
"relative_time.days": "{number} dni",
"relative_time.full.days": "{number, plural, one {# dzień} few {# dni} many {# dni} other {# dni}} temu",
"relative_time.full.hours": "{number, plural, one {# godzinę} few {# godziny} many {# godzin} other {# godzin}} temu",

View File

@ -414,9 +414,11 @@
"ignore_notifications_modal.not_followers_title": "Ignorar notificações de pessoas que não te seguem?",
"ignore_notifications_modal.not_following_title": "Ignorar notificações de pessoas que não segues?",
"ignore_notifications_modal.private_mentions_title": "Ignorar notificações de menções privadas não solicitadas?",
"info_button.label": "Ajuda",
"info_button.what_is_alt_text": "<h1>O que é texto alternativo?</h1> <p>O texto alternativo fornece descrições de imagens para pessoas com deficiências visuais, conexões de baixa largura de banda ou pessoas que procuram um contexto adicional.</p> <p>Podes melhorar a acessibilidade e a compreensão para todos escrevendo um texto alternativo claro, conciso e objetivo.</p> <ul> <li>Capta elementos importantes</li> <li>Resume o texto que aparece nas imagens</li> <li>Usa uma estrutura de frase regular</li> <li>Evita informações redundantes</li> <li>Centra-te nas tendências e nas principais conclusões em imagens complexas (como diagramas ou mapas)</li> </ul>",
"interaction_modal.action.favourite": "Para continuar, tens de adicionar um favorito na tua conta.",
"interaction_modal.action.follow": "Para continuar, tens de seguir alguém na tua conta.",
"interaction_modal.action.reblog": "Para continuar, tens de fazer uma republicação na tua conta.",
"interaction_modal.action.reblog": "Para continuar, tens de impulsionar desde a tua conta.",
"interaction_modal.action.reply": "Para continuar, tens de fazer uma resposta na tua conta.",
"interaction_modal.action.vote": "Para continuar é necessário votar a partir da tua conta.",
"interaction_modal.go": "Ir",

View File

@ -409,6 +409,8 @@
"ignore_notifications_modal.not_followers_title": "Të shpërfillen njoftime nga persona që sju ndjekin?",
"ignore_notifications_modal.not_following_title": "Të shpërfillen njoftime nga persona që si ndiqni?",
"ignore_notifications_modal.private_mentions_title": "Të shpërfillen njoftime nga Përmendje Private të pakërkuara?",
"info_button.label": "Ndihmë",
"info_button.what_is_alt_text": "<h1>Çështë teksti alternativ?</h1> <p>Teksti alternativ jep përshkrime figurash për persona me mangësi në të parët, lidhje me gjerësi bande të ulët, ose për ata që duan kontekst shtesë.</p> <p>Mund të përmirësoni përdorimin nga persona me aftësi të kufizuara dhe kuptimin për këto, duke shkruar tekst alternativ të qartë, konciz dhe objektiv.</p> <ul> <li>Rrokni elementët e rëndësishëm</li> <li>Përmblidhni tekst në figura</li> <li>Përdorni strukturë të rregullt fjalish</li> <li>Shmangni përsëritje informacioni</li> <li>Në aspekte pamore të ndërlikuara (fjala vjen, diagrame ose harta) përqendrohuni te prirje dhe gjetje gjërash kyçe</li> </ul>",
"interaction_modal.action.favourite": "Që të vazhdoni, lypset ti vini shenjë si i parapëlqyer që nga llogaria juaj.",
"interaction_modal.action.follow": "Që të vazhdoni, lypset ta ndiqni që nga llogaria juaj.",
"interaction_modal.action.reblog": "Që të vazhdoni, lypset ta riblogoni që nga llogaria juaj.",

View File

@ -523,7 +523,7 @@
"navigation_bar.favourites": "Favoriter",
"navigation_bar.filters": "Tystade ord",
"navigation_bar.follow_requests": "Följförfrågningar",
"navigation_bar.followed_tags": "Utvalda hashtags",
"navigation_bar.followed_tags": "Följda hashtaggar",
"navigation_bar.follows_and_followers": "Följer och följare",
"navigation_bar.lists": "Listor",
"navigation_bar.logout": "Logga ut",

View File

@ -1,11 +1,12 @@
{
"about.blocks": "ma lawa",
"about.contact": "toki:",
"about.disclaimer": "ilo Masoton la, jan ale li ken kama jo e ona kepeken mani ala, li ken ante e toki ilo ona. kulupu esun Mastodon li jo e nimi ona. kulupu esun Mastodon li nasin lawa gGmbH.",
"about.disclaimer": "ilo Masoton la jan ale li lawa e ona li pana e pona tawa ona. kulupu esun Mastodon gGmbH li lawa e nimi ona.",
"about.domain_blocks.no_reason_available": "mi sona ala e tan",
"about.domain_blocks.preamble": "ilo Masoton li ken e ni: sina lukin e toki jan pi ma ilo mute. sina ken toki tawa ona lon kulupu ma. taso, ma ni li ken ala e ni tawa ma ni:",
"about.domain_blocks.silenced.explanation": "sina lukin ala e toki e jan tan ma ni. taso, sina wile la, sina ken ni.",
"about.domain_blocks.silenced.title": "ken lili lukin",
"about.domain_blocks.silenced.title": "ken lukin lili ",
"about.domain_blocks.suspended.explanation": "sona ale pi ma ni li kama pali ala, li kama esun ala, li kama awen ala la sina ken ala toki tawa jan pi ma ni.",
"about.domain_blocks.suspended.title": "weka",
"about.not_available": "lon kulupu ni la sina ken alasa ala e sona ni.",
"about.powered_by": "lipu kulupu pi jan lawa mute tan {mastodon}",
@ -18,7 +19,7 @@
"account.block_domain": "o weka e ma {domain}",
"account.block_short": "o weka e jan tawa mi",
"account.blocked": "jan li weka tawa mi",
"account.cancel_follow_request": "o pini kute",
"account.cancel_follow_request": "o kute ala",
"account.copy": "o pali same e linja pi lipu jan",
"account.direct": "len la o mu e @{name}",
"account.disable_notifications": "@{name} li toki la o mu ala e mi",
@ -50,74 +51,95 @@
"account.mute": "o len e @{name}",
"account.mute_notifications_short": "o kute ala e mu tan jan ni",
"account.mute_short": "o kute ala",
"account.muted": "sina len e jan ni",
"account.muted": "sina kute ala e jan ni",
"account.mutual": "jan pona sona",
"account.no_bio": "lipu li weka",
"account.no_bio": "lipu li weka.",
"account.open_original_page": "o open e lipu open",
"account.posts": "toki suli",
"account.posts_with_replies": "toki ale",
"account.report": "jan @{name} la o toki tawa lawa",
"account.requested": "jan ni o ken e kute sina. sina pini wile kute la o luka e ni",
"account.requested_follow": "{name} li wile kute e sina",
"account.report": "jan @{name} la o toki e ike tawa lawa",
"account.requested": "jan ni o ken e kute sina",
"account.requested_follow": "jan {name} li wile kute e sina",
"account.share": "o pana e lipu jan @{name}",
"account.show_reblogs": "o lukin e pana toki tan @{name}",
"account.statuses_counter": "{count, plural, other {toki {counter}}}",
"account.unblock": "o weka ala e jan {name}",
"account.unblock_domain": "o weka ala e ma {domain}",
"account.unblock_short": "o pini weka",
"account.unblock_short": "o weka ala",
"account.unendorse": "lipu jan la o suli ala e ni",
"account.unfollow": "o pini kute",
"account.unfollow": "o kute ala",
"account.unmute": "o len ala e @{name}",
"account.unmute_notifications_short": "o kute e mu tan jan ni",
"account.unmute_short": "o len ala",
"account_note.placeholder": "o luka e ni la sona pi sina taso",
"admin.dashboard.daily_retention": "nanpa pi awen jan lon tenpo suno",
"admin.dashboard.monthly_retention": "nanpa pi awen jan lon tenpo mun",
"admin.dashboard.retention.average": "sama",
"admin.dashboard.retention.cohort": "tenpo mun open",
"admin.dashboard.retention.cohort_size": "jan sin",
"admin.impact_report.instance_accounts": "ni li pakala li weka e lipu jan ni",
"admin.impact_report.instance_followers": "jan pi ma mi li weka tan jan kute ni",
"admin.impact_report.instance_follows": "ma ante li weka tan jan kute ni",
"admin.impact_report.title": "sona pi pakala kulupu",
"alert.rate_limited.message": "tenpo {retry_time, time, medium} la o pali awen",
"alert.rate_limited.title": "ilo ni li lili e ken sina",
"alert.unexpected.message": "pakala li lon",
"alert.unexpected.title": "pakala a!",
"alt_text_badge.title": "toki sona sitelen",
"alt_text_modal.add_alt_text": "o pana e toki pi sona lukin",
"alt_text_modal.add_text_from_image": "o kama jo e toki sitelen tan sitelen ni",
"alt_text_modal.cancel": "weka",
"alt_text_modal.change_thumbnail": "o ante e sitelen lili",
"alt_text_modal.describe_for_people_with_hearing_impairments": "jan li ken ala kute la o pana e toki pi sona kalama…",
"alt_text_modal.describe_for_people_with_visual_impairments": "jan li ken ala lukin la o pana e toki pi sona lukin…",
"alt_text_modal.done": "pini",
"announcement.announcement": "toki suli",
"annual_report.summary.archetype.booster": "jan ni li alasa e pona",
"annual_report.summary.archetype.lurker": "jan ni li lukin taso",
"annual_report.summary.archetype.oracle": "jan ni li sona suli",
"annual_report.summary.archetype.pollster": "jan ni li wile sona e pilin jan",
"annual_report.summary.archetype.replier": "jan ni li toki tawa jan mute",
"annual_report.summary.followers.followers": "jan kute sina",
"annual_report.summary.followers.total": "ale la {count}",
"annual_report.summary.here_it_is": "toki lili la tenpo sike nanpa {year} li sama ni tawa sina:",
"annual_report.summary.highlighted_post.by_favourites": "toki pi olin nanpa wan",
"annual_report.summary.highlighted_post.by_reblogs": "toki pi sike nanpa wan",
"annual_report.summary.highlighted_post.by_replies": "toki li jo e toki kama pi nanpa wan",
"annual_report.summary.highlighted_post.possessive": "tan jan {name}",
"annual_report.summary.most_used_hashtag.none": "ala",
"annual_report.summary.new_posts.new_posts": "toki suli sin",
"annual_report.summary.percentile.we_wont_tell_bernie": "mi toki ala e ni tawa jan Peni.",
"annual_report.summary.percentile.text": "<topLabel>ni la sina nanpa sewi</topLabel><percentage></percentage><bottomLabel>pi jan ale lon {domain}.</bottomLabel>",
"annual_report.summary.percentile.we_wont_tell_bernie": "sona ni li len tawa ale.",
"annual_report.summary.thanks": "sina jan pi kulupu Masoton la sina pona a!",
"attachments_list.unprocessed": "(nasin open)",
"audio.hide": "o len e kalama",
"block_modal.remote_users_caveat": "mi pana e wile sina tawa ma {domain}. taso, o sona: ma li ken kepeken nasin len ante la pakala li ken lon. toki pi lukin ale la jan pi ma ala li ken lukin.",
"block_modal.show_less": "o lili e lukin",
"block_modal.show_more": "o mute e lukin",
"block_modal.they_cant_mention": "ona li ken ala toki e sina li ken ala alasa e sina",
"block_modal.show_more": "o suli e lukin",
"block_modal.they_cant_mention": "ona li ken ala toki tawa sina li ken ala kute e sina.",
"block_modal.they_cant_see_posts": "ona li ken ala lukin e toki sina. sina ken ala lukin e toki ona.",
"block_modal.they_will_know": "ona li sona e ni: sina ala e lukin ona.",
"block_modal.they_will_know": "ona li sona e ni: sina weka e lukin ona.",
"block_modal.title": "o weka ala weka e jan",
"block_modal.you_wont_see_mentions": "nimi ona li lon toki suli la sina lukin ala e toki ni.",
"block_modal.you_wont_see_mentions": "jan li toki e nimi ona la sina lukin ala e toki ni.",
"boost_modal.combo": "sina ken luka e nena {combo} tawa ni: sina wile ala luka e nena lon tenpo kama",
"boost_modal.reblog": "o wawa ala wawa e toki?",
"boost_modal.undo_reblog": "o pini ala pini e wawa toki?",
"boost_modal.undo_reblog": "o weka ala weka e wawa toki?",
"bundle_column_error.copy_stacktrace": "o awen e sona pakala lon ilo sina",
"bundle_column_error.error.body": "ilo li ken ala pana e lipu ni. ni li ken tan pakala ilo.",
"bundle_column_error.error.title": "ike a!",
"bundle_column_error.error.title": "pakala a!",
"bundle_column_error.network.body": "mi lukin pana e lipu la, pakala li lon. ken la, pakala li tan ilo nanpa sina. ken la, pakala li tan ilo nanpa suli pi ma kulupu ni.",
"bundle_column_error.network.title": "pakala la ilo sina li toki ala tawa ilo ante",
"bundle_column_error.retry": "o ni sin",
"bundle_column_error.return": "o tawa tomo",
"bundle_column_error.retry": "o alasa sin",
"bundle_column_error.return": "o tawa open",
"bundle_column_error.routing.body": "ilo li sona ala e lipu wile. sina pana ala pana e nasin pona tawa lipu?",
"bundle_column_error.routing.title": "pakala nanpa 404",
"bundle_modal_error.close": "o pini",
"bundle_modal_error.message": "ilo li wile kama e ijo ni, taso pakala li lon.",
"bundle_modal_error.retry": "o ni sin",
"closed_registrations.other_server_instructions": "kulupu Masoton li jo e jan lawa mute, la sina ken pali e sijelo lon ma ante, li ken lukin e ijo pi ma ni.",
"bundle_modal_error.retry": "o alasa sin",
"closed_registrations.other_server_instructions": "kulupu Masoton la lawa mute li lon. sina ken pali e sijelo lon ma ante la sina awen ken lukin e ijo pi ma ni.",
"closed_registrations_modal.description": "tenpo ni la, sina ken ala pali e jan lon ma {domain}. taso sina wile kepeken ilo Masoton la, sina ken pali e jan lon ma ante lon ala ma {domain}.",
"closed_registrations_modal.find_another_server": "o alasa e ma ante",
"closed_registrations_modal.preamble": "ilo Masoton li lon ilo wan ala. sina kepeken ma ante la sina ken lukin li ken kute e jan pi ma ni. sina wile la, sina ken pali e ma sin!",
"closed_registrations_modal.title": "sina kama lon kulupu Masoton",
"column.about": "sona",
"column.blocks": "kulupu pi jan weka",
@ -137,8 +159,11 @@
"column.mutes": "jan len",
"column.notifications": "mu pi sona sin",
"column.pins": "toki sewi",
"column.public": "toki pi ma poka ale",
"column_back_button.label": "o tawa monsi",
"column_header.hide_settings": "o len e lawa",
"column_header.moveLeft_settings": "poki toki ni o tawa ni ←",
"column_header.moveRight_settings": "poki toki ni o tawa ni →",
"column_header.pin": "o sewi",
"column_header.show_settings": "o lukin e lawa",
"column_header.unpin": "o sewi ala",
@ -154,6 +179,8 @@
"compose.saved.body": "ilo li awen e ijo pana sina.",
"compose_form.direct_message_warning_learn_more": "o kama sona e ijo ante",
"compose_form.encryption_warning": "toki li len ala lon ilo Masoton ꞏ o pana ala e sona suli len lon ilo Masoton",
"compose_form.lock_disclaimer": "lipu sina li open, li {locked} ala. jan ale li ken kama kute e sina, li ken lukin e toki sama ni.",
"compose_form.lock_disclaimer.lock": "pini",
"compose_form.placeholder": "sina wile toki e seme?",
"compose_form.poll.duration": "tenpo pana",
"compose_form.poll.multiple": "pana mute",
@ -169,7 +196,7 @@
"compose_form.spoiler.marked": "o weka e toki pi ijo ike ken",
"compose_form.spoiler.unmarked": "o pali e toki pi ijo ike ken",
"compose_form.spoiler_placeholder": "toki pi ijo ike ken (sina ken ala e ni)",
"confirmation_modal.cancel": "o pini",
"confirmation_modal.cancel": "o weka",
"confirmations.block.confirm": "o weka",
"confirmations.delete.confirm": "o weka",
"confirmations.delete.message": "sina wile ala wile weka e toki ni?",
@ -182,22 +209,31 @@
"confirmations.edit.confirm": "o ante",
"confirmations.edit.message": "sina ante e toki sina la toki pali sina li weka. sina wile ala wile e ni?",
"confirmations.edit.title": "o weka ala weka e toki? ni la, toki li kama toki sin.",
"confirmations.follow_to_list.confirm": "o kute, o pana tawa lipu jan",
"confirmations.follow_to_list.message": "sina wile pana e {name} tawa lipu jan la o kama kute e ona.",
"confirmations.follow_to_list.title": "sina wile ala wile kute?",
"confirmations.logout.confirm": "o weka",
"confirmations.logout.message": "sina wile ala wile weka",
"confirmations.logout.title": "o weka?",
"confirmations.mute.confirm": "o len",
"confirmations.redraft.confirm": "o weka o pali sin e toki",
"confirmations.redraft.message": "pali sin e toki ni la sina wile ala wile weka e ona? sina ni la suli pi toki ni en wawa pi toki ni li weka. kin la toki lon toki ni li jo e mama ala.",
"confirmations.redraft.title": "ni li weka li pali sin e toki ni.",
"confirmations.reply.confirm": "toki lon toki ni",
"confirmations.reply.message": "sina toki lon toki ni la toki pali sina li weka. sina wile ala wile e ni?",
"confirmations.unfollow.confirm": "o pini kute",
"confirmations.reply.title": "sina wile ala wile weka e toki lon?",
"confirmations.unfollow.confirm": "o kute ala",
"confirmations.unfollow.message": "sina o wile ala wile pini kute e jan {name}?",
"confirmations.unfollow.title": "sina wile ala wile pini kute?",
"content_warning.hide": "o len",
"content_warning.show": "o lukin",
"content_warning.show_more": "o lukin",
"conversation.delete": "o weka e toki ni",
"conversation.mark_as_read": "ni o sin ala",
"conversation.open": "o lukin e toki",
"conversation.with": "lon {names}",
"copy_icon_button.copied": "toki li awen lon ilo sina",
"copypaste.copied": "sina jo e toki",
"copypaste.copy_to_clipboard": "o awen lon ilo sina",
"directory.local": "tan {domain} taso",
"directory.new_arrivals": "jan pi kama sin",
@ -206,15 +242,24 @@
"disabled_account_banner.text": "sina ken ala kepeken e lipu jan sina pi nimi {disabledAccount}.",
"dismissable_banner.community_timeline": "ni li toki pi tenpo poka tawa ale tan jan lon ma lawa pi nimi {domain}.",
"dismissable_banner.dismiss": "o weka",
"dismissable_banner.explore_links": "tenpo suno ni la jan pi kulupu ale li toki e ijo sin ni. ijo sin pi jan ante mute li sewi lon lipu ni.",
"domain_block_modal.block": "o weka e ma",
"domain_block_modal.they_wont_know": "ona li sona ala e ni: sina weka e ona.",
"domain_block_modal.title": "sina wile weka ala weka e ma?",
"domain_block_modal.you_will_lose_num_followers": "{followersCount, plural, other {jan {followersCountDisplay}}} li kute e sina la, ona kama kute ala e sina. sina kute e {followingCount, plural,other {jan {followingCountDisplay}}} la, sina kama kute ala e ona.",
"domain_block_modal.you_will_lose_relationships": "jan li lon kulupu ni la ona kute e sina la, ona li kama kute ala e sina. jan li lon kulupu ni la sina kute e ona la, sina kama kute ala e ona.",
"domain_block_modal.you_wont_see_posts": "sina ken ala lukin e toki tan jan pi ma ni",
"domain_pill.server": "ma",
"domain_pill.their_handle": "nimi pi ona taso li ni:",
"domain_pill.their_server": "ni li ma ona lon ilo. toki ale ona li lon ma ni.",
"domain_pill.their_username": "ni li nimi ona lon ma ni. jan mute li lon ma ante la, nimi ona li ken sama.",
"domain_pill.username": "nimi jan",
"domain_pill.whats_in_a_handle": "seme li lon nimi?",
"domain_pill.who_they_are": "nimi ilo la sona jan en sona ma li lon. ni la sina ken toki tawa jan ni lon <button>kulupu ma ale</button>.",
"domain_pill.your_handle": "nimi sina:",
"domain_pill.your_server": "ni li ma sina lon ilo. toki ale sina li lon ma ni. ma li ike tawa sina la, sina ken tawa ma ante. ni la jan kute sina li tawa sama.",
"domain_pill.your_username": "ni li nimi sina. ma sina la, sina taso li jo e ona. jan mute li lon ma ante la, ona li ken jo e nimi sama.",
"embed.instructions": "o pana e toki ni la, toki li lon lipu ante. ",
"embed.preview": "ni li jo e sitelen ni:",
"emoji_button.activity": "musi",
"emoji_button.clear": "o weka",
@ -225,6 +270,7 @@
"emoji_button.not_found": "sitelen pilin ala li lon",
"emoji_button.objects": "ijo",
"emoji_button.people": "jan",
"emoji_button.recent": "kepeken suli",
"emoji_button.search": "o alasa...",
"emoji_button.search_results": "ijo pi alasa ni",
"emoji_button.symbols": "sitelen",
@ -249,6 +295,7 @@
"explore.title": "o alasa",
"explore.trending_links": "sin",
"explore.trending_statuses": "toki",
"explore.trending_tags": "kulupu pi lipu suli",
"filter_modal.added.settings_link": "lipu lawa",
"filter_modal.select_filter.expired": "tenpo pini",
"filter_modal.select_filter.search": "o alasa anu pali",
@ -277,15 +324,23 @@
"hashtag.column_settings.tag_mode.all": "ale ni",
"hashtag.column_settings.tag_mode.any": "wan ni",
"hashtag.column_settings.tag_mode.none": "ala ni",
"hashtag.counter_by_accounts": "{count, plural, other {jan {counter}}}",
"hashtag.counter_by_uses": "{count, plural, other {toki {counter}}}",
"hashtag.follow": "o kute e kulupu lipu",
"hashtag.unfollow": "o kute ala e kulupu lipu",
"home.pending_critical_update.link": "o lukin e ijo ilo sin",
"info_button.label": "sona",
"interaction_modal.go": "o tawa ma ni",
"interaction_modal.on_another_server": "lon ma ante",
"interaction_modal.on_this_server": "lon ma ni",
"interaction_modal.title.favourite": "o suli e toki {name}",
"interaction_modal.title.follow": "o kute e {name}",
"interaction_modal.title.reblog": "o wawa e toki {name}",
"interaction_modal.title.reply": "o toki lon toki pi jan {name}",
"interaction_modal.title.vote": "o pana tawa wile sona pi jan {name}",
"interaction_modal.username_prompt": "ni li sama ni: {example}",
"intervals.full.days": "{number, plural, other {suni #}}",
"intervals.full.hours": "{number, plural, other {tenpo suli #}}",
"keyboard_shortcuts.blocked": "o lukin e lipu sina pi jan weka",
"keyboard_shortcuts.boost": "o pana sin e toki",
"keyboard_shortcuts.down": "o tawa anpa lon lipu",
@ -304,10 +359,17 @@
"lightbox.previous": "monsi",
"link_preview.author": "tan {name}",
"lists.delete": "o weka e kulupu lipu",
"lists.done": "ale li pini",
"lists.edit": "o ante e kulupu lipu",
"lists.list_members_count": "{count, plural, other {jan #}}",
"lists.list_name": "nimi kulupu",
"lists.new_list_name": "nimi pi kulupu sin",
"lists.no_lists_yet": "kulupu li lon ala.",
"lists.remove_member": "o weka",
"lists.replies_policy.followed": "jan kute ale",
"lists.replies_policy.list": "jan pi kulupu ni taso",
"lists.replies_policy.none": "jan ala",
"lists.search": "o alasa",
"load_pending": "{count, plural, other {ijo sin #}}",
"loading_indicator.label": "ni li kama…",
"mute_modal.title": "sina wile ala wile kute e jan ni?",
@ -368,7 +430,7 @@
"report.category.title": "ike seme li lon {type} ni",
"report.category.title_account": "lipu",
"report.category.title_status": "toki",
"report.close": "o pini",
"report.close": "ale li pona",
"report.mute": "o kute ala e ona",
"report.mute_explanation": "sina kama ala lukin e ijo pana ona. ona li awen ken kute e sina li awen ken lukin e sina li sona ala e weka kute sina e weka lukin sina.",
"report.next": "awen",
@ -377,7 +439,7 @@
"report.reasons.other": "ni li ike tan ante",
"report.reasons.spam": "ni li ike tan toki mute",
"report.thanks.title": "sina wile ala lukin e ni anu seme?",
"report.unfollow": "o pini kute e {name}",
"report.unfollow": "o kute ala e {name}",
"report_notification.categories.legal": "ike tawa nasin lawa",
"report_notification.categories.other": "ante",
"search.no_recent_searches": "alasa ala li lon tenpo poka",

View File

@ -414,6 +414,8 @@
"ignore_notifications_modal.not_followers_title": "Takip etmeyen kişilerin bildirimlerini yoksay?",
"ignore_notifications_modal.not_following_title": "Takip etmediğin kişilerin bildirimlerini yoksay?",
"ignore_notifications_modal.private_mentions_title": "İstenmeyen özel bahsetmelerden gelen bildirimleri yoksay?",
"info_button.label": "Yardım",
"info_button.what_is_alt_text": "<h1>Alternatif metin nedir?</h1><p>Alternatif metin, görme bozukluğu olan, düşük bant genişliğine sahip bağlantıları olan veya ekstra bağlam arayan kişiler için görsel açıklamaları sağlar.</p><p>Net, sade ve nesnel alternatif metin yazarak herkes için erişilebilirliği ve anlaşılabilirliği iyileştirebilirsiniz.</p><ul><li>Önemlileri yakalayın</li><li>Resimlerdeki metni özetleyin</li><li>Düzenli cümle yapısı kullanın</li><li>Gereksiz bilgilerden kaçının</li><li>Karmaşık görsellerde (şemalar veya haritalar gibi) trendlere ve temel bulgulara odaklanın</li></ul>",
"interaction_modal.action.favourite": "Devam etmek için, hesabınızı kullanarak beğenmelisiniz.",
"interaction_modal.action.follow": "Devam etmek için, hesabınızı kullanarak takip etmelisiniz.",
"interaction_modal.action.reblog": "Devam etmek için, hesabınızı kullanarak tekrar göndermelisiniz.",

View File

@ -87,7 +87,11 @@
"alert.unexpected.title": "Ой!",
"alt_text_badge.title": "Альтернативний текст",
"alt_text_modal.add_alt_text": "Додати альтернативний текст",
"alt_text_modal.add_text_from_image": "Додати текст із малюнку",
"alt_text_modal.cancel": "Скасувати",
"alt_text_modal.change_thumbnail": "Змінити мініатюру",
"alt_text_modal.describe_for_people_with_hearing_impairments": "Опишіть цю ідею для людей із порушеннями слуху…",
"alt_text_modal.describe_for_people_with_visual_impairments": "Опишіть цю ідею для людей із порушеннями зору…",
"alt_text_modal.done": "Готово",
"announcement.announcement": "Оголошення",
"annual_report.summary.archetype.booster": "Мисливець на дописи",
@ -410,6 +414,8 @@
"ignore_notifications_modal.not_followers_title": "Ігнорувати сповіщення від людей, які не підписані на вас?",
"ignore_notifications_modal.not_following_title": "Ігнорувати сповіщення від людей, на яких ви не підписалися?",
"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.favourite": "Щоб продовжити, потрібно додати улюблене з вашого облікового запису.",
"interaction_modal.action.follow": "Щоб іти далі, потрібно підписатися з вашого облікового запису.",
"interaction_modal.action.reblog": "Щоб іти далі, потрібно зробити реблог з вашого облікового запису.",

View File

@ -86,6 +86,13 @@
"alert.unexpected.message": "发生了意外错误。",
"alert.unexpected.title": "哎呀!",
"alt_text_badge.title": "替代文本",
"alt_text_modal.add_alt_text": "添加替代文本",
"alt_text_modal.add_text_from_image": "从图像中添加文本",
"alt_text_modal.cancel": "取消",
"alt_text_modal.change_thumbnail": "更改缩略图",
"alt_text_modal.describe_for_people_with_hearing_impairments": "请为听力障碍人士描述此内容…",
"alt_text_modal.describe_for_people_with_visual_impairments": "请为视力障碍人士描述此内容…",
"alt_text_modal.done": "完成",
"announcement.announcement": "公告",
"annual_report.summary.archetype.booster": "潮流捕手",
"annual_report.summary.archetype.lurker": "吃瓜群众",
@ -109,7 +116,7 @@
"attachments_list.unprocessed": "(未处理)",
"audio.hide": "隐藏音频",
"block_modal.remote_users_caveat": "我们将要求站点 {domain} 尊重你的决定。然而,我们无法保证对方一定遵从,因为某些站点可能会以不同的方案处理屏蔽操作。公开嘟文仍然可能对未登录用户可见。",
"block_modal.show_less": "隐藏",
"block_modal.show_less": "折叠",
"block_modal.show_more": "显示更多",
"block_modal.they_cant_mention": "他们不能提及或关注你。",
"block_modal.they_cant_see_posts": "他们看不到你的嘟文,你也看不到他们的嘟文。",
@ -221,8 +228,8 @@
"confirmations.unfollow.confirm": "取消关注",
"confirmations.unfollow.message": "你确定要取消关注 {name} 吗?",
"confirmations.unfollow.title": "确定要取消关注用户?",
"content_warning.hide": "隐藏",
"content_warning.show": "展开",
"content_warning.hide": "隐藏嘟文",
"content_warning.show": "仍要显示",
"content_warning.show_more": "展开",
"conversation.delete": "删除对话",
"conversation.mark_as_read": "标记为已读",
@ -407,6 +414,8 @@
"ignore_notifications_modal.not_followers_title": "是否忽略未关注你的人的通知?",
"ignore_notifications_modal.not_following_title": "是否忽略你未关注的人的通知?",
"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.favourite": "你需要切换到自己的账号,再发送喜欢。",
"interaction_modal.action.follow": "你需要切换到自己的账号,再进行关注。",
"interaction_modal.action.reblog": "你需要切换到自己的账号,再进行转嘟。",

View File

@ -414,6 +414,8 @@
"ignore_notifications_modal.not_followers_title": "忽略來自未跟隨您帳號之推播通知?",
"ignore_notifications_modal.not_following_title": "忽略來自您未跟隨帳號之推播通知?",
"ignore_notifications_modal.private_mentions_title": "忽略來自不請自來私訊之推播通知?",
"info_button.label": "幫助",
"info_button.what_is_alt_text": "<h1>何謂 ALT 說明文字?</h1> <p>ALT 說明文字為視覺障礙者、低網路頻寬或尋求額外上下文語境的人們提供圖片描述。</p> <p>您可以透過撰寫清晰、簡潔及客觀的說明文字以替所有人改善無障礙特性與協助理解。</p> <ul> <li>掌握幾個重要元素</li> <li>替圖片提供文字摘要</li> <li>使用常規行文結構</li> <li>避免冗贅資訊</li> <li>聚焦於趨勢與複雜視覺中之關鍵(如圖表或地圖)</li> </ul>",
"interaction_modal.action.favourite": "若欲繼續,您必須自您的帳號加入最愛。",
"interaction_modal.action.follow": "若欲繼續,您必須自您的帳號跟隨。",
"interaction_modal.action.reblog": "若欲繼續,您必須自您的帳號轉嘟。",

View File

@ -0,0 +1 @@
<svg xmlns="http://www.w3.org/2000/svg" height="24" viewBox="0 -960 960 960" width="24"><path d="M424-320q0-81 14.5-116.5T500-514q41-36 62.5-62.5T584-637q0-41-27.5-68T480-732q-51 0-77.5 31T365-638l-103-44q21-64 77-111t141-47q105 0 161.5 58.5T698-641q0 50-21.5 85.5T609-475q-49 47-59.5 71.5T539-320H424Zm56 240q-33 0-56.5-23.5T400-160q0-33 23.5-56.5T480-240q33 0 56.5 23.5T560-160q0 33-23.5 56.5T480-80Z"/></svg>

After

Width:  |  Height:  |  Size: 411 B

View File

@ -0,0 +1 @@
<svg xmlns="http://www.w3.org/2000/svg" height="24" viewBox="0 -960 960 960" width="24"><path d="M424-320q0-81 14.5-116.5T500-514q41-36 62.5-62.5T584-637q0-41-27.5-68T480-732q-51 0-77.5 31T365-638l-103-44q21-64 77-111t141-47q105 0 161.5 58.5T698-641q0 50-21.5 85.5T609-475q-49 47-59.5 71.5T539-320H424Zm56 240q-33 0-56.5-23.5T400-160q0-33 23.5-56.5T480-240q33 0 56.5 23.5T560-160q0 33-23.5 56.5T480-80Z"/></svg>

After

Width:  |  Height:  |  Size: 411 B

View File

@ -451,6 +451,15 @@
background: darken($ui-base-color, 10%);
}
.dropdown-button.warning {
border-color: #b3261e;
color: #b3261e;
&.active {
background-color: #f9dedc;
}
}
.search__popout__menu__item {
&:hover,
&:active,

View File

@ -50,6 +50,34 @@
}
}
.help-button {
background: $ui-button-background-color;
border: 0;
color: $ui-button-color;
border-radius: 20px;
cursor: pointer;
width: 24px;
height: 24px;
display: flex;
align-items: center;
justify-content: center;
&:active,
&:focus,
&:hover {
background-color: $ui-button-focus-background-color;
}
&:focus-visible {
outline: $ui-button-icon-focus-outline;
}
.icon {
width: 14px;
height: 14px;
}
}
.button {
background-color: $ui-button-background-color;
border: 10px none;
@ -6091,6 +6119,20 @@ a.status-card {
}
}
&__popout {
background: var(--dropdown-background-color);
backdrop-filter: var(--background-filter);
border: 1px solid var(--dropdown-border-color);
box-shadow: var(--dropdown-shadow);
max-width: 320px;
padding: 16px;
border-radius: 8px;
z-index: 9999 !important;
font-size: 14px;
line-height: 20px;
color: $darker-text-color;
}
.copy-paste-text {
margin-bottom: 0;
}

View File

@ -83,9 +83,12 @@ code {
&__toolbar {
margin-top: 16px;
display: flex;
justify-content: space-between;
align-items: center;
gap: 16px;
.character-counter {
flex: 0 0 auto;
}
}
&.hidden {
@ -561,11 +564,14 @@ code {
}
.stacked-actions {
display: flex;
flex-direction: column;
gap: 10px;
margin-top: 30px;
margin-bottom: 15px;
}
button:not(.button, .link-button) {
.btn {
display: block;
width: 100%;
border: 0;
@ -582,8 +588,6 @@ code {
cursor: pointer;
font-weight: 500;
outline: 0;
margin-bottom: 10px;
margin-inline-end: 10px;
&:last-child {
margin-inline-end: 0;

View File

@ -17,7 +17,7 @@ class ActivityPub::Adapter < ActiveModelSerializers::Adapter::Base
options = serialization_options(options)
serialized_hash = serializer.serializable_hash(options.merge(named_contexts: named_contexts, context_extensions: context_extensions))
serialized_hash = serialized_hash.select { |k, _| options[:fields].include?(k) } if options[:fields]
serialized_hash = serialized_hash.slice(*options[:fields]) if options[:fields]
serialized_hash = self.class.transform_key_casing!(serialized_hash, instance_options)
{ '@context': serialized_context(named_contexts, context_extensions) }.merge(serialized_hash)

View File

@ -72,7 +72,7 @@
.fields-group
= f.input :agreement,
as: :boolean,
label: t('auth.user_agreement_html', privacy_policy_path: privacy_policy_path, terms_of_service_path: terms_of_service_path),
label: TermsOfService.live.exists? ? t('auth.user_agreement_html', privacy_policy_path: privacy_policy_path, terms_of_service_path: terms_of_service_path) : t('auth.user_privacy_agreement_html', privacy_policy_path: privacy_policy_path),
required: false,
wrapper: :with_label

27
bin/prometheus_exporter Executable file
View File

@ -0,0 +1,27 @@
#!/usr/bin/env ruby
# frozen_string_literal: true
#
# This file was generated by Bundler.
#
# The application 'prometheus_exporter' is installed as part of a gem, and
# this file is here to facilitate running it.
#
ENV["BUNDLE_GEMFILE"] ||= File.expand_path("../Gemfile", __dir__)
bundle_binstub = File.expand_path("bundle", __dir__)
if File.file?(bundle_binstub)
if File.read(bundle_binstub, 300).include?("This file was generated by Bundler")
load(bundle_binstub)
else
abort("Your `bin/bundle` was not generated by Bundler, so this binstub cannot run.
Replace `bin/bundle` by running `bundle binstubs bundler --force`, then run this command again.")
end
end
require "rubygems"
require "bundler/setup"
load Gem.bin_path("prometheus_exporter", "prometheus_exporter")

View File

@ -0,0 +1,24 @@
# frozen_string_literal: true
if ENV['MASTODON_PROMETHEUS_EXPORTER_ENABLED'] == 'true'
if ENV['MASTODON_PROMETHEUS_EXPORTER_LOCAL'] == 'true'
require 'prometheus_exporter/server'
require 'prometheus_exporter/client'
# bind is the address, on which the webserver will listen
# port is the port that will provide the /metrics route
server = PrometheusExporter::Server::WebServer.new bind: ENV.fetch('MASTODON_PROMETHEUS_EXPORTER_HOST', 'localhost'), port: ENV.fetch('MASTODON_PROMETHEUS_EXPORTER_PORT', '9394').to_i
server.start
# wire up a default local client
PrometheusExporter::Client.default = PrometheusExporter::LocalClient.new(collector: server.collector)
end
if ENV['MASTODON_PROMETHEUS_EXPORTER_WEB_DETAILED_METRICS'] == 'true'
# Optional, as those metrics might generate extra overhead and be redundant with what OTEL provides
require 'prometheus_exporter/middleware'
# Per-action/controller request stats like HTTP status and timings
Rails.application.middleware.unshift PrometheusExporter::Middleware
end
end

View File

@ -22,6 +22,48 @@ Sidekiq.configure_server do |config|
end
end
if ENV['MASTODON_PROMETHEUS_EXPORTER_ENABLED'] == 'true'
require 'prometheus_exporter'
require 'prometheus_exporter/instrumentation'
config.on :startup do
# Ruby process metrics (memory, GC, etc)
PrometheusExporter::Instrumentation::Process.start type: 'sidekiq'
# Sidekiq process metrics (concurrency, busy, etc)
PrometheusExporter::Instrumentation::SidekiqProcess.start
# ActiveRecord metrics (connection pool usage)
PrometheusExporter::Instrumentation::ActiveRecord.start(
custom_labels: { type: 'sidekiq' },
config_labels: [:database, :host]
)
if ENV['MASTODON_PROMETHEUS_EXPORTER_SIDEKIQ_DETAILED_METRICS'] == 'true'
# Optional, as those metrics might generate extra overhead and be redundant with what OTEL provides
# Per-job metrics
config.server_middleware do |chain|
chain.add PrometheusExporter::Instrumentation::Sidekiq
end
config.death_handlers << PrometheusExporter::Instrumentation::Sidekiq.death_handler
# Per-queue metrics for queues handled by this process (size, latency, etc)
# They will be reported by every process handling those queues, so do not sum them up
PrometheusExporter::Instrumentation::SidekiqQueue.start
# Global Sidekiq metrics (size of the global queues, number of jobs, etc)
# Will be the same for every Sidekiq process
PrometheusExporter::Instrumentation::SidekiqStats.start
end
end
at_exit do
# Wait for the latest metrics to be reported before shutting down
PrometheusExporter::Client.default.stop(wait_timeout_seconds: 10)
end
end
config.server_middleware do |chain|
chain.add Mastodon::SidekiqMiddleware
end

Some files were not shown because too many files have changed in this diff Show More