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

Commit f565a8ab authored by Hasib Prince's avatar Hasib Prince
Browse files

App Lounge: conflict resolved for mergin 4799-purchase_app

parents 02c0e8fc 7290bac7
Loading
Loading
Loading
Loading
Loading
+49 −12
Original line number Diff line number Diff line
@@ -26,13 +26,16 @@ import androidx.appcompat.app.AppCompatActivity
import androidx.lifecycle.ViewModelProvider
import androidx.lifecycle.lifecycleScope
import androidx.navigation.NavOptions
import androidx.navigation.findNavController
import androidx.navigation.fragment.NavHostFragment
import androidx.navigation.ui.setupWithNavController
import com.aurora.gplayapi.exceptions.ApiException
import com.google.android.material.snackbar.Snackbar
import dagger.hilt.android.AndroidEntryPoint
import foundation.e.apps.application.subFrags.ApplicationDialogFragment
import foundation.e.apps.databinding.ActivityMainBinding
import foundation.e.apps.manager.workmanager.InstallWorkManager
import foundation.e.apps.purchase.AppPurchaseFragmentDirections
import foundation.e.apps.setup.signin.SignInViewModel
import foundation.e.apps.updates.UpdatesNotifier
import foundation.e.apps.utils.enums.Status
@@ -156,17 +159,6 @@ class MainActivity : AppCompatActivity() {

        // Observe and handle downloads
        viewModel.downloadList.observe(this) { list ->
//            val shouldDownload = list.any {
//                it.status == Status.INSTALLING || it.status == Status.DOWNLOADING || it.status == Status.INSTALLED
//            }
//            if (!shouldDownload && list.isNotEmpty()) {
//                for (item in list) {
//                    if (item.status == Status.QUEUED) {
//                        viewModel.downloadApp(item)
//                        break
//                    }
//                }
//            }
            list.forEach {
                if (it.status == Status.QUEUED) {
                    lifecycleScope.launch {
@@ -178,10 +170,41 @@ class MainActivity : AppCompatActivity() {
            }
        }

        viewModel.purchaseAppLiveData.observe(this) {
            val action =
                AppPurchaseFragmentDirections.actionGlobalAppPurchaseFragment(it.package_name)
            findNavController(R.id.fragment).navigate(action)
        }

        viewModel.errorMessage.observe(this) {
            when (it) {
                is ApiException.AppNotPurchased -> showSnackbarMessage(getString(R.string.message_app_available_later))
                else -> showSnackbarMessage(it.localizedMessage ?: getString(R.string.unknown_error))
                else -> showSnackbarMessage(
                    it.localizedMessage ?: getString(R.string.unknown_error)
                )
            }
        }

        viewModel.errorMessageStringResource.observe(this) {
            showSnackbarMessage(getString(it))
        }

        viewModel.isAppPurchased.observe(this) {
            if (it.isNotEmpty()) {
                startInstallationOfPurchasedApp(viewModel, it)
                ApplicationDialogFragment(
                    title = "Purchase complete!",
                    message = "Your app will automatically be downloaded in this device",
                    positiveButtonText = "OK"
                ).show(supportFragmentManager, TAG)
            }
        }

        viewModel.purchaseDeclined.observe(this) {
            if (it.isNotEmpty()) {
                lifecycleScope.launch {
                    viewModel.updateUnavailableForPurchaseDeclined(it)
                }
            }
        }

@@ -190,6 +213,20 @@ class MainActivity : AppCompatActivity() {
        }
    }

    private fun startInstallationOfPurchasedApp(
        viewModel: MainActivityViewModel,
        it: String
    ) {
        lifecycleScope.launch {
            val fusedDownload = viewModel.updateAwaitingForPurchasedApp(it)
            if (fusedDownload != null) {
                InstallWorkManager.enqueueWork(applicationContext, fusedDownload)
            } else {
                showSnackbarMessage(getString(R.string.paid_app_anonymous_message))
            }
        }
    }

    private fun showSnackbarMessage(message: String) {
        Snackbar.make(binding.root, message, Snackbar.LENGTH_SHORT).show()
    }
+82 −1
Original line number Diff line number Diff line
@@ -21,6 +21,7 @@ package foundation.e.apps
import android.graphics.Bitmap
import android.os.Build
import android.util.Base64
import android.util.Log
import android.widget.ImageView
import androidx.annotation.RequiresApi
import androidx.core.graphics.drawable.toBitmap
@@ -31,12 +32,14 @@ import androidx.lifecycle.asLiveData
import androidx.lifecycle.liveData
import androidx.lifecycle.viewModelScope
import com.aurora.gplayapi.data.models.AuthData
import com.aurora.gplayapi.exceptions.ApiException
import com.google.gson.Gson
import dagger.hilt.android.lifecycle.HiltViewModel
import foundation.e.apps.api.fused.FusedAPIRepository
import foundation.e.apps.api.fused.data.FusedApp
import foundation.e.apps.manager.database.fusedDownload.FusedDownload
import foundation.e.apps.manager.fused.FusedManagerRepository
import foundation.e.apps.utils.enums.Origin
import foundation.e.apps.utils.enums.Status
import foundation.e.apps.utils.enums.Type
import foundation.e.apps.utils.modules.DataStoreModule
@@ -61,6 +64,10 @@ class MainActivityViewModel @Inject constructor(
    private var _authData: MutableLiveData<AuthData> = MutableLiveData()
    val authData: LiveData<AuthData> = _authData
    val authValidity: MutableLiveData<Boolean> = MutableLiveData()
    private val _purchaseAppLiveData: MutableLiveData<FusedDownload> = MutableLiveData()
    val purchaseAppLiveData: LiveData<FusedDownload> = _purchaseAppLiveData
    val isAppPurchased: MutableLiveData<String> = MutableLiveData()
    val purchaseDeclined: MutableLiveData<String> = MutableLiveData()
    var authRequestRunning = false

    // Downloads
@@ -68,10 +75,17 @@ class MainActivityViewModel @Inject constructor(
    var installInProgress = false
    private val _errorMessage = MutableLiveData<Exception>()
    val errorMessage: LiveData<Exception> = _errorMessage

    private val _errorMessageStringResource = MutableLiveData<Int>()
    val errorMessageStringResource: LiveData<Int> = _errorMessageStringResource
    /*
     * Authentication related functions
     */

    companion object {
        private const val TAG = "MainActivityViewModel"
    }

    fun getAuthData() {
        if (!authRequestRunning) {
            authRequestRunning = true
@@ -124,6 +138,10 @@ class MainActivityViewModel @Inject constructor(
    }

    fun getApplication(app: FusedApp, imageView: ImageView?) {
        if (!app.isFree && authData.value?.isAnonymous == true) {
            _errorMessageStringResource.value = R.string.paid_app_anonymous_message
            return
        }
        viewModelScope.launch {
            val fusedDownload: FusedDownload
            try {
@@ -141,9 +159,16 @@ class MainActivityViewModel @Inject constructor(
                    mutableMapOf(),
                    app.status,
                    app.type,
                    appIcon
                    appIcon,
                    app.latest_version_code,
                    app.offer_type,
                    app.isFree
                )
            } catch (e: Exception) {
                if (e is ApiException.AppNotPurchased) {
                    handleAppNotPurchased(imageView, app)
                    return@launch
                }
                _errorMessage.value = e
                return@launch
            }
@@ -155,10 +180,66 @@ class MainActivityViewModel @Inject constructor(
        }
    }

    private fun handleAppNotPurchased(
        imageView: ImageView?,
        app: FusedApp
    ) {
        val appIcon = imageView?.let { getImageBase64(it) } ?: ""
        val fusedDownload = FusedDownload(
            app._id,
            app.origin,
            Status.PURCHASE_NEEDED,
            app.name,
            app.package_name,
            mutableListOf(),
            mutableMapOf(),
            app.status,
            app.type,
            appIcon,
            app.latest_version_code,
            app.offer_type,
            app.isFree
        )
        viewModelScope.launch {
            fusedManagerRepository.addFusedDownloadPurchaseNeeded(fusedDownload)
            _purchaseAppLiveData.postValue(fusedDownload)
        }
    }

    suspend fun updateAwaiting(fusedDownload: FusedDownload) {
        fusedManagerRepository.updateAwaiting(fusedDownload)
    }

    suspend fun updateAwaitingForPurchasedApp(packageName: String): FusedDownload? {
        val fusedDownload = fusedManagerRepository.getFusedDownload(packageName = packageName)
        authData.value?.let {
            if (!it.isAnonymous) {
                try {
                    fusedDownload.downloadURLList = fusedAPIRepository.getDownloadLink(
                        fusedDownload.id,
                        fusedDownload.package_name,
                        fusedDownload.versionCode,
                        fusedDownload.offerType,
                        it,
                        Origin.GPLAY
                    ).toMutableList()
                } catch (e: Exception) {
                    Log.e(TAG, e.stackTraceToString())
                    _errorMessage.value = e
                    return null
                }
                updateAwaiting(fusedDownload)
                return fusedDownload
            }
        }
        return null
    }

    suspend fun updateUnavailableForPurchaseDeclined(packageName: String) {
        val fusedDownload = fusedManagerRepository.getFusedDownload(packageName = packageName)
        fusedManagerRepository.updateUnavailable(fusedDownload)
    }

    fun cancelDownload(app: FusedApp) {
        viewModelScope.launch {
            val fusedDownload =
+4 −3
Original line number Diff line number Diff line
@@ -20,7 +20,6 @@ package foundation.e.apps.api.fused

import android.content.Context
import android.text.format.Formatter
import android.util.Log
import com.aurora.gplayapi.SearchSuggestEntry
import com.aurora.gplayapi.data.models.App
import com.aurora.gplayapi.data.models.Artwork
@@ -202,7 +201,8 @@ class FusedAPIImpl @Inject constructor(
            }
            return response?.apps
        } else {
            return gPlayAPIRepository.listApps(browseUrl, authData).map { app ->
            val listApps = gPlayAPIRepository.listApps(browseUrl, authData)
            return listApps.map { app ->
                app.transformToFusedApp()
            }
        }
@@ -496,7 +496,8 @@ class FusedAPIImpl @Inject constructor(
    }

    private suspend fun getGplaySearchResults(query: String, authData: AuthData): List<FusedApp> {
        return gPlayAPIRepository.getSearchResults(query, authData).map { app ->
        val searchResults = gPlayAPIRepository.getSearchResults(query, authData)
        return searchResults.map { app ->
            app.transformToFusedApp()
        }
    }
+3 −1
Original line number Diff line number Diff line
@@ -52,10 +52,12 @@ class ApplicationDialogFragment(
                positiveButtonAction?.invoke()
                this.dismiss()
            }
            .setNegativeButton(cancelButtonText) { _, _ ->
        if (cancelButtonText.isNotEmpty()) {
            materialAlertDialogBuilder.setNegativeButton(cancelButtonText) { _, _ ->
                cancelButtonAction?.invoke()
                this.dismiss()
            }
        }
        if (drawable != -1) {
            materialAlertDialogBuilder.setIcon(drawable)
        }
+1 −5
Original line number Diff line number Diff line
@@ -19,7 +19,6 @@
package foundation.e.apps.applicationlist

import android.os.Bundle
import android.util.Log
import android.view.View
import android.widget.ImageView
import androidx.fragment.app.Fragment
@@ -121,6 +120,7 @@ class ApplicationListFragment : Fragment(R.layout.fragment_application_list), Fu
                        message = getString(R.string.dialog_paidapp_message, fusedApp.name, fusedApp.price),
                        positiveButtonText = getString(R.string.dialog_confirm),
                        positiveButtonAction = {
                            getApplication(fusedApp)
                        },
                        cancelButtonText = getString(R.string.dialog_cancel),
                    ).show(childFragmentManager, "HomeFragment")
@@ -171,10 +171,6 @@ class ApplicationListFragment : Fragment(R.layout.fragment_application_list), Fu
                    val progress = appProgressViewModel.calculateProgress(fusedApp, it)
                    val downloadProgress =
                        ((progress.second / progress.first.toDouble()) * 100).toInt()
                    Log.d(
                        "HomeParentAdapter",
                        "download progress of ===> ${fusedApp.name} : $downloadProgress"
                    )
                    val viewHolder = recyclerView.findViewHolderForAdapterPosition(
                        adapter.currentList.indexOf(fusedApp)
                    )
Loading