From f569407e080e7a84a389e9ffb8faf693c79bc125 Mon Sep 17 00:00:00 2001 From: HuiChan Seo <78739194+seochan99@users.noreply.github.com> Date: Sat, 4 May 2024 23:33:28 +0900 Subject: [PATCH 1/8] =?UTF-8?q?=E2=9C=A8Feat:=20Gemini=20=ED=8C=A8?= =?UTF-8?q?=ED=82=A4=EC=A7=80=20=EC=84=A4=EC=B9=98?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- pubspec.yaml | 1 + 1 file changed, 1 insertion(+) diff --git a/pubspec.yaml b/pubspec.yaml index 80c0e45..c8eaa6a 100644 --- a/pubspec.yaml +++ b/pubspec.yaml @@ -40,6 +40,7 @@ dependencies: youtube_player_flutter: ^8.1.2 flutter_spinkit: ^5.2.1 vibration: ^1.8.4 + flutter_gemini: ^2.0.3 dev_dependencies: flutter_test: From 799e18889c68fca4e61026ceccaa6e22a6b3ac8b Mon Sep 17 00:00:00 2001 From: HuiChan Seo <78739194+seochan99@users.noreply.github.com> Date: Sat, 4 May 2024 23:35:41 +0900 Subject: [PATCH 2/8] =?UTF-8?q?=E2=9C=A8Feat:=20Gemini=20KEy=20=EC=A0=81?= =?UTF-8?q?=EC=9A=A9?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- lib/main.dart | 3 +++ 1 file changed, 3 insertions(+) diff --git a/lib/main.dart b/lib/main.dart index 3a119e5..d294e36 100644 --- a/lib/main.dart +++ b/lib/main.dart @@ -3,6 +3,7 @@ import 'package:easy_localization/easy_localization.dart'; import 'package:firebase_core/firebase_core.dart'; import 'package:flutter/material.dart'; import 'package:flutter_dotenv/flutter_dotenv.dart'; +import 'package:flutter_gemini/flutter_gemini.dart'; import 'package:intl/date_symbol_data_local.dart'; import 'package:earlips/main_app.dart'; import 'package:flutter/services.dart'; @@ -22,6 +23,8 @@ void main() async { options: DefaultFirebaseOptions.currentPlatform, ); + // gemini + Gemini.init(apiKey: dotenv.env['GEMINI_API_KEY']!); runApp(EasyLocalization( // 지원 언어 리스트 saveLocale: true, From caf91d1f6d309cccd9d7b35c796cbfbc132dfce8 Mon Sep 17 00:00:00 2001 From: HuiChan Seo <78739194+seochan99@users.noreply.github.com> Date: Sat, 4 May 2024 23:36:53 +0900 Subject: [PATCH 3/8] =?UTF-8?q?=E2=9C=A8Feat:=20Word=20ViewModel=20Descrip?= =?UTF-8?q?tion=20=EA=B5=AC=EC=B6=95?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- lib/viewModels/word/word_viewmodel.dart | 26 +++++++++++++++++++++++++ 1 file changed, 26 insertions(+) diff --git a/lib/viewModels/word/word_viewmodel.dart b/lib/viewModels/word/word_viewmodel.dart index b862113..c2f4ef2 100644 --- a/lib/viewModels/word/word_viewmodel.dart +++ b/lib/viewModels/word/word_viewmodel.dart @@ -3,6 +3,7 @@ import 'package:earlips/models/user_word_model.dart'; import 'package:earlips/models/word_card_model.dart'; import 'package:earlips/models/word_data_model.dart'; import 'package:firebase_auth/firebase_auth.dart'; +import 'package:flutter_gemini/flutter_gemini.dart'; import 'package:get/get.dart'; import 'package:intl/intl.dart'; @@ -14,7 +15,9 @@ class WordViewModel extends GetxController { RxList wordList = RxList([]); RxInt currentIndex = 0.obs; // loading + RxString description = ''.obs; RxBool isLoading = true.obs; + RxBool isLoadingGemini = true.obs; // 로딩 상태를 관리하기 위한 변수 WordViewModel({required this.type}); @@ -29,6 +32,26 @@ class WordViewModel extends GetxController { currentIndex.value = index; } + // Gemini API 호출을 위한 메서드 정의 + Future generateDescription(String speaker) async { + isLoadingGemini.value = true; + final gemini = Gemini.instance; + + // Gemini API를 호출하여 결과를 처리합니다. + await gemini + .text( + "If you pronounce it, it's $speaker, tell me in detail in English, not in Korean, so that the deaf can visually see and pronounce it ** Don't use boulders like this and tell me within 150 characters! Never Use Bold and **, Never Over 150 characters if u over this limit, it will be cut off!, never Use Bold and **, never over 150 characters if u over this limit, it will be cut off!") + .then((value) { + // 성공적으로 결과를 받았을 때 출력 및 상태 업데이트 + description.value = value?.output ?? ""; + print(value?.output); // output이 정확한 필드인지 확인하세요. API 응답에 따라 다를 수 있습니다. + }).catchError((error) { + // 에러 처리 + print('Error occurred: $error'); + }); + isLoadingGemini.value = false; + } + // 단어 데이터 가져오기 Future fetchWords(int type) async { isLoading.value = true; @@ -50,6 +73,7 @@ class WordViewModel extends GetxController { .doc(uid) .collection('words') .get(); + // 사용자의 단어 데이터를 UserWord로 변환 final userWords = userWordsQuery.docs .map((doc) => UserWord.fromDocument(doc.data())) .toList(); @@ -69,6 +93,8 @@ class WordViewModel extends GetxController { } } + // 단어 AI 생성 Description 가져오기, wordList[0] + // 단어 완료 처리 Future markWordAsDone(WordCard word) async { final uid = _auth.currentUser?.uid; From b6e437ac6ac6d1b8cea414c650e5e08c7d169ac1 Mon Sep 17 00:00:00 2001 From: HuiChan Seo <78739194+seochan99@users.noreply.github.com> Date: Sat, 4 May 2024 23:37:37 +0900 Subject: [PATCH 4/8] =?UTF-8?q?=E2=9C=A8Feat:=20Phoneme=20=EB=94=94?= =?UTF-8?q?=ED=85=8C=EC=9D=BC=20=ED=99=94=EB=A9=B4,=20=EC=A0=9C=EB=AF=B8?= =?UTF-8?q?=EB=82=98=EC=9D=B4=20=EC=97=B0=EB=8F=99?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- lib/views/phoneme/phoneme_detail_screen.dart | 36 +++++++++++++++----- 1 file changed, 27 insertions(+), 9 deletions(-) diff --git a/lib/views/phoneme/phoneme_detail_screen.dart b/lib/views/phoneme/phoneme_detail_screen.dart index f9c8708..6f15caa 100644 --- a/lib/views/phoneme/phoneme_detail_screen.dart +++ b/lib/views/phoneme/phoneme_detail_screen.dart @@ -1,5 +1,6 @@ import 'package:earlips/models/phoneme_model.dart'; import 'package:earlips/utilities/style/color_system.dart'; +import 'package:earlips/viewModels/word/word_viewmodel.dart'; import 'package:earlips/views/phoneme/widget/phoneme_list_widget.dart'; import 'package:earlips/views/word/widget/blue_back_appbar.dart'; import 'package:flutter/material.dart'; @@ -9,10 +10,14 @@ import 'package:get/get.dart'; class PhonemeDetailScreen extends StatelessWidget { final Phoneme phoneme; - const PhonemeDetailScreen({super.key, required this.phoneme}); + PhonemeDetailScreen({super.key, required this.phoneme}); + + final wordViewModel = Get.find(); @override Widget build(BuildContext context) { + wordViewModel.generateDescription(phoneme.symbol); + return Scaffold( appBar: PreferredSize( preferredSize: const Size.fromHeight(kToolbarHeight), @@ -59,19 +64,32 @@ class PhonemeDetailScreen extends StatelessWidget { // --------------------------- 발음 세부 내용 기입 // image - const Padding( - padding: EdgeInsets.all(20), + Padding( + padding: const EdgeInsets.all(20), child: Column( children: [ - // SvgPicture.asset( - // 'assets/images/phoneme/vowels_1.svg', - // width: 90, - // height: 90, - // ), + Obx(() { + // isLoading이 true이면 로딩 인디케이터를 보여줌 + if (wordViewModel.isLoadingGemini.value) { + return const Center( + child: CircularProgressIndicator(), // 로딩 인디케이터 + ); + } else { + // isLoading이 false이면 설명 텍스트를 보여줌 + return Text( + wordViewModel.description.value, + style: const TextStyle( + fontSize: 16, + fontWeight: FontWeight.w600, + color: Colors.black, // ColorSystem.black으로 가정 + ), + ); + } + }), ], ), ), - Text(phoneme.description), + const Spacer(), ], ), From 4c235a7ad5871e159ec97cd87c6862542d941018 Mon Sep 17 00:00:00 2001 From: HuiChan Seo <78739194+seochan99@users.noreply.github.com> Date: Sat, 4 May 2024 23:38:15 +0900 Subject: [PATCH 5/8] =?UTF-8?q?=E2=9C=A8Feat:=20Learning=20sesson?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- lib/views/script/learning_session_screen.dart | 38 ++++++++++--------- 1 file changed, 21 insertions(+), 17 deletions(-) diff --git a/lib/views/script/learning_session_screen.dart b/lib/views/script/learning_session_screen.dart index 2bb9a33..fc571aa 100644 --- a/lib/views/script/learning_session_screen.dart +++ b/lib/views/script/learning_session_screen.dart @@ -10,7 +10,7 @@ import 'package:intl/intl.dart'; // DateFormat을 사용하기 위해 추가 class LearningSessionScreen extends StatefulWidget { final bool isStudyMode; // 스터디 모드 여부를 결정하는 변수 - const LearningSessionScreen({super.key,this.isStudyMode = false}); + const LearningSessionScreen({super.key, this.isStudyMode = false}); @override State createState() => _LearningSessionScreenState(); @@ -37,7 +37,8 @@ class _LearningSessionScreenState extends State { @override Widget build(BuildContext context) { - var title = widget.isStudyMode ? 'study_main_title_4'.tr : 'home_script_title'.tr; + var title = + widget.isStudyMode ? 'study_main_title_4'.tr : 'home_script_title'.tr; return Scaffold( appBar: PreferredSize( preferredSize: const Size.fromHeight(kToolbarHeight), @@ -93,18 +94,20 @@ class _LearningSessionScreenState extends State { } }), //여기에 조건문 넣고싶어 - floatingActionButton: !widget.isStudyMode ? FloatingActionButton( - onPressed: () => Get.to(() => const CreateScriptPage()), - child: const Icon(Icons.add), - ) : null, // widget.isStudyMode가 true일 때는 null을 반환 + floatingActionButton: !widget.isStudyMode + ? FloatingActionButton( + onPressed: () => Get.to(() => const CreateScriptPage()), + child: const Icon(Icons.add), + ) + : null, // widget.isStudyMode가 true일 때는 null을 반환 ); } Widget _buildParagraphContainer(Paragraph paragraph) { return InkWell( onTap: () { - Get.to(() => CreateScriptPage( - title: paragraph.title, text: paragraph.text)); + Get.to(() => + CreateScriptPage(title: paragraph.title, text: paragraph.text)); }, child: Container( width: Get.width * 0.9, @@ -128,16 +131,18 @@ class _LearningSessionScreenState extends State { children: [ Container( alignment: Alignment.centerLeft, - margin: EdgeInsets.only(left: 16.0,top: 16.0,bottom: 8.0), + margin: + const EdgeInsets.only(left: 16.0, top: 16.0, bottom: 8.0), child: Text( - paragraph.dateFormat == "Example" ? "script example" : "${DateFormat('yyyy년 MM월 dd일 ').format(DateFormat('yyyy/MM/dd').parse(paragraph.dateFormat!))}진행한 학습", - style: TextStyle( + paragraph.dateFormat == "Example" + ? "script example" + : "${DateFormat('yyyy년 MM월 dd일 ').format(DateFormat('yyyy/MM/dd').parse(paragraph.dateFormat!))}진행한 학습", + style: const TextStyle( fontSize: 11, color: Color(0xFF6E6A7C), ), ), ), - Container( margin: const EdgeInsets.only(right: 12.0, top: 12.0), child: SvgPicture.asset("assets/icons/book.svg", @@ -147,7 +152,8 @@ class _LearningSessionScreenState extends State { ), Container( alignment: Alignment.centerLeft, - margin: EdgeInsets.only(left: 16.0,bottom: 8.0, right: 16.0), + margin: + const EdgeInsets.only(left: 16.0, bottom: 8.0, right: 16.0), child: Text( overflow: TextOverflow.ellipsis, paragraph.title, @@ -157,7 +163,6 @@ class _LearningSessionScreenState extends State { ), ), ), - Container( margin: const EdgeInsets.only(left: 16, right: 12), child: Row( @@ -166,8 +171,7 @@ class _LearningSessionScreenState extends State { Row( children: [ SvgPicture.asset("assets/icons/TimeCircle.svg", - width: 14, - color: const Color(0xFFC4C4D9)), + width: 14, color: const Color(0xFFC4C4D9)), const SizedBox(width: 4), Text( paragraph.timeFormat!, @@ -199,7 +203,7 @@ class _LearningSessionScreenState extends State { alignment: Alignment.center, height: 17, child: Text( - '대본의 총 글자수 : ${text}', + '대본의 총 글자수 : $text', style: const TextStyle( color: Color(0xFF34AF20), fontSize: 9, From d7950fed9ea86d0e80ee55a87bbf38a7d9df52ec Mon Sep 17 00:00:00 2001 From: HuiChan Seo <78739194+seochan99@users.noreply.github.com> Date: Sat, 4 May 2024 23:38:26 +0900 Subject: [PATCH 6/8] =?UTF-8?q?=E2=9C=A8Feat:=20=EB=8B=A8=EC=96=B4=20?= =?UTF-8?q?=ED=99=94=EB=A9=B4?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- lib/views/word/word_screen.dart | 269 ++++++++++++++++---------------- 1 file changed, 132 insertions(+), 137 deletions(-) diff --git a/lib/views/word/word_screen.dart b/lib/views/word/word_screen.dart index 51b37dc..7e8dac0 100644 --- a/lib/views/word/word_screen.dart +++ b/lib/views/word/word_screen.dart @@ -1,8 +1,7 @@ -import 'package:earlips/models/phoneme_model.dart'; import 'package:earlips/utilities/style/color_system.dart'; import 'package:earlips/viewModels/word/word_viewmodel.dart'; -import 'package:earlips/views/phoneme/phoneme_detail_Screen.dart'; import 'package:earlips/views/word/widget/blue_back_appbar.dart'; +import 'package:earlips/views/word/widget/phonetic_buttons_widget.dart'; import 'package:earlips/views/word/widget/word_list_widget.dart'; import 'package:earlips/views/word/widget/word_sentence_widget.dart'; import 'package:earlips/views/word/widget/word_vibration_widget.dart'; @@ -11,69 +10,6 @@ import 'package:flutter/material.dart'; import 'package:get/get.dart'; import 'package:earlips/views/script/learning_session_screen.dart'; -class PhoneticButtons extends StatelessWidget { - final String phoneticString; - - const PhoneticButtons({super.key, required this.phoneticString}); - - @override - Widget build(BuildContext context) { - // Splitting the phonetic string into components - List phonemes1 = phoneticString.replaceAll('/', '').split('.'); - List phonemes2 = 'b.juː.t.ɪ.f.ə.l'.split('.'); - - return Column( - children: [ - const Text("Split Phonemes", - style: TextStyle( - fontSize: 16, - color: ColorSystem.black, - fontWeight: FontWeight.w500)), - const SizedBox(height: 10), - Wrap( - spacing: 8.0, // Space between buttons - children: phonemes1 - .map((phoneme) => ElevatedButton( - onPressed: () { - // Navigate to a detail page for the phoneme - Get.to(() => PhonemeDetailScreen( - phoneme: Phoneme( - symbol: phoneme, description: '', imageSrc: ''))); - }, - child: Text(phoneme, - style: const TextStyle( - fontSize: 16, color: ColorSystem.black)), - )) - .toList(), - ), - const SizedBox(height: 20), - const Text("More Detail", - style: TextStyle( - fontSize: 16, - color: ColorSystem.black, - fontWeight: FontWeight.w500)), - const SizedBox(height: 10), - Wrap( - spacing: 8.0, // Space between buttons - children: phonemes2 - .map((phoneme) => ElevatedButton( - onPressed: () { - // Navigate to a detail page for the phoneme - Get.to(() => PhonemeDetailScreen( - phoneme: Phoneme( - symbol: phoneme, description: '', imageSrc: ''))); - }, - child: Text(phoneme, - style: const TextStyle( - fontSize: 16, color: ColorSystem.black)), - )) - .toList(), - ), - ], - ); - } -} - class WordScreen extends StatelessWidget { final String title; final int type; @@ -93,87 +29,146 @@ class WordScreen extends StatelessWidget { preferredSize: const Size.fromHeight(kToolbarHeight), child: BlueBackAppbar(title: title), ), - body: Center( - child: Column( - children: [ - Container( - decoration: const BoxDecoration( - color: ColorSystem.main2, - borderRadius: BorderRadius.only( - bottomLeft: Radius.circular(24), - bottomRight: Radius.circular(24), - ), - ), - child: Column( - children: [ - const SizedBox(height: 20), - GetBuilder( - // Add GetBuilder here - builder: (controller) => WordList( - // viewmodel - wordDataList: controller.wordList, - type: type, - pageController: pageController, + body: SingleChildScrollView( + child: IntrinsicHeight( + child: Center( + child: Column( + children: [ + Container( + decoration: const BoxDecoration( + color: ColorSystem.main2, + borderRadius: BorderRadius.only( + bottomLeft: Radius.circular(24), + bottomRight: Radius.circular(24), ), ), - SizedBox( - height: 70, - child: Column( - children: [ - const SizedBox( - height: 15, + child: Column( + children: [ + const SizedBox(height: 20), + GetBuilder( + // Add GetBuilder here + builder: (controller) => WordList( + // viewmodel + wordDataList: controller.wordList, + type: type, + pageController: pageController, ), - Text( - type == 2 - ? "word_type_2_height".tr - : "word_type_12_height".tr, - style: const TextStyle( - fontSize: 16, - fontWeight: FontWeight.w600, - color: ColorSystem.white, - ), + ), + SizedBox( + height: 70, + child: Column( + children: [ + const SizedBox( + height: 15, + ), + Text( + type == 2 + ? "word_type_2_height".tr + : "word_type_12_height".tr, + style: const TextStyle( + fontSize: 16, + fontWeight: FontWeight.w600, + color: ColorSystem.white, + ), + ), + ], ), - ], - ), + ), + ], ), - ], - ), - ), - const Spacer(), - // wordViewModel final String video로 영상 유튜브 링크를 바로 볼 수 있게 하기 - GetBuilder( - builder: (controller) { - if (controller.type <= 2) { + ), + const Spacer(), + // wordViewModel final String video로 영상 유튜브 링크를 바로 볼 수 있게 하기 + GetBuilder( + builder: (controller) { + if (controller.wordList.isEmpty) { + return const Center(child: Text("No data available")); + } - return Padding( - padding: const EdgeInsets.all(20.0), - child: Column( - children: [ - // 유투브 영상 나옴 - const YoutubeWordPlayer(), - if(controller.type == 0)SizedBox( - height: 100, - ), - WordSentenceWidget( - pageController: pageController, - wordDataList: controller.wordList, - type: controller.type, - ), + /// -------------------- --------- -------------------- + /// -------------------- 단어 교정 -------------------- + /// -------------------- --------- -------------------- + if (controller.type == 1) { + return Padding( + padding: const EdgeInsets.fromLTRB(20, 10, 20, 10), + child: Column(children: [ + // 유투브 영상 나옴 + const WordVibrationWidget(), + const SizedBox( + height: 10, + ), + const YoutubeWordPlayer(), + // + // Text( + // controller.wordList[0].wordCard.speaker, + // style: const TextStyle( + // fontSize: 16, + // fontWeight: FontWeight.w600, + // color: ColorSystem.black, + // ), + // ), + const SizedBox(height: 20), + PhoneticButtons( + phoneticString: + controller.wordList[0].wordCard.speaker, + realString: controller.wordList[0].wordCard.word, + description: wordViewModel.description.value, + ), - const SizedBox( - height: 30, - ), - ], - ), - ); - } - else { - return LearningSessionScreen(isStudyMode: true); + WordSentenceWidget( + pageController: pageController, + wordDataList: controller.wordList, + type: controller.type, + ) + ])); + } - } - }, + /// -------------------- --------- -------------------- + /// -------------------- 문장 교정 -------------------- + /// -------------------- --------- -------------------- + if (controller.type == 2) { + return Padding( + padding: const EdgeInsets.fromLTRB(20, 10, 20, 10), + child: Column( + children: [ + const WordVibrationWidget(), + const SizedBox( + height: 10, + ), + // 유투브 영상 + const YoutubeWordPlayer(), + const SizedBox(height: 20), + // 단어 분리 + PhoneticButtons( + phoneticString: + controller.wordList[0].wordCard.speaker, + realString: controller.wordList[0].wordCard.word, + description: wordViewModel.description.value, + ), + // 녹음 버튼 + WordSentenceWidget( + pageController: pageController, + wordDataList: controller.wordList, + type: controller.type, + ), + + const SizedBox( + height: 30, + ), + ], + ), + ); + } else { + /// -------------------- --------- -------------------- + /// -------------------- 문단 교정 -------------------- + /// -------------------- --------- -------------------- + return const LearningSessionScreen(isStudyMode: true); + } + }, + ), + ], ), - ], + ), ), ), ); From 040639d0e06eea44f6db2e8e7fdf8f9eecb4963f Mon Sep 17 00:00:00 2001 From: HuiChan Seo <78739194+seochan99@users.noreply.github.com> Date: Sat, 4 May 2024 23:39:09 +0900 Subject: [PATCH 7/8] =?UTF-8?q?=F0=9F=94=A8Chore:=20=EA=B8=B0=ED=83=80?= =?UTF-8?q?=EC=9E=91=EC=97=85?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../word/widget/phonetic_buttons_widget.dart | 102 ++++++++++++++++++ .../word/widget/word_sentence_widget.dart | 10 +- .../word/widget/word_vibration_widget.dart | 43 ++++---- 3 files changed, 130 insertions(+), 25 deletions(-) create mode 100644 lib/views/word/widget/phonetic_buttons_widget.dart diff --git a/lib/views/word/widget/phonetic_buttons_widget.dart b/lib/views/word/widget/phonetic_buttons_widget.dart new file mode 100644 index 0000000..f9c8861 --- /dev/null +++ b/lib/views/word/widget/phonetic_buttons_widget.dart @@ -0,0 +1,102 @@ +import 'package:earlips/models/phoneme_model.dart'; +import 'package:earlips/utilities/style/color_system.dart'; +import 'package:earlips/views/phoneme/phoneme_detail_screen.dart'; +import 'package:flutter/material.dart'; +import 'package:get/get.dart'; + +class PhoneticButtons extends StatelessWidget { + final String phoneticString; + final String description; + final String realString; + + const PhoneticButtons( + {super.key, + required this.phoneticString, + required this.description, + required this.realString}); + + @override + Widget build(BuildContext context) { + // Splitting the phonetic string into components + List phonemesWord = phoneticString.replaceAll('/', '').split(' '); + + String cleanedString = phoneticString + .replaceAll('ˈ', '') + .replaceAll('ː', '') + .replaceAll('.', ''); + + List phonemesVowels = cleanedString.replaceAll(' ', '').split(''); + + // real String Split + List realWords = realString.split(' '); + + // List phonemes2 = 'b.juː.t.ɪ.f.ə.l'.split('.'); + + // final gemini = Gemini.instance; + + // // Gemini API를 호출하여 결과 처리 + // gemini + // .text( + // "$word 를 발음하면 $speak 이야, 이를 청각장애인이 시각적으로 보고 발음할 수 있도록 한글이 아닌 영어로 세세하게 말해줘") + // .then((value) { + // // 성공적으로 결과를 받았을 때 출력 및 상태 업데이트 + // wordViewModel.description.value = value?.output ?? ""; + // print(value?.output); // output이 정확한 필드인지 확인하세요. API 응답에 따라 다를 수 있습니다. + // }).catchError((error) { + // // 에러 처리 + // print('Error occurred: $error'); + // }); + + return Column( + children: [ + const Text("Split Words", + style: TextStyle( + fontSize: 16, + color: ColorSystem.black, + fontWeight: FontWeight.w500)), + const SizedBox(height: 10), + Wrap( + spacing: 8.0, // Space between buttons + children: phonemesWord + .map((phoneme) => ElevatedButton( + onPressed: () { + // Navigate to a detail page for the phoneme + Get.to(() => PhonemeDetailScreen( + phoneme: Phoneme( + symbol: phoneme, description: '', imageSrc: ''))); + }, + child: Text(phoneme, + style: const TextStyle( + fontSize: 16, color: ColorSystem.black)), + )) + .toList(), + ), + const SizedBox(height: 20), + const Text("Split Phonemes", + style: TextStyle( + fontSize: 16, + color: ColorSystem.black, + fontWeight: FontWeight.w500)), + const SizedBox(height: 10), + Wrap( + spacing: 8.0, // Space between buttons + children: phonemesVowels + .map((phoneme) => ElevatedButton( + onPressed: () { + print(description); + Get.to(() => PhonemeDetailScreen( + phoneme: Phoneme( + symbol: phoneme, + description: description, + imageSrc: ''))); + }, + child: Text(phoneme, + style: const TextStyle( + fontSize: 16, color: ColorSystem.black)), + )) + .toList(), + ), + ], + ); + } +} diff --git a/lib/views/word/widget/word_sentence_widget.dart b/lib/views/word/widget/word_sentence_widget.dart index d5c75a1..672f6d4 100644 --- a/lib/views/word/widget/word_sentence_widget.dart +++ b/lib/views/word/widget/word_sentence_widget.dart @@ -30,18 +30,16 @@ class WordSentenceWidget extends StatelessWidget { return Center( child: Column( children: [ - if(type!= 0)Container( - child: WordVibrationWidget() - ), Container( - margin: type != 0 ? EdgeInsets.only(top: Get.height * 0.1) : EdgeInsets.zero, + margin: const EdgeInsets.only(top: 30), child: Align( alignment: Alignment.bottomCenter, child: Container( - margin: EdgeInsets.only(bottom: 0), + margin: const EdgeInsets.only(bottom: 0), child: Ink( decoration: BoxDecoration( - color: model.isRecording.value ? Colors.red : Colors.blue, + color: + model.isRecording.value ? Colors.red : Colors.blue, borderRadius: BorderRadius.circular(40), ), child: InkWell( diff --git a/lib/views/word/widget/word_vibration_widget.dart b/lib/views/word/widget/word_vibration_widget.dart index 2d7f648..c1c8d94 100644 --- a/lib/views/word/widget/word_vibration_widget.dart +++ b/lib/views/word/widget/word_vibration_widget.dart @@ -3,9 +3,9 @@ import 'package:get/get.dart'; import 'package:vibration/vibration.dart'; import 'package:earlips/viewModels/word/word_viewmodel.dart'; - class WordVibrationWidget extends StatelessWidget { - const WordVibrationWidget({super.key, this.externalPattern, this.externalIntensities}); + const WordVibrationWidget( + {super.key, this.externalPattern, this.externalIntensities}); final List? externalPattern; final List? externalIntensities; @@ -15,36 +15,41 @@ class WordVibrationWidget extends StatelessWidget { final wordViewModel = Get.find(); return Obx(() { - if (wordViewModel.currentIndex.value >= 0 && wordViewModel.currentIndex.value < wordViewModel.wordList.length) { - final currentWordCard = wordViewModel.wordList[wordViewModel.currentIndex.value].wordCard; - final List? pattern = externalPattern != null ? externalPattern : currentWordCard.pattern; - final List? intensities = externalIntensities != null ? externalIntensities : currentWordCard.intensities; - + if (wordViewModel.currentIndex.value >= 0 && + wordViewModel.currentIndex.value < wordViewModel.wordList.length) { + final currentWordCard = + wordViewModel.wordList[wordViewModel.currentIndex.value].wordCard; + final List pattern = externalPattern ?? currentWordCard.pattern; + final List intensities = + externalIntensities ?? currentWordCard.intensities; print('pattern: $pattern'); print('intensities: $intensities'); return Container( alignment: Alignment.topLeft, - margin: const EdgeInsets.only(top: 10), + margin: const EdgeInsets.only(top: 15, left: 5, right: 5), child: Column( mainAxisAlignment: MainAxisAlignment.center, children: [ ElevatedButton( - child: Container( - width: Get.width * 0.33, - child: Row( - children: [ - Text('진동으로 들어보기'), - const SizedBox(width: 10), - Icon(Icons.vibration), - ], + child: const SizedBox( + child: Padding( + padding: EdgeInsets.symmetric(horizontal: 40), + child: Row( + mainAxisAlignment: MainAxisAlignment.center, + children: [ + Text('Try Listening with Vibration'), + SizedBox(width: 10), + Icon(Icons.vibration), + ], + ), ), ), onPressed: () { Vibration.vibrate( - pattern: pattern!, - intensities: intensities!, + pattern: pattern, + intensities: intensities, ); }, ), @@ -52,7 +57,7 @@ class WordVibrationWidget extends StatelessWidget { ), ); } else { - return Center(child: Text('Invalid index or word list empty')); + return const Center(child: Text('Invalid index or word list empty')); } }); } From 5eb1fe2ba5ca6056ab6a62e8740cc37b7c7ffccd Mon Sep 17 00:00:00 2001 From: HuiChan Seo <78739194+seochan99@users.noreply.github.com> Date: Sat, 4 May 2024 23:56:41 +0900 Subject: [PATCH 8/8] =?UTF-8?q?=E2=9C=A8Feat:=20=EB=94=94=ED=85=8C?= =?UTF-8?q?=EC=9D=BC=20=EC=8B=AC=EB=B3=BC/=EB=A6=AC=EC=96=BC=EC=8A=A4?= =?UTF-8?q?=ED=8A=B8=EB=A7=81=20=EC=A0=81=EC=9A=A9?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- lib/views/phoneme/phoneme_detail_screen.dart | 9 +++++++-- lib/views/phoneme/widget/phoneme_list_widget.dart | 6 ++++-- lib/views/phoneme/widget/vowles_widget.dart | 5 ++++- lib/views/word/widget/phonetic_buttons_widget.dart | 6 ++++-- 4 files changed, 19 insertions(+), 7 deletions(-) diff --git a/lib/views/phoneme/phoneme_detail_screen.dart b/lib/views/phoneme/phoneme_detail_screen.dart index 6f15caa..ed96dd4 100644 --- a/lib/views/phoneme/phoneme_detail_screen.dart +++ b/lib/views/phoneme/phoneme_detail_screen.dart @@ -9,8 +9,10 @@ import 'package:get/get.dart'; class PhonemeDetailScreen extends StatelessWidget { final Phoneme phoneme; + final String realString; - PhonemeDetailScreen({super.key, required this.phoneme}); + PhonemeDetailScreen( + {super.key, required this.phoneme, required this.realString}); final wordViewModel = Get.find(); @@ -38,7 +40,10 @@ class PhonemeDetailScreen extends StatelessWidget { children: [ const SizedBox(height: 20), // --------------------------- 발음 카드 - PhonemeListWidget(phoneme: phoneme), + PhonemeListWidget( + phoneme: phoneme, + realString: realString, + ), SizedBox( height: 70, child: Column( diff --git a/lib/views/phoneme/widget/phoneme_list_widget.dart b/lib/views/phoneme/widget/phoneme_list_widget.dart index 0c69758..4d2bc81 100644 --- a/lib/views/phoneme/widget/phoneme_list_widget.dart +++ b/lib/views/phoneme/widget/phoneme_list_widget.dart @@ -7,8 +7,10 @@ import 'package:get/get.dart'; class PhonemeListWidget extends StatelessWidget { final Phoneme phoneme; + final String realString; - const PhonemeListWidget({super.key, required this.phoneme}); + const PhonemeListWidget( + {super.key, required this.phoneme, required this.realString}); @override Widget build(BuildContext context) { @@ -32,7 +34,7 @@ class PhonemeListWidget extends StatelessWidget { ListTile( tileColor: Colors.white, title: Text( - phoneme.symbol, + realString, style: const TextStyle( fontSize: 19, fontWeight: FontWeight.w600, diff --git a/lib/views/phoneme/widget/vowles_widget.dart b/lib/views/phoneme/widget/vowles_widget.dart index ea79c34..bb62aba 100644 --- a/lib/views/phoneme/widget/vowles_widget.dart +++ b/lib/views/phoneme/widget/vowles_widget.dart @@ -28,7 +28,10 @@ class VowelsWidget extends StatelessWidget { itemBuilder: (context, index) { return GestureDetector( onTap: () { - Get.to(() => PhonemeDetailScreen(phoneme: phonemes[index])); + Get.to(() => PhonemeDetailScreen( + phoneme: phonemes[index], + realString: phonemes[index].symbol, + )); }, child: Card( child: Center( diff --git a/lib/views/word/widget/phonetic_buttons_widget.dart b/lib/views/word/widget/phonetic_buttons_widget.dart index f9c8861..adcff9a 100644 --- a/lib/views/word/widget/phonetic_buttons_widget.dart +++ b/lib/views/word/widget/phonetic_buttons_widget.dart @@ -63,7 +63,8 @@ class PhoneticButtons extends StatelessWidget { // Navigate to a detail page for the phoneme Get.to(() => PhonemeDetailScreen( phoneme: Phoneme( - symbol: phoneme, description: '', imageSrc: ''))); + symbol: phoneme, description: '', imageSrc: ''), + realString: realString)); }, child: Text(phoneme, style: const TextStyle( @@ -88,7 +89,8 @@ class PhoneticButtons extends StatelessWidget { phoneme: Phoneme( symbol: phoneme, description: description, - imageSrc: ''))); + imageSrc: ''), + realString: realString)); }, child: Text(phoneme, style: const TextStyle(