fix(i18n): 印尼语内容缺失时不再回退中文
This commit is contained in:
1 parent
9ef8eb15b0
commit
19196ceb8e
13 files changed
+261
-95
No files matched your search
@@ -241,11 +241,11 @@ class Drama {
|
||||
}
|
||||
|
||||
String localizedTitle(String languageCode) {
|
||||
return localizedText(languageCode, title, titleLocales);
|
||||
return localizedRequiredText(languageCode, title, titleLocales);
|
||||
}
|
||||
|
||||
String localizedSynopsis(String languageCode) {
|
||||
return localizedText(languageCode, synopsis, synopsisLocales);
|
||||
return localizedRequiredText(languageCode, synopsis, synopsisLocales);
|
||||
}
|
||||
|
||||
String localizedTag(String languageCode) {
|
||||
|
||||
@@ -7,10 +7,27 @@ Map<String, String> localeMap(Object? raw) {
|
||||
}
|
||||
|
||||
/// 按当前语言取文案。没有对应语言时用中文,中文也没有时用 fallback。
|
||||
String localizedText(String languageCode, String fallback, Map<String, String> locales) {
|
||||
String localizedText(
|
||||
String languageCode,
|
||||
String fallback,
|
||||
Map<String, String> locales,
|
||||
) {
|
||||
final selected = locales[languageCode] ?? '';
|
||||
if (selected.isNotEmpty) return selected;
|
||||
final chinese = locales['zh'] ?? '';
|
||||
if (chinese.isNotEmpty) return chinese;
|
||||
return fallback;
|
||||
}
|
||||
|
||||
/// 按当前语言取必须本地化的文案;印尼语缺失时不回退中文。
|
||||
String localizedRequiredText(
|
||||
String languageCode,
|
||||
String fallback,
|
||||
Map<String, String> locales,
|
||||
) {
|
||||
final primaryCode = languageCode.split(RegExp(r'[_-]')).first;
|
||||
final selected = locales[languageCode] ?? locales[primaryCode] ?? '';
|
||||
if (selected.trim().isNotEmpty) return selected;
|
||||
if (primaryCode == 'id') return '';
|
||||
return localizedText(primaryCode, fallback, locales);
|
||||
}
|
||||
@@ -0,0 +1,21 @@
|
||||
// Author: fruit.com.cn
|
||||
|
||||
import '../data/models/drama.dart';
|
||||
|
||||
const String _indonesianLanguageCode = 'id';
|
||||
|
||||
/// 判断短剧是否满足当前界面语言的基础文案完整度。
|
||||
bool isDramaCompleteForLocale(Drama drama, String languageCode) {
|
||||
final primaryCode = languageCode.split(RegExp(r'[_-]')).first;
|
||||
if (primaryCode != _indonesianLanguageCode) return true;
|
||||
return drama.localizedTitle(primaryCode).trim().isNotEmpty &&
|
||||
drama.localizedSynopsis(primaryCode).trim().isNotEmpty;
|
||||
}
|
||||
|
||||
/// 过滤不满足首发语言文案完整度的短剧,保持原顺序。
|
||||
List<Drama> visibleDramasForLocale(
|
||||
Iterable<Drama> dramas,
|
||||
String languageCode,
|
||||
) => dramas
|
||||
.where((drama) => isDramaCompleteForLocale(drama, languageCode))
|
||||
.toList(growable: false);
|
||||
@@ -4,6 +4,7 @@ import 'package:flutter/material.dart';
|
||||
|
||||
import '../../../core/data/models/drama.dart';
|
||||
import '../../../core/formatting/error_text.dart';
|
||||
import '../../../core/formatting/content_locale_guard.dart';
|
||||
import '../../../core/theme/app_colors.dart';
|
||||
import '../../../core/widgets/empty_state.dart';
|
||||
import '../../../l10n/app_localizations.dart';
|
||||
@@ -33,10 +34,18 @@ class DiscoverSearchResults extends StatelessWidget {
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
final l10n = AppLocalizations.of(context)!;
|
||||
if (!loading && error == null && results.isNotEmpty) {
|
||||
final visibleResults = visibleDramasForLocale(
|
||||
results,
|
||||
Localizations.localeOf(context).languageCode,
|
||||
);
|
||||
if (!loading && error == null && visibleResults.isNotEmpty) {
|
||||
return SliverPadding(
|
||||
padding: _topPadding,
|
||||
sliver: SliverDramaGrid(l10n: l10n, dramas: results, onOpen: onOpen),
|
||||
sliver: SliverDramaGrid(
|
||||
l10n: l10n,
|
||||
dramas: visibleResults,
|
||||
onOpen: onOpen,
|
||||
),
|
||||
);
|
||||
}
|
||||
return SliverPadding(
|
||||
|
||||
@@ -7,6 +7,7 @@ import 'package:provider/provider.dart';
|
||||
|
||||
import '../../../core/data/models/drama.dart';
|
||||
import '../../../core/data/services/category_controller.dart';
|
||||
import '../../../core/formatting/content_locale_guard.dart';
|
||||
import '../../../core/theme/app_dimens.dart';
|
||||
import '../../../core/widgets/app_pull_to_refresh.dart';
|
||||
import '../../../core/widgets/drama_grid_skeleton.dart';
|
||||
@@ -77,7 +78,10 @@ class _HomeCategoryDramasState extends State<HomeCategoryDramas> {
|
||||
final controller = context.watch<CategoryController>();
|
||||
final categoryId = widget.lockedCategoryId ?? '';
|
||||
final slot = categoryId.isEmpty ? null : controller.slotOf(categoryId);
|
||||
final dramas = slot?.dramas ?? const <Drama>[];
|
||||
final dramas = visibleDramasForLocale(
|
||||
slot?.dramas ?? const <Drama>[],
|
||||
Localizations.localeOf(context).languageCode,
|
||||
);
|
||||
return Column(
|
||||
children: [
|
||||
Expanded(
|
||||
@@ -164,9 +168,8 @@ class _HomeCategoryDramasState extends State<HomeCategoryDramas> {
|
||||
hasMore: slot?.hasMore ?? false,
|
||||
hasItems: dramas.isNotEmpty,
|
||||
errorMessage: null,
|
||||
onRetry: () => context.read<CategoryController>().loadMore(
|
||||
categoryId,
|
||||
),
|
||||
onRetry: () =>
|
||||
context.read<CategoryController>().loadMore(categoryId),
|
||||
),
|
||||
),
|
||||
),
|
||||
|
||||
@@ -12,6 +12,7 @@ import '../../../core/data/services/catalog_controller.dart';
|
||||
import '../../../core/data/services/category_controller.dart';
|
||||
import '../../../core/data/services/home_feed_controller.dart';
|
||||
import '../../../core/data/services/wallet_controller.dart';
|
||||
import '../../../core/formatting/content_locale_guard.dart';
|
||||
import '../../../core/theme/app_colors.dart';
|
||||
import '../../../core/theme/app_dimens.dart';
|
||||
import '../../../core/widgets/app_pull_to_refresh.dart';
|
||||
@@ -194,7 +195,10 @@ class _HomeFeedGridState extends State<HomeFeedGrid> {
|
||||
mainAxisSpacing: AppDimens.homeGridRowGap,
|
||||
);
|
||||
}
|
||||
final dramas = _dramasFor(category);
|
||||
final dramas = _dramasFor(
|
||||
category,
|
||||
Localizations.localeOf(context).languageCode,
|
||||
);
|
||||
if (widget.feedController.loadingFirstPage && dramas.isEmpty) {
|
||||
return const DramaGridSkeleton(
|
||||
key: Key('home-grid-skeleton'),
|
||||
@@ -324,8 +328,14 @@ class _HomeFeedGridState extends State<HomeFeedGrid> {
|
||||
];
|
||||
}
|
||||
|
||||
List<Drama> _dramasFor(HomeGridCategoryShortcut category) {
|
||||
final dramas = widget.feedController.dramas;
|
||||
List<Drama> _dramasFor(
|
||||
HomeGridCategoryShortcut category,
|
||||
String languageCode,
|
||||
) {
|
||||
final dramas = visibleDramasForLocale(
|
||||
widget.feedController.dramas,
|
||||
languageCode,
|
||||
);
|
||||
final categoryName = category.categoryName.toLowerCase();
|
||||
if (categoryName.isEmpty) return dramas;
|
||||
final matched = dramas
|
||||
|
||||
@@ -9,6 +9,7 @@ import '../../core/data/models/drama.dart';
|
||||
import '../../core/data/models/home_feed.dart';
|
||||
import '../../core/data/remote/catalog_api.dart';
|
||||
import '../../core/data/services/category_controller.dart';
|
||||
import '../../core/formatting/content_locale_guard.dart';
|
||||
import '../../core/theme/app_colors.dart';
|
||||
import '../../core/widgets/app_pull_to_refresh.dart';
|
||||
import '../../core/widgets/empty_state.dart';
|
||||
@@ -284,7 +285,10 @@ class _ChannelFeedState extends State<_ChannelFeed>
|
||||
super.build(context);
|
||||
final categories = context.watch<CategoryController>();
|
||||
final slot = categories.slotOf(widget.categoryId);
|
||||
final dramas = slot.dramas;
|
||||
final dramas = visibleDramasForLocale(
|
||||
slot.dramas,
|
||||
Localizations.localeOf(context).languageCode,
|
||||
);
|
||||
final showCarousel = widget.isFeatured && widget.banners.isNotEmpty;
|
||||
final bottomInset = MediaQuery.of(context).padding.bottom;
|
||||
|
||||
|
||||
@@ -13,6 +13,7 @@ import '../../core/data/services/download_controller.dart';
|
||||
import '../../core/data/services/home_feed_controller.dart';
|
||||
import '../../core/data/services/playlist_controller.dart';
|
||||
import '../../core/data/services/wallet_controller.dart';
|
||||
import '../../core/formatting/content_locale_guard.dart';
|
||||
import '../../core/theme/app_colors.dart';
|
||||
import '../../core/widgets/empty_state.dart';
|
||||
import '../../l10n/app_localizations.dart';
|
||||
@@ -289,7 +290,10 @@ class _RecommendPageState extends State<RecommendPage>
|
||||
|
||||
Widget _recommendFeed(BuildContext context) {
|
||||
final feed = widget.feedController;
|
||||
final dramas = widget.feedController.dramas;
|
||||
final dramas = visibleDramasForLocale(
|
||||
widget.feedController.dramas,
|
||||
Localizations.localeOf(context).languageCode,
|
||||
);
|
||||
if (dramas.isNotEmpty) {
|
||||
return PlayerPage(
|
||||
key: const Key('recommend-feed-player'),
|
||||
@@ -327,6 +331,9 @@ class _RecommendPageState extends State<RecommendPage>
|
||||
key: const Key('recommend-feed-empty'),
|
||||
icon: Icons.wifi_off_rounded,
|
||||
title: l10n.networkError,
|
||||
actionLabel: l10n.retry,
|
||||
actionKey: const Key('recommend-feed-retry'),
|
||||
onAction: _retryRecommendData,
|
||||
),
|
||||
);
|
||||
}
|
||||
@@ -340,6 +347,11 @@ class _RecommendPageState extends State<RecommendPage>
|
||||
);
|
||||
}
|
||||
|
||||
void _retryRecommendData() {
|
||||
_cancelRecommendRetries();
|
||||
unawaited(_refreshRecommendData());
|
||||
}
|
||||
|
||||
PlaylistController? _watchPlaylists(BuildContext context) {
|
||||
try {
|
||||
return context.watch<PlaylistController>();
|
||||
|
||||
@@ -10,6 +10,7 @@ import '../../../core/data/models/drama.dart';
|
||||
import '../../../core/data/remote/catalog_api.dart';
|
||||
import '../../../core/data/services/all_dramas_controller.dart';
|
||||
import '../../../core/data/services/home_feed_controller.dart';
|
||||
import '../../../core/formatting/content_locale_guard.dart';
|
||||
import '../../../core/theme/app_colors.dart';
|
||||
import '../../../core/theme/app_dimens.dart';
|
||||
import '../../../core/widgets/app_pull_to_refresh.dart';
|
||||
@@ -49,7 +50,8 @@ class _AllDramasFilterGridState extends State<AllDramasFilterGrid> {
|
||||
@override
|
||||
void initState() {
|
||||
super.initState();
|
||||
_library = widget.controller ??
|
||||
_library =
|
||||
widget.controller ??
|
||||
AllDramasController(
|
||||
api: widget.catalogApi == null
|
||||
? null
|
||||
@@ -74,8 +76,9 @@ class _AllDramasFilterGridState extends State<AllDramasFilterGrid> {
|
||||
await widget.feedController?.loadMore();
|
||||
}
|
||||
|
||||
List<Drama> get _dramas =>
|
||||
_library.usesRemote ? _library.dramas : widget.feedController?.dramas ?? _library.dramas;
|
||||
List<Drama> get _dramas => _library.usesRemote
|
||||
? _library.dramas
|
||||
: widget.feedController?.dramas ?? _library.dramas;
|
||||
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
@@ -86,7 +89,9 @@ class _AllDramasFilterGridState extends State<AllDramasFilterGrid> {
|
||||
crossAxisAlignment: CrossAxisAlignment.stretch,
|
||||
children: [
|
||||
_filters(l10n),
|
||||
Expanded(child: _dramaList(l10n, _itemExtent(constraints.maxWidth))),
|
||||
Expanded(
|
||||
child: _dramaList(l10n, _itemExtent(constraints.maxWidth)),
|
||||
),
|
||||
],
|
||||
);
|
||||
},
|
||||
@@ -95,13 +100,18 @@ class _AllDramasFilterGridState extends State<AllDramasFilterGrid> {
|
||||
|
||||
double _itemExtent(double width) {
|
||||
final itemWidth =
|
||||
(width - AppDimens.allDramasHorizontal * 2 - AppDimens.allDramasGridGap * 2) /
|
||||
(width -
|
||||
AppDimens.allDramasHorizontal * 2 -
|
||||
AppDimens.allDramasGridGap * 2) /
|
||||
_gridColumns;
|
||||
return itemWidth / AppDimens.cardCoverAspectRatio + _cardBodyExtent;
|
||||
}
|
||||
|
||||
Widget _dramaList(AppLocalizations l10n, double itemExtent) {
|
||||
final dramas = _dramas;
|
||||
final dramas = visibleDramasForLocale(
|
||||
_dramas,
|
||||
Localizations.localeOf(context).languageCode,
|
||||
);
|
||||
return NotificationListener<ScrollNotification>(
|
||||
onNotification: _onScroll,
|
||||
child: AppPullToRefresh(
|
||||
@@ -140,7 +150,9 @@ class _AllDramasFilterGridState extends State<AllDramasFilterGrid> {
|
||||
|
||||
Widget _grid(List<Drama> dramas, double itemExtent) {
|
||||
return SliverPadding(
|
||||
padding: const EdgeInsets.symmetric(horizontal: AppDimens.allDramasHorizontal),
|
||||
padding: const EdgeInsets.symmetric(
|
||||
horizontal: AppDimens.allDramasHorizontal,
|
||||
),
|
||||
sliver: SliverGrid(
|
||||
key: const Key('all-dramas-grid'),
|
||||
gridDelegate: SliverGridDelegateWithFixedCrossAxisCount(
|
||||
@@ -229,7 +241,11 @@ class _AllDramasFilterGridState extends State<AllDramasFilterGrid> {
|
||||
);
|
||||
}
|
||||
|
||||
Widget _optionRow(_FilterRow spec, String languageCode, AppLocalizations l10n) {
|
||||
Widget _optionRow(
|
||||
_FilterRow spec,
|
||||
String languageCode,
|
||||
AppLocalizations l10n,
|
||||
) {
|
||||
return _filterRow(
|
||||
row: spec.row,
|
||||
child: _horizontalChipScroll(
|
||||
@@ -302,7 +318,9 @@ class _AllDramasFilterGridState extends State<AllDramasFilterGrid> {
|
||||
),
|
||||
alignment: Alignment.center,
|
||||
decoration: BoxDecoration(
|
||||
color: selected ? AppColors.filterChipSelected : AppColors.transparent,
|
||||
color: selected
|
||||
? AppColors.filterChipSelected
|
||||
: AppColors.transparent,
|
||||
borderRadius: BorderRadius.circular(AppDimens.filterChipRadius),
|
||||
),
|
||||
child: Text(
|
||||
@@ -323,7 +341,8 @@ class _AllDramasFilterGridState extends State<AllDramasFilterGrid> {
|
||||
bool _onScroll(ScrollNotification notification) {
|
||||
if (notification.depth != 0) return false;
|
||||
if (notification.metrics.pixels <= 0) return false;
|
||||
final reachedBottom = notification.metrics.extentAfter <= _loadMoreThreshold;
|
||||
final reachedBottom =
|
||||
notification.metrics.extentAfter <= _loadMoreThreshold;
|
||||
if (reachedBottom &&
|
||||
(notification is ScrollUpdateNotification ||
|
||||
notification is ScrollEndNotification ||
|
||||
|
||||
@@ -4,6 +4,7 @@ import 'package:flutter/material.dart';
|
||||
|
||||
import '../../../core/data/models/drama.dart';
|
||||
import '../../../core/data/models/playlist_detail.dart';
|
||||
import '../../../core/formatting/content_locale_guard.dart';
|
||||
import '../../../core/theme/app_colors.dart';
|
||||
import '../../../core/theme/app_dimens.dart';
|
||||
import '../../../core/widgets/app_pull_to_refresh.dart';
|
||||
@@ -54,8 +55,7 @@ class _PlaylistDetailPageState extends State<PlaylistDetailPage> {
|
||||
bool _loadingMore = false;
|
||||
bool _failed = false;
|
||||
|
||||
bool get _hasMore =>
|
||||
widget.loadPage != null && _dramas.length < _dramaCount;
|
||||
bool get _hasMore => widget.loadPage != null && _dramas.length < _dramaCount;
|
||||
|
||||
Future<void> _refresh() async {
|
||||
final loadPage = widget.loadPage;
|
||||
@@ -112,7 +112,8 @@ class _PlaylistDetailPageState extends State<PlaylistDetailPage> {
|
||||
Widget build(BuildContext context) {
|
||||
final width = MediaQuery.sizeOf(context).width;
|
||||
final itemWidth = (width - _pageHorizontal * 2 - _gridGap) / 2;
|
||||
final itemExtent = itemWidth / AppDimens.cardCoverAspectRatio + _cardBodyExtent;
|
||||
final itemExtent =
|
||||
itemWidth / AppDimens.cardCoverAspectRatio + _cardBodyExtent;
|
||||
return Scaffold(
|
||||
key: const Key('playlist-detail-page'),
|
||||
backgroundColor: AppColors.ink,
|
||||
@@ -157,6 +158,10 @@ class _PlaylistDetailPageState extends State<PlaylistDetailPage> {
|
||||
}
|
||||
|
||||
Widget _body(double itemExtent) {
|
||||
final visibleDramas = visibleDramasForLocale(
|
||||
_dramas,
|
||||
Localizations.localeOf(context).languageCode,
|
||||
);
|
||||
return CustomScrollView(
|
||||
key: const Key('playlist-detail-scroll'),
|
||||
physics: AppPullToRefresh.physics,
|
||||
@@ -168,7 +173,9 @@ class _PlaylistDetailPageState extends State<PlaylistDetailPage> {
|
||||
_pageHorizontal,
|
||||
12,
|
||||
),
|
||||
sliver: SliverToBoxAdapter(child: _PlaylistCollage(dramas: _dramas)),
|
||||
sliver: SliverToBoxAdapter(
|
||||
child: _PlaylistCollage(dramas: visibleDramas),
|
||||
),
|
||||
),
|
||||
SliverPadding(
|
||||
padding: const EdgeInsets.symmetric(horizontal: _pageHorizontal),
|
||||
@@ -192,10 +199,11 @@ class _PlaylistDetailPageState extends State<PlaylistDetailPage> {
|
||||
),
|
||||
delegate: SliverChildBuilderDelegate(
|
||||
(context, index) => HomeFeedCard(
|
||||
drama: _dramas[index],
|
||||
onTap: () => playDramaFromCatalog(context, _dramas[index]),
|
||||
drama: visibleDramas[index],
|
||||
onTap: () =>
|
||||
playDramaFromCatalog(context, visibleDramas[index]),
|
||||
),
|
||||
childCount: _dramas.length,
|
||||
childCount: visibleDramas.length,
|
||||
),
|
||||
),
|
||||
),
|
||||
@@ -205,9 +213,13 @@ class _PlaylistDetailPageState extends State<PlaylistDetailPage> {
|
||||
child: PagedListFooter(
|
||||
loading: _loadingMore,
|
||||
hasMore: _hasMore,
|
||||
hasItems: _dramas.isNotEmpty,
|
||||
errorMessage: _failed ? AppLocalizations.of(context)!.catalogError : null,
|
||||
onRetry: _loadingMore ? _loadMore : (_hasMore ? _loadMore : _refresh),
|
||||
hasItems: visibleDramas.isNotEmpty,
|
||||
errorMessage: _failed
|
||||
? AppLocalizations.of(context)!.catalogError
|
||||
: null,
|
||||
onRetry: _loadingMore
|
||||
? _loadMore
|
||||
: (_hasMore ? _loadMore : _refresh),
|
||||
),
|
||||
),
|
||||
),
|
||||
|
||||
@@ -8,6 +8,7 @@ import '../../../core/data/models/playlist_detail.dart';
|
||||
import '../../../core/data/services/category_controller.dart';
|
||||
import '../../../core/data/services/home_feed_controller.dart';
|
||||
import '../../../core/data/services/playlist_controller.dart';
|
||||
import '../../../core/formatting/content_locale_guard.dart';
|
||||
import '../../../core/theme/app_colors.dart';
|
||||
import '../../../core/theme/app_dimens.dart';
|
||||
import '../../../core/widgets/app_pull_to_refresh.dart';
|
||||
@@ -43,7 +44,8 @@ class RecommendSectionsView extends StatelessWidget {
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
final l10n = AppLocalizations.of(context)!;
|
||||
final source = feedController.dramas;
|
||||
final languageCode = Localizations.localeOf(context).languageCode;
|
||||
final source = visibleDramasForLocale(feedController.dramas, languageCode);
|
||||
final remote = playlists;
|
||||
return AppPullToRefresh(
|
||||
key: const Key('recommend-sections-refresh'),
|
||||
@@ -83,39 +85,39 @@ class RecommendSectionsView extends StatelessWidget {
|
||||
source: source,
|
||||
);
|
||||
return [
|
||||
_section(
|
||||
context,
|
||||
l10n,
|
||||
key: 'hits',
|
||||
title: l10n.weeklyHitsTitle,
|
||||
subtitle: l10n.weeklyHitsSubtitle,
|
||||
dramas: hits.take(_sectionPreviewCount).toList(),
|
||||
onMore: () => onMore(RecommendSectionKind.hits),
|
||||
),
|
||||
const SizedBox(height: AppDimens.recommendSectionGap),
|
||||
_section(
|
||||
context,
|
||||
l10n,
|
||||
key: 'new',
|
||||
title: l10n.weeklyNewTitle,
|
||||
subtitle: l10n.weeklyNewSubtitle,
|
||||
dramas: newest.take(_sectionPreviewCount).toList(),
|
||||
onMore: () => onMore(RecommendSectionKind.newReleases),
|
||||
),
|
||||
const SizedBox(height: AppDimens.recommendSectionGap),
|
||||
_section(
|
||||
context,
|
||||
l10n,
|
||||
key: 'costume',
|
||||
title: l10n.costumeAwardsTitle,
|
||||
subtitle: l10n.costumeAwardsSubtitle,
|
||||
dramas: recommendSectionDramas(
|
||||
kind: RecommendSectionKind.costume,
|
||||
source: source,
|
||||
categories: categories,
|
||||
).take(_sectionPreviewCount).toList(),
|
||||
onMore: () => onMore(RecommendSectionKind.costume),
|
||||
),
|
||||
_section(
|
||||
context,
|
||||
l10n,
|
||||
key: 'hits',
|
||||
title: l10n.weeklyHitsTitle,
|
||||
subtitle: l10n.weeklyHitsSubtitle,
|
||||
dramas: hits.take(_sectionPreviewCount).toList(),
|
||||
onMore: () => onMore(RecommendSectionKind.hits),
|
||||
),
|
||||
const SizedBox(height: AppDimens.recommendSectionGap),
|
||||
_section(
|
||||
context,
|
||||
l10n,
|
||||
key: 'new',
|
||||
title: l10n.weeklyNewTitle,
|
||||
subtitle: l10n.weeklyNewSubtitle,
|
||||
dramas: newest.take(_sectionPreviewCount).toList(),
|
||||
onMore: () => onMore(RecommendSectionKind.newReleases),
|
||||
),
|
||||
const SizedBox(height: AppDimens.recommendSectionGap),
|
||||
_section(
|
||||
context,
|
||||
l10n,
|
||||
key: 'costume',
|
||||
title: l10n.costumeAwardsTitle,
|
||||
subtitle: l10n.costumeAwardsSubtitle,
|
||||
dramas: recommendSectionDramas(
|
||||
kind: RecommendSectionKind.costume,
|
||||
source: source,
|
||||
categories: categories,
|
||||
).take(_sectionPreviewCount).toList(),
|
||||
onMore: () => onMore(RecommendSectionKind.costume),
|
||||
),
|
||||
];
|
||||
}
|
||||
|
||||
@@ -163,7 +165,10 @@ class RecommendSectionsView extends StatelessWidget {
|
||||
subtitle: playlist.localizedDescription(
|
||||
Localizations.localeOf(context).languageCode,
|
||||
),
|
||||
dramas: playlist.dramas.take(_sectionPreviewCount).toList(),
|
||||
dramas: visibleDramasForLocale(
|
||||
playlist.dramas,
|
||||
Localizations.localeOf(context).languageCode,
|
||||
).take(_sectionPreviewCount).toList(),
|
||||
onMore: () => onOpenPlaylist?.call(playlist),
|
||||
),
|
||||
);
|
||||
@@ -320,9 +325,15 @@ List<Drama> recommendSectionDramas({
|
||||
int _newestFirst(Drama leftDrama, Drama rightDrama) {
|
||||
final left = publishedAtForDrama(leftDrama);
|
||||
final right = publishedAtForDrama(rightDrama);
|
||||
if (left == null && right == null) return rightDrama.id.compareTo(leftDrama.id);
|
||||
if (left == null) return 1;
|
||||
if (right == null) return -1;
|
||||
if (left == null && right == null) {
|
||||
return rightDrama.id.compareTo(leftDrama.id);
|
||||
}
|
||||
if (left == null) {
|
||||
return 1;
|
||||
}
|
||||
if (right == null) {
|
||||
return -1;
|
||||
}
|
||||
return right.compareTo(left);
|
||||
}
|
||||
|
||||
|
||||
Reference in new issue
Block a user