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

Commit 95902b5a authored by Abhishek Aggarwal's avatar Abhishek Aggarwal
Browse files

fix(auth): persist prepared Play bootstrap artifacts

parent 5041280b
Loading
Loading
Loading
Loading
+28 −29
Original line number Diff line number Diff line
@@ -73,39 +73,31 @@ class LoginViewModel @Inject constructor(
        email: String,
        oauthToken: String,
    ) {
        viewModelScope.launch {
            submitLogin(R.string.sign_in_microg_login_failed) {
        launchLoginSubmission(R.string.sign_in_microg_login_failed) {
            loginWorkflowCoordinator.submitMicrogLogin(email, oauthToken)
        }
    }
    }

    private fun initiateAnonymousLogin() {
        viewModelScope.launch {
            submitLogin(R.string.anonymous_login_failed_desc) {
        launchLoginSubmission(R.string.anonymous_login_failed_desc) {
            loginWorkflowCoordinator.submitAnonymousLogin()
        }
    }
    }

    private fun initiateGoogleLogin(
        email: String,
        oauthToken: String,
    ) {
        viewModelScope.launch {
            submitLogin(R.string.sign_in_failed_desc) {
        launchLoginSubmission(R.string.sign_in_failed_desc) {
            loginWorkflowCoordinator.submitGoogleLogin(email, oauthToken)
        }
    }
    }

    private fun initiateNoGoogleLogin() {
        viewModelScope.launch {
            submitLogin(R.string.something_went_wrong) {
        launchLoginSubmission(R.string.something_went_wrong) {
            loginWorkflowCoordinator.submitNoGoogleLogin()
        }
    }
    }

    private fun logout() {
        viewModelScope.launch {
@@ -114,17 +106,20 @@ class LoginViewModel @Inject constructor(
        }
    }

    private suspend fun submitLogin(
    private fun launchLoginSubmission(
        @StringRes fallbackMessageRes: Int,
        action: suspend () -> LoginWorkflowResult,
    ) {
        beginSubmission()
        if (!beginSubmission()) return

        viewModelScope.launch {
            try {
                handleLoginResult(action(), fallbackMessageRes)
            } finally {
                finishSubmission()
            }
        }
    }

    private fun handleLoginResult(
        result: LoginWorkflowResult,
@@ -154,14 +149,18 @@ class LoginViewModel @Inject constructor(
        }
    }

    private fun beginSubmission() {
        _uiState.update { currentState ->
            currentState.copy(
    private fun beginSubmission(): Boolean {
        val currentState = _uiState.value
        if (currentState.isSubmitting) {
            return false
        }

        _uiState.value = currentState.copy(
            isSubmitting = true,
            errorMessage = null,
            navigationTarget = null,
        )
        }
        return true
    }

    private fun finishSubmission() {
+15 −6
Original line number Diff line number Diff line
@@ -112,7 +112,7 @@ class ApplicationViewModel @Inject constructor(
                applicationLiveData.postValue(result)

                updateShareVisibilityState(app.shareUri.toString())
                updateAppContentRatingState(packageName, app.contentRating)
                updateAppContentRatingState(packageName, app.contentRating, source)
            } catch (e: InternalException.AppNotFound) {
                _errorMessageLiveData.postValue(R.string.app_not_found)
                scheduleAutoRedirect()
@@ -124,16 +124,25 @@ class ApplicationViewModel @Inject constructor(

    private suspend fun updateAppContentRatingState(
        packageName: String,
        contentRating: ContentRating
        contentRating: ContentRating,
        source: Source,
    ) {
        // Initially update the state without ID to show the UI immediately
        _appContentRatingState.update { contentRating }

        val ratingWithId = playStoreRepository.getContentRatingWithId(packageName, contentRating)
        if (source != Source.PLAY_STORE) {
            return
        }

        runCatching {
            playStoreRepository.getContentRatingWithId(packageName, contentRating)
        }.onSuccess { ratingWithId ->
            // Later, update with a new rating; no visual change in the UI
            val updatedContentRating = contentRating.copy(id = ratingWithId.id)
            _appContentRatingState.update { updatedContentRating }
        }.onFailure { throwable ->
            Timber.w(throwable, "Failed to enrich content rating for %s", packageName)
        }
    }

    private fun updateShareVisibilityState(shareUri: String) {
+26 −0
Original line number Diff line number Diff line
/*
 * Copyright (C) 2026 e Foundation
 *
 * This program is free software: you can redistribute it and/or modify
 * it under the terms of the GNU General Public License as published by
 * the Free Software Foundation, either version 3 of the License, or
 * (at your option) any later version.
 *
 * This program is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU General Public License for more details.
 *
 * You should have received a copy of the GNU General Public License
 * along with this program.  If not, see <https://www.gnu.org/licenses/>.
 *
 */

package foundation.e.apps.ui.application.dialog

import androidx.lifecycle.ViewModel
import foundation.e.apps.data.application.data.Application

class PendingOwnUpdateViewModel : ViewModel() {
    var pendingApplication: Application? = null
}
+5 −6
Original line number Diff line number Diff line
@@ -50,6 +50,7 @@ import foundation.e.apps.ui.AppInfoFetchViewModel
import foundation.e.apps.ui.AppProgressViewModel
import foundation.e.apps.ui.PrivacyInfoViewModel
import foundation.e.apps.ui.application.dialog.OwnUpdateWarningDialogFragment
import foundation.e.apps.ui.application.dialog.PendingOwnUpdateViewModel
import foundation.e.apps.ui.application.dialog.ownUpdateWarningDialogAction
import foundation.e.apps.ui.application.subFrags.ApplicationDialogFragment
import foundation.e.apps.ui.parentFragment.LegacyLoadFailureDialogs
@@ -79,6 +80,7 @@ class ApplicationListFragment :
    private val sessionViewModel: SessionViewModel by activityViewModels()
    private val mainActivityViewModel: MainActivityViewModel by activityViewModels()
    private val appProgressViewModel: AppProgressViewModel by viewModels()
    private val pendingOwnUpdateViewModel: PendingOwnUpdateViewModel by viewModels()
    private val loadFailureDialogs by lazy {
        LegacyLoadFailureDialogs(this, sessionViewModel, loginViewModel)
    }
@@ -87,8 +89,6 @@ class ApplicationListFragment :
    private val binding get() = _binding!!

    private lateinit var listAdapter: ApplicationListRVAdapter
    private var pendingSelfUpdateApplication: Application? = null

    companion object {
        private const val OWN_UPDATE_DIALOG_TAG = "application_list_own_update_dialog"
    }
@@ -168,7 +168,6 @@ class ApplicationListFragment :
    override fun onDestroyView() {
        super.onDestroyView()
        loadFailureDialogs.dismissActiveDialog()
        pendingSelfUpdateApplication = null
        _binding?.recyclerView?.adapter = null
        _binding = null
    }
@@ -227,8 +226,8 @@ class ApplicationListFragment :
            OwnUpdateWarningDialogFragment.REQUEST_KEY,
            viewLifecycleOwner,
        ) { _, result ->
            val applicationToInstall = pendingSelfUpdateApplication
            pendingSelfUpdateApplication = null
            val applicationToInstall = pendingOwnUpdateViewModel.pendingApplication
            pendingOwnUpdateViewModel.pendingApplication = null

            if (result.ownUpdateWarningDialogAction() ==
                OwnUpdateWarningDialogFragment.ACTION_CONFIRM
@@ -239,7 +238,7 @@ class ApplicationListFragment :
    }

    private fun showOwnUpdateWarningDialog(application: Application) {
        pendingSelfUpdateApplication = application
        pendingOwnUpdateViewModel.pendingApplication = application
        if (childFragmentManager.findFragmentByTag(OWN_UPDATE_DIALOG_TAG) != null) {
            return
        }
+5 −6
Original line number Diff line number Diff line
@@ -54,6 +54,7 @@ import foundation.e.apps.ui.AppInfoFetchViewModel
import foundation.e.apps.ui.AppProgressViewModel
import foundation.e.apps.ui.PrivacyInfoViewModel
import foundation.e.apps.ui.application.dialog.OwnUpdateWarningDialogFragment
import foundation.e.apps.ui.application.dialog.PendingOwnUpdateViewModel
import foundation.e.apps.ui.application.dialog.ownUpdateWarningDialogAction
import foundation.e.apps.ui.application.subFrags.ApplicationDialogFragment
import foundation.e.apps.ui.applicationlist.ApplicationListRVAdapter
@@ -75,6 +76,7 @@ class SearchFragment : Fragment(R.layout.fragment_search), ApplicationInstaller,
    private val appInfoFetchViewModel: AppInfoFetchViewModel by viewModels()
    val mainActivityViewModel: MainActivityViewModel by activityViewModels()
    private val appProgressViewModel: AppProgressViewModel by viewModels()
    private val pendingOwnUpdateViewModel: PendingOwnUpdateViewModel by viewModels()

    private var lastSearch = ""

@@ -88,8 +90,6 @@ class SearchFragment : Fragment(R.layout.fragment_search), ApplicationInstaller,

    lateinit var filterChipOpenSource: Chip
    lateinit var filterChipPWA: Chip
    private var pendingSelfUpdateApplication: Application? = null

    override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
        super.onViewCreated(view, savedInstanceState)
        _binding = FragmentSearchBinding.bind(view)
@@ -411,7 +411,6 @@ class SearchFragment : Fragment(R.layout.fragment_search), ApplicationInstaller,

    override fun onDestroyView() {
        super.onDestroyView()
        pendingSelfUpdateApplication = null
        _binding = null
        searchView = null
        shimmerLayout = null
@@ -479,8 +478,8 @@ class SearchFragment : Fragment(R.layout.fragment_search), ApplicationInstaller,
            OwnUpdateWarningDialogFragment.REQUEST_KEY,
            viewLifecycleOwner,
        ) { _, result ->
            val applicationToInstall = pendingSelfUpdateApplication
            pendingSelfUpdateApplication = null
            val applicationToInstall = pendingOwnUpdateViewModel.pendingApplication
            pendingOwnUpdateViewModel.pendingApplication = null

            if (result.ownUpdateWarningDialogAction() ==
                OwnUpdateWarningDialogFragment.ACTION_CONFIRM
@@ -491,7 +490,7 @@ class SearchFragment : Fragment(R.layout.fragment_search), ApplicationInstaller,
    }

    private fun showOwnUpdateWarningDialog(application: Application) {
        pendingSelfUpdateApplication = application
        pendingOwnUpdateViewModel.pendingApplication = application
        if (childFragmentManager.findFragmentByTag(OWN_UPDATE_DIALOG_TAG) != null) {
            return
        }
Loading