Some new layer fixes

Fix reading new messages by scrolling
This commit is contained in:
morethanwords 2020-10-03 03:35:26 +03:00
parent a25b5e9823
commit e76942d0bb
7 changed files with 108 additions and 112 deletions

4
src/layer.d.ts vendored
View File

@ -1196,7 +1196,9 @@ export namespace PhotoSize {
location: FileLocation, location: FileLocation,
w: number, w: number,
h: number, h: number,
sizes: Array<number> sizes: Array<number>,
url?: string,
size?: number
}; };
} }

View File

@ -129,7 +129,7 @@ export class ApiUpdatesManager {
} }
} }
public processUpdateMessage(updateMessage: any) { processUpdateMessage = (updateMessage: any) => {
// return forceGetDifference() // return forceGetDifference()
var processOpts = { var processOpts = {
date: updateMessage.date, date: updateMessage.date,
@ -190,7 +190,7 @@ export class ApiUpdatesManager {
default: default:
this.log.warn('Unknown update message', updateMessage); this.log.warn('Unknown update message', updateMessage);
} }
} };
public getDifference() { public getDifference() {
// this.trace('Get full diff') // this.trace('Get full diff')
@ -534,7 +534,7 @@ export class ApiUpdatesManager {
appStateManager.getState().then(_state => { appStateManager.getState().then(_state => {
const state = _state.updates; const state = _state.updates;
apiManager.setUpdatesProcessor(this.processUpdateMessage.bind(this)); apiManager.setUpdatesProcessor(this.processUpdateMessage);
if(!state || !state.pts || !state.date || !state.seq) { if(!state || !state.pts || !state.date || !state.seq) {
apiManager.invokeApi('updates.getState', {}, {noErrorBox: true}).then((stateResult) => { apiManager.invokeApi('updates.getState', {}, {noErrorBox: true}).then((stateResult) => {

View File

@ -153,7 +153,7 @@ export class AppImManager {
constructor() { constructor() {
apiUpdatesManager.attach(); apiUpdatesManager.attach();
this.log = logger('IM', LogLevels.log | LogLevels.warn | LogLevels.debug | LogLevels.error); this.log = logger('IM', LogLevels.log | LogLevels.warn | LogLevels.debug | LogLevels.error);
this.chatInputC = new ChatInput(); this.chatInputC = new ChatInput();
this.preloader = new ProgressivePreloader(null, false); this.preloader = new ProgressivePreloader(null, false);
@ -679,7 +679,7 @@ export class AppImManager {
}); });
this.unreadedObserver = new IntersectionObserver((entries) => { this.unreadedObserver = new IntersectionObserver((entries) => {
if(this.offline) { if(this.offline) { // ! but you can scroll the page without triggering 'focus', need something now
return; return;
} }
@ -714,9 +714,9 @@ export class AppImManager {
} */ } */
//appMessagesManager.readMessages(readed); //appMessagesManager.readMessages(readed);
/* false && */ appMessagesManager.readHistory(this.peerID, max, length).catch((err: any) => { /* false && */ appMessagesManager.readHistory(this.peerID, max).catch((err: any) => {
this.log.error('readHistory err:', err); this.log.error('readHistory err:', err);
appMessagesManager.readHistory(this.peerID, max, length); appMessagesManager.readHistory(this.peerID, max);
}); });
} }
}); });

View File

@ -1,4 +1,4 @@
import { copy, tsNow, safeReplaceObject, listMergeSorted, deepEqual, langPack } from "../utils"; import { copy, tsNow, safeReplaceObject, listMergeSorted, deepEqual, langPack, getObjectKeysAndSort } from "../utils";
import appMessagesIDsManager from "./appMessagesIDsManager"; import appMessagesIDsManager from "./appMessagesIDsManager";
import appChatsManager from "./appChatsManager"; import appChatsManager from "./appChatsManager";
import appUsersManager from "./appUsersManager"; import appUsersManager from "./appUsersManager";
@ -41,6 +41,7 @@ export type HistoryStorage = {
pending: number[], pending: number[],
readPromise?: Promise<boolean>, readPromise?: Promise<boolean>,
readMaxID?: number,
maxOutID?: number, maxOutID?: number,
reply_markup?: any reply_markup?: any
}; };
@ -477,6 +478,7 @@ type MyInputMessagesFilter = 'inputMessagesFilterEmpty'
export class AppMessagesManager { export class AppMessagesManager {
public messagesStorage: {[mid: string]: any} = {}; public messagesStorage: {[mid: string]: any} = {};
public messagesStorageByPeerID: {[peerID: string]: AppMessagesManager['messagesStorage']} = {};
public groupedMessagesStorage: {[groupID: string]: any} = {}; // will be used for albums public groupedMessagesStorage: {[groupID: string]: any} = {}; // will be used for albums
public historiesStorage: { public historiesStorage: {
[peerID: string]: HistoryStorage [peerID: string]: HistoryStorage
@ -521,7 +523,7 @@ export class AppMessagesManager {
dialogs: [] dialogs: []
}; };
private log = logger('MESSAGES', LogLevels.error); private log = logger('MESSAGES'/* , LogLevels.error */);
public dialogsStorage = new DialogsStorage(); public dialogsStorage = new DialogsStorage();
public filtersStorage = new FiltersStorage(); public filtersStorage = new FiltersStorage();
@ -2130,8 +2132,7 @@ export class AppMessagesManager {
return this.messagesStorage[messageID] || { return this.messagesStorage[messageID] || {
_: 'messageEmpty', _: 'messageEmpty',
id: messageID, id: messageID,
deleted: true, deleted: true
pFlags: {out: false, unread: false}
}; };
} }
@ -2273,7 +2274,6 @@ export class AppMessagesManager {
} }
public saveMessages(apiMessages: any[], options: { public saveMessages(apiMessages: any[], options: {
isNew?: boolean,
isEdited?: boolean isEdited?: boolean
} = {}) { } = {}) {
apiMessages.forEach((apiMessage) => { apiMessages.forEach((apiMessage) => {
@ -2281,14 +2281,6 @@ export class AppMessagesManager {
apiMessage.pFlags = {}; apiMessage.pFlags = {};
} }
if(!apiMessage.pFlags.out) {
apiMessage.pFlags.out = false;
}
if(!apiMessage.pFlags.unread) {
apiMessage.pFlags.unread = false;
}
if(apiMessage._ == 'messageEmpty') { if(apiMessage._ == 'messageEmpty') {
return; return;
} }
@ -2308,11 +2300,11 @@ export class AppMessagesManager {
const dialog = this.getDialogByPeerID(peerID)[0]; const dialog = this.getDialogByPeerID(peerID)[0];
if(dialog && mid > 0) { if(dialog && mid > 0) {
apiMessage.pFlags.unread = mid > dialog[apiMessage.pFlags.out if(mid > dialog[apiMessage.pFlags.out
? 'read_outbox_max_id' ? 'read_outbox_max_id'
: 'read_inbox_max_id']; : 'read_inbox_max_id']) {
} else if(options.isNew) { apiMessage.pFlags.unread = true;
apiMessage.pFlags.unread = true; }
} }
// this.log(dT(), 'msg unread', mid, apiMessage.pFlags.out, dialog && dialog[apiMessage.pFlags.out ? 'read_outbox_max_id' : 'read_inbox_max_id']) // this.log(dT(), 'msg unread', mid, apiMessage.pFlags.out, dialog && dialog[apiMessage.pFlags.out ? 'read_outbox_max_id' : 'read_inbox_max_id'])
@ -2328,7 +2320,7 @@ export class AppMessagesManager {
if(apiMessage.peerID == myID && !apiMessage.from_id && !apiMessage.fwd_from) { if(apiMessage.peerID == myID && !apiMessage.from_id && !apiMessage.fwd_from) {
apiMessage.fromID = myID; apiMessage.fromID = myID;
} else { } else {
apiMessage.fromID = apiMessage.pFlags.post || peerID == myID ? peerID : appPeersManager.getPeerID(apiMessage.from_id); apiMessage.fromID = apiMessage.pFlags.post || (!apiMessage.pFlags.out && !apiMessage.from_id) ? peerID : appPeersManager.getPeerID(apiMessage.from_id);
} }
const fwdHeader = apiMessage.fwd_from; const fwdHeader = apiMessage.fwd_from;
@ -2462,8 +2454,8 @@ export class AppMessagesManager {
case 'messageActionHistoryClear': case 'messageActionHistoryClear':
//apiMessage.deleted = true; //apiMessage.deleted = true;
apiMessage.clear_history = true; apiMessage.clear_history = true;
apiMessage.pFlags.out = false; delete apiMessage.pFlags.out;
apiMessage.pFlags.unread = false; delete apiMessage.pFlags.unread;
break; break;
case 'messageActionPhoneCall': case 'messageActionPhoneCall':
@ -2499,6 +2491,7 @@ export class AppMessagesManager {
if(!options.isEdited) { if(!options.isEdited) {
this.messagesStorage[mid] = apiMessage; this.messagesStorage[mid] = apiMessage;
(this.messagesStorageByPeerID[peerID] ?? (this.messagesStorageByPeerID[peerID] = {}))[mid] = apiMessage;
} }
}); });
} }
@ -2827,7 +2820,7 @@ export class AppMessagesManager {
peer_id: appPeersManager.getOutputPeer(peerID), peer_id: appPeersManager.getOutputPeer(peerID),
deleted: true, deleted: true,
flags: 0, flags: 0,
pFlags: {unread: false, out: true}, pFlags: {out: true},
date: 0, date: 0,
message: '' message: ''
}; };
@ -2866,15 +2859,15 @@ export class AppMessagesManager {
// Because we saved message without dialog present // Because we saved message without dialog present
if(message.mid > 0) { if(message.mid > 0) {
if(message.mid > dialog[message.pFlags.out ? 'read_outbox_max_id' : 'read_inbox_max_id']) message.pFlags.unread = true; if(message.mid > dialog[message.pFlags.out ? 'read_outbox_max_id' : 'read_inbox_max_id']) message.pFlags.unread = true;
else message.pFlags.unread = false; else delete message.pFlags.unread;
} }
if(this.historiesStorage[peerID] === undefined/* && !message.deleted */) { // warning if(this.historiesStorage[peerID] === undefined/* && !message.deleted */) { // warning
const historyStorage: HistoryStorage = {count: null, history: [], pending: []}; const historyStorage: HistoryStorage = {count: null, history: [], pending: []};
historyStorage[mid > 0 ? 'history' : 'pending'].push(mid); historyStorage[mid > 0 ? 'history' : 'pending'].push(mid);
if(mid < 0 && message.pFlags.unread) { /* if(mid < 0 && message.pFlags.unread) {
dialog.unread_count++; dialog.unread_count++;
} } */
this.historiesStorage[peerID] = historyStorage; this.historiesStorage[peerID] = historyStorage;
if(this.mergeReplyKeyboard(historyStorage, message)) { if(this.mergeReplyKeyboard(historyStorage, message)) {
$rootScope.$broadcast('history_reply_markup', {peerID}); $rootScope.$broadcast('history_reply_markup', {peerID});
@ -3291,7 +3284,7 @@ export class AppMessagesManager {
return Promise.all(promises); return Promise.all(promises);
} }
public readHistory(peerID: number, maxID = 0, readLength = 0): Promise<boolean> { public readHistory(peerID: number, maxID = 0) {
// console.trace('start read') // console.trace('start read')
const isChannel = appPeersManager.isChannel(peerID); const isChannel = appPeersManager.isChannel(peerID);
const historyStorage = this.historiesStorage[peerID]; const historyStorage = this.historiesStorage[peerID];
@ -3312,15 +3305,34 @@ export class AppMessagesManager {
} }
} }
if(isChannel) {
maxID = appMessagesIDsManager.getMessageLocalID(maxID);
}
if(!historyStorage.readMaxID || maxID > historyStorage.readMaxID) {
historyStorage.readMaxID = maxID;
}
if(historyStorage.readPromise) { if(historyStorage.readPromise) {
return historyStorage.readPromise; return historyStorage.readPromise;
} }
let apiPromise: any; let apiPromise: Promise<boolean>;
if(isChannel) { if(isChannel) {
apiPromise = apiManager.invokeApi('channels.readHistory', { apiPromise = apiManager.invokeApi('channels.readHistory', {
channel: appChatsManager.getChannelInput(-peerID), channel: appChatsManager.getChannelInput(-peerID),
max_id: maxID max_id: maxID
}).then((res) => {
apiUpdatesManager.processUpdateMessage({
_: 'updateShort',
update: {
_: 'updateReadChannelInbox',
max_id: maxID,
channel_id: -peerID
}
});
return res;
}); });
} else { } else {
apiPromise = apiManager.invokeApi('messages.readHistory', { apiPromise = apiManager.invokeApi('messages.readHistory', {
@ -3335,62 +3347,31 @@ export class AppMessagesManager {
pts_count: affectedMessages.pts_count pts_count: affectedMessages.pts_count
} }
}); });
apiUpdatesManager.processUpdateMessage({
_: 'updateShort',
update: {
_: 'updateReadHistoryInbox',
max_id: maxID,
peer: appPeersManager.getOutputPeer(peerID)
}
});
return true;
}); });
} }
historyStorage.readPromise = apiPromise.then(() => { apiPromise.finally(() => {
let index = -1;
if(maxID != 0 && historyStorage.history.length) {
index = historyStorage.history.indexOf(maxID);
}
let readedLength = 1;
if(historyStorage.history.length && maxID) {
for(let i = index == -1 ? 0 : index, length = historyStorage.history.length; i < length; i++) {
const messageID = historyStorage.history[i];
if(messageID > maxID) continue;
const message = this.messagesStorage[messageID];
if(message && !message.pFlags.out) {
message.pFlags.unread = false;
readedLength++;
//NotificationsManager.cancel('msg' + messageID); // warning
}
}
}
if(foundDialog) {
// this.log('done read history', peerID)
if(historyStorage.history.length) {
////////this.log.warn('readPromise:', index, historyStorage.history[index != -1 ? index : 0]);
foundDialog.read_inbox_max_id = maxID;
}
if(foundDialog.read_inbox_max_id == foundDialog.top_message || foundDialog.read_inbox_max_id == foundDialog.read_outbox_max_id) {
foundDialog.unread_count = 0;
} else {
foundDialog.unread_count = Math.max(foundDialog.unread_count - (readLength || readedLength), 0);
}
this.log('readHistory set unread_count to:', foundDialog.unread_count, foundDialog);
$rootScope.$broadcast('dialog_unread', {peerID: peerID, count: foundDialog.unread_count});
$rootScope.$broadcast('messages_read');
return true;
}
return false;
}).finally(() => {
delete historyStorage.readPromise; delete historyStorage.readPromise;
if(historyStorage.readMaxID > maxID) {
this.readHistory(peerID, historyStorage.readMaxID);
} else {
delete historyStorage.readMaxID;
}
}); });
// NotificationsManager.soundReset(appPeersManager.getPeerString(peerID)) // warning return historyStorage.readPromise = apiPromise;
return historyStorage.readPromise;
} }
public readMessages(messageIDs: number[]) { public readMessages(messageIDs: number[]) {
@ -3465,10 +3446,10 @@ export class AppMessagesManager {
var message = update.message; var message = update.message;
var peerID = this.getMessagePeer(message); var peerID = this.getMessagePeer(message);
var historyStorage = this.historiesStorage[peerID]; var historyStorage = this.historiesStorage[peerID];
var foundDialog = this.getDialogByPeerID(peerID); let foundDialog = this.getDialogByPeerID(peerID);
if(!foundDialog.length) { if(!foundDialog.length) {
this.newDialogsToHandle[peerID] = {reload: true} this.newDialogsToHandle[peerID] = {reload: true};
this.scheduleHandleNewDialogs(); this.scheduleHandleNewDialogs();
if(this.newUpdatesAfterReloadToHandle[peerID] === undefined) { if(this.newUpdatesAfterReloadToHandle[peerID] === undefined) {
this.newUpdatesAfterReloadToHandle[peerID] = []; this.newUpdatesAfterReloadToHandle[peerID] = [];
@ -3484,7 +3465,7 @@ export class AppMessagesManager {
} }
} }
this.saveMessages([message], {isNew: true}); this.saveMessages([message]);
// this.log.warn(dT(), 'message unread', message.mid, message.pFlags.unread) // this.log.warn(dT(), 'message unread', message.mid, message.pFlags.unread)
if(historyStorage === undefined) { if(historyStorage === undefined) {
@ -3755,17 +3736,14 @@ export class AppMessagesManager {
case 'updateReadHistoryOutbox': case 'updateReadHistoryOutbox':
case 'updateReadChannelInbox': case 'updateReadChannelInbox':
case 'updateReadChannelOutbox': { case 'updateReadChannelOutbox': {
var isOut = update._ == 'updateReadHistoryOutbox' || update._ == 'updateReadChannelOutbox'; const channelID: number = update.channel_id;
var channelID: number = update.channel_id; const maxID = appMessagesIDsManager.getFullMessageID(update.max_id, channelID);
var maxID = appMessagesIDsManager.getFullMessageID(update.max_id, channelID); const peerID = channelID ? -channelID : appPeersManager.getPeerID(update.peer);
var peerID = channelID ? -channelID : appPeersManager.getPeerID(update.peer); const isOut = update._ == 'updateReadHistoryOutbox' || update._ == 'updateReadChannelOutbox' ? true : undefined;
var foundDialog = this.getDialogByPeerID(peerID); const foundDialog = this.getDialogByPeerID(peerID)[0];
var history = (this.historiesStorage[peerID] || {}).history || []; const history = getObjectKeysAndSort(this.messagesStorageByPeerID[peerID] || {}, 'desc');
var newUnreadCount = 0; let newUnreadCount = 0;
var length = history.length; let foundAffected = false;
var foundAffected = false;
var messageID: number, message;
var i;
//this.log.warn(dT(), 'read', peerID, isOut ? 'out' : 'in', maxID) //this.log.warn(dT(), 'read', peerID, isOut ? 'out' : 'in', maxID)
@ -3773,13 +3751,13 @@ export class AppMessagesManager {
appUsersManager.forceUserOnline(peerID); appUsersManager.forceUserOnline(peerID);
} }
for(i = 0; i < length; i++) { for(let i = 0, length = history.length; i < length; i++) {
messageID = history[i]; const messageID = history[i];
if(messageID > maxID) { if(messageID > maxID) {
continue; continue;
} }
message = this.messagesStorage[messageID]; const message = this.messagesStorage[messageID];
if(!message) { if(!message) {
continue; continue;
} }
@ -3787,36 +3765,39 @@ export class AppMessagesManager {
if(message.pFlags.out != isOut) { if(message.pFlags.out != isOut) {
continue; continue;
} }
if(!message.pFlags.unread) { if(!message.pFlags.unread) {
break; break;
} }
// this.log.warn('read', messageID, message.pFlags.unread, message) // this.log.warn('read', messageID, message.pFlags.unread, message)
if(message && message.pFlags.unread) { if(message && message.pFlags.unread) {
message.pFlags.unread = false delete message.pFlags.unread;
if(!foundAffected) { if(!foundAffected) {
foundAffected = true; foundAffected = true;
} }
if(!message.pFlags.out) { if(!message.pFlags.out) {
if(foundDialog[0]) { if(foundDialog) {
newUnreadCount = --foundDialog[0].unread_count; newUnreadCount = --foundDialog.unread_count;
} }
//NotificationsManager.cancel('msg' + messageID); // warning //NotificationsManager.cancel('msg' + messageID); // warning
} }
} }
} }
if(foundDialog[0]) {
if(!isOut && newUnreadCount && foundDialog[0].top_message <= maxID) { if(foundDialog) {
newUnreadCount = foundDialog[0].unread_count = 0; if(!isOut && newUnreadCount && foundDialog.top_message <= maxID) {
newUnreadCount = foundDialog.unread_count = 0;
} }
foundDialog[0][isOut ? 'read_outbox_max_id' : 'read_inbox_max_id'] = maxID; foundDialog[isOut ? 'read_outbox_max_id' : 'read_inbox_max_id'] = maxID;
} }
// need be commented for read out messages // need be commented for read out messages
//if(newUnreadCount != 0 || !isOut) { // fix 16.11.2019 (maybe not) //if(newUnreadCount != 0 || !isOut) { // fix 16.11.2019 (maybe not)
//////////this.log.warn(dT(), 'cnt', peerID, newUnreadCount, isOut, foundDialog, update, foundAffected); //////////this.log.warn(dT(), 'cnt', peerID, newUnreadCount, isOut, foundDialog, update, foundAffected);
$rootScope.$broadcast('dialog_unread', {peerID: peerID, count: newUnreadCount}); $rootScope.$broadcast('dialog_unread', {peerID, count: newUnreadCount});
//} //}
if(foundAffected) { if(foundAffected) {

View File

@ -57,6 +57,13 @@ export class AppPhotosManager {
referenceDatabase.saveContext(photo.file_reference, context); referenceDatabase.saveContext(photo.file_reference, context);
} }
if(photo.sizes?.length) {
const size = photo.sizes[photo.sizes.length - 1];
if(size._ == 'photoSizeProgressive') {
size.size = size.sizes[size.sizes.length - 1];
}
}
if(oldPhoto) { if(oldPhoto) {
return Object.assign(oldPhoto, photo); return Object.assign(oldPhoto, photo);
} }
@ -220,7 +227,7 @@ export class AppPhotosManager {
} }
// maybe it's a thumb // maybe it's a thumb
const isPhoto = photoSize._ == 'photoSize' && photo.access_hash && photo.file_reference; const isPhoto = (photoSize._ == 'photoSize' || photoSize._ == 'photoSizeProgressive') && photo.access_hash && photo.file_reference;
const location: InputFileLocation.inputPhotoFileLocation | InputFileLocation.inputDocumentFileLocation | FileLocation = isPhoto ? { const location: InputFileLocation.inputPhotoFileLocation | InputFileLocation.inputDocumentFileLocation | FileLocation = isPhoto ? {
_: isMyDocument ? 'inputDocumentFileLocation' : 'inputPhotoFileLocation', _: isMyDocument ? 'inputDocumentFileLocation' : 'inputPhotoFileLocation',
id: photo.id, id: photo.id,
@ -309,7 +316,7 @@ export class AppPhotosManager {
public savePhotoFile(photo: MyPhoto | MyDocument) { public savePhotoFile(photo: MyPhoto | MyDocument) {
const fullPhotoSize = this.choosePhotoSize(photo, 0xFFFF, 0xFFFF); const fullPhotoSize = this.choosePhotoSize(photo, 0xFFFF, 0xFFFF);
if(fullPhotoSize._ != 'photoSize') { if(!(fullPhotoSize._ == 'photoSize' || fullPhotoSize._ == 'photoSizeProgressive')) {
return; return;
} }

View File

@ -241,7 +241,7 @@ export class ApiManager {
.then(resolve, (error: ApiError) => { .then(resolve, (error: ApiError) => {
//if(!options.ignoreErrors) { //if(!options.ignoreErrors) {
if(error.type != 'FILE_REFERENCE_EXPIRED') { if(error.type != 'FILE_REFERENCE_EXPIRED') {
this.log.error('Error', error.code, error.type, this.baseDcID, dcID); this.log.error('Error', error.code, error.type, this.baseDcID, dcID, method, params);
} }
if(error.code == 401 && this.baseDcID == dcID) { if(error.code == 401 && this.baseDcID == dcID) {

View File

@ -41,6 +41,12 @@
"params": [ "params": [
{"name": "url", "type": "string"} {"name": "url", "type": "string"}
] ]
}, {
"predicate": "photoSizeProgressive",
"params": [
{"name": "url", "type": "string"},
{"name": "size", "type": "number"}
]
}, { }, {
"predicate": "dialog", "predicate": "dialog",
"params": [ "params": [