Mark all calls read when opening calls tab

This commit is contained in:
Jamie Kyle 2023-08-22 14:01:36 -07:00 committed by GitHub
parent b7c17212c7
commit 344ebf494d
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
8 changed files with 80 additions and 17 deletions

View file

@ -223,7 +223,7 @@ export class ConversationModel extends window.Backbone
contactCollection?: Backbone.Collection<ConversationModel>;
debouncedUpdateLastMessage?: (() => void) & { flush(): void };
debouncedUpdateLastMessage: (() => void) & { flush(): void };
initialPromise?: Promise<unknown>;
@ -1400,9 +1400,7 @@ export class ConversationModel extends window.Backbone
): Promise<void> {
await this.beforeAddSingleMessage(message);
this.doAddSingleMessage(message, { isJustSent });
// eslint-disable-next-line @typescript-eslint/no-non-null-assertion
this.debouncedUpdateLastMessage!();
this.debouncedUpdateLastMessage();
}
private async beforeAddSingleMessage(message: MessageModel): Promise<void> {
@ -5221,7 +5219,7 @@ export class ConversationModel extends window.Backbone
async flushDebouncedUpdates(): Promise<void> {
try {
await this.debouncedUpdateLastMessage?.flush();
this.debouncedUpdateLastMessage.flush();
} catch (error) {
const logId = this.idForLogging();
log.error(

View file

@ -1148,7 +1148,7 @@ export class MessageModel extends window.Backbone.Model<MessageAttributesType> {
sticker: undefined,
...additionalProperties,
});
this.getConversation()?.debouncedUpdateLastMessage?.();
this.getConversation()?.debouncedUpdateLastMessage();
if (shouldPersist) {
await window.Signal.Data.saveMessage(this.attributes, {
@ -1485,7 +1485,7 @@ export class MessageModel extends window.Backbone.Model<MessageAttributesType> {
saveErrors?: (errors: Array<Error>) => void
): Promise<void> {
const updateLeftPane =
this.getConversation()?.debouncedUpdateLastMessage || noop;
this.getConversation()?.debouncedUpdateLastMessage ?? noop;
updateLeftPane();

View file

@ -637,6 +637,7 @@ export type DataInterface = {
clearCallHistory: (beforeTimestamp: number) => Promise<Array<string>>;
getCallHistoryUnreadCount(): Promise<number>;
markCallHistoryRead(callId: string): Promise<void>;
markAllCallHistoryRead(): Promise<ReadonlyArray<string>>;
getCallHistoryMessageByCallId(options: {
conversationId: string;
callId: string;

View file

@ -308,6 +308,7 @@ const dataInterface: ServerInterface = {
clearCallHistory,
getCallHistoryUnreadCount,
markCallHistoryRead,
markAllCallHistoryRead,
getCallHistoryMessageByCallId,
getCallHistory,
getCallHistoryGroupsCount,
@ -3369,6 +3370,35 @@ async function markCallHistoryRead(callId: string): Promise<void> {
db.prepare(query).run(params);
}
async function markAllCallHistoryRead(): Promise<ReadonlyArray<string>> {
const db = getInstance();
return db.transaction(() => {
const where = sqlFragment`
WHERE messages.type IS 'call-history'
AND messages.readStatus IS ${READ_STATUS_UNREAD}
`;
const [selectQuery, selectParams] = sql`
SELECT DISTINCT conversationId
FROM messages
${where};
`;
const conversationIds = db.prepare(selectQuery).pluck().all(selectParams);
const [updateQuery, updateParams] = sql`
UPDATE messages
SET readStatus = ${READ_STATUS_READ}
${where};
`;
db.prepare(updateQuery).run(updateParams);
return conversationIds;
})();
}
function getCallHistoryGroupDataSync(
db: Database,
isCount: boolean,
@ -5587,14 +5617,14 @@ async function eraseStorageServiceState(): Promise<void> {
storageVersion = null,
storageUnknownFields = null,
storageNeedsSync = 0;
UPDATE uninstalled_sticker_packs
SET
storageID = null,
storageVersion = null,
storageUnknownFields = null,
storageNeedsSync = 0;
-- Story Distribution Lists
UPDATE storyDistributions
SET

View file

@ -13,6 +13,7 @@ import { ToastType } from '../../types/Toast';
import type { CallHistoryDetails } from '../../types/CallDisposition';
import * as log from '../../logging/log';
import * as Errors from '../../types/errors';
import { drop } from '../../util/drop';
export type CallHistoryState = ReadonlyDeep<{
// This informs the app that underlying call history data has changed.
@ -77,9 +78,35 @@ function markCallHistoryRead(
return async dispatch => {
try {
await window.Signal.Data.markCallHistoryRead(callId);
await window.ConversationController.get(conversationId)?.updateUnread();
drop(window.ConversationController.get(conversationId)?.updateUnread());
} catch (error) {
log.error('Error marking call history read', Errors.toLogFormat(error));
log.error(
'markCallHistoryRead: Error marking call history read',
Errors.toLogFormat(error)
);
} finally {
dispatch(updateCallHistoryUnreadCount());
}
};
}
function markCallsTabViewed(): ThunkAction<
void,
RootStateType,
unknown,
CallHistoryUpdateUnread
> {
return async dispatch => {
try {
const conversationIds = await window.Signal.Data.markAllCallHistoryRead();
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());
}
@ -118,6 +145,7 @@ export const actions = {
clearAllCallHistory,
updateCallHistoryUnreadCount,
markCallHistoryRead,
markCallsTabViewed,
};
export const useCallHistoryActions = (): BoundActionCreatorsMapObject<

View file

@ -1,7 +1,7 @@
// Copyright 2023 Signal Messenger, LLC
// SPDX-License-Identifier: AGPL-3.0-only
import React, { useCallback } from 'react';
import React, { useCallback, useEffect } from 'react';
import { useSelector } from 'react-redux';
import { useItemsActions } from '../ducks/items';
import {
@ -102,8 +102,11 @@ export function SmartCallsTab(): JSX.Element {
onOutgoingAudioCallInConversation,
onOutgoingVideoCallInConversation,
} = useCallingActions();
const { clearAllCallHistory: clearCallHistory, markCallHistoryRead } =
useCallHistoryActions();
const {
clearAllCallHistory: clearCallHistory,
markCallHistoryRead,
markCallsTabViewed,
} = useCallHistoryActions();
const getCallHistoryGroupsCount = useCallback(
async (options: CallHistoryFilterOptions) => {
@ -149,6 +152,10 @@ export function SmartCallsTab(): JSX.Element {
[allConversations, regionCode, callHistoryEdition]
);
useEffect(() => {
markCallsTabViewed();
}, [markCallsTabViewed]);
return (
<CallsTab
activeCall={activeCall}

View file

@ -59,7 +59,6 @@ import {
callDetailsSchema,
} from '../types/CallDisposition';
import type { ConversationType } from '../state/ducks/conversations';
import { drop } from './drop';
// utils
// -----
@ -895,7 +894,7 @@ export async function clearCallHistoryDataAndSync(): Promise<void> {
messageId,
message.get('conversationId')
);
drop(conversation.updateLastMessage());
conversation.debouncedUpdateLastMessage();
window.MessageController.unregister(messageId);
});

View file

@ -15,7 +15,7 @@ export async function cleanupMessage(
window.reduxActions?.conversations.messageDeleted(id, conversationId);
const parentConversation = window.ConversationController.get(conversationId);
parentConversation?.debouncedUpdateLastMessage?.();
parentConversation?.debouncedUpdateLastMessage();
window.MessageController.unregister(id);