Implemented settings, new scan, enhanced UI/UX
This commit is contained in:
@ -1,11 +1,10 @@
|
||||
import 'package:flutter/material.dart';
|
||||
import 'package:app_links/app_links.dart';
|
||||
import 'package:flutter_bloc/flutter_bloc.dart';
|
||||
import 'package:hl_lieferservice/feature/authentication/bloc/auth_bloc.dart';
|
||||
import 'package:hl_lieferservice/feature/authentication/bloc/auth_event.dart';
|
||||
import 'package:hl_lieferservice/widget/operations/bloc/operation_bloc.dart';
|
||||
import 'package:hl_lieferservice/widget/operations/bloc/operation_event.dart';
|
||||
import 'package:hl_lieferservice/widget/operations/presentation/operation_view_enforcer.dart';
|
||||
|
||||
import '../bloc/auth_bloc.dart';
|
||||
import 'package:url_launcher/url_launcher.dart';
|
||||
import 'dart:async';
|
||||
|
||||
class LoginPage extends StatefulWidget {
|
||||
const LoginPage({super.key});
|
||||
@ -16,27 +15,111 @@ class LoginPage extends StatefulWidget {
|
||||
|
||||
class _LoginPageState extends State<LoginPage> {
|
||||
final _loginFormKey = GlobalKey<FormState>();
|
||||
final TextEditingController _passwordEditingController =
|
||||
TextEditingController();
|
||||
final TextEditingController _userIdEditingController =
|
||||
TextEditingController();
|
||||
bool _isLoading = false;
|
||||
late AppLinks _appLinks;
|
||||
StreamSubscription<Uri>? _linkSubscription;
|
||||
|
||||
bool _isEmpty = false;
|
||||
|
||||
void onChanged(String value) {
|
||||
setState(() {
|
||||
_isEmpty = value.isEmpty;
|
||||
});
|
||||
@override
|
||||
void initState() {
|
||||
super.initState();
|
||||
_appLinks = AppLinks();
|
||||
}
|
||||
|
||||
void _onPressLogin(BuildContext context) async {
|
||||
if (context.mounted) {
|
||||
context.read<AuthBloc>().add(
|
||||
Authenticate(
|
||||
username: _userIdEditingController.text,
|
||||
password: _passwordEditingController.text,
|
||||
),
|
||||
@override
|
||||
void dispose() {
|
||||
_linkSubscription?.cancel();
|
||||
super.dispose();
|
||||
}
|
||||
|
||||
void _onPressLogin() async {
|
||||
setState(() => _isLoading = true);
|
||||
|
||||
try {
|
||||
debugPrint("🔵 Setting up deep link listener...");
|
||||
|
||||
final completer = Completer<Uri>();
|
||||
|
||||
// Listen for deep links BEFORE opening browser
|
||||
_linkSubscription = _appLinks.uriLinkStream.listen(
|
||||
(Uri uri) {
|
||||
debugPrint("🟢 Deep link received: $uri");
|
||||
if (uri.scheme == 'myapp' && !completer.isCompleted) {
|
||||
completer.complete(uri);
|
||||
}
|
||||
},
|
||||
onError: (err) {
|
||||
debugPrint("🔴 Deep link error: $err");
|
||||
if (!completer.isCompleted) {
|
||||
completer.completeError(err);
|
||||
}
|
||||
},
|
||||
);
|
||||
|
||||
// Small delay to ensure listener is ready
|
||||
await Future.delayed(const Duration(milliseconds: 500));
|
||||
|
||||
debugPrint("🔵 Opening browser to: http://localhost:3000/login");
|
||||
|
||||
final loginUrl = Uri.parse('http://192.168.1.9:3000/login');
|
||||
final launched = await launchUrl(
|
||||
loginUrl,
|
||||
mode: LaunchMode.externalApplication,
|
||||
);
|
||||
|
||||
if (!launched) {
|
||||
throw Exception('Could not launch browser');
|
||||
}
|
||||
|
||||
debugPrint("🔵 Browser opened. Waiting for callback...");
|
||||
|
||||
// Wait for the deep link callback
|
||||
final callbackUri = await completer.future.timeout(
|
||||
const Duration(minutes: 5),
|
||||
onTimeout: () {
|
||||
debugPrint("⏱️ Timeout - no callback received");
|
||||
throw TimeoutException('Login timeout');
|
||||
},
|
||||
);
|
||||
|
||||
final sessionId = callbackUri.queryParameters['session_id']!;
|
||||
|
||||
debugPrint("✅ Success! Callback: $callbackUri");
|
||||
debugPrint("✅ Session ID: $sessionId");
|
||||
|
||||
await _linkSubscription?.cancel();
|
||||
_linkSubscription = null;
|
||||
|
||||
if (mounted) {
|
||||
ScaffoldMessenger.of(context).showSnackBar(
|
||||
const SnackBar(
|
||||
content: Text('Login erfolgreich!'),
|
||||
backgroundColor: Colors.green,
|
||||
),
|
||||
);
|
||||
|
||||
context.read<AuthBloc>().add(SetAuthenticatedEvent(sessionId: sessionId));
|
||||
}
|
||||
|
||||
} on TimeoutException {
|
||||
debugPrint("❌ Timeout");
|
||||
if (mounted) {
|
||||
ScaffoldMessenger.of(context).showSnackBar(
|
||||
const SnackBar(content: Text('Login Timeout')),
|
||||
);
|
||||
}
|
||||
} catch (e) {
|
||||
debugPrint("❌ Error: $e");
|
||||
if (mounted) {
|
||||
ScaffoldMessenger.of(context).showSnackBar(
|
||||
SnackBar(content: Text('Fehler: $e')),
|
||||
);
|
||||
}
|
||||
} finally {
|
||||
await _linkSubscription?.cancel();
|
||||
_linkSubscription = null;
|
||||
if (mounted) {
|
||||
setState(() => _isLoading = false);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@ -75,38 +158,19 @@ class _LoginPageState extends State<LoginPage> {
|
||||
child: Column(
|
||||
mainAxisAlignment: MainAxisAlignment.center,
|
||||
children: [
|
||||
Padding(
|
||||
padding: const EdgeInsets.only(bottom: 20),
|
||||
child: TextFormField(
|
||||
decoration: const InputDecoration(
|
||||
labelText: "Personalnummer",
|
||||
border: OutlineInputBorder(
|
||||
borderRadius: BorderRadius.all(
|
||||
Radius.circular(10.0),
|
||||
),
|
||||
),
|
||||
),
|
||||
controller: _userIdEditingController,
|
||||
onChanged: onChanged,
|
||||
),
|
||||
),
|
||||
TextFormField(
|
||||
decoration: const InputDecoration(
|
||||
labelText: "Passwort",
|
||||
border: OutlineInputBorder(
|
||||
borderRadius: BorderRadius.all(Radius.circular(10.0)),
|
||||
),
|
||||
),
|
||||
controller: _passwordEditingController,
|
||||
obscureText: true,
|
||||
onChanged: onChanged,
|
||||
),
|
||||
Padding(
|
||||
padding: const EdgeInsets.only(top: 15, bottom: 15),
|
||||
child: OutlinedButton(
|
||||
onPressed:
|
||||
!_isEmpty ? () => _onPressLogin(context) : null,
|
||||
child: const Text("Anmelden"),
|
||||
child: _isLoading
|
||||
? const Column(
|
||||
children: [
|
||||
CircularProgressIndicator(),
|
||||
SizedBox(height: 16),
|
||||
Text('Warte auf Login...'),
|
||||
],
|
||||
)
|
||||
: OutlinedButton(
|
||||
onPressed: _onPressLogin,
|
||||
child: const Text("Anmelden mit Holzleitner Login"),
|
||||
),
|
||||
),
|
||||
],
|
||||
@ -118,4 +182,4 @@ class _LoginPageState extends State<LoginPage> {
|
||||
),
|
||||
);
|
||||
}
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user