diff --git a/src/components/appNavigationController.ts b/src/components/appNavigationController.ts index fd85a2f7..4b2f2b31 100644 --- a/src/components/appNavigationController.ts +++ b/src/components/appNavigationController.ts @@ -106,23 +106,23 @@ export class AppNavigationController { this.manual = false; } - public back(type?: NavigationItem['type']) { - if(type) { - let item: NavigationItem; - let i = this.navigations.length - 1; - for(; i >= 0; --i) { - const _item = this.navigations[i]; - if(_item.type === type) { - item = _item; - break; - } + public findItemByType(type: NavigationItem['type']) { + for(let i = this.navigations.length - 1; i >= 0; --i) { + const item = this.navigations[i]; + if(item.type === type) { + return {item, index: i}; } + } + } - if(item) { + public back(type?: NavigationItem['type']) { + if(type) { + const ret = this.findItemByType(type); + if(ret) { this.manual = true; - if(i !== (this.navigations.length - 1)) { - this.navigations.splice(i, 1); - this.handleItem(item); + if(ret.index !== (this.navigations.length - 1)) { + this.navigations.splice(ret.index, 1); + this.handleItem(ret.item); return; } } diff --git a/src/components/chat/bubbleGroups.ts b/src/components/chat/bubbleGroups.ts index 8ec1fe7a..5a79d8c7 100644 --- a/src/components/chat/bubbleGroups.ts +++ b/src/components/chat/bubbleGroups.ts @@ -1,7 +1,7 @@ import rootScope from "../../lib/rootScope"; //import { generatePathData } from "../../helpers/dom"; import { MyMessage } from "../../lib/appManagers/appMessagesManager"; -import Chat from "./chat"; +import type Chat from "./chat"; type Group = {bubble: HTMLElement, mid: number, timestamp: number}[]; type BubbleGroup = {timestamp: number, fromId: number, mid: number, group: Group}; @@ -18,13 +18,17 @@ export default class BubbleGroups { removeBubble(bubble: HTMLElement) { const details = this.detailsMap.get(bubble); - if(details && details.group.length) { - details.group.findAndSplice(d => d.bubble === bubble); - if(!details.group.length) { - this.groups.findAndSplice(g => g === details.group); - } else { - this.updateGroup(details.group); + if(details) { + if(details.group.length) { + details.group.findAndSplice(d => d.bubble === bubble); + if(!details.group.length) { + this.groups.findAndSplice(g => g === details.group); + } else { + this.updateGroup(details.group); + } } + + this.detailsMap.delete(bubble); } } @@ -227,4 +231,4 @@ export default class BubbleGroups { } this.updateRAFs.clear(); */ } -} \ No newline at end of file +} diff --git a/src/components/chat/chat.ts b/src/components/chat/chat.ts index 86846d80..89e8406c 100644 --- a/src/components/chat/chat.ts +++ b/src/components/chat/chat.ts @@ -201,7 +201,7 @@ export default class Chat extends EventListenerBase<{ // set new if(!samePeer) { if(appSidebarRight.historyTabIds[appSidebarRight.historyTabIds.length - 1] === AppSidebarRight.SLIDERITEMSIDS.search) { - appSidebarRight.closeTab(AppSidebarRight.SLIDERITEMSIDS.search); + appSidebarRight.onCloseBtnClick(); } appSidebarRight.sharedMediaTab.setPeer(peerId, this.threadId); diff --git a/src/components/chat/topbar.ts b/src/components/chat/topbar.ts index 2623c7c2..3e937336 100644 --- a/src/components/chat/topbar.ts +++ b/src/components/chat/topbar.ts @@ -19,6 +19,7 @@ import ListenerSetter from "../../helpers/listenerSetter"; import appStateManager from "../../lib/appManagers/appStateManager"; import PopupDeleteDialog from "../popups/deleteDialog"; import appNavigationController from "../appNavigationController"; +import { LEFT_COLUMN_ACTIVE_CLASSNAME } from "../sidebarLeft"; export default class ChatTopbar { container: HTMLDivElement; @@ -136,16 +137,38 @@ export default class ChatTopbar { this.chat.appImManager.setInnerPeer(peerId, mid); } } else { - this.appSidebarRight.toggleSidebar(true); + if(mediaSizes.activeScreen === ScreenSize.medium && document.body.classList.contains(LEFT_COLUMN_ACTIVE_CLASSNAME)) { + onBtnBackClick(); + } else { + this.appSidebarRight.toggleSidebar(true); + } } }, {listenerSetter: this.listenerSetter}); - attachClickEvent(this.btnBack, (e) => { - cancelEvent(e); - /* this.chat.appImManager.setPeer(0); - blurActiveElement(); */ - appNavigationController.back('chat'); - }, {listenerSetter: this.listenerSetter}); + const onBtnBackClick = (e?: Event) => { + if(e) { + cancelEvent(e); + } + + //const item = appNavigationController.findItemByType('chat'); + // * return manually to chat by arrow, since can't get back to + if(mediaSizes.activeScreen === ScreenSize.medium && document.body.classList.contains(LEFT_COLUMN_ACTIVE_CLASSNAME)) { + this.chat.appImManager.setPeer(this.peerId); + } else { + const isFirstChat = this.chat.appImManager.chats.indexOf(this.chat) === 0; + appNavigationController.back(isFirstChat ? 'im' : 'chat'); + return; + + if(mediaSizes.activeScreen === ScreenSize.medium && !appNavigationController.findItemByType('chat')) { + this.chat.appImManager.setPeer(0); + blurActiveElement(); + } else { + appNavigationController.back('chat'); + } + } + }; + + attachClickEvent(this.btnBack, onBtnBackClick, {listenerSetter: this.listenerSetter}); } public constructUtils() { diff --git a/src/components/sidebarLeft/index.ts b/src/components/sidebarLeft/index.ts index b06671ce..2d4b1286 100644 --- a/src/components/sidebarLeft/index.ts +++ b/src/components/sidebarLeft/index.ts @@ -24,6 +24,8 @@ import AppContactsTab from "./tabs/contacts"; import AppArchivedTab from "./tabs/archivedTab"; import AppAddMembersTab from "./tabs/addMembers"; +export const LEFT_COLUMN_ACTIVE_CLASSNAME = 'is-left-column-shown'; + export class AppSidebarLeft extends SidebarSlider { private toolsBtn: HTMLButtonElement; private backBtn: HTMLButtonElement; diff --git a/src/components/sidebarRight/index.ts b/src/components/sidebarRight/index.ts index eee758dc..5303fe96 100644 --- a/src/components/sidebarRight/index.ts +++ b/src/components/sidebarRight/index.ts @@ -58,12 +58,12 @@ export class AppSidebarRight extends SidebarSlider { }); } - public onCloseTab(id: number, animate: boolean) { + public onCloseTab(id: number, animate: boolean, isNavigation?: boolean) { if(!this.historyTabIds.length) { this.toggleSidebar(false, animate); } - super.onCloseTab(id, animate); + super.onCloseTab(id, animate, isNavigation); } /* public selectTab(id: number) { diff --git a/src/components/sidebarRight/tabs/gifs.ts b/src/components/sidebarRight/tabs/gifs.ts index 5449513b..8bfa7bc8 100644 --- a/src/components/sidebarRight/tabs/gifs.ts +++ b/src/components/sidebarRight/tabs/gifs.ts @@ -52,7 +52,7 @@ export default class AppGifsTab implements SliderTab { const fileId = target.dataset.docId; if(appImManager.chat.input.sendMessageWithDocument(fileId)) { if(mediaSizes.isMobile) { - appSidebarRight.closeTab(AppSidebarRight.SLIDERITEMSIDS.gifs); + appSidebarRight.onCloseBtnClick(); } } else { console.warn('got no doc by id:', fileId); diff --git a/src/components/sidebarRight/tabs/pollResults.ts b/src/components/sidebarRight/tabs/pollResults.ts index 518d8866..91b65a96 100644 --- a/src/components/sidebarRight/tabs/pollResults.ts +++ b/src/components/sidebarRight/tabs/pollResults.ts @@ -71,7 +71,7 @@ export default class AppPollResultsTab implements SliderTab { list.classList.add('poll-results-voters'); appDialogsManager.setListClickListener(list, () => { - appSidebarRight.closeTab(AppSidebarRight.SLIDERITEMSIDS.pollResults); + appSidebarRight.onCloseBtnClick(); }, undefined, true); list.style.minHeight = Math.min(result.voters, 4) * 50 + 'px'; diff --git a/src/components/sidebarRight/tabs/sharedMedia.ts b/src/components/sidebarRight/tabs/sharedMedia.ts index b0f09c1d..376b402e 100644 --- a/src/components/sidebarRight/tabs/sharedMedia.ts +++ b/src/components/sidebarRight/tabs/sharedMedia.ts @@ -115,7 +115,7 @@ export default class AppSharedMediaTab implements SliderTab { transition(0); closeIcon.classList.remove('state-back'); } else if(!this.scroll.isHeavyAnimationInProgress) { - appSidebarRight.closeTab(); + appSidebarRight.onCloseBtnClick(); } }); @@ -369,4 +369,4 @@ export default class AppSharedMediaTab implements SliderTab { onOpenAfterTimeout() { this.scroll.onScroll(); } -} \ No newline at end of file +} diff --git a/src/components/slider.ts b/src/components/slider.ts index 62f5b4e9..12c4bbea 100644 --- a/src/components/slider.ts +++ b/src/components/slider.ts @@ -44,20 +44,20 @@ export default class SidebarSlider { }); } - private onCloseBtnClick = () => { + public onCloseBtnClick = () => { appNavigationController.back(this.navigationType); // this.closeTab(); }; - public closeTab = (id?: number | SliderSuperTab, animate?: boolean) => { + public closeTab = (id?: number | SliderSuperTab, animate?: boolean, isNavigation?: boolean) => { if(id !== undefined && this.historyTabIds[this.historyTabIds.length - 1] !== id) { return false; } //console.log('sidebar-close-button click:', this.historyTabIDs); const closingId = this.historyTabIds.pop(); // pop current - this.onCloseTab(closingId, animate); - + this.onCloseTab(closingId, animate, isNavigation); + const tab = this.historyTabIds[this.historyTabIds.length - 1]; this._selectTab(tab !== undefined ? (tab instanceof SliderSuperTab ? tab.container : tab) : (this.canHideFirst ? -1 : 0), animate); return true; @@ -89,7 +89,7 @@ export default class SidebarSlider { appNavigationController.pushItem({ type: this.navigationType, onPop: (canAnimate) => { - this.closeTab(undefined, canAnimate); + this.closeTab(undefined, canAnimate, true); return true; } }); @@ -117,7 +117,11 @@ export default class SidebarSlider { } } - public onCloseTab(id: number | SliderSuperTab, animate: boolean) { + protected onCloseTab(id: number | SliderSuperTab, animate: boolean, isNavigation?: boolean) { + if(!isNavigation) { + appNavigationController.removeByType(this.navigationType, true); + } + const tab: SliderTab = id instanceof SliderSuperTab ? id : this.tabs.get(id); if(tab) { if(tab.onClose) { diff --git a/src/lib/appManagers/appImManager.ts b/src/lib/appManagers/appImManager.ts index 6cc056e4..721be492 100644 --- a/src/lib/appManagers/appImManager.ts +++ b/src/lib/appManagers/appImManager.ts @@ -1,6 +1,6 @@ //import apiManager from '../mtproto/apiManager'; import animationIntersector from '../../components/animationIntersector'; -import appSidebarLeft from "../../components/sidebarLeft"; +import appSidebarLeft, { LEFT_COLUMN_ACTIVE_CLASSNAME } from "../../components/sidebarLeft"; import appSidebarRight, { AppSidebarRight, RIGHT_COLUMN_ACTIVE_CLASSNAME } from '../../components/sidebarRight'; import mediaSizes, { ScreenSize } from '../../helpers/mediaSizes'; import { logger, LogLevels } from "../logger"; @@ -41,8 +41,6 @@ import appNavigationController from '../../components/appNavigationController'; appSidebarLeft; // just to include -const LEFT_COLUMN_ACTIVE_CLASSNAME = 'is-left-column-shown'; - export const CHAT_ANIMATION_GROUP = 'chat'; const FOCUS_EVENT_NAME = isTouchSupported ? 'touchstart' : 'mousemove'; @@ -59,7 +57,7 @@ export class AppImManager { public tabId = -1; - private chats: Chat[] = []; + public chats: Chat[] = []; private prevTab: HTMLElement; private chatsSelectTabDebounced: () => void; @@ -86,7 +84,7 @@ export class AppImManager { this.offline = rootScope.idle.isIDLE = true; this.updateStatus(); clearInterval(this.updateStatusInterval); - rootScope.broadcast('idle', true); + rootScope.broadcast('idle', rootScope.idle.isIDLE); window.addEventListener('focus', () => { this.offline = rootScope.idle.isIDLE = false; @@ -96,7 +94,7 @@ export class AppImManager { // в обратном порядке animationIntersector.checkAnimations(false); - rootScope.broadcast('idle', false); + rootScope.broadcast('idle', rootScope.idle.isIDLE); }, {once: true}); }); @@ -105,7 +103,8 @@ export class AppImManager { this.updateStatusInterval = window.setInterval(() => this.updateStatus(), 50e3); this.updateStatus(); - rootScope.broadcast('idle', false); + this.offline = rootScope.idle.isIDLE = false; + rootScope.broadcast('idle', rootScope.idle.isIDLE); }, {once: true, passive: true}); this.chatsContainer = document.createElement('div'); @@ -566,14 +565,16 @@ export class AppImManager { document.body.classList.remove(RIGHT_COLUMN_ACTIVE_CLASSNAME); } - if(prevTabId !== -1 && id > prevTabId && id < 2) { - appNavigationController.pushItem({ - type: 'im', - onPop: (canAnimate) => { - //this.selectTab(prevTabId, !isSafari); - this.setPeer(0, undefined, canAnimate); - } - }); + if(prevTabId !== -1 && id > prevTabId) { + if(id < 2 || !appNavigationController.findItemByType('im')) { + appNavigationController.pushItem({ + type: 'im', + onPop: (canAnimate) => { + //this.selectTab(prevTabId, !isSafari); + this.setPeer(0, undefined, canAnimate); + } + }); + } } rootScope.broadcast('im_tab_change', id); @@ -623,7 +624,7 @@ export class AppImManager { rootScope.broadcast('peer_changed', this.chat.peerId); if(appSidebarRight.historyTabIds[appSidebarRight.historyTabIds.length - 1] === AppSidebarRight.SLIDERITEMSIDS.search) { - appSidebarRight.closeTab(AppSidebarRight.SLIDERITEMSIDS.search); + appSidebarRight.onCloseBtnClick(); } appSidebarRight.sharedMediaTab.setPeer(this.chat.peerId, this.chat.threadId);