From 2c0669f79ec27badc061e9cab47ffcb12bc4a51b Mon Sep 17 00:00:00 2001 From: Alex Li Date: Mon, 9 Dec 2024 22:46:01 +0800 Subject: [PATCH] =?UTF-8?q?=F0=9F=90=9B=20Fix=20custom=20filter=20updates?= =?UTF-8?q?=20in=20the=20example?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../custom_filter/advance_filter_page.dart | 287 +--------------- .../page/custom_filter/order_by_action.dart | 49 ++- example/lib/page/custom_filter/path_list.dart | 10 +- .../lib/page/custom_filter/where_action.dart | 314 ++++++++++++++++++ example/pubspec.lock | 2 +- 5 files changed, 356 insertions(+), 306 deletions(-) create mode 100644 example/lib/page/custom_filter/where_action.dart diff --git a/example/lib/page/custom_filter/advance_filter_page.dart b/example/lib/page/custom_filter/advance_filter_page.dart index df1ee860..d2ba7e1d 100644 --- a/example/lib/page/custom_filter/advance_filter_page.dart +++ b/example/lib/page/custom_filter/advance_filter_page.dart @@ -1,6 +1,8 @@ import 'package:flutter/material.dart'; import 'package:photo_manager/photo_manager.dart'; -import 'package:photo_manager_example/page/custom_filter/order_by_action.dart'; + +import 'order_by_action.dart'; +import 'where_action.dart'; class AdvancedCustomFilterPage extends StatefulWidget { const AdvancedCustomFilterPage({ @@ -16,15 +18,14 @@ class AdvancedCustomFilterPage extends StatefulWidget { } class _AdvancedCustomFilterPageState extends State { - final List _orderBy = [ + List _where = []; + List _orderBy = [ OrderByItem.named( column: CustomColumns.base.createDate, isAsc: false, ), ]; - final List _where = []; - late CustomFilter filter; @override @@ -48,14 +49,14 @@ class _AdvancedCustomFilterPageState extends State { title: const Text('Advanced Custom Filter Example'), actions: [ WhereAction( - where: _where, + items: _where, onChanged: (value) { if (!mounted) { return; } setState(() { - _where.clear(); - _where.addAll(value); + _where = value; + filter = _createFilter(); }); }, ), @@ -66,8 +67,8 @@ class _AdvancedCustomFilterPageState extends State { return; } setState(() { - _orderBy.clear(); - _orderBy.addAll(values); + _orderBy = values; + filter = _createFilter(); }); }, ), @@ -83,271 +84,3 @@ class _AdvancedCustomFilterPageState extends State { ); } } - -class WhereAction extends StatelessWidget { - const WhereAction({ - super.key, - required this.where, - required this.onChanged, - // required this - }); - - final List where; - final ValueChanged> onChanged; - - @override - Widget build(BuildContext context) { - return IconButton( - icon: const Icon(Icons.filter_alt), - onPressed: () { - _WhereConditionPage._saveItems = null; - Navigator.push>( - context, - MaterialPageRoute( - builder: (context) => _WhereConditionPage(where: where), - ), - ).then((value) { - value ??= _WhereConditionPage._saveItems; - if (value != null) { - onChanged(value); - } - }); - }, - ); - } -} - -class _WhereConditionPage extends StatefulWidget { - const _WhereConditionPage({ - required this.where, - }); - - final List where; - - static List? _saveItems; - - @override - State<_WhereConditionPage> createState() => _WhereConditionPageState(); -} - -class _WhereConditionPageState extends State<_WhereConditionPage> { - final List _where = []; - - bool isChanged = false; - - @override - void initState() { - super.initState(); - _where.addAll(widget.where); - _WhereConditionPage._saveItems = _where; - } - - @override - Widget build(BuildContext context) { - return Scaffold( - appBar: AppBar( - title: const Text('Where Condition'), - actions: [ - IconButton( - icon: const Icon(Icons.add), - onPressed: _createNew, - ), - ], - ), - body: buildList(context), - floatingActionButton: FloatingActionButton( - child: const Icon(Icons.done), - onPressed: () { - Navigator.of(context).pop(_where); - }, - ), - ); - } - - Future _createNew() async { - final result = await showDialog( - context: context, - builder: (context) { - return const _CreateWhereDialog(); - }, - ); - if (result != null) { - setState(() { - isChanged = true; - _where.add(result); - }); - } - } - - Widget buildList(BuildContext context) { - return ListView.builder( - itemCount: _where.length, - itemBuilder: (context, index) { - final item = _where[index]; - return ListTile( - title: Text(item.display()), - trailing: IconButton( - icon: const Icon(Icons.delete), - onPressed: () { - setState(() { - isChanged = true; - _where.removeAt(index); - }); - }, - ), - ); - }, - ); - } -} - -class _CreateWhereDialog extends StatefulWidget { - const _CreateWhereDialog(); - - @override - State<_CreateWhereDialog> createState() => _CreateWhereDialogState(); -} - -class _CreateWhereDialogState extends State<_CreateWhereDialog> { - List keys() { - return CustomColumns.platformValues(); - } - - late String column = keys().first; - String condition = '=='; - TextEditingController textValueController = TextEditingController(); - - DateTime _date = DateTime.now(); - - WhereConditionItem createItem() { - final cond = condition; - - if (isDateColumn()) { - return DateColumnWhereCondition( - column: column, - operator: condition, - value: _date, - ); - } - - final value = '$column $cond ${textValueController.text}'; - final item = WhereConditionItem.text(value); - return item; - } - - bool isDateColumn() { - final dateColumns = CustomColumns.dateColumns(); - return dateColumns.contains(column); - } - - @override - Widget build(BuildContext context) { - return AlertDialog( - title: const Text('Create Where Condition'), - content: Container( - width: double.maxFinite, - padding: const EdgeInsets.all(16.0), - child: Column( - mainAxisSize: MainAxisSize.min, - children: [ - DropdownButton( - items: keys().map((e) { - return DropdownMenuItem( - value: e, - child: Text(e), - ); - }).toList(), - onChanged: (value) { - if (value == null) { - return; - } - setState(() { - column = value; - }); - }, - value: column, - ), - DropdownButton( - hint: const Text('Condition'), - items: WhereConditionItem.platformConditions.map((e) { - return DropdownMenuItem( - value: e, - child: Text(e), - ); - }).toList(), - onChanged: (value) { - if (value == null) { - return; - } - setState(() { - condition = value; - }); - }, - value: condition, - ), - if (!isDateColumn()) - TextField( - controller: textValueController, - decoration: const InputDecoration( - hintText: 'Input condition', - ), - onChanged: (value) { - setState(() {}); - }, - ) - else - _datePicker(), - const SizedBox( - height: 16, - ), - Text( - createItem().text, - style: TextStyle( - color: Theme.of(context).primaryColor, - fontSize: 20, - ), - ), - ], - ), - ), - actions: [ - TextButton( - onPressed: () { - Navigator.of(context).pop(); - }, - child: const Text('Cancel'), - ), - TextButton( - onPressed: () { - Navigator.of(context).pop(createItem()); - }, - child: const Text('OK'), - ), - ], - ); - } - - Widget _datePicker() { - return Column( - children: [ - TextButton( - onPressed: () async { - final date = await showDatePicker( - context: context, - initialDate: _date, - firstDate: DateTime(1970), - lastDate: DateTime(2100), - ); - if (date == null) { - return; - } - setState(() { - _date = date; - }); - }, - child: Text(_date.toIso8601String()), - ), - ], - ); - } -} diff --git a/example/lib/page/custom_filter/order_by_action.dart b/example/lib/page/custom_filter/order_by_action.dart index f6e9cec7..8b979653 100644 --- a/example/lib/page/custom_filter/order_by_action.dart +++ b/example/lib/page/custom_filter/order_by_action.dart @@ -38,36 +38,34 @@ class OrderByAction extends StatelessWidget { Widget build(BuildContext context) { return Stack( children: [ - Align( - alignment: Alignment.center, - child: IconButton( - onPressed: () async { - await changeOrderBy(context, items, onChanged); - }, - icon: const Icon(Icons.sort), - ), + IconButton( + onPressed: () async { + await changeOrderBy(context, items, onChanged); + }, + icon: const Icon(Icons.sort), ), - Positioned( - right: 5, - top: 5, - child: Container( - width: 15, - height: 15, - decoration: const BoxDecoration( - color: Colors.red, - shape: BoxShape.circle, - ), - child: Center( - child: Text( - items.length.toString(), - style: const TextStyle( - color: Colors.white, - fontSize: 8, + if (items.isNotEmpty) + Positioned( + right: 5, + top: 5, + child: Container( + width: 15, + height: 15, + decoration: const BoxDecoration( + color: Colors.red, + shape: BoxShape.circle, + ), + child: Center( + child: Text( + items.length.toString(), + style: const TextStyle( + color: Colors.white, + fontSize: 8, + ), ), ), ), ), - ), ], ); } @@ -81,6 +79,7 @@ class OrderByActionPage extends StatefulWidget { final List items; static List? _saveItems; + @override State createState() => _OrderByActionPageState(); } diff --git a/example/lib/page/custom_filter/path_list.dart b/example/lib/page/custom_filter/path_list.dart index fc081222..f8dce60c 100644 --- a/example/lib/page/custom_filter/path_list.dart +++ b/example/lib/page/custom_filter/path_list.dart @@ -11,9 +11,13 @@ class FilterPathList extends StatelessWidget { @override Widget build(BuildContext context) { return FutureBuilder>( - future: PhotoManager.getAssetPathList( - filterOption: filter, - ), + future: Future(() async { + final ps = await PhotoManager.requestPermissionExtend(); + if (!ps.hasAccess) { + throw StateError('No access'); + } + return PhotoManager.getAssetPathList(filterOption: filter); + }), builder: ( BuildContext context, AsyncSnapshot> snapshot, diff --git a/example/lib/page/custom_filter/where_action.dart b/example/lib/page/custom_filter/where_action.dart new file mode 100644 index 00000000..6558729c --- /dev/null +++ b/example/lib/page/custom_filter/where_action.dart @@ -0,0 +1,314 @@ +import 'package:flutter/material.dart'; +import 'package:photo_manager/photo_manager.dart'; + +Future changeWhere( + BuildContext context, + List items, + ValueChanged> onChanged, +) async { + _WhereConditionPage._saveItems = null; + Navigator.push>( + context, + MaterialPageRoute( + builder: (context) => _WhereConditionPage(where: items), + ), + ).then((value) { + value ??= _WhereConditionPage._saveItems; + if (value != null) { + onChanged(value); + } + }); +} + +class WhereAction extends StatelessWidget { + const WhereAction({ + super.key, + required this.items, + required this.onChanged, + }); + + final List items; + final ValueChanged> onChanged; + + @override + Widget build(BuildContext context) { + return Stack( + children: [ + IconButton( + onPressed: () { + _WhereConditionPage._saveItems = null; + Navigator.push>( + context, + MaterialPageRoute( + builder: (context) => _WhereConditionPage(where: items), + ), + ).then((value) { + value ??= _WhereConditionPage._saveItems; + if (value != null) { + onChanged(value); + } + }); + }, + icon: const Icon(Icons.filter_alt), + ), + if (items.isNotEmpty) + Positioned( + right: 5, + top: 5, + child: Container( + width: 15, + height: 15, + decoration: const BoxDecoration( + color: Colors.red, + shape: BoxShape.circle, + ), + child: Center( + child: Text( + items.length.toString(), + style: const TextStyle( + color: Colors.white, + fontSize: 8, + ), + ), + ), + ), + ), + ], + ); + } +} + +class _WhereConditionPage extends StatefulWidget { + const _WhereConditionPage({ + required this.where, + }); + + final List where; + + static List? _saveItems; + + @override + State<_WhereConditionPage> createState() => _WhereConditionPageState(); +} + +class _WhereConditionPageState extends State<_WhereConditionPage> { + final List _where = []; + + bool isChanged = false; + + @override + void initState() { + super.initState(); + _where.addAll(widget.where); + _WhereConditionPage._saveItems = _where; + } + + @override + Widget build(BuildContext context) { + return Scaffold( + appBar: AppBar( + title: const Text('Where Condition'), + actions: [ + IconButton( + icon: const Icon(Icons.add), + onPressed: _createNew, + ), + ], + ), + body: buildList(context), + floatingActionButton: FloatingActionButton( + child: const Icon(Icons.done), + onPressed: () { + Navigator.of(context).pop(_where); + }, + ), + ); + } + + Future _createNew() async { + final result = await showDialog( + context: context, + builder: (context) { + return const _CreateWhereDialog(); + }, + ); + if (result != null) { + setState(() { + isChanged = true; + _where.add(result); + }); + } + } + + Widget buildList(BuildContext context) { + return ListView.builder( + itemCount: _where.length, + itemBuilder: (context, index) { + final item = _where[index]; + return ListTile( + title: Text(item.display()), + trailing: IconButton( + icon: const Icon(Icons.delete), + onPressed: () { + setState(() { + isChanged = true; + _where.removeAt(index); + }); + }, + ), + ); + }, + ); + } +} + +class _CreateWhereDialog extends StatefulWidget { + const _CreateWhereDialog(); + + @override + State<_CreateWhereDialog> createState() => _CreateWhereDialogState(); +} + +class _CreateWhereDialogState extends State<_CreateWhereDialog> { + List keys() { + return CustomColumns.platformValues(); + } + + late String column = keys().first; + String condition = '=='; + TextEditingController textValueController = TextEditingController(); + + DateTime _date = DateTime.now(); + + WhereConditionItem createItem() { + final cond = condition; + + if (isDateColumn()) { + return DateColumnWhereCondition( + column: column, + operator: condition, + value: _date, + ); + } + + final value = '$column $cond ${textValueController.text}'; + final item = WhereConditionItem.text(value); + return item; + } + + bool isDateColumn() { + final dateColumns = CustomColumns.dateColumns(); + return dateColumns.contains(column); + } + + @override + Widget build(BuildContext context) { + return AlertDialog( + title: const Text('Create Where Condition'), + content: Container( + width: double.maxFinite, + padding: const EdgeInsets.all(16.0), + child: Column( + mainAxisSize: MainAxisSize.min, + children: [ + DropdownButton( + items: keys().map((e) { + return DropdownMenuItem( + value: e, + child: Text(e), + ); + }).toList(), + onChanged: (value) { + if (value == null) { + return; + } + setState(() { + column = value; + }); + }, + value: column, + ), + DropdownButton( + hint: const Text('Condition'), + items: WhereConditionItem.platformConditions.map((e) { + return DropdownMenuItem( + value: e, + child: Text(e), + ); + }).toList(), + onChanged: (value) { + if (value == null) { + return; + } + setState(() { + condition = value; + }); + }, + value: condition, + ), + if (!isDateColumn()) + TextField( + controller: textValueController, + decoration: const InputDecoration( + hintText: 'Input condition', + ), + onChanged: (value) { + setState(() {}); + }, + ) + else + _datePicker(), + const SizedBox( + height: 16, + ), + Text( + createItem().text, + style: TextStyle( + color: Theme.of(context).primaryColor, + fontSize: 20, + ), + ), + ], + ), + ), + actions: [ + TextButton( + onPressed: () { + Navigator.of(context).pop(); + }, + child: const Text('Cancel'), + ), + TextButton( + onPressed: () { + Navigator.of(context).pop(createItem()); + }, + child: const Text('OK'), + ), + ], + ); + } + + Widget _datePicker() { + return Column( + children: [ + TextButton( + onPressed: () async { + final date = await showDatePicker( + context: context, + initialDate: _date, + firstDate: DateTime(1970), + lastDate: DateTime(2100), + ); + if (date == null) { + return; + } + setState(() { + _date = date; + }); + }, + child: Text(_date.toIso8601String()), + ), + ], + ); + } +} diff --git a/example/pubspec.lock b/example/pubspec.lock index c7f7433c..1e5a3c47 100644 --- a/example/pubspec.lock +++ b/example/pubspec.lock @@ -387,7 +387,7 @@ packages: path: ".." relative: true source: path - version: "3.6.2" + version: "3.6.3" photo_manager_image_provider: dependency: "direct main" description: