Merge commit '8ebe2e673e2fd175140df7275eb362c8eecfec31' into glitch-soc/merge-upstream

This commit is contained in:
Claire
2026-02-04 19:23:24 +01:00
115 changed files with 1142 additions and 562 deletions

View File

@@ -70,7 +70,8 @@ type CommonPayloadFields = Pick<
ApiCollectionJSON,
'name' | 'description' | 'sensitive' | 'discoverable'
> & {
tag_name?: string;
tag_name?: string | null;
language?: ApiCollectionJSON['language'];
};
export interface ApiUpdateCollectionPayload extends Partial<CommonPayloadFields> {

View File

@@ -1,6 +1,8 @@
export { FormStack } from './form_stack';
export { Fieldset } from './fieldset';
export { TextInputField, TextInput } from './text_input_field';
export { TextAreaField, TextArea } from './text_area_field';
export { CheckboxField, Checkbox } from './checkbox_field';
export { RadioButtonField, RadioButton } from './radio_button_field';
export { ToggleField, Toggle } from './toggle_field';
export { SelectField, Select } from './select_field';

View File

@@ -3,14 +3,12 @@ import PropTypes from 'prop-types';
import { injectIntl, defineMessages, FormattedMessage } from 'react-intl';
import classNames from 'classnames';
import { Link } from 'react-router-dom';
import ImmutablePropTypes from 'react-immutable-proptypes';
import ImmutablePureComponent from 'react-immutable-pure-component';
import AlternateEmailIcon from '@/material-icons/400-24px/alternate_email.svg?react';
import RepeatIcon from '@/material-icons/400-24px/repeat.svg?react';
import CancelFillIcon from '@/material-icons/400-24px/cancel-fill.svg?react';
import { Hotkeys } from 'mastodon/components/hotkeys';
import { ContentWarning } from 'mastodon/components/content_warning';
import { FilterWarning } from 'mastodon/components/filter_warning';
@@ -26,16 +24,12 @@ import { MediaGallery, Video, Audio } from '../features/ui/util/async-components
import { SensitiveMediaContext } from '../features/ui/util/sensitive_media_context';
import { displayMedia } from '../initial_state';
import { Avatar } from './avatar';
import { AvatarOverlay } from './avatar_overlay';
import { StatusHeader } from './status/header'
import { LinkedDisplayName } from './display_name';
import { getHashtagBarForStatus } from './hashtag_bar';
import { RelativeTimestamp } from './relative_timestamp';
import StatusActionBar from './status_action_bar';
import StatusContent from './status_content';
import { StatusThreadLabel } from './status_thread_label';
import { VisibilityIcon } from './visibility_icon';
import { IconButton } from './icon_button';
const domParser = new DOMParser();
@@ -112,7 +106,6 @@ class Status extends ImmutablePureComponent {
onToggleCollapsed: PropTypes.func,
onTranslate: PropTypes.func,
onInteractionModal: PropTypes.func,
onQuoteCancel: PropTypes.func,
muted: PropTypes.bool,
hidden: PropTypes.bool,
unread: PropTypes.bool,
@@ -129,6 +122,7 @@ class Status extends ImmutablePureComponent {
avatarSize: PropTypes.number,
deployPictureInPicture: PropTypes.func,
unfocusable: PropTypes.bool,
headerRenderFn: PropTypes.func,
pictureInPicture: ImmutablePropTypes.contains({
inUse: PropTypes.bool,
available: PropTypes.bool,
@@ -146,7 +140,6 @@ class Status extends ImmutablePureComponent {
'hidden',
'unread',
'pictureInPicture',
'onQuoteCancel',
];
state = {
@@ -364,10 +357,6 @@ class Status extends ImmutablePureComponent {
this.setState(state => ({ ...state, showDespiteFilter: !state.showDespiteFilter }));
};
handleQuoteCancel = () => {
this.props.onQuoteCancel?.();
}
_properStatus () {
const { status } = this.props;
@@ -383,7 +372,24 @@ class Status extends ImmutablePureComponent {
};
render () {
const { intl, hidden, featured, unfocusable, unread, showThread, showActions = true, isQuotedPost = false, scrollKey, pictureInPicture, previousId, nextInReplyToId, rootId, skipPrepend, avatarSize = 46, children } = this.props;
const {
intl,
hidden,
featured,
unfocusable,
unread,
showThread,
showActions = true,
isQuotedPost = false,
scrollKey,
pictureInPicture,
previousId,
nextInReplyToId,
rootId,
skipPrepend,
avatarSize = 46,
children,
} = this.props;
let { status, account, ...other } = this.props;
@@ -405,7 +411,7 @@ class Status extends ImmutablePureComponent {
onTranslate: this.handleTranslate,
};
let media, statusAvatar, prepend, rebloggedByText;
let media, prepend, rebloggedByText;
const connectUp = previousId && previousId === status.get('in_reply_to_id');
const connectToRoot = rootId && rootId === status.get('in_reply_to_id');
@@ -547,13 +553,19 @@ class Status extends ImmutablePureComponent {
);
}
if (account === undefined || account === null) {
statusAvatar = <Avatar account={status.get('account')} size={avatarSize} />;
} else {
statusAvatar = <AvatarOverlay account={status.get('account')} friend={account} />;
}
const {statusContentProps, hashtagBar} = getHashtagBarForStatus(status);
const header = this.props.headerRenderFn
? this.props.headerRenderFn({ status, account, avatarSize, messages, onHeaderClick: this.handleHeaderClick })
: (
<StatusHeader
status={status}
account={account}
avatarSize={avatarSize}
onHeaderClick={this.handleHeaderClick}
/>
);
return (
<Hotkeys handlers={handlers} focusable={!unfocusable}>
<div className={classNames('status__wrapper', `status__wrapper-${status.get('visibility')}`, { 'status__wrapper-reply': !!status.get('in_reply_to_id'), unread, focusable: !this.props.muted })} tabIndex={this.props.muted || unfocusable ? null : 0} data-featured={featured ? 'true' : null} aria-label={textForScreenReader({intl, status, rebloggedByText, isQuote: isQuotedPost})} ref={this.handleRef} data-nosnippet={status.getIn(['account', 'noindex'], true) || undefined}>
@@ -575,28 +587,7 @@ class Status extends ImmutablePureComponent {
>
{(connectReply || connectUp || connectToRoot) && <div className={classNames('status__line', { 'status__line--full': connectReply, 'status__line--first': !status.get('in_reply_to_id') && !connectToRoot })} />}
<div onClick={this.handleHeaderClick} onAuxClick={this.handleHeaderClick} className='status__info'>
<Link to={`/@${status.getIn(['account', 'acct'])}/${status.get('id')}`} className='status__relative-time'>
<span className='status__visibility-icon'><VisibilityIcon visibility={status.get('visibility')} /></span>
<RelativeTimestamp timestamp={status.get('created_at')} />{status.get('edited_at') && <abbr title={intl.formatMessage(messages.edited, { date: intl.formatDate(status.get('edited_at'), { year: 'numeric', month: 'short', day: '2-digit', hour: '2-digit', minute: '2-digit' }) })}> *</abbr>}
</Link>
<LinkedDisplayName displayProps={{account: status.get('account')}} className='status__display-name'>
<div className='status__avatar'>
{statusAvatar}
</div>
</LinkedDisplayName>
{isQuotedPost && !!this.props.onQuoteCancel && (
<IconButton
onClick={this.handleQuoteCancel}
className='status__quote-cancel'
title={intl.formatMessage(messages.quote_cancel)}
icon="cancel-fill"
iconComponent={CancelFillIcon}
/>
)}
</div>
{header}
{matchedFilters && <FilterWarning title={matchedFilters.join(', ')} expanded={this.state.showDespiteFilter} onClick={this.handleFilterToggle} />}

View File

@@ -0,0 +1,128 @@
import type { FC, HTMLAttributes, MouseEventHandler, ReactNode } from 'react';
import { defineMessage, useIntl } from 'react-intl';
import { Link } from 'react-router-dom';
import { isStatusVisibility } from '@/mastodon/api_types/statuses';
import type { Account } from '@/mastodon/models/account';
import type { Status } from '@/mastodon/models/status';
import { Avatar } from '../avatar';
import { AvatarOverlay } from '../avatar_overlay';
import type { DisplayNameProps } from '../display_name';
import { LinkedDisplayName } from '../display_name';
import { RelativeTimestamp } from '../relative_timestamp';
import { VisibilityIcon } from '../visibility_icon';
export interface StatusHeaderProps {
status: Status;
account?: Account;
avatarSize?: number;
children?: ReactNode;
wrapperProps?: HTMLAttributes<HTMLDivElement>;
displayNameProps?: DisplayNameProps;
onHeaderClick?: MouseEventHandler<HTMLDivElement>;
}
export type StatusHeaderRenderFn = (args: StatusHeaderProps) => ReactNode;
export const StatusHeader: FC<StatusHeaderProps> = ({
status,
account,
children,
avatarSize = 48,
wrapperProps,
onHeaderClick,
}) => {
const statusAccount = status.get('account') as Account | undefined;
const editedAt = status.get('edited_at') as string;
return (
/* eslint-disable jsx-a11y/no-static-element-interactions, jsx-a11y/click-events-have-key-events */
<div
onClick={onHeaderClick}
onAuxClick={onHeaderClick}
{...wrapperProps}
className='status__info'
/* eslint-enable jsx-a11y/no-static-element-interactions, jsx-a11y/click-events-have-key-events */
>
<Link
to={`/@${statusAccount?.acct}/${status.get('id') as string}`}
className='status__relative-time'
>
<StatusVisibility visibility={status.get('visibility')} />
<RelativeTimestamp timestamp={status.get('created_at') as string} />
{editedAt && <StatusEditedAt editedAt={editedAt} />}
</Link>
<StatusDisplayName
statusAccount={statusAccount}
friendAccount={account}
avatarSize={avatarSize}
/>
{children}
</div>
);
};
export const StatusVisibility: FC<{ visibility: unknown }> = ({
visibility,
}) => {
if (typeof visibility !== 'string' || !isStatusVisibility(visibility)) {
return null;
}
return (
<span className='status__visibility-icon'>
<VisibilityIcon visibility={visibility} />
</span>
);
};
const editMessage = defineMessage({
id: 'status.edited',
defaultMessage: 'Edited {date}',
});
export const StatusEditedAt: FC<{ editedAt: string }> = ({ editedAt }) => {
const intl = useIntl();
return (
<abbr
title={intl.formatMessage(editMessage, {
date: intl.formatDate(editedAt, {
year: 'numeric',
month: 'short',
day: '2-digit',
hour: '2-digit',
minute: '2-digit',
}),
})}
>
{' '}
*
</abbr>
);
};
export const StatusDisplayName: FC<{
statusAccount?: Account;
friendAccount?: Account;
avatarSize: number;
}> = ({ statusAccount, friendAccount, avatarSize }) => {
const AccountComponent = friendAccount ? AvatarOverlay : Avatar;
return (
<LinkedDisplayName
displayProps={{ account: statusAccount }}
className='status__display-name'
>
<div className='status__avatar'>
<AccountComponent
account={statusAccount}
friend={friendAccount}
size={avatarSize}
/>
</div>
</LinkedDisplayName>
);
};

View File

@@ -1,9 +1,10 @@
import { useCallback, useEffect, useMemo, useRef, useState } from 'react';
import { FormattedMessage } from 'react-intl';
import { defineMessage, FormattedMessage, useIntl } from 'react-intl';
import type { Map as ImmutableMap } from 'immutable';
import CancelFillIcon from '@/material-icons/400-24px/cancel-fill.svg?react';
import { fetchRelationships } from 'mastodon/actions/accounts';
import { revealAccount } from 'mastodon/actions/accounts_typed';
import { fetchStatus } from 'mastodon/actions/statuses';
@@ -18,6 +19,9 @@ import type { RootState } from 'mastodon/store';
import { useAppDispatch, useAppSelector } from 'mastodon/store';
import { Button } from './button';
import { IconButton } from './icon_button';
import type { StatusHeaderRenderFn } from './status/header';
import { StatusHeader } from './status/header';
const MAX_QUOTE_POSTS_NESTING_LEVEL = 1;
@@ -147,6 +151,11 @@ interface QuotedStatusProps {
onQuoteCancel?: () => void; // Used for composer.
}
const quoteCancelMessage = defineMessage({
id: 'status.quote.cancel',
defaultMessage: 'Cancel quote',
});
export const QuotedStatus: React.FC<QuotedStatusProps> = ({
quote,
contextType,
@@ -213,6 +222,22 @@ export const QuotedStatus: React.FC<QuotedStatusProps> = ({
if (accountId && hiddenAccount) dispatch(fetchRelationships([accountId]));
}, [accountId, hiddenAccount, dispatch]);
const intl = useIntl();
const headerRenderFn: StatusHeaderRenderFn = useCallback(
(props) => (
<StatusHeader {...props}>
<IconButton
onClick={onQuoteCancel}
className='status__quote-cancel'
title={intl.formatMessage(quoteCancelMessage)}
icon='cancel-fill'
iconComponent={CancelFillIcon}
/>
</StatusHeader>
),
[intl, onQuoteCancel],
);
const isFilteredAndHidden = loadingState === 'filtered';
let quoteError: React.ReactNode = null;
@@ -314,7 +339,7 @@ export const QuotedStatus: React.FC<QuotedStatusProps> = ({
id={quotedStatusId}
contextType={contextType}
avatarSize={32}
onQuoteCancel={onQuoteCancel}
headerRenderFn={headerRenderFn}
>
{canRenderChildQuote && (
<QuotedStatus

View File

@@ -1,268 +0,0 @@
import { useCallback, useState, useEffect } from 'react';
import { defineMessages, useIntl, FormattedMessage } from 'react-intl';
import { Helmet } from 'react-helmet';
import { useParams, useHistory } from 'react-router-dom';
import { isFulfilled } from '@reduxjs/toolkit';
import ListAltIcon from '@/material-icons/400-24px/list_alt.svg?react';
import type {
ApiCollectionJSON,
ApiCreateCollectionPayload,
ApiUpdateCollectionPayload,
} from 'mastodon/api_types/collections';
import { Button } from 'mastodon/components/button';
import { Column } from 'mastodon/components/column';
import { ColumnHeader } from 'mastodon/components/column_header';
import {
CheckboxField,
FormStack,
TextAreaField,
} from 'mastodon/components/form_fields';
import { TextInputField } from 'mastodon/components/form_fields/text_input_field';
import { LoadingIndicator } from 'mastodon/components/loading_indicator';
import {
createCollection,
fetchCollection,
updateCollection,
} from 'mastodon/reducers/slices/collections';
import { useAppDispatch, useAppSelector } from 'mastodon/store';
const messages = defineMessages({
edit: { id: 'column.edit_collection', defaultMessage: 'Edit collection' },
create: {
id: 'column.create_collection',
defaultMessage: 'Create collection',
},
});
const CollectionSettings: React.FC<{
collection?: ApiCollectionJSON | null;
}> = ({ collection }) => {
const dispatch = useAppDispatch();
const history = useHistory();
const {
id,
name: initialName = '',
description: initialDescription = '',
tag,
discoverable: initialDiscoverable = true,
sensitive: initialSensitive = false,
} = collection ?? {};
const [name, setName] = useState(initialName);
const [description, setDescription] = useState(initialDescription);
const [topic, setTopic] = useState(tag?.name ?? '');
const [discoverable] = useState(initialDiscoverable);
const [sensitive, setSensitive] = useState(initialSensitive);
const handleNameChange = useCallback(
(event: React.ChangeEvent<HTMLInputElement>) => {
setName(event.target.value);
},
[],
);
const handleDescriptionChange = useCallback(
(event: React.ChangeEvent<HTMLTextAreaElement>) => {
setDescription(event.target.value);
},
[],
);
const handleTopicChange = useCallback(
(event: React.ChangeEvent<HTMLInputElement>) => {
setTopic(event.target.value);
},
[],
);
const handleSensitiveChange = useCallback(
(event: React.ChangeEvent<HTMLInputElement>) => {
setSensitive(event.target.checked);
},
[],
);
const handleSubmit = useCallback(
(e: React.FormEvent) => {
e.preventDefault();
if (id) {
const payload: ApiUpdateCollectionPayload = {
id,
name,
description,
tag_name: topic,
discoverable,
sensitive,
};
void dispatch(updateCollection({ payload })).then(() => {
history.push(`/collections`);
});
} else {
const payload: ApiCreateCollectionPayload = {
name,
description,
discoverable,
sensitive,
};
if (topic) {
payload.tag_name = topic;
}
void dispatch(
createCollection({
payload,
}),
).then((result) => {
if (isFulfilled(result)) {
history.replace(
`/collections/${result.payload.collection.id}/edit`,
);
history.push(`/collections`);
}
});
}
},
[id, dispatch, name, description, topic, discoverable, sensitive, history],
);
return (
<FormStack as='form' onSubmit={handleSubmit}>
<TextInputField
required
label={
<FormattedMessage
id='collections.collection_name'
defaultMessage='Name'
/>
}
hint={
<FormattedMessage
id='collections.name_length_hint'
defaultMessage='40 characters limit'
/>
}
value={name}
onChange={handleNameChange}
maxLength={40}
/>
<TextAreaField
required
label={
<FormattedMessage
id='collections.collection_description'
defaultMessage='Description'
/>
}
hint={
<FormattedMessage
id='collections.description_length_hint'
defaultMessage='100 characters limit'
/>
}
value={description}
onChange={handleDescriptionChange}
maxLength={100}
/>
<TextInputField
required={false}
label={
<FormattedMessage
id='collections.collection_topic'
defaultMessage='Topic'
/>
}
hint={
<FormattedMessage
id='collections.topic_hint'
defaultMessage='Add a hashtag that helps others understand the main topic of this collection.'
/>
}
value={topic}
onChange={handleTopicChange}
maxLength={40}
/>
<CheckboxField
label={
<FormattedMessage
id='collections.mark_as_sensitive'
defaultMessage='Mark as sensitive'
/>
}
hint={
<FormattedMessage
id='collections.mark_as_sensitive_hint'
defaultMessage="Hides the collection's description and accounts behind a content warning. The collection name will still be visible."
/>
}
checked={sensitive}
onChange={handleSensitiveChange}
/>
<div className='actions'>
<Button type='submit'>
{id ? (
<FormattedMessage id='lists.save' defaultMessage='Save' />
) : (
<FormattedMessage id='lists.create' defaultMessage='Create' />
)}
</Button>
</div>
</FormStack>
);
};
export const CollectionEditorPage: React.FC<{
multiColumn?: boolean;
}> = ({ multiColumn }) => {
const intl = useIntl();
const dispatch = useAppDispatch();
const { id } = useParams<{ id?: string }>();
const collection = useAppSelector((state) =>
id ? state.collections.collections[id] : undefined,
);
const isEditMode = !!id;
const isLoading = isEditMode && !collection;
useEffect(() => {
if (id) {
void dispatch(fetchCollection({ collectionId: id }));
}
}, [dispatch, id]);
const pageTitle = intl.formatMessage(id ? messages.edit : messages.create);
return (
<Column bindToDocument={!multiColumn} label={pageTitle}>
<ColumnHeader
title={pageTitle}
icon='list-ul'
iconComponent={ListAltIcon}
multiColumn={multiColumn}
showBackButton
/>
<div className='scrollable'>
{isLoading ? (
<LoadingIndicator />
) : (
<CollectionSettings collection={collection} />
)}
</div>
<Helmet>
<title>{pageTitle}</title>
<meta name='robots' content='noindex' />
</Helmet>
</Column>
);
};

View File

@@ -0,0 +1,67 @@
import { useCallback } from 'react';
import { FormattedMessage } from 'react-intl';
import { useHistory, useLocation } from 'react-router-dom';
import type { ApiCollectionJSON } from 'mastodon/api_types/collections';
import { Button } from 'mastodon/components/button';
import { FormStack } from 'mastodon/components/form_fields';
import type { TempCollectionState } from './state';
import { getInitialState } from './state';
import { WizardStepHeader } from './wizard_step_header';
export const CollectionAccounts: React.FC<{
collection?: ApiCollectionJSON | null;
}> = ({ collection }) => {
const history = useHistory();
const location = useLocation<TempCollectionState>();
const { id } = getInitialState(collection, location.state);
const handleSubmit = useCallback(
(e: React.FormEvent) => {
e.preventDefault();
if (!id) {
history.push(`/collections/new/details`);
}
},
[id, history],
);
return (
<FormStack as='form' onSubmit={handleSubmit}>
{!id && (
<WizardStepHeader
step={1}
title={
<FormattedMessage
id='collections.create.accounts_title'
defaultMessage='Who will you feature in this collection?'
/>
}
description={
<FormattedMessage
id='collections.create.accounts_subtitle'
defaultMessage='Only accounts you follow who have opted into discovery can be added.'
/>
}
/>
)}
<div className='actions'>
<Button type='submit'>
{id ? (
<FormattedMessage id='lists.save' defaultMessage='Save' />
) : (
<FormattedMessage
id='collections.continue'
defaultMessage='Continue'
/>
)}
</Button>
</div>
</FormStack>
);
};

View File

@@ -0,0 +1,172 @@
import { useCallback, useState } from 'react';
import { FormattedMessage } from 'react-intl';
import { useHistory, useLocation } from 'react-router-dom';
import type {
ApiCollectionJSON,
ApiCreateCollectionPayload,
ApiUpdateCollectionPayload,
} from 'mastodon/api_types/collections';
import { Button } from 'mastodon/components/button';
import { FormStack, TextAreaField } from 'mastodon/components/form_fields';
import { TextInputField } from 'mastodon/components/form_fields/text_input_field';
import { updateCollection } from 'mastodon/reducers/slices/collections';
import { useAppDispatch } from 'mastodon/store';
import type { TempCollectionState } from './state';
import { getInitialState } from './state';
import { WizardStepHeader } from './wizard_step_header';
export const CollectionDetails: React.FC<{
collection?: ApiCollectionJSON | null;
}> = ({ collection }) => {
const dispatch = useAppDispatch();
const history = useHistory();
const location = useLocation<TempCollectionState>();
const { id, initialName, initialDescription, initialTopic } = getInitialState(
collection,
location.state,
);
const [name, setName] = useState(initialName);
const [description, setDescription] = useState(initialDescription);
const [topic, setTopic] = useState(initialTopic);
const handleNameChange = useCallback(
(event: React.ChangeEvent<HTMLInputElement>) => {
setName(event.target.value);
},
[],
);
const handleDescriptionChange = useCallback(
(event: React.ChangeEvent<HTMLTextAreaElement>) => {
setDescription(event.target.value);
},
[],
);
const handleTopicChange = useCallback(
(event: React.ChangeEvent<HTMLInputElement>) => {
setTopic(event.target.value);
},
[],
);
const handleSubmit = useCallback(
(e: React.FormEvent) => {
e.preventDefault();
if (id) {
const payload: ApiUpdateCollectionPayload = {
id,
name,
description,
tag_name: topic || null,
};
void dispatch(updateCollection({ payload })).then(() => {
history.push(`/collections`);
});
} else {
const payload: Partial<ApiCreateCollectionPayload> = {
name,
description,
tag_name: topic || null,
};
history.replace('/collections/new', payload);
history.push('/collections/new/settings', payload);
}
},
[id, dispatch, name, description, topic, history],
);
return (
<FormStack as='form' onSubmit={handleSubmit}>
{!id && (
<WizardStepHeader
step={2}
title={
<FormattedMessage
id='collections.create.basic_details_title'
defaultMessage='Basic details'
/>
}
/>
)}
<TextInputField
required
label={
<FormattedMessage
id='collections.collection_name'
defaultMessage='Name'
/>
}
hint={
<FormattedMessage
id='collections.name_length_hint'
defaultMessage='40 characters limit'
/>
}
value={name}
onChange={handleNameChange}
maxLength={40}
/>
<TextAreaField
required
label={
<FormattedMessage
id='collections.collection_description'
defaultMessage='Description'
/>
}
hint={
<FormattedMessage
id='collections.description_length_hint'
defaultMessage='100 characters limit'
/>
}
value={description}
onChange={handleDescriptionChange}
maxLength={100}
/>
<TextInputField
required={false}
label={
<FormattedMessage
id='collections.collection_topic'
defaultMessage='Topic'
/>
}
hint={
<FormattedMessage
id='collections.topic_hint'
defaultMessage='Add a hashtag that helps others understand the main topic of this collection.'
/>
}
value={topic}
onChange={handleTopicChange}
maxLength={40}
/>
<div className='actions'>
<Button type='submit'>
{id ? (
<FormattedMessage id='lists.save' defaultMessage='Save' />
) : (
<FormattedMessage
id='collections.continue'
defaultMessage='Continue'
/>
)}
</Button>
</div>
</FormStack>
);
};

View File

@@ -0,0 +1,135 @@
import { useEffect } from 'react';
import { defineMessages, useIntl } from 'react-intl';
import { Helmet } from 'react-helmet';
import {
Switch,
Route,
useParams,
useRouteMatch,
matchPath,
useLocation,
} from 'react-router-dom';
import ListAltIcon from '@/material-icons/400-24px/list_alt.svg?react';
import { Column } from 'mastodon/components/column';
import { ColumnHeader } from 'mastodon/components/column_header';
import { LoadingIndicator } from 'mastodon/components/loading_indicator';
import { fetchCollection } from 'mastodon/reducers/slices/collections';
import { useAppDispatch, useAppSelector } from 'mastodon/store';
import { CollectionAccounts } from './accounts';
import { CollectionDetails } from './details';
import { CollectionSettings } from './settings';
export const messages = defineMessages({
create: {
id: 'collections.create_collection',
defaultMessage: 'Create collection',
},
newCollection: {
id: 'collections.new_collection',
defaultMessage: 'New collection',
},
editDetails: {
id: 'collections.edit_details',
defaultMessage: 'Edit basic details',
},
manageAccounts: {
id: 'collections.manage_accounts',
defaultMessage: 'Manage accounts',
},
manageAccountsLong: {
id: 'collections.manage_accounts_in_collection',
defaultMessage: 'Manage accounts in this collection',
},
editSettings: {
id: 'collections.edit_settings',
defaultMessage: 'Edit settings',
},
});
function usePageTitle(id: string | undefined) {
const { path } = useRouteMatch();
const location = useLocation();
if (!id) {
return messages.newCollection;
}
if (matchPath(location.pathname, { path, exact: true })) {
return messages.manageAccounts;
} else if (matchPath(location.pathname, { path: `${path}/details` })) {
return messages.editDetails;
} else if (matchPath(location.pathname, { path: `${path}/settings` })) {
return messages.editSettings;
} else {
throw new Error('No page title defined for route');
}
}
export const CollectionEditorPage: React.FC<{
multiColumn?: boolean;
}> = ({ multiColumn }) => {
const intl = useIntl();
const dispatch = useAppDispatch();
const { id } = useParams<{ id?: string }>();
const { path } = useRouteMatch();
const collection = useAppSelector((state) =>
id ? state.collections.collections[id] : undefined,
);
const isEditMode = !!id;
const isLoading = isEditMode && !collection;
useEffect(() => {
if (id) {
void dispatch(fetchCollection({ collectionId: id }));
}
}, [dispatch, id]);
const pageTitle = intl.formatMessage(usePageTitle(id));
return (
<Column bindToDocument={!multiColumn} label={pageTitle}>
<ColumnHeader
title={pageTitle}
icon='list-ul'
iconComponent={ListAltIcon}
multiColumn={multiColumn}
showBackButton
/>
<div className='scrollable'>
{isLoading ? (
<LoadingIndicator />
) : (
<Switch>
<Route
exact
path={path}
// eslint-disable-next-line react/jsx-no-bind
render={() => <CollectionAccounts collection={collection} />}
/>
<Route
exact
path={`${path}/details`}
// eslint-disable-next-line react/jsx-no-bind
render={() => <CollectionDetails collection={collection} />}
/>
<Route
path={`${path}/settings`}
// eslint-disable-next-line react/jsx-no-bind
render={() => <CollectionSettings collection={collection} />}
/>
</Switch>
)}
</div>
<Helmet>
<title>{pageTitle}</title>
<meta name='robots' content='noindex' />
</Helmet>
</Column>
);
};

View File

@@ -0,0 +1,197 @@
import { useCallback, useState } from 'react';
import { FormattedMessage } from 'react-intl';
import { useHistory, useLocation } from 'react-router-dom';
import { isFulfilled } from '@reduxjs/toolkit';
import type {
ApiCollectionJSON,
ApiCreateCollectionPayload,
ApiUpdateCollectionPayload,
} from 'mastodon/api_types/collections';
import { Button } from 'mastodon/components/button';
import {
Fieldset,
FormStack,
CheckboxField,
RadioButtonField,
} from 'mastodon/components/form_fields';
import {
createCollection,
updateCollection,
} from 'mastodon/reducers/slices/collections';
import { useAppDispatch } from 'mastodon/store';
import type { TempCollectionState } from './state';
import { getInitialState } from './state';
import { WizardStepHeader } from './wizard_step_header';
export const CollectionSettings: React.FC<{
collection?: ApiCollectionJSON | null;
}> = ({ collection }) => {
const dispatch = useAppDispatch();
const history = useHistory();
const location = useLocation<TempCollectionState>();
const { id, initialDiscoverable, initialSensitive, ...temporaryState } =
getInitialState(collection, location.state);
const [discoverable, setDiscoverable] = useState(initialDiscoverable);
const [sensitive, setSensitive] = useState(initialSensitive);
const handleDiscoverableChange = useCallback(
(event: React.ChangeEvent<HTMLInputElement>) => {
setDiscoverable(event.target.value === 'public');
},
[],
);
const handleSensitiveChange = useCallback(
(event: React.ChangeEvent<HTMLInputElement>) => {
setSensitive(event.target.checked);
},
[],
);
const handleSubmit = useCallback(
(e: React.FormEvent) => {
e.preventDefault();
if (id) {
const payload: ApiUpdateCollectionPayload = {
id,
discoverable,
sensitive,
};
void dispatch(updateCollection({ payload })).then(() => {
history.push(`/collections`);
});
} else {
const payload: ApiCreateCollectionPayload = {
name: temporaryState.initialName,
description: temporaryState.initialDescription,
discoverable,
sensitive,
};
if (temporaryState.initialTopic) {
payload.tag_name = temporaryState.initialTopic;
}
void dispatch(
createCollection({
payload,
}),
).then((result) => {
if (isFulfilled(result)) {
history.replace(
`/collections/${result.payload.collection.id}/edit/settings`,
);
history.push(`/collections`);
}
});
}
},
[id, discoverable, sensitive, dispatch, history, temporaryState],
);
return (
<FormStack as='form' onSubmit={handleSubmit}>
{!id && (
<WizardStepHeader
step={3}
title={
<FormattedMessage
id='collections.create.settings_title'
defaultMessage='Settings'
/>
}
/>
)}
<Fieldset
legend={
<FormattedMessage
id='collections.visibility_title'
defaultMessage='Visibility'
/>
}
>
<RadioButtonField
label={
<FormattedMessage
id='collections.visibility_public'
defaultMessage='Public'
/>
}
hint={
<FormattedMessage
id='collections.visibility_public_hint'
defaultMessage='Discoverable in search results and other areas where recommendations appear.'
/>
}
value='public'
checked={discoverable}
onChange={handleDiscoverableChange}
/>
<RadioButtonField
label={
<FormattedMessage
id='collections.visibility_unlisted'
defaultMessage='Unlisted'
/>
}
hint={
<FormattedMessage
id='collections.visibility_unlisted_hint'
defaultMessage='Visible to anyone with a link. Hidden from search results and recommendations.'
/>
}
value='unlisted'
checked={!discoverable}
onChange={handleDiscoverableChange}
/>
</Fieldset>
<Fieldset
legend={
<FormattedMessage
id='collections.content_warning'
defaultMessage='Content warning'
/>
}
>
<CheckboxField
label={
<FormattedMessage
id='collections.mark_as_sensitive'
defaultMessage='Mark as sensitive'
/>
}
hint={
<FormattedMessage
id='collections.mark_as_sensitive_hint'
defaultMessage="Hides the collection's description and accounts behind a content warning. The collection name will still be visible."
/>
}
checked={sensitive}
onChange={handleSensitiveChange}
/>
</Fieldset>
<div className='actions'>
<Button type='submit'>
{id ? (
<FormattedMessage id='lists.save' defaultMessage='Save' />
) : (
<FormattedMessage
id='collections.create_collection'
defaultMessage='Create collection'
/>
)}
</Button>
</div>
</FormStack>
);
};

View File

@@ -0,0 +1,41 @@
import type {
ApiCollectionJSON,
ApiCreateCollectionPayload,
} from '@/mastodon/api_types/collections';
/**
* Temporary editor state across creation steps,
* kept in location state
*/
export type TempCollectionState =
| Partial<ApiCreateCollectionPayload>
| undefined;
/**
* Resolve initial editor state. Temporary location state
* trumps stored data, otherwise initial values are returned.
*/
export function getInitialState(
collection: ApiCollectionJSON | null | undefined,
locationState: TempCollectionState,
) {
const {
id,
name = '',
description = '',
tag,
language = '',
discoverable = true,
sensitive = false,
} = collection ?? {};
return {
id,
initialName: locationState?.name ?? name,
initialDescription: locationState?.description ?? description,
initialTopic: locationState?.tag_name ?? tag?.name ?? '',
initialLanguage: locationState?.language ?? language,
initialDiscoverable: locationState?.discoverable ?? discoverable,
initialSensitive: locationState?.sensitive ?? sensitive,
};
}

View File

@@ -0,0 +1,15 @@
.step {
font-size: 13px;
color: var(--color-text-secondary);
}
.title {
font-size: 22px;
line-height: 1.2;
margin-top: 4px;
}
.description {
font-size: 15px;
margin-top: 8px;
}

View File

@@ -0,0 +1,23 @@
import { FormattedMessage } from 'react-intl';
import classes from './styles.module.scss';
export const WizardStepHeader: React.FC<{
step: number;
title: React.ReactElement;
description?: React.ReactElement;
}> = ({ step, title, description }) => {
return (
<header>
<FormattedMessage
id='collections.create.steps'
defaultMessage='Step {step}/{total}'
values={{ step, total: 3 }}
>
{(content) => <p className={classes.step}>{content}</p>}
</FormattedMessage>
<h2 className={classes.title}>{title}</h2>
{!!description && <p className={classes.description}>{description}</p>}
</header>
);
};

View File

@@ -21,12 +21,10 @@ import {
} from 'mastodon/reducers/slices/collections';
import { useAppSelector, useAppDispatch } from 'mastodon/store';
import { messages as editorMessages } from './editor';
const messages = defineMessages({
heading: { id: 'column.collections', defaultMessage: 'My collections' },
create: {
id: 'collections.create_collection',
defaultMessage: 'Create collection',
},
view: {
id: 'collections.view_collection',
defaultMessage: 'View collection',
@@ -60,14 +58,35 @@ const ListItem: React.FC<{
const menu = useMemo(
() => [
{ text: intl.formatMessage(messages.view), to: `/collections/${id}` },
{ text: intl.formatMessage(messages.delete), action: handleDeleteClick },
null,
{
text: intl.formatMessage(editorMessages.manageAccounts),
to: `/collections/${id}/edit`,
},
{
text: intl.formatMessage(editorMessages.editDetails),
to: `/collections/${id}/edit/details`,
},
{
text: intl.formatMessage(editorMessages.editSettings),
to: `/collections/${id}/edit/settings`,
},
null,
{
text: intl.formatMessage(messages.delete),
action: handleDeleteClick,
dangerous: true,
},
],
[intl, id, handleDeleteClick],
);
return (
<div className='lists__item'>
<Link to={`/collections/${id}/edit`} className='lists__item__title'>
<Link
to={`/collections/${id}/edit/details`}
className='lists__item__title'
>
<span>{name}</span>
</Link>
@@ -132,8 +151,8 @@ export const Collections: React.FC<{
<Link
to='/collections/new'
className='column-header__button'
title={intl.formatMessage(messages.create)}
aria-label={intl.formatMessage(messages.create)}
title={intl.formatMessage(editorMessages.create)}
aria-label={intl.formatMessage(editorMessages.create)}
>
<Icon id='plus' icon={AddIcon} />
</Link>

View File

@@ -231,10 +231,7 @@ class SwitchingColumnsArea extends PureComponent {
<WrappedRoute path='/mutes' component={Mutes} content={children} />
<WrappedRoute path='/lists' component={Lists} content={children} />
{areCollectionsEnabled() &&
<WrappedRoute path='/collections/new' component={CollectionsEditor} content={children} />
}
{areCollectionsEnabled() &&
<WrappedRoute path='/collections/:id/edit' component={CollectionsEditor} content={children} />
<WrappedRoute path={['/collections/new', '/collections/:id/edit']} component={CollectionsEditor} content={children} />
}
{areCollectionsEnabled() &&
<WrappedRoute path='/collections' component={Collections} content={children} />

View File

@@ -17,8 +17,12 @@
"account.activity": "Activitat",
"account.add_note": "Afegeix una nota personal",
"account.add_or_remove_from_list": "Afegeix o elimina de les llistes",
"account.badges.admin": "Administrador",
"account.badges.blocked": "Blocat",
"account.badges.bot": "Automatitzat",
"account.badges.domain_blocked": "Domini blocat",
"account.badges.group": "Grup",
"account.badges.muted": "Silenciat",
"account.block": "Bloca @{name}",
"account.block_domain": "Bloca el domini {domain}",
"account.block_short": "Bloca",
@@ -42,6 +46,8 @@
"account.featured.hashtags": "Etiquetes",
"account.featured_tags.last_status_at": "Darrer tut el {date}",
"account.featured_tags.last_status_never": "No hi ha tuts",
"account.fields.scroll_next": "Mostrar el següent",
"account.fields.scroll_prev": "Mostrar l'anterior",
"account.filters.all": "Tota l'activitat",
"account.filters.boosts_toggle": "Mostra els impulsos",
"account.filters.posts_boosts": "Publicacions i impulsos",
@@ -73,6 +79,23 @@
"account.locked_info": "L'estat de privacitat del compte està definit com a blocat. El propietari revisa manualment qui pot seguir-lo.",
"account.media": "Contingut",
"account.mention": "Menciona @{name}",
"account.menu.add_to_list": "Afegir a la llista…",
"account.menu.block": "Blocar el compte",
"account.menu.block_domain": "Blocar {domain}",
"account.menu.copied": "Compte copiat al porta-retalls",
"account.menu.copy": "Copiar l'enllaç",
"account.menu.direct": "Mencionar privadament",
"account.menu.hide_reblogs": "Amagar impulsos en les línies de temps",
"account.menu.mention": "Mencionar",
"account.menu.mute": "Silenciar el compte",
"account.menu.open_original_page": "Veure a {domain}",
"account.menu.remove_follower": "Eliminar el seguidor",
"account.menu.report": "Denunciar el compte",
"account.menu.share": "Compartir…",
"account.menu.show_reblogs": "Mostrar impulsos en les línies de temps",
"account.menu.unblock": "Desblocar el compte",
"account.menu.unblock_domain": "Desblocar {domain}",
"account.menu.unmute": "Deixar de silenciar el compte",
"account.moved_to": "{name} ha indicat que el seu nou compte és:",
"account.mute": "Silencia @{name}",
"account.mute_notifications_short": "Silencia les notificacions",
@@ -185,21 +208,31 @@
"closed_registrations_modal.find_another_server": "Troba un altre servidor",
"closed_registrations_modal.preamble": "Mastodon és descentralitzat. Per tant, tinguis on tinguis el compte, seràs capaç de seguir i interactuar amb tothom des d'aquest servidor. Fins i tot pots tenir el compte en el teu propi servidor!",
"closed_registrations_modal.title": "Registrant-se a Mastodon",
"collections.collection_description": "Descripció",
"collections.collection_name": "Nom",
"collections.collection_topic": "Tema",
"collections.create_a_collection_hint": "Creeu una coŀlecció per a recomanar o compartir amb d'altres els vostres comptes preferits.",
"collections.create_collection": "Crea una coŀlecció",
"collections.delete_collection": "Elimina la coŀlecció",
"collections.description_length_hint": "Límit de 100 caràcters",
"collections.error_loading_collections": "Hi ha hagut un error en carregar les vostres coŀleccions.",
"collections.mark_as_sensitive": "Marcar com a sensible",
"collections.mark_as_sensitive_hint": "Amaga la descripció i els comptes de la coŀlecció rere un avís de contingut. El nom de la coŀlecció serà encara visible.",
"collections.name_length_hint": "Límit de 100 caràcters",
"collections.no_collections_yet": "Encara no hi ha coŀleccions.",
"collections.topic_hint": "Afegir una etiqueta que ajudi altres a entendre el tema principal de la coŀlecció.",
"collections.view_collection": "Mostra la coŀlecció",
"column.about": "Quant a",
"column.blocks": "Usuaris blocats",
"column.bookmarks": "Marcadors",
"column.collections": "Les meves coŀleccions",
"column.community": "Línia de temps local",
"column.create_collection": "Crear una coŀlecció",
"column.create_list": "Crea una llista",
"column.direct": "Mencions privades",
"column.directory": "Navega pels perfils",
"column.domain_blocks": "Dominis blocats",
"column.edit_collection": "Editar la col·lecció",
"column.edit_list": "Edita la llista",
"column.favourites": "Favorits",
"column.firehose": "Tuts en directe",
@@ -254,6 +287,9 @@
"confirmations.delete.confirm": "Elimina",
"confirmations.delete.message": "Segur que vols eliminar aquest tut?",
"confirmations.delete.title": "Eliminar la publicació?",
"confirmations.delete_collection.confirm": "Eliminar",
"confirmations.delete_collection.message": "Aquesta acció no es pot desfer.",
"confirmations.delete_collection.title": "Voleu eliminar «{name}»?",
"confirmations.delete_list.confirm": "Elimina",
"confirmations.delete_list.message": "Segur que vols suprimir permanentment aquesta llista?",
"confirmations.delete_list.title": "Eliminar la llista?",

View File

@@ -236,28 +236,43 @@
"collections.collection_description": "Description",
"collections.collection_name": "Name",
"collections.collection_topic": "Topic",
"collections.content_warning": "Content warning",
"collections.continue": "Continue",
"collections.create.accounts_subtitle": "Only accounts you follow who have opted into discovery can be added.",
"collections.create.accounts_title": "Who will you feature in this collection?",
"collections.create.basic_details_title": "Basic details",
"collections.create.settings_title": "Settings",
"collections.create.steps": "Step {step}/{total}",
"collections.create_a_collection_hint": "Create a collection to recommend or share your favourite accounts with others.",
"collections.create_collection": "Create collection",
"collections.delete_collection": "Delete collection",
"collections.description_length_hint": "100 characters limit",
"collections.edit_details": "Edit basic details",
"collections.edit_settings": "Edit settings",
"collections.error_loading_collections": "There was an error when trying to load your collections.",
"collections.manage_accounts": "Manage accounts",
"collections.manage_accounts_in_collection": "Manage accounts in this collection",
"collections.mark_as_sensitive": "Mark as sensitive",
"collections.mark_as_sensitive_hint": "Hides the collection's description and accounts behind a content warning. The collection name will still be visible.",
"collections.name_length_hint": "100 characters limit",
"collections.new_collection": "New collection",
"collections.no_collections_yet": "No collections yet.",
"collections.topic_hint": "Add a hashtag that helps others understand the main topic of this collection.",
"collections.view_collection": "View collection",
"collections.visibility_public": "Public",
"collections.visibility_public_hint": "Discoverable in search results and other areas where recommendations appear.",
"collections.visibility_title": "Visibility",
"collections.visibility_unlisted": "Unlisted",
"collections.visibility_unlisted_hint": "Visible to anyone with a link. Hidden from search results and recommendations.",
"column.about": "About",
"column.blocks": "Blocked users",
"column.bookmarks": "Bookmarks",
"column.collections": "My collections",
"column.community": "Local timeline",
"column.create_collection": "Create collection",
"column.create_list": "Create list",
"column.direct": "Private mentions",
"column.directory": "Browse profiles",
"column.domain_blocks": "Blocked domains",
"column.edit_collection": "Edit collection",
"column.edit_list": "Edit list",
"column.favourites": "Favorites",
"column.firehose": "Live feeds",

View File

@@ -16,7 +16,7 @@
"account.account_note_header": "Henkilökohtainen muistiinpano",
"account.activity": "Toiminta",
"account.add_note": "Lisää henkilökohtainen muistiinpano",
"account.add_or_remove_from_list": "Lisää tai poista listoista",
"account.add_or_remove_from_list": "Lisää tai poista listoilta",
"account.badges.admin": "Ylläpitäjä",
"account.badges.blocked": "Estetty",
"account.badges.bot": "Botti",
@@ -95,7 +95,7 @@
"account.menu.show_reblogs": "Näytä tehostukset aikajanalla",
"account.menu.unblock": "Kumoa tilin esto",
"account.menu.unblock_domain": "Kumoa palvelimen {domain} esto",
"account.menu.unmute": "Poista tilin mykistys",
"account.menu.unmute": "Kumoa tilin mykistys",
"account.moved_to": "{name} on ilmoittanut uudeksi tilikseen",
"account.mute": "Mykistä @{name}",
"account.mute_notifications_short": "Mykistä ilmoitukset",
@@ -128,9 +128,9 @@
"account.unblock_short": "Kumoa esto",
"account.unendorse": "Kumoa profiilissa esittely",
"account.unfollow": "Älä seuraa",
"account.unmute": "Poista käyttäjän @{name} mykistys",
"account.unmute_notifications_short": "Poista ilmoitusten mykistys",
"account.unmute_short": "Poista mykistys",
"account.unmute": "Kumoa käyttäjän @{name} mykistys",
"account.unmute_notifications_short": "Kumoa ilmoitusten mykistys",
"account.unmute_short": "Kumoa mykistys",
"account_note.placeholder": "Lisää muistiinpano napsauttamalla",
"admin.dashboard.daily_retention": "Käyttäjien pysyvyys päivittäin rekisteröitymisen jälkeen",
"admin.dashboard.monthly_retention": "Käyttäjien pysyvyys kuukausittain rekisteröitymisen jälkeen",
@@ -501,7 +501,7 @@
"follow_suggestions.popular_suggestion_longer": "Suosittu palvelimella {domain}",
"follow_suggestions.similar_to_recently_followed_longer": "Samankaltainen kuin äskettäin seuraamasi profiilit",
"follow_suggestions.view_all": "Näytä kaikki",
"follow_suggestions.who_to_follow": "Ehdotuksia seurattavaksi",
"follow_suggestions.who_to_follow": "Seurantaehdotuksia",
"followed_tags": "Seurattavat aihetunnisteet",
"footer.about": "Tietoja",
"footer.about_mastodon": "Tietoja Mastodonista",
@@ -1111,7 +1111,7 @@
"video.play": "Toista",
"video.skip_backward": "Siirry taaksepäin",
"video.skip_forward": "Siirry eteenpäin",
"video.unmute": "Poista mykistys",
"video.unmute": "Kumoa mykistys",
"video.volume_down": "Vähennä äänenvoimakkuutta",
"video.volume_up": "Lisää äänenvoimakkuutta",
"visibility_modal.button_title": "Aseta näkyvyys",

View File

@@ -57,7 +57,7 @@
"account.follow": "Suivre",
"account.follow_back": "Suivre en retour",
"account.follow_back_short": "Suivre en retour",
"account.follow_request": "Demande dabonnement",
"account.follow_request": "Demander à suivre",
"account.follow_request_cancel": "Annuler la demande",
"account.follow_request_cancel_short": "Annuler",
"account.follow_request_short": "Demander à suivre",
@@ -85,12 +85,23 @@
"account.menu.copied": "Lien du compte copié dans le presse-papiers",
"account.menu.copy": "Copier le lien",
"account.menu.direct": "Mentionner en privé",
"account.menu.hide_reblogs": "Masquer les partages dans le fil dactualité",
"account.menu.mention": "Mentionner",
"account.menu.mute": "Masquer le compte",
"account.menu.open_original_page": "Voir sur {domain}",
"account.menu.remove_follower": "Supprimer des abonné·e·s",
"account.menu.report": "Signaler le compte",
"account.menu.share": "Partager…",
"account.menu.show_reblogs": "Afficher les partages dans le fil d'actualité",
"account.menu.unblock": "Débloquer le compte",
"account.menu.unblock_domain": "Débloquer {domain}",
"account.menu.unmute": "Ne plus masquer le compte",
"account.moved_to": "{name} a indiqué que son nouveau compte est maintenant:",
"account.mute": "Masquer @{name}",
"account.mute_notifications_short": "Rendre les notifications muettes",
"account.mute_short": "Rendre muet",
"account.muted": "Masqué·e",
"account.muting": "Sourdine",
"account.muting": "Masqué",
"account.mutual": "Vous vous suivez mutuellement",
"account.no_bio": "Description manquante.",
"account.node_modal.callout": "Les notes personnelles sont ne sont visibles que pour vous.",
@@ -523,7 +534,7 @@
"hashtag.counter_by_uses_today": "{count, plural, one {{counter} message} other {{counter} messages}} aujourdhui",
"hashtag.feature": "Mettre en avant sur votre profil",
"hashtag.follow": "Suivre ce hashtag",
"hashtag.mute": "Mettre #{hashtag} en sourdine",
"hashtag.mute": "Masquer #{hashtag}",
"hashtag.unfeature": "Ne plus mettre en avant sur votre profil",
"hashtag.unfollow": "Ne plus suivre ce hashtag",
"hashtags.and_other": "…et {count, plural, other {# de plus}}",
@@ -1008,7 +1019,7 @@
"status.quote_error.filtered": "Caché par un de vos filtres",
"status.quote_error.limited_account_hint.action": "Afficher quand même",
"status.quote_error.limited_account_hint.title": "Ce compte a été masqué par la modération de {domain}.",
"status.quote_error.muted_account_hint.title": "Ce message est masqué car vous avez masqué @{name}.",
"status.quote_error.muted_account_hint.title": "Ce message est caché car vous avez masqué @{name}.",
"status.quote_error.not_available": "Message indisponible",
"status.quote_error.pending_approval": "Message en attente",
"status.quote_error.pending_approval_popout.body": "Sur Mastodon, vous pouvez contrôler si quelqu'un peut vous citer. Ce message est en attente pendant que nous recevons l'approbation de l'auteur original.",

View File

@@ -57,7 +57,7 @@
"account.follow": "Suivre",
"account.follow_back": "Suivre en retour",
"account.follow_back_short": "Suivre en retour",
"account.follow_request": "Demande dabonnement",
"account.follow_request": "Demander à suivre",
"account.follow_request_cancel": "Annuler la demande",
"account.follow_request_cancel_short": "Annuler",
"account.follow_request_short": "Demander à suivre",
@@ -85,12 +85,23 @@
"account.menu.copied": "Lien du compte copié dans le presse-papiers",
"account.menu.copy": "Copier le lien",
"account.menu.direct": "Mentionner en privé",
"account.menu.hide_reblogs": "Masquer les partages dans le fil dactualité",
"account.menu.mention": "Mentionner",
"account.menu.mute": "Masquer le compte",
"account.menu.open_original_page": "Voir sur {domain}",
"account.menu.remove_follower": "Supprimer des abonné·e·s",
"account.menu.report": "Signaler le compte",
"account.menu.share": "Partager…",
"account.menu.show_reblogs": "Afficher les partages dans le fil d'actualité",
"account.menu.unblock": "Débloquer le compte",
"account.menu.unblock_domain": "Débloquer {domain}",
"account.menu.unmute": "Ne plus masquer le compte",
"account.moved_to": "{name} a indiqué que son nouveau compte est maintenant :",
"account.mute": "Masquer @{name}",
"account.mute_notifications_short": "Désactiver les notifications",
"account.mute_short": "Mettre en sourdine",
"account.mute_short": "Masquer",
"account.muted": "Masqué·e",
"account.muting": "Sourdine",
"account.muting": "Masqué",
"account.mutual": "Vous vous suivez mutuellement",
"account.no_bio": "Aucune description fournie.",
"account.node_modal.callout": "Les notes personnelles sont ne sont visibles que pour vous.",
@@ -523,7 +534,7 @@
"hashtag.counter_by_uses_today": "{count, plural, one {{counter} message} other {{counter} messages}} aujourdhui",
"hashtag.feature": "Mettre en avant sur votre profil",
"hashtag.follow": "Suivre le hashtag",
"hashtag.mute": "Mettre #{hashtag} en sourdine",
"hashtag.mute": "Masquer #{hashtag}",
"hashtag.unfeature": "Ne plus mettre en avant sur votre profil",
"hashtag.unfollow": "Ne plus suivre le hashtag",
"hashtags.and_other": "…et {count, plural, other {# de plus}}",
@@ -1008,7 +1019,7 @@
"status.quote_error.filtered": "Caché par un de vos filtres",
"status.quote_error.limited_account_hint.action": "Afficher quand même",
"status.quote_error.limited_account_hint.title": "Ce compte a été masqué par la modération de {domain}.",
"status.quote_error.muted_account_hint.title": "Ce message est masqué car vous avez masqué @{name}.",
"status.quote_error.muted_account_hint.title": "Ce message est caché car vous avez masqué @{name}.",
"status.quote_error.not_available": "Message indisponible",
"status.quote_error.pending_approval": "Message en attente",
"status.quote_error.pending_approval_popout.body": "Sur Mastodon, vous pouvez contrôler si quelqu'un peut vous citer. Ce message est en attente pendant que nous recevons l'approbation de l'auteur original.",

View File

@@ -46,6 +46,8 @@
"account.featured.hashtags": "Haischlibeanna",
"account.featured_tags.last_status_at": "Postáil is déanaí ar {date}",
"account.featured_tags.last_status_never": "Gan aon phoist",
"account.fields.scroll_next": "Taispeáin an chéad cheann eile",
"account.fields.scroll_prev": "Taispeáin roimhe seo",
"account.filters.all": "Gach gníomhaíocht",
"account.filters.boosts_toggle": "Taispeáin borradh",
"account.filters.posts_boosts": "Poist agus borradh",
@@ -77,6 +79,23 @@
"account.locked_info": "Tá an socrú príobháideachais don cuntas seo curtha go 'faoi ghlas'. Déanann an t-úinéir léirmheas ar cén daoine atá ceadaithe an cuntas leanúint.",
"account.media": "Meáin",
"account.mention": "Luaigh @{name}",
"account.menu.add_to_list": "Cuir leis an liosta…",
"account.menu.block": "Cuntas blocáilte",
"account.menu.block_domain": "Blocáil {domain}",
"account.menu.copied": "Cóipeáladh nasc an chuntais chuig an ghearrthaisce",
"account.menu.copy": "Cóipeáil nasc",
"account.menu.direct": "Luaigh go príobháideach",
"account.menu.hide_reblogs": "Folaigh borradh sa líne ama",
"account.menu.mention": "Luaigh",
"account.menu.mute": "Balbhaigh cuntas",
"account.menu.open_original_page": "Féach ar {domain}",
"account.menu.remove_follower": "Bain leantóir",
"account.menu.report": "Tuairiscigh cuntas",
"account.menu.share": "Comhroinn…",
"account.menu.show_reblogs": "Taispeáin borradh san amlíne",
"account.menu.unblock": "Díbhlocáil cuntas",
"account.menu.unblock_domain": "Díbhlocáil {domain}",
"account.menu.unmute": "Díbholg an cuntas",
"account.moved_to": "Tá tugtha le fios ag {name} gurb é an cuntas nua atá acu ná:",
"account.mute": "Balbhaigh @{name}",
"account.mute_notifications_short": "Balbhaigh fógraí",

View File

@@ -411,7 +411,7 @@
"keyboard_shortcuts.muted": "o lukin e lipu sina pi jan len",
"keyboard_shortcuts.my_profile": "o lukin e lipu sina",
"keyboard_shortcuts.open_media": "o lukin e sitelen",
"keyboard_shortcuts.pinned": "o lukin pi lipu sina pi toki sewi",
"keyboard_shortcuts.pinned": "o lukin pi toki sina sewi",
"keyboard_shortcuts.reply": "o toki lon ijo ni",
"keyboard_shortcuts.toggle_hidden": "o lukin ala lukin e toki len",
"keyboard_shortcuts.toggle_sensitivity": "o lukin ala lukin e sitelen",

View File

@@ -24,7 +24,7 @@
%span= t('accounts.posts', count: account.statuses_count)
%td
%b= account_formatted_stat(account.following_count)
%span= t('accounts.following')
%span= t('accounts.following', count: account.following_count)
%td
%b= hide_followers_count?(account) ? '-' : account_formatted_stat(account.followers_count)
%span= t('accounts.followers', count: account.followers_count)

View File

@@ -9,7 +9,6 @@ af:
followers:
one: Volgeling
other: Volgelinge
following: Volg
nothing_here: Daar is niks hier nie!
posts:
one: Plasing

View File

@@ -10,7 +10,6 @@ an:
followers:
one: Seguidor
other: Seguidores
following: Seguindo
instance_actor_flash: Esta cuenta ye un actor virtual utilizau pa representar a lo servidor en ell mesmo y no a garra usuario individual. S'utiliza pa propositos d'a federación y no s'ha de suspender.
last_active: zaguera connexión
link_verified_on: La propiedat d'este vinclo estió verificada lo %{date}

View File

@@ -14,7 +14,6 @@ ar:
other: متابِعون
two: متابِعان
zero: لا متابِع
following: مُتابَع
instance_actor_flash: هذا الحساب هو ممثل افتراضي يُستخدم لتمثيل الخادم نفسه ولا يمثل أي مستخدم فردي، يُستخدم لأغراض الاتحاد ولا ينبغي حظره.
last_active: آخر نشاط
link_verified_on: تم التحقق مِن ملكية هذا الرابط بتاريخ %{date}

View File

@@ -14,7 +14,6 @@ be:
many: Падпісчыкаў
one: Падпісчык
other: Падпісчыкі
following: Падпіскі
instance_actor_flash: Гэты ўліковы запіс - лічбавы аватар, неабходны для рэпрэзентацыі самога сервера, а не якой-небудзь асобы. Ён выкарыстоўваецца для федэралізацыі і не можа быць замарожаны.
last_active: апошняя актыўнасць
link_verified_on: Права ўласнасці на гэтую спасылку праверана %{date}

View File

@@ -10,7 +10,6 @@ bg:
followers:
one: Последовател
other: Последователи
following: Следва
instance_actor_flash: Акаунтът е виртуално действащо лице, представляващо сървъра, а не отделен потребител. Използва се за целите на федериране и не бива да се спира.
last_active: последна дейност
link_verified_on: Собствеността върху тази връзка е проверена на %{date}

View File

@@ -10,7 +10,6 @@ bn:
followers:
one: যুক্ত আছে
other: যারা যুক্ত হয়েছে
following: যুক্ত করা
instance_actor_flash: এই অ্যাকাউন্টটি একটি ভার্চুয়াল সত্তা যা সার্ভারের প্রতিনিধিত্ব করতে ব্যবহৃত হয় এবং কোনও স্বতন্ত্র ব্যবহারকারী নয়। এটি ফেডারেশনের উদ্দেশ্যে ব্যবহার করা হয় এবং স্থগিত করা উচিত নয়.
last_active: শেষ সক্রিয় ছিল
link_verified_on: এই লিংকের মালিকানা শেষ চেক করা হয় %{date} তারিখে

View File

@@ -12,7 +12,6 @@ br:
one: Heulier·ez
other: Heulier·ez
two: Heulier·ez
following: Koumanantoù
last_active: oberiantiz ziwezhañ
nothing_here: N'eus netra amañ !
posts:

View File

@@ -12,7 +12,6 @@ ca:
followers:
one: Seguidor
other: Seguidors
following: Seguint
instance_actor_flash: Aquest compte és un actor virtual usat per a representar el mateix servidor i no cap usuari individual. Es fa servir per a federar i no s'hauria d'esborrar.
last_active: última activitat
link_verified_on: La propietat d'aquest enllaç va quedar verificada el %{date}
@@ -1665,6 +1664,7 @@ ca:
disabled_account: El teu compte actual no serà plenament utilitzable després. Tanmateix, tindràs accés a exportació de dades així com reactivació.
followers: Aquesta acció mourà tots els seguidors des de l'actual al compte nou
only_redirect_html: Alternativament, pots <a href="%{path}">posar només una redirecció en el teu perfil</a>.
other_data: No es mourà cap altra dada automàticament (incloses les vostres publicacions ni els comptes que seguiu)
redirect: El perfil del teu compte actual serà actualitzat amb un avís de redirecció i serà exclòs de les cerques
moderation:
title: Moderació

View File

@@ -10,7 +10,6 @@ ckb:
followers:
one: شوێنکەوتوو
other: شوێن‌کەوتووان
following: شوێن‌کەوتووی
instance_actor_flash: ئەم ئەکاونتە ئەکتەرێکی مەجازییە کە بەکاردێت بۆ نوێنەرایەتیکردنی خودی سێرڤەرەکە نەک هیچ بەکارهێنەرێکی تاکەکەسی. بۆ مەبەستی فیدراسیۆن بەکاردێت و نابێت ڕابگیرێت.
last_active: دوا چالاکی
link_verified_on: خاوەنداریەتی ئەم لینکە لە %{date} چێک کراوە

View File

@@ -9,7 +9,6 @@ co:
followers:
one: Abbunatu·a
other: Abbunati
following: Abbunamenti
instance_actor_flash: Stu contu virtuale riprisenta u servore stessu, micca un'utilizatore individuale. Hè utilizatu per scopi di federazione è ùn duveria mai esse suspesu.
last_active: ultima attività
link_verified_on: A pruprietà d'issu ligame hè stata verificata u %{date}

View File

@@ -14,7 +14,6 @@ cs:
many: Sledujících
one: Sledující
other: Sledujících
following: Sledovaných
instance_actor_flash: Tento účet je virtuální aktér, který představuje server samotný, nikoliv jednotlivého uživatele. Používá se pro účely federace a neměl by být pozastaven.
last_active: naposledy aktivní
link_verified_on: Vlastnictví tohoto odkazu bylo zkontrolováno %{date}

View File

@@ -16,7 +16,6 @@ cy:
other: Dilynwyr
two: Dilynwyr
zero: Dilynwyr
following: Yn dilyn
instance_actor_flash: Mae'r cyfrif hwn yn actor rhithwir sy'n cael ei ddefnyddio i gynrychioli'r gweinydd ei hun ac nid unrhyw ddefnyddiwr unigol. Mae'n cael ei ddefnyddio at ddibenion ffederasiwn ac ni ddylid ei atal.
last_active: gweithgar ddiwethaf
link_verified_on: Gwiriwyd perchnogaeth y ddolen yma ar %{date}

View File

@@ -12,7 +12,9 @@ da:
followers:
one: Følger
other: Følgere
following: Følger
following:
one: Fulgt
other: Fulgte
instance_actor_flash: Denne konto er en virtuel aktør repræsenterende selve serveren og ikke en individuel bruger. Den anvendes til fællesformål og bør ikke suspenderes.
last_active: senest aktiv
link_verified_on: Ejerskab af dette link blev tjekket %{date}

View File

@@ -12,7 +12,6 @@ de:
followers:
one: Follower
other: Follower
following: Folge ich
instance_actor_flash: Dieses Konto ist ein virtueller Akteur, der den Server selbst repräsentiert, und kein persönliches Profil. Es wird für Föderationszwecke verwendet und sollte daher nicht gesperrt werden.
last_active: zuletzt aktiv
link_verified_on: Das Profil mit dieser E-Mail-Adresse wurde bereits am %{date} bestätigt

View File

@@ -12,7 +12,6 @@ el:
followers:
one: Ακόλουθος
other: Ακόλουθοι
following: Ακολουθείτε
instance_actor_flash: Αυτός ο λογαριασμός είναι εικονικός και χρησιμοποιείται για να αντιπροσωπεύει τον ίδιο τον διακομιστή και όχι κάποιον μεμονωμένο χρήστη. Χρησιμοποιείται για σκοπούς ομοσπονδίας και δεν πρέπει να ανασταλεί.
last_active: τελευταία ενεργός/ή
link_verified_on: Η ιδιοκτησία αυτού του συνδέσμου ελέγχθηκε στις %{date}

View File

@@ -12,7 +12,9 @@ en-GB:
followers:
one: Follower
other: Followers
following: Following
following:
one: Following
other: Following
instance_actor_flash: This account is a virtual actor used to represent the server itself and not any individual user. It is used for federation purposes and should not be suspended.
last_active: last active
link_verified_on: Ownership of this link was checked on %{date}

View File

@@ -12,7 +12,9 @@ en:
followers:
one: Follower
other: Followers
following: Following
following:
one: Following
other: Following
instance_actor_flash: This account is a virtual actor used to represent the server itself and not any individual user. It is used for federation purposes and should not be suspended.
last_active: last active
link_verified_on: Ownership of this link was checked on %{date}

View File

@@ -10,7 +10,6 @@ eo:
followers:
one: Sekvanto
other: Sekvantoj
following: Sekvatoj
instance_actor_flash: Ĉi tiu konto estas virtuala agento uzata por reprezenti la servilon mem kaj neniun individuan uzanton. Ĝi estas uzata por federaciaj celoj kaj ĝi devas ne esti suspendita.
last_active: laste aktiva
link_verified_on: Proprieto de ĉi tiu ligilo estis kontrolita je %{date}

View File

@@ -12,7 +12,9 @@ es-AR:
followers:
one: Seguidor
other: Seguidores
following: Siguiendo
following:
one: Siguiendo
other: Siguiendo
instance_actor_flash: Esta cuenta es un actor virtual usado para representar al servidor en sí mismo y no a ningún usuario individual. Se usa para propósitos de la federación y no debe ser suspendido.
last_active: última actividad
link_verified_on: La propiedad de este enlace fue verificada el %{date}

View File

@@ -12,7 +12,6 @@ es-MX:
followers:
one: Seguidor
other: Seguidores
following: Siguiendo
instance_actor_flash: Esta cuenta es un actor virtual utilizado para representar al servidor en sí mismo y no a ningún usuario individual. Se utiliza para propósitos de la federación y no se debe suspender.
last_active: última conexión
link_verified_on: La propiedad de este vínculo fue verificada el %{date}

View File

@@ -12,7 +12,6 @@ es:
followers:
one: Seguidor
other: Seguidores
following: Siguiendo
instance_actor_flash: Esta cuenta es un actor virtual utilizado para representar al propio servidor y no a ningún usuario individual. Se utiliza con fines de federación y no debe suspenderse.
last_active: última conexión
link_verified_on: La propiedad de este vínculo fue verificada el %{date}

View File

@@ -12,7 +12,6 @@ et:
followers:
one: Jälgija
other: Jälgijaid
following: Jälgib
instance_actor_flash: See on serveri enda virtuaalne konto. See ei esinda ühtegi kindlat kasutajat, vaid seda kasutatakse födereerumisel. Seda kontot ei tohi kustutada.
last_active: viimati aktiivne
link_verified_on: Selle lingi autorsust kontrolliti %{date}

View File

@@ -12,7 +12,6 @@ eu:
followers:
one: Jarraitzaile
other: jarraitzaile
following: Jarraitzen
instance_actor_flash: Kontu hau zerbitzaria adierazten duen aktore birtual bat da eta ez banako erabiltzaile bat. Federatzeko helburuarekin erabiltzen da eta ez da kanporatu behar.
last_active: azkenekoz aktiboa
link_verified_on: 'Esteka honen jabetzaren egiaztaketa data: %{date}'

View File

@@ -12,7 +12,6 @@ fa:
followers:
one: پی‌گیرنده
other: پی‌گیرنده
following: پی می‌گیرد
instance_actor_flash: این حساب عاملی مجازیست که به نمایندگی از خود کارساز استفاده می‌شود و نه کاربری جداگانه. این حساب به منظور اتصال به فدراسیون استفاده می‌شود و نباید معلق شود.
last_active: آخرین فعّالیت
link_verified_on: مالکیت این پیوند در %{date} بررسی شد

View File

@@ -12,7 +12,9 @@ fi:
followers:
one: seuraaja
other: seuraajaa
following: seurattavaa
following:
one: seurattava
other: seurattavaa
instance_actor_flash: Tämä tili on virtuaalinen toimija, jota käytetään edustamaan itse palvelinta eikä yksittäistä käyttäjää. Sitä käytetään federointitarkoituksiin, eikä sitä tule jäädyttää.
last_active: viimeksi aktiivinen
link_verified_on: Tämän linkin omistus on tarkastettu %{date}
@@ -693,13 +695,13 @@ fi:
no_one_assigned: Ei kukaan
notes:
create: Lisää muistiinpano
create_and_resolve: Ratkaise ja jätä muistiinpano
create_and_unresolve: Avaa uudelleen ja jätä muistiinpano
create_and_resolve: Ratkaise ja lisää muistiinpano
create_and_unresolve: Avaa uudelleen ja lisää muistiinpano
delete: Poista
placeholder: Kuvaile tehtyjä toimia tai lisää muita käyttäjään liittyviä merkintöjä…
title: Muistiinpanot
notes_description_html: Tarkastele ja jätä muistiinpanoja muille moderaattoreille ja itsellesi tulevaisuuteen
processed_msg: Raportin nro %{id} käsittely onnistui
processed_msg: Raportin nro %{id} käsittely onnistui
quick_actions_description_html: 'Suorita pikatoiminto tai vieritä alas nähdäksesi raportoitu sisältö:'
remote_user_placeholder: etäkäyttäjä palvelimelta %{instance}
reopen: Avaa raportti uudelleen
@@ -724,7 +726,7 @@ fi:
mark_as_sensitive_html: Merkitse loukkaavien julkaisujen media arkaluonteiseksi
silence_html: Rajoita merkittävästi käyttäjän <strong>@%{acct}</strong> tavoitettavuutta tekemällä profiilista ja sen sisällöstä näkyviä vain niille, jotka jo seuraavat tiliä tai etsivät sen manuaalisesti
suspend_html: Jäädytä <strong>@%{acct}</strong>, jolloin hänen profiilinsa ja sisältönsä ei ole käytettävissä ja hänen kanssaan on mahdotonta olla vuorovaikutuksessa
close_report: Merkitse raportti nro %{id} ratkaistuksi
close_report: Merkitse raportti nro %{id} ratkaistuksi
close_reports_html: Merkitse <strong>kaikki</strong> käyttäjään <strong>@%{acct}</strong> kohdistuvat raportit ratkaistuiksi
delete_data_html: Poista käyttäjän <strong>@%{acct}</strong> profiili ja sen sisältö 30 päivän kuluttua, ellei jäädytystä sillä välin kumota
preview_preamble_html: "<strong>@%{acct}</strong> saa varoituksen, jonka sisältö on seuraava:"
@@ -900,7 +902,7 @@ fi:
back_to_account: Takaisin tilisivulle
back_to_report: Takaisin raporttisivulle
batch:
add_to_report: Lisää raporttiin nro %{id}
add_to_report: Lisää raporttiin nro %{id}
remove_from_report: Poista raportista
report: Raportoi
contents: Sisältö
@@ -1178,7 +1180,7 @@ fi:
new_report:
body: "%{reporter} on raportoinut kohteen %{target}"
body_remote: Joku palvelimelta %{domain} raportoi kohteen %{target}
subject: Uusi raportti palvelimesta %{instance} (nro %{id})
subject: Uusi raportti palvelimelta %{instance} (nro %{id})
new_software_updates:
body: Uusia Mastodon-versioita on julkaistu, joten saatat haluta päivittää!
subject: Palvelimelle %{instance} ovat saatavilla uusia Mastodon-versioita!
@@ -1380,7 +1382,7 @@ fi:
description_html: Nämä ovat tiliisi kohdistuvia toimia sekä varoituksia, jotka palvelimen %{instance} ylläpito on lähettänyt sinulle.
recipient: Osoitettu käyttäjälle
reject_appeal: Hylkää valitus
status: Julkaisu nro %{id}
status: Julkaisu nro %{id}
status_removed: Julkaisu on jo poistettu järjestelmästä
title: "%{action} alkaen %{date}"
title_actions:
@@ -1709,7 +1711,7 @@ fi:
follow_request:
action: Hallitse seurantapyyntöjä
body: "%{name} on pyytänyt lupaa seurata sinua"
subject: 'Odottava seuraamispyyntö: %{name}'
subject: 'Odottava seuraaja: %{name}'
title: Uusi seurantapyyntö
mention:
action: Vastaa
@@ -1849,7 +1851,7 @@ fi:
edge: Edge
electron: Electron
firefox: Firefox
generic: tuntematon selain
generic: Tuntematon selain
huawei_browser: Huawei-selain
ie: Internet Explorer
micro_messenger: MicroMessenger
@@ -1860,7 +1862,7 @@ fi:
qq: QQ Browser
safari: Safari
uc_browser: UC Browser
unknown_browser: tuntematon selain
unknown_browser: Tuntematon selain
weibo: Weibo
current_session: Nykyinen istunto
date: Päivämäärä
@@ -1950,7 +1952,7 @@ fi:
pin_errors:
direct: Vain mainituille käyttäjille näkyviä julkaisuja ei voi kiinnittää
limit: Olet jo kiinnittänyt enimmäismäärän julkaisuja
ownership: Muiden julkaisuja ei voi kiinnittää
ownership: Toisen julkaisua ei voi kiinnittää
reblog: Tehostusta ei voi kiinnittää
quote_error:
not_available: Julkaisu ei saatavilla
@@ -1968,7 +1970,7 @@ fi:
public: Julkinen
public_long: Kuka tahansa Mastodonissa ja sen ulkopuolella
unlisted: Vaivihkaa julkinen
unlisted_long: Piilotettu Mastodonin hakutuloksista, trendeistä ja julkisilta aikajanoilta
unlisted_long: Piilotetaan Mastodonin hakutuloksista, trendeistä ja julkisilta aikajanoilta
statuses_cleanup:
enabled: Poista vanhat julkaisut automaattisesti
enabled_hint: Poistaa julkaisusi automaattisesti, kun ne saavuttavat valitun ikäkynnyksen, ellei jokin alla olevista poikkeuksista tule kyseeseen
@@ -2105,7 +2107,7 @@ fi:
silence: Voit edelleen käyttää tiliäsi, mutta vain sinua jo seuraavat käyttäjät näkevät julkaisusi tällä palvelimella ja sinut voidaan sulkea pois eri löydettävyysominaisuuksista. Toiset voivat kuitenkin edelleen seurata sinua manuaalisesti.
suspend: Et voi enää käyttää tiliäsi, eivätkä profiilisi ja muut tiedot ole enää käytettävissä. Voit silti kirjautua sisään pyytääksesi tietojesi varmuuskopiota, kunnes tiedot on poistettu kokonaan noin 30 päivän kuluttua. Säilytämme kuitenkin joitain perustietoja, jotka estävät sinua kiertämästä jäädytystä.
reason: 'Syy:'
statuses: 'Julkaisuja lainattu:'
statuses: 'Viitatut julkaisut:'
subject:
delete_statuses: Julkaisusi tilillä %{acct} on poistettu
disable: Tilisi %{acct} on jäädytetty
@@ -2138,7 +2140,7 @@ fi:
feature_audience_title: Rakenna yleisöäsi luottavaisin mielin
feature_control: Tiedät itse parhaiten, mitä haluat nähdä kotisyötteessäsi. Ei algoritmeja eikä mainoksia tuhlaamassa aikaasi. Seuraa yhdellä tilillä ketä tahansa, miltä tahansa Mastodon-palvelimelta, vastaanota heidän julkaisunsa aikajärjestyksessä ja tee omasta internetin nurkastasi hieman enemmän omanlaisesi.
feature_control_title: Pidä aikajanasi hallussasi
feature_creativity: Mastodon tukee ääni-, video- ja kuvajulkaisuja, saavutettavuuskuvauksia, äänestyksiä, sisältövaroituksia, animoituja avattaria, mukautettuja emojeita, pikkukuvien rajauksen hallintaa ja paljon muuta, mikä auttaa ilmaisemaan itseäsi verkossa. Julkaisetpa sitten taidetta, musiikkia tai podcastia, Mastodon on sinua varten.
feature_creativity: Mastodon tukee ääni-, video- ja kuvajulkaisuja, saavutettavuuskuvauksia, äänestyksiä, sisältövaroituksia, animoituja avattaria, mukautettuja emojeita, pienoiskuvien rajauksen hallintaa ja paljon muuta, mikä auttaa ilmaisemaan itseäsi verkossa. Julkaisetpa sitten taidetta, musiikkia tai podcastia, Mastodon on sinua varten.
feature_creativity_title: Luovuutta vertaansa vailla
feature_moderation: Mastodon palauttaa päätöksenteon käsiisi. Jokainen palvelin luo omat sääntönsä ja määräyksensä, joita valvotaan paikallisesti eikä ylhäältä alas kuten kaupallisessa sosiaalisessa mediassa, mikä tekee siitä joustavimman vastaamaan eri ihmisryhmien tarpeisiin. Liity palvelimelle, jonka säännöt sopivat sinulle, tai ylläpidä omaa palvelinta.
feature_moderation_title: Moderointi juuri kuten sen pitäisi olla
@@ -2165,7 +2167,7 @@ fi:
users:
follow_limit_reached: Et voi seurata yli %{limit} käyttäjää
go_to_sso_account_settings: Avaa identiteettitarjoajasi tiliasetukset
invalid_otp_token: Virheellinen kaksivaiheisen todennuksen koodi
invalid_otp_token: Väärä kaksivaiheisen todennuksen koodi
otp_lost_help_html: Jos sinulla ei ole pääsyä kumpaankaan, voit ottaa yhteyden osoitteeseen %{email}
rate_limited: Liian monta todennusyritystä yritä uudelleen myöhemmin.
seamless_external_login: Olet kirjautunut ulkoisen palvelun kautta, joten salasana- ja sähköpostiasetukset eivät ole käytettävissä.

View File

@@ -7,7 +7,6 @@ fil:
hosted_on: Mastodon hosted sa %{domain}
title: About
accounts:
following: Following
instance_actor_flash: Ang account na ito ay virtual actor na ginagamit para i-represent ang mismong server at hindi anumang indibidwal na user. Ginagamit ito para sa mga layunin ng pederasyon at hindi dapat i-suspend.
last_active: huling aktibo
link_verified_on: Ang pagmamay-ari ng link na ito ay huling na-check sa %{date}

View File

@@ -12,7 +12,6 @@ fo:
followers:
one: Fylgjari
other: Fylgjarar
following: Fylgir
instance_actor_flash: Hendan kontan er ein tykisligur aktørur, sum verður brúktur til at umboða ambætaran sjálvan og ikki nakran ávísan brúkara. Hon verður brúkt til sameind endamál og eigur ikki at vera tikin úr gildi.
last_active: virkin seinast
link_verified_on: Eigaraskapur av hesum leinki var eftirkannaður tann %{date}

View File

@@ -12,7 +12,9 @@ fr-CA:
followers:
one: Abonné·e
other: Abonné·e·s
following: Abonnements
following:
one: Abonnement
other: Abonnements
instance_actor_flash: Ce compte est un acteur virtuel utilisé pour représenter le serveur lui-même et non un utilisateur individuel. Il est utilisé à des fins de fédération et ne doit pas être suspendu.
last_active: dernière activité
link_verified_on: La propriété de ce lien a été vérifiée le %{date}
@@ -23,11 +25,11 @@ fr-CA:
one: Message
other: Messages
posts_tab_heading: Messages
self_follow_error: Il n'est pas possible de suivre votre propre compte
self_follow_error: Suivre votre propre compte n'est pas autorisé
admin:
account_actions:
action: Effectuer l'action
already_silenced: Ce compte a déjà été limité.
already_silenced: Ce compte est déjà limité.
already_suspended: Ce compte est déjà suspendu.
title: Effectuer une action de modération sur %{acct}
account_moderation_notes:
@@ -50,7 +52,7 @@ fr-CA:
title: Modifier le courriel pour %{username}
change_role:
changed_msg: Rôle modifié avec succès !
edit_roles: Gérer les rôles d'utilisateur·ices
edit_roles: Gérer les rôles d'utilisateur·ice
label: Modifier le rôle
no_role: Aucun rôle
title: Modifier le rôle de %{username}

View File

@@ -12,7 +12,9 @@ fr:
followers:
one: Abonné·e
other: Abonné·e·s
following: Abonnements
following:
one: Abonnement
other: Abonnements
instance_actor_flash: Ce compte est un acteur virtuel utilisé pour représenter le serveur lui-même et non un utilisateur individuel. Il est utilisé à des fins de fédération et ne doit pas être suspendu.
last_active: dernière activité
link_verified_on: La propriété de ce lien a été vérifiée le %{date}
@@ -23,11 +25,11 @@ fr:
one: Message
other: Messages
posts_tab_heading: Messages
self_follow_error: Il n'est pas possible de suivre votre propre compte
self_follow_error: Suivre votre propre compte n'est pas autorisé
admin:
account_actions:
action: Effectuer l'action
already_silenced: Ce compte a déjà été limité.
already_silenced: Ce compte est déjà limité.
already_suspended: Ce compte est déjà suspendu.
title: Effectuer une action de modération sur %{acct}
account_moderation_notes:
@@ -46,18 +48,18 @@ fr:
current_email: Adresse de courriel actuelle
label: Modifier ladresse de courriel
new_email: Nouvelle adresse de courriel
submit: Modifier le courriel
submit: Modifier ladresse de courriel
title: Modifier ladresse de courriel pour %{username}
change_role:
changed_msg: Rôle modifié avec succès !
edit_roles: Gérer les rôles d'utilisateur·ices
edit_roles: Gérer les rôles d'utilisateur·ice
label: Modifier le rôle
no_role: Aucun rôle
title: Modifier le rôle de %{username}
confirm: Confirmer
confirmed: Confirmé
confirming: Confirmation
custom: Personnalisé
custom: Personnaliser
delete: Supprimer les données
deleted: Supprimé
demote: Rétrograder

View File

@@ -10,7 +10,6 @@ fy:
followers:
one: Folger
other: Folgers
following: Folgjend
instance_actor_flash: Dizze account is in virtual actor wêrmeit de server himsels fertsjinwurdiget en is dus gjin yndividuele brûker. It wurdt foar federaasjedoeleinen brûkt en moat net útsteld wurde.
last_active: lêst warber
link_verified_on: Eigendom fan dizze keppeling is kontrolearre op %{date}

View File

@@ -15,7 +15,12 @@ ga:
one: Leantóir
other: LeantóiríLeantóirí
two: Leantóirí
following: Ag leanúint
following:
few: Ag leanúint
many: Ag leanúint
one: Ag leanúint
other: Ag leanúint
two: Ag leanúint
instance_actor_flash: Is gníomhaí fíorúil é an cuntas seo a úsáidtear chun an freastalaí féin agus ní aon úsáideoir aonair a léiriú. Úsáidtear é chun críocha cónaidhme agus níor cheart é a chur ar fionraí.
last_active: deireanach gníomhach
link_verified_on: Seiceáladh úinéireacht an naisc seo ar %{date}

View File

@@ -14,7 +14,6 @@ gd:
one: Neach-leantainn
other: Luchd-leantainn
two: Luchd-leantainn
following: A leantainn
instance_actor_flash: "S e actar biortail a tha sa chunntas seo a riochdaicheas am frithealaiche fhèin seach cleachdaiche sònraichte. Tha e ga chleachdadh a chùm co-nasgaidh agus cha bu chòir dhut a chur à rèim."
last_active: an gnìomh mu dheireadh
link_verified_on: Chaidh dearbhadh cò leis a tha an ceangal seo %{date}

View File

@@ -12,7 +12,9 @@ gl:
followers:
one: Seguidora
other: Seguidoras
following: A Seguir
following:
one: Seguimento
other: Seguimentos
instance_actor_flash: Esta conta é un actor virtual utilizado para representar ó servidor mesmo e non a unha usuaria individual. Utilízase por motivos de federación e non debería estar suspendida.
last_active: última actividade
link_verified_on: A propiedade desta ligazón foi verificada en %{date}

View File

@@ -14,7 +14,11 @@ he:
one: עוקב
other: עוקבים
two: עוקבים
following: נעקבים
following:
many: נעקבים
one: נעקבים
other: נעקבים
two: נעקביים
instance_actor_flash: חשבון זה הינו פועל וירטואלי המשמש לייצוג השרת עצמו ולא אף משתמש ספציפי. הוא משמש למטרות פדרציה ואין להשעותו.
last_active: פעילות אחרונה
link_verified_on: בעלות על קישורית זו נבדקה לאחרונה ב-%{date}

View File

@@ -5,7 +5,6 @@ hi:
contact_unavailable: लागू नहीं है
title: के बारे में
accounts:
following: फ़ॉलो कर रहे हैं
instance_actor_flash: यह खाता आभासी है जो सर्वर को दिखाने के लिये है और ये किसी व्यक्तिका प्रतिनिधित्व नहि करता। यह सिर्फ देखरेख के हेतु से कार्यरत है और इसको निलंबित करने कि आवश्यकता नहि है।
last_active: आखिरि बार इस वक्त सक्रिय थे
link_verified_on: इस लिंक का स्वामित्व %{date} को चेक किया गया था

View File

@@ -5,7 +5,6 @@ hr:
contact_missing: Nije postavljeno
title: O aplikaciji
accounts:
following: Praćenih
last_active: posljednja aktivnost
nothing_here: Ovdje nema ničeg!
posts_tab_heading: Tootovi

View File

@@ -12,7 +12,6 @@ hu:
followers:
one: Követő
other: Követő
following: Követett
instance_actor_flash: Ez a fiók virtuális, magát a kiszolgálót reprezentálja, nem pedig konkrét felhasználót. Föderációs célokra szolgál, nem szabad tehát felfüggeszteni.
last_active: utoljára aktív
link_verified_on: 'A hivatkozás tulajdonosa ekkor volt ellenőrizve: %{date}'

View File

@@ -10,7 +10,6 @@ hy:
followers:
one: Հետեւորդ
other: Հետևորդներ
following: Հետեւած
instance_actor_flash: Այս հաշիւը վիրտուալ դերասան է, որը ներկայացնում է հանգոյցը, եւ ոչ որեւէ անհատ օգտատիրոջ։ Այն օգտագործուում է ֆեդերացիայի նպատակներով եւ չպէտք է կասեցուի։
last_active: վերջին այցը
link_verified_on: Սոյն յղման տիրապետումը ստուգուած է՝ %{date}֊ին

View File

@@ -10,7 +10,6 @@ ia:
followers:
one: Sequitor
other: Sequitores
following: Sequente
instance_actor_flash: Iste conto es un agente virtual usate pro representar le servitor mesme e non alcun usator individual. Illo es usate pro le federation e non debe esser suspendite.
last_active: ultime activitate
link_verified_on: Le proprietate de iste ligamine ha essite verificate le %{date}

View File

@@ -9,7 +9,6 @@ id:
accounts:
followers:
other: Pengikut
following: Mengikuti
instance_actor_flash: Akun ini adalah aktor virtual yang merepresentasikan server itu sendiri dan bukan pengguna individu. Ini dipakai untuk tujuan gabungan dan seharusnya tidak ditangguhkan.
last_active: terakhir aktif
link_verified_on: Kepemilikan tautan ini telah dicek pada %{date}

View File

@@ -10,7 +10,6 @@ ie:
followers:
one: Sequitor
other: Sequitores
following: Sequent
instance_actor_flash: Ti-ci conto es un virtual actor usat por representer li servitor self e null individual usator. It es usat por federational rasones e deve ne esser suspendet.
last_active: ultim activitá
link_verified_on: Proprietá de ti-ci ligament esset verificat ye %{date}

View File

@@ -10,7 +10,6 @@ io:
followers:
one: Sequanto
other: Sequanti
following: Sequati
instance_actor_flash: Ca konto esas virtuala aganto quo uzesas por reprezentar la servilo e ne irga individuala uzanto. Ol uzesas por federskopo e ne debas restriktesar.
last_active: lasta aktiva tempo
link_verified_on: Proprieteso di ca ligilo kontrolesis ye %{date}

View File

@@ -12,7 +12,9 @@ is:
followers:
one: fylgjandi
other: fylgjendur
following: Fylgist með
following:
one: Fylgist með
other: Fylgist með
instance_actor_flash: Þessi notandaaðgangur er sýndarnotandi sem stendur fyrir sjálfan netþjóninn en ekki neinn einstakling. Hann er notaður við skýjasambandsmiðlun og ætti ekki að setja hann í frysti eða banna.
last_active: síðasta virkni
link_verified_on: Eignarhald á þessum tengli var athugað þann %{date}

View File

@@ -12,7 +12,9 @@ it:
followers:
one: Seguace
other: Seguaci
following: Seguiti
following:
one: Stai seguendo
other: Stai seguendo
instance_actor_flash: Questo profilo è un attore virtuale, utilizzato per rappresentare il server stesso e non un singolo utente. È utilizzato per scopi federativi e non dovrebbe esser sospeso.
last_active: ultima attività
link_verified_on: La proprietà di questo link è stata controllata il %{date}

View File

@@ -9,7 +9,6 @@ ja:
accounts:
followers:
other: フォロワー
following: フォロー中
instance_actor_flash: このアカウントは、個々のユーザーではなく、サーバー自体を表すために使用される仮想のユーザーです。 連合のために使用されるため、停止しないで下さい。
last_active: 最後の活動
link_verified_on: このリンクの所有権は%{date}に確認されました

View File

@@ -6,7 +6,6 @@ ka:
contact_unavailable: მიუწ.
hosted_on: მასტოდონს მასპინძლობს %{domain}
accounts:
following: მიჰყვება
nothing_here: აქ არაფერია!
pin_errors:
following: იმ ადამიანს, ვინც მოგწონთ, უკვე უნდა მიჰყვებოდეთ

View File

@@ -10,7 +10,6 @@ kab:
followers:
one: Umeḍfaṛ
other: Imeḍfaṛen
following: Yeṭṭafaṛ
last_active: armud aneggaru
nothing_here: Ulac kra da!
posts:

View File

@@ -9,7 +9,6 @@ kk:
followers:
one: Оқырман
other: Оқырман
following: Жазылғандары
last_active: соңғы әрекеті
link_verified_on: Сілтеме меншігі расталған күн %{date}
nothing_here: Бұл жерде ештеңе жоқ!

View File

@@ -11,7 +11,6 @@ ko:
cannot_be_added_to_collections: 이 계정은 컬렉션에 추가할 수 없습니다.
followers:
other: 팔로워
following: 팔로잉
instance_actor_flash: 이 계정은 서버 자신을 나타내기 위한 가상의 계정이며 개인 사용자가 아닙니다. 이 계정은 연합을 위해 사용되며 정지되지 않아야 합니다.
last_active: 최근 활동
link_verified_on: "%{date}에 이 링크의 소유가 확인되었습니다"

View File

@@ -10,7 +10,6 @@ ku:
followers:
one: Şopîner
other: Şopîner
following: Dişopîne
instance_actor_flash: Ev ajimêr listikvaneke rastkî ye ku ji bo wek nûnerê rajekar bixwe tê bikaranîn û ne bikarhênerek kesane. Ew ji bo mebestên giştî tê bikaranîn û divê neyê rawestandin.
last_active: çalakiya dawî
link_verified_on: Xwedaniya li vê girêdanê di %{date} de hatiye kontrolkirin

View File

@@ -10,7 +10,6 @@ la:
followers:
one: Sectātor
other: Sectātōrēs
following: Sequendī
instance_actor_flash: Hic ratio est actōr virtuālis ad repraesentandam ipsum servatorem et non ullam individuam usorem. Ad scopōs foederātiōnis ūtor nec suspendendus est.
last_active: Ultimum Actum
link_verified_on: Dominium huius nexūs est comprobatum die %{date}.

View File

@@ -10,7 +10,6 @@ lad:
followers:
one: Suivante
other: Suivantes
following: Sigiendo
instance_actor_flash: Este kuento es un aktor virtual utilizado para reprezentar al sirvidor en si mezmo i no a dingun utilizador individual. Se utiliza para butos de la federasyon i no se deve suspender.
last_active: ultima koneksyon
link_verified_on: La propiedad de este atadijo fue verifikada el %{date}

View File

@@ -12,7 +12,6 @@ lt:
many: Sekėjo
one: Sekėjas
other: Sekėjų
following: Seka
instance_actor_flash: Ši paskyra yra virtualus veikėjas (-a), naudojamas atstovauti pačiam serveriui, o ne atskiram naudotojui. Tai naudojama federacijos tikslais ir neturėtų būti pristabdyta.
last_active: paskutinį kartą aktyvus
link_verified_on: Šios nuorodos nuosavybė buvo patikrinta %{date}

View File

@@ -11,7 +11,6 @@ lv:
one: Sekotājs
other: Sekotāji
zero: Sekotāju
following: Seko
instance_actor_flash: Šis konts ir virtuāls aktieris, ko izmanto, lai pārstāvētu pašu serveri, nevis atsevišķu lietotāju. To izmanto federācijas nolūkos, un to nevajadzētu apturēt.
last_active: pēdējā aktivitāte
link_verified_on: Šīs saites piederība tika pārbaudīta %{date}

View File

@@ -7,7 +7,6 @@ ml:
followers:
one: പിന്തുടരാളി
other: പിന്തുടരുന്നവർ
following: പിന്തുടരുന്നു
last_active: അവസാനം സജീവമായിരുന്നത്
link_verified_on: സന്ധിയുടെ ഉടമസ്ഥാവസ്‌കാശം %{date} ൽ പരിശോധിക്കപ്പെട്ടു
nothing_here: ഇവിടെ ഒന്നുമില്ല!

View File

@@ -9,7 +9,6 @@ ms:
accounts:
followers:
other: Pengikut
following: Mengikuti
instance_actor_flash: Akaun ini ialah pelaku maya yang digunakan untuk mewakili pelayan itu sendiri dan bukan mana-mana pengguna individu. Ia digunakan untuk tujuan persekutuan dan tidak patut digantung.
last_active: aktif terakhir
link_verified_on: Pemilikan pautan ini diperiksa pada %{date}

View File

@@ -9,7 +9,6 @@ my:
accounts:
followers:
other: စောင့်ကြည့်သူ
following: စောင့်ကြည့်နေသည်
instance_actor_flash: ဤအကောင့်သည် ဆာဗာကို ကိုယ်စားပြုသည့် အကောင့်တခုသာဖြစ်ပြီး မည်သည့်အသုံးပြုသူမှမဟုတ်ပါ။ ၎င်းကို Federation ရည်ရွယ်ချက်များအတွက် အသုံးပြုသည့်အတွက် ပိတ်ပင် ဆိုင်းငံ့ခြင်း မပြုသင့်ပါ။
last_active: နောက်ဆုံးအသုံးပြုခဲ့သည့်အချိန်
link_verified_on: ဤလင့်ခ်၏ ပိုင်ဆိုင်မှုကို %{date} တွင် စစ်ဆေးခဲ့သည်

View File

@@ -11,7 +11,6 @@ nan-TW:
cannot_be_added_to_collections: Tsit ê口座袂當加入kàu集合。
followers:
other: 跟tuè ê
following: Leh跟tuè
instance_actor_flash: Tsit ê口座是虛ê用來代表tsit臺服侍器毋是個人用者ê。伊用來做聯邦ê路用毋好kā伊ê權限停止。
last_active: 頂kái活動ê時間
link_verified_on: Tsit ê連結ê所有權佇 %{date} 受檢查

View File

@@ -12,7 +12,6 @@ nl:
followers:
one: Volger
other: Volgers
following: Volgend
instance_actor_flash: Dit account is een 'virtual actor' waarmee de server zichzelf vertegenwoordigt en is dus geen individuele gebruiker. Het wordt voor federatiedoeleinden gebruikt en moet niet worden opgeschort.
last_active: laatst actief
link_verified_on: Eigendom van deze link is gecontroleerd op %{date}

View File

@@ -12,7 +12,6 @@ nn:
followers:
one: Fylgjar
other: Fylgjarar
following: Fylgjer
instance_actor_flash: Denne kontoen er ein virtuell figur som nyttast som representant for tenaren, og ikkje som individuell brukar. Den nyttast til forbundsformål og bør ikkje suspenderast.
last_active: sist aktiv
link_verified_on: Eigarskap for denne lenkja vart sist sjekka %{date}

View File

@@ -10,7 +10,6 @@
followers:
one: Følger
other: Følgere
following: Følger
instance_actor_flash: Denne kontoen er en virtuell figur som brukes til å representere selve serveren og ikke noen individuell bruker. Den brukes til forbundsformål og bør ikke oppheves.
last_active: sist aktiv
link_verified_on: Eierskap av denne lenken ble sjekket %{date}

View File

@@ -10,7 +10,6 @@ oc:
followers:
one: Seguidor
other: Seguidors
following: Abonaments
last_active: darrièra activitat
link_verified_on: La proprietat daqueste ligam foguèt verificada lo %{date}
nothing_here: I a pas res aquí!

View File

@@ -10,7 +10,6 @@ pa:
followers:
one: ਫ਼ਾਲੋਅਰ
other: ਫ਼ਾਲੋਅਰ
following: ਫ਼ਾਲੋ ਕੀਤੇ ਜਾ ਰਹੇ
posts:
one: ਪੋਸਟ
other: ਪੋਸਟਾਂ

View File

@@ -12,7 +12,6 @@ pl:
many: śledzących
one: śledzący
other: obserwujących
following: Obserwowanych
instance_actor_flash: To konto jest wirtualnym profilem używanym do reprezentowania samego serwera, a nie żadnego indywidualnego użytkownika. Jest ono stosowane do celów federacji i nie powinien być zawieszany.
last_active: ostatnio aktywny(-a)
link_verified_on: Własność tego odnośnika została sprawdzona %{date}

View File

@@ -12,7 +12,6 @@ pt-BR:
followers:
one: Seguidor
other: Seguidores
following: Seguindo
instance_actor_flash: Esta conta é um ator virtual usado para representar o próprio servidor e não um usuário individual. É utilizada para fins de federação e não deve ser suspensa.
last_active: última atividade
link_verified_on: O link foi verificado em %{date}

View File

@@ -12,7 +12,6 @@ pt-PT:
followers:
one: Seguidor
other: Seguidores
following: Seguindo
instance_actor_flash: Esta conta é um ator virtual utilizado para representar o servidor em si e não um utilizador individual. É utilizada para efeitos de federação e não deve ser suspensa.
last_active: última atividade
link_verified_on: A posse desta hiperligação foi verificada em %{date}

View File

@@ -11,7 +11,6 @@ ro:
few: Urmăritori
one: Urmăritor
other: De Urmăritori
following: Urmăriți
instance_actor_flash: Acest cont este un actor virtual folosit pentru a reprezenta serverul în sine și nu un utilizator individual. Acesta este utilizat în scopuri federative şi nu trebuie suspendat.
last_active: ultima activitate
link_verified_on: Proprietatea acestui link a fost verificată la %{date}

View File

@@ -12,7 +12,6 @@ ru:
many: подписчиков
one: подписчик
other: подписчиков
following: подписки
instance_actor_flash: Эта учетная запись - виртуальный пользователь, используемый для представления самого сервера, а не отдельного пользователя. Она используется для организационных целей и не может быть заморожена.
last_active: последняя активность
link_verified_on: Владение этой ссылкой было проверено %{date}

View File

@@ -1,7 +1,6 @@
---
ry:
accounts:
following: Пудпискы
posts:
few: Публикації
one: Публикація

View File

@@ -10,7 +10,6 @@ sc:
followers:
one: Sighidura
other: Sighiduras
following: Sighende
instance_actor_flash: Custu contu est un'atore virtuale chi costumaiat a rapresentare su serbidore etotu e nono unu cale si siat utente individuale. Est impreadu pro finalidades de sa federatzione e non si depet suspèndere.
last_active: ùrtima atividade
link_verified_on: Sa propiedade de custu ligàmene est istada controllada su %{date}

View File

@@ -10,7 +10,6 @@ sco:
followers:
one: Follaer
other: Follaers
following: Follaein
instance_actor_flash: This accoont is a virtual actor uised tae represent the server itsel an no onie individual uiser. It is uised fir federation purposes an shuidnae be suspendit.
last_active: last active
link_verified_on: Ainership o this link wis checkt on %{date}

View File

@@ -10,7 +10,6 @@ si:
followers:
one: අනුගාමිකයා
other: අනුගාමිකයින්
following: අනුගමන
instance_actor_flash: මෙම ගිණුම සේවාදායකයම නියෝජනය කිරීමට භාවිතා කරන අතථ්‍ය නළුවෙකු වන අතර කිසිදු තනි පරිශීලකයෙකු නොවේ. එය ෆෙඩරේෂන් අරමුණු සඳහා භාවිතා කරන අතර අත්හිටුවිය යුතු නොවේ.
last_active: අවසාන ක්රියාකාරී
link_verified_on: මෙම සබැඳියේ හිමිකාරිත්වය %{date}හි පරීක්ෂා කරන ලදී

View File

@@ -231,7 +231,7 @@ fi:
max_uses: Käyttökertoja enintään
new_password: Uusi salasana
note: Elämäkerta
otp_attempt: Kaksivaiheisen todennuksen tunnusluku
otp_attempt: Kaksivaiheisen todennuksen koodi
password: Salasana
phrase: Avainsana tai fraasi
setting_advanced_layout: Ota edistynyt selainkäyttöliittymä käyttöön
@@ -321,7 +321,7 @@ fi:
must_be_following: Estä ilmoitukset käyttäjiltä, joita et seuraa
must_be_following_dm: Estä yksityisviestit käyttäjiltä, joita et seuraa
invite:
comment: Kommentoi
comment: Kommentti
invite_request:
text: Miksi haluat liittyä?
ip_block:
@@ -348,7 +348,7 @@ fi:
critical: Ilmoita vain kriittisistä päivityksistä
label: Uusi Mastodon-versio on saatavilla
none: Älä koskaan ilmoita päivityksistä (ei suositeltu)
patch: Ilmoita virhekorjauspäivityksistä
patch: Ilmoita virheenkorjauspäivityksistä
trending_tag: Uusi trendi vaatii tarkastuksen
rule:
hint: Lisätietoja
@@ -401,7 +401,7 @@ fi:
recommended: Suositellaan
required:
mark: "*"
text: vaadittu tieto
text: pakollinen
title:
sessions:
webauthn: Käytä yhtä suojausavaimistasi kirjautuaksesi sisään

View File

@@ -12,7 +12,6 @@ sk:
many: Sledovateľov
one: Sledujúci
other: Sledujúci
following: Nasledujem
instance_actor_flash: Toto konto je virtuálny aktér, ktorý predstavuje samotný server, a nie konkrétneho používateľa. Používa sa na účely federácie a nemal by byť pozastavený.
last_active: posledná aktivita
link_verified_on: Vlastníctvo tohto odkazu bolo skontrolované %{date}

View File

@@ -14,7 +14,6 @@ sl:
one: Sledilec
other: Sledilcev
two: Sledilca
following: Sledi
instance_actor_flash: Ta račun je navidezni akter, ki se uporablja za predstavljanje strežnika samega in ne posameznega uporabnika. Uporablja se za namene federacije in se ne sme začasno ustaviti.
last_active: zadnja dejavnost
link_verified_on: Lastništvo te povezave je bilo preverjeno %{date}

View File

@@ -12,7 +12,6 @@ sq:
followers:
one: Ndjekës
other: Ndjekës
following: Po ndjek
instance_actor_flash: Kjo llogari është një aktor virtual, i përdorur për të përfaqësuar vetë serverin dhe jo ndonjë përdorues. Përdoret për qëllime federimi dhe sduhet pezulluar.
last_active: aktiv së fundi
link_verified_on: Pronësia e kësaj lidhjeje qe kontrolluar më %{date}

View File

@@ -11,7 +11,6 @@ sr-Latn:
few: Pratioca
one: Pratilac
other: Pratilaca
following: Pratim
instance_actor_flash: Ovaj nalog je virtuelni akter koji ne predstavlja nijednog korisnika lično, već sâm server. Koristi se u svrhu federacije i ne treba ga suspendovati.
last_active: najskorija aktivnost
link_verified_on: Vlasništvo nad ovom vezom je provereno %{date}

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