Skip to content

Commit

Permalink
Merge pull request #104 from Team-Wable/hotfix/#103-in-app-error
Browse files Browse the repository at this point in the history
[Hotfix/#103] in app error, like.. etc
  • Loading branch information
sohyun127 authored Nov 12, 2024
2 parents b8525eb + 41c53fa commit 1d38750
Show file tree
Hide file tree
Showing 9 changed files with 73 additions and 63 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@ object AmplitudeSignUpTag {
const val CLICK_DETOUR_TEAM_SIGNUP = "click_detour_team_signup"
const val CLICK_NEXT_TEAM_SIGNUP = "click_next_team_signup"
const val CLICK_CHANGE_PICTURE_PROFILE_SIGNUP = "click_change_picture_profile_signup"
const val CLICK_ADD_PICTURE_PROFILE_SIGNUP = "k_add_picture_profile_signup"
const val CLICK_ADD_PICTURE_PROFILE_SIGNUP = "click_add_picture_profile_signup"
const val CLICK_NEXT_PROFILE_SIGNUP = "click_next_profile_signup"
const val CLICK_COMPLETE_TNC_SIGNUP = "click_complete_tnc_signup"
const val CLICK_JOIN_POPUP_SIGNUP = "click_join_popup_signup"
Expand Down
19 changes: 19 additions & 0 deletions core/ui/src/main/java/com/teamwable/ui/extensions/ContextExt.kt
Original file line number Diff line number Diff line change
Expand Up @@ -124,3 +124,22 @@ fun Context.restartApp() {
intent?.addFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP or Intent.FLAG_ACTIVITY_NEW_TASK)
startActivity(intent)
}

fun Context.showAlertDialog(
title: String,
message: String,
positiveButtonText: String,
negativeButtonText: String,
onPositiveClick: () -> Unit,
) {
val builder = AlertDialog.Builder(this)
builder.setTitle(title)
.setMessage(message)
.setPositiveButton(positiveButtonText) { dialog, _ ->
dialog.dismiss()
onPositiveClick()
}
.setNegativeButton(negativeButtonText) { dialog, _ -> dialog.dismiss() }

builder.create().show()
}
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,7 @@ class SingleEventHandler private constructor() {
}

companion object {
private const val DEBOUNCE_DELAY = 500L
private const val DEBOUNCE_DELAY = 200L

fun from(): SingleEventHandler = SingleEventHandler()
}
Expand Down
43 changes: 4 additions & 39 deletions feature/main/src/main/java/com/teamwable/main/AppUpdateHandler.kt
Original file line number Diff line number Diff line change
@@ -1,63 +1,28 @@
package com.teamwable.main

import android.content.Context
import androidx.activity.result.ActivityResultLauncher
import androidx.activity.result.IntentSenderRequest
import androidx.appcompat.app.AlertDialog
import com.google.android.play.core.appupdate.AppUpdateInfo
import com.google.android.play.core.appupdate.AppUpdateManager
import com.google.android.play.core.appupdate.AppUpdateManagerFactory
import com.google.android.play.core.appupdate.AppUpdateOptions
import com.google.android.play.core.install.model.AppUpdateType
import com.google.android.play.core.install.model.UpdateAvailability

class AppUpdateHandler(private val context: Context) {
private lateinit var appUpdateManager: AppUpdateManager

fun checkForAppUpdate(activityResultLauncher: ActivityResultLauncher<IntentSenderRequest>) {
appUpdateManager = AppUpdateManagerFactory.create(context)
class AppUpdateHandler(private val appUpdateManager: AppUpdateManager) {
fun checkForAppUpdate(onUpdateAvailable: (AppUpdateInfo) -> Unit) {
val appUpdateInfoTask = appUpdateManager.appUpdateInfo

appUpdateInfoTask.addOnSuccessListener { appUpdateInfo ->
if (appUpdateInfo.updateAvailability() == UpdateAvailability.UPDATE_AVAILABLE)
showUpdateDialog(appUpdateInfo, activityResultLauncher)
onUpdateAvailable(appUpdateInfo)
}
}

private fun showUpdateDialog(appUpdateInfo: AppUpdateInfo, activityResultLauncher: ActivityResultLauncher<IntentSenderRequest>) {
val builder = AlertDialog.Builder(context)
builder.setTitle(context.getString(R.string.label_in_app_update_title))
.setMessage(context.getString(R.string.label_in_app_update_content))
.setPositiveButton(context.getString(R.string.label_in_app_update_yes)) { dialog, _ ->
dialog.dismiss()
startUpdate(appUpdateInfo, activityResultLauncher)
}
.setNegativeButton(context.getString(R.string.label_in_app_update_next)) { dialog, _ ->
dialog.dismiss()
}

val dialog = builder.create()
dialog.show()
}

private fun startUpdate(appUpdateInfo: AppUpdateInfo, activityResultLauncher: ActivityResultLauncher<IntentSenderRequest>) {
fun startUpdate(appUpdateInfo: AppUpdateInfo, activityResultLauncher: ActivityResultLauncher<IntentSenderRequest>) {
appUpdateManager.startUpdateFlowForResult(
appUpdateInfo,
activityResultLauncher,
AppUpdateOptions.newBuilder(AppUpdateType.FLEXIBLE).build(),
)
}

fun resumeUpdateIfNeeded(activityResultLauncher: ActivityResultLauncher<IntentSenderRequest>) {
appUpdateManager.appUpdateInfo.addOnSuccessListener { appUpdateInfo ->
if (appUpdateInfo.updateAvailability() == UpdateAvailability.DEVELOPER_TRIGGERED_UPDATE_IN_PROGRESS) {
// In-app update가 이미 실행 중이면, 업데이트를 다시 시작
appUpdateManager.startUpdateFlowForResult(
appUpdateInfo,
activityResultLauncher,
AppUpdateOptions.newBuilder(AppUpdateType.FLEXIBLE).build(),
)
}
}
}
}
38 changes: 32 additions & 6 deletions feature/main/src/main/java/com/teamwable/main/MainActivity.kt
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,11 @@ import androidx.navigation.NavDestination
import androidx.navigation.fragment.NavHostFragment
import androidx.navigation.ui.onNavDestinationSelected
import androidx.navigation.ui.setupWithNavController
import com.google.android.play.core.appupdate.AppUpdateInfo
import com.google.android.play.core.appupdate.AppUpdateManager
import com.google.android.play.core.appupdate.AppUpdateManagerFactory
import com.google.android.play.core.install.InstallStateUpdatedListener
import com.google.android.play.core.install.model.InstallStatus
import com.teamwable.common.uistate.UiState
import com.teamwable.common.util.AmplitudeHomeTag.CLICK_HOME_BOTNAVI
import com.teamwable.common.util.AmplitudeHomeTag.CLICK_MYPROFILE_BOTNAVI
Expand All @@ -24,6 +29,7 @@ import com.teamwable.common.util.AmplitudeUtil.trackEvent
import com.teamwable.home.HomeFragment
import com.teamwable.main.databinding.ActivityMainBinding
import com.teamwable.ui.extensions.colorOf
import com.teamwable.ui.extensions.showAlertDialog
import com.teamwable.ui.extensions.toast
import com.teamwable.ui.extensions.visible
import com.teamwable.ui.util.Navigation
Expand All @@ -39,6 +45,7 @@ class MainActivity : AppCompatActivity(), Navigation {
private lateinit var binding: ActivityMainBinding
private val viewModel: MainViewModel by viewModels()
private lateinit var appUpdateHelper: AppUpdateHandler
private val appUpdateManager: AppUpdateManager by lazy { AppUpdateManagerFactory.create(this) }

private val activityResultLauncher =
registerForActivityResult(ActivityResultContracts.StartIntentSenderForResult()) { result ->
Expand All @@ -49,6 +56,16 @@ class MainActivity : AppCompatActivity(), Navigation {
}
}

private val installStateUpdatedListener = InstallStateUpdatedListener { state ->
if (state.installStatus() == InstallStatus.DOWNLOADED) {
Timber.i("Download Complete")
lifecycleScope.launch {
delay(5000)
appUpdateManager.completeUpdate()
}
}
}

@SuppressLint("SourceLockedOrientationActivity")
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
Expand All @@ -59,19 +76,28 @@ class MainActivity : AppCompatActivity(), Navigation {
requestedOrientation = ActivityInfo.SCREEN_ORIENTATION_PORTRAIT
}

override fun onResume() {
super.onResume()
appUpdateHelper.resumeUpdateIfNeeded(activityResultLauncher)
override fun onDestroy() {
super.onDestroy()
appUpdateManager.unregisterListener(installStateUpdatedListener)
}

private fun setInAppUpdate() {
appUpdateHelper = AppUpdateHandler(this)
appUpdateHelper.checkForAppUpdate(activityResultLauncher)
appUpdateManager.registerListener(installStateUpdatedListener)
appUpdateHelper = AppUpdateHandler(appUpdateManager).apply {
checkForAppUpdate { appUpdateInfo -> showUpdateDialog(appUpdateInfo) }
}
}

private fun showUpdateDialog(appUpdateInfo: AppUpdateInfo) = showAlertDialog(
title = getString(R.string.label_in_app_update_title),
message = getString(R.string.label_in_app_update_content),
positiveButtonText = getString(R.string.label_in_app_update_yes),
negativeButtonText = getString(R.string.label_in_app_update_next),
onPositiveClick = { appUpdateHelper.startUpdate(appUpdateInfo, activityResultLauncher) },
)

private fun initView() {
setBottomNavigation()

setupNumberObserve()
}

Expand Down
2 changes: 1 addition & 1 deletion feature/main/src/main/res/values/strings.xml
Original file line number Diff line number Diff line change
Expand Up @@ -18,5 +18,5 @@
<string name="label_in_app_update_content">와블이 새롭게 업그레이드 되었어요. 업데이트를 통해 최신 버전으로 즐겨보세요.</string>
<string name="label_in_app_update_yes">업데이트 하기</string>
<string name="label_in_app_update_next">다음에</string>
<string name="label_in_app_update_success">업데이트되었습니다. 앱을 재시작 해주세요.</string>
<string name="label_in_app_update_success">업데이트 진행 중 : 화면 이탈 시 업데이트가 취소 될 수 있습니다.</string>
</resources>
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@ import android.view.ViewGroup
import androidx.annotation.ColorRes
import androidx.core.content.ContextCompat
import androidx.fragment.app.Fragment
import com.google.android.material.appbar.AppBarLayout
import com.teamwable.model.Profile
import com.teamwable.profile.R
import com.teamwable.profile.databinding.FragmentProfileBinding
Expand All @@ -23,6 +24,8 @@ abstract class BindingProfileFragment : Fragment() {
protected val binding: FragmentProfileBinding
get() = requireNotNull(_binding) { "ViewBinding is not initialized" }

private lateinit var offsetChangedListener: AppBarLayout.OnOffsetChangedListener

override fun onCreateView(
inflater: LayoutInflater,
container: ViewGroup?,
Expand All @@ -34,6 +37,8 @@ abstract class BindingProfileFragment : Fragment() {

override fun onDestroyView() {
super.onDestroyView()
if (this::offsetChangedListener.isInitialized)
binding.appbarProfileInfo.removeOnOffsetChangedListener(offsetChangedListener)
_binding = null
}

Expand All @@ -43,9 +48,17 @@ abstract class BindingProfileFragment : Fragment() {
tvProfileNickname.text = data.nickName
tvProfileInfo.text = getString(R.string.label_profile_info, data.teamTag.ifBlank { TeamTag.LCK.name }, data.lckYears)
tvProfileGhostPercentage.text = getString(R.string.label_ghost_percentage, data.ghost)
setSwipeLayout()
setGhostProgress(data.ghost)
}

private fun setSwipeLayout() {
offsetChangedListener = AppBarLayout.OnOffsetChangedListener { _, verticalOffset ->
binding.layoutProfileSwipe.isEnabled = verticalOffset == 0
}
binding.appbarProfileInfo.addOnOffsetChangedListener(offsetChangedListener)
}

private fun setGhostProgress(percentage: Int) {
animateProgress(abs(100 + percentage))
if (percentage < -50) setGhostProgressColor(com.teamwable.ui.R.color.sky_50) else setGhostProgressColor(com.teamwable.ui.R.color.purple_50)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -6,14 +6,14 @@ import androidx.fragment.app.setFragmentResultListener
import androidx.fragment.app.viewModels
import androidx.lifecycle.flowWithLifecycle
import androidx.navigation.fragment.findNavController
import com.google.android.material.appbar.AppBarLayout
import com.google.android.material.tabs.TabLayoutMediator
import com.teamwable.model.Profile
import com.teamwable.model.profile.MemberInfoEditModel
import com.teamwable.profile.hamburger.ProfileHamburgerBottomSheet
import com.teamwable.profile.profiletabs.ProfilePagerStateAdapter
import com.teamwable.profile.profiletabs.ProfileTabType
import com.teamwable.ui.extensions.parcelable
import com.teamwable.ui.extensions.setOnDuplicateBlockClick
import com.teamwable.ui.extensions.stringOf
import com.teamwable.ui.extensions.viewLifeCycle
import com.teamwable.ui.extensions.viewLifeCycleScope
Expand Down Expand Up @@ -45,7 +45,7 @@ class ProfileAuthFragment : BindingProfileFragment() {
}

private fun initAppbarHamburgerClickListener() {
binding.viewProfileAppbar.btnProfileAppbarHamburger.setOnClickListener {
binding.viewProfileAppbar.btnProfileAppbarHamburger.setOnDuplicateBlockClick {
ProfileHamburgerBottomSheet().show(childFragmentManager, PROFILE_HAMBURGER_BOTTOM_SHEET)
}
}
Expand Down Expand Up @@ -81,12 +81,6 @@ class ProfileAuthFragment : BindingProfileFragment() {
}

private fun setSwipeLayout() {
binding.appbarProfileInfo.addOnOffsetChangedListener(
AppBarLayout.OnOffsetChangedListener { _, verticalOffset ->
binding.layoutProfileSwipe.isEnabled = verticalOffset == 0
},
)

binding.layoutProfileSwipe.setOnRefreshListener {
binding.layoutProfileSwipe.isRefreshing = false
viewModel.fetchAuthId()
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,6 @@ import android.view.View
import androidx.fragment.app.viewModels
import androidx.lifecycle.flowWithLifecycle
import androidx.navigation.fragment.findNavController
import com.google.android.material.appbar.AppBarLayout
import com.google.android.material.tabs.TabLayoutMediator
import com.teamwable.model.Profile
import com.teamwable.profile.profiletabs.ProfilePagerStateAdapter
Expand Down Expand Up @@ -63,12 +62,6 @@ class ProfileMemberFragment : BindingProfileFragment() {
}

private fun setSwipeLayout() {
binding.appbarProfileInfo.addOnOffsetChangedListener(
AppBarLayout.OnOffsetChangedListener { _, verticalOffset ->
binding.layoutProfileSwipe.isEnabled = verticalOffset == 0
},
)

binding.layoutProfileSwipe.setOnRefreshListener {
binding.layoutProfileSwipe.isRefreshing = false
viewModel.fetchProfileInfo(userId)
Expand Down

0 comments on commit 1d38750

Please sign in to comment.