diff --git a/lib/app_state.dart b/lib/app_state.dart index 575d250..89dce7b 100644 --- a/lib/app_state.dart +++ b/lib/app_state.dart @@ -19,7 +19,7 @@ abstract class _AppState with Store { bool loaded = false; @observable - var uuid = Uuid(); + Uuid uuid = Uuid(); @observable String deviceId; diff --git a/lib/app_state.g.dart b/lib/app_state.g.dart index 69b2271..540cc84 100644 --- a/lib/app_state.g.dart +++ b/lib/app_state.g.dart @@ -26,6 +26,40 @@ mixin _$AppState on _AppState, Store { }, _$loadedAtom, name: '${_$loadedAtom.name}_set'); } + final _$uuidAtom = Atom(name: '_AppState.uuid'); + + @override + Uuid get uuid { + _$uuidAtom.context.enforceReadPolicy(_$uuidAtom); + _$uuidAtom.reportObserved(); + return super.uuid; + } + + @override + set uuid(Uuid value) { + _$uuidAtom.context.conditionallyRunInAction(() { + super.uuid = value; + _$uuidAtom.reportChanged(); + }, _$uuidAtom, name: '${_$uuidAtom.name}_set'); + } + + final _$deviceIdAtom = Atom(name: '_AppState.deviceId'); + + @override + String get deviceId { + _$deviceIdAtom.context.enforceReadPolicy(_$deviceIdAtom); + _$deviceIdAtom.reportObserved(); + return super.deviceId; + } + + @override + set deviceId(String value) { + _$deviceIdAtom.context.conditionallyRunInAction(() { + super.deviceId = value; + _$deviceIdAtom.reportChanged(); + }, _$deviceIdAtom, name: '${_$deviceIdAtom.name}_set'); + } + final _$gameStateAtom = Atom(name: '_AppState.gameState'); @override @@ -108,6 +142,15 @@ mixin _$AppState on _AppState, Store { return _$sendSavedGameLogsAsyncAction.run(() => super.sendSavedGameLogs()); } + final _$sendSavedWordsComplainsAsyncAction = + AsyncAction('sendSavedWordsComplains'); + + @override + Future sendSavedWordsComplains() { + return _$sendSavedWordsComplainsAsyncAction + .run(() => super.sendSavedWordsComplains()); + } + final _$loadAppAsyncAction = AsyncAction('loadApp'); @override @@ -127,6 +170,16 @@ mixin _$AppState on _AppState, Store { } } + @override + void saveWordsComplains(dynamic wordsComplains) { + final _$actionInfo = _$_AppStateActionController.startAction(); + try { + return super.saveWordsComplains(wordsComplains); + } finally { + _$_AppStateActionController.endAction(_$actionInfo); + } + } + @override void restoreDefaultSettings() { final _$actionInfo = _$_AppStateActionController.startAction(); diff --git a/lib/turn.dart b/lib/turn.dart index 74d4d5e..85675a2 100644 --- a/lib/turn.dart +++ b/lib/turn.dart @@ -2,6 +2,7 @@ import 'dart:collection'; import 'package:beret/app_state.dart'; import 'package:flutter/material.dart'; +import 'package:flutter/scheduler.dart'; import 'package:flutter_mobx/flutter_mobx.dart'; import 'package:provider/provider.dart'; @@ -333,7 +334,8 @@ class _RoundEditingState extends State { return showDialog( context: context, builder: (BuildContext context) => - WordComplainDialog()); + WordComplainDialog(word: currentState + .turnLog[idx]['word'])); }), DropdownButton( value: 'Не угадано', @@ -384,63 +386,98 @@ class _RoundEditingState extends State { child: ListTile( leading: Icon(Icons.check, color: Colors.green), title: Text(currentState.turnLog[idx]['word']), - trailing: DropdownButton( - value: 'Угадано', - onChanged: (value) { - setState(() { - if (value == 'Не угадано') { - currentState.turnLog[idx].remove('outcome'); - currentState.players[currentState.playerOneID] - .explainedWrong(); - currentState.players[currentState.playerTwoID] - .guessedWrong(); - } else if (value == 'Ошибка') { - currentState.turnLog[idx]['outcome'] = 'failed'; - currentState.hat.removeWord( - currentState.turnLog[idx]['word']); - currentState.players[currentState.playerOneID] - .explainedWrong(); - currentState.players[currentState.playerTwoID] - .guessedWrong(); - } - }); - }, - items: ['Угадано', 'Не угадано', 'Ошибка'] - .map>((String value) { - return DropdownMenuItem( - value: value, - child: Text(value), - ); - }).toList()))); + trailing: IntrinsicWidth( + child: Row(children: [ + IconButton( + icon: Icon(Icons.thumb_down), + onPressed: () { + return showDialog( + context: context, + builder: (BuildContext context) => + WordComplainDialog(word: currentState + .turnLog[idx]['word'])); + }), + DropdownButton( + value: 'Угадано', + onChanged: (value) { + setState(() { + if (value == 'Не угадано') { + currentState.turnLog[idx].remove('outcome'); + currentState.players[currentState + .playerOneID] + .explainedWrong(); + currentState.players[currentState + .playerTwoID] + .guessedWrong(); + } else if (value == 'Ошибка') { + currentState.turnLog[idx]['outcome'] = + 'failed'; + currentState.hat.removeWord( + currentState.turnLog[idx]['word']); + currentState.players[currentState + .playerOneID] + .explainedWrong(); + currentState.players[currentState + .playerTwoID] + .guessedWrong(); + } + }); + }, + items: ['Угадано', 'Не угадано', 'Ошибка'] + .map>(( + String value) { + return DropdownMenuItem( + value: value, + child: Text(value), + ); + }).toList()) + ])))); } else { return Card( child: ListTile( leading: Icon(Icons.error, color: Colors.red), title: Text(currentState.turnLog[idx]['word']), - trailing: DropdownButton( - value: 'Ошибка', - onChanged: (value) { - setState(() { - if (value == 'Угадано') { - currentState.turnLog[idx]['outcome'] = 'guessed'; - currentState.players[currentState.playerOneID] - .explainedRight(); - currentState.players[currentState.playerTwoID] - .guessedRight(); - } else if (value == 'Не угадано') { - currentState.turnLog[idx].remove('outcome'); - } - currentState.hat - .putWord(currentState.turnLog[idx]['word']); - }); - }, - items: ['Угадано', 'Не угадано', 'Ошибка'] - .map>((String value) { - return DropdownMenuItem( - value: value, - child: Text(value), - ); - }).toList()))); + trailing: IntrinsicWidth( + child: Row(children: [ + IconButton( + icon: Icon(Icons.thumb_down), + onPressed: () { + return showDialog( + context: context, + builder: (BuildContext context) => + WordComplainDialog(word: currentState + .turnLog[idx]['word'])); + }), + DropdownButton( + value: 'Ошибка', + onChanged: (value) { + setState(() { + if (value == 'Угадано') { + currentState.turnLog[idx]['outcome'] = + 'guessed'; + currentState.players[currentState + .playerOneID] + .explainedRight(); + currentState.players[currentState + .playerTwoID] + .guessedRight(); + } else if (value == 'Не угадано') { + currentState.turnLog[idx].remove('outcome'); + } + currentState.hat + .putWord( + currentState.turnLog[idx]['word']); + }); + }, + items: ['Угадано', 'Не угадано', 'Ошибка'] + .map>(( + String value) { + return DropdownMenuItem( + value: value, + child: Text(value), + ); + }).toList()) + ])))); } }); } @@ -456,7 +493,10 @@ class WordComplainDialog extends StatefulWidget { } class _WordComplainDialogState extends State { + static GlobalKey replaceWordKey = GlobalKey(); + final ScrollController scrollController = ScrollController(); String word; + String replaceWord; String reason = 'non_noun'; @override @@ -470,11 +510,19 @@ class _WordComplainDialogState extends State { final currentState = Provider .of(context) .gameState; + SchedulerBinding.instance.addPostFrameCallback((_) { + scrollController.animateTo( + scrollController.position.maxScrollExtent, + duration: const Duration(milliseconds: 10), + curve: Curves.easeOut, + ); + }); return AlertDialog( - title: Text('Пожаловаться на слово'), + title: Text('Пожаловаться на слово $word'), content: Container( width: double.maxFinite, child: ListView( + controller: scrollController, shrinkWrap: true, children: [ ListTile( @@ -496,7 +544,35 @@ class _WordComplainDialogState extends State { setState(() { reason = value; }); - })) + })), + ListTile( + title: Text('Прямое заимствование'), + leading: Radio( + value: 'loanword', + groupValue: reason, + onChanged: (value) { + setState(() { + reason = value; + }); + })), + ListTile( + title: Text('Опечатка'), + leading: Radio( + value: 'typo', + groupValue: reason, + onChanged: (value) { + setState(() { + reason = value; + }); + })), + Visibility( + visible: reason == 'typo', + child: TextFormField( + decoration: InputDecoration(labelText: 'Заменить на'), + onSaved: (value) { + replaceWord = value; + }, + key: replaceWordKey)) ], )), actions: [ @@ -509,8 +585,17 @@ class _WordComplainDialogState extends State { FlatButton( child: Text('Готово'), onPressed: () { - currentState.wordComplains - .add({'word': word, 'reason': reason}); + if (reason == 'typo') { + replaceWordKey.currentState.save(); + currentState.wordComplains.add({ + 'word': word, + 'reason': reason, + 'replace_word': replaceWord + }); + } else { + currentState.wordComplains + .add({'word': word, 'reason': reason}); + } Navigator.of(context).pop(); }) ]);