// Author: fruit.com.cn import 'package:flutter/material.dart'; import '../../../core/theme/app_colors.dart'; import '../../../l10n/app_localizations.dart'; import 'player_text_size_sheet.dart'; import 'quality_sheet.dart'; const double _sheetRadius = 20; /// 更多面板运行状态。 class PlayerMoreState { /// 创建更多面板状态。 const PlayerMoreState({ required this.speed, required this.qualities, required this.textScale, required this.pipAvailable, }); /// 当前倍速。 final double speed; /// 后端下发的清晰度档位。 final List qualities; /// 当前信息文字缩放比例。 final double textScale; /// 设备是否提供画中画入口。 final bool pipAvailable; } /// 更多面板动作集合。 class PlayerMoreActions { /// 创建动作集合。 const PlayerMoreActions({ required this.onSpeed, required this.onQuality, required this.onDownload, required this.onTextSize, required this.onReport, this.onPip, }); /// 打开倍速面板。 final VoidCallback onSpeed; /// 打开清晰度面板。 final VoidCallback onQuality; /// 下载当前集。 final VoidCallback onDownload; /// 打开文字大小面板。 final VoidCallback onTextSize; /// 举报当前剧。 final VoidCallback onReport; /// 进入画中画。 final VoidCallback? onPip; } /// K28 播放页更多操作面板。 class PlayerMoreSheet extends StatelessWidget { /// 创建更多操作面板。 const PlayerMoreSheet({ super.key, required this.l10n, required this.state, required this.actions, }); /// 当前语言包。 final AppLocalizations l10n; /// 面板状态。 final PlayerMoreState state; /// 面板动作。 final PlayerMoreActions actions; @override Widget build(BuildContext context) { return Container( key: const Key('player-more-sheet'), decoration: const BoxDecoration( color: AppColors.card, borderRadius: BorderRadius.vertical(top: Radius.circular(_sheetRadius)), ), child: SafeArea( top: false, child: Padding( padding: const EdgeInsets.fromLTRB(16, 14, 16, 16), child: Column( mainAxisSize: MainAxisSize.min, crossAxisAlignment: CrossAxisAlignment.start, children: [ Padding( padding: const EdgeInsets.fromLTRB(4, 0, 4, 10), child: Text( l10n.more, style: const TextStyle( color: AppColors.onSurface, fontSize: 20, fontWeight: FontWeight.w800, ), ), ), _MoreRow( key: const Key('player-more-speed'), icon: Icons.speed_rounded, title: l10n.playbackSpeed, value: '${state.speed}x', action: actions.onSpeed, ), if (state.qualities.isNotEmpty) _MoreRow( key: const Key('player-more-quality'), icon: Icons.high_quality_rounded, title: l10n.playbackQuality, value: state.qualities.contains(QualitySheet.autoQuality) ? l10n.qualityAuto : state.qualities.first, action: actions.onQuality, ), _MoreRow( key: const Key('player-more-download'), icon: Icons.download_rounded, title: l10n.downloads, value: '', action: actions.onDownload, ), _MoreRow( key: const Key('player-more-text-size'), icon: Icons.format_size_rounded, title: l10n.textSize, value: playerTextSizeLabel(l10n, state.textScale), action: actions.onTextSize, ), if (state.pipAvailable && actions.onPip != null) _MoreRow( key: const Key('player-more-pip'), icon: Icons.picture_in_picture_alt_rounded, title: l10n.pictureInPicture, value: '', action: actions.onPip!, ), _MoreRow( key: const Key('player-more-report'), icon: Icons.flag_outlined, title: l10n.reportDrama, value: '', action: actions.onReport, ), ], ), ), ), ); } } class _MoreRow extends StatelessWidget { const _MoreRow({ super.key, required this.icon, required this.title, required this.value, required this.action, }); final IconData icon; final String title; final String value; final VoidCallback action; @override Widget build(BuildContext context) { return Material( color: Colors.transparent, borderRadius: BorderRadius.circular(12), child: InkWell( borderRadius: BorderRadius.circular(12), onTap: () { Navigator.pop(context); WidgetsBinding.instance.addPostFrameCallback((_) => action()); }, child: Padding( padding: const EdgeInsets.symmetric(horizontal: 8, vertical: 13), child: Row( children: [ Icon(icon, color: AppColors.muted, size: 21), const SizedBox(width: 12), Expanded( child: Text( title, style: const TextStyle( color: AppColors.onSurface, fontSize: 14, fontWeight: FontWeight.w700, ), ), ), if (value.isNotEmpty) Text( value, style: const TextStyle( color: AppColors.blue, fontSize: 12, fontWeight: FontWeight.w700, ), ), const SizedBox(width: 4), const Icon( Icons.chevron_right_rounded, color: AppColors.subtle, size: 20, ), ], ), ), ), ); } }