Add a spinner for the sort criteria

main
Clément FRÉVILLE 2 years ago
parent c12c46bdd5
commit 8651a29944

@ -2,6 +2,9 @@ package fr.uca.iut.clfreville2.teaiswarm.fragment
import android.os.Bundle
import android.view.View
import android.widget.AdapterView
import android.widget.ArrayAdapter
import android.widget.Spinner
import androidx.fragment.app.Fragment
import androidx.fragment.app.viewModels
import androidx.lifecycle.ViewModel
@ -16,36 +19,50 @@ import fr.uca.iut.clfreville2.teaiswarm.TeaIsWarm
import fr.uca.iut.clfreville2.teaiswarm.adapter.RepositoryListAdapter
import fr.uca.iut.clfreville2.teaiswarm.model.Repository
import fr.uca.iut.clfreville2.teaiswarm.model.search.SearchSettings
import fr.uca.iut.clfreville2.teaiswarm.model.search.SortCriteria
import fr.uca.iut.clfreville2.teaiswarm.network.RepositoryService
import kotlinx.coroutines.flow.collectLatest
import kotlinx.coroutines.launch
import retrofit2.HttpException
import java.io.IOException
import kotlin.properties.Delegates
class RepositoryListFragment(
private val search: SearchSettings,
private val initialSearch: SearchSettings,
private val onClick: (Repository) -> Unit
) : Fragment(R.layout.repository_list) {
private val service = TeaIsWarm.service
private var search: SearchSettings by Delegates.observable(SearchSettings()) { _, _, _ ->
updateRepositories()
}
private lateinit var recyclerView: RecyclerView
private lateinit var pagingAdapter: RepositoryListAdapter
override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
super.onViewCreated(view, savedInstanceState)
updateRepositories()
}
recyclerView = view.findViewById(R.id.repositories_view)
val spinner: Spinner = view.findViewById(R.id.sort_by_spinner)
ArrayAdapter.createFromResource(
requireContext(),
R.array.sort_criteria,
android.R.layout.simple_spinner_item
).also { adapter ->
adapter.setDropDownViewResource(android.R.layout.simple_spinner_dropdown_item)
spinner.adapter = adapter
}
spinner.onItemSelectedListener = SortListener()
private fun updateRepositories() {
val viewModel by viewModels<RepositoryViewModel>(
factoryProducer = {
RepositoryViewModelFactory(
service,
search
)
service
) { search }
}
)
val pagingAdapter =
pagingAdapter =
RepositoryListAdapter(RepositoryListAdapter.RepositoryComparator, onClick)
val recyclerView = requireView().findViewById<RecyclerView>(R.id.repositories_view)
recyclerView.adapter = pagingAdapter
recyclerView.layoutManager = LinearLayoutManager(requireContext())
viewLifecycleOwner.lifecycleScope.launch {
@ -53,6 +70,12 @@ class RepositoryListFragment(
pagingAdapter.submitData(pagingData)
}
}
search = initialSearch
}
private fun updateRepositories() {
pagingAdapter.refresh()
}
class RepositorySource(
@ -84,18 +107,18 @@ class RepositoryListFragment(
class RepositoryViewModel(
private val service: RepositoryService,
private val search: SearchSettings
private val search: () -> SearchSettings
) : ViewModel() {
val flow = Pager(
PagingConfig(pageSize = 10, enablePlaceholders = true)
) {
RepositorySource(service, search)
RepositorySource(service, search())
}.flow.cachedIn(viewModelScope)
}
class RepositoryViewModelFactory(
private val service: RepositoryService,
private val search: SearchSettings
private val search: () -> SearchSettings
) : ViewModelProvider.Factory {
override fun <T : ViewModel> create(modelClass: Class<T>): T {
if (modelClass.isAssignableFrom(RepositoryViewModel::class.java)) {
@ -105,4 +128,14 @@ class RepositoryListFragment(
throw IllegalArgumentException("Unknown ViewModel class")
}
}
inner class SortListener : AdapterView.OnItemSelectedListener {
override fun onItemSelected(parent: AdapterView<*>?, view: View?, position: Int, id: Long) {
search = search.copy(sort = SortCriteria.values()[position])
}
override fun onNothingSelected(parent: AdapterView<*>?) {
search = search.copy(sort = SortCriteria.ALPHA)
}
}
}

@ -86,28 +86,35 @@ class GiteaService(private val handle: GiteaApiService) : RepositoryService {
handle.retrieveFileContents(repository.identifier.owner, repository.identifier.name, filePath)
}
override suspend fun searchOwner(owner: String): Owner? = try {
handle.searchOwner(owner)
} catch (ex: HttpException) {
if (ex.code() == HTTP_NOT_FOUND) {
null
} else {
throw ex
override suspend fun searchOwner(owner: String): Owner? = withContext(Dispatchers.IO) {
try {
handle.searchOwner(owner)
} catch (ex: HttpException) {
if (ex.code() == HTTP_NOT_FOUND) {
null
} else {
throw ex
}
}
}
override suspend fun searchRepositories(settings: SearchSettings): List<Repository> =
handle.searchRepositories(
settings.query,
settings.userId,
settings.teamId,
settings.starredBy,
settings.mode?.toString()?.lowercase(),
settings.sort.toString().lowercase(),
settings.order.toString().lowercase(),
settings.page,
settings.limit
).data
override suspend fun searchRepositories(settings: SearchSettings): List<Repository> = withContext(Dispatchers.IO) {
if (settings.page < 1) {
emptyList()
} else {
handle.searchRepositories(
settings.query,
settings.userId,
settings.teamId,
settings.starredBy,
settings.mode?.toString()?.lowercase(),
settings.sort.toString().lowercase(),
settings.order.toString().lowercase(),
settings.page,
settings.limit
).data
}
}
}
private const val CODEFIRST_API_BASE = "https://codefirst.iut.uca.fr/git/api/v1/"

@ -1,9 +1,16 @@
<?xml version="1.0" encoding="utf-8"?>
<androidx.constraintlayout.widget.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android"
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent">
android:layout_height="match_parent"
android:orientation="vertical">
<Spinner
android:id="@+id/sort_by_spinner"
android:layout_width="match_parent"
android:layout_height="wrap_content" />
<androidx.recyclerview.widget.RecyclerView
android:id="@+id/repositories_view"
android:layout_width="match_parent"
android:layout_height="match_parent" />
</androidx.constraintlayout.widget.ConstraintLayout>
</LinearLayout>

@ -15,4 +15,12 @@
<string name="configure">Configure</string>
<string name="activity">Activity</string>
<string name="owner_not_found">User not found</string>
<string name="desc_sort">Desc</string>
<string-array name="sort_criteria">
<item>alpha</item>
<item>created</item>
<item>updated</item>
<item>size</item>
<item>id</item>
</string-array>
</resources>
Loading…
Cancel
Save