From 151cc536eaa1b849403e09ba9efad05e6fd8b4cb Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Elias=20M=C3=BCller?= Date: Tue, 6 Feb 2024 09:49:00 +0100 Subject: [PATCH 1/5] Added feedback dialog --- .../pages/more/feedback/feedbackDialog.dart | 42 +++++++++++++++++++ lib/view/pages/more/overhang.dart | 9 ++++ 2 files changed, 51 insertions(+) create mode 100644 lib/view/pages/more/feedback/feedbackDialog.dart diff --git a/lib/view/pages/more/feedback/feedbackDialog.dart b/lib/view/pages/more/feedback/feedbackDialog.dart new file mode 100644 index 0000000..6bf2964 --- /dev/null +++ b/lib/view/pages/more/feedback/feedbackDialog.dart @@ -0,0 +1,42 @@ + +import 'package:flutter/material.dart'; + +class FeedbackDialog extends StatefulWidget { + const FeedbackDialog({super.key}); + + @override + State createState() => _FeedbackDialogState(); +} + +class _FeedbackDialogState extends State { + @override + Widget build(BuildContext context) { + return AlertDialog( + title: const Text("Feedback"), + content: const Column( + mainAxisSize: MainAxisSize.min, + children: [ + Text("Bitte gib keine Daten wie z.B. Passwörter weiter."), + SizedBox(height: 20), + TextField( + decoration: InputDecoration( + border: OutlineInputBorder(), + label: Text("Feedback und Verbesserungen") + ), + style: TextStyle(), + minLines: 3, + maxLines: 5, + ) + ], + ), + actions: [ + TextButton( + onPressed: () { + + }, + child: const Text("Senden"), + ) + ], + ); + } +} diff --git a/lib/view/pages/more/overhang.dart b/lib/view/pages/more/overhang.dart index e5cb068..eb03aeb 100644 --- a/lib/view/pages/more/overhang.dart +++ b/lib/view/pages/more/overhang.dart @@ -1,5 +1,7 @@ import 'package:flutter/material.dart'; +import 'package:marianum_mobile/view/pages/more/feedback/feedbackDialog.dart'; +import 'package:marianum_mobile/widget/centeredLeading.dart'; import 'package:persistent_bottom_nav_bar/persistent_tab_view.dart'; import '../../../widget/ListItem.dart'; @@ -36,6 +38,13 @@ class Overhang extends StatelessWidget { trailing: const Icon(Icons.arrow_right), onTap: () => showDialog(context: context, builder: (context) => const SelectShareTypeDialog()) ), + ListTile( + leading: const CenteredLeading(Icon(Icons.feedback_outlined)), + title: const Text("Du hast eine Idee?"), + subtitle: const Text("Fehler und Verbessungsvorschläge"), + trailing: const Icon(Icons.arrow_right), + onTap: () => showDialog(context: context, builder: (context) => const FeedbackDialog()), + ) ], ), ); -- 2.30.2 From acb79bbc6f49f2419f5374f6374099cad596fcbc Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Elias=20M=C3=BCller?= Date: Wed, 7 Feb 2024 22:18:11 +0100 Subject: [PATCH 2/5] Design and better descriptions for feedback dialog --- lib/view/pages/more/feedback/feedbackDialog.dart | 12 +++++++++--- lib/view/pages/more/overhang.dart | 2 +- lib/view/settings/settings.dart | 4 ++-- 3 files changed, 12 insertions(+), 6 deletions(-) diff --git a/lib/view/pages/more/feedback/feedbackDialog.dart b/lib/view/pages/more/feedback/feedbackDialog.dart index 6bf2964..1af6289 100644 --- a/lib/view/pages/more/feedback/feedbackDialog.dart +++ b/lib/view/pages/more/feedback/feedbackDialog.dart @@ -12,24 +12,30 @@ class _FeedbackDialogState extends State { @override Widget build(BuildContext context) { return AlertDialog( + title: const Text("Feedback"), content: const Column( mainAxisSize: MainAxisSize.min, children: [ - Text("Bitte gib keine Daten wie z.B. Passwörter weiter."), - SizedBox(height: 20), + Text("Feedback, Anregungen, Ideen, Fehler und Verbesserungen"), + SizedBox(height: 10), + Text("Bitte gib keine geheimen Daten wie z.B. Passwörter weiter.", style: TextStyle(fontSize: 10)), + SizedBox(height: 10), TextField( + autofocus: true, decoration: InputDecoration( border: OutlineInputBorder(), label: Text("Feedback und Verbesserungen") ), - style: TextStyle(), + // style: TextStyle(), + // expands: true, minLines: 3, maxLines: 5, ) ], ), actions: [ + TextButton(onPressed: () => Navigator.of(context).pop(), child: const Text("Abbrechen")), TextButton( onPressed: () { diff --git a/lib/view/pages/more/overhang.dart b/lib/view/pages/more/overhang.dart index 3e4c367..2922144 100644 --- a/lib/view/pages/more/overhang.dart +++ b/lib/view/pages/more/overhang.dart @@ -43,7 +43,7 @@ class Overhang extends StatelessWidget { title: const Text("Du hast eine Idee?"), subtitle: const Text("Fehler und Verbessungsvorschläge"), trailing: const Icon(Icons.arrow_right), - onTap: () => showDialog(context: context, builder: (context) => const FeedbackDialog()), + onTap: () => showDialog(context: context, barrierDismissible: false, builder: (context) => const FeedbackDialog()), ) ], ), diff --git a/lib/view/settings/settings.dart b/lib/view/settings/settings.dart index 58d8abc..4d1630a 100644 --- a/lib/view/settings/settings.dart +++ b/lib/view/settings/settings.dart @@ -238,8 +238,8 @@ class _SettingsState extends State { ListTile( leading: const CenteredLeading(Icon(Icons.code)), - title: const Text("Quellcode der App"), - subtitle: const Text("Open Source GNU GPL v3"), + title: const Text("Quellcode MarianumMobile/Client"), + subtitle: const Text("open source GNU GPL v3"), onTap: () => ConfirmDialog.openBrowser(context, "https://mhsl.eu/gitea/MarianumMobile/Client"), ), -- 2.30.2 From f7144884e3e41f20183f8911d646e16d26473e09 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Elias=20M=C3=BCller?= Date: Fri, 9 Feb 2024 13:41:48 +0100 Subject: [PATCH 3/5] Fixed Share dialog for iPadOs --- lib/view/pages/more/share/selectShareTypeDialog.dart | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/lib/view/pages/more/share/selectShareTypeDialog.dart b/lib/view/pages/more/share/selectShareTypeDialog.dart index 7ef5c2b..e8f62e9 100644 --- a/lib/view/pages/more/share/selectShareTypeDialog.dart +++ b/lib/view/pages/more/share/selectShareTypeDialog.dart @@ -22,12 +22,11 @@ class SelectShareTypeDialog extends StatelessWidget { ), ListTile( leading: const Icon(Icons.link_outlined), - title: const Text("Per Link"), + title: const Text("Per Link teilen"), trailing: const Icon(Icons.arrow_right), onTap: () { - final box = context.findRenderObject() as RenderBox?; Share.share( - sharePositionOrigin: box!.localToGlobal(Offset.zero) & box.size, + sharePositionOrigin: Rect.fromLTWH(0, 0, MediaQuery.of(context).size.width, MediaQuery.of(context).size.height / 2), subject: "App Teilen", "Hol dir die für das Marianum maßgeschneiderte App:" "\n\nAndroid: https://play.google.com/store/apps/details?id=eu.mhsl.marianum.mobile.client " -- 2.30.2 From da28a132685a846cc3a6ac98698a2459d3ec6eb5 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Elias=20M=C3=BCller?= Date: Fri, 9 Feb 2024 13:42:11 +0100 Subject: [PATCH 4/5] Prevent unnecessary api request for chats --- lib/api/marianumcloud/talk/talkApi.dart | 2 +- lib/model/chatList/chatProps.dart | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/lib/api/marianumcloud/talk/talkApi.dart b/lib/api/marianumcloud/talk/talkApi.dart index cc0ef16..ec01893 100644 --- a/lib/api/marianumcloud/talk/talkApi.dart +++ b/lib/api/marianumcloud/talk/talkApi.dart @@ -47,7 +47,7 @@ abstract class TalkApi extends ApiRequest { if(data.statusCode >= 400 || data.statusCode < 200) throw Exception("Response status code '${data.statusCode}' might indicate an error"); } catch(e) { log(e.toString()); - throw ApiError("Request could not be dispatched: ${e.toString()}"); + throw ApiError("Request $endpoint could not be dispatched: ${e.toString()}"); } //dynamic jsonData = jsonDecode(data.body); diff --git a/lib/model/chatList/chatProps.dart b/lib/model/chatList/chatProps.dart index 87502a4..06442be 100644 --- a/lib/model/chatList/chatProps.dart +++ b/lib/model/chatList/chatProps.dart @@ -18,6 +18,7 @@ class ChatProps extends DataHolder { @override void run() { notifyListeners(); + if(_queryToken.isEmpty) return; DateTime requestStart = DateTime.now(); GetChatCache( @@ -27,7 +28,6 @@ class ChatProps extends DataHolder { _getChatResponse = data; notifyListeners(); - } ); } -- 2.30.2 From 3681fcdae075b7612d801bdb776d229d9f3a0f5d Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Elias=20M=C3=BCller?= Date: Fri, 9 Feb 2024 16:35:47 +0100 Subject: [PATCH 5/5] Added api for sending feedback --- lib/api/mhsl/mhslApi.dart | 3 +- lib/api/mhsl/server/feedback/addFeedback.dart | 21 ++++++++++ .../server/feedback/addFeedbackParams.dart | 20 +++++++++ .../server/feedback/addFeedbackParams.g.dart | 21 ++++++++++ .../userIndex/update/updateUserindex.dart | 13 +++--- lib/model/accountData.dart | 11 +++++ .../pages/more/feedback/feedbackDialog.dart | 41 +++++++++++++++---- 7 files changed, 112 insertions(+), 18 deletions(-) create mode 100644 lib/api/mhsl/server/feedback/addFeedback.dart create mode 100644 lib/api/mhsl/server/feedback/addFeedbackParams.dart create mode 100644 lib/api/mhsl/server/feedback/addFeedbackParams.g.dart diff --git a/lib/api/mhsl/mhslApi.dart b/lib/api/mhsl/mhslApi.dart index 64f6270..422ea1e 100644 --- a/lib/api/mhsl/mhslApi.dart +++ b/lib/api/mhsl/mhslApi.dart @@ -1,5 +1,4 @@ import 'dart:convert'; -import 'dart:developer'; import 'package:http/http.dart' as http; import '../apiError.dart'; @@ -23,7 +22,7 @@ abstract class MhslApi extends ApiRequest { } if(data.statusCode > 299) { - log("Non 200 Status code from mhsl services: $subpath: ${data.statusCode}"); + throw ApiError("Non 200 Status code from mhsl services: $subpath: ${data.statusCode}"); } return assemble(utf8.decode(data.bodyBytes)); diff --git a/lib/api/mhsl/server/feedback/addFeedback.dart b/lib/api/mhsl/server/feedback/addFeedback.dart new file mode 100644 index 0000000..679627a --- /dev/null +++ b/lib/api/mhsl/server/feedback/addFeedback.dart @@ -0,0 +1,21 @@ +import 'dart:convert'; + +import 'package:http/http.dart'; +import 'package:marianum_mobile/api/mhsl/mhslApi.dart'; +import 'package:http/http.dart' as http; + +import 'addFeedbackParams.dart'; + + +class AddFeedback extends MhslApi { + AddFeedbackParams params; + AddFeedback(this.params) : super('server/feedback'); + + @override + void assemble(String raw) {} + + @override + Future? request(Uri uri) { + return http.post(uri, body: jsonEncode(params.toJson())); + } +} \ No newline at end of file diff --git a/lib/api/mhsl/server/feedback/addFeedbackParams.dart b/lib/api/mhsl/server/feedback/addFeedbackParams.dart new file mode 100644 index 0000000..4f3e8b0 --- /dev/null +++ b/lib/api/mhsl/server/feedback/addFeedbackParams.dart @@ -0,0 +1,20 @@ +import 'package:json_annotation/json_annotation.dart'; + +part 'addFeedbackParams.g.dart'; + +@JsonSerializable() +class AddFeedbackParams { + String user; + String feedback; + int appVersion; + + + AddFeedbackParams({ + required this.user, + required this.feedback, + required this.appVersion, + }); + + factory AddFeedbackParams.fromJson(Map json) => _$AddFeedbackParamsFromJson(json); + Map toJson() => _$AddFeedbackParamsToJson(this); +} \ No newline at end of file diff --git a/lib/api/mhsl/server/feedback/addFeedbackParams.g.dart b/lib/api/mhsl/server/feedback/addFeedbackParams.g.dart new file mode 100644 index 0000000..47f2105 --- /dev/null +++ b/lib/api/mhsl/server/feedback/addFeedbackParams.g.dart @@ -0,0 +1,21 @@ +// GENERATED CODE - DO NOT MODIFY BY HAND + +part of 'addFeedbackParams.dart'; + +// ************************************************************************** +// JsonSerializableGenerator +// ************************************************************************** + +AddFeedbackParams _$AddFeedbackParamsFromJson(Map json) => + AddFeedbackParams( + user: json['user'] as String, + feedback: json['feedback'] as String, + appVersion: json['appVersion'] as int, + ); + +Map _$AddFeedbackParamsToJson(AddFeedbackParams instance) => + { + 'user': instance.user, + 'feedback': instance.feedback, + 'appVersion': instance.appVersion, + }; diff --git a/lib/api/mhsl/server/userIndex/update/updateUserindex.dart b/lib/api/mhsl/server/userIndex/update/updateUserindex.dart index 4500904..b41f4c9 100644 --- a/lib/api/mhsl/server/userIndex/update/updateUserindex.dart +++ b/lib/api/mhsl/server/userIndex/update/updateUserindex.dart @@ -2,9 +2,7 @@ import 'dart:convert'; import 'dart:developer'; -import 'package:crypto/crypto.dart'; import 'package:device_info_plus/device_info_plus.dart'; -import 'package:firebase_messaging/firebase_messaging.dart'; import 'package:http/http.dart' as http; import 'package:package_info/package_info.dart'; @@ -21,18 +19,17 @@ class UpdateUserIndex extends MhslApi { @override Future request(Uri uri) { - return http.post(uri, body: jsonEncode(params.toJson())); + String data = jsonEncode(params.toJson()); + log("Updating userindex:\n $data"); + return http.post(uri, body: data); } static void index() async { - String userId = sha512.convert(utf8.encode("${AccountData().getUsername()}:${AccountData().getPassword()}")).toString(); - String deviceId = sha512.convert(utf8.encode("$userId@${await FirebaseMessaging.instance.getToken()}")).toString(); - log("Userindex:\n userid:$userId\n deviceid:$deviceId"); UpdateUserIndex( UpdateUserIndexParams( username: AccountData().getUsername(), - user: userId, - device: deviceId, + user: AccountData().getUserId(), + device: await AccountData().getDeviceId(), appVersion: int.parse((await PackageInfo.fromPlatform()).buildNumber), deviceInfo: jsonEncode((await DeviceInfoPlugin().deviceInfo).data).toString(), ), diff --git a/lib/model/accountData.dart b/lib/model/accountData.dart index 9d6cf87..0f6ea35 100644 --- a/lib/model/accountData.dart +++ b/lib/model/accountData.dart @@ -1,5 +1,8 @@ import 'dart:async'; +import 'dart:convert'; +import 'package:crypto/crypto.dart'; +import 'package:firebase_messaging/firebase_messaging.dart'; import 'package:flutter/cupertino.dart'; import 'package:provider/provider.dart'; import 'package:shared_preferences/shared_preferences.dart'; @@ -35,6 +38,14 @@ class AccountData { return _password!; } + String getUserId() { + return sha512.convert(utf8.encode("${AccountData().getUsername()}:${AccountData().getPassword()}")).toString(); + } + + Future getDeviceId() async { + return sha512.convert(utf8.encode("${getUserId()}@${await FirebaseMessaging.instance.getToken()}")).toString(); + } + Future setData(String username, String password) async { SharedPreferences storage = await _storage; diff --git a/lib/view/pages/more/feedback/feedbackDialog.dart b/lib/view/pages/more/feedback/feedbackDialog.dart index 1af6289..d6d4ceb 100644 --- a/lib/view/pages/more/feedback/feedbackDialog.dart +++ b/lib/view/pages/more/feedback/feedbackDialog.dart @@ -1,5 +1,9 @@ import 'package:flutter/material.dart'; +import 'package:marianum_mobile/api/mhsl/server/feedback/addFeedback.dart'; +import 'package:marianum_mobile/api/mhsl/server/feedback/addFeedbackParams.dart'; +import 'package:marianum_mobile/model/accountData.dart'; +import 'package:package_info/package_info.dart'; class FeedbackDialog extends StatefulWidget { const FeedbackDialog({super.key}); @@ -9,21 +13,25 @@ class FeedbackDialog extends StatefulWidget { } class _FeedbackDialogState extends State { + final TextEditingController _feedbackInput = TextEditingController(); + String? _error; + @override Widget build(BuildContext context) { return AlertDialog( title: const Text("Feedback"), - content: const Column( + content: Column( mainAxisSize: MainAxisSize.min, children: [ - Text("Feedback, Anregungen, Ideen, Fehler und Verbesserungen"), - SizedBox(height: 10), - Text("Bitte gib keine geheimen Daten wie z.B. Passwörter weiter.", style: TextStyle(fontSize: 10)), - SizedBox(height: 10), + const Text("Feedback, Anregungen, Ideen, Fehler und Verbesserungen"), + const SizedBox(height: 10), + const Text("Bitte gib keine geheimen Daten wie z.B. Passwörter weiter.", style: TextStyle(fontSize: 10)), + const SizedBox(height: 10), TextField( + controller: _feedbackInput, autofocus: true, - decoration: InputDecoration( + decoration: const InputDecoration( border: OutlineInputBorder(), label: Text("Feedback und Verbesserungen") ), @@ -31,14 +39,31 @@ class _FeedbackDialogState extends State { // expands: true, minLines: 3, maxLines: 5, + ), + Visibility( + visible: _error != null, + child: Text("Senden fehlgeschlagen: $_error", style: const TextStyle(color: Colors.red)) ) ], ), actions: [ TextButton(onPressed: () => Navigator.of(context).pop(), child: const Text("Abbrechen")), TextButton( - onPressed: () { - + onPressed: () async { + AddFeedback( + AddFeedbackParams( + user: AccountData().getUserId(), + feedback: _feedbackInput.text, + appVersion: int.parse((await PackageInfo.fromPlatform()).buildNumber) + ) + ) + .run() + .then((value) => Navigator.of(context).pop()) + .catchError((error, trace) { + setState(() { + _error = error.toString(); + }); + }); }, child: const Text("Senden"), ) -- 2.30.2