feat(app): 剧场页九宫格与极简我的页
This commit is contained in:
1 parent
dc8ca7b743
commit
35338cbfc8
46 files changed
+2353
-4358
No files matched your search
@@ -0,0 +1,12 @@
|
||||
// Author: fruit.com.cn
|
||||
|
||||
import 'package:flutter/widgets.dart';
|
||||
|
||||
/// 将系统语言解析为受支持的语言;不支持时回退印尼语。
|
||||
Locale resolveAppLocale(Locale? deviceLocale) {
|
||||
return switch (deviceLocale?.languageCode) {
|
||||
'zh' => const Locale('zh'),
|
||||
'en' => const Locale('en'),
|
||||
_ => const Locale('id'),
|
||||
};
|
||||
}
|
||||
@@ -1,56 +0,0 @@
|
||||
// Author: fruit.com.cn
|
||||
|
||||
import 'package:flutter/widgets.dart';
|
||||
import 'package:shared_preferences/shared_preferences.dart';
|
||||
|
||||
/// Resolves the selected or system language to one of the supported app locales.
|
||||
///
|
||||
/// Indonesian is the launch-market fallback when a device uses an unsupported
|
||||
/// language. The legacy `in` code is treated as Indonesian as well.
|
||||
Locale resolveAppLocale(Locale? selected, Locale? deviceLocale) {
|
||||
final code = (selected ?? deviceLocale)?.languageCode;
|
||||
return switch (code) {
|
||||
'zh' => const Locale('zh'),
|
||||
'en' => const Locale('en'),
|
||||
_ => const Locale('id'),
|
||||
};
|
||||
}
|
||||
|
||||
class LocaleController extends ChangeNotifier {
|
||||
LocaleController({SharedPreferencesAsync? preferences})
|
||||
: _preferences = preferences ?? SharedPreferencesAsync();
|
||||
|
||||
final SharedPreferencesAsync _preferences;
|
||||
Locale? _locale;
|
||||
Locale? get locale => _locale;
|
||||
|
||||
Future<void> load() async {
|
||||
try {
|
||||
final code = await _preferences.getString('ui.locale');
|
||||
_locale = switch (code) {
|
||||
'en' => const Locale('en'),
|
||||
'zh' => const Locale('zh'),
|
||||
'id' => const Locale('id'),
|
||||
_ => null,
|
||||
};
|
||||
notifyListeners();
|
||||
} catch (_) {
|
||||
// The system locale remains usable if preferences are unavailable.
|
||||
}
|
||||
}
|
||||
|
||||
Future<void> select(String code) async {
|
||||
_locale = switch (code) {
|
||||
'en' => const Locale('en'),
|
||||
'zh' => const Locale('zh'),
|
||||
'id' => const Locale('id'),
|
||||
_ => null,
|
||||
};
|
||||
notifyListeners();
|
||||
try {
|
||||
await _preferences.setString('ui.locale', code);
|
||||
} catch (_) {
|
||||
// Preference persistence is best effort for this prototype.
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -7,38 +7,25 @@ import '../models/drama.dart';
|
||||
import '../models/home_feed.dart';
|
||||
import '../repositories/category_repository.dart';
|
||||
|
||||
/// 发现页分类状态:服务端分类清单、发现 feed 与当前筛选。
|
||||
/// 剧场页数据:服务端分类清单与发现 feed。
|
||||
class CategoryController extends ChangeNotifier {
|
||||
CategoryController(this._repository);
|
||||
|
||||
static const String allCode = 'all';
|
||||
static const String hotCode = 'hot';
|
||||
static const String newCode = 'new';
|
||||
|
||||
final CategoryRepository _repository;
|
||||
|
||||
List<ContentCategory> categories = const [];
|
||||
HomeFeed feed = const HomeFeed();
|
||||
String selectedCode = allCode;
|
||||
bool loading = false;
|
||||
String? error;
|
||||
bool _disposed = false;
|
||||
|
||||
/// 当前筛选对应的分区 code;全部分类为空字符串语义。
|
||||
bool get selectedSectionMissing =>
|
||||
selectedCode != allCode && _selectedSection == null;
|
||||
|
||||
/// 当前筛选应展示的剧集;全部分类按 feed 顺序去重。
|
||||
List<Drama> get visibleDramas {
|
||||
if (selectedCode == allCode) return feed.dramas;
|
||||
return _selectedSection?.dramas ?? const [];
|
||||
}
|
||||
|
||||
FeedSection? get _selectedSection {
|
||||
/// 分类九宫格点击后读取该分类的剧目;缺失分区返回空列表。
|
||||
List<Drama> dramasOf(String categoryId) {
|
||||
final code = 'category-$categoryId';
|
||||
for (final section in feed.sections) {
|
||||
if (section.code == selectedCode) return section;
|
||||
if (section.code == code) return section.dramas;
|
||||
}
|
||||
return null;
|
||||
return const [];
|
||||
}
|
||||
|
||||
/// 加载分类与发现 feed;失败保留可重试错误态。
|
||||
@@ -61,15 +48,6 @@ class CategoryController extends ChangeNotifier {
|
||||
}
|
||||
}
|
||||
|
||||
/// 选择服务端分类,内容只匹配 `category-{id}`。
|
||||
void selectCategory(String id) => selectCode('category-$id');
|
||||
|
||||
/// 选择内置或分区 code。
|
||||
void selectCode(String code) {
|
||||
selectedCode = code;
|
||||
_notify();
|
||||
}
|
||||
|
||||
void _notify() {
|
||||
if (!_disposed) notifyListeners();
|
||||
}
|
||||
|
||||
Reference in new issue
Block a user