Skip to content
Snippets Groups Projects
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);