diff --git a/src/components/chat/topbar.ts b/src/components/chat/topbar.ts index 0f65d925..93c0b21f 100644 --- a/src/components/chat/topbar.ts +++ b/src/components/chat/topbar.ts @@ -10,6 +10,7 @@ import type { AppMessagesManager } from "../../lib/appManagers/appMessagesManage import type { AppPeersManager } from "../../lib/appManagers/appPeersManager"; import type { AppSidebarRight } from "../sidebarRight"; import type Chat from "./chat"; +import { RIGHT_COLUMN_ACTIVE_CLASSNAME } from "../sidebarRight"; import mediaSizes, { ScreenSize } from "../../helpers/mediaSizes"; import { isSafari } from "../../helpers/userAgent"; import rootScope from "../../lib/rootScope"; @@ -31,6 +32,7 @@ import findUpClassName from "../../helpers/dom/findUpClassName"; import blurActiveElement from "../../helpers/dom/blurActiveElement"; import { cancelEvent } from "../../helpers/dom/cancelEvent"; import { attachClickEvent } from "../../helpers/dom/clickEvent"; +import findUpTag from "../../helpers/dom/findUpTag"; export default class ChatTopbar { public container: HTMLDivElement; @@ -150,6 +152,8 @@ export default class ChatTopbar { } else { if(mediaSizes.activeScreen === ScreenSize.medium && document.body.classList.contains(LEFT_COLUMN_ACTIVE_CLASSNAME)) { onBtnBackClick(); + } else if(findUpTag(e.target, 'AVATAR-ELEMENT')) { + this.appSidebarRight.toggleSidebar(!document.body.classList.contains(RIGHT_COLUMN_ACTIVE_CLASSNAME)); } else { this.appSidebarRight.toggleSidebar(true); } diff --git a/src/lib/appManagers/apiUpdatesManager.ts b/src/lib/appManagers/apiUpdatesManager.ts index 13b57796..37f25041 100644 --- a/src/lib/appManagers/apiUpdatesManager.ts +++ b/src/lib/appManagers/apiUpdatesManager.ts @@ -47,7 +47,7 @@ export class ApiUpdatesManager { syncLoading: null }; - public channelStates: {[channelId: number]: UpdatesState} = {}; + private channelStates: {[channelId: number]: UpdatesState} = {}; private attached = false; private log = logger('UPDATES', LogTypes.Error | LogTypes.Warn | LogTypes.Log/* | LogTypes.Debug */); @@ -305,6 +305,8 @@ export class ApiUpdatesManager { delete updatesState.seq; delete updatesState.date; + this.channelStates = {}; + rootScope.dispatchEvent('state_cleared'); } @@ -426,8 +428,8 @@ export class ApiUpdatesManager { return false; } - - private getChannelState(channelId: number, pts?: number) { + + public getChannelState(channelId: number, pts?: number) { if(this.channelStates[channelId] === undefined) { this.addChannelState(channelId, pts); } diff --git a/src/lib/appManagers/appChatsManager.ts b/src/lib/appManagers/appChatsManager.ts index 7fb50841..e6b9aa0b 100644 --- a/src/lib/appManagers/appChatsManager.ts +++ b/src/lib/appManagers/appChatsManager.ts @@ -33,16 +33,18 @@ export type UserTyping = Partial<{userId: number, action: SendMessageAction, tim export class AppChatsManager { private storage = appStateManager.storages.chats; - private chats: {[id: number]: Chat.channel | Chat.chat | any} = {}; - //private usernames: any = {}; - //private channelAccess: any = {}; - //private megagroups: {[id: number]: true} = {}; + private chats: {[id: number]: Chat.channel | Chat.chat | any}; + //private usernames: any; + //private channelAccess: any; + //private megagroups: {[id: number]: true}; - private megagroupOnlines: {[id: number]: {timestamp: number, onlines: number}} = {}; + private megagroupOnlines: {[id: number]: {timestamp: number, onlines: number}}; - private typingsInPeer: {[peerId: number]: UserTyping[]} = {}; + private typingsInPeer: {[peerId: number]: UserTyping[]}; constructor() { + this.clear(); + rootScope.addMultipleEventsListeners({ /* updateChannel: (update) => { const channelId = update.channel_id; @@ -102,6 +104,26 @@ export class AppChatsManager { }); } + public clear() { + if(this.chats) { + for(const chatId in this.chats) { + if(!appStateManager.isPeerNeeded(-+chatId)) { + /* const chat = this.chats[chatId]; + if(chat.username) { + delete this.usernames[cleanUsername(chat.username)]; + } */ + + delete this.chats[chatId]; + } + } + } else { + this.chats = {}; + } + + this.megagroupOnlines = {}; + this.typingsInPeer = {}; + } + private onUpdateUserTyping = (update: Update.updateUserTyping | Update.updateChatUserTyping | Update.updateChannelUserTyping) => { const fromId = (update as Update.updateUserTyping).user_id || appPeersManager.getPeerId((update as Update.updateChatUserTyping).from_id); if(rootScope.myId === fromId || update.action._ === 'speakingInGroupCallAction') { diff --git a/src/lib/appManagers/appDialogsManager.ts b/src/lib/appManagers/appDialogsManager.ts index 0cc80a04..6c78afd2 100644 --- a/src/lib/appManagers/appDialogsManager.ts +++ b/src/lib/appManagers/appDialogsManager.ts @@ -40,6 +40,7 @@ import { attachClickEvent } from "../../helpers/dom/clickEvent"; import positionElementByIndex from "../../helpers/dom/positionElementByIndex"; import replaceContent from "../../helpers/dom/replaceContent"; import ConnectionStatusComponent from "../../components/connectionStatus"; +import appChatsManager from "./appChatsManager"; export type DialogDom = { avatarEl: AvatarElement, @@ -324,6 +325,11 @@ export class AppDialogsManager { } }); + /* rootScope.addEventListener('state_cleared', () => { + appUsersManager.clear(); + appChatsManager.clear(); + }); */ + const foldersScrollable = new ScrollableX(this.folders.menuScrollContainer); bottomPart.prepend(this.folders.menuScrollContainer); const selectTab = horizontalMenu(this.folders.menu, this.folders.container, (id, tabContent) => { diff --git a/src/lib/appManagers/appStateManager.ts b/src/lib/appManagers/appStateManager.ts index 3f4f5be6..ed2f005d 100644 --- a/src/lib/appManagers/appStateManager.ts +++ b/src/lib/appManagers/appStateManager.ts @@ -24,7 +24,7 @@ import DATABASE_STATE from '../../config/databases/state'; import sessionStorage from '../sessionStorage'; const REFRESH_EVERY = 24 * 60 * 60 * 1000; // 1 day -const REFRESH_EVERY_WEEK = 24 * 60 * 60 * 1000 * 7; // 7 days +//const REFRESH_EVERY_WEEK = 24 * 60 * 60 * 1000 * 7; // 7 days const STATE_VERSION = App.version; export type Background = { @@ -159,7 +159,7 @@ const ALL_KEYS = Object.keys(STATE_INIT) as any as Array; const REFRESH_KEYS = ['contactsList', 'stateCreatedTime', 'maxSeenMsgId', 'filters', 'topPeers'] as any as Array; -const REFRESH_KEYS_WEEK = ['dialogs', 'allDialogsLoaded', 'updates', 'pinnedOrders'] as any as Array; +//const REFRESH_KEYS_WEEK = ['dialogs', 'allDialogsLoaded', 'updates', 'pinnedOrders'] as any as Array; export class AppStateManager extends EventListenerBase<{ save: (state: State) => Promise, @@ -330,13 +330,13 @@ export class AppStateManager extends EventListenerBase<{ r(REFRESH_KEYS); - if((state.stateCreatedTime + REFRESH_EVERY_WEEK) < time) { + /* if((state.stateCreatedTime + REFRESH_EVERY_WEEK) < time) { if(DEBUG) { this.log('will refresh updates'); } r(REFRESH_KEYS_WEEK); - } + } */ } //state = this.state = new Proxy(state, getHandler()); diff --git a/src/lib/appManagers/appUsersManager.ts b/src/lib/appManagers/appUsersManager.ts index f1de04ef..e1f7c87e 100644 --- a/src/lib/appManagers/appUsersManager.ts +++ b/src/lib/appManagers/appUsersManager.ts @@ -36,16 +36,18 @@ export type User = MTUser.user; export class AppUsersManager { private storage = appStateManager.storages.users; - private users: {[userId: number]: User} = {}; - private usernames: {[username: string]: number} = {}; - private contactsIndex = new SearchIndex(); + private users: {[userId: number]: User}; + private usernames: {[username: string]: number}; + private contactsIndex: SearchIndex; private contactsFillPromise: Promise>; - private contactsList: Set = new Set(); - private updatedContactsList = false; + private contactsList: Set; + private updatedContactsList: boolean; private getTopPeersPromise: Promise; constructor() { + this.clear(); + setInterval(this.updateUsersStatuses, 60000); rootScope.addEventListener('state_synchronized', this.updateUsersStatuses); @@ -158,6 +160,29 @@ export class AppUsersManager { }); } + public clear() { + if(this.users) { + for(const userId in this.users) { + if(!appStateManager.isPeerNeeded(+userId)) { + const user = this.users[userId]; + if(user.username) { + delete this.usernames[cleanUsername(user.username)]; + } + + delete this.users[userId]; + } + } + } else { + this.users = {}; + this.usernames = {}; + } + + this.contactsIndex = new SearchIndex(); + this.contactsFillPromise = undefined; + this.contactsList = new Set(); + this.updatedContactsList = false; + } + private onContactsModified() { const contactsList = [...this.contactsList]; appStateManager.pushToState('contactsList', contactsList); diff --git a/src/lib/idb.ts b/src/lib/idb.ts index b81e2568..0f7b535a 100644 --- a/src/lib/idb.ts +++ b/src/lib/idb.ts @@ -53,16 +53,17 @@ export default class IDBStorage> { constructor(db: T, storeName: typeof db['stores'][0]['name']) { safeAssign(this, db); + + if(Modes.test) { + this.name += '_test'; + } + this.storeName = storeName; this.log = logger('IDB-' + this.storeName); this.openDatabase(true); - if(Modes.test) { - this.name += '_test'; - } - IDBStorage.STORAGES.push(this); } diff --git a/src/lib/mtproto/mtproto.service.ts b/src/lib/mtproto/mtproto.service.ts index dceb7ee2..b61c7667 100644 --- a/src/lib/mtproto/mtproto.service.ts +++ b/src/lib/mtproto/mtproto.service.ts @@ -50,17 +50,23 @@ ctx.addEventListener('message', (e) => { //const cacheStorage = new CacheStorageController('cachedAssets'); let taskId = 0; +function isCorrectResponse(response: Response) { + return response.ok && response.status === 200; +} + async function requestCache(event: FetchEvent) { try { const cache = await ctx.caches.open('cachedAssets'); const file = await cache.match(event.request); - if(file) { + if(file && isCorrectResponse(file)) { return file; } const response = await fetch(event.request); - cache.put(event.request, response.clone()); + if(isCorrectResponse(response)) { + cache.put(event.request, response.clone()); + } return response; } catch(err) { diff --git a/src/lib/storages/dialogs.ts b/src/lib/storages/dialogs.ts index 554b1e6f..69b085b8 100644 --- a/src/lib/storages/dialogs.ts +++ b/src/lib/storages/dialogs.ts @@ -302,7 +302,7 @@ export default class DialogsStorage { dialog.topMessage = incomingMessage; if(dialog.peerId < 0 && dialog.pts) { - const newPts = this.apiUpdatesManager.channelStates[-dialog.peerId].pts; + const newPts = this.apiUpdatesManager.getChannelState(-dialog.peerId, dialog.pts).pts; dialog.pts = newPts; }