Add toast for image fetch failures

This commit is contained in:
Janez T
2026-03-05 13:07:53 +01:00
parent 9709511e90
commit ab0c531a4b
4 changed files with 219 additions and 118 deletions

View File

@@ -0,0 +1,157 @@
import 'dart:typed_data';
import '../models/contact.dart';
import '../providers/contacts_provider.dart';
enum TransmissionTargetFailure { unknownContact, unknownRoute, tooFar }
class TransmissionTargetResolution {
final Contact? target;
final TransmissionTargetFailure? failure;
final int maxHops;
const TransmissionTargetResolution({
required this.target,
required this.failure,
required this.maxHops,
});
int get hops => target?.outPathLen ?? -1;
bool get isValid => target != null && failure == null;
}
class TransmissionTargetResolver {
const TransmissionTargetResolver._();
static Contact? resolveLocalTarget({
required ContactsProvider contactsProvider,
required bool isSentByMe,
Uint8List? recipientPublicKey,
Uint8List? senderPublicKeyPrefix,
String? senderKey6FromEnvelope,
String? senderName,
}) {
if (isSentByMe) {
final recipient = _findByRecipientKey(contactsProvider, recipientPublicKey);
if (recipient != null) return recipient;
}
final byEnvelope = _findByEnvelopeKey6(contactsProvider, senderKey6FromEnvelope);
if (byEnvelope != null) return byEnvelope;
final byPrefix = _findByPrefix(contactsProvider, senderPublicKeyPrefix);
if (byPrefix != null) return byPrefix;
return _findByName(contactsProvider, senderName);
}
static Future<TransmissionTargetResolution> resolveFetchTarget({
required ContactsProvider contactsProvider,
required Future<void> Function() refreshContacts,
required bool isSentByMe,
Uint8List? recipientPublicKey,
Uint8List? senderPublicKeyPrefix,
String? senderKey6FromEnvelope,
String? senderName,
required int maxFetchHops,
}) async {
var target = resolveLocalTarget(
contactsProvider: contactsProvider,
isSentByMe: isSentByMe,
recipientPublicKey: recipientPublicKey,
senderPublicKeyPrefix: senderPublicKeyPrefix,
senderKey6FromEnvelope: senderKey6FromEnvelope,
senderName: senderName,
);
if (target == null || target.outPathLen < 0 || target.outPathLen > maxFetchHops) {
await refreshContacts();
target = resolveLocalTarget(
contactsProvider: contactsProvider,
isSentByMe: isSentByMe,
recipientPublicKey: recipientPublicKey,
senderPublicKeyPrefix: senderPublicKeyPrefix,
senderKey6FromEnvelope: senderKey6FromEnvelope,
senderName: senderName,
);
}
if (target == null) {
return TransmissionTargetResolution(
target: null,
failure: TransmissionTargetFailure.unknownContact,
maxHops: maxFetchHops,
);
}
if (target.outPathLen < 0) {
return TransmissionTargetResolution(
target: target,
failure: TransmissionTargetFailure.unknownRoute,
maxHops: maxFetchHops,
);
}
if (target.outPathLen > maxFetchHops) {
return TransmissionTargetResolution(
target: target,
failure: TransmissionTargetFailure.tooFar,
maxHops: maxFetchHops,
);
}
return TransmissionTargetResolution(
target: target,
failure: null,
maxHops: maxFetchHops,
);
}
static Contact? _findByRecipientKey(
ContactsProvider contactsProvider,
Uint8List? recipientKey,
) {
if (recipientKey == null || recipientKey.isEmpty) return null;
final byKey = contactsProvider.findContactByKey(recipientKey);
if (byKey != null) return byKey;
if (recipientKey.length >= 6) {
return contactsProvider.findContactByPrefix(
Uint8List.fromList(recipientKey.sublist(0, 6)),
);
}
return null;
}
static Contact? _findByEnvelopeKey6(
ContactsProvider contactsProvider,
String? senderKey6FromEnvelope,
) {
if (senderKey6FromEnvelope == null || senderKey6FromEnvelope.isEmpty) {
return null;
}
return contactsProvider.findContactByPrefixHex(senderKey6FromEnvelope);
}
static Contact? _findByPrefix(
ContactsProvider contactsProvider,
Uint8List? senderPublicKeyPrefix,
) {
if (senderPublicKeyPrefix == null || senderPublicKeyPrefix.length < 6) {
return null;
}
return contactsProvider.findContactByPrefix(
Uint8List.fromList(senderPublicKeyPrefix.sublist(0, 6)),
);
}
static Contact? _findByName(
ContactsProvider contactsProvider,
String? senderName,
) {
final normalized = senderName?.trim();
if (normalized == null || normalized.isEmpty) return null;
for (final contact in contactsProvider.contacts) {
if (contact.advName.trim().toLowerCase() == normalized.toLowerCase()) {
return contact;
}
}
return null;
}
}