[MM-38524] Rework the closing and opening tab logic, fixed login issue (#1735)
* Rework the closing and opening tab logic to better suit adding and removing servers * A couple more fixes * Lint fix * [MM-38524] Fix login issue * Remove unneeded code
This commit is contained in:
@@ -97,3 +97,4 @@ export const RECEIVE_DROPDOWN_MENU_SIZE = 'receive-dropdown-menu-size';
|
||||
export const SEND_DROPDOWN_MENU_SIZE = 'send-dropdown-menu-size';
|
||||
|
||||
export const BROWSER_HISTORY_PUSH = 'browser-history-push';
|
||||
export const APP_LOGGED_IN = 'app-logged-in';
|
||||
|
@@ -30,17 +30,15 @@ export function getDefaultTeamWithTabsFromTeam(team: Team) {
|
||||
{
|
||||
name: TAB_MESSAGING,
|
||||
order: 0,
|
||||
isClosed: false,
|
||||
isOpen: true,
|
||||
},
|
||||
{
|
||||
name: TAB_FOCALBOARD,
|
||||
order: 1,
|
||||
isClosed: false,
|
||||
},
|
||||
{
|
||||
name: TAB_PLAYBOOKS,
|
||||
order: 2,
|
||||
isClosed: false,
|
||||
},
|
||||
],
|
||||
};
|
||||
|
@@ -37,7 +37,7 @@ function shorten(string: string, max?: number) {
|
||||
return string;
|
||||
}
|
||||
|
||||
export function isServerVersionGreaterThanOrEqualTo(currentVersion: string, compareVersion: string): boolean {
|
||||
function isServerVersionGreaterThanOrEqualTo(currentVersion: string, compareVersion: string): boolean {
|
||||
if (currentVersion === compareVersion) {
|
||||
return true;
|
||||
}
|
||||
|
@@ -11,6 +11,7 @@ import {AppState} from 'types/appState';
|
||||
import {ComparableCertificate} from 'types/certificate';
|
||||
import {PermissionType, TrustedOrigin} from 'types/trustedOrigin';
|
||||
|
||||
import {TAB_MESSAGING} from 'common/tabs/TabView';
|
||||
import urlUtils from 'common/utils/url';
|
||||
|
||||
const defaultOptions = {
|
||||
@@ -103,7 +104,7 @@ const configDataSchemaV3 = Joi.object<ConfigV3>({
|
||||
tabs: Joi.array().items(Joi.object({
|
||||
name: Joi.string().required(),
|
||||
order: Joi.number().integer().min(0),
|
||||
isClosed: Joi.boolean().default(false),
|
||||
isOpen: Joi.boolean(),
|
||||
})).default([]),
|
||||
})).default([]),
|
||||
showTrayIcon: Joi.boolean().default(false),
|
||||
@@ -226,6 +227,14 @@ export function validateV3ConfigData(data: ConfigV3) {
|
||||
return {
|
||||
...team,
|
||||
url: cleanURL(team.url),
|
||||
|
||||
// Force messaging to stay open regardless of user config
|
||||
tabs: team.tabs.map((tab) => {
|
||||
return {
|
||||
...tab,
|
||||
isOpen: tab.name === TAB_MESSAGING ? true : tab.isOpen,
|
||||
};
|
||||
}),
|
||||
};
|
||||
});
|
||||
|
||||
|
@@ -47,7 +47,7 @@ import {
|
||||
import Config from 'common/config';
|
||||
import {MattermostServer} from 'common/servers/MattermostServer';
|
||||
import {getDefaultTeamWithTabsFromTeam, TAB_FOCALBOARD, TAB_MESSAGING, TAB_PLAYBOOKS} from 'common/tabs/TabView';
|
||||
import Utils, {isServerVersionGreaterThanOrEqualTo} from 'common/utils/util';
|
||||
import Utils from 'common/utils/util';
|
||||
|
||||
import urlUtils from 'common/utils/url';
|
||||
|
||||
@@ -515,12 +515,12 @@ function handleCloseTab(event: IpcMainEvent, serverName: string, tabName: string
|
||||
if (team.name === serverName) {
|
||||
team.tabs.forEach((tab) => {
|
||||
if (tab.name === tabName) {
|
||||
tab.isClosed = true;
|
||||
tab.isOpen = false;
|
||||
}
|
||||
});
|
||||
}
|
||||
});
|
||||
const nextTab = teams.find((team) => team.name === serverName)!.tabs.filter((tab) => !tab.isClosed)[0].name;
|
||||
const nextTab = teams.find((team) => team.name === serverName)!.tabs.filter((tab) => tab.isOpen)[0].name;
|
||||
WindowManager.switchTab(serverName, nextTab);
|
||||
config.set('teams', teams);
|
||||
}
|
||||
@@ -531,7 +531,7 @@ function handleOpenTab(event: IpcMainEvent, serverName: string, tabName: string)
|
||||
if (team.name === serverName) {
|
||||
team.tabs.forEach((tab) => {
|
||||
if (tab.name === tabName) {
|
||||
tab.isClosed = false;
|
||||
tab.isOpen = true;
|
||||
}
|
||||
});
|
||||
}
|
||||
@@ -815,28 +815,26 @@ function updateServerInfos(teams: TeamWithTabs[]) {
|
||||
});
|
||||
Promise.all(serverInfos).then((data: Array<RemoteInfo | string | undefined>) => {
|
||||
const teams = config.teams;
|
||||
teams.forEach((team) => closeUnneededTabs(data, team));
|
||||
teams.forEach((team) => openExtraTabs(data, team));
|
||||
config.set('teams', teams);
|
||||
}).catch((reason: any) => {
|
||||
log.error('Error getting server infos', reason);
|
||||
});
|
||||
}
|
||||
|
||||
function closeUnneededTabs(data: Array<RemoteInfo | string | undefined>, team: TeamWithTabs) {
|
||||
function openExtraTabs(data: Array<RemoteInfo | string | undefined>, team: TeamWithTabs) {
|
||||
const remoteInfo = data.find((info) => info && typeof info !== 'string' && info.name === team.name) as RemoteInfo;
|
||||
if (remoteInfo) {
|
||||
team.tabs.forEach((tab) => {
|
||||
if (tab.name === TAB_PLAYBOOKS && !remoteInfo.hasPlaybooks) {
|
||||
log.info(`closing ${team.name}___${tab.name} on !hasPlaybooks`);
|
||||
tab.isClosed = true;
|
||||
if (tab.name !== TAB_MESSAGING && remoteInfo.serverVersion && Utils.isServerVersionGreaterThanOrEqualTo(remoteInfo.serverVersion, '6.0.0')) {
|
||||
if (tab.name === TAB_PLAYBOOKS && remoteInfo.hasPlaybooks && tab.isOpen !== false) {
|
||||
log.info(`opening ${team.name}___${tab.name} on hasPlaybooks`);
|
||||
tab.isOpen = true;
|
||||
}
|
||||
if (tab.name === TAB_FOCALBOARD && !remoteInfo.hasFocalboard) {
|
||||
log.info(`closing ${team.name}___${tab.name} on !hasFocalboard`);
|
||||
tab.isClosed = true;
|
||||
if (tab.name === TAB_FOCALBOARD && remoteInfo.hasFocalboard && tab.isOpen !== false) {
|
||||
log.info(`opening ${team.name}___${tab.name} on hasFocalboard`);
|
||||
tab.isOpen = true;
|
||||
}
|
||||
if (tab.name !== TAB_MESSAGING && remoteInfo.serverVersion && !isServerVersionGreaterThanOrEqualTo(remoteInfo.serverVersion, '6.0.0')) {
|
||||
log.info(`closing ${team.name}___${tab.name} on !serverVersion`);
|
||||
tab.isClosed = true;
|
||||
}
|
||||
});
|
||||
}
|
||||
|
@@ -22,6 +22,7 @@ import {
|
||||
USER_ACTIVITY_UPDATE,
|
||||
CLOSE_TEAMS_DROPDOWN,
|
||||
BROWSER_HISTORY_PUSH,
|
||||
APP_LOGGED_IN,
|
||||
} from 'common/communication';
|
||||
|
||||
const UNREAD_COUNT_INTERVAL = 1000;
|
||||
@@ -242,4 +243,10 @@ ipcRenderer.on(BROWSER_HISTORY_PUSH, (event, pathName) => {
|
||||
);
|
||||
});
|
||||
|
||||
window.addEventListener('storage', (e) => {
|
||||
if (e.key === '__login__' && e.storageArea === localStorage && e.newValue) {
|
||||
ipcRenderer.send(APP_LOGGED_IN, viewName);
|
||||
}
|
||||
});
|
||||
|
||||
/* eslint-enable no-magic-numbers */
|
||||
|
@@ -20,7 +20,7 @@ import {
|
||||
UPDATE_LAST_ACTIVE,
|
||||
} from 'common/communication';
|
||||
import urlUtils from 'common/utils/url';
|
||||
import {isServerVersionGreaterThanOrEqualTo} from 'common/utils/util';
|
||||
import Utils from 'common/utils/util';
|
||||
|
||||
import {getServerView, getTabViewName} from 'common/tabs/TabView';
|
||||
|
||||
@@ -72,12 +72,13 @@ export class ViewManager {
|
||||
|
||||
loadView = (srv: MattermostServer, serverInfo: ServerInfo, tab: Tab, url?: string) => {
|
||||
const tabView = getServerView(srv, tab);
|
||||
if (tab.isClosed) {
|
||||
if (!tab.isOpen) {
|
||||
this.closedViews.set(tabView.name, {srv, tab});
|
||||
return;
|
||||
}
|
||||
const view = new MattermostView(tabView, serverInfo, this.mainWindow, this.viewOptions);
|
||||
this.views.set(tabView.name, view);
|
||||
this.showByName(tabView.name);
|
||||
if (!this.loadingScreen) {
|
||||
this.createLoadingScreen();
|
||||
}
|
||||
@@ -88,6 +89,13 @@ export class ViewManager {
|
||||
view.once(LOAD_FAILED, this.failLoading);
|
||||
}
|
||||
|
||||
reloadViewIfNeeded = (viewName: string) => {
|
||||
const view = this.views.get(viewName);
|
||||
if (!view?.getWebContents()?.getURL().startsWith(view.tab.url.toString())) {
|
||||
view?.load(view.tab.url);
|
||||
}
|
||||
}
|
||||
|
||||
load = () => {
|
||||
this.configServers.forEach((server) => this.loadServer(server));
|
||||
}
|
||||
@@ -107,7 +115,7 @@ export class ViewManager {
|
||||
if (recycle && recycle.isVisible) {
|
||||
setFocus = recycle.name;
|
||||
}
|
||||
if (tab.isClosed) {
|
||||
if (!tab.isOpen) {
|
||||
this.closedViews.set(tabView.name, {srv, tab});
|
||||
} else if (recycle && recycle.tab.name === tabView.name && recycle.tab.url.toString() === urlUtils.parseURL(tabView.url)!.toString()) {
|
||||
oldviews.delete(recycle.name);
|
||||
@@ -117,6 +125,14 @@ export class ViewManager {
|
||||
}
|
||||
});
|
||||
});
|
||||
if (this.currentView && (oldviews.has(this.currentView) || this.closedViews.has(this.currentView))) {
|
||||
if (configServers.length) {
|
||||
delete this.currentView;
|
||||
this.showInitial();
|
||||
} else {
|
||||
this.mainWindow.webContents.send(SET_ACTIVE_VIEW);
|
||||
}
|
||||
}
|
||||
oldviews.forEach((unused) => {
|
||||
unused.destroy();
|
||||
});
|
||||
@@ -132,8 +148,8 @@ export class ViewManager {
|
||||
const element = this.configServers.find((e) => e.order === this.lastActiveServer || 0);
|
||||
if (element && element.tabs.length) {
|
||||
let tab = element.tabs.find((tab) => tab.order === element.lastActiveTab || 0);
|
||||
if (tab?.isClosed) {
|
||||
const openTabs = element.tabs.filter((tab) => !tab.isClosed);
|
||||
if (!tab?.isOpen) {
|
||||
const openTabs = element.tabs.filter((tab) => tab.isOpen);
|
||||
tab = openTabs.find((e) => e.order === 0) || openTabs[0];
|
||||
}
|
||||
if (tab) {
|
||||
@@ -220,7 +236,7 @@ export class ViewManager {
|
||||
return;
|
||||
}
|
||||
const {srv, tab} = this.closedViews.get(name)!;
|
||||
tab.isClosed = false;
|
||||
tab.isOpen = true;
|
||||
this.closedViews.delete(name);
|
||||
this.loadView(srv, new ServerInfo(srv), tab, url);
|
||||
this.showByName(name);
|
||||
@@ -407,7 +423,7 @@ export class ViewManager {
|
||||
return;
|
||||
}
|
||||
|
||||
if (view.status === Status.READY && view.serverInfo.remoteInfo.serverVersion && isServerVersionGreaterThanOrEqualTo(view.serverInfo.remoteInfo.serverVersion, '6.0.0')) {
|
||||
if (view.status === Status.READY && view.serverInfo.remoteInfo.serverVersion && Utils.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);
|
||||
|
@@ -17,6 +17,7 @@ import {
|
||||
GET_DARK_MODE,
|
||||
UPDATE_SHORTCUT_MENU,
|
||||
BROWSER_HISTORY_PUSH,
|
||||
APP_LOGGED_IN,
|
||||
} from 'common/communication';
|
||||
import urlUtils from 'common/utils/url';
|
||||
|
||||
@@ -52,6 +53,7 @@ ipcMain.handle(GET_DARK_MODE, handleGetDarkMode);
|
||||
ipcMain.on(REACT_APP_INITIALIZED, handleReactAppInitialized);
|
||||
ipcMain.on(LOADING_SCREEN_ANIMATION_FINISHED, handleLoadingScreenAnimationFinished);
|
||||
ipcMain.on(BROWSER_HISTORY_PUSH, handleBrowserHistoryPush);
|
||||
ipcMain.on(APP_LOGGED_IN, handleAppLoggedIn);
|
||||
|
||||
export function setConfig(data: CombinedConfig) {
|
||||
if (data) {
|
||||
@@ -363,8 +365,12 @@ export function switchServer(serverName: string) {
|
||||
return;
|
||||
}
|
||||
status.currentServerName = serverName;
|
||||
const lastActiveTab = server.tabs.find((tab) => !tab.isClosed && tab.order === (server.lastActiveTab || 0)) || server.tabs[0];
|
||||
const tabViewName = getTabViewName(serverName, lastActiveTab.name);
|
||||
let nextTab = server.tabs.find((tab) => tab.isOpen && tab.order === (server.lastActiveTab || 0));
|
||||
if (!nextTab) {
|
||||
const openTabs = server.tabs.filter((tab) => tab.isOpen);
|
||||
nextTab = openTabs.find((e) => e.order === 0) || openTabs[0];
|
||||
}
|
||||
const tabViewName = getTabViewName(serverName, nextTab.name);
|
||||
status.viewManager?.showByName(tabViewName);
|
||||
ipcMain.emit(UPDATE_SHORTCUT_MENU);
|
||||
}
|
||||
@@ -489,7 +495,7 @@ export function selectNextTab() {
|
||||
}
|
||||
|
||||
const currentTeamTabs = status.config?.teams.find((team) => team.name === currentView.tab.server.name)?.tabs;
|
||||
const filteredTabs = currentTeamTabs?.filter((tab) => !tab.isClosed);
|
||||
const filteredTabs = currentTeamTabs?.filter((tab) => tab.isOpen);
|
||||
const currentTab = currentTeamTabs?.find((tab) => tab.name === currentView.tab.type);
|
||||
if (!currentTeamTabs || !currentTab || !filteredTabs) {
|
||||
return;
|
||||
@@ -514,7 +520,7 @@ export function selectPreviousTab() {
|
||||
}
|
||||
|
||||
const currentTeamTabs = status.config?.teams.find((team) => team.name === currentView.tab.server.name)?.tabs;
|
||||
const filteredTabs = currentTeamTabs?.filter((tab) => !tab.isClosed);
|
||||
const filteredTabs = currentTeamTabs?.filter((tab) => tab.isOpen);
|
||||
const currentTab = currentTeamTabs?.find((tab) => tab.name === currentView.tab.type);
|
||||
if (!currentTeamTabs || !currentTab || !filteredTabs) {
|
||||
return;
|
||||
@@ -554,3 +560,7 @@ function handleBrowserHistoryPush(e: IpcMainEvent, viewName: string, pathName: s
|
||||
export function getCurrentTeamName() {
|
||||
return status.currentServerName;
|
||||
}
|
||||
|
||||
function handleAppLoggedIn(event: IpcMainEvent, viewName: string) {
|
||||
status.viewManager?.reloadViewIfNeeded(viewName);
|
||||
}
|
||||
|
@@ -104,8 +104,8 @@ export default class MainPage extends React.PureComponent<Props, State> {
|
||||
|
||||
const firstServer = this.props.teams.find((team) => team.order === this.props.lastActiveTeam || 0);
|
||||
let firstTab = firstServer?.tabs.find((tab) => tab.order === firstServer.lastActiveTab || 0);
|
||||
if (firstTab?.isClosed) {
|
||||
const openTabs = firstServer?.tabs.filter((tab) => !tab.isClosed) || [];
|
||||
if (!firstTab?.isOpen) {
|
||||
const openTabs = firstServer?.tabs.filter((tab) => tab.isOpen) || [];
|
||||
firstTab = openTabs?.find((e) => e.order === 0) || openTabs[0];
|
||||
}
|
||||
|
||||
|
@@ -15,7 +15,6 @@ import {CombinedConfig, LocalConfiguration, Team} from 'types/config';
|
||||
import {DeepPartial} from 'types/utils';
|
||||
|
||||
import {GET_LOCAL_CONFIGURATION, UPDATE_CONFIGURATION, DOUBLE_CLICK_ON_WINDOW, GET_DOWNLOAD_LOCATION, ADD_SERVER, RELOAD_CONFIGURATION} from 'common/communication';
|
||||
import {getDefaultTeamWithTabsFromTeam} from 'common/tabs/TabView';
|
||||
|
||||
import AutoSaveIndicator, {SavingState} from './AutoSaveIndicator';
|
||||
|
||||
@@ -349,23 +348,6 @@ export default class SettingsPage extends React.PureComponent<Record<string, nev
|
||||
allowSaveSpellCheckerURL,
|
||||
});
|
||||
}
|
||||
updateTeam = (index: number, newData: Team) => {
|
||||
const teams = this.state.teams || [];
|
||||
teams[index] = newData;
|
||||
window.timers.setImmediate(this.saveSetting, CONFIG_TYPE_SERVERS, {key: 'teams', data: teams});
|
||||
this.setState({
|
||||
teams,
|
||||
});
|
||||
}
|
||||
|
||||
addServer = (team: Team) => {
|
||||
const teams = this.state.teams || [];
|
||||
teams.push(getDefaultTeamWithTabsFromTeam(team));
|
||||
window.timers.setImmediate(this.saveSetting, CONFIG_TYPE_SERVERS, {key: 'teams', data: teams});
|
||||
this.setState({
|
||||
teams,
|
||||
});
|
||||
}
|
||||
|
||||
handleDoubleClick = () => {
|
||||
window.ipcRenderer.send(DOUBLE_CLICK_ON_WINDOW, 'settings');
|
||||
|
@@ -85,7 +85,7 @@ export default class TabBar extends React.PureComponent<Props> {
|
||||
index={orderedIndex}
|
||||
>
|
||||
{(provided, snapshot) => {
|
||||
if (tab.isClosed) {
|
||||
if (!tab.isOpen) {
|
||||
return (
|
||||
<div
|
||||
ref={provided.innerRef}
|
||||
|
@@ -4,7 +4,7 @@
|
||||
export type Tab = {
|
||||
name: string;
|
||||
order: number;
|
||||
isClosed?: boolean;
|
||||
isOpen?: boolean;
|
||||
}
|
||||
|
||||
export type Team = {
|
||||
|
Reference in New Issue
Block a user