chore: replace future builder in morph edit widget to prevent infinite rebuild loop (#2273)

This commit is contained in:
ggurdin 2025-03-31 11:10:51 -04:00 committed by GitHub
parent 07128e3c0a
commit ac7d5f3938
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
2 changed files with 87 additions and 78 deletions

View file

@ -67,9 +67,7 @@ class MorphMeaningWidgetState extends State<MorphMeaningWidget> {
} catch (e) {
_error = e.toString();
} finally {
setState(() {
_isLoading = false;
});
if (mounted) setState(() => _isLoading = false);
}
}

View file

@ -53,27 +53,33 @@ class MorphFocusWidgetState extends State<MorphFocusWidget> {
/// the morphological tag that the user has selected in edit mode
String selectedMorphTag = "";
List<String> morphFeatures = [];
final ScrollController _scrollController = ScrollController();
void resetMorphTag() => setState(
() => selectedMorphTag =
widget.token.getMorphTag(widget.morphFeature) ?? "X",
);
@override
void didUpdateWidget(MorphFocusWidget oldWidget) {
if (widget.token != oldWidget.token ||
widget.morphFeature != oldWidget.morphFeature) {
resetMorphTag();
setState(() => editMode = false);
}
super.didUpdateWidget(oldWidget);
void resetMorphTag() {
setState(
() => selectedMorphTag =
widget.token.getMorphTag(widget.morphFeature) ?? "X",
);
}
@override
void initState() {
super.initState();
resetMorphTag();
_setAvailableMorphs();
}
@override
void didUpdateWidget(MorphFocusWidget oldWidget) {
if (widget.token != oldWidget.token ||
widget.morphFeature != oldWidget.morphFeature) {
resetMorphTag();
_setAvailableMorphs();
setState(() => editMode = false);
}
super.didUpdateWidget(oldWidget);
}
@override
@ -90,6 +96,21 @@ class MorphFocusWidgetState extends State<MorphFocusWidget> {
PangeaMessageEvent get pm => widget.pangeaMessageEvent;
Future<void> _setAvailableMorphs() async {
try {
final resp = await MorphsRepo.get();
morphFeatures = resp.getDisplayTags(
widget.morphFeature.name,
);
} catch (e) {
morphFeatures = defaultMorphMapping.getDisplayTags(
widget.morphFeature.name,
);
} finally {
if (mounted) setState(() {});
}
}
/// confirm the changes made by the user
/// this will send a new message to the server
/// with the new morphological tag
@ -230,73 +251,63 @@ class MorphFocusWidgetState extends State<MorphFocusWidget> {
textAlign: TextAlign.center,
style: const TextStyle(fontStyle: FontStyle.italic),
),
FutureBuilder(
future: MorphsRepo.get(),
builder: (context, snapshot) {
final allMorphTagsForEdit = snapshot.data
?.getDisplayTags(widget.morphFeature.name) ??
defaultMorphMapping.getDisplayTags(widget.morphFeature.name);
if (snapshot.connectionState == ConnectionState.waiting) {
return const CircularProgressIndicator();
}
return Wrap(
children: allMorphTagsForEdit.map((tag) {
return Container(
margin: const EdgeInsets.all(2),
padding: EdgeInsets.zero,
decoration: BoxDecoration(
borderRadius: const BorderRadius.all(
Radius.circular(10),
if (morphFeatures.isEmpty)
const CircularProgressIndicator()
else
Wrap(
children: morphFeatures.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,
),
),
border: Border.all(
color: selectedMorphTag == tag
? Theme.of(context).colorScheme.primary
backgroundColor: WidgetStateProperty.all<Color>(
selectedMorphTag == tag
? Theme.of(context)
.colorScheme
.primary
.withAlpha(50)
: Colors.transparent,
style: BorderStyle.solid,
width: 2.0,
),
shape: WidgetStateProperty.all(
RoundedRectangleBorder(
borderRadius: BorderRadius.circular(10),
),
),
),
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,
),
onPressed: () {
setState(() => selectedMorphTag = tag);
},
child: Text(
getGrammarCopy(
category: widget.morphFeature.name,
lemma: tag,
context: context,
) ??
tag,
textAlign: TextAlign.center,
),
);
}).toList(),
);
},
),
),
);
}).toList(),
),
Row(
mainAxisAlignment: MainAxisAlignment.center,
spacing: 10,