From e2027b1a32ed9382aa973938b121545c343e499e Mon Sep 17 00:00:00 2001 From: LittleSheep Date: Mon, 6 Jan 2025 22:57:44 +0800 Subject: [PATCH] :sparkles: Able to prefer sidebar to collapse --- assets/translations/en-US.json | 2 ++ assets/translations/zh-CN.json | 2 ++ assets/translations/zh-HK.json | 2 ++ assets/translations/zh-TW.json | 2 ++ lib/main.dart | 17 ++++++++++++++++- lib/providers/config.dart | 20 ++++++++++++++++++++ lib/screens/settings.dart | 13 +++++++++++++ lib/widgets/context_menu.dart | 9 +++++---- lib/widgets/navigation/app_scaffold.dart | 11 +++++++---- 9 files changed, 69 insertions(+), 9 deletions(-) diff --git a/assets/translations/en-US.json b/assets/translations/en-US.json index 6b6cbfc..e4b7a73 100644 --- a/assets/translations/en-US.json +++ b/assets/translations/en-US.json @@ -181,6 +181,8 @@ "settingsAppearance": "Appearance", "settingsAppBarTransparent": "Transparent App Bar", "settingsAppBarTransparentDescription": "Enable transparent effect for the app bar.", + "settingsDrawerPreferCollapse": "Prefer Drawer Collapse", + "settingsDrawerPreferCollapseDescription": "Make the drawer to collapse even when the screen is wide enough.", "settingsBackgroundImage": "Background Image", "settingsBackgroundImageDescription": "Set the background image that will be applied globally.", "settingsBackgroundImageClear": "Clear Existing Background Image", diff --git a/assets/translations/zh-CN.json b/assets/translations/zh-CN.json index b4868b8..f109dad 100644 --- a/assets/translations/zh-CN.json +++ b/assets/translations/zh-CN.json @@ -185,6 +185,8 @@ "settingsThemeMaterial3Description": "将应用主题设置为 Material 3 设计范式的主题。", "settingsAppBarTransparent": "透明顶栏", "settingsAppBarTransparentDescription": "为顶栏启用透明效果。", + "settingsDrawerPreferCollapse": "侧边栏偏好折叠", + "settingsDrawerPreferCollapseDescription": "将侧边栏优先折叠,即使屏幕宽度足够大去放下整个侧边栏。", "settingsColorScheme": "主题色", "settingsColorSchemeDescription": "设置应用主题色。", "settingsColorSeed": "预设色彩主题", diff --git a/assets/translations/zh-HK.json b/assets/translations/zh-HK.json index ce8c787..d656d83 100644 --- a/assets/translations/zh-HK.json +++ b/assets/translations/zh-HK.json @@ -185,6 +185,8 @@ "settingsThemeMaterial3Description": "將應用主題設置為 Material 3 設計範式的主題。", "settingsAppBarTransparent": "透明頂欄", "settingsAppBarTransparentDescription": "為頂欄啓用透明效果。", + "settingsDrawerPreferCollapse": "側邊欄偏好摺疊", + "settingsDrawerPreferCollapseDescription": "將側邊欄優先摺疊,即使屏幕寬度足夠大去放下整個側邊欄。", "settingsColorScheme": "主題色", "settingsColorSchemeDescription": "設置應用主題色。", "settingsColorSeed": "預設色彩主題", diff --git a/assets/translations/zh-TW.json b/assets/translations/zh-TW.json index 5ab094a..d0bb772 100644 --- a/assets/translations/zh-TW.json +++ b/assets/translations/zh-TW.json @@ -185,6 +185,8 @@ "settingsThemeMaterial3Description": "將應用主題設置為 Material 3 設計範式的主題。", "settingsAppBarTransparent": "透明頂欄", "settingsAppBarTransparentDescription": "為頂欄啟用透明效果。", + "settingsDrawerPreferCollapse": "側邊欄偏好摺疊", + "settingsDrawerPreferCollapseDescription": "將側邊欄優先摺疊,即使屏幕寬度足夠大去放下整個側邊欄。", "settingsColorScheme": "主題色", "settingsColorSchemeDescription": "設置應用主題色。", "settingsColorSeed": "預設色彩主題", diff --git a/lib/main.dart b/lib/main.dart index b3761c8..7f2c291 100644 --- a/lib/main.dart +++ b/lib/main.dart @@ -258,6 +258,10 @@ class _AppSplashScreenState extends State<_AppSplashScreen> { Future _initialize() async { try { + final cfg = context.read(); + WidgetsBinding.instance.addPostFrameCallback((_) { + cfg.calcDrawerSize(context); + }); final home = context.read(); await home.initialize(); if (!mounted) return; @@ -298,6 +302,17 @@ class _AppSplashScreenState extends State<_AppSplashScreen> { @override Widget build(BuildContext context) { - return widget.child; + final cfg = context.read(); + return NotificationListener( + onNotification: (notification) { + WidgetsBinding.instance.addPostFrameCallback((_) { + cfg.calcDrawerSize(context); + }); + return false; + }, + child: SizeChangedLayoutNotifier( + child: widget.child, + ), + ); } } diff --git a/lib/providers/config.dart b/lib/providers/config.dart index 78fafc0..b9eb021 100644 --- a/lib/providers/config.dart +++ b/lib/providers/config.dart @@ -1,5 +1,6 @@ import 'package:flutter/material.dart'; import 'package:provider/provider.dart'; +import 'package:responsive_framework/responsive_framework.dart'; import 'package:shared_preferences/shared_preferences.dart'; import 'package:surface/providers/widget.dart'; @@ -12,6 +13,7 @@ const kNetworkServerStoreKey = 'app_server_url'; const kAppbarTransparentStoreKey = 'app_bar_transparent'; const kAppBackgroundStoreKey = 'app_has_background'; const kAppColorSchemeStoreKey = 'app_color_scheme'; +const kAppDrawerPreferCollapse = 'app_drawer_prefer_collapse'; const Map kImageQualityLevel = { 'settingsImageQualityLowest': FilterQuality.none, @@ -33,6 +35,24 @@ class ConfigProvider extends ChangeNotifier { prefs = await SharedPreferences.getInstance(); } + bool drawerIsCollapsed = false; + bool drawerIsExpanded = false; + + void calcDrawerSize(BuildContext context) { + final rpb = ResponsiveBreakpoints.of(context); + final newDrawerIsCollapsed = rpb.smallerOrEqualTo(MOBILE); + final newDrawerIsExpanded = rpb.largerThan(TABLET) + ? (prefs.getBool(kAppDrawerPreferCollapse) ?? false) + ? false + : true + : false; + if (newDrawerIsExpanded != drawerIsExpanded || newDrawerIsCollapsed != drawerIsCollapsed) { + drawerIsExpanded = newDrawerIsExpanded; + drawerIsCollapsed = newDrawerIsCollapsed; + notifyListeners(); + } + } + FilterQuality get imageQuality { return kImageQualityLevel.values.elementAtOrNull(prefs.getInt('app_image_quality') ?? 3) ?? FilterQuality.high; } diff --git a/lib/screens/settings.dart b/lib/screens/settings.dart index 0bd7dc1..297030b 100644 --- a/lib/screens/settings.dart +++ b/lib/screens/settings.dart @@ -240,6 +240,19 @@ class _SettingsScreenState extends State { setState(() {}); }, ), + CheckboxListTile( + secondary: const Icon(Symbols.left_panel_close), + title: Text('settingsDrawerPreferCollapse').tr(), + subtitle: Text('settingsDrawerPreferCollapseDescription').tr(), + contentPadding: const EdgeInsets.only(left: 24, right: 17), + value: _prefs.getBool(kAppDrawerPreferCollapse) ?? false, + onChanged: (value) { + _prefs.setBool(kAppDrawerPreferCollapse, value ?? false); + final cfg = context.read(); + cfg.calcDrawerSize(context); + setState(() {}); + }, + ), ], ), Column( diff --git a/lib/widgets/context_menu.dart b/lib/widgets/context_menu.dart index 2b705e1..86c5819 100644 --- a/lib/widgets/context_menu.dart +++ b/lib/widgets/context_menu.dart @@ -1,7 +1,9 @@ import 'package:flutter/material.dart'; import 'package:flutter_animate/flutter_animate.dart'; import 'package:flutter_context_menu/flutter_context_menu.dart'; +import 'package:provider/provider.dart'; import 'package:responsive_framework/responsive_framework.dart'; +import 'package:surface/providers/config.dart'; class ContextMenuArea extends StatelessWidget { final ContextMenu contextMenu; @@ -22,11 +24,10 @@ class ContextMenuArea extends StatelessWidget { return Listener( onPointerDown: (event) { mousePosition = event.position; - final isCollapseDrawer = ResponsiveBreakpoints.of(context).smallerOrEqualTo(MOBILE); - if (!isCollapseDrawer) { - final isExpandDrawer = ResponsiveBreakpoints.of(context).largerThan(TABLET); + final cfg = context.read(); + if (!cfg.drawerIsCollapsed) { // Leave padding for side navigation - mousePosition = isExpandDrawer + mousePosition = cfg.drawerIsExpanded ? mousePosition.copyWith(dx: mousePosition.dx - 304 * 2) : mousePosition.copyWith(dx: mousePosition.dx - 72 * 2); } diff --git a/lib/widgets/navigation/app_scaffold.dart b/lib/widgets/navigation/app_scaffold.dart index c578432..5cb9387 100644 --- a/lib/widgets/navigation/app_scaffold.dart +++ b/lib/widgets/navigation/app_scaffold.dart @@ -6,8 +6,10 @@ import 'package:flutter/foundation.dart'; import 'package:flutter/material.dart'; import 'package:go_router/go_router.dart'; import 'package:google_fonts/google_fonts.dart'; +import 'package:provider/provider.dart'; import 'package:responsive_framework/responsive_framework.dart'; import 'package:styled_widget/styled_widget.dart'; +import 'package:surface/providers/config.dart'; import 'package:surface/providers/navigation.dart'; import 'package:surface/widgets/connection_indicator.dart'; import 'package:surface/widgets/dialog.dart'; @@ -57,10 +59,11 @@ class AppRootScaffold extends StatelessWidget { @override Widget build(BuildContext context) { + final cfg = context.watch(); final devicePixelRatio = MediaQuery.of(context).devicePixelRatio; - final isCollapseDrawer = ResponsiveBreakpoints.of(context).smallerOrEqualTo(MOBILE); - final isExpandDrawer = ResponsiveBreakpoints.of(context).largerThan(TABLET); + final isCollapseDrawer = cfg.drawerIsCollapsed; + final isExpandedDrawer = cfg.drawerIsExpanded; final routeName = GoRouter.of(context).routerDelegate.currentConfiguration.last.route.name; final isShowBottomNavigation = NavigationProvider.kShowBottomNavScreen.contains(routeName) @@ -81,7 +84,7 @@ class AppRootScaffold extends StatelessWidget { ), ), ), - child: isExpandDrawer ? AppNavigationDrawer(elevation: 0) : AppRailNavigation(), + child: isExpandedDrawer ? AppNavigationDrawer(elevation: 0) : AppRailNavigation(), ), Expanded(child: body), ], @@ -147,7 +150,7 @@ class AppRootScaffold extends StatelessWidget { Expanded(child: innerWidget), ], ), - drawer: !isExpandDrawer ? AppNavigationDrawer() : null, + drawer: !isExpandedDrawer ? AppNavigationDrawer() : null, drawerEdgeDragWidth: isPopable ? 0 : null, bottomNavigationBar: isShowBottomNavigation ? AppBottomNavigationBar() : null, ),