Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

✨Feat: 문단 학습페이지 대본 페이지로, 대본 테스트 페이지 디자인 수정 #32

Merged
merged 4 commits into from
Feb 19, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 2 additions & 2 deletions ios/Podfile.lock
Original file line number Diff line number Diff line change
Expand Up @@ -938,7 +938,7 @@ SPEC CHECKSUMS:
FirebaseFirestore: 21be9ea244830f6cac15464550c2975c43f9dffc
FirebaseFirestoreInternal: 7ac1e0c5b4e75aeb898dfe4b1d6d77abbac9eca3
FirebaseSharedSwift: 19b3f709993d6fa1d84941d41c01e3c4c11eab93
Flutter: e0871f40cf51350855a761d2e70bf5af5b9b5de7
Flutter: f04841e97a9d0b0a8025694d0796dd46242b2854
flutter_inappwebview: 3d32228f1304635e7c028b0d4252937730bbc6cf
flutter_localization: f43b18844a2b3d2c71fd64f04ffd6b1e64dd54d4
flutter_native_splash: 52501b97d1c0a5f898d687f1646226c1f93c56ef
Expand Down Expand Up @@ -966,4 +966,4 @@ SPEC CHECKSUMS:

PODFILE CHECKSUM: 0b2c97823421f8b156b8e4753a469ac167670df8

COCOAPODS: 1.15.2
COCOAPODS: 1.14.3
2 changes: 0 additions & 2 deletions lib/views/home/widget/study_chart.dart
Original file line number Diff line number Diff line change
Expand Up @@ -47,8 +47,6 @@ class ChartTitleWidgets {
fontSize: 13,
);
if (value == 0 || value == maxYValue) {
print(maxYValue);
print(value);
return Text('${value.toInt()}', style: style, textAlign: TextAlign.left);
}
return Container();
Expand Down
186 changes: 186 additions & 0 deletions lib/views/paragraph/analyze_screen.dart
Original file line number Diff line number Diff line change
@@ -0,0 +1,186 @@
import 'dart:async';

import 'package:flutter/material.dart';
import 'package:get/get.dart';
import 'package:get/get_core/src/get_main.dart';
import 'package:speech_to_text/speech_to_text.dart' as stt;
import 'package:permission_handler/permission_handler.dart';
import 'package:earlips/viewModels/script/analyze_viewmodel.dart';
import '../../utilities/app_routes.dart';



class AnalyzeScreen extends StatefulWidget {
@override
_AnalyzeScreenState createState() => _AnalyzeScreenState();
}

class _AnalyzeScreenState extends State<AnalyzeScreen> {

@override
Widget build(BuildContext context) {
return GestureDetector(
onTap: () {
FocusScope.of(context).requestFocus(FocusNode());
},
child: Scaffold(
appBar: AppBar(
title: Text('발음 및 빠르기 분석'),
centerTitle: true,
),
body: SingleChildScrollView(
child: Column(
children: [
Container(
alignment: Alignment.center,
width: Get.width - 40,
height: Get.height * 0.2,
margin: EdgeInsets.all(20.0),
padding: EdgeInsets.all(10.0), // 내부 여백을 추가합니다.
decoration: BoxDecoration(
color: Colors.white, // 배경색을 지정합니다.
borderRadius: BorderRadius.circular(15.0), // 테두리 둥글기를 지정합니다.
border: Border.all(color: Colors.white), // 테두리 색상을 지정합니다. 필요에 따라 변경 가능합니다.
),
child: _TopText(),
),
Stack(
children: [
Container(
alignment: Alignment.center,
width: Get.width - 40,
height: Get.height * 0.5,
margin: EdgeInsets.all(20.0),
padding: EdgeInsets.all(10.0), // 내부 여백을 추가합니다.
decoration: BoxDecoration(
color: Colors.white, // 배경색을 지정합니다.
borderRadius: BorderRadius.circular(15.0), // 테두리 둥글기를 지정합니다.
border: Border.all(color: Colors.white), // 테두리 색상을 지정합니다. 필요에 따라 변경 가능합니다.
),
child: TextStylingWidget(),
),

],
),
],
),
),
floatingActionButton: Container(
width: Get.width,
alignment: Alignment.bottomCenter,

child: FloatingActionButton(
onPressed: () {
Get.toNamed(Routes.HOME);
},
child: Icon(Icons.home), // 홈 아이콘 사용
tooltip: '홈으로', // 롱 프레스 시 표시되는 텍스트
),
),
),
);
}
}

class TextStylingWidget extends StatelessWidget {
final AnalyzeViewModel model = Get.put(AnalyzeViewModel());

@override
Widget build(BuildContext context) {
return SingleChildScrollView(
child: RichText(
text: TextSpan(
children: _buildTextSpans(),
style: TextStyle(color: Colors.black, fontSize: 16),
),
textAlign: TextAlign.start,
),
);
}

List<TextSpan> _buildTextSpans() {
List<TextSpan> spans = [];
int globalWordIndex = 0; // 전체 단어에 대한 인덱스를 추적합니다.

for (int i = 0; i < model.userSenten.length; i++) {
final List<String> words = model.userSenten[i].split(' ');
List<TextSpan> wordSpans = [];

for (String word in words) {
final bool isWrongWord = model.wrongWordIndexes.contains(globalWordIndex);
wordSpans.add(TextSpan(
text: "$word ",
style: TextStyle(
color: isWrongWord ? Colors.red : Colors.black,
),
));
globalWordIndex++; // 각 단어를 처리할 때마다 전체 단어 인덱스를 증가시킵니다.
}

spans.add(TextSpan(
children: wordSpans,
style: TextStyle(
decoration: model.wrongFastIndexes.contains(i) ? TextDecoration.underline : TextDecoration.none,
),
));
spans.add(TextSpan(text: "\n")); // 문장 사이에 줄바꿈 추가
}

return spans;
}

}

class _TopText extends StatelessWidget {
const _TopText({super.key});

@override
Widget build(BuildContext context) {
return Container(
padding: EdgeInsets.all(10.0),
child: Column(
mainAxisAlignment: MainAxisAlignment.center,
children: [
// 발음이 틀린 글씨에 대한 설명
RichText(
text: TextSpan(
style: TextStyle(fontSize: 16, color: Colors.black),
children: [
TextSpan(text: '발음이 틀린 글씨는 빨간색으로 표시됩니다 ex)'),
// 예시에 적용할 스타일
TextSpan(
text: '강아지는 ',
style: TextStyle(color: Colors.red),
),
TextSpan(
text: '뛴다',
),
],
),
),
Padding(
padding: EdgeInsets.only(top: 20),
),
// 문장의 빠르기에 대한 설명
RichText(
text: TextSpan(
style: TextStyle(fontSize: 16, color: Colors.black),
children: <TextSpan>[
TextSpan(text: '문장의 빠르기가 빠르거나 느리면 밑줄이 표시됩니다. ex)'),
// 예시에 적용할 스타일
TextSpan(
text: '강아지는 ',
style: TextStyle(decoration: TextDecoration.underline),
),
TextSpan(
text: '뛴다',
style: TextStyle(decoration: TextDecoration.underline),
),
],
),
),
],
),
);
}
}
122 changes: 122 additions & 0 deletions lib/views/paragraph/create_script_screen.dart
Original file line number Diff line number Diff line change
@@ -0,0 +1,122 @@
import 'package:earlips/utilities/style/color_styles.dart';
import 'package:flutter/material.dart';
import 'package:provider/provider.dart';
import 'package:earlips/viewModels/script/create_script_viewmodel.dart';
import 'package:get/get.dart';

class CreateScriptPage extends StatelessWidget {
const CreateScriptPage({super.key});

@override
Widget build(BuildContext context) {
return ChangeNotifierProvider<CreateScriptViewModel>(
create: (_) => CreateScriptViewModel(),
child: Consumer<CreateScriptViewModel>(
builder: (context, model, child) => Scaffold(
appBar: AppBar(
title: const Text('문단교정'),
centerTitle: true,
actions: <Widget>[
TextButton(
onPressed: model.complete,
child: const Text(
'완료',
style: TextStyle(
color: Colors.black,
fontSize: 20,
),
),
),
],
),
body: Stack(
// Stack 위젯을 사용하여 Positioned를 올바르게 배치합니다.
children: [
Column(
// 기존의 Column 구조를 Stack 내에 배치합니다.
children: [
Expanded(
flex: 1,
child: Padding(
padding: const EdgeInsets.all(10.0),
child: TextField(
controller: model.writedTextController,
expands: true,
maxLines: null,
decoration: InputDecoration(
hintText: '대본을 입력하세요...',
fillColor: Colors.white,
filled: true,
border: OutlineInputBorder(
borderRadius: BorderRadius.circular(15.0),
borderSide: BorderSide.none,
),
),
textAlignVertical: TextAlignVertical.top,
),
),
),
Expanded(
flex: 1,
child: Padding(
padding: const EdgeInsets.fromLTRB(25, 20, 25, 100),
child: Container(
padding: const EdgeInsets.all(20.0),
width: Get.width * 0.8,
decoration: BoxDecoration(
color: Colors.white,
borderRadius: BorderRadius.circular(15.0),
boxShadow: [
BoxShadow(
color: Colors.grey.withOpacity(0.5),
spreadRadius: 1,
blurRadius: 6,
offset: const Offset(0, 3),
),
],
),
child: SingleChildScrollView(
child: Text(
model.voicedTextController.text,
style: const TextStyle(fontSize: 16),
),
),
),
),
),
],
),
Positioned(
// Positioned 위젯으로 사용자 정의 FloatingActionButton을 배치합니다.
bottom: 20,
left: 0,
right: 0,
child: Align(
alignment: Alignment.bottomCenter,
child: Ink(
decoration: BoxDecoration(
color: model.isRecording ? Colors.red : Colors.blue,
borderRadius: BorderRadius.circular(40),
),
child: InkWell(
borderRadius: BorderRadius.circular(40),
onTap: model.toggleRecording,
child: Padding(
padding: const EdgeInsets.all(20),
child: Icon(
model.isRecording ? Icons.stop : Icons.mic,
size: 30,
color: Colors.white,
),
),
),
),
),
),
],
),
),
),
);
}
}
Loading
Loading