Skip to content

Commit

Permalink
Merge pull request #231 from team-winey/feature/feat-fcm-permission
Browse files Browse the repository at this point in the history
[feat] ํ‘ธ์‰ฌ์•Œ๋ฆผ / ์•Œ๋ฆผ๊ถŒํ•œ ์š”์ฒญ
  • Loading branch information
Sangwook123 authored Jan 10, 2024
2 parents 31abbd4 + b8f383e commit a3184ed
Show file tree
Hide file tree
Showing 6 changed files with 233 additions and 29 deletions.
3 changes: 3 additions & 0 deletions app/src/main/AndroidManifest.xml
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,9 @@

<uses-permission android:name="android.permission.INTERNET" />
<uses-permission android:name="android.permission.READ_PHONE_STATE" />
<uses-permission
android:name="android.permission.POST_NOTIFICATIONS"
android:minSdkVersion="33" />

<application
android:name=".WineyApplication"
Expand Down
Original file line number Diff line number Diff line change
@@ -1,8 +1,13 @@
package org.go.sopt.winey.presentation.main

import android.Manifest
import android.content.Intent
import android.content.pm.PackageManager
import android.os.Build
import android.os.Bundle
import androidx.activity.result.contract.ActivityResultContracts
import androidx.activity.viewModels
import androidx.core.content.ContextCompat
import androidx.fragment.app.Fragment
import androidx.fragment.app.commit
import androidx.fragment.app.replace
Expand Down Expand Up @@ -35,10 +40,22 @@ class MainActivity : BindingActivity<ActivityMainBinding>(R.layout.activity_main
private val prevScreenName by lazy { intent.extras?.getString(KEY_PREV_SCREEN, "") }
private val notiType by lazy { intent.extras?.getString(KEY_NOTI_TYPE, "") }
private val feedId by lazy { intent.extras?.getString(KEY_FEED_ID) }
private val notificationPermissionLauncher =
registerForActivityResult(ActivityResultContracts.RequestPermission()) { isGranted ->
if (!isGranted) {
wineySnackbar(
anchorView = binding.root,
isSuccess = false,
message = stringOf(R.string.snackbar_notification_permission_fail)
)
}
}

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

requestNotificationPermission()

// ์œ„๋‹ˆํ”ผ๋“œ, ๋งˆ์ดํŽ˜์ด์ง€ ํ”„๋ž˜๊ทธ๋จผํŠธ์—์„œ getUserState ๊ด€์ฐฐ
mainViewModel.getUser()
mainViewModel.patchFcmToken()
Expand All @@ -51,6 +68,16 @@ class MainActivity : BindingActivity<ActivityMainBinding>(R.layout.activity_main
showSuccessSnackBar()
}

private fun requestNotificationPermission() {
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.TIRAMISU && ContextCompat.checkSelfPermission(
this,
Manifest.permission.POST_NOTIFICATIONS
) == PackageManager.PERMISSION_DENIED
) {
notificationPermissionLauncher.launch(Manifest.permission.POST_NOTIFICATIONS)
}
}

private fun initNotiTypeHandler() {
val notificationType = NotificationType.values().find { it.key == notiType }
when (notificationType) {
Expand All @@ -61,9 +88,11 @@ class MainActivity : BindingActivity<ActivityMainBinding>(R.layout.activity_main
KEY_FROM_NOTI,
true
)

NotificationType.LIKE_NOTIFICATION, NotificationType.COMMENT_NOTIFICATION
-> navigateToDetail(feedId?.toInt())
else -> navigateToLevelupHelp()
NotificationType.HOW_TO_LEVEL_UP -> navigateToLevelupHelp()
else -> {}
}
}

Expand Down
Original file line number Diff line number Diff line change
@@ -1,10 +1,19 @@
package org.go.sopt.winey.presentation.main.mypage

import android.Manifest
import android.content.ActivityNotFoundException
import android.content.Context
import android.content.Intent
import android.content.pm.PackageManager
import android.net.Uri
import android.os.Build
import android.os.Bundle
import android.provider.Settings
import android.view.View
import androidx.activity.OnBackPressedCallback
import androidx.core.content.ContextCompat
import androidx.core.view.isGone
import androidx.core.view.isVisible
import androidx.fragment.app.Fragment
import androidx.fragment.app.activityViewModels
import androidx.fragment.app.commit
Expand Down Expand Up @@ -34,6 +43,7 @@ import org.go.sopt.winey.util.fragment.snackBar
import org.go.sopt.winey.util.fragment.stringOf
import org.go.sopt.winey.util.fragment.viewLifeCycle
import org.go.sopt.winey.util.fragment.viewLifeCycleScope
import org.go.sopt.winey.util.fragment.wineySnackbar
import org.go.sopt.winey.util.view.UiState
import org.go.sopt.winey.util.view.setOnSingleClickListener
import javax.inject.Inject
Expand All @@ -48,10 +58,12 @@ class MyPageFragment : BindingFragment<FragmentMyPageBinding>(R.layout.fragment_

@Inject
lateinit var amplitudeUtils: AmplitudeUtils
private var isNotificationPermissionAllowed = true

override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
super.onViewCreated(view, savedInstanceState)
amplitudeUtils.logEvent("view_mypage")
initCheckNotificationPermission()

initUserData()
initNavigation()
Expand All @@ -64,6 +76,7 @@ class MyPageFragment : BindingFragment<FragmentMyPageBinding>(R.layout.fragment_
initWithdrawButtonClickListener()
initNicknameButtonClickListener()
initAllowedNotificationButtonClickListener()
initNotificationPermissionChangeButtonClickListener()

registerBackPressedCallback()
setupGetUserState()
Expand All @@ -73,50 +86,128 @@ class MyPageFragment : BindingFragment<FragmentMyPageBinding>(R.layout.fragment_
checkFromWineyFeed()
}

private fun initCheckNotificationPermission() {
isNotificationPermissionAllowed = if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.TIRAMISU) {
ContextCompat.checkSelfPermission(
requireContext(),
Manifest.permission.POST_NOTIFICATIONS
) == PackageManager.PERMISSION_GRANTED
} else {
true
}
}

private fun setupPatchAllowedNotificationState() {
myPageViewModel.patchAllowedNotificationState.flowWithLifecycle(lifecycle).onEach { state ->
when (state) {
is UiState.Success -> {
when (state.data) {
true -> {
binding.ivMypageAgree.transitionToEnd()
binding.ivMypageAgree.transitionToState(R.id.end, -1)
}

false -> {
binding.ivMypageAgree.transitionToStart()
binding.ivMypageAgree.transitionToState(R.id.start, -1)
}

null -> {
binding.ivMypageAgree.transitionToStart()
binding.ivMypageAgree.transitionToState(R.id.start, -1)
}
}
}

is UiState.Failure -> {}
is UiState.Empty -> {}
else -> {}
}
}
}

private fun initAllowedNotificationButtonClickListener() {
binding.ivMypageSwitch.setOnClickListener {
val isAllowed = when (binding.ivMypageAgree.currentState) {
R.id.start -> false
R.id.end -> true
else -> false
}
when (isAllowed) {
when (isNotificationPermissionAllowed) {
true -> {
binding.ivMypageAgree.transitionToStart()
val isAllowed = when (binding.ivMypageAgree.currentState) {
R.id.start -> false
R.id.end -> true
else -> false
}
when (isAllowed) {
true -> {
showNotificationOffDialog(isAllowed)
}

false -> {
binding.ivMypageAgree.transitionToState(R.id.end, -1)
patchUserInfo()
myPageViewModel.patchAllowedNotification(isAllowed)
}
}
}

false -> {
binding.ivMypageAgree.transitionToEnd()
wineySnackbar(
binding.root,
true,
stringOf(R.string.snackbar_notification_permission_fail)
)
}
}
patchUserInfo()
myPageViewModel.patchAllowedNotification(isAllowed)
}
}

private fun showNotificationOffDialog(isAllowed: Boolean) {
val dialog = WineyDialogFragment.newInstance(
WineyDialogLabel(
stringOf(R.string.notification_off_dialog_title),
stringOf(R.string.notification_off_dialog_subtitle),
stringOf(R.string.notification_off_dialog_negative_button),
stringOf(R.string.notification_off_dialog_positive_button)
),
handleNegativeButton = {},
handlePositiveButton = {
binding.ivMypageAgree.transitionToState(R.id.start, -1)
patchUserInfo()
myPageViewModel.patchAllowedNotification(isAllowed)
}
)
dialog.show(
parentFragmentManager,
TAG_NOTIFICATION_OFF_DIALOG
)
}

private fun initNotificationPermissionChangeButtonClickListener() {
binding.llMypageAgreePermissionChange.setOnClickListener {
navigateToNotificationSetting(requireContext())
}
}

private fun navigateToNotificationSetting(context: Context) {
val intent = if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
setNotificationIntentActionOreo(context)
} else {
setNorificationIntentActionOreoLess(context)
}
try {
context.startActivity(intent)
} catch (e: ActivityNotFoundException) {
e.printStackTrace()
}
}

private fun setNotificationIntentActionOreo(context: Context): Intent {
return Intent().also { intent ->
intent.action = Settings.ACTION_APP_NOTIFICATION_SETTINGS
intent.putExtra(Settings.EXTRA_APP_PACKAGE, context.packageName)
intent.flags = Intent.FLAG_ACTIVITY_NEW_TASK
}
}

private fun setNorificationIntentActionOreoLess(context: Context): Intent {
return Intent().also { intent ->
intent.action = "android.settings.APP_NOTIFICATION_SETTINGS"
intent.putExtra("app_package", context.packageName)
intent.putExtra("app_uid", context.applicationInfo?.uid)
intent.flags = Intent.FLAG_ACTIVITY_NEW_TASK
}
}

Expand All @@ -132,6 +223,20 @@ class MyPageFragment : BindingFragment<FragmentMyPageBinding>(R.layout.fragment_
override fun onStart() {
super.onStart()
mainViewModel.getUser()
initCheckNotificationPermission()
changeNotiButtonByPermission()
}

private fun changeNotiButtonByPermission() {
if (isNotificationPermissionAllowed) {
binding.ivMypageAgree.isVisible = true
binding.llMypageAgreePermissionChange.isGone = true
binding.tvMypageAgreePermission.isGone = true
} else {
binding.ivMypageAgree.isGone = true
binding.llMypageAgreePermissionChange.isVisible = true
binding.tvMypageAgreePermission.isVisible = true
}
}

// ์œ„๋‹ˆํ”ผ๋“œ ํ”„๋ž˜๊ทธ๋จผํŠธ์—์„œ ๋งˆ์ดํŽ˜์ด์ง€๋กœ ์ „ํ™˜ ์‹œ, ๋ฐ”ํ…€์‹œํŠธ ๋ฐ”๋กœ ๋„์šฐ๋„๋ก
Expand Down Expand Up @@ -352,14 +457,23 @@ class MyPageFragment : BindingFragment<FragmentMyPageBinding>(R.layout.fragment_
}

private fun updateNotificationAllowSwitchState(data: User) {
when (data.fcmIsAllowed) {
true -> {
binding.ivMypageAgree.transitionToEnd()
}
if (isNotificationPermissionAllowed) {
binding.ivMypageAgree.isVisible = true
binding.llMypageAgreePermissionChange.isGone = true
binding.tvMypageAgreePermission.isGone = true
when (data.fcmIsAllowed) {
true -> {
binding.ivMypageAgree.transitionToState(R.id.end, 1)
}

false -> {
binding.ivMypageAgree.transitionToStart()
false -> {
binding.ivMypageAgree.transitionToState(R.id.start, 1)
}
}
} else {
binding.ivMypageAgree.isGone = true
binding.llMypageAgreePermissionChange.isVisible = true
binding.tvMypageAgreePermission.isVisible = true
}
}

Expand Down Expand Up @@ -412,6 +526,8 @@ class MyPageFragment : BindingFragment<FragmentMyPageBinding>(R.layout.fragment_
private const val VAL_MY_PAGE_SCREEN = "MyPageFragment"
private const val KEY_FROM_NOTI = "fromNoti"
private const val KEY_FROM_WINEY_FEED = "fromWineyFeed"

private const val KEY_TO_MYFEED = "toMyFeed"
private const val TAG_NOTIFICATION_OFF_DIALOG = "offNotification"
}
}
9 changes: 9 additions & 0 deletions app/src/main/res/drawable/ic_mypage_change.xml
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
<vector xmlns:android="http://schemas.android.com/apk/res/android"
android:width="8dp"
android:height="13dp"
android:viewportWidth="8"
android:viewportHeight="13">
<path
android:pathData="M7.79,5.992L2.03,0.24C1.75,-0.048 1.286,-0.048 1.006,0.24C0.87,0.376 0.79,0.56 0.79,0.752C0.79,0.944 0.862,1.128 1.006,1.264L6.246,6.504L1.006,11.744C0.726,12.024 0.726,12.488 1.006,12.768C1.15,12.912 1.334,12.976 1.518,12.976C1.702,12.976 1.894,12.904 2.03,12.76L7.79,7.008C8.07,6.728 8.07,6.256 7.79,5.984V5.992Z"
android:fillColor="#A266FC"/>
</vector>
Loading

0 comments on commit a3184ed

Please sign in to comment.