Update lot features

This commit is contained in:
2026-05-28 16:29:23 +07:00
parent 6272ece15d
commit 1110e5a42d
81 changed files with 4306 additions and 29813 deletions
@@ -3,9 +3,15 @@
import 'package:flutter/material.dart';
import 'package:go_router/go_router.dart';
import '../../app/router.dart';
import '../../app/injection_container.dart';
import '../../core/constants/app_constants.dart';
import '../../core/errors/friendly_error.dart';
import '../../core/network/api_client.dart';
import '../../core/services/fcm_service.dart';
import '../../core/services/incoming_call_polling_service.dart';
import '../../core/services/offline_queue_service.dart';
import '../../core/services/websocket_service.dart';
import '../../core/storage/secure_storage.dart';
// ---------------------------------------------------------------------------
@@ -40,7 +46,9 @@ class _SplashScreenState extends State<SplashScreen>
void initState() {
super.initState();
_animCtrl = AnimationController(
vsync: this, duration: const Duration(milliseconds: 700));
vsync: this,
duration: const Duration(milliseconds: 700),
);
_fadeAnim = CurvedAnimation(parent: _animCtrl, curve: Curves.easeIn);
_animCtrl.forward();
_route();
@@ -59,10 +67,12 @@ class _SplashScreenState extends State<SplashScreen>
await Future.delayed(const Duration(milliseconds: 500));
final storage = sl<SecureStorage>();
final token =
await storage.getAccessToken().timeout(const Duration(seconds: 3));
final role =
await storage.getUserRole().timeout(const Duration(seconds: 3));
final token = await storage.getAccessToken().timeout(
const Duration(seconds: 3),
);
final role = await storage.getUserRole().timeout(
const Duration(seconds: 3),
);
if (!mounted) return;
@@ -71,11 +81,16 @@ class _SplashScreenState extends State<SplashScreen>
return;
}
sl<IncomingCallPollingService>().start();
final serverUrl = await AppConstants.getServerUrl();
if (serverUrl != null && serverUrl.isNotEmpty) {
_startAutoLoginServices(serverUrl);
} else {
sl<IncomingCallPollingService>().start();
}
// Auto-login: arahkan ke home sesuai role.
context.go(role == 'ROLE_GUARDIAN'
? '/guardian/dashboard'
: '/user/walkguide');
context.go(
role == 'ROLE_GUARDIAN' ? '/guardian/dashboard' : '/user/walkguide',
);
},
onError: (_) {},
fallback: 'Sesi belum bisa dipulihkan.',
@@ -120,10 +135,7 @@ class _SplashScreenState extends State<SplashScreen>
const SizedBox(height: 6),
const Text(
'AI-powered navigation for everyone',
style: TextStyle(
color: Colors.white70,
fontSize: 13,
),
style: TextStyle(color: Colors.white70, fontSize: 13),
),
const SizedBox(height: 48),
const SizedBox(
@@ -141,3 +153,23 @@ class _SplashScreenState extends State<SplashScreen>
);
}
}
void _startAutoLoginServices(String serverUrl) {
Future.microtask(() async {
sl<IncomingCallPollingService>().start();
await sl<ApiClient>().init(serverUrl);
await sl<FcmService>().init().timeout(const Duration(seconds: 4));
final ws = sl<WebSocketService>();
await ws.connect(serverUrl).timeout(const Duration(seconds: 2));
ws.subscribeCall((data) {
if (data['type']?.toString() == 'INCOMING_CALL') {
appRouter.go('/incoming-call', extra: data);
}
});
await sl<OfflineQueueService>()
.syncPending(sl<ApiClient>())
.timeout(const Duration(seconds: 3));
}).catchError((Object e) {
debugPrint('Auto-login services skipped: $e');
});
}