diff --git a/lua/playing.lua b/lua/playing.lua index 942b8836..ff503a6c 100644 --- a/lua/playing.lua +++ b/lua/playing.lua @@ -226,7 +226,18 @@ return screen:new { end end), playback.track:bind(function(track) - if not track then return end + if not track then + if queue.loading:get() then + title:set { text = "Loading..." } + else + title:set { text = "" } + end + artist:set { text = "" } + cur_time:set { text = format_time(0) } + end_time:set { text = format_time(0) } + scrubber:set { value = 0 } + return + end if track.duration then end_time:set { text = format_time(track.duration) } else diff --git a/src/tangara/audio/audio_events.hpp b/src/tangara/audio/audio_events.hpp index 50fd4b00..a141832e 100644 --- a/src/tangara/audio/audio_events.hpp +++ b/src/tangara/audio/audio_events.hpp @@ -103,6 +103,7 @@ struct QueueUpdate : tinyfsm::Event { kRepeatingLastTrack, kTrackFinished, kDeserialised, + kBulkLoadingUpdate, }; Reason reason; }; diff --git a/src/tangara/audio/audio_fsm.cpp b/src/tangara/audio/audio_fsm.cpp index 54ea5b6c..163e56ec 100644 --- a/src/tangara/audio/audio_fsm.cpp +++ b/src/tangara/audio/audio_fsm.cpp @@ -112,10 +112,13 @@ void AudioState::react(const QueueUpdate& ev) { cmd.new_track = std::monostate{}; } break; + case QueueUpdate::kBulkLoadingUpdate: + // Bulk loading updates are informational only; a separate QueueUpdate + // event will be sent when loading is done. case QueueUpdate::kDeserialised: - default: // The current track is deserialised separately in order to retain seek // position. + default: return; } diff --git a/src/tangara/audio/track_queue.cpp b/src/tangara/audio/track_queue.cpp index 761ea09a..4f90e2ea 100644 --- a/src/tangara/audio/track_queue.cpp +++ b/src/tangara/audio/track_queue.cpp @@ -26,6 +26,7 @@ #include "database/track.hpp" #include "events/event_queue.hpp" #include "memory_resource.hpp" +#include "random.hpp" #include "tasks.hpp" #include "track_queue.hpp" #include "ui/ui_fsm.hpp" @@ -190,6 +191,8 @@ auto TrackQueue::append(Item i) -> void { // doesn't block. bg_worker_.Dispatch([=, this]() { database::TrackIterator it = std::get(i); + + size_t next_update_at = 10; while (true) { auto next = *it; if (!next) { @@ -205,7 +208,16 @@ auto TrackQueue::append(Item i) -> void { } } it++; + + // Appending very large iterators can take a while. Send out periodic + // queue updates during them so that the user has an idea what's going + // on. + if (!--next_update_at) { + next_update_at = util::sRandom->RangeInclusive(10, 20); + notifyChanged(false, Reason::kBulkLoadingUpdate); + } } + { const std::unique_lock lock(mutex_); updateShuffler(was_queue_empty); diff --git a/src/tangara/ui/ui_fsm.cpp b/src/tangara/ui/ui_fsm.cpp index 38e9b8e1..7da07215 100644 --- a/src/tangara/ui/ui_fsm.cpp +++ b/src/tangara/ui/ui_fsm.cpp @@ -225,6 +225,7 @@ lua::Property UiState::sQueueRandom{false, [](const lua::LuaValue& val) { sServices->track_queue().random(new_val); return true; }}; +lua::Property UiState::sQueueLoading{false}; lua::Property UiState::sVolumeCurrentPct{ 0, [](const lua::LuaValue& val) { @@ -424,7 +425,7 @@ void UiState::react(const system_fsm::BatteryStateChanged& ev) { } } -void UiState::react(const audio::QueueUpdate&) { +void UiState::react(const audio::QueueUpdate& update) { auto& queue = sServices->track_queue(); auto queue_size = queue.totalSize(); sQueueSize.setDirect(static_cast(queue_size)); @@ -439,6 +440,12 @@ void UiState::react(const audio::QueueUpdate&) { sQueueRandom.setDirect(queue.random()); sQueueRepeat.setDirect(queue.repeat()); sQueueReplay.setDirect(queue.replay()); + + if (update.reason == audio::QueueUpdate::Reason::kBulkLoadingUpdate) { + sQueueLoading.setDirect(true); + } else { + sQueueLoading.setDirect(false); + } } void UiState::react(const audio::PlaybackUpdate& ev) { @@ -614,6 +621,7 @@ void Lua::entry() { {"replay", &sQueueReplay}, {"repeat_track", &sQueueRepeat}, {"random", &sQueueRandom}, + {"loading", &sQueueLoading}, }); registry.AddPropertyModule("volume", { diff --git a/src/tangara/ui/ui_fsm.hpp b/src/tangara/ui/ui_fsm.hpp index 41f0db3a..32966657 100644 --- a/src/tangara/ui/ui_fsm.hpp +++ b/src/tangara/ui/ui_fsm.hpp @@ -122,6 +122,7 @@ class UiState : public tinyfsm::Fsm { static lua::Property sQueueReplay; static lua::Property sQueueRepeat; static lua::Property sQueueRandom; + static lua::Property sQueueLoading; static lua::Property sVolumeCurrentPct; static lua::Property sVolumeCurrentDb;