mirror of
https://git.selfprivacy.org/kherel/selfprivacy.org.app.git
synced 2024-11-05 00:13:12 +00:00
Merge pull request 'feat: Implement copying to clipboard for snapshot id of backups' (#325) from snapshot-id into master
Reviewed-on: https://git.selfprivacy.org/SelfPrivacy/selfprivacy.org.app/pulls/325 Reviewed-by: Inex Code <inex.code@selfprivacy.org>
This commit is contained in:
commit
fd13828ec3
|
@ -21,11 +21,12 @@ class NavigationService {
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
void showSnackBar(final String text) {
|
void showSnackBar(final String text, {final SnackBarBehavior? behavior}) {
|
||||||
final ScaffoldMessengerState state = scaffoldMessengerKey.currentState!;
|
final ScaffoldMessengerState state = scaffoldMessengerKey.currentState!;
|
||||||
final SnackBar snack = SnackBar(
|
final SnackBar snack = SnackBar(
|
||||||
content: Text(text),
|
content: Text(text),
|
||||||
duration: const Duration(seconds: 2),
|
duration: const Duration(seconds: 2),
|
||||||
|
behavior: behavior,
|
||||||
);
|
);
|
||||||
state.showSnackBar(snack);
|
state.showSnackBar(snack);
|
||||||
}
|
}
|
||||||
|
|
30
lib/ui/pages/backups/snapshot_id_list_tile.dart
Normal file
30
lib/ui/pages/backups/snapshot_id_list_tile.dart
Normal file
|
@ -0,0 +1,30 @@
|
||||||
|
import 'package:easy_localization/easy_localization.dart';
|
||||||
|
import 'package:flutter/material.dart';
|
||||||
|
import 'package:flutter/services.dart';
|
||||||
|
import 'package:selfprivacy/config/get_it_config.dart';
|
||||||
|
|
||||||
|
class SnapshotIdListTile extends StatelessWidget {
|
||||||
|
const SnapshotIdListTile({
|
||||||
|
required this.snapshotId,
|
||||||
|
super.key,
|
||||||
|
});
|
||||||
|
|
||||||
|
final String snapshotId;
|
||||||
|
|
||||||
|
@override
|
||||||
|
Widget build(final BuildContext context) => ListTile(
|
||||||
|
onLongPress: () {
|
||||||
|
Clipboard.setData(ClipboardData(text: snapshotId));
|
||||||
|
getIt<NavigationService>().showSnackBar(
|
||||||
|
'basis.copied_to_clipboard'.tr(),
|
||||||
|
behavior: SnackBarBehavior.floating,
|
||||||
|
);
|
||||||
|
},
|
||||||
|
leading: Icon(
|
||||||
|
Icons.numbers_outlined,
|
||||||
|
color: Theme.of(context).colorScheme.onSurface,
|
||||||
|
),
|
||||||
|
title: Text('backup.snapshot_id_title'.tr()),
|
||||||
|
subtitle: Text(snapshotId),
|
||||||
|
);
|
||||||
|
}
|
|
@ -11,6 +11,7 @@ import 'package:selfprivacy/logic/models/service.dart';
|
||||||
import 'package:selfprivacy/ui/components/buttons/brand_button.dart';
|
import 'package:selfprivacy/ui/components/buttons/brand_button.dart';
|
||||||
import 'package:selfprivacy/ui/components/cards/outlined_card.dart';
|
import 'package:selfprivacy/ui/components/cards/outlined_card.dart';
|
||||||
import 'package:selfprivacy/ui/components/info_box/info_box.dart';
|
import 'package:selfprivacy/ui/components/info_box/info_box.dart';
|
||||||
|
import 'package:selfprivacy/ui/pages/backups/snapshot_id_list_tile.dart';
|
||||||
|
|
||||||
class SnapshotModal extends StatefulWidget {
|
class SnapshotModal extends StatefulWidget {
|
||||||
const SnapshotModal({
|
const SnapshotModal({
|
||||||
|
@ -51,125 +52,117 @@ class _SnapshotModalState extends State<SnapshotModal> {
|
||||||
.state
|
.state
|
||||||
.getServiceById(widget.snapshot.serviceId);
|
.getServiceById(widget.snapshot.serviceId);
|
||||||
|
|
||||||
return ListView(
|
return Scaffold(
|
||||||
controller: widget.scrollController,
|
backgroundColor: Colors.transparent,
|
||||||
padding: const EdgeInsets.all(16),
|
body: ListView(
|
||||||
children: [
|
controller: widget.scrollController,
|
||||||
const SizedBox(height: 16),
|
padding: const EdgeInsets.all(16),
|
||||||
Text(
|
children: [
|
||||||
'backup.snapshot_modal_heading'.tr(),
|
const SizedBox(height: 16),
|
||||||
style: Theme.of(context).textTheme.headlineSmall,
|
Text(
|
||||||
textAlign: TextAlign.center,
|
'backup.snapshot_modal_heading'.tr(),
|
||||||
),
|
style: Theme.of(context).textTheme.headlineSmall,
|
||||||
const SizedBox(height: 16),
|
textAlign: TextAlign.center,
|
||||||
ListTile(
|
),
|
||||||
leading: service != null
|
const SizedBox(height: 16),
|
||||||
? SvgPicture.string(
|
ListTile(
|
||||||
service.svgIcon,
|
leading: service != null
|
||||||
height: 24,
|
? SvgPicture.string(
|
||||||
width: 24,
|
service.svgIcon,
|
||||||
colorFilter: ColorFilter.mode(
|
height: 24,
|
||||||
Theme.of(context).colorScheme.onSurface,
|
width: 24,
|
||||||
BlendMode.srcIn,
|
colorFilter: ColorFilter.mode(
|
||||||
|
Theme.of(context).colorScheme.onSurface,
|
||||||
|
BlendMode.srcIn,
|
||||||
|
),
|
||||||
|
)
|
||||||
|
: const Icon(
|
||||||
|
Icons.question_mark_outlined,
|
||||||
),
|
),
|
||||||
)
|
title: Text(
|
||||||
: const Icon(
|
'backup.snapshot_service_title'.tr(),
|
||||||
Icons.question_mark_outlined,
|
|
||||||
),
|
|
||||||
title: Text(
|
|
||||||
'backup.snapshot_service_title'.tr(),
|
|
||||||
),
|
|
||||||
subtitle: Text(
|
|
||||||
service?.displayName ?? widget.snapshot.fallbackServiceName,
|
|
||||||
),
|
|
||||||
),
|
|
||||||
ListTile(
|
|
||||||
leading: Icon(
|
|
||||||
Icons.access_time_outlined,
|
|
||||||
color: Theme.of(context).colorScheme.onSurface,
|
|
||||||
),
|
|
||||||
title: Text(
|
|
||||||
'backup.snapshot_creation_time_title'.tr(),
|
|
||||||
),
|
|
||||||
subtitle: Text(
|
|
||||||
'${MaterialLocalizations.of(context).formatShortDate(widget.snapshot.time)} ${TimeOfDay.fromDateTime(widget.snapshot.time).format(context)}',
|
|
||||||
),
|
|
||||||
),
|
|
||||||
ListTile(
|
|
||||||
leading: Icon(
|
|
||||||
Icons.numbers_outlined,
|
|
||||||
color: Theme.of(context).colorScheme.onSurface,
|
|
||||||
),
|
|
||||||
title: Text(
|
|
||||||
'backup.snapshot_id_title'.tr(),
|
|
||||||
),
|
|
||||||
subtitle: Text(
|
|
||||||
widget.snapshot.id,
|
|
||||||
),
|
|
||||||
),
|
|
||||||
if (service != null)
|
|
||||||
Column(
|
|
||||||
children: [
|
|
||||||
const SizedBox(height: 8),
|
|
||||||
Text(
|
|
||||||
'backup.snapshot_modal_select_strategy'.tr(),
|
|
||||||
style: Theme.of(context).textTheme.titleMedium,
|
|
||||||
),
|
|
||||||
const SizedBox(height: 8),
|
|
||||||
_BackupStrategySelectionCard(
|
|
||||||
isSelected: selectedStrategy ==
|
|
||||||
BackupRestoreStrategy.downloadVerifyOverwrite,
|
|
||||||
onTap: () {
|
|
||||||
setState(() {
|
|
||||||
selectedStrategy =
|
|
||||||
BackupRestoreStrategy.downloadVerifyOverwrite;
|
|
||||||
});
|
|
||||||
},
|
|
||||||
title:
|
|
||||||
'backup.snapshot_modal_download_verify_option_title'.tr(),
|
|
||||||
subtitle:
|
|
||||||
'backup.snapshot_modal_download_verify_option_description'
|
|
||||||
.tr(),
|
|
||||||
),
|
|
||||||
const SizedBox(height: 8),
|
|
||||||
_BackupStrategySelectionCard(
|
|
||||||
isSelected: selectedStrategy == BackupRestoreStrategy.inplace,
|
|
||||||
onTap: () {
|
|
||||||
setState(() {
|
|
||||||
selectedStrategy = BackupRestoreStrategy.inplace;
|
|
||||||
});
|
|
||||||
},
|
|
||||||
title: 'backup.snapshot_modal_inplace_option_title'.tr(),
|
|
||||||
subtitle:
|
|
||||||
'backup.snapshot_modal_inplace_option_description'.tr(),
|
|
||||||
),
|
|
||||||
const SizedBox(height: 8),
|
|
||||||
// Restore backup button
|
|
||||||
BrandButton.filled(
|
|
||||||
onPressed: isServiceBusy
|
|
||||||
? null
|
|
||||||
: () {
|
|
||||||
context.read<BackupsCubit>().restoreBackup(
|
|
||||||
widget.snapshot.id,
|
|
||||||
selectedStrategy,
|
|
||||||
);
|
|
||||||
Navigator.of(context).pop();
|
|
||||||
getIt<NavigationService>()
|
|
||||||
.showSnackBar('backup.restore_started'.tr());
|
|
||||||
},
|
|
||||||
text: 'backup.restore'.tr(),
|
|
||||||
),
|
|
||||||
],
|
|
||||||
)
|
|
||||||
else
|
|
||||||
Padding(
|
|
||||||
padding: const EdgeInsets.all(16.0),
|
|
||||||
child: InfoBox(
|
|
||||||
isWarning: true,
|
|
||||||
text: 'backup.snapshot_modal_service_not_found'.tr(),
|
|
||||||
),
|
),
|
||||||
)
|
subtitle: Text(
|
||||||
],
|
service?.displayName ?? widget.snapshot.fallbackServiceName,
|
||||||
|
),
|
||||||
|
),
|
||||||
|
ListTile(
|
||||||
|
leading: Icon(
|
||||||
|
Icons.access_time_outlined,
|
||||||
|
color: Theme.of(context).colorScheme.onSurface,
|
||||||
|
),
|
||||||
|
title: Text(
|
||||||
|
'backup.snapshot_creation_time_title'.tr(),
|
||||||
|
),
|
||||||
|
subtitle: Text(
|
||||||
|
'${MaterialLocalizations.of(context).formatShortDate(widget.snapshot.time)} ${TimeOfDay.fromDateTime(widget.snapshot.time).format(context)}',
|
||||||
|
),
|
||||||
|
),
|
||||||
|
SnapshotIdListTile(snapshotId: widget.snapshot.id),
|
||||||
|
if (service != null)
|
||||||
|
Column(
|
||||||
|
children: [
|
||||||
|
const SizedBox(height: 8),
|
||||||
|
Text(
|
||||||
|
'backup.snapshot_modal_select_strategy'.tr(),
|
||||||
|
style: Theme.of(context).textTheme.titleMedium,
|
||||||
|
),
|
||||||
|
const SizedBox(height: 8),
|
||||||
|
_BackupStrategySelectionCard(
|
||||||
|
isSelected: selectedStrategy ==
|
||||||
|
BackupRestoreStrategy.downloadVerifyOverwrite,
|
||||||
|
onTap: () {
|
||||||
|
setState(() {
|
||||||
|
selectedStrategy =
|
||||||
|
BackupRestoreStrategy.downloadVerifyOverwrite;
|
||||||
|
});
|
||||||
|
},
|
||||||
|
title:
|
||||||
|
'backup.snapshot_modal_download_verify_option_title'.tr(),
|
||||||
|
subtitle:
|
||||||
|
'backup.snapshot_modal_download_verify_option_description'
|
||||||
|
.tr(),
|
||||||
|
),
|
||||||
|
const SizedBox(height: 8),
|
||||||
|
_BackupStrategySelectionCard(
|
||||||
|
isSelected: selectedStrategy == BackupRestoreStrategy.inplace,
|
||||||
|
onTap: () {
|
||||||
|
setState(() {
|
||||||
|
selectedStrategy = BackupRestoreStrategy.inplace;
|
||||||
|
});
|
||||||
|
},
|
||||||
|
title: 'backup.snapshot_modal_inplace_option_title'.tr(),
|
||||||
|
subtitle:
|
||||||
|
'backup.snapshot_modal_inplace_option_description'.tr(),
|
||||||
|
),
|
||||||
|
const SizedBox(height: 8),
|
||||||
|
// Restore backup button
|
||||||
|
BrandButton.filled(
|
||||||
|
onPressed: isServiceBusy
|
||||||
|
? null
|
||||||
|
: () {
|
||||||
|
context.read<BackupsCubit>().restoreBackup(
|
||||||
|
widget.snapshot.id,
|
||||||
|
selectedStrategy,
|
||||||
|
);
|
||||||
|
Navigator.of(context).pop();
|
||||||
|
getIt<NavigationService>()
|
||||||
|
.showSnackBar('backup.restore_started'.tr());
|
||||||
|
},
|
||||||
|
text: 'backup.restore'.tr(),
|
||||||
|
),
|
||||||
|
],
|
||||||
|
)
|
||||||
|
else
|
||||||
|
Padding(
|
||||||
|
padding: const EdgeInsets.all(16.0),
|
||||||
|
child: InfoBox(
|
||||||
|
isWarning: true,
|
||||||
|
text: 'backup.snapshot_modal_service_not_found'.tr(),
|
||||||
|
),
|
||||||
|
)
|
||||||
|
],
|
||||||
|
),
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in a new issue