From 53e4711c392fa9ed87b26a05ee71d2f712a2435e Mon Sep 17 00:00:00 2001 From: Mastermindzh Date: Sun, 7 May 2023 15:45:45 +0200 Subject: [PATCH] chore: more typescript --- package-lock.json | 7 ++ package.json | 1 + src/constants/{settings.js => settings.ts} | 4 +- src/declarations.d.ts | 1 + src/main.ts | 57 ++++++------ src/models/mediaInfo.ts | 13 +++ src/models/mediaStatus.ts | 4 + src/pages/settings/preload.ts | 61 ++++++------ src/preload.ts | 38 ++++---- src/scripts/discord.js | 103 --------------------- src/scripts/discord.ts | 88 ++++++++++++++++++ src/scripts/express.ts | 19 ++-- src/scripts/mediaInfo.js | 38 -------- src/scripts/mediaInfo.ts | 35 +++++++ src/scripts/{settings.js => settings.ts} | 27 +++--- 15 files changed, 249 insertions(+), 247 deletions(-) rename src/constants/{settings.js => settings.ts} (95%) create mode 100644 src/declarations.d.ts create mode 100644 src/models/mediaInfo.ts create mode 100644 src/models/mediaStatus.ts delete mode 100644 src/scripts/discord.js create mode 100644 src/scripts/discord.ts delete mode 100644 src/scripts/mediaInfo.js create mode 100644 src/scripts/mediaInfo.ts rename src/scripts/{settings.js => settings.ts} (76%) diff --git a/package-lock.json b/package-lock.json index 6ff3b69..39afe00 100644 --- a/package-lock.json +++ b/package-lock.json @@ -20,6 +20,7 @@ }, "devDependencies": { "@mastermindzh/prettier-config": "^1.0.0", + "@types/discord-rpc": "^4.0.4", "@types/express": "^4.17.17", "@types/request": "^2.48.8", "@typescript-eslint/eslint-plugin": "^5.59.1", @@ -953,6 +954,12 @@ "@types/node": "*" } }, + "node_modules/@types/discord-rpc": { + "version": "4.0.4", + "resolved": "https://registry.npmjs.org/@types/discord-rpc/-/discord-rpc-4.0.4.tgz", + "integrity": "sha512-Afr+3GqUqZnQ6bA/WzNp388heVAmfKuNxy6giAde2ZZP7sNr6mnl+ELpcecD/z2sndfKSauLB89ABNqjWWCZlg==", + "dev": true + }, "node_modules/@types/express": { "version": "4.17.17", "resolved": "https://registry.npmjs.org/@types/express/-/express-4.17.17.tgz", diff --git a/package.json b/package.json index d9725ae..c377e6c 100644 --- a/package.json +++ b/package.json @@ -45,6 +45,7 @@ }, "devDependencies": { "@mastermindzh/prettier-config": "^1.0.0", + "@types/discord-rpc": "^4.0.4", "@types/express": "^4.17.17", "@types/request": "^2.48.8", "@typescript-eslint/eslint-plugin": "^5.59.1", diff --git a/src/constants/settings.js b/src/constants/settings.ts similarity index 95% rename from src/constants/settings.js rename to src/constants/settings.ts index b7cf6db..04444e6 100644 --- a/src/constants/settings.js +++ b/src/constants/settings.ts @@ -8,7 +8,7 @@ * }, * windowBounds: { width: 800, height: 600 }, */ -const settings = { +export const settings = { adBlock: "adBlock", api: "api", apiSettings: { @@ -41,5 +41,3 @@ const settings = { height: "windowBounds.height", }, }; - -module.exports = settings; diff --git a/src/declarations.d.ts b/src/declarations.d.ts new file mode 100644 index 0000000..5f44bbf --- /dev/null +++ b/src/declarations.d.ts @@ -0,0 +1 @@ +declare module "mpris-service"; diff --git a/src/main.ts b/src/main.ts index 11c6291..9d7ea4f 100644 --- a/src/main.ts +++ b/src/main.ts @@ -12,19 +12,20 @@ import path from "path"; import flagValues from "./constants/flags"; import globalEvents from "./constants/globalEvents"; import mediaKeys from "./constants/mediaKeys"; -import discordModule from "./scripts/discord"; +import { initRPC, rpc, unRPC } from "./scripts/discord"; import { startExpress } from "./scripts/express"; -import mediaInfoModule from "./scripts/mediaInfo"; +import { updateMediaInfo } from "./scripts/mediaInfo"; import { addMenu } from "./scripts/menu"; import { closeSettingsWindow, createSettingsWindow, hideSettingsWindow, - settings, showSettingsWindow, - store, + settingsStore, } from "./scripts/settings"; +import { settings } from "./constants/settings"; import { addTray, refreshTray } from "./scripts/tray"; +import { MediaInfo } from "./models/mediaInfo"; const tidalUrl = "https://listen.tidal.com"; initialize(); @@ -36,7 +37,7 @@ const PROTOCOL_PREFIX = "tidal"; setFlags(); function setFlags() { - const flags = store.get(settings.flags.root); + const flags = settingsStore.get(settings.flags.root); if (flags) { for (const [key, value] of Object.entries(flags)) { if (value) { @@ -59,7 +60,7 @@ function setFlags() { * */ function syncMenuBarWithStore() { - const fixedMenuBar = !!store.get(settings.menuBar); + const fixedMenuBar = !!settingsStore.get(settings.menuBar); mainWindow.autoHideMenuBar = !fixedMenuBar; mainWindow.setMenuBarVisibility(fixedMenuBar); @@ -72,7 +73,7 @@ function syncMenuBarWithStore() { * @returns true if singInstance is not requested, otherwise true/false based on whether the current window is the main window */ function isMainInstanceOrMultipleInstancesAllowed() { - if (store.get(settings.singleInstance)) { + if (settingsStore.get(settings.singleInstance)) { const gotTheLock = app.requestSingleInstanceLock(); if (!gotTheLock) { @@ -87,8 +88,8 @@ function createWindow(options = { x: 0, y: 0, backgroundColor: "white" }) { mainWindow = new BrowserWindow({ x: options.x, y: options.y, - width: store && store.get(settings.windowBounds.width), - height: store && store.get(settings.windowBounds.height), + width: settingsStore && settingsStore.get(settings.windowBounds.width), + height: settingsStore && settingsStore.get(settings.windowBounds.height), icon, backgroundColor: options.backgroundColor, autoHideMenuBar: true, @@ -106,13 +107,13 @@ function createWindow(options = { x: 0, y: 0, backgroundColor: "white" }) { // load the Tidal website mainWindow.loadURL(tidalUrl); - if (store.get(settings.disableBackgroundThrottle)) { + if (settingsStore.get(settings.disableBackgroundThrottle)) { // prevent setInterval lag mainWindow.webContents.setBackgroundThrottling(false); } mainWindow.on("close", function (event: CloseEvent) { - if (store.get(settings.minimizeOnClose)) { + if (settingsStore.get(settings.minimizeOnClose)) { event.preventDefault(); mainWindow.hide(); refreshTray(mainWindow); @@ -126,12 +127,12 @@ function createWindow(options = { x: 0, y: 0, backgroundColor: "white" }) { }); mainWindow.on("resize", () => { const { width, height } = mainWindow.getBounds(); - store.set(settings.windowBounds.root, { width, height }); + settingsStore.set(settings.windowBounds.root, { width, height }); }); } function registerHttpProtocols() { - protocol.registerHttpProtocol(PROTOCOL_PREFIX, (request, _callback) => { + protocol.registerHttpProtocol(PROTOCOL_PREFIX, (request) => { mainWindow.loadURL(`${tidalUrl}/${request.url.substring(PROTOCOL_PREFIX.length + 3)}`); }); if (!app.isDefaultProtocolClient(PROTOCOL_PREFIX)) { @@ -155,7 +156,7 @@ app.on("ready", async () => { await components.whenReady(); // Adblock - if (store.get(settings.adBlock)) { + if (settingsStore.get(settings.adBlock)) { const filter = { urls: ["https://listen.tidal.com/*"] }; session.defaultSession.webRequest.onBeforeRequest(filter, (details, callback) => { if (details.url.match(/\/users\/.*\d\?country/)) callback({ cancel: true }); @@ -167,12 +168,12 @@ app.on("ready", async () => { addMenu(mainWindow); createSettingsWindow(); addGlobalShortcuts(); - if (store.get(settings.trayIcon)) { + if (settingsStore.get(settings.trayIcon)) { addTray(mainWindow, { icon }); refreshTray(mainWindow); } - store.get(settings.api) && startExpress(mainWindow); - store.get(settings.enableDiscord) && discordModule.initRPC(); + settingsStore.get(settings.api) && startExpress(mainWindow); + settingsStore.get(settings.enableDiscord) && initRPC(); } else { app.quit(); } @@ -191,31 +192,31 @@ app.on("browser-window-created", (_, window) => { }); // IPC -ipcMain.on(globalEvents.updateInfo, (_event, arg) => { - mediaInfoModule.update(arg); +ipcMain.on(globalEvents.updateInfo, (_event, arg: MediaInfo) => { + updateMediaInfo(arg); }); -ipcMain.on(globalEvents.hideSettings, (_event, _arg) => { +ipcMain.on(globalEvents.hideSettings, () => { hideSettingsWindow(); }); -ipcMain.on(globalEvents.showSettings, (_event, _arg) => { +ipcMain.on(globalEvents.showSettings, () => { showSettingsWindow(); }); -ipcMain.on(globalEvents.refreshMenuBar, (_event, _arg) => { +ipcMain.on(globalEvents.refreshMenuBar, () => { syncMenuBarWithStore(); }); -ipcMain.on(globalEvents.storeChanged, (_event, _arg) => { +ipcMain.on(globalEvents.storeChanged, () => { syncMenuBarWithStore(); - if (store.get(settings.enableDiscord) && !discordModule.rpc) { - discordModule.initRPC(); - } else if (!store.get(settings.enableDiscord) && discordModule.rpc) { - discordModule.unRPC(); + if (settingsStore.get(settings.enableDiscord) && !rpc) { + initRPC(); + } else if (!settingsStore.get(settings.enableDiscord) && rpc) { + unRPC(); } }); -ipcMain.on(globalEvents.error, (event, _arg) => { +ipcMain.on(globalEvents.error, (event) => { console.log(event); }); diff --git a/src/models/mediaInfo.ts b/src/models/mediaInfo.ts new file mode 100644 index 0000000..6e6c62b --- /dev/null +++ b/src/models/mediaInfo.ts @@ -0,0 +1,13 @@ +import { MediaStatus } from "./mediaStatus"; + +export interface MediaInfo { + title: string; + artists: string; + album: string; + icon: string; + status: MediaStatus; + url: string; + current: string; + duration: string; + image: string; +} diff --git a/src/models/mediaStatus.ts b/src/models/mediaStatus.ts new file mode 100644 index 0000000..5d66392 --- /dev/null +++ b/src/models/mediaStatus.ts @@ -0,0 +1,4 @@ +export enum MediaStatus { + playing = "playing", + paused = "paused", +} diff --git a/src/pages/settings/preload.ts b/src/pages/settings/preload.ts index 1e9b120..c2e569d 100644 --- a/src/pages/settings/preload.ts +++ b/src/pages/settings/preload.ts @@ -1,3 +1,9 @@ +import remote from "@electron/remote"; +import { ipcRenderer, shell } from "electron"; +import globalEvents from "../../constants/globalEvents"; +import { settings } from "../../constants/settings"; +import { settingsStore } from "./../../scripts/settings"; + let adBlock: HTMLInputElement, api: HTMLInputElement, customCSS: HTMLInputElement, @@ -18,42 +24,35 @@ let adBlock: HTMLInputElement, trayIcon: HTMLInputElement, updateFrequency: HTMLInputElement; -const { store, settings } = require("../../scripts/settings"); -const { ipcRenderer } = require("electron"); -const globalEvents = require("../../constants/globalEvents"); -const remote = require("@electron/remote"); -const { app } = remote; - /** * Sync the UI forms with the current settings */ function refreshSettings() { - adBlock.checked = store.get(settings.adBlock); - api.checked = store.get(settings.api); - customCSS.value = store.get(settings.customCSS); - disableBackgroundThrottle.checked = store.get(settings.disableBackgroundThrottle); - disableHardwareMediaKeys.checked = store.get(settings.flags.disableHardwareMediaKeys); - enableCustomHotkeys.checked = store.get(settings.enableCustomHotkeys); - enableDiscord.checked = store.get(settings.enableDiscord); - gpuRasterization.checked = store.get(settings.flags.gpuRasterization); - menuBar.checked = store.get(settings.menuBar); - minimizeOnClose.checked = store.get(settings.minimizeOnClose); - mpris.checked = store.get(settings.mpris); - notifications.checked = store.get(settings.notifications); - playBackControl.checked = store.get(settings.playBackControl); - port.value = store.get(settings.apiSettings.port); - singleInstance.checked = store.get(settings.singleInstance); - skipArtists.checked = store.get(settings.skipArtists); - skippedArtists.value = (store.get(settings.skippedArtists) as string[]).join("\n"); - trayIcon.checked = store.get(settings.trayIcon); - updateFrequency.value = store.get(settings.updateFrequency); + adBlock.checked = settingsStore.get(settings.adBlock); + api.checked = settingsStore.get(settings.api); + customCSS.value = settingsStore.get(settings.customCSS); + disableBackgroundThrottle.checked = settingsStore.get(settings.disableBackgroundThrottle); + disableHardwareMediaKeys.checked = settingsStore.get(settings.flags.disableHardwareMediaKeys); + enableCustomHotkeys.checked = settingsStore.get(settings.enableCustomHotkeys); + enableDiscord.checked = settingsStore.get(settings.enableDiscord); + gpuRasterization.checked = settingsStore.get(settings.flags.gpuRasterization); + menuBar.checked = settingsStore.get(settings.menuBar); + minimizeOnClose.checked = settingsStore.get(settings.minimizeOnClose); + mpris.checked = settingsStore.get(settings.mpris); + notifications.checked = settingsStore.get(settings.notifications); + playBackControl.checked = settingsStore.get(settings.playBackControl); + port.value = settingsStore.get(settings.apiSettings.port); + singleInstance.checked = settingsStore.get(settings.singleInstance); + skipArtists.checked = settingsStore.get(settings.skipArtists); + skippedArtists.value = settingsStore.get(settings.skippedArtists).join("\n"); + trayIcon.checked = settingsStore.get(settings.trayIcon); + updateFrequency.value = settingsStore.get(settings.updateFrequency); } /** * Open an url in the default browsers */ function openExternal(url: string) { - const { shell } = require("electron"); shell.openExternal(url); } @@ -68,8 +67,8 @@ function hide() { * Restart tidal-hifi after changes */ function restart() { - app.relaunch(); - app.exit(); + remote.app.relaunch(); + remote.app.exit(); } /** @@ -91,9 +90,9 @@ window.addEventListener("DOMContentLoaded", () => { function addInputListener(source: HTMLInputElement, key: string) { source.addEventListener("input", () => { if (source.value === "on") { - store.set(key, source.checked); + settingsStore.set(key, source.checked); } else { - store.set(key, source.value); + settingsStore.set(key, source.value); } ipcRenderer.send(globalEvents.storeChanged); }); @@ -101,7 +100,7 @@ window.addEventListener("DOMContentLoaded", () => { function addTextAreaListener(source: HTMLInputElement, key: string) { source.addEventListener("input", () => { - store.set(key, source.value.split("\n")); + settingsStore.set(key, source.value.split("\n")); ipcRenderer.send(globalEvents.storeChanged); }); } diff --git a/src/preload.ts b/src/preload.ts index 7bf5e3d..5e17004 100644 --- a/src/preload.ts +++ b/src/preload.ts @@ -1,13 +1,15 @@ import { Notification, app, dialog } from "@electron/remote"; import { ipcRenderer } from "electron"; +import Player from "mpris-service"; import globalEvents from "./constants/globalEvents"; -import { customCSS, skipArtists, updateFrequency } from "./constants/settings"; +import { settings } from "./constants/settings"; import statuses from "./constants/statuses"; import { Options } from "./models/options"; import { downloadFile } from "./scripts/download"; import { addHotkey } from "./scripts/hotkeys"; -import { settings, store } from "./scripts/settings"; + import { setTitle } from "./scripts/window-functions"; +import { settingsStore } from "./scripts/settings"; const notificationPath = `${app.getPath("userData")}/notification.jpg`; const appName = "Tidal Hifi"; let currentSong = ""; @@ -146,7 +148,7 @@ const elements = { function addCustomCss() { window.addEventListener("DOMContentLoaded", () => { const style = document.createElement("style"); - style.innerHTML = store.get(customCSS); + style.innerHTML = settingsStore.get(settings.customCSS); document.head.appendChild(style); }); } @@ -156,7 +158,7 @@ function addCustomCss() { * make sure it returns a number, if not use the default */ function getUpdateFrequency() { - const storeValue = store.get(updateFrequency) as number; + const storeValue = settingsStore.get(settings.updateFrequency) as number; const defaultValue = 500; if (!isNaN(storeValue)) { @@ -185,7 +187,7 @@ function playPause() { * https://defkey.com/tidal-desktop-shortcuts */ function addHotKeys() { - if (store.get(settings.enableCustomHotkeys)) { + if (settingsStore.get(settings.enableCustomHotkeys)) { addHotkey("Control+p", function () { elements.click("account").click("settings"); }); @@ -291,7 +293,7 @@ function addIPCEventListeners() { * Update the current status of tidal (e.g playing or paused) */ function getCurrentlyPlayingStatus() { - let pause = elements.get("pause"); + const pause = elements.get("pause"); let status = undefined; // if pause button is visible tidal is playing @@ -320,7 +322,7 @@ function convertDuration(duration: string) { function updateMediaInfo(options: Options, notify: boolean) { if (options) { ipcRenderer.send(globalEvents.updateInfo, options); - if (store.get(settings.notifications) && notify) { + if (settingsStore.get(settings.notifications) && notify) { new Notification({ title: options.title, body: options.artists, icon: options.icon }).show(); } if (player) { @@ -430,23 +432,20 @@ setInterval(function () { // if the image can't be found on the page continue without it resolve(); } - }).then( - () => { - updateMediaInfo(options, titleOrArtistsChanged); - if (titleOrArtistsChanged) { - updateMediaSession(options); - } - }, - () => {} - ); + }).then(() => { + updateMediaInfo(options, titleOrArtistsChanged); + if (titleOrArtistsChanged) { + updateMediaSession(options); + } + }); /** * automatically skip a song if the artists are found in the list of artists to skip * @param {*} artists array of artists */ function skipArtistsIfFoundInSkippedArtistsList(artists: string[]) { - if (store.get(skipArtists)) { - const skippedArtists = store.get(settings.skippedArtists) as string[]; + if (settingsStore.get(settings.skipArtists)) { + const skippedArtists = settingsStore.get(settings.skippedArtists); if (skippedArtists.length > 0) { const artistsToSkip = skippedArtists.map((artist) => artist); const artistNames = Object.values(artists).map((artist) => artist); @@ -459,9 +458,8 @@ setInterval(function () { } }, getUpdateFrequency()); -if (process.platform === "linux" && store.get(settings.mpris)) { +if (process.platform === "linux" && settingsStore.get(settings.mpris)) { try { - const Player = require("mpris-service"); player = Player({ name: "tidal-hifi", identity: "tidal-hifi", diff --git a/src/scripts/discord.js b/src/scripts/discord.js deleted file mode 100644 index b8c6978..0000000 --- a/src/scripts/discord.js +++ /dev/null @@ -1,103 +0,0 @@ -const discordrpc = require("discord-rpc"); -const { app, ipcMain } = require("electron"); -const globalEvents = require("../constants/globalEvents"); -const clientId = "833617820704440341"; -const mediaInfoModule = require("./mediaInfo"); -const discordModule = { - rpc: {}, - unRPC: function () { - return; - }, - initRPC: function () { - return; - }, -}; - -function timeToSeconds(timeArray) { - let minutes = timeArray[0] * 1; - let seconds = minutes * 60 + timeArray[1] * 1; - return seconds; -} - -let rpc; -const observer = (event, arg) => { - if (mediaInfoModule.mediaInfo.status == "paused" && rpc) { - rpc.setActivity(idleStatus); - } else if (rpc) { - const currentSeconds = timeToSeconds(mediaInfoModule.mediaInfo.current.split(":")); - const durationSeconds = timeToSeconds(mediaInfoModule.mediaInfo.duration.split(":")); - const date = new Date(); - const now = (date.getTime() / 1000) | 0; - const remaining = date.setSeconds(date.getSeconds() + (durationSeconds - currentSeconds)); - if (mediaInfoModule.mediaInfo.url) { - rpc.setActivity({ - ...idleStatus, - ...{ - details: `Listening to ${mediaInfoModule.mediaInfo.title}`, - state: mediaInfoModule.mediaInfo.artists - ? mediaInfoModule.mediaInfo.artists - : "unknown artist(s)", - startTimestamp: parseInt(now), - endTimestamp: parseInt(remaining), - largeImageKey: mediaInfoModule.mediaInfo.image, - largeImageText: mediaInfoModule.mediaInfo.album - ? mediaInfoModule.mediaInfo.album - : `${idleStatus.largeImageText}`, - buttons: [{ label: "Play on Tidal", url: mediaInfoModule.mediaInfo.url }], - }, - }); - } else { - rpc.setActivity({ - ...idleStatus, - ...{ - details: `Watching ${mediaInfoModule.mediaInfo.title}`, - state: mediaInfoModule.mediaInfo.artists, - startTimestamp: parseInt(now), - endTimestamp: parseInt(remaining), - }, - }); - } - } -}; - -const idleStatus = { - details: `Browsing Tidal`, - largeImageKey: "tidal-hifi-icon", - largeImageText: `Tidal HiFi ${app.getVersion()}`, - instance: false, -}; - -/** - * Set up the discord rpc and listen on globalEvents.updateInfo - */ -discordModule.initRPC = function () { - rpc = new discordrpc.Client({ transport: "ipc" }); - rpc.login({ clientId }).then( - () => { - discordModule.rpc = rpc; - - rpc.on("ready", () => { - rpc.setActivity(idleStatus); - }); - ipcMain.on(globalEvents.updateInfo, observer); - }, - () => { - console.error("Can't connect to Discord, is it running?"); - } - ); -}; - -/** - * Remove any RPC connection with discord and remove the event listener on globalEvents.updateInfo - */ -discordModule.unRPC = function () { - if (rpc) { - rpc.clearActivity(); - rpc.destroy(); - rpc = false; - discordModule.rpc = undefined; - ipcMain.removeListener(globalEvents.updateInfo, observer); - } -}; - -module.exports = discordModule; diff --git a/src/scripts/discord.ts b/src/scripts/discord.ts new file mode 100644 index 0000000..4d07a21 --- /dev/null +++ b/src/scripts/discord.ts @@ -0,0 +1,88 @@ +import { Client } from "discord-rpc"; +import { app, ipcMain } from "electron"; +import globalEvents from "../constants/globalEvents"; +import { MediaStatus } from "../models/mediaStatus"; +import { mediaInfo } from "./mediaInfo"; + +const clientId = "833617820704440341"; + +function timeToSeconds(timeArray: string[]) { + const minutes = parseInt(timeArray[0]) * 1; + const seconds = minutes * 60 + parseInt(timeArray[1]) * 1; + return seconds; +} + +export let rpc: Client; + +const observer = () => { + if (mediaInfo.status == MediaStatus.paused && rpc) { + rpc.setActivity(idleStatus); + } else if (rpc) { + const currentSeconds = timeToSeconds(mediaInfo.current.split(":")); + const durationSeconds = timeToSeconds(mediaInfo.duration.split(":")); + const date = new Date(); + const now = (date.getTime() / 1000) | 0; + const remaining = date.setSeconds(date.getSeconds() + (durationSeconds - currentSeconds)); + if (mediaInfo.url) { + rpc.setActivity({ + ...idleStatus, + ...{ + details: `Listening to ${mediaInfo.title}`, + state: mediaInfo.artists ? mediaInfo.artists : "unknown artist(s)", + startTimestamp: now, + endTimestamp: remaining, + largeImageKey: mediaInfo.image, + largeImageText: mediaInfo.album ? mediaInfo.album : `${idleStatus.largeImageText}`, + buttons: [{ label: "Play on Tidal", url: mediaInfo.url }], + }, + }); + } else { + rpc.setActivity({ + ...idleStatus, + ...{ + details: `Watching ${mediaInfo.title}`, + state: mediaInfo.artists, + startTimestamp: now, + endTimestamp: remaining, + }, + }); + } + } +}; + +const idleStatus = { + details: `Browsing Tidal`, + largeImageKey: "tidal-hifi-icon", + largeImageText: `Tidal HiFi ${app.getVersion()}`, + instance: false, +}; + +/** + * Set up the discord rpc and listen on globalEvents.updateInfo + */ +export const initRPC = () => { + rpc = new Client({ transport: "ipc" }); + rpc.login({ clientId }).then( + () => { + rpc.on("ready", () => { + rpc.setActivity(idleStatus); + }); + ipcMain.on(globalEvents.updateInfo, observer); + }, + () => { + console.error("Can't connect to Discord, is it running?"); + } + ); +}; + +/** + * Remove any RPC connection with discord and remove the event listener on globalEvents.updateInfo + */ +export const unRPC = () => { + if (rpc) { + rpc.clearActivity(); + rpc.destroy(); + rpc = null; + ipcMain.removeListener(globalEvents.updateInfo, observer); + } +}; diff --git a/src/scripts/express.ts b/src/scripts/express.ts index 232c254..3667621 100644 --- a/src/scripts/express.ts +++ b/src/scripts/express.ts @@ -1,10 +1,11 @@ -import { BrowserWindow } from "electron"; +import { BrowserWindow, dialog } from "electron"; import express, { Response } from "express"; import fs from "fs"; -const { mediaInfo } = require("./mediaInfo"); -const { store, settings } = require("./settings"); -const globalEvents = require("./../constants/globalEvents"); -const statuses = require("./../constants/statuses"); +import globalEvents from "./../constants/globalEvents"; +import statuses from "./../constants/statuses"; +import { mediaInfo } from "./mediaInfo"; +import { settingsStore } from "./settings"; +import { settings } from "../constants/settings"; /** * Function to enable tidal-hifi's express api @@ -37,7 +38,7 @@ export const startExpress = (mainWindow: BrowserWindow) => { }); }); - if (store.get(settings.playBackControl)) { + if (settingsStore.get(settings.playBackControl)) { expressApp.get("/play", (req, res) => handleGlobalEvent(res, globalEvents.play)); expressApp.get("/pause", (req, res) => handleGlobalEvent(res, globalEvents.pause)); expressApp.get("/next", (req, res) => handleGlobalEvent(res, globalEvents.next)); @@ -51,15 +52,15 @@ export const startExpress = (mainWindow: BrowserWindow) => { }); } - let port = store.get(settings.apiSettings.port); + const port = settingsStore.get(settings.apiSettings.port); - const expressInstance = expressApp.listen(port, "127.0.0.1", () => {}); + const expressInstance = expressApp.listen(port, "127.0.0.1"); expressInstance.on("error", function (e: { code: string }) { let message = e.code; if (e.code === "EADDRINUSE") { message = `Port ${port} in use.`; } - const { dialog } = require("electron"); + dialog.showErrorBox("Api failed to start.", message); }); }; diff --git a/src/scripts/mediaInfo.js b/src/scripts/mediaInfo.js deleted file mode 100644 index 92cc2c5..0000000 --- a/src/scripts/mediaInfo.js +++ /dev/null @@ -1,38 +0,0 @@ -const statuses = require("./../constants/statuses"); - -const mediaInfo = { - title: "", - artists: "", - album: "", - icon: "", - status: statuses.paused, - url: "", - current: "", - duration: "", - image: "tidal-hifi-icon", -}; -const mediaInfoModule = { - mediaInfo, - update: function (arg) { - mediaInfo.title = propOrDefault(arg.title); - mediaInfo.artists = propOrDefault(arg.artists); - mediaInfo.album = propOrDefault(arg.album); - mediaInfo.icon = propOrDefault(arg.icon); - mediaInfo.url = propOrDefault(arg.url); - mediaInfo.status = propOrDefault(arg.status); - mediaInfo.current = propOrDefault(arg.current); - mediaInfo.duration = propOrDefault(arg.duration); - mediaInfo.image = propOrDefault(arg.image); - }, -}; - -/** - * Return the property or a default value - * @param {*} prop property to check - * @param {*} defaultValue defaults to "" - */ -function propOrDefault(prop, defaultValue = "") { - return prop ? prop : defaultValue; -} - -module.exports = mediaInfoModule; diff --git a/src/scripts/mediaInfo.ts b/src/scripts/mediaInfo.ts new file mode 100644 index 0000000..e35f7cc --- /dev/null +++ b/src/scripts/mediaInfo.ts @@ -0,0 +1,35 @@ +import { MediaInfo } from "../models/mediaInfo"; +import statuses from "./../constants/statuses"; + +export const mediaInfo = { + title: "", + artists: "", + album: "", + icon: "", + status: statuses.paused, + url: "", + current: "", + duration: "", + image: "tidal-hifi-icon", +}; + +export const updateMediaInfo = (arg: MediaInfo) => { + mediaInfo.title = propOrDefault(arg.title); + mediaInfo.artists = propOrDefault(arg.artists); + mediaInfo.album = propOrDefault(arg.album); + mediaInfo.icon = propOrDefault(arg.icon); + mediaInfo.url = propOrDefault(arg.url); + mediaInfo.status = propOrDefault(arg.status); + mediaInfo.current = propOrDefault(arg.current); + mediaInfo.duration = propOrDefault(arg.duration); + mediaInfo.image = propOrDefault(arg.image); +}; + +/** + * Return the property or a default value + * @param {*} prop property to check + * @param {*} defaultValue defaults to "" + */ +function propOrDefault(prop: string, defaultValue = "") { + return prop ? prop : defaultValue; +} diff --git a/src/scripts/settings.js b/src/scripts/settings.ts similarity index 76% rename from src/scripts/settings.js rename to src/scripts/settings.ts index 0e36c3f..8697d6c 100644 --- a/src/scripts/settings.js +++ b/src/scripts/settings.ts @@ -1,12 +1,12 @@ -const Store = require("electron-store"); +import Store from "electron-store"; -const settings = require("../constants/settings"); -const path = require("path"); -const { BrowserWindow } = require("electron"); +import { settings } from "../constants/settings"; +import path from "path"; +import { BrowserWindow } from "electron"; -let settingsWindow; +let settingsWindow: BrowserWindow; -const store = new Store({ +export const settingsStore = new Store({ defaults: { adBlock: false, api: true, @@ -46,12 +46,11 @@ const store = new Store({ }); const settingsModule = { - store, - settings, + // settings, settingsWindow, }; -settingsModule.createSettingsWindow = function () { +export const createSettingsWindow = function () { settingsWindow = new BrowserWindow({ width: 700, height: 600, @@ -67,7 +66,7 @@ settingsModule.createSettingsWindow = function () { }, }); - settingsWindow.on("close", (event) => { + settingsWindow.on("close", (event: any) => { if (settingsWindow != null) { event.preventDefault(); settingsWindow.hide(); @@ -79,19 +78,17 @@ settingsModule.createSettingsWindow = function () { settingsModule.settingsWindow = settingsWindow; }; -settingsModule.showSettingsWindow = function (tab = "general") { +export const showSettingsWindow = function (tab = "general") { settingsWindow.webContents.send("goToTab", tab); // refresh data just before showing the window settingsWindow.webContents.send("refreshData"); settingsWindow.show(); }; -settingsModule.hideSettingsWindow = function () { +export const hideSettingsWindow = function () { settingsWindow.hide(); }; -settingsModule.closeSettingsWindow = function () { +export const closeSettingsWindow = function () { settingsWindow = null; }; - -module.exports = settingsModule;