mirror of
https://github.com/twonlyapp/twonly-app.git
synced 2026-01-15 16:28:40 +00:00
started with #121
This commit is contained in:
parent
8ca017f5d8
commit
01c3e8ebbd
7 changed files with 186 additions and 1 deletions
|
|
@ -418,5 +418,6 @@
|
||||||
"tutorialChatMessagesReopenMessageDesc": "If your friend has sent you a picture or video with infinite display time, you can open it again at any time until you restart the app. To do this, simply double-click on the message. Your friend will then receive a notification that you have viewed the picture again.",
|
"tutorialChatMessagesReopenMessageDesc": "If your friend has sent you a picture or video with infinite display time, you can open it again at any time until you restart the app. To do this, simply double-click on the message. Your friend will then receive a notification that you have viewed the picture again.",
|
||||||
"memoriesEmpty": "As soon as you save pictures or videos, they end up here in your memories.",
|
"memoriesEmpty": "As soon as you save pictures or videos, they end up here in your memories.",
|
||||||
"deleteImageTitle": "Are you sure?",
|
"deleteImageTitle": "Are you sure?",
|
||||||
"deleteImageBody": "The image will be irrevocably deleted."
|
"deleteImageBody": "The image will be irrevocably deleted.",
|
||||||
|
"settingsBackup": "Backup"
|
||||||
}
|
}
|
||||||
|
|
@ -1573,6 +1573,12 @@ abstract class AppLocalizations {
|
||||||
/// In en, this message translates to:
|
/// In en, this message translates to:
|
||||||
/// **'The image will be irrevocably deleted.'**
|
/// **'The image will be irrevocably deleted.'**
|
||||||
String get deleteImageBody;
|
String get deleteImageBody;
|
||||||
|
|
||||||
|
/// No description provided for @settingsBackup.
|
||||||
|
///
|
||||||
|
/// In en, this message translates to:
|
||||||
|
/// **'Backup'**
|
||||||
|
String get settingsBackup;
|
||||||
}
|
}
|
||||||
|
|
||||||
class _AppLocalizationsDelegate
|
class _AppLocalizationsDelegate
|
||||||
|
|
|
||||||
|
|
@ -833,4 +833,7 @@ class AppLocalizationsDe extends AppLocalizations {
|
||||||
|
|
||||||
@override
|
@override
|
||||||
String get deleteImageBody => 'Das Bild wird unwiderruflich gelöscht.';
|
String get deleteImageBody => 'Das Bild wird unwiderruflich gelöscht.';
|
||||||
|
|
||||||
|
@override
|
||||||
|
String get settingsBackup => 'Backup';
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -827,4 +827,7 @@ class AppLocalizationsEn extends AppLocalizations {
|
||||||
|
|
||||||
@override
|
@override
|
||||||
String get deleteImageBody => 'The image will be irrevocably deleted.';
|
String get deleteImageBody => 'The image will be irrevocably deleted.';
|
||||||
|
|
||||||
|
@override
|
||||||
|
String get settingsBackup => 'Backup';
|
||||||
}
|
}
|
||||||
|
|
|
||||||
138
lib/src/views/settings/backup/backup.view.dart
Normal file
138
lib/src/views/settings/backup/backup.view.dart
Normal file
|
|
@ -0,0 +1,138 @@
|
||||||
|
import 'package:flutter/material.dart';
|
||||||
|
import 'package:twonly/src/utils/misc.dart';
|
||||||
|
import 'package:twonly/src/views/settings/backup/twonly_identity_backup.view.dart';
|
||||||
|
|
||||||
|
class BackupView extends StatefulWidget {
|
||||||
|
const BackupView({super.key});
|
||||||
|
|
||||||
|
@override
|
||||||
|
State<BackupView> createState() => _BackupViewState();
|
||||||
|
}
|
||||||
|
|
||||||
|
class _BackupViewState extends State<BackupView> {
|
||||||
|
bool _twonlyIdBackupEnabled = false;
|
||||||
|
DateTime? _twonlyIdLastBackup;
|
||||||
|
bool _dataBackupEnabled = false;
|
||||||
|
DateTime? _dataBackupLastBackup;
|
||||||
|
|
||||||
|
@override
|
||||||
|
void initState() {
|
||||||
|
initAsync();
|
||||||
|
super.initState();
|
||||||
|
}
|
||||||
|
|
||||||
|
Future initAsync() async {
|
||||||
|
setState(() {
|
||||||
|
_twonlyIdBackupEnabled = true;
|
||||||
|
_dataBackupEnabled = false;
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
@override
|
||||||
|
Widget build(BuildContext context) {
|
||||||
|
return Scaffold(
|
||||||
|
appBar: AppBar(
|
||||||
|
title: Text(context.lang.settingsBackup),
|
||||||
|
),
|
||||||
|
body: ListView(
|
||||||
|
children: [
|
||||||
|
BackupOption(
|
||||||
|
title: 'twonly-Identity Backup',
|
||||||
|
description:
|
||||||
|
'Back up your twonly identity, as this is the only way to restore your account if you uninstall or lose your phone.',
|
||||||
|
lastBackup: _twonlyIdLastBackup,
|
||||||
|
autoBackupEnabled: _twonlyIdBackupEnabled,
|
||||||
|
onTap: () async {
|
||||||
|
await Navigator.push(context,
|
||||||
|
MaterialPageRoute(builder: (context) {
|
||||||
|
return TwonlyIdentityBackupView();
|
||||||
|
}));
|
||||||
|
initAsync();
|
||||||
|
},
|
||||||
|
),
|
||||||
|
BackupOption(
|
||||||
|
title: 'Daten-Backup',
|
||||||
|
description:
|
||||||
|
'This backup contains besides of your twonly-Identity also all of your media files. This backup will also be encrypted using a password chosen by the user but stored locally on the smartphone. You then have to ensure to manually copy it onto your laptop or device of your choice.',
|
||||||
|
autoBackupEnabled: _dataBackupEnabled,
|
||||||
|
onTap: () {},
|
||||||
|
lastBackup: _dataBackupLastBackup,
|
||||||
|
),
|
||||||
|
],
|
||||||
|
),
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
class BackupOption extends StatelessWidget {
|
||||||
|
final String title;
|
||||||
|
final String description;
|
||||||
|
final bool autoBackupEnabled;
|
||||||
|
final DateTime? lastBackup;
|
||||||
|
final Function() onTap;
|
||||||
|
|
||||||
|
const BackupOption({
|
||||||
|
super.key,
|
||||||
|
required this.title,
|
||||||
|
required this.description,
|
||||||
|
required this.autoBackupEnabled,
|
||||||
|
required this.lastBackup,
|
||||||
|
required this.onTap,
|
||||||
|
});
|
||||||
|
|
||||||
|
String formatDateTime(DateTime? dateTime) {
|
||||||
|
if (dateTime == null) {
|
||||||
|
return "Never";
|
||||||
|
}
|
||||||
|
final now = DateTime.now();
|
||||||
|
final difference = now.difference(dateTime);
|
||||||
|
|
||||||
|
if (difference.inDays == 0) {
|
||||||
|
return 'Today';
|
||||||
|
} else if (difference.inDays == 1) {
|
||||||
|
return 'Yesterday';
|
||||||
|
} else {
|
||||||
|
return '${difference.inDays} Days ago';
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@override
|
||||||
|
Widget build(BuildContext context) {
|
||||||
|
return GestureDetector(
|
||||||
|
onTap: onTap,
|
||||||
|
child: Card(
|
||||||
|
margin: EdgeInsets.all(8.0),
|
||||||
|
child: Padding(
|
||||||
|
padding: const EdgeInsets.all(16.0),
|
||||||
|
child: Column(
|
||||||
|
crossAxisAlignment: CrossAxisAlignment.start,
|
||||||
|
children: [
|
||||||
|
Text(
|
||||||
|
title,
|
||||||
|
style: TextStyle(fontSize: 18, fontWeight: FontWeight.bold),
|
||||||
|
),
|
||||||
|
SizedBox(height: 8.0),
|
||||||
|
Text(description),
|
||||||
|
SizedBox(height: 8.0),
|
||||||
|
Row(
|
||||||
|
mainAxisAlignment: MainAxisAlignment.spaceBetween,
|
||||||
|
children: [
|
||||||
|
Text('Last backup: ${formatDateTime(lastBackup)}'),
|
||||||
|
(autoBackupEnabled)
|
||||||
|
? OutlinedButton(
|
||||||
|
onPressed: onTap,
|
||||||
|
child: Text("Disable"),
|
||||||
|
)
|
||||||
|
: FilledButton(
|
||||||
|
onPressed: onTap,
|
||||||
|
child: Text("Enable"),
|
||||||
|
)
|
||||||
|
],
|
||||||
|
),
|
||||||
|
],
|
||||||
|
),
|
||||||
|
),
|
||||||
|
),
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
@ -0,0 +1,24 @@
|
||||||
|
import 'package:flutter/material.dart';
|
||||||
|
|
||||||
|
class TwonlyIdentityBackupView extends StatefulWidget {
|
||||||
|
const TwonlyIdentityBackupView({super.key});
|
||||||
|
|
||||||
|
@override
|
||||||
|
State<TwonlyIdentityBackupView> createState() =>
|
||||||
|
_TwonlyIdentityBackupViewState();
|
||||||
|
}
|
||||||
|
|
||||||
|
class _TwonlyIdentityBackupViewState extends State<TwonlyIdentityBackupView> {
|
||||||
|
@override
|
||||||
|
Widget build(BuildContext context) {
|
||||||
|
return Scaffold(
|
||||||
|
appBar: AppBar(
|
||||||
|
title: Text("twonly-Identity Backup"),
|
||||||
|
),
|
||||||
|
body: ListView(children: [
|
||||||
|
Text(
|
||||||
|
'Backup of your twonly-Identity. As twonly does not have any second factor like your phone number or email, this backup contains your twonly-Identity. If you lose your device, the only option to recover is with the twonly-ID Backup. This backup will be protected by a password chosen by you in the next step and anonymously uploaded to the twonly servers. Read more [here](https://twonly.eu/s/backup).'),
|
||||||
|
]),
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
@ -120,6 +120,16 @@ class _SettingsMainViewState extends State<SettingsMainView> {
|
||||||
}));
|
}));
|
||||||
},
|
},
|
||||||
),
|
),
|
||||||
|
// BetterListTile(
|
||||||
|
// icon: Icons.lock_clock_rounded,
|
||||||
|
// text: context.lang.settingsBackup,
|
||||||
|
// onTap: () {
|
||||||
|
// Navigator.push(context,
|
||||||
|
// MaterialPageRoute(builder: (context) {
|
||||||
|
// return BackupView();
|
||||||
|
// }));
|
||||||
|
// },
|
||||||
|
// ),
|
||||||
const Divider(),
|
const Divider(),
|
||||||
BetterListTile(
|
BetterListTile(
|
||||||
icon: FontAwesomeIcons.sun,
|
icon: FontAwesomeIcons.sun,
|
||||||
|
|
|
||||||
Loading…
Reference in a new issue