diff --git a/vector/src/debug/AndroidManifest.xml b/vector/src/debug/AndroidManifest.xml index dba8440602..07d8c2f87a 100644 --- a/vector/src/debug/AndroidManifest.xml +++ b/vector/src/debug/AndroidManifest.xml @@ -5,6 +5,7 @@ + diff --git a/vector/src/debug/java/im/vector/app/features/debug/DebugMenuActivity.kt b/vector/src/debug/java/im/vector/app/features/debug/DebugMenuActivity.kt index 64de648a23..0f9ee5b0b3 100644 --- a/vector/src/debug/java/im/vector/app/features/debug/DebugMenuActivity.kt +++ b/vector/src/debug/java/im/vector/app/features/debug/DebugMenuActivity.kt @@ -34,6 +34,7 @@ import im.vector.app.core.utils.checkPermissions import im.vector.app.core.utils.registerForPermissionsResult import im.vector.app.core.utils.toast import im.vector.app.databinding.ActivityDebugMenuBinding +import im.vector.app.features.debug.analytics.DebugAnalyticsActivity import im.vector.app.features.debug.sas.DebugSasEmojiActivity import im.vector.app.features.debug.settings.DebugPrivateSettingsActivity import im.vector.app.features.qrcode.QrCodeScannerActivity @@ -77,6 +78,9 @@ class DebugMenuActivity : VectorBaseActivity() { private fun setupViews() { views.debugPrivateSetting.setOnClickListener { openPrivateSettings() } + views.debugAnalytics.setOnClickListener { + startActivity(Intent(this, DebugAnalyticsActivity::class.java)) + } views.debugTestTextViewLink.setOnClickListener { testTextViewLink() } views.debugOpenButtonStylesLight.setOnClickListener { startActivity(Intent(this, DebugVectorButtonStylesLightActivity::class.java)) diff --git a/vector/src/debug/java/im/vector/app/features/debug/analytics/DebugAnalyticsActivity.kt b/vector/src/debug/java/im/vector/app/features/debug/analytics/DebugAnalyticsActivity.kt new file mode 100644 index 0000000000..58940d9b24 --- /dev/null +++ b/vector/src/debug/java/im/vector/app/features/debug/analytics/DebugAnalyticsActivity.kt @@ -0,0 +1,38 @@ +/* + * 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.debug.analytics + +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 + +@AndroidEntryPoint +class DebugAnalyticsActivity : VectorBaseActivity() { + + override fun getBinding() = ActivitySimpleBinding.inflate(layoutInflater) + + override fun initUiAndData() { + if (isFirstCreation()) { + addFragment( + R.id.simpleFragmentContainer, + DebugAnalyticsFragment::class.java + ) + } + } +} diff --git a/vector/src/debug/java/im/vector/app/features/debug/analytics/DebugAnalyticsFragment.kt b/vector/src/debug/java/im/vector/app/features/debug/analytics/DebugAnalyticsFragment.kt new file mode 100644 index 0000000000..eb23fe6383 --- /dev/null +++ b/vector/src/debug/java/im/vector/app/features/debug/analytics/DebugAnalyticsFragment.kt @@ -0,0 +1,73 @@ +/* + * 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.debug.analytics + +import android.os.Bundle +import android.view.LayoutInflater +import android.view.View +import android.view.ViewGroup +import com.airbnb.mvrx.fragmentViewModel +import com.airbnb.mvrx.withState +import im.vector.app.core.epoxy.onClick +import im.vector.app.core.extensions.toOnOff +import im.vector.app.core.platform.VectorBaseFragment +import im.vector.app.databinding.FragmentDebugAnalyticsBinding +import me.gujun.android.span.span + +class DebugAnalyticsFragment : VectorBaseFragment() { + + private val viewModel: DebugAnalyticsViewModel by fragmentViewModel() + + override fun getBinding(inflater: LayoutInflater, container: ViewGroup?): FragmentDebugAnalyticsBinding { + return FragmentDebugAnalyticsBinding.inflate(inflater, container, false) + } + + override fun onViewCreated(view: View, savedInstanceState: Bundle?) { + super.onViewCreated(view, savedInstanceState) + + setViewListeners() + } + + private fun setViewListeners() { + views.showAnalyticsOptIn.onClick { + navigator.openAnalyticsOptIn(requireContext()) + } + views.resetAnalyticsOptInDisplayed.onClick { + viewModel.handle(DebugAnalyticsViewActions.ResetAnalyticsOptInDisplayed) + } + } + + override fun invalidate() = withState(viewModel) { state -> + views.analyticsStoreContent.text = span { + +"AnalyticsId: " + span { + textStyle = "bold" + text = state.analyticsId.orEmpty() + } + +"\nOptIn: " + span { + textStyle = "bold" + text = state.userConsent.toOnOff() + } + +"\nDidAsk: " + span { + textStyle = "bold" + text = state.didAskUserConsent.toString() + } + } + } +} diff --git a/vector/src/debug/java/im/vector/app/features/debug/analytics/DebugAnalyticsViewActions.kt b/vector/src/debug/java/im/vector/app/features/debug/analytics/DebugAnalyticsViewActions.kt new file mode 100644 index 0000000000..e1a7ce36fd --- /dev/null +++ b/vector/src/debug/java/im/vector/app/features/debug/analytics/DebugAnalyticsViewActions.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.debug.analytics + +import im.vector.app.core.platform.VectorViewModelAction + +sealed interface DebugAnalyticsViewActions : VectorViewModelAction { + object ResetAnalyticsOptInDisplayed : DebugAnalyticsViewActions +} diff --git a/vector/src/debug/java/im/vector/app/features/debug/analytics/DebugAnalyticsViewModel.kt b/vector/src/debug/java/im/vector/app/features/debug/analytics/DebugAnalyticsViewModel.kt new file mode 100644 index 0000000000..03e416813a --- /dev/null +++ b/vector/src/debug/java/im/vector/app/features/debug/analytics/DebugAnalyticsViewModel.kt @@ -0,0 +1,64 @@ +/* + * 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.debug.analytics + +import com.airbnb.mvrx.MavericksViewModelFactory +import dagger.assisted.Assisted +import dagger.assisted.AssistedFactory +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.store.AnalyticsStore +import kotlinx.coroutines.launch + +class DebugAnalyticsViewModel @AssistedInject constructor( + @Assisted initialState: DebugAnalyticsViewState, + private val analyticsStore: AnalyticsStore +) : VectorViewModel(initialState) { + + @AssistedFactory + interface Factory : MavericksAssistedViewModelFactory { + override fun create(initialState: DebugAnalyticsViewState): DebugAnalyticsViewModel + } + + companion object : MavericksViewModelFactory by hiltMavericksViewModelFactory() + + init { + observerStore() + } + + private fun observerStore() { + analyticsStore.analyticsIdFlow.setOnEach { copy(analyticsId = it) } + analyticsStore.userConsentFlow.setOnEach { copy(userConsent = it) } + analyticsStore.didAskUserConsentFlow.setOnEach { copy(didAskUserConsent = it) } + } + + override fun handle(action: DebugAnalyticsViewActions) { + when (action) { + DebugAnalyticsViewActions.ResetAnalyticsOptInDisplayed -> handleResetAnalyticsOptInDisplayed() + }.exhaustive + } + + private fun handleResetAnalyticsOptInDisplayed() { + viewModelScope.launch { + analyticsStore.setDidAskUserConsent(false) + } + } +} diff --git a/vector/src/debug/java/im/vector/app/features/debug/analytics/DebugAnalyticsViewState.kt b/vector/src/debug/java/im/vector/app/features/debug/analytics/DebugAnalyticsViewState.kt new file mode 100644 index 0000000000..8e7afb39ef --- /dev/null +++ b/vector/src/debug/java/im/vector/app/features/debug/analytics/DebugAnalyticsViewState.kt @@ -0,0 +1,25 @@ +/* + * 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.debug.analytics + +import com.airbnb.mvrx.MavericksState + +data class DebugAnalyticsViewState( + val analyticsId: String? = null, + val userConsent: Boolean = false, + val didAskUserConsent: Boolean = false +) : MavericksState diff --git a/vector/src/debug/java/im/vector/app/features/debug/di/MavericksViewModelDebugModule.kt b/vector/src/debug/java/im/vector/app/features/debug/di/MavericksViewModelDebugModule.kt index 8be4470b3f..6ef7fe441a 100644 --- a/vector/src/debug/java/im/vector/app/features/debug/di/MavericksViewModelDebugModule.kt +++ b/vector/src/debug/java/im/vector/app/features/debug/di/MavericksViewModelDebugModule.kt @@ -23,12 +23,18 @@ import dagger.multibindings.IntoMap import im.vector.app.core.di.MavericksAssistedViewModelFactory import im.vector.app.core.di.MavericksViewModelComponent import im.vector.app.core.di.MavericksViewModelKey +import im.vector.app.features.debug.analytics.DebugAnalyticsViewModel import im.vector.app.features.debug.settings.DebugPrivateSettingsViewModel @InstallIn(MavericksViewModelComponent::class) @Module interface MavericksViewModelDebugModule { + @Binds + @IntoMap + @MavericksViewModelKey(DebugAnalyticsViewModel::class) + fun debugAnalyticsViewModelFactory(factory: DebugAnalyticsViewModel.Factory): MavericksAssistedViewModelFactory<*, *> + @Binds @IntoMap @MavericksViewModelKey(DebugPrivateSettingsViewModel::class) diff --git a/vector/src/debug/res/layout/activity_debug_menu.xml b/vector/src/debug/res/layout/activity_debug_menu.xml index ac70e4ef0e..5aa33c4353 100644 --- a/vector/src/debug/res/layout/activity_debug_menu.xml +++ b/vector/src/debug/res/layout/activity_debug_menu.xml @@ -26,6 +26,12 @@ android:layout_height="wrap_content" android:text="Private settings" /> +