mirror of
https://git.selfprivacy.org/kherel/selfprivacy.org.app.git
synced 2025-01-23 09:16:54 +00:00
fix: Return the binds migration interface
Turns out, there are still servers that didn't perform the binds migration. The can't perform it anymore because email changed the id. I'm getting back the option to perform the binds migration, with some fallback defaults.
This commit is contained in:
parent
490e5f92f3
commit
a9a7b04ad5
|
@ -60,17 +60,18 @@ mixin VolumeApi on GraphQLApiMap {
|
|||
|
||||
Future<GenericResult<String?>> migrateToBinds(
|
||||
final Map<String, String> serviceToDisk,
|
||||
final String fallbackDrive,
|
||||
) async {
|
||||
GenericResult<String?>? mutation;
|
||||
|
||||
try {
|
||||
final GraphQLClient client = await getClient();
|
||||
final input = Input$MigrateToBindsInput(
|
||||
bitwardenBlockDevice: serviceToDisk['bitwarden']!,
|
||||
emailBlockDevice: serviceToDisk['mailserver']!,
|
||||
giteaBlockDevice: serviceToDisk['gitea']!,
|
||||
nextcloudBlockDevice: serviceToDisk['nextcloud']!,
|
||||
pleromaBlockDevice: serviceToDisk['pleroma']!,
|
||||
bitwardenBlockDevice: serviceToDisk['bitwarden'] ?? fallbackDrive,
|
||||
emailBlockDevice: serviceToDisk['email'] ?? fallbackDrive,
|
||||
giteaBlockDevice: serviceToDisk['gitea'] ?? fallbackDrive,
|
||||
nextcloudBlockDevice: serviceToDisk['nextcloud'] ?? fallbackDrive,
|
||||
pleromaBlockDevice: serviceToDisk['pleroma'] ?? fallbackDrive,
|
||||
);
|
||||
final variables = Variables$Mutation$MigrateToBinds(input: input);
|
||||
final migrateMutation =
|
||||
|
|
|
@ -2,6 +2,7 @@ import 'dart:async';
|
|||
|
||||
import 'package:bloc_concurrency/bloc_concurrency.dart';
|
||||
import 'package:equatable/equatable.dart';
|
||||
import 'package:flutter/material.dart';
|
||||
import 'package:flutter_bloc/flutter_bloc.dart';
|
||||
import 'package:selfprivacy/config/get_it_config.dart';
|
||||
import 'package:selfprivacy/logic/models/json/server_job.dart';
|
||||
|
@ -68,6 +69,25 @@ class ServerJobsBloc extends Bloc<ServerJobsEvent, ServerJobsState> {
|
|||
await getIt<ApiConnectionRepository>().removeAllFinishedServerJobs();
|
||||
}
|
||||
|
||||
Future<void> migrateToBinds(final Map<String, String> serviceToDisk) async {
|
||||
final fallbackDrive = getIt<ApiConnectionRepository>()
|
||||
.apiData
|
||||
.volumes
|
||||
.data
|
||||
?.where((final drive) => drive.root)
|
||||
.first
|
||||
.name ??
|
||||
'sda1';
|
||||
final result = await getIt<ApiConnectionRepository>()
|
||||
.api
|
||||
.migrateToBinds(serviceToDisk, fallbackDrive);
|
||||
if (result.data == null) {
|
||||
getIt<NavigationService>()
|
||||
.showSnackBar(result.message!, behavior: SnackBarBehavior.floating);
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
@override
|
||||
void onChange(final Change<ServerJobsState> change) {
|
||||
super.onChange(change);
|
||||
|
|
21
lib/ui/components/list_tiles/section_title.dart
Normal file
21
lib/ui/components/list_tiles/section_title.dart
Normal file
|
@ -0,0 +1,21 @@
|
|||
import 'package:flutter/material.dart';
|
||||
|
||||
class SectionTitle extends StatelessWidget {
|
||||
const SectionTitle({
|
||||
required this.title,
|
||||
super.key,
|
||||
});
|
||||
|
||||
final String title;
|
||||
|
||||
@override
|
||||
Widget build(final BuildContext context) => Padding(
|
||||
padding: const EdgeInsets.all(16),
|
||||
child: Text(
|
||||
title,
|
||||
style: Theme.of(context).textTheme.labelLarge!.copyWith(
|
||||
color: Theme.of(context).colorScheme.secondary,
|
||||
),
|
||||
),
|
||||
);
|
||||
}
|
|
@ -5,6 +5,7 @@ import 'package:easy_localization/easy_localization.dart';
|
|||
import 'package:flutter/material.dart';
|
||||
import 'package:package_info/package_info.dart';
|
||||
import 'package:selfprivacy/config/get_it_config.dart';
|
||||
import 'package:selfprivacy/ui/components/list_tiles/section_title.dart';
|
||||
import 'package:selfprivacy/ui/layouts/brand_hero_screen.dart';
|
||||
import 'package:selfprivacy/utils/breakpoints.dart';
|
||||
import 'package:selfprivacy/utils/platform_adapter.dart';
|
||||
|
@ -220,26 +221,6 @@ class AboutApplicationPage extends StatelessWidget {
|
|||
}
|
||||
}
|
||||
|
||||
class SectionTitle extends StatelessWidget {
|
||||
const SectionTitle({
|
||||
required this.title,
|
||||
super.key,
|
||||
});
|
||||
|
||||
final String title;
|
||||
|
||||
@override
|
||||
Widget build(final BuildContext context) => Padding(
|
||||
padding: const EdgeInsets.all(16),
|
||||
child: Text(
|
||||
title,
|
||||
style: Theme.of(context).textTheme.labelLarge!.copyWith(
|
||||
color: Theme.of(context).colorScheme.secondary,
|
||||
),
|
||||
),
|
||||
);
|
||||
}
|
||||
|
||||
class LinkListTile extends StatelessWidget {
|
||||
const LinkListTile({
|
||||
required this.title,
|
||||
|
|
|
@ -3,8 +3,12 @@ import 'package:easy_localization/easy_localization.dart';
|
|||
import 'package:flutter/material.dart';
|
||||
import 'package:selfprivacy/config/get_it_config.dart';
|
||||
import 'package:selfprivacy/logic/api_maps/tls_options.dart';
|
||||
import 'package:selfprivacy/logic/bloc/services/services_bloc.dart';
|
||||
import 'package:selfprivacy/logic/bloc/volumes/volumes_bloc.dart';
|
||||
import 'package:selfprivacy/logic/cubit/app_settings/app_settings_cubit.dart';
|
||||
import 'package:selfprivacy/ui/components/list_tiles/section_title.dart';
|
||||
import 'package:selfprivacy/ui/layouts/brand_hero_screen.dart';
|
||||
import 'package:selfprivacy/ui/router/router.dart';
|
||||
|
||||
@RoutePage()
|
||||
class DeveloperSettingsPage extends StatefulWidget {
|
||||
|
@ -23,15 +27,7 @@ class _DeveloperSettingsPageState extends State<DeveloperSettingsPage> {
|
|||
heroTitle: 'developer_settings.title'.tr(),
|
||||
heroSubtitle: 'developer_settings.subtitle'.tr(),
|
||||
children: [
|
||||
Padding(
|
||||
padding: const EdgeInsets.all(16),
|
||||
child: Text(
|
||||
'developer_settings.server_setup'.tr(),
|
||||
style: Theme.of(context).textTheme.labelLarge!.copyWith(
|
||||
color: Theme.of(context).colorScheme.secondary,
|
||||
),
|
||||
),
|
||||
),
|
||||
SectionTitle(title: 'developer_settings.server_setup'.tr()),
|
||||
SwitchListTile(
|
||||
title: Text('developer_settings.use_staging_acme'.tr()),
|
||||
subtitle:
|
||||
|
@ -59,15 +55,7 @@ class _DeveloperSettingsPageState extends State<DeveloperSettingsPage> {
|
|||
() => TlsOptions.allowCustomSshKeyDuringSetup = value,
|
||||
),
|
||||
),
|
||||
Padding(
|
||||
padding: const EdgeInsets.all(16),
|
||||
child: Text(
|
||||
'developer_settings.routing'.tr(),
|
||||
style: Theme.of(context).textTheme.labelLarge!.copyWith(
|
||||
color: Theme.of(context).colorScheme.secondary,
|
||||
),
|
||||
),
|
||||
),
|
||||
SectionTitle(title: 'developer_settings.routing'.tr()),
|
||||
ListTile(
|
||||
title: Text('developer_settings.reset_onboarding'.tr()),
|
||||
subtitle:
|
||||
|
@ -78,15 +66,32 @@ class _DeveloperSettingsPageState extends State<DeveloperSettingsPage> {
|
|||
.read<AppSettingsCubit>()
|
||||
.turnOffOnboarding(isOnboardingShowing: true),
|
||||
),
|
||||
Padding(
|
||||
padding: const EdgeInsets.all(16),
|
||||
child: Text(
|
||||
'developer_settings.cubit_statuses'.tr(),
|
||||
style: Theme.of(context).textTheme.labelLarge!.copyWith(
|
||||
color: Theme.of(context).colorScheme.secondary,
|
||||
),
|
||||
ListTile(
|
||||
title: Text('storage.start_migration_button'.tr()),
|
||||
subtitle: Text('storage.data_migration_notice'.tr()),
|
||||
enabled:
|
||||
!context.watch<AppSettingsCubit>().state.isOnboardingShowing,
|
||||
onTap: () => context.pushRoute(
|
||||
ServicesMigrationRoute(
|
||||
diskStatus: context.read<VolumesBloc>().state.diskStatus,
|
||||
services: context
|
||||
.read<ServicesBloc>()
|
||||
.state
|
||||
.services
|
||||
.where(
|
||||
(final service) =>
|
||||
service.id == 'bitwarden' ||
|
||||
service.id == 'gitea' ||
|
||||
service.id == 'pleroma' ||
|
||||
service.id == 'email' ||
|
||||
service.id == 'nextcloud',
|
||||
)
|
||||
.toList(),
|
||||
isMigration: true,
|
||||
),
|
||||
),
|
||||
),
|
||||
SectionTitle(title: 'developer_settings.cubit_statuses'.tr()),
|
||||
ListTile(
|
||||
title: const Text('ApiConnectionRepository status'),
|
||||
subtitle: Text(
|
||||
|
|
|
@ -18,11 +18,13 @@ class ServicesMigrationPage extends StatefulWidget {
|
|||
const ServicesMigrationPage({
|
||||
required this.services,
|
||||
required this.diskStatus,
|
||||
required this.isMigration,
|
||||
super.key,
|
||||
});
|
||||
|
||||
final DiskStatus diskStatus;
|
||||
final List<Service> services;
|
||||
final bool isMigration;
|
||||
|
||||
@override
|
||||
State<ServicesMigrationPage> createState() => _ServicesMigrationPageState();
|
||||
|
@ -169,18 +171,24 @@ class _ServicesMigrationPageState extends State<ServicesMigrationPage> {
|
|||
),
|
||||
),
|
||||
const SizedBox(height: 16),
|
||||
if (isVolumePicked)
|
||||
if (widget.isMigration || (!widget.isMigration && isVolumePicked))
|
||||
BrandButton.filled(
|
||||
child: Text('storage.start_migration_button'.tr()),
|
||||
onPressed: () {
|
||||
for (final service in widget.services) {
|
||||
if (serviceToDisk[service.id] != null) {
|
||||
context.read<ServicesBloc>().add(
|
||||
ServiceMove(
|
||||
service,
|
||||
serviceToDisk[service.id]!,
|
||||
),
|
||||
);
|
||||
if (widget.isMigration) {
|
||||
context.read<ServerJobsBloc>().migrateToBinds(
|
||||
serviceToDisk,
|
||||
);
|
||||
} else {
|
||||
for (final service in widget.services) {
|
||||
if (serviceToDisk[service.id] != null) {
|
||||
context.read<ServicesBloc>().add(
|
||||
ServiceMove(
|
||||
service,
|
||||
serviceToDisk[service.id]!,
|
||||
),
|
||||
);
|
||||
}
|
||||
}
|
||||
}
|
||||
context.router.popUntilRoot();
|
||||
|
|
|
@ -114,6 +114,7 @@ class _ServicePageState extends State<ServicePage> {
|
|||
ServicesMigrationRoute(
|
||||
services: [service],
|
||||
diskStatus: context.read<VolumesBloc>().state.diskStatus,
|
||||
isMigration: false,
|
||||
),
|
||||
),
|
||||
leading: const Icon(Icons.drive_file_move_outlined),
|
||||
|
|
|
@ -159,6 +159,7 @@ abstract class _$RootRouter extends RootStackRouter {
|
|||
child: ServicesMigrationPage(
|
||||
services: args.services,
|
||||
diskStatus: args.diskStatus,
|
||||
isMigration: args.isMigration,
|
||||
key: args.key,
|
||||
),
|
||||
);
|
||||
|
@ -575,6 +576,7 @@ class ServicesMigrationRoute extends PageRouteInfo<ServicesMigrationRouteArgs> {
|
|||
ServicesMigrationRoute({
|
||||
required List<Service> services,
|
||||
required DiskStatus diskStatus,
|
||||
required bool isMigration,
|
||||
Key? key,
|
||||
List<PageRouteInfo>? children,
|
||||
}) : super(
|
||||
|
@ -582,6 +584,7 @@ class ServicesMigrationRoute extends PageRouteInfo<ServicesMigrationRouteArgs> {
|
|||
args: ServicesMigrationRouteArgs(
|
||||
services: services,
|
||||
diskStatus: diskStatus,
|
||||
isMigration: isMigration,
|
||||
key: key,
|
||||
),
|
||||
initialChildren: children,
|
||||
|
@ -597,6 +600,7 @@ class ServicesMigrationRouteArgs {
|
|||
const ServicesMigrationRouteArgs({
|
||||
required this.services,
|
||||
required this.diskStatus,
|
||||
required this.isMigration,
|
||||
this.key,
|
||||
});
|
||||
|
||||
|
@ -604,11 +608,13 @@ class ServicesMigrationRouteArgs {
|
|||
|
||||
final DiskStatus diskStatus;
|
||||
|
||||
final bool isMigration;
|
||||
|
||||
final Key? key;
|
||||
|
||||
@override
|
||||
String toString() {
|
||||
return 'ServicesMigrationRouteArgs{services: $services, diskStatus: $diskStatus, key: $key}';
|
||||
return 'ServicesMigrationRouteArgs{services: $services, diskStatus: $diskStatus, isMigration: $isMigration, key: $key}';
|
||||
}
|
||||
}
|
||||
|
||||
|
|
Loading…
Reference in a new issue