diff --git a/lib/bloc/yesod/yesod_bloc.dart b/lib/bloc/yesod/yesod_bloc.dart index b04010b..89e8260 100644 --- a/lib/bloc/yesod/yesod_bloc.dart +++ b/lib/bloc/yesod/yesod_bloc.dart @@ -109,7 +109,7 @@ class YesodBloc extends Bloc { } final configs = [ ListFeedConfigsResponse_FeedWithConfig( - config: event.config, + config: event.config..id = resp.getData().id, feed: null, ) ]; @@ -222,6 +222,7 @@ class YesodBloc extends Bloc { event.set, ]; sets.addAll(state.feedActionSets ?? []); + add(YesodFeedActionSetLoadEvent()); emit(YesodFeedActionSetAddState( state.copyWith(feedActionSets: sets), EventStatus.success, diff --git a/lib/route.dart b/lib/route.dart index df6d6fe..73d1633 100644 --- a/lib/route.dart +++ b/lib/route.dart @@ -357,6 +357,7 @@ class YesodFunctionRoute extends GoRouteData { case YesodFunctions.recent: case YesodFunctions.timeline: context.read().add(YesodInitEvent()); + context.read().add(YesodFeedConfigLoadEvent()); case YesodFunctions.feedManage: context.read().add(MainRefreshServerInfoEvent()); context.read().add(YesodFeedConfigLoadEvent()); diff --git a/lib/view/components/pop_alert.dart b/lib/view/components/pop_alert.dart new file mode 100644 index 0000000..b691069 --- /dev/null +++ b/lib/view/components/pop_alert.dart @@ -0,0 +1,63 @@ +import 'package:flutter/material.dart'; + +class PopAlert extends StatelessWidget { + const PopAlert({ + super.key, + required this.child, + required this.title, + required this.content, + required this.onConfirm, + this.onDeny, + required this.onCancel, + }); + + final Widget child; + final String title; + final String content; + final void Function() onConfirm; + final void Function()? onDeny; + final void Function() onCancel; + + @override + Widget build(BuildContext context) { + return WillPopScope( + onWillPop: () async { + final shouldPop = await showDialog( + context: context, + builder: (context) { + return AlertDialog( + title: Text(title), + content: Text(content), + actions: [ + TextButton( + onPressed: () => { + Navigator.of(context).pop(true), + onConfirm(), + }, + child: const Text('是'), + ), + if (onDeny != null) + TextButton( + onPressed: () => { + Navigator.of(context).pop(true), + onDeny!(), + }, + child: const Text('否'), + ), + TextButton( + onPressed: () => { + Navigator.of(context).pop(false), + onCancel(), + }, + child: const Text('点错了'), + ), + ], + ); + }, + ); + return shouldPop ?? false; + }, + child: child, + ); + } +} diff --git a/lib/view/components/toast.dart b/lib/view/components/toast.dart index c8dc22a..7556da4 100644 --- a/lib/view/components/toast.dart +++ b/lib/view/components/toast.dart @@ -15,6 +15,7 @@ class Toast { ScaffoldFeatureController show( BuildContext context) { + final messenger = ScaffoldMessenger.of(context); final left = calculateColumnWidth( xxs: 0, sm: 6, @@ -22,19 +23,19 @@ class Toast { xl: 10, containerWidth: MediaQuery.of(context).size.width, ); - return ScaffoldMessenger.of(context).showSnackBar( + return messenger.showSnackBar( SnackBar( elevation: 0, margin: EdgeInsets.only(left: left), behavior: SnackBarBehavior.floating, hitTestBehavior: HitTestBehavior.deferToChild, backgroundColor: Colors.transparent, - content: _content(context), + content: _content(context, messenger), ), ); } - Widget _content(BuildContext context) { + Widget _content(BuildContext context, ScaffoldMessengerState messenger) { final List maybeActionAndIcon = [ if (action != null) Padding( @@ -85,8 +86,12 @@ class Toast { IconButton( icon: const Icon(Icons.close), color: Theme.of(context).colorScheme.onPrimary, - onPressed: () => ScaffoldMessenger.of(context) - .hideCurrentSnackBar(reason: SnackBarClosedReason.dismiss), + onPressed: () { + if (messenger.mounted) { + messenger.hideCurrentSnackBar( + reason: SnackBarClosedReason.dismiss); + } + }, ), ], ), diff --git a/lib/view/pages/yesod/manage_notify_flow_page.dart b/lib/view/pages/yesod/manage_notify_flow_page.dart index 2f556b6..cbf4d9b 100644 --- a/lib/view/pages/yesod/manage_notify_flow_page.dart +++ b/lib/view/pages/yesod/manage_notify_flow_page.dart @@ -181,6 +181,16 @@ class _NotifyFlowAddPanelState extends State { MultiSelectItem( config.config.id, config.feed.title), ], + itemsTextStyle: TextStyle( + fontSize: + Theme.of(context).textTheme.bodyMedium?.fontSize, + color: Theme.of(context).colorScheme.onSurface, + ), + selectedItemsTextStyle: TextStyle( + fontSize: + Theme.of(context).textTheme.bodyMedium?.fontSize, + color: Theme.of(context).colorScheme.onSurface, + ), initialValue: sources.map((e) => e.feedConfigId).toList(), onConfirm: (values) { final List newSources = []; @@ -349,6 +359,16 @@ class _NotifyFlowAddPanelState extends State { if (config.id.id != 0) MultiSelectItem(config.id, config.name), ], + itemsTextStyle: TextStyle( + fontSize: + Theme.of(context).textTheme.bodyMedium?.fontSize, + color: Theme.of(context).colorScheme.onSurface, + ), + selectedItemsTextStyle: TextStyle( + fontSize: + Theme.of(context).textTheme.bodyMedium?.fontSize, + color: Theme.of(context).colorScheme.onSurface, + ), initialValue: targets.map((e) => e.targetId).toList(), onConfirm: (values) { final List newTargets = []; @@ -652,9 +672,19 @@ class _NotifyFlowAddPageState extends State { for (final ListFeedConfigsResponse_FeedWithConfig config in notifySources) if (config.config.id.id != 0) - MultiSelectItem( - config.config.id, config.feed.title), + MultiSelectItem(config.config.id, + '${config.config.name} - ${config.feed.title}'), ], + itemsTextStyle: TextStyle( + fontSize: + Theme.of(context).textTheme.bodyMedium?.fontSize, + color: Theme.of(context).colorScheme.onSurface, + ), + selectedItemsTextStyle: TextStyle( + fontSize: + Theme.of(context).textTheme.bodyMedium?.fontSize, + color: Theme.of(context).colorScheme.onSurface, + ), initialValue: sources.map((e) => e.feedConfigId).toList(), onConfirm: (values) { final List newSources = []; @@ -696,8 +726,8 @@ class _NotifyFlowAddPageState extends State { child: Text(notifySources .firstWhere( (e) => e.config.id == sources[i].feedConfigId) - .feed - .title), + .config + .name), ), const SizedBox( height: 8, @@ -823,6 +853,16 @@ class _NotifyFlowAddPageState extends State { if (config.id.id != 0) MultiSelectItem(config.id, config.name), ], + itemsTextStyle: TextStyle( + fontSize: + Theme.of(context).textTheme.bodyMedium?.fontSize, + color: Theme.of(context).colorScheme.onSurface, + ), + selectedItemsTextStyle: TextStyle( + fontSize: + Theme.of(context).textTheme.bodyMedium?.fontSize, + color: Theme.of(context).colorScheme.onSurface, + ), initialValue: targets.map((e) => e.targetId).toList(), onConfirm: (values) { final List newTargets = []; diff --git a/lib/view/pages/yesod/manage_yesod_action_page.dart b/lib/view/pages/yesod/manage_yesod_action_page.dart index a700b4b..5cdeb69 100644 --- a/lib/view/pages/yesod/manage_yesod_action_page.dart +++ b/lib/view/pages/yesod/manage_yesod_action_page.dart @@ -11,6 +11,7 @@ import '../../../bloc/main_bloc.dart'; import '../../../bloc/yesod/yesod_bloc.dart'; import '../../../l10n/l10n.dart'; import '../../../route.dart'; +import '../../components/pop_alert.dart'; import '../../components/toast.dart'; import '../../helper/app_bar.dart'; import '../../layout/bootstrap_container.dart'; @@ -337,123 +338,134 @@ class _YesodActionConfigurePageState extends State<_YesodActionConfigurePage> @override Widget build(BuildContext context) { - return Scaffold( - appBar: AppBar( - title: const Text('编辑规则'), - shape: AppBarHelper.defaultShape, - leading: AppBarHelper.defaultMainLeading(context, onPressed: () { - Navigator.of(context).pop(); - }), - actions: [ - IconButton( - icon: const Icon(Icons.check), - onPressed: () { - widget.onSave(widget.actions); - Navigator.of(context).pop(); - }, - ), - ], - bottom: TabBar( - controller: _tabController, - tabs: [ - for (var i = 0; i < actions.length; i++) - Tab( - icon: CircleAvatar( - child: Text((i + 1).toString()), - ), - text: widget.features - .firstWhere((element) => element.id == actions[i].id) - .name, - ), - const Tab( - icon: Icon(Icons.add), - text: '添加', + return PopAlert( + title: '确定退出', + content: '是否保存更改再退出', + onConfirm: () { + widget.onSave(widget.actions); + const Toast(title: '', message: '已保存更改').show(context); + }, + onDeny: () {}, + onCancel: () {}, + child: Scaffold( + appBar: AppBar( + title: const Text('编辑规则'), + shape: AppBarHelper.defaultShape, + leading: AppBarHelper.defaultMainLeading(context, onPressed: () { + Navigator.of(context).pop(); + }), + actions: [ + IconButton( + icon: const Icon(Icons.check), + onPressed: () { + widget.onSave(widget.actions); + const Toast(title: '', message: '已保存更改').show(context); + Navigator.of(context).pop(); + }, ), ], + bottom: TabBar( + controller: _tabController, + tabs: [ + for (var i = 0; i < actions.length; i++) + Tab( + icon: CircleAvatar( + child: Text((i + 1).toString()), + ), + text: widget.features + .firstWhere((element) => element.id == actions[i].id) + .name, + ), + const Tab( + icon: Icon(Icons.add), + text: '添加', + ), + ], + ), ), - ), - body: TabBarView( - controller: _tabController, - children: [ - for (var i = 0; i < actions.length; i++) - Column( - children: [ - Container( - padding: const EdgeInsets.symmetric(vertical: 8), - child: Row( - mainAxisAlignment: MainAxisAlignment.center, - children: [ - ElevatedButton.icon( - onPressed: i > 0 - ? () { - setState(() { - final temp = actions[i - 1]; - actions[i - 1] = actions[i]; - actions[i] = temp; - }); - _tabController.animateTo(i - 1); - } - : null, - icon: const Icon(Icons.keyboard_arrow_left), - label: const Text('前移'), - ), - Container( - padding: const EdgeInsets.symmetric(horizontal: 8), - child: ElevatedButton.icon( - onPressed: () { - setState(() { - actions.removeAt(i); - _tabController = TabController( - length: actions.length + 1, vsync: this); - }); - }, - icon: const Icon(Icons.delete), - label: const Text('删除'), + body: TabBarView( + controller: _tabController, + children: [ + for (var i = 0; i < actions.length; i++) + Column( + children: [ + Container( + padding: const EdgeInsets.symmetric(vertical: 8), + child: Row( + mainAxisAlignment: MainAxisAlignment.center, + children: [ + ElevatedButton.icon( + onPressed: i > 0 + ? () { + setState(() { + final temp = actions[i - 1]; + actions[i - 1] = actions[i]; + actions[i] = temp; + }); + _tabController.animateTo(i - 1); + } + : null, + icon: const Icon(Icons.keyboard_arrow_left), + label: const Text('前移'), ), - ), - ElevatedButton.icon( - onPressed: i < actions.length - 1 - ? () { - setState(() { - final temp = actions[i + 1]; - actions[i + 1] = actions[i]; - actions[i] = temp; - }); - _tabController.animateTo(i + 1); - } - : null, - icon: const Icon(Icons.keyboard_arrow_right), - label: const Text('后移'), - ), - ], + Container( + padding: const EdgeInsets.symmetric(horizontal: 8), + child: ElevatedButton.icon( + onPressed: () { + setState(() { + actions.removeAt(i); + _tabController = TabController( + length: actions.length + 1, vsync: this); + }); + }, + icon: const Icon(Icons.delete), + label: const Text('删除'), + ), + ), + ElevatedButton.icon( + onPressed: i < actions.length - 1 + ? () { + setState(() { + final temp = actions[i + 1]; + actions[i + 1] = actions[i]; + actions[i] = temp; + }); + _tabController.animateTo(i + 1); + } + : null, + icon: const Icon(Icons.keyboard_arrow_right), + label: const Text('后移'), + ), + ], + ), ), - ), - Expanded( - child: _YesodActionConfigureItem( - key: Key(actions[i].toString()), - features: widget.features, - action: actions[i], - onSave: (action) { - setState(() { - actions[i] = action; - }); - }, + Expanded( + child: _YesodActionConfigureItem( + key: Key(actions[i].toString()), + features: widget.features, + action: actions[i], + onSave: (action) { + setState(() { + actions[i] = action; + }); + }, + ), ), - ), - ], + ], + ), + _YesodActionConfigureItem( + features: widget.features, + action: FeatureRequest(), + onSave: (action) { + setState(() { + actions.add(action); + _tabController = + TabController(length: actions.length + 1, vsync: this); + }); + }, ), - _YesodActionConfigureItem( - features: widget.features, - action: FeatureRequest(), - onSave: (action) { - setState(() { - actions.add(action); - _tabController = - TabController(length: actions.length + 1, vsync: this); - }); - }, - ), - ], + ], + ), ), ); } diff --git a/lib/view/pages/yesod/manage_yesod_feed_page.dart b/lib/view/pages/yesod/manage_yesod_feed_page.dart index d01e222..4dc02e3 100644 --- a/lib/view/pages/yesod/manage_yesod_feed_page.dart +++ b/lib/view/pages/yesod/manage_yesod_feed_page.dart @@ -9,6 +9,7 @@ import 'package:flutter/services.dart'; import 'package:flutter_bloc/flutter_bloc.dart'; import 'package:flutter_jsonschema_builder/flutter_jsonschema_builder.dart'; import 'package:multi_select_flutter/bottom_sheet/multi_select_bottom_sheet_field.dart'; +import 'package:multi_select_flutter/dialog/multi_select_dialog_field.dart'; import 'package:multi_select_flutter/util/multi_select_item.dart'; import 'package:multi_select_flutter/util/multi_select_list_type.dart'; import 'package:tuihub_protos/google/protobuf/duration.pb.dart' as $duration; @@ -146,6 +147,19 @@ class YesodFeedManageAddPanel extends StatelessWidget { return RightPanelForm( title: Text(S.of(context).feedConfigAdd), formFields: [ + TextFormField( + onChanged: (newValue) => name = newValue, + decoration: const InputDecoration( + border: OutlineInputBorder(), + label: Text('名称'), + ), + validator: (value) { + if (value?.isEmpty ?? false) { + return S.of(context).requiredField; + } + return null; + }, + ), if (feedSources.isEmpty) const TextFormErrorMessage(message: '当前服务器无可用订阅源'), DropdownButtonFormField( @@ -186,19 +200,6 @@ class YesodFeedManageAddPanel extends StatelessWidget { submitButtonBuilder: (_) => Container(), ), ), - TextFormField( - onChanged: (newValue) => name = newValue, - decoration: const InputDecoration( - border: OutlineInputBorder(), - label: Text('名称'), - ), - validator: (value) { - if (value?.isEmpty ?? false) { - return S.of(context).requiredField; - } - return null; - }, - ), TextFormField( onChanged: (newValue) => refreshInterval = int.parse(newValue), initialValue: refreshInterval.toString(), @@ -320,6 +321,20 @@ class YesodFeedManageEditPanel extends StatelessWidget { label: S.of(context).id, value: config.id.id.toString(), ), + TextFormField( + initialValue: name, + onSaved: (newValue) => name = newValue!, + decoration: const InputDecoration( + border: OutlineInputBorder(), + labelText: '名称', + ), + validator: (value) { + if (value?.isEmpty ?? false) { + return S.of(context).requiredField; + } + return null; + }, + ), TextReadOnlyFormField( label: '订阅源类型', value: config.source.id, @@ -343,20 +358,6 @@ class YesodFeedManageEditPanel extends StatelessWidget { submitButtonBuilder: (_) => Container(), ), ), - TextFormField( - initialValue: name, - onSaved: (newValue) => name = newValue!, - decoration: const InputDecoration( - border: OutlineInputBorder(), - labelText: '名称', - ), - validator: (value) { - if (value?.isEmpty ?? false) { - return S.of(context).requiredField; - } - return null; - }, - ), TextFormField( initialValue: pullInterval.toString(), onSaved: (newValue) => pullInterval = int.parse(newValue!), @@ -380,12 +381,15 @@ class YesodFeedManageEditPanel extends StatelessWidget { labelText: '分组', ), ), - MultiSelectBottomSheetField( + MultiSelectDialogField( title: const Text('规则集'), buttonText: const Text('自动化规则'), initialValue: actions, - items: - actionSets.map((e) => MultiSelectItem(e.id, e.name)).toList(), + searchable: true, + items: [ + for (final e in actionSets) + if (e.id.id != 0) MultiSelectItem(e.id, e.name), + ], listType: MultiSelectListType.LIST, onConfirm: (values) { actions = values; diff --git a/lib/view/pages/yesod/yesod_nav.dart b/lib/view/pages/yesod/yesod_nav.dart index ff58124..a3e719e 100644 --- a/lib/view/pages/yesod/yesod_nav.dart +++ b/lib/view/pages/yesod/yesod_nav.dart @@ -53,49 +53,51 @@ class YesodNav extends StatelessWidget { Expanded( child: _YesodFeedList(function: function), ), - ExpansionTile( - leading: const Icon(Icons.auto_awesome), - title: Text(S.of(context).automation), - children: [ - ListTile( - leading: const Icon( - Icons.filter_list, + Material( + child: ExpansionTile( + leading: const Icon(Icons.auto_awesome), + title: Text(S.of(context).automation), + children: [ + ListTile( + leading: const Icon( + Icons.featured_play_list, + ), + onTap: () { + const YesodFunctionRoute( + YesodFunctions.notifyTargetManage) + .go(context); + OverlappingPanels.of(context)?.reveal(RevealSide.main); + }, + title: Text(S.of(context).notifyTargetManage), + selected: function == YesodFunctions.notifyTargetManage, ), - onTap: () { - const YesodFunctionRoute(YesodFunctions.actionManage) - .go(context); - OverlappingPanels.of(context)?.reveal(RevealSide.main); - }, - title: Text(S.of(context).feedActionSetManage), - selected: function == YesodFunctions.actionManage, - ), - SpacingHelper.defaultDivider, - ListTile( - leading: const Icon( - Icons.featured_play_list, + ListTile( + leading: const Icon( + FontAwesomeIcons.codeFork, + ), + onTap: () { + const YesodFunctionRoute(YesodFunctions.notifyFlowManage) + .go(context); + OverlappingPanels.of(context)?.reveal(RevealSide.main); + }, + title: Text(S.of(context).notifyFlowManage), + selected: function == YesodFunctions.notifyFlowManage, ), - onTap: () { - const YesodFunctionRoute(YesodFunctions.notifyTargetManage) - .go(context); - OverlappingPanels.of(context)?.reveal(RevealSide.main); - }, - title: Text(S.of(context).notifyTargetManage), - selected: function == YesodFunctions.notifyTargetManage, - ), - ListTile( - leading: const Icon( - FontAwesomeIcons.codeFork, + SpacingHelper.defaultDivider, + ListTile( + leading: const Icon( + Icons.filter_list, + ), + onTap: () { + const YesodFunctionRoute(YesodFunctions.actionManage) + .go(context); + OverlappingPanels.of(context)?.reveal(RevealSide.main); + }, + title: Text(S.of(context).feedActionSetManage), + selected: function == YesodFunctions.actionManage, ), - onTap: () { - const YesodFunctionRoute(YesodFunctions.notifyFlowManage) - .go(context); - OverlappingPanels.of(context)?.reveal(RevealSide.main); - }, - title: Text(S.of(context).notifyFlowManage), - selected: function == YesodFunctions.notifyFlowManage, - ), - SpacingHelper.defaultDivider, - ]), + ]), + ), ListTile( leading: const Icon( Icons.rss_feed, @@ -131,13 +133,13 @@ class _YesodFeedList extends StatelessWidget { for (final feedConfig in feedConfigs) ListTile( leading: Container( - decoration: feedConfig.feed.link.isEmpty + decoration: feedConfig.feed.image.url.isEmpty ? const BoxDecoration() : BoxDecoration( borderRadius: BorderRadius.circular(4), image: DecorationImage( image: ExtendedNetworkImageProvider( - feedConfig.feed.link, + feedConfig.feed.image.url, ), fit: BoxFit.scaleDown, ), @@ -151,7 +153,7 @@ class _YesodFeedList extends StatelessWidget { .add(YesodFeedItemListConfigSetEvent( (state.listConfig ?? const YesodFeedItemListConfig()) .copyWith( - feedIdFilter: [feedConfig.feed.id.id.toString()], + feedIdFilter: [feedConfig.config.id.id.toString()], ), )); const YesodFunctionRoute(YesodFunctions.recent).go(context); @@ -161,8 +163,9 @@ class _YesodFeedList extends StatelessWidget { ? feedConfig.config.name : feedConfig.feed.title), selected: function == YesodFunctions.recent && + feedConfig.config.id.id != 0 && state.listConfig?.feedIdFilter?.singleOrNull == - feedConfig.feed.id.id.toString(), + feedConfig.config.id.id.toString(), ), ], ); diff --git a/lib/view/pages/yesod/yesod_recent_page.dart b/lib/view/pages/yesod/yesod_recent_page.dart index 25d2ae4..a706b78 100644 --- a/lib/view/pages/yesod/yesod_recent_page.dart +++ b/lib/view/pages/yesod/yesod_recent_page.dart @@ -45,13 +45,19 @@ class YesodRecentPageState extends State { if (length == 0) { return S.of(context).allArticles; } else if (length == 1) { - return state.feedConfigs - ?.firstWhere((element) => - element.config.id.id.toString() == - state.listConfig?.feedIdFilter?.first) - .config - .name ?? - S.of(context).allArticles; + if (state.feedConfigs?.any((element) => + element.config.id.id.toString() == + state.listConfig?.feedIdFilter?.first) ?? + false) { + return state.feedConfigs + ?.firstWhere((element) => + element.config.id.id.toString() == + state.listConfig?.feedIdFilter?.first) + .config + .name ?? + S.of(context).filteredArticles; + } + return S.of(context).filteredArticles; } else if (length > 1) { return S.of(context).filteredArticles; } else { @@ -218,6 +224,7 @@ class YesodRecentPageState extends State { context .read() .add(YesodFeedItemDigestsLoadEvent(1, refresh: true)); + context.read().add(YesodFeedConfigLoadEvent()); } : _scrollToTop, child: Icon(isScrolledToTop ? Icons.refresh : Icons.arrow_upward), @@ -286,11 +293,7 @@ class YesodRecentSettingPanelState extends State { spacing: 2.0, customIconBuilder: (context, local, global) { final text = const ['列表', '杂志', '卡片'][local.index]; - return Center( - child: Text(text, - style: TextStyle( - color: Color.lerp(Colors.black, Colors.white, - local.animationValue)))); + return Center(child: Text(text)); }, onChanged: (value) { setState(() { @@ -318,12 +321,21 @@ class YesodRecentSettingPanelState extends State { title: const Text('按订阅筛选'), buttonText: const Text('订阅'), buttonIcon: const Icon(Icons.filter_alt_outlined), + searchable: true, items: [ for (final ListFeedConfigsResponse_FeedWithConfig config in state.feedConfigs ?? []) - MultiSelectItem( - config.config.id.id.toString(), config.feed.title), + MultiSelectItem(config.config.id.id.toString(), + '${config.config.name} - ${config.feed.title}'), ], + itemsTextStyle: TextStyle( + fontSize: Theme.of(context).textTheme.bodyMedium?.fontSize, + color: Theme.of(context).colorScheme.onSurface, + ), + selectedItemsTextStyle: TextStyle( + fontSize: Theme.of(context).textTheme.bodyMedium?.fontSize, + color: Theme.of(context).colorScheme.onSurface, + ), initialValue: feedIDFilter, onConfirm: (values) { feedIDFilter = values; @@ -336,11 +348,20 @@ class YesodRecentSettingPanelState extends State { title: const Text('按分类筛选'), buttonText: const Text('分类'), buttonIcon: const Icon(Icons.filter_alt_outlined), + searchable: true, items: [ for (final String category in state.feedCategories ?? []) MultiSelectItem( category, category.isNotEmpty ? category : '未分类'), ], + itemsTextStyle: TextStyle( + fontSize: Theme.of(context).textTheme.bodyMedium?.fontSize, + color: Theme.of(context).colorScheme.onSurface, + ), + selectedItemsTextStyle: TextStyle( + fontSize: Theme.of(context).textTheme.bodyMedium?.fontSize, + color: Theme.of(context).colorScheme.onSurface, + ), initialValue: categoryFilter, onConfirm: (values) { categoryFilter = values;