merge: 移除全局两侧悬浮元素
This commit is contained in:
commit
d03dcf162e
8 files changed
+103
-217
No files matched your search
@@ -1039,3 +1039,34 @@ $ flutter test
|
|||||||
解读:用户区、UID、登录/编辑、VIP、7 项菜单顺序与跳转、旧入口可达性、
|
解读:用户区、UID、登录/编辑、VIP、7 项菜单顺序与跳转、旧入口可达性、
|
||||||
迷你播放器显隐/关闭/开播及无数据不渲染均有测试覆盖。`mine_view.dart`
|
迷你播放器显隐/关闭/开播及无数据不渲染均有测试覆盖。`mine_view.dart`
|
||||||
与新增子组件均低于 500 行;`pubspec.lock` 未提交,未操作真机。
|
与新增子组件均低于 500 行;`pubspec.lock` 未提交,未操作真机。
|
||||||
|
|
||||||
|
## 2026-10-22 全局移除两侧悬浮元素
|
||||||
|
|
||||||
|
- 分支:`feature/remove-floating-overlays`
|
||||||
|
- 基线:`develop` / `origin/develop` = `5cead7c`
|
||||||
|
|
||||||
|
### 改动
|
||||||
|
|
||||||
|
- 保留首页顶部礼物入口的 `home-wallet-badge` 红色余额角标。
|
||||||
|
- 删除「我的」页 `MineMiniPlayer` 文件、渲染分支及最近观看开播逻辑。
|
||||||
|
- 删除仅为迷你播放器新增的 `mineMini*` 尺寸 token;没有新增专属 l10n key。
|
||||||
|
- 首页、推荐、剧单、全部短剧和追剧页均不渲染两侧游戏/活动悬浮球、
|
||||||
|
悬浮关闭按钮或迷你播放器。
|
||||||
|
- 卡片角标、播放量、标题、标签和顶部钱包红标保持不变。
|
||||||
|
|
||||||
|
### 门禁命令与原始输出
|
||||||
|
|
||||||
|
```text
|
||||||
|
$ flutter analyze
|
||||||
|
Analyzing reelshort-home-floating...
|
||||||
|
No issues found! (ran in 2.5s)
|
||||||
|
```
|
||||||
|
|
||||||
|
```text
|
||||||
|
$ flutter test
|
||||||
|
01:32 +647: All tests passed!
|
||||||
|
```
|
||||||
|
|
||||||
|
解读:登录且钱包快照存在时钱包红标仍显示;首页四个 tab、推荐三个子 tab、
|
||||||
|
追剧页和我的页均断言不存在两侧悬浮组件。`pubspec.lock` 未提交,
|
||||||
|
未操作真机。
|
||||||
@@ -97,9 +97,4 @@ abstract final class AppDimens {
|
|||||||
static const double mineUserName = 20;
|
static const double mineUserName = 20;
|
||||||
static const double mineUid = 13;
|
static const double mineUid = 13;
|
||||||
static const double mineMenuIcon = 22;
|
static const double mineMenuIcon = 22;
|
||||||
static const double mineMiniWidth = 96;
|
|
||||||
static const double mineMiniHeight = 132;
|
|
||||||
static const double mineMiniRadius = 8;
|
|
||||||
static const double mineMiniTitle = 10;
|
|
||||||
static const double mineMiniClose = 22;
|
|
||||||
}
|
}
|
||||||
@@ -5,11 +5,8 @@ import 'dart:async';
|
|||||||
import 'package:flutter/material.dart';
|
import 'package:flutter/material.dart';
|
||||||
import 'package:provider/provider.dart';
|
import 'package:provider/provider.dart';
|
||||||
|
|
||||||
import '../../core/data/models/drama.dart';
|
|
||||||
import '../../core/data/models/watch_progress.dart';
|
|
||||||
import '../../core/data/repositories/watch_history_repository.dart';
|
import '../../core/data/repositories/watch_history_repository.dart';
|
||||||
import '../../core/data/services/auth_controller.dart';
|
import '../../core/data/services/auth_controller.dart';
|
||||||
import '../../core/data/services/catalog_controller.dart';
|
|
||||||
import '../../core/data/services/locale_controller.dart';
|
import '../../core/data/services/locale_controller.dart';
|
||||||
import '../../core/data/services/wallet_controller.dart';
|
import '../../core/data/services/wallet_controller.dart';
|
||||||
import '../../core/theme/app_colors.dart';
|
import '../../core/theme/app_colors.dart';
|
||||||
@@ -23,7 +20,6 @@ import '../downloads/downloads_page.dart';
|
|||||||
import '../account/account_profile_page.dart';
|
import '../account/account_profile_page.dart';
|
||||||
import '../filter/filter_page.dart';
|
import '../filter/filter_page.dart';
|
||||||
import '../notices/notices_page.dart';
|
import '../notices/notices_page.dart';
|
||||||
import '../player/open_player.dart';
|
|
||||||
import '../settings/settings_page.dart';
|
import '../settings/settings_page.dart';
|
||||||
import '../store/vip_page.dart';
|
import '../store/vip_page.dart';
|
||||||
import '../wallet/wallet_page.dart';
|
import '../wallet/wallet_page.dart';
|
||||||
@@ -33,7 +29,6 @@ import 'mine_logic.dart';
|
|||||||
import 'mine_types.dart';
|
import 'mine_types.dart';
|
||||||
import 'widgets/mine_header.dart';
|
import 'widgets/mine_header.dart';
|
||||||
import 'widgets/mine_menu.dart';
|
import 'widgets/mine_menu.dart';
|
||||||
import 'widgets/mine_mini_player.dart';
|
|
||||||
|
|
||||||
/// K28-B 我的页。
|
/// K28-B 我的页。
|
||||||
class MyPage extends StatefulWidget {
|
class MyPage extends StatefulWidget {
|
||||||
@@ -52,7 +47,6 @@ class MyPage extends StatefulWidget {
|
|||||||
|
|
||||||
class _MyPageState extends State<MyPage> {
|
class _MyPageState extends State<MyPage> {
|
||||||
late final MineLogic logic;
|
late final MineLogic logic;
|
||||||
bool _miniDismissed = false;
|
|
||||||
|
|
||||||
bool get embedded => widget.callbacks.embedded;
|
bool get embedded => widget.callbacks.embedded;
|
||||||
|
|
||||||
@@ -133,44 +127,23 @@ class _MyPageState extends State<MyPage> {
|
|||||||
|
|
||||||
Widget _body(BuildContext context, AppLocalizations l10n) {
|
Widget _body(BuildContext context, AppLocalizations l10n) {
|
||||||
final locale = context.watch<LocaleController>();
|
final locale = context.watch<LocaleController>();
|
||||||
final recent = _miniRecord;
|
return ListView(
|
||||||
return Stack(
|
key: const Key('mine-page-scroll'),
|
||||||
|
padding: const EdgeInsets.fromLTRB(
|
||||||
|
AppDimens.pageHorizontal,
|
||||||
|
0,
|
||||||
|
AppDimens.pageHorizontal,
|
||||||
|
AppDimens.spaceXl,
|
||||||
|
),
|
||||||
children: [
|
children: [
|
||||||
Positioned.fill(
|
MineHeader(onLogin: _openLogin, onEdit: _openEditActions),
|
||||||
child: ListView(
|
MineVipBanner(onOpen: () => _openDestination(MineDestination.vip)),
|
||||||
key: const Key('mine-page-scroll'),
|
const SizedBox(height: AppDimens.spaceMd),
|
||||||
padding: EdgeInsets.fromLTRB(
|
MineMenuList(
|
||||||
AppDimens.pageHorizontal,
|
onOpen: _openDestination,
|
||||||
0,
|
onLanguage: _openLanguage,
|
||||||
AppDimens.pageHorizontal,
|
languageLabel: _languageLabel(l10n, locale.locale),
|
||||||
recent == null ? AppDimens.spaceXl : 156,
|
|
||||||
),
|
|
||||||
children: [
|
|
||||||
MineHeader(onLogin: _openLogin, onEdit: _openEditActions),
|
|
||||||
MineVipBanner(
|
|
||||||
onOpen: () => _openDestination(MineDestination.vip),
|
|
||||||
),
|
|
||||||
const SizedBox(height: AppDimens.spaceMd),
|
|
||||||
MineMenuList(
|
|
||||||
onOpen: _openDestination,
|
|
||||||
onLanguage: _openLanguage,
|
|
||||||
languageLabel: _languageLabel(l10n, locale.locale),
|
|
||||||
),
|
|
||||||
],
|
|
||||||
),
|
|
||||||
),
|
),
|
||||||
if (recent != null)
|
|
||||||
Positioned(
|
|
||||||
left: AppDimens.pageHorizontal,
|
|
||||||
bottom: AppDimens.spaceMd,
|
|
||||||
child: MineMiniPlayer(
|
|
||||||
title: _miniTitle(l10n, recent),
|
|
||||||
coverUrl: recent.dramaCover?.trim() ?? '',
|
|
||||||
episodeLabel: l10n.episodeLabel(recent.episodeNumber ?? 0),
|
|
||||||
onTap: () => unawaited(_openRecent(recent)),
|
|
||||||
onClose: () => setState(() => _miniDismissed = true),
|
|
||||||
),
|
|
||||||
),
|
|
||||||
],
|
],
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
@@ -300,34 +273,6 @@ class _MyPageState extends State<MyPage> {
|
|||||||
await context.read<LocaleController>().select(selected);
|
await context.read<LocaleController>().select(selected);
|
||||||
}
|
}
|
||||||
|
|
||||||
WatchProgress? get _miniRecord {
|
|
||||||
if (_miniDismissed || logic.recent.isEmpty) return null;
|
|
||||||
final recent = logic.recent.first;
|
|
||||||
return recent.episodeId.isEmpty ? null : recent;
|
|
||||||
}
|
|
||||||
|
|
||||||
String _miniTitle(AppLocalizations l10n, WatchProgress recent) {
|
|
||||||
final title = recent.dramaTitle?.trim() ?? '';
|
|
||||||
return title.isEmpty ? l10n.episodeLabel(recent.episodeNumber ?? 0) : title;
|
|
||||||
}
|
|
||||||
|
|
||||||
Future<void> _openRecent(WatchProgress recent) async {
|
|
||||||
final catalog = context.read<CatalogController>();
|
|
||||||
final seed = Drama(
|
|
||||||
id: recent.dramaId,
|
|
||||||
title: recent.dramaTitle?.trim() ?? '',
|
|
||||||
synopsis: '',
|
|
||||||
posterUrl: recent.dramaCover?.trim() ?? '',
|
|
||||||
);
|
|
||||||
try {
|
|
||||||
final detail = await catalog.requireDetail(seed);
|
|
||||||
if (!mounted) return;
|
|
||||||
await playDramaFromCatalog(context, detail, episodeId: recent.episodeId);
|
|
||||||
} catch (_) {
|
|
||||||
// 最近记录失效时不投射错误页,等待下一次记录刷新。
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
Widget _bottomNav() {
|
Widget _bottomNav() {
|
||||||
return AppRootBottomNav(
|
return AppRootBottomNav(
|
||||||
selected: AppRootTab.mine,
|
selected: AppRootTab.mine,
|
||||||
|
|||||||
@@ -1,124 +0,0 @@
|
|||||||
// Author: fruit.com.cn
|
|
||||||
|
|
||||||
import 'package:flutter/material.dart';
|
|
||||||
|
|
||||||
import '../../../core/theme/app_colors.dart';
|
|
||||||
import '../../../core/theme/app_dimens.dart';
|
|
||||||
import '../../../core/widgets/remote_image.dart';
|
|
||||||
|
|
||||||
const double _infoHeight = 42;
|
|
||||||
|
|
||||||
/// 「我的」页左下角最近观看迷你播放器。
|
|
||||||
class MineMiniPlayer extends StatelessWidget {
|
|
||||||
const MineMiniPlayer({
|
|
||||||
super.key,
|
|
||||||
required this.title,
|
|
||||||
required this.coverUrl,
|
|
||||||
required this.episodeLabel,
|
|
||||||
required this.onTap,
|
|
||||||
required this.onClose,
|
|
||||||
});
|
|
||||||
|
|
||||||
final String title;
|
|
||||||
final String coverUrl;
|
|
||||||
final String episodeLabel;
|
|
||||||
final VoidCallback onTap;
|
|
||||||
final VoidCallback onClose;
|
|
||||||
|
|
||||||
@override
|
|
||||||
Widget build(BuildContext context) {
|
|
||||||
return SizedBox(
|
|
||||||
key: const Key('mine-mini-player'),
|
|
||||||
width: AppDimens.mineMiniWidth,
|
|
||||||
height: AppDimens.mineMiniHeight,
|
|
||||||
child: DecoratedBox(
|
|
||||||
decoration: BoxDecoration(
|
|
||||||
color: AppColors.mineCard,
|
|
||||||
borderRadius: BorderRadius.circular(AppDimens.mineMiniRadius),
|
|
||||||
border: Border.all(color: AppColors.contentBorder),
|
|
||||||
),
|
|
||||||
child: ClipRRect(
|
|
||||||
borderRadius: BorderRadius.circular(AppDimens.mineMiniRadius),
|
|
||||||
child: Material(
|
|
||||||
color: AppColors.transparent,
|
|
||||||
child: InkWell(
|
|
||||||
onTap: onTap,
|
|
||||||
child: Stack(
|
|
||||||
children: [
|
|
||||||
Column(
|
|
||||||
children: [
|
|
||||||
Expanded(
|
|
||||||
child: RemoteImage(
|
|
||||||
coverUrl,
|
|
||||||
fit: BoxFit.cover,
|
|
||||||
showFallbackIcon: true,
|
|
||||||
fallbackColor: AppColors.contentSurface,
|
|
||||||
),
|
|
||||||
),
|
|
||||||
SizedBox(
|
|
||||||
height: _infoHeight,
|
|
||||||
child: ColoredBox(
|
|
||||||
color: AppColors.mineCard,
|
|
||||||
child: Padding(
|
|
||||||
padding: const EdgeInsets.symmetric(
|
|
||||||
horizontal: 6,
|
|
||||||
vertical: 4,
|
|
||||||
),
|
|
||||||
child: Column(
|
|
||||||
crossAxisAlignment: CrossAxisAlignment.start,
|
|
||||||
children: [
|
|
||||||
Text(
|
|
||||||
title,
|
|
||||||
maxLines: 1,
|
|
||||||
overflow: TextOverflow.ellipsis,
|
|
||||||
style: const TextStyle(
|
|
||||||
color: AppColors.textPrimary,
|
|
||||||
fontSize: AppDimens.mineMiniTitle,
|
|
||||||
fontWeight: FontWeight.w600,
|
|
||||||
),
|
|
||||||
),
|
|
||||||
Text(
|
|
||||||
episodeLabel,
|
|
||||||
maxLines: 1,
|
|
||||||
overflow: TextOverflow.ellipsis,
|
|
||||||
style: const TextStyle(
|
|
||||||
color: AppColors.textSecondary,
|
|
||||||
fontSize: AppDimens.mineMiniTitle,
|
|
||||||
),
|
|
||||||
),
|
|
||||||
],
|
|
||||||
),
|
|
||||||
),
|
|
||||||
),
|
|
||||||
),
|
|
||||||
],
|
|
||||||
),
|
|
||||||
Positioned(
|
|
||||||
right: 3,
|
|
||||||
top: 3,
|
|
||||||
child: IconButton(
|
|
||||||
key: const Key('mine-mini-close'),
|
|
||||||
tooltip: MaterialLocalizations.of(
|
|
||||||
context,
|
|
||||||
).closeButtonTooltip,
|
|
||||||
onPressed: onClose,
|
|
||||||
style: IconButton.styleFrom(
|
|
||||||
minimumSize: const Size.square(AppDimens.mineMiniClose),
|
|
||||||
maximumSize: const Size.square(AppDimens.mineMiniClose),
|
|
||||||
padding: EdgeInsets.zero,
|
|
||||||
backgroundColor: AppColors.controlScrim,
|
|
||||||
foregroundColor: AppColors.textPrimary,
|
|
||||||
),
|
|
||||||
iconSize: 14,
|
|
||||||
icon: const Icon(Icons.close_rounded),
|
|
||||||
),
|
|
||||||
),
|
|
||||||
],
|
|
||||||
),
|
|
||||||
),
|
|
||||||
),
|
|
||||||
),
|
|
||||||
),
|
|
||||||
);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -71,6 +71,8 @@ void main() {
|
|||||||
expect(find.text('Charts'), findsOneWidget);
|
expect(find.text('Charts'), findsOneWidget);
|
||||||
expect(find.text('Costume'), findsOneWidget);
|
expect(find.text('Costume'), findsOneWidget);
|
||||||
expect(find.text('Community'), findsOneWidget);
|
expect(find.text('Community'), findsOneWidget);
|
||||||
|
expect(find.byKey(const Key('mine-mini-player')), findsNothing);
|
||||||
|
expect(find.byType(FloatingActionButton), findsNothing);
|
||||||
});
|
});
|
||||||
|
|
||||||
testWidgets('should_hide_unmatched_content_sections', (tester) async {
|
testWidgets('should_hide_unmatched_content_sections', (tester) async {
|
||||||
|
|||||||
@@ -3,6 +3,8 @@
|
|||||||
import 'package:flutter/material.dart';
|
import 'package:flutter/material.dart';
|
||||||
import 'package:flutter_test/flutter_test.dart';
|
import 'package:flutter_test/flutter_test.dart';
|
||||||
import 'package:fruitshorts/app.dart';
|
import 'package:fruitshorts/app.dart';
|
||||||
|
import 'package:fruitshorts/core/data/models/wallet.dart';
|
||||||
|
import 'package:fruitshorts/core/data/repositories/commerce_repository.dart';
|
||||||
import 'package:fruitshorts/core/data/repositories/favorite_repository.dart';
|
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';
|
||||||
@@ -46,6 +48,10 @@ void main() {
|
|||||||
for (final key in _keys) {
|
for (final key in _keys) {
|
||||||
expect(find.byKey(key), findsOneWidget);
|
expect(find.byKey(key), findsOneWidget);
|
||||||
}
|
}
|
||||||
|
expect(find.byKey(const Key('home-wallet-entry')), findsOneWidget);
|
||||||
|
expect(find.byKey(const Key('home-wallet-badge')), findsOneWidget);
|
||||||
|
expect(find.byKey(const Key('mine-mini-player')), findsNothing);
|
||||||
|
expect(find.byType(FloatingActionButton), findsNothing);
|
||||||
for (final key in _keys.skip(1)) {
|
for (final key in _keys.skip(1)) {
|
||||||
expect(tester.getSize(find.byKey(key)).height, greaterThanOrEqualTo(48));
|
expect(tester.getSize(find.byKey(key)).height, greaterThanOrEqualTo(48));
|
||||||
}
|
}
|
||||||
@@ -214,6 +220,7 @@ void main() {
|
|||||||
await tester.tap(find.byKey(const Key('tab-recommend')));
|
await tester.tap(find.byKey(const Key('tab-recommend')));
|
||||||
await tester.pumpAndSettle();
|
await tester.pumpAndSettle();
|
||||||
expect(find.byKey(const Key('recommend-page')), findsOneWidget);
|
expect(find.byKey(const Key('recommend-page')), findsOneWidget);
|
||||||
|
_expectNoFloatingOverlays();
|
||||||
|
|
||||||
await tester.tap(find.byKey(const Key('tab-follow')));
|
await tester.tap(find.byKey(const Key('tab-follow')));
|
||||||
await tester.pumpAndSettle();
|
await tester.pumpAndSettle();
|
||||||
@@ -226,6 +233,7 @@ void main() {
|
|||||||
findsNothing,
|
findsNothing,
|
||||||
);
|
);
|
||||||
expect(Navigator.canPop(tester.element(favorites)), isFalse);
|
expect(Navigator.canPop(tester.element(favorites)), isFalse);
|
||||||
|
_expectNoFloatingOverlays();
|
||||||
expect(
|
expect(
|
||||||
find.descendant(
|
find.descendant(
|
||||||
of: find.byKey(const Key('tab-follow')),
|
of: find.byKey(const Key('tab-follow')),
|
||||||
@@ -241,6 +249,7 @@ void main() {
|
|||||||
expect(find.byKey(const Key('mine-wallet')), findsOneWidget);
|
expect(find.byKey(const Key('mine-wallet')), findsOneWidget);
|
||||||
expect(find.byKey(const Key('mine-edit')), findsOneWidget);
|
expect(find.byKey(const Key('mine-edit')), findsOneWidget);
|
||||||
expect(find.byKey(const Key('mine-library-tab-0')), findsNothing);
|
expect(find.byKey(const Key('mine-library-tab-0')), findsNothing);
|
||||||
|
_expectNoFloatingOverlays();
|
||||||
|
|
||||||
await tester.tap(find.byKey(const Key('tab-follow')));
|
await tester.tap(find.byKey(const Key('tab-follow')));
|
||||||
await tester.pumpAndSettle();
|
await tester.pumpAndSettle();
|
||||||
@@ -287,6 +296,7 @@ Future<void> _pumpApp(WidgetTester tester, [FakeHaptics? haptics]) async {
|
|||||||
playbackRepository: FakePlaybackRepository(),
|
playbackRepository: FakePlaybackRepository(),
|
||||||
commentRepository: FakeCommentRepository(),
|
commentRepository: FakeCommentRepository(),
|
||||||
interactionRepository: FakeInteractionRepository(),
|
interactionRepository: FakeInteractionRepository(),
|
||||||
|
commerceRepository: const _WalletCommerceRepository(),
|
||||||
haptics: haptics ?? FakeHaptics(),
|
haptics: haptics ?? FakeHaptics(),
|
||||||
),
|
),
|
||||||
);
|
);
|
||||||
@@ -294,3 +304,34 @@ Future<void> _pumpApp(WidgetTester tester, [FakeHaptics? haptics]) async {
|
|||||||
await tester.tap(find.byKey(const Key('tab-home')));
|
await tester.tap(find.byKey(const Key('tab-home')));
|
||||||
await tester.pumpAndSettle();
|
await tester.pumpAndSettle();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
class _WalletCommerceRepository implements CommerceRepository {
|
||||||
|
const _WalletCommerceRepository();
|
||||||
|
|
||||||
|
@override
|
||||||
|
Future<WalletSnapshot> fetchWallet() async {
|
||||||
|
return const WalletSnapshot(
|
||||||
|
wallet: CoinWallet(
|
||||||
|
coinBalance: 320,
|
||||||
|
totalRechargedCoin: 500,
|
||||||
|
totalConsumedCoin: 180,
|
||||||
|
totalRefundedCoin: 0,
|
||||||
|
),
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
@override
|
||||||
|
Future<UnlockResult> unlock(String episodeId) async {
|
||||||
|
return const UnlockResult(
|
||||||
|
unlocked: true,
|
||||||
|
accessType: 'UNLOCKED',
|
||||||
|
coinCost: 0,
|
||||||
|
coinBalance: 320,
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void _expectNoFloatingOverlays() {
|
||||||
|
expect(find.byKey(const Key('mine-mini-player')), findsNothing);
|
||||||
|
expect(find.byType(FloatingActionButton), findsNothing);
|
||||||
|
}
|
||||||
@@ -82,12 +82,14 @@ void main() {
|
|||||||
expect(find.byKey(const Key('recommend-tab-playlist')), findsOneWidget);
|
expect(find.byKey(const Key('recommend-tab-playlist')), findsOneWidget);
|
||||||
expect(find.byKey(const Key('recommend-tab-all')), findsOneWidget);
|
expect(find.byKey(const Key('recommend-tab-all')), findsOneWidget);
|
||||||
expect(find.byKey(const Key('recommend-feed-player')), findsOneWidget);
|
expect(find.byKey(const Key('recommend-feed-player')), findsOneWidget);
|
||||||
|
_expectNoFloatingOverlays();
|
||||||
|
|
||||||
await tester.tap(find.byKey(const Key('recommend-tab-playlist')));
|
await tester.tap(find.byKey(const Key('recommend-tab-playlist')));
|
||||||
await tester.pumpAndSettle();
|
await tester.pumpAndSettle();
|
||||||
expect(find.byKey(const Key('recommend-section-hits')), findsOneWidget);
|
expect(find.byKey(const Key('recommend-section-hits')), findsOneWidget);
|
||||||
expect(find.byKey(const Key('recommend-section-new')), findsOneWidget);
|
expect(find.byKey(const Key('recommend-section-new')), findsOneWidget);
|
||||||
expect(find.byKey(const Key('recommend-section-costume')), findsOneWidget);
|
expect(find.byKey(const Key('recommend-section-costume')), findsOneWidget);
|
||||||
|
_expectNoFloatingOverlays();
|
||||||
});
|
});
|
||||||
|
|
||||||
testWidgets('should_switch_playlist_and_all_dramas_in_recommend', (
|
testWidgets('should_switch_playlist_and_all_dramas_in_recommend', (
|
||||||
@@ -101,6 +103,7 @@ void main() {
|
|||||||
await tester.pumpAndSettle();
|
await tester.pumpAndSettle();
|
||||||
expect(find.byKey(const Key('recommend-section-hits')), findsOneWidget);
|
expect(find.byKey(const Key('recommend-section-hits')), findsOneWidget);
|
||||||
expect(find.byType(AppBottomNav), findsOneWidget);
|
expect(find.byType(AppBottomNav), findsOneWidget);
|
||||||
|
_expectNoFloatingOverlays();
|
||||||
|
|
||||||
await tester.tap(find.byKey(const Key('recommend-tab-all')));
|
await tester.tap(find.byKey(const Key('recommend-tab-all')));
|
||||||
await tester.pumpAndSettle();
|
await tester.pumpAndSettle();
|
||||||
@@ -108,6 +111,7 @@ void main() {
|
|||||||
for (var row = 0; row < 4; row++) {
|
for (var row = 0; row < 4; row++) {
|
||||||
expect(find.byKey(Key('all-filter-row-$row')), findsOneWidget);
|
expect(find.byKey(Key('all-filter-row-$row')), findsOneWidget);
|
||||||
}
|
}
|
||||||
|
_expectNoFloatingOverlays();
|
||||||
});
|
});
|
||||||
|
|
||||||
testWidgets('should_open_search_from_home_and_recommend', (tester) async {
|
testWidgets('should_open_search_from_home_and_recommend', (tester) async {
|
||||||
@@ -159,6 +163,11 @@ const _tabKeys = [
|
|||||||
Key('tab-mine'),
|
Key('tab-mine'),
|
||||||
];
|
];
|
||||||
|
|
||||||
|
void _expectNoFloatingOverlays() {
|
||||||
|
expect(find.byKey(const Key('mine-mini-player')), findsNothing);
|
||||||
|
expect(find.byType(FloatingActionButton), findsNothing);
|
||||||
|
}
|
||||||
|
|
||||||
bool _hasLightStatusBar(WidgetTester tester) => tester
|
bool _hasLightStatusBar(WidgetTester tester) => tester
|
||||||
.widgetList<AnnotatedRegion<SystemUiOverlayStyle>>(
|
.widgetList<AnnotatedRegion<SystemUiOverlayStyle>>(
|
||||||
find.byType(AnnotatedRegion<SystemUiOverlayStyle>),
|
find.byType(AnnotatedRegion<SystemUiOverlayStyle>),
|
||||||
|
|||||||
@@ -14,7 +14,6 @@ import 'package:fruitshorts/l10n/app_localizations.dart';
|
|||||||
import 'package:fruitshorts/pages/auth/auth_view.dart';
|
import 'package:fruitshorts/pages/auth/auth_view.dart';
|
||||||
import 'package:fruitshorts/pages/mine/mine_types.dart';
|
import 'package:fruitshorts/pages/mine/mine_types.dart';
|
||||||
import 'package:fruitshorts/pages/mine/widgets/mine_menu.dart';
|
import 'package:fruitshorts/pages/mine/widgets/mine_menu.dart';
|
||||||
import 'package:fruitshorts/pages/player/player_view.dart';
|
|
||||||
import 'package:fruitshorts/pages/store/vip_page.dart';
|
import 'package:fruitshorts/pages/store/vip_page.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';
|
||||||
@@ -105,7 +104,7 @@ void main() {
|
|||||||
expect(find.byType(AuthPage), findsOneWidget);
|
expect(find.byType(AuthPage), findsOneWidget);
|
||||||
});
|
});
|
||||||
|
|
||||||
testWidgets('should_render_signed_in_user_and_dismiss_mini_player', (
|
testWidgets('should_render_signed_in_user_without_floating_mini_player', (
|
||||||
tester,
|
tester,
|
||||||
) async {
|
) async {
|
||||||
await _pumpApp(
|
await _pumpApp(
|
||||||
@@ -119,17 +118,8 @@ void main() {
|
|||||||
expect(find.text('UID: U-100'), findsOneWidget);
|
expect(find.text('UID: U-100'), findsOneWidget);
|
||||||
expect(find.byKey(const Key('mine-edit')), findsOneWidget);
|
expect(find.byKey(const Key('mine-edit')), findsOneWidget);
|
||||||
expect(find.byKey(const Key('mine-login')), findsNothing);
|
expect(find.byKey(const Key('mine-login')), findsNothing);
|
||||||
expect(find.byKey(const Key('mine-mini-player')), findsOneWidget);
|
|
||||||
expect(find.text('Recent drama'), findsOneWidget);
|
|
||||||
expect(find.text('Episode 3'), findsOneWidget);
|
|
||||||
expect(
|
|
||||||
tester.getSize(find.byKey(const Key('mine-mini-player'))),
|
|
||||||
const Size(AppDimens.mineMiniWidth, AppDimens.mineMiniHeight),
|
|
||||||
);
|
|
||||||
|
|
||||||
await tester.tap(find.byKey(const Key('mine-mini-close')));
|
|
||||||
await tester.pump();
|
|
||||||
expect(find.byKey(const Key('mine-mini-player')), findsNothing);
|
expect(find.byKey(const Key('mine-mini-player')), findsNothing);
|
||||||
|
expect(find.byType(FloatingActionButton), findsNothing);
|
||||||
|
|
||||||
await tester.tap(find.byKey(const Key('mine-edit')));
|
await tester.tap(find.byKey(const Key('mine-edit')));
|
||||||
await tester.pumpAndSettle();
|
await tester.pumpAndSettle();
|
||||||
@@ -143,7 +133,7 @@ void main() {
|
|||||||
expect(tester.takeException(), isNull);
|
expect(tester.takeException(), isNull);
|
||||||
});
|
});
|
||||||
|
|
||||||
testWidgets('should_open_vip_and_recent_player_from_mine_entries', (
|
testWidgets('should_open_vip_from_mine_without_floating_player', (
|
||||||
tester,
|
tester,
|
||||||
) async {
|
) async {
|
||||||
await _pumpApp(
|
await _pumpApp(
|
||||||
@@ -158,11 +148,8 @@ void main() {
|
|||||||
expect(find.byType(VipPage), findsOneWidget);
|
expect(find.byType(VipPage), findsOneWidget);
|
||||||
await tester.binding.handlePopRoute();
|
await tester.binding.handlePopRoute();
|
||||||
await tester.pumpAndSettle();
|
await tester.pumpAndSettle();
|
||||||
|
expect(find.byKey(const Key('mine-mini-player')), findsNothing);
|
||||||
await tester.tap(find.byKey(const Key('mine-mini-player')));
|
expect(find.byType(FloatingActionButton), findsNothing);
|
||||||
await tester.pumpAndSettle();
|
|
||||||
final player = tester.widget<PlayerPage>(find.byType(PlayerPage).last);
|
|
||||||
expect(player.embedded, isFalse);
|
|
||||||
});
|
});
|
||||||
|
|
||||||
testWidgets('should_expose_seven_menu_destinations_in_order', (tester) async {
|
testWidgets('should_expose_seven_menu_destinations_in_order', (tester) async {
|
||||||
|
|||||||
Reference in new issue
Block a user