Merge commit '02de05dc272856c77fac5c9e1d84cf585ae20c1e' into glitch-soc/merge-upstream
This commit is contained in:
commit
884d7996b1
50 files changed
+653
-96
No files matched your search
@@ -2,11 +2,12 @@ import {
|
||||
apiReblog,
|
||||
apiUnreblog,
|
||||
apiRevokeQuote,
|
||||
apiGetQuotes,
|
||||
} from 'mastodon/api/interactions';
|
||||
import type { StatusVisibility } from 'mastodon/models/status';
|
||||
import { createDataLoadingThunk } from 'mastodon/store/typed_functions';
|
||||
|
||||
import { importFetchedStatus } from './importer';
|
||||
import { importFetchedStatus, importFetchedStatuses } from './importer';
|
||||
|
||||
export const reblog = createDataLoadingThunk(
|
||||
'status/reblog',
|
||||
@@ -53,3 +54,19 @@ export const revokeQuote = createDataLoadingThunk(
|
||||
return discardLoadData;
|
||||
},
|
||||
);
|
||||
|
||||
export const fetchQuotes = createDataLoadingThunk(
|
||||
'status/fetch_quotes',
|
||||
async ({ statusId, next }: { statusId: string; next?: string }) => {
|
||||
const { links, statuses } = await apiGetQuotes(statusId, next);
|
||||
|
||||
return {
|
||||
links,
|
||||
statuses,
|
||||
replace: !next,
|
||||
};
|
||||
},
|
||||
(payload, { dispatch }) => {
|
||||
dispatch(importFetchedStatuses(payload.statuses));
|
||||
},
|
||||
);
|
||||
@@ -30,9 +30,20 @@ import { importFetchedAccounts, importFetchedStatuses } from './importer';
|
||||
import { NOTIFICATIONS_FILTER_SET } from './notifications';
|
||||
import { saveSettings } from './settings';
|
||||
|
||||
function notificationTypeForFilter(type: NotificationType) {
|
||||
if (type === 'quoted_update') return 'update';
|
||||
else return type;
|
||||
}
|
||||
|
||||
function notificationTypeForQuickFilter(type: NotificationType) {
|
||||
if (type === 'quoted_update') return 'update';
|
||||
else if (type === 'quote') return 'mention';
|
||||
else return type;
|
||||
}
|
||||
|
||||
function excludeAllTypesExcept(filter: string) {
|
||||
return allNotificationTypes.filter(
|
||||
(item) => item !== filter && !(item === 'quote' && filter === 'mention'),
|
||||
(item) => notificationTypeForQuickFilter(item) !== filter,
|
||||
);
|
||||
}
|
||||
|
||||
@@ -157,16 +168,17 @@ export const processNewNotificationForGroups = createAppAsyncThunk(
|
||||
|
||||
const showInColumn =
|
||||
activeFilter === 'all'
|
||||
? notificationShows[notification.type] !== false
|
||||
: activeFilter === notification.type ||
|
||||
(activeFilter === 'mention' && notification.type === 'quote');
|
||||
? notificationShows[notificationTypeForFilter(notification.type)] !==
|
||||
false
|
||||
: activeFilter === notificationTypeForQuickFilter(notification.type);
|
||||
|
||||
if (!showInColumn) return;
|
||||
|
||||
if (
|
||||
(notification.type === 'mention' ||
|
||||
notification.type === 'quote' ||
|
||||
notification.type === 'update' ||
|
||||
notification.type === 'quote') &&
|
||||
notification.type === 'quoted_update') &&
|
||||
notification.status?.filtered
|
||||
) {
|
||||
const filters = notification.status.filtered.filter((result) =>
|
||||
|
||||
@@ -31,7 +31,7 @@ export function updateNotifications(notification, intlMessages, intlLocale) {
|
||||
|
||||
let filtered = false;
|
||||
|
||||
if (['mention', 'status', 'quote'].includes(notification.type) && notification.status.filtered) {
|
||||
if (['mention', 'quote', 'status'].includes(notification.type) && notification.status.filtered) {
|
||||
const filters = notification.status.filtered.filter(result => result.filter.context.includes('notifications'));
|
||||
|
||||
if (filters.some(result => result.filter.filter_action === 'hide')) {
|
||||
|
||||
@@ -3,7 +3,7 @@ import { browserHistory } from 'mastodon/components/router';
|
||||
import api from '../api';
|
||||
|
||||
import { ensureComposeIsVisible, setComposeToStatus } from './compose';
|
||||
import { importFetchedStatus, importFetchedStatuses, importFetchedAccount } from './importer';
|
||||
import { importFetchedStatus, importFetchedAccount } from './importer';
|
||||
import { fetchContext } from './statuses_typed';
|
||||
import { deleteFromTimelines } from './timelines';
|
||||
|
||||
@@ -48,7 +48,18 @@ export function fetchStatusRequest(id, skipLoading) {
|
||||
};
|
||||
}
|
||||
|
||||
export function fetchStatus(id, forceFetch = false, alsoFetchContext = true) {
|
||||
/**
|
||||
* @param {string} id
|
||||
* @param {Object} [options]
|
||||
* @param {boolean} [options.forceFetch]
|
||||
* @param {boolean} [options.alsoFetchContext]
|
||||
* @param {string | null | undefined} [options.parentQuotePostId]
|
||||
*/
|
||||
export function fetchStatus(id, {
|
||||
forceFetch = false,
|
||||
alsoFetchContext = true,
|
||||
parentQuotePostId,
|
||||
} = {}) {
|
||||
return (dispatch, getState) => {
|
||||
const skipLoading = !forceFetch && getState().getIn(['statuses', id], null) !== null;
|
||||
|
||||
@@ -66,7 +77,7 @@ export function fetchStatus(id, forceFetch = false, alsoFetchContext = true) {
|
||||
dispatch(importFetchedStatus(response.data));
|
||||
dispatch(fetchStatusSuccess(skipLoading));
|
||||
}).catch(error => {
|
||||
dispatch(fetchStatusFail(id, error, skipLoading));
|
||||
dispatch(fetchStatusFail(id, error, skipLoading, parentQuotePostId));
|
||||
});
|
||||
};
|
||||
}
|
||||
@@ -78,11 +89,12 @@ export function fetchStatusSuccess(skipLoading) {
|
||||
};
|
||||
}
|
||||
|
||||
export function fetchStatusFail(id, error, skipLoading) {
|
||||
export function fetchStatusFail(id, error, skipLoading, parentQuotePostId) {
|
||||
return {
|
||||
type: STATUS_FETCH_FAIL,
|
||||
id,
|
||||
error,
|
||||
parentQuotePostId,
|
||||
skipLoading,
|
||||
skipAlert: true,
|
||||
};
|
||||
|
||||
@@ -1,15 +1,28 @@
|
||||
import { apiRequestPost } from 'mastodon/api';
|
||||
import type { Status, StatusVisibility } from 'mastodon/models/status';
|
||||
import api, { apiRequestPost, getLinks } from 'mastodon/api';
|
||||
import type { ApiStatusJSON } from 'mastodon/api_types/statuses';
|
||||
import type { StatusVisibility } from 'mastodon/models/status';
|
||||
|
||||
export const apiReblog = (statusId: string, visibility: StatusVisibility) =>
|
||||
apiRequestPost<{ reblog: Status }>(`v1/statuses/${statusId}/reblog`, {
|
||||
apiRequestPost<{ reblog: ApiStatusJSON }>(`v1/statuses/${statusId}/reblog`, {
|
||||
visibility,
|
||||
});
|
||||
|
||||
export const apiUnreblog = (statusId: string) =>
|
||||
apiRequestPost<Status>(`v1/statuses/${statusId}/unreblog`);
|
||||
apiRequestPost<ApiStatusJSON>(`v1/statuses/${statusId}/unreblog`);
|
||||
|
||||
export const apiRevokeQuote = (quotedStatusId: string, statusId: string) =>
|
||||
apiRequestPost<Status>(
|
||||
apiRequestPost<ApiStatusJSON>(
|
||||
`v1/statuses/${quotedStatusId}/quotes/${statusId}/revoke`,
|
||||
);
|
||||
|
||||
export const apiGetQuotes = async (statusId: string, url?: string) => {
|
||||
const response = await api().request<ApiStatusJSON[]>({
|
||||
method: 'GET',
|
||||
url: url ?? `/api/v1/statuses/${statusId}/quotes`,
|
||||
});
|
||||
|
||||
return {
|
||||
statuses: response.data,
|
||||
links: getLinks(response),
|
||||
};
|
||||
};
|
||||
@@ -7,7 +7,7 @@ import type { ApiReportJSON } from './reports';
|
||||
import type { ApiStatusJSON } from './statuses';
|
||||
|
||||
// See app/model/notification.rb
|
||||
export const allNotificationTypes = [
|
||||
export const allNotificationTypes: NotificationType[] = [
|
||||
'follow',
|
||||
'follow_request',
|
||||
'favourite',
|
||||
|
||||
@@ -46,6 +46,14 @@ const messages = defineMessages({
|
||||
id: 'status.cannot_quote',
|
||||
defaultMessage: 'Author has disabled quoting on this post',
|
||||
},
|
||||
quote_followers_only: {
|
||||
id: 'status.quote_followers_only',
|
||||
defaultMessage: 'Only followers can quote this post',
|
||||
},
|
||||
quote_manual_review: {
|
||||
id: 'status.quote_manual_review',
|
||||
defaultMessage: 'Author will manually review',
|
||||
},
|
||||
quote_private: {
|
||||
id: 'status.quote_private',
|
||||
defaultMessage: 'Private posts cannot be quoted',
|
||||
@@ -63,6 +71,10 @@ const messages = defineMessages({
|
||||
id: 'status.cannot_reblog',
|
||||
defaultMessage: 'This post cannot be boosted',
|
||||
},
|
||||
request_quote: {
|
||||
id: 'status.request_quote',
|
||||
defaultMessage: 'Request to quote',
|
||||
},
|
||||
});
|
||||
|
||||
interface ReblogButtonProps {
|
||||
@@ -79,13 +91,21 @@ export const StatusReblogButton: FC<ReblogButtonProps> = ({
|
||||
const statusState = useAppSelector((state) =>
|
||||
selectStatusState(state, status),
|
||||
);
|
||||
const { isLoggedIn, isReblogged, isReblogAllowed, isQuoteAllowed } =
|
||||
statusState;
|
||||
const {
|
||||
isLoggedIn,
|
||||
isReblogged,
|
||||
isReblogAllowed,
|
||||
isQuoteAutomaticallyAccepted,
|
||||
isQuoteManuallyAccepted,
|
||||
} = statusState;
|
||||
const { iconComponent } = useMemo(
|
||||
() => reblogIconText(statusState),
|
||||
[statusState],
|
||||
);
|
||||
const disabled = !isQuoteAllowed && !isReblogAllowed;
|
||||
const disabled =
|
||||
!isQuoteAutomaticallyAccepted &&
|
||||
!isQuoteManuallyAccepted &&
|
||||
!isReblogAllowed;
|
||||
|
||||
const dispatch = useAppDispatch();
|
||||
const statusId = status.get('id') as string;
|
||||
@@ -320,9 +340,15 @@ const selectStatusState = createAppSelector(
|
||||
status.get('visibility') === 'private',
|
||||
isReblogged: !!status.get('reblogged'),
|
||||
isReblogAllowed: isPublic || isMineAndPrivate,
|
||||
isQuoteAllowed:
|
||||
isQuoteAutomaticallyAccepted:
|
||||
status.getIn(['quote_approval', 'current_user']) === 'automatic' &&
|
||||
(isPublic || isMineAndPrivate),
|
||||
isQuoteManuallyAccepted:
|
||||
status.getIn(['quote_approval', 'current_user']) === 'manual' &&
|
||||
(isPublic || isMineAndPrivate),
|
||||
isQuoteFollowersOnly:
|
||||
status.getIn(['quote_approval', 'automatic', 0]) === 'followers' ||
|
||||
status.getIn(['quote_approval', 'manual', 0]) === 'followers',
|
||||
};
|
||||
},
|
||||
);
|
||||
@@ -364,7 +390,9 @@ function reblogIconText({
|
||||
|
||||
function quoteIconText({
|
||||
isMine,
|
||||
isQuoteAllowed,
|
||||
isQuoteAutomaticallyAccepted,
|
||||
isQuoteManuallyAccepted,
|
||||
isQuoteFollowersOnly,
|
||||
isPublic,
|
||||
}: StatusState): IconText {
|
||||
const iconText: IconText = {
|
||||
@@ -372,12 +400,22 @@ function quoteIconText({
|
||||
iconComponent: FormatQuote,
|
||||
};
|
||||
|
||||
if (!isQuoteAllowed || (!isPublic && !isMine)) {
|
||||
iconText.meta = !isQuoteAllowed
|
||||
? messages.quote_cannot
|
||||
: messages.quote_private;
|
||||
iconText.iconComponent = FormatQuoteOff;
|
||||
if (!isPublic && !isMine) {
|
||||
iconText.disabled = true;
|
||||
iconText.iconComponent = FormatQuoteOff;
|
||||
iconText.meta = messages.quote_private;
|
||||
} else if (isQuoteAutomaticallyAccepted) {
|
||||
iconText.title = messages.quote;
|
||||
} else if (isQuoteManuallyAccepted) {
|
||||
iconText.title = messages.request_quote;
|
||||
iconText.meta = messages.quote_manual_review;
|
||||
} else {
|
||||
iconText.disabled = true;
|
||||
iconText.iconComponent = FormatQuoteOff;
|
||||
iconText.meta = isQuoteFollowersOnly
|
||||
? messages.quote_followers_only
|
||||
: messages.quote_cannot;
|
||||
}
|
||||
|
||||
return iconText;
|
||||
}
|
||||
@@ -32,9 +32,7 @@ const QuoteWrapper: React.FC<{
|
||||
);
|
||||
};
|
||||
|
||||
const NestedQuoteLink: React.FC<{
|
||||
status: Status;
|
||||
}> = ({ status }) => {
|
||||
const NestedQuoteLink: React.FC<{ status: Status }> = ({ status }) => {
|
||||
const accountId = status.get('account') as string;
|
||||
const account = useAppSelector((state) =>
|
||||
accountId ? state.accounts.get(accountId) : undefined,
|
||||
@@ -66,6 +64,7 @@ type GetStatusSelector = (
|
||||
interface QuotedStatusProps {
|
||||
quote: QuoteMap;
|
||||
contextType?: string;
|
||||
parentQuotePostId?: string | null;
|
||||
variant?: 'full' | 'link';
|
||||
nestingLevel?: number;
|
||||
onQuoteCancel?: () => void; // Used for composer.
|
||||
@@ -74,23 +73,35 @@ interface QuotedStatusProps {
|
||||
export const QuotedStatus: React.FC<QuotedStatusProps> = ({
|
||||
quote,
|
||||
contextType,
|
||||
parentQuotePostId,
|
||||
nestingLevel = 1,
|
||||
variant = 'full',
|
||||
onQuoteCancel,
|
||||
}) => {
|
||||
const dispatch = useAppDispatch();
|
||||
const quoteState = useAppSelector((state) =>
|
||||
parentQuotePostId
|
||||
? state.statuses.getIn([parentQuotePostId, 'quote', 'state'])
|
||||
: quote.get('state'),
|
||||
);
|
||||
|
||||
const quotedStatusId = quote.get('quoted_status');
|
||||
const quoteState = quote.get('state');
|
||||
const status = useAppSelector((state) =>
|
||||
quotedStatusId ? state.statuses.get(quotedStatusId) : undefined,
|
||||
);
|
||||
const isQuoteLoaded = !!status && !status.get('isLoading');
|
||||
|
||||
const shouldLoadQuote = !status?.get('isLoading') && quoteState !== 'deleted';
|
||||
|
||||
useEffect(() => {
|
||||
if (!isQuoteLoaded && quotedStatusId) {
|
||||
dispatch(fetchStatus(quotedStatusId));
|
||||
if (shouldLoadQuote && quotedStatusId) {
|
||||
dispatch(
|
||||
fetchStatus(quotedStatusId, {
|
||||
parentQuotePostId,
|
||||
alsoFetchContext: false,
|
||||
}),
|
||||
);
|
||||
}
|
||||
}, [isQuoteLoaded, quotedStatusId, dispatch]);
|
||||
}, [shouldLoadQuote, quotedStatusId, parentQuotePostId, dispatch]);
|
||||
|
||||
// In order to find out whether the quoted post should be completely hidden
|
||||
// due to a matching filter, we run it through the selector used by `status_container`.
|
||||
@@ -175,6 +186,7 @@ export const QuotedStatus: React.FC<QuotedStatusProps> = ({
|
||||
{canRenderChildQuote && (
|
||||
<QuotedStatus
|
||||
quote={childQuote}
|
||||
parentQuotePostId={quotedStatusId}
|
||||
contextType={contextType}
|
||||
variant={
|
||||
nestingLevel === MAX_QUOTE_POSTS_NESTING_LEVEL ? 'link' : 'full'
|
||||
@@ -210,7 +222,11 @@ export const StatusQuoteManager = (props: StatusQuoteManagerProps) => {
|
||||
if (quote) {
|
||||
return (
|
||||
<StatusContainer {...props}>
|
||||
<QuotedStatus quote={quote} contextType={props.contextType} />
|
||||
<QuotedStatus
|
||||
quote={quote}
|
||||
parentQuotePostId={status?.get('id') as string}
|
||||
contextType={props.contextType}
|
||||
/>
|
||||
</StatusContainer>
|
||||
);
|
||||
}
|
||||
|
||||
@@ -0,0 +1,113 @@
|
||||
import { useCallback, useEffect } from 'react';
|
||||
|
||||
import { defineMessages, FormattedMessage, useIntl } from 'react-intl';
|
||||
|
||||
import { Helmet } from 'react-helmet';
|
||||
|
||||
import { List as ImmutableList } from 'immutable';
|
||||
|
||||
import RefreshIcon from '@/material-icons/400-24px/refresh.svg?react';
|
||||
import { fetchQuotes } from 'mastodon/actions/interactions_typed';
|
||||
import { ColumnHeader } from 'mastodon/components/column_header';
|
||||
import { Icon } from 'mastodon/components/icon';
|
||||
import { LoadingIndicator } from 'mastodon/components/loading_indicator';
|
||||
import StatusList from 'mastodon/components/status_list';
|
||||
import { useAppDispatch, useAppSelector } from 'mastodon/store';
|
||||
|
||||
import Column from '../ui/components/column';
|
||||
|
||||
const messages = defineMessages({
|
||||
refresh: { id: 'refresh', defaultMessage: 'Refresh' },
|
||||
});
|
||||
|
||||
const emptyList = ImmutableList();
|
||||
|
||||
export const Quotes: React.FC<{
|
||||
multiColumn?: boolean;
|
||||
params?: { statusId: string };
|
||||
}> = ({ multiColumn, params }) => {
|
||||
const intl = useIntl();
|
||||
const dispatch = useAppDispatch();
|
||||
|
||||
const statusId = params?.statusId;
|
||||
|
||||
const isCorrectStatusId: boolean = useAppSelector(
|
||||
(state) => state.status_lists.getIn(['quotes', 'statusId']) === statusId,
|
||||
);
|
||||
const statusIds = useAppSelector((state) =>
|
||||
state.status_lists.getIn(['quotes', 'items'], emptyList),
|
||||
);
|
||||
const nextUrl = useAppSelector(
|
||||
(state) =>
|
||||
state.status_lists.getIn(['quotes', 'next']) as string | undefined,
|
||||
);
|
||||
const isLoading = useAppSelector((state) =>
|
||||
state.status_lists.getIn(['quotes', 'isLoading'], true),
|
||||
);
|
||||
const hasMore = !!nextUrl;
|
||||
|
||||
useEffect(() => {
|
||||
if (statusId) void dispatch(fetchQuotes({ statusId }));
|
||||
}, [dispatch, statusId]);
|
||||
|
||||
const handleLoadMore = useCallback(() => {
|
||||
if (statusId && isCorrectStatusId && nextUrl)
|
||||
void dispatch(fetchQuotes({ statusId, next: nextUrl }));
|
||||
}, [dispatch, statusId, isCorrectStatusId, nextUrl]);
|
||||
|
||||
const handleRefresh = useCallback(() => {
|
||||
if (statusId) void dispatch(fetchQuotes({ statusId }));
|
||||
}, [dispatch, statusId]);
|
||||
|
||||
if (!statusIds || !isCorrectStatusId) {
|
||||
return (
|
||||
<Column>
|
||||
<LoadingIndicator />
|
||||
</Column>
|
||||
);
|
||||
}
|
||||
|
||||
const emptyMessage = (
|
||||
<FormattedMessage
|
||||
id='status.quotes.empty'
|
||||
defaultMessage='No one has quoted this post yet. When someone does, it will show up here.'
|
||||
/>
|
||||
);
|
||||
|
||||
return (
|
||||
<Column bindToDocument={!multiColumn}>
|
||||
<ColumnHeader
|
||||
showBackButton
|
||||
multiColumn={multiColumn}
|
||||
extraButton={
|
||||
<button
|
||||
type='button'
|
||||
className='column-header__button'
|
||||
title={intl.formatMessage(messages.refresh)}
|
||||
aria-label={intl.formatMessage(messages.refresh)}
|
||||
onClick={handleRefresh}
|
||||
>
|
||||
<Icon id='refresh' icon={RefreshIcon} />
|
||||
</button>
|
||||
}
|
||||
/>
|
||||
|
||||
<StatusList
|
||||
scrollKey='quotes_timeline'
|
||||
statusIds={statusIds}
|
||||
onLoadMore={handleLoadMore}
|
||||
hasMore={hasMore}
|
||||
isLoading={isLoading}
|
||||
emptyMessage={emptyMessage}
|
||||
bindToDocument={!multiColumn}
|
||||
/>
|
||||
|
||||
<Helmet>
|
||||
<meta name='robots' content='noindex' />
|
||||
</Helmet>
|
||||
</Column>
|
||||
);
|
||||
};
|
||||
|
||||
// eslint-disable-next-line import/no-default-export
|
||||
export default Quotes;
|
||||
@@ -32,7 +32,7 @@ const Embed: React.FC<{ id: string }> = ({ id }) => {
|
||||
const dispatchRenderSignal = useRenderSignal();
|
||||
|
||||
useEffect(() => {
|
||||
dispatch(fetchStatus(id, false, false));
|
||||
dispatch(fetchStatus(id, { alsoFetchContext: false }));
|
||||
}, [dispatch, id]);
|
||||
|
||||
const handleToggleHidden = useCallback(() => {
|
||||
|
||||
@@ -31,6 +31,7 @@ import { VisibilityIcon } from 'mastodon/components/visibility_icon';
|
||||
import { Audio } from 'mastodon/features/audio';
|
||||
import scheduleIdleTask from 'mastodon/features/ui/util/schedule_idle_task';
|
||||
import { Video } from 'mastodon/features/video';
|
||||
import { me } from 'mastodon/initial_state';
|
||||
|
||||
import Card from './card';
|
||||
|
||||
@@ -282,6 +283,22 @@ export const DetailedStatus: React.FC<{
|
||||
|
||||
if (['private', 'direct'].includes(status.get('visibility') as string)) {
|
||||
quotesLink = '';
|
||||
} else if (status.getIn(['account', 'id']) === me) {
|
||||
quotesLink = (
|
||||
<Link
|
||||
to={`/@${status.getIn(['account', 'acct'])}/${status.get('id')}/quotes`}
|
||||
className='detailed-status__link'
|
||||
>
|
||||
<span className='detailed-status__quotes'>
|
||||
<AnimatedNumber value={status.get('quotes_count')} />
|
||||
</span>
|
||||
<FormattedMessage
|
||||
id='status.quotes'
|
||||
defaultMessage='{count, plural, one {quote} other {quotes}}'
|
||||
values={{ count: status.get('quotes_count') }}
|
||||
/>
|
||||
</Link>
|
||||
);
|
||||
} else {
|
||||
quotesLink = (
|
||||
<span className='detailed-status__link'>
|
||||
@@ -399,7 +416,10 @@ export const DetailedStatus: React.FC<{
|
||||
{hashtagBar}
|
||||
|
||||
{status.get('quote') && (
|
||||
<QuotedStatus quote={status.get('quote')} />
|
||||
<QuotedStatus
|
||||
quote={status.get('quote')}
|
||||
parentQuotePostId={status.get('id')}
|
||||
/>
|
||||
)}
|
||||
</>
|
||||
)}
|
||||
|
||||
@@ -38,7 +38,7 @@ class FilterModal extends ImmutablePureComponent {
|
||||
|
||||
handleSuccess = () => {
|
||||
const { dispatch, statusId } = this.props;
|
||||
dispatch(fetchStatus(statusId, true));
|
||||
dispatch(fetchStatus(statusId, {forceFetch: true}));
|
||||
this.setState({ isSubmitting: false, isSubmitted: true, step: 'submitted' });
|
||||
};
|
||||
|
||||
|
||||
@@ -75,6 +75,7 @@ import {
|
||||
PrivacyPolicy,
|
||||
TermsOfService,
|
||||
AccountFeatured,
|
||||
Quotes,
|
||||
} from './util/async-components';
|
||||
import { ColumnsContextProvider } from './util/columns_context';
|
||||
import { focusColumn, getFocusedItemIndex, focusItemSibling } from './util/focusUtils';
|
||||
@@ -209,6 +210,7 @@ class SwitchingColumnsArea extends PureComponent {
|
||||
<WrappedRoute path='/@:acct/:statusId' exact component={Status} content={children} />
|
||||
<WrappedRoute path='/@:acct/:statusId/reblogs' component={Reblogs} content={children} />
|
||||
<WrappedRoute path='/@:acct/:statusId/favourites' component={Favourites} content={children} />
|
||||
<WrappedRoute path='/@:acct/:statusId/quotes' component={Quotes} content={children} />
|
||||
|
||||
{/* Legacy routes, cannot be easily factored with other routes because they share a param name */}
|
||||
<WrappedRoute path='/timelines/tag/:id' component={HashtagTimeline} content={children} />
|
||||
|
||||
@@ -86,6 +86,10 @@ export function Favourites () {
|
||||
return import('../../favourites');
|
||||
}
|
||||
|
||||
export function Quotes () {
|
||||
return import('../../quotes');
|
||||
}
|
||||
|
||||
export function FollowRequests () {
|
||||
return import('../../follow_requests');
|
||||
}
|
||||
|
||||
@@ -620,6 +620,7 @@
|
||||
"notification.moderation_warning.action_suspend": "Din konto er suspenderet.",
|
||||
"notification.own_poll": "Din afstemning er afsluttet",
|
||||
"notification.poll": "En afstemning, hvori du har stemt, er slut",
|
||||
"notification.quoted_update": "{name} redigerede et indlæg, man har citeret",
|
||||
"notification.reblog": "{name} fremhævede dit indlæg",
|
||||
"notification.reblog.name_and_others_with_link": "{name} og <a>{count, plural, one {# anden} other {# andre}}</a> fremhævede dit indlæg",
|
||||
"notification.relationships_severance_event": "Mistede forbindelser med {name}",
|
||||
@@ -900,6 +901,7 @@
|
||||
"status.quote_policy_change": "Ændr hvem der kan citere",
|
||||
"status.quote_post_author": "Citerede et indlæg fra @{name}",
|
||||
"status.quote_private": "Private indlæg kan ikke citeres",
|
||||
"status.quotes": "{count, plural, one {citat} other {citater}}",
|
||||
"status.read_more": "Læs mere",
|
||||
"status.reblog": "Fremhæv",
|
||||
"status.reblog_private": "Fremhæv med oprindelig synlighed",
|
||||
@@ -978,12 +980,15 @@
|
||||
"video.volume_up": "Lydstyrke op",
|
||||
"visibility_modal.button_title": "Indstil synlighed",
|
||||
"visibility_modal.header": "Synlighed og interaktion",
|
||||
"visibility_modal.helper.direct_quoting": "Private omtaler forfattet på Mastodon kan ikke citeres af andre.",
|
||||
"visibility_modal.helper.privacy_editing": "Publicerede indlægs synlighed kan ikke ændres.",
|
||||
"visibility_modal.helper.private_quoting": "Kun-følger indlæg forfattet på Mastodon kan ikke citeres af andre.",
|
||||
"visibility_modal.helper.unlisted_quoting": "Når folk citerer dig, vil deres indlæg også blive skjult fra trendtidslinjer.",
|
||||
"visibility_modal.instructions": "Styr, hvem der kan interagere med dette indlæg. Globale indstillinger findes under <link>Præferencer > Andet</link>.",
|
||||
"visibility_modal.privacy_label": "Fortrolighed",
|
||||
"visibility_modal.quote_followers": "Kun følgere",
|
||||
"visibility_modal.quote_label": "Ændr hvem der kan citere",
|
||||
"visibility_modal.quote_nobody": "Kun en selv",
|
||||
"visibility_modal.quote_public": "Alle",
|
||||
"visibility_modal.save": "Gem"
|
||||
}
|
||||
@@ -988,7 +988,7 @@
|
||||
"visibility_modal.privacy_label": "Datenschutz",
|
||||
"visibility_modal.quote_followers": "Nur Follower",
|
||||
"visibility_modal.quote_label": "Ändern, wer zitieren darf",
|
||||
"visibility_modal.quote_nobody": "Nur ich",
|
||||
"visibility_modal.quote_nobody": "Nur von mir",
|
||||
"visibility_modal.quote_public": "Alle",
|
||||
"visibility_modal.save": "Speichern"
|
||||
}
|
||||
@@ -898,10 +898,13 @@
|
||||
"status.quote_error.pending_approval": "Post pending",
|
||||
"status.quote_error.pending_approval_popout.body": "Quotes shared across the Fediverse may take time to display, as different servers have different protocols.",
|
||||
"status.quote_error.pending_approval_popout.title": "Pending quote? Remain calm",
|
||||
"status.quote_followers_only": "Only followers can quote this post",
|
||||
"status.quote_manual_review": "Author will manually review",
|
||||
"status.quote_policy_change": "Change who can quote",
|
||||
"status.quote_post_author": "Quoted a post by @{name}",
|
||||
"status.quote_private": "Private posts cannot be quoted",
|
||||
"status.quotes": "{count, plural, one {quote} other {quotes}}",
|
||||
"status.quotes.empty": "No one has quoted this post yet. When someone does, it will show up here.",
|
||||
"status.read_more": "Read more",
|
||||
"status.reblog": "Boost",
|
||||
"status.reblog_private": "Boost with original visibility",
|
||||
@@ -916,6 +919,7 @@
|
||||
"status.reply": "Reply",
|
||||
"status.replyAll": "Reply to thread",
|
||||
"status.report": "Report @{name}",
|
||||
"status.request_quote": "Request to quote",
|
||||
"status.revoke_quote": "Remove my post from @{name}’s post",
|
||||
"status.sensitive_warning": "Sensitive content",
|
||||
"status.share": "Share",
|
||||
|
||||
@@ -483,6 +483,7 @@
|
||||
"keyboard_shortcuts.home": "Ava kodu ajajoon",
|
||||
"keyboard_shortcuts.hotkey": "Kiirklahv",
|
||||
"keyboard_shortcuts.legend": "Kuva see legend",
|
||||
"keyboard_shortcuts.load_more": "Fookus „Laadi veel“ nupule",
|
||||
"keyboard_shortcuts.local": "Ava kohalik ajajoon",
|
||||
"keyboard_shortcuts.mention": "Maini autorit",
|
||||
"keyboard_shortcuts.muted": "Ava vaigistatud kasutajate loetelu",
|
||||
@@ -619,6 +620,7 @@
|
||||
"notification.moderation_warning.action_suspend": "Su konto on peatatud.",
|
||||
"notification.own_poll": "Su küsitlus on lõppenud",
|
||||
"notification.poll": "Hääletus, millel osalesid, on lõppenud",
|
||||
"notification.quoted_update": "{name} on muutnud sinu poolt tsiteeritud postitust",
|
||||
"notification.reblog": "{name} jagas edasi postitust",
|
||||
"notification.reblog.name_and_others_with_link": "{name} ja <a>{count, plural, one {# veel} other {# teist}}</a> jagas su postitust",
|
||||
"notification.relationships_severance_event": "Kadunud ühendus kasutajaga {name}",
|
||||
@@ -879,7 +881,7 @@
|
||||
"status.filter": "Filtreeri seda postitust",
|
||||
"status.history.created": "{name} lõi {date}",
|
||||
"status.history.edited": "{name} muutis {date}",
|
||||
"status.load_more": "Lae rohkem",
|
||||
"status.load_more": "Laadi veel",
|
||||
"status.media.open": "Avamiseks klõpsa",
|
||||
"status.media.show": "Näitamiseks klõpsa",
|
||||
"status.media_hidden": "Meedia peidetud",
|
||||
@@ -899,6 +901,7 @@
|
||||
"status.quote_policy_change": "Muuda neid, kes võivad tsiteerida",
|
||||
"status.quote_post_author": "Tsiteeris kasutaja @{name} postitust",
|
||||
"status.quote_private": "Otsepostituste tsiteerimine pole võimalik",
|
||||
"status.quotes": "{count, plural, one {# tsiteerimine} other {# tsiteerimist}}",
|
||||
"status.read_more": "Loe veel",
|
||||
"status.reblog": "Jaga",
|
||||
"status.reblog_private": "Jaga algse nähtavusega",
|
||||
@@ -947,12 +950,12 @@
|
||||
"units.short.billion": "{count} mld",
|
||||
"units.short.million": "{count} mln",
|
||||
"units.short.thousand": "{count} tuh",
|
||||
"upload_area.title": "Lohista & aseta üleslaadimiseks",
|
||||
"upload_button.label": "Lisa meedia (JPEG, PNG, GIF, WebM, MP4, MOV)",
|
||||
"upload_error.limit": "Faili üleslaadimise limiit ületatud.",
|
||||
"upload_area.title": "Lohista ja aseta üleslaadimiseks",
|
||||
"upload_button.label": "Lisa pilte, üks video- või helifail",
|
||||
"upload_error.limit": "Faili üleslaadimise piir ületatud.",
|
||||
"upload_error.poll": "Küsitlustes pole faili üleslaadimine lubatud.",
|
||||
"upload_error.quote": "Tsiteerimisel pole faili üleslaadimine lubatud.",
|
||||
"upload_form.drag_and_drop.instructions": "Vajuta tühikut või enterit, et tõsta manus. Lohistamise ajal kasuta nooleklahve, et manust liigutada teatud suunas. Vajuta tühikut või enterit uuesti, et paigutada manus oma uuele kohale, või escape tühistamiseks.",
|
||||
"upload_form.drag_and_drop.instructions": "Manuse valimiseks vajuta tühikut või sisestusklahvi. Lohistamise ajal kasuta nooleklahve, et manust liigutada teatud suunas. Vajuta tühikut või enterit uuesti, et paigutada manus oma uuele kohale, või escape tühistamiseks.",
|
||||
"upload_form.drag_and_drop.on_drag_cancel": "Lohistamine tühistati. Manus {item} on asetatud.",
|
||||
"upload_form.drag_and_drop.on_drag_end": "Manus {item} on asetatud.",
|
||||
"upload_form.drag_and_drop.on_drag_over": "Manus {item} on liigutatud.",
|
||||
@@ -962,7 +965,7 @@
|
||||
"upload_progress.processing": "Töötlen…",
|
||||
"username.taken": "See kasutajanimi on juba kasutusel. Proovi teist",
|
||||
"video.close": "Sulge video",
|
||||
"video.download": "Faili allalaadimine",
|
||||
"video.download": "Laadi fail alla",
|
||||
"video.exit_fullscreen": "Välju täisekraanist",
|
||||
"video.expand": "Suurenda video",
|
||||
"video.fullscreen": "Täisekraan",
|
||||
@@ -977,11 +980,15 @@
|
||||
"video.volume_up": "Heli valjemaks",
|
||||
"visibility_modal.button_title": "Muuda nähtavust",
|
||||
"visibility_modal.header": "Nähtavus ja kasutus",
|
||||
"visibility_modal.helper.direct_quoting": "Ainult mainituile mõeldud Mastodoni postitusi ei saa teiste poolt tsiteerida.",
|
||||
"visibility_modal.helper.privacy_editing": "Avaldatud postitused ei saa muuta oma nähtavust.",
|
||||
"visibility_modal.helper.private_quoting": "Ainult jälgijatele mõeldud Mastodoni postitusi ei saa teiste poolt tsiteerida.",
|
||||
"visibility_modal.helper.unlisted_quoting": "Kui teised kasutajad sind tsiteerivad, siis nende postitused peidetakse ajajoonelt, mis näitavad populaarsust koguvaid postitusi.",
|
||||
"visibility_modal.instructions": "Halda seda, kes võivad antud postitust kasutada. Üldised seadistused leiduvad siin: <link>Eelistused > Muu</link>.",
|
||||
"visibility_modal.privacy_label": "Privaatsus",
|
||||
"visibility_modal.quote_followers": "Ainult jälgijad",
|
||||
"visibility_modal.quote_label": "Muuda seda, kes võivad tsiteerida",
|
||||
"visibility_modal.quote_public": "Kõik"
|
||||
"visibility_modal.quote_nobody": "Ainult mina",
|
||||
"visibility_modal.quote_public": "Kõik",
|
||||
"visibility_modal.save": "Salvesta"
|
||||
}
|
||||
@@ -620,6 +620,7 @@
|
||||
"notification.moderation_warning.action_suspend": "Konta tín er ógildað.",
|
||||
"notification.own_poll": "Tín atkvøðugreiðsla er endað",
|
||||
"notification.poll": "Ein atkvøðugreiðsla, har tú atkvøddi, er endað",
|
||||
"notification.quoted_update": "{name} rættaði ein post, sum tú hevur siterað",
|
||||
"notification.reblog": "{name} lyfti tín post",
|
||||
"notification.reblog.name_and_others_with_link": "{name} og <a>{count, plural, one {# annar/onnur} other {# onnur}}</a> framhevjaðu tín post",
|
||||
"notification.relationships_severance_event": "Mist sambond við {name}",
|
||||
@@ -900,6 +901,7 @@
|
||||
"status.quote_policy_change": "Broyt hvør kann sitera",
|
||||
"status.quote_post_author": "Siteraði ein post hjá @{name}",
|
||||
"status.quote_private": "Privatir postar kunnu ikki siterast",
|
||||
"status.quotes": "{count, plural, one {sitat} other {sitat}}",
|
||||
"status.read_more": "Les meira",
|
||||
"status.reblog": "Stimbra",
|
||||
"status.reblog_private": "Stimbra við upprunasýni",
|
||||
@@ -978,12 +980,15 @@
|
||||
"video.volume_up": "Øk um ljóðstyrki",
|
||||
"visibility_modal.button_title": "Set sýni",
|
||||
"visibility_modal.header": "Sýni og samvirkni",
|
||||
"visibility_modal.helper.direct_quoting": "Privatar umrøður, sum eru skrivaðar á Mastodon, kunnu ikki siterast av øðrum.",
|
||||
"visibility_modal.helper.privacy_editing": "Útgivnir postar kunnnu ikki broyta sýni.",
|
||||
"visibility_modal.helper.private_quoting": "Postar, sum einans eru fyri fylgjarar á Mastodon, kunnu ikki siterast av øðrum.",
|
||||
"visibility_modal.helper.unlisted_quoting": "Tá fólk sitera teg, so vera teirra postar eisini fjaldir frá tíðarlinjum við ráki.",
|
||||
"visibility_modal.instructions": "Stýr, hvør kann virka saman við hesum postinum. Globalar stillingar finnast undir <link>Stilingar > Onnur</link>.",
|
||||
"visibility_modal.privacy_label": "Privatlív",
|
||||
"visibility_modal.quote_followers": "Einans fylgjarar",
|
||||
"visibility_modal.quote_label": "Broyt hvør kann sitera",
|
||||
"visibility_modal.quote_nobody": "Bara eg",
|
||||
"visibility_modal.quote_public": "Ein og hvør",
|
||||
"visibility_modal.save": "Goym"
|
||||
}
|
||||
@@ -620,6 +620,7 @@
|
||||
"notification.moderation_warning.action_suspend": "חשבונך הושעה.",
|
||||
"notification.own_poll": "הסקר שלך הסתיים",
|
||||
"notification.poll": "סקר שהצבעת בו הסתיים",
|
||||
"notification.quoted_update": "{name} ערך הודעה שהשתמשת בה בציטוט",
|
||||
"notification.reblog": "הודעתך הודהדה על ידי {name}",
|
||||
"notification.reblog.name_and_others_with_link": "{name} ועוד <a>{count, plural,one {אחד נוסף}other {# נוספים}}</a> הדהדו את הודעתך",
|
||||
"notification.relationships_severance_event": "אבד הקשר עם {name}",
|
||||
@@ -900,6 +901,7 @@
|
||||
"status.quote_policy_change": "הגדרת הרשאה לציטוט הודעותיך",
|
||||
"status.quote_post_author": "ההודעה צוטטה על ידי @{name}",
|
||||
"status.quote_private": "הודעות פרטיות לא ניתנות לציטוט",
|
||||
"status.quotes": "{count, plural,one {ציטוט}other {ציטוטים}}",
|
||||
"status.read_more": "לקרוא עוד",
|
||||
"status.reblog": "הדהוד",
|
||||
"status.reblog_private": "להדהד ברמת הנראות המקורית",
|
||||
@@ -978,12 +980,15 @@
|
||||
"video.volume_up": "הגברת עוצמת שמע",
|
||||
"visibility_modal.button_title": "בחירת רמת חשיפה",
|
||||
"visibility_modal.header": "חשיפה והידוּד (אינטראקציה)",
|
||||
"visibility_modal.helper.direct_quoting": "איזכורים פרטיים שנוצרו במסטודון חסומים מציטוט על ידי אחרים.",
|
||||
"visibility_modal.helper.privacy_editing": "לא ניתן לשנות את דרגת החשיפה של הודעות שפורסמו.",
|
||||
"visibility_modal.helper.private_quoting": "הודעות לעוקבים־בלבד שנוצרו במסטודון חסומות מציטוט על ידי אחרים.",
|
||||
"visibility_modal.helper.unlisted_quoting": "כאשר אחרים מצטטים אותך, ההודעות שלהם יוסתרו גם מ\"נושאים חמים\".",
|
||||
"visibility_modal.instructions": "שליטה בהרשאה להידוּד (תגובות וציטוטים) עם הודעה זו. הגדרות ברירת המחדל ניתן למצוא תחת <link>העדפות > אחרים</link>.",
|
||||
"visibility_modal.privacy_label": "פרטיות",
|
||||
"visibility_modal.quote_followers": "לעוקבים בלבד",
|
||||
"visibility_modal.quote_label": "הגדרת הרשאה לציטוט הודעותיך",
|
||||
"visibility_modal.quote_nobody": "רק אני",
|
||||
"visibility_modal.quote_public": "כולם",
|
||||
"visibility_modal.save": "שמירה"
|
||||
}
|
||||
@@ -1,6 +1,7 @@
|
||||
{
|
||||
"about.blocks": "Moderētie serveri",
|
||||
"about.contact": "Kontakts:",
|
||||
"about.default_locale": "Noklusējums",
|
||||
"about.disclaimer": "Mastodon ir bezmaksas atklātā pirmkoda programmatūra un Mastodon gGmbH preču zīme.",
|
||||
"about.domain_blocks.no_reason_available": "Iemesls nav norādīts",
|
||||
"about.domain_blocks.preamble": "Mastodon parasti ļauj apskatīt saturu un mijiedarboties ar lietotājiem no jebkura cita fediversa servera. Šie ir izņēmumi, kas veikti tieši šajā serverī.",
|
||||
@@ -8,6 +9,7 @@
|
||||
"about.domain_blocks.silenced.title": "Ierobežotie",
|
||||
"about.domain_blocks.suspended.explanation": "Nekādi dati no šī servera netiks apstrādāti, uzglabāti vai apmainīti, padarot neiespējamu jebkādu mijiedarbību vai saziņu ar šī servera lietotājiem.",
|
||||
"about.domain_blocks.suspended.title": "Apturētie",
|
||||
"about.language_label": "Valoda",
|
||||
"about.not_available": "Šī informācija nav padarīta pieejama šajā serverī.",
|
||||
"about.powered_by": "Decentralizētu sabiedrisko tīklu darbina {mastodon}",
|
||||
"about.rules": "Servera noteikumi",
|
||||
@@ -145,6 +147,7 @@
|
||||
"bundle_column_error.routing.body": "Pieprasīto lapu nevarēja atrast. Vai esi pārliecināts, ka URL adreses joslā ir pareizs?",
|
||||
"bundle_column_error.routing.title": "404",
|
||||
"bundle_modal_error.close": "Aizvērt",
|
||||
"bundle_modal_error.message": "Kaut kas nogāja greizi šī ekrāna ielādēšanas laikā.",
|
||||
"bundle_modal_error.retry": "Mēģināt vēlreiz",
|
||||
"closed_registrations.other_server_instructions": "Tā kā Mastodon ir decentralizēts, tu vari izveidot kontu citā serverī un joprojām mijiedarboties ar šo.",
|
||||
"closed_registrations_modal.description": "Pašlaik nav iespējams izveidot kontu {domain}, bet, lūdzu, ņem vērā, ka Tev nav nepieciešams tieši {domain} konts, lai lietotu Mastodon!",
|
||||
@@ -213,6 +216,11 @@
|
||||
"confirmations.delete_list.confirm": "Dzēst",
|
||||
"confirmations.delete_list.message": "Vai tiešām neatgriezeniski izdzēst šo sarakstu?",
|
||||
"confirmations.delete_list.title": "Izdzēst sarakstu?",
|
||||
"confirmations.discard_draft.confirm": "Atmest un turpināt",
|
||||
"confirmations.discard_draft.edit.cancel": "Atsākt labošanu",
|
||||
"confirmations.discard_draft.post.cancel": "Atsākt melnrakstu",
|
||||
"confirmations.discard_draft.post.message": "Turpinot tiks atmests pašreiz sastādītais ieraksts.",
|
||||
"confirmations.discard_draft.post.title": "Atmest melnraksta ierakstu?",
|
||||
"confirmations.discard_edit_media.confirm": "Atmest",
|
||||
"confirmations.discard_edit_media.message": "Ir nesaglabātas izmaiņas informācijas nesēja aprakstā vai priekšskatījumā. Vēlies tās atmest tik un tā?",
|
||||
"confirmations.follow_to_list.confirm": "Sekot un pievienot sarakstam",
|
||||
@@ -232,6 +240,9 @@
|
||||
"confirmations.remove_from_followers.confirm": "Dzēst sekotāju",
|
||||
"confirmations.remove_from_followers.message": "{name} pārstās sekot jums. Vai tiešām vēlaties turpināt?",
|
||||
"confirmations.remove_from_followers.title": "Vai dzēst sekotāju?",
|
||||
"confirmations.revoke_quote.confirm": "Noņemt ierakstu",
|
||||
"confirmations.revoke_quote.message": "Šo darbību nevar atsaukt.",
|
||||
"confirmations.revoke_quote.title": "Noņemt ierakstu?",
|
||||
"confirmations.unfollow.confirm": "Pārstāt sekot",
|
||||
"confirmations.unfollow.message": "Vai tiešam vairs nevēlies sekot lietotājam {name}?",
|
||||
"confirmations.unfollow.title": "Pārtraukt sekošanu lietotājam?",
|
||||
@@ -268,6 +279,7 @@
|
||||
"domain_pill.who_they_are": "Tā kā turi norāda, kas kāds ir un kur viņi ir atrodami, Tu vari mijiedarboties ar cilvēkiem viscaur sabiedriskajā tīklā no <button>ar ActivityPub darbinātām platformām</button>.",
|
||||
"domain_pill.who_you_are": "Tā kā Tavs turis norāda, kas Tu esi un kur atrodies, cilvēki var mijiedarboties ar Tevi viscaur sabiedriskajā tīklā no <button>ar ActivityPub darbinātām platformām</button>.",
|
||||
"domain_pill.your_handle": "Tavs turis:",
|
||||
"dropdown.empty": "Atlasīt iespēju",
|
||||
"embed.instructions": "Iekļauj šo ierakstu savā tīmekļvietnē, ievietojot zemāk redzamo kodu starpliktuvē!",
|
||||
"embed.preview": "Tas izskatīsies šādi:",
|
||||
"emoji_button.activity": "Aktivitāte",
|
||||
@@ -317,6 +329,7 @@
|
||||
"explore.trending_statuses": "Ieraksti",
|
||||
"explore.trending_tags": "Tēmturi",
|
||||
"featured_carousel.next": "Tālāk",
|
||||
"featured_carousel.post": "Ieraksts",
|
||||
"featured_carousel.previous": "Atpakaļ",
|
||||
"featured_carousel.slide": "{index} / {total}",
|
||||
"filter_modal.added.context_mismatch_explanation": "Šī atlases kategorija neattiecas uz kontekstu, kurā esi piekļuvis šim ierakstam. Ja vēlies, lai ieraksts tiktu atlasīts arī šajā kontekstā, Tev būs jālabo atlase.",
|
||||
@@ -335,6 +348,7 @@
|
||||
"filter_modal.select_filter.subtitle": "Izmanto esošu kategoriju vai izveido jaunu",
|
||||
"filter_modal.select_filter.title": "Atlasīt šo ierakstu",
|
||||
"filter_modal.title.status": "Atlasīt ziņu",
|
||||
"filter_warning.matches_filter": "Atbilst atlasītājam “<span>{title}</span>”",
|
||||
"filtered_notifications_banner.title": "Filtrētie paziņojumi",
|
||||
"firehose.all": "Visi",
|
||||
"firehose.local": "Šis serveris",
|
||||
@@ -449,6 +463,8 @@
|
||||
"keyboard_shortcuts.translate": "tulkot ierakstu",
|
||||
"keyboard_shortcuts.unfocus": "Atfokusēt veidojamā teksta/meklēšanas lauku",
|
||||
"keyboard_shortcuts.up": "Pārvietoties augšup sarakstā",
|
||||
"learn_more_link.got_it": "Sapratu",
|
||||
"learn_more_link.learn_more": "Uzzināt vairāk",
|
||||
"lightbox.close": "Aizvērt",
|
||||
"lightbox.next": "Tālāk",
|
||||
"lightbox.previous": "Iepriekšējais",
|
||||
@@ -466,6 +482,7 @@
|
||||
"lists.delete": "Izdzēst sarakstu",
|
||||
"lists.done": "Gatavs",
|
||||
"lists.edit": "Labot sarakstu",
|
||||
"lists.find_users_to_add": "Atrast lietotājus, kurus pievienot",
|
||||
"lists.list_name": "Saraksta nosaukums",
|
||||
"lists.remove_member": "Noņemt",
|
||||
"lists.replies_policy.followed": "Jebkuram sekotajam lietotājam",
|
||||
@@ -531,6 +548,8 @@
|
||||
"notification_requests.dismiss": "Noraidīt",
|
||||
"notification_requests.edit_selection": "Labot",
|
||||
"notification_requests.exit_selection": "Gatavs",
|
||||
"notification_requests.explainer_for_limited_account": "Paziņojumi no šī konta tika atsijāti, jo pārvaldītājs ierobežoja kontu.",
|
||||
"notification_requests.explainer_for_limited_remote_account": "Paziņojumi no šī konta tika atsijāti, jo pārvaldītājs ierobežoja kontu vai tā serveri.",
|
||||
"notification_requests.notifications_from": "Paziņojumi no {name}",
|
||||
"notification_requests.title": "Atlasītie paziņojumi",
|
||||
"notification_requests.view": "Skatīt paziņojumus",
|
||||
@@ -570,6 +589,7 @@
|
||||
"notifications.permission_required": "Darbvirsmas paziņojumi nav pieejami, jo nav piešķirta nepieciešamā atļauja.",
|
||||
"notifications.policy.accept": "Pieņemt",
|
||||
"notifications.policy.drop": "Ignorēt",
|
||||
"notifications.policy.filter_limited_accounts_hint": "Servera satura pārraudzītāju ierobežots",
|
||||
"notifications.policy.filter_new_accounts_title": "Jauni konti",
|
||||
"notifications.policy.filter_not_followers_title": "Cilvēki, kuri Tev neseko",
|
||||
"notifications.policy.filter_not_following_hint": "Līdz tos pašrocīgi apstiprināsi",
|
||||
@@ -767,6 +787,7 @@
|
||||
"subscribed_languages.target": "Mainīt abonētās valodas priekš {target}",
|
||||
"tabs_bar.home": "Sākums",
|
||||
"tabs_bar.notifications": "Paziņojumi",
|
||||
"terms_of_service.effective_as_of": "Spēkā no {date}",
|
||||
"terms_of_service.title": "Pakalpojuma izmantošanas noteikumi",
|
||||
"time_remaining.days": "{number, plural, one {Atlikusi # diena} other {Atlikušas # dienas}}",
|
||||
"time_remaining.hours": "{number, plural, one {Atlikusi # stunda} other {Atlikušas # stundas}}",
|
||||
@@ -800,5 +821,13 @@
|
||||
"video.skip_forward": "Tīt uz priekšu",
|
||||
"video.unmute": "Ieslēgt skaņu",
|
||||
"video.volume_down": "Pagriezt klusāk",
|
||||
"video.volume_up": "Pagriezt skaļāk"
|
||||
"video.volume_up": "Pagriezt skaļāk",
|
||||
"visibility_modal.button_title": "Iestatīt redzamību",
|
||||
"visibility_modal.header": "Redzamība un mijjiedarbība",
|
||||
"visibility_modal.privacy_label": "Privātums",
|
||||
"visibility_modal.quote_followers": "Tikai sekotāji",
|
||||
"visibility_modal.quote_label": "Mainīt, kas var citēt",
|
||||
"visibility_modal.quote_nobody": "Tikai es",
|
||||
"visibility_modal.quote_public": "Ikviens",
|
||||
"visibility_modal.save": "Saglabāt"
|
||||
}
|
||||
@@ -292,6 +292,7 @@
|
||||
"domain_pill.your_handle": "Handtaket ditt:",
|
||||
"domain_pill.your_server": "Din digitale heim, der alle innlegga dine bur. Liker du ikkje dette? Byt til ein ny tenar når som helst og ta med fylgjarane dine òg.",
|
||||
"domain_pill.your_username": "Din unike identifikator på denne tenaren. Det er mogleg å finne brukarar med same brukarnamn på forskjellige tenarar.",
|
||||
"dropdown.empty": "Vel eit alternativ",
|
||||
"embed.instructions": "Bygg inn denne statusen på nettsida di ved å kopiera koden nedanfor.",
|
||||
"embed.preview": "Slik kjem det til å sjå ut:",
|
||||
"emoji_button.activity": "Aktivitet",
|
||||
@@ -482,6 +483,7 @@
|
||||
"keyboard_shortcuts.home": "Opne heimetidslina",
|
||||
"keyboard_shortcuts.hotkey": "Snøggtast",
|
||||
"keyboard_shortcuts.legend": "Vis denne forklaringa",
|
||||
"keyboard_shortcuts.load_more": "Fokuser på «Last meir»-knappen",
|
||||
"keyboard_shortcuts.local": "Opne lokal tidsline",
|
||||
"keyboard_shortcuts.mention": "Nemn forfattaren",
|
||||
"keyboard_shortcuts.muted": "Opne liste over målbundne brukarar",
|
||||
@@ -618,6 +620,7 @@
|
||||
"notification.moderation_warning.action_suspend": "Kontoen din har blitt suspendert.",
|
||||
"notification.own_poll": "Rundspørjinga di er ferdig",
|
||||
"notification.poll": "Ei rundspørjing du røysta i er ferdig",
|
||||
"notification.quoted_update": "{name} redigerte eit innlegg du har sitert",
|
||||
"notification.reblog": "{name} framheva innlegget ditt",
|
||||
"notification.reblog.name_and_others_with_link": "{name} og <a>{count, plural, one {# annan} other {# andre}}</a> framheva innlegget ditt",
|
||||
"notification.relationships_severance_event": "Tapte samband med {name}",
|
||||
@@ -737,11 +740,18 @@
|
||||
"privacy.private.short": "Fylgjarar",
|
||||
"privacy.public.long": "Kven som helst på og av Mastodon",
|
||||
"privacy.public.short": "Offentleg",
|
||||
"privacy.quote.anyone": "{visibility}, alle kan sitera",
|
||||
"privacy.quote.disabled": "{visibility}, ingen kan sitera",
|
||||
"privacy.quote.limited": "{visibility}, avgrensa sitat",
|
||||
"privacy.unlisted.additional": "Dette er akkurat som offentleg, bortsett frå at innlegga ikkje dukkar opp i direktestraumar eller merkelappar, i oppdagingar eller Mastodon-søk, sjølv om du har sagt ja til at kontoen skal vera synleg.",
|
||||
"privacy.unlisted.long": "Færre algoritmiske fanfarar",
|
||||
"privacy.unlisted.short": "Stille offentleg",
|
||||
"privacy_policy.last_updated": "Sist oppdatert {date}",
|
||||
"privacy_policy.title": "Personvernsreglar",
|
||||
"quote_error.poll": "Du kan ikkje sitera meiningsmålingar.",
|
||||
"quote_error.quote": "Det er berre lov med eitt sitat om gongen.",
|
||||
"quote_error.unauthorized": "Du har ikkje løyve til å sitera dette innlegget.",
|
||||
"quote_error.upload": "Du kan ikkje sitera medievedlegg.",
|
||||
"recommended": "Tilrådd",
|
||||
"refresh": "Oppdater",
|
||||
"regeneration_indicator.please_stand_by": "Vent litt.",
|
||||
@@ -848,9 +858,11 @@
|
||||
"status.admin_account": "Opne moderasjonsgrensesnitt for @{name}",
|
||||
"status.admin_domain": "Opna moderatorgrensesnittet for {domain}",
|
||||
"status.admin_status": "Opne denne statusen i moderasjonsgrensesnittet",
|
||||
"status.all_disabled": "Framhevingar og sitat er skrudde av",
|
||||
"status.block": "Blokker @{name}",
|
||||
"status.bookmark": "Set bokmerke",
|
||||
"status.cancel_reblog_private": "Opphev framheving",
|
||||
"status.cannot_quote": "Skribenten har skrudd av sitat for dette innlegget",
|
||||
"status.cannot_reblog": "Du kan ikkje framheva dette innlegget",
|
||||
"status.context.load_new_replies": "Nye svar finst",
|
||||
"status.context.loading": "Ser etter fleire svar",
|
||||
@@ -879,12 +891,17 @@
|
||||
"status.mute_conversation": "Demp samtale",
|
||||
"status.open": "Utvid denne statusen",
|
||||
"status.pin": "Fest på profil",
|
||||
"status.quote": "Siter",
|
||||
"status.quote.cancel": "Avbryt siteringa",
|
||||
"status.quote_error.filtered": "Gøymt på grunn av eitt av filtra dine",
|
||||
"status.quote_error.not_available": "Innlegget er ikkje tilgjengeleg",
|
||||
"status.quote_error.pending_approval": "Innlegget ventar",
|
||||
"status.quote_error.pending_approval_popout.body": "Sitat frå rundt om i allheimen kan ta tid å visa, fordi ulike tenarar har ulike protokollar.",
|
||||
"status.quote_error.pending_approval_popout.title": "Ventande sitat? Ikkje stress",
|
||||
"status.quote_policy_change": "Byt kven som kan sitera",
|
||||
"status.quote_post_author": "Siterte eit innlegg av @{name}",
|
||||
"status.quote_private": "Du kan ikkje sitera private innlegg",
|
||||
"status.quotes": "{count, plural, one {sitat} other {sitat}}",
|
||||
"status.read_more": "Les meir",
|
||||
"status.reblog": "Framhev",
|
||||
"status.reblog_private": "Framhev til dei originale mottakarane",
|
||||
|
||||
@@ -28,6 +28,9 @@ import {
|
||||
PIN_SUCCESS,
|
||||
UNPIN_SUCCESS,
|
||||
} from '../actions/interactions';
|
||||
import {
|
||||
fetchQuotes
|
||||
} from '../actions/interactions_typed';
|
||||
import {
|
||||
PINNED_STATUSES_FETCH_SUCCESS,
|
||||
} from '../actions/pin_statuses';
|
||||
@@ -40,8 +43,6 @@ import {
|
||||
TRENDS_STATUSES_EXPAND_FAIL,
|
||||
} from '../actions/trends';
|
||||
|
||||
|
||||
|
||||
const initialState = ImmutableMap({
|
||||
favourites: ImmutableMap({
|
||||
next: null,
|
||||
@@ -63,6 +64,12 @@ const initialState = ImmutableMap({
|
||||
loaded: false,
|
||||
items: ImmutableOrderedSet(),
|
||||
}),
|
||||
quotes: ImmutableMap({
|
||||
next: null,
|
||||
loaded: false,
|
||||
items: ImmutableOrderedSet(),
|
||||
statusId: null,
|
||||
}),
|
||||
});
|
||||
|
||||
const normalizeList = (state, listType, statuses, next) => {
|
||||
@@ -147,6 +154,13 @@ export default function statusLists(state = initialState, action) {
|
||||
case muteAccountSuccess.type:
|
||||
return state.updateIn(['trending', 'items'], ImmutableOrderedSet(), list => list.filterNot(statusId => action.payload.statuses.getIn([statusId, 'account']) === action.payload.relationship.id));
|
||||
default:
|
||||
return state;
|
||||
if (fetchQuotes.fulfilled.match(action))
|
||||
return normalizeList(state, 'quotes', action.payload.statuses, action.payload.next).set('statusId', action.meta.arg.statusId);
|
||||
else if (fetchQuotes.pending.match(action))
|
||||
return state.setIn(['quotes', 'isLoading'], true).setIn(['quotes', 'statusId'], action.meta.arg.statusId);
|
||||
else if (fetchQuotes.rejected.match(action))
|
||||
return state.setIn(['quotes', 'isLoading', false]).setIn(['quotes', 'statusId'], action.meta.arg.statusId);
|
||||
else
|
||||
return state;
|
||||
}
|
||||
}
|
||||
@@ -90,8 +90,15 @@ export default function statuses(state = initialState, action) {
|
||||
switch(action.type) {
|
||||
case STATUS_FETCH_REQUEST:
|
||||
return state.setIn([action.id, 'isLoading'], true);
|
||||
case STATUS_FETCH_FAIL:
|
||||
return state.delete(action.id);
|
||||
case STATUS_FETCH_FAIL: {
|
||||
if (action.parentQuotePostId && action.error.status === 404) {
|
||||
return state
|
||||
.delete(action.id)
|
||||
.setIn([action.parentQuotePostId, 'quote', 'state'], 'deleted')
|
||||
} else {
|
||||
return state.delete(action.id);
|
||||
}
|
||||
}
|
||||
case STATUS_IMPORT:
|
||||
return importStatus(state, action.status);
|
||||
case STATUSES_IMPORT:
|
||||
|
||||
Reference in new issue
Block a user