diff --git a/vector/build.gradle b/vector/build.gradle
index 2fd562fff5..fb1199a497 100644
--- a/vector/build.gradle
+++ b/vector/build.gradle
@@ -236,6 +236,7 @@ android {
// Analytics. Set to empty strings to just disable analytics
buildConfigField "String", "ANALYTICS_POSTHOG_HOST", "\"https://posthog-poc.lab.element.dev\""
buildConfigField "String", "ANALYTICS_POSTHOG_API_KEY", "\"rs-pJjsYJTuAkXJfhaMmPUNBhWliDyTKLOOxike6ck8\""
+ buildConfigField "String", "ANALYTICS_POLICY_URL", "\"https://element.io/cookie-policy\""
signingConfig signingConfigs.debug
}
@@ -250,6 +251,7 @@ android {
// Analytics. Set to empty strings to just disable analytics
buildConfigField "String", "ANALYTICS_POSTHOG_HOST", "\"https://posthog.hss.element.io\""
buildConfigField "String", "ANALYTICS_POSTHOG_API_KEY", "\"phc_Jzsm6DTm6V2705zeU5dcNvQDlonOR68XvX2sh1sEOHO\""
+ buildConfigField "String", "ANALYTICS_POLICY_URL", "\"https://element.io/cookie-policy\""
postprocessing {
removeUnusedCode true
diff --git a/vector/src/main/AndroidManifest.xml b/vector/src/main/AndroidManifest.xml
index 5b56107ef7..7bd9f66b8e 100644
--- a/vector/src/main/AndroidManifest.xml
+++ b/vector/src/main/AndroidManifest.xml
@@ -310,6 +310,7 @@
+
diff --git a/vector/src/main/java/im/vector/app/core/di/FragmentModule.kt b/vector/src/main/java/im/vector/app/core/di/FragmentModule.kt
index b8d00fac5a..dcf3d6d113 100644
--- a/vector/src/main/java/im/vector/app/core/di/FragmentModule.kt
+++ b/vector/src/main/java/im/vector/app/core/di/FragmentModule.kt
@@ -24,6 +24,7 @@ import dagger.Module
import dagger.hilt.InstallIn
import dagger.hilt.android.components.ActivityComponent
import dagger.multibindings.IntoMap
+import im.vector.app.features.analytics.ui.consent.AnalyticsOptInFragment
import im.vector.app.features.attachments.preview.AttachmentsPreviewFragment
import im.vector.app.features.contactsbook.ContactsBookFragment
import im.vector.app.features.crypto.keysbackup.settings.KeysBackupSettingsFragment
@@ -519,6 +520,11 @@ interface FragmentModule {
@FragmentKey(BreadcrumbsFragment::class)
fun bindBreadcrumbsFragment(fragment: BreadcrumbsFragment): Fragment
+ @Binds
+ @IntoMap
+ @FragmentKey(AnalyticsOptInFragment::class)
+ fun bindAnalyticsOptInFragment(fragment: AnalyticsOptInFragment): Fragment
+
@Binds
@IntoMap
@FragmentKey(EmojiChooserFragment::class)
diff --git a/vector/src/main/java/im/vector/app/features/analytics/ui/consent/AnalyticsConsentViewActions.kt b/vector/src/main/java/im/vector/app/features/analytics/ui/consent/AnalyticsConsentViewActions.kt
index b43dc4742a..058ddcba27 100644
--- a/vector/src/main/java/im/vector/app/features/analytics/ui/consent/AnalyticsConsentViewActions.kt
+++ b/vector/src/main/java/im/vector/app/features/analytics/ui/consent/AnalyticsConsentViewActions.kt
@@ -20,5 +20,4 @@ import im.vector.app.core.platform.VectorViewModelAction
sealed class AnalyticsConsentViewActions : VectorViewModelAction {
data class SetUserConsent(val userConsent: Boolean) : AnalyticsConsentViewActions()
- object OnGetStarted : AnalyticsConsentViewActions()
}
diff --git a/vector/src/main/java/im/vector/app/features/analytics/ui/consent/AnalyticsConsentViewModel.kt b/vector/src/main/java/im/vector/app/features/analytics/ui/consent/AnalyticsConsentViewModel.kt
index 4fdbf08c5f..2c7a8ac9bc 100644
--- a/vector/src/main/java/im/vector/app/features/analytics/ui/consent/AnalyticsConsentViewModel.kt
+++ b/vector/src/main/java/im/vector/app/features/analytics/ui/consent/AnalyticsConsentViewModel.kt
@@ -23,7 +23,6 @@ import dagger.assisted.AssistedInject
import im.vector.app.core.di.MavericksAssistedViewModelFactory
import im.vector.app.core.di.hiltMavericksViewModelFactory
import im.vector.app.core.extensions.exhaustive
-import im.vector.app.core.platform.EmptyViewEvents
import im.vector.app.core.platform.VectorViewModel
import im.vector.app.features.analytics.VectorAnalytics
import kotlinx.coroutines.launch
@@ -31,7 +30,7 @@ import kotlinx.coroutines.launch
class AnalyticsConsentViewModel @AssistedInject constructor(
@Assisted initialState: AnalyticsConsentViewState,
private val analytics: VectorAnalytics
-) : VectorViewModel(initialState) {
+) : VectorViewModel(initialState) {
@AssistedFactory
interface Factory : MavericksAssistedViewModelFactory {
@@ -56,24 +55,14 @@ class AnalyticsConsentViewModel @AssistedInject constructor(
override fun handle(action: AnalyticsConsentViewActions) {
when (action) {
is AnalyticsConsentViewActions.SetUserConsent -> handleSetUserConsent(action)
- AnalyticsConsentViewActions.OnGetStarted -> handleOnScreenLeft()
}.exhaustive
}
private fun handleSetUserConsent(action: AnalyticsConsentViewActions.SetUserConsent) {
viewModelScope.launch {
analytics.setUserConsent(action.userConsent)
- if (!action.userConsent) {
- // User explicitly changed the default value, let's avoid reverting to the default value
- analytics.setDidAskUserConsent()
- }
- }
- }
-
- private fun handleOnScreenLeft() {
- // Whatever the state of the box, consider the user acknowledge it
- viewModelScope.launch {
analytics.setDidAskUserConsent()
+ _viewEvents.post(AnalyticsOptInViewEvents.OnDataSaved)
}
}
}
diff --git a/vector/src/main/java/im/vector/app/features/analytics/ui/consent/AnalyticsOptInActivity.kt b/vector/src/main/java/im/vector/app/features/analytics/ui/consent/AnalyticsOptInActivity.kt
new file mode 100644
index 0000000000..5fca7476f2
--- /dev/null
+++ b/vector/src/main/java/im/vector/app/features/analytics/ui/consent/AnalyticsOptInActivity.kt
@@ -0,0 +1,49 @@
+/*
+ * Copyright (c) 2020 New Vector Ltd
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package im.vector.app.features.analytics.ui.consent
+
+import com.airbnb.mvrx.viewModel
+import dagger.hilt.android.AndroidEntryPoint
+import im.vector.app.R
+import im.vector.app.core.extensions.addFragment
+import im.vector.app.core.platform.VectorBaseActivity
+import im.vector.app.databinding.ActivitySimpleBinding
+
+/**
+ * Simple container for AnalyticsOptInFragment
+ */
+@AndroidEntryPoint
+class AnalyticsOptInActivity : VectorBaseActivity() {
+
+ private val viewModel: AnalyticsConsentViewModel by viewModel()
+
+ override fun getBinding() = ActivitySimpleBinding.inflate(layoutInflater)
+
+ override fun getCoordinatorLayout() = views.coordinatorLayout
+
+ override fun initUiAndData() {
+ if (isFirstCreation()) {
+ addFragment(R.id.simpleFragmentContainer, AnalyticsOptInFragment::class.java)
+ }
+
+ viewModel.observeViewEvents {
+ when (it) {
+ AnalyticsOptInViewEvents.OnDataSaved -> finish()
+ }
+ }
+ }
+}
diff --git a/vector/src/main/java/im/vector/app/features/analytics/ui/consent/AnalyticsOptInFragment.kt b/vector/src/main/java/im/vector/app/features/analytics/ui/consent/AnalyticsOptInFragment.kt
new file mode 100644
index 0000000000..dded898961
--- /dev/null
+++ b/vector/src/main/java/im/vector/app/features/analytics/ui/consent/AnalyticsOptInFragment.kt
@@ -0,0 +1,67 @@
+/*
+ * Copyright (c) 2021 New Vector Ltd
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package im.vector.app.features.analytics.ui.consent
+
+import android.os.Bundle
+import android.view.LayoutInflater
+import android.view.View
+import android.view.ViewGroup
+import com.airbnb.mvrx.activityViewModel
+import im.vector.app.BuildConfig
+import im.vector.app.R
+import im.vector.app.core.extensions.setTextWithColoredPart
+import im.vector.app.core.platform.VectorBaseFragment
+import im.vector.app.core.utils.openUrlInChromeCustomTab
+import im.vector.app.databinding.FragmentAnalyticsOptinBinding
+import javax.inject.Inject
+
+class AnalyticsOptInFragment @Inject constructor(
+) : VectorBaseFragment() {
+
+ // Share the view model with the Activity so that the Activity
+ // can decide what to do when the data has been saved
+ private val viewModel: AnalyticsConsentViewModel by activityViewModel()
+
+ override fun getBinding(inflater: LayoutInflater, container: ViewGroup?): FragmentAnalyticsOptinBinding {
+ return FragmentAnalyticsOptinBinding.inflate(inflater, container, false)
+ }
+
+ override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
+ super.onViewCreated(view, savedInstanceState)
+ setupLink()
+ setupListeners()
+ }
+
+ private fun setupListeners() {
+ views.submit.debouncedClicks {
+ viewModel.handle(AnalyticsConsentViewActions.SetUserConsent(userConsent = true))
+ }
+ views.later.debouncedClicks {
+ viewModel.handle(AnalyticsConsentViewActions.SetUserConsent(userConsent = false))
+ }
+ }
+
+ private fun setupLink() {
+ views.submit.setTextWithColoredPart(
+ fullTextRes = R.string.analytics_opt_in_content,
+ coloredTextRes = R.string.analytics_opt_in_content_link,
+ onClick = {
+ openUrlInChromeCustomTab(requireContext(), null, BuildConfig.ANALYTICS_POLICY_URL)
+ }
+ )
+ }
+}
diff --git a/vector/src/main/java/im/vector/app/features/analytics/ui/consent/AnalyticsOptInViewEvents.kt b/vector/src/main/java/im/vector/app/features/analytics/ui/consent/AnalyticsOptInViewEvents.kt
new file mode 100644
index 0000000000..d73f472876
--- /dev/null
+++ b/vector/src/main/java/im/vector/app/features/analytics/ui/consent/AnalyticsOptInViewEvents.kt
@@ -0,0 +1,23 @@
+/*
+ * Copyright (c) 2021 New Vector Ltd
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package im.vector.app.features.analytics.ui.consent
+
+import im.vector.app.core.platform.VectorViewEvents
+
+sealed interface AnalyticsOptInViewEvents : VectorViewEvents {
+ object OnDataSaved : AnalyticsOptInViewEvents
+}
diff --git a/vector/src/main/java/im/vector/app/features/login/LoginSplashFragment.kt b/vector/src/main/java/im/vector/app/features/login/LoginSplashFragment.kt
index e045ba11b1..527f9f99b3 100644
--- a/vector/src/main/java/im/vector/app/features/login/LoginSplashFragment.kt
+++ b/vector/src/main/java/im/vector/app/features/login/LoginSplashFragment.kt
@@ -22,15 +22,10 @@ import android.view.LayoutInflater
import android.view.View
import android.view.ViewGroup
import androidx.core.view.isVisible
-import com.airbnb.mvrx.fragmentViewModel
import com.google.android.material.dialog.MaterialAlertDialogBuilder
import im.vector.app.BuildConfig
import im.vector.app.R
import im.vector.app.databinding.FragmentLoginSplashBinding
-import im.vector.app.features.analytics.AnalyticsConfig
-import im.vector.app.features.analytics.ui.consent.AnalyticsConsentViewActions
-import im.vector.app.features.analytics.ui.consent.AnalyticsConsentViewModel
-import im.vector.app.features.analytics.ui.consent.AnalyticsConsentViewState
import im.vector.app.features.settings.VectorPreferences
import org.matrix.android.sdk.api.failure.Failure
import java.net.UnknownHostException
@@ -43,8 +38,6 @@ class LoginSplashFragment @Inject constructor(
private val vectorPreferences: VectorPreferences
) : AbstractLoginFragment() {
- private val analyticsConsentViewModel: AnalyticsConsentViewModel by fragmentViewModel()
-
override fun getBinding(inflater: LayoutInflater, container: ViewGroup?): FragmentLoginSplashBinding {
return FragmentLoginSplashBinding.inflate(inflater, container, false)
}
@@ -53,24 +46,10 @@ class LoginSplashFragment @Inject constructor(
super.onViewCreated(view, savedInstanceState)
setupViews()
- observeAnalyticsState()
- }
-
- private fun observeAnalyticsState() {
- analyticsConsentViewModel.onEach(AnalyticsConsentViewState::shouldCheckTheBox) {
- views.loginSplashAnalyticsConsent.isChecked = it
- }
}
private fun setupViews() {
views.loginSplashSubmit.debouncedClicks { getStarted() }
- // setOnCheckedChangeListener is to annoying since it does not distinguish user changes and code changes
- views.loginSplashAnalyticsConsent.isVisible = AnalyticsConfig.isAnalyticsEnabled()
- views.loginSplashAnalyticsConsent.setOnClickListener {
- analyticsConsentViewModel.handle(AnalyticsConsentViewActions.SetUserConsent(
- views.loginSplashAnalyticsConsent.isChecked
- ))
- }
if (BuildConfig.DEBUG || vectorPreferences.developerMode()) {
views.loginSplashVersion.isVisible = true
@@ -82,7 +61,6 @@ class LoginSplashFragment @Inject constructor(
}
private fun getStarted() {
- analyticsConsentViewModel.handle(AnalyticsConsentViewActions.OnGetStarted)
loginViewModel.handle(LoginAction.OnGetStarted(resetLoginConfig = false))
}
diff --git a/vector/src/main/java/im/vector/app/features/navigation/DefaultNavigator.kt b/vector/src/main/java/im/vector/app/features/navigation/DefaultNavigator.kt
index 89a05c88da..631c7b8395 100644
--- a/vector/src/main/java/im/vector/app/features/navigation/DefaultNavigator.kt
+++ b/vector/src/main/java/im/vector/app/features/navigation/DefaultNavigator.kt
@@ -36,6 +36,7 @@ import im.vector.app.core.di.ActiveSessionHolder
import im.vector.app.core.error.fatalError
import im.vector.app.core.platform.VectorBaseActivity
import im.vector.app.core.utils.toast
+import im.vector.app.features.analytics.ui.consent.AnalyticsOptInActivity
import im.vector.app.features.call.conference.JitsiCallViewModel
import im.vector.app.features.call.conference.VectorJitsiActivity
import im.vector.app.features.call.transfer.CallTransferActivity
@@ -404,6 +405,10 @@ class DefaultNavigator @Inject constructor(
}
}
+ override fun openAnalyticsOptIn(context: Context) {
+ context.startActivity(Intent(context, AnalyticsOptInActivity::class.java))
+ }
+
override fun openTerms(context: Context,
activityResultLauncher: ActivityResultLauncher,
serviceType: TermsService.ServiceType,
diff --git a/vector/src/main/java/im/vector/app/features/navigation/Navigator.kt b/vector/src/main/java/im/vector/app/features/navigation/Navigator.kt
index 264593fe18..c828a80322 100644
--- a/vector/src/main/java/im/vector/app/features/navigation/Navigator.kt
+++ b/vector/src/main/java/im/vector/app/features/navigation/Navigator.kt
@@ -105,6 +105,8 @@ interface Navigator {
fun openBigImageViewer(activity: Activity, sharedElement: View?, mxcUrl: String?, title: String?)
+ fun openAnalyticsOptIn(context: Context)
+
fun openPinCode(context: Context,
activityResultLauncher: ActivityResultLauncher,
pinMode: PinMode)
diff --git a/vector/src/main/res/layout/fragment_login_splash.xml b/vector/src/main/res/layout/fragment_login_splash.xml
index 89a684be01..1d69cde723 100644
--- a/vector/src/main/res/layout/fragment_login_splash.xml
+++ b/vector/src/main/res/layout/fragment_login_splash.xml
@@ -204,20 +204,9 @@
android:layout_height="wrap_content"
android:textColor="?vctr_content_secondary"
android:visibility="gone"
- app:layout_constraintBottom_toTopOf="@id/loginSplashAnalyticsConsent"
+ app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintStart_toStartOf="parent"
tools:text="@string/settings_version"
tools:visibility="visible" />
-
-