2024-01-29 15:57:22 +00:00
|
|
|
import 'dart:async';
|
|
|
|
|
2024-01-31 12:17:27 +00:00
|
|
|
import 'package:bloc_concurrency/bloc_concurrency.dart';
|
2024-01-29 15:57:22 +00:00
|
|
|
import 'package:easy_localization/easy_localization.dart';
|
|
|
|
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/service.dart';
|
|
|
|
|
|
|
|
part 'services_event.dart';
|
|
|
|
part 'services_state.dart';
|
|
|
|
|
|
|
|
class ServicesBloc extends Bloc<ServicesEvent, ServicesState> {
|
|
|
|
ServicesBloc() : super(ServicesInitial()) {
|
2024-01-31 11:04:59 +00:00
|
|
|
on<ServicesListUpdate>(
|
|
|
|
_updateList,
|
2024-01-31 12:17:27 +00:00
|
|
|
transformer: sequential(),
|
2024-01-31 11:04:59 +00:00
|
|
|
);
|
|
|
|
on<ServicesReload>(
|
|
|
|
_reload,
|
2024-01-31 12:17:27 +00:00
|
|
|
transformer: droppable(),
|
2024-01-31 11:04:59 +00:00
|
|
|
);
|
|
|
|
on<ServiceRestart>(
|
|
|
|
_restart,
|
2024-01-31 12:17:27 +00:00
|
|
|
transformer: sequential(),
|
2024-01-31 11:04:59 +00:00
|
|
|
);
|
|
|
|
on<ServiceMove>(
|
|
|
|
_move,
|
2024-01-31 12:17:27 +00:00
|
|
|
transformer: sequential(),
|
2024-01-31 11:04:59 +00:00
|
|
|
);
|
|
|
|
|
2024-01-29 15:57:22 +00:00
|
|
|
final connectionRepository = getIt<ApiConnectionRepository>();
|
|
|
|
|
|
|
|
_apiDataSubscription = connectionRepository.dataStream.listen(
|
|
|
|
(final ApiData apiData) {
|
|
|
|
add(
|
|
|
|
ServicesListUpdate([...apiData.services.data ?? []]),
|
|
|
|
);
|
|
|
|
},
|
|
|
|
);
|
|
|
|
|
|
|
|
if (connectionRepository.connectionStatus == ConnectionStatus.connected) {
|
|
|
|
add(
|
|
|
|
ServicesListUpdate(
|
|
|
|
[...connectionRepository.apiData.services.data ?? []],
|
|
|
|
),
|
|
|
|
);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
Future<void> _updateList(
|
|
|
|
final ServicesListUpdate event,
|
|
|
|
final Emitter<ServicesState> emit,
|
|
|
|
) async {
|
|
|
|
if (event.services.isEmpty) {
|
|
|
|
emit(ServicesInitial());
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
final newState = ServicesLoaded(
|
|
|
|
services: event.services,
|
|
|
|
lockedServices: state._lockedServices,
|
|
|
|
);
|
|
|
|
emit(newState);
|
|
|
|
}
|
|
|
|
|
|
|
|
Future<void> _reload(
|
|
|
|
final ServicesReload event,
|
|
|
|
final Emitter<ServicesState> emit,
|
|
|
|
) async {
|
|
|
|
final currentState = state;
|
|
|
|
if (currentState is ServicesLoaded) {
|
|
|
|
emit(ServicesReloading.fromState(currentState));
|
|
|
|
getIt<ApiConnectionRepository>().apiData.services.invalidate();
|
|
|
|
await getIt<ApiConnectionRepository>().reload(null);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
Future<void> awaitReload() async {
|
|
|
|
final currentState = state;
|
|
|
|
if (currentState is ServicesLoaded) {
|
|
|
|
getIt<ApiConnectionRepository>().apiData.services.invalidate();
|
|
|
|
await getIt<ApiConnectionRepository>().reload(null);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
Future<void> _restart(
|
|
|
|
final ServiceRestart event,
|
|
|
|
final Emitter<ServicesState> emit,
|
|
|
|
) async {
|
|
|
|
emit(
|
|
|
|
state.copyWith(
|
|
|
|
lockedServices: [
|
|
|
|
...state._lockedServices,
|
|
|
|
ServiceLock(
|
|
|
|
serviceId: event.service.id,
|
|
|
|
lockDuration: const Duration(seconds: 15),
|
|
|
|
),
|
|
|
|
],
|
|
|
|
),
|
|
|
|
);
|
|
|
|
final result = await getIt<ApiConnectionRepository>()
|
|
|
|
.api
|
|
|
|
.restartService(event.service.id);
|
|
|
|
if (!result.success) {
|
|
|
|
getIt<NavigationService>().showSnackBar('jobs.generic_error'.tr());
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
if (!result.data) {
|
|
|
|
getIt<NavigationService>()
|
|
|
|
.showSnackBar(result.message ?? 'jobs.generic_error'.tr());
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
Future<void> _move(
|
|
|
|
final ServiceMove event,
|
|
|
|
final Emitter<ServicesState> emit,
|
|
|
|
) async {
|
|
|
|
final migrationJob = await getIt<ApiConnectionRepository>()
|
|
|
|
.api
|
|
|
|
.moveService(event.service.id, event.destination);
|
|
|
|
if (!migrationJob.success) {
|
|
|
|
getIt<NavigationService>()
|
|
|
|
.showSnackBar(migrationJob.message ?? 'jobs.generic_error'.tr());
|
|
|
|
}
|
|
|
|
if (migrationJob.data != null) {
|
|
|
|
getIt<ApiConnectionRepository>()
|
|
|
|
.apiData
|
|
|
|
.serverJobs
|
|
|
|
.data
|
|
|
|
?.add(migrationJob.data!);
|
|
|
|
getIt<ApiConnectionRepository>().emitData();
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
late StreamSubscription _apiDataSubscription;
|
|
|
|
|
|
|
|
@override
|
|
|
|
void onChange(final Change<ServicesState> change) {
|
|
|
|
super.onChange(change);
|
|
|
|
}
|
|
|
|
|
|
|
|
@override
|
|
|
|
Future<void> close() {
|
|
|
|
_apiDataSubscription.cancel();
|
|
|
|
return super.close();
|
|
|
|
}
|
|
|
|
}
|