From bd18f198217538f0089d5a1c4288dd97f982661b Mon Sep 17 00:00:00 2001 From: Kingkor Roy Tirtho Date: Thu, 8 Dec 2022 14:21:51 +0600 Subject: [PATCH] fix(windows): windows global title bar --- .../shared/page_window_title_bar.dart | 132 ++++++++++++++---- lib/pages/library/library.dart | 42 +++--- lib/pages/lyrics/lyrics.dart | 52 +++---- lib/pages/root/root_app.dart | 4 + 4 files changed, 159 insertions(+), 71 deletions(-) diff --git a/lib/components/shared/page_window_title_bar.dart b/lib/components/shared/page_window_title_bar.dart index 2aadc7a69..991a5b45a 100644 --- a/lib/components/shared/page_window_title_bar.dart +++ b/lib/components/shared/page_window_title_bar.dart @@ -1,40 +1,114 @@ import 'package:bitsdojo_window/bitsdojo_window.dart'; import 'package:flutter/material.dart'; +import 'package:flutter_hooks/flutter_hooks.dart'; +import 'package:hooks_riverpod/hooks_riverpod.dart'; import 'package:platform_ui/platform_ui.dart'; import 'package:spotube/utils/platform.dart'; -class PageWindowTitleBar extends PlatformAppBar { +class PageWindowTitleBar extends StatefulHookWidget with PreferredSizeWidget { + final Widget? leading; + final bool automaticallyImplyLeading; + final Widget? title; + final List? actions; + final Color? backgroundColor; + final Color? foregroundColor; + final IconThemeData? actionsIconTheme; + final bool? centerTitle; + final double? titleSpacing; + final double toolbarOpacity; + final double? leadingWidth; + final TextStyle? toolbarTextStyle; + final TextStyle? titleTextStyle; + final double? titleWidth; + final Widget? center; + final bool hideWhenWindows; + 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) - platform == TargetPlatform.linux - ? MoveWindow(child: const PlatformWindowButtons()) - : const PlatformWindowButtons(), - ], - title: platform == TargetPlatform.linux - ? MoveWindow(child: Center(child: center)) - : center, - ); + Key? key, + this.title, + this.actions, + this.center, + this.toolbarOpacity = 1, + this.backgroundColor, + this.actionsIconTheme, + this.automaticallyImplyLeading = false, + this.centerTitle, + this.foregroundColor, + this.leading, + this.leadingWidth, + this.titleSpacing, + this.titleTextStyle, + this.titleWidth, + this.toolbarTextStyle, + this.hideWhenWindows = true, + }) : super(key: key); + + @override + Size get preferredSize => Size.fromHeight( + platform == TargetPlatform.windows ? 33 : kToolbarHeight, + ); + + @override + State createState() => _PageWindowTitleBarState(); +} +class _PageWindowTitleBarState extends State { @override Widget build(BuildContext context) { - return MoveWindow(child: super.build(context)); + useEffect(() { + if (platform == TargetPlatform.windows && + widget.hideWhenWindows && + Navigator.of(context).canPop()) { + final entry = OverlayEntry( + builder: (context) => const Positioned( + left: 5, + top: 5, + child: PlatformBackButton(), + ), + ); + + WidgetsBinding.instance.addPostFrameCallback((_) { + Overlay.of(context)?.insert(entry); + }); + + return () { + entry.remove(); + }; + } + return null; + }, [platform, widget.hideWhenWindows]); + + var appBar = PlatformAppBar( + actions: [ + ...?widget.actions, + if (!kIsMacOS && !kIsMobile) + platform == TargetPlatform.linux + ? MoveWindow(child: const PlatformWindowButtons()) + : const PlatformWindowButtons(), + ], + title: platform == TargetPlatform.linux + ? MoveWindow(child: Center(child: widget.center)) + : widget.center, + toolbarOpacity: widget.toolbarOpacity, + backgroundColor: widget.backgroundColor, + actionsIconTheme: widget.actionsIconTheme, + automaticallyImplyLeading: widget.automaticallyImplyLeading, + centerTitle: widget.centerTitle, + foregroundColor: widget.foregroundColor, + leading: widget.leading, + leadingWidth: widget.leadingWidth, + titleSpacing: widget.titleSpacing, + titleTextStyle: widget.titleTextStyle, + titleWidth: widget.titleWidth, + toolbarTextStyle: widget.toolbarTextStyle, + ); + + if (platform == TargetPlatform.windows && widget.hideWhenWindows) { + return const SizedBox.shrink(); + } + + return MoveWindow( + child: appBar, + ); } } diff --git a/lib/pages/library/library.dart b/lib/pages/library/library.dart index 7a70740f1..cc10567d1 100644 --- a/lib/pages/library/library.dart +++ b/lib/pages/library/library.dart @@ -23,26 +23,32 @@ class LibraryPage extends HookConsumerWidget { const UserAlbums(), ][index.value]; + var tabbar = PlatformTabBar( + androidIsScrollable: true, + selectedIndex: index.value, + onSelectedIndexChanged: (value) => index.value = value, + isNavigational: + PlatformProperty.byPlatformGroup(mobile: false, desktop: true), + tabs: [ + PlatformTab(label: 'Playlists', icon: const SizedBox.shrink()), + PlatformTab(label: 'Tracks', icon: const SizedBox.shrink()), + PlatformTab(label: 'Downloads', icon: const SizedBox.shrink()), + PlatformTab(label: 'Artists', icon: const SizedBox.shrink()), + PlatformTab(label: 'Albums', icon: const SizedBox.shrink()), + ], + ); return SafeArea( child: PlatformScaffold( - appBar: PageWindowTitleBar( - titleWidth: 347, - centerTitle: true, - center: PlatformTabBar( - androidIsScrollable: true, - selectedIndex: index.value, - onSelectedIndexChanged: (value) => index.value = value, - isNavigational: - PlatformProperty.byPlatformGroup(mobile: false, desktop: true), - tabs: [ - PlatformTab(label: 'Playlists', icon: const SizedBox.shrink()), - PlatformTab(label: 'Tracks', icon: const SizedBox.shrink()), - PlatformTab(label: 'Downloads', icon: const SizedBox.shrink()), - PlatformTab(label: 'Artists', icon: const SizedBox.shrink()), - PlatformTab(label: 'Albums', icon: const SizedBox.shrink()), - ], - ), - ), + appBar: platform == TargetPlatform.windows + ? PreferredSize( + preferredSize: const Size.fromHeight(40), + child: tabbar, + ) + : PageWindowTitleBar( + titleWidth: 347, + centerTitle: true, + center: tabbar, + ), body: body, ), ); diff --git a/lib/pages/lyrics/lyrics.dart b/lib/pages/lyrics/lyrics.dart index 07ecde2bf..536a8fcda 100644 --- a/lib/pages/lyrics/lyrics.dart +++ b/lib/pages/lyrics/lyrics.dart @@ -42,33 +42,37 @@ class LyricsPage extends HookConsumerWidget { GeniusLyrics(palette: palette), ][index.value]; + final tabbar = PreferredSize( + preferredSize: const Size.fromHeight(40), + child: PlatformTabBar( + isNavigational: PlatformProperty.only(linux: true, other: false), + selectedIndex: index.value, + onSelectedIndexChanged: (value) => index.value = value, + backgroundColor: PlatformTheme.of(context).scaffoldBackgroundColor, + tabs: [ + PlatformTab( + label: "Synced", + icon: const SizedBox.shrink(), + color: PlatformTextTheme.of(context).caption?.color, + ), + PlatformTab( + label: "Genius", + icon: const SizedBox.shrink(), + color: PlatformTextTheme.of(context).caption?.color, + ), + ], + ), + ); return PlatformScaffold( extendBodyBehindAppBar: true, appBar: !kIsMacOS - ? PageWindowTitleBar( - toolbarOpacity: 0, - backgroundColor: Colors.transparent, - center: PlatformTabBar( - isNavigational: - PlatformProperty.only(linux: true, other: false), - selectedIndex: index.value, - onSelectedIndexChanged: (value) => index.value = value, - backgroundColor: - PlatformTheme.of(context).scaffoldBackgroundColor, - tabs: [ - PlatformTab( - label: "Synced", - icon: const SizedBox.shrink(), - color: PlatformTextTheme.of(context).caption?.color, - ), - PlatformTab( - label: "Genius", - icon: const SizedBox.shrink(), - color: PlatformTextTheme.of(context).caption?.color, - ), - ], - ), - ) + ? (platform != TargetPlatform.windows + ? PageWindowTitleBar( + toolbarOpacity: 0, + backgroundColor: Colors.transparent, + center: tabbar, + ) + : tabbar) : null, body: Container( clipBehavior: Clip.hardEdge, diff --git a/lib/pages/root/root_app.dart b/lib/pages/root/root_app.dart index 0973e4ef1..847aa9489 100644 --- a/lib/pages/root/root_app.dart +++ b/lib/pages/root/root_app.dart @@ -8,6 +8,7 @@ import 'package:spotube/components/shared/dialogs/replace_downloaded_dialog.dart import 'package:spotube/components/root/bottom_player.dart'; import 'package:spotube/components/root/sidebar.dart'; import 'package:spotube/components/root/spotube_navigation_bar.dart'; +import 'package:spotube/components/shared/page_window_title_bar.dart'; import 'package:spotube/hooks/use_update_checker.dart'; import 'package:spotube/provider/downloader_provider.dart'; @@ -63,6 +64,9 @@ class RootApp extends HookConsumerWidget { }, [backgroundColor]); return PlatformScaffold( + appBar: platform == TargetPlatform.windows + ? PageWindowTitleBar(hideWhenWindows: false) + : null, body: Sidebar( selectedIndex: index.value, onSelectedIndexChanged: (i) {