@@ -13,7 +13,7 @@ use futures::{
1313 Future ,
1414 task:: { Context , Poll } ,
1515} ;
16- use librespot_connect:: { LoadRequest , LoadRequestOptions , Spirc } ;
16+ use librespot_connect:: { LoadContextOptions , LoadRequest , LoadRequestOptions , Spirc } ;
1717use librespot_core:: { Session , SpotifyId , spotify_id:: SpotifyItemType } ;
1818use librespot_metadata:: audio:: AudioItem ;
1919use librespot_playback:: player:: PlayerEvent ;
@@ -139,33 +139,36 @@ impl Position {
139139#[ derive( Clone , Copy , Debug ) ]
140140enum RepeatState {
141141 None ,
142- // Track,
142+ Track ,
143143 All ,
144144}
145145
146146impl RepeatState {
147147 fn to_mpris ( self ) -> & ' static str {
148148 match self {
149149 RepeatState :: None => "None" ,
150- // RepeatState::Track => "Track",
150+ RepeatState :: Track => "Track" ,
151151 RepeatState :: All => "Playlist" ,
152152 }
153153 }
154- }
155154
156- impl From < RepeatState > for bool {
157- fn from ( repeat : RepeatState ) -> Self {
158- match repeat {
159- RepeatState :: None => false ,
160- RepeatState :: All => true ,
161- }
155+ fn repeat_track ( self ) -> bool {
156+ matches ! ( self , RepeatState :: Track )
157+ }
158+
159+ fn repeat_context ( self ) -> bool {
160+ ! matches ! ( self , RepeatState :: None )
162161 }
163162}
164163
165- impl From < bool > for RepeatState {
166- fn from ( repeat : bool ) -> Self {
167- if repeat {
168- RepeatState :: All
164+ impl From < ( bool , bool ) > for RepeatState {
165+ fn from ( ( context, track) : ( bool , bool ) ) -> Self {
166+ if context {
167+ if track {
168+ RepeatState :: Track
169+ } else {
170+ RepeatState :: All
171+ }
169172 } else {
170173 RepeatState :: None
171174 }
@@ -264,6 +267,7 @@ impl CurrentStateInner {
264267 insert_attr ( & mut changed, "Metadata" , self . to_metadata ( ) ) ;
265268 }
266269 PlayerEvent :: PositionCorrection { position_ms, .. }
270+ | PlayerEvent :: PositionChanged { position_ms, .. }
267271 | PlayerEvent :: Seeked { position_ms, .. } => {
268272 self . update_position ( Duration :: milliseconds ( position_ms as i64 ) ) ;
269273 seeked = true ;
@@ -272,8 +276,8 @@ impl CurrentStateInner {
272276 self . shuffle = shuffle;
273277 insert_attr ( & mut changed, "Shuffle" , self . shuffle ) ;
274278 }
275- PlayerEvent :: RepeatChanged { context : _ , track } => {
276- self . repeat = track. into ( ) ;
279+ PlayerEvent :: RepeatChanged { context, track } => {
280+ self . repeat = ( context , track) . into ( ) ;
277281 insert_attr (
278282 & mut changed,
279283 "LoopStatus" ,
@@ -293,7 +297,6 @@ impl CurrentStateInner {
293297 | PlayerEvent :: SessionConnected { .. }
294298 | PlayerEvent :: SessionDisconnected { .. }
295299 | PlayerEvent :: SessionClientChanged { .. } => ( ) ,
296- PlayerEvent :: PositionChanged { .. } => ( ) ,
297300 }
298301
299302 ( changed, seeked)
@@ -644,8 +647,9 @@ fn register_player_interface(
644647 } ) ;
645648 let local_spirc = spirc. clone ( ) ;
646649 b. method ( "Stop" , ( ) , ( ) , move |_, _, ( ) : ( ) | {
650+ let pause_playback = false ;
647651 local_spirc
648- . disconnect ( false )
652+ . disconnect ( pause_playback )
649653 . map_err ( |e| MethodErr :: failed ( & e) )
650654 } ) ;
651655
@@ -710,23 +714,25 @@ fn register_player_interface(
710714 let local_state = current_state. clone ( ) ;
711715 b. method ( "OpenUri" , ( "uri" , ) , ( ) , move |_, _, ( uri, ) : ( String , ) | {
712716 let id = SpotifyId :: from_uri ( & uri) . map_err ( |e| MethodErr :: invalid_arg ( & e) ) ?;
713- let CurrentStateInner { shuffle, .. } = * local_state. read ( ) ?;
717+ let CurrentStateInner {
718+ shuffle, repeat, ..
719+ } = * local_state. read ( ) ?;
714720
715721 let session = session. clone ( ) ;
716722
717723 let ( playing_track_index, context_uri) = Handle :: current ( )
718724 . block_on ( async move {
719725 use librespot_metadata:: * ;
720726 Ok :: < _ , librespot_core:: Error > ( match id. item_type {
721- SpotifyItemType :: Album => ( 0 , uri) ,
722- SpotifyItemType :: Artist => ( 0 , uri) ,
723- SpotifyItemType :: Playlist => ( 0 , uri) ,
724727 SpotifyItemType :: Track => {
725728 let track = Track :: get ( & session, & id) . await ?;
726729 ( track. number as u32 , track. album . id . to_uri ( ) ?)
727730 }
728- SpotifyItemType :: Episode => ( 0 , uri) ,
729- SpotifyItemType :: Show => ( 0 , uri) ,
731+ SpotifyItemType :: Album
732+ | SpotifyItemType :: Artist
733+ | SpotifyItemType :: Playlist
734+ | SpotifyItemType :: Episode
735+ | SpotifyItemType :: Show => ( 0 , uri) ,
730736 SpotifyItemType :: Local | SpotifyItemType :: Unknown => {
731737 return Err ( librespot_core:: Error :: unimplemented (
732738 "this type of uri is not supported" ,
@@ -746,11 +752,11 @@ fn register_player_interface(
746752 LoadRequestOptions {
747753 start_playing : true ,
748754 seek_to : 0 ,
749- context_options : Some ( librespot_connect :: LoadContextOptions :: Options (
755+ context_options : Some ( LoadContextOptions :: Options (
750756 librespot_connect:: Options {
751757 shuffle,
752- repeat : false ,
753- repeat_track : false ,
758+ repeat : repeat . repeat_context ( ) ,
759+ repeat_track : repeat . repeat_track ( ) ,
754760 } ,
755761 ) ) ,
756762 playing_track : Some ( librespot_connect:: PlayingTrack :: Index (
@@ -769,18 +775,17 @@ fn register_player_interface(
769775 Ok ( playback_state. to_mpris ( ) . to_string ( ) )
770776 } ) ;
771777
772- // let local_spirc = spirc.clone();
778+ let local_spirc = spirc. clone ( ) ;
773779 let local_state = current_state. clone ( ) ;
774780 b. property ( "Shuffle" )
775781 . emits_changed_false ( )
776- . get ( move |_, _| Ok ( local_state. read ( ) ?. shuffle ) ) ;
777- // TODO: re-enable, once setting shuffle via spirc works
778- // .set(move |_, _, value| {
779- // local_spirc
780- // .shuffle(value)
781- // .map(|_| None)
782- // .map_err(|err| dbus::MethodErr::failed(&err))
783- // });
782+ . get ( move |_, _| Ok ( local_state. read ( ) ?. shuffle ) )
783+ . set ( move |_, _, value| {
784+ local_spirc
785+ . shuffle ( value)
786+ . map ( |_| None )
787+ . map_err ( |err| dbus:: MethodErr :: failed ( & err) )
788+ } ) ;
784789
785790 b. property ( "Rate" ) . emits_changed_const ( ) . get ( |_, _| Ok ( 1.0 ) ) ;
786791 b. property ( "MaximumRate" )
@@ -811,20 +816,25 @@ fn register_player_interface(
811816 Ok ( repeat. to_mpris ( ) . to_string ( ) )
812817 } )
813818 . set ( move |_, _, value| {
814- let new_repeat = match value. as_str ( ) {
815- "None" => false ,
816- "Playlist" => true ,
819+ let repeat = match value. as_str ( ) {
820+ "None" => RepeatState :: None ,
821+ "Playlist" => RepeatState :: All ,
822+ "Track" => RepeatState :: Track ,
817823 mode => {
818824 return Err ( dbus:: MethodErr :: failed ( & format ! (
819825 "unsupported repeat mode: {mode}"
820826 ) ) ) ;
821827 }
822828 } ;
829+
823830 local_spirc
824- . repeat ( new_repeat )
831+ . repeat ( repeat . repeat_context ( ) )
825832 . map_err ( |e| MethodErr :: failed ( & e) ) ?;
826- // TODO: remove, once librespot sends us updates here
827- Ok ( Some ( value) )
833+ local_spirc
834+ . repeat_track ( repeat. repeat_track ( ) )
835+ . map_err ( |e| MethodErr :: failed ( & e) ) ?;
836+
837+ Ok ( None )
828838 } ) ;
829839
830840 let local_state = current_state. clone ( ) ;
0 commit comments