watchReleases method

Stream<List<SoftwareRelease>> watchReleases({
  1. required SoftwareAppRef app,
  2. String channel = 'main',
  3. Iterable<String>? relays,
})

Implementation

Stream<List<SoftwareRelease>> watchReleases({
  required SoftwareAppRef app,
  String channel = 'main',
  Iterable<String>? relays,
}) {
  final response = _requests.subscription(
    filter: Filter(
      authors: [app.publisher],
      kinds: const [softwareReleaseKind],
      tags: {
        '#i': [app.identifier],
        '#c': [channel],
      },
    ),
    explicitRelays: relays,
    cacheRead: true,
    cacheWrite: true,
    name: 'software-release-watch',
  );
  final byCoordinate = <String, SoftwareRelease>{};
  StreamSubscription<dynamic>? subscription;
  late final StreamController<List<SoftwareRelease>> controller;
  controller = StreamController<List<SoftwareRelease>>(
    onListen: () {
      subscription = response.stream.listen(
        (event) {
          final release = _parseRelease(event);
          if (release != null &&
              release.event.pubKey == app.publisher &&
              release.identifier == app.identifier &&
              release.channel == channel) {
            final coordinate =
                '${release.identifier}:${release.version}:${release.channel}';
            final previous = byCoordinate[coordinate];
            if (previous == null ||
                previous.event.createdAt < release.event.createdAt) {
              byCoordinate[coordinate] = release;
              final values = byCoordinate.values.toList()
                ..sort(
                  (a, b) => b.event.createdAt.compareTo(a.event.createdAt),
                );
              controller.add(values);
            }
          }
        },
        onError: controller.addError,
        onDone: controller.close,
      );
    },
    onCancel: () async {
      await subscription?.cancel();
      await _requests.closeSubscription(
        response.requestId,
        debugLabel: 'software release watcher cancelled',
      );
    },
  );
  return controller.stream;
}