Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
49 changes: 42 additions & 7 deletions data/com.github.alainm23.byte.gschema.xml
Original file line number Diff line number Diff line change
Expand Up @@ -40,15 +40,26 @@
<value nick="Files" value="1" />
</enum>

<schema path="/com/github/alainm23/byte/" id="com.github.alainm23.byte" gettext-domain="com.github.alainm23.byte">
<enum id="com.github.alainm23.byte.queue-type">
<value nick="None" value="0" />
<value nick="RecentlyAdded" value="1" />
<value nick="Songs" value="2" />
<value nick="Playlist" value="3" />
<value nick="Album" value="4" />
<value nick="Artist" value="5" />
<value nick="Favorites" value="6" />
<value nick="Radio" value="7" />
</enum>

<schema path="/com/github/alainm23/byte/" id="com.github.alainm23.byte" gettext-domain="com.github.alainm23.byte">
<key name="theme" enum="com.github.alainm23.byte.theme">
<default>"Byte"</default>
<summary>Theme</summary>
<description>Theme</description>
</key>
<default>"Byte"</default>
<summary>Theme</summary>
<description>Theme</description>
</key>

<key name="library-location" type="s">
<default>""</default>
<default>""</default>
<summary>Default library location.</summary>
<description>Default library location.</description>
</key>
Expand Down Expand Up @@ -101,11 +112,35 @@
<description>Album order reverse</description>
</key>

<key name="shuffle-mode" type="b">
<key name="shuffle-mode" type="b">
<default>false</default>
<summary>Shuffle mode</summary>
<description>Shuffle mode</description>
</key>

<key name="last-played" type="i">
<default>0</default>
<summary>Last track played</summary>
<description>ID of the last track that was played, to restore it after restart</description>
</key>

<key name="track-progression" type="d">
<default>0.0</default>
<summary>Play progression</summary>
<description>Progression of the last track that was played, to restore it after restart</description>
</key>

<key name="queue-type" enum="com.github.alainm23.byte.queue-type">
<default>"None"</default>
<summary>Queue Type</summary>
<description>Type of queue that was used, to restore it after restart</description>
</key>

<key name="queue-id" type="i">
<default>0</default>
<summary>Queue Type</summary>
<description>Type of queue that was used, to restore it after restart</description>
</key>

<key name="window-position" type="(ii)">
<default>(-1, -1)</default>
Expand Down
63 changes: 63 additions & 0 deletions src/MainWindow.vala
Original file line number Diff line number Diff line change
Expand Up @@ -86,6 +86,8 @@ public class MainWindow : Gtk.Window {
main_stack.visible_child_name = "welcome_view";
headerbar.visible_ui = false;
} else {
restore_playing_state ();

main_stack.visible_child_name = "library_view";

Byte.navCtrl.go_root ();
Expand Down Expand Up @@ -198,4 +200,65 @@ public class MainWindow : Gtk.Window {

return base.configure_event (event);
}

/**
* Restore last playing state
*/
private void restore_playing_state () {
int queue_type_id = Byte.settings.get_enum ("queue-type");
int queue_id = Byte.settings.get_int ("queue-id");
int last_played_id = Byte.settings.get_int ("last-played");
double track_progression = Byte.settings.get_double ("track-progression");

print ("restoring: %d, %d, %d, %f\n", queue_type_id, queue_id, last_played_id, track_progression);

switch (queue_type_id) {
case 1: // RecentlyAdded
print ("Restore playing recently added\n");
Byte.utils.play_queue_start_with_track_by_id (home_view.all_tracks, 1, last_played_id, track_progression);
break;
case 2: // Songs
print ("Restore playing all songs\n");
var tracks_view = new Views.Tracks ();
Byte.utils.play_queue_start_with_track_by_id (tracks_view.all_tracks, 2, last_played_id, track_progression);
break;
case 3: // Playlist
Objects.Playlist playlist = Byte.database.get_playlist_by_id (queue_id);
print ("Restoring last played playlist: %s\n", playlist.title);
var playlist_view = new Views.Playlist (playlist);
Byte.utils.play_queue_start_with_track_by_id (playlist_view.all_tracks, 3, last_played_id,
track_progression, queue_id);
break;
case 4: // Album
Objects.Album album = Byte.database.get_album_by_id (queue_id);
print ("Restoring last played album: %s\n", album.title);
var album_view = new Views.Album (album);
Byte.utils.play_queue_start_with_track_by_id (album_view.all_tracks, 4, last_played_id,
track_progression, queue_id);
break;
case 5: // Artist
Objects.Artist artist = Byte.database.get_artist_by_id (queue_id);
print ("Restoring last played artist: %s\n", artist.name);
var artist_view = new Views.Artist (artist);
Byte.utils.play_queue_start_with_track_by_id (artist_view.all_tracks, 5, last_played_id,
track_progression, queue_id);
break;
case 6: // Favorites
print ("Restore playing favorites\n");
var favorites_view = new Views.Favorites ();
Byte.utils.play_queue_start_with_track_by_id (favorites_view.all_tracks, 6, last_played_id, track_progression);
break;
// case 7: // Radio
// break;
default: // None
if (last_played_id != 0) {
Objects.Track? last_played_track = Byte.database.get_track_by_id (last_played_id);
if (last_played_track != null) {
print ("Restoring last played track: %s at %f%\n", last_played_track.title, track_progression);
Byte.player.set_track (last_played_track, track_progression);
}
}
break;
}
}
}
37 changes: 26 additions & 11 deletions src/Services/Database.vala
Original file line number Diff line number Diff line change
Expand Up @@ -488,14 +488,15 @@ public class Services.Database : GLib.Object {
Sqlite.Statement stmt;
int res;

string sql = """
SELECT tracks.id, tracks.path, tracks.title, tracks.duration, tracks.is_favorite, tracks.track, tracks.date_added,
tracks.play_count, tracks.album_id, albums.title, artists.id, artists.name, tracks.favorite_added, tracks.last_played FROM tracks
INNER JOIN albums ON tracks.album_id = albums.id
INNER JOIN artists ON albums.artist_id = artists.id WHERE id = ?;
string sql_track = """
SELECT tracks.id, tracks.path, tracks.title, tracks.duration, tracks.is_favorite, tracks.track,
tracks.date_added, tracks.play_count, tracks.favorite_added, tracks.last_played,
tracks.album_id, tracks.album_artist
FROM tracks
WHERE id = ?
""";

res = db.prepare_v2 (sql, -1, out stmt);
res = db.prepare_v2 (sql_track, -1, out stmt);
assert (res == Sqlite.OK);

res = stmt.bind_int (1, id);
Expand All @@ -512,12 +513,26 @@ public class Services.Database : GLib.Object {
track.track = stmt.column_int (5);
track.date_added = stmt.column_text (6);
track.play_count = stmt.column_int (7);
track.album_id = stmt.column_int (8);
track.album_title = stmt.column_text (9);
track.artist_id = stmt.column_int (10);
track.favorite_added = stmt.column_text (8);
track.last_played = stmt.column_text (9);
track.album_id = stmt.column_int (10);
// Artist name is retrieved from the Track, not the Artist of the Album
track.artist_name = stmt.column_text (11);
track.favorite_added = stmt.column_text (12);
track.last_played = stmt.column_text (13);

if (track.album_id != 0) {
string sql_album = "SELECT albums.title, albums.artist_id FROM albums WHERE id = ?";

res = db.prepare_v2 (sql_album, -1, out stmt);
assert (res == Sqlite.OK);

res = stmt.bind_int (1, track.album_id);
assert (res == Sqlite.OK);

if (stmt.step () == Sqlite.ROW) {
track.album_title = stmt.column_text (0);
track.artist_id = stmt.column_int (1);
}
}
}

return track;
Expand Down
23 changes: 17 additions & 6 deletions src/Services/Player.vala
Original file line number Diff line number Diff line change
Expand Up @@ -120,26 +120,37 @@ public class Services.Player : GLib.Object {
play ();
}

public void set_track (Objects.Track? track) {
public void set_track (Objects.Track? track, double progress = 0) {
if (track == null) {
current_duration_changed (0);
}

if (load_track (track)) {
if (load_track (track, progress)) {
current_track_changed (track);
mode_changed ("track");
mode = "track";

play ();
} else {
next ();
}
}

public bool load_track (Objects.Track? track, double progress = 0) {
public bool load_track (Objects.Track? track, double progress) {
if (track == current_track || track == null) {
return false;
}
print ("loading track: %s\n", track.title);

current_track = track;

// Skip current track if the file is not found
// TODO ajouter une notification d'avertissement
File song_file = File.new_for_uri (track.path);
if (!song_file.query_exists ()) {
print ("File not found: %s\n", track.path);
return false;
}

var last_state = get_state ();
stop ();
Expand All @@ -149,15 +160,15 @@ public class Services.Player : GLib.Object {
state_changed (Gst.State.PLAYING);
player_state = Gst.State.PLAYING;

while (duration == 0) {};
while (duration == 0 || duration == -1) {};

if (last_state != Gst.State.PLAYING) {
pause ();
}

current_duration_changed (duration);

if (progress > 0) {
if (progress > 0.0) {
seek_to_progress (progress);
current_progress_changed (progress);
}
Expand Down Expand Up @@ -199,7 +210,7 @@ public class Services.Player : GLib.Object {
public void stop_progress_signal (bool reset_timer = false) {
pause_progress_signal ();
if (reset_timer) {
current_progress_changed (0);
current_progress_changed (0.0);
}
}

Expand Down
1 change: 1 addition & 0 deletions src/Services/TagManager.vala
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,7 @@ public class Services.TagManager : GLib.Object {

if (info.get_result () != Gst.PbUtils.DiscovererResult.OK) {
if (err != null) {
// Printing err.message often triggers Segmentation fault for some reason
warning ("DISCOVER ERROR: '%d' %s %s\n(%s)", err.code, err.message, info.get_result ().to_string (), uri);
}
} else {
Expand Down
55 changes: 51 additions & 4 deletions src/Utils.vala
Original file line number Diff line number Diff line change
@@ -1,7 +1,8 @@
public class Utils : GLib.Object {
public Gee.ArrayList<Objects.Track?> queue_playlist { set; get; }

public signal void play_items (Gee.ArrayList<Objects.Track?> items, Objects.Track? track);
public signal void play_items (Gee.ArrayList<Objects.Track?> items, Objects.Track? track, int queue_type,
int queue_id, double progress);

public signal void update_next_track ();
public signal void add_next_track (Gee.ArrayList<Objects.Track?> items);
Expand All @@ -27,7 +28,9 @@ public class Utils : GLib.Object {
COVER_FOLDER = GLib.Path.build_filename (MAIN_FOLDER, "covers");
}

public void set_items (Gee.ArrayList<Objects.Track?> all_items, bool shuffle_mode, Objects.Track? track) {
public void set_items (Gee.ArrayList<Objects.Track?> all_items, bool shuffle_mode, Objects.Track? track,
int queue_type = 0, double progress = 0, int queue_id = 0
) {
if (all_items.size > 0) {
if (shuffle_mode) {
queue_playlist = generate_shuffle (all_items);
Expand All @@ -44,7 +47,7 @@ public class Utils : GLib.Object {
Byte.settings.set_boolean ("shuffle-mode", false);
}

play_items (queue_playlist, track);
play_items (queue_playlist, track, queue_type, queue_id, progress);
}
}

Expand All @@ -62,7 +65,7 @@ public class Utils : GLib.Object {
queue_playlist = playlist_order (queue_playlist);
}

play_items (queue_playlist, Byte.player.current_track);
play_items (queue_playlist, Byte.player.current_track, -1, -1, 0.0);
update_next_track ();
}
}
Expand Down Expand Up @@ -371,4 +374,48 @@ public class Utils : GLib.Object {
return;
}
}

public void play_queue_start_with_track_by_id (Gee.ArrayList<Objects.Track?> tracks, int queue_type,
int track_id, double progress, int queue_id = 0
) {
Objects.Track? track = find_track (tracks, track_id);

if (track == null) play_queue (tracks, queue_type, Byte.settings.get_boolean ("shuffle-mode"));
else play_queue_start_with_track (tracks, queue_type, track, progress, queue_id);
}

public void play_queue_start_with_track (Gee.ArrayList<Objects.Track?> tracks, int queue_type, Objects.Track track,
double progress = 0, int queue_id = 0
) {
set_items (
tracks,
Byte.settings.get_boolean ("shuffle-mode"),
track,
queue_type,
progress,
queue_id
);
}

public void play_queue (Gee.ArrayList<Objects.Track?> tracks, int queue_type, bool shuffled, int queue_id = 0) {
set_items (
tracks,
shuffled,
null,
queue_type,
0,
queue_id
);
}

private Objects.Track? find_track (Gee.ArrayList<Objects.Track?> tracks, int track_id) {
var it = tracks.iterator ();
for (var has_next = it.next (); has_next; has_next = it.next ()) {
if (it.get () != null && it.get ().id == track_id) {
return it.get ();
}
}

return null;
}
}
Loading