develop-biggerFeedbackWidget #51
@ -6,12 +6,14 @@ part 'addFeedbackParams.g.dart';
|
|||||||
class AddFeedbackParams {
|
class AddFeedbackParams {
|
||||||
String user;
|
String user;
|
||||||
String feedback;
|
String feedback;
|
||||||
|
String? screenshot;
|
||||||
int appVersion;
|
int appVersion;
|
||||||
|
|
||||||
|
|
||||||
AddFeedbackParams({
|
AddFeedbackParams({
|
||||||
required this.user,
|
required this.user,
|
||||||
required this.feedback,
|
required this.feedback,
|
||||||
|
this.screenshot,
|
||||||
required this.appVersion,
|
required this.appVersion,
|
||||||
});
|
});
|
||||||
|
|
||||||
|
@ -10,6 +10,7 @@ AddFeedbackParams _$AddFeedbackParamsFromJson(Map<String, dynamic> json) =>
|
|||||||
AddFeedbackParams(
|
AddFeedbackParams(
|
||||||
user: json['user'] as String,
|
user: json['user'] as String,
|
||||||
feedback: json['feedback'] as String,
|
feedback: json['feedback'] as String,
|
||||||
|
screenshot: json['screenshot'] as String?,
|
||||||
appVersion: json['appVersion'] as int,
|
appVersion: json['appVersion'] as int,
|
||||||
);
|
);
|
||||||
|
|
||||||
@ -17,5 +18,6 @@ Map<String, dynamic> _$AddFeedbackParamsToJson(AddFeedbackParams instance) =>
|
|||||||
<String, dynamic>{
|
<String, dynamic>{
|
||||||
'user': instance.user,
|
'user': instance.user,
|
||||||
'feedback': instance.feedback,
|
'feedback': instance.feedback,
|
||||||
|
'screenshot': instance.screenshot,
|
||||||
'appVersion': instance.appVersion,
|
'appVersion': instance.appVersion,
|
||||||
};
|
};
|
||||||
|
@ -1,10 +1,19 @@
|
|||||||
|
|
||||||
|
import 'dart:convert';
|
||||||
|
import 'dart:typed_data';
|
||||||
|
|
||||||
import 'package:flutter/material.dart';
|
import 'package:flutter/material.dart';
|
||||||
|
import 'package:image_picker/image_picker.dart';
|
||||||
|
import 'package:loader_overlay/loader_overlay.dart';
|
||||||
import 'package:package_info/package_info.dart';
|
import 'package:package_info/package_info.dart';
|
||||||
|
import 'package:provider/provider.dart';
|
||||||
|
import 'package:badges/badges.dart' as badges;
|
||||||
|
|
||||||
import '../../../../api/mhsl/server/feedback/addFeedback.dart';
|
import '../../../../api/mhsl/server/feedback/addFeedback.dart';
|
||||||
import '../../../../api/mhsl/server/feedback/addFeedbackParams.dart';
|
import '../../../../api/mhsl/server/feedback/addFeedbackParams.dart';
|
||||||
import '../../../../model/accountData.dart';
|
import '../../../../model/accountData.dart';
|
||||||
|
import '../../../../storage/base/settingsProvider.dart';
|
||||||
|
import '../../../../widget/filePick.dart';
|
||||||
import '../../../../widget/infoDialog.dart';
|
import '../../../../widget/infoDialog.dart';
|
||||||
|
|
||||||
class FeedbackDialog extends StatefulWidget {
|
class FeedbackDialog extends StatefulWidget {
|
||||||
@ -15,64 +24,150 @@ class FeedbackDialog extends StatefulWidget {
|
|||||||
}
|
}
|
||||||
|
|
||||||
class _FeedbackDialogState extends State<FeedbackDialog> {
|
class _FeedbackDialogState extends State<FeedbackDialog> {
|
||||||
|
final ImagePicker picker = ImagePicker();
|
||||||
|
|
||||||
final TextEditingController _feedbackInput = TextEditingController();
|
final TextEditingController _feedbackInput = TextEditingController();
|
||||||
|
Uint8List? _image;
|
||||||
String? _error;
|
String? _error;
|
||||||
|
bool _textFieldEmpty = false;
|
||||||
|
|
||||||
|
@override
|
||||||
|
void initState() {
|
||||||
|
super.initState();
|
||||||
|
_feedbackInput.addListener(() {
|
||||||
|
setState(() {
|
||||||
|
_textFieldEmpty = _feedbackInput.text.isEmpty;
|
||||||
|
_error = null;
|
||||||
|
});
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
@override
|
@override
|
||||||
Widget build(BuildContext context) {
|
Widget build(BuildContext context) {
|
||||||
return AlertDialog(
|
return Scaffold(
|
||||||
|
appBar: AppBar(
|
||||||
title: const Text('Feedback'),
|
title: const Text('Feedback'),
|
||||||
content: Column(
|
),
|
||||||
mainAxisSize: MainAxisSize.min,
|
body: Column(
|
||||||
|
mainAxisSize: MainAxisSize.max,
|
||||||
children: [
|
children: [
|
||||||
Pupsi marked this conversation as resolved
|
|||||||
const Text('Feedback, Anregungen, Ideen, Fehler und Verbesserungen'),
|
const SizedBox(height: 5),
|
||||||
const SizedBox(height: 10),
|
const Text('Feedback, Anregungen, Ideen, Fehler und Verbesserungen', textAlign: TextAlign.center),
|
||||||
const Text('Bitte gib keine geheimen Daten wie z.B. Passwörter weiter.', style: TextStyle(fontSize: 10)),
|
const SizedBox(height: 15),
|
||||||
const SizedBox(height: 10),
|
const Text('Bitte gib keine geheimen Daten wie z.B. Passwörter weiter.', textAlign: TextAlign.center, style: TextStyle(fontSize: 11)),
|
||||||
TextField(
|
const SizedBox(height: 20),
|
||||||
controller: _feedbackInput,
|
Padding(
|
||||||
autofocus: true,
|
padding: const EdgeInsets.all(10),
|
||||||
decoration: const InputDecoration(
|
child: TextField(
|
||||||
border: OutlineInputBorder(),
|
controller: _feedbackInput,
|
||||||
label: Text('Feedback und Verbesserungen')
|
autofocus: true,
|
||||||
|
decoration: InputDecoration(
|
||||||
|
border: const OutlineInputBorder(),
|
||||||
|
label: const Text('Feedback und Verbesserungen'),
|
||||||
|
errorText: _textFieldEmpty ? 'Bitte gib eine Beschreibung an' : null,
|
||||||
|
),
|
||||||
|
minLines: 4,
|
||||||
|
maxLines: 7,
|
||||||
),
|
),
|
||||||
// style: TextStyle(),
|
|
||||||
// expands: true,
|
|
||||||
minLines: 3,
|
|
||||||
maxLines: 5,
|
|
||||||
),
|
),
|
||||||
Visibility(
|
const SizedBox(height: 10),
|
||||||
visible: _error != null,
|
if(_image != null) Row(
|
||||||
child: Text('Senden fehlgeschlagen: $_error', style: const TextStyle(color: Colors.red))
|
mainAxisAlignment: MainAxisAlignment.center,
|
||||||
Pupsi marked this conversation as resolved
Outdated
MineTec
commented
bitte hier nochmal auf das Design achten, du kannst einen offline betrieb im emulator mithilfe des flugmodus in der Benachrichtigungsleiste simulieren bitte hier nochmal auf das Design achten, du kannst einen offline betrieb im emulator mithilfe des flugmodus in der Benachrichtigungsleiste simulieren
|
|||||||
|
children: [
|
||||||
|
badges.Badge(
|
||||||
|
badgeContent: const Icon(Icons.close_outlined, size: 17),
|
||||||
|
badgeStyle: const badges.BadgeStyle(
|
||||||
|
padding: EdgeInsets.all(2),
|
||||||
|
),
|
||||||
|
child: Container(
|
||||||
|
decoration: BoxDecoration(
|
||||||
|
borderRadius: const BorderRadius.all(Radius.circular(5)),
|
||||||
|
border: Border.all(
|
||||||
|
width: 3,
|
||||||
|
color: Theme.of(context).primaryColor,
|
||||||
|
),
|
||||||
|
),
|
||||||
|
height: 150,
|
||||||
|
child: Image(
|
||||||
|
image: Image.memory(_image!).image,
|
||||||
|
fit: BoxFit.contain,
|
||||||
|
),
|
||||||
|
),
|
||||||
|
onTap: () async {
|
||||||
|
setState(() {
|
||||||
|
_image = null;
|
||||||
|
});
|
||||||
|
},
|
||||||
|
),
|
||||||
|
],
|
||||||
|
),
|
||||||
|
Padding(
|
||||||
|
padding: const EdgeInsets.all(5),
|
||||||
|
child: Visibility(
|
||||||
|
visible: _error != null,
|
||||||
|
child: Visibility(
|
||||||
|
visible: Provider.of<SettingsProvider>(context, listen: false).val().devToolsEnabled,
|
||||||
|
replacement: const Text('Senden fehlgeschlagen, bitte überprüfe die Internetverbindung.', textAlign: TextAlign.center, style: TextStyle(color: Colors.red)),
|
||||||
|
child: Text('Senden fehlgeschlagen: \n $_error', textAlign: TextAlign.center, style: const TextStyle(color: Colors.red)),
|
||||||
|
),
|
||||||
|
),
|
||||||
|
),
|
||||||
|
Padding(
|
||||||
|
padding: const EdgeInsets.only(right: 20, left: 10),
|
||||||
|
child: Row(
|
||||||
|
mainAxisAlignment: MainAxisAlignment.end,
|
||||||
|
children: [
|
||||||
|
Visibility(
|
||||||
|
visible: _image == null,
|
||||||
|
child: IconButton(
|
||||||
|
onPressed: () async {
|
||||||
|
context.loaderOverlay.show();
|
||||||
|
var imageData = await (await FilePick.galleryPick())?.readAsBytes();
|
||||||
Pupsi marked this conversation as resolved
Outdated
MineTec
commented
raus wenn es nicht benötigt wird raus wenn es nicht benötigt wird
|
|||||||
|
context.loaderOverlay.hide();
|
||||||
|
setState(() {
|
||||||
|
_image = imageData;
|
||||||
|
});
|
||||||
|
},
|
||||||
|
icon: const Icon(Icons.attach_file_outlined),
|
||||||
|
),
|
||||||
|
),
|
||||||
|
const Expanded(child: SizedBox.shrink()),
|
||||||
|
TextButton(
|
||||||
|
onPressed: () async {
|
||||||
|
if(_feedbackInput.text.isEmpty){
|
||||||
|
setState(() {
|
||||||
|
_textFieldEmpty = true;
|
||||||
|
});
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
context.loaderOverlay.show();
|
||||||
|
AddFeedback(
|
||||||
|
AddFeedbackParams(
|
||||||
|
user: AccountData().getUserSecret(),
|
||||||
|
feedback: _feedbackInput.text,
|
||||||
|
screenshot: _image != null ? base64Encode(_image!) : null,
|
||||||
|
appVersion: int.parse((await PackageInfo.fromPlatform()).buildNumber),
|
||||||
|
)
|
||||||
|
).run().then((value) {
|
||||||
|
Navigator.of(context).pop();
|
||||||
|
InfoDialog.show(context, 'Danke für dein Feedback!');
|
||||||
|
context.loaderOverlay.hide();
|
||||||
|
}).catchError((error, trace) {
|
||||||
|
setState(() {
|
||||||
|
_error = error.toString();
|
||||||
|
});
|
||||||
|
context.loaderOverlay.hide();
|
||||||
|
});
|
||||||
|
},
|
||||||
|
child: const Text('Senden'),
|
||||||
|
)
|
||||||
|
]
|
||||||
|
)
|
||||||
)
|
)
|
||||||
|
|
||||||
],
|
],
|
||||||
),
|
),
|
||||||
actions: [
|
|
||||||
TextButton(onPressed: () => Navigator.of(context).pop(), child: const Text('Abbrechen')),
|
|
||||||
TextButton(
|
|
||||||
onPressed: () async {
|
|
||||||
AddFeedback(
|
|
||||||
AddFeedbackParams(
|
|
||||||
user: AccountData().getUserSecret(),
|
|
||||||
feedback: _feedbackInput.text,
|
|
||||||
appVersion: int.parse((await PackageInfo.fromPlatform()).buildNumber)
|
|
||||||
)
|
|
||||||
)
|
|
||||||
.run()
|
|
||||||
.then((value) {
|
|
||||||
Navigator.of(context).pop();
|
|
||||||
InfoDialog.show(context, 'Danke für dein Feedback!');
|
|
||||||
})
|
|
||||||
.catchError((error, trace) {
|
|
||||||
setState(() {
|
|
||||||
_error = error.toString();
|
|
||||||
});
|
|
||||||
});
|
|
||||||
},
|
|
||||||
child: const Text('Senden'),
|
|
||||||
)
|
|
||||||
],
|
|
||||||
);
|
);
|
||||||
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -74,7 +74,7 @@ class Overhang extends StatelessWidget {
|
|||||||
title: const Text('Du hast eine Idee?'),
|
title: const Text('Du hast eine Idee?'),
|
||||||
subtitle: const Text('Fehler und Verbessungsvorschläge'),
|
subtitle: const Text('Fehler und Verbessungsvorschläge'),
|
||||||
trailing: const Icon(Icons.arrow_right),
|
trailing: const Icon(Icons.arrow_right),
|
||||||
onTap: () => showDialog(context: context, barrierDismissible: false, builder: (context) => const FeedbackDialog()),
|
onTap: () => pushScreen(context, withNavBar: false, screen: const FeedbackDialog()),
|
||||||
),
|
),
|
||||||
],
|
],
|
||||||
),
|
),
|
||||||
|
Loading…
x
Reference in New Issue
Block a user
?