fix: lyrics modal sheet out of safe area so use 80% of screen height instead of full

This commit is contained in:
Kingkor Roy Tirtho 2023-01-08 14:18:29 +06:00
parent b5415f442a
commit 3db28f43b4
4 changed files with 128 additions and 122 deletions

View File

@ -1,6 +1,5 @@
import 'package:fl_query_hooks/fl_query_hooks.dart'; import 'package:fl_query_hooks/fl_query_hooks.dart';
import 'package:flutter/material.dart'; import 'package:flutter/material.dart';
import 'package:flutter_hooks/flutter_hooks.dart';
import 'package:hooks_riverpod/hooks_riverpod.dart'; import 'package:hooks_riverpod/hooks_riverpod.dart';
import 'package:palette_generator/palette_generator.dart'; import 'package:palette_generator/palette_generator.dart';
import 'package:spotify/spotify.dart'; import 'package:spotify/spotify.dart';
@ -15,8 +14,10 @@ import 'package:tuple/tuple.dart';
class GeniusLyrics extends HookConsumerWidget { class GeniusLyrics extends HookConsumerWidget {
final PaletteColor palette; final PaletteColor palette;
final bool? isModal;
const GeniusLyrics({ const GeniusLyrics({
required this.palette, required this.palette,
this.isModal,
Key? key, Key? key,
}) : super(key: key); }) : super(key: key);
@ -36,27 +37,29 @@ class GeniusLyrics extends HookConsumerWidget {
return Column( return Column(
crossAxisAlignment: CrossAxisAlignment.stretch, crossAxisAlignment: CrossAxisAlignment.stretch,
children: [ children: [
Center( if (isModal != true) ...[
child: Text( Center(
playback.track?.name ?? "", child: Text(
style: breakpoint >= Breakpoints.md playback.track?.name ?? "",
? textTheme.headline3 style: breakpoint >= Breakpoints.md
: textTheme.headline4?.copyWith( ? textTheme.headline3
fontSize: 25, : textTheme.headline4?.copyWith(
color: palette.titleTextColor, fontSize: 25,
), color: palette.titleTextColor,
),
),
), ),
), Center(
Center( child: Text(
child: Text( TypeConversionUtils.artists_X_String<Artist>(
TypeConversionUtils.artists_X_String<Artist>( playback.track?.artists ?? []),
playback.track?.artists ?? []), style: (breakpoint >= Breakpoints.md
style: (breakpoint >= Breakpoints.md ? textTheme.headline5
? textTheme.headline5 : textTheme.headline6)
: textTheme.headline6) ?.copyWith(color: palette.bodyTextColor),
?.copyWith(color: palette.bodyTextColor), ),
), )
), ],
Expanded( Expanded(
child: SingleChildScrollView( child: SingleChildScrollView(
child: Center( child: Center(

View File

@ -40,8 +40,8 @@ class LyricsPage extends HookConsumerWidget {
); );
Widget body = [ Widget body = [
SyncedLyrics(palette: palette), SyncedLyrics(palette: palette, isModal: isModal),
GeniusLyrics(palette: palette), GeniusLyrics(palette: palette, isModal: isModal),
][index.value]; ][index.value];
final tabbar = PreferredSize( final tabbar = PreferredSize(
@ -70,11 +70,12 @@ class LyricsPage extends HookConsumerWidget {
return SafeArea( return SafeArea(
child: Container( child: Container(
clipBehavior: Clip.hardEdge, clipBehavior: Clip.hardEdge,
decoration: BoxDecoration( decoration: const BoxDecoration(
color: Colors.black45, borderRadius: BorderRadius.only(
borderRadius: BorderRadius.circular(8), topLeft: Radius.circular(10),
topRight: Radius.circular(10),
),
), ),
margin: const EdgeInsets.all(16),
child: BackdropFilter( child: BackdropFilter(
filter: ImageFilter.blur(sigmaX: 50, sigmaY: 50), filter: ImageFilter.blur(sigmaX: 50, sigmaY: 50),
child: Column( child: Column(

View File

@ -26,8 +26,11 @@ final lyricDelayState = StateProvider<Duration>(
class SyncedLyrics extends HookConsumerWidget { class SyncedLyrics extends HookConsumerWidget {
final PaletteColor palette; final PaletteColor palette;
final bool? isModal;
const SyncedLyrics({ const SyncedLyrics({
required this.palette, required this.palette,
this.isModal,
Key? key, Key? key,
}) : super(key: key); }) : super(key: key);
@ -70,107 +73,102 @@ class SyncedLyrics extends HookConsumerWidget {
: textTheme.headline4?.copyWith(fontSize: 25)) : textTheme.headline4?.copyWith(fontSize: 25))
?.copyWith(color: palette.titleTextColor); ?.copyWith(color: palette.titleTextColor);
return Column( return Stack(
children: [ children: [
SizedBox( Column(
height: breakpoint >= Breakpoints.md ? 50 : 40, children: [
child: Material( if (isModal != true)
type: MaterialType.transparency, Center(
textStyle: PlatformTheme.of(context).textTheme!.body!, child: SpotubeMarqueeText(
child: Stack( text: playback.track?.name ?? "Not Playing",
children: [ style: headlineTextStyle,
Center( isHovering: true,
child: SpotubeMarqueeText(
text: playback.track?.name ?? "Not Playing",
style: headlineTextStyle,
isHovering: true,
),
), ),
Positioned( ),
top: 10, if (isModal != true)
right: 10, Center(
child: Align( child: Text(
alignment: Alignment.centerRight, TypeConversionUtils.artists_X_String<Artist>(
child: PlatformFilledButton( playback.track?.artists ?? []),
child: const Icon( style: breakpoint >= Breakpoints.md
SpotubeIcons.clock, ? textTheme.headline5
size: 16, : textTheme.headline6,
),
onPressed: () async {
final delay = await showPlatformAlertDialog(
context,
builder: (context) => const LyricDelayAdjustDialog(),
);
if (delay != null) {
ref.read(lyricDelayState.notifier).state = delay;
}
},
),
),
), ),
], ),
), if (lyricValue != null && lyricValue.lyrics.isNotEmpty)
), Expanded(
), child: ListView.builder(
Center(
child: Text(
TypeConversionUtils.artists_X_String<Artist>(
playback.track?.artists ?? []),
style: breakpoint >= Breakpoints.md
? textTheme.headline5
: textTheme.headline6,
),
),
if (lyricValue != null && lyricValue.lyrics.isNotEmpty)
Expanded(
child: ListView.builder(
controller: controller,
itemCount: lyricValue.lyrics.length,
itemBuilder: (context, index) {
final lyricSlice = lyricValue.lyrics[index];
final isActive = lyricSlice.time.inSeconds == currentTime;
if (isActive) {
controller.scrollToIndex(
index,
preferPosition: AutoScrollPosition.middle,
);
}
return AutoScrollTag(
key: ValueKey(index),
index: index,
controller: controller, controller: controller,
child: lyricSlice.text.isEmpty itemCount: lyricValue.lyrics.length,
? Container() itemBuilder: (context, index) {
: Center( final lyricSlice = lyricValue.lyrics[index];
child: Padding( final isActive = lyricSlice.time.inSeconds == currentTime;
padding: const EdgeInsets.all(8.0),
child: AnimatedDefaultTextStyle( if (isActive) {
duration: const Duration(milliseconds: 250), controller.scrollToIndex(
style: TextStyle( index,
color: isActive preferPosition: AutoScrollPosition.middle,
? Colors.white );
: palette.bodyTextColor, }
fontWeight: isActive return AutoScrollTag(
? FontWeight.bold key: ValueKey(index),
: FontWeight.normal, index: index,
fontSize: isActive ? 30 : 26, controller: controller,
), child: lyricSlice.text.isEmpty
child: Text( ? Container()
lyricSlice.text, : Center(
maxLines: 2, child: Padding(
textAlign: TextAlign.center, padding: const EdgeInsets.all(8.0),
child: AnimatedDefaultTextStyle(
duration: const Duration(milliseconds: 250),
style: TextStyle(
color: isActive
? Colors.white
: palette.bodyTextColor,
fontWeight: isActive
? FontWeight.bold
: FontWeight.normal,
fontSize: isActive ? 30 : 26,
),
child: Text(
lyricSlice.text,
maxLines: 2,
textAlign: TextAlign.center,
),
),
), ),
), ),
), );
), },
),
),
if (playback.track != null &&
(lyricValue == null || lyricValue.lyrics.isEmpty == true))
const Expanded(child: ShimmerLyrics()),
],
),
Positioned(
top: 10,
right: 10,
child: Align(
alignment: Alignment.centerRight,
child: PlatformFilledButton(
child: const Icon(
SpotubeIcons.clock,
size: 16,
),
onPressed: () async {
final delay = await showPlatformAlertDialog(
context,
builder: (context) => const LyricDelayAdjustDialog(),
); );
if (delay != null) {
ref.read(lyricDelayState.notifier).state = delay;
}
}, },
), ),
), ),
if (playback.track != null && ),
(lyricValue == null || lyricValue.lyrics.isEmpty == true))
const Expanded(child: ShimmerLyrics()),
], ],
); );
} }

View File

@ -201,13 +201,17 @@ class PlayerView extends HookConsumerWidget {
isDismissible: true, isDismissible: true,
enableDrag: true, enableDrag: true,
isScrollControlled: true, isScrollControlled: true,
backgroundColor: Colors.transparent, backgroundColor: Colors.black38,
barrierColor: Colors.black12, barrierColor: Colors.black12,
shape: RoundedRectangleBorder( shape: const RoundedRectangleBorder(
borderRadius: BorderRadius.circular(10), borderRadius: BorderRadius.only(
topLeft: Radius.circular(20),
topRight: Radius.circular(20),
),
), ),
constraints: BoxConstraints( constraints: BoxConstraints(
maxHeight: MediaQuery.of(context).size.height, maxHeight:
MediaQuery.of(context).size.height * 0.8,
), ),
builder: (context) => builder: (context) =>
const LyricsPage(isModal: true), const LyricsPage(isModal: true),