1
0
Fork 0
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:
Michael Hollister 2024-11-21 15:46:41 -06:00
parent cc07f95d23
commit 2fa6b6489b

View file

@ -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;