Optimistic replies: fix duplicated statuses
This commit is contained in:
parent
03dbd5bfd2
commit
135b4c4d7b
|
@ -26,8 +26,8 @@ export function importAccounts(accounts) {
|
||||||
return { type: ACCOUNTS_IMPORT, accounts };
|
return { type: ACCOUNTS_IMPORT, accounts };
|
||||||
}
|
}
|
||||||
|
|
||||||
export function importStatus(status) {
|
export function importStatus(status, idempotencyKey) {
|
||||||
return { type: STATUS_IMPORT, status };
|
return { type: STATUS_IMPORT, status, idempotencyKey };
|
||||||
}
|
}
|
||||||
|
|
||||||
export function importStatuses(statuses) {
|
export function importStatuses(statuses) {
|
||||||
|
@ -60,8 +60,27 @@ export function importFetchedAccounts(accounts) {
|
||||||
return importAccounts(normalAccounts);
|
return importAccounts(normalAccounts);
|
||||||
}
|
}
|
||||||
|
|
||||||
export function importFetchedStatus(status) {
|
export function importFetchedStatus(status, idempotencyKey) {
|
||||||
return importFetchedStatuses([status]);
|
return (dispatch, getState) => {
|
||||||
|
// Skip broken statuses
|
||||||
|
if (isBroken(status)) return;
|
||||||
|
|
||||||
|
const normalOldStatus = getState().getIn(['statuses', status.id]);
|
||||||
|
const expandSpoilers = getSettings(getState()).get('expandSpoilers');
|
||||||
|
|
||||||
|
const normalizedStatus = normalizeStatus(status, normalOldStatus, expandSpoilers);
|
||||||
|
|
||||||
|
dispatch(importStatus(normalizedStatus, idempotencyKey));
|
||||||
|
dispatch(importFetchedAccount(status.account));
|
||||||
|
|
||||||
|
if (status.reblog && status.reblog.id) {
|
||||||
|
dispatch(importFetchedStatus(status.reblog));
|
||||||
|
}
|
||||||
|
|
||||||
|
if (status.poll && status.poll.id) {
|
||||||
|
dispatch(importFetchedPoll(status.poll));
|
||||||
|
}
|
||||||
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
// Sometimes Pleroma can return an empty account,
|
// Sometimes Pleroma can return an empty account,
|
||||||
|
|
|
@ -48,7 +48,7 @@ export function createStatus(params, idempotencyKey) {
|
||||||
return api(getState).post('/api/v1/statuses', params, {
|
return api(getState).post('/api/v1/statuses', params, {
|
||||||
headers: { 'Idempotency-Key': idempotencyKey },
|
headers: { 'Idempotency-Key': idempotencyKey },
|
||||||
}).then(({ data: status }) => {
|
}).then(({ data: status }) => {
|
||||||
dispatch(importFetchedStatus(status));
|
dispatch(importFetchedStatus(status, idempotencyKey));
|
||||||
dispatch({ type: STATUS_CREATE_SUCCESS, status, params, idempotencyKey });
|
dispatch({ type: STATUS_CREATE_SUCCESS, status, params, idempotencyKey });
|
||||||
return status;
|
return status;
|
||||||
}).catch(error => {
|
}).catch(error => {
|
||||||
|
|
|
@ -29,8 +29,6 @@ export function processTimelineUpdate(timeline, status, accept) {
|
||||||
const columnSettings = getSettings(getState()).get(timeline, ImmutableMap());
|
const columnSettings = getSettings(getState()).get(timeline, ImmutableMap());
|
||||||
const shouldSkipQueue = shouldFilter(fromJS(status), columnSettings);
|
const shouldSkipQueue = shouldFilter(fromJS(status), columnSettings);
|
||||||
|
|
||||||
dispatch(importFetchedStatus(status));
|
|
||||||
|
|
||||||
if (ownStatus && hasPendingStatuses) {
|
if (ownStatus && hasPendingStatuses) {
|
||||||
// WebSockets push statuses without the Idempotency-Key,
|
// WebSockets push statuses without the Idempotency-Key,
|
||||||
// so if we have pending statuses, don't import it from here.
|
// so if we have pending statuses, don't import it from here.
|
||||||
|
@ -38,6 +36,8 @@ export function processTimelineUpdate(timeline, status, accept) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
dispatch(importFetchedStatus(status));
|
||||||
|
|
||||||
if (shouldSkipQueue) {
|
if (shouldSkipQueue) {
|
||||||
dispatch(updateTimeline(timeline, status.id, accept));
|
dispatch(updateTimeline(timeline, status.id, accept));
|
||||||
} else {
|
} else {
|
||||||
|
|
|
@ -16,7 +16,8 @@ const initialState = ImmutableMap({
|
||||||
replies: ImmutableMap(),
|
replies: ImmutableMap(),
|
||||||
});
|
});
|
||||||
|
|
||||||
const importStatus = (state, { id, in_reply_to_id }) => {
|
const importStatus = (state, status, idempotencyKey) => {
|
||||||
|
const { id, in_reply_to_id } = status;
|
||||||
if (!in_reply_to_id) return state;
|
if (!in_reply_to_id) return state;
|
||||||
|
|
||||||
return state.withMutations(state => {
|
return state.withMutations(state => {
|
||||||
|
@ -25,6 +26,10 @@ const importStatus = (state, { id, in_reply_to_id }) => {
|
||||||
state.updateIn(['replies', in_reply_to_id], ImmutableOrderedSet(), ids => {
|
state.updateIn(['replies', in_reply_to_id], ImmutableOrderedSet(), ids => {
|
||||||
return ids.add(id).sort();
|
return ids.add(id).sort();
|
||||||
});
|
});
|
||||||
|
|
||||||
|
if (idempotencyKey) {
|
||||||
|
deletePendingStatus(state, status, idempotencyKey);
|
||||||
|
}
|
||||||
});
|
});
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -129,7 +134,7 @@ export default function replies(state = initialState, action) {
|
||||||
case STATUS_CREATE_SUCCESS:
|
case STATUS_CREATE_SUCCESS:
|
||||||
return deletePendingStatus(state, action.status, action.idempotencyKey);
|
return deletePendingStatus(state, action.status, action.idempotencyKey);
|
||||||
case STATUS_IMPORT:
|
case STATUS_IMPORT:
|
||||||
return importStatus(state, action.status);
|
return importStatus(state, action.status, action.idempotencyKey);
|
||||||
case STATUSES_IMPORT:
|
case STATUSES_IMPORT:
|
||||||
return importStatuses(state, action.statuses);
|
return importStatuses(state, action.statuses);
|
||||||
default:
|
default:
|
||||||
|
|
Loading…
Reference in New Issue