-
Notifications
You must be signed in to change notification settings - Fork 290
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Queue history #1068
base: master
Are you sure you want to change the base?
Queue history #1068
Changes from all commits
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -36,6 +36,7 @@ | |
import java.util.Collections; | ||
import java.util.Comparator; | ||
import java.util.Iterator; | ||
import java.util.LinkedList; | ||
import java.util.List; | ||
import java.util.ListIterator; | ||
|
||
|
@@ -220,6 +221,12 @@ public final class SongTimeline { | |
* should be unique, even if it refers to the same media. | ||
*/ | ||
private ArrayList<Song> mSongs = new ArrayList<Song>(12); | ||
/** | ||
* Contains a history of previous queues. | ||
* | ||
* @author Markil 3 | ||
*/ | ||
private LinkedList<ArrayList<Song>> songHistory = new LinkedList<>(); | ||
/** | ||
* The position of the current song (i.e. the playing song). | ||
*/ | ||
|
@@ -725,6 +732,64 @@ else if (delta == SHIFT_PREVIOUS_SONG || delta == SHIFT_NEXT_SONG) { | |
return getSong(0); | ||
} | ||
|
||
/** | ||
* Jumps to a previously-created queue | ||
* @author Markil 3 | ||
* @since 1.0.86 | ||
*/ | ||
public void revertQueue() | ||
{ | ||
ArrayList<Song> timeline = mSongs; | ||
synchronized (this) | ||
{ | ||
if (this.songHistory.size() > 0) | ||
{ | ||
/* | ||
* Saves the queue for later | ||
*/ | ||
if (timeline.size() > 0) | ||
{ | ||
this.songHistory.addFirst(new ArrayList<>(timeline)); | ||
} | ||
timeline.clear(); | ||
timeline.addAll(this.songHistory.removeLast()); | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Probably not fatal, but it would be better if we checked for songs which were deleted in the meantime. See |
||
mCurrentPos = 0; | ||
int start = | ||
mCurrentPos + 1; // Position where our modification started | ||
Song jumpSong = | ||
null; // Jump to this song if `data' requested it | ||
|
||
/* Check if addAtPos is out-of-bounds OR if | ||
* the request does not want to work at the current | ||
* playlist position anyway | ||
*/ | ||
if (start > timeline.size()) | ||
{ | ||
start = timeline.size(); | ||
} | ||
|
||
if (mShuffleMode != SHUFFLE_NONE) | ||
MediaUtils.shuffle(timeline.subList(start, start), | ||
mShuffleMode == SHUFFLE_ALBUMS); | ||
|
||
if (jumpSong != null) | ||
{ | ||
int jumpPos = timeline.lastIndexOf(jumpSong); | ||
if (jumpPos > start) | ||
{ | ||
// Get the sublist twice to avoid a ConcurrentModificationException. | ||
timeline.addAll(timeline.subList(start, jumpPos)); | ||
timeline.subList(start, jumpPos).clear(); | ||
} | ||
} | ||
|
||
broadcastChangedSongs(); | ||
} | ||
} | ||
|
||
changed(); | ||
} | ||
|
||
/** | ||
* Run the given query and add the results to the song timeline. | ||
* | ||
|
@@ -736,6 +801,8 @@ else if (delta == SHIFT_PREVIOUS_SONG || delta == SHIFT_NEXT_SONG) { | |
*/ | ||
public int addSongs(Context context, QueryTask query) | ||
{ | ||
final int MAX_QUEUE_HISTORY = 1; | ||
|
||
Cursor cursor = query.runQuery(context); | ||
if (cursor == null) { | ||
return 0; | ||
|
@@ -793,6 +860,14 @@ public int addSongs(Context context, QueryTask query) | |
case MODE_PLAY: | ||
case MODE_PLAY_POS_FIRST: | ||
case MODE_PLAY_ID_FIRST: | ||
/* | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I think it would be better to generalize this and take a snapshot every time the queue is modified: this would also help in cases where users accidental clear the whole queue. Maybe this could be hooked up into There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. We could. However, as queues get longer, we would get longer and longer snapshots in the memory. The main point of this feature is to undo massive edits. It is relatively easy to change one song. Rebuilding an entire queue is harder. With this, I feel that a little moderation would be needed, especially with memory concerns. |
||
* Saves the queue for later | ||
*/ | ||
this.songHistory.add(new ArrayList<>(timeline)); | ||
if (this.songHistory.size() > MAX_QUEUE_HISTORY) | ||
{ | ||
this.songHistory.removeFirst(); | ||
} | ||
timeline.clear(); | ||
mCurrentPos = 0; | ||
break; | ||
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Just wondering: wouldn't showing a snackbar be better?
At least, the option should be greyed out if there is no queue we can restore.