Browse Source

Fix Malaysia code

Fix shared media switching tab with scale
Refactor users & chats
Fix showing chatlist corner button with active search
master
Eduard Kuzmenko 3 years ago
parent
commit
92dea78bbd
  1. 5
      src/components/sidebarLeft/index.ts
  2. 2
      src/components/sidebarLeft/tabs/blockedUsers.ts
  3. 2
      src/components/sidebarLeft/tabs/settings.ts
  4. 4
      src/components/sidebarRight/tabs/sharedMedia.ts
  5. 10
      src/config/database.ts
  6. 2
      src/countries.ts
  7. 2
      src/helpers/object.ts
  8. 10
      src/helpers/schedulers.ts
  9. 72
      src/lib/appManagers/appChatsManager.ts
  10. 2
      src/lib/appManagers/appImManager.ts
  11. 9
      src/lib/appManagers/appMessagesManager.ts
  12. 17
      src/lib/appManagers/appProfileManager.ts
  13. 61
      src/lib/appManagers/appUsersManager.ts
  14. 125
      src/lib/idb.ts
  15. 32
      src/lib/storage.ts
  16. 2
      src/scripts/in/countries.dat
  17. 9
      src/scss/partials/_leftSidebar.scss
  18. 8
      src/scss/partials/_rightSidebar.scss

5
src/components/sidebarLeft/index.ts

@ -478,12 +478,13 @@ export class AppSidebarLeft extends SidebarSlider { @@ -478,12 +478,13 @@ export class AppSidebarLeft extends SidebarSlider {
this.searchGroups.people.container.append(peopleContainer);
let peopleScrollable = new ScrollableX(peopleContainer);
let first = true;
let hideNewBtnMenuTimeout: number;
//const transition = Transition.bind(null, searchContainer.parentElement, 150);
const transition = TransitionSlider(searchContainer.parentElement, 'zoom-fade', 150, (id) => {
if(hideNewBtnMenuTimeout) clearTimeout(hideNewBtnMenuTimeout);
if(id === 0) {
if(id === 0 && !first) {
searchSuper.selectTab(0, false);
this.inputSearch.onClearClick();
hideNewBtnMenuTimeout = window.setTimeout(() => {
@ -491,6 +492,8 @@ export class AppSidebarLeft extends SidebarSlider { @@ -491,6 +492,8 @@ export class AppSidebarLeft extends SidebarSlider {
this.newBtnMenu.classList.remove('is-hidden');
}, 150);
}
first = false;
});
transition(0);

2
src/components/sidebarLeft/tabs/blockedUsers.ts

@ -64,7 +64,7 @@ export default class AppBlockedUsersTab extends SliderSuperTab { @@ -64,7 +64,7 @@ export default class AppBlockedUsersTab extends SliderSuperTab {
if(user.pFlags.bot) {
dom.lastMessageSpan.append('@' + user.username);
} else {
if(user.rPhone) dom.lastMessageSpan.innerHTML = user.rPhone;
if(user.phone) dom.lastMessageSpan.innerHTML = appUsersManager.formatUserPhone(user.phone);
else dom.lastMessageSpan.append(user.username ? '@' + user.username : appUsersManager.getUserStatusString(peerId));
}

2
src/components/sidebarLeft/tabs/settings.ts

@ -153,6 +153,6 @@ export default class AppSettingsTab extends SliderSuperTab { @@ -153,6 +153,6 @@ export default class AppSettingsTab extends SliderSuperTab {
this.avatarElem.setAttribute('peer', '' + user.id);
this.nameDiv.append(new PeerTitle({peerId: user.id}).element);
this.phoneDiv.innerHTML = user.rPhone || '';
this.phoneDiv.innerHTML = user.phone ? appUsersManager.formatUserPhone(user.phone) : '';
}
}

4
src/components/sidebarRight/tabs/sharedMedia.ts

@ -670,7 +670,7 @@ class PeerProfile { @@ -670,7 +670,7 @@ class PeerProfile {
let user = appUsersManager.getUser(peerId);
if(user.phone && peerId !== rootScope.myId) {
setText(user.rPhone, this.phone);
setText(appUsersManager.formatUserPhone(user.phone), this.phone);
}
}/* else {
//membersLi.style.display = appPeersManager.isBroadcast(peerId) ? 'none' : '';
@ -824,7 +824,7 @@ export default class AppSharedMediaTab extends SliderSuperTab { @@ -824,7 +824,7 @@ export default class AppSharedMediaTab extends SliderSuperTab {
const rect = this.searchSuper.nav.getBoundingClientRect();
if(!rect.width) return;
const top = rect.top;
const top = rect.top - 1;
const isSharedMedia = top <= HEADER_HEIGHT;
animatedCloseIcon.classList.toggle('state-back', isSharedMedia);
this.searchSuper.container.classList.toggle('is-full-viewport', isSharedMedia);

10
src/config/database.ts

@ -11,11 +11,19 @@ export type DatabaseStoreName = 'session' | 'stickerSets' | 'users' | 'chats' | @@ -11,11 +11,19 @@ export type DatabaseStoreName = 'session' | 'stickerSets' | 'users' | 'chats' |
export type DatabaseStore = Omit<IDBStore, 'name'> & {name: DatabaseStoreName};
const Database = {
name: 'tweb' + (Modes.test ? '_test' : ''),
version: 5,
version: 7,
stores: [{
name: 'session'
}, {
name: 'stickerSets'
}, {
name: 'users'
}, {
name: 'chats'
}, {
name: 'dialogs'
}, {
name: 'messages'
}] as DatabaseStore[],
};

2
src/countries.ts

File diff suppressed because one or more lines are too long

2
src/helpers/object.ts

@ -72,7 +72,7 @@ export function safeReplaceObject(wasObject: any, newObject: any) { @@ -72,7 +72,7 @@ export function safeReplaceObject(wasObject: any, newObject: any) {
}
for(var key in wasObject) {
if(!newObject.hasOwnProperty(key) && key.charAt(0) !== '$') {
if(!newObject.hasOwnProperty(key)) {
delete wasObject[key];
}
}

10
src/helpers/schedulers.ts

@ -50,16 +50,16 @@ export function throttle<F extends AnyToVoidFunction>( @@ -50,16 +50,16 @@ export function throttle<F extends AnyToVoidFunction>(
isPending = true;
args = _args;
if (!interval) {
if (shouldRunFirst) {
if(!interval) {
if(shouldRunFirst) {
isPending = false;
// @ts-ignore
fn(...args);
}
interval = window.setInterval(() => {
interval = setInterval(() => {
if (!isPending) {
window.clearInterval(interval!);
clearInterval(interval!);
interval = null;
return;
}
@ -67,7 +67,7 @@ export function throttle<F extends AnyToVoidFunction>( @@ -67,7 +67,7 @@ export function throttle<F extends AnyToVoidFunction>(
isPending = false;
// @ts-ignore
fn(...args);
}, ms);
}, ms) as any;
}
};
}

72
src/lib/appManagers/appChatsManager.ts

@ -18,6 +18,7 @@ import apiManagerProxy from "../mtproto/mtprotoworker"; @@ -18,6 +18,7 @@ import apiManagerProxy from "../mtproto/mtprotoworker";
import apiManager from '../mtproto/mtprotoworker';
import { RichTextProcessor } from "../richtextprocessor";
import rootScope from "../rootScope";
//import AppStorage from "../storage";
import apiUpdatesManager from "./apiUpdatesManager";
import appMessagesManager from "./appMessagesManager";
import appPeersManager from "./appPeersManager";
@ -32,14 +33,18 @@ export type ChatRights = keyof ChatBannedRights['pFlags'] | keyof ChatAdminRight @@ -32,14 +33,18 @@ export type ChatRights = keyof ChatBannedRights['pFlags'] | keyof ChatAdminRight
export type UserTyping = Partial<{userId: number, action: SendMessageAction, timeout: number}>;
export class AppChatsManager {
public chats: {[id: number]: Chat.channel | Chat.chat | any} = {};
//public usernames: any = {};
//public channelAccess: any = {};
//public megagroups: {[id: number]: true} = {};
/* private storage = new AppStorage<Record<number, Chat>>({
storeName: 'chats'
}); */
private chats: {[id: number]: Chat.channel | Chat.chat | any} = {};
//private usernames: any = {};
//private channelAccess: any = {};
//private megagroups: {[id: number]: true} = {};
public megagroupOnlines: {[id: number]: {timestamp: number, onlines: number}} = {};
private megagroupOnlines: {[id: number]: {timestamp: number, onlines: number}} = {};
public typingsInPeer: {[peerId: number]: UserTyping[]} = {};
private typingsInPeer: {[peerId: number]: UserTyping[]} = {};
constructor() {
rootScope.addMultipleEventsListeners({
@ -57,9 +62,9 @@ export class AppChatsManager { @@ -57,9 +62,9 @@ export class AppChatsManager {
updateChatDefaultBannedRights: (update) => {
const chatId = -appPeersManager.getPeerId(update.peer);
const chat: Chat = this.getChat(chatId);
if(chat._ !== 'chatEmpty') {
(chat as Chat.chat).default_banned_rights = update.default_banned_rights;
const chat: Chat.chat = this.chats[chatId];
if(chat) {
chat.default_banned_rights = update.default_banned_rights;
rootScope.broadcast('chat_update', chatId);
}
},
@ -142,31 +147,40 @@ export class AppChatsManager { @@ -142,31 +147,40 @@ export class AppChatsManager {
}
};
public saveApiChats(apiChats: any[]) {
apiChats.forEach(chat => this.saveApiChat(chat));
public getPeerTypings(peerId: number) {
return this.typingsInPeer[peerId];
}
public saveApiChats(apiChats: any[], override?: boolean) {
apiChats.forEach(chat => this.saveApiChat(chat, override));
}
public saveApiChat(chat: any) {
public saveApiChat(chat: any, override?: boolean) {
/* if(chat._ !== 'chat' && chat._ !== 'channel') {
return;
} */
// * exclude from state
// defineNotNumerableProperties(chat, ['rTitle', 'initials']);
//chat.rTitle = chat.title || 'chat_title_deleted';
chat.rTitle = RichTextProcessor.wrapRichText(chat.title, {noLinks: true, noLinebreaks: true}) || 'chat_title_deleted';
const oldChat = this.chats[chat.id];
chat.initials = RichTextProcessor.getAbbreviation(chat.title);
/* if(oldChat && !override) {
return;
} */
if(chat.pFlags === undefined) {
chat.pFlags = {};
}
if(chat.pFlags.min) {
if(oldChat !== undefined) {
return;
}
if(chat.pFlags.min && oldChat !== undefined) {
return;
}
chat.initials = RichTextProcessor.getAbbreviation(chat.title);
//console.log('im the weatherman', chat.id);
if(chat._ === 'channel' &&
chat.participants_count === undefined &&
oldChat !== undefined &&
@ -204,6 +218,10 @@ export class AppChatsManager { @@ -204,6 +218,10 @@ export class AppChatsManager {
if(changedTitle) {
rootScope.broadcast('peer_title_edit', -chat.id);
}
/* this.storage.set({
[chat.id]: chat
}); */
}
public getChat(id: number) {
@ -335,10 +353,7 @@ export class AppChatsManager { @@ -335,10 +353,7 @@ export class AppChatsManager {
public isChannel(id: number) {
if(id < 0) id = -id;
const chat = this.chats[id];
if(chat && (chat._ === 'channel' || chat._ === 'channelForbidden')/* || this.channelAccess[id] */) {
return true;
}
return false;
return chat && (chat._ === 'channel' || chat._ === 'channelForbidden')/* || this.channelAccess[id] */;
}
public isMegagroup(id: number) {
@ -347,10 +362,7 @@ export class AppChatsManager { @@ -347,10 +362,7 @@ export class AppChatsManager {
} */
const chat = this.chats[id];
if(chat && chat._ === 'channel' && chat.pFlags.megagroup) {
return true;
}
return false;
return chat && chat._ === 'channel' && chat.pFlags.megagroup;
}
public isBroadcast(id: number) {
@ -430,7 +442,7 @@ export class AppChatsManager { @@ -430,7 +442,7 @@ export class AppChatsManager {
return i18n(key, [numberThousandSplitter(count)]);
}
public wrapForFull(id: number, fullChat: any) {
/* public wrapForFull(id: number, fullChat: any) {
const chatFull = copy(fullChat);
const chat = this.getChat(id);
@ -480,7 +492,7 @@ export class AppChatsManager { @@ -480,7 +492,7 @@ export class AppChatsManager {
}
return participants;
}
} */
public createChannel(title: string, about: string): Promise<number> {
return apiManager.invokeApi('channels.createChannel', {

2
src/lib/appManagers/appImManager.ts

@ -908,7 +908,7 @@ export class AppImManager { @@ -908,7 +908,7 @@ export class AppImManager {
public getPeerTyping(peerId: number, container?: HTMLElement) {
if(!appUsersManager.isBot(peerId)) {
const typings = appChatsManager.typingsInPeer[peerId];
const typings = appChatsManager.getPeerTypings(peerId);
if(!typings || !typings.length) {
return;
}

9
src/lib/appManagers/appMessagesManager.ts

@ -2331,7 +2331,8 @@ export class AppMessagesManager { @@ -2331,7 +2331,8 @@ export class AppMessagesManager {
public saveMessages(messages: any[], options: Partial<{
storage: MessagesStorage,
isScheduled: true,
isOutgoing: true
isOutgoing: true,
//isNew: boolean, // * new - from update
}> = {}) {
//let groups: Set<string>;
messages.forEach((message) => {
@ -2503,6 +2504,12 @@ export class AppMessagesManager { @@ -2503,6 +2504,12 @@ export class AppMessagesManager {
break;
case 'messageActionChatEditTitle':
/* if(options.isNew) {
const chat = appChatsManager.getChat(-peerId);
chat.title = message.action.title;
appChatsManager.saveApiChat(chat, true);
} */
if(isBroadcast) {
message.action._ = 'messageActionChannelEditTitle';
}

17
src/lib/appManagers/appProfileManager.ts

@ -154,21 +154,10 @@ export class AppProfileManager { @@ -154,21 +154,10 @@ export class AppProfileManager {
id: appUsersManager.getUserInput(id)
}).then((userFull) => {
const user = userFull.user as User;
/* if(override && isObject(override) && override.phone_number) {
user.phone = override.phone_number;
if(override.first_name || override.last_name) {
user.first_name = override.first_name;
user.last_name = override.last_name;
}
appUsersManager.saveApiUser(user);
} else { */
appUsersManager.saveApiUser(user, true);
//}
appUsersManager.saveApiUser(user, true);
if(userFull.profile_photo) {
userFull.profile_photo = appPhotosManager.savePhoto(userFull.profile_photo, {type: 'profilePhoto', peerId: id});
/* appPhotosManager.savePhoto(userFull.profile_photo, {user_id: id}); */
}
if(userFull.about !== undefined) {
@ -253,7 +242,7 @@ export class AppProfileManager { @@ -253,7 +242,7 @@ export class AppProfileManager {
return this.fullPromises[peerId] = apiManager.invokeApi('messages.getFullChat', {
chat_id: id
}).then((result) => {
appChatsManager.saveApiChats(result.chats);
appChatsManager.saveApiChats(result.chats, true);
appUsersManager.saveApiUsers(result.users);
const fullChat = result.full_chat as ChatFull.chatFull;
if(fullChat && fullChat.chat_photo && fullChat.chat_photo.id) {
@ -362,7 +351,7 @@ export class AppProfileManager { @@ -362,7 +351,7 @@ export class AppProfileManager {
return this.fullPromises[peerId] = apiManager.invokeApi('channels.getFullChannel', {
channel: appChatsManager.getChannelInput(id)
}).then((result) => {
appChatsManager.saveApiChats(result.chats);
appChatsManager.saveApiChats(result.chats, true);
appUsersManager.saveApiUsers(result.users);
const fullChannel = result.full_chat as ChatFull.channelFull;
if(fullChannel && fullChannel.chat_photo.id) {

61
src/lib/appManagers/appUsersManager.ts

@ -47,6 +47,8 @@ export class AppUsersManager { @@ -47,6 +47,8 @@ export class AppUsersManager {
private getTopPeersPromise: Promise<number[]>;
constructor() {
//this.users = this.storage.getCache();
setInterval(this.updateUsersStatuses, 60000);
rootScope.on('state_synchronized', this.updateUsersStatuses);
@ -67,7 +69,7 @@ export class AppUsersManager { @@ -67,7 +69,7 @@ export class AppUsersManager {
}
}
user.sortStatus = this.getUserStatusForSort(user.status);
//user.sortStatus = this.getUserStatusForSort(user.status);
rootScope.broadcast('user_update', userId);
} //////else console.warn('No user by id:', userId);
},
@ -99,7 +101,7 @@ export class AppUsersManager { @@ -99,7 +101,7 @@ export class AppUsersManager {
first_name: update.first_name,
last_name: update.last_name,
username: update.username
}));
}), true);
}
}
});
@ -271,42 +273,28 @@ export class AppUsersManager { @@ -271,42 +273,28 @@ export class AppUsersManager {
apiUsers.forEach((user) => this.saveApiUser(user));
}
public saveApiUser(_user: MTUser, noReplace?: boolean) {
if(_user._ === 'userEmpty') return;
public saveApiUser(user: MTUser, override?: boolean) {
if(user._ === 'userEmpty') return;
const userId = user.id;
const oldUser = this.users[userId];
const user = _user;
if(noReplace && isObject(this.users[user.id]) && this.users[user.id].first_name) {
if(oldUser && !override) {
return;
}
const userId = user.id;
if(user.pFlags === undefined) {
user.pFlags = {};
}
if(user.pFlags.min) {
if(this.users[userId] !== undefined) {
return;
}
if(user.pFlags.min && oldUser !== undefined) {
return;
}
// * exclude from state
// defineNotNumerableProperties(user, ['initials', 'num', 'rFirstName', 'rFullName', 'rPhone', 'sortName', 'sortStatus']);
if(user.phone) {
user.rPhone = '+' + formatPhoneNumber(user.phone).formatted;
}
const fullName = user.first_name + ' ' + (user.last_name || '');
if(user.first_name) {
user.rFirstName = RichTextProcessor.wrapRichText(user.first_name, {noLinks: true, noLinebreaks: true});
user.rFullName = user.last_name ? RichTextProcessor.wrapRichText(fullName, {noLinks: true, noLinebreaks: true}) : user.rFirstName;
} else {
user.rFirstName = RichTextProcessor.wrapRichText(user.last_name, {noLinks: true, noLinebreaks: true}) || user.rPhone || 'user_first_name_deleted';
user.rFullName = RichTextProcessor.wrapRichText(user.last_name, {noLinks: true, noLinebreaks: true}) || user.rPhone || 'user_name_deleted';
}
if(user.username) {
const searchUsername = searchIndexManager.cleanUsername(user.username);
this.usernames[searchUsername] = userId;
@ -318,22 +306,17 @@ export class AppUsersManager { @@ -318,22 +306,17 @@ export class AppUsersManager {
if(user.status) {
if((user.status as UserStatus.userStatusOnline).expires) {
(user.status as UserStatus.userStatusOnline).expires -= serverTimeManager.serverTimeOffset
(user.status as UserStatus.userStatusOnline).expires -= serverTimeManager.serverTimeOffset;
}
if((user.status as UserStatus.userStatusOffline).was_online) {
(user.status as UserStatus.userStatusOffline).was_online -= serverTimeManager.serverTimeOffset
(user.status as UserStatus.userStatusOffline).was_online -= serverTimeManager.serverTimeOffset;
}
}
if(user.pFlags.bot) {
user.sortStatus = -1;
} else {
user.sortStatus = this.getUserStatusForSort(user.status);
}
//user.sortStatus = user.pFlags.bot ? -1 : this.getUserStatusForSort(user.status);
let changedTitle = false;
const oldUser = this.users[userId];
if(oldUser === undefined) {
this.users[userId] = user;
} else {
@ -347,11 +330,21 @@ export class AppUsersManager { @@ -347,11 +330,21 @@ export class AppUsersManager {
rootScope.broadcast('user_update', userId);
}
//console.log('we never give this up');
/* this.storage.set({
[userId]: user
}); */
if(changedTitle) {
rootScope.broadcast('peer_title_edit', user.id);
}
}
public formatUserPhone(phone: string) {
return '+' + formatPhoneNumber(phone).formatted;
}
public getUserStatusForSort(status: User['status'] | number) {
if(typeof(status) === 'number') {
status = this.getUser(status).status;
@ -579,7 +572,7 @@ export class AppUsersManager { @@ -579,7 +572,7 @@ export class AppUsersManager {
expires: timestamp + onlineTimeFor
};
user.sortStatus = this.getUserStatusForSort(user.status);
//user.sortStatus = this.getUserStatusForSort(user.status);
rootScope.broadcast('user_update', id);
}
}
@ -781,7 +774,7 @@ export class AppUsersManager { @@ -781,7 +774,7 @@ export class AppUsersManager {
};
user.status = status;
user.sortStatus = this.getUserStatusForSort(user.status);
//user.sortStatus = this.getUserStatusForSort(user.status);
rootScope.broadcast('user_update', userId);
}
}

125
src/lib/idb.ts

@ -225,7 +225,7 @@ export default class IDBStorage { @@ -225,7 +225,7 @@ export default class IDBStorage {
});
}
public save(entryName: string, value: any) {
public save(entryName: string | string[], value: any | any[]) {
return this.openDatabase().then((db) => {
//this.log('save:', entryName, value);
@ -240,44 +240,52 @@ export default class IDBStorage { @@ -240,44 +240,52 @@ export default class IDBStorage {
}
};
try {
const transaction = db.transaction([this.storeName], 'readwrite');
transaction.onerror = (e) => {
handleError(transaction.error);
};
/* transaction.oncomplete = (e) => {
this.log('save: transaction complete:', entryName);
}; */
/* transaction.addEventListener('abort', (e) => {
//handleError();
this.log.error('IndexedDB: save transaction abort!', transaction.error);
}); */
const objectStore = transaction.objectStore(this.storeName);
var request = objectStore.put(value, entryName);
} catch(error) {
handleError(error);
return Promise.reject(error);
/* this.storageIsAvailable = false;
throw error; */
}
return new Promise<void>((resolve, reject) => {
const timeout = setTimeout(() => {
this.log.error('save: request not finished', entryName, request);
}, 10000);
request.onsuccess = (event) => {
resolve();
clearTimeout(timeout);
};
try {
const transaction = db.transaction([this.storeName], 'readwrite');
request.onerror = (error) => {
transaction.onerror = (e) => {
handleError(transaction.error);
reject(transaction.error);
clearTimeout(timeout);
};
transaction.oncomplete = (e) => {
//this.log('save: transaction complete:', entryName);
resolve();
clearTimeout(timeout);
};
const timeout = setTimeout(() => {
this.log.error('save: transaction not finished', entryName, transaction);
}, 10000);
/* transaction.addEventListener('abort', (e) => {
//handleError();
this.log.error('IndexedDB: save transaction abort!', transaction.error);
}); */
const objectStore = transaction.objectStore(this.storeName);
if(!Array.isArray(entryName)) {
entryName = [].concat(entryName);
value = [].concat(value);
}
for(let i = 0, length = entryName.length; i < length; ++i) {
const request = objectStore.put(value[i], entryName[i]);
request.onerror = (error) => {
reject(transaction.error);
clearTimeout(timeout);
};
}
} catch(error) {
handleError(error);
reject(error);
clearTimeout(timeout);
};
/* this.storageIsAvailable = false;
throw error; */
}
});
});
}
@ -401,6 +409,51 @@ export default class IDBStorage { @@ -401,6 +409,51 @@ export default class IDBStorage {
});
}
public getAll<T>(): Promise<T[]> {
return this.openDatabase().then((db) => {
//this.log('getAll pre:', fileName);
try {
const transaction = db.transaction([this.storeName], 'readonly');
/* transaction.onabort = (e) => {
this.log.error('getAll transaction onabort?', e);
}; */
const objectStore = transaction.objectStore(this.storeName);
var request = objectStore.getAll();
//this.log.log('IDB getAll:', fileName, request);
} catch(err) {
this.log.error('getAll error:', err, request, request.error);
}
return new Promise((resolve, reject) => {
const timeout = setTimeout(() => {
this.log.error('getAll request not finished!', request);
reject();
}, 3000);
request.onsuccess = function(event) {
const result = request.result;
if(result === undefined) {
reject('NO_ENTRY_FOUND');
} /* else if(typeof result === 'string' &&
result.substr(0, 5) === 'data:') {
resolve(dataUrlToBlob(result));
} */else {
resolve(result);
}
clearTimeout(timeout);
}
request.onerror = () => {
clearTimeout(timeout);
reject();
};
});
});
}
/* public getAllKeys(): Promise<Array<string>> {
console.time('getAllEntries');
return this.openDatabase().then((db) => {

32
src/lib/storage.ts

@ -10,6 +10,7 @@ @@ -10,6 +10,7 @@
*/
import { DatabaseStore, DatabaseStoreName } from "../config/database";
import { throttle } from "../helpers/schedulers";
import IDBStorage, { IDBOptions } from "./idb";
export default class AppStorage<Storage extends Record<string, any>/* Storage extends {[name: string]: any} *//* Storage extends Record<string, any> */> {
@ -19,11 +20,29 @@ export default class AppStorage<Storage extends Record<string, any>/* Storage ex @@ -19,11 +20,29 @@ export default class AppStorage<Storage extends Record<string, any>/* Storage ex
//private cache: Partial<{[key: string]: Storage[typeof key]}> = {};
private cache: Partial<Storage> = {};
private useStorage = true;
private updateKeys: Set<keyof Storage> = new Set();
private saveThrottled: () => void;
constructor(storageOptions: Omit<IDBOptions, 'storeName' | 'stores'> & {stores?: DatabaseStore[], storeName: DatabaseStoreName}) {
this.storage = new IDBStorage(storageOptions);
AppStorage.STORAGES.push(this);
this.saveThrottled = throttle(async() => {
const keys = Array.from(this.updateKeys.values()) as string[];
this.updateKeys.clear();
try {
//console.log('setItem: will set', key/* , value */);
//await this.cacheStorage.delete(key); // * try to prevent memory leak in Chrome leading to 'Unexpected internal error.'
//await this.storage.save(key, new Response(value, {headers: {'Content-Type': 'application/json'}}));
await this.storage.save(keys, keys.map(key => this.cache[key]));
//console.log('setItem: have set', key/* , value */);
} catch(e) {
//this.useCS = false;
console.error('[AS]: set error:', e, keys/* , value */);
}
}, 50, false);
}
public getCache() {
@ -83,16 +102,8 @@ export default class AppStorage<Storage extends Record<string, any>/* Storage ex @@ -83,16 +102,8 @@ export default class AppStorage<Storage extends Record<string, any>/* Storage ex
console.log('LocalStorage set: stringify time by own stringify:', performance.now() - perf); */
if(this.useStorage && !onlyLocal) {
try {
//console.log('setItem: will set', key/* , value */);
//await this.cacheStorage.delete(key); // * try to prevent memory leak in Chrome leading to 'Unexpected internal error.'
//await this.storage.save(key, new Response(value, {headers: {'Content-Type': 'application/json'}}));
await this.storage.save(key, value);
//console.log('setItem: have set', key/* , value */);
} catch(e) {
//this.useCS = false;
console.error('[AS]: set error:', e, key/* , value */);
}
this.updateKeys.add(key);
this.saveThrottled();
}
}
}
@ -126,6 +137,7 @@ export default class AppStorage<Storage extends Record<string, any>/* Storage ex @@ -126,6 +137,7 @@ export default class AppStorage<Storage extends Record<string, any>/* Storage ex
storage.useStorage = enabled;
if(!enabled) {
storage.updateKeys.clear();
return storage.clear();
} else {
return storage.set(storage.cache);

2
src/scripts/in/countries.dat

@ -135,7 +135,7 @@ @@ -135,7 +135,7 @@
389;MK;Macedonia;;0;๐Ÿ‡ฒ๐Ÿ‡ฐ
261;MG;Madagascar;261 XX XX XXX XX;12;๐Ÿ‡ฒ๐Ÿ‡ฌ
265;MW;Malawi;;0;๐Ÿ‡ฒ๐Ÿ‡ผ
60;MM;Malaysia;;0;๐Ÿ‡ฒ๐Ÿ‡ฒ
60;MY;Malaysia;;0;๐Ÿ‡ฒ๐Ÿ‡พ
960;MV;Maldives;;0;๐Ÿ‡ฒ๐Ÿ‡ป
223;ML;Mali;223 XXXX XXXX;11;๐Ÿ‡ฒ๐Ÿ‡ฑ
356;MT;Malta;356 XX XX XX XX;11;๐Ÿ‡ฒ๐Ÿ‡น

9
src/scss/partials/_leftSidebar.scss

@ -365,14 +365,17 @@ @@ -365,14 +365,17 @@
z-index: 1;
}
html:not(.no-touch) & {
/* html:not(.no-touch) & {
transform: translateZ(0);
} */
&:not(.is-hidden) {
transform: translateZ(0);
}
}
html.no-touch &:hover .btn-corner:not(.is-hidden) {
/* html.no-touch &:hover .btn-corner:not(.is-hidden) {
transform: translateZ(0);
}
} */
}
.connection-status {

8
src/scss/partials/_rightSidebar.scss

@ -150,17 +150,17 @@ @@ -150,17 +150,17 @@
}
&.can-add-members {
@include respond-to(handhelds) {
//@include respond-to(handhelds) {
.btn-corner:not(.is-hidden) {
transform: translateZ(0);
}
}
//}
@include hover() {
/* @include hover() {
.btn-corner:not(.is-hidden) {
transform: translateZ(0);
}
}
} */
}
.search-super {

Loadingโ€ฆ
Cancel
Save