diff --git a/receivers/common/web/NetworkService.ts b/receivers/common/web/NetworkService.ts index a318a1f..56abb3d 100644 --- a/receivers/common/web/NetworkService.ts +++ b/receivers/common/web/NetworkService.ts @@ -1,11 +1,9 @@ import { PlayMessage, PlaybackErrorMessage, PlaybackUpdateMessage, VolumeUpdateMessage } from 'common/Packets'; -import * as os from 'os'; import * as http from 'http'; import * as url from 'url'; import { AddressInfo } from 'modules/ws'; import { v4 as uuidv4 } from 'modules/uuid'; import { Main } from 'src/Main'; -import si from 'modules/systeminformation'; export class NetworkService { static key: string = null; @@ -13,8 +11,6 @@ export class NetworkService { static proxyServer: http.Server; static proxyServerAddress: AddressInfo; static proxiedFiles: Map = new Map(); - static networkStateChangeListenerTimeout = 2500; - private static networkStateChangeListenerInterfaces = []; private static setupProxyServer(): Promise { return new Promise((resolve, reject) => { @@ -106,55 +102,4 @@ export class NetworkService { NetworkService.proxiedFiles.set(proxiedUrl, { url: url, headers: headers }); return proxiedUrl; } - - static async networkStateChangeListener(forceUpdate: boolean, networkChangedCb: (networkInfo: any) => void) { - const queriedInterfaces: si.Systeminformation.NetworkInterfacesData[] = await new Promise((resolve, reject) => { - si.networkInterfaces((data) => { - // console.log(data); - - if (Array.isArray(data)) { - resolve(data); - } - else { - resolve([data]); - } - }); - }); - - const wifiConnections: si.Systeminformation.WifiConnectionData[] = await new Promise((resolve, reject) => { - si.wifiConnections((data) => { - // console.log(data); - - if (Array.isArray(data)) { - resolve(data); - } - else { - resolve([data]); - } - }); - }); - - const interfaces = []; - for (const iface of queriedInterfaces) { - if (iface.ip4 !== '' && !iface.internal && !iface.virtual) { - const isWireless = wifiConnections.some(e => { - if (e.iface === iface.iface) { - interfaces.push({ type: 'wireless', name: e.ssid, address: iface.ip4, signalLevel: e.quality }); - return true; - } - - return false; - }); - - if (!isWireless) { - interfaces.push({ type: 'wired', name: iface.ifaceName, address: iface.ip4 }); - } - } - } - - if (forceUpdate || (JSON.stringify(interfaces) !== JSON.stringify(NetworkService.networkStateChangeListenerInterfaces))) { - NetworkService.networkStateChangeListenerInterfaces = interfaces; - networkChangedCb(interfaces); - } - } } diff --git a/receivers/common/web/main/Renderer.ts b/receivers/common/web/main/Renderer.ts index 28b7275..6b20636 100644 --- a/receivers/common/web/main/Renderer.ts +++ b/receivers/common/web/main/Renderer.ts @@ -7,6 +7,7 @@ const connectionStatusText = document.getElementById("connection-status-text"); const connectionStatusSpinner = document.getElementById("connection-spinner"); const connectionStatusCheck = document.getElementById("connection-check"); let connections = []; +let renderedConnectionInfo = false; let renderedAddresses = null; // Window might be re-created while devices are still connected @@ -66,8 +67,8 @@ function renderIPsAndQRCode() { toast("Network connections has changed, please reconnect sender devices to receiver if you experience issues", ToastIcon.WARNING); } else if (addresses.length === 0) { - connInfo.setAttribute("style", "display: none"); - connError.setAttribute("style", "display: block"); + connInfo.style.display = 'none'; + connError.style.display = 'block'; if (renderedAddresses !== null) { toast("Lost network connection, please reconnect to a network", ToastIcon.ERROR); @@ -78,8 +79,8 @@ function renderIPsAndQRCode() { } if (renderedAddresses !== null && renderedAddresses.length === 0) { - connInfo.setAttribute("style", "display: block"); - connError.setAttribute("style", "display: none"); + connInfo.style.display = 'block'; + connError.style.display = 'none'; } renderIPs(value.interfaces); @@ -124,6 +125,12 @@ function renderIPsAndQRCode() { } }); + if (!renderedConnectionInfo) { + const connInfoLoading = document.getElementById('connection-information-loading'); + connInfoLoading.style.display = 'none'; + connInfo.style.display = 'block'; + } + onQRCodeRendered(); } diff --git a/receivers/common/web/main/common.css b/receivers/common/web/main/common.css index d0009b6..69ea3c1 100644 --- a/receivers/common/web/main/common.css +++ b/receivers/common/web/main/common.css @@ -72,11 +72,15 @@ body, html { gap: 15vw; font-family: InterVariable; - font-size: 20px; + font-size: 28px; font-style: normal; font-weight: 400; } +#main-view { + padding: 25px; +} + #title-container { display: flex; justify-content: center; @@ -85,7 +89,7 @@ body, html { #title-text { font-family: Outfit; - font-size: 100px; + font-size: 140px; font-weight: 800; text-align: center; @@ -96,12 +100,12 @@ body, html { } #title-icon { - width: 84px; - height: 84px; + width: 124px; + height: 124px; background-image: url(../assets/icons/app/icon.svg); background-size: cover; - margin-right: 15px; + margin-right: 25px; } #connection-status { @@ -109,35 +113,13 @@ body, html { text-align: center; } -#main-view { - padding: 25px; -} - -#manual-connection-info { - font-weight: 700; - line-height: 24px; - margin: 10px; -} - -#manual-connection-info-separator { - height: 1px; - background: #2E2E2E; - margin-top: 3px; - margin-bottom: 3px; -} - -#qr-code { - display: flex; - margin: 20px auto; - flex-direction: column; - align-items: center; - padding: 20px; - background-color: white; -} - -#scan-to-connect { +#connection-status-text { margin-top: 20px; - font-weight: bold; + white-space: pre; +} + +#connection-spinner { + padding: 20px; } #connection-error { @@ -159,9 +141,37 @@ body, html { font-weight: bold; } -#connection-status-text { +#connection-information-loading { + display: flex; + flex-direction: column; + align-items: center; +} + +#connection-information-loading-text { + width: auto; + height: auto; + margin: 10px 20px; +} + +#connection-information { + display: none; + flex-direction: column; + align-items: center; + justify-content: center; +} + +#scan-to-connect { margin-top: 20px; - white-space: pre; + font-weight: bold; +} + +#qr-code { + display: flex; + margin: 20px auto; + flex-direction: column; + align-items: center; + padding: 20px; + background-color: white; } #ips { @@ -219,10 +229,6 @@ body, html { background-image: url(../assets/icons/app/wifi-strength-outline.svg); } -#connection-spinner { - padding: 20px; -} - #window-can-be-closed { color: #666666; position: absolute; @@ -230,7 +236,7 @@ body, html { margin-bottom: 20px; font-family: InterVariable; - font-size: 18px; + font-size: 24px; font-style: normal; font-weight: 400; } @@ -238,15 +244,15 @@ body, html { .lds-ring { display: inline-block; position: relative; - width: 80px; - height: 80px; + width: 120px; + height: 120px; } .lds-ring div { box-sizing: border-box; display: block; position: absolute; - width: 64px; - height: 64px; + width: 104px; + height: 104px; margin: 8px; border: 8px solid #fff; border-radius: 50%; @@ -275,8 +281,8 @@ body, html { /* display: inline-block; */ display: none; position: relative; - width: 64px; - height: 64px; + width: 104px; + height: 104px; margin: 18px; padding: 10px; @@ -329,8 +335,8 @@ body, html { } #toast-icon { - width: 48px; - height: 48px; + width: 88px; + height: 88px; background-image: url(../assets/icons/app/info.svg); background-size: cover; flex-shrink: 0; @@ -345,7 +351,7 @@ body, html { word-break: break-word; font-family: InterVariable; - font-size: 20px; + font-size: 28px; font-style: normal; font-weight: 400; } diff --git a/receivers/electron/src/Main.ts b/receivers/electron/src/Main.ts index 59046f8..3a6bc31 100644 --- a/receivers/electron/src/Main.ts +++ b/receivers/electron/src/Main.ts @@ -302,27 +302,28 @@ export class Main { } }); - let networkStateChangeListener = null; Main.mainWindow.loadFile(path.join(__dirname, 'main/index.html')); Main.mainWindow.on('closed', () => { Main.mainWindow = null; - clearInterval(networkStateChangeListener); }); Main.mainWindow.maximize(); Main.mainWindow.show(); Main.mainWindow.on('ready-to-show', () => { - NetworkService.networkStateChangeListener(true, (interfaces: any) => { - Main.mainWindow.webContents.send("device-info", { name: os.hostname(), interfaces: interfaces }); - - networkStateChangeListener = setInterval(() => { - NetworkService.networkStateChangeListener(false, (interfaces: any) => { - Main.mainWindow.webContents.send("device-info", { name: os.hostname(), interfaces: interfaces }); - }); - }, - NetworkService.networkStateChangeListenerTimeout); + const networkWorker = new BrowserWindow({ + show: false, + webPreferences: { + nodeIntegration: true, + contextIsolation: false, + preload: path.join(__dirname, 'main/networkWorker.js') + } }); + + ipcMain.on('network-changed', (event: IpcMainEvent, value: any) => { + Main.mainWindow.webContents.send("device-info", { name: os.hostname(), interfaces: value }); + }); + networkWorker.loadFile(path.join(__dirname, 'main/worker.html')); }); } diff --git a/receivers/electron/src/main/NetworkWorker.ts b/receivers/electron/src/main/NetworkWorker.ts new file mode 100644 index 0000000..9929428 --- /dev/null +++ b/receivers/electron/src/main/NetworkWorker.ts @@ -0,0 +1,47 @@ +import { ipcRenderer } from 'electron'; +import si from 'modules/systeminformation'; + +const networkStateChangeListenerTimeout = 2500; +let networkStateChangeListenerInterfaces = []; + +networkStateChangeListener(true); +setInterval(networkStateChangeListener, networkStateChangeListenerTimeout); + +function networkStateChangeListener(forceUpdate: boolean) { + new Promise((resolve) => { + si.networkInterfaces((data) => { + // console.log(data); + const queriedInterfaces = Array.isArray(data) ? data : [data]; + + si.wifiConnections((data) => { + // console.log(data); + const wifiConnections = Array.isArray(data) ? data : [data]; + + const interfaces = []; + for (const iface of queriedInterfaces) { + if (iface.ip4 !== '' && !iface.internal && !iface.virtual) { + const isWireless = wifiConnections.some(e => { + if (e.iface === iface.iface) { + interfaces.push({ type: 'wireless', name: e.ssid, address: iface.ip4, signalLevel: e.quality }); + return true; + } + + return false; + }); + + if (!isWireless) { + interfaces.push({ type: 'wired', name: iface.ifaceName, address: iface.ip4 }); + } + } + } + + if (forceUpdate || (JSON.stringify(interfaces) !== JSON.stringify(networkStateChangeListenerInterfaces))) { + networkStateChangeListenerInterfaces = interfaces; + ipcRenderer.send('network-changed', interfaces); + } + + resolve(); + }); + }); + }); +} diff --git a/receivers/electron/src/main/index.html b/receivers/electron/src/main/index.html index b318f28..5fd566f 100644 --- a/receivers/electron/src/main/index.html +++ b/receivers/electron/src/main/index.html @@ -47,6 +47,14 @@
Connection Information
+
+
Fetching Network Info...
+
+
+
+
+
Device not connected to a network
+
Scan with a FCast sender app
@@ -64,10 +72,6 @@
Port
46899 (TCP), 46898 (WS)
-
-
-
Device not connected to a network
-
diff --git a/receivers/electron/src/main/worker.html b/receivers/electron/src/main/worker.html new file mode 100644 index 0000000..5dc152b --- /dev/null +++ b/receivers/electron/src/main/worker.html @@ -0,0 +1,9 @@ + + + + FCast Receiver Worker + + + + + diff --git a/receivers/electron/webpack.config.js b/receivers/electron/webpack.config.js index bf094aa..1e38608 100644 --- a/receivers/electron/webpack.config.js +++ b/receivers/electron/webpack.config.js @@ -63,6 +63,7 @@ module.exports = [ entry: { preload: './src/main/Preload.ts', renderer: './src/main/Renderer.ts', + networkWorker: './src/main/NetworkWorker.ts' }, target: 'electron-renderer', module: {