contacts_cache.dart 3.83 KiB
import 'dart:async';
import 'dart:convert';
import 'dart:html';
import 'package:flutter/foundation.dart';
import '../data/models/contact.dart';
import '../g1/api.dart';
import 'logger.dart';
class ContactsCache {
factory ContactsCache() {
_instance ??= ContactsCache._internal();
return _instance!;
}
ContactsCache._internal();
static ContactsCache? _instance;
final Map<String, List<Completer<Contact>>> _pendingRequests =
<String, List<Completer<Contact>>>{};
static Duration duration =
kReleaseMode ? const Duration(days: 3) : const Duration(hours: 5);
Future<Contact> getContact(String pubKey) async {
final String cacheKey = _key(pubKey);
Contact? cachedContact;
try {
cachedContact = _retrieveContact(pubKey);
} catch (e) {
logger('Error while retrieving contact from cache: $e, $pubKey');
}
if (cachedContact != null) {
if (!kReleaseMode) {
logger('Returning cached contact $cachedContact');
}
return cachedContact;
} else {
if (!kReleaseMode) {
logger('Contact $pubKey not cached');
}
}
if (_pendingRequests.containsKey(pubKey)) {
final Completer<Contact> completer = Completer<Contact>();
_pendingRequests[pubKey]!.add(completer);
return completer.future;
}
final Completer<Contact> completer = Completer<Contact>();
_pendingRequests[pubKey] = <Completer<Contact>>[completer];
try {
cachedContact = await getProfile(pubKey);
final String encodedValue = json.encode(<String, dynamic>{
'timestamp': DateTime.now().toIso8601String(),
'data': cachedContact.toJson(),
});
window.localStorage[cacheKey] = encodedValue;
if (!kReleaseMode) {
// logger('Returning non cached contact $contact');
}
// Send to listeners
for (final Completer<Contact> completer in _pendingRequests[pubKey]!) {
completer.complete(cachedContact);
}
_pendingRequests.remove(pubKey);