diff --git a/lib/screens/dashboard/dashboard_screen.dart b/lib/screens/dashboard/dashboard_screen.dart index c9bd49b..99d3d9a 100644 --- a/lib/screens/dashboard/dashboard_screen.dart +++ b/lib/screens/dashboard/dashboard_screen.dart @@ -106,8 +106,8 @@ class _DashboardScreenState extends ConsumerState { child: HomeBannerWidget(posters: homeCarouselItems), ), ), - } else if (AdaptiveLayout.of(context).isDesktop) - const DefaultSliverTopBadding(), + }, + const DefaultSliverTopBadding(), if (AdaptiveLayout.of(context).isDesktop) const SliverToBoxAdapter( child: Row( diff --git a/lib/screens/shared/default_title_bar.dart b/lib/screens/shared/default_title_bar.dart index 8802caf..d44b344 100644 --- a/lib/screens/shared/default_title_bar.dart +++ b/lib/screens/shared/default_title_bar.dart @@ -16,6 +16,8 @@ class DefaultTitleBar extends ConsumerStatefulWidget { } class _DefaultTitleBarState extends ConsumerState with WindowListener { + bool hovering = false; + @override void initState() { windowManager.addListener(this); @@ -40,135 +42,149 @@ class _DefaultTitleBarState extends ConsumerState with WindowLi ] : []; final iconColor = Theme.of(context).colorScheme.onSurface.withValues(alpha: 0.65); - return SizedBox( - height: widget.height, - child: switch (AdaptiveLayout.of(context).platform) { - TargetPlatform.android || TargetPlatform.iOS => SizedBox(height: MediaQuery.paddingOf(context).top), - TargetPlatform.windows || TargetPlatform.linux => Row( - children: [ - Expanded( - child: Container( - color: Colors.black.withValues(alpha: 0), - child: DragToMoveArea( - child: Row( - crossAxisAlignment: CrossAxisAlignment.stretch, - mainAxisSize: MainAxisSize.max, - children: [ - Container( - padding: const EdgeInsets.only(left: 16), - child: DefaultTextStyle( - style: TextStyle( - color: iconColor, - fontSize: 14, + return MouseRegion( + onEnter: (event) => setState(() => hovering = true), + onExit: (event) => setState(() => hovering = false), + child: AnimatedContainer( + duration: const Duration(milliseconds: 250), + decoration: BoxDecoration( + color: hovering ? Colors.black.withValues(alpha: 0.15) : Colors.transparent, + ), + height: widget.height, + child: switch (AdaptiveLayout.of(context).platform) { + TargetPlatform.android || TargetPlatform.iOS => SizedBox(height: MediaQuery.paddingOf(context).top), + TargetPlatform.windows || TargetPlatform.linux => Row( + children: [ + Expanded( + child: Container( + color: Colors.black.withValues(alpha: 0), + child: DragToMoveArea( + child: Row( + crossAxisAlignment: CrossAxisAlignment.stretch, + mainAxisSize: MainAxisSize.max, + children: [ + Container( + padding: const EdgeInsets.only(left: 16), + child: DefaultTextStyle( + style: TextStyle( + color: iconColor, + fontSize: 14, + ), + child: Text(widget.label ?? ""), ), - child: Text(widget.label ?? ""), ), - ), - ], + ], + ), ), ), ), - ), - Row( - children: [ - FutureBuilder( - future: windowManager.isMinimizable(), - builder: (context, data) { - final isMinimized = !(data.data ?? false); - return IconButton( - style: IconButton.styleFrom( - hoverColor: brightness == Brightness.light - ? Colors.black.withValues(alpha: 0.1) - : Colors.white.withValues(alpha: 0.2), - shape: RoundedRectangleBorder(borderRadius: BorderRadius.circular(2))), - onPressed: () async { - if (isMinimized) { - windowManager.restore(); - } else { - windowManager.minimize(); - } - }, - icon: Transform.translate( - offset: const Offset(0, -2), - child: Icon( - Icons.minimize_rounded, - color: iconColor, - size: 20, - shadows: shadows, - ), - ), - ); - }), - FutureBuilder>( - future: Future.microtask(() async { - final isMaximized = await windowManager.isMaximized(); + Row( + children: [ + FutureBuilder>(future: Future.microtask(() async { + final isMinimized = await windowManager.isMinimized(); final isFullScreen = await windowManager.isFullScreen(); - return [isMaximized, isFullScreen]; - }), - builder: (BuildContext context, AsyncSnapshot> snapshot) { - final maximized = snapshot.data?.firstOrNull ?? false; + return [isMinimized, isFullScreen]; + }), builder: (context, snapshot) { + final isMinimized = snapshot.data?.firstOrNull ?? false; final fullScreen = snapshot.data?.lastOrNull ?? false; return IconButton( style: IconButton.styleFrom( - hoverColor: brightness == Brightness.light - ? Colors.black.withValues(alpha: 0.1) - : Colors.white.withValues(alpha: 0.2), - shape: RoundedRectangleBorder(borderRadius: BorderRadius.circular(2)), - ), + hoverColor: brightness == Brightness.light + ? Colors.black.withValues(alpha: 0.1) + : Colors.white.withValues(alpha: 0.2), + shape: RoundedRectangleBorder(borderRadius: BorderRadius.circular(2))), onPressed: () async { - if (fullScreen && maximized) { - await windowManager.setFullScreen(false); - await windowManager.unmaximize(); - return; - } - if (fullScreen) { await windowManager.setFullScreen(false); - } else if (!maximized) { - await windowManager.maximize(); + } + if (isMinimized) { + windowManager.restore(); } else { - await windowManager.unmaximize(); + windowManager.minimize(); } }, icon: Transform.translate( - offset: const Offset(0, 0), + offset: const Offset(0, -2), child: Icon( - maximized ? Icons.maximize_rounded : Icons.crop_square_rounded, + Icons.minimize_rounded, color: iconColor, - size: 19, + size: 20, shadows: shadows, ), ), ); - }, - ), - IconButton( - style: IconButton.styleFrom( - hoverColor: Colors.red, - shape: RoundedRectangleBorder( - borderRadius: BorderRadius.circular(2), + }), + FutureBuilder>( + future: Future.microtask(() async { + final isMaximized = await windowManager.isMaximized(); + final isFullScreen = await windowManager.isFullScreen(); + return [isMaximized, isFullScreen]; + }), + builder: (BuildContext context, AsyncSnapshot> snapshot) { + final maximized = snapshot.data?.firstOrNull ?? false; + final fullScreen = snapshot.data?.lastOrNull ?? false; + return IconButton( + style: IconButton.styleFrom( + hoverColor: brightness == Brightness.light + ? Colors.black.withValues(alpha: 0.1) + : Colors.white.withValues(alpha: 0.2), + shape: RoundedRectangleBorder(borderRadius: BorderRadius.circular(2)), + ), + onPressed: () async { + if (fullScreen && maximized) { + await windowManager.setFullScreen(false); + await windowManager.unmaximize(); + return; + } + + if (fullScreen) { + await windowManager.setFullScreen(false); + } else if (!maximized) { + await windowManager.maximize(); + } else { + await windowManager.unmaximize(); + } + }, + icon: Transform.translate( + offset: const Offset(0, 0), + child: Icon( + maximized ? Icons.maximize_rounded : Icons.crop_square_rounded, + color: iconColor, + size: 19, + shadows: shadows, + ), + ), + ); + }, + ), + IconButton( + style: IconButton.styleFrom( + hoverColor: Colors.red, + shape: RoundedRectangleBorder( + borderRadius: BorderRadius.circular(2), + ), + ), + onPressed: () async { + windowManager.close(); + }, + icon: Transform.translate( + offset: const Offset(0, -2), + child: Icon( + Icons.close_rounded, + color: iconColor, + size: 23, + shadows: shadows, + ), ), ), - onPressed: () async { - windowManager.close(); - }, - icon: Transform.translate( - offset: const Offset(0, -2), - child: Icon( - Icons.close_rounded, - color: iconColor, - size: 23, - shadows: shadows, - ), - ), - ), - ], - ), - ], - ), - TargetPlatform.macOS => const SizedBox.shrink(), - _ => Text(widget.label ?? "Fladder"), - }, + ], + ), + ], + ), + TargetPlatform.macOS => const SizedBox.shrink(), + _ => Text(widget.label ?? "Fladder"), + }, + ), ); } } diff --git a/lib/util/sliver_list_padding.dart b/lib/util/sliver_list_padding.dart index 09bdd48..e1b30cf 100644 --- a/lib/util/sliver_list_padding.dart +++ b/lib/util/sliver_list_padding.dart @@ -19,8 +19,8 @@ class DefaultSliverTopBadding extends StatelessWidget { @override Widget build(BuildContext context) { - return (AdaptiveLayout.viewSizeOf(context) != ViewSize.phone) - ? const SliverPadding(padding: EdgeInsets.only(top: 35)) + return (AdaptiveLayout.viewSizeOf(context) == ViewSize.phone) + ? const SliverToBoxAdapter() : SliverPadding(padding: EdgeInsets.only(top: MediaQuery.of(context).padding.top)); } }