MM-62005 Change UrlView to always stay mounted (#3453)
* MM-62005 Change UrlView to always stay mounted * Rename message for URL view and corresponding methods * Change log level
This commit is contained in:
@@ -100,6 +100,7 @@ export const GET_MODAL_UNCLOSEABLE = 'get-modal-uncloseable';
|
||||
|
||||
export const UPDATE_PATHS = 'update-paths';
|
||||
|
||||
export const SET_URL_FOR_URL_VIEW = 'set-url-for-url-view';
|
||||
export const UPDATE_URL_VIEW_WIDTH = 'update-url-view-width';
|
||||
|
||||
export const OPEN_SERVER_EXTERNALLY = 'open-server-externally';
|
||||
|
@@ -100,6 +100,7 @@ import {
|
||||
LOAD_INCOMPATIBLE_SERVER,
|
||||
OPEN_SERVER_UPGRADE_LINK,
|
||||
OPEN_CHANGELOG_LINK,
|
||||
SET_URL_FOR_URL_VIEW,
|
||||
} from 'common/communication';
|
||||
|
||||
console.log('Preload initialized');
|
||||
@@ -188,6 +189,7 @@ contextBridge.exposeInMainWorld('desktop', {
|
||||
onUpdateDownloadsDropdown: (listener) => ipcRenderer.on(UPDATE_DOWNLOADS_DROPDOWN, (_, downloads, darkMode, windowBounds, item) => listener(downloads, darkMode, windowBounds, item)),
|
||||
onAppMenuWillClose: (listener) => ipcRenderer.on(APP_MENU_WILL_CLOSE, () => listener()),
|
||||
onFocusThreeDotMenu: (listener) => ipcRenderer.on(FOCUS_THREE_DOT_MENU, () => listener()),
|
||||
onSetURLForURLView: (listener) => ipcRenderer.on(SET_URL_FOR_URL_VIEW, (_, url) => listener(url)),
|
||||
updateURLViewWidth: (width) => ipcRenderer.send(UPDATE_URL_VIEW_WIDTH, width),
|
||||
openNotificationPreferences: () => ipcRenderer.send(OPEN_NOTIFICATION_PREFERENCES),
|
||||
openWindowsCameraPreferences: () => ipcRenderer.send(OPEN_WINDOWS_CAMERA_PREFERENCES),
|
||||
|
@@ -1,7 +1,7 @@
|
||||
// Copyright (c) 2016-present Mattermost, Inc. All Rights Reserved.
|
||||
// See LICENSE.txt for license information.
|
||||
|
||||
import type {IpcMainEvent, IpcMainInvokeEvent} from 'electron';
|
||||
import type {IpcMainEvent, IpcMainInvokeEvent, View} from 'electron';
|
||||
import {WebContentsView, ipcMain, shell} from 'electron';
|
||||
import isDev from 'electron-is-dev';
|
||||
|
||||
@@ -33,6 +33,7 @@ import {
|
||||
UNREADS_AND_MENTIONS,
|
||||
TAB_LOGIN_CHANGED,
|
||||
DEVELOPER_MODE_UPDATED,
|
||||
SET_URL_FOR_URL_VIEW,
|
||||
} from 'common/communication';
|
||||
import Config from 'common/config';
|
||||
import {DEFAULT_CHANGELOG_LINK} from 'common/constants';
|
||||
@@ -68,6 +69,7 @@ export class ViewManager {
|
||||
private views: Map<string, MattermostWebContentsView>;
|
||||
private currentView?: string;
|
||||
|
||||
private urlView?: WebContentsView;
|
||||
private urlViewCancel?: () => void;
|
||||
|
||||
constructor() {
|
||||
@@ -110,6 +112,8 @@ export class ViewManager {
|
||||
await this.initServer(currentServer);
|
||||
this.showInitial();
|
||||
}
|
||||
|
||||
this.initURLView();
|
||||
};
|
||||
|
||||
private initServer = async (server: MattermostServer) => {
|
||||
@@ -117,6 +121,24 @@ export class ViewManager {
|
||||
this.loadServer(server);
|
||||
};
|
||||
|
||||
private initURLView = () => {
|
||||
const mainWindow = MainWindow.get();
|
||||
if (!mainWindow) {
|
||||
return;
|
||||
}
|
||||
|
||||
const urlView = new WebContentsView({webPreferences: {preload: getLocalPreload('internalAPI.js')}});
|
||||
urlView.setBackgroundColor('#00000000');
|
||||
|
||||
urlView.webContents.loadURL('mattermost-desktop://renderer/urlView.html');
|
||||
|
||||
MainWindow.get()?.contentView.addChildView(urlView);
|
||||
|
||||
performanceMonitor.registerView('URLView', urlView.webContents);
|
||||
|
||||
this.urlView = urlView;
|
||||
};
|
||||
|
||||
private handleDeveloperModeUpdated = (json: DeveloperSettings) => {
|
||||
log.debug('handleDeveloperModeUpdated', json);
|
||||
|
||||
@@ -147,6 +169,17 @@ export class ViewManager {
|
||||
return this.closedViews.has(viewId);
|
||||
};
|
||||
|
||||
private isViewInFront = (view: View) => {
|
||||
const mainWindow = MainWindow.get();
|
||||
if (!mainWindow) {
|
||||
return false;
|
||||
}
|
||||
|
||||
const index = mainWindow.contentView.children.indexOf(view);
|
||||
const front = mainWindow.contentView.children.length - 1;
|
||||
return index === front;
|
||||
};
|
||||
|
||||
showById = (viewId: string) => {
|
||||
this.getViewLogger(viewId).debug('showById', viewId);
|
||||
|
||||
@@ -372,35 +405,24 @@ export class ViewManager {
|
||||
if (this.urlViewCancel) {
|
||||
this.urlViewCancel();
|
||||
}
|
||||
|
||||
if (url && url !== '') {
|
||||
const urlString = typeof url === 'string' ? url : url.toString();
|
||||
const urlView = new WebContentsView({webPreferences: {preload: getLocalPreload('internalAPI.js')}});
|
||||
urlView.setBackgroundColor('#00000000');
|
||||
const localURL = `mattermost-desktop://renderer/urlView.html?url=${encodeURIComponent(urlString)}`;
|
||||
performanceMonitor.registerView('URLView', urlView.webContents);
|
||||
urlView.webContents.loadURL(localURL);
|
||||
|
||||
// This is a workaround for an issue where the URL view would steal focus from the main window
|
||||
// See: https://github.com/electron/electron/issues/42339
|
||||
// @ts-expect-error Using an undocumented event that fires last when the URL view pops up
|
||||
urlView.webContents.once('ready-to-show', () => {
|
||||
log.debug('URL view focus prevented');
|
||||
this.getCurrentView()?.focus();
|
||||
});
|
||||
if (this.urlView && !this.isViewInFront(this.urlView)) {
|
||||
log.silly('moving URL view to front');
|
||||
MainWindow.get()?.contentView.addChildView(this.urlView);
|
||||
}
|
||||
|
||||
this.urlView?.webContents.send(SET_URL_FOR_URL_VIEW, urlString);
|
||||
this.urlView?.setVisible(true);
|
||||
|
||||
MainWindow.get()?.contentView.addChildView(urlView);
|
||||
const boundaries = this.views.get(this.currentView || '')?.getBounds() ?? MainWindow.getBounds();
|
||||
|
||||
const hideView = () => {
|
||||
delete this.urlViewCancel;
|
||||
try {
|
||||
mainWindow.contentView.removeChildView(urlView);
|
||||
} catch (e) {
|
||||
log.error('Failed to remove URL view', e);
|
||||
}
|
||||
|
||||
performanceMonitor.unregisterView(urlView.webContents.id);
|
||||
urlView.webContents.close();
|
||||
this.urlView?.setVisible(false);
|
||||
};
|
||||
|
||||
const adjustWidth = (event: IpcMainEvent, width: number) => {
|
||||
@@ -418,7 +440,7 @@ export class ViewManager {
|
||||
};
|
||||
|
||||
log.silly('showURLView.setBounds', boundaries, bounds);
|
||||
urlView.setBounds(bounds);
|
||||
this.urlView?.setBounds(bounds);
|
||||
};
|
||||
|
||||
ipcMain.on(UPDATE_URL_VIEW_WIDTH, adjustWidth);
|
||||
|
@@ -1,22 +1,32 @@
|
||||
// Copyright (c) 2016-present Mattermost, Inc. All Rights Reserved.
|
||||
// See LICENSE.txt for license information.
|
||||
|
||||
import React, {useEffect} from 'react';
|
||||
import React, {useEffect, useRef, useState} from 'react';
|
||||
|
||||
export default function UrlDescription(props: {url: string}) {
|
||||
const urlRef = React.createRef<HTMLDivElement>();
|
||||
export default function UrlDescription() {
|
||||
const urlRef = useRef<HTMLDivElement>(null);
|
||||
|
||||
const [url, setUrl] = useState<string | undefined>();
|
||||
|
||||
useEffect(() => {
|
||||
window.desktop.updateURLViewWidth(urlRef.current?.scrollWidth);
|
||||
window.desktop.onSetURLForURLView((newUrl) => {
|
||||
setUrl(newUrl);
|
||||
});
|
||||
}, []);
|
||||
|
||||
if (props.url) {
|
||||
useEffect(() => {
|
||||
if (url) {
|
||||
window.desktop.updateURLViewWidth(urlRef.current?.scrollWidth);
|
||||
}
|
||||
}, [url]);
|
||||
|
||||
if (url) {
|
||||
return (
|
||||
<div
|
||||
ref={urlRef}
|
||||
className='HoveringURL HoveringURL-left'
|
||||
>
|
||||
<p>{props.url}</p>
|
||||
<p>{url}</p>
|
||||
</div>
|
||||
);
|
||||
}
|
||||
|
@@ -3,9 +3,6 @@
|
||||
|
||||
import 'renderer/css/components/HoveringURL.css';
|
||||
|
||||
const queryString = window.location.search;
|
||||
const urlParams = new URLSearchParams(queryString);
|
||||
|
||||
import React from 'react';
|
||||
import ReactDOM from 'react-dom';
|
||||
|
||||
@@ -13,9 +10,7 @@ import UrlDescription from '../../components/urlDescription';
|
||||
|
||||
const start = async () => {
|
||||
ReactDOM.render(
|
||||
<UrlDescription
|
||||
url={decodeURIComponent(urlParams.get('url')!)}
|
||||
/>,
|
||||
<UrlDescription/>,
|
||||
document.getElementById('app'),
|
||||
);
|
||||
};
|
||||
|
@@ -98,6 +98,7 @@ declare global {
|
||||
onAppMenuWillClose: (listener: () => void) => void;
|
||||
onFocusThreeDotMenu: (listener: () => void) => void;
|
||||
|
||||
onSetURLForURLView: (listener: (link?: string) => void) => void;
|
||||
updateURLViewWidth: (width?: number) => void;
|
||||
openNotificationPreferences: () => void;
|
||||
openWindowsCameraPreferences: () => void;
|
||||
|
Reference in New Issue
Block a user