loadEvents method

  1. @override
Future<List<Nip01Event>> loadEvents({
  1. List<String>? ids,
  2. List<String>? pubKeys,
  3. List<int>? kinds,
  4. Map<String, List<String>>? tags,
  5. int? since,
  6. int? until,
  7. String? search,
  8. int? limit,
})
override

Load events from cache with flexible filtering
ids - list of event ids
pubKeys - list of authors pubKeys
kinds - list of kinds
tags - map of tags (e.g. {'p': 'pubkey1', 'e': 'eventid1'})
since - timestamp
until - timestamp
search - search string to match against content
limit - limit of results
returns list of events

Implementation

@override
Future<List<Nip01Event>> loadEvents({
  List<String>? ids,
  List<String>? pubKeys,
  List<int>? kinds,
  Map<String, List<String>>? tags,
  int? since,
  int? until,
  String? search,
  int? limit,
}) async {
  List<Nip01Event> result = [];
  for (var event in events.values) {
    // Filter by ids
    if (ids != null && ids.isNotEmpty && !ids.contains(event.id)) {
      continue;
    }
    // Filter by pubKeys
    if (pubKeys != null && pubKeys.isNotEmpty && !pubKeys.contains(event.pubKey)) {
      continue;
    }
    // Filter by kinds
    if (kinds != null && kinds.isNotEmpty && !kinds.contains(event.kind)) {
      continue;
    }
    // Filter by time range
    if (since != null && event.createdAt < since) {
      continue;
    }
    if (until != null && event.createdAt > until) {
      continue;
    }
    // Filter by search in content
    if (search != null && search.isNotEmpty) {
      if (!event.content.toLowerCase().contains(search.toLowerCase())) {
        continue;
      }
    }
    // Filter by tags
    if (tags != null && tags.isNotEmpty) {
      bool matchesTags = tags.entries.every((tagEntry) {
        String tagKey = tagEntry.key;
        List<String> tagValues = tagEntry.value;

        // Handle the special case where tag key starts with '#'
        if (tagKey.startsWith('#') && tagKey.length > 1) {
          tagKey = tagKey.substring(1);
        }

        final eventTagValues = event.getTags(tagKey);

        if (tagValues.isEmpty &&
            event.tags.where((e) => e[0] == tagKey).isNotEmpty) {
          return true;
        }

        return tagValues.any((value) =>
            eventTagValues.contains(value) ||
            eventTagValues.contains(value.toLowerCase()));
      });
      if (!matchesTags) {
        continue;
      }
    }

    result.add(event);
  }

  result.sort((a, b) => b.createdAt.compareTo(a.createdAt));

  if (limit != null && limit > 0 && result.length > limit) {
    result = result.take(limit).toList();
  }

  return result;
}