mirror of
https://github.com/rhysd/Mstdn.git
synced 2025-01-21 20:52:11 +01:00
recreate browser window to switch session partition
This commit is contained in:
parent
8395159007
commit
bf680a4b89
@ -11,7 +11,7 @@ export default class AccountSwitcher extends EventEmitter {
|
|||||||
accounts: Account[];
|
accounts: Account[];
|
||||||
current: Account;
|
current: Account;
|
||||||
|
|
||||||
constructor(private win: Electron.BrowserWindow, accounts: Account[]) {
|
constructor(accounts: Account[]) {
|
||||||
super();
|
super();
|
||||||
const submenu = [] as Electron.MenuItemOptions[];
|
const submenu = [] as Electron.MenuItemOptions[];
|
||||||
|
|
||||||
@ -25,7 +25,7 @@ export default class AccountSwitcher extends EventEmitter {
|
|||||||
label: name,
|
label: name,
|
||||||
type: 'radio',
|
type: 'radio',
|
||||||
checked: false,
|
checked: false,
|
||||||
click: () => this.switchAccountTo(account),
|
click: () => this.switchTo(account),
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -49,18 +49,13 @@ export default class AccountSwitcher extends EventEmitter {
|
|||||||
Menu.setApplicationMenu(menu);
|
Menu.setApplicationMenu(menu);
|
||||||
}
|
}
|
||||||
|
|
||||||
switchAccountTo(account: Account) {
|
switchTo(account: Account) {
|
||||||
if (this.current.name === account.name && this.current.host === account.host) {
|
if (this.current.name === account.name && this.current.host === account.host) {
|
||||||
log.debug('Current account is already @' + account.name);
|
log.debug('Current account is already @' + account.name);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
log.debug('Switch to account', account);
|
log.debug('Switch to account', account);
|
||||||
this.emit('will-switch', account);
|
this.emit('switch', account, this.current);
|
||||||
|
|
||||||
log.error('TODO: Switch partition');
|
|
||||||
|
|
||||||
this.win.webContents.send('mstdn:change-account', account);
|
|
||||||
this.emit('did-switch', account);
|
|
||||||
this.current = account;
|
this.current = account;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
25
main/app.ts
25
main/app.ts
@ -1,7 +1,7 @@
|
|||||||
import * as path from 'path';
|
import * as path from 'path';
|
||||||
import {app, Menu} from 'electron';
|
import {app, Menu, globalShortcut} from 'electron';
|
||||||
import log from './log';
|
import log from './log';
|
||||||
import {Config} from './config';
|
import {Config, Account} from './config';
|
||||||
import AccountSwitcher from './account_switcher';
|
import AccountSwitcher from './account_switcher';
|
||||||
import defaultMenu from './default_menu';
|
import defaultMenu from './default_menu';
|
||||||
import Window from './window';
|
import Window from './window';
|
||||||
@ -20,17 +20,30 @@ export class App {
|
|||||||
app.dock.setIcon(APP_ICON);
|
app.dock.setIcon(APP_ICON);
|
||||||
}
|
}
|
||||||
Menu.setApplicationMenu(defaultMenu());
|
Menu.setApplicationMenu(defaultMenu());
|
||||||
this.switcher = new AccountSwitcher(win.browser, this.config.accounts);
|
this.switcher = new AccountSwitcher(this.config.accounts);
|
||||||
this.switcher.on('did-switch', () => this.open());
|
this.switcher.on('switch', this.onAccountSwitch);
|
||||||
}
|
}
|
||||||
|
|
||||||
open() {
|
start() {
|
||||||
const url = `https://${this.switcher.current.host}${this.switcher.current.default_page}`;
|
const url = `https://${this.switcher.current.host}${this.switcher.current.default_page}`;
|
||||||
this.win.open(url);
|
this.win.open(url);
|
||||||
log.debug('Open URL: ', url);
|
log.debug('Open URL: ', url);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private onAccountSwitch = (next: Account) => {
|
||||||
|
this.win.close();
|
||||||
|
if (this.config.hot_key) {
|
||||||
|
globalShortcut.unregister(this.config.hot_key);
|
||||||
|
}
|
||||||
|
Window.create(next, this.config, this.win.menubar) .then(win => {
|
||||||
|
this.win = win;
|
||||||
|
this.start();
|
||||||
|
});
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
export default function startApp(config: Config) {
|
export default function startApp(config: Config) {
|
||||||
return Window.create(config).then(win => new App(win, config));
|
const default_account = config.accounts[0];
|
||||||
|
return Window.create(default_account, config)
|
||||||
|
.then(win => new App(win, config));
|
||||||
}
|
}
|
||||||
|
@ -3,6 +3,10 @@ import log from './log';
|
|||||||
import startApp from './app';
|
import startApp from './app';
|
||||||
import loadConfig from './config';
|
import loadConfig from './config';
|
||||||
|
|
||||||
|
// default_app sets app.on('all-window-closed', () => app.quit()) before
|
||||||
|
// loading this application. We need to disable the callback.
|
||||||
|
app.removeAllListeners();
|
||||||
|
|
||||||
const appReady = new Promise<void>(resolve => app.once('ready', resolve));
|
const appReady = new Promise<void>(resolve => app.once('ready', resolve));
|
||||||
|
|
||||||
process.on('unhandledRejection', (reason: string) => {
|
process.on('unhandledRejection', (reason: string) => {
|
||||||
@ -16,7 +20,7 @@ app.on('will-quit', () => {
|
|||||||
Promise.all([
|
Promise.all([
|
||||||
loadConfig(),
|
loadConfig(),
|
||||||
appReady
|
appReady
|
||||||
]).then(([config, _]) => startApp(config)).then(win => {
|
]).then(([config, _]) => startApp(config)).then(mstdn => {
|
||||||
win.open();
|
mstdn.start();
|
||||||
log.debug('Application launched!');
|
log.debug('Application launched!');
|
||||||
});
|
});
|
||||||
|
@ -12,12 +12,17 @@ const APP_ICON = path.join(__dirname, '..', 'resources', 'icon', 'icon.png');
|
|||||||
const PRELOAD_JS = path.join(__dirname, '..', 'renderer', 'preload.js');
|
const PRELOAD_JS = path.join(__dirname, '..', 'renderer', 'preload.js');
|
||||||
|
|
||||||
export default class Window {
|
export default class Window {
|
||||||
static create(config: Config) {
|
static create(account: Account, config: Config, mb: Menubar.MenubarApp | null = null) {
|
||||||
return (config.normal_window ? startNormalWindow : startMenuBar)(config);
|
if (config.normal_window) {
|
||||||
|
return startNormalWindow(account, config);
|
||||||
|
} else {
|
||||||
|
return startMenuBar(account, config, mb);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
constructor(
|
constructor(
|
||||||
public browser: Electron.BrowserWindow,
|
public browser: Electron.BrowserWindow,
|
||||||
|
public state: any /*XXX: ElectronWindowState.WindowState */,
|
||||||
public account: Account,
|
public account: Account,
|
||||||
public menubar: Menubar.MenubarApp | null,
|
public menubar: Menubar.MenubarApp | null,
|
||||||
) {
|
) {
|
||||||
@ -60,12 +65,16 @@ export default class Window {
|
|||||||
this.browser.loadURL(url);
|
this.browser.loadURL(url);
|
||||||
}
|
}
|
||||||
|
|
||||||
isMenubar() {
|
|
||||||
return this.menubar !== null;
|
|
||||||
}
|
|
||||||
|
|
||||||
close() {
|
close() {
|
||||||
log.error('TODO: close window');
|
this.state.unmanage();
|
||||||
|
this.browser.webContents.removeAllListeners();
|
||||||
|
this.browser.removeAllListeners();
|
||||||
|
if (this.menubar) {
|
||||||
|
// Note:
|
||||||
|
// menubar.windowClear() won't be called because all listners was removed
|
||||||
|
delete this.menubar.window;
|
||||||
|
}
|
||||||
|
this.browser.close();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -75,14 +84,13 @@ function trayIcon(color: string) {
|
|||||||
}@2x.png`);
|
}@2x.png`);
|
||||||
}
|
}
|
||||||
|
|
||||||
function startNormalWindow(config: Config): Promise<Window> {
|
function startNormalWindow(account: Account, config: Config): Promise<Window> {
|
||||||
log.debug('Setup a normal window');
|
log.debug('Setup a normal window');
|
||||||
return new Promise<Window>(resolve => {
|
return new Promise<Window>(resolve => {
|
||||||
const state = windowState({
|
const state = windowState({
|
||||||
defaultWidth: 600,
|
defaultWidth: 600,
|
||||||
defaultHeight: 800,
|
defaultHeight: 800,
|
||||||
});
|
});
|
||||||
const account = config.accounts[0];
|
|
||||||
const win = new BrowserWindow({
|
const win = new BrowserWindow({
|
||||||
width: state.width,
|
width: state.width,
|
||||||
height: state.height,
|
height: state.height,
|
||||||
@ -129,7 +137,7 @@ function startNormalWindow(config: Config): Promise<Window> {
|
|||||||
|
|
||||||
win.webContents.on('dom-ready', () => {
|
win.webContents.on('dom-ready', () => {
|
||||||
log.debug('Send config to renderer procress');
|
log.debug('Send config to renderer procress');
|
||||||
win.webContents.send('mstdn:config', config);
|
win.webContents.send('mstdn:config', config, account);
|
||||||
});
|
});
|
||||||
win.webContents.once('dom-ready', () => {
|
win.webContents.once('dom-ready', () => {
|
||||||
log.debug('Normal window application was launched');
|
log.debug('Normal window application was launched');
|
||||||
@ -150,20 +158,19 @@ function startNormalWindow(config: Config): Promise<Window> {
|
|||||||
tray.setHighlightMode('never');
|
tray.setHighlightMode('never');
|
||||||
}
|
}
|
||||||
|
|
||||||
resolve(new Window(win, account, null));
|
resolve(new Window(win, state, account, null));
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
function startMenuBar(config: Config): Promise<Window> {
|
function startMenuBar(account: Account, config: Config, bar: Menubar.MenubarApp | null): Promise<Window> {
|
||||||
log.debug('Setup a menubar window');
|
log.debug('Setup a menubar window');
|
||||||
return new Promise<Window>(resolve => {
|
return new Promise<Window>(resolve => {
|
||||||
const state = windowState({
|
const state = windowState({
|
||||||
defaultWidth: 350,
|
defaultWidth: 350,
|
||||||
defaultHeight: 420,
|
defaultHeight: 420,
|
||||||
});
|
});
|
||||||
const account = config.accounts[0];
|
|
||||||
const icon = trayIcon(config.icon_color);
|
const icon = trayIcon(config.icon_color);
|
||||||
const mb = menubar({
|
const mb = bar || menubar({
|
||||||
icon,
|
icon,
|
||||||
width: state.width,
|
width: state.width,
|
||||||
height: state.height,
|
height: state.height,
|
||||||
@ -180,7 +187,6 @@ function startMenuBar(config: Config): Promise<Window> {
|
|||||||
partition: partitionForAccount(account),
|
partition: partitionForAccount(account),
|
||||||
},
|
},
|
||||||
});
|
});
|
||||||
mb.once('ready', () => mb.showWindow());
|
|
||||||
mb.once('after-create-window', () => {
|
mb.once('after-create-window', () => {
|
||||||
log.debug('Menubar application was launched');
|
log.debug('Menubar application was launched');
|
||||||
if (config.hot_key) {
|
if (config.hot_key) {
|
||||||
@ -200,15 +206,24 @@ function startMenuBar(config: Config): Promise<Window> {
|
|||||||
}
|
}
|
||||||
mb.window.webContents.on('dom-ready', () => {
|
mb.window.webContents.on('dom-ready', () => {
|
||||||
log.debug('Send config to renderer procress');
|
log.debug('Send config to renderer procress');
|
||||||
mb.window.webContents.send('mstdn:config', config);
|
mb.window.webContents.send('mstdn:config', config, account);
|
||||||
});
|
});
|
||||||
state.manage(mb.window);
|
state.manage(mb.window);
|
||||||
|
|
||||||
resolve(new Window(mb.window, account, mb));
|
resolve(new Window(mb.window, state, account, mb));
|
||||||
});
|
});
|
||||||
mb.once('after-close', () => {
|
mb.once('after-close', () => {
|
||||||
app.quit();
|
app.quit();
|
||||||
});
|
});
|
||||||
|
if (bar) {
|
||||||
|
log.debug('recreate menubar window with different partition:', account);
|
||||||
|
const pref = mb.getOption('webPreferences');
|
||||||
|
pref.partition = partitionForAccount(account);
|
||||||
|
mb.setOption('webPreferences', pref);
|
||||||
|
mb.showWindow();
|
||||||
|
} else {
|
||||||
|
mb.once('ready', () => mb.showWindow());
|
||||||
|
}
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -54,16 +54,8 @@ function setupKeybinds(keybinds: {[key: string]: string}, host: string) {
|
|||||||
|
|
||||||
let config: Config | null = null;
|
let config: Config | null = null;
|
||||||
|
|
||||||
Ipc.on('mstdn:config', (c: Config) => {
|
Ipc.on('mstdn:config', (c: Config, a: Account) => {
|
||||||
config = c;
|
config = c;
|
||||||
const host = config.accounts[0].host;
|
const host = a.host;
|
||||||
setupKeybinds(config.keymaps, host);
|
setupKeybinds(config.keymaps, host);
|
||||||
});
|
});
|
||||||
|
|
||||||
Ipc.on('mstdn:change-account', (account: Account) => {
|
|
||||||
if (config === null) {
|
|
||||||
log.error('FATAL: config is null at receiving mstdn:change-account');
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
setupKeybinds(config.keymaps, account.host);
|
|
||||||
});
|
|
||||||
|
Loading…
x
Reference in New Issue
Block a user