diff --git a/assets/images/sentance.gif b/assets/images/sentance.gif new file mode 100644 index 0000000..ed6e642 Binary files /dev/null and b/assets/images/sentance.gif differ diff --git a/assets/images/word.gif b/assets/images/word.gif new file mode 100644 index 0000000..77db136 Binary files /dev/null and b/assets/images/word.gif differ diff --git a/lib/bindings/root_binding.dart b/lib/bindings/root_binding.dart index 30f0385..3e90955 100644 --- a/lib/bindings/root_binding.dart +++ b/lib/bindings/root_binding.dart @@ -3,6 +3,7 @@ import 'package:earlips/viewModels/home/home_viewmodel.dart'; import 'package:earlips/viewModels/root/root_viewmodel.dart'; import 'package:earlips/viewModels/study/study_viewmodel.dart'; import 'package:earlips/viewModels/realtime/real_create_viewmodel.dart'; +import 'package:earlips/viewModels/word/word_viewmodel.dart'; class RootBinding extends Bindings { @override diff --git a/lib/models/phoneme_model.dart b/lib/models/phoneme_model.dart index 24e6bad..fd228bd 100644 --- a/lib/models/phoneme_model.dart +++ b/lib/models/phoneme_model.dart @@ -192,3 +192,4 @@ List rControlledVowels = [ description: 'Fort, more, door', imageSrc: 'assets/images/phoneme/vowels_1.png'), ]; + diff --git a/lib/views/phoneme/phoneme_detail_screen.dart b/lib/views/phoneme/phoneme_detail_screen.dart index 61faedc..001a9a4 100644 --- a/lib/views/phoneme/phoneme_detail_screen.dart +++ b/lib/views/phoneme/phoneme_detail_screen.dart @@ -3,7 +3,6 @@ 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/cupertino.dart'; import 'package:flutter/material.dart'; import 'package:flutter_svg/flutter_svg.dart'; import 'package:get/get.dart'; @@ -15,10 +14,12 @@ class PhonemeDetailScreen extends StatelessWidget { PhonemeDetailScreen( {super.key, required this.phoneme, required this.realString}); + final wordViewModel = Get.find(); @override Widget build(BuildContext context) { + Get.put(WordViewModel(type: 0)); wordViewModel.generateDescription(phoneme.symbol); return Scaffold( @@ -26,109 +27,80 @@ class PhonemeDetailScreen extends StatelessWidget { preferredSize: const Size.fromHeight(kToolbarHeight), child: BlueBackAppbar(title: 'Details for ${phoneme.symbol}'), ), - body: SingleChildScrollView( - child: Center( - child: Column( - children: [ - Container( - decoration: const BoxDecoration( - color: ColorSystem.main2, - borderRadius: BorderRadius.only( - bottomLeft: Radius.circular(24), - bottomRight: Radius.circular(24), - ), + 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), - // --------------------------- 발음 카드 - PhonemeListWidget( - phoneme: phoneme, - realString: realString, - ), - SizedBox( - height: 70, - child: Column( - children: [ - const SizedBox( - height: 15, + ), + child: Column( + children: [ + const SizedBox(height: 20), + // --------------------------- 발음 카드 + PhonemeListWidget( + phoneme: phoneme, + realString: realString, + ), + SizedBox( + height: 70, + child: Column( + children: [ + const SizedBox( + height: 15, + ), + // --------------------------- 발음 안내 + Text( + "word_type_12_height".tr, + style: const TextStyle( + fontSize: 16, + fontWeight: FontWeight.w600, + color: ColorSystem.white, ), - // --------------------------- 발음 안내 - Text( - "word_type_12_height".tr, - style: const TextStyle( - fontSize: 16, - fontWeight: FontWeight.w600, - color: ColorSystem.white, - ), - ) - ], - ), + ), + ], ), - ], - ), - ), - // --------------------------- 발음 세부 내용 기입 - const Padding( - padding: EdgeInsets.all(20), - child: Column( - children: [ - // SvgPicture.asset( - // 'assets/images/phoneme/vowels_1.svg', - // width: 90, - // height: 90, - // ), - ], - ), + ), + ], ), - _BottomBox(phoneme: phoneme), - ], - ), - ), - ), - ); - } -} - -class _BottomBox extends StatelessWidget { - const _BottomBox({super.key, required this.phoneme}); - - final Phoneme phoneme; + ), - @override - Widget build(BuildContext context) { - return Column( - children: [ - Image.asset( - phoneme.imageSrc, - width: Get.width * 0.50, - ), - const SizedBox(height: 25), - Container( - padding: const EdgeInsets.all(20.0), - width: Get.width - 40, - margin: const EdgeInsets.only(bottom: 40), - decoration: BoxDecoration( - borderRadius: BorderRadius.circular(15.0), - color: const Color(0x80FFFFFF), // 80은 50% - boxShadow: [ - BoxShadow( - color: Colors.black.withOpacity(0.1), - spreadRadius: 0, - blurRadius: 20, - offset: const Offset(0, 4), + // --------------------------- 발음 세부 내용 기입 +// image + Padding( + padding: const EdgeInsets.all(20), + child: Column( + children: [ + 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으로 가정 + ), + ); + } + }), + ], ), - ], - ), - child: Text( - phoneme.description, - style: const TextStyle( - fontSize: 18, - fontWeight: FontWeight.w600, ), - ), + + const Spacer(), + ], ), - ], + ), ); } -} +} \ No newline at end of file diff --git a/lib/views/phoneme/vowel_datail_screen.dart b/lib/views/phoneme/vowel_datail_screen.dart new file mode 100644 index 0000000..e58b028 --- /dev/null +++ b/lib/views/phoneme/vowel_datail_screen.dart @@ -0,0 +1,126 @@ +import 'package:earlips/models/phoneme_model.dart'; +import 'package:earlips/utilities/style/color_system.dart'; +import 'package:earlips/views/phoneme/widget/phoneme_list_widget.dart'; +import 'package:earlips/views/word/widget/blue_back_appbar.dart'; +import 'package:flutter/cupertino.dart'; +import 'package:flutter/material.dart'; +import 'package:flutter_svg/flutter_svg.dart'; +import 'package:get/get.dart'; + +class VowelDetailScreen extends StatelessWidget { + final Phoneme phoneme; + + const VowelDetailScreen({super.key, required this.phoneme, required String realString}); + + @override + Widget build(BuildContext context) { + return Scaffold( + appBar: PreferredSize( + preferredSize: const Size.fromHeight(kToolbarHeight), + child: BlueBackAppbar(title: 'Details for ${phoneme.symbol}'), + ), + body: SingleChildScrollView( + child: 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), + // --------------------------- 발음 카드 + PhonemeListWidget(phoneme: phoneme, realString: '',), + SizedBox( + height: 70, + child: Column( + children: [ + const SizedBox( + height: 15, + ), + // --------------------------- 발음 안내 + Text( + "word_type_12_height".tr, + style: const TextStyle( + fontSize: 16, + fontWeight: FontWeight.w600, + color: ColorSystem.white, + ), + ), + ], + ), + ), + ], + ), + ), + + // --------------------------- 발음 세부 내용 기입 + // image + const Padding( + padding: EdgeInsets.all(20), + child: Column( + children: [ + // SvgPicture.asset( + // 'assets/images/phoneme/vowels_1.svg', + // width: 90, + // height: 90, + // ), + ], + ), + ), + _BottomBox(phoneme: phoneme), + ], + ), + ), + ), + ); + } +} + +class _BottomBox extends StatelessWidget { + const _BottomBox({super.key, required this.phoneme}); + + final Phoneme phoneme; + + @override + Widget build(BuildContext context) { + return Column( + children: [ + Image.asset( + phoneme.imageSrc, + width: Get.width * 0.50, + ), + const SizedBox(height: 25), + Container( + padding: const EdgeInsets.all(20.0), + width: Get.width - 40, + margin: EdgeInsets.only(bottom: 40), + decoration: BoxDecoration( + borderRadius: BorderRadius.circular(15.0), + color: Color(0x80FFFFFF), // 80은 50% + boxShadow: [ + BoxShadow( + color: Colors.black.withOpacity(0.1), + spreadRadius: 0, + blurRadius: 20, + offset: const Offset(0, 4), + ), + ], + ), + child: Text( + phoneme.description, + style: const TextStyle( + fontSize: 18, + fontWeight: FontWeight.w600, + ), + ), + ), + ], + ); + } +} \ No newline at end of file diff --git a/lib/views/phoneme/widget/vowles_widget.dart b/lib/views/phoneme/widget/vowles_widget.dart index bb62aba..01ee644 100644 --- a/lib/views/phoneme/widget/vowles_widget.dart +++ b/lib/views/phoneme/widget/vowles_widget.dart @@ -3,6 +3,8 @@ import 'package:earlips/views/phoneme/phoneme_detail_screen.dart'; import 'package:flutter/material.dart'; import 'package:get/get.dart'; +import '../vowel_datail_screen.dart'; + class VowelsWidget extends StatelessWidget { final int type; // 0 for vowels, 1 for consonants, 2 for R-Controlled Vowels const VowelsWidget({ @@ -28,7 +30,7 @@ class VowelsWidget extends StatelessWidget { itemBuilder: (context, index) { return GestureDetector( onTap: () { - Get.to(() => PhonemeDetailScreen( + Get.to(() => VowelDetailScreen( phoneme: phonemes[index], realString: phonemes[index].symbol, )); diff --git a/lib/views/word/widget/phonetic_buttons_widget.dart b/lib/views/word/widget/phonetic_buttons_widget.dart index adcff9a..002d05b 100644 --- a/lib/views/word/widget/phonetic_buttons_widget.dart +++ b/lib/views/word/widget/phonetic_buttons_widget.dart @@ -4,6 +4,10 @@ import 'package:earlips/views/phoneme/phoneme_detail_screen.dart'; import 'package:flutter/material.dart'; import 'package:get/get.dart'; +import '../../phoneme/vowel_datail_screen.dart'; +import 'package:earlips/models/phoneme_model.dart'; + + class PhoneticButtons extends StatelessWidget { final String phoneticString; final String description; @@ -15,6 +19,7 @@ class PhoneticButtons extends StatelessWidget { required this.description, required this.realString}); + @override Widget build(BuildContext context) { // Splitting the phonetic string into components @@ -30,23 +35,6 @@ class PhoneticButtons extends StatelessWidget { // 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", @@ -80,25 +68,27 @@ class PhoneticButtons extends StatelessWidget { fontWeight: FontWeight.w500)), const SizedBox(height: 10), Wrap( - spacing: 8.0, // Space between buttons + spacing: 8.0, children: phonemesVowels - .map((phoneme) => ElevatedButton( - onPressed: () { - print(description); - Get.to(() => PhonemeDetailScreen( - phoneme: Phoneme( - symbol: phoneme, - description: description, - imageSrc: ''), - realString: realString)); - }, - child: Text(phoneme, - style: const TextStyle( - fontSize: 16, color: ColorSystem.black)), - )) - .toList(), + .map((phonemeSymbol) { + Phoneme phoneme = vowels.firstWhere( + (vowel) => vowel.symbol == phonemeSymbol, + orElse: () => Phoneme(symbol: phonemeSymbol, description: 'Description not found', imageSrc: 'assets/images/phoneme/placeholder.png') + ); + return ElevatedButton( + onPressed: () { + Get.to(() => VowelDetailScreen( + phoneme: phoneme, + realString: realString)); + }, + child: Text(phonemeSymbol, style: const TextStyle(fontSize: 16, color: ColorSystem.black)), + ); + }).toList(), ), + ], ); } } + + diff --git a/lib/views/word/word_screen.dart b/lib/views/word/word_screen.dart index 7e8dac0..f1038cf 100644 --- a/lib/views/word/word_screen.dart +++ b/lib/views/word/word_screen.dart @@ -97,7 +97,8 @@ class WordScreen extends StatelessWidget { const SizedBox( height: 10, ), - const YoutubeWordPlayer(), + Image.asset("assets/images/word.gif", + width: Get.width * 0.8,), // // Text( // controller.wordList[0].wordCard.speaker, @@ -136,7 +137,8 @@ class WordScreen extends StatelessWidget { height: 10, ), // 유투브 영상 - const YoutubeWordPlayer(), + Image.asset("assets/images/sentance.gif", + width: Get.width * 0.8,), const SizedBox(height: 20), // 단어 분리 PhoneticButtons( diff --git a/pubspec.yaml b/pubspec.yaml index b1ace64..e20fe67 100644 --- a/pubspec.yaml +++ b/pubspec.yaml @@ -63,6 +63,8 @@ flutter: - assets/images/phoneme/ - assets/images/output-onlinegiftools.gif - assets/images/sound_wave.gif + - assets/images/sentance.gif + - assets/images/word.gif # - assets/sounds/speech_to_text_listening.m4r # - assets/sounds/speech_to_text_cancel.m4r # - assets/sounds/speech_to_text_stop.m4r