diff --git a/src/components/button.ts b/src/components/button.ts
index 3ac1141d..e0cf12b5 100644
--- a/src/components/button.ts
+++ b/src/components/button.ts
@@ -1,10 +1,25 @@
import { ripple } from "./ripple";
-const Button = (className: string, options: Partial<{noRipple: true, onlyMobile: true, icon: string}> = {}) => {
+const Button = (className: string, options: Partial<{noRipple: true, onlyMobile: true, icon: string, rippleSquare: true, text: string}> = {}) => {
const button = document.createElement('button');
button.className = className + (options.icon ? ' tgico-' + options.icon : '');
- if(!options.noRipple) ripple(button);
- if(options.onlyMobile) button.classList.add('only-handhelds');
+
+ if(!options.noRipple) {
+ if(options.rippleSquare) {
+ button.classList.add('rp-square');
+ }
+
+ ripple(button);
+ }
+
+ if(options.onlyMobile) {
+ button.classList.add('only-handhelds');
+ }
+
+ if(options.text) {
+ button.append(options.text);
+ }
+
return button;
};
diff --git a/src/components/sidebarLeft/index.ts b/src/components/sidebarLeft/index.ts
index c5efc2ac..95fc5cb5 100644
--- a/src/components/sidebarLeft/index.ts
+++ b/src/components/sidebarLeft/index.ts
@@ -7,7 +7,7 @@ import appUsersManager from "../../lib/appManagers/appUsersManager";
import { MOUNT_CLASS_TO } from "../../lib/mtproto/mtproto_config";
import rootScope from "../../lib/rootScope";
import { attachClickEvent, findUpClassName, findUpTag } from "../../helpers/dom";
-import AppSearch, { SearchGroup } from "../appSearch";
+import { SearchGroup } from "../appSearch";
import "../avatar";
import { parseMenuButtonsTo } from "../misc";
import Scrollable, { ScrollableX } from "../scrollable";
@@ -33,9 +33,6 @@ const newChannelTab = new AppNewChannelTab();
const addMembersTab = new AppAddMembersTab();
const contactsTab = new AppContactsTab();
const newGroupTab = new AppNewGroupTab();
-const settingsTab = new AppSettingsTab();
-const editFolderTab = new AppEditFolderTab();
-const includedChatsTab = new AppIncludedChatsTab();
const archivedTab = new AppArchivedTab();
export class AppSidebarLeft extends SidebarSlider {
@@ -44,11 +41,7 @@ export class AppSidebarLeft extends SidebarSlider {
contacts: 2,
newChannel: 3,
addMembers: 4,
- newGroup: 5,
- settings: 6,
- chatFolders: 7,
- editFolder: 8,
- includedChats: 9,
+ newGroup: 5
};
private toolsBtn: HTMLButtonElement;
@@ -98,11 +91,7 @@ export class AppSidebarLeft extends SidebarSlider {
[AppSidebarLeft.SLIDERITEMSIDS.newChannel]: newChannelTab,
[AppSidebarLeft.SLIDERITEMSIDS.contacts]: contactsTab,
[AppSidebarLeft.SLIDERITEMSIDS.addMembers]: addMembersTab,
- [AppSidebarLeft.SLIDERITEMSIDS.newGroup]: newGroupTab,
- [AppSidebarLeft.SLIDERITEMSIDS.settings]: settingsTab,
- [AppSidebarLeft.SLIDERITEMSIDS.chatFolders]: this.chatFoldersTab = new AppChatFoldersTab(appMessagesManager, appPeersManager, this, apiManagerProxy, rootScope),
- [AppSidebarLeft.SLIDERITEMSIDS.editFolder]: editFolderTab,
- [AppSidebarLeft.SLIDERITEMSIDS.includedChats]: includedChatsTab,
+ [AppSidebarLeft.SLIDERITEMSIDS.newGroup]: newGroupTab
});
//this._selectTab(0); // make first tab as default
@@ -119,9 +108,10 @@ export class AppSidebarLeft extends SidebarSlider {
this.addMembersTab = addMembersTab;
this.contactsTab = contactsTab;
this.newGroupTab = newGroupTab;
- this.settingsTab = settingsTab;
- this.editFolderTab = editFolderTab;
- this.includedChatsTab = includedChatsTab;
+ this.settingsTab = new AppSettingsTab(this);
+ this.chatFoldersTab = new AppChatFoldersTab(appMessagesManager, appPeersManager, this, apiManagerProxy, rootScope);
+ this.editFolderTab = new AppEditFolderTab(this);
+ this.includedChatsTab = new AppIncludedChatsTab(this);
this.editProfileTab = new AppEditProfileTab(this);
this.menuEl = this.toolsBtn.querySelector('.btn-menu');
@@ -150,8 +140,7 @@ export class AppSidebarLeft extends SidebarSlider {
});
attachClickEvent(this.buttons.settings, (e) => {
- this.settingsTab.fillElements();
- this.selectTab(AppSidebarLeft.SLIDERITEMSIDS.settings);
+ this.settingsTab.open();
});
attachClickEvent(this.newButtons.channel, (e) => {
diff --git a/src/components/sidebarLeft/tabs/chatFolders.ts b/src/components/sidebarLeft/tabs/chatFolders.ts
index 179f5aa3..5e9d0bef 100644
--- a/src/components/sidebarLeft/tabs/chatFolders.ts
+++ b/src/components/sidebarLeft/tabs/chatFolders.ts
@@ -1,4 +1,4 @@
-import { SliderTab } from "../../slider";
+import { SliderTab, SliderSuperTab } from "../../slider";
import lottieLoader, { RLottiePlayer } from "../../../lib/lottieLoader";
import { RichTextProcessor } from "../../../lib/richtextprocessor";
import { cancelEvent, positionElementByIndex } from "../../../helpers/dom";
@@ -11,9 +11,9 @@ import type { AppPeersManager } from "../../../lib/appManagers/appPeersManager";
import type { AppSidebarLeft } from "..";
import type { DialogFilterSuggested, DialogFilter } from "../../../layer";
import type _rootScope from "../../../lib/rootScope";
+import Button from "../../button";
-export default class AppChatFoldersTab implements SliderTab {
- public container: HTMLElement;
+export default class AppChatFoldersTab extends SliderSuperTab {
public createFolderBtn: HTMLElement;
private foldersContainer: HTMLElement;
private suggestedContainer: HTMLElement;
@@ -23,7 +23,7 @@ export default class AppChatFoldersTab implements SliderTab {
private filtersRendered: {[filterId: number]: HTMLElement} = {};
constructor(private appMessagesManager: AppMessagesManager, private appPeersManager: AppPeersManager, private appSidebarLeft: AppSidebarLeft, private apiManager: ApiManagerProxy, private rootScope: typeof _rootScope) {
-
+ super(appSidebarLeft);
}
private renderFolder(dialogFilter: DialogFilterSuggested | DialogFilter | MyDialogFilter, container?: HTMLElement, div: HTMLElement = document.createElement('div')) {
@@ -97,11 +97,43 @@ export default class AppChatFoldersTab implements SliderTab {
}
init() {
- this.container = document.querySelector('.chat-folders-container');
- this.stickerContainer = this.container.querySelector('.sticker-container');
- this.foldersContainer = this.container.querySelector('.folders-my');
- this.suggestedContainer = this.container.querySelector('.folders-suggested');
- this.createFolderBtn = this.container.querySelector('.btn-create-folder');
+ this.container.classList.add('chat-folders-container');
+ this.title.innerText = 'Chat Folders';
+
+ this.scrollable.container.classList.add('chat-folders');
+
+ this.stickerContainer = document.createElement('div');
+ this.stickerContainer.classList.add('sticker-container');
+
+ const caption = document.createElement('div');
+ caption.classList.add('caption');
+ caption.innerHTML = `Create folders for different groups of chats
and quickly switch between them.`;
+
+ this.createFolderBtn = Button('btn-primary btn-create-folder', {
+ text: 'Create Folder',
+ icon: 'add'
+ });
+
+ this.foldersContainer = document.createElement('div');
+ this.foldersContainer.classList.add('folders-my');
+
+ const foldersH2 = document.createElement('div');
+ foldersH2.classList.add('sidebar-left-h2');
+ foldersH2.innerText = 'Folders';
+
+ this.foldersContainer.append(foldersH2);
+
+ this.suggestedContainer = document.createElement('div');
+ this.suggestedContainer.classList.add('folders-suggested');
+ this.suggestedContainer.style.display = 'none';
+
+ const suggestedH2 = document.createElement('div');
+ suggestedH2.classList.add('sidebar-left-h2');
+ suggestedH2.innerText = 'Recommended folders';
+
+ this.suggestedContainer.append(suggestedH2);
+
+ this.scrollable.append(this.stickerContainer, caption, this.createFolderBtn, document.createElement('hr'), this.foldersContainer, document.createElement('hr'), this.suggestedContainer);
this.createFolderBtn.addEventListener('click', () => {
if(Object.keys(this.filtersRendered).length >= 10) {
diff --git a/src/components/sidebarLeft/tabs/editFolder.ts b/src/components/sidebarLeft/tabs/editFolder.ts
index 8c009925..4f2736c3 100644
--- a/src/components/sidebarLeft/tabs/editFolder.ts
+++ b/src/components/sidebarLeft/tabs/editFolder.ts
@@ -5,25 +5,25 @@ import { MyDialogFilter as DialogFilter } from "../../../lib/storages/filters";
import lottieLoader, { RLottiePlayer } from "../../../lib/lottieLoader";
import { parseMenuButtonsTo } from "../../misc";
import { ripple } from "../../ripple";
-import { SliderTab } from "../../slider";
+import { SliderTab, SliderSuperTab } from "../../slider";
import { toast } from "../../toast";
import appMessagesManager from "../../../lib/appManagers/appMessagesManager";
import { attachClickEvent } from "../../../helpers/dom";
import InputField from "../../inputField";
import RichTextProcessor from "../../../lib/richtextprocessor";
+import ButtonIcon from "../../buttonIcon";
+import ButtonMenuToggle from "../../buttonMenuToggle";
+import { ButtonMenuItemOptions } from "../../buttonMenu";
+import Button from "../../button";
const MAX_FOLDER_NAME_LENGTH = 12;
-export default class AppEditFolderTab implements SliderTab {
- public container: HTMLElement;
- private closeBtn: HTMLElement;
- private title: HTMLElement;
+export default class AppEditFolderTab extends SliderSuperTab {
private caption: HTMLElement;
private stickerContainer: HTMLElement;
private confirmBtn: HTMLElement;
private menuBtn: HTMLElement;
- private deleteFolderBtn: HTMLElement;
private nameInput: HTMLElement;
private nameInputField: InputField;
@@ -37,16 +37,37 @@ export default class AppEditFolderTab implements SliderTab {
private type: 'edit' | 'create';
+ constructor(appSidebarLeft: AppSidebarLeft) {
+ super(appSidebarLeft);
+ }
+
init() {
- this.container = document.querySelector('.edit-folder-container');
- this.closeBtn = this.container.querySelector('.sidebar-close-button');
- this.title = this.container.querySelector('.sidebar-header__title');
- this.caption = this.container.querySelector('.caption');
- this.stickerContainer = this.container.querySelector('.sticker-container');
+ this.container.classList.add('edit-folder-container');
+ this.caption = document.createElement('div');
+ this.caption.classList.add('caption');
+ this.caption.innerHTML = `Choose chats and types of chats that will
appear and never appear in this folder.`;
+ this.stickerContainer = document.createElement('div');
+ this.stickerContainer.classList.add('sticker-container');
+
+ this.confirmBtn = ButtonIcon('check1 btn-confirm hide');
+ const deleteFolderButton: ButtonMenuItemOptions = {
+ icon: 'delete danger',
+ text: 'Delete Folder',
+ onClick: () => {
+ deleteFolderButton.element.setAttribute('disabled', 'true');
+ appMessagesManager.filtersStorage.updateDialogFilter(this.filter, true).then(bool => {
+ if(bool) {
+ this.close();
+ }
+ }).finally(() => {
+ deleteFolderButton.element.removeAttribute('disabled');
+ });
+ }
+ };
+ this.menuBtn = ButtonMenuToggle({}, 'bottom-left', [deleteFolderButton]);
+ this.menuBtn.classList.add('hide');
- this.confirmBtn = this.container.querySelector('.btn-confirm');
- this.menuBtn = this.container.querySelector('.btn-menu-toggle');
- this.deleteFolderBtn = this.menuBtn.querySelector('.menu-delete');
+ this.header.append(this.confirmBtn, this.menuBtn);
const inputWrapper = document.createElement('div');
inputWrapper.classList.add('input-wrapper');
@@ -59,15 +80,85 @@ export default class AppEditFolderTab implements SliderTab {
inputWrapper.append(this.nameInputField.container);
- this.caption.parentElement.insertBefore(inputWrapper, this.caption.nextSibling);
+ const generateList = (className: string, h2Text: string, buttons: {icon: string, name?: string, withRipple?: true, text: string}[], to: any) => {
+ const container = document.createElement('div');
+ container.classList.add('folder-list', className);
+
+ const h2 = document.createElement('div');
+ h2.classList.add('sidebar-left-h2');
+ h2.innerHTML = h2Text;
+
+ const categories = document.createElement('div');
+ categories.classList.add('folder-categories');
+
+ buttons.forEach(o => {
+ const button = Button('folder-category-button btn-primary btn-transparent', {
+ icon: o.icon,
+ text: o.text,
+ noRipple: o.withRipple ? undefined : true,
+ rippleSquare: true
+ });
+
+ if(o.name) {
+ to[o.name] = button;
+ }
+
+ categories.append(button);
+ });
- this.include_peers = this.container.querySelector('.folder-list-included');
- this.exclude_peers = this.container.querySelector('.folder-list-excluded');
+ container.append(h2, categories);
+
+ return container;
+ };
+
+ this.include_peers = generateList('folder-list-included', 'Included chats', [{
+ icon: 'add blue',
+ text: 'Add Chats',
+ withRipple: true
+ }, {
+ text: 'Contacts',
+ icon: 'newprivate',
+ name: 'contacts'
+ }, {
+ text: 'Non-Contacts',
+ icon: 'noncontacts',
+ name: 'non_contacts'
+ }, {
+ text: 'Groups',
+ icon: 'group',
+ name: 'groups'
+ }, {
+ text: 'Channels',
+ icon: 'channel',
+ name: 'broadcasts'
+ }, {
+ text: 'Bots',
+ icon: 'bots',
+ name: 'bots'
+ }], this.flags);
+
+ this.exclude_peers = generateList('folder-list-excluded', 'Excluded chats', [{
+ icon: 'minus blue',
+ text: 'Remove Chats',
+ withRipple: true
+ }, {
+ text: 'Muted',
+ icon: 'mute',
+ name: 'exclude_muted'
+ }, {
+ text: 'Archived',
+ icon: 'archive',
+ name: 'exclude_archived'
+ }, {
+ text: 'Read',
+ icon: 'readchats',
+ name: 'exclude_read'
+ }], this.flags);
+
+ this.scrollable.append(this.stickerContainer, this.caption, inputWrapper, this.include_peers, this.exclude_peers);
const includedFlagsContainer = this.include_peers.querySelector('.folder-categories');
const excludedFlagsContainer = this.exclude_peers.querySelector('.folder-categories');
- parseMenuButtonsTo(this.flags, includedFlagsContainer.children);
- parseMenuButtonsTo(this.flags, excludedFlagsContainer.children);
includedFlagsContainer.firstElementChild.addEventListener('click', () => {
appSidebarLeft.includedChatsTab.open(this.filter, 'included');
@@ -87,17 +178,6 @@ export default class AppEditFolderTab implements SliderTab {
this.animation = player;
});
- attachClickEvent(this.deleteFolderBtn, () => {
- this.deleteFolderBtn.setAttribute('disabled', 'true');
- appMessagesManager.filtersStorage.updateDialogFilter(this.filter, true).then(bool => {
- if(bool) {
- appSidebarLeft.closeTab(AppSidebarLeft.SLIDERITEMSIDS.editFolder);
- }
- }).finally(() => {
- this.deleteFolderBtn.removeAttribute('disabled');
- });
- });
-
this.confirmBtn.addEventListener('click', () => {
if(this.nameInputField.input.classList.contains('error')) {
return;
@@ -127,7 +207,7 @@ export default class AppEditFolderTab implements SliderTab {
promise.then(bool => {
if(bool) {
- appSidebarLeft.closeTab(AppSidebarLeft.SLIDERITEMSIDS.editFolder);
+ this.close();
}
}).catch(err => {
if(err.type == 'DIALOG_FILTERS_TOO_MUCH') {
@@ -176,9 +256,9 @@ export default class AppEditFolderTab implements SliderTab {
private onEditOpen() {
this.caption.style.display = 'none';
- this.title.innerText = this.type == 'create' ? 'New Folder' : 'Edit Folder';
+ this.title.innerText = this.type === 'create' ? 'New Folder' : 'Edit Folder';
- if(this.type == 'edit') {
+ if(this.type === 'edit') {
this.menuBtn.classList.remove('hide');
this.confirmBtn.classList.add('hide');
}
@@ -187,8 +267,7 @@ export default class AppEditFolderTab implements SliderTab {
this.nameInputField.value = RichTextProcessor.wrapDraftText(filter.title);
for(const flag in this.flags) {
- // @ts-ignore
- this.flags[flag].style.display = !!filter.pFlags[flag] ? '' : 'none';
+ this.flags[flag as keyof AppEditFolderTab['flags']].style.display = !!filter.pFlags[flag as keyof AppEditFolderTab['flags']] ? '' : 'none';
}
(['include_peers', 'exclude_peers'] as ['include_peers', 'exclude_peers']).forEach(key => {
@@ -237,7 +316,7 @@ export default class AppEditFolderTab implements SliderTab {
}
editCheckForChange() {
- if(this.type == 'edit') {
+ if(this.type === 'edit') {
const changed = !deepEqual(this.originalFilter, this.filter);
this.confirmBtn.classList.toggle('hide', !changed);
this.menuBtn.classList.toggle('hide', changed);
@@ -258,9 +337,9 @@ export default class AppEditFolderTab implements SliderTab {
}
}
- open(filter?: DialogFilter) {
- appSidebarLeft.selectTab(AppSidebarLeft.SLIDERITEMSIDS.editFolder);
-
+ public open(filter?: DialogFilter) {
+ const ret = super.open();
+
if(filter === undefined) {
this.setFilter({
_: 'dialogFilter',
@@ -278,5 +357,7 @@ export default class AppEditFolderTab implements SliderTab {
this.type = 'edit';
this.onEditOpen();
}
+
+ return ret;
}
}
\ No newline at end of file
diff --git a/src/components/sidebarLeft/tabs/includedChats.ts b/src/components/sidebarLeft/tabs/includedChats.ts
index 0bfa5d11..a151bd67 100644
--- a/src/components/sidebarLeft/tabs/includedChats.ts
+++ b/src/components/sidebarLeft/tabs/includedChats.ts
@@ -1,4 +1,4 @@
-import { SliderTab } from "../../slider";
+import { SliderTab, SliderSuperTab } from "../../slider";
import AppSelectPeers from "../../appSelectPeers";
import appSidebarLeft, { AppSidebarLeft } from "..";
import appDialogsManager from "../../../lib/appManagers/appDialogsManager";
@@ -7,23 +7,27 @@ import appUsersManager from "../../../lib/appManagers/appUsersManager";
import { MyDialogFilter as DialogFilter } from "../../../lib/storages/filters";
import rootScope from "../../../lib/rootScope";
import { copy } from "../../../helpers/object";
+import ButtonIcon from "../../buttonIcon";
-export default class AppIncludedChatsTab implements SliderTab {
- public container: HTMLElement;
- private closeBtn: HTMLElement;
+export default class AppIncludedChatsTab extends SliderSuperTab {
private confirmBtn: HTMLElement;
- private title: HTMLElement;
private selector: AppSelectPeers;
private type: 'included' | 'excluded';
private filter: DialogFilter;
private originalFilter: DialogFilter;
+ constructor(appSidebarLeft: AppSidebarLeft) {
+ super(appSidebarLeft);
+ }
+
init() {
- this.container = document.querySelector('.included-chatlist-container');
- this.closeBtn = this.container.querySelector('.sidebar-close-button');
- this.confirmBtn = this.container.querySelector('.btn-confirm');
- this.title = this.container.querySelector('.sidebar-header__title');
+ this.content.remove();
+ this.container.classList.add('included-chatlist-container');
+ this.confirmBtn = ButtonIcon('check1 btn-confirm', {noRipple: true});
+ this.confirmBtn.style.display = 'none';
+
+ this.header.append(this.confirmBtn);
this.confirmBtn.addEventListener('click', () => {
const selected = this.selector.getSelected();
@@ -86,7 +90,7 @@ export default class AppIncludedChatsTab implements SliderTab {
//this.filter.pinned_peers = this.filter.pinned_peers.filter(peerId => this.filter.include_peers.includes(peerId));
appSidebarLeft.editFolderTab.setFilter(this.filter, false);
- appSidebarLeft.closeTab(AppSidebarLeft.SLIDERITEMSIDS.includedChats);
+ this.close();
});
}
@@ -150,26 +154,26 @@ export default class AppIncludedChatsTab implements SliderTab {
const categories = document.createElement('div');
categories.classList.add('folder-categories');
- let details: any;
+ let details: {[flag: string]: {ico: string, text: string}};
if(this.type == 'excluded') {
details = {
- exclude_muted: {ico: 'tgico-mute', text: 'Muted'},
- exclude_archived: {ico: 'tgico-archive', text: 'Archived'},
- exclude_read: {ico: 'tgico-readchats', text: 'Read'}
+ exclude_muted: {ico: 'mute', text: 'Muted'},
+ exclude_archived: {ico: 'archive', text: 'Archived'},
+ exclude_read: {ico: 'readchats', text: 'Read'}
};
} else {
details = {
- contacts: {ico: 'tgico-newprivate', text: 'Contacts'},
- non_contacts: {ico: 'tgico-noncontacts', text: 'Non-Contacts'},
- groups: {ico: 'tgico-group', text: 'Groups'},
- broadcasts: {ico: 'tgico-newchannel', text: 'Channels'},
- bots: {ico: 'tgico-bots', text: 'Bots'}
+ contacts: {ico: 'newprivate', text: 'Contacts'},
+ non_contacts: {ico: 'noncontacts', text: 'Non-Contacts'},
+ groups: {ico: 'group', text: 'Groups'},
+ broadcasts: {ico: 'newchannel', text: 'Channels'},
+ bots: {ico: 'bots', text: 'Bots'}
};
}
let html = '';
for(const key in details) {
- html += `