1
0
Fork 0
mirror of https://github.com/anyproto/anytype-ts.git synced 2025-06-08 05:57:02 +09:00
anytype-ts/electron/js/window.js
Andrew Simachev 493acf07ae
JS-3259: fix
2023-10-30 14:02:17 +01:00

248 lines
No EOL
5.9 KiB
JavaScript

const { app, BrowserWindow, nativeImage, dialog, screen } = require('electron');
const { is, fixPathForAsarUnpack } = require('electron-util');
const version = app.getVersion();
const path = require('path');
const windowStateKeeper = require('electron-window-state');
const remote = require('@electron/remote/main');
const port = process.env.SERVER_PORT;
const ConfigManager = require('./config.js');
const UpdateManager = require('./update.js');
const MenuManager = require('./menu.js');
const Util = require('./util.js');
const DEFAULT_WIDTH = 1024;
const DEFAULT_HEIGHT = 768;
const MIN_WIDTH = 640;
const MIN_HEIGHT = 480;
const NEW_WINDOW_SHIFT = 30;
class WindowManager {
list = new Set();
create (options, param) {
const Api = require('./api.js');
const { route, isChild } = options;
const { languages, zoom, hideMenuBar } = ConfigManager.config;
param = Object.assign({
backgroundColor: Util.getBgColor('dark'),
show: false,
titleBarStyle: 'hidden-inset',
webPreferences: {},
}, param);
param.webPreferences = Object.assign({
nativeWindowOpen: true,
contextIsolation: true,
nodeIntegration: false,
spellcheck: true,
sandbox: false,
}, param.webPreferences);
let win = new BrowserWindow(param);
win.isChild = isChild;
win.route = route;
win.windowId = win.id;
this.list.add(win);
win.on('closed', () => {
this.list.delete(win);
win = null;
});
win.once('ready-to-show', () => { win.show(); });
win.on('focus', () => {
UpdateManager.setWindow(win);
MenuManager.setWindow(win);
});
win.on('enter-full-screen', () => Util.send(win, 'enter-full-screen'));
win.on('leave-full-screen', () => Util.send(win, 'leave-full-screen'));
win.webContents.on('context-menu', (e, param) => Util.send(win, 'spellcheck', param));
Api.setSpellingLang(win, languages);
Api.setZoom(win, zoom);
if (hideMenuBar) {
win.setMenuBarVisibility(false);
win.setAutoHideMenuBar(true);
};
return win;
};
createMain (options) {
const { isChild } = options;
const image = nativeImage.createFromPath(path.join(Util.imagePath(), 'icon512x512.png'));
let state = {};
let param = {
minWidth: MIN_WIDTH,
minHeight: MIN_HEIGHT,
width: DEFAULT_WIDTH,
height: DEFAULT_HEIGHT,
webPreferences: {
preload: fixPathForAsarUnpack(path.join(Util.electronPath(), 'js', 'preload.js')),
},
};
if (is.macos) {
app.dock.setIcon(image);
param.frame = false;
param.titleBarStyle = 'hidden';
param.icon = path.join(Util.imagePath(), 'icon.icns');
param.trafficLightPosition = { x: 20, y: 18 };
} else
if (is.windows) {
param.icon = path.join(Util.imagePath(), 'icon32x32.png');
} else
if (is.linux) {
param.icon = image;
};
if (!isChild) {
state = windowStateKeeper({ defaultWidth: DEFAULT_WIDTH, defaultHeight: DEFAULT_HEIGHT });
param = Object.assign(param, {
x: state.x,
y: state.y,
width: state.width,
height: state.height,
});
} else {
const primaryDisplay = screen.getPrimaryDisplay();
const { width, height } = primaryDisplay.workAreaSize;
param = Object.assign(param, this.getWindowPosition(param, width, height));
};
const win = this.create(options, param);
remote.enable(win.webContents);
if (!isChild) {
state.manage(win);
};
if (is.development) {
win.loadURL(`http://localhost:${port}`);
win.toggleDevTools();
} else {
win.loadURL('file://' + path.join(Util.appPath, 'dist', 'index.html'));
};
win.on('enter-full-screen', () => MenuManager.initMenu());
win.on('leave-full-screen', () => MenuManager.initMenu());
return win;
};
createAbout () {
const win = this.create({}, {
width: 400,
height: 400,
useContentSize: true,
backgroundColor: Util.getBgColor(Util.getTheme()),
});
win.loadURL('file://' + path.join(Util.electronPath(), 'about', `index.html?version=${version}&theme=${Util.getTheme()}&lang=${Util.getLang()}`));
win.setMenu(null);
win.webContents.on('will-navigate', (e, url) => {
e.preventDefault();
// eslint-disable-next-line no-undef
shell.openExternal(url);
});
win.webContents.on('new-window', (e, url) => {
e.preventDefault();
// eslint-disable-next-line no-undef
shell.openExternal(url);
});
return win;
};
command (win, cmd, param) {
param = param || {};
switch (cmd) {
case 'menu':
MenuManager.menu.popup({ x: 16, y: 38 });
break;
case 'minimize':
win.minimize();
break;
case 'maximize':
win.isMaximized() ? win.unmaximize() : win.maximize();
break;
case 'close':
win.hide();
break;
case 'printHtml':
case 'printPdf':
const ext = cmd.replace(/print/, '').toLowerCase();
dialog.showSaveDialog(win, {
buttonLabel: 'Export',
fileFilter: { extensions: [ ext ] },
defaultPath: `${app.getPath('documents')}/${param.name}.${ext}`,
properties: [ 'createDirectory', 'showOverwriteConfirmation' ],
}).then((result) => {
const fp = result.filePath;
if (!fp) {
Util.send(win, 'commandGlobal', 'saveAsHTMLSuccess');
} else {
Util[cmd](win, path.dirname(fp), path.basename(fp), param.options);
};
});
break;
};
};
getWindowPosition (param, displayWidth, displayHeight) {
const currentWindow = BrowserWindow.getFocusedWindow();
let x = Math.round(displayWidth / 2 - param.width / 2);
let y = Math.round(displayHeight / 2 - param.height / 2 + 20);
if (currentWindow) {
const [xPos, yPos] = currentWindow.getPosition();
x = xPos + NEW_WINDOW_SHIFT;
y = yPos + NEW_WINDOW_SHIFT;
const xLimit = x + param.width > displayWidth;
const yLimit = y + param.height > displayHeight;
if (xLimit || yLimit) {
x = 0;
y = 0;
};
};
return { x, y };
};
sendToAll () {
const args = [ ...arguments ];
this.list.forEach(it => {
Util.send.apply(this, [ it ].concat(args));
});
};
reloadAll () {
this.list.forEach(it => it.webContents.reload());
};
};
module.exports = new WindowManager();