mirror of
https://git.selfprivacy.org/kherel/selfprivacy.org.app.git
synced 2025-01-23 17:26:35 +00:00
refactor(ui): Update recovery flow to use new support drawer
This commit is contained in:
parent
d242f5141e
commit
a9d7a27e9d
113
lib/ui/components/drawers/progress_drawer.dart
Normal file
113
lib/ui/components/drawers/progress_drawer.dart
Normal file
|
@ -0,0 +1,113 @@
|
||||||
|
import 'package:easy_localization/easy_localization.dart';
|
||||||
|
import 'package:flutter/material.dart';
|
||||||
|
|
||||||
|
class ProgressDrawer extends StatelessWidget {
|
||||||
|
/// A [Drawer] that displays a list of steps and the current step.
|
||||||
|
/// Used in setup wizards. The [trailing] widget is displayed at the bottom.
|
||||||
|
/// The [steps] are translated using [EasyLocalization].
|
||||||
|
const ProgressDrawer({
|
||||||
|
required this.steps,
|
||||||
|
required this.currentStep,
|
||||||
|
required this.constraints,
|
||||||
|
required this.trailing,
|
||||||
|
required this.title,
|
||||||
|
super.key,
|
||||||
|
});
|
||||||
|
|
||||||
|
final List<String> steps;
|
||||||
|
final int currentStep;
|
||||||
|
final Widget trailing;
|
||||||
|
final BoxConstraints constraints;
|
||||||
|
final String title;
|
||||||
|
|
||||||
|
@override
|
||||||
|
Widget build(final BuildContext context) => SizedBox(
|
||||||
|
width: 300,
|
||||||
|
height: constraints.maxHeight,
|
||||||
|
child: Drawer(
|
||||||
|
child: Column(
|
||||||
|
crossAxisAlignment: CrossAxisAlignment.start,
|
||||||
|
children: [
|
||||||
|
Padding(
|
||||||
|
padding: const EdgeInsets.all(16.0),
|
||||||
|
child: Text(
|
||||||
|
title,
|
||||||
|
style: Theme.of(context).textTheme.titleLarge,
|
||||||
|
),
|
||||||
|
),
|
||||||
|
Flexible(
|
||||||
|
fit: FlexFit.tight,
|
||||||
|
child: SingleChildScrollView(
|
||||||
|
child: Column(
|
||||||
|
children: [
|
||||||
|
...steps.map((final step) {
|
||||||
|
final index = steps.indexOf(step);
|
||||||
|
return _StepIndicator(
|
||||||
|
title: step.tr(),
|
||||||
|
isCurrent: index == currentStep,
|
||||||
|
isCompleted: index < currentStep,
|
||||||
|
);
|
||||||
|
}),
|
||||||
|
],
|
||||||
|
),
|
||||||
|
),
|
||||||
|
),
|
||||||
|
// const Spacer(),
|
||||||
|
Padding(
|
||||||
|
padding: const EdgeInsets.all(16.0),
|
||||||
|
child: trailing,
|
||||||
|
),
|
||||||
|
],
|
||||||
|
),
|
||||||
|
),
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
class _StepIndicator extends StatelessWidget {
|
||||||
|
const _StepIndicator({
|
||||||
|
required this.title,
|
||||||
|
required this.isCompleted,
|
||||||
|
required this.isCurrent,
|
||||||
|
});
|
||||||
|
|
||||||
|
final String title;
|
||||||
|
final bool isCompleted;
|
||||||
|
final bool isCurrent;
|
||||||
|
|
||||||
|
@override
|
||||||
|
Widget build(final BuildContext context) => ListTile(
|
||||||
|
selected: isCurrent,
|
||||||
|
leading: isCurrent
|
||||||
|
? const _StepCurrentIcon()
|
||||||
|
: isCompleted
|
||||||
|
? const _StepCompletedIcon()
|
||||||
|
: const _StepPendingIcon(),
|
||||||
|
title: Text(
|
||||||
|
title,
|
||||||
|
),
|
||||||
|
textColor: Theme.of(context).colorScheme.onSurfaceVariant,
|
||||||
|
iconColor: Theme.of(context).colorScheme.onSurfaceVariant,
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
class _StepCompletedIcon extends StatelessWidget {
|
||||||
|
const _StepCompletedIcon();
|
||||||
|
|
||||||
|
@override
|
||||||
|
Widget build(final BuildContext context) => const Icon(Icons.check_circle);
|
||||||
|
}
|
||||||
|
|
||||||
|
class _StepPendingIcon extends StatelessWidget {
|
||||||
|
const _StepPendingIcon();
|
||||||
|
|
||||||
|
@override
|
||||||
|
Widget build(final BuildContext context) => const Icon(Icons.circle_outlined);
|
||||||
|
}
|
||||||
|
|
||||||
|
class _StepCurrentIcon extends StatelessWidget {
|
||||||
|
const _StepCurrentIcon();
|
||||||
|
|
||||||
|
@override
|
||||||
|
Widget build(final BuildContext context) =>
|
||||||
|
const Icon(Icons.build_circle_outlined);
|
||||||
|
}
|
|
@ -3,6 +3,7 @@ import 'package:flutter/material.dart';
|
||||||
import 'package:ionicons/ionicons.dart';
|
import 'package:ionicons/ionicons.dart';
|
||||||
import 'package:selfprivacy/logic/cubit/client_jobs/client_jobs_cubit.dart';
|
import 'package:selfprivacy/logic/cubit/client_jobs/client_jobs_cubit.dart';
|
||||||
import 'package:selfprivacy/ui/components/jobs_content/jobs_content.dart';
|
import 'package:selfprivacy/ui/components/jobs_content/jobs_content.dart';
|
||||||
|
import 'package:selfprivacy/ui/components/drawers/support_drawer.dart';
|
||||||
import 'package:selfprivacy/ui/helpers/widget_size.dart';
|
import 'package:selfprivacy/ui/helpers/widget_size.dart';
|
||||||
import 'package:selfprivacy/utils/breakpoints.dart';
|
import 'package:selfprivacy/utils/breakpoints.dart';
|
||||||
|
|
||||||
|
@ -18,6 +19,8 @@ class BrandHeroScreen extends StatelessWidget {
|
||||||
this.heroSubtitle,
|
this.heroSubtitle,
|
||||||
this.onBackButtonPressed,
|
this.onBackButtonPressed,
|
||||||
this.bodyPadding = const EdgeInsets.all(16.0),
|
this.bodyPadding = const EdgeInsets.all(16.0),
|
||||||
|
this.ignoreBreakpoints = false,
|
||||||
|
this.hasSupportDrawer = false,
|
||||||
});
|
});
|
||||||
|
|
||||||
final List<Widget> children;
|
final List<Widget> children;
|
||||||
|
@ -30,6 +33,15 @@ class BrandHeroScreen extends StatelessWidget {
|
||||||
final VoidCallback? onBackButtonPressed;
|
final VoidCallback? onBackButtonPressed;
|
||||||
final EdgeInsetsGeometry bodyPadding;
|
final EdgeInsetsGeometry bodyPadding;
|
||||||
|
|
||||||
|
/// On non-mobile screens the buttons of the app bar are hidden.
|
||||||
|
/// This is because this widget implies that it is nested inside a bigger layout.
|
||||||
|
/// If it is not nested, set this to true.
|
||||||
|
final bool ignoreBreakpoints;
|
||||||
|
|
||||||
|
/// Usually support drawer is provided by the parent layout.
|
||||||
|
/// If it is not provided, set this to true.
|
||||||
|
final bool hasSupportDrawer;
|
||||||
|
|
||||||
@override
|
@override
|
||||||
Widget build(final BuildContext context) {
|
Widget build(final BuildContext context) {
|
||||||
final Widget heroIconWidget = this.heroIconWidget ??
|
final Widget heroIconWidget = this.heroIconWidget ??
|
||||||
|
@ -41,6 +53,8 @@ class BrandHeroScreen extends StatelessWidget {
|
||||||
final bool hasHeroIcon = heroIcon != null || this.heroIconWidget != null;
|
final bool hasHeroIcon = heroIcon != null || this.heroIconWidget != null;
|
||||||
|
|
||||||
return Scaffold(
|
return Scaffold(
|
||||||
|
endDrawerEnableOpenDragGesture: false,
|
||||||
|
endDrawer: hasSupportDrawer ? const SupportDrawer() : null,
|
||||||
body: CustomScrollView(
|
body: CustomScrollView(
|
||||||
slivers: [
|
slivers: [
|
||||||
HeroSliverAppBar(
|
HeroSliverAppBar(
|
||||||
|
@ -50,6 +64,7 @@ class BrandHeroScreen extends StatelessWidget {
|
||||||
onBackButtonPressed: onBackButtonPressed,
|
onBackButtonPressed: onBackButtonPressed,
|
||||||
heroIconWidget: heroIconWidget,
|
heroIconWidget: heroIconWidget,
|
||||||
hasFlashButton: hasFlashButton,
|
hasFlashButton: hasFlashButton,
|
||||||
|
ignoreBreakpoints: ignoreBreakpoints,
|
||||||
),
|
),
|
||||||
if (heroSubtitle != null)
|
if (heroSubtitle != null)
|
||||||
SliverPadding(
|
SliverPadding(
|
||||||
|
@ -89,6 +104,7 @@ class HeroSliverAppBar extends StatefulWidget {
|
||||||
required this.onBackButtonPressed,
|
required this.onBackButtonPressed,
|
||||||
required this.heroIconWidget,
|
required this.heroIconWidget,
|
||||||
required this.hasFlashButton,
|
required this.hasFlashButton,
|
||||||
|
required this.ignoreBreakpoints,
|
||||||
super.key,
|
super.key,
|
||||||
});
|
});
|
||||||
|
|
||||||
|
@ -98,6 +114,7 @@ class HeroSliverAppBar extends StatefulWidget {
|
||||||
final bool hasFlashButton;
|
final bool hasFlashButton;
|
||||||
final VoidCallback? onBackButtonPressed;
|
final VoidCallback? onBackButtonPressed;
|
||||||
final Widget heroIconWidget;
|
final Widget heroIconWidget;
|
||||||
|
final bool ignoreBreakpoints;
|
||||||
|
|
||||||
@override
|
@override
|
||||||
State<HeroSliverAppBar> createState() => _HeroSliverAppBarState();
|
State<HeroSliverAppBar> createState() => _HeroSliverAppBarState();
|
||||||
|
@ -107,7 +124,8 @@ class _HeroSliverAppBarState extends State<HeroSliverAppBar> {
|
||||||
Size _size = Size.zero;
|
Size _size = Size.zero;
|
||||||
@override
|
@override
|
||||||
Widget build(final BuildContext context) {
|
Widget build(final BuildContext context) {
|
||||||
final isMobile = Breakpoints.small.isActive(context);
|
final isMobile =
|
||||||
|
widget.ignoreBreakpoints ? true : Breakpoints.small.isActive(context);
|
||||||
final isJobsListEmpty = context.watch<JobsCubit>().state is JobsStateEmpty;
|
final isJobsListEmpty = context.watch<JobsCubit>().state is JobsStateEmpty;
|
||||||
return SliverAppBar(
|
return SliverAppBar(
|
||||||
expandedHeight:
|
expandedHeight:
|
||||||
|
@ -127,8 +145,7 @@ class _HeroSliverAppBarState extends State<HeroSliverAppBar> {
|
||||||
onPressed: () {
|
onPressed: () {
|
||||||
showModalBottomSheet(
|
showModalBottomSheet(
|
||||||
context: context,
|
context: context,
|
||||||
builder: (final BuildContext context) =>
|
builder: (final BuildContext context) => const JobsContent(),
|
||||||
const JobsContent(),
|
|
||||||
);
|
);
|
||||||
},
|
},
|
||||||
icon: Icon(
|
icon: Icon(
|
||||||
|
@ -139,6 +156,7 @@ class _HeroSliverAppBarState extends State<HeroSliverAppBar> {
|
||||||
: Theme.of(context).colorScheme.primary,
|
: Theme.of(context).colorScheme.primary,
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
|
const SizedBox.shrink(),
|
||||||
],
|
],
|
||||||
flexibleSpace: FlexibleSpaceBar(
|
flexibleSpace: FlexibleSpaceBar(
|
||||||
title: LayoutBuilder(
|
title: LayoutBuilder(
|
||||||
|
|
|
@ -1,7 +1,7 @@
|
||||||
import 'package:auto_route/auto_route.dart';
|
import 'package:auto_route/auto_route.dart';
|
||||||
import 'package:flutter/material.dart';
|
import 'package:flutter/material.dart';
|
||||||
import 'package:selfprivacy/ui/components/pre_styled_buttons/flash_fab.dart';
|
import 'package:selfprivacy/ui/components/pre_styled_buttons/flash_fab.dart';
|
||||||
import 'package:selfprivacy/ui/components/support_drawer/support_drawer.dart';
|
import 'package:selfprivacy/ui/components/drawers/support_drawer.dart';
|
||||||
import 'package:selfprivacy/ui/router/root_destinations.dart';
|
import 'package:selfprivacy/ui/router/root_destinations.dart';
|
||||||
import 'package:selfprivacy/utils/breakpoints.dart';
|
import 'package:selfprivacy/utils/breakpoints.dart';
|
||||||
|
|
||||||
|
|
|
@ -182,8 +182,7 @@ class _ServicesMigrationPageState extends State<ServicesMigrationPage> {
|
||||||
);
|
);
|
||||||
showModalBottomSheet(
|
showModalBottomSheet(
|
||||||
context: context,
|
context: context,
|
||||||
builder: (final BuildContext context) =>
|
builder: (final BuildContext context) => const JobsContent(),
|
||||||
const JobsContent(),
|
|
||||||
);
|
);
|
||||||
},
|
},
|
||||||
),
|
),
|
||||||
|
|
|
@ -13,8 +13,9 @@ import 'package:selfprivacy/logic/cubit/support_system/support_system_cubit.dart
|
||||||
import 'package:selfprivacy/ui/components/buttons/brand_button.dart';
|
import 'package:selfprivacy/ui/components/buttons/brand_button.dart';
|
||||||
import 'package:selfprivacy/ui/components/buttons/outlined_button.dart';
|
import 'package:selfprivacy/ui/components/buttons/outlined_button.dart';
|
||||||
import 'package:selfprivacy/ui/components/brand_timer/brand_timer.dart';
|
import 'package:selfprivacy/ui/components/brand_timer/brand_timer.dart';
|
||||||
|
import 'package:selfprivacy/ui/components/drawers/progress_drawer.dart';
|
||||||
import 'package:selfprivacy/ui/components/progress_bar/progress_bar.dart';
|
import 'package:selfprivacy/ui/components/progress_bar/progress_bar.dart';
|
||||||
import 'package:selfprivacy/ui/components/support_drawer/support_drawer.dart';
|
import 'package:selfprivacy/ui/components/drawers/support_drawer.dart';
|
||||||
import 'package:selfprivacy/ui/layouts/responsive_layout_with_infobox.dart';
|
import 'package:selfprivacy/ui/layouts/responsive_layout_with_infobox.dart';
|
||||||
import 'package:selfprivacy/ui/pages/setup/initializing/server_provider_picker.dart';
|
import 'package:selfprivacy/ui/pages/setup/initializing/server_provider_picker.dart';
|
||||||
import 'package:selfprivacy/ui/pages/setup/initializing/server_type_picker.dart';
|
import 'package:selfprivacy/ui/pages/setup/initializing/server_type_picker.dart';
|
||||||
|
@ -113,10 +114,42 @@ class InitializingPage extends StatelessWidget {
|
||||||
builder: (final context, final constraints) => Row(
|
builder: (final context, final constraints) => Row(
|
||||||
children: [
|
children: [
|
||||||
if (Breakpoints.large.isActive(context))
|
if (Breakpoints.large.isActive(context))
|
||||||
_ProgressDrawer(
|
ProgressDrawer(
|
||||||
steps: steps,
|
steps: steps,
|
||||||
cubit: cubit,
|
currentStep: cubit.state.progress.index,
|
||||||
|
title: 'more_page.configuration_wizard'.tr(),
|
||||||
constraints: constraints,
|
constraints: constraints,
|
||||||
|
trailing: Column(
|
||||||
|
mainAxisAlignment: MainAxisAlignment.center,
|
||||||
|
children: [
|
||||||
|
if (cubit.state is ServerInstallationEmpty ||
|
||||||
|
cubit.state is ServerInstallationNotFinished)
|
||||||
|
Container(
|
||||||
|
alignment: Alignment.center,
|
||||||
|
child: BrandButton.filled(
|
||||||
|
text: 'basis.connect_to_existing'.tr(),
|
||||||
|
onPressed: () {
|
||||||
|
context.router.replace(const RecoveryRoute());
|
||||||
|
},
|
||||||
|
),
|
||||||
|
),
|
||||||
|
ConstrainedBox(
|
||||||
|
constraints: const BoxConstraints(
|
||||||
|
minWidth: double.infinity,
|
||||||
|
),
|
||||||
|
child: OutlinedButton(
|
||||||
|
child: Text(
|
||||||
|
cubit.state is ServerInstallationFinished
|
||||||
|
? 'basis.close'.tr()
|
||||||
|
: 'basis.later'.tr(),
|
||||||
|
),
|
||||||
|
onPressed: () {
|
||||||
|
context.router.popUntilRoot();
|
||||||
|
},
|
||||||
|
),
|
||||||
|
),
|
||||||
|
],
|
||||||
|
),
|
||||||
),
|
),
|
||||||
SizedBox(
|
SizedBox(
|
||||||
width: constraints.maxWidth -
|
width: constraints.maxWidth -
|
||||||
|
@ -625,136 +658,3 @@ class InitializingPage extends StatelessWidget {
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
class _ProgressDrawer extends StatelessWidget {
|
|
||||||
const _ProgressDrawer({
|
|
||||||
required this.steps,
|
|
||||||
required this.cubit,
|
|
||||||
required this.constraints,
|
|
||||||
});
|
|
||||||
|
|
||||||
final List<String> steps;
|
|
||||||
final ServerInstallationCubit cubit;
|
|
||||||
final BoxConstraints constraints;
|
|
||||||
|
|
||||||
@override
|
|
||||||
Widget build(final BuildContext context) => SizedBox(
|
|
||||||
width: 300,
|
|
||||||
height: constraints.maxHeight,
|
|
||||||
child: Drawer(
|
|
||||||
child: Column(
|
|
||||||
crossAxisAlignment: CrossAxisAlignment.start,
|
|
||||||
children: [
|
|
||||||
Padding(
|
|
||||||
padding: const EdgeInsets.all(16.0),
|
|
||||||
child: Text(
|
|
||||||
'more_page.configuration_wizard'.tr(),
|
|
||||||
style: Theme.of(context).textTheme.titleLarge,
|
|
||||||
),
|
|
||||||
),
|
|
||||||
Flexible(
|
|
||||||
fit: FlexFit.tight,
|
|
||||||
child: SingleChildScrollView(
|
|
||||||
child: Column(
|
|
||||||
children: [
|
|
||||||
...steps.map((final step) {
|
|
||||||
final index = steps.indexOf(step);
|
|
||||||
return _StepIndicator(
|
|
||||||
title: step.tr(),
|
|
||||||
isCurrent: index == cubit.state.progress.index,
|
|
||||||
isCompleted: index < cubit.state.progress.index,
|
|
||||||
);
|
|
||||||
}),
|
|
||||||
],
|
|
||||||
),
|
|
||||||
),
|
|
||||||
),
|
|
||||||
// const Spacer(),
|
|
||||||
Padding(
|
|
||||||
padding: const EdgeInsets.all(16.0),
|
|
||||||
child: Column(
|
|
||||||
mainAxisAlignment: MainAxisAlignment.center,
|
|
||||||
children: [
|
|
||||||
if (cubit.state is ServerInstallationEmpty ||
|
|
||||||
cubit.state is ServerInstallationNotFinished)
|
|
||||||
Container(
|
|
||||||
alignment: Alignment.center,
|
|
||||||
child: BrandButton.filled(
|
|
||||||
text: 'basis.connect_to_existing'.tr(),
|
|
||||||
onPressed: () {
|
|
||||||
context.router.replace(const RecoveryRoute());
|
|
||||||
},
|
|
||||||
),
|
|
||||||
),
|
|
||||||
ConstrainedBox(
|
|
||||||
constraints: const BoxConstraints(
|
|
||||||
minWidth: double.infinity,
|
|
||||||
),
|
|
||||||
child: OutlinedButton(
|
|
||||||
child: Text(
|
|
||||||
cubit.state is ServerInstallationFinished
|
|
||||||
? 'basis.close'.tr()
|
|
||||||
: 'basis.later'.tr(),
|
|
||||||
),
|
|
||||||
onPressed: () {
|
|
||||||
context.router.popUntilRoot();
|
|
||||||
},
|
|
||||||
),
|
|
||||||
),
|
|
||||||
],
|
|
||||||
),
|
|
||||||
),
|
|
||||||
],
|
|
||||||
),
|
|
||||||
),
|
|
||||||
);
|
|
||||||
}
|
|
||||||
|
|
||||||
class _StepIndicator extends StatelessWidget {
|
|
||||||
const _StepIndicator({
|
|
||||||
required this.title,
|
|
||||||
required this.isCompleted,
|
|
||||||
required this.isCurrent,
|
|
||||||
});
|
|
||||||
|
|
||||||
final String title;
|
|
||||||
final bool isCompleted;
|
|
||||||
final bool isCurrent;
|
|
||||||
|
|
||||||
@override
|
|
||||||
Widget build(final BuildContext context) => ListTile(
|
|
||||||
selected: isCurrent,
|
|
||||||
leading: isCurrent
|
|
||||||
? const _StepCurrentIcon()
|
|
||||||
: isCompleted
|
|
||||||
? const _StepCompletedIcon()
|
|
||||||
: const _StepPendingIcon(),
|
|
||||||
title: Text(
|
|
||||||
title,
|
|
||||||
),
|
|
||||||
textColor: Theme.of(context).colorScheme.onSurfaceVariant,
|
|
||||||
iconColor: Theme.of(context).colorScheme.onSurfaceVariant,
|
|
||||||
);
|
|
||||||
}
|
|
||||||
|
|
||||||
class _StepCompletedIcon extends StatelessWidget {
|
|
||||||
const _StepCompletedIcon();
|
|
||||||
|
|
||||||
@override
|
|
||||||
Widget build(final BuildContext context) => const Icon(Icons.check_circle);
|
|
||||||
}
|
|
||||||
|
|
||||||
class _StepPendingIcon extends StatelessWidget {
|
|
||||||
const _StepPendingIcon();
|
|
||||||
|
|
||||||
@override
|
|
||||||
Widget build(final BuildContext context) => const Icon(Icons.circle_outlined);
|
|
||||||
}
|
|
||||||
|
|
||||||
class _StepCurrentIcon extends StatelessWidget {
|
|
||||||
const _StepCurrentIcon();
|
|
||||||
|
|
||||||
@override
|
|
||||||
Widget build(final BuildContext context) =>
|
|
||||||
const Icon(Icons.build_circle_outlined);
|
|
||||||
}
|
|
||||||
|
|
|
@ -17,6 +17,7 @@ class RecoverByNewDeviceKeyInstruction extends StatelessWidget {
|
||||||
heroSubtitle: 'recovering.method_device_description'.tr(),
|
heroSubtitle: 'recovering.method_device_description'.tr(),
|
||||||
hasBackButton: true,
|
hasBackButton: true,
|
||||||
hasFlashButton: false,
|
hasFlashButton: false,
|
||||||
|
ignoreBreakpoints: true,
|
||||||
onBackButtonPressed:
|
onBackButtonPressed:
|
||||||
context.read<ServerInstallationCubit>().revertRecoveryStep,
|
context.read<ServerInstallationCubit>().revertRecoveryStep,
|
||||||
children: [
|
children: [
|
||||||
|
@ -61,6 +62,7 @@ class RecoverByNewDeviceKeyInput extends StatelessWidget {
|
||||||
heroSubtitle: 'recovering.method_device_input_description'.tr(),
|
heroSubtitle: 'recovering.method_device_input_description'.tr(),
|
||||||
hasBackButton: true,
|
hasBackButton: true,
|
||||||
hasFlashButton: false,
|
hasFlashButton: false,
|
||||||
|
ignoreBreakpoints: true,
|
||||||
children: [
|
children: [
|
||||||
CubitFormTextField(
|
CubitFormTextField(
|
||||||
formFieldCubit:
|
formFieldCubit:
|
||||||
|
|
|
@ -28,6 +28,7 @@ class RecoverByOldTokenInstruction extends StatelessWidget {
|
||||||
heroTitle: 'recovering.recovery_main_header'.tr(),
|
heroTitle: 'recovering.recovery_main_header'.tr(),
|
||||||
hasBackButton: true,
|
hasBackButton: true,
|
||||||
hasFlashButton: false,
|
hasFlashButton: false,
|
||||||
|
ignoreBreakpoints: true,
|
||||||
onBackButtonPressed:
|
onBackButtonPressed:
|
||||||
context.read<ServerInstallationCubit>().revertRecoveryStep,
|
context.read<ServerInstallationCubit>().revertRecoveryStep,
|
||||||
children: [
|
children: [
|
||||||
|
@ -72,6 +73,7 @@ class RecoverByOldToken extends StatelessWidget {
|
||||||
heroSubtitle: 'recovering.method_device_input_description'.tr(),
|
heroSubtitle: 'recovering.method_device_input_description'.tr(),
|
||||||
hasBackButton: true,
|
hasBackButton: true,
|
||||||
hasFlashButton: false,
|
hasFlashButton: false,
|
||||||
|
ignoreBreakpoints: true,
|
||||||
children: [
|
children: [
|
||||||
CubitFormTextField(
|
CubitFormTextField(
|
||||||
formFieldCubit:
|
formFieldCubit:
|
||||||
|
|
|
@ -31,6 +31,7 @@ class RecoverByRecoveryKey extends StatelessWidget {
|
||||||
heroSubtitle: 'recovering.method_recovery_input_description'.tr(),
|
heroSubtitle: 'recovering.method_recovery_input_description'.tr(),
|
||||||
hasBackButton: true,
|
hasBackButton: true,
|
||||||
hasFlashButton: false,
|
hasFlashButton: false,
|
||||||
|
ignoreBreakpoints: true,
|
||||||
onBackButtonPressed:
|
onBackButtonPressed:
|
||||||
context.read<ServerInstallationCubit>().revertRecoveryStep,
|
context.read<ServerInstallationCubit>().revertRecoveryStep,
|
||||||
children: [
|
children: [
|
||||||
|
|
|
@ -1,12 +1,11 @@
|
||||||
import 'package:cubit_form/cubit_form.dart';
|
import 'package:cubit_form/cubit_form.dart';
|
||||||
import 'package:easy_localization/easy_localization.dart';
|
import 'package:easy_localization/easy_localization.dart';
|
||||||
import 'package:flutter/material.dart';
|
import 'package:flutter/material.dart';
|
||||||
import 'package:selfprivacy/config/brand_theme.dart';
|
|
||||||
import 'package:selfprivacy/logic/cubit/forms/setup/initializing/backblaze_form_cubit.dart';
|
import 'package:selfprivacy/logic/cubit/forms/setup/initializing/backblaze_form_cubit.dart';
|
||||||
import 'package:selfprivacy/logic/cubit/server_installation/server_installation_cubit.dart';
|
import 'package:selfprivacy/logic/cubit/server_installation/server_installation_cubit.dart';
|
||||||
|
import 'package:selfprivacy/logic/cubit/support_system/support_system_cubit.dart';
|
||||||
import 'package:selfprivacy/ui/components/buttons/brand_button.dart';
|
import 'package:selfprivacy/ui/components/buttons/brand_button.dart';
|
||||||
import 'package:selfprivacy/ui/layouts/brand_hero_screen.dart';
|
import 'package:selfprivacy/ui/layouts/brand_hero_screen.dart';
|
||||||
import 'package:selfprivacy/ui/components/brand_md/brand_md.dart';
|
|
||||||
|
|
||||||
class RecoveryConfirmBackblaze extends StatelessWidget {
|
class RecoveryConfirmBackblaze extends StatelessWidget {
|
||||||
const RecoveryConfirmBackblaze({super.key});
|
const RecoveryConfirmBackblaze({super.key});
|
||||||
|
@ -27,6 +26,8 @@ class RecoveryConfirmBackblaze extends StatelessWidget {
|
||||||
heroTitle: 'recovering.confirm_backblaze'.tr(),
|
heroTitle: 'recovering.confirm_backblaze'.tr(),
|
||||||
heroSubtitle: 'recovering.confirm_backblaze_description'.tr(),
|
heroSubtitle: 'recovering.confirm_backblaze_description'.tr(),
|
||||||
hasBackButton: true,
|
hasBackButton: true,
|
||||||
|
ignoreBreakpoints: true,
|
||||||
|
hasSupportDrawer: true,
|
||||||
onBackButtonPressed: () {
|
onBackButtonPressed: () {
|
||||||
Navigator.of(context).popUntil((final route) => route.isFirst);
|
Navigator.of(context).popUntil((final route) => route.isFirst);
|
||||||
},
|
},
|
||||||
|
@ -56,24 +57,15 @@ class RecoveryConfirmBackblaze extends StatelessWidget {
|
||||||
text: 'basis.connect'.tr(),
|
text: 'basis.connect'.tr(),
|
||||||
),
|
),
|
||||||
const SizedBox(height: 16),
|
const SizedBox(height: 16),
|
||||||
BrandButton.text(
|
Builder(
|
||||||
onPressed: () => showModalBottomSheet<void>(
|
builder: (final context) => BrandButton.text(
|
||||||
context: context,
|
onPressed: () =>
|
||||||
isScrollControlled: true,
|
context.read<SupportSystemCubit>().showArticle(
|
||||||
backgroundColor: Colors.transparent,
|
article: 'how_backblaze',
|
||||||
builder: (final BuildContext context) => Padding(
|
context: context,
|
||||||
padding: paddingH15V0,
|
|
||||||
child: ListView(
|
|
||||||
padding: const EdgeInsets.symmetric(vertical: 16),
|
|
||||||
children: const [
|
|
||||||
BrandMarkdown(
|
|
||||||
fileName: 'how_backblaze',
|
|
||||||
),
|
),
|
||||||
],
|
title: 'initializing.how'.tr(),
|
||||||
),
|
|
||||||
),
|
|
||||||
),
|
),
|
||||||
title: 'initializing.how'.tr(),
|
|
||||||
),
|
),
|
||||||
],
|
],
|
||||||
);
|
);
|
||||||
|
|
|
@ -1,12 +1,11 @@
|
||||||
import 'package:cubit_form/cubit_form.dart';
|
import 'package:cubit_form/cubit_form.dart';
|
||||||
import 'package:easy_localization/easy_localization.dart';
|
import 'package:easy_localization/easy_localization.dart';
|
||||||
import 'package:flutter/material.dart';
|
import 'package:flutter/material.dart';
|
||||||
import 'package:selfprivacy/config/brand_theme.dart';
|
|
||||||
import 'package:selfprivacy/logic/cubit/forms/setup/initializing/dns_provider_form_cubit.dart';
|
import 'package:selfprivacy/logic/cubit/forms/setup/initializing/dns_provider_form_cubit.dart';
|
||||||
import 'package:selfprivacy/logic/cubit/server_installation/server_installation_cubit.dart';
|
import 'package:selfprivacy/logic/cubit/server_installation/server_installation_cubit.dart';
|
||||||
|
import 'package:selfprivacy/logic/cubit/support_system/support_system_cubit.dart';
|
||||||
import 'package:selfprivacy/ui/components/buttons/brand_button.dart';
|
import 'package:selfprivacy/ui/components/buttons/brand_button.dart';
|
||||||
import 'package:selfprivacy/ui/layouts/brand_hero_screen.dart';
|
import 'package:selfprivacy/ui/layouts/brand_hero_screen.dart';
|
||||||
import 'package:selfprivacy/ui/components/brand_md/brand_md.dart';
|
|
||||||
|
|
||||||
class RecoveryConfirmCloudflare extends StatelessWidget {
|
class RecoveryConfirmCloudflare extends StatelessWidget {
|
||||||
const RecoveryConfirmCloudflare({super.key});
|
const RecoveryConfirmCloudflare({super.key});
|
||||||
|
@ -30,6 +29,8 @@ class RecoveryConfirmCloudflare extends StatelessWidget {
|
||||||
),
|
),
|
||||||
hasBackButton: true,
|
hasBackButton: true,
|
||||||
hasFlashButton: false,
|
hasFlashButton: false,
|
||||||
|
ignoreBreakpoints: true,
|
||||||
|
hasSupportDrawer: true,
|
||||||
onBackButtonPressed:
|
onBackButtonPressed:
|
||||||
context.read<ServerInstallationCubit>().revertRecoveryStep,
|
context.read<ServerInstallationCubit>().revertRecoveryStep,
|
||||||
children: [
|
children: [
|
||||||
|
@ -48,24 +49,15 @@ class RecoveryConfirmCloudflare extends StatelessWidget {
|
||||||
text: 'basis.connect'.tr(),
|
text: 'basis.connect'.tr(),
|
||||||
),
|
),
|
||||||
const SizedBox(height: 16),
|
const SizedBox(height: 16),
|
||||||
BrandButton.text(
|
Builder(
|
||||||
onPressed: () => showModalBottomSheet<void>(
|
builder: (final context) => BrandButton.text(
|
||||||
context: context,
|
onPressed: () =>
|
||||||
isScrollControlled: true,
|
context.read<SupportSystemCubit>().showArticle(
|
||||||
backgroundColor: Colors.transparent,
|
article: 'how_cloudflare',
|
||||||
builder: (final BuildContext context) => Padding(
|
context: context,
|
||||||
padding: paddingH15V0,
|
),
|
||||||
child: ListView(
|
title: 'initializing.how'.tr(),
|
||||||
padding: const EdgeInsets.symmetric(vertical: 16),
|
|
||||||
children: const [
|
|
||||||
BrandMarkdown(
|
|
||||||
fileName: 'how_cloudflare',
|
|
||||||
),
|
|
||||||
],
|
|
||||||
),
|
|
||||||
),
|
|
||||||
),
|
),
|
||||||
title: 'initializing.how'.tr(),
|
|
||||||
),
|
),
|
||||||
],
|
],
|
||||||
);
|
);
|
||||||
|
|
|
@ -38,6 +38,7 @@ class _RecoveryConfirmServerState extends State<RecoveryConfirmServer> {
|
||||||
? 'recovering.choose_server_description'.tr()
|
? 'recovering.choose_server_description'.tr()
|
||||||
: 'recovering.confirm_server_description'.tr(),
|
: 'recovering.confirm_server_description'.tr(),
|
||||||
hasBackButton: true,
|
hasBackButton: true,
|
||||||
|
ignoreBreakpoints: true,
|
||||||
onBackButtonPressed: () {
|
onBackButtonPressed: () {
|
||||||
Navigator.of(context).popUntil((final route) => route.isFirst);
|
Navigator.of(context).popUntil((final route) => route.isFirst);
|
||||||
},
|
},
|
||||||
|
|
|
@ -17,6 +17,7 @@ class RecoveryMethodSelect extends StatelessWidget {
|
||||||
heroSubtitle: 'recovering.method_select_description'.tr(),
|
heroSubtitle: 'recovering.method_select_description'.tr(),
|
||||||
hasBackButton: true,
|
hasBackButton: true,
|
||||||
hasFlashButton: false,
|
hasFlashButton: false,
|
||||||
|
ignoreBreakpoints: true,
|
||||||
onBackButtonPressed:
|
onBackButtonPressed:
|
||||||
context.read<ServerInstallationCubit>().revertRecoveryStep,
|
context.read<ServerInstallationCubit>().revertRecoveryStep,
|
||||||
children: [
|
children: [
|
||||||
|
@ -74,6 +75,7 @@ class RecoveryFallbackMethodSelect extends StatelessWidget {
|
||||||
heroSubtitle: 'recovering.fallback_select_description'.tr(),
|
heroSubtitle: 'recovering.fallback_select_description'.tr(),
|
||||||
hasBackButton: true,
|
hasBackButton: true,
|
||||||
hasFlashButton: false,
|
hasFlashButton: false,
|
||||||
|
ignoreBreakpoints: true,
|
||||||
children: [
|
children: [
|
||||||
OutlinedCard(
|
OutlinedCard(
|
||||||
child: ListTile(
|
child: ListTile(
|
||||||
|
|
|
@ -112,6 +112,7 @@ class SelectDomainToRecover extends StatelessWidget {
|
||||||
heroSubtitle: 'recovering.domain_recovery_description'.tr(),
|
heroSubtitle: 'recovering.domain_recovery_description'.tr(),
|
||||||
hasBackButton: true,
|
hasBackButton: true,
|
||||||
hasFlashButton: false,
|
hasFlashButton: false,
|
||||||
|
ignoreBreakpoints: true,
|
||||||
onBackButtonPressed: () {
|
onBackButtonPressed: () {
|
||||||
Navigator.of(context).pushAndRemoveUntil(
|
Navigator.of(context).pushAndRemoveUntil(
|
||||||
materialRoute(const RootPage()),
|
materialRoute(const RootPage()),
|
||||||
|
|
|
@ -1,12 +1,11 @@
|
||||||
import 'package:easy_localization/easy_localization.dart';
|
import 'package:easy_localization/easy_localization.dart';
|
||||||
import 'package:flutter/material.dart';
|
import 'package:flutter/material.dart';
|
||||||
import 'package:selfprivacy/config/brand_theme.dart';
|
|
||||||
import 'package:selfprivacy/logic/cubit/forms/setup/initializing/provider_form_cubit.dart';
|
import 'package:selfprivacy/logic/cubit/forms/setup/initializing/provider_form_cubit.dart';
|
||||||
|
import 'package:selfprivacy/logic/cubit/support_system/support_system_cubit.dart';
|
||||||
import 'package:selfprivacy/ui/components/buttons/brand_button.dart';
|
import 'package:selfprivacy/ui/components/buttons/brand_button.dart';
|
||||||
import 'package:selfprivacy/ui/layouts/brand_hero_screen.dart';
|
import 'package:selfprivacy/ui/layouts/brand_hero_screen.dart';
|
||||||
import 'package:cubit_form/cubit_form.dart';
|
import 'package:cubit_form/cubit_form.dart';
|
||||||
import 'package:selfprivacy/logic/cubit/server_installation/server_installation_cubit.dart';
|
import 'package:selfprivacy/logic/cubit/server_installation/server_installation_cubit.dart';
|
||||||
import 'package:selfprivacy/ui/components/brand_md/brand_md.dart';
|
|
||||||
|
|
||||||
class RecoveryServerProviderConnected extends StatelessWidget {
|
class RecoveryServerProviderConnected extends StatelessWidget {
|
||||||
const RecoveryServerProviderConnected({super.key});
|
const RecoveryServerProviderConnected({super.key});
|
||||||
|
@ -30,6 +29,8 @@ class RecoveryServerProviderConnected extends StatelessWidget {
|
||||||
),
|
),
|
||||||
hasBackButton: true,
|
hasBackButton: true,
|
||||||
hasFlashButton: false,
|
hasFlashButton: false,
|
||||||
|
ignoreBreakpoints: true,
|
||||||
|
hasSupportDrawer: true,
|
||||||
onBackButtonPressed: () {
|
onBackButtonPressed: () {
|
||||||
Navigator.of(context).popUntil((final route) => route.isFirst);
|
Navigator.of(context).popUntil((final route) => route.isFirst);
|
||||||
},
|
},
|
||||||
|
@ -50,23 +51,14 @@ class RecoveryServerProviderConnected extends StatelessWidget {
|
||||||
child: Text('basis.continue'.tr()),
|
child: Text('basis.continue'.tr()),
|
||||||
),
|
),
|
||||||
const SizedBox(height: 16),
|
const SizedBox(height: 16),
|
||||||
BrandButton.text(
|
Builder(
|
||||||
title: 'initializing.how'.tr(),
|
builder: (final context) => BrandButton.text(
|
||||||
onPressed: () => showModalBottomSheet<void>(
|
title: 'initializing.how'.tr(),
|
||||||
context: context,
|
onPressed: () =>
|
||||||
isScrollControlled: true,
|
context.read<SupportSystemCubit>().showArticle(
|
||||||
backgroundColor: Colors.transparent,
|
article: 'how_hetzner',
|
||||||
builder: (final BuildContext context) => Padding(
|
context: context,
|
||||||
padding: paddingH15V0,
|
),
|
||||||
child: ListView(
|
|
||||||
padding: const EdgeInsets.symmetric(vertical: 16),
|
|
||||||
children: const [
|
|
||||||
BrandMarkdown(
|
|
||||||
fileName: 'how_hetzner',
|
|
||||||
),
|
|
||||||
],
|
|
||||||
),
|
|
||||||
),
|
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
],
|
],
|
||||||
|
|
|
@ -10,73 +10,72 @@ class ResetPassword extends StatelessWidget {
|
||||||
|
|
||||||
@override
|
@override
|
||||||
Widget build(final BuildContext context) => BlocProvider(
|
Widget build(final BuildContext context) => BlocProvider(
|
||||||
create: (final BuildContext context) => UserFormCubit(
|
create: (final BuildContext context) => UserFormCubit(
|
||||||
jobsCubit: context.read<JobsCubit>(),
|
jobsCubit: context.read<JobsCubit>(),
|
||||||
fieldFactory: FieldCubitFactory(context),
|
fieldFactory: FieldCubitFactory(context),
|
||||||
initialUser: user,
|
initialUser: user,
|
||||||
),
|
),
|
||||||
child: Builder(
|
child: Builder(
|
||||||
builder: (final BuildContext context) {
|
builder: (final BuildContext context) {
|
||||||
final FormCubitState formCubitState =
|
final FormCubitState formCubitState =
|
||||||
context.watch<UserFormCubit>().state;
|
context.watch<UserFormCubit>().state;
|
||||||
|
|
||||||
return BlocListener<UserFormCubit, FormCubitState>(
|
return BlocListener<UserFormCubit, FormCubitState>(
|
||||||
listener:
|
listener:
|
||||||
(final BuildContext context, final FormCubitState state) {
|
(final BuildContext context, final FormCubitState state) {
|
||||||
if (state.isSubmitted) {
|
if (state.isSubmitted) {
|
||||||
Navigator.pop(context);
|
Navigator.pop(context);
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
child: Column(
|
child: Column(
|
||||||
crossAxisAlignment: CrossAxisAlignment.start,
|
crossAxisAlignment: CrossAxisAlignment.start,
|
||||||
mainAxisSize: MainAxisSize.min,
|
mainAxisSize: MainAxisSize.min,
|
||||||
children: [
|
children: [
|
||||||
BrandHeader(
|
BrandHeader(
|
||||||
title: 'users.reset_password'.tr(),
|
title: 'users.reset_password'.tr(),
|
||||||
),
|
),
|
||||||
const SizedBox(width: 14),
|
const SizedBox(width: 14),
|
||||||
Padding(
|
Padding(
|
||||||
padding: paddingH15V0,
|
padding: paddingH15V0,
|
||||||
child: Column(
|
child: Column(
|
||||||
mainAxisSize: MainAxisSize.min,
|
mainAxisSize: MainAxisSize.min,
|
||||||
children: [
|
children: [
|
||||||
CubitFormTextField(
|
CubitFormTextField(
|
||||||
formFieldCubit:
|
formFieldCubit:
|
||||||
context.read<UserFormCubit>().password,
|
context.read<UserFormCubit>().password,
|
||||||
decoration: InputDecoration(
|
decoration: InputDecoration(
|
||||||
alignLabelWithHint: false,
|
alignLabelWithHint: false,
|
||||||
labelText: 'basis.password'.tr(),
|
labelText: 'basis.password'.tr(),
|
||||||
suffixIcon: Padding(
|
suffixIcon: Padding(
|
||||||
padding: const EdgeInsets.only(right: 8),
|
padding: const EdgeInsets.only(right: 8),
|
||||||
child: IconButton(
|
child: IconButton(
|
||||||
icon: Icon(
|
icon: Icon(
|
||||||
BrandIcons.refresh,
|
BrandIcons.refresh,
|
||||||
color:
|
color:
|
||||||
Theme.of(context).colorScheme.secondary,
|
Theme.of(context).colorScheme.secondary,
|
||||||
|
),
|
||||||
|
onPressed: context
|
||||||
|
.read<UserFormCubit>()
|
||||||
|
.genNewPassword,
|
||||||
|
),
|
||||||
),
|
),
|
||||||
onPressed: context
|
|
||||||
.read<UserFormCubit>()
|
|
||||||
.genNewPassword,
|
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
),
|
const SizedBox(height: 30),
|
||||||
|
BrandButton.rised(
|
||||||
|
onPressed: formCubitState.isSubmitting
|
||||||
|
? null
|
||||||
|
: () => context.read<UserFormCubit>().trySubmit(),
|
||||||
|
text: 'basis.apply'.tr(),
|
||||||
|
),
|
||||||
|
const SizedBox(height: 30),
|
||||||
|
],
|
||||||
),
|
),
|
||||||
const SizedBox(height: 30),
|
),
|
||||||
BrandButton.rised(
|
],
|
||||||
onPressed: formCubitState.isSubmitting
|
|
||||||
? null
|
|
||||||
: () =>
|
|
||||||
context.read<UserFormCubit>().trySubmit(),
|
|
||||||
text: 'basis.apply'.tr(),
|
|
||||||
),
|
|
||||||
const SizedBox(height: 30),
|
|
||||||
],
|
|
||||||
),
|
|
||||||
),
|
),
|
||||||
],
|
);
|
||||||
),
|
},
|
||||||
);
|
),
|
||||||
},
|
);
|
||||||
),
|
|
||||||
);
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -255,69 +255,68 @@ class NewSshKey extends StatelessWidget {
|
||||||
|
|
||||||
@override
|
@override
|
||||||
Widget build(final BuildContext context) => BlocProvider(
|
Widget build(final BuildContext context) => BlocProvider(
|
||||||
create: (final context) {
|
create: (final context) {
|
||||||
final jobCubit = context.read<JobsCubit>();
|
final jobCubit = context.read<JobsCubit>();
|
||||||
final jobState = jobCubit.state;
|
final jobState = jobCubit.state;
|
||||||
if (jobState is JobsStateWithJobs) {
|
if (jobState is JobsStateWithJobs) {
|
||||||
final jobs = jobState.clientJobList;
|
final jobs = jobState.clientJobList;
|
||||||
for (final job in jobs) {
|
for (final job in jobs) {
|
||||||
if (job is CreateSSHKeyJob && job.user.login == user.login) {
|
if (job is CreateSSHKeyJob && job.user.login == user.login) {
|
||||||
user.sshKeys.add(job.publicKey);
|
user.sshKeys.add(job.publicKey);
|
||||||
}
|
}
|
||||||
}
|
|
||||||
}
|
|
||||||
return SshFormCubit(
|
|
||||||
jobsCubit: jobCubit,
|
|
||||||
user: user,
|
|
||||||
);
|
|
||||||
},
|
|
||||||
child: Builder(
|
|
||||||
builder: (final context) {
|
|
||||||
final formCubitState = context.watch<SshFormCubit>().state;
|
|
||||||
|
|
||||||
return BlocListener<SshFormCubit, FormCubitState>(
|
|
||||||
listener: (final context, final state) {
|
|
||||||
if (state.isSubmitted) {
|
|
||||||
Navigator.pop(context);
|
|
||||||
}
|
}
|
||||||
},
|
}
|
||||||
child: Column(
|
return SshFormCubit(
|
||||||
crossAxisAlignment: CrossAxisAlignment.start,
|
jobsCubit: jobCubit,
|
||||||
mainAxisSize: MainAxisSize.min,
|
user: user,
|
||||||
children: [
|
);
|
||||||
BrandHeader(
|
},
|
||||||
title: user.login,
|
child: Builder(
|
||||||
),
|
builder: (final context) {
|
||||||
const SizedBox(width: 14),
|
final formCubitState = context.watch<SshFormCubit>().state;
|
||||||
Padding(
|
|
||||||
padding: paddingH15V0,
|
return BlocListener<SshFormCubit, FormCubitState>(
|
||||||
child: Column(
|
listener: (final context, final state) {
|
||||||
mainAxisSize: MainAxisSize.min,
|
if (state.isSubmitted) {
|
||||||
children: [
|
Navigator.pop(context);
|
||||||
IntrinsicHeight(
|
}
|
||||||
child: CubitFormTextField(
|
},
|
||||||
formFieldCubit: context.read<SshFormCubit>().key,
|
child: Column(
|
||||||
decoration: InputDecoration(
|
crossAxisAlignment: CrossAxisAlignment.start,
|
||||||
labelText: 'ssh.input_label'.tr(),
|
mainAxisSize: MainAxisSize.min,
|
||||||
|
children: [
|
||||||
|
BrandHeader(
|
||||||
|
title: user.login,
|
||||||
|
),
|
||||||
|
const SizedBox(width: 14),
|
||||||
|
Padding(
|
||||||
|
padding: paddingH15V0,
|
||||||
|
child: Column(
|
||||||
|
mainAxisSize: MainAxisSize.min,
|
||||||
|
children: [
|
||||||
|
IntrinsicHeight(
|
||||||
|
child: CubitFormTextField(
|
||||||
|
formFieldCubit: context.read<SshFormCubit>().key,
|
||||||
|
decoration: InputDecoration(
|
||||||
|
labelText: 'ssh.input_label'.tr(),
|
||||||
|
),
|
||||||
|
),
|
||||||
),
|
),
|
||||||
),
|
const SizedBox(height: 30),
|
||||||
|
BrandButton.rised(
|
||||||
|
onPressed: formCubitState.isSubmitting
|
||||||
|
? null
|
||||||
|
: () => context.read<SshFormCubit>().trySubmit(),
|
||||||
|
text: 'ssh.create'.tr(),
|
||||||
|
),
|
||||||
|
const SizedBox(height: 30),
|
||||||
|
],
|
||||||
),
|
),
|
||||||
const SizedBox(height: 30),
|
),
|
||||||
BrandButton.rised(
|
],
|
||||||
onPressed: formCubitState.isSubmitting
|
|
||||||
? null
|
|
||||||
: () =>
|
|
||||||
context.read<SshFormCubit>().trySubmit(),
|
|
||||||
text: 'ssh.create'.tr(),
|
|
||||||
),
|
|
||||||
const SizedBox(height: 30),
|
|
||||||
],
|
|
||||||
),
|
|
||||||
),
|
),
|
||||||
],
|
);
|
||||||
),
|
},
|
||||||
);
|
),
|
||||||
},
|
);
|
||||||
),
|
|
||||||
);
|
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in a new issue