From 444ea1f446e7b0e873b242eb5dfcf8d318955474 Mon Sep 17 00:00:00 2001 From: Eduard Kuzmenko Date: Mon, 1 Feb 2021 05:07:44 +0200 Subject: [PATCH] Refactor checkbox --- src/components/button.ts | 6 +- src/components/chat/selection.ts | 5 +- src/components/checkbox.ts | 28 +++++++--- src/components/popups/createPoll.ts | 15 ++++- src/components/popups/newMedia.ts | 5 +- src/components/sidebarLeft/tabs/background.ts | 10 +++- .../sidebarLeft/tabs/generalSettings.ts | 56 ++++++++++++++++--- .../sidebarLeft/tabs/includedChats.ts | 4 +- src/components/sidebarLeft/tabs/settings.ts | 4 +- .../sidebarRight/tabs/sharedMedia.ts | 5 +- src/pages/pageSignIn.ts | 5 +- src/scss/partials/_button.scss | 2 +- src/scss/partials/_checkbox.scss | 6 ++ src/scss/partials/_leftSidebar.scss | 5 ++ 14 files changed, 123 insertions(+), 33 deletions(-) diff --git a/src/components/button.ts b/src/components/button.ts index e0cf12b5..3a3ba565 100644 --- a/src/components/button.ts +++ b/src/components/button.ts @@ -1,6 +1,6 @@ import { ripple } from "./ripple"; -const Button = (className: string, options: Partial<{noRipple: true, onlyMobile: true, icon: string, rippleSquare: true, text: string}> = {}) => { +const Button = (className: string, options: Partial<{noRipple: true, onlyMobile: true, icon: string, rippleSquare: true, text: string, disabled: boolean}> = {}) => { const button = document.createElement('button'); button.className = className + (options.icon ? ' tgico-' + options.icon : ''); @@ -16,6 +16,10 @@ const Button = (className: string, options: Partial<{noRipple: true, onlyMobile: button.classList.add('only-handhelds'); } + if(options.disabled) { + button.disabled = true; + } + if(options.text) { button.append(options.text); } diff --git a/src/components/chat/selection.ts b/src/components/chat/selection.ts index e2ea0ab6..adc3489e 100644 --- a/src/components/chat/selection.ts +++ b/src/components/chat/selection.ts @@ -161,7 +161,10 @@ export default class ChatSelection { if(show) { if(hasCheckbox) return; - const checkboxField = CheckboxField('', bubble.dataset.mid, true); + const checkboxField = CheckboxField({ + name: bubble.dataset.mid, + round: true + }); checkboxField.label.classList.add('bubble-select-checkbox'); // * if it is a render of new message diff --git a/src/components/checkbox.ts b/src/components/checkbox.ts index 99e52ad5..63afb795 100644 --- a/src/components/checkbox.ts +++ b/src/components/checkbox.ts @@ -1,37 +1,47 @@ import appStateManager from "../lib/appManagers/appStateManager"; import { getDeepProperty } from "../helpers/object"; -const CheckboxField = (text?: string, name?: string, round = false, stateKey?: string) => { +const CheckboxField = (options: { + text?: string, + name?: string, + round?: boolean, + stateKey?: string, + disabled?: boolean +} = {}) => { const label = document.createElement('label'); label.classList.add('checkbox-field'); - if(round) { + if(options.round) { label.classList.add('checkbox-field-round'); } + if(options.disabled) { + label.classList.add('checkbox-disabled'); + } + const input = document.createElement('input'); input.type = 'checkbox'; - if(name) { + if(options.name) { input.id = 'input-' + name; } - if(stateKey) { + if(options.stateKey) { appStateManager.getState().then(state => { - input.checked = getDeepProperty(state, stateKey); + input.checked = getDeepProperty(state, options.stateKey); }); input.addEventListener('change', () => { - appStateManager.setByKey(stateKey, input.checked); + appStateManager.setByKey(options.stateKey, input.checked); }); } let span: HTMLSpanElement; - if(text) { + if(options.text) { span = document.createElement('span'); span.classList.add('checkbox-caption'); - if(text) { - span.innerText = text; + if(options.text) { + span.innerText = options.text; } } else { label.classList.add('checkbox-without-caption'); diff --git a/src/components/popups/createPoll.ts b/src/components/popups/createPoll.ts index 37c9c44a..03106362 100644 --- a/src/components/popups/createPoll.ts +++ b/src/components/popups/createPoll.ts @@ -77,13 +77,22 @@ export default class PopupCreatePoll extends PopupElement { settingsCaption.innerText = 'Settings'; if(!this.chat.appPeersManager.isBroadcast(this.chat.peerId)) { - this.anonymousCheckboxField = CheckboxField('Anonymous Voting', 'anonymous'); + this.anonymousCheckboxField = CheckboxField({ + text: 'Anonymous Voting', + name: 'anonymous' + }); this.anonymousCheckboxField.input.checked = true; dd.append(this.anonymousCheckboxField.label); } - this.multipleCheckboxField = CheckboxField('Multiple Answers', 'multiple'); - this.quizCheckboxField = CheckboxField('Quiz Mode', 'quiz'); + this.multipleCheckboxField = CheckboxField({ + text: 'Multiple Answers', + name: 'multiple' + }); + this.quizCheckboxField = CheckboxField({ + text: 'Quiz Mode', + name: 'quiz' + }); this.multipleCheckboxField.input.addEventListener('change', () => { const checked = this.multipleCheckboxField.input.checked; diff --git a/src/components/popups/newMedia.ts b/src/components/popups/newMedia.ts index f671604f..31bd950c 100644 --- a/src/components/popups/newMedia.ts +++ b/src/components/popups/newMedia.ts @@ -88,7 +88,10 @@ export default class PopupNewMedia extends PopupElement { this.container.append(scrollable.container); if(files.length > 1) { - this.groupCheckboxField = CheckboxField('Group items', 'group-items'); + this.groupCheckboxField = CheckboxField({ + text: 'Group items', + name: 'group-items' + }); this.container.append(this.groupCheckboxField.label, this.inputField.container); this.groupCheckboxField.input.checked = true; diff --git a/src/components/sidebarLeft/tabs/background.ts b/src/components/sidebarLeft/tabs/background.ts index 892eb692..48b0ca20 100644 --- a/src/components/sidebarLeft/tabs/background.ts +++ b/src/components/sidebarLeft/tabs/background.ts @@ -27,10 +27,14 @@ export default class AppBackgroundTab extends SliderSuperTab { { const container = generateSection(this.scrollable); - const uploadButton = Button('btn-primary btn-transparent', {icon: 'cameraadd', text: 'Upload Wallpaper'}); - const colorButton = Button('btn-primary btn-transparent', {icon: 'colorize', text: 'Set a Color'}); + const uploadButton = Button('btn-primary btn-transparent', {icon: 'cameraadd', text: 'Upload Wallpaper', disabled: true}); + const colorButton = Button('btn-primary btn-transparent', {icon: 'colorize', text: 'Set a Color', disabled: true}); - const blurCheckboxField = CheckboxField('Blur Wallpaper Image', 'blur', false, 'settings.background.blur'); + const blurCheckboxField = CheckboxField({ + text: 'Blur Wallpaper Image', + name: 'blur', + stateKey: 'settings.background.blur' + }); blurCheckboxField.input.addEventListener('change', () => { const active = grid.querySelector('.active') as HTMLElement; if(!active) return; diff --git a/src/components/sidebarLeft/tabs/generalSettings.ts b/src/components/sidebarLeft/tabs/generalSettings.ts index e65e0947..fb4d1a67 100644 --- a/src/components/sidebarLeft/tabs/generalSettings.ts +++ b/src/components/sidebarLeft/tabs/generalSettings.ts @@ -78,7 +78,11 @@ export default class AppGeneralSettingsTab extends SliderSuperTab { new AppBackgroundTab(this.slider).open(); }); - const animationsCheckboxField = CheckboxField('Enable Animations', 'animations', false, 'settings.animationsEnabled'); + const animationsCheckboxField = CheckboxField({ + text: 'Enable Animations', + name: 'animations', + stateKey: 'settings.animationsEnabled' + }); container.append(range.container, chatBackgroundButton, animationsCheckboxField.label); } @@ -104,20 +108,46 @@ export default class AppGeneralSettingsTab extends SliderSuperTab { { const container = section('Auto-Download Media'); + container.classList.add('sidebar-left-section-disabled'); - const contactsCheckboxField = CheckboxField('Contacts', 'contacts', false, 'settings.autoDownload.contacts'); - const privateCheckboxField = CheckboxField('Private Chats', 'private', false, 'settings.autoDownload.private'); - const groupsCheckboxField = CheckboxField('Group Chats', 'groups', false, 'settings.autoDownload.groups'); - const channelsCheckboxField = CheckboxField('Channels', 'channels', false, 'settings.autoDownload.channels'); + const contactsCheckboxField = CheckboxField({ + text: 'Contacts', + name: 'contacts', + stateKey: 'settings.autoDownload.contacts' + }); + const privateCheckboxField = CheckboxField({ + text: 'Private Chats', + name: 'private', + stateKey: 'settings.autoDownload.private' + }); + const groupsCheckboxField = CheckboxField({ + text: 'Group Chats', + name: 'groups', + stateKey: 'settings.autoDownload.groups' + }); + const channelsCheckboxField = CheckboxField({ + text: 'Channels', + name: 'channels', + stateKey: 'settings.autoDownload.channels' + }); container.append(contactsCheckboxField.label, privateCheckboxField.label, groupsCheckboxField.label, channelsCheckboxField.label); } { const container = section('Auto-Play Media'); + container.classList.add('sidebar-left-section-disabled'); - const gifsCheckboxField = CheckboxField('GIFs', 'gifs', false, 'settings.autoPlay.gifs'); - const videosCheckboxField = CheckboxField('Videos', 'videos', false, 'settings.autoPlay.videos'); + const gifsCheckboxField = CheckboxField({ + text: 'GIFs', + name: 'gifs', + stateKey: 'settings.autoPlay.gifs' + }); + const videosCheckboxField = CheckboxField({ + text: 'Videos', + name: 'videos', + stateKey: 'settings.autoPlay.videos' + }); container.append(gifsCheckboxField.label, videosCheckboxField.label); } @@ -125,8 +155,16 @@ export default class AppGeneralSettingsTab extends SliderSuperTab { { const container = section('Stickers'); - const suggestCheckboxField = CheckboxField('Suggest Stickers by Emoji', 'suggest', false, 'settings.stickers.suggest'); - const loopCheckboxField = CheckboxField('Loop Animated Stickers', 'loop', false, 'settings.stickers.loop'); + const suggestCheckboxField = CheckboxField({ + text: 'Suggest Stickers by Emoji', + name: 'suggest', + stateKey: 'settings.stickers.suggest' + }); + const loopCheckboxField = CheckboxField({ + text: 'Loop Animated Stickers', + name: 'loop', + stateKey: 'settings.stickers.loop' + }); container.append(suggestCheckboxField.label, loopCheckboxField.label); } diff --git a/src/components/sidebarLeft/tabs/includedChats.ts b/src/components/sidebarLeft/tabs/includedChats.ts index c024db60..7420c3ae 100644 --- a/src/components/sidebarLeft/tabs/includedChats.ts +++ b/src/components/sidebarLeft/tabs/includedChats.ts @@ -98,7 +98,9 @@ export default class AppIncludedChatsTab extends SliderSuperTab { } checkbox(selected?: boolean) { - const checkboxField = CheckboxField('', '', true); + const checkboxField = CheckboxField({ + round: true + }); if(selected) { checkboxField.input.checked = selected; } diff --git a/src/components/sidebarLeft/tabs/settings.ts b/src/components/sidebarLeft/tabs/settings.ts index e865e1ba..6d5cadcb 100644 --- a/src/components/sidebarLeft/tabs/settings.ts +++ b/src/components/sidebarLeft/tabs/settings.ts @@ -98,9 +98,9 @@ export default class AppSettingsTab extends SliderSuperTab { buttonsDiv.append(this.buttons.edit = Button(className, {icon: 'edit', rippleSquare: true, text: 'Edit Profile'})); buttonsDiv.append(this.buttons.folders = Button(className, {icon: 'folder', rippleSquare: true, text: 'Chat Folders'})); buttonsDiv.append(this.buttons.general = Button(className, {icon: 'settings', rippleSquare: true, text: 'General Settings'})); - buttonsDiv.append(this.buttons.notifications = Button(className + ' btn-disabled', {icon: 'unmute', rippleSquare: true, text: 'Notifications'})); + buttonsDiv.append(this.buttons.notifications = Button(className, {icon: 'unmute', rippleSquare: true, text: 'Notifications', disabled: true})); buttonsDiv.append(this.buttons.privacy = Button(className, {icon: 'lock', rippleSquare: true, text: 'Privacy and Security'})); - buttonsDiv.append(this.buttons.language = Button(className + ' btn-disabled', {icon: 'language', rippleSquare: true, text: 'Language'})); + buttonsDiv.append(this.buttons.language = Button(className, {icon: 'language', rippleSquare: true, text: 'Language', disabled: true})); this.scrollable.append(this.avatarElem, this.nameDiv, this.phoneDiv, buttonsDiv); this.scrollable.container.classList.add('profile-content-wrapper'); diff --git a/src/components/sidebarRight/tabs/sharedMedia.ts b/src/components/sidebarRight/tabs/sharedMedia.ts index d4c3956a..858b59b6 100644 --- a/src/components/sidebarRight/tabs/sharedMedia.ts +++ b/src/components/sidebarRight/tabs/sharedMedia.ts @@ -77,7 +77,10 @@ export default class AppSharedMediaTab implements SliderTab { notificationsStatus: this.profileContentEl.querySelector('.profile-row-notifications > p') }; - const checkboxField = CheckboxField('Notifications', 'notifications'); + const checkboxField = CheckboxField({ + text: 'Notifications', + name: 'notifications' + }); this.profileElements.notificationsCheckbox = checkboxField.input; this.profileElements.notificationsCheckbox.checked = true; this.profileElements.notificationsRow.prepend(checkboxField.label); diff --git a/src/pages/pageSignIn.ts b/src/pages/pageSignIn.ts index daeeb3cb..9542b2b6 100644 --- a/src/pages/pageSignIn.ts +++ b/src/pages/pageSignIn.ts @@ -290,7 +290,10 @@ let onFirstMount = () => { this.removeAttribute('readonly'); // fix autocomplete });*/ - const signedCheckboxField = CheckboxField('Keep me signed in', 'keepSession'); + const signedCheckboxField = CheckboxField({ + text: 'Keep me signed in', + name: 'keepSession' + }); signedCheckboxField.input.checked = true; btnNext = Button('btn-primary', {text: 'NEXT'}); diff --git a/src/scss/partials/_button.scss b/src/scss/partials/_button.scss index 9ef63d43..c3d7dc7c 100644 --- a/src/scss/partials/_button.scss +++ b/src/scss/partials/_button.scss @@ -327,6 +327,6 @@ color: #707579 !important; &:before { - color: #707579 !important; + color: inherit !important; } } \ No newline at end of file diff --git a/src/scss/partials/_checkbox.scss b/src/scss/partials/_checkbox.scss index 5e23e623..5ba17afb 100644 --- a/src/scss/partials/_checkbox.scss +++ b/src/scss/partials/_checkbox.scss @@ -7,6 +7,12 @@ cursor: pointer; min-width: var(--size); min-height: var(--size); + transition: .2s opacity; + + &.checkbox-disabled { + pointer-events: none !important; + opacity: .25; + } @include respond-to(handhelds) { margin-bottom: 27px; diff --git a/src/scss/partials/_leftSidebar.scss b/src/scss/partials/_leftSidebar.scss index f97a8931..b520fa36 100644 --- a/src/scss/partials/_leftSidebar.scss +++ b/src/scss/partials/_leftSidebar.scss @@ -891,6 +891,11 @@ &-caption { padding: 0 .875rem; } + + &-disabled { + pointer-events: none !important; + opacity: .25; + } } &-h2 {