mirror of
https://github.com/kilyabin/psysonic.git
synced 2026-07-21 22:15:40 +00:00
feat(player-stats): local listening history tab with heatmap and summaries (#849)
* feat(player-stats): local listening history tab with heatmap and summaries Record play sessions in library.sqlite when the library index is enabled, add Rust read APIs and Tauri commands for year/day aggregates, and ship the Player stats UI with session clustering, event-driven live refresh, and a notice when some servers are excluded from indexing. * test(player-stats): split play_session repo and expand test coverage Move the repository into play_session/ (completion, cluster, integration tests), add remap/purge/FK coverage in Rust, and cover ingestion gates plus live-refresh hooks on the frontend per spec v0.3. * docs(release): CHANGELOG and credits for player stats (PR #849) * fix(player-stats): satisfy tsc and clippy CI gates Use InternetRadioStation field names in the radio skip test and replace manual month/day range checks with RangeInclusive::contains.
This commit is contained in:
@@ -20,12 +20,13 @@ use crate::dto::{
|
||||
count_local_tracks, local_tracks_max_updated_ms, track_index_nonempty, ArtifactInputDto,
|
||||
FactInputDto, LibraryAdvancedSearchRequest, LibraryAdvancedSearchResponse,
|
||||
LibraryCrossServerSearchResponse, LibraryLiveSearchRequest, LibraryLiveSearchResponse, LibraryTrackDto,
|
||||
LibraryTracksEnvelope, OfflinePathDto, PurgeReportDto, SyncJobDto, SyncStateDto,
|
||||
LibraryTracksEnvelope, OfflinePathDto, PlaySessionDayDetailDto, PlaySessionHeatmapDayDto,
|
||||
PlaySessionInputDto, PlaySessionRecentDayDto, PlaySessionYearBoundsDto, PlaySessionYearSummaryDto, PurgeReportDto, SyncJobDto, SyncStateDto,
|
||||
TrackArtifactDto, TrackFactDto, TrackRefDto,
|
||||
};
|
||||
use crate::live_search;
|
||||
use crate::payload::LibrarySyncProgressPayload;
|
||||
use crate::repos::{SyncStateRepository, TrackRepository};
|
||||
use crate::repos::{PlaySessionRepository, SyncStateRepository, TrackRepository};
|
||||
use crate::runtime::{CurrentJob, LibraryRuntime, SyncSession};
|
||||
use crate::search::search_tracks;
|
||||
use crate::store::LibraryStore;
|
||||
@@ -955,6 +956,53 @@ pub fn library_put_fact(
|
||||
crate::repos::FactRepository::new(&runtime.store).put(&server_id, &track_id, &fact, now_unix_ms())
|
||||
}
|
||||
|
||||
#[tauri::command]
|
||||
pub fn library_record_play_session(
|
||||
runtime: State<'_, LibraryRuntime>,
|
||||
input: PlaySessionInputDto,
|
||||
) -> Result<(), String> {
|
||||
PlaySessionRepository::new(&runtime.store).insert(&input)
|
||||
}
|
||||
|
||||
#[tauri::command]
|
||||
pub fn library_get_player_stats_year_summary(
|
||||
runtime: State<'_, LibraryRuntime>,
|
||||
year: i32,
|
||||
) -> Result<PlaySessionYearSummaryDto, String> {
|
||||
PlaySessionRepository::new(&runtime.store).year_summary(year)
|
||||
}
|
||||
|
||||
#[tauri::command]
|
||||
pub fn library_get_player_stats_heatmap(
|
||||
runtime: State<'_, LibraryRuntime>,
|
||||
year: i32,
|
||||
) -> Result<Vec<PlaySessionHeatmapDayDto>, String> {
|
||||
PlaySessionRepository::new(&runtime.store).heatmap(year)
|
||||
}
|
||||
|
||||
#[tauri::command]
|
||||
pub fn library_get_player_stats_day_detail(
|
||||
runtime: State<'_, LibraryRuntime>,
|
||||
date_iso: String,
|
||||
) -> Result<PlaySessionDayDetailDto, String> {
|
||||
PlaySessionRepository::new(&runtime.store).day_detail(&date_iso)
|
||||
}
|
||||
|
||||
#[tauri::command]
|
||||
pub fn library_get_player_stats_year_bounds(
|
||||
runtime: State<'_, LibraryRuntime>,
|
||||
) -> Result<PlaySessionYearBoundsDto, String> {
|
||||
PlaySessionRepository::new(&runtime.store).year_bounds()
|
||||
}
|
||||
|
||||
#[tauri::command]
|
||||
pub fn library_get_player_stats_recent_days(
|
||||
runtime: State<'_, LibraryRuntime>,
|
||||
limit: Option<u32>,
|
||||
) -> Result<Vec<PlaySessionRecentDayDto>, String> {
|
||||
PlaySessionRepository::new(&runtime.store).recent_days(limit.unwrap_or(30))
|
||||
}
|
||||
|
||||
#[tauri::command]
|
||||
pub fn library_purge_server(
|
||||
runtime: State<'_, LibraryRuntime>,
|
||||
@@ -1013,6 +1061,10 @@ pub fn library_purge_server(
|
||||
"DELETE FROM track_id_history WHERE server_id = ?1",
|
||||
params![server_id],
|
||||
)?;
|
||||
tx.execute(
|
||||
"DELETE FROM play_session WHERE server_id = ?1",
|
||||
params![server_id],
|
||||
)?;
|
||||
tx.execute(
|
||||
"DELETE FROM track WHERE server_id = ?1",
|
||||
params![server_id],
|
||||
|
||||
Reference in New Issue
Block a user