feat(app): 完善播放协议搜索与空状态
This commit is contained in:
1 parent
671e0ce143
commit
ef29fc5f15
85 files changed
+2976
-768
No files matched your search
@@ -22,19 +22,25 @@ const double _segmentTrackRadius = 10;
|
||||
const double _segmentTrackPadding = 4;
|
||||
const double _segmentPadding = 10;
|
||||
const List<double> _speedOptions = [0.75, 1.0, 1.25, 1.5, 2.0, 3.0];
|
||||
const List<String> _qualityOptions = ['AUTO', '720P', '1080P'];
|
||||
const String _autoQuality = 'AUTO';
|
||||
const List<String> _qualityOptions = ['AUTO', '360P', '480P', '720P', '1080P'];
|
||||
|
||||
/// 更多面板运行状态。
|
||||
class PlayerMoreState {
|
||||
/// 创建更多面板状态。
|
||||
const PlayerMoreState({required this.speed, required this.qualities});
|
||||
const PlayerMoreState({
|
||||
required this.speed,
|
||||
required this.qualities,
|
||||
this.selectedQuality = 'AUTO',
|
||||
});
|
||||
|
||||
/// 当前倍速。
|
||||
final double speed;
|
||||
|
||||
/// 后端下发的清晰度档位。
|
||||
final List<String> qualities;
|
||||
|
||||
/// 当前选中的档位,如 AUTO / 720P。
|
||||
final String selectedQuality;
|
||||
}
|
||||
|
||||
/// 更多面板动作集合。
|
||||
@@ -44,6 +50,7 @@ class PlayerMoreActions {
|
||||
required this.onSpeedChanged,
|
||||
required this.onClear,
|
||||
required this.onDownload,
|
||||
required this.onQualityChanged,
|
||||
this.onPip,
|
||||
});
|
||||
|
||||
@@ -56,6 +63,9 @@ class PlayerMoreActions {
|
||||
/// 离线缓存当前集。
|
||||
final VoidCallback onDownload;
|
||||
|
||||
/// 切换清晰度。成功返回 true;失败时面板恢复到上一档。
|
||||
final Future<bool> Function(String quality) onQualityChanged;
|
||||
|
||||
/// 进入小窗播放;平台不支持时为 null。
|
||||
final VoidCallback? onPip;
|
||||
}
|
||||
@@ -85,6 +95,7 @@ class PlayerMoreSheet extends StatefulWidget {
|
||||
|
||||
class _PlayerMoreSheetState extends State<PlayerMoreSheet> {
|
||||
late double _speed = widget.state.speed;
|
||||
late String _quality = widget.state.selectedQuality.toUpperCase();
|
||||
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
@@ -247,19 +258,31 @@ class _PlayerMoreSheetState extends State<PlayerMoreSheet> {
|
||||
);
|
||||
}
|
||||
|
||||
Future<void> _chooseQuality(String quality) async {
|
||||
if (_quality == quality) return;
|
||||
final previous = _quality;
|
||||
setState(() => _quality = quality);
|
||||
final switched = await widget.actions.onQualityChanged(quality);
|
||||
if (!mounted || switched) return;
|
||||
setState(() => _quality = previous);
|
||||
}
|
||||
|
||||
bool _hasQuality(String quality) {
|
||||
final wanted = quality.toUpperCase();
|
||||
for (final item in widget.state.qualities) {
|
||||
if (item.toUpperCase() == wanted) return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
Widget _qualitySegment(AppLocalizations l10n, String quality) {
|
||||
final enabled = widget.state.qualities.contains(quality);
|
||||
final selected =
|
||||
quality == _autoQuality && enabled ||
|
||||
!widget.state.qualities.contains(_autoQuality) &&
|
||||
widget.state.qualities.isNotEmpty &&
|
||||
widget.state.qualities.first == quality;
|
||||
final enabled = _hasQuality(quality);
|
||||
return _SegmentButton(
|
||||
key: Key('player-more-quality-$quality'),
|
||||
label: enabled ? quality : '$quality · ${l10n.qualityUnavailable}',
|
||||
selected: selected,
|
||||
selected: enabled && _quality == quality,
|
||||
enabled: enabled,
|
||||
onTap: enabled ? () {} : null,
|
||||
onTap: enabled ? () => _chooseQuality(quality) : null,
|
||||
);
|
||||
}
|
||||
|
||||
|
||||
Reference in new issue
Block a user