import 'package:sepot/models/identity.dart'; /// Kontakt — osoba, se kterou můžeme chatovat /// /// Odpovídá Rust: Contact class Contact { String displayName; final PublicIdentity publicIdentity; final DateTime addedAt; bool verified; String? notes; /// Blokovaný kontakt: příchozí zprávy se zahodí (ACKnou, ale neuloží ani /// nezobrazí) a odesílání je v UI zablokované. bool blocked; Contact({ required this.displayName, required this.publicIdentity, required this.addedAt, this.verified = false, this.notes, this.blocked = false, }); /// ID kontaktu = fingerprint identity klíče (identita = klíč). /// /// Dřív náhodné UUID — vznikly tím DVĚ klíčové soustavy (konverzace se /// ukládaly pod UUID, UI ale routovalo fingerprintem), takže konverzace /// otevřená z kontaktů neuměla odeslat zprávu a chat list nenašel jméno. /// Bez datové migrace (žádná produkční data; testovací zařízení se /// re-párují — stejný precedens jako S9). String get id => publicIdentity.id; /// Vytvoř nový kontakt z veřejné identity factory Contact.fromPublicIdentity( PublicIdentity identity, { bool verified = false, }) { return Contact( displayName: identity.displayName, publicIdentity: identity, addedAt: DateTime.now(), verified: verified, ); } /// Šepot ID kontaktu String get sepotId => publicIdentity.sepotId; /// Otisk kontaktu (plné Crockford base32 zobrazení) String get fingerprint => publicIdentity.fingerprint.display; Map toJson() => { 'displayName': displayName, 'publicIdentity': publicIdentity.toJson(), 'addedAt': addedAt.toIso8601String(), 'verified': verified, 'notes': notes, 'blocked': blocked, }; factory Contact.fromJson(Map json) { return Contact( displayName: json['displayName'] as String, publicIdentity: PublicIdentity.fromJson( json['publicIdentity'] as Map, ), addedAt: DateTime.parse(json['addedAt'] as String), verified: json['verified'] as bool? ?? false, notes: json['notes'] as String?, blocked: json['blocked'] as bool? ?? false, ); } }