parent
1dd386c3d6
commit
35462dfe00
@ -0,0 +1,104 @@
|
|||||||
|
package fr.uca.iut.clfreville2.teaiswarm.fragment
|
||||||
|
|
||||||
|
import android.os.Bundle
|
||||||
|
import android.view.View
|
||||||
|
import androidx.fragment.app.Fragment
|
||||||
|
import androidx.fragment.app.viewModels
|
||||||
|
import androidx.lifecycle.ViewModel
|
||||||
|
import androidx.lifecycle.ViewModelProvider
|
||||||
|
import androidx.lifecycle.lifecycleScope
|
||||||
|
import androidx.lifecycle.viewModelScope
|
||||||
|
import androidx.paging.*
|
||||||
|
import androidx.recyclerview.widget.LinearLayoutManager
|
||||||
|
import androidx.recyclerview.widget.RecyclerView
|
||||||
|
import fr.uca.iut.clfreville2.teaiswarm.R
|
||||||
|
import fr.uca.iut.clfreville2.teaiswarm.adapter.RepositoryListAdapter
|
||||||
|
import fr.uca.iut.clfreville2.teaiswarm.model.Repository
|
||||||
|
import fr.uca.iut.clfreville2.teaiswarm.network.GiteaService
|
||||||
|
import fr.uca.iut.clfreville2.teaiswarm.network.RepositoryService
|
||||||
|
import kotlinx.coroutines.flow.collectLatest
|
||||||
|
import kotlinx.coroutines.launch
|
||||||
|
import retrofit2.HttpException
|
||||||
|
import java.io.IOException
|
||||||
|
|
||||||
|
class RepositoryListFragment(private val username: String, private val onClick: (Repository) -> Unit) : Fragment(R.layout.repository_list) {
|
||||||
|
|
||||||
|
private val service = GiteaService()
|
||||||
|
|
||||||
|
override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
|
||||||
|
super.onViewCreated(view, savedInstanceState)
|
||||||
|
updateRepositories()
|
||||||
|
}
|
||||||
|
|
||||||
|
private fun updateRepositories() {
|
||||||
|
val viewModel by viewModels<RepositoryViewModel>(
|
||||||
|
factoryProducer = {
|
||||||
|
RepositoryViewModelFactory(
|
||||||
|
service,
|
||||||
|
username
|
||||||
|
)
|
||||||
|
}
|
||||||
|
)
|
||||||
|
val pagingAdapter =
|
||||||
|
RepositoryListAdapter(RepositoryListAdapter.RepositoryComparator, onClick)
|
||||||
|
val recyclerView = requireView().findViewById<RecyclerView>(R.id.repositories_view)
|
||||||
|
recyclerView.adapter = pagingAdapter
|
||||||
|
recyclerView.layoutManager = LinearLayoutManager(requireContext())
|
||||||
|
viewLifecycleOwner.lifecycleScope.launch {
|
||||||
|
viewModel.flow.collectLatest { pagingData ->
|
||||||
|
pagingAdapter.submitData(pagingData)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
class RepositorySource(
|
||||||
|
private val service: RepositoryService,
|
||||||
|
private val username: String
|
||||||
|
) : PagingSource<Int, Repository>() {
|
||||||
|
|
||||||
|
override suspend fun load(params: LoadParams<Int>): LoadResult<Int, Repository> =
|
||||||
|
try {
|
||||||
|
val nextPageNumber = params.key ?: 1
|
||||||
|
val response = service.listActiveRepositories(username, nextPageNumber)
|
||||||
|
LoadResult.Page(
|
||||||
|
data = response,
|
||||||
|
prevKey = nextPageNumber - 1,
|
||||||
|
nextKey = nextPageNumber + 1
|
||||||
|
)
|
||||||
|
} catch (e: IOException) {
|
||||||
|
LoadResult.Error(e)
|
||||||
|
} catch (e: HttpException) {
|
||||||
|
LoadResult.Error(e)
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun getRefreshKey(state: PagingState<Int, Repository>): Int? =
|
||||||
|
state.anchorPosition?.let { anchorPosition ->
|
||||||
|
val anchorPage = state.closestPageToPosition(anchorPosition)
|
||||||
|
anchorPage?.prevKey?.plus(1) ?: anchorPage?.nextKey?.minus(1)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
class RepositoryViewModel(
|
||||||
|
private val service: RepositoryService,
|
||||||
|
private val username: String
|
||||||
|
) : ViewModel() {
|
||||||
|
val flow = Pager(
|
||||||
|
PagingConfig(pageSize = 10, enablePlaceholders = true)
|
||||||
|
) {
|
||||||
|
RepositorySource(service, username)
|
||||||
|
}.flow.cachedIn(viewModelScope)
|
||||||
|
}
|
||||||
|
|
||||||
|
class RepositoryViewModelFactory(
|
||||||
|
private val service: RepositoryService,
|
||||||
|
private val username: String
|
||||||
|
) : ViewModelProvider.Factory {
|
||||||
|
override fun <T : ViewModel> create(modelClass: Class<T>): T {
|
||||||
|
if (modelClass.isAssignableFrom(RepositoryViewModel::class.java)) {
|
||||||
|
@Suppress("UNCHECKED_CAST")
|
||||||
|
return RepositoryViewModel(service, username) as T
|
||||||
|
}
|
||||||
|
throw IllegalArgumentException("Unknown ViewModel class")
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
@ -1,32 +1,13 @@
|
|||||||
<?xml version="1.0" encoding="utf-8"?>
|
<?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"
|
||||||
xmlns:app="http://schemas.android.com/apk/res-auto"
|
xmlns:app="http://schemas.android.com/apk/res-auto"
|
||||||
xmlns:tools="http://schemas.android.com/tools"
|
xmlns:tools="http://schemas.android.com/tools"
|
||||||
android:layout_width="match_parent"
|
android:layout_width="match_parent"
|
||||||
android:layout_height="match_parent"
|
android:layout_height="match_parent"
|
||||||
tools:context=".MainActivity">
|
tools:context=".MainActivity">
|
||||||
|
|
||||||
<androidx.recyclerview.widget.RecyclerView
|
<androidx.fragment.app.FragmentContainerView
|
||||||
android:id="@+id/repositories_view"
|
|
||||||
android:layout_width="match_parent"
|
android:layout_width="match_parent"
|
||||||
android:layout_height="match_parent"
|
android:layout_height="match_parent"
|
||||||
app:layoutManager="LinearLayoutManager"/>
|
android:id="@+id/fragment_container_view" />
|
||||||
|
|
||||||
<LinearLayout
|
|
||||||
android:layout_width="wrap_content"
|
|
||||||
android:layout_height="wrap_content"
|
|
||||||
app:layout_constraintBottom_toBottomOf="parent"
|
|
||||||
app:layout_constraintEnd_toEndOf="parent"
|
|
||||||
app:layout_constraintStart_toStartOf="parent">
|
|
||||||
<Button
|
|
||||||
android:layout_width="wrap_content"
|
|
||||||
android:layout_height="wrap_content"
|
|
||||||
android:id="@+id/previous_repository_list"
|
|
||||||
android:text="@string/previous" />
|
|
||||||
<Button
|
|
||||||
android:layout_width="wrap_content"
|
|
||||||
android:layout_height="wrap_content"
|
|
||||||
android:id="@+id/next_repository_list"
|
|
||||||
android:text="@string/next" />
|
|
||||||
</LinearLayout>
|
</LinearLayout>
|
||||||
</androidx.constraintlayout.widget.ConstraintLayout>
|
|
@ -0,0 +1,9 @@
|
|||||||
|
<?xml version="1.0" encoding="utf-8"?>
|
||||||
|
<androidx.constraintlayout.widget.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android"
|
||||||
|
android:layout_width="match_parent"
|
||||||
|
android:layout_height="match_parent">
|
||||||
|
<androidx.recyclerview.widget.RecyclerView
|
||||||
|
android:id="@+id/repositories_view"
|
||||||
|
android:layout_width="match_parent"
|
||||||
|
android:layout_height="match_parent" />
|
||||||
|
</androidx.constraintlayout.widget.ConstraintLayout>
|
Loading…
Reference in new issue