Skip to content

Commit

Permalink
Merge pull request #79 from Team-Walkie/feat/challenge_stop
Browse files Browse the repository at this point in the history
챌린지 그만두기 기능 구현
  • Loading branch information
yonghanJu authored Aug 1, 2024
2 parents b9cba04 + eed3983 commit 03d17ef
Show file tree
Hide file tree
Showing 12 changed files with 105 additions and 20 deletions.
8 changes: 8 additions & 0 deletions app/build.gradle.kts
Original file line number Diff line number Diff line change
Expand Up @@ -125,4 +125,12 @@ dependencies {
implementation(platform("com.google.firebase:firebase-bom:32.7.0"))
implementation("com.google.firebase:firebase-crashlytics")
implementation("com.google.firebase:firebase-analytics")

// orbit
// TODO: change To Core For Compose Multiplatform
val orbitVersion = "4.6.1"
implementation("org.orbit-mvi:orbit-viewmodel:$orbitVersion")
implementation("org.orbit-mvi:orbit-compose:$orbitVersion")
// Tests
testImplementation("org.orbit-mvi:orbit-test:$orbitVersion")
}
35 changes: 19 additions & 16 deletions app/src/main/java/com/whyranoid/walkie/KoinModules.kt
Original file line number Diff line number Diff line change
Expand Up @@ -49,6 +49,7 @@ import com.whyranoid.domain.repository.PostRepository
import com.whyranoid.domain.repository.RunningHistoryRepository
import com.whyranoid.domain.repository.RunningRepository
import com.whyranoid.domain.repository.UserRepository
import com.whyranoid.domain.usecase.ChangeChallengeStatusUseCase
import com.whyranoid.domain.usecase.GetChallengeDetailUseCase
import com.whyranoid.domain.usecase.GetChallengePreviewsByTypeUseCase
import com.whyranoid.domain.usecase.GetChallengingPreviewsUseCase
Expand Down Expand Up @@ -105,29 +106,30 @@ import okhttp3.OkHttpClient
import okhttp3.Response
import okhttp3.logging.HttpLoggingInterceptor
import org.koin.android.ext.koin.androidContext
import org.koin.androidx.viewmodel.dsl.viewModel
import org.koin.dsl.module
import retrofit2.Retrofit
import retrofit2.converter.gson.GsonConverterFactory
import java.util.concurrent.TimeUnit

val viewModelModule =
module {
single { ChallengeMainViewModel(get(), get(), get(), get(), get()) }
single { ChallengeDetailViewModel(get(), get()) }
single { ChallengeExitViewModel(get()) }
factory { UserPageViewModel(get(), get(), get(), get(), get(), get(), get(), get(), get()) }
factory { RunningViewModel(get(), get(), get(), get(), get(), get()) }
factory { RunningEditViewModel() }
factory { SplashViewModel(get()) }
factory { SignInViewModel(get()) }
factory { SelectHistoryViewModel(get()) }
factory { EditProfileViewModel(get()) }
factory { AddPostViewModel(get()) }
factory { SearchFriendViewModel(get(), get(), get()) }
factory { DialogViewModel(get(), get(), get(), get(), get(), get()) }
factory { CommunityScreenViewModel(get(), get(), get()) }
factory { FollowingViewModel(get(), get(), get(), get(), get(), get()) }
factory { SettingViewModel(get(), get()) }
viewModel { ChallengeMainViewModel(get(), get(), get(), get(), get()) }
viewModel { ChallengeDetailViewModel(get(), get()) }
viewModel { ChallengeExitViewModel(get(), get()) }
viewModel { UserPageViewModel(get(), get(), get(), get(), get(), get(), get(), get(), get()) }
viewModel { RunningViewModel(get(), get(), get(), get(), get(), get()) }
viewModel { RunningEditViewModel() }
viewModel { SplashViewModel(get()) }
viewModel { SignInViewModel(get()) }
viewModel { SelectHistoryViewModel(get()) }
viewModel { EditProfileViewModel(get()) }
viewModel { AddPostViewModel(get()) }
viewModel { SearchFriendViewModel(get(), get(), get()) }
viewModel { DialogViewModel(get(), get(), get(), get(), get(), get()) }
viewModel { CommunityScreenViewModel(get(), get(), get()) }
viewModel { FollowingViewModel(get(), get(), get(), get(), get(), get()) }
viewModel { SettingViewModel(get(), get()) }
}

val repositoryModule =
Expand Down Expand Up @@ -193,6 +195,7 @@ val useCaseModule =
single { GetMyFollowingUseCase(get(), get()) }
single { SendCommentUseCase(get(), get()) }
single { GetUserUseCase(get()) }
single { ChangeChallengeStatusUseCase(get(), get())}
}

val databaseModule =
Expand Down
2 changes: 2 additions & 0 deletions data/src/main/java/com/whyranoid/data/API.kt
Original file line number Diff line number Diff line change
Expand Up @@ -45,6 +45,8 @@ object API {

const val CHALLENGE_START = "api/challenge/challenge-detail/start"

const val CHALLENGE_CHANGE_STATUS = "api/challenge/challenge-detail/update-status"

object WalkingControl {
const val RUNNING_START = "api/walk/start"

Expand Down
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
package com.whyranoid.data.datasource.challenge

import android.util.Log
import com.whyranoid.data.getResult
import com.whyranoid.data.model.challenge.request.ChallengeChangeStatusRequest
import com.whyranoid.data.model.challenge.request.ChallengeStartRequest
import com.whyranoid.domain.datasource.ChallengeDataSource
import com.whyranoid.domain.model.challenge.Badge
Expand Down Expand Up @@ -71,4 +71,10 @@ class ChallengeDataSourceImpl(
challengeService.startChallenge(ChallengeStartRequest(uid, challengeId))
}
}

override suspend fun changeChallengeStatus(challengeId: Int, status: String, walkieId: Int): Result<Unit> {
return runCatching {
challengeService.changeChallengeStatus(ChallengeChangeStatusRequest(challengeId, status, walkieId))
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@ import com.whyranoid.data.model.StatusWithMessage
import com.whyranoid.data.model.challenge.BadgeResponse
import com.whyranoid.data.model.challenge.ChallengeDetailResponse
import com.whyranoid.data.model.challenge.ChallengePreviewResponse
import com.whyranoid.data.model.challenge.request.ChallengeChangeStatusRequest
import com.whyranoid.data.model.challenge.request.ChallengeStartRequest
import retrofit2.Response
import retrofit2.http.Body
Expand Down Expand Up @@ -46,4 +47,9 @@ interface ChallengeService {
suspend fun getBadgeList(
@Query("walkieId") uid: Long
): Response<List<BadgeResponse>>

@POST(API.CHALLENGE_CHANGE_STATUS)
suspend fun changeChallengeStatus(
@Body changeChallengeStatusRequest: ChallengeChangeStatusRequest
) : Response<StatusWithMessage>
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
package com.whyranoid.data.model.challenge.request

data class ChallengeChangeStatusRequest(
val challengeId: Int,
val status: String,
val walkieId: Int
)
Original file line number Diff line number Diff line change
Expand Up @@ -37,4 +37,8 @@ class ChallengeRepositoryImpl(
override suspend fun startChallenge(uid: Int, challengeId: Int): Result<Unit> {
return challengeDataSource.startChallenge(uid, challengeId)
}

override suspend fun changeChallengeStatus(challengeId: Int, status: String, walkieId: Int): Result<Unit> {
return challengeDataSource.changeChallengeStatus(challengeId, status, walkieId)
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -20,4 +20,6 @@ interface ChallengeDataSource {
suspend fun getUserBadges(uid: Long): Result<List<Badge>>

suspend fun startChallenge(uid: Int, challengeId: Int): Result<Unit>

suspend fun changeChallengeStatus(challengeId: Int, status: String, walkieId: Int): Result<Unit>
}
Original file line number Diff line number Diff line change
Expand Up @@ -20,4 +20,6 @@ interface ChallengeRepository {
suspend fun getUserBadges(uid: Long): Result<List<Badge>>

suspend fun startChallenge(uid: Int, challengeId: Int): Result<Unit>

suspend fun changeChallengeStatus(challengeId: Int, status: String, walkieId: Int): Result<Unit>
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
package com.whyranoid.domain.usecase

import com.whyranoid.domain.repository.ChallengeRepository
import javax.inject.Inject

class ChangeChallengeStatusUseCase @Inject constructor(
private val challengeRepository: ChallengeRepository,
private val getMyUidUseCase: GetMyUidUseCase
) {
suspend operator fun invoke(challengeId: Int, status: String): Result<Unit> {
val myId = getMyUidUseCase()
return challengeRepository.changeChallengeStatus(challengeId, status, myId.getOrNull()?.toInt() ?: -1)
}

}
Original file line number Diff line number Diff line change
Expand Up @@ -29,17 +29,20 @@ import com.whyranoid.presentation.component.button.WalkieNegativeButton
import com.whyranoid.presentation.component.button.WalkiePositiveButton
import com.whyranoid.presentation.reusable.WalkieCircularProgressIndicator
import com.whyranoid.presentation.theme.WalkieTypography
import com.whyranoid.presentation.viewmodel.challenge.ChallengeExitSideEffect
import com.whyranoid.presentation.viewmodel.challenge.ChallengeExitState
import com.whyranoid.presentation.viewmodel.challenge.ChallengeExitViewModel
import org.koin.androidx.compose.koinViewModel
import org.orbitmvi.orbit.compose.collectAsState
import org.orbitmvi.orbit.compose.collectSideEffect

@Composable
fun ChallengeExitScreen(
navController: NavController,
challengeId: Long,
) {

val context = LocalContext.current
val viewModel = koinViewModel<ChallengeExitViewModel>()

LaunchedEffect(true) {
Expand All @@ -48,10 +51,23 @@ fun ChallengeExitScreen(

val state by viewModel.collectAsState()

viewModel.collectSideEffect {
when (it) {
ChallengeExitSideEffect.StopChallengeSuccess -> {
Toast.makeText(context, "챌린지를 성공적으로 중단하였습니다.", Toast.LENGTH_SHORT).show()
navController.popBackStack()
}

ChallengeExitSideEffect.StopChallengeFailure -> {
Toast.makeText(context, "챌린지 중단에 실패하였습니다.", Toast.LENGTH_SHORT).show()
}
}
}

ChallengeExitContent(
state,
onPositiveButtonClicked = {
// TODO
viewModel.stopChallenge()
},
onNegativeButtonClicked = {
navController.popBackStack()
Expand Down Expand Up @@ -135,7 +151,6 @@ fun ChallengeExitContent(
) {
WalkiePositiveButton(text = "확인") {
onPositiveButtonClicked()
Toast.makeText(context, "확인", Toast.LENGTH_SHORT).show()
}
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2,15 +2,18 @@ package com.whyranoid.presentation.viewmodel.challenge

import androidx.lifecycle.ViewModel
import com.whyranoid.domain.model.challenge.Challenge
import com.whyranoid.domain.usecase.ChangeChallengeStatusUseCase
import com.whyranoid.domain.usecase.GetChallengeDetailUseCase
import com.whyranoid.presentation.model.UiState
import org.orbitmvi.orbit.ContainerHost
import org.orbitmvi.orbit.syntax.simple.intent
import org.orbitmvi.orbit.syntax.simple.postSideEffect
import org.orbitmvi.orbit.syntax.simple.reduce
import org.orbitmvi.orbit.viewmodel.container

sealed class ChallengeExitSideEffect {

object StopChallengeSuccess : ChallengeExitSideEffect()
object StopChallengeFailure : ChallengeExitSideEffect()
}

data class ChallengeExitState(
Expand All @@ -19,6 +22,7 @@ data class ChallengeExitState(

class ChallengeExitViewModel(
private val getChallengeDetailUseCase: GetChallengeDetailUseCase,
private val changeChallengeStatusUseCase: ChangeChallengeStatusUseCase
) : ViewModel(),
ContainerHost<ChallengeExitState, ChallengeExitSideEffect> {

Expand All @@ -35,4 +39,15 @@ class ChallengeExitViewModel(
}
}

fun stopChallenge() = intent {
changeChallengeStatusUseCase(
state.challenge.getDataOrNull()?.id?.toInt() ?: 0,
"N",
).onSuccess {
postSideEffect(ChallengeExitSideEffect.StopChallengeSuccess)
}.onFailure {
postSideEffect(ChallengeExitSideEffect.StopChallengeFailure)
}
}

}

0 comments on commit 03d17ef

Please sign in to comment.