diff --git a/README.md b/README.md index da7a384..b279e5d 100644 --- a/README.md +++ b/README.md @@ -18,13 +18,8 @@ ### Settings (tray / notifications icon) > Settings are available in the tray icon (located in the notification icons area) -- Toggle: Shows or hides the DeezerRPC window. -- Player: Manually control basic player actions outside main window. -- Settings: Miscellaneous options like controlling how the window is minimized and checking for updates on startup. -- Check for updates: Check if there is a new version available. -- DeezerRPC [version]: Open this GitHub page. -- Exit: Closes the application. +Right click the tray icon to display the menu. ## Notes - This application is not affiliated with Deezer or Discord. diff --git a/package.json b/package.json index 31f06bc..8ea2451 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "deezer-rpc", - "version": "1.0.3", + "version": "1.0.4", "description": "Deezer integrated with the Discord Rich Presence.", "main": "build/main.js", "scripts": { diff --git a/src/app/app.ts b/src/app/app.ts index a9e9575..adbe678 100644 --- a/src/app/app.ts +++ b/src/app/app.ts @@ -1,6 +1,8 @@ -import { Client } from 'discord-rpc'; -import { BrowserWindow } from 'electron'; +import {Client} from 'discord-rpc'; import ElectronStore from 'electron-store'; +import {SetIntervalAsyncTimer} from "set-interval-async"; +import {setIntervalAsync} from "set-interval-async/dynamic"; +import {updateRPC} from "../player/player"; const PACKAGE = require('../../package.json'); @@ -18,41 +20,63 @@ export const APP = { discordClientID: '1193973433986449458' }, preferences: { - closeToTray: 'closeToTray', - checkUpdates: 'checkUpdates', - startOnStartup: 'startOnStartup', + closeToTray: 'closeToTray', checkUpdates: 'checkUpdates', startOnStartup: 'startOnStartup', }, }; export const APP_CONFIG = new ElectronStore({ defaults: { - closeToTray: true, - checkUpdates: true, - startOnStartup: true, + closeToTray: true, checkUpdates: true, startOnStartup: true, } }); -// RPC -export let RPC = new Client({ - transport: 'ipc' -}); +let rpc: Client; + +export function getRPC() { + if (rpc == null) { + resetRPC(); + } + return rpc; +} + +let connected = false; +let timer: SetIntervalAsyncTimer + +export function isConnected() { + return connected; +} -let firstTime = true; +function resetRPC() { + connected = false; + newClient() +} -export function resetRPC() { - let newClient = new Client({ +function newClient() { + rpc = new Client({ transport: 'ipc' }); +} - if (firstTime) { - firstTime = false; - RPC = newClient; - return; - } - - RPC.destroy().then(() => { - RPC = newClient; - }).catch(() => { - RPC = newClient; - }) +export function handleRPCError(reason: any) { + console.error('Failed to initialize RPC, retrying in 10 seconds... Reason: ' + reason.message); + resetRPC() + setTimeout(() => { + console.log('Retrying RPC initialization...'); + initializeRPC(); + }, 10_000); } + +export function initializeRPC() { + if (timer == null) { + timer = setIntervalAsync(updateRPC, 1_000); + } + try { + getRPC().login({clientId: APP.settings.discordClientID}).then(() => { + if (connected) return; + connected = true; + console.log('RPC initialized successfully'); + }).catch(handleRPCError); + } catch (e) { + handleRPCError(e) + } +} \ No newline at end of file diff --git a/src/main.ts b/src/main.ts index 0912a6b..d0e3b29 100644 --- a/src/main.ts +++ b/src/main.ts @@ -1,4 +1,4 @@ -import {APP, resetRPC, RPC} from './app/app'; +import {APP, initializeRPC} from './app/app'; import * as Tray from './manager/tray'; import * as Update from './utils/update'; import * as Player from './player/player'; @@ -38,11 +38,15 @@ function createMainWindow() { // Load URL mainWindow.loadURL(APP.settings.deezerUrl, {userAgent: Window.userAgent()}).then(() => { - let css = ` - .page-topbar, .css-efpag6, .tempo-topbar, #dzr-app { - margin-top: 30px !important; - } - `; + let selectors = [ + '.page-topbar', + '.css-efpag6', + '.tempo-topbar', + '#dzr-app', + '.mtZhp' + ]; + + let css = selectors.join(', ') + ' { margin-top: 30px !important; }'; let javascript = ` if (document.head.querySelector('#deezer-rpc-css') == null) { @@ -71,6 +75,7 @@ function createMainWindow() { mainWindow.setPosition(mainWindowStateKeeper.x, mainWindowStateKeeper.y) mainWindow.setSize(mainWindowStateKeeper.width, mainWindowStateKeeper.height) TitleBar.register() + loadThumbnailButtons() }); mainWindow.on('hide', () => { mainWindowStateKeeper.saveState(mainWindow); @@ -78,7 +83,7 @@ function createMainWindow() { }) mainWindow.on('minimize', () => { - mainWindow.hide(); + mainWindow.minimize(); }); mainWindow.on('close', (event) => { @@ -97,7 +102,6 @@ function handleLoadComplete() { Tray.register(); Player.registerShortcuts(); - loadThumbnailButtons() if (Preferences.getPreference(APP.preferences.checkUpdates)) Update.checkVersion(false); @@ -106,6 +110,9 @@ function handleLoadComplete() { } export function loadThumbnailButtons(playing: boolean = false) { + if (!mainWindow.isVisible()) { + return; + } mainWindow.setThumbarButtons([{ tooltip: 'Previous', icon: nativeImage.createFromPath(path.join(__dirname, 'assets/images/previous.png')), @@ -125,17 +132,6 @@ export function getMainWindow() { return mainWindow; } -function initializeRPC() { - RPC.login({clientId: APP.settings.discordClientID}).then(() => { - console.log('RPC initialized successfully'); - setTimeout(Player.registerRPC, 3000); - }).catch(() => { - console.error('Failed to initialize RPC, retrying in 10 seconds...'); - resetRPC() - setTimeout(initializeRPC, 10000); - }); -} - const gotTheLock = app.requestSingleInstanceLock() if (!gotTheLock) { diff --git a/src/player/player.ts b/src/player/player.ts index 1e65ecd..e8e8ef2 100644 --- a/src/player/player.ts +++ b/src/player/player.ts @@ -1,4 +1,4 @@ -import {APP, RPC} from '../app/app'; +import {APP, getRPC, handleRPCError, isConnected} from '../app/app'; import Song from '../model/song'; import Radio from '../model/radio'; import Unknown from '../model/unknown'; @@ -6,7 +6,6 @@ import Episode from '../model/episode'; import * as Tray from '../manager/tray'; import {globalShortcut} from 'electron'; import PlayerModel from '../model/player'; -import {setIntervalAsync} from 'set-interval-async/dynamic'; import {getMainWindow, loadThumbnailButtons} from "../main"; let LAST = ''; @@ -32,28 +31,24 @@ export function registerShortcuts() { globalShortcut.register('MediaPreviousTrack', () => previousSong()); } -export function registerRPC() { - setIntervalAsync(updateRPC, 1_000); -} +export async function updateRPC() { + let [current, listening, remaining] = await getMainWindow().webContents.executeJavaScript(`[ dzPlayer.getCurrentSong(),dzPlayer.isPlaying(), dzPlayer.getRemainingTime() ]`); -async function updateRPC() { - try { - let [current, listening, remaining] = await getMainWindow().webContents.executeJavaScript(`[ - dzPlayer.getCurrentSong(), - dzPlayer.isPlaying(), - dzPlayer.getRemainingTime() - ]`); + playing = listening; - playing = listening; + SONG = getSong(current, listening, remaining); - SONG = getSong(current, listening, remaining); + loadThumbnailButtons(listening); - loadThumbnailButtons(listening); + if (!isConnected()) { + return; + } + try { if (!SONG.listening) { - RPC.clearActivity(); + getRPC().clearActivity().catch(handleRPCError) } else { - RPC.setActivity({ + getRPC().setActivity({ details: SONG.title, state: SONG.getState(), startTimestamp: SONG.getStartTimestamp(), @@ -64,7 +59,7 @@ async function updateRPC() { smallImageText: 'DeezerRPC v' + APP.version, buttons: SONG.getButtons(), instance: false - }); + }).catch(handleRPCError); if (LAST !== SONG.getId()) { Tray.setMessage(SONG.trayMessage); @@ -72,7 +67,7 @@ async function updateRPC() { } } } catch (e) { - console.error(e); + handleRPCError(e) } }