mirror of
https://git.selfprivacy.org/kherel/selfprivacy.org.app.git
synced 2024-11-08 09:53:12 +00:00
207 lines
5.6 KiB
Dart
207 lines
5.6 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:selfprivacy/config/get_it_config.dart';
|
|
import 'package:selfprivacy/logic/models/job.dart';
|
|
import 'package:selfprivacy/logic/models/json/server_job.dart';
|
|
|
|
export 'package:provider/provider.dart';
|
|
|
|
part 'client_jobs_state.dart';
|
|
|
|
class JobsCubit extends Cubit<JobsState> {
|
|
JobsCubit() : super(JobsStateEmpty()) {
|
|
final apiConnectionRepository = getIt<ApiConnectionRepository>();
|
|
_apiDataSubscription = apiConnectionRepository.dataStream.listen(
|
|
(final ApiData apiData) {
|
|
if (apiData.serverJobs.data != null &&
|
|
apiData.serverJobs.data!.isNotEmpty) {
|
|
_handleServerJobs(apiData.serverJobs.data!);
|
|
}
|
|
},
|
|
);
|
|
}
|
|
|
|
StreamSubscription? _apiDataSubscription;
|
|
|
|
void _handleServerJobs(final List<ServerJob> jobs) {
|
|
if (state is! JobsStateLoading) {
|
|
return;
|
|
}
|
|
if (state.rebuildJobUid == null) {
|
|
return;
|
|
}
|
|
// Find a job with the uid of the rebuild job
|
|
final ServerJob? rebuildJob = jobs.firstWhereOrNull(
|
|
(final job) => job.uid == state.rebuildJobUid,
|
|
);
|
|
if (rebuildJob == null ||
|
|
rebuildJob.status == JobStatusEnum.error ||
|
|
rebuildJob.status == JobStatusEnum.finished) {
|
|
emit((state as JobsStateLoading).finished());
|
|
}
|
|
}
|
|
|
|
void addJob(final ClientJob job) async {
|
|
emit(state.addJob(job));
|
|
}
|
|
|
|
void removeJob(final String id) {
|
|
final JobsState newState = (state as JobsStateWithJobs).removeById(id);
|
|
emit(newState);
|
|
}
|
|
|
|
Future<void> rebootServer() async {
|
|
if (state is JobsStateEmpty) {
|
|
emit(
|
|
JobsStateLoading(
|
|
[RebootServerJob(status: JobStatusEnum.running)],
|
|
null,
|
|
const [],
|
|
),
|
|
);
|
|
final rebootResult = await getIt<ApiConnectionRepository>().api.reboot();
|
|
if (rebootResult.success && rebootResult.data != null) {
|
|
emit(
|
|
JobsStateFinished(
|
|
[
|
|
RebootServerJob(
|
|
status: JobStatusEnum.finished,
|
|
message: rebootResult.message,
|
|
),
|
|
],
|
|
null,
|
|
const [],
|
|
),
|
|
);
|
|
} else {
|
|
emit(
|
|
JobsStateFinished(
|
|
[RebootServerJob(status: JobStatusEnum.error)],
|
|
null,
|
|
const [],
|
|
),
|
|
);
|
|
}
|
|
}
|
|
}
|
|
|
|
Future<void> upgradeServer() async {
|
|
if (state is JobsStateEmpty) {
|
|
emit(
|
|
JobsStateLoading(
|
|
[UpgradeServerJob(status: JobStatusEnum.running)],
|
|
null,
|
|
const [],
|
|
),
|
|
);
|
|
final result = await getIt<ApiConnectionRepository>().api.upgrade();
|
|
if (result.success && result.data != null) {
|
|
emit(
|
|
JobsStateLoading(
|
|
[UpgradeServerJob(status: JobStatusEnum.finished)],
|
|
result.data!.uid,
|
|
const [],
|
|
),
|
|
);
|
|
} else if (result.success) {
|
|
emit(
|
|
JobsStateFinished(
|
|
[UpgradeServerJob(status: JobStatusEnum.finished)],
|
|
null,
|
|
const [],
|
|
),
|
|
);
|
|
} else {
|
|
emit(
|
|
JobsStateFinished(
|
|
[UpgradeServerJob(status: JobStatusEnum.error)],
|
|
null,
|
|
const [],
|
|
),
|
|
);
|
|
}
|
|
}
|
|
}
|
|
|
|
Future<void> applyAll() async {
|
|
if (state is JobsStateWithJobs) {
|
|
final List<ClientJob> jobs = (state as JobsStateWithJobs).clientJobList;
|
|
emit(JobsStateLoading(jobs, null, const []));
|
|
|
|
await Future<void>.delayed(Duration.zero);
|
|
|
|
final rebuildRequired = jobs.any((final job) => job.requiresRebuild);
|
|
|
|
for (final ClientJob job in jobs) {
|
|
emit(
|
|
(state as JobsStateLoading)
|
|
.updateJobStatus(job.id, JobStatusEnum.running),
|
|
);
|
|
final (result, message) = await job.execute();
|
|
if (result) {
|
|
emit(
|
|
(state as JobsStateLoading).updateJobStatus(
|
|
job.id,
|
|
JobStatusEnum.finished,
|
|
message: message,
|
|
),
|
|
);
|
|
} else {
|
|
emit(
|
|
(state as JobsStateLoading)
|
|
.updateJobStatus(job.id, JobStatusEnum.error, message: message),
|
|
);
|
|
}
|
|
}
|
|
|
|
if (!rebuildRequired) {
|
|
emit((state as JobsStateLoading).finished());
|
|
return;
|
|
}
|
|
final rebuildResult = await getIt<ApiConnectionRepository>().api.apply();
|
|
if (rebuildResult.success) {
|
|
if (rebuildResult.data != null) {
|
|
emit(
|
|
(state as JobsStateLoading)
|
|
.copyWith(rebuildJobUid: rebuildResult.data!.uid),
|
|
);
|
|
} else {
|
|
emit((state as JobsStateLoading).finished());
|
|
}
|
|
} else {
|
|
emit((state as JobsStateLoading).finished());
|
|
}
|
|
}
|
|
}
|
|
|
|
Future<void> acknowledgeFinished() async {
|
|
if (state is! JobsStateFinished) {
|
|
return;
|
|
}
|
|
final rebuildJobUid = state.rebuildJobUid;
|
|
if ((state as JobsStateFinished).postponedJobs.isNotEmpty) {
|
|
emit(JobsStateWithJobs((state as JobsStateFinished).postponedJobs));
|
|
} else {
|
|
emit(JobsStateEmpty());
|
|
}
|
|
if (rebuildJobUid != null) {
|
|
await getIt<ApiConnectionRepository>().removeServerJob(rebuildJobUid);
|
|
}
|
|
}
|
|
|
|
@override
|
|
void onChange(final Change<JobsState> change) {
|
|
super.onChange(change);
|
|
}
|
|
|
|
@override
|
|
Future<void> close() {
|
|
_apiDataSubscription?.cancel();
|
|
return super.close();
|
|
}
|
|
}
|