mirror of
https://gitlab.com/futo-org/fcast.git
synced 2025-06-24 21:25:23 +00:00
Added v2 update notification
This commit is contained in:
parent
cc07f95d23
commit
2fa6b6489b
1 changed files with 37 additions and 57 deletions
|
@ -1,4 +1,4 @@
|
||||||
import { BrowserWindow, ipcMain, IpcMainEvent, nativeImage, Tray, Menu, dialog } from 'electron';
|
import { BrowserWindow, ipcMain, IpcMainEvent, nativeImage, Tray, Menu, dialog, shell } from 'electron';
|
||||||
import { TcpListenerService } from './TcpListenerService';
|
import { TcpListenerService } from './TcpListenerService';
|
||||||
import { PlayMessage, PlaybackErrorMessage, PlaybackUpdateMessage, VolumeUpdateMessage } from './Packets';
|
import { PlayMessage, PlaybackErrorMessage, PlaybackUpdateMessage, VolumeUpdateMessage } from './Packets';
|
||||||
import { DiscoveryService } from './DiscoveryService';
|
import { DiscoveryService } from './DiscoveryService';
|
||||||
|
@ -13,7 +13,7 @@ import { AddressInfo } from 'ws';
|
||||||
import { v4 as uuidv4 } from 'uuid';
|
import { v4 as uuidv4 } from 'uuid';
|
||||||
|
|
||||||
export default class Main {
|
export default class Main {
|
||||||
static shouldOpenMainWindow = true;
|
static shouldOpenMainWindow = true;
|
||||||
static playerWindow: Electron.BrowserWindow;
|
static playerWindow: Electron.BrowserWindow;
|
||||||
static mainWindow: Electron.BrowserWindow;
|
static mainWindow: Electron.BrowserWindow;
|
||||||
static application: Electron.App;
|
static application: Electron.App;
|
||||||
|
@ -27,6 +27,21 @@ export default class Main {
|
||||||
static proxyServerAddress: AddressInfo;
|
static proxyServerAddress: AddressInfo;
|
||||||
static proxiedFiles: Map<string, { url: string, headers: { [key: string]: string } }> = new Map();
|
static proxiedFiles: Map<string, { url: string, headers: { [key: string]: string } }> = new Map();
|
||||||
|
|
||||||
|
private static async updateNotify() {
|
||||||
|
const upateURL = 'https://github.com/futo-org/fcast/releases';
|
||||||
|
const updatePrompt = await dialog.showMessageBox({
|
||||||
|
type: 'info',
|
||||||
|
title: 'Major update available',
|
||||||
|
message: 'Please visit https://fcast.org/ to download the latest update',
|
||||||
|
buttons: ['Download', 'Later'],
|
||||||
|
defaultId: 0
|
||||||
|
});
|
||||||
|
|
||||||
|
if (updatePrompt.response === 0) {
|
||||||
|
shell.openExternal(upateURL);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
private static createTray() {
|
private static createTray() {
|
||||||
const icon = (process.platform === 'win32') ? path.join(__dirname, 'app.ico') : path.join(__dirname, 'app.png');
|
const icon = (process.platform === 'win32') ? path.join(__dirname, 'app.ico') : path.join(__dirname, 'app.png');
|
||||||
const trayicon = nativeImage.createFromPath(icon)
|
const trayicon = nativeImage.createFromPath(icon)
|
||||||
|
@ -39,44 +54,7 @@ export default class Main {
|
||||||
{
|
{
|
||||||
label: 'Check for updates',
|
label: 'Check for updates',
|
||||||
click: async () => {
|
click: async () => {
|
||||||
try {
|
await Main.updateNotify();
|
||||||
const updater = new Updater(path.join(__dirname, '../'), 'https://releases.grayjay.app/fcastreceiver');
|
|
||||||
if (await updater.update()) {
|
|
||||||
const restartPrompt = await dialog.showMessageBox({
|
|
||||||
type: 'info',
|
|
||||||
title: 'Update completed',
|
|
||||||
message: 'The application has been updated. Restart now to apply the changes.',
|
|
||||||
buttons: ['Restart'],
|
|
||||||
defaultId: 0
|
|
||||||
});
|
|
||||||
|
|
||||||
console.log('Update completed');
|
|
||||||
|
|
||||||
// Restart the app if the user clicks the 'Restart' button
|
|
||||||
if (restartPrompt.response === 0) {
|
|
||||||
Main.application.relaunch();
|
|
||||||
Main.application.exit(0);
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
await dialog.showMessageBox({
|
|
||||||
type: 'info',
|
|
||||||
title: 'Already up-to-date',
|
|
||||||
message: 'The application is already on the latest version.',
|
|
||||||
buttons: ['OK'],
|
|
||||||
defaultId: 0
|
|
||||||
});
|
|
||||||
}
|
|
||||||
} catch (err) {
|
|
||||||
await dialog.showMessageBox({
|
|
||||||
type: 'error',
|
|
||||||
title: 'Failed to update',
|
|
||||||
message: 'The application failed to update.',
|
|
||||||
buttons: ['OK'],
|
|
||||||
defaultId: 0
|
|
||||||
});
|
|
||||||
|
|
||||||
console.error('Failed to update:', err);
|
|
||||||
}
|
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
|
@ -96,7 +74,7 @@ export default class Main {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
])
|
])
|
||||||
|
|
||||||
tray.setContextMenu(contextMenu);
|
tray.setContextMenu(contextMenu);
|
||||||
this.tray = tray;
|
this.tray = tray;
|
||||||
}
|
}
|
||||||
|
@ -106,7 +84,7 @@ export default class Main {
|
||||||
|
|
||||||
Main.discoveryService = new DiscoveryService();
|
Main.discoveryService = new DiscoveryService();
|
||||||
Main.discoveryService.start();
|
Main.discoveryService.start();
|
||||||
|
|
||||||
Main.tcpListenerService = new TcpListenerService();
|
Main.tcpListenerService = new TcpListenerService();
|
||||||
Main.webSocketListenerService = new WebSocketListenerService();
|
Main.webSocketListenerService = new WebSocketListenerService();
|
||||||
|
|
||||||
|
@ -121,10 +99,10 @@ export default class Main {
|
||||||
preload: path.join(__dirname, 'player/preload.js')
|
preload: path.join(__dirname, 'player/preload.js')
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
Main.playerWindow.setAlwaysOnTop(false, 'pop-up-menu');
|
Main.playerWindow.setAlwaysOnTop(false, 'pop-up-menu');
|
||||||
Main.playerWindow.show();
|
Main.playerWindow.show();
|
||||||
|
|
||||||
Main.playerWindow.loadFile(path.join(__dirname, 'player/index.html'));
|
Main.playerWindow.loadFile(path.join(__dirname, 'player/index.html'));
|
||||||
Main.playerWindow.on('ready-to-show', async () => {
|
Main.playerWindow.on('ready-to-show', async () => {
|
||||||
Main.playerWindow?.webContents?.send("play", await Main.proxyPlayIfRequired(message));
|
Main.playerWindow?.webContents?.send("play", await Main.proxyPlayIfRequired(message));
|
||||||
|
@ -134,17 +112,17 @@ export default class Main {
|
||||||
});
|
});
|
||||||
} else {
|
} else {
|
||||||
Main.playerWindow?.webContents?.send("play", await Main.proxyPlayIfRequired(message));
|
Main.playerWindow?.webContents?.send("play", await Main.proxyPlayIfRequired(message));
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
l.emitter.on("pause", () => Main.playerWindow?.webContents?.send("pause"));
|
l.emitter.on("pause", () => Main.playerWindow?.webContents?.send("pause"));
|
||||||
l.emitter.on("resume", () => Main.playerWindow?.webContents?.send("resume"));
|
l.emitter.on("resume", () => Main.playerWindow?.webContents?.send("resume"));
|
||||||
|
|
||||||
l.emitter.on("stop", () => {
|
l.emitter.on("stop", () => {
|
||||||
Main.playerWindow.close();
|
Main.playerWindow.close();
|
||||||
Main.playerWindow = null;
|
Main.playerWindow = null;
|
||||||
});
|
});
|
||||||
|
|
||||||
l.emitter.on("seek", (message) => Main.playerWindow?.webContents?.send("seek", message));
|
l.emitter.on("seek", (message) => Main.playerWindow?.webContents?.send("seek", message));
|
||||||
l.emitter.on("setvolume", (message) => Main.playerWindow?.webContents?.send("setvolume", message));
|
l.emitter.on("setvolume", (message) => Main.playerWindow?.webContents?.send("setvolume", message));
|
||||||
l.emitter.on("setspeed", (message) => Main.playerWindow?.webContents?.send("setspeed", message));
|
l.emitter.on("setspeed", (message) => Main.playerWindow?.webContents?.send("setspeed", message));
|
||||||
|
@ -157,7 +135,7 @@ export default class Main {
|
||||||
ipcMain.on('send-playback-update', (event: IpcMainEvent, value: PlaybackUpdateMessage) => {
|
ipcMain.on('send-playback-update', (event: IpcMainEvent, value: PlaybackUpdateMessage) => {
|
||||||
l.send(Opcode.PlaybackUpdate, value);
|
l.send(Opcode.PlaybackUpdate, value);
|
||||||
});
|
});
|
||||||
|
|
||||||
ipcMain.on('send-volume-update', (event: IpcMainEvent, value: VolumeUpdateMessage) => {
|
ipcMain.on('send-volume-update', (event: IpcMainEvent, value: VolumeUpdateMessage) => {
|
||||||
l.send(Opcode.VolumeUpdate, value);
|
l.send(Opcode.VolumeUpdate, value);
|
||||||
});
|
});
|
||||||
|
@ -184,6 +162,8 @@ export default class Main {
|
||||||
if (Main.shouldOpenMainWindow) {
|
if (Main.shouldOpenMainWindow) {
|
||||||
Main.openMainWindow();
|
Main.openMainWindow();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Main.updateNotify();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@ -198,7 +178,7 @@ export default class Main {
|
||||||
const requestUrl = `http://${req.headers.host}${req.url}`;
|
const requestUrl = `http://${req.headers.host}${req.url}`;
|
||||||
|
|
||||||
const proxyInfo = Main.proxiedFiles.get(requestUrl);
|
const proxyInfo = Main.proxiedFiles.get(requestUrl);
|
||||||
|
|
||||||
if (!proxyInfo) {
|
if (!proxyInfo) {
|
||||||
res.writeHead(404);
|
res.writeHead(404);
|
||||||
res.end('Not found');
|
res.end('Not found');
|
||||||
|
@ -215,8 +195,8 @@ export default class Main {
|
||||||
'trailers',
|
'trailers',
|
||||||
'transfer-encoding',
|
'transfer-encoding',
|
||||||
'upgrade'
|
'upgrade'
|
||||||
]);
|
]);
|
||||||
|
|
||||||
const filteredHeaders = Object.fromEntries(Object.entries(req.headers)
|
const filteredHeaders = Object.fromEntries(Object.entries(req.headers)
|
||||||
.filter(([key]) => !omitHeaders.has(key.toLowerCase()))
|
.filter(([key]) => !omitHeaders.has(key.toLowerCase()))
|
||||||
.map(([key, value]) => [key, Array.isArray(value) ? value.join(', ') : value]));
|
.map(([key, value]) => [key, Array.isArray(value) ? value.join(', ') : value]));
|
||||||
|
@ -232,7 +212,7 @@ export default class Main {
|
||||||
res.writeHead(proxyRes.statusCode, proxyRes.headers);
|
res.writeHead(proxyRes.statusCode, proxyRes.headers);
|
||||||
proxyRes.pipe(res, { end: true });
|
proxyRes.pipe(res, { end: true });
|
||||||
});
|
});
|
||||||
|
|
||||||
req.pipe(proxyReq, { end: true });
|
req.pipe(proxyReq, { end: true });
|
||||||
proxyReq.on('error', (e) => {
|
proxyReq.on('error', (e) => {
|
||||||
console.error(`Problem with request: ${e.message}`);
|
console.error(`Problem with request: ${e.message}`);
|
||||||
|
@ -281,18 +261,18 @@ export default class Main {
|
||||||
static getAllIPv4Addresses() {
|
static getAllIPv4Addresses() {
|
||||||
const interfaces = os.networkInterfaces();
|
const interfaces = os.networkInterfaces();
|
||||||
const ipv4Addresses: string[] = [];
|
const ipv4Addresses: string[] = [];
|
||||||
|
|
||||||
for (const interfaceName in interfaces) {
|
for (const interfaceName in interfaces) {
|
||||||
const addresses = interfaces[interfaceName];
|
const addresses = interfaces[interfaceName];
|
||||||
if (!addresses) continue;
|
if (!addresses) continue;
|
||||||
|
|
||||||
for (const addressInfo of addresses) {
|
for (const addressInfo of addresses) {
|
||||||
if (addressInfo.family === 'IPv4' && !addressInfo.internal) {
|
if (addressInfo.family === 'IPv4' && !addressInfo.internal) {
|
||||||
ipv4Addresses.push(addressInfo.address);
|
ipv4Addresses.push(addressInfo.address);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return ipv4Addresses;
|
return ipv4Addresses;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -322,7 +302,7 @@ export default class Main {
|
||||||
Main.mainWindow.on('ready-to-show', () => {
|
Main.mainWindow.on('ready-to-show', () => {
|
||||||
Main.mainWindow.webContents.send("device-info", {name: os.hostname(), addresses: Main.getAllIPv4Addresses()});
|
Main.mainWindow.webContents.send("device-info", {name: os.hostname(), addresses: Main.getAllIPv4Addresses()});
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
static main(app: Electron.App) {
|
static main(app: Electron.App) {
|
||||||
Main.application = app;
|
Main.application = app;
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue