mirror of
https://git.selfprivacy.org/kherel/selfprivacy.org.app.git
synced 2024-11-11 03:03:18 +00:00
158 lines
4.9 KiB
Dart
158 lines
4.9 KiB
Dart
import 'dart:async';
|
|
|
|
import 'package:collection/collection.dart';
|
|
import 'package:easy_localization/easy_localization.dart';
|
|
import 'package:equatable/equatable.dart';
|
|
import 'package:flutter_bloc/flutter_bloc.dart';
|
|
import 'package:pub_semver/pub_semver.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<ServerLogsEvent, ServerLogsState> {
|
|
ServerLogsBloc() : super(ServerLogsInitial()) {
|
|
on<ServerLogsFetch>((final event, final emit) async {
|
|
emit(ServerLogsLoading());
|
|
final String? slice = event.serviceId != null
|
|
? '${event.serviceId?.replaceAll('-', '_')}.slice'
|
|
: null;
|
|
try {
|
|
final (logsData, meta) = await _getLogs(limit: 50, slice: slice);
|
|
emit(
|
|
ServerLogsLoaded(
|
|
oldEntries: logsData.sorted(
|
|
(final a, final b) => b.timestamp.compareTo(a.timestamp),
|
|
),
|
|
newEntries: List<ServerLogEntry>.empty(growable: true),
|
|
meta: meta,
|
|
loadingMore: false,
|
|
slice: slice,
|
|
),
|
|
);
|
|
if (_apiLogsSubscription != null) {
|
|
await _apiLogsSubscription?.cancel();
|
|
}
|
|
_apiLogsSubscription =
|
|
getIt<ApiConnectionRepository>().api.getServerLogsStream().listen(
|
|
(final ServerLogEntry logEntry) {
|
|
print('Got new log entry');
|
|
print(logEntry);
|
|
add(ServerLogsGotNewEntry(logEntry));
|
|
},
|
|
);
|
|
} catch (e) {
|
|
emit(ServerLogsError(e.toString()));
|
|
}
|
|
});
|
|
|
|
on<ServerLogsFetchMore>((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,
|
|
slice: currentState.slice,
|
|
);
|
|
final allEntries = currentState.oldEntries
|
|
..addAll(logsData)
|
|
..sort((final a, final b) => b.timestamp.compareTo(a.timestamp));
|
|
emit(
|
|
ServerLogsLoaded(
|
|
oldEntries: allEntries.toSet().toList(),
|
|
newEntries: currentState.newEntries,
|
|
meta: meta,
|
|
loadingMore: false,
|
|
slice: currentState.slice,
|
|
),
|
|
);
|
|
} catch (e) {
|
|
emit(ServerLogsError(e.toString()));
|
|
}
|
|
}
|
|
});
|
|
|
|
on<ServerLogsGotNewEntry>((final event, final emit) {
|
|
final currentState = state;
|
|
if (currentState is ServerLogsLoaded) {
|
|
if (currentState.slice != null &&
|
|
event.entry.systemdSlice != currentState.slice) {
|
|
return;
|
|
}
|
|
final allEntries = currentState.newEntries
|
|
..add(event.entry)
|
|
..sort(
|
|
(final a, final b) => b.timestamp.compareTo(a.timestamp),
|
|
);
|
|
emit(
|
|
ServerLogsLoaded(
|
|
oldEntries: currentState.oldEntries,
|
|
newEntries: allEntries.toSet().toList(),
|
|
meta: currentState.meta,
|
|
loadingMore: currentState.loadingMore,
|
|
slice: currentState.slice,
|
|
),
|
|
);
|
|
}
|
|
});
|
|
|
|
on<ServerLogsDisconnect>((final event, final emit) {
|
|
_apiLogsSubscription?.cancel();
|
|
emit(ServerLogsInitial());
|
|
});
|
|
}
|
|
|
|
static const String logsSupportedVersion = '>=3.3.0';
|
|
|
|
Future<(List<ServerLogEntry>, 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.
|
|
final String? slice,
|
|
}) {
|
|
final String? apiVersion =
|
|
getIt<ApiConnectionRepository>().apiData.apiVersion.data;
|
|
if (apiVersion == null) {
|
|
throw Exception('basis.network_error'.tr());
|
|
}
|
|
if (!VersionConstraint.parse(logsSupportedVersion)
|
|
.allows(Version.parse(apiVersion))) {
|
|
throw Exception(
|
|
'basis.feature_unsupported_on_api_version'.tr(
|
|
namedArgs: {
|
|
'versionConstraint': logsSupportedVersion,
|
|
'currentVersion': apiVersion,
|
|
},
|
|
),
|
|
);
|
|
}
|
|
return getIt<ApiConnectionRepository>().api.getServerLogs(
|
|
limit: limit,
|
|
upCursor: upCursor,
|
|
downCursor: downCursor,
|
|
slice: slice,
|
|
);
|
|
}
|
|
|
|
@override
|
|
Future<void> close() {
|
|
_apiLogsSubscription?.cancel();
|
|
return super.close();
|
|
}
|
|
|
|
@override
|
|
void onChange(final Change<ServerLogsState> change) {
|
|
super.onChange(change);
|
|
}
|
|
|
|
StreamSubscription? _apiLogsSubscription;
|
|
}
|