Compare commits

...

4 Commits

Author SHA1 Message Date
LittleSheep
7169aff841 🚀 Launch 3.2.0+127 2025-08-18 13:28:05 +08:00
LittleSheep
fac3efb50c 💄 Add status code to userinfo alert 2025-08-18 13:19:50 +08:00
LittleSheep
e809aadaea Userinfo failed to load alert 2025-08-18 13:08:57 +08:00
LittleSheep
f33b569221 🐛 Fix realm detail 2025-08-18 11:51:44 +08:00
5 changed files with 62 additions and 4 deletions

View File

@@ -850,5 +850,9 @@
"zero": "No invitation", "zero": "No invitation",
"one": "{} available invitation", "one": "{} available invitation",
"other": "{} available invitations" "other": "{} available invitations"
} },
"failedToLoadUserInfo": "Failed to load user info",
"failedToLoadUserInfoNetwork": "It seems be network issue, you can tap the button below to try again.",
"failedToLoadUserInfoUnauthorized": "It seems your session has been logged out or not available anymore, you can still try agian to fetch the user info if you want.",
"okay": "Okay"
} }

View File

@@ -824,5 +824,9 @@
"zero": "无邀请", "zero": "无邀请",
"one": "{} 个可用邀请", "one": "{} 个可用邀请",
"other": "{} 个可用邀请" "other": "{} 个可用邀请"
} },
"failedToLoadUserInfo": "加载用户信息失败",
"failedToLoadUserInfoNetwork": "这看起来是个网络问题,你可以按下面的按钮来重试",
"failedToLoadUserInfoUnauthorized": "看来您的会话已被注销或不再可用,如果您愿意,您仍然可以再次尝试获取用户信息。",
"okay": "了解"
} }

View File

@@ -1,6 +1,11 @@
import 'dart:convert';
import 'dart:developer'; import 'dart:developer';
import 'package:dio/dio.dart';
import 'package:easy_localization/easy_localization.dart';
import 'package:firebase_analytics/firebase_analytics.dart'; import 'package:firebase_analytics/firebase_analytics.dart';
import 'package:flutter/foundation.dart';
import 'package:flutter_platform_alert/flutter_platform_alert.dart';
import 'package:flutter_riverpod/flutter_riverpod.dart'; import 'package:flutter_riverpod/flutter_riverpod.dart';
import 'package:hooks_riverpod/hooks_riverpod.dart'; import 'package:hooks_riverpod/hooks_riverpod.dart';
import 'package:island/models/account.dart'; import 'package:island/models/account.dart';
@@ -13,6 +18,11 @@ class UserInfoNotifier extends StateNotifier<AsyncValue<SnAccount?>> {
UserInfoNotifier(this._ref) : super(const AsyncValue.data(null)); UserInfoNotifier(this._ref) : super(const AsyncValue.data(null));
Future<void> fetchUser() async { Future<void> fetchUser() async {
final token = _ref.watch(tokenProvider);
if (token == null) {
log('[UserInfo] No token found, not going to fetch...');
return;
}
try { try {
final client = _ref.read(apiClientProvider); final client = _ref.read(apiClientProvider);
final response = await client.get('/id/accounts/me'); final response = await client.get('/id/accounts/me');
@@ -20,6 +30,44 @@ class UserInfoNotifier extends StateNotifier<AsyncValue<SnAccount?>> {
state = AsyncValue.data(user); state = AsyncValue.data(user);
FirebaseAnalytics.instance.setUserId(id: user.id); FirebaseAnalytics.instance.setUserId(id: user.id);
} catch (error, stackTrace) { } catch (error, stackTrace) {
if (!kIsWeb) {
if (error is DioException) {
FlutterPlatformAlert.showCustomAlert(
windowTitle: 'failedToLoadUserInfo'.tr(),
text: [
(error.response?.statusCode == 401
? 'failedToLoadUserInfoUnauthorized'
: 'failedToLoadUserInfoNetwork')
.tr()
.trim(),
'${error.response!.statusCode}\n${error.response?.headers}',
jsonEncode(error.response?.data),
].join('\n\n'),
iconStyle: IconStyle.error,
neutralButtonTitle: 'retry'.tr(),
negativeButtonTitle: 'okay'.tr(),
).then((value) {
if (value == CustomButton.neutralButton) {
fetchUser();
}
});
}
FlutterPlatformAlert.showCustomAlert(
windowTitle: 'failedToLoadUserInfo'.tr(),
text:
[
'failedToLoadUserInfoNetwork'.tr(),
error.toString(),
].join('\n\n').trim(),
iconStyle: IconStyle.error,
neutralButtonTitle: 'retry'.tr(),
negativeButtonTitle: 'okay'.tr(),
).then((value) {
if (value == CustomButton.neutralButton) {
fetchUser();
}
});
}
log( log(
"[UserInfo] Failed to fetch user info...", "[UserInfo] Failed to fetch user info...",
name: 'UserInfoNotifier', name: 'UserInfoNotifier',

View File

@@ -142,7 +142,9 @@ class RealmDetailScreen extends HookConsumerWidget {
error: (error, _) => Center(child: Text('Error: $error')), error: (error, _) => Center(child: Text('Error: $error')),
data: (rooms) { data: (rooms) {
if (rooms.isEmpty) { if (rooms.isEmpty) {
return const SliverToBoxAdapter(child: SizedBox.shrink()); return Text(
'dataEmpty',
).tr().padding(horizontal: 24, bottom: 12);
} }
return Column( return Column(
children: [ children: [

View File

@@ -16,7 +16,7 @@ publish_to: "none" # Remove this line if you wish to publish to pub.dev
# https://developer.apple.com/library/archive/documentation/General/Reference/InfoPlistKeyReference/Articles/CoreFoundationKeys.html # https://developer.apple.com/library/archive/documentation/General/Reference/InfoPlistKeyReference/Articles/CoreFoundationKeys.html
# In Windows, build-name is used as the major, minor, and patch parts # In Windows, build-name is used as the major, minor, and patch parts
# of the product and file versions while build-number is used as the build suffix. # of the product and file versions while build-number is used as the build suffix.
version: 3.2.0+126 version: 3.2.0+127
environment: environment:
sdk: ^3.7.2 sdk: ^3.7.2