import 'dart:async'; import 'package:cloud_firestore/cloud_firestore.dart'; import 'package:connectivity_plus/connectivity_plus.dart'; import 'package:hive_flutter/hive_flutter.dart'; import 'package:uuid/uuid.dart'; import '../models/sync_operation.dart'; class SyncService { final FirebaseFirestore _firestore = FirebaseFirestore.instance; final Connectivity _connectivity = Connectivity(); late Box _queueBox; bool _isOnline = true; bool _isSyncing = false; final _uuid = const Uuid(); // Stream controller for sync status final _isSyncingController = StreamController.broadcast(); Stream get isSyncingStream => _isSyncingController.stream; bool get isOnline => _isOnline; Future init() async { _queueBox = await Hive.openBox('sync_queue'); // Sjekk initiell tilkobling try { final result = await _connectivity.checkConnectivity(); _updateConnectionStatus(result); } catch (e) { print('Kunne ikke sjekke tilkobling: $e'); } // Lytt etter endringer _connectivity.onConnectivityChanged.listen(_updateConnectionStatus); } void _updateConnectionStatus(ConnectivityResult result) { _isOnline = result != ConnectivityResult.none; print('Tilkoblingsstatus endret: $_isOnline ($result)'); if (_isOnline) { _processQueue(); } } // Legg til operasjon i køen Future addToQueue(SyncOperation operation) async { await _queueBox.put(operation.id, operation.toMap()); // Prøv å synkronisere umiddelbart hvis vi er online if (_isOnline) { _processQueue(); } } // Behandle køen Future _processQueue() async { if (_isSyncing || _queueBox.isEmpty) return; _isSyncing = true; _isSyncingController.add(true); try { // Hent alle operasjoner og sorter etter tidsstempel final operations = _queueBox.values .map((map) => SyncOperation.fromMap(Map.from(map))) .toList() ..sort((a, b) => a.timestamp.compareTo(b.timestamp)); for (final op in operations) { try { await _performOperation(op); await _queueBox.delete(op.id); } catch (e) { print('Feil ved synkronisering av operasjon ${op.id}: $e'); // Vi lar den ligge i køen for å prøve igjen senere // Men hvis det er en permanent feil, burde vi kanskje flytte den til en "feil-kø" } } } finally { _isSyncing = false; _isSyncingController.add(false); } } Future _performOperation(SyncOperation op) async { final collection = _firestore.collection(op.collection); final docRef = collection.doc(op.docId); switch (op.action) { case SyncAction.create: await docRef.set(op.data); break; case SyncAction.update: await docRef.update(op.data); break; case SyncAction.delete: await docRef.delete(); break; } } // Hjelpemetode for å opprette operasjon Future queueOperation({ required String collection, required String docId, required SyncAction action, required Map data, }) async { final op = SyncOperation( id: _uuid.v4(), collection: collection, docId: docId, action: action, data: data, timestamp: DateTime.now(), ); await addToQueue(op); } }