This repository has been archived on 2025-09-19. You can view files and clone it. You cannot open issues or pull requests or push a commit.
Files
repertory-ui/public/electron.js

373 lines
9.1 KiB
JavaScript

const {
app,
BrowserWindow,
dialog,
ipcMain,
Menu,
nativeImage,
Tray,
} = require('electron');
const AutoLaunch = require('auto-launch');
const Constants = require('../src/constants');
const fs = require('fs');
const helpers = require('../src/helpers');
const os = require('os');
const path = require('path');
const url = require('url');
const debug = require('electron-debug');
debug({
devToolsMode: 'undocked',
isEnabled: true,
showDevTools: !!process.env.ELECTRON_START_URL,
});
require.extensions['.sh'] = function (module, filename) {
module.exports = fs.readFileSync(filename, 'utf8');
};
const detectScript = require('./detect_linux.sh');
const AppIPC = require('../src/renderer/ipc/AppIPC');
const ConfigIPC = require('../src/renderer/ipc/ConfigIPC');
const DaemonIPC = require('../src/renderer/ipc/DaemonIPC');
const DependencyIPC = require('../src/renderer/ipc/DependencyIPC');
const DownloadIPC = require('../src/renderer/ipc/DownloadIPC');
const FilesystemIPC = require('../src/renderer/ipc/FilesystemIPC');
const MountsIPC = require('../src/renderer/ipc/MountsIPC');
const PinnedIPC = require('../src/renderer/ipc/PinnedIPC');
const PlatformIPC = require('../src/renderer/ipc/PlatformIPC');
const ReleaseIPC = require('../src/renderer/ipc/ReleaseIPC');
const SkynetIPC = require('../src/renderer/ipc/SkynetIPC');
const StateIPC = require('../src/renderer/ipc/StateIPC');
const SystemIPC = require('../src/renderer/ipc/SystemIPC');
const UpgradeIPC = require('../src/renderer/ipc/UpgradeIPC');
const platform = os.platform();
const dimensions = {
height: platform === "win32" || platform === "darwin" ? 420 : 400,
width: platform === "win32" ? 468 : 628
};
let isShutdown = false;
let isQuitting = false;
let isInstalling = false;
let launchHidden = false;
let cleanupReleases = false;
let mainWindow;
let mainWindowTray;
let trayContextMenu;
const closeApplication = () => {
if (!isShutdown) {
isShutdown = true;
if (mainWindowTray) {
mainWindowTray.destroy();
}
app.quit();
}
};
const configurePrimaryApp = () => {
app.on('second-instance', () => {
if (!isInstalling && mainWindow) {
setWindowVisibility(true);
}
});
app.on('ready', createWindow);
app.on('window-all-closed', () => {
closeApplication();
});
};
const createWindow = () => {
loadUiSettings();
let extra = {};
if (platform === 'linux') {
extra = {
icon: path.join(__dirname, '../build/', 'logo.png'),
};
}
// Create the browser window.
mainWindow = new BrowserWindow({
height: dimensions.height,
width: dimensions.width,
fullscreen: false,
resizable: false,
show: !launchHidden,
title: 'Repertory UI',
...extra,
webPreferences: {
nodeIntegration: true,
webSecurity: !process.env.ELECTRON_START_URL,
},
});
if (platform === 'linux') {
mainWindow.setMenuBarVisibility(false);
} else {
mainWindow.removeMenu();
}
if (platform === 'darwin' && launchHidden) {
app.dock.hide();
}
// and load the index.html of the app.
const startUrl =
process.env.ELECTRON_START_URL ||
url.format({
pathname: path.join(__dirname, '../build/index.html'),
protocol: 'file:',
slashes: true,
});
mainWindow.on('close', function (event) {
if (!isQuitting) {
event.preventDefault();
if (mainWindow.isVisible()) {
setWindowVisibility(false);
}
event.returnValue = false;
}
});
mainWindow.on('closed', function () {
// Dereference the window object, usually you would store windows
// in an array if your app supports multi windows, this is the time
// when you should delete the corresponding element.
mainWindow = null;
MountsIPC.unmountAllDrives();
});
const appPath =
platform === 'win32'
? path.resolve(path.join(app.getAppPath(), '..\\..\\repertory-ui.exe'))
: platform === 'darwin'
? path.resolve(
path.join(path.dirname(app.getAppPath()), '../MacOS/repertory-ui')
)
: process.env.APPIMAGE;
const autoLauncher = new AutoLaunch({
name: 'Repertory UI',
path: appPath,
});
trayContextMenu = Menu.buildFromTemplate([
{
label: 'Visible',
type: 'checkbox',
click(item) {
setWindowVisibility(item.checked);
},
checked: !launchHidden,
},
{ type: 'separator' },
{
label: 'Auto-start',
type: 'checkbox',
click(item) {
if (item.checked) {
autoLauncher.enable();
} else {
autoLauncher.disable();
}
},
},
{
label: 'Launch Hidden',
type: 'checkbox',
click(item) {
launchHidden = !!item.checked;
saveUiSettings();
},
checked: launchHidden,
},
{ type: 'separator' },
{
label: 'Delete Old Releases',
type: 'checkbox',
click(item) {
cleanupReleases = !!item.checked;
saveUiSettings();
},
checked: cleanupReleases,
},
{ type: 'separator' },
{
label: 'Exit and Unmount',
click() {
closeApplication();
},
},
]);
const image = nativeImage.createFromPath(
path.join(
__dirname,
platform === 'darwin' ? '../build/logo_mac.png' : '../build/logo.png'
)
);
mainWindowTray = new Tray(image);
autoLauncher
.isEnabled()
.then((enabled) => {
trayContextMenu.items[2].checked = enabled;
mainWindowTray.setToolTip('Repertory UI');
mainWindowTray.setContextMenu(trayContextMenu);
})
.catch(() => {
closeApplication();
});
mainWindow.loadURL(startUrl);
};
const getMainWindow = () => {
return mainWindow;
};
const loadUiSettings = () => {
const settingFile = path.join(
helpers.resolvePath(Constants.DATA_LOCATIONS[platform]),
'ui.json'
);
try {
if (fs.statSync(settingFile).isFile()) {
const settings = JSON.parse(fs.readFileSync(settingFile, 'utf8'));
launchHidden = !!settings.launch_hidden;
cleanupReleases = !!settings.cleanup_releases;
PlatformIPC.setPlatformOverride(settings.platform_override);
}
} catch (e) {}
};
const saveUiSettings = () => {
const settingFile = path.join(helpers.getDataDirectory(), 'ui.json');
try {
fs.writeFileSync(
settingFile,
JSON.stringify({
cleanup_releases: cleanupReleases,
launch_hidden: launchHidden,
platform_override: PlatformIPC.getPlatformOverride(),
}),
'utf-8'
);
} catch (e) {}
};
const setIsInstalling = (installing) => {
isInstalling = installing;
};
const setTrayImage = (driveInUse) => {
let image;
if (driveInUse) {
image = nativeImage.createFromPath(
path.join(
__dirname,
platform === 'darwin'
? '../build/logo_both_mac.png'
: '../build/logo_both.png'
)
);
} else {
image = nativeImage.createFromPath(
path.join(
__dirname,
platform === 'darwin' ? '../build/logo_mac.png' : '../build/logo.png'
)
);
}
mainWindowTray.setImage(image);
};
const setWindowVisibility = (show) => {
if (show) {
mainWindow.show();
if (platform === 'darwin') {
app.dock.show();
} else if (platform === 'linux') {
mainWindow.setSize(dimensions.width, dimensions.height);
}
if (mainWindow.isMinimized()) {
mainWindow.restore();
}
mainWindow.focus();
} else {
mainWindow.hide();
if (platform === 'darwin') {
app.dock.hide();
}
}
if (trayContextMenu && mainWindowTray) {
trayContextMenu.items[0].checked = show;
mainWindowTray.setContextMenu(trayContextMenu);
}
};
const standardIPCReply = (event, channel, data, error) => {
if (mainWindow) {
event.sender.send(channel, {
data: {
...data,
Error: error instanceof Error ? error.toString() : error,
Success: !error,
},
});
}
};
app.on('before-quit', function () {
isQuitting = true;
});
let instanceLock = app.requestSingleInstanceLock();
if (!instanceLock) {
setTimeout(() => {
if ((instanceLock = app.requestSingleInstanceLock())) {
configurePrimaryApp();
} else {
closeApplication();
}
}, 3000);
} else {
configurePrimaryApp();
}
const AppFunctions = {
closeApplication,
detectScript,
dialog,
getCleanupReleases: () => cleanupReleases,
getMainWindow,
saveUiSettings,
setIsInstalling,
setTrayImage,
setWindowVisibility,
standardIPCReply,
unmountAllDrives: MountsIPC.unmountAllDrives,
};
AppIPC.addListeners(ipcMain, AppFunctions);
ConfigIPC.addListeners(ipcMain, AppFunctions);
DaemonIPC.addListeners(ipcMain, AppFunctions);
DependencyIPC.addListeners(ipcMain, AppFunctions);
DownloadIPC.addListeners(ipcMain, AppFunctions);
FilesystemIPC.addListeners(ipcMain, AppFunctions);
MountsIPC.addListeners(ipcMain, AppFunctions);
PinnedIPC.addListeners(ipcMain, AppFunctions);
PlatformIPC.addListeners(ipcMain, AppFunctions);
ReleaseIPC.addListeners(ipcMain, AppFunctions);
SkynetIPC.addListeners(ipcMain, AppFunctions);
StateIPC.addListeners(ipcMain, AppFunctions);
SystemIPC.addListeners(ipcMain, AppFunctions);
UpgradeIPC.addListeners(ipcMain, AppFunctions);