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

#273 [feat] 앱 버전이 맞지 않을 경우, 업데이트 화면 뜨게 하기 #274

Merged
Merged
Show file tree
Hide file tree
Changes from 20 commits
Commits
Show all changes
32 commits
Select commit Hold shift + click to select a range
1537930
#273[feat]force_update xml 추가 및 string 업데이트
Nov 2, 2023
3cbbb2c
#273[feat] Version, VersionResponse data class 추가
Nov 2, 2023
9b119ca
#273[feat] ForceUpdateActivity 추가 및 버튼 클릭시, 플레이 스토어 화면으로 넘어가게 코드 작성
Nov 2, 2023
4cb7c5f
#273[feat] ForceUpdateActivity 추가
Nov 2, 2023
74ab40a
#273[feat] ForceUpdate 서버 연결 파일 추가(DataSource, Repository, Repository…
Nov 2, 2023
73fe39b
#273[feat] ForceUpdate Repo 모듈에 추가
Nov 2, 2023
78256da
#273[feat] SplashActivity에 dataObserver로 서버 통신 성공 시, 현재 appName과 비교 후…
Nov 2, 2023
c570cba
#273[feat] ktlint 정렬
Nov 2, 2023
a3f5a7c
#273[feat] ktlint 정렬
Nov 2, 2023
555f79a
#273[feat] ktlint 정렬
Nov 2, 2023
bdebaf0
#273[chore] Version domain entity 불필요한 변수 삭제
stellar-halo Nov 3, 2023
2034dc5
#273[chore] forceUpdateActivity에서 intent private으로 변경
stellar-halo Nov 3, 2023
c030123
#273[fix] splash 화면 전에 업데이트 뷰로 이동하던 코드 수정
stellar-halo Nov 5, 2023
2e6744f
#273[chore] viewModel 서버 통신 변수명 수정(isVersionStatus -> isForceUpdateSt…
stellar-halo Nov 5, 2023
10c6fb5
#273[chore] 데이터 바인딩에 따른 안쓰는 string 아이템 삭제
stellar-halo Nov 5, 2023
f631c2d
#273[fix] ForceUpdateActivity에 VERSION 엔티티 넘기기
stellar-halo Nov 5, 2023
96f0c6c
#273[fix] VERSION 엔티티로 변경
stellar-halo Nov 5, 2023
9abb91a
#273[add] viewModel 생성, view와 데이터 바인딩 연결, intent로 값 받아오기
stellar-halo Nov 5, 2023
24baa99
#273[fix] Parcelable 추가
stellar-halo Nov 5, 2023
4be191c
#273[fix] forceUpdateViewModel과 연결
stellar-halo Nov 5, 2023
33130f8
#273[add] versionDetail, versionState 엔티티 추가
stellar-halo Nov 5, 2023
a1a3192
#273[fix] viewModel로 버전 비교 로직 이전
stellar-halo Nov 5, 2023
44b9eac
#273[fix] update state 엔티티 추가로 when으로 변경하여 분기 처리
stellar-halo Nov 5, 2023
f3a3b98
#273[fix] private 처리
stellar-halo Nov 5, 2023
cb2bccd
#273[fix] vm -> viewModel 약어 교체
stellar-halo Nov 5, 2023
b633534
#273[fix] listener 함수명 구체적으로 변경 및 뷰모델 캡슐화
stellar-halo Nov 5, 2023
d4ac96c
#273[fix] checkUpdateVersion 리턴값 수정
stellar-halo Nov 5, 2023
6baa58e
#273[fix] checkUpdateVersion 반대로 되어있던 리턴값 수정
stellar-halo Nov 5, 2023
4877767
#273[fix] 스토어 링크 object로 추출, 함수명 자세하게 수정
stellar-halo Nov 5, 2023
855c21e
#273[fix] MutableLiveData, LiveData로 변경 및 그에 따른 null 처리 추가.
stellar-halo Nov 5, 2023
04c2dcd
#273[fix] String으로 스토어 링크 추출
stellar-halo Nov 5, 2023
35bb9fd
#273[fix] 불필요한 변수 삭제 및 observer 수정
stellar-halo Nov 5, 2023
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 3 additions & 0 deletions app/src/main/AndroidManifest.xml
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,9 @@
android:theme="@style/Theme.PeekabookAOS"
android:usesCleartextTraffic="true"
tools:targetApi="31">
<activity android:name=".presentation.forceUpdate.ForceUpdateActivity"
android:exported="false"
android:screenOrientation="portrait"/>
<activity
android:name=".presentation.profileModify.ProfileModifyActivity"
android:exported="false"
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
package com.sopt.peekabookaos.data.entity.response

import com.sopt.peekabookaos.domain.entity.Version
import kotlinx.serialization.SerialName
import kotlinx.serialization.Serializable

@Serializable
data class VersionResponse(
val imageUrl: String,
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

imageUrl이 현재 뷰에는 쓰이지 않는데 nullable 변수인지 서버한테 물어보면 좋을 것 같네요

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

꼼꼼한 핃백 감사합니다

val iosForceVersion: String,
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

현재 우리는 iOSForceVersion이라는 변수가 필요하지 않습니다!
json에는 ignoreUnknownKey라는 키워드가 있는데 다음에 공부해서 리팩토링 해봅시다

val androidForceVersion: String,
@SerialName("text")
val versionText: String
) {
fun toVersion(): Version = Version(
imageUrl = this.imageUrl,
androidForceVersion = this.androidForceVersion,
versionText = this.versionText
)
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
package com.sopt.peekabookaos.data.repository

import com.sopt.peekabookaos.data.source.remote.ForceUpdateDataSource
import com.sopt.peekabookaos.domain.entity.Version
import com.sopt.peekabookaos.domain.repository.ForceUpdateRepository
import javax.inject.Inject

class ForceUpdateRepositoryImpl @Inject constructor(
private val forceUpdateDataSource: ForceUpdateDataSource
) : ForceUpdateRepository {
override suspend fun getVersion(): Result<Version> =
kotlin.runCatching { forceUpdateDataSource.getVersion() }.map { response ->
requireNotNull(response.data).toVersion()
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
package com.sopt.peekabookaos.data.service

import com.sopt.peekabookaos.data.entity.BaseResponse
import com.sopt.peekabookaos.data.entity.response.VersionResponse
import retrofit2.http.GET

interface ForceUpdateService {
@GET("user/v1/version")
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

👍👍👍

suspend fun getVersion(): BaseResponse<VersionResponse>
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
package com.sopt.peekabookaos.data.source.remote

import com.sopt.peekabookaos.data.entity.BaseResponse
import com.sopt.peekabookaos.data.entity.response.VersionResponse
import com.sopt.peekabookaos.data.service.ForceUpdateService
import javax.inject.Inject

class ForceUpdateDataSource @Inject constructor(
private val forceUpdateService: ForceUpdateService
) {
suspend fun getVersion(): BaseResponse<VersionResponse> =
forceUpdateService.getVersion()
}
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@ import com.sopt.peekabookaos.data.repository.AuthRepositoryImpl
import com.sopt.peekabookaos.data.repository.BlockRepositoryImpl
import com.sopt.peekabookaos.data.repository.BookRepositoryImpl
import com.sopt.peekabookaos.data.repository.DetailRepositoryImpl
import com.sopt.peekabookaos.data.repository.ForceUpdateRepositoryImpl
import com.sopt.peekabookaos.data.repository.MyPageRepositoryImpl
import com.sopt.peekabookaos.data.repository.NaverRepositoryImpl
import com.sopt.peekabookaos.data.repository.NotificationRepositoryImpl
Expand All @@ -17,6 +18,7 @@ import com.sopt.peekabookaos.domain.repository.AuthRepository
import com.sopt.peekabookaos.domain.repository.BlockRepository
import com.sopt.peekabookaos.domain.repository.BookRepository
import com.sopt.peekabookaos.domain.repository.DetailRepository
import com.sopt.peekabookaos.domain.repository.ForceUpdateRepository
import com.sopt.peekabookaos.domain.repository.MyPageRepository
import com.sopt.peekabookaos.domain.repository.NaverRepository
import com.sopt.peekabookaos.domain.repository.NotificationRepository
Expand Down Expand Up @@ -112,4 +114,10 @@ abstract class RepositoryModule {
abstract fun bindToMyPageRepository(
myPageRepositoryImpl: MyPageRepositoryImpl
): MyPageRepository

@Binds
@Singleton
abstract fun bindToForceUpdateRepository(
forceUpdateRepositoryImpl: ForceUpdateRepositoryImpl
): ForceUpdateRepository
}
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@ import com.sopt.peekabookaos.data.service.AuthService
import com.sopt.peekabookaos.data.service.BlockService
import com.sopt.peekabookaos.data.service.BookService
import com.sopt.peekabookaos.data.service.DetailService
import com.sopt.peekabookaos.data.service.ForceUpdateService
import com.sopt.peekabookaos.data.service.MyPageService
import com.sopt.peekabookaos.data.service.NaverService
import com.sopt.peekabookaos.data.service.NotificationService
Expand All @@ -21,6 +22,7 @@ import dagger.Provides
import dagger.hilt.InstallIn
import dagger.hilt.components.SingletonComponent
import retrofit2.Retrofit
import retrofit2.create

@Module
@InstallIn(SingletonComponent::class)
Expand Down Expand Up @@ -76,4 +78,8 @@ object RetrofitServiceModule {
@Provides
fun providesReportService(@PeekaType retrofit: Retrofit): ReportService =
retrofit.create(ReportService::class.java)

@Provides
fun providesForceUpdateService(@PeekaType retrofit: Retrofit): ForceUpdateService =
retrofit.create(ForceUpdateService::class.java)
}
11 changes: 11 additions & 0 deletions app/src/main/java/com/sopt/peekabookaos/domain/entity/Version.kt
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
package com.sopt.peekabookaos.domain.entity

import android.os.Parcelable
import kotlinx.parcelize.Parcelize

@Parcelize
stellar-halo marked this conversation as resolved.
Show resolved Hide resolved
data class Version(
val imageUrl: String = "",
val androidForceVersion: String = "",
val versionText: String = ""
) : Parcelable
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
package com.sopt.peekabookaos.domain.repository

import com.sopt.peekabookaos.domain.entity.Version

interface ForceUpdateRepository {
suspend fun getVersion(): Result<Version>
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
package com.sopt.peekabookaos.domain.usecase

import com.sopt.peekabookaos.domain.repository.ForceUpdateRepository
import javax.inject.Inject

class GetVersionUseCase @Inject constructor(
private val forceUpdateRepository: ForceUpdateRepository
) {
suspend operator fun invoke() = forceUpdateRepository.getVersion()
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,40 @@
package com.sopt.peekabookaos.presentation.forceUpdate

import android.content.Intent
import android.net.Uri
import android.os.Bundle
import androidx.activity.viewModels
import com.sopt.peekabookaos.R
import com.sopt.peekabookaos.databinding.ActivityForceUpdateBinding
import com.sopt.peekabookaos.domain.entity.Version
import com.sopt.peekabookaos.presentation.splash.SplashActivity.Companion.LATEST_VERSION
import com.sopt.peekabookaos.util.binding.BindingActivity
import com.sopt.peekabookaos.util.extensions.getParcelable

class ForceUpdateActivity :
BindingActivity<ActivityForceUpdateBinding>(R.layout.activity_force_update) {
private lateinit var intentToPlayStore: Intent
private val viewModel by viewModels<ForceUpdateViewModel>()

override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
binding.vm = viewModel
getLatestVersion()
initClickListener()
}

private fun initClickListener() {
stellar-halo marked this conversation as resolved.
Show resolved Hide resolved
binding.btnForceUpdate.setOnClickListener {
intentToPlayStore = Intent(
Intent.ACTION_VIEW,
Uri.parse("https://play.google.com/store/apps/details?id=com.sopt.peekabookaos&hl=ko-KR")
)
startActivity(intentToPlayStore)
}
}

private fun getLatestVersion() {
intent.getParcelable(LATEST_VERSION, Version::class.java)
?.let { viewModel.getLatestVersion(it) }
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
package com.sopt.peekabookaos.presentation.forceUpdate

import androidx.lifecycle.ViewModel
import com.sopt.peekabookaos.domain.entity.Version

class ForceUpdateViewModel : ViewModel() {
lateinit var latestVersion: Version

fun getLatestVersion(version: Version) {
latestVersion = version
}
stellar-halo marked this conversation as resolved.
Show resolved Hide resolved
}
Original file line number Diff line number Diff line change
Expand Up @@ -2,13 +2,17 @@ package com.sopt.peekabookaos.presentation.splash

import android.annotation.SuppressLint
import android.content.Intent
import android.content.Intent.FLAG_ACTIVITY_CLEAR_TASK
import android.content.Intent.FLAG_ACTIVITY_NEW_TASK
import android.os.Bundle
import android.os.Handler
import android.os.Looper
import androidx.activity.viewModels
import com.sopt.peekabookaos.BuildConfig
import com.sopt.peekabookaos.R
import com.sopt.peekabookaos.databinding.ActivitySplashBinding
import com.sopt.peekabookaos.domain.entity.SplashState
import com.sopt.peekabookaos.presentation.forceUpdate.ForceUpdateActivity
import com.sopt.peekabookaos.presentation.main.MainActivity
import com.sopt.peekabookaos.presentation.onboarding.OnboardingActivity
import com.sopt.peekabookaos.util.binding.BindingActivity
Expand All @@ -18,11 +22,39 @@ import dagger.hilt.android.AndroidEntryPoint
@SuppressLint("CustomSplashScreen")
class SplashActivity : BindingActivity<ActivitySplashBinding>(R.layout.activity_splash) {
private val splashViewModel: SplashViewModel by viewModels()
private val appVersionName = BuildConfig.VERSION_NAME

override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
binding.lottieSplash.playAnimation()
Handler(Looper.getMainLooper()).postDelayed({ checkSplashState() }, DURATION)
Handler(Looper.getMainLooper()).postDelayed({ initObserver() }, DURATION)
}

private fun initObserver() {
stellar-halo marked this conversation as resolved.
Show resolved Hide resolved
splashViewModel.isForceUpdateStatus.observe(this) { success ->
if (success) {
splashViewModel.getSplitVersion()
checkVersionUpdate()
}
}
}
stellar-halo marked this conversation as resolved.
Show resolved Hide resolved

private fun checkVersionUpdate() {
val appVersionList = appVersionName.split(".")
val previousMajor = appVersionList[0]
val previousMinor = appVersionList[1]
val isPreviousVersions =
previousMajor != splashViewModel.majorVersion || previousMinor != splashViewModel.minorVersion
stellar-halo marked this conversation as resolved.
Show resolved Hide resolved
if (isPreviousVersions) {
val intentToForceUpdate = Intent(this, ForceUpdateActivity::class.java).apply {
putExtra(LATEST_VERSION, splashViewModel.latestVersion)
addFlags(FLAG_ACTIVITY_CLEAR_TASK or FLAG_ACTIVITY_NEW_TASK)
}
startActivity(Intent(intentToForceUpdate))
finish()
} else {
checkSplashState()
}
stellar-halo marked this conversation as resolved.
Show resolved Hide resolved
}

private fun checkSplashState() {
Expand All @@ -36,5 +68,6 @@ class SplashActivity : BindingActivity<ActivitySplashBinding>(R.layout.activity_

companion object {
private const val DURATION: Long = 2000
const val LATEST_VERSION = "latest version"
2zerozu marked this conversation as resolved.
Show resolved Hide resolved
}
}
Original file line number Diff line number Diff line change
@@ -1,14 +1,56 @@
package com.sopt.peekabookaos.presentation.splash

import androidx.lifecycle.LiveData
import androidx.lifecycle.MutableLiveData
import androidx.lifecycle.ViewModel
import androidx.lifecycle.viewModelScope
import com.sopt.peekabookaos.domain.entity.SplashState
import com.sopt.peekabookaos.domain.entity.Version
import com.sopt.peekabookaos.domain.usecase.GetSplashStateUseCase
import com.sopt.peekabookaos.domain.usecase.GetVersionUseCase
import dagger.hilt.android.lifecycle.HiltViewModel
import kotlinx.coroutines.launch
import timber.log.Timber
import javax.inject.Inject

@HiltViewModel
class SplashViewModel @Inject constructor(
private val getSplashStateUseCase: GetSplashStateUseCase
private val getSplashStateUseCase: GetSplashStateUseCase,
private val getVersionUseCase: GetVersionUseCase
) : ViewModel() {
var latestVersion = Version()
private val _isForceUpdateStatus = MutableLiveData(false)
val isForceUpdateStatus: LiveData<Boolean> = _isForceUpdateStatus
lateinit var majorVersion: String
lateinit var minorVersion: String
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

public인 이유가 있나요?

Copy link
Member Author

@stellar-halo stellar-halo Nov 5, 2023

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

로직 변경해서 바뀐 변수들은 private으로 처리했습니다


init {
getVersion()
}

fun getSplashState(): SplashState = getSplashStateUseCase()

fun getSplitVersion() = run {
val versionSpiltList = latestVersion.androidForceVersion.split(".")
majorVersion = versionSpiltList[0]
minorVersion = versionSpiltList[1]
}

private fun getVersion() {
viewModelScope.launch {
getVersionUseCase()
.onSuccess { response ->
latestVersion = Version(
response.imageUrl,
response.androidForceVersion,
response.versionText
)
_isForceUpdateStatus.value = true
}
.onFailure { throwable ->
_isForceUpdateStatus.value = false
Timber.e("$throwable")
}
}
}
}
Loading
Loading