♻️ Extract the poll related words
This commit is contained in:
@@ -799,5 +799,42 @@
|
|||||||
"filesListAdditional": {
|
"filesListAdditional": {
|
||||||
"one": "+{} file remaining",
|
"one": "+{} file remaining",
|
||||||
"other": "+{} files remaining"
|
"other": "+{} files remaining"
|
||||||
}
|
},
|
||||||
}
|
"pollAnswerSubmitted": "Poll answer has been submitted.",
|
||||||
|
"modifyAnswers": "Modify Answers",
|
||||||
|
"back": "Back",
|
||||||
|
"submit": "Submit",
|
||||||
|
"pollOptionDefaultLabel": "Option 1",
|
||||||
|
"pollUpdated": "Poll updated.",
|
||||||
|
"pollCreated": "Poll created.",
|
||||||
|
"pollCreate": "Create Poll",
|
||||||
|
"pollEdit": "Edit Poll",
|
||||||
|
"pollPreviewJsonDebug": "Debug Preview",
|
||||||
|
"pollTitleRequired": "Title is required",
|
||||||
|
"pollEndDateOptional": "End date & time (optional)",
|
||||||
|
"notSet": "Not set",
|
||||||
|
"pick": "Pick",
|
||||||
|
"clear": "Clear",
|
||||||
|
"questions": "Questions",
|
||||||
|
"pollAddQuestion": "Add question",
|
||||||
|
"pollQuestionTypeSingleChoice": "Single choice",
|
||||||
|
"pollQuestionTypeMultipleChoice": "Multiple choice",
|
||||||
|
"pollQuestionTypeFreeText": "Free text",
|
||||||
|
"pollQuestionTypeYesNo": "Yes / No",
|
||||||
|
"pollQuestionTypeRating": "Rating",
|
||||||
|
"pollNoQuestionsYet": "No questions yet",
|
||||||
|
"pollNoQuestionsHint": "Use \"Add question\" to start building your poll.",
|
||||||
|
"pollDebugPreview": "Debug Preview",
|
||||||
|
"pollUntitledQuestion": "Untitled question",
|
||||||
|
"moveUp": "Move up",
|
||||||
|
"moveDown": "Move down",
|
||||||
|
"required": "Required",
|
||||||
|
"pollQuestionTitle": "Question title",
|
||||||
|
"pollQuestionTitleRequired": "Question title is required",
|
||||||
|
"pollQuestionDescriptionOptional": "Question description (optional)",
|
||||||
|
"options": "Options",
|
||||||
|
"pollAddOption": "Add option",
|
||||||
|
"pollOptionLabel": "Option label",
|
||||||
|
"pollLongTextAnswerPreview": "Long text answer (preview)",
|
||||||
|
"pollShortTextAnswerPreview": "Short text answer (preview)"
|
||||||
|
}
|
@@ -1,5 +1,5 @@
|
|||||||
import 'package:firebase_analytics/firebase_analytics.dart';
|
import 'package:firebase_analytics/firebase_analytics.dart';
|
||||||
import 'package:firebase_analytics/observer.dart';
|
|
||||||
import 'package:flutter/material.dart';
|
import 'package:flutter/material.dart';
|
||||||
import 'package:go_router/go_router.dart';
|
import 'package:go_router/go_router.dart';
|
||||||
import 'package:hooks_riverpod/hooks_riverpod.dart';
|
import 'package:hooks_riverpod/hooks_riverpod.dart';
|
||||||
|
@@ -11,6 +11,7 @@ import 'package:island/widgets/alert.dart';
|
|||||||
import 'package:island/models/poll.dart';
|
import 'package:island/models/poll.dart';
|
||||||
import 'package:island/widgets/app_scaffold.dart';
|
import 'package:island/widgets/app_scaffold.dart';
|
||||||
import 'package:uuid/uuid.dart';
|
import 'package:uuid/uuid.dart';
|
||||||
|
import 'package:easy_localization/easy_localization.dart';
|
||||||
|
|
||||||
class PollEditorState {
|
class PollEditorState {
|
||||||
String? id; // for editing
|
String? id; // for editing
|
||||||
@@ -110,7 +111,7 @@ class PollEditor extends Notifier<PollEditorState> {
|
|||||||
? [
|
? [
|
||||||
SnPollOption(
|
SnPollOption(
|
||||||
id: const Uuid().v4(),
|
id: const Uuid().v4(),
|
||||||
label: 'Option 1',
|
label: 'pollOptionDefaultLabel'.tr(),
|
||||||
order: 0,
|
order: 0,
|
||||||
),
|
),
|
||||||
]
|
]
|
||||||
@@ -191,7 +192,7 @@ class PollEditor extends Notifier<PollEditorState> {
|
|||||||
: [
|
: [
|
||||||
SnPollOption(
|
SnPollOption(
|
||||||
id: const Uuid().v4(),
|
id: const Uuid().v4(),
|
||||||
label: 'Option 1',
|
label: 'pollOptionDefaultLabel'.tr(),
|
||||||
order: 0,
|
order: 0,
|
||||||
),
|
),
|
||||||
])
|
])
|
||||||
@@ -389,7 +390,7 @@ class PollEditorScreen extends ConsumerWidget {
|
|||||||
data: body,
|
data: body,
|
||||||
));
|
));
|
||||||
|
|
||||||
showSnackBar(isUpdate ? 'Poll updated.' : 'Poll created.');
|
showSnackBar(isUpdate ? 'pollUpdated'.tr() : 'pollCreated'.tr());
|
||||||
|
|
||||||
if (!context.mounted) return;
|
if (!context.mounted) return;
|
||||||
Navigator.of(context).maybePop(res.data);
|
Navigator.of(context).maybePop(res.data);
|
||||||
@@ -416,11 +417,11 @@ class PollEditorScreen extends ConsumerWidget {
|
|||||||
|
|
||||||
return AppScaffold(
|
return AppScaffold(
|
||||||
appBar: AppBar(
|
appBar: AppBar(
|
||||||
title: Text(model.id == null ? 'Create Poll' : 'Edit Poll'),
|
title: Text(model.id == null ? 'pollCreate'.tr() : 'pollEdit'.tr()),
|
||||||
actions: [
|
actions: [
|
||||||
if (kDebugMode)
|
if (kDebugMode)
|
||||||
IconButton(
|
IconButton(
|
||||||
tooltip: 'Preview JSON (debug)',
|
tooltip: 'pollPreviewJsonDebug'.tr(),
|
||||||
onPressed: () {
|
onPressed: () {
|
||||||
_showDebugPreview(context, model);
|
_showDebugPreview(context, model);
|
||||||
},
|
},
|
||||||
@@ -439,8 +440,8 @@ class PollEditorScreen extends ConsumerWidget {
|
|||||||
children: [
|
children: [
|
||||||
TextFormField(
|
TextFormField(
|
||||||
initialValue: model.title ?? '',
|
initialValue: model.title ?? '',
|
||||||
decoration: const InputDecoration(
|
decoration: InputDecoration(
|
||||||
labelText: 'Title',
|
labelText: 'title'.tr(),
|
||||||
border: OutlineInputBorder(
|
border: OutlineInputBorder(
|
||||||
borderRadius: BorderRadius.all(Radius.circular(16)),
|
borderRadius: BorderRadius.all(Radius.circular(16)),
|
||||||
),
|
),
|
||||||
@@ -452,7 +453,7 @@ class PollEditorScreen extends ConsumerWidget {
|
|||||||
(_) => FocusManager.instance.primaryFocus?.unfocus(),
|
(_) => FocusManager.instance.primaryFocus?.unfocus(),
|
||||||
validator: (v) {
|
validator: (v) {
|
||||||
if (v == null || v.trim().isEmpty) {
|
if (v == null || v.trim().isEmpty) {
|
||||||
return 'Title is required';
|
return 'pollTitleRequired'.tr();
|
||||||
}
|
}
|
||||||
return null;
|
return null;
|
||||||
},
|
},
|
||||||
@@ -460,8 +461,8 @@ class PollEditorScreen extends ConsumerWidget {
|
|||||||
const Gap(12),
|
const Gap(12),
|
||||||
TextFormField(
|
TextFormField(
|
||||||
initialValue: model.description ?? '',
|
initialValue: model.description ?? '',
|
||||||
decoration: const InputDecoration(
|
decoration: InputDecoration(
|
||||||
labelText: 'Description',
|
labelText: 'description'.tr(),
|
||||||
alignLabelWithHint: true,
|
alignLabelWithHint: true,
|
||||||
border: OutlineInputBorder(
|
border: OutlineInputBorder(
|
||||||
borderRadius: BorderRadius.all(Radius.circular(16)),
|
borderRadius: BorderRadius.all(Radius.circular(16)),
|
||||||
@@ -482,7 +483,7 @@ class PollEditorScreen extends ConsumerWidget {
|
|||||||
Row(
|
Row(
|
||||||
children: [
|
children: [
|
||||||
Text(
|
Text(
|
||||||
'Questions',
|
'questions'.tr(),
|
||||||
style: Theme.of(context).textTheme.titleLarge,
|
style: Theme.of(context).textTheme.titleLarge,
|
||||||
),
|
),
|
||||||
const Spacer(),
|
const Spacer(),
|
||||||
@@ -495,7 +496,7 @@ class PollEditorScreen extends ConsumerWidget {
|
|||||||
: controller.open();
|
: controller.open();
|
||||||
},
|
},
|
||||||
icon: const Icon(Icons.add),
|
icon: const Icon(Icons.add),
|
||||||
label: const Text('Add question'),
|
label: Text('pollAddQuestion'.tr()),
|
||||||
);
|
);
|
||||||
},
|
},
|
||||||
menuChildren:
|
menuChildren:
|
||||||
@@ -514,9 +515,9 @@ class PollEditorScreen extends ConsumerWidget {
|
|||||||
const Gap(8),
|
const Gap(8),
|
||||||
if (model.questions.isEmpty)
|
if (model.questions.isEmpty)
|
||||||
_EmptyState(
|
_EmptyState(
|
||||||
title: 'No questions yet',
|
title: 'pollNoQuestionsYet'.tr(),
|
||||||
subtitle:
|
subtitle:
|
||||||
'Use "Add question" to start building your poll.',
|
'pollNoQuestionsHint'.tr(),
|
||||||
)
|
)
|
||||||
else
|
else
|
||||||
ReorderableListView.builder(
|
ReorderableListView.builder(
|
||||||
@@ -585,7 +586,7 @@ class PollEditorScreen extends ConsumerWidget {
|
|||||||
Navigator.of(context).maybePop();
|
Navigator.of(context).maybePop();
|
||||||
},
|
},
|
||||||
icon: const Icon(Icons.close),
|
icon: const Icon(Icons.close),
|
||||||
label: const Text('Cancel'),
|
label: Text('cancel'.tr()),
|
||||||
),
|
),
|
||||||
const Spacer(),
|
const Spacer(),
|
||||||
FilledButton.icon(
|
FilledButton.icon(
|
||||||
@@ -593,7 +594,7 @@ class PollEditorScreen extends ConsumerWidget {
|
|||||||
_submitPoll(context, ref);
|
_submitPoll(context, ref);
|
||||||
},
|
},
|
||||||
icon: const Icon(Icons.cloud_upload_outlined),
|
icon: const Icon(Icons.cloud_upload_outlined),
|
||||||
label: Text(model.id == null ? 'Create' : 'Update'),
|
label: Text(model.id == null ? 'create'.tr() : 'update'.tr()),
|
||||||
),
|
),
|
||||||
],
|
],
|
||||||
),
|
),
|
||||||
@@ -637,14 +638,14 @@ class PollEditorScreen extends ConsumerWidget {
|
|||||||
context: context,
|
context: context,
|
||||||
builder:
|
builder:
|
||||||
(_) => AlertDialog(
|
(_) => AlertDialog(
|
||||||
title: const Text('Debug Preview'),
|
title: Text('pollDebugPreview'.tr()),
|
||||||
content: SingleChildScrollView(
|
content: SingleChildScrollView(
|
||||||
child: SelectableText(buf.toString()),
|
child: SelectableText(buf.toString()),
|
||||||
),
|
),
|
||||||
actions: [
|
actions: [
|
||||||
TextButton(
|
TextButton(
|
||||||
onPressed: () => Navigator.of(context).pop(),
|
onPressed: () => Navigator.of(context).pop(),
|
||||||
child: const Text('Close'),
|
child: Text('close'.tr()),
|
||||||
),
|
),
|
||||||
],
|
],
|
||||||
),
|
),
|
||||||
@@ -673,15 +674,15 @@ IconData _iconForType(SnPollQuestionType t) {
|
|||||||
String _labelForType(SnPollQuestionType t) {
|
String _labelForType(SnPollQuestionType t) {
|
||||||
switch (t) {
|
switch (t) {
|
||||||
case SnPollQuestionType.singleChoice:
|
case SnPollQuestionType.singleChoice:
|
||||||
return 'Single choice';
|
return 'pollQuestionTypeSingleChoice'.tr();
|
||||||
case SnPollQuestionType.multipleChoice:
|
case SnPollQuestionType.multipleChoice:
|
||||||
return 'Multiple choice';
|
return 'pollQuestionTypeMultipleChoice'.tr();
|
||||||
case SnPollQuestionType.freeText:
|
case SnPollQuestionType.freeText:
|
||||||
return 'Free text';
|
return 'pollQuestionTypeFreeText'.tr();
|
||||||
case SnPollQuestionType.yesNo:
|
case SnPollQuestionType.yesNo:
|
||||||
return 'Yes / No';
|
return 'pollQuestionTypeYesNo'.tr();
|
||||||
case SnPollQuestionType.rating:
|
case SnPollQuestionType.rating:
|
||||||
return 'Rating';
|
return 'pollQuestionTypeRating'.tr();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -698,8 +699,8 @@ class _EndDatePicker extends StatelessWidget {
|
|||||||
children: [
|
children: [
|
||||||
Expanded(
|
Expanded(
|
||||||
child: InputDecorator(
|
child: InputDecorator(
|
||||||
decoration: const InputDecoration(
|
decoration: InputDecoration(
|
||||||
labelText: 'End date & time (optional)',
|
labelText: 'pollEndDateOptional'.tr(),
|
||||||
border: OutlineInputBorder(
|
border: OutlineInputBorder(
|
||||||
borderRadius: BorderRadius.all(Radius.circular(16)),
|
borderRadius: BorderRadius.all(Radius.circular(16)),
|
||||||
),
|
),
|
||||||
@@ -711,7 +712,7 @@ class _EndDatePicker extends StatelessWidget {
|
|||||||
Icon(Icons.event, color: Theme.of(context).colorScheme.primary),
|
Icon(Icons.event, color: Theme.of(context).colorScheme.primary),
|
||||||
Text(
|
Text(
|
||||||
value == null
|
value == null
|
||||||
? 'Not set'
|
? 'notSet'.tr()
|
||||||
: MaterialLocalizations.of(
|
: MaterialLocalizations.of(
|
||||||
context,
|
context,
|
||||||
).formatFullDate(value!),
|
).formatFullDate(value!),
|
||||||
@@ -759,12 +760,12 @@ class _EndDatePicker extends StatelessWidget {
|
|||||||
);
|
);
|
||||||
onChanged(dt);
|
onChanged(dt);
|
||||||
},
|
},
|
||||||
child: const Text('Pick'),
|
child: Text('pick'.tr()),
|
||||||
),
|
),
|
||||||
if (value != null)
|
if (value != null)
|
||||||
TextButton(
|
TextButton(
|
||||||
onPressed: () => onChanged(null),
|
onPressed: () => onChanged(null),
|
||||||
child: const Text('Clear'),
|
child: Text('clear'.tr()),
|
||||||
),
|
),
|
||||||
],
|
],
|
||||||
),
|
),
|
||||||
@@ -799,7 +800,7 @@ class _QuestionHeader extends StatelessWidget {
|
|||||||
child: const Icon(Icons.drag_handle),
|
child: const Icon(Icons.drag_handle),
|
||||||
),
|
),
|
||||||
title: Text(
|
title: Text(
|
||||||
question.title.isEmpty ? 'Untitled question' : question.title,
|
question.title.isEmpty ? 'pollUntitledQuestion'.tr() : question.title,
|
||||||
maxLines: 1,
|
maxLines: 1,
|
||||||
overflow: TextOverflow.ellipsis,
|
overflow: TextOverflow.ellipsis,
|
||||||
),
|
),
|
||||||
@@ -808,17 +809,17 @@ class _QuestionHeader extends StatelessWidget {
|
|||||||
spacing: 4,
|
spacing: 4,
|
||||||
children: [
|
children: [
|
||||||
IconButton(
|
IconButton(
|
||||||
tooltip: 'Move up',
|
tooltip: 'moveUp'.tr(),
|
||||||
onPressed: onMoveUp,
|
onPressed: onMoveUp,
|
||||||
icon: const Icon(Icons.arrow_upward),
|
icon: const Icon(Icons.arrow_upward),
|
||||||
),
|
),
|
||||||
IconButton(
|
IconButton(
|
||||||
tooltip: 'Move down',
|
tooltip: 'moveDown'.tr(),
|
||||||
onPressed: onMoveDown,
|
onPressed: onMoveDown,
|
||||||
icon: const Icon(Icons.arrow_downward),
|
icon: const Icon(Icons.arrow_downward),
|
||||||
),
|
),
|
||||||
IconButton(
|
IconButton(
|
||||||
tooltip: 'Delete',
|
tooltip: 'delete'.tr(),
|
||||||
onPressed: onDelete,
|
onPressed: onDelete,
|
||||||
icon: const Icon(Icons.delete_outline),
|
icon: const Icon(Icons.delete_outline),
|
||||||
color: Theme.of(context).colorScheme.error,
|
color: Theme.of(context).colorScheme.error,
|
||||||
@@ -853,7 +854,7 @@ class _QuestionEditor extends ConsumerWidget {
|
|||||||
onChanged: (t) => notifier.setQuestionType(index, t),
|
onChanged: (t) => notifier.setQuestionType(index, t),
|
||||||
),
|
),
|
||||||
FilterChip(
|
FilterChip(
|
||||||
label: const Text('Required'),
|
label: Text('required'.tr()),
|
||||||
selected: question.isRequired,
|
selected: question.isRequired,
|
||||||
onSelected: (v) => notifier.setQuestionRequired(index, v),
|
onSelected: (v) => notifier.setQuestionRequired(index, v),
|
||||||
avatar: Icon(
|
avatar: Icon(
|
||||||
@@ -867,8 +868,8 @@ class _QuestionEditor extends ConsumerWidget {
|
|||||||
const Gap(12),
|
const Gap(12),
|
||||||
TextFormField(
|
TextFormField(
|
||||||
initialValue: question.title,
|
initialValue: question.title,
|
||||||
decoration: const InputDecoration(
|
decoration: InputDecoration(
|
||||||
labelText: 'Question title',
|
labelText: 'pollQuestionTitle'.tr(),
|
||||||
border: OutlineInputBorder(
|
border: OutlineInputBorder(
|
||||||
borderRadius: BorderRadius.all(Radius.circular(16)),
|
borderRadius: BorderRadius.all(Radius.circular(16)),
|
||||||
),
|
),
|
||||||
@@ -879,7 +880,7 @@ class _QuestionEditor extends ConsumerWidget {
|
|||||||
onTapOutside: (_) => FocusManager.instance.primaryFocus?.unfocus(),
|
onTapOutside: (_) => FocusManager.instance.primaryFocus?.unfocus(),
|
||||||
validator: (v) {
|
validator: (v) {
|
||||||
if (v == null || v.trim().isEmpty) {
|
if (v == null || v.trim().isEmpty) {
|
||||||
return 'Question title is required';
|
return 'pollQuestionTitleRequired'.tr();
|
||||||
}
|
}
|
||||||
return null;
|
return null;
|
||||||
},
|
},
|
||||||
@@ -887,8 +888,8 @@ class _QuestionEditor extends ConsumerWidget {
|
|||||||
const Gap(12),
|
const Gap(12),
|
||||||
TextFormField(
|
TextFormField(
|
||||||
initialValue: question.description ?? '',
|
initialValue: question.description ?? '',
|
||||||
decoration: const InputDecoration(
|
decoration: InputDecoration(
|
||||||
labelText: 'Question description (optional)',
|
labelText: 'pollQuestionDescriptionOptional'.tr(),
|
||||||
border: OutlineInputBorder(
|
border: OutlineInputBorder(
|
||||||
borderRadius: BorderRadius.all(Radius.circular(16)),
|
borderRadius: BorderRadius.all(Radius.circular(16)),
|
||||||
),
|
),
|
||||||
@@ -902,7 +903,7 @@ class _QuestionEditor extends ConsumerWidget {
|
|||||||
),
|
),
|
||||||
if (question.options != null) ...[
|
if (question.options != null) ...[
|
||||||
const Gap(16),
|
const Gap(16),
|
||||||
Text('Options', style: Theme.of(context).textTheme.titleMedium),
|
Text('options'.tr(), style: Theme.of(context).textTheme.titleMedium),
|
||||||
const Gap(8),
|
const Gap(8),
|
||||||
_OptionsEditor(index: index, options: question.options!),
|
_OptionsEditor(index: index, options: question.options!),
|
||||||
const Gap(4),
|
const Gap(4),
|
||||||
@@ -911,7 +912,7 @@ class _QuestionEditor extends ConsumerWidget {
|
|||||||
child: OutlinedButton.icon(
|
child: OutlinedButton.icon(
|
||||||
onPressed: () => notifier.addOption(index),
|
onPressed: () => notifier.addOption(index),
|
||||||
icon: const Icon(Icons.add),
|
icon: const Icon(Icons.add),
|
||||||
label: const Text('Add option'),
|
label: Text('pollAddOption'.tr()),
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
],
|
],
|
||||||
@@ -937,8 +938,8 @@ class _QuestionTypePicker extends StatelessWidget {
|
|||||||
Widget build(BuildContext context) {
|
Widget build(BuildContext context) {
|
||||||
return DropdownButtonFormField<SnPollQuestionType>(
|
return DropdownButtonFormField<SnPollQuestionType>(
|
||||||
value: value,
|
value: value,
|
||||||
decoration: const InputDecoration(
|
decoration: InputDecoration(
|
||||||
labelText: 'Type',
|
labelText: 'Type'.tr(),
|
||||||
border: OutlineInputBorder(
|
border: OutlineInputBorder(
|
||||||
borderRadius: BorderRadius.all(Radius.circular(16)),
|
borderRadius: BorderRadius.all(Radius.circular(16)),
|
||||||
),
|
),
|
||||||
@@ -987,8 +988,8 @@ class _OptionsEditor extends ConsumerWidget {
|
|||||||
child: TextFormField(
|
child: TextFormField(
|
||||||
key: ValueKey(options[i].id),
|
key: ValueKey(options[i].id),
|
||||||
initialValue: options[i].label,
|
initialValue: options[i].label,
|
||||||
decoration: const InputDecoration(
|
decoration: InputDecoration(
|
||||||
labelText: 'Option label',
|
labelText: 'pollOptionLabel'.tr(),
|
||||||
border: OutlineInputBorder(
|
border: OutlineInputBorder(
|
||||||
borderRadius: BorderRadius.all(Radius.circular(16)),
|
borderRadius: BorderRadius.all(Radius.circular(16)),
|
||||||
),
|
),
|
||||||
@@ -1003,7 +1004,7 @@ class _OptionsEditor extends ConsumerWidget {
|
|||||||
SizedBox(
|
SizedBox(
|
||||||
width: 40,
|
width: 40,
|
||||||
child: IconButton(
|
child: IconButton(
|
||||||
tooltip: 'Move up',
|
tooltip: 'moveUp'.tr(),
|
||||||
onPressed:
|
onPressed:
|
||||||
i > 0 ? () => notifier.moveOptionUp(index, i) : null,
|
i > 0 ? () => notifier.moveOptionUp(index, i) : null,
|
||||||
icon: const Icon(Icons.arrow_upward),
|
icon: const Icon(Icons.arrow_upward),
|
||||||
@@ -1012,7 +1013,7 @@ class _OptionsEditor extends ConsumerWidget {
|
|||||||
SizedBox(
|
SizedBox(
|
||||||
width: 40,
|
width: 40,
|
||||||
child: IconButton(
|
child: IconButton(
|
||||||
tooltip: 'Move down',
|
tooltip: 'moveDown'.tr(),
|
||||||
onPressed:
|
onPressed:
|
||||||
i < options.length - 1
|
i < options.length - 1
|
||||||
? () => notifier.moveOptionDown(index, i)
|
? () => notifier.moveOptionDown(index, i)
|
||||||
@@ -1023,7 +1024,7 @@ class _OptionsEditor extends ConsumerWidget {
|
|||||||
SizedBox(
|
SizedBox(
|
||||||
width: 40,
|
width: 40,
|
||||||
child: IconButton(
|
child: IconButton(
|
||||||
tooltip: 'Delete',
|
tooltip: 'delete'.tr(),
|
||||||
onPressed: () => notifier.removeOption(index, i),
|
onPressed: () => notifier.removeOption(index, i),
|
||||||
icon: const Icon(Icons.close),
|
icon: const Icon(Icons.close),
|
||||||
),
|
),
|
||||||
@@ -1048,7 +1049,7 @@ class _TextAnswerPreview extends StatelessWidget {
|
|||||||
maxLines: long ? 4 : 1,
|
maxLines: long ? 4 : 1,
|
||||||
decoration: InputDecoration(
|
decoration: InputDecoration(
|
||||||
labelText:
|
labelText:
|
||||||
long ? 'Long text answer (preview)' : 'Short text answer (preview)',
|
long ? 'pollLongTextAnswerPreview'.tr() : 'pollShortTextAnswerPreview'.tr(),
|
||||||
border: const OutlineInputBorder(
|
border: const OutlineInputBorder(
|
||||||
borderRadius: BorderRadius.all(Radius.circular(16)),
|
borderRadius: BorderRadius.all(Radius.circular(16)),
|
||||||
),
|
),
|
||||||
@@ -1082,9 +1083,9 @@ class _EmptyState extends StatelessWidget {
|
|||||||
child: Column(
|
child: Column(
|
||||||
crossAxisAlignment: CrossAxisAlignment.start,
|
crossAxisAlignment: CrossAxisAlignment.start,
|
||||||
children: [
|
children: [
|
||||||
Text(title, style: Theme.of(context).textTheme.titleMedium),
|
Text('pollNoQuestionsYet'.tr(), style: Theme.of(context).textTheme.titleMedium),
|
||||||
const Gap(4),
|
const Gap(4),
|
||||||
Text(subtitle, style: Theme.of(context).textTheme.bodyMedium),
|
Text('pollNoQuestionsHint'.tr(), style: Theme.of(context).textTheme.bodyMedium),
|
||||||
],
|
],
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
|
@@ -1,5 +1,6 @@
|
|||||||
import 'package:flutter/material.dart';
|
import 'package:flutter/material.dart';
|
||||||
import 'package:flutter/services.dart';
|
import 'package:flutter/services.dart';
|
||||||
|
import 'package:easy_localization/easy_localization.dart';
|
||||||
import 'package:flutter_riverpod/flutter_riverpod.dart';
|
import 'package:flutter_riverpod/flutter_riverpod.dart';
|
||||||
import 'package:island/models/poll.dart';
|
import 'package:island/models/poll.dart';
|
||||||
import 'package:island/pods/network.dart';
|
import 'package:island/pods/network.dart';
|
||||||
@@ -212,7 +213,7 @@ class _PollSubmitState extends ConsumerState<PollSubmit> {
|
|||||||
// Only call onSubmit after server accepts
|
// Only call onSubmit after server accepts
|
||||||
widget.onSubmit(Map<String, dynamic>.unmodifiable(_answers));
|
widget.onSubmit(Map<String, dynamic>.unmodifiable(_answers));
|
||||||
|
|
||||||
showSnackBar('Poll answer has been submitted.');
|
showSnackBar('pollAnswerSubmitted'.tr());
|
||||||
HapticFeedback.heavyImpact();
|
HapticFeedback.heavyImpact();
|
||||||
} catch (e) {
|
} catch (e) {
|
||||||
showErrorAlert(e);
|
showErrorAlert(e);
|
||||||
@@ -393,9 +394,9 @@ class _PollSubmitState extends ConsumerState<PollSubmit> {
|
|||||||
children: [
|
children: [
|
||||||
Expanded(
|
Expanded(
|
||||||
child: SegmentedButton<bool>(
|
child: SegmentedButton<bool>(
|
||||||
segments: const [
|
segments: [
|
||||||
ButtonSegment(value: true, label: Text('Yes')),
|
ButtonSegment(value: true, label: Text('yes'.tr())),
|
||||||
ButtonSegment(value: false, label: Text('No')),
|
ButtonSegment(value: false, label: Text('no'.tr())),
|
||||||
],
|
],
|
||||||
selected: _yesNoSelected == null ? {} : {_yesNoSelected!},
|
selected: _yesNoSelected == null ? {} : {_yesNoSelected!},
|
||||||
onSelectionChanged: (sel) {
|
onSelectionChanged: (sel) {
|
||||||
@@ -448,7 +449,7 @@ class _PollSubmitState extends ConsumerState<PollSubmit> {
|
|||||||
// If poll is submitted and not in modification mode, show "Modify" button
|
// If poll is submitted and not in modification mode, show "Modify" button
|
||||||
return FilledButton.icon(
|
return FilledButton.icon(
|
||||||
icon: const Icon(Icons.edit),
|
icon: const Icon(Icons.edit),
|
||||||
label: const Text('Modify Answers'),
|
label: Text('modifyAnswers'.tr()),
|
||||||
onPressed: () {
|
onPressed: () {
|
||||||
setState(() {
|
setState(() {
|
||||||
_isModifying = true;
|
_isModifying = true;
|
||||||
@@ -463,7 +464,7 @@ class _PollSubmitState extends ConsumerState<PollSubmit> {
|
|||||||
children: [
|
children: [
|
||||||
OutlinedButton.icon(
|
OutlinedButton.icon(
|
||||||
icon: const Icon(Icons.arrow_back),
|
icon: const Icon(Icons.arrow_back),
|
||||||
label: Text(_index == 0 ? 'Cancel' : 'Back'),
|
label: Text(_index == 0 ? 'cancel'.tr() : 'back'.tr()),
|
||||||
onPressed:
|
onPressed:
|
||||||
_submitting
|
_submitting
|
||||||
? null
|
? null
|
||||||
@@ -488,7 +489,7 @@ class _PollSubmitState extends ConsumerState<PollSubmit> {
|
|||||||
child: CircularProgressIndicator(strokeWidth: 2),
|
child: CircularProgressIndicator(strokeWidth: 2),
|
||||||
)
|
)
|
||||||
: Icon(isLast ? Icons.check : Icons.arrow_forward),
|
: Icon(isLast ? Icons.check : Icons.arrow_forward),
|
||||||
label: Text(isLast ? 'Submit' : 'Next'),
|
label: Text(isLast ? 'submit'.tr() : 'next'.tr()),
|
||||||
onPressed: canProceed ? _next : null,
|
onPressed: canProceed ? _next : null,
|
||||||
),
|
),
|
||||||
],
|
],
|
||||||
|
Reference in New Issue
Block a user