Improve - Installed Apps, Updates & Blaclists
This commit is contained in:
committed by
Aayush Gupta
parent
a43779ed79
commit
a2fef6a897
@@ -4,7 +4,7 @@ import android.content.pm.PackageInfo
|
|||||||
import android.os.Process
|
import android.os.Process
|
||||||
|
|
||||||
fun PackageInfo.isApp(): Boolean {
|
fun PackageInfo.isApp(): Boolean {
|
||||||
if (this.applicationInfo == null) return false
|
if (this.applicationInfo == null || this.packageName.isEmpty()) return false
|
||||||
|
|
||||||
return when {
|
return when {
|
||||||
isQAndAbove() -> {
|
isQAndAbove() -> {
|
||||||
|
|||||||
@@ -28,8 +28,8 @@ import coil.transform.RoundedCornersTransformation
|
|||||||
import com.airbnb.epoxy.CallbackProp
|
import com.airbnb.epoxy.CallbackProp
|
||||||
import com.airbnb.epoxy.ModelProp
|
import com.airbnb.epoxy.ModelProp
|
||||||
import com.airbnb.epoxy.ModelView
|
import com.airbnb.epoxy.ModelView
|
||||||
|
import com.aurora.gplayapi.data.models.App
|
||||||
import com.aurora.store.R
|
import com.aurora.store.R
|
||||||
import com.aurora.store.data.model.Black
|
|
||||||
import com.aurora.store.databinding.ViewBlackBinding
|
import com.aurora.store.databinding.ViewBlackBinding
|
||||||
|
|
||||||
@ModelView(
|
@ModelView(
|
||||||
@@ -62,15 +62,15 @@ class BlackListView : RelativeLayout {
|
|||||||
}
|
}
|
||||||
|
|
||||||
@ModelProp
|
@ModelProp
|
||||||
fun black(black: Black) {
|
fun app(app: App) {
|
||||||
B.imgIcon.load(black.drawable) {
|
B.imgIcon.load(app.iconArtwork.url) {
|
||||||
placeholder(R.drawable.bg_placeholder)
|
placeholder(R.drawable.bg_placeholder)
|
||||||
transformations(RoundedCornersTransformation(25F))
|
transformations(RoundedCornersTransformation(25F))
|
||||||
}
|
}
|
||||||
|
|
||||||
B.txtLine1.text = black.displayName
|
B.txtLine1.text = app.displayName
|
||||||
B.txtLine2.text = black.packageName
|
B.txtLine2.text = app.packageName
|
||||||
B.txtLine3.text = ("${black.versionName}.${black.versionCode}")
|
B.txtLine3.text = ("${app.versionName}.${app.versionCode}")
|
||||||
}
|
}
|
||||||
|
|
||||||
@ModelProp
|
@ModelProp
|
||||||
|
|||||||
@@ -22,7 +22,7 @@ package com.aurora.store.view.ui.all
|
|||||||
import android.os.Bundle
|
import android.os.Bundle
|
||||||
import android.util.Log
|
import android.util.Log
|
||||||
import android.view.View
|
import android.view.View
|
||||||
import androidx.fragment.app.viewModels
|
import androidx.fragment.app.activityViewModels
|
||||||
import androidx.lifecycle.lifecycleScope
|
import androidx.lifecycle.lifecycleScope
|
||||||
import com.aurora.gplayapi.data.models.App
|
import com.aurora.gplayapi.data.models.App
|
||||||
import com.aurora.store.AuroraApp
|
import com.aurora.store.AuroraApp
|
||||||
@@ -46,7 +46,7 @@ class InstalledAppsFragment : BaseFragment(R.layout.fragment_apps) {
|
|||||||
private val binding: FragmentAppsBinding
|
private val binding: FragmentAppsBinding
|
||||||
get() = _binding!!
|
get() = _binding!!
|
||||||
|
|
||||||
private val viewModel: InstalledViewModel by viewModels()
|
private val viewModel: InstalledViewModel by activityViewModels()
|
||||||
|
|
||||||
companion object {
|
companion object {
|
||||||
@JvmStatic
|
@JvmStatic
|
||||||
@@ -60,7 +60,7 @@ class InstalledAppsFragment : BaseFragment(R.layout.fragment_apps) {
|
|||||||
is BusEvent.InstallEvent,
|
is BusEvent.InstallEvent,
|
||||||
is BusEvent.UninstallEvent,
|
is BusEvent.UninstallEvent,
|
||||||
is BusEvent.Blacklisted -> {
|
is BusEvent.Blacklisted -> {
|
||||||
viewModel.getInstalledApps(requireContext())
|
viewModel.fetchApps()
|
||||||
}
|
}
|
||||||
|
|
||||||
else -> {
|
else -> {
|
||||||
@@ -73,14 +73,12 @@ class InstalledAppsFragment : BaseFragment(R.layout.fragment_apps) {
|
|||||||
super.onViewCreated(view, savedInstanceState)
|
super.onViewCreated(view, savedInstanceState)
|
||||||
_binding = FragmentAppsBinding.bind(view)
|
_binding = FragmentAppsBinding.bind(view)
|
||||||
|
|
||||||
viewModel.liveData.observe(viewLifecycleOwner) {
|
viewLifecycleOwner.lifecycleScope.launch {
|
||||||
updateController(it)
|
viewModel.installedApps.collect {
|
||||||
|
updateController(it)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
updateController(null)
|
|
||||||
|
|
||||||
viewModel.getInstalledApps(view.context)
|
|
||||||
|
|
||||||
viewLifecycleOwner.lifecycleScope.launch {
|
viewLifecycleOwner.lifecycleScope.launch {
|
||||||
AuroraApp.flowEvent.busEvent.collect { onEvent(it) }
|
AuroraApp.flowEvent.busEvent.collect { onEvent(it) }
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -22,16 +22,18 @@ package com.aurora.store.view.ui.commons
|
|||||||
import android.os.Bundle
|
import android.os.Bundle
|
||||||
import android.view.View
|
import android.view.View
|
||||||
import androidx.fragment.app.Fragment
|
import androidx.fragment.app.Fragment
|
||||||
import androidx.fragment.app.viewModels
|
import androidx.fragment.app.activityViewModels
|
||||||
|
import androidx.lifecycle.lifecycleScope
|
||||||
import androidx.navigation.fragment.findNavController
|
import androidx.navigation.fragment.findNavController
|
||||||
|
import com.aurora.gplayapi.data.models.App
|
||||||
import com.aurora.store.R
|
import com.aurora.store.R
|
||||||
import com.aurora.store.data.model.Black
|
|
||||||
import com.aurora.store.data.providers.BlacklistProvider
|
import com.aurora.store.data.providers.BlacklistProvider
|
||||||
import com.aurora.store.databinding.ActivityGenericRecyclerBinding
|
import com.aurora.store.databinding.ActivityGenericRecyclerBinding
|
||||||
import com.aurora.store.view.epoxy.views.BlackListViewModel_
|
import com.aurora.store.view.epoxy.views.BlackListViewModel_
|
||||||
import com.aurora.store.view.epoxy.views.shimmer.AppListViewShimmerModel_
|
import com.aurora.store.view.epoxy.views.shimmer.AppListViewShimmerModel_
|
||||||
import com.aurora.store.viewmodel.all.BlacklistViewModel
|
import com.aurora.store.viewmodel.all.BlacklistViewModel
|
||||||
import dagger.hilt.android.AndroidEntryPoint
|
import dagger.hilt.android.AndroidEntryPoint
|
||||||
|
import kotlinx.coroutines.launch
|
||||||
|
|
||||||
@AndroidEntryPoint
|
@AndroidEntryPoint
|
||||||
class BlacklistFragment : Fragment(R.layout.activity_generic_recycler) {
|
class BlacklistFragment : Fragment(R.layout.activity_generic_recycler) {
|
||||||
@@ -40,7 +42,7 @@ class BlacklistFragment : Fragment(R.layout.activity_generic_recycler) {
|
|||||||
private val binding: ActivityGenericRecyclerBinding
|
private val binding: ActivityGenericRecyclerBinding
|
||||||
get() = _binding!!
|
get() = _binding!!
|
||||||
|
|
||||||
private val viewModel: BlacklistViewModel by viewModels()
|
private val viewModel: BlacklistViewModel by activityViewModels()
|
||||||
|
|
||||||
private lateinit var blacklistProvider: BlacklistProvider
|
private lateinit var blacklistProvider: BlacklistProvider
|
||||||
|
|
||||||
@@ -48,12 +50,12 @@ class BlacklistFragment : Fragment(R.layout.activity_generic_recycler) {
|
|||||||
super.onViewCreated(view, savedInstanceState)
|
super.onViewCreated(view, savedInstanceState)
|
||||||
|
|
||||||
_binding = ActivityGenericRecyclerBinding.bind(view)
|
_binding = ActivityGenericRecyclerBinding.bind(view)
|
||||||
blacklistProvider = BlacklistProvider.with(view.context)
|
blacklistProvider = BlacklistProvider.with(requireContext())
|
||||||
|
|
||||||
viewModel.liveData.observe(viewLifecycleOwner) {
|
viewLifecycleOwner.lifecycleScope.launch {
|
||||||
updateController(it.sortedByDescending { app ->
|
viewModel.blackListedApps.collect {
|
||||||
blacklistProvider.isBlacklisted(app.packageName)
|
updateController(it)
|
||||||
})
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Toolbar
|
// Toolbar
|
||||||
@@ -61,8 +63,6 @@ class BlacklistFragment : Fragment(R.layout.activity_generic_recycler) {
|
|||||||
binding.layoutToolbarAction.imgActionPrimary.setOnClickListener {
|
binding.layoutToolbarAction.imgActionPrimary.setOnClickListener {
|
||||||
findNavController().navigateUp()
|
findNavController().navigateUp()
|
||||||
}
|
}
|
||||||
|
|
||||||
updateController(null)
|
|
||||||
}
|
}
|
||||||
|
|
||||||
override fun onPause() {
|
override fun onPause() {
|
||||||
@@ -75,7 +75,7 @@ class BlacklistFragment : Fragment(R.layout.activity_generic_recycler) {
|
|||||||
_binding = null
|
_binding = null
|
||||||
}
|
}
|
||||||
|
|
||||||
private fun updateController(blackList: List<Black>?) {
|
private fun updateController(blackList: List<App>?) {
|
||||||
binding.recycler.withModels {
|
binding.recycler.withModels {
|
||||||
setFilterDuplicates(true)
|
setFilterDuplicates(true)
|
||||||
if (blackList == null) {
|
if (blackList == null) {
|
||||||
@@ -86,22 +86,24 @@ class BlacklistFragment : Fragment(R.layout.activity_generic_recycler) {
|
|||||||
)
|
)
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
blackList.forEach {
|
blackList
|
||||||
add(
|
.sortedByDescending { app -> blacklistProvider.isBlacklisted(app.packageName) }
|
||||||
BlackListViewModel_()
|
.forEach {
|
||||||
.id(it.packageName.hashCode())
|
add(
|
||||||
.black(it)
|
BlackListViewModel_()
|
||||||
.markChecked(viewModel.selected.contains(it.packageName))
|
.id(it.packageName.hashCode())
|
||||||
.checked { _, isChecked ->
|
.app(it)
|
||||||
if (isChecked)
|
.markChecked(viewModel.selected.contains(it.packageName))
|
||||||
viewModel.selected.add(it.packageName)
|
.checked { _, isChecked ->
|
||||||
else
|
if (isChecked)
|
||||||
viewModel.selected.remove(it.packageName)
|
viewModel.selected.add(it.packageName)
|
||||||
|
else
|
||||||
|
viewModel.selected.remove(it.packageName)
|
||||||
|
|
||||||
requestModelBuild()
|
requestModelBuild()
|
||||||
}
|
}
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -97,52 +97,53 @@ class UpdatesFragment : BaseFragment(R.layout.fragment_updates) {
|
|||||||
true
|
true
|
||||||
}
|
}
|
||||||
|
|
||||||
viewModel.observe()
|
|
||||||
viewLifecycleOwner.lifecycleScope.launch {
|
viewLifecycleOwner.lifecycleScope.launch {
|
||||||
viewModel.updates.combine(viewModel.downloadsList) { uList, dList ->
|
viewModel.updates
|
||||||
uList?.associateWith { a ->
|
.combine(viewModel.downloadsList) { uList, dList ->
|
||||||
dList.find { it.packageName == a.packageName && it.versionCode == a.versionCode }
|
uList?.associateWith { a ->
|
||||||
}
|
dList.find { it.packageName == a.packageName && it.versionCode == a.versionCode }
|
||||||
}.collectLatest { map ->
|
}
|
||||||
updateController(map)
|
}.collectLatest { map ->
|
||||||
binding.swipeRefreshLayout.isRefreshing = false
|
updateController(map)
|
||||||
viewModel.updateAllEnqueued = map?.values?.all { it?.isRunning == true } ?: false
|
binding.swipeRefreshLayout.isRefreshing = false
|
||||||
|
viewModel.updateAllEnqueued =
|
||||||
if (!map.isNullOrEmpty()) {
|
map?.values?.all { it?.isRunning == true } ?: false
|
||||||
binding.updateFab.apply {
|
|
||||||
visibility = View.VISIBLE
|
if (!map.isNullOrEmpty()) {
|
||||||
if (viewModel.updateAllEnqueued) {
|
binding.updateFab.apply {
|
||||||
setImageDrawable(
|
visibility = View.VISIBLE
|
||||||
ContextCompat.getDrawable(
|
if (viewModel.updateAllEnqueued) {
|
||||||
requireContext(),
|
setImageDrawable(
|
||||||
R.drawable.ic_cancel
|
ContextCompat.getDrawable(
|
||||||
)
|
requireContext(),
|
||||||
)
|
R.drawable.ic_cancel
|
||||||
} else {
|
)
|
||||||
setImageDrawable(
|
)
|
||||||
ContextCompat.getDrawable(
|
} else {
|
||||||
requireContext(),
|
setImageDrawable(
|
||||||
R.drawable.ic_installation
|
ContextCompat.getDrawable(
|
||||||
)
|
requireContext(),
|
||||||
)
|
R.drawable.ic_installation
|
||||||
}
|
)
|
||||||
setOnClickListener {
|
)
|
||||||
if (viewModel.updateAllEnqueued) {
|
}
|
||||||
cancelAll()
|
setOnClickListener {
|
||||||
} else {
|
if (viewModel.updateAllEnqueued) {
|
||||||
map.keys.forEach { updateSingle(it, true) }
|
cancelAll()
|
||||||
}
|
} else {
|
||||||
binding.recycler.requestModelBuild()
|
map.keys.forEach { updateSingle(it, true) }
|
||||||
}
|
}
|
||||||
|
binding.recycler.requestModelBuild()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
binding.updateFab.visibility = View.GONE
|
||||||
}
|
}
|
||||||
} else {
|
|
||||||
binding.updateFab.visibility = View.GONE
|
|
||||||
}
|
}
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
binding.swipeRefreshLayout.setOnRefreshListener {
|
binding.swipeRefreshLayout.setOnRefreshListener {
|
||||||
viewModel.observe(true)
|
viewModel.fetchUpdates()
|
||||||
}
|
}
|
||||||
|
|
||||||
viewLifecycleOwner.lifecycleScope.launch {
|
viewLifecycleOwner.lifecycleScope.launch {
|
||||||
@@ -158,7 +159,7 @@ class UpdatesFragment : BaseFragment(R.layout.fragment_updates) {
|
|||||||
private fun onEvent(event: BusEvent) {
|
private fun onEvent(event: BusEvent) {
|
||||||
when (event) {
|
when (event) {
|
||||||
is BusEvent.InstallEvent, is BusEvent.UninstallEvent -> {
|
is BusEvent.InstallEvent, is BusEvent.UninstallEvent -> {
|
||||||
viewModel.observe(true)
|
viewModel.fetchUpdates()
|
||||||
}
|
}
|
||||||
|
|
||||||
else -> {}
|
else -> {}
|
||||||
|
|||||||
@@ -21,18 +21,19 @@ package com.aurora.store.viewmodel.all
|
|||||||
|
|
||||||
import android.annotation.SuppressLint
|
import android.annotation.SuppressLint
|
||||||
import android.content.Context
|
import android.content.Context
|
||||||
import android.content.pm.PackageManager
|
|
||||||
import androidx.core.content.pm.PackageInfoCompat
|
|
||||||
import androidx.lifecycle.MutableLiveData
|
|
||||||
import androidx.lifecycle.ViewModel
|
import androidx.lifecycle.ViewModel
|
||||||
import androidx.lifecycle.viewModelScope
|
import androidx.lifecycle.viewModelScope
|
||||||
import com.aurora.extensions.isApp
|
import com.aurora.extensions.isApp
|
||||||
import com.aurora.store.data.model.Black
|
import com.aurora.gplayapi.data.models.App
|
||||||
|
import com.aurora.gplayapi.helpers.AppDetailsHelper
|
||||||
|
import com.aurora.store.data.network.HttpClient
|
||||||
|
import com.aurora.store.data.providers.AuthProvider
|
||||||
import com.aurora.store.data.providers.BlacklistProvider
|
import com.aurora.store.data.providers.BlacklistProvider
|
||||||
import com.aurora.store.util.PackageUtil
|
|
||||||
import dagger.hilt.android.lifecycle.HiltViewModel
|
import dagger.hilt.android.lifecycle.HiltViewModel
|
||||||
import dagger.hilt.android.qualifiers.ApplicationContext
|
import dagger.hilt.android.qualifiers.ApplicationContext
|
||||||
import kotlinx.coroutines.Dispatchers
|
import kotlinx.coroutines.Dispatchers
|
||||||
|
import kotlinx.coroutines.flow.MutableStateFlow
|
||||||
|
import kotlinx.coroutines.flow.asStateFlow
|
||||||
import kotlinx.coroutines.launch
|
import kotlinx.coroutines.launch
|
||||||
import kotlinx.coroutines.supervisorScope
|
import kotlinx.coroutines.supervisorScope
|
||||||
import java.util.Locale
|
import java.util.Locale
|
||||||
@@ -41,40 +42,36 @@ import javax.inject.Inject
|
|||||||
@HiltViewModel
|
@HiltViewModel
|
||||||
@SuppressLint("StaticFieldLeak") // false positive, see https://github.com/google/dagger/issues/3253
|
@SuppressLint("StaticFieldLeak") // false positive, see https://github.com/google/dagger/issues/3253
|
||||||
class BlacklistViewModel @Inject constructor(
|
class BlacklistViewModel @Inject constructor(
|
||||||
@ApplicationContext private val context: Context
|
@ApplicationContext private val context: Context,
|
||||||
|
authProvider: AuthProvider
|
||||||
) : ViewModel() {
|
) : ViewModel() {
|
||||||
|
|
||||||
private val packageManager: PackageManager = context.packageManager
|
|
||||||
private val blacklistProvider: BlacklistProvider = BlacklistProvider.with(context)
|
private val blacklistProvider: BlacklistProvider = BlacklistProvider.with(context)
|
||||||
|
private val appDetailsHelper = AppDetailsHelper(authProvider.authData)
|
||||||
|
.using(HttpClient.getPreferredClient(context))
|
||||||
|
|
||||||
|
private val _blacklistedApps = MutableStateFlow<List<App>?>(null)
|
||||||
|
val blackListedApps = _blacklistedApps.asStateFlow()
|
||||||
|
|
||||||
var blackList: MutableList<Black> = mutableListOf()
|
|
||||||
var selected: MutableSet<String> = mutableSetOf()
|
var selected: MutableSet<String> = mutableSetOf()
|
||||||
|
|
||||||
val liveData: MutableLiveData<List<Black>> = MutableLiveData()
|
|
||||||
|
|
||||||
init {
|
init {
|
||||||
selected = blacklistProvider.getBlackList()
|
selected = blacklistProvider.getBlackList()
|
||||||
observe()
|
fetchApps()
|
||||||
}
|
}
|
||||||
|
|
||||||
fun observe() {
|
private fun fetchApps() {
|
||||||
viewModelScope.launch(Dispatchers.IO) {
|
viewModelScope.launch(Dispatchers.IO) {
|
||||||
supervisorScope {
|
supervisorScope {
|
||||||
try {
|
try {
|
||||||
val packageInfoMap = PackageUtil.getPackageInfoMap(context)
|
val packageNames = context.packageManager.getInstalledPackages(0)
|
||||||
packageInfoMap.values
|
|
||||||
.filter { it.isApp() }
|
.filter { it.isApp() }
|
||||||
.forEach {
|
.map { it.packageName }
|
||||||
val black = Black(it.packageName).apply {
|
|
||||||
displayName = packageManager.getApplicationLabel(it.applicationInfo)
|
val apps = appDetailsHelper
|
||||||
.toString()
|
.getAppByPackageName(packageNames)
|
||||||
versionCode = PackageInfoCompat.getLongVersionCode(it)
|
.filter { it.displayName.isNotBlank() }
|
||||||
versionName = it.versionName
|
|
||||||
drawable = packageManager.getApplicationIcon(packageName)
|
_blacklistedApps.emit(apps.sortedBy { it.displayName.lowercase(Locale.getDefault()) })
|
||||||
}
|
|
||||||
blackList.add(black)
|
|
||||||
}
|
|
||||||
liveData.postValue(blackList.sortedBy { it.displayName.lowercase(Locale.getDefault()) })
|
|
||||||
} catch (e: Exception) {
|
} catch (e: Exception) {
|
||||||
e.printStackTrace()
|
e.printStackTrace()
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -28,26 +28,40 @@ import com.aurora.gplayapi.data.models.App
|
|||||||
import com.aurora.store.data.providers.AuthProvider
|
import com.aurora.store.data.providers.AuthProvider
|
||||||
import com.aurora.store.util.AppUtil
|
import com.aurora.store.util.AppUtil
|
||||||
import dagger.hilt.android.lifecycle.HiltViewModel
|
import dagger.hilt.android.lifecycle.HiltViewModel
|
||||||
|
import dagger.hilt.android.qualifiers.ApplicationContext
|
||||||
import kotlinx.coroutines.Dispatchers
|
import kotlinx.coroutines.Dispatchers
|
||||||
|
import kotlinx.coroutines.flow.MutableStateFlow
|
||||||
|
import kotlinx.coroutines.flow.asStateFlow
|
||||||
import kotlinx.coroutines.launch
|
import kotlinx.coroutines.launch
|
||||||
import java.util.Locale
|
import java.util.Locale
|
||||||
import javax.inject.Inject
|
import javax.inject.Inject
|
||||||
|
|
||||||
@HiltViewModel
|
@HiltViewModel
|
||||||
class InstalledViewModel @Inject constructor(
|
class InstalledViewModel @Inject constructor(
|
||||||
|
@ApplicationContext private val context: Context,
|
||||||
private val authProvider: AuthProvider
|
private val authProvider: AuthProvider
|
||||||
) : ViewModel() {
|
) : ViewModel() {
|
||||||
|
|
||||||
private val TAG = InstalledViewModel::class.java.simpleName
|
private val TAG = InstalledViewModel::class.java.simpleName
|
||||||
|
|
||||||
private var appList: MutableList<App> = mutableListOf()
|
private val _installedApps = MutableStateFlow<List<App>?>(null)
|
||||||
|
val installedApps = _installedApps.asStateFlow()
|
||||||
|
|
||||||
val liveData: MutableLiveData<List<App>> = MutableLiveData()
|
val liveData: MutableLiveData<List<App>> = MutableLiveData()
|
||||||
|
|
||||||
fun getInstalledApps(context: Context) {
|
init {
|
||||||
|
fetchApps()
|
||||||
|
}
|
||||||
|
|
||||||
|
fun fetchApps() {
|
||||||
viewModelScope.launch(Dispatchers.IO) {
|
viewModelScope.launch(Dispatchers.IO) {
|
||||||
try {
|
try {
|
||||||
appList = AppUtil.getFilteredInstalledApps(context, authProvider.authData).toMutableList()
|
val apps = AppUtil.getFilteredInstalledApps(
|
||||||
liveData.postValue(appList.sortedBy { it.displayName.lowercase(Locale.getDefault()) })
|
context,
|
||||||
|
authProvider.authData
|
||||||
|
)
|
||||||
|
|
||||||
|
_installedApps.emit(apps.sortedBy { it.displayName.lowercase(Locale.getDefault()) })
|
||||||
} catch (exception: Exception) {
|
} catch (exception: Exception) {
|
||||||
Log.e(TAG, "Failed to get installed apps", exception)
|
Log.e(TAG, "Failed to get installed apps", exception)
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -33,11 +33,10 @@ import com.google.gson.Gson
|
|||||||
import dagger.hilt.android.lifecycle.HiltViewModel
|
import dagger.hilt.android.lifecycle.HiltViewModel
|
||||||
import dagger.hilt.android.qualifiers.ApplicationContext
|
import dagger.hilt.android.qualifiers.ApplicationContext
|
||||||
import kotlinx.coroutines.Dispatchers
|
import kotlinx.coroutines.Dispatchers
|
||||||
import kotlinx.coroutines.flow.MutableSharedFlow
|
|
||||||
import kotlinx.coroutines.flow.MutableStateFlow
|
import kotlinx.coroutines.flow.MutableStateFlow
|
||||||
import kotlinx.coroutines.flow.asSharedFlow
|
|
||||||
import kotlinx.coroutines.flow.asStateFlow
|
import kotlinx.coroutines.flow.asStateFlow
|
||||||
import kotlinx.coroutines.launch
|
import kotlinx.coroutines.launch
|
||||||
|
import kotlinx.coroutines.supervisorScope
|
||||||
import java.util.Locale
|
import java.util.Locale
|
||||||
import javax.inject.Inject
|
import javax.inject.Inject
|
||||||
|
|
||||||
@@ -56,34 +55,31 @@ class UpdatesViewModel @Inject constructor(
|
|||||||
private val _updates = MutableStateFlow<List<App>?>(null)
|
private val _updates = MutableStateFlow<List<App>?>(null)
|
||||||
val updates = _updates.asStateFlow()
|
val updates = _updates.asStateFlow()
|
||||||
|
|
||||||
val stash: MutableList<App> = mutableListOf()
|
|
||||||
|
|
||||||
val downloadsList get() = downloadWorkerUtil.downloadsList
|
val downloadsList get() = downloadWorkerUtil.downloadsList
|
||||||
|
|
||||||
fun observe(forceRefresh: Boolean = false) {
|
init {
|
||||||
|
fetchUpdates()
|
||||||
|
}
|
||||||
|
|
||||||
|
fun fetchUpdates() {
|
||||||
viewModelScope.launch(Dispatchers.IO) {
|
viewModelScope.launch(Dispatchers.IO) {
|
||||||
if (stash.isNotEmpty() && !forceRefresh) {
|
supervisorScope {
|
||||||
_updates.emit(stash)
|
try {
|
||||||
}
|
val isExtendedUpdateEnabled = Preferences.getBoolean(
|
||||||
|
context, Preferences.PREFERENCE_UPDATES_EXTENDED
|
||||||
|
)
|
||||||
|
|
||||||
try {
|
val updates = AppUtil.getUpdatableApps(
|
||||||
val isExtendedUpdateEnabled = Preferences.getBoolean(
|
context,
|
||||||
context, Preferences.PREFERENCE_UPDATES_EXTENDED
|
authProvider.authData,
|
||||||
)
|
gson,
|
||||||
|
!isExtendedUpdateEnabled
|
||||||
|
).sortedBy { it.displayName.lowercase(Locale.getDefault()) }
|
||||||
|
|
||||||
val updates = AppUtil.getUpdatableApps(
|
_updates.emit(updates)
|
||||||
context,
|
} catch (exception: Exception) {
|
||||||
authProvider.authData,
|
Log.d(TAG, "Failed to get updates", exception)
|
||||||
gson,
|
}
|
||||||
!isExtendedUpdateEnabled
|
|
||||||
).sortedBy { it.displayName.lowercase(Locale.getDefault()) }
|
|
||||||
|
|
||||||
stash.clear()
|
|
||||||
stash.addAll(updates)
|
|
||||||
|
|
||||||
_updates.emit(updates)
|
|
||||||
} catch (exception: Exception) {
|
|
||||||
Log.d(TAG, "Failed to get updates", exception)
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user