Lab 04: add pagination

This commit is contained in:
abazov73 2023-12-05 22:26:05 +04:00
parent 7707836c12
commit c40d14e9b4
17 changed files with 140 additions and 69 deletions

View File

@ -76,6 +76,8 @@ dependencies {
implementation("androidx.room:room-ktx:$room_version") implementation("androidx.room:room-ktx:$room_version")
implementation("androidx.room:room-paging:$room_version") implementation("androidx.room:room-paging:$room_version")
implementation("androidx.paging:paging-compose:3.2.1")
//Tests //Tests
testImplementation("junit:junit:4.13.2") testImplementation("junit:junit:4.13.2")
androidTestImplementation("androidx.test.ext:junit:1.1.5") androidTestImplementation("androidx.test.ext:junit:1.1.5")

View File

@ -29,5 +29,6 @@ class AppDataContainer(private val context: Context) : AppContainer {
companion object { companion object {
const val TIMEOUT = 5000L const val TIMEOUT = 5000L
const val LIMIT = 3
} }
} }

View File

@ -1,5 +1,6 @@
package com.example.mobile_labs.database.event.dao package com.example.mobile_labs.database.event.dao
import androidx.paging.PagingSource
import androidx.room.Dao import androidx.room.Dao
import androidx.room.Delete import androidx.room.Delete
import androidx.room.Insert 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.event.model.EventWithPerformance
import com.example.mobile_labs.database.performance.model.Performance import com.example.mobile_labs.database.performance.model.Performance
import kotlinx.coroutines.flow.Flow import kotlinx.coroutines.flow.Flow
import java.time.LocalDate
import java.time.format.DateTimeFormatter
@Dao @Dao
interface EventDao { interface EventDao {
@Query("select * from events order by date asc") @Query("select * from events order by date asc")
fun getAll(): Flow<List<Event>> fun getAll(): Flow<List<Event>>
@Query("select * from events where events.date > :dateFrom order by date asc") @Query("select * from events where events.date > :dateFrom order by date collate nocase asc")
fun getAllWithPerformance(dateFrom: String): Flow<List<EventWithPerformance>> fun getAllWithPerformance(dateFrom: String? = LocalDate.now().format(
DateTimeFormatter.ofPattern("dd.MM"))): PagingSource<Int, EventWithPerformance>
@Query("select * from events where events.uid = :uid") @Query("select * from events where events.uid = :uid")
fun getByUid(uid: Int): Flow<EventWithPerformance> fun getByUid(uid: Int): Flow<EventWithPerformance>

View File

@ -1,12 +1,13 @@
package com.example.mobile_labs.database.event.repository 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.Event
import com.example.mobile_labs.database.event.model.EventWithPerformance import com.example.mobile_labs.database.event.model.EventWithPerformance
import kotlinx.coroutines.flow.Flow import kotlinx.coroutines.flow.Flow
interface EventRepository { interface EventRepository {
fun getAll(): Flow<List<Event>> fun getAll(): Flow<List<Event>>
fun getAllWithPerformance(): Flow<List<EventWithPerformance>> fun getAllWithPerformance(): Flow<PagingData<EventWithPerformance>>
fun getEvent(uid: Int): Flow<EventWithPerformance?> fun getEvent(uid: Int): Flow<EventWithPerformance?>
suspend fun insertEvent(event: Event) suspend fun insertEvent(event: Event)
suspend fun updateEvent(event: Event) suspend fun updateEvent(event: Event)

View File

@ -1,5 +1,9 @@
package com.example.mobile_labs.database.event.repository 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.dao.EventDao
import com.example.mobile_labs.database.event.model.Event import com.example.mobile_labs.database.event.model.Event
import com.example.mobile_labs.database.event.model.EventWithPerformance 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 { class OfflineEventRepository(private val eventDao: EventDao) : EventRepository {
override fun getAll(): Flow<List<Event>> = eventDao.getAll(); override fun getAll(): Flow<List<Event>> = eventDao.getAll();
override fun getAllWithPerformance(): Flow<List<EventWithPerformance>> = eventDao.getAllWithPerformance(LocalDate.now().format( override fun getAllWithPerformance(): Flow<PagingData<EventWithPerformance>> = Pager(
DateTimeFormatter.ofPattern("dd.MM") config = PagingConfig(
)) pageSize = AppDataContainer.LIMIT,
enablePlaceholders = false,
),
pagingSourceFactory = eventDao::getAllWithPerformance
).flow
override fun getEvent(uid: Int): Flow<EventWithPerformance?> = eventDao.getByUid(uid); override fun getEvent(uid: Int): Flow<EventWithPerformance?> = eventDao.getByUid(uid);
override suspend fun insertEvent(event: Event) = eventDao.insert(event); override suspend fun insertEvent(event: Event) = eventDao.insert(event);

View File

@ -1,5 +1,6 @@
package com.example.mobile_labs.database.performance.dao package com.example.mobile_labs.database.performance.dao
import androidx.paging.PagingSource
import androidx.room.Dao import androidx.room.Dao
import androidx.room.Delete import androidx.room.Delete
import androidx.room.Insert import androidx.room.Insert
@ -13,7 +14,7 @@ import kotlinx.coroutines.flow.Flow
@Dao @Dao
interface PerformanceDao { interface PerformanceDao {
@Query("select * from performances order by title collate nocase asc") @Query("select * from performances order by title collate nocase asc")
fun getAll(): Flow<List<Performance>> fun getAll(): PagingSource<Int, Performance>
@Query("select * from performances where performances.performance_uid = :uid") @Query("select * from performances where performances.performance_uid = :uid")
fun getByUid(uid: Int): Flow<PerformanceWithPeople> fun getByUid(uid: Int): Flow<PerformanceWithPeople>

View File

@ -1,12 +1,22 @@
package com.example.mobile_labs.database.performance.repository 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.dao.PerformanceDao
import com.example.mobile_labs.database.performance.model.Performance import com.example.mobile_labs.database.performance.model.Performance
import com.example.mobile_labs.database.performance.model.PerformanceWithPeople import com.example.mobile_labs.database.performance.model.PerformanceWithPeople
import kotlinx.coroutines.flow.Flow import kotlinx.coroutines.flow.Flow
class OfflinePerformanceRepository(private val performanceDao: PerformanceDao) : PerformanceRepository { class OfflinePerformanceRepository(private val performanceDao: PerformanceDao) : PerformanceRepository {
override fun getAllPerformances(): Flow<List<Performance>> = performanceDao.getAll(); override fun getAllPerformances(): Flow<PagingData<Performance>> = Pager(
config = PagingConfig(
pageSize = AppDataContainer.LIMIT,
enablePlaceholders = false,
),
pagingSourceFactory = performanceDao::getAll
).flow
override fun getPerformance(uid: Int): Flow<PerformanceWithPeople?> = performanceDao.getByUid(uid); override fun getPerformance(uid: Int): Flow<PerformanceWithPeople?> = performanceDao.getByUid(uid);
override suspend fun insertPerformance(performance: Performance) = performanceDao.insert(performance); override suspend fun insertPerformance(performance: Performance) = performanceDao.insert(performance);

View File

@ -1,11 +1,12 @@
package com.example.mobile_labs.database.performance.repository 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.Performance
import com.example.mobile_labs.database.performance.model.PerformanceWithPeople import com.example.mobile_labs.database.performance.model.PerformanceWithPeople
import kotlinx.coroutines.flow.Flow import kotlinx.coroutines.flow.Flow
interface PerformanceRepository { interface PerformanceRepository {
fun getAllPerformances(): Flow<List<Performance>> fun getAllPerformances(): Flow<PagingData<Performance>>
fun getPerformance(uid: Int): Flow<PerformanceWithPeople?> fun getPerformance(uid: Int): Flow<PerformanceWithPeople?>
suspend fun insertPerformance(performance: Performance) suspend fun insertPerformance(performance: Performance)
suspend fun updatePerformance(performance: Performance) suspend fun updatePerformance(performance: Performance)

View File

@ -1,5 +1,6 @@
package com.example.mobile_labs.database.person.dao package com.example.mobile_labs.database.person.dao
import androidx.paging.PagingSource
import androidx.room.Dao import androidx.room.Dao
import androidx.room.Delete import androidx.room.Delete
import androidx.room.Insert import androidx.room.Insert
@ -11,7 +12,7 @@ import kotlinx.coroutines.flow.Flow
@Dao @Dao
interface PersonDao { interface PersonDao {
@Query("select * from people order by last_name collate nocase asc") @Query("select * from people order by last_name collate nocase asc")
fun getAll(): Flow<List<Person>> fun getAll(): PagingSource<Int, Person>
@Query("select * from people where people.uid = :uid") @Query("select * from people where people.uid = :uid")
fun getByUid(uid: Int): Flow<Person> fun getByUid(uid: Int): Flow<Person>

View File

@ -1,11 +1,22 @@
package com.example.mobile_labs.database.person.repository 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.dao.PersonDao
import com.example.mobile_labs.database.person.model.Person import com.example.mobile_labs.database.person.model.Person
import kotlinx.coroutines.flow.Flow import kotlinx.coroutines.flow.Flow
class OfflinePersonRepository(private val personDao: PersonDao) : PersonRepository { class OfflinePersonRepository(private val personDao: PersonDao) : PersonRepository {
override fun getAllPeople(): Flow<List<Person>> = personDao.getAll(); override fun getAllPeople(): Flow<PagingData<Person>> = Pager(
config = PagingConfig(
pageSize = AppDataContainer.LIMIT,
enablePlaceholders = false,
),
pagingSourceFactory = personDao::getAll
).flow;
override fun getPerson(uid: Int): Flow<Person?> = personDao.getByUid(uid); override fun getPerson(uid: Int): Flow<Person?> = personDao.getByUid(uid);
override suspend fun insertPerson(person: Person) = personDao.insert(person); override suspend fun insertPerson(person: Person) = personDao.insert(person);

View File

@ -1,10 +1,11 @@
package com.example.mobile_labs.database.person.repository package com.example.mobile_labs.database.person.repository
import androidx.paging.PagingData
import com.example.mobile_labs.database.person.model.Person import com.example.mobile_labs.database.person.model.Person
import kotlinx.coroutines.flow.Flow import kotlinx.coroutines.flow.Flow
interface PersonRepository { interface PersonRepository {
fun getAllPeople(): Flow<List<Person>> fun getAllPeople(): Flow<PagingData<Person>>
fun getPerson(uid: Int): Flow<Person?> fun getPerson(uid: Int): Flow<Person?>
suspend fun insertPerson(person: Person) suspend fun insertPerson(person: Person)
suspend fun updatePerson(person: Person) suspend fun updatePerson(person: Person)

View File

@ -35,17 +35,24 @@ import androidx.compose.ui.tooling.preview.Preview
import androidx.compose.ui.unit.dp import androidx.compose.ui.unit.dp
import androidx.lifecycle.viewmodel.compose.viewModel import androidx.lifecycle.viewmodel.compose.viewModel
import androidx.navigation.NavController 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 coil.compose.AsyncImage
import com.example.mobile_labs.R import com.example.mobile_labs.R
import com.example.mobile_labs.database.AppDatabase import com.example.mobile_labs.database.AppDatabase
import com.example.mobile_labs.database.event.model.Event import com.example.mobile_labs.database.event.model.Event
import com.example.mobile_labs.database.event.model.EventWithPerformance 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.database.person.model.Person
import com.example.mobile_labs.ui.AppViewModelProvider import com.example.mobile_labs.ui.AppViewModelProvider
import com.example.mobile_labs.ui.navigation.Screen import com.example.mobile_labs.ui.navigation.Screen
import com.example.mobile_labs.ui.person.list.PeopleListViewModel import com.example.mobile_labs.ui.person.list.PeopleListViewModel
import com.example.mobile_labs.ui.theme.Mobile_LabsTheme import com.example.mobile_labs.ui.theme.Mobile_LabsTheme
import kotlinx.coroutines.Dispatchers import kotlinx.coroutines.Dispatchers
import kotlinx.coroutines.flow.MutableStateFlow
import kotlinx.coroutines.withContext import kotlinx.coroutines.withContext
import java.time.LocalDate import java.time.LocalDate
import java.time.format.DateTimeFormatter import java.time.format.DateTimeFormatter
@ -55,14 +62,14 @@ fun EventList(
navController: NavController, navController: NavController,
viewModel: EventListViewModel = viewModel(factory = AppViewModelProvider.Factory) viewModel: EventListViewModel = viewModel(factory = AppViewModelProvider.Factory)
) { ) {
val eventListUiState by viewModel.eventListUiState.collectAsState() val eventListUiState = viewModel.eventListUiState.collectAsLazyPagingItems()
Column( Column(
horizontalAlignment = Alignment.CenterHorizontally, horizontalAlignment = Alignment.CenterHorizontally,
modifier = Modifier modifier = Modifier
.padding(all = 10.dp)) { .padding(all = 10.dp)) {
EventList( EventList(
eventList = eventListUiState.eventList, eventList = eventListUiState,
onClick = {uid : Int -> onClick = {uid : Int ->
val route = Screen.PerformanceView.route.replace("{id}", uid.toString()) val route = Screen.PerformanceView.route.replace("{id}", uid.toString())
navController.navigate(route) navController.navigate(route)
@ -75,13 +82,13 @@ fun EventList(
@Composable @Composable
private fun EventList( private fun EventList(
modifier: Modifier = Modifier, modifier: Modifier = Modifier,
eventList: List<EventWithPerformance>, eventList: LazyPagingItems<EventWithPerformance>,
onClick: (uid: Int) -> Unit onClick: (uid: Int) -> Unit
) { ) {
Column( Column(
modifier = modifier modifier = modifier
) { ) {
if (eventList.isEmpty()) { if (eventList.itemCount == 0) {
Text( Text(
text = stringResource(R.string.events_missing_description), text = stringResource(R.string.events_missing_description),
textAlign = TextAlign.Center, textAlign = TextAlign.Center,
@ -89,9 +96,16 @@ private fun EventList(
) )
} else { } else {
LazyColumn(modifier = Modifier.padding(all = 10.dp)) { LazyColumn(modifier = Modifier.padding(all = 10.dp)) {
items(items = eventList, key = { it.event.uid !! }) { event -> items(
EventListItem(event = event, modifier = Modifier count = eventList.itemCount,
.padding(vertical = 7.dp), onClick = onClick) 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( Surface(
color = MaterialTheme.colorScheme.background color = MaterialTheme.colorScheme.background
) { ) {
EventList(eventList = listOf(), onClick = {}) EventList(eventList = MutableStateFlow(
PagingData.empty<EventWithPerformance>()
).collectAsLazyPagingItems(),
onClick = {})
} }
} }
} }

View File

@ -2,10 +2,12 @@ package com.example.mobile_labs.ui.event.list
import androidx.lifecycle.ViewModel import androidx.lifecycle.ViewModel
import androidx.lifecycle.viewModelScope import androidx.lifecycle.viewModelScope
import androidx.paging.PagingData
import com.example.mobile_labs.database.AppDataContainer import com.example.mobile_labs.database.AppDataContainer
import com.example.mobile_labs.database.event.repository.EventRepository 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.Event
import com.example.mobile_labs.database.event.model.EventWithPerformance import com.example.mobile_labs.database.event.model.EventWithPerformance
import kotlinx.coroutines.flow.Flow
import kotlinx.coroutines.flow.SharingStarted import kotlinx.coroutines.flow.SharingStarted
import kotlinx.coroutines.flow.StateFlow import kotlinx.coroutines.flow.StateFlow
import kotlinx.coroutines.flow.map import kotlinx.coroutines.flow.map
@ -14,13 +16,5 @@ import kotlinx.coroutines.flow.stateIn
class EventListViewModel( class EventListViewModel(
private val eventRepository: EventRepository private val eventRepository: EventRepository
) : ViewModel() { ) : ViewModel() {
val eventListUiState: StateFlow<EventListUiState> = eventRepository.getAllWithPerformance().map { val eventListUiState: Flow<PagingData<EventWithPerformance>> = eventRepository.getAllWithPerformance()
EventListUiState(it)
}.stateIn(
scope = viewModelScope,
started = SharingStarted.WhileSubscribed(stopTimeoutMillis = AppDataContainer.TIMEOUT),
initialValue = EventListUiState()
)
} }
data class EventListUiState(val eventList: List<EventWithPerformance> = listOf())

View File

@ -36,6 +36,11 @@ import androidx.compose.ui.tooling.preview.Preview
import androidx.compose.ui.unit.dp import androidx.compose.ui.unit.dp
import androidx.lifecycle.viewmodel.compose.viewModel import androidx.lifecycle.viewmodel.compose.viewModel
import androidx.navigation.NavController 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 coil.compose.AsyncImage
import com.example.mobile_labs.R import com.example.mobile_labs.R
import com.example.mobile_labs.database.AppDatabase 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.database.person.model.Person
import com.example.mobile_labs.ui.AppViewModelProvider import com.example.mobile_labs.ui.AppViewModelProvider
import com.example.mobile_labs.ui.navigation.Screen 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.person.list.PeopleListViewModel
import com.example.mobile_labs.ui.theme.Mobile_LabsTheme import com.example.mobile_labs.ui.theme.Mobile_LabsTheme
import kotlinx.coroutines.Dispatchers import kotlinx.coroutines.Dispatchers
import kotlinx.coroutines.flow.MutableStateFlow
import kotlinx.coroutines.withContext import kotlinx.coroutines.withContext
import java.time.LocalDate import java.time.LocalDate
import java.time.format.DateTimeFormatter import java.time.format.DateTimeFormatter
@ -57,14 +64,14 @@ fun PerformanceList(
navController: NavController, navController: NavController,
viewModel: PerformanceListViewModel = viewModel(factory = AppViewModelProvider.Factory) viewModel: PerformanceListViewModel = viewModel(factory = AppViewModelProvider.Factory)
) { ) {
val performanceListUiState by viewModel.performanceListUiState.collectAsState() val performanceListUiState = viewModel.performanceListUiState.collectAsLazyPagingItems()
Column( Column(
horizontalAlignment = Alignment.CenterHorizontally, horizontalAlignment = Alignment.CenterHorizontally,
modifier = Modifier modifier = Modifier
.padding(all = 10.dp)) { .padding(all = 10.dp)) {
PerformanceList( PerformanceList(
performanceList = performanceListUiState.performanceList, performanceList = performanceListUiState,
onClick = {uid : Int -> onClick = {uid : Int ->
val route = Screen.PerformanceView.route.replace("{id}", uid.toString()) val route = Screen.PerformanceView.route.replace("{id}", uid.toString())
navController.navigate(route) navController.navigate(route)
@ -77,13 +84,13 @@ fun PerformanceList(
@Composable @Composable
private fun PerformanceList( private fun PerformanceList(
modifier: Modifier = Modifier, modifier: Modifier = Modifier,
performanceList: List<Performance>, performanceList: LazyPagingItems<Performance>,
onClick: (uid: Int) -> Unit onClick: (uid: Int) -> Unit
) { ) {
Column( Column(
modifier = modifier modifier = modifier
) { ) {
if (performanceList.isEmpty()) { if (performanceList.itemCount == 0) {
Text( Text(
text = stringResource(R.string.performance_missing_description), text = stringResource(R.string.performance_missing_description),
textAlign = TextAlign.Center, textAlign = TextAlign.Center,
@ -91,9 +98,16 @@ private fun PerformanceList(
) )
} else { } else {
LazyColumn(modifier = Modifier.padding(all = 10.dp)) { LazyColumn(modifier = Modifier.padding(all = 10.dp)) {
items(items = performanceList, key = { it.performance_uid !! }) { performance -> items(
PerformanceListItem(performance = performance, modifier = Modifier count = performanceList.itemCount,
.padding(vertical = 7.dp), onClick = onClick) 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( Surface(
color = MaterialTheme.colorScheme.background color = MaterialTheme.colorScheme.background
) { ) {
PerformanceList(performanceList = listOf(), onClick = {}) PerformanceList(
performanceList = MutableStateFlow(
PagingData.empty<Performance>()
).collectAsLazyPagingItems(),
onClick = {}
)
} }
} }
} }

View File

@ -2,9 +2,12 @@ package com.example.mobile_labs.ui.performance.list
import androidx.lifecycle.ViewModel import androidx.lifecycle.ViewModel
import androidx.lifecycle.viewModelScope import androidx.lifecycle.viewModelScope
import androidx.paging.PagingData
import com.example.mobile_labs.database.AppDataContainer import com.example.mobile_labs.database.AppDataContainer
import com.example.mobile_labs.database.performance.model.Performance import com.example.mobile_labs.database.performance.model.Performance
import com.example.mobile_labs.database.performance.repository.PerformanceRepository 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.SharingStarted
import kotlinx.coroutines.flow.StateFlow import kotlinx.coroutines.flow.StateFlow
import kotlinx.coroutines.flow.map import kotlinx.coroutines.flow.map
@ -13,17 +16,5 @@ import kotlinx.coroutines.flow.stateIn
class PerformanceListViewModel( class PerformanceListViewModel(
private val performanceRepository: PerformanceRepository private val performanceRepository: PerformanceRepository
) : ViewModel() { ) : ViewModel() {
val performanceListUiState: StateFlow<PerformanceListUiState> = performanceRepository.getAllPerformances().map { val performanceListUiState: Flow<PagingData<Performance>> = performanceRepository.getAllPerformances()
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<Performance> = listOf())

View File

@ -41,6 +41,11 @@ import androidx.compose.ui.tooling.preview.Preview
import androidx.compose.ui.unit.dp import androidx.compose.ui.unit.dp
import androidx.lifecycle.viewmodel.compose.viewModel import androidx.lifecycle.viewmodel.compose.viewModel
import androidx.navigation.NavController 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 coil.compose.AsyncImage
import com.example.mobile_labs.R import com.example.mobile_labs.R
import com.example.mobile_labs.ui.navigation.Screen 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.AppViewModelProvider
import com.example.mobile_labs.ui.theme.Mobile_LabsTheme import com.example.mobile_labs.ui.theme.Mobile_LabsTheme
import kotlinx.coroutines.Dispatchers import kotlinx.coroutines.Dispatchers
import kotlinx.coroutines.flow.MutableStateFlow
import kotlinx.coroutines.withContext import kotlinx.coroutines.withContext
import java.time.LocalDate import java.time.LocalDate
import java.time.format.DateTimeFormatter import java.time.format.DateTimeFormatter
@ -58,7 +64,7 @@ import java.time.format.DateTimeFormatter
fun PeopleList( fun PeopleList(
viewModel: PeopleListViewModel = viewModel(factory = AppViewModelProvider.Factory) viewModel: PeopleListViewModel = viewModel(factory = AppViewModelProvider.Factory)
) { ) {
val peopleListUiState by viewModel.personListUiState.collectAsState() val peopleListUiState = viewModel.personListUiState.collectAsLazyPagingItems()
Column( Column(
horizontalAlignment = Alignment.CenterHorizontally, horizontalAlignment = Alignment.CenterHorizontally,
@ -67,7 +73,7 @@ fun PeopleList(
PeopleList( PeopleList(
modifier = Modifier modifier = Modifier
.fillMaxSize(), .fillMaxSize(),
peopleList = peopleListUiState.personList peopleList = peopleListUiState
) )
} }
} }
@ -76,12 +82,12 @@ fun PeopleList(
@Composable @Composable
private fun PeopleList( private fun PeopleList(
modifier: Modifier = Modifier, modifier: Modifier = Modifier,
peopleList: List<Person>, peopleList: LazyPagingItems<Person>,
) { ) {
Column( Column(
modifier = modifier modifier = modifier
) { ) {
if (peopleList.isEmpty()) { if (peopleList.itemCount == 0) {
Text( Text(
text = stringResource(R.string.people_missing_description), text = stringResource(R.string.people_missing_description),
textAlign = TextAlign.Center, textAlign = TextAlign.Center,
@ -89,9 +95,15 @@ private fun PeopleList(
) )
} else { } else {
LazyColumn(modifier = Modifier.padding(all = 10.dp)) { LazyColumn(modifier = Modifier.padding(all = 10.dp)) {
items(items = peopleList, key = { it.uid !! }) { person -> items(
PeopleListItem(person = person, modifier = Modifier count = peopleList.itemCount,
.padding(vertical = 7.dp)) 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( Surface(
color = MaterialTheme.colorScheme.background color = MaterialTheme.colorScheme.background
) { ) {
PeopleList(peopleList = listOf()) PeopleList(peopleList = MutableStateFlow(
PagingData.empty<Person>()
).collectAsLazyPagingItems())
} }
} }
} }

View File

@ -2,9 +2,11 @@ package com.example.mobile_labs.ui.person.list
import androidx.lifecycle.ViewModel import androidx.lifecycle.ViewModel
import androidx.lifecycle.viewModelScope import androidx.lifecycle.viewModelScope
import androidx.paging.PagingData
import com.example.mobile_labs.database.AppDataContainer import com.example.mobile_labs.database.AppDataContainer
import com.example.mobile_labs.database.person.model.Person import com.example.mobile_labs.database.person.model.Person
import com.example.mobile_labs.database.person.repository.PersonRepository import com.example.mobile_labs.database.person.repository.PersonRepository
import kotlinx.coroutines.flow.Flow
import kotlinx.coroutines.flow.SharingStarted import kotlinx.coroutines.flow.SharingStarted
import kotlinx.coroutines.flow.StateFlow import kotlinx.coroutines.flow.StateFlow
import kotlinx.coroutines.flow.map import kotlinx.coroutines.flow.map
@ -13,13 +15,5 @@ import kotlinx.coroutines.flow.stateIn
class PeopleListViewModel( class PeopleListViewModel(
private val personRepository: PersonRepository private val personRepository: PersonRepository
) : ViewModel() { ) : ViewModel() {
val personListUiState: StateFlow<PersonListUiState> = personRepository.getAllPeople().map { val personListUiState: Flow<PagingData<Person>> = personRepository.getAllPeople()
PersonListUiState(it) }
}.stateIn(
scope = viewModelScope,
started = SharingStarted.WhileSubscribed(stopTimeoutMillis = AppDataContainer.TIMEOUT),
initialValue = PersonListUiState()
)
}
data class PersonListUiState(val personList: List<Person> = listOf())