diff --git a/app/src/main/AndroidManifest.xml b/app/src/main/AndroidManifest.xml
index 373e249..bbd44e1 100644
--- a/app/src/main/AndroidManifest.xml
+++ b/app/src/main/AndroidManifest.xml
@@ -16,6 +16,10 @@
android:supportsRtl="true"
android:theme="@style/Theme.Comus"
tools:targetApi="31">
+
+
+
@@ -39,12 +43,13 @@
android:name=".MainActivity"
android:exported="true"
android:label="@string/app_name" >
-
+
+
diff --git a/app/src/main/java/com/example/com_us/ui/home/HomeFragment.kt b/app/src/main/java/com/example/com_us/ui/home/HomeFragment.kt
index 95b146b..145b3e2 100644
--- a/app/src/main/java/com/example/com_us/ui/home/HomeFragment.kt
+++ b/app/src/main/java/com/example/com_us/ui/home/HomeFragment.kt
@@ -6,9 +6,13 @@ import android.view.LayoutInflater
import android.view.View
import android.view.ViewGroup
import android.view.ViewTreeObserver
+import android.widget.Toast
import androidx.fragment.app.Fragment
import androidx.fragment.app.viewModels
+import androidx.lifecycle.Lifecycle
import androidx.lifecycle.MutableLiveData
+import androidx.lifecycle.lifecycleScope
+import androidx.lifecycle.repeatOnLifecycle
import com.bumptech.glide.Glide
import com.bumptech.glide.load.resource.bitmap.RoundedCorners
import com.bumptech.glide.request.RequestOptions
@@ -16,14 +20,16 @@ import com.example.com_us.R
import com.example.com_us.data.model.home.Block
import com.example.com_us.data.model.home.Category
import com.example.com_us.databinding.FragmentHomeBinding
+import com.example.com_us.ui.ApiResult
import com.example.com_us.ui.question.theme.ThemeQuestionListActivity
import com.example.com_us.util.ColorMatch
import com.example.com_us.util.ServerResponseHandler
import com.example.com_us.util.ThemeType
import dagger.hilt.android.AndroidEntryPoint
+import kotlinx.coroutines.launch
@AndroidEntryPoint
-class HomeFragment : Fragment(), View.OnClickListener, ServerResponseHandler {
+class HomeFragment : Fragment(), View.OnClickListener {
private lateinit var blockList: List>
@@ -55,9 +61,6 @@ class HomeFragment : Fragment(), View.OnClickListener, ServerResponseHandler {
listOf(binding.viewHomeBlock30, binding.viewHomeBlock31, binding.viewHomeBlock32, binding.viewHomeBlock33),
)
- homeViewModel.serverResponseHandler = this
- homeViewModel.loadHomeData()
-
setSwipeRefresh()
setThemeClickListener()
setHomeData()
@@ -91,19 +94,41 @@ class HomeFragment : Fragment(), View.OnClickListener, ServerResponseHandler {
private fun setHomeData() {
val emojiText = String(Character.toChars(resources.getInteger(R.integer.waving_hand_sign)))
- homeViewModel.homeData.observe(viewLifecycleOwner) {
- val chatMinute = it.user.todayChatTime.substring(3, 5).toInt()
- binding.textviewHomeGreeting.text = String.format(resources.getString(R.string.home_title_greeting_user_hi), it.user.name, emojiText)
- binding.textviewHomeMinute.text = String.format(resources.getString(R.string.home_sub_today_conversation_minute), chatMinute)
- Glide.with(this)
- .load(it.user.imageUrl)
- .apply(RequestOptions().transform(RoundedCorners(300)))
- .into(binding.imageviewHomeUsericon)
-
- setThemeProgress(it.category)
- setBlock(it.block)
- isReload.value = true
+ viewLifecycleOwner.lifecycleScope.launch {
+ repeatOnLifecycle(Lifecycle.State.STARTED) {
+ homeViewModel.homeUiState.collect {
+ when (it) {
+ is ApiResult.Success -> {
+ binding.constraintHome.visibility = View.VISIBLE
+ val chatMinute = it.data.user.todayChatTime.substring(3, 5).toInt()
+ binding.textviewHomeGreeting.text = String.format(
+ resources.getString(R.string.home_title_greeting_user_hi),
+ it.data.user.name,
+ emojiText
+ )
+ binding.textviewHomeMinute.text = String.format(
+ resources.getString(R.string.home_sub_today_conversation_minute),
+ chatMinute
+ )
+ Glide.with(this@HomeFragment)
+ .load(it.data.user.imageUrl)
+ .apply(RequestOptions().transform(RoundedCorners(300)))
+ .into(binding.imageviewHomeUsericon)
+
+ setThemeProgress(it.data.category)
+ setBlock(it.data.block)
+ isReload.value = true
+
+ }
+ is ApiResult.Error -> {
+ Toast.makeText(context,"잠시 후에 다시 시도해주세요!",Toast.LENGTH_SHORT).show()
+ }
+ else -> {}
+ }
+ }
+ }
}
+
}
override fun onClick(view: View) {
@@ -190,10 +215,4 @@ class HomeFragment : Fragment(), View.OnClickListener, ServerResponseHandler {
_binding = null
}
- override fun onServerSuccess() {
- binding.constraintHome.visibility = View.VISIBLE
- }
-
- override fun onServerFailure() {
- }
}
diff --git a/app/src/main/java/com/example/com_us/ui/home/HomeViewModel.kt b/app/src/main/java/com/example/com_us/ui/home/HomeViewModel.kt
index e6ba048..a68b046 100644
--- a/app/src/main/java/com/example/com_us/ui/home/HomeViewModel.kt
+++ b/app/src/main/java/com/example/com_us/ui/home/HomeViewModel.kt
@@ -5,30 +5,41 @@ 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.repository.HomeRepository
import com.example.com_us.data.model.home.ResponseHomeDataDto
+import com.example.com_us.ui.ApiResult
import com.example.com_us.util.ServerResponseHandler
import dagger.hilt.android.lifecycle.HiltViewModel
+import kotlinx.coroutines.flow.MutableStateFlow
+import kotlinx.coroutines.flow.asStateFlow
import kotlinx.coroutines.launch
import javax.inject.Inject
@HiltViewModel
class HomeViewModel @Inject constructor(private val homeRepository: HomeRepository) : ViewModel() {
- private val _homeData = MutableLiveData()
- val homeData: LiveData = _homeData
+ private val _homeUiState= MutableStateFlow>(ApiResult.Initial)
+ val homeUiState = _homeUiState.asStateFlow()
var serverResponseHandler: ServerResponseHandler? = null
+ init {
+ loadHomeData()
+ }
+
fun loadHomeData(){
viewModelScope.launch {
homeRepository.getHomeData()
.onSuccess {
- _homeData.value = it
- serverResponseHandler?.onServerSuccess()
+ _homeUiState.value = ApiResult.Success(it)
}
.onFailure {
- Log.d("GET: [HOME DATA] DATA FAILURE", it.toString())
- serverResponseHandler?.onServerFailure()
+ val errorMessage = when(it) {
+ is NetworkError.NetworkException -> { it.message }
+ is NetworkError.NullDataError -> { "데이터가 준비중이에요!" }
+ else -> "알 수 없는 에러가 발생했습니다. 다시 시도해주세요!"
+ }
+ if (errorMessage!= null ) _homeUiState.value = ApiResult.Error(errorMessage)
}
}
}
diff --git a/app/src/main/java/com/example/com_us/ui/login/LoginActivity.kt b/app/src/main/java/com/example/com_us/ui/login/LoginActivity.kt
new file mode 100644
index 0000000..1cf1f4b
--- /dev/null
+++ b/app/src/main/java/com/example/com_us/ui/login/LoginActivity.kt
@@ -0,0 +1,19 @@
+package com.example.com_us.ui.login
+
+import android.os.Bundle
+import androidx.appcompat.app.AppCompatActivity
+import com.example.com_us.databinding.ActivityLoginBinding
+import com.example.com_us.databinding.ActivityQuestionCheckAnswerBinding
+import dagger.hilt.android.AndroidEntryPoint
+
+@AndroidEntryPoint
+class LoginActivity : AppCompatActivity() {
+
+ private lateinit var binding: ActivityLoginBinding
+ override fun onCreate(savedInstanceState: Bundle?) {
+ super.onCreate(savedInstanceState)
+ binding = ActivityLoginBinding.inflate(layoutInflater)
+ setContentView(binding.root)
+
+ }
+}
\ No newline at end of file
diff --git a/app/src/main/java/com/example/com_us/ui/question/list/AllQuestionListFragment.kt b/app/src/main/java/com/example/com_us/ui/question/list/AllQuestionListFragment.kt
index f3cbe63..ca67618 100644
--- a/app/src/main/java/com/example/com_us/ui/question/list/AllQuestionListFragment.kt
+++ b/app/src/main/java/com/example/com_us/ui/question/list/AllQuestionListFragment.kt
@@ -97,10 +97,11 @@ class AllQuestionListFragment : Fragment(), View.OnClickListener {
}
}
}
- else -> {
+ is ApiResult.Error -> {
binding.constraintQuestion.visibility = View.GONE
Toast.makeText(context, it.toString(), Toast.LENGTH_SHORT).show()
}
+ else -> {}
}
}
}
diff --git a/app/src/main/java/com/example/com_us/ui/question/result/ResultBeforeSignActivity.kt b/app/src/main/java/com/example/com_us/ui/question/result/ResultBeforeSignActivity.kt
index 89296fb..8be505e 100644
--- a/app/src/main/java/com/example/com_us/ui/question/result/ResultBeforeSignActivity.kt
+++ b/app/src/main/java/com/example/com_us/ui/question/result/ResultBeforeSignActivity.kt
@@ -1,19 +1,24 @@
package com.example.com_us.ui.question.result
-import android.content.Intent
import android.net.Uri
import android.os.Bundle
import android.view.MenuItem
import android.view.View
+import android.widget.Toast
import androidx.activity.viewModels
import androidx.appcompat.app.AppCompatActivity
+import androidx.lifecycle.Lifecycle
import androidx.lifecycle.MutableLiveData
+import androidx.lifecycle.lifecycleScope
+import androidx.lifecycle.repeatOnLifecycle
import com.example.com_us.R
import com.example.com_us.data.model.question.response.question.ResponseAnswerDetailDto
import com.example.com_us.databinding.ActivityQuestionCheckAnswerBinding
+import com.example.com_us.ui.ApiResult
import com.example.com_us.ui.question.sign.SignAnswerDialog
import com.example.com_us.util.QuestionManager
import dagger.hilt.android.AndroidEntryPoint
+import kotlinx.coroutines.launch
// 답변 선택 시 처음으로 이동하는 화면 (질문, 답변 , 수형 영상, 따라해보기 버튼)
@AndroidEntryPoint
@@ -37,7 +42,7 @@ class ResultBeforeSignActivity : AppCompatActivity(){
question = intent.getStringExtra("question").toString()
category = intent.getStringExtra("category").toString()
- if(!answer.isNullOrEmpty()){
+ if (!answer.isNullOrEmpty()) {
QuestionManager.question = question
viewModel.loadAnswerDetail(answer)
}
@@ -46,16 +51,29 @@ class ResultBeforeSignActivity : AppCompatActivity(){
setContentView(binding.root)
setActionBar()
- viewModel.answerDetail.observe(this) {
- if(!it.isNullOrEmpty()){
- QuestionManager.signLanguageInfo = it
- signData = it
- setAnswerDetail()
- binding.buttonAnswerFollowalong.setOnClickListener {
- moveToFollowAlongDialog()
+
+ lifecycleScope.launch {
+ repeatOnLifecycle(Lifecycle.State.STARTED) {
+ viewModel.answerDetail.collect {
+ when (it) {
+ is ApiResult.Success -> {
+ QuestionManager.signLanguageInfo = it.data
+ signData = it.data
+ setAnswerDetail()
+ binding.buttonAnswerFollowalong.setOnClickListener {
+ moveToFollowAlongDialog()
+ }
+ }
+
+ is ApiResult.Error -> {
+ Toast.makeText(this@ResultBeforeSignActivity, it.toString(), Toast.LENGTH_SHORT).show()
+ }
+ else -> {}
+ }
}
}
}
+
}
private fun setActionBar() {
@@ -109,11 +127,23 @@ class ResultBeforeSignActivity : AppCompatActivity(){
videoPlayCount.value = -1
viewModel.answerDetail.value
- val dialog = viewModel.answerDetail.value?.let {
- SignAnswerDialog.newInstance(question, answer, category,
- it
- )
+ viewModel.answerDetail.value.let {
+ when(it) {
+ is ApiResult.Success -> {
+ val dialog =
+ SignAnswerDialog.newInstance(question, answer, category,
+ it.data
+ )
+ dialog.isCancelable = false
+ dialog.show(supportFragmentManager, "FollowAlongDialog")
+
+ }
+ else -> {
+ Toast.makeText(this , "잠시 후에 다시 시도해주세요",Toast.LENGTH_SHORT).show()
+ }
+ }
}
+
print(viewModel.answerDetail.value)
// 다이얼로그가 뜨면 아래 내용 질문만 희미하게 보이게 하기
@@ -123,9 +153,7 @@ class ResultBeforeSignActivity : AppCompatActivity(){
binding.textviewAnswerDescrp.visibility = View.GONE
binding.buttonAnswerFollowalong.visibility = View.GONE
binding.videoviewAnswerSign.visibility = View.GONE
- dialog?.isCancelable = false
- dialog?.show(supportFragmentManager, "FollowAlongDialog")
}
diff --git a/app/src/main/java/com/example/com_us/ui/question/result/ResultViewModel.kt b/app/src/main/java/com/example/com_us/ui/question/result/ResultViewModel.kt
index 5e8ba86..28a5628 100644
--- a/app/src/main/java/com/example/com_us/ui/question/result/ResultViewModel.kt
+++ b/app/src/main/java/com/example/com_us/ui/question/result/ResultViewModel.kt
@@ -1,13 +1,17 @@
package com.example.com_us.ui.question.result
import android.util.Log
+import androidx.compose.runtime.MutableState
import androidx.lifecycle.LiveData
import androidx.lifecycle.MutableLiveData
import androidx.lifecycle.ViewModel
import androidx.lifecycle.viewModelScope
import com.example.com_us.data.model.question.response.question.ResponseAnswerDetailDto
import com.example.com_us.data.repository.QuestionRepository
+import com.example.com_us.ui.ApiResult
import dagger.hilt.android.lifecycle.HiltViewModel
+import kotlinx.coroutines.flow.MutableStateFlow
+import kotlinx.coroutines.flow.asStateFlow
import kotlinx.coroutines.launch
import javax.inject.Inject
@@ -16,15 +20,15 @@ class ResultViewModel @Inject constructor(
private val questionRepository : QuestionRepository
) : ViewModel() {
- private val _answerDetail = MutableLiveData>()
- val answerDetail: LiveData> = _answerDetail
+ private val _answerDetail = MutableStateFlow>>(ApiResult.Initial)
+ val answerDetail =_answerDetail.asStateFlow()
fun loadAnswerDetail(answer: String){
viewModelScope.launch {
questionRepository.getAnswerDetail(answer)
.onSuccess {
- _answerDetail.value = it
+ _answerDetail.value = ApiResult.Success(it)
}
.onFailure {
Log.d("GET: [ANSWER DETAIL]", it.toString())
diff --git a/app/src/main/java/com/example/com_us/ui/question/theme/ThemeQuestionListActivity.kt b/app/src/main/java/com/example/com_us/ui/question/theme/ThemeQuestionListActivity.kt
index ae75a59..e658874 100644
--- a/app/src/main/java/com/example/com_us/ui/question/theme/ThemeQuestionListActivity.kt
+++ b/app/src/main/java/com/example/com_us/ui/question/theme/ThemeQuestionListActivity.kt
@@ -60,9 +60,10 @@ class ThemeQuestionListActivity : AppCompatActivity() {
}
}
}
- else -> {
+ is ApiResult.Error -> {
Toast.makeText(this@ThemeQuestionListActivity,it.toString(),Toast.LENGTH_SHORT).show()
}
+ else -> {}
}
}
}
diff --git a/app/src/main/res/drawable/btn_google_login.png b/app/src/main/res/drawable/btn_google_login.png
new file mode 100644
index 0000000..4f15111
Binary files /dev/null and b/app/src/main/res/drawable/btn_google_login.png differ
diff --git a/app/src/main/res/drawable/ic_logo.xml b/app/src/main/res/drawable/ic_logo.xml
new file mode 100644
index 0000000..862d47d
--- /dev/null
+++ b/app/src/main/res/drawable/ic_logo.xml
@@ -0,0 +1,12 @@
+
+
+
+
diff --git a/app/src/main/res/layout/activity_login.xml b/app/src/main/res/layout/activity_login.xml
new file mode 100644
index 0000000..281f59d
--- /dev/null
+++ b/app/src/main/res/layout/activity_login.xml
@@ -0,0 +1,45 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file