From 9157706cade92f45d5fc66fb1a44a0217787bfe2 Mon Sep 17 00:00:00 2001 From: Dmitry Date: Sat, 20 Dec 2025 22:46:11 +0300 Subject: [PATCH] stuff --- .../presentation/pages/auth/auth_page.dart | 110 +--------------- .../pages/auth/sign_in_with_telegram.dart | 117 ++++++++---------- 2 files changed, 53 insertions(+), 174 deletions(-) diff --git a/mnemo_cards_web_v2/lib/presentation/pages/auth/auth_page.dart b/mnemo_cards_web_v2/lib/presentation/pages/auth/auth_page.dart index fa50ff9..6ef052e 100644 --- a/mnemo_cards_web_v2/lib/presentation/pages/auth/auth_page.dart +++ b/mnemo_cards_web_v2/lib/presentation/pages/auth/auth_page.dart @@ -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 { bool _isLoading = false; String? _errorMessage; - Future _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( - 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.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 _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 { 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 { ), 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 { ), 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 { ), ), ], - // 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), diff --git a/mnemo_cards_web_v2/lib/presentation/pages/auth/sign_in_with_telegram.dart b/mnemo_cards_web_v2/lib/presentation/pages/auth/sign_in_with_telegram.dart index a5cfd19..359145f 100644 --- a/mnemo_cards_web_v2/lib/presentation/pages/auth/sign_in_with_telegram.dart +++ b/mnemo_cards_web_v2/lib/presentation/pages/auth/sign_in_with_telegram.dart @@ -34,17 +34,38 @@ class _SignInWithTelegramState extends State { 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 _loginWithTelegram({String? codeParam}) async { final code = codeParam ?? _telegramCodeController.text.trim(); @@ -428,29 +449,6 @@ class _SignInWithTelegramState extends State { } } - Future _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 { 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 { 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, ),