Browse Source

Default folder

master
Eduard Kuzmenko 2 years ago
parent
commit
44bef6bdee
  1. 12
      src/components/sidebarLeft/tabs/archivedTab.ts
  2. 4
      src/components/sidebarLeft/tabs/chatFolders.ts
  3. 5
      src/config/state.ts
  4. 11
      src/layer.d.ts
  5. 89
      src/lib/appManagers/appDialogsManager.ts
  6. 8
      src/lib/appManagers/appMessagesManager.ts
  7. 2
      src/lib/appManagers/utils/dialogs/getDialogIndex.ts
  8. 4
      src/lib/appManagers/utils/dialogs/getDialogIndexKey.ts
  9. 4
      src/lib/appManagers/utils/state/loadState.ts
  10. 6
      src/lib/mtproto/mtproto_config.ts
  11. 140
      src/lib/storages/dialogs.ts
  12. 198
      src/lib/storages/filters.ts
  13. 13
      src/scripts/in/schema_additional_params.json

12
src/components/sidebarLeft/tabs/archivedTab.ts

@ -5,12 +5,11 @@
*/ */
import appDialogsManager from "../../../lib/appManagers/appDialogsManager"; import appDialogsManager from "../../../lib/appManagers/appDialogsManager";
import type { LOCAL_FOLDER_ID } from "../../../lib/storages/dialogs";
import type { MyDialogFilter } from "../../../lib/storages/filters";
import { SliderSuperTab } from "../../slider"; import { SliderSuperTab } from "../../slider";
import { FOLDER_ID_ARCHIVE, REAL_FOLDER_ID } from "../../../lib/mtproto/mtproto_config";
export default class AppArchivedTab extends SliderSuperTab { export default class AppArchivedTab extends SliderSuperTab {
private static filterId: LOCAL_FOLDER_ID = 1; private static filterId: REAL_FOLDER_ID = FOLDER_ID_ARCHIVE;
private wasFilterId: number; private wasFilterId: number;
protected init() { protected init() {
@ -21,7 +20,12 @@ export default class AppArchivedTab extends SliderSuperTab {
if(!appDialogsManager.sortedLists[AppArchivedTab.filterId]) { if(!appDialogsManager.sortedLists[AppArchivedTab.filterId]) {
const chatList = appDialogsManager.createChatList(); const chatList = appDialogsManager.createChatList();
appDialogsManager.generateScrollable(chatList, {id: AppArchivedTab.filterId, orderIndex: 1} as any as MyDialogFilter).container.append(chatList); const scrollable = appDialogsManager.generateScrollable(chatList, {
title: undefined,
id: AppArchivedTab.filterId,
localId: FOLDER_ID_ARCHIVE
});
scrollable.container.append(chatList);
appDialogsManager.setListClickListener(chatList, null, true); appDialogsManager.setListClickListener(chatList, null, true);
//appDialogsManager.setListClickListener(archivedChatList, null, true); // * to test peer changing //appDialogsManager.setListClickListener(archivedChatList, null, true); // * to test peer changing
} }

4
src/components/sidebarLeft/tabs/chatFolders.ts

@ -109,9 +109,9 @@ export default class AppChatFoldersTab extends SliderSuperTab {
div = row.container; div = row.container;
if((filter as MyDialogFilter).hasOwnProperty('orderIndex')) { if((filter as MyDialogFilter).localId !== undefined) {
// ! header will be at 0 index // ! header will be at 0 index
positionElementByIndex(div, div.parentElement || container, (filter as MyDialogFilter).orderIndex); positionElementByIndex(div, div.parentElement || container, (filter as MyDialogFilter).localId);
} else if(container) container.append(div); } else if(container) container.append(div);
return div; return div;

5
src/config/state.ts

@ -50,7 +50,8 @@ export type State = {
pts: number, pts: number,
date: number date: number
}>, }>,
filters: FiltersStorage['filters'], // filters?: FiltersStorage['filters'], // ! DEPRECATED
filtersArr?: FiltersStorage['filtersArr'],
maxSeenMsgId: number, maxSeenMsgId: number,
stateCreatedTime: number, stateCreatedTime: number,
recentEmoji: string[], recentEmoji: string[],
@ -151,7 +152,7 @@ export const STATE_INIT: State = {
// contactsList: [], // contactsList: [],
contactsListCachedTime: 0, contactsListCachedTime: 0,
updates: {}, updates: {},
filters: {}, filtersArr: [],
maxSeenMsgId: 0, maxSeenMsgId: 0,
stateCreatedTime: Date.now(), stateCreatedTime: Date.now(),
recentEmoji: [], recentEmoji: [],

11
src/layer.d.ts vendored

@ -8399,6 +8399,7 @@ export namespace DialogFilter {
exclude_muted?: true, exclude_muted?: true,
exclude_read?: true, exclude_read?: true,
exclude_archived?: true, exclude_archived?: true,
exclude_unarchived?: true,
}>, }>,
id: number, id: number,
title: string, title: string,
@ -8406,13 +8407,15 @@ export namespace DialogFilter {
pinned_peers: Array<InputPeer>, pinned_peers: Array<InputPeer>,
include_peers: Array<InputPeer>, include_peers: Array<InputPeer>,
exclude_peers: Array<InputPeer>, exclude_peers: Array<InputPeer>,
orderIndex?: 0 | 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21, localId?: 0 | 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21,
peerId?: PeerId, pinnedPeerIds?: PeerId[],
folder_id?: number includePeerIds?: PeerId[],
excludePeerIds?: PeerId[]
}; };
export type dialogFilterDefault = { export type dialogFilterDefault = {
_: 'dialogFilterDefault' _: 'dialogFilterDefault',
localId?: 0 | 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21
}; };
} }

89
src/lib/appManagers/appDialogsManager.ts

@ -45,7 +45,7 @@ import isInDOM from "../../helpers/dom/isInDOM";
import { setSendingStatus } from "../../components/sendingStatus"; import { setSendingStatus } from "../../components/sendingStatus";
import SortedList, { SortedElementBase } from "../../helpers/sortedList"; import SortedList, { SortedElementBase } from "../../helpers/sortedList";
import debounce from "../../helpers/schedulers/debounce"; import debounce from "../../helpers/schedulers/debounce";
import { NULL_PEER_ID } from "../mtproto/mtproto_config"; import { FOLDER_ID_ALL, FOLDER_ID_ARCHIVE, NULL_PEER_ID, REAL_FOLDERS, REAL_FOLDER_ID } from "../mtproto/mtproto_config";
import groupCallActiveIcon from "../../components/groupCallActiveIcon"; import groupCallActiveIcon from "../../components/groupCallActiveIcon";
import { Chat, Message, NotifyPeer } from "../../layer"; import { Chat, Message, NotifyPeer } from "../../layer";
import IS_GROUP_CALL_SUPPORTED from "../../environment/groupCallSupport"; import IS_GROUP_CALL_SUPPORTED from "../../environment/groupCallSupport";
@ -81,6 +81,7 @@ import DialogsPlaceholder from "../../helpers/dialogsPlaceholder";
import pause from "../../helpers/schedulers/pause"; import pause from "../../helpers/schedulers/pause";
import apiManagerProxy from "../mtproto/mtprotoworker"; import apiManagerProxy from "../mtproto/mtprotoworker";
import filterAsync from "../../helpers/array/filterAsync"; import filterAsync from "../../helpers/array/filterAsync";
import forEachReverse from "../../helpers/array/forEachReverse";
export const DIALOG_LIST_ELEMENT_TAG = 'A'; export const DIALOG_LIST_ELEMENT_TAG = 'A';
@ -315,11 +316,11 @@ export class AppDialogsManager {
})//, 5000); })//, 5000);
}); });
this.setFilterId(0, 0); this.setFilterId(FOLDER_ID_ALL, FOLDER_ID_ALL);
this.addFilter({ this.addFilter({
id: this.filterId, id: FOLDER_ID_ALL,
title: '', title: '',
orderIndex: 0 localId: FOLDER_ID_ALL
}); });
const foldersScrollable = new ScrollableX(this.folders.menuScrollContainer); const foldersScrollable = new ScrollableX(this.folders.menuScrollContainer);
@ -329,7 +330,7 @@ export class AppDialogsManager {
id += 1; id += 1;
} */ } */
id = +tabContent.dataset.filterId || 0; id = +tabContent.dataset.filterId || FOLDER_ID_ALL;
if(!IS_MOBILE_SAFARI) { if(!IS_MOBILE_SAFARI) {
if(id) { if(id) {
@ -420,15 +421,15 @@ export class AppDialogsManager {
this.scroll = this.scrollables[this.filterId]; this.scroll = this.scrollables[this.filterId];
//selectTab(0); //selectTab(0);
(this.folders.menu.firstElementChild as HTMLElement).click(); // (this.folders.menu.firstElementChild as HTMLElement).click();
} }
public get chatList() { public get chatList() {
return this.sortedList.list; return this.sortedList.list;
} }
public setFilterId(filterId: number, orderIndex: MyDialogFilter['orderIndex']) { public setFilterId(filterId: number, localId: MyDialogFilter['localId']) {
this.indexKey = getDialogIndexKey(orderIndex); this.indexKey = getDialogIndexKey(localId);
this.filterId = filterId; this.filterId = filterId;
} }
@ -552,6 +553,10 @@ export class AppDialogsManager {
}); });
rootScope.addEventListener('filter_update', async(filter) => { rootScope.addEventListener('filter_update', async(filter) => {
if(REAL_FOLDERS.has(filter.id)) {
return;
}
if(!this.filtersRendered[filter.id]) { if(!this.filtersRendered[filter.id]) {
this.addFilter(filter); this.addFilter(filter);
return; return;
@ -602,8 +607,8 @@ export class AppDialogsManager {
const sortedList = this.sortedLists[filterId]; const sortedList = this.sortedLists[filterId];
sortedList.indexKey = indexKey; sortedList.indexKey = indexKey;
positionElementByIndex(renderedFilter.menu, containerToAppend, filter.orderIndex); positionElementByIndex(renderedFilter.menu, containerToAppend, filter.localId);
positionElementByIndex(renderedFilter.container, this.folders.container, filter.orderIndex); positionElementByIndex(renderedFilter.container, this.folders.container, filter.localId);
}); });
this.indexKey = await this.managers.dialogsStorage.getDialogIndexKeyByFilterId(this.filterId); this.indexKey = await this.managers.dialogsStorage.getDialogIndexKeyByFilterId(this.filterId);
@ -642,6 +647,27 @@ export class AppDialogsManager {
} }
private async onStateLoaded(state: State) { private async onStateLoaded(state: State) {
const filtersArr = state.filtersArr;
const haveFilters = filtersArr.length > REAL_FOLDERS.size;
const filter = filtersArr.find((filter) => filter.id !== FOLDER_ID_ARCHIVE);
const addFilters = (filters: MyDialogFilter[]) => {
// forEachReverse(filters, (filter) => {
// this.addFilter(filter);
// });
for(const filter of filters) {
this.addFilter(filter);
}
};
if(haveFilters) {
addFilters(filtersArr);
} else {
this.managers.filtersStorage.getDialogFilters().then(addFilters);
}
(this.folders.menu.firstElementChild as HTMLElement).click();
const loadDialogsPromise = this.onChatsScroll(); const loadDialogsPromise = this.onChatsScroll();
if(!this.initedListeners) { if(!this.initedListeners) {
@ -649,19 +675,8 @@ export class AppDialogsManager {
this.initedListeners = true; this.initedListeners = true;
} }
const haveFilters = !!(state.filters && Object.keys(state.filters).length); if(haveFilters && this.showFiltersPromise) {
const getDialogsFiltersPromise = haveFilters ? Promise.resolve(Object.values(state.filters).sort((a, b) => a.orderIndex - b.orderIndex)) : this.managers.filtersStorage.getDialogFilters(); await this.showFiltersPromise;
const renderFiltersPromise = getDialogsFiltersPromise.then((filters) => {
for(const filter of filters) {
this.addFilter(filter);
}
});
if(haveFilters) {
await renderFiltersPromise;
if(this.showFiltersPromise) {
await this.showFiltersPromise;
}
} }
this.managers.appNotificationsManager.getNotifyPeerTypeSettings(); this.managers.appNotificationsManager.getNotifyPeerTypeSettings();
@ -738,7 +753,7 @@ export class AppDialogsManager {
}; };
private async setFilterUnreadCount(filterId: number) { private async setFilterUnreadCount(filterId: number) {
if(filterId === 0) { if(filterId === FOLDER_ID_ALL) {
return; return;
} }
@ -786,7 +801,7 @@ export class AppDialogsManager {
public testDialogForFilter(dialog: Dialog) { public testDialogForFilter(dialog: Dialog) {
if( if(
!dialog || !dialog ||
(this.filterId > 1 ? getDialogIndex(dialog, this.indexKey) === undefined : this.filterId !== dialog.folder_id) (!REAL_FOLDERS.has(this.filterId) ? getDialogIndex(dialog, this.indexKey) === undefined : this.filterId !== dialog.folder_id)
// (filter && !(await this.managers.filtersStorage.testDialogForFilter(dialog, filter))) // (filter && !(await this.managers.filtersStorage.testDialogForFilter(dialog, filter)))
) { ) {
return false; return false;
@ -807,7 +822,7 @@ export class AppDialogsManager {
const sortedDialogList = new SortedDialogList( const sortedDialogList = new SortedDialogList(
this.managers, this.managers,
list, list,
getDialogIndexKey(filter.orderIndex), getDialogIndexKey(filter.localId),
this.onListLengthChange this.onListLengthChange
); );
@ -820,16 +835,16 @@ export class AppDialogsManager {
return scrollable; return scrollable;
} }
private addFilter(filter: Pick<DialogFilter, 'title' | 'id' | 'orderIndex'>) { private addFilter(filter: Pick<DialogFilter, 'title' | 'id' | 'localId'>) {
if(filter.id === 1) { if(filter.id === FOLDER_ID_ARCHIVE) {
return; return;
} }
const containerToAppend = this.folders.menu as HTMLElement; const containerToAppend = this.folders.menu as HTMLElement;
const renderedFilter = this.filtersRendered[filter.id]; const renderedFilter = this.filtersRendered[filter.id];
if(renderedFilter) { if(renderedFilter) {
positionElementByIndex(renderedFilter.menu, containerToAppend, filter.orderIndex); positionElementByIndex(renderedFilter.menu, containerToAppend, filter.localId);
positionElementByIndex(renderedFilter.container, this.folders.container, filter.orderIndex); positionElementByIndex(renderedFilter.container, this.folders.container, filter.localId);
return; return;
} }
@ -838,7 +853,7 @@ export class AppDialogsManager {
const span = document.createElement('span'); const span = document.createElement('span');
const titleSpan = document.createElement('span'); const titleSpan = document.createElement('span');
titleSpan.classList.add('text-super'); titleSpan.classList.add('text-super');
if(filter.id === 0) titleSpan.append(this.allChatsIntlElement.element); if(filter.id === FOLDER_ID_ALL) titleSpan.append(this.allChatsIntlElement.element);
else setInnerHTML(titleSpan, wrapEmojiText(filter.title)); else setInnerHTML(titleSpan, wrapEmojiText(filter.title));
const unreadSpan = document.createElement('div'); const unreadSpan = document.createElement('div');
unreadSpan.classList.add('badge', 'badge-20', 'badge-primary'); unreadSpan.classList.add('badge', 'badge-20', 'badge-primary');
@ -847,7 +862,9 @@ export class AppDialogsManager {
ripple(menuTab); ripple(menuTab);
menuTab.append(span); menuTab.append(span);
positionElementByIndex(menuTab, containerToAppend, filter.orderIndex); menuTab.dataset.filterId = '' + filter.id;
positionElementByIndex(menuTab, containerToAppend, filter.localId);
//containerToAppend.append(li); //containerToAppend.append(li);
const ul = this.createChatList(); const ul = this.createChatList();
@ -871,7 +888,7 @@ export class AppDialogsManager {
const div = scrollable.container; const div = scrollable.container;
//this.folders.container.append(div); //this.folders.container.append(div);
positionElementByIndex(scrollable.container, this.folders.container, filter.orderIndex); positionElementByIndex(scrollable.container, this.folders.container, filter.localId);
this.setListClickListener(ul, null, true); this.setListClickListener(ul, null, true);
@ -969,7 +986,7 @@ export class AppDialogsManager {
) )
) { ) {
placeholder = this.placeholders[filterId] = new DialogsPlaceholder(); placeholder = this.placeholders[filterId] = new DialogsPlaceholder();
const getRectFrom = filterId === 1 ? this.chatsContainer : this.folders.container; const getRectFrom = filterId === FOLDER_ID_ARCHIVE ? this.chatsContainer : this.folders.container;
placeholder.attach({ placeholder.attach({
container: chatList.parentElement, container: chatList.parentElement,
getRectFrom, getRectFrom,
@ -1104,7 +1121,7 @@ export class AppDialogsManager {
} }
private checkIfPlaceholderNeeded() { private checkIfPlaceholderNeeded() {
if(this.filterId === 1) { if(this.filterId === FOLDER_ID_ARCHIVE) {
return; return;
} }
@ -1239,7 +1256,7 @@ export class AppDialogsManager {
this.checkIfPlaceholderNeeded(); this.checkIfPlaceholderNeeded();
if(this.filterId > 0) return; if(this.filterId !== FOLDER_ID_ALL) return;
const chatList = this.chatList; const chatList = this.chatList;
const count = chatList.childElementCount; const count = chatList.childElementCount;

8
src/lib/appManagers/appMessagesManager.ts

@ -18,14 +18,14 @@ import { ArgumentTypes, InvokeApiOptions } from "../../types";
import { logger, LogTypes } from "../logger"; import { logger, LogTypes } from "../logger";
import type { ApiFileManager } from '../mtproto/apiFileManager'; import type { ApiFileManager } from '../mtproto/apiFileManager';
import { ReferenceContext } from "../mtproto/referenceDatabase"; import { ReferenceContext } from "../mtproto/referenceDatabase";
import { GLOBAL_FOLDER_ID, LOCAL_FOLDER_ID } from "../storages/dialogs"; import { GLOBAL_FOLDER_ID } from "../storages/dialogs";
import { ChatRights } from "./appChatsManager"; import { ChatRights } from "./appChatsManager";
import { MyDocument } from "./appDocsManager"; import { MyDocument } from "./appDocsManager";
import { MyPhoto } from "./appPhotosManager"; import { MyPhoto } from "./appPhotosManager";
import { getFileNameByLocation } from "../../helpers/fileName"; import { getFileNameByLocation } from "../../helpers/fileName";
import DEBUG from "../../config/debug"; import DEBUG from "../../config/debug";
import SlicedArray, { Slice, SliceEnd } from "../../helpers/slicedArray"; import SlicedArray, { Slice, SliceEnd } from "../../helpers/slicedArray";
import { MUTE_UNTIL, NULL_PEER_ID, REPLIES_HIDDEN_CHANNEL_ID, REPLIES_PEER_ID, SERVICE_PEER_ID } from "../mtproto/mtproto_config"; import { FOLDER_ID_ALL, MUTE_UNTIL, NULL_PEER_ID, REAL_FOLDER_ID, REPLIES_HIDDEN_CHANNEL_ID, REPLIES_PEER_ID, SERVICE_PEER_ID } from "../mtproto/mtproto_config";
import telegramMeWebManager from "../mtproto/telegramMeWebManager"; import telegramMeWebManager from "../mtproto/telegramMeWebManager";
import { getMiddleware } from "../../helpers/middleware"; import { getMiddleware } from "../../helpers/middleware";
import assumeType from "../../helpers/assumeType"; import assumeType from "../../helpers/assumeType";
@ -1852,7 +1852,7 @@ export class AppMessagesManager extends AppManager {
} }
// public lolSet = new Set(); // public lolSet = new Set();
public getTopMessages(limit: number, folderId: LOCAL_FOLDER_ID, offsetDate?: number) { public getTopMessages(limit: number, folderId: REAL_FOLDER_ID, offsetDate?: number) {
//const dialogs = this.dialogsStorage.getFolder(folderId); //const dialogs = this.dialogsStorage.getFolder(folderId);
let offsetId = 0; let offsetId = 0;
let offsetPeerId: PeerId; let offsetPeerId: PeerId;
@ -1913,7 +1913,7 @@ export class AppMessagesManager extends AppManager {
let maxSeenIdIncremented = offsetDate ? true : false; let maxSeenIdIncremented = offsetDate ? true : false;
let hasPrepend = false; let hasPrepend = false;
const noIdsDialogs: {[peerId: PeerId]: Dialog} = {}; const noIdsDialogs: {[peerId: PeerId]: Dialog} = {};
const setFolderId: LOCAL_FOLDER_ID = folderId === GLOBAL_FOLDER_ID ? 0 : folderId; const setFolderId: REAL_FOLDER_ID = folderId === GLOBAL_FOLDER_ID ? FOLDER_ID_ALL : folderId;
const saveGlobalOffset = folderId === GLOBAL_FOLDER_ID; const saveGlobalOffset = folderId === GLOBAL_FOLDER_ID;
forEachReverse((dialogsResult.dialogs as Dialog[]), (dialog) => { forEachReverse((dialogsResult.dialogs as Dialog[]), (dialog) => {
//const d = Object.assign({}, dialog); //const d = Object.assign({}, dialog);

2
src/lib/appManagers/utils/dialogs/getDialogIndex.ts

@ -11,5 +11,5 @@ export default function getDialogIndex(
dialog: Dialog.dialog, dialog: Dialog.dialog,
indexKey: ReturnType<typeof getDialogIndexKey> = getDialogIndexKey(dialog.folder_id) indexKey: ReturnType<typeof getDialogIndexKey> = getDialogIndexKey(dialog.folder_id)
) { ) {
return dialog && dialog[indexKey]; return dialog?.[indexKey];
} }

4
src/lib/appManagers/utils/dialogs/getDialogIndexKey.ts

@ -6,8 +6,8 @@
import type { DialogFilter } from "../../../../layer"; import type { DialogFilter } from "../../../../layer";
export default function getDialogIndexKey(orderIndex?: DialogFilter.dialogFilter['orderIndex']) { export default function getDialogIndexKey(localId?: DialogFilter.dialogFilter['localId']) {
return `index_${orderIndex}` as const; return `index_${localId}` as const;
// return filterId !== undefined && filterId > 1 ? `filter_${filterId}` as const : 'main' as const; // return filterId !== undefined && filterId > 1 ? `filter_${filterId}` as const : 'main' as const;
// const indexStr = filterId > 1 ? // const indexStr = filterId > 1 ?
// `index_${filterId}` as const : // `index_${filterId}` as const :

4
src/lib/appManagers/utils/state/loadState.ts

@ -32,7 +32,7 @@ const REFRESH_KEYS: Array<keyof State> = [
'contactsListCachedTime', 'contactsListCachedTime',
'stateCreatedTime', 'stateCreatedTime',
'maxSeenMsgId', 'maxSeenMsgId',
'filters' 'filtersArr'
]; ];
//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>;
@ -300,7 +300,7 @@ async function loadStateInner() {
// reset filters and dialogs if version is older // reset filters and dialogs if version is older
if(compareVersion(state.version, '0.8.7') === -1 || state.build < 179) { if(compareVersion(state.version, '0.8.7') === -1 || state.build < 179) {
state.allDialogsLoaded = copy(STATE_INIT.allDialogsLoaded); state.allDialogsLoaded = copy(STATE_INIT.allDialogsLoaded);
state.filters = copy(STATE_INIT.filters); // state.filters = copy(STATE_INIT.filters);
resetStorages.add('dialogs'); resetStorages.add('dialogs');
} }

6
src/lib/mtproto/mtproto_config.ts

@ -4,11 +4,11 @@
* https://github.com/morethanwords/tweb/blob/master/LICENSE * https://github.com/morethanwords/tweb/blob/master/LICENSE
*/ */
/** /**
* Legacy Webogram's format, don't change dcID to camelCase. date is timestamp * Legacy Webogram's format, don't change dcID to camelCase. date is timestamp
*/ */
export type UserAuth = {dcID: number | string, date: number, id: PeerId}; export type UserAuth = {dcID: number | string, date: number, id: PeerId};
export type REAL_FOLDER_ID = 0 | 1;
export const NULL_PEER_ID: PeerId = 0; export const NULL_PEER_ID: PeerId = 0;
export const REPLIES_PEER_ID: PeerId = 1271266957; export const REPLIES_PEER_ID: PeerId = 1271266957;
@ -16,3 +16,7 @@ export const REPLIES_HIDDEN_CHANNEL_ID: ChatId = 777;
export const SERVICE_PEER_ID: PeerId = 777000; export const SERVICE_PEER_ID: PeerId = 777000;
export const MUTE_UNTIL = 0x7FFFFFFF; export const MUTE_UNTIL = 0x7FFFFFFF;
export const BOT_START_PARAM = ''; export const BOT_START_PARAM = '';
export const FOLDER_ID_ALL: REAL_FOLDER_ID = 0;
export const FOLDER_ID_ARCHIVE: REAL_FOLDER_ID = 1;
export const REAL_FOLDERS: Set<number> = new Set([FOLDER_ID_ALL, FOLDER_ID_ARCHIVE]);

140
src/lib/storages/dialogs.ts

@ -15,7 +15,7 @@ import tsNow from "../../helpers/tsNow";
import SearchIndex from "../searchIndex"; import SearchIndex from "../searchIndex";
import { SliceEnd } from "../../helpers/slicedArray"; import { SliceEnd } from "../../helpers/slicedArray";
import { MyDialogFilter } from "./filters"; import { MyDialogFilter } from "./filters";
import { NULL_PEER_ID } from "../mtproto/mtproto_config"; import { FOLDER_ID_ALL, FOLDER_ID_ARCHIVE, NULL_PEER_ID, REAL_FOLDERS, REAL_FOLDER_ID } from "../mtproto/mtproto_config";
import { NoneToVoidFunction } from "../../types"; import { NoneToVoidFunction } from "../../types";
import ctx from "../../environment/ctx"; import ctx from "../../environment/ctx";
import AppStorage from "../storage"; import AppStorage from "../storage";
@ -50,8 +50,7 @@ export type Folder = {
dispatchUnreadTimeout?: number dispatchUnreadTimeout?: number
}; };
export const GLOBAL_FOLDER_ID: LOCAL_FOLDER_ID = undefined; export const GLOBAL_FOLDER_ID: REAL_FOLDER_ID = undefined;
export type LOCAL_FOLDER_ID = 0 | 1;
// let spentTime = 0; // let spentTime = 0;
export default class DialogsStorage extends AppManager { export default class DialogsStorage extends AppManager {
@ -159,9 +158,15 @@ export default class DialogsStorage extends AppManager {
this.storage = storage; this.storage = storage;
this.dialogs = this.storage.getCache(); this.dialogs = this.storage.getCache();
this.pinnedOrders = state.pinnedOrders || {}; for(const folderId of REAL_FOLDERS) {
if(!this.pinnedOrders[0]) this.pinnedOrders[0] = []; const order = state.pinnedOrders[folderId];
if(!this.pinnedOrders[1]) this.pinnedOrders[1] = []; if(!order) {
continue;
}
const _order = this.pinnedOrders[folderId];
_order.splice(0, _order.length, ...order);
}
if(dialogs.length) { if(dialogs.length) {
AppStorage.freezeSaving<typeof DATABASE_STATE>(this.setDialogsFromState.bind(this, dialogs), ['chats', 'dialogs', 'messages', 'users']); AppStorage.freezeSaving<typeof DATABASE_STATE>(this.setDialogsFromState.bind(this, dialogs), ['chats', 'dialogs', 'messages', 'users']);
@ -212,13 +217,13 @@ export default class DialogsStorage extends AppManager {
public setDialogsLoaded(folderId: number, loaded: boolean) { public setDialogsLoaded(folderId: number, loaded: boolean) {
if(folderId === GLOBAL_FOLDER_ID && loaded) { if(folderId === GLOBAL_FOLDER_ID && loaded) {
this.allDialogsLoaded[0] = loaded; this.allDialogsLoaded[FOLDER_ID_ALL] = loaded;
this.allDialogsLoaded[1] = loaded; this.allDialogsLoaded[FOLDER_ID_ARCHIVE] = loaded;
} else { } else {
this.allDialogsLoaded[folderId] = loaded; this.allDialogsLoaded[folderId] = loaded;
} }
if(this.allDialogsLoaded[0] && this.allDialogsLoaded[1]) { if(Array.from(REAL_FOLDERS).every((folderId) => this.allDialogsLoaded[folderId])) {
this.allDialogsLoaded[GLOBAL_FOLDER_ID] = true; this.allDialogsLoaded[GLOBAL_FOLDER_ID] = true;
} }
@ -226,20 +231,23 @@ export default class DialogsStorage extends AppManager {
} }
public clear = (init = false) => { public clear = (init = false) => {
this.pinnedOrders = {
0: [],
1: []
};
if(!init) { if(!init) {
this.storage.clear(); this.storage.clear();
this.setDialogsLoaded(0, false); this.setDialogsLoaded(FOLDER_ID_ALL, false);
this.setDialogsLoaded(1, false); this.setDialogsLoaded(FOLDER_ID_ARCHIVE, false);
this.setDialogsLoaded(GLOBAL_FOLDER_ID, false); this.setDialogsLoaded(GLOBAL_FOLDER_ID, false);
for(const folderId of REAL_FOLDERS) {
this.resetPinnedOrder(folderId);
}
this.savePinnedOrders(); this.savePinnedOrders();
} else { } else {
this.allDialogsLoaded = {}; this.allDialogsLoaded = {};
this.pinnedOrders = {};
for(const folderId of REAL_FOLDERS) {
this.pinnedOrders[folderId] = [];
}
} }
this.folders = {}; this.folders = {};
@ -270,7 +278,7 @@ export default class DialogsStorage extends AppManager {
} }
public resetPinnedOrder(folderId: number) { public resetPinnedOrder(folderId: number) {
this.pinnedOrders[folderId] = []; this.pinnedOrders[folderId].length = 0;
} }
public getPinnedOrders(folderId: number) { public getPinnedOrders(folderId: number) {
@ -280,29 +288,30 @@ export default class DialogsStorage extends AppManager {
public getOffsetDate(folderId: number): number { public getOffsetDate(folderId: number): number {
const offsetDate = this.dialogsOffsetDate[folderId] || 0; const offsetDate = this.dialogsOffsetDate[folderId] || 0;
if(folderId === GLOBAL_FOLDER_ID && !offsetDate) { // make request not from beginning if we have loaded some dialogs if(folderId === GLOBAL_FOLDER_ID && !offsetDate) { // make request not from beginning if we have loaded some dialogs
return Math.min(this.getOffsetDate(0), this.getOffsetDate(1)); return Math.min(...Array.from(REAL_FOLDERS).sort((a, b) => a - b));
} }
return offsetDate; return offsetDate;
} }
public getFolder(id: number) { private generateFolder(id: number) {
let folder = this.folders[id]; const folder: Folder = {
if(!folder) { dialogs: [],
folder = this.folders[id] = { id,
dialogs: [], unreadMessagesCount: 0,
id, unreadPeerIds: new Set(),
unreadMessagesCount: 0, unreadUnmutedPeerIds: new Set()
unreadPeerIds: new Set(), };
unreadUnmutedPeerIds: new Set()
};
defineNotNumerableProperties(folder, ['dispatchUnreadTimeout']); defineNotNumerableProperties(folder, ['dispatchUnreadTimeout']);
}
return folder; return folder;
} }
public getFolder(id: number) {
return this.folders[id] ??= this.generateFolder(id);
}
public getFolderDialogs(id: number, skipMigrated = true): Dialog[] { public getFolderDialogs(id: number, skipMigrated = true): Dialog[] {
if(id === GLOBAL_FOLDER_ID) { // * it won't be sorted if(id === GLOBAL_FOLDER_ID) { // * it won't be sorted
return this.getCachedDialogs(skipMigrated); return this.getCachedDialogs(skipMigrated);
@ -331,9 +340,9 @@ export default class DialogsStorage extends AppManager {
} }
public getDialogIndexKeyByFilterId(filterId: number) { public getDialogIndexKeyByFilterId(filterId: number) {
if(filterId <= 1) return getDialogIndexKey(filterId as LOCAL_FOLDER_ID); if(REAL_FOLDERS.has(filterId)) return getDialogIndexKey(filterId as REAL_FOLDER_ID);
const filter = this.filtersStorage.getFilter(filterId); const filter = this.filtersStorage.getFilter(filterId);
return getDialogIndexKey(filter.orderIndex); return getDialogIndexKey(filter.localId);
} }
public isPeerUnmuted(peerId: PeerId) { public isPeerUnmuted(peerId: PeerId) {
@ -346,18 +355,19 @@ export default class DialogsStorage extends AppManager {
} }
public getCachedDialogs(skipMigrated?: boolean) { public getCachedDialogs(skipMigrated?: boolean) {
return this.getFolderDialogs(0, skipMigrated).concat(this.getFolderDialogs(1, skipMigrated)); const arrays = Array.from(REAL_FOLDERS).map((folderId) => this.getFolderDialogs(folderId, skipMigrated));
return [].concat(...arrays) as typeof arrays[0];
} }
private setDialogIndexInFilter(dialog: Dialog, indexKey: ReturnType<typeof getDialogIndexKey>, filter: MyDialogFilter) { private setDialogIndexInFilter(dialog: Dialog, indexKey: ReturnType<typeof getDialogIndexKey>, filter: MyDialogFilter) {
let index: number; let index: number;
/* if(filter.id <= 1) { if(REAL_FOLDERS.has(filter.id)) {
index = getDialogIndex(dialog, getDialogIndexKey(filter.id)); index = getDialogIndex(dialog, indexKey);
} else */if(this.filtersStorage.testDialogForFilter(dialog, filter)) { } else if(this.filtersStorage.testDialogForFilter(dialog, filter)) {
const pinnedIndex = filter.pinnedPeerIds.indexOf(dialog.peerId); const pinnedIndex = filter.pinnedPeerIds.indexOf(dialog.peerId);
if(pinnedIndex !== -1) { if(pinnedIndex !== -1) {
index = this.generateDialogIndex(this.generateDialogPinnedDateByIndex(filter.pinned_peers.length - 1 - pinnedIndex), true); index = this.generateDialogIndex(this.generateDialogPinnedDateByIndex(filter.pinnedPeerIds.length - 1 - pinnedIndex), true);
} else if(dialog.pFlags?.pinned) { } else if(dialog.pFlags?.pinned) {
index = this.generateIndexForDialog(dialog, true); index = this.generateIndexForDialog(dialog, true);
} else { } else {
@ -376,7 +386,7 @@ export default class DialogsStorage extends AppManager {
const folders: Dialog[][] = []; const folders: Dialog[][] = [];
if(folderId === undefined) { if(folderId === undefined) {
folders.push(this.getFolder(0).dialogs, this.getFolder(1).dialogs); folders.push(...Array.from(REAL_FOLDERS).map((folderId) => this.getFolder(folderId).dialogs));
} else { } else {
folders.push(this.getFolderDialogs(folderId, false)); folders.push(this.getFolderDialogs(folderId, false));
} }
@ -533,6 +543,10 @@ export default class DialogsStorage extends AppManager {
} }
public generateIndexForDialog(dialog: Dialog, justReturn = false, message?: MyMessage) { public generateIndexForDialog(dialog: Dialog, justReturn = false, message?: MyMessage) {
// if(!justReturn) {
// return;
// }
let topDate = 0, isPinned: boolean; let topDate = 0, isPinned: boolean;
if(dialog.pFlags.pinned && !justReturn) { if(dialog.pFlags.pinned && !justReturn) {
topDate = this.generateDialogPinnedDate(dialog); topDate = this.generateDialogPinnedDate(dialog);
@ -577,14 +591,14 @@ export default class DialogsStorage extends AppManager {
public generateDialogPinnedDate(dialog: Dialog) { public generateDialogPinnedDate(dialog: Dialog) {
const order = this.pinnedOrders[dialog.folder_id]; const order = this.pinnedOrders[dialog.folder_id];
const foundIndex = order.indexOf(dialog.peerId); let pinnedIndex = order.indexOf(dialog.peerId);
let pinnedIndex = foundIndex; if(pinnedIndex === -1) {
if(foundIndex === -1) { order.unshift(dialog.peerId);
pinnedIndex = order.push(dialog.peerId) - 1; pinnedIndex = 0;
this.savePinnedOrders(); this.savePinnedOrders();
} }
return this.generateDialogPinnedDateByIndex(pinnedIndex); return this.generateDialogPinnedDateByIndex(order.length - 1 - pinnedIndex);
} }
/* public generateDialog(peerId: PeerId) { /* public generateDialog(peerId: PeerId) {
@ -658,11 +672,11 @@ export default class DialogsStorage extends AppManager {
public pushDialog(dialog: Dialog, offsetDate?: number, ignoreOffsetDate?: boolean, saveGlobalOffset?: boolean) { public pushDialog(dialog: Dialog, offsetDate?: number, ignoreOffsetDate?: boolean, saveGlobalOffset?: boolean) {
const {folder_id, peerId} = dialog; const {folder_id, peerId} = dialog;
const dialogs = this.getFolderDialogs(folder_id, false); // const dialogs = this.getFolderDialogs(folder_id, false);
const pos = dialogs.findIndex((d) => d.peerId === peerId); // const pos = dialogs.findIndex((d) => d.peerId === peerId);
if(pos !== -1) { // if(pos !== -1) {
dialogs.splice(pos, 1); // dialogs.splice(pos, 1);
} // }
//if(!this.dialogs[peerId]) { //if(!this.dialogs[peerId]) {
this.dialogs[peerId] = dialog; this.dialogs[peerId] = dialog;
@ -696,12 +710,12 @@ export default class DialogsStorage extends AppManager {
} }
} }
if(pos === -1) { // if(pos === -1) {
this.prepareFolderUnreadCountModifyingByDialog(folder_id, dialog, true); // this.prepareFolderUnreadCountModifyingByDialog(folder_id, dialog, true);
} // }
const indexKey = getDialogIndexKey(folder_id); // const indexKey = getDialogIndexKey(folder_id);
/* const newPos = */insertInDescendSortedArray(dialogs, dialog, (dialog) => getDialogIndex(dialog, indexKey), -1); // /* const newPos = */insertInDescendSortedArray(dialogs, dialog, (dialog) => getDialogIndex(dialog, indexKey), -1);
/* if(pos !== -1 && pos !== newPos) { /* if(pos !== -1 && pos !== newPos) {
rootScope.dispatchEvent('dialog_order', {dialog, pos: newPos}); rootScope.dispatchEvent('dialog_order', {dialog, pos: newPos});
} */ } */
@ -823,7 +837,7 @@ export default class DialogsStorage extends AppManager {
/** /**
* Won't save migrated from peer, forbidden peers, left and kicked * Won't save migrated from peer, forbidden peers, left and kicked
*/ */
public saveDialog(dialog: Dialog, folderId = dialog.folder_id ?? 0, ignoreOffsetDate?: boolean, saveGlobalOffset?: boolean) { public saveDialog(dialog: Dialog, folderId = dialog.folder_id ?? FOLDER_ID_ALL, ignoreOffsetDate?: boolean, saveGlobalOffset?: boolean) {
const peerId = getPeerId(dialog.peer); const peerId = getPeerId(dialog.peer);
if(!peerId) { if(!peerId) {
console.error('saveConversation no peerId???', dialog, folderId); console.error('saveConversation no peerId???', dialog, folderId);
@ -914,6 +928,10 @@ export default class DialogsStorage extends AppManager {
dialog.peerId = peerId; dialog.peerId = peerId;
// dialog.indexes ??= {} as any; // dialog.indexes ??= {} as any;
// if(dialog.peerId === -) {
// debugger;
// }
// Because we saved message without dialog present // Because we saved message without dialog present
if(message && message.pFlags.is_outgoing) { if(message && message.pFlags.is_outgoing) {
const isOut = message.pFlags.out; const isOut = message.pFlags.out;
@ -983,7 +1001,7 @@ export default class DialogsStorage extends AppManager {
isTopEnd: boolean, isTopEnd: boolean,
isEnd: boolean isEnd: boolean
}> { }> {
if(folderId > 1) { if(!REAL_FOLDERS.has(folderId)) {
const promises: Promise<any>[] = []; const promises: Promise<any>[] = [];
const fillContactsResult = this.appUsersManager.fillContacts(); const fillContactsResult = this.appUsersManager.fillContacts();
@ -1004,7 +1022,7 @@ export default class DialogsStorage extends AppManager {
} }
// let's load only first pages by certain folderId. next pages will load without folder filtering // let's load only first pages by certain folderId. next pages will load without folder filtering
const realFolderId: LOCAL_FOLDER_ID = folderId > 1 || this.getOffsetDate(folderId) ? GLOBAL_FOLDER_ID : folderId as LOCAL_FOLDER_ID; const realFolderId: REAL_FOLDER_ID = !REAL_FOLDERS.has(folderId) || this.getOffsetDate(folderId) ? GLOBAL_FOLDER_ID : folderId as REAL_FOLDER_ID;
let curDialogStorage = this.getFolderDialogs(folderId, skipMigrated); let curDialogStorage = this.getFolderDialogs(folderId, skipMigrated);
const indexKey = this.getDialogIndexKeyByFilterId(folderId); const indexKey = this.getDialogIndexKeyByFilterId(folderId);
@ -1098,7 +1116,7 @@ export default class DialogsStorage extends AppManager {
this.handleDialogUnpinning(dialog, folder_id); this.handleDialogUnpinning(dialog, folder_id);
} }
dialog.folder_id = folder_id as LOCAL_FOLDER_ID; dialog.folder_id = folder_id as REAL_FOLDER_ID;
this.generateIndexForDialog(dialog); this.generateIndexForDialog(dialog);
this.pushDialog(dialog); // need for simultaneously updatePinnedDialogs this.pushDialog(dialog); // need for simultaneously updatePinnedDialogs
} }
@ -1108,7 +1126,7 @@ export default class DialogsStorage extends AppManager {
}; };
private onUpdateDialogPinned = (update: Update.updateDialogPinned) => { private onUpdateDialogPinned = (update: Update.updateDialogPinned) => {
const folderId = update.folder_id ?? 0; const folderId = update.folder_id ?? FOLDER_ID_ALL;
//this.log('updateDialogPinned', update); //this.log('updateDialogPinned', update);
const peerId = getPeerId((update.peer as DialogPeer.dialogPeer).peer); const peerId = getPeerId((update.peer as DialogPeer.dialogPeer).peer);
const dialog = this.getDialogOnly(peerId); const dialog = this.getDialogOnly(peerId);
@ -1137,10 +1155,10 @@ export default class DialogsStorage extends AppManager {
}; };
private onUpdatePinnedDialogs = (update: Update.updatePinnedDialogs) => { private onUpdatePinnedDialogs = (update: Update.updatePinnedDialogs) => {
const folderId = update.folder_id ?? 0; const folderId = update.folder_id ?? FOLDER_ID_ALL;
const handleOrder = (order: PeerId[]) => { const handleOrder = (order: PeerId[]) => {
this.pinnedOrders[folderId].length = 0; this.resetPinnedOrder(folderId);
order.reverse(); // index must be higher order.reverse(); // index must be higher
order.forEach((peerId) => { order.forEach((peerId) => {
newPinned[peerId] = true; newPinned[peerId] = true;

198
src/lib/storages/filters.ts

@ -5,23 +5,16 @@
*/ */
import type { DialogFilter, Update } from "../../layer"; import type { DialogFilter, Update } from "../../layer";
import { Modify } from "../../types";
import type { Dialog } from '../appManagers/appMessagesManager'; import type { Dialog } from '../appManagers/appMessagesManager';
import forEachReverse from "../../helpers/array/forEachReverse"; import forEachReverse from "../../helpers/array/forEachReverse";
import copy from "../../helpers/object/copy"; import copy from "../../helpers/object/copy";
import safeReplaceObject from "../../helpers/object/safeReplaceObject";
import getPeerId from "../appManagers/utils/peers/getPeerId"; import getPeerId from "../appManagers/utils/peers/getPeerId";
import { AppManager } from "../appManagers/manager"; import { AppManager } from "../appManagers/manager";
import findAndSplice from "../../helpers/array/findAndSplice";
import assumeType from "../../helpers/assumeType"; import assumeType from "../../helpers/assumeType";
import { FOLDER_ID_ALL, FOLDER_ID_ARCHIVE, REAL_FOLDERS, REAL_FOLDER_ID } from "../mtproto/mtproto_config";
export type MyDialogFilter = Modify<DialogFilter.dialogFilter, { export type MyDialogFilter = DialogFilter.dialogFilter;
/* pinned_peers: PeerId[],
include_peers: PeerId[],
exclude_peers: PeerId[], */
pinnedPeerIds: PeerId[],
includePeerIds: PeerId[],
excludePeerIds: PeerId[]
}>;
const convertment = [ const convertment = [
['pinned_peers', 'pinnedPeerIds'], ['pinned_peers', 'pinnedPeerIds'],
@ -29,29 +22,32 @@ const convertment = [
['include_peers', 'includePeerIds'] ['include_peers', 'includePeerIds']
] as ['pinned_peers' | 'exclude_peers' | 'include_peers', 'pinnedPeerIds' | 'excludePeerIds' | 'includePeerIds'][]; ] as ['pinned_peers' | 'exclude_peers' | 'include_peers', 'pinnedPeerIds' | 'excludePeerIds' | 'includePeerIds'][];
const START_ORDER_INDEX = 2; const START_LOCAL_ID = Math.max(...Array.from(REAL_FOLDERS)) + 1 as MyDialogFilter['localId'];
const PREPENDED_FILTERS = REAL_FOLDERS.size;
// const LOCAL_FILTER: MyDialogFilter = {
// _: 'dialogFilter', const LOCAL_FILTER: MyDialogFilter = {
// id: 0, _: 'dialogFilter',
// title: '', pFlags: {},
// exclude_peers: [], flags: 0,
// include_peers: [], id: 0,
// pinned_peers: [], title: '',
// excludePeerIds: [], exclude_peers: [],
// includePeerIds: [], include_peers: [],
// pinnedPeerIds: [], pinned_peers: [],
// pFlags: {} excludePeerIds: [],
// }; includePeerIds: [],
pinnedPeerIds: [],
};
export default class FiltersStorage extends AppManager { export default class FiltersStorage extends AppManager {
private filters: {[filterId: string]: MyDialogFilter}; private filters: {[filterId: string]: MyDialogFilter};
private orderIndex: number; private filtersArr: Array<MyDialogFilter>;
private localFilters: {[filterId: string]: MyDialogFilter};
private localId: number;
private reloadedPeerIds: Set<PeerId>; private reloadedPeerIds: Set<PeerId>;
protected after() { protected after() {
this.clear(true); this.clear(true);
this.filters = {};
this.apiUpdatesManager.addMultipleEventsListeners({ this.apiUpdatesManager.addMultipleEventsListeners({
updateDialogFilter: this.onUpdateDialogFilter, updateDialogFilter: this.onUpdateDialogFilter,
@ -97,28 +93,50 @@ export default class FiltersStorage extends AppManager {
}); */ }); */
return this.appStateManager.getState().then((state) => { return this.appStateManager.getState().then((state) => {
safeReplaceObject(this.filters, state.filters); const filtersArr = this.prependFilters(state.filtersArr);
filtersArr.map((filter) => {
delete filter.localId;
this.saveDialogFilter(filter, false, true);
});
});
}
for(const filterId in this.filters) { /**
const filter = this.filters[filterId]; * ! use it only with saving
if(filter.hasOwnProperty('orderIndex') && filter.orderIndex >= this.orderIndex) { */
this.orderIndex = filter.orderIndex + 1; private prependFilters(filters: DialogFilter[]) {
} filters = filters.slice();
/* this.appMessagesManager.dialogsStorage.folders[+filterId] = { const allChatsFilter = this.localFilters[FOLDER_ID_ALL];
dialogs: [] const archiveFilter = this.localFilters[FOLDER_ID_ARCHIVE];
}; */
}
// delete this.filters[0]; const allChatsFilterIndex = filters.findIndex((filter) => filter._ === 'dialogFilterDefault' || filter.id === FOLDER_ID_ALL);
// delete this.filters[1]; if(allChatsFilterIndex !== -1) filters[allChatsFilterIndex] = allChatsFilter;
// this.getLocalFilter(0); else filters.unshift(allChatsFilter);
// this.getLocalFilter(1);
}); findAndSplice(filters, (filter) => (filter as MyDialogFilter).id === FOLDER_ID_ARCHIVE);
filters.splice(/* 1 */filters[0] === allChatsFilter ? 1 : 0, 0, archiveFilter);
return filters;
}
private generateLocalFilter(id: REAL_FOLDER_ID) {
const filter: MyDialogFilter = {...copy(LOCAL_FILTER), id};
if(id === FOLDER_ID_ALL) {
filter.pFlags.exclude_archived = true;
} else if(id === FOLDER_ID_ARCHIVE) {
filter.pFlags.exclude_unarchived = true;
}
if(REAL_FOLDERS.has(id)) {
filter.pinnedPeerIds = this.dialogsStorage.getPinnedOrders(id);
}
return filter;
} }
// private getLocalFilter(id: number) { // private getLocalFilter(id: number) {
// return this.filters[id] ??= {...copy(LOCAL_FILTER), id}; // return this.filters[id] ??= this.generateLocalFilter(id);
// } // }
public clear = (init?: boolean) => { public clear = (init?: boolean) => {
@ -128,10 +146,16 @@ export default class FiltersStorage extends AppManager {
this.clearFilters(); this.clearFilters();
} else { } else {
this.filters = {}; this.filters = {};
this.filtersArr = [];
this.reloadedPeerIds = new Set(); this.reloadedPeerIds = new Set();
this.localFilters = {};
for(const filterId of REAL_FOLDERS) {
this.localFilters[filterId] = this.generateLocalFilter(filterId as REAL_FOLDER_ID);
}
} }
this.orderIndex = START_ORDER_INDEX; this.localId = START_LOCAL_ID;
}; };
private onUpdateDialogFilter = (update: Update.updateDialogFilter) => { private onUpdateDialogFilter = (update: Update.updateDialogFilter) => {
@ -141,28 +165,33 @@ export default class FiltersStorage extends AppManager {
//this.getDialogFilters(true); //this.getDialogFilters(true);
this.rootScope.dispatchEvent('filter_delete', this.filters[update.id]); this.rootScope.dispatchEvent('filter_delete', this.filters[update.id]);
delete this.filters[update.id]; delete this.filters[update.id];
findAndSplice(this.filtersArr, (filter) => (filter as DialogFilter.dialogFilter).id === update.id);
} }
this.appStateManager.pushToState('filters', this.filters); this.pushToState();
}; };
private onUpdateDialogFilterOrder = (update: Update.updateDialogFilterOrder) => { private onUpdateDialogFilterOrder = (update: Update.updateDialogFilterOrder) => {
//console.log('updateDialogFilterOrder', update); //console.log('updateDialogFilterOrder', update);
this.orderIndex = START_ORDER_INDEX; this.localId = START_LOCAL_ID;
update.order.forEach((filterId, idx) => { update.order.forEach((filterId, idx) => {
const filter = this.filters[filterId]; const filter = this.filters[filterId];
delete filter.orderIndex; delete filter.localId;
this.setOrderIndex(filter); this.setLocalId(filter);
}); });
this.rootScope.dispatchEvent('filter_order', update.order); this.rootScope.dispatchEvent('filter_order', update.order);
this.appStateManager.pushToState('filters', this.filters); this.pushToState();
}; };
private pushToState() {
this.appStateManager.pushToState('filtersArr', this.filtersArr);
}
public testDialogForFilter(dialog: Dialog, filter: MyDialogFilter) { public testDialogForFilter(dialog: Dialog, filter: MyDialogFilter) {
if(filter.id <= 1) { if(REAL_FOLDERS.has(filter.id)) {
return dialog.folder_id === filter.id; return dialog.folder_id === filter.id;
} }
@ -186,7 +215,7 @@ export default class FiltersStorage extends AppManager {
const pFlags = filter.pFlags; const pFlags = filter.pFlags;
// exclude_archived // exclude_archived
if(pFlags.exclude_archived && dialog.folder_id === 1) { if(pFlags.exclude_archived && dialog.folder_id === FOLDER_ID_ARCHIVE) {
return false; return false;
} }
@ -247,6 +276,10 @@ export default class FiltersStorage extends AppManager {
public clearFilters() { public clearFilters() {
const filters = this.getFilters(); const filters = this.getFilters();
for(const filterId in filters) { // delete filters for(const filterId in filters) { // delete filters
if(REAL_FOLDERS.has(+filterId)) {
continue;
}
this.onUpdateDialogFilter({ this.onUpdateDialogFilter({
_: 'updateDialogFilter', _: 'updateDialogFilter',
id: +filterId, id: +filterId,
@ -311,13 +344,13 @@ export default class FiltersStorage extends AppManager {
const f: MyDialogFilter[] = []; const f: MyDialogFilter[] = [];
for(const filterId in this.filters) { for(const filterId in this.filters) {
const filter = this.filters[filterId]; const filter = this.filters[filterId];
++filter.orderIndex; ++filter.localId;
f.push(filter); f.push(filter);
} }
filter.orderIndex = START_ORDER_INDEX; filter.localId = START_LOCAL_ID;
const order = f.sort((a, b) => a.orderIndex - b.orderIndex).map((filter) => filter.id); const order = f.sort((a, b) => a.localId - b.localId).map((filter) => filter.id);
this.onUpdateDialogFilterOrder({ this.onUpdateDialogFilterOrder({
_: 'updateDialogFilterOrder', _: 'updateDialogFilterOrder',
order order
@ -427,37 +460,37 @@ export default class FiltersStorage extends AppManager {
public async getDialogFilters(overwrite = false): Promise<MyDialogFilter[]> { public async getDialogFilters(overwrite = false): Promise<MyDialogFilter[]> {
const keys = Object.keys(this.filters); const keys = Object.keys(this.filters);
if(keys.length && !overwrite) { if(keys.length > PREPENDED_FILTERS && !overwrite) {
return keys.map((filterId) => this.filters[filterId]).sort((a, b) => a.orderIndex - b.orderIndex); return keys.map((filterId) => this.filters[filterId]).sort((a, b) => a.localId - b.localId);
} }
const filters = await this.apiManager.invokeApiSingle('messages.getDialogFilters'); const filters = await this.apiManager.invokeApiSingle('messages.getDialogFilters');
return filters.map((filter) => this.saveDialogFilter(filter, overwrite)).filter(Boolean); return this.prependFilters(filters).map((filter) => this.saveDialogFilter(filter, overwrite)).filter(Boolean);
} }
public getSuggestedDialogsFilters() { public getSuggestedDialogsFilters() {
return this.apiManager.invokeApi('messages.getSuggestedDialogFilters'); return this.apiManager.invokeApi('messages.getSuggestedDialogFilters');
} }
public saveDialogFilter(filter: DialogFilter, update = true) { public saveDialogFilter(filter: DialogFilter, update = true, silent?: boolean) {
// defineNotNumerableProperties(filter, ['includePeerIds', 'excludePeerIds', 'pinnedPeerIds']); // defineNotNumerableProperties(filter, ['includePeerIds', 'excludePeerIds', 'pinnedPeerIds']);
// if(filter._ === 'dialogFilterDefault') { if(filter._ === 'dialogFilterDefault') {
// return; filter = this.localFilters[FOLDER_ID_ALL];
// // filter = this.getLocalFilter(0); }
// // delete filter.orderIndex;
// }
assumeType<MyDialogFilter>(filter); assumeType<MyDialogFilter>(filter);
convertment.forEach(([from, to]) => { if(!REAL_FOLDERS.has(filter.id)) {
assumeType<MyDialogFilter>(filter); convertment.forEach(([from, to]) => {
filter[to] = filter[from].map((peer) => getPeerId(peer)); assumeType<MyDialogFilter>(filter);
}); filter[to] = filter[from].map((peer) => getPeerId(peer));
});
this.filterIncludedPinnedPeers(filter); this.filterIncludedPinnedPeers(filter);
filter.include_peers = filter.pinned_peers.concat(filter.include_peers); filter.include_peers = filter.pinned_peers.concat(filter.include_peers);
filter.includePeerIds = filter.pinnedPeerIds.concat(filter.includePeerIds); filter.includePeerIds = filter.pinnedPeerIds.concat(filter.includePeerIds);
}
const oldFilter = this.filters[filter.id]; const oldFilter = this.filters[filter.id];
if(oldFilter) { if(oldFilter) {
@ -466,26 +499,29 @@ export default class FiltersStorage extends AppManager {
this.filters[filter.id] = filter; this.filters[filter.id] = filter;
} }
this.setOrderIndex(filter); this.setLocalId(filter);
if(update) { if(!silent) {
this.rootScope.dispatchEvent('filter_update', filter); if(update) {
} else if(!oldFilter) { this.rootScope.dispatchEvent('filter_update', filter);
this.rootScope.dispatchEvent('filter_new', filter); } else if(!oldFilter) {
this.rootScope.dispatchEvent('filter_new', filter);
}
} }
return filter; return filter;
} }
public setOrderIndex(filter: MyDialogFilter) { private setLocalId(filter: MyDialogFilter) {
if(filter.hasOwnProperty('orderIndex')) { if(filter.localId !== undefined) {
if(filter.orderIndex >= this.orderIndex) { if(filter.localId >= this.localId) {
this.orderIndex = filter.orderIndex + 1; this.localId = filter.localId + 1;
} }
} else { } else {
filter.orderIndex = this.orderIndex++ as MyDialogFilter['orderIndex']; filter.localId = this.localId++ as MyDialogFilter['localId'];
findAndSplice(this.filtersArr, (_filter) => _filter.id === filter.id);
this.filtersArr.push(filter);
this.pushToState();
} }
this.appStateManager.pushToState('filters', this.filters);
} }
} }

13
src/scripts/in/schema_additional_params.json

@ -61,9 +61,16 @@
}, { }, {
"predicate": "dialogFilter", "predicate": "dialogFilter",
"params": [ "params": [
{"name": "orderIndex", "type": "0 | 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21"}, {"name": "localId", "type": "0 | 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21"},
{"name": "peerId", "type": "PeerId"}, {"name": "pinnedPeerIds", "type": "PeerId[]"},
{"name": "folder_id", "type": "number"} {"name": "includePeerIds", "type": "PeerId[]"},
{"name": "excludePeerIds", "type": "PeerId[]"},
{"name": "exclude_unarchived", "type": "true"}
]
}, {
"predicate": "dialogFilterDefault",
"params": [
{"name": "localId", "type": "0 | 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21"}
] ]
}, { }, {
"predicate": "message", "predicate": "message",

Loading…
Cancel
Save