summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--src/tangara/audio/audio_fsm.cpp19
-rw-r--r--src/tangara/audio/audio_fsm.hpp5
-rw-r--r--src/tangara/database/records.cpp5
-rw-r--r--src/tangara/database/track.cpp1
-rw-r--r--src/tangara/database/track.hpp5
-rw-r--r--src/tangara/lua/lua_database.cpp4
6 files changed, 35 insertions, 4 deletions
diff --git a/src/tangara/audio/audio_fsm.cpp b/src/tangara/audio/audio_fsm.cpp
index f9823fb3..c6ac75f0 100644
--- a/src/tangara/audio/audio_fsm.cpp
+++ b/src/tangara/audio/audio_fsm.cpp
@@ -91,7 +91,8 @@ auto AudioState::emitPlaybackUpdate(bool paused) -> void {
}
// If we've got an elapsed duration and it's more than 5 minutes
- // increment a counter. Every 60 counts (ie, every minute) save the current elapsed position
+ // increment a counter. Every 60 counts (ie, every minute) save the current
+ // elapsed position
if (position && *position > (5 * 60)) {
sUpdateCounter++;
if (sUpdateCounter >= 60) {
@@ -232,6 +233,7 @@ void AudioState::react(const internal::DecodingFinished& ev) {
}
if (path == ev.track->uri) {
queue.finish();
+ incrementPlayCount(ev.track->uri);
}
});
}
@@ -399,7 +401,8 @@ void AudioState::react(const OutputModeChanged& ev) {
}
}
-auto AudioState::updateSavedPosition(std::string uri, uint32_t position)
+auto AudioState::updateTrackData(std::string uri,
+ std::function<void(database::TrackData&)> fn)
-> void {
sServices->bg_worker().Dispatch<void>([=]() {
auto db = sServices->database().lock();
@@ -415,11 +418,21 @@ auto AudioState::updateSavedPosition(std::string uri, uint32_t position)
return;
}
auto data = track->data().clone();
- data->last_position = position;
+ std::invoke(fn, *data);
db->setTrackData(*id, *data);
});
}
+auto AudioState::updateSavedPosition(std::string uri, uint32_t position)
+ -> void {
+ updateTrackData(
+ uri, [&](database::TrackData& data) { data.last_position = position; });
+}
+
+auto AudioState::incrementPlayCount(std::string uri) -> void {
+ updateTrackData(uri, [&](database::TrackData& data) { data.play_count++; });
+}
+
auto AudioState::updateOutputMode() -> void {
if (is_in_state<states::Playback>() || sIsTtsPlaying) {
sOutput->mode(IAudioOutput::Modes::kOnPlaying);
diff --git a/src/tangara/audio/audio_fsm.hpp b/src/tangara/audio/audio_fsm.hpp
index c765b417..fb42e387 100644
--- a/src/tangara/audio/audio_fsm.hpp
+++ b/src/tangara/audio/audio_fsm.hpp
@@ -76,6 +76,7 @@ class AudioState : public tinyfsm::Fsm<AudioState> {
auto commitVolume() -> void;
auto updateSavedPosition(std::string uri, uint32_t position) -> void;
+ auto incrementPlayCount(std::string uri) -> void;
static std::shared_ptr<system_fsm::ServiceLocator> sServices;
@@ -94,6 +95,10 @@ class AudioState : public tinyfsm::Fsm<AudioState> {
static bool sIsPaused;
static uint8_t sUpdateCounter;
static bool sIsTtsPlaying;
+
+ private:
+ auto updateTrackData(std::string uri,
+ std::function<void(database::TrackData&)>) -> void;
};
namespace states {
diff --git a/src/tangara/database/records.cpp b/src/tangara/database/records.cpp
index b93ed149..addcc13d 100644
--- a/src/tangara/database/records.cpp
+++ b/src/tangara/database/records.cpp
@@ -95,6 +95,7 @@ auto EncodeDataValue(const TrackData& track) -> std::string {
tag_hashes,
cppbor::Uint{track.last_position},
cppbor::Uint{static_cast<unsigned int>(track.type)},
+ cppbor::Uint{track.play_count},
};
return val.toString();
}
@@ -147,6 +148,10 @@ auto ParseDataValue(const leveldb::Slice& slice) -> std::shared_ptr<TrackData> {
}
}
+ if (vals->size() >= 10 && vals->get(9)->type() == cppbor::UINT) {
+ res->play_count = vals->get(9)->asUint()->unsignedValue();
+ }
+
return res;
}
diff --git a/src/tangara/database/track.cpp b/src/tangara/database/track.cpp
index 51d50a38..49babb6a 100644
--- a/src/tangara/database/track.cpp
+++ b/src/tangara/database/track.cpp
@@ -302,6 +302,7 @@ auto database::TrackData::clone() const -> std::shared_ptr<TrackData> {
data->is_tombstoned = is_tombstoned;
data->modified_at = modified_at;
data->last_position = last_position;
+ data->play_count = play_count;
data->type = type;
return data;
}
diff --git a/src/tangara/database/track.hpp b/src/tangara/database/track.hpp
index 71f40910..65c5cfec 100644
--- a/src/tangara/database/track.hpp
+++ b/src/tangara/database/track.hpp
@@ -177,7 +177,9 @@ struct TrackData {
individual_tag_hashes(&memory::kSpiRamResource),
is_tombstoned(false),
modified_at(),
- last_position(0) {}
+ last_position(0),
+ play_count(0),
+ type(MediaType::kUnknown) {}
TrackId id;
std::pmr::string filepath;
@@ -186,6 +188,7 @@ struct TrackData {
bool is_tombstoned;
std::pair<uint16_t, uint16_t> modified_at;
uint32_t last_position;
+ uint32_t play_count;
MediaType type;
TrackData(const TrackData&& other) = delete;
diff --git a/src/tangara/lua/lua_database.cpp b/src/tangara/lua/lua_database.cpp
index 2e00f427..39179bf3 100644
--- a/src/tangara/lua/lua_database.cpp
+++ b/src/tangara/lua/lua_database.cpp
@@ -121,6 +121,10 @@ static void pushTrack(lua_State* L, const database::Track& track) {
lua_pushliteral(L, "saved_position");
lua_pushinteger(L, track.data().last_position);
lua_settable(L, -3);
+
+ lua_pushliteral(L, "play_count");
+ lua_pushinteger(L, track.data().play_count);
+ lua_settable(L, -3);
}
static auto version(lua_State* L) -> int {