Browse Source

Misc folder management fixes

master
Eduard Kuzmenko 2 years ago
parent
commit
b148a60c8c
  1. 73
      src/components/sidebarLeft/tabs/chatFolders.ts
  2. 31
      src/components/sidebarLeft/tabs/includedChats.ts
  3. 1
      src/lib/appManagers/appUsersManager.ts
  4. 1
      src/lib/mtproto/api_methods.ts
  5. 3
      src/lib/mtproto/mtproto_config.ts
  6. 15
      src/lib/rootScope.ts
  7. 3
      src/lib/storages/filters.ts

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

@ -4,12 +4,12 @@ @@ -4,12 +4,12 @@
* https://github.com/morethanwords/tweb/blob/master/LICENSE
*/
import type { MyDialogFilter } from "../../../lib/storages/filters";
import type { DialogFilterSuggested } from "../../../layer";
import type _rootScope from "../../../lib/rootScope";
import { SliderSuperTab } from "../../slider";
import lottieLoader, { LottieLoader } from "../../../lib/rlottie/lottieLoader";
import { toast } from "../../toast";
import type { MyDialogFilter } from "../../../lib/storages/filters";
import type { DialogFilterSuggested, DialogFilter } from "../../../layer";
import type _rootScope from "../../../lib/rootScope";
import Button from "../../button";
import rootScope from "../../../lib/rootScope";
import AppEditFolderTab from "./editFolder";
@ -22,6 +22,7 @@ import positionElementByIndex from "../../../helpers/dom/positionElementByIndex" @@ -22,6 +22,7 @@ import positionElementByIndex from "../../../helpers/dom/positionElementByIndex"
import RLottiePlayer from "../../../lib/rlottie/rlottiePlayer";
import wrapEmojiText from "../../../lib/richTextProcessor/wrapEmojiText";
import { FOLDER_ID_ALL, FOLDER_ID_ARCHIVE, REAL_FOLDERS } from "../../../lib/mtproto/mtproto_config";
import replaceContent from "../../../helpers/dom/replaceContent";
export default class AppChatFoldersTab extends SliderSuperTab {
private createFolderBtn: HTMLElement;
@ -33,7 +34,12 @@ export default class AppChatFoldersTab extends SliderSuperTab { @@ -33,7 +34,12 @@ export default class AppChatFoldersTab extends SliderSuperTab {
private filtersRendered: {[filterId: number]: Row} = {};
private loadAnimationPromise: ReturnType<LottieLoader['waitForFirstFrame']>;
private async renderFolder(dialogFilter: DialogFilterSuggested | MyDialogFilter, container?: HTMLElement, row?: Row) {
private async renderFolder(
dialogFilter: DialogFilterSuggested | MyDialogFilter,
container?: HTMLElement,
row?: Row,
append?: boolean
) {
let filter: MyDialogFilter;
let description = '';
let d: HTMLElement[] = [];
@ -86,14 +92,12 @@ export default class AppChatFoldersTab extends SliderSuperTab { @@ -86,14 +92,12 @@ export default class AppChatFoldersTab extends SliderSuperTab {
});
if(d.length) {
join(d).forEach((el) => {
row.subtitle.append(el);
});
row.subtitle.append(...join(d));
}
if(dialogFilter._ === 'dialogFilter') {
const filterId = filter.id;
if(!this.filtersRendered.hasOwnProperty(filter.id) && filter.id !== FOLDER_ID_ALL) {
if(!this.filtersRendered[filter.id] && filter.id !== FOLDER_ID_ALL) {
attachClickEvent(row.container, async() => {
this.slider.createTab(AppEditFolderTab).open(await this.managers.filtersStorage.getFilter(filterId));
}, {listenerSetter: this.listenerSetter});
@ -102,18 +106,25 @@ export default class AppChatFoldersTab extends SliderSuperTab { @@ -102,18 +106,25 @@ export default class AppChatFoldersTab extends SliderSuperTab {
this.filtersRendered[filter.id] = row;
}
} else {
if(filter.id !== FOLDER_ID_ALL) {
replaceContent(row.title, wrapEmojiText(filter.title));
}
row.subtitle.textContent = '';
join(d).forEach((el) => {
row.subtitle.append(el);
});
row.subtitle.append(...join(d));
}
div = row.container;
if((filter as MyDialogFilter).localId !== undefined) {
// ! header will be at 0 index
positionElementByIndex(div, div.parentElement || container, (filter as MyDialogFilter).localId);
} else if(container) container.append(div);
if(append) {
const localId = (filter as MyDialogFilter).localId;
if(localId !== undefined) {
// ! header will be at 0 index
positionElementByIndex(div, div.parentElement || container, localId);
} else if(container) {
container.append(div);
}
}
return div;
}
@ -166,17 +177,20 @@ export default class AppChatFoldersTab extends SliderSuperTab { @@ -166,17 +177,20 @@ export default class AppChatFoldersTab extends SliderSuperTab {
continue;
}
await this.renderFolder(filter, this.foldersSection.content);
await this.renderFolder(filter, this.foldersSection.content, undefined, true);
}
this.toggleAllChats();
onFiltersContainerUpdate();
});
this.listenerSetter.add(rootScope)('filter_update', async(filter) => {
if(this.filtersRendered.hasOwnProperty(filter.id)) {
await this.renderFolder(filter, null, this.filtersRendered[filter.id]);
} else {
await this.renderFolder(filter, this.foldersSection.content);
const filterRendered = this.filtersRendered[filter.id];
if(filterRendered) {
await this.renderFolder(filter, null, filterRendered);
} else if(filter.id !== FOLDER_ID_ARCHIVE) {
await this.renderFolder(filter, this.foldersSection.content, undefined, true);
}
onFiltersContainerUpdate();
@ -185,7 +199,8 @@ export default class AppChatFoldersTab extends SliderSuperTab { @@ -185,7 +199,8 @@ export default class AppChatFoldersTab extends SliderSuperTab {
});
this.listenerSetter.add(rootScope)('filter_delete', (filter) => {
if(this.filtersRendered.hasOwnProperty(filter.id)) {
const filterRendered = this.filtersRendered[filter.id];
if(filterRendered) {
/* for(const suggested of this.suggestedFilters) {
if(deepEqual(suggested.filter, filter)) {
@ -193,7 +208,7 @@ export default class AppChatFoldersTab extends SliderSuperTab { @@ -193,7 +208,7 @@ export default class AppChatFoldersTab extends SliderSuperTab {
} */
this.getSuggestedFilters();
this.filtersRendered[filter.id].container.remove();
filterRendered.container.remove();
delete this.filtersRendered[filter.id];
}
@ -201,12 +216,17 @@ export default class AppChatFoldersTab extends SliderSuperTab { @@ -201,12 +216,17 @@ export default class AppChatFoldersTab extends SliderSuperTab {
});
this.listenerSetter.add(rootScope)('filter_order', (order) => {
order.forEach((filterId, idx) => {
const container = this.filtersRendered[filterId].container;
order.filter((filterId) => !!this.filtersRendered[filterId]).forEach((filterId, idx) => {
const filterRendered = this.filtersRendered[filterId];
const container = filterRendered.container;
positionElementByIndex(container, container.parentElement, idx + 1); // ! + 1 due to header
});
});
this.listenerSetter.add(rootScope)('premium_toggle', () => {
this.toggleAllChats();
});
this.loadAnimationPromise = lottieLoader.loadAnimationAsAsset({
container: this.stickerContainer,
loop: false,
@ -234,6 +254,11 @@ export default class AppChatFoldersTab extends SliderSuperTab { @@ -234,6 +254,11 @@ export default class AppChatFoldersTab extends SliderSuperTab {
});
}
private toggleAllChats() {
const filterRendered = this.filtersRendered[FOLDER_ID_ALL];
filterRendered.container.classList.toggle('hide', !rootScope.premium);
}
private async canCreateFolder() {
const [appConfig, filters] = await Promise.all([
this.managers.apiManager.getAppConfig(),

31
src/components/sidebarLeft/tabs/includedChats.ts

@ -20,6 +20,8 @@ import forEachReverse from "../../../helpers/array/forEachReverse"; @@ -20,6 +20,8 @@ import forEachReverse from "../../../helpers/array/forEachReverse";
import setInnerHTML from "../../../helpers/dom/setInnerHTML";
import wrapEmojiText from "../../../lib/richTextProcessor/wrapEmojiText";
import { REAL_FOLDERS } from "../../../lib/mtproto/mtproto_config";
import rootScope from "../../../lib/rootScope";
import { MTAppConfig } from "../../../lib/mtproto/appConfig";
export default class AppIncludedChatsTab extends SliderSuperTab {
private editFolderTab: AppEditFolderTab;
@ -31,6 +33,7 @@ export default class AppIncludedChatsTab extends SliderSuperTab { @@ -31,6 +33,7 @@ export default class AppIncludedChatsTab extends SliderSuperTab {
private originalFilter: DialogFilter;
private dialogsByFilters: Map<DialogFilter, Set<PeerId>>;
private limit: number;
protected init() {
this.content.remove();
@ -106,14 +109,26 @@ export default class AppIncludedChatsTab extends SliderSuperTab { @@ -106,14 +109,26 @@ export default class AppIncludedChatsTab extends SliderSuperTab {
this.close();
});
const onAppConfig = (appConfig: MTAppConfig) => {
this.limit = rootScope.premium ? appConfig.dialog_filters_chats_limit_premium : appConfig.dialog_filters_chats_limit_default;
};
this.listenerSetter.add(rootScope)('app_config', onAppConfig);
this.dialogsByFilters = new Map();
return this.managers.filtersStorage.getDialogFilters().then(async(filters) => {
await Promise.all(filters.filter((filter) => !REAL_FOLDERS.has(filter.id)).map(async(filter) => {
const dialogs = await this.managers.dialogsStorage.getFolderDialogs(filter.id);
const peerIds = dialogs.map((d) => d.peerId);
this.dialogsByFilters.set(filter, new Set(peerIds));
}));
});
return Promise.all([
this.managers.filtersStorage.getDialogFilters().then(async(filters) => {
await Promise.all(filters.filter((filter) => !REAL_FOLDERS.has(filter.id)).map(async(filter) => {
const dialogs = await this.managers.dialogsStorage.getFolderDialogs(filter.id);
const peerIds = dialogs.map((d) => d.peerId);
this.dialogsByFilters.set(filter, new Set(peerIds));
}));
}),
this.managers.apiManager.getAppConfig().then((appConfig) => {
onAppConfig(appConfig);
})
]);
}
checkbox(selected?: boolean) {
@ -223,7 +238,7 @@ export default class AppIncludedChatsTab extends SliderSuperTab { @@ -223,7 +238,7 @@ export default class AppIncludedChatsTab extends SliderSuperTab {
let addedInitial = false;
const _add = this.selector.add.bind(this.selector);
this.selector.add = (peerId, title, scroll) => {
if(this.selector.selected.size >= 100 && addedInitial && !details[peerId]) {
if(this.selector.selected.size >= this.limit && addedInitial && !details[peerId]) {
const el: HTMLInputElement = this.selector.list.querySelector(`[data-peer-id="${peerId}"] [type="checkbox"]`);
if(el) {
setTimeout(() => {

1
src/lib/appManagers/appUsersManager.ts

@ -550,7 +550,6 @@ export class AppUsersManager extends AppManager { @@ -550,7 +550,6 @@ export class AppUsersManager extends AppManager {
if(user.pFlags.self) {
const isPremium = !!user.pFlags.premium;
if(this.rootScope.premium !== isPremium) {
this.rootScope.premium = isPremium;
this.rootScope.dispatchEvent('premium_toggle', isPremium);
}
}

1
src/lib/mtproto/api_methods.ts

@ -241,6 +241,7 @@ export default abstract class ApiManagerMethods extends AppManager { @@ -241,6 +241,7 @@ export default abstract class ApiManagerMethods extends AppManager {
this.appConfig = config;
ignoreRestrictionReasons(config.ignore_restriction_reasons ?? []);
this.rootScope.dispatchEvent('app_config', config);
return config;
});

3
src/lib/mtproto/mtproto_config.ts

@ -4,6 +4,8 @@ @@ -4,6 +4,8 @@
* https://github.com/morethanwords/tweb/blob/master/LICENSE
*/
import type { MyDialogFilter } from "../storages/filters";
/**
* Legacy Webogram's format, don't change dcID to camelCase. date is timestamp
*/
@ -20,3 +22,4 @@ export const BOT_START_PARAM = ''; @@ -20,3 +22,4 @@ 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]);
export const START_LOCAL_ID = Math.max(...Array.from(REAL_FOLDERS)) + 1 as MyDialogFilter['localId'];

15
src/lib/rootScope.ts

@ -21,6 +21,7 @@ import EventListenerBase from "../helpers/eventListenerBase"; @@ -21,6 +21,7 @@ import EventListenerBase from "../helpers/eventListenerBase";
import { MOUNT_CLASS_TO } from "../config/debug";
import MTProtoMessagePort from "./mtproto/mtprotoMessagePort";
import { IS_WORKER } from "../helpers/context";
import { MTAppConfig } from "./mtproto/appConfig";
export type BroadcastEvents = {
'chat_full_update': ChatId,
@ -140,7 +141,9 @@ export type BroadcastEvents = { @@ -140,7 +141,9 @@ export type BroadcastEvents = {
'payment_sent': {peerId: PeerId, mid: number},
'premium_toggle': boolean
'premium_toggle': boolean,
'app_config': MTAppConfig
};
export type BroadcastEventsListeners = {
@ -148,8 +151,8 @@ export type BroadcastEventsListeners = { @@ -148,8 +151,8 @@ export type BroadcastEventsListeners = {
};
export class RootScope extends EventListenerBase<BroadcastEventsListeners> {
public myId: PeerId = NULL_PEER_ID;
private connectionStatus: {[name: string]: ConnectionStatusChange} = {};
public myId: PeerId;
private connectionStatus: {[name: string]: ConnectionStatusChange};
public settings: State['settings'];
public managers: AppManagers;
public premium: boolean;
@ -157,12 +160,18 @@ export class RootScope extends EventListenerBase<BroadcastEventsListeners> { @@ -157,12 +160,18 @@ export class RootScope extends EventListenerBase<BroadcastEventsListeners> {
constructor() {
super();
this.myId = NULL_PEER_ID;
this.connectionStatus = {};
this.premium = false;
this.addEventListener('user_auth', ({id}) => {
this.myId = id.toPeerId();
});
this.addEventListener('premium_toggle', (isPremium) => {
this.premium = isPremium;
});
this.addEventListener('connection_status_change', (status) => {
this.connectionStatus[status.name] = status;
});

3
src/lib/storages/filters.ts

@ -11,7 +11,7 @@ import copy from "../../helpers/object/copy"; @@ -11,7 +11,7 @@ import copy from "../../helpers/object/copy";
import { AppManager } from "../appManagers/manager";
import findAndSplice from "../../helpers/array/findAndSplice";
import assumeType from "../../helpers/assumeType";
import { FOLDER_ID_ALL, FOLDER_ID_ARCHIVE, REAL_FOLDERS, REAL_FOLDER_ID } from "../mtproto/mtproto_config";
import { FOLDER_ID_ALL, FOLDER_ID_ARCHIVE, REAL_FOLDERS, REAL_FOLDER_ID, START_LOCAL_ID } from "../mtproto/mtproto_config";
export type MyDialogFilter = DialogFilter.dialogFilter;
@ -21,7 +21,6 @@ const convertment = [ @@ -21,7 +21,6 @@ const convertment = [
['include_peers', 'includePeerIds']
] as ['pinned_peers' | 'exclude_peers' | 'include_peers', 'pinnedPeerIds' | 'excludePeerIds' | 'includePeerIds'][];
const START_LOCAL_ID = Math.max(...Array.from(REAL_FOLDERS)) + 1 as MyDialogFilter['localId'];
const PREPENDED_FILTERS = REAL_FOLDERS.size;
const LOCAL_FILTER: MyDialogFilter = {

Loading…
Cancel
Save