tweb/src/lib/storages/filters.ts
Eduard Kuzmenko 4d7638af5a Notifications almost finished
Maybe fix updates
Removed jsbn dependency
2021-03-09 02:15:44 +04:00

263 lines
7.4 KiB
TypeScript
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

import { copy } from "../../helpers/object";
import type { DialogFilter, Update } from "../../layer";
import type { Modify } from "../../types";
import type { AppPeersManager } from "../appManagers/appPeersManager";
import type { AppUsersManager } from "../appManagers/appUsersManager";
//import type { ApiManagerProxy } from "../mtproto/mtprotoworker";
import type _rootScope from "../rootScope";
import type {Dialog} from '../appManagers/appMessagesManager';
import apiManager from "../mtproto/mtprotoworker";
export type MyDialogFilter = Modify<DialogFilter, {
pinned_peers: number[],
include_peers: number[],
exclude_peers: number[],
orderIndex?: number
}>;
// ! because 0 index is 'All Chats'
const START_ORDER_INDEX = 1;
export default class FiltersStorage {
public filters: {[filterId: string]: MyDialogFilter} = {};
public orderIndex = START_ORDER_INDEX;
constructor(private appPeersManager: AppPeersManager, private appUsersManager: AppUsersManager, /* private apiManager: ApiManagerProxy, */ private rootScope: typeof _rootScope) {
rootScope.on('apiUpdate', (e) => {
this.handleUpdate(e);
});
}
public handleUpdate(update: Update) {
switch(update._) {
case 'updateDialogFilter': {
//console.log('updateDialogFilter', update);
if(update.filter) {
this.saveDialogFilter(update.filter as any);
} else if(this.filters[update.id]) { // Папка удалена
//this.getDialogFilters(true);
this.rootScope.broadcast('filter_delete', this.filters[update.id]);
delete this.filters[update.id];
}
break;
}
case 'updateDialogFilters': {
//console.warn('updateDialogFilters', update);
const oldFilters = copy(this.filters);
this.getDialogFilters(true).then(filters => {
for(const _filterId in oldFilters) {
const filterId = +_filterId;
if(!filters.find(filter => filter.id === filterId)) { // * deleted
this.handleUpdate({_: 'updateDialogFilter', id: filterId});
}
}
this.handleUpdate({_: 'updateDialogFilterOrder', order: filters.map(filter => filter.id)});
});
break;
}
case 'updateDialogFilterOrder': {
//console.log('updateDialogFilterOrder', update);
this.orderIndex = START_ORDER_INDEX;
update.order.forEach((filterId, idx) => {
const filter = this.filters[filterId];
delete filter.orderIndex;
this.setOrderIndex(filter);
});
this.rootScope.broadcast('filter_order', update.order);
break;
}
}
}
public testDialogForFilter(dialog: Dialog, filter: MyDialogFilter) {
// exclude_peers
for(const peerId of filter.exclude_peers) {
if(peerId === dialog.peerId) {
return false;
}
}
// include_peers
for(const peerId of filter.include_peers) {
if(peerId === dialog.peerId) {
return true;
}
}
const pFlags = filter.pFlags;
// exclude_archived
if(pFlags.exclude_archived && dialog.folder_id === 1) {
return false;
}
// exclude_read
if(pFlags.exclude_read && !dialog.unread_count) {
return false;
}
// exclude_muted
if(pFlags.exclude_muted) {
const isMuted = (dialog.notify_settings?.mute_until * 1000) > Date.now();
if(isMuted) {
return false;
}
}
const peerId = dialog.peerId;
if(peerId < 0) {
// broadcasts
if(pFlags.broadcasts && this.appPeersManager.isBroadcast(peerId)) {
return true;
}
// groups
if(pFlags.groups && this.appPeersManager.isAnyGroup(peerId)) {
return true;
}
} else {
// bots
if(this.appPeersManager.isBot(peerId)) {
return !!pFlags.bots;
}
// non_contacts
if(pFlags.non_contacts && !this.appUsersManager.contactsList.has(peerId)) {
return true;
}
// contacts
if(pFlags.contacts && this.appUsersManager.contactsList.has(peerId)) {
return true;
}
}
return false;
}
public toggleDialogPin(peerId: number, filterId: number) {
const filter = this.filters[filterId];
const wasPinned = filter.pinned_peers.findAndSplice(p => p === peerId);
if(!wasPinned) {
filter.pinned_peers.unshift(peerId);
}
return this.updateDialogFilter(filter);
}
public createDialogFilter(filter: MyDialogFilter) {
let maxId = Math.max(1, ...Object.keys(this.filters).map(i => +i));
filter = copy(filter);
filter.id = maxId + 1;
return this.updateDialogFilter(filter);
}
public updateDialogFilter(filter: MyDialogFilter, remove = false) {
const flags = remove ? 0 : 1;
return apiManager.invokeApi('messages.updateDialogFilter', {
flags,
id: filter.id,
filter: remove ? undefined : this.getOutputDialogFilter(filter)
}).then((bool: boolean) => { // возможно нужна проверка и откат, если результат не ТРУ
//console.log('updateDialogFilter bool:', bool);
if(bool) {
/* if(!this.filters[filter.id]) {
this.saveDialogFilter(filter);
}
rootScope.$broadcast('filter_update', filter); */
this.handleUpdate({
_: 'updateDialogFilter',
id: filter.id,
filter: remove ? undefined : filter as any
});
}
return bool;
});
}
public getOutputDialogFilter(filter: MyDialogFilter) {
const c: MyDialogFilter = copy(filter);
['pinned_peers', 'exclude_peers', 'include_peers'].forEach(key => {
// @ts-ignore
c[key] = c[key].map((peerId: number) => this.appPeersManager.getInputPeerById(peerId));
});
c.include_peers.forEachReverse((peerId, idx) => {
if(c.pinned_peers.includes(peerId)) {
c.include_peers.splice(idx, 1);
}
});
return c as any as DialogFilter;
}
public async getDialogFilters(overwrite = false): Promise<MyDialogFilter[]> {
const keys = Object.keys(this.filters);
if(keys.length && !overwrite) {
return keys.map(filterId => this.filters[filterId]).sort((a, b) => a.orderIndex - b.orderIndex);
}
const filters: MyDialogFilter[] = await apiManager.invokeApi('messages.getDialogFilters') as any;
for(const filter of filters) {
this.saveDialogFilter(filter, overwrite);
}
//console.log(this.filters);
return filters;
}
public saveDialogFilter(filter: MyDialogFilter, update = true) {
['pinned_peers', 'exclude_peers', 'include_peers'].forEach(key => {
// @ts-ignore
filter[key] = filter[key].map((peer: any) => this.appPeersManager.getPeerId(peer));
});
filter.include_peers.forEachReverse((peerId, idx) => {
if(filter.pinned_peers.includes(peerId)) {
filter.include_peers.splice(idx, 1);
}
});
filter.include_peers = filter.pinned_peers.concat(filter.include_peers);
if(this.filters[filter.id]) {
Object.assign(this.filters[filter.id], filter);
} else {
this.filters[filter.id] = filter;
}
this.setOrderIndex(filter);
if(update) {
this.rootScope.broadcast('filter_update', filter);
}
}
public setOrderIndex(filter: MyDialogFilter) {
if(filter.hasOwnProperty('orderIndex')) {
if(filter.orderIndex >= this.orderIndex) {
this.orderIndex = filter.orderIndex + 1;
}
} else {
filter.orderIndex = this.orderIndex++;
}
}
}