fix(mobile-app): improve app restart flow for incomplete wallet creation
When user closes app during wallet generation (before backup completion), app now correctly navigates directly to backup mnemonic page on restart instead of requiring extra button click on onboarding page. Changes: - AuthProvider: Add isAccountCreated, isWalletReady, userSerialNum, referralCode states - AuthProvider: Enhanced checkAuthStatus() to detect partial account creation - SplashPage: Add navigation priority for account-created-but-wallet-incomplete state - SplashPage: Navigate directly to BackupMnemonicPage when account exists but wallet not ready Navigation priority: 1. Wallet created + backed up → Main page (ranking) 2. Account created but wallet incomplete → Backup mnemonic page 3. First launch or unseen guide → Guide page 4. Otherwise → Onboarding page 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
This commit is contained in:
parent
823fc5056e
commit
6ff1868944
|
|
@ -3,6 +3,7 @@ import 'package:flutter_riverpod/flutter_riverpod.dart';
|
|||
import 'package:go_router/go_router.dart';
|
||||
import '../../../../core/constants/app_constants.dart';
|
||||
import '../../../../routes/route_paths.dart';
|
||||
import '../../../../routes/app_router.dart';
|
||||
import '../../../../bootstrap.dart';
|
||||
import '../providers/auth_provider.dart';
|
||||
|
||||
|
|
@ -38,20 +39,38 @@ class _SplashPageState extends ConsumerState<SplashPage> {
|
|||
final authState = ref.read(authProvider);
|
||||
|
||||
// 根据认证状态决定跳转目标
|
||||
String targetRoute;
|
||||
// 优先级:
|
||||
// 1. 钱包已创建且已备份 → 主页面
|
||||
// 2. 账号已创建但钱包未完成 → 备份助记词页面
|
||||
// 3. 首次打开或未看过向导 → 向导页
|
||||
// 4. 其他情况 → 创建账户页面
|
||||
if (authState.isWalletCreated) {
|
||||
// 已创建钱包,进入主页面(龙虎榜)
|
||||
targetRoute = RoutePaths.ranking;
|
||||
// 已创建钱包且已备份,进入主页面(龙虎榜)
|
||||
debugPrint('[SplashPage] 钱包已创建且已备份 → 跳转到龙虎榜');
|
||||
context.go(RoutePaths.ranking);
|
||||
} else if (authState.isAccountCreated && authState.userSerialNum != null) {
|
||||
// 账号已创建但钱包未完成(可能正在生成或未备份),直接进入备份助记词页面
|
||||
debugPrint('[SplashPage] 账号已创建但钱包未完成 → 跳转到备份助记词页面');
|
||||
debugPrint('[SplashPage] userSerialNum: ${authState.userSerialNum}, isWalletReady: ${authState.isWalletReady}');
|
||||
context.go(
|
||||
RoutePaths.backupMnemonic,
|
||||
extra: BackupMnemonicParams(
|
||||
userSerialNum: authState.userSerialNum!,
|
||||
referralCode: authState.referralCode,
|
||||
),
|
||||
);
|
||||
} else if (authState.isFirstLaunch || !authState.hasSeenGuide) {
|
||||
// 首次打开或未看过向导,进入向导页
|
||||
targetRoute = RoutePaths.guide;
|
||||
debugPrint('[SplashPage] 首次打开或未看过向导 → 跳转到向导页');
|
||||
context.go(RoutePaths.guide);
|
||||
} else {
|
||||
// 已看过向导但未创建钱包,直接进入创建账户页面
|
||||
targetRoute = RoutePaths.onboarding;
|
||||
debugPrint('[SplashPage] 已看过向导但未创建钱包 → 跳转到创建账户页面');
|
||||
context.go(RoutePaths.onboarding);
|
||||
}
|
||||
|
||||
// 跳转到目标页面
|
||||
context.go(targetRoute);
|
||||
// 获取目标路由用于后续检查
|
||||
final targetRoute = authState.isWalletCreated ? RoutePaths.ranking : null;
|
||||
|
||||
// 延迟检查应用更新(跳转后执行,避免阻塞启动)
|
||||
if (targetRoute == RoutePaths.ranking) {
|
||||
|
|
|
|||
|
|
@ -17,6 +17,14 @@ class AuthState {
|
|||
final bool isFirstLaunch;
|
||||
final bool hasSeenGuide;
|
||||
final String? errorMessage;
|
||||
// 新增:账号是否已创建(但钱包可能还未就绪)
|
||||
final bool isAccountCreated;
|
||||
// 新增:钱包是否已就绪
|
||||
final bool isWalletReady;
|
||||
// 新增:用户序列号(用于跳转到备份助记词页面)
|
||||
final int? userSerialNum;
|
||||
// 新增:推荐码
|
||||
final String? referralCode;
|
||||
|
||||
const AuthState({
|
||||
this.status = AuthStatus.initial,
|
||||
|
|
@ -25,6 +33,10 @@ class AuthState {
|
|||
this.isFirstLaunch = true,
|
||||
this.hasSeenGuide = false,
|
||||
this.errorMessage,
|
||||
this.isAccountCreated = false,
|
||||
this.isWalletReady = false,
|
||||
this.userSerialNum,
|
||||
this.referralCode,
|
||||
});
|
||||
|
||||
AuthState copyWith({
|
||||
|
|
@ -34,6 +46,10 @@ class AuthState {
|
|||
bool? isFirstLaunch,
|
||||
bool? hasSeenGuide,
|
||||
String? errorMessage,
|
||||
bool? isAccountCreated,
|
||||
bool? isWalletReady,
|
||||
int? userSerialNum,
|
||||
String? referralCode,
|
||||
}) {
|
||||
return AuthState(
|
||||
status: status ?? this.status,
|
||||
|
|
@ -42,6 +58,10 @@ class AuthState {
|
|||
isFirstLaunch: isFirstLaunch ?? this.isFirstLaunch,
|
||||
hasSeenGuide: hasSeenGuide ?? this.hasSeenGuide,
|
||||
errorMessage: errorMessage,
|
||||
isAccountCreated: isAccountCreated ?? this.isAccountCreated,
|
||||
isWalletReady: isWalletReady ?? this.isWalletReady,
|
||||
userSerialNum: userSerialNum ?? this.userSerialNum,
|
||||
referralCode: referralCode ?? this.referralCode,
|
||||
);
|
||||
}
|
||||
}
|
||||
|
|
@ -59,22 +79,64 @@ class AuthNotifier extends StateNotifier<AuthState> {
|
|||
final isFirstLaunchStr = await _secureStorage.read(key: StorageKeys.isFirstLaunch);
|
||||
final isFirstLaunch = isFirstLaunchStr == null || isFirstLaunchStr != 'false';
|
||||
|
||||
// 检查钱包状态
|
||||
// 检查账号是否已创建
|
||||
final isAccountCreatedStr = await _secureStorage.read(key: StorageKeys.isAccountCreated);
|
||||
final isAccountCreated = isAccountCreatedStr == 'true';
|
||||
|
||||
// 检查钱包是否已就绪
|
||||
final isWalletReadyStr = await _secureStorage.read(key: StorageKeys.isWalletReady);
|
||||
final isWalletReady = isWalletReadyStr == 'true';
|
||||
|
||||
// 检查助记词是否已备份
|
||||
final isMnemonicBackedUpStr = await _secureStorage.read(key: StorageKeys.isMnemonicBackedUp);
|
||||
final isMnemonicBackedUp = isMnemonicBackedUpStr == 'true';
|
||||
|
||||
// 获取用户序列号和推荐码(用于跳转到备份页面)
|
||||
final userSerialNumStr = await _secureStorage.read(key: StorageKeys.userSerialNum);
|
||||
final userSerialNum = userSerialNumStr != null ? int.tryParse(userSerialNumStr) : null;
|
||||
final referralCode = await _secureStorage.read(key: StorageKeys.referralCode);
|
||||
|
||||
// 旧版兼容:检查旧的 walletAddress 字段
|
||||
final walletAddress = await _secureStorage.read(key: StorageKeys.walletAddress);
|
||||
final isWalletCreated = walletAddress != null && walletAddress.isNotEmpty;
|
||||
final hasLegacyWallet = walletAddress != null && walletAddress.isNotEmpty;
|
||||
|
||||
// 综合判断钱包是否已创建完成
|
||||
// 1. 新版:isWalletReady == true 且 isMnemonicBackedUp == true
|
||||
// 2. 旧版兼容:有 walletAddress
|
||||
final isWalletCreated = (isWalletReady && isMnemonicBackedUp) || hasLegacyWallet;
|
||||
|
||||
if (isWalletCreated) {
|
||||
// 钱包已创建且备份完成,进入主页面
|
||||
state = state.copyWith(
|
||||
status: AuthStatus.authenticated,
|
||||
walletAddress: walletAddress,
|
||||
isWalletCreated: true,
|
||||
isAccountCreated: true,
|
||||
isWalletReady: true,
|
||||
isFirstLaunch: false,
|
||||
hasSeenGuide: true,
|
||||
userSerialNum: userSerialNum,
|
||||
referralCode: referralCode,
|
||||
);
|
||||
} else {
|
||||
} else if (isAccountCreated) {
|
||||
// 账号已创建但钱包未完成(可能正在生成或未备份)
|
||||
state = state.copyWith(
|
||||
status: AuthStatus.unauthenticated,
|
||||
isWalletCreated: false,
|
||||
isAccountCreated: true,
|
||||
isWalletReady: isWalletReady,
|
||||
isFirstLaunch: false,
|
||||
hasSeenGuide: true,
|
||||
userSerialNum: userSerialNum,
|
||||
referralCode: referralCode,
|
||||
);
|
||||
} else {
|
||||
// 账号未创建
|
||||
state = state.copyWith(
|
||||
status: AuthStatus.unauthenticated,
|
||||
isWalletCreated: false,
|
||||
isAccountCreated: false,
|
||||
isWalletReady: false,
|
||||
isFirstLaunch: isFirstLaunch,
|
||||
hasSeenGuide: !isFirstLaunch,
|
||||
);
|
||||
|
|
|
|||
Loading…
Reference in New Issue