feat(flutter/likes): LikeButton with optimistic toggle + rollback
LikedIdsController loads /api/likes/ids once and mutates the local set on toggle. Failed mutations roll the set back so the icon never lies. Wired into ArtistDetail header, AlbumDetail header, and per-track in the album track list.
This commit is contained in:
@@ -1,6 +1,8 @@
|
||||
import 'package:flutter/material.dart';
|
||||
import 'package:flutter_riverpod/flutter_riverpod.dart';
|
||||
|
||||
import '../api/endpoints/likes.dart';
|
||||
import '../likes/like_button.dart';
|
||||
import '../theme/theme_extension.dart';
|
||||
import 'library_providers.dart';
|
||||
import 'widgets/track_row.dart';
|
||||
@@ -43,11 +45,15 @@ class AlbumDetailScreen extends ConsumerWidget {
|
||||
onPressed: () { /* play wired in Task 18 */ },
|
||||
),
|
||||
),
|
||||
// LikeButton goes here in Task 16.
|
||||
LikeButton(kind: LikeKind.album, id: r.album.id, size: 28),
|
||||
]),
|
||||
),
|
||||
for (final t in r.tracks)
|
||||
TrackRow(track: t, onTap: () { /* play wired in Task 18 */ }),
|
||||
TrackRow(
|
||||
track: t,
|
||||
onTap: () { /* play wired in Task 18 */ },
|
||||
trailing: LikeButton(kind: LikeKind.track, id: t.id),
|
||||
),
|
||||
]),
|
||||
),
|
||||
);
|
||||
|
||||
@@ -2,6 +2,8 @@ import 'package:flutter/material.dart';
|
||||
import 'package:flutter_riverpod/flutter_riverpod.dart';
|
||||
import 'package:go_router/go_router.dart';
|
||||
|
||||
import '../api/endpoints/likes.dart';
|
||||
import '../likes/like_button.dart';
|
||||
import '../models/album.dart';
|
||||
import '../theme/theme_extension.dart';
|
||||
import 'library_providers.dart';
|
||||
@@ -50,7 +52,7 @@ class ArtistDetailScreen extends ConsumerWidget {
|
||||
onPressed: () { /* play wired in Task 18 */ },
|
||||
),
|
||||
),
|
||||
// LikeButton goes here in Task 16.
|
||||
LikeButton(kind: LikeKind.artist, id: a.id, size: 28),
|
||||
]),
|
||||
),
|
||||
const Padding(
|
||||
|
||||
Reference in New Issue
Block a user