0134281b8c
- artist_detail_screen.dart missed an `import '../models/artist.dart'` for the ArtistRef seed parameter; analyze flagged undefined_class. - radio.dart + player_provider.dart doc comments wrapped URL parameters in <...> which lint reads as HTML. Switched to backticks. Full player title is now centered absolutely via a Stack: title with horizontal padding equal to the actions cluster width sits at the optical center, while LikeButton + TrackActionsButton are pinned to the right edge with Positioned. Fixed-height SizedBox(32) keeps the row stable when the title wraps to a single ellipsized line.
28 lines
884 B
Dart
28 lines
884 B
Dart
import 'package:dio/dio.dart';
|
|
|
|
import '../../models/track.dart';
|
|
|
|
/// `GET /api/radio?seed_track=<uuid>&limit=<int>`. Returns the seed
|
|
/// at index 0 followed by up to `limit-1` weighted-shuffle picks
|
|
/// scored by the server's recommendation engine. The shape matches
|
|
/// what `playerActions.playTracks` expects, so a radio start is just
|
|
/// one fetch + one playTracks call.
|
|
class RadioApi {
|
|
RadioApi(this._dio);
|
|
final Dio _dio;
|
|
|
|
Future<List<TrackRef>> seedTrack(String trackId, {int? limit}) async {
|
|
final r = await _dio.get<Map<String, dynamic>>(
|
|
'/api/radio',
|
|
queryParameters: {
|
|
'seed_track': trackId,
|
|
if (limit != null) 'limit': limit,
|
|
},
|
|
);
|
|
final raw = (r.data?['tracks'] as List?) ?? const [];
|
|
return raw
|
|
.map((e) => TrackRef.fromJson((e as Map).cast<String, dynamic>()))
|
|
.toList(growable: false);
|
|
}
|
|
}
|