Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit b0fb099d authored by Jonathan Klee's avatar Jonathan Klee
Browse files

refactor: introduce domain ReportFaultyTokenUseCase

- move observeAuthObjects() logic out of the MainActivity
- get AuthData from AppLoungeDataStore directly. This removes a weird
dependency from SettingsFragment to the MainActivityViewModel.
parent fd94d042
Loading
Loading
Loading
Loading
Loading
+1 −11
Original line number Diff line number Diff line
@@ -12,12 +12,10 @@
    <ID>LongParameterList:AppManagerImpl.kt$AppManagerImpl$( @Named("cacheDir") private val cacheDir: String, private val downloadManager: DownloadManager, private val notificationManager: NotificationManager, private val appInstallRepository: AppInstallRepository, private val pwaManager: PwaManager, private val appLoungePackageManager: AppLoungePackageManager, @Named("download") private val downloadNotificationChannel: NotificationChannel, @Named("update") private val updateNotificationChannel: NotificationChannel, @ApplicationContext private val context: Context )</ID>
    <ID>LongParameterList:ApplicationDialogFragment.kt$ApplicationDialogFragment$( title: String, message: String, @DrawableRes drawableResId: Int = -1, drawable: Drawable? = null, positiveButtonText: String = "", positiveButtonAction: (() -&gt; Unit)? = null, cancelButtonText: String = "", cancelButtonAction: (() -&gt; Unit)? = null, cancelable: Boolean = true, onDismissListener: (() -&gt; Unit)? = null, )</ID>
    <ID>LongParameterList:ApplicationListRVAdapter.kt$ApplicationListRVAdapter$( private val applicationInstaller: ApplicationInstaller, private val privacyInfoViewModel: PrivacyInfoViewModel, private val appInfoFetchViewModel: AppInfoFetchViewModel, private val mainActivityViewModel: MainActivityViewModel, private val currentDestinationId: Int, private var lifecycleOwner: LifecycleOwner?, private var paidAppHandler: ((Application) -&gt; Unit)? = null )</ID>
    <ID>LongParameterList:CleanApkRetrofit.kt$CleanApkRetrofit$( @Query("keyword") keyword: String, @Query("source") source: String = APP_SOURCE_FOSS, @Query("type") type: String = APP_TYPE_ANY, @Query("nres") nres: Int = 20, @Query("page") page: Int = 1, @Query("by") by: String? = null, )</ID>
    <ID>LongParameterList:EglExtensionProvider.kt$EglExtensionProvider$( egl10: EGL10, eglDisplay: EGLDisplay, eglConfig: EGLConfig?, ai: IntArray, ai1: IntArray?, set: MutableSet&lt;String&gt; )</ID>
    <ID>LongParameterList:MainActivityViewModel.kt$MainActivityViewModel$( private val appLoungeDataStore: AppLoungeDataStore, private val applicationRepository: ApplicationRepository, private val appManagerWrapper: AppManagerWrapper, private val appLoungePackageManager: AppLoungePackageManager, private val pwaManager: PwaManager, private val ecloudRepository: EcloudRepository, private val blockedAppRepository: BlockedAppRepository, private val gPlayContentRatingRepository: GPlayContentRatingRepository, private val fDroidAntiFeatureRepository: FDroidAntiFeatureRepository, private val appInstallProcessor: AppInstallProcessor, private val systemAppsUpdatesRepository: SystemAppsUpdatesRepository, )</ID>
    <ID>LongParameterList:MainActivityViewModel.kt$MainActivityViewModel$( private val appLoungeDataStore: AppLoungeDataStore, private val applicationRepository: ApplicationRepository, private val appManagerWrapper: AppManagerWrapper, private val appLoungePackageManager: AppLoungePackageManager, private val pwaManager: PwaManager, private val blockedAppRepository: BlockedAppRepository, private val gPlayContentRatingRepository: GPlayContentRatingRepository, private val fDroidAntiFeatureRepository: FDroidAntiFeatureRepository, private val appInstallProcessor: AppInstallProcessor, private val systemAppsUpdatesRepository: SystemAppsUpdatesRepository, private val reportFaultyTokenUseCase: ReportFaultyTokenUseCase, )</ID>
    <ID>LongParameterList:UpdatesManagerImpl.kt$UpdatesManagerImpl$( @ApplicationContext private val context: Context, private val appLoungePackageManager: AppLoungePackageManager, private val applicationRepository: ApplicationRepository, private val faultyAppRepository: FaultyAppRepository, private val appLoungePreference: AppLoungePreference, private val fDroidRepository: FDroidRepository, private val blockedAppRepository: BlockedAppRepository, private val systemAppsUpdatesRepository: SystemAppsUpdatesRepository, )</ID>
    <ID>LongParameterList:UpdatesWorker.kt$UpdatesWorker$( @Assisted private val context: Context, @Assisted private val params: WorkerParameters, private val updatesManagerRepository: UpdatesManagerRepository, private val appLoungeDataStore: AppLoungeDataStore, private val authenticatorRepository: AuthenticatorRepository, private val appInstallProcessor: AppInstallProcessor, private val blockedAppRepository: BlockedAppRepository, private val systemAppsUpdatesRepository: SystemAppsUpdatesRepository, )</ID>
    <ID>NoWildcardImports:SystemAppsUpdatesRepository.kt$import foundation.e.apps.data.gitlab.UpdatableSystemAppsApi.*</ID>
    <ID>ProtectedMemberInFinalClass:ApplicationListFragment.kt$ApplicationListFragment$// protected to avoid SyntheticAccessor protected val args: ApplicationListFragmentArgs by navArgs()</ID>
    <ID>ProtectedMemberInFinalClass:ApplicationListFragment.kt$ApplicationListFragment$// protected to avoid SyntheticAccessor protected val viewModel: ApplicationListViewModel by viewModels()</ID>
    <ID>ProtectedMemberInFinalClass:GoogleSignInFragment.kt$GoogleSignInFragment$// protected to avoid SyntheticAccessor protected val viewModel: LoginViewModel by lazy { ViewModelProvider(requireActivity())[LoginViewModel::class.java] }</ID>
@@ -32,8 +30,6 @@
    <ID>ReturnCount:DownloadManager.kt$DownloadManager$fun getSizeRequired(downloadId: Long): Long</ID>
    <ID>ReturnCount:DownloadManager.kt$DownloadManager$private fun sanitizeStatus(downloadId: Long, status: Int, reason: Int): Int</ID>
    <ID>ReturnCount:Extensions.kt$fun Context.isNetworkAvailable(): Boolean</ID>
    <ID>ReturnCount:PlayStoreAuthenticator.kt$PlayStoreAuthenticator$override suspend fun validateAuthData(): ResultSupreme&lt;AuthData?&gt;</ID>
    <ID>ReturnCount:PlayStoreAuthenticator.kt$PlayStoreAuthenticator$private suspend fun getAuthDataWithGoogleAccount(): ResultSupreme&lt;AuthData?&gt;</ID>
    <ID>ReturnCount:PrivacyInfoViewModel.kt$PrivacyInfoViewModel$fun shouldRequestExodusReport(application: Application?): Boolean</ID>
    <ID>ReturnCount:StorageNotificationManager.kt$StorageNotificationManager$private fun getSpaceMissing(appInstall: AppInstall, downloadId: Long? = null): Long</ID>
    <ID>ReturnCount:SystemAppsUpdatesRepository.kt$SystemAppsUpdatesRepository$private suspend fun getApplication( packageName: String, releaseType: OsReleaseType, sdkLevel: Int, device: String, ): Application?</ID>
@@ -52,11 +48,9 @@
    <ID>SwallowedException:ApplicationViewModel.kt$ApplicationViewModel$e: Exception</ID>
    <ID>SwallowedException:ApplicationViewModel.kt$ApplicationViewModel$e: InternalException.AppNotFound</ID>
    <ID>SwallowedException:GPlayHttpClient.kt$GPlayHttpClient$e: Exception</ID>
    <ID>SwallowedException:NativeDeviceInfoProviderModule.kt$NativeDeviceInfoProviderModule$e: Exception</ID>
    <ID>SwallowedException:NativeGsfVersionProvider.kt$NativeGsfVersionProvider$e: PackageManager.NameNotFoundException</ID>
    <ID>SwallowedException:UpdatesManagerImpl.kt$UpdatesManagerImpl$e: Exception</ID>
    <ID>TooGenericExceptionCaught:AgeRatingProvider.kt$AgeRatingProvider$e: Exception</ID>
    <ID>TooGenericExceptionCaught:AnonymousLoginManager.kt$AnonymousLoginManager$e: Exception</ID>
    <ID>TooGenericExceptionCaught:ApiCaller.kt$e: Exception</ID>
    <ID>TooGenericExceptionCaught:ApkSignatureManager.kt$ApkSignatureManager$e: Exception</ID>
    <ID>TooGenericExceptionCaught:AppInfoFetchViewModel.kt$AppInfoFetchViewModel$e: Exception</ID>
@@ -74,12 +68,10 @@
    <ID>TooGenericExceptionCaught:EcloudRepository.kt$EcloudRepository$e: Exception</ID>
    <ID>TooGenericExceptionCaught:FileManager.kt$FileManager$e: Exception</ID>
    <ID>TooGenericExceptionCaught:GPlayHttpClient.kt$GPlayHttpClient$e: Exception</ID>
    <ID>TooGenericExceptionCaught:GoogleLoginManager.kt$GoogleLoginManager$e: Exception</ID>
    <ID>TooGenericExceptionCaught:InstallWorkManager.kt$InstallWorkManager$e: Exception</ID>
    <ID>TooGenericExceptionCaught:LocaleChangedBroadcastReceiver.kt$LocaleChangedBroadcastReceiver$ex: Exception</ID>
    <ID>TooGenericExceptionCaught:NativeDeviceInfoProviderModule.kt$NativeDeviceInfoProviderModule$e: Exception</ID>
    <ID>TooGenericExceptionCaught:NetworkHandler.kt$e: Exception</ID>
    <ID>TooGenericExceptionCaught:PlayStoreAuthenticator.kt$PlayStoreAuthenticator$e: Exception</ID>
    <ID>TooGenericExceptionCaught:PlayStoreRepository.kt$PlayStoreRepository$exception: Exception</ID>
    <ID>TooGenericExceptionCaught:PwaManager.kt$PwaManager$e: Exception</ID>
    <ID>TooGenericExceptionCaught:PwaPlayerStatusReceiver.kt$PwaPlayerStatusReceiver$e: Exception</ID>
@@ -87,8 +79,6 @@
    <ID>TooGenericExceptionCaught:UpdatesManagerImpl.kt$UpdatesManagerImpl$e: Exception</ID>
    <ID>TooGenericExceptionCaught:UpdatesWorker.kt$UpdatesWorker$e: Throwable</ID>
    <ID>TooGenericExceptionThrown:AnonymousLoginManager.kt$AnonymousLoginManager$throw Exception( "Error fetching Anonymous credentials\n" + "Network code: ${response.code}\n" + "Success: ${response.isSuccessful}" + response.errorString.run { if (isNotBlank()) "\nError message: $this" else "" } )</ID>
    <ID>TooGenericExceptionThrown:PlayStoreLoginWrapper.kt$PlayStoreLoginWrapper$throw Exception("Validation network code: ${response.code}")</ID>
    <ID>TooGenericExceptionThrown:PlayStoreLoginWrapper.kt$PlayStoreLoginWrapper$throw Exception(error)</ID>
    <ID>TooManyFunctions:AppLoungePackageManager.kt$AppLoungePackageManager</ID>
    <ID>TooManyFunctions:AppManager.kt$AppManager</ID>
    <ID>TooManyFunctions:AppManagerImpl.kt$AppManagerImpl : AppManager</ID>
+39 −0
Original line number Diff line number Diff line
package foundation.e.apps.domain.login

import foundation.e.apps.data.ecloud.EcloudRepository
import foundation.e.apps.data.login.core.AuthObject
import foundation.e.apps.data.login.exceptions.GPlayValidationException
import foundation.e.apps.utils.SystemInfoProvider
import kotlinx.coroutines.Dispatchers
import kotlinx.coroutines.withContext
import timber.log.Timber
import javax.inject.Inject

class ReportFaultyTokenUseCase @Inject constructor(
    private val ecloudRepository: EcloudRepository
) {
    suspend operator fun invoke(authObjects: List<AuthObject>) {
        val gPlayAuthObject = authObjects.firstOrNull { it is AuthObject.GPlayAuth } as? AuthObject.GPlayAuth
        if (gPlayAuthObject == null) {
            return
        }

        val result = gPlayAuthObject.result
        val exception = result.exception
        val shouldUploadFaultyToken = exception is GPlayValidationException

        if (shouldUploadFaultyToken) {
            val email = result.otherPayload.toString()
            val buildInfo = SystemInfoProvider.getAppBuildInfo()
            withContext(Dispatchers.IO) {
                ecloudRepository.uploadFaultyEmail(email, buildInfo)
            }
        }

        if (!shouldUploadFaultyToken) {
            exception?.let {
                Timber.e(it, "Login failed! message: ${it.localizedMessage}")
            }
        }
    }
}
+11 −34
Original line number Diff line number Diff line
@@ -39,7 +39,6 @@ import androidx.navigation.findNavController
import androidx.navigation.fragment.NavHostFragment
import androidx.navigation.ui.NavigationUI
import androidx.navigation.ui.setupWithNavController
import com.aurora.gplayapi.data.models.AuthData
import com.aurora.gplayapi.exceptions.InternalException
import com.google.android.material.bottomnavigation.BottomNavigationView
import com.google.android.material.snackbar.Snackbar
@@ -50,9 +49,7 @@ import foundation.e.apps.contract.ParentalControlContract.COLUMN_LOGIN_TYPE
import foundation.e.apps.data.Constants
import foundation.e.apps.data.enums.User
import foundation.e.apps.data.install.models.AppInstall
import foundation.e.apps.data.login.core.AuthObject
import foundation.e.apps.data.login.core.StoreType
import foundation.e.apps.data.login.exceptions.GPlayValidationException
import foundation.e.apps.databinding.ActivityMainBinding
import foundation.e.apps.install.updates.UpdatesNotifier
import foundation.e.apps.ui.application.subFrags.ApplicationDialogFragment
@@ -61,7 +58,6 @@ import foundation.e.apps.ui.purchase.AppPurchaseFragmentDirections
import foundation.e.apps.ui.settings.SettingsFragment
import foundation.e.apps.ui.setup.signin.SignInViewModel
import foundation.e.apps.utils.ParentalControlAuthenticator
import foundation.e.apps.utils.SystemInfoProvider
import foundation.e.apps.utils.eventBus.AppEvent
import foundation.e.apps.utils.eventBus.EventBus
import kotlinx.coroutines.Dispatchers
@@ -378,40 +374,21 @@ class MainActivity : AppCompatActivity() {
    }

    private fun observeAuthObjects(navController: NavController) {
        loginViewModel.authObjects.distinctUntilChanged().observe(this) {
            when {
                it == null -> return@observe
                it.isEmpty() -> {
                    // No auth type defined means user has not logged in yet
                    // Pop back stack to prevent showing TOSFragment on pressing back button.
        viewModel.uiState.distinctUntilChanged().observe(this) { state ->
            if (state.navigateToSignIn) {
                navController.popBackStack()
                navController.navigate(R.id.signInFragment)
                    if (viewModel.gPlayLoginRequested) viewModel.closeAfterLogin = true
                    return@observe
                }

                else -> {}
                viewModel.onNavigateToSignInHandled()
            }

            val gPlayAuthObject = it.find { it is AuthObject.GPlayAuth }

            gPlayAuthObject?.result?.run {
                if (isSuccess()) {
                    viewModel.gPlayAuthData = data as AuthData
                } else if (exception is GPlayValidationException && viewModel.getUser() == User.ANONYMOUS) {
                    val email = otherPayload.toString()
                    viewModel.uploadFaultyTokenToEcloud(
                        email,
                        SystemInfoProvider.getAppBuildInfo()
                    )
                } else if (exception != null) {
                    Timber.e(exception, "Login failed! message: ${exception?.localizedMessage}")
            if (state.finishAfterLogin) {
                viewModel.onFinishAfterLoginHandled()
                finishAndRemoveTask()
            }
        }

            if (viewModel.closeAfterLogin && it.isNotEmpty() && it.all { it.result.isSuccess() }) {
                finishAndRemoveTask()
            }
        loginViewModel.authObjects.distinctUntilChanged().observe(this) {
            viewModel.handleAuthObjects(it)
        }
    }

+93 −49
Original line number Diff line number Diff line
@@ -20,31 +20,30 @@ package foundation.e.apps.ui

import android.content.Context
import android.content.Intent
import android.net.ConnectivityManager
import androidx.appcompat.app.AlertDialog
import androidx.lifecycle.LiveData
import androidx.lifecycle.MutableLiveData
import androidx.lifecycle.ViewModel
import androidx.lifecycle.asLiveData
import androidx.lifecycle.viewModelScope
import com.aurora.gplayapi.data.models.AuthData
import dagger.hilt.android.lifecycle.HiltViewModel
import foundation.e.apps.R
import foundation.e.apps.data.application.ApplicationRepository
import foundation.e.apps.data.application.data.Application
import foundation.e.apps.data.blockedApps.BlockedAppRepository
import foundation.e.apps.data.ecloud.EcloudRepository
import foundation.e.apps.data.enums.User
import foundation.e.apps.data.enums.isInitialized
import foundation.e.apps.data.enums.isUnFiltered
import foundation.e.apps.data.gitlab.SystemAppsUpdatesRepository
import foundation.e.apps.data.install.AppManagerWrapper
import foundation.e.apps.data.install.models.AppInstall
import foundation.e.apps.data.login.core.AuthObject
import foundation.e.apps.data.login.state.LoginState
import foundation.e.apps.data.parentalcontrol.fdroid.FDroidAntiFeatureRepository
import foundation.e.apps.data.parentalcontrol.googleplay.GPlayContentRatingRepository
import foundation.e.apps.data.preference.AppLoungeDataStore
import foundation.e.apps.data.preference.getSync
import foundation.e.apps.domain.login.ReportFaultyTokenUseCase
import foundation.e.apps.install.pkg.AppLoungePackageManager
import foundation.e.apps.install.pkg.PwaManager
import foundation.e.apps.install.workmanager.AppInstallProcessor
@@ -60,12 +59,12 @@ class MainActivityViewModel @Inject constructor(
    private val appManagerWrapper: AppManagerWrapper,
    private val appLoungePackageManager: AppLoungePackageManager,
    private val pwaManager: PwaManager,
    private val ecloudRepository: EcloudRepository,
    private val blockedAppRepository: BlockedAppRepository,
    private val gPlayContentRatingRepository: GPlayContentRatingRepository,
    private val fDroidAntiFeatureRepository: FDroidAntiFeatureRepository,
    private val appInstallProcessor: AppInstallProcessor,
    private val systemAppsUpdatesRepository: SystemAppsUpdatesRepository,
    private val reportFaultyTokenUseCase: ReportFaultyTokenUseCase,
) : ViewModel() {

    init {
@@ -82,8 +81,6 @@ class MainActivityViewModel @Inject constructor(
    val purchaseDeclined: MutableLiveData<String> = MutableLiveData()
    lateinit var internetConnection: LiveData<Boolean>

    var gPlayAuthData = AuthData("", "")

    // Downloads
    val downloadList = appManagerWrapper.getDownloadLiveList()
    private val _errorMessage = MutableLiveData<Exception>()
@@ -92,11 +89,19 @@ class MainActivityViewModel @Inject constructor(
    private val _errorMessageStringResource = MutableLiveData<Int>()
    val errorMessageStringResource: LiveData<Int> = _errorMessageStringResource

    data class MainUiState(
        val navigateToSignIn: Boolean = false,
        val finishAfterLogin: Boolean = false
    )

    private val _uiState = MutableLiveData(MainUiState())
    val uiState: LiveData<MainUiState> = _uiState

    private val initialUiState = MainUiState()

    var gPlayLoginRequested = false
    var closeAfterLogin = false

    lateinit var connectivityManager: ConnectivityManager

    var shouldIgnoreSessionError = false

    fun getTocStatus(): Boolean {
@@ -111,14 +116,51 @@ class MainActivityViewModel @Inject constructor(
        return appLoungeDataStore.getLoginState()
    }

    fun getUserEmail(): String {
        return appLoungeDataStore.emailData.getSync()
    fun handleAuthObjects(authObjects: List<AuthObject>?) {
        if (authObjects == null) {
            return
        }

    fun uploadFaultyTokenToEcloud(email: String, description: String = "") {
        if (authObjects.isEmpty()) {
            handleEmptyAuthObjects()
            return
        }

        val shouldFinishAfterLogin = shouldFinishAfterLogin(authObjects)
        val user = getUser()
        if (user == User.ANONYMOUS) {
            viewModelScope.launch {
            ecloudRepository.uploadFaultyEmail(email, description)
                reportFaultyTokenUseCase(authObjects)
            }
        }

        if (shouldFinishAfterLogin) {
            _uiState.value = _uiState.value?.copy(finishAfterLogin = true)
                ?: initialUiState.copy(finishAfterLogin = true)
        }
    }

    fun onNavigateToSignInHandled() {
        _uiState.value = _uiState.value?.copy(navigateToSignIn = false)
            ?: initialUiState
    }

    fun onFinishAfterLoginHandled() {
        _uiState.value = _uiState.value?.copy(finishAfterLogin = false)
            ?: initialUiState
    }

    private fun handleEmptyAuthObjects() {
        if (gPlayLoginRequested) {
            closeAfterLogin = true
        }

        _uiState.value = _uiState.value?.copy(navigateToSignIn = true)
            ?: initialUiState.copy(navigateToSignIn = true)
    }

    private fun shouldFinishAfterLogin(authObjects: List<AuthObject>): Boolean {
        return closeAfterLogin && authObjects.all { it.result.isSuccess() }
    }

    /*
@@ -140,10 +182,12 @@ class MainActivityViewModel @Inject constructor(
     * Issue: https://gitlab.e.foundation/e/os/backlog/-/issues/266
     */
    fun shouldShowPaidAppsSnackBar(app: Application): Boolean {
        if (!app.isFree && gPlayAuthData.isAnonymous) {
        val authData = appLoungeDataStore.getAuthData()
        if (!app.isFree && authData.isAnonymous) {
            _errorMessageStringResource.value = R.string.paid_app_anonymous_message
            return true
        }

        return false
    }

@@ -205,12 +249,12 @@ class MainActivityViewModel @Inject constructor(

    suspend fun updateAwaitingForPurchasedApp(packageName: String): AppInstall? {
        val fusedDownload = appManagerWrapper.getFusedDownload(packageName = packageName)
        gPlayAuthData.let {
            if (!it.isAnonymous) {
        val authData = appLoungeDataStore.getAuthData()
        if (!authData.isAnonymous) {
            appInstallProcessor.enqueueFusedDownload(fusedDownload)
            return fusedDownload
        }
        }

        return null
    }

+13 −7
Original line number Diff line number Diff line
@@ -26,7 +26,6 @@ import android.view.View
import android.widget.Toast
import androidx.core.net.toUri
import androidx.core.view.isVisible
import androidx.fragment.app.activityViewModels
import androidx.lifecycle.ViewModelProvider
import androidx.navigation.findNavController
import androidx.preference.CheckBoxPreference
@@ -46,10 +45,11 @@ import foundation.e.apps.data.Stores
import foundation.e.apps.data.application.UpdatesDao
import foundation.e.apps.data.enums.Source
import foundation.e.apps.data.enums.User
import foundation.e.apps.data.preference.AppLoungeDataStore
import foundation.e.apps.data.preference.getSync
import foundation.e.apps.databinding.CustomPreferenceBinding
import foundation.e.apps.install.updates.UpdatesWorkManager
import foundation.e.apps.ui.LoginViewModel
import foundation.e.apps.ui.MainActivityViewModel
import foundation.e.apps.utils.SystemInfoProvider
import timber.log.Timber
import java.util.Locale
@@ -59,7 +59,6 @@ import javax.inject.Inject
class SettingsFragment : PreferenceFragmentCompat() {
    private var _binding: CustomPreferenceBinding? = null
    private val binding get() = _binding!!
    private val mainActivityViewModel: MainActivityViewModel by activityViewModels()
    private var showAllApplications: CheckBoxPreference? = null
    private var showFOSSApplications: CheckBoxPreference? = null
    private var showPWAApplications: CheckBoxPreference? = null
@@ -77,8 +76,11 @@ class SettingsFragment : PreferenceFragmentCompat() {
    @Inject
    lateinit var clipboardManager: ClipboardManager

    @Inject
    lateinit var appLoungeDataStore: AppLoungeDataStore

    private val user by lazy {
        mainActivityViewModel.getUser()
        appLoungeDataStore.getUser()
    }

    private val allSourceCheckboxes by lazy {
@@ -96,8 +98,10 @@ class SettingsFragment : PreferenceFragmentCompat() {

        val updateCheckInterval =
            preferenceManager.findPreference<ListPreference>(getString(R.string.update_check_intervals))

        val updateCheckIntervalAnonymous =
            preferenceManager.findPreference<ListPreference>(getString(R.string.update_check_intervals_anonymous))

        val updateChangeListener = { _: Preference, newValue: Any ->
            Timber.d("onCreatePreferences: updated Value: $newValue")
            context?.let {
@@ -109,6 +113,7 @@ class SettingsFragment : PreferenceFragmentCompat() {
            }
            true
        }

        updateCheckInterval?.setOnPreferenceChangeListener(updateChangeListener)
        updateCheckIntervalAnonymous?.setOnPreferenceChangeListener(updateChangeListener)
        configureUpdatePreferencesForUser(updateCheckInterval, updateCheckIntervalAnonymous)
@@ -129,6 +134,7 @@ class SettingsFragment : PreferenceFragmentCompat() {
                    appVersionLabel,
                    contents
                )

                Toast.makeText(context, R.string.copied, Toast.LENGTH_SHORT).show()

                true
@@ -188,8 +194,8 @@ class SettingsFragment : PreferenceFragmentCompat() {
        // This is useful if a user from older App Lounge updates to this version
        disableDependentCheckbox(onlyUnmeteredNetwork, autoInstallUpdate)

        mainActivityViewModel.gPlayAuthData.let { authData ->
            mainActivityViewModel.getUser().name.let { user ->
        appLoungeDataStore.getAuthData().let { authData ->
            appLoungeDataStore.getUser().name.let { user ->
                handleUser(user, authData)
            }
        }
@@ -248,7 +254,7 @@ class SettingsFragment : PreferenceFragmentCompat() {
            User.GOOGLE.name -> {
                if (!authData.isAnonymous) {
                    binding.accountType.text = authData.userProfile?.name
                    binding.email.text = mainActivityViewModel.getUserEmail()
                    binding.email.text = appLoungeDataStore.emailData.getSync()
                    binding.avatar.load(authData.userProfile?.artwork?.url)
                }
            }
Loading