@@ -65,67 +65,12 @@ String getContextUri() {
6565 return state .getContextUri ();
6666 }
6767
68- @ NotNull
69- private Spirc .PlayStatus getStatus () {
70- return state .getStatus ();
71- }
72-
7368 void setStatus (@ NotNull Spirc .PlayStatus status ) {
7469 state .setStatus (status );
7570 }
7671
7772 boolean isStatus (@ NotNull Spirc .PlayStatus status ) {
78- return status == getStatus ();
79- }
80-
81- void setShuffle (boolean shuffle ) {
82- state .setShuffle (shuffle && (playablesProvider == null || playablesProvider .canShuffle ()));
83- if (state .getShuffle ()) shuffleContent (false );
84- else unshuffleContent ();
85- }
86-
87- private void loadPlayablesProvider (@ NotNull String uri ) throws SpotifyContext .UnsupportedContextException {
88- SpotifyContext context = SpotifyContext .from (uri );
89- playablesProvider = context .initProvider (session , state );
90- }
91-
92- private void shuffleContent (boolean fully ) {
93- if (playablesProvider == null ) return ;
94-
95- if (playablesProvider .canShuffle () && playablesProvider instanceof ShuffleableProvider )
96- ((ShuffleableProvider ) playablesProvider ).shuffleContent (session .random (), fully );
97- else
98- LOGGER .warn ("Cannot shuffle provider: " + playablesProvider );
99- }
100-
101- private void unshuffleContent () {
102- if (playablesProvider == null ) return ;
103-
104- if (playablesProvider .canShuffle () && playablesProvider instanceof ShuffleableProvider )
105- ((ShuffleableProvider ) playablesProvider ).unshuffleContent ();
106- else
107- LOGGER .warn ("Cannot unshuffle provider: " + playablesProvider );
108- }
109-
110- void updated () {
111- session .spirc ().deviceStateUpdated (state );
112- }
113-
114- void seekTo (@ Nullable String uri ) {
115- int pos = -1 ;
116- List <Spirc .TrackRef > tracks = state .getTrackList ();
117- for (int i = 0 ; i < tracks .size (); i ++) {
118- Spirc .TrackRef track = tracks .get (i );
119- if (track .getUri ().equals (uri )) {
120- pos = i ;
121- break ;
122- }
123- }
124-
125- if (pos == -1 )
126- pos = 0 ;
127-
128- state .setPlayingTrackIndex (pos );
73+ return status == state .getStatus ();
12974 }
13075
13176 long getPositionMeasuredAt () {
@@ -144,31 +89,32 @@ void setPositionMs(int pos) {
14489 state .setPositionMs (pos );
14590 }
14691
147- boolean getRepeat () {
148- return state .getRepeat ();
149- }
150-
15192 void setRepeat (boolean repeat ) {
15293 state .setRepeat (repeat && (playablesProvider == null || playablesProvider .canRepeat ()));
15394 }
15495
155- void setPlayingTrackIndex (int i ) {
156- state .setPlayingTrackIndex (i );
96+ void setShuffle (boolean shuffle ) {
97+ state .setShuffle (shuffle && (playablesProvider == null || playablesProvider .canShuffle ()));
98+ if (state .getShuffle ()) shuffleContent (false );
99+ else unshuffleContent ();
157100 }
158101
159- int getTrackCount () {
160- return state .getTrackCount ();
161- }
102+ private void shuffleContent (boolean fully ) {
103+ if (playablesProvider == null ) return ;
162104
163- void loadStation (@ NotNull MercuryRequests .StationsWrapper station ) throws SpotifyContext .UnsupportedContextException {
164- state .setContextUri (station .uri ());
105+ if (playablesProvider .canShuffle () && playablesProvider instanceof ShuffleableProvider )
106+ ((ShuffleableProvider ) playablesProvider ).shuffleContent (session .random (), fully );
107+ else
108+ LOGGER .warn ("Cannot shuffle provider: " + playablesProvider );
109+ }
165110
166- state .clearTrack ();
167- state .addAllTrack (station .tracks ());
168- state .setPlayingTrackIndex (0 );
169- SpotifyIrc .trimTracks (state );
111+ private void unshuffleContent () {
112+ if (playablesProvider == null ) return ;
170113
171- loadPlayablesProvider (station .uri ());
114+ if (playablesProvider .canShuffle () && playablesProvider instanceof ShuffleableProvider )
115+ ((ShuffleableProvider ) playablesProvider ).unshuffleContent ();
116+ else
117+ LOGGER .warn ("Cannot unshuffle provider: " + playablesProvider );
172118 }
173119
174120 private int lastQueuedSongIndex () {
@@ -185,6 +131,13 @@ private int lastQueuedSongIndex() {
185131 return lastQueued ;
186132 }
187133
134+ private void loadPlayablesProvider (@ NotNull String uri ) throws SpotifyContext .UnsupportedContextException {
135+ if (state .getTrackCount () == 0 ) throw SpotifyContext .UnsupportedContextException .empty ();
136+
137+ SpotifyContext context = SpotifyContext .from (uri );
138+ playablesProvider = context .initProvider (session , state );
139+ }
140+
188141 @ NotNull
189142 private List <Remote3Page > getPages (@ NotNull Remote3Frame .Context context ) throws IOException , MercuryClient .MercuryException {
190143 MercuryRequests .ResolvedContextWrapper resolved = session .mercury ().sendSync (MercuryRequests .resolveContext (context .uri ));
@@ -200,15 +153,6 @@ private List<Remote3Track> getTracks(@NotNull String pageUrl) throws IOException
200153 return Remote3Track .array (obj .getAsJsonArray ("tracks" ));
201154 }
202155
203- void loadFromUri (@ NotNull String context ) throws IOException , MercuryClient .MercuryException , SpotifyContext .UnsupportedContextException {
204- state .setContextUri (context );
205- state .clearTrack ();
206-
207- MercuryRequests .ResolvedContextWrapper resolved = session .mercury ().sendSync (MercuryRequests .resolveContext (context ));
208- loadPage (resolved .pages ().get (0 ), null );
209- loadPlayablesProvider (context );
210- }
211-
212156 private void loadPage (@ NotNull Remote3Page page , @ Nullable TrackSelector selector ) throws IOException {
213157 List <Remote3Track > tracks = page .tracks ;
214158 if (tracks == null ) {
@@ -231,6 +175,47 @@ private void loadPage(@NotNull Remote3Page page, @Nullable TrackSelector selecto
231175 if (state .getShuffle ()) shuffleContent (selector == null || !selector .findMatch ());
232176 }
233177
178+ void updated () {
179+ session .spirc ().deviceStateUpdated (state );
180+ }
181+
182+ void seekTo (@ Nullable String uri ) {
183+ int pos = -1 ;
184+ List <Spirc .TrackRef > tracks = state .getTrackList ();
185+ for (int i = 0 ; i < tracks .size (); i ++) {
186+ Spirc .TrackRef track = tracks .get (i );
187+ if (track .getUri ().equals (uri )) {
188+ pos = i ;
189+ break ;
190+ }
191+ }
192+
193+ if (pos == -1 )
194+ pos = 0 ;
195+
196+ state .setPlayingTrackIndex (pos );
197+ }
198+
199+ void loadStation (@ NotNull MercuryRequests .StationsWrapper station ) throws SpotifyContext .UnsupportedContextException {
200+ state .setContextUri (station .uri ());
201+
202+ state .clearTrack ();
203+ state .addAllTrack (station .tracks ());
204+ state .setPlayingTrackIndex (0 );
205+ SpotifyIrc .trimTracks (state );
206+
207+ loadPlayablesProvider (station .uri ());
208+ }
209+
210+ void loadFromUri (@ NotNull String context ) throws IOException , MercuryClient .MercuryException , SpotifyContext .UnsupportedContextException {
211+ state .setContextUri (context );
212+ state .clearTrack ();
213+
214+ MercuryRequests .ResolvedContextWrapper resolved = session .mercury ().sendSync (MercuryRequests .resolveContext (context ));
215+ loadPage (resolved .pages ().get (0 ), null );
216+ loadPlayablesProvider (context );
217+ }
218+
234219 void load (@ NotNull Remote3Frame frame ) throws IOException , MercuryClient .MercuryException , SpotifyContext .UnsupportedContextException {
235220 if (frame .context == null ) throw new IllegalArgumentException ("Missing context object!" );
236221
@@ -348,22 +333,65 @@ boolean hasProvider() {
348333 return playablesProvider != null ;
349334 }
350335
351- int getPrevTrackIndex () {
352- return playablesProvider .getPrevTrackIndex ();
336+ @ NotNull
337+ PlayableId getCurrentTrack () {
338+ return playablesProvider .getCurrentTrack ();
353339 }
354340
355- int getNextTrackIndex (boolean consume ) {
356- return playablesProvider .getNextTrackIndex (consume );
341+ @ NotNull
342+ StateWrapper .NextPlayable nextPlayable (@ NotNull Player .Configuration conf ) {
343+ if (playablesProvider == null ) return NextPlayable .MISSING_PROVIDER ;
344+
345+ int newTrack = playablesProvider .getNextTrackIndex (true );
346+ boolean play = true ;
347+ if (newTrack >= state .getTrackCount ()) {
348+ if (state .getRepeat ()) {
349+ newTrack = 0 ;
350+ play = true ;
351+ } else {
352+ if (conf .autoplayEnabled ()) {
353+ return NextPlayable .AUTOPLAY ;
354+ } else {
355+ newTrack = 0 ;
356+ play = false ;
357+ }
358+ }
359+ }
360+
361+ state .setPlayingTrackIndex (newTrack );
362+ if (play ) return NextPlayable .OK_PLAY ;
363+ else return NextPlayable .OK_PAUSE ;
357364 }
358365
359- @ NotNull
360- PlayableId getTrackAt (int index ) {
361- return playablesProvider .getTrackAt (index );
366+ @ Nullable
367+ PlayableId nextPlayableDoNotSet () {
368+ int next = playablesProvider .getNextTrackIndex (true );
369+ if (next >= state .getTrackCount ()) return null ;
370+ else return playablesProvider .getTrackAt (next );
362371 }
363372
364373 @ NotNull
365- PlayableId getCurrentTrack () {
366- return playablesProvider .getCurrentTrack ();
374+ PreviousPlayable previousPlayable () {
375+ if (playablesProvider == null ) return PreviousPlayable .MISSING_PROVIDER ;
376+ state .setPlayingTrackIndex (playablesProvider .getPrevTrackIndex ());
377+ return PreviousPlayable .OK ;
378+ }
379+
380+ public enum PreviousPlayable {
381+ MISSING_PROVIDER , OK ;
382+
383+ public boolean isOk () {
384+ return this == OK ;
385+ }
386+ }
387+
388+ public enum NextPlayable {
389+ MISSING_PROVIDER , AUTOPLAY ,
390+ OK_PLAY , OK_PAUSE ;
391+
392+ public boolean isOk () {
393+ return this == OK_PLAY || this == OK_PAUSE ;
394+ }
367395 }
368396
369397 private static class TrackSelector {
0 commit comments