import 'dart:async'; import 'package:equatable/equatable.dart'; import 'package:flutter_bloc/flutter_bloc.dart'; import 'package:selfprivacy/config/get_it_config.dart'; import 'package:selfprivacy/logic/models/server_logs.dart'; part 'server_logs_event.dart'; part 'server_logs_state.dart'; class ServerLogsBloc extends Bloc { ServerLogsBloc() : super(ServerLogsInitial()) { on((final event, final emit) async { emit(ServerLogsLoading()); try { final (logsData, meta) = await _getLogs(limit: 50); emit(ServerLogsLoaded(logsData, meta, false)); if (_apiLogsSubscription != null) { await _apiLogsSubscription?.cancel(); } _apiLogsSubscription = getIt().api.getServerLogsStream().listen( (final ServerLogEntry logEntry) { print('Got new log entry'); print(logEntry); add(ServerLogsGotNewEntry(logEntry)); }, ); } catch (e) { emit(ServerLogsError(e.toString())); } }); on((final event, final emit) async { final currentState = state; if (currentState is ServerLogsLoaded && !currentState.loadingMore && currentState.meta.upCursor != null) { try { final (logsData, meta) = await _getLogs(limit: 50, downCursor: currentState.meta.upCursor); final allEntries = currentState.entries ..addAll(logsData) ..sort((final a, final b) => b.timestamp.compareTo(a.timestamp)); emit(ServerLogsLoaded(allEntries.toSet().toList(), meta, false)); } catch (e) { emit(ServerLogsError(e.toString())); } } }); on((final event, final emit) { final currentState = state; if (currentState is ServerLogsLoaded) { final entries = currentState.entries; if (!entries.any((final entry) => entry.cursor == event.entry.cursor)) { entries.add(event.entry); entries .sort((final a, final b) => b.timestamp.compareTo(a.timestamp)); emit( ServerLogsLoaded( entries, currentState.meta, currentState.loadingMore, ), ); } } }); on((final event, final emit) { _apiLogsSubscription?.cancel(); emit(ServerLogsInitial()); }); } Future<(List, ServerLogsPageMeta)> _getLogs({ // No more than 50 required final int limit, // All entries returned will be lesser than this cursor. Sets upper bound on results. final String? upCursor, // All entries returned will be greater than this cursor. Sets lower bound on results. final String? downCursor, // Only one cursor can be set at a time. }) => getIt().api.getServerLogs( limit: limit, upCursor: upCursor, downCursor: downCursor, ); @override Future close() { _apiLogsSubscription?.cancel(); return super.close(); } @override void onChange(final Change change) { super.onChange(change); } StreamSubscription? _apiLogsSubscription; }