From e659e3c56fb02ad8a1c5114bf80074f0324cc4f1 Mon Sep 17 00:00:00 2001 From: Kingkor Roy Tirtho Date: Fri, 11 Nov 2022 13:01:23 +0600 Subject: [PATCH] feat(title_bar): platform specific title bar --- lib/components/Artist/ArtistProfile.dart | 4 +- lib/components/Home/Shell.dart | 52 +++--- lib/components/Home/Sidebar.dart | 2 +- lib/components/Login/TokenLogin.dart | 2 +- .../Playlist/PlaylistGenreView.dart | 4 +- lib/components/Shared/PageWindowTitleBar.dart | 149 +++--------------- lib/main.dart | 2 +- 7 files changed, 59 insertions(+), 156 deletions(-) diff --git a/lib/components/Artist/ArtistProfile.dart b/lib/components/Artist/ArtistProfile.dart index bf9150c19..e5924e02d 100644 --- a/lib/components/Artist/ArtistProfile.dart +++ b/lib/components/Artist/ArtistProfile.dart @@ -54,8 +54,8 @@ class ArtistProfile extends HookConsumerWidget { return SafeArea( child: PlatformScaffold( - appBar: const PageWindowTitleBar( - leading: PlatformBackButton(), + appBar: PageWindowTitleBar( + leading: const PlatformBackButton(), ), body: HookBuilder( builder: (context) { diff --git a/lib/components/Home/Shell.dart b/lib/components/Home/Shell.dart index 2d24a7f82..7518cddc3 100644 --- a/lib/components/Home/Shell.dart +++ b/lib/components/Home/Shell.dart @@ -13,7 +13,7 @@ import 'package:spotube/hooks/useUpdateChecker.dart'; import 'package:spotube/provider/Downloader.dart'; import 'package:spotube/utils/platform.dart'; -const _path = { +const rootPaths = { 0: "/", 1: "/search", 2: "/library", @@ -64,34 +64,40 @@ class Shell extends HookConsumerWidget { return null; }, [backgroundColor]); - final allowedPath = _path.values.contains(GoRouter.of(context).location); - final preferredSize = - allowedPath ? PageWindowTitleBar.staticPreferredSize : Size.zero; - return Scaffold( - appBar: kIsDesktop - ? PreferredSize( - preferredSize: preferredSize, - child: AnimatedContainer( + final allowedPath = + rootPaths.values.contains(GoRouter.of(context).location); + final titleBar = PageWindowTitleBar( + backgroundColor: + platform == TargetPlatform.android ? Colors.transparent : null, + ); + final preferredSize = allowedPath ? titleBar.preferredSize : Size.zero; + var appBar = kIsDesktop + ? PreferredSize( + preferredSize: preferredSize, + child: AnimatedContainer( + duration: const Duration(milliseconds: 250), + height: allowedPath ? titleBar.preferredSize.height : 0, + child: AnimatedOpacity( duration: const Duration(milliseconds: 250), - height: allowedPath - ? PageWindowTitleBar.staticPreferredSize.height - : 0, - child: AnimatedOpacity( - duration: const Duration(milliseconds: 250), - opacity: allowedPath ? 1 : 0, - child: PageWindowTitleBar(preferredSize: preferredSize), - ), + opacity: allowedPath ? 1 : 0, + child: titleBar, ), - ) - : null, - extendBodyBehindAppBar: true, + ), + ) + : null; + return PlatformScaffold( + appBar: platform == TargetPlatform.windows ? appBar : null, + extendBodyBehindAppBar: false, body: Sidebar( selectedIndex: index.value, onSelectedIndexChanged: (i) { index.value = i; - GoRouter.of(context).go(_path[index.value]!); + GoRouter.of(context).go(rootPaths[index.value]!); }, - child: child, + child: PlatformScaffold( + appBar: platform != TargetPlatform.windows ? appBar : null, + body: child, + ), ), extendBody: true, bottomNavigationBar: Column( @@ -102,7 +108,7 @@ class Shell extends HookConsumerWidget { selectedIndex: index.value, onSelectedIndexChanged: (selectedIndex) { index.value = selectedIndex; - GoRouter.of(context).go(_path[selectedIndex]!); + GoRouter.of(context).go(rootPaths[selectedIndex]!); }, ), ], diff --git a/lib/components/Home/Sidebar.dart b/lib/components/Home/Sidebar.dart index 6cda41d63..673fe4f95 100644 --- a/lib/components/Home/Sidebar.dart +++ b/lib/components/Home/Sidebar.dart @@ -110,7 +110,7 @@ class Sidebar extends HookConsumerWidget { expanded: extended.value, header: Column( children: [ - if (kIsDesktop) + if (kIsMacOS) SizedBox( height: appWindow.titleBarHeight, width: extended.value ? 256 : 80, diff --git a/lib/components/Login/TokenLogin.dart b/lib/components/Login/TokenLogin.dart index ad5b51d73..8528d3d01 100644 --- a/lib/components/Login/TokenLogin.dart +++ b/lib/components/Login/TokenLogin.dart @@ -16,7 +16,7 @@ class TokenLogin extends HookConsumerWidget { return SafeArea( child: Scaffold( - appBar: const PageWindowTitleBar(leading: PlatformBackButton()), + appBar: PageWindowTitleBar(leading: PlatformBackButton()), body: SingleChildScrollView( child: Center( child: Container( diff --git a/lib/components/Playlist/PlaylistGenreView.dart b/lib/components/Playlist/PlaylistGenreView.dart index 94fb89c5f..892bca9bd 100644 --- a/lib/components/Playlist/PlaylistGenreView.dart +++ b/lib/components/Playlist/PlaylistGenreView.dart @@ -20,8 +20,8 @@ class PlaylistGenreView extends ConsumerWidget { @override Widget build(BuildContext context, ref) { return Scaffold( - appBar: const PageWindowTitleBar( - leading: PlatformBackButton(), + appBar: PageWindowTitleBar( + leading: const PlatformBackButton(), ), body: Column( children: [ diff --git a/lib/components/Shared/PageWindowTitleBar.dart b/lib/components/Shared/PageWindowTitleBar.dart index df4a0350b..88e857b43 100644 --- a/lib/components/Shared/PageWindowTitleBar.dart +++ b/lib/components/Shared/PageWindowTitleBar.dart @@ -1,132 +1,29 @@ -import 'package:bitsdojo_window/bitsdojo_window.dart'; -import 'package:fluent_ui/fluent_ui.dart' show FluentTheme; import 'package:flutter/material.dart'; import 'package:platform_ui/platform_ui.dart'; import 'package:spotube/utils/platform.dart'; -class TitleBarActionButtons extends StatelessWidget { - final Color? color; - const TitleBarActionButtons({ - Key? key, - this.color, - }) : super(key: key); - - @override - Widget build(BuildContext context) { - return TextButtonTheme( - data: TextButtonThemeData( - style: ButtonStyle( - splashFactory: NoSplash.splashFactory, - shape: MaterialStateProperty.all(const RoundedRectangleBorder()), - overlayColor: MaterialStateProperty.all(Colors.black12), - padding: MaterialStateProperty.all(EdgeInsets.zero), - minimumSize: MaterialStateProperty.all(const Size(50, 40)), - maximumSize: MaterialStateProperty.all(const Size(50, 40)), - ), - ), - child: IconTheme( - data: const IconThemeData(size: 16), - child: Row( - children: [ - TextButton( - onPressed: () { - appWindow.minimize(); - }, - style: ButtonStyle( - foregroundColor: MaterialStateProperty.all( - PlatformTheme.of(context).iconTheme?.color), - ), - child: Icon( - Icons.minimize_rounded, - color: color, - )), - TextButton( - onPressed: () async { - appWindow.maximizeOrRestore(); - }, - style: ButtonStyle( - foregroundColor: MaterialStateProperty.all( - PlatformTheme.of(context).iconTheme?.color), - ), - child: Icon( - Icons.crop_square_rounded, - color: color, - )), - TextButton( - onPressed: () { - appWindow.close(); - }, - style: ButtonStyle( - foregroundColor: MaterialStateProperty.all( - color ?? PlatformTheme.of(context).iconTheme?.color), - overlayColor: MaterialStateProperty.all(Colors.redAccent), - ), - child: const Icon( - Icons.close_rounded, - )), - ], - ), - ), - ); - } -} - -class PageWindowTitleBar extends StatelessWidget - implements PreferredSizeWidget { - final Widget? leading; - final Widget? center; - final Color? backgroundColor; - final Color? foregroundColor; - final Size? _preferredSize; - const PageWindowTitleBar({ - Key? key, - Size? preferredSize, - this.leading, - this.center, - this.backgroundColor, - this.foregroundColor, - }) : _preferredSize = preferredSize, - super(key: key); - - static Size get staticPreferredSize => Size.fromHeight( - (kIsDesktop ? appWindow.titleBarHeight : 35), - ); - - @override - Size get preferredSize => _preferredSize ?? staticPreferredSize; - - @override - Widget build(BuildContext context) { - if (kIsMobile) { - return PreferredSize( - preferredSize: const Size.fromHeight(300), - child: Container( - color: backgroundColor, - child: Row( - children: [ - if (leading != null) leading!, - Expanded(child: Center(child: center)), - ], - ), - ), - ); - } - return WindowTitleBarBox( - child: Container( - color: backgroundColor ?? - FluentTheme.maybeOf(context)?.micaBackgroundColor, - child: Row( - children: [ - if (kIsMacOS) - SizedBox( - width: MediaQuery.of(context).size.width * 0.045, - ), - if (leading != null) leading!, - Expanded(child: MoveWindow(child: Center(child: center))), - if (!kIsMacOS && !kIsMobile) const PlatformWindowButtons() +class PageWindowTitleBar extends PlatformAppBar { + PageWindowTitleBar({ + super.backgroundColor, + List? actions, + super.actionsIconTheme, + super.automaticallyImplyLeading = false, + super.centerTitle, + super.foregroundColor, + super.key, + super.leading, + super.leadingWidth, + Widget? center, + super.titleSpacing, + super.titleTextStyle, + super.titleWidth, + super.toolbarOpacity, + super.toolbarTextStyle, + }) : super( + actions: [ + ...?actions, + if (!kIsMacOS && !kIsMobile) const PlatformWindowButtons(), ], - ), - ), - ); - } + title: center, + ); } diff --git a/lib/main.dart b/lib/main.dart index 4939a7b54..9a421cd9b 100644 --- a/lib/main.dart +++ b/lib/main.dart @@ -236,7 +236,7 @@ class SpotubeState extends ConsumerState with WidgetsBindingObserver { macosDarkTheme: macosDarkTheme, themeMode: themeMode, windowButtonConfig: PlatformWindowButtonConfig( - isMaximized: appWindow.isMaximized, + isMaximized: () => appWindow.isMaximized, onClose: appWindow.close, onRestore: appWindow.restore, onMaximize: appWindow.maximize,