// Author: fruit.com.cn import 'package:flutter/foundation.dart'; import 'package:flutter/material.dart'; import '../../core/data/services/favorite_controller.dart'; import '../../core/theme/app_colors.dart'; import '../../l10n/app_localizations.dart'; enum FollowingTab { favorites, history } /// 编辑底栏的全选与取消动作。 class FollowingEditActions { const FollowingEditActions({ required this.onToggleAll, required this.onRemove, }); final void Function(Set ids) onToggleAll; final VoidCallback onRemove; } const double _barHeight = 48; const double _barHorizontal = 16; const double _barFontSize = 13; const double _barButtonHeight = 30; const double _removeDialogButtonHeight = 32; /// 只在追剧编辑中显示底栏。 class FollowingEditSlot extends StatelessWidget { const FollowingEditSlot({ super.key, required this.tab, required this.editing, required this.favorites, required this.selected, required this.actions, }); final ValueListenable tab; final ValueListenable editing; final FavoriteController favorites; final ValueListenable> selected; final FollowingEditActions actions; @override Widget build(BuildContext context) { return ValueListenableBuilder( valueListenable: tab, builder: (context, current, _) { return ValueListenableBuilder( valueListenable: editing, builder: (context, isEditing, _) { if (!isEditing || current != FollowingTab.favorites) { return const SizedBox.shrink(); } return _bar(); }, ); }, ); } Widget _bar() { return ListenableBuilder( listenable: favorites, builder: (context, _) { return ValueListenableBuilder>( valueListenable: selected, builder: (context, picked, _) { final ids = favorites.cards.map((drama) => drama.id).toSet(); return FollowingEditBar( allSelected: ids.isNotEmpty && ids.every(picked.contains), canRemove: picked.isNotEmpty, onToggleAll: () => actions.onToggleAll(ids), onRemove: actions.onRemove, ); }, ); }, ); } } /// 追剧编辑底栏:全选,以及取消已选追剧。 class FollowingEditBar extends StatelessWidget { const FollowingEditBar({ super.key, required this.allSelected, required this.canRemove, required this.onToggleAll, required this.onRemove, }); final bool allSelected; final bool canRemove; final VoidCallback onToggleAll; final VoidCallback onRemove; @override Widget build(BuildContext context) { final l10n = AppLocalizations.of(context)!; return Material( key: const Key('following-edit-bar'), color: AppColors.card, child: SafeArea( top: false, child: SizedBox( height: _barHeight, child: Padding( padding: const EdgeInsets.symmetric(horizontal: _barHorizontal), child: Row( children: [ TextButton( key: const Key('following-select-all'), style: TextButton.styleFrom( foregroundColor: AppColors.brandRed, visualDensity: VisualDensity.compact, tapTargetSize: MaterialTapTargetSize.shrinkWrap, minimumSize: const Size(0, _barButtonHeight), padding: const EdgeInsets.symmetric(horizontal: 4), textStyle: const TextStyle( fontSize: _barFontSize, fontWeight: FontWeight.w500, ), ), onPressed: onToggleAll, child: Text( allSelected ? l10n.deselectAll : l10n.selectAll, style: const TextStyle( fontSize: _barFontSize, fontWeight: FontWeight.w500, ), ), ), const Spacer(), TextButton( key: const Key('following-cancel-follow'), style: TextButton.styleFrom( foregroundColor: AppColors.brandRed, visualDensity: VisualDensity.compact, tapTargetSize: MaterialTapTargetSize.shrinkWrap, minimumSize: const Size(0, _removeDialogButtonHeight), padding: const EdgeInsets.symmetric(horizontal: 12), textStyle: const TextStyle( fontSize: _barFontSize, fontWeight: FontWeight.w600, ), ), onPressed: canRemove ? onRemove : null, child: Text( l10n.cancelFollowing, style: const TextStyle( fontSize: _barFontSize, fontWeight: FontWeight.w600, ), ), ), ], ), ), ), ), ); } }