mirror of
https://github.com/mastodon/mastodon.git
synced 2026-07-28 07:08:00 -05:00
Merge branch 'main' into compose-language-detection
This commit is contained in:
commit
d46a8a8c8e
|
|
@ -9,7 +9,7 @@ RUN /bin/bash --login -i -c "nvm install"
|
|||
# Install additional OS packages
|
||||
RUN apt-get update && \
|
||||
export DEBIAN_FRONTEND=noninteractive && \
|
||||
apt-get -y install --no-install-recommends libicu-dev libidn11-dev ffmpeg imagemagick libvips42 libpam-dev
|
||||
apt-get -y install --no-install-recommends libicu-dev libidn11-dev ffmpeg libvips42 libpam-dev
|
||||
|
||||
# Disable download prompt for Corepack
|
||||
ENV COREPACK_ENABLE_DOWNLOAD_PROMPT=0
|
||||
|
|
|
|||
2
.github/workflows/chromatic.yml
vendored
2
.github/workflows/chromatic.yml
vendored
|
|
@ -58,5 +58,5 @@ jobs:
|
|||
projectToken: ${{ secrets.CHROMATIC_PROJECT_TOKEN }}
|
||||
zip: true
|
||||
storybookBuildDir: 'storybook-static'
|
||||
exitZeroOnChanges: false # Fail workflow if changes are found
|
||||
exitOnceUploaded: true # Exit immediately after upload
|
||||
autoAcceptChanges: 'main' # Auto-accept changes on main branch only
|
||||
|
|
|
|||
87
.github/workflows/test-ruby.yml
vendored
87
.github/workflows/test-ruby.yml
vendored
|
|
@ -173,93 +173,6 @@ jobs:
|
|||
env:
|
||||
CODECOV_TOKEN: ${{ secrets.CODECOV_TOKEN }}
|
||||
|
||||
test-imagemagick:
|
||||
name: ImageMagick tests
|
||||
runs-on: ubuntu-latest
|
||||
|
||||
needs:
|
||||
- build
|
||||
|
||||
services:
|
||||
postgres:
|
||||
image: postgres:14-alpine
|
||||
env:
|
||||
POSTGRES_PASSWORD: postgres
|
||||
POSTGRES_USER: postgres
|
||||
options: >-
|
||||
--health-cmd pg_isready
|
||||
--health-interval 10ms
|
||||
--health-timeout 3s
|
||||
--health-retries 50
|
||||
ports:
|
||||
- 5432:5432
|
||||
|
||||
redis:
|
||||
image: redis:7-alpine
|
||||
options: >-
|
||||
--health-cmd "redis-cli ping"
|
||||
--health-interval 10ms
|
||||
--health-timeout 3s
|
||||
--health-retries 50
|
||||
ports:
|
||||
- 6379:6379
|
||||
|
||||
env:
|
||||
DB_HOST: localhost
|
||||
DB_USER: postgres
|
||||
DB_PASS: postgres
|
||||
COVERAGE: ${{ matrix.ruby-version == '.ruby-version' }}
|
||||
RAILS_ENV: test
|
||||
ALLOW_NOPAM: true
|
||||
PAM_ENABLED: true
|
||||
PAM_DEFAULT_SERVICE: pam_test
|
||||
PAM_CONTROLLED_SERVICE: pam_test_controlled
|
||||
OIDC_ENABLED: true
|
||||
OIDC_SCOPE: read
|
||||
SAML_ENABLED: true
|
||||
CAS_ENABLED: true
|
||||
BUNDLE_WITH: 'pam_authentication test'
|
||||
GITHUB_RSPEC: ${{ matrix.ruby-version == '.ruby-version' && github.event.pull_request && 'true' }}
|
||||
MASTODON_USE_LIBVIPS: false
|
||||
|
||||
strategy:
|
||||
fail-fast: false
|
||||
matrix:
|
||||
ruby-version:
|
||||
- '3.2'
|
||||
- '3.3'
|
||||
- '.ruby-version'
|
||||
steps:
|
||||
- uses: actions/checkout@v5
|
||||
|
||||
- uses: actions/download-artifact@v6
|
||||
with:
|
||||
path: './'
|
||||
name: ${{ github.sha }}
|
||||
|
||||
- name: Expand archived asset artifacts
|
||||
run: |
|
||||
tar xvzf artifacts.tar.gz
|
||||
|
||||
- name: Set up Ruby environment
|
||||
uses: ./.github/actions/setup-ruby
|
||||
with:
|
||||
ruby-version: ${{ matrix.ruby-version}}
|
||||
additional-system-dependencies: ffmpeg imagemagick libpam-dev
|
||||
|
||||
- name: Load database schema
|
||||
run: './bin/rails db:create db:schema:load db:seed'
|
||||
|
||||
- run: bin/rspec --tag attachment_processing
|
||||
|
||||
- name: Upload coverage reports to Codecov
|
||||
if: matrix.ruby-version == '.ruby-version'
|
||||
uses: codecov/codecov-action@v5
|
||||
with:
|
||||
files: coverage/lcov/mastodon.lcov
|
||||
env:
|
||||
CODECOV_TOKEN: ${{ secrets.CODECOV_TOKEN }}
|
||||
|
||||
test-e2e:
|
||||
name: End to End testing
|
||||
runs-on: ubuntu-latest
|
||||
|
|
|
|||
8
.storybook/modes.ts
Normal file
8
.storybook/modes.ts
Normal file
|
|
@ -0,0 +1,8 @@
|
|||
export const modes = {
|
||||
darkTheme: {
|
||||
theme: 'dark',
|
||||
},
|
||||
lightTheme: {
|
||||
theme: 'light',
|
||||
},
|
||||
} as const;
|
||||
|
|
@ -25,6 +25,7 @@ import { mockHandlers, unhandledRequestHandler } from '@/testing/api';
|
|||
// you can change the below to `/application.scss`
|
||||
import '../app/javascript/styles/mastodon-light.scss';
|
||||
import './styles.css';
|
||||
import { modes } from './modes';
|
||||
|
||||
const localeFiles = import.meta.glob('@/mastodon/locales/*.json', {
|
||||
query: { as: 'json' },
|
||||
|
|
@ -198,6 +199,13 @@ const preview: Preview = {
|
|||
msw: {
|
||||
handlers: mockHandlers,
|
||||
},
|
||||
|
||||
chromatic: {
|
||||
modes: {
|
||||
dark: modes.darkTheme,
|
||||
light: modes.lightTheme,
|
||||
},
|
||||
},
|
||||
},
|
||||
};
|
||||
|
||||
|
|
|
|||
|
|
@ -70,8 +70,6 @@ ENV \
|
|||
PATH="${PATH}:/opt/ruby/bin:/opt/mastodon/bin" \
|
||||
# Optimize jemalloc 5.x performance
|
||||
MALLOC_CONF="narenas:2,background_thread:true,thp:never,dirty_decay_ms:1000,muzzy_decay_ms:0" \
|
||||
# Enable libvips, should not be changed
|
||||
MASTODON_USE_LIBVIPS=true \
|
||||
# Sidekiq will touch tmp/sidekiq_process_has_started_and_will_begin_processing_jobs to indicate it is ready. This can be used for a readiness check in Kubernetes
|
||||
MASTODON_SIDEKIQ_READY_FILENAME=sidekiq_process_has_started_and_will_begin_processing_jobs
|
||||
|
||||
|
|
|
|||
|
|
@ -52,8 +52,8 @@ Mastodon requires all `POST` requests to be signed, and MAY require `GET` reques
|
|||
## Size limits
|
||||
|
||||
Mastodon imposes a few hard limits on federated content.
|
||||
These limits are intended to be very generous and way above what the Mastodon user experience is optimized for, so as to accomodate future changes and unusual or unforeseen usage patterns, while still providing some limits for performance reasons.
|
||||
The following table attempts to summary those limits.
|
||||
These limits are intended to be very generous and way above what the Mastodon user experience is optimized for, so as to accommodate future changes and unusual or unforeseen usage patterns, while still providing some limits for performance reasons.
|
||||
The following table summarizes those limits.
|
||||
|
||||
| Limited property | Size limit | Consequence of exceeding the limit |
|
||||
| ------------------------------------------------------------- | ---------- | ---------------------------------- |
|
||||
|
|
|
|||
26
Gemfile.lock
26
Gemfile.lock
|
|
@ -96,8 +96,8 @@ GEM
|
|||
ast (2.4.3)
|
||||
attr_required (1.0.2)
|
||||
aws-eventstream (1.4.0)
|
||||
aws-partitions (1.1201.0)
|
||||
aws-sdk-core (3.241.3)
|
||||
aws-partitions (1.1206.0)
|
||||
aws-sdk-core (3.241.4)
|
||||
aws-eventstream (~> 1, >= 1.3.0)
|
||||
aws-partitions (~> 1, >= 1.992.0)
|
||||
aws-sigv4 (~> 1.9)
|
||||
|
|
@ -105,11 +105,11 @@ GEM
|
|||
bigdecimal
|
||||
jmespath (~> 1, >= 1.6.1)
|
||||
logger
|
||||
aws-sdk-kms (1.120.0)
|
||||
aws-sdk-core (~> 3, >= 3.241.3)
|
||||
aws-sdk-kms (1.121.0)
|
||||
aws-sdk-core (~> 3, >= 3.241.4)
|
||||
aws-sigv4 (~> 1.5)
|
||||
aws-sdk-s3 (1.211.0)
|
||||
aws-sdk-core (~> 3, >= 3.241.3)
|
||||
aws-sdk-s3 (1.212.0)
|
||||
aws-sdk-core (~> 3, >= 3.241.4)
|
||||
aws-sdk-kms (~> 1)
|
||||
aws-sigv4 (~> 1.5)
|
||||
aws-sigv4 (1.12.1)
|
||||
|
|
@ -193,9 +193,9 @@ GEM
|
|||
railties (>= 4.1.0)
|
||||
responders
|
||||
warden (~> 1.2.3)
|
||||
devise-two-factor (6.2.0)
|
||||
devise-two-factor (6.3.1)
|
||||
activesupport (>= 7.0, < 8.2)
|
||||
devise (~> 4.0)
|
||||
devise (>= 4.0, < 5.0)
|
||||
railties (>= 7.0, < 8.2)
|
||||
rotp (~> 6.0)
|
||||
devise_pam_authenticatable2 (9.2.0)
|
||||
|
|
@ -234,7 +234,7 @@ GEM
|
|||
excon (1.3.2)
|
||||
logger
|
||||
fabrication (3.0.0)
|
||||
faker (3.5.3)
|
||||
faker (3.6.0)
|
||||
i18n (>= 1.8.11, < 2)
|
||||
faraday (2.14.0)
|
||||
faraday-net_http (>= 2.0, < 3.5)
|
||||
|
|
@ -305,8 +305,8 @@ GEM
|
|||
highline (3.1.2)
|
||||
reline
|
||||
hiredis (0.6.3)
|
||||
hiredis-client (0.26.3)
|
||||
redis-client (= 0.26.3)
|
||||
hiredis-client (0.26.4)
|
||||
redis-client (= 0.26.4)
|
||||
hkdf (0.3.0)
|
||||
htmlentities (4.3.4)
|
||||
http (5.3.1)
|
||||
|
|
@ -700,7 +700,7 @@ GEM
|
|||
readline (~> 0.0)
|
||||
rdf-normalize (0.7.0)
|
||||
rdf (~> 3.3)
|
||||
rdoc (7.0.3)
|
||||
rdoc (7.1.0)
|
||||
erb
|
||||
psych (>= 4.0.0)
|
||||
tsort
|
||||
|
|
@ -708,7 +708,7 @@ GEM
|
|||
reline
|
||||
redcarpet (3.6.1)
|
||||
redis (4.8.1)
|
||||
redis-client (0.26.3)
|
||||
redis-client (0.26.4)
|
||||
connection_pool
|
||||
regexp_parser (2.11.3)
|
||||
reline (0.6.3)
|
||||
|
|
|
|||
1
Vagrantfile
vendored
1
Vagrantfile
vendored
|
|
@ -29,7 +29,6 @@ sudo apt-get install \
|
|||
libpq-dev \
|
||||
libxml2-dev \
|
||||
libxslt1-dev \
|
||||
imagemagick \
|
||||
nodejs \
|
||||
redis-server \
|
||||
redis-tools \
|
||||
|
|
|
|||
|
|
@ -9,9 +9,9 @@ class Api::V1::Accounts::NotesController < Api::BaseController
|
|||
|
||||
def create
|
||||
if params[:comment].blank?
|
||||
AccountNote.find_by(account: current_account, target_account: @account)&.destroy
|
||||
current_account.account_notes.find_by(target_account: @account)&.destroy
|
||||
else
|
||||
@note = AccountNote.find_or_initialize_by(account: current_account, target_account: @account)
|
||||
@note = current_account.account_notes.find_or_initialize_by(target_account: @account)
|
||||
@note.comment = params[:comment]
|
||||
@note.save! if @note.changed?
|
||||
end
|
||||
|
|
|
|||
|
|
@ -21,7 +21,7 @@ class Api::V1Alpha::CollectionItemsController < Api::BaseController
|
|||
|
||||
@item = AddAccountToCollectionService.new.call(@collection, @account)
|
||||
|
||||
render json: @item, serializer: REST::CollectionItemSerializer
|
||||
render json: @item, serializer: REST::CollectionItemSerializer, adapter: :json
|
||||
end
|
||||
|
||||
def destroy
|
||||
|
|
|
|||
|
|
@ -26,16 +26,18 @@ class Api::V1Alpha::CollectionsController < Api::BaseController
|
|||
|
||||
def index
|
||||
cache_if_unauthenticated!
|
||||
authorize Collection, :index?
|
||||
authorize @account, :index_collections?
|
||||
|
||||
render json: @collections, each_serializer: REST::BaseCollectionSerializer
|
||||
render json: @collections, each_serializer: REST::CollectionSerializer, adapter: :json
|
||||
rescue Mastodon::NotPermittedError
|
||||
render json: { collections: [] }
|
||||
end
|
||||
|
||||
def show
|
||||
cache_if_unauthenticated!
|
||||
authorize @collection, :show?
|
||||
|
||||
render json: @collection, serializer: REST::CollectionSerializer
|
||||
render json: @collection, serializer: REST::CollectionWithAccountsSerializer
|
||||
end
|
||||
|
||||
def create
|
||||
|
|
@ -43,7 +45,7 @@ class Api::V1Alpha::CollectionsController < Api::BaseController
|
|||
|
||||
@collection = CreateCollectionService.new.call(collection_creation_params, current_user.account)
|
||||
|
||||
render json: @collection, serializer: REST::CollectionSerializer
|
||||
render json: @collection, serializer: REST::CollectionSerializer, adapter: :json
|
||||
end
|
||||
|
||||
def update
|
||||
|
|
@ -51,7 +53,7 @@ class Api::V1Alpha::CollectionsController < Api::BaseController
|
|||
|
||||
@collection.update!(collection_update_params) # TODO: Create a service for this to federate changes
|
||||
|
||||
render json: @collection, serializer: REST::CollectionSerializer
|
||||
render json: @collection, serializer: REST::CollectionSerializer, adapter: :json
|
||||
end
|
||||
|
||||
def destroy
|
||||
|
|
|
|||
|
|
@ -29,7 +29,7 @@ class StatusesController < ApplicationController
|
|||
end
|
||||
|
||||
format.json do
|
||||
expires_in 3.minutes, public: true if @status.distributable? && public_fetch_mode?
|
||||
expires_in @status.quote&.pending? ? 5.seconds : 3.minutes, public: true if @status.distributable? && public_fetch_mode?
|
||||
render_with_cache json: @status, content_type: 'application/activity+json', serializer: ActivityPub::NoteSerializer, adapter: ActivityPub::Adapter
|
||||
end
|
||||
end
|
||||
|
|
|
|||
39
app/javascript/mastodon/api/collections.ts
Normal file
39
app/javascript/mastodon/api/collections.ts
Normal file
|
|
@ -0,0 +1,39 @@
|
|||
import {
|
||||
apiRequestPost,
|
||||
apiRequestPut,
|
||||
apiRequestGet,
|
||||
apiRequestDelete,
|
||||
} from 'mastodon/api';
|
||||
|
||||
import type {
|
||||
ApiWrappedCollectionJSON,
|
||||
ApiCollectionWithAccountsJSON,
|
||||
ApiCreateCollectionPayload,
|
||||
ApiPatchCollectionPayload,
|
||||
ApiCollectionsJSON,
|
||||
} from '../api_types/collections';
|
||||
|
||||
export const apiCreateCollection = (collection: ApiCreateCollectionPayload) =>
|
||||
apiRequestPost<ApiWrappedCollectionJSON>('v1_alpha/collections', collection);
|
||||
|
||||
export const apiUpdateCollection = ({
|
||||
id,
|
||||
...collection
|
||||
}: ApiPatchCollectionPayload) =>
|
||||
apiRequestPut<ApiWrappedCollectionJSON>(
|
||||
`v1_alpha/collections/${id}`,
|
||||
collection,
|
||||
);
|
||||
|
||||
export const apiDeleteCollection = (collectionId: string) =>
|
||||
apiRequestDelete(`v1_alpha/collections/${collectionId}`);
|
||||
|
||||
export const apiGetCollection = (collectionId: string) =>
|
||||
apiRequestGet<ApiCollectionWithAccountsJSON[]>(
|
||||
`v1_alpha/collections/${collectionId}`,
|
||||
);
|
||||
|
||||
export const apiGetAccountCollections = (accountId: string) =>
|
||||
apiRequestGet<ApiCollectionsJSON>(
|
||||
`v1_alpha/accounts/${accountId}/collections`,
|
||||
);
|
||||
82
app/javascript/mastodon/api_types/collections.ts
Normal file
82
app/javascript/mastodon/api_types/collections.ts
Normal file
|
|
@ -0,0 +1,82 @@
|
|||
// See app/serializers/rest/base_collection_serializer.rb
|
||||
|
||||
import type { ApiAccountJSON } from './accounts';
|
||||
import type { ApiTagJSON } from './statuses';
|
||||
|
||||
/**
|
||||
* Returned when fetching all collections for an account,
|
||||
* doesn't contain account and item data
|
||||
*/
|
||||
export interface ApiCollectionJSON {
|
||||
account_id: string;
|
||||
|
||||
id: string;
|
||||
uri: string;
|
||||
local: boolean;
|
||||
item_count: number;
|
||||
|
||||
name: string;
|
||||
description: string;
|
||||
tag?: ApiTagJSON;
|
||||
language: string;
|
||||
sensitive: boolean;
|
||||
discoverable: boolean;
|
||||
|
||||
created_at: string;
|
||||
updated_at: string;
|
||||
|
||||
items: CollectionAccountItem[];
|
||||
}
|
||||
|
||||
/**
|
||||
* Returned when fetching all collections for an account
|
||||
*/
|
||||
export interface ApiCollectionsJSON {
|
||||
collections: ApiCollectionJSON[];
|
||||
}
|
||||
|
||||
/**
|
||||
* Returned when creating, updating, and adding to a collection
|
||||
*/
|
||||
export interface ApiWrappedCollectionJSON {
|
||||
collection: ApiCollectionJSON;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returned when fetching a single collection
|
||||
*/
|
||||
export interface ApiCollectionWithAccountsJSON extends ApiWrappedCollectionJSON {
|
||||
accounts: ApiAccountJSON[];
|
||||
}
|
||||
|
||||
/**
|
||||
* Nested account item
|
||||
*/
|
||||
interface CollectionAccountItem {
|
||||
account_id?: string; // Only present when state is 'accepted' (or the collection is your own)
|
||||
state: 'pending' | 'accepted' | 'rejected' | 'revoked';
|
||||
position: number;
|
||||
}
|
||||
|
||||
export interface WrappedCollectionAccountItem {
|
||||
collection_item: CollectionAccountItem;
|
||||
}
|
||||
|
||||
/**
|
||||
* Payload types
|
||||
*/
|
||||
|
||||
type CommonPayloadFields = Pick<
|
||||
ApiCollectionJSON,
|
||||
'name' | 'description' | 'sensitive' | 'discoverable'
|
||||
> & {
|
||||
tag?: string;
|
||||
};
|
||||
|
||||
export interface ApiPatchCollectionPayload extends Partial<CommonPayloadFields> {
|
||||
id: string;
|
||||
}
|
||||
|
||||
export interface ApiCreateCollectionPayload extends CommonPayloadFields {
|
||||
account_ids?: string[];
|
||||
}
|
||||
|
|
@ -0,0 +1,93 @@
|
|||
import type { Meta, StoryObj } from '@storybook/react-vite';
|
||||
import { action } from 'storybook/actions';
|
||||
|
||||
import { Callout } from '.';
|
||||
|
||||
const meta = {
|
||||
title: 'Components/Callout',
|
||||
args: {
|
||||
children: 'Contents here',
|
||||
title: 'Title',
|
||||
onPrimary: action('Primary action clicked'),
|
||||
primaryLabel: 'Primary',
|
||||
onSecondary: action('Secondary action clicked'),
|
||||
secondaryLabel: 'Secondary',
|
||||
onClose: action('Close clicked'),
|
||||
},
|
||||
component: Callout,
|
||||
render(args) {
|
||||
return (
|
||||
<div style={{ minWidth: 'min(400px, calc(100vw - 2rem))' }}>
|
||||
<Callout {...args} />
|
||||
</div>
|
||||
);
|
||||
},
|
||||
} satisfies Meta<typeof Callout>;
|
||||
|
||||
export default meta;
|
||||
|
||||
type Story = StoryObj<typeof meta>;
|
||||
|
||||
export const Default: Story = {
|
||||
args: {
|
||||
variant: 'default',
|
||||
},
|
||||
};
|
||||
|
||||
export const NoIcon: Story = {
|
||||
args: {
|
||||
icon: false,
|
||||
},
|
||||
};
|
||||
|
||||
export const NoActions: Story = {
|
||||
args: {
|
||||
onPrimary: undefined,
|
||||
onSecondary: undefined,
|
||||
},
|
||||
};
|
||||
|
||||
export const OnlyText: Story = {
|
||||
args: {
|
||||
onClose: undefined,
|
||||
onPrimary: undefined,
|
||||
onSecondary: undefined,
|
||||
icon: false,
|
||||
},
|
||||
};
|
||||
|
||||
// export const Subtle: Story = {
|
||||
// args: {
|
||||
// variant: 'subtle',
|
||||
// },
|
||||
// };
|
||||
|
||||
export const Feature: Story = {
|
||||
args: {
|
||||
variant: 'feature',
|
||||
},
|
||||
};
|
||||
|
||||
export const Inverted: Story = {
|
||||
args: {
|
||||
variant: 'inverted',
|
||||
},
|
||||
};
|
||||
|
||||
export const Success: Story = {
|
||||
args: {
|
||||
variant: 'success',
|
||||
},
|
||||
};
|
||||
|
||||
export const Warning: Story = {
|
||||
args: {
|
||||
variant: 'warning',
|
||||
},
|
||||
};
|
||||
|
||||
export const Error: Story = {
|
||||
args: {
|
||||
variant: 'error',
|
||||
},
|
||||
};
|
||||
27
app/javascript/mastodon/components/callout/dismissible.tsx
Normal file
27
app/javascript/mastodon/components/callout/dismissible.tsx
Normal file
|
|
@ -0,0 +1,27 @@
|
|||
import { useCallback } from 'react';
|
||||
import type { FC } from 'react';
|
||||
|
||||
import { useDismissible } from '@/mastodon/hooks/useDismissible';
|
||||
|
||||
import { Callout } from '.';
|
||||
import type { CalloutProps } from '.';
|
||||
|
||||
type DismissibleCalloutProps = CalloutProps & {
|
||||
id: string;
|
||||
};
|
||||
|
||||
export const DismissibleCallout: FC<DismissibleCalloutProps> = (props) => {
|
||||
const { dismiss, wasDismissed } = useDismissible(props.id);
|
||||
|
||||
const { onClose } = props;
|
||||
const handleClose = useCallback(() => {
|
||||
dismiss();
|
||||
onClose?.();
|
||||
}, [dismiss, onClose]);
|
||||
|
||||
if (wasDismissed) {
|
||||
return null;
|
||||
}
|
||||
|
||||
return <Callout {...props} onClose={handleClose} />;
|
||||
};
|
||||
154
app/javascript/mastodon/components/callout/index.tsx
Normal file
154
app/javascript/mastodon/components/callout/index.tsx
Normal file
|
|
@ -0,0 +1,154 @@
|
|||
import type { FC, ReactNode } from 'react';
|
||||
|
||||
import { useIntl } from 'react-intl';
|
||||
|
||||
import classNames from 'classnames';
|
||||
|
||||
import CheckIcon from '@/material-icons/400-24px/check.svg?react';
|
||||
import CloseIcon from '@/material-icons/400-24px/close.svg?react';
|
||||
import ErrorIcon from '@/material-icons/400-24px/error.svg?react';
|
||||
import InfoIcon from '@/material-icons/400-24px/info.svg?react';
|
||||
import WarningIcon from '@/material-icons/400-24px/warning.svg?react';
|
||||
|
||||
import type { IconProp } from '../icon';
|
||||
import { Icon } from '../icon';
|
||||
import { IconButton } from '../icon_button';
|
||||
|
||||
import classes from './styles.module.css';
|
||||
|
||||
export interface CalloutProps {
|
||||
variant?:
|
||||
| 'default'
|
||||
// | 'subtle'
|
||||
| 'feature'
|
||||
| 'inverted'
|
||||
| 'success'
|
||||
| 'warning'
|
||||
| 'error';
|
||||
title?: ReactNode;
|
||||
children: ReactNode;
|
||||
className?: string;
|
||||
/** Set to false to hide the icon. */
|
||||
icon?: IconProp | boolean;
|
||||
onPrimary?: () => void;
|
||||
primaryLabel?: string;
|
||||
onSecondary?: () => void;
|
||||
secondaryLabel?: string;
|
||||
onClose?: () => void;
|
||||
id?: string;
|
||||
extraContent?: ReactNode;
|
||||
}
|
||||
|
||||
const variantClasses = {
|
||||
default: classes.variantDefault as string,
|
||||
// subtle: classes.variantSubtle as string,
|
||||
feature: classes.variantFeature as string,
|
||||
inverted: classes.variantInverted as string,
|
||||
success: classes.variantSuccess as string,
|
||||
warning: classes.variantWarning as string,
|
||||
error: classes.variantError as string,
|
||||
} as const;
|
||||
|
||||
export const Callout: FC<CalloutProps> = ({
|
||||
className,
|
||||
variant = 'default',
|
||||
title,
|
||||
children,
|
||||
icon,
|
||||
onPrimary: primaryAction,
|
||||
primaryLabel,
|
||||
onSecondary: secondaryAction,
|
||||
secondaryLabel,
|
||||
onClose,
|
||||
extraContent,
|
||||
id,
|
||||
}) => {
|
||||
const intl = useIntl();
|
||||
|
||||
return (
|
||||
<aside
|
||||
className={classNames(
|
||||
className,
|
||||
classes.wrapper,
|
||||
variantClasses[variant],
|
||||
)}
|
||||
data-variant={variant}
|
||||
id={id}
|
||||
>
|
||||
<CalloutIcon variant={variant} icon={icon} />
|
||||
<div className={classes.content}>
|
||||
<div className={classes.body}>
|
||||
{title && <h3>{title}</h3>}
|
||||
{children}
|
||||
</div>
|
||||
|
||||
{(primaryAction ?? secondaryAction) && (
|
||||
<div className={classes.actionWrapper}>
|
||||
{secondaryAction && (
|
||||
<button
|
||||
type='button'
|
||||
onClick={secondaryAction}
|
||||
className={classes.action}
|
||||
>
|
||||
{secondaryLabel ?? 'Click'}
|
||||
</button>
|
||||
)}
|
||||
|
||||
{primaryAction && (
|
||||
<button
|
||||
type='button'
|
||||
onClick={primaryAction}
|
||||
className={classes.action}
|
||||
>
|
||||
{primaryLabel ?? 'Click'}
|
||||
</button>
|
||||
)}
|
||||
</div>
|
||||
)}
|
||||
</div>
|
||||
|
||||
{extraContent}
|
||||
|
||||
{onClose && (
|
||||
<IconButton
|
||||
icon='close'
|
||||
title={intl.formatMessage({
|
||||
id: 'callout.dismiss',
|
||||
defaultMessage: 'Dismiss',
|
||||
})}
|
||||
iconComponent={CloseIcon}
|
||||
className={classes.close}
|
||||
onClick={onClose}
|
||||
/>
|
||||
)}
|
||||
</aside>
|
||||
);
|
||||
};
|
||||
|
||||
const CalloutIcon: FC<Pick<CalloutProps, 'variant' | 'icon'>> = ({
|
||||
variant = 'default',
|
||||
icon,
|
||||
}) => {
|
||||
if (icon === false) {
|
||||
return null;
|
||||
}
|
||||
|
||||
if (!icon || icon === true) {
|
||||
switch (variant) {
|
||||
case 'inverted':
|
||||
case 'success':
|
||||
icon = CheckIcon;
|
||||
break;
|
||||
case 'warning':
|
||||
icon = WarningIcon;
|
||||
break;
|
||||
case 'error':
|
||||
icon = ErrorIcon;
|
||||
break;
|
||||
default:
|
||||
icon = InfoIcon;
|
||||
}
|
||||
}
|
||||
|
||||
return <Icon id={variant} icon={icon} className={classes.icon} />;
|
||||
};
|
||||
128
app/javascript/mastodon/components/callout/styles.module.css
Normal file
128
app/javascript/mastodon/components/callout/styles.module.css
Normal file
|
|
@ -0,0 +1,128 @@
|
|||
.wrapper {
|
||||
display: flex;
|
||||
align-items: start;
|
||||
padding: 12px;
|
||||
gap: 8px;
|
||||
background-color: var(--color-bg-brand-softer);
|
||||
color: var(--color-text-primary);
|
||||
border-radius: 12px;
|
||||
}
|
||||
|
||||
.icon {
|
||||
padding: 4px;
|
||||
border-radius: 9999px;
|
||||
width: 1rem;
|
||||
height: 1rem;
|
||||
margin-top: -2px;
|
||||
}
|
||||
|
||||
.content {
|
||||
display: flex;
|
||||
gap: 8px;
|
||||
flex-direction: column;
|
||||
flex-grow: 1;
|
||||
}
|
||||
|
||||
@media screen and (width >= 630px) {
|
||||
.content {
|
||||
flex-direction: row;
|
||||
}
|
||||
}
|
||||
|
||||
.body {
|
||||
flex-grow: 1;
|
||||
|
||||
h3 {
|
||||
font-weight: 500;
|
||||
margin-bottom: 5px;
|
||||
}
|
||||
}
|
||||
|
||||
.actionWrapper {
|
||||
display: flex;
|
||||
gap: 8px;
|
||||
align-items: start;
|
||||
}
|
||||
|
||||
.action {
|
||||
appearance: none;
|
||||
background: none;
|
||||
border: none;
|
||||
color: inherit;
|
||||
font-weight: 500;
|
||||
padding: 0;
|
||||
text-decoration: underline;
|
||||
transition: color 0.1s ease-in-out;
|
||||
|
||||
&:hover {
|
||||
color: var(--color-text-brand-soft);
|
||||
}
|
||||
}
|
||||
|
||||
@media (prefers-reduced-motion: reduce) {
|
||||
.action {
|
||||
transition: none;
|
||||
}
|
||||
}
|
||||
|
||||
.close {
|
||||
color: inherit;
|
||||
|
||||
svg {
|
||||
width: 20px;
|
||||
height: 20px;
|
||||
}
|
||||
}
|
||||
|
||||
.variantDefault {
|
||||
.icon {
|
||||
background-color: var(--color-bg-brand-soft);
|
||||
}
|
||||
}
|
||||
|
||||
/* .variantSubtle {
|
||||
border: 1px solid var(--color-bg-brand-softer);
|
||||
background-color: var(--color-bg-primary);
|
||||
|
||||
.icon {
|
||||
background-color: var(--color-bg-brand-softer);
|
||||
}
|
||||
} */
|
||||
|
||||
.variantFeature {
|
||||
background-color: var(--color-bg-brand-base);
|
||||
color: var(--color-text-on-brand-base);
|
||||
|
||||
button:hover {
|
||||
color: color-mix(var(--color-text-on-brand-base), transparent 20%);
|
||||
}
|
||||
}
|
||||
|
||||
.variantInverted {
|
||||
background-color: var(--color-bg-inverted);
|
||||
color: var(--color-text-on-inverted);
|
||||
}
|
||||
|
||||
.variantSuccess {
|
||||
background-color: var(--color-bg-success-softer);
|
||||
|
||||
.icon {
|
||||
background-color: var(--color-bg-success-soft);
|
||||
}
|
||||
}
|
||||
|
||||
.variantWarning {
|
||||
background-color: var(--color-bg-warning-softer);
|
||||
|
||||
.icon {
|
||||
background-color: var(--color-bg-warning-soft);
|
||||
}
|
||||
}
|
||||
|
||||
.variantError {
|
||||
background-color: var(--color-bg-error-softer);
|
||||
|
||||
.icon {
|
||||
background-color: var(--color-bg-error-soft);
|
||||
}
|
||||
}
|
||||
3
app/javascript/mastodon/components/form_fields/index.ts
Normal file
3
app/javascript/mastodon/components/form_fields/index.ts
Normal file
|
|
@ -0,0 +1,3 @@
|
|||
export { TextInputField } from './text_input_field';
|
||||
export { TextAreaField } from './text_area_field';
|
||||
export { SelectField } from './select_field';
|
||||
|
|
@ -0,0 +1,55 @@
|
|||
import type { Meta, StoryObj } from '@storybook/react-vite';
|
||||
|
||||
import { SelectField } from './select_field';
|
||||
|
||||
const meta = {
|
||||
title: 'Components/Form Fields/SelectField',
|
||||
component: SelectField,
|
||||
args: {
|
||||
label: 'Fruit preference',
|
||||
hint: 'Select your favourite fruit or not. Up to you.',
|
||||
},
|
||||
render(args) {
|
||||
// Component styles require a wrapper class at the moment
|
||||
return (
|
||||
<div className='simple_form'>
|
||||
<SelectField {...args}>
|
||||
<option>Apple</option>
|
||||
<option>Banana</option>
|
||||
<option>Kiwi</option>
|
||||
<option>Lemon</option>
|
||||
<option>Mango</option>
|
||||
<option>Orange</option>
|
||||
<option>Pomelo</option>
|
||||
<option>Strawberries</option>
|
||||
<option>Something else</option>
|
||||
</SelectField>
|
||||
</div>
|
||||
);
|
||||
},
|
||||
} satisfies Meta<typeof SelectField>;
|
||||
|
||||
export default meta;
|
||||
|
||||
type Story = StoryObj<typeof meta>;
|
||||
|
||||
export const Simple: Story = {};
|
||||
|
||||
export const Required: Story = {
|
||||
args: {
|
||||
required: true,
|
||||
},
|
||||
};
|
||||
|
||||
export const Optional: Story = {
|
||||
args: {
|
||||
required: false,
|
||||
},
|
||||
};
|
||||
|
||||
export const WithError: Story = {
|
||||
args: {
|
||||
required: false,
|
||||
hasError: true,
|
||||
},
|
||||
};
|
||||
|
|
@ -0,0 +1,38 @@
|
|||
import type { ComponentPropsWithoutRef } from 'react';
|
||||
import { forwardRef } from 'react';
|
||||
|
||||
import { FormFieldWrapper } from './wrapper';
|
||||
import type { CommonFieldWrapperProps } from './wrapper';
|
||||
|
||||
interface Props
|
||||
extends ComponentPropsWithoutRef<'select'>, CommonFieldWrapperProps {}
|
||||
|
||||
/**
|
||||
* A simple form field for single-item selections.
|
||||
* Provide selectable items via nested `<option>` elements.
|
||||
*
|
||||
* Accepts an optional `hint` and can be marked as required
|
||||
* or optional (by explicitly setting `required={false}`)
|
||||
*/
|
||||
|
||||
export const SelectField = forwardRef<HTMLSelectElement, Props>(
|
||||
({ id, label, hint, required, hasError, children, ...otherProps }, ref) => (
|
||||
<FormFieldWrapper
|
||||
label={label}
|
||||
hint={hint}
|
||||
required={required}
|
||||
hasError={hasError}
|
||||
inputId={id}
|
||||
>
|
||||
{(inputProps) => (
|
||||
<div className='select-wrapper'>
|
||||
<select {...otherProps} {...inputProps} ref={ref}>
|
||||
{children}
|
||||
</select>
|
||||
</div>
|
||||
)}
|
||||
</FormFieldWrapper>
|
||||
),
|
||||
);
|
||||
|
||||
SelectField.displayName = 'SelectField';
|
||||
|
|
@ -0,0 +1,45 @@
|
|||
import type { Meta, StoryObj } from '@storybook/react-vite';
|
||||
|
||||
import { TextAreaField } from './text_area_field';
|
||||
|
||||
const meta = {
|
||||
title: 'Components/Form Fields/TextAreaField',
|
||||
component: TextAreaField,
|
||||
args: {
|
||||
label: 'Label',
|
||||
hint: 'This is a description of this form field',
|
||||
},
|
||||
render(args) {
|
||||
// Component styles require a wrapper class at the moment
|
||||
return (
|
||||
<div className='simple_form'>
|
||||
<TextAreaField {...args} />
|
||||
</div>
|
||||
);
|
||||
},
|
||||
} satisfies Meta<typeof TextAreaField>;
|
||||
|
||||
export default meta;
|
||||
|
||||
type Story = StoryObj<typeof meta>;
|
||||
|
||||
export const Simple: Story = {};
|
||||
|
||||
export const Required: Story = {
|
||||
args: {
|
||||
required: true,
|
||||
},
|
||||
};
|
||||
|
||||
export const Optional: Story = {
|
||||
args: {
|
||||
required: false,
|
||||
},
|
||||
};
|
||||
|
||||
export const WithError: Story = {
|
||||
args: {
|
||||
required: false,
|
||||
hasError: true,
|
||||
},
|
||||
};
|
||||
|
|
@ -0,0 +1,31 @@
|
|||
import type { ComponentPropsWithoutRef } from 'react';
|
||||
import { forwardRef } from 'react';
|
||||
|
||||
import { FormFieldWrapper } from './wrapper';
|
||||
import type { CommonFieldWrapperProps } from './wrapper';
|
||||
|
||||
interface Props
|
||||
extends ComponentPropsWithoutRef<'textarea'>, CommonFieldWrapperProps {}
|
||||
|
||||
/**
|
||||
* A simple form field for multi-line text.
|
||||
*
|
||||
* Accepts an optional `hint` and can be marked as required
|
||||
* or optional (by explicitly setting `required={false}`)
|
||||
*/
|
||||
|
||||
export const TextAreaField = forwardRef<HTMLTextAreaElement, Props>(
|
||||
({ id, label, hint, required, hasError, ...otherProps }, ref) => (
|
||||
<FormFieldWrapper
|
||||
label={label}
|
||||
hint={hint}
|
||||
required={required}
|
||||
hasError={hasError}
|
||||
inputId={id}
|
||||
>
|
||||
{(inputProps) => <textarea {...otherProps} {...inputProps} ref={ref} />}
|
||||
</FormFieldWrapper>
|
||||
),
|
||||
);
|
||||
|
||||
TextAreaField.displayName = 'TextAreaField';
|
||||
|
|
@ -0,0 +1,45 @@
|
|||
import type { Meta, StoryObj } from '@storybook/react-vite';
|
||||
|
||||
import { TextInputField } from './text_input_field';
|
||||
|
||||
const meta = {
|
||||
title: 'Components/Form Fields/TextInputField',
|
||||
component: TextInputField,
|
||||
args: {
|
||||
label: 'Label',
|
||||
hint: 'This is a description of this form field',
|
||||
},
|
||||
render(args) {
|
||||
// Component styles require a wrapper class at the moment
|
||||
return (
|
||||
<div className='simple_form'>
|
||||
<TextInputField {...args} />
|
||||
</div>
|
||||
);
|
||||
},
|
||||
} satisfies Meta<typeof TextInputField>;
|
||||
|
||||
export default meta;
|
||||
|
||||
type Story = StoryObj<typeof meta>;
|
||||
|
||||
export const Simple: Story = {};
|
||||
|
||||
export const Required: Story = {
|
||||
args: {
|
||||
required: true,
|
||||
},
|
||||
};
|
||||
|
||||
export const Optional: Story = {
|
||||
args: {
|
||||
required: false,
|
||||
},
|
||||
};
|
||||
|
||||
export const WithError: Story = {
|
||||
args: {
|
||||
required: false,
|
||||
hasError: true,
|
||||
},
|
||||
};
|
||||
|
|
@ -0,0 +1,36 @@
|
|||
import type { ComponentPropsWithoutRef } from 'react';
|
||||
import { forwardRef } from 'react';
|
||||
|
||||
import { FormFieldWrapper } from './wrapper';
|
||||
import type { CommonFieldWrapperProps } from './wrapper';
|
||||
|
||||
interface Props
|
||||
extends ComponentPropsWithoutRef<'input'>, CommonFieldWrapperProps {}
|
||||
|
||||
/**
|
||||
* A simple form field for single-line text.
|
||||
*
|
||||
* Accepts an optional `hint` and can be marked as required
|
||||
* or optional (by explicitly setting `required={false}`)
|
||||
*/
|
||||
|
||||
export const TextInputField = forwardRef<HTMLInputElement, Props>(
|
||||
(
|
||||
{ id, label, hint, hasError, required, type = 'text', ...otherProps },
|
||||
ref,
|
||||
) => (
|
||||
<FormFieldWrapper
|
||||
label={label}
|
||||
hint={hint}
|
||||
required={required}
|
||||
hasError={hasError}
|
||||
inputId={id}
|
||||
>
|
||||
{(inputProps) => (
|
||||
<input type={type} {...otherProps} {...inputProps} ref={ref} />
|
||||
)}
|
||||
</FormFieldWrapper>
|
||||
),
|
||||
);
|
||||
|
||||
TextInputField.displayName = 'TextInputField';
|
||||
|
|
@ -0,0 +1,70 @@
|
|||
.input {
|
||||
position: absolute;
|
||||
opacity: 0;
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
margin: 0;
|
||||
cursor: pointer;
|
||||
z-index: 1;
|
||||
}
|
||||
|
||||
.toggle {
|
||||
--diameter: 20px;
|
||||
--padding: 2px;
|
||||
--transition: 0.2s ease-in-out;
|
||||
|
||||
display: inline-flex;
|
||||
align-items: center;
|
||||
border-radius: 9999px;
|
||||
width: calc(var(--diameter) * 2);
|
||||
background: var(--color-bg-tertiary);
|
||||
padding: var(--padding);
|
||||
transition: background var(--transition);
|
||||
box-sizing: border-box;
|
||||
}
|
||||
|
||||
.toggle::before {
|
||||
content: '';
|
||||
height: var(--diameter);
|
||||
width: var(--diameter);
|
||||
border-radius: 9999px;
|
||||
background: var(--color-text-on-brand-base);
|
||||
box-shadow: 0 2px 4px 0 color-mix(var(--color-black), transparent 75%);
|
||||
transition: transform var(--transition);
|
||||
}
|
||||
|
||||
@media (prefers-reduced-motion: reduce) {
|
||||
.toggle,
|
||||
.toggle::before {
|
||||
transition: none;
|
||||
}
|
||||
}
|
||||
|
||||
.input:checked + .toggle {
|
||||
background: var(--color-bg-brand-base);
|
||||
}
|
||||
|
||||
.input:checked:is(:hover, :focus) + .toggle {
|
||||
background: var(--color-bg-brand-base-hover);
|
||||
}
|
||||
|
||||
.input:focus-visible + .toggle {
|
||||
outline: var(--outline-focus-default);
|
||||
outline-offset: 2px;
|
||||
}
|
||||
|
||||
.input:checked + .toggle::before {
|
||||
transform: translateX(calc(var(--diameter) - (var(--padding) * 2)));
|
||||
}
|
||||
|
||||
.input:disabled {
|
||||
cursor: not-allowed;
|
||||
}
|
||||
|
||||
.input:disabled + .toggle {
|
||||
opacity: 0.6;
|
||||
}
|
||||
|
||||
:global([dir='rtl']) .input:checked + .toggle::before {
|
||||
transform: translateX(calc(-1 * (var(--diameter) - (var(--padding) * 2))));
|
||||
}
|
||||
|
|
@ -0,0 +1,77 @@
|
|||
import type { Meta, StoryObj } from '@storybook/react-vite';
|
||||
|
||||
import { PlainToggleField, ToggleField } from './toggle_field';
|
||||
|
||||
const meta = {
|
||||
title: 'Components/Form Fields/ToggleField',
|
||||
component: ToggleField,
|
||||
args: {
|
||||
label: 'Label',
|
||||
hint: 'This is a description of this form field',
|
||||
disabled: false,
|
||||
size: 20,
|
||||
},
|
||||
argTypes: {
|
||||
size: {
|
||||
control: { type: 'range', min: 10, max: 40, step: 1 },
|
||||
},
|
||||
},
|
||||
render(args) {
|
||||
// Component styles require a wrapper class at the moment
|
||||
return (
|
||||
<div className='simple_form'>
|
||||
<ToggleField {...args} />
|
||||
</div>
|
||||
);
|
||||
},
|
||||
} satisfies Meta<typeof ToggleField>;
|
||||
|
||||
export default meta;
|
||||
|
||||
type Story = StoryObj<typeof meta>;
|
||||
|
||||
export const Simple: Story = {};
|
||||
|
||||
export const Required: Story = {
|
||||
args: {
|
||||
required: true,
|
||||
},
|
||||
};
|
||||
|
||||
export const Optional: Story = {
|
||||
args: {
|
||||
required: false,
|
||||
},
|
||||
};
|
||||
|
||||
export const WithError: Story = {
|
||||
args: {
|
||||
required: false,
|
||||
hasError: true,
|
||||
},
|
||||
};
|
||||
|
||||
export const Disabled: Story = {
|
||||
args: {
|
||||
disabled: true,
|
||||
checked: true,
|
||||
},
|
||||
};
|
||||
|
||||
export const Plain: Story = {
|
||||
render(props) {
|
||||
return <PlainToggleField {...props} />;
|
||||
},
|
||||
};
|
||||
|
||||
export const Small: Story = {
|
||||
args: {
|
||||
size: 12,
|
||||
},
|
||||
};
|
||||
|
||||
export const Large: Story = {
|
||||
args: {
|
||||
size: 36,
|
||||
},
|
||||
};
|
||||
|
|
@ -0,0 +1,52 @@
|
|||
import type { ComponentPropsWithoutRef, CSSProperties } from 'react';
|
||||
import { forwardRef } from 'react';
|
||||
|
||||
import classNames from 'classnames';
|
||||
|
||||
import classes from './toggle.module.css';
|
||||
import type { CommonFieldWrapperProps } from './wrapper';
|
||||
import { FormFieldWrapper } from './wrapper';
|
||||
|
||||
type Props = Omit<ComponentPropsWithoutRef<'input'>, 'type'> & {
|
||||
size?: number;
|
||||
};
|
||||
|
||||
export const ToggleField = forwardRef<
|
||||
HTMLInputElement,
|
||||
Props & CommonFieldWrapperProps
|
||||
>(({ id, label, hint, hasError, required, ...otherProps }, ref) => (
|
||||
<FormFieldWrapper
|
||||
label={label}
|
||||
hint={hint}
|
||||
required={required}
|
||||
hasError={hasError}
|
||||
inputId={id}
|
||||
>
|
||||
{(inputProps) => (
|
||||
<PlainToggleField {...otherProps} {...inputProps} ref={ref} />
|
||||
)}
|
||||
</FormFieldWrapper>
|
||||
));
|
||||
|
||||
ToggleField.displayName = 'ToggleField';
|
||||
|
||||
export const PlainToggleField = forwardRef<HTMLInputElement, Props>(
|
||||
({ className, size, ...otherProps }, ref) => (
|
||||
<>
|
||||
<input
|
||||
{...otherProps}
|
||||
type='checkbox'
|
||||
className={classes.input}
|
||||
ref={ref}
|
||||
/>
|
||||
<span
|
||||
className={classNames(classes.toggle, className)}
|
||||
style={
|
||||
{ '--diameter': size ? `${size}px` : undefined } as CSSProperties
|
||||
}
|
||||
hidden
|
||||
/>
|
||||
</>
|
||||
),
|
||||
);
|
||||
PlainToggleField.displayName = 'PlainToggleField';
|
||||
100
app/javascript/mastodon/components/form_fields/wrapper.tsx
Normal file
100
app/javascript/mastodon/components/form_fields/wrapper.tsx
Normal file
|
|
@ -0,0 +1,100 @@
|
|||
/* eslint-disable @typescript-eslint/prefer-nullish-coalescing */
|
||||
|
||||
import type { ReactNode, FC } from 'react';
|
||||
import { useId } from 'react';
|
||||
|
||||
import { FormattedMessage } from 'react-intl';
|
||||
|
||||
import classNames from 'classnames';
|
||||
|
||||
interface InputProps {
|
||||
id: string;
|
||||
required?: boolean;
|
||||
'aria-describedby'?: string;
|
||||
}
|
||||
|
||||
interface FieldWrapperProps {
|
||||
label: ReactNode;
|
||||
hint?: ReactNode;
|
||||
required?: boolean;
|
||||
hasError?: boolean;
|
||||
inputId?: string;
|
||||
children: (inputProps: InputProps) => ReactNode;
|
||||
}
|
||||
|
||||
/**
|
||||
* These types can be extended when creating individual field components.
|
||||
*/
|
||||
export type CommonFieldWrapperProps = Pick<
|
||||
FieldWrapperProps,
|
||||
'label' | 'hint' | 'hasError'
|
||||
>;
|
||||
|
||||
/**
|
||||
* A simple form field wrapper for adding a label and hint to enclosed components.
|
||||
* Accepts an optional `hint` and can be marked as required
|
||||
* or optional (by explicitly setting `required={false}`)
|
||||
*/
|
||||
|
||||
export const FormFieldWrapper: FC<FieldWrapperProps> = ({
|
||||
inputId: inputIdProp,
|
||||
label,
|
||||
hint,
|
||||
required,
|
||||
hasError,
|
||||
children,
|
||||
}) => {
|
||||
const uniqueId = useId();
|
||||
const inputId = inputIdProp || `${uniqueId}-input`;
|
||||
const hintId = `${inputIdProp || uniqueId}-hint`;
|
||||
const hasHint = !!hint;
|
||||
|
||||
const inputProps: InputProps = {
|
||||
required,
|
||||
id: inputId,
|
||||
};
|
||||
if (hasHint) {
|
||||
inputProps['aria-describedby'] = hintId;
|
||||
}
|
||||
|
||||
return (
|
||||
<div
|
||||
className={classNames('input with_block_label', {
|
||||
field_with_errors: hasError,
|
||||
})}
|
||||
>
|
||||
<div className='label_input'>
|
||||
<label htmlFor={inputId}>
|
||||
{label}
|
||||
{required !== undefined && <RequiredMark required={required} />}
|
||||
</label>
|
||||
|
||||
{hasHint && (
|
||||
<span className='hint' id={hintId}>
|
||||
{hint}
|
||||
</span>
|
||||
)}
|
||||
|
||||
<div className='label_input__wrapper'>{children(inputProps)}</div>
|
||||
</div>
|
||||
</div>
|
||||
);
|
||||
};
|
||||
|
||||
/**
|
||||
* If `required` is explicitly set to `false` rather than `undefined`,
|
||||
* the field will be visually marked as "optional".
|
||||
*/
|
||||
|
||||
const RequiredMark: FC<{ required?: boolean }> = ({ required }) =>
|
||||
required ? (
|
||||
<>
|
||||
{' '}
|
||||
<abbr aria-hidden='true'>*</abbr>
|
||||
</>
|
||||
) : (
|
||||
<>
|
||||
{' '}
|
||||
<FormattedMessage id='form_field.optional' defaultMessage='(optional)' />
|
||||
</>
|
||||
);
|
||||
|
|
@ -13,6 +13,7 @@ interface Props extends React.SVGProps<SVGSVGElement> {
|
|||
children?: never;
|
||||
id: string;
|
||||
icon: IconProp;
|
||||
noFill?: boolean;
|
||||
}
|
||||
|
||||
export const Icon: React.FC<Props> = ({
|
||||
|
|
@ -20,6 +21,7 @@ export const Icon: React.FC<Props> = ({
|
|||
icon: IconComponent,
|
||||
className,
|
||||
'aria-label': ariaLabel,
|
||||
noFill = false,
|
||||
...other
|
||||
}) => {
|
||||
// eslint-disable-next-line @typescript-eslint/no-unnecessary-condition
|
||||
|
|
@ -42,7 +44,12 @@ export const Icon: React.FC<Props> = ({
|
|||
|
||||
return (
|
||||
<IconComponent
|
||||
className={classNames('icon', `icon-${id}`, className)}
|
||||
className={classNames(
|
||||
'icon',
|
||||
`icon-${id}`,
|
||||
noFill && 'icon--no-fill',
|
||||
className,
|
||||
)}
|
||||
title={title}
|
||||
aria-hidden={ariaHidden}
|
||||
aria-label={ariaLabel}
|
||||
|
|
|
|||
|
|
@ -44,8 +44,7 @@ export const DomainPill: React.FC<{
|
|||
aria-controls={accessibilityId}
|
||||
type='button'
|
||||
>
|
||||
{domain}
|
||||
{children}
|
||||
{children ?? domain}
|
||||
</button>
|
||||
|
||||
<Overlay
|
||||
|
|
|
|||
|
|
@ -24,6 +24,7 @@ import { AccountHeaderFields } from './fields';
|
|||
import { AccountInfo } from './info';
|
||||
import { MemorialNote } from './memorial_note';
|
||||
import { MovedNote } from './moved_note';
|
||||
import { AccountNote as AccountNoteRedesign } from './note';
|
||||
import { AccountNumberFields } from './number_fields';
|
||||
import redesignClasses from './redesign.module.scss';
|
||||
import { AccountTabs } from './tabs';
|
||||
|
|
@ -142,12 +143,7 @@ export const AccountHeader: React.FC<{
|
|||
isRedesignEnabled() && redesignClasses.nameWrapper,
|
||||
)}
|
||||
>
|
||||
<AccountName
|
||||
accountId={accountId}
|
||||
className={classNames(
|
||||
isRedesignEnabled() && redesignClasses.name,
|
||||
)}
|
||||
/>
|
||||
<AccountName accountId={accountId} />
|
||||
{isRedesignEnabled() && <AccountButtons accountId={accountId} />}
|
||||
</div>
|
||||
|
||||
|
|
@ -166,7 +162,9 @@ export const AccountHeader: React.FC<{
|
|||
{!suspendedOrHidden && (
|
||||
<div className='account__header__extra'>
|
||||
<div className='account__header__bio'>
|
||||
{me && account.id !== me && (
|
||||
{me && account.id !== me && isRedesignEnabled() ? (
|
||||
<AccountNoteRedesign accountId={accountId} />
|
||||
) : (
|
||||
<AccountNote accountId={accountId} />
|
||||
)}
|
||||
|
||||
|
|
|
|||
|
|
@ -6,7 +6,7 @@ import { DisplayName } from '@/mastodon/components/display_name';
|
|||
import { Icon } from '@/mastodon/components/icon';
|
||||
import { useAccount } from '@/mastodon/hooks/useAccount';
|
||||
import { useAppSelector } from '@/mastodon/store';
|
||||
import InfoIcon from '@/material-icons/400-24px/info.svg?react';
|
||||
import HelpIcon from '@/material-icons/400-24px/help.svg?react';
|
||||
import LockIcon from '@/material-icons/400-24px/lock.svg?react';
|
||||
|
||||
import { DomainPill } from '../../account/components/domain_pill';
|
||||
|
|
@ -14,10 +14,7 @@ import { isRedesignEnabled } from '../common';
|
|||
|
||||
import classes from './redesign.module.scss';
|
||||
|
||||
export const AccountName: FC<{ accountId: string; className?: string }> = ({
|
||||
accountId,
|
||||
className,
|
||||
}) => {
|
||||
export const AccountName: FC<{ accountId: string }> = ({ accountId }) => {
|
||||
const intl = useIntl();
|
||||
const account = useAccount(accountId);
|
||||
const me = useAppSelector((state) => state.meta.get('me') as string);
|
||||
|
|
@ -31,38 +28,52 @@ export const AccountName: FC<{ accountId: string; className?: string }> = ({
|
|||
|
||||
const [username = '', domain = localDomain] = account.acct.split('@');
|
||||
|
||||
return (
|
||||
<h1 className={className}>
|
||||
<DisplayName account={account} variant='simple' />
|
||||
<small>
|
||||
<span>
|
||||
@{username}
|
||||
{isRedesignEnabled() && '@'}
|
||||
<span className='invisible'>
|
||||
{!isRedesignEnabled() && '@'}
|
||||
{domain}
|
||||
if (!isRedesignEnabled()) {
|
||||
return (
|
||||
<h1>
|
||||
<DisplayName account={account} variant='simple' />
|
||||
<small>
|
||||
<span>
|
||||
@{username}
|
||||
<span className='invisible'>@{domain}</span>
|
||||
</span>
|
||||
</span>
|
||||
<DomainPill
|
||||
username={username}
|
||||
domain={domain}
|
||||
isSelf={me === account.id}
|
||||
/>
|
||||
{account.locked && (
|
||||
<Icon
|
||||
id='lock'
|
||||
icon={LockIcon}
|
||||
aria-label={intl.formatMessage({
|
||||
id: 'account.locked_info',
|
||||
defaultMessage:
|
||||
'This account privacy status is set to locked. The owner manually reviews who can follow them.',
|
||||
})}
|
||||
/>
|
||||
)}
|
||||
</small>
|
||||
</h1>
|
||||
);
|
||||
}
|
||||
|
||||
return (
|
||||
<div className={classes.name}>
|
||||
<h1>
|
||||
<DisplayName account={account} variant='simple' />
|
||||
</h1>
|
||||
<p className={classes.username}>
|
||||
@{username}@{domain}
|
||||
<DomainPill
|
||||
username={username}
|
||||
domain={domain}
|
||||
isSelf={me === account.id}
|
||||
className={(isRedesignEnabled() && classes.domainPill) || ''}
|
||||
className={classes.domainPill}
|
||||
>
|
||||
{isRedesignEnabled() && <Icon id='info' icon={InfoIcon} />}
|
||||
<Icon id='help' icon={HelpIcon} />
|
||||
</DomainPill>
|
||||
{!isRedesignEnabled() && account.locked && (
|
||||
<Icon
|
||||
id='lock'
|
||||
icon={LockIcon}
|
||||
aria-label={intl.formatMessage({
|
||||
id: 'account.locked_info',
|
||||
defaultMessage:
|
||||
'This account privacy status is set to locked. The owner manually reviews who can follow them.',
|
||||
})}
|
||||
/>
|
||||
)}
|
||||
</small>
|
||||
</h1>
|
||||
</p>
|
||||
</div>
|
||||
);
|
||||
};
|
||||
|
|
|
|||
|
|
@ -37,7 +37,12 @@ export const AccountBadges: FC<{ accountId: string }> = ({ accountId }) => {
|
|||
let icon: ReactNode = undefined;
|
||||
if (isAdminBadge(role)) {
|
||||
icon = (
|
||||
<Icon icon={IconAdmin} id='badge-admin' className={classes.badgeIcon} />
|
||||
<Icon
|
||||
icon={IconAdmin}
|
||||
id='badge-admin'
|
||||
className={classes.badgeIcon}
|
||||
noFill
|
||||
/>
|
||||
);
|
||||
}
|
||||
badges.push(
|
||||
|
|
|
|||
|
|
@ -76,6 +76,7 @@ const RedesignAccountHeaderFields: FC<{ account: Account }> = ({ account }) => {
|
|||
id='verified'
|
||||
icon={IconVerified}
|
||||
className={classes.fieldIconVerified}
|
||||
noFill
|
||||
/>
|
||||
)}
|
||||
</>
|
||||
|
|
|
|||
|
|
@ -81,6 +81,7 @@ export const AccountFieldsModal: FC<{
|
|||
id='verified'
|
||||
icon={IconVerified}
|
||||
className={classes.fieldIconVerified}
|
||||
noFill
|
||||
/>
|
||||
)}
|
||||
</dd>
|
||||
|
|
|
|||
|
|
@ -31,6 +31,8 @@ import {
|
|||
import { useAppDispatch, useAppSelector } from '@/mastodon/store';
|
||||
import MoreHorizIcon from '@/material-icons/400-24px/more_horiz.svg?react';
|
||||
|
||||
import { isRedesignEnabled } from '../common';
|
||||
|
||||
const messages = defineMessages({
|
||||
unblock: { id: 'account.unblock', defaultMessage: 'Unblock @{name}' },
|
||||
mention: { id: 'account.mention', defaultMessage: 'Mention @{name}' },
|
||||
|
|
@ -55,6 +57,14 @@ const messages = defineMessages({
|
|||
id: 'account.show_reblogs',
|
||||
defaultMessage: 'Show boosts from @{name}',
|
||||
},
|
||||
addNote: {
|
||||
id: 'account.add_note',
|
||||
defaultMessage: 'Add a personal note',
|
||||
},
|
||||
editNote: {
|
||||
id: 'account.edit_note',
|
||||
defaultMessage: 'Edit personal note',
|
||||
},
|
||||
endorse: { id: 'account.endorse', defaultMessage: 'Feature on profile' },
|
||||
unendorse: {
|
||||
id: 'account.unendorse',
|
||||
|
|
@ -187,7 +197,30 @@ export const AccountMenu: FC<{ accountId: string }> = ({ accountId }) => {
|
|||
});
|
||||
arr.push(null);
|
||||
}
|
||||
}
|
||||
|
||||
if (isRedesignEnabled()) {
|
||||
arr.push({
|
||||
text: intl.formatMessage(
|
||||
relationship?.note ? messages.editNote : messages.addNote,
|
||||
),
|
||||
action: () => {
|
||||
dispatch(
|
||||
openModal({
|
||||
modalType: 'ACCOUNT_NOTE',
|
||||
modalProps: {
|
||||
accountId: account.id,
|
||||
},
|
||||
}),
|
||||
);
|
||||
},
|
||||
});
|
||||
if (!relationship?.following) {
|
||||
arr.push(null);
|
||||
}
|
||||
}
|
||||
|
||||
if (relationship?.following) {
|
||||
arr.push({
|
||||
text: intl.formatMessage(
|
||||
relationship.endorsed ? messages.unendorse : messages.endorse,
|
||||
|
|
|
|||
|
|
@ -0,0 +1,69 @@
|
|||
import { useCallback, useEffect } from 'react';
|
||||
import type { FC } from 'react';
|
||||
|
||||
import { defineMessages, useIntl } from 'react-intl';
|
||||
|
||||
import { fetchRelationships } from '@/mastodon/actions/accounts';
|
||||
import { openModal } from '@/mastodon/actions/modal';
|
||||
import { Callout } from '@/mastodon/components/callout';
|
||||
import { IconButton } from '@/mastodon/components/icon_button';
|
||||
import { useAppDispatch, useAppSelector } from '@/mastodon/store';
|
||||
import EditIcon from '@/material-icons/400-24px/edit_square.svg?react';
|
||||
|
||||
import classes from './redesign.module.scss';
|
||||
|
||||
const messages = defineMessages({
|
||||
title: {
|
||||
id: 'account.note.title',
|
||||
defaultMessage: 'Personal note (visible only to you)',
|
||||
},
|
||||
editButton: {
|
||||
id: 'account.note.edit_button',
|
||||
defaultMessage: 'Edit',
|
||||
},
|
||||
});
|
||||
|
||||
export const AccountNote: FC<{ accountId: string }> = ({ accountId }) => {
|
||||
const intl = useIntl();
|
||||
const relationship = useAppSelector((state) =>
|
||||
state.relationships.get(accountId),
|
||||
);
|
||||
const dispatch = useAppDispatch();
|
||||
useEffect(() => {
|
||||
if (!relationship) {
|
||||
dispatch(fetchRelationships([accountId]));
|
||||
}
|
||||
}, [accountId, dispatch, relationship]);
|
||||
|
||||
const handleEdit = useCallback(() => {
|
||||
dispatch(
|
||||
openModal({
|
||||
modalType: 'ACCOUNT_NOTE',
|
||||
modalProps: { accountId },
|
||||
}),
|
||||
);
|
||||
}, [accountId, dispatch]);
|
||||
|
||||
if (!relationship?.note) {
|
||||
return null;
|
||||
}
|
||||
|
||||
return (
|
||||
<Callout
|
||||
icon={false}
|
||||
title={intl.formatMessage(messages.title)}
|
||||
className={classes.note}
|
||||
extraContent={
|
||||
<IconButton
|
||||
icon='edit'
|
||||
iconComponent={EditIcon}
|
||||
title={intl.formatMessage(messages.editButton)}
|
||||
className={classes.noteEditButton}
|
||||
onClick={handleEdit}
|
||||
/>
|
||||
}
|
||||
>
|
||||
{relationship.note}
|
||||
</Callout>
|
||||
);
|
||||
};
|
||||
|
|
@ -7,20 +7,16 @@
|
|||
flex-grow: 1;
|
||||
font-size: 22px;
|
||||
white-space: initial;
|
||||
text-overflow: initial;
|
||||
line-height: normal;
|
||||
|
||||
:global(.icon-info) {
|
||||
margin-left: 2px;
|
||||
width: 1em;
|
||||
height: 1em;
|
||||
align-self: center;
|
||||
}
|
||||
}
|
||||
|
||||
// Overrides .account__header__tabs__name h1 small
|
||||
h1.name > small {
|
||||
gap: 0;
|
||||
.username {
|
||||
display: flex;
|
||||
font-size: 13px;
|
||||
color: var(--color-text-secondary);
|
||||
align-items: center;
|
||||
user-select: all;
|
||||
margin-top: 4px;
|
||||
}
|
||||
|
||||
.domainPill {
|
||||
|
|
@ -32,10 +28,20 @@ h1.name > small {
|
|||
color: inherit;
|
||||
font-size: 1em;
|
||||
font-weight: initial;
|
||||
margin-left: 2px;
|
||||
width: 16px;
|
||||
height: 16px;
|
||||
transition: color 0.2s ease-in-out;
|
||||
|
||||
> svg {
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
}
|
||||
|
||||
&:hover,
|
||||
&:global(.active) {
|
||||
background: none;
|
||||
color: inherit;
|
||||
color: var(--color-text-brand-soft);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -53,10 +59,18 @@ h1.name > small {
|
|||
|
||||
svg.badgeIcon {
|
||||
opacity: 1;
|
||||
fill: revert-layer;
|
||||
}
|
||||
|
||||
path {
|
||||
fill: revert-layer;
|
||||
.note {
|
||||
margin-bottom: 16px;
|
||||
}
|
||||
|
||||
.noteEditButton {
|
||||
color: inherit;
|
||||
|
||||
svg {
|
||||
width: 20px;
|
||||
height: 20px;
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -90,11 +104,6 @@ svg.badgeIcon {
|
|||
.fieldIconVerified {
|
||||
width: 1rem;
|
||||
height: 1rem;
|
||||
|
||||
// Need to override .icon path.
|
||||
path {
|
||||
fill: revert-layer;
|
||||
}
|
||||
}
|
||||
|
||||
.fieldNumbersWrapper {
|
||||
|
|
|
|||
|
|
@ -0,0 +1,21 @@
|
|||
.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;
|
||||
}
|
||||
|
|
@ -0,0 +1,160 @@
|
|||
import { useCallback, useEffect, useRef, useState } from 'react';
|
||||
import type { ChangeEventHandler, FC } from 'react';
|
||||
|
||||
import { defineMessages, FormattedMessage, useIntl } from 'react-intl';
|
||||
|
||||
import { submitAccountNote } from '@/mastodon/actions/account_notes';
|
||||
import { fetchRelationships } from '@/mastodon/actions/accounts';
|
||||
import { Callout } from '@/mastodon/components/callout';
|
||||
import { TextAreaField } from '@/mastodon/components/form_fields';
|
||||
import { LoadingIndicator } from '@/mastodon/components/loading_indicator';
|
||||
import type { Relationship } from '@/mastodon/models/relationship';
|
||||
import { useAppDispatch, useAppSelector } from '@/mastodon/store';
|
||||
|
||||
import { ConfirmationModal } from '../../ui/components/confirmation_modals';
|
||||
|
||||
import classes from './modals.module.css';
|
||||
|
||||
const messages = defineMessages({
|
||||
newTitle: {
|
||||
id: 'account.node_modal.title',
|
||||
defaultMessage: 'Add a personal note',
|
||||
},
|
||||
editTitle: {
|
||||
id: 'account.node_modal.edit_title',
|
||||
defaultMessage: 'Edit personal note',
|
||||
},
|
||||
save: {
|
||||
id: 'account.node_modal.save',
|
||||
defaultMessage: 'Save',
|
||||
},
|
||||
fieldLabel: {
|
||||
id: 'account.node_modal.field_label',
|
||||
defaultMessage: 'Personal Note',
|
||||
},
|
||||
errorUnknown: {
|
||||
id: 'account.node_modal.error_unknown',
|
||||
defaultMessage: 'Could not save the note',
|
||||
},
|
||||
});
|
||||
|
||||
export const AccountNoteModal: FC<{
|
||||
accountId: string;
|
||||
onClose: () => void;
|
||||
}> = ({ accountId, onClose }) => {
|
||||
const relationship = useAppSelector((state) =>
|
||||
state.relationships.get(accountId),
|
||||
);
|
||||
const dispatch = useAppDispatch();
|
||||
useEffect(() => {
|
||||
if (!relationship) {
|
||||
dispatch(fetchRelationships([accountId]));
|
||||
}
|
||||
}, [accountId, dispatch, relationship]);
|
||||
|
||||
if (!relationship) {
|
||||
return <LoadingIndicator />;
|
||||
}
|
||||
|
||||
return (
|
||||
<InnerNodeModal
|
||||
relationship={relationship}
|
||||
accountId={accountId}
|
||||
onClose={onClose}
|
||||
/>
|
||||
);
|
||||
};
|
||||
|
||||
const InnerNodeModal: FC<{
|
||||
relationship: Relationship;
|
||||
accountId: string;
|
||||
onClose: () => void;
|
||||
}> = ({ relationship, accountId, onClose }) => {
|
||||
// Set up the state.
|
||||
const initialContents = relationship.note;
|
||||
const [note, setNote] = useState(initialContents);
|
||||
const [errorText, setErrorText] = useState('');
|
||||
const [state, setState] = useState<'idle' | 'saving' | 'error'>('idle');
|
||||
const isDirty = note !== initialContents;
|
||||
|
||||
const handleChange: ChangeEventHandler<HTMLTextAreaElement> = useCallback(
|
||||
(e) => {
|
||||
if (state !== 'saving') {
|
||||
setNote(e.target.value);
|
||||
}
|
||||
},
|
||||
[state],
|
||||
);
|
||||
|
||||
const intl = useIntl();
|
||||
|
||||
// Create an abort controller to cancel the request if the modal is closed.
|
||||
const abortController = useRef(new AbortController());
|
||||
const dispatch = useAppDispatch();
|
||||
const handleSave = useCallback(() => {
|
||||
if (state === 'saving' || !isDirty) {
|
||||
return;
|
||||
}
|
||||
setState('saving');
|
||||
dispatch(
|
||||
submitAccountNote(
|
||||
{ accountId, note },
|
||||
{ signal: abortController.current.signal },
|
||||
),
|
||||
)
|
||||
.then(() => {
|
||||
setState('idle');
|
||||
onClose();
|
||||
})
|
||||
.catch((err: unknown) => {
|
||||
setState('error');
|
||||
if (err instanceof Error) {
|
||||
setErrorText(err.message);
|
||||
} else {
|
||||
setErrorText(intl.formatMessage(messages.errorUnknown));
|
||||
}
|
||||
});
|
||||
}, [accountId, dispatch, intl, isDirty, note, onClose, state]);
|
||||
|
||||
const handleCancel = useCallback(() => {
|
||||
abortController.current.abort();
|
||||
onClose();
|
||||
}, [onClose]);
|
||||
|
||||
return (
|
||||
<ConfirmationModal
|
||||
title={
|
||||
initialContents
|
||||
? intl.formatMessage(messages.editTitle)
|
||||
: intl.formatMessage(messages.newTitle)
|
||||
}
|
||||
extraContent={
|
||||
<>
|
||||
<Callout className={classes.noteCallout}>
|
||||
<FormattedMessage
|
||||
id='account.node_modal.callout'
|
||||
defaultMessage='Personal notes are visible only to you.'
|
||||
/>
|
||||
</Callout>
|
||||
<TextAreaField
|
||||
value={note}
|
||||
onChange={handleChange}
|
||||
label={intl.formatMessage(messages.fieldLabel)}
|
||||
className={classes.noteInput}
|
||||
hasError={state === 'error'}
|
||||
hint={errorText}
|
||||
// eslint-disable-next-line jsx-a11y/no-autofocus -- We want to focus here as it's a modal.
|
||||
autoFocus
|
||||
/>
|
||||
</>
|
||||
}
|
||||
onClose={handleCancel}
|
||||
confirm={intl.formatMessage(messages.save)}
|
||||
onConfirm={handleSave}
|
||||
updating={state === 'saving'}
|
||||
disabled={!isDirty}
|
||||
closeWhenConfirm={false}
|
||||
noFocusButton
|
||||
/>
|
||||
);
|
||||
};
|
||||
179
app/javascript/mastodon/features/collections/index.tsx
Normal file
179
app/javascript/mastodon/features/collections/index.tsx
Normal file
|
|
@ -0,0 +1,179 @@
|
|||
import { useEffect, useMemo, useCallback } from 'react';
|
||||
|
||||
import { defineMessages, useIntl, FormattedMessage } from 'react-intl';
|
||||
|
||||
import { Helmet } from 'react-helmet';
|
||||
import { Link } from 'react-router-dom';
|
||||
|
||||
import AddIcon from '@/material-icons/400-24px/add.svg?react';
|
||||
import ListAltIcon from '@/material-icons/400-24px/list_alt.svg?react';
|
||||
import MoreHorizIcon from '@/material-icons/400-24px/more_horiz.svg?react';
|
||||
import SquigglyArrow from '@/svg-icons/squiggly_arrow.svg?react';
|
||||
import { openModal } from 'mastodon/actions/modal';
|
||||
import { Column } from 'mastodon/components/column';
|
||||
import { ColumnHeader } from 'mastodon/components/column_header';
|
||||
import { Dropdown } from 'mastodon/components/dropdown_menu';
|
||||
import { Icon } from 'mastodon/components/icon';
|
||||
import ScrollableList from 'mastodon/components/scrollable_list';
|
||||
import {
|
||||
createCollection,
|
||||
fetchAccountCollections,
|
||||
selectMyCollections,
|
||||
} from 'mastodon/reducers/slices/collections';
|
||||
import { useAppSelector, useAppDispatch } from 'mastodon/store';
|
||||
|
||||
const messages = defineMessages({
|
||||
heading: { id: 'column.collections', defaultMessage: 'My collections' },
|
||||
create: {
|
||||
id: 'collections.create_collection',
|
||||
defaultMessage: 'Create collection',
|
||||
},
|
||||
view: {
|
||||
id: 'collections.view_collection',
|
||||
defaultMessage: 'View collection',
|
||||
},
|
||||
delete: {
|
||||
id: 'collections.delete_collection',
|
||||
defaultMessage: 'Delete collection',
|
||||
},
|
||||
more: { id: 'status.more', defaultMessage: 'More' },
|
||||
});
|
||||
|
||||
const ListItem: React.FC<{
|
||||
id: string;
|
||||
name: string;
|
||||
}> = ({ id, name }) => {
|
||||
const dispatch = useAppDispatch();
|
||||
const intl = useIntl();
|
||||
|
||||
const handleDeleteClick = useCallback(() => {
|
||||
dispatch(
|
||||
openModal({
|
||||
modalType: 'CONFIRM_DELETE_LIST',
|
||||
modalProps: {
|
||||
listId: id,
|
||||
},
|
||||
}),
|
||||
);
|
||||
}, [dispatch, id]);
|
||||
|
||||
const menu = useMemo(
|
||||
() => [
|
||||
{ text: intl.formatMessage(messages.view), to: `/collections/${id}` },
|
||||
{ text: intl.formatMessage(messages.delete), action: handleDeleteClick },
|
||||
],
|
||||
[intl, id, handleDeleteClick],
|
||||
);
|
||||
|
||||
return (
|
||||
<div className='lists__item'>
|
||||
<Link to={`/collections/${id}`} className='lists__item__title'>
|
||||
<span>{name}</span>
|
||||
</Link>
|
||||
|
||||
<Dropdown
|
||||
scrollKey='collections'
|
||||
items={menu}
|
||||
icon='ellipsis-h'
|
||||
iconComponent={MoreHorizIcon}
|
||||
title={intl.formatMessage(messages.more)}
|
||||
/>
|
||||
</div>
|
||||
);
|
||||
};
|
||||
|
||||
export const Collections: React.FC<{
|
||||
multiColumn?: boolean;
|
||||
}> = ({ multiColumn }) => {
|
||||
const dispatch = useAppDispatch();
|
||||
const intl = useIntl();
|
||||
const me = useAppSelector((state) => state.meta.get('me') as string);
|
||||
const { collections, status } = useAppSelector(selectMyCollections);
|
||||
|
||||
useEffect(() => {
|
||||
void dispatch(fetchAccountCollections({ accountId: me }));
|
||||
}, [dispatch, me]);
|
||||
|
||||
const addDummyCollection = useCallback(
|
||||
(event: React.MouseEvent) => {
|
||||
event.preventDefault();
|
||||
|
||||
void dispatch(
|
||||
createCollection({
|
||||
payload: {
|
||||
name: 'Test Collection',
|
||||
description: 'A useful test collection',
|
||||
discoverable: true,
|
||||
sensitive: false,
|
||||
},
|
||||
}),
|
||||
);
|
||||
},
|
||||
[dispatch],
|
||||
);
|
||||
|
||||
const emptyMessage =
|
||||
status === 'error' ? (
|
||||
<FormattedMessage
|
||||
id='collections.error_loading_collections'
|
||||
defaultMessage='There was an error when trying to load your collections.'
|
||||
/>
|
||||
) : (
|
||||
<>
|
||||
<span>
|
||||
<FormattedMessage
|
||||
id='collections.no_collections_yet'
|
||||
defaultMessage='No collections yet.'
|
||||
/>
|
||||
<br />
|
||||
<FormattedMessage
|
||||
id='collections.create_a_collection_hint'
|
||||
defaultMessage='Create a collection to recommend or share your favourite accounts with others.'
|
||||
/>
|
||||
</span>
|
||||
|
||||
<SquigglyArrow className='empty-column-indicator__arrow' />
|
||||
</>
|
||||
);
|
||||
|
||||
return (
|
||||
<Column
|
||||
bindToDocument={!multiColumn}
|
||||
label={intl.formatMessage(messages.heading)}
|
||||
>
|
||||
<ColumnHeader
|
||||
title={intl.formatMessage(messages.heading)}
|
||||
icon='list-ul'
|
||||
iconComponent={ListAltIcon}
|
||||
multiColumn={multiColumn}
|
||||
extraButton={
|
||||
<Link
|
||||
to='/collections/new'
|
||||
className='column-header__button'
|
||||
title={intl.formatMessage(messages.create)}
|
||||
aria-label={intl.formatMessage(messages.create)}
|
||||
onClick={addDummyCollection}
|
||||
>
|
||||
<Icon id='plus' icon={AddIcon} />
|
||||
</Link>
|
||||
}
|
||||
/>
|
||||
|
||||
<ScrollableList
|
||||
scrollKey='collections'
|
||||
emptyMessage={emptyMessage}
|
||||
isLoading={status === 'loading'}
|
||||
bindToDocument={!multiColumn}
|
||||
>
|
||||
{collections.map((item) => (
|
||||
<ListItem key={item.id} id={item.id} name={item.name} />
|
||||
))}
|
||||
</ScrollableList>
|
||||
|
||||
<Helmet>
|
||||
<title>{intl.formatMessage(messages.heading)}</title>
|
||||
<meta name='robots' content='noindex' />
|
||||
</Helmet>
|
||||
</Column>
|
||||
);
|
||||
};
|
||||
11
app/javascript/mastodon/features/collections/utils.ts
Normal file
11
app/javascript/mastodon/features/collections/utils.ts
Normal file
|
|
@ -0,0 +1,11 @@
|
|||
import {
|
||||
isClientFeatureEnabled,
|
||||
isServerFeatureEnabled,
|
||||
} from '@/mastodon/utils/environment';
|
||||
|
||||
export function areCollectionsEnabled() {
|
||||
return (
|
||||
isClientFeatureEnabled('collections') &&
|
||||
isServerFeatureEnabled('collections')
|
||||
);
|
||||
}
|
||||
|
|
@ -10,8 +10,8 @@ import { useSortable } from '@dnd-kit/sortable';
|
|||
import { CSS } from '@dnd-kit/utilities';
|
||||
|
||||
import CloseIcon from '@/material-icons/400-20px/close.svg?react';
|
||||
import SoundIcon from '@/material-icons/400-24px/audio.svg?react';
|
||||
import EditIcon from '@/material-icons/400-24px/edit.svg?react';
|
||||
import SoundIcon from '@/material-icons/400-24px/graphic_eq.svg?react';
|
||||
import WarningIcon from '@/material-icons/400-24px/warning.svg?react';
|
||||
import { undoUploadCompose } from 'mastodon/actions/compose';
|
||||
import { openModal } from 'mastodon/actions/modal';
|
||||
|
|
|
|||
|
|
@ -20,6 +20,7 @@ import { Avatar } from 'mastodon/components/avatar';
|
|||
import { AvatarGroup } from 'mastodon/components/avatar_group';
|
||||
import { Column } from 'mastodon/components/column';
|
||||
import { ColumnHeader } from 'mastodon/components/column_header';
|
||||
import { SelectField, TextInputField } from 'mastodon/components/form_fields';
|
||||
import { Icon } from 'mastodon/components/icon';
|
||||
import { LoadingIndicator } from 'mastodon/components/loading_indicator';
|
||||
import type { List } from 'mastodon/models/list';
|
||||
|
|
@ -149,68 +150,49 @@ const NewList: React.FC<{ list?: List | null }> = ({ list }) => {
|
|||
return (
|
||||
<form className='simple_form app-form' onSubmit={handleSubmit}>
|
||||
<div className='fields-group'>
|
||||
<div className='input with_label'>
|
||||
<div className='label_input'>
|
||||
<label htmlFor='list_title'>
|
||||
<FormattedMessage
|
||||
id='lists.list_name'
|
||||
defaultMessage='List name'
|
||||
/>
|
||||
</label>
|
||||
|
||||
<div className='label_input__wrapper'>
|
||||
<input
|
||||
id='list_title'
|
||||
type='text'
|
||||
value={title}
|
||||
onChange={handleTitleChange}
|
||||
maxLength={30}
|
||||
required
|
||||
placeholder=' '
|
||||
/>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<TextInputField
|
||||
required
|
||||
maxLength={30}
|
||||
label={
|
||||
<FormattedMessage id='lists.list_name' defaultMessage='List name' />
|
||||
}
|
||||
value={title}
|
||||
onChange={handleTitleChange}
|
||||
id='list_title'
|
||||
/>
|
||||
</div>
|
||||
|
||||
<div className='fields-group'>
|
||||
<div className='input with_label'>
|
||||
<div className='label_input'>
|
||||
<label htmlFor='list_replies_policy'>
|
||||
<FormattedMessage
|
||||
id='lists.show_replies_to'
|
||||
defaultMessage='Include replies from list members to'
|
||||
/>
|
||||
</label>
|
||||
|
||||
<div className='label_input__wrapper'>
|
||||
<select
|
||||
id='list_replies_policy'
|
||||
value={repliesPolicy}
|
||||
onChange={handleRepliesPolicyChange}
|
||||
>
|
||||
<FormattedMessage
|
||||
id='lists.replies_policy.none'
|
||||
defaultMessage='No one'
|
||||
>
|
||||
{(msg) => <option value='none'>{msg}</option>}
|
||||
</FormattedMessage>
|
||||
<FormattedMessage
|
||||
id='lists.replies_policy.list'
|
||||
defaultMessage='Members of the list'
|
||||
>
|
||||
{(msg) => <option value='list'>{msg}</option>}
|
||||
</FormattedMessage>
|
||||
<FormattedMessage
|
||||
id='lists.replies_policy.followed'
|
||||
defaultMessage='Any followed user'
|
||||
>
|
||||
{(msg) => <option value='followed'>{msg}</option>}
|
||||
</FormattedMessage>
|
||||
</select>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<SelectField
|
||||
label={
|
||||
<FormattedMessage
|
||||
id='lists.show_replies_to'
|
||||
defaultMessage='Include replies from list members to'
|
||||
/>
|
||||
}
|
||||
value={repliesPolicy}
|
||||
onChange={handleRepliesPolicyChange}
|
||||
id='list_replies_policy'
|
||||
>
|
||||
<FormattedMessage
|
||||
id='lists.replies_policy.none'
|
||||
defaultMessage='No one'
|
||||
>
|
||||
{(msg) => <option value='none'>{msg}</option>}
|
||||
</FormattedMessage>
|
||||
<FormattedMessage
|
||||
id='lists.replies_policy.list'
|
||||
defaultMessage='Members of the list'
|
||||
>
|
||||
{(msg) => <option value='list'>{msg}</option>}
|
||||
</FormattedMessage>
|
||||
<FormattedMessage
|
||||
id='lists.replies_policy.followed'
|
||||
defaultMessage='Any followed user'
|
||||
>
|
||||
{(msg) => <option value='followed'>{msg}</option>}
|
||||
</FormattedMessage>
|
||||
</SelectField>
|
||||
</div>
|
||||
|
||||
{id && (
|
||||
|
|
|
|||
|
|
@ -16,6 +16,7 @@ import { closeOnboarding } from 'mastodon/actions/onboarding';
|
|||
import { Button } from 'mastodon/components/button';
|
||||
import { Column } from 'mastodon/components/column';
|
||||
import { ColumnHeader } from 'mastodon/components/column_header';
|
||||
import { TextAreaField, TextInputField } from 'mastodon/components/form_fields';
|
||||
import { Icon } from 'mastodon/components/icon';
|
||||
import { LoadingIndicator } from 'mastodon/components/loading_indicator';
|
||||
import { me } from 'mastodon/initial_state';
|
||||
|
|
@ -212,62 +213,47 @@ export const Profile: React.FC<{
|
|||
</div>
|
||||
|
||||
<div className='fields-group'>
|
||||
<div
|
||||
className={classNames('input with_block_label', {
|
||||
field_with_errors: !!errors?.display_name,
|
||||
})}
|
||||
>
|
||||
<label htmlFor='display_name'>
|
||||
<TextInputField
|
||||
maxLength={30}
|
||||
label={
|
||||
<FormattedMessage
|
||||
id='onboarding.profile.display_name'
|
||||
defaultMessage='Display name'
|
||||
/>
|
||||
</label>
|
||||
<span className='hint'>
|
||||
}
|
||||
hint={
|
||||
<FormattedMessage
|
||||
id='onboarding.profile.display_name_hint'
|
||||
defaultMessage='Your full name or your fun name…'
|
||||
/>
|
||||
</span>
|
||||
<div className='label_input'>
|
||||
<input
|
||||
id='display_name'
|
||||
type='text'
|
||||
value={displayName}
|
||||
onChange={handleDisplayNameChange}
|
||||
maxLength={30}
|
||||
/>
|
||||
</div>
|
||||
</div>
|
||||
}
|
||||
value={displayName}
|
||||
onChange={handleDisplayNameChange}
|
||||
hasError={!!errors?.display_name}
|
||||
id='display_name'
|
||||
/>
|
||||
</div>
|
||||
|
||||
<div className='fields-group'>
|
||||
<div
|
||||
className={classNames('input with_block_label', {
|
||||
field_with_errors: !!errors?.note,
|
||||
})}
|
||||
>
|
||||
<label htmlFor='note'>
|
||||
<TextAreaField
|
||||
maxLength={500}
|
||||
label={
|
||||
<FormattedMessage
|
||||
id='onboarding.profile.note'
|
||||
defaultMessage='Bio'
|
||||
/>
|
||||
</label>
|
||||
<span className='hint'>
|
||||
}
|
||||
hint={
|
||||
<FormattedMessage
|
||||
id='onboarding.profile.note_hint'
|
||||
defaultMessage='You can @mention other people or #hashtags…'
|
||||
/>
|
||||
</span>
|
||||
<div className='label_input'>
|
||||
<textarea
|
||||
id='note'
|
||||
value={note}
|
||||
onChange={handleNoteChange}
|
||||
maxLength={500}
|
||||
/>
|
||||
</div>
|
||||
</div>
|
||||
}
|
||||
value={note}
|
||||
onChange={handleNoteChange}
|
||||
hasError={!!errors?.note}
|
||||
id='note'
|
||||
/>
|
||||
</div>
|
||||
|
||||
<label className='app-form__toggle'>
|
||||
|
|
|
|||
|
|
@ -19,6 +19,9 @@ export const ConfirmationModal: React.FC<
|
|||
onConfirm: () => void;
|
||||
closeWhenConfirm?: boolean;
|
||||
extraContent?: React.ReactNode;
|
||||
updating?: boolean;
|
||||
disabled?: boolean;
|
||||
noFocusButton?: boolean;
|
||||
} & BaseConfirmationModalProps
|
||||
> = ({
|
||||
title,
|
||||
|
|
@ -31,6 +34,9 @@ export const ConfirmationModal: React.FC<
|
|||
onSecondary,
|
||||
closeWhenConfirm = true,
|
||||
extraContent,
|
||||
updating,
|
||||
disabled,
|
||||
noFocusButton = false,
|
||||
}) => {
|
||||
const handleClick = useCallback(() => {
|
||||
if (closeWhenConfirm) {
|
||||
|
|
@ -74,16 +80,23 @@ export const ConfirmationModal: React.FC<
|
|||
onClick={handleSecondary}
|
||||
className='link-button'
|
||||
type='button'
|
||||
disabled={disabled}
|
||||
>
|
||||
{secondary}
|
||||
</button>
|
||||
</>
|
||||
)}
|
||||
|
||||
{/* eslint-disable-next-line jsx-a11y/no-autofocus -- we are in a modal and thus autofocusing is justified */}
|
||||
<Button onClick={handleClick} autoFocus>
|
||||
{/* eslint-disable jsx-a11y/no-autofocus -- we are in a modal and thus autofocusing is justified */}
|
||||
<Button
|
||||
onClick={handleClick}
|
||||
loading={updating}
|
||||
disabled={disabled}
|
||||
autoFocus={!noFocusButton}
|
||||
>
|
||||
{confirm}
|
||||
</Button>
|
||||
{/* eslint-enable */}
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
|
|
|||
|
|
@ -85,6 +85,7 @@ export const MODAL_COMPONENTS = {
|
|||
'IGNORE_NOTIFICATIONS': IgnoreNotificationsModal,
|
||||
'ANNUAL_REPORT': AnnualReportModal,
|
||||
'COMPOSE_PRIVACY': () => Promise.resolve({ default: VisibilityModal }),
|
||||
'ACCOUNT_NOTE': () => import('@/mastodon/features/account_timeline/modals/note_modal').then(module => ({ default: module.AccountNoteModal })),
|
||||
'ACCOUNT_FIELDS': () => import('mastodon/features/account_timeline/components/fields_modal.tsx').then(module => ({ default: module.AccountFieldsModal })),
|
||||
};
|
||||
|
||||
|
|
|
|||
|
|
@ -63,6 +63,7 @@ import {
|
|||
Lists,
|
||||
ListEdit,
|
||||
ListMembers,
|
||||
Collections,
|
||||
Blocks,
|
||||
DomainBlocks,
|
||||
Mutes,
|
||||
|
|
@ -85,6 +86,7 @@ import { WrappedSwitch, WrappedRoute } from './util/react_router_helpers';
|
|||
// Dummy import, to make sure that <Status /> ends up in the application bundle.
|
||||
// Without this it ends up in ~8 very commonly used bundles.
|
||||
import '../../components/status';
|
||||
import { areCollectionsEnabled } from '../collections/utils';
|
||||
|
||||
const messages = defineMessages({
|
||||
beforeUnload: { id: 'ui.beforeunload', defaultMessage: 'Your draft will be lost if you leave Mastodon.' },
|
||||
|
|
@ -227,6 +229,9 @@ class SwitchingColumnsArea extends PureComponent {
|
|||
<WrappedRoute path='/followed_tags' component={FollowedTags} content={children} />
|
||||
<WrappedRoute path='/mutes' component={Mutes} content={children} />
|
||||
<WrappedRoute path='/lists' component={Lists} content={children} />
|
||||
{areCollectionsEnabled() &&
|
||||
<WrappedRoute path='/collections' component={Collections} content={children} />
|
||||
}
|
||||
|
||||
<Route component={BundleColumnError} />
|
||||
</WrappedSwitch>
|
||||
|
|
|
|||
|
|
@ -42,6 +42,12 @@ export function Lists () {
|
|||
return import('../../lists');
|
||||
}
|
||||
|
||||
export function Collections () {
|
||||
return import('../../collections').then(
|
||||
module => ({default: module.Collections})
|
||||
);
|
||||
}
|
||||
|
||||
export function Status () {
|
||||
return import('../../status');
|
||||
}
|
||||
|
|
|
|||
|
|
@ -714,7 +714,6 @@
|
|||
"privacy.private.short": "للمتابِعين",
|
||||
"privacy.public.long": "أي شخص على أو خارج ماستدون",
|
||||
"privacy.public.short": "للعامة",
|
||||
"privacy.quote.anyone": "{visibility}، يمكن لأي شخص الاقتباس",
|
||||
"privacy.quote.disabled": "{visibility}، الاقتباس معطل",
|
||||
"privacy.quote.limited": "{visibility}، الاقتباسات محدودة",
|
||||
"privacy.unlisted.additional": "هذا يتصرف بالضبط مثل النشر للعامة، باستثناء أن المنشور لن يظهر في الموجزات الحية أو في الوسوم أو في الإستكشاف، أو في نتائج بحث ماستدون، حتى وإن قمت بتفعيله على مستوى الحساب.",
|
||||
|
|
|
|||
|
|
@ -187,6 +187,7 @@
|
|||
"bundle_modal_error.close": "Закрыць",
|
||||
"bundle_modal_error.message": "Падчас загрузкі гэтага экрана штосьці пайшло не так.",
|
||||
"bundle_modal_error.retry": "Паспрабуйце зноў",
|
||||
"callout.dismiss": "Адхіліць",
|
||||
"carousel.current": "<sr>Слайд</sr> {current, number} з {max, number}",
|
||||
"carousel.slide": "Слайд {current, number} з {max, number}",
|
||||
"closed_registrations.other_server_instructions": "Паколькі Mastodon дэцэнтралізаваны, вы можаце стварыць уліковы запіс на іншым серверы і працягваць узаемадзейнічаць з ім.",
|
||||
|
|
@ -194,9 +195,16 @@
|
|||
"closed_registrations_modal.find_another_server": "Знайсці іншы сервер",
|
||||
"closed_registrations_modal.preamble": "Mastodon дэцэнтралізаваны, так што дзе б вы ні стварылі ўліковы запіс, вы зможаце падпісвацца і камунікаваць з кім хочаце на гэтым серверы. Вы нават можаце стварыць свой!",
|
||||
"closed_registrations_modal.title": "Рэгістрацыя ў Mastodon",
|
||||
"collections.create_a_collection_hint": "Стварыце калекцыю, каб параіць або падзяліцца сваімі любімымі ўліковымі запісамі з іншымі.",
|
||||
"collections.create_collection": "Стварыць калекцыю",
|
||||
"collections.delete_collection": "Выдаліць калекцыю",
|
||||
"collections.error_loading_collections": "Адбылася памылка падчас загрузкі Вашых калекцый.",
|
||||
"collections.no_collections_yet": "Пакуль няма калекцый.",
|
||||
"collections.view_collection": "Глядзець калекцыю",
|
||||
"column.about": "Пра нас",
|
||||
"column.blocks": "Заблакіраваныя карыстальнікі",
|
||||
"column.bookmarks": "Закладкі",
|
||||
"column.collections": "Мае калекцыі",
|
||||
"column.community": "Лакальная стужка",
|
||||
"column.create_list": "Стварыць спіс",
|
||||
"column.direct": "Прыватныя згадванні",
|
||||
|
|
@ -454,6 +462,7 @@
|
|||
"footer.source_code": "Прагледзець зыходны код",
|
||||
"footer.status": "Статус",
|
||||
"footer.terms_of_service": "Умовы выкарыстання",
|
||||
"form_field.optional": "(неабавязкова)",
|
||||
"generic.saved": "Захавана",
|
||||
"getting_started.heading": "Пачатак працы",
|
||||
"hashtag.admin_moderation": "Адкрыць інтэрфейс мадэратара для #{name}",
|
||||
|
|
@ -790,7 +799,7 @@
|
|||
"privacy.private.short": "Падпісчыкі",
|
||||
"privacy.public.long": "Усе, хто ёсць і каго няма ў Mastodon",
|
||||
"privacy.public.short": "Публічны",
|
||||
"privacy.quote.anyone": "{visibility}, усе могуць цытаваць",
|
||||
"privacy.quote.anyone": "{visibility}, цытаты дазволеныя",
|
||||
"privacy.quote.disabled": "{visibility}, цытаты адключаныя",
|
||||
"privacy.quote.limited": "{visibility}, абмежаваныя цытаты",
|
||||
"privacy.unlisted.additional": "Паводзіць сябе гэтак жа, як і публічны, за выключэннем таго, што допіс не будзе адлюстроўвацца ў жывой стужцы, хэштэгах, аглядзе або ў пошуку Mastodon, нават калі Вы ўключылі бачнасць у пошуку ў наладах.",
|
||||
|
|
|
|||
|
|
@ -714,7 +714,6 @@
|
|||
"privacy.private.short": "Последователи",
|
||||
"privacy.public.long": "Всеки във и извън Mastodon",
|
||||
"privacy.public.short": "Публично",
|
||||
"privacy.quote.anyone": "{visibility}, всеки може да цитира",
|
||||
"privacy.quote.disabled": "{visibility}, цитатите са изключени",
|
||||
"privacy.quote.limited": "{visibility}, цитатите са ограничени",
|
||||
"privacy.unlisted.additional": "Това действие е точно като публичното, с изключение на това, че публикацията няма да се появява в каналите на живо, хаштаговете, разглеждането или търсенето в Mastodon, дори ако сте избрали да се публично видими на ниво акаунт.",
|
||||
|
|
|
|||
|
|
@ -559,7 +559,6 @@
|
|||
"privacy.private.long": "Hoc'h heulierien·ezed hepken",
|
||||
"privacy.private.short": "Heulierien",
|
||||
"privacy.public.short": "Publik",
|
||||
"privacy.quote.anyone": "{visibility}, n'eus forzh piv a c'hall menegiñ",
|
||||
"privacy.quote.disabled": "{visibility}, menegoù diweredekaet",
|
||||
"privacy_policy.last_updated": "Hizivadenn ziwezhañ {date}",
|
||||
"privacy_policy.title": "Reolennoù Prevezded",
|
||||
|
|
|
|||
|
|
@ -57,6 +57,7 @@
|
|||
"account.go_to_profile": "Vés al perfil",
|
||||
"account.hide_reblogs": "Amaga els impulsos de @{name}",
|
||||
"account.in_memoriam": "En Memòria.",
|
||||
"account.joined_long": "Membre des de {date}",
|
||||
"account.joined_short": "S'hi va unir",
|
||||
"account.languages": "Canvia les llengües subscrites",
|
||||
"account.link_verified_on": "La propietat d'aquest enllaç es va verificar el dia {date}",
|
||||
|
|
@ -90,6 +91,8 @@
|
|||
"account.unmute": "Deixa de silenciar @{name}",
|
||||
"account.unmute_notifications_short": "Deixa de silenciar les notificacions",
|
||||
"account.unmute_short": "Deixa de silenciar",
|
||||
"account_fields_modal.close": "Tanca",
|
||||
"account_fields_modal.title": "Informació de {name}",
|
||||
"account_note.placeholder": "Clica per a afegir-hi una nota",
|
||||
"admin.dashboard.daily_retention": "Ràtio de retenció d'usuaris per dia, després de registrar-se",
|
||||
"admin.dashboard.monthly_retention": "Ràtio de retenció d'usuaris per mes, després de registrar-se",
|
||||
|
|
@ -158,6 +161,7 @@
|
|||
"bundle_modal_error.close": "Tanca",
|
||||
"bundle_modal_error.message": "S'ha produït un error en carregar aquesta pantalla.",
|
||||
"bundle_modal_error.retry": "Torna-ho a provar",
|
||||
"callout.dismiss": "Omet",
|
||||
"carousel.current": "<sr>Diapositiva</sr> {current, number} / {max, number}",
|
||||
"carousel.slide": "Diapositiva {current, number} de {max, number}",
|
||||
"closed_registrations.other_server_instructions": "Com que Mastodon és descentralitzat, pots crear un compte en un altre servidor i continuar interactuant amb aquest.",
|
||||
|
|
@ -165,9 +169,16 @@
|
|||
"closed_registrations_modal.find_another_server": "Troba un altre servidor",
|
||||
"closed_registrations_modal.preamble": "Mastodon és descentralitzat. Per tant, tinguis on tinguis el compte, seràs capaç de seguir i interactuar amb tothom des d'aquest servidor. Fins i tot pots tenir el compte en el teu propi servidor!",
|
||||
"closed_registrations_modal.title": "Registrant-se a Mastodon",
|
||||
"collections.create_a_collection_hint": "Creeu una coŀlecció per a recomanar o compartir amb d'altres els vostres comptes preferits.",
|
||||
"collections.create_collection": "Crea una coŀlecció",
|
||||
"collections.delete_collection": "Elimina la coŀlecció",
|
||||
"collections.error_loading_collections": "Hi ha hagut un error en carregar les vostres coŀleccions.",
|
||||
"collections.no_collections_yet": "Encara no hi ha coŀleccions.",
|
||||
"collections.view_collection": "Mostra la coŀlecció",
|
||||
"column.about": "Quant a",
|
||||
"column.blocks": "Usuaris blocats",
|
||||
"column.bookmarks": "Marcadors",
|
||||
"column.collections": "Les meves coŀleccions",
|
||||
"column.community": "Línia de temps local",
|
||||
"column.create_list": "Crea una llista",
|
||||
"column.direct": "Mencions privades",
|
||||
|
|
@ -425,6 +436,7 @@
|
|||
"footer.source_code": "Mostra el codi font",
|
||||
"footer.status": "Estat",
|
||||
"footer.terms_of_service": "Condicions de servei",
|
||||
"form_field.optional": "(opcional)",
|
||||
"generic.saved": "Desat",
|
||||
"getting_started.heading": "Primeres passes",
|
||||
"hashtag.admin_moderation": "Obre la interfície de moderació per a #{name}",
|
||||
|
|
@ -562,6 +574,7 @@
|
|||
"load_pending": "{count, plural, one {# element nou} other {# elements nous}}",
|
||||
"loading_indicator.label": "Es carrega…",
|
||||
"media_gallery.hide": "Amaga",
|
||||
"minicard.more_items": "+{count}",
|
||||
"moved_to_account_banner.text": "El teu compte {disabledAccount} està desactivat perquè l'has mogut a {movedToAccount}.",
|
||||
"mute_modal.hide_from_notifications": "Amaga de les notificacions",
|
||||
"mute_modal.hide_options": "Amaga les opcions",
|
||||
|
|
@ -759,7 +772,6 @@
|
|||
"privacy.private.short": "Seguidors",
|
||||
"privacy.public.long": "Tothom dins o fora Mastodon",
|
||||
"privacy.public.short": "Públic",
|
||||
"privacy.quote.anyone": "{visibility}, qualsevol pot citar",
|
||||
"privacy.quote.disabled": "{visibility}, cites desactivades",
|
||||
"privacy.quote.limited": "{visibility}, cites limitades",
|
||||
"privacy.unlisted.additional": "Es comporta igual que públic, excepte que la publicació no apareixerà als canals en directe o etiquetes, l'explora o a la cerca de Mastodon, fins i tot si ho heu activat a nivell de compte.",
|
||||
|
|
@ -1027,7 +1039,7 @@
|
|||
"visibility_modal.direct_quote_warning.title": "Les cites no es poden incrustar a les mencions privades",
|
||||
"visibility_modal.header": "Visibilitat i interacció",
|
||||
"visibility_modal.helper.direct_quoting": "No es poden citar mencions privades fetes a Mastondon.",
|
||||
"visibility_modal.helper.privacy_editing": "La visibilitat no es pot canviar després de publicar una publicació.",
|
||||
"visibility_modal.helper.privacy_editing": "La visibilitat no es pot canviar després s'ha fet una publicació.",
|
||||
"visibility_modal.helper.privacy_private_self_quote": "Les autocites de publicacions privades no es poden fer públiques.",
|
||||
"visibility_modal.helper.private_quoting": "No es poden citar publicacions fetes a Mastodon només per a seguidors.",
|
||||
"visibility_modal.helper.unlisted_quoting": "Quan la gent us citi, les seves publicacions quedaran amagades de les línies de temps de tendències.",
|
||||
|
|
|
|||
|
|
@ -790,7 +790,6 @@
|
|||
"privacy.private.short": "Sledující",
|
||||
"privacy.public.long": "Kdokoliv na Mastodonu i mimo něj",
|
||||
"privacy.public.short": "Veřejné",
|
||||
"privacy.quote.anyone": "{visibility}, kdokoliv může citovat",
|
||||
"privacy.quote.disabled": "{visibility}, citování je zakázáno",
|
||||
"privacy.quote.limited": "{visibility}, citování je omezené",
|
||||
"privacy.unlisted.additional": "Chová se stejně jako veřejný, až na to, že se příspěvek neobjeví v živých kanálech nebo hashtazích, v objevování nebo vyhledávání na Mastodonu, a to i když je účet nastaven tak, aby se zde všude tyto příspěvky zobrazovaly.",
|
||||
|
|
|
|||
|
|
@ -785,7 +785,6 @@
|
|||
"privacy.private.short": "Dilynwyr",
|
||||
"privacy.public.long": "Unrhyw un ar ac oddi ar Mastodon",
|
||||
"privacy.public.short": "Cyhoeddus",
|
||||
"privacy.quote.anyone": "{visibility}, gall unrhyw un ddyfynnu",
|
||||
"privacy.quote.disabled": "{visibility}, dyfyniadau wedi'u hanalluogi",
|
||||
"privacy.quote.limited": "{visibility}, dyfyniadau wedi'u cyfyngu",
|
||||
"privacy.unlisted.additional": "Mae hwn yn ymddwyn yn union fel y cyhoeddus, ac eithrio na fydd y postiad yn ymddangos mewn ffrydiau byw neu hashnodau, archwilio, neu chwiliad Mastodon, hyd yn oed os ydych wedi eich cynnwys ar draws y cyfrif.",
|
||||
|
|
|
|||
|
|
@ -187,6 +187,7 @@
|
|||
"bundle_modal_error.close": "Luk",
|
||||
"bundle_modal_error.message": "Noget gik galt under indlæsningen af denne skærm.",
|
||||
"bundle_modal_error.retry": "Forsøg igen",
|
||||
"callout.dismiss": "Afvis",
|
||||
"carousel.current": "<sr>Dias</sr> {current, number} / {max, number}",
|
||||
"carousel.slide": "Dias {current, number} af {max, number}",
|
||||
"closed_registrations.other_server_instructions": "Eftersom Mastodon er decentraliseret, kan du oprette en konto på en anden server og stadig interagere med denne.",
|
||||
|
|
@ -194,9 +195,16 @@
|
|||
"closed_registrations_modal.find_another_server": "Find en anden server",
|
||||
"closed_registrations_modal.preamble": "Mastodon er decentraliseret, så uanset hvor du opretter din konto, vil du være i stand til at følge og interagere med hvem som helst på denne server. Du kan endda selv være vært for den!",
|
||||
"closed_registrations_modal.title": "Oprettelse på Mastodon",
|
||||
"collections.create_a_collection_hint": "Opret en samling for at anbefale eller dele dine yndlingskonti med andre.",
|
||||
"collections.create_collection": "Opret samling",
|
||||
"collections.delete_collection": "Slet samling",
|
||||
"collections.error_loading_collections": "Der opstod en fejl under indlæsning af dine samlinger.",
|
||||
"collections.no_collections_yet": "Ingen samlinger endnu.",
|
||||
"collections.view_collection": "Vis samling",
|
||||
"column.about": "Om",
|
||||
"column.blocks": "Blokerede brugere",
|
||||
"column.bookmarks": "Bogmærker",
|
||||
"column.collections": "Mine samlinger",
|
||||
"column.community": "Lokal tidslinje",
|
||||
"column.create_list": "Opret liste",
|
||||
"column.direct": "Private omtaler",
|
||||
|
|
@ -454,6 +462,7 @@
|
|||
"footer.source_code": "Vis kildekode",
|
||||
"footer.status": "Status",
|
||||
"footer.terms_of_service": "Tjenestevilkår",
|
||||
"form_field.optional": "(valgfri)",
|
||||
"generic.saved": "Gemt",
|
||||
"getting_started.heading": "Startmenu",
|
||||
"hashtag.admin_moderation": "Åbn modereringsbrugerflade for #{name}",
|
||||
|
|
@ -568,7 +577,7 @@
|
|||
"lists.add_to_list": "Føj til liste",
|
||||
"lists.add_to_lists": "Føj {name} til lister",
|
||||
"lists.create": "Opret",
|
||||
"lists.create_a_list_to_organize": "Opret en ny liste til organisering af hjemmefeed",
|
||||
"lists.create_a_list_to_organize": "Opret en ny liste til organisering af dit Hjem-feed",
|
||||
"lists.create_list": "Opret liste",
|
||||
"lists.delete": "Slet liste",
|
||||
"lists.done": "Færdig",
|
||||
|
|
@ -790,7 +799,7 @@
|
|||
"privacy.private.short": "Følgere",
|
||||
"privacy.public.long": "Alle på og udenfor Mastodon",
|
||||
"privacy.public.short": "Offentlig",
|
||||
"privacy.quote.anyone": "{visibility}, alle kan citere",
|
||||
"privacy.quote.anyone": "{visibility}, citering tilladt",
|
||||
"privacy.quote.disabled": "{visibility}, citering deaktiveret",
|
||||
"privacy.quote.limited": "{visibility}, citering begrænset",
|
||||
"privacy.unlisted.additional": "Dette svarer til offentlig, bortset fra at indlægget ikke vises i live-feeds eller hashtags, udforsk eller Mastodon-søgning, selvom du har tilvalgt dette for kontoen.",
|
||||
|
|
|
|||
|
|
@ -178,7 +178,7 @@
|
|||
"bundle_column_error.copy_stacktrace": "Fehlerbericht kopieren",
|
||||
"bundle_column_error.error.body": "Die angeforderte Seite konnte nicht dargestellt werden. Dies könnte auf einen Fehler in unserem Code oder auf ein Browser-Kompatibilitätsproblem zurückzuführen sein.",
|
||||
"bundle_column_error.error.title": "Oh nein!",
|
||||
"bundle_column_error.network.body": "Beim Versuch, diese Seite zu laden, ist ein Fehler aufgetreten. Dies könnte auf ein vorübergehendes Problem mit deiner Internetverbindung oder diesem Server zurückzuführen sein.",
|
||||
"bundle_column_error.network.body": "Beim Laden dieser Seite ist ein Fehler aufgetreten. Die Ursache könnte ein vorübergehendes Problem mit deiner Internetverbindung oder diesem Server sein.",
|
||||
"bundle_column_error.network.title": "Netzwerkfehler",
|
||||
"bundle_column_error.retry": "Erneut versuchen",
|
||||
"bundle_column_error.return": "Zurück zur Startseite",
|
||||
|
|
@ -187,6 +187,7 @@
|
|||
"bundle_modal_error.close": "Schließen",
|
||||
"bundle_modal_error.message": "Beim Laden des Inhalts ist etwas schiefgelaufen.",
|
||||
"bundle_modal_error.retry": "Erneut versuchen",
|
||||
"callout.dismiss": "Verwerfen",
|
||||
"carousel.current": "<sr>Seite</sr> {current, number}/{max, number}",
|
||||
"carousel.slide": "Seite {current, number} von {max, number}",
|
||||
"closed_registrations.other_server_instructions": "Da Mastodon dezentralisiert ist, kannst du dich auch woanders im Fediverse registrieren und trotzdem mit diesem Server in Kontakt bleiben.",
|
||||
|
|
@ -194,9 +195,16 @@
|
|||
"closed_registrations_modal.find_another_server": "Anderen Server suchen",
|
||||
"closed_registrations_modal.preamble": "Mastodon ist dezentralisiert, das heißt, unabhängig davon, wo du dein Konto erstellst, kannst du jedem Profil auf diesem Server folgen und mit ihm interagieren. Du kannst sogar deinen eigenen Mastodon-Server hosten!",
|
||||
"closed_registrations_modal.title": "Bei Mastodon registrieren",
|
||||
"collections.create_a_collection_hint": "Erstelle eine Sammlung, um deine Lieblingsprofile anderen zu empfehlen oder sie zu teilen.",
|
||||
"collections.create_collection": "Sammlung erstellen",
|
||||
"collections.delete_collection": "Sammlung löschen",
|
||||
"collections.error_loading_collections": "Beim Laden deiner Sammlungen ist ein Fehler aufgetreten.",
|
||||
"collections.no_collections_yet": "Bisher keine Sammlungen vorhanden.",
|
||||
"collections.view_collection": "Sammlungen anzeigen",
|
||||
"column.about": "Über",
|
||||
"column.blocks": "Blockierte Profile",
|
||||
"column.bookmarks": "Lesezeichen",
|
||||
"column.collections": "Meine Sammlungen",
|
||||
"column.community": "Lokale Timeline",
|
||||
"column.create_list": "Liste erstellen",
|
||||
"column.direct": "Private Erwähnungen",
|
||||
|
|
@ -454,6 +462,7 @@
|
|||
"footer.source_code": "Quellcode anzeigen",
|
||||
"footer.status": "Status",
|
||||
"footer.terms_of_service": "Nutzungsbedingungen",
|
||||
"form_field.optional": "(optional)",
|
||||
"generic.saved": "Gespeichert",
|
||||
"getting_started.heading": "Auf gehts!",
|
||||
"hashtag.admin_moderation": "#{name} moderieren",
|
||||
|
|
@ -604,7 +613,7 @@
|
|||
"mute_modal.you_wont_see_mentions": "Du wirst keine Beiträge sehen, die dieses Profil erwähnen.",
|
||||
"mute_modal.you_wont_see_posts": "Deine Beiträge können von diesem stummgeschalteten Profil weiterhin gesehen werden, aber du wirst dessen Beiträge nicht mehr sehen.",
|
||||
"navigation_bar.about": "Über",
|
||||
"navigation_bar.account_settings": "Passwort und Sicherheit",
|
||||
"navigation_bar.account_settings": "Passwort & Sicherheit",
|
||||
"navigation_bar.administration": "Administration",
|
||||
"navigation_bar.advanced_interface": "Erweitertes Webinterface öffnen",
|
||||
"navigation_bar.automated_deletion": "Automatisiertes Löschen",
|
||||
|
|
@ -790,7 +799,7 @@
|
|||
"privacy.private.short": "Follower",
|
||||
"privacy.public.long": "Alle innerhalb und außerhalb von Mastodon",
|
||||
"privacy.public.short": "Öffentlich",
|
||||
"privacy.quote.anyone": "{visibility} – alle dürfen zitieren",
|
||||
"privacy.quote.anyone": "{visibility}, zitierte Beiträge erlaubt",
|
||||
"privacy.quote.disabled": "{visibility} – Zitieren deaktiviert",
|
||||
"privacy.quote.limited": "{visibility} – nur Follower",
|
||||
"privacy.unlisted.additional": "Das Verhalten ist wie bei „Öffentlich“, jedoch gibt es einige Einschränkungen. Der Beitrag wird nicht in „Live-Feeds“, „Erkunden“, Hashtags oder über die Mastodon-Suchfunktion auffindbar sein – selbst wenn die zugehörige Einstellung aktiviert wurde.",
|
||||
|
|
|
|||
|
|
@ -60,7 +60,7 @@
|
|||
"account.joined_long": "Έγινε μέλος {date}",
|
||||
"account.joined_short": "Έγινε μέλος",
|
||||
"account.languages": "Αλλαγή εγγεγραμμένων γλωσσών",
|
||||
"account.link_verified_on": "Η ιδιοκτησία αυτού του συνδέσμου ελέχθηκε στις {date}",
|
||||
"account.link_verified_on": "Η ιδιοκτησία αυτού του συνδέσμου ελέγχθηκε στις {date}",
|
||||
"account.locked_info": "Η κατάσταση απορρήτου αυτού του λογαριασμού έχει ρυθμιστεί σε κλειδωμένη. Ο ιδιοκτήτης αξιολογεί χειροκίνητα ποιος μπορεί να τον ακολουθήσει.",
|
||||
"account.media": "Πολυμέσα",
|
||||
"account.mention": "Επισήμανε @{name}",
|
||||
|
|
@ -187,6 +187,7 @@
|
|||
"bundle_modal_error.close": "Κλείσιμο",
|
||||
"bundle_modal_error.message": "Κάτι πήγε στραβά κατά τη φόρτωση αυτής της οθόνης.",
|
||||
"bundle_modal_error.retry": "Δοκίμασε ξανά",
|
||||
"callout.dismiss": "Απόρριψη",
|
||||
"carousel.current": "<sr>Διαφάνεια</sr> {current, number} / {max, number}",
|
||||
"carousel.slide": "Διαφάνεια {current, number} από {max, number}",
|
||||
"closed_registrations.other_server_instructions": "Καθώς το Mastodon είναι αποκεντρωμένο, μπορείς να δημιουργήσεις λογαριασμό σε άλλον διακομιστή αλλά να συνεχίσεις να αλληλεπιδράς με αυτόν.",
|
||||
|
|
@ -194,9 +195,16 @@
|
|||
"closed_registrations_modal.find_another_server": "Βρες άλλον διακομιστή",
|
||||
"closed_registrations_modal.preamble": "Το Mastodon είναι αποκεντρωμένο, οπότε ανεξάρτητα από το πού θα δημιουργήσεις τον λογαριασμό σου, μπορείς να ακολουθήσεις και να αλληλεπιδράσεις με οποιονδήποτε σε αυτόν τον διακομιστή. Μπορείς ακόμη και να κάνεις τον δικό σου!",
|
||||
"closed_registrations_modal.title": "Εγγραφή στο Mastodon",
|
||||
"collections.create_a_collection_hint": "Δημιουργήστε μια συλλογή για να προτείνετε ή να μοιραστείτε τους αγαπημένους σας λογαριασμούς με άλλους.",
|
||||
"collections.create_collection": "Δημιουργία συλλογής",
|
||||
"collections.delete_collection": "Διαγραφή συλλογής",
|
||||
"collections.error_loading_collections": "Παρουσιάστηκε σφάλμα κατά την προσπάθεια φόρτωσης των συλλογών σας.",
|
||||
"collections.no_collections_yet": "Καμία συλλογή ακόμη.",
|
||||
"collections.view_collection": "Προβολή συλλογής",
|
||||
"column.about": "Σχετικά με",
|
||||
"column.blocks": "Αποκλεισμένοι χρήστες",
|
||||
"column.bookmarks": "Σελιδοδείκτες",
|
||||
"column.collections": "Οι συλλογές μου",
|
||||
"column.community": "Τοπική ροή",
|
||||
"column.create_list": "Δημιουργία λίστας",
|
||||
"column.direct": "Ιδιωτικές επισημάνσεις",
|
||||
|
|
@ -454,6 +462,7 @@
|
|||
"footer.source_code": "Προβολή πηγαίου κώδικα",
|
||||
"footer.status": "Κατάσταση",
|
||||
"footer.terms_of_service": "Όροι υπηρεσίας",
|
||||
"form_field.optional": "(προαιρετικό)",
|
||||
"generic.saved": "Αποθηκεύτηκε",
|
||||
"getting_started.heading": "Ας ξεκινήσουμε",
|
||||
"hashtag.admin_moderation": "Άνοιγμα διεπαφής συντονισμού για το #{name}",
|
||||
|
|
@ -790,7 +799,7 @@
|
|||
"privacy.private.short": "Ακόλουθοι",
|
||||
"privacy.public.long": "Όλοι εντός και εκτός του Mastodon",
|
||||
"privacy.public.short": "Δημόσια",
|
||||
"privacy.quote.anyone": "{visibility}, ο καθένας μπορεί να παραθέσει",
|
||||
"privacy.quote.anyone": "{visibility}, παραθέσεις επιτρεπτές",
|
||||
"privacy.quote.disabled": "{visibility}, παραθέσεις απενεργοποιημένες",
|
||||
"privacy.quote.limited": "{visibility}, παραθέσεις περιορισμένες",
|
||||
"privacy.unlisted.additional": "Αυτό συμπεριφέρεται ακριβώς όπως το δημόσιο, εκτός από το ότι η ανάρτηση δεν θα εμφανιστεί σε ζωντανές ροές ή ετικέτες, εξερεύνηση ή αναζήτηση στο Mastodon, ακόμη και αν το έχεις επιλέξει για τον λογαριασμό σου.",
|
||||
|
|
|
|||
|
|
@ -187,6 +187,7 @@
|
|||
"bundle_modal_error.close": "Close",
|
||||
"bundle_modal_error.message": "Something went wrong while loading this screen.",
|
||||
"bundle_modal_error.retry": "Try again",
|
||||
"callout.dismiss": "Dismiss",
|
||||
"carousel.current": "<sr>Slide</sr> {current, number} / {max, number}",
|
||||
"carousel.slide": "Slide {current, number} of {max, number}",
|
||||
"closed_registrations.other_server_instructions": "Since Mastodon is decentralised, you can create an account on another server and still interact with this one.",
|
||||
|
|
@ -194,9 +195,16 @@
|
|||
"closed_registrations_modal.find_another_server": "Find another server",
|
||||
"closed_registrations_modal.preamble": "Mastodon is decentralised, so no matter where you create your account, you will be able to follow and interact with anyone on this server. You can even self-host it!",
|
||||
"closed_registrations_modal.title": "Signing up on Mastodon",
|
||||
"collections.create_a_collection_hint": "Create a collection to recommend or share your favourite accounts with others.",
|
||||
"collections.create_collection": "Create collection",
|
||||
"collections.delete_collection": "Delete collection",
|
||||
"collections.error_loading_collections": "There was an error when trying to load your collections.",
|
||||
"collections.no_collections_yet": "No collections yet.",
|
||||
"collections.view_collection": "View collection",
|
||||
"column.about": "About",
|
||||
"column.blocks": "Blocked users",
|
||||
"column.bookmarks": "Bookmarks",
|
||||
"column.collections": "My collections",
|
||||
"column.community": "Local timeline",
|
||||
"column.create_list": "Create list",
|
||||
"column.direct": "Private mentions",
|
||||
|
|
@ -454,6 +462,7 @@
|
|||
"footer.source_code": "View source code",
|
||||
"footer.status": "Status",
|
||||
"footer.terms_of_service": "Terms of service",
|
||||
"form_field.optional": "(optional)",
|
||||
"generic.saved": "Saved",
|
||||
"getting_started.heading": "Getting started",
|
||||
"hashtag.admin_moderation": "Open moderation interface for #{name}",
|
||||
|
|
@ -790,7 +799,7 @@
|
|||
"privacy.private.short": "Followers",
|
||||
"privacy.public.long": "Anyone on and off Mastodon",
|
||||
"privacy.public.short": "Public",
|
||||
"privacy.quote.anyone": "{visibility}, anyone can quote",
|
||||
"privacy.quote.anyone": "{visibility}, quotes allowed",
|
||||
"privacy.quote.disabled": "{visibility}, quotes disabled",
|
||||
"privacy.quote.limited": "{visibility}, quotes limited",
|
||||
"privacy.unlisted.additional": "This behaves exactly like public, except the post will not appear in live feeds or hashtags, explore, or Mastodon search, even if you are opted-in account-wide.",
|
||||
|
|
|
|||
|
|
@ -14,6 +14,7 @@
|
|||
"about.powered_by": "Decentralized social media powered by {mastodon}",
|
||||
"about.rules": "Server rules",
|
||||
"account.account_note_header": "Personal note",
|
||||
"account.add_note": "Add a personal note",
|
||||
"account.add_or_remove_from_list": "Add or Remove from lists",
|
||||
"account.badges.bot": "Automated",
|
||||
"account.badges.group": "Group",
|
||||
|
|
@ -27,6 +28,7 @@
|
|||
"account.direct": "Privately mention @{name}",
|
||||
"account.disable_notifications": "Stop notifying me when @{name} posts",
|
||||
"account.domain_blocking": "Blocking domain",
|
||||
"account.edit_note": "Edit personal note",
|
||||
"account.edit_profile": "Edit profile",
|
||||
"account.edit_profile_short": "Edit",
|
||||
"account.enable_notifications": "Notify me when @{name} posts",
|
||||
|
|
@ -72,6 +74,14 @@
|
|||
"account.muting": "Muting",
|
||||
"account.mutual": "You follow each other",
|
||||
"account.no_bio": "No description provided.",
|
||||
"account.node_modal.callout": "Personal notes are visible only to you.",
|
||||
"account.node_modal.edit_title": "Edit personal note",
|
||||
"account.node_modal.error_unknown": "Could not save the note",
|
||||
"account.node_modal.field_label": "Personal Note",
|
||||
"account.node_modal.save": "Save",
|
||||
"account.node_modal.title": "Add a personal note",
|
||||
"account.note.edit_button": "Edit",
|
||||
"account.note.title": "Personal note (visible only to you)",
|
||||
"account.open_original_page": "Open original page",
|
||||
"account.posts": "Posts",
|
||||
"account.posts_with_replies": "Posts and replies",
|
||||
|
|
@ -187,6 +197,7 @@
|
|||
"bundle_modal_error.close": "Close",
|
||||
"bundle_modal_error.message": "Something went wrong while loading this screen.",
|
||||
"bundle_modal_error.retry": "Try again",
|
||||
"callout.dismiss": "Dismiss",
|
||||
"carousel.current": "<sr>Slide</sr> {current, number} / {max, number}",
|
||||
"carousel.slide": "Slide {current, number} of {max, number}",
|
||||
"closed_registrations.other_server_instructions": "Since Mastodon is decentralized, you can create an account on another server and still interact with this one.",
|
||||
|
|
@ -194,9 +205,16 @@
|
|||
"closed_registrations_modal.find_another_server": "Find another server",
|
||||
"closed_registrations_modal.preamble": "Mastodon is decentralized, so no matter where you create your account, you will be able to follow and interact with anyone on this server. You can even self-host it!",
|
||||
"closed_registrations_modal.title": "Signing up on Mastodon",
|
||||
"collections.create_a_collection_hint": "Create a collection to recommend or share your favourite accounts with others.",
|
||||
"collections.create_collection": "Create collection",
|
||||
"collections.delete_collection": "Delete collection",
|
||||
"collections.error_loading_collections": "There was an error when trying to load your collections.",
|
||||
"collections.no_collections_yet": "No collections yet.",
|
||||
"collections.view_collection": "View collection",
|
||||
"column.about": "About",
|
||||
"column.blocks": "Blocked users",
|
||||
"column.bookmarks": "Bookmarks",
|
||||
"column.collections": "My collections",
|
||||
"column.community": "Local timeline",
|
||||
"column.create_list": "Create list",
|
||||
"column.direct": "Private mentions",
|
||||
|
|
@ -454,6 +472,7 @@
|
|||
"footer.source_code": "View source code",
|
||||
"footer.status": "Status",
|
||||
"footer.terms_of_service": "Terms of service",
|
||||
"form_field.optional": "(optional)",
|
||||
"generic.saved": "Saved",
|
||||
"getting_started.heading": "Getting started",
|
||||
"hashtag.admin_moderation": "Open moderation interface for #{name}",
|
||||
|
|
@ -790,7 +809,7 @@
|
|||
"privacy.private.short": "Followers",
|
||||
"privacy.public.long": "Anyone on and off Mastodon",
|
||||
"privacy.public.short": "Public",
|
||||
"privacy.quote.anyone": "{visibility}, anyone can quote",
|
||||
"privacy.quote.anyone": "{visibility}, quotes allowed",
|
||||
"privacy.quote.disabled": "{visibility}, quotes disabled",
|
||||
"privacy.quote.limited": "{visibility}, quotes limited",
|
||||
"privacy.unlisted.additional": "This behaves exactly like public, except the post will not appear in live feeds or hashtags, explore, or Mastodon search, even if you are opted-in account-wide.",
|
||||
|
|
|
|||
|
|
@ -86,6 +86,7 @@
|
|||
"account.unmute": "Malsilentigi @{name}",
|
||||
"account.unmute_notifications_short": "Malsilentigu sciigojn",
|
||||
"account.unmute_short": "Ne plu silentigi",
|
||||
"account_fields_modal.close": "Fermi",
|
||||
"account_note.placeholder": "Alklaku por aldoni noton",
|
||||
"admin.dashboard.daily_retention": "Uzantoretenprocento laŭ tag post registro",
|
||||
"admin.dashboard.monthly_retention": "Uzantoretenprocento laŭ monato post registro",
|
||||
|
|
@ -112,6 +113,7 @@
|
|||
"annual_report.announcement.action_dismiss": "Ne, dankon",
|
||||
"annual_report.nav_item.badge": "Nova",
|
||||
"annual_report.shared_page.donate": "Donaci",
|
||||
"annual_report.summary.close": "Fermi",
|
||||
"annual_report.summary.copy_link": "Kopii ligilon",
|
||||
"annual_report.summary.highlighted_post.title": "Plej populara afiŝo",
|
||||
"annual_report.summary.most_used_app.most_used_app": "plej uzita aplikaĵo",
|
||||
|
|
@ -149,6 +151,9 @@
|
|||
"closed_registrations_modal.find_another_server": "Trovi alian servilon",
|
||||
"closed_registrations_modal.preamble": "Mastodon estas malcentraliza, do sendepende de tio, kie vi kreas vian konton, vi povos sekvi kaj komuniki kun ĉiuj ajn el ĉi tiu servilo. Vi eĉ povas mem starigi propran servilon!",
|
||||
"closed_registrations_modal.title": "Registriĝi en Mastodon",
|
||||
"collections.create_collection": "Krei kolekton",
|
||||
"collections.delete_collection": "Forigi kolekton",
|
||||
"collections.error_loading_collections": "Okazis eraro provante ŝargi viajn kolektojn.",
|
||||
"column.about": "Pri",
|
||||
"column.blocks": "Blokitaj uzantoj",
|
||||
"column.bookmarks": "Legosignoj",
|
||||
|
|
@ -179,6 +184,7 @@
|
|||
"community.column_settings.local_only": "Nur loka",
|
||||
"community.column_settings.media_only": "Nur aŭdovidaĵoj",
|
||||
"community.column_settings.remote_only": "Nur fora",
|
||||
"compose.error.blank_post": "Afiŝo ne povas esti malplena.",
|
||||
"compose.language.change": "Ŝanĝi lingvon",
|
||||
"compose.language.search": "Serĉi lingvojn...",
|
||||
"compose.published.body": "Afiŝo publikigita.",
|
||||
|
|
@ -213,6 +219,7 @@
|
|||
"confirmations.delete_list.title": "Ĉu forigi liston?",
|
||||
"confirmations.discard_draft.confirm": "Forĵetu kaj daŭrigu",
|
||||
"confirmations.discard_draft.edit.cancel": "Daŭrigi redaktadon",
|
||||
"confirmations.discard_draft.edit.message": "Daŭrigo forigos ĉiujn ŝanĝojn, kiujn vi faris al la afiŝo, kiun vi nun redaktas.",
|
||||
"confirmations.discard_draft.edit.title": "Ĉu forĵeti ŝanĝojn al via afiŝo?",
|
||||
"confirmations.discard_draft.post.cancel": "Daŭrigi malneton",
|
||||
"confirmations.discard_draft.post.message": "Daŭrigo forigos la afiŝon, kiun vi nun verkas.",
|
||||
|
|
@ -230,6 +237,8 @@
|
|||
"confirmations.missing_alt_text.secondary": "Afiŝi ĉiuokaze",
|
||||
"confirmations.missing_alt_text.title": "Ĉu aldoni alttekston?",
|
||||
"confirmations.mute.confirm": "Silentigi",
|
||||
"confirmations.private_quote_notify.confirm": "Publikigi afiŝon",
|
||||
"confirmations.private_quote_notify.do_not_show_again": "Ne montru al mi ĉi tiun mesaĝon denove",
|
||||
"confirmations.quiet_post_quote_info.dismiss": "Ne memorigu min denove",
|
||||
"confirmations.quiet_post_quote_info.got_it": "Komprenite",
|
||||
"confirmations.redraft.confirm": "Forigi kaj reskribi",
|
||||
|
|
@ -336,6 +345,7 @@
|
|||
"explore.trending_statuses": "Afiŝoj",
|
||||
"explore.trending_tags": "Kradvortoj",
|
||||
"featured_carousel.header": "{count, plural, one {Alpinglita afiŝo} other {Alpinglitaj afiŝoj}}",
|
||||
"featured_carousel.slide": "Afiŝo {current, number} de {max, number}",
|
||||
"filter_modal.added.context_mismatch_explanation": "Ĉi tiu filtrilkategorio ne kongruas kun la kunteksto en kiu vi akcesis ĉi tiun afiŝon. Se vi volas ke la afiŝo estas ankaŭ filtrita en ĉi tiu kunteksto, vi devus redakti la filtrilon.",
|
||||
"filter_modal.added.context_mismatch_title": "Ne kongruas la kunteksto!",
|
||||
"filter_modal.added.expired_explanation": "Ĉi tiu filtrilkategorio eksvalidiĝis, vu bezonos ŝanĝi la eksvaliddaton por ĝi.",
|
||||
|
|
@ -378,6 +388,9 @@
|
|||
"follow_suggestions.who_to_follow": "Kiun sekvi",
|
||||
"followed_tags": "Sekvataj kradvortoj",
|
||||
"footer.about": "Pri",
|
||||
"footer.about_mastodon": "Pri Mastodon",
|
||||
"footer.about_server": "Pri {domain}",
|
||||
"footer.about_this_server": "Pri",
|
||||
"footer.directory": "Profilujo",
|
||||
"footer.get_app": "Akiri la apon",
|
||||
"footer.keyboard_shortcuts": "Fulmoklavoj",
|
||||
|
|
@ -710,7 +723,6 @@
|
|||
"privacy.private.short": "Sekvantoj",
|
||||
"privacy.public.long": "Ĉiujn ajn ĉe kaj ekster Mastodon",
|
||||
"privacy.public.short": "Publika",
|
||||
"privacy.quote.anyone": "{visibility}, iu ajn povas citi",
|
||||
"privacy.quote.disabled": "{visibility}, malŝaltitaj citaĵoj",
|
||||
"privacy.quote.limited": "{visibility}, limigitaj citaĵoj",
|
||||
"privacy.unlisted.additional": "Ĉi tio kondutas ekzakte kiel publika, krom ke la afiŝo ne aperos en vivaj fluoj aŭ kradvortoj, esploro aŭ Mastodon-serĉo, eĉ se vi estas enskribita en la tuta konto.",
|
||||
|
|
@ -835,6 +847,7 @@
|
|||
"status.cancel_reblog_private": "Ne plu diskonigi",
|
||||
"status.cannot_quote": "Vi ne rajtas citi ĉi tiun afiŝon",
|
||||
"status.cannot_reblog": "Ĉi tiun afiŝon ne eblas diskonigi",
|
||||
"status.context.show": "Montri",
|
||||
"status.continued_thread": "Daŭrigis fadenon",
|
||||
"status.copy": "Kopii la ligilon al la afiŝo",
|
||||
"status.delete": "Forigi",
|
||||
|
|
|
|||
|
|
@ -187,6 +187,7 @@
|
|||
"bundle_modal_error.close": "Cerrar",
|
||||
"bundle_modal_error.message": "Algo salió mal al cargar esta pantalla.",
|
||||
"bundle_modal_error.retry": "Intentá de nuevo",
|
||||
"callout.dismiss": "Descartar",
|
||||
"carousel.current": "<sr>Diapositiva</sr> {current, number} / {max, number}",
|
||||
"carousel.slide": "Diapositiva {current, number} de {max, number}",
|
||||
"closed_registrations.other_server_instructions": "Ya que Mastodon es descentralizado, podés crearte una cuenta en otro servidor y todavía interactuar con éste.",
|
||||
|
|
@ -194,9 +195,16 @@
|
|||
"closed_registrations_modal.find_another_server": "Buscar otro servidor",
|
||||
"closed_registrations_modal.preamble": "Mastodon es descentralizado, por lo que no importa dónde creés tu cuenta, podrás seguir e interactuar con cualquier persona en este servidor. ¡Incluso podés montar tu propio servidor!",
|
||||
"closed_registrations_modal.title": "Registrarse en Mastodon",
|
||||
"collections.create_a_collection_hint": "Creá una colección para recomendar o compartir tus cuentas favoritas con otras personas.",
|
||||
"collections.create_collection": "Crear colección",
|
||||
"collections.delete_collection": "Eliminar colección",
|
||||
"collections.error_loading_collections": "Hubo un error al intentar cargar tus colecciones.",
|
||||
"collections.no_collections_yet": "No hay colecciones aún.",
|
||||
"collections.view_collection": "Abrir colección",
|
||||
"column.about": "Información",
|
||||
"column.blocks": "Usuarios bloqueados",
|
||||
"column.bookmarks": "Marcadores",
|
||||
"column.collections": "Mis colecciones",
|
||||
"column.community": "Línea temporal local",
|
||||
"column.create_list": "Crear lista",
|
||||
"column.direct": "Menciones privadas",
|
||||
|
|
@ -454,6 +462,7 @@
|
|||
"footer.source_code": "Ver código fuente",
|
||||
"footer.status": "Estado",
|
||||
"footer.terms_of_service": "Términos del servicio",
|
||||
"form_field.optional": "(opcional)",
|
||||
"generic.saved": "Guardado",
|
||||
"getting_started.heading": "Inicio de Mastodon",
|
||||
"hashtag.admin_moderation": "Abrir interface de moderación para #{name}",
|
||||
|
|
@ -790,7 +799,7 @@
|
|||
"privacy.private.short": "Seguidores",
|
||||
"privacy.public.long": "Cualquier persona dentro y fuera de Mastodon",
|
||||
"privacy.public.short": "Público",
|
||||
"privacy.quote.anyone": "{visibility}, todos pueden citar",
|
||||
"privacy.quote.anyone": "{visibility}, citas permitidas",
|
||||
"privacy.quote.disabled": "{visibility}, citas deshabilitadas",
|
||||
"privacy.quote.limited": "{visibility}, citas limitadas",
|
||||
"privacy.unlisted.additional": "Esto se comporta exactamente igual que con la configuración de privacidad de mensaje «Público», excepto que el mensaje no aparecerá en las líneas temporales en vivo, ni en las etiquetas, ni en la línea temporal «Explorá», ni en la búsqueda de Mastodon; incluso si optaste por hacer tu cuenta visible.",
|
||||
|
|
|
|||
|
|
@ -187,6 +187,7 @@
|
|||
"bundle_modal_error.close": "Cerrar",
|
||||
"bundle_modal_error.message": "Algo ha fallado al cargar esta pantalla.",
|
||||
"bundle_modal_error.retry": "Inténtalo de nuevo",
|
||||
"callout.dismiss": "Descartar",
|
||||
"carousel.current": "<sr>Diapositiva</sr> {current, number} / {max, number}",
|
||||
"carousel.slide": "Diapositiva {current, number} de {max, number}",
|
||||
"closed_registrations.other_server_instructions": "Como Mastodon es descentralizado, puedes crear una cuenta en otro servidor y seguir interactuando con este.",
|
||||
|
|
@ -194,9 +195,16 @@
|
|||
"closed_registrations_modal.find_another_server": "Buscar otro servidor",
|
||||
"closed_registrations_modal.preamble": "Mastodon es descentralizado, por lo que no importa dónde crees tu cuenta, podrás seguir e interactuar con cualquier persona en este servidor. ¡Incluso puedes alojarlo tú mismo!",
|
||||
"closed_registrations_modal.title": "Registrarse en Mastodon",
|
||||
"collections.create_a_collection_hint": "Crea una colección para recomendar o compartir tus cuentas favoritas con otras personas.",
|
||||
"collections.create_collection": "Crear colección",
|
||||
"collections.delete_collection": "Eliminar colección",
|
||||
"collections.error_loading_collections": "Se produjo un error al intentar cargar tus colecciones.",
|
||||
"collections.no_collections_yet": "No hay colecciones todavía.",
|
||||
"collections.view_collection": "Ver colección",
|
||||
"column.about": "Acerca de",
|
||||
"column.blocks": "Usuarios bloqueados",
|
||||
"column.bookmarks": "Marcadores",
|
||||
"column.collections": "Mis colecciones",
|
||||
"column.community": "Cronología local",
|
||||
"column.create_list": "Crear lista",
|
||||
"column.direct": "Menciones privadas",
|
||||
|
|
@ -454,6 +462,7 @@
|
|||
"footer.source_code": "Ver código fuente",
|
||||
"footer.status": "Estado",
|
||||
"footer.terms_of_service": "Condiciones del servicio",
|
||||
"form_field.optional": "(opcional)",
|
||||
"generic.saved": "Guardado",
|
||||
"getting_started.heading": "Primeros pasos",
|
||||
"hashtag.admin_moderation": "Abrir interfaz de moderación para #{name}",
|
||||
|
|
@ -790,7 +799,7 @@
|
|||
"privacy.private.short": "Seguidores",
|
||||
"privacy.public.long": "Cualquiera dentro y fuera de Mastodon",
|
||||
"privacy.public.short": "Público",
|
||||
"privacy.quote.anyone": "{visibility}, cualquiera puede citar",
|
||||
"privacy.quote.anyone": "{visibility}, citas permitidas",
|
||||
"privacy.quote.disabled": "{visibility}, citas desactivadas",
|
||||
"privacy.quote.limited": "{visibility}, citas limitadas",
|
||||
"privacy.unlisted.additional": "Esto se comporta exactamente igual que el público, excepto que el post no aparecerá en las cronologías en directo o en las etiquetas, la exploración o busquedas en Mastodon, incluso si está optado por activar la cuenta de usuario.",
|
||||
|
|
|
|||
|
|
@ -187,6 +187,7 @@
|
|||
"bundle_modal_error.close": "Cerrar",
|
||||
"bundle_modal_error.message": "Ha habido algún error mientras cargábamos esta pantalla.",
|
||||
"bundle_modal_error.retry": "Inténtalo de nuevo",
|
||||
"callout.dismiss": "Descartar",
|
||||
"carousel.current": "<sr>Diapositiva</sr> {current, number} / {max, number}",
|
||||
"carousel.slide": "Diapositiva {current, number} de {max, number}",
|
||||
"closed_registrations.other_server_instructions": "Como Mastodon es descentralizado, puedes crear una cuenta en otro servidor y seguir interactuando con este.",
|
||||
|
|
@ -194,9 +195,16 @@
|
|||
"closed_registrations_modal.find_another_server": "Buscar otro servidor",
|
||||
"closed_registrations_modal.preamble": "Mastodon es descentralizado, por lo que no importa dónde crees tu cuenta, podrás seguir e interactuar con cualquier persona en este servidor. ¡Incluso puedes alojarlo tú mismo!",
|
||||
"closed_registrations_modal.title": "Registrarse en Mastodon",
|
||||
"collections.create_a_collection_hint": "Crea una colección para recomendar o compartir tus cuentas favoritas con otros.",
|
||||
"collections.create_collection": "Crear colección",
|
||||
"collections.delete_collection": "Eliminar colección",
|
||||
"collections.error_loading_collections": "Se ha producido un error al intentar cargar tus colecciones.",
|
||||
"collections.no_collections_yet": "Aún no hay colecciones.",
|
||||
"collections.view_collection": "Ver colección",
|
||||
"column.about": "Acerca de",
|
||||
"column.blocks": "Usuarios bloqueados",
|
||||
"column.bookmarks": "Marcadores",
|
||||
"column.collections": "Mis colecciones",
|
||||
"column.community": "Cronología local",
|
||||
"column.create_list": "Crear lista",
|
||||
"column.direct": "Menciones privadas",
|
||||
|
|
@ -454,6 +462,7 @@
|
|||
"footer.source_code": "Ver código fuente",
|
||||
"footer.status": "Estado",
|
||||
"footer.terms_of_service": "Términos del servicio",
|
||||
"form_field.optional": "(opcional)",
|
||||
"generic.saved": "Guardado",
|
||||
"getting_started.heading": "Primeros pasos",
|
||||
"hashtag.admin_moderation": "Abrir interfaz de moderación para #{name}",
|
||||
|
|
@ -790,7 +799,7 @@
|
|||
"privacy.private.short": "Seguidores",
|
||||
"privacy.public.long": "Visible por todo el mundo, dentro y fuera de Mastodon",
|
||||
"privacy.public.short": "Pública",
|
||||
"privacy.quote.anyone": "{visibility}, cualquiera puede citar",
|
||||
"privacy.quote.anyone": "{visibility}, citas permitidas",
|
||||
"privacy.quote.disabled": "{visibility}, citas deshabilitadas",
|
||||
"privacy.quote.limited": "{visibility}, citas limitadas",
|
||||
"privacy.unlisted.additional": "Se comporta exactamente igual que la visibilidad pública, excepto que la publicación no aparecerá en las cronologías públicas o en las etiquetas, la sección de Explorar o la búsqueda de Mastodon, incluso si has habilitado la opción de búsqueda en tu perfil.",
|
||||
|
|
|
|||
|
|
@ -454,6 +454,7 @@
|
|||
"footer.source_code": "Lähtekood",
|
||||
"footer.status": "Olek",
|
||||
"footer.terms_of_service": "Kasutustingimused",
|
||||
"form_field.optional": "(valikuline)",
|
||||
"generic.saved": "Salvestatud",
|
||||
"getting_started.heading": "Alustamine",
|
||||
"hashtag.admin_moderation": "Ava modereerimisliides #{name} jaoks",
|
||||
|
|
@ -790,7 +791,6 @@
|
|||
"privacy.private.short": "Jälgijad",
|
||||
"privacy.public.long": "Nii kasutajad kui mittekasutajad",
|
||||
"privacy.public.short": "Avalik",
|
||||
"privacy.quote.anyone": "{visibility}, kõik võivad tsiteerida",
|
||||
"privacy.quote.disabled": "{visibility}, tsiteerimine pole lubatud",
|
||||
"privacy.quote.limited": "{visibility}, tsiteerimine on piiratud",
|
||||
"privacy.unlisted.additional": "See on olemuselt küll avalik, aga postitus ei ilmu voogudes ega teemaviidetes, lehitsedes ega Mastodoni otsingus, isegi kui konto on seadistustes avalik.",
|
||||
|
|
|
|||
|
|
@ -785,7 +785,6 @@
|
|||
"privacy.private.short": "Jarraitzaileak",
|
||||
"privacy.public.long": "Mastodonen dagoen edo ez dagoen edonor",
|
||||
"privacy.public.short": "Publikoa",
|
||||
"privacy.quote.anyone": "{visibility}, edonork aipa dezake",
|
||||
"privacy.quote.disabled": "{visibility}, aipuak desgaituta",
|
||||
"privacy.quote.limited": "{visibility}, aipuak mugatuta",
|
||||
"privacy.unlisted.additional": "Aukera honek publiko modua bezala funtzionatzen du, baina argitalpena ez da agertuko zuzeneko jarioetan edo traoletan, \"Arakatu\" atalean edo Mastodonen bilaketan, nahiz eta kontua zabaltzeko onartu duzun.",
|
||||
|
|
|
|||
|
|
@ -785,7 +785,6 @@
|
|||
"privacy.private.short": "پیگیرندگان",
|
||||
"privacy.public.long": "هرکسی در و بیرون از ماستودون",
|
||||
"privacy.public.short": "عمومی",
|
||||
"privacy.quote.anyone": "{visibility}، هرکسی میتواند نقل کند",
|
||||
"privacy.quote.disabled": "{visibility}، نقلها از کار افتاده",
|
||||
"privacy.quote.limited": "{visibility}، نقلها محدود شده",
|
||||
"privacy.unlisted.additional": "درست مثل عمومی رفتار میکند؛ جز این که فرسته در برچسبها یا خوراکهای زنده، کشف یا جستوجوی ماستودون ظاهر نخواهد شد. حتا اگر کلیّت نمایهتان اجازه داده باشد.",
|
||||
|
|
|
|||
|
|
@ -187,6 +187,7 @@
|
|||
"bundle_modal_error.close": "Sulje",
|
||||
"bundle_modal_error.message": "Jotain meni pieleen tätä näyttöä ladattaessa.",
|
||||
"bundle_modal_error.retry": "Yritä uudelleen",
|
||||
"callout.dismiss": "Hylkää",
|
||||
"carousel.current": "<sr>Dia</sr> {current, number} / {max, number}",
|
||||
"carousel.slide": "Dia {current, number} / {max, number}",
|
||||
"closed_registrations.other_server_instructions": "Koska Mastodon on hajautettu, voit luoda tilin toiselle palvelimelle ja olla silti vuorovaikutuksessa tämän kanssa.",
|
||||
|
|
@ -194,9 +195,16 @@
|
|||
"closed_registrations_modal.find_another_server": "Etsi toinen palvelin",
|
||||
"closed_registrations_modal.preamble": "Mastodon on hajautettu, joten riippumatta siitä, missä luot tilisi, voit seurata ja olla vuorovaikutuksessa kenen tahansa kanssa tällä palvelimella. Voit jopa isännöidä palvelinta!",
|
||||
"closed_registrations_modal.title": "Rekisteröityminen Mastodoniin",
|
||||
"collections.create_a_collection_hint": "Luomalla kokoelman voit suositella tai jakaa suosikkitilejäsi muiden kanssa.",
|
||||
"collections.create_collection": "Luo kokoelma",
|
||||
"collections.delete_collection": "Poista kokoelma",
|
||||
"collections.error_loading_collections": "Kokoelmien latauksessa tapahtui virhe.",
|
||||
"collections.no_collections_yet": "Ei vielä kokoelmia.",
|
||||
"collections.view_collection": "Näytä kokoelma",
|
||||
"column.about": "Tietoja",
|
||||
"column.blocks": "Estetyt käyttäjät",
|
||||
"column.bookmarks": "Kirjanmerkit",
|
||||
"column.collections": "Omat kokoelmat",
|
||||
"column.community": "Paikallinen aikajana",
|
||||
"column.create_list": "Luo lista",
|
||||
"column.direct": "Yksityismaininnat",
|
||||
|
|
@ -454,6 +462,7 @@
|
|||
"footer.source_code": "Näytä lähdekoodi",
|
||||
"footer.status": "Tila",
|
||||
"footer.terms_of_service": "Käyttöehdot",
|
||||
"form_field.optional": "(valinnainen)",
|
||||
"generic.saved": "Tallennettu",
|
||||
"getting_started.heading": "Näin pääset alkuun",
|
||||
"hashtag.admin_moderation": "Avaa tunnisteen #{name} moderointinäkymä",
|
||||
|
|
@ -790,7 +799,7 @@
|
|||
"privacy.private.short": "Seuraajat",
|
||||
"privacy.public.long": "Kuka tahansa Mastodonissa ja sen ulkopuolella",
|
||||
"privacy.public.short": "Julkinen",
|
||||
"privacy.quote.anyone": "{visibility}, kuka tahansa voi lainata",
|
||||
"privacy.quote.anyone": "{visibility}, lainaukset sallittu",
|
||||
"privacy.quote.disabled": "{visibility}, lainaukset poissa käytöstä",
|
||||
"privacy.quote.limited": "{visibility}, lainauksia rajoitettu",
|
||||
"privacy.unlisted.additional": "Tämä toimii muuten kuin julkinen, mutta julkaisut eivät näy livesyöte-, aihetunniste- tai selausnäkymissä eivätkä Mastodonin hakutuloksissa, vaikka ne olisivat käyttäjätililläsi yleisesti sallittuina.",
|
||||
|
|
|
|||
|
|
@ -187,6 +187,7 @@
|
|||
"bundle_modal_error.close": "Lat aftur",
|
||||
"bundle_modal_error.message": "Okkurt gekk galið, tá hendan síðan bleiv innlisin.",
|
||||
"bundle_modal_error.retry": "Royn umaftur",
|
||||
"callout.dismiss": "Avvís",
|
||||
"carousel.current": "<sr>Glæra</sr> {current, number} / {max, number}",
|
||||
"carousel.slide": "Glæra {current, number} av {max, number}",
|
||||
"closed_registrations.other_server_instructions": "Av tí at Mastodon er desentraliserað, kanst tú stovna eina kontu á einum øðrum ambætara og framvegis virka saman við hesum ambætaranum.",
|
||||
|
|
@ -194,9 +195,16 @@
|
|||
"closed_registrations_modal.find_another_server": "Finn ein annan ambætara",
|
||||
"closed_registrations_modal.preamble": "Mastodon er desentraliserað, so óansæð hvar tú stovnar tína kontu, so ber til hjá tær at fylgja og virka saman við einum og hvørjum á hesum ambætaranum. Tað ber enntá til at hýsa tí sjálvi!",
|
||||
"closed_registrations_modal.title": "At stovna kontu á Mastodon",
|
||||
"collections.create_a_collection_hint": "Ger eitt savn sum kann brúkast til at viðmæla ella deila yndiskontur við øðrum.",
|
||||
"collections.create_collection": "Ger savn",
|
||||
"collections.delete_collection": "Strika savn",
|
||||
"collections.error_loading_collections": "Ein feilur hendi, tá tú royndi at finna fram søvnini hjá tær.",
|
||||
"collections.no_collections_yet": "Eingi søvn enn.",
|
||||
"collections.view_collection": "Vís savn",
|
||||
"column.about": "Um",
|
||||
"column.blocks": "Bannaðir brúkarar",
|
||||
"column.bookmarks": "Bókamerki",
|
||||
"column.collections": "Míni søvn",
|
||||
"column.community": "Lokal tíðarlinja",
|
||||
"column.create_list": "Ger lista",
|
||||
"column.direct": "Privatar umrøður",
|
||||
|
|
@ -454,6 +462,7 @@
|
|||
"footer.source_code": "Vís keldukotuna",
|
||||
"footer.status": "Støða",
|
||||
"footer.terms_of_service": "Tænastutreytir",
|
||||
"form_field.optional": "(valfrítt)",
|
||||
"generic.saved": "Goymt",
|
||||
"getting_started.heading": "At byrja",
|
||||
"hashtag.admin_moderation": "Lat umsjónarmarkamót upp fyri #{name}",
|
||||
|
|
@ -790,7 +799,7 @@
|
|||
"privacy.private.short": "Fylgjarar",
|
||||
"privacy.public.long": "Øll í og uttanfyri Mastodon",
|
||||
"privacy.public.short": "Alment",
|
||||
"privacy.quote.anyone": "{visibility}, øll kunnu sitera",
|
||||
"privacy.quote.anyone": "{visibility}, siteringar loyvdar",
|
||||
"privacy.quote.disabled": "{visibility}, siteringar óvirknar",
|
||||
"privacy.quote.limited": "{visibility}, siteringar avmarkaðar",
|
||||
"privacy.unlisted.additional": "Hetta er júst sum almenn, tó verður posturin ikki vístur í samtíðarrásum ella frámerkjum, rannsakan ella Mastodon leitingum, sjálvt um valið er galdandi fyri alla kontuna.",
|
||||
|
|
|
|||
|
|
@ -187,6 +187,7 @@
|
|||
"bundle_modal_error.close": "Fermer",
|
||||
"bundle_modal_error.message": "Un problème s'est produit lors du chargement de cet écran.",
|
||||
"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}",
|
||||
"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.",
|
||||
|
|
@ -194,9 +195,16 @@
|
|||
"closed_registrations_modal.find_another_server": "Trouver un autre serveur",
|
||||
"closed_registrations_modal.preamble": "Mastodon est décentralisé, donc peu importe où vous créez votre compte, vous serez en mesure de suivre et d'interagir avec quiconque sur ce serveur. Vous pouvez même l'héberger vous-même!",
|
||||
"closed_registrations_modal.title": "S'inscrire sur Mastodon",
|
||||
"collections.create_a_collection_hint": "Créer une collection pour recommander ou partager vos comptes préférés.",
|
||||
"collections.create_collection": "Créer une collection",
|
||||
"collections.delete_collection": "Supprimer la collection",
|
||||
"collections.error_loading_collections": "Une erreur s'est produite durant le chargement de vos collections.",
|
||||
"collections.no_collections_yet": "Aucune collection pour le moment.",
|
||||
"collections.view_collection": "Voir la collection",
|
||||
"column.about": "À propos",
|
||||
"column.blocks": "Comptes bloqués",
|
||||
"column.bookmarks": "Signets",
|
||||
"column.collections": "Mes collections",
|
||||
"column.community": "Fil local",
|
||||
"column.create_list": "Créer une liste",
|
||||
"column.direct": "Mention privée",
|
||||
|
|
@ -454,6 +462,7 @@
|
|||
"footer.source_code": "Voir le code source",
|
||||
"footer.status": "État",
|
||||
"footer.terms_of_service": "Conditions d’utilisation",
|
||||
"form_field.optional": "(facultatif)",
|
||||
"generic.saved": "Sauvegardé",
|
||||
"getting_started.heading": "Pour commencer",
|
||||
"hashtag.admin_moderation": "Ouvrir l'interface de modération pour #{name}",
|
||||
|
|
|
|||
|
|
@ -187,6 +187,7 @@
|
|||
"bundle_modal_error.close": "Fermer",
|
||||
"bundle_modal_error.message": "Un problème s'est produit lors du chargement de cet écran.",
|
||||
"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}",
|
||||
"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.",
|
||||
|
|
@ -194,9 +195,16 @@
|
|||
"closed_registrations_modal.find_another_server": "Trouver un autre serveur",
|
||||
"closed_registrations_modal.preamble": "Mastodon est décentralisé : peu importe où vous créez votre compte, vous serez en mesure de suivre et d'interagir avec quiconque sur ce serveur. Vous pouvez même l'héberger !",
|
||||
"closed_registrations_modal.title": "Inscription sur Mastodon",
|
||||
"collections.create_a_collection_hint": "Créer une collection pour recommander ou partager vos comptes préférés.",
|
||||
"collections.create_collection": "Créer une collection",
|
||||
"collections.delete_collection": "Supprimer la collection",
|
||||
"collections.error_loading_collections": "Une erreur s'est produite durant le chargement de vos collections.",
|
||||
"collections.no_collections_yet": "Aucune collection pour le moment.",
|
||||
"collections.view_collection": "Voir la collection",
|
||||
"column.about": "À propos",
|
||||
"column.blocks": "Utilisateurs bloqués",
|
||||
"column.bookmarks": "Marque-pages",
|
||||
"column.collections": "Mes collections",
|
||||
"column.community": "Fil public local",
|
||||
"column.create_list": "Créer une liste",
|
||||
"column.direct": "Mentions privées",
|
||||
|
|
@ -454,6 +462,7 @@
|
|||
"footer.source_code": "Voir le code source",
|
||||
"footer.status": "État",
|
||||
"footer.terms_of_service": "Conditions d’utilisation",
|
||||
"form_field.optional": "(facultatif)",
|
||||
"generic.saved": "Sauvegardé",
|
||||
"getting_started.heading": "Pour commencer",
|
||||
"hashtag.admin_moderation": "Ouvrir l'interface de modération pour #{name}",
|
||||
|
|
|
|||
|
|
@ -790,7 +790,6 @@
|
|||
"privacy.private.short": "Leantóirí",
|
||||
"privacy.public.long": "Duine ar bith ar agus amach Mastodon",
|
||||
"privacy.public.short": "Poiblí",
|
||||
"privacy.quote.anyone": "{visibility}, is féidir le duine ar bith lua",
|
||||
"privacy.quote.disabled": "{visibility}, sleachta díchumasaithe",
|
||||
"privacy.quote.limited": "{visibility}, sleachta teoranta",
|
||||
"privacy.unlisted.additional": "Iompraíonn sé seo díreach mar a bheadh poiblí, ach amháin ní bheidh an postáil le feiceáil i bhfothaí beo nó i hashtags, in iniúchadh nó i gcuardach Mastodon, fiú má tá tú liostáilte ar fud an chuntais.",
|
||||
|
|
|
|||
|
|
@ -786,7 +786,6 @@
|
|||
"privacy.private.short": "Luchd-leantainn",
|
||||
"privacy.public.long": "Duine sam bith taobh a-staigh no a-muigh Mhastodon",
|
||||
"privacy.public.short": "Poblach",
|
||||
"privacy.quote.anyone": "{visibility}, luaidh fosgailte",
|
||||
"privacy.quote.disabled": "{visibility}, luaidh à comas",
|
||||
"privacy.quote.limited": "{visibility}, luaidh cuingichte",
|
||||
"privacy.unlisted.additional": "Tha seo coltach ris an fhaicsinneachd phoblach ach cha nochd am post air loidhnichean-ama an t-saoghail phoblaich, nan tagaichean hais no an rùrachaidh no ann an toraidhean luirg Mhastodon fiù ’s ma thug thu ro-aonta airson sin seachad.",
|
||||
|
|
|
|||
|
|
@ -187,6 +187,7 @@
|
|||
"bundle_modal_error.close": "Pechar",
|
||||
"bundle_modal_error.message": "Algo fallou mentras cargaba esta páxina.",
|
||||
"bundle_modal_error.retry": "Téntao de novo",
|
||||
"callout.dismiss": "Desbotar",
|
||||
"carousel.current": "<sr>Filmina</sr> {current, number} / {max, number}",
|
||||
"carousel.slide": "Filmina {current, number} de {max, number}",
|
||||
"closed_registrations.other_server_instructions": "Cómo Mastodon é descentralizado, podes crear unha conta noutro servidor e interactuar igualmente con este.",
|
||||
|
|
@ -194,9 +195,16 @@
|
|||
"closed_registrations_modal.find_another_server": "Atopa outro servidor",
|
||||
"closed_registrations_modal.preamble": "Mastodon é descentralizado, así que non importa onde crees a conta, poderás seguir e interactuar con calquera conta deste servidor. Incluso podes ter o teu servidor!",
|
||||
"closed_registrations_modal.title": "Crear conta en Mastodon",
|
||||
"collections.create_a_collection_hint": "Crear unha colección para recomendar ou compartir as túas contas favoritas.",
|
||||
"collections.create_collection": "Crear colección",
|
||||
"collections.delete_collection": "Eliminar colección",
|
||||
"collections.error_loading_collections": "Houbo un erro ao intentar cargar as túas coleccións.",
|
||||
"collections.no_collections_yet": "Aínda non tes coleccións.",
|
||||
"collections.view_collection": "Ver colección",
|
||||
"column.about": "Sobre",
|
||||
"column.blocks": "Usuarias bloqueadas",
|
||||
"column.bookmarks": "Marcadores",
|
||||
"column.collections": "As miñas coleccións",
|
||||
"column.community": "Cronoloxía local",
|
||||
"column.create_list": "Crear lista",
|
||||
"column.direct": "Mencións privadas",
|
||||
|
|
@ -454,6 +462,7 @@
|
|||
"footer.source_code": "Ver código fonte",
|
||||
"footer.status": "Estado",
|
||||
"footer.terms_of_service": "Condicións do servizo",
|
||||
"form_field.optional": "(optativo)",
|
||||
"generic.saved": "Gardado",
|
||||
"getting_started.heading": "Primeiros pasos",
|
||||
"hashtag.admin_moderation": "Abrir interface de moderación para ##{name}",
|
||||
|
|
@ -790,7 +799,7 @@
|
|||
"privacy.private.short": "Seguidoras",
|
||||
"privacy.public.long": "Para todas dentro e fóra de Mastodon",
|
||||
"privacy.public.short": "Público",
|
||||
"privacy.quote.anyone": "{visibility}, calquera pode citar",
|
||||
"privacy.quote.anyone": "{visibility}, permítese citar",
|
||||
"privacy.quote.disabled": "{visibility}, citas desactivadas",
|
||||
"privacy.quote.limited": "{visibility}, citas limitadas",
|
||||
"privacy.unlisted.additional": "Do mesmo xeito que público, menos que a publicación non aparecerá nas cronoloxías en directo ou nos cancelos, en descubrir ou nas buscas de Mastodon, incluso se estivese establecido nas opcións xerais da conta.",
|
||||
|
|
|
|||
|
|
@ -187,6 +187,7 @@
|
|||
"bundle_modal_error.close": "לסגור",
|
||||
"bundle_modal_error.message": "משהו השתבש בעת טעינת המסך הזה.",
|
||||
"bundle_modal_error.retry": "לנסות שוב",
|
||||
"callout.dismiss": "לבטל",
|
||||
"carousel.current": "<sr>שקופית</sr>{current, number} מתוך {max, number}",
|
||||
"carousel.slide": "שקופית {current, number} מתוך {max, number}",
|
||||
"closed_registrations.other_server_instructions": "מכיוון שמסטודון היא רשת מבוזרת, ניתן ליצור חשבון על שרת נוסף ועדיין לקיים קשר עם משתמשים בשרת זה.",
|
||||
|
|
@ -194,9 +195,16 @@
|
|||
"closed_registrations_modal.find_another_server": "חיפוש שרת אחר",
|
||||
"closed_registrations_modal.preamble": "מסטודון הוא רשת מבוזרת, כך שלא משנה היכן החשבון שלך, קיימת האפשרות לעקוב ולתקשר עם משתמשים בשרת הזה. אפשר אפילו להריץ שרת בעצמך!",
|
||||
"closed_registrations_modal.title": "להרשם למסטודון",
|
||||
"collections.create_a_collection_hint": "יצירת אוסף כדי להמליץ או לשתף את החשבונות החביבים עליך עם אחרים.",
|
||||
"collections.create_collection": "יצירת אוסף",
|
||||
"collections.delete_collection": "מחיקת האוסף",
|
||||
"collections.error_loading_collections": "חלה שגיאה בנסיון לטעון את אוספיך.",
|
||||
"collections.no_collections_yet": "עוד אין אוספים.",
|
||||
"collections.view_collection": "צפיה באוסף",
|
||||
"column.about": "אודות",
|
||||
"column.blocks": "משתמשים חסומים",
|
||||
"column.bookmarks": "סימניות",
|
||||
"column.collections": "האוספים שלי",
|
||||
"column.community": "פיד שרת מקומי",
|
||||
"column.create_list": "יצירת רשימה",
|
||||
"column.direct": "הודעות פרטיות",
|
||||
|
|
@ -454,6 +462,7 @@
|
|||
"footer.source_code": "צפיה בקוד המקור",
|
||||
"footer.status": "מצב",
|
||||
"footer.terms_of_service": "תנאי השירות",
|
||||
"form_field.optional": "(אפשרות)",
|
||||
"generic.saved": "נשמר",
|
||||
"getting_started.heading": "בואו נתחיל",
|
||||
"hashtag.admin_moderation": "פתיחת ממשק פיקוח דיון עבור #{name}",
|
||||
|
|
@ -790,7 +799,7 @@
|
|||
"privacy.private.short": "עוקבים",
|
||||
"privacy.public.long": "כל הגולשים, מחוברים למסטודון או לא",
|
||||
"privacy.public.short": "פומבי",
|
||||
"privacy.quote.anyone": "{visibility}, הציטוט מותר לכל",
|
||||
"privacy.quote.anyone": "{visibility}, רשות הציטוט נתונה",
|
||||
"privacy.quote.disabled": "{visibility}, האפשרות לציטוט מכובה",
|
||||
"privacy.quote.limited": "{visibility}, האפשרות לציטוט מוגבלת",
|
||||
"privacy.unlisted.additional": "ההתנהגות דומה להודעה ציבורית, מלבד שההודעה לא תופיע בפיד החי המקומי או בתגיות, תגליות או חיפוש מסטודון, אפילו אם ביקשת שהחשבון כולו יהיה פומבי.",
|
||||
|
|
|
|||
|
|
@ -194,9 +194,16 @@
|
|||
"closed_registrations_modal.find_another_server": "Másik kiszolgáló keresése",
|
||||
"closed_registrations_modal.preamble": "A Mastodon decentralizált, így teljesen mindegy, hol hozod létre a fiókodat, követhetsz és kapcsolódhatsz bárkivel ezen a kiszolgálón is. Saját magad is üzemeltethetsz kiszolgálót!",
|
||||
"closed_registrations_modal.title": "Regisztráció a Mastodonra",
|
||||
"collections.create_a_collection_hint": "Gyűjtemény létrehozása a kedvenc fiókok másoknak való ajánlásához.",
|
||||
"collections.create_collection": "Gyűjtemény létrehozása",
|
||||
"collections.delete_collection": "Gyűjtemény törlése",
|
||||
"collections.error_loading_collections": "Hiba történt a gyűjtemények betöltése során.",
|
||||
"collections.no_collections_yet": "Még nincsenek gyűjtemények.",
|
||||
"collections.view_collection": "Gyűjtemény megtekintése",
|
||||
"column.about": "Névjegy",
|
||||
"column.blocks": "Letiltott felhasználók",
|
||||
"column.bookmarks": "Könyvjelzők",
|
||||
"column.collections": "Saját gyűjtemények",
|
||||
"column.community": "Helyi idővonal",
|
||||
"column.create_list": "Lista létrehozása",
|
||||
"column.direct": "Személyes említések",
|
||||
|
|
@ -790,7 +797,6 @@
|
|||
"privacy.private.short": "Követők",
|
||||
"privacy.public.long": "Bárki a Mastodonon és azon kívül",
|
||||
"privacy.public.short": "Nyilvános",
|
||||
"privacy.quote.anyone": "{visibility}, bárki idézheti",
|
||||
"privacy.quote.disabled": "{visibility}, idézés letiltva",
|
||||
"privacy.quote.limited": "{visibility}, idézés korlátozva",
|
||||
"privacy.unlisted.additional": "Ez pontosan úgy viselkedik, mint a nyilvános, kivéve, hogy a bejegyzés nem jelenik meg élő hírfolyamokban, hashtagekben, felfedezésben vagy a Mastodonos keresésben, még akkor sem, ha ezt az egész fiókra engedélyezted.",
|
||||
|
|
|
|||
|
|
@ -741,7 +741,6 @@
|
|||
"privacy.private.short": "Sequitores",
|
||||
"privacy.public.long": "Quicunque, sur Mastodon o non",
|
||||
"privacy.public.short": "Public",
|
||||
"privacy.quote.anyone": "{visibility}, omnes pote citar",
|
||||
"privacy.quote.disabled": "{visibility}, citation disactivate",
|
||||
"privacy.quote.limited": "{visibility}, citation limitate",
|
||||
"privacy.unlisted.additional": "Isto es exactemente como public, excepte que le message non apparera in fluxos in vivo, in hashtags, in Explorar, o in le recerca de Mastodon, mesmo si tu ha optate pro render tote le conto discoperibile.",
|
||||
|
|
|
|||
|
|
@ -187,6 +187,7 @@
|
|||
"bundle_modal_error.close": "Loka",
|
||||
"bundle_modal_error.message": "Eitthvað fór úrskeiðis við að hlaða inn þessum skjá.",
|
||||
"bundle_modal_error.retry": "Reyndu aftur",
|
||||
"callout.dismiss": "Vísa frá",
|
||||
"carousel.current": "<sr>Skyggna</sr> {current, number} / {max, number}",
|
||||
"carousel.slide": "Skyggna {current, number} af {max, number}",
|
||||
"closed_registrations.other_server_instructions": "Þar sem Mastodon er ekki miðstýrt, þá getur þú búið til aðgang á öðrum þjóni, en samt haft samskipti við þennan.",
|
||||
|
|
@ -194,9 +195,16 @@
|
|||
"closed_registrations_modal.find_another_server": "Finna annan netþjón",
|
||||
"closed_registrations_modal.preamble": "Mastodon er ekki miðstýrt, svo það skiptir ekki máli hvar þú býrð til aðgang; þú munt get fylgt eftir og haft samskipti við hvern sem er á þessum þjóni. Þú getur jafnvel hýst þinn eigin Mastodon þjón!",
|
||||
"closed_registrations_modal.title": "Að nýskrá sig á Mastodon",
|
||||
"collections.create_a_collection_hint": "Búðu til safn með eftirlætisnotendunum þínum til að deila eða mæla með við aðra.",
|
||||
"collections.create_collection": "Búa til safn",
|
||||
"collections.delete_collection": "Eyða safni",
|
||||
"collections.error_loading_collections": "Villa kom upp þegar reynt var að hlaða inn söfnunum þínum.",
|
||||
"collections.no_collections_yet": "Engin söfn ennþá.",
|
||||
"collections.view_collection": "Skoða safn",
|
||||
"column.about": "Um hugbúnaðinn",
|
||||
"column.blocks": "Útilokaðir notendur",
|
||||
"column.bookmarks": "Bókamerki",
|
||||
"column.collections": "Söfnin mín",
|
||||
"column.community": "Staðvær tímalína",
|
||||
"column.create_list": "Búa til lista",
|
||||
"column.direct": "Einkaspjall",
|
||||
|
|
@ -454,6 +462,7 @@
|
|||
"footer.source_code": "Skoða frumkóða",
|
||||
"footer.status": "Staða",
|
||||
"footer.terms_of_service": "Þjónustuskilmálar",
|
||||
"form_field.optional": "(valfrjálst)",
|
||||
"generic.saved": "Vistað",
|
||||
"getting_started.heading": "Komast í gang",
|
||||
"hashtag.admin_moderation": "Opna umsjónarviðmót fyrir #{name}",
|
||||
|
|
@ -790,7 +799,7 @@
|
|||
"privacy.private.short": "Fylgjendur",
|
||||
"privacy.public.long": "Hver sem er, á og utan Mastodon",
|
||||
"privacy.public.short": "Opinbert",
|
||||
"privacy.quote.anyone": "{visibility}, hver sem er getur vitnað í færslu",
|
||||
"privacy.quote.anyone": "{visibility}, tilvitnanir leyfðar",
|
||||
"privacy.quote.disabled": "{visibility}, tilvitnanir eru óvirkar",
|
||||
"privacy.quote.limited": "{visibility}, tilvitnanir eru takmarkaðar",
|
||||
"privacy.unlisted.additional": "Þetta hegðar sér eins og opinber færsla, fyrir utan að færslan birtist ekki í beinum streymum eða myllumerkjum, né heldur í Mastodon-leitum jafnvel þótt þú hafir valið að falla undir slíkt í notandasniðinu þínu.",
|
||||
|
|
|
|||
|
|
@ -187,6 +187,7 @@
|
|||
"bundle_modal_error.close": "Chiudi",
|
||||
"bundle_modal_error.message": "Si è verificato un errore durante il caricamento di questa schermata.",
|
||||
"bundle_modal_error.retry": "Riprova",
|
||||
"callout.dismiss": "Ignora",
|
||||
"carousel.current": "<sr>Diapositiva</sr> {current, number} / {max, number}",
|
||||
"carousel.slide": "Diapositiva {current, number} di {max, number}",
|
||||
"closed_registrations.other_server_instructions": "Poiché Mastodon è decentralizzato, puoi creare un profilo su un altro server, pur continuando a interagire con questo.",
|
||||
|
|
@ -194,9 +195,16 @@
|
|||
"closed_registrations_modal.find_another_server": "Trova un altro server",
|
||||
"closed_registrations_modal.preamble": "Mastodon è decentralizzato, quindi, non importa dove crei il tuo profilo, potrai seguire e interagire con chiunque su questo server. Anche se sei tu stesso a ospitarlo!",
|
||||
"closed_registrations_modal.title": "Registrazione su Mastodon",
|
||||
"collections.create_a_collection_hint": "Crea una collezione per consigliare o condividere i tuoi account preferiti con altri.",
|
||||
"collections.create_collection": "Crea la collezione",
|
||||
"collections.delete_collection": "Cancella la collezione",
|
||||
"collections.error_loading_collections": "Si è verificato un errore durante il tentativo di caricare le tue collezioni.",
|
||||
"collections.no_collections_yet": "Nessuna collezione ancora.",
|
||||
"collections.view_collection": "Visualizza la collezione",
|
||||
"column.about": "Info",
|
||||
"column.blocks": "Utenti bloccati",
|
||||
"column.bookmarks": "Segnalibri",
|
||||
"column.collections": "Le mie collezioni",
|
||||
"column.community": "Cronologia locale",
|
||||
"column.create_list": "Crea lista",
|
||||
"column.direct": "Menzioni private",
|
||||
|
|
@ -454,6 +462,7 @@
|
|||
"footer.source_code": "Visualizza il codice sorgente",
|
||||
"footer.status": "Stato",
|
||||
"footer.terms_of_service": "Termini di servizio",
|
||||
"form_field.optional": "(opzionale)",
|
||||
"generic.saved": "Salvato",
|
||||
"getting_started.heading": "Per iniziare",
|
||||
"hashtag.admin_moderation": "Apri l'interfaccia di moderazione per #{name}",
|
||||
|
|
@ -790,7 +799,7 @@
|
|||
"privacy.private.short": "Follower",
|
||||
"privacy.public.long": "Chiunque dentro e fuori Mastodon",
|
||||
"privacy.public.short": "Pubblico",
|
||||
"privacy.quote.anyone": "{visibility}, chiunque può citare",
|
||||
"privacy.quote.anyone": "{visibility}, citazioni autorizzate",
|
||||
"privacy.quote.disabled": "{visibility}, citazioni disabilitate",
|
||||
"privacy.quote.limited": "{visibility}, citazioni limitate",
|
||||
"privacy.unlisted.additional": "Si comporta esattamente come pubblico, tranne per il fatto che il post non verrà visualizzato nei feed live o negli hashtag, nell'esplorazione o nella ricerca Mastodon, anche se hai attivato l'attivazione a livello di account.",
|
||||
|
|
|
|||
|
|
@ -729,7 +729,6 @@
|
|||
"privacy.private.short": "フォロワー",
|
||||
"privacy.public.long": "すべての人 (Mastodon以外も含む)",
|
||||
"privacy.public.short": "公開",
|
||||
"privacy.quote.anyone": "{visibility}、誰でも引用可能",
|
||||
"privacy.quote.disabled": "{visibility}、引用不可",
|
||||
"privacy.quote.limited": "{visibility}、引用は制限",
|
||||
"privacy.unlisted.additional": "「公開」とほとんど同じですが、リアルタイムフィードやハッシュタグ、探索機能、Mastodon検索などに投稿が表示されない点で「公開」と異なります。また、アカウント設定で投稿の検索や表示を許可している場合でも、この公開範囲を設定した投稿は前述の機能には表示されません。",
|
||||
|
|
|
|||
|
|
@ -782,7 +782,6 @@
|
|||
"privacy.private.short": "팔로워",
|
||||
"privacy.public.long": "마스토돈 내외 모두",
|
||||
"privacy.public.short": "공개",
|
||||
"privacy.quote.anyone": "{visibility}, 누구나 인용 가능",
|
||||
"privacy.quote.disabled": "{visibility}, 인용 비활성화",
|
||||
"privacy.quote.limited": "{visibility}, 제한된 인용",
|
||||
"privacy.unlisted.additional": "공개와 똑같지만 게시물이 실시간 피드나 해시태그, 둘러보기, (계정 설정에서 허용했더라도) 마스토돈 검색에서 제외됩니다.",
|
||||
|
|
|
|||
|
|
@ -747,7 +747,6 @@
|
|||
"privacy.private.short": "Sekėjai",
|
||||
"privacy.public.long": "Bet kas iš Mastodon ir ne Mastodon",
|
||||
"privacy.public.short": "Vieša",
|
||||
"privacy.quote.anyone": "{visibility}, kiekvienas gali cituoti",
|
||||
"privacy.quote.disabled": "{visibility}, paminėjimai išjungti",
|
||||
"privacy.quote.limited": "{visibility}, paminėjimai apriboti",
|
||||
"privacy.unlisted.additional": "Tai veikia lygiai taip pat, kaip ir vieša, tik įrašas nebus rodomas tiesioginiuose srautuose, grotažymėse, naršyme ar Mastodon paieškoje, net jei esi įtraukęs (-usi) visą paskyrą.",
|
||||
|
|
|
|||
|
|
@ -633,7 +633,6 @@
|
|||
"privacy.private.short": "Sekotāji",
|
||||
"privacy.public.long": "Jebkurš Mastodon platformā un ārpus tās",
|
||||
"privacy.public.short": "Publisks",
|
||||
"privacy.quote.anyone": "{visibility}, jebkurš var citēt",
|
||||
"privacy.quote.disabled": "{visibility}, aizliegta citēšana",
|
||||
"privacy.quote.limited": "{visibility}, ierobežota citēšana",
|
||||
"privacy.unlisted.additional": "Šis uzvedas tieši kā publisks, izņemot to, ka ieraksts neparādīsies tiešraides barotnēs vai tēmturos, izpētē vai Mastodon meklēšanā, pat ja esi to norādījis visa konta ietvaros.",
|
||||
|
|
|
|||
|
|
@ -786,7 +786,6 @@
|
|||
"privacy.private.short": "跟tuè lí ê",
|
||||
"privacy.public.long": "逐ê lâng(無論佇Mastodon以內á是以外)",
|
||||
"privacy.public.short": "公開ê",
|
||||
"privacy.quote.anyone": "{visibility},ta̍k ê lâng lóng ē當引用",
|
||||
"privacy.quote.disabled": "{visibility},停止引用PO文",
|
||||
"privacy.quote.limited": "{visibility},PO文引用受限",
|
||||
"privacy.unlisted.additional": "Tse ê行為kap公開相siâng,m̄-koh 就算lí佇口座設定phah開有關ê公開功能,PO文mā bē顯示佇即時ê動態、hashtag、探索kap Mastodon ê搜尋結果。",
|
||||
|
|
|
|||
|
|
@ -57,6 +57,7 @@
|
|||
"account.go_to_profile": "Ga naar profiel",
|
||||
"account.hide_reblogs": "Boosts van @{name} verbergen",
|
||||
"account.in_memoriam": "In memoriam.",
|
||||
"account.joined_long": "Geregistreerd op {date}",
|
||||
"account.joined_short": "Geregistreerd op",
|
||||
"account.languages": "Getoonde talen wijzigen",
|
||||
"account.link_verified_on": "Eigendom van deze link is gecontroleerd op {date}",
|
||||
|
|
@ -90,6 +91,8 @@
|
|||
"account.unmute": "@{name} niet langer negeren",
|
||||
"account.unmute_notifications_short": "Meldingen niet langer negeren",
|
||||
"account.unmute_short": "Niet langer negeren",
|
||||
"account_fields_modal.close": "Sluiten",
|
||||
"account_fields_modal.title": "Info over {name}",
|
||||
"account_note.placeholder": "Klik om een opmerking toe te voegen",
|
||||
"admin.dashboard.daily_retention": "Retentiegraad van gebruikers per dag, vanaf registratie",
|
||||
"admin.dashboard.monthly_retention": "Retentiegraad van gebruikers per maand, vanaf registratie",
|
||||
|
|
@ -184,6 +187,7 @@
|
|||
"bundle_modal_error.close": "Sluiten",
|
||||
"bundle_modal_error.message": "Er ging iets mis tijdens het laden van dit scherm.",
|
||||
"bundle_modal_error.retry": "Opnieuw proberen",
|
||||
"callout.dismiss": "Afwijzen",
|
||||
"carousel.current": "<sr>Bericht</sr> {current, number} / {max, number}",
|
||||
"carousel.slide": "Bericht {current, number} van {max, number}",
|
||||
"closed_registrations.other_server_instructions": "Omdat Mastodon gedecentraliseerd is, kun je op een andere server een account registreren en vanaf daar nog steeds met deze server communiceren.",
|
||||
|
|
@ -191,9 +195,16 @@
|
|||
"closed_registrations_modal.find_another_server": "Een andere server zoeken",
|
||||
"closed_registrations_modal.preamble": "Mastodon is gedecentraliseerd. Op welke server je ook een account hebt, je kunt overal vandaan mensen op deze server volgen en er mee interactie hebben. Je kunt zelfs zelf een Mastodon-server hosten!",
|
||||
"closed_registrations_modal.title": "Registreren op Mastodon",
|
||||
"collections.create_a_collection_hint": "Een verzameling aanmaken om je favoriete accounts aan te bevelen of te delen met anderen.",
|
||||
"collections.create_collection": "Verzameling aanmaken",
|
||||
"collections.delete_collection": "Verzameling verwijderen",
|
||||
"collections.error_loading_collections": "Er is een fout opgetreden bij het laden van je verzamelingen.",
|
||||
"collections.no_collections_yet": "Nog geen verzamelingen.",
|
||||
"collections.view_collection": "Verzameling bekijken",
|
||||
"column.about": "Over",
|
||||
"column.blocks": "Geblokkeerde gebruikers",
|
||||
"column.bookmarks": "Bladwijzers",
|
||||
"column.collections": "Mijn verzamelingen",
|
||||
"column.community": "Lokale tijdlijn",
|
||||
"column.create_list": "Lijst aanmaken",
|
||||
"column.direct": "Privéberichten",
|
||||
|
|
@ -451,6 +462,7 @@
|
|||
"footer.source_code": "Broncode bekijken",
|
||||
"footer.status": "Status",
|
||||
"footer.terms_of_service": "Gebruiksvoorwaarden",
|
||||
"form_field.optional": "(optioneel)",
|
||||
"generic.saved": "Opgeslagen",
|
||||
"getting_started.heading": "Aan de slag",
|
||||
"hashtag.admin_moderation": "Moderatie-omgeving van #{name} openen",
|
||||
|
|
@ -589,6 +601,7 @@
|
|||
"load_pending": "{count, plural, one {# nieuw item} other {# nieuwe items}}",
|
||||
"loading_indicator.label": "Laden…",
|
||||
"media_gallery.hide": "Verberg",
|
||||
"minicard.more_items": "+{count}",
|
||||
"moved_to_account_banner.text": "Omdat je naar {movedToAccount} bent verhuisd is jouw account {disabledAccount} momenteel uitgeschakeld.",
|
||||
"mute_modal.hide_from_notifications": "Onder meldingen verbergen",
|
||||
"mute_modal.hide_options": "Opties verbergen",
|
||||
|
|
@ -786,7 +799,6 @@
|
|||
"privacy.private.short": "Volgers",
|
||||
"privacy.public.long": "Iedereen op Mastodon en daarbuiten",
|
||||
"privacy.public.short": "Openbaar",
|
||||
"privacy.quote.anyone": "{visibility}, iedereen mag citeren",
|
||||
"privacy.quote.disabled": "{visibility}, citeren uitgeschakeld",
|
||||
"privacy.quote.limited": "{visibility}, citeren beperkt",
|
||||
"privacy.unlisted.additional": "Dit is vergelijkbaar met openbaar, behalve dat het bericht niet op openbare tijdlijnen, onder hashtags, verkennen of zoeken verschijnt, zelfs als je je account daarvoor hebt ingesteld.",
|
||||
|
|
|
|||
|
|
@ -790,7 +790,6 @@
|
|||
"privacy.private.short": "Fylgjarar",
|
||||
"privacy.public.long": "Kven som helst på og av Mastodon",
|
||||
"privacy.public.short": "Offentleg",
|
||||
"privacy.quote.anyone": "{visibility}, alle kan sitera",
|
||||
"privacy.quote.disabled": "{visibility}, ingen kan sitera",
|
||||
"privacy.quote.limited": "{visibility}, avgrensa sitat",
|
||||
"privacy.unlisted.additional": "Dette er akkurat som offentleg, bortsett frå at innlegga ikkje dukkar opp i direktestraumar eller emneknaggar, i oppdagingar eller Mastodon-søk, sjølv om du har sagt ja til at kontoen skal vera synleg.",
|
||||
|
|
|
|||
|
|
@ -57,6 +57,7 @@
|
|||
"account.go_to_profile": "Przejdź do profilu",
|
||||
"account.hide_reblogs": "Ukryj podbicia od @{name}",
|
||||
"account.in_memoriam": "Ku pamięci.",
|
||||
"account.joined_long": "Dołączył(a) dnia {date}",
|
||||
"account.joined_short": "Dołączył(a)",
|
||||
"account.languages": "Zmień subskrybowane języki",
|
||||
"account.link_verified_on": "Własność tego odnośnika została potwierdzona {date}",
|
||||
|
|
@ -90,6 +91,8 @@
|
|||
"account.unmute": "Nie wyciszaj @{name}",
|
||||
"account.unmute_notifications_short": "Nie wyciszaj powiadomień",
|
||||
"account.unmute_short": "Nie wyciszaj",
|
||||
"account_fields_modal.close": "Zamknij",
|
||||
"account_fields_modal.title": "Informacje o {name}",
|
||||
"account_note.placeholder": "Kliknij, aby dodać notatkę",
|
||||
"admin.dashboard.daily_retention": "Wskaźnik utrzymania użytkowników według dni od rejestracji",
|
||||
"admin.dashboard.monthly_retention": "Wskaźnik utrzymania użytkowników według miesięcy od rejestracji",
|
||||
|
|
@ -126,6 +129,8 @@
|
|||
"annual_report.summary.archetype.booster.desc_self": "Pozostałeś na polowaniu na posty do wzmocnienia i wzmocnienia innych twórców doskonałym celem.",
|
||||
"annual_report.summary.archetype.booster.name": "Łucznik",
|
||||
"annual_report.summary.archetype.die_drei_fragezeichen": "???",
|
||||
"annual_report.summary.archetype.lurker.desc_public": "Wiemy, że {name} był(a) tam gdzieś i cieszył(a) się Mastodonem na swój własny, cichy sposób.",
|
||||
"annual_report.summary.archetype.lurker.desc_self": "Wiemy, że byłeś(-aś) tam gdzieś i cieszyłeś(-aś) się Mastodonem na swój własny, cichy sposób.",
|
||||
"annual_report.summary.archetype.lurker.name": "Stoik",
|
||||
"annual_report.summary.archetype.oracle.name": "Wyrocznia",
|
||||
"annual_report.summary.archetype.pollster.name": "Zastanawiacz",
|
||||
|
|
@ -764,7 +769,6 @@
|
|||
"privacy.private.short": "Obserwujący",
|
||||
"privacy.public.long": "Każdy na i poza Mastodon",
|
||||
"privacy.public.short": "Publiczny",
|
||||
"privacy.quote.anyone": "{visibility}, każdy może cytować",
|
||||
"privacy.quote.disabled": "{visibility}, cytaty wyłączone",
|
||||
"privacy.quote.limited": "{visibility}, cytaty ograniczone",
|
||||
"privacy.unlisted.additional": "Dostępny podobnie jak wpis publiczny, ale nie będzie widoczny w aktualnościach, hashtagach ani wyszukiwarce Mastodon, nawet jeśli twoje konto jest widoczne.",
|
||||
|
|
|
|||
|
|
@ -785,7 +785,6 @@
|
|||
"privacy.private.short": "Seguidores",
|
||||
"privacy.public.long": "Qualquer um dentro ou fora do Mastodon",
|
||||
"privacy.public.short": "Público",
|
||||
"privacy.quote.anyone": "{visibility} Qualquer pessoa pode citar",
|
||||
"privacy.quote.disabled": "{visibility} Citações desabilitadas",
|
||||
"privacy.quote.limited": "{visibility} Citações limitadas",
|
||||
"privacy.unlisted.additional": "Isso se comporta exatamente como público, exceto que a publicação não aparecerá nos _feeds ao vivo_ ou nas _hashtags_, explorar, ou barra de busca, mesmo que você seja escolhido em toda a conta.",
|
||||
|
|
|
|||
|
|
@ -187,6 +187,7 @@
|
|||
"bundle_modal_error.close": "Fechar",
|
||||
"bundle_modal_error.message": "Algo correu mal ao carregar este ecrã.",
|
||||
"bundle_modal_error.retry": "Tenta de novo",
|
||||
"callout.dismiss": "Descartar",
|
||||
"carousel.current": "<sr>Slide</sr> {current, number} / {max, number}",
|
||||
"carousel.slide": "Slide {current, number} de {max, number}",
|
||||
"closed_registrations.other_server_instructions": "Visto que o Mastodon é descentralizado, podes criar uma conta noutro servidor e interagir com este na mesma.",
|
||||
|
|
@ -194,9 +195,16 @@
|
|||
"closed_registrations_modal.find_another_server": "Procurar outro servidor",
|
||||
"closed_registrations_modal.preamble": "O Mastodon é descentralizado, por isso não importa onde a tua conta é criada, pois continuarás a poder acompanhar e interagir com qualquer um neste servidor. Podes até alojar o teu próprio servidor!",
|
||||
"closed_registrations_modal.title": "Criar uma conta no Mastodon",
|
||||
"collections.create_a_collection_hint": "Crie uma coleção para recomendar ou partilhar as suas contas favoritas com outras pessoas.",
|
||||
"collections.create_collection": "Criar coleção",
|
||||
"collections.delete_collection": "Eliminar coleção",
|
||||
"collections.error_loading_collections": "Ocorreu um erro ao tentar carregar as suas coleções.",
|
||||
"collections.no_collections_yet": "Ainda não existem coleções.",
|
||||
"collections.view_collection": "Ver coleções",
|
||||
"column.about": "Sobre",
|
||||
"column.blocks": "Utilizadores bloqueados",
|
||||
"column.bookmarks": "Marcadores",
|
||||
"column.collections": "As minhas coleções",
|
||||
"column.community": "Cronologia local",
|
||||
"column.create_list": "Criar lista",
|
||||
"column.direct": "Menções privadas",
|
||||
|
|
@ -454,6 +462,7 @@
|
|||
"footer.source_code": "Ver código-fonte",
|
||||
"footer.status": "Estado",
|
||||
"footer.terms_of_service": "Termos de serviço",
|
||||
"form_field.optional": "(opcional)",
|
||||
"generic.saved": "Guardado",
|
||||
"getting_started.heading": "Primeiros passos",
|
||||
"hashtag.admin_moderation": "Abrir interface de moderação para #{name}",
|
||||
|
|
@ -790,7 +799,6 @@
|
|||
"privacy.private.short": "Seguidores",
|
||||
"privacy.public.long": "Qualquer pessoa no Mastodon ou não",
|
||||
"privacy.public.short": "Público",
|
||||
"privacy.quote.anyone": "{visibility}, qualquer pessoa pode citar",
|
||||
"privacy.quote.disabled": "{visibility}, citações desativadas",
|
||||
"privacy.quote.limited": "{visibility}, citações limitadas",
|
||||
"privacy.unlisted.additional": "Este comportamento é exatamente igual ao do público, exceto que a publicação não aparecerá em cronologias, nas etiquetas, ao explorar ou na pesquisa do Mastodon, mesmo que tenhas optado por participar em toda a tua conta.",
|
||||
|
|
|
|||
|
|
@ -759,7 +759,6 @@
|
|||
"privacy.private.short": "Для подписчиков",
|
||||
"privacy.public.long": "Для кого угодно в интернете",
|
||||
"privacy.public.short": "Публичный",
|
||||
"privacy.quote.anyone": "{visibility}, цитировать разрешено всем",
|
||||
"privacy.quote.disabled": "{visibility}, без возможности цитирования",
|
||||
"privacy.quote.limited": "{visibility}, с ограничениями цитирования",
|
||||
"privacy.unlisted.additional": "Похоже на «Публичный» за исключением того, что пост не появится ни в живых лентах, ни в лентах хештегов, ни в разделе «Актуальное», ни в поиске Mastodon, даже если вы разрешили поиск по своим постам в настройках профиля.",
|
||||
|
|
|
|||
|
|
@ -665,7 +665,6 @@
|
|||
"privacy.private.short": "Sledovatelia",
|
||||
"privacy.public.long": "Ktokoľvek na Mastodone aj mimo neho",
|
||||
"privacy.public.short": "Verejné",
|
||||
"privacy.quote.anyone": "{visibility}, hocikto môže citovať",
|
||||
"privacy.quote.disabled": "{visibility}, citovanie nepovolené",
|
||||
"privacy.quote.limited": "{visibility}, citovanie obmedzené",
|
||||
"privacy.unlisted.additional": "Presne ako verejné, s tým rozdielom, že sa príspevok nezobrazí v živých kanáloch, hashtagoch, objavovaní či vo vyhľadávaní na Mastodone, aj keď máte pre účet objaviteľnosť zapnutú.",
|
||||
|
|
|
|||
|
|
@ -21,10 +21,12 @@
|
|||
"account.block_domain": "Blokiraj domeno {domain}",
|
||||
"account.block_short": "Blokiraj",
|
||||
"account.blocked": "Blokirano",
|
||||
"account.blocking": "Blokirano",
|
||||
"account.cancel_follow_request": "Umakni zahtevo za sledenje",
|
||||
"account.copy": "Kopiraj povezavo do profila",
|
||||
"account.direct": "Zasebno omeni @{name}",
|
||||
"account.disable_notifications": "Ne obveščaj me več, ko ima @{name} novo objavo",
|
||||
"account.domain_blocking": "Blokirana domena",
|
||||
"account.edit_profile": "Uredi profil",
|
||||
"account.edit_profile_short": "Uredi",
|
||||
"account.enable_notifications": "Obvesti me, ko ima @{name} novo objavo",
|
||||
|
|
@ -45,6 +47,7 @@
|
|||
"account.followers": "Sledilci",
|
||||
"account.followers.empty": "Nihče še ne sledi temu uporabniku.",
|
||||
"account.followers_counter": "{count, plural, one {{counter} sledilec} two {{counter} sledilca} few {{counter} sledilci} other {{counter} sledilcev}}",
|
||||
"account.followers_you_know_counter": "{counter} znanih",
|
||||
"account.following": "Sledim",
|
||||
"account.following_counter": "{count, plural, one {{counter} sleden} two {{counter} sledena} few {{counter} sledeni} other {{counter} sledenih}}",
|
||||
"account.follows.empty": "Ta uporabnik še ne sledi nikomur.",
|
||||
|
|
@ -87,6 +90,7 @@
|
|||
"account.unmute_notifications_short": "Izklopi utišanje obvestil",
|
||||
"account.unmute_short": "Povrni glas",
|
||||
"account_fields_modal.close": "Zapri",
|
||||
"account_fields_modal.title": "Podatki o: {name}",
|
||||
"account_note.placeholder": "Kliknite, da dodate opombo",
|
||||
"admin.dashboard.daily_retention": "Mera ohranjanja uporabnikov po dnevih od registracije",
|
||||
"admin.dashboard.monthly_retention": "Mera ohranjanja uporabnikov po mesecih od registracije",
|
||||
|
|
@ -113,6 +117,11 @@
|
|||
"annual_report.announcement.action_dismiss": "Ne, hvala",
|
||||
"annual_report.nav_item.badge": "Nov",
|
||||
"annual_report.shared_page.donate": "Prispevaj",
|
||||
"annual_report.shared_page.footer": "S {heart} ustvarila ekipa Mastodon",
|
||||
"annual_report.summary.archetype.booster.name": "Lokostrelec",
|
||||
"annual_report.summary.archetype.die_drei_fragezeichen": "???",
|
||||
"annual_report.summary.archetype.lurker.name": "Stoik",
|
||||
"annual_report.summary.archetype.oracle.name": "Orakelj",
|
||||
"annual_report.summary.archetype.replier.name": "Metulj",
|
||||
"annual_report.summary.archetype.reveal": "Razkrij moj arhetip",
|
||||
"annual_report.summary.archetype.title_public": "Arhetip {name}",
|
||||
|
|
@ -153,14 +162,21 @@
|
|||
"bundle_modal_error.close": "Zapri",
|
||||
"bundle_modal_error.message": "Med nalaganjem prikaza je prišlo do napake.",
|
||||
"bundle_modal_error.retry": "Poskusi znova",
|
||||
"callout.dismiss": "Opusti",
|
||||
"carousel.current": "<sr>Prosojnica</sr> {current, number} / {max, number}",
|
||||
"carousel.slide": "Prosojnica {current, number} od {max, number}",
|
||||
"closed_registrations.other_server_instructions": "Ker je Mastodon decentraliziran, lahko ustvarite račun na drugem strežniku in ste še vedno v interakciji s tem.",
|
||||
"closed_registrations_modal.description": "Odpiranje računa na domeni {domain} trenutno ni možno, upoštevajte pa, da ne potrebujete računa prav na domeni {domain}, da bi uporabljali Mastodon.",
|
||||
"closed_registrations_modal.find_another_server": "Najdi drug strežnik",
|
||||
"closed_registrations_modal.preamble": "Mastodon je decentraliziran, kar pomeni, da ni pomembno, kje ustvarite svoj račun; od koder koli je mogoče slediti in komunicirati z vsemi s tega strežnika. Strežnik lahko gostite tudi sami!",
|
||||
"closed_registrations_modal.title": "Registracija v Mastodon",
|
||||
"collections.create_collection": "Ustvari zbirko",
|
||||
"collections.delete_collection": "Izbriši zbirko",
|
||||
"collections.view_collection": "Pokaži zbirko",
|
||||
"column.about": "O programu",
|
||||
"column.blocks": "Blokirani uporabniki",
|
||||
"column.bookmarks": "Zaznamki",
|
||||
"column.collections": "Moje zbirke",
|
||||
"column.community": "Krajevna časovnica",
|
||||
"column.create_list": "Ustvari seznam",
|
||||
"column.direct": "Zasebne omembe",
|
||||
|
|
@ -223,6 +239,7 @@
|
|||
"confirmations.delete_list.confirm": "Izbriši",
|
||||
"confirmations.delete_list.message": "Ali ste prepričani, da želite trajno izbrisati ta seznam?",
|
||||
"confirmations.delete_list.title": "Želite izbrisati seznam?",
|
||||
"confirmations.discard_draft.confirm": "Opusti in nadaljuj",
|
||||
"confirmations.discard_draft.edit.cancel": "Nadaljuj z urejanjem",
|
||||
"confirmations.discard_draft.post.cancel": "Nadaljuj na osnutku",
|
||||
"confirmations.discard_edit_media.confirm": "Opusti",
|
||||
|
|
@ -297,6 +314,7 @@
|
|||
"domain_pill.your_handle": "Vaša ročica:",
|
||||
"domain_pill.your_server": "Vaše digitalno domovanje, kjer bivajo vse vaše objave. Vam ni všeč? Kadar koli ga prenesite med strežniki in z njim tudi svoje sledilce.",
|
||||
"domain_pill.your_username": "Vaš edinstveni identifikator na tem strežniku. Uporabnike z istim uporabniškim imenom je možno najti na različnih strežnikih.",
|
||||
"dropdown.empty": "Izberite možnost",
|
||||
"embed.instructions": "Vstavite to objavo na svojo spletno stran tako, da kopirate spodnjo kodo.",
|
||||
"embed.preview": "Takole bo videti:",
|
||||
"emoji_button.activity": "Dejavnost",
|
||||
|
|
@ -346,6 +364,8 @@
|
|||
"explore.trending_links": "Novice",
|
||||
"explore.trending_statuses": "Objave",
|
||||
"explore.trending_tags": "Ključniki",
|
||||
"featured_carousel.current": "<sr>Objava</sr> {current, number} / {max, number}",
|
||||
"featured_carousel.slide": "Objava {current, number} od {max, number}",
|
||||
"filter_modal.added.context_mismatch_explanation": "Ta kategorija filtra ne velja za kontekst, v katerem ste dostopali do te objave. Če želite, da je objava filtrirana tudi v tem kontekstu, morate urediti filter.",
|
||||
"filter_modal.added.context_mismatch_title": "Neujemanje konteksta!",
|
||||
"filter_modal.added.expired_explanation": "Ta kategorija filtra je pretekla. Morali boste spremeniti datum veljavnosti, da bo veljal še naprej.",
|
||||
|
|
@ -397,6 +417,7 @@
|
|||
"footer.source_code": "Pokaži izvorno kodo",
|
||||
"footer.status": "Stanje",
|
||||
"footer.terms_of_service": "Pogoji uporabe",
|
||||
"form_field.optional": "(neobvezno)",
|
||||
"generic.saved": "Shranjeno",
|
||||
"getting_started.heading": "Kako začeti",
|
||||
"hashtag.admin_moderation": "Odpri vmesnik za moderiranje za #{name}",
|
||||
|
|
@ -486,6 +507,7 @@
|
|||
"keyboard_shortcuts.toggle_hidden": "Pokaži/skrij besedilo za CW",
|
||||
"keyboard_shortcuts.toggle_sensitivity": "Pokaži/skrij predstavnosti",
|
||||
"keyboard_shortcuts.toot": "Začni povsem novo objavo",
|
||||
"keyboard_shortcuts.top": "Premakni na vrh seznama",
|
||||
"keyboard_shortcuts.translate": "za prevod objave",
|
||||
"keyboard_shortcuts.unfocus": "Odstrani pozornost z območja za sestavljanje besedila/iskanje",
|
||||
"keyboard_shortcuts.up": "Premakni navzgor po seznamu",
|
||||
|
|
@ -529,6 +551,7 @@
|
|||
"load_pending": "{count, plural, one {# nov element} two {# nova elementa} few {# novi elementi} other {# novih elementov}}",
|
||||
"loading_indicator.label": "Nalaganje …",
|
||||
"media_gallery.hide": "Skrij",
|
||||
"minicard.more_items": "+{count}",
|
||||
"moved_to_account_banner.text": "Vaš račun {disabledAccount} je trenutno onemogočen, ker ste se prestavili na {movedToAccount}.",
|
||||
"mute_modal.hide_from_notifications": "Skrijte se pred obvestili",
|
||||
"mute_modal.hide_options": "Skrij možnosti",
|
||||
|
|
@ -555,6 +578,8 @@
|
|||
"navigation_bar.follows_and_followers": "Sledenja in sledilci",
|
||||
"navigation_bar.import_export": "Uvoz in izvoz",
|
||||
"navigation_bar.lists": "Seznami",
|
||||
"navigation_bar.live_feed_local": "Vir v živo (krajevno)",
|
||||
"navigation_bar.live_feed_public": "Vir v živo (javno)",
|
||||
"navigation_bar.logout": "Odjava",
|
||||
"navigation_bar.moderation": "Moderiranje",
|
||||
"navigation_bar.more": "Več",
|
||||
|
|
@ -865,11 +890,16 @@
|
|||
"status.mute_conversation": "Utišaj pogovor",
|
||||
"status.open": "Razširi to objavo",
|
||||
"status.pin": "Pripni na profil",
|
||||
"status.quote": "Citiraj",
|
||||
"status.quote.cancel": "Prekliči citat",
|
||||
"status.quote_error.blocked_account_hint.title": "Ta objava je skrita, ker ste blokirali up. @{name}.",
|
||||
"status.quote_error.blocked_domain_hint.title": "Ta objava je skrita, ker ste blokirali {domain}.",
|
||||
"status.quote_error.filtered": "Skrito zaradi enega od vaših filtrov",
|
||||
"status.quote_error.limited_account_hint.action": "Vseeno pokaži",
|
||||
"status.quote_error.limited_account_hint.title": "Ta račun so moderatorji {domain} skrili.",
|
||||
"status.quote_error.muted_account_hint.title": "Ta objava je skrita, ker ste utišali up. @{name}.",
|
||||
"status.quote_error.not_available": "Objava ni na voljo",
|
||||
"status.quote_error.revoked": "Avtor je umaknil objavo",
|
||||
"status.quote_followers_only": "Samo sledilci lahko citirajo to objavo",
|
||||
"status.quote_policy_change": "Spremenite, kdo lahko citira",
|
||||
"status.quote_private": "Zasebnih objav ni možno citirati",
|
||||
|
|
@ -926,6 +956,7 @@
|
|||
"upload_button.label": "Dodajte slike, video ali zvočno datoteko",
|
||||
"upload_error.limit": "Omejitev prenosa datoteke je presežena.",
|
||||
"upload_error.poll": "Prenos datoteke z anketami ni dovoljen.",
|
||||
"upload_error.quote": "Prenos datoteke s citati ni dovoljen.",
|
||||
"upload_form.drag_and_drop.instructions": "Predstavnostno priponko lahko poberete tako, da pritisnete preslednico ali vnašalko. S puščicami na tipkovnici premikate priponko v posamezno smer. Priponko lahko odložite na novem položaju s ponovnim pritiskom na preslednico ali vnašalko ali pa dejanje prekličete s tipko ubežnica.",
|
||||
"upload_form.drag_and_drop.on_drag_cancel": "Premikanje priponke je preklicano. Predstavnostna priponka {item} je padla nazaj na prejšnje mesto.",
|
||||
"upload_form.drag_and_drop.on_drag_end": "Predstavnostna priponka {item} je padla nazaj.",
|
||||
|
|
|
|||
|
|
@ -185,6 +185,7 @@
|
|||
"bundle_modal_error.close": "Mbylle",
|
||||
"bundle_modal_error.message": "Diç shkoi ters, teksa ngarkohej kjo skenë.",
|
||||
"bundle_modal_error.retry": "Riprovoni",
|
||||
"callout.dismiss": "Hidhe tej",
|
||||
"carousel.current": "<sr>Diapozitivi</sr> {current, number} / {max, number}",
|
||||
"carousel.slide": "Diapozitivi {current, number} nga {max, number} gjithsej",
|
||||
"closed_registrations.other_server_instructions": "Ngaqë Mastodon-i është i decentralizuar, mund të krijoni një llogari në një tjetër shërbyes dhe prapë të ndëveproni me këtë këtu.",
|
||||
|
|
@ -192,9 +193,16 @@
|
|||
"closed_registrations_modal.find_another_server": "Gjeni shërbyes tjetër",
|
||||
"closed_registrations_modal.preamble": "Mastodon-i është i decentralizuar, ndaj pavarësisht se ku krijoni llogarinë tuaj, do të jeni në gjendje të ndiqni dhe ndërveproni me këdo në këtë shërbyes. Mundeni madje edhe ta strehoni ju vetë!",
|
||||
"closed_registrations_modal.title": "Po regjistroheni në Mastodon",
|
||||
"collections.create_a_collection_hint": "Krijoni një koleksion për ta rekomanduar, ose për të ndarë me të tjerët llogaritë tuaja të parapëlqyera.",
|
||||
"collections.create_collection": "Krijoni koleksion",
|
||||
"collections.delete_collection": "Fshije koleksionin",
|
||||
"collections.error_loading_collections": "Pati një gabim teksa provohej të ngarkoheshin koleksionet tuaj.",
|
||||
"collections.no_collections_yet": "Ende pa koleksione.",
|
||||
"collections.view_collection": "Shiheni koleksionin",
|
||||
"column.about": "Mbi",
|
||||
"column.blocks": "Përdorues të bllokuar",
|
||||
"column.bookmarks": "Faqerojtës",
|
||||
"column.collections": "Koleksionet e mi",
|
||||
"column.community": "Rrjedhë kohore vendore",
|
||||
"column.create_list": "Krijo listë",
|
||||
"column.direct": "Përmendje private",
|
||||
|
|
@ -452,6 +460,7 @@
|
|||
"footer.source_code": "Shihni kodin burim",
|
||||
"footer.status": "Gjendje",
|
||||
"footer.terms_of_service": "Kushte shërbimi",
|
||||
"form_field.optional": "(opsionale)",
|
||||
"generic.saved": "U ruajt",
|
||||
"getting_started.heading": "Si t’ia fillohet",
|
||||
"hashtag.admin_moderation": "Hap ndërfaqe moderimi për #{name}",
|
||||
|
|
@ -788,7 +797,7 @@
|
|||
"privacy.private.short": "Ndjekës",
|
||||
"privacy.public.long": "Cilido që hyn e del në Mastodon",
|
||||
"privacy.public.short": "Publik",
|
||||
"privacy.quote.anyone": "{visibility}, mund të citojë cilido",
|
||||
"privacy.quote.anyone": "{visibility}, lejohen citimet",
|
||||
"privacy.quote.disabled": "{visibility}, citimet janë çaktivizuar",
|
||||
"privacy.quote.limited": "{visibility}, citime të kufizuara",
|
||||
"privacy.unlisted.additional": "Ky sillet saktësisht si publik, vetëm se postimi s’do të shfaqet në prurje të drejtpërdrejta, ose në hashtag-ë, te eksploroni, apo kërkim në Mastodon, edhe kur keni zgjedhur të jetë për tërë llogarinë.",
|
||||
|
|
|
|||
|
|
@ -57,6 +57,7 @@
|
|||
"account.go_to_profile": "Gå till profilen",
|
||||
"account.hide_reblogs": "Dölj boostar från @{name}",
|
||||
"account.in_memoriam": "Till minne av.",
|
||||
"account.joined_long": "Gick med {date}",
|
||||
"account.joined_short": "Gick med",
|
||||
"account.languages": "Ändra vilka språk du helst vill se i ditt flöde",
|
||||
"account.link_verified_on": "Ägarskap för denna länk kontrollerades den {date}",
|
||||
|
|
@ -90,6 +91,8 @@
|
|||
"account.unmute": "Sluta tysta @{name}",
|
||||
"account.unmute_notifications_short": "Aktivera aviseringsljud",
|
||||
"account.unmute_short": "Avtysta",
|
||||
"account_fields_modal.close": "Stäng",
|
||||
"account_fields_modal.title": "{name}s info",
|
||||
"account_note.placeholder": "Klicka för att lägga till anteckning",
|
||||
"admin.dashboard.daily_retention": "Användarlojalitet per dag efter registrering",
|
||||
"admin.dashboard.monthly_retention": "Användarlojalitet per månad efter registrering",
|
||||
|
|
@ -184,6 +187,7 @@
|
|||
"bundle_modal_error.close": "Stäng",
|
||||
"bundle_modal_error.message": "Något gick fel när skärmen laddades.",
|
||||
"bundle_modal_error.retry": "Försök igen",
|
||||
"callout.dismiss": "Avfärda",
|
||||
"carousel.current": "<sr>Bild</sr>{current, number} / {max, number}",
|
||||
"carousel.slide": "Bild {current, number} av {max, number}",
|
||||
"closed_registrations.other_server_instructions": "Eftersom Mastodon är decentraliserat kan du skapa ett konto på en annan server och fortfarande interagera med denna.",
|
||||
|
|
@ -191,9 +195,16 @@
|
|||
"closed_registrations_modal.find_another_server": "Hitta en annan server",
|
||||
"closed_registrations_modal.preamble": "Mastodon är decentraliserat så oavsett var du skapar ditt konto kommer du att kunna följa och interagera med någon på denna server. Du kan också köra din egen server!",
|
||||
"closed_registrations_modal.title": "Registrera sig på Mastodon",
|
||||
"collections.create_a_collection_hint": "Skapa en samling för att rekommendera eller dela dina favoritkonton med andra.",
|
||||
"collections.create_collection": "Skapa samling",
|
||||
"collections.delete_collection": "Radera samling",
|
||||
"collections.error_loading_collections": "Det uppstod ett fel när dina samlingar skulle laddas.",
|
||||
"collections.no_collections_yet": "Inga samlingar än.",
|
||||
"collections.view_collection": "Visa samling",
|
||||
"column.about": "Om",
|
||||
"column.blocks": "Blockerade användare",
|
||||
"column.bookmarks": "Bokmärken",
|
||||
"column.collections": "Mina samlingar",
|
||||
"column.community": "Lokal tidslinje",
|
||||
"column.create_list": "Skapa lista",
|
||||
"column.direct": "Privata omnämnande",
|
||||
|
|
@ -786,7 +797,6 @@
|
|||
"privacy.private.short": "Följare",
|
||||
"privacy.public.long": "Alla på och utanför Mastodon",
|
||||
"privacy.public.short": "Offentlig",
|
||||
"privacy.quote.anyone": "{visibility}, vem som helst kan citera",
|
||||
"privacy.quote.disabled": "{visibility}, citat inaktiverade",
|
||||
"privacy.quote.limited": "{visibility}, citat begränsade",
|
||||
"privacy.unlisted.additional": "Detta fungerar precis som offentlig, förutom att inlägget inte visas i liveflöden eller hashtaggar, utforska eller Mastodon-sökning, även om du har valt detta för hela kontot.",
|
||||
|
|
|
|||
|
|
@ -708,7 +708,6 @@
|
|||
"privacy.private.short": "ผู้ติดตาม",
|
||||
"privacy.public.long": "ใครก็ตามที่อยู่ในและนอก Mastodon",
|
||||
"privacy.public.short": "สาธารณะ",
|
||||
"privacy.quote.anyone": "{visibility}, ใครก็ตามสามารถอ้างอิง",
|
||||
"privacy.quote.disabled": "{visibility}, ปิดใช้งานการอ้างอิงแล้ว",
|
||||
"privacy.quote.limited": "{visibility}, จำกัดการอ้างอิงอยู่",
|
||||
"privacy.unlisted.additional": "สิ่งนี้ทำงานเหมือนกับสาธารณะทุกประการ ยกเว้นโพสต์จะไม่ปรากฏในฟีดสดหรือแฮชแท็ก, การสำรวจ หรือการค้นหา Mastodon แม้ว่าคุณได้เลือกรับทั่วทั้งบัญชีก็ตาม",
|
||||
|
|
|
|||
|
|
@ -187,6 +187,7 @@
|
|||
"bundle_modal_error.close": "Kapat",
|
||||
"bundle_modal_error.message": "Bu ekran yüklenirken bir şeyler ters gitti.",
|
||||
"bundle_modal_error.retry": "Tekrar deneyin",
|
||||
"callout.dismiss": "Yoksay",
|
||||
"carousel.current": "<sr>Slayt</sr> {current, number} / {max, number}",
|
||||
"carousel.slide": "Slayt {current, number} / {max, number}",
|
||||
"closed_registrations.other_server_instructions": "Mastodon merkeziyetsiz olduğu için, başka bir sunucuda bir hesap oluşturabilir ve bu sunucuyla etkileşimde bulunmaya devam edebilirsiniz.",
|
||||
|
|
@ -194,9 +195,16 @@
|
|||
"closed_registrations_modal.find_another_server": "Başka sunucu bul",
|
||||
"closed_registrations_modal.preamble": "Mastodon merkeziyetsizdir, bu yüzden hesabınızı nerede oluşturursanız oluşturun, bu sunucudaki herhangi birini takip edebilecek veya onunla etkileşebileceksiniz. Hatta kendi sunucunuzu bile barındırabilirsiniz!",
|
||||
"closed_registrations_modal.title": "Mastodon'a kayıt olmak",
|
||||
"collections.create_a_collection_hint": "En sevdiğiniz hesapları başkalarına önermek veya paylaşmak için bir koleksiyon oluşturun.",
|
||||
"collections.create_collection": "Koleksiyon oluştur",
|
||||
"collections.delete_collection": "Koleksiyonu sil",
|
||||
"collections.error_loading_collections": "Koleksiyonlarınızı yüklemeye çalışırken bir hata oluştu.",
|
||||
"collections.no_collections_yet": "Henüz hiçbir koleksiyon yok.",
|
||||
"collections.view_collection": "Koleksiyonu görüntüle",
|
||||
"column.about": "Hakkında",
|
||||
"column.blocks": "Engellenen kullanıcılar",
|
||||
"column.bookmarks": "Yer İşaretleri",
|
||||
"column.collections": "Koleksiyonlarım",
|
||||
"column.community": "Yerel ağ akışı",
|
||||
"column.create_list": "Liste oluştur",
|
||||
"column.direct": "Özel bahsetmeler",
|
||||
|
|
@ -454,6 +462,7 @@
|
|||
"footer.source_code": "Kaynak kodu görüntüle",
|
||||
"footer.status": "Durum",
|
||||
"footer.terms_of_service": "Hizmet şartları",
|
||||
"form_field.optional": "(isteğe bağlı)",
|
||||
"generic.saved": "Kaydet",
|
||||
"getting_started.heading": "Başlarken",
|
||||
"hashtag.admin_moderation": "#{name} için denetim arayüzünü açın",
|
||||
|
|
@ -790,7 +799,7 @@
|
|||
"privacy.private.short": "Takipçiler",
|
||||
"privacy.public.long": "Mastodon'da olan olmayan herkes",
|
||||
"privacy.public.short": "Herkese açık",
|
||||
"privacy.quote.anyone": "{visibility}, herkes alıntılayabilir",
|
||||
"privacy.quote.anyone": "{visibility}, alıntı yapılabilir",
|
||||
"privacy.quote.disabled": "{visibility}, alıntı yapılamaz",
|
||||
"privacy.quote.limited": "{visibility}, sınırlı alıntı",
|
||||
"privacy.unlisted.additional": "Bu neredeyse herkese açık gibi çalışır, tek farkı gönderi canlı akışlarda veya etiketlerde, keşfette, veya Mastodon aramasında gözükmez, hesap çapında öyle seçmiş olsanız bile.",
|
||||
|
|
|
|||
|
|
@ -718,7 +718,6 @@
|
|||
"privacy.private.short": "Підписники",
|
||||
"privacy.public.long": "Усі з Mastodon",
|
||||
"privacy.public.short": "Публічно",
|
||||
"privacy.quote.anyone": "{visibility}, будь-хто може цитувати",
|
||||
"privacy.quote.disabled": "{visibility}, цитування вимкнено",
|
||||
"privacy.quote.limited": "{visibility}, цитування обмежено",
|
||||
"privacy.unlisted.additional": "Має таку ж поведінку, як у людей, але повідомлення не з'являтимуться у стрічках або хештегах, оглядах, або пошуку Mastodon, навіть якщо ви використовуєте облікові записи.",
|
||||
|
|
|
|||
Some files were not shown because too many files have changed in this diff Show More
Loading…
Reference in New Issue
Block a user