Browse Source

Fix caching

master
Eduard Kuzmenko 4 years ago
parent
commit
dfab2818eb
  1. 4
      src/components/chat/topbar.ts
  2. 8
      src/lib/appManagers/apiUpdatesManager.ts
  3. 34
      src/lib/appManagers/appChatsManager.ts
  4. 6
      src/lib/appManagers/appDialogsManager.ts
  5. 8
      src/lib/appManagers/appStateManager.ts
  6. 35
      src/lib/appManagers/appUsersManager.ts
  7. 9
      src/lib/idb.ts
  8. 10
      src/lib/mtproto/mtproto.service.ts
  9. 2
      src/lib/storages/dialogs.ts

4
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 { AppPeersManager } from "../../lib/appManagers/appPeersManager";
import type { AppSidebarRight } from "../sidebarRight"; import type { AppSidebarRight } from "../sidebarRight";
import type Chat from "./chat"; import type Chat from "./chat";
import { RIGHT_COLUMN_ACTIVE_CLASSNAME } from "../sidebarRight";
import mediaSizes, { ScreenSize } from "../../helpers/mediaSizes"; import mediaSizes, { ScreenSize } from "../../helpers/mediaSizes";
import { isSafari } from "../../helpers/userAgent"; import { isSafari } from "../../helpers/userAgent";
import rootScope from "../../lib/rootScope"; import rootScope from "../../lib/rootScope";
@ -31,6 +32,7 @@ import findUpClassName from "../../helpers/dom/findUpClassName";
import blurActiveElement from "../../helpers/dom/blurActiveElement"; import blurActiveElement from "../../helpers/dom/blurActiveElement";
import { cancelEvent } from "../../helpers/dom/cancelEvent"; import { cancelEvent } from "../../helpers/dom/cancelEvent";
import { attachClickEvent } from "../../helpers/dom/clickEvent"; import { attachClickEvent } from "../../helpers/dom/clickEvent";
import findUpTag from "../../helpers/dom/findUpTag";
export default class ChatTopbar { export default class ChatTopbar {
public container: HTMLDivElement; public container: HTMLDivElement;
@ -150,6 +152,8 @@ export default class ChatTopbar {
} else { } else {
if(mediaSizes.activeScreen === ScreenSize.medium && document.body.classList.contains(LEFT_COLUMN_ACTIVE_CLASSNAME)) { if(mediaSizes.activeScreen === ScreenSize.medium && document.body.classList.contains(LEFT_COLUMN_ACTIVE_CLASSNAME)) {
onBtnBackClick(); onBtnBackClick();
} else if(findUpTag(e.target, 'AVATAR-ELEMENT')) {
this.appSidebarRight.toggleSidebar(!document.body.classList.contains(RIGHT_COLUMN_ACTIVE_CLASSNAME));
} else { } else {
this.appSidebarRight.toggleSidebar(true); this.appSidebarRight.toggleSidebar(true);
} }

8
src/lib/appManagers/apiUpdatesManager.ts

@ -47,7 +47,7 @@ export class ApiUpdatesManager {
syncLoading: null syncLoading: null
}; };
public channelStates: {[channelId: number]: UpdatesState} = {}; private channelStates: {[channelId: number]: UpdatesState} = {};
private attached = false; private attached = false;
private log = logger('UPDATES', LogTypes.Error | LogTypes.Warn | LogTypes.Log/* | LogTypes.Debug */); private log = logger('UPDATES', LogTypes.Error | LogTypes.Warn | LogTypes.Log/* | LogTypes.Debug */);
@ -305,6 +305,8 @@ export class ApiUpdatesManager {
delete updatesState.seq; delete updatesState.seq;
delete updatesState.date; delete updatesState.date;
this.channelStates = {};
rootScope.dispatchEvent('state_cleared'); rootScope.dispatchEvent('state_cleared');
} }
@ -426,8 +428,8 @@ export class ApiUpdatesManager {
return false; return false;
} }
private getChannelState(channelId: number, pts?: number) { public getChannelState(channelId: number, pts?: number) {
if(this.channelStates[channelId] === undefined) { if(this.channelStates[channelId] === undefined) {
this.addChannelState(channelId, pts); this.addChannelState(channelId, pts);
} }

34
src/lib/appManagers/appChatsManager.ts

@ -33,16 +33,18 @@ export type UserTyping = Partial<{userId: number, action: SendMessageAction, tim
export class AppChatsManager { export class AppChatsManager {
private storage = appStateManager.storages.chats; private storage = appStateManager.storages.chats;
private chats: {[id: number]: Chat.channel | Chat.chat | any} = {}; private chats: {[id: number]: Chat.channel | Chat.chat | any};
//private usernames: any = {}; //private usernames: any;
//private channelAccess: any = {}; //private channelAccess: any;
//private megagroups: {[id: number]: true} = {}; //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() { constructor() {
this.clear();
rootScope.addMultipleEventsListeners({ rootScope.addMultipleEventsListeners({
/* updateChannel: (update) => { /* updateChannel: (update) => {
const channelId = update.channel_id; 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) => { 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); const fromId = (update as Update.updateUserTyping).user_id || appPeersManager.getPeerId((update as Update.updateChatUserTyping).from_id);
if(rootScope.myId === fromId || update.action._ === 'speakingInGroupCallAction') { if(rootScope.myId === fromId || update.action._ === 'speakingInGroupCallAction') {

6
src/lib/appManagers/appDialogsManager.ts

@ -40,6 +40,7 @@ import { attachClickEvent } from "../../helpers/dom/clickEvent";
import positionElementByIndex from "../../helpers/dom/positionElementByIndex"; import positionElementByIndex from "../../helpers/dom/positionElementByIndex";
import replaceContent from "../../helpers/dom/replaceContent"; import replaceContent from "../../helpers/dom/replaceContent";
import ConnectionStatusComponent from "../../components/connectionStatus"; import ConnectionStatusComponent from "../../components/connectionStatus";
import appChatsManager from "./appChatsManager";
export type DialogDom = { export type DialogDom = {
avatarEl: AvatarElement, avatarEl: AvatarElement,
@ -324,6 +325,11 @@ export class AppDialogsManager {
} }
}); });
/* rootScope.addEventListener('state_cleared', () => {
appUsersManager.clear();
appChatsManager.clear();
}); */
const foldersScrollable = new ScrollableX(this.folders.menuScrollContainer); const foldersScrollable = new ScrollableX(this.folders.menuScrollContainer);
bottomPart.prepend(this.folders.menuScrollContainer); bottomPart.prepend(this.folders.menuScrollContainer);
const selectTab = horizontalMenu(this.folders.menu, this.folders.container, (id, tabContent) => { const selectTab = horizontalMenu(this.folders.menu, this.folders.container, (id, tabContent) => {

8
src/lib/appManagers/appStateManager.ts

@ -24,7 +24,7 @@ import DATABASE_STATE from '../../config/databases/state';
import sessionStorage from '../sessionStorage'; import sessionStorage from '../sessionStorage';
const REFRESH_EVERY = 24 * 60 * 60 * 1000; // 1 day 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; const STATE_VERSION = App.version;
export type Background = { export type Background = {
@ -159,7 +159,7 @@ const ALL_KEYS = Object.keys(STATE_INIT) as any as Array<keyof State>;
const REFRESH_KEYS = ['contactsList', 'stateCreatedTime', const REFRESH_KEYS = ['contactsList', 'stateCreatedTime',
'maxSeenMsgId', 'filters', 'topPeers'] as any as Array<keyof State>; 'maxSeenMsgId', 'filters', 'topPeers'] as any as Array<keyof State>;
const REFRESH_KEYS_WEEK = ['dialogs', 'allDialogsLoaded', 'updates', 'pinnedOrders'] as any as Array<keyof State>; //const REFRESH_KEYS_WEEK = ['dialogs', 'allDialogsLoaded', 'updates', 'pinnedOrders'] as any as Array<keyof State>;
export class AppStateManager extends EventListenerBase<{ export class AppStateManager extends EventListenerBase<{
save: (state: State) => Promise<void>, save: (state: State) => Promise<void>,
@ -330,13 +330,13 @@ export class AppStateManager extends EventListenerBase<{
r(REFRESH_KEYS); r(REFRESH_KEYS);
if((state.stateCreatedTime + REFRESH_EVERY_WEEK) < time) { /* if((state.stateCreatedTime + REFRESH_EVERY_WEEK) < time) {
if(DEBUG) { if(DEBUG) {
this.log('will refresh updates'); this.log('will refresh updates');
} }
r(REFRESH_KEYS_WEEK); r(REFRESH_KEYS_WEEK);
} } */
} }
//state = this.state = new Proxy(state, getHandler()); //state = this.state = new Proxy(state, getHandler());

35
src/lib/appManagers/appUsersManager.ts

@ -36,16 +36,18 @@ export type User = MTUser.user;
export class AppUsersManager { export class AppUsersManager {
private storage = appStateManager.storages.users; private storage = appStateManager.storages.users;
private users: {[userId: number]: User} = {}; private users: {[userId: number]: User};
private usernames: {[username: string]: number} = {}; private usernames: {[username: string]: number};
private contactsIndex = new SearchIndex<number>(); private contactsIndex: SearchIndex<number>;
private contactsFillPromise: Promise<Set<number>>; private contactsFillPromise: Promise<Set<number>>;
private contactsList: Set<number> = new Set(); private contactsList: Set<number>;
private updatedContactsList = false; private updatedContactsList: boolean;
private getTopPeersPromise: Promise<number[]>; private getTopPeersPromise: Promise<number[]>;
constructor() { constructor() {
this.clear();
setInterval(this.updateUsersStatuses, 60000); setInterval(this.updateUsersStatuses, 60000);
rootScope.addEventListener('state_synchronized', this.updateUsersStatuses); 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() { private onContactsModified() {
const contactsList = [...this.contactsList]; const contactsList = [...this.contactsList];
appStateManager.pushToState('contactsList', contactsList); appStateManager.pushToState('contactsList', contactsList);

9
src/lib/idb.ts

@ -53,16 +53,17 @@ export default class IDBStorage<T extends Database<any>> {
constructor(db: T, storeName: typeof db['stores'][0]['name']) { constructor(db: T, storeName: typeof db['stores'][0]['name']) {
safeAssign(this, db); safeAssign(this, db);
if(Modes.test) {
this.name += '_test';
}
this.storeName = storeName; this.storeName = storeName;
this.log = logger('IDB-' + this.storeName); this.log = logger('IDB-' + this.storeName);
this.openDatabase(true); this.openDatabase(true);
if(Modes.test) {
this.name += '_test';
}
IDBStorage.STORAGES.push(this); IDBStorage.STORAGES.push(this);
} }

10
src/lib/mtproto/mtproto.service.ts

@ -50,17 +50,23 @@ ctx.addEventListener('message', (e) => {
//const cacheStorage = new CacheStorageController('cachedAssets'); //const cacheStorage = new CacheStorageController('cachedAssets');
let taskId = 0; let taskId = 0;
function isCorrectResponse(response: Response) {
return response.ok && response.status === 200;
}
async function requestCache(event: FetchEvent) { async function requestCache(event: FetchEvent) {
try { try {
const cache = await ctx.caches.open('cachedAssets'); const cache = await ctx.caches.open('cachedAssets');
const file = await cache.match(event.request); const file = await cache.match(event.request);
if(file) { if(file && isCorrectResponse(file)) {
return file; return file;
} }
const response = await fetch(event.request); const response = await fetch(event.request);
cache.put(event.request, response.clone()); if(isCorrectResponse(response)) {
cache.put(event.request, response.clone());
}
return response; return response;
} catch(err) { } catch(err) {

2
src/lib/storages/dialogs.ts

@ -302,7 +302,7 @@ export default class DialogsStorage {
dialog.topMessage = incomingMessage; dialog.topMessage = incomingMessage;
if(dialog.peerId < 0 && dialog.pts) { 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; dialog.pts = newPts;
} }

Loading…
Cancel
Save