Skip to content
This repository has been archived by the owner on Oct 20, 2024. It is now read-only.

✏️ Home 화면 수정 #43

Merged
merged 8 commits into from
Aug 6, 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: 3 additions & 1 deletion Nabi/data/src/main/java/com/nabi/data/mapper/HomeMapper.kt
Original file line number Diff line number Diff line change
Expand Up @@ -13,9 +13,11 @@ object HomeMapper {
nickname = this.nickname,
recentFiveDiaries = this.recentFiveDiaries.map { diary ->
RecentFiveDiary(
diaryId = diary.diaryId,
content = diary.content,
diaryEntryDate = diary.diaryEntryDate,
emotion = diary.emotion ?: ""
emotion = diary.emotion ?: "",
isBookmarked = diary.isBookmarked
)
}
)
Expand Down
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
package com.nabi.data.model.diary

data class UpdateDiaryRequestDTO (
val content: String
val content: String,
val diaryEntryDate: String
)
Original file line number Diff line number Diff line change
Expand Up @@ -4,10 +4,14 @@ package com.nabi.data.model.home
import com.google.gson.annotations.SerializedName

data class RecentFiveDiary(
@SerializedName("diaryId")
val diaryId: Int,
@SerializedName("content")
val content: String,
@SerializedName("diaryEntryDate")
val diaryEntryDate: String,
@SerializedName("emotion")
val emotion: String?
val emotion: String?,
@SerializedName("isBookmarked")
val isBookmarked: Boolean
)
Original file line number Diff line number Diff line change
Expand Up @@ -9,5 +9,5 @@ data class ResponseHomeDTO(
@SerializedName("nickname")
val nickname: String,
@SerializedName("recentFiveDiaries")
val recentFiveDiaries: List<RecentFiveDiary>
val recentFiveDiaries: List<RecentFiveDiary>,
)
Original file line number Diff line number Diff line change
Expand Up @@ -146,10 +146,11 @@ class DiaryRepositoryImpl @Inject constructor(
override suspend fun updateDiary(
accessToken: String,
id: Int,
content: String
content: String,
diaryEntryDate: String
): Result<UpdateDiaryInfo> {
val result =
diaryRemoteDataSource.updateDiary(accessToken, id, UpdateDiaryRequestDTO(content))
diaryRemoteDataSource.updateDiary(accessToken, id, UpdateDiaryRequestDTO(content, diaryEntryDate))

return if (result.isSuccess) {
val res = result.getOrNull()
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,9 @@ data class HomeInfo(
)

class RecentFiveDiary(
val diaryId: Int,
val content: String,
val diaryEntryDate: String,
val emotion: String
val emotion: String,
val isBookmarked: Boolean
)
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,7 @@ interface DiaryRepository {
suspend fun updateDiary(
accessToken: String,
id: Int,
content: String
content: String,
diaryEntryDate: String
): Result<UpdateDiaryInfo>
}
Original file line number Diff line number Diff line change
Expand Up @@ -7,8 +7,9 @@ class UpdateDiaryUseCase(private val repository: DiaryRepository) {
suspend operator fun invoke(
accessToken: String,
id: Int,
content: String
content: String,
diaryEntryDate: String
): Result<UpdateDiaryInfo> {
return repository.updateDiary("Bearer $accessToken", id, content)
return repository.updateDiary("Bearer $accessToken", id, content, diaryEntryDate)
}
}
3 changes: 3 additions & 0 deletions Nabi/presentation/build.gradle.kts
Original file line number Diff line number Diff line change
Expand Up @@ -128,4 +128,7 @@ dependencies {

// LoggerUtils
implementation(libs.logger)

// ReadMoreView
implementation("com.github.jeonjungin:ReadMoreView:v1.0.4")
}
1 change: 1 addition & 0 deletions Nabi/presentation/src/main/AndroidManifest.xml
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@

<uses-permission android:name="android.permission.INTERNET"/>
<uses-permission android:name="android.permission.POST_NOTIFICATIONS"/>
<uses-permission android:name="android.permission.RECORD_AUDIO" />

<application
android:name=".base.NabiApplication"
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -47,7 +47,7 @@ abstract class BaseActivity<T: ViewDataBinding>(@LayoutRes private val layoutId:


// Permission
protected fun checkPermissions(permissions: Array<String>): Boolean {
fun checkPermissions(permissions: Array<String>): Boolean {
setPermissionLauncher()

for(permission in permissions){
Expand Down Expand Up @@ -102,7 +102,7 @@ abstract class BaseActivity<T: ViewDataBinding>(@LayoutRes private val layoutId:
// }.show(requireActivity().supportFragmentManager, "")
}

protected fun requestPermissions(permissions: Array<String>){
fun requestPermissions(permissions: Array<String>){
val permissionsToRequest = permissions.filter {
ContextCompat.checkSelfPermission(this, it) != PackageManager.PERMISSION_GRANTED
}.toTypedArray()
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -3,9 +3,11 @@ package com.nabi.nabi.utils
import android.os.Build

object Constants {
val FCM_PERMISSIONS = if(Build.VERSION.SDK_INT >= Build.VERSION_CODES.TIRAMISU) {
val FCM_PERMISSIONS = if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.TIRAMISU) {
arrayOf(android.Manifest.permission.POST_NOTIFICATIONS)
} else {
emptyArray()
}

val AUDIO_PERMISSIONS = arrayOf(android.Manifest.permission.RECORD_AUDIO)
}
Original file line number Diff line number Diff line change
@@ -1,48 +1,85 @@
package com.nabi.nabi.views.diary.add

import androidx.fragment.app.activityViewModels
import android.Manifest
import android.annotation.SuppressLint
import android.content.Intent
import android.content.pm.PackageManager
import android.os.Build
import android.os.Bundle
import android.speech.RecognitionListener
import android.speech.RecognizerIntent
import android.speech.SpeechRecognizer
import android.widget.Toast
import androidx.core.app.ActivityCompat
import androidx.core.content.ContextCompat
import androidx.fragment.app.viewModels
import com.nabi.nabi.R
import com.nabi.nabi.base.BaseActivity
import com.nabi.nabi.base.BaseFragment
import com.nabi.nabi.databinding.ActivityMainBinding
import com.nabi.nabi.databinding.FragmentAddDiaryBinding
import com.nabi.nabi.utils.Constants
import com.nabi.nabi.utils.LoggerUtils
import com.nabi.nabi.utils.UiState
import com.nabi.nabi.views.MainActivity
import dagger.hilt.android.AndroidEntryPoint
import java.time.LocalDate
import java.time.format.DateTimeFormatter

@AndroidEntryPoint
class AddDiaryFragment : BaseFragment<FragmentAddDiaryBinding>(R.layout.fragment_add_diary) {
private val viewModel: AddDiaryViewModel by activityViewModels()
class AddDiaryFragment(
private val isEdit: Boolean,
private val diaryId: Int? = null,
private val content: String? = null,
private val diaryDate: String,
) : BaseFragment<FragmentAddDiaryBinding>(R.layout.fragment_add_diary) {
private val viewModel: AddDiaryViewModel by viewModels()
private lateinit var speechRecognizer: SpeechRecognizer

override fun initView() {
viewModel.selectedDate.observe(viewLifecycleOwner) { date ->
binding.tvDiaryDate.text = date.toString()
binding.tvDiaryDate.text = diaryDate
if (isEdit) {
binding.etDiary.setText(content)
}
}

override fun initListener() {
super.initListener()

binding.ibBack.setOnClickListener {
(requireActivity() as MainActivity).replaceFragment(AddDiarySelectDateFragment(), false)
requireActivity().supportFragmentManager.popBackStack()
}

// RecognizerIntent 생성
val intent = Intent(RecognizerIntent.ACTION_RECOGNIZE_SPEECH)
intent.putExtra(RecognizerIntent.EXTRA_CALLING_PACKAGE, "Nabi") // 여분의 키
intent.putExtra(RecognizerIntent.EXTRA_LANGUAGE, "ko-KR") // 언어 설정

binding.ibMic.setOnClickListener {
// mic 버튼 눌렀을 때 로직
if (!(requireActivity() as BaseActivity<*>).checkPermissions(Constants.AUDIO_PERMISSIONS)) {
(requireActivity() as BaseActivity<*>).requestPermissions(Constants.AUDIO_PERMISSIONS)
} else {
// mic 버튼 눌렀을 때 로직
speechRecognizer = SpeechRecognizer.createSpeechRecognizer(requireContext())
speechRecognizer.setRecognitionListener(recognitionListener) // 리스너 설정
speechRecognizer.startListening(intent) // 듣기 시작
}
}

binding.btnAddDiary.setOnClickListener {
val content = binding.etDiary.text.toString().trim()
val selectedDate = viewModel.selectedDate.value.orEmpty()

if (content.isNotEmpty()) {
val inputFormatter = DateTimeFormatter.ofPattern("yyyy년 M월 d일")
val outputFormatter = DateTimeFormatter.ofPattern("yyyy-MM-dd")

val date = LocalDate.parse(selectedDate, inputFormatter)
val date = LocalDate.parse(diaryDate, inputFormatter)
val diaryEntryDate = date.format(outputFormatter)
LoggerUtils.d(diaryEntryDate)
viewModel.addDiary(content, diaryEntryDate)
if (isEdit) {
viewModel.updateDiary(diaryId!!, content, diaryEntryDate)
} else {
viewModel.addDiary(content, diaryEntryDate)
}
} else {
showToast("일기 내용을 입력해주세요")
}
Expand Down Expand Up @@ -78,4 +115,59 @@ class AddDiaryFragment : BaseFragment<FragmentAddDiaryBinding>(R.layout.fragment
}
}
}

private val recognitionListener: RecognitionListener = object : RecognitionListener {
// 말하기 시작할 준비가되면 호출
override fun onReadyForSpeech(params: Bundle) {
Toast.makeText(requireContext(), "음성인식 시작", Toast.LENGTH_SHORT).show()
}

// 말하기 시작했을 때 호출
override fun onBeginningOfSpeech() {
}

// 입력받는 소리의 크기를 알려줌
override fun onRmsChanged(rmsdB: Float) {}

// 말을 시작하고 인식이 된 단어를 buffer에 담음
override fun onBufferReceived(buffer: ByteArray) {}

// 말하기를 중지하면 호출
override fun onEndOfSpeech() {
}

// 오류 발생했을 때 호출
override fun onError(error: Int) {
val message = when (error) {
SpeechRecognizer.ERROR_AUDIO -> "오디오 에러"
SpeechRecognizer.ERROR_CLIENT -> "클라이언트 에러"
SpeechRecognizer.ERROR_INSUFFICIENT_PERMISSIONS -> "퍼미션 없음"
SpeechRecognizer.ERROR_NETWORK -> "네트워크 에러"
SpeechRecognizer.ERROR_NETWORK_TIMEOUT -> "네트웍 타임아웃"
SpeechRecognizer.ERROR_NO_MATCH -> "찾을 수 없음"
SpeechRecognizer.ERROR_RECOGNIZER_BUSY -> "RECOGNIZER 가 바쁨"
SpeechRecognizer.ERROR_SERVER -> "서버가 이상함"
SpeechRecognizer.ERROR_SPEECH_TIMEOUT -> "말하는 시간초과"
else -> "알 수 없는 오류임"
}
}

// 인식 결과가 준비되면 호출
override fun onResults(results: Bundle) {
// 말을 하면 ArrayList에 단어를 넣고 textView에 단어를 이어줌
val matches = results.getStringArrayList(SpeechRecognizer.RESULTS_RECOGNITION)
if (matches != null) {
// 모든 인식된 단어를 공백으로 구분하여 결합
val resultText = matches.joinToString(separator = " ")
// EditText에 결합된 텍스트 설정
binding.etDiary.setText(resultText)
}
}

// 부분 인식 결과를 사용할 수 있을 때 호출
override fun onPartialResults(partialResults: Bundle) {}

// 향후 이벤트를 추가하기 위해 예약
override fun onEvent(eventType: Int, params: Bundle) {}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@ package com.nabi.nabi.views.diary.add

import android.annotation.SuppressLint
import androidx.fragment.app.activityViewModels
import androidx.fragment.app.viewModels
import androidx.recyclerview.widget.LinearLayoutManager
import com.nabi.nabi.utils.LoggerUtils
import com.nabi.nabi.R
Expand All @@ -21,7 +22,7 @@ class AddDiarySelectDateFragment :
AddDiaryMonthAdapter.OnDateSelectedListener {
private lateinit var monthAdapter: AddDiaryMonthAdapter
private lateinit var monthListManager: LinearLayoutManager
private val viewModel: AddDiaryViewModel by activityViewModels()
private val viewModel: AddDiarySelectDateViewModel by viewModels()
private val calendar = Calendar.getInstance()
private var diaryDates: Set<String> = emptySet()

Expand All @@ -41,13 +42,23 @@ class AddDiarySelectDateFragment :
}

binding.btnDone.setOnClickListener {
val selectedDate = changeDateFormat(binding.tvSelectDate.text.toString())
val originalFormat = SimpleDateFormat("yyyy년 M월 d일", Locale.KOREAN)
val targetFormat = SimpleDateFormat("yyyy-MM-dd", Locale.KOREAN)
val originalDateStr = binding.tvSelectDate.text.toString()
val date: Date? = originalFormat.parse(originalDateStr)
val selectedDate = date?.let { targetFormat.format(it) }

if (diaryDates.contains(selectedDate)) {
showToast("이미 일기를 쓴 날이에요!")
} else {
viewModel.selectDate(selectedDate)
(requireActivity() as MainActivity).replaceFragment(AddDiaryFragment(), true)
(requireActivity() as MainActivity).replaceFragment(
AddDiaryFragment(
false,
null,
null,
selectedDate!!
), true
)
}
}

Expand Down Expand Up @@ -124,11 +135,4 @@ class AddDiarySelectDateFragment :
}
}
}

private fun changeDateFormat(selectedDate: String): String {
val inputFormat = SimpleDateFormat("yyyy년 M월 d일", Locale.KOREAN)
val outputFormat = SimpleDateFormat("yyyy-MM-dd", Locale.KOREAN)
val date = inputFormat.parse(selectedDate)
return outputFormat.format(date!!)
}
}
Loading