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

Feature/#121 update notification #190

Merged
merged 11 commits into from
Feb 18, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
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
1 change: 1 addition & 0 deletions .idea/misc.xml

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

2 changes: 2 additions & 0 deletions app/build.gradle
Original file line number Diff line number Diff line change
Expand Up @@ -137,4 +137,6 @@ dependencies {
// Splash Screen
implementation 'androidx.core:core-splashscreen:1.0.1'

// In App Update
implementation 'com.google.android.play:app-update-ktx:2.1.0'
}
Original file line number Diff line number Diff line change
Expand Up @@ -42,6 +42,14 @@ object SparkleStorage {
)
}

fun setUpdateAvailableBoolean(key: String, value: Boolean) {
pref.edit { putBoolean(key, value) }
}

fun getUpdateAvailableBoolean(key: String): Boolean {
return pref.getBoolean(key, false)
}

var accessToken: String?
get() = pref.getString(ACCESS_TOKEN, null)
set(value) = pref.edit { putString(ACCESS_TOKEN, value).apply() }
Expand Down
21 changes: 21 additions & 0 deletions app/src/main/java/sopt/uni/di/AppModule.kt
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
package sopt.uni.di

import android.content.Context
import com.google.android.play.core.appupdate.AppUpdateManager
import com.google.android.play.core.appupdate.AppUpdateManagerFactory
import dagger.Module
import dagger.Provides
import dagger.hilt.InstallIn
import dagger.hilt.android.qualifiers.ApplicationContext
import dagger.hilt.components.SingletonComponent
import javax.inject.Singleton

@Module
@InstallIn(SingletonComponent::class)
object AppModule {

@Provides
@Singleton
fun provideAppUpdateManager(@ApplicationContext context: Context): AppUpdateManager =
AppUpdateManagerFactory.create(context)
}
38 changes: 37 additions & 1 deletion app/src/main/java/sopt/uni/presentation/IntroActivity.kt
Original file line number Diff line number Diff line change
Expand Up @@ -5,30 +5,66 @@ import android.os.Bundle
import android.util.Log
import androidx.appcompat.app.AppCompatActivity
import androidx.core.splashscreen.SplashScreen.Companion.installSplashScreen
import com.google.android.play.core.appupdate.AppUpdateManager
import com.google.android.play.core.install.model.AppUpdateType
import com.google.android.play.core.install.model.UpdateAvailability
import dagger.hilt.android.AndroidEntryPoint
import sopt.uni.data.datasource.local.SparkleStorage
import sopt.uni.data.repository.shortgame.ShortGameRepository
import sopt.uni.presentation.home.HomeActivity
import sopt.uni.presentation.home.UpdateDialogFragment
import sopt.uni.presentation.invite.NickNameActivity
import sopt.uni.presentation.invite.ShareInviteCodeActivity
import sopt.uni.presentation.onboarding.OnBoardingActivity
import sopt.uni.util.extension.startActivity
import timber.log.Timber
import javax.inject.Inject

@AndroidEntryPoint
class IntroActivity : AppCompatActivity() {
@Inject
lateinit var shortGameRepository: ShortGameRepository

@Inject
lateinit var appUpdateManager: AppUpdateManager

override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
installSplashScreen()

checkUserStatus()
checkUpdateAvailability()

// ๋ฉ”๋ชจ์žฅ ์ดˆ๊ธฐํ™”
shortGameRepository.setMemoText("")
}

private fun checkUpdateAvailability() {
val appUpdateInfoTask = appUpdateManager.appUpdateInfo
appUpdateInfoTask.addOnSuccessListener { appUpdateInfo ->
if (appUpdateInfo.updateAvailability() == UpdateAvailability.UPDATE_AVAILABLE && appUpdateInfo.isUpdateTypeAllowed(
AppUpdateType.IMMEDIATE,
)
) {
showUpdateDialog()
} else {
checkUserStatus()
}
}
appUpdateInfoTask.addOnFailureListener { exception ->
Timber.tag("inappUpdate").e("์—…๋ฐ์ดํŠธ ์ฒดํฌ ์‹คํŒจ: ${exception.message}")
checkUserStatus()
}
}

private fun showUpdateDialog() {
val dialogFragment = UpdateDialogFragment(
onDismissOrComplete = {
checkUserStatus()
},
)
dialogFragment.show(supportFragmentManager, "UpdateDialog")
}

private fun checkUserStatus() {
if (SparkleStorage.accessToken != null) {
Log.e("accessToken", SparkleStorage.accessToken.toString())
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,80 @@
package sopt.uni.presentation.home

import android.app.Activity
import android.os.Bundle
import android.util.Log
import android.view.View
import androidx.activity.result.contract.ActivityResultContracts
import com.google.android.play.core.appupdate.AppUpdateManager
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
import dagger.hilt.android.AndroidEntryPoint
import sopt.uni.R
import sopt.uni.data.datasource.local.SparkleStorage
import sopt.uni.databinding.TitleAction2DialogBinding
import sopt.uni.util.binding.BindingDialogFragment
import sopt.uni.util.extension.setOnSingleClickListener
import sopt.uni.util.extension.showSnackbar
import timber.log.Timber
import javax.inject.Inject

@AndroidEntryPoint
class UpdateDialogFragment(private val onDismissOrComplete: () -> Unit) :
BindingDialogFragment<TitleAction2DialogBinding>(R.layout.title_action2_dialog) {

@Inject
lateinit var appUpdateManager: AppUpdateManager

override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
super.onViewCreated(view, savedInstanceState)
setLayoutSizeRatio(0.778f, 0.2f)

with(binding) {
dialogTitle.setText(getString(R.string.update_dialog_title))
dialogBody.setText(getString(R.string.update_dialog_body))
btnRight.setText(getString(R.string.update_dialog_ok))
btnLeft.setOnSingleClickListener {
dismiss()
onDismissOrComplete()
}
btnRight.setOnSingleClickListener {
updateSparkle()
}
}
}

private fun updateSparkle() {
appUpdateManager.appUpdateInfo.addOnSuccessListener { appUpdateInfo ->
if (appUpdateInfo.updateAvailability() == UpdateAvailability.UPDATE_AVAILABLE &&
appUpdateInfo.isUpdateTypeAllowed(AppUpdateType.IMMEDIATE)
) {
appUpdateManager.startUpdateFlowForResult(
appUpdateInfo,
startForResult,
AppUpdateOptions.newBuilder(AppUpdateType.IMMEDIATE).build(),
)
}
}.addOnFailureListener {
Timber.tag("updateSparkleFail").e("์—…๋Žƒ์‹คํŒจใ… ")
}
}

private val startForResult =
registerForActivityResult(ActivityResultContracts.StartIntentSenderForResult()) {
if (it.resultCode != Activity.RESULT_OK) {
showSnackbar(binding.root, "์—…๋ฐ์ดํŠธ์— ์‹คํŒจํ–ˆ์Šต๋‹ˆ๋‹ค. ๋‹ค์‹œ ์‹œ๋„ํ•ด์ฃผ์„ธ์š”.")
Log.e("update", it.resultCode.toString())
} else {
SparkleStorage.setUpdateAvailableBoolean(
IS_UPDATE_AVAILABLE,
true,
)
onDismissOrComplete()
}
}

companion object {
const val IS_UPDATE_AVAILABLE = "IS_UPDATE_AVAILABLE"
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -9,15 +9,16 @@ import sopt.uni.data.datasource.local.SparkleStorage
import sopt.uni.databinding.NoBodyAction2DialogBinding
import sopt.uni.databinding.TitleAction2DialogBinding
import sopt.uni.di.ServicePool
import sopt.uni.presentation.BindingDialogFragment
import sopt.uni.presentation.invite.NickNameActivity
import sopt.uni.presentation.login.LoginActivity
import sopt.uni.util.binding.BindingDialogFragment
import sopt.uni.util.extension.setOnSingleClickListener

class MypageAccountLogoutDialogFragment :
BindingDialogFragment<NoBodyAction2DialogBinding>(R.layout.no_body_action2_dialog) {
override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
super.onViewCreated(view, savedInstanceState)
setLayoutSizeRatio(0.778f, 0.16f)

with(binding) {
dialogTitle.setText(getString(R.string.logout_dialog_title))
Expand Down Expand Up @@ -47,6 +48,7 @@ class MypageAccountDeleteDialogFragment :

override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
super.onViewCreated(view, savedInstanceState)
setLayoutSizeRatio(0.778f, 0.22f)

with(binding) {
dialogTitle.setText(getString(R.string.delete_dialog_title))
Expand Down Expand Up @@ -77,6 +79,7 @@ class MypageAccountCoupleDisconnectDialogFragment :

override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
super.onViewCreated(view, savedInstanceState)
setLayoutSizeRatio(0.778f, 0.22f)

with(binding) {
dialogTitle.setText(getString(R.string.disconnect_dialog_title))
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -4,14 +4,13 @@ import android.os.Bundle
import android.view.View
import sopt.uni.R
import sopt.uni.databinding.DatepickerDialogBinding
import sopt.uni.presentation.BindingDialogFragment
import sopt.uni.util.binding.BindingDialogFragment
import sopt.uni.util.extension.setOnSingleClickListener
import java.util.Calendar

class MypageDatePickerDialogFragment :
BindingDialogFragment<DatepickerDialogBinding>(
R.layout.datepicker_dialog,
isWrapContent = true,
) {
private var listener: DatePickerDialogListener? = null

Expand All @@ -21,6 +20,7 @@ class MypageDatePickerDialogFragment :

override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
super.onViewCreated(view, savedInstanceState)
setLayoutSizeRatio(0.77f, 0.34f)

setMaxDate()

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@ import android.os.Bundle
import android.view.View
import sopt.uni.R
import sopt.uni.databinding.TitleAction2DialogBinding
import sopt.uni.presentation.BindingDialogFragment
import sopt.uni.util.binding.BindingDialogFragment

class CreateShortGameDialogFragment :
BindingDialogFragment<TitleAction2DialogBinding>(R.layout.title_action2_dialog) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@ import android.os.Bundle
import android.view.View
import sopt.uni.R
import sopt.uni.databinding.TitleAction2DialogBinding
import sopt.uni.presentation.BindingDialogFragment
import sopt.uni.util.binding.BindingDialogFragment
import sopt.uni.util.extension.setOnSingleClickListener

class TimerDialogFragment :
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@ import android.os.Bundle
import android.view.View
import sopt.uni.R
import sopt.uni.databinding.TitleAction2DialogBinding
import sopt.uni.presentation.BindingDialogFragment
import sopt.uni.util.binding.BindingDialogFragment
import sopt.uni.util.extension.setOnSingleClickListener

class NewWishDialogFragment :
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@ import android.os.Bundle
import android.view.View
import sopt.uni.R
import sopt.uni.databinding.TitleAction2DialogBinding
import sopt.uni.presentation.BindingDialogFragment
import sopt.uni.util.binding.BindingDialogFragment

class UseWishDialogFragment :
BindingDialogFragment<TitleAction2DialogBinding>(R.layout.title_action2_dialog) {
Expand Down
38 changes: 22 additions & 16 deletions app/src/main/java/sopt/uni/util/binding/BindingDialogFragment.kt
Original file line number Diff line number Diff line change
@@ -1,5 +1,7 @@
package sopt.uni.presentation
package sopt.uni.util.binding

import android.graphics.Color
import android.graphics.drawable.ColorDrawable
import android.os.Bundle
import android.view.LayoutInflater
import android.view.View
Expand All @@ -10,21 +12,11 @@ import androidx.databinding.ViewDataBinding
import androidx.fragment.app.DialogFragment
import sopt.uni.R

abstract class BindingDialogFragment<B : ViewDataBinding>(
abstract class BindingDialogFragment<T : ViewDataBinding>(
@LayoutRes private val layoutRes: Int,
private val isWrapContent: Boolean = false,
) :
DialogFragment() {
private var _binding: B? = null
val binding get() = requireNotNull(_binding!!) { "${this::class.java.simpleName}์—์„œ ์—๋Ÿฌ๊ฐ€ ๋ฐœ์ƒํ–ˆ์Šต๋‹ˆ๋‹ค." }

override fun onStart() {
super.onStart()
val width = if (isWrapContent) ViewGroup.LayoutParams.WRAP_CONTENT else resources.getDimensionPixelSize(R.dimen.dialog_width)
val height = if (isWrapContent) ViewGroup.LayoutParams.WRAP_CONTENT else resources.getDimensionPixelSize(R.dimen.dialog_height)
dialog?.window?.setLayout(width, height)
dialog?.window?.setBackgroundDrawableResource(android.R.color.transparent)
}
) : DialogFragment() {
private var _binding: T? = null
protected val binding get() = _binding ?: error(getString(R.string.binding_error))

override fun onCreateView(
inflater: LayoutInflater,
Expand All @@ -35,8 +27,22 @@ abstract class BindingDialogFragment<B : ViewDataBinding>(
return binding.root
}

override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
super.onViewCreated(view, savedInstanceState)
dialog?.window?.setBackgroundDrawable(ColorDrawable(Color.TRANSPARENT))
}

protected fun setLayoutSizeRatio(widthPercent: Float, heightPercent: Float) {
context?.resources?.displayMetrics?.let { metrics ->
binding.root.layoutParams.apply {
width = ((metrics.widthPixels * widthPercent).toInt())
height = ((metrics.heightPixels * heightPercent).toInt())
}
}
}

override fun onDestroyView() {
super.onDestroyView()
_binding = null
super.onDestroyView()
}
}
4 changes: 2 additions & 2 deletions app/src/main/res/layout/title_action2_dialog.xml
Original file line number Diff line number Diff line change
Expand Up @@ -47,7 +47,7 @@
android:layout_height="wrap_content"
android:layout_marginTop="30dp"
android:layout_marginEnd="10dp"
android:layout_marginBottom="16dp"
android:layout_marginBottom="45dp"
android:paddingHorizontal="14dp"
android:paddingVertical="7dp"
android:text="@string/dialog_cancel_text"
Expand All @@ -62,7 +62,7 @@
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginHorizontal="10dp"
android:layout_marginBottom="16dp"
android:layout_marginBottom="45dp"
android:paddingHorizontal="14dp"
android:paddingVertical="7dp"
android:text="@string/dialog_ok_text"
Expand Down
3 changes: 0 additions & 3 deletions app/src/main/res/values/dimens.xml
Original file line number Diff line number Diff line change
Expand Up @@ -3,9 +3,6 @@
<dimen name="home_lightblue_background">158dp</dimen>
<dimen name="divider_width">49dp</dimen>
<dimen name="on_boarding_image">328dp</dimen>
<dimen name="dialog_width">300dp</dimen>
<dimen name="dialog_height">165dp</dimen>

<!-- Button -->
<dimen name="long_button_height">48dp</dimen>
</resources>
Expand Down
5 changes: 5 additions & 0 deletions app/src/main/res/values/strings.xml
Original file line number Diff line number Diff line change
Expand Up @@ -121,6 +121,11 @@
<string name="dialog_ok_text">ํ™•์ธ</string>
<string name="dialog_title_text">Title</string>

<!-- updateDialog -->
<string name="update_dialog_title">์ƒˆ๋กœ์šด ๋ฒ„์ „์ด ์—…๋ฐ์ดํŠธ ๋˜์—ˆ์–ด์š”</string>
<string name="update_dialog_body">์ƒˆ๋กœ์šด ๋ฒ„์ „์œผ๋กœ ์—…๋ฐ์ดํŠธ ํ•˜์‹œ๊ฒ ์Šต๋‹ˆ๊นŒ?</string>
<string name="update_dialog_ok">์—…๋ฐ์ดํŠธ</string>

<!-- createShortGame -->
<string name="create_short_game_title">ํ•œํŒ์Šน๋ถ€</string>
<string name="create_short_game_select_mission">๋ฏธ์…˜ ์นดํ…Œ๊ณ ๋ฆฌ ์„ ํƒํ•˜๊ธฐ</string>
Expand Down
Loading