Browse Source

alpha state fix

master
morethanwords 3 years ago
parent
commit
d132ef290a
  1. 27
      src/lib/appManagers/apiUpdatesManager.ts
  2. 17
      src/lib/appManagers/appChatsManager.ts
  3. 9
      src/lib/appManagers/appDialogsManager.ts
  4. 6
      src/lib/appManagers/appDraftsManager.ts
  5. 105
      src/lib/appManagers/appMessagesManager.ts
  6. 58
      src/lib/appManagers/appStateManager.ts
  7. 41
      src/lib/appManagers/appUsersManager.ts
  8. 4
      src/lib/storage.ts
  9. 45
      src/lib/storages/dialogs.ts
  10. 18
      src/lib/storages/filters.ts
  11. 1
      src/pages/pageAuthCode.ts
  12. 1
      src/pages/pagePassword.ts
  13. 1
      src/pages/pageSignIn.ts
  14. 1
      src/pages/pageSignUp.ts

27
src/lib/appManagers/apiUpdatesManager.ts

@ -54,6 +54,23 @@ export class ApiUpdatesManager { @@ -54,6 +54,23 @@ export class ApiUpdatesManager {
private log = logger('UPDATES', LogTypes.Error | LogTypes.Warn/* | LogTypes.Log | LogTypes.Debug */);
private debug = DEBUG;
private setProxy() {
const self = this;
this.updatesState = new Proxy(this.updatesState, {
set: function(target: ApiUpdatesManager['updatesState'], key: keyof ApiUpdatesManager['updatesState'], value: ApiUpdatesManager['updatesState'][typeof key]) {
// @ts-ignore
target[key] = value;
const us = self.updatesState;
appStateManager.pushToState('updates', {
seq: us.seq,
pts: us.pts,
date: us.date
});
return true;
}
});
}
private popPendingSeqUpdate() {
const state = this.updatesState;
const nextSeq = state.seq + 1;
@ -633,15 +650,7 @@ export class ApiUpdatesManager { @@ -633,15 +650,7 @@ export class ApiUpdatesManager {
apiManager.setUpdatesProcessor(this.processUpdateMessage);
this.updatesState.syncLoading.then(() => {
// * false for test purposes
/* false && */appStateManager.addEventListener('save', async() => {
const us = this.updatesState;
appStateManager.pushToState('updates', {
seq: us.seq,
pts: us.pts,
date: us.date
});
});
this.setProxy();
});
});
}

17
src/lib/appManagers/appChatsManager.ts

@ -74,8 +74,21 @@ export class AppChatsManager { @@ -74,8 +74,21 @@ export class AppChatsManager {
updateChannelUserTyping: this.onUpdateUserTyping
});
appStateManager.getState().then((state) => {
this.chats = state.chats;
let storageChats: Chat[];
const getStorageChatsPromise = this.storage.getAll().then(chats => {
storageChats = chats as any;
});
appStateManager.addLoadPromise(getStorageChatsPromise).then((state) => {
if(storageChats.length) {
this.chats = {};
for(let i = 0, length = storageChats.length; i < length; ++i) {
const user = storageChats[i];
this.chats[user.id] = user;
}
} else if(state.chats) {
this.chats = state.chats;
}
appStateManager.addEventListener('peerNeeded', (peerId: number) => {
if(peerId > 0 || this.storage.getFromCache(-peerId)) {

9
src/lib/appManagers/appDialogsManager.ts

@ -507,10 +507,11 @@ export class AppDialogsManager { @@ -507,10 +507,11 @@ export class AppDialogsManager {
return this.loadDialogs();
}).then(() => {
const allDialogsLoaded = appMessagesManager.dialogsStorage.allDialogsLoaded;
const wasLoaded = allDialogsLoaded[0] || allDialogsLoaded[1];
const a: Promise<any> = allDialogsLoaded[0] ? Promise.resolve() : appMessagesManager.getConversationsAll('', 0);
const b: Promise<any> = allDialogsLoaded[1] ? Promise.resolve() : appMessagesManager.getConversationsAll('', 1);
const isLoadedMain = appMessagesManager.dialogsStorage.isDialogsLoaded(0);
const isLoadedArchive = appMessagesManager.dialogsStorage.isDialogsLoaded(1);
const wasLoaded = isLoadedMain || isLoadedArchive;
const a: Promise<any> = isLoadedMain ? Promise.resolve() : appMessagesManager.getConversationsAll('', 0);
const b: Promise<any> = isLoadedArchive ? Promise.resolve() : appMessagesManager.getConversationsAll('', 1);
a.finally(() => {
b.then(() => {
this.accumulateArchivedUnread();

6
src/lib/appManagers/appDraftsManager.ts

@ -32,10 +32,6 @@ export class AppDraftsManager { @@ -32,10 +32,6 @@ export class AppDraftsManager {
constructor() {
appStateManager.getState().then(state => {
this.drafts = state.drafts;
appStateManager.addEventListener('save', async() => {
appStateManager.pushToState('drafts', this.drafts);
});
});
rootScope.addMultipleEventsListeners({
@ -100,6 +96,8 @@ export class AppDraftsManager { @@ -100,6 +96,8 @@ export class AppDraftsManager {
delete this.drafts[key];
}
appStateManager.pushToState('drafts', this.drafts);
if(options.notify) {
// console.warn(dT(), 'save draft', peerId, apiDraft, options)
rootScope.broadcast('draft_updated', {

105
src/lib/appManagers/appMessagesManager.ts

@ -194,7 +194,7 @@ export class AppMessagesManager { @@ -194,7 +194,7 @@ export class AppMessagesManager {
constructor() {
this.dialogsStorage = new DialogsStorage(this, appChatsManager, appPeersManager, appUsersManager, appDraftsManager, appNotificationsManager, appStateManager, apiUpdatesManager, serverTimeManager);
this.filtersStorage = new FiltersStorage(this, appPeersManager, appUsersManager, appNotificationsManager, apiUpdatesManager, /* apiManager, */ rootScope);
this.filtersStorage = new FiltersStorage(this, appPeersManager, appUsersManager, appNotificationsManager, appStateManager, apiUpdatesManager, /* apiManager, */ rootScope);
rootScope.addMultipleEventsListeners({
updateMessageID: this.onUpdateMessageId,
@ -303,111 +303,11 @@ export class AppMessagesManager { @@ -303,111 +303,11 @@ export class AppMessagesManager {
if(state.maxSeenMsgId) {
this.maxSeenId = state.maxSeenMsgId;
}
const messages = state.messages;
if(messages) {
/* let tempId = this.tempId;
for(let message of messages) {
if(message.id < tempId) {
tempId = message.id;
}
}
if(tempId !== this.tempId) {
this.log('Set tempId to:', tempId);
this.tempId = tempId;
} */
this.saveMessages(messages);
}
if(!state.dialogs || !Object.keys(state.dialogs).length) {
state.allDialogsLoaded = {};
}
if(state.allDialogsLoaded) {
this.dialogsStorage.allDialogsLoaded = state.allDialogsLoaded;
}
if(state.filters) {
for(const filterId in state.filters) {
this.filtersStorage.saveDialogFilter(state.filters[filterId], false);
}
}
if(state.dialogs) {
forEachReverse(state.dialogs, dialog => {
dialog.top_message = this.getServerMessageId(dialog.top_message); // * fix outgoing message to avoid copying dialog
this.dialogsStorage.saveDialog(dialog);
// ! WARNING, убрать это когда нужно будет делать чтобы pending сообщения сохранялись
const message = this.getMessageByPeer(dialog.peerId, dialog.top_message);
if(message.deleted) {
this.reloadConversation(dialog.peerId);
}
});
}
appStateManager.addEventListener('save', this.saveState);
});
appNotificationsManager.start();
}
private saveState = () => {
const messages: any[] = [];
const dialogs: Dialog[] = [];
const items: any[] = [];
const processDialog = (dialog: MTDialog.dialog) => {
const historyStorage = this.getHistoryStorage(dialog.peerId);
const history = [].concat(historyStorage.history.slice);
for(const mid of history) {
const message = this.getMessageByPeer(dialog.peerId, mid);
if(!message.pFlags.is_outgoing) {
messages.push(message);
if(message.fromId !== dialog.peerId) {
appStateManager.requestPeer(message.fromId, 'topMessage_' + dialog.peerId, 1);
}
break;
}
}
if(dialog.peerId < 0 && dialog.pts) {
const newPts = apiUpdatesManager.channelStates[-dialog.peerId].pts;
dialog.pts = newPts;
}
dialogs.push(dialog);
appStateManager.requestPeer(dialog.peerId, 'dialog');
};
for(const folderId in this.dialogsStorage.byFolders) {
const folder = this.dialogsStorage.getFolder(+folderId);
for(let dialog of folder) {
items.push([dialog]);
}
}
return pushHeavyTask({
items,
process: processDialog,
context: this
}).then(() => {
appStateManager.pushToState('dialogs', dialogs);
appStateManager.pushToState('messages', messages);
appStateManager.pushToState('filters', this.filtersStorage.filters);
appStateManager.pushToState('allDialogsLoaded', this.dialogsStorage.allDialogsLoaded);
appStateManager.pushToState('maxSeenMsgId', this.maxSeenId);
});
};
public getInputEntities(entities: MessageEntity[]) {
var sendEntites = copy(entities);
sendEntites.forEach((entity: any) => {
@ -1807,7 +1707,7 @@ export class AppMessagesManager { @@ -1807,7 +1707,7 @@ export class AppMessagesManager {
if(!dialogsResult.dialogs.length ||
!count ||
dialogs.length >= count) {
this.dialogsStorage.allDialogsLoaded[folderId] = true;
this.dialogsStorage.setDialogsLoaded(folderId, true);
}
if(hasPrepend) {
@ -4498,6 +4398,7 @@ export class AppMessagesManager { @@ -4498,6 +4398,7 @@ export class AppMessagesManager {
}
this.maxSeenId = maxId;
appStateManager.pushToState('maxSeenMsgId', maxId);
apiManager.invokeApi('messages.receivedMessages', {
max_id: this.getServerMessageId(maxId)

58
src/lib/appManagers/appStateManager.ts

@ -162,12 +162,12 @@ export class AppStateManager extends EventListenerBase<{ @@ -162,12 +162,12 @@ export class AppStateManager extends EventListenerBase<{
peerUnneeded: (peerId: number) => void,
}> {
public static STATE_INIT = STATE_INIT;
public loaded: Promise<State>;
private loaded: Promise<State>;
private loadPromises: Promise<any>[] = [];
private loadAllPromise: Promise<any>;
private log = logger('STATE'/* , LogLevels.error */);
private state: State;
private savePromise: Promise<void>;
private tempId = 0;
private neededPeers: Map<number, Set<string>> = new Map();
private singlePeerMap: Map<string, number> = new Map();
@ -177,10 +177,10 @@ export class AppStateManager extends EventListenerBase<{ @@ -177,10 +177,10 @@ export class AppStateManager extends EventListenerBase<{
this.loadSavedState();
}
public loadSavedState() {
if(this.loaded) return this.loaded;
public loadSavedState(): Promise<State> {
if(this.loadAllPromise) return this.loadAllPromise;
//console.time('load state');
return this.loaded = new Promise((resolve) => {
this.loaded = new Promise((resolve) => {
Promise.all(ALL_KEYS.concat('user_auth' as any).map(key => sessionStorage.get(key))).then((arr) => {
let state: State = {};
@ -255,46 +255,24 @@ export class AppStateManager extends EventListenerBase<{ @@ -255,46 +255,24 @@ export class AppStateManager extends EventListenerBase<{
//console.timeEnd('load state');
resolve(this.state);
}).catch(resolve).finally(() => {
setInterval(() => {
this.tempId++;
this.saveState();
}, 10000);
});
}).catch(resolve);
});
}
public getState() {
return this.state === undefined ? this.loadSavedState() : Promise.resolve(this.state);
return this.addLoadPromise(this.loaded);
}
public saveState() {
if(this.state === undefined || this.savePromise) return;
return;
const tempId = this.tempId;
this.savePromise = getHeavyAnimationPromise().then(() => {
return Promise.all(this.dispatchEvent('save', this.state))
.then(() => getHeavyAnimationPromise())
.then(() => sessionStorage.set(this.state))
.then(() => {
this.savePromise = null;
if(this.tempId !== tempId) {
this.saveState();
}
});
});
//let perf = performance.now();
//this.log('saveState: event time:', performance.now() - perf);
public addLoadPromise(promise: Promise<any>) {
if(!this.loaded) {
return this.loadSavedState();
}
//const pinnedOrders = appMessagesManager.dialogsStorage.pinnedOrders;
this.loadPromises.push(promise);
return this.loadAllPromise = Promise.all(this.loadPromises)
.then(() => this.state, () => this.state);
}
//perf = performance.now();
//this.log('saveState: storage set time:', performance.now() - perf);
public getState() {
return this.state === undefined ? this.loadSavedState() : Promise.resolve(this.state);
}
public setByKey(key: string, value: any) {

41
src/lib/appManagers/appUsersManager.ts

@ -113,8 +113,21 @@ export class AppUsersManager { @@ -113,8 +113,21 @@ export class AppUsersManager {
searchIndexManager.indexObject(userId, this.getUserSearchText(userId), this.contactsIndex);
});
appStateManager.getState().then((state) => {
this.users = state.users;
let storageUsers: User[];
const getStorageUsersPromise = this.storage.getAll().then(users => {
storageUsers = users as any;
});
appStateManager.addLoadPromise(getStorageUsersPromise).then((state) => {
if(storageUsers.length) {
this.users = {};
for(let i = 0, length = storageUsers.length; i < length; ++i) {
const user = storageUsers[i];
this.users[user.id] = user;
}
} else if(state.users) {
this.users = state.users;
}
const contactsList = state.contactsList;
if(contactsList && Array.isArray(contactsList)) {
@ -122,20 +135,11 @@ export class AppUsersManager { @@ -122,20 +135,11 @@ export class AppUsersManager {
this.pushContact(userId);
});
if(this.contactsList.size) {
if(contactsList.length) {
this.contactsFillPromise = Promise.resolve(this.contactsList);
}
}
appStateManager.addEventListener('save', async() => {
const contactsList = [...this.contactsList];
for(const userId of contactsList) {
appStateManager.requestPeer(userId, 'contacts');
}
appStateManager.pushToState('contactsList', contactsList);
});
appStateManager.addEventListener('peerNeeded', (peerId: number) => {
if(peerId < 0 || this.storage.getFromCache(peerId)) {
return;
@ -156,6 +160,11 @@ export class AppUsersManager { @@ -156,6 +160,11 @@ export class AppUsersManager {
});
}
private onContactsModified() {
const contactsList = [...this.contactsList];
appStateManager.pushToState('contactsList', contactsList);
}
public fillContacts() {
if(this.contactsFillPromise && this.updatedContactsList) {
return this.contactsFillPromise;
@ -170,6 +179,8 @@ export class AppUsersManager { @@ -170,6 +179,8 @@ export class AppUsersManager {
result.contacts.forEach((contact) => {
this.pushContact(contact.user_id);
});
this.onContactsModified();
}
this.contactsFillPromise = promise;
@ -201,6 +212,7 @@ export class AppUsersManager { @@ -201,6 +212,7 @@ export class AppUsersManager {
public pushContact(userId: number) {
this.contactsList.add(userId);
searchIndexManager.indexObject(userId, this.getUserSearchText(userId), this.contactsIndex);
appStateManager.requestPeer(userId, 'contacts');
}
public getUserSearchText(id: number) {
@ -756,12 +768,13 @@ export class AppUsersManager { @@ -756,12 +768,13 @@ export class AppUsersManager {
const curIsContact = this.isContact(userId);
if(isContact !== curIsContact) {
if(isContact) {
this.contactsList.add(userId)
searchIndexManager.indexObject(userId, this.getUserSearchText(userId), this.contactsIndex);
this.pushContact(userId);
} else {
this.contactsList.delete(userId);
}
this.onContactsModified();
rootScope.broadcast('contacts_update', userId);
}
}

4
src/lib/storage.ts

@ -83,6 +83,10 @@ export default class AppStorage<Storage extends Record<string, any>/* Storage ex @@ -83,6 +83,10 @@ export default class AppStorage<Storage extends Record<string, any>/* Storage ex
} */
}
public getAll() {
return this.storage.getAll();
}
public async set(obj: Partial<Storage>, onlyLocal = false) {
//console.log('storageSetValue', obj, callback, arguments);

45
src/lib/storages/dialogs.ts

@ -35,7 +35,7 @@ export default class DialogsStorage { @@ -35,7 +35,7 @@ export default class DialogsStorage {
private dialogs: {[peerId: string]: Dialog} = {};
public byFolders: {[folderId: number]: Dialog[]} = {};
public allDialogsLoaded: {[folder_id: number]: boolean};
private allDialogsLoaded: {[folder_id: number]: boolean};
private dialogsOffsetDate: {[folder_id: number]: number};
private pinnedOrders: {[folder_id: number]: number[]};
private dialogsNum: number;
@ -84,6 +84,40 @@ export default class DialogsStorage { @@ -84,6 +84,40 @@ export default class DialogsStorage {
updatePinnedDialogs: this.onUpdatePinnedDialogs,
});
let storageDialogs: Dialog[];
const getStorageDialogsPromise = this.storage.getAll().then(dialogs => {
storageDialogs = dialogs as any;
forEachReverse(storageDialogs, dialog => {
dialog.top_message = this.appMessagesManager.getServerMessageId(dialog.top_message); // * fix outgoing message to avoid copying dialog
this.saveDialog(dialog);
if(dialog.topMessage) {
this.appMessagesManager.saveMessages([dialog.topMessage]);
}
// ! WARNING, убрать это когда нужно будет делать чтобы pending сообщения сохранялись
const message = this.appMessagesManager.getMessageByPeer(dialog.peerId, dialog.top_message);
if(message.deleted) {
this.appMessagesManager.reloadConversation(dialog.peerId);
}
});
});
appStateManager.addLoadPromise(getStorageDialogsPromise).then((state) => {
this.allDialogsLoaded = state.allDialogsLoaded || {};
});
}
public isDialogsLoaded(folderId: number) {
return !!this.allDialogsLoaded[folderId];
}
public setDialogsLoaded(folderId: number, loaded: boolean) {
this.allDialogsLoaded[folderId] = loaded;
this.appStateManager.pushToState('allDialogsLoaded', this.allDialogsLoaded);
}
public reset() {
@ -512,11 +546,12 @@ export default class DialogsStorage { @@ -512,11 +546,12 @@ export default class DialogsStorage {
}
}
if(query || this.allDialogsLoaded[realFolderId] || curDialogStorage.length >= offset + limit) {
const loadedAll = this.isDialogsLoaded(realFolderId);
if(query || loadedAll || curDialogStorage.length >= offset + limit) {
return Promise.resolve({
dialogs: curDialogStorage.slice(offset, offset + limit),
count: this.allDialogsLoaded[realFolderId] ? curDialogStorage.length : null,
isEnd: this.allDialogsLoaded[realFolderId] && (offset + limit) >= curDialogStorage.length
count: loadedAll ? curDialogStorage.length : null,
isEnd: loadedAll && (offset + limit) >= curDialogStorage.length
});
}
@ -537,7 +572,7 @@ export default class DialogsStorage { @@ -537,7 +572,7 @@ export default class DialogsStorage {
return {
dialogs: curDialogStorage.slice(offset, offset + limit),
count: messagesDialogs._ === 'messages.dialogs' ? messagesDialogs.dialogs.length : messagesDialogs.count,
isEnd: this.allDialogsLoaded[realFolderId] && (offset + limit) >= curDialogStorage.length
isEnd: this.isDialogsLoaded(realFolderId) && (offset + limit) >= curDialogStorage.length
};
});
}

18
src/lib/storages/filters.ts

@ -16,6 +16,7 @@ import type {AppNotificationsManager} from "../appManagers/appNotificationsManag @@ -16,6 +16,7 @@ import type {AppNotificationsManager} from "../appManagers/appNotificationsManag
import type { ApiUpdatesManager } from "../appManagers/apiUpdatesManager";
import apiManager from "../mtproto/mtprotoworker";
import { forEachReverse } from "../../helpers/array";
import { AppStateManager } from "../appManagers/appStateManager";
export type MyDialogFilter = Modify<DialogFilter, {
pinned_peers: number[],
@ -29,16 +30,25 @@ const START_ORDER_INDEX = 1; @@ -29,16 +30,25 @@ const START_ORDER_INDEX = 1;
export default class FiltersStorage {
public filters: {[filterId: string]: MyDialogFilter} = {};
public orderIndex = START_ORDER_INDEX;
private orderIndex = START_ORDER_INDEX;
constructor(private appMessagesManager: AppMessagesManager,
private appPeersManager: AppPeersManager,
private appUsersManager: AppUsersManager,
private appNotificationsManager: AppNotificationsManager,
private appStateManager: AppStateManager,
private apiUpdatesManager: ApiUpdatesManager,
/* private apiManager: ApiManagerProxy, */
private rootScope: typeof _rootScope) {
this.appStateManager.getState().then((state) => {
if(state.filters) {
for(const filterId in state.filters) {
this.saveDialogFilter(state.filters[filterId], false);
}
}
});
rootScope.addMultipleEventsListeners({
updateDialogFilter: this.onUpdateDialogFilter,
@ -71,6 +81,8 @@ export default class FiltersStorage { @@ -71,6 +81,8 @@ export default class FiltersStorage {
this.rootScope.broadcast('filter_delete', this.filters[update.id]);
delete this.filters[update.id];
}
this.appStateManager.pushToState('filters', this.filters);
};
private onUpdateDialogFilterOrder = (update: Update.updateDialogFilterOrder) => {
@ -84,6 +96,8 @@ export default class FiltersStorage { @@ -84,6 +96,8 @@ export default class FiltersStorage {
});
this.rootScope.broadcast('filter_order', update.order);
this.appStateManager.pushToState('filters', this.filters);
};
public testDialogForFilter(dialog: Dialog, filter: MyDialogFilter) {
@ -264,5 +278,7 @@ export default class FiltersStorage { @@ -264,5 +278,7 @@ export default class FiltersStorage {
} else {
filter.orderIndex = this.orderIndex++;
}
this.appStateManager.pushToState('filters', this.filters);
}
}

1
src/pages/pageAuthCode.ts

@ -165,7 +165,6 @@ const page = new Page('page-authCode', true, onFirstMount, (_authCode: typeof au @@ -165,7 +165,6 @@ const page = new Page('page-authCode', true, onFirstMount, (_authCode: typeof au
replaceContent(sentTypeElement, i18n(key, args));
appStateManager.pushToState('authState', {_: 'authStateAuthCode', sentCode: _authCode});
appStateManager.saveState();
}, () => {
codeInput.focus();
});

1
src/pages/pagePassword.ts

@ -140,7 +140,6 @@ const page = new Page('page-password', true, onFirstMount, null, () => { @@ -140,7 +140,6 @@ const page = new Page('page-password', true, onFirstMount, null, () => {
//}
appStateManager.pushToState('authState', {_: 'authStatePassword'});
appStateManager.saveState();
});
export default page;

1
src/pages/pageSignIn.ts

@ -516,7 +516,6 @@ const page = new Page('page-sign', true, onFirstMount, () => { @@ -516,7 +516,6 @@ const page = new Page('page-sign', true, onFirstMount, () => {
}
appStateManager.pushToState('authState', {_: 'authStateSignIn'});
appStateManager.saveState();
});
export default page;

1
src/pages/pageSignUp.ts

@ -169,7 +169,6 @@ const page = new Page('page-signUp', true, onFirstMount, (_authCode: typeof auth @@ -169,7 +169,6 @@ const page = new Page('page-signUp', true, onFirstMount, (_authCode: typeof auth
authCode = _authCode;
appStateManager.pushToState('authState', {_: 'authStateSignUp', authCode: _authCode});
appStateManager.saveState();
});
export default page;

Loading…
Cancel
Save