style(client): 对齐短剧列表字号与间距

This commit is contained in:
Zhou Weidong committed 2026-10-22 18:06:03 +08:00
1 parent d03dcf162e
commit d7a59e5a27
17 files changed
+576 -148

No files matched your search

+56 -8
View File
@@ -14,6 +14,7 @@ class FollowingGridCard extends StatelessWidget {
required this.title,
required this.posterUrl,
required this.viewCount,
required this.tags,
required this.subtitle,
required this.onTap,
this.progress,
@@ -25,6 +26,7 @@ class FollowingGridCard extends StatelessWidget {
final String title;
final String posterUrl;
final int viewCount;
final List<String> tags;
final String subtitle;
final VoidCallback onTap;
final double? progress;
@@ -40,7 +42,9 @@ class FollowingGridCard extends StatelessWidget {
child: Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: [
Expanded(
AspectRatio(
key: Key('following-cover-$dramaId'),
aspectRatio: AppDimens.cardCoverAspectRatio,
child: Stack(
clipBehavior: Clip.none,
children: [
@@ -75,13 +79,14 @@ class FollowingGridCard extends StatelessWidget {
const Icon(
Icons.play_arrow_rounded,
color: AppColors.textPrimary,
size: AppDimens.homeCardMeta,
size: AppDimens.cardViewsIcon,
),
Text(
formatInteractionCount(viewCount),
key: Key('following-views-$dramaId'),
style: const TextStyle(
color: AppColors.textPrimary,
fontSize: AppDimens.homeCardMeta,
fontSize: AppDimens.cardViewsFont,
),
),
],
@@ -109,24 +114,30 @@ class FollowingGridCard extends StatelessWidget {
],
),
),
const SizedBox(height: AppDimens.spaceXs),
const SizedBox(height: AppDimens.cardCoverTitleGap),
Text(
title,
maxLines: 2,
overflow: TextOverflow.ellipsis,
style: const TextStyle(
color: AppColors.textPrimary,
fontSize: AppDimens.homeCardTitle,
fontWeight: FontWeight.w600,
fontSize: AppDimens.cardTitleFont,
fontWeight: FontWeight.w500,
height: AppDimens.cardTitleLineHeight,
),
),
if (tags.isNotEmpty) ...[
const SizedBox(height: AppDimens.cardTitleTagGap),
_tags(),
],
const SizedBox(height: AppDimens.spaceXs),
Text(
subtitle,
maxLines: 1,
overflow: TextOverflow.ellipsis,
style: const TextStyle(
color: AppColors.textSecondary,
fontSize: AppDimens.homeCardMeta,
color: AppColors.textTertiary,
fontSize: AppDimens.cardViewsFont,
),
),
if (progress != null) ...[
@@ -148,4 +159,41 @@ class FollowingGridCard extends StatelessWidget {
),
);
}
Widget _tags() {
final visible = tags.take(2).toList(growable: false);
return Row(
children: [
for (final (index, tag) in visible.indexed)
Flexible(
child: Padding(
padding: EdgeInsets.only(
right: index == visible.length - 1 ? 0 : AppDimens.spaceXs,
),
child: Container(
key: Key('following-tag-$dramaId-$index'),
height: AppDimens.cardTagHeight,
alignment: Alignment.center,
padding: const EdgeInsets.symmetric(
horizontal: AppDimens.cardTagHorizontalPadding,
),
decoration: BoxDecoration(
color: AppColors.contentSurface,
borderRadius: BorderRadius.circular(AppDimens.cardTagRadius),
),
child: Text(
tag,
maxLines: 1,
overflow: TextOverflow.ellipsis,
style: const TextStyle(
color: AppColors.textTertiary,
fontSize: AppDimens.cardTagFont,
),
),
),
),
),
],
);
}
}
+67 -46
View File
@@ -5,6 +5,7 @@ import 'dart:async';
import 'package:flutter/material.dart';
import 'package:provider/provider.dart';
import '../../core/data/models/drama.dart';
import '../../core/data/models/watch_record.dart';
import '../../core/data/repositories/catalog_repository.dart';
import '../../core/data/repositories/watch_history_repository.dart';
@@ -22,6 +23,8 @@ import '../../l10n/app_localizations.dart';
import '../player/open_player.dart';
import 'following_grid_card.dart';
final RegExp _tagSplitter = RegExp(r'[,/、·]');
enum FollowingTab { favorites, history, reserve }
class FollowingPage extends StatefulWidget {
@@ -117,51 +120,56 @@ class _FollowingPageState extends State<FollowingPage> {
return SizedBox(
key: const Key('following-header'),
height: 52,
child: Row(
children: [
for (final tab in tabs)
Expanded(
child: InkWell(
key: Key('following-tab-${tab.$3}'),
onTap: () => setState(() {
_tab = tab.$1;
_editing = false;
}),
child: Column(
mainAxisAlignment: MainAxisAlignment.center,
children: [
Text(
tab.$2,
maxLines: 1,
style: TextStyle(
color: _tab == tab.$1
? AppColors.textPrimary
: AppColors.textSecondary,
fontSize: 16,
fontWeight: _tab == tab.$1
? FontWeight.w700
: FontWeight.w500,
child: Padding(
padding: const EdgeInsets.symmetric(
horizontal: AppDimens.feedPageHorizontal,
),
child: Row(
children: [
for (final tab in tabs)
Expanded(
child: InkWell(
key: Key('following-tab-${tab.$3}'),
onTap: () => setState(() {
_tab = tab.$1;
_editing = false;
}),
child: Column(
mainAxisAlignment: MainAxisAlignment.center,
children: [
Text(
tab.$2,
maxLines: 1,
style: TextStyle(
color: _tab == tab.$1
? AppColors.textPrimary
: AppColors.textTertiary,
fontSize: AppDimens.followingTabFont,
fontWeight: _tab == tab.$1
? FontWeight.w700
: FontWeight.w400,
),
),
),
const SizedBox(height: 3),
Container(
width: _tab == tab.$1 ? 20 : 0,
height: 2,
color: AppColors.textPrimary,
),
],
const SizedBox(height: 3),
Container(
width: _tab == tab.$1 ? 20 : 0,
height: 2,
color: AppColors.textPrimary,
),
],
),
),
),
IconButton(
key: const Key('following-edit'),
tooltip: _editing ? l10n.done : l10n.edit,
onPressed: () => setState(() => _editing = !_editing),
color: AppColors.textPrimary,
iconSize: 24,
icon: Icon(_editing ? Icons.check_rounded : Icons.edit_outlined),
),
IconButton(
key: const Key('following-edit'),
tooltip: _editing ? l10n.done : l10n.edit,
onPressed: () => setState(() => _editing = !_editing),
color: AppColors.textPrimary,
iconSize: 24,
icon: Icon(_editing ? Icons.check_rounded : Icons.edit_outlined),
),
],
],
),
),
);
}
@@ -233,6 +241,7 @@ class _FavoritesGrid extends StatelessWidget {
title: drama.title,
posterUrl: drama.posterUrl,
viewCount: drama.viewCount,
tags: _dramaTags(drama),
editing: editing,
subtitle: l10n.favoriteEpisodeProgress(
episode,
@@ -304,6 +313,7 @@ class _HistoryGrid extends StatelessWidget {
title: title,
posterUrl: record.displayCover,
viewCount: record.drama?.viewCount ?? 0,
tags: _dramaTags(record.drama),
progress: record.progress.fraction,
editing: editing,
subtitle: l10n.watchedToEpisode(record.episodeNumber),
@@ -322,6 +332,17 @@ class _HistoryGrid extends StatelessWidget {
}
}
List<String> _dramaTags(Drama? drama) {
if (drama == null) return const [];
final seen = <String>{};
return [drama.genre, drama.category]
.expand((value) => value.split(_tagSplitter))
.map((value) => value.trim())
.where((value) => value.isNotEmpty && seen.add(value))
.take(2)
.toList(growable: false);
}
Future<void> _openHistory(
BuildContext context,
WatchRecordsController controller,
@@ -416,17 +437,17 @@ class _PagedGrid extends StatelessWidget {
else ...[
SliverPadding(
padding: const EdgeInsets.fromLTRB(
AppDimens.pageHorizontal,
AppDimens.feedPageHorizontal,
AppDimens.spaceMd,
AppDimens.pageHorizontal,
AppDimens.feedPageHorizontal,
AppDimens.spaceSm,
),
sliver: SliverGrid(
gridDelegate: const SliverGridDelegateWithFixedCrossAxisCount(
crossAxisCount: 2,
crossAxisSpacing: AppDimens.spaceMd,
mainAxisSpacing: AppDimens.spaceMd,
childAspectRatio: 0.56,
crossAxisSpacing: AppDimens.homeGridGap,
mainAxisSpacing: AppDimens.homeGridRowGap,
childAspectRatio: AppDimens.followingGridAspectRatio,
),
delegate: SliverChildBuilderDelegate(
itemBuilder,