Correctly process forum for folders + unread count

This commit is contained in:
Eduard Kuzmenko 2023-01-13 15:10:41 +04:00
parent 053b313df2
commit a88043f966
6 changed files with 94 additions and 19 deletions

View File

@ -155,8 +155,8 @@ export class AppChatsManager extends AppManager {
} else {
const oldPhotoId = ((oldChat as Chat.chat).photo as ChatPhoto.chatPhoto)?.photo_id;
const newPhotoId = ((chat as Chat.chat).photo as ChatPhoto.chatPhoto)?.photo_id;
const changedPhoto = oldPhotoId !== newPhotoId ||
(oldChat as Chat.channel).pFlags.forum !== (chat as Chat.channel).pFlags.forum;
const toggledForum = (oldChat as Chat.channel).pFlags.forum !== (chat as Chat.channel).pFlags.forum;
const changedPhoto = oldPhotoId !== newPhotoId || toggledForum;
const changedTitle = oldChat.title !== chat.title || changedUsername;
@ -174,6 +174,10 @@ export class AppChatsManager extends AppManager {
if(changedTitle || changedAnyBadge) {
this.rootScope.dispatchEvent('peer_title_edit', {peerId});
}
if(toggledForum) {
this.rootScope.dispatchEvent('chat_toggle_forum', {chatId: chat.id, enabled: !!(chat as Chat.channel).pFlags.forum});
}
}
if(this.peersStorage.isPeerNeeded(peerId)) {

View File

@ -2057,6 +2057,7 @@ export class AppDialogsManager {
}
const {unreadUnmutedCount, unreadCount} = await this.managers.dialogsStorage.getFolderUnreadCount(filterId);
unreadSpan.classList.toggle('badge-gray', !unreadUnmutedCount);
const count = filterId === FOLDER_ID_ALL ? unreadUnmutedCount : unreadCount;
unreadSpan.innerText = count ? '' + count : '';

View File

@ -395,6 +395,20 @@ export class AppMessagesManager extends AppManager {
}
});
// * clear forum cache
this.rootScope.addEventListener('chat_toggle_forum', ({chatId, enabled}) => {
const peerId = chatId.toPeerId(true);
if(!enabled) {
delete this.threadsStorage[peerId];
for(const key in this.pinnedMessages) {
if(+key === peerId && key.startsWith(peerId + '_')) {
delete this.pinnedMessages[key];
}
}
}
});
this.batchUpdatesDebounced = debounce(() => {
for(const event in this.batchUpdates) {
const details = this.batchUpdates[event as keyof BatchUpdates];
@ -6345,7 +6359,17 @@ export class AppMessagesManager extends AppManager {
}
public getDialogUnreadCount(dialog: Dialog | ForumTopic) {
return dialog.unread_count || +!!(dialog as Dialog).pFlags.unread_mark;
let unreadCount = dialog.unread_count;
if(!this.dialogsStorage.isTopic(dialog) && this.appPeersManager.isForum(dialog.peerId)) {
const forumUnreadCount = this.dialogsStorage.getForumUnreadCount(dialog.peerId);
if(forumUnreadCount instanceof Promise) {
unreadCount = 0;
} else {
unreadCount = forumUnreadCount.count;
}
}
return unreadCount || +!!(dialog as Dialog).pFlags.unread_mark;
}
public isDialogUnread(dialog: Dialog | ForumTopic) {

View File

@ -271,7 +271,7 @@ export class CustomEmojiRendererElement extends HTMLElement {
return;
}
this.destroy();
this.destroy?.();
this.disconnectedCallback = undefined;
}

View File

@ -27,6 +27,7 @@ import {IS_WORKER} from '../helpers/context';
export type BroadcastEvents = {
'chat_full_update': ChatId,
'chat_update': ChatId,
'chat_toggle_forum': {chatId: ChatId, enabled: boolean},
'channel_update': ChatId,

View File

@ -142,8 +142,7 @@ export default class DialogsStorage extends AppManager {
});
this.rootScope.addEventListener('dialog_notify_settings', (dialog) => {
this.processDialogForFilters(dialog);
this.prepareDialogUnreadCountModifying(dialog)();
this.processChangedUnreadOrUnmuted(dialog.peerId);
});
this.rootScope.addEventListener('chat_update', (chatId) => {
@ -155,6 +154,15 @@ export default class DialogsStorage extends AppManager {
}
});
this.rootScope.addEventListener('chat_toggle_forum', ({chatId, enabled}) => {
const peerId = chatId.toPeerId(true);
if(!enabled) {
this.flushForumTopicsCache(peerId);
}
this.processChangedUnreadOrUnmuted(peerId);
});
this.apiUpdatesManager.addMultipleEventsListeners({
updateFolderPeers: this.onUpdateFolderPeers,
@ -592,7 +600,7 @@ export default class DialogsStorage extends AppManager {
return false;
}
if((!wasDialogIndex && newDialogIndex) || (wasIndex && !newDialogIndex)) {
if(!!wasDialogIndex !== !!newDialogIndex) {
this.prepareFolderUnreadCountModifyingByDialog(folderId, dialog, !!newDialogIndex);
}
@ -607,24 +615,24 @@ export default class DialogsStorage extends AppManager {
return true;
}
public prepareDialogUnreadCountModifying(dialog: Dialog | ForumTopic) {
public prepareDialogUnreadCountModifying(dialog: Dialog | ForumTopic, toggle?: boolean) {
const isTopic = this.isTopic(dialog);
const callbacks: NoneToVoidFunction[] = [];
const folderId = isTopic ? this.getFilterIdForForum(dialog) : dialog.folder_id;
callbacks.push(this.prepareFolderUnreadCountModifyingByDialog(folderId, dialog));
callbacks.push(this.prepareFolderUnreadCountModifyingByDialog(folderId, dialog, toggle));
if(!isTopic) {
const filters = this.filtersStorage.getFilters();
for(const id in filters) {
const filter = filters[id];
if(this.filtersStorage.testDialogForFilter(dialog, filter)) {
callbacks.push(this.prepareFolderUnreadCountModifyingByDialog(filter.id, dialog));
callbacks.push(this.prepareFolderUnreadCountModifyingByDialog(filter.id, dialog, toggle));
}
}
}
return () => callbacks.forEach((callback) => callback());
return () => !toggle && callbacks.forEach((callback) => callback());
}
public prepareFolderUnreadCountModifyingByDialog(folderId: number, dialog: Dialog | ForumTopic, toggle?: boolean) {
@ -653,6 +661,35 @@ export default class DialogsStorage extends AppManager {
toggleUnmuted: boolean,
dialog: Dialog | ForumTopic
) {
const {peerId} = dialog;
const isForum = this.appPeersManager.isForum(peerId);
const isTopic = this.isTopic(dialog);
if(isForum && !isTopic) {
const forumUnreadCount = this.getForumUnreadCount(peerId);
if(forumUnreadCount instanceof Promise) {
forumUnreadCount.then(({count, hasUnmuted}) => {
dialog = this.getDialogOnly(peerId);
const folder = this.getFolder(folderId);
if(
!dialog ||
!this.appPeersManager.isForum(peerId) ||
!folder ||
!folder.dialogs.some((dialog) => dialog.peerId === peerId)
) {
return;
}
this.modifyFolderUnreadCount(folderId, 0, false, false, dialog);
});
return;
} else {
addMessagesCount = 0;
toggleDialog = forumUnreadCount.count > 0;
toggleUnmuted = forumUnreadCount.hasUnmuted;
}
}
const folder = this.getFolder(folderId);
if(addMessagesCount) {
folder.unreadMessagesCount = Math.max(0, folder.unreadMessagesCount + addMessagesCount);
@ -671,18 +708,30 @@ export default class DialogsStorage extends AppManager {
folder.unreadUnmutedPeerIds.delete(key);
}
// if(this.isTopic(dialog)) {
// return;
// }
folder.dispatchUnreadTimeout ??= ctx.setTimeout(() => {
folder.dispatchUnreadTimeout = undefined;
const _folder = {...folder};
delete _folder.dialogs;
this.rootScope.dispatchEvent('folder_unread', _folder);
if(isTopic) { // * refresh forum dialog unread count
this.processChangedUnreadOrUnmuted(peerId);
}
}, 0);
}
public processChangedUnreadOrUnmuted(peerId: PeerId) {
const dialog = this.getDialogOnly(peerId);
if(dialog) {
this.processDialogForFilters(dialog);
this.prepareDialogUnreadCountModifying(dialog)();
this.rootScope.dispatchEvent('dialog_unread', {
peerId,
dialog
});
}
}
public generateIndexForDialog(
dialog: Dialog | ForumTopic,
justReturn?: boolean,
@ -1169,10 +1218,6 @@ export default class DialogsStorage extends AppManager {
dialog.peerId = peerId;
// dialog.indexes ??= {} as any;
// if(dialog.peerId === -) {
// debugger;
// }
// Because we saved message without dialog present
if(message && message.pFlags.is_outgoing) {
const isOut = message.pFlags.out;