Merge commit '24c25ec4f503eb1b27b4e417d15ea62b5b9ee9fb' into glitch-soc/merge-upstream
@@ -63,7 +63,7 @@ docker-compose.override.yml
|
||||
|
||||
# Ignore emoji map file
|
||||
/app/javascript/mastodon/features/emoji/emoji_map.json
|
||||
/app/javascript/mastodon/features/emoji/emoji_sheet.json
|
||||
/app/javascript/mastodon/features/emoji/emoji_data.json
|
||||
|
||||
# Ignore locale files
|
||||
/app/javascript/mastodon/locales/*.json
|
||||
|
||||
2
Gemfile
@@ -212,7 +212,7 @@ group :development, :test do
|
||||
gem 'test-prof', require: false
|
||||
|
||||
# RSpec runner for rails
|
||||
gem 'rspec-rails', '~> 7.0'
|
||||
gem 'rspec-rails', '~> 8.0'
|
||||
end
|
||||
|
||||
group :production do
|
||||
|
||||
26
Gemfile.lock
@@ -160,7 +160,7 @@ GEM
|
||||
cocoon (1.2.15)
|
||||
color_diff (0.1)
|
||||
concurrent-ruby (1.3.5)
|
||||
connection_pool (2.5.2)
|
||||
connection_pool (2.5.3)
|
||||
cose (1.3.1)
|
||||
cbor (~> 0.5.9)
|
||||
openssl-signature_algorithm (~> 1.0)
|
||||
@@ -435,7 +435,7 @@ GEM
|
||||
mutex_m (0.3.0)
|
||||
net-http (0.6.0)
|
||||
uri
|
||||
net-imap (0.5.6)
|
||||
net-imap (0.5.8)
|
||||
date
|
||||
net-protocol
|
||||
net-ldap (0.19.0)
|
||||
@@ -711,7 +711,7 @@ GEM
|
||||
rotp (6.3.0)
|
||||
rouge (4.5.1)
|
||||
rpam2 (4.0.2)
|
||||
rqrcode (3.0.0)
|
||||
rqrcode (3.1.0)
|
||||
chunky_png (~> 1.0)
|
||||
rqrcode_core (~> 2.0)
|
||||
rqrcode_core (2.0.0)
|
||||
@@ -721,18 +721,18 @@ GEM
|
||||
rspec-mocks (~> 3.13.0)
|
||||
rspec-core (3.13.3)
|
||||
rspec-support (~> 3.13.0)
|
||||
rspec-expectations (3.13.3)
|
||||
rspec-expectations (3.13.4)
|
||||
diff-lcs (>= 1.2.0, < 2.0)
|
||||
rspec-support (~> 3.13.0)
|
||||
rspec-github (3.0.0)
|
||||
rspec-core (~> 3.0)
|
||||
rspec-mocks (3.13.2)
|
||||
rspec-mocks (3.13.3)
|
||||
diff-lcs (>= 1.2.0, < 2.0)
|
||||
rspec-support (~> 3.13.0)
|
||||
rspec-rails (7.1.1)
|
||||
actionpack (>= 7.0)
|
||||
activesupport (>= 7.0)
|
||||
railties (>= 7.0)
|
||||
rspec-rails (8.0.0)
|
||||
actionpack (>= 7.2)
|
||||
activesupport (>= 7.2)
|
||||
railties (>= 7.2)
|
||||
rspec-core (~> 3.13)
|
||||
rspec-expectations (~> 3.13)
|
||||
rspec-mocks (~> 3.13)
|
||||
@@ -742,8 +742,8 @@ GEM
|
||||
rspec-expectations (~> 3.0)
|
||||
rspec-mocks (~> 3.0)
|
||||
sidekiq (>= 5, < 9)
|
||||
rspec-support (3.13.2)
|
||||
rubocop (1.75.3)
|
||||
rspec-support (3.13.3)
|
||||
rubocop (1.75.4)
|
||||
json (~> 2.3)
|
||||
language_server-protocol (~> 3.17.0.2)
|
||||
lint_roller (~> 1.1.0)
|
||||
@@ -842,7 +842,7 @@ GEM
|
||||
base64
|
||||
stoplight (4.1.1)
|
||||
redlock (~> 1.0)
|
||||
stringio (3.1.6)
|
||||
stringio (3.1.7)
|
||||
strong_migrations (2.3.0)
|
||||
activerecord (>= 7)
|
||||
swd (2.0.3)
|
||||
@@ -1045,7 +1045,7 @@ DEPENDENCIES
|
||||
redis-namespace (~> 1.10)
|
||||
rqrcode (~> 3.0)
|
||||
rspec-github (~> 3.0)
|
||||
rspec-rails (~> 7.0)
|
||||
rspec-rails (~> 8.0)
|
||||
rspec-sidekiq (~> 5.0)
|
||||
rubocop
|
||||
rubocop-capybara
|
||||
|
||||
@@ -27,6 +27,13 @@ module ContextHelper
|
||||
suspended: { 'toot' => 'http://joinmastodon.org/ns#', 'suspended' => 'toot:suspended' },
|
||||
attribution_domains: { 'toot' => 'http://joinmastodon.org/ns#', 'attributionDomains' => { '@id' => 'toot:attributionDomains', '@type' => '@id' } },
|
||||
quote_requests: { 'QuoteRequest' => 'https://w3id.org/fep/044f#QuoteRequest' },
|
||||
interaction_policies: {
|
||||
'gts' => 'https://gotosocial.org/ns#',
|
||||
'interactionPolicy' => { '@id' => 'gts:interactionPolicy', '@type' => '@id' },
|
||||
'canQuote' => { '@id' => 'gts:canQuote', '@type' => '@id' },
|
||||
'automaticApproval' => { '@id' => 'gts:automaticApproval', '@type' => '@id' },
|
||||
'manualApproval' => { '@id' => 'gts:manualApproval', '@type' => '@id' },
|
||||
},
|
||||
}.freeze
|
||||
|
||||
def full_context
|
||||
|
||||
@@ -1,18 +1,18 @@
|
||||
import { createAction } from '@reduxjs/toolkit';
|
||||
|
||||
import { apiRemoveAccountFromFollowers } from 'mastodon/api/accounts';
|
||||
import type { ApiAccountJSON } from 'mastodon/api_types/accounts';
|
||||
import {
|
||||
apiRemoveAccountFromFollowers,
|
||||
apiGetEndorsedAccounts,
|
||||
} from 'mastodon/api/accounts';
|
||||
import type { ApiRelationshipJSON } from 'mastodon/api_types/relationships';
|
||||
import { createDataLoadingThunk } from 'mastodon/store/typed_functions';
|
||||
|
||||
import { importFetchedAccounts } from './importer';
|
||||
|
||||
export const revealAccount = createAction<{
|
||||
id: string;
|
||||
}>('accounts/revealAccount');
|
||||
|
||||
export const importAccounts = createAction<{ accounts: ApiAccountJSON[] }>(
|
||||
'accounts/importAccounts',
|
||||
);
|
||||
|
||||
function actionWithSkipLoadingTrue<Args extends object>(args: Args) {
|
||||
return {
|
||||
payload: {
|
||||
@@ -104,3 +104,12 @@ export const removeAccountFromFollowers = createDataLoadingThunk(
|
||||
apiRemoveAccountFromFollowers(accountId),
|
||||
(relationship) => ({ relationship }),
|
||||
);
|
||||
|
||||
export const fetchEndorsedAccounts = createDataLoadingThunk(
|
||||
'accounts/endorsements',
|
||||
({ accountId }: { accountId: string }) => apiGetEndorsedAccounts(accountId),
|
||||
(data, { dispatch }) => {
|
||||
dispatch(importFetchedAccounts(data));
|
||||
return data;
|
||||
},
|
||||
);
|
||||
|
||||
@@ -1,34 +0,0 @@
|
||||
import api from '../api';
|
||||
|
||||
export const FEATURED_TAGS_FETCH_REQUEST = 'FEATURED_TAGS_FETCH_REQUEST';
|
||||
export const FEATURED_TAGS_FETCH_SUCCESS = 'FEATURED_TAGS_FETCH_SUCCESS';
|
||||
export const FEATURED_TAGS_FETCH_FAIL = 'FEATURED_TAGS_FETCH_FAIL';
|
||||
|
||||
export const fetchFeaturedTags = (id) => (dispatch, getState) => {
|
||||
if (getState().getIn(['user_lists', 'featured_tags', id, 'items'])) {
|
||||
return;
|
||||
}
|
||||
|
||||
dispatch(fetchFeaturedTagsRequest(id));
|
||||
|
||||
api().get(`/api/v1/accounts/${id}/featured_tags`)
|
||||
.then(({ data }) => dispatch(fetchFeaturedTagsSuccess(id, data)))
|
||||
.catch(err => dispatch(fetchFeaturedTagsFail(id, err)));
|
||||
};
|
||||
|
||||
export const fetchFeaturedTagsRequest = (id) => ({
|
||||
type: FEATURED_TAGS_FETCH_REQUEST,
|
||||
id,
|
||||
});
|
||||
|
||||
export const fetchFeaturedTagsSuccess = (id, tags) => ({
|
||||
type: FEATURED_TAGS_FETCH_SUCCESS,
|
||||
id,
|
||||
tags,
|
||||
});
|
||||
|
||||
export const fetchFeaturedTagsFail = (id, error) => ({
|
||||
type: FEATURED_TAGS_FETCH_FAIL,
|
||||
id,
|
||||
error,
|
||||
});
|
||||
7
app/javascript/mastodon/actions/featured_tags.ts
Normal file
@@ -0,0 +1,7 @@
|
||||
import { apiGetFeaturedTags } from 'mastodon/api/accounts';
|
||||
import { createDataLoadingThunk } from 'mastodon/store/typed_functions';
|
||||
|
||||
export const fetchFeaturedTags = createDataLoadingThunk(
|
||||
'accounts/featured_tags',
|
||||
({ accountId }: { accountId: string }) => apiGetFeaturedTags(accountId),
|
||||
);
|
||||
7
app/javascript/mastodon/actions/importer/accounts.ts
Normal file
@@ -0,0 +1,7 @@
|
||||
import { createAction } from '@reduxjs/toolkit';
|
||||
|
||||
import type { ApiAccountJSON } from 'mastodon/api_types/accounts';
|
||||
|
||||
export const importAccounts = createAction<{ accounts: ApiAccountJSON[] }>(
|
||||
'accounts/importAccounts',
|
||||
);
|
||||
@@ -1,7 +1,6 @@
|
||||
import { createPollFromServerJSON } from 'mastodon/models/poll';
|
||||
|
||||
import { importAccounts } from '../accounts_typed';
|
||||
|
||||
import { importAccounts } from './accounts';
|
||||
import { normalizeStatus } from './normalizer';
|
||||
import { importPolls } from './polls';
|
||||
|
||||
|
||||
@@ -1,5 +1,7 @@
|
||||
import { apiRequestPost } from 'mastodon/api';
|
||||
import { apiRequestPost, apiRequestGet } from 'mastodon/api';
|
||||
import type { ApiAccountJSON } from 'mastodon/api_types/accounts';
|
||||
import type { ApiRelationshipJSON } from 'mastodon/api_types/relationships';
|
||||
import type { ApiHashtagJSON } from 'mastodon/api_types/tags';
|
||||
|
||||
export const apiSubmitAccountNote = (id: string, value: string) =>
|
||||
apiRequestPost<ApiRelationshipJSON>(`v1/accounts/${id}/note`, {
|
||||
@@ -23,3 +25,9 @@ export const apiRemoveAccountFromFollowers = (id: string) =>
|
||||
apiRequestPost<ApiRelationshipJSON>(
|
||||
`v1/accounts/${id}/remove_from_followers`,
|
||||
);
|
||||
|
||||
export const apiGetFeaturedTags = (id: string) =>
|
||||
apiRequestGet<ApiHashtagJSON>(`v1/accounts/${id}/featured_tags`);
|
||||
|
||||
export const apiGetEndorsedAccounts = (id: string) =>
|
||||
apiRequestGet<ApiAccountJSON>(`v1/accounts/${id}/endorsements`);
|
||||
|
||||
@@ -297,6 +297,7 @@ interface DropdownProps<Item = MenuItem> {
|
||||
scrollable?: boolean;
|
||||
scrollKey?: string;
|
||||
status?: ImmutableMap<string, unknown>;
|
||||
forceDropdown?: boolean;
|
||||
renderItem?: RenderItemFn<Item>;
|
||||
renderHeader?: RenderHeaderFn<Item>;
|
||||
onOpen?: () => void;
|
||||
@@ -316,6 +317,7 @@ export const Dropdown = <Item = MenuItem,>({
|
||||
disabled,
|
||||
scrollable,
|
||||
status,
|
||||
forceDropdown = false,
|
||||
renderItem,
|
||||
renderHeader,
|
||||
onOpen,
|
||||
@@ -386,7 +388,7 @@ export const Dropdown = <Item = MenuItem,>({
|
||||
dispatch(fetchRelationships([prefetchAccountId]));
|
||||
}
|
||||
|
||||
if (isUserTouching()) {
|
||||
if (isUserTouching() && !forceDropdown) {
|
||||
dispatch(
|
||||
openModal({
|
||||
modalType: 'ACTIONS',
|
||||
@@ -416,6 +418,7 @@ export const Dropdown = <Item = MenuItem,>({
|
||||
handleItemClick,
|
||||
open,
|
||||
items,
|
||||
forceDropdown,
|
||||
handleClose,
|
||||
],
|
||||
);
|
||||
|
||||
@@ -116,6 +116,7 @@ export const EditedTimestamp: React.FC<{
|
||||
renderHeader={renderHeader}
|
||||
onOpen={handleOpen}
|
||||
onItemClick={handleItemClick}
|
||||
forceDropdown
|
||||
>
|
||||
<button className='dropdown-menu__text-button'>
|
||||
<FormattedMessage
|
||||
|
||||
@@ -1,24 +1,32 @@
|
||||
import { FormattedMessage } from 'react-intl';
|
||||
|
||||
import { LoadingIndicator } from './loading_indicator';
|
||||
|
||||
interface Props {
|
||||
onClick: (event: React.MouseEvent) => void;
|
||||
disabled?: boolean;
|
||||
visible?: boolean;
|
||||
loading?: boolean;
|
||||
}
|
||||
export const LoadMore: React.FC<Props> = ({
|
||||
onClick,
|
||||
disabled,
|
||||
visible = true,
|
||||
loading = false,
|
||||
}) => {
|
||||
return (
|
||||
<button
|
||||
type='button'
|
||||
className='load-more'
|
||||
disabled={disabled || !visible}
|
||||
disabled={disabled || loading || !visible}
|
||||
style={{ visibility: visible ? 'visible' : 'hidden' }}
|
||||
onClick={onClick}
|
||||
>
|
||||
<FormattedMessage id='status.load_more' defaultMessage='Load more' />
|
||||
{loading ? (
|
||||
<LoadingIndicator />
|
||||
) : (
|
||||
<FormattedMessage id='status.load_more' defaultMessage='Load more' />
|
||||
)}
|
||||
</button>
|
||||
);
|
||||
};
|
||||
|
||||
@@ -7,19 +7,21 @@ import { useParams } from 'react-router';
|
||||
import type { Map as ImmutableMap } from 'immutable';
|
||||
import { List as ImmutableList } from 'immutable';
|
||||
|
||||
import { fetchEndorsedAccounts } from 'mastodon/actions/accounts';
|
||||
import { fetchFeaturedTags } from 'mastodon/actions/featured_tags';
|
||||
import { expandAccountFeaturedTimeline } from 'mastodon/actions/timelines';
|
||||
import { Account } from 'mastodon/components/account';
|
||||
import { ColumnBackButton } from 'mastodon/components/column_back_button';
|
||||
import { LoadingIndicator } from 'mastodon/components/loading_indicator';
|
||||
import { RemoteHint } from 'mastodon/components/remote_hint';
|
||||
import StatusContainer from 'mastodon/containers/status_container';
|
||||
import { AccountHeader } from 'mastodon/features/account_timeline/components/account_header';
|
||||
import BundleColumnError from 'mastodon/features/ui/components/bundle_column_error';
|
||||
import Column from 'mastodon/features/ui/components/column';
|
||||
import { useAccountId } from 'mastodon/hooks/useAccountId';
|
||||
import { useAccountVisibility } from 'mastodon/hooks/useAccountVisibility';
|
||||
import { useAppDispatch, useAppSelector } from 'mastodon/store';
|
||||
|
||||
import { AccountHeader } from '../account_timeline/components/account_header';
|
||||
import Column from '../ui/components/column';
|
||||
|
||||
import { EmptyMessage } from './components/empty_message';
|
||||
import { FeaturedTag } from './components/featured_tag';
|
||||
import type { TagMap } from './components/featured_tag';
|
||||
@@ -29,7 +31,9 @@ interface Params {
|
||||
id?: string;
|
||||
}
|
||||
|
||||
const AccountFeatured = () => {
|
||||
const AccountFeatured: React.FC<{ multiColumn: boolean }> = ({
|
||||
multiColumn,
|
||||
}) => {
|
||||
const accountId = useAccountId();
|
||||
const { suspended, blockedBy, hidden } = useAccountVisibility(accountId);
|
||||
const forceEmptyState = suspended || blockedBy || hidden;
|
||||
@@ -40,7 +44,8 @@ const AccountFeatured = () => {
|
||||
useEffect(() => {
|
||||
if (accountId) {
|
||||
void dispatch(expandAccountFeaturedTimeline(accountId));
|
||||
dispatch(fetchFeaturedTags(accountId));
|
||||
void dispatch(fetchFeaturedTags({ accountId }));
|
||||
void dispatch(fetchEndorsedAccounts({ accountId }));
|
||||
}
|
||||
}, [accountId, dispatch]);
|
||||
|
||||
@@ -67,6 +72,17 @@ const AccountFeatured = () => {
|
||||
ImmutableList(),
|
||||
) as ImmutableList<string>,
|
||||
);
|
||||
const featuredAccountIds = useAppSelector(
|
||||
(state) =>
|
||||
state.user_lists.getIn(
|
||||
['featured_accounts', accountId, 'items'],
|
||||
ImmutableList(),
|
||||
) as ImmutableList<string>,
|
||||
);
|
||||
|
||||
if (accountId === null) {
|
||||
return <BundleColumnError multiColumn={multiColumn} errorType='routing' />;
|
||||
}
|
||||
|
||||
if (isLoading) {
|
||||
return (
|
||||
@@ -78,7 +94,11 @@ const AccountFeatured = () => {
|
||||
);
|
||||
}
|
||||
|
||||
if (featuredStatusIds.isEmpty() && featuredTags.isEmpty()) {
|
||||
if (
|
||||
featuredStatusIds.isEmpty() &&
|
||||
featuredTags.isEmpty() &&
|
||||
featuredAccountIds.isEmpty()
|
||||
) {
|
||||
return (
|
||||
<AccountFeaturedWrapper accountId={accountId}>
|
||||
<EmptyMessage
|
||||
@@ -131,6 +151,19 @@ const AccountFeatured = () => {
|
||||
))}
|
||||
</>
|
||||
)}
|
||||
{!featuredAccountIds.isEmpty() && (
|
||||
<>
|
||||
<h4 className='column-subheading'>
|
||||
<FormattedMessage
|
||||
id='account.featured.accounts'
|
||||
defaultMessage='Profiles'
|
||||
/>
|
||||
</h4>
|
||||
{featuredAccountIds.map((featuredAccountId) => (
|
||||
<Account key={featuredAccountId} id={featuredAccountId} />
|
||||
))}
|
||||
</>
|
||||
)}
|
||||
<RemoteHint accountId={accountId} />
|
||||
</div>
|
||||
</Column>
|
||||
|
||||
@@ -147,7 +147,7 @@ export const AccountGallery: React.FC<{
|
||||
[dispatch],
|
||||
);
|
||||
|
||||
if (accountId && !isAccount) {
|
||||
if (accountId === null) {
|
||||
return <BundleColumnError multiColumn={multiColumn} errorType='routing' />;
|
||||
}
|
||||
|
||||
|
||||
@@ -107,7 +107,6 @@ const messages = defineMessages({
|
||||
id: 'account.disable_notifications',
|
||||
defaultMessage: 'Stop notifying me when @{name} posts',
|
||||
},
|
||||
pins: { id: 'navigation_bar.pins', defaultMessage: 'Pinned posts' },
|
||||
preferences: {
|
||||
id: 'navigation_bar.preferences',
|
||||
defaultMessage: 'Preferences',
|
||||
@@ -451,7 +450,6 @@ export const AccountHeader: React.FC<{
|
||||
text: intl.formatMessage(messages.preferences),
|
||||
href: '/settings/preferences',
|
||||
});
|
||||
arr.push({ text: intl.formatMessage(messages.pins), to: '/pinned' });
|
||||
arr.push(null);
|
||||
arr.push({
|
||||
text: intl.formatMessage(messages.follow_requests),
|
||||
|
||||
@@ -13,7 +13,6 @@ import { normalizeForLookup } from 'mastodon/reducers/accounts_map';
|
||||
import { getAccountHidden } from 'mastodon/selectors/accounts';
|
||||
|
||||
import { lookupAccount, fetchAccount } from '../../actions/accounts';
|
||||
import { fetchFeaturedTags } from '../../actions/featured_tags';
|
||||
import { expandAccountFeaturedTimeline, expandAccountTimeline, connectTimeline, disconnectTimeline } from '../../actions/timelines';
|
||||
import { ColumnBackButton } from '../../components/column_back_button';
|
||||
import { LoadingIndicator } from '../../components/loading_indicator';
|
||||
@@ -27,7 +26,7 @@ import { LimitedAccountHint } from './components/limited_account_hint';
|
||||
const emptyList = ImmutableList();
|
||||
|
||||
const mapStateToProps = (state, { params: { acct, id, tagged }, withReplies = false }) => {
|
||||
const accountId = id || state.getIn(['accounts_map', normalizeForLookup(acct)]);
|
||||
const accountId = id || state.accounts_map[normalizeForLookup(acct)];
|
||||
|
||||
if (accountId === null) {
|
||||
return {
|
||||
@@ -86,7 +85,6 @@ class AccountTimeline extends ImmutablePureComponent {
|
||||
dispatch(expandAccountFeaturedTimeline(accountId, { tagged }));
|
||||
}
|
||||
|
||||
dispatch(fetchFeaturedTags(accountId));
|
||||
dispatch(expandAccountTimeline(accountId, { withReplies, tagged }));
|
||||
|
||||
if (accountId === me) {
|
||||
|
||||
@@ -9,7 +9,6 @@ import { useAppDispatch } from 'mastodon/store';
|
||||
|
||||
const messages = defineMessages({
|
||||
edit_profile: { id: 'account.edit_profile', defaultMessage: 'Edit profile' },
|
||||
pins: { id: 'navigation_bar.pins', defaultMessage: 'Pinned posts' },
|
||||
preferences: {
|
||||
id: 'navigation_bar.preferences',
|
||||
defaultMessage: 'Preferences',
|
||||
@@ -53,7 +52,6 @@ export const ActionBar: React.FC = () => {
|
||||
text: intl.formatMessage(messages.preferences),
|
||||
href: '/settings/preferences',
|
||||
},
|
||||
{ text: intl.formatMessage(messages.pins), to: '/pinned' },
|
||||
null,
|
||||
{
|
||||
text: intl.formatMessage(messages.follow_requests),
|
||||
|
||||
@@ -40,7 +40,7 @@ let EmojiPicker, Emoji; // load asynchronously
|
||||
|
||||
const listenerOptions = supportsPassiveEvents ? { passive: true, capture: true } : true;
|
||||
|
||||
const backgroundImageFn = () => `${assetHost}/emoji/sheet_15.png`;
|
||||
const backgroundImageFn = () => `${assetHost}/emoji/sheet_15_1.png`;
|
||||
|
||||
const notFoundFn = () => (
|
||||
<div className='emoji-mart-no-results'>
|
||||
|
||||
@@ -130,6 +130,7 @@ export const Directory: React.FC<{
|
||||
}, [dispatch, order, local]);
|
||||
|
||||
const pinned = !!columnId;
|
||||
const initialLoad = isLoading && accountIds.size === 0;
|
||||
|
||||
const scrollableArea = (
|
||||
<div className='scrollable'>
|
||||
@@ -170,7 +171,7 @@ export const Directory: React.FC<{
|
||||
</div>
|
||||
|
||||
<div className='directory__list'>
|
||||
{isLoading ? (
|
||||
{initialLoad ? (
|
||||
<LoadingIndicator />
|
||||
) : (
|
||||
accountIds.map((accountId) => (
|
||||
@@ -179,7 +180,11 @@ export const Directory: React.FC<{
|
||||
)}
|
||||
</div>
|
||||
|
||||
<LoadMore onClick={handleLoadMore} visible={!isLoading} />
|
||||
<LoadMore
|
||||
onClick={handleLoadMore}
|
||||
visible={!initialLoad}
|
||||
loading={isLoading}
|
||||
/>
|
||||
</div>
|
||||
);
|
||||
|
||||
|
||||
@@ -7,94 +7,21 @@
|
||||
|
||||
// This version comment should be bumped each time the emoji data is changed
|
||||
// to ensure that the prevaled file is regenerated by Babel
|
||||
// version: 3
|
||||
// version: 4
|
||||
|
||||
// This json file contains the names of the categories.
|
||||
const emojiMart5LocalesData = require('@emoji-mart/data/i18n/en.json');
|
||||
const emojiMart5Data = require('@emoji-mart/data/sets/15/all.json');
|
||||
const { NimbleEmojiIndex } = require('emoji-mart');
|
||||
const { uncompress: emojiMartUncompress } = require('emoji-mart/dist/utils/data');
|
||||
const _ = require('lodash');
|
||||
|
||||
|
||||
let data = require('./emoji_data.json');
|
||||
const emojiMap = require('./emoji_map.json');
|
||||
// This json file is downloaded from https://github.com/iamcal/emoji-data/
|
||||
// and is used to correct the sheet coordinates since we're using that repo's sheet
|
||||
const emojiSheetData = require('./emoji_sheet.json');
|
||||
const { unicodeToFilename } = require('./unicode_to_filename');
|
||||
const { unicodeToUnifiedName } = require('./unicode_to_unified_name');
|
||||
|
||||
// Grabbed from `emoji_utils` to avoid circular dependency
|
||||
function unifiedToNative(unified) {
|
||||
let unicodes = unified.split('-'),
|
||||
codePoints = unicodes.map((u) => `0x${u}`);
|
||||
|
||||
return String.fromCodePoint(...codePoints);
|
||||
}
|
||||
|
||||
let data = {
|
||||
compressed: true,
|
||||
categories: emojiMart5Data.categories.map(cat => {
|
||||
return {
|
||||
...cat,
|
||||
name: emojiMart5LocalesData.categories[cat.id]
|
||||
};
|
||||
}),
|
||||
aliases: emojiMart5Data.aliases,
|
||||
emojis: _(emojiMart5Data.emojis).values().map(emoji => {
|
||||
let skin_variations = {};
|
||||
const unified = emoji.skins[0].unified.toUpperCase();
|
||||
const emojiFromRawData = emojiSheetData.find(e => e.unified === unified);
|
||||
|
||||
if (!emojiFromRawData) {
|
||||
return undefined;
|
||||
}
|
||||
|
||||
if (emoji.skins.length > 1) {
|
||||
const [, ...nonDefaultSkins] = emoji.skins;
|
||||
nonDefaultSkins.forEach(skin => {
|
||||
const [matchingRawCodePoints,matchingRawEmoji] = Object.entries(emojiFromRawData.skin_variations).find((pair) => {
|
||||
const [, value] = pair;
|
||||
return value.unified.toLowerCase() === skin.unified;
|
||||
});
|
||||
|
||||
if (matchingRawEmoji && matchingRawCodePoints) {
|
||||
// At the time of writing, the json from `@emoji-mart/data` doesn't have data
|
||||
// for emoji like `woman-heart-woman` with two different skin tones.
|
||||
const skinToneCode = matchingRawCodePoints.split('-')[0];
|
||||
skin_variations[skinToneCode] = {
|
||||
unified: matchingRawEmoji.unified.toUpperCase(),
|
||||
non_qualified: null,
|
||||
sheet_x: matchingRawEmoji.sheet_x,
|
||||
sheet_y: matchingRawEmoji.sheet_y,
|
||||
has_img_twitter: true,
|
||||
native: unifiedToNative(matchingRawEmoji.unified.toUpperCase())
|
||||
};
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
return {
|
||||
a: emoji.name,
|
||||
b: unified,
|
||||
c: undefined,
|
||||
f: true,
|
||||
j: [emoji.id, ...emoji.keywords],
|
||||
k: [emojiFromRawData.sheet_x, emojiFromRawData.sheet_y],
|
||||
m: emoji.emoticons?.[0],
|
||||
l: emoji.emoticons,
|
||||
o: emoji.version,
|
||||
id: emoji.id,
|
||||
skin_variations,
|
||||
native: unifiedToNative(unified.toUpperCase())
|
||||
};
|
||||
}).compact().keyBy(e => e.id).mapValues(e => _.omit(e, 'id')).value()
|
||||
};
|
||||
|
||||
if (data.compressed) {
|
||||
emojiMartUncompress(data);
|
||||
}
|
||||
emojiMartUncompress(data);
|
||||
|
||||
const emojiMartData = data;
|
||||
const emojiIndex = new NimbleEmojiIndex(emojiMartData);
|
||||
|
||||
const excluded = ['®', '©', '™'];
|
||||
const skinTones = ['🏻', '🏼', '🏽', '🏾', '🏿'];
|
||||
@@ -103,10 +30,15 @@ const shortcodeMap = {};
|
||||
const shortCodesToEmojiData = {};
|
||||
const emojisWithoutShortCodes = [];
|
||||
|
||||
Object.keys(emojiMart5Data.emojis).forEach(key => {
|
||||
let emoji = emojiMart5Data.emojis[key];
|
||||
Object.keys(emojiIndex.emojis).forEach(key => {
|
||||
let emoji = emojiIndex.emojis[key];
|
||||
|
||||
shortcodeMap[emoji.skins[0].native] = emoji.id;
|
||||
// Emojis with skin tone modifiers are stored like this
|
||||
if (Object.hasOwn(emoji, '1')) {
|
||||
emoji = emoji['1'];
|
||||
}
|
||||
|
||||
shortcodeMap[emoji.native] = emoji.id;
|
||||
});
|
||||
|
||||
const stripModifiers = unicode => {
|
||||
@@ -150,9 +82,13 @@ Object.keys(emojiMap).forEach(key => {
|
||||
}
|
||||
});
|
||||
|
||||
Object.keys(emojiMartData.emojis).forEach(key => {
|
||||
let emoji = emojiMartData.emojis[key];
|
||||
Object.keys(emojiIndex.emojis).forEach(key => {
|
||||
let emoji = emojiIndex.emojis[key];
|
||||
|
||||
// Emojis with skin tone modifiers are stored like this
|
||||
if (Object.hasOwn(emoji, '1')) {
|
||||
emoji = emoji['1'];
|
||||
}
|
||||
|
||||
const { native } = emoji;
|
||||
let { short_names, search, unified } = emojiMartData.emojis[key];
|
||||
|
||||
1
app/javascript/mastodon/features/emoji/emoji_data.json
Normal file
@@ -29,7 +29,7 @@ import { LimitedAccountHint } from '../account_timeline/components/limited_accou
|
||||
import Column from '../ui/components/column';
|
||||
|
||||
const mapStateToProps = (state, { params: { acct, id } }) => {
|
||||
const accountId = id || state.getIn(['accounts_map', normalizeForLookup(acct)]);
|
||||
const accountId = id || state.accounts_map[normalizeForLookup(acct)];
|
||||
|
||||
if (!accountId) {
|
||||
return {
|
||||
|
||||
@@ -29,7 +29,7 @@ import { LimitedAccountHint } from '../account_timeline/components/limited_accou
|
||||
import Column from '../ui/components/column';
|
||||
|
||||
const mapStateToProps = (state, { params: { acct, id } }) => {
|
||||
const accountId = id || state.getIn(['accounts_map', normalizeForLookup(acct)]);
|
||||
const accountId = id || state.accounts_map[normalizeForLookup(acct)];
|
||||
|
||||
if (!accountId) {
|
||||
return {
|
||||
|
||||
@@ -11,27 +11,25 @@ interface Params {
|
||||
id?: string;
|
||||
}
|
||||
|
||||
export function useAccountId() {
|
||||
export const useAccountId = () => {
|
||||
const { acct, id } = useParams<Params>();
|
||||
const dispatch = useAppDispatch();
|
||||
const accountId = useAppSelector(
|
||||
(state) =>
|
||||
id ??
|
||||
(state.accounts_map.get(normalizeForLookup(acct)) as string | undefined),
|
||||
id ?? (acct ? state.accounts_map[normalizeForLookup(acct)] : undefined),
|
||||
);
|
||||
|
||||
const account = useAppSelector((state) =>
|
||||
accountId ? state.accounts.get(accountId) : undefined,
|
||||
);
|
||||
const isAccount = !!account;
|
||||
const accountInStore = !!account;
|
||||
|
||||
const dispatch = useAppDispatch();
|
||||
useEffect(() => {
|
||||
if (!accountId) {
|
||||
if (typeof accountId === 'undefined' && acct) {
|
||||
dispatch(lookupAccount(acct));
|
||||
} else if (!isAccount) {
|
||||
} else if (accountId && !accountInStore) {
|
||||
dispatch(fetchAccount(accountId));
|
||||
}
|
||||
}, [dispatch, accountId, acct, isAccount]);
|
||||
}, [dispatch, accountId, acct, accountInStore]);
|
||||
|
||||
return accountId;
|
||||
}
|
||||
};
|
||||
|
||||
@@ -1,12 +1,14 @@
|
||||
import { getAccountHidden } from 'mastodon/selectors/accounts';
|
||||
import { useAppSelector } from 'mastodon/store';
|
||||
|
||||
export function useAccountVisibility(accountId?: string) {
|
||||
const blockedBy = useAppSelector(
|
||||
(state) => !!state.relationships.getIn([accountId, 'blocked_by'], false),
|
||||
export function useAccountVisibility(accountId?: string | null) {
|
||||
const blockedBy = useAppSelector((state) =>
|
||||
accountId
|
||||
? !!state.relationships.getIn([accountId, 'blocked_by'], false)
|
||||
: false,
|
||||
);
|
||||
const suspended = useAppSelector(
|
||||
(state) => !!state.accounts.getIn([accountId, 'suspended'], false),
|
||||
const suspended = useAppSelector((state) =>
|
||||
accountId ? !!state.accounts.getIn([accountId, 'suspended'], false) : false,
|
||||
);
|
||||
const hidden = useAppSelector((state) =>
|
||||
accountId ? Boolean(getAccountHidden(state, accountId)) : false,
|
||||
|
||||
@@ -29,6 +29,7 @@
|
||||
"account.enable_notifications": "Notifica'm els tuts de @{name}",
|
||||
"account.endorse": "Recomana en el perfil",
|
||||
"account.featured": "Destacat",
|
||||
"account.featured.accounts": "Perfils",
|
||||
"account.featured.hashtags": "Etiquetes",
|
||||
"account.featured.posts": "Publicacions",
|
||||
"account.featured_tags.last_status_at": "Darrer tut el {date}",
|
||||
@@ -405,8 +406,10 @@
|
||||
"hashtag.counter_by_accounts": "{count, plural, one {{counter} participant} other {{counter} participants}}",
|
||||
"hashtag.counter_by_uses": "{count, plural, one {{counter} tut} other {{counter} tuts}}",
|
||||
"hashtag.counter_by_uses_today": "{count, plural, one {{counter} tut} other {{counter} tuts}} avui",
|
||||
"hashtag.feature": "Destaca al perfil",
|
||||
"hashtag.follow": "Segueix l'etiqueta",
|
||||
"hashtag.mute": "Silencia #{hashtag}",
|
||||
"hashtag.unfeature": "No destaquis al perfil",
|
||||
"hashtag.unfollow": "Deixa de seguir l'etiqueta",
|
||||
"hashtags.and_other": "…i {count, plural, other {# més}}",
|
||||
"hints.profiles.followers_may_be_missing": "Es poden haver perdut seguidors d'aquest perfil.",
|
||||
|
||||
@@ -29,6 +29,7 @@
|
||||
"account.enable_notifications": "Oznamovat mi příspěvky @{name}",
|
||||
"account.endorse": "Zvýraznit na profilu",
|
||||
"account.featured": "Zvýrazněné",
|
||||
"account.featured.accounts": "Profily",
|
||||
"account.featured.hashtags": "Hashtagy",
|
||||
"account.featured.posts": "Příspěvky",
|
||||
"account.featured_tags.last_status_at": "Poslední příspěvek {date}",
|
||||
@@ -405,8 +406,10 @@
|
||||
"hashtag.counter_by_accounts": "{count, plural, one {{counter} účastník*ice} few {{counter} účastníci} other {{counter} účastníků}}",
|
||||
"hashtag.counter_by_uses": "{count, plural, one {{counter} příspěvek} few {{counter} příspěvky} other {{counter} příspěvků}}",
|
||||
"hashtag.counter_by_uses_today": "Dnes {count, plural, one {{counter} příspěvek} few {{counter} příspěvky} other {{counter} příspěvků}}",
|
||||
"hashtag.feature": "Zvýraznit na profilu",
|
||||
"hashtag.follow": "Sledovat hashtag",
|
||||
"hashtag.mute": "Skrýt #{hashtag}",
|
||||
"hashtag.unfeature": "Nezvýrazňovat na profilu",
|
||||
"hashtag.unfollow": "Přestat sledovat hashtag",
|
||||
"hashtags.and_other": "…a {count, plural, one {# další} few {# další} other {# dalších}}",
|
||||
"hints.profiles.followers_may_be_missing": "Sledující mohou pro tento profil chybět.",
|
||||
|
||||
@@ -6,19 +6,19 @@
|
||||
"about.domain_blocks.preamble": "Fel rheol, mae Mastodon yn caniatáu i chi weld cynnwys gan unrhyw weinyddwr arall yn y ffedysawd a rhyngweithio â hi. Dyma'r eithriadau a wnaed ar y gweinydd penodol hwn.",
|
||||
"about.domain_blocks.silenced.explanation": "Fel rheol, fyddwch chi ddim yn gweld proffiliau a chynnwys o'r gweinydd hwn, oni bai eich bod yn chwilio'n benodol amdano neu yn ymuno drwy ei ddilyn.",
|
||||
"about.domain_blocks.silenced.title": "Cyfyngedig",
|
||||
"about.domain_blocks.suspended.explanation": "Ni fydd data o'r gweinydd hwn yn cael ei brosesu, ei gadw na'i gyfnewid, gan wneud unrhyw ryngweithio neu gyfathrebu gyda defnyddwyr o'r gweinydd hwn yn amhosibl.",
|
||||
"about.domain_blocks.suspended.explanation": "Fydd data o'r gweinydd hwn ddim yn cael ei brosesu, ei gadw na'i gyfnewid, gan wneud unrhyw ryngweithio neu gyfathrebu gyda defnyddwyr o'r gweinydd hwn yn amhosibl.",
|
||||
"about.domain_blocks.suspended.title": "Wedi'i atal",
|
||||
"about.not_available": "Nid yw'r wybodaeth hon ar gael ar y gweinydd hwn.",
|
||||
"about.not_available": "Dyw'r wybodaeth yma heb ei wneud ar gael ar y gweinydd hwn.",
|
||||
"about.powered_by": "Cyfrwng cymdeithasol datganoledig wedi ei yrru gan {mastodon}",
|
||||
"about.rules": "Rheolau'r gweinydd",
|
||||
"account.account_note_header": "Nodyn personol",
|
||||
"account.add_or_remove_from_list": "Ychwanegu neu Ddileu o'r rhestrau",
|
||||
"account.badges.bot": "Awtomataidd",
|
||||
"account.badges.group": "Grŵp",
|
||||
"account.block": "Blocio @{name}",
|
||||
"account.block_domain": "Blocio'r parth {domain}",
|
||||
"account.block_short": "Blocio",
|
||||
"account.blocked": "Blociwyd",
|
||||
"account.block": "Rhwystro @{name}",
|
||||
"account.block_domain": "Rhwystro'r parth {domain}",
|
||||
"account.block_short": "Rhwystro",
|
||||
"account.blocked": "Wedi'i rwystro",
|
||||
"account.blocking": "Yn Rhwystro",
|
||||
"account.cancel_follow_request": "Tynnu cais i ddilyn",
|
||||
"account.copy": "Copïo dolen i'r proffil",
|
||||
@@ -28,7 +28,7 @@
|
||||
"account.edit_profile": "Golygu'r proffil",
|
||||
"account.enable_notifications": "Rhowch wybod i fi pan fydd @{name} yn postio",
|
||||
"account.endorse": "Dangos ar fy mhroffil",
|
||||
"account.featured": "Dethol",
|
||||
"account.featured": "Nodwedd",
|
||||
"account.featured.hashtags": "Hashnodau",
|
||||
"account.featured.posts": "Postiadau",
|
||||
"account.featured_tags.last_status_at": "Y postiad olaf ar {date}",
|
||||
@@ -40,7 +40,7 @@
|
||||
"account.followers_counter": "{count, plural, one {{counter} dilynwr} two {{counter} ddilynwr} other {{counter} dilynwyr}}",
|
||||
"account.following": "Yn dilyn",
|
||||
"account.following_counter": "{count, plural, one {Yn dilyn {counter}} other {Yn dilyn {counter} arall}}",
|
||||
"account.follows.empty": "Nid yw'r defnyddiwr hwn yn dilyn unrhyw un eto.",
|
||||
"account.follows.empty": "Dyw'r defnyddiwr hwn ddim yn dilyn unrhyw un eto.",
|
||||
"account.follows_you": "Yn eich dilyn chi",
|
||||
"account.go_to_profile": "Mynd i'r proffil",
|
||||
"account.hide_reblogs": "Cuddio hybiau gan @{name}",
|
||||
|
||||
@@ -29,6 +29,7 @@
|
||||
"account.enable_notifications": "Advisér mig, når @{name} poster",
|
||||
"account.endorse": "Fremhæv på profil",
|
||||
"account.featured": "Fremhævet",
|
||||
"account.featured.accounts": "Profiler",
|
||||
"account.featured.hashtags": "Hashtags",
|
||||
"account.featured.posts": "Indlæg",
|
||||
"account.featured_tags.last_status_at": "Seneste indlæg {date}",
|
||||
@@ -405,8 +406,10 @@
|
||||
"hashtag.counter_by_accounts": "{count, plural, one {{counter} deltager} other {{counter} deltagere}}",
|
||||
"hashtag.counter_by_uses": "{count, plural, one {{counter} indlæg} other {{counter} indlæg}}",
|
||||
"hashtag.counter_by_uses_today": "{count, plural, one {{counter} indlæg} other {{counter} indlæg}} i dag",
|
||||
"hashtag.feature": "Fremhæv på profil",
|
||||
"hashtag.follow": "Følg etiket",
|
||||
"hashtag.mute": "Tavsgør #{hashtag}",
|
||||
"hashtag.unfeature": "Fremhæv ikke på profil",
|
||||
"hashtag.unfollow": "Stop med at følge etiket",
|
||||
"hashtags.and_other": "…og {count, plural, one {}other {# flere}}",
|
||||
"hints.profiles.followers_may_be_missing": "Der kan mangle følgere for denne profil.",
|
||||
|
||||
@@ -29,6 +29,7 @@
|
||||
"account.enable_notifications": "Benachrichtige mich wenn @{name} etwas postet",
|
||||
"account.endorse": "Im Profil vorstellen",
|
||||
"account.featured": "Vorgestellt",
|
||||
"account.featured.accounts": "Profile",
|
||||
"account.featured.hashtags": "Hashtags",
|
||||
"account.featured.posts": "Beiträge",
|
||||
"account.featured_tags.last_status_at": "Letzter Beitrag am {date}",
|
||||
@@ -405,8 +406,10 @@
|
||||
"hashtag.counter_by_accounts": "{count, plural, one{{counter} Beteiligte*r} other{{counter} Beteiligte}}",
|
||||
"hashtag.counter_by_uses": "{count, plural, one {{counter} Beitrag} other {{counter} Beiträge}}",
|
||||
"hashtag.counter_by_uses_today": "{count, plural, one {{counter} Beitrag} other {{counter} Beiträge}} heute",
|
||||
"hashtag.feature": "Im Profil vorstellen",
|
||||
"hashtag.follow": "Hashtag folgen",
|
||||
"hashtag.mute": "#{hashtag} stummschalten",
|
||||
"hashtag.unfeature": "Im Profil nicht mehr vorstellen",
|
||||
"hashtag.unfollow": "Hashtag entfolgen",
|
||||
"hashtags.and_other": "… und {count, plural, one{# weiterer} other {# weitere}}",
|
||||
"hints.profiles.followers_may_be_missing": "Möglicherweise werden für dieses Profil nicht alle Follower angezeigt.",
|
||||
@@ -426,7 +429,7 @@
|
||||
"home.show_announcements": "Ankündigungen anzeigen",
|
||||
"ignore_notifications_modal.disclaimer": "Mastodon kann anderen Nutzer*innen nicht mitteilen, dass du deren Benachrichtigungen ignorierst. Das Ignorieren von Benachrichtigungen wird nicht das Absenden der Nachricht selbst unterbinden.",
|
||||
"ignore_notifications_modal.filter_instead": "Stattdessen filtern",
|
||||
"ignore_notifications_modal.filter_to_act_users": "Du wirst weiterhin die Möglichkeit haben, andere Nutzer*innen zu genehmigen, abzulehnen oder zu melden",
|
||||
"ignore_notifications_modal.filter_to_act_users": "Du wirst weiterhin die Möglichkeit haben, andere Nutzer*innen zu akzeptieren, abzulehnen oder zu melden",
|
||||
"ignore_notifications_modal.filter_to_avoid_confusion": "Filtern hilft, mögliches Durcheinander zu vermeiden",
|
||||
"ignore_notifications_modal.filter_to_review_separately": "Gefilterte Benachrichtigungen können separat überprüft werden",
|
||||
"ignore_notifications_modal.ignore": "Benachrichtigungen ignorieren",
|
||||
@@ -610,11 +613,11 @@
|
||||
"notification.relationships_severance_event.user_domain_block": "Du hast {target} blockiert – {followersCount} deiner Follower und {followingCount, plural, one {# Konto, dem} other {# Konten, denen}} du folgst, wurden entfernt.",
|
||||
"notification.status": "{name} postete …",
|
||||
"notification.update": "{name} bearbeitete einen Beitrag",
|
||||
"notification_requests.accept": "Genehmigen",
|
||||
"notification_requests.accept_multiple": "{count, plural, one {# Anfrage genehmigen …} other {# Anfragen genehmigen …}}",
|
||||
"notification_requests.confirm_accept_multiple.button": "{count, plural, one {Anfrage genehmigen} other {Anfragen genehmigen}}",
|
||||
"notification_requests.confirm_accept_multiple.message": "Du bist dabei, {{count, plural, one {eine Benachrichtigungsanfrage} other {# Benachrichtigungsanfragen}} zu genehmigen. Möchtest du wirklich fortfahren?",
|
||||
"notification_requests.confirm_accept_multiple.title": "Benachrichtigungsanfragen genehmigen?",
|
||||
"notification_requests.accept": "Akzeptieren",
|
||||
"notification_requests.accept_multiple": "{count, plural, one {# Anfrage akzeptieren …} other {# Anfragen akzeptieren …}}",
|
||||
"notification_requests.confirm_accept_multiple.button": "{count, plural, one {Anfrage akzeptieren} other {Anfragen akzeptieren}}",
|
||||
"notification_requests.confirm_accept_multiple.message": "Du bist dabei, {{count, plural, one {eine Benachrichtigungsanfrage} other {# Benachrichtigungsanfragen}} zu akzeptieren. Möchtest du wirklich fortfahren?",
|
||||
"notification_requests.confirm_accept_multiple.title": "Benachrichtigungsanfragen akzeptieren?",
|
||||
"notification_requests.confirm_dismiss_multiple.button": "{count, plural, one {Anfrage ablehnen} other {Anfragen ablehnen}}",
|
||||
"notification_requests.confirm_dismiss_multiple.message": "Du bist dabei, {count, plural, one {eine Benachrichtigungsanfrage} other {# Benachrichtigungsanfragen}} abzulehnen. Du wirst nicht mehr ohne Weiteres auf {count, plural, one {sie} other {sie}} zugreifen können. Möchtest du wirklich fortfahren?",
|
||||
"notification_requests.confirm_dismiss_multiple.title": "Benachrichtigungsanfragen ablehnen?",
|
||||
|
||||
@@ -29,6 +29,7 @@
|
||||
"account.enable_notifications": "Notify me when @{name} posts",
|
||||
"account.endorse": "Feature on profile",
|
||||
"account.featured": "Featured",
|
||||
"account.featured.accounts": "Profiles",
|
||||
"account.featured.hashtags": "Hashtags",
|
||||
"account.featured.posts": "Posts",
|
||||
"account.featured_tags.last_status_at": "Last post on {date}",
|
||||
|
||||
@@ -29,6 +29,7 @@
|
||||
"account.enable_notifications": "Notificarme cuando @{name} envíe mensajes",
|
||||
"account.endorse": "Destacar en el perfil",
|
||||
"account.featured": "Destacados",
|
||||
"account.featured.accounts": "Perfiles",
|
||||
"account.featured.hashtags": "Etiquetas",
|
||||
"account.featured.posts": "Mensajes",
|
||||
"account.featured_tags.last_status_at": "Último mensaje: {date}",
|
||||
@@ -405,8 +406,10 @@
|
||||
"hashtag.counter_by_accounts": "{count, plural, one {{counter} participante} other {{counter} participantes}}",
|
||||
"hashtag.counter_by_uses": "{count, plural, one {{counter} mensaje} other {{counter} mensajes}}",
|
||||
"hashtag.counter_by_uses_today": "{count, plural, one {{counter} mensaje} other {{counter} mensajes}} hoy",
|
||||
"hashtag.feature": "Destacar en el perfil",
|
||||
"hashtag.follow": "Seguir etiqueta",
|
||||
"hashtag.mute": "Silenciar #{hashtag}",
|
||||
"hashtag.unfeature": "No destacar en el perfil",
|
||||
"hashtag.unfollow": "Dejar de seguir etiqueta",
|
||||
"hashtags.and_other": "…y {count, plural, other {# más}}",
|
||||
"hints.profiles.followers_may_be_missing": "Es posible que falten seguidores de este perfil.",
|
||||
|
||||
@@ -29,6 +29,7 @@
|
||||
"account.enable_notifications": "Notificarme cuando @{name} publique algo",
|
||||
"account.endorse": "Destacar en mi perfil",
|
||||
"account.featured": "Destacado",
|
||||
"account.featured.accounts": "Perfiles",
|
||||
"account.featured.hashtags": "Etiquetas",
|
||||
"account.featured.posts": "Publicaciones",
|
||||
"account.featured_tags.last_status_at": "Última publicación el {date}",
|
||||
@@ -405,8 +406,10 @@
|
||||
"hashtag.counter_by_accounts": "{count, plural, one {{counter} participante} other {{counter} participantes}}",
|
||||
"hashtag.counter_by_uses": "{count, plural, one {{counter} publicación} other {{counter} publicaciones}}",
|
||||
"hashtag.counter_by_uses_today": "{count, plural, one {{counter} publicación} other {{counter} publicaciones}} hoy",
|
||||
"hashtag.feature": "Destacar en el perfil",
|
||||
"hashtag.follow": "Seguir etiqueta",
|
||||
"hashtag.mute": "Silenciar #{hashtag}",
|
||||
"hashtag.unfeature": "No destacar en el perfil",
|
||||
"hashtag.unfollow": "Dejar de seguir etiqueta",
|
||||
"hashtags.and_other": "…y {count, plural, other {# más}}",
|
||||
"hints.profiles.followers_may_be_missing": "Puede que no se muestren todos los seguidores de este perfil.",
|
||||
|
||||
@@ -29,6 +29,7 @@
|
||||
"account.enable_notifications": "Notificarme cuando @{name} publique algo",
|
||||
"account.endorse": "Destacar en el perfil",
|
||||
"account.featured": "Destacado",
|
||||
"account.featured.accounts": "Perfiles",
|
||||
"account.featured.hashtags": "Etiquetas",
|
||||
"account.featured.posts": "Publicaciones",
|
||||
"account.featured_tags.last_status_at": "Última publicación el {date}",
|
||||
@@ -405,8 +406,10 @@
|
||||
"hashtag.counter_by_accounts": "{count, plural, one {{counter} participante} other {{counter} participantes}}",
|
||||
"hashtag.counter_by_uses": "{count, plural, one {{counter} publicación} other {{counter} publicaciones}}",
|
||||
"hashtag.counter_by_uses_today": "{count, plural, one {{counter} publicación} other {{counter} publicaciones}} hoy",
|
||||
"hashtag.feature": "Destacar en el perfil",
|
||||
"hashtag.follow": "Seguir etiqueta",
|
||||
"hashtag.mute": "Silenciar #{hashtag}",
|
||||
"hashtag.unfeature": "No destacar en el perfil",
|
||||
"hashtag.unfollow": "Dejar de seguir etiqueta",
|
||||
"hashtags.and_other": "…y {count, plural, other {# más}}",
|
||||
"hints.profiles.followers_may_be_missing": "Puede que no se muestren todos los seguidores de este perfil.",
|
||||
@@ -581,7 +584,7 @@
|
||||
"notification.favourite_pm": "{name} ha marcado como favorita tu mención privada",
|
||||
"notification.favourite_pm.name_and_others_with_link": "{name} y <a>{count, plural, one {# más} other {# más}}</a> han marcado como favorita tu mención privada",
|
||||
"notification.follow": "{name} te empezó a seguir",
|
||||
"notification.follow.name_and_others": "{name} y <a>{count, plural, one {# otro} other {# otros}}</a> te siguieron",
|
||||
"notification.follow.name_and_others": "{name} y <a>{count, plural, one {# otro} other {otros #}}</a> te siguieron",
|
||||
"notification.follow_request": "{name} ha solicitado seguirte",
|
||||
"notification.follow_request.name_and_others": "{name} y {count, plural, one {# más} other {# más}} han solicitado seguirte",
|
||||
"notification.label.mention": "Mención",
|
||||
|
||||
@@ -29,6 +29,7 @@
|
||||
"account.enable_notifications": "Ilmoita minulle, kun @{name} julkaisee",
|
||||
"account.endorse": "Suosittele profiilissa",
|
||||
"account.featured": "Suositellut",
|
||||
"account.featured.accounts": "Profiilit",
|
||||
"account.featured.hashtags": "Aihetunnisteet",
|
||||
"account.featured.posts": "Julkaisut",
|
||||
"account.featured_tags.last_status_at": "Viimeisin julkaisu {date}",
|
||||
@@ -405,8 +406,10 @@
|
||||
"hashtag.counter_by_accounts": "{count, plural, one {{counter} osallistuja} other {{counter} osallistujaa}}",
|
||||
"hashtag.counter_by_uses": "{count, plural, one{{counter} julkaisu} other {{counter} julkaisua}}",
|
||||
"hashtag.counter_by_uses_today": "{count, plural, one {{counter} julkaisu} other {{counter} julkaisua}} tänään",
|
||||
"hashtag.feature": "Suosittele profiilissa",
|
||||
"hashtag.follow": "Seuraa aihetunnistetta",
|
||||
"hashtag.mute": "Mykistä #{hashtag}",
|
||||
"hashtag.unfeature": "Kumoa suosittelu profiilissa",
|
||||
"hashtag.unfollow": "Lopeta aihetunnisteen seuraaminen",
|
||||
"hashtags.and_other": "…ja {count, plural, other {# lisää}}",
|
||||
"hints.profiles.followers_may_be_missing": "Tämän profiilin seuraajia saattaa puuttua.",
|
||||
|
||||
@@ -29,6 +29,7 @@
|
||||
"account.enable_notifications": "Boða mær frá, tá @{name} skrivar",
|
||||
"account.endorse": "Víst á vangamyndini",
|
||||
"account.featured": "Tikin fram",
|
||||
"account.featured.accounts": "Vangar",
|
||||
"account.featured.hashtags": "Frámerki",
|
||||
"account.featured.posts": "Postar",
|
||||
"account.featured_tags.last_status_at": "Seinasta strongur skrivaður {date}",
|
||||
@@ -405,8 +406,10 @@
|
||||
"hashtag.counter_by_accounts": "{count, plural, one {{counter} luttakari} other {{counter} luttakarar}}",
|
||||
"hashtag.counter_by_uses": "{count, plural, one {{counter} postur} other {{counter} postar}}",
|
||||
"hashtag.counter_by_uses_today": "{count, plural, one {{counter} postur} other {{counter} postar}} í dag",
|
||||
"hashtag.feature": "Vís á vanga",
|
||||
"hashtag.follow": "Fylg frámerki",
|
||||
"hashtag.mute": "Doyv @#{hashtag}",
|
||||
"hashtag.unfeature": "Vís ikki á vanga",
|
||||
"hashtag.unfollow": "Gevst at fylgja frámerki",
|
||||
"hashtags.and_other": "…og {count, plural, other {# afturat}}",
|
||||
"hints.profiles.followers_may_be_missing": "Fylgjarar hjá hesum vanganum kunnu mangla.",
|
||||
|
||||
@@ -29,6 +29,7 @@
|
||||
"account.enable_notifications": "Noficarme cando @{name} publique",
|
||||
"account.endorse": "Amosar no perfil",
|
||||
"account.featured": "Destacado",
|
||||
"account.featured.accounts": "Perfís",
|
||||
"account.featured.hashtags": "Cancelos",
|
||||
"account.featured.posts": "Publicacións",
|
||||
"account.featured_tags.last_status_at": "Última publicación o {date}",
|
||||
@@ -405,8 +406,10 @@
|
||||
"hashtag.counter_by_accounts": "{count, plural, one {{counter} participante} other {{counter} participantes}}",
|
||||
"hashtag.counter_by_uses": "{count, plural, one {{counter} publicación} other {{counter} publicacións}}",
|
||||
"hashtag.counter_by_uses_today": "{count, plural, one {{counter} publicación} other {{counter} publicacións}} hoxe",
|
||||
"hashtag.feature": "Destacar no perfil",
|
||||
"hashtag.follow": "Seguir cancelo",
|
||||
"hashtag.mute": "Acalar a #{hashtag}",
|
||||
"hashtag.unfeature": "Non destacar no perfil",
|
||||
"hashtag.unfollow": "Deixar de seguir cancelo",
|
||||
"hashtags.and_other": "…e {count, plural, one {}other {# máis}}",
|
||||
"hints.profiles.followers_may_be_missing": "Poderían faltar seguidoras deste perfil.",
|
||||
|
||||
@@ -29,6 +29,7 @@
|
||||
"account.enable_notifications": "שלח לי התראות כש@{name} מפרסם",
|
||||
"account.endorse": "קדם את החשבון בפרופיל",
|
||||
"account.featured": "מומלץ",
|
||||
"account.featured.accounts": "פרופילים",
|
||||
"account.featured.hashtags": "תגיות",
|
||||
"account.featured.posts": "הודעות",
|
||||
"account.featured_tags.last_status_at": "חצרוץ אחרון בתאריך {date}",
|
||||
@@ -405,8 +406,10 @@
|
||||
"hashtag.counter_by_accounts": "{count, plural,one{{count} משתתף.ת}other{{counter} משתתפיםות}}",
|
||||
"hashtag.counter_by_uses": "{count, plural, one {הודעה אחת} two {הודעותיים} many {{counter} הודעות} other {{counter} הודעות}}",
|
||||
"hashtag.counter_by_uses_today": "{count, plural, one {הודעה אחת} two {הודעותיים} many {{counter} הודעות} other {{counter} הודעות}} היום",
|
||||
"hashtag.feature": "מובלט בפרופיל",
|
||||
"hashtag.follow": "לעקוב אחרי תגית",
|
||||
"hashtag.mute": "להשתיק את #{hashtag}",
|
||||
"hashtag.unfeature": "לא להבליט בפרופיל",
|
||||
"hashtag.unfollow": "להפסיק לעקוב אחרי תגית",
|
||||
"hashtags.and_other": "…{count, plural,other {ועוד #}}",
|
||||
"hints.profiles.followers_may_be_missing": "יתכן כי עוקבים של פרופיל זה חסרים.",
|
||||
|
||||
@@ -19,13 +19,19 @@
|
||||
"account.block_domain": "Blocar dominio {domain}",
|
||||
"account.block_short": "Blocar",
|
||||
"account.blocked": "Blocate",
|
||||
"account.blocking": "Blocate",
|
||||
"account.cancel_follow_request": "Cancellar sequimento",
|
||||
"account.copy": "Copiar ligamine a profilo",
|
||||
"account.direct": "Mentionar privatemente @{name}",
|
||||
"account.disable_notifications": "Non plus notificar me quando @{name} publica",
|
||||
"account.domain_blocking": "Dominio blocate",
|
||||
"account.edit_profile": "Modificar profilo",
|
||||
"account.enable_notifications": "Notificar me quando @{name} publica",
|
||||
"account.endorse": "Evidentiar sur le profilo",
|
||||
"account.featured": "In evidentia",
|
||||
"account.featured.accounts": "Profilos",
|
||||
"account.featured.hashtags": "Hashtags",
|
||||
"account.featured.posts": "Messages",
|
||||
"account.featured_tags.last_status_at": "Ultime message publicate le {date}",
|
||||
"account.featured_tags.last_status_never": "Necun message",
|
||||
"account.follow": "Sequer",
|
||||
@@ -36,6 +42,7 @@
|
||||
"account.following": "Sequente",
|
||||
"account.following_counter": "{count, plural, one {{counter} sequite} other {{counter} sequites}}",
|
||||
"account.follows.empty": "Iste usator non seque ancora alcuno.",
|
||||
"account.follows_you": "Te seque",
|
||||
"account.go_to_profile": "Vader al profilo",
|
||||
"account.hide_reblogs": "Celar impulsos de @{name}",
|
||||
"account.in_memoriam": "In memoriam.",
|
||||
@@ -50,18 +57,23 @@
|
||||
"account.mute_notifications_short": "Silentiar le notificationes",
|
||||
"account.mute_short": "Silentiar",
|
||||
"account.muted": "Silentiate",
|
||||
"account.muting": "Silentiate",
|
||||
"account.mutual": "Sequimento mutue",
|
||||
"account.no_bio": "Nulle description fornite.",
|
||||
"account.open_original_page": "Aperir le pagina original",
|
||||
"account.posts": "Messages",
|
||||
"account.posts_with_replies": "Messages e responsas",
|
||||
"account.remove_from_followers": "Remover {name} del sequitores",
|
||||
"account.report": "Reportar @{name}",
|
||||
"account.requested": "Attendente le approbation. Clicca pro cancellar le requesta de sequer",
|
||||
"account.requested_follow": "{name} ha requestate de sequer te",
|
||||
"account.requests_to_follow_you": "Requestas de sequer te",
|
||||
"account.share": "Compartir profilo de @{name}",
|
||||
"account.show_reblogs": "Monstrar impulsos de @{name}",
|
||||
"account.statuses_counter": "{count, plural, one {{counter} message} other {{counter} messages}}",
|
||||
"account.unblock": "Disblocar @{name}",
|
||||
"account.unblock_domain": "Disblocar dominio {domain}",
|
||||
"account.unblock_domain_short": "Disblocar",
|
||||
"account.unblock_short": "Disblocar",
|
||||
"account.unendorse": "Non evidentiar sur le profilo",
|
||||
"account.unfollow": "Non plus sequer",
|
||||
@@ -157,6 +169,7 @@
|
||||
"column.lists": "Listas",
|
||||
"column.mutes": "Usatores silentiate",
|
||||
"column.notifications": "Notificationes",
|
||||
"column.pins": "Messages in evidentia",
|
||||
"column.public": "Chronologia federate",
|
||||
"column_back_button.label": "Retro",
|
||||
"column_header.hide_settings": "Celar le parametros",
|
||||
@@ -222,6 +235,9 @@
|
||||
"confirmations.redraft.confirm": "Deler e rescriber",
|
||||
"confirmations.redraft.message": "Es tu secur de voler deler iste message e rescriber lo? Le favorites e le impulsos essera perdite, e le responsas al message original essera orphanate.",
|
||||
"confirmations.redraft.title": "Deler e rescriber le message?",
|
||||
"confirmations.remove_from_followers.confirm": "Remover sequitor",
|
||||
"confirmations.remove_from_followers.message": "{name} non plus te sequera. Es tu secur de voler continuar?",
|
||||
"confirmations.remove_from_followers.title": "Remover sequitor?",
|
||||
"confirmations.reply.confirm": "Responder",
|
||||
"confirmations.reply.message": "Si tu responde ora, le message in curso de composition essera perdite. Es tu secur de voler continuar?",
|
||||
"confirmations.reply.title": "Superscriber le message?",
|
||||
@@ -289,6 +305,9 @@
|
||||
"emoji_button.search_results": "Resultatos de recerca",
|
||||
"emoji_button.symbols": "Symbolos",
|
||||
"emoji_button.travel": "Viages e locos",
|
||||
"empty_column.account_featured.me": "Tu non ha ancora mittite alcun cosa in evidentia. Sapeva tu que tu pote mitter in evidentia tu messages, le hashtags que tu usa le plus, e mesmo le contos de tu amicos sur tu profilo?",
|
||||
"empty_column.account_featured.other": "{acct} non ha ancora mittite alcun cosa in evidentia. Sapeva tu que tu pote mitter in evidentia tu messages, le hashtags que tu usa le plus, e mesmo le contos de tu amicos sur tu profilo?",
|
||||
"empty_column.account_featured_other.unknown": "Iste conto non ha ancora mittite alcun cosa in evidentia.",
|
||||
"empty_column.account_hides_collections": "Le usator non ha rendite iste information disponibile",
|
||||
"empty_column.account_suspended": "Conto suspendite",
|
||||
"empty_column.account_timeline": "Nulle messages hic!",
|
||||
|
||||
@@ -29,6 +29,7 @@
|
||||
"account.enable_notifications": "Láta mig vita þegar @{name} sendir inn",
|
||||
"account.endorse": "Birta á notandasniði",
|
||||
"account.featured": "Með aukið vægi",
|
||||
"account.featured.accounts": "Notendasnið",
|
||||
"account.featured.hashtags": "Myllumerki",
|
||||
"account.featured.posts": "Færslur",
|
||||
"account.featured_tags.last_status_at": "Síðasta færsla þann {date}",
|
||||
@@ -405,8 +406,10 @@
|
||||
"hashtag.counter_by_accounts": "{count, plural, one {{counter} þátttakandi} other {{counter} þátttakendur}}",
|
||||
"hashtag.counter_by_uses": "{count, plural, one {{counter} færsla} other {{counter} færslur}}",
|
||||
"hashtag.counter_by_uses_today": "{count, plural, one {{counter} færsla} other {{counter} færslur}} í dag",
|
||||
"hashtag.feature": "Birta á notandasniði",
|
||||
"hashtag.follow": "Fylgjast með myllumerki",
|
||||
"hashtag.mute": "Þagga #{hashtag}",
|
||||
"hashtag.unfeature": "Ekki birta á notandasniði",
|
||||
"hashtag.unfollow": "Hætta að fylgjast með myllumerki",
|
||||
"hashtags.and_other": "…og {count, plural, other {# til viðbótar}}",
|
||||
"hints.profiles.followers_may_be_missing": "Fylgjendur frá þessum notanda gæti vantað.",
|
||||
|
||||
@@ -24,6 +24,7 @@
|
||||
"account.edit_profile": "Ẓreg amaɣnu",
|
||||
"account.enable_notifications": "Azen-iyi-d ilɣa mi ara d-isuffeɣ @{name}",
|
||||
"account.endorse": "Welleh fell-as deg umaɣnu-inek",
|
||||
"account.featured.accounts": "Imeɣna",
|
||||
"account.featured.hashtags": "Ihacṭagen",
|
||||
"account.featured.posts": "Tisuffaɣ",
|
||||
"account.featured_tags.last_status_at": "Tasuffeɣt taneggarut ass n {date}",
|
||||
@@ -36,6 +37,7 @@
|
||||
"account.following": "Yeṭṭafaṛ",
|
||||
"account.following_counter": "{count, plural, one {{counter} yettwaḍfaren} other {{counter} yettwaḍfaren}}",
|
||||
"account.follows.empty": "Ar tura, amseqdac-agi ur yeṭṭafaṛ yiwen.",
|
||||
"account.follows_you": "Yeṭṭafaṛ-ik·em-id",
|
||||
"account.go_to_profile": "Ddu ɣer umaɣnu",
|
||||
"account.hide_reblogs": "Ffer ayen i ibeṭṭu @{name}",
|
||||
"account.joined_short": "Izeddi da seg ass n",
|
||||
@@ -415,6 +417,7 @@
|
||||
"not_signed_in_indicator.not_signed_in": "You need to sign in to access this resource.",
|
||||
"notification.admin.report": "Yemla-t-id {name} {target}",
|
||||
"notification.admin.sign_up": "Ijerred {name}",
|
||||
"notification.annual_report.view": "Wali #Wrapstodon",
|
||||
"notification.favourite": "{name} yesmenyaf addad-ik·im",
|
||||
"notification.follow": "iṭṭafar-ik·em-id {name}",
|
||||
"notification.follow.name_and_others": "{name} akked <a>{count, plural, one {# nniḍen} other {# nniḍen}}</a> iḍfeṛ-k·m-id",
|
||||
@@ -466,6 +469,7 @@
|
||||
"notifications.group": "{count} n yilɣa",
|
||||
"notifications.mark_as_read": "Creḍ akk ilɣa am wakken ttwaɣran",
|
||||
"notifications.permission_denied": "D awezɣi ad yili wermad n yilɣa n tnarit axateṛ turagt tettwagdel",
|
||||
"notifications.policy.accept": "Qbel",
|
||||
"notifications.policy.drop": "Anef-as",
|
||||
"notifications.policy.filter": "Sizdeg",
|
||||
"notifications.policy.filter_new_accounts.hint": "Imiḍanen imaynuten i d-yennulfan deg {days, plural, one {yiwen n wass} other {# n wussan}} yezrin",
|
||||
@@ -580,6 +584,7 @@
|
||||
"search_results.all": "Akk",
|
||||
"search_results.hashtags": "Ihacṭagen",
|
||||
"search_results.no_results": "Ulac igemmaḍ.",
|
||||
"search_results.no_search_yet": "Ɛreḍ ad d-tnadiḍ ɣef iznan, imaɣnuten neɣ ihacṭagen.",
|
||||
"search_results.see_all": "Wali-ten akk",
|
||||
"search_results.statuses": "Tisuffaɣ",
|
||||
"search_results.title": "Igemmaḍ n unadi ɣef \"{q}\"",
|
||||
|
||||
@@ -29,6 +29,7 @@
|
||||
"account.enable_notifications": "@{name} 의 게시물 알림 켜기",
|
||||
"account.endorse": "프로필에 추천하기",
|
||||
"account.featured": "추천",
|
||||
"account.featured.accounts": "프로필",
|
||||
"account.featured.hashtags": "해시태그",
|
||||
"account.featured.posts": "게시물",
|
||||
"account.featured_tags.last_status_at": "{date}에 마지막으로 게시",
|
||||
@@ -168,6 +169,7 @@
|
||||
"column.lists": "리스트",
|
||||
"column.mutes": "뮤트한 사용자",
|
||||
"column.notifications": "알림",
|
||||
"column.pins": "추천 게시물",
|
||||
"column.public": "연합 타임라인",
|
||||
"column_back_button.label": "돌아가기",
|
||||
"column_header.hide_settings": "설정 숨기기",
|
||||
@@ -226,9 +228,9 @@
|
||||
"confirmations.logout.message": "정말로 로그아웃 하시겠습니까?",
|
||||
"confirmations.logout.title": "로그아웃 할까요?",
|
||||
"confirmations.missing_alt_text.confirm": "대체 텍스트 추가",
|
||||
"confirmations.missing_alt_text.message": "대체 텍스트가 없는 미디어를 포함하고 있습니다. 설명을 추가하면 더 많은 사람들이 내 콘텐츠에 접근할 수 있습니다.",
|
||||
"confirmations.missing_alt_text.message": "대체 텍스트가 없는 미디어를 포함하고 있습니다. 설명을 추가하면 더 많은 사람들이 내 콘텐츠에 접근할 수 있습니다. ",
|
||||
"confirmations.missing_alt_text.secondary": "그냥 게시하기",
|
||||
"confirmations.missing_alt_text.title": "대체 텍스트를 추가할까요?",
|
||||
"confirmations.missing_alt_text.title": "대체 텍스트를 추가할까요? ",
|
||||
"confirmations.mute.confirm": "뮤트",
|
||||
"confirmations.redraft.confirm": "삭제하고 다시 쓰기",
|
||||
"confirmations.redraft.message": "정말로 이 게시물을 삭제하고 다시 쓰시겠습니까? 해당 게시물에 대한 부스트와 좋아요를 잃게 되고 원본에 대한 답장은 연결 되지 않습니다.",
|
||||
@@ -435,7 +437,7 @@
|
||||
"ignore_notifications_modal.not_following_title": "내가 팔로우하지 않는 사람들의 알림을 무시할까요?",
|
||||
"ignore_notifications_modal.private_mentions_title": "요청하지 않은 개인 멘션 알림을 무시할까요?",
|
||||
"info_button.label": "도움말",
|
||||
"info_button.what_is_alt_text": "<h1>대체 텍스트가 무었인가요?</h1> <p>대체 텍스트는 저시력자, 낮은 인터넷 대역폭 사용자, 더 자세한 문맥을 위해 이미지에 대한 설명을 제공하는 것입니다.</p> <p>깔끔하고 간결하고 객관적인 대체 텍스트를 작성해 모두가 이해하기 쉽게 만들고 접근성이 높아질 수 있습니다.</p><ul><li>중요한 요소에 중점을 두세요</li> <li>이미지 안의 글자를 요약하세요</li> <li>정형화된 문장 구조를 사용하세요</li> <li>중복된 정보를 피하세요</li> <li>복잡한 시각자료(도표나 지도 같은)에선 추세와 주요 결과에 중점을 두세요</li> </ul>",
|
||||
"info_button.what_is_alt_text": "<h1>대체 텍스트가 무엇인가요?</h1> <p>대체 텍스트는 저시력자, 낮은 인터넷 대역폭 사용자, 더 자세한 문맥을 위해 이미지에 대한 설명을 제공하는 것입니다.</p> <p>깔끔하고 간결하고 객관적인 대체 텍스트를 작성해 모두가 이해하기 쉽게 만들고 접근성이 높아질 수 있습니다.</p><ul><li>중요한 요소에 중점을 두세요</li> <li>이미지 안의 글자를 요약하세요</li> <li>정형화된 문장 구조를 사용하세요</li> <li>중복된 정보를 피하세요</li> <li>복잡한 시각자료(도표나 지도 같은)에선 추세와 주요 결과에 중점을 두세요</li> </ul>",
|
||||
"interaction_modal.action.favourite": "계속하려면 내 계정으로 즐겨찾기해야 합니다.",
|
||||
"interaction_modal.action.follow": "계속하려면 내 계정으로 팔로우해야 합니다.",
|
||||
"interaction_modal.action.reblog": "계속하려면 내 계정으로 리블로그해야 합니다.",
|
||||
@@ -476,6 +478,7 @@
|
||||
"keyboard_shortcuts.my_profile": "내 프로필 열기",
|
||||
"keyboard_shortcuts.notifications": "알림 컬럼 열기",
|
||||
"keyboard_shortcuts.open_media": "미디어 열기",
|
||||
"keyboard_shortcuts.pinned": "추천 게시물 목록 열기",
|
||||
"keyboard_shortcuts.profile": "작성자의 프로필 열기",
|
||||
"keyboard_shortcuts.reply": "게시물에 답장",
|
||||
"keyboard_shortcuts.requests": "팔로우 요청 리스트 열기",
|
||||
@@ -559,6 +562,7 @@
|
||||
"navigation_bar.mutes": "뮤트한 사용자",
|
||||
"navigation_bar.opened_in_classic_interface": "게시물, 계정, 기타 특정 페이지들은 기본적으로 기존 웹 인터페이스로 열리게 됩니다.",
|
||||
"navigation_bar.personal": "개인용",
|
||||
"navigation_bar.pins": "추천 게시물",
|
||||
"navigation_bar.preferences": "환경설정",
|
||||
"navigation_bar.public_timeline": "연합 타임라인",
|
||||
"navigation_bar.search": "검색",
|
||||
@@ -753,12 +757,12 @@
|
||||
"report.comment.title": "우리가 더 알아야 할 내용이 있나요?",
|
||||
"report.forward": "{target}에 전달",
|
||||
"report.forward_hint": "이 계정은 다른 서버에 있습니다. 익명화 된 사본을 해당 서버에도 전송할까요?",
|
||||
"report.mute": "침묵",
|
||||
"report.mute": "뮤트",
|
||||
"report.mute_explanation": "당신은 해당 계정의 게시물을 보지 않게 됩니다. 해당 계정은 여전히 당신을 팔로우 하거나 당신의 게시물을 볼 수 있으며 해당 계정은 자신이 뮤트 되었는지 알지 못합니다.",
|
||||
"report.next": "다음",
|
||||
"report.placeholder": "코멘트",
|
||||
"report.placeholder": "추가 정보 입력",
|
||||
"report.reasons.dislike": "마음에 안 듭니다",
|
||||
"report.reasons.dislike_description": "내가 보기 싫은 종류에 속합니다",
|
||||
"report.reasons.dislike_description": "원치 않는 게시물입니다",
|
||||
"report.reasons.legal": "불법입니다",
|
||||
"report.reasons.legal_description": "내 서버가 속한 국가의 법률을 위반한다고 생각합니다",
|
||||
"report.reasons.other": "기타",
|
||||
@@ -843,17 +847,18 @@
|
||||
"status.favourite": "좋아요",
|
||||
"status.favourites": "{count, plural, other {좋아요}}",
|
||||
"status.filter": "이 게시물을 필터",
|
||||
"status.history.created": "{name} 님이 {date}에 처음 게시함",
|
||||
"status.history.created": "{name} 님이 {date}에 게시함",
|
||||
"status.history.edited": "{name} 님이 {date}에 수정함",
|
||||
"status.load_more": "더 보기",
|
||||
"status.load_more": "더보기",
|
||||
"status.media.open": "클릭하여 열기",
|
||||
"status.media.show": "클릭하여 보기",
|
||||
"status.media_hidden": "미디어 숨겨짐",
|
||||
"status.mention": "@{name} 님에게 멘션",
|
||||
"status.more": "자세히",
|
||||
"status.mute": "@{name} 뮤트",
|
||||
"status.mute_conversation": "이 대화를 뮤트",
|
||||
"status.mute_conversation": "대화 뮤트",
|
||||
"status.open": "상세 정보 표시",
|
||||
"status.pin": "고정",
|
||||
"status.read_more": "더 보기",
|
||||
"status.reblog": "부스트",
|
||||
"status.reblog_private": "원래의 수신자들에게 부스트",
|
||||
@@ -878,6 +883,7 @@
|
||||
"status.translated_from_with": "{provider}에 의해 {lang}에서 번역됨",
|
||||
"status.uncached_media_warning": "미리보기를 사용할 수 없습니다",
|
||||
"status.unmute_conversation": "이 대화의 뮤트 해제하기",
|
||||
"status.unpin": "고정 취소",
|
||||
"subscribed_languages.lead": "변경 후에는 선택한 언어들로 작성된 게시물들만 홈 타임라인과 리스트 타임라인에 나타나게 됩니다. 아무 것도 선택하지 않으면 모든 언어로 작성된 게시물을 받아봅니다.",
|
||||
"subscribed_languages.save": "변경사항 저장",
|
||||
"subscribed_languages.target": "{target}에 대한 구독 언어 변경",
|
||||
@@ -894,9 +900,9 @@
|
||||
"trends.counter_by_accounts": "이전 {days}일 동안 {counter} 명의 사용자",
|
||||
"trends.trending_now": "지금 유행 중",
|
||||
"ui.beforeunload": "지금 나가면 저장되지 않은 항목을 잃게 됩니다.",
|
||||
"units.short.billion": "{count}B",
|
||||
"units.short.million": "{count}B",
|
||||
"units.short.thousand": "{count}K",
|
||||
"units.short.billion": "{count}십억",
|
||||
"units.short.million": "{count}백만",
|
||||
"units.short.thousand": "{count}천",
|
||||
"upload_area.title": "드래그 & 드롭으로 업로드",
|
||||
"upload_button.label": "이미지, 영상, 오디오 파일 추가",
|
||||
"upload_error.limit": "파일 업로드 제한에 도달했습니다.",
|
||||
@@ -909,7 +915,7 @@
|
||||
"upload_form.edit": "수정",
|
||||
"upload_progress.label": "업로드 중...",
|
||||
"upload_progress.processing": "처리 중...",
|
||||
"username.taken": "이미 쓰인 사용자명입니다. 다른 것으로 시도해보세요",
|
||||
"username.taken": "이미 사용중인 사용자명입니다. 다시 시도해보세요",
|
||||
"video.close": "동영상 닫기",
|
||||
"video.download": "파일 다운로드",
|
||||
"video.exit_fullscreen": "전체화면 나가기",
|
||||
|
||||
@@ -26,6 +26,7 @@
|
||||
"account.edit_profile": "Labot profilu",
|
||||
"account.enable_notifications": "Paziņot man, kad @{name} izveido ierakstu",
|
||||
"account.endorse": "Izcelts profilā",
|
||||
"account.featured.accounts": "Profili",
|
||||
"account.featured.hashtags": "Tēmturi",
|
||||
"account.featured.posts": "Ieraksti",
|
||||
"account.featured_tags.last_status_at": "Pēdējais ieraksts {date}",
|
||||
@@ -369,7 +370,9 @@
|
||||
"hashtag.counter_by_accounts": "{count, plural, zero{{counter} dalībnieku} one {{counter} dalībnieks} other {{counter} dalībnieki}}",
|
||||
"hashtag.counter_by_uses": "{count, plural, zero {{counter} ierakstu} one {{counter} ieraksts} other {{counter} ieraksti}}",
|
||||
"hashtag.counter_by_uses_today": "{count, plural, zero {{counter} ierakstu} one {{counter} ieraksts} other {{counter} ieraksti}} šodien",
|
||||
"hashtag.feature": "Attēlot profilā",
|
||||
"hashtag.follow": "Sekot tēmturim",
|
||||
"hashtag.unfeature": "Neattēlot profilā",
|
||||
"hashtag.unfollow": "Pārstāt sekot tēmturim",
|
||||
"hashtags.and_other": "… un {count, plural, other {vēl #}}",
|
||||
"hints.profiles.see_more_followers": "Skatīt vairāk sekotāju {domain}",
|
||||
|
||||
@@ -670,8 +670,14 @@
|
||||
"notifications.policy.drop_hint": "送去虛空,bē koh看見",
|
||||
"notifications.policy.filter": "過濾器",
|
||||
"notifications.policy.filter_hint": "送kàu受過濾ê通知ê收件kheh-á",
|
||||
"notifications.policy.filter_limited_accounts_hint": "Hōo服侍器ê管理員限制",
|
||||
"notifications.policy.filter_limited_accounts_title": "受管制ê口座",
|
||||
"notifications.policy.filter_new_accounts.hint": "建立tī最近 {days, plural, other {# kang}}內",
|
||||
"notifications.policy.filter_new_accounts_title": "新ê口座",
|
||||
"notifications.policy.filter_not_followers_hint": "包含最近{days, plural, other {# kang}}內跟tuè lí ê lâng",
|
||||
"notifications.policy.filter_not_followers_title": "無跟tuè lí ê lâng",
|
||||
"notifications.policy.filter_not_following_hint": "直到lí手動允准in",
|
||||
"notifications.policy.filter_not_following_title": "Lí無跟tuè ê lâng",
|
||||
"notifications_permission_banner.title": "逐ê著看",
|
||||
"onboarding.follows.back": "轉去",
|
||||
"onboarding.follows.done": "做好ah",
|
||||
|
||||
@@ -29,6 +29,7 @@
|
||||
"account.enable_notifications": "Geef een melding wanneer @{name} een bericht plaatst",
|
||||
"account.endorse": "Op profiel weergeven",
|
||||
"account.featured": "Uitgelicht",
|
||||
"account.featured.accounts": "Profielen",
|
||||
"account.featured.hashtags": "Hashtags",
|
||||
"account.featured.posts": "Berichten",
|
||||
"account.featured_tags.last_status_at": "Laatste bericht op {date}",
|
||||
@@ -405,8 +406,10 @@
|
||||
"hashtag.counter_by_accounts": "{count, plural, one {{counter} deelnemer} other {{counter} deelnemers}}",
|
||||
"hashtag.counter_by_uses": "{count, plural, one {{counter} bericht} other {{counter} berichten}}",
|
||||
"hashtag.counter_by_uses_today": "{count, plural, one {{counter} bericht} other {{counter} berichten}} vandaag",
|
||||
"hashtag.feature": "Op profiel uitlichten",
|
||||
"hashtag.follow": "Hashtag volgen",
|
||||
"hashtag.mute": "#{hashtag} negeren",
|
||||
"hashtag.unfeature": "Niet op profiel uitlichten",
|
||||
"hashtag.unfollow": "Hashtag ontvolgen",
|
||||
"hashtags.and_other": "…en {count, plural, one {}other {# meer}}",
|
||||
"hints.profiles.followers_may_be_missing": "Volgers voor dit profiel kunnen ontbreken.",
|
||||
@@ -857,7 +860,7 @@
|
||||
"status.mute": "@{name} negeren",
|
||||
"status.mute_conversation": "Gesprek negeren",
|
||||
"status.open": "Volledig bericht tonen",
|
||||
"status.pin": "Uitlichten op profiel",
|
||||
"status.pin": "Op profiel uitlichten",
|
||||
"status.read_more": "Meer lezen",
|
||||
"status.reblog": "Boosten",
|
||||
"status.reblog_private": "Boost naar oorspronkelijke ontvangers",
|
||||
@@ -882,7 +885,7 @@
|
||||
"status.translated_from_with": "Vertaald vanuit het {lang} met behulp van {provider}",
|
||||
"status.uncached_media_warning": "Voorvertoning niet beschikbaar",
|
||||
"status.unmute_conversation": "Gesprek niet langer negeren",
|
||||
"status.unpin": "Niet uitlichten op profiel",
|
||||
"status.unpin": "Niet op profiel uitlichten",
|
||||
"subscribed_languages.lead": "Na de wijziging worden alleen berichten van geselecteerde talen op jouw starttijdlijn en in lijsten weergegeven.",
|
||||
"subscribed_languages.save": "Wijzigingen opslaan",
|
||||
"subscribed_languages.target": "Getoonde talen voor {target} wijzigen",
|
||||
|
||||
@@ -29,6 +29,7 @@
|
||||
"account.enable_notifications": "Varsle meg når @{name} skriv innlegg",
|
||||
"account.endorse": "Vis på profilen",
|
||||
"account.featured": "Utvald",
|
||||
"account.featured.accounts": "Profilar",
|
||||
"account.featured.hashtags": "Emneknaggar",
|
||||
"account.featured.posts": "Innlegg",
|
||||
"account.featured_tags.last_status_at": "Sist nytta {date}",
|
||||
@@ -168,6 +169,7 @@
|
||||
"column.lists": "Lister",
|
||||
"column.mutes": "Målbundne brukarar",
|
||||
"column.notifications": "Varsel",
|
||||
"column.pins": "Utvalde innlegg",
|
||||
"column.public": "Samla tidsline",
|
||||
"column_back_button.label": "Attende",
|
||||
"column_header.hide_settings": "Gøym innstillingane",
|
||||
@@ -303,9 +305,9 @@
|
||||
"emoji_button.search_results": "Søkeresultat",
|
||||
"emoji_button.symbols": "Symbol",
|
||||
"emoji_button.travel": "Reise & stader",
|
||||
"empty_column.account_featured.me": "Du har ikkje framheva noko enno. Visste du at du kan framheva innlegg, merkelappar du bruker mykje, og til og med venekontoar på profilen din?",
|
||||
"empty_column.account_featured.other": "{acct} har ikkje framheva noko enno. Visste du at du kan framheva innlegg, merkelappar du bruker mykje, og til og med venekontoar på profilen din?",
|
||||
"empty_column.account_featured_other.unknown": "Denne kontoen har ikkje framheva noko enno.",
|
||||
"empty_column.account_featured.me": "Du har ikkje valt ut noko enno. Visste du at du kan velja ut innlegg, merkelappar du bruker mykje, og til og med venekontoar på profilen din?",
|
||||
"empty_column.account_featured.other": "{acct} har ikkje valt ut noko enno. Visste du at du kan velja ut innlegg, merkelappar du bruker mykje, og til og med venekontoar på profilen din?",
|
||||
"empty_column.account_featured_other.unknown": "Denne kontoen har ikkje valt ut noko enno.",
|
||||
"empty_column.account_hides_collections": "Denne brukaren har valt å ikkje gjere denne informasjonen tilgjengeleg",
|
||||
"empty_column.account_suspended": "Kontoen er utestengd",
|
||||
"empty_column.account_timeline": "Ingen tut her!",
|
||||
@@ -404,8 +406,10 @@
|
||||
"hashtag.counter_by_accounts": "{count, plural,one {{counter} deltakar} other {{counter} deltakarar}}",
|
||||
"hashtag.counter_by_uses": "{count, plural,one {{counter} innlegg} other {{counter} innlegg}}",
|
||||
"hashtag.counter_by_uses_today": "{count, plural,one {{counter} innlegg} other {{counter} innlegg}} i dag",
|
||||
"hashtag.feature": "Vis på profilen",
|
||||
"hashtag.follow": "Fylg emneknagg",
|
||||
"hashtag.mute": "Demp @#{hashtag}",
|
||||
"hashtag.unfeature": "Ikkje vis på profilen",
|
||||
"hashtag.unfollow": "Slutt å fylgje emneknaggen",
|
||||
"hashtags.and_other": "…og {count, plural, one {}other {# fleire}}",
|
||||
"hints.profiles.followers_may_be_missing": "Kven som fylgjer denne profilen manglar kanskje.",
|
||||
@@ -476,6 +480,7 @@
|
||||
"keyboard_shortcuts.my_profile": "Opne profilen din",
|
||||
"keyboard_shortcuts.notifications": "Opne varselkolonna",
|
||||
"keyboard_shortcuts.open_media": "Opne media",
|
||||
"keyboard_shortcuts.pinned": "Opne lista over utvalde innlegg",
|
||||
"keyboard_shortcuts.profile": "Opne forfattaren sin profil",
|
||||
"keyboard_shortcuts.reply": "Svar på innlegg",
|
||||
"keyboard_shortcuts.requests": "Opne lista med fylgjeførespurnader",
|
||||
@@ -559,6 +564,7 @@
|
||||
"navigation_bar.mutes": "Målbundne brukarar",
|
||||
"navigation_bar.opened_in_classic_interface": "Innlegg, kontoar, og enkelte andre sider blir opna som standard i det klassiske webgrensesnittet.",
|
||||
"navigation_bar.personal": "Personleg",
|
||||
"navigation_bar.pins": "Utvalde innlegg",
|
||||
"navigation_bar.preferences": "Innstillingar",
|
||||
"navigation_bar.public_timeline": "Føderert tidsline",
|
||||
"navigation_bar.search": "Søk",
|
||||
@@ -854,6 +860,7 @@
|
||||
"status.mute": "Demp @{name}",
|
||||
"status.mute_conversation": "Demp samtale",
|
||||
"status.open": "Utvid denne statusen",
|
||||
"status.pin": "Vis på profilen",
|
||||
"status.read_more": "Les meir",
|
||||
"status.reblog": "Framhev",
|
||||
"status.reblog_private": "Framhev til dei originale mottakarane",
|
||||
@@ -878,6 +885,7 @@
|
||||
"status.translated_from_with": "Omsett frå {lang} ved bruk av {provider}",
|
||||
"status.uncached_media_warning": "Førehandsvisning er ikkje tilgjengeleg",
|
||||
"status.unmute_conversation": "Opphev demping av samtalen",
|
||||
"status.unpin": "Ikkje vis på profilen",
|
||||
"subscribed_languages.lead": "Kun innlegg på valde språk vil bli dukke opp i heimestraumen din og i listene dine etter denne endringa. For å motta innlegg på alle språk, la vere å velje nokon.",
|
||||
"subscribed_languages.save": "Lagre endringar",
|
||||
"subscribed_languages.target": "Endre abonnerte språk for {target}",
|
||||
|
||||
@@ -386,7 +386,9 @@
|
||||
"hashtag.counter_by_accounts": "{count, plural,one {{counter} participante} other {{counter} participantes}}",
|
||||
"hashtag.counter_by_uses": "{count, plural, one {{counter} publicação} other {{counter} publicações}}",
|
||||
"hashtag.counter_by_uses_today": "{count, plural, one {{counter} publicação} other {{counter} publicações}} hoje",
|
||||
"hashtag.feature": "Destacar no perfil",
|
||||
"hashtag.follow": "Seguir #etiqueta",
|
||||
"hashtag.unfeature": "Não destacar no perfil",
|
||||
"hashtag.unfollow": "Deixar de seguir #etiqueta",
|
||||
"hashtags.and_other": "…e {count, plural, other {mais #}}",
|
||||
"hints.profiles.followers_may_be_missing": "É possível que não estejam a ser mostrados todos os seguidores deste perfil.",
|
||||
|
||||
@@ -330,8 +330,8 @@
|
||||
"empty_column.public": "Здесь ничего нет! Опубликуйте что-нибудь или подпишитесь на пользователей с других серверов, чтобы заполнить ленту",
|
||||
"error.unexpected_crash.explanation": "Из-за несовместимого браузера или ошибки в нашем коде эта страница не может быть корректно отображена.",
|
||||
"error.unexpected_crash.explanation_addons": "Эта страница не может быть корректно отображена. Скорее всего, ошибка вызвана расширением браузера или инструментом автоматического перевода.",
|
||||
"error.unexpected_crash.next_steps": "Попробуйте обновить страницу. Если проблема не исчезает, используйте Mastodon из-под другого браузера или приложения.",
|
||||
"error.unexpected_crash.next_steps_addons": "Попробуйте их отключить и перезагрузить страницу. Если это не поможет, вы по-прежнему сможете войти в Mastodon через другой браузер или приложение.",
|
||||
"error.unexpected_crash.next_steps": "Попробуйте обновить страницу. Если это не поможет, вы, скорее всего, всё ещё сможете использовать Mastodon в другом браузере или приложении.",
|
||||
"error.unexpected_crash.next_steps_addons": "Попробуйте их отключить и обновить страницу. Если это не поможет, вы, скорее всего, всё ещё сможете использовать Mastodon в другом браузере или приложении.",
|
||||
"errors.unexpected_crash.copy_stacktrace": "Скопировать диагностическую информацию",
|
||||
"errors.unexpected_crash.report_issue": "Сообщить о проблеме",
|
||||
"explore.suggested_follows": "Люди",
|
||||
@@ -339,47 +339,47 @@
|
||||
"explore.trending_links": "Новости",
|
||||
"explore.trending_statuses": "Посты",
|
||||
"explore.trending_tags": "Хэштеги",
|
||||
"filter_modal.added.context_mismatch_explanation": "Эта категория не применяется к контексту, в котором вы получили доступ к этому посту. Если вы хотите, чтобы пост был отфильтрован в этом контексте, вам придётся отредактировать фильтр.",
|
||||
"filter_modal.added.context_mismatch_explanation": "Этот фильтр не применяется в том контексте, в котором вы видели этот пост. Если вы хотите, чтобы пост был отфильтрован в этом контексте, необходимо редактировать фильтр.",
|
||||
"filter_modal.added.context_mismatch_title": "Несоответствие контекста!",
|
||||
"filter_modal.added.expired_explanation": "Эта категория фильтра устарела, вам нужно изменить дату окончания фильтра, чтобы применить его.",
|
||||
"filter_modal.added.expired_explanation": "Этот фильтр истёк. Чтобы он был применён, вам нужно изменить срок действия фильтра.",
|
||||
"filter_modal.added.expired_title": "Истёкший фильтр!",
|
||||
"filter_modal.added.review_and_configure": "Для просмотра и настройки этой категории фильтра, перейдите в {settings_link}.",
|
||||
"filter_modal.added.review_and_configure": "Для просмотра или редактирования этого фильтра перейдите в {settings_link}.",
|
||||
"filter_modal.added.review_and_configure_title": "Настройки фильтра",
|
||||
"filter_modal.added.settings_link": "настройки",
|
||||
"filter_modal.added.short_explanation": "Этот пост был добавлен в следующую категорию фильтра: {title}.",
|
||||
"filter_modal.added.short_explanation": "Этот пост был добавлен к фильтру «{title}».",
|
||||
"filter_modal.added.title": "Фильтр добавлен!",
|
||||
"filter_modal.select_filter.context_mismatch": "не применяется к этому контексту",
|
||||
"filter_modal.select_filter.context_mismatch": "не применяется в этом контексте",
|
||||
"filter_modal.select_filter.expired": "истёкший",
|
||||
"filter_modal.select_filter.prompt_new": "Новая категория: {name}",
|
||||
"filter_modal.select_filter.search": "Поиск или создание",
|
||||
"filter_modal.select_filter.subtitle": "Используйте существующую категорию или создайте новую",
|
||||
"filter_modal.select_filter.prompt_new": "Новый фильтр: {name}",
|
||||
"filter_modal.select_filter.search": "Поиск или название нового фильтра",
|
||||
"filter_modal.select_filter.subtitle": "Используйте существующий фильтр или создайте новый",
|
||||
"filter_modal.select_filter.title": "Фильтровать этот пост",
|
||||
"filter_modal.title.status": "Фильтровать пост",
|
||||
"filter_warning.matches_filter": "Соответствует фильтру \"<span>{title}</span>\"",
|
||||
"filter_warning.matches_filter": "Соответствует фильтру «<span>{title}</span>»",
|
||||
"filtered_notifications_banner.pending_requests": "От {count, plural, =0 {не известных вам людей} one {# возможно вам известного человека} other {# возможно вам известных человек}}",
|
||||
"filtered_notifications_banner.title": "Отфильтрованные уведомления",
|
||||
"firehose.all": "Всё вместе",
|
||||
"firehose.local": "Этот сервер",
|
||||
"firehose.remote": "Другие серверы",
|
||||
"follow_request.authorize": "Авторизовать",
|
||||
"follow_request.authorize": "Разрешить",
|
||||
"follow_request.reject": "Отказать",
|
||||
"follow_requests.unlocked_explanation": "Хотя ваша учетная запись не закрыта, команда {domain} подумала, что вы захотите просмотреть запросы от этих учетных записей вручную.",
|
||||
"follow_requests.unlocked_explanation": "Хотя ваша учётная запись не закрыта, команда сервера {domain} подумала, что вы захотите рассмотреть запросы на подписку от этих учётных записей вручную.",
|
||||
"follow_suggestions.curated_suggestion": "Выбор команды сервера",
|
||||
"follow_suggestions.dismiss": "Больше не показывать",
|
||||
"follow_suggestions.featured_longer": "Отобранные командой {domain} вручную",
|
||||
"follow_suggestions.dismiss": "Не показывать снова",
|
||||
"follow_suggestions.featured_longer": "Вручную выбрано командой сервера {domain}",
|
||||
"follow_suggestions.friends_of_friends_longer": "Популярно среди людей, на которых вы подписаны",
|
||||
"follow_suggestions.hints.featured": "Этот профиль был вручную выбран командой {domain}.",
|
||||
"follow_suggestions.hints.featured": "Этот профиль был вручную выбран командой сервера {domain}.",
|
||||
"follow_suggestions.hints.friends_of_friends": "Этот профиль популярен среди людей, на которых вы подписаны.",
|
||||
"follow_suggestions.hints.most_followed": "Этот профиль один из самых отслеживаемых на {domain}.",
|
||||
"follow_suggestions.hints.most_interactions": "Этот профиль в последнее время привлекает много внимания на {domain}.",
|
||||
"follow_suggestions.hints.most_followed": "Этот профиль лидирует по числу подписчиков с сервера {domain}.",
|
||||
"follow_suggestions.hints.most_interactions": "Этот профиль в последнее время привлекает много внимания на сервере {domain}.",
|
||||
"follow_suggestions.hints.similar_to_recently_followed": "Этот профиль похож на другие профили, на которые вы подписывались в последнее время.",
|
||||
"follow_suggestions.personalized_suggestion": "Персонализированное предложение",
|
||||
"follow_suggestions.personalized_suggestion": "Персональное предложение",
|
||||
"follow_suggestions.popular_suggestion": "Популярное предложение",
|
||||
"follow_suggestions.popular_suggestion_longer": "Популярное на {domain}",
|
||||
"follow_suggestions.similar_to_recently_followed_longer": "Похоже на профили, на которые вы недавно подписались",
|
||||
"follow_suggestions.popular_suggestion_longer": "Популярно на сервере {domain}",
|
||||
"follow_suggestions.similar_to_recently_followed_longer": "Похоже на профили, на которые вы подписывались в последнее время",
|
||||
"follow_suggestions.view_all": "Посмотреть все",
|
||||
"follow_suggestions.who_to_follow": "На кого подписаться",
|
||||
"followed_tags": "Отслеживаемые хэштеги",
|
||||
"followed_tags": "Подписки на хэштеги",
|
||||
"footer.about": "О проекте",
|
||||
"footer.directory": "Каталог профилей",
|
||||
"footer.get_app": "Скачать приложение",
|
||||
@@ -401,21 +401,21 @@
|
||||
"hashtag.column_settings.tag_mode.all": "Все из списка",
|
||||
"hashtag.column_settings.tag_mode.any": "Любой из списка",
|
||||
"hashtag.column_settings.tag_mode.none": "Ни один из списка",
|
||||
"hashtag.column_settings.tag_toggle": "Включить дополнительные теги для этой колонки",
|
||||
"hashtag.column_settings.tag_toggle": "Включить дополнительные теги для этого столбца",
|
||||
"hashtag.counter_by_accounts": "{count, plural, one {{counter} пользователь} few {{counter} пользователя} other {{counter} пользователей}}",
|
||||
"hashtag.counter_by_uses": "{count, plural, one {{counter} пост} few {{counter} поста} other {{counter} постов}}",
|
||||
"hashtag.counter_by_uses_today": "{count, plural, one {{counter} пост} few {{counter} поста} other {{counter} постов}} сегодня",
|
||||
"hashtag.follow": "Подписаться на новые посты",
|
||||
"hashtag.mute": "Игнорировать #{hashtag}",
|
||||
"hashtag.unfollow": "Отписаться",
|
||||
"hashtag.unfollow": "Отписаться от новых постов",
|
||||
"hashtags.and_other": "…и {count, plural, other {ещё #}}",
|
||||
"hints.profiles.followers_may_be_missing": "Подписчики этого профиля могут отсутствовать.",
|
||||
"hints.profiles.follows_may_be_missing": "Подписки этого профиля могут отсутствовать.",
|
||||
"hints.profiles.posts_may_be_missing": "Некоторые сообщения этого профиля могут отсутствовать.",
|
||||
"hints.profiles.followers_may_be_missing": "Некоторые подписчики этого профиля могут отсутствовать.",
|
||||
"hints.profiles.follows_may_be_missing": "Некоторые подписки этого профиля могут отсутствовать.",
|
||||
"hints.profiles.posts_may_be_missing": "Некоторые посты в этом профиле могут отсутствовать.",
|
||||
"hints.profiles.see_more_followers": "Перейдите на {domain}, чтобы увидеть всех подписчиков",
|
||||
"hints.profiles.see_more_follows": "Перейдите на {domain}, чтобы увидеть все подписки",
|
||||
"hints.profiles.see_more_posts": "Перейдите на {domain}, чтобы увидеть все посты",
|
||||
"hints.threads.replies_may_be_missing": "Ответы с других серверов могут отсутствовать.",
|
||||
"hints.threads.replies_may_be_missing": "Некоторые ответы с других серверов могут отсутствовать.",
|
||||
"hints.threads.see_more": "Перейдите на {domain}, чтобы увидеть все ответы",
|
||||
"home.column_settings.show_reblogs": "Показывать продвижения",
|
||||
"home.column_settings.show_replies": "Показывать ответы",
|
||||
@@ -495,11 +495,11 @@
|
||||
"lightbox.previous": "Назад",
|
||||
"lightbox.zoom_in": "Масштаб до фактического размера",
|
||||
"lightbox.zoom_out": "Масштаб по размеру экрана",
|
||||
"limited_account_hint.action": "Все равно показать профиль",
|
||||
"limited_account_hint.title": "Этот профиль был скрыт модераторами {domain}.",
|
||||
"limited_account_hint.action": "Всё равно показать",
|
||||
"limited_account_hint.title": "Этот профиль был скрыт модераторами сервера {domain}.",
|
||||
"link_preview.author": "Автор: {name}",
|
||||
"link_preview.more_from_author": "Больше от {name}",
|
||||
"link_preview.shares": "{count, plural, one {{counter} пост} other {{counter} посты}}",
|
||||
"link_preview.more_from_author": "Автор: {name}",
|
||||
"link_preview.shares": "{count, plural, one {{counter} пост} few {{counter} поста} other {{counter} постов}}",
|
||||
"lists.add_member": "Добавить",
|
||||
"lists.add_to_list": "Добавить в список",
|
||||
"lists.add_to_lists": "Добавить {name} в списки",
|
||||
@@ -508,7 +508,7 @@
|
||||
"lists.create_list": "Создать список",
|
||||
"lists.delete": "Удалить список",
|
||||
"lists.done": "Готово",
|
||||
"lists.edit": "Изменить список",
|
||||
"lists.edit": "Редактировать список",
|
||||
"lists.exclusive": "Не показывать участников в домашней ленте",
|
||||
"lists.exclusive_hint": "Если кто-то есть в этом списке, скрыть его в домашней ленте, чтобы не видеть его посты дважды.",
|
||||
"lists.find_users_to_add": "Найти пользователей для добавления",
|
||||
@@ -603,7 +603,6 @@
|
||||
"notification.poll": "Опрос, в котором вы приняли участие, завершился",
|
||||
"notification.reblog": "{name} продвинул(а) ваш пост",
|
||||
"notification.reblog.name_and_others_with_link": "{name} и ещё <a>{count, plural, one {# пользователь} few {# пользователя} other {# пользователей}}</a> продвинули ваш пост",
|
||||
"notification.relationships_severance_event": "Потеряно соединение с {name}",
|
||||
"notification.relationships_severance_event.account_suspension": "Администратор {from} заблокировал {target}, что означает, что вы больше не сможете получать обновления от них или взаймодествовать с ними.",
|
||||
"notification.relationships_severance_event.domain_block": "Администратор {from} заблокировал {target} включая {followersCount} ваших подписчиков и {followingCount, plural, one {# аккаунт} few {# аккаунта} other {# аккаунтов}}, на которые вы подписаны.",
|
||||
"notification.relationships_severance_event.learn_more": "Узнать больше",
|
||||
|
||||
@@ -29,6 +29,7 @@
|
||||
"account.enable_notifications": "Njoftomë, kur poston @{name}",
|
||||
"account.endorse": "Pasqyrojeni në profil",
|
||||
"account.featured": "Të zgjedhur",
|
||||
"account.featured.accounts": "Profile",
|
||||
"account.featured.hashtags": "Hashtag-ë",
|
||||
"account.featured.posts": "Postime",
|
||||
"account.featured_tags.last_status_at": "Postimi i fundit më {date}",
|
||||
@@ -400,8 +401,10 @@
|
||||
"hashtag.counter_by_accounts": "{count, plural, one {{counter} pjesëmarrës} other {{counter} pjesëmarrës}}",
|
||||
"hashtag.counter_by_uses": "{count, plural, one {{counter} postim} other {{counter} postime}}",
|
||||
"hashtag.counter_by_uses_today": "{count, plural, one {{counter} postim} other {{counter} postime}} sot",
|
||||
"hashtag.feature": "Pasqyrojeni në profil",
|
||||
"hashtag.follow": "Ndiqe hashtag-un",
|
||||
"hashtag.mute": "Heshtoje #{hashtag}",
|
||||
"hashtag.unfeature": "Mos e përfshi në profil",
|
||||
"hashtag.unfollow": "Hiqe ndjekjen e hashtag-ut",
|
||||
"hashtags.and_other": "…dhe {count, plural, one {}other {# më tepër}}",
|
||||
"hints.profiles.followers_may_be_missing": "Mund të mungojnë ndjekës për këtë profil.",
|
||||
|
||||
@@ -29,6 +29,7 @@
|
||||
"account.enable_notifications": "@{name} kişisinin gönderi bildirimlerini aç",
|
||||
"account.endorse": "Profilimde öne çıkar",
|
||||
"account.featured": "Öne çıkan",
|
||||
"account.featured.accounts": "Profiller",
|
||||
"account.featured.hashtags": "Etiketler",
|
||||
"account.featured.posts": "Gönderiler",
|
||||
"account.featured_tags.last_status_at": "Son gönderinin tarihi {date}",
|
||||
@@ -405,8 +406,10 @@
|
||||
"hashtag.counter_by_accounts": "{count, plural, one {{counter} katılımcı} other {{counter} katılımcı}}",
|
||||
"hashtag.counter_by_uses": "{count, plural, one {{counter} gönderi} other {{counter} gönderi}}",
|
||||
"hashtag.counter_by_uses_today": "bugün {count, plural, one {{counter} gönderi} other {{counter} gönderi}}",
|
||||
"hashtag.feature": "Profilimde öne çıkar",
|
||||
"hashtag.follow": "Etiketi takip et",
|
||||
"hashtag.mute": "#{hashtag} gönderilerini sessize al",
|
||||
"hashtag.unfeature": "Profilimde öne çıkarma",
|
||||
"hashtag.unfollow": "Etiketi takibi bırak",
|
||||
"hashtags.and_other": "…ve {count, plural, one {}other {# fazlası}}",
|
||||
"hints.profiles.followers_may_be_missing": "Bu profilin takipçileri eksik olabilir.",
|
||||
|
||||
@@ -27,6 +27,7 @@
|
||||
"account.enable_notifications": "Повідомляти мене про дописи @{name}",
|
||||
"account.endorse": "Рекомендувати у моєму профілі",
|
||||
"account.featured": "Рекомендоване",
|
||||
"account.featured.accounts": "Профілі",
|
||||
"account.featured.hashtags": "Хештеги",
|
||||
"account.featured.posts": "Дописи",
|
||||
"account.featured_tags.last_status_at": "Останній допис {date}",
|
||||
|
||||
@@ -29,6 +29,7 @@
|
||||
"account.enable_notifications": "Nhận thông báo khi @{name} đăng tút",
|
||||
"account.endorse": "Tôn vinh người này",
|
||||
"account.featured": "Nêu bật",
|
||||
"account.featured.accounts": "Mọi người",
|
||||
"account.featured.hashtags": "Hashtag",
|
||||
"account.featured.posts": "Tút",
|
||||
"account.featured_tags.last_status_at": "Tút gần nhất {date}",
|
||||
@@ -405,8 +406,10 @@
|
||||
"hashtag.counter_by_accounts": "{count, plural, other {{counter} người dùng}}",
|
||||
"hashtag.counter_by_uses": "{count, plural, other {{counter} tút}}",
|
||||
"hashtag.counter_by_uses_today": "{count, plural, other {{counter} tút}} hôm nay",
|
||||
"hashtag.feature": "Nêu bật trên hồ sơ",
|
||||
"hashtag.follow": "Theo dõi hashtag",
|
||||
"hashtag.mute": "Ẩn #{hashtag}",
|
||||
"hashtag.unfeature": "Bỏ nêu bật trên hồ sơ",
|
||||
"hashtag.unfollow": "Bỏ theo dõi hashtag",
|
||||
"hashtags.and_other": "…và {count, plural, other {# nữa}}",
|
||||
"hints.profiles.followers_may_be_missing": "Số người theo dõi có thể không đầy đủ.",
|
||||
|
||||
@@ -29,6 +29,7 @@
|
||||
"account.enable_notifications": "當 @{name} 嘟文時通知我",
|
||||
"account.endorse": "於個人檔案推薦對方",
|
||||
"account.featured": "精選內容",
|
||||
"account.featured.accounts": "個人檔案",
|
||||
"account.featured.hashtags": "主題標籤",
|
||||
"account.featured.posts": "嘟文",
|
||||
"account.featured_tags.last_status_at": "上次嘟文於 {date}",
|
||||
@@ -405,8 +406,10 @@
|
||||
"hashtag.counter_by_accounts": "{count, plural, one {{counter} 名} other {{counter} 名}}參與者",
|
||||
"hashtag.counter_by_uses": "{count, plural, one {{counter} 則} other {{counter} 則}}嘟文",
|
||||
"hashtag.counter_by_uses_today": "本日有 {count, plural, one {{counter} 則} other {{counter} 則}}嘟文",
|
||||
"hashtag.feature": "於個人檔案推薦",
|
||||
"hashtag.follow": "跟隨主題標籤",
|
||||
"hashtag.mute": "靜音 #{hashtag}",
|
||||
"hashtag.unfeature": "取消於個人檔案推薦",
|
||||
"hashtag.unfollow": "取消跟隨主題標籤",
|
||||
"hashtags.and_other": "…及其他 {count, plural, other {# 個}}",
|
||||
"hints.profiles.followers_may_be_missing": "此個人檔案之跟隨者或有缺失。",
|
||||
@@ -525,7 +528,7 @@
|
||||
"lists.replies_policy.none": "沒有人",
|
||||
"lists.save": "儲存",
|
||||
"lists.search": "搜尋",
|
||||
"lists.show_replies_to": "包含來自列表成員的回覆到",
|
||||
"lists.show_replies_to": "包含來自列表成員的回覆至",
|
||||
"load_pending": "{count, plural, other {# 個新項目}}",
|
||||
"loading_indicator.label": "正在載入...",
|
||||
"media_gallery.hide": "隱藏",
|
||||
|
||||
@@ -4,9 +4,9 @@ import { Map as ImmutableMap } from 'immutable';
|
||||
import {
|
||||
followAccountSuccess,
|
||||
unfollowAccountSuccess,
|
||||
importAccounts,
|
||||
revealAccount,
|
||||
} from 'mastodon/actions/accounts_typed';
|
||||
import { importAccounts } from 'mastodon/actions/importer/accounts';
|
||||
import type { ApiAccountJSON } from 'mastodon/api_types/accounts';
|
||||
import { me } from 'mastodon/initial_state';
|
||||
import type { Account } from 'mastodon/models/account';
|
||||
|
||||
@@ -1,23 +0,0 @@
|
||||
import { Map as ImmutableMap } from 'immutable';
|
||||
|
||||
import { ACCOUNT_LOOKUP_FAIL } from '../actions/accounts';
|
||||
import { importAccounts } from '../actions/accounts_typed';
|
||||
import { domain } from '../initial_state';
|
||||
|
||||
const pattern = new RegExp(`@${domain}$`, 'gi');
|
||||
|
||||
export const normalizeForLookup = str =>
|
||||
str.toLowerCase().replace(pattern, '');
|
||||
|
||||
const initialState = ImmutableMap();
|
||||
|
||||
export default function accountsMap(state = initialState, action) {
|
||||
switch(action.type) {
|
||||
case ACCOUNT_LOOKUP_FAIL:
|
||||
return action.error?.response?.status === 404 ? state.set(normalizeForLookup(action.acct), null) : state;
|
||||
case importAccounts.type:
|
||||
return state.withMutations(map => action.payload.accounts.forEach(account => map.set(normalizeForLookup(account.acct), account.id)));
|
||||
default:
|
||||
return state;
|
||||
}
|
||||
}
|
||||
38
app/javascript/mastodon/reducers/accounts_map.ts
Normal file
@@ -0,0 +1,38 @@
|
||||
import { createReducer } from '@reduxjs/toolkit';
|
||||
import type { UnknownAction } from '@reduxjs/toolkit';
|
||||
|
||||
import type { AxiosError } from 'axios';
|
||||
|
||||
import { ACCOUNT_LOOKUP_FAIL } from 'mastodon/actions/accounts';
|
||||
import { importAccounts } from 'mastodon/actions/importer/accounts';
|
||||
import { domain } from 'mastodon/initial_state';
|
||||
|
||||
interface AccountLookupFailAction extends UnknownAction {
|
||||
acct: string;
|
||||
error?: AxiosError;
|
||||
}
|
||||
|
||||
const pattern = new RegExp(`@${domain}$`, 'gi');
|
||||
|
||||
export const normalizeForLookup = (str: string) =>
|
||||
str.toLowerCase().replace(pattern, '');
|
||||
|
||||
const initialState: Record<string, string | null> = {};
|
||||
|
||||
export const accountsMapReducer = createReducer(initialState, (builder) => {
|
||||
builder
|
||||
.addCase(importAccounts, (state, action) => {
|
||||
action.payload.accounts.forEach((account) => {
|
||||
state[normalizeForLookup(account.acct)] = account.id;
|
||||
});
|
||||
})
|
||||
.addMatcher(
|
||||
(action: UnknownAction): action is AccountLookupFailAction =>
|
||||
action.type === ACCOUNT_LOOKUP_FAIL,
|
||||
(state, action) => {
|
||||
if (action.error?.response?.status === 404) {
|
||||
state[normalizeForLookup(action.acct)] = null;
|
||||
}
|
||||
},
|
||||
);
|
||||
});
|
||||
@@ -4,7 +4,7 @@ import { loadingBarReducer } from 'react-redux-loading-bar';
|
||||
import { combineReducers } from 'redux-immutable';
|
||||
|
||||
import { accountsReducer } from './accounts';
|
||||
import accounts_map from './accounts_map';
|
||||
import { accountsMapReducer } from './accounts_map';
|
||||
import { alertsReducer } from './alerts';
|
||||
import announcements from './announcements';
|
||||
import { composeReducer } from './compose';
|
||||
@@ -49,7 +49,7 @@ const reducers = {
|
||||
user_lists,
|
||||
status_lists,
|
||||
accounts: accountsReducer,
|
||||
accounts_map,
|
||||
accounts_map: accountsMapReducer,
|
||||
statuses,
|
||||
relationships: relationshipsReducer,
|
||||
settings,
|
||||
|
||||
@@ -5,9 +5,7 @@ import {
|
||||
fetchDirectory
|
||||
} from 'mastodon/actions/directory';
|
||||
import {
|
||||
FEATURED_TAGS_FETCH_REQUEST,
|
||||
FEATURED_TAGS_FETCH_SUCCESS,
|
||||
FEATURED_TAGS_FETCH_FAIL,
|
||||
fetchFeaturedTags
|
||||
} from 'mastodon/actions/featured_tags';
|
||||
|
||||
import {
|
||||
@@ -31,6 +29,7 @@ import {
|
||||
FOLLOW_REQUESTS_EXPAND_FAIL,
|
||||
authorizeFollowRequestSuccess,
|
||||
rejectFollowRequestSuccess,
|
||||
fetchEndorsedAccounts,
|
||||
} from '../actions/accounts';
|
||||
import {
|
||||
BLOCKS_FETCH_REQUEST,
|
||||
@@ -191,21 +190,27 @@ export default function userLists(state = initialState, action) {
|
||||
case MUTES_FETCH_FAIL:
|
||||
case MUTES_EXPAND_FAIL:
|
||||
return state.setIn(['mutes', 'isLoading'], false);
|
||||
case FEATURED_TAGS_FETCH_SUCCESS:
|
||||
return normalizeFeaturedTags(state, ['featured_tags', action.id], action.tags, action.id);
|
||||
case FEATURED_TAGS_FETCH_REQUEST:
|
||||
return state.setIn(['featured_tags', action.id, 'isLoading'], true);
|
||||
case FEATURED_TAGS_FETCH_FAIL:
|
||||
return state.setIn(['featured_tags', action.id, 'isLoading'], false);
|
||||
default:
|
||||
if(fetchDirectory.fulfilled.match(action))
|
||||
if (fetchEndorsedAccounts.fulfilled.match(action))
|
||||
return normalizeList(state, ['featured_accounts', action.meta.arg.accountId], action.payload, undefined);
|
||||
else if (fetchEndorsedAccounts.pending.match(action))
|
||||
return state.setIn(['featured_accounts', action.meta.arg.accountId, 'isLoading'], true);
|
||||
else if (fetchEndorsedAccounts.rejected.match(action))
|
||||
return state.setIn(['featured_accounts', action.meta.arg.accountId, 'isLoading'], false);
|
||||
else if (fetchFeaturedTags.fulfilled.match(action))
|
||||
return normalizeFeaturedTags(state, ['featured_tags', action.meta.arg.accountId], action.payload, action.meta.arg.accountId);
|
||||
else if (fetchFeaturedTags.pending.match(action))
|
||||
return state.setIn(['featured_tags', action.meta.arg.accountId, 'isLoading'], true);
|
||||
else if (fetchFeaturedTags.rejected.match(action))
|
||||
return state.setIn(['featured_tags', action.meta.arg.accountId, 'isLoading'], false);
|
||||
else if (fetchDirectory.fulfilled.match(action))
|
||||
return normalizeList(state, ['directory'], action.payload.accounts, undefined);
|
||||
else if( expandDirectory.fulfilled.match(action))
|
||||
else if (expandDirectory.fulfilled.match(action))
|
||||
return appendToList(state, ['directory'], action.payload.accounts, undefined);
|
||||
else if(fetchDirectory.pending.match(action) ||
|
||||
else if (fetchDirectory.pending.match(action) ||
|
||||
expandDirectory.pending.match(action))
|
||||
return state.setIn(['directory', 'isLoading'], true);
|
||||
else if(fetchDirectory.rejected.match(action) ||
|
||||
else if (fetchDirectory.rejected.match(action) ||
|
||||
expandDirectory.rejected.match(action))
|
||||
return state.setIn(['directory', 'isLoading'], false);
|
||||
else
|
||||
|
||||
@@ -41,7 +41,7 @@ export const getDescendantsIds = createAppSelector(
|
||||
}
|
||||
|
||||
if (replies) {
|
||||
replies.reverse().forEach((replyId) => {
|
||||
replies.toReversed().forEach((replyId) => {
|
||||
if (
|
||||
!visitIds.includes(replyId) &&
|
||||
!descendantsIds.includes(replyId) &&
|
||||
|
||||
@@ -959,6 +959,8 @@ cy:
|
||||
system_checks:
|
||||
database_schema_check:
|
||||
message_html: Mae mudo cronfa ddata ar fin digwydd. Rhedwch nhw i sicrhau bod y rhaglen yn ymddwyn yn ôl y disgwyl
|
||||
elasticsearch_analysis_index_mismatch:
|
||||
message_html: Mae gosodiadau dadansoddwr mynegai Elasticsearch wedi dyddio. Rhedwch <code>tootctl search deploy --only-mapping --only=%{value}</code>
|
||||
elasticsearch_health_red:
|
||||
message_html: Mae clwstwr Elasticsearch yn afiach (statws coch), nid yw'r nodweddion chwilio ar gael
|
||||
elasticsearch_health_yellow:
|
||||
|
||||
@@ -486,7 +486,10 @@ fi:
|
||||
created_at: Luotu
|
||||
delete: Poista
|
||||
ip: IP-osoite
|
||||
title: Aloita takaisinkutsujen vianetsintä
|
||||
providers:
|
||||
base_url: Perus-URL
|
||||
callback: Takaisinkutsu
|
||||
delete: Poista
|
||||
finish_registration: Viimeistele rekisteröinti
|
||||
name: Nimi
|
||||
|
||||
@@ -275,6 +275,10 @@ kab:
|
||||
ip: Tansa IP
|
||||
providers:
|
||||
delete: Kkes
|
||||
name: Isem
|
||||
providers: Asaǧǧaw
|
||||
registrations:
|
||||
confirm: Sentem
|
||||
save: Sekles
|
||||
title: FASP
|
||||
follow_recommendations:
|
||||
@@ -387,6 +391,7 @@ kab:
|
||||
everyone: Tisirag timezwura
|
||||
privileges:
|
||||
administrator: Anedbal
|
||||
manage_settings: Asefrek n iɣewwaṛen
|
||||
view_dashboard: Timẓriwt n tfelwit
|
||||
rules:
|
||||
add_new: Rnu alugen
|
||||
@@ -451,6 +456,7 @@ kab:
|
||||
changelog: Amaynut
|
||||
draft: Arewway
|
||||
history: Amazray
|
||||
live: Srid
|
||||
publish: Asuffeɣ
|
||||
save_draft: Sekles arewway
|
||||
title: Tiwtilin n useqdec
|
||||
|
||||
@@ -304,6 +304,7 @@ lt:
|
||||
create: Sukurti skelbimą
|
||||
title: Naujas skelbimas
|
||||
preview:
|
||||
disclaimer: Kadangi naudotojai negali jų atsisakyti, el. pašto pranešimai turėtų būti siunčiami tik svarbiems pranešimams, pavyzdžiui, asmeninių duomenų pažeidimo ar serverio uždarymo pranešimams.
|
||||
explanation_html: 'El. laiškas bus išsiųstas <strong>%{display_count} naudotojams</strong>. Į el. laišką bus įtrauktas toliau nurodytas tekstas:'
|
||||
title: Peržiūrėti skelbimo pranešimą
|
||||
publish: Skelbti
|
||||
|
||||
@@ -904,7 +904,7 @@ nl:
|
||||
database_schema_check:
|
||||
message_html: Niet alle databasemigraties zijn voltooid. Je moet deze uitvoeren om er voor te zorgen dat de applicatie blijft werken zoals het hoort
|
||||
elasticsearch_analysis_index_mismatch:
|
||||
message_html: Elasticsearch index analyser instellingen zijn verouderd. Voer <code>tootctl zoek deploy --only-mapping --only=%{value}</code> uit
|
||||
message_html: Elasticsearch index analyser-instellingen zijn verouderd. Voer <code>tootctl search deploy --only-mapping --only=%{value}</code> uit
|
||||
elasticsearch_health_red:
|
||||
message_html: Elasticsearch-cluster is ongezond (rode status), zoekfuncties zijn niet beschikbaar
|
||||
elasticsearch_health_yellow:
|
||||
|
||||
@@ -903,6 +903,8 @@ nn:
|
||||
system_checks:
|
||||
database_schema_check:
|
||||
message_html: Det venter på databaseoverføringer. Vennligst kjør disse for å sikre at applikasjonen oppfører seg som forventet
|
||||
elasticsearch_analysis_index_mismatch:
|
||||
message_html: Indeksanalyseinnstillingane til Elasticsearch er utdaterte. Køyr <code>tootctl search deploy --only-mapping --only=%{value}</code>
|
||||
elasticsearch_health_red:
|
||||
message_html: Elasticsearch-klynga er usunn (raud status), og søkjefunksjonane er utilgjengelege
|
||||
elasticsearch_health_yellow:
|
||||
@@ -1367,8 +1369,8 @@ nn:
|
||||
featured_tags:
|
||||
add_new: Legg til ny
|
||||
errors:
|
||||
limit: Du har allereie framheva så mange emneknaggar som det går an å gjera
|
||||
hint_html: "<strong>Hva er utvalgte emneknagger?</strong> De vises frem tydelig på din offentlige profil, og lar folk bla i dine offentlige innlegg som spesifikt har de emneknaggene. De er et bra verktøy for å holde styr på kreative verk eller langtidsprosjekter."
|
||||
limit: Du har allereie valt ut så mange emneknaggar som det går an å gjera
|
||||
hint_html: "<strong>Vel ut dei viktigaste emneknaggane på profilen din.</strong> Utvalde emneknaggar er eit flott verkty for å halda oversikt over kreativt arbeid og langtidsprosjekt. Dei er lette å sjå på profilen din, og gjev deg rask tilgang til dine eigne innlegg."
|
||||
filters:
|
||||
contexts:
|
||||
account: Profiler
|
||||
@@ -1805,7 +1807,7 @@ nn:
|
||||
development: Utvikling
|
||||
edit_profile: Endr profil
|
||||
export: Eksporter
|
||||
featured_tags: Utvalgte emneknagger
|
||||
featured_tags: Utvalde emneknaggar
|
||||
import: Hent inn
|
||||
import_and_export: Importer og eksporter
|
||||
migrate: Kontoflytting
|
||||
|
||||
@@ -381,7 +381,7 @@ pl:
|
||||
few: "<strong>%{count}</strong> oczekujące raporty"
|
||||
many: "<strong>%{count}</strong> oczekujących raportów"
|
||||
one: "<strong>%{count}</strong> oczekujące zgłoszenie"
|
||||
other: "<strong>%{count}</strong> oczekujących raportów"
|
||||
other: "<strong>%{count}</strong> oczekujących zgłoszeń"
|
||||
pending_tags_html:
|
||||
few: "<strong>%{count}</strong> oczekujące hashtagi"
|
||||
many: "<strong>%{count}</strong> oczekujących hashtagów"
|
||||
|
||||
@@ -1628,7 +1628,7 @@ zh-TW:
|
||||
thousand: K
|
||||
trillion: T
|
||||
otp_authentication:
|
||||
code_hint: 請輸入您驗證應用程式所產生的代碼以確認
|
||||
code_hint: 請輸入您驗證應用程式所產生之 token 以確認
|
||||
description_html: 若您啟用使用驗證應用程式的<strong>兩階段驗證</strong>,您每次登入都需要輸入由您的手機所產生之 Token。
|
||||
enable: 啟用
|
||||
instructions_html: "<strong>請用您手機上的 Google Authenticator 或類似的 TOTP 應用程式掃描此 QR code</strong>。從現在開始,該應用程式將會產生您每次登入都必須輸入的 token。"
|
||||
|
||||
@@ -48,7 +48,7 @@ module.exports = merge(sharedConfig, {
|
||||
logLevel: 'silent', // do not bother Webpacker, who runs with --json and parses stdout
|
||||
}),
|
||||
new InjectManifest({
|
||||
additionalManifestEntries: ['1f602.svg', 'sheet_15.png'].map((filename) => {
|
||||
additionalManifestEntries: ['1f602.svg', 'sheet_15_1.png'].map((filename) => {
|
||||
const path = resolve(root, 'public', 'emoji', filename);
|
||||
const body = readFileSync(path);
|
||||
const md5 = createHash('md5');
|
||||
|
||||
@@ -1,5 +1,7 @@
|
||||
# frozen_string_literal: true
|
||||
|
||||
require 'vips'
|
||||
|
||||
def gen_border(codepoint, color)
|
||||
input = Rails.public_path.join('emoji', "#{codepoint}.svg")
|
||||
dest = Rails.public_path.join('emoji', "#{codepoint}_border.svg")
|
||||
@@ -42,10 +44,24 @@ def codepoints_to_unicode(codepoints)
|
||||
end
|
||||
end
|
||||
|
||||
def get_image(row, emoji_base, fallback, compressed)
|
||||
path = emoji_base.join("#{row[compressed ? 'b' : 'unified'].downcase}.svg")
|
||||
path = emoji_base.join("#{row[compressed ? 'c' : 'non_qualified'].downcase.sub(/^00/, '')}.svg") if !path.exist? && row[compressed ? 'c' : 'non_qualified']
|
||||
if path.exist?
|
||||
Vips::Image.new_from_file(path.to_s, dpi: 64)
|
||||
else
|
||||
fallback
|
||||
end
|
||||
end
|
||||
|
||||
def titleize(string)
|
||||
string.humanize.gsub(/\b(?<!['’`()])(?!(and|the|or|with|a)\b)[a-z]/, &:capitalize)
|
||||
end
|
||||
|
||||
namespace :emojis do
|
||||
desc 'Generate a unicode to filename mapping'
|
||||
task :generate do
|
||||
source = 'http://www.unicode.org/Public/emoji/15.0/emoji-test.txt'
|
||||
source = 'http://www.unicode.org/Public/emoji/15.1/emoji-test.txt'
|
||||
codes = []
|
||||
dest = Rails.root.join('app', 'javascript', 'mastodon', 'features', 'emoji', 'emoji_map.json')
|
||||
|
||||
@@ -104,35 +120,110 @@ namespace :emojis do
|
||||
end
|
||||
end
|
||||
|
||||
desc 'Download the JSON sheet data of emojis'
|
||||
task :download_sheet_json do
|
||||
source = 'https://raw.githubusercontent.com/iamcal/emoji-data/refs/tags/v15.1.2/emoji.json'
|
||||
dest = Rails.root.join('app', 'javascript', 'mastodon', 'features', 'emoji', 'emoji_sheet.json')
|
||||
desc 'Generate the JSON emoji data'
|
||||
task :generate_json do
|
||||
data_source = 'https://raw.githubusercontent.com/iamcal/emoji-data/refs/tags/v15.1.2/emoji.json'
|
||||
keyword_source = 'https://raw.githubusercontent.com/muan/emojilib/refs/tags/v3.0.12/dist/emoji-en-US.json'
|
||||
data_dest = Rails.root.join('app', 'javascript', 'mastodon', 'features', 'emoji', 'emoji_data.json')
|
||||
|
||||
puts "Downloading emoji data from source... (#{source})"
|
||||
|
||||
res = HTTP.get(source).to_s
|
||||
puts "Downloading emoji data from source... (#{data_source})"
|
||||
res = HTTP.get(data_source).to_s
|
||||
data = JSON.parse(res)
|
||||
|
||||
filtered_data = data.map do |emoji|
|
||||
filtered_item = {
|
||||
'unified' => emoji['unified'],
|
||||
'sheet_x' => emoji['sheet_x'],
|
||||
'sheet_y' => emoji['sheet_y'],
|
||||
'skin_variations' => {},
|
||||
puts "Downloading keyword data from source... (#{keyword_source})"
|
||||
res = HTTP.get(keyword_source).to_s
|
||||
keywords = JSON.parse(res)
|
||||
|
||||
puts 'Generating JSON emoji data...'
|
||||
|
||||
emoji_data = {
|
||||
compressed: true,
|
||||
categories: [
|
||||
{ id: 'smileys', name: 'Smileys & Emotion', emojis: [] },
|
||||
{ id: 'people', name: 'People & Body', emojis: [] },
|
||||
{ id: 'nature', name: 'Animals & Nature', emojis: [] },
|
||||
{ id: 'foods', name: 'Food & Drink', emojis: [] },
|
||||
{ id: 'activity', name: 'Activities', emojis: [] },
|
||||
{ id: 'places', name: 'Travel & Places', emojis: [] },
|
||||
{ id: 'objects', name: 'Objects', emojis: [] },
|
||||
{ id: 'symbols', name: 'Symbols', emojis: [] },
|
||||
{ id: 'flags', name: 'Flags', emojis: [] },
|
||||
],
|
||||
emojis: {},
|
||||
aliases: {},
|
||||
}
|
||||
|
||||
sorted = data.sort { |a, b| (a['sort_order'] || a['short_name']) - (b['sort_order'] || b['sort_name']) }
|
||||
category_map = emoji_data[:categories].each_with_index.to_h { |c, i| [c[:name], i] }
|
||||
|
||||
sorted.each do |emoji|
|
||||
emoji_keywords = keywords[codepoints_to_unicode(emoji['unified'].downcase)]
|
||||
|
||||
single_emoji = {
|
||||
a: titleize(emoji['name']), # name
|
||||
b: emoji['unified'], # unified
|
||||
f: true, # has_img_twitter
|
||||
k: [emoji['sheet_x'], emoji['sheet_y']], # sheet
|
||||
}
|
||||
|
||||
emoji['skin_variations']&.each do |key, variation|
|
||||
filtered_item['skin_variations'][key] = {
|
||||
'unified' => variation['unified'],
|
||||
'sheet_x' => variation['sheet_x'],
|
||||
'sheet_y' => variation['sheet_y'],
|
||||
}
|
||||
end
|
||||
single_emoji[:c] = emoji['non_qualified'] unless emoji['non_qualified'].nil? # non_qualified
|
||||
single_emoji[:j] = emoji_keywords.filter { |k| k != emoji['short_name'] } if emoji_keywords.present? # keywords
|
||||
single_emoji[:l] = emoji['texts'] if emoji['texts'].present? # emoticons
|
||||
single_emoji[:m] = emoji['text'] if emoji['text'].present? # text
|
||||
single_emoji[:skin_variations] = emoji['skin_variations'] if emoji['skin_variations'].present?
|
||||
|
||||
filtered_item
|
||||
emoji_data[:emojis][emoji['short_name']] = single_emoji
|
||||
emoji_data[:categories][category_map[emoji['category']]][:emojis].push(emoji['short_name']) if emoji['category'] != 'Component'
|
||||
|
||||
emoji['short_names'].each do |name|
|
||||
emoji_data[:aliases][name] = emoji['short_name'] unless name == emoji['short_name']
|
||||
end
|
||||
end
|
||||
|
||||
File.write(dest, JSON.generate(filtered_data))
|
||||
smileys = emoji_data[:categories][0]
|
||||
people = emoji_data[:categories][1]
|
||||
smileys_and_people = { id: 'people', name: 'Smileys & People', emojis: [*smileys[:emojis][..128], *people[:emojis], *smileys[:emojis][129..]] }
|
||||
emoji_data[:categories].unshift(smileys_and_people)
|
||||
emoji_data[:categories] -= emoji_data[:categories][1, 2]
|
||||
|
||||
File.write(data_dest, JSON.generate(emoji_data))
|
||||
end
|
||||
|
||||
desc 'Generate a spritesheet of emojis'
|
||||
task :generate_emoji_sheet do
|
||||
src = Rails.root.join('app', 'javascript', 'mastodon', 'features', 'emoji', 'emoji_data.json')
|
||||
sheet = Oj.load(File.read(src))
|
||||
|
||||
max = 0
|
||||
sheet['emojis'].each_value do |row|
|
||||
max = [max, row['k'][0], row['k'][1]].max
|
||||
next if row['skin_variations'].blank?
|
||||
|
||||
row['skin_variations'].each_value do |variation|
|
||||
max = [max, variation['sheet_x'], variation['sheet_y']].max
|
||||
end
|
||||
end
|
||||
|
||||
size = max + 1
|
||||
|
||||
puts 'Generating spritesheet...'
|
||||
|
||||
emoji_base = Rails.public_path.join('emoji')
|
||||
fallback = Vips::Image.new_from_file(emoji_base.join('2753.svg').to_s, dpi: 64)
|
||||
comp = Array.new(size) do
|
||||
Array.new(size, 0)
|
||||
end
|
||||
|
||||
sheet['emojis'].each_value do |row|
|
||||
comp[row['k'][1]][row['k'][0]] = get_image(row, emoji_base, fallback, true)
|
||||
next if row['skin_variations'].blank?
|
||||
|
||||
row['skin_variations'].each_value do |variation|
|
||||
comp[variation['sheet_y']][variation['sheet_x']] = get_image(variation, emoji_base, fallback, false)
|
||||
end
|
||||
end
|
||||
|
||||
joined = Vips::Image.arrayjoin(comp.flatten, across: size, hspacing: 34, halign: :centre, vspacing: 34, valign: :centre)
|
||||
joined.write_to_file(emoji_base.join('sheet_15_1.png').to_s, palette: true, dither: 0, Q: 100)
|
||||
end
|
||||
end
|
||||
|
||||
@@ -46,7 +46,6 @@
|
||||
"@dnd-kit/core": "^6.1.0",
|
||||
"@dnd-kit/sortable": "^10.0.0",
|
||||
"@dnd-kit/utilities": "^3.2.2",
|
||||
"@emoji-mart/data": "1.2.1",
|
||||
"@formatjs/intl-pluralrules": "^5.4.4",
|
||||
"@gamestdio/websocket": "^0.3.2",
|
||||
"@github/webauthn-json": "^2.1.1",
|
||||
|
||||
1
public/emoji/1f344-200d-1f7eb.svg
Normal file
@@ -0,0 +1 @@
|
||||
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 36 36"><path fill="#F2C994" d="M27 33c0 2.209-1.791 3-4 3H13c-2.209 0-4-.791-4-3s3-7 3-13 12-6 12 0 3 10.791 3 13z"/><path fill="#C1694F" d="M34.666 11.189l-.001-.002c-.96-2.357-2.404-4.453-4.208-6.182h-.003C27.222 1.904 22.839 0 18 0 13.638 0 9.639 1.541 6.524 4.115c-2.19 1.809-3.941 4.13-5.076 6.785C.518 13.075 0 15.473 0 18c0 2.209 1.791 4 4 4h28c2.209 0 4-1.791 4-4 0-2.417-.48-4.713-1.334-6.811z"/><path fill="#CC927A" d="M11.771 10.934c1.546-1.547 1.86-3.74.7-4.9-1.16-1.16-3.353-.846-4.9.7-1.546 1.546-1.86 3.74-.7 4.9 1.16 1.16 3.354.846 4.9-.7Z"/></svg>
|
||||
|
After Width: | Height: | Size: 617 B |
1
public/emoji/1f34b-200d-1f7e9.svg
Normal file
@@ -0,0 +1 @@
|
||||
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 36 36"><path fill="#C6E5B3" d="M7.22 9.12c-2.48 6.42.72 13.66 7.13 16.14s13.65-.72 16.14-7.14l-23.27-9z"/><path fill="#77B255" d="M15.86 24.03c2.18.63 4.43.54 6.46-.16.35-.12.53-.51.38-.85l-3.22-7.3c-.23-.51-.96-.5-1.16.03-.81 2.1-2.3 5.95-2.88 7.45-.14.34.06.73.42.83zM8.52 10.35c-.72 2.27-.64 4.62.08 6.74.12.35.51.53.85.38l7.65-3.38c.51-.23.49-.96-.03-1.16L9.34 9.94a.626.626 0 0 0-.82.41zm19.84 6.95-7.73-2.99c-.52-.2-1.03.33-.8.84l3.38 7.65c.15.34.56.47.89.29 1.96-1.08 3.6-2.77 4.6-4.93.15-.34 0-.73-.34-.86zM9.38 18.86c1.04 1.88 2.64 3.46 4.68 4.47.33.17.74.02.87-.33.58-1.5 2.07-5.35 2.88-7.45.2-.52-.33-1.03-.84-.8l-7.3 3.23c-.34.14-.47.56-.29.88z"/><path fill="#4E932B" d="M30.49 18.12c-2.48 6.42-9.72 9.62-16.14 7.13S4.73 15.53 7.22 9.12l-.85-.33a.72.72 0 0 0-.94.41l-.26.65c-2.8 7.23.62 15.49 7.82 18.38 7.31 2.94 15.59-.67 18.43-8l.33-.85c.15-.38-.04-.8-.42-.94l-.84-.32z"/></svg>
|
||||
|
After Width: | Height: | Size: 946 B |
|
After Width: | Height: | Size: 5.8 KiB |
|
After Width: | Height: | Size: 5.6 KiB |
1
public/emoji/1f3c3-1f3fb-200d-27a1-fe0f.svg
Normal file
|
After Width: | Height: | Size: 5.8 KiB |
|
After Width: | Height: | Size: 5.8 KiB |
|
After Width: | Height: | Size: 5.6 KiB |
1
public/emoji/1f3c3-1f3fc-200d-27a1-fe0f.svg
Normal file
|
After Width: | Height: | Size: 5.8 KiB |
|
After Width: | Height: | Size: 5.8 KiB |
|
After Width: | Height: | Size: 5.6 KiB |
1
public/emoji/1f3c3-1f3fd-200d-27a1-fe0f.svg
Normal file
|
After Width: | Height: | Size: 5.8 KiB |
|
After Width: | Height: | Size: 5.8 KiB |
|
After Width: | Height: | Size: 5.6 KiB |
1
public/emoji/1f3c3-1f3fe-200d-27a1-fe0f.svg
Normal file
|
After Width: | Height: | Size: 5.8 KiB |
|
After Width: | Height: | Size: 5.8 KiB |
|
After Width: | Height: | Size: 5.6 KiB |
1
public/emoji/1f3c3-1f3ff-200d-27a1-fe0f.svg
Normal file
|
After Width: | Height: | Size: 5.8 KiB |
1
public/emoji/1f3c3-200d-2640-fe0f-200d-27a1-fe0f.svg
Normal file
|
After Width: | Height: | Size: 5.8 KiB |
1
public/emoji/1f3c3-200d-2642-fe0f-200d-27a1-fe0f.svg
Normal file
|
After Width: | Height: | Size: 5.6 KiB |
1
public/emoji/1f3c3-200d-27a1-fe0f.svg
Normal file
|
After Width: | Height: | Size: 5.8 KiB |
1
public/emoji/1f426-200d-1f525.svg
Normal file
|
After Width: | Height: | Size: 7.4 KiB |
1
public/emoji/1f468-1f3fb-200d-1f9af-200d-27a1-fe0f.svg
Normal file
@@ -0,0 +1 @@
|
||||
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 36 36"><path fill="#CCD6DD" d="m23.846 19.416-.802.598 8.968 12.026.802-.598z"/><path fill="#DD2E44" d="m32.814 31.444 2.093 2.806a.5.5 0 0 1-.802.598l-2.092-2.806z"/><path fill="#292F33" d="M24.641 21.319a.5.5 0 0 0 .102-.7l-1.793-2.405a.5.5 0 0 0-.7-.102.5.5 0 0 0-.102.7l1.793 2.405a.5.5 0 0 0 .7.102"/><path fill="#292F33" d="m24.24 21.618.802-.598a.5.5 0 0 0 .102-.7.5.5 0 0 0-.7-.102l-.802.598a.5.5 0 0 0 .598.802"/><path fill="#99AAB5" d="M35.402 35.751a.5.5 0 0 0 .102-.7.5.5 0 0 0-.7-.102.5.5 0 0 0-.102.7c.165.22.48.266.7.102"/><path fill="#292F33" d="M15.564 35.056s-.061-.144-.061-.448c0-.303.156-.869.199-.95s.09-.139.194-.11c.079.022.685.326 1.072.341.719.027 1.066-.618 1.066-.618s.399.228.716.413c.318.185.687.462.959.627.232.141.497.208.771.243s.497.023.563.029.621-.061.641.488l-.004.16s-.987.397-2.344.397-1.566-.399-2.444-.399-1.328-.173-1.328-.173"/><path fill="#292F33" d="M17.315 35.926c.058-.052.123-.22.173-.243s.57.089.813.146c.243.058.66.156 1.152.156s1.126-.144 1.519-.243c.393-.098.701-.23.77-.274.07-.043.05-.063.046-.096s-.052-.202-.052-.202-.251.132-.678.237c-.426.104-.851.183-1.584.183s-1.193-.109-1.574-.211c-.475-.128-1.163-.267-1.656-.267-.38 0-.648-.112-.751-.139a.037.037 0 0 0-.046.037v.649c0 .042.035.139.146.162.112.024 1.664.157 1.722.105M5.093 30.914s.072-.142.307-.343.777-.454.868-.473c.091-.02.167-.022.213.078.035.075.199.746.444 1.056.454.575 1.184.418 1.184.418s.087.46.153.828.096.838.148 1.158c.044.273.167.523.322.758.154.236.31.4.35.456s.457.441.045.82L9 35.771s-.96-.502-1.857-1.555-.726-1.477-1.306-2.158-.744-1.144-.744-1.144"/><path fill="#292F33" d="M5.575 32.846c.078.01.252-.05.303-.026s.308.5.424.727.316.615.64.996.856.778 1.192 1.018.642.391.721.416.082-.003.104-.028.122-.174.122-.174-.269-.107-.631-.369a6 6 0 0 1-1.189-1.107 5.7 5.7 0 0 1-.876-1.36c-.214-.452-.562-1.078-.887-1.46-.251-.295-.342-.576-.388-.674a.038.038 0 0 0-.059-.012l-.503.429a.18.18 0 0 0-.029.22c.055.103.978 1.394 1.056 1.404"/><path fill="#F7DECE" d="M14.5 1.384c1.593-.627 4.077.182 4.365 2.043.287 1.848-.239 4.747-1.863 4.572-1.702-.184-3.448-.554-4.138-2.307s.042-3.681 1.636-4.308"/><path fill="#F7DECE" d="M13.316 6.143c-2.318-2.723 3.266-2.458 3.266-2.458 1.057.038.329 1.799.827 2.761.341.665-1.095 1.018-1.095 1.018s-.659-.01-.694.79v.007c-.008.204.013.445.108.769.473 1.601-1.677 2.582-2.149.978-.187-.635-.114-1.193-.02-1.708l.009-.046c.144-.766.322-1.437-.252-2.111"/><path fill="#292F33" d="M12.68 2.026c1.061-1.242 2.58-1.901 5.019-.791.994.452 1.439.285 1.58.484.679.953-.246 2.01-.608 1.799-1.148-.669-2.183-.47-2.447.014s-.021 1.354-.234 1.359c-.578.016-.484-.551-.714-.878-.375-.534-.946-.232-1.071.362-.099.471 0 1.271.77 1.412-.523 1.151-1.56 1.502-1.56 1.502s-.337.132-.912-1.001c-.576-1.134-.877-3.029.177-4.262"/><path fill="#2A6797" d="M17.442 34.203c1.266.109 1.853-.233 1.721-.416-.165-.228-.128-.397-.13-.536-.028-2.441.472-5.991.472-5.991 0-.348-.003-.813-.312-1.562-.778-1.883-3.951-7.69-3.951-7.69a2 2 0 0 0-2.729-.744c-.959.548-1.122 1.405-.744 2.729.715 2.508 2.965 5.602 3.903 7.477-.224 2.121.174 3.853-.035 5.857-.03.288.54.767 1.805.876"/><path fill="#4289C1" d="M6.708 31.931c.364.553.97.942 1.598.838 1.269-1.924 4.955-5.321 4.955-5.321.241-.25.562-.587.86-1.341.748-1.895 2.498-8.277 2.498-8.277a2 2 0 0 0-1.446-2.43c-1.07-.272-1.783.232-2.43 1.446-1.227 2.301-1.757 6.09-2.384 8.09-1.87 1.568-2.383 3.603-4.275 5.151.064.857.26 1.291.624 1.844"/><path fill="#77B255" d="M10.505 20s0 1 2 1h4.898c.415-2 .027-5.004-.006-7.765-.043-3.623-2.298-5.609-3.71-5.155-1.846.594-2.693 2.641-2.932 5.858a97 97 0 0 0-.25 6.062"/><path fill="#F7DECE" d="M15.971 11.693c.781 1.172 2.291 3.808 2.518 3.909 1.205.534 2.549 1.22 3.445 1.314.649.068 1.254.68 1.508.925.316.304.75 1.008.63 1.37-.075.226-.571.488-.742.253-.332-.458-.973-.535-1.49-.889-1.038-.712-3.284-.765-4.556-1.709-.528-.391-1.677-1.309-3.2-3.9.592-.426 1.887-1.273 1.887-1.273"/><path fill="#292F33" d="M21.79 17.018c-.477.152-.847.624-.557 1.114s-.403.185-.512-.045c-.223-.468.178-1.158.646-1.314s.746.142.423.245"/></svg>
|
||||
|
After Width: | Height: | Size: 4.0 KiB |
1
public/emoji/1f468-1f3fb-200d-1f9bc-200d-27a1-fe0f.svg
Normal file
|
After Width: | Height: | Size: 6.2 KiB |
1
public/emoji/1f468-1f3fb-200d-1f9bd-200d-27a1-fe0f.svg
Normal file
|
After Width: | Height: | Size: 5.7 KiB |
1
public/emoji/1f468-1f3fc-200d-1f9af-200d-27a1-fe0f.svg
Normal file
@@ -0,0 +1 @@
|
||||
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 36 36"><path fill="#CCD6DD" d="m23.846 19.416-.802.598 8.968 12.026.802-.598z"/><path fill="#DD2E44" d="m32.814 31.444 2.093 2.806a.5.5 0 0 1-.802.598l-2.092-2.806z"/><path fill="#292F33" d="M24.641 21.319a.5.5 0 0 0 .102-.7l-1.793-2.405a.5.5 0 0 0-.7-.102.5.5 0 0 0-.102.7l1.793 2.405a.5.5 0 0 0 .7.102"/><path fill="#292F33" d="m24.24 21.618.802-.598a.5.5 0 0 0 .102-.7.5.5 0 0 0-.7-.102l-.802.598a.5.5 0 0 0 .598.802"/><path fill="#99AAB5" d="M35.402 35.751a.5.5 0 0 0 .102-.7.5.5 0 0 0-.7-.102.5.5 0 0 0-.102.7c.165.22.48.266.7.102"/><path fill="#292F33" d="M15.564 35.056s-.061-.144-.061-.448c0-.303.156-.869.199-.95s.09-.139.194-.11c.079.022.685.326 1.072.341.719.027 1.066-.618 1.066-.618s.399.228.716.413c.318.185.687.462.959.627.232.141.497.208.771.243s.497.023.563.029.621-.061.641.488l-.004.16s-.987.397-2.344.397-1.566-.399-2.444-.399-1.328-.173-1.328-.173"/><path fill="#292F33" d="M17.315 35.926c.058-.052.123-.22.173-.243s.57.089.813.146c.243.058.66.156 1.152.156s1.126-.144 1.519-.243c.393-.098.701-.23.77-.274.07-.043.05-.063.046-.096s-.052-.202-.052-.202-.251.132-.678.237c-.426.104-.851.183-1.584.183s-1.193-.109-1.574-.211c-.475-.128-1.163-.267-1.656-.267-.38 0-.648-.112-.751-.139a.037.037 0 0 0-.046.037v.649c0 .042.035.139.146.162.112.024 1.664.157 1.722.105M5.093 30.914s.072-.142.307-.343.777-.454.868-.473c.091-.02.167-.022.213.078.035.075.199.746.444 1.056.454.575 1.184.418 1.184.418s.087.46.153.828.096.838.148 1.158c.044.273.167.523.322.758.154.236.31.4.35.456s.457.441.045.82L9 35.771s-.96-.502-1.857-1.555-.726-1.477-1.306-2.158-.744-1.144-.744-1.144"/><path fill="#292F33" d="M5.575 32.846c.078.01.252-.05.303-.026s.308.5.424.727.316.615.64.996.856.778 1.192 1.018.642.391.721.416.082-.003.104-.028.122-.174.122-.174-.269-.107-.631-.369a6 6 0 0 1-1.189-1.107 5.7 5.7 0 0 1-.876-1.36c-.214-.452-.562-1.078-.887-1.46-.251-.295-.342-.576-.388-.674a.038.038 0 0 0-.059-.012l-.503.429a.18.18 0 0 0-.029.22c.055.103.978 1.394 1.056 1.404"/><path fill="#F3D2A2" d="M14.5 1.384c1.593-.627 4.077.182 4.365 2.043.287 1.848-.239 4.747-1.863 4.572-1.702-.184-3.448-.554-4.138-2.307s.042-3.681 1.636-4.308"/><path fill="#F3D2A2" d="M13.316 6.143c-2.318-2.723 3.266-2.458 3.266-2.458 1.057.038.329 1.799.827 2.761.341.665-1.095 1.018-1.095 1.018s-.659-.01-.694.79v.007c-.008.204.013.445.108.769.473 1.601-1.677 2.582-2.149.978-.187-.635-.114-1.193-.02-1.708l.009-.046c.144-.766.322-1.437-.252-2.111"/><path fill="#FFE51E" d="M12.68 2.026c1.061-1.242 2.58-1.901 5.019-.791.994.452 1.439.285 1.58.484.679.953-.246 2.01-.608 1.799-1.148-.669-2.183-.47-2.447.014s-.021 1.354-.234 1.359c-.578.016-.484-.551-.714-.878-.375-.534-.946-.232-1.071.362-.099.471 0 1.271.77 1.412-.523 1.151-1.56 1.502-1.56 1.502s-.337.132-.912-1.001c-.576-1.134-.877-3.029.177-4.262"/><path fill="#2A6797" d="M17.442 34.203c1.266.109 1.853-.233 1.721-.416-.165-.228-.128-.397-.13-.536-.028-2.441.472-5.991.472-5.991 0-.348-.003-.813-.312-1.562-.778-1.883-3.951-7.69-3.951-7.69a2 2 0 0 0-2.729-.744c-.959.548-1.122 1.405-.744 2.729.715 2.508 2.965 5.602 3.903 7.477-.224 2.121.174 3.853-.035 5.857-.03.288.54.767 1.805.876"/><path fill="#4289C1" d="M6.708 31.931c.364.553.97.942 1.598.838 1.269-1.924 4.955-5.321 4.955-5.321.241-.25.562-.587.86-1.341.748-1.895 2.498-8.277 2.498-8.277a2 2 0 0 0-1.446-2.43c-1.07-.272-1.783.232-2.43 1.446-1.227 2.301-1.757 6.09-2.384 8.09-1.87 1.568-2.383 3.603-4.275 5.151.064.857.26 1.291.624 1.844"/><path fill="#77B255" d="M10.505 20s0 1 2 1h4.898c.415-2 .027-5.004-.006-7.765-.043-3.623-2.298-5.609-3.71-5.155-1.846.594-2.693 2.641-2.932 5.858a97 97 0 0 0-.25 6.062"/><path fill="#F3D2A2" d="M15.971 11.693c.781 1.172 2.291 3.808 2.518 3.909 1.205.534 2.549 1.22 3.445 1.314.649.068 1.254.68 1.508.925.316.304.75 1.008.63 1.37-.075.226-.571.488-.742.253-.332-.458-.973-.535-1.49-.889-1.038-.712-3.284-.765-4.556-1.709-.528-.391-1.677-1.309-3.2-3.9.592-.426 1.887-1.273 1.887-1.273"/><path fill="#292F33" d="M21.79 17.018c-.477.152-.847.624-.557 1.114s-.403.185-.512-.045c-.223-.468.178-1.158.646-1.314s.746.142.423.245"/></svg>
|
||||
|
After Width: | Height: | Size: 4.0 KiB |
1
public/emoji/1f468-1f3fc-200d-1f9bc-200d-27a1-fe0f.svg
Normal file
|
After Width: | Height: | Size: 6.2 KiB |
1
public/emoji/1f468-1f3fc-200d-1f9bd-200d-27a1-fe0f.svg
Normal file
|
After Width: | Height: | Size: 5.8 KiB |