@@ -14,8 +14,8 @@ use crate::model::{
1414const APP_ID : & str = "1454403710162698293" ;
1515const SP_ICON_ASSET_KEY : & str = "logo-icon" ;
1616
17- // 主要用来应对跳转进度的更新
18- const TIMESTAMP_UPDATE_THRESHOLD_MS : i64 = 100 ;
17+ // 主要用来应对跳转进度的更新(单位:秒)
18+ const TIMESTAMP_UPDATE_THRESHOLD_S : i64 = 2 ;
1919const RECONNECT_COOLDOWN_SECONDS : u8 = 5 ;
2020
2121pub enum RpcMessage {
@@ -235,7 +235,7 @@ impl RpcWorker {
235235 }
236236 }
237237
238- fn build_base_activity ( data : & ActivityData , _display_mode : DiscordDisplayMode ) -> Activity < ' _ > {
238+ fn build_base_activity ( data : & ActivityData , display_mode : DiscordDisplayMode ) -> Activity < ' _ > {
239239 let assets = Assets :: new ( )
240240 . large_image ( & data. cached_cover_url )
241241 . large_text ( & data. metadata . album_name )
@@ -244,12 +244,30 @@ impl RpcWorker {
244244
245245 let buttons = vec ! [ Button :: new( "🎧 Listen" , & data. cached_song_url) ] ;
246246
247- Activity :: new ( )
248- . details ( & data. metadata . song_name )
249- . state ( & data. metadata . author_name )
247+ let mut activity = Activity :: new ( )
250248 . activity_type ( ActivityType :: Listening )
251249 . assets ( assets)
252- . buttons ( buttons)
250+ . buttons ( buttons) ;
251+
252+ // 根据显示模式设置 details 和 state
253+ activity = match display_mode {
254+ DiscordDisplayMode :: Name => {
255+ // 显示为 "Listening to SPlayer"
256+ activity. details ( "SPlayer" )
257+ }
258+ DiscordDisplayMode :: State => {
259+ // 显示为 "Listening to {artist}"
260+ activity. details ( & data. metadata . author_name )
261+ }
262+ DiscordDisplayMode :: Details => {
263+ // 显示为 "Listening to {song}" - by {artist}
264+ activity
265+ . details ( & data. metadata . song_name )
266+ . state ( & data. metadata . author_name )
267+ }
268+ } ;
269+
270+ activity
253271 }
254272
255273 fn calc_paused_timestamps ( current_time : f64 , duration : f64 ) -> ( i64 , i64 ) {
@@ -269,6 +287,11 @@ impl RpcWorker {
269287 }
270288
271289 fn calc_playing_timestamps ( current_time : f64 , duration : f64 ) -> ( i64 , i64 ) {
290+ // 边界检查:如果当前时间超过总时长,返回无效时间戳
291+ if current_time >= duration {
292+ return ( 0 , 0 ) ;
293+ }
294+
272295 let now_ms = SystemTime :: now ( )
273296 . duration_since ( UNIX_EPOCH )
274297 . unwrap_or_default ( )
@@ -335,21 +358,27 @@ impl RpcWorker {
335358 let ( start, end) =
336359 Self :: calc_playing_timestamps ( data. current_time , duration) ;
337360
338- if let Some ( last_end) = last_sent_end_timestamp {
339- let diff = ( * last_end - end) . abs ( ) ;
340- if diff < TIMESTAMP_UPDATE_THRESHOLD_MS {
341- return true ;
361+ // 如果时间戳无效(边界检查失败),跳过此次更新
362+ if start == 0 && end == 0 {
363+ debug ! ( "当前时间超过总时长,跳过时间戳更新" ) ;
364+ should_send = false ;
365+ } else {
366+ if let Some ( last_end) = last_sent_end_timestamp {
367+ let diff = ( * last_end - end) . abs ( ) ;
368+ if diff < TIMESTAMP_UPDATE_THRESHOLD_S {
369+ return true ;
370+ }
371+ debug ! (
372+ diff_s = diff,
373+ threshold_s = TIMESTAMP_UPDATE_THRESHOLD_S ,
374+ "进度变更超过阈值,触发更新"
375+ ) ;
342376 }
343- debug ! (
344- diff_ms = diff,
345- threshold_ms = TIMESTAMP_UPDATE_THRESHOLD_MS ,
346- "进度变更超过阈值,触发更新"
347- ) ;
348- }
349377
350- activity = activity. timestamps ( Timestamps :: new ( ) . start ( start) . end ( end) ) ;
351- new_end_timestamp = Some ( end) ;
352- should_send = true ;
378+ activity = activity. timestamps ( Timestamps :: new ( ) . start ( start) . end ( end) ) ;
379+ new_end_timestamp = Some ( end) ;
380+ should_send = true ;
381+ }
353382 } else {
354383 should_send = last_sent_end_timestamp. is_some ( ) ;
355384 if should_send {
@@ -450,3 +479,11 @@ pub fn update_play_state(status: PlaybackStatus) {
450479pub fn update_timeline ( payload : TimelinePayload ) {
451480 send ( RpcMessage :: Timeline ( payload) ) ;
452481}
482+
483+ pub fn shutdown ( ) {
484+ if let Ok ( mut guard) = SENDER . lock ( ) {
485+ if guard. take ( ) . is_some ( ) {
486+ info ! ( "Shutting down Discord RPC thread." ) ;
487+ }
488+ }
489+ }
0 commit comments