Implement shuffle radio feature (#145)

master
François-Xavier Thomas 8 years ago
parent a2deb0b779
commit 6d8df63a7e
No known key found for this signature in database
GPG Key ID: 64337406D2DD45CE
  1. 10
      libresonic-main/src/main/java/org/libresonic/player/ajax/PlayQueueInfo.java
  2. 24
      libresonic-main/src/main/java/org/libresonic/player/ajax/PlayQueueService.java
  3. 2
      libresonic-main/src/main/java/org/libresonic/player/controller/RandomPlayQueueController.java
  4. 11
      libresonic-main/src/main/java/org/libresonic/player/domain/PlayQueue.java
  5. 4
      libresonic-main/src/main/resources/org/libresonic/player/i18n/ResourceBundle_en.properties
  6. 15
      libresonic-main/src/main/webapp/WEB-INF/jsp/more.jsp
  7. 19
      libresonic-main/src/main/webapp/WEB-INF/jsp/playQueue.jsp

@ -33,15 +33,17 @@ public class PlayQueueInfo {
private final List<Entry> entries;
private final boolean stopEnabled;
private final boolean repeatEnabled;
private final boolean radioEnabled;
private final boolean sendM3U;
private final float gain;
private int startPlayerAt = -1;
private long startPlayerAtPosition; // millis
public PlayQueueInfo(List<Entry> entries, boolean stopEnabled, boolean repeatEnabled, boolean sendM3U, float gain) {
public PlayQueueInfo(List<Entry> entries, boolean stopEnabled, boolean repeatEnabled, boolean radioEnabled, boolean sendM3U, float gain) {
this.entries = entries;
this.stopEnabled = stopEnabled;
this.repeatEnabled = repeatEnabled;
this.radioEnabled = radioEnabled;
this.sendM3U = sendM3U;
this.gain = gain;
}
@ -72,6 +74,10 @@ public class PlayQueueInfo {
return repeatEnabled;
}
public boolean isRadioEnabled() {
return radioEnabled;
}
public float getGain() {
return gain;
}
@ -215,4 +221,4 @@ public class PlayQueueInfo {
return remoteCoverArtUrl;
}
}
}
}

@ -148,6 +148,18 @@ public class PlayQueueService {
return convert(request, player, serverSidePlaylist, offset);
}
public PlayQueueInfo reloadSearchCriteria() throws Exception {
HttpServletRequest request = WebContextFactory.get().getHttpServletRequest();
HttpServletResponse response = WebContextFactory.get().getHttpServletResponse();
String username = securityService.getCurrentUsername(request);
Player player = getCurrentPlayer(request, response);
PlayQueue playQueue = player.getPlayQueue();
if (playQueue.getRandomSearchCriteria() != null) {
playQueue.addFiles(true, mediaFileService.getRandomSongs(playQueue.getRandomSearchCriteria(), username));
}
return convert(request, player, false);
}
public void savePlayQueue(int currentSongIndex, long positionMillis) {
HttpServletRequest request = WebContextFactory.get().getHttpServletRequest();
HttpServletResponse response = WebContextFactory.get().getHttpServletResponse();
@ -581,7 +593,13 @@ public class PlayQueueService {
HttpServletRequest request = WebContextFactory.get().getHttpServletRequest();
HttpServletResponse response = WebContextFactory.get().getHttpServletResponse();
Player player = getCurrentPlayer(request, response);
player.getPlayQueue().setRepeatEnabled(!player.getPlayQueue().isRepeatEnabled());
PlayQueue playQueue = player.getPlayQueue();
if (playQueue.isRadioEnabled()) {
playQueue.setRandomSearchCriteria(null);
playQueue.setRepeatEnabled(false);
} else {
playQueue.setRepeatEnabled(!player.getPlayQueue().isRepeatEnabled());
}
return convert(request, player, false);
}
@ -668,7 +686,7 @@ public class PlayQueueService {
}
boolean isStopEnabled = playQueue.getStatus() == PlayQueue.Status.PLAYING && !player.isExternalWithPlaylist();
float gain = jukeboxService.getGain();
return new PlayQueueInfo(entries, isStopEnabled, playQueue.isRepeatEnabled(), serverSidePlaylist, gain);
return new PlayQueueInfo(entries, isStopEnabled, playQueue.isRepeatEnabled(), playQueue.isRadioEnabled(), serverSidePlaylist, gain);
}
private String formatFileSize(Long fileSize, Locale locale) {
@ -751,4 +769,4 @@ public class PlayQueueService {
public void setPlaylistService(PlaylistService playlistService) {
this.playlistService = playlistService;
}
}
}

@ -199,7 +199,7 @@ public class RandomPlayQueueController extends ParameterizableViewController {
List<MusicFolder> musicFolders = getMusicFolders(request);
// Do we add to the current playlist or do we replace it?
boolean shouldAddToPlayList = ServletRequestUtils.getBooleanParameter(request, "addToPlaylist", false);
boolean shouldAddToPlayList = request.getParameter("addToPlaylist") != null;
// Search the database using these criteria
RandomSearchCriteria criteria = new RandomSearchCriteria(

@ -368,6 +368,15 @@ public class PlayQueue {
this.repeatEnabled = repeatEnabled;
}
/**
* Returns whether the playlist is a shuffle radio
*
* @return Whether the playlist is a shuffle radio.
*/
public synchronized boolean isRadioEnabled() {
return this.randomSearchCriteria != null;
}
/**
* Revert the last operation.
*/
@ -455,4 +464,4 @@ public class PlayQueue {
ARTIST,
ALBUM
}
}
}

@ -100,6 +100,7 @@ playlist.clear = Clear
playlist.shuffle = Shuffle
playlist.repeat_on = Repeat is on
playlist.repeat_off = Repeat is off
playlist.repeat_radio = Stop shuffle radio
playlist.undo = Undo
playlist.settings = Settings
playlist.more = More actions...
@ -233,7 +234,8 @@ more.random.text = Shuffle play
more.random.songs = {0} songs
more.random.auto = Play more random songs when end of play queue is reached.
more.random.ok = OK
more.random.addtoplaylist = Add to current playlist
more.random.add = Add to queue
more.random.radio = Shuffle radio
more.random.any = Any
more.random.format = Format
more.random.genre = Genre

@ -232,24 +232,13 @@
<option value="mp3">MP3</option>
</select>
</td>
<td><fmt:message key="more.random.addtoplaylist"/></td>
<td>
<input name="addToPlaylist" value="true" type="checkbox"/>
</td>
</tr>
<tr>
<td colspan="2">
<input type="submit" value="<fmt:message key="more.random.ok"/>">
<input type="submit" name="addToPlaylist" value="<fmt:message key="more.random.add"/>">
<input type="submit" name="autoRandom" value="<fmt:message key="more.random.radio"/>">
</td>
</tr>
<c:if test="${not model.clientSidePlaylist}">
<tr>
<td colspan="9">
<input type="checkbox" name="autoRandom" id="autoRandom" class="checkbox"/>
<label for="autoRandom"><fmt:message key="more.random.auto"/></label>
</td>
</tr>
</c:if>
</table>
</form>
</c:if>

@ -37,6 +37,7 @@
var songs = null;
var currentStreamUrl = null;
var repeatEnabled = false;
var radioEnabled = false;
var isVisible = ${model.autoHide ? 'false' : 'true'};
var CastPlayer = new CastPlayer();
var ignore = false;
@ -269,7 +270,13 @@
}
function onNext(wrap) {
var index = parseInt(getCurrentSongIndex()) + 1;
if (wrap) {
if (radioEnabled && index >= songs.length) {
playQueueService.reloadSearchCriteria(function(playQueue) {
playQueueCallback(playQueue);
onSkip(index);
});
return;
} else if (wrap) {
index = index % songs.length;
}
onSkip(index);
@ -402,14 +409,20 @@
function playQueueCallback(playQueue) {
songs = playQueue.entries;
repeatEnabled = playQueue.repeatEnabled;
radioEnabled = playQueue.radioEnabled;
if ($("#start")) {
$("#start").toggle(!playQueue.stopEnabled);
$("#stop").toggle(playQueue.stopEnabled);
}
if ($("#toggleRepeat")) {
var text = repeatEnabled ? "<fmt:message key="playlist.repeat_on"/>" : "<fmt:message key="playlist.repeat_off"/>";
$("#toggleRepeat").html(text);
if (radioEnabled) {
$("#toggleRepeat").html("<fmt:message key="playlist.repeat_radio"/>");
} else if (repeatEnabled) {
$("#toggleRepeat").html("<fmt:message key="playlist.repeat_on"/>");
} else {
$("#toggleRepeat").html("<fmt:message key="playlist.repeat_off"/>");
}
}
if (songs.length == 0) {

Loading…
Cancel
Save