feat: make core pages local-first offline

This commit is contained in:
2026-08-21 12:40:01 +08:00
parent 8828851631
commit fefa2d74e6
20 changed files with 921 additions and 188 deletions
+48 -9
View File
@@ -1,5 +1,9 @@
import 'dart:convert';
import 'package:dio/dio.dart';
import 'package:shared_preferences/shared_preferences.dart';
import 'package:miaoji_zhang/shared/api/api_client.dart';
import 'package:miaoji_zhang/shared/api/backend_identity.dart';
import 'package:miaoji_zhang/shared/services/current_ledger_store.dart';
import 'package:miaoji_zhang/shared/services/local_export_service.dart';
import 'package:miaoji_zhang/shared/services/session_store.dart';
@@ -19,6 +23,15 @@ class AiCompanion {
roastLevel = json['roastLevel'] as int,
stickerFrequency = json['stickerFrequency'] as int,
proactiveLevel = json['proactiveLevel'] as int;
Map<String, dynamic> toJson() => {
'avatarKey': avatarKey,
'personaKey': personaKey,
'customName': customName,
'roastLevel': roastLevel,
'stickerFrequency': stickerFrequency,
'proactiveLevel': proactiveLevel,
};
}
class UserProfile {
@@ -49,8 +62,9 @@ class UserProfile {
required this.nickname,
required this.appMode,
required this.onboardingDone,
this.aiCompanion,
this.aiEnabled = false,
}) : aiCompanion = null;
});
}
class AuthLoginResult {
@@ -120,6 +134,20 @@ class AuthApi {
}
}
static Future<AiCompanion?> cachedCompanion() async {
final userId = SessionStore.instance.userId;
if (userId == null) return null;
final value = (await SharedPreferences.getInstance()).getString(
_companionCacheKey(userId),
);
if (value == null) return null;
try {
return AiCompanion.fromJson(jsonDecode(value) as Map<String, dynamic>);
} catch (_) {
return null;
}
}
static Future<UserProfile> completeOnboarding({
required String appMode,
required String avatarKey,
@@ -272,13 +300,24 @@ class AuthApi {
);
}
static Future<void> _cacheProfile(UserProfile profile) =>
SessionStore.instance.activateAccount(
userId: profile.userId,
username: profile.username,
nickname: profile.nickname,
appMode: profile.appMode,
onboardingDone: profile.onboardingDone,
aiEnabled: profile.aiEnabled,
static Future<void> _cacheProfile(UserProfile profile) async {
await SessionStore.instance.activateAccount(
userId: profile.userId,
username: profile.username,
nickname: profile.nickname,
appMode: profile.appMode,
onboardingDone: profile.onboardingDone,
aiEnabled: profile.aiEnabled,
);
final companion = profile.aiCompanion;
if (companion != null) {
await (await SharedPreferences.getInstance()).setString(
_companionCacheKey(profile.userId),
jsonEncode(companion.toJson()),
);
}
}
static String _companionCacheKey(int userId) =>
'ai_companion_${BackendIdentity.scope}_$userId';
}