fix(home): 调整榜单版式并去掉二级分类

This commit is contained in:
Zhou Weidong committed 2026-10-23 03:18:24 +08:00
1 parent 60489d6dca
commit f4cf7bc2dd
7 files changed
+90 -316

No files matched your search

+7 -22
View File
@@ -14,6 +14,7 @@ import '../../../core/data/services/home_feed_controller.dart';
import '../../../core/data/services/wallet_controller.dart';
import '../../../core/theme/app_colors.dart';
import '../../../core/theme/app_dimens.dart';
import '../../../core/theme/app_theme.dart';
import '../../../core/widgets/app_pull_to_refresh.dart';
import '../../../core/widgets/drama_grid_skeleton.dart';
import '../../../core/widgets/empty_state.dart';
@@ -81,17 +82,16 @@ class _HomeFeedGridState extends State<HomeFeedGrid> {
final auth = context.watch<AuthController>();
final wallet = context.watch<WalletController>();
final shortcuts = _categoryShortcuts(categories, l10n);
final tags = _availableTags(l10n);
final activeTag =
tags.any((tag) => tag.id == _selectedTags[_selectedPrimary])
? _selectedTags[_selectedPrimary]
: null;
final walletBadge = auth.isSignedIn && wallet.snapshot != null
? wallet.balance
: null;
return ColoredBox(
final ranking = _selectedPrimary == HomePrimaryTab.ranking;
return DecoratedBox(
key: const Key('home-grid'),
color: AppColors.appBackground,
decoration: BoxDecoration(
color: ranking ? null : AppColors.appBackground,
gradient: ranking ? AppTheme.pageGradient : null,
),
child: SafeArea(
bottom: false,
child: Column(
@@ -100,12 +100,8 @@ class _HomeFeedGridState extends State<HomeFeedGrid> {
HomeGridHeader(
callbacks: widget.callbacks,
categories: shortcuts,
tags: tags,
selectedPrimary: _selectedPrimary,
selectedTag: activeTag,
onPrimarySelected: _selectPrimary,
onTagSelected: (tag) =>
setState(() => _selectedTags[_selectedPrimary] = tag),
walletBadge: walletBadge,
),
Expanded(
@@ -322,17 +318,6 @@ class _HomeFeedGridState extends State<HomeFeedGrid> {
return null;
}
List<HomeGridTagOption> _availableTags(AppLocalizations l10n) {
// UI 先完整展示筛选维度;后续接口补齐题材字段时只替换数据来源。
return [
HomeGridTagOption(id: 'hot', label: l10n.homeTagHot),
HomeGridTagOption(id: 'uplifting', label: l10n.homeTagUplifting),
HomeGridTagOption(id: 'sweet', label: l10n.homeTagSweet),
HomeGridTagOption(id: 'faceSlap', label: l10n.homeTagFaceSlap),
HomeGridTagOption(id: 'angst', label: l10n.homeTagAngst),
];
}
List<Drama> _dramasFor(
HomePrimaryTab tab,
String? tag,
+1 -132
View File
@@ -28,13 +28,6 @@ class HomeGridCategoryShortcut {
final HomePrimaryTab tab;
}
class HomeGridTagOption {
const HomeGridTagOption({required this.id, required this.label});
final String id;
final String label;
}
class HomeGridCallbacks {
const HomeGridCallbacks({
required this.onSearch,
@@ -54,21 +47,15 @@ class HomeGridHeader extends StatelessWidget {
super.key,
required this.callbacks,
required this.categories,
required this.tags,
required this.selectedPrimary,
required this.selectedTag,
required this.onPrimarySelected,
required this.onTagSelected,
this.walletBadge,
});
final HomeGridCallbacks callbacks;
final List<HomeGridCategoryShortcut> categories;
final List<HomeGridTagOption> tags;
final HomePrimaryTab selectedPrimary;
final String? selectedTag;
final ValueChanged<HomePrimaryTab> onPrimarySelected;
final ValueChanged<String?> onTagSelected;
final int? walletBadge;
@override
@@ -81,10 +68,7 @@ class HomeGridHeader extends StatelessWidget {
children: [
_searchRow(l10n),
_primaryRow(l10n),
if (selectedPrimary == HomePrimaryTab.featured)
_tagRow(l10n)
else
const SizedBox(height: AppDimens.homeSecondaryGridGap),
const SizedBox(height: AppDimens.homeSecondaryGridGap),
],
);
}
@@ -323,119 +307,4 @@ class HomeGridHeader extends StatelessWidget {
),
);
}
Widget _tagRow(AppLocalizations l10n) {
return Padding(
padding: const EdgeInsets.fromLTRB(
AppDimens.feedPageHorizontal,
AppDimens.homePrimarySecondaryGap,
AppDimens.feedPageHorizontal,
AppDimens.homeSecondaryGridGap,
),
child: Row(
crossAxisAlignment: CrossAxisAlignment.center,
mainAxisAlignment: MainAxisAlignment.start,
children: [
Expanded(
child: SingleChildScrollView(
key: const Key('home-secondary-tags'),
scrollDirection: Axis.horizontal,
child: Row(
crossAxisAlignment: CrossAxisAlignment.center,
mainAxisAlignment: MainAxisAlignment.start,
children: [
for (final tag in tags) ...[
_tagChip(tag),
const SizedBox(width: AppDimens.homeSecondaryTagGap),
],
],
),
),
),
const SizedBox(width: AppDimens.homeSecondaryFilterGap),
Tooltip(
message: l10n.filter,
child: SizedBox.square(
dimension: AppDimens.homeSecondaryFilterVisualSize,
child: Material(
color: AppColors.transparent,
child: InkWell(
key: const Key('home-grid-filter'),
onTap: callbacks.onOpenFilter,
child: Center(
child: SizedBox.square(
key: const Key('home-secondary-filter-visual'),
dimension: AppDimens.homeSecondaryFilterVisualSize,
child: const Center(
child: CustomPaint(
key: Key('home-secondary-filter-icon'),
size: Size.square(AppDimens.homeSecondaryFilterIcon),
painter: _ThreeLineFilterPainter(),
),
),
),
),
),
),
),
),
],
),
);
}
Widget _tagChip(HomeGridTagOption tag) {
final selected = selectedTag == tag.id;
final label = Text(
tag.label,
style: TextStyle(
color: selected ? AppColors.navSelected : AppColors.textTertiary,
fontSize: AppDimens.homeSecondaryTagFont,
fontWeight: FontWeight.w600,
letterSpacing: 0,
),
);
return InkWell(
key: Key('home-tag-${tag.id}'),
borderRadius: BorderRadius.circular(AppDimens.pillRadius),
onTap: () => onTagSelected(selected ? null : tag.id),
child: AnimatedContainer(
key: Key('home-tag-animated-${tag.id}'),
duration: AppDimens.homeSecondaryTagAnimationDuration,
curve: Curves.easeOut,
height: AppDimens.homeSecondaryTagHeight,
padding: const EdgeInsets.symmetric(
horizontal: AppDimens.homeSecondaryTagHorizontalPadding,
),
alignment: Alignment.center,
decoration: BoxDecoration(
color: selected ? AppColors.contentSurface : AppColors.transparent,
borderRadius: BorderRadius.circular(AppDimens.homeSecondaryTagRadius),
),
child: label,
),
);
}
}
class _ThreeLineFilterPainter extends CustomPainter {
const _ThreeLineFilterPainter();
@override
void paint(Canvas canvas, Size size) {
final paint = Paint()
..color = AppColors.textFilterIcon
..strokeWidth = AppDimens.homeSecondaryFilterStroke
..strokeCap = StrokeCap.butt;
for (final y in [
size.height * 0.25,
size.height * 0.5,
size.height * 0.75,
]) {
canvas.drawLine(Offset(0, y), Offset(size.width, y), paint);
}
}
@override
bool shouldRepaint(_ThreeLineFilterPainter oldDelegate) => false;
}