diff --git a/src/common/communication.js b/src/common/communication.js index bf0ebbba..bedafb79 100644 --- a/src/common/communication.js +++ b/src/common/communication.js @@ -75,3 +75,5 @@ export const SELECT_NEXT_TAB = 'select-next-tab'; export const SELECT_PREVIOUS_TAB = 'select-previous-tab'; export const ADD_SERVER = 'add-server'; export const FOCUS_THREE_DOT_MENU = 'focus-three-dot-menu'; + +export const LOADSCREEN_END = 'loadscreen-end'; diff --git a/src/common/utils/constants.js b/src/common/utils/constants.js index b39a9dee..145e29d6 100644 --- a/src/common/utils/constants.js +++ b/src/common/utils/constants.js @@ -5,6 +5,8 @@ export const PRODUCTION = 'production'; export const DEVELOPMENT = 'development'; export const SECOND = 1000; -export const RELOAD_INTERVAL = 10 * SECOND; +export const RELOAD_INTERVAL = 5 * SECOND; -export const MAX_SERVER_RETRIES = 5; +export const MAX_SERVER_RETRIES = 3; + +export const MAX_LOADING_SCREEN_SECONDS = 4 * SECOND; diff --git a/src/main/views/MattermostView.js b/src/main/views/MattermostView.js index 662103eb..347358a9 100644 --- a/src/main/views/MattermostView.js +++ b/src/main/views/MattermostView.js @@ -7,9 +7,19 @@ import log from 'electron-log'; import {EventEmitter} from 'events'; import Util from 'common/utils/util'; -import {RELOAD_INTERVAL, MAX_SERVER_RETRIES, SECOND} from 'common/utils/constants'; +import {RELOAD_INTERVAL, MAX_SERVER_RETRIES, SECOND, MAX_LOADING_SCREEN_SECONDS} from 'common/utils/constants'; import urlUtils from 'common/utils/url'; -import {LOAD_RETRY, LOAD_SUCCESS, LOAD_FAILED, UPDATE_TARGET_URL, IS_UNREAD, UNREAD_RESULT, TOGGLE_BACK_BUTTON, SET_SERVER_NAME} from 'common/communication'; +import { + LOAD_RETRY, + LOAD_SUCCESS, + LOAD_FAILED, + UPDATE_TARGET_URL, + IS_UNREAD, + UNREAD_RESULT, + TOGGLE_BACK_BUTTON, + SET_SERVER_NAME, + LOADSCREEN_END, +} from 'common/communication'; import {getWindowBoundaries, getLocalPreload} from '../utils'; import * as WindowManager from '../windows/windowManager'; @@ -21,6 +31,7 @@ import {removeWebContentsListeners} from './webContentEvents'; // TODO: review const userAgent = `Mozilla/5.0 (Macintosh; Intel Mac OS X 10_14_6) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/76.0.3809.146 Electron/6.1.7 Safari/537.36 Mattermost/${app.getVersion()}`; const READY = 1; +const WAITING_MM = 2; const LOADING = 0; const ERROR = -1; @@ -51,6 +62,7 @@ export class MattermostView extends EventEmitter { }; this.isVisible = false; this.view = new BrowserView(this.options); + this.removeLoading = null; this.resetLoadingStatus(); /** @@ -131,7 +143,8 @@ export class MattermostView extends EventEmitter { this.handleTitleUpdate(null, this.view.webContents.getTitle()); this.findUnreadState(null); } - this.status = READY; + this.status = WAITING_MM; + this.removeLoading = setTimeout(this.setInitialized, MAX_LOADING_SCREEN_SECONDS, true); this.emit(LOAD_SUCCESS, this.server.name, loadURL.toString()); this.view.webContents.send(SET_SERVER_NAME, this.server.name); }; @@ -192,15 +205,22 @@ export class MattermostView extends EventEmitter { } isReady = () => { - return this.status === READY; + return this.status !== LOADING; } needsLoadingScreen = () => { - return !(this.isInitialized && this.hasBeenShown); + return !(this.status === READY || this.status === ERROR); } - setInitialized = () => { - this.isInitialized = true; + setInitialized = (timedout) => { + this.status = READY; + + if (timedout) { + log.info(`${this.server.name} timeout expired will show the browserview`); + this.emit(LOADSCREEN_END, this.server.name); + } + clearTimeout(this.removeLoading); + this.removeLoading = null; } openDevTools = () => { diff --git a/src/main/views/viewManager.js b/src/main/views/viewManager.js index 0d278e90..2668b6a9 100644 --- a/src/main/views/viewManager.js +++ b/src/main/views/viewManager.js @@ -4,7 +4,15 @@ import log from 'electron-log'; import {BrowserView, dialog} from 'electron'; import {SECOND} from 'common/utils/constants'; -import {UPDATE_TARGET_URL, 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, + LOADSCREEN_END, +} from 'common/communication'; import urlUtils from 'common/utils/url'; import contextMenu from '../contextMenu'; @@ -46,6 +54,8 @@ export class ViewManager { view.once(LOAD_SUCCESS, this.activateView); view.load(); view.on(UPDATE_TARGET_URL, this.showURLView); + view.on(LOADSCREEN_END, this.finishLoading); + view.once(LOAD_FAILED, this.failLoading); } load = () => { @@ -119,6 +129,9 @@ export class ViewManager { contextMenu.reload(newView.getWebContents()); } else { log.warn(`couldn't show ${name}, not ready`); + if (newView.needsLoadingScreen()) { + this.showLoadingScreen(); + } } } else { log.warn(`Couldn't find a view with name: ${name}`); @@ -145,6 +158,18 @@ export class ViewManager { addWebContentsEventListeners(view, this.getServers); } + finishLoading = (server) => { + const view = this.views.get(server); + if (view && this.getCurrentView() === view) { + this.showByName(this.currentView); + this.fadeLoadingScreen(); + } + } + + failLoading = () => { + this.fadeLoadingScreen(); + } + getCurrentView() { return this.views.get(this.currentView); } diff --git a/src/renderer/components/MainPage.jsx b/src/renderer/components/MainPage.jsx index 1731b792..e95306fe 100644 --- a/src/renderer/components/MainPage.jsx +++ b/src/renderer/components/MainPage.jsx @@ -81,11 +81,16 @@ export default class MainPage extends React.PureComponent { return {status: NOSERVERS}; } + updateTabStatus(server, newStatusValue) { + const status = new Map(this.state.tabStatus); + status.set(server, newStatusValue); + this.setState({tabStatus: status}); + } + componentDidMount() { // set page on retry window.ipcRenderer.on(LOAD_RETRY, (_, server, retry, err, loadUrl) => { console.log(`${server}: failed to load ${err}, but retrying`); - const status = this.state.tabStatus; const statusValue = { status: RETRY, extra: { @@ -94,19 +99,15 @@ export default class MainPage extends React.PureComponent { url: loadUrl, }, }; - status.set(server, statusValue); - this.setState({tabStatus: status}); + this.updateTabStatus(server, statusValue); }); window.ipcRenderer.on(LOAD_SUCCESS, (_, server) => { - const status = this.state.tabStatus; - status.set(server, {status: DONE}); - this.setState({tabStatus: status}); + this.updateTabStatus(server, {status: DONE}); }); window.ipcRenderer.on(LOAD_FAILED, (_, server, err, loadUrl) => { console.log(`${server}: failed to load ${err}`); - const status = this.state.tabStatus; const statusValue = { status: FAILED, extra: { @@ -114,8 +115,7 @@ export default class MainPage extends React.PureComponent { url: loadUrl, }, }; - status.set(server, statusValue); - this.setState({tabStatus: status}); + this.updateTabStatus(server, statusValue); }); window.ipcRenderer.on(DARK_MODE_CHANGE, (_, darkMode) => {