mirror of
https://github.com/zarzet/SpotiFLAC-Mobile.git
synced 2026-10-22 07:18:38 +02:00
The empty lyrics page offers Search online, which asks the enabled lyrics providers in their configured order. The result is shown in the player only and never written to the file; a late result is dropped after the track changes, and a miss says so.
144 lines
4.7 KiB
Dart
144 lines
4.7 KiB
Dart
import 'package:flutter/material.dart';
|
|
import 'package:flutter/services.dart' show HapticFeedback;
|
|
import 'package:flutter_riverpod/flutter_riverpod.dart';
|
|
import 'package:spotiflac_android/controllers/player_metadata_controller.dart';
|
|
import 'package:spotiflac_android/l10n/l10n.dart';
|
|
import 'package:spotiflac_android/providers/settings_provider.dart';
|
|
import 'package:spotiflac_android/theme/mornye_theme.dart';
|
|
import 'package:spotiflac_android/utils/lyrics_parser.dart';
|
|
import 'package:spotiflac_android/utils/playback_seek_preview.dart';
|
|
import 'package:spotiflac_android/widgets/app_icon.dart';
|
|
import 'package:spotiflac_android/widgets/app_loading_indicator.dart';
|
|
import 'package:spotiflac_android/widgets/expressive_button.dart';
|
|
import 'package:spotiflac_android/widgets/player_lyrics.dart';
|
|
import 'package:spotiflac_android/widgets/lyrics_text_scale.dart';
|
|
|
|
class PlayerLyricsSection extends ConsumerWidget {
|
|
const PlayerLyricsSection({
|
|
super.key,
|
|
required this.metadata,
|
|
required this.seekPreview,
|
|
required this.colorScheme,
|
|
required this.isActive,
|
|
this.options,
|
|
this.onShareLyrics,
|
|
});
|
|
|
|
final PlayerMetadataController metadata;
|
|
final PlaybackSeekPreview seekPreview;
|
|
final ColorScheme colorScheme;
|
|
final bool isActive;
|
|
final Widget? options;
|
|
|
|
/// Long-pressing lyrics opens sharing, preselecting a timed line.
|
|
final ValueChanged<LyricLine?>? onShareLyrics;
|
|
|
|
@override
|
|
Widget build(BuildContext context, WidgetRef ref) {
|
|
final visibility = ref.watch(
|
|
settingsProvider.select(
|
|
(settings) =>
|
|
(settings.playerShowPronunciation, settings.playerShowTranslation),
|
|
),
|
|
);
|
|
return ListenableBuilder(
|
|
listenable: metadata,
|
|
builder: (context, _) => _buildLyricsSection(context, visibility),
|
|
);
|
|
}
|
|
|
|
Widget _buildLyricsSection(BuildContext context, (bool, bool) visibility) {
|
|
if (metadata.loading || metadata.searchingOnline) {
|
|
return const Center(child: AppLoadingIndicator());
|
|
}
|
|
if (metadata.lyrics.isEmpty) {
|
|
return Center(
|
|
child: Column(
|
|
mainAxisSize: MainAxisSize.min,
|
|
children: [
|
|
AppIcon(
|
|
Icons.lyrics_outlined,
|
|
size: 40,
|
|
color: colorScheme.onSurfaceVariant,
|
|
),
|
|
const SizedBox(height: 12),
|
|
Text(
|
|
metadata.onlineSearchMissed
|
|
? context.l10n.nowPlayingNoLyricsOnline
|
|
: context.l10n.nowPlayingNoLyrics,
|
|
style: Theme.of(context).textTheme.bodyMedium?.copyWith(
|
|
color: colorScheme.onSurfaceVariant,
|
|
),
|
|
),
|
|
if (metadata.canSearchOnline) ...[
|
|
const SizedBox(height: 16),
|
|
ExpressiveButton(
|
|
tonal: true,
|
|
onPressed: metadata.searchOnline,
|
|
icon: const Icon(Icons.manage_search),
|
|
child: Text(context.l10n.nowPlayingSearchLyricsOnline),
|
|
),
|
|
],
|
|
],
|
|
),
|
|
);
|
|
}
|
|
if (metadata.lyrics.synced) {
|
|
return Stack(
|
|
fit: StackFit.expand,
|
|
children: [
|
|
SyncedLyricsView(
|
|
lyrics: metadata.lyrics,
|
|
seekPreview: seekPreview,
|
|
credits: _lyricsCredits(),
|
|
colorScheme: colorScheme,
|
|
isActive: isActive,
|
|
showPronunciation: visibility.$1,
|
|
showTranslation: visibility.$2,
|
|
onLongPressLine: onShareLyrics,
|
|
),
|
|
if (options != null)
|
|
Positioned(
|
|
left: context.isMornye ? mornyeLyricsContentInset : 24,
|
|
bottom: 8,
|
|
child: options!,
|
|
),
|
|
],
|
|
);
|
|
}
|
|
return SingleChildScrollView(
|
|
padding: const EdgeInsets.fromLTRB(24, 16, 24, 32),
|
|
child: Column(
|
|
crossAxisAlignment: CrossAxisAlignment.stretch,
|
|
children: [
|
|
GestureDetector(
|
|
onLongPress: onShareLyrics == null
|
|
? null
|
|
: () {
|
|
HapticFeedback.mediumImpact();
|
|
onShareLyrics!(null);
|
|
},
|
|
child: LyricsTextScale(
|
|
child: Text(
|
|
metadata.lyrics.plainText,
|
|
style: Theme.of(context).textTheme.titleMedium?.copyWith(
|
|
height: 1.6,
|
|
color: colorScheme.onSurface,
|
|
),
|
|
textAlign: TextAlign.center,
|
|
),
|
|
),
|
|
),
|
|
?_lyricsCredits(),
|
|
],
|
|
),
|
|
);
|
|
}
|
|
|
|
LyricsCredits? _lyricsCredits() {
|
|
final (:writers, :provider) = metadata.credits;
|
|
if (writers == null && provider == null) return null;
|
|
return LyricsCredits(writers: writers, provider: provider);
|
|
}
|
|
}
|