优化:积分页面积分同步处理
This commit is contained in:
parent
5cfb4c74af
commit
6ae2b55677
@ -90,7 +90,7 @@ class _MainScaffold extends StatelessWidget {
|
||||
body: IndexedStack(
|
||||
index: currentTab.index,
|
||||
children: [
|
||||
const HomeScreen(),
|
||||
HomeScreen(isActive: currentTab == NavTab.home),
|
||||
GalleryScreen(isActive: currentTab == NavTab.gallery),
|
||||
ProfileScreen(isActive: currentTab == NavTab.profile),
|
||||
],
|
||||
|
||||
30
lib/core/user/account_refresh.dart
Normal file
30
lib/core/user/account_refresh.dart
Normal file
@ -0,0 +1,30 @@
|
||||
import '../api/api_config.dart';
|
||||
import '../api/services/user_api.dart';
|
||||
import '../auth/auth_service.dart';
|
||||
import 'user_state.dart';
|
||||
|
||||
/// 刷新用户账户信息并更新 UserState
|
||||
///
|
||||
/// [updateProfile] 为 true 时,同时更新 avatar 和 userName(用于 Profile 页)
|
||||
Future<void> refreshAccount({bool updateProfile = false}) 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 (!res.isSuccess || res.data == null) return;
|
||||
final data = res.data as Map<String, dynamic>?;
|
||||
final credits = data?['reveal'] as int?;
|
||||
if (credits != null) UserState.setCredits(credits);
|
||||
if (updateProfile) {
|
||||
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 (_) {}
|
||||
}
|
||||
@ -8,7 +8,6 @@ import '../../core/api/services/image_api.dart';
|
||||
import '../../core/auth/auth_service.dart';
|
||||
import '../../core/theme/app_colors.dart';
|
||||
import '../../core/theme/app_spacing.dart';
|
||||
import '../../core/user/user_state.dart';
|
||||
import '../../shared/widgets/top_nav_bar.dart';
|
||||
|
||||
import 'models/gallery_task_item.dart';
|
||||
@ -142,9 +141,7 @@ class _GalleryScreenState extends State<GalleryScreen> {
|
||||
appBar: PreferredSize(
|
||||
preferredSize: const Size.fromHeight(56),
|
||||
child: TopNavBar(
|
||||
title: 'Gallery',
|
||||
credits: UserCreditsData.of(context)?.creditsDisplay ?? '--',
|
||||
onCreditsTap: () => Navigator.of(context).pushNamed('/recharge'),
|
||||
title: 'My Gallery',
|
||||
),
|
||||
),
|
||||
body: _loading
|
||||
@ -176,7 +173,8 @@ class _GalleryScreenState extends State<GalleryScreen> {
|
||||
onRefresh: () => _loadTasks(refresh: true),
|
||||
child: _gridItems.isEmpty && !_loading
|
||||
? SingleChildScrollView(
|
||||
physics: const AlwaysScrollableScrollPhysics(),
|
||||
physics:
|
||||
const AlwaysScrollableScrollPhysics(),
|
||||
child: SizedBox(
|
||||
height: constraints.maxHeight - 100,
|
||||
child: Center(
|
||||
@ -190,7 +188,8 @@ class _GalleryScreenState extends State<GalleryScreen> {
|
||||
),
|
||||
)
|
||||
: GridView.builder(
|
||||
physics: const AlwaysScrollableScrollPhysics(),
|
||||
physics:
|
||||
const AlwaysScrollableScrollPhysics(),
|
||||
controller: _scrollController,
|
||||
padding: EdgeInsets.fromLTRB(
|
||||
AppSpacing.screenPadding,
|
||||
@ -206,8 +205,8 @@ class _GalleryScreenState extends State<GalleryScreen> {
|
||||
mainAxisSpacing: AppSpacing.xl,
|
||||
crossAxisSpacing: AppSpacing.xl,
|
||||
),
|
||||
itemCount:
|
||||
_gridItems.length + (_loadingMore ? 1 : 0),
|
||||
itemCount: _gridItems.length +
|
||||
(_loadingMore ? 1 : 0),
|
||||
itemBuilder: (context, index) {
|
||||
if (index >= _gridItems.length) {
|
||||
return const Center(
|
||||
|
||||
@ -13,13 +13,12 @@ import '../../core/log/app_logger.dart';
|
||||
import '../../core/theme/app_colors.dart';
|
||||
import '../../core/theme/app_spacing.dart';
|
||||
import '../../core/theme/app_typography.dart';
|
||||
import '../../core/user/account_refresh.dart';
|
||||
import '../../core/user/user_state.dart';
|
||||
import '../../features/home/models/task_item.dart';
|
||||
import '../../shared/widgets/top_nav_bar.dart';
|
||||
|
||||
import '../../core/api/api_config.dart';
|
||||
import '../../core/api/services/image_api.dart';
|
||||
import '../../core/api/services/user_api.dart';
|
||||
|
||||
/// Generate Video screen - matches Pencil mmLB5
|
||||
class GenerateVideoScreen extends StatefulWidget {
|
||||
@ -56,6 +55,7 @@ class _GenerateVideoScreenState extends State<GenerateVideoScreen> {
|
||||
@override
|
||||
void initState() {
|
||||
super.initState();
|
||||
refreshAccount();
|
||||
WidgetsBinding.instance.addPostFrameCallback((_) {
|
||||
GenerateVideoScreen._log.d('opened with task: ${widget.task}');
|
||||
});
|
||||
@ -192,17 +192,7 @@ class _GenerateVideoScreenState extends State<GenerateVideoScreen> {
|
||||
final taskId = taskData?['tree'];
|
||||
|
||||
// 创建任务成功后刷新用户账户信息(积分等)
|
||||
final accountRes = await UserApi.getAccount(
|
||||
sentinel: ApiConfig.appId,
|
||||
asset: userId,
|
||||
);
|
||||
if (accountRes.isSuccess && accountRes.data != null) {
|
||||
final accountData = accountRes.data as Map<String, dynamic>?;
|
||||
final credits = accountData?['reveal'] as int?;
|
||||
if (credits != null) {
|
||||
UserState.setCredits(credits);
|
||||
}
|
||||
}
|
||||
await refreshAccount();
|
||||
|
||||
if (!mounted) return;
|
||||
Navigator.of(context).pushReplacementNamed(
|
||||
@ -235,10 +225,8 @@ class _GenerateVideoScreenState extends State<GenerateVideoScreen> {
|
||||
preferredSize: const Size.fromHeight(56),
|
||||
child: TopNavBar(
|
||||
title: 'Generate Video',
|
||||
credits: UserCreditsData.of(context)?.creditsDisplay ?? '--',
|
||||
showBackButton: true,
|
||||
onBack: () => Navigator.of(context).pop(),
|
||||
onCreditsTap: () => Navigator.of(context).pushNamed('/recharge'),
|
||||
),
|
||||
),
|
||||
body: Column(
|
||||
|
||||
@ -1,8 +1,9 @@
|
||||
import 'package:flutter/material.dart';
|
||||
|
||||
import '../../core/api/services/image_api.dart';
|
||||
import '../../core/user/user_state.dart';
|
||||
import '../../core/auth/auth_service.dart';
|
||||
import '../../core/user/account_refresh.dart';
|
||||
import '../../core/user/user_state.dart';
|
||||
import '../../core/theme/app_spacing.dart';
|
||||
import '../../shared/widgets/top_nav_bar.dart';
|
||||
import 'models/category_item.dart';
|
||||
@ -12,7 +13,9 @@ import 'widgets/video_card.dart';
|
||||
|
||||
/// AI Video App home screen - tab 来自分类接口,Grid 来自任务列表接口
|
||||
class HomeScreen extends StatefulWidget {
|
||||
const HomeScreen({super.key});
|
||||
const HomeScreen({super.key, this.isActive = true});
|
||||
|
||||
final bool isActive;
|
||||
|
||||
@override
|
||||
State<HomeScreen> createState() => _HomeScreenState();
|
||||
@ -30,6 +33,15 @@ class _HomeScreenState extends State<HomeScreen> {
|
||||
void initState() {
|
||||
super.initState();
|
||||
_loadCategories();
|
||||
if (widget.isActive) refreshAccount();
|
||||
}
|
||||
|
||||
@override
|
||||
void didUpdateWidget(covariant HomeScreen oldWidget) {
|
||||
super.didUpdateWidget(oldWidget);
|
||||
if (widget.isActive && !oldWidget.isActive) {
|
||||
refreshAccount();
|
||||
}
|
||||
}
|
||||
|
||||
Future<void> _loadCategories() async {
|
||||
|
||||
@ -2,9 +2,7 @@ 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/user/account_refresh.dart';
|
||||
import '../recharge/payment_webview_screen.dart';
|
||||
import '../../core/theme/app_colors.dart';
|
||||
import '../../core/user/user_state.dart';
|
||||
@ -25,41 +23,17 @@ class _ProfileScreenState extends State<ProfileScreen> {
|
||||
@override
|
||||
void initState() {
|
||||
super.initState();
|
||||
if (widget.isActive) _fetchAccount();
|
||||
if (widget.isActive) refreshAccount(updateProfile: true);
|
||||
}
|
||||
|
||||
@override
|
||||
void didUpdateWidget(covariant ProfileScreen oldWidget) {
|
||||
super.didUpdateWidget(oldWidget);
|
||||
if (widget.isActive && !oldWidget.isActive) {
|
||||
_fetchAccount();
|
||||
refreshAccount(updateProfile: true);
|
||||
}
|
||||
}
|
||||
|
||||
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) {
|
||||
return Scaffold(
|
||||
|
||||
@ -6,6 +6,7 @@ import '../../core/adjust/adjust_events.dart';
|
||||
import '../../core/api/api_config.dart';
|
||||
import '../../core/api/services/payment_api.dart';
|
||||
import '../../core/auth/auth_service.dart';
|
||||
import '../../core/user/account_refresh.dart';
|
||||
import '../../core/log/app_logger.dart';
|
||||
import '../../core/theme/app_colors.dart';
|
||||
import '../../core/user/user_state.dart';
|
||||
@ -39,6 +40,7 @@ class _RechargeScreenState extends State<RechargeScreen> with WidgetsBindingObse
|
||||
void initState() {
|
||||
super.initState();
|
||||
WidgetsBinding.instance.addObserver(this);
|
||||
refreshAccount();
|
||||
_fetchActivities();
|
||||
}
|
||||
|
||||
@ -368,10 +370,8 @@ class _RechargeScreenState extends State<RechargeScreen> with WidgetsBindingObse
|
||||
preferredSize: const Size.fromHeight(56),
|
||||
child: TopNavBar(
|
||||
title: 'Recharge',
|
||||
credits: UserCreditsData.of(context)?.creditsDisplay ?? '--',
|
||||
showBackButton: true,
|
||||
onBack: () => Navigator.of(context).pop(),
|
||||
onCreditsTap: null,
|
||||
),
|
||||
),
|
||||
body: SingleChildScrollView(
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user