Lyrics for remote tracks

This commit is contained in:
2025-12-20 01:01:12 +08:00
parent aaba0382cf
commit 7f67332590
8 changed files with 630 additions and 427 deletions

View File

@@ -1,9 +1,63 @@
import 'package:groovybox/logic/audio_handler.dart';
import 'package:groovybox/logic/metadata_service.dart';
import 'package:riverpod_annotation/riverpod_annotation.dart';
import 'package:groovybox/data/db.dart' as db;
part 'audio_provider.g.dart';
// Simple data class for current track to avoid drift type issues
class CurrentTrackData {
final int id;
final String title;
final String? artist;
final String? album;
final String path;
final String? lyrics;
final int lyricsOffset;
CurrentTrackData({
required this.id,
required this.title,
this.artist,
this.album,
required this.path,
this.lyrics,
required this.lyricsOffset,
});
factory CurrentTrackData.fromTrack(db.Track track) {
return CurrentTrackData(
id: track.id,
title: track.title,
artist: track.artist,
album: track.album,
path: track.path,
lyrics: track.lyrics,
lyricsOffset: track.lyricsOffset,
);
}
CurrentTrackData copyWith({
int? id,
String? title,
String? artist,
String? album,
String? path,
String? lyrics,
int? lyricsOffset,
}) {
return CurrentTrackData(
id: id ?? this.id,
title: title ?? this.title,
artist: artist ?? this.artist,
album: album ?? this.album,
path: path ?? this.path,
lyrics: lyrics ?? this.lyrics,
lyricsOffset: lyricsOffset ?? this.lyricsOffset,
);
}
}
// This should be set after AudioService.init in main.dart
late AudioHandler _audioHandler;
@@ -17,6 +71,22 @@ void setAudioHandler(AudioHandler handler) {
_audioHandler = handler;
}
@Riverpod(keepAlive: true)
class CurrentTrackNotifier extends _$CurrentTrackNotifier {
@override
CurrentTrackData? build() {
return null;
}
void setTrack(CurrentTrackData? track) {
state = track;
}
void clear() {
state = null;
}
}
@Riverpod(keepAlive: true)
class CurrentTrackMetadataNotifier extends _$CurrentTrackMetadataNotifier {
@override

View File

@@ -50,6 +50,60 @@ final class AudioHandlerProvider
String _$audioHandlerHash() => r'65fbd92e049fe4f3a0763516f1e68e1614f7630f';
@ProviderFor(CurrentTrackNotifier)
const currentTrackProvider = CurrentTrackNotifierProvider._();
final class CurrentTrackNotifierProvider
extends $NotifierProvider<CurrentTrackNotifier, CurrentTrackData?> {
const CurrentTrackNotifierProvider._()
: super(
from: null,
argument: null,
retry: null,
name: r'currentTrackProvider',
isAutoDispose: false,
dependencies: null,
$allTransitiveDependencies: null,
);
@override
String debugGetCreateSourceHash() => _$currentTrackNotifierHash();
@$internal
@override
CurrentTrackNotifier create() => CurrentTrackNotifier();
/// {@macro riverpod.override_with_value}
Override overrideWithValue(CurrentTrackData? value) {
return $ProviderOverride(
origin: this,
providerOverride: $SyncValueProvider<CurrentTrackData?>(value),
);
}
}
String _$currentTrackNotifierHash() =>
r'faa718574ece8c3c4b8f19b70d79d142b4b7f3e9';
abstract class _$CurrentTrackNotifier extends $Notifier<CurrentTrackData?> {
CurrentTrackData? build();
@$mustCallSuper
@override
void runBuild() {
final created = build();
final ref = this.ref as $Ref<CurrentTrackData?, CurrentTrackData?>;
final element =
ref.element
as $ClassProviderElement<
AnyNotifier<CurrentTrackData?, CurrentTrackData?>,
CurrentTrackData?,
Object?,
Object?
>;
element.handleValue(ref, created);
}
}
@ProviderFor(CurrentTrackMetadataNotifier)
const currentTrackMetadataProvider = CurrentTrackMetadataNotifierProvider._();

View File

@@ -3,6 +3,7 @@ import 'package:groovybox/data/db.dart' as db;
import 'package:drift/drift.dart' as drift;
import 'package:groovybox/logic/lrc_providers.dart';
import 'package:groovybox/logic/lyrics_parser.dart';
import 'package:groovybox/providers/audio_provider.dart';
import 'package:groovybox/providers/db_provider.dart';
import 'package:groovybox/ui/screens/player_screen.dart';
import 'package:hooks_riverpod/hooks_riverpod.dart';
@@ -60,6 +61,16 @@ class LyricsFetcher extends _$LyricsFetcher {
debugPrint('Updated database with lyrics for track $trackId');
// Update the current track provider if this is the current track
final currentTrackNotifier = ref.read(currentTrackProvider.notifier);
final currentTrack = currentTrackNotifier.state;
if (currentTrack != null && currentTrack.id == trackId) {
// Update the current track with new lyrics
final updatedTrack = currentTrack.copyWith(lyrics: lyricsJson);
currentTrackNotifier.setTrack(updatedTrack);
debugPrint('Updated current track provider with new lyrics');
}
// Invalidate the track provider to refresh the UI
ref.invalidate(trackByPathProvider(trackPath));

View File

@@ -247,7 +247,7 @@ class RemoteUrlResolver {
try {
// Create Jellyfin client and authenticate
final client = JellyfinDart(basePathOverride: provider.serverUrl);
client.setDeviceId('groovybox-${providerId}');
client.setDeviceId('groovybox-$providerId');
client.setVersion('1.0.0');
final userApi = client.getUserApi();