Handle new sync message MarkedAsRead for Calls Tab
This commit is contained in:
parent
b410d14753
commit
c332bd240f
8 changed files with 72 additions and 16 deletions
|
@ -614,6 +614,7 @@ message SyncMessage {
|
||||||
message CallLogEvent {
|
message CallLogEvent {
|
||||||
enum Type {
|
enum Type {
|
||||||
CLEAR = 0;
|
CLEAR = 0;
|
||||||
|
MARKED_AS_READ = 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
optional Type type = 1;
|
optional Type type = 1;
|
||||||
|
|
|
@ -649,7 +649,9 @@ export type DataInterface = {
|
||||||
cleanupCallHistoryMessages: () => Promise<void>;
|
cleanupCallHistoryMessages: () => Promise<void>;
|
||||||
getCallHistoryUnreadCount(): Promise<number>;
|
getCallHistoryUnreadCount(): Promise<number>;
|
||||||
markCallHistoryRead(callId: string): Promise<void>;
|
markCallHistoryRead(callId: string): Promise<void>;
|
||||||
markAllCallHistoryRead(): Promise<ReadonlyArray<string>>;
|
markAllCallHistoryRead(
|
||||||
|
beforeTimestamp: number
|
||||||
|
): Promise<ReadonlyArray<string>>;
|
||||||
getCallHistoryMessageByCallId(options: {
|
getCallHistoryMessageByCallId(options: {
|
||||||
conversationId: string;
|
conversationId: string;
|
||||||
callId: string;
|
callId: string;
|
||||||
|
|
|
@ -3487,13 +3487,16 @@ async function markCallHistoryRead(callId: string): Promise<void> {
|
||||||
db.prepare(query).run(params);
|
db.prepare(query).run(params);
|
||||||
}
|
}
|
||||||
|
|
||||||
async function markAllCallHistoryRead(): Promise<ReadonlyArray<string>> {
|
async function markAllCallHistoryRead(
|
||||||
|
beforeTimestamp: number
|
||||||
|
): Promise<ReadonlyArray<string>> {
|
||||||
const db = await getWritableInstance();
|
const db = await getWritableInstance();
|
||||||
|
|
||||||
return db.transaction(() => {
|
return db.transaction(() => {
|
||||||
const where = sqlFragment`
|
const where = sqlFragment`
|
||||||
WHERE messages.type IS 'call-history'
|
WHERE messages.type IS 'call-history'
|
||||||
AND messages.seenStatus IS ${SEEN_STATUS_UNSEEN}
|
AND messages.seenStatus IS ${SEEN_STATUS_UNSEEN}
|
||||||
|
AND messages.sent_at <= ${beforeTimestamp};
|
||||||
`;
|
`;
|
||||||
|
|
||||||
const [selectQuery, selectParams] = sql`
|
const [selectQuery, selectParams] = sql`
|
||||||
|
|
|
@ -5,7 +5,10 @@ import type { ReadonlyDeep } from 'type-fest';
|
||||||
import type { ThunkAction } from 'redux-thunk';
|
import type { ThunkAction } from 'redux-thunk';
|
||||||
import { omit } from 'lodash';
|
import { omit } from 'lodash';
|
||||||
import type { StateType as RootStateType } from '../reducer';
|
import type { StateType as RootStateType } from '../reducer';
|
||||||
import { clearCallHistoryDataAndSync } from '../../util/callDisposition';
|
import {
|
||||||
|
clearCallHistoryDataAndSync,
|
||||||
|
markAllCallHistoryReadAndSync,
|
||||||
|
} from '../../util/callDisposition';
|
||||||
import type { BoundActionCreatorsMapObject } from '../../hooks/useBoundActions';
|
import type { BoundActionCreatorsMapObject } from '../../hooks/useBoundActions';
|
||||||
import { useBoundActions } from '../../hooks/useBoundActions';
|
import { useBoundActions } from '../../hooks/useBoundActions';
|
||||||
import type { ToastActionType } from './toast';
|
import type { ToastActionType } from './toast';
|
||||||
|
@ -107,19 +110,8 @@ function markCallsTabViewed(): ThunkAction<
|
||||||
CallHistoryUpdateUnread
|
CallHistoryUpdateUnread
|
||||||
> {
|
> {
|
||||||
return async dispatch => {
|
return async dispatch => {
|
||||||
try {
|
await markAllCallHistoryReadAndSync();
|
||||||
const conversationIds = await window.Signal.Data.markAllCallHistoryRead();
|
dispatch(updateCallHistoryUnreadCount());
|
||||||
for (const conversationId of conversationIds) {
|
|
||||||
drop(window.ConversationController.get(conversationId)?.updateUnread());
|
|
||||||
}
|
|
||||||
} catch (error) {
|
|
||||||
log.error(
|
|
||||||
'markCallsTabViewed: Error marking all call history read',
|
|
||||||
Errors.toLogFormat(error)
|
|
||||||
);
|
|
||||||
} finally {
|
|
||||||
dispatch(updateCallHistoryUnreadCount());
|
|
||||||
}
|
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -3505,6 +3505,10 @@ export default class MessageReceiver
|
||||||
callLogEvent.type === Proto.SyncMessage.CallLogEvent.Type.CLEAR
|
callLogEvent.type === Proto.SyncMessage.CallLogEvent.Type.CLEAR
|
||||||
) {
|
) {
|
||||||
event = CallLogEvent.Clear;
|
event = CallLogEvent.Clear;
|
||||||
|
} else if (
|
||||||
|
callLogEvent.type === Proto.SyncMessage.CallLogEvent.Type.MARKED_AS_READ
|
||||||
|
) {
|
||||||
|
event = CallLogEvent.MarkedAsRead;
|
||||||
} else {
|
} else {
|
||||||
throw new Error(
|
throw new Error(
|
||||||
`MessageReceiver.handleCallLogEvent: unknown type ${callLogEvent.type}`
|
`MessageReceiver.handleCallLogEvent: unknown type ${callLogEvent.type}`
|
||||||
|
|
|
@ -23,6 +23,7 @@ export enum CallDirection {
|
||||||
|
|
||||||
export enum CallLogEvent {
|
export enum CallLogEvent {
|
||||||
Clear = 'Clear',
|
Clear = 'Clear',
|
||||||
|
MarkedAsRead = 'MarkedAsRead',
|
||||||
}
|
}
|
||||||
|
|
||||||
export enum LocalCallEvent {
|
export enum LocalCallEvent {
|
||||||
|
|
|
@ -1056,6 +1056,49 @@ export async function clearCallHistoryDataAndSync(): Promise<void> {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
export async function markAllCallHistoryReadAndSync(): Promise<void> {
|
||||||
|
try {
|
||||||
|
const timestamp = Date.now();
|
||||||
|
|
||||||
|
log.info(
|
||||||
|
`markAllCallHistoryReadAndSync: Marking call history read before ${timestamp}`
|
||||||
|
);
|
||||||
|
await window.Signal.Data.markAllCallHistoryRead(timestamp);
|
||||||
|
|
||||||
|
const ourAci = window.textsecure.storage.user.getCheckedAci();
|
||||||
|
|
||||||
|
const callLogEvent = new Proto.SyncMessage.CallLogEvent({
|
||||||
|
type: Proto.SyncMessage.CallLogEvent.Type.MARKED_AS_READ,
|
||||||
|
timestamp: Long.fromNumber(timestamp),
|
||||||
|
});
|
||||||
|
|
||||||
|
const syncMessage = MessageSender.createSyncMessage();
|
||||||
|
syncMessage.callLogEvent = callLogEvent;
|
||||||
|
|
||||||
|
const contentMessage = new Proto.Content();
|
||||||
|
contentMessage.syncMessage = syncMessage;
|
||||||
|
|
||||||
|
const { ContentHint } = Proto.UnidentifiedSenderMessage.Message;
|
||||||
|
|
||||||
|
log.info('markAllCallHistoryReadAndSync: Queueing sync message');
|
||||||
|
await singleProtoJobQueue.add({
|
||||||
|
contentHint: ContentHint.RESENDABLE,
|
||||||
|
serviceId: ourAci,
|
||||||
|
isSyncMessage: true,
|
||||||
|
protoBase64: Bytes.toBase64(
|
||||||
|
Proto.Content.encode(contentMessage).finish()
|
||||||
|
),
|
||||||
|
type: 'callLogEventSync',
|
||||||
|
urgent: false,
|
||||||
|
});
|
||||||
|
} catch (error) {
|
||||||
|
log.error(
|
||||||
|
'markAllCallHistoryReadAndSync: Failed to mark call history read',
|
||||||
|
error
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
export async function updateLocalGroupCallHistoryTimestamp(
|
export async function updateLocalGroupCallHistoryTimestamp(
|
||||||
conversationId: string,
|
conversationId: string,
|
||||||
callId: string,
|
callId: string,
|
||||||
|
|
|
@ -25,6 +25,16 @@ export async function onCallLogEventSync(
|
||||||
window.reduxActions.callHistory.resetCallHistory();
|
window.reduxActions.callHistory.resetCallHistory();
|
||||||
}
|
}
|
||||||
confirm();
|
confirm();
|
||||||
|
} else if (event === CallLogEvent.MarkedAsRead) {
|
||||||
|
log.info(
|
||||||
|
`onCallLogEventSync: Marking call history read before ${timestamp}`
|
||||||
|
);
|
||||||
|
try {
|
||||||
|
await window.Signal.Data.markAllCallHistoryRead(timestamp);
|
||||||
|
} finally {
|
||||||
|
window.reduxActions.callHistory.updateCallHistoryUnreadCount();
|
||||||
|
}
|
||||||
|
confirm();
|
||||||
} else {
|
} else {
|
||||||
throw missingCaseError(event);
|
throw missingCaseError(event);
|
||||||
}
|
}
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue