From 40a6e5a10bb67fc05561cc8b37c3e380a8bd64e1 Mon Sep 17 00:00:00 2001 From: ggurdin Date: Mon, 16 Jun 2025 13:52:32 -0400 Subject: [PATCH] chore: started adding widget to show phonetic transcription --- lib/l10n/intl_en.arb | 3 +- .../vocab_analytics_details_view.dart | 10 ++ .../phonetic_transcription_repo.dart | 20 ++-- .../phonetic_transcription_widget.dart | 106 ++++++++++++++++++ .../test_phonetic_transcription_api.dart | 0 5 files changed, 131 insertions(+), 8 deletions(-) create mode 100644 lib/pangea/phonetic_transcription/phonetic_transcription_widget.dart delete mode 100644 lib/pangea/phonetic_transcription/test_phonetic_transcription_api.dart diff --git a/lib/l10n/intl_en.arb b/lib/l10n/intl_en.arb index 50166f59f..a7e110b90 100644 --- a/lib/l10n/intl_en.arb +++ b/lib/l10n/intl_en.arb @@ -5016,5 +5016,6 @@ "directMessage": "Direct Message", "newDirectMessage": "New direct message", "speakingExercisesTooltip": "Speaking practice", - "noChatsFoundHereYet": "No chats found here yet" + "noChatsFoundHereYet": "No chats found here yet", + "phoneticTranscriptionError": "Phonetic transcription failed" } \ No newline at end of file diff --git a/lib/pangea/analytics_details_popup/vocab_analytics_details_view.dart b/lib/pangea/analytics_details_popup/vocab_analytics_details_view.dart index 56fabe42c..4f65589cc 100644 --- a/lib/pangea/analytics_details_popup/vocab_analytics_details_view.dart +++ b/lib/pangea/analytics_details_popup/vocab_analytics_details_view.dart @@ -11,6 +11,7 @@ import 'package:fluffychat/pangea/lemmas/lemma_emoji_row.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_icon.dart'; +import 'package:fluffychat/pangea/phonetic_transcription/phonetic_transcription_widget.dart'; import 'package:fluffychat/pangea/toolbar/widgets/practice_activity/word_text_with_audio_button.dart'; import 'package:fluffychat/pangea/toolbar/widgets/word_zoom/lemma_meaning_widget.dart'; import 'package:fluffychat/widgets/matrix.dart'; @@ -26,6 +27,9 @@ class VocabDetailsView extends StatelessWidget { ConstructUses get _construct => constructId.constructUses; + String? get _userL1 => + MatrixState.pangeaController.languageController.userL1?.langCode; + /// Get the language code for the current lemma String? get _userL2 => MatrixState.pangeaController.languageController.userL2?.langCode; @@ -60,6 +64,12 @@ class VocabDetailsView extends StatelessWidget { ), subtitle: Column( children: [ + if (_userL1 != null && _userL2 != null) + PhoneticTranscription( + text: _construct.lemma, + l1: _userL1!, + l2: _userL2!, + ), Row( mainAxisSize: MainAxisSize.min, spacing: 8.0, diff --git a/lib/pangea/phonetic_transcription/phonetic_transcription_repo.dart b/lib/pangea/phonetic_transcription/phonetic_transcription_repo.dart index 30eac8302..124389eed 100644 --- a/lib/pangea/phonetic_transcription/phonetic_transcription_repo.dart +++ b/lib/pangea/phonetic_transcription/phonetic_transcription_repo.dart @@ -1,6 +1,11 @@ import 'dart:convert'; import 'dart:developer'; +import 'package:flutter/foundation.dart'; + +import 'package:get_storage/get_storage.dart'; +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'; @@ -8,22 +13,22 @@ import 'package:fluffychat/pangea/common/utils/error_handler.dart'; import 'package:fluffychat/pangea/phonetic_transcription/phonetic_transcription_request.dart'; import 'package:fluffychat/pangea/phonetic_transcription/phonetic_transcription_response.dart'; import 'package:fluffychat/widgets/matrix.dart'; -import 'package:flutter/foundation.dart'; -import 'package:get_storage/get_storage.dart'; -import 'package:http/http.dart'; class PhoneticTranscriptionRepo { static final GetStorage _storage = GetStorage('phonetic_transcription_storage'); - static void set(PhoneticTranscriptionRequest request, - PhoneticTranscriptionResponse response) { + static void set( + PhoneticTranscriptionRequest request, + PhoneticTranscriptionResponse response, + ) { response.expireAt ??= DateTime.now().add(const Duration(days: 100)); _storage.write(request.storageKey, response.toJson()); } static Future _fetch( - PhoneticTranscriptionRequest request) async { + PhoneticTranscriptionRequest request, + ) async { final cachedJson = _storage.read(request.storageKey); final cached = cachedJson == null ? null @@ -54,7 +59,8 @@ class PhoneticTranscriptionRepo { } static Future get( - PhoneticTranscriptionRequest request) async { + PhoneticTranscriptionRequest request, + ) async { try { return await _fetch(request); } catch (e) { diff --git a/lib/pangea/phonetic_transcription/phonetic_transcription_widget.dart b/lib/pangea/phonetic_transcription/phonetic_transcription_widget.dart new file mode 100644 index 000000000..b8d7f0d77 --- /dev/null +++ b/lib/pangea/phonetic_transcription/phonetic_transcription_widget.dart @@ -0,0 +1,106 @@ +import 'package:flutter/material.dart'; + +import 'package:fluffychat/l10n/l10n.dart'; +import 'package:fluffychat/pangea/common/utils/error_handler.dart'; +import 'package:fluffychat/pangea/phonetic_transcription/phonetic_transcription_repo.dart'; +import 'package:fluffychat/pangea/phonetic_transcription/phonetic_transcription_request.dart'; +import 'package:fluffychat/pangea/phonetic_transcription/phonetic_transcription_response.dart'; + +class PhoneticTranscription extends StatefulWidget { + final String text; + final String l1; + final String l2; + + const PhoneticTranscription({ + super.key, + required this.text, + required this.l1, + required this.l2, + }); + + @override + State createState() => PhoneticTranscriptionState(); +} + +class PhoneticTranscriptionState extends State { + bool _loading = false; + String? error; + + PhoneticTranscriptionResponse? _response; + + @override + void initState() { + super.initState(); + _fetchPhoneticTranscription(); + } + + @override + void didUpdateWidget(covariant PhoneticTranscription oldWidget) { + super.didUpdateWidget(oldWidget); + if (oldWidget.text != widget.text || + oldWidget.l1 != widget.l1 || + oldWidget.l2 != widget.l2) { + _fetchPhoneticTranscription(); + } + } + + Future _fetchPhoneticTranscription() async { + final PhoneticTranscriptionRequest request = PhoneticTranscriptionRequest( + l1: widget.l1, + l2: widget.l2, + content: widget.text, + ); + + try { + setState(() { + _loading = true; + error = null; + }); + + _response = await PhoneticTranscriptionRepo.get(request); + } catch (e, s) { + ErrorHandler.logError( + e: e, + s: s, + data: request.toJson(), + ); + error = e.toString(); + } finally { + if (mounted) { + setState(() { + _loading = false; + }); + } + } + } + + @override + Widget build(BuildContext context) { + if (error != null) { + return Row( + mainAxisSize: MainAxisSize.min, + children: [ + Icon( + Icons.error_outline, + color: Theme.of(context).colorScheme.error, + size: 16.0, + ), + const SizedBox(width: 8), + Text( + L10n.of(context).phoneticTranscriptionError, + style: Theme.of(context).textTheme.bodyLarge, + ), + ], + ); + } + + if (_loading || _response == null) { + return const Center(child: CircularProgressIndicator.adaptive()); + } + + return Text( + 'Phonetic transcription for "${widget.text}" in ${widget.l2}', + style: Theme.of(context).textTheme.bodyLarge, + ); + } +} diff --git a/lib/pangea/phonetic_transcription/test_phonetic_transcription_api.dart b/lib/pangea/phonetic_transcription/test_phonetic_transcription_api.dart deleted file mode 100644 index e69de29bb..000000000