feat(mobile): queue track reactions made offline and sync on reconnect (M5)
Likes and dislikes without a network are kept in a pending_reactions table (last reaction per track wins) and sent when the connection returns, instead of being rolled back. Downloaded track DTOs pick up the new reaction so the offline wave and Downloads reflect it. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
This commit is contained in:
1 parent
be34ee5361
commit
756e915ff9
5 files changed
+74
-9
No files matched your search
@@ -246,21 +246,21 @@ class Controller {
|
||||
void TrackPlayer.seekTo(ms / 1000);
|
||||
}
|
||||
|
||||
/** Реакция на трек: сразу в UI; без сети запоминается и уходит на сервер при появлении связи. */
|
||||
async react(track: Track, reaction: 'like' | 'dislike' | null) {
|
||||
if (!this.session) return;
|
||||
if (!this.persistent) return;
|
||||
const prev = track.reaction;
|
||||
const apply = (r: Track['reaction']) => {
|
||||
this.update({
|
||||
queue: this.state.queue.map((t) => (t.id === track.id ? { ...t, reaction: r } : t)),
|
||||
track: this.state.track?.id === track.id ? { ...this.state.track, reaction: r } : this.state.track,
|
||||
});
|
||||
void downloads.setReaction(track.id, r);
|
||||
};
|
||||
apply(reaction);
|
||||
this.events?.push({ type: reaction ?? (prev === 'like' ? 'unlike' : 'undislike'), track_id: track.id });
|
||||
try {
|
||||
const params = { params: { path: { id: track.id } } };
|
||||
if (reaction) unwrap(await this.session.client.PUT('/api/v1/me/reactions/tracks/{id}', { ...params, body: { reaction } }));
|
||||
else unwrap(await this.session.client.DELETE('/api/v1/me/reactions/tracks/{id}', params));
|
||||
await this.persistent.react(track.id, reaction);
|
||||
} catch (e) {
|
||||
apply(prev);
|
||||
throw e;
|
||||
|
||||
Reference in new issue
Block a user