stuff
This commit is contained in:
parent
1bfec9d511
commit
9157706cad
2 changed files with 53 additions and 174 deletions
|
|
@ -6,7 +6,6 @@ import 'package:yx_scope_flutter/yx_scope_flutter.dart';
|
|||
|
||||
import 'package:mnemo_cards_web_v2/di/app_scope/app_scope_container.dart';
|
||||
import 'package:mnemo_cards_web_v2/domain/config/api_config_v2.dart';
|
||||
import 'package:mnemo_cards_web_v2/presentation/pages/auth/sign_in_with_google_button.dart';
|
||||
import 'package:mnemo_cards_web_v2/presentation/pages/auth/sign_in_with_telegram.dart';
|
||||
|
||||
/// Authentication page
|
||||
|
|
@ -23,75 +22,6 @@ class _AuthPageState extends State<AuthPage> {
|
|||
bool _isLoading = false;
|
||||
String? _errorMessage;
|
||||
|
||||
Future<void> _loginWithGoogle(BuildContext context) async {
|
||||
setState(() {
|
||||
_isLoading = true;
|
||||
_errorMessage = null;
|
||||
});
|
||||
|
||||
// Get router before async operations to avoid context issues
|
||||
final router = GoRouter.of(context);
|
||||
|
||||
try {
|
||||
final appScope = ScopeProvider.of<AppScopeContainer>(
|
||||
context,
|
||||
listen: false,
|
||||
);
|
||||
|
||||
if (appScope == null) {
|
||||
throw Exception('AppScope not available');
|
||||
}
|
||||
|
||||
// Login via Google
|
||||
final user = await appScope.authService.loginWithGoogle();
|
||||
|
||||
if (!mounted) return;
|
||||
|
||||
if (user != null) {
|
||||
log('Google login successful: ${user.email}', name: 'AuthPage');
|
||||
|
||||
// Create UserScope if it doesn't exist
|
||||
if (appScope.userScopeHolder.scope == null) {
|
||||
await appScope.userScopeHolder.create();
|
||||
}
|
||||
|
||||
// Update user state and wait for it to complete
|
||||
await appScope.userScopeHolder.scope!.userStateManager.setUser(user);
|
||||
|
||||
// Notify that UserScope has changed
|
||||
appScope.notifyUserScopeChanged();
|
||||
|
||||
// Notify router about auth change
|
||||
appScope.userScopeHolder.notifyAuthChanged();
|
||||
|
||||
// Router will automatically redirect to /home when authentication state changes
|
||||
// Force router refresh to ensure redirect happens
|
||||
if (mounted) {
|
||||
// Small delay to ensure state is fully updated
|
||||
await Future<void>.delayed(const Duration(milliseconds: 50));
|
||||
if (mounted && appScope.userScopeHolder.isAuthenticated) {
|
||||
router.go('/home');
|
||||
}
|
||||
}
|
||||
} else {
|
||||
setState(() {
|
||||
_errorMessage = 'Login cancelled';
|
||||
});
|
||||
}
|
||||
} catch (e, s) {
|
||||
log('Error in Google login', error: e, stackTrace: s, name: 'AuthPage');
|
||||
if (mounted) {
|
||||
setState(() {
|
||||
_errorMessage = 'Login failed: ${e.toString()}';
|
||||
});
|
||||
}
|
||||
} finally {
|
||||
if (mounted) {
|
||||
setState(() => _isLoading = false);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Future<void> _onTelegramLoginSuccess(BuildContext context) async {
|
||||
// Router will automatically redirect to /home when authentication state changes
|
||||
// No manual navigation needed - let the GoRouter handle the redirect
|
||||
|
|
@ -115,7 +45,7 @@ class _AuthPageState extends State<AuthPage> {
|
|||
backgroundColor: theme.colorScheme.surface,
|
||||
appBar: AppBar(
|
||||
title: Text(
|
||||
'Login',
|
||||
'Вход',
|
||||
style: theme.textTheme.titleLarge?.copyWith(
|
||||
fontWeight: FontWeight.w700,
|
||||
),
|
||||
|
|
@ -149,7 +79,7 @@ class _AuthPageState extends State<AuthPage> {
|
|||
),
|
||||
const SizedBox(height: 24),
|
||||
Text(
|
||||
'Sign in to your account',
|
||||
'Войдите в свой аккаунт',
|
||||
style: theme.textTheme.headlineMedium?.copyWith(
|
||||
fontWeight: FontWeight.w700,
|
||||
color: theme.colorScheme.onSurface,
|
||||
|
|
@ -158,7 +88,7 @@ class _AuthPageState extends State<AuthPage> {
|
|||
),
|
||||
const SizedBox(height: 8),
|
||||
Text(
|
||||
'Save your progress and sync data',
|
||||
'Сохраняйте прогресс и синхронизируйте данные',
|
||||
style: theme.textTheme.bodyMedium?.copyWith(
|
||||
fontWeight: FontWeight.w700,
|
||||
color: theme.colorScheme.onSurfaceVariant,
|
||||
|
|
@ -205,40 +135,6 @@ class _AuthPageState extends State<AuthPage> {
|
|||
),
|
||||
),
|
||||
],
|
||||
// Login buttons
|
||||
// SignInWithGoogleButton(
|
||||
// onPressed: () => _loginWithGoogle(context),
|
||||
// isLoading: _isLoading,
|
||||
// ),
|
||||
// const SizedBox(height: 24),
|
||||
// Divider
|
||||
Row(
|
||||
children: [
|
||||
Expanded(
|
||||
child: Divider(
|
||||
color: theme.dividerColor,
|
||||
thickness: 1,
|
||||
),
|
||||
),
|
||||
Padding(
|
||||
padding: const EdgeInsets.symmetric(horizontal: 16),
|
||||
child: Text(
|
||||
'OR',
|
||||
style: theme.textTheme.bodySmall?.copyWith(
|
||||
fontWeight: FontWeight.w700,
|
||||
color: theme.colorScheme.onSurfaceVariant,
|
||||
),
|
||||
),
|
||||
),
|
||||
Expanded(
|
||||
child: Divider(
|
||||
color: theme.dividerColor,
|
||||
thickness: 1,
|
||||
),
|
||||
),
|
||||
],
|
||||
),
|
||||
const SizedBox(height: 24),
|
||||
// Telegram auth code input
|
||||
SignInWithTelegram(
|
||||
onLoginSuccess: () => _onTelegramLoginSuccess(context),
|
||||
|
|
|
|||
|
|
@ -34,17 +34,38 @@ class _SignInWithTelegramState extends State<SignInWithTelegram> {
|
|||
TelegramAuthCodeStatus? _webCodeStatus;
|
||||
Timer? _codeStatusTimer;
|
||||
Timer? _countdownTimer;
|
||||
Timer? _autoCheckTimer;
|
||||
DateTime? _codeExpiryTime;
|
||||
bool _autoLoginAttempted = false;
|
||||
|
||||
@override
|
||||
void initState() {
|
||||
super.initState();
|
||||
_telegramCodeController.addListener(_onCodeChanged);
|
||||
}
|
||||
|
||||
@override
|
||||
void dispose() {
|
||||
_codeStatusTimer?.cancel();
|
||||
_countdownTimer?.cancel();
|
||||
_autoCheckTimer?.cancel();
|
||||
_telegramCodeController.removeListener(_onCodeChanged);
|
||||
_telegramCodeController.dispose();
|
||||
super.dispose();
|
||||
}
|
||||
|
||||
void _onCodeChanged() {
|
||||
_autoCheckTimer?.cancel();
|
||||
final code = _telegramCodeController.text.trim();
|
||||
if (code.length > 4) {
|
||||
_autoCheckTimer = Timer(const Duration(seconds: 1), () {
|
||||
if (mounted && _telegramCodeController.text.trim().length > 4) {
|
||||
_loginWithTelegram();
|
||||
}
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
Future<void> _loginWithTelegram({String? codeParam}) async {
|
||||
final code = codeParam ?? _telegramCodeController.text.trim();
|
||||
|
||||
|
|
@ -428,29 +449,6 @@ class _SignInWithTelegramState extends State<SignInWithTelegram> {
|
|||
}
|
||||
}
|
||||
|
||||
Future<void> _openTelegramBot() async {
|
||||
final deepLink = Uri.parse(ApiConfigV2.telegramBotDeepLinkBase);
|
||||
|
||||
try {
|
||||
final launched = await launchUrl(
|
||||
deepLink,
|
||||
mode: LaunchMode.externalApplication,
|
||||
);
|
||||
if (!launched) {
|
||||
throw Exception('Could not launch Telegram');
|
||||
}
|
||||
} catch (e, s) {
|
||||
log(
|
||||
'Error opening Telegram bot',
|
||||
error: e,
|
||||
stackTrace: s,
|
||||
name: 'SignInWithTelegram',
|
||||
);
|
||||
widget.onError(
|
||||
'Не удалось открыть Telegram. Попробуйте вручную: ${deepLink.toString()}',
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
|
|
@ -460,12 +458,29 @@ class _SignInWithTelegramState extends State<SignInWithTelegram> {
|
|||
crossAxisAlignment: CrossAxisAlignment.start,
|
||||
children: [
|
||||
Text(
|
||||
'Введите код из Telegram бота',
|
||||
'Два способа входа:',
|
||||
style: theme.textTheme.titleMedium?.copyWith(
|
||||
fontWeight: FontWeight.w700,
|
||||
color: theme.colorScheme.onSurface,
|
||||
),
|
||||
),
|
||||
const SizedBox(height: 16),
|
||||
// Вариант 1: Ввод кода вручную
|
||||
Text(
|
||||
'Вариант 1: Введите код вручную',
|
||||
style: theme.textTheme.bodyLarge?.copyWith(
|
||||
fontWeight: FontWeight.w700,
|
||||
color: theme.colorScheme.onSurface,
|
||||
),
|
||||
),
|
||||
const SizedBox(height: 8),
|
||||
Text(
|
||||
'Код будет проверен автоматически при длине более 4 символов',
|
||||
style: theme.textTheme.bodySmall?.copyWith(
|
||||
fontWeight: FontWeight.w500,
|
||||
color: theme.colorScheme.onSurfaceVariant,
|
||||
),
|
||||
),
|
||||
const SizedBox(height: 12),
|
||||
TextField(
|
||||
controller: _telegramCodeController,
|
||||
|
|
@ -500,60 +515,28 @@ class _SignInWithTelegramState extends State<SignInWithTelegram> {
|
|||
maxLength: 6,
|
||||
onSubmitted: (_) => _loginWithTelegram(),
|
||||
),
|
||||
const SizedBox(height: 16),
|
||||
Row(
|
||||
children: [
|
||||
Expanded(
|
||||
child: ElevatedButton.icon(
|
||||
onPressed: widget.isLoading ? null : _generateTelegramCode,
|
||||
icon: const Icon(Icons.bolt, size: 20),
|
||||
label: Text(
|
||||
widget.isLoading ? 'Создание...' : 'Получить код',
|
||||
style: theme.textTheme.labelLarge?.copyWith(
|
||||
fontWeight: FontWeight.w700,
|
||||
),
|
||||
),
|
||||
style: ElevatedButton.styleFrom(
|
||||
shape: RoundedRectangleBorder(
|
||||
borderRadius: BorderRadius.circular(12),
|
||||
),
|
||||
),
|
||||
),
|
||||
),
|
||||
const SizedBox(width: 12),
|
||||
Expanded(
|
||||
child: OutlinedButton.icon(
|
||||
onPressed: widget.isLoading ? null : _openTelegramBot,
|
||||
icon: const Icon(Icons.telegram, size: 20),
|
||||
label: Text(
|
||||
'Открыть бота',
|
||||
style: theme.textTheme.labelLarge?.copyWith(
|
||||
fontWeight: FontWeight.w700,
|
||||
),
|
||||
),
|
||||
style: OutlinedButton.styleFrom(
|
||||
shape: RoundedRectangleBorder(
|
||||
borderRadius: BorderRadius.circular(12),
|
||||
),
|
||||
side: BorderSide(color: theme.dividerColor, width: 1),
|
||||
),
|
||||
),
|
||||
),
|
||||
],
|
||||
),
|
||||
if (_webCodeStatus != null) ...[
|
||||
const SizedBox(height: 16),
|
||||
_buildTelegramStatusCard(),
|
||||
],
|
||||
const SizedBox(height: 24),
|
||||
// Вариант 2: Кнопка входа
|
||||
Text(
|
||||
'Вариант 2: Нажмите кнопку для автоматической генерации кода',
|
||||
style: theme.textTheme.bodyLarge?.copyWith(
|
||||
fontWeight: FontWeight.w700,
|
||||
color: theme.colorScheme.onSurface,
|
||||
),
|
||||
),
|
||||
const SizedBox(height: 12),
|
||||
SizedBox(
|
||||
width: double.infinity,
|
||||
height: 56,
|
||||
child: ElevatedButton.icon(
|
||||
onPressed: widget.isLoading ? null : _loginWithTelegram,
|
||||
onPressed: widget.isLoading ? null : _generateTelegramCode,
|
||||
icon: const Icon(Icons.telegram, size: 24),
|
||||
label: Text(
|
||||
'Войти с кодом Telegram',
|
||||
'Войти через телеграм',
|
||||
style: theme.textTheme.labelLarge?.copyWith(
|
||||
fontWeight: FontWeight.w700,
|
||||
),
|
||||
|
|
|
|||
Loading…
Reference in a new issue