refactor: 替换硬编码的AppTypography为基于context的动态获取

1. 批量修改所有直接调用AppTypography静态方法的地方,改为使用AppTypography.of(context)获取主题文本样式,适配不同主题上下文
2. 新增channelOrder存储键,支持频道排序持久化
3. 修复笔记删除全部功能未重置total字段的bug
4. 调整build.yaml配置,扩展freezed和json_serializable的生成范围
5. 优化底部弹窗默认样式,使用主题色替代硬编码颜色
6. 调整主题设置中的卡片样式默认文案
This commit is contained in:
Developer
2026-05-24 09:26:55 +08:00
parent 794da27193
commit 09d68cd6aa
265 changed files with 5197 additions and 3981 deletions

View File

@@ -1,9 +1,9 @@
/// ============================================================
/// 闲言APP — 首页Feed数据拉取Mixin
/// 创建时间: 2026-05-12
/// 更新时间: 2026-05-20
/// 更新时间: 2026-05-24
/// 作用: 频道/每日推荐/列表/降级/缓存的拉取逻辑
/// 上次更新: fetchDailySentence成功后同步推送拾光角色小组件数据
/// 上次更新: 新增_applyChannelOrder方法加载频道时应用用户自定义排序
/// ============================================================
import 'dart:convert';
@@ -156,9 +156,10 @@ mixin HomeFeedMixin on Notifier<HomeState> {
if (channels.isNotEmpty) {
allChannels = channels;
final disabledKeys = loadDisabledKeys();
final filtered = disabledKeys.isNotEmpty
var filtered = disabledKeys.isNotEmpty
? channels.where((c) => !disabledKeys.contains(c.key)).toList()
: channels;
filtered = _applyChannelOrder(filtered);
state = state.copyWith(channels: filtered);
saveChannelsCache(channels);
}
@@ -181,9 +182,10 @@ mixin HomeFeedMixin on Notifier<HomeState> {
}
}
final keys = disabledKeys ?? loadDisabledKeys();
final filtered = keys.isNotEmpty
var filtered = keys.isNotEmpty
? source.where((c) => !keys.contains(c.key)).toList()
: source;
filtered = _applyChannelOrder(filtered);
Log.i(
'refreshChannels: 源频道${source.length}个, '
@@ -241,9 +243,10 @@ mixin HomeFeedMixin on Notifier<HomeState> {
if (cached.isNotEmpty && state.channels.isEmpty) {
allChannels = cached;
final disabledKeys = loadDisabledKeys();
final filtered = disabledKeys.isNotEmpty
var filtered = disabledKeys.isNotEmpty
? cached.where((c) => !disabledKeys.contains(c.key)).toList()
: cached;
filtered = _applyChannelOrder(filtered);
state = state.copyWith(channels: filtered);
}
} catch (e) {
@@ -266,6 +269,28 @@ mixin HomeFeedMixin on Notifier<HomeState> {
return {};
}
// ── 应用用户自定义频道排序 ──
List<FeedChannel> _applyChannelOrder(List<FeedChannel> channels) {
try {
final savedOrder = KvStorage.getStringList(StorageKeys.channelOrder);
if (savedOrder == null || savedOrder.isEmpty) return channels;
final orderMap = <String, int>{
for (var i = 0; i < savedOrder.length; i++) savedOrder[i]: i,
};
final sorted = List<FeedChannel>.from(channels);
sorted.sort((a, b) {
final aIdx = orderMap[a.key] ?? 999;
final bIdx = orderMap[b.key] ?? 999;
return aIdx.compareTo(bIdx);
});
return sorted;
} catch (e) {
Log.e('频道排序应用失败', e);
return channels;
}
}
Future<void> saveChannelsCache(List<FeedChannel> channels) async {
try {
final encoded = jsonEncode(channels.map((c) => c.toJson()).toList());

View File

@@ -2,26 +2,15 @@
// 闲言APP — 工具中心最近使用 Provider
// 创建时间: 2026-05-24
// 更新时间: 2026-05-24
// 作用: 管理工具中心最近使用路由列表和自定义路由,持久化到 KvStorage
// 上次更新: 初始创建 — 最近3条路由 + 1条自定义路由
// 作用: 管理工具中心最近使用路由列表和自定义路由,通过RecentRouteService单一数据源
// 上次更新: 使用RecentRouteService替代直接KvStorage操作消除双写问题
// ============================================================
import 'dart:convert';
import 'package:flutter_riverpod/flutter_riverpod.dart';
import '../../../core/storage/kv_storage.dart';
import '../../../core/utils/logger.dart';
const _kRecentRoutes = 'tool_center_recent_routes';
const _kCustomRoute = 'tool_center_custom_route';
const _maxRecentCount = 3;
import '../../../core/services/navigation/recent_route_service.dart';
class ToolCenterRecentState {
const ToolCenterRecentState({
this.recentRoutes = const [],
this.customRoute,
});
const ToolCenterRecentState({this.recentRoutes = const [], this.customRoute});
final List<String> recentRoutes;
final String? customRoute;
@@ -40,60 +29,32 @@ class ToolCenterRecentState {
class ToolCenterRecentNotifier extends Notifier<ToolCenterRecentState> {
@override
ToolCenterRecentState build() {
return _loadFromStorage();
return _loadFromService();
}
ToolCenterRecentState _loadFromStorage() {
List<String> recentRoutes = [];
try {
final raw = KvStorage.getString(_kRecentRoutes);
if (raw != null && raw.isNotEmpty) {
final decoded = jsonDecode(raw) as List<dynamic>;
recentRoutes = decoded.map((e) => e.toString()).toList();
}
} catch (e) {
Log.w('工具中心: 读取最近路由失败 $e');
}
String? customRoute;
try {
customRoute = KvStorage.getString(_kCustomRoute);
} catch (e) {
Log.w('工具中心: 读取自定义路由失败 $e');
}
ToolCenterRecentState _loadFromService() {
return ToolCenterRecentState(
recentRoutes: recentRoutes,
customRoute: customRoute,
recentRoutes: RecentRouteService.getRecentRoutes(),
customRoute: RecentRouteService.getCustomRoute(),
);
}
void refreshFromService() {
state = _loadFromService();
}
Future<void> addRecentRoute(String route) async {
final updated = List<String>.from(state.recentRoutes)
..remove(route)
..insert(0, route);
if (updated.length > _maxRecentCount) {
updated.removeRange(_maxRecentCount, updated.length);
}
state = state.copyWith(recentRoutes: updated);
try {
await KvStorage.setString(_kRecentRoutes, jsonEncode(updated));
} catch (e) {
Log.e('工具中心: 保存最近路由失败 $e');
}
await RecentRouteService.addRecentRoute(route);
refreshFromService();
}
Future<void> setCustomRoute(String route) async {
state = state.copyWith(customRoute: route);
try {
await KvStorage.setString(_kCustomRoute, route);
} catch (e) {
Log.e('工具中心: 保存自定义路由失败 $e');
}
await RecentRouteService.setCustomRoute(route);
refreshFromService();
}
}
final toolCenterRecentProvider =
NotifierProvider<ToolCenterRecentNotifier, ToolCenterRecentState>(
ToolCenterRecentNotifier.new,
);
ToolCenterRecentNotifier.new,
);