Merge pull request #759 from ente-io/settings-highlight-expanded
Settings menu: Highlight expanded section
This commit is contained in:
commit
28ea0fe49a
4 changed files with 109 additions and 4 deletions
|
@ -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/captioned_text_widget.dart';
|
||||||
import 'package:photos/ui/components/menu_item_widget.dart';
|
import 'package:photos/ui/components/menu_item_widget.dart';
|
||||||
import 'package:photos/ui/settings/common_settings.dart';
|
import 'package:photos/ui/settings/common_settings.dart';
|
||||||
|
import 'package:photos/ui/settings/inherited_settings_state.dart';
|
||||||
|
|
||||||
class ExpandableMenuItemWidget extends StatefulWidget {
|
class ExpandableMenuItemWidget extends StatefulWidget {
|
||||||
final String title;
|
final String title;
|
||||||
|
@ -37,6 +38,11 @@ class _ExpandableMenuItemWidgetState extends State<ExpandableMenuItemWidget> {
|
||||||
|
|
||||||
@override
|
@override
|
||||||
Widget build(BuildContext context) {
|
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 enteColorScheme = Theme.of(context).colorScheme.enteTheme.colorScheme;
|
||||||
final backgroundColor =
|
final backgroundColor =
|
||||||
MediaQuery.of(context).platformBrightness == Brightness.light
|
MediaQuery.of(context).platformBrightness == Brightness.light
|
||||||
|
@ -59,10 +65,19 @@ class _ExpandableMenuItemWidgetState extends State<ExpandableMenuItemWidget> {
|
||||||
captionedTextWidget: CaptionedTextWidget(
|
captionedTextWidget: CaptionedTextWidget(
|
||||||
title: widget.title,
|
title: widget.title,
|
||||||
makeTextBold: true,
|
makeTextBold: true,
|
||||||
|
textColor: isSuppressed
|
||||||
|
? enteColorScheme.textMuted
|
||||||
|
: enteColorScheme.textBase,
|
||||||
),
|
),
|
||||||
isExpandable: true,
|
isExpandable: true,
|
||||||
leadingIcon: widget.leadingIcon,
|
leadingIcon: widget.leadingIcon,
|
||||||
|
leadingIconColor: isSuppressed
|
||||||
|
? enteColorScheme.strokeMuted
|
||||||
|
: enteColorScheme.strokeBase,
|
||||||
trailingIcon: Icons.expand_more,
|
trailingIcon: Icons.expand_more,
|
||||||
|
trailingIconColor: isSuppressed
|
||||||
|
? enteColorScheme.strokeMuted
|
||||||
|
: enteColorScheme.strokeBase,
|
||||||
menuItemColor: enteColorScheme.fillFaint,
|
menuItemColor: enteColorScheme.fillFaint,
|
||||||
expandableController: expandableController,
|
expandableController: expandableController,
|
||||||
),
|
),
|
||||||
|
@ -81,6 +96,12 @@ class _ExpandableMenuItemWidgetState extends State<ExpandableMenuItemWidget> {
|
||||||
}
|
}
|
||||||
|
|
||||||
void _expandableControllerListener() {
|
void _expandableControllerListener() {
|
||||||
setState(() {});
|
setState(() {
|
||||||
|
if (expandableController.expanded) {
|
||||||
|
InheritedSettingsState.of(context).increment();
|
||||||
|
} else {
|
||||||
|
InheritedSettingsState.of(context).decrement();
|
||||||
|
}
|
||||||
|
});
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -18,6 +18,7 @@ class MenuItemWidget extends StatefulWidget {
|
||||||
/// trailing icon can be passed without size as default size set by
|
/// trailing icon can be passed without size as default size set by
|
||||||
/// flutter is what this component expects
|
/// flutter is what this component expects
|
||||||
final IconData? trailingIcon;
|
final IconData? trailingIcon;
|
||||||
|
final Color? trailingIconColor;
|
||||||
final Widget? trailingWidget;
|
final Widget? trailingWidget;
|
||||||
final bool trailingIconIsMuted;
|
final bool trailingIconIsMuted;
|
||||||
final VoidCallback? onTap;
|
final VoidCallback? onTap;
|
||||||
|
@ -41,6 +42,7 @@ class MenuItemWidget extends StatefulWidget {
|
||||||
this.leadingIconSize = 20.0,
|
this.leadingIconSize = 20.0,
|
||||||
this.leadingIconWidget,
|
this.leadingIconWidget,
|
||||||
this.trailingIcon,
|
this.trailingIcon,
|
||||||
|
this.trailingIconColor,
|
||||||
this.trailingWidget,
|
this.trailingWidget,
|
||||||
this.trailingIconIsMuted = false,
|
this.trailingIconIsMuted = false,
|
||||||
this.onTap,
|
this.onTap,
|
||||||
|
@ -167,7 +169,10 @@ class _MenuItemWidgetState extends State<MenuItemWidget> {
|
||||||
switchInCurve: Curves.easeOut,
|
switchInCurve: Curves.easeOut,
|
||||||
child: isExpanded
|
child: isExpanded
|
||||||
? const SizedBox.shrink()
|
? const SizedBox.shrink()
|
||||||
: Icon(widget.trailingIcon),
|
: Icon(
|
||||||
|
widget.trailingIcon,
|
||||||
|
color: widget.trailingIconColor,
|
||||||
|
),
|
||||||
),
|
),
|
||||||
)
|
)
|
||||||
: widget.trailingIcon != null
|
: widget.trailingIcon != null
|
||||||
|
@ -175,7 +180,7 @@ class _MenuItemWidgetState extends State<MenuItemWidget> {
|
||||||
widget.trailingIcon,
|
widget.trailingIcon,
|
||||||
color: widget.trailingIconIsMuted
|
color: widget.trailingIconIsMuted
|
||||||
? enteColorScheme.strokeMuted
|
? enteColorScheme.strokeMuted
|
||||||
: null,
|
: widget.trailingIconColor,
|
||||||
)
|
)
|
||||||
: widget.trailingWidget ?? const SizedBox.shrink(),
|
: widget.trailingWidget ?? const SizedBox.shrink(),
|
||||||
],
|
],
|
||||||
|
|
76
lib/ui/settings/inherited_settings_state.dart
Normal file
76
lib/ui/settings/inherited_settings_state.dart
Normal file
|
@ -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;
|
||||||
|
}
|
||||||
|
}
|
|
@ -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/backup_section_widget.dart';
|
||||||
import 'package:photos/ui/settings/debug_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/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/security_section_widget.dart';
|
||||||
import 'package:photos/ui/settings/settings_title_bar_widget.dart';
|
import 'package:photos/ui/settings/settings_title_bar_widget.dart';
|
||||||
import 'package:photos/ui/settings/social_section_widget.dart';
|
import 'package:photos/ui/settings/social_section_widget.dart';
|
||||||
|
@ -33,7 +34,9 @@ class SettingsPage extends StatelessWidget {
|
||||||
return Scaffold(
|
return Scaffold(
|
||||||
body: Container(
|
body: Container(
|
||||||
color: enteColorScheme.backdropMuted,
|
color: enteColorScheme.backdropMuted,
|
||||||
child: _getBody(context, enteColorScheme),
|
child: SettingsStateContainer(
|
||||||
|
child: _getBody(context, enteColorScheme),
|
||||||
|
),
|
||||||
),
|
),
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
Loading…
Add table
Reference in a new issue