[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:
Devin Binnie
2021-09-16 13:35:07 -04:00
committed by GitHub
parent df57051eaa
commit b25ccfeecf
12 changed files with 76 additions and 55 deletions

View File

@@ -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';

View File

@@ -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,
},
],
};

View File

@@ -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;
}

View File

@@ -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,
};
}),
};
});

View File

@@ -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;
}
});
}

View File

@@ -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 */

View File

@@ -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);

View File

@@ -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);
}

View File

@@ -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];
}

View File

@@ -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');

View File

@@ -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}

View File

@@ -4,7 +4,7 @@
export type Tab = {
name: string;
order: number;
isClosed?: boolean;
isOpen?: boolean;
}
export type Team = {