From c5570cd7af8568760e1f852fbeeee1ecea485a42 Mon Sep 17 00:00:00 2001 From: Eduard Kuzmenko Date: Wed, 23 Dec 2020 05:40:30 +0200 Subject: [PATCH] Restrict selecting service messages Fix returning by chat back button --- src/components/chat/audio.ts | 6 +++--- src/components/chat/bubbles.ts | 2 +- src/components/chat/pinnedContainer.ts | 6 +++--- src/components/chat/selection.ts | 16 ++++++++++++---- src/components/preloader.ts | 4 ++-- src/components/slider.ts | 3 ++- src/lib/appManagers/appImManager.ts | 3 ++- 7 files changed, 25 insertions(+), 15 deletions(-) diff --git a/src/components/chat/audio.ts b/src/components/chat/audio.ts index e3070142..d7b1c9f5 100644 --- a/src/components/chat/audio.ts +++ b/src/components/chat/audio.ts @@ -3,7 +3,7 @@ import type { AppPeersManager } from "../../lib/appManagers/appPeersManager"; import type ChatTopbar from "./topbar"; import { RichTextProcessor } from "../../lib/richtextprocessor"; import rootScope from "../../lib/rootScope"; -import { cancelEvent } from "../../helpers/dom"; +import { attachClickEvent, cancelEvent } from "../../helpers/dom"; import appMediaPlaybackController from "../appMediaPlaybackController"; import DivAndCaption from "../divAndCaption"; import { formatDate } from "../wrappers"; @@ -27,10 +27,10 @@ export default class ChatAudio extends PinnedContainer { this.toggleEl = document.createElement('button'); this.toggleEl.classList.add('pinned-audio-ico', 'tgico', 'btn-icon'); - this.topbar.listenerSetter.add(this.toggleEl, 'click', (e) => { + attachClickEvent(this.toggleEl, (e) => { cancelEvent(e); appMediaPlaybackController.toggle(); - }); + }, {listenerSetter: this.topbar.listenerSetter}); this.wrapper.prepend(this.toggleEl); diff --git a/src/components/chat/bubbles.ts b/src/components/chat/bubbles.ts index 6fa16a76..4d9c09a6 100644 --- a/src/components/chat/bubbles.ts +++ b/src/components/chat/bubbles.ts @@ -1546,7 +1546,7 @@ export default class ChatBubbles { bubble.dataset.mid = message.mid; bubble.dataset.timestamp = message.date; - if(this.chat.selection.isSelecting) { + if(this.chat.selection.isSelecting && message._ !== 'messageService') { this.chat.selection.toggleBubbleCheckbox(bubble, true); } diff --git a/src/components/chat/pinnedContainer.ts b/src/components/chat/pinnedContainer.ts index 5714df51..05091278 100644 --- a/src/components/chat/pinnedContainer.ts +++ b/src/components/chat/pinnedContainer.ts @@ -1,7 +1,7 @@ import type Chat from "./chat"; import type ChatTopbar from "./topbar"; import mediaSizes from "../../helpers/mediaSizes"; -import { cancelEvent } from "../../helpers/dom"; +import { attachClickEvent, cancelEvent } from "../../helpers/dom"; import DivAndCaption from "../divAndCaption"; import { ripple } from "../ripple"; import ListenerSetter from "../../helpers/listenerSetter"; @@ -41,7 +41,7 @@ export default class PinnedContainer { divAndCaption.container.append(this.close, this.wrapper); - this.listenerSetter.add(this.close, 'click', (e) => { + attachClickEvent(this.close, (e) => { cancelEvent(e); ((onClose ? onClose() : null) || Promise.resolve(true)).then(needClose => { @@ -49,7 +49,7 @@ export default class PinnedContainer { this.toggle(true); } }); - }); + }, {listenerSetter: this.listenerSetter}); } public toggle(hide?: boolean) { diff --git a/src/components/chat/selection.ts b/src/components/chat/selection.ts index 6148843c..ca1ac1b2 100644 --- a/src/components/chat/selection.ts +++ b/src/components/chat/selection.ts @@ -154,6 +154,8 @@ export default class ChatSelection { } public toggleBubbleCheckbox(bubble: HTMLElement, show: boolean) { + if(!this.canSelectBubble(bubble)) return; + const hasCheckbox = !!this.getCheckboxInputFromBubble(bubble); const isGrouped = bubble.classList.contains('is-grouped'); if(show) { @@ -183,7 +185,7 @@ export default class ChatSelection { } } - public getCheckboxInputFromBubble(bubble: HTMLElement): HTMLInputElement { + private getCheckboxInputFromBubble(bubble: HTMLElement): HTMLInputElement { /* let perf = performance.now(); let checkbox = bubble.firstElementChild.tagName == 'LABEL' && bubble.firstElementChild.firstElementChild as HTMLInputElement; console.log('getCheckboxInputFromBubble firstElementChild time:', performance.now() - perf); @@ -204,7 +206,7 @@ export default class ChatSelection { bubble.firstElementChild.tagName == 'LABEL' && bubble.firstElementChild.firstElementChild as HTMLInputElement; } - public updateForwardContainer(forceSelection = false) { + private updateForwardContainer(forceSelection = false) { if(!this.selectedMids.size && !forceSelection) return; this.selectionCountEl.innerText = this.selectedMids.size + ' Message' + (this.selectedMids.size == 1 ? '' : 's'); @@ -373,18 +375,20 @@ export default class ChatSelection { SetTransition(bubble, 'is-selected', isSelected, 200); } - public isGroupedBubbleSelected(bubble: HTMLElement) { + private isGroupedBubbleSelected(bubble: HTMLElement) { const groupedCheckboxInput = this.getCheckboxInputFromBubble(bubble); return groupedCheckboxInput?.checked; } - public isGroupedMidsSelected(mid: number) { + private isGroupedMidsSelected(mid: number) { const mids = this.chat.getMidsByMid(mid); const selectedMids = mids.filter(mid => this.selectedMids.has(mid)); return mids.length == selectedMids.length; } public toggleByBubble = (bubble: HTMLElement) => { + if(!this.canSelectBubble(bubble)) return; + const mid = +bubble.dataset.mid; const isGrouped = bubble.classList.contains('is-grouped'); @@ -438,4 +442,8 @@ export default class ChatSelection { this.updateBubbleSelection(bubble, !found); }; + + private canSelectBubble(bubble: HTMLElement) { + return !bubble.classList.contains('service'); + } } \ No newline at end of file diff --git a/src/components/preloader.ts b/src/components/preloader.ts index 6ecaa757..209ea75c 100644 --- a/src/components/preloader.ts +++ b/src/components/preloader.ts @@ -1,4 +1,4 @@ -import { isInDOM, cancelEvent } from "../helpers/dom"; +import { isInDOM, cancelEvent, attachClickEvent } from "../helpers/dom"; import { CancellablePromise } from "../helpers/cancellablePromise"; export default class ProgressivePreloader { @@ -42,7 +42,7 @@ export default class ProgressivePreloader { } if(this.cancelable) { - this.preloader.addEventListener('click', (e) => { + attachClickEvent(this.preloader, (e) => { cancelEvent(e); if(this.promise && this.promise.cancel) { diff --git a/src/components/slider.ts b/src/components/slider.ts index 63625396..e26be753 100644 --- a/src/components/slider.ts +++ b/src/components/slider.ts @@ -1,3 +1,4 @@ +import { attachClickEvent } from "../helpers/dom"; import { horizontalMenu } from "./horizontalMenu"; export interface SliderTab { @@ -41,7 +42,7 @@ export default class SidebarSlider { } Array.from(this.sidebarEl.querySelectorAll('.sidebar-close-button') as any as HTMLElement[]).forEach(el => { - el.addEventListener('click', () => this.closeTab()); + attachClickEvent(el, () => this.closeTab()); }); } diff --git a/src/lib/appManagers/appImManager.ts b/src/lib/appManagers/appImManager.ts index 1c40f2c7..cd2d6d1a 100644 --- a/src/lib/appManagers/appImManager.ts +++ b/src/lib/appManagers/appImManager.ts @@ -496,11 +496,12 @@ export class AppImManager { if(chatIndex > 0) { this.spliceChats(chatIndex); return; - } else if(mediaSizes.activeScreen == ScreenSize.medium) { // * floating sidebar case + } else if(mediaSizes.activeScreen === ScreenSize.medium) { // * floating sidebar case const isNowOpen = document.body.classList.toggle(LEFT_COLUMN_ACTIVE_CLASSNAME); if(isNowOpen && document.body.classList.contains(RIGHT_COLUMN_ACTIVE_CLASSNAME)) { appSidebarRight.toggleSidebar(false, false); + this.selectTab(0); this.hideRightSidebar = isNowOpen; } else if(this.hideRightSidebar) { appSidebarRight.toggleSidebar(true);