chore: 完成v5.10.0版本迭代更新
此版本包含多项功能优化与修复: 1. 新增鸿蒙分层图标生成脚本,完善鸿蒙应用图标适配 2. 重构多处FutureProvider为NotifierProvider,修复ElementWithFuture异常 3. 更新flutter_tts依赖为鸿蒙适配版本,调整pubspec配置 4. 优化运势卡片样式文案,更新引导页功能介绍详情 5. 修复在线TTS服务Path正则匹配问题,支持含点号的路径 6. 重构通知权限、崩溃监控等状态管理逻辑 7. 更新翻译覆盖率统计,支持手动标注真实翻译进度 8. 优化编辑器工具栏、会话流页面交互细节 9. 新增日志筛选、导出CSV等增强功能 10. 调整设置页面文案,优化用户操作体验
This commit is contained in:
@@ -1,9 +1,9 @@
|
||||
/// ============================================================
|
||||
/// 闲言APP — 统一存储抽象层
|
||||
/// 创建时间: 2026-05-25
|
||||
/// 更新时间: 2026-05-25
|
||||
/// 更新时间: 2026-05-26
|
||||
/// 作用: 统一KvStorage/SecureStorage的存储访问入口,按功能域分组
|
||||
/// 上次更新: 初始创建
|
||||
/// 上次更新: LockStorage增加生物识别启用存储
|
||||
/// ============================================================
|
||||
|
||||
import 'kv_storage.dart';
|
||||
@@ -61,6 +61,7 @@ class LockStorage {
|
||||
|
||||
static const _keyEnabled = 'general_app_lock';
|
||||
static const _keyMethod = 'app_lock_method';
|
||||
static const _keyBiometricEnabled = 'app_lock_biometric_enabled';
|
||||
static const _keyPattern = 'app_lock_pattern';
|
||||
static const _keyPin = 'app_lock_pin';
|
||||
static const _keyHintCode = 'app_lock_hint_code';
|
||||
@@ -77,6 +78,12 @@ class LockStorage {
|
||||
|
||||
void writeMethodId(String id) => KvStorage.setString(_keyMethod, id);
|
||||
|
||||
bool readBiometricEnabled() =>
|
||||
KvStorage.getBool(_keyBiometricEnabled) ?? false;
|
||||
|
||||
void writeBiometricEnabled(bool v) =>
|
||||
KvStorage.setBool(_keyBiometricEnabled, v);
|
||||
|
||||
int readFailedAttempts() =>
|
||||
KvStorage.getInt(_keyFailedAttempts) ?? 0;
|
||||
|
||||
@@ -121,6 +128,7 @@ class LockStorage {
|
||||
await SecureStorage.delete(_keyPattern);
|
||||
await SecureStorage.delete(_keyPin);
|
||||
writeMethodId('none');
|
||||
writeBiometricEnabled(false);
|
||||
writeEnabled(false);
|
||||
}
|
||||
|
||||
|
||||
@@ -1,11 +1,32 @@
|
||||
/// ============================================================
|
||||
/// 闲言APP — 缓存配置模型
|
||||
/// 创建时间: 2026-04-28
|
||||
/// 更新时间: 2026-05-23
|
||||
/// 更新时间: 2026-05-26
|
||||
/// 作用: 定义缓存策略配置,支持离线模式、预加载、缓存上限等
|
||||
/// 上次更新: preloadChannels改用后端英文key(all/poetry/wisdom)
|
||||
/// 上次更新: 新增智能预加载策略字段(preloadMode/preloadContentTypes/preloadFrequency/batteryThreshold)
|
||||
/// ============================================================
|
||||
|
||||
/// 预加载模式
|
||||
enum PreloadMode {
|
||||
smart,
|
||||
wifiOnly,
|
||||
disabled,
|
||||
}
|
||||
|
||||
/// 预加载内容类型
|
||||
enum PreloadContentType {
|
||||
text,
|
||||
image,
|
||||
audio,
|
||||
}
|
||||
|
||||
/// 预加载频率
|
||||
enum PreloadFrequency {
|
||||
realtime,
|
||||
hourly,
|
||||
daily,
|
||||
}
|
||||
|
||||
class CacheConfig {
|
||||
final bool offlineModeEnabled;
|
||||
final bool preloadOnWifi;
|
||||
@@ -16,6 +37,18 @@ class CacheConfig {
|
||||
final int maxRetryCount;
|
||||
final Set<String> preloadChannels;
|
||||
|
||||
/// 预加载模式: smart(智能)/wifiOnly(仅WiFi)/disabled(关闭)
|
||||
final PreloadMode preloadMode;
|
||||
|
||||
/// 预加载内容类型集合
|
||||
final Set<PreloadContentType> preloadContentTypes;
|
||||
|
||||
/// 预加载频率: realtime(实时)/hourly(每小时)/daily(每天)
|
||||
final PreloadFrequency preloadFrequency;
|
||||
|
||||
/// 低电量阈值百分比,低于此值暂停预加载
|
||||
final int batteryThreshold;
|
||||
|
||||
const CacheConfig({
|
||||
this.offlineModeEnabled = true,
|
||||
this.preloadOnWifi = true,
|
||||
@@ -25,6 +58,13 @@ class CacheConfig {
|
||||
this.maxOfflineActions = 100,
|
||||
this.maxRetryCount = 3,
|
||||
this.preloadChannels = const {'all', 'poetry', 'wisdom'},
|
||||
this.preloadMode = PreloadMode.smart,
|
||||
this.preloadContentTypes = const {
|
||||
PreloadContentType.text,
|
||||
PreloadContentType.image,
|
||||
},
|
||||
this.preloadFrequency = PreloadFrequency.hourly,
|
||||
this.batteryThreshold = 20,
|
||||
});
|
||||
|
||||
CacheConfig copyWith({
|
||||
@@ -36,6 +76,10 @@ class CacheConfig {
|
||||
int? maxOfflineActions,
|
||||
int? maxRetryCount,
|
||||
Set<String>? preloadChannels,
|
||||
PreloadMode? preloadMode,
|
||||
Set<PreloadContentType>? preloadContentTypes,
|
||||
PreloadFrequency? preloadFrequency,
|
||||
int? batteryThreshold,
|
||||
}) {
|
||||
return CacheConfig(
|
||||
offlineModeEnabled: offlineModeEnabled ?? this.offlineModeEnabled,
|
||||
@@ -46,6 +90,10 @@ class CacheConfig {
|
||||
maxOfflineActions: maxOfflineActions ?? this.maxOfflineActions,
|
||||
maxRetryCount: maxRetryCount ?? this.maxRetryCount,
|
||||
preloadChannels: preloadChannels ?? this.preloadChannels,
|
||||
preloadMode: preloadMode ?? this.preloadMode,
|
||||
preloadContentTypes: preloadContentTypes ?? this.preloadContentTypes,
|
||||
preloadFrequency: preloadFrequency ?? this.preloadFrequency,
|
||||
batteryThreshold: batteryThreshold ?? this.batteryThreshold,
|
||||
);
|
||||
}
|
||||
|
||||
@@ -58,6 +106,11 @@ class CacheConfig {
|
||||
'maxOfflineActions': maxOfflineActions,
|
||||
'maxRetryCount': maxRetryCount,
|
||||
'preloadChannels': preloadChannels.toList(),
|
||||
'preloadMode': preloadMode.name,
|
||||
'preloadContentTypes':
|
||||
preloadContentTypes.map((e) => e.name).toList(),
|
||||
'preloadFrequency': preloadFrequency.name,
|
||||
'batteryThreshold': batteryThreshold,
|
||||
};
|
||||
|
||||
factory CacheConfig.fromJson(Map<String, dynamic> json) => CacheConfig(
|
||||
@@ -72,5 +125,50 @@ class CacheConfig {
|
||||
?.map((e) => e.toString())
|
||||
.toSet() ??
|
||||
const {'all', 'poetry', 'wisdom'},
|
||||
preloadMode: _parsePreloadMode(json['preloadMode'] as String?),
|
||||
preloadContentTypes: _parseContentTypes(
|
||||
json['preloadContentTypes'] as List<dynamic>?,
|
||||
),
|
||||
preloadFrequency:
|
||||
_parsePreloadFrequency(json['preloadFrequency'] as String?),
|
||||
batteryThreshold: json['batteryThreshold'] as int? ?? 20,
|
||||
);
|
||||
|
||||
static PreloadMode _parsePreloadMode(String? value) {
|
||||
switch (value) {
|
||||
case 'wifiOnly':
|
||||
return PreloadMode.wifiOnly;
|
||||
case 'disabled':
|
||||
return PreloadMode.disabled;
|
||||
default:
|
||||
return PreloadMode.smart;
|
||||
}
|
||||
}
|
||||
|
||||
static Set<PreloadContentType> _parseContentTypes(List<dynamic>? values) {
|
||||
if (values == null || values.isEmpty) {
|
||||
return const {PreloadContentType.text, PreloadContentType.image};
|
||||
}
|
||||
return values.map((e) {
|
||||
switch (e.toString()) {
|
||||
case 'image':
|
||||
return PreloadContentType.image;
|
||||
case 'audio':
|
||||
return PreloadContentType.audio;
|
||||
default:
|
||||
return PreloadContentType.text;
|
||||
}
|
||||
}).toSet();
|
||||
}
|
||||
|
||||
static PreloadFrequency _parsePreloadFrequency(String? value) {
|
||||
switch (value) {
|
||||
case 'realtime':
|
||||
return PreloadFrequency.realtime;
|
||||
case 'daily':
|
||||
return PreloadFrequency.daily;
|
||||
default:
|
||||
return PreloadFrequency.hourly;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -658,7 +658,7 @@ class AppDatabase extends _$AppDatabase {
|
||||
}
|
||||
|
||||
Future<void> _markMigrationExecuted(int version) async {
|
||||
await into(schemaMigrations).insert(
|
||||
await into(schemaMigrations).insertOnConflictUpdate(
|
||||
SchemaMigrationsCompanion(
|
||||
version: Value(version),
|
||||
executedAt: Value(DateTime.now()),
|
||||
|
||||
Reference in New Issue
Block a user