新增:更新个人中心数据显示
This commit is contained in:
parent
dedc03fc3c
commit
f3a163c958
@ -83,7 +83,7 @@ class _MainScaffold extends StatelessWidget {
|
||||
children: [
|
||||
const HomeScreen(),
|
||||
GalleryScreen(isActive: currentTab == NavTab.gallery),
|
||||
const ProfileScreen(),
|
||||
ProfileScreen(isActive: currentTab == NavTab.profile),
|
||||
],
|
||||
),
|
||||
bottomNavigationBar: BottomNavBar(
|
||||
|
||||
@ -118,6 +118,14 @@ class AuthService {
|
||||
UserState.setUserId(uid);
|
||||
_log('init: 已设置 userId');
|
||||
}
|
||||
final avatarUrl = data?['realm'] as String?;
|
||||
if (avatarUrl != null && avatarUrl.isNotEmpty) {
|
||||
UserState.setAvatar(avatarUrl);
|
||||
}
|
||||
final name = data?['terminal'] as String?;
|
||||
if (name != null && name.isNotEmpty) {
|
||||
UserState.setUserName(name);
|
||||
}
|
||||
} else {
|
||||
_log('init: 登录失败');
|
||||
}
|
||||
|
||||
@ -6,6 +6,8 @@ class UserState {
|
||||
|
||||
static final ValueNotifier<int?> credits = ValueNotifier<int?>(null);
|
||||
static final ValueNotifier<String?> userId = ValueNotifier<String?>(null);
|
||||
static final ValueNotifier<String?> avatar = ValueNotifier<String?>(null);
|
||||
static final ValueNotifier<String?> userName = ValueNotifier<String?>(null);
|
||||
|
||||
static void setCredits(int? value) {
|
||||
credits.value = value;
|
||||
@ -15,6 +17,14 @@ class UserState {
|
||||
userId.value = value;
|
||||
}
|
||||
|
||||
static void setAvatar(String? value) {
|
||||
avatar.value = value;
|
||||
}
|
||||
|
||||
static void setUserName(String? value) {
|
||||
userName.value = value;
|
||||
}
|
||||
|
||||
static String formatCredits(int? value) {
|
||||
if (value == null) return '--';
|
||||
return value.toString().replaceAllMapped(
|
||||
|
||||
@ -1,14 +1,63 @@
|
||||
import 'package:flutter/material.dart';
|
||||
import 'package:flutter_lucide/flutter_lucide.dart';
|
||||
import 'package:cached_network_image/cached_network_image.dart';
|
||||
|
||||
import '../../core/api/api_config.dart';
|
||||
import '../../core/api/services/user_api.dart';
|
||||
import '../../core/auth/auth_service.dart';
|
||||
import '../../core/theme/app_colors.dart';
|
||||
import '../../core/user/user_state.dart';
|
||||
import '../../core/theme/app_spacing.dart';
|
||||
import '../../core/theme/app_typography.dart';
|
||||
|
||||
/// Profile screen - matches Pencil KXeow
|
||||
class ProfileScreen extends StatelessWidget {
|
||||
const ProfileScreen({super.key});
|
||||
class ProfileScreen extends StatefulWidget {
|
||||
const ProfileScreen({super.key, required this.isActive});
|
||||
|
||||
final bool isActive;
|
||||
|
||||
@override
|
||||
State<ProfileScreen> createState() => _ProfileScreenState();
|
||||
}
|
||||
|
||||
class _ProfileScreenState extends State<ProfileScreen> {
|
||||
@override
|
||||
void initState() {
|
||||
super.initState();
|
||||
if (widget.isActive) _fetchAccount();
|
||||
}
|
||||
|
||||
@override
|
||||
void didUpdateWidget(covariant ProfileScreen oldWidget) {
|
||||
super.didUpdateWidget(oldWidget);
|
||||
if (widget.isActive && !oldWidget.isActive) {
|
||||
_fetchAccount();
|
||||
}
|
||||
}
|
||||
|
||||
Future<void> _fetchAccount() async {
|
||||
final uid = UserState.userId.value;
|
||||
if (uid == null || uid.isEmpty) return;
|
||||
try {
|
||||
await AuthService.loginComplete;
|
||||
final res = await UserApi.getAccount(
|
||||
sentinel: ApiConfig.appId,
|
||||
asset: uid,
|
||||
);
|
||||
if (!mounted) return;
|
||||
if (res.isSuccess && res.data != null) {
|
||||
final data = res.data as Map<String, dynamic>?;
|
||||
final credits = data?['reveal'] as int?;
|
||||
if (credits != null) UserState.setCredits(credits);
|
||||
final avatarUrl = data?['realm'] as String?;
|
||||
UserState.setAvatar(
|
||||
avatarUrl != null && avatarUrl.isNotEmpty ? avatarUrl : null);
|
||||
final name = data?['terminal'] as String?;
|
||||
UserState.setUserName(
|
||||
name != null && name.isNotEmpty ? name : null);
|
||||
}
|
||||
} catch (_) {}
|
||||
}
|
||||
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
@ -23,9 +72,25 @@ class ProfileScreen extends StatelessWidget {
|
||||
),
|
||||
child: Column(
|
||||
children: [
|
||||
_ProfileHeader(
|
||||
userName: 'Alex Johnson',
|
||||
uid: 'UID 84920133',
|
||||
ValueListenableBuilder<String?>(
|
||||
valueListenable: UserState.avatar,
|
||||
builder: (_, avatarUrl, __) {
|
||||
return ValueListenableBuilder<String?>(
|
||||
valueListenable: UserState.userName,
|
||||
builder: (_, userName, __) {
|
||||
return ValueListenableBuilder<String?>(
|
||||
valueListenable: UserState.userId,
|
||||
builder: (_, userId, __) {
|
||||
return _ProfileHeader(
|
||||
avatarUrl: avatarUrl,
|
||||
userName: userName,
|
||||
uid: userId,
|
||||
);
|
||||
},
|
||||
);
|
||||
},
|
||||
);
|
||||
},
|
||||
),
|
||||
const SizedBox(height: AppSpacing.xl),
|
||||
_BalanceCard(
|
||||
@ -56,12 +121,14 @@ class ProfileScreen extends StatelessWidget {
|
||||
|
||||
class _ProfileHeader extends StatelessWidget {
|
||||
const _ProfileHeader({
|
||||
required this.userName,
|
||||
required this.uid,
|
||||
this.avatarUrl,
|
||||
this.userName,
|
||||
this.uid,
|
||||
});
|
||||
|
||||
final String userName;
|
||||
final String uid;
|
||||
final String? avatarUrl;
|
||||
final String? userName;
|
||||
final String? uid;
|
||||
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
@ -82,7 +149,23 @@ class _ProfileHeader extends StatelessWidget {
|
||||
width: 2,
|
||||
),
|
||||
),
|
||||
child: const Icon(
|
||||
clipBehavior: Clip.antiAlias,
|
||||
child: avatarUrl != null && avatarUrl!.isNotEmpty
|
||||
? CachedNetworkImage(
|
||||
imageUrl: avatarUrl!,
|
||||
fit: BoxFit.cover,
|
||||
placeholder: (_, __) => Icon(
|
||||
LucideIcons.user,
|
||||
size: 40,
|
||||
color: AppColors.textSecondary,
|
||||
),
|
||||
errorWidget: (_, __, ___) => Icon(
|
||||
LucideIcons.user,
|
||||
size: 40,
|
||||
color: AppColors.textSecondary,
|
||||
),
|
||||
)
|
||||
: Icon(
|
||||
LucideIcons.user,
|
||||
size: 40,
|
||||
color: AppColors.textSecondary,
|
||||
@ -90,7 +173,7 @@ class _ProfileHeader extends StatelessWidget {
|
||||
),
|
||||
const SizedBox(height: AppSpacing.lg),
|
||||
Text(
|
||||
userName,
|
||||
userName ?? 'Guest',
|
||||
style: AppTypography.bodyLarge.copyWith(
|
||||
color: AppColors.textPrimary,
|
||||
),
|
||||
@ -107,7 +190,7 @@ class _ProfileHeader extends StatelessWidget {
|
||||
border: Border.all(color: AppColors.border),
|
||||
),
|
||||
child: Text(
|
||||
uid,
|
||||
uid != null && uid!.isNotEmpty ? 'UID $uid' : 'UID --',
|
||||
style: AppTypography.caption.copyWith(
|
||||
color: AppColors.textSecondary,
|
||||
),
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user