Skip to content
Open
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
55 changes: 54 additions & 1 deletion src-tauri/src/discord.rs
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,41 @@ pub fn try_connect() -> Option<DiscordIpcClient> {
Some(client)
}

fn get_quality_desc(state: &PlaybackState) -> Option<String> {
let sample_rate = state.sample_rate?;

// Hi-Res is typically > 48 kHz (e.g., 88.2, 96, 192 kHz) or > 16-bit depth
let is_hi_res = sample_rate > 48000 || state.bits_per_sample.map_or(false, |b| b > 16);
// Lossless is CD quality or standard lossless (>= 44.1 kHz, e.g., 44.1 kHz, 48 kHz)
let is_lossless = sample_rate >= 44100;

let badge = if is_hi_res {
"Hi-Res"
} else if is_lossless {
"Lossless"
} else {
"HQ"
};

let khz = (sample_rate as f64) / 1000.0;
let khz_str = if sample_rate % 1000 == 0 {
format!("{:.0}", khz)
} else {
format!("{:.1}", khz)
};

let bit_depth = state.bits_per_sample.map(|bits| format!("{}-bit", bits));

let mut parts = Vec::new();
parts.push(badge.to_string());
if let Some(bd) = bit_depth {
parts.push(bd);
}
parts.push(format!("{} kHz", khz_str));

Some(parts.join(" • "))
}

fn build_activity<'a>(
state: &'a PlaybackState,
artwork_url: Option<&'a str>,
Expand Down Expand Up @@ -67,10 +102,16 @@ fn build_activity<'a>(
.small_image(small_image)
.small_text(small_text);

let state_text = if let Some(quality) = get_quality_desc(state) {
format!("{} • {}", track.artist, quality)
} else {
track.artist.clone()
};

let mut activity = Activity::new()
.status_display_type(StatusDisplayType::Details)
.details(track.title.clone())
.state(track.artist.clone())
.state(state_text)
.assets(assets);

if state.is_playing {
Expand Down Expand Up @@ -248,6 +289,18 @@ mod tests {
assert_eq!(value["assets"]["small_text"], "Playing");
}

#[test]
fn activity_includes_playback_quality() {
let state = playback_state(true);
let activity = build_activity(&state, None).expect("activity");
let value = serde_json::to_value(activity).expect("activity json");

assert_eq!(
value["state"],
"Test Artist • Lossless • 16-bit • 44.1 kHz"
);
}

#[test]
fn finished_track_clears_activity() {
let mut state = playback_state(false);
Expand Down