start with settings

This commit is contained in:
otsmr 2025-02-08 00:03:59 +01:00
parent 86b6177d42
commit e7f0488a10
10 changed files with 329 additions and 71 deletions

View file

@ -0,0 +1,37 @@
import 'package:flutter/material.dart';
class RadioButton<T> extends StatelessWidget {
final T value;
final T? groupValue;
final String label;
final ValueChanged<T?> onChanged;
const RadioButton({
super.key,
required this.value,
required this.groupValue,
required this.label,
required this.onChanged,
});
@override
Widget build(BuildContext context) {
return Row(
children: [
Radio<T>(
value: value,
groupValue: groupValue,
onChanged: onChanged,
materialTapTargetSize: MaterialTapTargetSize.shrinkWrap,
),
Expanded(
child: GestureDetector(
onTap: () =>
onChanged(value), // Call onChanged when the text is tapped
child: Text(label),
),
),
],
);
}
}

View file

@ -30,6 +30,18 @@
"messageSendState_TapToLoad": "Tap to load", "messageSendState_TapToLoad": "Tap to load",
"messageSendState_Loading": "Downloading", "messageSendState_Loading": "Downloading",
"imageEditorDrawOk": "Take drawing", "imageEditorDrawOk": "Take drawing",
"settingsTitle": "Settings",
"settingsAccount": "Konto",
"settingsSubscription": "Subscription",
"settingsAppearance": "Appearance",
"settingsPrivacy": "Privacy",
"settingsNotification": "Notification",
"settingsHelp": "Help",
"settingsHelpSupport": "Support Center",
"settingsHelpVersion": "Version",
"settingsHelpLicenses": "Licenses",
"settingsHelpLegal": "Terms & Privacy Policy",
"settingsAppearanceTheme": "Theme",
"undo": "Undo", "undo": "Undo",
"redo": "Redo", "redo": "Redo",
"close": "Close", "close": "Close",

View file

@ -33,7 +33,7 @@ class _CameraPreviewViewPermission extends State<CameraPreviewViewPermission> {
}); });
} }
} else { } else {
return const CircularProgressIndicator(); return Container();
} }
}); });
} }

View file

@ -73,8 +73,8 @@ class HomeViewState extends State<HomeView> {
bottomNavigationBar: BottomNavigationBar( bottomNavigationBar: BottomNavigationBar(
showSelectedLabels: false, showSelectedLabels: false,
showUnselectedLabels: false, showUnselectedLabels: false,
selectedIconTheme: selectedIconTheme: IconThemeData(
IconThemeData(color: const Color.fromARGB(255, 255, 255, 255)), color: Theme.of(context).colorScheme.inverseSurface),
items: [ items: [
BottomNavigationBarItem( BottomNavigationBarItem(
icon: FaIcon(FontAwesomeIcons.camera), icon: FaIcon(FontAwesomeIcons.camera),
@ -82,8 +82,6 @@ class HomeViewState extends State<HomeView> {
), ),
BottomNavigationBarItem( BottomNavigationBarItem(
icon: FaIcon(FontAwesomeIcons.solidComments), label: ""), icon: FaIcon(FontAwesomeIcons.solidComments), label: ""),
// BottomNavigationBarItem(
// icon: FaIcon(FontAwesomeIcons.userShield), label: ""),
], ],
onTap: (int index) { onTap: (int index) {
activePageIdx = index; activePageIdx = index;

View file

@ -0,0 +1,14 @@
import 'package:restart_app/restart_app.dart';
// FilledButton.icon(
// onPressed: () async {
// await deleteLocalUserData();
// Restart.restartApp(
// notificationTitle: 'Successfully logged out',
// notificationBody: 'Click here to open the app again',
// );
// },
// label: Text("Logout"),
// icon: Icon(Icons.no_accounts),
// ),

View file

@ -0,0 +1,80 @@
import 'package:flutter/material.dart';
import 'package:provider/provider.dart';
import 'package:twonly/src/components/radio_button.dart';
import 'package:twonly/src/providers/settings_change_provider.dart';
import 'package:twonly/src/utils/misc.dart';
class AppearanceView extends StatelessWidget {
const AppearanceView({super.key});
void _showSelectThemeMode(BuildContext context) async {
ThemeMode? selectedValue = context.read<SettingsChangeProvider>().themeMode;
await showDialog(
context: context,
builder: (BuildContext context) {
return AlertDialog(
title: Text(context.lang.settingsAppearanceTheme),
content: Column(
mainAxisSize: MainAxisSize.min,
children: [
RadioButton<ThemeMode>(
value: ThemeMode.system,
groupValue: selectedValue,
label: 'System default',
onChanged: (ThemeMode? value) {
selectedValue = value;
Navigator.of(context).pop();
},
),
RadioButton<ThemeMode>(
value: ThemeMode.light,
groupValue: selectedValue,
label: 'Light',
onChanged: (ThemeMode? value) {
selectedValue = value;
Navigator.of(context).pop();
},
),
RadioButton<ThemeMode>(
value: ThemeMode.dark,
groupValue: selectedValue,
label: 'Dark',
onChanged: (ThemeMode? value) {
selectedValue = value;
Navigator.of(context).pop();
},
),
],
),
);
},
);
if (selectedValue != null && context.mounted) {
context.read<SettingsChangeProvider>().updateThemeMode(selectedValue);
}
}
@override
Widget build(BuildContext context) {
ThemeMode? selectedTheme =
context.watch<SettingsChangeProvider>().themeMode;
return Scaffold(
appBar: AppBar(
title: Text(context.lang.settingsAppearance),
),
body: ListView(
children: [
ListTile(
title: Text(context.lang.settingsAppearanceTheme),
subtitle:
Text(selectedTheme.name, style: TextStyle(color: Colors.grey)),
onTap: () {
_showSelectThemeMode(context);
},
),
],
),
);
}
}

View file

@ -0,0 +1,69 @@
import 'package:flutter/material.dart';
import 'package:font_awesome_flutter/font_awesome_flutter.dart';
import 'package:package_info_plus/package_info_plus.dart';
import 'package:twonly/src/utils/misc.dart';
import 'package:url_launcher/url_launcher.dart';
class HelpView extends StatelessWidget {
const HelpView({super.key});
@override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
title: Text(context.lang.settingsHelp),
),
body: ListView(
children: [
ListTile(
title: Text(context.lang.settingsHelpSupport),
onTap: () {
launchUrl(Uri.parse("https://twonly.eu/support"));
},
trailing:
FaIcon(FontAwesomeIcons.arrowUpRightFromSquare, size: 15),
),
Divider(),
FutureBuilder(
future: PackageInfo.fromPlatform(),
builder: (context, snap) {
if (snap.hasData) {
return ListTile(
title: Text(context.lang.settingsHelpVersion),
subtitle: Text(snap.data!.version),
);
} else {
return Container();
}
},
),
ListTile(
title: Text(context.lang.settingsHelpLicenses),
onTap: () {
showLicensePage(context: context);
},
),
// Diagnoseprotokoll
ListTile(
title: Text(context.lang.settingsHelpLegal),
onTap: () {
launchUrl(Uri.parse("https://twonly.eu/legal"));
// showLicensePage(context: context);
},
trailing:
FaIcon(FontAwesomeIcons.arrowUpRightFromSquare, size: 15),
),
ListTile(
title: Text(
"Copyright twonly",
style: TextStyle(color: Colors.grey, fontSize: 13),
),
),
//
],
));
}
}

View file

@ -1,13 +1,13 @@
import 'package:flutter_local_notifications/flutter_local_notifications.dart'; import 'package:flutter_local_notifications/flutter_local_notifications.dart';
import 'package:font_awesome_flutter/font_awesome_flutter.dart'; import 'package:font_awesome_flutter/font_awesome_flutter.dart';
import 'package:provider/provider.dart';
import 'package:twonly/main.dart'; import 'package:twonly/main.dart';
import 'package:twonly/src/components/initialsavatar.dart'; import 'package:twonly/src/components/initialsavatar.dart';
import 'package:twonly/src/model/json/user_data.dart'; import 'package:twonly/src/model/json/user_data.dart';
import 'package:restart_app/restart_app.dart';
import 'package:flutter/material.dart'; import 'package:flutter/material.dart';
import 'package:twonly/src/providers/settings_change_provider.dart'; import 'package:twonly/src/utils/misc.dart';
import 'package:twonly/src/utils/storage.dart'; import 'package:twonly/src/utils/storage.dart';
import 'package:twonly/src/views/settings/appearance_view.dart';
import 'package:twonly/src/views/settings/help_view.dart';
class ProfileView extends StatefulWidget { class ProfileView extends StatefulWidget {
const ProfileView({super.key}); const ProfileView({super.key});
@ -33,7 +33,7 @@ class _ProfileViewState extends State<ProfileView> {
Widget build(BuildContext context) { Widget build(BuildContext context) {
return Scaffold( return Scaffold(
appBar: AppBar( appBar: AppBar(
title: Text("Settings"), title: Text(context.lang.settingsTitle),
), ),
body: (userData == null) body: (userData == null)
? null ? null
@ -79,100 +79,66 @@ class _ProfileViewState extends State<ProfileView> {
), ),
SettingsListTile( SettingsListTile(
icon: FontAwesomeIcons.user, icon: FontAwesomeIcons.user,
text: "Konto", text: context.lang.settingsAccount,
onTap: () {}, onTap: () {},
), ),
SettingsListTile( SettingsListTile(
icon: FontAwesomeIcons.shieldHeart, icon: FontAwesomeIcons.shieldHeart,
text: "Subscription", text: context.lang.settingsSubscription,
onTap: () {}, onTap: () {},
), ),
const Divider(), const Divider(),
SettingsListTile( SettingsListTile(
icon: FontAwesomeIcons.sun, icon: FontAwesomeIcons.sun,
text: "Darstellung", text: context.lang.settingsAppearance,
onTap: () {}, onTap: () {
Navigator.push(context,
MaterialPageRoute(builder: (context) {
return AppearanceView();
}));
},
), ),
SettingsListTile( SettingsListTile(
icon: FontAwesomeIcons.lock, icon: FontAwesomeIcons.lock,
text: "Datenschutz", text: context.lang.settingsPrivacy,
onTap: () {}, onTap: () {},
), ),
SettingsListTile( SettingsListTile(
icon: FontAwesomeIcons.bell, icon: FontAwesomeIcons.bell,
text: "Benachrichtigungen", text: context.lang.settingsNotification,
onTap: () async { onTap: () async {
const AndroidNotificationDetails const AndroidNotificationDetails
androidNotificationDetails = AndroidNotificationDetails( androidNotificationDetails = AndroidNotificationDetails(
'0', '0',
'Messages', 'Messages2',
channelDescription: 'Messages from other users.', channelDescription: 'Messages from other users.',
importance: Importance.max, importance: Importance.max,
priority: Priority.high, priority: Priority.max,
ticker: 'ticker', ticker: 'ticker',
); );
const NotificationDetails notificationDetails = const NotificationDetails notificationDetails =
NotificationDetails( NotificationDetails(
android: androidNotificationDetails); android: androidNotificationDetails);
await flutterLocalNotificationsPlugin.show(0, 'New message', await flutterLocalNotificationsPlugin.show(
'You got a new message from XX', notificationDetails, 1,
payload: 'item x'); 'New message from x',
'You got a new message from XX',
notificationDetails,
payload: 'test');
}, },
), ),
const Divider(), const Divider(),
SettingsListTile( SettingsListTile(
icon: FontAwesomeIcons.circleQuestion, icon: FontAwesomeIcons.circleQuestion,
text: "Help", text: context.lang.settingsHelp,
onTap: () {}, onTap: () {
Navigator.push(context, MaterialPageRoute(
builder: (context) {
return HelpView();
},
));
},
), ),
// Padding(
// padding: const EdgeInsets.all(16),
// // Glue the SettingsController to the theme selection DropdownButton.
// //
// // When a user selects a theme from the dropdown list, the
// // SettingsController is updated, which rebuilds the MaterialApp.
// child: DropdownButton<ThemeMode>(
// // Read the selected themeMode from the controller
// value: context.watch<SettingsChangeProvider>().themeMode,
// // Call the updateThemeMode method any time the user selects a theme.
// onChanged: (theme) {
// context
// .read<SettingsChangeProvider>()
// .updateThemeMode(theme);
// },
// items: const [
// DropdownMenuItem(
// value: ThemeMode.system,
// child: Text('System Theme'),
// ),
// DropdownMenuItem(
// value: ThemeMode.light,
// child: Text('Light Theme'),
// ),
// DropdownMenuItem(
// value: ThemeMode.dark,
// child: Text('Dark Theme'),
// )
// ],
// ),
// ),
// ElevatedButton(
// onPressed: () {
// showLicensePage(context: context);
// },
// child: Text('Show Licenses'),
// ),
// FilledButton.icon(
// onPressed: () async {
// await deleteLocalUserData();
// Restart.restartApp(
// notificationTitle: 'Successfully logged out',
// notificationBody: 'Click here to open the app again',
// );
// },
// label: Text("Logout"),
// icon: Icon(Icons.no_accounts),
// ),
], ],
), ),
); );

View file

@ -850,6 +850,22 @@ packages:
url: "https://pub.dev" url: "https://pub.dev"
source: hosted source: hosted
version: "2.1.1" version: "2.1.1"
package_info_plus:
dependency: "direct main"
description:
name: package_info_plus
sha256: "67eae327b1b0faf761964a1d2e5d323c797f3799db0e85aa232db8d9e922bc35"
url: "https://pub.dev"
source: hosted
version: "8.2.1"
package_info_plus_platform_interface:
dependency: transitive
description:
name: package_info_plus_platform_interface
sha256: "205ec83335c2ab9107bbba3f8997f9356d72ca3c715d2f038fc773d0366b4c76"
url: "https://pub.dev"
source: hosted
version: "3.1.0"
path: path:
dependency: "direct main" dependency: "direct main"
description: description:
@ -1215,6 +1231,70 @@ packages:
url: "https://pub.dev" url: "https://pub.dev"
source: hosted source: hosted
version: "1.4.0" version: "1.4.0"
url_launcher:
dependency: "direct main"
description:
name: url_launcher
sha256: "9d06212b1362abc2f0f0d78e6f09f726608c74e3b9462e8368bb03314aa8d603"
url: "https://pub.dev"
source: hosted
version: "6.3.1"
url_launcher_android:
dependency: transitive
description:
name: url_launcher_android
sha256: "6fc2f56536ee873eeb867ad176ae15f304ccccc357848b351f6f0d8d4a40d193"
url: "https://pub.dev"
source: hosted
version: "6.3.14"
url_launcher_ios:
dependency: transitive
description:
name: url_launcher_ios
sha256: "16a513b6c12bb419304e72ea0ae2ab4fed569920d1c7cb850263fe3acc824626"
url: "https://pub.dev"
source: hosted
version: "6.3.2"
url_launcher_linux:
dependency: transitive
description:
name: url_launcher_linux
sha256: "4e9ba368772369e3e08f231d2301b4ef72b9ff87c31192ef471b380ef29a4935"
url: "https://pub.dev"
source: hosted
version: "3.2.1"
url_launcher_macos:
dependency: transitive
description:
name: url_launcher_macos
sha256: "17ba2000b847f334f16626a574c702b196723af2a289e7a93ffcb79acff855c2"
url: "https://pub.dev"
source: hosted
version: "3.2.2"
url_launcher_platform_interface:
dependency: transitive
description:
name: url_launcher_platform_interface
sha256: "552f8a1e663569be95a8190206a38187b531910283c3e982193e4f2733f01029"
url: "https://pub.dev"
source: hosted
version: "2.3.2"
url_launcher_web:
dependency: transitive
description:
name: url_launcher_web
sha256: "3ba963161bd0fe395917ba881d320b9c4f6dd3c4a233da62ab18a5025c85f1e9"
url: "https://pub.dev"
source: hosted
version: "2.4.0"
url_launcher_windows:
dependency: transitive
description:
name: url_launcher_windows
sha256: "3284b6d2ac454cf34f114e1d3319866fdd1e19cdc329999057e44ffe936cfa77"
url: "https://pub.dev"
source: hosted
version: "3.1.4"
vector_math: vector_math:
dependency: transitive dependency: transitive
description: description:

View file

@ -4,7 +4,7 @@ description: "Send pictures to friends in real time and be sure you are the only
# Prevent accidental publishing to pub.dev. # Prevent accidental publishing to pub.dev.
publish_to: 'none' publish_to: 'none'
version: 1.0.0+1 version: 0.0.1+1
environment: environment:
sdk: ^3.5.4 sdk: ^3.5.4
@ -38,6 +38,7 @@ dependencies:
logging: ^1.3.0 logging: ^1.3.0
lottie: ^3.3.1 lottie: ^3.3.1
no_screenshot: ^0.3.1 no_screenshot: ^0.3.1
package_info_plus: ^8.2.1
path: ^1.9.0 path: ^1.9.0
path_provider: ^2.1.5 path_provider: ^2.1.5
permission_handler: ^11.3.1 permission_handler: ^11.3.1
@ -48,6 +49,7 @@ dependencies:
restart_app: ^1.3.2 restart_app: ^1.3.2
screenshot: ^3.0.0 screenshot: ^3.0.0
sqflite_sqlcipher: ^3.1.0+1 sqflite_sqlcipher: ^3.1.0+1
url_launcher: ^6.3.1
web_socket_channel: ^3.0.1 web_socket_channel: ^3.0.1
dev_dependencies: dev_dependencies: