mirror of
				https://github.com/vector-im/element-web.git
				synced 2025-11-04 02:02:14 +01:00 
			
		
		
		
	Merge pull request #2535 from vector-im/dbkr/electron_3
Electron app (take 3)
This commit is contained in:
		
						commit
						80bae0563d
					
				
							
								
								
									
										1
									
								
								.gitignore
									
									
									
									
										vendored
									
									
								
							
							
						
						
									
										1
									
								
								.gitignore
									
									
									
									
										vendored
									
									
								
							@ -13,3 +13,4 @@
 | 
				
			|||||||
/vector/olm.*
 | 
					/vector/olm.*
 | 
				
			||||||
.DS_Store
 | 
					.DS_Store
 | 
				
			||||||
npm-debug.log
 | 
					npm-debug.log
 | 
				
			||||||
 | 
					electron/dist
 | 
				
			||||||
 | 
				
			|||||||
							
								
								
									
										
											BIN
										
									
								
								electron/build/icon.icns
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										
											BIN
										
									
								
								electron/build/icon.icns
									
									
									
									
									
										Normal file
									
								
							
										
											Binary file not shown.
										
									
								
							
							
								
								
									
										
											BIN
										
									
								
								electron/build/icon.ico
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										
											BIN
										
									
								
								electron/build/icon.ico
									
									
									
									
									
										Normal file
									
								
							
										
											Binary file not shown.
										
									
								
							| 
		 After Width: | Height: | Size: 21 KiB  | 
							
								
								
									
										158
									
								
								electron/src/electron-main.js
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										158
									
								
								electron/src/electron-main.js
									
									
									
									
									
										Normal file
									
								
							@ -0,0 +1,158 @@
 | 
				
			|||||||
 | 
					// @flow
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					/*
 | 
				
			||||||
 | 
					Copyright 2016 Aviral Dasgupta
 | 
				
			||||||
 | 
					Copyright 2016 OpenMarket Ltd
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					Licensed under the Apache License, Version 2.0 (the "License");
 | 
				
			||||||
 | 
					you may not use this file except in compliance with the License.
 | 
				
			||||||
 | 
					You may obtain a copy of the License at
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    http://www.apache.org/licenses/LICENSE-2.0
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					Unless required by applicable law or agreed to in writing, software
 | 
				
			||||||
 | 
					distributed under the License is distributed on an "AS IS" BASIS,
 | 
				
			||||||
 | 
					WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 | 
				
			||||||
 | 
					See the License for the specific language governing permissions and
 | 
				
			||||||
 | 
					limitations under the License.
 | 
				
			||||||
 | 
					*/
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					const electron = require('electron');
 | 
				
			||||||
 | 
					const url = require('url');
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					const VectorMenu = require('./vectormenu');
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					const PERMITTED_URL_SCHEMES = [
 | 
				
			||||||
 | 
					    'http:',
 | 
				
			||||||
 | 
					    'https:',
 | 
				
			||||||
 | 
					    'mailto:',
 | 
				
			||||||
 | 
					];
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					const UPDATE_POLL_INTERVAL_MS = 60 * 60 * 1000;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					let mainWindow = null;
 | 
				
			||||||
 | 
					let appQuitting = false;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					function safeOpenURL(target) {
 | 
				
			||||||
 | 
					    // openExternal passes the target to open/start/xdg-open,
 | 
				
			||||||
 | 
					    // so put fairly stringent limits on what can be opened
 | 
				
			||||||
 | 
					    // (for instance, open /bin/sh does indeed open a terminal
 | 
				
			||||||
 | 
					    // with a shell, albeit with no arguments)
 | 
				
			||||||
 | 
					    const parsed_url = url.parse(target);
 | 
				
			||||||
 | 
					    if (PERMITTED_URL_SCHEMES.indexOf(parsed_url.protocol) > -1) {
 | 
				
			||||||
 | 
					        // explicitly use the URL re-assembled by the url library,
 | 
				
			||||||
 | 
					        // so we know the url parser has understood all the parts
 | 
				
			||||||
 | 
					        // of the input string
 | 
				
			||||||
 | 
					        const new_target = url.format(parsed_url);
 | 
				
			||||||
 | 
					        electron.shell.openExternal(new_target);
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					function onWindowOrNavigate(ev, target) {
 | 
				
			||||||
 | 
					    // always prevent the default: if something goes wrong,
 | 
				
			||||||
 | 
					    // we don't want to end up opening it in the electron
 | 
				
			||||||
 | 
					    // app, as we could end up opening any sort of random
 | 
				
			||||||
 | 
					    // url in a window that has node scripting access.
 | 
				
			||||||
 | 
					    ev.preventDefault();
 | 
				
			||||||
 | 
					    safeOpenURL(target);
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					function onLinkContextMenu(ev, params) {
 | 
				
			||||||
 | 
					    const popup_menu = new electron.Menu();
 | 
				
			||||||
 | 
					    popup_menu.append(new electron.MenuItem({
 | 
				
			||||||
 | 
					        label: params.linkURL,
 | 
				
			||||||
 | 
					        click() {
 | 
				
			||||||
 | 
					            safeOpenURL(params.linkURL);
 | 
				
			||||||
 | 
					        },
 | 
				
			||||||
 | 
					    }));
 | 
				
			||||||
 | 
					    popup_menu.popup();
 | 
				
			||||||
 | 
					    ev.preventDefault();
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					function installUpdate() {
 | 
				
			||||||
 | 
					    // for some reason, quitAndInstall does not fire the
 | 
				
			||||||
 | 
					    // before-quit event, so we need to set the flag here.
 | 
				
			||||||
 | 
					    appQuitting = true;
 | 
				
			||||||
 | 
					    electron.autoUpdater.quitAndInstall();
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					function pollForUpdates() {
 | 
				
			||||||
 | 
					    try {
 | 
				
			||||||
 | 
					        electron.autoUpdater.checkForUpdates();
 | 
				
			||||||
 | 
					    } catch (e) {
 | 
				
			||||||
 | 
					        console.log("Couldn't check for update", e);
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					electron.ipcMain.on('install_update', installUpdate);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					electron.app.on('ready', () => {
 | 
				
			||||||
 | 
					    try {
 | 
				
			||||||
 | 
					        // For reasons best known to Squirrel, the way it checks for updates
 | 
				
			||||||
 | 
					        // is completely different between macOS and windows. On macOS, it
 | 
				
			||||||
 | 
					        // hits a URL that either gives it a 200 with some json or
 | 
				
			||||||
 | 
					        // 204 No Content. On windows it takes a base path and looks for
 | 
				
			||||||
 | 
					        // files under that path.
 | 
				
			||||||
 | 
					        if (process.platform == 'darwin') {
 | 
				
			||||||
 | 
					            electron.autoUpdater.setFeedURL("https://riot.im/autoupdate/desktop/");
 | 
				
			||||||
 | 
					        } else if (process.platform == 'win32') {
 | 
				
			||||||
 | 
					            electron.autoUpdater.setFeedURL("https://riot.im/download/desktop/win32/");
 | 
				
			||||||
 | 
					        } else {
 | 
				
			||||||
 | 
					            // Squirrel / electron only supports auto-update on these two platforms.
 | 
				
			||||||
 | 
					            // I'm not even going to try to guess which feed style they'd use if they
 | 
				
			||||||
 | 
					            // implemented it on Linux, or if it would be different again.
 | 
				
			||||||
 | 
					            console.log("Auto update not supported on this platform");
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					        // We check for updates ourselves rather than using 'updater' because we need to
 | 
				
			||||||
 | 
					        // do it in the main process (and we don't really need to check every 10 minutes:
 | 
				
			||||||
 | 
					        // every hour should be just fine for a desktop app)
 | 
				
			||||||
 | 
					        // However, we still let the main window listen for the update events.
 | 
				
			||||||
 | 
					        pollForUpdates();
 | 
				
			||||||
 | 
					        setInterval(pollForUpdates, UPDATE_POLL_INTERVAL_MS);
 | 
				
			||||||
 | 
					    } catch (err) {
 | 
				
			||||||
 | 
					        // will fail if running in debug mode
 | 
				
			||||||
 | 
					        console.log("Couldn't enable update checking", err);
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    mainWindow = new electron.BrowserWindow({
 | 
				
			||||||
 | 
					        icon: `${__dirname}/../../vector/img/logo.png`,
 | 
				
			||||||
 | 
					        width: 1024, height: 768,
 | 
				
			||||||
 | 
					    });
 | 
				
			||||||
 | 
					    mainWindow.loadURL(`file://${__dirname}/../../vector/index.html`);
 | 
				
			||||||
 | 
					    electron.Menu.setApplicationMenu(VectorMenu);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    mainWindow.on('closed', () => {
 | 
				
			||||||
 | 
					        mainWindow = null;
 | 
				
			||||||
 | 
					    });
 | 
				
			||||||
 | 
					    mainWindow.on('close', (e) => {
 | 
				
			||||||
 | 
					        if (process.platform == 'darwin' && !appQuitting) {
 | 
				
			||||||
 | 
					            // On Mac, closing the window just hides it
 | 
				
			||||||
 | 
					            // (this is generally how single-window Mac apps
 | 
				
			||||||
 | 
					            // behave, eg. Mail.app)
 | 
				
			||||||
 | 
					            e.preventDefault();
 | 
				
			||||||
 | 
					            mainWindow.hide();
 | 
				
			||||||
 | 
					            return false;
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					    });
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    mainWindow.webContents.on('new-window', onWindowOrNavigate);
 | 
				
			||||||
 | 
					    mainWindow.webContents.on('will-navigate', onWindowOrNavigate);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    mainWindow.webContents.on('context-menu', function(ev, params) {
 | 
				
			||||||
 | 
					        if (params.linkURL) {
 | 
				
			||||||
 | 
					            onLinkContextMenu(ev, params);
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					    });
 | 
				
			||||||
 | 
					});
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					electron.app.on('window-all-closed', () => {
 | 
				
			||||||
 | 
					    electron.app.quit();
 | 
				
			||||||
 | 
					});
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					electron.app.on('activate', () => {
 | 
				
			||||||
 | 
					    mainWindow.show();
 | 
				
			||||||
 | 
					});
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					electron.app.on('before-quit', () => {
 | 
				
			||||||
 | 
					    appQuitting = true;
 | 
				
			||||||
 | 
					});
 | 
				
			||||||
							
								
								
									
										188
									
								
								electron/src/vectormenu.js
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										188
									
								
								electron/src/vectormenu.js
									
									
									
									
									
										Normal file
									
								
							@ -0,0 +1,188 @@
 | 
				
			|||||||
 | 
					/*
 | 
				
			||||||
 | 
					Copyright 2016 OpenMarket Ltd
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					Licensed under the Apache License, Version 2.0 (the "License");
 | 
				
			||||||
 | 
					you may not use this file except in compliance with the License.
 | 
				
			||||||
 | 
					You may obtain a copy of the License at
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    http://www.apache.org/licenses/LICENSE-2.0
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					Unless required by applicable law or agreed to in writing, software
 | 
				
			||||||
 | 
					distributed under the License is distributed on an "AS IS" BASIS,
 | 
				
			||||||
 | 
					WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 | 
				
			||||||
 | 
					See the License for the specific language governing permissions and
 | 
				
			||||||
 | 
					limitations under the License.
 | 
				
			||||||
 | 
					*/
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					const electron = require('electron');
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					// Menu template from http://electron.atom.io/docs/api/menu/, edited
 | 
				
			||||||
 | 
					const template = [
 | 
				
			||||||
 | 
					    {
 | 
				
			||||||
 | 
					        label: 'Edit',
 | 
				
			||||||
 | 
					        submenu: [
 | 
				
			||||||
 | 
					            {
 | 
				
			||||||
 | 
					                role: 'undo'
 | 
				
			||||||
 | 
					            },
 | 
				
			||||||
 | 
					            {
 | 
				
			||||||
 | 
					                role: 'redo'
 | 
				
			||||||
 | 
					            },
 | 
				
			||||||
 | 
					            {
 | 
				
			||||||
 | 
					                type: 'separator'
 | 
				
			||||||
 | 
					            },
 | 
				
			||||||
 | 
					            {
 | 
				
			||||||
 | 
					                role: 'cut'
 | 
				
			||||||
 | 
					            },
 | 
				
			||||||
 | 
					            {
 | 
				
			||||||
 | 
					                role: 'copy'
 | 
				
			||||||
 | 
					            },
 | 
				
			||||||
 | 
					            {
 | 
				
			||||||
 | 
					                role: 'paste'
 | 
				
			||||||
 | 
					            },
 | 
				
			||||||
 | 
					            {
 | 
				
			||||||
 | 
					                role: 'pasteandmatchstyle'
 | 
				
			||||||
 | 
					            },
 | 
				
			||||||
 | 
					            {
 | 
				
			||||||
 | 
					                role: 'delete'
 | 
				
			||||||
 | 
					            },
 | 
				
			||||||
 | 
					            {
 | 
				
			||||||
 | 
					                role: 'selectall'
 | 
				
			||||||
 | 
					            }
 | 
				
			||||||
 | 
					        ]
 | 
				
			||||||
 | 
					    },
 | 
				
			||||||
 | 
					    {
 | 
				
			||||||
 | 
					        label: 'View',
 | 
				
			||||||
 | 
					        submenu: [
 | 
				
			||||||
 | 
					            {
 | 
				
			||||||
 | 
					                type: 'separator'
 | 
				
			||||||
 | 
					            },
 | 
				
			||||||
 | 
					            {
 | 
				
			||||||
 | 
					                role: 'resetzoom'
 | 
				
			||||||
 | 
					            },
 | 
				
			||||||
 | 
					            {
 | 
				
			||||||
 | 
					                role: 'zoomin'
 | 
				
			||||||
 | 
					            },
 | 
				
			||||||
 | 
					            {
 | 
				
			||||||
 | 
					                role: 'zoomout'
 | 
				
			||||||
 | 
					            },
 | 
				
			||||||
 | 
					            {
 | 
				
			||||||
 | 
					                type: 'separator'
 | 
				
			||||||
 | 
					            },
 | 
				
			||||||
 | 
					            {
 | 
				
			||||||
 | 
					                role: 'togglefullscreen'
 | 
				
			||||||
 | 
					            },
 | 
				
			||||||
 | 
					            {
 | 
				
			||||||
 | 
					                label: 'Toggle Developer Tools',
 | 
				
			||||||
 | 
					                accelerator: process.platform == 'darwin' ? 'Alt+Command+I' : 'Ctrl+Shift+I',
 | 
				
			||||||
 | 
					                click: function(item, focusedWindow) {
 | 
				
			||||||
 | 
					                    if (focusedWindow) focusedWindow.toggleDevTools();
 | 
				
			||||||
 | 
					                }
 | 
				
			||||||
 | 
					            }
 | 
				
			||||||
 | 
					        ]
 | 
				
			||||||
 | 
					    },
 | 
				
			||||||
 | 
					    {
 | 
				
			||||||
 | 
					        role: 'window',
 | 
				
			||||||
 | 
					        submenu: [
 | 
				
			||||||
 | 
					            {
 | 
				
			||||||
 | 
					                role: 'minimize'
 | 
				
			||||||
 | 
					            },
 | 
				
			||||||
 | 
					            {
 | 
				
			||||||
 | 
					                role: 'close'
 | 
				
			||||||
 | 
					            }
 | 
				
			||||||
 | 
					        ]
 | 
				
			||||||
 | 
					    },
 | 
				
			||||||
 | 
					    {
 | 
				
			||||||
 | 
					        role: 'help',
 | 
				
			||||||
 | 
					        submenu: [
 | 
				
			||||||
 | 
					            {
 | 
				
			||||||
 | 
					                label: 'riot.im',
 | 
				
			||||||
 | 
					                click () { electron.shell.openExternal('https://riot.im/') }
 | 
				
			||||||
 | 
					            }
 | 
				
			||||||
 | 
					        ]
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					];
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					// macOS has specific menu conventions...
 | 
				
			||||||
 | 
					if (process.platform === 'darwin') {
 | 
				
			||||||
 | 
					    // first macOS menu is the name of the app
 | 
				
			||||||
 | 
					    const name = electron.app.getName()
 | 
				
			||||||
 | 
					    template.unshift({
 | 
				
			||||||
 | 
					        label: name,
 | 
				
			||||||
 | 
					        submenu: [
 | 
				
			||||||
 | 
					            {
 | 
				
			||||||
 | 
					                role: 'about'
 | 
				
			||||||
 | 
					            },
 | 
				
			||||||
 | 
					            {
 | 
				
			||||||
 | 
					                type: 'separator'
 | 
				
			||||||
 | 
					            },
 | 
				
			||||||
 | 
					            {
 | 
				
			||||||
 | 
					                role: 'services',
 | 
				
			||||||
 | 
					                submenu: []
 | 
				
			||||||
 | 
					            },
 | 
				
			||||||
 | 
					            {
 | 
				
			||||||
 | 
					                type: 'separator'
 | 
				
			||||||
 | 
					            },
 | 
				
			||||||
 | 
					            {
 | 
				
			||||||
 | 
					                role: 'hide'
 | 
				
			||||||
 | 
					            },
 | 
				
			||||||
 | 
					            {
 | 
				
			||||||
 | 
					                role: 'hideothers'
 | 
				
			||||||
 | 
					            },
 | 
				
			||||||
 | 
					            {
 | 
				
			||||||
 | 
					                role: 'unhide'
 | 
				
			||||||
 | 
					            },
 | 
				
			||||||
 | 
					            {
 | 
				
			||||||
 | 
					                type: 'separator'
 | 
				
			||||||
 | 
					            },
 | 
				
			||||||
 | 
					            {
 | 
				
			||||||
 | 
					                role: 'quit'
 | 
				
			||||||
 | 
					            }
 | 
				
			||||||
 | 
					        ]
 | 
				
			||||||
 | 
					    })
 | 
				
			||||||
 | 
					    // Edit menu.
 | 
				
			||||||
 | 
					    // This has a 'speech' section on macOS
 | 
				
			||||||
 | 
					    template[1].submenu.push(
 | 
				
			||||||
 | 
					        {
 | 
				
			||||||
 | 
					            type: 'separator'
 | 
				
			||||||
 | 
					        },
 | 
				
			||||||
 | 
					        {
 | 
				
			||||||
 | 
					            label: 'Speech',
 | 
				
			||||||
 | 
					            submenu: [
 | 
				
			||||||
 | 
					                {
 | 
				
			||||||
 | 
					                    role: 'startspeaking'
 | 
				
			||||||
 | 
					                },
 | 
				
			||||||
 | 
					                {
 | 
				
			||||||
 | 
					                    role: 'stopspeaking'
 | 
				
			||||||
 | 
					                }
 | 
				
			||||||
 | 
					            ]
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					    )
 | 
				
			||||||
 | 
					    // Window menu.
 | 
				
			||||||
 | 
					    // This also has specific functionality on macOS
 | 
				
			||||||
 | 
					    template[3].submenu = [
 | 
				
			||||||
 | 
					        {
 | 
				
			||||||
 | 
					            label: 'Close',
 | 
				
			||||||
 | 
					            accelerator: 'CmdOrCtrl+W',
 | 
				
			||||||
 | 
					            role: 'close'
 | 
				
			||||||
 | 
					        },
 | 
				
			||||||
 | 
					        {
 | 
				
			||||||
 | 
					            label: 'Minimize',
 | 
				
			||||||
 | 
					            accelerator: 'CmdOrCtrl+M',
 | 
				
			||||||
 | 
					            role: 'minimize'
 | 
				
			||||||
 | 
					        },
 | 
				
			||||||
 | 
					        {
 | 
				
			||||||
 | 
					            label: 'Zoom',
 | 
				
			||||||
 | 
					            role: 'zoom'
 | 
				
			||||||
 | 
					        },
 | 
				
			||||||
 | 
					        {
 | 
				
			||||||
 | 
					            type: 'separator'
 | 
				
			||||||
 | 
					        },
 | 
				
			||||||
 | 
					        {
 | 
				
			||||||
 | 
					            label: 'Bring All to Front',
 | 
				
			||||||
 | 
					            role: 'front'
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					    ]
 | 
				
			||||||
 | 
					};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					module.exports = electron.Menu.buildFromTemplate(template)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
							
								
								
									
										27
									
								
								package.json
									
									
									
									
									
								
							
							
						
						
									
										27
									
								
								package.json
									
									
									
									
									
								
							@ -1,8 +1,10 @@
 | 
				
			|||||||
{
 | 
					{
 | 
				
			||||||
  "name": "vector-web",
 | 
					  "name": "vector-web",
 | 
				
			||||||
 | 
					  "productName": "Riot",
 | 
				
			||||||
 | 
					  "main": "electron/src/electron-main.js",
 | 
				
			||||||
  "version": "0.8.4-rc.2",
 | 
					  "version": "0.8.4-rc.2",
 | 
				
			||||||
  "description": "Vector webapp",
 | 
					  "description": "A feature-rich client for Matrix.org",
 | 
				
			||||||
  "author": "matrix.org",
 | 
					  "author": "Vector Creations Ltd.",
 | 
				
			||||||
  "repository": {
 | 
					  "repository": {
 | 
				
			||||||
    "type": "git",
 | 
					    "type": "git",
 | 
				
			||||||
    "url": "https://github.com/vector-im/vector-web"
 | 
					    "url": "https://github.com/vector-im/vector-web"
 | 
				
			||||||
@ -31,6 +33,7 @@
 | 
				
			|||||||
    "build:compile": "babel --source-maps -d lib src",
 | 
					    "build:compile": "babel --source-maps -d lib src",
 | 
				
			||||||
    "build:bundle": "NODE_ENV=production webpack -p --progress",
 | 
					    "build:bundle": "NODE_ENV=production webpack -p --progress",
 | 
				
			||||||
    "build:bundle:dev": "webpack --optimize-occurence-order --progress",
 | 
					    "build:bundle:dev": "webpack --optimize-occurence-order --progress",
 | 
				
			||||||
 | 
					    "build:electron": "build -lwm",
 | 
				
			||||||
    "build": "node scripts/babelcheck.js && npm run build:emojione && npm run build:css && npm run build:bundle",
 | 
					    "build": "node scripts/babelcheck.js && npm run build:emojione && npm run build:css && npm run build:bundle",
 | 
				
			||||||
    "build:dev": "npm run build:emojione && npm run build:css && npm run build:bundle:dev",
 | 
					    "build:dev": "npm run build:emojione && npm run build:css && npm run build:bundle:dev",
 | 
				
			||||||
    "dist": "scripts/package.sh",
 | 
					    "dist": "scripts/package.sh",
 | 
				
			||||||
@ -90,6 +93,7 @@
 | 
				
			|||||||
    "catw": "^1.0.1",
 | 
					    "catw": "^1.0.1",
 | 
				
			||||||
    "cpx": "^1.3.2",
 | 
					    "cpx": "^1.3.2",
 | 
				
			||||||
    "css-raw-loader": "^0.1.1",
 | 
					    "css-raw-loader": "^0.1.1",
 | 
				
			||||||
 | 
					    "electron-builder": "^7.10.2",
 | 
				
			||||||
    "emojione": "^2.2.3",
 | 
					    "emojione": "^2.2.3",
 | 
				
			||||||
    "expect": "^1.16.0",
 | 
					    "expect": "^1.16.0",
 | 
				
			||||||
    "fs-extra": "^0.30.0",
 | 
					    "fs-extra": "^0.30.0",
 | 
				
			||||||
@ -116,5 +120,24 @@
 | 
				
			|||||||
  },
 | 
					  },
 | 
				
			||||||
  "optionalDependencies": {
 | 
					  "optionalDependencies": {
 | 
				
			||||||
    "olm": "https://matrix.org/packages/npm/olm/olm-2.0.0.tgz"
 | 
					    "olm": "https://matrix.org/packages/npm/olm/olm-2.0.0.tgz"
 | 
				
			||||||
 | 
					  },
 | 
				
			||||||
 | 
					  "build": {
 | 
				
			||||||
 | 
					    "appId": "im.riot.app",
 | 
				
			||||||
 | 
					    "category": "Network",
 | 
				
			||||||
 | 
					    "electronVersion": "1.4.2",
 | 
				
			||||||
 | 
					    "//asar=false": "https://github.com/electron-userland/electron-builder/issues/675",
 | 
				
			||||||
 | 
					    "asar": false,
 | 
				
			||||||
 | 
					    "dereference": true,
 | 
				
			||||||
 | 
					    "//files": "We bundle everything, so we only need to include vector/",
 | 
				
			||||||
 | 
					    "files": [
 | 
				
			||||||
 | 
					      "!**/*",
 | 
				
			||||||
 | 
					      "electron/src/**",
 | 
				
			||||||
 | 
					      "vector/**",
 | 
				
			||||||
 | 
					      "package.json"
 | 
				
			||||||
 | 
					    ]
 | 
				
			||||||
 | 
					  },
 | 
				
			||||||
 | 
					  "directories": {
 | 
				
			||||||
 | 
					    "buildResources": "electron/build",
 | 
				
			||||||
 | 
					    "output": "electron/dist"
 | 
				
			||||||
  }
 | 
					  }
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
				
			|||||||
							
								
								
									
										99
									
								
								src/vector/platform/ElectronPlatform.js
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										99
									
								
								src/vector/platform/ElectronPlatform.js
									
									
									
									
									
										Normal file
									
								
							@ -0,0 +1,99 @@
 | 
				
			|||||||
 | 
					// @flow
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					/*
 | 
				
			||||||
 | 
					Copyright 2016 Aviral Dasgupta
 | 
				
			||||||
 | 
					Copyright 2016 OpenMarket Ltd
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					Licensed under the Apache License, Version 2.0 (the "License");
 | 
				
			||||||
 | 
					you may not use this file except in compliance with the License.
 | 
				
			||||||
 | 
					You may obtain a copy of the License at
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    http://www.apache.org/licenses/LICENSE-2.0
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					Unless required by applicable law or agreed to in writing, software
 | 
				
			||||||
 | 
					distributed under the License is distributed on an "AS IS" BASIS,
 | 
				
			||||||
 | 
					WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 | 
				
			||||||
 | 
					See the License for the specific language governing permissions and
 | 
				
			||||||
 | 
					limitations under the License.
 | 
				
			||||||
 | 
					*/
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					import VectorBasePlatform from './VectorBasePlatform';
 | 
				
			||||||
 | 
					import dis from 'matrix-react-sdk/lib/dispatcher';
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					const electron = require('electron');
 | 
				
			||||||
 | 
					const remote = electron.remote;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					electron.remote.autoUpdater.on('update-downloaded', onUpdateDownloaded);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					function onUpdateDownloaded(ev, releaseNotes, ver, date, updateURL) {
 | 
				
			||||||
 | 
					    dis.dispatch({
 | 
				
			||||||
 | 
					        action: 'new_version',
 | 
				
			||||||
 | 
					        currentVersion: electron.remote.app.getVersion(),
 | 
				
			||||||
 | 
					        newVersion: ver,
 | 
				
			||||||
 | 
					        releaseNotes: releaseNotes,
 | 
				
			||||||
 | 
					    });
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					export default class ElectronPlatform extends VectorBasePlatform {
 | 
				
			||||||
 | 
					    setNotificationCount(count: number) {
 | 
				
			||||||
 | 
					        super.setNotificationCount(count);
 | 
				
			||||||
 | 
					        // this sometimes throws because electron is made of fail:
 | 
				
			||||||
 | 
					        // https://github.com/electron/electron/issues/7351
 | 
				
			||||||
 | 
					        // For now, let's catch the error, but I suspect it may
 | 
				
			||||||
 | 
					        // continue to fail and we might just have to accept that
 | 
				
			||||||
 | 
					        // electron's remote RPC is a non-starter for now and use IPC
 | 
				
			||||||
 | 
					        try {
 | 
				
			||||||
 | 
					            remote.app.setBadgeCount(count);
 | 
				
			||||||
 | 
					        } catch (e) {
 | 
				
			||||||
 | 
					            console.error("Failed to set notification count", e);
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    supportsNotifications() : boolean {
 | 
				
			||||||
 | 
					        return true;
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    maySendNotifications() : boolean {
 | 
				
			||||||
 | 
					        return true;
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    displayNotification(title: string, msg: string, avatarUrl: string): Notification {
 | 
				
			||||||
 | 
					        // Notifications in Electron use the HTML5 notification API
 | 
				
			||||||
 | 
					        const notification = new global.Notification(
 | 
				
			||||||
 | 
					            title,
 | 
				
			||||||
 | 
					            {
 | 
				
			||||||
 | 
					                body: msg,
 | 
				
			||||||
 | 
					                icon: avatarUrl,
 | 
				
			||||||
 | 
					                tag: "vector",
 | 
				
			||||||
 | 
					                silent: true, // we play our own sounds
 | 
				
			||||||
 | 
					            }
 | 
				
			||||||
 | 
					        );
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        notification.onclick = function() {
 | 
				
			||||||
 | 
					            dis.dispatch({
 | 
				
			||||||
 | 
					                action: 'view_room',
 | 
				
			||||||
 | 
					                room_id: room.roomId
 | 
				
			||||||
 | 
					            });
 | 
				
			||||||
 | 
					            global.focus();
 | 
				
			||||||
 | 
					        };
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        return notification;
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    clearNotification(notif: Notification) {
 | 
				
			||||||
 | 
					        notif.close();
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    pollForUpdate() {
 | 
				
			||||||
 | 
					        // In electron we control the update process ourselves, since
 | 
				
			||||||
 | 
					        // it needs to run in the main process, so we just run the timer
 | 
				
			||||||
 | 
					        // loop in the main electron process instead.
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    installUpdate() {
 | 
				
			||||||
 | 
					        // IPC to the main process to install the update, since quitAndInstall
 | 
				
			||||||
 | 
					        // doesn't fire the before-quit event so the main process needs to know
 | 
				
			||||||
 | 
					        // it should exit.
 | 
				
			||||||
 | 
					        electron.ipcRenderer.send('install_update');
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
@ -17,8 +17,13 @@ See the License for the specific language governing permissions and
 | 
				
			|||||||
limitations under the License.
 | 
					limitations under the License.
 | 
				
			||||||
*/
 | 
					*/
 | 
				
			||||||
 | 
					
 | 
				
			||||||
import WebPlatform from './WebPlatform';
 | 
					let Platform = null;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
let Platform = WebPlatform;
 | 
					if (window && window.process && window.process && window.process.type === 'renderer') {
 | 
				
			||||||
 | 
					    // we're running inside electron
 | 
				
			||||||
 | 
					    Platform = require('./ElectronPlatform');
 | 
				
			||||||
 | 
					} else {
 | 
				
			||||||
 | 
					    Platform = require('./WebPlatform');
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
export default Platform;
 | 
					export default Platform;
 | 
				
			||||||
 | 
				
			|||||||
@ -66,6 +66,9 @@ module.exports = {
 | 
				
			|||||||
    },
 | 
					    },
 | 
				
			||||||
    externals: {
 | 
					    externals: {
 | 
				
			||||||
        "olm": "Olm",
 | 
					        "olm": "Olm",
 | 
				
			||||||
 | 
					        // Don't try to bundle electron: leave it as a commonjs dependency
 | 
				
			||||||
 | 
					        // (the 'commonjs' here means it will output a 'require')
 | 
				
			||||||
 | 
					        "electron": "commonjs electron",
 | 
				
			||||||
    },
 | 
					    },
 | 
				
			||||||
    plugins: [
 | 
					    plugins: [
 | 
				
			||||||
        new webpack.DefinePlugin({
 | 
					        new webpack.DefinePlugin({
 | 
				
			||||||
 | 
				
			|||||||
		Loading…
	
	
			
			x
			
			
		
	
		Reference in New Issue
	
	Block a user