Merge commit '02de05dc272856c77fac5c9e1d84cf585ae20c1e' into glitch-soc/merge-upstream

This commit is contained in:
Claire committed 2025-08-27 18:13:03 +02:00
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')) {
+16 -4
View File
@@ -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,
};
+18 -5
View File
@@ -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');
}
+5
View File
@@ -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"
}
+1 -1
View File
@@ -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"
}
+4
View File
@@ -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",
+14 -7
View File
@@ -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"
}
+5
View File
@@ -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"
}
+5
View File
@@ -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": "שמירה"
}
+30 -1
View File
@@ -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"
}
+17
View File
@@ -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;
}
}
+9 -2
View File
@@ -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: