freezerpc/app/background.js

364 lines
8.9 KiB
JavaScript

const {app, BrowserWindow, ipcMain, Tray, Menu, session, dialog, shell, nativeTheme} = require('electron');
const {createServer} = require('./src/server');
const path = require('path');
const arg = require('arg');
const { exit } = require('process');
const packageJson = require('./package.json');
const chalk = require('chalk');
const {Settings} = require('./src/settings');
const fs = require('fs');
let win;
let tray;
let settings;
let shouldExit = false;
let playing = false;
//Arguments
const args = arg({
'--server': Boolean,
'--host': String,
'--port': Number,
'--help': Boolean,
'--settings': Boolean,
'--reset-settings': Boolean,
'--reset-downloads': Boolean,
'--log': Boolean,
'-S': '--server',
'-H': '--host',
'-h': '--help',
'-p': '--port'
}, {argv: process.argv.slice(1)});
executeCli();
//Get path to asset
function assetPath(a) {
return path.join(__dirname, 'assets', a);
}
//Execute actions by parameters
function executeCli() {
if (args['--help']) {
console.log(`
${chalk.bold.blue('Freezer PC')} ${chalk.bold(`v${packageJson.version}`)} by exttex
${chalk.bold('USAGE:')}
--help, -h Prints this and exits
--server, -S Starts in server mode
--host, -H Override host (default: 127.0.0.1)
--port, -p Override port (default: 10069)
${chalk.bold('TOOLS:')}
--settings Prints current settings and exits
--log Prints server log and exits
--reset-settings Reset settings to default
--reset-downloads Delete downloads cache and database
`);
exit(0);
}
//Print settings and exit
if (args["--settings"]) {
let settings = new Settings();
settings.load();
console.log(JSON.stringify(settings, null, 2));
exit(0);
}
if (args["--reset-settings"]) {
fs.unlinkSync(Settings.getPath());
exit(0);
}
//Delete downloads db and temp
if (args['--reset-downloads']) {
fs.unlinkSync(Settings.getDownloadsDB());
fs.rmdirSync(Settings.getTempDownloads(), {recursive: true});
exit(0);
}
//Show log
if (args['--log']) {
let p = path.join(Settings.getDir(), "freezer-server.log");
console.log(fs.readFileSync(p, {encoding: 'utf-8'}).toString());
exit(0);
}
}
async function startServer() {
//Override settings
let override = {};
if (args["--host"])
override['host'] = args["--host"];
if (args["--port"])
override['port'] = args["--port"];
settings = await createServer(true, () => {
//Server error
shouldExit = true;
if (win) win.close();
dialog.showMessageBoxSync({
type: 'error',
title: 'Server error',
message: 'Server error occured, Freezer is probably already running!',
buttons: ['Close']
});
}, override);
}
async function createWindow() {
//Create window
win = new BrowserWindow({
width: settings.width,
darkTheme: true,
height: settings.height,
minWidth: 620,
minHeight: 600,
resizable: true,
autoHideMenuBar: true,
frame: false,
icon: assetPath("icon.png"),
title: 'Freezer',
webPreferences: {
enableRemoteModule: true,
nodeIntegration: true,
devTools: true
}
});
win.loadURL(`http://localhost:${settings.port}`);
//Minimize to tray
win.on('minimize', (event) => {
if (settings.minimizeToTray) {
event.preventDefault();
win.hide();
}
});
//On close
win.on('close', async (event) => {
if (shouldExit) {
win = null;
tray = null;
app.quit();
return true;
}
//Normal exit
if (!settings || !settings.arl || settings.arl == '' || settings.closeOnExit) {
win.webContents.send('onExit');
shouldExit = true;
}
event.preventDefault();
win.hide();
return false;
});
//Thumbnail Toolbars
setThumbarButtons();
}
//Single instance
const singleInstanceLock = app.requestSingleInstanceLock();
if (!singleInstanceLock) {
app.quit();
} else {
app.on('second-instance', () => {
if (win) {
if (!win.visible) win.show();
}
});
}
//Create window
app.on('ready', async () => {
await startServer();
//Server mode
if (args['--server']) return;
createWindow();
//Create Tray
if (settings.forceWhiteTrayIcon || nativeTheme.shouldUseDarkColors)
tray = new Tray(assetPath("icon-taskbar-white.png"));
else
tray = new Tray(assetPath("icon-taskbar-black.png"));
tray.on('double-click', () => restoreWindow());
tray.on('click', () => restoreWindow());
setTray();
});
//Restore or create new window
function restoreWindow() {
if (win) {
win.show();
setThumbarButtons();
return;
}
createWindow();
}
//Update tray context menu
function setTray() {
const contextMenu = Menu.buildFromTemplate([
{
label: 'Restore',
type: 'normal',
click: () => restoreWindow()
},
playing ?
{
label: 'Pause',
type: 'normal',
click: () => win.webContents.send('togglePlayback')
}
: {
label: 'Play',
type: 'normal',
click: () => win.webContents.send('togglePlayback')
},
{
label: 'Next',
type: 'normal',
click: () => win.webContents.send('skipNext')
},
{
label: 'Previous',
type: 'normal',
click: () => win.webContents.send('skipPrev')
},
{
label: 'Exit',
type: 'normal',
click: () => {
shouldExit = true;
if (!win) return app.quit();
win.close();
}
}
]);
tray.setContextMenu(contextMenu);
}
//Update Thumbnail Toolbars (Windows)
function setThumbarButtons() {
win.setThumbarButtons([
{
tooltip: 'Skip Previous',
icon: assetPath('skip-previous.png'),
click: () => win.webContents.send('skipPrev')
},
//Play/Pause
playing ?
{
tooltip: 'Pause',
icon: assetPath('pause.png'),
click: () => win.webContents.send('togglePlayback')
} :
{
tooltip: 'Play',
icon: assetPath('play.png'),
click: () => win.webContents.send('togglePlayback')
},
//Skip next
{
tooltip: 'Skip Next',
icon: assetPath('skip-next.png'),
click: () => win.webContents.send('skipNext')
},
]);
}
//[] button
ipcMain.on('maximize', () => {
win.isMaximized() ? win.unmaximize() : win.maximize();
});
//_ button in ui
ipcMain.on('minimize', () => {
win.minimize();
});
//X button in ui
ipcMain.on('close', () => {
win.close();
});
ipcMain.on('openUrl', (event, args) => {
shell.openExternal(args);
});
//Playing state change from UI
ipcMain.on('playing', (event, args) => {
playing = args;
setThumbarButtons();
setTray();
});
//Update settings from ui
ipcMain.on('updateSettings', (event, args) => {
Object.assign(settings, args);
});
//onExit callback
ipcMain.on('onExit', () => {
shouldExit = true;
win.close();
});
//Open downloads directory
ipcMain.on('openDownloadsDir', async () => {
if ((await shell.openPath(settings.downloadsPath)) == "") return;
shell.showItemInFolder(settings.downloadsPath);
});
//Download path picker
ipcMain.on('selectDownloadPath', async (event) => {
let res = await dialog.showOpenDialog({
title: 'Downloads folder',
properties: ['openDirectory', 'promptToCreate'],
});
if (!res.canceled && res.filePaths.length > 0) {
event.reply('selectDownloadPath', res.filePaths[0]);
}
});
//Login using browser
ipcMain.on('browserLogin', async (event) => {
//Initial clean
session.defaultSession.clearStorageData();
let lwin = new BrowserWindow({
width: 800,
height: 600,
icon: assetPath('icon.png'),
title: "Deezer Login",
resizable: true,
autoHideMenuBar: true,
webPreferences: {
nodeIntegration: false
}
});
lwin.loadURL('https://deezer.com/login');
let arl = await new Promise((res) => {
lwin.webContents.on('did-navigate', async () => {
let arlCookie = await session.defaultSession.cookies.get({
name: "arl"
});
if (arlCookie.length > 0) {
res(arlCookie[0].value);
}
});
});
lwin.close();
lwin = null;
//Delete deezer junk
session.defaultSession.clearStorageData();
event.reply('browserLogin', arl);
});