mirror of
https://gitlab.com/futo-org/fcast.git
synced 2025-06-24 21:25:23 +00:00
Receivers: Added unified logger module
This commit is contained in:
parent
7f9d7939bc
commit
b24b3f0c55
17 changed files with 351 additions and 117 deletions
|
@ -7,6 +7,7 @@ let uiUpdateCallbacks = {
|
||||||
onConnect: null,
|
onConnect: null,
|
||||||
onDisconnect: null,
|
onDisconnect: null,
|
||||||
}
|
}
|
||||||
|
const logger = window.targetAPI.logger;
|
||||||
|
|
||||||
// Window might be re-created while devices are still connected
|
// Window might be re-created while devices are still connected
|
||||||
export function setUiUpdateCallbacks(callbacks: any) {
|
export function setUiUpdateCallbacks(callbacks: any) {
|
||||||
|
@ -27,12 +28,12 @@ window.targetAPI.onPing((_event, value: any) => onPingPong(value));
|
||||||
window.targetAPI.onPong((_event, value: any) => onPingPong(value));
|
window.targetAPI.onPong((_event, value: any) => onPingPong(value));
|
||||||
|
|
||||||
window.targetAPI.onConnect((_event, value: any) => {
|
window.targetAPI.onConnect((_event, value: any) => {
|
||||||
console.log(`Device connected: ${JSON.stringify(value)}`);
|
logger.info(`Device connected: ${JSON.stringify(value)}`);
|
||||||
connections.push(value.sessionId);
|
connections.push(value.sessionId);
|
||||||
uiUpdateCallbacks.onConnect(connections);
|
uiUpdateCallbacks.onConnect(connections);
|
||||||
});
|
});
|
||||||
window.targetAPI.onDisconnect((_event, value: any) => {
|
window.targetAPI.onDisconnect((_event, value: any) => {
|
||||||
console.log(`Device disconnected: ${JSON.stringify(value)}`);
|
logger.info(`Device disconnected: ${JSON.stringify(value)}`);
|
||||||
const index = connections.indexOf(value.sessionId);
|
const index = connections.indexOf(value.sessionId);
|
||||||
if (index != -1) {
|
if (index != -1) {
|
||||||
connections.splice(index, 1);
|
connections.splice(index, 1);
|
||||||
|
@ -46,7 +47,7 @@ setInterval(() => {
|
||||||
|
|
||||||
for (const sessionId of connections) {
|
for (const sessionId of connections) {
|
||||||
if (heartbeatRetries[sessionId] > 3) {
|
if (heartbeatRetries[sessionId] > 3) {
|
||||||
console.warn(`Could not ping device with connection id ${sessionId}. Disconnecting...`);
|
logger.warn(`Could not ping device with connection id ${sessionId}. Disconnecting...`);
|
||||||
window.targetAPI.disconnectDevice(sessionId);
|
window.targetAPI.disconnectDevice(sessionId);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -1,5 +1,7 @@
|
||||||
import mdns from 'modules/mdns-js';
|
import mdns from 'modules/mdns-js';
|
||||||
import { Main, getComputerName } from 'src/Main';
|
import { Logger, LoggerType } from 'common/Logger';
|
||||||
|
import { getComputerName } from 'src/Main';
|
||||||
|
const logger = new Logger('DiscoveryService', LoggerType.BACKEND);
|
||||||
|
|
||||||
export class DiscoveryService {
|
export class DiscoveryService {
|
||||||
private serviceTcp: any;
|
private serviceTcp: any;
|
||||||
|
@ -11,13 +13,7 @@ export class DiscoveryService {
|
||||||
}
|
}
|
||||||
|
|
||||||
const name = `FCast-${getComputerName()}`;
|
const name = `FCast-${getComputerName()}`;
|
||||||
// Cannot reference Main during static class initialization
|
logger.info(`Discovery service started: ${name}`);
|
||||||
// @ts-ignore
|
|
||||||
if (TARGET === 'webOS') {
|
|
||||||
console.log(`Discovery service started: ${name}`);
|
|
||||||
} else {
|
|
||||||
Main.logger.info(`Discovery service started: ${name}`);
|
|
||||||
}
|
|
||||||
|
|
||||||
this.serviceTcp = mdns.createAdvertisement(mdns.tcp('_fcast'), 46899, { name: name });
|
this.serviceTcp = mdns.createAdvertisement(mdns.tcp('_fcast'), 46899, { name: name });
|
||||||
this.serviceTcp.start();
|
this.serviceTcp.start();
|
||||||
|
|
|
@ -1,10 +1,10 @@
|
||||||
import * as net from 'net';
|
import * as net from 'net';
|
||||||
import * as log4js from "modules/log4js";
|
|
||||||
import { EventEmitter } from 'events';
|
import { EventEmitter } from 'events';
|
||||||
import { Opcode, PlaybackErrorMessage, PlaybackUpdateMessage, PlayMessage, SeekMessage, SetSpeedMessage, SetVolumeMessage, VersionMessage, VolumeUpdateMessage } from 'common/Packets';
|
import { Opcode, PlaybackErrorMessage, PlaybackUpdateMessage, PlayMessage, SeekMessage, SetSpeedMessage, SetVolumeMessage, VersionMessage, VolumeUpdateMessage } from 'common/Packets';
|
||||||
|
import { Logger, LoggerType } from 'common/Logger';
|
||||||
import { WebSocket } from 'modules/ws';
|
import { WebSocket } from 'modules/ws';
|
||||||
import { v4 as uuidv4 } from 'modules/uuid';
|
import { v4 as uuidv4 } from 'modules/uuid';
|
||||||
const logger = log4js.getLogger();
|
const logger = new Logger('FCastSession', LoggerType.BACKEND);
|
||||||
|
|
||||||
enum SessionState {
|
enum SessionState {
|
||||||
Idle = 0,
|
Idle = 0,
|
||||||
|
@ -100,7 +100,7 @@ export class FCastSession {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
logger.info(`${receivedBytes.length} bytes received`);
|
logger.debug(`${receivedBytes.length} bytes received`);
|
||||||
|
|
||||||
switch (this.state) {
|
switch (this.state) {
|
||||||
case SessionState.WaitingForLength:
|
case SessionState.WaitingForLength:
|
||||||
|
@ -110,7 +110,7 @@ export class FCastSession {
|
||||||
this.handlePacketBytes(receivedBytes);
|
this.handlePacketBytes(receivedBytes);
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
logger.info(`Data received is unhandled in current session state ${this.state}.`);
|
logger.warn(`Data received is unhandled in current session state ${this.state}.`);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -121,20 +121,20 @@ export class FCastSession {
|
||||||
receivedBytes.copy(this.buffer, this.bytesRead, 0, bytesToRead);
|
receivedBytes.copy(this.buffer, this.bytesRead, 0, bytesToRead);
|
||||||
this.bytesRead += bytesToRead;
|
this.bytesRead += bytesToRead;
|
||||||
|
|
||||||
logger.info(`handleLengthBytes: Read ${bytesToRead} bytes from packet`);
|
logger.debug(`handleLengthBytes: Read ${bytesToRead} bytes from packet`);
|
||||||
|
|
||||||
if (this.bytesRead >= LENGTH_BYTES) {
|
if (this.bytesRead >= LENGTH_BYTES) {
|
||||||
this.state = SessionState.WaitingForData;
|
this.state = SessionState.WaitingForData;
|
||||||
this.packetLength = this.buffer.readUInt32LE(0);
|
this.packetLength = this.buffer.readUInt32LE(0);
|
||||||
this.bytesRead = 0;
|
this.bytesRead = 0;
|
||||||
logger.info(`Packet length header received from: ${this.packetLength}`);
|
logger.debug(`Packet length header received from: ${this.packetLength}`);
|
||||||
|
|
||||||
if (this.packetLength > MAXIMUM_PACKET_LENGTH) {
|
if (this.packetLength > MAXIMUM_PACKET_LENGTH) {
|
||||||
throw new Error(`Maximum packet length is 32kB: ${this.packetLength}`);
|
throw new Error(`Maximum packet length is 32kB: ${this.packetLength}`);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (bytesRemaining > 0) {
|
if (bytesRemaining > 0) {
|
||||||
logger.info(`${bytesRemaining} remaining bytes pushed to handlePacketBytes`);
|
logger.debug(`${bytesRemaining} remaining bytes pushed to handlePacketBytes`);
|
||||||
this.handlePacketBytes(receivedBytes.slice(bytesToRead));
|
this.handlePacketBytes(receivedBytes.slice(bytesToRead));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -146,10 +146,10 @@ export class FCastSession {
|
||||||
receivedBytes.copy(this.buffer, this.bytesRead, 0, bytesToRead);
|
receivedBytes.copy(this.buffer, this.bytesRead, 0, bytesToRead);
|
||||||
this.bytesRead += bytesToRead;
|
this.bytesRead += bytesToRead;
|
||||||
|
|
||||||
logger.info(`handlePacketBytes: Read ${bytesToRead} bytes from packet`);
|
logger.debug(`handlePacketBytes: Read ${bytesToRead} bytes from packet`);
|
||||||
|
|
||||||
if (this.bytesRead >= this.packetLength) {
|
if (this.bytesRead >= this.packetLength) {
|
||||||
logger.info(`Packet finished receiving from of ${this.packetLength} bytes.`);
|
logger.debug(`handlePacketBytes: Finished handling packet with ${this.packetLength} bytes. Total bytes read ${this.bytesRead}.`);
|
||||||
this.handleNextPacket();
|
this.handleNextPacket();
|
||||||
|
|
||||||
this.state = SessionState.WaitingForLength;
|
this.state = SessionState.WaitingForLength;
|
||||||
|
@ -157,7 +157,7 @@ export class FCastSession {
|
||||||
this.bytesRead = 0;
|
this.bytesRead = 0;
|
||||||
|
|
||||||
if (bytesRemaining > 0) {
|
if (bytesRemaining > 0) {
|
||||||
logger.info(`${bytesRemaining} remaining bytes pushed to handleLengthBytes`);
|
logger.debug(`${bytesRemaining} remaining bytes pushed to handleLengthBytes`);
|
||||||
this.handleLengthBytes(receivedBytes.slice(bytesToRead));
|
this.handleLengthBytes(receivedBytes.slice(bytesToRead));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -206,11 +206,8 @@ export class FCastSession {
|
||||||
}
|
}
|
||||||
|
|
||||||
private handleNextPacket() {
|
private handleNextPacket() {
|
||||||
logger.info(`Processing packet of ${this.bytesRead} bytes from`);
|
|
||||||
|
|
||||||
const opcode = this.buffer[0];
|
const opcode = this.buffer[0];
|
||||||
const body = this.packetLength > 1 ? this.buffer.toString('utf8', 1, this.packetLength) : null;
|
const body = this.packetLength > 1 ? this.buffer.toString('utf8', 1, this.packetLength) : null;
|
||||||
logger.info('body', body);
|
|
||||||
this.handlePacket(opcode, body);
|
this.handlePacket(opcode, body);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
197
receivers/common/web/Logger.ts
Normal file
197
receivers/common/web/Logger.ts
Normal file
|
@ -0,0 +1,197 @@
|
||||||
|
|
||||||
|
export enum LoggerType {
|
||||||
|
BACKEND,
|
||||||
|
FRONTEND,
|
||||||
|
}
|
||||||
|
|
||||||
|
export class Logger {
|
||||||
|
private static log4js = null;
|
||||||
|
private static ipcLoggerTags = {
|
||||||
|
trace: [],
|
||||||
|
debug: [],
|
||||||
|
info: [],
|
||||||
|
warn: [],
|
||||||
|
error: [],
|
||||||
|
fatal: [],
|
||||||
|
};
|
||||||
|
private funcTable = {
|
||||||
|
trace: console.trace,
|
||||||
|
debug: console.debug,
|
||||||
|
info: console.log,
|
||||||
|
warn: console.warn,
|
||||||
|
error: console.error,
|
||||||
|
fatal: console.error,
|
||||||
|
};
|
||||||
|
|
||||||
|
public static initialize(config: any) {
|
||||||
|
// @ts-ignore
|
||||||
|
if (TARGET === 'electron') {
|
||||||
|
// @ts-ignore
|
||||||
|
const electronAPI = __non_webpack_require__('electron');
|
||||||
|
|
||||||
|
// @ts-ignore
|
||||||
|
Logger.log4js = __non_webpack_require__('log4js');
|
||||||
|
Logger.log4js.configure(config);
|
||||||
|
let logger = Logger.log4js.getLogger();
|
||||||
|
|
||||||
|
electronAPI.ipcMain.on('logger-trace', (event, value) => {
|
||||||
|
if (!Logger.ipcLoggerTags.trace.includes(value.tag)) {
|
||||||
|
Logger.ipcLoggerTags.trace.push(value.tag);
|
||||||
|
logger = Logger.log4js.getLogger(value.tag);
|
||||||
|
}
|
||||||
|
|
||||||
|
logger.info(value.message, ...value.optionalParams);
|
||||||
|
});
|
||||||
|
|
||||||
|
electronAPI.ipcMain.on('logger-debug', (event, value) => {
|
||||||
|
if (!Logger.ipcLoggerTags.debug.includes(value.tag)) {
|
||||||
|
Logger.ipcLoggerTags.debug.push(value.tag);
|
||||||
|
logger = Logger.log4js.getLogger(value.tag);
|
||||||
|
}
|
||||||
|
|
||||||
|
logger.info(value.message, ...value.optionalParams);
|
||||||
|
});
|
||||||
|
|
||||||
|
electronAPI.ipcMain.on('logger-info', (event, value) => {
|
||||||
|
if (!Logger.ipcLoggerTags.info.includes(value.tag)) {
|
||||||
|
Logger.ipcLoggerTags.info.push(value.tag);
|
||||||
|
logger = Logger.log4js.getLogger(value.tag);
|
||||||
|
}
|
||||||
|
|
||||||
|
logger.info(value.message, ...value.optionalParams);
|
||||||
|
});
|
||||||
|
|
||||||
|
electronAPI.ipcMain.on('logger-warn', (event, value) => {
|
||||||
|
if (!Logger.ipcLoggerTags.warn.includes(value.tag)) {
|
||||||
|
Logger.ipcLoggerTags.warn.push(value.tag);
|
||||||
|
logger = Logger.log4js.getLogger(value.tag);
|
||||||
|
}
|
||||||
|
|
||||||
|
logger.warn(value.message, ...value.optionalParams);
|
||||||
|
});
|
||||||
|
|
||||||
|
electronAPI.ipcMain.on('logger-error', (event, value) => {
|
||||||
|
if (!Logger.ipcLoggerTags.error.includes(value.tag)) {
|
||||||
|
Logger.ipcLoggerTags.error.push(value.tag);
|
||||||
|
logger = Logger.log4js.getLogger(value.tag);
|
||||||
|
}
|
||||||
|
|
||||||
|
logger.error(value.message, ...value.optionalParams);
|
||||||
|
});
|
||||||
|
|
||||||
|
electronAPI.ipcMain.on('logger-fatal', (event, value) => {
|
||||||
|
if (!Logger.ipcLoggerTags.fatal.includes(value.tag)) {
|
||||||
|
Logger.ipcLoggerTags.fatal.push(value.tag);
|
||||||
|
logger = Logger.log4js.getLogger(value.tag);
|
||||||
|
}
|
||||||
|
|
||||||
|
logger.fatal(value.message, ...value.optionalParams);
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
constructor(tag: string = 'default', type: LoggerType = LoggerType.FRONTEND) {
|
||||||
|
// @ts-ignore
|
||||||
|
if (TARGET === 'electron') {
|
||||||
|
if (type === LoggerType.BACKEND) {
|
||||||
|
// log4js should be initialized via the static method, but providing fallback when logger is used
|
||||||
|
// before initialization as done currently by the Store module on startup.
|
||||||
|
if (!Logger.log4js) {
|
||||||
|
// @ts-ignore
|
||||||
|
Logger.log4js = __non_webpack_require__('log4js');
|
||||||
|
}
|
||||||
|
|
||||||
|
const logger = Logger.log4js.getLogger(tag);
|
||||||
|
this.funcTable = {
|
||||||
|
trace: (message?: any, ...optionalParams: any[]) => {
|
||||||
|
logger.trace(message, ...optionalParams);
|
||||||
|
},
|
||||||
|
debug: (message?: any, ...optionalParams: any[]) => {
|
||||||
|
logger.debug(message, ...optionalParams);
|
||||||
|
},
|
||||||
|
info: (message?: any, ...optionalParams: any[]) => {
|
||||||
|
logger.info(message, ...optionalParams);
|
||||||
|
},
|
||||||
|
warn: (message?: any, ...optionalParams: any[]) => {
|
||||||
|
logger.warn(message, ...optionalParams);
|
||||||
|
},
|
||||||
|
error: (message?: any, ...optionalParams: any[]) => {
|
||||||
|
logger.error(message, ...optionalParams);
|
||||||
|
},
|
||||||
|
fatal: (message?: any, ...optionalParams: any[]) => {
|
||||||
|
logger.fatal(message, ...optionalParams);
|
||||||
|
},
|
||||||
|
};
|
||||||
|
}
|
||||||
|
else if (type === LoggerType.FRONTEND) {
|
||||||
|
// @ts-ignore
|
||||||
|
const electronAPI = __non_webpack_require__('electron');
|
||||||
|
|
||||||
|
this.funcTable = {
|
||||||
|
trace: (message?: any, ...optionalParams: any[]) => {
|
||||||
|
console.trace(message, ...optionalParams);
|
||||||
|
electronAPI.ipcRenderer.send('logger-trace', { tag: tag, message: message, optionalParams: optionalParams });
|
||||||
|
},
|
||||||
|
debug: (message?: any, ...optionalParams: any[]) => {
|
||||||
|
console.debug(message, ...optionalParams);
|
||||||
|
electronAPI.ipcRenderer.send('logger-debug', { tag: tag, message: message, optionalParams: optionalParams });
|
||||||
|
},
|
||||||
|
info: (message?: any, ...optionalParams: any[]) => {
|
||||||
|
console.log(message, ...optionalParams);
|
||||||
|
electronAPI.ipcRenderer.send('logger-info', { tag: tag, message: message, optionalParams: optionalParams });
|
||||||
|
},
|
||||||
|
warn: (message?: any, ...optionalParams: any[]) => {
|
||||||
|
console.warn(message, ...optionalParams);
|
||||||
|
electronAPI.ipcRenderer.send('logger-warn', { tag: tag, message: message, optionalParams: optionalParams });
|
||||||
|
},
|
||||||
|
error: (message?: any, ...optionalParams: any[]) => {
|
||||||
|
console.error(message, ...optionalParams);
|
||||||
|
electronAPI.ipcRenderer.send('logger-error', { tag: tag, message: message, optionalParams: optionalParams });
|
||||||
|
},
|
||||||
|
fatal: (message?: any, ...optionalParams: any[]) => {
|
||||||
|
console.error(message, ...optionalParams);
|
||||||
|
electronAPI.ipcRenderer.send('logger-fatal', { tag: tag, message: message, optionalParams: optionalParams });
|
||||||
|
},
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
// @ts-ignore
|
||||||
|
} else if (TARGET === 'webOS' || TARGET === 'tizenOS') {
|
||||||
|
|
||||||
|
} else {
|
||||||
|
// @ts-ignore
|
||||||
|
console.warn(`Attempting to initialize logger on unsupported target: ${TARGET}`);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public trace(message?: any, ...optionalParams: any[]): void {
|
||||||
|
this.funcTable.trace(message, ...optionalParams);
|
||||||
|
}
|
||||||
|
|
||||||
|
public debug(message?: any, ...optionalParams: any[]): void {
|
||||||
|
this.funcTable.debug(message, ...optionalParams);
|
||||||
|
}
|
||||||
|
|
||||||
|
public info(message?: any, ...optionalParams: any[]): void {
|
||||||
|
this.funcTable.info(message, ...optionalParams);
|
||||||
|
}
|
||||||
|
|
||||||
|
public warn(message?: any, ...optionalParams: any[]): void {
|
||||||
|
this.funcTable.warn(message, ...optionalParams);
|
||||||
|
}
|
||||||
|
|
||||||
|
public error(message?: any, ...optionalParams: any[]): void {
|
||||||
|
this.funcTable.error(message, ...optionalParams);
|
||||||
|
}
|
||||||
|
|
||||||
|
public fatal(message?: any, ...optionalParams: any[]): void {
|
||||||
|
this.funcTable.fatal(message, ...optionalParams);
|
||||||
|
}
|
||||||
|
|
||||||
|
public shutdown() {
|
||||||
|
// @ts-ignore
|
||||||
|
if (TARGET === 'electron') {
|
||||||
|
Logger.log4js.shutdown();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
|
@ -3,7 +3,8 @@ import * as http from 'http';
|
||||||
import * as url from 'url';
|
import * as url from 'url';
|
||||||
import { AddressInfo } from 'modules/ws';
|
import { AddressInfo } from 'modules/ws';
|
||||||
import { v4 as uuidv4 } from 'modules/uuid';
|
import { v4 as uuidv4 } from 'modules/uuid';
|
||||||
import { Main } from 'src/Main';
|
import { Logger, LoggerType } from 'common/Logger';
|
||||||
|
const logger = new Logger('NetworkService', LoggerType.BACKEND);
|
||||||
|
|
||||||
export class NetworkService {
|
export class NetworkService {
|
||||||
static key: string = null;
|
static key: string = null;
|
||||||
|
@ -15,11 +16,11 @@ export class NetworkService {
|
||||||
private static setupProxyServer(): Promise<void> {
|
private static setupProxyServer(): Promise<void> {
|
||||||
return new Promise<void>((resolve, reject) => {
|
return new Promise<void>((resolve, reject) => {
|
||||||
try {
|
try {
|
||||||
Main.logger.info(`Proxy server starting`);
|
logger.info(`Proxy server starting`);
|
||||||
|
|
||||||
const port = 0;
|
const port = 0;
|
||||||
NetworkService.proxyServer = http.createServer((req, res) => {
|
NetworkService.proxyServer = http.createServer((req, res) => {
|
||||||
Main.logger.info(`Request received`);
|
logger.info(`Request received`);
|
||||||
const requestUrl = `http://${req.headers.host}${req.url}`;
|
const requestUrl = `http://${req.headers.host}${req.url}`;
|
||||||
|
|
||||||
const proxyInfo = NetworkService.proxiedFiles.get(requestUrl);
|
const proxyInfo = NetworkService.proxiedFiles.get(requestUrl);
|
||||||
|
@ -60,7 +61,7 @@ export class NetworkService {
|
||||||
|
|
||||||
req.pipe(proxyReq, { end: true });
|
req.pipe(proxyReq, { end: true });
|
||||||
proxyReq.on('error', (e) => {
|
proxyReq.on('error', (e) => {
|
||||||
Main.logger.error(`Problem with request: ${e.message}`);
|
logger.error(`Problem with request: ${e.message}`);
|
||||||
res.writeHead(500);
|
res.writeHead(500);
|
||||||
res.end();
|
res.end();
|
||||||
});
|
});
|
||||||
|
@ -70,7 +71,7 @@ export class NetworkService {
|
||||||
});
|
});
|
||||||
NetworkService.proxyServer.listen(port, '127.0.0.1', () => {
|
NetworkService.proxyServer.listen(port, '127.0.0.1', () => {
|
||||||
NetworkService.proxyServerAddress = NetworkService.proxyServer.address() as AddressInfo;
|
NetworkService.proxyServerAddress = NetworkService.proxyServer.address() as AddressInfo;
|
||||||
Main.logger.info(`Proxy server running at http://127.0.0.1:${NetworkService.proxyServerAddress.port}/`);
|
logger.info(`Proxy server running at http://127.0.0.1:${NetworkService.proxyServerAddress.port}/`);
|
||||||
resolve();
|
resolve();
|
||||||
});
|
});
|
||||||
} catch (e) {
|
} catch (e) {
|
||||||
|
@ -98,7 +99,7 @@ export class NetworkService {
|
||||||
}
|
}
|
||||||
|
|
||||||
const proxiedUrl = `http://127.0.0.1:${NetworkService.proxyServerAddress.port}/${uuidv4()}`;
|
const proxiedUrl = `http://127.0.0.1:${NetworkService.proxyServerAddress.port}/${uuidv4()}`;
|
||||||
Main.logger.info("Proxied url", { proxiedUrl, url, headers });
|
logger.info("Proxied url", { proxiedUrl, url, headers });
|
||||||
NetworkService.proxiedFiles.set(proxiedUrl, { url: url, headers: headers });
|
NetworkService.proxiedFiles.set(proxiedUrl, { url: url, headers: headers });
|
||||||
return proxiedUrl;
|
return proxiedUrl;
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,8 +1,10 @@
|
||||||
import * as net from 'net';
|
import * as net from 'net';
|
||||||
import { FCastSession } from 'common/FCastSession';
|
import { FCastSession } from 'common/FCastSession';
|
||||||
import { Opcode } from 'common/Packets';
|
import { Opcode } from 'common/Packets';
|
||||||
|
import { Logger, LoggerType } from 'common/Logger';
|
||||||
import { EventEmitter } from 'events';
|
import { EventEmitter } from 'events';
|
||||||
import { Main, errorHandler } from 'src/Main';
|
import { errorHandler } from 'src/Main';
|
||||||
|
const logger = new Logger('TcpListenerService', LoggerType.BACKEND);
|
||||||
|
|
||||||
export class TcpListenerService {
|
export class TcpListenerService {
|
||||||
public static PORT = 46899;
|
public static PORT = 46899;
|
||||||
|
@ -35,12 +37,12 @@ export class TcpListenerService {
|
||||||
}
|
}
|
||||||
|
|
||||||
send(opcode: number, message = null) {
|
send(opcode: number, message = null) {
|
||||||
// Main.logger.info(`Sending message ${JSON.stringify(message)}`);
|
// logger.info(`Sending message ${JSON.stringify(message)}`);
|
||||||
this.sessions.forEach(session => {
|
this.sessions.forEach(session => {
|
||||||
try {
|
try {
|
||||||
session.send(opcode, message);
|
session.send(opcode, message);
|
||||||
} catch (e) {
|
} catch (e) {
|
||||||
Main.logger.warn("Failed to send error.", e);
|
logger.warn("Failed to send error.", e);
|
||||||
session.close();
|
session.close();
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
@ -60,7 +62,7 @@ export class TcpListenerService {
|
||||||
}
|
}
|
||||||
|
|
||||||
private handleConnection(socket: net.Socket) {
|
private handleConnection(socket: net.Socket) {
|
||||||
Main.logger.info(`New connection from ${socket.remoteAddress}:${socket.remotePort}`);
|
logger.info(`New connection from ${socket.remoteAddress}:${socket.remotePort}`);
|
||||||
|
|
||||||
const session = new FCastSession(socket, (data) => socket.write(data));
|
const session = new FCastSession(socket, (data) => socket.write(data));
|
||||||
session.bindEvents(this.emitter);
|
session.bindEvents(this.emitter);
|
||||||
|
@ -68,7 +70,7 @@ export class TcpListenerService {
|
||||||
this.sessionMap.set(session.sessionId, session);
|
this.sessionMap.set(session.sessionId, session);
|
||||||
|
|
||||||
socket.on("error", (err) => {
|
socket.on("error", (err) => {
|
||||||
Main.logger.warn(`Error from ${socket.remoteAddress}:${socket.remotePort}.`, err);
|
logger.warn(`Error from ${socket.remoteAddress}:${socket.remotePort}.`, err);
|
||||||
this.disconnect(session.sessionId);
|
this.disconnect(session.sessionId);
|
||||||
});
|
});
|
||||||
|
|
||||||
|
@ -76,7 +78,7 @@ export class TcpListenerService {
|
||||||
try {
|
try {
|
||||||
session.processBytes(buffer);
|
session.processBytes(buffer);
|
||||||
} catch (e) {
|
} catch (e) {
|
||||||
Main.logger.warn(`Error while handling packet from ${socket.remoteAddress}:${socket.remotePort}.`, e);
|
logger.warn(`Error while handling packet from ${socket.remoteAddress}:${socket.remotePort}.`, e);
|
||||||
socket.end();
|
socket.end();
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
@ -91,10 +93,10 @@ export class TcpListenerService {
|
||||||
|
|
||||||
this.emitter.emit('connect', { sessionId: session.sessionId, type: 'tcp', data: { address: socket.remoteAddress, port: socket.remotePort }});
|
this.emitter.emit('connect', { sessionId: session.sessionId, type: 'tcp', data: { address: socket.remoteAddress, port: socket.remotePort }});
|
||||||
try {
|
try {
|
||||||
Main.logger.info('Sending version');
|
logger.info('Sending version');
|
||||||
session.send(Opcode.Version, {version: 2});
|
session.send(Opcode.Version, {version: 2});
|
||||||
} catch (e) {
|
} catch (e) {
|
||||||
Main.logger.info('Failed to send version', e);
|
logger.info('Failed to send version', e);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,8 +1,10 @@
|
||||||
import { FCastSession } from 'common/FCastSession';
|
import { FCastSession } from 'common/FCastSession';
|
||||||
import { Opcode } from 'common/Packets';
|
import { Opcode } from 'common/Packets';
|
||||||
|
import { Logger, LoggerType } from 'common/Logger';
|
||||||
import { EventEmitter } from 'events';
|
import { EventEmitter } from 'events';
|
||||||
import { WebSocket, WebSocketServer } from 'modules/ws';
|
import { WebSocket, WebSocketServer } from 'modules/ws';
|
||||||
import { Main, errorHandler } from 'src/Main';
|
import { errorHandler } from 'src/Main';
|
||||||
|
const logger = new Logger('WebSocketListenerService', LoggerType.BACKEND);
|
||||||
|
|
||||||
export class WebSocketListenerService {
|
export class WebSocketListenerService {
|
||||||
public static PORT = 46898;
|
public static PORT = 46898;
|
||||||
|
@ -39,7 +41,7 @@ export class WebSocketListenerService {
|
||||||
try {
|
try {
|
||||||
session.send(opcode, message);
|
session.send(opcode, message);
|
||||||
} catch (e) {
|
} catch (e) {
|
||||||
Main.logger.warn("Failed to send error.", e);
|
logger.warn("Failed to send error.", e);
|
||||||
session.close();
|
session.close();
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
@ -59,7 +61,7 @@ export class WebSocketListenerService {
|
||||||
}
|
}
|
||||||
|
|
||||||
private handleConnection(socket: WebSocket) {
|
private handleConnection(socket: WebSocket) {
|
||||||
Main.logger.info('New WebSocket connection');
|
logger.info('New WebSocket connection');
|
||||||
|
|
||||||
const session = new FCastSession(socket, (data) => socket.send(data));
|
const session = new FCastSession(socket, (data) => socket.send(data));
|
||||||
session.bindEvents(this.emitter);
|
session.bindEvents(this.emitter);
|
||||||
|
@ -67,7 +69,7 @@ export class WebSocketListenerService {
|
||||||
this.sessionMap.set(session.sessionId, session);
|
this.sessionMap.set(session.sessionId, session);
|
||||||
|
|
||||||
socket.on("error", (err) => {
|
socket.on("error", (err) => {
|
||||||
Main.logger.warn(`Error.`, err);
|
logger.warn(`Error.`, err);
|
||||||
this.disconnect(session.sessionId);
|
this.disconnect(session.sessionId);
|
||||||
});
|
});
|
||||||
|
|
||||||
|
@ -76,16 +78,16 @@ export class WebSocketListenerService {
|
||||||
if (data instanceof Buffer) {
|
if (data instanceof Buffer) {
|
||||||
session.processBytes(data);
|
session.processBytes(data);
|
||||||
} else {
|
} else {
|
||||||
Main.logger.warn("Received unhandled string message", data);
|
logger.warn("Received unhandled string message", data);
|
||||||
}
|
}
|
||||||
} catch (e) {
|
} catch (e) {
|
||||||
Main.logger.warn(`Error while handling packet.`, e);
|
logger.warn(`Error while handling packet.`, e);
|
||||||
session.close();
|
session.close();
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
socket.on("close", () => {
|
socket.on("close", () => {
|
||||||
Main.logger.info('WebSocket connection closed');
|
logger.info('WebSocket connection closed');
|
||||||
|
|
||||||
const index = this.sessions.indexOf(session);
|
const index = this.sessions.indexOf(session);
|
||||||
if (index != -1) {
|
if (index != -1) {
|
||||||
|
@ -96,10 +98,10 @@ export class WebSocketListenerService {
|
||||||
|
|
||||||
this.emitter.emit('connect', { sessionId: session.sessionId, type: 'ws', data: { url: socket.url }});
|
this.emitter.emit('connect', { sessionId: session.sessionId, type: 'ws', data: { url: socket.url }});
|
||||||
try {
|
try {
|
||||||
Main.logger.info('Sending version');
|
logger.info('Sending version');
|
||||||
session.send(Opcode.Version, {version: 2});
|
session.send(Opcode.Version, {version: 2});
|
||||||
} catch (e) {
|
} catch (e) {
|
||||||
Main.logger.info('Failed to send version');
|
logger.info('Failed to send version');
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,6 +1,18 @@
|
||||||
/* eslint-disable @typescript-eslint/ban-ts-comment */
|
/* eslint-disable @typescript-eslint/ban-ts-comment */
|
||||||
/* eslint-disable @typescript-eslint/no-explicit-any */
|
/* eslint-disable @typescript-eslint/no-explicit-any */
|
||||||
import { Opcode } from 'common/Packets';
|
import { Opcode } from 'common/Packets';
|
||||||
|
import { Logger, LoggerType } from 'common/Logger';
|
||||||
|
const logger = new Logger('MainWindow', LoggerType.FRONTEND);
|
||||||
|
|
||||||
|
// Cannot directly pass the object to the renderer for some reason...
|
||||||
|
const loggerInterface = {
|
||||||
|
trace: (message?: any, ...optionalParams: any[]) => { logger.trace(message, ...optionalParams); },
|
||||||
|
debug: (message?: any, ...optionalParams: any[]) => { logger.debug(message, ...optionalParams); },
|
||||||
|
info: (message?: any, ...optionalParams: any[]) => { logger.info(message, ...optionalParams); },
|
||||||
|
warn: (message?: any, ...optionalParams: any[]) => { logger.warn(message, ...optionalParams); },
|
||||||
|
error: (message?: any, ...optionalParams: any[]) => { logger.error(message, ...optionalParams); },
|
||||||
|
fatal: (message?: any, ...optionalParams: any[]) => { logger.fatal(message, ...optionalParams); },
|
||||||
|
};
|
||||||
|
|
||||||
declare global {
|
declare global {
|
||||||
interface Window {
|
interface Window {
|
||||||
|
@ -32,15 +44,16 @@ if (TARGET === 'electron') {
|
||||||
onDisconnect: (callback: any) => electronAPI.ipcRenderer.on('disconnect', callback),
|
onDisconnect: (callback: any) => electronAPI.ipcRenderer.on('disconnect', callback),
|
||||||
onPing: (callback: any) => electronAPI.ipcRenderer.on('ping', callback),
|
onPing: (callback: any) => electronAPI.ipcRenderer.on('ping', callback),
|
||||||
onPong: (callback: any) => electronAPI.ipcRenderer.on('pong', callback),
|
onPong: (callback: any) => electronAPI.ipcRenderer.on('pong', callback),
|
||||||
|
logger: loggerInterface,
|
||||||
});
|
});
|
||||||
|
|
||||||
// @ts-ignore
|
// @ts-ignore
|
||||||
} else if (TARGET === 'webOS' || TARGET === 'tizenOS') {
|
} else if (TARGET === 'webOS' || TARGET === 'tizenOS') {
|
||||||
preloadData = {
|
preloadData = {
|
||||||
onDeviceInfoCb: () => { console.log('Main: Callback not set while fetching device info'); },
|
onDeviceInfoCb: () => { logger.error('Main: Callback not set while fetching device info'); },
|
||||||
onConnectCb: (_, value: any) => { console.log('Main: Callback not set while calling onConnect'); },
|
onConnectCb: (_, value: any) => { logger.error('Main: Callback not set while calling onConnect'); },
|
||||||
onDisconnectCb: (_, value: any) => { console.log('Main: Callback not set while calling onDisconnect'); },
|
onDisconnectCb: (_, value: any) => { logger.error('Main: Callback not set while calling onDisconnect'); },
|
||||||
onPingCb: (_, value: any) => { console.log('Main: Callback not set while calling onPing'); },
|
onPingCb: (_, value: any) => { logger.error('Main: Callback not set while calling onPing'); },
|
||||||
};
|
};
|
||||||
|
|
||||||
window.targetAPI = {
|
window.targetAPI = {
|
||||||
|
@ -49,10 +62,11 @@ if (TARGET === 'electron') {
|
||||||
onDisconnect: (callback: (_, value: any) => void) => preloadData.onDisconnectCb = callback,
|
onDisconnect: (callback: (_, value: any) => void) => preloadData.onDisconnectCb = callback,
|
||||||
onPing: (callback: (_, value: any) => void) => preloadData.onPingCb = callback,
|
onPing: (callback: (_, value: any) => void) => preloadData.onPingCb = callback,
|
||||||
getDeviceInfo: () => preloadData.deviceInfo,
|
getDeviceInfo: () => preloadData.deviceInfo,
|
||||||
|
logger: loggerInterface,
|
||||||
};
|
};
|
||||||
} else {
|
} else {
|
||||||
// @ts-ignore
|
// @ts-ignore
|
||||||
console.log(`Attempting to run FCast player on unsupported target: ${TARGET}`);
|
logger.warn(`Attempting to run FCast player on unsupported target: ${TARGET}`);
|
||||||
}
|
}
|
||||||
|
|
||||||
export {
|
export {
|
||||||
|
|
|
@ -12,6 +12,7 @@ let renderedAddresses = null;
|
||||||
let qrCodeUrl = null;
|
let qrCodeUrl = null;
|
||||||
let qrWidth = null;
|
let qrWidth = null;
|
||||||
|
|
||||||
|
const logger = window.targetAPI.logger;
|
||||||
window.addEventListener('resize', (event) => calculateQRCodeWidth());
|
window.addEventListener('resize', (event) => calculateQRCodeWidth());
|
||||||
|
|
||||||
connectionMonitor.setUiUpdateCallbacks({
|
connectionMonitor.setUiUpdateCallbacks({
|
||||||
|
@ -37,13 +38,13 @@ connectionMonitor.setUiUpdateCallbacks({
|
||||||
window.targetAPI.onDeviceInfo(renderIPsAndQRCode);
|
window.targetAPI.onDeviceInfo(renderIPsAndQRCode);
|
||||||
|
|
||||||
if(window.targetAPI.getDeviceInfo()) {
|
if(window.targetAPI.getDeviceInfo()) {
|
||||||
console.log('device info already present');
|
logger.info('device info already present');
|
||||||
renderIPsAndQRCode();
|
renderIPsAndQRCode();
|
||||||
}
|
}
|
||||||
|
|
||||||
function renderIPsAndQRCode() {
|
function renderIPsAndQRCode() {
|
||||||
const value = window.targetAPI.getDeviceInfo();
|
const value = window.targetAPI.getDeviceInfo();
|
||||||
console.log(`Network Interface Info: ${JSON.stringify(value)}`);
|
logger.info(`Network Interface Info: ${JSON.stringify(value)}`);
|
||||||
renderIPs(value.interfaces);
|
renderIPs(value.interfaces);
|
||||||
|
|
||||||
const addresses = [];
|
const addresses = [];
|
||||||
|
@ -91,7 +92,7 @@ function renderIPsAndQRCode() {
|
||||||
let base64 = btoa(json);
|
let base64 = btoa(json);
|
||||||
base64 = base64.replace(/\+/g, '-').replace(/\//g, '_').replace(/=+$/, '');
|
base64 = base64.replace(/\+/g, '-').replace(/\//g, '_').replace(/=+$/, '');
|
||||||
qrCodeUrl = `fcast://r/${base64}`;
|
qrCodeUrl = `fcast://r/${base64}`;
|
||||||
console.log('QR Code:', {json, qrCodeUrl, base64});
|
logger.info('QR Code:', {json, qrCodeUrl, base64});
|
||||||
|
|
||||||
calculateQRCodeWidth();
|
calculateQRCodeWidth();
|
||||||
if (!renderedConnectionInfo) {
|
if (!renderedConnectionInfo) {
|
||||||
|
@ -188,11 +189,11 @@ function renderQRCode(url: string) {
|
||||||
},
|
},
|
||||||
(err) => {
|
(err) => {
|
||||||
if (err) {
|
if (err) {
|
||||||
console.error(`Error rendering QR Code: ${err}`);
|
logger.error(`Error rendering QR Code: ${err}`);
|
||||||
toast(`Error rendering QR Code: ${err}`, ToastIcon.ERROR);
|
toast(`Error rendering QR Code: ${err}`, ToastIcon.ERROR);
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
console.log(`Rendered QR Code`);
|
logger.info(`Rendered QR Code`);
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
|
|
|
@ -1,6 +1,8 @@
|
||||||
import dashjs from 'modules/dashjs';
|
import dashjs from 'modules/dashjs';
|
||||||
import Hls from 'modules/hls.js';
|
import Hls from 'modules/hls.js';
|
||||||
|
|
||||||
|
const logger = window.targetAPI.logger;
|
||||||
|
|
||||||
export enum PlayerType {
|
export enum PlayerType {
|
||||||
Html,
|
Html,
|
||||||
Dash,
|
Dash,
|
||||||
|
@ -26,7 +28,7 @@ export class Player {
|
||||||
try {
|
try {
|
||||||
(this.player as dashjs.MediaPlayerClass).destroy();
|
(this.player as dashjs.MediaPlayerClass).destroy();
|
||||||
} catch (e) {
|
} catch (e) {
|
||||||
console.warn("Failed to destroy dash player", e);
|
logger.warn("Failed to destroy dash player", e);
|
||||||
}
|
}
|
||||||
this.player = null;
|
this.player = null;
|
||||||
this.playerType = null;
|
this.playerType = null;
|
||||||
|
@ -37,7 +39,7 @@ export class Player {
|
||||||
try {
|
try {
|
||||||
this.hlsPlayer.destroy();
|
this.hlsPlayer.destroy();
|
||||||
} catch (e) {
|
} catch (e) {
|
||||||
console.warn("Failed to destroy hls player", e);
|
logger.warn("Failed to destroy hls player", e);
|
||||||
}
|
}
|
||||||
// fall through
|
// fall through
|
||||||
|
|
||||||
|
@ -65,7 +67,7 @@ export class Player {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
play() { console.log("Player: play"); this.player.play(); }
|
play() { logger.info("Player: play"); this.player.play(); }
|
||||||
|
|
||||||
isPaused(): boolean {
|
isPaused(): boolean {
|
||||||
if (this.playerType === PlayerType.Dash) {
|
if (this.playerType === PlayerType.Dash) {
|
||||||
|
@ -74,7 +76,7 @@ export class Player {
|
||||||
return (this.player as HTMLVideoElement).paused;
|
return (this.player as HTMLVideoElement).paused;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
pause() { console.log("Player: pause"); this.player.pause(); }
|
pause() { logger.info("Player: pause"); this.player.pause(); }
|
||||||
|
|
||||||
getVolume(): number {
|
getVolume(): number {
|
||||||
if (this.playerType === PlayerType.Dash) {
|
if (this.playerType === PlayerType.Dash) {
|
||||||
|
@ -84,7 +86,7 @@ export class Player {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
setVolume(value: number) {
|
setVolume(value: number) {
|
||||||
console.log(`Player: setVolume ${value}`);
|
logger.info(`Player: setVolume ${value}`);
|
||||||
const sanitizedVolume = Math.min(1.0, Math.max(0.0, value));
|
const sanitizedVolume = Math.min(1.0, Math.max(0.0, value));
|
||||||
|
|
||||||
if (this.playerType === PlayerType.Dash) {
|
if (this.playerType === PlayerType.Dash) {
|
||||||
|
@ -102,7 +104,7 @@ export class Player {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
setMute(value: boolean) {
|
setMute(value: boolean) {
|
||||||
console.log(`Player: setMute ${value}`);
|
logger.info(`Player: setMute ${value}`);
|
||||||
|
|
||||||
if (this.playerType === PlayerType.Dash) {
|
if (this.playerType === PlayerType.Dash) {
|
||||||
(this.player as dashjs.MediaPlayerClass).setMute(value);
|
(this.player as dashjs.MediaPlayerClass).setMute(value);
|
||||||
|
@ -119,7 +121,7 @@ export class Player {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
setPlaybackRate(value: number) {
|
setPlaybackRate(value: number) {
|
||||||
console.log(`Player: setPlaybackRate ${value}`);
|
logger.info(`Player: setPlaybackRate ${value}`);
|
||||||
const sanitizedSpeed = Math.min(16.0, Math.max(0.0, value));
|
const sanitizedSpeed = Math.min(16.0, Math.max(0.0, value));
|
||||||
|
|
||||||
if (this.playerType === PlayerType.Dash) {
|
if (this.playerType === PlayerType.Dash) {
|
||||||
|
@ -147,7 +149,7 @@ export class Player {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
setCurrentTime(value: number) {
|
setCurrentTime(value: number) {
|
||||||
// console.log(`Player: setCurrentTime ${value}`);
|
// logger.info(`Player: setCurrentTime ${value}`);
|
||||||
const sanitizedTime = Math.min(this.getDuration(), Math.max(0.0, value));
|
const sanitizedTime = Math.min(this.getDuration(), Math.max(0.0, value));
|
||||||
|
|
||||||
if (this.playerType === PlayerType.Dash) {
|
if (this.playerType === PlayerType.Dash) {
|
||||||
|
|
|
@ -1,7 +1,18 @@
|
||||||
/* eslint-disable @typescript-eslint/ban-ts-comment */
|
/* eslint-disable @typescript-eslint/ban-ts-comment */
|
||||||
/* eslint-disable @typescript-eslint/no-explicit-any */
|
/* eslint-disable @typescript-eslint/no-explicit-any */
|
||||||
import { PlaybackErrorMessage, PlaybackUpdateMessage, VolumeUpdateMessage, Opcode } from 'common/Packets';
|
import { PlaybackErrorMessage, PlaybackUpdateMessage, VolumeUpdateMessage, Opcode } from 'common/Packets';
|
||||||
export {};
|
import { Logger, LoggerType } from 'common/Logger';
|
||||||
|
const logger = new Logger('PlayerWindow', LoggerType.FRONTEND);
|
||||||
|
|
||||||
|
// Cannot directly pass the object to the renderer for some reason...
|
||||||
|
const loggerInterface = {
|
||||||
|
trace: (message?: any, ...optionalParams: any[]) => { logger.trace(message, ...optionalParams); },
|
||||||
|
debug: (message?: any, ...optionalParams: any[]) => { logger.debug(message, ...optionalParams); },
|
||||||
|
info: (message?: any, ...optionalParams: any[]) => { logger.info(message, ...optionalParams); },
|
||||||
|
warn: (message?: any, ...optionalParams: any[]) => { logger.warn(message, ...optionalParams); },
|
||||||
|
error: (message?: any, ...optionalParams: any[]) => { logger.error(message, ...optionalParams); },
|
||||||
|
fatal: (message?: any, ...optionalParams: any[]) => { logger.fatal(message, ...optionalParams); },
|
||||||
|
};
|
||||||
|
|
||||||
declare global {
|
declare global {
|
||||||
interface Window {
|
interface Window {
|
||||||
|
@ -37,21 +48,22 @@ if (TARGET === 'electron') {
|
||||||
onDisconnect: (callback: any) => electronAPI.ipcRenderer.on('disconnect', callback),
|
onDisconnect: (callback: any) => electronAPI.ipcRenderer.on('disconnect', callback),
|
||||||
onPing: (callback: any) => electronAPI.ipcRenderer.on('ping', callback),
|
onPing: (callback: any) => electronAPI.ipcRenderer.on('ping', callback),
|
||||||
onPong: (callback: any) => electronAPI.ipcRenderer.on('pong', callback),
|
onPong: (callback: any) => electronAPI.ipcRenderer.on('pong', callback),
|
||||||
|
logger: loggerInterface,
|
||||||
});
|
});
|
||||||
|
|
||||||
// @ts-ignore
|
// @ts-ignore
|
||||||
} else if (TARGET === 'webOS' || TARGET === 'tizenOS') {
|
} else if (TARGET === 'webOS' || TARGET === 'tizenOS') {
|
||||||
preloadData = {
|
preloadData = {
|
||||||
sendPlaybackErrorCb: () => { console.error('Player: Callback "send_playback_error" not set'); },
|
sendPlaybackErrorCb: () => { logger.error('Player: Callback "send_playback_error" not set'); },
|
||||||
sendPlaybackUpdateCb: () => { console.error('Player: Callback "send_playback_update" not set'); },
|
sendPlaybackUpdateCb: () => { logger.error('Player: Callback "send_playback_update" not set'); },
|
||||||
sendVolumeUpdateCb: () => { console.error('Player: Callback "send_volume_update" not set'); },
|
sendVolumeUpdateCb: () => { logger.error('Player: Callback "send_volume_update" not set'); },
|
||||||
// onPlayCb: () => { console.error('Player: Callback "play" not set'); },
|
// onPlayCb: () => { logger.error('Player: Callback "play" not set'); },
|
||||||
onPlayCb: undefined,
|
onPlayCb: undefined,
|
||||||
onPauseCb: () => { console.error('Player: Callback "pause" not set'); },
|
onPauseCb: () => { logger.error('Player: Callback "pause" not set'); },
|
||||||
onResumeCb: () => { console.error('Player: Callback "resume" not set'); },
|
onResumeCb: () => { logger.error('Player: Callback "resume" not set'); },
|
||||||
onSeekCb: () => { console.error('Player: Callback "onseek" not set'); },
|
onSeekCb: () => { logger.error('Player: Callback "onseek" not set'); },
|
||||||
onSetVolumeCb: () => { console.error('Player: Callback "setvolume" not set'); },
|
onSetVolumeCb: () => { logger.error('Player: Callback "setvolume" not set'); },
|
||||||
onSetSpeedCb: () => { console.error('Player: Callback "setspeed" not set'); },
|
onSetSpeedCb: () => { logger.error('Player: Callback "setspeed" not set'); },
|
||||||
};
|
};
|
||||||
|
|
||||||
window.targetAPI = {
|
window.targetAPI = {
|
||||||
|
@ -64,10 +76,11 @@ if (TARGET === 'electron') {
|
||||||
onSeek: (callback: any) => { preloadData.onSeekCb = callback; },
|
onSeek: (callback: any) => { preloadData.onSeekCb = callback; },
|
||||||
onSetVolume: (callback: any) => { preloadData.onSetVolumeCb = callback; },
|
onSetVolume: (callback: any) => { preloadData.onSetVolumeCb = callback; },
|
||||||
onSetSpeed: (callback: any) => { preloadData.onSetSpeedCb = callback; },
|
onSetSpeed: (callback: any) => { preloadData.onSetSpeedCb = callback; },
|
||||||
|
logger: loggerInterface,
|
||||||
};
|
};
|
||||||
} else {
|
} else {
|
||||||
// @ts-ignore
|
// @ts-ignore
|
||||||
console.log(`Attempting to run FCast player on unsupported target: ${TARGET}`);
|
logger.warn(`Attempting to run FCast player on unsupported target: ${TARGET}`);
|
||||||
}
|
}
|
||||||
|
|
||||||
export {
|
export {
|
||||||
|
|
|
@ -12,6 +12,8 @@ import {
|
||||||
captionsLineHeight
|
captionsLineHeight
|
||||||
} from 'src/player/Renderer';
|
} from 'src/player/Renderer';
|
||||||
|
|
||||||
|
const logger = window.targetAPI.logger;
|
||||||
|
|
||||||
function formatDuration(duration: number) {
|
function formatDuration(duration: number) {
|
||||||
if (isNaN(duration)) {
|
if (isNaN(duration)) {
|
||||||
return '00:00';
|
return '00:00';
|
||||||
|
@ -120,7 +122,7 @@ let captionsBaseHeight = 0;
|
||||||
let captionsContentHeight = 0;
|
let captionsContentHeight = 0;
|
||||||
|
|
||||||
function onPlay(_event, value: PlayMessage) {
|
function onPlay(_event, value: PlayMessage) {
|
||||||
console.log("Handle play message renderer", JSON.stringify(value));
|
logger.info("Handle play message renderer", JSON.stringify(value));
|
||||||
const currentVolume = player ? player.getVolume() : null;
|
const currentVolume = player ? player.getVolume() : null;
|
||||||
const currentPlaybackRate = player ? player.getPlaybackRate() : null;
|
const currentPlaybackRate = player ? player.getPlaybackRate() : null;
|
||||||
|
|
||||||
|
@ -143,7 +145,7 @@ function onPlay(_event, value: PlayMessage) {
|
||||||
|
|
||||||
if ((value.url || value.content) && value.container && videoElement) {
|
if ((value.url || value.content) && value.container && videoElement) {
|
||||||
if (value.container === 'application/dash+xml') {
|
if (value.container === 'application/dash+xml') {
|
||||||
console.log("Loading dash player");
|
logger.info("Loading dash player");
|
||||||
const dashPlayer = dashjs.MediaPlayer().create();
|
const dashPlayer = dashjs.MediaPlayer().create();
|
||||||
const source = value.content ? value.content : value.url;
|
const source = value.content ? value.content : value.url;
|
||||||
player = new Player(PlayerType.Dash, dashPlayer, source);
|
player = new Player(PlayerType.Dash, dashPlayer, source);
|
||||||
|
@ -236,7 +238,7 @@ function onPlay(_event, value: PlayMessage) {
|
||||||
}
|
}
|
||||||
|
|
||||||
} else if ((value.container === 'application/vnd.apple.mpegurl' || value.container === 'application/x-mpegURL') && !videoElement.canPlayType(value.container)) {
|
} else if ((value.container === 'application/vnd.apple.mpegurl' || value.container === 'application/x-mpegURL') && !videoElement.canPlayType(value.container)) {
|
||||||
console.log("Loading hls player");
|
logger.info("Loading hls player");
|
||||||
|
|
||||||
const config = {
|
const config = {
|
||||||
xhrSetup: function (xhr: XMLHttpRequest) {
|
xhrSetup: function (xhr: XMLHttpRequest) {
|
||||||
|
@ -277,7 +279,7 @@ function onPlay(_event, value: PlayMessage) {
|
||||||
// hlsPlayer.subtitleDisplay = true;
|
// hlsPlayer.subtitleDisplay = true;
|
||||||
|
|
||||||
} else {
|
} else {
|
||||||
console.log("Loading html player");
|
logger.info("Loading html player");
|
||||||
player = new Player(PlayerType.Html, videoElement, value.url);
|
player = new Player(PlayerType.Html, videoElement, value.url);
|
||||||
|
|
||||||
videoElement.src = value.url;
|
videoElement.src = value.url;
|
||||||
|
@ -307,7 +309,7 @@ function onPlay(_event, value: PlayMessage) {
|
||||||
};
|
};
|
||||||
|
|
||||||
videoElement.onerror = (event: Event | string, source?: string, lineno?: number, colno?: number, error?: Error) => {
|
videoElement.onerror = (event: Event | string, source?: string, lineno?: number, colno?: number, error?: Error) => {
|
||||||
console.error("Player error", {source, lineno, colno, error});
|
logger.error("Player error", {source, lineno, colno, error});
|
||||||
};
|
};
|
||||||
|
|
||||||
videoElement.onloadedmetadata = (ev) => {
|
videoElement.onloadedmetadata = (ev) => {
|
||||||
|
@ -419,7 +421,7 @@ function playerCtrlStateUpdate(event: PlayerControlEvent) {
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case PlayerControlEvent.VolumeChange: {
|
case PlayerControlEvent.VolumeChange: {
|
||||||
// console.log(`VolumeChange: isMute ${player?.isMuted()}, volume: ${player?.getVolume()}`);
|
// logger.info(`VolumeChange: isMute ${player?.isMuted()}, volume: ${player?.getVolume()}`);
|
||||||
const volume = Math.round(player?.getVolume() * playerCtrlVolumeBar.offsetWidth);
|
const volume = Math.round(player?.getVolume() * playerCtrlVolumeBar.offsetWidth);
|
||||||
|
|
||||||
if (player?.isMuted()) {
|
if (player?.isMuted()) {
|
||||||
|
@ -440,7 +442,7 @@ function playerCtrlStateUpdate(event: PlayerControlEvent) {
|
||||||
}
|
}
|
||||||
|
|
||||||
case PlayerControlEvent.TimeUpdate: {
|
case PlayerControlEvent.TimeUpdate: {
|
||||||
// console.log(`TimeUpdate: Position: ${player.getCurrentTime()}, Duration: ${player.getDuration()}`);
|
// logger.info(`TimeUpdate: Position: ${player.getCurrentTime()}, Duration: ${player.getDuration()}`);
|
||||||
|
|
||||||
if (isLive) {
|
if (isLive) {
|
||||||
if (isLivePosition && player.getDuration() - player.getCurrentTime() > livePositionWindow) {
|
if (isLivePosition && player.getDuration() - player.getCurrentTime() > livePositionWindow) {
|
||||||
|
@ -736,7 +738,7 @@ const skipInterval = 10;
|
||||||
const volumeIncrement = 0.1;
|
const volumeIncrement = 0.1;
|
||||||
|
|
||||||
function keyDownEventListener(event: any) {
|
function keyDownEventListener(event: any) {
|
||||||
// console.log("KeyDown", event);
|
// logger.info("KeyDown", event);
|
||||||
const handledCase = targetKeyDownEventListener(event);
|
const handledCase = targetKeyDownEventListener(event);
|
||||||
if (handledCase) {
|
if (handledCase) {
|
||||||
return;
|
return;
|
||||||
|
|
|
@ -4,14 +4,15 @@ import { DiscoveryService } from 'common/DiscoveryService';
|
||||||
import { TcpListenerService } from 'common/TcpListenerService';
|
import { TcpListenerService } from 'common/TcpListenerService';
|
||||||
import { WebSocketListenerService } from 'common/WebSocketListenerService';
|
import { WebSocketListenerService } from 'common/WebSocketListenerService';
|
||||||
import { NetworkService } from 'common/NetworkService';
|
import { NetworkService } from 'common/NetworkService';
|
||||||
|
import { Logger, LoggerType } from 'common/Logger';
|
||||||
import { Updater } from './Updater';
|
import { Updater } from './Updater';
|
||||||
import * as os from 'os';
|
import * as os from 'os';
|
||||||
import * as path from 'path';
|
import * as path from 'path';
|
||||||
import * as log4js from "log4js";
|
|
||||||
import yargs from 'yargs';
|
import yargs from 'yargs';
|
||||||
import { hideBin } from 'yargs/helpers';
|
import { hideBin } from 'yargs/helpers';
|
||||||
import { ToastIcon } from 'common/components/Toast';
|
import { ToastIcon } from 'common/components/Toast';
|
||||||
const cp = require('child_process');
|
const cp = require('child_process');
|
||||||
|
let logger = null;
|
||||||
|
|
||||||
export class Main {
|
export class Main {
|
||||||
static shouldOpenMainWindow = true;
|
static shouldOpenMainWindow = true;
|
||||||
|
@ -23,7 +24,6 @@ export class Main {
|
||||||
static webSocketListenerService: WebSocketListenerService;
|
static webSocketListenerService: WebSocketListenerService;
|
||||||
static discoveryService: DiscoveryService;
|
static discoveryService: DiscoveryService;
|
||||||
static tray: Tray;
|
static tray: Tray;
|
||||||
static logger: log4js.Logger;
|
|
||||||
|
|
||||||
private static toggleMainWindow() {
|
private static toggleMainWindow() {
|
||||||
if (Main.mainWindow) {
|
if (Main.mainWindow) {
|
||||||
|
@ -68,7 +68,7 @@ export class Main {
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
Main.logger.error('Failed to check for updates:', err);
|
logger.error('Failed to check for updates:', err);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -180,8 +180,8 @@ export class Main {
|
||||||
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));
|
||||||
|
@ -242,7 +242,7 @@ export class Main {
|
||||||
defaultId: 0
|
defaultId: 0
|
||||||
});
|
});
|
||||||
|
|
||||||
Main.logger.error('Failed to download update:', err);
|
logger.error('Failed to download update:', err);
|
||||||
Main.mainWindow?.webContents?.send("download-failed");
|
Main.mainWindow?.webContents?.send("download-failed");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -342,7 +342,7 @@ export class Main {
|
||||||
Main.mainWindow.on('closed', () => {
|
Main.mainWindow.on('closed', () => {
|
||||||
Main.mainWindow = null;
|
Main.mainWindow = null;
|
||||||
|
|
||||||
if (!networkWorker.isDestoryed()) {
|
if (!networkWorker.isDestroyed()) {
|
||||||
networkWorker.close();
|
networkWorker.close();
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
@ -366,27 +366,28 @@ export class Main {
|
||||||
})
|
})
|
||||||
.options({
|
.options({
|
||||||
'no-main-window': { type: 'boolean', default: false, desc: "Start minimized to tray" },
|
'no-main-window': { type: 'boolean', default: false, desc: "Start minimized to tray" },
|
||||||
'fullscreen': { type: 'boolean', default: false, desc: "Start application in fullscreen" }
|
'fullscreen': { type: 'boolean', default: false, desc: "Start application in fullscreen" },
|
||||||
|
'log': { chocies: ['ALL', 'TRACE', 'DEBUG', 'INFO', 'WARN', 'ERROR', 'FATAL', 'MARK', 'OFF'], alias: 'loglevel', default: 'INFO', desc: "Defines the verbosity level of the logger" },
|
||||||
})
|
})
|
||||||
.parseSync();
|
.parseSync();
|
||||||
|
|
||||||
const isUpdating = Updater.isUpdating();
|
const isUpdating = Updater.isUpdating();
|
||||||
const fileLogType = isUpdating ? 'fileSync' : 'file';
|
const fileLogType = isUpdating ? 'fileSync' : 'file';
|
||||||
log4js.configure({
|
Logger.initialize({
|
||||||
appenders: {
|
appenders: {
|
||||||
out: { type: 'stdout' },
|
out: { type: 'stdout' },
|
||||||
log: { type: fileLogType, filename: path.join(app.getPath('logs'), 'fcast-receiver.log'), flags: 'a', maxLogSize: '5M' },
|
log: { type: fileLogType, filename: path.join(app.getPath('logs'), 'fcast-receiver.log'), flags: 'a', maxLogSize: '5M' },
|
||||||
},
|
},
|
||||||
categories: {
|
categories: {
|
||||||
default: { appenders: ['out', 'log'], level: 'info' },
|
default: { appenders: ['out', 'log'], level: argv.log },
|
||||||
},
|
},
|
||||||
});
|
});
|
||||||
Main.logger = log4js.getLogger();
|
logger = new Logger('Main', LoggerType.BACKEND);
|
||||||
Main.logger.info(`Starting application: ${app.name} | ${app.getAppPath()}`);
|
logger.info(`Starting application: ${app.name} | ${app.getAppPath()}`);
|
||||||
Main.logger.info(`Version: ${app.getVersion()}`);
|
logger.info(`Version: ${app.getVersion()}`);
|
||||||
Main.logger.info(`Commit: ${Updater.getCommit()}`);
|
logger.info(`Commit: ${Updater.getCommit()}`);
|
||||||
Main.logger.info(`Release channel: ${Updater.releaseChannel} - ${Updater.getChannelVersion()}`);
|
logger.info(`Release channel: ${Updater.releaseChannel} - ${Updater.getChannelVersion()}`);
|
||||||
Main.logger.info(`OS: ${process.platform} ${process.arch}`);
|
logger.info(`OS: ${process.platform} ${process.arch}`);
|
||||||
|
|
||||||
if (isUpdating) {
|
if (isUpdating) {
|
||||||
await Updater.processUpdate();
|
await Updater.processUpdate();
|
||||||
|
@ -415,7 +416,7 @@ export class Main {
|
||||||
Main.application.on('window-all-closed', () => { });
|
Main.application.on('window-all-closed', () => { });
|
||||||
}
|
}
|
||||||
catch (err) {
|
catch (err) {
|
||||||
Main.logger.error(`Error starting application: ${err}`);
|
logger.error(`Error starting application: ${err}`);
|
||||||
app.exit();
|
app.exit();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -435,15 +436,15 @@ export function getComputerName() {
|
||||||
hostname = os.hostname();
|
hostname = os.hostname();
|
||||||
}
|
}
|
||||||
catch (err) {
|
catch (err) {
|
||||||
Main.logger.warn('Error fetching hostname, trying different method...');
|
logger.warn('Error fetching hostname, trying different method...');
|
||||||
Main.logger.warn(err);
|
logger.warn(err);
|
||||||
|
|
||||||
try {
|
try {
|
||||||
hostname = cp.execSync("hostnamectl hostname").toString().trim();
|
hostname = cp.execSync("hostnamectl hostname").toString().trim();
|
||||||
}
|
}
|
||||||
catch (err2) {
|
catch (err2) {
|
||||||
Main.logger.warn('Error fetching hostname again, using generic name...');
|
logger.warn('Error fetching hostname again, using generic name...');
|
||||||
Main.logger.warn(err2);
|
logger.warn(err2);
|
||||||
|
|
||||||
hostname = 'linux device';
|
hostname = 'linux device';
|
||||||
}
|
}
|
||||||
|
@ -458,7 +459,7 @@ export function getComputerName() {
|
||||||
}
|
}
|
||||||
|
|
||||||
export async function errorHandler(err: NodeJS.ErrnoException) {
|
export async function errorHandler(err: NodeJS.ErrnoException) {
|
||||||
Main.logger.error("Application error:", err);
|
logger.error("Application error:", err);
|
||||||
Main.mainWindow?.webContents?.send("toast", { message: err, icon: ToastIcon.ERROR });
|
Main.mainWindow?.webContents?.send("toast", { message: err, icon: ToastIcon.ERROR });
|
||||||
|
|
||||||
const restartPrompt = await dialog.showMessageBox({
|
const restartPrompt = await dialog.showMessageBox({
|
||||||
|
|
|
@ -1,8 +1,8 @@
|
||||||
/* eslint-disable @typescript-eslint/no-explicit-any */
|
/* eslint-disable @typescript-eslint/no-explicit-any */
|
||||||
import storage from 'electron-json-storage';
|
import storage from 'electron-json-storage';
|
||||||
import { app } from 'electron';
|
import { app } from 'electron';
|
||||||
import * as log4js from "log4js";
|
import { Logger, LoggerType } from 'common/Logger';
|
||||||
const logger = log4js.getLogger();
|
const logger = new Logger('Store', LoggerType.BACKEND);
|
||||||
|
|
||||||
export class Store {
|
export class Store {
|
||||||
private static storeVersion = 1;
|
private static storeVersion = 1;
|
||||||
|
|
|
@ -2,13 +2,14 @@ import * as fs from 'fs';
|
||||||
import * as https from 'https';
|
import * as https from 'https';
|
||||||
import * as path from 'path';
|
import * as path from 'path';
|
||||||
import * as crypto from 'crypto';
|
import * as crypto from 'crypto';
|
||||||
import * as log4js from "log4js";
|
|
||||||
import { app } from 'electron';
|
import { app } from 'electron';
|
||||||
import { Store } from './Store';
|
import { Store } from './Store';
|
||||||
import sudo from 'sudo-prompt';
|
import sudo from 'sudo-prompt';
|
||||||
|
import { Logger, LoggerType } from 'common/Logger';
|
||||||
|
|
||||||
const cp = require('child_process');
|
const cp = require('child_process');
|
||||||
const extract = require('extract-zip');
|
const extract = require('extract-zip');
|
||||||
const logger = log4js.getLogger();
|
const logger = new Logger('Updater', LoggerType.BACKEND);
|
||||||
|
|
||||||
enum UpdateState {
|
enum UpdateState {
|
||||||
Copy = 'copy',
|
Copy = 'copy',
|
||||||
|
@ -193,7 +194,7 @@ export class Updater {
|
||||||
// Also does not work very well on Mac...
|
// Also does not work very well on Mac...
|
||||||
private static relaunch(binPath: string) {
|
private static relaunch(binPath: string) {
|
||||||
logger.info(`Relaunching app binary: ${binPath}`);
|
logger.info(`Relaunching app binary: ${binPath}`);
|
||||||
log4js.shutdown();
|
logger.shutdown();
|
||||||
|
|
||||||
let proc;
|
let proc;
|
||||||
if (process.platform === 'win32') {
|
if (process.platform === 'win32') {
|
||||||
|
@ -394,7 +395,8 @@ export class Updater {
|
||||||
|
|
||||||
logger.info('Extraction complete.');
|
logger.info('Extraction complete.');
|
||||||
const updateInfo: UpdateInfo = {
|
const updateInfo: UpdateInfo = {
|
||||||
updateState: UpdateState.Copy,
|
// updateState: UpdateState.Copy,
|
||||||
|
updateState: UpdateState.Cleanup,
|
||||||
installPath: Updater.installPath,
|
installPath: Updater.installPath,
|
||||||
tempPath: path.dirname(destination),
|
tempPath: path.dirname(destination),
|
||||||
currentVersion: Updater.releasesJson.currentVersion,
|
currentVersion: Updater.releasesJson.currentVersion,
|
||||||
|
|
|
@ -1,5 +1,7 @@
|
||||||
import { ipcRenderer } from 'electron';
|
import { ipcRenderer } from 'electron';
|
||||||
import si from 'modules/systeminformation';
|
import si from 'modules/systeminformation';
|
||||||
|
import { Logger, LoggerType } from 'common/Logger';
|
||||||
|
const logger = new Logger('NetworkWorker', LoggerType.FRONTEND);
|
||||||
|
|
||||||
const networkStateChangeListenerTimeout = 2500;
|
const networkStateChangeListenerTimeout = 2500;
|
||||||
let networkStateChangeListenerInterfaces = [];
|
let networkStateChangeListenerInterfaces = [];
|
||||||
|
@ -10,11 +12,11 @@ setInterval(networkStateChangeListener, networkStateChangeListenerTimeout);
|
||||||
function networkStateChangeListener(forceUpdate: boolean) {
|
function networkStateChangeListener(forceUpdate: boolean) {
|
||||||
new Promise<void>((resolve) => {
|
new Promise<void>((resolve) => {
|
||||||
si.networkInterfaces((data) => {
|
si.networkInterfaces((data) => {
|
||||||
// console.log(data);
|
// logger.info(data);
|
||||||
const queriedInterfaces = Array.isArray(data) ? data : [data];
|
const queriedInterfaces = Array.isArray(data) ? data : [data];
|
||||||
|
|
||||||
si.wifiConnections((data) => {
|
si.wifiConnections((data) => {
|
||||||
// console.log(data);
|
// logger.info(data);
|
||||||
const wifiConnections = Array.isArray(data) ? data : [data];
|
const wifiConnections = Array.isArray(data) ? data : [data];
|
||||||
|
|
||||||
const interfaces = [];
|
const interfaces = [];
|
||||||
|
|
|
@ -1,5 +1,6 @@
|
||||||
import 'common/main/Renderer';
|
import 'common/main/Renderer';
|
||||||
|
|
||||||
|
const logger = window.targetAPI.logger;
|
||||||
export function onQRCodeRendered() {}
|
export function onQRCodeRendered() {}
|
||||||
|
|
||||||
const updateView = document.getElementById("update-view");
|
const updateView = document.getElementById("update-view");
|
||||||
|
@ -14,7 +15,7 @@ const progressBarProgress = document.getElementById("progress-bar-progress");
|
||||||
let updaterProgressUIUpdateTimer = null;
|
let updaterProgressUIUpdateTimer = null;
|
||||||
|
|
||||||
window.electronAPI.onUpdateAvailable(() => {
|
window.electronAPI.onUpdateAvailable(() => {
|
||||||
console.log(`Received UpdateAvailable event`);
|
logger.info(`Received UpdateAvailable event`);
|
||||||
updateViewTitle.textContent = 'FCast update available';
|
updateViewTitle.textContent = 'FCast update available';
|
||||||
|
|
||||||
updateText.textContent = 'Do you wish to update now?';
|
updateText.textContent = 'Do you wish to update now?';
|
||||||
|
@ -26,7 +27,7 @@ window.electronAPI.onUpdateAvailable(() => {
|
||||||
});
|
});
|
||||||
|
|
||||||
window.electronAPI.onDownloadComplete(() => {
|
window.electronAPI.onDownloadComplete(() => {
|
||||||
console.log(`Received DownloadComplete event`);
|
logger.info(`Received DownloadComplete event`);
|
||||||
window.clearTimeout(updaterProgressUIUpdateTimer);
|
window.clearTimeout(updaterProgressUIUpdateTimer);
|
||||||
updateViewTitle.textContent = 'FCast update ready';
|
updateViewTitle.textContent = 'FCast update ready';
|
||||||
|
|
||||||
|
@ -39,7 +40,7 @@ window.electronAPI.onDownloadComplete(() => {
|
||||||
});
|
});
|
||||||
|
|
||||||
window.electronAPI.onDownloadFailed(() => {
|
window.electronAPI.onDownloadFailed(() => {
|
||||||
console.log(`Received DownloadFailed event`);
|
logger.info(`Received DownloadFailed event`);
|
||||||
window.clearTimeout(updaterProgressUIUpdateTimer);
|
window.clearTimeout(updaterProgressUIUpdateTimer);
|
||||||
updateView.setAttribute("style", "display: none");
|
updateView.setAttribute("style", "display: none");
|
||||||
});
|
});
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue