fix: fetch morphs once and sort after fetching instead of using future builder in grammar analytics view (#1890)

This commit is contained in:
ggurdin 2025-02-21 17:06:15 -05:00 committed by GitHub
parent ba4800adcc
commit 5367dbfb59
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
2 changed files with 63 additions and 45 deletions

View file

@ -10,7 +10,12 @@ import 'package:fluffychat/pangea/analytics_details_popup/vocab_details_view.dar
import 'package:fluffychat/pangea/analytics_misc/construct_identifier.dart';
import 'package:fluffychat/pangea/analytics_misc/construct_type_enum.dart';
import 'package:fluffychat/pangea/analytics_summary/progress_indicators_enum.dart';
import 'package:fluffychat/pangea/common/utils/error_handler.dart';
import 'package:fluffychat/pangea/common/widgets/full_width_dialog.dart';
import 'package:fluffychat/pangea/morphs/default_morph_mapping.dart';
import 'package:fluffychat/pangea/morphs/morph_models.dart';
import 'package:fluffychat/pangea/morphs/morph_repo.dart';
import 'package:fluffychat/widgets/matrix.dart';
class AnalyticsPopupWrapper extends StatefulWidget {
const AnalyticsPopupWrapper({
@ -30,14 +35,39 @@ class AnalyticsPopupWrapperState extends State<AnalyticsPopupWrapper> {
ConstructIdentifier? localConstructZoom;
ConstructTypeEnum localView = ConstructTypeEnum.vocab;
MorphFeaturesAndTags morphs = defaultMorphMapping;
List<MorphFeature> features = defaultMorphMapping.displayFeatures;
@override
void initState() {
super.initState();
localView = widget.view;
setConstructZoom(widget.constructZoom);
_setConstructZoom(widget.constructZoom);
_setMorphs();
}
void setConstructZoom(ConstructIdentifier? id) {
Future<void> _setMorphs() async {
try {
final resp = await MorphsRepo.get();
morphs = resp;
features = resp.displayFeatures;
} catch (e, s) {
ErrorHandler.logError(
e: e,
s: s,
data: {"l2": MatrixState.pangeaController.languageController.userL2},
);
} finally {
features.sort(
(a, b) => morphFeatureSortOrder
.indexOf(a.feature)
.compareTo(morphFeatureSortOrder.indexOf(b.feature)),
);
if (mounted) setState(() {});
}
}
void _setConstructZoom(ConstructIdentifier? id) {
if (id != null && id.type != localView) {
localView = id.type;
}
@ -61,7 +91,7 @@ class AnalyticsPopupWrapperState extends State<AnalyticsPopupWrapper> {
: const Icon(Icons.arrow_back),
onPressed: localConstructZoom == null
? () => Navigator.of(context).pop()
: () => setConstructZoom(null),
: () => _setConstructZoom(null),
),
actions: [
TextButton.icon(
@ -102,10 +132,13 @@ class AnalyticsPopupWrapperState extends State<AnalyticsPopupWrapper> {
),
body: localView == ConstructTypeEnum.morph
? localConstructZoom == null
? MorphAnalyticsView(onConstructZoom: setConstructZoom)
? MorphAnalyticsView(
onConstructZoom: _setConstructZoom,
controller: this,
)
: MorphDetailsView(constructId: localConstructZoom!)
: localConstructZoom == null
? VocabAnalyticsView(onConstructZoom: setConstructZoom)
? VocabAnalyticsView(onConstructZoom: _setConstructZoom)
: VocabDetailsView(constructId: localConstructZoom!),
),
maxWidth: 600,

View file

@ -4,64 +4,49 @@ import 'package:collection/collection.dart';
import 'package:flutter_gen/gen_l10n/l10n.dart';
import 'package:fluffychat/config/app_config.dart';
import 'package:fluffychat/pangea/analytics_details_popup/analytics_details_popup.dart';
import 'package:fluffychat/pangea/analytics_misc/construct_identifier.dart';
import 'package:fluffychat/pangea/analytics_misc/construct_level_enum.dart';
import 'package:fluffychat/pangea/analytics_misc/construct_type_enum.dart';
import 'package:fluffychat/pangea/analytics_misc/construct_use_model.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_icon.dart';
import 'package:fluffychat/pangea/user/client_extension.dart';
import 'package:fluffychat/widgets/matrix.dart';
import '../morphs/morph_repo.dart';
class MorphAnalyticsView extends StatelessWidget {
final void Function(ConstructIdentifier) onConstructZoom;
final AnalyticsPopupWrapperState controller;
const MorphAnalyticsView({
required this.onConstructZoom,
required this.controller,
super.key,
});
@override
Widget build(BuildContext context) => Padding(
padding: const EdgeInsets.symmetric(vertical: 20),
child: FutureBuilder(
future: MorphsRepo.get(),
builder: (context, snapshot) {
final morphs = snapshot.data ?? defaultMorphMapping;
final features = morphs.displayFeatures.sorted(
(a, b) => morphFeatureSortOrder
.indexOf(a.feature)
.compareTo(morphFeatureSortOrder.indexOf(b.feature)),
);
return snapshot.connectionState == ConnectionState.done
? ListView.builder(
key: const PageStorageKey<String>('morph-analytics'),
itemCount: features.length,
itemBuilder: (context, index) =>
features[index].displayTags.isNotEmpty
? MorphFeatureBox(
morphFeature: features[index].feature,
allTags: snapshot.data
?.getDisplayTags(
features[index].feature,
)
.map((tag) => tag.toLowerCase())
.toSet() ??
{},
onConstructZoom: onConstructZoom,
)
: const SizedBox.shrink(),
)
: const Center(
child: CircularProgressIndicator(),
);
},
),
);
Widget build(BuildContext context) {
return Padding(
padding: const EdgeInsets.symmetric(vertical: 20),
child: ListView.builder(
key: const PageStorageKey<String>('morph-analytics'),
itemCount: controller.features.length,
itemBuilder: (context, index) {
final feature = controller.features[index];
return feature.displayTags.isNotEmpty
? MorphFeatureBox(
morphFeature: feature.feature,
allTags: controller.morphs
.getDisplayTags(feature.feature)
.map((tag) => tag.toLowerCase())
.toSet(),
onConstructZoom: onConstructZoom,
)
: const SizedBox.shrink();
},
),
);
}
}
class MorphFeatureBox extends StatelessWidget {