Fix call history deletion from sync messages
This commit is contained in:
parent
20ddca9684
commit
1cc478180e
6 changed files with 84 additions and 11 deletions
|
@ -8,6 +8,7 @@ import { strictAssert } from '../util/assert';
|
|||
let callsHistoryData: ReadonlyArray<CallHistoryDetails>;
|
||||
|
||||
export async function loadCallsHistory(): Promise<void> {
|
||||
await dataInterface.cleanupCallHistoryMessages();
|
||||
callsHistoryData = await dataInterface.getAllCallHistory();
|
||||
}
|
||||
|
||||
|
|
|
@ -630,6 +630,7 @@ export type DataInterface = {
|
|||
}): Promise<MessageType | undefined>;
|
||||
getAllCallHistory: () => Promise<ReadonlyArray<CallHistoryDetails>>;
|
||||
clearCallHistory: (beforeTimestamp: number) => Promise<Array<string>>;
|
||||
cleanupCallHistoryMessages: () => Promise<void>;
|
||||
getCallHistoryUnreadCount(): Promise<number>;
|
||||
markCallHistoryRead(callId: string): Promise<void>;
|
||||
markAllCallHistoryRead(): Promise<ReadonlyArray<string>>;
|
||||
|
|
|
@ -305,6 +305,7 @@ const dataInterface: ServerInterface = {
|
|||
getLastConversationMessage,
|
||||
getAllCallHistory,
|
||||
clearCallHistory,
|
||||
cleanupCallHistoryMessages,
|
||||
getCallHistoryUnreadCount,
|
||||
markCallHistoryRead,
|
||||
markAllCallHistoryRead,
|
||||
|
@ -3294,6 +3295,24 @@ async function clearCallHistory(
|
|||
})();
|
||||
}
|
||||
|
||||
async function cleanupCallHistoryMessages(): Promise<void> {
|
||||
const db = getInstance();
|
||||
return db
|
||||
.transaction(() => {
|
||||
const [query, params] = sql`
|
||||
DELETE FROM messages
|
||||
WHERE messages.id IN (
|
||||
SELECT messages.id FROM messages
|
||||
LEFT JOIN callsHistory ON callsHistory.callId IS messages.callId
|
||||
WHERE messages.type IS 'call-history'
|
||||
AND callsHistory.status IS ${CALL_STATUS_DELETED}
|
||||
)
|
||||
`;
|
||||
db.prepare(query).run(params);
|
||||
})
|
||||
.immediate();
|
||||
}
|
||||
|
||||
async function getCallHistoryMessageByCallId(options: {
|
||||
conversationId: string;
|
||||
callId: string;
|
||||
|
|
|
@ -3,6 +3,7 @@
|
|||
|
||||
import type { ReadonlyDeep } from 'type-fest';
|
||||
import type { ThunkAction } from 'redux-thunk';
|
||||
import { omit } from 'lodash';
|
||||
import type { StateType as RootStateType } from '../reducer';
|
||||
import { clearCallHistoryDataAndSync } from '../../util/callDisposition';
|
||||
import type { BoundActionCreatorsMapObject } from '../../hooks/useBoundActions';
|
||||
|
@ -22,15 +23,21 @@ export type CallHistoryState = ReadonlyDeep<{
|
|||
callHistoryByCallId: Record<string, CallHistoryDetails>;
|
||||
}>;
|
||||
|
||||
const CALL_HISTORY_CACHE = 'callHistory/CACHE';
|
||||
const CALL_HISTORY_ADD = 'callHistory/ADD';
|
||||
const CALL_HISTORY_REMOVE = 'callHistory/REMOVE';
|
||||
const CALL_HISTORY_RESET = 'callHistory/RESET';
|
||||
const CALL_HISTORY_UPDATE_UNREAD = 'callHistory/UPDATE_UNREAD';
|
||||
|
||||
export type CallHistoryCache = ReadonlyDeep<{
|
||||
type: typeof CALL_HISTORY_CACHE;
|
||||
export type CallHistoryAdd = ReadonlyDeep<{
|
||||
type: typeof CALL_HISTORY_ADD;
|
||||
payload: CallHistoryDetails;
|
||||
}>;
|
||||
|
||||
export type CallHistoryRemove = ReadonlyDeep<{
|
||||
type: typeof CALL_HISTORY_REMOVE;
|
||||
payload: CallHistoryDetails['callId'];
|
||||
}>;
|
||||
|
||||
export type CallHistoryReset = ReadonlyDeep<{
|
||||
type: typeof CALL_HISTORY_RESET;
|
||||
}>;
|
||||
|
@ -41,7 +48,10 @@ export type CallHistoryUpdateUnread = ReadonlyDeep<{
|
|||
}>;
|
||||
|
||||
export type CallHistoryAction = ReadonlyDeep<
|
||||
CallHistoryCache | CallHistoryReset | CallHistoryUpdateUnread
|
||||
| CallHistoryAdd
|
||||
| CallHistoryRemove
|
||||
| CallHistoryReset
|
||||
| CallHistoryUpdateUnread
|
||||
>;
|
||||
|
||||
export function getEmptyState(): CallHistoryState {
|
||||
|
@ -113,13 +123,26 @@ function markCallsTabViewed(): ThunkAction<
|
|||
};
|
||||
}
|
||||
|
||||
function cacheCallHistory(callHistory: CallHistoryDetails): CallHistoryCache {
|
||||
function addCallHistory(callHistory: CallHistoryDetails): CallHistoryAdd {
|
||||
return {
|
||||
type: CALL_HISTORY_CACHE,
|
||||
type: CALL_HISTORY_ADD,
|
||||
payload: callHistory,
|
||||
};
|
||||
}
|
||||
|
||||
function removeCallHistory(
|
||||
callId: CallHistoryDetails['callId']
|
||||
): CallHistoryRemove {
|
||||
return {
|
||||
type: CALL_HISTORY_REMOVE,
|
||||
payload: callId,
|
||||
};
|
||||
}
|
||||
|
||||
function resetCallHistory(): CallHistoryReset {
|
||||
return { type: CALL_HISTORY_RESET };
|
||||
}
|
||||
|
||||
function clearAllCallHistory(): ThunkAction<
|
||||
void,
|
||||
RootStateType,
|
||||
|
@ -134,14 +157,16 @@ function clearAllCallHistory(): ThunkAction<
|
|||
log.error('Error clearing call history', Errors.toLogFormat(error));
|
||||
} finally {
|
||||
// Just force a reset, even if the clear failed.
|
||||
dispatch({ type: CALL_HISTORY_RESET });
|
||||
dispatch(resetCallHistory());
|
||||
dispatch(updateCallHistoryUnreadCount());
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
export const actions = {
|
||||
cacheCallHistory,
|
||||
addCallHistory,
|
||||
removeCallHistory,
|
||||
resetCallHistory,
|
||||
clearAllCallHistory,
|
||||
updateCallHistoryUnreadCount,
|
||||
markCallHistoryRead,
|
||||
|
@ -159,7 +184,7 @@ export function reducer(
|
|||
switch (action.type) {
|
||||
case CALL_HISTORY_RESET:
|
||||
return { ...state, edition: state.edition + 1, callHistoryByCallId: {} };
|
||||
case CALL_HISTORY_CACHE:
|
||||
case CALL_HISTORY_ADD:
|
||||
return {
|
||||
...state,
|
||||
callHistoryByCallId: {
|
||||
|
@ -167,6 +192,11 @@ export function reducer(
|
|||
[action.payload.callId]: action.payload,
|
||||
},
|
||||
};
|
||||
case CALL_HISTORY_REMOVE:
|
||||
return {
|
||||
...state,
|
||||
callHistoryByCallId: omit(state.callHistoryByCallId, action.payload),
|
||||
};
|
||||
case CALL_HISTORY_UPDATE_UNREAD:
|
||||
return {
|
||||
...state,
|
||||
|
|
|
@ -785,8 +785,18 @@ async function updateLocalCallHistory(
|
|||
'updateLocalCallHistory: Saving call history:',
|
||||
formatCallHistory(callHistory)
|
||||
);
|
||||
|
||||
const isDeleted =
|
||||
callHistory.status === DirectCallStatus.Deleted ||
|
||||
callHistory.status === GroupCallStatus.Deleted;
|
||||
|
||||
await window.Signal.Data.saveCallHistory(callHistory);
|
||||
window.reduxActions.callHistory.cacheCallHistory(callHistory);
|
||||
|
||||
if (isDeleted) {
|
||||
window.reduxActions.callHistory.removeCallHistory(callHistory.callId);
|
||||
} else {
|
||||
window.reduxActions.callHistory.addCallHistory(callHistory);
|
||||
}
|
||||
|
||||
const prevMessage =
|
||||
await window.Signal.Data.getCallHistoryMessageByCallId({
|
||||
|
@ -806,6 +816,13 @@ async function updateLocalCallHistory(
|
|||
);
|
||||
}
|
||||
|
||||
if (isDeleted) {
|
||||
if (prevMessage != null) {
|
||||
await window.Signal.Data.removeMessage(prevMessage.id);
|
||||
}
|
||||
return callHistory;
|
||||
}
|
||||
|
||||
let unread = false;
|
||||
if (callHistory.mode === CallMode.Direct) {
|
||||
unread =
|
||||
|
|
|
@ -18,7 +18,12 @@ export async function onCallLogEventSync(
|
|||
|
||||
if (event === CallLogEvent.Clear) {
|
||||
log.info(`onCallLogEventSync: Clearing call history before ${timestamp}`);
|
||||
await window.Signal.Data.clearCallHistory(timestamp);
|
||||
try {
|
||||
await window.Signal.Data.clearCallHistory(timestamp);
|
||||
} finally {
|
||||
// We want to reset the call history even if the clear fails.
|
||||
window.reduxActions.callHistory.resetCallHistory();
|
||||
}
|
||||
confirm();
|
||||
} else {
|
||||
throw missingCaseError(event);
|
||||
|
|
Loading…
Reference in a new issue