bug fix
This commit is contained in:
parent
92bbbcb0eb
commit
f2e9ac3c60
@ -1,11 +1,13 @@
|
||||
import 'package:fluro/fluro.dart' as fluro;
|
||||
import 'package:flutter/material.dart';
|
||||
import 'package:provider/provider.dart';
|
||||
import 'package:yumi/app/routes/sc_router_init.dart';
|
||||
import 'package:yumi/modules/country/country_route.dart';
|
||||
import 'package:yumi/modules/index/main_route.dart';
|
||||
import 'package:yumi/modules/chat/chat_route.dart';
|
||||
import 'package:yumi/modules/store/store_route.dart';
|
||||
import 'package:yumi/modules/index/index_page.dart';
|
||||
import 'package:yumi/services/room/rc_room_manager.dart';
|
||||
import 'package:yumi/modules/user/settings/settings_route.dart';
|
||||
import 'package:yumi/modules/user/task/task_route.dart';
|
||||
import 'package:yumi/modules/user/vip/vip_route.dart';
|
||||
@ -32,7 +34,7 @@ class SCRoutes {
|
||||
handler: fluro.Handler(
|
||||
handlerFunc:
|
||||
(BuildContext? context, Map<String, List<String>> params) =>
|
||||
SCIndexPage(),
|
||||
_buildHomePage(context),
|
||||
),
|
||||
);
|
||||
|
||||
@ -57,6 +59,13 @@ class SCRoutes {
|
||||
routerProvider.initRouter(router);
|
||||
}
|
||||
}
|
||||
|
||||
static Widget _buildHomePage(BuildContext? context) {
|
||||
return ChangeNotifierProvider<SocialChatRoomManager>.value(
|
||||
value: resolveSocialChatRoomManager(context),
|
||||
child: const SCIndexPage(),
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
// PS:路由使用方法
|
||||
|
||||
@ -241,9 +241,8 @@ class RootAppWithProviders extends StatelessWidget {
|
||||
),
|
||||
|
||||
// 房间与社交功能Provider - 懒加载
|
||||
ChangeNotifierProvider<SocialChatRoomManager>(
|
||||
lazy: true,
|
||||
create: (context) => SocialChatRoomManager(),
|
||||
ChangeNotifierProvider<SocialChatRoomManager>.value(
|
||||
value: socialChatRoomManager,
|
||||
),
|
||||
|
||||
// 礼物与动画系统Provider - 懒加载
|
||||
|
||||
@ -640,7 +640,9 @@ class _SCEditProfilePageState extends State<SCEditProfilePage> {
|
||||
authType = SCAuthType.GOOGLE.name;
|
||||
idToken = googleUid;
|
||||
}
|
||||
} catch (e) {}
|
||||
} catch (_) {
|
||||
// Fallback auth lookup is best effort; the form will ask to sign in again below.
|
||||
}
|
||||
}
|
||||
if (authType.isEmpty || idToken.isEmpty) {
|
||||
SCLoadingManager.hide();
|
||||
|
||||
@ -563,7 +563,8 @@ class _SCIndexPageState extends State<SCIndexPage>
|
||||
return;
|
||||
}
|
||||
await SCEntryPopupCoordinator.openFirstPartyRoomRandomGame(context);
|
||||
} catch (error) {
|
||||
} catch (_) {
|
||||
// The entry popup is optional; failure should not block the home page.
|
||||
} finally {
|
||||
_isOpeningFirstRegisterRoomGame = false;
|
||||
}
|
||||
|
||||
@ -2708,13 +2708,7 @@ class RealTimeCommunicationManager extends ChangeNotifier {
|
||||
return;
|
||||
}
|
||||
_startRoomStatePolling();
|
||||
final currentContext = context;
|
||||
if (currentContext != null && currentContext.mounted) {
|
||||
Provider.of<SocialChatRoomManager>(
|
||||
currentContext,
|
||||
listen: false,
|
||||
).fetchContributionLevelData(roomId);
|
||||
}
|
||||
socialChatRoomManager.fetchContributionLevelData(roomId);
|
||||
|
||||
failureType = RoomStartupFailureType.rtc;
|
||||
final rtcTokenResult = await rtcTokenFuture;
|
||||
@ -3400,13 +3394,7 @@ class RealTimeCommunicationManager extends ChangeNotifier {
|
||||
|
||||
void _clearRoomContributionLevelData([BuildContext? targetContext]) {
|
||||
final currentContext = targetContext ?? context;
|
||||
if (currentContext == null || !currentContext.mounted) {
|
||||
return;
|
||||
}
|
||||
Provider.of<SocialChatRoomManager>(
|
||||
currentContext,
|
||||
listen: false,
|
||||
).clearContributionLevelData();
|
||||
resolveSocialChatRoomManager(currentContext).clearContributionLevelData();
|
||||
}
|
||||
|
||||
@override
|
||||
|
||||
@ -32,8 +32,12 @@ class SocialChatAuthenticationManager extends ChangeNotifier {
|
||||
}
|
||||
|
||||
Future<void> _initializeAuthentication() async {
|
||||
await SCGoogleAuthService.initialize();
|
||||
await _verifyExistingSession();
|
||||
try {
|
||||
await SCGoogleAuthService.initialize();
|
||||
await _verifyExistingSession();
|
||||
} catch (_) {
|
||||
// Login buttons should remain usable even if silent Google restore fails.
|
||||
}
|
||||
}
|
||||
|
||||
Future<void> _verifyExistingSession() async {
|
||||
@ -51,10 +55,11 @@ class SocialChatAuthenticationManager extends ChangeNotifier {
|
||||
if (authType == SCAuthType.GOOGLE.name) {
|
||||
this.authType = authType;
|
||||
try {
|
||||
_user ??= await SCGoogleAuthService.signInWithGoogle();
|
||||
if (_user == null) {
|
||||
final signedInUser = await SCGoogleAuthService.signInWithGoogle();
|
||||
if (signedInUser == null) {
|
||||
return;
|
||||
}
|
||||
_user = signedInUser;
|
||||
uid = _user!.uid;
|
||||
SCLoadingManager.show();
|
||||
if (uid.isNotEmpty) {
|
||||
|
||||
@ -1,4 +1,5 @@
|
||||
import 'package:flutter/cupertino.dart';
|
||||
import 'package:provider/provider.dart';
|
||||
import 'package:yumi/app_localizations.dart';
|
||||
import 'package:yumi/ui_kit/components/sc_tts.dart';
|
||||
import 'package:yumi/shared/tools/sc_loading_manager.dart';
|
||||
@ -9,6 +10,25 @@ import 'package:yumi/shared/business_logic/models/res/sc_edit_room_info_res.dart
|
||||
import 'package:yumi/shared/business_logic/models/res/my_room_res.dart';
|
||||
import 'package:yumi/shared/business_logic/models/res/sc_room_contribute_level_res.dart';
|
||||
|
||||
final SocialChatRoomManager socialChatRoomManager = SocialChatRoomManager();
|
||||
|
||||
SocialChatRoomManager resolveSocialChatRoomManager(BuildContext? context) {
|
||||
if (context != null && context.mounted) {
|
||||
try {
|
||||
final manager = Provider.of<SocialChatRoomManager?>(
|
||||
context,
|
||||
listen: false,
|
||||
);
|
||||
if (manager != null) {
|
||||
return manager;
|
||||
}
|
||||
} catch (_) {
|
||||
// A stale route context can be outside the provider tree after logout.
|
||||
}
|
||||
}
|
||||
return socialChatRoomManager;
|
||||
}
|
||||
|
||||
class SocialChatRoomManager extends ChangeNotifier {
|
||||
MyRoomRes? myRoom;
|
||||
SCRoomContributeLevelRes? roomContributeLevelRes;
|
||||
|
||||
@ -107,6 +107,7 @@ Future<bool> _isCurrentSessionStillValid(DioException e) async {
|
||||
class BaseNetworkClient {
|
||||
final Dio dio;
|
||||
static const String silentErrorToastKey = 'silentErrorToast';
|
||||
static const String suppressAuthLogoutKey = 'suppressAuthLogout';
|
||||
static const String baseUrlOverrideKey = 'baseUrlOverride';
|
||||
|
||||
BaseNetworkClient() : dio = Dio() {
|
||||
@ -292,6 +293,13 @@ class BaseNetworkClient {
|
||||
SCLoadingManager.hide();
|
||||
final bool silentErrorToast =
|
||||
e.requestOptions.extra[BaseNetworkClient.silentErrorToastKey] == true;
|
||||
final handledBusinessError = await _handleBusinessErrorResponse(
|
||||
e,
|
||||
silentErrorToast: silentErrorToast,
|
||||
);
|
||||
if (handledBusinessError != null) {
|
||||
return handledBusinessError;
|
||||
}
|
||||
switch (e.type) {
|
||||
case DioExceptionType.connectionTimeout:
|
||||
return DioException(requestOptions: e.requestOptions, error: '连接超时');
|
||||
@ -300,50 +308,10 @@ class BaseNetworkClient {
|
||||
case DioExceptionType.receiveTimeout:
|
||||
return DioException(requestOptions: e.requestOptions, error: '接收超时');
|
||||
case DioExceptionType.badResponse:
|
||||
final responseData = e.response?.data;
|
||||
final errorCode =
|
||||
responseData is Map ? responseData["errorCode"] : null;
|
||||
final errorMsg =
|
||||
responseData is Map
|
||||
? responseData["errorMsg"]
|
||||
: responseData?.toString();
|
||||
if (errorCode == SCErroCode.userNotRegistered.code) {
|
||||
//用户还没有注册
|
||||
SCTts.show("Please register an account first.");
|
||||
BuildContext? context = navigatorKey.currentContext;
|
||||
if (context != null) {
|
||||
SCNavigatorUtils.push(
|
||||
context,
|
||||
LoginRouter.editProfile,
|
||||
replace: false,
|
||||
);
|
||||
}
|
||||
} else if (errorCode == SCErroCode.authUnauthorized.code) {
|
||||
//token过期
|
||||
final shouldLogout =
|
||||
!SCNavigatorUtils.inLoginPage &&
|
||||
!await _isCurrentSessionStillValid(e);
|
||||
final BuildContext? context = navigatorKey.currentContext;
|
||||
if (context != null && context.mounted && shouldLogout) {
|
||||
AccountStorage().logout(context);
|
||||
SCNavigatorUtils.inLoginPage = true;
|
||||
}
|
||||
} else {
|
||||
if (errorMsg.toString().endsWith("balance not made")) {
|
||||
BuildContext? context = navigatorKey.currentContext;
|
||||
if (context != null) {
|
||||
SCRoomUtils.goRecharge(context);
|
||||
}
|
||||
} else {
|
||||
if (!silentErrorToast) {
|
||||
SCTts.show(errorMsg);
|
||||
}
|
||||
}
|
||||
}
|
||||
return DioException(
|
||||
requestOptions: e.requestOptions,
|
||||
response: e.response,
|
||||
error: '服务器错误: $errorCode ${errorMsg ?? ""}'.trim(),
|
||||
error: e.error ?? e.message ?? 'Server fail',
|
||||
);
|
||||
case DioExceptionType.cancel:
|
||||
return DioException(
|
||||
@ -362,6 +330,95 @@ class BaseNetworkClient {
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
Future<DioException?> _handleBusinessErrorResponse(
|
||||
DioException e, {
|
||||
required bool silentErrorToast,
|
||||
}) async {
|
||||
final responseData = e.response?.data;
|
||||
if (responseData == null) {
|
||||
return null;
|
||||
}
|
||||
|
||||
final errorCode = _readErrorCode(responseData);
|
||||
final errorMsg = _readErrorMessage(responseData);
|
||||
if (errorCode == null && errorMsg == null) {
|
||||
return null;
|
||||
}
|
||||
|
||||
if (errorCode == SCErroCode.userNotRegistered.code) {
|
||||
// 用户还没有注册:Google/Apple 登录后需要继续补充资料。
|
||||
SCTts.show("Please register an account first.");
|
||||
final BuildContext? context = navigatorKey.currentContext;
|
||||
if (context != null && context.mounted) {
|
||||
SCNavigatorUtils.push(context, LoginRouter.editProfile, replace: false);
|
||||
}
|
||||
} else if (errorCode == SCErroCode.authUnauthorized.code) {
|
||||
// token过期
|
||||
if (e.requestOptions.extra[BaseNetworkClient.suppressAuthLogoutKey] ==
|
||||
true) {
|
||||
return DioException(
|
||||
requestOptions: e.requestOptions,
|
||||
response: e.response,
|
||||
type: e.type,
|
||||
error: '服务器错误: ${errorCode ?? ""} ${errorMsg ?? ""}'.trim(),
|
||||
message: e.message,
|
||||
);
|
||||
}
|
||||
final shouldLogout =
|
||||
!SCNavigatorUtils.inLoginPage &&
|
||||
!await _isCurrentSessionStillValid(e);
|
||||
final BuildContext? context = navigatorKey.currentContext;
|
||||
if (context != null && context.mounted && shouldLogout) {
|
||||
AccountStorage().logout(context);
|
||||
SCNavigatorUtils.inLoginPage = true;
|
||||
}
|
||||
} else {
|
||||
final message = errorMsg ?? "";
|
||||
if (message.endsWith("balance not made")) {
|
||||
final BuildContext? context = navigatorKey.currentContext;
|
||||
if (context != null && context.mounted) {
|
||||
SCRoomUtils.goRecharge(context);
|
||||
}
|
||||
} else if (!silentErrorToast && message.isNotEmpty) {
|
||||
SCTts.show(message);
|
||||
}
|
||||
}
|
||||
|
||||
return DioException(
|
||||
requestOptions: e.requestOptions,
|
||||
response: e.response,
|
||||
type: e.type,
|
||||
error: '服务器错误: ${errorCode ?? ""} ${errorMsg ?? ""}'.trim(),
|
||||
message: e.message,
|
||||
);
|
||||
}
|
||||
|
||||
int? _readErrorCode(dynamic responseData) {
|
||||
if (responseData is! Map) {
|
||||
return null;
|
||||
}
|
||||
final value = responseData["errorCode"] ?? responseData["code"];
|
||||
if (value is int) {
|
||||
return value;
|
||||
}
|
||||
if (value is num) {
|
||||
return value.toInt();
|
||||
}
|
||||
if (value is String) {
|
||||
return int.tryParse(value);
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
String? _readErrorMessage(dynamic responseData) {
|
||||
if (responseData is Map) {
|
||||
return responseData["errorMsg"]?.toString() ??
|
||||
responseData["message"]?.toString();
|
||||
}
|
||||
final message = responseData?.toString().trim();
|
||||
return message == null || message.isEmpty ? null : message;
|
||||
}
|
||||
}
|
||||
|
||||
class NotSuccessException implements Exception {
|
||||
|
||||
@ -213,6 +213,10 @@ class SCAccountRepository implements SocialChatUserRepository {
|
||||
final result = await http.post(
|
||||
"58f9485b5b9f401c6a14bc1e6534122c7a085bb5f6a613094188ca56fe8bc03d",
|
||||
data: parm,
|
||||
extra: const {
|
||||
BaseNetworkClient.silentErrorToastKey: true,
|
||||
BaseNetworkClient.suppressAuthLogoutKey: true,
|
||||
},
|
||||
fromJson: (json) => {},
|
||||
);
|
||||
return result;
|
||||
@ -352,6 +356,10 @@ class SCAccountRepository implements SocialChatUserRepository {
|
||||
final result = await http.get(
|
||||
"d28c7d4eeb945fb765c8206c8f79d77f",
|
||||
queryParams: {"roomId": roomId},
|
||||
extra: const {
|
||||
BaseNetworkClient.silentErrorToastKey: true,
|
||||
BaseNetworkClient.suppressAuthLogoutKey: true,
|
||||
},
|
||||
fromJson: (json) => {},
|
||||
);
|
||||
return result;
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user