mirror of
https://github.com/dz0ny/meshcore-sar.git
synced 2026-08-15 02:10:30 +00:00
initial commit
This commit is contained in:
135
lib/providers/contacts_provider.dart
Normal file
135
lib/providers/contacts_provider.dart
Normal file
@@ -0,0 +1,135 @@
|
||||
import 'dart:async';
|
||||
import 'dart:typed_data';
|
||||
import 'package:flutter/foundation.dart';
|
||||
import '../models/contact.dart';
|
||||
import '../models/contact_telemetry.dart';
|
||||
import '../services/cayenne_lpp_parser.dart';
|
||||
|
||||
/// Contacts Provider - manages contact list and telemetry
|
||||
class ContactsProvider with ChangeNotifier {
|
||||
final Map<String, Contact> _contacts = {};
|
||||
|
||||
List<Contact> get contacts => _contacts.values.toList();
|
||||
|
||||
List<Contact> get chatContacts =>
|
||||
contacts.where((c) => c.isChat).toList()..sort(_sortByLastSeen);
|
||||
|
||||
List<Contact> get repeaters =>
|
||||
contacts.where((c) => c.isRepeater).toList()..sort(_sortByLastSeen);
|
||||
|
||||
List<Contact> get rooms =>
|
||||
contacts.where((c) => c.isRoom).toList()..sort(_sortByLastSeen);
|
||||
|
||||
/// Get contacts with location (for map display)
|
||||
List<Contact> get contactsWithLocation =>
|
||||
contacts.where((c) => c.displayLocation != null).toList();
|
||||
|
||||
/// Get chat contacts with location (team members on map)
|
||||
List<Contact> get chatContactsWithLocation =>
|
||||
chatContacts.where((c) => c.displayLocation != null).toList();
|
||||
|
||||
/// Sort contacts by last seen (most recent first)
|
||||
int _sortByLastSeen(Contact a, Contact b) {
|
||||
return b.lastSeenTime.compareTo(a.lastSeenTime);
|
||||
}
|
||||
|
||||
/// Add or update a contact
|
||||
void addOrUpdateContact(Contact contact) {
|
||||
_contacts[contact.publicKeyHex] = contact;
|
||||
notifyListeners();
|
||||
}
|
||||
|
||||
/// Add multiple contacts
|
||||
void addContacts(List<Contact> contacts) {
|
||||
for (final contact in contacts) {
|
||||
_contacts[contact.publicKeyHex] = contact;
|
||||
}
|
||||
notifyListeners();
|
||||
}
|
||||
|
||||
/// Update contact telemetry
|
||||
void updateTelemetry(Uint8List publicKeyPrefix, Uint8List lppData) {
|
||||
// Find contact by public key prefix
|
||||
final contact = _findContactByPrefix(publicKeyPrefix);
|
||||
if (contact == null) return;
|
||||
|
||||
try {
|
||||
// Parse Cayenne LPP data
|
||||
final telemetry = CayenneLppParser.parse(lppData);
|
||||
|
||||
// Update contact with new telemetry
|
||||
final updatedContact = contact.copyWith(telemetry: telemetry);
|
||||
_contacts[contact.publicKeyHex] = updatedContact;
|
||||
notifyListeners();
|
||||
} catch (e) {
|
||||
debugPrint('Failed to parse telemetry: $e');
|
||||
}
|
||||
}
|
||||
|
||||
/// Find contact by public key prefix (6 bytes)
|
||||
Contact? _findContactByPrefix(Uint8List prefix) {
|
||||
if (prefix.length < 6) return null;
|
||||
|
||||
final prefixHex = prefix
|
||||
.sublist(0, 6)
|
||||
.map((b) => b.toRadixString(16).padLeft(2, '0'))
|
||||
.join('');
|
||||
|
||||
for (final contact in contacts) {
|
||||
if (contact.publicKeyHex.startsWith(prefixHex)) {
|
||||
return contact;
|
||||
}
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
/// Find contact by public key
|
||||
Contact? findContactByKey(Uint8List publicKey) {
|
||||
final keyHex =
|
||||
publicKey.map((b) => b.toRadixString(16).padLeft(2, '0')).join('');
|
||||
return _contacts[keyHex];
|
||||
}
|
||||
|
||||
/// Find contact by name
|
||||
Contact? findContactByName(String name) {
|
||||
return contacts.firstWhere(
|
||||
(c) => c.advName == name,
|
||||
orElse: () => contacts.first,
|
||||
);
|
||||
}
|
||||
|
||||
/// Get contacts with low battery
|
||||
List<Contact> get lowBatteryContacts {
|
||||
return contacts.where((c) {
|
||||
final battery = c.displayBattery;
|
||||
return battery != null && battery < 20.0;
|
||||
}).toList();
|
||||
}
|
||||
|
||||
/// Get recently seen contacts (within last 10 minutes)
|
||||
List<Contact> get recentlySeenContacts {
|
||||
return contacts.where((c) => c.isRecentlySeen).toList();
|
||||
}
|
||||
|
||||
/// Clear all contacts
|
||||
void clearContacts() {
|
||||
_contacts.clear();
|
||||
notifyListeners();
|
||||
}
|
||||
|
||||
/// Remove a contact
|
||||
void removeContact(String publicKeyHex) {
|
||||
_contacts.remove(publicKeyHex);
|
||||
notifyListeners();
|
||||
}
|
||||
|
||||
/// Get contact count by type
|
||||
Map<String, int> get contactCounts {
|
||||
return {
|
||||
'chat': chatContacts.length,
|
||||
'repeater': repeaters.length,
|
||||
'room': rooms.length,
|
||||
'total': contacts.length,
|
||||
};
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user