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

Storing and tracking the onboarding messaging use case #5009

Merged
merged 10 commits into from
Jan 31, 2022
30 changes: 0 additions & 30 deletions vector/src/main/java/im/vector/app/core/extensions/DataStore.kt

This file was deleted.

4 changes: 2 additions & 2 deletions vector/src/main/java/im/vector/app/core/extensions/Session.kt
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,7 @@ import androidx.core.content.ContextCompat
import androidx.lifecycle.Lifecycle
import androidx.lifecycle.ProcessLifecycleOwner
import im.vector.app.core.services.VectorSyncService
import im.vector.app.features.onboarding.store.OnboardingStore
import im.vector.app.features.session.VectorSessionStore
import org.matrix.android.sdk.api.session.Session
import org.matrix.android.sdk.api.session.crypto.keysbackup.KeysBackupState
import org.matrix.android.sdk.api.session.sync.FilterService
Expand Down Expand Up @@ -78,4 +78,4 @@ fun Session.cannotLogoutSafely(): Boolean {
!sharedSecretStorageService.isRecoverySetup())
}

fun Session.onboardingStore(context: Context) = OnboardingStore(context, myUserId)
fun Session.vectorStore(context: Context) = VectorSessionStore(context, myUserId)
10 changes: 5 additions & 5 deletions vector/src/main/java/im/vector/app/features/MainActivity.kt
Original file line number Diff line number Diff line change
Expand Up @@ -28,20 +28,20 @@ import dagger.hilt.android.AndroidEntryPoint
import im.vector.app.R
import im.vector.app.core.di.ActiveSessionHolder
import im.vector.app.core.error.ErrorFormatter
import im.vector.app.core.extensions.onboardingStore
import im.vector.app.core.extensions.startSyncing
import im.vector.app.core.extensions.vectorStore
import im.vector.app.core.platform.VectorBaseActivity
import im.vector.app.core.utils.deleteAllFiles
import im.vector.app.databinding.ActivityMainBinding
import im.vector.app.features.analytics.VectorAnalytics
import im.vector.app.features.home.HomeActivity
import im.vector.app.features.home.ShortcutsHandler
import im.vector.app.features.notifications.NotificationDrawerManager
import im.vector.app.features.onboarding.store.OnboardingStore
import im.vector.app.features.pin.PinCodeStore
import im.vector.app.features.pin.PinLocker
import im.vector.app.features.pin.UnlockedActivity
import im.vector.app.features.popup.PopupAlertManager
import im.vector.app.features.session.VectorSessionStore
import im.vector.app.features.settings.VectorPreferences
import im.vector.app.features.signout.hard.SignedOutActivity
import im.vector.app.features.themes.ActivityOtherThemes
Expand Down Expand Up @@ -146,7 +146,7 @@ class MainActivity : VectorBaseActivity<ActivityMainBinding>(), UnlockedActivity
return
}

val onboardingStore = session.onboardingStore(this)
val onboardingStore = session.vectorStore(this)
when {
args.isAccountDeactivated -> {
lifecycleScope.launch {
Expand Down Expand Up @@ -187,7 +187,7 @@ class MainActivity : VectorBaseActivity<ActivityMainBinding>(), UnlockedActivity
Timber.w("Ignoring invalid token global error")
}

private suspend fun doLocalCleanup(clearPreferences: Boolean, onboardingStore: OnboardingStore) {
private suspend fun doLocalCleanup(clearPreferences: Boolean, vectorSessionStore: VectorSessionStore) {
// On UI Thread
Glide.get(this@MainActivity).clearMemory()

Expand All @@ -197,7 +197,7 @@ class MainActivity : VectorBaseActivity<ActivityMainBinding>(), UnlockedActivity
pinLocker.unlock()
pinCodeStore.deleteEncodedPin()
vectorAnalytics.onSignOut()
onboardingStore.clear()
vectorSessionStore.clear()
}
withContext(Dispatchers.IO) {
// On BG thread
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -32,7 +32,7 @@ import im.vector.app.core.di.MavericksAssistedViewModelFactory
import im.vector.app.core.di.hiltMavericksViewModelFactory
import im.vector.app.core.extensions.configureAndStart
import im.vector.app.core.extensions.exhaustive
import im.vector.app.core.extensions.onboardingStore
import im.vector.app.core.extensions.vectorStore
import im.vector.app.core.platform.VectorViewModel
import im.vector.app.core.resources.StringProvider
import im.vector.app.core.utils.ensureTrailingSlash
Expand Down Expand Up @@ -753,7 +753,7 @@ class OnboardingViewModel @AssistedInject constructor(

private suspend fun onSessionCreated(session: Session) {
awaitState().useCase?.let { useCase ->
session.onboardingStore(applicationContext).setUseCase(useCase)
session.vectorStore(applicationContext).setUseCase(useCase)
}
activeSessionHolder.setActiveSession(session)

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -14,48 +14,46 @@
* limitations under the License.
*/

package im.vector.app.features.onboarding.store
package im.vector.app.features.session

import android.content.Context
import androidx.datastore.core.DataStore
import androidx.datastore.preferences.core.Preferences
import androidx.datastore.preferences.core.edit
import androidx.datastore.preferences.core.stringPreferencesKey
import androidx.datastore.preferences.preferencesDataStore
import im.vector.app.core.extensions.removeKeysWithPrefix
import im.vector.app.features.onboarding.FtueUseCase
import kotlinx.coroutines.flow.first

private val Context.dataStore: DataStore<Preferences> by preferencesDataStore(name = "vector_onboarding")

/**
* Local storage for:
* - messaging use case (Enum/String)
*/
class OnboardingStore constructor(
class VectorSessionStore constructor(
private val context: Context,
private val myUserId: String
myUserId: String
) {

private val Context.dataStore: DataStore<Preferences> by preferencesDataStore(name = "vector_session_store_$myUserId")
Copy link
Member

Choose a reason for hiding this comment

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

I am wondering if directly using the userId may lead to some trouble: special chars - low risk, length - higher risk. Maybe using a hash of it would be better.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

very good point, I keep forgetting that user-id is actually a matrix id rather than a uuid, will change

Copy link
Member

Choose a reason for hiding this comment

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

Yes. "Matrix Id" is not really a specific concept, but it is sometimes used for user ids. https://spec.matrix.org/v1.1/appendices/#identifier-grammar is an interesting reading on the subject

Copy link
Contributor Author

Choose a reason for hiding this comment

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

private val useCaseKey = stringPreferencesKey("use_case")

suspend fun readUseCase() = context.dataStore.data.first().let { preferences ->
preferences[myUserId.toUseCaseKey()]?.let { FtueUseCase.from(it) }
preferences[useCaseKey]?.let { FtueUseCase.from(it) }
}

suspend fun setUseCase(useCase: FtueUseCase) {
context.dataStore.edit { settings ->
settings[myUserId.toUseCaseKey()] = useCase.persistableValue
settings[useCaseKey] = useCase.persistableValue
}
}

suspend fun resetUseCase() {
context.dataStore.edit { settings ->
settings.remove(myUserId.toUseCaseKey())
settings.remove(useCaseKey)
}
}

suspend fun clear() {
context.dataStore.removeKeysWithPrefix(myUserId)
context.dataStore.edit { settings -> settings.clear() }
}

private fun String.toUseCaseKey() = stringPreferencesKey("$this-use_case")
}