Skip to content

Commit

Permalink
Merge pull request #119 from uswLectureEvaluation/feature/#116-#118-f…
Browse files Browse the repository at this point in the history
…ix-null-force-update

Feature/#116 #118 fix null force update
  • Loading branch information
jinukeu authored Jan 24, 2024
2 parents be3e014 + 4849b97 commit a4df53a
Show file tree
Hide file tree
Showing 15 changed files with 103 additions and 7 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,7 @@ import androidx.compose.ui.Alignment
import androidx.compose.ui.Modifier
import androidx.compose.ui.draw.clip
import androidx.compose.ui.res.painterResource
import androidx.compose.ui.res.stringResource
import androidx.compose.ui.text.style.TextOverflow
import androidx.compose.ui.tooling.preview.Preview
import androidx.compose.ui.unit.dp
Expand Down Expand Up @@ -92,7 +93,7 @@ fun SuwikiClassReviewCard(
.padding(vertical = 3.dp),
)
Text(
text = professor,
text = if (professor == "null") stringResource(id = com.suwiki.core.ui.R.string.word_none) else professor,
style = SuwikiTheme.typography.body7,
color = Gray6A,
)
Expand Down
1 change: 1 addition & 0 deletions core/ui/src/main/java/com/suwiki/core/ui/util/Consts.kt
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@ const val ASK_SITE = "https://alike-pump-ae3.notion.site/SUWIKI-2cd58468e90b404f
const val FEEDBACK_SITE = "https://forms.gle/tZByKoN6rJCysvNz6"
const val TERMS_SITE = "https://sites.google.com/view/suwiki-policy-terms/"
const val PRIVACY_POLICY_SITE = "https://sites.google.com/view/suwiki-policy-privacy"
const val PLAY_STORE_SITE = "https://play.google.com/store/apps/details?id=com.kunize.uswtimetable&hl=ko-KR"

object REGEX {
val ID = """^[A-Za-z0-9]{6,20}$""".toRegex()
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -8,4 +8,8 @@ interface RemoteNoticeDataSource {
suspend fun getNoticeList(page: Int): List<Notice>

suspend fun getNoticeDetail(id: Long): NoticeDetail

suspend fun checkUpdateMandatory(
versionCode: Long,
): Boolean
}
Original file line number Diff line number Diff line change
Expand Up @@ -16,4 +16,8 @@ class NoticeRepositoryImpl @Inject constructor(
override suspend fun getNoticeDetail(id: Long): NoticeDetail {
return remoteNoticeDataSource.getNoticeDetail(id)
}

override suspend fun checkUpdateMandatory(versionCode: Long): Boolean {
return remoteNoticeDataSource.checkUpdateMandatory(versionCode)
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -8,4 +8,8 @@ interface NoticeRepository {
suspend fun getNoticeList(page: Int): List<Notice>

suspend fun getNoticeDetail(id: Long): NoticeDetail

suspend fun checkUpdateMandatory(
versionCode: Long,
): Boolean
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
package com.suwiki.domain.notice.usecase

import com.suwiki.core.common.runCatchingIgnoreCancelled
import com.suwiki.domain.notice.repository.NoticeRepository
import javax.inject.Inject

class CheckUpdateMandatoryUseCase @Inject constructor(
private val noticeRepository: NoticeRepository,
) {
suspend operator fun invoke(versionCode: Long): Result<Boolean> = runCatchingIgnoreCancelled {
noticeRepository.checkUpdateMandatory(versionCode)
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -87,7 +87,7 @@ fun SuwikiReviewStatisticsContainer(
.padding(vertical = 3.dp),
)
Text(
text = data.info.professor,
text = if (data.info.professor == "null") stringResource(id = com.suwiki.core.ui.R.string.word_none) else data.info.professor,
style = SuwikiTheme.typography.body7,
color = Gray6A,
)
Expand Down
2 changes: 2 additions & 0 deletions feature/navigator/build.gradle.kts
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,8 @@ android {
}

dependencies {
implementation(projects.domain.notice)

implementation(projects.feature.lectureevaluation.editor)
implementation(projects.feature.lectureevaluation.my)
implementation(projects.feature.lectureevaluation.viewerreporter)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,9 @@ data class MainState(
val toastMessage: String = "",
val toastVisible: Boolean = false,
val showNetworkErrorDialog: Boolean = false,
val showUpdateMandatoryDialog: Boolean = false,
)

sealed interface MainSideEffect
sealed interface MainSideEffect {
data object OpenPlayStoreSite : MainSideEffect
}
Original file line number Diff line number Diff line change
Expand Up @@ -18,8 +18,11 @@ import androidx.compose.foundation.shape.RoundedCornerShape
import androidx.compose.material3.Icon
import androidx.compose.material3.Scaffold
import androidx.compose.runtime.Composable
import androidx.compose.runtime.LaunchedEffect
import androidx.compose.ui.Alignment
import androidx.compose.ui.Modifier
import androidx.compose.ui.platform.LocalContext
import androidx.compose.ui.platform.LocalUriHandler
import androidx.compose.ui.res.painterResource
import androidx.compose.ui.res.stringResource
import androidx.compose.ui.unit.IntOffset
Expand All @@ -33,6 +36,8 @@ import com.suwiki.core.designsystem.theme.GrayDA
import com.suwiki.core.designsystem.theme.Primary
import com.suwiki.core.designsystem.theme.White
import com.suwiki.core.ui.extension.suwikiClickable
import com.suwiki.core.ui.extension.versionCode
import com.suwiki.core.ui.util.PLAY_STORE_SITE
import com.suwiki.feature.lectureevaluation.editor.navigation.myEvaluationEditNavGraph
import com.suwiki.feature.lectureevaluation.my.navigation.myEvaluationNavGraph
import com.suwiki.feature.lectureevaluation.viewerreporter.navigation.lectureEvaluationNavGraph
Expand All @@ -46,6 +51,7 @@ import com.suwiki.feature.timetable.navigation.timetableNavGraph
import kotlinx.collections.immutable.ImmutableList
import kotlinx.collections.immutable.toImmutableList
import org.orbitmvi.orbit.compose.collectAsState
import org.orbitmvi.orbit.compose.collectSideEffect

@Composable
internal fun MainScreen(
Expand All @@ -54,6 +60,17 @@ internal fun MainScreen(
navigator: MainNavigator = rememberMainNavigator(),
) {
val uiState = viewModel.collectAsState().value
val uriHandler = LocalUriHandler.current
val context = LocalContext.current
viewModel.collectSideEffect { sideEffect ->
when (sideEffect) {
MainSideEffect.OpenPlayStoreSite -> uriHandler.openUri(PLAY_STORE_SITE)
}
}

LaunchedEffect(key1 = Unit) {
viewModel.checkUpdateMandatory(context.versionCode)
}

Scaffold(
modifier = modifier,
Expand Down Expand Up @@ -156,14 +173,24 @@ internal fun MainScreen(

if (uiState.showNetworkErrorDialog) {
SuwikiDialog(
headerText = stringResource(com.suwiki.feature.navigator.R.string.dialog_network_header),
bodyText = stringResource(com.suwiki.feature.navigator.R.string.dialog_network_body),
headerText = stringResource(R.string.dialog_network_header),
bodyText = stringResource(R.string.dialog_network_body),
confirmButtonText = stringResource(id = com.suwiki.core.ui.R.string.word_confirm),
onDismissRequest = viewModel::hideNetworkErrorDialog,
onClickConfirm = viewModel::hideNetworkErrorDialog,
)
}

if (uiState.showUpdateMandatoryDialog) {
SuwikiDialog(
headerText = stringResource(R.string.dialog_update_mandatory_header),
bodyText = stringResource(R.string.dialog_update_mandatory_body),
confirmButtonText = stringResource(id = com.suwiki.core.ui.R.string.word_confirm),
onDismissRequest = {},
onClickConfirm = viewModel::openPlayStoreSite,
)
}

SuwikiToast(
visible = uiState.toastVisible,
message = uiState.toastMessage,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -4,23 +4,39 @@ import androidx.lifecycle.ViewModel
import com.suwiki.core.android.recordException
import com.suwiki.core.model.exception.NetworkException
import com.suwiki.core.model.exception.UnknownException
import com.suwiki.domain.notice.usecase.CheckUpdateMandatoryUseCase
import dagger.hilt.android.lifecycle.HiltViewModel
import kotlinx.coroutines.delay
import kotlinx.coroutines.sync.Mutex
import kotlinx.coroutines.sync.withLock
import org.orbitmvi.orbit.Container
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
import java.net.ConnectException
import javax.inject.Inject

@HiltViewModel
class MainViewModel @Inject constructor() : ContainerHost<MainState, MainSideEffect>, ViewModel() {
class MainViewModel @Inject constructor(
private val checkUpdateMandatoryUseCase: CheckUpdateMandatoryUseCase,
) : ContainerHost<MainState, MainSideEffect>, ViewModel() {
override val container: Container<MainState, MainSideEffect> = container(MainState())

private val mutex = Mutex()
private var isFirstVisit: Boolean = true

fun checkUpdateMandatory(versionCode: Long) = intent {
if (isFirstVisit.not()) return@intent
checkUpdateMandatoryUseCase(versionCode)
.onSuccess { updateMandatory ->
reduce { state.copy(showUpdateMandatoryDialog = updateMandatory) }
}
isFirstVisit = true
}

fun openPlayStoreSite() = intent { postSideEffect(MainSideEffect.OpenPlayStoreSite) }

fun onShowToast(msg: String) = intent {
mutex.withLock {
Expand Down
4 changes: 3 additions & 1 deletion feature/navigator/src/main/res/values/strings.xml
Original file line number Diff line number Diff line change
@@ -1,6 +1,8 @@
<?xml version="1.0" encoding="utf-8"?>
<resources>
<string name="app_name">SUWIKI</string>
<string name="dialog_network_header">네트워크에 문제가 있어요.</string>
<string name="dialog_network_header">네트워크에 문제가 있어요.</string>
<string name="dialog_network_body">네트워크 연결 상태 또는 수위키 서버에 문제가 있어요. 문제가 지속된다면 내 정보 -> 문의하기를 통해 연락 주세요.</string>
<string name="dialog_update_mandatory_header">수위키 업데이트</string>
<string name="dialog_update_mandatory_body">원활한 서비스를 위해 업데이트를 진행해야 합니다. 확인을 누르면 앱 스토어로 이동합니다.</string>
</resources>
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@ import com.suwiki.core.network.retrofit.ApiResult
import com.suwiki.remote.notice.response.DataResponse
import com.suwiki.remote.notice.response.NoticeDetailResponse
import com.suwiki.remote.notice.response.NoticeResponse
import com.suwiki.remote.notice.response.UpdateMandatoryResponse
import retrofit2.http.GET
import retrofit2.http.Query

Expand All @@ -25,4 +26,10 @@ interface NoticeApi {
suspend fun getNotice(
@Query(QUERY_NOTICE_ID) id: Long,
): ApiResult<DataResponse<NoticeDetailResponse>>

@GET("/client/version/update-mandatory")
suspend fun checkUpdateMandatory(
@Query("os") os: String = "android",
@Query("versionCode") versionCode: Long,
): ApiResult<UpdateMandatoryResponse>
}
Original file line number Diff line number Diff line change
Expand Up @@ -18,4 +18,8 @@ class RemoteNoticeDataSourceImpl @Inject constructor(
override suspend fun getNoticeDetail(id: Long): NoticeDetail {
return noticeApi.getNotice(id).getOrThrow().data.toModel()
}

override suspend fun checkUpdateMandatory(versionCode: Long): Boolean {
return noticeApi.checkUpdateMandatory(versionCode = versionCode).getOrThrow().isUpdateMandatory
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
package com.suwiki.remote.notice.response

import kotlinx.serialization.Serializable

@Serializable
data class UpdateMandatoryResponse(
val isUpdateMandatory: Boolean,
)

0 comments on commit a4df53a

Please sign in to comment.