mirror of
https://github.com/FoggedLens/deflock-app.git
synced 2026-02-13 17:23:04 +00:00
212 lines
5.6 KiB
Dart
212 lines
5.6 KiB
Dart
import 'package:flutter/material.dart';
|
|
import 'package:latlong2/latlong.dart';
|
|
|
|
import 'models/camera_profile.dart';
|
|
import 'models/pending_upload.dart';
|
|
import 'services/offline_area_service.dart';
|
|
import 'state/auth_state.dart';
|
|
import 'state/profile_state.dart';
|
|
import 'state/session_state.dart';
|
|
import 'state/settings_state.dart';
|
|
import 'state/upload_queue_state.dart';
|
|
|
|
// Re-export types for backward compatibility
|
|
export 'state/settings_state.dart' show UploadMode;
|
|
export 'state/session_state.dart' show AddCameraSession;
|
|
|
|
// ------------------ AppState ------------------
|
|
class AppState extends ChangeNotifier {
|
|
static late AppState instance;
|
|
|
|
// State modules
|
|
late final AuthState _authState;
|
|
late final ProfileState _profileState;
|
|
late final SessionState _sessionState;
|
|
late final SettingsState _settingsState;
|
|
late final UploadQueueState _uploadQueueState;
|
|
|
|
bool _isInitialized = false;
|
|
|
|
AppState() {
|
|
instance = this;
|
|
_authState = AuthState();
|
|
_profileState = ProfileState();
|
|
_sessionState = SessionState();
|
|
_settingsState = SettingsState();
|
|
_uploadQueueState = UploadQueueState();
|
|
|
|
// Set up state change listeners
|
|
_authState.addListener(_onStateChanged);
|
|
_profileState.addListener(_onStateChanged);
|
|
_sessionState.addListener(_onStateChanged);
|
|
_settingsState.addListener(_onStateChanged);
|
|
_uploadQueueState.addListener(_onStateChanged);
|
|
|
|
_init();
|
|
}
|
|
|
|
// Getters that delegate to individual state modules
|
|
bool get isInitialized => _isInitialized;
|
|
|
|
// Auth state
|
|
bool get isLoggedIn => _authState.isLoggedIn;
|
|
String get username => _authState.username;
|
|
|
|
// Profile state
|
|
List<CameraProfile> get profiles => _profileState.profiles;
|
|
List<CameraProfile> get enabledProfiles => _profileState.enabledProfiles;
|
|
bool isEnabled(CameraProfile p) => _profileState.isEnabled(p);
|
|
|
|
// Session state
|
|
AddCameraSession? get session => _sessionState.session;
|
|
|
|
// Settings state
|
|
bool get offlineMode => _settingsState.offlineMode;
|
|
int get maxCameras => _settingsState.maxCameras;
|
|
UploadMode get uploadMode => _settingsState.uploadMode;
|
|
|
|
// Upload queue state
|
|
int get pendingCount => _uploadQueueState.pendingCount;
|
|
List<PendingUpload> get pendingUploads => _uploadQueueState.pendingUploads;
|
|
|
|
void _onStateChanged() {
|
|
notifyListeners();
|
|
}
|
|
|
|
// ---------- Init ----------
|
|
Future<void> _init() async {
|
|
// Initialize all state modules
|
|
await _settingsState.init();
|
|
await _profileState.init();
|
|
await _uploadQueueState.init();
|
|
await _authState.init(_settingsState.uploadMode);
|
|
|
|
// Initialize OfflineAreaService to ensure offline areas are loaded
|
|
await OfflineAreaService().ensureInitialized();
|
|
|
|
// Start uploader if conditions are met
|
|
_startUploader();
|
|
|
|
_isInitialized = true;
|
|
notifyListeners();
|
|
}
|
|
|
|
// ---------- Auth Methods ----------
|
|
Future<void> login() async {
|
|
await _authState.login();
|
|
}
|
|
|
|
Future<void> logout() async {
|
|
await _authState.logout();
|
|
}
|
|
|
|
Future<void> refreshAuthState() async {
|
|
await _authState.refreshAuthState();
|
|
}
|
|
|
|
Future<void> forceLogin() async {
|
|
await _authState.forceLogin();
|
|
}
|
|
|
|
Future<bool> validateToken() async {
|
|
return await _authState.validateToken();
|
|
}
|
|
|
|
// ---------- Profile Methods ----------
|
|
void toggleProfile(CameraProfile p, bool e) {
|
|
_profileState.toggleProfile(p, e);
|
|
}
|
|
|
|
void addOrUpdateProfile(CameraProfile p) {
|
|
_profileState.addOrUpdateProfile(p);
|
|
}
|
|
|
|
void deleteProfile(CameraProfile p) {
|
|
_profileState.deleteProfile(p);
|
|
}
|
|
|
|
// ---------- Session Methods ----------
|
|
void startAddSession() {
|
|
_sessionState.startAddSession(enabledProfiles);
|
|
}
|
|
|
|
void updateSession({
|
|
double? directionDeg,
|
|
CameraProfile? profile,
|
|
LatLng? target,
|
|
}) {
|
|
_sessionState.updateSession(
|
|
directionDeg: directionDeg,
|
|
profile: profile,
|
|
target: target,
|
|
);
|
|
}
|
|
|
|
void cancelSession() {
|
|
_sessionState.cancelSession();
|
|
}
|
|
|
|
void commitSession() {
|
|
final session = _sessionState.commitSession();
|
|
if (session != null) {
|
|
_uploadQueueState.addFromSession(session);
|
|
_startUploader();
|
|
}
|
|
}
|
|
|
|
// ---------- Settings Methods ----------
|
|
Future<void> setOfflineMode(bool enabled) async {
|
|
await _settingsState.setOfflineMode(enabled);
|
|
if (!enabled) {
|
|
_startUploader(); // Resume upload queue processing as we leave offline mode
|
|
} else {
|
|
_uploadQueueState.stopUploader(); // Stop uploader in offline mode
|
|
}
|
|
}
|
|
|
|
set maxCameras(int n) {
|
|
_settingsState.maxCameras = n;
|
|
}
|
|
|
|
Future<void> setUploadMode(UploadMode mode) async {
|
|
await _settingsState.setUploadMode(mode);
|
|
await _authState.onUploadModeChanged(mode);
|
|
_startUploader(); // Restart uploader with new mode
|
|
}
|
|
|
|
// ---------- Queue Methods ----------
|
|
void clearQueue() {
|
|
_uploadQueueState.clearQueue();
|
|
}
|
|
|
|
void removeFromQueue(PendingUpload upload) {
|
|
_uploadQueueState.removeFromQueue(upload);
|
|
}
|
|
|
|
void retryUpload(PendingUpload upload) {
|
|
_uploadQueueState.retryUpload(upload);
|
|
_startUploader(); // resume uploader if not busy
|
|
}
|
|
|
|
// ---------- Private Methods ----------
|
|
void _startUploader() {
|
|
_uploadQueueState.startUploader(
|
|
offlineMode: offlineMode,
|
|
uploadMode: uploadMode,
|
|
getAccessToken: _authState.getAccessToken,
|
|
);
|
|
}
|
|
|
|
@override
|
|
void dispose() {
|
|
_authState.removeListener(_onStateChanged);
|
|
_profileState.removeListener(_onStateChanged);
|
|
_sessionState.removeListener(_onStateChanged);
|
|
_settingsState.removeListener(_onStateChanged);
|
|
_uploadQueueState.removeListener(_onStateChanged);
|
|
|
|
_uploadQueueState.dispose();
|
|
super.dispose();
|
|
}
|
|
}
|