fix(flutter): 优化播放加载占位与主题色
This commit is contained in:
1 parent
9864c8e102
commit
fa5fd124a4
2 files changed
+86
-10
No files matched your search
@@ -20,6 +20,7 @@ import '../../core/theme/app_colors.dart';
|
||||
import '../../core/theme/app_theme.dart';
|
||||
import '../../core/widgets/auth_gate.dart';
|
||||
import '../../core/widgets/download_action.dart';
|
||||
import '../../core/widgets/remote_image.dart';
|
||||
import '../../l10n/app_localizations.dart';
|
||||
import 'player_binding.dart';
|
||||
import 'player_logic.dart';
|
||||
@@ -298,11 +299,7 @@ class _PlayerPageState extends State<PlayerPage> with WidgetsBindingObserver {
|
||||
return Stack(
|
||||
fit: StackFit.expand,
|
||||
children: [
|
||||
if (!ready)
|
||||
const ColoredBox(
|
||||
key: Key('player-fallback-background'),
|
||||
color: Colors.black,
|
||||
),
|
||||
if (!ready) _PlayerFallbackBackground(posterUrl: drama.posterUrl),
|
||||
?video,
|
||||
if (widget.homeMode && _chromeVisible && !logic.chromeHidden)
|
||||
Positioned.fill(
|
||||
@@ -316,7 +313,10 @@ class _PlayerPageState extends State<PlayerPage> with WidgetsBindingObserver {
|
||||
// 票据三态之一:起播前正在向后端要签名地址
|
||||
if (selected && logic.ticketLoading)
|
||||
const Center(
|
||||
child: CircularProgressIndicator(color: AppColors.blueSoft),
|
||||
child: CircularProgressIndicator(
|
||||
key: Key('player-ticket-loading'),
|
||||
color: AppColors.blue,
|
||||
),
|
||||
),
|
||||
// 票据三态之二:拿票失败(断网/服务异常)→ 可重试,不假装在加载
|
||||
if (selected && !logic.ticketLoading && logic.ticketError != null)
|
||||
@@ -348,7 +348,10 @@ class _PlayerPageState extends State<PlayerPage> with WidgetsBindingObserver {
|
||||
),
|
||||
if (selected && logic.session.loading)
|
||||
const Center(
|
||||
child: CircularProgressIndicator(color: AppColors.blueSoft),
|
||||
child: CircularProgressIndicator(
|
||||
key: Key('player-session-loading'),
|
||||
color: AppColors.blue,
|
||||
),
|
||||
),
|
||||
if (selected && !ready && logic.session.error != null)
|
||||
Center(
|
||||
@@ -550,3 +553,34 @@ class _PlayerPageState extends State<PlayerPage> with WidgetsBindingObserver {
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
class _PlayerFallbackBackground extends StatelessWidget {
|
||||
const _PlayerFallbackBackground({required this.posterUrl});
|
||||
|
||||
final String posterUrl;
|
||||
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
if (posterUrl.trim().isEmpty) {
|
||||
return const ColoredBox(
|
||||
key: Key('player-fallback-background'),
|
||||
color: Colors.black,
|
||||
);
|
||||
}
|
||||
return Stack(
|
||||
key: const Key('player-fallback-background'),
|
||||
fit: StackFit.expand,
|
||||
children: [
|
||||
RemoteImage(
|
||||
posterUrl,
|
||||
key: const Key('player-fallback-cover'),
|
||||
fit: BoxFit.cover,
|
||||
),
|
||||
const ColoredBox(
|
||||
key: Key('player-fallback-scrim'),
|
||||
color: Color(0x66000000),
|
||||
),
|
||||
],
|
||||
);
|
||||
}
|
||||
}
|
||||
@@ -49,6 +49,26 @@ void main() {
|
||||
expect(tester.takeException(), isNull);
|
||||
});
|
||||
|
||||
testWidgets('should_fall_back_to_black_when_poster_is_empty', (tester) async {
|
||||
await _pumpApp(
|
||||
tester,
|
||||
catalog: FakeCatalogRepository(dramas: const [_noCoverDrama]),
|
||||
);
|
||||
await _openSeriesPlayer(
|
||||
tester,
|
||||
cardKey: const Key('home-drama-card-no-cover-demo'),
|
||||
);
|
||||
|
||||
expect(
|
||||
tester
|
||||
.widget<ColoredBox>(
|
||||
find.byKey(const Key('player-fallback-background')),
|
||||
)
|
||||
.color,
|
||||
Colors.black,
|
||||
);
|
||||
});
|
||||
|
||||
testWidgets('should_show_center_toggle_only_when_paused', (tester) async {
|
||||
await _pumpApp(tester);
|
||||
await _openSeriesPlayer(tester);
|
||||
@@ -283,9 +303,14 @@ void main() {
|
||||
);
|
||||
expect(find.byKey(const Key('player-background')), findsNothing);
|
||||
final fallback = find.byKey(const Key('player-fallback-background'));
|
||||
if (fallback.evaluate().isNotEmpty) {
|
||||
expect(tester.widget<ColoredBox>(fallback).color, Colors.black);
|
||||
}
|
||||
expect(fallback, findsOneWidget);
|
||||
expect(find.byKey(const Key('player-fallback-cover')), findsOneWidget);
|
||||
expect(
|
||||
tester
|
||||
.widget<ColoredBox>(find.byKey(const Key('player-fallback-scrim')))
|
||||
.color,
|
||||
const Color(0x66000000),
|
||||
);
|
||||
expect(
|
||||
tester
|
||||
.widget<Scaffold>(find.byKey(const Key('player-scaffold')))
|
||||
@@ -1024,3 +1049,20 @@ const _lockedDrama = Drama(
|
||||
),
|
||||
],
|
||||
);
|
||||
|
||||
const _noCoverDrama = Drama(
|
||||
id: 'no-cover-demo',
|
||||
title: 'No Cover Demo',
|
||||
synopsis: 'No cover synopsis',
|
||||
posterUrl: '',
|
||||
detailLoaded: true,
|
||||
episodes: [
|
||||
Episode(
|
||||
id: 'no-cover-demo-1',
|
||||
number: 1,
|
||||
title: 'No Cover Episode',
|
||||
isFree: true,
|
||||
videoUrl: 'https://example.test/no-cover-demo-1.mp4',
|
||||
),
|
||||
],
|
||||
);
|
||||
Reference in new issue
Block a user