This commit is contained in:
IsraelGPT 2026-02-15 23:57:06 +00:00
parent 762488d823
commit 084bf957f5
4 changed files with 124 additions and 0 deletions

View file

@ -3908,6 +3908,18 @@
<span class="slider"></span>
</label>
</div>
<div class="setting-item">
<div class="info">
<span class="label">Analytics</span>
<span class="description"
>Send anonymous usage data to help improve the app</span
>
</div>
<label class="toggle-switch">
<input type="checkbox" id="analytics-toggle" checked />
<span class="slider"></span>
</label>
</div>
<div class="setting-item">
<div class="info">
<span class="label">Reset Local Data</span>

View file

@ -1,11 +1,22 @@
// js/analytics.js - Plausible Analytics custom event tracking
import { analyticsSettings } from './storage.js';
/**
* Check if analytics is enabled
* @returns {boolean}
*/
function isAnalyticsEnabled() {
return analyticsSettings.isEnabled();
}
/**
* Track a custom event with Plausible
* @param {string} eventName - The name of the event
* @param {object} [props] - Optional event properties
*/
export function trackEvent(eventName, props = {}) {
if (!isAnalyticsEnabled()) return;
if (window.plausible) {
try {
window.plausible(eventName, { props });
@ -26,26 +37,40 @@ export function trackPageView(path) {
// Playback Events
export function trackPlayTrack(track) {
trackEvent('Play Track', {
track_id: track?.id || 'unknown',
track_title: track?.title || 'Unknown',
artist_id: track?.artist?.id || track?.artists?.[0]?.id || 'unknown',
artist: track?.artist?.name || track?.artists?.[0]?.name || 'Unknown',
album_id: track?.album?.id || 'unknown',
album: track?.album?.title || 'Unknown',
duration: track?.duration || 0,
quality: track?.audioQuality || track?.quality || 'Unknown',
is_local: track?.isLocal || false,
is_explicit: track?.explicit || false,
track_number: track?.trackNumber || 0,
year: track?.album?.releaseYear || track?.album?.releaseDate || 'unknown',
});
}
export function trackPauseTrack(track) {
trackEvent('Pause Track', {
track_id: track?.id || 'unknown',
track_title: track?.title || 'Unknown',
artist_id: track?.artist?.id || track?.artists?.[0]?.id || 'unknown',
artist: track?.artist?.name || track?.artists?.[0]?.name || 'Unknown',
album_id: track?.album?.id || 'unknown',
album: track?.album?.title || 'Unknown',
});
}
export function trackSkipTrack(track, direction) {
trackEvent('Skip Track', {
track_id: track?.id || 'unknown',
track_title: track?.title || 'Unknown',
artist_id: track?.artist?.id || track?.artists?.[0]?.id || 'unknown',
artist: track?.artist?.name || track?.artists?.[0]?.name || 'Unknown',
album_id: track?.album?.id || 'unknown',
album: track?.album?.title || 'Unknown',
direction: direction,
});
}
@ -58,6 +83,19 @@ export function trackToggleRepeat(mode) {
trackEvent('Toggle Repeat', { mode });
}
export function trackTrackComplete(track, completionPercent) {
trackEvent('Track Complete', {
track_id: track?.id || 'unknown',
track_title: track?.title || 'Unknown',
artist_id: track?.artist?.id || track?.artists?.[0]?.id || 'unknown',
artist: track?.artist?.name || track?.artists?.[0]?.name || 'Unknown',
album_id: track?.album?.id || 'unknown',
album: track?.album?.title || 'Unknown',
duration: track?.duration || 0,
completion_percent: completionPercent || 100,
});
}
export function trackSetVolume(level) {
// Only track volume changes at coarse intervals to avoid spam
const roundedLevel = Math.round(level * 10) / 10;
@ -80,6 +118,16 @@ export function trackSeek(position, duration) {
}
}
// Track listening progress milestones (10%, 25%, 50%, 75%, 90%, 100%)
export function trackListeningProgress(track, percent) {
trackEvent('Listening Progress', {
track_id: track?.id || 'unknown',
track_title: track?.title || 'Unknown',
artist_id: track?.artist?.id || track?.artists?.[0]?.id || 'unknown',
percent: percent,
});
}
// Search Events
export function trackSearch(query, resultsCount) {
trackEvent('Search', {
@ -108,15 +156,22 @@ export function trackSidebarNavigation(item) {
// Library Events
export function trackLikeTrack(track) {
trackEvent('Like Track', {
track_id: track?.id || 'unknown',
track_title: track?.title || 'Unknown',
artist_id: track?.artist?.id || track?.artists?.[0]?.id || 'unknown',
artist: track?.artist?.name || track?.artists?.[0]?.name || 'Unknown',
album_id: track?.album?.id || 'unknown',
album: track?.album?.title || 'Unknown',
});
}
export function trackUnlikeTrack(track) {
trackEvent('Unlike Track', {
track_id: track?.id || 'unknown',
track_title: track?.title || 'Unknown',
artist_id: track?.artist?.id || track?.artists?.[0]?.id || 'unknown',
artist: track?.artist?.name || track?.artists?.[0]?.name || 'Unknown',
album_id: track?.album?.id || 'unknown',
});
}
@ -204,23 +259,29 @@ export function trackDeleteFolder(folderName) {
// Playback Actions
export function trackPlayAlbum(album, shuffle) {
trackEvent('Play Album', {
album_id: album?.id || 'unknown',
album_title: album?.title || 'Unknown',
artist_id: album?.artist?.id || 'unknown',
artist: album?.artist?.name || 'Unknown',
shuffle: shuffle || false,
track_count: album?.numberOfTracks || album?.tracks?.length || 0,
year: album?.releaseYear || album?.releaseDate || 'unknown',
});
}
export function trackPlayPlaylist(playlist, shuffle) {
trackEvent('Play Playlist', {
playlist_id: playlist?.id || 'unknown',
playlist_name: playlist?.title || playlist?.name || 'Unknown',
shuffle: shuffle || false,
track_count: playlist?.tracks?.length || 0,
is_public: playlist?.isPublic || false,
});
}
export function trackPlayArtistRadio(artist) {
trackEvent('Play Artist Radio', {
artist_id: artist?.id || 'unknown',
artist_name: artist?.name || 'Unknown',
});
}
@ -232,15 +293,20 @@ export function trackShuffleLikedTracks(count) {
// Download Events
export function trackDownloadTrack(track, quality) {
trackEvent('Download Track', {
track_id: track?.id || 'unknown',
track_title: track?.title || 'Unknown',
artist_id: track?.artist?.id || track?.artists?.[0]?.id || 'unknown',
artist: track?.artist?.name || track?.artists?.[0]?.name || 'Unknown',
album_id: track?.album?.id || 'unknown',
quality: quality || 'Unknown',
});
}
export function trackDownloadAlbum(album, quality) {
trackEvent('Download Album', {
album_id: album?.id || 'unknown',
album_title: album?.title || 'Unknown',
artist_id: album?.artist?.id || 'unknown',
artist: album?.artist?.name || 'Unknown',
track_count: album?.numberOfTracks || album?.tracks?.length || 0,
quality: quality || 'Unknown',
@ -249,6 +315,7 @@ export function trackDownloadAlbum(album, quality) {
export function trackDownloadPlaylist(playlist, quality) {
trackEvent('Download Playlist', {
playlist_id: playlist?.id || 'unknown',
playlist_name: playlist?.title || playlist?.name || 'Unknown',
track_count: playlist?.tracks?.length || 0,
quality: quality || 'Unknown',
@ -264,6 +331,7 @@ export function trackDownloadLikedTracks(count, quality) {
export function trackDownloadDiscography(artist, selection) {
trackEvent('Download Discography', {
artist_id: artist?.id || 'unknown',
artist_name: artist?.name || 'Unknown',
include_albums: selection?.includeAlbums || false,
include_eps: selection?.includeEPs || false,
@ -274,16 +342,22 @@ export function trackDownloadDiscography(artist, selection) {
// Queue Management
export function trackAddToQueue(track, position) {
trackEvent('Add to Queue', {
track_id: track?.id || 'unknown',
track_title: track?.title || 'Unknown',
artist_id: track?.artist?.id || track?.artists?.[0]?.id || 'unknown',
artist: track?.artist?.name || track?.artists?.[0]?.name || 'Unknown',
album_id: track?.album?.id || 'unknown',
position: position || 'end',
});
}
export function trackPlayNext(track) {
trackEvent('Play Next', {
track_id: track?.id || 'unknown',
track_title: track?.title || 'Unknown',
artist_id: track?.artist?.id || track?.artists?.[0]?.id || 'unknown',
artist: track?.artist?.name || track?.artists?.[0]?.name || 'Unknown',
album_id: track?.album?.id || 'unknown',
});
}
@ -306,37 +380,46 @@ export function trackContextMenuAction(action, itemType, item) {
export function trackBlockTrack(track) {
trackEvent('Block Track', {
track_id: track?.id || 'unknown',
track_title: track?.title || 'Unknown',
artist_id: track?.artist?.id || track?.artists?.[0]?.id || 'unknown',
artist: track?.artist?.name || track?.artists?.[0]?.name || 'Unknown',
album_id: track?.album?.id || 'unknown',
});
}
export function trackUnblockTrack(track) {
trackEvent('Unblock Track', {
track_id: track?.id || 'unknown',
track_title: track?.title || 'Unknown',
});
}
export function trackBlockAlbum(album) {
trackEvent('Block Album', {
album_id: album?.id || 'unknown',
album_title: album?.title || 'Unknown',
artist_id: album?.artist?.id || 'unknown',
});
}
export function trackUnblockAlbum(album) {
trackEvent('Unblock Album', {
album_id: album?.id || 'unknown',
album_title: album?.title || 'Unknown',
});
}
export function trackBlockArtist(artist) {
trackEvent('Block Artist', {
artist_id: artist?.id || 'unknown',
artist_name: artist?.name || 'Unknown',
});
}
export function trackUnblockArtist(artist) {
trackEvent('Unblock Artist', {
artist_id: artist?.id || 'unknown',
artist_name: artist?.name || 'Unknown',
});
}
@ -634,6 +717,8 @@ export function trackSessionEnd(duration) {
// Initialize analytics on page load
export function initAnalytics() {
if (!isAnalyticsEnabled()) return;
// Track initial page view
trackPageView(window.location.pathname);

View file

@ -31,6 +31,7 @@ import {
pwaUpdateSettings,
contentBlockingSettings,
musicProviderSettings,
analyticsSettings,
} from './storage.js';
import { audioContextManager, EQ_PRESETS } from './audio-context.js';
import { getButterchurnPresets } from './visualizers/butterchurn.js';
@ -2363,6 +2364,15 @@ export function initializeSettings(scrobbler, player, api, ui) {
});
}
// Analytics Toggle
const analyticsToggle = document.getElementById('analytics-toggle');
if (analyticsToggle) {
analyticsToggle.checked = analyticsSettings.isEnabled();
analyticsToggle.addEventListener('change', (e) => {
analyticsSettings.setEnabled(e.target.checked);
});
}
// Reset Local Data Button
const resetLocalDataBtn = document.getElementById('reset-local-data-btn');
if (resetLocalDataBtn) {

View file

@ -1481,6 +1481,23 @@ export const homePageSettings = {
},
};
export const analyticsSettings = {
ENABLED_KEY: 'analytics-enabled',
isEnabled() {
try {
const val = localStorage.getItem(this.ENABLED_KEY);
return val === null ? true : val === 'true';
} catch {
return true;
}
},
setEnabled(enabled) {
localStorage.setItem(this.ENABLED_KEY, enabled ? 'true' : 'false');
},
};
export const sidebarSectionSettings = {
SHOW_HOME_KEY: 'sidebar-show-home',
SHOW_LIBRARY_KEY: 'sidebar-show-library',