Commit dc2ea068cd28130ba7a192e2b725202b30760719

Authored by 常守达
1 parent 528f3532

fix(login): 苹果登录loading

... ... @@ -335,7 +335,7 @@ class TodayController extends GetMaterialController {
Future<void> onAuthorizeTap() async {
ta.track('click_doublefeel_today_status', properties: {'ita': '授权访问健康数据'});
if (showHealthDataAuthCardStatus.value == 1) {
if (showHealthDataAuthCardStatus.value == 1 && hrvChartData.isNotEmpty) {
return;
} else if (showHealthDataAuthCardStatus.value == 0) {
await requestHealthAuthorization(isFromNoPermissionPage: true);
... ... @@ -344,6 +344,9 @@ class TodayController extends GetMaterialController {
await Get.to(NoHealthDataPage(
onRefresh: () {
refreshTab();
Future.delayed(const Duration(milliseconds: 800), () {
AppToast.show(l10n.refreshComplete);
});
},
onHelp: () {
Get.toNamed(Routes.HELP);
... ...
... ... @@ -61,24 +61,27 @@ class LoginController extends GetxController {
final newValue = !termsChecked.value;
termsChecked.value = newValue;
// ① 写盘不 await,避免阻塞(SharedPrefs 写失败影响极小)
unawaited(Get.find<LocalStorage>().setTermsAgreed(newValue).catchError(
(e) => AppLogger.e('setTermsAgreed error: $e'),
));
if (newValue && !_userStateService.sdksInitialized) {
// ② SDK 初始化完全异步,不阻塞任何点击
unawaited(_initSdksAndTrack());
}
}
Future<void> _initSdksAndTrack() async {
try {
final local = Get.find<LocalStorage>();
await local.setTermsAgreed(newValue);
if (newValue) {
unawaited(() async {
// 等待 Flutter 完成当前帧渲染,让勾选图标先显示
await WidgetsBinding.instance.endOfFrame;
if (!_userStateService.sdksInitialized) {
await _userStateService.initializeSdks();
}
if (needTrackWelcomepage) {
ta.track('enter_doublefeel_welcome_page');
needTrackWelcomepage = false;
}
}());
await _userStateService.initializeSdks();
if (needTrackWelcomepage) {
ta.track('enter_doublefeel_welcome_page');
needTrackWelcomepage = false;
}
} catch (e) {
AppLogger.e(e.toString());
AppLogger.e('initializeSdks error: $e');
}
}
... ... @@ -99,7 +102,7 @@ class LoginController extends GetxController {
try {
final result = await LoadingService.instance.run(() async {
return await PlatformHostApi().requestAppleSignIn();
});
}, type: LoadingType.circular);
// result 为 null 或 identityToken 为空,说明用户取消或苹果授权失败
if (result == null ||
result.identityToken?.isNotEmpty != true ||
... ...
... ... @@ -2,6 +2,11 @@ import 'package:flutter/material.dart';
import 'package:get/get.dart';
import 'package:lottie/lottie.dart';
/// Loading 动画类型
/// - [lottie] 默认,使用 Lottie 动画(现有行为,保持不变)
/// - [circular] 使用系统 CircularProgressIndicator
enum LoadingType { lottie, circular }
class LoadingService {
OverlayEntry? _entry;
int _counter = 0;
... ... @@ -13,8 +18,9 @@ class LoadingService {
static LoadingService get instance => Get.find();
/// 包装一个异步操作,执行期间显示 Loading,完成后自动隐藏。
Future<T> run<T>(Future<T> Function() block) async {
show();
Future<T> run<T>(Future<T> Function() block,
{LoadingType type = LoadingType.lottie}) async {
show(type: type);
try {
return await block();
} finally {
... ... @@ -22,7 +28,7 @@ class LoadingService {
}
}
void show() {
void show({LoadingType type = LoadingType.lottie}) {
_counter++;
if (_counter > 1) return;
... ... @@ -35,7 +41,9 @@ class LoadingService {
// 防御:清理可能残留的旧 entry
_entry?.remove();
_entry = OverlayEntry(builder: (_) => const _GlobalLoadingWidget());
_entry = OverlayEntry(
builder: (_) => _GlobalLoadingWidget(type: type),
);
overlay.insert(_entry!);
}
... ... @@ -50,7 +58,9 @@ class LoadingService {
}
class _GlobalLoadingWidget extends StatelessWidget {
const _GlobalLoadingWidget();
const _GlobalLoadingWidget({this.type = LoadingType.lottie});
final LoadingType type;
@override
Widget build(BuildContext context) {
... ... @@ -63,16 +73,27 @@ class _GlobalLoadingWidget extends StatelessWidget {
color: Colors.black.withValues(alpha: 0.3),
child: Align(
alignment: const Alignment(0.0, -0.1),
child: Lottie.asset(
'assets/lottie/loading.json',
width: 130,
height: 90,
repeat: true,
animate: true,
),
child: _buildIndicator(),
),
),
),
);
}
Widget _buildIndicator() {
switch (type) {
case LoadingType.lottie:
return Lottie.asset(
'assets/lottie/loading.json',
width: 130,
height: 90,
repeat: true,
animate: true,
);
case LoadingType.circular:
return const CircularProgressIndicator(
strokeWidth: 3,
);
}
}
}
... ...
... ... @@ -771,5 +771,6 @@
"healthLocalNotificationRealtimeStressAttentionContent": "Your stress was elevated over the past 60 minutes. Consider relaxing and making time for rest and recovery.",
"healthLocalNotificationRealtimeStressOverloadContent": "You stayed in a high-stress state over the past 60 minutes. Reduce exertion and prioritize rest and sleep.",
"turnOnNotifications": "Turn on Notifications",
"stayUpToDateOnChangesInYourOwnAndYourFriendsHealth": "Stay up to date on changes in your own and your friends' health"
}
"stayUpToDateOnChangesInYourOwnAndYourFriendsHealth": "Stay up to date on changes in your own and your friends' health",
"refreshComplete": "Refresh Complete"
}
\ No newline at end of file
... ...
... ... @@ -1164,5 +1164,6 @@
"healthLocalNotificationRealtimeStressAttentionContent": "你过去60分钟压力偏高,建议适当放松,并注意休息与恢复。",
"healthLocalNotificationRealtimeStressOverloadContent": "你过去60分钟持续处于高压力状态,建议减少消耗,并优先保证休息与睡眠。",
"turnOnNotifications": "开启通知",
"stayUpToDateOnChangesInYourOwnAndYourFriendsHealth": "及时了解自己和好友的健康波动"
}
"stayUpToDateOnChangesInYourOwnAndYourFriendsHealth": "及时了解自己和好友的健康波动",
"refreshComplete": "刷新完成"
}
\ No newline at end of file
... ...
... ... @@ -4149,6 +4149,12 @@ abstract class AppLocalizations {
/// In zh, this message translates to:
/// **'及时了解自己和好友的健康波动'**
String get stayUpToDateOnChangesInYourOwnAndYourFriendsHealth;
/// No description provided for @refreshComplete.
///
/// In zh, this message translates to:
/// **'刷新完成'**
String get refreshComplete;
}
class _AppLocalizationsDelegate
... ...
... ... @@ -2336,4 +2336,7 @@ class AppLocalizationsEn extends AppLocalizations {
@override
String get stayUpToDateOnChangesInYourOwnAndYourFriendsHealth =>
'Stay up to date on changes in your own and your friends\' health';
@override
String get refreshComplete => 'Refresh Complete';
}
... ...
... ... @@ -2232,4 +2232,7 @@ class AppLocalizationsZh extends AppLocalizations {
@override
String get stayUpToDateOnChangesInYourOwnAndYourFriendsHealth =>
'及时了解自己和好友的健康波动';
@override
String get refreshComplete => '刷新完成';
}
... ...