Lab 04: add pagination
This commit is contained in:
parent
7707836c12
commit
c40d14e9b4
@ -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")
|
||||||
|
@ -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
|
||||||
}
|
}
|
||||||
}
|
}
|
@ -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>
|
||||||
|
@ -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)
|
||||||
|
@ -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);
|
||||||
|
@ -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>
|
||||||
|
@ -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);
|
||||||
|
@ -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)
|
||||||
|
@ -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>
|
||||||
|
@ -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);
|
||||||
|
@ -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)
|
||||||
|
@ -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,7 +96,13 @@ 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(
|
||||||
|
count = eventList.itemCount,
|
||||||
|
key = eventList.itemKey(),
|
||||||
|
contentType = eventList.itemContentType(),
|
||||||
|
) { index ->
|
||||||
|
val event = eventList[index]
|
||||||
|
event?.let{
|
||||||
EventListItem(event = event, modifier = Modifier
|
EventListItem(event = event, modifier = Modifier
|
||||||
.padding(vertical = 7.dp), onClick = onClick)
|
.padding(vertical = 7.dp), onClick = onClick)
|
||||||
}
|
}
|
||||||
@ -97,6 +110,7 @@ private fun EventList(
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
@Composable
|
@Composable
|
||||||
private fun EventListItem(
|
private fun EventListItem(
|
||||||
@ -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 = {})
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
@ -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())
|
|
@ -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,7 +98,13 @@ 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(
|
||||||
|
count = performanceList.itemCount,
|
||||||
|
key = performanceList.itemKey(),
|
||||||
|
contentType = performanceList.itemContentType()
|
||||||
|
) { index ->
|
||||||
|
val performance = performanceList[index]
|
||||||
|
performance?.let {
|
||||||
PerformanceListItem(performance = performance, modifier = Modifier
|
PerformanceListItem(performance = performance, modifier = Modifier
|
||||||
.padding(vertical = 7.dp), onClick = onClick)
|
.padding(vertical = 7.dp), onClick = onClick)
|
||||||
}
|
}
|
||||||
@ -99,6 +112,7 @@ private fun PerformanceList(
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
@Composable
|
@Composable
|
||||||
private fun PerformanceListItem(
|
private fun PerformanceListItem(
|
||||||
@ -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 = {}
|
||||||
|
)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
@ -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())
|
|
@ -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())
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
@ -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())
|
|
Loading…
Reference in New Issue
Block a user