From f2209aa9dd8f01c07cab1d487abdd55f82d76a93 Mon Sep 17 00:00:00 2001 From: Yuya Ochiai Date: Tue, 12 Jan 2016 21:28:08 +0900 Subject: [PATCH 01/11] Keep focus on webview after switching to main window When switching window focus, webview lost its focus. Please refer to #10 --- src/browser/index.jsx | 9 +++++++++ 1 file changed, 9 insertions(+) diff --git a/src/browser/index.jsx b/src/browser/index.jsx index 6e4bd862..f961cae1 100644 --- a/src/browser/index.jsx +++ b/src/browser/index.jsx @@ -17,6 +17,8 @@ const path = require('path'); const settings = require('../common/settings'); +remote.getCurrentWindow().removeAllListeners('focus'); + var MainPage = React.createClass({ getInitialState: function() { return { @@ -24,6 +26,13 @@ var MainPage = React.createClass({ unreadCounts: new Array(this.props.teams.length) }; }, + componentDidMount: function() { + var thisObj = this; + remote.getCurrentWindow().on('focus', function() { + var webview = document.getElementById('mattermostView' + thisObj.state.key); + webview.focus(); + }); + }, handleSelect: function(key) { this.setState({ key: key From 48f63b6bcb7643e6e5af70df235eff773fd6d73c Mon Sep 17 00:00:00 2001 From: Yuya Ochiai Date: Tue, 12 Jan 2016 22:08:24 +0900 Subject: [PATCH 02/11] Restore maximized/fullscreen state on startup Please refer to #4 --- src/main.js | 16 ++++++++++++---- 1 file changed, 12 insertions(+), 4 deletions(-) diff --git a/src/main.js b/src/main.js index 7c3ad83f..46121107 100644 --- a/src/main.js +++ b/src/main.js @@ -111,6 +111,9 @@ app.on('ready', function() { } window_options.icon = __dirname + '/resources/appicon.png'; mainWindow = new BrowserWindow(window_options); + if (window_options.maximized) { + mainWindow.maximize(); + } // and load the index.html of the app. mainWindow.loadURL('file://' + __dirname + '/browser/index.html'); @@ -118,10 +121,16 @@ app.on('ready', function() { // Open the DevTools. // mainWindow.openDevTools(); + var saveWindowState = function(file, window) { + var window_state = window.getBounds(); + window_state.maximized = window.isMaximized(); + window_state.fullscreen = window.isFullScreen(); + fs.writeFileSync(bounds_info_path, JSON.stringify(window_state)); + }; + mainWindow.on('close', function(event) { if (willAppQuit) { // when [Ctrl|Cmd]+Q - var bounds = mainWindow.getBounds(); - fs.writeFileSync(bounds_info_path, JSON.stringify(bounds)); + saveWindowState(bounds_info_path, mainWindow); } else { // Minimize or hide the window for close button. event.preventDefault(); @@ -144,8 +153,7 @@ app.on('ready', function() { // 'blur' event was effective in order to avoid this. // Ideally, app should detect that OS is shutting down. mainWindow.on('blur', function() { - var bounds = mainWindow.getBounds(); - fs.writeFileSync(bounds_info_path, JSON.stringify(bounds)); + saveWindowState(bounds_info_path, mainWindow); }); var app_menu = appMenu.createMenu(mainWindow); From 1cc68197d2e1a922149a46211cbd1079bfe3556c Mon Sep 17 00:00:00 2001 From: Yuya Ochiai Date: Wed, 13 Jan 2016 22:07:37 +0900 Subject: [PATCH 03/11] Hide tabs when the number of teams is 1 --- src/browser/index.jsx | 61 +++++++++++++++++++++++++++---------------- test/browser_test.js | 14 +++++++++- 2 files changed, 52 insertions(+), 23 deletions(-) diff --git a/src/browser/index.jsx b/src/browser/index.jsx index f961cae1..38be3d3f 100644 --- a/src/browser/index.jsx +++ b/src/browser/index.jsx @@ -55,7 +55,7 @@ var MainPage = React.createClass({ var visibility = visible ? 'visible' : 'hidden'; return { position: 'absolute', - top: 42, + top: (this.props.teams.length > 1) ? 42 : 0, right: 0, bottom: 0, left: 0, @@ -64,19 +64,16 @@ var MainPage = React.createClass({ }, render: function() { var thisObj = this; - var tabs = this.props.teams.map(function(team, index) { - var badge; - if (thisObj.state.unreadCounts[index] != 0) { - badge = ( - { thisObj.state.unreadCounts[index] } - ); - } - return ( - { team.name } - { ' ' } - { badge } - ); - }); + + var tabs_row; + if (this.props.teams.length > 1) { + tabs_row = ( + + + + ); + } + var views = this.props.teams.map(function(team, index) { var handleUnreadCountChange = function(count) { thisObj.handleUnreadCountChange(index, count); @@ -87,21 +84,41 @@ var MainPage = React.createClass({ return () }); + var views_row = ( + { views } + ); return ( - - - - - { views } - + { tabs_row } + { views_row } ); } }); +var TabBar = React.createClass({ + render: function() { + var thisObj = this; + var tabs = this.props.teams.map(function(team, index) { + var badge; + if (thisObj.props.unreadCounts[index] != 0) { + badge = ( + { thisObj.props.unreadCounts[index] } + ); + } + return ( + { team.name } + { ' ' } + { badge } + ); + }); + return ( + + ); + } +}); var MattermostView = React.createClass({ getInitialState: function() { diff --git a/test/browser_test.js b/test/browser_test.js index a689e9e2..746ce496 100644 --- a/test/browser_test.js +++ b/test/browser_test.js @@ -106,10 +106,22 @@ describe('electron-mattermost', function() { }] }; - before(function() { + beforeEach(function() { fs.writeFileSync(config_file_path, JSON.stringify(config)); }); + it('should NOT show tabs when there is one team', function() { + fs.writeFileSync(config_file_path, JSON.stringify({ + url: mattermost_url + })); + return client + .init() + .isExisting('#tabBar').then(function(isExisting) { + isExisting.should.be.false(); + }) + .end(); + }); + it('should set src of webview from config file', function() { return client .init() From 0cff18b210c74846051c04b51e10793a113e7348 Mon Sep 17 00:00:00 2001 From: Yuya Ochiai Date: Thu, 14 Jan 2016 21:24:27 +0900 Subject: [PATCH 04/11] Update Electron to 0.36.3 --- package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/package.json b/package.json index 0f5446da..acbd093b 100644 --- a/package.json +++ b/package.json @@ -25,7 +25,7 @@ "del": "^2.2.0", "electron-connect": "^0.3.3", "electron-packager": "^5.1.0", - "electron-prebuilt": "0.36.2", + "electron-prebuilt": "0.36.3", "esformatter": "^0.8.1", "esformatter-jsx": "^4.0.6", "gulp": "^3.9.0", From d6afda37f2924383770e9985e5fc6daf4afddb59 Mon Sep 17 00:00:00 2001 From: Yuya Ochiai Date: Thu, 14 Jan 2016 21:51:06 +0900 Subject: [PATCH 05/11] Remove 'focus' event listener when leaving from index.html --- src/browser/index.jsx | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) diff --git a/src/browser/index.jsx b/src/browser/index.jsx index 38be3d3f..190570d4 100644 --- a/src/browser/index.jsx +++ b/src/browser/index.jsx @@ -28,9 +28,15 @@ var MainPage = React.createClass({ }, componentDidMount: function() { var thisObj = this; - remote.getCurrentWindow().on('focus', function() { + var focusListener = function() { var webview = document.getElementById('mattermostView' + thisObj.state.key); webview.focus(); + }; + + var currentWindow = remote.getCurrentWindow(); + currentWindow.on('focus', focusListener); + window.addEventListener('beforeunload', function() { + currentWindow.removeListener('focus', focusListener); }); }, handleSelect: function(key) { From 267d0e3ded0e57575fc678f4c4b4906afe49db96 Mon Sep 17 00:00:00 2001 From: Yuya Ochiai Date: Thu, 14 Jan 2016 22:50:12 +0900 Subject: [PATCH 06/11] Show menubar in default setttings on Windows, and add the option to hide --- src/browser/settings.jsx | 54 +++++++++++++++++++++++++++++----------- src/main.js | 9 ++++--- 2 files changed, 45 insertions(+), 18 deletions(-) diff --git a/src/browser/settings.jsx b/src/browser/settings.jsx index cc5f9d5d..50c796c0 100644 --- a/src/browser/settings.jsx +++ b/src/browser/settings.jsx @@ -6,6 +6,7 @@ const settings = require('../common/settings'); const Grid = ReactBootstrap.Grid; const Row = ReactBootstrap.Row; const Col = ReactBootstrap.Col; +const Input = ReactBootstrap.Input; const Button = ReactBootstrap.Button; const ListGroup = ReactBootstrap.ListGroup; const ListGroupItem = ReactBootstrap.ListGroupItem; @@ -13,15 +14,11 @@ const Glyphicon = ReactBootstrap.Glyphicon; var SettingsPage = React.createClass({ getInitialState: function() { - return { - teams: [] - }; - }, - componentDidMount: function() { var config = settings.readFileSync(this.props.configFile); - this.setState({ - teams: config.teams - }) + return { + teams: config.teams, + hideMenuBar: config.hideMenuBar + }; }, handleTeamsChange: function(teams) { this.setState({ @@ -31,23 +28,50 @@ var SettingsPage = React.createClass({ handleSave: function() { var config = { teams: this.state.teams, - version: 1 + hideMenuBar: this.refs.hideMenuBar.getChecked(), + version: settings.version }; settings.writeFileSync(this.props.configFile, config); + var currentWindow = remote.getCurrentWindow(); + currentWindow.setAutoHideMenuBar(config.hideMenuBar); + currentWindow.setMenuBarVisibility(!config.hideMenuBar); window.location = './index.html'; }, handleCancel: function() { window.location = './index.html'; }, + handleChangeHideMenuBar: function() { + this.setState({ + hideMenuBar: this.refs.hideMenuBar.getChecked() + }); + }, render: function() { + var teams_row = ( + + +

Teams

+ + +
+ ); + + var options = []; + if (process.platform === 'win32') { + options.push(); + } + var options_row = (options.length > 0) ? ( + + +

Options

+ { options } + +
+ ) : null; + return ( - - -

Teams

- - -
+ { teams_row } + { options_row } diff --git a/src/main.js b/src/main.js index 46121107..37e3eecf 100644 --- a/src/main.js +++ b/src/main.js @@ -28,9 +28,10 @@ else { global['config-file'] = app.getPath('userData') + '/config.json' } +var config = {}; try { var configFile = global['config-file']; - var config = settings.readFileSync(configFile); + config = settings.readFileSync(configFile); if (config.version != settings.version) { config = settings.upgrade(config); settings.writeFileSync(configFile, config); @@ -61,8 +62,10 @@ app.on('window-all-closed', function() { // For win32, auto-hide menu bar. app.on('browser-window-created', function(event, window) { if (process.platform === 'win32') { - window.setAutoHideMenuBar(true); - window.setMenuBarVisibility(false); + if (config.hideMenuBar) { + window.setAutoHideMenuBar(true); + window.setMenuBarVisibility(false); + } } }); From 54f7eb3657490c697211af8506b683d6909179dd Mon Sep 17 00:00:00 2001 From: Yuya Ochiai Date: Thu, 14 Jan 2016 23:27:37 +0900 Subject: [PATCH 07/11] Fix some error cases when the number of teams is zero * There is no config.json * config.teams.length === 0 --- src/browser/index.jsx | 3 +++ src/browser/settings.jsx | 9 +++++++-- src/common/settings.js | 8 ++++++++ 3 files changed, 18 insertions(+), 2 deletions(-) diff --git a/src/browser/index.jsx b/src/browser/index.jsx index 190570d4..43790a6b 100644 --- a/src/browser/index.jsx +++ b/src/browser/index.jsx @@ -210,6 +210,9 @@ try { } catch (e) { window.location = 'settings.html'; } +if (config.teams.length === 0) { + window.location = 'settings.html'; +} var contextMenu = require('./menus/context'); var menu = contextMenu.createDefault(); diff --git a/src/browser/settings.jsx b/src/browser/settings.jsx index 50c796c0..e4dd9ee5 100644 --- a/src/browser/settings.jsx +++ b/src/browser/settings.jsx @@ -14,7 +14,12 @@ const Glyphicon = ReactBootstrap.Glyphicon; var SettingsPage = React.createClass({ getInitialState: function() { - var config = settings.readFileSync(this.props.configFile); + var config; + try { + config = settings.readFileSync(this.props.configFile); + } catch (e) { + config = settings.loadDefault(); + } return { teams: config.teams, hideMenuBar: config.hideMenuBar @@ -76,7 +81,7 @@ var SettingsPage = React.createClass({ { ' ' } - +
diff --git a/src/common/settings.js b/src/common/settings.js index 5fd345e8..e63dee0e 100644 --- a/src/common/settings.js +++ b/src/common/settings.js @@ -38,5 +38,13 @@ module.exports = { } var data = JSON.stringify(config, null, ' '); fs.writeFileSync(configFile, data, 'utf8'); + }, + + loadDefault: function() { + return { + teams: [], + hideMenuBar: false, + version: version + }; } }; From ea33fc5c588d0fd2993d40fa8ef1144f700cecb0 Mon Sep 17 00:00:00 2001 From: Yuya Ochiai Date: Fri, 15 Jan 2016 00:20:17 +0900 Subject: [PATCH 08/11] Avoid hide-menubar functions when saving config except on Windows --- src/browser/settings.jsx | 10 ++++++---- src/common/settings.js | 1 + 2 files changed, 7 insertions(+), 4 deletions(-) diff --git a/src/browser/settings.jsx b/src/browser/settings.jsx index e4dd9ee5..6a85292e 100644 --- a/src/browser/settings.jsx +++ b/src/browser/settings.jsx @@ -33,13 +33,15 @@ var SettingsPage = React.createClass({ handleSave: function() { var config = { teams: this.state.teams, - hideMenuBar: this.refs.hideMenuBar.getChecked(), + hideMenuBar: this.state.hideMenuBar, version: settings.version }; settings.writeFileSync(this.props.configFile, config); - var currentWindow = remote.getCurrentWindow(); - currentWindow.setAutoHideMenuBar(config.hideMenuBar); - currentWindow.setMenuBarVisibility(!config.hideMenuBar); + if (process.platform === 'win32') { + var currentWindow = remote.getCurrentWindow(); + currentWindow.setAutoHideMenuBar(config.hideMenuBar); + currentWindow.setMenuBarVisibility(!config.hideMenuBar); + } window.location = './index.html'; }, handleCancel: function() { diff --git a/src/common/settings.js b/src/common/settings.js index e63dee0e..b7302274 100644 --- a/src/common/settings.js +++ b/src/common/settings.js @@ -9,6 +9,7 @@ var upgradeV0toV1 = function(config_v0) { name: 'Primary team', url: config_v0.url }], + hideMenuBar: false, version: 1 }; }; From 84c1f1666519105e3709cd64c7fa41650e64e622 Mon Sep 17 00:00:00 2001 From: Yuya Ochiai Date: Sat, 16 Jan 2016 17:04:23 +0900 Subject: [PATCH 09/11] Add setup guide for OS X and fix some words --- docs/setup.md | 45 +++++++++++++++++++++++++++++++++++++-------- 1 file changed, 37 insertions(+), 8 deletions(-) diff --git a/docs/setup.md b/docs/setup.md index d09381b4..24467d84 100644 --- a/docs/setup.md +++ b/docs/setup.md @@ -1,25 +1,54 @@ -# Electron Mattermost Setup Guides +# Electron-Mattermost Setup Guides ## Step-by-step Windows 7 setup +Windows 8 and 10 have similar way. -1. Download [the latest release](https://github.com/yuya-oc/electron-mattermost/releases) of electron Mattermost +1. Download [the latest release](https://github.com/yuya-oc/electron-mattermost/releases) of electron-attermost - Find the file ending in `-win64.zip` if you're running a x64 version of Windows and `-win32.zip` if you're running an older 32-bit version. + Find the file ending in `-win64.zip` if you're running a x64 version of Windows and `-win32.zip` if you're running an older 32-bit version. -2. From the `/Downloads` directory right click on the file and select "Extract All..." +2. From the `/Downloads` directory right-click on the file and select "Extract All..." A new directory should be created on your PC. 3. Go to `/electron-mattermost...` directory and double-click on `electron-mattermost` file to start the application You should see a new application called **electron-mattermost** open. - -4. Click `Alt` to bring up the menu at the top of the screen, then click `Settings` + +4. Press `Alt` key to bring up the menu at the top of the window, then click `File -> Settings` 5. For each Mattermost team you'd like to use, enter its **Name** and **URL** then click **Add** 6. Click **Save** to save your setting - You're now ready to use Electron Mattermost to interact with multiple teams from one desktop application - + You're now ready to use electron-mattermost to interact with multiple teams from one desktop application + To quit, use `Ctrl+Q` + + +## Step-by-step OS X setup +For OS X 10.11 El Capitan. An older version of OS X has similar way. + +1. Download [the latest release](https://github.com/yuya-oc/electron-mattermost/releases) of electron-mattermost + + Find the file ending in `-osx.tar.gz`. + +2. From the `/Downloads` directory double-click on the file." + + A new directory should be created on your Mac. + +3. Go to `/electron-mattermost...` directory and right-click on `electron-mattermost` package and select "Open" + + If you see a dialog to confirm the application, select "Open". + + You should see a new application called **electron-mattermost** open. + +4. Click `electron-mattermost` from the menu at the top of the screen, then click `Settings` + +5. For each Mattermost team you'd like to use, enter its **Name** and **URL** then click **Add** + +6. Click **Save** to save your setting + + You're now ready to use electron-mattermost to interact with multiple teams from one desktop application + + To quit, use `Command+Q` From 5503e3756bc0acc91ac89f48f144f804826f4df3 Mon Sep 17 00:00:00 2001 From: Yuya Ochiai Date: Sat, 16 Jan 2016 17:10:37 +0900 Subject: [PATCH 10/11] Update README.md --- README.md | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/README.md b/README.md index 8106435a..5e505a07 100644 --- a/README.md +++ b/README.md @@ -23,9 +23,11 @@ You don't have to install any other software. ## Usage ### Installation +Detailed guides are available at [docs/setup.md](docs/setup.md). + 1. Download and unarchive a file from [release page](http://github.com/yuya-oc/electron-mattermost/releases). 2. Launch `electron-mattermost` in the unarchived folder. -3. After first launching, please input URL for your Mattermost team. For example, `http://mattermost.example.com/team`. +3. After first launching, please input name and URL for your Mattermost team. For example, `myteam : http://mattermost.example.com/team`. ### Quit Ctrl or Command + Q to quit. From 147800ff71f1db3d3da474907f99c3b2cdb335f5 Mon Sep 17 00:00:00 2001 From: Yuya Ochiai Date: Sat, 16 Jan 2016 17:33:10 +0900 Subject: [PATCH 11/11] Update version to 1.0.2 --- package.json | 4 ++-- src/package.json | 4 ++-- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/package.json b/package.json index acbd093b..f3fa85cf 100644 --- a/package.json +++ b/package.json @@ -1,7 +1,7 @@ { "name": "electron-mattermost", - "version": "1.0.1", - "description": "Desktop app for Mattermost that run on Electron", + "version": "1.0.2", + "description": "Electron-based desktop application for Mattermost", "main": "main.js", "author": "Yuya Ochiai", "license": "MIT", diff --git a/src/package.json b/src/package.json index 47f6998f..8c2302e3 100644 --- a/src/package.json +++ b/src/package.json @@ -1,7 +1,7 @@ { "name": "electron-mattermost", - "version": "1.0.1", - "description": "Desktop app for Mattermost that run on Electron", + "version": "1.0.2", + "description": "Electron-based desktop application for Mattermost", "main": "main.js", "author": "Yuya Ochiai", "license": "MIT",