Merge commit '3473b8a65278783bc74ce2738aea98cca0c7a5ed' into glitch-soc/merge-upstream
Conflicts: - `config/settings.yml`: Upstream added a new setting textually adjacent to ones modified by glitch-soc's. Added upstream's new setting.
This commit is contained in:
commit
b3bae7e78f
@ -587,7 +587,7 @@ GEM
|
||||
opentelemetry-api (~> 1.0)
|
||||
orm_adapter (0.5.0)
|
||||
ostruct (0.6.3)
|
||||
ox (2.14.23)
|
||||
ox (2.14.25)
|
||||
bigdecimal (>= 3.0)
|
||||
parallel (1.28.0)
|
||||
parser (3.3.11.1)
|
||||
|
||||
@ -62,7 +62,7 @@ module Admin
|
||||
|
||||
def resource_params
|
||||
params
|
||||
.expect(user_role: [:name, :color, :highlighted, :position, :require_2fa, permissions_as_keys: []])
|
||||
.expect(user_role: [:name, :color, :highlighted, :position, :require_2fa, :collection_limit, permissions_as_keys: []])
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
@ -17,7 +17,10 @@ class CollectionsController < ApplicationController
|
||||
|
||||
def show
|
||||
respond_to do |format|
|
||||
# TODO: format.html
|
||||
format.html do
|
||||
expires_in expiration_duration, public: true unless user_signed_in?
|
||||
render template: 'home/index'
|
||||
end
|
||||
|
||||
format.json do
|
||||
expires_in expiration_duration, public: true if public_fetch_mode?
|
||||
@ -28,8 +31,17 @@ class CollectionsController < ApplicationController
|
||||
|
||||
private
|
||||
|
||||
def set_account
|
||||
if account_id_param.present?
|
||||
@account = Account.local.find(account_id_param)
|
||||
else
|
||||
@collection = Collection.find(params[:id])
|
||||
@account = @collection.account
|
||||
end
|
||||
end
|
||||
|
||||
def set_collection
|
||||
@collection = @account.collections.find(params[:id])
|
||||
@collection ||= @account.collections.find(params[:id])
|
||||
authorize @collection, :show?
|
||||
rescue ActiveRecord::RecordNotFound, Mastodon::NotPermittedError
|
||||
not_found
|
||||
|
||||
1
app/javascript/images/anniversary.svg
Normal file
1
app/javascript/images/anniversary.svg
Normal file
File diff suppressed because one or more lines are too long
|
After Width: | Height: | Size: 9.5 KiB |
@ -153,10 +153,11 @@ export function resetCompose() {
|
||||
};
|
||||
}
|
||||
|
||||
export const focusCompose = (defaultText = '') => (dispatch, getState) => {
|
||||
export const focusCompose = (defaultText = '', caretStart = false) => (dispatch, getState) => {
|
||||
dispatch({
|
||||
type: COMPOSE_FOCUS,
|
||||
defaultText,
|
||||
caretStart,
|
||||
});
|
||||
|
||||
ensureComposeIsVisible(getState);
|
||||
|
||||
@ -11,7 +11,8 @@ export interface ApiCollectionJSON {
|
||||
account_id: string;
|
||||
|
||||
id: string;
|
||||
uri: string | null;
|
||||
uri: string;
|
||||
url: string;
|
||||
local: boolean;
|
||||
item_count: number;
|
||||
|
||||
@ -56,7 +57,7 @@ export interface CollectionAccountItem {
|
||||
id: string;
|
||||
account_id?: string; // Only present when state is 'accepted' (or the collection is your own)
|
||||
state: 'pending' | 'accepted' | 'rejected' | 'revoked';
|
||||
position: number;
|
||||
created_at: string;
|
||||
}
|
||||
|
||||
export interface WrappedCollectionAccountItem {
|
||||
|
||||
@ -2,6 +2,8 @@ import { useState, useCallback, useRef, useId } from 'react';
|
||||
|
||||
import { FormattedMessage, useIntl } from 'react-intl';
|
||||
|
||||
import classNames from 'classnames';
|
||||
|
||||
import type {
|
||||
OffsetValue,
|
||||
UsePopperOptions,
|
||||
@ -18,9 +20,10 @@ import classes from './styles.module.scss';
|
||||
const offset = [0, 4] as OffsetValue;
|
||||
const popperConfig = { strategy: 'fixed' } as UsePopperOptions;
|
||||
|
||||
export const AltTextBadge: React.FC<{ description: string }> = ({
|
||||
description,
|
||||
}) => {
|
||||
export const AltTextBadge: React.FC<{
|
||||
description: string;
|
||||
className?: string;
|
||||
}> = ({ description, className }) => {
|
||||
const intl = useIntl();
|
||||
const uniqueId = useId();
|
||||
const popoverId = `${uniqueId}-popover`;
|
||||
@ -48,7 +51,7 @@ export const AltTextBadge: React.FC<{ description: string }> = ({
|
||||
<button
|
||||
type='button'
|
||||
ref={buttonRef}
|
||||
className='media-gallery__alt__label'
|
||||
className={classNames('media-gallery__alt__label', className)}
|
||||
onClick={handleClick}
|
||||
aria-expanded={open}
|
||||
aria-controls={popoverId}
|
||||
|
||||
@ -24,9 +24,14 @@ export const NumberFieldsItem: React.FC<ItemProps> = ({
|
||||
link,
|
||||
children,
|
||||
className,
|
||||
...restProps
|
||||
}) => {
|
||||
return (
|
||||
<li className={classNames(classes.item, className)} title={hint}>
|
||||
<li
|
||||
{...restProps}
|
||||
className={classNames(classes.item, className)}
|
||||
title={hint}
|
||||
>
|
||||
{label}
|
||||
{link ? (
|
||||
<NavLink exact to={link}>
|
||||
|
||||
@ -14,6 +14,7 @@
|
||||
}
|
||||
|
||||
a,
|
||||
button,
|
||||
strong {
|
||||
display: block;
|
||||
font-weight: 600;
|
||||
@ -25,10 +26,21 @@
|
||||
a {
|
||||
padding: 0;
|
||||
text-decoration: none;
|
||||
}
|
||||
|
||||
a,
|
||||
button {
|
||||
&:hover,
|
||||
&:focus {
|
||||
text-decoration: underline;
|
||||
}
|
||||
}
|
||||
|
||||
button {
|
||||
appearance: none;
|
||||
background: none;
|
||||
border: none;
|
||||
display: block;
|
||||
padding: 0;
|
||||
}
|
||||
}
|
||||
|
||||
@ -3,7 +3,7 @@ import { PureComponent } from 'react';
|
||||
|
||||
import { FormattedMessage, defineMessages } from 'react-intl';
|
||||
|
||||
import { Link } from 'react-router-dom';
|
||||
import { NavLink } from 'react-router-dom';
|
||||
|
||||
import { connect } from 'react-redux';
|
||||
|
||||
@ -18,6 +18,7 @@ import { injectIntl } from './intl';
|
||||
|
||||
const messages = defineMessages({
|
||||
aboutActiveUsers: { id: 'server_banner.about_active_users', defaultMessage: 'People using this server during the last 30 days (Monthly Active Users)' },
|
||||
aboutThisServer: { id: 'server_banner.more_about_this_server', defaultMessage: 'More about this server'},
|
||||
});
|
||||
|
||||
const mapStateToProps = state => ({
|
||||
@ -47,9 +48,14 @@ class ServerBanner extends PureComponent {
|
||||
<FormattedMessage id='server_banner.is_one_of_many' defaultMessage='{domain} is one of the many independent Mastodon servers you can use to participate in the fediverse.' values={{ domain: <strong>{domain}</strong>, mastodon: <a href='https://joinmastodon.org' target='_blank' rel='noopener'>Mastodon</a> }} />
|
||||
</div>
|
||||
|
||||
<Link to='/about'>
|
||||
<ServerHeroImage blurhash={server.getIn(['thumbnail', 'blurhash'])} src={server.getIn(['thumbnail', 'url'])} className='server-banner__hero' />
|
||||
</Link>
|
||||
<NavLink to='/about'>
|
||||
<ServerHeroImage
|
||||
blurhash={server.getIn(['thumbnail', 'blurhash'])}
|
||||
src={server.getIn(['thumbnail', 'url'])}
|
||||
alt={intl.formatMessage(messages.aboutThisServer)}
|
||||
className='server-banner__hero'
|
||||
/>
|
||||
</NavLink>
|
||||
|
||||
<div className='server-banner__description'>
|
||||
{isLoading ? (
|
||||
|
||||
@ -2,9 +2,14 @@ import { useCallback, useState } from 'react';
|
||||
|
||||
import classNames from 'classnames';
|
||||
|
||||
import { Blurhash } from './blurhash';
|
||||
import { AltTextBadge } from '../alt_text_badge';
|
||||
import { Blurhash } from '../blurhash';
|
||||
|
||||
import classes from './styles.module.scss';
|
||||
|
||||
interface Props {
|
||||
withAltBadge?: boolean;
|
||||
alt: string;
|
||||
src: string;
|
||||
srcSet?: string;
|
||||
blurhash?: string;
|
||||
@ -12,9 +17,11 @@ interface Props {
|
||||
}
|
||||
|
||||
export const ServerHeroImage: React.FC<Props> = ({
|
||||
alt,
|
||||
src,
|
||||
srcSet,
|
||||
blurhash,
|
||||
withAltBadge,
|
||||
className,
|
||||
}) => {
|
||||
const [loaded, setLoaded] = useState(false);
|
||||
@ -24,12 +31,12 @@ export const ServerHeroImage: React.FC<Props> = ({
|
||||
}, [setLoaded]);
|
||||
|
||||
return (
|
||||
<div
|
||||
className={classNames('image', { loaded }, className)}
|
||||
role='presentation'
|
||||
>
|
||||
<div className={classNames('image', { loaded }, className)}>
|
||||
{blurhash && <Blurhash hash={blurhash} className='image__preview' />}
|
||||
<img src={src} srcSet={srcSet} alt='' onLoad={handleLoad} />
|
||||
<img src={src} srcSet={srcSet} alt={alt} onLoad={handleLoad} />
|
||||
{withAltBadge && alt && (
|
||||
<AltTextBadge description={alt} className={classes.altBadge} />
|
||||
)}
|
||||
</div>
|
||||
);
|
||||
};
|
||||
@ -0,0 +1,5 @@
|
||||
.altBadge {
|
||||
position: absolute;
|
||||
bottom: 8px;
|
||||
inset-inline-end: 8px;
|
||||
}
|
||||
@ -31,6 +31,7 @@ import { getHashtagBarForStatus } from './hashtag_bar';
|
||||
import StatusActionBar from './status_action_bar';
|
||||
import StatusContent from './status_content';
|
||||
import { StatusThreadLabel } from './status_thread_label';
|
||||
import { CollectionPreviewCard } from '../features/collections/components/collection_preview_card';
|
||||
|
||||
const domParser = new DOMParser();
|
||||
|
||||
@ -547,13 +548,30 @@ class Status extends ImmutablePureComponent {
|
||||
);
|
||||
}
|
||||
} else if (status.get('card') && !status.get('quote')) {
|
||||
media = (
|
||||
<Card
|
||||
key={`${status.get('id')}-${status.get('edited_at')}`}
|
||||
card={status.get('card')}
|
||||
sensitive={status.get('sensitive')}
|
||||
/>
|
||||
);
|
||||
const cardUrl = status.getIn(['card', 'url']);
|
||||
|
||||
const taggedCollection = (
|
||||
status.get('tagged_collections')
|
||||
).find((item) => compareUrls(item.get('url'), cardUrl));
|
||||
|
||||
if (taggedCollection) {
|
||||
media = <CollectionPreviewCard collection={taggedCollection} />;
|
||||
} else {
|
||||
media = (
|
||||
<Card
|
||||
key={`${status.get('id')}-${status.get('edited_at')}`}
|
||||
card={status.get('card')}
|
||||
sensitive={status.get('sensitive')}
|
||||
/>
|
||||
);
|
||||
}
|
||||
} else if (status.get('tagged_collections').size) {
|
||||
const firstLinkedCollection = status.get('tagged_collections').first();
|
||||
if (firstLinkedCollection) {
|
||||
media = (
|
||||
<CollectionPreviewCard collection={firstLinkedCollection.toJS()} />
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
const {statusContentProps, hashtagBar} = getHashtagBarForStatus(status);
|
||||
|
||||
@ -4,7 +4,9 @@ import type { ComponentProps, FC } from 'react';
|
||||
import classNames from 'classnames';
|
||||
import { Link } from 'react-router-dom';
|
||||
|
||||
import type { ApiCollectionJSON } from '@/mastodon/api_types/collections';
|
||||
import type { ApiMentionJSON } from '@/mastodon/api_types/statuses';
|
||||
import { getCollectionPath } from '@/mastodon/features/collections/utils';
|
||||
import type { OnElementHandler } from '@/mastodon/utils/html';
|
||||
|
||||
export interface HandledLinkProps {
|
||||
@ -13,6 +15,7 @@ export interface HandledLinkProps {
|
||||
prevText?: string;
|
||||
hashtagAccountId?: string;
|
||||
mention?: Pick<ApiMentionJSON, 'id' | 'acct'>;
|
||||
collection?: Pick<ApiCollectionJSON, 'id'>;
|
||||
}
|
||||
|
||||
export const HandledLink: FC<HandledLinkProps & ComponentProps<'a'>> = ({
|
||||
@ -21,6 +24,7 @@ export const HandledLink: FC<HandledLinkProps & ComponentProps<'a'>> = ({
|
||||
prevText,
|
||||
hashtagAccountId,
|
||||
mention,
|
||||
collection,
|
||||
className,
|
||||
children,
|
||||
...props
|
||||
@ -57,6 +61,15 @@ export const HandledLink: FC<HandledLinkProps & ComponentProps<'a'>> = ({
|
||||
{children}
|
||||
</Link>
|
||||
);
|
||||
} else if (collection) {
|
||||
return (
|
||||
<Link
|
||||
className={classNames(className)}
|
||||
to={getCollectionPath(collection.id)}
|
||||
>
|
||||
{children}
|
||||
</Link>
|
||||
);
|
||||
}
|
||||
|
||||
// Non-absolute paths treated as internal links. This shouldn't happen, but just in case.
|
||||
|
||||
@ -18,6 +18,7 @@ import { languages as preloadedLanguages } from 'mastodon/initial_state';
|
||||
import { EmojiHTML } from './emoji/html';
|
||||
import { injectIntl } from './intl';
|
||||
import { HandledLink } from './status/handled_link';
|
||||
import { compareUrls } from '../utils/compare_urls';
|
||||
|
||||
const MAX_HEIGHT = 706; // 22px * 32 (+ 2px padding at the top)
|
||||
|
||||
@ -71,17 +72,6 @@ const mapStateToProps = state => ({
|
||||
languages: state.getIn(['server', 'translationLanguages', 'items']),
|
||||
});
|
||||
|
||||
const compareUrls = (href1, href2) => {
|
||||
try {
|
||||
const url1 = new URL(href1);
|
||||
const url2 = new URL(href2);
|
||||
|
||||
return url1.origin === url2.origin && url1.pathname === url2.pathname && url1.search === url2.search;
|
||||
} catch {
|
||||
return false;
|
||||
}
|
||||
};
|
||||
|
||||
class StatusContent extends PureComponent {
|
||||
static propTypes = {
|
||||
identity: identityContextPropShape,
|
||||
@ -166,7 +156,13 @@ class StatusContent extends PureComponent {
|
||||
|
||||
handleElement = (element, { key, ...props }, children) => {
|
||||
if (element instanceof HTMLAnchorElement) {
|
||||
const mention = this.props.status.get('mentions').find(item => compareUrls(element.href, item.get('url')));
|
||||
const mention = this.props.status.get('mentions').find(
|
||||
item => compareUrls(element.href, item.get('url'))
|
||||
);
|
||||
const taggedCollection = this.props.status.get('tagged_collections').find(
|
||||
item => compareUrls(element.href, item.get('url'))
|
||||
)
|
||||
|
||||
return (
|
||||
<HandledLink
|
||||
{...props}
|
||||
@ -174,6 +170,7 @@ class StatusContent extends PureComponent {
|
||||
text={element.innerText}
|
||||
hashtagAccountId={this.props.status.getIn(['account', 'id'])}
|
||||
mention={mention?.toJSON()}
|
||||
collection={taggedCollection?.toJSON()}
|
||||
key={key}
|
||||
>
|
||||
{children}
|
||||
|
||||
@ -82,7 +82,14 @@ class About extends PureComponent {
|
||||
<Column bindToDocument={!multiColumn} label={intl.formatMessage(messages.title)}>
|
||||
<div className='scrollable about'>
|
||||
<div className='about__header'>
|
||||
<ServerHeroImage blurhash={server.getIn(['thumbnail', 'blurhash'])} src={server.getIn(['thumbnail', 'url'])} srcSet={server.getIn(['thumbnail', 'versions'])?.map((value, key) => `${value} ${key.replace('@', '')}`).join(', ')} className='about__header__hero' />
|
||||
<ServerHeroImage
|
||||
withAltBadge
|
||||
alt={server.getIn(['thumbnail', 'description']) ?? ''}
|
||||
blurhash={server.getIn(['thumbnail', 'blurhash'])}
|
||||
src={server.getIn(['thumbnail', 'url'])}
|
||||
srcSet={server.getIn(['thumbnail', 'versions'])?.map((value, key) => `${value} ${key.replace('@', '')}`).join(', ')}
|
||||
className='about__header__hero'
|
||||
/>
|
||||
<h1>{isLoading ? <Skeleton width='10ch' /> : server.get('domain')}</h1>
|
||||
<p><FormattedMessage id='about.powered_by' defaultMessage='Decentralized social media powered by {mastodon}' values={{ mastodon: <a href='https://joinmastodon.org' className='about__mail' target='_blank' rel='noopener'>Mastodon</a> }} /></p>
|
||||
</div>
|
||||
|
||||
@ -23,7 +23,7 @@ export const AccountEditEmptyColumn: FC<{
|
||||
}
|
||||
|
||||
return (
|
||||
<Column bindToDocument={!multiColumn} className={classes.column}>
|
||||
<Column bindToDocument={!multiColumn}>
|
||||
<LoadingIndicator />
|
||||
</Column>
|
||||
);
|
||||
@ -38,7 +38,7 @@ export const AccountEditColumn: FC<{
|
||||
|
||||
return (
|
||||
<>
|
||||
<Column bindToDocument={!multiColumn} className={classes.column}>
|
||||
<Column bindToDocument={!multiColumn}>
|
||||
<ColumnHeader
|
||||
title={title}
|
||||
className={classes.columnHeader}
|
||||
@ -53,7 +53,7 @@ export const AccountEditColumn: FC<{
|
||||
}
|
||||
/>
|
||||
|
||||
{children}
|
||||
<div className='scrollable'>{children}</div>
|
||||
</Column>
|
||||
<Helmet>
|
||||
<title>{title}</title>
|
||||
|
||||
@ -17,6 +17,7 @@ import { ToggleField } from '@/mastodon/components/form_fields';
|
||||
import { useElementHandledLink } from '@/mastodon/components/status/handled_link';
|
||||
import { useAccount } from '@/mastodon/hooks/useAccount';
|
||||
import { useCurrentAccountId } from '@/mastodon/hooks/useAccountId';
|
||||
import { useCustomEmojis } from '@/mastodon/hooks/useCustomEmojis';
|
||||
import { autoPlayGif } from '@/mastodon/initial_state';
|
||||
import {
|
||||
fetchProfile,
|
||||
@ -175,7 +176,7 @@ export const AccountEdit: FC = () => {
|
||||
}, [dispatch, profile?.bot]);
|
||||
|
||||
// Normally we would use the account emoji, but we want all custom emojis to be available to render after editing.
|
||||
const emojis = useAppSelector((state) => state.custom_emojis);
|
||||
const emojis = useCustomEmojis();
|
||||
const htmlHandlers = useElementHandledLink({
|
||||
hashtagAccountId: profile?.id,
|
||||
});
|
||||
|
||||
@ -1,4 +1,10 @@
|
||||
import { forwardRef, useCallback, useImperativeHandle, useState } from 'react';
|
||||
import {
|
||||
forwardRef,
|
||||
useCallback,
|
||||
useImperativeHandle,
|
||||
useMemo,
|
||||
useState,
|
||||
} from 'react';
|
||||
import type { FC, FocusEventHandler } from 'react';
|
||||
|
||||
import { defineMessages, FormattedMessage, useIntl } from 'react-intl';
|
||||
@ -9,6 +15,7 @@ import { closeModal } from '@/mastodon/actions/modal';
|
||||
import { Button } from '@/mastodon/components/button';
|
||||
import type { FieldStatus } from '@/mastodon/components/form_fields';
|
||||
import { EmojiTextInputField } from '@/mastodon/components/form_fields';
|
||||
import { useCustomEmojis } from '@/mastodon/hooks/useCustomEmojis';
|
||||
import {
|
||||
removeField,
|
||||
selectFieldById,
|
||||
@ -104,11 +111,6 @@ const selectFieldLimits = createAppSelector(
|
||||
|
||||
const RECOMMENDED_LIMIT = 40;
|
||||
|
||||
const selectEmojiCodes = createAppSelector(
|
||||
[(state) => state.custom_emojis],
|
||||
(emojis) => emojis.map((emoji) => emoji.get('shortcode')).toArray(),
|
||||
);
|
||||
|
||||
interface ConfirmationMessage {
|
||||
message: string;
|
||||
confirm: string;
|
||||
@ -143,7 +145,11 @@ export const EditFieldModal = forwardRef<
|
||||
value?: FieldStatus;
|
||||
}>({});
|
||||
|
||||
const customEmojiCodes = useAppSelector(selectEmojiCodes);
|
||||
const customEmojis = useCustomEmojis();
|
||||
const customEmojiCodes = useMemo(
|
||||
() => Object.keys(customEmojis ?? {}),
|
||||
[customEmojis],
|
||||
);
|
||||
const checkField = useCallback(
|
||||
(value: string): FieldStatus | null => {
|
||||
if (!value.trim()) {
|
||||
|
||||
@ -35,6 +35,7 @@ import { CSS } from '@dnd-kit/utilities';
|
||||
import { CustomEmojiProvider } from '@/mastodon/components/emoji/context';
|
||||
import { normalizeKey } from '@/mastodon/components/hotkeys/utils';
|
||||
import { Icon } from '@/mastodon/components/icon';
|
||||
import { useCustomEmojis } from '@/mastodon/hooks/useCustomEmojis';
|
||||
import type { FieldData } from '@/mastodon/reducers/slices/profile_edit';
|
||||
import {
|
||||
patchProfile,
|
||||
@ -217,7 +218,7 @@ export const ReorderFieldsModal: FC<DialogModalProps> = ({ onClose }) => {
|
||||
void dispatch(patchProfile({ fields_attributes: newFields })).then(onClose);
|
||||
}, [dispatch, fieldKeys, fields, onClose]);
|
||||
|
||||
const emojis = useAppSelector((state) => state.custom_emojis);
|
||||
const emojis = useCustomEmojis();
|
||||
|
||||
return (
|
||||
// Add a wrapper here in the capture phase, so that it can be intercepted before the window listener in ModalRoot.
|
||||
|
||||
@ -126,11 +126,6 @@
|
||||
|
||||
// Column component
|
||||
|
||||
.column {
|
||||
border: 1px solid var(--color-border-primary);
|
||||
border-top-width: 0;
|
||||
}
|
||||
|
||||
.columnHeader {
|
||||
:global(.column-header__buttons) {
|
||||
align-items: center;
|
||||
@ -258,6 +253,10 @@
|
||||
padding: 24px;
|
||||
border-bottom: 1px solid var(--color-border-primary);
|
||||
font-size: 15px;
|
||||
|
||||
&:last-child {
|
||||
border-bottom: none;
|
||||
}
|
||||
}
|
||||
|
||||
.sectionHeader {
|
||||
|
||||
@ -25,12 +25,9 @@ import Column from 'mastodon/features/ui/components/column';
|
||||
import { useAccount } from 'mastodon/hooks/useAccount';
|
||||
import { useAccountId } from 'mastodon/hooks/useAccountId';
|
||||
import { useAccountVisibility } from 'mastodon/hooks/useAccountVisibility';
|
||||
import {
|
||||
fetchAccountCollections,
|
||||
selectAccountCollections,
|
||||
} from 'mastodon/reducers/slices/collections';
|
||||
import { useAppDispatch, useAppSelector } from 'mastodon/store';
|
||||
|
||||
import { useAccountCollections } from '../collections';
|
||||
import { CollectionListItem } from '../collections/components/collection_list_item';
|
||||
import { areCollectionsEnabled } from '../collections/utils';
|
||||
|
||||
@ -59,10 +56,6 @@ const AccountFeatured: React.FC<{ multiColumn: boolean }> = ({
|
||||
useEffect(() => {
|
||||
if (accountId) {
|
||||
void dispatch(fetchEndorsedAccounts({ accountId }));
|
||||
|
||||
if (collectionsEnabled) {
|
||||
void dispatch(fetchAccountCollections({ accountId }));
|
||||
}
|
||||
}
|
||||
}, [accountId, dispatch]);
|
||||
|
||||
@ -73,9 +66,8 @@ const AccountFeatured: React.FC<{ multiColumn: boolean }> = ({
|
||||
ImmutableList(),
|
||||
) as ImmutableList<string>,
|
||||
);
|
||||
const { collections, status: collectionsLoadStatus } = useAppSelector(
|
||||
(state) => selectAccountCollections(state, accountId ?? null),
|
||||
);
|
||||
const { collections, status: collectionsLoadStatus } =
|
||||
useAccountCollections(accountId);
|
||||
|
||||
const { listedCollections = [], unlistedCollections = [] } = Object.groupBy(
|
||||
collections,
|
||||
|
||||
@ -1,8 +1,9 @@
|
||||
import { useMemo } from 'react';
|
||||
import { useCallback, useMemo } from 'react';
|
||||
import type { FC } from 'react';
|
||||
|
||||
import { FormattedMessage, useIntl } from 'react-intl';
|
||||
|
||||
import { openModal } from '@/mastodon/actions/modal';
|
||||
import { FormattedDateWrapper } from '@/mastodon/components/formatted_date';
|
||||
import {
|
||||
NumberFields,
|
||||
@ -10,6 +11,7 @@ import {
|
||||
} from '@/mastodon/components/number_fields';
|
||||
import { ShortNumber } from '@/mastodon/components/short_number';
|
||||
import { useAccount } from '@/mastodon/hooks/useAccount';
|
||||
import { useAppDispatch } from '@/mastodon/store';
|
||||
|
||||
export const AccountNumberFields: FC<{ accountId: string }> = ({
|
||||
accountId,
|
||||
@ -21,6 +23,13 @@ export const AccountNumberFields: FC<{ accountId: string }> = ({
|
||||
[account?.created_at],
|
||||
);
|
||||
|
||||
const dispatch = useAppDispatch();
|
||||
const showJoinModal = useCallback(() => {
|
||||
dispatch(
|
||||
openModal({ modalType: 'ACCOUNT_JOIN_DATE', modalProps: { accountId } }),
|
||||
);
|
||||
}, [accountId, dispatch]);
|
||||
|
||||
if (!account) {
|
||||
return null;
|
||||
}
|
||||
@ -60,15 +69,17 @@ export const AccountNumberFields: FC<{ accountId: string }> = ({
|
||||
}
|
||||
hint={intl.formatDate(account.created_at)}
|
||||
>
|
||||
{createdThisYear ? (
|
||||
<FormattedDateWrapper
|
||||
value={account.created_at}
|
||||
month='short'
|
||||
day='2-digit'
|
||||
/>
|
||||
) : (
|
||||
<FormattedDateWrapper value={account.created_at} year='numeric' />
|
||||
)}
|
||||
<button type='button' onClick={showJoinModal}>
|
||||
{createdThisYear ? (
|
||||
<FormattedDateWrapper
|
||||
value={account.created_at}
|
||||
month='short'
|
||||
day='2-digit'
|
||||
/>
|
||||
) : (
|
||||
<FormattedDateWrapper value={account.created_at} year='numeric' />
|
||||
)}
|
||||
</button>
|
||||
</NumberFieldsItem>
|
||||
</NumberFields>
|
||||
);
|
||||
|
||||
@ -13,7 +13,7 @@ import {
|
||||
import type { AccountField } from '../common';
|
||||
import { useFieldHtml } from '../hooks/useFieldHtml';
|
||||
|
||||
import classes from './styles.module.css';
|
||||
import classes from './styles.module.scss';
|
||||
|
||||
export const AccountFieldModal: FC<{
|
||||
onClose: () => void;
|
||||
|
||||
@ -0,0 +1,270 @@
|
||||
import { useCallback, useMemo } from 'react';
|
||||
import type { FC } from 'react';
|
||||
|
||||
import { defineMessage, FormattedMessage, useIntl } from 'react-intl';
|
||||
|
||||
import AnniversaryImage from '@/images/anniversary.svg?react';
|
||||
import { focusCompose, resetCompose } from '@/mastodon/actions/compose';
|
||||
import { closeModal } from '@/mastodon/actions/modal';
|
||||
import { Button } from '@/mastodon/components/button';
|
||||
import { DisplayNameSimple } from '@/mastodon/components/display_name/simple';
|
||||
import { FormattedDateWrapper } from '@/mastodon/components/formatted_date';
|
||||
import { IconButton } from '@/mastodon/components/icon_button';
|
||||
import { ModalShell, ModalShellBody } from '@/mastodon/components/modal_shell';
|
||||
import { useAccount } from '@/mastodon/hooks/useAccount';
|
||||
import { useCurrentAccountId } from '@/mastodon/hooks/useAccountId';
|
||||
import {
|
||||
createAppSelector,
|
||||
useAppDispatch,
|
||||
useAppSelector,
|
||||
} from '@/mastodon/store';
|
||||
import CloseIcon from '@/material-icons/400-24px/close.svg?react';
|
||||
|
||||
import classes from './styles.module.scss';
|
||||
|
||||
const closeMessage = defineMessage({
|
||||
id: 'lightbox.close',
|
||||
defaultMessage: 'Close',
|
||||
});
|
||||
|
||||
const selectServerName = createAppSelector(
|
||||
[
|
||||
(state) => state.accounts,
|
||||
(_, accountId: string) => accountId,
|
||||
(state) => state.server.getIn(['server', 'domain']) as string | undefined,
|
||||
],
|
||||
(accounts, accountId, serverDomain) => {
|
||||
const acct = accounts.getIn([accountId, 'acct']) as string | undefined;
|
||||
if (!acct) {
|
||||
return undefined;
|
||||
}
|
||||
|
||||
const domain = acct.split('@').at(1);
|
||||
if (domain) {
|
||||
return domain;
|
||||
}
|
||||
|
||||
return serverDomain;
|
||||
},
|
||||
);
|
||||
|
||||
export const AccountJoinModal: FC<{
|
||||
accountId: string;
|
||||
onClose: () => void;
|
||||
}> = ({ accountId, onClose }) => {
|
||||
const intl = useIntl();
|
||||
const account = useAccount(accountId);
|
||||
const currentId = useCurrentAccountId();
|
||||
const isMe = accountId === currentId;
|
||||
|
||||
const createdAtStr = account?.created_at;
|
||||
const anniversary = useMemo(() => {
|
||||
if (!createdAtStr) {
|
||||
return null;
|
||||
}
|
||||
const now = new Date();
|
||||
const createdAt = new Date(createdAtStr);
|
||||
if (
|
||||
now.getMonth() === createdAt.getMonth() &&
|
||||
now.getDate() === createdAt.getDate()
|
||||
) {
|
||||
return now.getFullYear() - createdAt.getFullYear();
|
||||
}
|
||||
return null;
|
||||
}, [createdAtStr]);
|
||||
|
||||
const domain = useAppSelector((state) => selectServerName(state, accountId));
|
||||
|
||||
const dispatch = useAppDispatch();
|
||||
const handle = account?.acct;
|
||||
const handleShare = useCallback(() => {
|
||||
if (anniversary === null) {
|
||||
return;
|
||||
}
|
||||
|
||||
let shareText = '#Fediversary';
|
||||
if (anniversary === 0) {
|
||||
shareText = isMe ? '#firstday' : '#welcome';
|
||||
}
|
||||
|
||||
if (!isMe && handle) {
|
||||
shareText = `@${handle} ${shareText}`;
|
||||
}
|
||||
|
||||
dispatch(resetCompose());
|
||||
dispatch(focusCompose(`\n\n${shareText}`, true));
|
||||
dispatch(closeModal({ modalType: 'ACCOUNT_JOIN_DATE', ignoreFocus: true }));
|
||||
}, [anniversary, handle, dispatch, isMe]);
|
||||
|
||||
return (
|
||||
<ModalShell className={classes.joinShell}>
|
||||
<ModalShellBody className={classes.joinWrapper}>
|
||||
<AccountAnniversaryImage anniversary={anniversary} />
|
||||
|
||||
<div>
|
||||
<AccountJoinMessage
|
||||
name={<DisplayNameSimple account={account} />}
|
||||
isMe={isMe}
|
||||
serverName={domain}
|
||||
anniversary={anniversary}
|
||||
/>
|
||||
<h1>
|
||||
<FormattedDateWrapper
|
||||
value={account?.created_at}
|
||||
month='short'
|
||||
day='numeric'
|
||||
year='numeric'
|
||||
/>
|
||||
</h1>
|
||||
</div>
|
||||
|
||||
<AccountAnniversaryShare
|
||||
anniversary={anniversary}
|
||||
onShare={handleShare}
|
||||
isMe={isMe}
|
||||
/>
|
||||
|
||||
<IconButton
|
||||
iconComponent={CloseIcon}
|
||||
icon='times'
|
||||
onClick={onClose}
|
||||
title={intl.formatMessage(closeMessage)}
|
||||
className={classes.joinClose}
|
||||
/>
|
||||
</ModalShellBody>
|
||||
</ModalShell>
|
||||
);
|
||||
};
|
||||
|
||||
const AccountJoinMessage: FC<{
|
||||
name: React.JSX.Element;
|
||||
isMe: boolean;
|
||||
serverName?: string;
|
||||
anniversary: number | null;
|
||||
}> = ({ name, isMe, serverName, anniversary }) => {
|
||||
if (anniversary === 0) {
|
||||
if (isMe) {
|
||||
return (
|
||||
<FormattedMessage
|
||||
id='account.join_modal.me_today'
|
||||
defaultMessage='It’s your first day on {server}!'
|
||||
tagName='p'
|
||||
values={{
|
||||
server: serverName,
|
||||
}}
|
||||
/>
|
||||
);
|
||||
}
|
||||
return (
|
||||
<FormattedMessage
|
||||
id='account.join_modal.other_today'
|
||||
defaultMessage='It’s {name}’s first day on {server}!'
|
||||
tagName='p'
|
||||
values={{
|
||||
name,
|
||||
server: serverName,
|
||||
}}
|
||||
/>
|
||||
);
|
||||
}
|
||||
|
||||
if (isMe) {
|
||||
if (anniversary !== null && anniversary > 0) {
|
||||
return (
|
||||
<FormattedMessage
|
||||
id='account.join_modal.me_anniversary'
|
||||
defaultMessage='Happy Fediversary! You joined {server} on'
|
||||
tagName='p'
|
||||
values={{
|
||||
server: serverName,
|
||||
}}
|
||||
/>
|
||||
);
|
||||
}
|
||||
return (
|
||||
<FormattedMessage
|
||||
id='account.join_modal.me'
|
||||
defaultMessage='You joined {server} on'
|
||||
tagName='p'
|
||||
values={{
|
||||
server: serverName,
|
||||
}}
|
||||
/>
|
||||
);
|
||||
}
|
||||
|
||||
return (
|
||||
<FormattedMessage
|
||||
id='account.join_modal.other'
|
||||
defaultMessage='{name} joined {server} on'
|
||||
tagName='p'
|
||||
values={{
|
||||
name,
|
||||
server: serverName,
|
||||
}}
|
||||
/>
|
||||
);
|
||||
};
|
||||
|
||||
const AccountAnniversaryImage: FC<{ anniversary: number | null }> = ({
|
||||
anniversary,
|
||||
}) => {
|
||||
if (anniversary === null) {
|
||||
return null;
|
||||
}
|
||||
|
||||
return (
|
||||
<div className={classes.joinBanner}>
|
||||
<AnniversaryImage role='presentation' />
|
||||
<h2>{anniversary || 1}</h2>
|
||||
{anniversary === 0 && (
|
||||
<FormattedMessage
|
||||
id='account.join_modal.day'
|
||||
defaultMessage='Day'
|
||||
tagName='h3'
|
||||
/>
|
||||
)}
|
||||
{anniversary > 0 && (
|
||||
<FormattedMessage
|
||||
id='account.join_modal.years'
|
||||
defaultMessage='{number, plural, one {year} other {years}}'
|
||||
values={{ number: anniversary }}
|
||||
tagName='h3'
|
||||
/>
|
||||
)}
|
||||
</div>
|
||||
);
|
||||
};
|
||||
|
||||
const AccountAnniversaryShare: FC<{
|
||||
anniversary: number | null;
|
||||
onShare: () => void;
|
||||
isMe: boolean;
|
||||
}> = ({ anniversary, onShare, isMe }) => {
|
||||
if (anniversary === null) {
|
||||
return null;
|
||||
}
|
||||
|
||||
return (
|
||||
<Button onClick={onShare}>
|
||||
{anniversary === 0 && isMe && (
|
||||
<FormattedMessage
|
||||
id='account.join_modal.share.intro'
|
||||
defaultMessage='Share an intro post'
|
||||
/>
|
||||
)}
|
||||
{anniversary === 0 && !isMe && (
|
||||
<FormattedMessage
|
||||
id='account.join_modal.share.welcome'
|
||||
defaultMessage='Share a welcome post'
|
||||
/>
|
||||
)}
|
||||
{anniversary > 0 && (
|
||||
<FormattedMessage
|
||||
id='account.join_modal.share.celebrate'
|
||||
defaultMessage='Share a celebratory post'
|
||||
/>
|
||||
)}
|
||||
</Button>
|
||||
);
|
||||
};
|
||||
@ -13,7 +13,7 @@ import { useAppDispatch, useAppSelector } from '@/mastodon/store';
|
||||
|
||||
import { ConfirmationModal } from '../../ui/components/confirmation_modals';
|
||||
|
||||
import classes from './styles.module.css';
|
||||
import classes from './styles.module.scss';
|
||||
|
||||
const messages = defineMessages({
|
||||
newTitle: {
|
||||
|
||||
@ -1,32 +0,0 @@
|
||||
.noteCallout {
|
||||
margin-bottom: 16px;
|
||||
}
|
||||
|
||||
.noteInput {
|
||||
min-height: 70px;
|
||||
width: 100%;
|
||||
padding: 8px;
|
||||
border-radius: 8px;
|
||||
box-sizing: border-box;
|
||||
background: var(--color-bg-primary);
|
||||
border: 1px solid var(--color-border-primary);
|
||||
appearance: none;
|
||||
resize: none;
|
||||
margin-top: 4px;
|
||||
}
|
||||
|
||||
.noteInput:focus-visible {
|
||||
outline: var(--outline-focus-default);
|
||||
outline-offset: 2px;
|
||||
}
|
||||
|
||||
.fieldName,
|
||||
.fieldValue {
|
||||
word-break: break-all;
|
||||
}
|
||||
|
||||
.fieldValue {
|
||||
color: var(--color-text-primary);
|
||||
font-weight: 600;
|
||||
margin-top: 4px;
|
||||
}
|
||||
@ -0,0 +1,108 @@
|
||||
@use '@/styles/mastodon/variables' as *;
|
||||
|
||||
.noteCallout {
|
||||
margin-bottom: 16px;
|
||||
}
|
||||
|
||||
.noteInput {
|
||||
min-height: 70px;
|
||||
width: 100%;
|
||||
padding: 8px;
|
||||
border-radius: 8px;
|
||||
box-sizing: border-box;
|
||||
background: var(--color-bg-primary);
|
||||
border: 1px solid var(--color-border-primary);
|
||||
appearance: none;
|
||||
resize: none;
|
||||
margin-top: 4px;
|
||||
}
|
||||
|
||||
.noteInput:focus-visible {
|
||||
outline: var(--outline-focus-default);
|
||||
outline-offset: 2px;
|
||||
}
|
||||
|
||||
.fieldName,
|
||||
.fieldValue {
|
||||
word-break: break-all;
|
||||
}
|
||||
|
||||
.fieldValue {
|
||||
color: var(--color-text-primary);
|
||||
font-weight: 600;
|
||||
margin-top: 4px;
|
||||
}
|
||||
|
||||
@media screen and (min-width: ($mobile-breakpoint + 1)) {
|
||||
.joinShell {
|
||||
> :global(.safety-action-modal__top) {
|
||||
border-bottom-left-radius: 16px;
|
||||
border-bottom-right-radius: 16px;
|
||||
border-bottom-width: 1px;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
.joinWrapper {
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
color: var(--color-text-primary);
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
position: relative;
|
||||
min-height: 120px;
|
||||
gap: 16px;
|
||||
|
||||
p,
|
||||
h1 {
|
||||
text-align: center;
|
||||
}
|
||||
|
||||
p {
|
||||
font-size: 13px;
|
||||
}
|
||||
|
||||
h1 {
|
||||
margin-top: 8px;
|
||||
margin-bottom: 0;
|
||||
font-size: 17px;
|
||||
font-weight: 600;
|
||||
}
|
||||
}
|
||||
|
||||
.joinBanner {
|
||||
width: 120px;
|
||||
height: 110px;
|
||||
position: relative;
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
|
||||
svg {
|
||||
width: 100%;
|
||||
position: absolute;
|
||||
top: 0;
|
||||
left: 0;
|
||||
}
|
||||
|
||||
h2 {
|
||||
font-size: 40px;
|
||||
font-weight: 600;
|
||||
line-height: 40px;
|
||||
margin-top: 8px;
|
||||
}
|
||||
|
||||
h3 {
|
||||
font-size: 13px;
|
||||
color: var(--color-text-secondary);
|
||||
text-transform: uppercase;
|
||||
}
|
||||
}
|
||||
|
||||
.joinClose {
|
||||
position: absolute;
|
||||
top: 0;
|
||||
right: 0;
|
||||
z-index: 1;
|
||||
}
|
||||
@ -13,6 +13,8 @@ import { RelativeTimestamp } from 'mastodon/components/relative_timestamp';
|
||||
import { useAccount } from 'mastodon/hooks/useAccount';
|
||||
import { domain } from 'mastodon/initial_state';
|
||||
|
||||
import { getCollectionPath } from '../utils';
|
||||
|
||||
import classes from './collection_lockup.module.scss';
|
||||
|
||||
export const AvatarGrid: React.FC<{
|
||||
@ -27,10 +29,10 @@ export const AvatarGrid: React.FC<{
|
||||
sensitive ? classes.avatarGridSensitive : null,
|
||||
)}
|
||||
>
|
||||
{avatarIds.map((id) => (
|
||||
{avatarIds.map((id, index) => (
|
||||
<AvatarById
|
||||
animate={false}
|
||||
key={id}
|
||||
key={index}
|
||||
accountId={id}
|
||||
className={classes.avatar}
|
||||
size={25}
|
||||
@ -67,7 +69,7 @@ export const CollectionLockup: React.FC<CollectionLockupProps> = ({
|
||||
/>
|
||||
<div>
|
||||
<h2 id={linkId}>
|
||||
<Link to={`/collections/${id}`} className={classes.link}>
|
||||
<Link to={getCollectionPath(id)} className={classes.link}>
|
||||
{name}
|
||||
</Link>
|
||||
</h2>
|
||||
|
||||
@ -15,6 +15,7 @@ import type { MenuItem } from 'mastodon/models/dropdown_menu';
|
||||
import { useAppDispatch } from 'mastodon/store';
|
||||
|
||||
import { messages as editorMessages } from '../editor';
|
||||
import { getCollectionPath } from '../utils';
|
||||
|
||||
const messages = defineMessages({
|
||||
view: {
|
||||
@ -120,7 +121,7 @@ export const CollectionMenu: React.FC<{
|
||||
const menu = useMemo(() => {
|
||||
const viewCollectionItem: MenuItem = {
|
||||
text: intl.formatMessage(messages.view),
|
||||
to: `/collections/${id}`,
|
||||
to: getCollectionPath(id),
|
||||
};
|
||||
const shareItems: MenuItem[] = [
|
||||
{
|
||||
@ -130,7 +131,7 @@ export const CollectionMenu: React.FC<{
|
||||
{
|
||||
text: intl.formatMessage(messages.copyLink),
|
||||
action: () => {
|
||||
void navigator.clipboard.writeText(`/collections/${id}`);
|
||||
void navigator.clipboard.writeText(getCollectionPath(id));
|
||||
dispatch(showAlert({ message: messages.copyLinkConfirmation }));
|
||||
},
|
||||
},
|
||||
|
||||
@ -1,3 +1,5 @@
|
||||
import classNames from 'classnames';
|
||||
|
||||
import type { CollectionLockupProps } from 'mastodon/features/collections/components/collection_lockup';
|
||||
import { CollectionLockup } from 'mastodon/features/collections/components/collection_lockup';
|
||||
|
||||
@ -13,7 +15,7 @@ export const CollectionPreviewCard: React.FC<CollectionPreviewCardProps> = ({
|
||||
...otherProps
|
||||
}) => {
|
||||
return (
|
||||
<div className={classes.wrapper}>
|
||||
<div className={classNames(classes.wrapper, 'collection-preview')}>
|
||||
<CollectionLockup collection={collection} {...otherProps} />
|
||||
</div>
|
||||
);
|
||||
|
||||
@ -7,6 +7,8 @@ import { useHistory } from 'react-router-dom';
|
||||
import { isFulfilled } from '@reduxjs/toolkit';
|
||||
|
||||
import { ComboboxMenuItem } from '@/mastodon/components/form_fields/combobox_field';
|
||||
import { useAccount } from '@/mastodon/hooks/useAccount';
|
||||
import { useCurrentAccountId } from '@/mastodon/hooks/useAccountId';
|
||||
import { languages } from '@/mastodon/initial_state';
|
||||
import {
|
||||
hasSpecialCharacters,
|
||||
@ -36,6 +38,8 @@ import {
|
||||
} from 'mastodon/reducers/slices/collections';
|
||||
import { useAppDispatch, useAppSelector } from 'mastodon/store';
|
||||
|
||||
import { getCollectionPath } from '../utils';
|
||||
|
||||
import classes from './styles.module.scss';
|
||||
import { WizardStepTitle } from './wizard_step_title';
|
||||
|
||||
@ -93,6 +97,9 @@ export const CollectionDetails: React.FC = () => {
|
||||
[dispatch],
|
||||
);
|
||||
|
||||
const accountId = useCurrentAccountId();
|
||||
const { acct: currentUserName } = useAccount(accountId) ?? {};
|
||||
|
||||
const handleSubmit = useCallback(
|
||||
(e: React.FormEvent) => {
|
||||
e.preventDefault();
|
||||
@ -128,8 +135,8 @@ export const CollectionDetails: React.FC = () => {
|
||||
}),
|
||||
).then((result) => {
|
||||
if (isFulfilled(result)) {
|
||||
history.replace(`/collections`);
|
||||
history.push(`/collections/${result.payload.collection.id}`, {
|
||||
history.replace(`/@${currentUserName}/collections`);
|
||||
history.push(getCollectionPath(result.payload.collection.id), {
|
||||
newCollection: true,
|
||||
});
|
||||
}
|
||||
@ -146,6 +153,7 @@ export const CollectionDetails: React.FC = () => {
|
||||
dispatch,
|
||||
history,
|
||||
accountIds,
|
||||
currentUserName,
|
||||
],
|
||||
);
|
||||
|
||||
|
||||
@ -1,6 +1,6 @@
|
||||
import { useEffect } from 'react';
|
||||
|
||||
import { defineMessages, useIntl } from 'react-intl';
|
||||
import { defineMessages, FormattedMessage, useIntl } from 'react-intl';
|
||||
|
||||
import { Helmet } from 'react-helmet';
|
||||
import {
|
||||
@ -12,6 +12,9 @@ import {
|
||||
useLocation,
|
||||
} from 'react-router-dom';
|
||||
|
||||
import { Callout } from '@/mastodon/components/callout';
|
||||
import { useCurrentAccountId } from '@/mastodon/hooks/useAccountId';
|
||||
import { initialState } from '@/mastodon/initial_state';
|
||||
import ListAltIcon from '@/material-icons/400-24px/list_alt.svg?react';
|
||||
import { Column } from 'mastodon/components/column';
|
||||
import { ColumnHeader } from 'mastodon/components/column_header';
|
||||
@ -22,8 +25,11 @@ import {
|
||||
} from 'mastodon/reducers/slices/collections';
|
||||
import { useAppDispatch, useAppSelector } from 'mastodon/store';
|
||||
|
||||
import { useAccountCollections } from '..';
|
||||
|
||||
import { CollectionAccounts } from './accounts';
|
||||
import { CollectionDetails } from './details';
|
||||
import classes from './styles.module.scss';
|
||||
|
||||
export const messages = defineMessages({
|
||||
create: {
|
||||
@ -61,11 +67,14 @@ function usePageTitle(id: string | null) {
|
||||
}
|
||||
}
|
||||
|
||||
export const userCollectionLimit = initialState?.role?.collection_limit ?? 0;
|
||||
|
||||
export const CollectionEditorPage: React.FC<{
|
||||
multiColumn?: boolean;
|
||||
}> = ({ multiColumn }) => {
|
||||
const intl = useIntl();
|
||||
const dispatch = useAppDispatch();
|
||||
const accountId = useCurrentAccountId();
|
||||
const { id = null } = useParams<{ id?: string }>();
|
||||
const { path } = useRouteMatch();
|
||||
const collection = useAppSelector((state) =>
|
||||
@ -73,7 +82,18 @@ export const CollectionEditorPage: React.FC<{
|
||||
);
|
||||
const editorStateId = useAppSelector((state) => state.collections.editor.id);
|
||||
const isEditMode = !!id;
|
||||
const isLoading = isEditMode && !collection;
|
||||
|
||||
// When creating a new collection, we load the current account's collections
|
||||
// to determine if they're allowed to create more.
|
||||
const { collections: collectionList, status: collectionListStatus } =
|
||||
useAccountCollections(isEditMode ? null : accountId);
|
||||
|
||||
const isLoading =
|
||||
(isEditMode && !collection) ||
|
||||
(!isEditMode && collectionListStatus === 'loading');
|
||||
|
||||
const canCreateMoreCollections =
|
||||
isEditMode || collectionList.length < userCollectionLimit;
|
||||
|
||||
useEffect(() => {
|
||||
if (id) {
|
||||
@ -108,7 +128,7 @@ export const CollectionEditorPage: React.FC<{
|
||||
<div className='scrollable'>
|
||||
{isLoading ? (
|
||||
<LoadingIndicator />
|
||||
) : (
|
||||
) : canCreateMoreCollections ? (
|
||||
<Switch>
|
||||
<Route
|
||||
exact
|
||||
@ -123,6 +143,8 @@ export const CollectionEditorPage: React.FC<{
|
||||
render={() => <CollectionDetails />}
|
||||
/>
|
||||
</Switch>
|
||||
) : (
|
||||
<MaxCollectionsCallout />
|
||||
)}
|
||||
</div>
|
||||
|
||||
@ -133,3 +155,21 @@ export const CollectionEditorPage: React.FC<{
|
||||
</Column>
|
||||
);
|
||||
};
|
||||
|
||||
export const MaxCollectionsCallout: React.FC = () => (
|
||||
<Callout
|
||||
className={classes.maxCollectionsError}
|
||||
title={
|
||||
<FormattedMessage
|
||||
id='collections.maximum_collection_count_reached'
|
||||
defaultMessage='You have created the maximum number of collections'
|
||||
/>
|
||||
}
|
||||
>
|
||||
<FormattedMessage
|
||||
id='collections.maximum_collection_count_description'
|
||||
defaultMessage='Your server allows creation of up to {count} collections.'
|
||||
values={{ count: userCollectionLimit }}
|
||||
/>
|
||||
</Callout>
|
||||
);
|
||||
|
||||
@ -77,3 +77,7 @@
|
||||
.suggestionGroup {
|
||||
padding-bottom: 4px;
|
||||
}
|
||||
|
||||
.maxCollectionsError {
|
||||
margin: 16px;
|
||||
}
|
||||
|
||||
@ -25,7 +25,12 @@ import {
|
||||
import { useAppSelector, useAppDispatch } from 'mastodon/store';
|
||||
|
||||
import { CollectionListItem } from './components/collection_list_item';
|
||||
import { messages as editorMessages } from './editor';
|
||||
import {
|
||||
messages as editorMessages,
|
||||
MaxCollectionsCallout,
|
||||
userCollectionLimit,
|
||||
} from './editor';
|
||||
import { areCollectionsEnabled } from './utils';
|
||||
|
||||
const messages = defineMessages({
|
||||
headingMe: { id: 'column.my_collections', defaultMessage: 'My collections' },
|
||||
@ -35,24 +40,27 @@ const messages = defineMessages({
|
||||
},
|
||||
});
|
||||
|
||||
export function useAccountCollections(accountId: string | null | undefined) {
|
||||
const dispatch = useAppDispatch();
|
||||
|
||||
useEffect(() => {
|
||||
if (accountId && areCollectionsEnabled()) {
|
||||
void dispatch(fetchAccountCollections({ accountId }));
|
||||
}
|
||||
}, [dispatch, accountId]);
|
||||
|
||||
return useAppSelector((state) => selectAccountCollections(state, accountId));
|
||||
}
|
||||
|
||||
export const Collections: React.FC<{
|
||||
multiColumn?: boolean;
|
||||
}> = ({ multiColumn }) => {
|
||||
const dispatch = useAppDispatch();
|
||||
const intl = useIntl();
|
||||
const me = useCurrentAccountId();
|
||||
const accountId = useAccountId();
|
||||
const account = useAccount(accountId);
|
||||
|
||||
const { collections, status } = useAppSelector((state) =>
|
||||
selectAccountCollections(state, accountId),
|
||||
);
|
||||
|
||||
useEffect(() => {
|
||||
if (accountId) {
|
||||
void dispatch(fetchAccountCollections({ accountId }));
|
||||
}
|
||||
}, [dispatch, accountId]);
|
||||
const { collections, status } = useAccountCollections(accountId);
|
||||
|
||||
const emptyMessage =
|
||||
status === 'error' || !accountId ? (
|
||||
@ -79,6 +87,7 @@ export const Collections: React.FC<{
|
||||
</>
|
||||
);
|
||||
|
||||
const canCreateMoreCollections = collections.length < userCollectionLimit;
|
||||
const isOwnCollection = accountId === me;
|
||||
const titleMessage = isOwnCollection
|
||||
? messages.headingMe
|
||||
@ -99,7 +108,9 @@ export const Collections: React.FC<{
|
||||
iconComponent={CollectionsFilledIcon}
|
||||
multiColumn={multiColumn}
|
||||
extraButton={
|
||||
isOwnCollection && (
|
||||
isOwnCollection &&
|
||||
status === 'idle' &&
|
||||
canCreateMoreCollections && (
|
||||
<Link
|
||||
to='/collections/new'
|
||||
className='column-header__button'
|
||||
@ -113,6 +124,9 @@ export const Collections: React.FC<{
|
||||
/>
|
||||
|
||||
<Scrollable>
|
||||
{status === 'idle' && !canCreateMoreCollections && (
|
||||
<MaxCollectionsCallout />
|
||||
)}
|
||||
<ItemList emptyMessage={emptyMessage} isLoading={status === 'loading'}>
|
||||
{collections.map((item, index) => (
|
||||
<CollectionListItem
|
||||
|
||||
@ -3,3 +3,5 @@ import { isServerFeatureEnabled } from '@/mastodon/utils/environment';
|
||||
export function areCollectionsEnabled() {
|
||||
return isServerFeatureEnabled('collections');
|
||||
}
|
||||
|
||||
export const getCollectionPath = (id: string) => `/collections/${id}`;
|
||||
|
||||
@ -267,6 +267,11 @@ export async function searchCustomEmojisByShortcodes(shortcodes: string[]) {
|
||||
return results.filter((emoji) => shortcodes.includes(emoji.shortcode));
|
||||
}
|
||||
|
||||
export async function loadAllCustomEmoji() {
|
||||
const db = await loadDB();
|
||||
return db.getAll('custom');
|
||||
}
|
||||
|
||||
export async function loadLegacyShortcodesByShortcode(shortcode: string) {
|
||||
const db = await loadDB();
|
||||
return db.getFromIndex(
|
||||
|
||||
@ -185,21 +185,16 @@ export function cleanExtraEmojis(extraEmojis?: CustomEmojiMapArg | null) {
|
||||
if (!extraEmojis) {
|
||||
return null;
|
||||
}
|
||||
if (Array.isArray(extraEmojis)) {
|
||||
return extraEmojis.reduce<ExtraCustomEmojiMap>(
|
||||
(acc, emoji) => ({ ...acc, [emoji.shortcode]: emoji }),
|
||||
{},
|
||||
);
|
||||
if (!Array.isArray(extraEmojis) && !isList(extraEmojis)) {
|
||||
return extraEmojis;
|
||||
}
|
||||
if (isList(extraEmojis)) {
|
||||
return extraEmojis
|
||||
.toJS()
|
||||
.reduce<ExtraCustomEmojiMap>(
|
||||
(acc, emoji) => ({ ...acc, [emoji.shortcode]: emoji }),
|
||||
{},
|
||||
);
|
||||
const emojis: ExtraCustomEmojiMap = {};
|
||||
const emojiArray = isList(extraEmojis) ? extraEmojis.toJS() : extraEmojis;
|
||||
for (const emoji of emojiArray) {
|
||||
emojis[emoji.shortcode] = emoji;
|
||||
}
|
||||
return extraEmojis;
|
||||
|
||||
return emojis;
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
@ -7,6 +7,7 @@ import elephantUIPlane from '@/images/elephant_ui_plane.svg';
|
||||
import type { RenderSlideFn } from '@/mastodon/components/carousel';
|
||||
import { Carousel } from '@/mastodon/components/carousel';
|
||||
import { CustomEmojiProvider } from '@/mastodon/components/emoji/context';
|
||||
import { useCustomEmojis } from '@/mastodon/hooks/useCustomEmojis';
|
||||
import { mascot } from '@/mastodon/initial_state';
|
||||
import { createAppSelector, useAppSelector } from '@/mastodon/store';
|
||||
|
||||
@ -23,7 +24,7 @@ const announcementSelector = createAppSelector(
|
||||
|
||||
export const Announcements: FC = () => {
|
||||
const announcements = useAppSelector(announcementSelector);
|
||||
const emojis = useAppSelector((state) => state.custom_emojis);
|
||||
const emojis = useCustomEmojis();
|
||||
|
||||
const renderSlide: RenderSlideFn<{
|
||||
id: string;
|
||||
|
||||
@ -29,9 +29,12 @@ import StatusContent from 'mastodon/components/status_content';
|
||||
import { QuotedStatus } from 'mastodon/components/status_quoted';
|
||||
import { VisibilityIcon } from 'mastodon/components/visibility_icon';
|
||||
import { Audio } from 'mastodon/features/audio';
|
||||
import { CollectionPreviewCard } from 'mastodon/features/collections/components/collection_preview_card';
|
||||
import scheduleIdleTask from 'mastodon/features/ui/util/schedule_idle_task';
|
||||
import { Video } from 'mastodon/features/video';
|
||||
import { useIdentity } from 'mastodon/identity_context';
|
||||
import type { CollectionAttachment } from 'mastodon/models/status';
|
||||
import { compareUrls } from 'mastodon/utils/compare_urls';
|
||||
|
||||
import Card from './card';
|
||||
|
||||
@ -260,13 +263,32 @@ export const DetailedStatus: React.FC<{
|
||||
);
|
||||
}
|
||||
} else if (status.get('card') && !status.get('quote')) {
|
||||
media = (
|
||||
<Card
|
||||
key={`${status.get('id')}-${status.get('edited_at')}`}
|
||||
sensitive={status.get('sensitive')}
|
||||
card={status.get('card')}
|
||||
/>
|
||||
);
|
||||
const cardUrl: string = status.getIn(['card', 'url']);
|
||||
|
||||
const taggedCollection = status
|
||||
.get('tagged_collections')
|
||||
.find((item: CollectionAttachment) =>
|
||||
compareUrls(item.get('url'), cardUrl),
|
||||
);
|
||||
|
||||
if (taggedCollection) {
|
||||
media = <CollectionPreviewCard collection={taggedCollection} />;
|
||||
} else {
|
||||
media = (
|
||||
<Card
|
||||
key={`${status.get('id')}-${status.get('edited_at')}`}
|
||||
sensitive={status.get('sensitive')}
|
||||
card={status.get('card')}
|
||||
/>
|
||||
);
|
||||
}
|
||||
} else if (status.get('tagged_collections').size) {
|
||||
const firstLinkedCollection = status.get('tagged_collections').first();
|
||||
if (firstLinkedCollection) {
|
||||
media = (
|
||||
<CollectionPreviewCard collection={firstLinkedCollection.toJS()} />
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
if (status.get('application')) {
|
||||
|
||||
@ -93,6 +93,7 @@ export const MODAL_COMPONENTS = {
|
||||
'COMPOSE_PRIVACY': () => Promise.resolve({ default: VisibilityModal }),
|
||||
'ACCOUNT_NOTE': () => import('@/mastodon/features/account_timeline/modals/note_modal').then(module => ({ default: module.AccountNoteModal })),
|
||||
'ACCOUNT_FIELD_OVERFLOW': () => import('@/mastodon/features/account_timeline/modals/field_modal').then(module => ({ default: module.AccountFieldModal })),
|
||||
'ACCOUNT_JOIN_DATE': () => import('@/mastodon/features/account_timeline/modals/join_modal').then(module => ({ default: module.AccountJoinModal })),
|
||||
'ACCOUNT_EDIT_NAME': accountEditModal('NameModal'),
|
||||
'ACCOUNT_EDIT_BIO': accountEditModal('BioModal'),
|
||||
'ACCOUNT_EDIT_PROFILE_DISPLAY': accountEditModal('ProfileDisplayModal'),
|
||||
|
||||
35
app/javascript/mastodon/hooks/useCustomEmojis.ts
Normal file
35
app/javascript/mastodon/hooks/useCustomEmojis.ts
Normal file
@ -0,0 +1,35 @@
|
||||
import { useEffect, useState } from 'react';
|
||||
|
||||
import type { ExtraCustomEmojiMap } from '../features/emoji/types';
|
||||
|
||||
let emojis: ExtraCustomEmojiMap | null = null;
|
||||
|
||||
export function useCustomEmojis() {
|
||||
const [, setLoaded] = useState(emojis !== null);
|
||||
useEffect(() => {
|
||||
if (!emojis) {
|
||||
void loadEmojisIntoCache().then(() => {
|
||||
setLoaded(true);
|
||||
});
|
||||
}
|
||||
}, []);
|
||||
|
||||
return emojis;
|
||||
}
|
||||
|
||||
async function loadEmojisIntoCache() {
|
||||
const { loadAllCustomEmoji } = await import('../features/emoji/database');
|
||||
const emojisRaw = await loadAllCustomEmoji();
|
||||
if (emojisRaw.length === 0) {
|
||||
return;
|
||||
}
|
||||
|
||||
emojis = {};
|
||||
for (const emoji of emojisRaw) {
|
||||
emojis[emoji.shortcode] = {
|
||||
url: emoji.url,
|
||||
shortcode: emoji.shortcode,
|
||||
static_url: emoji.static_url,
|
||||
};
|
||||
}
|
||||
}
|
||||
@ -57,6 +57,7 @@ interface Role {
|
||||
permissions: string;
|
||||
color: string;
|
||||
highlighted: boolean;
|
||||
collection_limit: number;
|
||||
}
|
||||
|
||||
interface InitialWrapstodonState {
|
||||
|
||||
@ -18,8 +18,12 @@
|
||||
"account.add_note": "إضافة ملاحظة شخصية",
|
||||
"account.add_or_remove_from_list": "الإضافة أو الإزالة من القائمة",
|
||||
"account.badges.admin": "مدير",
|
||||
"account.badges.blocked": "محظور",
|
||||
"account.badges.bot": "آلي",
|
||||
"account.badges.domain_blocked": "النطاق محظور",
|
||||
"account.badges.group": "فريق",
|
||||
"account.badges.muted": "مكتوم",
|
||||
"account.badges.muted_until": "مكتوم إلى غاية {until}",
|
||||
"account.block": "احجب @{name}",
|
||||
"account.block_domain": "حظر اسم النِّطاق {domain}",
|
||||
"account.block_short": "حظر",
|
||||
@ -30,6 +34,7 @@
|
||||
"account.direct": "إشارة خاصة لـ @{name}",
|
||||
"account.disable_notifications": "توقف عن إشعاري عندما ينشر @{name}",
|
||||
"account.domain_blocking": "نطاق محظور",
|
||||
"account.edit_note": "تعديل الملاحظة الشخصية",
|
||||
"account.edit_profile": "تعديل الملف الشخصي",
|
||||
"account.edit_profile_short": "تعديل",
|
||||
"account.enable_notifications": "أشعرني عندما ينشر @{name}",
|
||||
@ -40,6 +45,8 @@
|
||||
"account.featured": "معروض",
|
||||
"account.featured.accounts": "ملفات شخصية",
|
||||
"account.filters.all": "جميع الأنشطة",
|
||||
"account.filters.boosts_toggle": "اعرض المعاد نشرها",
|
||||
"account.filters.posts_boosts": "المنشورات والمعاد نشرها",
|
||||
"account.filters.posts_only": "منشورات",
|
||||
"account.filters.posts_replies": "المنشورات والردود",
|
||||
"account.filters.replies_toggle": "اعرض الردود",
|
||||
@ -49,6 +56,7 @@
|
||||
"account.follow_request": "طلب المتابعة",
|
||||
"account.follow_request_cancel": "إلغاء الطلب",
|
||||
"account.follow_request_cancel_short": "إلغاء",
|
||||
"account.follow_request_short": "طلب المتابعة",
|
||||
"account.followers": "مُتابِعون",
|
||||
"account.followers.empty": "لا أحدَ يُتابع هذا المُستخدم إلى حد الآن.",
|
||||
"account.followers_counter": "{count, plural, zero{لا مُتابع} one {مُتابعٌ واحِد} two {مُتابعانِ اِثنان} few {{counter} مُتابِعين} many {{counter} مُتابِعًا} other {{counter} مُتابع}}",
|
||||
@ -62,11 +70,26 @@
|
||||
"account.in_memoriam": "في الذكرى.",
|
||||
"account.joined_short": "انضم في",
|
||||
"account.languages": "تغيير اللغات المشترَك فيها",
|
||||
"account.last_active": "آخر نشاط",
|
||||
"account.link_verified_on": "تمَّ التَّحقق مِن مِلْكيّة هذا الرابط بتاريخ {date}",
|
||||
"account.locked_info": "تم ضبط حالة خصوصية هذا الحساب على أنه مؤمّن. إذ يراجع صاحبه يدويًا من يُسمح له بالمتابعة.",
|
||||
"account.media": "وسائط",
|
||||
"account.mention": "أذكُر @{name}",
|
||||
"account.menu.add_to_list": "إضافة إلى القائمة…",
|
||||
"account.menu.block": "حظر الحساب",
|
||||
"account.menu.block_domain": "حظر {domain}",
|
||||
"account.menu.copied": "تم نسخ رابط الحساب إلى الحافظة",
|
||||
"account.menu.copy": "نسخ الرابط",
|
||||
"account.menu.direct": "إشارة خاصة لـ",
|
||||
"account.menu.mention": "إشارة",
|
||||
"account.menu.mute": "كتم الحساب",
|
||||
"account.menu.note.description": "مرئي لك فقط",
|
||||
"account.menu.remove_follower": "إزالة المتابِع",
|
||||
"account.menu.report": "الإبلاغ عن الحساب",
|
||||
"account.menu.share": "مشاركة…",
|
||||
"account.menu.unblock": "رفع الحظر عن الحساب",
|
||||
"account.menu.unblock_domain": "رفع الحظر عن {domain}",
|
||||
"account.menu.unmute": "إلغاء كتم الحساب",
|
||||
"account.moved_to": "أشار {name} إلى أن حسابه الجديد الآن:",
|
||||
"account.mute": "أكتم @{name}",
|
||||
"account.mute_notifications_short": "كتم الإشعارات",
|
||||
@ -74,7 +97,11 @@
|
||||
"account.muted": "مَكتوم",
|
||||
"account.muting": "مكتوم",
|
||||
"account.mutual": "أنتم تتابعون بعضكم البعض",
|
||||
"account.name.copy": "نسخ المعرف",
|
||||
"account.name_info": "ما معنى ذلك؟",
|
||||
"account.no_bio": "لم يتم تقديم وصف.",
|
||||
"account.node_modal.edit_title": "تعديل الملاحظة الشخصية",
|
||||
"account.node_modal.error_unknown": "تعذر حفظ الملاحظة",
|
||||
"account.node_modal.field_label": "ملاحظة شخصية",
|
||||
"account.node_modal.save": "حفظ",
|
||||
"account.node_modal.title": "إضافة ملاحظة شخصية",
|
||||
@ -89,6 +116,8 @@
|
||||
"account.share": "شارِك الملف التعريفي لـ @{name}",
|
||||
"account.show_reblogs": "اعرض إعادات نشر @{name}",
|
||||
"account.statuses_counter": "{count, plural, zero {}one {{counter} مشور} two {{counter} منشور} few {{counter} منشور} many {{counter} منشور} other {{counter} منشور}}",
|
||||
"account.timeline.pinned": "مثبّت",
|
||||
"account.timeline.pinned.view_all": "عرض جميع المنشورات المثبتة",
|
||||
"account.unblock": "إلغاء الحَظر عن @{name}",
|
||||
"account.unblock_domain": "إلغاء الحَظر عن النِّطاق {domain}",
|
||||
"account.unblock_domain_short": "رفع الحظر",
|
||||
@ -98,20 +127,57 @@
|
||||
"account.unmute": "إلغاء الكَتم عن @{name}",
|
||||
"account.unmute_notifications_short": "إلغاء كَتم الإشعارات",
|
||||
"account.unmute_short": "إلغاء الكتم",
|
||||
"account_edit.advanced_settings.bot_label": "حساب آلي",
|
||||
"account_edit.advanced_settings.title": "الإعدادات المتقدمة",
|
||||
"account_edit.bio.add_label": "إضافة سيرة ذاتية",
|
||||
"account_edit.bio.edit_label": "تعديل السيرة الذاتية",
|
||||
"account_edit.bio.title": "نبذة عنك",
|
||||
"account_edit.bio_modal.add_title": "إضافة سيرة ذاتية",
|
||||
"account_edit.bio_modal.edit_title": "تعديل السيرة الذاتية",
|
||||
"account_edit.column_button": "تمّ",
|
||||
"account_edit.column_title": "تعديل الملف الشخصي",
|
||||
"account_edit.custom_fields.add_label": "إضافة حقل",
|
||||
"account_edit.custom_fields.edit_label": "تعديل الحقل",
|
||||
"account_edit.custom_fields.placeholder": "أضف ضمائر أو روابط خارجية أو أي شيء آخر ترغب في مشاركته.",
|
||||
"account_edit.custom_fields.reorder_button": "إعادة ترتيب الحقول",
|
||||
"account_edit.custom_fields.tip_title": "نصيحة: إضافة روابط متحقق منها",
|
||||
"account_edit.custom_fields.title": "الحقول المخصصة",
|
||||
"account_edit.custom_fields.verified_hint": "كيف يمكنني إضافة رابط متحقق منه؟",
|
||||
"account_edit.display_name.add_label": "إضافة اسم علني",
|
||||
"account_edit.display_name.edit_label": "تعديل الاسم العلني",
|
||||
"account_edit.display_name.title": "الاسم العلني",
|
||||
"account_edit.featured_hashtags.edit_label": "إضافة وسوم",
|
||||
"account_edit.featured_hashtags.title": "الوسوم المروّجة",
|
||||
"account_edit.field_actions.delete": "حذف الحقل",
|
||||
"account_edit.field_actions.edit": "تعديل الحقل",
|
||||
"account_edit.field_delete_modal.delete_button": "حذف",
|
||||
"account_edit.field_delete_modal.title": "أتريد حذف الحقل المخصص؟",
|
||||
"account_edit.field_edit_modal.add_title": "إضافة حقل مخصص",
|
||||
"account_edit.field_edit_modal.discard_confirm": "تجاهل",
|
||||
"account_edit.field_edit_modal.edit_title": "تعديل الحقل المخصص",
|
||||
"account_edit.field_edit_modal.name_hint": "على سبيل المثال \"الموقع الشخصي\"",
|
||||
"account_edit.field_edit_modal.name_label": "التسمية",
|
||||
"account_edit.field_edit_modal.url_warning": "لإضافة رابط ، يرجى تضمين {protocol} في البداية.",
|
||||
"account_edit.field_edit_modal.value_hint": "على سبيل المثال \"https://example.me\"",
|
||||
"account_edit.field_edit_modal.value_label": "قيمة",
|
||||
"account_edit.image_alt_modal.add_title": "إضافة نص بديل",
|
||||
"account_edit.image_alt_modal.edit_title": "تعديل نص بديل",
|
||||
"account_edit.image_alt_modal.text_label": "نص بديل",
|
||||
"account_edit.image_delete_modal.delete_button": "حذف",
|
||||
"account_edit.image_edit.add_button": "إضافة صورة",
|
||||
"account_edit.image_edit.alt_add_button": "إضافة نص بديل",
|
||||
"account_edit.image_edit.alt_edit_button": "تعديل نص بديل",
|
||||
"account_edit.image_edit.remove_button": "إزالة الصورة",
|
||||
"account_edit.image_edit.replace_button": "استبدال الصورة",
|
||||
"account_edit.item_list.delete": "حذف {name}",
|
||||
"account_edit.item_list.edit": "تعديل {name}",
|
||||
"account_edit.profile_tab.button_label": "تخصيص",
|
||||
"account_edit.save": "حفظ",
|
||||
"account_edit.upload_modal.back": "العودة",
|
||||
"account_edit.upload_modal.done": "تمّ",
|
||||
"account_edit.upload_modal.next": "التالي",
|
||||
"account_edit.upload_modal.step_crop.zoom": "تكبير",
|
||||
"account_edit.upload_modal.step_upload.button": "تصفح الملفات",
|
||||
"account_edit.upload_modal.step_upload.dragging": "إسقاط للتحميل",
|
||||
"account_edit.upload_modal.step_upload.header": "اختيار صورة",
|
||||
"account_edit.upload_modal.title_add.avatar": "إضافة صورة الملف الشخصي",
|
||||
@ -119,6 +185,7 @@
|
||||
"account_edit.upload_modal.title_replace.avatar": "استبدال صورة الملف الشخصي",
|
||||
"account_edit.upload_modal.title_replace.header": "استبدال صورة الغلاف",
|
||||
"account_edit_tags.add_tag": "إضافة #{tagName}",
|
||||
"account_edit_tags.suggestions": "الاقتراحات:",
|
||||
"account_note.placeholder": "اضغط لإضافة مُلاحظة",
|
||||
"admin.dashboard.daily_retention": "معدّل بقاء المستخدمين بعد إنشاء الحسابات، بالأيام",
|
||||
"admin.dashboard.monthly_retention": "معدّل بقاء المستخدمين بعد إنشاء الحسابات، بالشهور",
|
||||
@ -145,6 +212,7 @@
|
||||
"annual_report.announcement.action_dismiss": "لا شكراً",
|
||||
"annual_report.nav_item.badge": "جديد",
|
||||
"annual_report.shared_page.donate": "تبرع",
|
||||
"annual_report.summary.archetype.oracle.name": "الحكيم",
|
||||
"annual_report.summary.archetype.replier.name": "الفراشة",
|
||||
"annual_report.summary.close": "اغلق",
|
||||
"annual_report.summary.copy_link": "نسخ الرابط",
|
||||
@ -186,17 +254,33 @@
|
||||
"closed_registrations_modal.find_another_server": "ابحث على خادم آخر",
|
||||
"closed_registrations_modal.preamble": "ماستدون لامركزي، لذلك بغض النظر عن مكان إنشاء حسابك، سيكون بإمكانك المتابعة والتفاعل مع أي شخص على هذا الخادم. يمكنك حتى أن تستضيفه ذاتياً!",
|
||||
"closed_registrations_modal.title": "إنشاء حساب على ماستدون",
|
||||
"collection.share_modal.share_link_label": "مشاركة الرابط",
|
||||
"collection.share_modal.share_via_post": "نشر على ماستدون",
|
||||
"collections.block_collection_owner": "حظر الحساب",
|
||||
"collections.by_account": "مِن {account_handle}",
|
||||
"collections.collection_description": "الوصف",
|
||||
"collections.collection_language": "اللغة",
|
||||
"collections.collection_language_none": "لا شيء",
|
||||
"collections.collection_name": "الاسم",
|
||||
"collections.collection_topic": "الموضوع",
|
||||
"collections.content_warning": "تحذير عن المحتوى",
|
||||
"collections.continue": "مواصلة",
|
||||
"collections.copy_link": "نسخ الرابط",
|
||||
"collections.copy_link_confirmation": "نسخ الرابط إلى الحافظة",
|
||||
"collections.create.basic_details_title": "المعلومات الأساسية",
|
||||
"collections.create.steps": "الخطوة {step}/{total}",
|
||||
"collections.detail.accounts_heading": "الحسابات",
|
||||
"collections.detail.revoke_inclusion": "أزلني",
|
||||
"collections.detail.sensitive_content": "محتوى حساس",
|
||||
"collections.edit_details": "تعديل التفاصيل",
|
||||
"collections.hints.accounts_counter": "{count}/{max} حسابات",
|
||||
"collections.manage_accounts": "إدارة الحسابات",
|
||||
"collections.remove_account": "إزالة",
|
||||
"collections.sensitive": "حساس",
|
||||
"collections.share_short": "مشاركة",
|
||||
"collections.visibility_public": "للعامة",
|
||||
"collections.visibility_title": "مدى الظهور",
|
||||
"collections.visibility_unlisted": "غير مُدرَج",
|
||||
"column.about": "عن",
|
||||
"column.blocks": "المُستَخدِمون المَحظورون",
|
||||
"column.bookmarks": "الفواصل المرجعية",
|
||||
@ -260,6 +344,7 @@
|
||||
"confirmations.delete.message": "هل أنتَ مُتأكدٌ أنك تُريدُ حَذفَ هذا المنشور؟",
|
||||
"confirmations.delete.title": "أتريد حذف المنشور؟",
|
||||
"confirmations.delete_collection.confirm": "حذف",
|
||||
"confirmations.delete_collection.title": "حذف \"{name}\"؟",
|
||||
"confirmations.delete_list.confirm": "حذف",
|
||||
"confirmations.delete_list.message": "هل أنتَ مُتأكدٌ أنكَ تُريدُ حَذفَ هذِهِ القائمة بشكلٍ دائم؟",
|
||||
"confirmations.delete_list.title": "أتريد حذف القائمة؟",
|
||||
@ -283,6 +368,9 @@
|
||||
"confirmations.missing_alt_text.secondary": "انشر على أي حال",
|
||||
"confirmations.missing_alt_text.title": "أضف نصًا بديلًا؟",
|
||||
"confirmations.mute.confirm": "أكتم",
|
||||
"confirmations.private_quote_notify.cancel": "العودة إلى التحرير",
|
||||
"confirmations.private_quote_notify.confirm": "نشر المنشور",
|
||||
"confirmations.private_quote_notify.do_not_show_again": "لا تظهر علي هذه الرسالة مجددًا",
|
||||
"confirmations.quiet_post_quote_info.dismiss": "لا تُذكرني مرة أخرى",
|
||||
"confirmations.quiet_post_quote_info.got_it": "مفهوم",
|
||||
"confirmations.quiet_post_quote_info.message": "عندما تقتبس منشورا هادئا للعامة، فإن منشورك سيكون أيضا مخفيا عن الخيوط الزمنية الرائجة.",
|
||||
@ -293,6 +381,7 @@
|
||||
"confirmations.remove_from_followers.confirm": "إزالة المتابع",
|
||||
"confirmations.remove_from_followers.message": "سيتوقف {name} عن متابعتك. هل بالتأكيد تريد المتابعة؟",
|
||||
"confirmations.remove_from_followers.title": "إزالة المتابع؟",
|
||||
"confirmations.revoke_collection_inclusion.confirm": "أزلني",
|
||||
"confirmations.revoke_quote.confirm": "إزالة المنشور",
|
||||
"confirmations.revoke_quote.message": "لا يمكن التراجع عن هذا الإجراء.",
|
||||
"confirmations.revoke_quote.title": "أتريد إزالة المنشور؟",
|
||||
@ -343,6 +432,8 @@
|
||||
"dropdown.empty": "حدد خيارا",
|
||||
"email_subscriptions.email": "البريد الإلكتروني",
|
||||
"email_subscriptions.form.action": "اشترك",
|
||||
"email_subscriptions.submitted.title": "خطوة واحدة أخرى",
|
||||
"email_subscriptions.validation.email.invalid": "عنوان البريد الإلكتروني غير صالح",
|
||||
"embed.instructions": "يمكنكم إدماج هذا المنشور على موقعكم الإلكتروني عن طريق نسخ الشفرة أدناه.",
|
||||
"embed.preview": "إليك ما سيبدو عليه:",
|
||||
"emoji_button.activity": "الأنشطة",
|
||||
@ -437,6 +528,7 @@
|
||||
"follow_suggestions.view_all": "عرض الكل",
|
||||
"follow_suggestions.who_to_follow": "حسابات للمُتابَعة",
|
||||
"followed_tags": "الوسوم المتابَعة",
|
||||
"following.title": "يتبعه {name}",
|
||||
"footer.about": "عن",
|
||||
"footer.about_mastodon": "عن ماستدون",
|
||||
"footer.about_server": "عن {domain}",
|
||||
@ -750,12 +842,14 @@
|
||||
"notifications_permission_banner.title": "لا تفوت شيئاً أبداً",
|
||||
"onboarding.follows.back": "عودة",
|
||||
"onboarding.follows.empty": "نأسف، لا يمكن عرض نتائج في الوقت الحالي. جرب البحث أو انتقل لصفحة الاستكشاف لإيجاد أشخاص للمتابعة، أو حاول مرة أخرى.",
|
||||
"onboarding.follows.next": "التالي: إعداد ملفك الشخصي",
|
||||
"onboarding.follows.search": "بحث",
|
||||
"onboarding.follows.title": "للبدء قم بمتابعة أشخاص",
|
||||
"onboarding.profile.discoverable": "اجعل ملفي الشخصي قابلاً للاكتشاف",
|
||||
"onboarding.profile.discoverable_hint": "عندما تختار تفعيل إمكانية الاكتشاف على ماستدون، قد تظهر منشوراتك في نتائج البحث والمواضيع الرائجة، وقد يتم اقتراح ملفك الشخصي لأشخاص ذوي اهتمامات مماثلة معك.",
|
||||
"onboarding.profile.display_name": "الاسم العلني",
|
||||
"onboarding.profile.display_name_hint": "اسمك الكامل أو اسمك المرح…",
|
||||
"onboarding.profile.finish": "إنهاء",
|
||||
"onboarding.profile.note": "نبذة عنك",
|
||||
"onboarding.profile.note_hint": "يمكنك @ذِكر أشخاص آخرين أو استعمال #الوسوم…",
|
||||
"onboarding.profile.title": "إعداد الملف الشخصي",
|
||||
@ -896,6 +990,7 @@
|
||||
"sign_in_banner.mastodon_is": "ماستودون هو أفضل وسيلة لمواكبة الأحداث.",
|
||||
"sign_in_banner.sign_in": "تسجيل الدخول",
|
||||
"sign_in_banner.sso_redirect": "تسجيل الدخول أو إنشاء حساب",
|
||||
"skip_links.skip_to_content": "تخطي إلى المحتوى الرئيسي",
|
||||
"status.admin_account": "افتح الواجهة الإدارية لـ @{name}",
|
||||
"status.admin_domain": "فتح واجهة الإشراف لـ {domain}",
|
||||
"status.admin_status": "افتح هذا المنشور على واجهة الإشراف",
|
||||
@ -905,6 +1000,10 @@
|
||||
"status.cancel_reblog_private": "إلغاء إعادة النشر",
|
||||
"status.cannot_quote": "غير مصرح لك باقتباس هذا المنشور",
|
||||
"status.cannot_reblog": "لا يمكن إعادة نشر هذا المنشور",
|
||||
"status.contains_quote": "يحتوي على اقتباس",
|
||||
"status.context.loading": "تحميل المزيد من الردود",
|
||||
"status.context.loading_success": "تم تحميل ردود جديدة",
|
||||
"status.context.more_replies_found": "تم العثور على المزيد من الردود",
|
||||
"status.context.retry": "حاول مجددًا",
|
||||
"status.context.show": "إظهار",
|
||||
"status.continued_thread": "تكملة للخيط",
|
||||
|
||||
@ -71,6 +71,8 @@
|
||||
"account.go_to_profile": "Перайсці да профілю",
|
||||
"account.hide_reblogs": "Схаваць пашырэнні ад @{name}",
|
||||
"account.in_memoriam": "У памяць.",
|
||||
"account.join_modal.me": "Вы далучыліся да {server}",
|
||||
"account.join_modal.years": "{number, plural, one {# год} few {# гады} many {# гадоў} other {# гады}}",
|
||||
"account.joined_short": "Далучыўся",
|
||||
"account.languages": "Змяніць выбраныя мовы",
|
||||
"account.last_active": "Апошняя актыўнасць",
|
||||
@ -398,6 +400,8 @@
|
||||
"collections.manage_accounts": "Кіраванне ўліковымі запісамі",
|
||||
"collections.mark_as_sensitive": "Пазначыць як адчувальную",
|
||||
"collections.mark_as_sensitive_hint": "Схаваць апісанне калекцыі і ўліковыя запісы за банерам з папярэджаннем. Назва калекцыі застанецца бачнай.",
|
||||
"collections.maximum_collection_count_description": "Ваш сервер дазваляе ствараць да {count} калекцый.",
|
||||
"collections.maximum_collection_count_reached": "Вы стварылі максімальную колькасць калекцый",
|
||||
"collections.name_length_hint": "Максімум 40 сімвалаў",
|
||||
"collections.new_collection": "Новая калекцыя",
|
||||
"collections.no_collections_yet": "Пакуль няма калекцый.",
|
||||
|
||||
@ -71,6 +71,16 @@
|
||||
"account.go_to_profile": "Gå til profil",
|
||||
"account.hide_reblogs": "Skjul fremhævelser fra @{name}",
|
||||
"account.in_memoriam": "Til minde om.",
|
||||
"account.join_modal.day": "Dag",
|
||||
"account.join_modal.me": "Du tilmeldte dig {server}",
|
||||
"account.join_modal.me_anniversary": "Tillykke med dit fedivers-jubilæum! Du tilmeldte dig {server}",
|
||||
"account.join_modal.me_today": "Det er din første dag på {server}!",
|
||||
"account.join_modal.other": "{name} tilmeldte sig {server}",
|
||||
"account.join_modal.other_today": "Det er {name}’s første dag på {server}!",
|
||||
"account.join_modal.share.celebrate": "Del et indlæg for at fejre begivenheden",
|
||||
"account.join_modal.share.intro": "Del et introindlæg",
|
||||
"account.join_modal.share.welcome": "Del et velkomstindlæg",
|
||||
"account.join_modal.years": "{number, plural, one {år} other {år}}",
|
||||
"account.joined_short": "Oprettet",
|
||||
"account.languages": "Skift abonnementssprog",
|
||||
"account.last_active": "Senest aktiv",
|
||||
@ -398,6 +408,8 @@
|
||||
"collections.manage_accounts": "Administrer konti",
|
||||
"collections.mark_as_sensitive": "Markér som sensitiv",
|
||||
"collections.mark_as_sensitive_hint": "Skjuler samlingens beskrivelse og konti bag en indholdsadvarsel. Samlingens navn vil stadig være synligt.",
|
||||
"collections.maximum_collection_count_description": "Din server tillader oprettelse af op til {count} samlinger.",
|
||||
"collections.maximum_collection_count_reached": "Du har oprettet det maksimale antal samlinger",
|
||||
"collections.name_length_hint": "Begrænset til 40 tegn",
|
||||
"collections.new_collection": "Ny samling",
|
||||
"collections.no_collections_yet": "Ingen samlinger endnu.",
|
||||
|
||||
@ -71,6 +71,16 @@
|
||||
"account.go_to_profile": "Profil aufrufen",
|
||||
"account.hide_reblogs": "Geteilte Beiträge von @{name} ausblenden",
|
||||
"account.in_memoriam": "Zum Andenken.",
|
||||
"account.join_modal.day": "Tag",
|
||||
"account.join_modal.me": "Du bist auf {server} dabei seit",
|
||||
"account.join_modal.me_anniversary": "Happy Fediversary! Du bist auf {server} dabei seit",
|
||||
"account.join_modal.me_today": "Dein erster Tag auf {server}!",
|
||||
"account.join_modal.other": "{name} ist auf {server} dabei seit",
|
||||
"account.join_modal.other_today": "{name} ist seit einem Tag auf {server}!",
|
||||
"account.join_modal.share.celebrate": "Teile die Feierlichkeit",
|
||||
"account.join_modal.share.intro": "Teile einen Einblick über dich",
|
||||
"account.join_modal.share.welcome": "Teile ein herzliches Willkommen",
|
||||
"account.join_modal.years": "{number, plural, one {Jahr} other {Jahre}}",
|
||||
"account.joined_short": "Dabei seit",
|
||||
"account.languages": "Sprachen verwalten",
|
||||
"account.last_active": "Zuletzt aktiv",
|
||||
@ -398,6 +408,8 @@
|
||||
"collections.manage_accounts": "Profile verwalten",
|
||||
"collections.mark_as_sensitive": "Mit Inhaltswarnung versehen",
|
||||
"collections.mark_as_sensitive_hint": "Die Beschreibung sowie enthaltenen Profile werden durch eine Inhaltswarnung ausgeblendet. Der Titel bleibt weiterhin sichtbar.",
|
||||
"collections.maximum_collection_count_description": "Auf deinem Server darfst du bis zu {count} Sammlungen erstellen.",
|
||||
"collections.maximum_collection_count_reached": "Du hast die Höchstzahl an Sammlungen erreicht",
|
||||
"collections.name_length_hint": "Maximal 40 Zeichen",
|
||||
"collections.new_collection": "Neue Sammlung",
|
||||
"collections.no_collections_yet": "Bisher keine Sammlungen vorhanden.",
|
||||
|
||||
@ -71,6 +71,16 @@
|
||||
"account.go_to_profile": "Μετάβαση στο προφίλ",
|
||||
"account.hide_reblogs": "Απόκρυψη ενισχύσεων από @{name}",
|
||||
"account.in_memoriam": "Εις μνήμην.",
|
||||
"account.join_modal.day": "Ημέρα",
|
||||
"account.join_modal.me": "Έγινες μέλος στο {server} στις",
|
||||
"account.join_modal.me_anniversary": "Ευτυχισμένο Fediversary! Έγινες μέλος στο {server} στις",
|
||||
"account.join_modal.me_today": "Είναι η πρώτη σου μέρα στο {server}!",
|
||||
"account.join_modal.other": "Ο/Η {name} έγινε μέλος στο {server} στις",
|
||||
"account.join_modal.other_today": "Είναι η πρώτη μέρα του/της {name} στο {server}!",
|
||||
"account.join_modal.share.celebrate": "Μοιράσου μια εορταστική ανάρτηση",
|
||||
"account.join_modal.share.intro": "Μοιράσου μια εισαγωγική ανάρτηση",
|
||||
"account.join_modal.share.welcome": "Μοιράσου μια ανάρτηση καλωσορίσματος",
|
||||
"account.join_modal.years": "{number, plural, one {χρόνος} other {χρόνια}}",
|
||||
"account.joined_short": "Έγινε μέλος",
|
||||
"account.languages": "Αλλαγή εγγεγραμμένων γλωσσών",
|
||||
"account.last_active": "Τελευταία ενεργός",
|
||||
@ -398,6 +408,8 @@
|
||||
"collections.manage_accounts": "Διαχείριση λογαριασμών",
|
||||
"collections.mark_as_sensitive": "Σήμανση ως ευαίσθητο",
|
||||
"collections.mark_as_sensitive_hint": "Κρύβει την περιγραφή και τους λογαριασμούς της συλλογής πίσω από μια προειδοποίηση περιεχομένου. Το όνομα της συλλογής θα είναι ακόμη ορατό.",
|
||||
"collections.maximum_collection_count_description": "Ο εξυπηρετητής σου επιτρέπει την δημιουργία μέχρι {count} συλλογών.",
|
||||
"collections.maximum_collection_count_reached": "Έχεις δημιουργήσει τον μέγιστο αριθμό συλλογών",
|
||||
"collections.name_length_hint": "Όριο 40 χαρακτήρων",
|
||||
"collections.new_collection": "Νέα συλλογή",
|
||||
"collections.no_collections_yet": "Καμία συλλογή ακόμη.",
|
||||
|
||||
@ -71,6 +71,16 @@
|
||||
"account.go_to_profile": "Go to profile",
|
||||
"account.hide_reblogs": "Hide boosts from @{name}",
|
||||
"account.in_memoriam": "In Memoriam.",
|
||||
"account.join_modal.day": "Day",
|
||||
"account.join_modal.me": "You joined {server} on",
|
||||
"account.join_modal.me_anniversary": "Happy Fediversary! You joined {server} on",
|
||||
"account.join_modal.me_today": "It’s your first day on {server}!",
|
||||
"account.join_modal.other": "{name} joined {server} on",
|
||||
"account.join_modal.other_today": "It’s {name}’s first day on {server}!",
|
||||
"account.join_modal.share.celebrate": "Share a celebratory post",
|
||||
"account.join_modal.share.intro": "Share an intro post",
|
||||
"account.join_modal.share.welcome": "Share a welcome post",
|
||||
"account.join_modal.years": "{number, plural, one {year} other {years}}",
|
||||
"account.joined_short": "Joined",
|
||||
"account.languages": "Change subscribed languages",
|
||||
"account.last_active": "Last active",
|
||||
@ -398,6 +408,8 @@
|
||||
"collections.manage_accounts": "Manage accounts",
|
||||
"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.maximum_collection_count_description": "Your server allows creation of up to {count} collections.",
|
||||
"collections.maximum_collection_count_reached": "You have created the maximum number of collections",
|
||||
"collections.name_length_hint": "40 characters limit",
|
||||
"collections.new_collection": "New collection",
|
||||
"collections.no_collections_yet": "No collections yet.",
|
||||
@ -1184,6 +1196,7 @@
|
||||
"server_banner.active_users": "active users",
|
||||
"server_banner.administered_by": "Administered by:",
|
||||
"server_banner.is_one_of_many": "{domain} is one of the many independent Mastodon servers you can use to participate in the fediverse.",
|
||||
"server_banner.more_about_this_server": "More about this server",
|
||||
"server_banner.server_stats": "Server stats:",
|
||||
"sign_in_banner.create_account": "Create account",
|
||||
"sign_in_banner.follow_anyone": "Follow anyone across the fediverse and see it all in chronological order. No algorithms, ads, or clickbait in sight.",
|
||||
|
||||
@ -71,6 +71,16 @@
|
||||
"account.go_to_profile": "Ir al perfil",
|
||||
"account.hide_reblogs": "Ocultar adhesiones de @{name}",
|
||||
"account.in_memoriam": "Cuenta conmemorativa.",
|
||||
"account.join_modal.day": "Día",
|
||||
"account.join_modal.me": "Te uniste a {server} el",
|
||||
"account.join_modal.me_anniversary": "¡Feliz Fediversario! Te uniste a {server} el",
|
||||
"account.join_modal.me_today": "¡Es tu primer día en {server}!",
|
||||
"account.join_modal.other": "{name} se unió a {server} el",
|
||||
"account.join_modal.other_today": "¡Es el primer día de {name} en {server}!",
|
||||
"account.join_modal.share.celebrate": "Compartí un mensaje conmemorativo",
|
||||
"account.join_modal.share.intro": "Compartí un mensaje introductorio",
|
||||
"account.join_modal.share.welcome": "Compartí un mensaje de bienvenida",
|
||||
"account.join_modal.years": "{number, plural, one {# año} other {# años}}",
|
||||
"account.joined_short": "En este servidor desde el",
|
||||
"account.languages": "Cambiar idiomas suscritos",
|
||||
"account.last_active": "Última actividad",
|
||||
@ -398,6 +408,8 @@
|
||||
"collections.manage_accounts": "Administrar cuentas",
|
||||
"collections.mark_as_sensitive": "Marcar como sensible",
|
||||
"collections.mark_as_sensitive_hint": "Oculta la descripción de la colección y las cuentas detrás de una advertencia de contenido. El nombre de la colección seguirá siendo visible.",
|
||||
"collections.maximum_collection_count_description": "Tu servidor permite creaciones de hasta {count} colecciones.",
|
||||
"collections.maximum_collection_count_reached": "Creaste el número máximo de colecciones",
|
||||
"collections.name_length_hint": "Límite de 40 caracteres",
|
||||
"collections.new_collection": "Nueva colección",
|
||||
"collections.no_collections_yet": "No hay colecciones aún.",
|
||||
|
||||
@ -71,6 +71,16 @@
|
||||
"account.go_to_profile": "Ir al perfil",
|
||||
"account.hide_reblogs": "Ocultar impulsos de @{name}",
|
||||
"account.in_memoriam": "En memoria.",
|
||||
"account.join_modal.day": "Día",
|
||||
"account.join_modal.me": "Te uniste a {server} el",
|
||||
"account.join_modal.me_anniversary": "¡Feliz Fediversario! Te uniste a {server} el",
|
||||
"account.join_modal.me_today": "¡Es tu primer día en {server}!",
|
||||
"account.join_modal.other": "{name} se unió a {server} el",
|
||||
"account.join_modal.other_today": "¡Es el primer día de {name} en {server}!",
|
||||
"account.join_modal.share.celebrate": "Compartir una publicación para celebrarlo",
|
||||
"account.join_modal.share.intro": "Compartir una publicación de presentación",
|
||||
"account.join_modal.share.welcome": "Compartir una publicación de bienvenida",
|
||||
"account.join_modal.years": "{number, plural, one {año} other {# años}}",
|
||||
"account.joined_short": "Se unió",
|
||||
"account.languages": "Cambiar idiomas suscritos",
|
||||
"account.last_active": "Última actividad",
|
||||
@ -398,6 +408,8 @@
|
||||
"collections.manage_accounts": "Administrar cuentas",
|
||||
"collections.mark_as_sensitive": "Marcar como sensible",
|
||||
"collections.mark_as_sensitive_hint": "Oculta la descripción y las cuentas de la colección detrás de una advertencia de contenido. El nombre de la colección seguirá siendo visible.",
|
||||
"collections.maximum_collection_count_description": "Tu servidor permite la creación de hasta {count} colecciones.",
|
||||
"collections.maximum_collection_count_reached": "Has creado el número máximo de colecciones",
|
||||
"collections.name_length_hint": "Limitado a 40 caracteres",
|
||||
"collections.new_collection": "Nueva colección",
|
||||
"collections.no_collections_yet": "No hay colecciones todavía.",
|
||||
|
||||
@ -71,6 +71,16 @@
|
||||
"account.go_to_profile": "Ir al perfil",
|
||||
"account.hide_reblogs": "Ocultar impulsos de @{name}",
|
||||
"account.in_memoriam": "Cuenta conmemorativa.",
|
||||
"account.join_modal.day": "Día",
|
||||
"account.join_modal.me": "Te uniste a {server} el",
|
||||
"account.join_modal.me_anniversary": "¡Feliz Fediversario! Te uniste a {server} el",
|
||||
"account.join_modal.me_today": "¡Es tu primer día en {server}!",
|
||||
"account.join_modal.other": "{name} se unió a {server} el",
|
||||
"account.join_modal.other_today": "¡Es el primer día de {name} en {server}!",
|
||||
"account.join_modal.share.celebrate": "Compartir una publicación para celebrarlo",
|
||||
"account.join_modal.share.intro": "Compartir una publicación de presentación",
|
||||
"account.join_modal.share.welcome": "Compartir una publicación de bienvenida",
|
||||
"account.join_modal.years": "{number, plural, one {año} other {# años}}",
|
||||
"account.joined_short": "Se unió",
|
||||
"account.languages": "Cambiar idiomas suscritos",
|
||||
"account.last_active": "Última actividad",
|
||||
@ -398,6 +408,8 @@
|
||||
"collections.manage_accounts": "Administrar cuentas",
|
||||
"collections.mark_as_sensitive": "Marcar como sensible",
|
||||
"collections.mark_as_sensitive_hint": "Oculta la descripción de la colección y las cuentas detrás de una advertencia de contenido. El nombre de la colección seguirá siendo visible.",
|
||||
"collections.maximum_collection_count_description": "Tu servidor permite la creación de hasta {count} colecciones.",
|
||||
"collections.maximum_collection_count_reached": "Has creado el número máximo de colecciones",
|
||||
"collections.name_length_hint": "Límite de 40 caracteres",
|
||||
"collections.new_collection": "Nueva colección",
|
||||
"collections.no_collections_yet": "Aún no hay colecciones.",
|
||||
|
||||
@ -71,6 +71,10 @@
|
||||
"account.go_to_profile": "Vaata profiili",
|
||||
"account.hide_reblogs": "Peida @{name} jagamised",
|
||||
"account.in_memoriam": "In Memoriam.",
|
||||
"account.join_modal.day": "Päev",
|
||||
"account.join_modal.me": "Ühinesid {server} kohas",
|
||||
"account.join_modal.me_anniversary": "Rõõmsat Födiversumist! Ühinesid {server} kohas",
|
||||
"account.join_modal.me_today": "See on sinu esimene päev kohas {server}!",
|
||||
"account.joined_short": "Liitus",
|
||||
"account.languages": "Muuda tellitud keeli",
|
||||
"account.last_active": "Viimati aktiivne",
|
||||
|
||||
@ -71,6 +71,16 @@
|
||||
"account.go_to_profile": "Siirry profiiliin",
|
||||
"account.hide_reblogs": "Piilota käyttäjän @{name} tehostukset",
|
||||
"account.in_memoriam": "Muistoissamme.",
|
||||
"account.join_modal.day": "päivä",
|
||||
"account.join_modal.me": "Liityit palvelimelle {server}",
|
||||
"account.join_modal.me_anniversary": "Hyvää fediversumin vuosipäivää! Liityit palvelimelle {server}",
|
||||
"account.join_modal.me_today": "On ensimmäinen päiväsi palvelimella {server}!",
|
||||
"account.join_modal.other": "{name} liittyi palvelimelle {server}",
|
||||
"account.join_modal.other_today": "On käyttäjän {name} ensimmäinen päivä palvelimella {server}!",
|
||||
"account.join_modal.share.celebrate": "Jaa juhlajulkaisu",
|
||||
"account.join_modal.share.intro": "Jaa esittelyjulkaisu",
|
||||
"account.join_modal.share.welcome": "Jaa tervetulojulkaisu",
|
||||
"account.join_modal.years": "{number, plural, one {vuosi} other {vuotta}}",
|
||||
"account.joined_short": "Liittynyt",
|
||||
"account.languages": "Vaihda tilattuja kieliä",
|
||||
"account.last_active": "Viimeksi aktiivisena",
|
||||
@ -398,6 +408,8 @@
|
||||
"collections.manage_accounts": "Hallitse tilejä",
|
||||
"collections.mark_as_sensitive": "Merkitse arkaluonteiseksi",
|
||||
"collections.mark_as_sensitive_hint": "Piilottaa kokoelman kuvauksen ja tilit sisältövaroituksen taakse. Kokoelman nimi jää esiin.",
|
||||
"collections.maximum_collection_count_description": "Palvelimesi sallii enintään {count} kokoelman luomisen.",
|
||||
"collections.maximum_collection_count_reached": "Olet luonut enimmäismäärän kokoelmia",
|
||||
"collections.name_length_hint": "40 merkin rajoitus",
|
||||
"collections.new_collection": "Uusi kokoelma",
|
||||
"collections.no_collections_yet": "Ei vielä kokoelmia.",
|
||||
|
||||
@ -327,8 +327,8 @@
|
||||
"block_modal.title": "Bloquer l'utilisateur·ice ?",
|
||||
"block_modal.you_wont_see_mentions": "Vous ne verrez plus les messages qui le ou la mentionnent.",
|
||||
"boost_modal.combo": "Vous pouvez appuyer sur {combo} pour sauter ceci la prochaine fois",
|
||||
"boost_modal.reblog": "Booster le message ?",
|
||||
"boost_modal.undo_reblog": "Annuler le boost du message ?",
|
||||
"boost_modal.reblog": "Partager le message ?",
|
||||
"boost_modal.undo_reblog": "Annuler le partage du message ?",
|
||||
"bundle_column_error.copy_stacktrace": "Copier le rapport d'erreur",
|
||||
"bundle_column_error.error.body": "La page demandée n'a pas pu être affichée. Cela pourrait être dû à un bogue dans notre code, ou à un problème de compatibilité avec le navigateur.",
|
||||
"bundle_column_error.error.title": "Oh non!",
|
||||
@ -343,7 +343,7 @@
|
||||
"bundle_modal_error.retry": "Réessayer",
|
||||
"callout.dismiss": "Rejeter",
|
||||
"carousel.current": "<sr>Diapositive</sr> {current, number} / {max, number}",
|
||||
"carousel.slide": "Diapositive {current, number} de {max, number}",
|
||||
"carousel.slide": "Diapositive {current, number} sur {max, number}",
|
||||
"character_counter.recommended": "{currentLength}/{maxLength} caractères recommandés",
|
||||
"character_counter.required": "{currentLength}/{maxLength} caractères",
|
||||
"closed_registrations.other_server_instructions": "Puisque Mastodon est décentralisé, vous pouvez créer un compte sur un autre serveur et interagir quand même avec celui-ci.",
|
||||
@ -949,7 +949,7 @@
|
||||
"notification.poll": "Un sondage auquel vous avez participé vient de se terminer",
|
||||
"notification.quoted_update": "{name} a modifié un message que vous avez cité",
|
||||
"notification.reblog": "{name} a boosté votre message",
|
||||
"notification.reblog.name_and_others_with_link": "{name} et <a>{count, plural, one {# autre} other {# autres}}</a> ont boosté votre message",
|
||||
"notification.reblog.name_and_others_with_link": "{name} et <a>{count, plural, one {# autre} other {# autres}}</a> ont partagé votre message",
|
||||
"notification.relationships_severance_event": "Connexions perdues avec {name}",
|
||||
"notification.relationships_severance_event.account_suspension": "Un·e administrateur·rice de {from} a suspendu {target}, ce qui signifie que vous ne pourrez plus recevoir de mises à jour ou interagir avec lui.",
|
||||
"notification.relationships_severance_event.domain_block": "Un·e administrateur·rice de {from} en a bloqué {target}, comprenant {followersCount} de vos abonné·e·s et {followingCount, plural, one {# compte} other {# comptes}} vous suivez.",
|
||||
|
||||
@ -327,8 +327,8 @@
|
||||
"block_modal.title": "Bloquer l'utilisateur·ice ?",
|
||||
"block_modal.you_wont_see_mentions": "Vous ne verrez plus les messages qui le ou la mentionnent.",
|
||||
"boost_modal.combo": "Vous pouvez appuyer sur {combo} pour passer ceci la prochaine fois",
|
||||
"boost_modal.reblog": "Booster le message ?",
|
||||
"boost_modal.undo_reblog": "Annuler le boost du message ?",
|
||||
"boost_modal.reblog": "Partager le message ?",
|
||||
"boost_modal.undo_reblog": "Annuler le partage du message ?",
|
||||
"bundle_column_error.copy_stacktrace": "Copier le rapport d'erreur",
|
||||
"bundle_column_error.error.body": "La page demandée n'a pas pu être affichée. Cela peut être dû à un bogue dans notre code, ou à un problème de compatibilité avec le navigateur.",
|
||||
"bundle_column_error.error.title": "Oh non !",
|
||||
@ -343,7 +343,7 @@
|
||||
"bundle_modal_error.retry": "Réessayer",
|
||||
"callout.dismiss": "Rejeter",
|
||||
"carousel.current": "<sr>Diapositive</sr> {current, number} / {max, number}",
|
||||
"carousel.slide": "Diapositive {current, number} de {max, number}",
|
||||
"carousel.slide": "Diapositive {current, number} sur {max, number}",
|
||||
"character_counter.recommended": "{currentLength}/{maxLength} caractères recommandés",
|
||||
"character_counter.required": "{currentLength}/{maxLength} caractères",
|
||||
"closed_registrations.other_server_instructions": "Puisque Mastodon est décentralisé, vous pouvez créer un compte sur un autre serveur et interagir quand même avec celui-ci.",
|
||||
@ -949,7 +949,7 @@
|
||||
"notification.poll": "Un sondage auquel vous avez participé vient de se terminer",
|
||||
"notification.quoted_update": "{name} a modifié un message que vous avez cité",
|
||||
"notification.reblog": "{name} a partagé votre message",
|
||||
"notification.reblog.name_and_others_with_link": "{name} et <a>{count, plural, one {# autre} other {# autres}}</a> ont boosté votre message",
|
||||
"notification.reblog.name_and_others_with_link": "{name} et <a>{count, plural, one {# autre} other {# autres}}</a> ont partagé votre message",
|
||||
"notification.relationships_severance_event": "Connexions perdues avec {name}",
|
||||
"notification.relationships_severance_event.account_suspension": "Un·e administrateur·rice de {from} a suspendu {target}, ce qui signifie que vous ne pourrez plus recevoir de mises à jour ou interagir avec lui.",
|
||||
"notification.relationships_severance_event.domain_block": "Un·e administrateur·rice de {from} en a bloqué {target}, comprenant {followersCount} de vos abonné·e·s et {followingCount, plural, one {# compte} other {# comptes}} vous suivez.",
|
||||
|
||||
@ -71,6 +71,16 @@
|
||||
"account.go_to_profile": "Téigh go dtí próifíl",
|
||||
"account.hide_reblogs": "Folaigh moltaí ó @{name}",
|
||||
"account.in_memoriam": "Ón tseanaimsir.",
|
||||
"account.join_modal.day": "Lá",
|
||||
"account.join_modal.me": "Chuaigh tú isteach i {server} ar",
|
||||
"account.join_modal.me_anniversary": "Lá Féile sona duit! Chuaigh tú isteach i {server} ar",
|
||||
"account.join_modal.me_today": "Seo é do chéad lá ar {server}!",
|
||||
"account.join_modal.other": "Chuaigh {name} isteach i {server} ar",
|
||||
"account.join_modal.other_today": "Seo é an chéad lá ag {name} ar {server}!",
|
||||
"account.join_modal.share.celebrate": "Roinn post ceiliúrtha",
|
||||
"account.join_modal.share.intro": "Comhroinn post réamhrá",
|
||||
"account.join_modal.share.welcome": "Roinn post fáilte",
|
||||
"account.join_modal.years": "{number, plural, one {bliain} two {blianta} few {blianta} many {blianta} other {blianta}}",
|
||||
"account.joined_short": "Cláraithe",
|
||||
"account.languages": "Athraigh teangacha foscríofa",
|
||||
"account.last_active": "Gníomhach deireanach",
|
||||
@ -398,6 +408,8 @@
|
||||
"collections.manage_accounts": "Bainistigh cuntais",
|
||||
"collections.mark_as_sensitive": "Marcáil mar íogair",
|
||||
"collections.mark_as_sensitive_hint": "Folaíonn sé cur síos agus cuntais an bhailiúcháin taobh thiar de rabhadh ábhair. Beidh ainm an bhailiúcháin le feiceáil fós.",
|
||||
"collections.maximum_collection_count_description": "Ceadaíonn do fhreastalaí cruthú suas le {count} bailiúchán.",
|
||||
"collections.maximum_collection_count_reached": "Tá an líon uasta bailiúcháin cruthaithe agat",
|
||||
"collections.name_length_hint": "Teorainn 40 carachtar",
|
||||
"collections.new_collection": "Bailiúchán nua",
|
||||
"collections.no_collections_yet": "Gan aon bhailiúcháin fós.",
|
||||
|
||||
@ -71,6 +71,16 @@
|
||||
"account.go_to_profile": "Ir ao perfil",
|
||||
"account.hide_reblogs": "Agochar promocións de @{name}",
|
||||
"account.in_memoriam": "Lembranzas.",
|
||||
"account.join_modal.day": "Día",
|
||||
"account.join_modal.me": "Unícheste a {server} o",
|
||||
"account.join_modal.me_anniversary": "Feliz Fediversario! Chegaches a {server} o",
|
||||
"account.join_modal.me_today": "É o teu primeiro día en {server}!",
|
||||
"account.join_modal.other": "{name} uníuse a {server} o",
|
||||
"account.join_modal.other_today": "É o primeiro día de {name} en {server}!",
|
||||
"account.join_modal.share.celebrate": "Comparte unha mensaxe de celebración",
|
||||
"account.join_modal.share.intro": "Comparte unha mensaxe de presentación",
|
||||
"account.join_modal.share.welcome": "Comparte unha mensaxe de benvida",
|
||||
"account.join_modal.years": "{number, plural, one {ano} other {anos}}",
|
||||
"account.joined_short": "Uniuse",
|
||||
"account.languages": "Modificar os idiomas subscritos",
|
||||
"account.last_active": "Última actividade",
|
||||
@ -398,6 +408,8 @@
|
||||
"collections.manage_accounts": "Xestionar contas",
|
||||
"collections.mark_as_sensitive": "Marcar como sensible",
|
||||
"collections.mark_as_sensitive_hint": "Oculta a descrición e contas da colección detrás dun aviso sobre o contido. O nome da colección permanece visible.",
|
||||
"collections.maximum_collection_count_description": "O teu servidor permíteche crear ata {count} coleccións.",
|
||||
"collections.maximum_collection_count_reached": "Creaches o número máximo de coleccións",
|
||||
"collections.name_length_hint": "Límite de 40 caracteres",
|
||||
"collections.new_collection": "Nova colección",
|
||||
"collections.no_collections_yet": "Aínda non tes coleccións.",
|
||||
@ -410,6 +422,10 @@
|
||||
"collections.search_accounts_max_reached": "Acadaches o máximo de contas permitidas",
|
||||
"collections.sensitive": "Sensible",
|
||||
"collections.share_short": "Compartir",
|
||||
"collections.suggestions.can_not_add": "Non se pode engadir",
|
||||
"collections.suggestions.can_not_add_desc": "Estas contas optaron por poder ser engadidas, ou pode que estean nun servidor que aínda non é compatible coas coleccións.",
|
||||
"collections.suggestions.must_follow": "Primeiro tes que seguila",
|
||||
"collections.suggestions.must_follow_desc": "Estas contas revisan todas as solicitudes de seguimento. As seguidoras poden engadilas a coleccións.",
|
||||
"collections.topic_hint": "Engadir un cancelo para que axudar a que outras persoas coñezan a temática desta colección.",
|
||||
"collections.topic_special_chars_hint": "Vanse eliminar os caracteres especiais ao gardar",
|
||||
"collections.unlisted_collections_description": "Estas non se mostran no teu perfil, pero calquera que coñeza a ligazón pode velas.",
|
||||
|
||||
@ -71,6 +71,16 @@
|
||||
"account.go_to_profile": "Fara í notandasnið",
|
||||
"account.hide_reblogs": "Fela endurbirtingar fyrir @{name}",
|
||||
"account.in_memoriam": "Minning.",
|
||||
"account.join_modal.day": "daginn",
|
||||
"account.join_modal.me": "Þú skráðir þig á {server} þann",
|
||||
"account.join_modal.me_anniversary": "Til hamingju með daginn! Þú skráðir þig á {server} þann",
|
||||
"account.join_modal.me_today": "Þetta er fyrsti dagurinn þinn á {server}!",
|
||||
"account.join_modal.other": "{name} skráði sig á {server} þann",
|
||||
"account.join_modal.other_today": "Þetta er fyrsti dagurinn hjá {name} á {server}!",
|
||||
"account.join_modal.share.celebrate": "Deila fagnaðarfærslu",
|
||||
"account.join_modal.share.intro": "Deila kynningarfærslu",
|
||||
"account.join_modal.share.welcome": "Deila móttökufærslu",
|
||||
"account.join_modal.years": "{number, plural, one {ár} other {ár}}",
|
||||
"account.joined_short": "Gerðist þátttakandi",
|
||||
"account.languages": "Breyta tungumálum í áskrift",
|
||||
"account.last_active": "Síðasta virkni",
|
||||
@ -398,6 +408,8 @@
|
||||
"collections.manage_accounts": "Sýsla með notandaaðganga",
|
||||
"collections.mark_as_sensitive": "Merkja sem viðkvæmt",
|
||||
"collections.mark_as_sensitive_hint": "Felur lýsingu safnsins og notendur á bakvið aðvörun vegna efnis. Nafn safnsins verður áfram sýnilegt.",
|
||||
"collections.maximum_collection_count_description": "Netþjónninn þinn leyfir gerð á allt að {count} söfnum.",
|
||||
"collections.maximum_collection_count_reached": "Þú hefur útbúið leyfilegan hámarksfjölda safna",
|
||||
"collections.name_length_hint": "40 stafa takmörk",
|
||||
"collections.new_collection": "Nýtt safn",
|
||||
"collections.no_collections_yet": "Engin söfn ennþá.",
|
||||
|
||||
@ -71,6 +71,16 @@
|
||||
"account.go_to_profile": "Vai al profilo",
|
||||
"account.hide_reblogs": "Nascondi condivisioni da @{name}",
|
||||
"account.in_memoriam": "In memoria.",
|
||||
"account.join_modal.day": "Giorno",
|
||||
"account.join_modal.me": "Ti sei iscritto/a su {server} il",
|
||||
"account.join_modal.me_anniversary": "Buon Fediversario! Ti sei iscritto/a su {server} il",
|
||||
"account.join_modal.me_today": "È il tuo primo giorno su {server}!",
|
||||
"account.join_modal.other": "{name} si è iscritto/a su {server} il",
|
||||
"account.join_modal.other_today": "È il primo giorno di {name} su {server}!",
|
||||
"account.join_modal.share.celebrate": "Condividi un post celebrativo",
|
||||
"account.join_modal.share.intro": "Condividi un post introduttivo",
|
||||
"account.join_modal.share.welcome": "Condividi un post di benvenuto",
|
||||
"account.join_modal.years": "{number, plural, one {anno} other {anni}}",
|
||||
"account.joined_short": "Iscritto",
|
||||
"account.languages": "Modifica le lingue d'iscrizione",
|
||||
"account.last_active": "Ultima attività",
|
||||
@ -398,6 +408,8 @@
|
||||
"collections.manage_accounts": "Gestisci account",
|
||||
"collections.mark_as_sensitive": "Segna come sensibile",
|
||||
"collections.mark_as_sensitive_hint": "Nasconde la descrizione e gli account della collezione dietro un avviso di contenuto. Il nome della collezione rimarrà visibile.",
|
||||
"collections.maximum_collection_count_description": "Il tuo server consente la creazione di un massimo di {count} collezioni.",
|
||||
"collections.maximum_collection_count_reached": "Hai creato il numero massimo di collezioni",
|
||||
"collections.name_length_hint": "Limite di 40 caratteri",
|
||||
"collections.new_collection": "Nuova collezione",
|
||||
"collections.no_collections_yet": "Nessuna collezione ancora.",
|
||||
|
||||
@ -231,6 +231,7 @@
|
||||
"bundle_column_error.routing.title": "404",
|
||||
"bundle_modal_error.close": "Mdel",
|
||||
"bundle_modal_error.retry": "Ɛreḍ tikelt-nniḍen",
|
||||
"callout.dismiss": "Zgel-it",
|
||||
"closed_registrations_modal.description": "Asnulfu n umiḍan deg {domain} mačči d ayen izemren ad yili, maca ttxil-k·m, err deg lbal-ik·im belli ur teḥwaǧeḍ ara amiḍan s wudem ibanen ɣef {domain} akken ad tesqedceḍ Mastodon.",
|
||||
"closed_registrations_modal.find_another_server": "Aff-d aqeddac nniḍen",
|
||||
"closed_registrations_modal.title": "Ajerred deg Masṭudun",
|
||||
@ -241,6 +242,7 @@
|
||||
"collection.share_modal.title_new": "Zuzer talkensit-ik·im tamaynut!",
|
||||
"collections.account_count": "{count, plural, one {# n umiḍan} other {# n imiḍanen}}",
|
||||
"collections.accounts.empty_title": "Talkensit-a d tilemt",
|
||||
"collections.block_collection_owner": "Sewḥel amiḍan",
|
||||
"collections.by_account": "sɣur {account_handle}",
|
||||
"collections.collection_description": "Aglam",
|
||||
"collections.collection_language": "Tutlayt",
|
||||
@ -248,6 +250,7 @@
|
||||
"collections.collection_name": "Isem",
|
||||
"collections.collection_topic": "Asentel",
|
||||
"collections.continue": "Kemmel",
|
||||
"collections.copy_link": "Nɣel aseɣwen",
|
||||
"collections.create.steps": "Asurif wis {step}/{total}",
|
||||
"collections.create_collection": "Snulfu-d talkensit",
|
||||
"collections.delete_collection": "Kkes talkensit",
|
||||
@ -259,12 +262,16 @@
|
||||
"collections.detail.sensitive_content": "Agbur amḥulfu",
|
||||
"collections.detail.share": "Zuzer talkensit-a",
|
||||
"collections.edit_details": "Ẓreg talqayt",
|
||||
"collections.hidden_accounts_link": "{count, plural, one {# n umiḍan uffir} other {# n imiḍanen yettwaffaren}}",
|
||||
"collections.hints.accounts_counter": "{count}/{max} n imiḍanen",
|
||||
"collections.manage_accounts": "Sefrek imiḍanen",
|
||||
"collections.name_length_hint": "talast n 40 n yisekkilen",
|
||||
"collections.new_collection": "Talkensit tamaynut",
|
||||
"collections.no_collections_yet": "Ur ɛad llant tilkensa.",
|
||||
"collections.remove_account": "Kkes",
|
||||
"collections.report_collection": "Cetki ɣef telkensit-a",
|
||||
"collections.revoke_collection_inclusion": "Kkes-iyi seg telkensit-a",
|
||||
"collections.share_short": "Bḍu",
|
||||
"collections.view_collection": "Wali talkensit",
|
||||
"collections.visibility_public": "Azayaz",
|
||||
"collections.visibility_title": "Abani",
|
||||
|
||||
@ -71,6 +71,16 @@
|
||||
"account.go_to_profile": "Profile git",
|
||||
"account.hide_reblogs": "@{name} kişisinin yeniden paylaşımlarını gizle",
|
||||
"account.in_memoriam": "Hatırasına.",
|
||||
"account.join_modal.day": "Gün",
|
||||
"account.join_modal.me": "{server} sunucusuna katıldığınız tarih",
|
||||
"account.join_modal.me_anniversary": "Fediversary kutlu olsun! {server} sunucusuna katıldığınız tarih",
|
||||
"account.join_modal.me_today": "{server} sunucusunda ilk gününüz!",
|
||||
"account.join_modal.other": "{name}, {server} sunucusuna katıldığı tarih",
|
||||
"account.join_modal.other_today": "{name} kişisinin {server} sunucusunda ilk günü!",
|
||||
"account.join_modal.share.celebrate": "Kutlama amaçlı bir paylaşım yapın",
|
||||
"account.join_modal.share.intro": "Tanıtım için bir paylaşım yapın",
|
||||
"account.join_modal.share.welcome": "Bir hoşgeldiniz paylaşımı yapın",
|
||||
"account.join_modal.years": "{number, plural, one {yıl} other {yıl}}",
|
||||
"account.joined_short": "Katıldı",
|
||||
"account.languages": "Abone olunan dilleri değiştir",
|
||||
"account.last_active": "Son etkin",
|
||||
@ -398,6 +408,8 @@
|
||||
"collections.manage_accounts": "Hesapları yönet",
|
||||
"collections.mark_as_sensitive": "Hassas olarak işaretle",
|
||||
"collections.mark_as_sensitive_hint": "Koleksiyonun açıklamasını ve hesaplarını içerik uyarısının arkasında gizler. Koleksiyon adı hala görünür olacaktır.",
|
||||
"collections.maximum_collection_count_description": "Sunucusunuz en fazla {count} koleksiyon oluşturmanıza izin veriyor.",
|
||||
"collections.maximum_collection_count_reached": "Maksimum koleksiyon sayısına ulaştınız",
|
||||
"collections.name_length_hint": "40 karakterle sınırlı",
|
||||
"collections.new_collection": "Yeni koleksiyon",
|
||||
"collections.no_collections_yet": "Henüz hiçbir koleksiyon yok.",
|
||||
|
||||
@ -71,6 +71,16 @@
|
||||
"account.go_to_profile": "Xem hồ sơ",
|
||||
"account.hide_reblogs": "Ẩn tút @{name} đăng lại",
|
||||
"account.in_memoriam": "Tưởng Niệm.",
|
||||
"account.join_modal.day": "Ngày",
|
||||
"account.join_modal.me": "Bạn đã tham gia {server} vào",
|
||||
"account.join_modal.me_anniversary": "Happy Fediversary! Bạn đã tham gia {server} vào",
|
||||
"account.join_modal.me_today": "Đó là ngày đầu tiên của bạn trên {server}!",
|
||||
"account.join_modal.other": "{name} đã tham gia {server} vào",
|
||||
"account.join_modal.other_today": "Đó là ngày đầu tiên của {name} trên {server}!",
|
||||
"account.join_modal.share.celebrate": "Chia sẻ một tút kỷ niệm",
|
||||
"account.join_modal.share.intro": "Chia sẻ một tút giới thiệu",
|
||||
"account.join_modal.share.welcome": "Chia sẻ một tút chào mừng",
|
||||
"account.join_modal.years": "{number, plural, other {năm}}",
|
||||
"account.joined_short": "Năm",
|
||||
"account.languages": "Đổi ngôn ngữ mong muốn",
|
||||
"account.last_active": "Hoạt động lần cuối",
|
||||
@ -398,6 +408,8 @@
|
||||
"collections.manage_accounts": "Quản lý tài khoản",
|
||||
"collections.mark_as_sensitive": "Đánh dấu nhạy cảm",
|
||||
"collections.mark_as_sensitive_hint": "Ẩn phần mô tả và các tài khoản của gói khởi đầu phía sau cảnh báo nội dung. Tên gói khởi đầu vẫn hiển thị.",
|
||||
"collections.maximum_collection_count_description": "Máy chủ của bạn cho phép tạo tối đa {count} gói khởi đầu.",
|
||||
"collections.maximum_collection_count_reached": "Bạn đã đạt đến số lượng gói khởi đầu tối đa",
|
||||
"collections.name_length_hint": "Giới hạn 40 ký tự",
|
||||
"collections.new_collection": "Gói khởi đầu mới",
|
||||
"collections.no_collections_yet": "Chưa có gói khởi đầu.",
|
||||
|
||||
@ -71,6 +71,16 @@
|
||||
"account.go_to_profile": "前往个人资料页",
|
||||
"account.hide_reblogs": "隐藏来自 @{name} 的转嘟",
|
||||
"account.in_memoriam": "谨此悼念。",
|
||||
"account.join_modal.day": "天",
|
||||
"account.join_modal.me": "你加入 {server} 的时间为",
|
||||
"account.join_modal.me_anniversary": "加入 Mastodon 一周年快乐!你加入 {server} 的时间为",
|
||||
"account.join_modal.me_today": "这是你加入 {server} 的第一天!",
|
||||
"account.join_modal.other": "{name} 加入 {server} 的时间为",
|
||||
"account.join_modal.other_today": "这是 {name} 加入 {server} 的第一天!",
|
||||
"account.join_modal.share.celebrate": "分享纪念嘟文",
|
||||
"account.join_modal.share.intro": "分享介绍嘟文",
|
||||
"account.join_modal.share.welcome": "分享欢迎嘟文",
|
||||
"account.join_modal.years": "{number, plural, other {年}}",
|
||||
"account.joined_short": "加入于",
|
||||
"account.languages": "更改订阅语言",
|
||||
"account.last_active": "上次活跃",
|
||||
@ -398,6 +408,8 @@
|
||||
"collections.manage_accounts": "管理账号",
|
||||
"collections.mark_as_sensitive": "标记为敏感内容",
|
||||
"collections.mark_as_sensitive_hint": "将此收藏列表的说明用内容警告隐藏。此收藏列表的名称仍将可见。",
|
||||
"collections.maximum_collection_count_description": "你的服务器最多只支持创建 {count} 个收藏列表。",
|
||||
"collections.maximum_collection_count_reached": "你创建的收藏列表数量已达上限",
|
||||
"collections.name_length_hint": "40 字限制",
|
||||
"collections.new_collection": "新建收藏列表",
|
||||
"collections.no_collections_yet": "尚无收藏列表。",
|
||||
|
||||
@ -71,6 +71,16 @@
|
||||
"account.go_to_profile": "前往個人檔案",
|
||||
"account.hide_reblogs": "隱藏來自 @{name} 之轉嘟",
|
||||
"account.in_memoriam": "謹此悼念。",
|
||||
"account.join_modal.day": "日",
|
||||
"account.join_modal.me": "您加入 {server} 的時間為",
|
||||
"account.join_modal.me_anniversary": "聯邦宇宙週年快了!您加入 {server} 的時間為",
|
||||
"account.join_modal.me_today": "這是您在 {server} 的第一天!",
|
||||
"account.join_modal.other": "{name} 加入 {server} 的時間為",
|
||||
"account.join_modal.other_today": "這是 {name} 在 {server} 的第一天!",
|
||||
"account.join_modal.share.celebrate": "分享慶祝嘟文",
|
||||
"account.join_modal.share.intro": "分享介紹嘟文",
|
||||
"account.join_modal.share.welcome": "分享歡迎嘟文",
|
||||
"account.join_modal.years": "{number, plural, other {年}}",
|
||||
"account.joined_short": "加入時間",
|
||||
"account.languages": "變更訂閱的語言",
|
||||
"account.last_active": "上次活躍時間",
|
||||
|
||||
@ -1,5 +1,6 @@
|
||||
import type { RecordOf } from 'immutable';
|
||||
|
||||
import type { ApiCollectionJSON } from 'mastodon/api_types/collections';
|
||||
import type { ApiPreviewCardJSON } from 'mastodon/api_types/statuses';
|
||||
|
||||
export type { StatusVisibility } from 'mastodon/api_types/statuses';
|
||||
@ -10,3 +11,5 @@ export type Status = Immutable.Map<string, unknown>;
|
||||
export type Card = RecordOf<ApiPreviewCardJSON>;
|
||||
|
||||
export type MediaAttachment = Immutable.Map<string, unknown>;
|
||||
|
||||
export type CollectionAttachment = RecordOf<ApiCollectionJSON>;
|
||||
|
||||
@ -610,7 +610,10 @@ export const composeReducer = (state = initialState, action) => {
|
||||
case COMPOSE_LANGUAGE_CHANGE:
|
||||
return state.set('language', action.language);
|
||||
case COMPOSE_FOCUS:
|
||||
return state.set('focusDate', new Date()).update('text', text => text.length > 0 ? text : action.defaultText);
|
||||
return state
|
||||
.set('focusDate', new Date())
|
||||
.update('text', text => text.length > 0 ? text : action.defaultText)
|
||||
.update('caretPosition', position => action.caretStart ? 0 : position);
|
||||
case COMPOSE_CHANGE_MEDIA_ORDER:
|
||||
return state.update('media_attachments', list => {
|
||||
const indexA = list.findIndex(x => x.get('id') === action.a);
|
||||
|
||||
14
app/javascript/mastodon/utils/compare_urls.ts
Normal file
14
app/javascript/mastodon/utils/compare_urls.ts
Normal file
@ -0,0 +1,14 @@
|
||||
export function compareUrls(href1: string, href2: string) {
|
||||
try {
|
||||
const url1 = new URL(href1);
|
||||
const url2 = new URL(href2);
|
||||
|
||||
return (
|
||||
url1.origin === url2.origin &&
|
||||
url1.pathname === url2.pathname &&
|
||||
url1.search === url2.search
|
||||
);
|
||||
} catch {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
@ -1499,8 +1499,9 @@ body > [data-popper-placement] {
|
||||
.media-gallery,
|
||||
.video-player,
|
||||
.audio-player,
|
||||
.attachment-list {
|
||||
margin-top: 16px;
|
||||
.attachment-list,
|
||||
.collection-preview {
|
||||
margin-top: 14px;
|
||||
}
|
||||
|
||||
&--in-thread {
|
||||
@ -1517,6 +1518,7 @@ body > [data-popper-placement] {
|
||||
& > .picture-in-picture-placeholder,
|
||||
& > .more-from-author,
|
||||
& > .status-card,
|
||||
& > .collection-preview,
|
||||
& > .hashtag-bar,
|
||||
& > .content-warning,
|
||||
& > .filter-warning,
|
||||
@ -1787,7 +1789,8 @@ body > [data-popper-placement] {
|
||||
|
||||
.media-gallery,
|
||||
.video-player,
|
||||
.audio-player {
|
||||
.audio-player,
|
||||
.collection-preview {
|
||||
margin-top: 16px;
|
||||
}
|
||||
|
||||
@ -6367,7 +6370,7 @@ a.status-card {
|
||||
|
||||
&__top {
|
||||
border-radius: 16px 16px 0 0;
|
||||
border-bottom: 0;
|
||||
border-bottom-width: 0;
|
||||
gap: 16px;
|
||||
}
|
||||
|
||||
|
||||
@ -32,7 +32,7 @@ class ActivityPub::TagManager
|
||||
when :flag
|
||||
target.uri
|
||||
when :featured_collection
|
||||
account_collection_url(target.account, target)
|
||||
collection_url(target)
|
||||
end
|
||||
end
|
||||
|
||||
|
||||
@ -25,6 +25,7 @@ class Form::AdminSettings
|
||||
hide_followers_count
|
||||
flavour_and_skin
|
||||
thumbnail
|
||||
thumbnail_description
|
||||
mascot
|
||||
show_reblogs_in_public_timelines
|
||||
show_replies_in_public_timelines
|
||||
@ -124,6 +125,7 @@ class Form::AdminSettings
|
||||
validates :media_cache_retention_period, :content_cache_retention_period, :backups_retention_period, numericality: { only_integer: true }, allow_blank: true, if: -> { defined?(@media_cache_retention_period) || defined?(@content_cache_retention_period) || defined?(@backups_retention_period) }
|
||||
validates :min_age, numericality: { only_integer: true }, allow_blank: true, if: -> { defined?(@min_age) }
|
||||
validates :site_short_description, length: { maximum: DESCRIPTION_LIMIT }, if: -> { defined?(@site_short_description) }
|
||||
validates :thumbnail_description, length: { maximum: DESCRIPTION_LIMIT }, if: -> { defined?(@thumbnail_description) }
|
||||
validates :status_page_url, url: true, allow_blank: true
|
||||
validate :validate_site_uploads
|
||||
validates :landing_page, inclusion: { in: LANDING_PAGE }, if: -> { defined?(@landing_page) }
|
||||
|
||||
@ -26,6 +26,7 @@ class REST::InstanceSerializer < ActiveModel::Serializer
|
||||
'@1x': full_asset_url(object.thumbnail.file.url(:'@1x')),
|
||||
'@2x': full_asset_url(object.thumbnail.file.url(:'@2x')),
|
||||
},
|
||||
description: Setting.thumbnail_description,
|
||||
}
|
||||
else
|
||||
{
|
||||
|
||||
@ -2,7 +2,7 @@
|
||||
= t('admin.collections.collection_title', name: @account.pretty_acct)
|
||||
|
||||
- content_for :heading_actions do
|
||||
= link_to t('admin.collections.open'), account_collection_path(@account, @collection), class: 'button', target: '_blank', rel: 'noopener'
|
||||
= link_to t('admin.collections.open'), collection_path(@collection), class: 'button', target: '_blank', rel: 'noopener'
|
||||
|
||||
%h3= t('admin.collections.contents')
|
||||
|
||||
|
||||
@ -33,6 +33,11 @@
|
||||
= f.input :thumbnail,
|
||||
as: :file,
|
||||
wrapper: :with_block_label
|
||||
- if @admin_settings.thumbnail.persisted?
|
||||
= f.input :thumbnail_description,
|
||||
as: :text,
|
||||
input_html: { rows: 2, maxlength: Form::AdminSettings::DESCRIPTION_LIMIT },
|
||||
wrapper: :with_block_label
|
||||
.fields-row__column.fields-row__column-6.fields-group
|
||||
- if @admin_settings.thumbnail.persisted?
|
||||
= image_tag @admin_settings.thumbnail.file.url(:'@1x'), class: 'fields-group__thumbnail'
|
||||
|
||||
@ -18,5 +18,5 @@
|
||||
·
|
||||
= t('admin.collections.number_of_accounts', count: collection.accepted_collection_items.size)
|
||||
·
|
||||
= link_to account_collection_path(collection.account, collection), class: 'detailed-status__link', target: 'blank', rel: 'noopener' do
|
||||
= link_to collection_path(collection), class: 'detailed-status__link', target: 'blank', rel: 'noopener' do
|
||||
= t('admin.collections.view_publicly')
|
||||
|
||||
@ -98,11 +98,6 @@ Devise.setup do |config|
|
||||
manager.default_strategies(scope: :user).unshift :two_factor_ldap_authenticatable if Devise.ldap_authentication
|
||||
manager.default_strategies(scope: :user).unshift :two_factor_pam_authenticatable if Devise.pam_authentication
|
||||
manager.default_strategies(scope: :user).unshift :session_activation_rememberable
|
||||
|
||||
unless ENV['DISABLE_DEVISE_TWO_STRATEGIES'] == 'true'
|
||||
manager.default_strategies(scope: :user).unshift :two_factor_authenticatable
|
||||
manager.default_strategies(scope: :user).unshift :two_factor_backupable
|
||||
end
|
||||
end
|
||||
|
||||
# The secret key used by Devise. Devise uses this key to generate
|
||||
|
||||
@ -201,6 +201,7 @@ ar:
|
||||
create_relay: إنشاء خادم ترحيل
|
||||
create_unavailable_domain: إنشاء نطاق غير متوفر
|
||||
create_user_role: انشاء دور
|
||||
create_username_block: إنشاء قاعدة اسم المستخدم
|
||||
demote_user: إنزال رتبة المستخدم
|
||||
destroy_announcement: احذف الإعلان
|
||||
destroy_canonical_email_block: إلغاء حظر لبريد إلكتروني
|
||||
@ -756,6 +757,7 @@ ar:
|
||||
resolved_msg: تمت معالجة الشكوى بنجاح!
|
||||
skip_to_actions: تخطي إلى الإجراءات
|
||||
status: الحالة
|
||||
statuses: المنشورات (%{count})
|
||||
statuses_description_html: سيشار إلى المحتوى المخالف في الاتصال بالحساب المبلغ عنه
|
||||
summary:
|
||||
action_preambles:
|
||||
@ -825,6 +827,7 @@ ar:
|
||||
manage_blocks_description: السماح للمستخدمين بحظر مقدمي خدمات البريد الإلكتروني وعناوين IP
|
||||
manage_custom_emojis: إدارة الرموز التعبيريّة المخصصة
|
||||
manage_custom_emojis_description: السماح للمستخدمين بإدارة الرموز التعبيريّة المخصصة على الخادم
|
||||
manage_email_subscriptions: إدارة اشتراكات البريد الإلكتروني
|
||||
manage_federation: إدارة الفديرالية
|
||||
manage_federation_description: يسمح للمستخدمين بحظر أو السماح للاتحاد مع النطاقات الأخرى، والتحكم في إمكانية التسليم
|
||||
manage_invites: إدارة الدعوات
|
||||
@ -902,9 +905,13 @@ ar:
|
||||
all: للجميع
|
||||
disabled: لا أحد
|
||||
users: للمستخدمين المتصلين محليا
|
||||
feed_access:
|
||||
modes:
|
||||
public: الجميع
|
||||
landing_page:
|
||||
values:
|
||||
about: عن
|
||||
local_feed: الخيط المحلي
|
||||
trends: المتداوَلة
|
||||
registrations:
|
||||
moderation_recommandation: الرجاء التأكد من أن لديك فريق إشراف كافي وفعال قبل فتح التسجيلات للجميع!
|
||||
@ -1321,6 +1328,7 @@ ar:
|
||||
progress:
|
||||
confirm: تأكيد عنوان البريد الإلكتروني
|
||||
details: تفاصيلك
|
||||
list: تقدم التسجيل
|
||||
review: رأيُنا
|
||||
rules: قبول القواعد
|
||||
providers:
|
||||
@ -1385,6 +1393,7 @@ ar:
|
||||
light: فاتح
|
||||
contrast:
|
||||
auto: تلقائي
|
||||
high: عالٍ
|
||||
crypto:
|
||||
errors:
|
||||
invalid_key: ليس بمفتاح Ed25519 أو Curve25519 صالح
|
||||
@ -1457,9 +1466,22 @@ ar:
|
||||
other: أخرى
|
||||
email_subscription_mailer:
|
||||
confirmation:
|
||||
action: تأكيد عنوان البريد الإلكتروني
|
||||
subject: تأكيد عنوان بريدك الإلكتروني
|
||||
notification:
|
||||
create_account: إنشاء حساب ماستدون
|
||||
subject:
|
||||
plural: منشورات جديدة من %{name}
|
||||
singular: 'منشور جديد: "%{excerpt}"'
|
||||
email_subscriptions:
|
||||
active: نشط
|
||||
confirmations:
|
||||
show:
|
||||
changed_your_mind: هل غيرت رأيك؟
|
||||
unsubscribe: إلغاء الاشتراك
|
||||
inactive: غير نشط
|
||||
status: الحالة
|
||||
subscribers: المشتركون
|
||||
emoji_styles:
|
||||
auto: تلقائي
|
||||
native: محلي
|
||||
@ -1754,6 +1776,7 @@ ar:
|
||||
link_preview:
|
||||
author_html: مِن %{name}
|
||||
potentially_sensitive_content:
|
||||
action: اضغط للعرض
|
||||
hide_button: إخفاء
|
||||
lists:
|
||||
errors:
|
||||
@ -1897,6 +1920,7 @@ ar:
|
||||
posting_defaults: التفضيلات الافتراضية للنشر
|
||||
public_timelines: الخيوط الزمنية العامة
|
||||
privacy:
|
||||
email_subscriptions: إرسال المنشورات عبر البريد الإلكتروني
|
||||
hint_html: "<strong>قم بتخصيص الطريقة التي تريد بها أن يُكتَشَف ملفك الشخصي ومنشوراتك.</strong> يمكن لمجموعة متنوعة من الميزات في Mastodon أن تساعدك في الوصول إلى جمهور أوسع عند تفعيلها. خذ بعض الوقت لمراجعة هذه الإعدادات للتأكد من أنها تناسب حالة الاستخدام الخاصة بك."
|
||||
privacy: الخصوصية
|
||||
privacy_hint_html: تحكم في مقدار ما ترغب في الكشف عنه لصالح الآخرين. يكتشف الأشخاص الملفات الشخصية المثيرة والتطبيقات الرائعة من خلال تصفح متابعات الأشخاص الآخرين ورؤية التطبيقات التي ينشرونها، ولكن قد تفضل الاحتفاظ بها مخفية.
|
||||
@ -2080,10 +2104,14 @@ ar:
|
||||
limit: لقد بلغت الحد الأقصى للمنشورات المثبتة
|
||||
ownership: لا يمكن تثبيت منشور نشره شخص آخر
|
||||
reblog: لا يمكن تثبيت إعادة نشر
|
||||
quote_error:
|
||||
not_available: المنشور غير متوفر
|
||||
revoked: تمت إزالة المنشور من قبل صاحبه
|
||||
quote_policies:
|
||||
followers: للمتابِعين فقط
|
||||
nobody: لي فقط
|
||||
public: أيا كان
|
||||
quote_post_author: اقتبس منشور من قبل %{acct}
|
||||
title: '%{name}: "%{quote}"'
|
||||
visibilities:
|
||||
direct: إشارة خاصة
|
||||
@ -2165,6 +2193,9 @@ ar:
|
||||
recovery_codes_regenerated: تم إعادة توليد رموز الاسترجاع الاحتياطية بنجاح
|
||||
recovery_instructions_html: إن فقدت الوصول إلى هاتفك، يمكنك استخدام أحد رموز الاسترداد أدناه لاستعادة الوصول إلى حسابك. <strong>حافظ على رموز الاسترداد بأمان</strong>. يمكنك ، على سبيل المثال ، طباعتها وتخزينها مع مستندات أخرى هامة.
|
||||
webauthn: مفاتيح الأمان
|
||||
unsubscriptions:
|
||||
create:
|
||||
action: الذهاب إلى الصفحة الرئيسية للخادم
|
||||
user_mailer:
|
||||
announcement_published:
|
||||
description: 'يقوم مديرو %{domain} بإصدار إعلان:'
|
||||
|
||||
@ -2200,7 +2200,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, pienoiskuvien 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, pikkukuvien 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
|
||||
|
||||
@ -162,6 +162,7 @@ be:
|
||||
other: Нам трэба ўпэўніцца, што Вы як мінімум %{count} чалавекі з тых, хто карыстаецца %{domain}. Мы не будзем захоўваць гэту інфармацыю.
|
||||
role: Роля кантралюе тое, якія дазволы мае карыстальнік.
|
||||
user_role:
|
||||
collection_limit: Абмяжоўвае колькасць Калекцый, якія можа стварыць адзін карыстальнік гэтай ролі. Майце на ўвазе, калі ласка, што калі Вы зменшыце гэтую колькасць, то карыстальнікі, у якіх быў дасягнуты папярэдні ліміт, не страцяць нічога. Але новыя Калекцыі яны стварыць не змогуць.
|
||||
color: Колер, які будзе выкарыстоўвацца для гэтай ролі па ўсім UI, у фармаце RGB ці hex
|
||||
highlighted: Гэта робіць ролю публічна бачнай
|
||||
name: Публічная назва ролі, калі роля дэманструецца як значок у профілю
|
||||
@ -388,6 +389,7 @@ be:
|
||||
role: Роля
|
||||
time_zone: Часавы пояс
|
||||
user_role:
|
||||
collection_limit: Максімальная колькасць Калекцый на карыстальніка
|
||||
color: Колер значка
|
||||
highlighted: Паказваць ролю як значок у профілях
|
||||
name: Назва
|
||||
|
||||
@ -109,6 +109,7 @@ da:
|
||||
status_page_url: URL'en til en side, hvor status for denne server kan ses under en afbrydelse
|
||||
theme: Tema, som udloggede besøgende og nye brugere ser.
|
||||
thumbnail: Et ca. 2:1 billede vist sammen med dine serveroplysninger.
|
||||
thumbnail_description: En beskrivelse af billedet, der hjælper personer med synshandicap med at forstå dets indhold.
|
||||
trendable_by_default: Spring manuel gennemgang af trendindhold over. Individuelle elementer kan stadig fjernes fra trends efter kendsgerningen.
|
||||
trends: Trends viser, hvilke indlæg, hashtags og nyhedshistorier der opnår momentum på din server.
|
||||
wrapstodon: Tilbyd lokale brugere at generere en sjov oversigt over deres brug af Mastodon i løbet af året. Denne funktion er tilgængelig mellem den 10. og 31. december hvert år og tilbydes til brugere, der har lavet mindst ét offentligt eller stille offentligt indlæg og brugt mindst ét hashtag i løbet af året.
|
||||
@ -160,6 +161,7 @@ da:
|
||||
other: Vi skal sikre os, at du er mindst %{count} for at kunne bruge %{domain}. Informationen gemmes ikke.
|
||||
role: Rollen styrer, hvilke tilladelser brugeren er tildelt.
|
||||
user_role:
|
||||
collection_limit: Begrænser antallet af samlinger, som en enkelt bruger med denne rolle kan oprette. Bemærk, at hvis du reducerer dette antal, vil brugere, der allerede har nået denne grænse, ikke miste nogen samlinger. De vil dog ikke kunne oprette flere.
|
||||
color: Farven, i RGB hex-format, der skal bruges til rollen i hele UI'en
|
||||
highlighted: Dette gør rollen offentligt synlig
|
||||
name: Offentligt rollennavn, hvis rollen er opsat til fremstå som et badge
|
||||
@ -316,6 +318,7 @@ da:
|
||||
status_page_url: Statusside-URL
|
||||
theme: Standardtema
|
||||
thumbnail: Serverminiaturebillede
|
||||
thumbnail_description: Alt-tekst til miniaturebillede
|
||||
trendable_by_default: Tillad ikke-reviderede trends
|
||||
trends: Aktivér trends
|
||||
wrapstodon: Aktivér Wrapstodon
|
||||
@ -386,6 +389,7 @@ da:
|
||||
role: Rolle
|
||||
time_zone: Tidszone
|
||||
user_role:
|
||||
collection_limit: Maksimalt antal samlinger pr. bruger
|
||||
color: Badge-farve
|
||||
highlighted: Vis rolle som badge på brugerprofiler
|
||||
name: Navn
|
||||
|
||||
@ -106,6 +106,7 @@ de:
|
||||
status_page_url: Link zu einer Internetseite, auf der der Serverstatus während eines Ausfalls angezeigt wird
|
||||
theme: Das Design, das nicht angemeldete Personen sehen.
|
||||
thumbnail: Ein Bild ungefähr im 2:1-Format, das neben den Server-Informationen angezeigt wird.
|
||||
thumbnail_description: Eine Beschreibung des Bildes, damit Menschen, die blind oder sehbehindert sind, den Inhalt besser verstehen und einordnen können.
|
||||
trendable_by_default: Manuelles Überprüfen angesagter Inhalte überspringen. Einzelne Elemente können später noch aus den Trends entfernt werden.
|
||||
trends: Trends zeigen, welche Beiträge, Hashtags und Nachrichten auf deinem Server immer beliebter werden.
|
||||
wrapstodon: Ermöglicht Nutzer*innen dieses Servers einen spielerischen Jahresrückblick ihrer Mastodon-Aktivität zu erstellen. Diese Funktion ist jedes Jahr zwischen dem 10. und 31. Dezember verfügbar und wird Nutzer*innen angeboten, die innerhalb des Jahres mindestens einen öffentlichen oder stillen Beitrag verfasst und mindestens einen Hashtag verwendet haben.
|
||||
@ -156,6 +157,7 @@ de:
|
||||
other: Wir müssen sicherstellen, dass du mindestens %{count} Jahre alt bist, um %{domain} verwenden zu können. Wir werden diese Information nicht aufbewahren.
|
||||
role: Die Rolle bestimmt, welche Berechtigungen das Konto hat.
|
||||
user_role:
|
||||
collection_limit: Begrenzt die Anzahl an Sammlungen, die Profile mit dieser Rolle erstellen können. Solltest du die Anzahl verringern, verlieren Konten, die die maximal Anzahl bereits erreicht haben, zwar keine Sammlungen – aber sie können keine weiteren erstellen.
|
||||
color: Farbe, die für diese Rolle im Webinterface verwendet wird, als RGB im Hexadezimalsystem
|
||||
highlighted: Moderative/administrative Rolle im öffentlichen Profil anzeigen
|
||||
name: Name der Rolle, der auch öffentlich als Badge angezeigt wird, sofern dies unten aktiviert ist
|
||||
@ -312,6 +314,7 @@ de:
|
||||
status_page_url: Statusseite (URL)
|
||||
theme: Standard-Design
|
||||
thumbnail: Vorschaubild des Servers
|
||||
thumbnail_description: Bildbeschreibung des Vorschaubilds
|
||||
trendable_by_default: Trends ohne vorherige Überprüfung erlauben
|
||||
trends: Trends aktivieren
|
||||
wrapstodon: Wrapstodon aktivieren
|
||||
@ -382,6 +385,7 @@ de:
|
||||
role: Rolle
|
||||
time_zone: Zeitzone
|
||||
user_role:
|
||||
collection_limit: Höchstzahl an Sammlungen pro Profil
|
||||
color: Badge-Farbe
|
||||
highlighted: Badge im Profil
|
||||
name: Name
|
||||
|
||||
@ -109,6 +109,7 @@ el:
|
||||
status_page_url: Το URL μιας σελίδας όπου κάποιος μπορεί να δει την κατάσταση αυτού του διακομιστή κατά τη διάρκεια μιας διακοπής λειτουργίας
|
||||
theme: Θέμα που βλέπουν αποσυνδεδεμένοι επισκέπτες ή νέοι χρήστες.
|
||||
thumbnail: Μια εικόνα περίπου 2:1 που εμφανίζεται παράλληλα με τις πληροφορίες του διακομιστή σου.
|
||||
thumbnail_description: Μια περιγραφή της εικόνας για να βοηθήσει τα άτομα με προβλήματα όρασης να κατανοήσουν το περιεχόμενό της.
|
||||
trendable_by_default: Παράλειψη χειροκίνητου ελέγχου του περιεχομένου σε τάση. Μεμονωμένα στοιχεία μπορούν ακόμη να αφαιρεθούν από τις τάσεις μετέπειτα.
|
||||
trends: Τάσεις δείχνουν ποιες αναρτήσεις, ετικέτες και ειδήσεις προκαλούν έλξη στο διακομιστή σας.
|
||||
wrapstodon: Πρόσφερε στους τοπικούς χρήστες τη δυνατότητα να δημιουργήσουν μια παιχνιδιάρικη σύνοψη της χρήσης τους του Mastodon κατά τη διάρκεια του έτους. Αυτή η λειτουργία είναι διαθέσιμη μεταξύ της 10ης και της 31ης Δεκεμβρίου κάθε έτους, και προσφέρεται σε χρήστες που έκαναν τουλάχιστον μία δημόσια ή ήσυχα δημόσια ανάρτηση και χρησιμοποίησαν τουλάχιστον μία ετικέτα εντός του έτους.
|
||||
@ -160,6 +161,7 @@ el:
|
||||
other: Πρέπει να βεβαιωθούμε ότι είσαι τουλάχιστον %{count} για να χρησιμοποιήσεις το %{domain}. Δε θα το αποθηκεύσουμε.
|
||||
role: Ο ρόλος ελέγχει ποια δικαιώματα έχει ο χρήστης.
|
||||
user_role:
|
||||
collection_limit: Περιορίζει τον αριθμό των Συλλογών που μπορεί να δημιουργήσει ένας μόνο χρήστης με αυτόν τον ρόλο. Παρακαλούμε σημειώστε ότι όταν μειώσετε αυτόν τον αριθμό, οι χρήστες που βρίσκονται ήδη σε αυτό το όριο δεν θα χάσουν καμία Συλλογή. Αλλά δεν θα μπορούν να δημιουργήσουν επιπρόσθετες.
|
||||
color: Το χρώμα που θα χρησιμοποιηθεί για το ρόλο σε ολόκληρη τη διεπαφή, ως RGB σε δεκαεξαδική μορφή
|
||||
highlighted: Αυτό καθιστά το ρόλο δημόσια ορατό
|
||||
name: Δημόσιο όνομα του ρόλου, εάν ο ρόλος έχει οριστεί να εμφανίζεται ως σήμα
|
||||
@ -316,6 +318,7 @@ el:
|
||||
status_page_url: URL σελίδας κατάστασης
|
||||
theme: Προεπιλεγμένο θέμα
|
||||
thumbnail: Μικρογραφία διακομιστή
|
||||
thumbnail_description: Εναλλακτικό κείμενο μικρογραφίας
|
||||
trendable_by_default: Επίτρεψε τις τάσεις χωρίς προηγούμενο έλεγχο
|
||||
trends: Ενεργοποίηση τάσεων
|
||||
wrapstodon: Ενεργοποίηση Wrapstodon
|
||||
@ -386,6 +389,7 @@ el:
|
||||
role: Ρόλος
|
||||
time_zone: Ζώνη ώρας
|
||||
user_role:
|
||||
collection_limit: Μέγιστος αριθμός Συλλογών ανά χρήστη
|
||||
color: Χρώμα σήματος
|
||||
highlighted: Εμφάνιση ρόλου ως σήμα στα προφίλ χρηστών
|
||||
name: Όνομα
|
||||
|
||||
@ -109,6 +109,7 @@ en:
|
||||
status_page_url: URL of a page where people can see the status of this server during an outage
|
||||
theme: Theme that logged out visitors and new users see.
|
||||
thumbnail: A roughly 2:1 image displayed alongside your server information.
|
||||
thumbnail_description: A description of the image to help people with visual impairments understand its content.
|
||||
trendable_by_default: Skip manual review of trending content. Individual items can still be removed from trends after the fact.
|
||||
trends: Trends show which posts, hashtags and news stories are gaining traction on your server.
|
||||
wrapstodon: Offer local users to generate a playful summary of their Mastodon use during the year. This feature is available between the 10th and 31st of December of each year, and is offered to users who made at least one Public or Quiet Public post and used at least one hashtag within the year.
|
||||
@ -317,6 +318,7 @@ en:
|
||||
status_page_url: Status page URL
|
||||
theme: Default theme
|
||||
thumbnail: Server thumbnail
|
||||
thumbnail_description: Thumbnail alt text
|
||||
trendable_by_default: Allow trends without prior review
|
||||
trends: Enable trends
|
||||
wrapstodon: Enable Wrapstodon
|
||||
|
||||
@ -109,6 +109,7 @@ es-AR:
|
||||
status_page_url: Dirección web de una página donde la gente puede ver el estado de este servidor durante un apagón
|
||||
theme: El tema que los visitantes no registrados y los nuevos usuarios ven.
|
||||
thumbnail: Una imagen de aproximadamente 2:1 se muestra junto a la información de tu servidor.
|
||||
thumbnail_description: Una descripción de la imagen para ayudar a personas con discapacidades visuales a entender su contenido.
|
||||
trendable_by_default: Omití la revisión manual del contenido en tendencia. Los elementos individuales aún podrán eliminarse de las tendencias.
|
||||
trends: Las tendencias muestran qué mensajes, etiquetas y noticias están ganando tracción en tu servidor.
|
||||
wrapstodon: Ofrecer a los usuarios locales un resumen lúdico de su uso en Mastodon durante el año. Esta función está disponible entre los días 10 y 31 de diciembre de cada año, y se ofrece a los usuarios que enviaron a Mastodon, al menos, un mensaje público o un mensaje público pero silencioso, y que utilizaron, al menos, una etiqueta durante el año.
|
||||
@ -160,6 +161,7 @@ es-AR:
|
||||
other: Tenemos que asegurarnos de que al menos tenés %{count} años de edad para usar %{domain}. No almacenaremos esta información.
|
||||
role: El rol controla qué permisos tiene el usuario.
|
||||
user_role:
|
||||
collection_limit: Limita el número de colecciones que un solo usuario con este rol puede crear. Por favor, tené en cuenta que cuando disminuya este número, los usuarios que ya están en este límite no perderán ninguna colección. Pero no podrán crear otras más.
|
||||
color: Color que se utilizará para el rol a lo largo de la interface de usuario, como RGB en formato hexadecimal
|
||||
highlighted: Esto hace que el rol sea públicamente visible
|
||||
name: Nombre público del rol, si el rol se establece para que se muestre como una insignia
|
||||
@ -316,6 +318,7 @@ es-AR:
|
||||
status_page_url: Dirección web de la página de estado
|
||||
theme: Tema predeterminado
|
||||
thumbnail: Miniatura del servidor
|
||||
thumbnail_description: Texto alternativo de miniatura
|
||||
trendable_by_default: Permitir tendencias sin revisión previa
|
||||
trends: Habilitar tendencias
|
||||
wrapstodon: Habilitar MastodonAnual
|
||||
@ -386,6 +389,7 @@ es-AR:
|
||||
role: Rol
|
||||
time_zone: Zona horaria
|
||||
user_role:
|
||||
collection_limit: Número máximo de colecciones por usuario
|
||||
color: Color de Insignia
|
||||
highlighted: Mostrar rol como insignia en perfiles de usuario
|
||||
name: Nombre
|
||||
|
||||
@ -109,6 +109,7 @@ es-MX:
|
||||
status_page_url: URL de una página donde las personas pueden ver el estado de este servidor durante una interrupción
|
||||
theme: El tema que los visitantes no registrados y los nuevos usuarios ven.
|
||||
thumbnail: Una imagen de aproximadamente 2:1 se muestra junto a la información de tu servidor.
|
||||
thumbnail_description: Una descripción de la imagen para ayudar a las personas con discapacidades visuales a entender su contenido.
|
||||
trendable_by_default: Omitir la revisión manual del contenido en tendencia. Los elementos individuales aún podrán eliminarse de las tendencias.
|
||||
trends: Las tendencias muestran qué mensajes, etiquetas y noticias están ganando tracción en tu servidor.
|
||||
wrapstodon: Ofrece a los usuarios locales la posibilidad de generar un resumen divertido de su uso de Mastodon durante el año. Esta función está disponible entre el 10 y el 31 de diciembre de cada año, y se ofrece a los usuarios que hayan publicado al menos una publicación pública o pública silenciosa y hayan utilizado al menos una etiqueta durante el año.
|
||||
@ -160,6 +161,7 @@ es-MX:
|
||||
other: Tenemos que asegurarnos de que tienes al menos %{count} para usar %{domain}. No almacenaremos esta información.
|
||||
role: El rol controla qué permisos tiene el usuario.
|
||||
user_role:
|
||||
collection_limit: Limita el número de colecciones que puede crear un solo usuario con este rol. Ten en cuenta que, si reduces este número, los usuarios que ya hayan alcanzado este límite no perderán ninguna de sus colecciones, pero no podrán crear otras nuevas.
|
||||
color: Color que se usará para el rol en toda la interfaz de usuario, como RGB en formato hexadecimal
|
||||
highlighted: Esto hace que el rol sea públicamente visible
|
||||
name: Nombre público del rol, si el rol se establece para que se muestre como una insignia
|
||||
@ -316,6 +318,7 @@ es-MX:
|
||||
status_page_url: URL de página de estado
|
||||
theme: Tema por defecto
|
||||
thumbnail: Miniatura del servidor
|
||||
thumbnail_description: Texto alternativo de miniatura
|
||||
trendable_by_default: Permitir tendencias sin revisión previa
|
||||
trends: Habilitar tendencias
|
||||
wrapstodon: Habilitar Wrapstodon
|
||||
@ -386,6 +389,7 @@ es-MX:
|
||||
role: Rol
|
||||
time_zone: Zona horaria
|
||||
user_role:
|
||||
collection_limit: Número máximo de colecciones por usuario
|
||||
color: Color de insignia
|
||||
highlighted: Mostrar rol como insignia en perfiles de usuario
|
||||
name: Nombre
|
||||
|
||||
@ -109,6 +109,7 @@ es:
|
||||
status_page_url: URL de una página donde se pueda ver el estado de este servidor durante una incidencia
|
||||
theme: El tema que los visitantes no registrados y los nuevos usuarios ven.
|
||||
thumbnail: Una imagen de aproximadamente 2:1 se muestra junto a la información de tu servidor.
|
||||
thumbnail_description: Una descripción de la imagen para ayudar a las personas con discapacidades visuales a entender su contenido.
|
||||
trendable_by_default: Omitir la revisión manual del contenido en tendencia. Los elementos individuales aún podrán eliminarse de las tendencias.
|
||||
trends: Las tendencias muestran qué publicaciones, etiquetas y noticias están ganando tracción en tu servidor.
|
||||
wrapstodon: Ofrecer a los usuarios locales un resumen lúdico de su uso en Mastodon durante el año. Esta característica está disponible entre los días 10 y 31 de diciembre de cada año, y se ofrece a los usuarios que hicieron al menos una publicación Pública o Pública Silenciosa y utilizaron al menos una etiqueta durante el año.
|
||||
@ -160,6 +161,7 @@ es:
|
||||
other: Tenemos que asegurarnos de que tienes al menos %{count} para usar %{domain}. No guardaremos esta información.
|
||||
role: El rol controla qué permisos tiene el usuario.
|
||||
user_role:
|
||||
collection_limit: Limita el número de Colecciones que un usuario con este rol puede crear. Ten en cuenta que, al reducir este número, los usuarios que superen este límite no perderán ninguna Colección, pero tampoco podrán crear más.
|
||||
color: Color que se utilizará para el rol a lo largo de la interfaz de usuario, como RGB en formato hexadecimal
|
||||
highlighted: Esto hace que el rol sea públicamente visible
|
||||
name: Nombre público del rol, si el rol se establece para que se muestre como una insignia
|
||||
@ -316,6 +318,7 @@ es:
|
||||
status_page_url: URL de página de estado
|
||||
theme: Tema por defecto
|
||||
thumbnail: Miniatura del servidor
|
||||
thumbnail_description: Texto alternativo de miniatura
|
||||
trendable_by_default: Permitir tendencias sin revisión previa
|
||||
trends: Habilitar tendencias
|
||||
wrapstodon: Habilitar Wrapstodon
|
||||
@ -386,6 +389,7 @@ es:
|
||||
role: Rol
|
||||
time_zone: Zona horaria
|
||||
user_role:
|
||||
collection_limit: Número máximo de Colecciones por usuario
|
||||
color: Color de insignia
|
||||
highlighted: Mostrar rol como insignia en perfiles de usuario
|
||||
name: Nombre
|
||||
|
||||
@ -160,6 +160,7 @@ et:
|
||||
other: "%{domain} saidi teenuste kasutamiseks pead olema vähemalt %{count} aastat vana. Me ei salvesta neid andmeid."
|
||||
role: Rollid määravad, millised õigused kasutajal on.
|
||||
user_role:
|
||||
collection_limit: Piirab sellise rolliga kasutaja poolt loodavate kogumike arvu. Pane tähele, et kui vähendad seda arvu, ei kaota kasutajad, kes on juba piirmäära saavutanud, ühtegi kogumikku, aga nad ei saa luua uusi kogumikke.
|
||||
color: Rolli tähistamise värvus üle kasutajaliidese, RGB 16nd-formaadis
|
||||
highlighted: Teeb rolli avalikult nähtavaks
|
||||
name: Rolli avalik nimi, kui roll on märgitud avalikuks kuvamiseks märgina
|
||||
@ -386,6 +387,7 @@ et:
|
||||
role: Roll
|
||||
time_zone: Ajavöönd
|
||||
user_role:
|
||||
collection_limit: Kogumike maksimumarv kasutaja kohta
|
||||
color: Märgi värv
|
||||
highlighted: Kuva roll kasutajaprofiilidel märgina
|
||||
name: Nimi
|
||||
|
||||
@ -109,6 +109,7 @@ fi:
|
||||
status_page_url: URL-osoite sivulle, josta tämän palvelimen tilan voi ongelmatilanteissa tarkistaa
|
||||
theme: Teema, jonka uloskirjautuneet vierailijat ja uudet käyttäjät näkevät.
|
||||
thumbnail: Noin 2:1 kuva näkyy palvelimen tietojen ohessa.
|
||||
thumbnail_description: Kuvan kuvaus, joka auttaa näkövammallisia ymmärtämään kuvan sisällön.
|
||||
trendable_by_default: Ohita suositun sisällön manuaalinen tarkastus. Yksittäisiä kohteita voidaan edelleen poistaa jälkikäteen.
|
||||
trends: Trendit osoittavat, mitkä julkaisut, aihetunnisteet ja uutiset keräävät huomiota palvelimellasi.
|
||||
wrapstodon: Tarjoa paikallisille käyttäjille mahdollisuus luoda leikkisä koonti heidän Mastodonin käytöstään vuoden aikana. Tämä ominaisuus on saatavilla vuosittain 10.–31. joulukuuta, ja sitä tarjotaan käyttäjille, jotka ovat laatineet ainakin yhden julkisen tai vaihvihkaa julkisen julkaisun ja käyttäneet ainakin yhtä aihetunnistetta vuoden aikana.
|
||||
@ -160,6 +161,7 @@ fi:
|
||||
other: Meidän tulee varmistaa, että olet vähintään %{count}, jotta voit käyttää %{domain}. Emme tallenna tätä.
|
||||
role: Rooli määrää, millaiset käyttöoikeudet käyttäjällä on.
|
||||
user_role:
|
||||
collection_limit: Rajoittaa kokoelmien määrää, jonka yksittäinen käyttäjä, jolla on tämä rooli, voi luoda. Huomaa, että kun pienennät tätä lukua, käyttäjät, jotka ovat jo tällä rajalla, eivät menetä yhtäkään kokoelmaa. He eivät kuitenkaan voi luoda uusia rooleja.
|
||||
color: Väri, jota käytetään roolille kaikkialla käyttöliittymässä, RGB-heksadesimaalimuodossa
|
||||
highlighted: Tämä tekee roolista julkisesti näkyvän
|
||||
name: Roolin julkinen nimi, jos rooli on asetettu näytettäväksi merkkinä
|
||||
@ -315,7 +317,8 @@ fi:
|
||||
site_title: Palvelimen nimi
|
||||
status_page_url: Tilasivun URL-osoite
|
||||
theme: Oletusteema
|
||||
thumbnail: Palvelimen pienoiskuva
|
||||
thumbnail: Palvelimen pikkukuva
|
||||
thumbnail_description: Pikkukuvan tekstivastine
|
||||
trendable_by_default: Salli trendit ilman ennakkotarkastusta
|
||||
trends: Ota trendit käyttöön
|
||||
wrapstodon: Ota Wrapstodon käyttöön
|
||||
@ -386,6 +389,7 @@ fi:
|
||||
role: Rooli
|
||||
time_zone: Aikavyöhyke
|
||||
user_role:
|
||||
collection_limit: Kokoelmien käyttäjäkohtainen enimmäismäärä
|
||||
color: Merkin väri
|
||||
highlighted: Näytä rooli merkkinä käyttäjäprofiileissa
|
||||
name: Nimi
|
||||
|
||||
@ -160,6 +160,7 @@ fr-CA:
|
||||
other: Nous devons vérifier que vous avez au moins %{count} ans pour utiliser %{domain}. Cette information ne sera pas conservée.
|
||||
role: Le rôle définit les autorisations de l'utilisateur⋅rice.
|
||||
user_role:
|
||||
collection_limit: Limite le nombre de collections qu'un compte avec ce rôle peut créer. Veuillez noter que si vous diminuez cette limite, les comptes qui la dépassent ne perdront pas de collections. Mais ile ne pourront pas en créer de nouvelles.
|
||||
color: Couleur à attribuer au rôle dans l'interface, au format hexadécimal RVB
|
||||
highlighted: Cela rend le rôle visible publiquement
|
||||
name: Nom public du rôle, si le rôle est configuré pour être affiché avec un badge
|
||||
@ -386,6 +387,7 @@ fr-CA:
|
||||
role: Rôle
|
||||
time_zone: Fuseau horaire
|
||||
user_role:
|
||||
collection_limit: Nombre maximum de collections par compte
|
||||
color: Couleur du badge
|
||||
highlighted: Afficher le rôle avec un badge sur les profils des utilisateur·rice·s
|
||||
name: Nom
|
||||
|
||||
@ -160,6 +160,7 @@ fr:
|
||||
other: Nous devons vérifier que vous avez au moins %{count} ans pour utiliser %{domain}. Cette information ne sera pas conservée.
|
||||
role: Le rôle définit les autorisations de l'utilisateur⋅rice.
|
||||
user_role:
|
||||
collection_limit: Limite le nombre de collections qu'un compte avec ce rôle peut créer. Veuillez noter que si vous diminuez cette limite, les comptes qui la dépassent ne perdront pas de collections. Mais ile ne pourront pas en créer de nouvelles.
|
||||
color: Couleur à attribuer au rôle dans l'interface, au format hexadécimal RVB
|
||||
highlighted: Cela rend le rôle visible publiquement
|
||||
name: Nom public du rôle, si le rôle est configuré pour être affiché en tant que badge
|
||||
@ -386,6 +387,7 @@ fr:
|
||||
role: Rôle
|
||||
time_zone: Fuseau horaire
|
||||
user_role:
|
||||
collection_limit: Nombre maximum de collections par compte
|
||||
color: Couleur du badge
|
||||
highlighted: Afficher le rôle en tant que badge sur les profils des utilisateur·rice·s
|
||||
name: Nom
|
||||
|
||||
@ -163,6 +163,7 @@ ga:
|
||||
two: Caithfimid a chinntiú go bhfuil tú %{count} ar a laghad chun %{domain} a úsáid. Ní stórálfaimid é seo.
|
||||
role: Rialaíonn an ról na ceadanna atá ag an úsáideoir.
|
||||
user_role:
|
||||
collection_limit: Cuireann sé teorainn le líon na mbailiúchán is féidir le húsáideoir aonair leis an ról seo a chruthú. Tabhair faoi deara, le do thoil, nuair a laghdaíonn tú an líon seo, nach gcaillfidh úsáideoirí atá ag an teorainn seo cheana féin aon bhailiúcháin. Ach ní bheidh siad in ann cinn bhreise a chruthú.
|
||||
color: Dath le húsáid don ról ar fud an Chomhéadain, mar RGB i bhformáid heicsidheachúlach
|
||||
highlighted: Déanann sé seo an ról le feiceáil go poiblí
|
||||
name: Ainm poiblí an róil, má tá an ról socraithe le taispeáint mar shuaitheantas
|
||||
@ -389,6 +390,7 @@ ga:
|
||||
role: Ról
|
||||
time_zone: Crios ama
|
||||
user_role:
|
||||
collection_limit: Uasmhéid na mBailiúchán in aghaidh an úsáideora
|
||||
color: Dath suaitheantas
|
||||
highlighted: Taispeáin ról mar shuaitheantas ar phróifílí úsáideora
|
||||
name: Ainm
|
||||
|
||||
@ -61,6 +61,9 @@ gl:
|
||||
setting_default_quote_policy_private: As publicacións só para seguidoras creadas con Mastodon non poden ser citadas.
|
||||
setting_default_quote_policy_unlisted: Cando alguén te cite, a súa publicación non aparecerá nas cronoloxías de popularidade.
|
||||
setting_default_sensitive: Medios sensibles marcados como ocultos por defecto e móstranse cun click
|
||||
setting_display_media_default: Aviso antes de mostrar multimedia marcado como sensible
|
||||
setting_display_media_hide_all: Aviso antes de mostrar calquera multimedia
|
||||
setting_display_media_show_all: Mostrar todo o multimedia sen avisar, incluíndo o multimedia marcado como sensible
|
||||
setting_emoji_style: Forma de mostrar emojis. «Auto» intentará usar os emojis nativos, e se falla recurrirase a Twemoji en navegadores antigos.
|
||||
setting_quick_boosting_html: Se está activo, ao premer na icona %{boost_icon} Promover farase automáticamente a promoción no lugar de abrir o menú despregable promover/citar. Sitúa a acción de citar no menú %{options_icon} (Opcións).
|
||||
setting_system_scrollbars_ui: Aplícase só en navegadores de escritorio baseados en Safari e Chrome
|
||||
@ -106,6 +109,7 @@ gl:
|
||||
status_page_url: URL dunha páxina onde se pode ver o estado deste servidor cando non está a funcionar
|
||||
theme: Decorado que verán visitantes e novas usuarias.
|
||||
thumbnail: Imaxe con proporcións 2:1 mostrada xunto á información sobre o servidor.
|
||||
thumbnail_description: A descrición da imaxe axuda ás persoas con problemas de visión a comprender o seu contido.
|
||||
trendable_by_default: Omitir a revisión manual dos contidos populares. Poderás igualmente eliminar manualmente os elementos que vaian aparecendo.
|
||||
trends: As tendencias mostran publicacións, cancelos e novas historias que teñen popularidade no teu servidor.
|
||||
wrapstodon: Ofrecerlle ás usuarias locais crear un divertido resumo do seu uso de Mastodon durante o ano. Esta ferramenta está dispoñible entre o 10 e o 31 de Decembro de cada ano, e ofréceselle ás usuarias que publicaron polo menos unha mensaxe Pública ou Pública Limitada e utilizaron polo menos un cancelo durante o ano.
|
||||
@ -157,6 +161,7 @@ gl:
|
||||
other: Temos que confirmar que tes %{count} anos polo menos para usar %{domain}. Non gardamos este dato.
|
||||
role: Os roles establecen os permisos que ten a usuaria.
|
||||
user_role:
|
||||
collection_limit: Limita o número de coleccións que unha única usuaria con este rol pode crear. Ten en conta que cando diminúes este número as usuarias que xa acadasen o límite non perderán ningunha colección, mais non poderán crear ningunha nova.
|
||||
color: Cor que se usará para o rol a través da IU, como RGB en formato hex
|
||||
highlighted: Isto fai o rol publicamente visible
|
||||
name: Nome público do rol, se o rol se mostra como unha insignia
|
||||
@ -313,6 +318,7 @@ gl:
|
||||
status_page_url: URL da páxina do estado
|
||||
theme: Decorado predeterminado
|
||||
thumbnail: Icona do servidor
|
||||
thumbnail_description: Texto alternativo da miniatura
|
||||
trendable_by_default: Permitir tendencias sen aprobación previa
|
||||
trends: Activar tendencias
|
||||
wrapstodon: Activar Wrapstodon
|
||||
@ -383,6 +389,7 @@ gl:
|
||||
role: Rol
|
||||
time_zone: Fuso horario
|
||||
user_role:
|
||||
collection_limit: Número máximo de coleccións por usuaria
|
||||
color: Cor da insignia
|
||||
highlighted: Mostrar rol como insignia en perfís de usuarias
|
||||
name: Nome
|
||||
|
||||
@ -109,6 +109,7 @@ is:
|
||||
status_page_url: Slóð á síðu þar sem fólk getur séð ástand netþjónsins þegar vandræði koma upp
|
||||
theme: Þema sem útskráðir gestir og nýjir notendur sjá.
|
||||
thumbnail: Mynd um það bil 2:1 sem birtist samhliða upplýsingum um netþjóninn þinn.
|
||||
thumbnail_description: Lýsing á myndinni sem hjálpar sjónskertu fólki að skilja efni hennar.
|
||||
trendable_by_default: Sleppa handvirkri yfirferð á vinsælu efni. Áfram verður hægt að fjarlægja stök atriði úr vinsældarlistum.
|
||||
trends: Vinsældir sýna hvaða færslur, myllumerki og fréttasögur séu í umræðunni á netþjóninum þínum.
|
||||
wrapstodon: Býður notendum á netþjóninum upp á skemmtilega samantekt um notkun þeirra á Mastodon á árinu sem er að líða. Þessi eiginleiki er í boði á milli 10. og 31. desember ár hvert og býðst þeim notendum sem hafa gert að minnsta kosti eina opinbera eða hljóðlega opinbera færslu og notað a. m. k. eitt myllumerki á árinu.
|
||||
@ -160,6 +161,7 @@ is:
|
||||
other: Við verðum að ganga úr skugga um að þú hafir náð %{count} aldri til að nota %{domain}. Við munum ekki geyma þessar upplýsingar.
|
||||
role: Hlutverk stýrir hvaða heimildir notandinn hefur.
|
||||
user_role:
|
||||
collection_limit: Takmarkar fjöldi safna sem hver notandi með þetta hlutverk getur útbúið. Athugaðu að með því að minnka þennan fjölda, þá munu notendur sem þegar eru við þessi mörk ekki missa nein söfn. En þeir munu ekki geta útbúið nein í viðbót.
|
||||
color: Litur sem notaður er fyrir hlutverkið allsstaðar í viðmótinu, sem RGB-gildi á hex-sniði
|
||||
highlighted: Þetta gerir hlutverk sýnilegt opinberlega
|
||||
name: Opinbert heiti hlutverks, ef birta á hlutverk sem merki
|
||||
@ -316,6 +318,7 @@ is:
|
||||
status_page_url: Slóð á ástandssíðu
|
||||
theme: Sjálfgefið þema
|
||||
thumbnail: Smámynd vefþjóns
|
||||
thumbnail_description: Hjálpartexti smámynda
|
||||
trendable_by_default: Leyfa vinsælt efni án undanfarandi yfirferðar
|
||||
trends: Virkja vinsælt
|
||||
wrapstodon: Virkja Ársuppgjörið
|
||||
@ -386,6 +389,7 @@ is:
|
||||
role: Hlutverk
|
||||
time_zone: Tímabelti
|
||||
user_role:
|
||||
collection_limit: Hámarksfjöldi safna á hvern notanda
|
||||
color: Litur merkis
|
||||
highlighted: Birta hlutverk sem merki á notandaauðkenni
|
||||
name: Nafn
|
||||
|
||||
@ -109,6 +109,7 @@ it:
|
||||
status_page_url: URL di una pagina in cui le persone possono visualizzare lo stato di questo server durante un disservizio
|
||||
theme: Tema visualizzato dai visitatori e dai nuovi utenti disconnessi.
|
||||
thumbnail: Un'immagine approssimativamente 2:1 visualizzata insieme alle informazioni del tuo server.
|
||||
thumbnail_description: Una descrizione dell'immagine per aiutare le persone con disabilità visive a comprenderne il contenuto.
|
||||
trendable_by_default: Salta la revisione manuale dei contenuti di tendenza. I singoli elementi possono ancora essere rimossi dalle tendenze dopo il fatto.
|
||||
trends: Le tendenze mostrano quali post, hashtag e notizie stanno guadagnando popolarità sul tuo server.
|
||||
wrapstodon: Offri agli utenti locali la possibilità di generare un riassunto giocoso del loro utilizzo di Mastodon durante l’anno. Questa funzione è disponibile dal 10 al 31 dicembre di ogni anno ed è offerta agli utenti che hanno pubblicato almeno un post pubblico o pubblico silenzioso e utilizzato almeno un hashtag nell’arco dell’anno.
|
||||
@ -160,6 +161,7 @@ it:
|
||||
other: Dobbiamo assicurarci che tu abbia almeno %{count} anni per utilizzare %{domain}. Non memorizzeremo questo dato.
|
||||
role: Il ruolo controlla quali permessi ha l'utente.
|
||||
user_role:
|
||||
collection_limit: Limita il numero di collezioni che un singolo utente con questo ruolo può creare. Si prega di tenere presente che, quando diminuisci questo numero, gli utenti che hanno già raggiunto questo limite, non perderanno alcuna collezione. Ma non potranno crearne di nuove.
|
||||
color: Colore da usare per il ruolo in tutta l'UI, come RGB in formato esadecimale
|
||||
highlighted: Rende il ruolo visibile
|
||||
name: Nome pubblico del ruolo, se il ruolo è impostato per essere visualizzato come distintivo
|
||||
@ -316,6 +318,7 @@ it:
|
||||
status_page_url: URL della pagina di stato
|
||||
theme: Tema predefinito
|
||||
thumbnail: Miniatura del server
|
||||
thumbnail_description: Testo alternativo dell'immagine in miniatura
|
||||
trendable_by_default: Consenti le tendenze senza revisione preventiva
|
||||
trends: Abilita le tendenze
|
||||
wrapstodon: Abilita Wrapstodon
|
||||
@ -386,6 +389,7 @@ it:
|
||||
role: Ruolo
|
||||
time_zone: Fuso orario
|
||||
user_role:
|
||||
collection_limit: Numero massimo di collezioni per utente
|
||||
color: Colore distintivo
|
||||
highlighted: Mostra il ruolo come distintivo sui profili utente
|
||||
name: Nome
|
||||
|
||||
@ -160,6 +160,7 @@ nl:
|
||||
other: We moeten er zeker van zijn dat je tenminste %{count} bent om %{domain} te mogen gebruiken. Deze informatie wordt niet door ons opgeslagen.
|
||||
role: De rol bepaalt welke rechten de gebruiker heeft.
|
||||
user_role:
|
||||
collection_limit: Beperkt het aantal verzamelingen dat een gebruiker met deze rol kan aanmaken. Houd er rekening mee dat wanneer je dit aantal verlaagt, gebruikers die al over deze limiet zijn geen Verzamelingen zullen verliezen. Zij zullen echter niet in staat zijn om er nog meer aan te maken.
|
||||
color: Kleur die gebruikt wordt voor de rol in de UI, als RGB in hexadecimale formaat
|
||||
highlighted: Dit maakt de rol openbaar zichtbaar
|
||||
name: Openbare naam van de rol, wanneer de rol als badge op profielpagina's wordt getoond
|
||||
@ -386,6 +387,7 @@ nl:
|
||||
role: Rol
|
||||
time_zone: Tijdzone
|
||||
user_role:
|
||||
collection_limit: Maximum aantal verzamelingen per gebruiker
|
||||
color: Kleur van badge
|
||||
highlighted: Rol als badge op profielpagina's tonen
|
||||
name: Naam
|
||||
|
||||
@ -160,6 +160,7 @@ pt-BR:
|
||||
other: Temos que ter certeza de que você é pelo menos %{count} para usar o %{domain} Não vamos armazenar isso.
|
||||
role: A função controla quais permissões o usuário tem.
|
||||
user_role:
|
||||
collection_limit: Limita o número de Coleções que um único usuário com este cargo pode criar. Note que caso reduza o número, usuários que já estavam no limite permitido não perderão nenhuma de suas Coleções. Mas não conseguirão criar Coleções adicionais.
|
||||
color: Cor a ser usada para o cargo em toda a interface do usuário, como RGB no formato hexadecimal
|
||||
highlighted: Isso torna o cargo publicamente visível
|
||||
name: Nome público do cargo, se ele for definido para ser exibido como um distintivo
|
||||
@ -386,6 +387,7 @@ pt-BR:
|
||||
role: Cargo
|
||||
time_zone: Fuso horário
|
||||
user_role:
|
||||
collection_limit: Número máximo de Coleções por usuário
|
||||
color: Cor do emblema
|
||||
highlighted: Exibir cargo como distintivo nos perfis de usuários
|
||||
name: Nome
|
||||
|
||||
@ -159,6 +159,7 @@ sq:
|
||||
other: Na duhet të sigurohemi se jeni të paktën %{count} që të përdorni %{domain}. S’do ta depozitojmë këtë.
|
||||
role: Roli kontrollon cilat leje ka përdoruesi.
|
||||
user_role:
|
||||
collection_limit: Kufizon numrin e Koleksioneve që mund të krijojë një përdorues me këtë rol. Ju lutemi, kini parasysh se kur zvogëloni këtë numër, përdoruesit që janë tashmë në këtë kufi, s’do të humbin ndonjë Koleksion. Por s’do të jenë në gjendje të krijojnë të rinj të tjerë.
|
||||
color: Ngjyrë për t’u përdorur për rolin nëpër UI, si RGB në format gjashtëmbëdhjetësh
|
||||
highlighted: Kjo e bën rolin të dukshëm publikisht
|
||||
name: Emër publik për rolin, nëse roli është ujdisur të shfaqet si një stemë
|
||||
@ -385,6 +386,7 @@ sq:
|
||||
role: Rol
|
||||
time_zone: Zonë kohore
|
||||
user_role:
|
||||
collection_limit: Numër maksimum Koleksionesh për përdorues
|
||||
color: Ngjyrë steme
|
||||
highlighted: Shfaqe rolin si një stemë në profile përdoruesish
|
||||
name: Emër
|
||||
|
||||
@ -160,6 +160,7 @@ tr:
|
||||
other: "%{domain} kullanmak için en az %{count} yaşında olduğunuzdan emin olmalıyız. Bu bilgiyi saklamıyoruz."
|
||||
role: Rol, kullanıcıların sahip olduğu izinleri denetler.
|
||||
user_role:
|
||||
collection_limit: Bu role sahip tek bir kullanıcının oluşturabileceği Koleksiyon sayısını sınırlar. Bu sayıyı azalttığınızda, halihazırda bu sınıra ulaşmış olan kullanıcıların mevcut Koleksiyonlarını kaybetmeyeceklerini lütfen unutmayın. Ancak bu kullanıcılar yeni Koleksiyonlar oluşturamayacaklardır.
|
||||
color: Arayüz boyunca rol için kullanılacak olan renk, hex biçiminde RGB
|
||||
highlighted: Bu rolü herkese açık hale getirir
|
||||
name: Rolün, eğer rozet olarak görüntülenmesi ayarlandıysa kullanılacak herkese açık ismi
|
||||
@ -386,6 +387,7 @@ tr:
|
||||
role: Rol
|
||||
time_zone: Zaman dilimi
|
||||
user_role:
|
||||
collection_limit: Bir kullanıcının sahip olabileceği maksimum Koleksiyon sayısı
|
||||
color: Rozet rengi
|
||||
highlighted: Rolü kullanıcıların profilinde rozet olarak görüntüle
|
||||
name: Ad
|
||||
|
||||
@ -109,6 +109,7 @@ zh-CN:
|
||||
status_page_url: 配置一个网址,当服务中断时,人们可以通过该网址查看服务器的状态。
|
||||
theme: 给未登录访客和新用户使用的主题。
|
||||
thumbnail: 与服务器信息一并展示的约 2:1 比例的图像。
|
||||
thumbnail_description: 一段图像描述,可以帮助视力障碍人士理解其内容。
|
||||
trendable_by_default: 跳过对热门内容的手工审核。个别项目仍可在之后从趋势中删除。
|
||||
trends: 热门页中会显示正在你服务器上受到关注的嘟文、标签和新闻故事。
|
||||
wrapstodon: 为本站用户提供生成他们过去一年使用 Mastodon 情况的趣味总结的功能。此功能在每年12月10日至12月31日提供给这一年发布过至少1条公开嘟文(无论是否设置为在时间线上显示)及至少使用过1个话题标签的用户。
|
||||
@ -159,6 +160,7 @@ zh-CN:
|
||||
other: 我们必须确保你至少年满 %{count} 岁才能使用 %{domain}。我们不会存储此信息。
|
||||
role: 角色用于控制用户拥有的权限。
|
||||
user_role:
|
||||
collection_limit: 限制具备此角色的单个用户可创建的收藏列表数量。请注意,当你减少这个数字的时候,已经达到该限制的用户并不会因此失去任何收藏列表,只是会不能再创建新的收藏列表。
|
||||
color: 在界面各处用于标记该角色的颜色,以十六进制 RGB 格式表示
|
||||
highlighted: 使角色公开可见
|
||||
name: 角色的公开名称,将在外显为徽章时使用
|
||||
@ -315,6 +317,7 @@ zh-CN:
|
||||
status_page_url: 状态页网址
|
||||
theme: 默认主题
|
||||
thumbnail: 本站缩略图
|
||||
thumbnail_description: 缩略图替代文本
|
||||
trendable_by_default: 允许在未审核的情况下将话题置为热门
|
||||
trends: 启用热门
|
||||
wrapstodon: 启用 Wrapstodon 年度回顾
|
||||
@ -385,6 +388,7 @@ zh-CN:
|
||||
role: 角色
|
||||
time_zone: 时区
|
||||
user_role:
|
||||
collection_limit: 每个用户收藏列表的最大数量
|
||||
color: 徽章颜色
|
||||
highlighted: 在用户资料中显示角色徽章
|
||||
name: 名称
|
||||
|
||||
@ -159,6 +159,7 @@ zh-TW:
|
||||
other: 我們必須確認您至少年滿 %{count} 以使用 %{domain}。我們不會儲存此資料。
|
||||
role: 角色控制使用者有哪些權限。
|
||||
user_role:
|
||||
collection_limit: 限制此角色單一使用者能建立收藏名單之數量。請注意,當您降低此數值時,已超過此限制之使用者將不會失去任何收藏名單,但將無法新增更多。
|
||||
color: 於整個使用者介面中用於角色的顏色,十六進位格式的 RGB
|
||||
highlighted: 這將使角色公開可見
|
||||
name: 角色的公開名稱,如果角色設定為顯示為徽章
|
||||
@ -385,6 +386,7 @@ zh-TW:
|
||||
role: 角色
|
||||
time_zone: 時區
|
||||
user_role:
|
||||
collection_limit: 每位使用者收藏名單數量上限
|
||||
color: 識別顏色
|
||||
highlighted: 於使用者個人檔案中顯示角色徽章
|
||||
name: 名稱
|
||||
|
||||
Some files were not shown because too many files have changed in this diff Show More
Loading…
x
Reference in New Issue
Block a user