👽 Update third party login

This commit is contained in:
2025-11-30 21:38:36 +08:00
parent a7960da362
commit 27c7c8f039
3 changed files with 62 additions and 29 deletions

View File

@@ -120,7 +120,7 @@ class _CreateAccountEmailScreen extends HookConsumerWidget {
return null;
}, [isBusy]);
void performNext() {
Future<void> performNext() async {
final email = emailController.text.trim();
if (email.isEmpty) {
showErrorAlert('fieldCannotBeEmpty'.tr());
@@ -130,7 +130,18 @@ class _CreateAccountEmailScreen extends HookConsumerWidget {
showErrorAlert('fieldEmailAddressMustBeValid'.tr());
return;
}
onNext();
// Validate email availability with API
isBusy.value = true;
try {
final client = ref.watch(apiClientProvider);
await client.post('/pass/accounts/validate', data: {'email': email});
onNext();
} catch (err) {
showErrorAlert(err);
} finally {
isBusy.value = false;
}
}
return Column(
@@ -343,14 +354,25 @@ class _CreateAccountProfileScreen extends HookConsumerWidget {
return null;
}, [isBusy]);
void performNext() {
Future<void> performNext() async {
final username = usernameController.text.trim();
final nickname = nicknameController.text.trim();
if (username.isEmpty || nickname.isEmpty) {
showErrorAlert('fieldCannotBeEmpty'.tr());
return;
}
onNext();
// Validate username availability with API
isBusy.value = true;
try {
final client = ref.watch(apiClientProvider);
await client.post('/pass/accounts/validate', data: {'name': username});
onNext();
} catch (err) {
showErrorAlert(err);
} finally {
isBusy.value = false;
}
}
return Column(

View File

@@ -38,6 +38,20 @@ final Map<int, (String, String, IconData)> kFactorTypes = {
4: ('authFactorPin', 'authFactorPinDescription', Symbols.nest_secure_alarm),
};
/// Performs post-login tasks including fetching user info, subscribing to push
/// notifications, connecting websocket, and closing the login dialog.
Future<void> performPostLogin(BuildContext context, WidgetRef ref) async {
final userNotifier = ref.read(userInfoProvider.notifier);
await userNotifier.fetchUser();
final apiClient = ref.read(apiClientProvider);
subscribePushNotification(apiClient);
final wsNotifier = ref.read(websocketStateProvider.notifier);
wsNotifier.connect();
if (context.mounted && Navigator.canPop(context)) {
Navigator.pop(context, true);
}
}
class _LoginCheckScreen extends HookConsumerWidget {
final SnAuthChallenge? challenge;
final SnAuthFactor? factor;
@@ -80,14 +94,7 @@ class _LoginCheckScreen extends HookConsumerWidget {
if (!context.mounted) return;
// Do post login tasks
final userNotifier = ref.read(userInfoProvider.notifier);
userNotifier.fetchUser().then((_) {
final apiClient = ref.read(apiClientProvider);
subscribePushNotification(apiClient);
final wsNotifier = ref.read(websocketStateProvider.notifier);
wsNotifier.connect();
if (context.mounted) Navigator.pop(context, true);
});
await performPostLogin(context, ref);
}
useEffect(() {
@@ -628,17 +635,13 @@ class _LoginLookupScreen extends HookConsumerWidget {
},
);
final challenge = SnAuthChallenge.fromJson(resp.data);
onChallenge(challenge);
final factorResp = await client.get(
'/pass/auth/challenge/${challenge.id}/factors',
);
onFactor(
List<SnAuthFactor>.from(
factorResp.data.map((ele) => SnAuthFactor.fromJson(ele)),
),
);
onNext();
final token = resp.data['token'];
setToken(ref.watch(sharedPreferencesProvider), token);
ref.invalidate(tokenProvider);
if (!context.mounted) return;
// Do post login tasks
await performPostLogin(context, ref);
} catch (err) {
if (err is SignInWithAppleAuthorizationException) return;
showErrorAlert(err);