Implement server jobs cubit

pull/111/head
NaiJi ✨ 2022-08-30 06:09:09 +03:00
parent 7d8f8e1d38
commit 503c8d37ea
14 changed files with 136 additions and 98 deletions

View File

@ -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,

View File

@ -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<JobsState> {
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<JobsState> {
}
newJobsList.add(job);
getIt<NavigationService>().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<JobsState> {
} else {
newJobsList.add(job);
getIt<NavigationService>().showSnackBar('jobs.jobAdded'.tr());
emit(JobsStateWithJobs(newJobsList, state.serverJobList));
emit(JobsStateWithJobs(newJobsList));
}
}
@ -69,23 +68,23 @@ class JobsCubit extends Cubit<JobsState> {
if (!isExistInJobList) {
newJobsList.add(job);
getIt<NavigationService>().showSnackBar('jobs.jobAdded'.tr());
emit(JobsStateWithJobs(newJobsList, state.serverJobList));
emit(JobsStateWithJobs(newJobsList));
}
}
Future<void> rebootServer() async {
emit(JobsStateLoading(state.serverJobList));
emit(JobsStateLoading());
final bool isSuccessful = await api.reboot();
if (isSuccessful) {
getIt<NavigationService>().showSnackBar('jobs.rebootSuccess'.tr());
} else {
getIt<NavigationService>().showSnackBar('jobs.rebootFailed'.tr());
}
emit(JobsStateEmpty(state.serverJobList));
emit(JobsStateEmpty());
}
Future<void> 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<JobsState> {
} else {
getIt<NavigationService>().showSnackBar('jobs.upgradeFailed'.tr());
}
emit(JobsStateEmpty(state.serverJobList));
emit(JobsStateEmpty());
}
Future<void> applyAll() async {
if (state is JobsStateWithJobs) {
final List<ClientJob> 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<JobsState> {
await servicesCubit.load();
}
emit(JobsStateEmpty(state.serverJobList));
emit(JobsStateEmpty());
}
}
Future<void> resetRequestsTimer() async {
const duration = Duration(seconds: 1);
Timer.periodic(
duration,
(final timer) async {
if (timer.tick >= 10) {
final List<ServerJob> serverJobs = await api.getServerJobs();
final List<ServerJob> 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),
);
}
}
},
);
}
}

View File

@ -0,0 +1,26 @@
part of 'client_jobs_cubit.dart';
abstract class JobsState extends Equatable {
@override
List<Object?> get props => [];
}
class JobsStateLoading extends JobsState {}
class JobsStateEmpty extends JobsState {}
class JobsStateWithJobs extends JobsState {
JobsStateWithJobs(this.clientJobList);
final List<ClientJob> clientJobList;
JobsState removeById(final String id) {
final List<ClientJob> newJobsList =
clientJobList.where((final element) => element.id != id).toList();
if (newJobsList.isEmpty) {
return JobsStateEmpty();
}
return JobsStateWithJobs(newJobsList);
}
@override
List<Object?> get props => clientJobList;
}

View File

@ -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';

View File

@ -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';

View File

@ -1,34 +0,0 @@
part of 'jobs_cubit.dart';
abstract class JobsState extends Equatable {
const JobsState(this.serverJobList);
final List<ServerJob> serverJobList;
@override
List<Object?> 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<ClientJob> clientJobList;
JobsState removeById(final String id) {
final List<ClientJob> newJobsList =
clientJobList.where((final element) => element.id != id).toList();
if (newJobsList.isEmpty) {
return JobsStateEmpty(serverJobList);
}
return JobsStateWithJobs(newJobsList, serverJobList);
}
@override
List<Object?> get props => [...super.props, clientJobList];
}

View File

@ -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<ServerJobsState> {
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<ServerJob> jobs = await api.getServerJobs();
emit(
ServerJobsState(
serverJobList: jobs,
),
);
timer = Timer(const Duration(seconds: 10), () => reload(useTimer: true));
}
}
Future<void> reload({final bool useTimer = false}) async {
final List<ServerJob> jobs = await api.getServerJobs();
emit(
ServerJobsState(
serverJobList: jobs,
),
);
if (useTimer) {
timer = Timer(const Duration(seconds: 10), () => reload(useTimer: true));
}
}
}

View File

@ -0,0 +1,16 @@
part of 'server_jobs_cubit.dart';
class ServerJobsState extends ServerInstallationDependendState {
const ServerJobsState({this.serverJobList = const []});
final List<ServerJob> serverJobList;
@override
List<Object?> get props => serverJobList;
ServerJobsState copyWith({
final List<ServerJob>? serverJobList,
}) =>
ServerJobsState(
serverJobList: serverJobList ?? this.serverJobList,
);
}

View File

@ -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<ServerJobsCubit>().state.serverJobList.map(
(final job) => ServerJobCard(
serverJob: job,
),
),
],
);
},

View File

@ -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';

View File

@ -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';

View File

@ -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,

View File

@ -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';

View File

@ -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';