add logs to discord rpc events

This commit is contained in:
jeffvli
2025-11-28 13:48:25 -08:00
parent 2f32534cf9
commit f0c35be21f
3 changed files with 117 additions and 7 deletions
@@ -1,6 +1,6 @@
import { SetActivity, StatusDisplayType } from '@xhayper/discord-rpc';
import isElectron from 'is-electron';
import { useCallback, useEffect, useState } from 'react';
import { useCallback, useEffect, useRef, useState } from 'react';
import { controller } from '/@/renderer/api/controller';
import {
@@ -13,6 +13,8 @@ import {
useTimestampStoreBase,
} from '/@/renderer/store';
import { sentenceCase } from '/@/renderer/utils';
import { LogCategory, logFn } from '/@/renderer/utils/logger';
import { logMsg } from '/@/renderer/utils/logger-message';
import { QueueSong, ServerType } from '/@/shared/types/domain-types';
import { PlayerStatus } from '/@/shared/types/types';
@@ -30,6 +32,8 @@ export const useDiscordRpc = () => {
const privateMode = useAppStore((state) => state.privateMode);
const [lastUniqueId, setlastUniqueId] = useState('');
const previousEnabledRef = useRef<boolean>(discordSettings.enabled);
const setActivity = useCallback(
async (current: ActivityState, previous: ActivityState) => {
if (
@@ -37,6 +41,22 @@ export const useDiscordRpc = () => {
current[1] === 0 || // Start of track
(current[2] === 'paused' && !discordSettings.showPaused) // Track paused with show paused setting disabled
) {
let reason: string;
if (!current[0]) {
reason = 'no_track';
} else if (current[1] === 0) {
reason = 'start_of_track';
} else {
reason = 'paused_with_show_paused_disabled';
}
logFn.debug(logMsg[LogCategory.EXTERNAL].discordRpcActivityCleared, {
category: LogCategory.EXTERNAL,
meta: {
reason,
status: current[2],
},
});
return discordRpc?.clearActivity();
}
@@ -57,9 +77,40 @@ export const useDiscordRpc = () => {
current[2] !== previous[2]
) {
if (trackChanged) {
logFn.debug(logMsg[LogCategory.EXTERNAL].discordRpcTrackChanged, {
category: LogCategory.EXTERNAL,
meta: {
artistName: song.artists?.[0]?.name,
songId: song._uniqueId,
songName: song.name,
},
});
setlastUniqueId(song._uniqueId);
}
let reason: string;
if (previous[1] === 0) {
reason = 'song_started';
} else if (Math.abs(current[1] - previous[1]) > 1.2) {
reason = 'time_jump';
} else if (trackChanged) {
reason = 'track_changed';
} else {
reason = 'player_state_changed';
}
logFn.debug(logMsg[LogCategory.EXTERNAL].discordRpcActivityUpdate, {
category: LogCategory.EXTERNAL,
meta: {
currentStatus: current[2],
currentTime: current[1],
previousStatus: previous[2],
previousTime: previous[1],
reason,
trackChanged,
},
});
const start = Math.round(Date.now() - current[1] * 1000);
const end = Math.round(start + song.duration);
@@ -170,10 +221,41 @@ export const useDiscordRpc = () => {
// Initialize if needed
const isConnected = await discordRpc?.isConnected();
if (!isConnected) {
logFn.debug(logMsg[LogCategory.EXTERNAL].discordRpcInitialized, {
category: LogCategory.EXTERNAL,
meta: {
clientId: discordSettings.clientId,
},
});
await discordRpc?.initialize(discordSettings.clientId);
}
logFn.debug(logMsg[LogCategory.EXTERNAL].discordRpcSetActivity, {
category: LogCategory.EXTERNAL,
meta: {
albumName: song.album,
artistName: song.artists?.[0]?.name,
displayType: discordSettings.displayType,
hasLargeImage: !!activity.largeImageKey,
hasTimestamps: !!(activity.startTimestamp && activity.endTimestamp),
showAsListening: discordSettings.showAsListening,
songName: song.name,
status: current[2],
},
});
discordRpc?.setActivity(activity);
} else {
logFn.debug(logMsg[LogCategory.EXTERNAL].discordRpcUpdateSkipped, {
category: LogCategory.EXTERNAL,
meta: {
currentStatus: current[2],
currentTime: current[1],
previousStatus: previous[2],
previousTime: previous[1],
timeDiff: Math.abs(current[1] - previous[1]),
trackChanged,
},
});
}
},
[
@@ -188,20 +270,36 @@ export const useDiscordRpc = () => {
],
);
// Quit Discord RPC if it was enabled and is now disabled
useEffect(() => {
if (!discordSettings.enabled || privateMode) {
if ((!discordSettings.enabled || privateMode) && Boolean(previousEnabledRef.current)) {
logFn.info(logMsg[LogCategory.EXTERNAL].discordRpcQuit, {
category: LogCategory.EXTERNAL,
meta: {
enabled: discordSettings.enabled,
privateMode,
},
});
previousEnabledRef.current = false;
return discordRpc?.quit();
}
return () => {
discordRpc?.quit();
};
}, [discordSettings.clientId, privateMode, discordSettings.enabled]);
useEffect(() => {
if (!discordSettings.enabled || privateMode) {
return;
}
logFn.info(logMsg[LogCategory.EXTERNAL].discordRpcEnabled, {
category: LogCategory.EXTERNAL,
meta: {
clientId: discordSettings.clientId,
subscribed: true,
},
});
const unsubSongChange = usePlayerStore.subscribe((state): ActivityState => {
const currentSong = state.getCurrentSong();
const currentTime = useTimestampStoreBase.getState().timestamp;
@@ -209,8 +307,9 @@ export const useDiscordRpc = () => {
return [currentSong, currentTime, status];
}, setActivity);
return () => {
unsubSongChange();
};
}, [discordSettings.enabled, privateMode, setActivity]);
}, [discordSettings.clientId, discordSettings.enabled, privateMode, setActivity]);
};
+10
View File
@@ -6,6 +6,16 @@ export const logMsg = {
pageViewTracked: 'Page view tracked',
},
[LogCategory.API]: {},
[LogCategory.EXTERNAL]: {
discordRpcActivityCleared: 'Activity was cleared for Discord RPC',
discordRpcActivityUpdate: 'Activity was updated for Discord RPC',
discordRpcEnabled: 'Discord RPC was enabled',
discordRpcInitialized: 'Discord RPC was initialized',
discordRpcQuit: 'Discord RPC was quit',
discordRpcSetActivity: 'Activity was set for Discord RPC',
discordRpcTrackChanged: 'Track was changed for Discord RPC',
discordRpcUpdateSkipped: 'Activity was not updated for Discord RPC',
},
[LogCategory.OTHER]: {},
[LogCategory.PLAYER]: {
addToQueueByData: 'Added to queue by data',
+1
View File
@@ -3,6 +3,7 @@ import dayjs from 'dayjs';
export enum LogCategory {
ANALYTICS = 'analytics',
API = 'api',
EXTERNAL = 'external',
OTHER = 'other',
PLAYER = 'player',
SCROBBLE = 'scrobble',