Skip to content

Commit

Permalink
issue boostcampwm-2022#161 refactor: ViewModel 데이터 Flow로 리팩토링
Browse files Browse the repository at this point in the history
  • Loading branch information
TTC1018 committed Jul 2, 2023
1 parent 7bbfc04 commit 73e76f2
Showing 1 changed file with 60 additions and 35 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,7 @@ import dagger.hilt.android.lifecycle.HiltViewModel
import kotlinx.coroutines.flow.MutableSharedFlow
import kotlinx.coroutines.flow.MutableStateFlow
import kotlinx.coroutines.flow.SharedFlow
import kotlinx.coroutines.flow.StateFlow
import kotlinx.coroutines.flow.asStateFlow
import kotlinx.coroutines.launch
import javax.inject.Inject
Expand All @@ -39,7 +40,7 @@ class UploadFilmViewModel @Inject constructor(
val startTime = savedStateHandle.get<Long>(KEY_START_TIME) ?: 0L
val dateModel = savedStateHandle.get<DateModel>(KEY_DATE_MODEL)
val calendarIndex = savedStateHandle.get<Int>(KEY_CALENDAR_INDEX)
val editState = savedStateHandle.get<EditState>(KEY_EDIT_STATE)
val editState = savedStateHandle.getStateFlow<EditState?>(KEY_EDIT_STATE, null)

private val _uploadResult = MutableSharedFlow<Uri?>()
val uploadResult: SharedFlow<Uri?> get() = _uploadResult
Expand All @@ -61,12 +62,25 @@ class UploadFilmViewModel @Inject constructor(
private val _isWriting = MutableLiveData(false)
val isWriting: LiveData<Boolean> get() = _isWriting

private val _clickSound = MutableStateFlow(true)
val clickSound = _clickSound.asStateFlow()

private val _compressProgress = MutableLiveData(0)
val compressProgress: LiveData<Int> get() = _compressProgress


private val _uploadUiState = MutableStateFlow<UploadUiState>(UploadUiState.Idle)
val uploadUiState: StateFlow<UploadUiState> get() = _uploadUiState

private val _writingState = MutableStateFlow(false)
val writingState: StateFlow<Boolean> get() = _writingState

private val _muteState = MutableStateFlow(false)
val muteState = _muteState.asStateFlow()

private val _contentState = MutableStateFlow("")

private val _compressState = MutableStateFlow(0)
val compressState: StateFlow<Int> get() = _compressState


init {
calcProgress()
}
Expand All @@ -75,10 +89,10 @@ class UploadFilmViewModel @Inject constructor(
Config.resetStatistics()
Config.enableStatisticsCallback {
val percentage = it.videoFrameNumber
_compressProgress.postValue(percentage)
_compressState.value = percentage

if (isEnded())
_compressProgress.postValue(240)
_compressState.value = 240
}
}

Expand All @@ -90,21 +104,22 @@ class UploadFilmViewModel @Inject constructor(


fun uploadVideo() {
val text = textContent.value ?: ""
val progress = _compressProgress.value ?: 0
val text = _contentState.value ?: ""
val progress = _compressState.value

when {
text.isEmpty() -> {
_uiState.value = UiState.Failure(Throwable("영상에 맞는 문구를 입력해주세요."))
_uploadUiState.value = UploadUiState.UploadFailed(Throwable("일기가 비어있습니다"))
return
}
(editState != EditState.EDIT_CONTENT) && progress < 240 -> {
_uiState.value = UiState.Failure(Throwable("영상 처리중입니다. 잠시만 기다려주세요."))
(editState.value != EditState.EDIT_CONTENT) && progress < 240 -> {
_uploadUiState.value = UploadUiState.UploadFailed(Throwable("영상이 처리중입니다. 잠시만 기다려주세요"))
return
}
}

editState?.let { state ->
_uploadUiState.value = UploadUiState.UploadLoading
editState.value?.let { state ->
when (state) {
EditState.NEW_UPLOAD -> uploadStorage()
EditState.EDIT_CONTENT -> uploadEdit()
Expand All @@ -115,22 +130,19 @@ class UploadFilmViewModel @Inject constructor(

private fun uploadEdit() {

val text = textContent.value ?: ""
val text = _contentState.value ?: ""

infoItem?.let { item ->
_uiState.value = UiState.Loading
viewModelScope.launch {
dateModel ?: return@launch
val date = item.uploadDate
val dailyFilmItem = DailyFilmItem(dateModel.videoUrl.toString(), text, date)
when (val result = uploadFilmRepository.uploadEditVideo(date, dailyFilmItem)) {
is Result.Success -> {
_uiState.value = UiState.Success(
dateModel.copy(text = text)
)
_uploadUiState.value = UploadUiState.UploadSuccess(dateModel.copy(text = text))
}
is Result.Error -> {
_uiState.value = UiState.Failure(result.exception)
_uploadUiState.value = UploadUiState.UploadFailed(result.exception)
}
}
}
Expand All @@ -139,14 +151,13 @@ class UploadFilmViewModel @Inject constructor(

private fun uploadStorage() {
infoItem?.let { item ->
_uiState.value = UiState.Loading
viewModelScope.launch {
when (val result = uploadFilmRepository.uploadVideo(item.uploadDate, item.uri)) {
is Result.Success -> {
uploadRealtime(result.data)
}
is Result.Error -> {
_uiState.value = UiState.Failure(result.exception)
_uploadUiState.value = UploadUiState.UploadFailed(result.exception)
}
}
}
Expand All @@ -155,9 +166,9 @@ class UploadFilmViewModel @Inject constructor(

private fun uploadRealtime(videoUrl: Uri?) {
val uploadDate = infoItem?.uploadDate
val text = textContent.value ?: ""
val text = _contentState.value ?: ""
if (dateModel ==null){
_uiState.value = UiState.Failure(Throwable("dateModel Fail"))
_uploadUiState.value = UploadUiState.UploadFailed(Throwable("dateModel failed"))
return
}
if (videoUrl != null && uploadDate != null) {
Expand All @@ -166,23 +177,23 @@ class UploadFilmViewModel @Inject constructor(
when (val result = uploadFilmRepository.uploadFilmInfo(uploadDate, filmItem)) {
is Result.Success -> {
uploadFilmRepository.insertFilmEntity(filmItem)
_uiState.value = UiState.Success(
_uploadUiState.value = UploadUiState.UploadSuccess(
dateModel.copy(text = text, videoUrl = videoUrl.toString())
)
}
is Result.Error -> {
_uiState.value = UiState.Failure(result.exception)
_uploadUiState.value = UploadUiState.UploadFailed(result.exception)
}
}
}
} else {
_uiState.value =
UiState.Failure(Throwable("userId == null or videoUrl == null or uploadDate or null "))
_uploadUiState.value =
UploadUiState.UploadFailed(Throwable("userId or videoUrl or uploadDate is null"))
}
}

fun updateSpannableText() {
textContent.value?.let { text ->
_contentState.value.let { text ->
if (text.isNotEmpty()) {
_showedTextContent.value = SpannableString(text).apply {
setSpan(
Expand All @@ -198,41 +209,42 @@ class UploadFilmViewModel @Inject constructor(
}
}

fun updateTextContent(text: String) {
_contentState.value = text
}

private fun deleteVideo() {
dateModel ?: return

viewModelScope.launch {
_uiState.value = UiState.Loading
val updateDate = dateModel.getDate()

when (val result = deleteFilmRepository.delete(updateDate)) {
is Result.Success -> {
uploadStorage()
}
is Result.Error -> {
UiState.Failure(result.exception)
_uploadUiState.value = UploadUiState.UploadFailed(result.exception)
}
}
}
}

fun changeIsWriting() {
_isWriting.value?.let {
_isWriting.value = it.not()
}
_writingState.value = _writingState.value.not()
}

fun updateIsWriting(flag: Boolean) {
_isWriting.value = flag
_writingState.value = flag
}

fun controlSound() {
_clickSound.value = !_clickSound.value
_muteState.value = !_muteState.value
}

fun cancelUploadVideo() {
viewModelScope.launch {
_cancelUploadResult.emit(true)
_uploadUiState.emit(UploadUiState.Canceled)
}
}

Expand All @@ -241,3 +253,16 @@ class UploadFilmViewModel @Inject constructor(
const val KEY_START_TIME = "start_time"
}
}

sealed interface UploadUiState {

object Idle: UploadUiState

object Canceled: UploadUiState
object UploadLoading: UploadUiState

data class UploadSuccess(val dateModel: DateModel): UploadUiState

data class UploadFailed(val throwable: Throwable): UploadUiState

}

0 comments on commit 73e76f2

Please sign in to comment.