mirror of
https://git.selfprivacy.org/kherel/selfprivacy.org.app.git
synced 2025-01-08 00:51:20 +00:00
refactor(ui): Refactor Devices screen UI
This commit is contained in:
parent
1168b2219f
commit
c17d87c348
|
@ -249,7 +249,7 @@
|
|||
"autobackup_period_disable": "Disable automatic backups",
|
||||
"autobackup_set_period": "Set period",
|
||||
"backups_encryption_key": "Encryption key",
|
||||
"backups_encryption_key_subtitle": "Keep it in a safe place.",
|
||||
"backups_encryption_key_subtitle": "Keep it in a safe place",
|
||||
"backups_encryption_key_copy": "Copy the encryption key",
|
||||
"backups_encryption_key_show": "Show the encryption key",
|
||||
"backups_encryption_key_description": "This key is used to encrypt your backups. If you lose it, you will not be able to restore your backups. Keep it in a safe place, as it will be useful if you ever need to restore from backups manually.",
|
||||
|
@ -598,7 +598,6 @@
|
|||
"key_replace_button": "Generate new key",
|
||||
"key_receiving_description": "Write down this key and put to a safe place. It is used to restore full access to your server:",
|
||||
"key_receiving_info": "The key will never ever be shown again, but you will be able to replace it with another one.",
|
||||
"key_receiving_done": "Done!",
|
||||
"generation_error": "Couldn't generate a recovery key. {}"
|
||||
},
|
||||
"modals": {
|
||||
|
|
|
@ -1,15 +1,14 @@
|
|||
import 'package:easy_localization/easy_localization.dart';
|
||||
import 'package:flutter/material.dart';
|
||||
|
||||
class SectionHeadline extends StatelessWidget {
|
||||
const SectionHeadline({
|
||||
required this.title,
|
||||
required this.subtitle,
|
||||
this.subtitle,
|
||||
super.key,
|
||||
});
|
||||
|
||||
final String title;
|
||||
final String subtitle;
|
||||
final String? subtitle;
|
||||
|
||||
@override
|
||||
Widget build(final BuildContext context) => ListTile(
|
||||
|
@ -19,9 +18,11 @@ class SectionHeadline extends StatelessWidget {
|
|||
color: Theme.of(context).colorScheme.secondary,
|
||||
),
|
||||
),
|
||||
subtitle: Text(
|
||||
subtitle,
|
||||
style: Theme.of(context).textTheme.labelMedium,
|
||||
),
|
||||
subtitle: subtitle != null
|
||||
? Text(
|
||||
subtitle!,
|
||||
style: Theme.of(context).textTheme.labelMedium,
|
||||
)
|
||||
: null,
|
||||
);
|
||||
}
|
||||
|
|
|
@ -12,7 +12,10 @@ class SectionTitle extends StatelessWidget {
|
|||
|
||||
@override
|
||||
Widget build(final BuildContext context) => Padding(
|
||||
padding: const EdgeInsets.all(16),
|
||||
padding: const EdgeInsets.symmetric(
|
||||
horizontal: 16.0,
|
||||
vertical: 8.0,
|
||||
),
|
||||
child: Text(
|
||||
title,
|
||||
style: Theme.of(context).textTheme.labelLarge!.copyWith(
|
||||
|
|
|
@ -19,7 +19,10 @@ class BrandHeroScreen extends StatelessWidget {
|
|||
this.heroTitle = '',
|
||||
this.heroSubtitle,
|
||||
this.onBackButtonPressed,
|
||||
this.bodyPadding = const EdgeInsets.all(16.0),
|
||||
this.bodyPadding = const EdgeInsets.symmetric(
|
||||
vertical: 16.0,
|
||||
horizontal: 8.0,
|
||||
),
|
||||
this.ignoreBreakpoints = false,
|
||||
this.hasSupportDrawer = false,
|
||||
});
|
||||
|
@ -80,7 +83,7 @@ class BrandHeroScreen extends StatelessWidget {
|
|||
style: Theme.of(context).textTheme.bodyMedium!.copyWith(
|
||||
color: Theme.of(context).colorScheme.onSurface,
|
||||
),
|
||||
textAlign: hasHeroIcon ? TextAlign.center : TextAlign.start,
|
||||
textAlign: TextAlign.center,
|
||||
),
|
||||
]),
|
||||
),
|
||||
|
|
131
lib/ui/molecules/list_items/device_item.dart
Normal file
131
lib/ui/molecules/list_items/device_item.dart
Normal file
|
@ -0,0 +1,131 @@
|
|||
import 'package:cubit_form/cubit_form.dart';
|
||||
import 'package:easy_localization/easy_localization.dart';
|
||||
import 'package:flutter/material.dart';
|
||||
import 'package:selfprivacy/logic/bloc/devices/devices_bloc.dart';
|
||||
import 'package:selfprivacy/logic/bloc/tokens/tokens_bloc.dart';
|
||||
import 'package:selfprivacy/logic/cubit/server_installation/server_installation_cubit.dart';
|
||||
import 'package:selfprivacy/logic/models/json/api_token.dart';
|
||||
|
||||
class DeviceItem extends StatelessWidget {
|
||||
const DeviceItem({
|
||||
required this.device,
|
||||
super.key,
|
||||
});
|
||||
|
||||
final ApiToken device;
|
||||
|
||||
@override
|
||||
Widget build(final BuildContext context) => ListTile(
|
||||
title: Text(device.name),
|
||||
subtitle: Text(
|
||||
'devices.main_screen.access_granted_on'
|
||||
.tr(args: [DateFormat.yMMMMd().format(device.date)]),
|
||||
),
|
||||
onTap: device.isCaller
|
||||
? () => _showTokenRefreshDialog(context, device)
|
||||
: () => _showConfirmationDialog(context, device),
|
||||
);
|
||||
|
||||
Future _showConfirmationDialog(
|
||||
final BuildContext context,
|
||||
final ApiToken device,
|
||||
) =>
|
||||
showDialog(
|
||||
context: context,
|
||||
builder: (final context) => AlertDialog(
|
||||
title: Column(
|
||||
crossAxisAlignment: CrossAxisAlignment.center,
|
||||
children: [
|
||||
const Icon(Icons.link_off_outlined),
|
||||
const SizedBox(height: 16),
|
||||
Text(
|
||||
'devices.revoke_device_alert.header'.tr(),
|
||||
style: Theme.of(context).textTheme.headlineSmall,
|
||||
textAlign: TextAlign.center,
|
||||
),
|
||||
],
|
||||
),
|
||||
content: Column(
|
||||
mainAxisSize: MainAxisSize.min,
|
||||
crossAxisAlignment: CrossAxisAlignment.start,
|
||||
children: <Widget>[
|
||||
Text(
|
||||
'devices.revoke_device_alert.description'
|
||||
.tr(args: [device.name]),
|
||||
style: Theme.of(context).textTheme.bodyMedium,
|
||||
),
|
||||
],
|
||||
),
|
||||
actions: <Widget>[
|
||||
TextButton(
|
||||
child: Text('devices.revoke_device_alert.no'.tr()),
|
||||
onPressed: () {
|
||||
Navigator.of(context).pop();
|
||||
},
|
||||
),
|
||||
TextButton(
|
||||
child: Text(
|
||||
'devices.revoke_device_alert.yes'.tr(),
|
||||
style: Theme.of(context).textTheme.labelLarge?.copyWith(
|
||||
color: Theme.of(context).colorScheme.error,
|
||||
),
|
||||
),
|
||||
onPressed: () {
|
||||
context.read<DevicesBloc>().add(DeleteDevice(device));
|
||||
Navigator.of(context).pop();
|
||||
},
|
||||
),
|
||||
],
|
||||
),
|
||||
);
|
||||
|
||||
Future _showTokenRefreshDialog(
|
||||
final BuildContext context,
|
||||
final ApiToken device,
|
||||
) =>
|
||||
showDialog(
|
||||
context: context,
|
||||
builder: (final context) => AlertDialog(
|
||||
title: Column(
|
||||
crossAxisAlignment: CrossAxisAlignment.center,
|
||||
children: [
|
||||
const Icon(Icons.update_outlined),
|
||||
const SizedBox(height: 16),
|
||||
Text(
|
||||
'devices.refresh_token_alert.header'.tr(),
|
||||
style: Theme.of(context).textTheme.headlineSmall,
|
||||
textAlign: TextAlign.center,
|
||||
),
|
||||
],
|
||||
),
|
||||
content: Column(
|
||||
mainAxisSize: MainAxisSize.min,
|
||||
crossAxisAlignment: CrossAxisAlignment.start,
|
||||
children: <Widget>[
|
||||
Text(
|
||||
'devices.refresh_token_alert.description'
|
||||
.tr(args: [device.name]),
|
||||
style: Theme.of(context).textTheme.bodyMedium,
|
||||
),
|
||||
],
|
||||
),
|
||||
actions: <Widget>[
|
||||
TextButton(
|
||||
child: Text('devices.refresh_token_alert.no'.tr()),
|
||||
onPressed: () {
|
||||
Navigator.of(context).pop();
|
||||
},
|
||||
),
|
||||
TextButton(
|
||||
child: Text('devices.refresh_token_alert.yes'.tr()),
|
||||
onPressed: () {
|
||||
context
|
||||
.read<TokensBloc>()
|
||||
.add(const RefreshServerApiTokenEvent());
|
||||
Navigator.of(context).pop();
|
||||
},
|
||||
),
|
||||
],
|
||||
),
|
||||
);
|
||||
}
|
60
lib/ui/organisms/displays/key_display.dart
Normal file
60
lib/ui/organisms/displays/key_display.dart
Normal file
|
@ -0,0 +1,60 @@
|
|||
import 'package:easy_localization/easy_localization.dart';
|
||||
import 'package:flutter/material.dart';
|
||||
import 'package:selfprivacy/ui/atoms/buttons/brand_button.dart';
|
||||
import 'package:selfprivacy/ui/molecules/info_box/info_box.dart';
|
||||
|
||||
class KeyDisplay extends StatelessWidget {
|
||||
const KeyDisplay({
|
||||
required this.keyToDisplay,
|
||||
required this.canCopy,
|
||||
required this.infoboxText,
|
||||
super.key,
|
||||
});
|
||||
|
||||
final String keyToDisplay;
|
||||
final bool canCopy;
|
||||
final String infoboxText;
|
||||
|
||||
@override
|
||||
Widget build(final BuildContext context) => Column(
|
||||
crossAxisAlignment: CrossAxisAlignment.start,
|
||||
children: [
|
||||
const Divider(),
|
||||
const SizedBox(height: 16),
|
||||
if (canCopy)
|
||||
SelectableText(
|
||||
keyToDisplay,
|
||||
style: Theme.of(context).textTheme.bodyLarge!.copyWith(
|
||||
fontSize: 24,
|
||||
fontFamily: 'RobotoMono',
|
||||
),
|
||||
textAlign: TextAlign.center,
|
||||
),
|
||||
if (!canCopy)
|
||||
Text(
|
||||
keyToDisplay,
|
||||
style: Theme.of(context).textTheme.bodyLarge!.copyWith(
|
||||
fontSize: 24,
|
||||
fontFamily: 'RobotoMono',
|
||||
),
|
||||
textAlign: TextAlign.center,
|
||||
),
|
||||
const SizedBox(height: 16),
|
||||
const Divider(),
|
||||
const SizedBox(height: 16),
|
||||
InfoBox(
|
||||
text: infoboxText,
|
||||
),
|
||||
const SizedBox(height: 16),
|
||||
BrandButton.filled(
|
||||
child: Text(
|
||||
'basis.done'.tr(),
|
||||
),
|
||||
onPressed: () {
|
||||
Navigator.of(context).popUntil((final route) => route.isFirst);
|
||||
},
|
||||
),
|
||||
const SizedBox(height: 24),
|
||||
],
|
||||
);
|
||||
}
|
|
@ -257,13 +257,8 @@ class BackupDetailsPage extends StatelessWidget {
|
|||
Column(
|
||||
crossAxisAlignment: CrossAxisAlignment.start,
|
||||
children: [
|
||||
ListTile(
|
||||
title: Text(
|
||||
'backup.pending_jobs'.tr(),
|
||||
style: Theme.of(context).textTheme.headlineSmall!.copyWith(
|
||||
color: Theme.of(context).colorScheme.secondary,
|
||||
),
|
||||
),
|
||||
SectionHeadline(
|
||||
title: 'backup.pending_jobs'.tr(),
|
||||
),
|
||||
for (final job in backupJobs)
|
||||
Padding(
|
||||
|
@ -312,7 +307,6 @@ class BackupDetailsPage extends StatelessWidget {
|
|||
ListTile(
|
||||
title: Text(
|
||||
'backup.show_more'.tr(),
|
||||
style: Theme.of(context).textTheme.labelMedium,
|
||||
),
|
||||
leading: const Icon(
|
||||
Icons.arrow_drop_down,
|
||||
|
@ -345,6 +339,7 @@ class BackupDetailsPage extends StatelessWidget {
|
|||
Icons.cached_outlined,
|
||||
color: overrideColor,
|
||||
),
|
||||
isThreeLine: true,
|
||||
onTap: preventActions
|
||||
? null
|
||||
: () => context
|
||||
|
|
|
@ -3,23 +3,22 @@ import 'package:cubit_form/cubit_form.dart';
|
|||
import 'package:easy_localization/easy_localization.dart';
|
||||
import 'package:flutter/material.dart';
|
||||
import 'package:selfprivacy/logic/bloc/devices/devices_bloc.dart';
|
||||
import 'package:selfprivacy/logic/bloc/tokens/tokens_bloc.dart';
|
||||
import 'package:selfprivacy/logic/cubit/server_installation/server_installation_cubit.dart';
|
||||
import 'package:selfprivacy/logic/models/json/api_token.dart';
|
||||
import 'package:selfprivacy/ui/atoms/list_tiles/section_title.dart';
|
||||
import 'package:selfprivacy/ui/layouts/brand_hero_screen.dart';
|
||||
import 'package:selfprivacy/ui/molecules/info_box/info_box.dart';
|
||||
import 'package:selfprivacy/ui/pages/devices/new_device.dart';
|
||||
import 'package:selfprivacy/utils/route_transitions/basic.dart';
|
||||
import 'package:selfprivacy/ui/molecules/list_items/device_item.dart';
|
||||
import 'package:selfprivacy/ui/router/router.dart';
|
||||
|
||||
@RoutePage()
|
||||
class DevicesScreen extends StatefulWidget {
|
||||
const DevicesScreen({super.key});
|
||||
class DevicesPage extends StatefulWidget {
|
||||
const DevicesPage({super.key});
|
||||
|
||||
@override
|
||||
State<DevicesScreen> createState() => _DevicesScreenState();
|
||||
State<DevicesPage> createState() => _DevicesPageState();
|
||||
}
|
||||
|
||||
class _DevicesScreenState extends State<DevicesScreen> {
|
||||
class _DevicesPageState extends State<DevicesPage> {
|
||||
@override
|
||||
Widget build(final BuildContext context) {
|
||||
final DevicesState devicesStatus = context.watch<DevicesBloc>().state;
|
||||
|
@ -31,6 +30,7 @@ class _DevicesScreenState extends State<DevicesScreen> {
|
|||
child: BrandHeroScreen(
|
||||
heroTitle: 'devices.main_screen.header'.tr(),
|
||||
heroSubtitle: 'devices.main_screen.description'.tr(),
|
||||
heroIcon: Icons.devices_outlined,
|
||||
hasBackButton: true,
|
||||
hasFlashButton: false,
|
||||
children: [
|
||||
|
@ -46,8 +46,7 @@ class _DevicesScreenState extends State<DevicesScreen> {
|
|||
),
|
||||
const SizedBox(height: 16),
|
||||
OutlinedButton(
|
||||
onPressed: () => Navigator.of(context)
|
||||
.push(materialRoute(const NewDeviceScreen())),
|
||||
onPressed: () => context.pushRoute(const NewDeviceRoute()),
|
||||
child: Text('devices.main_screen.authorize_new_device'.tr()),
|
||||
),
|
||||
const SizedBox(height: 16),
|
||||
|
@ -75,22 +74,17 @@ class _DevicesInfo extends StatelessWidget {
|
|||
Widget build(final BuildContext context) => Column(
|
||||
crossAxisAlignment: CrossAxisAlignment.start,
|
||||
children: [
|
||||
Text(
|
||||
'devices.main_screen.this_device'.tr(),
|
||||
style: Theme.of(context).textTheme.labelLarge!.copyWith(
|
||||
color: Theme.of(context).colorScheme.secondary,
|
||||
),
|
||||
SectionTitle(
|
||||
title: 'devices.main_screen.this_device'.tr(),
|
||||
),
|
||||
_DeviceTile(
|
||||
DeviceItem(
|
||||
device: devicesStatus.thisDevice,
|
||||
),
|
||||
const SizedBox(height: 8),
|
||||
const Divider(height: 1),
|
||||
const SizedBox(height: 16),
|
||||
Text(
|
||||
'devices.main_screen.other_devices'.tr(),
|
||||
style: Theme.of(context).textTheme.labelLarge!.copyWith(
|
||||
color: Theme.of(context).colorScheme.secondary,
|
||||
),
|
||||
const SizedBox(height: 8),
|
||||
SectionTitle(
|
||||
title: 'devices.main_screen.other_devices'.tr(),
|
||||
),
|
||||
if (devicesStatus is DevicesDeleting) ...[
|
||||
const Center(
|
||||
|
@ -100,127 +94,10 @@ class _DevicesInfo extends StatelessWidget {
|
|||
],
|
||||
if (devicesStatus is! DevicesDeleting)
|
||||
...devicesStatus.otherDevices.map(
|
||||
(final device) => _DeviceTile(
|
||||
(final device) => DeviceItem(
|
||||
device: device,
|
||||
),
|
||||
),
|
||||
],
|
||||
);
|
||||
}
|
||||
|
||||
class _DeviceTile extends StatelessWidget {
|
||||
const _DeviceTile({required this.device});
|
||||
|
||||
final ApiToken device;
|
||||
|
||||
@override
|
||||
Widget build(final BuildContext context) => ListTile(
|
||||
contentPadding: EdgeInsets.zero,
|
||||
title: Text(device.name),
|
||||
subtitle: Text(
|
||||
'devices.main_screen.access_granted_on'
|
||||
.tr(args: [DateFormat.yMMMMd().format(device.date)]),
|
||||
),
|
||||
onTap: device.isCaller
|
||||
? () => _showTokenRefreshDialog(context, device)
|
||||
: () => _showConfirmationDialog(context, device),
|
||||
);
|
||||
|
||||
Future _showConfirmationDialog(
|
||||
final BuildContext context,
|
||||
final ApiToken device,
|
||||
) =>
|
||||
showDialog(
|
||||
context: context,
|
||||
builder: (final context) => AlertDialog(
|
||||
title: Column(
|
||||
crossAxisAlignment: CrossAxisAlignment.center,
|
||||
children: [
|
||||
const Icon(Icons.link_off_outlined),
|
||||
const SizedBox(height: 16),
|
||||
Text(
|
||||
'devices.revoke_device_alert.header'.tr(),
|
||||
style: Theme.of(context).textTheme.headlineSmall,
|
||||
textAlign: TextAlign.center,
|
||||
),
|
||||
],
|
||||
),
|
||||
content: Column(
|
||||
mainAxisSize: MainAxisSize.min,
|
||||
crossAxisAlignment: CrossAxisAlignment.start,
|
||||
children: <Widget>[
|
||||
Text(
|
||||
'devices.revoke_device_alert.description'
|
||||
.tr(args: [device.name]),
|
||||
style: Theme.of(context).textTheme.bodyMedium,
|
||||
),
|
||||
],
|
||||
),
|
||||
actions: <Widget>[
|
||||
TextButton(
|
||||
child: Text('devices.revoke_device_alert.no'.tr()),
|
||||
onPressed: () {
|
||||
Navigator.of(context).pop();
|
||||
},
|
||||
),
|
||||
TextButton(
|
||||
child: Text('devices.revoke_device_alert.yes'.tr()),
|
||||
onPressed: () {
|
||||
context.read<DevicesBloc>().add(DeleteDevice(device));
|
||||
Navigator.of(context).pop();
|
||||
},
|
||||
),
|
||||
],
|
||||
),
|
||||
);
|
||||
|
||||
Future _showTokenRefreshDialog(
|
||||
final BuildContext context,
|
||||
final ApiToken device,
|
||||
) =>
|
||||
showDialog(
|
||||
context: context,
|
||||
builder: (final context) => AlertDialog(
|
||||
title: Column(
|
||||
crossAxisAlignment: CrossAxisAlignment.center,
|
||||
children: [
|
||||
const Icon(Icons.update_outlined),
|
||||
const SizedBox(height: 16),
|
||||
Text(
|
||||
'devices.refresh_token_alert.header'.tr(),
|
||||
style: Theme.of(context).textTheme.headlineSmall,
|
||||
textAlign: TextAlign.center,
|
||||
),
|
||||
],
|
||||
),
|
||||
content: Column(
|
||||
mainAxisSize: MainAxisSize.min,
|
||||
crossAxisAlignment: CrossAxisAlignment.start,
|
||||
children: <Widget>[
|
||||
Text(
|
||||
'devices.refresh_token_alert.description'
|
||||
.tr(args: [device.name]),
|
||||
style: Theme.of(context).textTheme.bodyMedium,
|
||||
),
|
||||
],
|
||||
),
|
||||
actions: <Widget>[
|
||||
TextButton(
|
||||
child: Text('devices.refresh_token_alert.no'.tr()),
|
||||
onPressed: () {
|
||||
Navigator.of(context).pop();
|
||||
},
|
||||
),
|
||||
TextButton(
|
||||
child: Text('devices.refresh_token_alert.yes'.tr()),
|
||||
onPressed: () {
|
||||
context
|
||||
.read<TokensBloc>()
|
||||
.add(const RefreshServerApiTokenEvent());
|
||||
Navigator.of(context).pop();
|
||||
},
|
||||
),
|
||||
],
|
||||
),
|
||||
);
|
||||
}
|
||||
|
|
|
@ -1,13 +1,15 @@
|
|||
import 'package:auto_route/auto_route.dart';
|
||||
import 'package:cubit_form/cubit_form.dart';
|
||||
import 'package:easy_localization/easy_localization.dart';
|
||||
import 'package:flutter/material.dart';
|
||||
import 'package:selfprivacy/logic/bloc/devices/devices_bloc.dart';
|
||||
import 'package:selfprivacy/logic/cubit/server_installation/server_installation_cubit.dart';
|
||||
import 'package:selfprivacy/ui/atoms/buttons/brand_button.dart';
|
||||
import 'package:selfprivacy/ui/layouts/brand_hero_screen.dart';
|
||||
import 'package:selfprivacy/ui/organisms/displays/key_display.dart';
|
||||
|
||||
class NewDeviceScreen extends StatelessWidget {
|
||||
const NewDeviceScreen({super.key});
|
||||
@RoutePage()
|
||||
class NewDevicePage extends StatelessWidget {
|
||||
const NewDevicePage({super.key});
|
||||
|
||||
@override
|
||||
Widget build(final BuildContext context) => BrandHeroScreen(
|
||||
|
@ -23,8 +25,10 @@ class NewDeviceScreen extends StatelessWidget {
|
|||
final AsyncSnapshot<Object?> snapshot,
|
||||
) {
|
||||
if (snapshot.hasData) {
|
||||
return _KeyDisplay(
|
||||
newDeviceKey: snapshot.data.toString(),
|
||||
return KeyDisplay(
|
||||
keyToDisplay: snapshot.data.toString(),
|
||||
canCopy: true,
|
||||
infoboxText: 'devices.add_new_device_screen.tip'.tr(),
|
||||
);
|
||||
} else {
|
||||
return const Center(
|
||||
|
@ -36,51 +40,3 @@ class NewDeviceScreen extends StatelessWidget {
|
|||
],
|
||||
);
|
||||
}
|
||||
|
||||
class _KeyDisplay extends StatelessWidget {
|
||||
const _KeyDisplay({required this.newDeviceKey});
|
||||
|
||||
final String newDeviceKey;
|
||||
|
||||
@override
|
||||
Widget build(final BuildContext context) => Column(
|
||||
crossAxisAlignment: CrossAxisAlignment.start,
|
||||
children: [
|
||||
const Divider(),
|
||||
const SizedBox(height: 16),
|
||||
SelectableText(
|
||||
newDeviceKey,
|
||||
style: Theme.of(context).textTheme.bodyLarge!.copyWith(
|
||||
fontSize: 24,
|
||||
fontFamily: 'RobotoMono',
|
||||
),
|
||||
textAlign: TextAlign.center,
|
||||
),
|
||||
const SizedBox(height: 16),
|
||||
const Divider(),
|
||||
const SizedBox(height: 16),
|
||||
Column(
|
||||
crossAxisAlignment: CrossAxisAlignment.start,
|
||||
children: [
|
||||
Icon(
|
||||
Icons.info_outline,
|
||||
color: Theme.of(context).colorScheme.onSurface,
|
||||
),
|
||||
const SizedBox(height: 16),
|
||||
Text(
|
||||
'devices.add_new_device_screen.tip'.tr(),
|
||||
style: Theme.of(context).textTheme.bodyMedium,
|
||||
),
|
||||
],
|
||||
),
|
||||
const SizedBox(height: 16),
|
||||
BrandButton.filled(
|
||||
child: Text(
|
||||
'basis.done'.tr(),
|
||||
),
|
||||
onPressed: () => Navigator.of(context).pop(),
|
||||
),
|
||||
const SizedBox(height: 24),
|
||||
],
|
||||
);
|
||||
}
|
||||
|
|
|
@ -43,7 +43,6 @@ class AboutApplicationPage extends StatelessWidget {
|
|||
hasBackButton: true,
|
||||
hasFlashButton: false,
|
||||
heroTitle: 'about_application_page.title'.tr(),
|
||||
bodyPadding: const EdgeInsets.symmetric(vertical: 16),
|
||||
children: [
|
||||
SectionTitle(title: 'about_application_page.versions'.tr()),
|
||||
FutureBuilder(
|
||||
|
|
|
@ -25,7 +25,6 @@ class _DeveloperSettingsPageState extends State<DeveloperSettingsPage> {
|
|||
Widget build(final BuildContext context) => BrandHeroScreen(
|
||||
hasBackButton: true,
|
||||
hasFlashButton: false,
|
||||
bodyPadding: const EdgeInsets.symmetric(vertical: 16),
|
||||
heroTitle: 'developer_settings.title'.tr(),
|
||||
heroSubtitle: 'developer_settings.subtitle'.tr(),
|
||||
children: [
|
||||
|
|
|
@ -250,7 +250,7 @@ class _RecoveryKeyConfigurationState extends State<RecoveryKeyConfiguration> {
|
|||
});
|
||||
await Navigator.of(context).push(
|
||||
materialRoute(
|
||||
RecoveryKeyReceiving(recoveryKey: token),
|
||||
NewRecoveryKeyPage(recoveryKey: token),
|
||||
),
|
||||
);
|
||||
} on GenerationError catch (e) {
|
||||
|
|
|
@ -1,11 +1,10 @@
|
|||
import 'package:easy_localization/easy_localization.dart';
|
||||
import 'package:flutter/material.dart';
|
||||
import 'package:selfprivacy/ui/atoms/buttons/brand_button.dart';
|
||||
import 'package:selfprivacy/ui/layouts/brand_hero_screen.dart';
|
||||
import 'package:selfprivacy/ui/molecules/info_box/info_box.dart';
|
||||
import 'package:selfprivacy/ui/organisms/displays/key_display.dart';
|
||||
|
||||
class RecoveryKeyReceiving extends StatelessWidget {
|
||||
const RecoveryKeyReceiving({required this.recoveryKey, super.key});
|
||||
class NewRecoveryKeyPage extends StatelessWidget {
|
||||
const NewRecoveryKeyPage({required this.recoveryKey, super.key});
|
||||
|
||||
final String recoveryKey;
|
||||
|
||||
|
@ -16,28 +15,10 @@ class RecoveryKeyReceiving extends StatelessWidget {
|
|||
hasBackButton: false,
|
||||
hasFlashButton: false,
|
||||
children: [
|
||||
const Divider(),
|
||||
const SizedBox(height: 16),
|
||||
Text(
|
||||
recoveryKey,
|
||||
style: Theme.of(context).textTheme.bodyLarge!.copyWith(
|
||||
fontSize: 24,
|
||||
fontFamily: 'RobotoMono',
|
||||
),
|
||||
textAlign: TextAlign.center,
|
||||
),
|
||||
const SizedBox(height: 16),
|
||||
const Divider(),
|
||||
const SizedBox(height: 16),
|
||||
InfoBox(
|
||||
text: 'recovery_key.key_receiving_info'.tr(),
|
||||
),
|
||||
const SizedBox(height: 16),
|
||||
BrandButton.filled(
|
||||
child: Text('recovery_key.key_receiving_done'.tr()),
|
||||
onPressed: () {
|
||||
Navigator.of(context).popUntil((final route) => route.isFirst);
|
||||
},
|
||||
KeyDisplay(
|
||||
keyToDisplay: recoveryKey,
|
||||
canCopy: false,
|
||||
infoboxText: 'recovery_key.key_receiving_info'.tr(),
|
||||
),
|
||||
],
|
||||
);
|
||||
|
|
|
@ -7,6 +7,7 @@ import 'package:selfprivacy/logic/models/service.dart';
|
|||
import 'package:selfprivacy/ui/pages/backups/backup_details.dart';
|
||||
import 'package:selfprivacy/ui/pages/backups/backups_list.dart';
|
||||
import 'package:selfprivacy/ui/pages/devices/devices.dart';
|
||||
import 'package:selfprivacy/ui/pages/devices/new_device.dart';
|
||||
import 'package:selfprivacy/ui/pages/dns_details/dns_details.dart';
|
||||
import 'package:selfprivacy/ui/pages/more/about_application.dart';
|
||||
import 'package:selfprivacy/ui/pages/more/app_settings/app_settings.dart';
|
||||
|
@ -101,6 +102,7 @@ class RootRouter extends RootStackRouter {
|
|||
AutoRoute(page: NewUserRoute.page),
|
||||
AutoRoute(page: RecoveryKeyRoute.page),
|
||||
AutoRoute(page: DevicesRoute.page),
|
||||
AutoRoute(page: NewDeviceRoute.page),
|
||||
AutoRoute(page: AboutApplicationRoute.page),
|
||||
AutoRoute(page: DeveloperSettingsRoute.page),
|
||||
AutoRoute(page: ServiceRoute.page),
|
||||
|
|
|
@ -198,7 +198,7 @@ class DeveloperSettingsRoute extends PageRouteInfo<void> {
|
|||
}
|
||||
|
||||
/// generated route for
|
||||
/// [DevicesScreen]
|
||||
/// [DevicesPage]
|
||||
class DevicesRoute extends PageRouteInfo<void> {
|
||||
const DevicesRoute({List<PageRouteInfo>? children})
|
||||
: super(
|
||||
|
@ -211,7 +211,7 @@ class DevicesRoute extends PageRouteInfo<void> {
|
|||
static PageInfo page = PageInfo(
|
||||
name,
|
||||
builder: (data) {
|
||||
return const DevicesScreen();
|
||||
return const DevicesPage();
|
||||
},
|
||||
);
|
||||
}
|
||||
|
@ -344,6 +344,25 @@ class MoreRoute extends PageRouteInfo<void> {
|
|||
);
|
||||
}
|
||||
|
||||
/// generated route for
|
||||
/// [NewDevicePage]
|
||||
class NewDeviceRoute extends PageRouteInfo<void> {
|
||||
const NewDeviceRoute({List<PageRouteInfo>? children})
|
||||
: super(
|
||||
NewDeviceRoute.name,
|
||||
initialChildren: children,
|
||||
);
|
||||
|
||||
static const String name = 'NewDeviceRoute';
|
||||
|
||||
static PageInfo page = PageInfo(
|
||||
name,
|
||||
builder: (data) {
|
||||
return const NewDevicePage();
|
||||
},
|
||||
);
|
||||
}
|
||||
|
||||
/// generated route for
|
||||
/// [NewUserPage]
|
||||
class NewUserRoute extends PageRouteInfo<void> {
|
||||
|
|
Loading…
Reference in a new issue