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/#75] 생성완료 뷰 / 완료 여부 서버통신 #76

Merged
merged 9 commits into from
Jul 18, 2024
Original file line number Diff line number Diff line change
Expand Up @@ -11,10 +11,13 @@ data class GenerateStatusDto(
val pictureGenerateRequestId: Long,
@SerialName("status")
val status: GenerateStatus,
@SerialName("pictureGenerateResponse")
val pictureGenerateResponse: ImageDto?,
) {
fun toModel() =
GenerateStatusModel(
pictureGenerateRequestId,
status,
pictureGenerateResponse?.toModel(),
)
}
Original file line number Diff line number Diff line change
Expand Up @@ -5,4 +5,5 @@ import kr.genti.domain.enums.GenerateStatus
data class GenerateStatusModel(
val pictureGenerateRequestId: Long,
val status: GenerateStatus,
val pictureGenerateResponse: ImageModel?,
)
Original file line number Diff line number Diff line change
@@ -1,12 +1,8 @@
package kr.genti.domain.enums

enum class GenerateStatus {
CREATED,
ASSIGNING,
IN_PROGRESS,
CANCELED,
REPORTED,
MATCH_TO_ADMIN,
AWAIT_USER_VERIFICATION,
COMPLETED,
ERROR,
}
Original file line number Diff line number Diff line change
@@ -1,45 +1,43 @@
package kr.genti.presentation.main

import android.os.Bundle
import androidx.activity.viewModels
import androidx.core.view.isVisible
import androidx.fragment.app.Fragment
import androidx.fragment.app.commit
import androidx.fragment.app.replace
import androidx.lifecycle.flowWithLifecycle
import androidx.lifecycle.lifecycleScope
import com.google.android.material.navigation.NavigationBarView
import dagger.hilt.android.AndroidEntryPoint
import kotlinx.coroutines.flow.launchIn
import kotlinx.coroutines.flow.onEach
import kr.genti.core.base.BaseActivity
import kr.genti.core.extension.setOnSingleClickListener
import kr.genti.core.extension.setStatusBarColorFromResource
import kr.genti.domain.enums.PictureRatio
import kr.genti.core.extension.stringOf
import kr.genti.core.extension.toast
import kr.genti.domain.enums.GenerateStatus
import kr.genti.presentation.R
import kr.genti.presentation.databinding.ActivityMainBinding
import kr.genti.presentation.main.create.CreateFragment
import kr.genti.presentation.main.feed.FeedFragment
import kr.genti.presentation.main.profile.ProfileFragment
import kr.genti.presentation.result.finished.FinishedActivity
import kr.genti.presentation.result.waiting.WaitingActivity

@AndroidEntryPoint
class MainActivity : BaseActivity<ActivityMainBinding>(R.layout.activity_main) {
private val viewModel by viewModels<MainViewModel>()

private var mainFinishedDialog: MainFinishedDialog? = null

override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)

initBnvItemIconTintList()
initBnvItemSelectedListener()
initCreateBtnListener()
setStatusBarColor()
moveToFinish()
}

// TODO 서버통신 진행 후 삭제
private fun moveToFinish() {
binding.btnMoveToFinish.setOnSingleClickListener {
FinishedActivity.createIntent(
this,
0,
"https://github.com/Marchbreeze/Marchbreeze/assets/97405341/ad58982b-9ba3-448d-a788-748511718ffe",
PictureRatio.RATIO_2_3.name,
).apply { startActivity(this) }
}
observeStatusResult()
}

fun initBnvItemIconTintList() {
Expand All @@ -60,7 +58,7 @@ class MainActivity : BaseActivity<ActivityMainBinding>(R.layout.activity_main) {
when (menu.itemId) {
R.id.menu_feed -> navigateTo<FeedFragment>()

R.id.menu_create -> navigateTo<CreateFragment>()
R.id.menu_create -> navigateByGenerateStatus()

R.id.menu_profile -> navigateTo<ProfileFragment>()

Expand All @@ -73,20 +71,60 @@ class MainActivity : BaseActivity<ActivityMainBinding>(R.layout.activity_main) {

private fun initCreateBtnListener() {
binding.btnMenuCreate.setOnClickListener {
supportFragmentManager.commit {
replace<CreateFragment>(R.id.fcv_main)
}
binding.bnvMain.selectedItemId = R.id.menu_create
navigateByGenerateStatus()
}
}

private fun setStatusBarColor() {
setStatusBarColorFromResource(R.color.background_white)
}

private fun navigateByGenerateStatus() {
when (viewModel.currentStatus) {
GenerateStatus.COMPLETED -> {
navigateTo<CreateFragment>()
binding.bnvMain.selectedItemId = R.id.menu_create
}

GenerateStatus.AWAIT_USER_VERIFICATION -> {
mainFinishedDialog = MainFinishedDialog()
mainFinishedDialog?.show(supportFragmentManager, DIALOG_FINISHED)
}

GenerateStatus.IN_PROGRESS -> {
WaitingActivity.createIntent(this, false).apply {
startActivity(this)
}
}

GenerateStatus.ERROR -> {
WaitingActivity.createIntent(this, true).apply {
startActivity(this)
}
}
}
}

private fun observeStatusResult() {
viewModel.getStatusResult.flowWithLifecycle(lifecycle).onEach { result ->
if (!result) {
toast(stringOf(R.string.error_msg))
}
}.launchIn(lifecycleScope)
}

private inline fun <reified T : Fragment> navigateTo() {
supportFragmentManager.commit {
replace<T>(R.id.fcv_main, T::class.java.canonicalName)
}
}

override fun onDestroy() {
super.onDestroy()
mainFinishedDialog = null
}

companion object {
private const val DIALOG_FINISHED = "DIALOG_FINISHED"
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,54 @@
package kr.genti.presentation.main

import android.os.Bundle
import android.view.View
import android.view.WindowManager
import androidx.fragment.app.activityViewModels
import kr.genti.core.base.BaseDialog
import kr.genti.core.extension.setOnSingleClickListener
import kr.genti.core.extension.stringOf
import kr.genti.core.extension.toast
import kr.genti.presentation.R
import kr.genti.presentation.databinding.DialogMainFinishedBinding
import kr.genti.presentation.result.finished.FinishedActivity

class MainFinishedDialog :
BaseDialog<DialogMainFinishedBinding>(R.layout.dialog_main_finished) {
private val viewModel by activityViewModels<MainViewModel>()

override fun onStart() {
super.onStart()
dialog?.window?.apply {
setLayout(
WindowManager.LayoutParams.MATCH_PARENT,
WindowManager.LayoutParams.WRAP_CONTENT,
)
setBackgroundDrawableResource(R.color.transparent)
}
}

override fun onViewCreated(
view: View,
savedInstanceState: Bundle?,
) {
super.onViewCreated(view, savedInstanceState)

initMoveToFinishBtnListener()
}

private fun initMoveToFinishBtnListener() {
binding.btnMoveToFinish.setOnSingleClickListener {
if (viewModel.checkNerPictureInitialized()) {
FinishedActivity.createIntent(
requireContext(),
viewModel.newPicture.pictureGenerateRequestId,
viewModel.newPicture.pictureGenerateResponse?.url.orEmpty(),
viewModel.newPicture.pictureGenerateResponse?.pictureRatio?.name.orEmpty(),
).apply { startActivity(this) }
} else {
toast(stringOf(R.string.error_msg))
}
dismiss()
}
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,44 @@
package kr.genti.presentation.main

import androidx.lifecycle.ViewModel
import androidx.lifecycle.viewModelScope
import dagger.hilt.android.lifecycle.HiltViewModel
import kotlinx.coroutines.flow.MutableSharedFlow
import kotlinx.coroutines.flow.SharedFlow
import kotlinx.coroutines.launch
import kr.genti.domain.entity.response.GenerateStatusModel
import kr.genti.domain.enums.GenerateStatus
import kr.genti.domain.repository.GenerateRepository
import javax.inject.Inject

@HiltViewModel
class MainViewModel
@Inject
constructor(
private val generateRepository: GenerateRepository,
) : ViewModel() {
private val _getStatusResult = MutableSharedFlow<Boolean>()
val getStatusResult: SharedFlow<Boolean> = _getStatusResult

var currentStatus: GenerateStatus = GenerateStatus.COMPLETED
lateinit var newPicture: GenerateStatusModel

init {
getGenerateStatusFromServer()
}

private fun getGenerateStatusFromServer() {
viewModelScope.launch {
generateRepository.getGenerateStatus()
.onSuccess {
currentStatus = GenerateStatus.ERROR
newPicture = it
}
.onFailure {
_getStatusResult.emit(false)
}
}
}

fun checkNerPictureInitialized() = ::newPicture.isInitialized
}
Original file line number Diff line number Diff line change
Expand Up @@ -176,11 +176,13 @@ class CreateViewModel
}
}

fun resetGeneratingState() {
_totalGeneratingState.value = UiState.Empty
}

fun getRandomPrompt(): String {
val randomPrompt = promptList[Random.nextInt(promptList.size)]
if (randomPrompt != currentPrompt) {
currentPrompt = randomPrompt
}
if (randomPrompt != currentPrompt) currentPrompt = randomPrompt
return currentPrompt
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -189,12 +189,10 @@ class SelfieFragment() : BaseFragment<FragmentSelfieBinding>(R.layout.fragment_s
when (state) {
is UiState.Success -> {
waitingResult.launch(Intent(requireContext(), WaitingActivity::class.java))
viewModel.resetGeneratingState()
}

is UiState.Failure -> {
toast(stringOf(R.string.error_msg))
}

is UiState.Failure -> toast(stringOf(R.string.error_msg))
else -> return@onEach
}
}.launchIn(lifecycleScope)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,6 @@ import kr.genti.core.state.UiState
import kr.genti.domain.entity.response.PicturePagedListModel
import kr.genti.domain.enums.GenerateStatus
import kr.genti.domain.repository.GenerateRepository
import timber.log.Timber
import javax.inject.Inject

@HiltViewModel
Expand Down Expand Up @@ -43,17 +42,8 @@ class ProfileViewModel
_getGenerateStatusState.value = UiState.Loading
generateRepository.getGenerateStatus()
.onSuccess {
val isGenerating =
when (it.status) {
GenerateStatus.CREATED,
GenerateStatus.ASSIGNING,
GenerateStatus.IN_PROGRESS,
GenerateStatus.MATCH_TO_ADMIN,
-> true

else -> false
}
_getGenerateStatusState.value = UiState.Success(isGenerating)
_getGenerateStatusState.value =
UiState.Success(it.status == GenerateStatus.IN_PROGRESS)
}
.onFailure { t ->
_getGenerateStatusState.value = UiState.Failure(t.message.toString())
Expand Down Expand Up @@ -82,7 +72,6 @@ class ProfileViewModel
_getPictureListState.value = UiState.Success(it)
}.onFailure {
_getPictureListState.value = UiState.Failure(it.message.toString())
Timber.tag("okhttp").d("@@@@${it.message}")
}
}
}
Expand Down
Original file line number Diff line number Diff line change
@@ -1,6 +1,8 @@
package kr.genti.presentation.result.waiting

import android.app.Activity
import android.content.Context
import android.content.Intent
import android.os.Bundle
import android.text.SpannableStringBuilder
import android.text.Spanned
Expand All @@ -20,10 +22,13 @@ import kr.genti.presentation.databinding.ActivityWaitBinding

@AndroidEntryPoint
class WaitingActivity : BaseActivity<ActivityWaitBinding>(R.layout.activity_wait) {
private var waitingErrorDialog: WaitingErrorDialog? = null

override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)

initReturnBtnListener()
getIntentIsError()
setOnBackPressed()
setStatusBarTransparent()
setEmphasizedText()
Expand All @@ -36,6 +41,14 @@ class WaitingActivity : BaseActivity<ActivityWaitBinding>(R.layout.activity_wait
}
}

private fun getIntentIsError() {
val isError = intent.getBooleanExtra(EXTRA_IS_ERROR, false)
if (isError) {
waitingErrorDialog = WaitingErrorDialog()
waitingErrorDialog?.show(supportFragmentManager, DIALOG_ERROR)
}
}

private fun setOnBackPressed() {
val onBackPressedCallback =
object : OnBackPressedCallback(true) {
Expand Down Expand Up @@ -74,4 +87,24 @@ class WaitingActivity : BaseActivity<ActivityWaitBinding>(R.layout.activity_wait
}
}
}

override fun onDestroy() {
super.onDestroy()
waitingErrorDialog = null
}

companion object {
private const val DIALOG_ERROR = "DIALOG_ERROR"

private const val EXTRA_IS_ERROR = "EXTRA_IS_ERROR"

@JvmStatic
fun createIntent(
context: Context,
isError: Boolean,
): Intent =
Intent(context, WaitingActivity::class.java).apply {
putExtra(EXTRA_IS_ERROR, isError)
}
}
}
Loading
Loading