refactor: remove ability to directly edit lemma defintions and morph assignments (#4347)
This commit is contained in:
parent
97984f85eb
commit
181c4a369b
10 changed files with 48 additions and 818 deletions
|
|
@ -50,8 +50,6 @@ class PApiUrls {
|
|||
|
||||
static String lemmaDictionary =
|
||||
"${PApiUrls._choreoEndpoint}/lemma_definition";
|
||||
static String lemmaDictionaryEdit =
|
||||
"${PApiUrls._choreoEndpoint}/lemma_definition/edit";
|
||||
static String morphDictionary = "${PApiUrls._choreoEndpoint}/morph_meaning";
|
||||
|
||||
// static String activityPlan = "${PApiUrls._choreoEndpoint}/activity_plan";
|
||||
|
|
|
|||
|
|
@ -1,40 +0,0 @@
|
|||
class LemmaEditRequest {
|
||||
String lemma;
|
||||
String partOfSpeech;
|
||||
String lemmaLang;
|
||||
String userL1;
|
||||
|
||||
String? newMeaning;
|
||||
List<String>? newEmojis;
|
||||
|
||||
LemmaEditRequest({
|
||||
required this.lemma,
|
||||
required this.partOfSpeech,
|
||||
required this.lemmaLang,
|
||||
required this.userL1,
|
||||
this.newMeaning,
|
||||
this.newEmojis,
|
||||
});
|
||||
|
||||
Map<String, dynamic> toJson() {
|
||||
return {
|
||||
"lemma": lemma,
|
||||
"part_of_speech": partOfSpeech,
|
||||
"lemma_lang": lemmaLang,
|
||||
"user_l1": userL1,
|
||||
"new_meaning": newMeaning,
|
||||
"new_emojis": newEmojis,
|
||||
};
|
||||
}
|
||||
|
||||
factory LemmaEditRequest.fromJson(Map<String, dynamic> json) {
|
||||
return LemmaEditRequest(
|
||||
lemma: json["lemma"],
|
||||
partOfSpeech: json["part_of_speech"],
|
||||
lemmaLang: json["lemma_lang"],
|
||||
userL1: json["user_l1"],
|
||||
newMeaning: json["new_meaning"],
|
||||
newEmojis: List<String>.from(json["new_emojis"] ?? []),
|
||||
);
|
||||
}
|
||||
}
|
||||
|
|
@ -6,7 +6,6 @@ import 'package:http/http.dart';
|
|||
import 'package:fluffychat/pangea/common/config/environment.dart';
|
||||
import 'package:fluffychat/pangea/common/network/requests.dart';
|
||||
import 'package:fluffychat/pangea/common/network/urls.dart';
|
||||
import 'package:fluffychat/pangea/lemmas/lemma_edit_request.dart';
|
||||
import 'package:fluffychat/pangea/lemmas/lemma_info_request.dart';
|
||||
import 'package:fluffychat/pangea/lemmas/lemma_info_response.dart';
|
||||
import 'package:fluffychat/widgets/matrix.dart';
|
||||
|
|
@ -57,35 +56,4 @@ class LemmaInfoRepo {
|
|||
set(request, response);
|
||||
return response;
|
||||
}
|
||||
|
||||
static Future<void> edit(LemmaEditRequest request) async {
|
||||
final Requests req = Requests(
|
||||
choreoApiKey: Environment.choreoApiKey,
|
||||
accessToken: MatrixState.pangeaController.userController.accessToken,
|
||||
);
|
||||
|
||||
final resp = await req.post(
|
||||
url: PApiUrls.lemmaDictionaryEdit,
|
||||
body: request.toJson(),
|
||||
);
|
||||
|
||||
if (resp.statusCode != 200) {
|
||||
throw Exception(
|
||||
'Failed to edit lemma: ${resp.statusCode} ${resp.body}',
|
||||
);
|
||||
}
|
||||
|
||||
final decodedBody = jsonDecode(utf8.decode(resp.bodyBytes));
|
||||
final response = LemmaInfoResponse.fromJson(decodedBody);
|
||||
|
||||
set(
|
||||
LemmaInfoRequest(
|
||||
lemma: request.lemma,
|
||||
partOfSpeech: request.partOfSpeech,
|
||||
lemmaLang: request.lemmaLang,
|
||||
userL1: request.userL1,
|
||||
),
|
||||
response,
|
||||
);
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,234 +0,0 @@
|
|||
import 'package:fluffychat/pangea/morphs/morph_models.dart';
|
||||
|
||||
final MorphFeaturesAndTags defaultUDMapping = MorphFeaturesAndTags.fromJson({
|
||||
"language_code": "default",
|
||||
"features": [
|
||||
{
|
||||
"feature": "pos",
|
||||
"tag": [
|
||||
"ADJ",
|
||||
"ADP",
|
||||
"ADV",
|
||||
"AFFIX",
|
||||
"AUX",
|
||||
"CCONJ",
|
||||
"DET",
|
||||
"INTJ",
|
||||
"NOUN",
|
||||
"NUM",
|
||||
"PART",
|
||||
"PRON",
|
||||
"PROPN",
|
||||
"PUNCT",
|
||||
"SCONJ",
|
||||
"SPACE",
|
||||
"SYM",
|
||||
"VERB",
|
||||
"X",
|
||||
],
|
||||
},
|
||||
{
|
||||
"feature": "advtype",
|
||||
"tag": ["Adverbial", "Tim"],
|
||||
},
|
||||
{
|
||||
"feature": "aspect",
|
||||
"tag": ["Imp", "Perf", "Prog", "Hab"],
|
||||
},
|
||||
{
|
||||
"feature": "case",
|
||||
"tag": [
|
||||
"Nom",
|
||||
"Acc",
|
||||
"Dat",
|
||||
"Gen",
|
||||
"Voc",
|
||||
"Abl",
|
||||
"Loc",
|
||||
"All",
|
||||
"Ins",
|
||||
"Ess",
|
||||
"Tra",
|
||||
"Com",
|
||||
"Par",
|
||||
"Adv",
|
||||
"Ref",
|
||||
"Rel",
|
||||
"Equ",
|
||||
"Dis",
|
||||
"Abs",
|
||||
"Erg",
|
||||
"Cau",
|
||||
"Ben",
|
||||
"Sub",
|
||||
"Sup",
|
||||
"Tem",
|
||||
"Obl",
|
||||
"Acc,Dat",
|
||||
"Acc,Nom",
|
||||
"Pre",
|
||||
],
|
||||
},
|
||||
{
|
||||
"feature": "conjtype",
|
||||
"tag": ["Coord", "Sub", "Cmp"],
|
||||
},
|
||||
{
|
||||
"feature": "definite",
|
||||
"tag": ["Def", "Ind", "Cons"],
|
||||
},
|
||||
{
|
||||
"feature": "degree",
|
||||
"tag": ["Pos", "Cmp", "Sup", "Abs"],
|
||||
},
|
||||
{
|
||||
"feature": "evident",
|
||||
"tag": ["Fh", "Nfh"],
|
||||
},
|
||||
{
|
||||
"feature": "foreign",
|
||||
"tag": ["Yes"],
|
||||
},
|
||||
{
|
||||
"feature": "gender",
|
||||
"tag": ["Masc", "Fem", "Neut", "Com"],
|
||||
},
|
||||
{
|
||||
"feature": "mood",
|
||||
"tag": [
|
||||
"Ind",
|
||||
"Imp",
|
||||
"Sub",
|
||||
"Cnd",
|
||||
"Opt",
|
||||
"Jus",
|
||||
"Adm",
|
||||
"Des",
|
||||
"Nec",
|
||||
"Pot",
|
||||
"Prp",
|
||||
"Qot",
|
||||
"Int",
|
||||
],
|
||||
},
|
||||
{
|
||||
"feature": "nountype",
|
||||
"tag": ["Prop", "Comm", "Not_proper"],
|
||||
},
|
||||
{
|
||||
"feature": "numform",
|
||||
"tag": ["Digit", "Word", "Roman", "Letter"],
|
||||
},
|
||||
{
|
||||
"feature": "numtype",
|
||||
"tag": ["Card", "Ord", "Mult", "Frac", "Sets", "Range", "Dist"],
|
||||
},
|
||||
{
|
||||
"feature": "number",
|
||||
"tag": ["Sing", "Plur", "Dual", "Tri", "Pauc", "Grpa", "Grpl", "Inv"],
|
||||
},
|
||||
{
|
||||
"feature": "number[psor]",
|
||||
"tag": ["Sing", "Plur", "Dual"],
|
||||
},
|
||||
{
|
||||
"feature": "person",
|
||||
"tag": ["0", "1", "2", "3", "4"],
|
||||
},
|
||||
{
|
||||
"feature": "polarity",
|
||||
"tag": ["Pos", "Neg"],
|
||||
},
|
||||
{
|
||||
"feature": "polite",
|
||||
"tag": ["Infm", "Form", "Elev", "Humb"],
|
||||
},
|
||||
{
|
||||
"feature": "poss",
|
||||
"tag": ["Yes"],
|
||||
},
|
||||
{
|
||||
"feature": "prepcase",
|
||||
"tag": ["Npr"],
|
||||
},
|
||||
{
|
||||
"feature": "prontype",
|
||||
"tag": [
|
||||
"Prs",
|
||||
"Int",
|
||||
"Rel",
|
||||
"Dem",
|
||||
"Tot",
|
||||
"Neg",
|
||||
"Art",
|
||||
"Emp",
|
||||
"Exc",
|
||||
"Ind",
|
||||
"Rcp",
|
||||
"Int,Rel",
|
||||
],
|
||||
},
|
||||
{
|
||||
"feature": "punctside",
|
||||
"tag": ["Ini", "Fin"],
|
||||
},
|
||||
{
|
||||
"feature": "puncttype",
|
||||
"tag": [
|
||||
"Brck",
|
||||
"Dash",
|
||||
"Excl",
|
||||
"Peri",
|
||||
"Qest",
|
||||
"Quot",
|
||||
"Semi",
|
||||
"Colo",
|
||||
"Comm",
|
||||
],
|
||||
},
|
||||
{
|
||||
"feature": "reflex",
|
||||
"tag": ["Yes"],
|
||||
},
|
||||
{
|
||||
"feature": "tense",
|
||||
"tag": ["Pres", "Past", "Fut", "Imp", "Pqp", "Aor", "Eps", "Prosp"],
|
||||
},
|
||||
{
|
||||
"feature": "verbform",
|
||||
"tag": [
|
||||
"Fin",
|
||||
"Inf",
|
||||
"Sup",
|
||||
"Part",
|
||||
"Conv",
|
||||
"Vnoun",
|
||||
"Ger",
|
||||
"Adn",
|
||||
"Lng",
|
||||
],
|
||||
},
|
||||
{
|
||||
"feature": "verbtype",
|
||||
"tag": ["Mod", "Caus"],
|
||||
},
|
||||
{
|
||||
"feature": "voice",
|
||||
"tag": [
|
||||
"Act",
|
||||
"Mid",
|
||||
"Pass",
|
||||
"Antip",
|
||||
"Cau",
|
||||
"Dir",
|
||||
"Inv",
|
||||
"Rcp",
|
||||
"Caus",
|
||||
],
|
||||
},
|
||||
{
|
||||
"feature": "x",
|
||||
"tag": ["X"],
|
||||
}
|
||||
],
|
||||
});
|
||||
|
|
@ -1,258 +0,0 @@
|
|||
import 'package:flutter/material.dart';
|
||||
|
||||
import 'package:fluffychat/l10n/l10n.dart';
|
||||
import 'package:fluffychat/pangea/common/constants/model_keys.dart';
|
||||
import 'package:fluffychat/pangea/common/utils/error_handler.dart';
|
||||
import 'package:fluffychat/pangea/events/event_wrappers/pangea_message_event.dart';
|
||||
import 'package:fluffychat/pangea/events/models/pangea_token_model.dart';
|
||||
import 'package:fluffychat/pangea/events/models/tokens_event_content_model.dart';
|
||||
import 'package:fluffychat/pangea/extensions/pangea_room_extension.dart';
|
||||
import 'package:fluffychat/pangea/morphs/default_morph_mapping.dart';
|
||||
import 'package:fluffychat/pangea/morphs/get_grammar_copy.dart';
|
||||
import 'package:fluffychat/pangea/morphs/morph_features_enum.dart';
|
||||
import 'package:fluffychat/pangea/morphs/morph_repo.dart';
|
||||
import 'package:fluffychat/widgets/future_loading_dialog.dart';
|
||||
|
||||
class EditMorphWidget extends StatefulWidget {
|
||||
final PangeaToken token;
|
||||
final PangeaMessageEvent pangeaMessageEvent;
|
||||
final MorphFeaturesEnum morphFeature;
|
||||
final VoidCallback onClose;
|
||||
|
||||
const EditMorphWidget({
|
||||
required this.token,
|
||||
required this.pangeaMessageEvent,
|
||||
required this.morphFeature,
|
||||
required this.onClose,
|
||||
super.key,
|
||||
});
|
||||
|
||||
@override
|
||||
State<EditMorphWidget> createState() => EditMorphWidgetState();
|
||||
}
|
||||
|
||||
class EditMorphWidgetState extends State<EditMorphWidget> {
|
||||
List<String>? _availableMorphTags;
|
||||
String? _selectedMorphTag;
|
||||
|
||||
@override
|
||||
void initState() {
|
||||
super.initState();
|
||||
_setAvailableMorphs(widget.morphFeature);
|
||||
_selectedMorphTag = _assignedMorphTag;
|
||||
}
|
||||
|
||||
@override
|
||||
void didUpdateWidget(covariant EditMorphWidget oldWidget) {
|
||||
super.didUpdateWidget(oldWidget);
|
||||
if (oldWidget.morphFeature != widget.morphFeature) {
|
||||
_setAvailableMorphs(widget.morphFeature);
|
||||
}
|
||||
}
|
||||
|
||||
String? get _assignedMorphTag => widget.token.morph[widget.morphFeature];
|
||||
|
||||
Future<void> _setAvailableMorphs(MorphFeaturesEnum feature) async {
|
||||
try {
|
||||
setState(() => _availableMorphTags = null);
|
||||
final resp = await MorphsRepo.get();
|
||||
_availableMorphTags = resp.getDisplayTags(
|
||||
feature.name,
|
||||
);
|
||||
} catch (e) {
|
||||
_availableMorphTags = defaultMorphMapping.getDisplayTags(
|
||||
feature.name,
|
||||
);
|
||||
} finally {
|
||||
if (mounted) setState(() {});
|
||||
}
|
||||
}
|
||||
|
||||
void _saveChanges() {
|
||||
if (_selectedMorphTag == null) return;
|
||||
showFutureLoadingDialog(
|
||||
context: context,
|
||||
future: () => _sendEditedMessage(
|
||||
(token) {
|
||||
token.morph[widget.morphFeature] = _selectedMorphTag!;
|
||||
if (widget.morphFeature.name.toLowerCase() == 'pos') {
|
||||
token.pos = _selectedMorphTag!;
|
||||
}
|
||||
return token;
|
||||
},
|
||||
),
|
||||
);
|
||||
}
|
||||
|
||||
Future<void> _sendEditedMessage(
|
||||
PangeaToken Function(PangeaToken token) changeCallback,
|
||||
) async {
|
||||
try {
|
||||
final pm = widget.pangeaMessageEvent;
|
||||
final existingTokens = pm.originalSent!.tokens!
|
||||
.map((token) => PangeaToken.fromJson(token.toJson()))
|
||||
.toList();
|
||||
|
||||
final tokenIndex = existingTokens.indexWhere(
|
||||
(token) => token.text.offset == widget.token.text.offset,
|
||||
);
|
||||
if (tokenIndex == -1) {
|
||||
throw Exception("Token not found in message");
|
||||
}
|
||||
existingTokens[tokenIndex] = changeCallback(existingTokens[tokenIndex]);
|
||||
|
||||
await pm.room.pangeaSendTextEvent(
|
||||
pm.messageDisplayText,
|
||||
editEventId: pm.eventId,
|
||||
originalSent: pm.originalSent?.content,
|
||||
originalWritten: pm.originalWritten?.content,
|
||||
tokensSent: PangeaMessageTokens(
|
||||
tokens: existingTokens,
|
||||
detections: pm.originalSent?.detections,
|
||||
),
|
||||
tokensWritten: pm.originalWritten?.tokens != null
|
||||
? PangeaMessageTokens(
|
||||
tokens: pm.originalWritten!.tokens!,
|
||||
detections: pm.originalWritten?.detections,
|
||||
)
|
||||
: null,
|
||||
choreo: pm.originalSent?.choreo,
|
||||
messageTag: ModelKey.messageTagMorphEdit,
|
||||
);
|
||||
|
||||
widget.onClose();
|
||||
} catch (e) {
|
||||
ErrorHandler.logError(
|
||||
e: e,
|
||||
data: {
|
||||
"selectedMorphTag": _selectedMorphTag,
|
||||
"morphFeature": widget.morphFeature.name,
|
||||
"pangeaMessageEvent": widget.pangeaMessageEvent.event.content,
|
||||
},
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
bool get _canSaveChanges =>
|
||||
_selectedMorphTag != _assignedMorphTag && _selectedMorphTag != null;
|
||||
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
return Stack(
|
||||
children: [
|
||||
Padding(
|
||||
padding: const EdgeInsets.only(
|
||||
top: 16.0,
|
||||
bottom: 48.0,
|
||||
),
|
||||
child: SingleChildScrollView(
|
||||
child: Column(
|
||||
mainAxisSize: MainAxisSize.min,
|
||||
spacing: 8.0,
|
||||
children: [
|
||||
Text(
|
||||
"${L10n.of(context).pangeaBotIsFallible} ${L10n.of(context).chooseCorrectLabel}",
|
||||
textAlign: TextAlign.center,
|
||||
style: const TextStyle(fontStyle: FontStyle.italic),
|
||||
),
|
||||
if (_availableMorphTags == null || _availableMorphTags!.isEmpty)
|
||||
const CircularProgressIndicator()
|
||||
else
|
||||
Wrap(
|
||||
alignment: WrapAlignment.center,
|
||||
children: _availableMorphTags!.map((tag) {
|
||||
return Container(
|
||||
margin: const EdgeInsets.all(2),
|
||||
padding: EdgeInsets.zero,
|
||||
decoration: BoxDecoration(
|
||||
borderRadius: const BorderRadius.all(
|
||||
Radius.circular(10),
|
||||
),
|
||||
border: Border.all(
|
||||
color: _selectedMorphTag == tag
|
||||
? Theme.of(context).colorScheme.primary
|
||||
: Colors.transparent,
|
||||
style: BorderStyle.solid,
|
||||
width: 2.0,
|
||||
),
|
||||
),
|
||||
child: TextButton(
|
||||
style: ButtonStyle(
|
||||
padding: WidgetStateProperty.all(
|
||||
const EdgeInsets.symmetric(
|
||||
horizontal: 7,
|
||||
),
|
||||
),
|
||||
backgroundColor: WidgetStateProperty.all<Color>(
|
||||
_selectedMorphTag == tag
|
||||
? Theme.of(context)
|
||||
.colorScheme
|
||||
.primary
|
||||
.withAlpha(50)
|
||||
: Colors.transparent,
|
||||
),
|
||||
shape: WidgetStateProperty.all(
|
||||
RoundedRectangleBorder(
|
||||
borderRadius: BorderRadius.circular(10),
|
||||
),
|
||||
),
|
||||
),
|
||||
onPressed: () =>
|
||||
setState(() => _selectedMorphTag = tag),
|
||||
child: Text(
|
||||
getGrammarCopy(
|
||||
category: widget.morphFeature.name,
|
||||
lemma: tag,
|
||||
context: context,
|
||||
) ??
|
||||
tag,
|
||||
textAlign: TextAlign.center,
|
||||
),
|
||||
),
|
||||
);
|
||||
}).toList(),
|
||||
),
|
||||
],
|
||||
),
|
||||
),
|
||||
),
|
||||
Positioned(
|
||||
bottom: 0,
|
||||
left: 0,
|
||||
right: 0,
|
||||
child: Container(
|
||||
decoration: BoxDecoration(
|
||||
color: Theme.of(context).colorScheme.surface,
|
||||
),
|
||||
child: Row(
|
||||
mainAxisAlignment: MainAxisAlignment.center,
|
||||
spacing: 10,
|
||||
children: [
|
||||
ElevatedButton(
|
||||
style: ElevatedButton.styleFrom(
|
||||
shape: RoundedRectangleBorder(
|
||||
borderRadius: BorderRadius.circular(10.0),
|
||||
),
|
||||
padding: const EdgeInsets.symmetric(horizontal: 10),
|
||||
),
|
||||
onPressed: widget.onClose,
|
||||
child: Text(L10n.of(context).cancel),
|
||||
),
|
||||
ElevatedButton(
|
||||
style: ElevatedButton.styleFrom(
|
||||
shape: RoundedRectangleBorder(
|
||||
borderRadius: BorderRadius.circular(10.0),
|
||||
),
|
||||
padding: const EdgeInsets.symmetric(horizontal: 10),
|
||||
),
|
||||
onPressed: _canSaveChanges ? _saveChanges : null,
|
||||
child: Text(L10n.of(context).saveChanges),
|
||||
),
|
||||
],
|
||||
),
|
||||
),
|
||||
),
|
||||
],
|
||||
);
|
||||
}
|
||||
}
|
||||
|
|
@ -1,10 +0,0 @@
|
|||
import 'package:flutter/material.dart';
|
||||
|
||||
import 'package:fluffychat/config/app_config.dart';
|
||||
|
||||
String getMorphSvgLink({
|
||||
required String morphFeature,
|
||||
String? morphTag,
|
||||
required BuildContext context,
|
||||
}) =>
|
||||
"${AppConfig.assetsBaseURL}/${morphFeature.toLowerCase()}_${morphTag?.toLowerCase() ?? ''}.svg";
|
||||
|
|
@ -1,8 +1,8 @@
|
|||
import 'package:flutter/material.dart';
|
||||
|
||||
import 'package:fluffychat/config/app_config.dart';
|
||||
import 'package:fluffychat/pangea/common/widgets/customized_svg.dart';
|
||||
import 'package:fluffychat/pangea/morphs/get_grammar_copy.dart';
|
||||
import 'package:fluffychat/pangea/morphs/get_svg_link.dart';
|
||||
import 'package:fluffychat/pangea/morphs/morph_features_enum.dart';
|
||||
import 'package:fluffychat/utils/color_value.dart';
|
||||
|
||||
|
|
@ -20,6 +20,13 @@ class MorphIcon extends StatelessWidget {
|
|||
final bool showTooltip;
|
||||
final Size? size;
|
||||
|
||||
String getMorphSvgLink({
|
||||
required String morphFeature,
|
||||
String? morphTag,
|
||||
required BuildContext context,
|
||||
}) =>
|
||||
"${AppConfig.assetsBaseURL}/${morphFeature.toLowerCase()}_${morphTag?.toLowerCase() ?? ''}.svg";
|
||||
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
// debugPrint("MorphIcon: morphFeature: $morphFeature, morphTag: $morphTag");
|
||||
|
|
|
|||
|
|
@ -1,9 +1,7 @@
|
|||
import 'package:flutter/material.dart';
|
||||
|
||||
import 'package:fluffychat/pangea/common/utils/error_handler.dart';
|
||||
import 'package:fluffychat/pangea/constructs/construct_identifier.dart';
|
||||
import 'package:fluffychat/pangea/learning_settings/constants/language_constants.dart';
|
||||
import 'package:fluffychat/pangea/lemmas/lemma_edit_request.dart';
|
||||
import 'package:fluffychat/pangea/lemmas/lemma_info_repo.dart';
|
||||
import 'package:fluffychat/pangea/lemmas/lemma_info_request.dart';
|
||||
import 'package:fluffychat/pangea/lemmas/lemma_info_response.dart';
|
||||
|
|
@ -29,13 +27,10 @@ class LemmaMeaningBuilder extends StatefulWidget {
|
|||
}
|
||||
|
||||
class LemmaMeaningBuilderState extends State<LemmaMeaningBuilder> {
|
||||
bool editMode = false;
|
||||
LemmaInfoResponse? lemmaInfo;
|
||||
bool isLoading = true;
|
||||
Object? error;
|
||||
|
||||
TextEditingController controller = TextEditingController();
|
||||
|
||||
@override
|
||||
void initState() {
|
||||
super.initState();
|
||||
|
|
@ -51,12 +46,6 @@ class LemmaMeaningBuilderState extends State<LemmaMeaningBuilder> {
|
|||
}
|
||||
}
|
||||
|
||||
@override
|
||||
void dispose() {
|
||||
controller.dispose();
|
||||
super.dispose();
|
||||
}
|
||||
|
||||
LemmaInfoRequest get _request => LemmaInfoRequest(
|
||||
lemma: widget.constructId.lemma,
|
||||
partOfSpeech: widget.constructId.category,
|
||||
|
|
@ -75,7 +64,6 @@ class LemmaMeaningBuilderState extends State<LemmaMeaningBuilder> {
|
|||
try {
|
||||
final resp = await LemmaInfoRepo.get(_request);
|
||||
lemmaInfo = resp;
|
||||
controller.text = resp.meaning;
|
||||
} catch (e) {
|
||||
error = e;
|
||||
} finally {
|
||||
|
|
@ -83,42 +71,6 @@ class LemmaMeaningBuilderState extends State<LemmaMeaningBuilder> {
|
|||
}
|
||||
}
|
||||
|
||||
void toggleEditMode(bool value) => setState(() => editMode = value);
|
||||
|
||||
Future<void> editLemmaMeaning(String userEdit) async {
|
||||
try {
|
||||
await LemmaInfoRepo.edit(
|
||||
LemmaEditRequest(
|
||||
lemma: widget.constructId.lemma,
|
||||
partOfSpeech: widget.constructId.category,
|
||||
lemmaLang: widget.langCode,
|
||||
userL1: MatrixState
|
||||
.pangeaController.languageController.userL1?.langCode ??
|
||||
LanguageKeys.defaultLanguage,
|
||||
newMeaning: userEdit,
|
||||
newEmojis: lemmaInfo?.emoji,
|
||||
),
|
||||
);
|
||||
} catch (e, s) {
|
||||
ErrorHandler.logError(
|
||||
e: e,
|
||||
s: s,
|
||||
data: {
|
||||
'lemma': widget.constructId.lemma,
|
||||
'partOfSpeech': widget.constructId.category,
|
||||
'lemmaLang': widget.langCode,
|
||||
'userL1': MatrixState
|
||||
.pangeaController.languageController.userL1?.langCode ??
|
||||
LanguageKeys.defaultLanguage,
|
||||
'newMeaning': userEdit,
|
||||
},
|
||||
);
|
||||
} finally {
|
||||
toggleEditMode(false);
|
||||
_fetchLemmaMeaning();
|
||||
}
|
||||
}
|
||||
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
return widget.builder(
|
||||
|
|
|
|||
|
|
@ -46,93 +46,22 @@ class LemmaMeaningWidget extends StatelessWidget {
|
|||
);
|
||||
}
|
||||
|
||||
if (controller.editMode) {
|
||||
controller.controller.text = controller.lemmaInfo?.meaning ?? "";
|
||||
return Material(
|
||||
type: MaterialType.transparency,
|
||||
child: Column(
|
||||
mainAxisSize: MainAxisSize.min,
|
||||
children: [
|
||||
Text(
|
||||
"${L10n.of(context).pangeaBotIsFallible} ${L10n.of(context).whatIsMeaning(
|
||||
constructUse.lemma,
|
||||
constructUse.category,
|
||||
)}",
|
||||
textAlign: TextAlign.center,
|
||||
style: const TextStyle(fontStyle: FontStyle.italic),
|
||||
),
|
||||
const SizedBox(height: 10),
|
||||
Padding(
|
||||
padding: const EdgeInsets.symmetric(horizontal: 16.0),
|
||||
child: TextField(
|
||||
minLines: 1,
|
||||
maxLines: 3,
|
||||
controller: controller.controller,
|
||||
decoration: InputDecoration(
|
||||
hintText: controller.lemmaInfo?.meaning,
|
||||
),
|
||||
),
|
||||
),
|
||||
const SizedBox(height: 10),
|
||||
Row(
|
||||
mainAxisAlignment: MainAxisAlignment.center,
|
||||
children: [
|
||||
ElevatedButton(
|
||||
onPressed: () => controller.toggleEditMode(false),
|
||||
style: ElevatedButton.styleFrom(
|
||||
shape: RoundedRectangleBorder(
|
||||
borderRadius: BorderRadius.circular(10.0),
|
||||
),
|
||||
padding: const EdgeInsets.symmetric(horizontal: 10),
|
||||
),
|
||||
child: Text(L10n.of(context).cancel),
|
||||
),
|
||||
const SizedBox(width: 10),
|
||||
ElevatedButton(
|
||||
onPressed: () => controller.controller.text !=
|
||||
controller.lemmaInfo?.meaning &&
|
||||
controller.controller.text.isNotEmpty
|
||||
? controller.editLemmaMeaning(controller.controller.text)
|
||||
: null,
|
||||
style: ElevatedButton.styleFrom(
|
||||
shape: RoundedRectangleBorder(
|
||||
borderRadius: BorderRadius.circular(10.0),
|
||||
),
|
||||
padding: const EdgeInsets.symmetric(horizontal: 10),
|
||||
),
|
||||
child: Text(L10n.of(context).saveChanges),
|
||||
),
|
||||
],
|
||||
),
|
||||
],
|
||||
),
|
||||
);
|
||||
}
|
||||
|
||||
return Row(
|
||||
mainAxisSize: MainAxisSize.min,
|
||||
children: [
|
||||
Flexible(
|
||||
child: Tooltip(
|
||||
triggerMode: TooltipTriggerMode.tap,
|
||||
message: L10n.of(context).doubleClickToEdit,
|
||||
child: GestureDetector(
|
||||
onLongPress: () => controller.toggleEditMode(true),
|
||||
onDoubleTap: () => controller.toggleEditMode(true),
|
||||
child: RichText(
|
||||
textAlign: leading == null ? TextAlign.center : TextAlign.start,
|
||||
text: TextSpan(
|
||||
style: style,
|
||||
children: [
|
||||
if (leading != null) leading!,
|
||||
if (leading != null)
|
||||
const WidgetSpan(child: SizedBox(width: 6.0)),
|
||||
TextSpan(
|
||||
text: controller.lemmaInfo?.meaning,
|
||||
),
|
||||
],
|
||||
child: RichText(
|
||||
textAlign: leading == null ? TextAlign.center : TextAlign.start,
|
||||
text: TextSpan(
|
||||
style: style,
|
||||
children: [
|
||||
if (leading != null) leading!,
|
||||
if (leading != null)
|
||||
const WidgetSpan(child: SizedBox(width: 6.0)),
|
||||
TextSpan(
|
||||
text: controller.lemmaInfo?.meaning,
|
||||
),
|
||||
),
|
||||
],
|
||||
),
|
||||
),
|
||||
),
|
||||
|
|
|
|||
|
|
@ -134,81 +134,6 @@ class WordZoomWidget extends StatelessWidget {
|
|||
langCode: langCode,
|
||||
constructId: construct,
|
||||
builder: (context, controller) {
|
||||
if (controller.editMode) {
|
||||
return Column(
|
||||
children: [
|
||||
Text(
|
||||
"${L10n.of(context).pangeaBotIsFallible} ${L10n.of(context).whatIsMeaning(
|
||||
construct.lemma,
|
||||
construct.category,
|
||||
)}",
|
||||
textAlign: TextAlign.center,
|
||||
style: const TextStyle(
|
||||
fontStyle: FontStyle.italic,
|
||||
),
|
||||
),
|
||||
const SizedBox(height: 10),
|
||||
Padding(
|
||||
padding: const EdgeInsets.symmetric(
|
||||
horizontal: 16.0,
|
||||
),
|
||||
child: TextField(
|
||||
minLines: 1,
|
||||
maxLines: 3,
|
||||
controller: controller.controller,
|
||||
decoration: InputDecoration(
|
||||
hintText: controller.lemmaInfo?.meaning,
|
||||
),
|
||||
),
|
||||
),
|
||||
const SizedBox(height: 10),
|
||||
Row(
|
||||
mainAxisAlignment: MainAxisAlignment.center,
|
||||
children: [
|
||||
ElevatedButton(
|
||||
onPressed: () =>
|
||||
controller.toggleEditMode(false),
|
||||
style: ElevatedButton.styleFrom(
|
||||
shape: RoundedRectangleBorder(
|
||||
borderRadius:
|
||||
BorderRadius.circular(10.0),
|
||||
),
|
||||
padding: const EdgeInsets.symmetric(
|
||||
horizontal: 10,
|
||||
),
|
||||
),
|
||||
child: Text(L10n.of(context).cancel),
|
||||
),
|
||||
const SizedBox(width: 10),
|
||||
ElevatedButton(
|
||||
onPressed: () =>
|
||||
controller.controller.text !=
|
||||
controller.lemmaInfo
|
||||
?.meaning &&
|
||||
controller.controller.text
|
||||
.isNotEmpty
|
||||
? controller.editLemmaMeaning(
|
||||
controller.controller.text,
|
||||
)
|
||||
: null,
|
||||
style: ElevatedButton.styleFrom(
|
||||
shape: RoundedRectangleBorder(
|
||||
borderRadius:
|
||||
BorderRadius.circular(10.0),
|
||||
),
|
||||
padding: const EdgeInsets.symmetric(
|
||||
horizontal: 10,
|
||||
),
|
||||
),
|
||||
child:
|
||||
Text(L10n.of(context).saveChanges),
|
||||
),
|
||||
],
|
||||
),
|
||||
],
|
||||
);
|
||||
}
|
||||
|
||||
return Column(
|
||||
spacing: 12.0,
|
||||
mainAxisSize: MainAxisSize.min,
|
||||
|
|
@ -246,44 +171,37 @@ class WordZoomWidget extends StatelessWidget {
|
|||
controller.lemmaInfo == null)
|
||||
const CircularProgressIndicator.adaptive()
|
||||
else
|
||||
GestureDetector(
|
||||
onLongPress: () =>
|
||||
controller.toggleEditMode(true),
|
||||
onDoubleTap: () =>
|
||||
controller.toggleEditMode(true),
|
||||
child: construct.lemma.toLowerCase() ==
|
||||
token.content.toLowerCase()
|
||||
? Text(
|
||||
controller.lemmaInfo!.meaning,
|
||||
style:
|
||||
const TextStyle(fontSize: 14.0),
|
||||
textAlign: TextAlign.center,
|
||||
)
|
||||
: RichText(
|
||||
text: TextSpan(
|
||||
style:
|
||||
DefaultTextStyle.of(context)
|
||||
.style
|
||||
.copyWith(
|
||||
fontSize: 14.0,
|
||||
),
|
||||
children: [
|
||||
TextSpan(text: construct.lemma),
|
||||
const WidgetSpan(
|
||||
child: SizedBox(width: 8.0),
|
||||
construct.lemma.toLowerCase() ==
|
||||
token.content.toLowerCase()
|
||||
? Text(
|
||||
controller.lemmaInfo!.meaning,
|
||||
style:
|
||||
const TextStyle(fontSize: 14.0),
|
||||
textAlign: TextAlign.center,
|
||||
)
|
||||
: RichText(
|
||||
text: TextSpan(
|
||||
style: DefaultTextStyle.of(context)
|
||||
.style
|
||||
.copyWith(
|
||||
fontSize: 14.0,
|
||||
),
|
||||
const TextSpan(text: ":"),
|
||||
const WidgetSpan(
|
||||
child: SizedBox(width: 8.0),
|
||||
),
|
||||
TextSpan(
|
||||
text: controller
|
||||
.lemmaInfo!.meaning,
|
||||
),
|
||||
],
|
||||
),
|
||||
children: [
|
||||
TextSpan(text: construct.lemma),
|
||||
const WidgetSpan(
|
||||
child: SizedBox(width: 8.0),
|
||||
),
|
||||
const TextSpan(text: ":"),
|
||||
const WidgetSpan(
|
||||
child: SizedBox(width: 8.0),
|
||||
),
|
||||
TextSpan(
|
||||
text: controller
|
||||
.lemmaInfo!.meaning,
|
||||
),
|
||||
],
|
||||
),
|
||||
),
|
||||
),
|
||||
],
|
||||
);
|
||||
},
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue