remove settings from analytics

This commit is contained in:
jeffvli
2025-11-30 18:19:00 -08:00
parent c7bf0d8fb8
commit 286651c1b3
@@ -1,34 +1,19 @@
import { mutationOptions, useMutation } from '@tanstack/react-query'; import { mutationOptions, useMutation } from '@tanstack/react-query';
import dayjs from 'dayjs'; import dayjs from 'dayjs';
import timezone from 'dayjs/plugin/timezone';
import utc from 'dayjs/plugin/utc'; import utc from 'dayjs/plugin/utc';
import isElectron from 'is-electron'; import isElectron from 'is-electron';
import { useEffect } from 'react'; import { useEffect, useRef } from 'react';
dayjs.extend(utc); dayjs.extend(utc);
dayjs.extend(timezone);
import packageJson from '../../../../../package.json'; import packageJson from '../../../../../package.json';
import { isAnalyticsDisabled } from '/@/renderer/features/analytics/hooks/use-analytics-disabled'; import { isAnalyticsDisabled } from '/@/renderer/features/analytics/hooks/use-analytics-disabled';
import { import { useAuthStore } from '/@/renderer/store';
BarAlign,
PlayerbarSliderType,
SideQueueType,
useAuthStore,
usePlayerStore,
useSettingsStore,
} from '/@/renderer/store';
import { LogCategory, logFn } from '/@/renderer/utils/logger'; import { LogCategory, logFn } from '/@/renderer/utils/logger';
import { logMsg } from '/@/renderer/utils/logger-message'; import { logMsg } from '/@/renderer/utils/logger-message';
import { ServerType } from '/@/shared/types/domain-types'; import { ServerType } from '/@/shared/types/domain-types';
import { import { Platform } from '/@/shared/types/types';
FontType,
Platform,
PlayerQueueType,
PlayerStyle,
PlayerType,
} from '/@/shared/types/types';
const utils = isElectron() ? window.api.utils : null; const utils = isElectron() ? window.api.utils : null;
@@ -59,143 +44,135 @@ const getPlatform = (): AppTrackerProperties['_platform'] => {
type AppTrackerProperties = { type AppTrackerProperties = {
_platform: 'unknown' | Platform; _platform: 'unknown' | Platform;
_version: string; _version: string;
player: { // player: {
mediaSession: boolean; // mediaSession: boolean;
playerQueueType: PlayerQueueType; // playerQueueType: PlayerQueueType;
playerStyle: PlayerStyle; // playerStyle: PlayerStyle;
playerType: PlayerType; // playerType: PlayerType;
transcoding: boolean; // transcoding: boolean;
webAudio: boolean; // webAudio: boolean;
}; // };
server: { server: {
[ServerType.JELLYFIN]: number; [ServerType.JELLYFIN]?: boolean;
[ServerType.NAVIDROME]: number; [ServerType.NAVIDROME]?: boolean;
[ServerType.SUBSONIC]: number; [ServerType.SUBSONIC]?: boolean;
};
settings: {
albumBackground: boolean;
albumBackgroundBlur: number;
artistBackground: boolean;
artistBackgroundBlur: number;
customCss: boolean;
disableAutoUpdate: boolean;
discord: boolean;
exitToTray: boolean;
fontType: FontType;
globalHotkeys: boolean;
homeFeature: boolean;
language: string;
lastFM: boolean;
lyricsEnableAutoTranslation: boolean;
lyricsEnableNeteaseTranslation: boolean;
lyricsFetch: boolean;
minimizeToTray: boolean;
musicBrainz: boolean;
nativeAspectRatio: boolean;
playerbarSliderType: PlayerbarSliderType;
playerbarWaveformAlign: BarAlign;
playerbarWaveformBarWidth: number;
playerbarWaveformGap: number;
playerbarWaveformRadius: number;
preventSleepOnPlayback: boolean;
releaseChannel: string;
resume: boolean;
scrobbleEnabled: boolean;
sideQueueType: SideQueueType;
skipBackwardSeconds: number;
skipButtons: boolean;
skipForwardSeconds: number;
startMinimized: boolean;
theme: string;
tray: boolean;
windowBarStyle: Platform;
zoomFactor: number;
}; };
// settings: {
// albumBackground: boolean;
// albumBackgroundBlur: number;
// artistBackground: boolean;
// artistBackgroundBlur: number;
// customCss: boolean;
// disableAutoUpdate: boolean;
// discord: boolean;
// exitToTray: boolean;
// fontType: FontType;
// globalHotkeys: boolean;
// homeFeature: boolean;
// language: string;
// lastFM: boolean;
// lyricsEnableAutoTranslation: boolean;
// lyricsEnableNeteaseTranslation: boolean;
// lyricsFetch: boolean;
// minimizeToTray: boolean;
// musicBrainz: boolean;
// nativeAspectRatio: boolean;
// playerbarSliderType: PlayerbarSliderType;
// playerbarWaveformAlign: BarAlign;
// playerbarWaveformBarWidth: number;
// playerbarWaveformGap: number;
// playerbarWaveformRadius: number;
// preventSleepOnPlayback: boolean;
// releaseChannel: string;
// resume: boolean;
// scrobbleEnabled: boolean;
// sideQueueType: SideQueueType;
// skipBackwardSeconds: number;
// skipButtons: boolean;
// skipForwardSeconds: number;
// startMinimized: boolean;
// theme: string;
// tray: boolean;
// windowBarStyle: Platform;
// zoomFactor: number;
// };
}; };
const getPlayerProperties = (): AppTrackerProperties['player'] => { // const getPlayerProperties = (): AppTrackerProperties['player'] => {
const player = usePlayerStore.getState(); // const player = usePlayerStore.getState();
const playbackSettings = useSettingsStore.getState().playback; // const playbackSettings = useSettingsStore.getState().playback;
return { // return {
mediaSession: playbackSettings.mediaSession, // mediaSession: playbackSettings.mediaSession,
playerQueueType: player.player.queueType, // playerQueueType: player.player.queueType,
playerStyle: player.player.transitionType, // playerStyle: player.player.transitionType,
playerType: playbackSettings.type, // playerType: playbackSettings.type,
transcoding: playbackSettings.transcode.enabled, // transcoding: playbackSettings.transcode.enabled,
webAudio: playbackSettings.webAudio, // webAudio: playbackSettings.webAudio,
}; // };
}; // };
const getSettingsProperties = (): AppTrackerProperties['settings'] => { // const getSettingsProperties = (): AppTrackerProperties['settings'] => {
const settings = useSettingsStore.getState(); // const settings = useSettingsStore.getState();
return { // return {
albumBackground: settings.general.albumBackground, // albumBackground: settings.general.albumBackground,
albumBackgroundBlur: settings.general.albumBackgroundBlur, // albumBackgroundBlur: settings.general.albumBackgroundBlur,
artistBackground: settings.general.artistBackground, // artistBackground: settings.general.artistBackground,
artistBackgroundBlur: settings.general.artistBackgroundBlur, // artistBackgroundBlur: settings.general.artistBackgroundBlur,
customCss: settings.css.enabled, // customCss: settings.css.enabled,
disableAutoUpdate: settings.window.disableAutoUpdate, // disableAutoUpdate: settings.window.disableAutoUpdate,
discord: settings.discord.enabled, // discord: settings.discord.enabled,
exitToTray: settings.window.exitToTray, // exitToTray: settings.window.exitToTray,
fontType: settings.font.type, // fontType: settings.font.type,
globalHotkeys: settings.hotkeys.globalMediaHotkeys, // globalHotkeys: settings.hotkeys.globalMediaHotkeys,
homeFeature: settings.general.homeFeature, // homeFeature: settings.general.homeFeature,
language: settings.general.language, // language: settings.general.language,
lastFM: settings.general.lastFM, // lastFM: settings.general.lastFM,
lyricsEnableAutoTranslation: settings.lyrics.enableAutoTranslation, // lyricsEnableAutoTranslation: settings.lyrics.enableAutoTranslation,
lyricsEnableNeteaseTranslation: settings.lyrics.enableNeteaseTranslation, // lyricsEnableNeteaseTranslation: settings.lyrics.enableNeteaseTranslation,
lyricsFetch: settings.lyrics.fetch, // lyricsFetch: settings.lyrics.fetch,
minimizeToTray: settings.window.minimizeToTray, // minimizeToTray: settings.window.minimizeToTray,
musicBrainz: settings.general.musicBrainz, // musicBrainz: settings.general.musicBrainz,
nativeAspectRatio: settings.general.nativeAspectRatio, // nativeAspectRatio: settings.general.nativeAspectRatio,
playerbarSliderType: settings.general.playerbarSlider.type as PlayerbarSliderType, // playerbarSliderType: settings.general.playerbarSlider.type as PlayerbarSliderType,
playerbarWaveformAlign: settings.general.playerbarSlider.barAlign as BarAlign, // playerbarWaveformAlign: settings.general.playerbarSlider.barAlign as BarAlign,
playerbarWaveformBarWidth: settings.general.playerbarSlider.barWidth, // playerbarWaveformBarWidth: settings.general.playerbarSlider.barWidth,
playerbarWaveformGap: settings.general.playerbarSlider.barGap, // playerbarWaveformGap: settings.general.playerbarSlider.barGap,
playerbarWaveformRadius: settings.general.playerbarSlider.barRadius, // playerbarWaveformRadius: settings.general.playerbarSlider.barRadius,
preventSleepOnPlayback: settings.window.preventSleepOnPlayback, // preventSleepOnPlayback: settings.window.preventSleepOnPlayback,
releaseChannel: settings.window.releaseChannel, // releaseChannel: settings.window.releaseChannel,
resume: settings.general.resume, // resume: settings.general.resume,
scrobbleEnabled: settings.playback.scrobble.enabled, // scrobbleEnabled: settings.playback.scrobble.enabled,
sideQueueType: settings.general.sideQueueType, // sideQueueType: settings.general.sideQueueType,
skipBackwardSeconds: settings.general.skipButtons.skipBackwardSeconds, // skipBackwardSeconds: settings.general.skipButtons.skipBackwardSeconds,
skipButtons: settings.general.skipButtons.enabled, // skipButtons: settings.general.skipButtons.enabled,
skipForwardSeconds: settings.general.skipButtons.skipForwardSeconds, // skipForwardSeconds: settings.general.skipButtons.skipForwardSeconds,
startMinimized: settings.window.startMinimized, // startMinimized: settings.window.startMinimized,
theme: settings.general.theme, // theme: settings.general.theme,
tray: settings.window.tray, // tray: settings.window.tray,
windowBarStyle: settings.window.windowBarStyle, // windowBarStyle: settings.window.windowBarStyle,
zoomFactor: settings.general.zoomFactor, // zoomFactor: settings.general.zoomFactor,
}; // };
}; // };
const getServerProperties = (): AppTrackerProperties['server'] => { const getServerProperties = (): AppTrackerProperties['server'] => {
const auth = useAuthStore.getState(); const auth = useAuthStore.getState();
const serverList = auth.serverList; const serverList = auth.serverList;
return Object.entries(serverList).reduce( const properties: AppTrackerProperties['server'] = {};
(acc, [, server]) => {
if (server.type === ServerType.JELLYFIN) { Object.values(serverList).forEach((server) => {
acc[ServerType.JELLYFIN] += 1; properties[server.type] = true;
} else if (server.type === ServerType.NAVIDROME) { });
acc[ServerType.NAVIDROME] += 1;
} else if (server.type === ServerType.SUBSONIC) { return properties;
acc[ServerType.SUBSONIC] += 1;
}
return acc;
},
{
[ServerType.JELLYFIN]: 0,
[ServerType.NAVIDROME]: 0,
[ServerType.SUBSONIC]: 0,
},
);
}; };
export const useAppTracker = () => { export const useAppTracker = () => {
const { mutate: trackAppMutation } = useMutation(appTrackerMutation); const { mutate: trackAppMutation } = useMutation(appTrackerMutation);
const isTrackingInProgressRef = useRef(false);
const hasRunOnMountRef = useRef(false);
useEffect(() => { useEffect(() => {
if (!window.umami || isAnalyticsDisabled()) { if (!window.umami || isAnalyticsDisabled()) {
@@ -205,47 +182,60 @@ export const useAppTracker = () => {
const getProperties = () => { const getProperties = () => {
const platform = getPlatform(); const platform = getPlatform();
const version = getVersion(); const version = getVersion();
const playerProperties = getPlayerProperties();
const serverProperties = getServerProperties(); const serverProperties = getServerProperties();
const settingsProperties = getSettingsProperties(); // const playerProperties = getPlayerProperties();
// const settingsProperties = getSettingsProperties();
const properties: AppTrackerProperties = { const properties: AppTrackerProperties = {
_platform: platform, _platform: platform,
_version: version, _version: version,
player: playerProperties,
server: serverProperties, server: serverProperties,
settings: settingsProperties, // player: playerProperties,
// settings: settingsProperties,
}; };
return properties; return properties;
}; };
const checkAndTrack = () => { const checkAndTrack = () => {
const lastSentDate = localStorage.getItem('analytics_app_tracker_timestamp'); // Prevent multiple simultaneous requests
const todayPST = dayjs().tz('America/Los_Angeles').format('YYYY-MM-DD'); if (isTrackingInProgressRef.current) {
return;
}
// Only send if it's a new day in PST const lastSentDate = localStorage.getItem('analytics_app_tracker_timestamp');
if (lastSentDate !== todayPST) { const todayUTC = dayjs.utc().format('YYYY-MM-DD');
// Only send if it's a new day in UTC (ensures once per 24 hours)
if (lastSentDate !== todayUTC) {
isTrackingInProgressRef.current = true;
const properties = getProperties(); const properties = getProperties();
trackAppMutation(properties, { trackAppMutation(properties, {
onError: () => {},
onSettled: () => { onSettled: () => {
isTrackingInProgressRef.current = false;
},
onSuccess: () => {
// Only update timestamp on success to ensure we only send once per 24 hours
const utcDate = dayjs.utc().format('YYYY-MM-DD');
localStorage.setItem('analytics_app_tracker_timestamp', utcDate);
logFn.debug(logMsg[LogCategory.ANALYTICS].appTracked, { logFn.debug(logMsg[LogCategory.ANALYTICS].appTracked, {
category: LogCategory.ANALYTICS, category: LogCategory.ANALYTICS,
meta: { properties }, meta: { properties },
}); });
const pstDate = dayjs().tz('America/Los_Angeles').format('YYYY-MM-DD');
localStorage.setItem('analytics_app_tracker_timestamp', pstDate);
}, },
}); });
} }
}; };
// Check immediately on mount // Check immediately on mount
checkAndTrack(); if (!hasRunOnMountRef.current) {
hasRunOnMountRef.current = true;
checkAndTrack();
}
// Then check every hour
const interval = setInterval(checkAndTrack, 1000 * 60 * 60); const interval = setInterval(checkAndTrack, 1000 * 60 * 60);
return () => clearInterval(interval); return () => clearInterval(interval);