Migrate session from IndexedDB to LocalStorage
This commit is contained in:
parent
02e2802d6d
commit
f8069d3e85
@ -36,6 +36,7 @@ import PeerTitle from "../peerTitle";
|
|||||||
import App from "../../config/app";
|
import App from "../../config/app";
|
||||||
import ButtonMenuToggle from "../buttonMenuToggle";
|
import ButtonMenuToggle from "../buttonMenuToggle";
|
||||||
import replaceContent from "../../helpers/dom/replaceContent";
|
import replaceContent from "../../helpers/dom/replaceContent";
|
||||||
|
import sessionStorage from "../../lib/sessionStorage";
|
||||||
|
|
||||||
export const LEFT_COLUMN_ACTIVE_CLASSNAME = 'is-left-column-shown';
|
export const LEFT_COLUMN_ACTIVE_CLASSNAME = 'is-left-column-shown';
|
||||||
|
|
||||||
@ -171,7 +172,9 @@ export class AppSidebarLeft extends SidebarSlider {
|
|||||||
icon: 'char z',
|
icon: 'char z',
|
||||||
text: 'ChatList.Menu.SwitchTo.Z',
|
text: 'ChatList.Menu.SwitchTo.Z',
|
||||||
onClick: () => {
|
onClick: () => {
|
||||||
|
sessionStorage.set({kz_version: 'z'}).then(() => {
|
||||||
location.href = 'https://web.telegram.org/z/';
|
location.href = 'https://web.telegram.org/z/';
|
||||||
|
});
|
||||||
},
|
},
|
||||||
verify: () => App.isMainDomain
|
verify: () => App.isMainDomain
|
||||||
}, {
|
}, {
|
||||||
|
@ -263,7 +263,7 @@ export class AppStateManager extends EventListenerBase<{
|
|||||||
|
|
||||||
const values = await Promise.all(keys.map(key => stateStorage.get(key as any)));
|
const values = await Promise.all(keys.map(key => stateStorage.get(key as any)));
|
||||||
keys.push('user_auth');
|
keys.push('user_auth');
|
||||||
values.push(typeof(auth) === 'number' ? {dcID: values[0] || App.baseDcId, id: auth} : auth);
|
values.push(typeof(auth) === 'number' ? {dcID: values[0] || App.baseDcId, date: Date.now() / 1000 | 0, id: auth} as UserAuth : auth);
|
||||||
|
|
||||||
let obj: any = {};
|
let obj: any = {};
|
||||||
keys.forEach((key, idx) => {
|
keys.forEach((key, idx) => {
|
||||||
@ -273,7 +273,7 @@ export class AppStateManager extends EventListenerBase<{
|
|||||||
await sessionStorage.set(obj);
|
await sessionStorage.set(obj);
|
||||||
}
|
}
|
||||||
|
|
||||||
if(!auth) { // try to read Webogram's session from localStorage
|
/* if(!auth) { // try to read Webogram's session from localStorage
|
||||||
try {
|
try {
|
||||||
const keys = Object.keys(localStorage);
|
const keys = Object.keys(localStorage);
|
||||||
for(let i = 0; i < keys.length; ++i) {
|
for(let i = 0; i < keys.length; ++i) {
|
||||||
@ -295,12 +295,12 @@ export class AppStateManager extends EventListenerBase<{
|
|||||||
} catch(err) {
|
} catch(err) {
|
||||||
this.log.error('localStorage import error', err);
|
this.log.error('localStorage import error', err);
|
||||||
}
|
}
|
||||||
}
|
} */
|
||||||
|
|
||||||
if(auth) {
|
if(auth) {
|
||||||
// ! Warning ! DON'T delete this
|
// ! Warning ! DON'T delete this
|
||||||
state.authState = {_: 'authStateSignedIn'};
|
state.authState = {_: 'authStateSignedIn'};
|
||||||
rootScope.dispatchEvent('user_auth', typeof(auth) === 'number' ? {dcID: 0, id: auth} : auth); // * support old version
|
rootScope.dispatchEvent('user_auth', typeof(auth) === 'number' ? {dcID: 0, date: Date.now() / 1000 | 0, id: auth} : auth); // * support old version
|
||||||
}
|
}
|
||||||
|
|
||||||
// * Read storages
|
// * Read storages
|
||||||
|
@ -24,6 +24,10 @@ export default class CacheStorageController {
|
|||||||
this.dbName += '_test';
|
this.dbName += '_test';
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if(CacheStorageController.STORAGES.length) {
|
||||||
|
this.useStorage = CacheStorageController.STORAGES[0].useStorage;
|
||||||
|
}
|
||||||
|
|
||||||
this.openDatabase();
|
this.openDatabase();
|
||||||
CacheStorageController.STORAGES.push(this);
|
CacheStorageController.STORAGES.push(this);
|
||||||
}
|
}
|
||||||
@ -131,7 +135,7 @@ export default class CacheStorageController {
|
|||||||
|
|
||||||
public getFileWriter(fileName: string, mimeType: string) {
|
public getFileWriter(fileName: string, mimeType: string) {
|
||||||
const fakeWriter = FileManager.getFakeFileWriter(mimeType, (blob) => {
|
const fakeWriter = FileManager.getFakeFileWriter(mimeType, (blob) => {
|
||||||
return this.saveFile(fileName, blob);
|
return this.saveFile(fileName, blob).catch(() => blob);
|
||||||
});
|
});
|
||||||
|
|
||||||
return Promise.resolve(fakeWriter);
|
return Promise.resolve(fakeWriter);
|
||||||
|
206
src/lib/localStorage.ts
Normal file
206
src/lib/localStorage.ts
Normal file
@ -0,0 +1,206 @@
|
|||||||
|
/*
|
||||||
|
* https://github.com/morethanwords/tweb
|
||||||
|
* Copyright (C) 2019-2021 Eduard Kuzmenko
|
||||||
|
* https://github.com/morethanwords/tweb/blob/master/LICENSE
|
||||||
|
*
|
||||||
|
* Originally from:
|
||||||
|
* https://github.com/zhukov/webogram
|
||||||
|
* Copyright (C) 2014 Igor Zhukov <igor.beatle@gmail.com>
|
||||||
|
* https://github.com/zhukov/webogram/blob/master/LICENSE
|
||||||
|
*/
|
||||||
|
|
||||||
|
import Modes from '../config/modes';
|
||||||
|
import { notifySomeone, isWorker } from '../helpers/context';
|
||||||
|
import { WorkerTaskTemplate } from '../types';
|
||||||
|
//import { stringify } from '../helpers/json';
|
||||||
|
|
||||||
|
class LocalStorage<Storage extends Record<string, any>> {
|
||||||
|
private prefix = '';
|
||||||
|
private cache: Partial<Storage> = {};
|
||||||
|
private useStorage = true;
|
||||||
|
|
||||||
|
constructor(private preserveKeys: (keyof Storage)[]) {
|
||||||
|
if(Modes.test) {
|
||||||
|
this.prefix = 't_';
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public get<T extends keyof Storage>(key: T, useCache = true): Storage[T] {
|
||||||
|
if(this.cache.hasOwnProperty(key) && useCache) {
|
||||||
|
return this.cache[key];
|
||||||
|
} else if(this.useStorage) {
|
||||||
|
let value: Storage[T];
|
||||||
|
try {
|
||||||
|
value = localStorage.getItem(this.prefix + key as string) as any;
|
||||||
|
} catch(err) {
|
||||||
|
this.useStorage = false;
|
||||||
|
}
|
||||||
|
|
||||||
|
if(value !== null) {
|
||||||
|
try {
|
||||||
|
value = JSON.parse(value);
|
||||||
|
} catch(err) {
|
||||||
|
//console.error(err);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return value;
|
||||||
|
}/* else {
|
||||||
|
throw 'something went wrong';
|
||||||
|
} */
|
||||||
|
}
|
||||||
|
|
||||||
|
public set(obj: Partial<Storage>, onlyLocal = false) {
|
||||||
|
for(const key in obj) {
|
||||||
|
if(obj.hasOwnProperty(key)) {
|
||||||
|
const value = obj[key];
|
||||||
|
this.cache[key] = value;
|
||||||
|
|
||||||
|
if(this.useStorage && !onlyLocal) {
|
||||||
|
try {
|
||||||
|
const stringified = JSON.stringify(value);
|
||||||
|
localStorage.setItem(this.prefix + key, stringified);
|
||||||
|
} catch(err) {
|
||||||
|
this.useStorage = false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public delete(key: keyof Storage, saveLocal = false) {
|
||||||
|
// ! it is needed here
|
||||||
|
key = '' + key;
|
||||||
|
|
||||||
|
if(!saveLocal) {
|
||||||
|
delete this.cache[key];
|
||||||
|
}
|
||||||
|
|
||||||
|
if(this.useStorage) {
|
||||||
|
localStorage.removeItem(this.prefix + key);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public clear(preserveKeys: (keyof Storage)[] = this.preserveKeys) {
|
||||||
|
// if(this.useStorage) {
|
||||||
|
try {
|
||||||
|
let obj: Partial<Storage> = {};
|
||||||
|
if(preserveKeys) {
|
||||||
|
preserveKeys.forEach(key => {
|
||||||
|
const value = this.get(key);
|
||||||
|
if(value !== undefined) {
|
||||||
|
obj[key] = value;
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
localStorage.clear();
|
||||||
|
|
||||||
|
if(preserveKeys) {
|
||||||
|
this.set(obj);
|
||||||
|
}
|
||||||
|
} catch(err) {
|
||||||
|
|
||||||
|
}
|
||||||
|
// }
|
||||||
|
}
|
||||||
|
|
||||||
|
public toggleStorage(enabled: boolean) {
|
||||||
|
this.useStorage = enabled;
|
||||||
|
|
||||||
|
if(!enabled) {
|
||||||
|
this.clear();
|
||||||
|
} else {
|
||||||
|
return this.set(this.cache);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
export interface LocalStorageProxyTask extends WorkerTaskTemplate {
|
||||||
|
type: 'localStorageProxy',
|
||||||
|
payload: {
|
||||||
|
type: 'set' | 'get' | 'delete' | 'clear' | 'toggleStorage',
|
||||||
|
args: any[]
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
export interface LocalStorageProxyTaskResponse extends WorkerTaskTemplate {
|
||||||
|
type: 'localStorageProxy',
|
||||||
|
payload: any
|
||||||
|
};
|
||||||
|
|
||||||
|
export default class LocalStorageController<Storage extends Record<string, any>> {
|
||||||
|
private static STORAGES: LocalStorageController<any>[] = [];
|
||||||
|
private taskId = 0;
|
||||||
|
private tasks: {[taskID: number]: (result: any) => void} = {};
|
||||||
|
//private log = (...args: any[]) => console.log('[SW LS]', ...args);
|
||||||
|
//private log = (...args: any[]) => {};
|
||||||
|
|
||||||
|
private storage: LocalStorage<Storage>;
|
||||||
|
|
||||||
|
constructor(private preserveKeys: (keyof Storage)[] = []) {
|
||||||
|
LocalStorageController.STORAGES.push(this);
|
||||||
|
|
||||||
|
if(!isWorker) {
|
||||||
|
this.storage = new LocalStorage(preserveKeys);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public finishTask(taskId: number, result: any) {
|
||||||
|
//this.log('finishTask:', taskID, result, Object.keys(this.tasks));
|
||||||
|
|
||||||
|
if(!this.tasks.hasOwnProperty(taskId)) {
|
||||||
|
//this.log('no such task:', taskID, result);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
this.tasks[taskId](result);
|
||||||
|
delete this.tasks[taskId];
|
||||||
|
}
|
||||||
|
|
||||||
|
private proxy<T>(type: LocalStorageProxyTask['payload']['type'], ...args: LocalStorageProxyTask['payload']['args']) {
|
||||||
|
return new Promise<T>((resolve, reject) => {
|
||||||
|
if(isWorker) {
|
||||||
|
const taskId = this.taskId++;
|
||||||
|
|
||||||
|
this.tasks[taskId] = resolve;
|
||||||
|
const task: LocalStorageProxyTask = {
|
||||||
|
type: 'localStorageProxy',
|
||||||
|
id: taskId,
|
||||||
|
payload: {
|
||||||
|
type,
|
||||||
|
args
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
notifySomeone(task);
|
||||||
|
} else {
|
||||||
|
args = Array.prototype.slice.call(args);
|
||||||
|
|
||||||
|
// @ts-ignore
|
||||||
|
const result: any = this.storage[type].apply(this.storage, args as any);
|
||||||
|
resolve(result);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
public get<T extends keyof Storage>(key: T, useCache?: boolean) {
|
||||||
|
return this.proxy<Storage[T]>('get', key, useCache);
|
||||||
|
}
|
||||||
|
|
||||||
|
public set(obj: Partial<Storage>, onlyLocal?: boolean) {
|
||||||
|
return this.proxy<void>('set', obj, onlyLocal);
|
||||||
|
}
|
||||||
|
|
||||||
|
public delete(key: keyof Storage, saveLocal?: boolean) {
|
||||||
|
return this.proxy<void>('delete', key, saveLocal);
|
||||||
|
}
|
||||||
|
|
||||||
|
public clear(preserveKeys?: (keyof Storage)[]) {
|
||||||
|
return this.proxy<void>('clear', preserveKeys);
|
||||||
|
}
|
||||||
|
|
||||||
|
public toggleStorage(enabled: boolean) {
|
||||||
|
return this.proxy<void>('toggleStorage', enabled);
|
||||||
|
}
|
||||||
|
}
|
@ -15,8 +15,11 @@ import type { ServiceWorkerTask, ServiceWorkerTaskResponse } from './mtproto.ser
|
|||||||
import { ctx } from '../../helpers/userAgent';
|
import { ctx } from '../../helpers/userAgent';
|
||||||
import { socketsProxied } from './dcConfigurator';
|
import { socketsProxied } from './dcConfigurator';
|
||||||
import { notifyAll } from '../../helpers/context';
|
import { notifyAll } from '../../helpers/context';
|
||||||
import AppStorage from '../storage';
|
// import AppStorage from '../storage';
|
||||||
import CacheStorageController from '../cacheStorage';
|
import CacheStorageController from '../cacheStorage';
|
||||||
|
import sessionStorage from '../sessionStorage';
|
||||||
|
import { LocalStorageProxyTask } from '../localStorage';
|
||||||
|
import { WebpConvertTask } from '../webp/webpWorkerController';
|
||||||
|
|
||||||
let webpSupported = false;
|
let webpSupported = false;
|
||||||
export const isWebpSupported = () => {
|
export const isWebpSupported = () => {
|
||||||
@ -31,22 +34,17 @@ networkerFactory.onConnectionStatusChange = (status) => {
|
|||||||
notifyAll({type: 'connectionStatusChange', payload: status});
|
notifyAll({type: 'connectionStatusChange', payload: status});
|
||||||
};
|
};
|
||||||
|
|
||||||
const onMessage = async(e: any) => {
|
const taskListeners = {
|
||||||
try {
|
convertWebp: (task: WebpConvertTask) => {
|
||||||
const task = e.data;
|
|
||||||
const taskId = task.taskId;
|
|
||||||
|
|
||||||
if(task.type === 'convertWebp') {
|
|
||||||
const {fileName, bytes} = task.payload;
|
const {fileName, bytes} = task.payload;
|
||||||
const deferred = apiFileManager.webpConvertPromises[fileName];
|
const deferred = apiFileManager.webpConvertPromises[fileName];
|
||||||
if(deferred) {
|
if(deferred) {
|
||||||
deferred.resolve(bytes);
|
deferred.resolve(bytes);
|
||||||
delete apiFileManager.webpConvertPromises[fileName];
|
delete apiFileManager.webpConvertPromises[fileName];
|
||||||
}
|
}
|
||||||
|
},
|
||||||
|
|
||||||
return;
|
requestFilePart: async(task: ServiceWorkerTask) => {
|
||||||
} else if((task as ServiceWorkerTask).type === 'requestFilePart') {
|
|
||||||
const task = e.data as ServiceWorkerTask;
|
|
||||||
const responseTask: ServiceWorkerTaskResponse = {
|
const responseTask: ServiceWorkerTaskResponse = {
|
||||||
type: task.type,
|
type: task.type,
|
||||||
id: task.id
|
id: task.id
|
||||||
@ -61,11 +59,13 @@ const onMessage = async(e: any) => {
|
|||||||
}
|
}
|
||||||
|
|
||||||
notifyAll(responseTask);
|
notifyAll(responseTask);
|
||||||
return;
|
},
|
||||||
} else if(task.type === 'webpSupport') {
|
|
||||||
|
webpSupport: (task: any) => {
|
||||||
webpSupported = task.payload;
|
webpSupported = task.payload;
|
||||||
return;
|
},
|
||||||
} else if(task.type === 'socketProxy') {
|
|
||||||
|
socketProxy: (task: any) => {
|
||||||
const socketTask = task.payload;
|
const socketTask = task.payload;
|
||||||
const id = socketTask.id;
|
const id = socketTask.id;
|
||||||
|
|
||||||
@ -78,6 +78,23 @@ const onMessage = async(e: any) => {
|
|||||||
socketProxied.dispatchEvent('close');
|
socketProxied.dispatchEvent('close');
|
||||||
socketsProxied.delete(id);
|
socketsProxied.delete(id);
|
||||||
}
|
}
|
||||||
|
},
|
||||||
|
|
||||||
|
localStorageProxy: (task: LocalStorageProxyTask) => {
|
||||||
|
sessionStorage.finishTask(task.id, task.payload);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
const onMessage = async(e: any) => {
|
||||||
|
try {
|
||||||
|
const task = e.data;
|
||||||
|
const taskId = task.taskId;
|
||||||
|
|
||||||
|
// @ts-ignore
|
||||||
|
const f = taskListeners[task.type];
|
||||||
|
if(f) {
|
||||||
|
f(task);
|
||||||
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
if(!task.task) {
|
if(!task.task) {
|
||||||
@ -126,7 +143,7 @@ const onMessage = async(e: any) => {
|
|||||||
|
|
||||||
case 'toggleStorage': {
|
case 'toggleStorage': {
|
||||||
const enabled = task.args[0];
|
const enabled = task.args[0];
|
||||||
AppStorage.toggleStorage(enabled);
|
// AppStorage.toggleStorage(enabled);
|
||||||
CacheStorageController.toggleStorage(enabled);
|
CacheStorageController.toggleStorage(enabled);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
@ -5,8 +5,8 @@
|
|||||||
*/
|
*/
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Legacy Webogram's format, don't change dcID to camelCase.
|
* Legacy Webogram's format, don't change dcID to camelCase. date is timestamp
|
||||||
*/
|
*/
|
||||||
export type UserAuth = {dcID: number, id: number};
|
export type UserAuth = {dcID: number | string, date: number, id: number};
|
||||||
|
|
||||||
export const REPLIES_PEER_ID = 1271266957;
|
export const REPLIES_PEER_ID = 1271266957;
|
||||||
|
@ -4,7 +4,8 @@
|
|||||||
* https://github.com/morethanwords/tweb/blob/master/LICENSE
|
* https://github.com/morethanwords/tweb/blob/master/LICENSE
|
||||||
*/
|
*/
|
||||||
|
|
||||||
import type { LocalStorageProxyDeleteTask, LocalStorageProxySetTask } from '../storage';
|
import type { LocalStorageProxyTask, LocalStorageProxyTaskResponse } from '../localStorage';
|
||||||
|
//import type { LocalStorageProxyDeleteTask, LocalStorageProxySetTask } from '../storage';
|
||||||
import type { InvokeApiOptions } from '../../types';
|
import type { InvokeApiOptions } from '../../types';
|
||||||
import type { MethodDeclMap } from '../../layer';
|
import type { MethodDeclMap } from '../../layer';
|
||||||
import MTProtoWorker from 'worker-loader!./mtproto.worker';
|
import MTProtoWorker from 'worker-loader!./mtproto.worker';
|
||||||
@ -22,6 +23,7 @@ import DEBUG, { MOUNT_CLASS_TO } from '../../config/debug';
|
|||||||
import Socket from './transports/websocket';
|
import Socket from './transports/websocket';
|
||||||
import IDBStorage from '../idb';
|
import IDBStorage from '../idb';
|
||||||
import singleInstance from './singleInstance';
|
import singleInstance from './singleInstance';
|
||||||
|
import sessionStorage from '../sessionStorage';
|
||||||
|
|
||||||
type Task = {
|
type Task = {
|
||||||
taskId: number,
|
taskId: number,
|
||||||
@ -93,9 +95,10 @@ export class ApiManagerProxy extends CryptoWorkerMethods {
|
|||||||
this.registerServiceWorker();
|
this.registerServiceWorker();
|
||||||
|
|
||||||
this.addTaskListener('clear', () => {
|
this.addTaskListener('clear', () => {
|
||||||
const promise = IDBStorage.deleteDatabase();
|
Promise.all([
|
||||||
localStorage.clear(); // * clear legacy Webogram's localStorage
|
IDBStorage.deleteDatabase(),
|
||||||
promise.finally(() => {
|
sessionStorage.clear()
|
||||||
|
]).finally(() => {
|
||||||
location.reload();
|
location.reload();
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
@ -164,19 +167,16 @@ export class ApiManagerProxy extends CryptoWorkerMethods {
|
|||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
this.addTaskListener('localStorageProxy', (task: LocalStorageProxySetTask | LocalStorageProxyDeleteTask) => {
|
this.addTaskListener('localStorageProxy', (task: LocalStorageProxyTask) => {
|
||||||
const storageTask = task.payload;
|
const storageTask = task.payload;
|
||||||
if(storageTask.type === 'set') {
|
// @ts-ignore
|
||||||
for(let i = 0, length = storageTask.keys.length; i < length; ++i) {
|
sessionStorage[storageTask.type](...storageTask.args).then(res => {
|
||||||
if(storageTask.values[i] !== undefined) {
|
this.postMessage({
|
||||||
localStorage.setItem(storageTask.keys[i], JSON.stringify(storageTask.values[i]));
|
type: 'localStorageProxy',
|
||||||
}
|
id: task.id,
|
||||||
}
|
payload: res
|
||||||
} else if(storageTask.type === 'delete') {
|
} as LocalStorageProxyTaskResponse);
|
||||||
for(let i = 0, length = storageTask.keys.length; i < length; ++i) {
|
});
|
||||||
localStorage.removeItem(storageTask.keys[i]);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
});
|
});
|
||||||
|
|
||||||
rootScope.addEventListener('language_change', (language) => {
|
rootScope.addEventListener('language_change', (language) => {
|
||||||
@ -483,7 +483,7 @@ export class ApiManagerProxy extends CryptoWorkerMethods {
|
|||||||
|
|
||||||
public setUserAuth(userAuth: UserAuth | number) {
|
public setUserAuth(userAuth: UserAuth | number) {
|
||||||
if(typeof(userAuth) === 'number') {
|
if(typeof(userAuth) === 'number') {
|
||||||
userAuth = {dcID: 0, id: userAuth};
|
userAuth = {dcID: 0, date: Date.now() / 1000 | 0, id: userAuth};
|
||||||
}
|
}
|
||||||
|
|
||||||
rootScope.dispatchEvent('user_auth', userAuth);
|
rootScope.dispatchEvent('user_auth', userAuth);
|
||||||
|
@ -7,10 +7,9 @@
|
|||||||
import type { AppInstance } from './mtproto/singleInstance';
|
import type { AppInstance } from './mtproto/singleInstance';
|
||||||
import type { UserAuth } from './mtproto/mtproto_config';
|
import type { UserAuth } from './mtproto/mtproto_config';
|
||||||
import { MOUNT_CLASS_TO } from '../config/debug';
|
import { MOUNT_CLASS_TO } from '../config/debug';
|
||||||
import AppStorage from './storage';
|
import LocalStorageController from './localStorage';
|
||||||
import DATABASE_SESSION from '../config/databases/session';
|
|
||||||
|
|
||||||
const sessionStorage = new AppStorage<{
|
const sessionStorage = new LocalStorageController<{
|
||||||
dc: number,
|
dc: number,
|
||||||
user_auth: UserAuth,
|
user_auth: UserAuth,
|
||||||
dc1_auth_key: string,
|
dc1_auth_key: string,
|
||||||
@ -24,7 +23,8 @@ const sessionStorage = new AppStorage<{
|
|||||||
dc4_server_salt: string,
|
dc4_server_salt: string,
|
||||||
dc5_server_salt: string,
|
dc5_server_salt: string,
|
||||||
server_time_offset: number,
|
server_time_offset: number,
|
||||||
xt_instance: AppInstance
|
xt_instance: AppInstance,
|
||||||
}, typeof DATABASE_SESSION>(DATABASE_SESSION, 'session');
|
kz_version: 'k' | 'z'
|
||||||
|
}>(['kz_version']);
|
||||||
MOUNT_CLASS_TO.appStorage = sessionStorage;
|
MOUNT_CLASS_TO.appStorage = sessionStorage;
|
||||||
export default sessionStorage;
|
export default sessionStorage;
|
||||||
|
@ -10,15 +10,15 @@
|
|||||||
*/
|
*/
|
||||||
|
|
||||||
import { Database } from "../config/databases";
|
import { Database } from "../config/databases";
|
||||||
import DATABASE_SESSION from "../config/databases/session";
|
//import DATABASE_SESSION from "../config/databases/session";
|
||||||
import { CancellablePromise, deferredPromise } from "../helpers/cancellablePromise";
|
import { CancellablePromise, deferredPromise } from "../helpers/cancellablePromise";
|
||||||
import { throttle } from "../helpers/schedulers";
|
import { throttle } from "../helpers/schedulers";
|
||||||
import { WorkerTaskTemplate } from "../types";
|
//import { WorkerTaskTemplate } from "../types";
|
||||||
import IDBStorage from "./idb";
|
import IDBStorage from "./idb";
|
||||||
|
|
||||||
function noop() {}
|
function noop() {}
|
||||||
|
|
||||||
export interface LocalStorageProxySetTask extends WorkerTaskTemplate {
|
/* export interface LocalStorageProxySetTask extends WorkerTaskTemplate {
|
||||||
type: 'localStorageProxy',
|
type: 'localStorageProxy',
|
||||||
payload: {
|
payload: {
|
||||||
type: 'set',
|
type: 'set',
|
||||||
@ -33,7 +33,7 @@ export interface LocalStorageProxyDeleteTask extends WorkerTaskTemplate {
|
|||||||
type: 'delete',
|
type: 'delete',
|
||||||
keys: string[]
|
keys: string[]
|
||||||
}
|
}
|
||||||
};
|
}; */
|
||||||
|
|
||||||
export default class AppStorage<Storage extends Record<string, any>, T extends Database<any>/* Storage extends {[name: string]: any} *//* Storage extends Record<string, any> */> {
|
export default class AppStorage<Storage extends Record<string, any>, T extends Database<any>/* Storage extends {[name: string]: any} *//* Storage extends Record<string, any> */> {
|
||||||
private static STORAGES: AppStorage<any, Database<any>>[] = [];
|
private static STORAGES: AppStorage<any, Database<any>>[] = [];
|
||||||
@ -57,6 +57,10 @@ export default class AppStorage<Storage extends Record<string, any>, T extends D
|
|||||||
constructor(private db: T, storeName: typeof db['stores'][number]['name']) {
|
constructor(private db: T, storeName: typeof db['stores'][number]['name']) {
|
||||||
this.storage = new IDBStorage<T>(db, storeName);
|
this.storage = new IDBStorage<T>(db, storeName);
|
||||||
|
|
||||||
|
if(AppStorage.STORAGES.length) {
|
||||||
|
this.useStorage = AppStorage.STORAGES[0].useStorage;
|
||||||
|
}
|
||||||
|
|
||||||
AppStorage.STORAGES.push(this);
|
AppStorage.STORAGES.push(this);
|
||||||
|
|
||||||
this.saveThrottled = throttle(async() => {
|
this.saveThrottled = throttle(async() => {
|
||||||
@ -74,7 +78,7 @@ export default class AppStorage<Storage extends Record<string, any>, T extends D
|
|||||||
//await this.storage.save(key, new Response(value, {headers: {'Content-Type': 'application/json'}}));
|
//await this.storage.save(key, new Response(value, {headers: {'Content-Type': 'application/json'}}));
|
||||||
|
|
||||||
const values = keys.map(key => this.cache[key]);
|
const values = keys.map(key => this.cache[key]);
|
||||||
if(db === DATABASE_SESSION && !('localStorage' in self)) { // * support legacy Webogram's localStorage
|
/* if(db === DATABASE_SESSION && !('localStorage' in self)) { // * support legacy Webogram's localStorage
|
||||||
self.postMessage({
|
self.postMessage({
|
||||||
type: 'localStorageProxy',
|
type: 'localStorageProxy',
|
||||||
payload: {
|
payload: {
|
||||||
@ -83,7 +87,7 @@ export default class AppStorage<Storage extends Record<string, any>, T extends D
|
|||||||
values
|
values
|
||||||
}
|
}
|
||||||
} as LocalStorageProxySetTask);
|
} as LocalStorageProxySetTask);
|
||||||
}
|
} */
|
||||||
|
|
||||||
await this.storage.save(keys, values);
|
await this.storage.save(keys, values);
|
||||||
//console.log('setItem: have set', key/* , value */);
|
//console.log('setItem: have set', key/* , value */);
|
||||||
@ -110,7 +114,7 @@ export default class AppStorage<Storage extends Record<string, any>, T extends D
|
|||||||
set.clear();
|
set.clear();
|
||||||
|
|
||||||
try {
|
try {
|
||||||
if(db === DATABASE_SESSION && !('localStorage' in self)) { // * support legacy Webogram's localStorage
|
/* if(db === DATABASE_SESSION && !('localStorage' in self)) { // * support legacy Webogram's localStorage
|
||||||
self.postMessage({
|
self.postMessage({
|
||||||
type: 'localStorageProxy',
|
type: 'localStorageProxy',
|
||||||
payload: {
|
payload: {
|
||||||
@ -118,7 +122,7 @@ export default class AppStorage<Storage extends Record<string, any>, T extends D
|
|||||||
keys
|
keys
|
||||||
}
|
}
|
||||||
} as LocalStorageProxyDeleteTask);
|
} as LocalStorageProxyDeleteTask);
|
||||||
}
|
} */
|
||||||
|
|
||||||
await this.storage.delete(keys);
|
await this.storage.delete(keys);
|
||||||
} catch(e) {
|
} catch(e) {
|
||||||
@ -275,19 +279,19 @@ export default class AppStorage<Storage extends Record<string, any>, T extends D
|
|||||||
storage.getPromises.forEach((deferred) => deferred.resolve());
|
storage.getPromises.forEach((deferred) => deferred.resolve());
|
||||||
storage.getPromises.clear();
|
storage.getPromises.clear();
|
||||||
|
|
||||||
if(storage.db === DATABASE_SESSION && 'localStorage' in self) { // * support legacy Webogram's localStorage
|
/* if(storage.db === DATABASE_SESSION && 'localStorage' in self) { // * support legacy Webogram's localStorage
|
||||||
localStorage.clear();
|
localStorage.clear();
|
||||||
}
|
} */
|
||||||
|
|
||||||
return storage.clear();
|
return storage.clear();
|
||||||
} else {
|
} else {
|
||||||
if(storage.db === DATABASE_SESSION && 'localStorage' in self) { // * support legacy Webogram's localStorage
|
/* if(storage.db === DATABASE_SESSION && 'localStorage' in self) { // * support legacy Webogram's localStorage
|
||||||
for(const i in storage.cache) {
|
for(const i in storage.cache) {
|
||||||
if(storage.cache[i] !== undefined) {
|
if(storage.cache[i] !== undefined) {
|
||||||
localStorage.setItem(i, JSON.stringify(storage.cache[i]));
|
localStorage.setItem(i, JSON.stringify(storage.cache[i]));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
} */
|
||||||
|
|
||||||
return storage.set(storage.cache);
|
return storage.set(storage.cache);
|
||||||
}
|
}
|
||||||
|
@ -33,6 +33,7 @@ import { cancelEvent } from "../helpers/dom/cancelEvent";
|
|||||||
import { attachClickEvent } from "../helpers/dom/clickEvent";
|
import { attachClickEvent } from "../helpers/dom/clickEvent";
|
||||||
import replaceContent from "../helpers/dom/replaceContent";
|
import replaceContent from "../helpers/dom/replaceContent";
|
||||||
import toggleDisability from "../helpers/dom/toggleDisability";
|
import toggleDisability from "../helpers/dom/toggleDisability";
|
||||||
|
import sessionStorage from "../lib/sessionStorage";
|
||||||
|
|
||||||
type Country = _Country & {
|
type Country = _Country & {
|
||||||
li?: HTMLLIElement[]
|
li?: HTMLLIElement[]
|
||||||
@ -332,6 +333,7 @@ let onFirstMount = () => {
|
|||||||
AppStorage.toggleStorage(keepSigned);
|
AppStorage.toggleStorage(keepSigned);
|
||||||
CacheStorageController.toggleStorage(keepSigned);
|
CacheStorageController.toggleStorage(keepSigned);
|
||||||
apiManager.toggleStorage(keepSigned);
|
apiManager.toggleStorage(keepSigned);
|
||||||
|
sessionStorage.toggleStorage(keepSigned);
|
||||||
});
|
});
|
||||||
|
|
||||||
appStateManager.getState().then(state => {
|
appStateManager.getState().then(state => {
|
||||||
|
Loading…
Reference in New Issue
Block a user