Skip to content

Commit

Permalink
feat: 답변 따라하기 로직 구현
Browse files Browse the repository at this point in the history
- UiState 적용
- 답변 따라하기 로직 구현
  • Loading branch information
hyeonhh committed Nov 22, 2024
1 parent 3b8c592 commit b7127df
Show file tree
Hide file tree
Showing 17 changed files with 268 additions and 179 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,7 @@ sealed class NetworkError : Exception(){
) : NetworkError()

data class NetworkException(
override val cause : Throwable
override val cause : Throwable,
) : NetworkError()

data class NullDataError(
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -5,11 +5,11 @@ import kotlinx.serialization.Serializable
@Serializable
data class ResponseAnswerDetailDto(
@SerialName("id")
val id: Long,
val id: Long=0L,
@SerialName("signLanguageName")
val signLanguageName: String,
val signLanguageName: String = "",
@SerialName("signLanguageVideoUrl")
val signLanguageVideoUrl: String,
val signLanguageVideoUrl: String = "",
@SerialName("signLanguageDescription")
val signLanguageDescription: String,
val signLanguageDescription: String = "",
)
9 changes: 9 additions & 0 deletions app/src/main/java/com/example/com_us/ui/UiState.kt
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
package com.example.com_us.ui


// 성공 / 실패에 따른 UI 처리
sealed class UiState<out T> {
data object Initial : UiState<Nothing>()
data class Success<T>(val data : T) : UiState<T>()
data class Error(val message : String) : UiState<Nothing>()
}
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@ import androidx.appcompat.app.AppCompatActivity
import android.os.Bundle
import android.os.Handler
import androidx.activity.OnBackPressedCallback
import com.example.com_us.MainActivity
import com.example.com_us.databinding.ActivityQuestionCollectBlockBinding
import com.example.com_us.ui.question.result.ResultAfterSignActivity
import com.example.com_us.util.ThemeType
Expand All @@ -20,20 +21,20 @@ class CollectBlockActivity : AppCompatActivity() {
super.onCreate(savedInstanceState)
binding = ActivityQuestionCollectBlockBinding.inflate(layoutInflater)
setContentView(binding.root)

category = intent.getStringExtra("category").toString()

if(!category.isNullOrEmpty()){
if(category.isNotEmpty()){
setTheme()
}

controlBackButton()

Handler().postDelayed({
val intent = Intent(this, ResultAfterSignActivity::class.java)
intent.putExtra("category",category)
startActivity(intent)
finish()
}, 1500) // 3초
}, 3000) // 3초
}

private fun setTheme() {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -14,22 +14,25 @@ import androidx.compose.ui.platform.ViewCompositionStrategy
import androidx.core.content.ContextCompat
import androidx.fragment.app.Fragment
import androidx.fragment.app.viewModels
import androidx.lifecycle.Lifecycle
import androidx.lifecycle.lifecycleScope
import androidx.lifecycle.repeatOnLifecycle
import com.example.com_us.R
import com.example.com_us.databinding.FragmentQuestionBinding
import com.example.com_us.ui.UiState
import com.example.com_us.ui.compose.QuestionListItem
import com.example.com_us.ui.question.select.SelectAnswerActivity
import com.example.com_us.util.ThemeType
import dagger.hilt.android.AndroidEntryPoint
import kotlinx.coroutines.launch

// 바텀 네비게이션바에서 햄버거 버튼 클릭 시 이동하는 질문 리스트 화면
@AndroidEntryPoint
class AllQuestionListFragment : Fragment(), View.OnClickListener {

private var _binding: FragmentQuestionBinding? = null
private val binding get() = _binding!!

private val viewModel: AllQuestionListViewModel by viewModels()

private var lastSelectedView: TextView? = null
private lateinit var selectedView:TextView
private lateinit var themeKor:String
Expand Down Expand Up @@ -68,31 +71,41 @@ class AllQuestionListFragment : Fragment(), View.OnClickListener {
// 각 질문을 담을 아이템
private fun setComposeList() {
// 데이터 리스트
viewModel.questionListByCate.observe(viewLifecycleOwner) {
if (it.isNotEmpty()) {
setThemeSelected()
binding.constraintQuestion.visibility = View.VISIBLE
binding.textviewQuestionCount.text = String.format(
resources.getString(R.string.question_title_question_count),
it.size
)
binding.composeviewQuestion.apply {
setViewCompositionStrategy(ViewCompositionStrategy.DisposeOnViewTreeLifecycleDestroyed)
setContent {
LazyColumn(modifier = Modifier.fillMaxSize()) {
items(it.size) { idx ->
QuestionListItem(
data = it[idx],
onClick = { movieToSelectAnswer(it[idx].id) })
lifecycleScope.launch {
repeatOnLifecycle(Lifecycle.State.STARTED){
viewModel.uiState.collect {
when(it) {
is UiState.Success -> {
if (it.data.isNotEmpty()) {
setThemeSelected()
binding.constraintQuestion.visibility = View.VISIBLE
binding.textviewQuestionCount.text = String.format(
resources.getString(R.string.question_title_question_count),
it.data.size
)
binding.composeviewQuestion.apply {
setViewCompositionStrategy(ViewCompositionStrategy.DisposeOnViewTreeLifecycleDestroyed)
setContent {
LazyColumn(modifier = Modifier.fillMaxSize()) {
items(it.data.size) { idx ->
QuestionListItem(
data = it.data[idx],
onClick = { movieToSelectAnswer(it.data[idx].id) })
}
}
}
}
}
}
else -> {
binding.constraintQuestion.visibility = View.GONE
Toast.makeText(context, it.toString(), Toast.LENGTH_SHORT).show()
}
}
}
}
else {
Toast.makeText(context,"질문을 준비중이에요!",Toast.LENGTH_SHORT).show()
}
}

}

private fun setThemeClickListener(){
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -6,15 +6,19 @@ import androidx.lifecycle.ViewModel
import androidx.lifecycle.viewModelScope
import com.example.com_us.R
import com.example.com_us.data.default_repository.NetworkError
import com.example.com_us.data.model.home.ResponseHomeDataDto
import com.example.com_us.data.model.question.response.question.ResponseAnswerDetailWithDateDto
import com.example.com_us.data.model.question.response.question.ResponseQuestionDto
import com.example.com_us.data.repository.QuestionRepository
import com.example.com_us.ui.question.sign.QuestionUiState
import com.example.com_us.ui.UiState
import dagger.hilt.android.lifecycle.HiltViewModel
import kotlinx.coroutines.flow.MutableStateFlow
import kotlinx.coroutines.flow.StateFlow
import kotlinx.coroutines.flow.asStateFlow
import kotlinx.coroutines.launch
import javax.inject.Inject


@HiltViewModel
class AllQuestionListViewModel @Inject constructor(
private val questionRepository: QuestionRepository
Expand All @@ -30,8 +34,8 @@ class AllQuestionListViewModel @Inject constructor(


// ui 상태 변수
private val _uiState = MutableStateFlow<QuestionUiState>(QuestionUiState.Initial)
val uiState: StateFlow<QuestionUiState> = _uiState
private val _uiState = MutableStateFlow<UiState<List<ResponseQuestionDto>>>(UiState.Initial)
val uiState = _uiState.asStateFlow()


// 선택한 테마의 id
Expand All @@ -51,10 +55,8 @@ class AllQuestionListViewModel @Inject constructor(
fun loadQuestionListByCate(category: String){
viewModelScope.launch {
questionRepository.getQuestionListByCate(category)

.onSuccess {
_uiState.value = QuestionUiState.Success(it)
_questionListByCate.value = it
_uiState.value = UiState.Success(it)
}
.onFailure {
val errorMessage = when(it){
Expand All @@ -63,7 +65,7 @@ class AllQuestionListViewModel @Inject constructor(
else -> "알 수 없는 에러가 발생했습니다. 다시 시도해주세요!"
}
if (errorMessage != null) {
_uiState.value = QuestionUiState.Error(errorMessage)
_uiState.value = UiState.Error(errorMessage)
} }
}
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -3,18 +3,24 @@ package com.example.com_us.ui.question.previous
import androidx.appcompat.app.AppCompatActivity
import android.os.Bundle
import android.view.MenuItem
import android.widget.Toast
import androidx.activity.viewModels
import androidx.compose.foundation.layout.Row
import androidx.compose.foundation.lazy.grid.GridCells
import androidx.compose.foundation.lazy.grid.LazyVerticalGrid
import androidx.compose.ui.platform.ViewCompositionStrategy
import androidx.lifecycle.Lifecycle
import androidx.lifecycle.lifecycleScope
import androidx.lifecycle.repeatOnLifecycle
import com.example.com_us.R
import com.example.com_us.data.model.question.response.question.Answer
import com.example.com_us.databinding.ActivityQuestionPreviousAnswerBinding
import com.example.com_us.ui.UiState
import com.example.com_us.ui.compose.AnswerHistoryItem
import com.example.com_us.ui.compose.AnswerTypeTag
import com.example.com_us.util.ColorMatch
import dagger.hilt.android.AndroidEntryPoint
import kotlinx.coroutines.launch

// 이전 답변을 보여주는 화면
@AndroidEntryPoint
Expand All @@ -38,11 +44,23 @@ class PreviousAnswerActivity : AppCompatActivity() {
println(questionId)
if(questionId > -1) viewModel.loadPreviousAnswer(questionId)

viewModel.answerPrevious.observe(this) {
setQuestion(it.question.questionCount, it.question.questionContent)
setQuestionTypeCompose(it.question.category, it.question.answerType)
setComposeList(it.answerList)
}
lifecycleScope.launch {
repeatOnLifecycle(Lifecycle.State.STARTED){
viewModel.uiState.collect{
when(it){
is UiState.Success -> {
setQuestion(it.data.question.questionCount, it.data.question.questionContent)
setQuestionTypeCompose(it.data.question.category, it.data.question.answerType)
setComposeList(it.data.answerList)
}
else ->
Toast.makeText(this@PreviousAnswerActivity, it.toString(), Toast.LENGTH_SHORT).show()

}
}

}
}
}

private fun setActionBar() {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -5,28 +5,49 @@ import androidx.lifecycle.LiveData
import androidx.lifecycle.MutableLiveData
import androidx.lifecycle.ViewModel
import androidx.lifecycle.viewModelScope
import com.example.com_us.data.default_repository.NetworkError
import com.example.com_us.data.model.question.response.question.ResponseAnswerDetailDto
import com.example.com_us.data.model.question.response.question.ResponsePreviousAnswerDto
import com.example.com_us.data.model.question.response.question.ResponseQuestionDto
import com.example.com_us.data.repository.QuestionRepository
import com.example.com_us.ui.UiState
import dagger.hilt.android.lifecycle.HiltViewModel
import kotlinx.coroutines.flow.MutableStateFlow
import kotlinx.coroutines.flow.StateFlow
import kotlinx.coroutines.flow.asStateFlow
import kotlinx.coroutines.launch
import okhttp3.Response
import javax.inject.Inject



@HiltViewModel
class PreviousAnswerViewModel @Inject constructor(
private val questionRepository: QuestionRepository
) : ViewModel(){

// ui 상태 변수
private val _uiState = MutableStateFlow<UiState<ResponsePreviousAnswerDto>>(UiState.Initial)
val uiState= _uiState.asStateFlow()

private val _answerPrevious = MutableLiveData<ResponsePreviousAnswerDto>()
val answerPrevious: LiveData<ResponsePreviousAnswerDto> = _answerPrevious

fun loadPreviousAnswer(questionId: Long) {
viewModelScope.launch {
questionRepository.getPreviousAnswer(questionId)
.onSuccess {
_answerPrevious.value = it
_uiState.value = UiState.Success(it)
}
.onFailure {
Log.d("GET: [ANSWER DETAIL]", it.toString())
val errorMessage = when(it){
is NetworkError.NetworkException -> {it.message}
is NetworkError.NullDataError -> "데이터가 없어요"
else -> "알 수 없는 에러가 발생했어요. 다시 시도해주세요!"
}
if (errorMessage != null) {
_uiState.value = UiState.Error(errorMessage)
}
}
}
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@ import com.example.com_us.MainActivity
import com.example.com_us.R
import com.example.com_us.data.model.question.response.question.ResponseAnswerDetailDto
import com.example.com_us.databinding.ActivityQuestionResultBinding
import com.example.com_us.ui.question.block.CollectBlockActivity
import com.example.com_us.util.QuestionManager
import dagger.hilt.android.AndroidEntryPoint

Expand All @@ -18,6 +19,7 @@ import dagger.hilt.android.AndroidEntryPoint
class ResultAfterSignActivity : AppCompatActivity() {

private lateinit var binding: ActivityQuestionResultBinding
private lateinit var category : String

private var videoPlayCount: MutableLiveData<Int> = MutableLiveData(0)

Expand All @@ -35,6 +37,7 @@ class ResultAfterSignActivity : AppCompatActivity() {
if(!QuestionManager.answerDate.isNullOrEmpty()) {
binding.textviewResultDate.text = QuestionManager.answerDate
}
category = intent.getStringExtra("category").toString()

setActionBar()
setCompleteButton()
Expand Down Expand Up @@ -91,7 +94,8 @@ class ResultAfterSignActivity : AppCompatActivity() {
private fun setCompleteButton() {
binding.buttonResultComplete.setOnClickListener{
QuestionManager.reset()
val intent = Intent(this, MainActivity::class.java)
// 메인 화면으로 이동
val intent = Intent(this,MainActivity::class.java)
startActivity(intent)
finish()
}
Expand Down
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
package com.example.com_us.ui.question.result

import android.content.Intent
import android.net.Uri
import android.os.Bundle
import android.view.MenuItem
Expand All @@ -16,7 +17,7 @@ import dagger.hilt.android.AndroidEntryPoint

// 답변 선택 시 처음으로 이동하는 화면 (질문, 답변 , 수형 영상, 따라해보기 버튼)
@AndroidEntryPoint
class ResultBeforeSignActivity : AppCompatActivity() {
class ResultBeforeSignActivity : AppCompatActivity(){

private lateinit var binding: ActivityQuestionCheckAnswerBinding
private val viewModel: ResultViewModel by viewModels()
Expand Down Expand Up @@ -106,7 +107,14 @@ class ResultBeforeSignActivity : AppCompatActivity() {
}
private fun moveToFollowAlongDialog() {
videoPlayCount.value = -1
val dialog = SignAnswerDialog.newInstance(question, answer, category)

viewModel.answerDetail.value
val dialog = viewModel.answerDetail.value?.let {
SignAnswerDialog.newInstance(question, answer, category,
it
)
}
print(viewModel.answerDetail.value)

// 다이얼로그가 뜨면 아래 내용 질문만 희미하게 보이게 하기
binding.textView8.visibility = View.GONE
Expand All @@ -115,11 +123,12 @@ class ResultBeforeSignActivity : AppCompatActivity() {
binding.textviewAnswerDescrp.visibility = View.GONE
binding.buttonAnswerFollowalong.visibility = View.GONE
binding.videoviewAnswerSign.visibility = View.GONE
dialog.isCancelable = false
dialog?.isCancelable = false

dialog.show(supportFragmentManager, "FollowAlongDialog")
dialog?.show(supportFragmentManager, "FollowAlongDialog")
}


// override fun onServerSuccess() {
// }
//
Expand Down
Loading

0 comments on commit b7127df

Please sign in to comment.