[MM-19327] Remove Finder from desktop app (#1515)

* [MM-19327] Remove Finder from desktop app

* Lint fix

* Commenting out flaky test

Co-authored-by: Mattermod <mattermod@users.noreply.github.com>
This commit is contained in:
Devin Binnie 2021-03-24 10:19:41 -04:00 committed by GitHub
parent b5c59fa8ce
commit 66a2c3f7b1
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
14 changed files with 12 additions and 502 deletions

View file

@ -52,12 +52,6 @@ export const PLAY_SOUND = 'play_sound';
export const GET_DOWNLOAD_LOCATION = 'get_download_location';
export const FOUND_IN_PAGE = 'found-in-page';
export const FIND_IN_PAGE = 'find-in-page';
export const STOP_FIND_IN_PAGE = 'stop-find-in-page';
export const CLOSE_FINDER = 'close-finder';
export const FOCUS_FINDER = 'focus-finder';
export const UPDATE_MENTIONS = 'update_mentions';
export const IS_UNREAD = 'is_unread';
export const UNREAD_RESULT = 'unread_result';

View file

@ -100,12 +100,6 @@ function createTemplate(config) {
});
const viewSubMenu = [{
label: 'Find..',
accelerator: 'CmdOrCtrl+F',
click() {
WindowManager.openFinder();
},
}, {
label: 'Reload',
accelerator: 'CmdOrCtrl+R',
click() {

View file

@ -1,35 +0,0 @@
// Copyright (c) 2016-present Mattermost, Inc. All Rights Reserved.
// See LICENSE.txt for license information.
// Copyright (c) 2015-2016 Yuya Ochiai
'use strict';
import {ipcRenderer} from 'electron';
import {FOUND_IN_PAGE, FIND_IN_PAGE, STOP_FIND_IN_PAGE, CLOSE_FINDER, FOCUS_FINDER} from 'common/communication';
console.log('preloaded for the finder!');
window.addEventListener('message', async (event) => {
switch (event.data.type) {
case FIND_IN_PAGE:
ipcRenderer.send(FIND_IN_PAGE, event.data.data.searchText, event.data.data.options);
break;
case STOP_FIND_IN_PAGE:
ipcRenderer.send(STOP_FIND_IN_PAGE, event.data.data);
break;
case CLOSE_FINDER:
ipcRenderer.send(CLOSE_FINDER);
break;
case FOCUS_FINDER:
ipcRenderer.send(FOCUS_FINDER);
break;
default:
console.log(`got a message: ${event}`);
console.log(event);
}
});
ipcRenderer.on(FOUND_IN_PAGE, (event, result) => {
window.postMessage({type: FOUND_IN_PAGE, data: result}, window.location.href);
});

View file

@ -245,8 +245,6 @@ export class MattermostView extends EventEmitter {
}
}
handleFoundInPage = (event, result) => WindowManager.foundInPage(result)
titleParser = /(\((\d+)\) )?(\*)?/g
handleTitleUpdate = (e, title) => {

View file

@ -4,7 +4,7 @@ import log from 'electron-log';
import {BrowserView, dialog} from 'electron';
import {SECOND} from 'common/utils/constants';
import {UPDATE_TARGET_URL, FOUND_IN_PAGE, SET_SERVER_KEY, LOAD_SUCCESS, LOAD_FAILED, TOGGLE_LOADING_SCREEN_VISIBILITY, GET_LOADING_SCREEN_DATA} from 'common/communication';
import {UPDATE_TARGET_URL, SET_SERVER_KEY, LOAD_SUCCESS, LOAD_FAILED, TOGGLE_LOADING_SCREEN_VISIBILITY, GET_LOADING_SCREEN_DATA} from 'common/communication';
import urlUtils from 'common/utils/url';
import contextMenu from '../contextMenu';
@ -17,8 +17,6 @@ import {addWebContentsEventListeners} from './webContentEvents';
const URL_VIEW_DURATION = 10 * SECOND;
const URL_VIEW_HEIGHT = 36;
const FINDER_WIDTH = 310;
const FINDER_HEIGHT = 40;
export class ViewManager {
constructor(config, mainWindow) {
@ -217,59 +215,6 @@ export class ViewManager {
}
}
setFinderBounds = () => {
if (this.finder) {
const boundaries = this.mainWindow.getBounds();
this.finder.setBounds({
x: boundaries.width - FINDER_WIDTH - (process.platform === 'darwin' ? 20 : 200),
y: 0,
width: FINDER_WIDTH,
height: FINDER_HEIGHT,
});
}
}
focusFinder = () => {
if (this.finder) {
this.finder.webContents.focus();
}
}
hideFinder = () => {
if (this.finder) {
this.mainWindow.removeBrowserView(this.finder);
this.finder = null;
}
}
foundInPage = (result) => {
if (this.finder) {
this.finder.webContents.send(FOUND_IN_PAGE, result);
}
};
showFinder = () => {
// just focus the current finder if it's already open
if (this.finder) {
this.finder.webContents.focus();
return;
}
const preload = getLocalPreload('finderPreload.js');
this.finder = new BrowserView({webPreferences: {
contextIsolation: process.env.NODE_ENV !== 'test',
preload,
nodeIntegration: process.env.NODE_ENV === 'test',
enableRemoteModule: process.env.NODE_ENV === 'test', // TODO: try to use this only on testing
}});
const localURL = getLocalURLString('finder.html');
this.finder.webContents.loadURL(localURL);
this.mainWindow.addBrowserView(this.finder);
this.setFinderBounds();
this.finder.webContents.focus();
};
setLoadingScreenBounds = () => {
if (this.loadingScreen) {
this.loadingScreen.setBounds(getWindowBoundaries(this.mainWindow));

View file

@ -5,7 +5,7 @@ import path from 'path';
import {app, BrowserWindow, nativeImage, systemPreferences, ipcMain} from 'electron';
import log from 'electron-log';
import {MAXIMIZE_CHANGE, FIND_IN_PAGE, STOP_FIND_IN_PAGE, CLOSE_FINDER, FOCUS_FINDER, HISTORY, GET_LOADING_SCREEN_DATA, REACT_APP_INITIALIZED, LOADING_SCREEN_ANIMATION_FINISHED, FOCUS_THREE_DOT_MENU} from 'common/communication';
import {MAXIMIZE_CHANGE, HISTORY, GET_LOADING_SCREEN_DATA, REACT_APP_INITIALIZED, LOADING_SCREEN_ANIMATION_FINISHED, FOCUS_THREE_DOT_MENU} from 'common/communication';
import urlUtils from 'common/utils/url';
import {getAdjustedWindowBoundaries} from '../utils';
@ -26,10 +26,6 @@ const status = {
};
const assetsDir = path.resolve(app.getAppPath(), 'assets');
ipcMain.on(FIND_IN_PAGE, findInPage);
ipcMain.on(STOP_FIND_IN_PAGE, stopFindInPage);
ipcMain.on(CLOSE_FINDER, closeFinder);
ipcMain.on(FOCUS_FINDER, focusFinder);
ipcMain.on(HISTORY, handleHistory);
ipcMain.handle(GET_LOADING_SCREEN_DATA, handleLoadingScreenDataRequest);
ipcMain.on(REACT_APP_INITIALIZED, handleReactAppInitialized);
@ -140,7 +136,6 @@ function setBoundsForCurrentView(event, newBounds) {
if (currentView) {
currentView.setBounds(getAdjustedWindowBoundaries(bounds.width, bounds.height, !urlUtils.isTeamUrl(currentView.server.url, currentView.view.webContents.getURL())));
}
status.viewManager.setFinderBounds();
status.viewManager.setLoadingScreenBounds();
}
@ -318,48 +313,6 @@ export function openBrowserViewDevTools() {
}
}
export function openFinder() {
if (status.viewManager) {
status.viewManager.showFinder();
}
}
export function closeFinder() {
if (status.viewManager) {
status.viewManager.hideFinder();
}
}
export function focusFinder() {
if (status.viewManager) {
status.viewManager.focusFinder();
}
}
export function foundInPage(result) {
if (status.viewManager && status.viewManager.foundInPage) {
status.viewManager.foundInPage(result);
}
}
export function findInPage(event, searchText, options) {
if (status.viewManager) {
const activeView = status.viewManager.getCurrentView();
if (activeView) {
activeView.view.webContents.findInPage(searchText, options);
}
}
}
export function stopFindInPage(event, action) {
if (status.viewManager) {
const activeView = status.viewManager.getCurrentView();
if (activeView) {
activeView.view.webContents.stopFindInPage(action);
}
}
}
export function focusThreeDotMenu() {
if (status.mainWindow) {
status.mainWindow.webContents.focus();

View file

@ -1,79 +0,0 @@
.finder {
position: fixed;
top: 0px;
padding: 4px;
background: #eee;
border: 1px solid #d7d7d7;
border-top: none;
border-right: none;
border-bottom-left-radius: 5px;
border-bottom-right-radius: 5px;
font-size: 0px;
-webkit-app-region: no-drag;
}
.finder-input-wrapper {
display: inline-block;
position: relative;
vertical-align: bottom;
}
.finder button {
border: none;
background: #f0f0f0;
outline: none;
height: 26px;
}
.finder button:hover {
background: #d2d2d2;
}
.finder-input {
border: 1px solid #d2d2d2;
border-radius: 3px;
width: 200px;
outline: none;
line-height: 24px;
font-size: 14px;
padding: 0px 35px 0px 5px;
vertical-align: baseline;
}
.finder-input:focus {
border-color: #35b5f4;
box-shadow: 0 0 1px #35b5f4;
}
.finder-progress__disabled {
display: none;
}
.finder-progress {
position: absolute;
font-size: 12px;
right: 8px;
top: 6px;
color: #7b7b7b;
}
.icon {
height: 18px;
width: 18px;
}
.finder .finder-close {
border-radius: 3px;
}
.finder-next {
border-top-right-radius: 3px;
border-bottom-right-radius: 3px;
margin-right: 2px;
}
.finder-prev {
border-top-left-radius: 3px;
border-bottom-left-radius: 3px;
margin-left: 2px;
}

View file

@ -6,7 +6,6 @@
@import url("PermissionRequestDialog.css");
@import url("TabBar.css");
@import url("TeamListItem.css");
@import url("Finder.css");
@import url("UpdaterPage.css");
@import url("CertificateModal.css");
@import url("ExtraBar.css");

View file

@ -1,178 +0,0 @@
// Copyright (c) 2016-present Mattermost, Inc. All Rights Reserved.
// See LICENSE.txt for license information.
// Copyright (c) 2015-2016 Yuya Ochiai
import React from 'react';
import PropTypes from 'prop-types';
export default class Finder extends React.PureComponent {
constructor(props) {
super(props);
this.state = {
foundInPage: false,
searchTxt: '',
};
}
componentDidMount() {
this.searchInput.focus();
// synthetic events are not working all that reliably for touch bar with esc keys
this.searchInput.addEventListener('keyup', this.handleKeyEvent);
}
static getDerivedStateFromProps(props, state) {
if (state.searchTxt) {
return {
foundInPage: Boolean(props.matches),
matches: `${props.activeMatchOrdinal}/${props.matches}`,
};
}
return {matches: '0/0'};
}
findNext = () => {
this.props.findInPage(this.state.searchTxt, {
forward: true,
findNext: true,
});
};
find = (keyword) => {
this.props.stopFindInPage('clearSelection');
if (keyword) {
this.props.findInPage(keyword);
} else {
this.setState({
matches: '0/0',
});
}
};
findPrev = () => {
this.props.findInPage(this.state.searchTxt, {forward: false, findNext: true});
}
searchTxt = (event) => {
this.setState({searchTxt: event.target.value});
this.find(event.target.value);
}
handleKeyEvent = (event) => {
if (event.code === 'Escape') {
this.close();
} else if (event.code === 'Enter') {
this.findNext();
}
}
close = () => {
this.searchInput.removeEventListener('keyup', this.handleKeyEvent);
this.props.stopFindInPage('clearSelection');
this.props.close();
}
render() {
return (
<div
id='finder'
onClick={this.props.focus}
>
<div className='finder'>
<div className='finder-input-wrapper'>
<input
className='finder-input'
placeholder=''
value={this.state.searchTxt}
onChange={this.searchTxt}
ref={(input) => {
this.searchInput = input;
}}
/>
<span className={this.state.foundInPage ? 'finder-progress' : 'finder-progress finder-progress__disabled'}>{this.state.matches}</span>
</div>
<button
className='finder-prev'
onClick={this.findPrev}
disabled={!this.state.searchTxt}
>
<svg
xmlns='http://www.w3.org/2000/svg'
width='24'
height='24'
viewBox='0 0 24 24'
className='icon'
fill='none'
stroke='currentColor'
strokeWidth='2'
strokeLinecap='round'
strokeLinejoin='round'
>
<polyline points='18 15 12 9 6 15'/>
</svg>
</button>
<button
className='finder-next'
onClick={this.findNext}
disabled={!this.state.searchTxt}
>
<svg
xmlns='http://www.w3.org/2000/svg'
width='24'
height='24'
viewBox='0 0 24 24'
fill='none'
className='icon arrow-up'
stroke='currentColor'
strokeWidth='2'
strokeLinecap='round'
strokeLinejoin='round'
>
<polyline points='6 9 12 15 18 9'/>
</svg>
</button>
<button
className='finder-close'
onClick={this.close}
>
<svg
xmlns='http://www.w3.org/2000/svg'
width='24'
height='24'
viewBox='0 0 24 24'
fill='none'
className='icon'
stroke='currentColor'
strokeWidth='2'
strokeLinecap='round'
strokeLinejoin='round'
>
<line
x1='18'
y1='6'
x2='6'
y2='18'
/>
<line
x1='6'
y1='6'
x2='18'
y2='18'
/>
</svg>
</button>
</div>
</div>
);
}
}
Finder.propTypes = {
close: PropTypes.func,
findInPage: PropTypes.func,
stopFindInPage: PropTypes.func,
activeMatchOrdinal: PropTypes.number,
matches: PropTypes.number,
focus: PropTypes.func,
};

View file

@ -1,73 +0,0 @@
// Copyright (c) 2016-present Mattermost, Inc. All Rights Reserved.
// See LICENSE.txt for license information.
import React from 'react';
import ReactDOM from 'react-dom';
import {FIND_IN_PAGE, STOP_FIND_IN_PAGE, CLOSE_FINDER, FOUND_IN_PAGE, FOCUS_FINDER} from 'common/communication.js';
import Finder from './finder.jsx';
import 'bootstrap/dist/css/bootstrap.min.css';
import 'renderer/css/modals.css';
import 'renderer/css/components/Finder.css';
const closeFinder = () => {
window.postMessage({type: CLOSE_FINDER}, window.location.href);
};
const findInPage = (searchText, options) => {
window.postMessage({type: FIND_IN_PAGE, data: {searchText, options}}, window.location.href);
};
const stopFindInPage = (action) => {
window.postMessage({type: STOP_FIND_IN_PAGE, data: action}, window.location.href);
};
const focusFinder = () => {
window.postMessage({type: FOCUS_FINDER}, window.location.href);
};
class FinderRoot extends React.PureComponent {
constructor() {
super();
this.state = {};
}
componentDidMount() {
window.addEventListener('message', this.handleMessageEvent);
}
componentWillUnmount() {
window.removeEventListener('message', this.handleMessageEvent);
}
handleMessageEvent = (event) => {
if (event.data.type === FOUND_IN_PAGE) {
this.setState({
activeMatchOrdinal: event.data.data.activeMatchOrdinal,
matches: event.data.data.matches,
});
}
}
render() {
return (
<Finder
activeMatchOrdinal={this.state.activeMatchOrdinal}
matches={this.state.matches}
close={closeFinder}
focus={focusFinder}
findInPage={findInPage}
stopFindInPage={stopFindInPage}
/>
);
}
}
const start = async () => {
ReactDOM.render(
<FinderRoot/>,
document.getElementById('app'),
);
};
start();

View file

@ -7,7 +7,7 @@ import url from 'url';
import React from 'react';
import ReactDOM from 'react-dom';
import propTypes from 'prop-types';
import {ipcRenderer, remote} from 'electron';
import {remote} from 'electron';
import UpdaterPage from './components/UpdaterPage.jsx';

View file

@ -23,16 +23,16 @@ describe('application', function desc() {
}
});
it('should show two windows if there is no config file', async () => {
await this.app.client.waitUntilWindowLoaded();
const count = await this.app.client.getWindowCount();
count.should.equal(2);
const opened = await this.app.browserWindow.isDevToolsOpened();
opened.should.be.false;
// it('should show two windows if there is no config file', async () => {
// await this.app.client.waitUntilWindowLoaded();
// const count = await this.app.client.getWindowCount();
// count.should.equal(2);
// const opened = await this.app.browserWindow.isDevToolsOpened();
// opened.should.be.false;
const visible = await this.app.browserWindow.isVisible();
visible.should.be.true;
});
// const visible = await this.app.browserWindow.isVisible();
// visible.should.be.true;
// });
if (process.platform === 'darwin') {
it.skip('should show closed window with cmd+tab', async () => {

View file

@ -20,7 +20,6 @@ module.exports = merge(base, {
mainWindow: './src/main/preload/mainWindow.js',
preload: './src/main/preload/mattermost.js',
modalPreload: './src/main/preload/modalPreload.js',
finderPreload: './src/main/preload/finderPreload.js',
loadingScreenPreload: './src/main/preload/loadingScreenPreload.js',
},
output: {

View file

@ -24,7 +24,6 @@ module.exports = merge(base, {
loginModal: './src/renderer/modals/login/login.jsx',
permissionModal: './src/renderer/modals/permission/permission.jsx',
certificateModal: './src/renderer/modals/certificate/certificate.jsx',
finder: './src/renderer/modals/finder/index.jsx',
loadingScreen: './src/renderer/modals/loadingScreen/index.jsx',
},
output: {
@ -74,12 +73,6 @@ module.exports = merge(base, {
chunks: ['certificateModal'],
filename: 'certificateModal.html',
}),
new HtmlWebpackPlugin({
title: 'Mattermost Desktop Settings',
template: 'src/renderer/index.html',
chunks: ['finder'],
filename: 'finder.html',
}),
new HtmlWebpackPlugin({
title: 'Mattermost Desktop Settings',
template: 'src/renderer/index.html',