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

Hack week: Update target SDK from 31 to 33 #8538

Merged
merged 24 commits into from
Apr 20, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
24 commits
Select commit Hold shift + click to select a range
0cce6ac
Update resources
0nko Mar 10, 2023
bef40ca
Add new notifications permission bar view
0nko Mar 10, 2023
2eaf798
Add the new permission and the associated helper functions
0nko Mar 10, 2023
c82b3ae
Add a preference to remember notification bar dismissal
0nko Mar 10, 2023
3424d07
Clean up code
0nko Mar 11, 2023
4738c2b
Update margins and background colors
0nko Mar 11, 2023
8dab2c5
Update target SDK to 33
0nko Mar 11, 2023
2ee0173
Update Gradle version to 7.3.0 due to target SDK update
0nko Mar 11, 2023
e954703
Move the package namespace declarations from manifest to gradle files
0nko Mar 11, 2023
2636823
Revert "Update Gradle version to 7.3.0 due to target SDK update"
0nko Mar 14, 2023
630139c
Move the notification permission bar display logic to the presenter
0nko Mar 14, 2023
8ef3f08
Merge branch 'trunk' into hackweek/notifications-permission
0nko Mar 29, 2023
a7e3020
Merge branch 'trunk' into hackweek/notifications-permission
0nko Apr 17, 2023
c2b8221
Update the MediaPicker library to 0.1.2 and make the necessary changes
0nko Apr 17, 2023
dbceea7
Add the missing string
0nko Apr 18, 2023
669c94b
Merge branch 'trunk' into hackweek/notifications-permission
0nko Apr 18, 2023
f45f432
Merge branch 'trunk' into hackweek/notifications-permission
0nko Apr 20, 2023
99fb2fd
Move notification permission bar logic to the ViewModel
0nko Apr 20, 2023
48b1b9c
Remove the card style from the onboarding card
0nko Apr 20, 2023
0a8efd8
Convert the notifications permission bar view to Compose UI
0nko Apr 20, 2023
7d668bd
Remove the old view
0nko Apr 20, 2023
0dec1cc
Add the icon back
0nko Apr 20, 2023
a4dc842
Fix ktlint issues
0nko Apr 20, 2023
97af4d7
Fix the color reference
0nko Apr 20, 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
2 changes: 2 additions & 0 deletions WooCommerce/build.gradle
Original file line number Diff line number Diff line change
Expand Up @@ -66,6 +66,8 @@ repositories {
}

android {
namespace "com.woocommerce.android"

compileSdkVersion gradle.ext.compileSdkVersion

defaultConfig {
Expand Down
3 changes: 1 addition & 2 deletions WooCommerce/src/debug/AndroidManifest.xml
Original file line number Diff line number Diff line change
@@ -1,8 +1,7 @@
<?xml version="1.0" encoding="utf-8"?>

<manifest xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
package="com.woocommerce.android">
xmlns:tools="http://schemas.android.com/tools">

<!-- Allows unlocking your device and activating its screen so UI tests can succeed -->
<uses-permission android:name="android.permission.DISABLE_KEYGUARD" />
Expand Down
4 changes: 2 additions & 2 deletions WooCommerce/src/main/AndroidManifest.xml
Original file line number Diff line number Diff line change
@@ -1,7 +1,6 @@
<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
package="com.woocommerce.android">
xmlns:tools="http://schemas.android.com/tools">

<!-- Mark the camera as optional, as the back camera is missing from some ChromeOS devices -->
<uses-feature
Expand All @@ -14,6 +13,7 @@
<uses-permission android:name="android.permission.WAKE_LOCK" />
<uses-permission android:name="android.permission.ACTION_OPEN_DOCUMENT" />
<uses-permission android:name="android.permission.NFC" />
<uses-permission android:name="android.permission.POST_NOTIFICATIONS"/>

<application
android:name=".WooCommerce"
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -107,6 +107,7 @@ object AppPrefs {
CUSTOM_DOMAINS_SOURCE,
IS_TAP_TO_PAY_BETA_ENABLED,
JETPACK_INSTALLATION_FROM_BANNER,
NOTIFICATIONS_PERMISSION_BAR,
}

/**
Expand Down Expand Up @@ -864,6 +865,12 @@ object AppPrefs {

fun getJetpackInstallationIsFromBanner() = getBoolean(DeletablePrefKey.JETPACK_INSTALLATION_FROM_BANNER, false)

fun setWasNotificationsPermissionBarDismissed(source: Boolean) {
setBoolean(DeletablePrefKey.NOTIFICATIONS_PERMISSION_BAR, source)
}

fun getWasNotificationsPermissionBarDismissed() = getBoolean(DeletablePrefKey.NOTIFICATIONS_PERMISSION_BAR, false)

private fun getActiveStatsGranularityFilterKey(currentSiteId: Int) =
PrefKeyString("${DeletablePrefKey.ACTIVE_STATS_GRANULARITY}:$currentSiteId")

Expand Down
Original file line number Diff line number Diff line change
@@ -1,11 +1,13 @@
package com.woocommerce.android.mediapicker

import com.woocommerce.android.R
import org.wordpress.android.mediapicker.api.MediaPickerSetup
import org.wordpress.android.mediapicker.api.MediaPickerSetup.DataSource
import org.wordpress.android.mediapicker.api.MediaPickerSetup.DataSource.CAMERA
import org.wordpress.android.mediapicker.api.MediaPickerSetup.DataSource.DEVICE
import org.wordpress.android.mediapicker.api.MediaPickerSetup.DataSource.SYSTEM_PICKER
import org.wordpress.android.mediapicker.api.MediaPickerSetup.DataSource.WP_MEDIA_LIBRARY
import org.wordpress.android.mediapicker.api.MediaPickerSetup.SearchMode.VISIBLE_UNTOGGLED
import org.wordpress.android.mediapicker.model.MediaTypes
import org.wordpress.android.mediapicker.source.device.DeviceMediaPickerSetup
import org.wordpress.android.mediapicker.source.wordpress.MediaLibraryPickerSetup
Expand All @@ -20,9 +22,14 @@ class MediaPickerSetupFactory @Inject constructor() : MediaPickerSetup.Factory {
mediaTypes = MediaTypes.IMAGES,
canMultiSelect = isMultiSelectAllowed
)
DEVICE -> DeviceMediaPickerSetup.buildMediaPicker(
mediaTypes = MediaTypes.IMAGES,
canMultiSelect = true
DEVICE -> MediaPickerSetup(
primaryDataSource = DEVICE,
isMultiSelectEnabled = isMultiSelectAllowed,
areResultsQueued = false,
searchMode = VISIBLE_UNTOGGLED,
availableDataSources = setOf(SYSTEM_PICKER),
allowedTypes = MediaTypes.IMAGES.allowedTypes,
title = R.string.photo_picker_title
)
SYSTEM_PICKER -> DeviceMediaPickerSetup.buildSystemPicker(
mediaTypes = MediaTypes.IMAGES,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2,21 +2,27 @@

package com.woocommerce.android.ui.main

import NotificationsPermissionCard
import android.animation.ValueAnimator
import android.app.Activity
import android.app.ProgressDialog
import android.content.Intent
import android.net.Uri
import android.os.Build.VERSION
import android.os.Build.VERSION_CODES
import android.os.Bundle
import android.os.Handler
import android.text.method.LinkMovementMethod
import android.view.Menu
import android.view.MenuItem
import android.view.View
import android.view.animation.AccelerateDecelerateInterpolator
import androidx.activity.result.contract.ActivityResultContracts.RequestPermission
import androidx.activity.viewModels
import androidx.annotation.StringRes
import androidx.appcompat.app.AppCompatDelegate
import androidx.appcompat.widget.Toolbar
import androidx.compose.ui.platform.ViewCompositionStrategy
import androidx.coordinatorlayout.widget.CoordinatorLayout
import androidx.core.content.ContextCompat
import androidx.core.splashscreen.SplashScreen.Companion.installSplashScreen
Expand Down Expand Up @@ -55,6 +61,7 @@ import com.woocommerce.android.ui.appwidgets.WidgetUpdater
import com.woocommerce.android.ui.base.BaseFragment
import com.woocommerce.android.ui.base.TopLevelFragment
import com.woocommerce.android.ui.base.UIMessageResolver
import com.woocommerce.android.ui.compose.theme.WooThemeWithBackground
import com.woocommerce.android.ui.feedback.SurveyType
import com.woocommerce.android.ui.login.LoginActivity
import com.woocommerce.android.ui.main.BottomNavigationPosition.MORE
Expand All @@ -64,6 +71,7 @@ import com.woocommerce.android.ui.main.BottomNavigationPosition.PRODUCTS
import com.woocommerce.android.ui.main.MainActivityViewModel.BottomBarState
import com.woocommerce.android.ui.main.MainActivityViewModel.MoreMenuBadgeState.Hidden
import com.woocommerce.android.ui.main.MainActivityViewModel.MoreMenuBadgeState.UnseenReviews
import com.woocommerce.android.ui.main.MainActivityViewModel.RequestNotificationsPermission
import com.woocommerce.android.ui.main.MainActivityViewModel.RestartActivityForAppLink
import com.woocommerce.android.ui.main.MainActivityViewModel.RestartActivityForNotification
import com.woocommerce.android.ui.main.MainActivityViewModel.ShortcutOpenOrderCreation
Expand All @@ -89,9 +97,9 @@ import com.woocommerce.android.ui.plans.trial.DetermineTrialStatusBarState.Trial
import com.woocommerce.android.ui.prefs.AppSettingsActivity
import com.woocommerce.android.ui.products.ProductListFragmentDirections
import com.woocommerce.android.ui.reviews.ReviewListFragmentDirections
import com.woocommerce.android.util.WooAnimUtils
import com.woocommerce.android.util.WooAnimUtils.Duration
import com.woocommerce.android.util.WooAnimUtils.animateBottomBar
import com.woocommerce.android.util.WooPermissionUtils
import com.woocommerce.android.widgets.AppRatingDialog
import com.woocommerce.android.widgets.DisabledAppBarLayoutBehavior
import dagger.hilt.android.AndroidEntryPoint
Expand Down Expand Up @@ -126,6 +134,8 @@ class MainActivity :
const val FIELD_OPENED_FROM_WIDGET = "opened-from-push-widget"
const val FIELD_WIDGET_NAME = "widget-name"

const val NOTIFICATIONS_PERMISSION_BAR_DISPLAY_DELAY = 2000L

interface BackPressListener {
fun onRequestAllowBackPress(): Boolean
}
Expand Down Expand Up @@ -224,6 +234,12 @@ class MainActivity :
}
}

private val launcher = this.registerForActivityResult(RequestPermission()) { isGranted: Boolean ->
if (isGranted) {
viewModel.checkForNotificationsPermission(hasNotificationsPermission = true)
}
}

override fun onCreateOptionsMenu(menu: Menu): Boolean {
this.menu = menu
return super.onCreateOptionsMenu(menu)
Expand Down Expand Up @@ -312,6 +328,10 @@ class MainActivity :

if (selectedSite.exists()) {
updateOrderBadge(false)

if (VERSION.SDK_INT >= VERSION_CODES.TIRAMISU) {
viewModel.checkForNotificationsPermission(WooPermissionUtils.hasNotificationsPermission(this))
}
}

checkConnection()
Expand Down Expand Up @@ -707,26 +727,51 @@ class MainActivity :
is RestartActivityForAppLink -> restartActivityForAppLink(event)
is ShowFeatureAnnouncement -> navigateToFeatureAnnouncement(event)
is ViewUrlInWebView -> navigateToWebView(event)
is RequestNotificationsPermission -> requestNotificationsPermission()
ViewPayments -> showPayments()
ViewTapToPay -> showTapToPaySummary()
ShortcutOpenPayments -> shortcutShowPayments()
ShortcutOpenOrderCreation -> shortcutOpenOrderCreation()
}
}

observeNotificationsPermissionBarVisibility()
observeMoreMenuBadgeStateEvent()
observeTrialStatus()
observeBottomBarState()
}

private fun observeNotificationsPermissionBarVisibility() {
viewModel.isNotificationsPermissionCardVisible.observe(this) { isVisible ->
if (isVisible) {
binding.notificationsPermissionBar.apply {
setViewCompositionStrategy(ViewCompositionStrategy.DisposeOnViewTreeLifecycleDestroyed)
setContent {
WooThemeWithBackground {
NotificationsPermissionCard()
}
}
}
Handler().postDelayed(
{
animateBottomBar(binding.notificationsPermissionBar, show = true)
},
NOTIFICATIONS_PERMISSION_BAR_DISPLAY_DELAY
)
} else {
animateBottomBar(binding.notificationsPermissionBar, show = false)
}
}
}

private fun observeBottomBarState() {
viewModel.bottomBarState.observe(this) { bottomBarState ->
val show = when (bottomBarState) {
BottomBarState.Hidden -> false
BottomBarState.Visible -> true
}

WooAnimUtils.animateBottomBar(binding.bottomNav, show, Duration.MEDIUM)
animateBottomBar(binding.bottomNav, show, Duration.MEDIUM)
}
}

Expand Down Expand Up @@ -756,6 +801,12 @@ class MainActivity :
}
}

private fun requestNotificationsPermission() {
if (VERSION.SDK_INT >= VERSION_CODES.TIRAMISU) {
WooPermissionUtils.requestNotificationsPermission(launcher)
}
}

private fun navigateToFeatureAnnouncement(event: ShowFeatureAnnouncement) {
val action = NavGraphMainDirections.actionOpenWhatsnewFromMain(event.announcement)
navController.navigateSafely(action)
Expand Down
Original file line number Diff line number Diff line change
@@ -1,6 +1,8 @@
package com.woocommerce.android.ui.main

import android.net.Uri
import android.os.Build.VERSION
import android.os.Build.VERSION_CODES
import androidx.lifecycle.SavedStateHandle
import androidx.lifecycle.asLiveData
import com.woocommerce.android.AppPrefs
Expand All @@ -16,6 +18,8 @@ import com.woocommerce.android.push.NotificationChannelType
import com.woocommerce.android.push.NotificationMessageHandler
import com.woocommerce.android.push.UnseenReviewsCountHandler
import com.woocommerce.android.tools.SelectedSite
import com.woocommerce.android.tools.SiteConnectionType.Jetpack
import com.woocommerce.android.tools.connectionType
import com.woocommerce.android.ui.main.MainActivityViewModel.MoreMenuBadgeState.Hidden
import com.woocommerce.android.ui.main.MainActivityViewModel.MoreMenuBadgeState.UnseenReviews
import com.woocommerce.android.ui.plans.trial.DetermineTrialStatusBarState
Expand All @@ -28,6 +32,7 @@ import com.woocommerce.android.viewmodel.ScopedViewModel
import dagger.hilt.android.lifecycle.HiltViewModel
import kotlinx.coroutines.flow.MutableStateFlow
import kotlinx.coroutines.flow.map
import kotlinx.coroutines.flow.update
import kotlinx.coroutines.launch
import org.wordpress.android.fluxc.store.SiteStore
import javax.inject.Inject
Expand All @@ -44,7 +49,7 @@ class MainActivityViewModel @Inject constructor(
private val analyticsTrackerWrapper: AnalyticsTrackerWrapper,
private val resolveAppLink: ResolveAppLink,
unseenReviewsCountHandler: UnseenReviewsCountHandler,
private val determineTrialStatusBarState: DetermineTrialStatusBarState,
determineTrialStatusBarState: DetermineTrialStatusBarState,
) : ScopedViewModel(savedState) {
init {
launch {
Expand All @@ -61,6 +66,9 @@ class MainActivityViewModel @Inject constructor(
private val _bottomBarState: MutableStateFlow<BottomBarState> = MutableStateFlow(BottomBarState.Visible)
val bottomBarState = _bottomBarState.asLiveData()

private val _isNotificationPermissionCardVisible = MutableStateFlow(false)
val isNotificationsPermissionCardVisible = _isNotificationPermissionCardVisible.asLiveData()

val trialStatusBarState = determineTrialStatusBarState(_bottomBarState).asLiveData()

fun handleShortcutAction(action: String?) {
Expand Down Expand Up @@ -202,6 +210,14 @@ class MainActivityViewModel @Inject constructor(
}
}

fun checkForNotificationsPermission(hasNotificationsPermission: Boolean) {
val shouldShowNotificationsPermissionBar = VERSION.SDK_INT >= VERSION_CODES.TIRAMISU &&
!hasNotificationsPermission && !AppPrefs.getWasNotificationsPermissionBarDismissed() &&
selectedSite.get().connectionType == Jetpack

_isNotificationPermissionCardVisible.update { shouldShowNotificationsPermissionBar }
}

fun hideBottomNav() {
_bottomBarState.value = BottomBarState.Hidden
}
Expand All @@ -210,12 +226,22 @@ class MainActivityViewModel @Inject constructor(
_bottomBarState.value = BottomBarState.Visible
}

fun onNotificationsPermissionBarDismissButtonTapped() {
AppPrefs.setWasNotificationsPermissionBarDismissed(true)
_isNotificationPermissionCardVisible.update { false }
}

fun onNotificationsPermissionBarAllowButtonTapped() {
triggerEvent(RequestNotificationsPermission)
}

object ViewOrderList : Event()
object ViewReviewList : Event()
object ViewMyStoreStats : Event()
object ViewZendeskTickets : Event()
object ViewPayments : Event()
object ViewTapToPay : Event()
object RequestNotificationsPermission : Event()
data class ViewUrlInWebView(val url: String) : Event()
object ShortcutOpenPayments : Event()
object ShortcutOpenOrderCreation : Event()
Expand Down
Loading