Skip to content

Commit

Permalink
feat: 로그인 화면 구현
Browse files Browse the repository at this point in the history
  • Loading branch information
hyeonhh committed Nov 23, 2024
1 parent 90531d1 commit 48d2221
Show file tree
Hide file tree
Showing 11 changed files with 194 additions and 49 deletions.
7 changes: 6 additions & 1 deletion app/src/main/AndroidManifest.xml
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,10 @@
android:supportsRtl="true"
android:theme="@style/Theme.Comus"
tools:targetApi="31">
<activity android:name=".ui.login.LoginActivity"
android:exported="true">

</activity>
<activity
android:name=".ui.question.previous.PreviousAnswerActivity"
android:exported="false" />
Expand All @@ -39,12 +43,13 @@
android:name=".MainActivity"
android:exported="true"
android:label="@string/app_name" >

<intent-filter>
<action android:name="android.intent.action.MAIN" />

<category android:name="android.intent.category.LAUNCHER" />
</intent-filter>


</activity>
</application>

Expand Down
63 changes: 41 additions & 22 deletions app/src/main/java/com/example/com_us/ui/home/HomeFragment.kt
Original file line number Diff line number Diff line change
Expand Up @@ -6,24 +6,30 @@ 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
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<List<View>>

Expand Down Expand Up @@ -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()
Expand Down Expand Up @@ -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) {
Expand Down Expand Up @@ -190,10 +215,4 @@ class HomeFragment : Fragment(), View.OnClickListener, ServerResponseHandler {
_binding = null
}

override fun onServerSuccess() {
binding.constraintHome.visibility = View.VISIBLE
}

override fun onServerFailure() {
}
}
23 changes: 17 additions & 6 deletions app/src/main/java/com/example/com_us/ui/home/HomeViewModel.kt
Original file line number Diff line number Diff line change
Expand Up @@ -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<ResponseHomeDataDto>()
val homeData: LiveData<ResponseHomeDataDto> = _homeData
private val _homeUiState= MutableStateFlow<ApiResult<ResponseHomeDataDto>>(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)
}
}
}
Expand Down
19 changes: 19 additions & 0 deletions app/src/main/java/com/example/com_us/ui/login/LoginActivity.kt
Original file line number Diff line number Diff line change
@@ -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)

}
}
Original file line number Diff line number Diff line change
Expand Up @@ -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 -> {}
}
}
}
Expand Down
Original file line number Diff line number Diff line change
@@ -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
Expand All @@ -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)
}
Expand All @@ -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() {
Expand Down Expand Up @@ -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)

// 다이얼로그가 뜨면 아래 내용 질문만 희미하게 보이게 하기
Expand All @@ -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")
}


Expand Down
Original file line number Diff line number Diff line change
@@ -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

Expand All @@ -16,15 +20,15 @@ class ResultViewModel @Inject constructor(
private val questionRepository : QuestionRepository
) : ViewModel() {

private val _answerDetail = MutableLiveData<List<ResponseAnswerDetailDto>>()
val answerDetail: LiveData<List<ResponseAnswerDetailDto>> = _answerDetail
private val _answerDetail = MutableStateFlow<ApiResult<List<ResponseAnswerDetailDto>>>(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())
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -60,9 +60,10 @@ class ThemeQuestionListActivity : AppCompatActivity() {
}
}
}
else -> {
is ApiResult.Error -> {
Toast.makeText(this@ThemeQuestionListActivity,it.toString(),Toast.LENGTH_SHORT).show()
}
else -> {}
}
}
}
Expand Down
Binary file added app/src/main/res/drawable/btn_google_login.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
12 changes: 12 additions & 0 deletions app/src/main/res/drawable/ic_logo.xml
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
<vector xmlns:android="http://schemas.android.com/apk/res/android"
android:width="158dp"
android:height="47dp"
android:viewportWidth="158"
android:viewportHeight="47">
<path
android:pathData="M0,0h158v47h-158z"
android:fillColor="#00A3E8"/>
<path
android:pathData="M29.59,32.12C26.17,32.12 23.5,31.39 21.59,29.92C19.69,28.45 18.73,26.39 18.73,23.72C18.73,21.06 19.69,18.99 21.59,17.52C23.5,16.06 26.17,15.32 29.59,15.32C32.67,15.32 35.13,15.91 36.97,17.1C38.83,18.28 39.95,19.97 40.33,22.16H34.84C34.43,21.39 33.76,20.79 32.83,20.36C31.92,19.92 30.84,19.7 29.59,19.7C28,19.7 26.66,20.05 25.59,20.76C24.54,21.47 24.01,22.46 24.01,23.72C24.01,24.97 24.54,25.95 25.59,26.68C26.66,27.39 28,27.74 29.59,27.74C30.84,27.74 31.92,27.53 32.83,27.1C33.76,26.66 34.43,26.05 34.84,25.28H40.33C39.95,27.47 38.83,29.16 36.97,30.34C35.13,31.53 32.67,32.12 29.59,32.12ZM52.11,32.12C48.69,32.12 46.03,31.39 44.12,29.92C42.21,28.45 41.26,26.39 41.26,23.72C41.26,21.06 42.21,18.99 44.12,17.52C46.03,16.06 48.69,15.32 52.11,15.32C55.55,15.32 58.22,16.06 60.13,17.52C62.04,18.99 62.99,21.06 62.99,23.72C62.99,26.39 62.04,28.45 60.13,29.92C58.22,31.39 55.55,32.12 52.11,32.12ZM52.11,27.74C53.72,27.74 55.05,27.39 56.11,26.68C57.18,25.95 57.72,24.97 57.72,23.72C57.72,22.46 57.18,21.47 56.11,20.76C55.05,20.05 53.72,19.7 52.11,19.7C50.52,19.7 49.19,20.05 48.12,20.76C47.06,21.47 46.53,22.46 46.53,23.72C46.53,24.97 47.06,25.95 48.12,26.68C49.19,27.39 50.52,27.74 52.11,27.74ZM86.71,32H81.53V24.62L77.77,32H73.11L69.37,24.62V32H64.19V15.44H69.58L75.45,26.65L81.31,15.44H86.71V32ZM99.1,25.28H88.24V21.14H99.1V25.28ZM109.93,32.35C106.98,32.35 104.68,31.69 103.03,30.37C101.39,29.03 100.57,27.13 100.57,24.67V15.44H105.75V24.67C105.75,25.68 106.09,26.47 106.79,27.06C107.5,27.62 108.54,27.91 109.93,27.91C111.31,27.91 112.35,27.62 113.06,27.06C113.76,26.47 114.12,25.68 114.12,24.67V15.44H119.3V24.67C119.3,27.13 118.47,29.03 116.82,30.37C115.18,31.69 112.88,32.35 109.93,32.35ZM129.59,32.12C126.85,32.12 124.7,31.64 123.14,30.68C121.59,29.71 120.82,28.37 120.82,26.65H126.09C126.09,26.97 126.42,27.23 127.09,27.43C127.76,27.64 128.69,27.74 129.85,27.74C131.94,27.74 132.98,27.49 132.98,26.99C132.98,26.84 132.91,26.72 132.76,26.63C132.62,26.52 132.34,26.42 131.91,26.32C131.36,26.2 130.18,26.03 128.39,25.83C125.94,25.54 124.08,24.98 122.81,24.15C121.54,23.31 120.91,22.09 120.91,20.48C120.91,18.89 121.66,17.63 123.16,16.72C124.67,15.79 126.79,15.32 129.52,15.32C132.27,15.32 134.39,15.81 135.89,16.79C137.4,17.77 138.16,19.1 138.16,20.79H132.86C132.86,20.47 132.54,20.21 131.91,20.01C131.3,19.8 130.4,19.7 129.21,19.7C127.26,19.7 126.26,19.96 126.21,20.48C126.21,20.73 126.41,20.92 126.8,21.05C127.2,21.17 127.95,21.3 129.05,21.43L130.68,21.62C133.13,21.9 134.99,22.46 136.29,23.29C137.6,24.13 138.25,25.35 138.25,26.96C138.25,28.52 137.49,29.78 135.98,30.72C134.47,31.65 132.34,32.12 129.59,32.12Z"
android:fillColor="#ffffff"/>
</vector>
Loading

0 comments on commit 48d2221

Please sign in to comment.