Browse Source

Improve smoothness of opening chat on handhelds

Fix schedule send & delete
Fix min schedule date
master
Eduard Kuzmenko 4 years ago
parent
commit
cbd9c28d3e
  1. 3
      src/components/chat/bubbles.ts
  2. 2
      src/components/chat/chat.ts
  3. 3
      src/components/chat/contextMenu.ts
  4. 2
      src/components/chat/search.ts
  5. 32
      src/components/chat/topbar.ts
  6. 3
      src/components/misc.ts
  7. 4
      src/components/popups/datePicker.ts
  8. 4
      src/components/popups/schedule.ts
  9. 4
      src/components/scrollable.ts
  10. 2
      src/components/wrappers.ts
  11. 8
      src/helpers/dom.ts
  12. 7
      src/helpers/eventListenerBase.ts
  13. 2
      src/lib/appManagers/apiUpdatesManager.ts
  14. 41
      src/lib/appManagers/appImManager.ts
  15. 95
      src/lib/appManagers/appMessagesManager.ts
  16. 87
      src/lib/appManagers/appStateManager.ts
  17. 2
      src/lib/appManagers/appUsersManager.ts
  18. 2
      src/lib/logger.ts
  19. 6
      src/lib/mediaPlayer.ts
  20. 32
      src/lib/storage.ts
  21. 13
      src/scss/partials/_chat.scss
  22. 5
      src/scss/partials/_leftSidebar.scss
  23. 6
      src/scss/partials/_rightSidebar.scss
  24. 6
      src/scss/partials/pages/_chats.scss
  25. 2
      src/scss/partials/popups/_datePicker.scss
  26. 1
      src/types.d.ts

3
src/components/chat/bubbles.ts

@ -2408,7 +2408,8 @@ export default class ChatBubbles { @@ -2408,7 +2408,8 @@ export default class ChatBubbles {
//console.time('appImManager call getHistory');
const pageCount = this.appPhotosManager.windowH / 38/* * 1.25 */ | 0;
//const loadCount = Object.keys(this.bubbles).length > 0 ? 50 : pageCount;
const realLoadCount = Object.keys(this.bubbles).length > 0 || additionMsgId ? Math.max(40, pageCount) : pageCount;//const realLoadCount = 50;
//const realLoadCount = Object.keys(this.bubbles).length > 0 || additionMsgId ? Math.max(40, pageCount) : pageCount;//const realLoadCount = 50;
const realLoadCount = pageCount;//const realLoadCount = 50;
let loadCount = realLoadCount;
/* if(TEST_SCROLL) {

2
src/components/chat/chat.ts

@ -191,7 +191,7 @@ export default class Chat extends EventListenerBase<{ @@ -191,7 +191,7 @@ export default class Chat extends EventListenerBase<{
appSidebarRight.sharedMediaTab.loadSidebarMedia(false);
}); */
return this.setPeerPromise;
return result;
}
public finishPeerChange(isTarget: boolean, isJump: boolean, lastMsgId: number) {

3
src/components/chat/contextMenu.ts

@ -113,7 +113,8 @@ export default class ChatContextMenu { @@ -113,7 +113,8 @@ export default class ChatContextMenu {
const good = ['bubble', 'bubble__container', 'message', 'time', 'inner'].find(c => className.match(new RegExp(c + '($|\\s)')));
if(good) {
cancelEvent(e);
onContextMenu((e as TouchEvent).changedTouches[0]);
//onContextMenu((e as TouchEvent).changedTouches[0]);
onContextMenu((e as TouchEvent).changedTouches ? (e as TouchEvent).changedTouches[0] : e as MouseEvent);
}
}, {listenerSetter: this.chat.bubbles.listenerSetter});

2
src/components/chat/search.ts

@ -149,7 +149,7 @@ export default class ChatSearch { @@ -149,7 +149,7 @@ export default class ChatSearch {
this.chat.bubbles.bubblesContainer.classList.remove('search-results-active');
const res = this.chat.setPeer(peerId, lastMsgId);
this.setPeerPromise = (res instanceof Promise ? res : Promise.resolve(res)).then(() => {
this.setPeerPromise = ((res instanceof Promise ? res : Promise.resolve(res)) as Promise<any>).then(() => {
this.selectedIndex = index;
this.foundCountEl.innerText = `${index + 1} of ${this.foundCount}`;

32
src/components/chat/topbar.ts

@ -271,22 +271,24 @@ export default class ChatTopbar { @@ -271,22 +271,24 @@ export default class ChatTopbar {
}
});
this.chat.addListener('setPeer', (mid, isTopMessage) => {
const middleware = this.chat.bubbles.getMiddleware();
appStateManager.getState().then((state) => {
if(!middleware()) return;
this.pinnedMessage.hidden = !!state.hiddenPinnedMessages[this.chat.peerId];
if(isTopMessage) {
this.pinnedMessage.unsetScrollDownListener();
this.pinnedMessage.testMid(mid, 0); // * because slider will not let get bubble by document.elementFromPoint
} else if(!this.pinnedMessage.locked) {
this.pinnedMessage.handleFollowingPinnedMessage();
this.pinnedMessage.testMid(mid);
}
if(this.pinnedMessage) {
this.chat.addListener('setPeer', (mid, isTopMessage) => {
const middleware = this.chat.bubbles.getMiddleware();
appStateManager.getState().then((state) => {
if(!middleware()) return;
this.pinnedMessage.hidden = !!state.hiddenPinnedMessages[this.chat.peerId];
if(isTopMessage) {
this.pinnedMessage.unsetScrollDownListener();
this.pinnedMessage.testMid(mid, 0); // * because slider will not let get bubble by document.elementFromPoint
} else if(!this.pinnedMessage.locked) {
this.pinnedMessage.handleFollowingPinnedMessage();
this.pinnedMessage.testMid(mid);
}
});
});
});
}
this.setPeerStatusInterval = window.setInterval(this.setPeerStatus, 60e3);

3
src/components/misc.ts

@ -2,9 +2,8 @@ import Countries, { Country, PhoneCodesMain } from "../countries"; @@ -2,9 +2,8 @@ import Countries, { Country, PhoneCodesMain } from "../countries";
import { cancelEvent, CLICK_EVENT_NAME } from "../helpers/dom";
import ListenerSetter from "../helpers/listenerSetter";
import mediaSizes from "../helpers/mediaSizes";
import { clamp } from "../helpers/number";
import { isTouchSupported } from "../helpers/touchSupport";
import { isApple, isSafari } from "../helpers/userAgent";
import { isApple } from "../helpers/userAgent";
export const loadedURLs: {[url: string]: boolean} = {};
const set = (elem: HTMLElement | HTMLImageElement | SVGImageElement | HTMLVideoElement, url: string) => {

4
src/components/popups/datePicker.ts

@ -45,6 +45,10 @@ export default class PopupDatePicker extends PopupElement { @@ -45,6 +45,10 @@ export default class PopupDatePicker extends PopupElement {
this.minDate = options.minDate || new Date('2013-08-01T00:00:00');
if(initDate < this.minDate) {
initDate.setFullYear(this.minDate.getFullYear(), this.minDate.getMonth(), this.minDate.getDate());
}
// Controls
this.controlsDiv = document.createElement('div');
this.controlsDiv.classList.add('date-picker-controls');

4
src/components/popups/schedule.ts

@ -2,8 +2,8 @@ import PopupDatePicker from "./datePicker"; @@ -2,8 +2,8 @@ import PopupDatePicker from "./datePicker";
const getMinDate = () => {
const date = new Date();
date.setDate(date.getDate() - 1);
//date.setHours(0, 0, 0, 0);
//date.setDate(date.getDate() - 1);
date.setHours(0, 0, 0, 0);
return date;
};

4
src/components/scrollable.ts

@ -154,7 +154,9 @@ export default class Scrollable extends ScrollableBase { @@ -154,7 +154,9 @@ export default class Scrollable extends ScrollableBase {
//return;
if(this.onScrollMeasure || ((this.scrollLocked || (!this.onScrolledTop && !this.onScrolledBottom)) && !this.splitUp && !this.onAdditionalScroll)) return;
//if(this.onScrollMeasure || ((this.scrollLocked || (!this.onScrolledTop && !this.onScrolledBottom)) && !this.splitUp && !this.onAdditionalScroll)) return;
if((this.scrollLocked || (!this.onScrolledTop && !this.onScrolledBottom)) && !this.splitUp && !this.onAdditionalScroll) return;
if(this.onScrollMeasure) window.cancelAnimationFrame(this.onScrollMeasure);
this.onScrollMeasure = window.requestAnimationFrame(() => {
this.onScrollMeasure = 0;

2
src/components/wrappers.ts

@ -559,7 +559,7 @@ export function wrapPhoto({photo, message, container, boxWidth, boxHeight, withT @@ -559,7 +559,7 @@ export function wrapPhoto({photo, message, container, boxWidth, boxHeight, withT
if(message?.media?.preloader) { // means upload
message.media.preloader.attach(container);
} else if(!cacheContext.downloaded) {
preloader = new ProgressivePreloader(container, false, false, photo._ == 'document' ? 'prepend' : 'append');
preloader = new ProgressivePreloader(null, false, false, photo._ == 'document' ? 'prepend' : 'append');
}
const load = () => {

8
src/helpers/dom.ts

@ -466,13 +466,14 @@ export function blurActiveElement() { @@ -466,13 +466,14 @@ export function blurActiveElement() {
}
}
export const CLICK_EVENT_NAME = isTouchSupported ? 'touchend' : 'click';
export const CLICK_EVENT_NAME: 'mousedown' | 'touchend' | 'click' = (isTouchSupported ? 'mousedown' : 'click') as any;
export type AttachClickOptions = AddEventListenerOptions & Partial<{listenerSetter: ListenerSetter, touchMouseDown: true}>;
export const attachClickEvent = (elem: HTMLElement, callback: (e: TouchEvent | MouseEvent) => void, options: AttachClickOptions = {}) => {
const add = options.listenerSetter ? options.listenerSetter.add.bind(options.listenerSetter, elem) : elem.addEventListener.bind(elem);
const remove = options.listenerSetter ? options.listenerSetter.removeManual.bind(options.listenerSetter, elem) : elem.removeEventListener.bind(elem);
if(options.touchMouseDown && CLICK_EVENT_NAME === 'touchend') {
options.touchMouseDown = true;
/* if(options.touchMouseDown && CLICK_EVENT_NAME === 'touchend') {
add('mousedown', callback, options);
} else if(CLICK_EVENT_NAME === 'touchend') {
const o = {...options, once: true};
@ -498,7 +499,8 @@ export const attachClickEvent = (elem: HTMLElement, callback: (e: TouchEvent | M @@ -498,7 +499,8 @@ export const attachClickEvent = (elem: HTMLElement, callback: (e: TouchEvent | M
add('touchstart', onTouchStart);
} else {
add(CLICK_EVENT_NAME, callback, options);
}
} */
add(CLICK_EVENT_NAME, callback, options);
};
export const detachClickEvent = (elem: HTMLElement, callback: (e: TouchEvent | MouseEvent) => void, options?: AddEventListenerOptions) => {

7
src/helpers/eventListenerBase.ts

@ -1,4 +1,4 @@ @@ -1,4 +1,4 @@
import type { ArgumentTypes } from "../types";
import type { ArgumentTypes, SuperReturnType } from "../types";
export default class EventListenerBase<Listeners extends {[name: string]: Function}> {
protected listeners: Partial<{
@ -36,14 +36,17 @@ export default class EventListenerBase<Listeners extends {[name: string]: Functi @@ -36,14 +36,17 @@ export default class EventListenerBase<Listeners extends {[name: string]: Functi
this.listenerResults[name] = args;
}
const arr: Array<SuperReturnType<Listeners[typeof name]>> = [];
if(this.listeners[name]) {
this.listeners[name].forEach(listener => {
listener.callback(...args);
arr.push(listener.callback(...args));
if(listener.once) {
this.removeListener(name, listener.callback);
}
});
}
return arr;
}
}

2
src/lib/appManagers/apiUpdatesManager.ts

@ -40,7 +40,7 @@ export class ApiUpdatesManager { @@ -40,7 +40,7 @@ export class ApiUpdatesManager {
constructor() {
// * false for test purposes
/* false && */appStateManager.addListener('save', () => {
/* false && */appStateManager.addListener('save', async() => {
const us = this.updatesState;
appStateManager.pushToState('updates', {
seq: us.seq,

41
src/lib/appManagers/appImManager.ts

@ -51,8 +51,8 @@ export class AppImManager { @@ -51,8 +51,8 @@ export class AppImManager {
public setPeerPromise: Promise<void> = null;
private mainColumns: HTMLElement;
public _selectTab: ReturnType<typeof horizontalMenu>;
//private mainColumns: HTMLElement;
//public _selectTab: ReturnType<typeof horizontalMenu>;
public tabId = -1;
//private closeBtn: HTMLButtonElement;// = this.topbar.querySelector('.sidebar-close-button') as HTMLButtonElement;
public hideRightSidebar = false;
@ -74,8 +74,8 @@ export class AppImManager { @@ -74,8 +74,8 @@ export class AppImManager {
this.log = logger('IM', LogLevels.log | LogLevels.warn | LogLevels.debug | LogLevels.error);
this.mainColumns = this.columnEl.parentElement;
this._selectTab = horizontalMenu(null, this.mainColumns);
//this.mainColumns = this.columnEl.parentElement;
//this._selectTab = horizontalMenu(null, this.mainColumns);
this.selectTab(0);
window.addEventListener('blur', () => {
@ -420,7 +420,7 @@ export class AppImManager { @@ -420,7 +420,7 @@ export class AppImManager {
document.body.classList.remove(RIGHT_COLUMN_ACTIVE_CLASSNAME);
}
this._selectTab(id, mediaSizes.isMobile);
//this._selectTab(id, mediaSizes.isMobile);
//document.body.classList.toggle(RIGHT_COLUMN_ACTIVE_CLASSNAME, id == 2);
}
@ -498,24 +498,29 @@ export class AppImManager { @@ -498,24 +498,29 @@ export class AppImManager {
return this.setPeer(peerId, lastMsgId);
}
if(peerId || mediaSizes.activeScreen != ScreenSize.mobile) {
chat.setPeer(peerId, lastMsgId);
if(peerId || mediaSizes.activeScreen !== ScreenSize.mobile) {
const result = chat.setPeer(peerId, lastMsgId);
const promise = result?.cached ? result.promise : Promise.resolve();
if(peerId) {
promise.then(() => {
//window.requestAnimationFrame(() => {
setTimeout(() => { // * setTimeout is better here
if(this.hideRightSidebar) {
appSidebarRight.toggleSidebar(true);
this.hideRightSidebar = false;
}
this.selectTab(1);
}, 0);
});
}
}
if(peerId == 0) {
if(!peerId) {
this.selectTab(0);
document.body.classList.add(LEFT_COLUMN_ACTIVE_CLASSNAME);
return false;
}
document.body.classList.remove(LEFT_COLUMN_ACTIVE_CLASSNAME);
if(this.hideRightSidebar) {
appSidebarRight.toggleSidebar(true);
this.hideRightSidebar = false;
}
this.selectTab(1);
}
public setInnerPeer(peerId: number, lastMsgId?: number, type: ChatType = 'chat') {

95
src/lib/appManagers/appMessagesManager.ts

@ -227,51 +227,77 @@ export class AppMessagesManager { @@ -227,51 +227,77 @@ export class AppMessagesManager {
}
}); */
function timedChunk(items: any[], process: (...args: any[]) => any, context: any, callback: (...args: any[]) => void) {
const todo = items.slice();
const f = () => {
const start = +new Date();
do {
process.call(context, todo.shift());
} while(todo.length > 0 && (+new Date() - start < 50));
if(todo.length > 0) {
setTimeout(f, 25);
} else {
callback(items);
}
};
setTimeout(f, 25);
}
appStateManager.addListener('save', () => {
const messages: any[] = [];
const dialogs: Dialog[] = [];
for(const folderId in this.dialogsStorage.byFolders) {
const folder = this.dialogsStorage.getFolder(+folderId);
for(let dialog of folder) {
const historyStorage = this.getHistoryStorage(dialog.peerId);
const history = [].concat(historyStorage.pending, historyStorage.history);
dialog = copy(dialog);
let removeUnread = 0;
for(const mid of history) {
const message = this.getMessageByPeer(dialog.peerId, mid);
if(/* message._ != 'messageEmpty' && */!message.pFlags.is_outgoing) {
messages.push(message);
const items: any[] = [];
if(message.fromId != dialog.peerId) {
appStateManager.setPeer(message.fromId, appPeersManager.getPeer(message.fromId));
}
const processDialog = (dialog: MTDialog.dialog) => {
const historyStorage = this.getHistoryStorage(dialog.peerId);
const history = [].concat(historyStorage.pending, historyStorage.history);
dialog = copy(dialog);
let removeUnread = 0;
for(const mid of history) {
const message = this.getMessageByPeer(dialog.peerId, mid);
if(/* message._ != 'messageEmpty' && */!message.pFlags.is_outgoing) {
messages.push(message);
if(message.fromId != dialog.peerId) {
appStateManager.setPeer(message.fromId, appPeersManager.getPeer(message.fromId));
}
dialog.top_message = message.mid;
this.setDialogIndexByMessage(dialog, message);
dialog.top_message = message.mid;
this.setDialogIndexByMessage(dialog, message);
break;
} else if(message.pFlags && message.pFlags.unread) {
++removeUnread;
}
break;
} else if(message.pFlags && message.pFlags.unread) {
++removeUnread;
}
}
if(removeUnread && dialog.unread_count) dialog.unread_count -= removeUnread;
if(removeUnread && dialog.unread_count) dialog.unread_count -= removeUnread;
dialog.unread_count = Math.max(0, dialog.unread_count);
dialogs.push(dialog);
dialog.unread_count = Math.max(0, dialog.unread_count);
dialogs.push(dialog);
appStateManager.setPeer(dialog.peerId, appPeersManager.getPeer(dialog.peerId));
appStateManager.setPeer(dialog.peerId, appPeersManager.getPeer(dialog.peerId));
};
for(const folderId in this.dialogsStorage.byFolders) {
const folder = this.dialogsStorage.getFolder(+folderId);
for(let dialog of folder) {
items.push(dialog);
}
}
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);
return new Promise((resolve => timedChunk(items, processDialog, this, resolve))).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);
});
});
appStateManager.getState().then(state => {
@ -3187,6 +3213,7 @@ export class AppMessagesManager { @@ -3187,6 +3213,7 @@ export class AppMessagesManager {
}
public readMessages(peerId: number, msgIds: number[]) {
msgIds = msgIds.map(mid => this.getLocalMessageId(mid));
if(peerId < 0 && appPeersManager.isChannel(peerId)) {
const channelId = -peerId;
apiManager.invokeApi('channels.readMessageContents', {
@ -4113,7 +4140,7 @@ export class AppMessagesManager { @@ -4113,7 +4140,7 @@ export class AppMessagesManager {
public sendScheduledMessages(peerId: number, mids: number[]) {
return apiManager.invokeApi('messages.sendScheduledMessages', {
peer: appPeersManager.getInputPeerById(peerId),
id: mids
id: mids.map(mid => this.getLocalMessageId(mid))
}).then(updates => {
apiUpdatesManager.processUpdateMessage(updates);
});
@ -4122,7 +4149,7 @@ export class AppMessagesManager { @@ -4122,7 +4149,7 @@ export class AppMessagesManager {
public deleteScheduledMessages(peerId: number, mids: number[]) {
return apiManager.invokeApi('messages.deleteScheduledMessages', {
peer: appPeersManager.getInputPeerById(peerId),
id: mids
id: mids.map(mid => this.getLocalMessageId(mid))
}).then(updates => {
apiUpdatesManager.processUpdateMessage(updates);
});

87
src/lib/appManagers/appStateManager.ts

@ -16,13 +16,16 @@ const STATE_VERSION = App.version; @@ -16,13 +16,16 @@ const STATE_VERSION = App.version;
type State = Partial<{
dialogs: Dialog[],
allDialogsLoaded: DialogsStorage['allDialogsLoaded'],
//peers: {[peerId: string]: ReturnType<AppPeersManager['getPeer']>},
allDialogsLoaded: DialogsStorage['allDialogsLoaded'],
chats: {[peerId: string]: ReturnType<AppChatsManager['getChat']>},
users: {[peerId: string]: ReturnType<AppUsersManager['getUser']>},
messages: any[],
contactsList: number[],
updates: any,
updates: Partial<{
seq: number,
pts: number,
date: number
}>,
filters: FiltersStorage['filters'],
maxSeenMsgId: number,
stateCreatedTime: number,
@ -35,16 +38,45 @@ type State = Partial<{ @@ -35,16 +38,45 @@ type State = Partial<{
hiddenPinnedMessages: {[peerId: string]: number}
}>;
/* const STATE_INIT: State = {
dialogs: [],
allDialogsLoaded: {},
chats: {},
users: {},
messages: [],
contactsList: [],
updates: {},
filters: {},
maxSeenMsgId: 0,
stateCreatedTime: 0,
recentEmoji: [],
topPeers: [],
recentSearch: [],
stickerSets: {},
version: '',
authState:
}; */
const ALL_KEYS = ['dialogs', 'allDialogsLoaded', 'chats',
'users', 'messages', 'contactsList',
'updates', 'filters', 'maxSeenMsgId',
'stateCreatedTime', 'recentEmoji', 'topPeers',
'recentSearch', 'stickerSets', 'version',
'authState', 'hiddenPinnedMessages'
] as any as Array<keyof State>;
const REFRESH_KEYS = ['dialogs', 'allDialogsLoaded', 'messages', 'contactsList', 'stateCreatedTime',
'updates', 'maxSeenMsgId', 'filters', 'topPeers'] as any as Array<keyof State>;
export class AppStateManager extends EventListenerBase<{
save: (state: State) => void
save: (state: State) => Promise<void>
}> {
public loaded: Promise<State>;
private log = logger('STATE'/* , LogLevels.error */);
private state: State;
private savePromise: Promise<void>;
private tempId = 0;
constructor() {
super();
@ -55,7 +87,18 @@ export class AppStateManager extends EventListenerBase<{ @@ -55,7 +87,18 @@ export class AppStateManager extends EventListenerBase<{
if(this.loaded) return this.loaded;
//console.time('load state');
return this.loaded = new Promise((resolve) => {
AppStorage.get<[State, UserAuth]>('state', 'user_auth').then(([state, auth]) => {
AppStorage.get<any>(...ALL_KEYS, 'user_auth').then((arr) => {
let state: State = {};
// ! then can't store false values
ALL_KEYS.forEach((key, idx) => {
const value = arr[idx];
if(value !== false) {
// @ts-ignore
state[key] = value;
}
});
const time = Date.now();
if(state) {
if(state.version != STATE_VERSION) {
@ -84,6 +127,7 @@ export class AppStateManager extends EventListenerBase<{ @@ -84,6 +127,7 @@ export class AppStateManager extends EventListenerBase<{
//return resolve();
const auth: UserAuth = arr[arr.length - 1];
if(auth) {
// ! Warning ! DON'T delete this
this.state.authState = {_: 'authStateSignedIn'};
@ -95,7 +139,10 @@ export class AppStateManager extends EventListenerBase<{ @@ -95,7 +139,10 @@ export class AppStateManager extends EventListenerBase<{
//console.timeEnd('load state');
resolve(this.state);
}).catch(resolve).finally(() => {
setInterval(() => this.saveState(), 10000);
setInterval(() => {
this.tempId++;
this.saveState();
}, 10000);
});
});
}
@ -105,18 +152,26 @@ export class AppStateManager extends EventListenerBase<{ @@ -105,18 +152,26 @@ export class AppStateManager extends EventListenerBase<{
}
public saveState() {
if(this.state === undefined) return;
if(this.state === undefined || this.savePromise) return;
const tempId = this.tempId;
this.savePromise = Promise.all(this.setListenerResult('save', this.state)).then(() => {
return AppStorage.set(this.state);
}).then(() => {
this.savePromise = null;
if(this.tempId !== tempId) {
this.saveState();
}
});
//let perf = performance.now();
this.setListenerResult('save', this.state);
//this.log('saveState: event time:', performance.now() - perf);
//const pinnedOrders = appMessagesManager.dialogsStorage.pinnedOrders;
//perf = performance.now();
AppStorage.set({
state: this.state
});
//this.log('saveState: storage set time:', performance.now() - perf);
}
@ -129,6 +184,16 @@ export class AppStateManager extends EventListenerBase<{ @@ -129,6 +184,16 @@ export class AppStateManager extends EventListenerBase<{
if(container.hasOwnProperty(peerId)) return;
container[peerId] = peer;
}
public resetState() {
for(let i in this.state) {
// @ts-ignore
this.state[i] = false;
}
AppStorage.set(this.state).then(() => {
location.reload();
});
}
}
//console.trace('appStateManager include');

2
src/lib/appManagers/appUsersManager.ts

@ -100,7 +100,7 @@ export class AppUsersManager { @@ -100,7 +100,7 @@ export class AppUsersManager {
}
});
appStateManager.addListener('save', () => {
appStateManager.addListener('save', async() => {
const contactsList = [...this.contactsList];
for(const userId of contactsList) {
appStateManager.setPeer(userId, this.getUser(userId));

2
src/lib/logger.ts

@ -13,7 +13,7 @@ function dT() { @@ -13,7 +13,7 @@ function dT() {
}
export function logger(prefix: string, level = LogLevels.log | LogLevels.warn | LogLevels.error) {
if(process.env.NODE_ENV != 'development'/* || true */) {
if(process.env.NODE_ENV != 'development' || true) {
level = LogLevels.error;
}

6
src/lib/mediaPlayer.ts

@ -70,9 +70,9 @@ export class ProgressLine { @@ -70,9 +70,9 @@ export class ProgressLine {
this.container.addEventListener('mouseup', this.onMouseUp);
if(isTouchSupported) {
this.container.addEventListener('touchmove', this.onMouseMove);
this.container.addEventListener('touchstart', this.onMouseDown);
this.container.addEventListener('touchend', this.onMouseUp);
this.container.addEventListener('touchmove', this.onMouseMove, {passive: true});
this.container.addEventListener('touchstart', this.onMouseDown, {passive: true});
this.container.addEventListener('touchend', this.onMouseUp, {passive: true});
}
}

32
src/lib/storage.ts

@ -3,9 +3,6 @@ import { MOUNT_CLASS_TO } from './mtproto/mtproto_config'; @@ -3,9 +3,6 @@ import { MOUNT_CLASS_TO } from './mtproto/mtproto_config';
//import { stringify } from '../helpers/json';
class AppStorage {
//private log = (...args: any[]) => console.log('[SW LS]', ...args);
private log = (...args: any[]) => {};
private cacheStorage = new CacheStorageController('session');
//public noPrefix = false;
@ -66,24 +63,23 @@ class AppStorage { @@ -66,24 +63,23 @@ class AppStorage {
}
public async set(obj: any) {
let keyValues: any = {};
let prefix = this.storageGetPrefix(),
key, value;
const prefix = this.storageGetPrefix();
//console.log('storageSetValue', obj, callback, arguments);
for(key in obj) {
for(let key in obj) {
if(obj.hasOwnProperty(key)) {
value = obj[key];
let value = obj[key];
key = prefix + key;
this.cache[key] = value;
let perf = performance.now();
value = JSON.stringify(value);
/* let perf = performance.now();
let value2 = JSON.stringify(value);
console.log('LocalStorage set: stringify time by JSON.stringify:', performance.now() - perf, value2);
perf = performance.now();
let elapsedTime = performance.now() - perf;
if(elapsedTime > 10) {
console.warn('LocalStorage set: stringify time by JSON.stringify:', elapsedTime, key);
}
/* perf = performance.now();
value = stringify(value);
console.log('LocalStorage set: stringify time by own stringify:', performance.now() - perf); */
@ -97,8 +93,6 @@ class AppStorage { @@ -97,8 +93,6 @@ class AppStorage {
//this.useCS = false;
console.error('[AS]: set error:', e, key/* , value */);
}
} else {
keyValues[key] = value;
}
}
}
@ -109,11 +103,9 @@ class AppStorage { @@ -109,11 +103,9 @@ class AppStorage {
keys = Array.prototype.slice.call(arguments);
}
let prefix = this.storageGetPrefix(),
i, key;
for(i = 0; i < keys.length; i++) {
key = keys[i] = prefix + keys[i];
const prefix = this.storageGetPrefix();
for(let i = 0; i < keys.length; i++) {
const key = keys[i] = prefix + keys[i];
delete this.cache[key];
if(this.useCS) {
try {

13
src/scss/partials/_chat.scss

@ -22,6 +22,8 @@ $chat-helper-size: 39px; @@ -22,6 +22,8 @@ $chat-helper-size: 39px;
transition: transform var(--layer-transition);
transform: translateY(var(--translateY));
//display: none !important;
/* // * for no ESG top
flex: 1 1 auto;
height: calc(100% - 56px); */
@ -407,6 +409,17 @@ $chat-helper-size: 39px; @@ -407,6 +409,17 @@ $chat-helper-size: 39px;
position: relative;
flex: 3;
@include respond-to(handhelds) {
body.is-left-column-shown & {
transform: translate3d(100vw, 0, 0);
}
body.is-right-column-shown & {
transform: translate3d(-25vw, 0, 0);
filter: brightness(80%);
}
}
@include respond-to(floating-left-sidebar) {
position: fixed !important;
left: 0;

5
src/scss/partials/_leftSidebar.scss

@ -9,6 +9,11 @@ @@ -9,6 +9,11 @@
@include respond-to(handhelds) {
width: 100%;
max-width: 100%;
body:not(.is-left-column-shown) & {
transform: translate3d(-25vw, 0, 0);
filter: brightness(80%);
}
}
@include respond-to(floating-left-sidebar) {

6
src/scss/partials/_rightSidebar.scss

@ -5,6 +5,12 @@ @@ -5,6 +5,12 @@
box-shadow: 0 0.25rem 0.5rem 0.1rem hsla(0, 0%, 44.7%, .25);
}
@include respond-to(handhelds) {
body:not(.is-right-column-shown) & {
transform: translate3d(100vw, 0, 0);
}
}
@include respond-to(not-handhelds) {
width: var(--right-column-width);
transition: transform var(--layer-transition);

6
src/scss/partials/pages/_chats.scss

@ -24,10 +24,12 @@ @@ -24,10 +24,12 @@
@include respond-to(handhelds) {
.main-column {
width: 100%;
display: flex !important;
z-index: 1;
&:not(.active) {
/* &:not(.active) {
display: none;
}
} */
}
/* #column-left {

2
src/scss/partials/popups/_datePicker.scss

@ -177,7 +177,7 @@ @@ -177,7 +177,7 @@
&:disabled {
visibility: visible;
opacity: 1;
//opacity: 1;
}
}
}

1
src/types.d.ts vendored

@ -34,6 +34,7 @@ export type Modify<T, R> = Omit<T, keyof R> & R; @@ -34,6 +34,7 @@ export type Modify<T, R> = Omit<T, keyof R> & R;
//export type Parameters<T> = T extends (... args: infer T) => any ? T : never;
export type ArgumentTypes<F extends Function> = F extends (...args: infer A) => any ? A : never;
export type SuperReturnType<F extends Function> = F extends (...args: any) => any ? ReturnType<F> : never;
export type AnyLiteral = Record<string, any>;
export type AnyClass = new (...args: any[]) => any;

Loading…
Cancel
Save