feat(app): 剧场列表增加语种筛选
This commit is contained in:
1 parent
ade0cc3566
commit
30a5fa0776
5 files changed
+220
-4
No files matched your search
@@ -36,6 +36,7 @@ class DiscoverLogic extends ChangeNotifier {
|
||||
Duration searchDebounce = const Duration(milliseconds: 350);
|
||||
static const int searchPageSize = 20;
|
||||
List<Drama> searchResults = const [];
|
||||
String? selectedLanguage;
|
||||
int searchTotal = 0;
|
||||
bool searchLoading = false;
|
||||
String? searchError;
|
||||
@@ -87,8 +88,32 @@ class DiscoverLogic extends ChangeNotifier {
|
||||
|
||||
/// 搜索态展示后端结果,非搜索态展示剧场自身的可见短剧。
|
||||
List<Drama> visibleDramas(List<Drama> fallback) {
|
||||
if (!hasSearchQuery) return fallback;
|
||||
return searchResults;
|
||||
if (!hasSearchQuery) return _filterByLanguage(fallback);
|
||||
return _filterByLanguage(searchResults);
|
||||
}
|
||||
|
||||
/// 当前 feed 中出现过的语种,按首次出现顺序去重。
|
||||
List<String> languagesOf(List<Drama> dramas) {
|
||||
final languages = <String>[];
|
||||
for (final drama in dramas) {
|
||||
final language = drama.language;
|
||||
if (language.isNotEmpty && !languages.contains(language)) {
|
||||
languages.add(language);
|
||||
}
|
||||
}
|
||||
return languages;
|
||||
}
|
||||
|
||||
/// 按语种筛选;null 表示全部。
|
||||
void selectLanguage(String? code) {
|
||||
selectedLanguage = code;
|
||||
notify();
|
||||
}
|
||||
|
||||
List<Drama> _filterByLanguage(List<Drama> dramas) {
|
||||
final code = selectedLanguage;
|
||||
if (code == null) return dramas;
|
||||
return dramas.where((drama) => drama.language == code).toList();
|
||||
}
|
||||
|
||||
Future<void> retrySearch() async {
|
||||
|
||||
@@ -176,7 +176,12 @@ class _DiscoverPageState extends State<DiscoverPage> {
|
||||
child: _categories(l10n, categories),
|
||||
),
|
||||
),
|
||||
if (logic.resumeRecord != null && logic.resumeDrama(allDramas) != null)
|
||||
SliverToBoxAdapter(
|
||||
child: Padding(
|
||||
padding: const EdgeInsets.fromLTRB(0, 0, 0, 12),
|
||||
child: _languages(l10n, allDramas),
|
||||
),
|
||||
), if (logic.resumeRecord != null && logic.resumeDrama(allDramas) != null)
|
||||
SliverToBoxAdapter(
|
||||
child: Padding(
|
||||
padding: const EdgeInsets.fromLTRB(16, 0, 16, 14),
|
||||
@@ -427,6 +432,69 @@ class _DiscoverPageState extends State<DiscoverPage> {
|
||||
);
|
||||
}
|
||||
|
||||
Widget _languages(AppLocalizations l10n, List<Drama> dramas) {
|
||||
final languages = logic.languagesOf(dramas);
|
||||
if (languages.isEmpty) return const SizedBox.shrink();
|
||||
final selected = logic.selectedLanguage;
|
||||
return SizedBox(
|
||||
key: const Key('discover-language-chips'),
|
||||
height: AppDimens.tapTarget,
|
||||
child: ListView(
|
||||
padding: const EdgeInsets.symmetric(horizontal: 14),
|
||||
scrollDirection: Axis.horizontal,
|
||||
children: [
|
||||
_languageChip(
|
||||
key: const Key('discover-language-all'),
|
||||
label: l10n.all,
|
||||
selected: selected == null,
|
||||
onTap: () => logic.selectLanguage(null),
|
||||
),
|
||||
for (final language in languages)
|
||||
_languageChip(
|
||||
key: Key('discover-language-$language'),
|
||||
label: _languageLabel(l10n, language),
|
||||
selected: selected == language,
|
||||
onTap: () => logic.selectLanguage(language),
|
||||
),
|
||||
],
|
||||
),
|
||||
);
|
||||
}
|
||||
|
||||
Widget _languageChip({
|
||||
required Key key,
|
||||
required String label,
|
||||
required bool selected,
|
||||
required VoidCallback onTap,
|
||||
}) {
|
||||
return Padding(
|
||||
padding: const EdgeInsets.only(right: 8),
|
||||
child: Center(
|
||||
child: ChoiceChip(
|
||||
key: key,
|
||||
label: Text(label),
|
||||
selected: selected,
|
||||
showCheckmark: false,
|
||||
onSelected: (_) => onTap(),
|
||||
selectedColor: AppColors.blue,
|
||||
backgroundColor: const Color(0xFF29272B),
|
||||
side: BorderSide.none,
|
||||
labelStyle: TextStyle(
|
||||
color: selected ? AppColors.onPrimary : AppColors.muted,
|
||||
fontSize: AppDimens.chipFont,
|
||||
fontWeight: selected ? FontWeight.w700 : FontWeight.w500,
|
||||
),
|
||||
),
|
||||
),
|
||||
);
|
||||
}
|
||||
|
||||
String _languageLabel(AppLocalizations l10n, String code) {
|
||||
if (code == 'zh-CN' || code == 'zh') return l10n.languageChinese;
|
||||
if (code == 'id') return l10n.languageIndonesian;
|
||||
if (code == 'en') return l10n.languageEnglish;
|
||||
return code;
|
||||
}
|
||||
Widget _continueCard(
|
||||
AppLocalizations l10n,
|
||||
Drama drama,
|
||||
|
||||
Reference in new issue
Block a user