From 503c8d37eafaef74b53a52f1f291124921a7212e Mon Sep 17 00:00:00 2001 From: NaiJi Date: Tue, 30 Aug 2022 06:09:09 +0300 Subject: [PATCH] Implement server jobs cubit --- lib/config/bloc_config.dart | 7 ++- .../client_jobs_cubit.dart} | 56 ++++------------- .../cubit/client_jobs/client_jobs_state.dart | 26 ++++++++ .../cubit/forms/user/ssh_form_cubit.dart | 2 +- .../cubit/forms/user/user_form_cubit.dart | 2 +- lib/logic/cubit/jobs/jobs_state.dart | 34 ----------- .../cubit/server_jobs/server_jobs_cubit.dart | 61 +++++++++++++++++++ .../cubit/server_jobs/server_jobs_state.dart | 16 +++++ .../components/jobs_content/jobs_content.dart | 13 ++-- .../pre_styled_buttons/flash_fab.dart | 2 +- .../pre_styled_buttons.dart | 2 +- lib/ui/pages/services/services.dart | 9 +-- lib/ui/pages/ssh_keys/ssh_keys.dart | 2 +- lib/ui/pages/users/users.dart | 2 +- 14 files changed, 136 insertions(+), 98 deletions(-) rename lib/logic/cubit/{jobs/jobs_cubit.dart => client_jobs/client_jobs_cubit.dart} (73%) create mode 100644 lib/logic/cubit/client_jobs/client_jobs_state.dart delete mode 100644 lib/logic/cubit/jobs/jobs_state.dart create mode 100644 lib/logic/cubit/server_jobs/server_jobs_cubit.dart create mode 100644 lib/logic/cubit/server_jobs/server_jobs_state.dart diff --git a/lib/config/bloc_config.dart b/lib/config/bloc_config.dart index 0b4fe048..fd00db2b 100644 --- a/lib/config/bloc_config.dart +++ b/lib/config/bloc_config.dart @@ -6,8 +6,9 @@ import 'package:selfprivacy/logic/cubit/server_installation/server_installation_ import 'package:selfprivacy/logic/cubit/app_settings/app_settings_cubit.dart'; import 'package:selfprivacy/logic/cubit/backups/backups_cubit.dart'; import 'package:selfprivacy/logic/cubit/dns_records/dns_records_cubit.dart'; -import 'package:selfprivacy/logic/cubit/jobs/jobs_cubit.dart'; +import 'package:selfprivacy/logic/cubit/client_jobs/client_jobs_cubit.dart'; import 'package:selfprivacy/logic/cubit/providers/providers_cubit.dart'; +import 'package:selfprivacy/logic/cubit/server_jobs/server_jobs_cubit.dart'; import 'package:selfprivacy/logic/cubit/server_volumes/server_volume_cubit.dart'; import 'package:selfprivacy/logic/cubit/services/services_cubit.dart'; import 'package:selfprivacy/logic/cubit/users/users_cubit.dart'; @@ -30,6 +31,7 @@ class BlocAndProviderConfig extends StatelessWidget { final apiDevicesCubit = ApiDevicesCubit(serverInstallationCubit); final apiVolumesCubit = ApiProviderVolumeCubit(serverInstallationCubit); final apiServerVolumesCubit = ApiServerVolumeCubit(serverInstallationCubit); + final serverJobsCubit = ServerJobsCubit(serverInstallationCubit); return MultiProvider( providers: [ @@ -73,6 +75,9 @@ class BlocAndProviderConfig extends StatelessWidget { BlocProvider( create: (final _) => apiServerVolumesCubit..load(), ), + BlocProvider( + create: (final _) => serverJobsCubit..load(), + ), BlocProvider( create: (final _) => JobsCubit( usersCubit: usersCubit, diff --git a/lib/logic/cubit/jobs/jobs_cubit.dart b/lib/logic/cubit/client_jobs/client_jobs_cubit.dart similarity index 73% rename from lib/logic/cubit/jobs/jobs_cubit.dart rename to lib/logic/cubit/client_jobs/client_jobs_cubit.dart index 4457fba5..7461a6df 100644 --- a/lib/logic/cubit/jobs/jobs_cubit.dart +++ b/lib/logic/cubit/client_jobs/client_jobs_cubit.dart @@ -8,17 +8,16 @@ import 'package:selfprivacy/logic/api_maps/graphql_maps/server_api/server.dart'; import 'package:selfprivacy/logic/cubit/services/services_cubit.dart'; import 'package:selfprivacy/logic/cubit/users/users_cubit.dart'; import 'package:selfprivacy/logic/models/job.dart'; -import 'package:selfprivacy/logic/models/json/server_job.dart'; export 'package:provider/provider.dart'; -part 'jobs_state.dart'; +part 'client_jobs_state.dart'; class JobsCubit extends Cubit { JobsCubit({ required this.usersCubit, required this.servicesCubit, - }) : super(const JobsStateEmpty([])); + }) : super(JobsStateEmpty()); final ServerApi api = ServerApi(); final UsersCubit usersCubit; @@ -32,7 +31,7 @@ class JobsCubit extends Cubit { } newJobsList.add(job); getIt().showSnackBar('jobs.jobAdded'.tr()); - emit(JobsStateWithJobs(newJobsList, state.serverJobList)); + emit(JobsStateWithJobs(newJobsList)); } void removeJob(final String id) { @@ -55,7 +54,7 @@ class JobsCubit extends Cubit { } else { newJobsList.add(job); getIt().showSnackBar('jobs.jobAdded'.tr()); - emit(JobsStateWithJobs(newJobsList, state.serverJobList)); + emit(JobsStateWithJobs(newJobsList)); } } @@ -69,23 +68,23 @@ class JobsCubit extends Cubit { if (!isExistInJobList) { newJobsList.add(job); getIt().showSnackBar('jobs.jobAdded'.tr()); - emit(JobsStateWithJobs(newJobsList, state.serverJobList)); + emit(JobsStateWithJobs(newJobsList)); } } Future rebootServer() async { - emit(JobsStateLoading(state.serverJobList)); + emit(JobsStateLoading()); final bool isSuccessful = await api.reboot(); if (isSuccessful) { getIt().showSnackBar('jobs.rebootSuccess'.tr()); } else { getIt().showSnackBar('jobs.rebootFailed'.tr()); } - emit(JobsStateEmpty(state.serverJobList)); + emit(JobsStateEmpty()); } Future upgradeServer() async { - emit(JobsStateLoading(state.serverJobList)); + emit(JobsStateLoading()); final bool isPullSuccessful = await api.pullConfigurationUpdate(); final bool isSuccessful = await api.upgrade(); if (isSuccessful) { @@ -97,13 +96,13 @@ class JobsCubit extends Cubit { } else { getIt().showSnackBar('jobs.upgradeFailed'.tr()); } - emit(JobsStateEmpty(state.serverJobList)); + emit(JobsStateEmpty()); } Future applyAll() async { if (state is JobsStateWithJobs) { final List jobs = (state as JobsStateWithJobs).clientJobList; - emit(JobsStateLoading(state.serverJobList)); + emit(JobsStateLoading()); bool hasServiceJobs = false; for (final ClientJob job in jobs) { if (job is CreateUserJob) { @@ -131,40 +130,7 @@ class JobsCubit extends Cubit { await servicesCubit.load(); } - emit(JobsStateEmpty(state.serverJobList)); + emit(JobsStateEmpty()); } } - - Future resetRequestsTimer() async { - const duration = Duration(seconds: 1); - Timer.periodic( - duration, - (final timer) async { - if (timer.tick >= 10) { - final List serverJobs = await api.getServerJobs(); - final List newServerJobs = []; - for (final ServerJob job in serverJobs) { - if (job.status == 'FINISHED') { - await api.removeApiJob(job.uid); - } else { - newServerJobs.add(job); - } - } - - if (state is JobsStateWithJobs) { - emit( - JobsStateWithJobs( - (state as JobsStateWithJobs).clientJobList, - newServerJobs, - ), - ); - } else { - emit( - JobsStateEmpty(newServerJobs), - ); - } - } - }, - ); - } } diff --git a/lib/logic/cubit/client_jobs/client_jobs_state.dart b/lib/logic/cubit/client_jobs/client_jobs_state.dart new file mode 100644 index 00000000..2bb31856 --- /dev/null +++ b/lib/logic/cubit/client_jobs/client_jobs_state.dart @@ -0,0 +1,26 @@ +part of 'client_jobs_cubit.dart'; + +abstract class JobsState extends Equatable { + @override + List get props => []; +} + +class JobsStateLoading extends JobsState {} + +class JobsStateEmpty extends JobsState {} + +class JobsStateWithJobs extends JobsState { + JobsStateWithJobs(this.clientJobList); + final List clientJobList; + JobsState removeById(final String id) { + final List newJobsList = + clientJobList.where((final element) => element.id != id).toList(); + if (newJobsList.isEmpty) { + return JobsStateEmpty(); + } + return JobsStateWithJobs(newJobsList); + } + + @override + List get props => clientJobList; +} diff --git a/lib/logic/cubit/forms/user/ssh_form_cubit.dart b/lib/logic/cubit/forms/user/ssh_form_cubit.dart index b6493ee7..ba992af0 100644 --- a/lib/logic/cubit/forms/user/ssh_form_cubit.dart +++ b/lib/logic/cubit/forms/user/ssh_form_cubit.dart @@ -2,7 +2,7 @@ import 'dart:async'; import 'package:cubit_form/cubit_form.dart'; import 'package:easy_localization/easy_localization.dart'; -import 'package:selfprivacy/logic/cubit/jobs/jobs_cubit.dart'; +import 'package:selfprivacy/logic/cubit/client_jobs/client_jobs_cubit.dart'; import 'package:selfprivacy/logic/models/job.dart'; import 'package:selfprivacy/logic/models/hive/user.dart'; diff --git a/lib/logic/cubit/forms/user/user_form_cubit.dart b/lib/logic/cubit/forms/user/user_form_cubit.dart index a385befb..92f66f15 100644 --- a/lib/logic/cubit/forms/user/user_form_cubit.dart +++ b/lib/logic/cubit/forms/user/user_form_cubit.dart @@ -2,7 +2,7 @@ import 'dart:async'; import 'package:cubit_form/cubit_form.dart'; import 'package:selfprivacy/logic/cubit/forms/factories/field_cubit_factory.dart'; -import 'package:selfprivacy/logic/cubit/jobs/jobs_cubit.dart'; +import 'package:selfprivacy/logic/cubit/client_jobs/client_jobs_cubit.dart'; import 'package:selfprivacy/logic/models/job.dart'; import 'package:selfprivacy/logic/models/hive/user.dart'; import 'package:selfprivacy/utils/password_generator.dart'; diff --git a/lib/logic/cubit/jobs/jobs_state.dart b/lib/logic/cubit/jobs/jobs_state.dart deleted file mode 100644 index 3737cb5d..00000000 --- a/lib/logic/cubit/jobs/jobs_state.dart +++ /dev/null @@ -1,34 +0,0 @@ -part of 'jobs_cubit.dart'; - -abstract class JobsState extends Equatable { - const JobsState(this.serverJobList); - final List serverJobList; - @override - List get props => [serverJobList]; -} - -class JobsStateLoading extends JobsState { - const JobsStateLoading(super.serverJobList); -} - -class JobsStateEmpty extends JobsState { - const JobsStateEmpty(super.serverJobList); -} - -class JobsStateWithJobs extends JobsState { - const JobsStateWithJobs(this.clientJobList, super.serverJobList); - final List clientJobList; - - JobsState removeById(final String id) { - final List newJobsList = - clientJobList.where((final element) => element.id != id).toList(); - - if (newJobsList.isEmpty) { - return JobsStateEmpty(serverJobList); - } - return JobsStateWithJobs(newJobsList, serverJobList); - } - - @override - List get props => [...super.props, clientJobList]; -} diff --git a/lib/logic/cubit/server_jobs/server_jobs_cubit.dart b/lib/logic/cubit/server_jobs/server_jobs_cubit.dart new file mode 100644 index 00000000..254e6380 --- /dev/null +++ b/lib/logic/cubit/server_jobs/server_jobs_cubit.dart @@ -0,0 +1,61 @@ +import 'dart:async'; + +import 'package:selfprivacy/logic/api_maps/graphql_maps/server_api/server.dart'; +import 'package:selfprivacy/logic/cubit/app_config_dependent/authentication_dependend_cubit.dart'; +import 'package:selfprivacy/logic/models/json/server_job.dart'; + +export 'package:provider/provider.dart'; + +part 'server_jobs_state.dart'; + +class ServerJobsCubit + extends ServerInstallationDependendCubit { + ServerJobsCubit(final ServerInstallationCubit serverInstallationCubit) + : super( + serverInstallationCubit, + const ServerJobsState( + serverJobList: [], + ), + ); + + Timer? timer; + final ServerApi api = ServerApi(); + + @override + void clear() async { + emit( + const ServerJobsState( + serverJobList: [], + ), + ); + if (timer != null && timer!.isActive) { + timer!.cancel(); + timer = null; + } + } + + @override + void load() async { + if (serverInstallationCubit.state is ServerInstallationFinished) { + final List jobs = await api.getServerJobs(); + emit( + ServerJobsState( + serverJobList: jobs, + ), + ); + timer = Timer(const Duration(seconds: 10), () => reload(useTimer: true)); + } + } + + Future reload({final bool useTimer = false}) async { + final List jobs = await api.getServerJobs(); + emit( + ServerJobsState( + serverJobList: jobs, + ), + ); + if (useTimer) { + timer = Timer(const Duration(seconds: 10), () => reload(useTimer: true)); + } + } +} diff --git a/lib/logic/cubit/server_jobs/server_jobs_state.dart b/lib/logic/cubit/server_jobs/server_jobs_state.dart new file mode 100644 index 00000000..82ac4377 --- /dev/null +++ b/lib/logic/cubit/server_jobs/server_jobs_state.dart @@ -0,0 +1,16 @@ +part of 'server_jobs_cubit.dart'; + +class ServerJobsState extends ServerInstallationDependendState { + const ServerJobsState({this.serverJobList = const []}); + final List serverJobList; + + @override + List get props => serverJobList; + + ServerJobsState copyWith({ + final List? serverJobList, + }) => + ServerJobsState( + serverJobList: serverJobList ?? this.serverJobList, + ); +} diff --git a/lib/ui/components/jobs_content/jobs_content.dart b/lib/ui/components/jobs_content/jobs_content.dart index 3948f7c4..f7063230 100644 --- a/lib/ui/components/jobs_content/jobs_content.dart +++ b/lib/ui/components/jobs_content/jobs_content.dart @@ -3,8 +3,9 @@ import 'package:easy_localization/easy_localization.dart'; import 'package:flutter_bloc/flutter_bloc.dart'; import 'package:selfprivacy/config/brand_theme.dart'; import 'package:selfprivacy/config/get_it_config.dart'; -import 'package:selfprivacy/logic/cubit/jobs/jobs_cubit.dart'; +import 'package:selfprivacy/logic/cubit/client_jobs/client_jobs_cubit.dart'; import 'package:selfprivacy/logic/cubit/server_installation/server_installation_cubit.dart'; +import 'package:selfprivacy/logic/cubit/server_jobs/server_jobs_cubit.dart'; import 'package:selfprivacy/ui/components/action_button/action_button.dart'; import 'package:selfprivacy/ui/components/brand_alert/brand_alert.dart'; import 'package:selfprivacy/ui/components/brand_button/brand_button.dart'; @@ -122,11 +123,11 @@ class JobsContent extends StatelessWidget { const SizedBox(height: 8), const Divider(), const SizedBox(height: 8), - ...state.serverJobList.map( - (final job) => ServerJobCard( - serverJob: job, - ), - ), + ...context.read().state.serverJobList.map( + (final job) => ServerJobCard( + serverJob: job, + ), + ), ], ); }, diff --git a/lib/ui/components/pre_styled_buttons/flash_fab.dart b/lib/ui/components/pre_styled_buttons/flash_fab.dart index 4ae29087..c9fb754f 100644 --- a/lib/ui/components/pre_styled_buttons/flash_fab.dart +++ b/lib/ui/components/pre_styled_buttons/flash_fab.dart @@ -1,7 +1,7 @@ import 'package:flutter/material.dart'; import 'package:flutter_bloc/flutter_bloc.dart'; import 'package:ionicons/ionicons.dart'; -import 'package:selfprivacy/logic/cubit/jobs/jobs_cubit.dart'; +import 'package:selfprivacy/logic/cubit/client_jobs/client_jobs_cubit.dart'; import 'package:selfprivacy/ui/components/brand_bottom_sheet/brand_bottom_sheet.dart'; import 'package:selfprivacy/ui/components/jobs_content/jobs_content.dart'; import 'package:selfprivacy/ui/helpers/modals.dart'; diff --git a/lib/ui/components/pre_styled_buttons/pre_styled_buttons.dart b/lib/ui/components/pre_styled_buttons/pre_styled_buttons.dart index ad9105fb..5649236c 100644 --- a/lib/ui/components/pre_styled_buttons/pre_styled_buttons.dart +++ b/lib/ui/components/pre_styled_buttons/pre_styled_buttons.dart @@ -2,7 +2,7 @@ import 'package:flutter/material.dart'; import 'package:flutter_bloc/flutter_bloc.dart'; import 'package:ionicons/ionicons.dart'; import 'package:selfprivacy/config/brand_colors.dart'; -import 'package:selfprivacy/logic/cubit/jobs/jobs_cubit.dart'; +import 'package:selfprivacy/logic/cubit/client_jobs/client_jobs_cubit.dart'; import 'package:selfprivacy/ui/components/brand_bottom_sheet/brand_bottom_sheet.dart'; import 'package:selfprivacy/ui/components/brand_text/brand_text.dart'; import 'package:easy_localization/easy_localization.dart'; diff --git a/lib/ui/pages/services/services.dart b/lib/ui/pages/services/services.dart index ba8465d2..a469d06b 100644 --- a/lib/ui/pages/services/services.dart +++ b/lib/ui/pages/services/services.dart @@ -4,7 +4,7 @@ import 'package:flutter/material.dart'; import 'package:selfprivacy/config/brand_theme.dart'; import 'package:selfprivacy/logic/common_enum/common_enum.dart'; import 'package:selfprivacy/logic/cubit/server_installation/server_installation_cubit.dart'; -import 'package:selfprivacy/logic/cubit/jobs/jobs_cubit.dart'; +import 'package:selfprivacy/logic/cubit/client_jobs/client_jobs_cubit.dart'; import 'package:selfprivacy/logic/cubit/services/services_cubit.dart'; import 'package:selfprivacy/logic/models/job.dart'; import 'package:selfprivacy/logic/models/state_types.dart'; @@ -115,11 +115,8 @@ class _Card extends StatelessWidget { final domainName = UiHelpers.getDomainName(config); return GestureDetector( - onTap: () => Navigator.of(context).push( - materialRoute( - ServicePage(serviceId: serviceType.name) - ) - ), + onTap: () => Navigator.of(context) + .push(materialRoute(ServicePage(serviceId: serviceType.name))), child: BrandCards.big( child: Column( crossAxisAlignment: CrossAxisAlignment.start, diff --git a/lib/ui/pages/ssh_keys/ssh_keys.dart b/lib/ui/pages/ssh_keys/ssh_keys.dart index 4059ba63..64c1af9c 100644 --- a/lib/ui/pages/ssh_keys/ssh_keys.dart +++ b/lib/ui/pages/ssh_keys/ssh_keys.dart @@ -10,7 +10,7 @@ import 'package:selfprivacy/ui/components/brand_icons/brand_icons.dart'; import 'package:selfprivacy/config/brand_colors.dart'; import 'package:selfprivacy/config/brand_theme.dart'; -import 'package:selfprivacy/logic/cubit/jobs/jobs_cubit.dart'; +import 'package:selfprivacy/logic/cubit/client_jobs/client_jobs_cubit.dart'; import 'package:selfprivacy/logic/models/hive/user.dart'; import 'package:selfprivacy/ui/components/brand_button/brand_button.dart'; import 'package:selfprivacy/ui/components/brand_header/brand_header.dart'; diff --git a/lib/ui/pages/users/users.dart b/lib/ui/pages/users/users.dart index 659453d1..3ccb696a 100644 --- a/lib/ui/pages/users/users.dart +++ b/lib/ui/pages/users/users.dart @@ -8,7 +8,7 @@ import 'package:selfprivacy/config/text_themes.dart'; import 'package:selfprivacy/logic/cubit/server_installation/server_installation_cubit.dart'; import 'package:selfprivacy/logic/cubit/forms/factories/field_cubit_factory.dart'; import 'package:selfprivacy/logic/cubit/forms/user/user_form_cubit.dart'; -import 'package:selfprivacy/logic/cubit/jobs/jobs_cubit.dart'; +import 'package:selfprivacy/logic/cubit/client_jobs/client_jobs_cubit.dart'; import 'package:selfprivacy/logic/cubit/users/users_cubit.dart'; import 'package:selfprivacy/logic/models/job.dart'; import 'package:selfprivacy/logic/models/hive/user.dart';