mirror of
https://gitlab.com/comunic/comunicmobile
synced 2024-12-30 14:58:52 +00:00
217 lines
5.9 KiB
Dart
217 lines
5.9 KiB
Dart
import 'package:comunic/helpers/survey_helper.dart';
|
|
import 'package:comunic/models/survey.dart';
|
|
import 'package:comunic/models/survey_choice.dart';
|
|
import 'package:comunic/ui/widgets/safe_state.dart';
|
|
import 'package:comunic/utils/intl_utils.dart';
|
|
import 'package:comunic/utils/ui_utils.dart';
|
|
import 'package:flutter/material.dart';
|
|
import 'package:pie_chart/pie_chart.dart';
|
|
|
|
/// Survey widget
|
|
///
|
|
/// @author Pierre HUBERT
|
|
|
|
class SurveyWidget extends StatefulWidget {
|
|
final Survey survey;
|
|
final Function(Survey) onUpdated;
|
|
|
|
const SurveyWidget({
|
|
Key key,
|
|
@required this.survey,
|
|
@required this.onUpdated,
|
|
}) : assert(survey != null),
|
|
assert(onUpdated != null),
|
|
super(key: key);
|
|
|
|
@override
|
|
_SurveyWidgetState createState() => _SurveyWidgetState();
|
|
}
|
|
|
|
class _SurveyWidgetState extends SafeState<SurveyWidget> {
|
|
final SurveyHelper _helper = SurveyHelper();
|
|
|
|
Survey get survey => widget.survey;
|
|
|
|
Map<String, double> _buildDataMap() {
|
|
Map<String, double> data = Map();
|
|
widget.survey.choices.forEach((e) => data.putIfAbsent(
|
|
e.name + " (" + e.responses.toString() + ")", () => 1.0 * e.responses));
|
|
return data;
|
|
}
|
|
|
|
@override
|
|
Widget build(BuildContext context) {
|
|
return Column(
|
|
children: <Widget>[
|
|
Text(
|
|
widget.survey.question,
|
|
style: TextStyle(fontWeight: FontWeight.bold),
|
|
),
|
|
_buildUserResponse(),
|
|
|
|
// Offer the user to create a new choice on the survey, if possible
|
|
survey.allowNewChoicesCreation ? _buildNewChoiceLink() : Container(),
|
|
|
|
// Offer to block the creation of new responses, if possible
|
|
survey.canBlockNewChoicesCreation
|
|
? _buildBlockNewResponsesLink()
|
|
: Container(),
|
|
|
|
survey.hasResponses ? _buildChart() : _buildNoResponseNotice(),
|
|
],
|
|
);
|
|
}
|
|
|
|
Widget _buildUserResponse() {
|
|
if (survey.hasResponded) return _buildUserRespondedWidget();
|
|
return _buildUserResponseFormWidget();
|
|
}
|
|
|
|
Widget _buildUserRespondedWidget() {
|
|
return Row(
|
|
mainAxisAlignment: MainAxisAlignment.center,
|
|
children: <Widget>[
|
|
Flexible(
|
|
child: Text(
|
|
tr("Your response: %response%",
|
|
args: {"response": survey.userResponse.name}),
|
|
textAlign: TextAlign.center,
|
|
),
|
|
),
|
|
MaterialButton(
|
|
child: Text(tr("Cancel").toUpperCase()),
|
|
onPressed: _cancelUserResponse,
|
|
)
|
|
],
|
|
);
|
|
}
|
|
|
|
Future<void> _cancelUserResponse() async {
|
|
if (!await showConfirmDialog(
|
|
context: context,
|
|
title: tr("Cancel response to survey"),
|
|
message:
|
|
tr("Do you really want to cancel your response to this survey ?"),
|
|
)) return;
|
|
|
|
if (!await _helper.cancelResponse(survey)) {
|
|
showSimpleSnack(
|
|
context, tr("Could not cancel your response to the survey !"));
|
|
return;
|
|
}
|
|
|
|
setState(() {
|
|
survey.cancelUserResponse();
|
|
});
|
|
}
|
|
|
|
Widget _buildUserResponseFormWidget() {
|
|
return ConstrainedBox(
|
|
constraints: BoxConstraints(maxWidth: 300),
|
|
child: DropdownButton<SurveyChoice>(
|
|
isExpanded: true,
|
|
hint: Text(tr("Respond to survey")),
|
|
items: survey.choices
|
|
.map(
|
|
(f) => DropdownMenuItem<SurveyChoice>(
|
|
value: f,
|
|
child: Text(f.name),
|
|
),
|
|
)
|
|
.toList(),
|
|
onChanged: _respondToSurvey,
|
|
),
|
|
);
|
|
}
|
|
|
|
Widget _buildNewChoiceLink() => Padding(
|
|
padding: const EdgeInsets.all(8.0),
|
|
child: InkWell(
|
|
onTap: _createNewChoices,
|
|
child: Text(tr("Create a new choice")),
|
|
),
|
|
);
|
|
|
|
Widget _buildBlockNewResponsesLink() => Padding(
|
|
padding: const EdgeInsets.all(8.0),
|
|
child: InkWell(
|
|
onTap: _blockNewChoices,
|
|
child: Text(tr("Block the creation of new responses")),
|
|
),
|
|
);
|
|
|
|
Widget _buildChart() {
|
|
return PieChart(
|
|
dataMap: _buildDataMap(),
|
|
);
|
|
}
|
|
|
|
Widget _buildNoResponseNotice() {
|
|
return Padding(
|
|
padding: const EdgeInsets.all(16.0),
|
|
child: Text(tr("No response yet to this survey.")),
|
|
);
|
|
}
|
|
|
|
/// Respond to survey
|
|
Future<void> _respondToSurvey(SurveyChoice choice) async {
|
|
// Send the response to the server
|
|
if (!await _helper.respondToSurvey(survey: survey, choice: choice))
|
|
return showSimpleSnack(
|
|
context, tr("Could not send your response to the survey!"));
|
|
|
|
setState(() {
|
|
survey.setUserResponse(choice);
|
|
});
|
|
}
|
|
|
|
/// Reload survey information
|
|
///
|
|
/// Throws in case of failure
|
|
Future<void> _reloadSurvey() async {
|
|
final newSurvey = await SurveyHelper.getSurveyInfo(widget.survey.postID);
|
|
widget.onUpdated(newSurvey);
|
|
}
|
|
|
|
/// Create a new choice
|
|
void _createNewChoices() async {
|
|
try {
|
|
final newChoice = await askUserString(
|
|
context: context,
|
|
title: tr("New choice"),
|
|
message: tr("Please specify the new choice for the survey"),
|
|
defaultValue: "",
|
|
hint: tr("New choice..."),
|
|
maxLength: 50,
|
|
);
|
|
|
|
if (newChoice == null || newChoice.isEmpty) return;
|
|
|
|
await SurveyHelper.createNewChoice(survey.postID, newChoice);
|
|
|
|
await _reloadSurvey();
|
|
} catch (e, s) {
|
|
print("Could not create new survey choice! $e\n$s");
|
|
showSimpleSnack(
|
|
context, tr("Could not create a new choice for this survey!"));
|
|
}
|
|
}
|
|
|
|
/// Block the creation of new choices on this survey
|
|
void _blockNewChoices() async {
|
|
try {
|
|
if (!await showConfirmDialog(
|
|
context: context,
|
|
message: tr("Do you really want to block new choices creation?"))) return;
|
|
|
|
await SurveyHelper.blockNewChoicesCreation(survey.postID);
|
|
|
|
setState(() => survey.allowNewChoicesCreation = false);
|
|
} catch (e, s) {
|
|
print("Could not block the creation of new choices! $e\n$s");
|
|
showSimpleSnack(
|
|
context, tr("Could not block the creation of new choices!"));
|
|
}
|
|
}
|
|
}
|