diff --git a/app/src/main/java/fr/uca/iut/clfreville2/teaiswarm/fragment/RepositoryListFragment.kt b/app/src/main/java/fr/uca/iut/clfreville2/teaiswarm/fragment/RepositoryListFragment.kt index b1b1189..48f4c88 100644 --- a/app/src/main/java/fr/uca/iut/clfreville2/teaiswarm/fragment/RepositoryListFragment.kt +++ b/app/src/main/java/fr/uca/iut/clfreville2/teaiswarm/fragment/RepositoryListFragment.kt @@ -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( factoryProducer = { RepositoryViewModelFactory( - service, - search - ) + service + ) { search } } ) - val pagingAdapter = + pagingAdapter = RepositoryListAdapter(RepositoryListAdapter.RepositoryComparator, onClick) - val recyclerView = requireView().findViewById(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 create(modelClass: Class): 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) + } + } } diff --git a/app/src/main/java/fr/uca/iut/clfreville2/teaiswarm/network/GiteaService.kt b/app/src/main/java/fr/uca/iut/clfreville2/teaiswarm/network/GiteaService.kt index 8c49b3b..aed7890 100644 --- a/app/src/main/java/fr/uca/iut/clfreville2/teaiswarm/network/GiteaService.kt +++ b/app/src/main/java/fr/uca/iut/clfreville2/teaiswarm/network/GiteaService.kt @@ -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 = - 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 = 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/" diff --git a/app/src/main/res/layout/repository_list.xml b/app/src/main/res/layout/repository_list.xml index 62dc2d9..2ea9510 100644 --- a/app/src/main/res/layout/repository_list.xml +++ b/app/src/main/res/layout/repository_list.xml @@ -1,9 +1,16 @@ - + android:layout_height="match_parent" + android:orientation="vertical"> + + + - \ No newline at end of file + \ No newline at end of file diff --git a/app/src/main/res/values/strings.xml b/app/src/main/res/values/strings.xml index d9a437e..2abebe3 100644 --- a/app/src/main/res/values/strings.xml +++ b/app/src/main/res/values/strings.xml @@ -15,4 +15,12 @@ Configure Activity User not found + Desc + + alpha + created + updated + size + id + \ No newline at end of file