diff --git a/i18n/en.json b/i18n/en.json
index ce63337f..2172facd 100644
--- a/i18n/en.json
+++ b/i18n/en.json
@@ -85,8 +85,6 @@
"main.menus.app.view.developerModeDisableContextMenu": "Disable Context Menu",
"main.menus.app.view.developerModeDisableNotificationStorage": "Disable Notification Storage",
"main.menus.app.view.developerModeDisableUserActivityMonitor": "Disable User Activity Monitor",
- "main.menus.app.view.developerModeForceLegacyAPI": "Force Legacy API",
- "main.menus.app.view.developerModeForceNewAPI": "Force New API",
"main.menus.app.view.devToolsAppWrapper": "Developer Tools for Application Wrapper",
"main.menus.app.view.devToolsCurrentCallWidget": "Developer Tools for Call Widget",
"main.menus.app.view.devToolsCurrentServer": "Developer Tools for Current Server",
@@ -164,7 +162,6 @@
"renderer.components.errorView.troubleshooting.browserView.canReachFromBrowserWindow": "You can reach {url} from a browser window.",
"renderer.components.errorView.troubleshooting.computerIsConnected": "Your computer is connected to the internet.",
"renderer.components.errorView.troubleshooting.urlIsCorrect.appNameIsCorrect": "The {appName} URL {url} is correct",
- "renderer.components.extraBar.back": "Back",
"renderer.components.input.required": "This field is required",
"renderer.components.mainPage.contextMenu.ariaLabel": "Context menu",
"renderer.components.mainPage.titleBar": "{appName}",
diff --git a/src/common/communication.ts b/src/common/communication.ts
index 903403d3..cd73b89d 100644
--- a/src/common/communication.ts
+++ b/src/common/communication.ts
@@ -55,15 +55,11 @@ export const PLAY_SOUND = 'play_sound';
export const GET_DOWNLOAD_LOCATION = 'get_download_location';
export const UPDATE_MENTIONS = 'update_mentions';
-export const IS_UNREAD = 'is_unread';
-export const UNREAD_RESULT = 'unread_result';
export const UNREADS_AND_MENTIONS = 'unreads-and-mentions';
export const SESSION_EXPIRED = 'session_expired';
export const REACT_APP_INITIALIZED = 'react-app-initialized';
-export const TOGGLE_BACK_BUTTON = 'toggle-back-button';
-
export const SHOW_SETTINGS_WINDOW = 'show-settings-window';
export const LOADING_SCREEN_ANIMATION_FINISHED = 'loading-screen-animation-finished';
@@ -93,8 +89,6 @@ export const CHECK_FOR_UPDATES = 'check-for-updates';
export const NO_UPDATE_AVAILABLE = 'no-update-available';
export const BROWSER_HISTORY_PUSH = 'browser-history-push';
-export const APP_LOGGED_IN = 'app-logged-in';
-export const APP_LOGGED_OUT = 'app-logged-out';
export const TAB_LOGIN_CHANGED = 'tab-login-changed';
export const GET_AVAILABLE_SPELL_CHECKER_LANGUAGES = 'get-available-spell-checker-languages';
@@ -118,13 +112,11 @@ export const VIEW_FINISHED_RESIZING = 'view-finished-resizing';
// Calls
export const GET_DESKTOP_SOURCES = 'get-desktop-sources';
-export const DESKTOP_SOURCES_RESULT = 'desktop-sources-result';
export const DESKTOP_SOURCES_MODAL_REQUEST = 'desktop-sources-modal-request';
export const CALLS_JOIN_CALL = 'calls-join-call';
export const CALLS_LEAVE_CALL = 'calls-leave-call';
export const CALLS_WIDGET_RESIZE = 'calls-widget-resize';
export const CALLS_WIDGET_SHARE_SCREEN = 'calls-widget-share-screen';
-export const CALLS_WIDGET_CHANNEL_LINK_CLICK = 'calls-widget-channel-link-click';
export const CALLS_LINK_CLICK = 'calls-link-click';
export const CALLS_JOINED_CALL = 'calls-joined-call';
export const CALLS_POPOUT_FOCUS = 'calls-popout-focus';
@@ -189,14 +181,10 @@ export const OPEN_WINDOWS_CAMERA_PREFERENCES = 'open-windows-camera-preferences'
export const OPEN_WINDOWS_MICROPHONE_PREFERENCES = 'open-windows-microphone-preferences';
export const GET_MEDIA_ACCESS_STATUS = 'get-media-access-status';
-// Legacy code remove signal
-export const LEGACY_OFF = 'legacy-off';
-
export const GET_NONCE = 'get-nonce';
export const DEVELOPER_MODE_UPDATED = 'developer-mode-updated';
export const IS_DEVELOPER_MODE_ENABLED = 'is-developer-mode-enabled';
-export const GET_DEVELOPER_MODE_SETTING = 'get-developer-mode-setting';
export const METRICS_SEND = 'metrics-send';
export const METRICS_RECEIVE = 'metrics-receive';
diff --git a/src/common/utils/constants.ts b/src/common/utils/constants.ts
index f7307722..6b347784 100644
--- a/src/common/utils/constants.ts
+++ b/src/common/utils/constants.ts
@@ -15,7 +15,6 @@ export const MAX_LOADING_SCREEN_SECONDS = 4 * SECOND;
export const TAB_BAR_HEIGHT = 40;
export const TAB_BAR_PADDING = 4;
-export const BACK_BAR_HEIGHT = 36;
export const THREE_DOT_MENU_WIDTH = 40;
export const THREE_DOT_MENU_WIDTH_MAC = 80;
export const MENU_SHADOW_WIDTH = 24;
@@ -55,20 +54,6 @@ export const URLValidationStatus = {
URLUpdated: 'URL_UPDATED',
};
-// supported custom login paths (oath, saml)
-export const customLoginRegexPaths = [
- /^\/oauth\/authorize$/i,
- /^\/oauth\/deauthorize$/i,
- /^\/oauth\/access_token$/i,
- /^\/oauth\/[A-Za-z0-9]+\/complete$/i,
- /^\/oauth\/[A-Za-z0-9]+\/login$/i,
- /^\/oauth\/[A-Za-z0-9]+\/signup$/i,
- /^\/api\/v3\/oauth\/[A-Za-z0-9]+\/complete$/i,
- /^\/signup\/[A-Za-z0-9]+\/complete$/i,
- /^\/login\/[A-Za-z0-9]+\/complete$/i,
- /^\/login\/sso\/saml$/i,
-];
-
export const nonTeamUrlPaths = [
'plugins',
'signup',
diff --git a/src/common/utils/url.test.js b/src/common/utils/url.test.js
index 2f18a345..16375423 100644
--- a/src/common/utils/url.test.js
+++ b/src/common/utils/url.test.js
@@ -9,7 +9,6 @@ import {
isValidURI,
parseURL,
isInternalURL,
- isCustomLoginURL,
isCallsPopOutURL,
isTrustedURL,
} from 'common/utils/url';
@@ -204,45 +203,6 @@ describe('common/utils/url', () => {
});
});
- describe('isCustomLoginURL', () => {
- it('should match correct URL', () => {
- expect(isCustomLoginURL(
- new URL('http://server.com/oauth/authorize'),
- new URL('http://server.com'),
- )).toBe(true);
- });
- it('should not match incorrect URL', () => {
- expect(isCustomLoginURL(
- new URL('http://server.com/oauth/notauthorize'),
- new URL('http://server.com'),
- )).toBe(false);
- });
- it('should not match base URL', () => {
- expect(isCustomLoginURL(
- new URL('http://server.com/'),
- new URL('http://server.com'),
- )).toBe(false);
- });
- it('should match with subpath', () => {
- expect(isCustomLoginURL(
- new URL('http://server.com/subpath/oauth/authorize'),
- new URL('http://server.com/subpath'),
- )).toBe(true);
- });
- it('should not match with different subpath', () => {
- expect(isCustomLoginURL(
- new URL('http://server.com/subpath/oauth/authorize'),
- new URL('http://server.com/different/subpath'),
- )).toBe(false);
- });
- it('should not match with oauth subpath', () => {
- expect(isCustomLoginURL(
- new URL('http://server.com/oauth/authorize'),
- new URL('http://server.com/oauth/authorize'),
- )).toBe(false);
- });
- });
-
describe('isCallsPopOutURL', () => {
it('should match correct URL', () => {
expect(isCallsPopOutURL(
diff --git a/src/common/utils/url.ts b/src/common/utils/url.ts
index 856beb93..c0ce205b 100644
--- a/src/common/utils/url.ts
+++ b/src/common/utils/url.ts
@@ -4,7 +4,7 @@
import {isHttpsUri, isHttpUri, isUri} from 'valid-url';
import buildConfig from 'common/config/buildConfig';
-import {customLoginRegexPaths, nonTeamUrlPaths, CALLS_PLUGIN_ID} from 'common/utils/constants';
+import {nonTeamUrlPaths, CALLS_PLUGIN_ID} from 'common/utils/constants';
export const getFormattedPathName = (pn: string) => (pn.endsWith('/') ? pn : `${pn}/`);
export const parseURL = (inputURL: string | URL) => {
@@ -77,22 +77,6 @@ export const isTeamUrl = (serverURL: URL, inputURL: URL, withApi?: boolean) => {
}
return !(paths.some((testPath) => isUrlType(testPath, serverURL, inputURL)));
};
-export const isCustomLoginURL = (inputURL: URL, serverURL: URL) => {
- if (!isTrustedURL(inputURL, serverURL)) {
- return false;
- }
- const subpath = serverURL.pathname;
- const urlPath = inputURL.pathname;
- const replacement = subpath.endsWith('/') ? '/' : '';
- const replacedPath = urlPath.replace(subpath, replacement);
- for (const regexPath of customLoginRegexPaths) {
- if (replacedPath.match(regexPath)) {
- return true;
- }
- }
-
- return false;
-};
export const isCallsPopOutURL = (serverURL: URL, inputURL: URL, callID: string) => {
const matches = inputURL.pathname.match(new RegExp(`^${escapeRegExp(getFormattedPathName(serverURL.pathname))}([A-Za-z0-9-_]+)/`, 'i'));
diff --git a/src/main/authManager.test.js b/src/main/authManager.test.js
index c408e58e..3a1b2306 100644
--- a/src/main/authManager.test.js
+++ b/src/main/authManager.test.js
@@ -14,9 +14,6 @@ jest.mock('common/utils/url', () => {
isTrustedURL: (url) => {
return url.toString() === 'http://trustedurl.com/';
},
- isCustomLoginURL: (url) => {
- return url.toString() === 'http://customloginurl.com/';
- },
};
});
@@ -73,13 +70,6 @@ describe('main/authManager', () => {
expect(authManager.popPermissionModal).not.toBeCalled();
});
- it('should popLoginModal when isCustomLoginURL', () => {
- ViewManager.getViewByWebContentsId.mockReturnValue({view: {server: {url: new URL('http://customloginurl.com/')}}});
- authManager.handleAppLogin({preventDefault: jest.fn()}, {id: 1}, {url: 'http://customloginurl.com/'}, null, jest.fn());
- expect(authManager.popLoginModal).toBeCalled();
- expect(authManager.popPermissionModal).not.toBeCalled();
- });
-
it('should popLoginModal when has permission', () => {
ViewManager.getViewByWebContentsId.mockReturnValue({view: {server: {url: new URL('http://haspermissionurl.com/')}}});
authManager.handleAppLogin({preventDefault: jest.fn()}, {id: 1}, {url: 'http://haspermissionurl.com/'}, null, jest.fn());
diff --git a/src/main/authManager.ts b/src/main/authManager.ts
index a0a8d892..444acf4b 100644
--- a/src/main/authManager.ts
+++ b/src/main/authManager.ts
@@ -4,7 +4,7 @@ import type {AuthenticationResponseDetails, AuthInfo, WebContents, Event} from '
import {Logger} from 'common/log';
import {BASIC_AUTH_PERMISSION} from 'common/permissions';
-import {isCustomLoginURL, isTrustedURL, parseURL} from 'common/utils/url';
+import {isTrustedURL, parseURL} from 'common/utils/url';
import TrustedOriginsStore from 'main/trustedOrigins';
import {getLocalPreload} from 'main/utils';
import modalManager from 'main/views/modalManager';
@@ -45,7 +45,7 @@ export class AuthManager {
}
this.loginCallbackMap.set(request.url, callback); // if callback is undefined set it to null instead so we know we have set it up with no value
- if (isTrustedURL(parsedURL, serverURL) || isCustomLoginURL(parsedURL, serverURL) || TrustedOriginsStore.checkPermission(parsedURL, BASIC_AUTH_PERMISSION)) {
+ if (isTrustedURL(parsedURL, serverURL) || TrustedOriginsStore.checkPermission(parsedURL, BASIC_AUTH_PERMISSION)) {
this.popLoginModal(request, authInfo);
} else {
this.popPermissionModal(request, authInfo, BASIC_AUTH_PERMISSION);
diff --git a/src/main/developerMode.ts b/src/main/developerMode.ts
index c8496ba7..d85f344f 100644
--- a/src/main/developerMode.ts
+++ b/src/main/developerMode.ts
@@ -4,7 +4,7 @@
import {ipcMain} from 'electron';
import {EventEmitter} from 'events';
-import {DEVELOPER_MODE_UPDATED, IS_DEVELOPER_MODE_ENABLED, UPDATE_PATHS, GET_DEVELOPER_MODE_SETTING} from 'common/communication';
+import {DEVELOPER_MODE_UPDATED, IS_DEVELOPER_MODE_ENABLED, UPDATE_PATHS} from 'common/communication';
import JsonFileManager from 'common/JsonFileManager';
import {developerModeJson} from 'main/constants';
@@ -18,7 +18,6 @@ export class DeveloperMode extends EventEmitter {
this.json = new JsonFileManager(file);
ipcMain.handle(IS_DEVELOPER_MODE_ENABLED, this.enabled);
- ipcMain.handle(GET_DEVELOPER_MODE_SETTING, (_, setting) => this.get(setting));
}
enabled = () => process.env.MM_DESKTOP_DEVELOPER_MODE === 'true';
diff --git a/src/main/menus/app.ts b/src/main/menus/app.ts
index 3bc64898..816d0b86 100644
--- a/src/main/menus/app.ts
+++ b/src/main/menus/app.ts
@@ -214,22 +214,6 @@ export function createTemplate(config: Config, updateManager: UpdateManager) {
DeveloperMode.toggle('disableContextMenu');
},
},
- {
- label: localizeMessage('main.menus.app.view.developerModeForceLegacyAPI', 'Force Legacy API'),
- type: 'checkbox' as const,
- checked: DeveloperMode.get('forceLegacyAPI'),
- click() {
- DeveloperMode.toggle('forceLegacyAPI');
- },
- },
- {
- label: localizeMessage('main.menus.app.view.developerModeForceNewAPI', 'Force New API'),
- type: 'checkbox' as const,
- checked: DeveloperMode.get('forceNewAPI'),
- click() {
- DeveloperMode.toggle('forceNewAPI');
- },
- },
]);
}
diff --git a/src/main/preload/externalAPI.ts b/src/main/preload/externalAPI.ts
index 46d81c25..f8016bd8 100644
--- a/src/main/preload/externalAPI.ts
+++ b/src/main/preload/externalAPI.ts
@@ -8,16 +8,11 @@ import type {DesktopAPI} from '@mattermost/desktop-api';
import {
NOTIFY_MENTION,
- IS_UNREAD,
- UNREAD_RESULT,
SESSION_EXPIRED,
REACT_APP_INITIALIZED,
USER_ACTIVITY_UPDATE,
BROWSER_HISTORY_PUSH,
- APP_LOGGED_IN,
- APP_LOGGED_OUT,
GET_VIEW_INFO_FOR_TEST,
- DESKTOP_SOURCES_RESULT,
VIEW_FINISHED_RESIZING,
CALLS_JOIN_CALL,
CALLS_JOINED_CALL,
@@ -33,7 +28,6 @@ import {
BROWSER_HISTORY_STATUS_UPDATED,
NOTIFICATION_CLICKED,
CALLS_WIDGET_RESIZE,
- CALLS_WIDGET_CHANNEL_LINK_CLICK,
CALLS_LINK_CLICK,
CALLS_POPOUT_FOCUS,
CALLS_WIDGET_OPEN_THREAD,
@@ -41,9 +35,7 @@ import {
CALLS_WIDGET_OPEN_USER_SETTINGS,
GET_DESKTOP_SOURCES,
UNREADS_AND_MENTIONS,
- LEGACY_OFF,
TAB_LOGIN_CHANGED,
- GET_DEVELOPER_MODE_SETTING,
METRICS_SEND,
METRICS_REQUEST,
METRICS_RECEIVE,
@@ -51,96 +43,80 @@ import {
import type {ExternalAPI} from 'types/externalAPI';
-let legacyEnabled = false;
-let legacyOff: () => void;
-
-ipcRenderer.invoke(GET_DEVELOPER_MODE_SETTING, 'forceLegacyAPI').then((force) => {
- if (force) {
- return;
- }
-
- const createListener: ExternalAPI['createListener'] = (channel: string, listener: (...args: never[]) => void) => {
- const listenerWithEvent = (_: IpcRendererEvent, ...args: unknown[]) =>
- listener(...args as never[]);
- ipcRenderer.on(channel, listenerWithEvent);
- return () => {
- ipcRenderer.off(channel, listenerWithEvent);
- };
+const createListener: ExternalAPI['createListener'] = (channel: string, listener: (...args: never[]) => void) => {
+ const listenerWithEvent = (_: IpcRendererEvent, ...args: unknown[]) =>
+ listener(...args as never[]);
+ ipcRenderer.on(channel, listenerWithEvent);
+ return () => {
+ ipcRenderer.off(channel, listenerWithEvent);
};
+};
- const desktopAPI: DesktopAPI = {
+const desktopAPI: DesktopAPI = {
- // Initialization
- isDev: () => ipcRenderer.invoke(GET_IS_DEV_MODE),
- getAppInfo: () => {
- // Using this signal as the sign to disable the legacy code, since it is run before the app is rendered
- if (legacyEnabled) {
- legacyOff?.();
- }
+ // Initialization
+ isDev: () => ipcRenderer.invoke(GET_IS_DEV_MODE),
+ getAppInfo: () => ipcRenderer.invoke(GET_APP_INFO),
+ reactAppInitialized: () => ipcRenderer.send(REACT_APP_INITIALIZED),
- return ipcRenderer.invoke(GET_APP_INFO);
- },
- reactAppInitialized: () => ipcRenderer.send(REACT_APP_INITIALIZED),
+ // Session
+ setSessionExpired: (isExpired) => ipcRenderer.send(SESSION_EXPIRED, isExpired),
+ onUserActivityUpdate: (listener) => createListener(USER_ACTIVITY_UPDATE, listener),
- // Session
- setSessionExpired: (isExpired) => ipcRenderer.send(SESSION_EXPIRED, isExpired),
- onUserActivityUpdate: (listener) => createListener(USER_ACTIVITY_UPDATE, listener),
+ onLogin: () => ipcRenderer.send(TAB_LOGIN_CHANGED, true),
+ onLogout: () => ipcRenderer.send(TAB_LOGIN_CHANGED, false),
- onLogin: () => ipcRenderer.send(TAB_LOGIN_CHANGED, true),
- onLogout: () => ipcRenderer.send(TAB_LOGIN_CHANGED, false),
+ // Unreads/mentions/notifications
+ sendNotification: (title, body, channelId, teamId, url, silent, soundName) =>
+ ipcRenderer.invoke(NOTIFY_MENTION, title, body, channelId, teamId, url, silent, soundName),
+ onNotificationClicked: (listener) => createListener(NOTIFICATION_CLICKED, listener),
+ setUnreadsAndMentions: (isUnread, mentionCount) => ipcRenderer.send(UNREADS_AND_MENTIONS, isUnread, mentionCount),
- // Unreads/mentions/notifications
- sendNotification: (title, body, channelId, teamId, url, silent, soundName) =>
- ipcRenderer.invoke(NOTIFY_MENTION, title, body, channelId, teamId, url, silent, soundName),
- onNotificationClicked: (listener) => createListener(NOTIFICATION_CLICKED, listener),
- setUnreadsAndMentions: (isUnread, mentionCount) => ipcRenderer.send(UNREADS_AND_MENTIONS, isUnread, mentionCount),
+ // Navigation
+ requestBrowserHistoryStatus: () => ipcRenderer.invoke(REQUEST_BROWSER_HISTORY_STATUS),
+ onBrowserHistoryStatusUpdated: (listener) => createListener(BROWSER_HISTORY_STATUS_UPDATED, listener),
+ onBrowserHistoryPush: (listener) => createListener(BROWSER_HISTORY_PUSH, listener),
+ sendBrowserHistoryPush: (path) => ipcRenderer.send(BROWSER_HISTORY_PUSH, path),
- // Navigation
- requestBrowserHistoryStatus: () => ipcRenderer.invoke(REQUEST_BROWSER_HISTORY_STATUS),
- onBrowserHistoryStatusUpdated: (listener) => createListener(BROWSER_HISTORY_STATUS_UPDATED, listener),
- onBrowserHistoryPush: (listener) => createListener(BROWSER_HISTORY_PUSH, listener),
- sendBrowserHistoryPush: (path) => ipcRenderer.send(BROWSER_HISTORY_PUSH, path),
+ // Calls
+ joinCall: (opts) => ipcRenderer.invoke(CALLS_JOIN_CALL, opts),
+ leaveCall: () => ipcRenderer.send(CALLS_LEAVE_CALL),
- // Calls
- joinCall: (opts) => ipcRenderer.invoke(CALLS_JOIN_CALL, opts),
- leaveCall: () => ipcRenderer.send(CALLS_LEAVE_CALL),
+ callsWidgetConnected: (callID, sessionID) => ipcRenderer.send(CALLS_JOINED_CALL, callID, sessionID),
+ resizeCallsWidget: (width, height) => ipcRenderer.send(CALLS_WIDGET_RESIZE, width, height),
- callsWidgetConnected: (callID, sessionID) => ipcRenderer.send(CALLS_JOINED_CALL, callID, sessionID),
- resizeCallsWidget: (width, height) => ipcRenderer.send(CALLS_WIDGET_RESIZE, width, height),
+ sendCallsError: (err, callID, errMsg) => ipcRenderer.send(CALLS_ERROR, err, callID, errMsg),
+ onCallsError: (listener) => createListener(CALLS_ERROR, listener),
- sendCallsError: (err, callID, errMsg) => ipcRenderer.send(CALLS_ERROR, err, callID, errMsg),
- onCallsError: (listener) => createListener(CALLS_ERROR, listener),
+ getDesktopSources: (opts) => ipcRenderer.invoke(GET_DESKTOP_SOURCES, opts),
+ openScreenShareModal: () => ipcRenderer.send(DESKTOP_SOURCES_MODAL_REQUEST),
+ onOpenScreenShareModal: (listener) => createListener(DESKTOP_SOURCES_MODAL_REQUEST, listener),
- getDesktopSources: (opts) => ipcRenderer.invoke(GET_DESKTOP_SOURCES, opts),
- openScreenShareModal: () => ipcRenderer.send(DESKTOP_SOURCES_MODAL_REQUEST),
- onOpenScreenShareModal: (listener) => createListener(DESKTOP_SOURCES_MODAL_REQUEST, listener),
+ shareScreen: (sourceID, withAudio) => ipcRenderer.send(CALLS_WIDGET_SHARE_SCREEN, sourceID, withAudio),
+ onScreenShared: (listener) => createListener(CALLS_WIDGET_SHARE_SCREEN, listener),
- shareScreen: (sourceID, withAudio) => ipcRenderer.send(CALLS_WIDGET_SHARE_SCREEN, sourceID, withAudio),
- onScreenShared: (listener) => createListener(CALLS_WIDGET_SHARE_SCREEN, listener),
+ sendJoinCallRequest: (callId) => ipcRenderer.send(CALLS_JOIN_REQUEST, callId),
+ onJoinCallRequest: (listener) => createListener(CALLS_JOIN_REQUEST, listener),
- sendJoinCallRequest: (callId) => ipcRenderer.send(CALLS_JOIN_REQUEST, callId),
- onJoinCallRequest: (listener) => createListener(CALLS_JOIN_REQUEST, listener),
+ openLinkFromCalls: (url) => ipcRenderer.send(CALLS_LINK_CLICK, url),
- openLinkFromCalls: (url) => ipcRenderer.send(CALLS_LINK_CLICK, url),
+ focusPopout: () => ipcRenderer.send(CALLS_POPOUT_FOCUS),
- focusPopout: () => ipcRenderer.send(CALLS_POPOUT_FOCUS),
+ openThreadForCalls: (threadID) => ipcRenderer.send(CALLS_WIDGET_OPEN_THREAD, threadID),
+ onOpenThreadForCalls: (listener) => createListener(CALLS_WIDGET_OPEN_THREAD, listener),
- openThreadForCalls: (threadID) => ipcRenderer.send(CALLS_WIDGET_OPEN_THREAD, threadID),
- onOpenThreadForCalls: (listener) => createListener(CALLS_WIDGET_OPEN_THREAD, listener),
+ openStopRecordingModal: (channelID) => ipcRenderer.send(CALLS_WIDGET_OPEN_STOP_RECORDING_MODAL, channelID),
+ onOpenStopRecordingModal: (listener) => createListener(CALLS_WIDGET_OPEN_STOP_RECORDING_MODAL, listener),
- openStopRecordingModal: (channelID) => ipcRenderer.send(CALLS_WIDGET_OPEN_STOP_RECORDING_MODAL, channelID),
- onOpenStopRecordingModal: (listener) => createListener(CALLS_WIDGET_OPEN_STOP_RECORDING_MODAL, listener),
+ openCallsUserSettings: () => ipcRenderer.send(CALLS_WIDGET_OPEN_USER_SETTINGS),
+ onOpenCallsUserSettings: (listener) => createListener(CALLS_WIDGET_OPEN_USER_SETTINGS, listener),
- openCallsUserSettings: () => ipcRenderer.send(CALLS_WIDGET_OPEN_USER_SETTINGS),
- onOpenCallsUserSettings: (listener) => createListener(CALLS_WIDGET_OPEN_USER_SETTINGS, listener),
+ onSendMetrics: (listener) => createListener(METRICS_SEND, listener),
- onSendMetrics: (listener) => createListener(METRICS_SEND, listener),
-
- // Utility
- unregister: (channel) => ipcRenderer.removeAllListeners(channel),
- };
- contextBridge.exposeInMainWorld('desktopAPI', desktopAPI);
-});
+ // Utility
+ unregister: (channel) => ipcRenderer.removeAllListeners(channel),
+};
+contextBridge.exposeInMainWorld('desktopAPI', desktopAPI);
ipcRenderer.on(METRICS_REQUEST, async (_, name, serverId) => {
const memory = await process.getProcessMemoryInfo();
@@ -203,319 +179,3 @@ const CLEAR_CACHE_INTERVAL = 6 * 60 * 60 * 1000; // 6 hours
setInterval(() => {
webFrame.clearCache();
}, CLEAR_CACHE_INTERVAL);
-
-ipcRenderer.invoke(GET_DEVELOPER_MODE_SETTING, 'forceNewAPI').then((force) => {
- if (force) {
- return;
- }
-
- /****************************************************************************
- * LEGACY CODE BELOW
- * All of this code is deprecated and should be removed eventually
- * Current it is there to support older versions of the web app
- ****************************************************************************
- */
-
- /**
- * Legacy helper functions
- */
-
- const onLoad = () => {
- if (document.getElementById('root') === null) {
- console.warn('The guest is not assumed as mattermost-webapp');
- return;
- }
- watchReactAppUntilInitialized(() => {
- console.warn('Legacy preload initialized');
- ipcRenderer.send(REACT_APP_INITIALIZED);
- ipcRenderer.invoke(REQUEST_BROWSER_HISTORY_STATUS).then(sendHistoryButtonReturn);
- });
- };
-
- const onStorageChanged = (e: StorageEvent) => {
- if (e.key === '__login__' && e.storageArea === localStorage && e.newValue) {
- ipcRenderer.send(APP_LOGGED_IN);
- }
- if (e.key === '__logout__' && e.storageArea === localStorage && e.newValue) {
- ipcRenderer.send(APP_LOGGED_OUT);
- }
- };
-
- const isReactAppInitialized = () => {
- const initializedRoot =
- document.querySelector('#root.channel-view') || // React 16 webapp
- document.querySelector('#root .signup-team__container') || // React 16 login
- document.querySelector('div[data-reactroot]'); // Older React apps
- if (initializedRoot === null) {
- return false;
- }
- return initializedRoot.children.length !== 0;
- };
-
- const watchReactAppUntilInitialized = (callback: () => void) => {
- let count = 0;
- const interval = 500;
- const timeout = 30000;
- const timer = setInterval(() => {
- count += interval;
- if (isReactAppInitialized() || count >= timeout) { // assumed as webapp has been initialized.
- clearTimeout(timer);
- callback();
- }
- }, interval);
- };
-
- const checkUnread = () => {
- if (isReactAppInitialized()) {
- findUnread();
- } else {
- watchReactAppUntilInitialized(() => {
- findUnread();
- });
- }
- };
-
- const findUnread = () => {
- const classes = ['team-container unread', 'SidebarChannel unread', 'sidebar-item unread-title'];
- const isUnread = classes.some((classPair) => {
- const result = document.getElementsByClassName(classPair);
- return result && result.length > 0;
- });
- ipcRenderer.send(UNREAD_RESULT, isUnread);
- };
-
- let sessionExpired: boolean;
- const getUnreadCount = () => {
- // LHS not found => Log out => Count should be 0, but session may be expired.
- let isExpired;
- if (document.getElementById('sidebar-left') === null) {
- const extraParam = (new URLSearchParams(window.location.search)).get('extra');
- isExpired = extraParam === 'expired';
- } else {
- isExpired = false;
- }
- if (isExpired !== sessionExpired) {
- sessionExpired = isExpired;
- ipcRenderer.send(SESSION_EXPIRED, sessionExpired);
- }
- };
-
- /**
- * Legacy message passing code - can be running alongside the new API stuff
- */
-
- // Disabling no-explicit-any for this legacy code
- // eslint-disable-next-line @typescript-eslint/no-explicit-any
- window.addEventListener('message', ({origin, data = {}}: {origin?: string; data?: {type?: string; message?: any}} = {}) => {
- const {type, message = {}} = data;
- if (origin !== window.location.origin) {
- return;
- }
- switch (type) {
- case 'webapp-ready':
- case 'get-app-version': {
- // register with the webapp to enable custom integration functionality
- ipcRenderer.invoke(GET_APP_INFO).then((info) => {
- console.log(`registering ${info.name} v${info.version} with the server`);
- window.postMessage(
- {
- type: 'register-desktop',
- message: info,
- },
- window.location.origin || '*',
- );
- });
- break;
- }
- case 'dispatch-notification': {
- const {title, body, channel, teamId, url, silent, data: messageData} = message;
- channels.set(channel.id, channel);
- ipcRenderer.invoke(NOTIFY_MENTION, title, body, channel.id, teamId, url, silent, messageData.soundName);
- break;
- }
- case BROWSER_HISTORY_PUSH: {
- const {path} = message as {path: string};
- ipcRenderer.send(BROWSER_HISTORY_PUSH, path);
- break;
- }
- case 'history-button': {
- ipcRenderer.invoke(REQUEST_BROWSER_HISTORY_STATUS).then(sendHistoryButtonReturn);
- break;
- }
- case CALLS_LINK_CLICK: {
- ipcRenderer.send(CALLS_LINK_CLICK, message.link);
- break;
- }
- case GET_DESKTOP_SOURCES: {
- ipcRenderer.invoke(GET_DESKTOP_SOURCES, message).then(sendDesktopSourcesResult);
- break;
- }
- case CALLS_WIDGET_SHARE_SCREEN: {
- ipcRenderer.send(CALLS_WIDGET_SHARE_SCREEN, message.sourceID, message.withAudio);
- break;
- }
- case CALLS_JOIN_CALL: {
- ipcRenderer.invoke(CALLS_JOIN_CALL, message).then(sendCallsJoinedCall);
- break;
- }
- case CALLS_JOINED_CALL: {
- ipcRenderer.send(CALLS_JOINED_CALL, message.callID, message.sessionID);
- break;
- }
- case CALLS_JOIN_REQUEST: {
- ipcRenderer.send(CALLS_JOIN_REQUEST, message.callID);
- break;
- }
- case CALLS_WIDGET_RESIZE: {
- ipcRenderer.send(CALLS_WIDGET_RESIZE, message.width, message.height);
- break;
- }
- case CALLS_ERROR: {
- ipcRenderer.send(CALLS_ERROR, message.err, message.callID, message.errMsg);
- break;
- }
- case CALLS_WIDGET_CHANNEL_LINK_CLICK:
- case CALLS_LEAVE_CALL:
- case DESKTOP_SOURCES_MODAL_REQUEST:
- case CALLS_POPOUT_FOCUS: {
- ipcRenderer.send(type);
- }
- }
- });
-
- // Legacy support to hold the full channel object so that it can be used for the click event
- const channels: Map = new Map();
- ipcRenderer.on(NOTIFICATION_CLICKED, (event, channelId, teamId, url) => {
- const channel = channels.get(channelId) ?? {id: channelId};
- channels.delete(channelId);
- window.postMessage(
- {
- type: NOTIFICATION_CLICKED,
- message: {
- channel,
- teamId,
- url,
- },
- },
- window.location.origin,
- );
- });
-
- ipcRenderer.on(BROWSER_HISTORY_PUSH, (event, pathName) => {
- window.postMessage(
- {
- type: 'browser-history-push-return',
- message: {
- pathName,
- },
- },
- window.location.origin,
- );
- });
-
- const sendHistoryButtonReturn = (status: {canGoBack: boolean; canGoForward: boolean}) => {
- window.postMessage(
- {
- type: 'history-button-return',
- message: {
- enableBack: status.canGoBack,
- enableForward: status.canGoForward,
- },
- },
- window.location.origin,
- );
- };
-
- ipcRenderer.on(BROWSER_HISTORY_STATUS_UPDATED, (event, canGoBack, canGoForward) => sendHistoryButtonReturn({canGoBack, canGoForward}));
-
- const sendDesktopSourcesResult = (sources: Array<{
- id: string;
- name: string;
- thumbnailURL: string;
- }>) => {
- window.postMessage(
- {
- type: DESKTOP_SOURCES_RESULT,
- message: sources,
- },
- window.location.origin,
- );
- };
-
- const sendCallsJoinedCall = (message: {callID: string; sessionID: string}) => {
- window.postMessage(
- {
- type: CALLS_JOINED_CALL,
- message,
- },
- window.location.origin,
- );
- };
-
- ipcRenderer.on(CALLS_JOIN_REQUEST, (_, callID) => {
- window.postMessage(
- {
- type: CALLS_JOIN_REQUEST,
- message: {callID},
- },
- window.location.origin,
- );
- });
-
- ipcRenderer.on(DESKTOP_SOURCES_MODAL_REQUEST, () => {
- window.postMessage(
- {
- type: DESKTOP_SOURCES_MODAL_REQUEST,
- },
- window.location.origin,
- );
- });
-
- ipcRenderer.on(CALLS_WIDGET_SHARE_SCREEN, (_, sourceID, withAudio) => {
- window.postMessage(
- {
- type: CALLS_WIDGET_SHARE_SCREEN,
- message: {sourceID, withAudio},
- },
- window.location.origin,
- );
- });
-
- ipcRenderer.on(CALLS_ERROR, (_, err, callID, errMsg) => {
- window.postMessage(
- {
- type: CALLS_ERROR,
- message: {err, callID, errMsg},
- },
- window.location.origin,
- );
- });
-
- // push user activity updates to the webapp
- ipcRenderer.on(USER_ACTIVITY_UPDATE, (event, userIsActive, isSystemEvent) => {
- if (window.location.origin !== 'null') {
- window.postMessage({type: USER_ACTIVITY_UPDATE, message: {userIsActive, manual: isSystemEvent}}, window.location.origin);
- }
- });
-
- /**
- * Legacy functionality that needs to be disabled with the new API
- */
-
- legacyEnabled = true;
- ipcRenderer.on(IS_UNREAD, checkUnread);
- const unreadInterval = setInterval(getUnreadCount, 1000);
- window.addEventListener('storage', onStorageChanged);
- window.addEventListener('load', onLoad);
-
- legacyOff = () => {
- ipcRenderer.send(LEGACY_OFF);
- ipcRenderer.off(IS_UNREAD, checkUnread);
- clearInterval(unreadInterval);
- window.removeEventListener('storage', onStorageChanged);
- window.removeEventListener('load', onLoad);
-
- legacyEnabled = false;
- console.log('New API preload initialized');
- };
-});
diff --git a/src/main/preload/internalAPI.js b/src/main/preload/internalAPI.js
index 4b0a4b57..d5bb4ad3 100644
--- a/src/main/preload/internalAPI.js
+++ b/src/main/preload/internalAPI.js
@@ -42,7 +42,6 @@ import {
PLAY_SOUND,
MODAL_OPEN,
MODAL_CLOSE,
- TOGGLE_BACK_BUTTON,
UPDATE_MENTIONS,
SHOW_DOWNLOADS_DROPDOWN_BUTTON_BADGE,
HIDE_DOWNLOADS_DROPDOWN_BUTTON_BADGE,
@@ -163,7 +162,6 @@ contextBridge.exposeInMainWorld('desktop', {
onPlaySound: (listener) => ipcRenderer.on(PLAY_SOUND, (_, soundName) => listener(soundName)),
onModalOpen: (listener) => ipcRenderer.on(MODAL_OPEN, () => listener()),
onModalClose: (listener) => ipcRenderer.on(MODAL_CLOSE, () => listener()),
- onToggleBackButton: (listener) => ipcRenderer.on(TOGGLE_BACK_BUTTON, (_, showExtraBar) => listener(showExtraBar)),
onUpdateMentions: (listener) => ipcRenderer.on(UPDATE_MENTIONS, (_event, view, mentions, unreads, isExpired) => listener(view, mentions, unreads, isExpired)),
onCloseServersDropdown: (listener) => ipcRenderer.on(CLOSE_SERVERS_DROPDOWN, () => listener()),
onOpenServersDropdown: (listener) => ipcRenderer.on(OPEN_SERVERS_DROPDOWN, () => listener()),
diff --git a/src/main/utils.test.js b/src/main/utils.test.js
index f6dd57ff..1f69d8a9 100644
--- a/src/main/utils.test.js
+++ b/src/main/utils.test.js
@@ -2,7 +2,7 @@
// See LICENSE.txt for license information.
'use strict';
-import {BACK_BAR_HEIGHT, TAB_BAR_HEIGHT} from 'common/utils/constants';
+import {TAB_BAR_HEIGHT} from 'common/utils/constants';
import * as Utils from './utils';
@@ -68,27 +68,6 @@ describe('main/utils', () => {
height: 400 - TAB_BAR_HEIGHT,
});
});
-
- it('should include back bar height when specified', () => {
- expect(Utils.getWindowBoundaries({
- getContentBounds: () => ({width: 500, height: 400}),
- }, true)).toStrictEqual({
- x: 0,
- y: TAB_BAR_HEIGHT + BACK_BAR_HEIGHT,
- width: 500,
- height: 400 - TAB_BAR_HEIGHT - BACK_BAR_HEIGHT,
- });
- });
- });
-
- describe('shouldHaveBackBar', () => {
- it('should have back bar for custom logins', () => {
- expect(Utils.shouldHaveBackBar(new URL('https://server-1.com'), new URL('https://server-1.com/login/sso/saml'))).toBe(true);
- });
-
- it('should not have back bar for regular login', () => {
- expect(Utils.shouldHaveBackBar(new URL('https://server-1.com'), new URL('https://server-1.com/login'))).toBe(false);
- });
});
describe('isStringWithLength', () => {
diff --git a/src/main/utils.ts b/src/main/utils.ts
index b98469cb..2696bf6d 100644
--- a/src/main/utils.ts
+++ b/src/main/utils.ts
@@ -11,8 +11,7 @@ const exec = promisify(execOriginal);
import type {BrowserWindow} from 'electron';
import {app} from 'electron';
-import {BACK_BAR_HEIGHT, customLoginRegexPaths, TAB_BAR_HEIGHT} from 'common/utils/constants';
-import {isAdminUrl, isPluginUrl, isTeamUrl, isUrlType, parseURL} from 'common/utils/url';
+import {TAB_BAR_HEIGHT} from 'common/utils/constants';
import type {Args} from 'types/args';
@@ -48,42 +47,20 @@ export function shouldBeHiddenOnStartup(parsedArgv: Args) {
return false;
}
-export function getWindowBoundaries(win: BrowserWindow, hasBackBar = false) {
+export function getWindowBoundaries(win: BrowserWindow) {
const {width, height} = win.getContentBounds();
- return getAdjustedWindowBoundaries(width, height, hasBackBar);
+ return getAdjustedWindowBoundaries(width, height);
}
-export function getAdjustedWindowBoundaries(width: number, height: number, hasBackBar = false) {
+export function getAdjustedWindowBoundaries(width: number, height: number) {
return {
x: 0,
- y: TAB_BAR_HEIGHT + (hasBackBar ? BACK_BAR_HEIGHT : 0),
+ y: TAB_BAR_HEIGHT,
width,
- height: height - TAB_BAR_HEIGHT - (hasBackBar ? BACK_BAR_HEIGHT : 0),
+ height: height - TAB_BAR_HEIGHT,
};
}
-export function shouldHaveBackBar(serverUrl: URL, inputURL: URL) {
- if (isUrlType('login', serverUrl, inputURL)) {
- const serverURL = parseURL(serverUrl);
- const subpath = serverURL ? serverURL.pathname : '';
- const parsedURL = parseURL(inputURL);
- if (!parsedURL) {
- return false;
- }
- const urlPath = parsedURL.pathname;
- const replacement = subpath.endsWith('/') ? '/' : '';
- const replacedPath = urlPath.replace(subpath, replacement);
- for (const regexPath of customLoginRegexPaths) {
- if (replacedPath.match(regexPath)) {
- return true;
- }
- }
-
- return false;
- }
- return !isTeamUrl(serverUrl, inputURL) && !isAdminUrl(serverUrl, inputURL) && !isPluginUrl(serverUrl, inputURL);
-}
-
export function getLocalPreload(file: string) {
return path.join(app.getAppPath(), file);
}
diff --git a/src/main/views/MattermostBrowserView.test.js b/src/main/views/MattermostBrowserView.test.js
index 49a35a92..ec01e09f 100644
--- a/src/main/views/MattermostBrowserView.test.js
+++ b/src/main/views/MattermostBrowserView.test.js
@@ -4,14 +4,13 @@
'use strict';
import AppState from 'common/appState';
-import {LOAD_FAILED, TOGGLE_BACK_BUTTON, UPDATE_TARGET_URL} from 'common/communication';
+import {LOAD_FAILED, UPDATE_TARGET_URL} from 'common/communication';
import {MattermostServer} from 'common/servers/MattermostServer';
import MessagingView from 'common/views/MessagingView';
import {MattermostBrowserView} from './MattermostBrowserView';
import ContextMenu from '../contextMenu';
-import Utils from '../utils';
import MainWindow from '../windows/mainWindow';
jest.mock('electron', () => ({
@@ -423,28 +422,6 @@ describe('main/views/MattermostBrowserView', () => {
});
});
- describe('handleDidNavigate', () => {
- const window = {on: jest.fn()};
- const mattermostView = new MattermostBrowserView(view, {}, {});
-
- beforeEach(() => {
- MainWindow.get.mockReturnValue(window);
- mattermostView.setBounds = jest.fn();
- });
-
- it('should hide back button on internal url', () => {
- Utils.shouldHaveBackBar.mockReturnValue(false);
- mattermostView.handleDidNavigate(null, 'http://server-1.com/path/to/channels');
- expect(MainWindow.sendToRenderer).toHaveBeenCalledWith(TOGGLE_BACK_BUTTON, false);
- });
-
- it('should show back button on external url', () => {
- Utils.shouldHaveBackBar.mockReturnValue(true);
- mattermostView.handleDidNavigate(null, 'http://server-2.com/some/other/path');
- expect(MainWindow.sendToRenderer).toHaveBeenCalledWith(TOGGLE_BACK_BUTTON, true);
- });
- });
-
describe('handleUpdateTarget', () => {
const window = {on: jest.fn()};
const mattermostView = new MattermostBrowserView(view, {}, {});
@@ -476,18 +453,4 @@ describe('main/views/MattermostBrowserView', () => {
expect(mattermostView.emit).toHaveBeenCalled();
});
});
-
- describe('updateMentionsFromTitle', () => {
- const mattermostView = new MattermostBrowserView(view, {}, {});
-
- it('should parse mentions from title', () => {
- mattermostView.updateMentionsFromTitle('(7) Mattermost');
- expect(AppState.updateMentions).toHaveBeenCalledWith(mattermostView.view.id, 7);
- });
-
- it('should parse unreads from title', () => {
- mattermostView.updateMentionsFromTitle('* Mattermost');
- expect(AppState.updateMentions).toHaveBeenCalledWith(mattermostView.view.id, 0);
- });
- });
});
diff --git a/src/main/views/MattermostBrowserView.ts b/src/main/views/MattermostBrowserView.ts
index 7ee8a3c0..1a5599cd 100644
--- a/src/main/views/MattermostBrowserView.ts
+++ b/src/main/views/MattermostBrowserView.ts
@@ -11,8 +11,6 @@ import {
LOAD_SUCCESS,
LOAD_FAILED,
UPDATE_TARGET_URL,
- IS_UNREAD,
- TOGGLE_BACK_BUTTON,
LOADSCREEN_END,
SERVERS_URL_MODIFIED,
BROWSER_HISTORY_STATUS_UPDATED,
@@ -32,7 +30,7 @@ import MainWindow from 'main/windows/mainWindow';
import WebContentsEventManager from './webContentEvents';
import ContextMenu from '../contextMenu';
-import {getWindowBoundaries, getLocalPreload, composeUserAgent, shouldHaveBackBar} from '../utils';
+import {getWindowBoundaries, getLocalPreload, composeUserAgent} from '../utils';
enum Status {
LOADING,
@@ -41,9 +39,6 @@ enum Status {
ERROR = -1,
}
-const MENTIONS_GROUP = 2;
-const titleParser = /(\((\d+)\) )?(\* )?/g;
-
export class MattermostBrowserView extends EventEmitter {
view: MattermostView;
isVisible: boolean;
@@ -84,7 +79,6 @@ export class MattermostBrowserView extends EventEmitter {
this.log.verbose('View created');
this.browserView.webContents.on('update-target-url', this.handleUpdateTarget);
- this.browserView.webContents.on('did-navigate', this.handleDidNavigate);
if (process.platform !== 'darwin') {
this.browserView.webContents.on('before-input-event', this.handleInputEvents);
}
@@ -95,10 +89,6 @@ export class MattermostBrowserView extends EventEmitter {
}
});
- // Legacy handlers using the title/favicon
- this.browserView.webContents.on('page-title-updated', this.handleTitleUpdate);
- this.browserView.webContents.on('page-favicon-updated', this.handleFaviconUpdate);
-
WebContentsEventManager.addWebContentsEventListeners(this.browserView.webContents);
if (!DeveloperMode.get('disableContextMenu')) {
@@ -233,7 +223,7 @@ export class MattermostBrowserView extends EventEmitter {
this.isVisible = true;
mainWindow.addBrowserView(this.browserView);
mainWindow.setTopBrowserView(this.browserView);
- this.setBounds(getWindowBoundaries(mainWindow, shouldHaveBackBar(this.view.url || '', this.currentURL)));
+ this.setBounds(getWindowBoundaries(mainWindow));
if (this.status === Status.READY) {
this.focus();
}
@@ -280,15 +270,6 @@ export class MattermostBrowserView extends EventEmitter {
}
};
- /**
- * Code to turn off the old method of getting unreads
- * Newer web apps will send the mentions/unreads directly
- */
- offLegacyUnreads = () => {
- this.browserView.webContents.off('page-title-updated', this.handleTitleUpdate);
- this.browserView.webContents.off('page-favicon-updated', this.handleFaviconUpdate);
- };
-
/**
* Status hooks
*/
@@ -393,41 +374,6 @@ export class MattermostBrowserView extends EventEmitter {
}
};
- /**
- * Unreads/mentions handlers
- */
-
- private updateMentionsFromTitle = (title: string) => {
- const resultsIterator = title.matchAll(titleParser);
- const results = resultsIterator.next(); // we are only interested in the first set
- const mentions = (results && results.value && parseInt(results.value[MENTIONS_GROUP], 10)) || 0;
-
- AppState.updateMentions(this.id, mentions);
- };
-
- // if favicon is null, it will affect appState, but won't be memoized
- private findUnreadState = (favicon: string | null) => {
- try {
- this.browserView.webContents.send(IS_UNREAD, favicon, this.id);
- } catch (err: any) {
- this.log.error('There was an error trying to request the unread state', err);
- }
- };
-
- private handleTitleUpdate = (e: Event, title: string) => {
- this.log.debug('handleTitleUpdate', title);
-
- this.updateMentionsFromTitle(title);
- };
-
- private handleFaviconUpdate = (e: Event, favicons: string[]) => {
- this.log.silly('handleFaviconUpdate', favicons);
-
- // if unread state is stored for that favicon, retrieve value.
- // if not, get related info from preload and store it for future changes
- this.findUnreadState(favicons[0]);
- };
-
/**
* Loading/retry logic
*/
@@ -486,16 +432,12 @@ export class MattermostBrowserView extends EventEmitter {
this.log.verbose(`finished loading ${loadURL}`);
MainWindow.sendToRenderer(LOAD_SUCCESS, this.id);
this.maxRetries = MAX_SERVER_RETRIES;
- if (this.status === Status.LOADING) {
- this.updateMentionsFromTitle(this.browserView.webContents.getTitle());
- this.findUnreadState(null);
- }
this.status = Status.WAITING_MM;
this.removeLoading = setTimeout(this.setInitialized, MAX_LOADING_SCREEN_SECONDS, true);
this.emit(LOAD_SUCCESS, this.id, loadURL);
const mainWindow = MainWindow.get();
if (mainWindow && this.currentURL) {
- this.setBounds(getWindowBoundaries(mainWindow, shouldHaveBackBar(this.view.url || '', this.currentURL)));
+ this.setBounds(getWindowBoundaries(mainWindow));
}
};
};
@@ -504,29 +446,6 @@ export class MattermostBrowserView extends EventEmitter {
* WebContents event handlers
*/
- private handleDidNavigate = (event: Event, url: string) => {
- this.log.debug('handleDidNavigate', url);
-
- const mainWindow = MainWindow.get();
- if (!mainWindow) {
- return;
- }
- const parsedURL = parseURL(url);
- if (!parsedURL) {
- return;
- }
-
- if (shouldHaveBackBar(this.view.url || '', parsedURL)) {
- this.setBounds(getWindowBoundaries(mainWindow, true));
- MainWindow.sendToRenderer(TOGGLE_BACK_BUTTON, true);
- this.log.debug('show back button');
- } else {
- this.setBounds(getWindowBoundaries(mainWindow));
- MainWindow.sendToRenderer(TOGGLE_BACK_BUTTON, false);
- this.log.debug('hide back button');
- }
- };
-
private handleUpdateTarget = (e: Event, url: string) => {
this.log.silly('handleUpdateTarget', e, url);
const parsedURL = parseURL(url);
diff --git a/src/main/views/viewManager.ts b/src/main/views/viewManager.ts
index c2147fac..14357687 100644
--- a/src/main/views/viewManager.ts
+++ b/src/main/views/viewManager.ts
@@ -18,10 +18,7 @@ import {
UPDATE_URL_VIEW_WIDTH,
SERVERS_UPDATE,
REACT_APP_INITIALIZED,
- APP_LOGGED_OUT,
- APP_LOGGED_IN,
RELOAD_CURRENT_VIEW,
- UNREAD_RESULT,
HISTORY,
GET_VIEW_INFO_FOR_TEST,
SESSION_EXPIRED,
@@ -31,7 +28,6 @@ import {
SWITCH_TAB,
GET_IS_DEV_MODE,
REQUEST_BROWSER_HISTORY_STATUS,
- LEGACY_OFF,
UNREADS_AND_MENTIONS,
TAB_LOGIN_CHANGED,
DEVELOPER_MODE_UPDATED,
@@ -58,7 +54,7 @@ import LoadingScreen from './loadingScreen';
import {MattermostBrowserView} from './MattermostBrowserView';
import modalManager from './modalManager';
-import {getLocalPreload, getAdjustedWindowBoundaries, shouldHaveBackBar} from '../utils';
+import {getLocalPreload, getAdjustedWindowBoundaries} from '../utils';
const log = new Logger('ViewManager');
const URL_VIEW_DURATION = 10 * SECOND;
@@ -84,14 +80,10 @@ export class ViewManager {
ipcMain.on(HISTORY, this.handleHistory);
ipcMain.on(REACT_APP_INITIALIZED, this.handleReactAppInitialized);
ipcMain.on(BROWSER_HISTORY_PUSH, this.handleBrowserHistoryPush);
- ipcMain.on(APP_LOGGED_IN, this.handleAppLoggedIn);
- ipcMain.on(APP_LOGGED_OUT, this.handleAppLoggedOut);
ipcMain.on(TAB_LOGIN_CHANGED, this.handleTabLoginChanged);
ipcMain.on(RELOAD_CURRENT_VIEW, this.handleReloadCurrentView);
- ipcMain.on(UNREAD_RESULT, this.handleUnreadChanged);
ipcMain.on(UNREADS_AND_MENTIONS, this.handleUnreadsAndMentionsChanged);
ipcMain.on(SESSION_EXPIRED, this.handleSessionExpired);
- ipcMain.on(LEGACY_OFF, this.handleLegacyOff);
ipcMain.on(SWITCH_TAB, (event, viewId) => this.showById(viewId));
@@ -108,7 +100,7 @@ export class ViewManager {
private handleDeveloperModeUpdated = (json: DeveloperSettings) => {
log.debug('handleDeveloperModeUpdated', json);
- if (['browserOnly', 'disableContextMenu', 'forceLegacyAPI', 'forceNewAPI'].some((key) => Object.hasOwn(json, key))) {
+ if (['browserOnly', 'disableContextMenu'].some((key) => Object.hasOwn(json, key))) {
this.views.forEach((view) => view.destroy());
this.views = new Map();
this.closedViews = new Map();
@@ -504,27 +496,6 @@ export class ViewManager {
this.getCurrentView()?.goToOffset(offset);
};
- private handleAppLoggedIn = (event: IpcMainEvent) => {
- log.debug('handleAppLoggedIn', event.sender.id);
- const view = this.getViewByWebContentsId(event.sender.id);
- if (!view) {
- return;
- }
- view.onLogin(true);
- flushCookiesStore();
- };
-
- private handleAppLoggedOut = (event: IpcMainEvent) => {
- log.debug('handleAppLoggedOut', event.sender.id);
- const view = this.getViewByWebContentsId(event.sender.id);
- if (!view) {
- return;
- }
- view.onLogin(false);
- AppState.clear(view.id);
- flushCookiesStore();
- };
-
private handleTabLoginChanged = (event: IpcMainEvent, loggedIn: boolean) => {
log.debug('handleTabLoggedIn', event.sender.id);
const view = this.getViewByWebContentsId(event.sender.id);
@@ -605,28 +576,6 @@ export class ViewManager {
this.showById(view?.id);
};
- private handleLegacyOff = (e: IpcMainEvent) => {
- log.silly('handleLegacyOff', {webContentsId: e.sender.id});
-
- const view = this.getViewByWebContentsId(e.sender.id);
- if (!view) {
- return;
- }
- view.offLegacyUnreads();
- };
-
- // 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 handleUnreadChanged = (e: IpcMainEvent, result: boolean) => {
- log.silly('handleUnreadChanged', {webContentsId: e.sender.id, result});
-
- const view = this.getViewByWebContentsId(e.sender.id);
- if (!view) {
- return;
- }
- AppState.updateUnreads(view.id, result);
- };
-
private handleUnreadsAndMentionsChanged = (e: IpcMainEvent, isUnread: boolean, mentionCount: number) => {
log.silly('handleUnreadsAndMentionsChanged', {webContentsId: e.sender.id, isUnread, mentionCount});
@@ -653,7 +602,7 @@ export class ViewManager {
const currentView = this.getCurrentView();
if (currentView && currentView.currentURL) {
- const adjustedBounds = getAdjustedWindowBoundaries(newBounds.width, newBounds.height, shouldHaveBackBar(currentView.view.url, currentView.currentURL));
+ const adjustedBounds = getAdjustedWindowBoundaries(newBounds.width, newBounds.height);
currentView.setBounds(adjustedBounds);
}
};
diff --git a/src/main/views/webContentEvents.test.js b/src/main/views/webContentEvents.test.js
index c64c7acb..392ef5e7 100644
--- a/src/main/views/webContentEvents.test.js
+++ b/src/main/views/webContentEvents.test.js
@@ -95,27 +95,11 @@ describe('main/views/webContentsEvents', () => {
expect(event.preventDefault).not.toBeCalled();
});
- it('should allow navigation when isCustomLoginURL', () => {
- willNavigate(event, 'http://server-1.com/oauth/authorize');
- expect(event.preventDefault).not.toBeCalled();
- });
-
- it('should not allow navigation when isCustomLoginURL is external', () => {
- willNavigate(event, 'http://loginurl.com/oauth/authorize');
- expect(event.preventDefault).toBeCalled();
- });
-
it('should allow navigation when protocol is mailto', () => {
willNavigate(event, 'mailto:test@mattermost.com');
expect(event.preventDefault).not.toBeCalled();
});
- it('should allow navigation when a custom login is in progress', () => {
- webContentsEventManager.customLogins[1] = {inProgress: true};
- willNavigate(event, 'http://anyoldurl.com');
- expect(event.preventDefault).not.toBeCalled();
- });
-
it('should allow navigation when it isChannelExportUrl', () => {
willNavigate(event, 'http://server-1.com/plugins/com.mattermost.plugin-channel-export/api/v1/export');
expect(event.preventDefault).not.toBeCalled();
@@ -127,32 +111,6 @@ describe('main/views/webContentsEvents', () => {
});
});
- describe('didStartNavigation', () => {
- const webContentsEventManager = new WebContentsEventManager();
- const didStartNavigation = webContentsEventManager.generateDidStartNavigation(1);
-
- beforeEach(() => {
- webContentsEventManager.getServerURLFromWebContentsId = jest.fn().mockImplementation(() => new URL('http://server-1.com'));
- });
-
- afterEach(() => {
- jest.clearAllMocks();
- webContentsEventManager.customLogins = {};
- });
-
- it('should add custom login entry on custom login URL', () => {
- webContentsEventManager.customLogins[1] = {inProgress: false};
- didStartNavigation(event, 'http://server-1.com/oauth/authorize');
- expect(webContentsEventManager.customLogins[1]).toStrictEqual({inProgress: true});
- });
-
- it('should remove custom login entry once navigating back to internal URL', () => {
- webContentsEventManager.customLogins[1] = {inProgress: true};
- didStartNavigation(event, 'http://server-1.com/subpath');
- expect(webContentsEventManager.customLogins[1]).toStrictEqual({inProgress: false});
- });
- });
-
describe('newWindow', () => {
const webContentsEventManager = new WebContentsEventManager();
const newWindow = webContentsEventManager.generateNewWindowListener(1, true);
diff --git a/src/main/views/webContentEvents.ts b/src/main/views/webContentEvents.ts
index 30144010..bfa6e7fe 100644
--- a/src/main/views/webContentEvents.ts
+++ b/src/main/views/webContentEvents.ts
@@ -11,7 +11,6 @@ import {
isAdminUrl,
isCallsPopOutURL,
isChannelExportUrl,
- isCustomLoginURL,
isHelpUrl,
isImageProxyUrl,
isInternalURL,
@@ -20,11 +19,9 @@ import {
isPluginUrl,
isPublicFilesUrl,
isTeamUrl,
- isTrustedURL,
isValidURI,
parseURL,
} from 'common/utils/url';
-import {flushCookiesStore} from 'main/app/utils';
import ContextMenu from 'main/contextMenu';
import PluginsPopUpsManager from 'main/views/pluginsPopUps';
import ViewManager from 'main/views/viewManager';
@@ -36,19 +33,13 @@ import {generateHandleConsoleMessage, isCustomProtocol} from './webContentEvents
import allowProtocolDialog from '../allowProtocolDialog';
import {composeUserAgent} from '../utils';
-type CustomLogin = {
- inProgress: boolean;
-}
-
const log = new Logger('WebContentsEventManager');
export class WebContentsEventManager {
- customLogins: Record;
listeners: Record void>;
popupWindow?: {win: BrowserWindow; serverURL?: URL};
constructor() {
- this.customLogins = {};
this.listeners = {};
}
@@ -101,16 +92,9 @@ export class WebContentsEventManager {
return;
}
- if (serverURL && isCustomLoginURL(parsedURL, serverURL)) {
- return;
- }
if (parsedURL.protocol === 'mailto:') {
return;
}
- if (this.customLogins[webContentsId]?.inProgress) {
- flushCookiesStore();
- return;
- }
const callID = CallsWidgetWindow.callID;
if (serverURL && callID && isCallsPopOutURL(serverURL, parsedURL, callID)) {
@@ -122,25 +106,6 @@ export class WebContentsEventManager {
};
};
- private generateDidStartNavigation = (webContentsId: number) => {
- return (event: Event, url: string) => {
- this.log(webContentsId).debug('did-start-navigation', url);
-
- const parsedURL = parseURL(url)!;
- const serverURL = this.getServerURLFromWebContentsId(webContentsId);
-
- if (!serverURL || !isTrustedURL(parsedURL, serverURL)) {
- return;
- }
-
- if (serverURL && isCustomLoginURL(parsedURL, serverURL)) {
- this.customLogins[webContentsId].inProgress = true;
- } else if (serverURL && this.customLogins[webContentsId].inProgress && isInternalURL(serverURL || new URL(''), parsedURL)) {
- this.customLogins[webContentsId].inProgress = false;
- }
- };
- };
-
private denyNewWindow = (details: Electron.HandlerDetails): {action: 'deny' | 'allow'} => {
this.log().warn(`Prevented popup window to open a new window to ${details.url}.`);
return {action: 'deny'};
@@ -239,9 +204,6 @@ export class WebContentsEventManager {
}),
serverURL,
};
- this.customLogins[this.popupWindow.win.webContents.id] = {
- inProgress: false,
- };
popup = this.popupWindow.win;
popup.webContents.on('will-redirect', (event, url) => {
@@ -256,7 +218,6 @@ export class WebContentsEventManager {
}
});
popup.webContents.on('will-navigate', this.generateWillNavigate(popup.webContents.id));
- popup.webContents.on('did-start-navigation', this.generateDidStartNavigation(popup.webContents.id));
popup.webContents.setWindowOpenHandler(this.denyNewWindow);
popup.once('closed', () => {
this.popupWindow = undefined;
@@ -304,11 +265,6 @@ export class WebContentsEventManager {
addListeners?: (contents: WebContents) => void,
removeListeners?: (contents: WebContents) => void,
) => {
- // initialize custom login tracking
- this.customLogins[contents.id] = {
- inProgress: false,
- };
-
if (this.listeners[contents.id]) {
this.removeWebContentsListeners(contents.id);
}
@@ -316,14 +272,6 @@ export class WebContentsEventManager {
const willNavigate = this.generateWillNavigate(contents.id);
contents.on('will-navigate', willNavigate);
- // handle custom login requests (oath, saml):
- // 1. are we navigating to a supported local custom login path from the `/login` page?
- // - indicate custom login is in progress
- // 2. are we finished with the custom login process?
- // - indicate custom login is NOT in progress
- const didStartNavigation = this.generateDidStartNavigation(contents.id);
- contents.on('did-start-navigation', didStartNavigation);
-
const spellcheck = Config.useSpellChecker;
const newWindow = this.generateNewWindowListener(contents.id, spellcheck);
contents.setWindowOpenHandler(newWindow);
@@ -340,7 +288,6 @@ export class WebContentsEventManager {
const removeWebContentsListeners = () => {
try {
contents.removeListener('will-navigate', willNavigate);
- contents.removeListener('did-start-navigation', didStartNavigation);
contents.removeListener('console-message', consoleMessage);
removeListeners?.(contents);
} catch (e) {
diff --git a/src/main/windows/callsWidgetWindow.test.js b/src/main/windows/callsWidgetWindow.test.js
index 8630af2f..9efe2203 100644
--- a/src/main/windows/callsWidgetWindow.test.js
+++ b/src/main/windows/callsWidgetWindow.test.js
@@ -784,74 +784,6 @@ describe('main/windows/callsWidgetWindow', () => {
});
});
- describe('handleCallsWidgetChannelLinkClick', () => {
- const callsWidgetWindow = new CallsWidgetWindow();
- callsWidgetWindow.win = {webContents: {id: 1}};
- callsWidgetWindow.mainView = {
- view: {
- server: {
- id: 'server-2',
- },
- },
- sendToRenderer: jest.fn(),
- };
- callsWidgetWindow.getChannelURL = jest.fn();
- const servers = [
- {
- name: 'server-1',
- order: 1,
- views: [
- {
- name: 'view-1',
- order: 0,
- isOpen: false,
- },
- {
- name: 'view-2',
- order: 2,
- isOpen: true,
- },
- ],
- }, {
- name: 'server-2',
- order: 0,
- views: [
- {
- name: 'view-1',
- order: 0,
- isOpen: false,
- },
- {
- name: 'view-2',
- order: 2,
- isOpen: true,
- },
- ],
- lastActiveView: 2,
- },
- ];
- const map = servers.reduce((arr, item) => {
- item.views.forEach((view) => {
- arr.push([`${item.name}_${view.name}`, {}]);
- });
- return arr;
- }, []);
- const views = new Map(map);
-
- beforeEach(() => {
- ViewManager.getView.mockImplementation((viewId) => views.get(viewId));
- });
-
- afterEach(() => {
- jest.resetAllMocks();
- });
-
- it('should switch server', () => {
- callsWidgetWindow.handleCallsWidgetChannelLinkClick({sender: {id: 1}});
- expect(ServerViewState.switchServer).toHaveBeenCalledWith('server-2');
- });
- });
-
describe('forwardToMainApp', () => {
const view = {
view: {
diff --git a/src/main/windows/callsWidgetWindow.ts b/src/main/windows/callsWidgetWindow.ts
index 3ae9f8eb..7afaea53 100644
--- a/src/main/windows/callsWidgetWindow.ts
+++ b/src/main/windows/callsWidgetWindow.ts
@@ -14,7 +14,6 @@ import {
CALLS_LEAVE_CALL,
CALLS_LINK_CLICK,
CALLS_POPOUT_FOCUS,
- CALLS_WIDGET_CHANNEL_LINK_CLICK,
CALLS_WIDGET_RESIZE,
CALLS_WIDGET_SHARE_SCREEN,
CALLS_WIDGET_OPEN_THREAD,
@@ -80,9 +79,6 @@ export class CallsWidgetWindow {
ipcMain.on(CALLS_WIDGET_OPEN_THREAD, this.handleCallsOpenThread);
ipcMain.on(CALLS_WIDGET_OPEN_STOP_RECORDING_MODAL, this.handleCallsOpenStopRecordingModal);
ipcMain.on(CALLS_WIDGET_OPEN_USER_SETTINGS, this.forwardToMainApp(CALLS_WIDGET_OPEN_USER_SETTINGS));
-
- // deprecated in favour of CALLS_LINK_CLICK
- ipcMain.on(CALLS_WIDGET_CHANNEL_LINK_CLICK, this.handleCallsWidgetChannelLinkClick);
}
/**
@@ -555,25 +551,6 @@ export class CallsWidgetWindow {
MainWindow.get()?.focus();
this.mainView?.sendToRenderer(BROWSER_HISTORY_PUSH, url);
};
-
- /**
- * @deprecated
- */
- private handleCallsWidgetChannelLinkClick = (event: IpcMainEvent) => {
- log.debug('handleCallsWidgetChannelLinkClick');
-
- if (!this.isCallsWidget(event.sender.id)) {
- return;
- }
-
- if (!this.serverID) {
- return;
- }
-
- ServerViewState.switchServer(this.serverID);
- MainWindow.get()?.focus();
- this.mainView?.sendToRenderer(BROWSER_HISTORY_PUSH, this.options?.channelURL);
- };
}
const callsWidgetWindow = new CallsWidgetWindow();
diff --git a/src/renderer/components/ExtraBar.tsx b/src/renderer/components/ExtraBar.tsx
deleted file mode 100644
index d841362b..00000000
--- a/src/renderer/components/ExtraBar.tsx
+++ /dev/null
@@ -1,53 +0,0 @@
-// Copyright (c) 2016-present Mattermost, Inc. All Rights Reserved.
-// See LICENSE.txt for license information.
-
-import React from 'react';
-import {Row, Button} from 'react-bootstrap';
-import {FormattedMessage} from 'react-intl';
-
-type Props = {
- darkMode?: boolean;
- goBack?: () => void;
- show?: boolean;
-};
-
-export default class ExtraBar extends React.PureComponent {
- handleBack = () => {
- if (this.props.goBack) {
- this.props.goBack();
- }
- };
- render() {
- let barClass = 'clear-mode';
- if (!this.props.show) {
- barClass = 'hidden';
- } else if (this.props.darkMode) {
- barClass = 'dark-mode';
- }
-
- return (
-
- );
- }
-}
diff --git a/src/renderer/components/MainPage.tsx b/src/renderer/components/MainPage.tsx
index ac6c4b28..0d669110 100644
--- a/src/renderer/components/MainPage.tsx
+++ b/src/renderer/components/MainPage.tsx
@@ -15,7 +15,6 @@ import type {DownloadedItems} from 'types/downloads';
import DeveloperModeIndicator from './DeveloperModeIndicator';
import DownloadsDropdownButton from './DownloadsDropdown/DownloadsDropdownButton';
import ErrorView from './ErrorView';
-import ExtraBar from './ExtraBar';
import ServerDropdownButton from './ServerDropdownButton';
import TabBar from './TabBar';
@@ -50,7 +49,6 @@ type State = {
tabViewStatus: Map;
modalOpen?: boolean;
fullScreen?: boolean;
- showExtraBar?: boolean;
isMenuOpen: boolean;
isDownloadsDropdownOpen: boolean;
showDownloadsBadge: boolean;
@@ -210,10 +208,6 @@ class MainPage extends React.PureComponent {
this.setState({modalOpen: false});
});
- window.desktop.onToggleBackButton((showExtraBar) => {
- this.setState({showExtraBar});
- });
-
window.desktop.onUpdateMentions((view, mentions, unreads, isExpired) => {
const {unreadCounts, mentionCounts, sessionsExpired} = this.state;
@@ -532,13 +526,6 @@ class MainPage extends React.PureComponent {
const viewsRow = (
- {
- window.desktop.goBack();
- }}
- />
{views()}
diff --git a/src/renderer/css/components/ExtraBar.css b/src/renderer/css/components/ExtraBar.css
deleted file mode 100644
index 57a67ce7..00000000
--- a/src/renderer/css/components/ExtraBar.css
+++ /dev/null
@@ -1,44 +0,0 @@
-#extra-bar {
- max-height: 76px;
- transition: max-height 0.25s ease;
- background-color: #f5f5f5;
- -webkit-font-smoothing: antialiased;
-}
-
-#extra-bar div {
- padding: 0 0.93em 0.2em;
-}
-
-#extra-bar.hidden {
- display: none;
-}
-
-#extra-bar.dark-mode {
- background: #1F1F1F;
-}
-
-#extra-bar.dark-mode .btn-link {
- color: rgba(243,243,243,0.7);
-}
-
-#extra-bar.dark-mode span.backLabel {
- color: rgba(243,243,243,0.7);
-}
-
-span.backLabel {
- font-family: "Open Sans", sans-serif;
- font-weight: normal;
- line-height: 30px;
- font-size: 14px;
- padding-top: 0px;
- padding-bottom: 0px;
- color: #166de0;
-}
-
-span.backIcon {
- margin-right: 4px;
-}
-
-.container-fluid button:first-child {
- padding-left: 0px;
-}
diff --git a/src/renderer/css/components/index.css b/src/renderer/css/components/index.css
index 44b9d518..bdce1efe 100644
--- a/src/renderer/css/components/index.css
+++ b/src/renderer/css/components/index.css
@@ -6,6 +6,5 @@
@import url("TabBar.css");
@import url("UpdaterPage.css");
@import url("CertificateModal.css");
-@import url("ExtraBar.css");
@import url("LoadingScreen.css");
@import url("LoadingAnimation.css");
diff --git a/src/types/settings.ts b/src/types/settings.ts
index c780b608..934427e7 100644
--- a/src/types/settings.ts
+++ b/src/types/settings.ts
@@ -14,6 +14,4 @@ export type DeveloperSettings = {
disableNotificationStorage?: boolean;
disableUserActivityMonitor?: boolean;
disableContextMenu?: boolean;
- forceLegacyAPI?: boolean;
- forceNewAPI?: boolean;
};
diff --git a/src/types/window.ts b/src/types/window.ts
index ec1af282..8b7f2e67 100644
--- a/src/types/window.ts
+++ b/src/types/window.ts
@@ -79,7 +79,6 @@ declare global {
onPlaySound: (listener: (soundName: string) => void) => void;
onModalOpen: (listener: () => void) => void;
onModalClose: (listener: () => void) => void;
- onToggleBackButton: (listener: (showExtraBar: boolean) => void) => void;
onUpdateMentions: (listener: (view: string, mentions: number, unreads: boolean, isExpired: boolean) => void) => void;
onCloseServersDropdown: (listener: () => void) => void;
onOpenServersDropdown: (listener: () => void) => void;