Browse Source

Merge pull request #759 from ente-io/settings-highlight-expanded

Settings menu: Highlight expanded section
Neeraj Gupta 2 years ago
parent
commit
28ea0fe49a

+ 22 - 1
lib/ui/components/expandable_menu_item_widget.dart

@@ -4,6 +4,7 @@ import 'package:photos/ente_theme_data.dart';
 import 'package:photos/ui/components/captioned_text_widget.dart';
 import 'package:photos/ui/components/menu_item_widget.dart';
 import 'package:photos/ui/settings/common_settings.dart';
+import 'package:photos/ui/settings/inherited_settings_state.dart';
 
 class ExpandableMenuItemWidget extends StatefulWidget {
   final String title;
@@ -37,6 +38,11 @@ class _ExpandableMenuItemWidgetState extends State<ExpandableMenuItemWidget> {
 
   @override
   Widget build(BuildContext context) {
+    final isAnySectionExpanded =
+        InheritedSettingsState.maybeOf(context)?.isAnySectionExpanded ?? false;
+    final isCurrentSectionExpanded = expandableController.expanded;
+    final isSuppressed = isAnySectionExpanded && !isCurrentSectionExpanded;
+
     final enteColorScheme = Theme.of(context).colorScheme.enteTheme.colorScheme;
     final backgroundColor =
         MediaQuery.of(context).platformBrightness == Brightness.light
@@ -59,10 +65,19 @@ class _ExpandableMenuItemWidgetState extends State<ExpandableMenuItemWidget> {
                 captionedTextWidget: CaptionedTextWidget(
                   title: widget.title,
                   makeTextBold: true,
+                  textColor: isSuppressed
+                      ? enteColorScheme.textMuted
+                      : enteColorScheme.textBase,
                 ),
                 isExpandable: true,
                 leadingIcon: widget.leadingIcon,
+                leadingIconColor: isSuppressed
+                    ? enteColorScheme.strokeMuted
+                    : enteColorScheme.strokeBase,
                 trailingIcon: Icons.expand_more,
+                trailingIconColor: isSuppressed
+                    ? enteColorScheme.strokeMuted
+                    : enteColorScheme.strokeBase,
                 menuItemColor: enteColorScheme.fillFaint,
                 expandableController: expandableController,
               ),
@@ -81,6 +96,12 @@ class _ExpandableMenuItemWidgetState extends State<ExpandableMenuItemWidget> {
   }
 
   void _expandableControllerListener() {
-    setState(() {});
+    setState(() {
+      if (expandableController.expanded) {
+        InheritedSettingsState.of(context).increment();
+      } else {
+        InheritedSettingsState.of(context).decrement();
+      }
+    });
   }
 }

+ 7 - 2
lib/ui/components/menu_item_widget.dart

@@ -18,6 +18,7 @@ class MenuItemWidget extends StatefulWidget {
   /// trailing icon can be passed without size as default size set by
   /// flutter is what this component expects
   final IconData? trailingIcon;
+  final Color? trailingIconColor;
   final Widget? trailingWidget;
   final bool trailingIconIsMuted;
   final VoidCallback? onTap;
@@ -41,6 +42,7 @@ class MenuItemWidget extends StatefulWidget {
     this.leadingIconSize = 20.0,
     this.leadingIconWidget,
     this.trailingIcon,
+    this.trailingIconColor,
     this.trailingWidget,
     this.trailingIconIsMuted = false,
     this.onTap,
@@ -167,7 +169,10 @@ class _MenuItemWidgetState extends State<MenuItemWidget> {
                     switchInCurve: Curves.easeOut,
                     child: isExpanded
                         ? const SizedBox.shrink()
-                        : Icon(widget.trailingIcon),
+                        : Icon(
+                            widget.trailingIcon,
+                            color: widget.trailingIconColor,
+                          ),
                   ),
                 )
               : widget.trailingIcon != null
@@ -175,7 +180,7 @@ class _MenuItemWidgetState extends State<MenuItemWidget> {
                       widget.trailingIcon,
                       color: widget.trailingIconIsMuted
                           ? enteColorScheme.strokeMuted
-                          : null,
+                          : widget.trailingIconColor,
                     )
                   : widget.trailingWidget ?? const SizedBox.shrink(),
         ],

+ 76 - 0
lib/ui/settings/inherited_settings_state.dart

@@ -0,0 +1,76 @@
+import 'package:flutter/widgets.dart';
+
+/// StatefulWidget that wraps InheritedSettingsState
+class SettingsStateContainer extends StatefulWidget {
+  const SettingsStateContainer({
+    Key? key,
+    required this.child,
+  }) : super(key: key);
+  final Widget child;
+
+  @override
+  State<SettingsStateContainer> createState() => _SettingsState();
+}
+
+class _SettingsState extends State<SettingsStateContainer> {
+  int _expandedSectionCount = 0;
+
+  void increment() {
+    setState(() {
+      _expandedSectionCount += 1;
+    });
+  }
+
+  void decrement() {
+    setState(() {
+      _expandedSectionCount -= 1;
+    });
+  }
+
+  @override
+  Widget build(BuildContext context) {
+    return InheritedSettingsState(
+      expandedSectionCount: _expandedSectionCount,
+      increment: increment,
+      decrement: decrement,
+      child: widget.child,
+    );
+  }
+}
+
+/// Keep track of the number of expanded sections in an entire menu tree.
+///
+/// Since this is an InheritedWidget, subsections can obtain it from the context
+/// and use the current expansion state to style themselves differently if
+/// needed.
+///
+/// Example usage:
+///
+///     InheritedSettingsState.of(context).increment()
+///
+class InheritedSettingsState extends InheritedWidget {
+  final int expandedSectionCount;
+  final void Function() increment;
+  final void Function() decrement;
+
+  const InheritedSettingsState({
+    Key? key,
+    required this.expandedSectionCount,
+    required this.increment,
+    required this.decrement,
+    required Widget child,
+  }) : super(key: key, child: child);
+
+  bool get isAnySectionExpanded => expandedSectionCount > 0;
+
+  static InheritedSettingsState of(BuildContext context) =>
+      context.dependOnInheritedWidgetOfExactType<InheritedSettingsState>()!;
+
+  static InheritedSettingsState? maybeOf(BuildContext context) =>
+      context.dependOnInheritedWidgetOfExactType<InheritedSettingsState>();
+
+  @override
+  bool updateShouldNotify(covariant InheritedSettingsState oldWidget) {
+    return isAnySectionExpanded != oldWidget.isAnySectionExpanded;
+  }
+}

+ 4 - 1
lib/ui/settings_page.dart

@@ -15,6 +15,7 @@ import 'package:photos/ui/settings/app_version_widget.dart';
 import 'package:photos/ui/settings/backup_section_widget.dart';
 import 'package:photos/ui/settings/debug_section_widget.dart';
 import 'package:photos/ui/settings/general_section_widget.dart';
+import 'package:photos/ui/settings/inherited_settings_state.dart';
 import 'package:photos/ui/settings/security_section_widget.dart';
 import 'package:photos/ui/settings/settings_title_bar_widget.dart';
 import 'package:photos/ui/settings/social_section_widget.dart';
@@ -33,7 +34,9 @@ class SettingsPage extends StatelessWidget {
     return Scaffold(
       body: Container(
         color: enteColorScheme.backdropMuted,
-        child: _getBody(context, enteColorScheme),
+        child: SettingsStateContainer(
+          child: _getBody(context, enteColorScheme),
+        ),
       ),
     );
   }