Improve Apps & Games page
This commit is contained in:
@@ -48,21 +48,12 @@ abstract class EndlessRecyclerOnScrollListener : RecyclerView.OnScrollListener {
|
||||
|
||||
constructor()
|
||||
|
||||
constructor(layoutManager: RecyclerView.LayoutManager) {
|
||||
this.layoutManager = layoutManager
|
||||
}
|
||||
|
||||
constructor(visibleThreshold: Int) {
|
||||
this.visibleThreshold = visibleThreshold
|
||||
}
|
||||
|
||||
constructor(layoutManager: RecyclerView.LayoutManager, visibleThreshold: Int) {
|
||||
this.layoutManager = layoutManager
|
||||
this.visibleThreshold = visibleThreshold
|
||||
}
|
||||
|
||||
private fun findFirstVisibleItemPosition(recyclerView: RecyclerView): Int {
|
||||
val child = findOneVisibleChild(0, layoutManager.childCount, false, true)
|
||||
val child = findOneVisibleChild(0, layoutManager.childCount, true, false)
|
||||
return if (child == null) RecyclerView.NO_POSITION else recyclerView.getChildAdapterPosition(
|
||||
child
|
||||
)
|
||||
|
||||
@@ -26,7 +26,7 @@ import android.view.ViewGroup
|
||||
import androidx.lifecycle.ViewModelProvider
|
||||
import com.aurora.gplayapi.data.models.App
|
||||
import com.aurora.store.R
|
||||
import com.aurora.store.databinding.FragmentUpdatesBinding
|
||||
import com.aurora.store.databinding.FragmentAppsBinding
|
||||
import com.aurora.store.view.epoxy.views.HeaderViewModel_
|
||||
import com.aurora.store.view.epoxy.views.app.AppListViewModel_
|
||||
import com.aurora.store.view.epoxy.views.shimmer.AppListViewShimmerModel_
|
||||
@@ -36,14 +36,12 @@ import com.aurora.store.viewmodel.all.InstalledViewModel
|
||||
class InstalledAppsFragment : BaseFragment() {
|
||||
|
||||
private lateinit var VM: InstalledViewModel
|
||||
private lateinit var B: FragmentUpdatesBinding
|
||||
private lateinit var B: FragmentAppsBinding
|
||||
|
||||
companion object {
|
||||
@JvmStatic
|
||||
fun newInstance(): InstalledAppsFragment {
|
||||
return InstalledAppsFragment().apply {
|
||||
|
||||
}
|
||||
return InstalledAppsFragment()
|
||||
}
|
||||
}
|
||||
|
||||
@@ -52,15 +50,15 @@ class InstalledAppsFragment : BaseFragment() {
|
||||
container: ViewGroup?,
|
||||
savedInstanceState: Bundle?
|
||||
): View {
|
||||
B = FragmentUpdatesBinding.bind(
|
||||
B = FragmentAppsBinding.bind(
|
||||
inflater.inflate(
|
||||
R.layout.fragment_updates,
|
||||
R.layout.fragment_apps,
|
||||
container,
|
||||
false
|
||||
)
|
||||
)
|
||||
|
||||
VM = ViewModelProvider(requireActivity()).get(InstalledViewModel::class.java)
|
||||
VM = ViewModelProvider(requireActivity())[InstalledViewModel::class.java]
|
||||
|
||||
return B.root
|
||||
}
|
||||
@@ -69,11 +67,6 @@ class InstalledAppsFragment : BaseFragment() {
|
||||
super.onViewCreated(view, savedInstanceState)
|
||||
VM.liveData.observe(viewLifecycleOwner) {
|
||||
updateController(it)
|
||||
B.swipeRefreshLayout.isRefreshing = false
|
||||
}
|
||||
|
||||
B.swipeRefreshLayout.setOnRefreshListener {
|
||||
VM.observe()
|
||||
}
|
||||
|
||||
updateController(null)
|
||||
@@ -83,7 +76,7 @@ class InstalledAppsFragment : BaseFragment() {
|
||||
B.recycler.withModels {
|
||||
setFilterDuplicates(true)
|
||||
if (appList == null) {
|
||||
for (i in 1..6) {
|
||||
for (i in 1..10) {
|
||||
add(
|
||||
AppListViewShimmerModel_()
|
||||
.id(i)
|
||||
|
||||
@@ -26,6 +26,7 @@ import android.view.ViewGroup
|
||||
import androidx.lifecycle.ViewModelProvider
|
||||
import com.aurora.gplayapi.data.models.StreamCluster
|
||||
import com.aurora.store.R
|
||||
import com.aurora.store.databinding.FragmentAppsBinding
|
||||
import com.aurora.store.databinding.FragmentUpdatesBinding
|
||||
import com.aurora.store.view.custom.recycler.EndlessRecyclerOnScrollListener
|
||||
import com.aurora.store.view.epoxy.views.AppProgressViewModel_
|
||||
@@ -38,7 +39,7 @@ import com.aurora.store.viewmodel.all.LibraryAppsViewModel
|
||||
class LibraryAppsFragment : BaseFragment() {
|
||||
|
||||
private lateinit var VM: LibraryAppsViewModel
|
||||
private lateinit var B: FragmentUpdatesBinding
|
||||
private lateinit var B: FragmentAppsBinding
|
||||
lateinit var endlessRecyclerOnScrollListener: EndlessRecyclerOnScrollListener
|
||||
|
||||
companion object {
|
||||
@@ -55,9 +56,9 @@ class LibraryAppsFragment : BaseFragment() {
|
||||
container: ViewGroup?,
|
||||
savedInstanceState: Bundle?
|
||||
): View {
|
||||
B = FragmentUpdatesBinding.bind(
|
||||
B = FragmentAppsBinding.bind(
|
||||
inflater.inflate(
|
||||
R.layout.fragment_updates,
|
||||
R.layout.fragment_apps,
|
||||
container,
|
||||
false
|
||||
)
|
||||
@@ -70,7 +71,6 @@ class LibraryAppsFragment : BaseFragment() {
|
||||
|
||||
override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
|
||||
super.onViewCreated(view, savedInstanceState)
|
||||
B.swipeRefreshLayout.isEnabled = false
|
||||
VM.liveData.observe(viewLifecycleOwner) {
|
||||
updateController(it)
|
||||
}
|
||||
@@ -92,7 +92,7 @@ class LibraryAppsFragment : BaseFragment() {
|
||||
B.recycler.withModels {
|
||||
setFilterDuplicates(true)
|
||||
if (streamCluster == null) {
|
||||
for (i in 1..6) {
|
||||
for (i in 1..10) {
|
||||
add(
|
||||
AppListViewShimmerModel_()
|
||||
.id(i)
|
||||
|
||||
@@ -24,28 +24,26 @@ import android.view.LayoutInflater
|
||||
import android.view.View
|
||||
import android.view.ViewGroup
|
||||
import androidx.lifecycle.ViewModelProvider
|
||||
import com.aurora.gplayapi.data.models.App
|
||||
import com.aurora.store.R
|
||||
import com.aurora.store.databinding.FragmentUpdatesBinding
|
||||
import com.aurora.store.databinding.FragmentAppsBinding
|
||||
import com.aurora.store.view.custom.recycler.EndlessRecyclerOnScrollListener
|
||||
import com.aurora.store.view.epoxy.views.HeaderViewModel_
|
||||
import com.aurora.store.view.epoxy.views.AppProgressViewModel_
|
||||
import com.aurora.store.view.epoxy.views.app.AppListViewModel_
|
||||
import com.aurora.store.view.epoxy.views.shimmer.AppListViewShimmerModel_
|
||||
import com.aurora.store.view.ui.commons.BaseFragment
|
||||
import com.aurora.store.viewmodel.all.PaginatedAppList
|
||||
import com.aurora.store.viewmodel.all.PurchasedViewModel
|
||||
|
||||
class PurchasedAppsFragment : BaseFragment() {
|
||||
|
||||
private lateinit var VM: PurchasedViewModel
|
||||
private lateinit var B: FragmentUpdatesBinding
|
||||
private lateinit var B: FragmentAppsBinding
|
||||
lateinit var endlessRecyclerOnScrollListener: EndlessRecyclerOnScrollListener
|
||||
|
||||
companion object {
|
||||
@JvmStatic
|
||||
fun newInstance(): PurchasedAppsFragment {
|
||||
return PurchasedAppsFragment().apply {
|
||||
|
||||
}
|
||||
return PurchasedAppsFragment()
|
||||
}
|
||||
}
|
||||
|
||||
@@ -54,15 +52,15 @@ class PurchasedAppsFragment : BaseFragment() {
|
||||
container: ViewGroup?,
|
||||
savedInstanceState: Bundle?
|
||||
): View {
|
||||
B = FragmentUpdatesBinding.bind(
|
||||
B = FragmentAppsBinding.bind(
|
||||
inflater.inflate(
|
||||
R.layout.fragment_updates,
|
||||
R.layout.fragment_apps,
|
||||
container,
|
||||
false
|
||||
)
|
||||
)
|
||||
|
||||
VM = ViewModelProvider(requireActivity()).get(PurchasedViewModel::class.java)
|
||||
VM = ViewModelProvider(requireActivity())[PurchasedViewModel::class.java]
|
||||
|
||||
return B.root
|
||||
}
|
||||
@@ -71,11 +69,6 @@ class PurchasedAppsFragment : BaseFragment() {
|
||||
super.onViewCreated(view, savedInstanceState)
|
||||
VM.liveData.observe(viewLifecycleOwner) {
|
||||
updateController(it)
|
||||
B.swipeRefreshLayout.isRefreshing = false
|
||||
}
|
||||
|
||||
B.swipeRefreshLayout.setOnRefreshListener {
|
||||
VM.observe()
|
||||
}
|
||||
|
||||
attachRecycler()
|
||||
@@ -84,32 +77,28 @@ class PurchasedAppsFragment : BaseFragment() {
|
||||
}
|
||||
|
||||
private fun attachRecycler() {
|
||||
endlessRecyclerOnScrollListener = object : EndlessRecyclerOnScrollListener() {
|
||||
val endlessRecyclerOnScrollListener = object : EndlessRecyclerOnScrollListener(8) {
|
||||
override fun onLoadMore(currentPage: Int) {
|
||||
VM.observe()
|
||||
}
|
||||
}
|
||||
|
||||
B.recycler.addOnScrollListener(endlessRecyclerOnScrollListener)
|
||||
}
|
||||
|
||||
|
||||
private fun updateController(appList: List<App>?) {
|
||||
private fun updateController(paginatedAppList: PaginatedAppList?) {
|
||||
B.recycler.withModels {
|
||||
setFilterDuplicates(true)
|
||||
if (appList == null) {
|
||||
for (i in 1..6) {
|
||||
if (paginatedAppList == null) {
|
||||
for (i in 1..10) {
|
||||
add(
|
||||
AppListViewShimmerModel_()
|
||||
.id(i)
|
||||
)
|
||||
}
|
||||
} else {
|
||||
add(
|
||||
HeaderViewModel_()
|
||||
.id("header")
|
||||
.title("${appList.size} apps purchased")
|
||||
)
|
||||
appList.forEach { app ->
|
||||
paginatedAppList.appList.forEach { app ->
|
||||
add(
|
||||
AppListViewModel_()
|
||||
.id(app.id)
|
||||
@@ -121,6 +110,13 @@ class PurchasedAppsFragment : BaseFragment() {
|
||||
}
|
||||
)
|
||||
}
|
||||
|
||||
if (paginatedAppList.hasMore){
|
||||
add(
|
||||
AppProgressViewModel_()
|
||||
.id("progress")
|
||||
)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -74,7 +74,7 @@ class BlacklistFragment : Fragment(R.layout.activity_generic_recycler) {
|
||||
binding.recycler.withModels {
|
||||
setFilterDuplicates(true)
|
||||
if (blackList == null) {
|
||||
for (i in 1..6) {
|
||||
for (i in 1..10) {
|
||||
add(
|
||||
AppListViewShimmerModel_()
|
||||
.id(i)
|
||||
|
||||
@@ -185,7 +185,7 @@ class UpdatesFragment : BaseFragment(R.layout.fragment_updates) {
|
||||
binding.recycler.withModels {
|
||||
setFilterDuplicates(true)
|
||||
if (updateFileMap == null) {
|
||||
for (i in 1..6) {
|
||||
for (i in 1..10) {
|
||||
add(
|
||||
AppListViewShimmerModel_()
|
||||
.id(i)
|
||||
|
||||
@@ -80,8 +80,4 @@ class BlacklistViewModel(application: Application) : BaseAndroidViewModel(applic
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
override fun onCleared() {
|
||||
super.onCleared()
|
||||
}
|
||||
}
|
||||
|
||||
@@ -42,12 +42,12 @@ class InstalledViewModel(application: Application) : BaseAppsViewModel(applicati
|
||||
|
||||
override fun observe() {
|
||||
viewModelScope.launch(Dispatchers.IO) {
|
||||
try {
|
||||
requestState = try {
|
||||
appList.flushAndAdd(getFilteredApps())
|
||||
liveData.postValue(appList.sortedBy { it.displayName.lowercase(Locale.getDefault()) })
|
||||
requestState = RequestState.Complete
|
||||
RequestState.Complete
|
||||
} catch (e: Exception) {
|
||||
requestState = RequestState.Pending
|
||||
RequestState.Pending
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -58,12 +58,15 @@ class InstalledViewModel(application: Application) : BaseAppsViewModel(applicati
|
||||
is BusEvent.InstallEvent -> {
|
||||
updateListAndPost(event.packageName)
|
||||
}
|
||||
|
||||
is BusEvent.UninstallEvent -> {
|
||||
updateListAndPost(event.packageName)
|
||||
}
|
||||
|
||||
is BusEvent.Blacklisted -> {
|
||||
observe()
|
||||
}
|
||||
|
||||
else -> {
|
||||
|
||||
}
|
||||
|
||||
@@ -43,7 +43,7 @@ class LibraryAppsViewModel(application: Application) : BaseAndroidViewModel(appl
|
||||
var streamCluster: StreamCluster = StreamCluster()
|
||||
|
||||
init {
|
||||
observe()
|
||||
requestState = RequestState.Init
|
||||
}
|
||||
|
||||
override fun observe() {
|
||||
|
||||
@@ -32,39 +32,51 @@ import kotlinx.coroutines.Dispatchers
|
||||
import kotlinx.coroutines.launch
|
||||
import kotlinx.coroutines.supervisorScope
|
||||
|
||||
data class PaginatedAppList(
|
||||
var appList: MutableList<App> = mutableListOf(),
|
||||
var hasMore: Boolean
|
||||
)
|
||||
|
||||
class PurchasedViewModel(application: Application) : BaseAndroidViewModel(application) {
|
||||
|
||||
private val authData = AuthProvider
|
||||
.with(application)
|
||||
.getAuthData()
|
||||
private val authData = AuthProvider.with(application).getAuthData()
|
||||
|
||||
private val purchaseHelper = PurchaseHelper(authData)
|
||||
.using(HttpClient.getPreferredClient())
|
||||
private val purchaseHelper = PurchaseHelper(authData).using(HttpClient.getPreferredClient())
|
||||
|
||||
val liveData: MutableLiveData<List<App>> = MutableLiveData()
|
||||
private var appList: MutableList<App> = mutableListOf()
|
||||
|
||||
var appList: MutableList<App> = mutableListOf()
|
||||
val liveData: MutableLiveData<PaginatedAppList> = MutableLiveData()
|
||||
|
||||
init {
|
||||
requestState = RequestState.Init
|
||||
observe()
|
||||
}
|
||||
|
||||
override fun observe() {
|
||||
viewModelScope.launch(Dispatchers.IO) {
|
||||
supervisorScope {
|
||||
try {
|
||||
appList.addAll(purchaseHelper.getPurchaseHistory(appList.size))
|
||||
liveData.postValue(appList)
|
||||
requestState = RequestState.Complete
|
||||
requestState = try {
|
||||
val nextAppList = purchaseHelper.getPurchaseHistory(appList.size)
|
||||
.filter { it.displayName.isNotEmpty() }
|
||||
|
||||
if (nextAppList.isEmpty()) {
|
||||
liveData.postValue(PaginatedAppList(
|
||||
appList,
|
||||
false
|
||||
))
|
||||
} else {
|
||||
appList.addAll(nextAppList)
|
||||
liveData.postValue(
|
||||
PaginatedAppList(
|
||||
appList,
|
||||
true
|
||||
)
|
||||
)
|
||||
}
|
||||
RequestState.Complete
|
||||
} catch (e: Exception) {
|
||||
requestState = RequestState.Pending
|
||||
RequestState.Pending
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
override fun onCleared() {
|
||||
super.onCleared()
|
||||
}
|
||||
}
|
||||
36
app/src/main/res/layout/fragment_apps.xml
Normal file
36
app/src/main/res/layout/fragment_apps.xml
Normal file
@@ -0,0 +1,36 @@
|
||||
<?xml version="1.0" encoding="utf-8"?><!--
|
||||
~ Aurora Store
|
||||
~ Copyright (C) 2021, Rahul Kumar Patel <whyorean@gmail.com>
|
||||
~
|
||||
~ Aurora Store 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 2 of the License, or
|
||||
~ (at your option) any later version.
|
||||
~
|
||||
~ Aurora Store 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 Aurora Store. If not, see <http://www.gnu.org/licenses/>.
|
||||
~
|
||||
-->
|
||||
|
||||
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
xmlns:app="http://schemas.android.com/apk/res-auto"
|
||||
xmlns:tools="http://schemas.android.com/tools"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="match_parent"
|
||||
android:orientation="vertical">
|
||||
|
||||
<com.airbnb.epoxy.EpoxyRecyclerView
|
||||
android:id="@+id/recycler"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="match_parent"
|
||||
android:clipToPadding="false"
|
||||
app:itemSpacing="@dimen/margin_normal"
|
||||
app:layoutManager="androidx.recyclerview.widget.LinearLayoutManager"
|
||||
app:stackFromEnd="false"
|
||||
tools:listitem="@layout/view_app_list" />
|
||||
</RelativeLayout>
|
||||
@@ -20,6 +20,7 @@
|
||||
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
xmlns:app="http://schemas.android.com/apk/res-auto"
|
||||
android:layout_gravity="center_horizontal"
|
||||
android:layout_margin="@dimen/margin_xsmall">
|
||||
|
||||
@@ -27,5 +28,7 @@
|
||||
android:id="@+id/img_icon"
|
||||
android:layout_width="@dimen/icon_size_cluster"
|
||||
android:layout_height="@dimen/icon_size_cluster"
|
||||
android:scaleX="0.5"
|
||||
android:scaleY="0.5"
|
||||
android:layout_centerInParent="true" />
|
||||
</RelativeLayout>
|
||||
Reference in New Issue
Block a user