From 59189db86d8649d110b58e88fcf6b6cb32b15d50 Mon Sep 17 00:00:00 2001 From: Devin Binnie <52460000+devinbinnie@users.noreply.github.com> Date: Fri, 10 Sep 2021 11:11:36 -0400 Subject: [PATCH] [MM-38275] Use browser history push for deeplinking and other inter-tab navigation when using a v6.0 server (#1726) --- src/main/views/MattermostView.ts | 7 +++++-- src/main/views/viewManager.ts | 33 +++++++++++++++++++++----------- 2 files changed, 27 insertions(+), 13 deletions(-) diff --git a/src/main/views/MattermostView.ts b/src/main/views/MattermostView.ts index 48905157..4f3a1e1b 100644 --- a/src/main/views/MattermostView.ts +++ b/src/main/views/MattermostView.ts @@ -24,6 +24,7 @@ import { import {TabView} from 'common/tabs/TabView'; +import {ServerInfo} from 'main/server/serverInfo'; import ContextMenu from '../contextMenu'; import {getWindowBoundaries, getLocalPreload, composeUserAgent} from '../utils'; import * as WindowManager from '../windows/windowManager'; @@ -31,7 +32,7 @@ import * as appState from '../appState'; import {removeWebContentsListeners} from './webContentEvents'; -enum Status { +export enum Status { LOADING, READY, WAITING_MM, @@ -47,6 +48,7 @@ export class MattermostView extends EventEmitter { view: BrowserView; isVisible: boolean; options: BrowserViewConstructorOptions; + serverInfo: ServerInfo; removeLoading?: number; @@ -65,10 +67,11 @@ export class MattermostView extends EventEmitter { retryLoad?: NodeJS.Timeout; maxRetries: number; - constructor(tab: TabView, win: BrowserWindow, options: BrowserViewConstructorOptions) { + constructor(tab: TabView, serverInfo: ServerInfo, win: BrowserWindow, options: BrowserViewConstructorOptions) { super(); this.tab = tab; this.window = win; + this.serverInfo = serverInfo; const preload = getLocalPreload('preload.js'); this.options = Object.assign({}, options); diff --git a/src/main/views/viewManager.ts b/src/main/views/viewManager.ts index 18092444..6f9e4b9e 100644 --- a/src/main/views/viewManager.ts +++ b/src/main/views/viewManager.ts @@ -16,16 +16,19 @@ import { LOADSCREEN_END, SET_ACTIVE_VIEW, OPEN_TAB, + BROWSER_HISTORY_PUSH, UPDATE_LAST_ACTIVE, } from 'common/communication'; import urlUtils from 'common/utils/url'; +import {isServerVersionGreaterThanOrEqualTo} from 'common/utils/util'; import {getServerView, getTabViewName} from 'common/tabs/TabView'; +import {ServerInfo} from 'main/server/serverInfo'; import {MattermostServer} from '../../common/servers/MattermostServer'; import {getLocalURLString, getLocalPreload, getWindowBoundaries} from '../utils'; -import {MattermostView} from './MattermostView'; +import {MattermostView, Status} from './MattermostView'; import {showModal, isModalDisplayed, focusCurrentModal} from './modalManager'; import {addWebContentsEventListeners} from './webContentEvents'; @@ -63,16 +66,17 @@ export class ViewManager { loadServer = (server: TeamWithTabs) => { const srv = new MattermostServer(server.name, server.url); - server.tabs.forEach((tab) => this.loadView(srv, tab)); + const serverInfo = new ServerInfo(srv); + server.tabs.forEach((tab) => this.loadView(srv, serverInfo, tab)); } - loadView = (srv: MattermostServer, tab: Tab, url?: string) => { + loadView = (srv: MattermostServer, serverInfo: ServerInfo, tab: Tab, url?: string) => { const tabView = getServerView(srv, tab); if (tab.isClosed) { this.closedViews.set(tabView.name, {srv, tab}); return; } - const view = new MattermostView(tabView, this.mainWindow, this.viewOptions); + const view = new MattermostView(tabView, serverInfo, this.mainWindow, this.viewOptions); this.views.set(tabView.name, view); if (!this.loadingScreen) { this.createLoadingScreen(); @@ -96,6 +100,7 @@ export class ViewManager { let setFocus; sorted.forEach((server) => { const srv = new MattermostServer(server.name, server.url); + const serverInfo = new ServerInfo(srv); server.tabs.forEach((tab) => { const tabView = getServerView(srv, tab); const recycle = oldviews.get(tabView.name); @@ -108,7 +113,7 @@ export class ViewManager { oldviews.delete(recycle.name); this.views.set(recycle.name, recycle); } else { - this.loadView(srv, tab); + this.loadView(srv, serverInfo, tab); } }); }); @@ -217,7 +222,7 @@ export class ViewManager { const {srv, tab} = this.closedViews.get(name)!; tab.isClosed = false; this.closedViews.delete(name); - this.loadView(srv, tab, url); + this.loadView(srv, new ServerInfo(srv), tab, url); this.showByName(name); const view = this.views.get(name)!; view.isVisible = true; @@ -402,11 +407,17 @@ export class ViewManager { return; } - // attempting to change parsedURL protocol results in it not being modified. - view.resetLoadingStatus(); - view.load(urlWithSchema); - view.once(LOAD_SUCCESS, this.deeplinkSuccess); - view.once(LOAD_FAILED, this.deeplinkFailed); + if (view.status === Status.READY && view.serverInfo.remoteInfo.serverVersion && isServerVersionGreaterThanOrEqualTo(view.serverInfo.remoteInfo.serverVersion, '6.0.0')) { + const pathName = `/${urlWithSchema.replace(view.tab.server.url.toString(), '')}`; + view.view.webContents.send(BROWSER_HISTORY_PUSH, pathName); + this.deeplinkSuccess(view.name); + } else { + // attempting to change parsedURL protocol results in it not being modified. + view.resetLoadingStatus(); + view.load(urlWithSchema); + view.once(LOAD_SUCCESS, this.deeplinkSuccess); + view.once(LOAD_FAILED, this.deeplinkFailed); + } } } else { dialog.showErrorBox('No matching server', `there is no configured server in the app that matches the requested url: ${parsedURL.toString()}`);