[MM-22555] Auto-fill server URLs when deep linking into the Desktop App and the server isn't configured (#3200)
* Allow deep linking to non-configured servers by auto filling the modal * Fall back to base URL if URL with path name does not work * Allow deep linking directly into a new server with a permalink * Support welcome screen/no server case * Some cleanup
This commit is contained in:
@@ -65,6 +65,18 @@ export class ModalManager {
|
||||
return this.modalPromises.get(key) as Promise<T2>;
|
||||
};
|
||||
|
||||
removeModal = (key: string) => {
|
||||
const modalView = this.modalQueue.find((modal) => modal.key === key);
|
||||
if (!modalView) {
|
||||
return;
|
||||
}
|
||||
|
||||
modalView.hide();
|
||||
modalView.resolve(null);
|
||||
this.modalPromises.delete(key);
|
||||
this.filterActive();
|
||||
};
|
||||
|
||||
findModalByCaller = (event: IpcMainInvokeEvent) => {
|
||||
if (this.modalQueue.length) {
|
||||
const requestModal = this.modalQueue.find((modal) => {
|
||||
|
@@ -1,8 +1,6 @@
|
||||
// Copyright (c) 2016-present Mattermost, Inc. All Rights Reserved.
|
||||
// See LICENSE.txt for license information.
|
||||
|
||||
import {dialog} from 'electron';
|
||||
|
||||
import ServerViewState from 'app/serverViewState';
|
||||
import {BROWSER_HISTORY_PUSH, LOAD_SUCCESS, SET_ACTIVE_VIEW} from 'common/communication';
|
||||
import ServerManager from 'common/servers/serverManager';
|
||||
@@ -20,9 +18,6 @@ jest.mock('electron', () => ({
|
||||
getAppPath: () => '/path/to/app',
|
||||
getPath: jest.fn(() => '/valid/downloads/path'),
|
||||
},
|
||||
dialog: {
|
||||
showErrorBox: jest.fn(),
|
||||
},
|
||||
ipcMain: {
|
||||
emit: jest.fn(),
|
||||
on: jest.fn(),
|
||||
@@ -33,6 +28,7 @@ jest.mock('app/serverViewState', () => ({
|
||||
getCurrentServer: jest.fn(),
|
||||
updateCurrentView: jest.fn(),
|
||||
init: jest.fn(),
|
||||
showNewServerModal: jest.fn(),
|
||||
}));
|
||||
jest.mock('common/views/View', () => ({
|
||||
getViewName: jest.fn((a, b) => `${a}-${b}`),
|
||||
@@ -62,6 +58,10 @@ jest.mock('main/app/utils', () => ({
|
||||
flushCookiesStore: jest.fn(),
|
||||
}));
|
||||
|
||||
jest.mock('main/app/intercom', () => ({
|
||||
handleWelcomeScreenModal: jest.fn(),
|
||||
}));
|
||||
|
||||
jest.mock('main/i18nManager', () => ({
|
||||
localizeMessage: jest.fn(),
|
||||
}));
|
||||
@@ -116,8 +116,9 @@ jest.mock('./MattermostWebContentsView', () => ({
|
||||
MattermostWebContentsView: jest.fn(),
|
||||
}));
|
||||
|
||||
jest.mock('./modalManager', () => ({
|
||||
jest.mock('main/views/modalManager', () => ({
|
||||
showModal: jest.fn(),
|
||||
removeModal: jest.fn(),
|
||||
isModalDisplayed: jest.fn(),
|
||||
}));
|
||||
jest.mock('./webContentEvents', () => ({}));
|
||||
@@ -321,6 +322,7 @@ describe('main/views/viewManager', () => {
|
||||
isOpen: true,
|
||||
url: new URL('http://server1.com/view'),
|
||||
},
|
||||
undefined,
|
||||
);
|
||||
makeSpy.mockRestore();
|
||||
});
|
||||
@@ -692,11 +694,12 @@ describe('main/views/viewManager', () => {
|
||||
expect(view.load).not.toHaveBeenCalled();
|
||||
});
|
||||
|
||||
it('should throw dialog when cannot find the view', () => {
|
||||
it('should open new server modal when using a server that does not exist', () => {
|
||||
ServerManager.hasServers.mockReturnValue(true);
|
||||
const view = {...baseView};
|
||||
viewManager.handleDeepLink('mattermost://server-1.com/deep/link?thing=yes');
|
||||
viewManager.handleDeepLink('mattermost://server-2.com/deep/link?thing=yes');
|
||||
expect(view.load).not.toHaveBeenCalled();
|
||||
expect(dialog.showErrorBox).toHaveBeenCalled();
|
||||
expect(ServerViewState.showNewServerModal).toHaveBeenCalled();
|
||||
});
|
||||
|
||||
it('should reopen closed view if called upon', () => {
|
||||
|
@@ -2,7 +2,7 @@
|
||||
// See LICENSE.txt for license information.
|
||||
|
||||
import type {IpcMainEvent, IpcMainInvokeEvent} from 'electron';
|
||||
import {WebContentsView, dialog, ipcMain} from 'electron';
|
||||
import {WebContentsView, ipcMain} from 'electron';
|
||||
import isDev from 'electron-is-dev';
|
||||
|
||||
import ServerViewState from 'app/serverViewState';
|
||||
@@ -41,18 +41,18 @@ import {getFormattedPathName, parseURL} from 'common/utils/url';
|
||||
import Utils from 'common/utils/util';
|
||||
import type {MattermostView} from 'common/views/View';
|
||||
import {TAB_MESSAGING} from 'common/views/View';
|
||||
import {handleWelcomeScreenModal} from 'main/app/intercom';
|
||||
import {flushCookiesStore} from 'main/app/utils';
|
||||
import DeveloperMode from 'main/developerMode';
|
||||
import {localizeMessage} from 'main/i18nManager';
|
||||
import performanceMonitor from 'main/performanceMonitor';
|
||||
import PermissionsManager from 'main/permissionsManager';
|
||||
import ModalManager from 'main/views/modalManager';
|
||||
import MainWindow from 'main/windows/mainWindow';
|
||||
|
||||
import type {DeveloperSettings} from 'types/settings';
|
||||
|
||||
import LoadingScreen from './loadingScreen';
|
||||
import {MattermostWebContentsView} from './MattermostWebContentsView';
|
||||
import modalManager from './modalManager';
|
||||
|
||||
import {getLocalPreload, getAdjustedWindowBoundaries} from '../utils';
|
||||
|
||||
@@ -158,14 +158,14 @@ export class ViewManager {
|
||||
} else {
|
||||
this.getViewLogger(viewId).warn(`Couldn't find a view with name: ${viewId}`);
|
||||
}
|
||||
modalManager.showModal();
|
||||
ModalManager.showModal();
|
||||
};
|
||||
|
||||
focusCurrentView = () => {
|
||||
log.debug('focusCurrentView');
|
||||
|
||||
if (modalManager.isModalDisplayed()) {
|
||||
modalManager.focusCurrentModal();
|
||||
if (ModalManager.isModalDisplayed()) {
|
||||
ModalManager.focusCurrentModal();
|
||||
return;
|
||||
}
|
||||
|
||||
@@ -227,11 +227,11 @@ export class ViewManager {
|
||||
webContentsView.once(LOAD_FAILED, this.deeplinkFailed);
|
||||
}
|
||||
}
|
||||
} else if (ServerManager.hasServers()) {
|
||||
ServerViewState.showNewServerModal(`${parsedURL.host}${getFormattedPathName(parsedURL.pathname)}${parsedURL.search}`);
|
||||
} else {
|
||||
dialog.showErrorBox(
|
||||
localizeMessage('main.views.viewManager.handleDeepLink.error.title', 'No matching server'),
|
||||
localizeMessage('main.views.viewManager.handleDeepLink.error.body', 'There is no configured server in the app that matches the requested url: {url}', {url: parsedURL.toString()}),
|
||||
);
|
||||
ModalManager.removeModal('welcomeScreen');
|
||||
handleWelcomeScreenModal(`${parsedURL.host}${getFormattedPathName(parsedURL.pathname)}${parsedURL.search}`);
|
||||
}
|
||||
}
|
||||
};
|
||||
@@ -439,7 +439,7 @@ export class ViewManager {
|
||||
} else if (recycle) {
|
||||
views.set(view.id, recycle);
|
||||
} else {
|
||||
views.set(view.id, this.makeView(srv, view));
|
||||
views.set(view.id, this.makeView(srv, view, srv.initialLoadURL?.toString()));
|
||||
}
|
||||
}
|
||||
|
||||
|
Reference in New Issue
Block a user