mirror of
https://git.selfprivacy.org/kherel/selfprivacy.org.app.git
synced 2025-01-28 19:56:50 +00:00
Pre-release testing bug fixes
This commit is contained in:
parent
900e07f364
commit
2a4c691f1e
|
@ -202,7 +202,7 @@
|
||||||
"extend_volume_button": "Extend volume",
|
"extend_volume_button": "Extend volume",
|
||||||
"extending_volume_title": "Extending volume",
|
"extending_volume_title": "Extending volume",
|
||||||
"extending_volume_description": "Resizing volume will allow you to store more data on your server without extending the server itself. Volume can only be extended: shrinking is not possible.",
|
"extending_volume_description": "Resizing volume will allow you to store more data on your server without extending the server itself. Volume can only be extended: shrinking is not possible.",
|
||||||
"extending_volume_price_info": "Price includes VAT and is estimated from pricing data provided by Hetzner.",
|
"extending_volume_price_info": "Price includes VAT and is estimated from pricing data provided by Hetzner. Server will be rebooted after resizing.",
|
||||||
"extending_volume_error": "Couldn't initialize volume extending.",
|
"extending_volume_error": "Couldn't initialize volume extending.",
|
||||||
"size": "Size",
|
"size": "Size",
|
||||||
"euro": "Euro",
|
"euro": "Euro",
|
||||||
|
@ -490,7 +490,8 @@
|
||||||
"rebootServer": "Reboot server",
|
"rebootServer": "Reboot server",
|
||||||
"create_ssh_key": "Create SSH key for {}",
|
"create_ssh_key": "Create SSH key for {}",
|
||||||
"delete_ssh_key": "Delete SSH key for {}",
|
"delete_ssh_key": "Delete SSH key for {}",
|
||||||
"server_jobs": "Jobs on the server"
|
"server_jobs": "Jobs on the server",
|
||||||
|
"resetUserPassword": "Reset password of user"
|
||||||
},
|
},
|
||||||
"validations": {
|
"validations": {
|
||||||
"required": "Required.",
|
"required": "Required.",
|
||||||
|
|
|
@ -204,7 +204,7 @@
|
||||||
"extend_volume_button": "Расширить хранилище",
|
"extend_volume_button": "Расширить хранилище",
|
||||||
"extending_volume_title": "Расширение хранилища",
|
"extending_volume_title": "Расширение хранилища",
|
||||||
"extending_volume_description": "Изменение размера хранилища позволит вам держать больше данных на вашем сервере без расширения самого сервера. Объем можно только увеличить: уменьшить нельзя.",
|
"extending_volume_description": "Изменение размера хранилища позволит вам держать больше данных на вашем сервере без расширения самого сервера. Объем можно только увеличить: уменьшить нельзя.",
|
||||||
"extending_volume_price_info": "Цена включает НДС и рассчитана на основе данных о ценах, предоставленных Hetzner.",
|
"extending_volume_price_info": "Цена включает НДС и рассчитана на основе данных о ценах, предоставленных Hetzner. Сервер будет перезагружен во время процесса.",
|
||||||
"extending_volume_error": "Не удалось начать расширение хранилища.",
|
"extending_volume_error": "Не удалось начать расширение хранилища.",
|
||||||
"size": "Размер",
|
"size": "Размер",
|
||||||
"euro": "Евро",
|
"euro": "Евро",
|
||||||
|
|
|
@ -17,6 +17,8 @@ class ApiProviderVolumeCubit
|
||||||
|
|
||||||
VolumeProviderApiFactory? providerApi;
|
VolumeProviderApiFactory? providerApi;
|
||||||
|
|
||||||
|
final ServerApi serverApi = ServerApi();
|
||||||
|
|
||||||
@override
|
@override
|
||||||
Future<void> load() async {
|
Future<void> load() async {
|
||||||
if (serverInstallationCubit.state is ServerInstallationFinished) {
|
if (serverInstallationCubit.state is ServerInstallationFinished) {
|
||||||
|
@ -34,23 +36,23 @@ class ApiProviderVolumeCubit
|
||||||
providerApi!.getVolumeProvider().getPricePerGb();
|
providerApi!.getVolumeProvider().getPricePerGb();
|
||||||
|
|
||||||
Future<void> refresh() async {
|
Future<void> refresh() async {
|
||||||
emit(const ApiProviderVolumeState([], LoadingStatus.refreshing));
|
emit(const ApiProviderVolumeState([], LoadingStatus.refreshing, false));
|
||||||
_refetch();
|
_refetch();
|
||||||
}
|
}
|
||||||
|
|
||||||
Future<void> _refetch() async {
|
Future<void> _refetch() async {
|
||||||
if (providerApi == null) {
|
if (providerApi == null) {
|
||||||
return emit(const ApiProviderVolumeState([], LoadingStatus.error));
|
return emit(const ApiProviderVolumeState([], LoadingStatus.error, false));
|
||||||
}
|
}
|
||||||
|
|
||||||
final List<ServerVolume> volumes =
|
final List<ServerVolume> volumes =
|
||||||
await providerApi!.getVolumeProvider().getVolumes();
|
await providerApi!.getVolumeProvider().getVolumes();
|
||||||
|
|
||||||
if (volumes.isEmpty) {
|
if (volumes.isEmpty) {
|
||||||
return emit(const ApiProviderVolumeState([], LoadingStatus.error));
|
return emit(const ApiProviderVolumeState([], LoadingStatus.error, false));
|
||||||
}
|
}
|
||||||
|
|
||||||
emit(ApiProviderVolumeState(volumes, LoadingStatus.success));
|
emit(ApiProviderVolumeState(volumes, LoadingStatus.success, false));
|
||||||
}
|
}
|
||||||
|
|
||||||
Future<void> attachVolume(final DiskVolume volume) async {
|
Future<void> attachVolume(final DiskVolume volume) async {
|
||||||
|
@ -71,7 +73,12 @@ class ApiProviderVolumeCubit
|
||||||
Future<bool> resizeVolume(
|
Future<bool> resizeVolume(
|
||||||
final DiskVolume volume,
|
final DiskVolume volume,
|
||||||
final int newSizeGb,
|
final int newSizeGb,
|
||||||
|
final Function() callback,
|
||||||
) async {
|
) async {
|
||||||
|
getIt<NavigationService>().showSnackBar(
|
||||||
|
'Starting resize',
|
||||||
|
);
|
||||||
|
emit(state.copyWith(isResizing: true));
|
||||||
final bool resized = await providerApi!.getVolumeProvider().resizeVolume(
|
final bool resized = await providerApi!.getVolumeProvider().resizeVolume(
|
||||||
volume.providerVolume!.id,
|
volume.providerVolume!.id,
|
||||||
newSizeGb,
|
newSizeGb,
|
||||||
|
@ -81,13 +88,29 @@ class ApiProviderVolumeCubit
|
||||||
getIt<NavigationService>().showSnackBar(
|
getIt<NavigationService>().showSnackBar(
|
||||||
'providers.storage.extending_volume_error'.tr(),
|
'providers.storage.extending_volume_error'.tr(),
|
||||||
);
|
);
|
||||||
|
emit(state.copyWith(isResizing: false));
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
getIt<NavigationService>().showSnackBar(
|
||||||
|
'Hetzner resized, waiting 10 seconds',
|
||||||
|
);
|
||||||
await Future.delayed(const Duration(seconds: 10));
|
await Future.delayed(const Duration(seconds: 10));
|
||||||
|
|
||||||
await ServerApi().resizeVolume(volume.name);
|
await ServerApi().resizeVolume(volume.name);
|
||||||
refresh();
|
getIt<NavigationService>().showSnackBar(
|
||||||
|
'Server api resized, waiting 20 seconds',
|
||||||
|
);
|
||||||
|
|
||||||
|
await Future.delayed(const Duration(seconds: 20));
|
||||||
|
getIt<NavigationService>().showSnackBar(
|
||||||
|
'Restarting server',
|
||||||
|
);
|
||||||
|
|
||||||
|
await refresh();
|
||||||
|
emit(state.copyWith(isResizing: false));
|
||||||
|
await callback();
|
||||||
|
await serverApi.reboot();
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -1,22 +1,25 @@
|
||||||
part of 'provider_volume_cubit.dart';
|
part of 'provider_volume_cubit.dart';
|
||||||
|
|
||||||
class ApiProviderVolumeState extends ServerInstallationDependendState {
|
class ApiProviderVolumeState extends ServerInstallationDependendState {
|
||||||
const ApiProviderVolumeState(this._volumes, this.status);
|
const ApiProviderVolumeState(this._volumes, this.status, this.isResizing);
|
||||||
|
|
||||||
const ApiProviderVolumeState.initial()
|
const ApiProviderVolumeState.initial()
|
||||||
: this(const [], LoadingStatus.uninitialized);
|
: this(const [], LoadingStatus.uninitialized, false);
|
||||||
final List<ServerVolume> _volumes;
|
final List<ServerVolume> _volumes;
|
||||||
final LoadingStatus status;
|
final LoadingStatus status;
|
||||||
|
final bool isResizing;
|
||||||
|
|
||||||
List<ServerVolume> get volumes => _volumes;
|
List<ServerVolume> get volumes => _volumes;
|
||||||
|
|
||||||
ApiProviderVolumeState copyWith({
|
ApiProviderVolumeState copyWith({
|
||||||
final List<ServerVolume>? volumes,
|
final List<ServerVolume>? volumes,
|
||||||
final LoadingStatus? status,
|
final LoadingStatus? status,
|
||||||
|
final bool? isResizing,
|
||||||
}) =>
|
}) =>
|
||||||
ApiProviderVolumeState(
|
ApiProviderVolumeState(
|
||||||
volumes ?? _volumes,
|
volumes ?? _volumes,
|
||||||
status ?? this.status,
|
status ?? this.status,
|
||||||
|
isResizing ?? this.isResizing,
|
||||||
);
|
);
|
||||||
|
|
||||||
@override
|
@override
|
||||||
|
|
|
@ -24,7 +24,7 @@ class ApiServerVolumeCubit
|
||||||
@override
|
@override
|
||||||
Future<void> load() async {
|
Future<void> load() async {
|
||||||
if (serverInstallationCubit.state is ServerInstallationFinished) {
|
if (serverInstallationCubit.state is ServerInstallationFinished) {
|
||||||
_refetch();
|
reload();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -43,7 +43,7 @@ class ApiServerVolumeCubit
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
Future<void> _refetch() async {
|
Future<void> reload() async {
|
||||||
final volumes = await serverApi.getServerDiskVolumes();
|
final volumes = await serverApi.getServerDiskVolumes();
|
||||||
final usesBinds = await serverApi.isUsingBinds();
|
final usesBinds = await serverApi.isUsingBinds();
|
||||||
var status = LoadingStatus.error;
|
var status = LoadingStatus.error;
|
||||||
|
|
|
@ -46,8 +46,10 @@ class ServerJobCard extends StatelessWidget {
|
||||||
children: [
|
children: [
|
||||||
Row(
|
Row(
|
||||||
crossAxisAlignment: CrossAxisAlignment.start,
|
crossAxisAlignment: CrossAxisAlignment.start,
|
||||||
|
mainAxisAlignment: MainAxisAlignment.spaceBetween,
|
||||||
children: [
|
children: [
|
||||||
Column(
|
Flexible(
|
||||||
|
child: Column(
|
||||||
crossAxisAlignment: CrossAxisAlignment.start,
|
crossAxisAlignment: CrossAxisAlignment.start,
|
||||||
children: [
|
children: [
|
||||||
Text(
|
Text(
|
||||||
|
@ -60,7 +62,7 @@ class ServerJobCard extends StatelessWidget {
|
||||||
),
|
),
|
||||||
],
|
],
|
||||||
),
|
),
|
||||||
const Spacer(),
|
),
|
||||||
Icon(
|
Icon(
|
||||||
icon,
|
icon,
|
||||||
color: color,
|
color: color,
|
||||||
|
|
|
@ -3,13 +3,16 @@ import 'package:flutter/material.dart';
|
||||||
import 'package:selfprivacy/logic/cubit/server_jobs/server_jobs_cubit.dart';
|
import 'package:selfprivacy/logic/cubit/server_jobs/server_jobs_cubit.dart';
|
||||||
import 'package:selfprivacy/logic/models/disk_size.dart';
|
import 'package:selfprivacy/logic/models/disk_size.dart';
|
||||||
import 'package:selfprivacy/logic/models/service.dart';
|
import 'package:selfprivacy/logic/models/service.dart';
|
||||||
|
import 'package:selfprivacy/ui/components/brand_bottom_sheet/brand_bottom_sheet.dart';
|
||||||
import 'package:selfprivacy/ui/components/brand_button/filled_button.dart';
|
import 'package:selfprivacy/ui/components/brand_button/filled_button.dart';
|
||||||
import 'package:selfprivacy/ui/components/brand_header/brand_header.dart';
|
import 'package:selfprivacy/ui/components/brand_header/brand_header.dart';
|
||||||
import 'package:selfprivacy/ui/components/info_box/info_box.dart';
|
import 'package:selfprivacy/ui/components/info_box/info_box.dart';
|
||||||
import 'package:selfprivacy/logic/models/disk_status.dart';
|
import 'package:selfprivacy/logic/models/disk_status.dart';
|
||||||
|
import 'package:selfprivacy/ui/components/jobs_content/jobs_content.dart';
|
||||||
import 'package:selfprivacy/ui/components/storage_list_items/server_storage_list_item.dart';
|
import 'package:selfprivacy/ui/components/storage_list_items/server_storage_list_item.dart';
|
||||||
import 'package:selfprivacy/ui/components/storage_list_items/service_migration_list_item.dart';
|
import 'package:selfprivacy/ui/components/storage_list_items/service_migration_list_item.dart';
|
||||||
import 'package:selfprivacy/ui/pages/server_storage/binds_migration/migration_process_page.dart';
|
import 'package:selfprivacy/ui/helpers/modals.dart';
|
||||||
|
import 'package:selfprivacy/ui/pages/root_route.dart';
|
||||||
import 'package:selfprivacy/utils/route_transitions/basic.dart';
|
import 'package:selfprivacy/utils/route_transitions/basic.dart';
|
||||||
|
|
||||||
class DataToBindsMigrationPage extends StatefulWidget {
|
class DataToBindsMigrationPage extends StatefulWidget {
|
||||||
|
@ -162,8 +165,17 @@ class _DataToBindsMigrationPageState extends State<DataToBindsMigrationPage> {
|
||||||
title: 'providers.storage.start_migration_button'.tr(),
|
title: 'providers.storage.start_migration_button'.tr(),
|
||||||
onPressed: () {
|
onPressed: () {
|
||||||
context.read<ServerJobsCubit>().migrateToBinds(serviceToDisk);
|
context.read<ServerJobsCubit>().migrateToBinds(serviceToDisk);
|
||||||
Navigator.of(context).push(
|
Navigator.of(context).pushAndRemoveUntil(
|
||||||
materialRoute(const MigrationProcessPage()),
|
materialRoute(const RootPage()),
|
||||||
|
(final predicate) => false,
|
||||||
|
);
|
||||||
|
showBrandBottomSheet(
|
||||||
|
context: context,
|
||||||
|
builder: (final BuildContext context) =>
|
||||||
|
const BrandBottomSheet(
|
||||||
|
isExpended: true,
|
||||||
|
child: JobsContent(),
|
||||||
|
),
|
||||||
);
|
);
|
||||||
},
|
},
|
||||||
),
|
),
|
||||||
|
|
|
@ -2,6 +2,7 @@ import 'package:easy_localization/easy_localization.dart';
|
||||||
import 'package:flutter/material.dart';
|
import 'package:flutter/material.dart';
|
||||||
import 'package:selfprivacy/logic/cubit/app_config_dependent/authentication_dependend_cubit.dart';
|
import 'package:selfprivacy/logic/cubit/app_config_dependent/authentication_dependend_cubit.dart';
|
||||||
import 'package:selfprivacy/logic/cubit/provider_volumes/provider_volume_cubit.dart';
|
import 'package:selfprivacy/logic/cubit/provider_volumes/provider_volume_cubit.dart';
|
||||||
|
import 'package:selfprivacy/logic/cubit/server_volumes/server_volume_cubit.dart';
|
||||||
import 'package:selfprivacy/logic/models/disk_size.dart';
|
import 'package:selfprivacy/logic/models/disk_size.dart';
|
||||||
import 'package:selfprivacy/ui/components/brand_button/filled_button.dart';
|
import 'package:selfprivacy/ui/components/brand_button/filled_button.dart';
|
||||||
import 'package:selfprivacy/ui/components/brand_hero_screen/brand_hero_screen.dart';
|
import 'package:selfprivacy/ui/components/brand_hero_screen/brand_hero_screen.dart';
|
||||||
|
@ -26,7 +27,7 @@ class ExtendingVolumePage extends StatefulWidget {
|
||||||
class _ExtendingVolumePageState extends State<ExtendingVolumePage> {
|
class _ExtendingVolumePageState extends State<ExtendingVolumePage> {
|
||||||
@override
|
@override
|
||||||
void initState() {
|
void initState() {
|
||||||
minSize = widget.diskVolumeToResize.sizeTotal + DiskSize.fromGibibyte(2);
|
minSize = widget.diskVolumeToResize.sizeTotal + DiskSize.fromGibibyte(3);
|
||||||
_currentSliderGbValue = minSize.gibibyte;
|
_currentSliderGbValue = minSize.gibibyte;
|
||||||
super.initState();
|
super.initState();
|
||||||
}
|
}
|
||||||
|
@ -73,11 +74,14 @@ class _ExtendingVolumePageState extends State<ExtendingVolumePage> {
|
||||||
(_euroPerGb * double.parse(_sizeController.text))
|
(_euroPerGb * double.parse(_sizeController.text))
|
||||||
.toStringAsFixed(2);
|
.toStringAsFixed(2);
|
||||||
minSize =
|
minSize =
|
||||||
widget.diskVolumeToResize.sizeTotal + DiskSize.fromGibibyte(2);
|
widget.diskVolumeToResize.sizeTotal + DiskSize.fromGibibyte(3);
|
||||||
if (_currentSliderGbValue < 0) {
|
if (_currentSliderGbValue < 0) {
|
||||||
_currentSliderGbValue = minSize.gibibyte;
|
_currentSliderGbValue = minSize.gibibyte;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
final isAlreadyResizing =
|
||||||
|
context.watch<ApiProviderVolumeCubit>().state.isResizing;
|
||||||
|
|
||||||
return BrandHeroScreen(
|
return BrandHeroScreen(
|
||||||
hasBackButton: true,
|
hasBackButton: true,
|
||||||
heroTitle: 'providers.storage.extending_volume_title'.tr(),
|
heroTitle: 'providers.storage.extending_volume_title'.tr(),
|
||||||
|
@ -143,13 +147,14 @@ class _ExtendingVolumePageState extends State<ExtendingVolumePage> {
|
||||||
context.read<ApiProviderVolumeCubit>().resizeVolume(
|
context.read<ApiProviderVolumeCubit>().resizeVolume(
|
||||||
widget.diskVolumeToResize,
|
widget.diskVolumeToResize,
|
||||||
_currentSliderGbValue.round(),
|
_currentSliderGbValue.round(),
|
||||||
|
context.read<ApiServerVolumeCubit>().reload,
|
||||||
);
|
);
|
||||||
Navigator.of(context).pushAndRemoveUntil(
|
Navigator.of(context).pushAndRemoveUntil(
|
||||||
materialRoute(const RootPage()),
|
materialRoute(const RootPage()),
|
||||||
(final predicate) => false,
|
(final predicate) => false,
|
||||||
);
|
);
|
||||||
},
|
},
|
||||||
disabled: _isError,
|
disabled: _isError || isAlreadyResizing,
|
||||||
),
|
),
|
||||||
const SizedBox(height: 16),
|
const SizedBox(height: 16),
|
||||||
const Divider(
|
const Divider(
|
||||||
|
|
Loading…
Reference in a new issue