Skip to content
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
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@ import android.os.Build.VERSION
import android.os.Build.VERSION_CODES
import android.os.Bundle
import android.os.Handler
import android.os.Parcelable
import android.text.method.LinkMovementMethod
import android.view.Menu
import android.view.MenuItem
Expand Down Expand Up @@ -96,6 +97,7 @@ import com.woocommerce.android.ui.plans.di.StartUpgradeFlowFactory
import com.woocommerce.android.ui.plans.di.TrialStatusBarFormatterFactory
import com.woocommerce.android.ui.plans.trial.DetermineTrialStatusBarState.TrialStatusBarState
import com.woocommerce.android.ui.prefs.AppSettingsActivity
import com.woocommerce.android.ui.prefs.RequestedAnalyticsValue
import com.woocommerce.android.ui.products.ProductListFragmentDirections
import com.woocommerce.android.ui.reviews.ReviewListFragmentDirections
import com.woocommerce.android.util.ChromeCustomTabUtils
Expand Down Expand Up @@ -596,6 +598,17 @@ class MainActivity :
startActivityForResult(intent, RequestCodes.SETTINGS)
}

private fun showPrivacySettingsScreen(requestedAnalyticsValue: Parcelable) {
val intent = Intent(this, AppSettingsActivity::class.java).apply {
putExtra(AppSettingsActivity.EXTRA_SHOW_PRIVACY_SETTINGS, true)
putExtra(
AppSettingsActivity.EXTRA_REQUESTED_ANALYTICS_VALUE_FROM_ERROR,
requestedAnalyticsValue
)
}
startActivityForResult(intent, RequestCodes.SETTINGS)
}

override fun showAnalytics(targetPeriod: StatsTimeRangeSelection.SelectionType) {
val action = MyStoreFragmentDirections.actionMyStoreToAnalytics(targetPeriod)
navController.navigateSafely(action)
Expand Down Expand Up @@ -749,6 +762,12 @@ class MainActivity :
viewModel.onRequestPrivacyUpdate(event.analyticsEnabled)
}.show()
}
MainActivityViewModel.ShowPrivacySettings -> {
showPrivacySettingsScreen(RequestedAnalyticsValue.NONE)
}
is MainActivityViewModel.ShowPrivacySettingsWithError -> {
showPrivacySettingsScreen(event.requestedAnalyticsValue)
}
}
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,7 @@ import com.woocommerce.android.ui.moremenu.MoreMenuNewFeature
import com.woocommerce.android.ui.moremenu.MoreMenuNewFeatureHandler
import com.woocommerce.android.ui.plans.trial.DetermineTrialStatusBarState
import com.woocommerce.android.ui.prefs.PrivacySettingsRepository
import com.woocommerce.android.ui.prefs.RequestedAnalyticsValue
import com.woocommerce.android.ui.whatsnew.FeatureAnnouncementRepository
import com.woocommerce.android.util.BuildConfigWrapper
import com.woocommerce.android.util.WooLog
Expand Down Expand Up @@ -270,6 +271,14 @@ class MainActivityViewModel @Inject constructor(
}
}

fun onPrivacySettingsTapped() {
triggerEvent(ShowPrivacySettings)
}

fun onSettingsPrivacyPreferenceUpdateFailed(requestedAnalyticsPreference: RequestedAnalyticsValue) {
triggerEvent(ShowPrivacySettingsWithError(requestedAnalyticsPreference))
}

object ViewOrderList : Event()
object ViewReviewList : Event()
object ViewMyStoreStats : Event()
Expand All @@ -286,6 +295,8 @@ class MainActivityViewModel @Inject constructor(
data class ViewReviewDetail(val uniqueId: Long) : Event()
data class ViewOrderDetail(val uniqueId: Long, val remoteNoteId: Long) : Event()
data class ShowPrivacyPreferenceUpdatedFailed(val analyticsEnabled: Boolean) : Event()
object ShowPrivacySettings : Event()
data class ShowPrivacySettingsWithError(val requestedAnalyticsValue: RequestedAnalyticsValue) : Event()

sealed class MoreMenuBadgeState {
data class UnseenReviews(val count: Int) : MoreMenuBadgeState()
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,7 @@ import com.woocommerce.android.ui.main.AppBarStatus
import com.woocommerce.android.ui.main.MainActivity
import com.woocommerce.android.ui.prefs.MainSettingsFragment.AppSettingsListener
import com.woocommerce.android.util.AnalyticsUtils
import com.woocommerce.android.util.parcelable
import dagger.android.DispatchingAndroidInjector
import dagger.hilt.android.AndroidEntryPoint
import javax.inject.Inject
Expand All @@ -37,6 +38,8 @@ class AppSettingsActivity :
AppSettingsListener,
AppSettingsContract.View {
companion object {
const val EXTRA_SHOW_PRIVACY_SETTINGS = "extra_show_privacy_settings"
const val EXTRA_REQUESTED_ANALYTICS_VALUE_FROM_ERROR = "extra_requested_analytics_value_from_error"
const val RESULT_CODE_BETA_OPTIONS_CHANGED = 2
const val KEY_BETA_OPTION_CHANGED = "key_beta_option_changed"
}
Expand Down Expand Up @@ -75,6 +78,19 @@ class AppSettingsActivity :
if (isBetaOptionChanged) {
setResult(RESULT_CODE_BETA_OPTIONS_CHANGED)
}

if (intent.getBooleanExtra(EXTRA_SHOW_PRIVACY_SETTINGS, false)) {

val requestedAnalyticsValue =
intent.parcelable(EXTRA_REQUESTED_ANALYTICS_VALUE_FROM_ERROR)
?: RequestedAnalyticsValue.NONE

navHostFragment.navController.navigate(
MainSettingsFragmentDirections.actionMainSettingsFragmentToPrivacySettingsFragment(
requestedAnalyticsValue
)
)
}
}

private val fragmentLifecycleObserver: FragmentLifecycleCallbacks = object : FragmentLifecycleCallbacks() {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -184,7 +184,11 @@ class MainSettingsFragment : Fragment(R.layout.fragment_settings_main), MainSett

binding.optionPrivacy.setOnClickListener {
AnalyticsTracker.track(SETTINGS_PRIVACY_SETTINGS_BUTTON_TAPPED)
findNavController().navigateSafely(R.id.action_mainSettingsFragment_to_privacySettingsFragment)
findNavController().navigateSafely(
MainSettingsFragmentDirections.actionMainSettingsFragmentToPrivacySettingsFragment(
RequestedAnalyticsValue.NONE
)
)
}

binding.optionSendFeedback.setOnClickListener {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@ import com.woocommerce.android.viewmodel.MultiLiveEvent
import com.woocommerce.android.viewmodel.ResourceProvider
import com.woocommerce.android.viewmodel.ScopedViewModel
import com.woocommerce.android.viewmodel.combineWith
import com.woocommerce.android.viewmodel.navArgs
import dagger.hilt.android.lifecycle.HiltViewModel
import kotlinx.coroutines.launch
import javax.inject.Inject
Expand All @@ -24,6 +25,8 @@ class PrivacySettingsViewModel @Inject constructor(
private val repository: PrivacySettingsRepository,
) : ScopedViewModel(savedState) {

private val args: PrivacySettingsFragmentArgs by savedState.navArgs()

private val analyticsEnabled: LiveData<Boolean> = analyticsTrackerWrapper
.observeSendUsageStats()
.asLiveData()
Expand Down Expand Up @@ -60,6 +63,17 @@ class PrivacySettingsViewModel @Inject constructor(
}
)
}

if (args.requestedAnalyticsValue != RequestedAnalyticsValue.NONE) {
val checked =
args.requestedAnalyticsValue == RequestedAnalyticsValue.ENABLED

triggerEvent(
MultiLiveEvent.Event.ShowActionSnackbar(
resourceProvider.getString(R.string.settings_tracking_analytics_error_update)
) { onSendStatsSettingChanged(checked) }
)
}
}
}
}
Expand Down Expand Up @@ -100,6 +114,7 @@ class PrivacySettingsViewModel @Inject constructor(

event.fold(
onSuccess = {
appPrefs.savedPrivacyBannerSettings = true
analyticsTrackerWrapper.sendUsageStats = checked
},
onFailure = {
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
package com.woocommerce.android.ui.prefs

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

@Parcelize
enum class RequestedAnalyticsValue : Parcelable {
NONE, ENABLED, DISABLE
}
Original file line number Diff line number Diff line change
Expand Up @@ -37,13 +37,23 @@ class PrivacyBannerFragment : WCBottomSheetDialogFragment() {
viewModel.event.observe(viewLifecycleOwner) { event ->
when (event) {
is PrivacyBannerViewModel.ShowError -> {
mainViewModel.onPrivacyPreferenceUpdateFailed(event.requestedChange)
mainViewModel.onPrivacyPreferenceUpdateFailed(event.requestedAnalyticsValue)
dismiss()
}

is PrivacyBannerViewModel.Dismiss -> {
dismiss()
}

is PrivacyBannerViewModel.ShowSettings -> {
mainViewModel.onPrivacySettingsTapped()
dismiss()
}

is PrivacyBannerViewModel.ShowErrorOnSettings -> {
mainViewModel.onSettingsPrivacyPreferenceUpdateFailed(event.requestedAnalyticsValue)
dismiss()
}
}
}
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -44,7 +44,8 @@ fun PrivacyBannerScreen(viewModel: PrivacyBannerViewModel) {
PrivacyBannerScreen(
state,
viewModel::onSwitchChanged,
viewModel::onSavePressed
viewModel::onSavePressed,
viewModel::onSettingsPressed,
)
}

Expand All @@ -53,6 +54,7 @@ fun PrivacyBannerScreen(
state: PrivacyBannerViewModel.State,
onSwitchChanged: (Boolean) -> Unit,
onSavePressed: () -> Unit,
onSettingsPressed: () -> Unit,
) {
Box(Modifier.background(MaterialTheme.colors.surface)) {
Column(
Expand Down Expand Up @@ -120,7 +122,7 @@ fun PrivacyBannerScreen(
hoveredElevation = 0.dp,
focusedElevation = 0.dp
),
onClick = { /*TODO*/ }
onClick = onSettingsPressed
) {
Text(stringResource(R.string.privacy_banner_settings))
}
Expand Down Expand Up @@ -178,7 +180,7 @@ private fun Default() {
analyticsSwitchEnabled = false,
loading = true
),
{}, {}
{}, {}, {}
)
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@ import androidx.lifecycle.SavedStateHandle
import com.woocommerce.android.AppPrefsWrapper
import com.woocommerce.android.analytics.AnalyticsTrackerWrapper
import com.woocommerce.android.ui.prefs.PrivacySettingsRepository
import com.woocommerce.android.ui.prefs.RequestedAnalyticsValue
import com.woocommerce.android.viewmodel.MultiLiveEvent
import com.woocommerce.android.viewmodel.ScopedViewModel
import dagger.hilt.android.lifecycle.HiltViewModel
Expand All @@ -20,10 +21,11 @@ class PrivacyBannerViewModel @Inject constructor(
private val repository: PrivacySettingsRepository,
) : ScopedViewModel(savedStateHandle) {

private val initialUserPreference: Boolean = analyticsTrackerWrapper.sendUsageStats

private val _state: MutableLiveData<State> = MutableLiveData(
State(
analyticsSwitchEnabled = analyticsTrackerWrapper.sendUsageStats,
loading = false
analyticsSwitchEnabled = initialUserPreference, loading = false
)
)

Expand All @@ -33,6 +35,45 @@ class PrivacyBannerViewModel @Inject constructor(
_state.value = _state.value?.copy(analyticsSwitchEnabled = checked)
}

fun onSettingsPressed() {
val analyticsPreference = _state.value?.analyticsSwitchEnabled ?: false

if (analyticsPreference == initialUserPreference) {
appPrefsWrapper.savedPrivacyBannerSettings = true
triggerEvent(ShowSettings)
return
}

launch {
if (repository.isUserWPCOM()) {
_state.value = _state.value?.copy(loading = true)
val event =
repository.updateTracksSetting(_state.value?.analyticsSwitchEnabled ?: false)
_state.value = _state.value?.copy(loading = false)

event.fold(
onSuccess = {
appPrefsWrapper.savedPrivacyBannerSettings = true
analyticsTrackerWrapper.sendUsageStats = analyticsPreference
triggerEvent(ShowSettings)
},
onFailure = {
triggerEvent(
ShowErrorOnSettings(
requestedAnalyticsValue = if (analyticsPreference) RequestedAnalyticsValue.ENABLED
else RequestedAnalyticsValue.DISABLE
)
)
}
)
} else {
appPrefsWrapper.savedPrivacyBannerSettings = true
analyticsTrackerWrapper.sendUsageStats = analyticsPreference
triggerEvent(ShowSettings)
}
}
Comment on lines +47 to +74
Copy link
Contributor

Choose a reason for hiding this comment

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

np: We might want to unit test this in the future

}

fun onSavePressed() {
val analyticsPreference = _state.value?.analyticsSwitchEnabled ?: false

Expand All @@ -50,7 +91,7 @@ class PrivacyBannerViewModel @Inject constructor(
triggerEvent(Dismiss)
},
onFailure = {
triggerEvent(ShowError(requestedChange = analyticsPreference))
triggerEvent(ShowError(requestedAnalyticsValue = analyticsPreference))
}
)
} else {
Expand All @@ -67,5 +108,9 @@ class PrivacyBannerViewModel @Inject constructor(
)

object Dismiss : MultiLiveEvent.Event()
data class ShowError(val requestedChange: Boolean) : MultiLiveEvent.Event()
data class ShowError(val requestedAnalyticsValue: Boolean) : MultiLiveEvent.Event()
object ShowSettings : MultiLiveEvent.Event()
data class ShowErrorOnSettings(
val requestedAnalyticsValue: RequestedAnalyticsValue
) : MultiLiveEvent.Event()
}
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,8 @@ import android.content.Context
import android.content.Intent
import android.content.pm.PackageManager
import android.net.Uri
import android.os.Build.VERSION.SDK_INT
import android.os.Parcelable
import androidx.core.content.FileProvider
import com.woocommerce.android.R
import com.woocommerce.android.extensions.intentActivities
Expand Down Expand Up @@ -140,3 +142,9 @@ object ActivityUtils {
context.startActivity(Intent.createChooser(sendIntent, title))
}
}

@Suppress("MagicNumber")
Copy link
Contributor

Choose a reason for hiding this comment

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

Nice!

inline fun <reified T : Parcelable> Intent.parcelable(key: String): T? = when {
SDK_INT >= 33 -> getParcelableExtra(key, T::class.java)
else -> @Suppress("DEPRECATION") getParcelableExtra(key) as? T
}
5 changes: 4 additions & 1 deletion WooCommerce/src/main/res/navigation/nav_graph_settings.xml
Original file line number Diff line number Diff line change
Expand Up @@ -48,7 +48,10 @@
<fragment
android:id="@+id/privacySettingsFragment"
android:name="com.woocommerce.android.ui.prefs.PrivacySettingsFragment"
android:label="PrivacySettingsFragment" >
android:label="PrivacySettingsFragment">
<argument
android:name="requestedAnalyticsValue"
app:argType="com.woocommerce.android.ui.prefs.RequestedAnalyticsValue" />
<action
android:id="@+id/action_privacySettingsFragment_to_privacySettingsPolicesFragment"
app:destination="@id/privacySettingsPolicesFragment" />
Expand Down