From c40d14e9b4585d365d767740df93bfa9f6babd69 Mon Sep 17 00:00:00 2001 From: abazov73 <92822431+abazov73@users.noreply.github.com> Date: Tue, 5 Dec 2023 22:26:05 +0400 Subject: [PATCH] Lab 04: add pagination --- app/build.gradle.kts | 2 ++ .../mobile_labs/database/AppContainer.kt | 1 + .../database/event/dao/EventDao.kt | 8 +++-- .../event/repository/EventRepository.kt | 3 +- .../repository/OfflineEventRepository.kt | 15 ++++++-- .../performance/dao/PerformanceDao.kt | 3 +- .../OfflinePerformanceRepository.kt | 12 ++++++- .../repository/PerformanceRepository.kt | 3 +- .../database/person/dao/PersonDao.kt | 3 +- .../repository/OfflinePersonRepository.kt | 13 ++++++- .../person/repository/PersonRepository.kt | 3 +- .../mobile_labs/ui/event/list/EventList.kt | 33 ++++++++++++----- .../ui/event/list/EventListViewModel.kt | 12 ++----- .../ui/performance/list/PerformanceList.kt | 35 ++++++++++++++----- .../list/PerformanceListViewModel.kt | 19 +++------- .../mobile_labs/ui/person/list/PeopleList.kt | 30 +++++++++++----- .../ui/person/list/PeopleListViewModel.kt | 14 +++----- 17 files changed, 140 insertions(+), 69 deletions(-) diff --git a/app/build.gradle.kts b/app/build.gradle.kts index eae8623..ee3ebe4 100644 --- a/app/build.gradle.kts +++ b/app/build.gradle.kts @@ -76,6 +76,8 @@ dependencies { implementation("androidx.room:room-ktx:$room_version") implementation("androidx.room:room-paging:$room_version") + implementation("androidx.paging:paging-compose:3.2.1") + //Tests testImplementation("junit:junit:4.13.2") androidTestImplementation("androidx.test.ext:junit:1.1.5") diff --git a/app/src/main/java/com/example/mobile_labs/database/AppContainer.kt b/app/src/main/java/com/example/mobile_labs/database/AppContainer.kt index a48175e..0e51cc8 100644 --- a/app/src/main/java/com/example/mobile_labs/database/AppContainer.kt +++ b/app/src/main/java/com/example/mobile_labs/database/AppContainer.kt @@ -29,5 +29,6 @@ class AppDataContainer(private val context: Context) : AppContainer { companion object { const val TIMEOUT = 5000L + const val LIMIT = 3 } } \ No newline at end of file diff --git a/app/src/main/java/com/example/mobile_labs/database/event/dao/EventDao.kt b/app/src/main/java/com/example/mobile_labs/database/event/dao/EventDao.kt index fae5ac7..c5440f1 100644 --- a/app/src/main/java/com/example/mobile_labs/database/event/dao/EventDao.kt +++ b/app/src/main/java/com/example/mobile_labs/database/event/dao/EventDao.kt @@ -1,5 +1,6 @@ package com.example.mobile_labs.database.event.dao +import androidx.paging.PagingSource import androidx.room.Dao import androidx.room.Delete import androidx.room.Insert @@ -9,14 +10,17 @@ import com.example.mobile_labs.database.event.model.Event import com.example.mobile_labs.database.event.model.EventWithPerformance import com.example.mobile_labs.database.performance.model.Performance import kotlinx.coroutines.flow.Flow +import java.time.LocalDate +import java.time.format.DateTimeFormatter @Dao interface EventDao { @Query("select * from events order by date asc") fun getAll(): Flow> - @Query("select * from events where events.date > :dateFrom order by date asc") - fun getAllWithPerformance(dateFrom: String): Flow> + @Query("select * from events where events.date > :dateFrom order by date collate nocase asc") + fun getAllWithPerformance(dateFrom: String? = LocalDate.now().format( + DateTimeFormatter.ofPattern("dd.MM"))): PagingSource @Query("select * from events where events.uid = :uid") fun getByUid(uid: Int): Flow diff --git a/app/src/main/java/com/example/mobile_labs/database/event/repository/EventRepository.kt b/app/src/main/java/com/example/mobile_labs/database/event/repository/EventRepository.kt index 47eba28..cbb03cc 100644 --- a/app/src/main/java/com/example/mobile_labs/database/event/repository/EventRepository.kt +++ b/app/src/main/java/com/example/mobile_labs/database/event/repository/EventRepository.kt @@ -1,12 +1,13 @@ package com.example.mobile_labs.database.event.repository +import androidx.paging.PagingData import com.example.mobile_labs.database.event.model.Event import com.example.mobile_labs.database.event.model.EventWithPerformance import kotlinx.coroutines.flow.Flow interface EventRepository { fun getAll(): Flow> - fun getAllWithPerformance(): Flow> + fun getAllWithPerformance(): Flow> fun getEvent(uid: Int): Flow suspend fun insertEvent(event: Event) suspend fun updateEvent(event: Event) diff --git a/app/src/main/java/com/example/mobile_labs/database/event/repository/OfflineEventRepository.kt b/app/src/main/java/com/example/mobile_labs/database/event/repository/OfflineEventRepository.kt index 7fc908f..5663fcc 100644 --- a/app/src/main/java/com/example/mobile_labs/database/event/repository/OfflineEventRepository.kt +++ b/app/src/main/java/com/example/mobile_labs/database/event/repository/OfflineEventRepository.kt @@ -1,5 +1,9 @@ package com.example.mobile_labs.database.event.repository +import androidx.paging.Pager +import androidx.paging.PagingConfig +import androidx.paging.PagingData +import com.example.mobile_labs.database.AppDataContainer import com.example.mobile_labs.database.event.dao.EventDao import com.example.mobile_labs.database.event.model.Event import com.example.mobile_labs.database.event.model.EventWithPerformance @@ -9,9 +13,14 @@ import java.time.format.DateTimeFormatter class OfflineEventRepository(private val eventDao: EventDao) : EventRepository { override fun getAll(): Flow> = eventDao.getAll(); - override fun getAllWithPerformance(): Flow> = eventDao.getAllWithPerformance(LocalDate.now().format( - DateTimeFormatter.ofPattern("dd.MM") - )) + override fun getAllWithPerformance(): Flow> = Pager( + config = PagingConfig( + pageSize = AppDataContainer.LIMIT, + enablePlaceholders = false, + ), + pagingSourceFactory = eventDao::getAllWithPerformance + ).flow + override fun getEvent(uid: Int): Flow = eventDao.getByUid(uid); override suspend fun insertEvent(event: Event) = eventDao.insert(event); diff --git a/app/src/main/java/com/example/mobile_labs/database/performance/dao/PerformanceDao.kt b/app/src/main/java/com/example/mobile_labs/database/performance/dao/PerformanceDao.kt index 4903bd0..dfb9a87 100644 --- a/app/src/main/java/com/example/mobile_labs/database/performance/dao/PerformanceDao.kt +++ b/app/src/main/java/com/example/mobile_labs/database/performance/dao/PerformanceDao.kt @@ -1,5 +1,6 @@ package com.example.mobile_labs.database.performance.dao +import androidx.paging.PagingSource import androidx.room.Dao import androidx.room.Delete import androidx.room.Insert @@ -13,7 +14,7 @@ import kotlinx.coroutines.flow.Flow @Dao interface PerformanceDao { @Query("select * from performances order by title collate nocase asc") - fun getAll(): Flow> + fun getAll(): PagingSource @Query("select * from performances where performances.performance_uid = :uid") fun getByUid(uid: Int): Flow diff --git a/app/src/main/java/com/example/mobile_labs/database/performance/repository/OfflinePerformanceRepository.kt b/app/src/main/java/com/example/mobile_labs/database/performance/repository/OfflinePerformanceRepository.kt index ea6cdaf..cebf393 100644 --- a/app/src/main/java/com/example/mobile_labs/database/performance/repository/OfflinePerformanceRepository.kt +++ b/app/src/main/java/com/example/mobile_labs/database/performance/repository/OfflinePerformanceRepository.kt @@ -1,12 +1,22 @@ package com.example.mobile_labs.database.performance.repository +import androidx.paging.Pager +import androidx.paging.PagingConfig +import androidx.paging.PagingData +import com.example.mobile_labs.database.AppDataContainer import com.example.mobile_labs.database.performance.dao.PerformanceDao import com.example.mobile_labs.database.performance.model.Performance import com.example.mobile_labs.database.performance.model.PerformanceWithPeople import kotlinx.coroutines.flow.Flow class OfflinePerformanceRepository(private val performanceDao: PerformanceDao) : PerformanceRepository { - override fun getAllPerformances(): Flow> = performanceDao.getAll(); + override fun getAllPerformances(): Flow> = Pager( + config = PagingConfig( + pageSize = AppDataContainer.LIMIT, + enablePlaceholders = false, + ), + pagingSourceFactory = performanceDao::getAll + ).flow override fun getPerformance(uid: Int): Flow = performanceDao.getByUid(uid); override suspend fun insertPerformance(performance: Performance) = performanceDao.insert(performance); diff --git a/app/src/main/java/com/example/mobile_labs/database/performance/repository/PerformanceRepository.kt b/app/src/main/java/com/example/mobile_labs/database/performance/repository/PerformanceRepository.kt index bdea708..09ab2ac 100644 --- a/app/src/main/java/com/example/mobile_labs/database/performance/repository/PerformanceRepository.kt +++ b/app/src/main/java/com/example/mobile_labs/database/performance/repository/PerformanceRepository.kt @@ -1,11 +1,12 @@ package com.example.mobile_labs.database.performance.repository +import androidx.paging.PagingData import com.example.mobile_labs.database.performance.model.Performance import com.example.mobile_labs.database.performance.model.PerformanceWithPeople import kotlinx.coroutines.flow.Flow interface PerformanceRepository { - fun getAllPerformances(): Flow> + fun getAllPerformances(): Flow> fun getPerformance(uid: Int): Flow suspend fun insertPerformance(performance: Performance) suspend fun updatePerformance(performance: Performance) diff --git a/app/src/main/java/com/example/mobile_labs/database/person/dao/PersonDao.kt b/app/src/main/java/com/example/mobile_labs/database/person/dao/PersonDao.kt index 98a0d9b..462f81f 100644 --- a/app/src/main/java/com/example/mobile_labs/database/person/dao/PersonDao.kt +++ b/app/src/main/java/com/example/mobile_labs/database/person/dao/PersonDao.kt @@ -1,5 +1,6 @@ package com.example.mobile_labs.database.person.dao +import androidx.paging.PagingSource import androidx.room.Dao import androidx.room.Delete import androidx.room.Insert @@ -11,7 +12,7 @@ import kotlinx.coroutines.flow.Flow @Dao interface PersonDao { @Query("select * from people order by last_name collate nocase asc") - fun getAll(): Flow> + fun getAll(): PagingSource @Query("select * from people where people.uid = :uid") fun getByUid(uid: Int): Flow diff --git a/app/src/main/java/com/example/mobile_labs/database/person/repository/OfflinePersonRepository.kt b/app/src/main/java/com/example/mobile_labs/database/person/repository/OfflinePersonRepository.kt index 712823f..c94b1d8 100644 --- a/app/src/main/java/com/example/mobile_labs/database/person/repository/OfflinePersonRepository.kt +++ b/app/src/main/java/com/example/mobile_labs/database/person/repository/OfflinePersonRepository.kt @@ -1,11 +1,22 @@ package com.example.mobile_labs.database.person.repository +import androidx.paging.Pager +import androidx.paging.PagingConfig +import androidx.paging.PagingData +import com.example.mobile_labs.database.AppContainer +import com.example.mobile_labs.database.AppDataContainer import com.example.mobile_labs.database.person.dao.PersonDao import com.example.mobile_labs.database.person.model.Person import kotlinx.coroutines.flow.Flow class OfflinePersonRepository(private val personDao: PersonDao) : PersonRepository { - override fun getAllPeople(): Flow> = personDao.getAll(); + override fun getAllPeople(): Flow> = Pager( + config = PagingConfig( + pageSize = AppDataContainer.LIMIT, + enablePlaceholders = false, + ), + pagingSourceFactory = personDao::getAll + ).flow; override fun getPerson(uid: Int): Flow = personDao.getByUid(uid); override suspend fun insertPerson(person: Person) = personDao.insert(person); diff --git a/app/src/main/java/com/example/mobile_labs/database/person/repository/PersonRepository.kt b/app/src/main/java/com/example/mobile_labs/database/person/repository/PersonRepository.kt index cfc29a3..f676fb9 100644 --- a/app/src/main/java/com/example/mobile_labs/database/person/repository/PersonRepository.kt +++ b/app/src/main/java/com/example/mobile_labs/database/person/repository/PersonRepository.kt @@ -1,10 +1,11 @@ package com.example.mobile_labs.database.person.repository +import androidx.paging.PagingData import com.example.mobile_labs.database.person.model.Person import kotlinx.coroutines.flow.Flow interface PersonRepository { - fun getAllPeople(): Flow> + fun getAllPeople(): Flow> fun getPerson(uid: Int): Flow suspend fun insertPerson(person: Person) suspend fun updatePerson(person: Person) diff --git a/app/src/main/java/com/example/mobile_labs/ui/event/list/EventList.kt b/app/src/main/java/com/example/mobile_labs/ui/event/list/EventList.kt index 1423443..41f1206 100644 --- a/app/src/main/java/com/example/mobile_labs/ui/event/list/EventList.kt +++ b/app/src/main/java/com/example/mobile_labs/ui/event/list/EventList.kt @@ -35,17 +35,24 @@ import androidx.compose.ui.tooling.preview.Preview import androidx.compose.ui.unit.dp import androidx.lifecycle.viewmodel.compose.viewModel import androidx.navigation.NavController +import androidx.paging.PagingData +import androidx.paging.compose.LazyPagingItems +import androidx.paging.compose.collectAsLazyPagingItems +import androidx.paging.compose.itemContentType +import androidx.paging.compose.itemKey import coil.compose.AsyncImage import com.example.mobile_labs.R import com.example.mobile_labs.database.AppDatabase import com.example.mobile_labs.database.event.model.Event import com.example.mobile_labs.database.event.model.EventWithPerformance +import com.example.mobile_labs.database.performance.model.Performance import com.example.mobile_labs.database.person.model.Person import com.example.mobile_labs.ui.AppViewModelProvider import com.example.mobile_labs.ui.navigation.Screen import com.example.mobile_labs.ui.person.list.PeopleListViewModel import com.example.mobile_labs.ui.theme.Mobile_LabsTheme import kotlinx.coroutines.Dispatchers +import kotlinx.coroutines.flow.MutableStateFlow import kotlinx.coroutines.withContext import java.time.LocalDate import java.time.format.DateTimeFormatter @@ -55,14 +62,14 @@ fun EventList( navController: NavController, viewModel: EventListViewModel = viewModel(factory = AppViewModelProvider.Factory) ) { - val eventListUiState by viewModel.eventListUiState.collectAsState() + val eventListUiState = viewModel.eventListUiState.collectAsLazyPagingItems() Column( horizontalAlignment = Alignment.CenterHorizontally, modifier = Modifier .padding(all = 10.dp)) { EventList( - eventList = eventListUiState.eventList, + eventList = eventListUiState, onClick = {uid : Int -> val route = Screen.PerformanceView.route.replace("{id}", uid.toString()) navController.navigate(route) @@ -75,13 +82,13 @@ fun EventList( @Composable private fun EventList( modifier: Modifier = Modifier, - eventList: List, + eventList: LazyPagingItems, onClick: (uid: Int) -> Unit ) { Column( modifier = modifier ) { - if (eventList.isEmpty()) { + if (eventList.itemCount == 0) { Text( text = stringResource(R.string.events_missing_description), textAlign = TextAlign.Center, @@ -89,9 +96,16 @@ private fun EventList( ) } else { LazyColumn(modifier = Modifier.padding(all = 10.dp)) { - items(items = eventList, key = { it.event.uid !! }) { event -> - EventListItem(event = event, modifier = Modifier - .padding(vertical = 7.dp), onClick = onClick) + items( + count = eventList.itemCount, + key = eventList.itemKey(), + contentType = eventList.itemContentType(), + ) { index -> + val event = eventList[index] + event?.let{ + EventListItem(event = event, modifier = Modifier + .padding(vertical = 7.dp), onClick = onClick) + } } } } @@ -133,7 +147,10 @@ fun SchedulePreview() { Surface( color = MaterialTheme.colorScheme.background ) { - EventList(eventList = listOf(), onClick = {}) + EventList(eventList = MutableStateFlow( + PagingData.empty() + ).collectAsLazyPagingItems(), + onClick = {}) } } } \ No newline at end of file diff --git a/app/src/main/java/com/example/mobile_labs/ui/event/list/EventListViewModel.kt b/app/src/main/java/com/example/mobile_labs/ui/event/list/EventListViewModel.kt index e4d6663..fae66c7 100644 --- a/app/src/main/java/com/example/mobile_labs/ui/event/list/EventListViewModel.kt +++ b/app/src/main/java/com/example/mobile_labs/ui/event/list/EventListViewModel.kt @@ -2,10 +2,12 @@ package com.example.mobile_labs.ui.event.list import androidx.lifecycle.ViewModel import androidx.lifecycle.viewModelScope +import androidx.paging.PagingData import com.example.mobile_labs.database.AppDataContainer import com.example.mobile_labs.database.event.repository.EventRepository import com.example.mobile_labs.database.event.model.Event import com.example.mobile_labs.database.event.model.EventWithPerformance +import kotlinx.coroutines.flow.Flow import kotlinx.coroutines.flow.SharingStarted import kotlinx.coroutines.flow.StateFlow import kotlinx.coroutines.flow.map @@ -14,13 +16,5 @@ import kotlinx.coroutines.flow.stateIn class EventListViewModel( private val eventRepository: EventRepository ) : ViewModel() { - val eventListUiState: StateFlow = eventRepository.getAllWithPerformance().map { - EventListUiState(it) - }.stateIn( - scope = viewModelScope, - started = SharingStarted.WhileSubscribed(stopTimeoutMillis = AppDataContainer.TIMEOUT), - initialValue = EventListUiState() - ) + val eventListUiState: Flow> = eventRepository.getAllWithPerformance() } - -data class EventListUiState(val eventList: List = listOf()) \ No newline at end of file diff --git a/app/src/main/java/com/example/mobile_labs/ui/performance/list/PerformanceList.kt b/app/src/main/java/com/example/mobile_labs/ui/performance/list/PerformanceList.kt index be607da..4060056 100644 --- a/app/src/main/java/com/example/mobile_labs/ui/performance/list/PerformanceList.kt +++ b/app/src/main/java/com/example/mobile_labs/ui/performance/list/PerformanceList.kt @@ -36,6 +36,11 @@ import androidx.compose.ui.tooling.preview.Preview import androidx.compose.ui.unit.dp import androidx.lifecycle.viewmodel.compose.viewModel import androidx.navigation.NavController +import androidx.paging.PagingData +import androidx.paging.compose.LazyPagingItems +import androidx.paging.compose.collectAsLazyPagingItems +import androidx.paging.compose.itemContentType +import androidx.paging.compose.itemKey import coil.compose.AsyncImage import com.example.mobile_labs.R import com.example.mobile_labs.database.AppDatabase @@ -45,9 +50,11 @@ import com.example.mobile_labs.database.performance.model.Performance import com.example.mobile_labs.database.person.model.Person import com.example.mobile_labs.ui.AppViewModelProvider import com.example.mobile_labs.ui.navigation.Screen +import com.example.mobile_labs.ui.person.list.PeopleList import com.example.mobile_labs.ui.person.list.PeopleListViewModel import com.example.mobile_labs.ui.theme.Mobile_LabsTheme import kotlinx.coroutines.Dispatchers +import kotlinx.coroutines.flow.MutableStateFlow import kotlinx.coroutines.withContext import java.time.LocalDate import java.time.format.DateTimeFormatter @@ -57,14 +64,14 @@ fun PerformanceList( navController: NavController, viewModel: PerformanceListViewModel = viewModel(factory = AppViewModelProvider.Factory) ) { - val performanceListUiState by viewModel.performanceListUiState.collectAsState() + val performanceListUiState = viewModel.performanceListUiState.collectAsLazyPagingItems() Column( horizontalAlignment = Alignment.CenterHorizontally, modifier = Modifier .padding(all = 10.dp)) { PerformanceList( - performanceList = performanceListUiState.performanceList, + performanceList = performanceListUiState, onClick = {uid : Int -> val route = Screen.PerformanceView.route.replace("{id}", uid.toString()) navController.navigate(route) @@ -77,13 +84,13 @@ fun PerformanceList( @Composable private fun PerformanceList( modifier: Modifier = Modifier, - performanceList: List, + performanceList: LazyPagingItems, onClick: (uid: Int) -> Unit ) { Column( modifier = modifier ) { - if (performanceList.isEmpty()) { + if (performanceList.itemCount == 0) { Text( text = stringResource(R.string.performance_missing_description), textAlign = TextAlign.Center, @@ -91,9 +98,16 @@ private fun PerformanceList( ) } else { LazyColumn(modifier = Modifier.padding(all = 10.dp)) { - items(items = performanceList, key = { it.performance_uid !! }) { performance -> - PerformanceListItem(performance = performance, modifier = Modifier - .padding(vertical = 7.dp), onClick = onClick) + items( + count = performanceList.itemCount, + key = performanceList.itemKey(), + contentType = performanceList.itemContentType() + ) { index -> + val performance = performanceList[index] + performance?.let { + PerformanceListItem(performance = performance, modifier = Modifier + .padding(vertical = 7.dp), onClick = onClick) + } } } } @@ -132,7 +146,12 @@ fun SchedulePreview() { Surface( color = MaterialTheme.colorScheme.background ) { - PerformanceList(performanceList = listOf(), onClick = {}) + PerformanceList( + performanceList = MutableStateFlow( + PagingData.empty() + ).collectAsLazyPagingItems(), + onClick = {} + ) } } } \ No newline at end of file diff --git a/app/src/main/java/com/example/mobile_labs/ui/performance/list/PerformanceListViewModel.kt b/app/src/main/java/com/example/mobile_labs/ui/performance/list/PerformanceListViewModel.kt index 0c714d7..57014c5 100644 --- a/app/src/main/java/com/example/mobile_labs/ui/performance/list/PerformanceListViewModel.kt +++ b/app/src/main/java/com/example/mobile_labs/ui/performance/list/PerformanceListViewModel.kt @@ -2,9 +2,12 @@ package com.example.mobile_labs.ui.performance.list import androidx.lifecycle.ViewModel import androidx.lifecycle.viewModelScope +import androidx.paging.PagingData import com.example.mobile_labs.database.AppDataContainer import com.example.mobile_labs.database.performance.model.Performance import com.example.mobile_labs.database.performance.repository.PerformanceRepository +import com.example.mobile_labs.database.person.model.Person +import kotlinx.coroutines.flow.Flow import kotlinx.coroutines.flow.SharingStarted import kotlinx.coroutines.flow.StateFlow import kotlinx.coroutines.flow.map @@ -13,17 +16,5 @@ import kotlinx.coroutines.flow.stateIn class PerformanceListViewModel( private val performanceRepository: PerformanceRepository ) : ViewModel() { - val performanceListUiState: StateFlow = performanceRepository.getAllPerformances().map { - PerformanceListUiState(it) - }.stateIn( - scope = viewModelScope, - started = SharingStarted.WhileSubscribed(stopTimeoutMillis = AppDataContainer.TIMEOUT), - initialValue = PerformanceListUiState() - ) - -// suspend fun deleteStudent(student: Student) { -// studentRepository.deleteStudent(student) -// } -} - -data class PerformanceListUiState(val performanceList: List = listOf()) \ No newline at end of file + val performanceListUiState: Flow> = performanceRepository.getAllPerformances() +} \ No newline at end of file diff --git a/app/src/main/java/com/example/mobile_labs/ui/person/list/PeopleList.kt b/app/src/main/java/com/example/mobile_labs/ui/person/list/PeopleList.kt index f87b361..accecf4 100644 --- a/app/src/main/java/com/example/mobile_labs/ui/person/list/PeopleList.kt +++ b/app/src/main/java/com/example/mobile_labs/ui/person/list/PeopleList.kt @@ -41,6 +41,11 @@ import androidx.compose.ui.tooling.preview.Preview import androidx.compose.ui.unit.dp import androidx.lifecycle.viewmodel.compose.viewModel import androidx.navigation.NavController +import androidx.paging.PagingData +import androidx.paging.compose.LazyPagingItems +import androidx.paging.compose.collectAsLazyPagingItems +import androidx.paging.compose.itemContentType +import androidx.paging.compose.itemKey import coil.compose.AsyncImage import com.example.mobile_labs.R import com.example.mobile_labs.ui.navigation.Screen @@ -50,6 +55,7 @@ import com.example.mobile_labs.database.person.model.Person import com.example.mobile_labs.ui.AppViewModelProvider import com.example.mobile_labs.ui.theme.Mobile_LabsTheme import kotlinx.coroutines.Dispatchers +import kotlinx.coroutines.flow.MutableStateFlow import kotlinx.coroutines.withContext import java.time.LocalDate import java.time.format.DateTimeFormatter @@ -58,7 +64,7 @@ import java.time.format.DateTimeFormatter fun PeopleList( viewModel: PeopleListViewModel = viewModel(factory = AppViewModelProvider.Factory) ) { - val peopleListUiState by viewModel.personListUiState.collectAsState() + val peopleListUiState = viewModel.personListUiState.collectAsLazyPagingItems() Column( horizontalAlignment = Alignment.CenterHorizontally, @@ -67,7 +73,7 @@ fun PeopleList( PeopleList( modifier = Modifier .fillMaxSize(), - peopleList = peopleListUiState.personList + peopleList = peopleListUiState ) } } @@ -76,12 +82,12 @@ fun PeopleList( @Composable private fun PeopleList( modifier: Modifier = Modifier, - peopleList: List, + peopleList: LazyPagingItems, ) { Column( modifier = modifier ) { - if (peopleList.isEmpty()) { + if (peopleList.itemCount == 0) { Text( text = stringResource(R.string.people_missing_description), textAlign = TextAlign.Center, @@ -89,9 +95,15 @@ private fun PeopleList( ) } else { LazyColumn(modifier = Modifier.padding(all = 10.dp)) { - items(items = peopleList, key = { it.uid !! }) { person -> - PeopleListItem(person = person, modifier = Modifier - .padding(vertical = 7.dp)) + items( + count = peopleList.itemCount, + key = peopleList.itemKey(), + contentType = peopleList.itemContentType() + ) { index -> + val person = peopleList[index] + person?.let { + PeopleListItem(person = person, modifier = Modifier.padding(10.dp)) + } } } } @@ -130,7 +142,9 @@ fun PeopleListPreview() { Surface( color = MaterialTheme.colorScheme.background ) { - PeopleList(peopleList = listOf()) + PeopleList(peopleList = MutableStateFlow( + PagingData.empty() + ).collectAsLazyPagingItems()) } } } \ No newline at end of file diff --git a/app/src/main/java/com/example/mobile_labs/ui/person/list/PeopleListViewModel.kt b/app/src/main/java/com/example/mobile_labs/ui/person/list/PeopleListViewModel.kt index 9d5422d..a271d5a 100644 --- a/app/src/main/java/com/example/mobile_labs/ui/person/list/PeopleListViewModel.kt +++ b/app/src/main/java/com/example/mobile_labs/ui/person/list/PeopleListViewModel.kt @@ -2,9 +2,11 @@ package com.example.mobile_labs.ui.person.list import androidx.lifecycle.ViewModel import androidx.lifecycle.viewModelScope +import androidx.paging.PagingData import com.example.mobile_labs.database.AppDataContainer import com.example.mobile_labs.database.person.model.Person import com.example.mobile_labs.database.person.repository.PersonRepository +import kotlinx.coroutines.flow.Flow import kotlinx.coroutines.flow.SharingStarted import kotlinx.coroutines.flow.StateFlow import kotlinx.coroutines.flow.map @@ -13,13 +15,5 @@ import kotlinx.coroutines.flow.stateIn class PeopleListViewModel( private val personRepository: PersonRepository ) : ViewModel() { - val personListUiState: StateFlow = personRepository.getAllPeople().map { - PersonListUiState(it) - }.stateIn( - scope = viewModelScope, - started = SharingStarted.WhileSubscribed(stopTimeoutMillis = AppDataContainer.TIMEOUT), - initialValue = PersonListUiState() - ) -} - -data class PersonListUiState(val personList: List = listOf()) \ No newline at end of file + val personListUiState: Flow> = personRepository.getAllPeople() +} \ No newline at end of file