mirror of
https://github.com/KRTirtho/spotube.git
synced 2026-05-08 16:24:36 +00:00
feat: use provider in lyrics screen
This commit is contained in:
parent
ac8121647b
commit
4d774b6ef1
@ -12,8 +12,8 @@ import 'package:spotube/extensions/constrains.dart';
|
|||||||
import 'package:spotube/extensions/context.dart';
|
import 'package:spotube/extensions/context.dart';
|
||||||
|
|
||||||
import 'package:spotube/provider/proxy_playlist/proxy_playlist_provider.dart';
|
import 'package:spotube/provider/proxy_playlist/proxy_playlist_provider.dart';
|
||||||
|
import 'package:spotube/provider/spotify/spotify.dart';
|
||||||
|
|
||||||
import 'package:spotube/services/queries/queries.dart';
|
|
||||||
import 'package:spotube/utils/type_conversion_utils.dart';
|
import 'package:spotube/utils/type_conversion_utils.dart';
|
||||||
|
|
||||||
class PlainLyrics extends HookConsumerWidget {
|
class PlainLyrics extends HookConsumerWidget {
|
||||||
@ -30,8 +30,7 @@ class PlainLyrics extends HookConsumerWidget {
|
|||||||
@override
|
@override
|
||||||
Widget build(BuildContext context, ref) {
|
Widget build(BuildContext context, ref) {
|
||||||
final playlist = ref.watch(ProxyPlaylistNotifier.provider);
|
final playlist = ref.watch(ProxyPlaylistNotifier.provider);
|
||||||
final lyricsQuery =
|
final lyricsQuery = ref.watch(syncedLyricsProvider(playlist.activeTrack));
|
||||||
useQueries.lyrics.spotifySynced(ref, playlist.activeTrack);
|
|
||||||
final mediaQuery = MediaQuery.of(context);
|
final mediaQuery = MediaQuery.of(context);
|
||||||
final textTheme = Theme.of(context).textTheme;
|
final textTheme = Theme.of(context).textTheme;
|
||||||
|
|
||||||
@ -96,9 +95,9 @@ class PlainLyrics extends HookConsumerWidget {
|
|||||||
}
|
}
|
||||||
|
|
||||||
final lyrics =
|
final lyrics =
|
||||||
lyricsQuery.data?.lyrics.mapIndexed((i, e) {
|
lyricsQuery.value?.lyrics.mapIndexed((i, e) {
|
||||||
final next =
|
final next =
|
||||||
lyricsQuery.data?.lyrics.elementAtOrNull(i + 1);
|
lyricsQuery.value?.lyrics.elementAtOrNull(i + 1);
|
||||||
if (next != null &&
|
if (next != null &&
|
||||||
e.time - next.time >
|
e.time - next.time >
|
||||||
const Duration(milliseconds: 700)) {
|
const Duration(milliseconds: 700)) {
|
||||||
|
|||||||
@ -13,14 +13,12 @@ import 'package:spotube/hooks/controllers/use_auto_scroll_controller.dart';
|
|||||||
import 'package:spotube/components/lyrics/use_synced_lyrics.dart';
|
import 'package:spotube/components/lyrics/use_synced_lyrics.dart';
|
||||||
import 'package:scroll_to_index/scroll_to_index.dart';
|
import 'package:scroll_to_index/scroll_to_index.dart';
|
||||||
import 'package:spotube/provider/proxy_playlist/proxy_playlist_provider.dart';
|
import 'package:spotube/provider/proxy_playlist/proxy_playlist_provider.dart';
|
||||||
|
import 'package:spotube/provider/spotify/spotify.dart';
|
||||||
import 'package:spotube/services/audio_player/audio_player.dart';
|
import 'package:spotube/services/audio_player/audio_player.dart';
|
||||||
import 'package:spotube/services/queries/queries.dart';
|
|
||||||
|
|
||||||
import 'package:spotube/utils/type_conversion_utils.dart';
|
import 'package:spotube/utils/type_conversion_utils.dart';
|
||||||
import 'package:stroke_text/stroke_text.dart';
|
import 'package:stroke_text/stroke_text.dart';
|
||||||
|
|
||||||
final _delay = StateProvider<int>((ref) => 0);
|
|
||||||
|
|
||||||
class SyncedLyrics extends HookConsumerWidget {
|
class SyncedLyrics extends HookConsumerWidget {
|
||||||
final PaletteColor palette;
|
final PaletteColor palette;
|
||||||
final bool? isModal;
|
final bool? isModal;
|
||||||
@ -40,28 +38,18 @@ class SyncedLyrics extends HookConsumerWidget {
|
|||||||
final mediaQuery = MediaQuery.of(context);
|
final mediaQuery = MediaQuery.of(context);
|
||||||
final controller = useAutoScrollController();
|
final controller = useAutoScrollController();
|
||||||
|
|
||||||
final delay = ref.watch(_delay);
|
final delay = ref.watch(syncedLyricsDelayProvider);
|
||||||
|
|
||||||
final timedLyricsQuery =
|
final timedLyricsQuery =
|
||||||
useQueries.lyrics.spotifySynced(ref, playlist.activeTrack);
|
ref.watch(syncedLyricsProvider(playlist.activeTrack));
|
||||||
|
|
||||||
final lyricValue = timedLyricsQuery.data;
|
final lyricValue = timedLyricsQuery.asData?.value;
|
||||||
|
|
||||||
final isUnSyncLyric = useMemoized(
|
final lyricsState = ref.watch(
|
||||||
() => lyricValue?.lyrics.every((l) => l.time == Duration.zero),
|
syncedLyricsMapProvider(playlist.activeTrack),
|
||||||
[lyricValue],
|
|
||||||
);
|
);
|
||||||
|
final currentTime =
|
||||||
final lyricsMap = useMemoized(
|
useSyncedLyrics(ref, lyricsState.asData?.value.lyricsMap ?? {}, delay);
|
||||||
() =>
|
|
||||||
lyricValue?.lyrics
|
|
||||||
.map((lyric) => {lyric.time.inSeconds: lyric.text})
|
|
||||||
.reduce((accumulator, lyricSlice) =>
|
|
||||||
{...accumulator, ...lyricSlice}) ??
|
|
||||||
{},
|
|
||||||
[lyricValue],
|
|
||||||
);
|
|
||||||
final currentTime = useSyncedLyrics(ref, lyricsMap, delay);
|
|
||||||
final textZoomLevel = useState<int>(defaultTextZoom);
|
final textZoomLevel = useState<int>(defaultTextZoom);
|
||||||
|
|
||||||
final textTheme = Theme.of(context).textTheme;
|
final textTheme = Theme.of(context).textTheme;
|
||||||
@ -70,7 +58,7 @@ class SyncedLyrics extends HookConsumerWidget {
|
|||||||
ProxyPlaylistNotifier.provider.select((s) => s.activeTrack),
|
ProxyPlaylistNotifier.provider.select((s) => s.activeTrack),
|
||||||
(previous, next) {
|
(previous, next) {
|
||||||
controller.scrollToIndex(0);
|
controller.scrollToIndex(0);
|
||||||
ref.read(_delay.notifier).state = 0;
|
ref.read(syncedLyricsDelayProvider.notifier).state = 0;
|
||||||
},
|
},
|
||||||
);
|
);
|
||||||
|
|
||||||
@ -105,7 +93,7 @@ class SyncedLyrics extends HookConsumerWidget {
|
|||||||
),
|
),
|
||||||
if (lyricValue != null &&
|
if (lyricValue != null &&
|
||||||
lyricValue.lyrics.isNotEmpty &&
|
lyricValue.lyrics.isNotEmpty &&
|
||||||
isUnSyncLyric == false)
|
lyricsState.asData?.value.static != true)
|
||||||
Expanded(
|
Expanded(
|
||||||
child: ListView.builder(
|
child: ListView.builder(
|
||||||
controller: controller,
|
controller: controller,
|
||||||
@ -202,7 +190,7 @@ class SyncedLyrics extends HookConsumerWidget {
|
|||||||
),
|
),
|
||||||
const Gap(26),
|
const Gap(26),
|
||||||
const Icon(SpotubeIcons.noLyrics, size: 60),
|
const Icon(SpotubeIcons.noLyrics, size: 60),
|
||||||
] else if (isUnSyncLyric == true)
|
] else if (lyricsState.asData?.value.static == true)
|
||||||
Expanded(
|
Expanded(
|
||||||
child: Center(
|
child: Center(
|
||||||
child: RichText(
|
child: RichText(
|
||||||
@ -235,7 +223,8 @@ class SyncedLyrics extends HookConsumerWidget {
|
|||||||
final actions = [
|
final actions = [
|
||||||
ZoomControls(
|
ZoomControls(
|
||||||
value: delay,
|
value: delay,
|
||||||
onChanged: (value) => ref.read(_delay.notifier).state = value,
|
onChanged: (value) =>
|
||||||
|
ref.read(syncedLyricsDelayProvider.notifier).state = value,
|
||||||
interval: 1,
|
interval: 1,
|
||||||
unit: "s",
|
unit: "s",
|
||||||
increaseIcon: const Icon(SpotubeIcons.add),
|
increaseIcon: const Icon(SpotubeIcons.add),
|
||||||
|
|||||||
@ -54,3 +54,24 @@ class SyncedLyricsNotifier extends FamilyAsyncNotifier<SubtitleSimple, Track?>
|
|||||||
@override
|
@override
|
||||||
Map<String, dynamic> toJson(SubtitleSimple data) => data.toJson();
|
Map<String, dynamic> toJson(SubtitleSimple data) => data.toJson();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
final syncedLyricsDelayProvider = StateProvider<int>((ref) => 0);
|
||||||
|
|
||||||
|
final syncedLyricsProvider =
|
||||||
|
AsyncNotifierProviderFamily<SyncedLyricsNotifier, SubtitleSimple, Track?>(
|
||||||
|
() => SyncedLyricsNotifier(),
|
||||||
|
);
|
||||||
|
|
||||||
|
final syncedLyricsMapProvider =
|
||||||
|
FutureProvider.family((ref, Track? track) async {
|
||||||
|
final syncedLyrics = await ref.watch(syncedLyricsProvider(track).future);
|
||||||
|
|
||||||
|
final isStaticLyrics =
|
||||||
|
syncedLyrics.lyrics.every((l) => l.time == Duration.zero);
|
||||||
|
|
||||||
|
final lyricsMap = syncedLyrics.lyrics
|
||||||
|
.map((lyric) => {lyric.time.inSeconds: lyric.text})
|
||||||
|
.reduce((accumulator, lyricSlice) => {...accumulator, ...lyricSlice});
|
||||||
|
|
||||||
|
return (static: isStaticLyrics, lyricsMap: lyricsMap);
|
||||||
|
});
|
||||||
|
|||||||
Loading…
Reference in New Issue
Block a user