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

Commit 2f53bfa4 authored by Aayush Gupta's avatar Aayush Gupta
Browse files

App Lounge: Migrate download and cancellation logic to unified viewModel

parent 5b3e17da
Loading
Loading
Loading
Loading
+73 −2
Original line number Diff line number Diff line
@@ -18,8 +18,12 @@

package foundation.e.apps

import android.graphics.Bitmap
import android.os.Build
import android.util.Base64
import android.widget.ImageView
import androidx.annotation.RequiresApi
import androidx.core.graphics.drawable.toBitmap
import androidx.lifecycle.LiveData
import androidx.lifecycle.MutableLiveData
import androidx.lifecycle.ViewModel
@@ -29,17 +33,20 @@ import com.aurora.gplayapi.data.models.AuthData
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.fused.FusedDownload
import foundation.e.apps.manager.fused.FusedManagerRepository
import foundation.e.apps.utils.DataStoreModule
import foundation.e.apps.utils.enums.Type
import kotlinx.coroutines.launch
import java.io.ByteArrayOutputStream
import javax.inject.Inject

@HiltViewModel
class MainActivityViewModel @Inject constructor(
    private val fusedAPIRepository: FusedAPIRepository,
    private val dataStoreModule: DataStoreModule,
    private val gson: Gson,
    private val dataStoreModule: DataStoreModule,
    private val fusedAPIRepository: FusedAPIRepository,
    private val fusedManagerRepository: FusedManagerRepository
) : ViewModel() {

@@ -56,6 +63,10 @@ class MainActivityViewModel @Inject constructor(
    val downloadList = fusedManagerRepository.getDownloadList()
    var isInstallInProgress = false

    /*
     * Authentication related functions
     */

    fun getAuthData() {
        if (!authRequestRunning) {
            authRequestRunning = true
@@ -84,15 +95,75 @@ class MainActivityViewModel @Inject constructor(
        return fusedAPIRepository.validateAuthData(authData)
    }

    /*
     * Notification functions
     */

    @RequiresApi(Build.VERSION_CODES.O)
    fun createNotificationChannels() {
        fusedManagerRepository.createNotificationChannels()
    }

    /*
     * Download and cancellation functions
     */

    fun downloadAndInstallApp(fusedDownload: FusedDownload) {
        isInstallInProgress = true
        viewModelScope.launch {
            fusedManagerRepository.downloadAndInstallApp(fusedDownload)
        }
    }

    fun getApplication(app: FusedApp, imageView: ImageView?) {
        viewModelScope.launch {
            val appIcon = imageView?.let { getImageBase64(it) } ?: ""
            val downloadLink = getAppDownloadLink(app)

            val fusedDownload = FusedDownload(
                app._id,
                app.origin,
                app.status,
                app.name,
                app.package_name,
                downloadLink,
                0,
                app.status,
                app.type,
                appIcon
            )
            fusedManagerRepository.addDownload(fusedDownload)
        }
    }

    fun cancelDownload(app: FusedApp) {
        viewModelScope.launch {
            fusedManagerRepository.cancelDownload(app.package_name)
        }
    }

    private suspend fun getAppDownloadLink(app: FusedApp): String {
        authData.value?.let {
            return if (app.type == Type.PWA) {
                app.url
            } else {
                fusedAPIRepository.getDownloadLink(
                    app._id,
                    app.package_name,
                    app.latest_version_code,
                    app.offer_type,
                    it,
                    app.origin
                )
            }
        }
        return String()
    }

    private fun getImageBase64(imageView: ImageView): String {
        val byteArrayOS = ByteArrayOutputStream()
        val bitmap = imageView.drawable.toBitmap()
        bitmap.compress(Bitmap.CompressFormat.PNG, 100, byteArrayOS)
        return Base64.encodeToString(byteArrayOS.toByteArray(), Base64.DEFAULT)
    }
}
+2 −1
Original line number Diff line number Diff line
@@ -18,6 +18,7 @@

package foundation.e.apps.api.fused

import android.widget.ImageView
import foundation.e.apps.api.fused.data.FusedApp

/**
@@ -25,7 +26,7 @@ import foundation.e.apps.api.fused.data.FusedApp
 */
interface FusedAPIInterface {

    fun getApplication(app: FusedApp)
    fun getApplication(app: FusedApp, appIcon: ImageView? = null)

    fun cancelDownload(app: FusedApp)
}
+7 −14
Original line number Diff line number Diff line
@@ -111,10 +111,7 @@ class ApplicationFragment : Fragment(R.layout.fragment_application) {
        mainActivityViewModel.downloadList.observe(viewLifecycleOwner) { list ->
            list.forEach {
                if (it.origin == args.origin && (it.package_name == args.packageName || it.id == args.id)) {
                    applicationViewModel.apply {
                        appStatus.value = it.status
                        fusedDownload = it
                    }
                    applicationViewModel.appStatus.value = it.status
                }
            }
        }
@@ -143,8 +140,8 @@ class ApplicationFragment : Fragment(R.layout.fragment_application) {
                        setTextColor(Color.WHITE)
                        backgroundTintList = ContextCompat.getColorStateList(view.context, R.color.colorAccent)
                        setOnClickListener {
                            mainActivityViewModel.authData.value?.let { data ->
                                applicationViewModel.getApplication(data, fusedApp, args.origin, applicationIcon!!)
                            applicationIcon?.let {
                                mainActivityViewModel.getApplication(fusedApp, it)
                            }
                        }
                    }
@@ -155,8 +152,8 @@ class ApplicationFragment : Fragment(R.layout.fragment_application) {
                    installButton.apply {
                        text = getString(R.string.install)
                        setOnClickListener {
                            mainActivityViewModel.authData.value?.let { data ->
                                applicationViewModel.getApplication(data, fusedApp, args.origin, applicationIcon!!)
                            applicationIcon?.let {
                                mainActivityViewModel.getApplication(fusedApp, it)
                            }
                        }
                    }
@@ -167,9 +164,7 @@ class ApplicationFragment : Fragment(R.layout.fragment_application) {
                    installButton.apply {
                        text = getString(R.string.cancel)
                        setOnClickListener {
                            applicationViewModel.apply {
                                cancelDownload()
                            }
                            mainActivityViewModel.cancelDownload(fusedApp)
                        }
                    }
                }
@@ -177,9 +172,7 @@ class ApplicationFragment : Fragment(R.layout.fragment_application) {
                    installButton.apply {
                        text = getString(R.string.cancel)
                        setOnClickListener {
                            applicationViewModel.apply {
                                cancelDownload()
                            }
                            mainActivityViewModel.cancelDownload(fusedApp)
                        }
                    }
                    downloadPB.visibility = View.VISIBLE
+2 −62
Original line number Diff line number Diff line
@@ -18,11 +18,6 @@

package foundation.e.apps.application

import android.graphics.Bitmap
import android.util.Base64
import android.util.Log
import android.widget.ImageView
import androidx.core.graphics.drawable.toBitmap
import androidx.lifecycle.MutableLiveData
import androidx.lifecycle.ViewModel
import androidx.lifecycle.viewModelScope
@@ -30,30 +25,23 @@ import com.aurora.gplayapi.data.models.AuthData
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.fused.FusedDownload
import foundation.e.apps.manager.download.data.DownloadProgressLD
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 kotlinx.coroutines.Dispatchers
import kotlinx.coroutines.launch
import java.io.ByteArrayOutputStream
import javax.inject.Inject

@HiltViewModel
class ApplicationViewModel @Inject constructor(
    private val fusedAPIRepository: FusedAPIRepository,
    private val downloadProgressLD: DownloadProgressLD,
    private val fusedManagerRepository: FusedManagerRepository
    downloadProgressLD: DownloadProgressLD,
    private val fusedAPIRepository: FusedAPIRepository
) : ViewModel() {

    val fusedApp: MutableLiveData<FusedApp> = MutableLiveData()
    val appStatus: MutableLiveData<Status?> = MutableLiveData()
    val downloadProgress = downloadProgressLD

    var fusedDownload: FusedDownload? = null

    fun getApplicationDetails(id: String, packageName: String, authData: AuthData, origin: Origin) {
        viewModelScope.launch(Dispatchers.IO) {
            fusedApp.postValue(
@@ -67,54 +55,6 @@ class ApplicationViewModel @Inject constructor(
        }
    }

    fun getApplication(authData: AuthData, app: FusedApp, origin: Origin, imageView: ImageView) {
        viewModelScope.launch {
            val byteArrayOS = ByteArrayOutputStream()
            val bitmap = imageView.drawable.toBitmap()
            bitmap.compress(Bitmap.CompressFormat.PNG, 100, byteArrayOS)

            val downloadLink = if (app.type == Type.PWA) {
                app.url
            } else {
                fusedAPIRepository.getDownloadLink(
                    app._id,
                    app.package_name,
                    app.latest_version_code,
                    app.offer_type,
                    authData,
                    origin
                )
            }

            fusedDownload = FusedDownload(
                app._id,
                app.origin,
                app.status,
                app.name,
                app.package_name,
                downloadLink,
                0,
                app.status,
                app.type,
                Base64.encodeToString(byteArrayOS.toByteArray(), Base64.DEFAULT)
            )
            fusedDownload?.let { fusedManagerRepository.addDownload(it) }
        }
    }

    fun cancelDownload() {
        viewModelScope.launch {
            fusedDownload?.let { fusedManagerRepository.cancelDownload(it.downloadId) }
        }
    }

    fun getYouTubeUrl(youTubeImg: String): String {
        val ytURL = "https://www.youtube.com/watch?v="
        val splitID = youTubeImg.split("https://i.ytimg.com/vi/")[1]
        val id = splitID.split("/")[0]
        return ytURL + id
    }

    fun transformPermsToString(permissions: MutableList<String>): String {
        // Filter list to only keep platform permissions
        val filteredList = permissions.filter {
+4 −5
Original line number Diff line number Diff line
@@ -20,6 +20,7 @@ package foundation.e.apps.applicationlist

import android.os.Bundle
import android.view.View
import android.widget.ImageView
import androidx.fragment.app.Fragment
import androidx.fragment.app.activityViewModels
import androidx.fragment.app.viewModels
@@ -121,13 +122,11 @@ class ApplicationListFragment : Fragment(R.layout.fragment_application_list), Fu
        super.onPause()
    }

    override fun getApplication(app: FusedApp) {
        mainActivityViewModel.authData.value?.let {
            viewModel.getApplication(it, app)
        }
    override fun getApplication(app: FusedApp, appIcon: ImageView?) {
        mainActivityViewModel.getApplication(app, appIcon)
    }

    override fun cancelDownload(app: FusedApp) {
        viewModel.cancelDownload(app.package_name)
        mainActivityViewModel.cancelDownload(app)
    }
}
Loading