fix(flutter): 剧场与榜单卡片直接进播放页
This commit is contained in:
1 parent
04a1a4ee82
commit
720fd26935
6 files changed
+72
-47
No files matched your search
@@ -1,5 +1,7 @@
|
|||||||
// Author: fruit.com.cn
|
// Author: fruit.com.cn
|
||||||
|
|
||||||
|
import 'dart:async';
|
||||||
|
|
||||||
import 'package:flutter/material.dart';
|
import 'package:flutter/material.dart';
|
||||||
import 'package:flutter/services.dart';
|
import 'package:flutter/services.dart';
|
||||||
import 'package:provider/provider.dart';
|
import 'package:provider/provider.dart';
|
||||||
@@ -14,8 +16,8 @@ import '../../core/theme/app_theme.dart';
|
|||||||
import '../../core/widgets/app_bottom_nav.dart';
|
import '../../core/widgets/app_bottom_nav.dart';
|
||||||
import '../../core/widgets/empty_state.dart';
|
import '../../core/widgets/empty_state.dart';
|
||||||
import '../../l10n/app_localizations.dart';
|
import '../../l10n/app_localizations.dart';
|
||||||
import '../drama_detail/drama_detail_view.dart';
|
|
||||||
import '../new_releases/new_releases_page.dart';
|
import '../new_releases/new_releases_page.dart';
|
||||||
|
import '../player/open_player.dart';
|
||||||
import '../ranking/ranking_page.dart';
|
import '../ranking/ranking_page.dart';
|
||||||
import '../reserve/reserve_page.dart';
|
import '../reserve/reserve_page.dart';
|
||||||
import 'discover_binding.dart';
|
import 'discover_binding.dart';
|
||||||
@@ -489,9 +491,7 @@ class _DiscoverPageState extends State<DiscoverPage> {
|
|||||||
callback(drama);
|
callback(drama);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
Navigator.of(context).push<void>(
|
unawaited(playDramaFromCatalog(context, drama));
|
||||||
MaterialPageRoute(builder: (_) => DramaDetailPage(drama: drama)),
|
|
||||||
);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
Widget _bottomNav(AppLocalizations l10n) => AppBottomNav(
|
Widget _bottomNav(AppLocalizations l10n) => AppBottomNav(
|
||||||
|
|||||||
@@ -1,17 +1,13 @@
|
|||||||
// Author: fruit.com.cn
|
// Author: fruit.com.cn
|
||||||
|
|
||||||
import 'package:flutter/material.dart';
|
import 'package:flutter/material.dart';
|
||||||
import 'package:provider/provider.dart';
|
|
||||||
|
|
||||||
import '../../core/data/models/drama.dart';
|
import '../../core/data/models/drama.dart';
|
||||||
import '../../core/data/services/catalog_controller.dart';
|
|
||||||
import '../../core/data/services/download_controller.dart';
|
|
||||||
import '../../core/data/services/wallet_controller.dart';
|
|
||||||
import '../discover/discover_types.dart';
|
import '../discover/discover_types.dart';
|
||||||
import '../drama_detail/drama_detail_view.dart';
|
import '../drama_detail/drama_detail_view.dart';
|
||||||
import '../favorites/favorites_page.dart';
|
import '../favorites/favorites_page.dart';
|
||||||
import '../mine/mine_types.dart';
|
import '../mine/mine_types.dart';
|
||||||
import '../player/player_view.dart';
|
import '../player/open_player.dart';
|
||||||
import '../watch_records/watch_records_page.dart';
|
import '../watch_records/watch_records_page.dart';
|
||||||
|
|
||||||
class HomeLogic extends ChangeNotifier {
|
class HomeLogic extends ChangeNotifier {
|
||||||
@@ -73,29 +69,7 @@ class HomeLogic extends ChangeNotifier {
|
|||||||
BuildContext context,
|
BuildContext context,
|
||||||
Drama drama, {
|
Drama drama, {
|
||||||
String? episodeId,
|
String? episodeId,
|
||||||
}) async {
|
}) => playDramaFromCatalog(context, drama, episodeId: episodeId);
|
||||||
// 列表卡片只有一集预览,进入播放前补齐完整剧集,否则选集列表是空的。
|
|
||||||
var playable = drama;
|
|
||||||
try {
|
|
||||||
playable = await context.read<CatalogController>().requireDetail(drama);
|
|
||||||
} catch (_) {
|
|
||||||
// 取详情失败就用卡片自带的那一集起播。
|
|
||||||
}
|
|
||||||
if (!context.mounted) return;
|
|
||||||
final index = episodeId == null
|
|
||||||
? 0
|
|
||||||
: playable.episodes.indexWhere((episode) => episode.id == episodeId);
|
|
||||||
await Navigator.of(context).push(
|
|
||||||
MaterialPageRoute<void>(
|
|
||||||
builder: (_) => PlayerPage(
|
|
||||||
drama: playable,
|
|
||||||
initialIndex: index < 0 ? 0 : index,
|
|
||||||
wallet: context.read<WalletController>(),
|
|
||||||
downloads: context.read<DownloadController>(),
|
|
||||||
),
|
|
||||||
),
|
|
||||||
);
|
|
||||||
}
|
|
||||||
|
|
||||||
void openProfile() => select(3);
|
void openProfile() => select(3);
|
||||||
|
|
||||||
|
|||||||
@@ -1,5 +1,7 @@
|
|||||||
// Author: fruit.com.cn
|
// Author: fruit.com.cn
|
||||||
|
|
||||||
|
import 'dart:async';
|
||||||
|
|
||||||
import 'package:flutter/material.dart';
|
import 'package:flutter/material.dart';
|
||||||
import 'package:provider/provider.dart';
|
import 'package:provider/provider.dart';
|
||||||
|
|
||||||
@@ -8,7 +10,7 @@ import '../../core/widgets/empty_state.dart';
|
|||||||
import '../../core/widgets/plain_page_scaffold.dart';
|
import '../../core/widgets/plain_page_scaffold.dart';
|
||||||
import '../../l10n/app_localizations.dart';
|
import '../../l10n/app_localizations.dart';
|
||||||
import '../discover/widgets/drama_grid.dart';
|
import '../discover/widgets/drama_grid.dart';
|
||||||
import '../drama_detail/drama_detail_view.dart';
|
import '../player/open_player.dart';
|
||||||
|
|
||||||
/// 剧场新剧页:按 id 倒序展示最新上架短剧。
|
/// 剧场新剧页:按 id 倒序展示最新上架短剧。
|
||||||
class NewReleasesPage extends StatelessWidget {
|
class NewReleasesPage extends StatelessWidget {
|
||||||
@@ -31,11 +33,8 @@ class NewReleasesPage extends StatelessWidget {
|
|||||||
child: DramaGrid(
|
child: DramaGrid(
|
||||||
l10n: l10n,
|
l10n: l10n,
|
||||||
dramas: dramas,
|
dramas: dramas,
|
||||||
onOpen: (drama) => Navigator.of(context).push<void>(
|
onOpen: (drama) =>
|
||||||
MaterialPageRoute(
|
unawaited(playDramaFromCatalog(context, drama)),
|
||||||
builder: (_) => DramaDetailPage(drama: drama),
|
|
||||||
),
|
|
||||||
),
|
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
);
|
);
|
||||||
|
|||||||
@@ -0,0 +1,41 @@
|
|||||||
|
// Author: fruit.com.cn
|
||||||
|
|
||||||
|
import 'package:flutter/material.dart';
|
||||||
|
import 'package:provider/provider.dart';
|
||||||
|
|
||||||
|
import '../../core/data/models/drama.dart';
|
||||||
|
import '../../core/data/services/catalog_controller.dart';
|
||||||
|
import '../../core/data/services/download_controller.dart';
|
||||||
|
import '../../core/data/services/wallet_controller.dart';
|
||||||
|
import 'player_view.dart';
|
||||||
|
|
||||||
|
/// 目录卡片统一入口:补齐详情后直接进入全屏播放页。
|
||||||
|
Future<void> playDramaFromCatalog(
|
||||||
|
BuildContext context,
|
||||||
|
Drama drama, {
|
||||||
|
String? episodeId,
|
||||||
|
}) async {
|
||||||
|
final catalog = context.read<CatalogController>();
|
||||||
|
final wallet = context.read<WalletController>();
|
||||||
|
final downloads = context.read<DownloadController>();
|
||||||
|
var playable = drama;
|
||||||
|
try {
|
||||||
|
playable = await catalog.requireDetail(drama);
|
||||||
|
} catch (_) {
|
||||||
|
// 取详情失败就用卡片自带的可播预览集起播。
|
||||||
|
}
|
||||||
|
if (!context.mounted) return;
|
||||||
|
final index = episodeId == null
|
||||||
|
? 0
|
||||||
|
: playable.episodes.indexWhere((episode) => episode.id == episodeId);
|
||||||
|
await Navigator.of(context).push(
|
||||||
|
MaterialPageRoute<void>(
|
||||||
|
builder: (_) => PlayerPage(
|
||||||
|
drama: playable,
|
||||||
|
initialIndex: index < 0 ? 0 : index,
|
||||||
|
wallet: wallet,
|
||||||
|
downloads: downloads,
|
||||||
|
),
|
||||||
|
),
|
||||||
|
);
|
||||||
|
}
|
||||||
@@ -1,5 +1,7 @@
|
|||||||
// Author: fruit.com.cn
|
// Author: fruit.com.cn
|
||||||
|
|
||||||
|
import 'dart:async';
|
||||||
|
|
||||||
import 'package:flutter/material.dart';
|
import 'package:flutter/material.dart';
|
||||||
import 'package:provider/provider.dart';
|
import 'package:provider/provider.dart';
|
||||||
|
|
||||||
@@ -12,7 +14,7 @@ import '../../core/widgets/empty_state.dart';
|
|||||||
import '../../core/widgets/plain_page_scaffold.dart';
|
import '../../core/widgets/plain_page_scaffold.dart';
|
||||||
import '../../core/widgets/remote_image.dart';
|
import '../../core/widgets/remote_image.dart';
|
||||||
import '../../l10n/app_localizations.dart';
|
import '../../l10n/app_localizations.dart';
|
||||||
import '../drama_detail/drama_detail_view.dart';
|
import '../player/open_player.dart';
|
||||||
|
|
||||||
const int _topCount = 50;
|
const int _topCount = 50;
|
||||||
const double _podiumGap = 8;
|
const double _podiumGap = 8;
|
||||||
@@ -134,9 +136,7 @@ class _PodiumCard extends StatelessWidget {
|
|||||||
@override
|
@override
|
||||||
Widget build(BuildContext context) {
|
Widget build(BuildContext context) {
|
||||||
return GestureDetector(
|
return GestureDetector(
|
||||||
onTap: () => Navigator.of(context).push<void>(
|
onTap: () => unawaited(playDramaFromCatalog(context, drama)),
|
||||||
MaterialPageRoute(builder: (_) => DramaDetailPage(drama: drama)),
|
|
||||||
),
|
|
||||||
child: Column(
|
child: Column(
|
||||||
mainAxisSize: MainAxisSize.min,
|
mainAxisSize: MainAxisSize.min,
|
||||||
children: [
|
children: [
|
||||||
@@ -246,9 +246,7 @@ class _RankingRow extends StatelessWidget {
|
|||||||
clipBehavior: Clip.antiAlias,
|
clipBehavior: Clip.antiAlias,
|
||||||
child: InkWell(
|
child: InkWell(
|
||||||
key: Key('ranking-row-$index'),
|
key: Key('ranking-row-$index'),
|
||||||
onTap: () => Navigator.of(context).push<void>(
|
onTap: () => unawaited(playDramaFromCatalog(context, drama)),
|
||||||
MaterialPageRoute(builder: (_) => DramaDetailPage(drama: drama)),
|
|
||||||
),
|
|
||||||
child: Padding(
|
child: Padding(
|
||||||
padding: const EdgeInsets.all(10),
|
padding: const EdgeInsets.all(10),
|
||||||
child: Row(
|
child: Row(
|
||||||
|
|||||||
@@ -8,7 +8,6 @@ import 'package:fruitshorts/core/data/repositories/favorite_repository.dart';
|
|||||||
import 'package:fruitshorts/core/data/repositories/playback_repository.dart';
|
import 'package:fruitshorts/core/data/repositories/playback_repository.dart';
|
||||||
import 'package:fruitshorts/core/data/repositories/watch_history_repository.dart';
|
import 'package:fruitshorts/core/data/repositories/watch_history_repository.dart';
|
||||||
import 'package:fruitshorts/pages/discover/widgets/drama_grid.dart';
|
import 'package:fruitshorts/pages/discover/widgets/drama_grid.dart';
|
||||||
import 'package:fruitshorts/pages/drama_detail/drama_detail_view.dart';
|
|
||||||
import 'package:shared_preferences_platform_interface/in_memory_shared_preferences_async.dart';
|
import 'package:shared_preferences_platform_interface/in_memory_shared_preferences_async.dart';
|
||||||
import 'package:shared_preferences_platform_interface/shared_preferences_async_platform_interface.dart';
|
import 'package:shared_preferences_platform_interface/shared_preferences_async_platform_interface.dart';
|
||||||
|
|
||||||
@@ -38,7 +37,7 @@ void main() {
|
|||||||
|
|
||||||
await tester.tap(find.byKey(const Key('ranking-top-1')));
|
await tester.tap(find.byKey(const Key('ranking-top-1')));
|
||||||
await tester.pumpAndSettle();
|
await tester.pumpAndSettle();
|
||||||
expect(find.byType(DramaDetailPage), findsOneWidget);
|
expect(find.byKey(const Key('player-scaffold')), findsOneWidget);
|
||||||
});
|
});
|
||||||
|
|
||||||
testWidgets('should_open_new_releases_sorted_by_id', (tester) async {
|
testWidgets('should_open_new_releases_sorted_by_id', (tester) async {
|
||||||
@@ -115,6 +114,20 @@ void main() {
|
|||||||
expect(find.byKey(const Key('ranking-top-3')), findsNothing);
|
expect(find.byKey(const Key('ranking-top-3')), findsNothing);
|
||||||
});
|
});
|
||||||
|
|
||||||
|
testWidgets('should_open_player_from_new_releases_card', (tester) async {
|
||||||
|
await _pumpTheater(tester);
|
||||||
|
await tester.tap(find.byKey(const Key('theater-toolbar-new')));
|
||||||
|
await tester.pumpAndSettle();
|
||||||
|
|
||||||
|
final card = find.byKey(const Key('home-drama-card-the-signal-demo'));
|
||||||
|
await tester.ensureVisible(card);
|
||||||
|
await tester.pumpAndSettle();
|
||||||
|
await tester.tap(card);
|
||||||
|
await tester.pumpAndSettle();
|
||||||
|
|
||||||
|
expect(find.byKey(const Key('player-scaffold')), findsOneWidget);
|
||||||
|
});
|
||||||
|
|
||||||
testWidgets('should_go_back_to_theater_from_ranking_page', (tester) async {
|
testWidgets('should_go_back_to_theater_from_ranking_page', (tester) async {
|
||||||
await _pumpTheater(tester);
|
await _pumpTheater(tester);
|
||||||
await tester.tap(find.byKey(const Key('theater-toolbar-ranking')));
|
await tester.tap(find.byKey(const Key('theater-toolbar-ranking')));
|
||||||
|
|||||||
Reference in new issue
Block a user