From beee9d8a6e6999a5b5f7313c93c946ed74f2d27c Mon Sep 17 00:00:00 2001 From: Vadim <44135514+vodemn@users.noreply.github.com> Date: Mon, 6 Jan 2025 15:00:26 +0100 Subject: [PATCH] deleted `ExpandableSectionList` --- .../widget_dialog_section_name.dart | 56 ------ .../widget_expandable_section_list_item.dart | 184 ------------------ .../widget_expandable_section_list.dart | 95 --------- 3 files changed, 335 deletions(-) delete mode 100644 lib/screens/settings/components/shared/expandable_section_list/components/dialog_section_name/widget_dialog_section_name.dart delete mode 100644 lib/screens/settings/components/shared/expandable_section_list/components/expandable_section_list_item/widget_expandable_section_list_item.dart delete mode 100644 lib/screens/settings/components/shared/expandable_section_list/widget_expandable_section_list.dart diff --git a/lib/screens/settings/components/shared/expandable_section_list/components/dialog_section_name/widget_dialog_section_name.dart b/lib/screens/settings/components/shared/expandable_section_list/components/dialog_section_name/widget_dialog_section_name.dart deleted file mode 100644 index 4fa2edc..0000000 --- a/lib/screens/settings/components/shared/expandable_section_list/components/dialog_section_name/widget_dialog_section_name.dart +++ /dev/null @@ -1,56 +0,0 @@ -import 'package:flutter/material.dart'; -import 'package:lightmeter/generated/l10n.dart'; -import 'package:lightmeter/res/dimens.dart'; - -class ExpandableSectionNameDialog extends StatefulWidget { - final String title; - final String hint; - final String initialValue; - - const ExpandableSectionNameDialog({ - this.initialValue = '', - required this.title, - required this.hint, - super.key, - }); - - @override - State createState() => _ExpandableSectionNameDialogState(); -} - -class _ExpandableSectionNameDialogState extends State { - late final _nameController = TextEditingController(text: widget.initialValue); - - @override - void dispose() { - _nameController.dispose(); - super.dispose(); - } - - @override - Widget build(BuildContext context) { - return AlertDialog( - icon: const Icon(Icons.edit_outlined), - titlePadding: Dimens.dialogIconTitlePadding, - title: Text(widget.title), - content: TextField( - autofocus: true, - controller: _nameController, - decoration: InputDecoration(hintText: widget.hint), - ), - actions: [ - TextButton( - onPressed: Navigator.of(context).pop, - child: Text(S.of(context).cancel), - ), - ValueListenableBuilder( - valueListenable: _nameController, - builder: (_, value, __) => TextButton( - onPressed: value.text.isNotEmpty ? () => Navigator.of(context).pop(value.text) : null, - child: Text(S.of(context).save), - ), - ), - ], - ); - } -} diff --git a/lib/screens/settings/components/shared/expandable_section_list/components/expandable_section_list_item/widget_expandable_section_list_item.dart b/lib/screens/settings/components/shared/expandable_section_list/components/expandable_section_list_item/widget_expandable_section_list_item.dart deleted file mode 100644 index 28e1926..0000000 --- a/lib/screens/settings/components/shared/expandable_section_list/components/expandable_section_list_item/widget_expandable_section_list_item.dart +++ /dev/null @@ -1,184 +0,0 @@ -import 'dart:math'; - -import 'package:flutter/material.dart'; -import 'package:flutter/scheduler.dart'; -import 'package:lightmeter/generated/l10n.dart'; -import 'package:lightmeter/res/dimens.dart'; - -class ExpandableSectionListItem extends StatefulWidget { - final String title; - final VoidCallback onTitleTap; - final VoidCallback onExpand; - final List actions; - final List children; - - const ExpandableSectionListItem({ - required this.title, - required this.onTitleTap, - required this.onExpand, - required this.actions, - required this.children, - super.key, - }); - - static ExpandableSectionListItemState of(BuildContext context) { - return context.findAncestorStateOfType()!; - } - - @override - State createState() => ExpandableSectionListItemState(); -} - -class ExpandableSectionListItemState extends State with TickerProviderStateMixin { - late final AnimationController _controller = AnimationController( - duration: Dimens.durationM, - vsync: this, - ); - bool get _expanded => _controller.isCompleted; - - @override - void dispose() { - _controller.dispose(); - super.dispose(); - } - - @override - Widget build(BuildContext context) { - return Card( - child: Padding( - padding: const EdgeInsets.symmetric(vertical: Dimens.paddingM), - child: Column( - crossAxisAlignment: CrossAxisAlignment.start, - mainAxisSize: MainAxisSize.min, - children: [ - ListTile( - contentPadding: const EdgeInsets.symmetric(horizontal: Dimens.paddingM), - title: Row( - children: [ - _AnimatedNameLeading(controller: _controller), - const SizedBox(width: Dimens.grid8), - Flexible( - child: Text( - widget.title, - maxLines: 1, - overflow: TextOverflow.ellipsis, - ), - ), - ], - ), - trailing: _AnimatedArrowButton( - controller: _controller, - onPressed: () => _expanded ? collapse() : expand(), - ), - onTap: () => _expanded ? widget.onTitleTap() : expand(), - ), - _AnimatedContent( - controller: _controller, - actions: widget.actions, - children: widget.children, - ), - ], - ), - ), - ); - } - - void expand() { - widget.onExpand(); - _controller.forward(); - SchedulerBinding.instance.addPostFrameCallback((_) { - Future.delayed(_controller.duration!).then((_) { - Scrollable.ensureVisible( - context, - alignmentPolicy: ScrollPositionAlignmentPolicy.keepVisibleAtEnd, - duration: _controller.duration!, - ); - }); - }); - } - - void collapse() { - _controller.reverse(); - } -} - -class _AnimatedNameLeading extends AnimatedWidget { - const _AnimatedNameLeading({required AnimationController controller}) : super(listenable: controller); - - Animation get _progress => listenable as Animation; - - @override - Widget build(BuildContext context) { - return Padding( - padding: EdgeInsets.only(right: _progress.value * Dimens.grid8), - child: Icon( - Icons.edit_outlined, - size: _progress.value * Dimens.grid24, - ), - ); - } -} - -class _AnimatedArrowButton extends AnimatedWidget { - final VoidCallback onPressed; - - const _AnimatedArrowButton({ - required AnimationController controller, - required this.onPressed, - }) : super(listenable: controller); - - Animation get _progress => listenable as Animation; - - @override - Widget build(BuildContext context) { - return IconButton( - onPressed: onPressed, - icon: Transform.rotate( - angle: _progress.value * pi, - child: const Icon(Icons.keyboard_arrow_down_outlined), - ), - tooltip: _progress.value == 0 ? S.of(context).tooltipExpand : S.of(context).tooltipCollapse, - ); - } -} - -class _AnimatedContent extends AnimatedWidget { - final List actions; - final List children; - - const _AnimatedContent({ - required AnimationController controller, - required this.actions, - required this.children, - }) : super(listenable: controller); - - Animation get _progress => listenable as Animation; - - @override - Widget build(BuildContext context) { - return SizedOverflowBox( - alignment: Alignment.topCenter, - size: Size( - double.maxFinite, - _progress.value * Dimens.grid56 * (children.length + 1), - ), - // https://github.com/gskinnerTeam/flutter-folio/pull/62 - child: Opacity( - opacity: _progress.value, - child: Column( - children: [ - ...children, - ListTile( - contentPadding: const EdgeInsets.symmetric(horizontal: Dimens.paddingM), - trailing: Row( - mainAxisAlignment: MainAxisAlignment.end, - mainAxisSize: MainAxisSize.min, - children: actions, - ), - ), - ], - ), - ), - ); - } -} diff --git a/lib/screens/settings/components/shared/expandable_section_list/widget_expandable_section_list.dart b/lib/screens/settings/components/shared/expandable_section_list/widget_expandable_section_list.dart deleted file mode 100644 index 0fc5de2..0000000 --- a/lib/screens/settings/components/shared/expandable_section_list/widget_expandable_section_list.dart +++ /dev/null @@ -1,95 +0,0 @@ -import 'package:flutter/material.dart'; -import 'package:lightmeter/res/dimens.dart'; -import 'package:lightmeter/screens/settings/components/shared/expandable_section_list/components/expandable_section_list_item/widget_expandable_section_list_item.dart'; -import 'package:m3_lightmeter_resources/m3_lightmeter_resources.dart'; - -typedef _WidgetBuilder = W Function(BuildContext context, T value); - -class ExpandableSectionList extends StatefulWidget { - final List values; - final VoidCallback onSectionTitleTap; - final _WidgetBuilder, T> contentBuilder; - final _WidgetBuilder, T> actionsBuilder; - - const ExpandableSectionList({ - required this.values, - required this.onSectionTitleTap, - required this.contentBuilder, - required this.actionsBuilder, - super.key, - }); - - @override - State createState() => _ExpandableSectionListState(); -} - -class _ExpandableSectionListState extends State> { - final Map> keysMap = {}; - - @override - void didChangeDependencies() { - super.didChangeDependencies(); - _updateProfilesKeys(); - } - - @override - Widget build(BuildContext context) { - return SliverList( - delegate: SliverChildBuilderDelegate( - (context, index) { - final item = widget.values[index]; - return Padding( - padding: EdgeInsets.fromLTRB( - Dimens.paddingM, - index == 0 ? Dimens.paddingM : 0, - Dimens.paddingM, - Dimens.paddingM, - ), - child: ExpandableSectionListItem( - key: keysMap[item.id], - title: item.name, - onTitleTap: widget.onSectionTitleTap, - onExpand: () => _keepExpandedAt(index), - actions: widget.actionsBuilder(context, item), - children: widget.contentBuilder(context, item), - ), - ); - }, - childCount: widget.values.length, - ), - ); - } - - void _keepExpandedAt(int index) { - keysMap.values.toList().getRange(0, index).forEach((element) { - element.currentState?.collapse(); - }); - keysMap.values.toList().getRange(index + 1, keysMap.length).forEach((element) { - element.currentState?.collapse(); - }); - } - - void _updateProfilesKeys() { - if (widget.values.length > keysMap.length) { - // item added - final List idsToAdd = []; - for (final item in widget.values) { - if (!keysMap.keys.contains(item.id)) idsToAdd.add(item.id); - } - for (final id in idsToAdd) { - keysMap[id] = GlobalKey(debugLabel: id); - } - idsToAdd.clear(); - } else if (widget.values.length < keysMap.length) { - // item deleted - final List idsToDelete = []; - for (final id in keysMap.keys) { - if (!widget.values.any((p) => p.id == id)) idsToDelete.add(id); - } - idsToDelete.forEach(keysMap.remove); - idsToDelete.clear(); - } else { - // item updated, no need to updated keys - } - } -}