Fix loading dialogs

Fix showing chat where user is kicked
Don't save dialogs offset if it's an update
This commit is contained in:
Eduard Kuzmenko 2021-06-29 04:19:53 +03:00
parent 892ff839c0
commit bb420d6a50
5 changed files with 126 additions and 71 deletions

3
src/layer.d.ts vendored
View File

@ -1231,7 +1231,8 @@ export namespace Dialog {
folder_id?: number,
index?: number,
peerId?: number,
topMessage?: any
topMessage?: any,
migratedTo?: number
};
export type dialogFolder = {

View File

@ -326,35 +326,34 @@ export class AppDialogsManager {
});
rootScope.addEventListener('state_cleared', () => {
appUsersManager.clear();
appChatsManager.clear();
const filtersStorage = appMessagesManager.filtersStorage;
const filters = filtersStorage.filters;
for(const filterId in filters) { // delete filters
rootScope.dispatchEvent('updateDialogFilter', {
_: 'updateDialogFilter',
id: +filterId,
});
}
//setTimeout(() =>
appStateManager.getState().then((state) => {
appUsersManager.clear();
appChatsManager.clear();
const filtersStorage = appMessagesManager.filtersStorage;
const filters = filtersStorage.filters;
for(const filterId in filters) { // delete filters
rootScope.dispatchEvent('updateDialogFilter', {
_: 'updateDialogFilter',
id: +filterId,
});
}
appMessagesManager.clear();
appMessagesManager.clear();
/* const clearPromises: Promise<any>[] = [];
for(const name in appStateManager.storagesResults) {
const results = appStateManager.storagesResults[name as keyof AppStateManager['storages']];
const storage = appStateManager.storages[name as keyof AppStateManager['storages']];
results.length = 0;
clearPromises.push(storage.clear());
} */
/* const clearPromises: Promise<any>[] = [];
for(const name in appStateManager.storagesResults) {
const results = appStateManager.storagesResults[name as keyof AppStateManager['storages']];
const storage = appStateManager.storages[name as keyof AppStateManager['storages']];
results.length = 0;
clearPromises.push(storage.clear());
} */
this.validateForFilter();
this.validateForFilter();
Promise.all([
appStateManager.getState(),
//Promise.all(clearPromises)
]).then(([state]) => {
this.onStateLoaded(state);
});
})//, 5000);
});
const foldersScrollable = new ScrollableX(this.folders.menuScrollContainer);
@ -450,6 +449,7 @@ export class AppDialogsManager {
}
private isDialogMustBeInViewport(dialog: Dialog) {
if(dialog.migratedTo !== undefined) return false;
//return true;
const topOffset = this.getOffset('top');
const bottomOffset = this.getOffset('bottom');
@ -636,8 +636,10 @@ export class AppDialogsManager {
this.showFiltersPromise = new Promise<void>((resolve) => {
window.setTimeout(() => {
this.showFiltersPromise = undefined;
this.folders.menuScrollContainer.classList.remove('hide');
this.setFiltersUnreadCount();
if(Object.keys(this.filtersRendered).length > 1) {
this.folders.menuScrollContainer.classList.remove('hide');
this.setFiltersUnreadCount();
}
resolve();
}, 0);
});
@ -661,14 +663,13 @@ export class AppDialogsManager {
const filterId = this.filterId;
let loadCount = 30/*this.chatsLoadCount */;
const storage = appMessagesManager.dialogsStorage.getFolder(filterId);
let offsetIndex = 0;
if(side === 'top') {
const element = this.chatList.firstElementChild as HTMLElement;
if(element) {
const peerId = +element.dataset.peerId;
const storage = appMessagesManager.dialogsStorage.getFolder(filterId);
const index = storage.findIndex(dialog => dialog.peerId === peerId);
const needIndex = Math.max(0, index - loadCount);
loadCount = index - needIndex;
@ -678,7 +679,7 @@ export class AppDialogsManager {
const element = this.chatList.lastElementChild as HTMLElement;
if(element) {
const peerId = +element.dataset.peerId;
const dialog = storage.find(dialog => dialog.peerId === peerId);
const dialog = appMessagesManager.getDialogOnly(peerId);
offsetIndex = dialog.index;
}
}
@ -1210,7 +1211,7 @@ export class AppDialogsManager {
const peerId: number = dialog.peerId;
if(container === undefined) {
if(this.doms[peerId]) return;
if(this.doms[peerId] || dialog.migratedTo !== undefined) return;
const filter = appMessagesManager.filtersStorage.filters[this.filterId];
if((filter && !appMessagesManager.filtersStorage.testDialogForFilter(dialog, filter)) || (!filter && this.filterId !== dialog.folder_id)) {

View File

@ -54,6 +54,8 @@ import htmlToSpan from "../../helpers/dom/htmlToSpan";
import { REPLIES_PEER_ID } from "../mtproto/mtproto_config";
import formatCallDuration from "../../helpers/formatCallDuration";
import appAvatarsManager from "./appAvatarsManager";
import telegramMeWebManager from "../mtproto/telegramMeWebManager";
import { getMiddleware } from "../../helpers/middleware";
//console.trace('include');
// TODO: если удалить сообщение в непрогруженном диалоге, то при обновлении, из-за стейта, последнего сообщения в чатлисте не будет
@ -196,6 +198,8 @@ export class AppMessagesManager {
private typings: {[peerId: string]: {type: SendMessageAction['_'], timeout?: number}} = {};
private middleware: ReturnType<typeof getMiddleware>;
constructor() {
this.clear();
@ -310,6 +314,12 @@ export class AppMessagesManager {
}
public clear() {
if(this.middleware) {
this.middleware.clean();
} else {
this.middleware = getMiddleware();
}
this.messagesStorageByPeerId = {};
this.groupedMessagesStorage = {};
this.scheduledMessagesStorage = {};
@ -1575,7 +1585,7 @@ export class AppMessagesManager {
for(let folderId = 0; folderId < 2; ++folderId) {
let offsetDate = 0;
for(;;) {
const {dialogs} = await appMessagesManager.getTopMessages(limit, folderId, offsetDate);
const {dialogs, isEnd} = await this.getTopMessages(limit, folderId, offsetDate);
if(dialogs.length) {
outDialogs.push(...dialogs as Dialog[]);
@ -1590,7 +1600,9 @@ export class AppMessagesManager {
console.error('refreshConversations: got no offsetDate', dialog);
break;
}
} else {
}
if(isEnd) {
break;
}
}
@ -1642,8 +1654,9 @@ export class AppMessagesManager {
}
}
public lolSet = new Set();
public getTopMessages(limit: number, folderId: number, offsetDate?: number) {
const dialogs = this.dialogsStorage.getFolder(folderId);
//const dialogs = this.dialogsStorage.getFolder(folderId);
let offsetId = 0;
let offsetPeerId = 0;
let offsetIndex = 0;
@ -1657,6 +1670,8 @@ export class AppMessagesManager {
offsetDate += serverTimeManager.serverTimeOffset;
}
const middleware = this.middleware.get();
// ! ВНИМАНИЕ: ОЧЕНЬ СЛОЖНАЯ ЛОГИКА:
// ! если делать запрос сначала по папке 0, потом по папке 1, по индексу 0 в массиве будет один и тот же диалог, с dialog.pFlags.pinned, ЛОЛ???
// ! т.е., с запросом folder_id: 1, и exclude_pinned: 0, в результате будут ещё и закреплённые с папки 0
@ -1671,7 +1686,7 @@ export class AppMessagesManager {
//timeout: APITIMEOUT,
noErrorBox: true
}).then((dialogsResult) => {
if(dialogsResult._ === 'messages.dialogsNotModified') return null;
if(!middleware() || dialogsResult._ === 'messages.dialogsNotModified') return null;
if(DEBUG) {
this.log('messages.getDialogs result:', dialogsResult.dialogs, {...dialogsResult.dialogs[0]});
@ -1681,11 +1696,15 @@ export class AppMessagesManager {
telegramMeWebService.setAuthorized(true);
} */
// can reset here pinned order
// can reset pinned order here
if(!offsetId && !offsetDate && !offsetPeerId) {
this.dialogsStorage.resetPinnedOrder(folderId);
}
if(!offsetDate) {
telegramMeWebManager.setAuthorized(true);
}
appUsersManager.saveApiUsers(dialogsResult.users);
appChatsManager.saveApiChats(dialogsResult.chats);
this.saveMessages(dialogsResult.messages);
@ -1696,10 +1715,10 @@ export class AppMessagesManager {
forEachReverse((dialogsResult.dialogs as Dialog[]), dialog => {
//const d = Object.assign({}, dialog);
// ! нужно передавать folderId, так как по папке !== 0 нет свойства folder_id
this.dialogsStorage.saveDialog(dialog, dialog.folder_id ?? folderId);
this.dialogsStorage.saveDialog(dialog, dialog.folder_id ?? folderId, true);
if(!maxSeenIdIncremented &&
!appPeersManager.isChannel(appPeersManager.getPeerId(dialog.peer))) {
!appPeersManager.isChannel(dialog.peerId || appPeersManager.getPeerId(dialog.peer))) {
this.incrementMaxSeenId(dialog.top_message);
maxSeenIdIncremented = true;
}
@ -1708,6 +1727,10 @@ export class AppMessagesManager {
return;
}
if(!folderId && !dialog.folder_id) {
this.lolSet.add(dialog.peerId);
}
/* if(dialog.peerId === -1213511294) {
this.log.error('lun bot', folderId, d);
} */
@ -1744,9 +1767,20 @@ export class AppMessagesManager {
const count = (dialogsResult as MessagesDialogs.messagesDialogsSlice).count;
if(limit > dialogsResult.dialogs.length ||
// exclude empty draft dialogs
const dialogs = this.dialogsStorage.getFolder(folderId);
let dialogsLength = 0;
for(let i = 0, length = dialogs.length; i < length; ++i) {
if(this.getServerMessageId(dialogs[i].top_message)) {
++dialogsLength;
}
}
const isEnd = /* limit > dialogsResult.dialogs.length || */
!count ||
dialogs.length >= count) {
dialogsLength >= count ||
!dialogsResult.dialogs.length;
if(isEnd) {
this.dialogsStorage.setDialogsLoaded(folderId, true);
}
@ -1756,7 +1790,11 @@ export class AppMessagesManager {
rootScope.dispatchEvent('dialogs_multiupdate', {});
}
return dialogsResult;
return {
isEnd,
count,
dialogs: (dialogsResult as MessagesDialogs.messagesDialogsSlice).dialogs
};
});
}
@ -1914,13 +1952,15 @@ export class AppMessagesManager {
return this.dialogsStorage.getDialogOnly(peerId);
}
public reloadConversation(peerId: number | number[]) {
[].concat(peerId).forEach(peerId => {
if(!this.reloadConversationsPeers.has(peerId)) {
this.reloadConversationsPeers.add(peerId);
//this.log('will reloadConversation', peerId);
}
});
public reloadConversation(peerId?: number | number[]) {
if(peerId !== undefined) {
[].concat(peerId).forEach(peerId => {
if(!this.reloadConversationsPeers.has(peerId)) {
this.reloadConversationsPeers.add(peerId);
//this.log('will reloadConversation', peerId);
}
});
}
if(this.reloadConversationsPromise) return this.reloadConversationsPromise;
return this.reloadConversationsPromise = new Promise((resolve, reject) => {
@ -1933,13 +1973,17 @@ export class AppMessagesManager {
resolve();
}, reject).finally(() => {
this.reloadConversationsPromise = null;
if(this.reloadConversationsPeers.size) {
this.reloadConversation();
}
});
}, 0);
});
}
private doFlushHistory(inputPeer: any, justClear?: boolean, revoke?: boolean): Promise<true> {
return apiManager.invokeApi('messages.deleteHistory', {
return apiManager.invokeApiSingle('messages.deleteHistory', {
just_clear: justClear,
revoke: revoke,
peer: inputPeer,
@ -1959,7 +2003,7 @@ export class AppMessagesManager {
}
return this.doFlushHistory(inputPeer, justClear);
})
});
}
public async flushHistory(peerId: number, justClear?: boolean, revoke?: boolean) {
@ -1970,7 +2014,7 @@ export class AppMessagesManager {
const channelId = -peerId;
const maxId = historyResult.history[0] || 0;
return apiManager.invokeApi('channels.deleteHistory', {
return apiManager.invokeApiSingle('channels.deleteHistory', {
channel: appChatsManager.getChannelInput(channelId),
max_id: maxId
}).then(() => {
@ -2045,7 +2089,7 @@ export class AppMessagesManager {
}
public unpinAllMessages(peerId: number): Promise<boolean> {
return apiManager.invokeApi('messages.unpinAllMessages', {
return apiManager.invokeApiSingle('messages.unpinAllMessages', {
peer: appPeersManager.getInputPeerById(peerId)
}).then(affectedHistory => {
apiUpdatesManager.processUpdateMessage({

View File

@ -94,7 +94,7 @@ export default class DialogsStorage {
this.appMessagesManager.saveMessages([dialog.topMessage]);
}
this.saveDialog(dialog);
this.saveDialog(dialog, undefined, true);
// ! WARNING, убрать это когда нужно будет делать чтобы pending сообщения сохранялись
const message = this.appMessagesManager.getMessageByPeer(dialog.peerId, dialog.top_message);
@ -180,7 +180,7 @@ export default class DialogsStorage {
return dialogs.map(d => d.dialog);
}
public getDialog(peerId: number, folderId?: number): [Dialog, number] | [] {
public getDialog(peerId: number, folderId?: number, skipMigrated = true): [Dialog, number] | [] {
const folders: Dialog[][] = [];
if(folderId === undefined) {
@ -193,9 +193,14 @@ export default class DialogsStorage {
}
for(let folder of folders) {
const index = folder.findIndex(dialog => dialog.peerId === peerId);
if(index !== -1) {
return [folder[index], index];
let i = 0, skipped = 0;
for(let length = folder.length; i < length; ++i) {
const dialog = folder[i];
if(dialog.peerId === peerId) {
return [dialog, i - skipped];
} else if(skipMigrated && dialog.migratedTo !== undefined) {
++skipped;
}
}
}
@ -272,7 +277,7 @@ export default class DialogsStorage {
return this.generateDialogPinnedDateByIndex(pinnedIndex);
}
public generateDialog(peerId: number) {
/* public generateDialog(peerId: number) {
const dialog: Dialog = {
_: 'dialog',
pFlags: {},
@ -288,7 +293,7 @@ export default class DialogsStorage {
};
return dialog;
}
} */
public setDialogToState(dialog: Dialog) {
const historyStorage = this.appMessagesManager.getHistoryStorage(dialog.peerId);
@ -427,11 +432,11 @@ export default class DialogsStorage {
/**
* Won't save migrated from peer, forbidden peers, left and kicked
*/
public saveDialog(dialog: Dialog, folderId = 0) {
public saveDialog(dialog: Dialog, folderId = 0, saveOffset = false) {
const peerId = this.appPeersManager.getPeerId(dialog.peer);
if(!peerId) {
console.error('saveConversation no peerId???', dialog, folderId);
return false;
return;
}
if(dialog._ !== 'dialog'/* || peerId === 239602833 */) {
@ -442,8 +447,9 @@ export default class DialogsStorage {
if(peerId < 0) {
const chat: Chat = this.appChatsManager.getChat(-peerId);
if(chat._ === 'channelForbidden' || chat._ === 'chatForbidden' || (chat as Chat.chat).pFlags.left || (chat as Chat.chat).pFlags.kicked) {
return false;
// ! chatForbidden stays for chat where you're kicked
if(chat._ === 'channelForbidden' /* || chat._ === 'chatForbidden' */ || (chat as Chat.chat).pFlags.left || (chat as Chat.chat).pFlags.kicked) {
return;
}
}
@ -480,7 +486,8 @@ export default class DialogsStorage {
const migratedToPeer = this.appPeersManager.getPeerId(chat.migrated_to);
this.appMessagesManager.migratedFromTo[peerId] = migratedToPeer;
this.appMessagesManager.migratedToFrom[migratedToPeer] = peerId;
return;
dialog.migratedTo = migratedToPeer;
//return;
}
}
@ -538,7 +545,7 @@ export default class DialogsStorage {
safeReplaceObject(wasDialogBefore, dialog);
}
this.pushDialog(dialog, message.date);
this.pushDialog(dialog, saveOffset && message.date);
}
public getDialogs(query = '', offsetIndex?: number, limit = 20, folderId = 0) {
@ -589,7 +596,7 @@ export default class DialogsStorage {
});
}
return this.appMessagesManager.getTopMessages(limit, realFolderId).then(messagesDialogs => {
return this.appMessagesManager.getTopMessages(limit, realFolderId).then(result => {
//const curDialogStorage = this[folderId];
offset = 0;
@ -605,8 +612,9 @@ export default class DialogsStorage {
return {
dialogs: curDialogStorage.slice(offset, offset + limit),
count: messagesDialogs._ === 'messages.dialogs' ? messagesDialogs.dialogs.length : messagesDialogs.count,
isEnd: this.isDialogsLoaded(realFolderId) && (offset + limit) >= curDialogStorage.length
count: result.count === undefined ? curDialogStorage.length : result.count,
// isEnd: this.isDialogsLoaded(realFolderId) && (offset + limit) >= curDialogStorage.length
isEnd: result.isEnd
};
});
}

View File

@ -29,7 +29,8 @@
"params": [
{"name": "index", "type": "number"},
{"name": "peerId", "type": "number"},
{"name": "topMessage", "type": "any"}
{"name": "topMessage", "type": "any"},
{"name": "migratedTo", "type": "number"}
]
}, {
"predicate": "dialogFolder",