[MM-50485] Migrate app to ServerManager, remove view names and replace with IDs (#2672)
* Migrate app to ServerManager, remove view names and replace with IDs * Fixed a test * Fixed a bug when adding the initial server * Merge'd * Bug fixes and PR feedback
This commit is contained in:
@@ -1,9 +1,7 @@
|
||||
// Copyright (c) 2016-present Mattermost, Inc. All Rights Reserved.
|
||||
// See LICENSE.txt for license information.
|
||||
import {BrowserView, dialog, ipcMain, IpcMainEvent, IpcMainInvokeEvent} from 'electron';
|
||||
import {BrowserViewConstructorOptions} from 'electron/main';
|
||||
|
||||
import {Tab, TeamWithTabs} from 'types/config';
|
||||
import {BrowserView, dialog, ipcMain, IpcMainEvent, IpcMainInvokeEvent} from 'electron';
|
||||
|
||||
import {SECOND, TAB_BAR_HEIGHT} from 'common/utils/constants';
|
||||
import {
|
||||
@@ -16,28 +14,25 @@ import {
|
||||
BROWSER_HISTORY_PUSH,
|
||||
UPDATE_LAST_ACTIVE,
|
||||
UPDATE_URL_VIEW_WIDTH,
|
||||
MAIN_WINDOW_SHOWN,
|
||||
RELOAD_CURRENT_VIEW,
|
||||
SERVERS_UPDATE,
|
||||
REACT_APP_INITIALIZED,
|
||||
APP_LOGGED_IN,
|
||||
BROWSER_HISTORY_BUTTON,
|
||||
APP_LOGGED_OUT,
|
||||
APP_LOGGED_IN,
|
||||
RELOAD_CURRENT_VIEW,
|
||||
UNREAD_RESULT,
|
||||
GET_VIEW_NAME,
|
||||
HISTORY,
|
||||
GET_VIEW_INFO_FOR_TEST,
|
||||
} from 'common/communication';
|
||||
import Config from 'common/config';
|
||||
import {Logger} from 'common/log';
|
||||
import urlUtils, {equalUrlsIgnoringSubpath} from 'common/utils/url';
|
||||
import urlUtils from 'common/utils/url';
|
||||
import Utils from 'common/utils/util';
|
||||
import {MattermostServer} from 'common/servers/MattermostServer';
|
||||
import {getTabViewName, TAB_FOCALBOARD, TAB_MESSAGING, TAB_PLAYBOOKS} from 'common/tabs/TabView';
|
||||
import MessagingTabView from 'common/tabs/MessagingTabView';
|
||||
import FocalboardTabView from 'common/tabs/FocalboardTabView';
|
||||
import PlaybooksTabView from 'common/tabs/PlaybooksTabView';
|
||||
import ServerManager from 'common/servers/serverManager';
|
||||
import {TabView, TAB_MESSAGING} from 'common/tabs/TabView';
|
||||
|
||||
import {localizeMessage} from 'main/i18nManager';
|
||||
import {ServerInfo} from 'main/server/serverInfo';
|
||||
import MainWindow from 'main/windows/mainWindow';
|
||||
|
||||
import * as appState from '../appState';
|
||||
@@ -52,21 +47,17 @@ const URL_VIEW_DURATION = 10 * SECOND;
|
||||
const URL_VIEW_HEIGHT = 20;
|
||||
|
||||
export class ViewManager {
|
||||
private closedViews: Map<string, {srv: MattermostServer; tab: Tab}>;
|
||||
private closedViews: Map<string, {srv: MattermostServer; tab: TabView}>;
|
||||
private views: Map<string, MattermostView>;
|
||||
private currentView?: string;
|
||||
|
||||
private urlViewCancel?: () => void;
|
||||
|
||||
private lastActiveServer?: number;
|
||||
private viewOptions: BrowserViewConstructorOptions;
|
||||
|
||||
constructor() {
|
||||
this.lastActiveServer = Config.lastActiveTeam;
|
||||
this.viewOptions = {webPreferences: {spellcheck: Config.useSpellChecker}};
|
||||
this.views = new Map(); // keep in mind that this doesn't need to hold server order, only tabs on the renderer need that.
|
||||
this.closedViews = new Map();
|
||||
|
||||
ipcMain.handle(GET_VIEW_INFO_FOR_TEST, this.handleGetViewInfoForTest);
|
||||
ipcMain.on(HISTORY, this.handleHistory);
|
||||
ipcMain.on(REACT_APP_INITIALIZED, this.handleReactAppInitialized);
|
||||
ipcMain.on(BROWSER_HISTORY_PUSH, this.handleBrowserHistoryPush);
|
||||
@@ -75,23 +66,24 @@ export class ViewManager {
|
||||
ipcMain.on(APP_LOGGED_OUT, this.handleAppLoggedOut);
|
||||
ipcMain.on(RELOAD_CURRENT_VIEW, this.handleReloadCurrentView);
|
||||
ipcMain.on(UNREAD_RESULT, this.handleFaviconIsUnread);
|
||||
ipcMain.handle(GET_VIEW_NAME, this.handleGetViewName);
|
||||
|
||||
ServerManager.on(SERVERS_UPDATE, this.handleReloadConfiguration);
|
||||
}
|
||||
|
||||
init = () => {
|
||||
this.getServers().forEach((server) => this.loadServer(server));
|
||||
LoadingScreen.show();
|
||||
ServerManager.getAllServers().forEach((server) => this.loadServer(server));
|
||||
this.showInitial();
|
||||
}
|
||||
|
||||
getView = (viewName: string) => {
|
||||
return this.views.get(viewName);
|
||||
getView = (viewId: string) => {
|
||||
return this.views.get(viewId);
|
||||
}
|
||||
|
||||
getCurrentView = () => {
|
||||
if (this.currentView) {
|
||||
return this.views.get(this.currentView);
|
||||
}
|
||||
|
||||
return undefined;
|
||||
}
|
||||
|
||||
@@ -99,42 +91,50 @@ export class ViewManager {
|
||||
return [...this.views.values()].find((view) => view.webContentsId === webContentsId);
|
||||
}
|
||||
|
||||
showByName = (name: string) => {
|
||||
log.debug('viewManager.showByName', name);
|
||||
isViewClosed = (viewId: string) => {
|
||||
return this.closedViews.has(viewId);
|
||||
}
|
||||
|
||||
const newView = this.views.get(name);
|
||||
showById = (tabId: string) => {
|
||||
this.getViewLogger(tabId).debug('showById', tabId);
|
||||
|
||||
const newView = this.views.get(tabId);
|
||||
if (newView) {
|
||||
if (newView.isVisible) {
|
||||
return;
|
||||
}
|
||||
if (this.currentView && this.currentView !== name) {
|
||||
let hidePrevious;
|
||||
if (this.currentView && this.currentView !== tabId) {
|
||||
const previous = this.getCurrentView();
|
||||
if (previous) {
|
||||
previous.hide();
|
||||
hidePrevious = () => previous.hide();
|
||||
}
|
||||
}
|
||||
|
||||
this.currentView = name;
|
||||
this.currentView = tabId;
|
||||
if (!newView.isErrored()) {
|
||||
newView.show();
|
||||
if (newView.needsLoadingScreen()) {
|
||||
LoadingScreen.show();
|
||||
}
|
||||
}
|
||||
MainWindow.get()?.webContents.send(SET_ACTIVE_VIEW, newView.tab.server.name, newView.tab.type);
|
||||
ipcMain.emit(SET_ACTIVE_VIEW, true, newView.tab.server.name, newView.tab.type);
|
||||
hidePrevious?.();
|
||||
MainWindow.get()?.webContents.send(SET_ACTIVE_VIEW, newView.tab.server.id, newView.tab.id);
|
||||
ipcMain.emit(SET_ACTIVE_VIEW, true, newView.tab.server.id, newView.tab.id);
|
||||
if (newView.isReady()) {
|
||||
ipcMain.emit(UPDATE_LAST_ACTIVE, true, newView.tab.server.name, newView.tab.type);
|
||||
ipcMain.emit(UPDATE_LAST_ACTIVE, true, newView.tab.id);
|
||||
} else {
|
||||
log.warn(`couldn't show ${name}, not ready`);
|
||||
this.getViewLogger(tabId).warn(`couldn't show ${tabId}, not ready`);
|
||||
}
|
||||
} else {
|
||||
log.warn(`Couldn't find a view with name: ${name}`);
|
||||
this.getViewLogger(tabId).warn(`Couldn't find a view with name: ${tabId}`);
|
||||
}
|
||||
modalManager.showModal();
|
||||
}
|
||||
|
||||
focusCurrentView = () => {
|
||||
log.debug('focusCurrentView');
|
||||
|
||||
if (modalManager.isModalDisplayed()) {
|
||||
modalManager.focusCurrentModal();
|
||||
return;
|
||||
@@ -171,25 +171,24 @@ export class ViewManager {
|
||||
*/
|
||||
|
||||
handleDeepLink = (url: string | URL) => {
|
||||
// TODO: fix for new tabs
|
||||
if (url) {
|
||||
const parsedURL = urlUtils.parseURL(url)!;
|
||||
const tabView = this.getViewByURL(parsedURL, true);
|
||||
const tabView = ServerManager.lookupTabByURL(parsedURL, true);
|
||||
if (tabView) {
|
||||
const urlWithSchema = `${urlUtils.parseURL(tabView.url)?.origin}${parsedURL.pathname}${parsedURL.search}`;
|
||||
if (this.closedViews.has(tabView.name)) {
|
||||
this.openClosedTab(tabView.name, urlWithSchema);
|
||||
const urlWithSchema = `${tabView.url.origin}${parsedURL.pathname}${parsedURL.search}`;
|
||||
if (this.closedViews.has(tabView.id)) {
|
||||
this.openClosedTab(tabView.id, urlWithSchema);
|
||||
} else {
|
||||
const view = this.views.get(tabView.name);
|
||||
const view = this.views.get(tabView.id);
|
||||
if (!view) {
|
||||
log.error(`Couldn't find a view matching the name ${tabView.name}`);
|
||||
log.error(`Couldn't find a view matching the id ${tabView.id}`);
|
||||
return;
|
||||
}
|
||||
|
||||
if (view.isReady() && view.serverInfo.remoteInfo.serverVersion && Utils.isVersionGreaterThanOrEqualTo(view.serverInfo.remoteInfo.serverVersion, '6.0.0')) {
|
||||
if (view.isReady() && ServerManager.getRemoteInfo(view.tab.server.id)?.serverVersion && Utils.isVersionGreaterThanOrEqualTo(ServerManager.getRemoteInfo(view.tab.server.id)?.serverVersion ?? '', '6.0.0')) {
|
||||
const pathName = `/${urlWithSchema.replace(view.tab.server.url.toString(), '')}`;
|
||||
view.sendToRenderer(BROWSER_HISTORY_PUSH, pathName);
|
||||
this.deeplinkSuccess(view.name);
|
||||
this.deeplinkSuccess(view.id);
|
||||
} else {
|
||||
// attempting to change parsedURL protocol results in it not being modified.
|
||||
view.resetLoadingStatus();
|
||||
@@ -207,83 +206,67 @@ export class ViewManager {
|
||||
}
|
||||
};
|
||||
|
||||
private deeplinkSuccess = (viewName: string) => {
|
||||
log.debug('deeplinkSuccess', viewName);
|
||||
private deeplinkSuccess = (viewId: string) => {
|
||||
this.getViewLogger(viewId).debug('deeplinkSuccess');
|
||||
|
||||
const view = this.views.get(viewName);
|
||||
if (!view) {
|
||||
return;
|
||||
}
|
||||
this.showByName(viewName);
|
||||
view.removeListener(LOAD_FAILED, this.deeplinkFailed);
|
||||
this.showById(viewId);
|
||||
this.views.get(viewId)?.removeListener(LOAD_FAILED, this.deeplinkFailed);
|
||||
};
|
||||
|
||||
private deeplinkFailed = (viewName: string, err: string, url: string) => {
|
||||
log.error(`[${viewName}] failed to load deeplink ${url}: ${err}`);
|
||||
const view = this.views.get(viewName);
|
||||
if (!view) {
|
||||
return;
|
||||
}
|
||||
view.removeListener(LOAD_SUCCESS, this.deeplinkSuccess);
|
||||
private deeplinkFailed = (viewId: string, err: string, url: string) => {
|
||||
this.getViewLogger(viewId).error(`failed to load deeplink ${url}`, err);
|
||||
this.views.get(viewId)?.removeListener(LOAD_SUCCESS, this.deeplinkSuccess);
|
||||
}
|
||||
|
||||
/**
|
||||
* View loading helpers
|
||||
*/
|
||||
|
||||
private loadServer = (server: TeamWithTabs) => {
|
||||
const srv = new MattermostServer(server);
|
||||
const serverInfo = new ServerInfo(srv);
|
||||
server.tabs.forEach((tab) => this.loadView(srv, serverInfo, tab));
|
||||
private loadServer = (server: MattermostServer) => {
|
||||
const tabs = ServerManager.getOrderedTabsForServer(server.id);
|
||||
tabs.forEach((tab) => this.loadView(server, tab));
|
||||
}
|
||||
|
||||
private loadView = (srv: MattermostServer, serverInfo: ServerInfo, tab: Tab, url?: string) => {
|
||||
private loadView = (srv: MattermostServer, tab: TabView, url?: string) => {
|
||||
if (!tab.isOpen) {
|
||||
this.closedViews.set(getTabViewName(srv.name, tab.name), {srv, tab});
|
||||
this.closedViews.set(tab.id, {srv, tab});
|
||||
return;
|
||||
}
|
||||
const view = this.makeView(srv, serverInfo, tab, url);
|
||||
const view = this.makeView(srv, tab, url);
|
||||
this.addView(view);
|
||||
}
|
||||
|
||||
private makeView = (srv: MattermostServer, serverInfo: ServerInfo, tab: Tab, url?: string): MattermostView => {
|
||||
const tabView = this.getServerView(srv, tab.name);
|
||||
const view = new MattermostView(tabView, serverInfo, this.viewOptions);
|
||||
private makeView = (srv: MattermostServer, tab: TabView, url?: string): MattermostView => {
|
||||
const mainWindow = MainWindow.get();
|
||||
if (!mainWindow) {
|
||||
throw new Error('Cannot create view, no main window present');
|
||||
}
|
||||
|
||||
const view = new MattermostView(tab, {webPreferences: {spellcheck: Config.useSpellChecker}});
|
||||
view.once(LOAD_SUCCESS, this.activateView);
|
||||
view.load(url);
|
||||
view.on(UPDATE_TARGET_URL, this.showURLView);
|
||||
view.on(LOADSCREEN_END, this.finishLoading);
|
||||
view.on(LOAD_FAILED, this.failLoading);
|
||||
view.on(UPDATE_TARGET_URL, this.showURLView);
|
||||
view.load(url);
|
||||
return view;
|
||||
}
|
||||
|
||||
private addView = (view: MattermostView): void => {
|
||||
this.views.set(view.name, view);
|
||||
if (this.closedViews.has(view.name)) {
|
||||
this.closedViews.delete(view.name);
|
||||
this.views.set(view.id, view);
|
||||
if (this.closedViews.has(view.id)) {
|
||||
this.closedViews.delete(view.id);
|
||||
}
|
||||
}
|
||||
|
||||
private showInitial = () => {
|
||||
log.verbose('showInitial');
|
||||
|
||||
const servers = this.getServers();
|
||||
if (servers.length) {
|
||||
const element = servers.find((e) => e.order === this.lastActiveServer) || servers.find((e) => e.order === 0);
|
||||
if (element && element.tabs.length) {
|
||||
let tab = element.tabs.find((tab) => tab.order === element.lastActiveTab) || element.tabs.find((tab) => tab.order === 0);
|
||||
if (!tab?.isOpen) {
|
||||
const openTabs = element.tabs.filter((tab) => tab.isOpen);
|
||||
tab = openTabs.find((e) => e.order === 0) || openTabs.concat().sort((a, b) => a.order - b.order)[0];
|
||||
}
|
||||
if (tab) {
|
||||
const tabView = getTabViewName(element.name, tab.name);
|
||||
this.showByName(tabView);
|
||||
}
|
||||
}
|
||||
if (ServerManager.hasServers()) {
|
||||
const lastActiveServer = ServerManager.getCurrentServer();
|
||||
const lastActiveTab = ServerManager.getLastActiveTabForServer(lastActiveServer.id);
|
||||
this.showById(lastActiveTab.id);
|
||||
} else {
|
||||
MainWindow.get()?.webContents.send(SET_ACTIVE_VIEW, null, null);
|
||||
ipcMain.emit(MAIN_WINDOW_SHOWN);
|
||||
MainWindow.get()?.webContents.send(SET_ACTIVE_VIEW);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -291,29 +274,28 @@ export class ViewManager {
|
||||
* Mattermost view event handlers
|
||||
*/
|
||||
|
||||
private activateView = (viewName: string) => {
|
||||
log.debug('activateView', viewName);
|
||||
private activateView = (viewId: string) => {
|
||||
this.getViewLogger(viewId).debug('activateView');
|
||||
|
||||
if (this.currentView === viewName) {
|
||||
this.showByName(this.currentView);
|
||||
if (this.currentView === viewId) {
|
||||
this.showById(this.currentView);
|
||||
}
|
||||
}
|
||||
|
||||
private finishLoading = (server: string) => {
|
||||
log.debug('finishLoading', server);
|
||||
private finishLoading = (viewId: string) => {
|
||||
this.getViewLogger(viewId).debug('finishLoading');
|
||||
|
||||
const view = this.views.get(server);
|
||||
if (view && this.getCurrentView() === view) {
|
||||
this.showByName(this.currentView!);
|
||||
if (this.currentView === viewId) {
|
||||
this.showById(this.currentView);
|
||||
LoadingScreen.fade();
|
||||
}
|
||||
}
|
||||
|
||||
private failLoading = (tabName: string) => {
|
||||
log.debug('failLoading', tabName);
|
||||
private failLoading = (viewId: string) => {
|
||||
this.getViewLogger(viewId).debug('failLoading');
|
||||
|
||||
LoadingScreen.fade();
|
||||
if (this.currentView === tabName) {
|
||||
if (this.currentView === viewId) {
|
||||
this.getCurrentView()?.hide();
|
||||
}
|
||||
}
|
||||
@@ -344,7 +326,7 @@ export class ViewManager {
|
||||
const query = new Map([['url', urlString]]);
|
||||
const localURL = getLocalURLString('urlView.html', query);
|
||||
urlView.webContents.loadURL(localURL);
|
||||
mainWindow.addBrowserView(urlView);
|
||||
MainWindow.get()?.addBrowserView(urlView);
|
||||
const boundaries = this.views.get(this.currentView || '')?.getBounds() ?? mainWindow.getBounds();
|
||||
|
||||
const hideView = () => {
|
||||
@@ -372,7 +354,7 @@ export class ViewManager {
|
||||
height: URL_VIEW_HEIGHT,
|
||||
};
|
||||
|
||||
log.silly('showURLView setBounds', boundaries, bounds);
|
||||
log.silly('showURLView.setBounds', boundaries, bounds);
|
||||
urlView.setBounds(bounds);
|
||||
};
|
||||
|
||||
@@ -397,34 +379,30 @@ export class ViewManager {
|
||||
* Servers or tabs have been added or edited. We need to
|
||||
* close, open, or reload tabs, taking care to reuse tabs and
|
||||
* preserve focus on the currently selected tab. */
|
||||
reloadConfiguration = () => {
|
||||
log.debug('reloadConfiguration');
|
||||
private handleReloadConfiguration = () => {
|
||||
log.debug('handleReloadConfiguration');
|
||||
|
||||
const currentTabId: string | undefined = this.views.get(this.currentView as string)?.tab.id;
|
||||
|
||||
const current: Map<string, MattermostView> = new Map();
|
||||
for (const view of this.views.values()) {
|
||||
current.set(view.name, view);
|
||||
current.set(view.tab.id, view);
|
||||
}
|
||||
|
||||
const views: Map<string, MattermostView> = new Map();
|
||||
const closed: Map<string, {srv: MattermostServer; tab: Tab; name: string}> = new Map();
|
||||
const closed: Map<string, {srv: MattermostServer; tab: TabView}> = new Map();
|
||||
|
||||
const sortedTabs = this.getServers().flatMap((x) => [...x.tabs].
|
||||
sort((a, b) => a.order - b.order).
|
||||
map((t): [TeamWithTabs, Tab] => [x, t]));
|
||||
const sortedTabs = ServerManager.getAllServers().flatMap((x) => ServerManager.getOrderedTabsForServer(x.id).
|
||||
map((t): [MattermostServer, TabView] => [x, t]));
|
||||
|
||||
for (const [team, tab] of sortedTabs) {
|
||||
const srv = new MattermostServer(team);
|
||||
const info = new ServerInfo(srv);
|
||||
const tabName = getTabViewName(team.name, tab.name);
|
||||
const recycle = current.get(tabName);
|
||||
for (const [srv, tab] of sortedTabs) {
|
||||
const recycle = current.get(tab.id);
|
||||
if (!tab.isOpen) {
|
||||
const view = this.getServerView(srv, tab.name);
|
||||
closed.set(tabName, {srv, tab, name: view.name});
|
||||
closed.set(tab.id, {srv, tab});
|
||||
} else if (recycle) {
|
||||
recycle.updateServerInfo(srv);
|
||||
views.set(tabName, recycle);
|
||||
views.set(tab.id, recycle);
|
||||
} else {
|
||||
views.set(tabName, this.makeView(srv, info, tab, team.url));
|
||||
views.set(tab.id, this.makeView(srv, tab));
|
||||
}
|
||||
}
|
||||
|
||||
@@ -439,16 +417,16 @@ export class ViewManager {
|
||||
// commit views
|
||||
this.views = new Map();
|
||||
for (const x of views.values()) {
|
||||
this.views.set(x.name, x);
|
||||
this.views.set(x.id, x);
|
||||
}
|
||||
|
||||
// commit closed
|
||||
for (const x of closed.values()) {
|
||||
this.closedViews.set(x.name, {srv: x.srv, tab: x.tab});
|
||||
this.closedViews.set(x.tab.id, {srv: x.srv, tab: x.tab});
|
||||
}
|
||||
|
||||
if ((this.currentView && closed.has(this.currentView)) || (this.currentView && this.closedViews.has(this.currentView))) {
|
||||
if (this.getServers().length) {
|
||||
if ((currentTabId && closed.has(currentTabId)) || (this.currentView && this.closedViews.has(this.currentView))) {
|
||||
if (ServerManager.hasServers()) {
|
||||
this.currentView = undefined;
|
||||
this.showInitial();
|
||||
} else {
|
||||
@@ -457,12 +435,14 @@ export class ViewManager {
|
||||
}
|
||||
|
||||
// show the focused tab (or initial)
|
||||
if (this.currentView && views.has(this.currentView)) {
|
||||
const view = views.get(this.currentView);
|
||||
if (view) {
|
||||
this.currentView = view.name;
|
||||
this.showByName(view.name);
|
||||
MainWindow.get()?.webContents.send(SET_ACTIVE_VIEW, view.tab.server.name, view.tab.type);
|
||||
if (currentTabId && views.has(currentTabId)) {
|
||||
const view = views.get(currentTabId);
|
||||
if (view && view.id !== this.currentView) {
|
||||
this.currentView = view.id;
|
||||
this.showById(view.id);
|
||||
MainWindow.get()?.webContents.send(SET_ACTIVE_VIEW, view.tab.server.id, view.tab.id);
|
||||
} else {
|
||||
this.focusCurrentView();
|
||||
}
|
||||
} else {
|
||||
this.showInitial();
|
||||
@@ -481,21 +461,21 @@ export class ViewManager {
|
||||
this.getView(viewId)?.onLogin(false);
|
||||
}
|
||||
|
||||
private handleBrowserHistoryPush = (e: IpcMainEvent, viewName: string, pathName: string) => {
|
||||
log.debug('handleBrowserHistoryPush', {viewName, pathName});
|
||||
private handleBrowserHistoryPush = (e: IpcMainEvent, viewId: string, pathName: string) => {
|
||||
log.debug('handleBrowserHistoryPush', {viewId, pathName});
|
||||
|
||||
const currentView = this.views.get(viewName);
|
||||
const currentView = this.getView(viewId);
|
||||
const cleanedPathName = urlUtils.cleanPathName(currentView?.tab.server.url.pathname || '', pathName);
|
||||
const redirectedViewName = this.getViewByURL(`${currentView?.tab.server.url.toString().replace(/\/$/, '')}${cleanedPathName}`)?.name || viewName;
|
||||
if (this.closedViews.has(redirectedViewName)) {
|
||||
const redirectedviewId = ServerManager.lookupTabByURL(`${currentView?.tab.server.url.toString().replace(/\/$/, '')}${cleanedPathName}`)?.id || viewId;
|
||||
if (this.isViewClosed(redirectedviewId)) {
|
||||
// If it's a closed view, just open it and stop
|
||||
this.openClosedTab(redirectedViewName, `${currentView?.tab.server.url}${cleanedPathName}`);
|
||||
this.openClosedTab(redirectedviewId, `${currentView?.tab.server.url}${cleanedPathName}`);
|
||||
return;
|
||||
}
|
||||
let redirectedView = this.views.get(redirectedViewName) || currentView;
|
||||
if (redirectedView !== currentView && redirectedView?.tab.name === this.currentView && redirectedView?.isLoggedIn) {
|
||||
log.info('redirecting to a new view', redirectedView?.name || viewName);
|
||||
this.showByName(redirectedView?.name || viewName);
|
||||
let redirectedView = this.getView(redirectedviewId) || currentView;
|
||||
if (redirectedView !== currentView && redirectedView?.tab.server.id === ServerManager.getCurrentServer().id && redirectedView?.isLoggedIn) {
|
||||
log.info('redirecting to a new view', redirectedView?.id || viewId);
|
||||
this.showById(redirectedView?.id || viewId);
|
||||
} else {
|
||||
redirectedView = currentView;
|
||||
}
|
||||
@@ -504,21 +484,19 @@ export class ViewManager {
|
||||
if (!(redirectedView !== currentView && redirectedView?.tab.type === TAB_MESSAGING && cleanedPathName === '/')) {
|
||||
redirectedView?.sendToRenderer(BROWSER_HISTORY_PUSH, cleanedPathName);
|
||||
if (redirectedView) {
|
||||
this.handleBrowserHistoryButton(e, redirectedView.name);
|
||||
this.handleBrowserHistoryButton(e, redirectedView.id);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private handleBrowserHistoryButton = (e: IpcMainEvent, viewName: string) => {
|
||||
log.debug('handleBrowserHistoryButton', viewName);
|
||||
|
||||
this.getView(viewName)?.updateHistoryButton();
|
||||
private handleBrowserHistoryButton = (e: IpcMainEvent, viewId: string) => {
|
||||
this.getView(viewId)?.updateHistoryButton();
|
||||
}
|
||||
|
||||
private handleReactAppInitialized = (e: IpcMainEvent, viewName: string) => {
|
||||
log.debug('handleReactAppInitialized', viewName);
|
||||
private handleReactAppInitialized = (e: IpcMainEvent, viewId: string) => {
|
||||
log.debug('handleReactAppInitialized', viewId);
|
||||
|
||||
const view = this.views.get(viewName);
|
||||
const view = this.views.get(viewId);
|
||||
if (view) {
|
||||
view.setInitialized();
|
||||
if (this.getCurrentView() === view) {
|
||||
@@ -535,94 +513,53 @@ export class ViewManager {
|
||||
return;
|
||||
}
|
||||
view?.reload();
|
||||
this.showByName(view?.name);
|
||||
this.showById(view?.id);
|
||||
}
|
||||
|
||||
// if favicon is null, it means it is the initial load,
|
||||
// so don't memoize as we don't have the favicons and there is no rush to find out.
|
||||
private handleFaviconIsUnread = (e: Event, favicon: string, viewName: string, result: boolean) => {
|
||||
log.silly('handleFaviconIsUnread', {favicon, viewName, result});
|
||||
private handleFaviconIsUnread = (e: Event, favicon: string, viewId: string, result: boolean) => {
|
||||
log.silly('handleFaviconIsUnread', {favicon, viewId, result});
|
||||
|
||||
appState.updateUnreads(viewName, result);
|
||||
appState.updateUnreads(viewId, result);
|
||||
}
|
||||
|
||||
/**
|
||||
* Helper functions
|
||||
*/
|
||||
|
||||
private openClosedTab = (name: string, url?: string) => {
|
||||
if (!this.closedViews.has(name)) {
|
||||
private openClosedTab = (id: string, url?: string) => {
|
||||
if (!this.closedViews.has(id)) {
|
||||
return;
|
||||
}
|
||||
const {srv, tab} = this.closedViews.get(name)!;
|
||||
const {srv, tab} = this.closedViews.get(id)!;
|
||||
tab.isOpen = true;
|
||||
this.loadView(srv, new ServerInfo(srv), tab, url);
|
||||
this.showByName(name);
|
||||
const view = this.views.get(name)!;
|
||||
this.loadView(srv, tab, url);
|
||||
this.showById(id);
|
||||
const view = this.views.get(id)!;
|
||||
view.isVisible = true;
|
||||
view.on(LOAD_SUCCESS, () => {
|
||||
view.isVisible = false;
|
||||
this.showByName(name);
|
||||
this.showById(id);
|
||||
});
|
||||
ipcMain.emit(OPEN_TAB, null, srv.name, tab.name);
|
||||
ipcMain.emit(OPEN_TAB, null, tab.id);
|
||||
}
|
||||
|
||||
getViewByURL = (inputURL: URL | string, ignoreScheme = false) => {
|
||||
log.silly('getViewByURL', `${inputURL}`, ignoreScheme);
|
||||
private getViewLogger = (viewId: string) => {
|
||||
return ServerManager.getViewLog(viewId, 'ViewManager');
|
||||
}
|
||||
|
||||
const parsedURL = urlUtils.parseURL(inputURL);
|
||||
if (!parsedURL) {
|
||||
return undefined;
|
||||
}
|
||||
const server = this.getServers().find((team) => {
|
||||
const parsedServerUrl = urlUtils.parseURL(team.url)!;
|
||||
return equalUrlsIgnoringSubpath(parsedURL, parsedServerUrl, ignoreScheme) && parsedURL.pathname.match(new RegExp(`^${parsedServerUrl.pathname}(.+)?(/(.+))?$`));
|
||||
});
|
||||
if (!server) {
|
||||
return undefined;
|
||||
}
|
||||
const mmServer = new MattermostServer(server);
|
||||
let selectedTab = this.getServerView(mmServer, TAB_MESSAGING);
|
||||
server.tabs.
|
||||
filter((tab) => tab.name !== TAB_MESSAGING).
|
||||
forEach((tab) => {
|
||||
const tabCandidate = this.getServerView(mmServer, tab.name);
|
||||
if (parsedURL.pathname.match(new RegExp(`^${tabCandidate.url.pathname}(/(.+))?`))) {
|
||||
selectedTab = tabCandidate;
|
||||
}
|
||||
});
|
||||
return selectedTab;
|
||||
}
|
||||
|
||||
private getServerView = (srv: MattermostServer, tabName: string) => {
|
||||
switch (tabName) {
|
||||
case TAB_MESSAGING:
|
||||
return new MessagingTabView(srv);
|
||||
case TAB_FOCALBOARD:
|
||||
return new FocalboardTabView(srv);
|
||||
case TAB_PLAYBOOKS:
|
||||
return new PlaybooksTabView(srv);
|
||||
default:
|
||||
throw new Error('Not implemeneted');
|
||||
}
|
||||
}
|
||||
|
||||
private getServers = () => {
|
||||
return Config.teams.concat();
|
||||
}
|
||||
|
||||
handleGetViewName = (event: IpcMainInvokeEvent) => {
|
||||
return this.getViewByWebContentsId(event.sender.id);
|
||||
}
|
||||
|
||||
setServerInitialized = (server: string) => {
|
||||
const view = this.views.get(server);
|
||||
if (view) {
|
||||
view.setInitialized();
|
||||
if (this.getCurrentView() === view) {
|
||||
LoadingScreen.fade();
|
||||
}
|
||||
private handleGetViewInfoForTest = (event: IpcMainInvokeEvent) => {
|
||||
const view = this.getViewByWebContentsId(event.sender.id);
|
||||
if (!view) {
|
||||
return null;
|
||||
}
|
||||
return {
|
||||
id: view.id,
|
||||
webContentsId: view.webContentsId,
|
||||
serverName: view.tab.server.name,
|
||||
tabType: view.tab.type,
|
||||
};
|
||||
}
|
||||
}
|
||||
|
||||
|
Reference in New Issue
Block a user