Compare commits
6 Commits
f11ebc82f5
...
5e33722852
Author | SHA1 | Date | |
---|---|---|---|
5e33722852 | |||
ff58cccfc5 | |||
93f4af21a9 | |||
d35ee4907d | |||
c8f8b59672 | |||
4bf7ebb6bf |
@ -3,6 +3,7 @@ package com.example.myapplication.api
|
|||||||
import com.example.myapplication.api.cinema.CinemaRemote
|
import com.example.myapplication.api.cinema.CinemaRemote
|
||||||
import com.example.myapplication.api.cinema.CinemaWithSessionsRemote
|
import com.example.myapplication.api.cinema.CinemaWithSessionsRemote
|
||||||
import com.example.myapplication.api.order.OrderRemote
|
import com.example.myapplication.api.order.OrderRemote
|
||||||
|
import com.example.myapplication.api.order.OrderWithUserRemote
|
||||||
import com.example.myapplication.api.session.ReportRemote
|
import com.example.myapplication.api.session.ReportRemote
|
||||||
import com.example.myapplication.api.session.SessionFromCinemaRemote
|
import com.example.myapplication.api.session.SessionFromCinemaRemote
|
||||||
import com.example.myapplication.api.session.SessionRemote
|
import com.example.myapplication.api.session.SessionRemote
|
||||||
@ -137,6 +138,12 @@ interface MyServerService {
|
|||||||
@Query("_limit") limit: Int,
|
@Query("_limit") limit: Int,
|
||||||
): List<OrderRemote>
|
): List<OrderRemote>
|
||||||
|
|
||||||
|
@GET("orders?_expand=user")
|
||||||
|
suspend fun getOrders(
|
||||||
|
@Query("_page") page: Int,
|
||||||
|
@Query("_limit") limit: Int,
|
||||||
|
): List<OrderWithUserRemote>
|
||||||
|
|
||||||
@GET("orders/{id}")
|
@GET("orders/{id}")
|
||||||
suspend fun getOrder(
|
suspend fun getOrder(
|
||||||
@Path("id") id: Int,
|
@Path("id") id: Int,
|
||||||
@ -144,7 +151,7 @@ interface MyServerService {
|
|||||||
|
|
||||||
@POST("orders")
|
@POST("orders")
|
||||||
suspend fun createOrder(
|
suspend fun createOrder(
|
||||||
@Body cinema: OrderRemote,
|
@Body order: OrderRemote,
|
||||||
): OrderRemote
|
): OrderRemote
|
||||||
|
|
||||||
@PUT("orders/{id}")
|
@PUT("orders/{id}")
|
||||||
|
@ -55,9 +55,6 @@ class CinemaRemoteMediator(
|
|||||||
|
|
||||||
try {
|
try {
|
||||||
val cinemas = service.getCinemas(page, state.config.pageSize).map { it.toCinema() }
|
val cinemas = service.getCinemas(page, state.config.pageSize).map { it.toCinema() }
|
||||||
val sessionsFromCinemas = cinemas.flatMap { cinema ->
|
|
||||||
service.getCinemaWithSessions(cinema.uid).toSessions()
|
|
||||||
}
|
|
||||||
val endOfPaginationReached = cinemas.isEmpty()
|
val endOfPaginationReached = cinemas.isEmpty()
|
||||||
database.withTransaction {
|
database.withTransaction {
|
||||||
if (loadType == LoadType.REFRESH) {
|
if (loadType == LoadType.REFRESH) {
|
||||||
@ -77,7 +74,6 @@ class CinemaRemoteMediator(
|
|||||||
}
|
}
|
||||||
dbRemoteKeyRepository.createRemoteKeys(keys)
|
dbRemoteKeyRepository.createRemoteKeys(keys)
|
||||||
dbCinemaRepository.insertCinemas(cinemas)
|
dbCinemaRepository.insertCinemas(cinemas)
|
||||||
dbSessionRepository.insertSessions(sessionsFromCinemas)
|
|
||||||
}
|
}
|
||||||
return MediatorResult.Success(endOfPaginationReached = endOfPaginationReached)
|
return MediatorResult.Success(endOfPaginationReached = endOfPaginationReached)
|
||||||
} catch (exception: IOException) {
|
} catch (exception: IOException) {
|
||||||
|
@ -1,10 +1,7 @@
|
|||||||
package com.example.myapplication.api.cinema
|
package com.example.myapplication.api.cinema
|
||||||
|
|
||||||
import com.example.myapplication.api.session.SessionFromCinemaRemote
|
import com.example.myapplication.api.session.SessionFromCinemaRemote
|
||||||
import com.example.myapplication.api.session.toSessionFromCinema
|
|
||||||
import com.example.myapplication.database.entities.model.Cinema
|
import com.example.myapplication.database.entities.model.Cinema
|
||||||
import com.example.myapplication.database.entities.model.Session
|
|
||||||
import com.example.myapplication.database.entities.model.toSession
|
|
||||||
import kotlinx.serialization.SerialName
|
import kotlinx.serialization.SerialName
|
||||||
import kotlinx.serialization.Serializable
|
import kotlinx.serialization.Serializable
|
||||||
|
|
||||||
@ -27,5 +24,3 @@ fun CinemaWithSessionsRemote.toCinema(): Cinema = Cinema(
|
|||||||
year
|
year
|
||||||
)
|
)
|
||||||
|
|
||||||
fun CinemaWithSessionsRemote.toSessions(): List<Session> =
|
|
||||||
sessions.map { it.toSessionFromCinema().toSession() }
|
|
@ -5,11 +5,13 @@ import androidx.paging.Pager
|
|||||||
import androidx.paging.PagingConfig
|
import androidx.paging.PagingConfig
|
||||||
import androidx.paging.PagingData
|
import androidx.paging.PagingData
|
||||||
import com.example.myapplication.api.MyServerService
|
import com.example.myapplication.api.MyServerService
|
||||||
|
import com.example.myapplication.api.session.toSessionFromCinema
|
||||||
import com.example.myapplication.database.AppContainer
|
import com.example.myapplication.database.AppContainer
|
||||||
import com.example.myapplication.database.AppDatabase
|
import com.example.myapplication.database.AppDatabase
|
||||||
import com.example.myapplication.database.entities.model.Cinema
|
import com.example.myapplication.database.entities.model.Cinema
|
||||||
import com.example.myapplication.database.entities.model.CinemaWithSessions
|
import com.example.myapplication.database.entities.model.CinemaWithSessions
|
||||||
import com.example.myapplication.database.entities.model.SessionFromCinema
|
import com.example.myapplication.database.entities.model.SessionFromCinema
|
||||||
|
import com.example.myapplication.database.entities.model.toSession
|
||||||
import com.example.myapplication.database.entities.repository.CinemaRepository
|
import com.example.myapplication.database.entities.repository.CinemaRepository
|
||||||
import com.example.myapplication.database.entities.repository.OfflineCinemaRepository
|
import com.example.myapplication.database.entities.repository.OfflineCinemaRepository
|
||||||
import com.example.myapplication.database.entities.repository.OfflineSessionRepository
|
import com.example.myapplication.database.entities.repository.OfflineSessionRepository
|
||||||
@ -65,6 +67,9 @@ class RestCinemaRepository(
|
|||||||
uid
|
uid
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
dbSessionRepository.insertSessions(cinemaWithSessions.sessions.map {
|
||||||
|
it.toSessionFromCinema().toSession()
|
||||||
|
})
|
||||||
return CinemaWithSessions(cinemaWithSessions.toCinema(), sessions)
|
return CinemaWithSessions(cinemaWithSessions.toCinema(), sessions)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -20,5 +20,5 @@ fun OrderRemote.toOrder(): Order = Order(
|
|||||||
)
|
)
|
||||||
|
|
||||||
fun Order.toOrderRemote(): OrderRemote = OrderRemote(
|
fun Order.toOrderRemote(): OrderRemote = OrderRemote(
|
||||||
uid, userId!!, dateTime, sessions = emptyList()
|
uid, userId, dateTime, sessions = emptyList()
|
||||||
)
|
)
|
@ -7,9 +7,14 @@ import androidx.paging.RemoteMediator
|
|||||||
import androidx.room.withTransaction
|
import androidx.room.withTransaction
|
||||||
import com.example.myapplication.LiveStore
|
import com.example.myapplication.LiveStore
|
||||||
import com.example.myapplication.api.MyServerService
|
import com.example.myapplication.api.MyServerService
|
||||||
|
import com.example.myapplication.api.user.toUser
|
||||||
import com.example.myapplication.database.AppDatabase
|
import com.example.myapplication.database.AppDatabase
|
||||||
import com.example.myapplication.database.entities.model.Order
|
import com.example.myapplication.database.entities.model.Order
|
||||||
|
import com.example.myapplication.database.entities.model.OrderWithUser
|
||||||
|
import com.example.myapplication.database.entities.model.User
|
||||||
|
import com.example.myapplication.database.entities.model.UserRole
|
||||||
import com.example.myapplication.database.entities.repository.OfflineOrderRepository
|
import com.example.myapplication.database.entities.repository.OfflineOrderRepository
|
||||||
|
import com.example.myapplication.database.entities.repository.OfflineUserRepository
|
||||||
import com.example.myapplication.database.remotekeys.model.RemoteKeyType
|
import com.example.myapplication.database.remotekeys.model.RemoteKeyType
|
||||||
import com.example.myapplication.database.remotekeys.model.RemoteKeys
|
import com.example.myapplication.database.remotekeys.model.RemoteKeys
|
||||||
import com.example.myapplication.database.remotekeys.repository.OfflineRemoteKeyRepository
|
import com.example.myapplication.database.remotekeys.repository.OfflineRemoteKeyRepository
|
||||||
@ -20,9 +25,10 @@ import java.io.IOException
|
|||||||
class OrderRemoteMediator(
|
class OrderRemoteMediator(
|
||||||
private val service: MyServerService,
|
private val service: MyServerService,
|
||||||
private val dbOrderRepository: OfflineOrderRepository,
|
private val dbOrderRepository: OfflineOrderRepository,
|
||||||
|
private val dbUserRepository: OfflineUserRepository,
|
||||||
private val dbRemoteKeyRepository: OfflineRemoteKeyRepository,
|
private val dbRemoteKeyRepository: OfflineRemoteKeyRepository,
|
||||||
private val database: AppDatabase
|
private val database: AppDatabase
|
||||||
) : RemoteMediator<Int, Order>() {
|
) : RemoteMediator<Int, OrderWithUser>() {
|
||||||
|
|
||||||
override suspend fun initialize(): InitializeAction {
|
override suspend fun initialize(): InitializeAction {
|
||||||
return InitializeAction.LAUNCH_INITIAL_REFRESH
|
return InitializeAction.LAUNCH_INITIAL_REFRESH
|
||||||
@ -30,7 +36,7 @@ class OrderRemoteMediator(
|
|||||||
|
|
||||||
override suspend fun load(
|
override suspend fun load(
|
||||||
loadType: LoadType,
|
loadType: LoadType,
|
||||||
state: PagingState<Int, Order>
|
state: PagingState<Int, OrderWithUser>
|
||||||
): MediatorResult {
|
): MediatorResult {
|
||||||
val page = when (loadType) {
|
val page = when (loadType) {
|
||||||
LoadType.REFRESH -> {
|
LoadType.REFRESH -> {
|
||||||
@ -52,14 +58,23 @@ class OrderRemoteMediator(
|
|||||||
}
|
}
|
||||||
|
|
||||||
try {
|
try {
|
||||||
val orders = service.getOrders(
|
val user = LiveStore.user
|
||||||
userId = LiveStore.user.value?.uid ?: 0,
|
var users: List<User> = emptyList()
|
||||||
page = page, limit = state.config.pageSize
|
val orders: List<Order> = if (user.value?.role == UserRole.ADMIN) {
|
||||||
).map { it.toOrder() }
|
val temp = service.getOrders(page = page, limit = state.config.pageSize)
|
||||||
|
users = temp.map { it.user.toUser() }
|
||||||
|
temp.map { it.toOrder() }
|
||||||
|
} else {
|
||||||
|
service.getOrders(
|
||||||
|
userId = user.value?.uid ?: 0, page = page, limit = state.config.pageSize
|
||||||
|
).map { it.toOrder() }
|
||||||
|
}
|
||||||
|
|
||||||
val endOfPaginationReached = orders.isEmpty()
|
val endOfPaginationReached = orders.isEmpty()
|
||||||
database.withTransaction {
|
database.withTransaction {
|
||||||
if (loadType == LoadType.REFRESH) {
|
if (loadType == LoadType.REFRESH) {
|
||||||
dbRemoteKeyRepository.deleteRemoteKey(RemoteKeyType.ORDER)
|
dbRemoteKeyRepository.deleteRemoteKey(RemoteKeyType.ORDER)
|
||||||
|
dbUserRepository.clearUsers()
|
||||||
dbOrderRepository.clearOrders()
|
dbOrderRepository.clearOrders()
|
||||||
}
|
}
|
||||||
val prevKey = if (page == 1) null else page - 1
|
val prevKey = if (page == 1) null else page - 1
|
||||||
@ -74,6 +89,7 @@ class OrderRemoteMediator(
|
|||||||
}
|
}
|
||||||
dbRemoteKeyRepository.createRemoteKeys(keys)
|
dbRemoteKeyRepository.createRemoteKeys(keys)
|
||||||
dbOrderRepository.insertOrders(orders)
|
dbOrderRepository.insertOrders(orders)
|
||||||
|
dbUserRepository.insertUsers(users)
|
||||||
}
|
}
|
||||||
return MediatorResult.Success(endOfPaginationReached = endOfPaginationReached)
|
return MediatorResult.Success(endOfPaginationReached = endOfPaginationReached)
|
||||||
} catch (exception: IOException) {
|
} catch (exception: IOException) {
|
||||||
@ -83,14 +99,14 @@ class OrderRemoteMediator(
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private suspend fun getRemoteKeyForLastItem(state: PagingState<Int, Order>): RemoteKeys? {
|
private suspend fun getRemoteKeyForLastItem(state: PagingState<Int, OrderWithUser>): RemoteKeys? {
|
||||||
return state.pages.lastOrNull { it.data.isNotEmpty() }?.data?.lastOrNull()
|
return state.pages.lastOrNull { it.data.isNotEmpty() }?.data?.lastOrNull()
|
||||||
?.let { order ->
|
?.let { order ->
|
||||||
dbRemoteKeyRepository.getAllRemoteKeys(order.uid, RemoteKeyType.ORDER)
|
dbRemoteKeyRepository.getAllRemoteKeys(order.uid, RemoteKeyType.ORDER)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private suspend fun getRemoteKeyForFirstItem(state: PagingState<Int, Order>): RemoteKeys? {
|
private suspend fun getRemoteKeyForFirstItem(state: PagingState<Int, OrderWithUser>): RemoteKeys? {
|
||||||
return state.pages.firstOrNull { it.data.isNotEmpty() }?.data?.firstOrNull()
|
return state.pages.firstOrNull { it.data.isNotEmpty() }?.data?.firstOrNull()
|
||||||
?.let { order ->
|
?.let { order ->
|
||||||
dbRemoteKeyRepository.getAllRemoteKeys(order.uid, RemoteKeyType.ORDER)
|
dbRemoteKeyRepository.getAllRemoteKeys(order.uid, RemoteKeyType.ORDER)
|
||||||
@ -98,7 +114,7 @@ class OrderRemoteMediator(
|
|||||||
}
|
}
|
||||||
|
|
||||||
private suspend fun getRemoteKeyClosestToCurrentPosition(
|
private suspend fun getRemoteKeyClosestToCurrentPosition(
|
||||||
state: PagingState<Int, Order>
|
state: PagingState<Int, OrderWithUser>
|
||||||
): RemoteKeys? {
|
): RemoteKeys? {
|
||||||
return state.anchorPosition?.let { position ->
|
return state.anchorPosition?.let { position ->
|
||||||
state.closestItemToPosition(position)?.uid?.let { orderUid ->
|
state.closestItemToPosition(position)?.uid?.let { orderUid ->
|
||||||
|
@ -0,0 +1,22 @@
|
|||||||
|
package com.example.myapplication.api.order
|
||||||
|
|
||||||
|
import com.example.myapplication.api.session.SessionFromOrderRemote
|
||||||
|
import com.example.myapplication.api.user.UserRemote
|
||||||
|
import com.example.myapplication.database.entities.model.Order
|
||||||
|
import kotlinx.serialization.Contextual
|
||||||
|
import kotlinx.serialization.Serializable
|
||||||
|
import org.threeten.bp.LocalDateTime
|
||||||
|
|
||||||
|
@Serializable
|
||||||
|
data class OrderWithUserRemote(
|
||||||
|
val id: Int = 0,
|
||||||
|
val userId: Int = 0,
|
||||||
|
val user: UserRemote,
|
||||||
|
@Contextual
|
||||||
|
val dateTime: LocalDateTime = LocalDateTime.now(),
|
||||||
|
var sessions: List<SessionFromOrderRemote> = emptyList()
|
||||||
|
)
|
||||||
|
|
||||||
|
fun OrderWithUserRemote.toOrder(): Order = Order(
|
||||||
|
id, userId, dateTime
|
||||||
|
)
|
@ -10,9 +10,11 @@ import com.example.myapplication.database.AppContainer
|
|||||||
import com.example.myapplication.database.AppDatabase
|
import com.example.myapplication.database.AppDatabase
|
||||||
import com.example.myapplication.database.entities.model.Order
|
import com.example.myapplication.database.entities.model.Order
|
||||||
import com.example.myapplication.database.entities.model.OrderSessionCrossRef
|
import com.example.myapplication.database.entities.model.OrderSessionCrossRef
|
||||||
|
import com.example.myapplication.database.entities.model.OrderWithUser
|
||||||
import com.example.myapplication.database.entities.model.SessionFromOrder
|
import com.example.myapplication.database.entities.model.SessionFromOrder
|
||||||
import com.example.myapplication.database.entities.repository.OfflineOrderRepository
|
import com.example.myapplication.database.entities.repository.OfflineOrderRepository
|
||||||
import com.example.myapplication.database.entities.repository.OfflineOrderSessionRepository
|
import com.example.myapplication.database.entities.repository.OfflineOrderSessionRepository
|
||||||
|
import com.example.myapplication.database.entities.repository.OfflineUserRepository
|
||||||
import com.example.myapplication.database.entities.repository.OrderRepository
|
import com.example.myapplication.database.entities.repository.OrderRepository
|
||||||
import com.example.myapplication.database.remotekeys.repository.OfflineRemoteKeyRepository
|
import com.example.myapplication.database.remotekeys.repository.OfflineRemoteKeyRepository
|
||||||
import kotlinx.coroutines.flow.Flow
|
import kotlinx.coroutines.flow.Flow
|
||||||
@ -20,11 +22,12 @@ import kotlinx.coroutines.flow.Flow
|
|||||||
class RestOrderRepository(
|
class RestOrderRepository(
|
||||||
private val service: MyServerService,
|
private val service: MyServerService,
|
||||||
private val dbOrderRepository: OfflineOrderRepository,
|
private val dbOrderRepository: OfflineOrderRepository,
|
||||||
|
private val dbUserRepository: OfflineUserRepository,
|
||||||
private val dbOrderSessionRepository: OfflineOrderSessionRepository,
|
private val dbOrderSessionRepository: OfflineOrderSessionRepository,
|
||||||
private val dbRemoteKeyRepository: OfflineRemoteKeyRepository,
|
private val dbRemoteKeyRepository: OfflineRemoteKeyRepository,
|
||||||
private val database: AppDatabase
|
private val database: AppDatabase
|
||||||
) : OrderRepository {
|
) : OrderRepository {
|
||||||
override fun getAllOrders(): Flow<PagingData<Order>> {
|
override fun getAllOrders(): Flow<PagingData<OrderWithUser>> {
|
||||||
val pagingSourceFactory = { dbOrderRepository.getAllOrdersPagingSource() }
|
val pagingSourceFactory = { dbOrderRepository.getAllOrdersPagingSource() }
|
||||||
@OptIn(ExperimentalPagingApi::class)
|
@OptIn(ExperimentalPagingApi::class)
|
||||||
return Pager(
|
return Pager(
|
||||||
@ -35,6 +38,7 @@ class RestOrderRepository(
|
|||||||
remoteMediator = OrderRemoteMediator(
|
remoteMediator = OrderRemoteMediator(
|
||||||
service,
|
service,
|
||||||
dbOrderRepository,
|
dbOrderRepository,
|
||||||
|
dbUserRepository,
|
||||||
dbRemoteKeyRepository,
|
dbRemoteKeyRepository,
|
||||||
database,
|
database,
|
||||||
),
|
),
|
||||||
|
@ -40,11 +40,6 @@ class RestSessionRepository(
|
|||||||
service.deleteUserSession(userSessionRemote.id)
|
service.deleteUserSession(userSessionRemote.id)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
val orders = service.getOrders()
|
|
||||||
orders.forEach { orderRemote ->
|
|
||||||
orderRemote.sessions = orderRemote.sessions.filter { x -> x.id != session.uid }
|
|
||||||
service.updateOrder(orderRemote.id, orderRemote)
|
|
||||||
}
|
|
||||||
service.deleteSession(session.uid)
|
service.deleteSession(session.uid)
|
||||||
dbUserSessionRepository.deleteSessionsByUid(session.uid)
|
dbUserSessionRepository.deleteSessionsByUid(session.uid)
|
||||||
dbOrderSessionRepository.deleteSessionsByUid(session.uid)
|
dbOrderSessionRepository.deleteSessionsByUid(session.uid)
|
||||||
|
@ -80,6 +80,7 @@ class AppDataContainer(private val context: Context) : AppContainer {
|
|||||||
RestOrderRepository(
|
RestOrderRepository(
|
||||||
MyServerService.getInstance(),
|
MyServerService.getInstance(),
|
||||||
orderRepository,
|
orderRepository,
|
||||||
|
userRepository,
|
||||||
orderSessionRepository,
|
orderSessionRepository,
|
||||||
remoteKeyRepository,
|
remoteKeyRepository,
|
||||||
AppDatabase.getInstance(context)
|
AppDatabase.getInstance(context)
|
||||||
|
@ -27,10 +27,6 @@ object AppViewModelProvider {
|
|||||||
CinemaViewModel(
|
CinemaViewModel(
|
||||||
this.createSavedStateHandle(),
|
this.createSavedStateHandle(),
|
||||||
cinemaApplication().container.cinemaRestRepository,
|
cinemaApplication().container.cinemaRestRepository,
|
||||||
)
|
|
||||||
}
|
|
||||||
initializer {
|
|
||||||
SessionListViewModel(
|
|
||||||
cinemaApplication().container.sessionRestRepository,
|
cinemaApplication().container.sessionRestRepository,
|
||||||
cinemaApplication().container.userSessionRestRepository,
|
cinemaApplication().container.userSessionRestRepository,
|
||||||
)
|
)
|
||||||
|
@ -4,12 +4,20 @@ import androidx.compose.runtime.getValue
|
|||||||
import androidx.compose.runtime.mutableStateOf
|
import androidx.compose.runtime.mutableStateOf
|
||||||
import androidx.compose.runtime.setValue
|
import androidx.compose.runtime.setValue
|
||||||
import androidx.lifecycle.SavedStateHandle
|
import androidx.lifecycle.SavedStateHandle
|
||||||
|
import com.example.myapplication.LiveStore
|
||||||
import com.example.myapplication.composeui.MyViewModel
|
import com.example.myapplication.composeui.MyViewModel
|
||||||
import com.example.myapplication.database.entities.model.CinemaWithSessions
|
import com.example.myapplication.database.entities.model.CinemaWithSessions
|
||||||
|
import com.example.myapplication.database.entities.model.Session
|
||||||
|
import com.example.myapplication.database.entities.model.SessionFromCinema
|
||||||
|
import com.example.myapplication.database.entities.model.UserSessionCrossRef
|
||||||
import com.example.myapplication.database.entities.repository.CinemaRepository
|
import com.example.myapplication.database.entities.repository.CinemaRepository
|
||||||
|
import com.example.myapplication.database.entities.repository.SessionRepository
|
||||||
|
import com.example.myapplication.database.entities.repository.UserSessionRepository
|
||||||
|
|
||||||
class CinemaViewModel(
|
class CinemaViewModel(
|
||||||
savedStateHandle: SavedStateHandle, private val cinemaRepository: CinemaRepository
|
savedStateHandle: SavedStateHandle, private val cinemaRepository: CinemaRepository,
|
||||||
|
private val sessionRepository: SessionRepository,
|
||||||
|
private val userSessionRepository: UserSessionRepository
|
||||||
) : MyViewModel() {
|
) : MyViewModel() {
|
||||||
private val cinemaUid: Int = checkNotNull(savedStateHandle["id"])
|
private val cinemaUid: Int = checkNotNull(savedStateHandle["id"])
|
||||||
|
|
||||||
@ -25,6 +33,34 @@ class CinemaViewModel(
|
|||||||
})
|
})
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
suspend fun deleteSession(session: SessionFromCinema) {
|
||||||
|
runInScope(actionSuccess = {
|
||||||
|
sessionRepository.deleteSession(
|
||||||
|
Session(
|
||||||
|
uid = session.uid,
|
||||||
|
dateTime = session.dateTime,
|
||||||
|
price = session.price,
|
||||||
|
maxCount = 0,
|
||||||
|
cinemaId = 0
|
||||||
|
)
|
||||||
|
)
|
||||||
|
refreshState()
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
suspend fun addSessionInCart(sessionId: Int, count: Int = 1) {
|
||||||
|
val userId: Int = LiveStore.user.value?.uid ?: return
|
||||||
|
runInScope(actionSuccess = {
|
||||||
|
userSessionRepository.insertUserSession(
|
||||||
|
UserSessionCrossRef(
|
||||||
|
userId,
|
||||||
|
sessionId,
|
||||||
|
count
|
||||||
|
)
|
||||||
|
)
|
||||||
|
}, actionError = {}, needLoadingScreen = false)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
data class CinemaUiState(val cinemaWithSessions: CinemaWithSessions? = null)
|
data class CinemaUiState(val cinemaWithSessions: CinemaWithSessions? = null)
|
@ -24,7 +24,9 @@ import androidx.navigation.NavController
|
|||||||
import androidx.paging.compose.collectAsLazyPagingItems
|
import androidx.paging.compose.collectAsLazyPagingItems
|
||||||
import androidx.paging.compose.itemContentType
|
import androidx.paging.compose.itemContentType
|
||||||
import androidx.paging.compose.itemKey
|
import androidx.paging.compose.itemKey
|
||||||
|
import com.example.myapplication.LiveStore
|
||||||
import com.example.myapplication.composeui.navigation.Screen
|
import com.example.myapplication.composeui.navigation.Screen
|
||||||
|
import com.example.myapplication.database.entities.model.UserRole
|
||||||
import com.example.myapplication.ui.theme.PmudemoTheme
|
import com.example.myapplication.ui.theme.PmudemoTheme
|
||||||
import org.threeten.bp.format.DateTimeFormatter
|
import org.threeten.bp.format.DateTimeFormatter
|
||||||
|
|
||||||
@ -66,10 +68,17 @@ fun OrderList(
|
|||||||
verticalAlignment = Alignment.CenterVertically,
|
verticalAlignment = Alignment.CenterVertically,
|
||||||
horizontalArrangement = Arrangement.spacedBy(8.dp)
|
horizontalArrangement = Arrangement.spacedBy(8.dp)
|
||||||
) {
|
) {
|
||||||
Text(
|
if (LiveStore.user.value?.role == UserRole.ADMIN)
|
||||||
"Заказ №${order.uid}, ${formattedDate}",
|
Text(
|
||||||
color = MaterialTheme.colorScheme.onSecondary
|
"Заказ №${order.uid}, ${formattedDate}\n" +
|
||||||
)
|
"Пользователь: ${order.user?.login ?: "Неизвестно"}",
|
||||||
|
color = MaterialTheme.colorScheme.onSecondary
|
||||||
|
)
|
||||||
|
else
|
||||||
|
Text(
|
||||||
|
"Заказ №${order.uid}, $formattedDate",
|
||||||
|
color = MaterialTheme.colorScheme.onSecondary
|
||||||
|
)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -3,11 +3,12 @@ package com.example.myapplication.database.entities.composeui
|
|||||||
import androidx.paging.PagingData
|
import androidx.paging.PagingData
|
||||||
import com.example.myapplication.composeui.MyViewModel
|
import com.example.myapplication.composeui.MyViewModel
|
||||||
import com.example.myapplication.database.entities.model.Order
|
import com.example.myapplication.database.entities.model.Order
|
||||||
|
import com.example.myapplication.database.entities.model.OrderWithUser
|
||||||
import com.example.myapplication.database.entities.repository.OrderRepository
|
import com.example.myapplication.database.entities.repository.OrderRepository
|
||||||
import kotlinx.coroutines.flow.Flow
|
import kotlinx.coroutines.flow.Flow
|
||||||
|
|
||||||
class OrderListViewModel(
|
class OrderListViewModel(
|
||||||
orderRepository: OrderRepository
|
orderRepository: OrderRepository
|
||||||
) : MyViewModel() {
|
) : MyViewModel() {
|
||||||
var orderListUiState: Flow<PagingData<Order>> = orderRepository.getAllOrders()
|
val orderListUiState: Flow<PagingData<OrderWithUser>> = orderRepository.getAllOrders()
|
||||||
}
|
}
|
@ -30,7 +30,6 @@ import androidx.compose.ui.graphics.asImageBitmap
|
|||||||
import androidx.compose.ui.res.stringResource
|
import androidx.compose.ui.res.stringResource
|
||||||
import androidx.compose.ui.text.style.TextAlign
|
import androidx.compose.ui.text.style.TextAlign
|
||||||
import androidx.compose.ui.unit.dp
|
import androidx.compose.ui.unit.dp
|
||||||
import androidx.lifecycle.viewmodel.compose.viewModel
|
|
||||||
import androidx.navigation.NavController
|
import androidx.navigation.NavController
|
||||||
import com.example.myapplication.LiveStore
|
import com.example.myapplication.LiveStore
|
||||||
import com.example.myapplication.R
|
import com.example.myapplication.R
|
||||||
@ -42,8 +41,7 @@ import org.threeten.bp.format.DateTimeFormatter
|
|||||||
@Composable
|
@Composable
|
||||||
fun SessionList(
|
fun SessionList(
|
||||||
cinemaWithSessionsViewModel: CinemaViewModel,
|
cinemaWithSessionsViewModel: CinemaViewModel,
|
||||||
navController: NavController,
|
navController: NavController
|
||||||
viewModel: SessionListViewModel = viewModel(factory = AppViewModelProvider.Factory)
|
|
||||||
) {
|
) {
|
||||||
val coroutineScope = rememberCoroutineScope()
|
val coroutineScope = rememberCoroutineScope()
|
||||||
val cinemaWithSessions = cinemaWithSessionsViewModel.cinemaUiState.cinemaWithSessions!!
|
val cinemaWithSessions = cinemaWithSessionsViewModel.cinemaUiState.cinemaWithSessions!!
|
||||||
@ -113,7 +111,7 @@ fun SessionList(
|
|||||||
IconButton(
|
IconButton(
|
||||||
onClick = {
|
onClick = {
|
||||||
coroutineScope.launch {
|
coroutineScope.launch {
|
||||||
viewModel.addSessionInCart(sessionId = session.uid)
|
cinemaWithSessionsViewModel.addSessionInCart(sessionId = session.uid)
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
) {
|
) {
|
||||||
@ -129,8 +127,7 @@ fun SessionList(
|
|||||||
IconButton(
|
IconButton(
|
||||||
onClick = {
|
onClick = {
|
||||||
coroutineScope.launch {
|
coroutineScope.launch {
|
||||||
viewModel.deleteSession(session = session)
|
cinemaWithSessionsViewModel.deleteSession(session = session)
|
||||||
cinemaWithSessionsViewModel.refreshState()
|
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
) {
|
) {
|
||||||
|
@ -1,41 +0,0 @@
|
|||||||
package com.example.myapplication.database.entities.composeui
|
|
||||||
|
|
||||||
import com.example.myapplication.LiveStore
|
|
||||||
import com.example.myapplication.composeui.MyViewModel
|
|
||||||
import com.example.myapplication.database.entities.model.Session
|
|
||||||
import com.example.myapplication.database.entities.model.SessionFromCinema
|
|
||||||
import com.example.myapplication.database.entities.model.UserSessionCrossRef
|
|
||||||
import com.example.myapplication.database.entities.repository.SessionRepository
|
|
||||||
import com.example.myapplication.database.entities.repository.UserSessionRepository
|
|
||||||
|
|
||||||
class SessionListViewModel(
|
|
||||||
private val sessionRepository: SessionRepository,
|
|
||||||
private val userSessionRepository: UserSessionRepository
|
|
||||||
) : MyViewModel() {
|
|
||||||
suspend fun deleteSession(session: SessionFromCinema) {
|
|
||||||
runInScope(actionSuccess = {
|
|
||||||
sessionRepository.deleteSession(
|
|
||||||
Session(
|
|
||||||
uid = session.uid,
|
|
||||||
dateTime = session.dateTime,
|
|
||||||
price = session.price,
|
|
||||||
maxCount = 0,
|
|
||||||
cinemaId = 0
|
|
||||||
)
|
|
||||||
)
|
|
||||||
})
|
|
||||||
}
|
|
||||||
|
|
||||||
suspend fun addSessionInCart(sessionId: Int, count: Int = 1) {
|
|
||||||
val userId: Int = LiveStore.user.value?.uid ?: return
|
|
||||||
runInScope(actionSuccess = {
|
|
||||||
userSessionRepository.insertUserSession(
|
|
||||||
UserSessionCrossRef(
|
|
||||||
userId,
|
|
||||||
sessionId,
|
|
||||||
count
|
|
||||||
)
|
|
||||||
)
|
|
||||||
})
|
|
||||||
}
|
|
||||||
}
|
|
@ -35,6 +35,7 @@ class UserProfileViewModel(
|
|||||||
if (overlap == null || userUiState.details.password != overlap.password) {
|
if (overlap == null || userUiState.details.password != overlap.password) {
|
||||||
errorId = R.string.err_04
|
errorId = R.string.err_04
|
||||||
} else {
|
} else {
|
||||||
|
dataStoreManager.setLogin("")
|
||||||
dataStoreManager.setLogin(userUiState.details.login)
|
dataStoreManager.setLogin(userUiState.details.login)
|
||||||
Log.d("UserProfileViewModel", "sign in success")
|
Log.d("UserProfileViewModel", "sign in success")
|
||||||
}
|
}
|
||||||
|
@ -8,12 +8,17 @@ import androidx.room.OnConflictStrategy
|
|||||||
import androidx.room.Query
|
import androidx.room.Query
|
||||||
import androidx.room.Update
|
import androidx.room.Update
|
||||||
import com.example.myapplication.database.entities.model.Order
|
import com.example.myapplication.database.entities.model.Order
|
||||||
|
import com.example.myapplication.database.entities.model.OrderWithUser
|
||||||
import com.example.myapplication.database.entities.model.SessionFromOrder
|
import com.example.myapplication.database.entities.model.SessionFromOrder
|
||||||
|
|
||||||
@Dao
|
@Dao
|
||||||
interface OrderDao {
|
interface OrderDao {
|
||||||
@Query("select * from orders where user_id = :userId")
|
@Query("select * from orders where user_id = :userId")
|
||||||
fun getAll(userId: Int?): PagingSource<Int, Order>
|
fun getAll(userId: Int?): PagingSource<Int, OrderWithUser>
|
||||||
|
|
||||||
|
@Query("select * from orders " +
|
||||||
|
"left join users on orders.user_id = users.uid")
|
||||||
|
fun getAll(): PagingSource<Int, OrderWithUser>
|
||||||
|
|
||||||
@Query(
|
@Query(
|
||||||
"SELECT o.*, s.*, os.count, os.frozen_price " +
|
"SELECT o.*, s.*, os.count, os.frozen_price " +
|
||||||
|
@ -12,7 +12,7 @@ data class Order(
|
|||||||
@PrimaryKey(autoGenerate = true)
|
@PrimaryKey(autoGenerate = true)
|
||||||
val uid: Int,
|
val uid: Int,
|
||||||
@ColumnInfo(name = "user_id", index = true)
|
@ColumnInfo(name = "user_id", index = true)
|
||||||
val userId: Int?,
|
val userId: Int = 0,
|
||||||
@ColumnInfo(name = "date_time")
|
@ColumnInfo(name = "date_time")
|
||||||
val dateTime: LocalDateTime,
|
val dateTime: LocalDateTime,
|
||||||
) {
|
) {
|
||||||
|
@ -0,0 +1,18 @@
|
|||||||
|
package com.example.myapplication.database.entities.model
|
||||||
|
|
||||||
|
import androidx.room.ColumnInfo
|
||||||
|
import androidx.room.Relation
|
||||||
|
import org.threeten.bp.LocalDateTime
|
||||||
|
|
||||||
|
data class OrderWithUser(
|
||||||
|
val uid: Int,
|
||||||
|
@ColumnInfo(name = "user_id", index = true)
|
||||||
|
val userId: Int = 0,
|
||||||
|
@ColumnInfo(name = "date_time")
|
||||||
|
val dateTime: LocalDateTime,
|
||||||
|
@Relation(
|
||||||
|
parentColumn = "user_id",
|
||||||
|
entity = User::class,
|
||||||
|
entityColumn = "uid"
|
||||||
|
) val user: User?
|
||||||
|
)
|
@ -8,24 +8,29 @@ import com.example.myapplication.LiveStore
|
|||||||
import com.example.myapplication.database.AppContainer
|
import com.example.myapplication.database.AppContainer
|
||||||
import com.example.myapplication.database.entities.dao.OrderDao
|
import com.example.myapplication.database.entities.dao.OrderDao
|
||||||
import com.example.myapplication.database.entities.model.Order
|
import com.example.myapplication.database.entities.model.Order
|
||||||
|
import com.example.myapplication.database.entities.model.OrderWithUser
|
||||||
import com.example.myapplication.database.entities.model.SessionFromOrder
|
import com.example.myapplication.database.entities.model.SessionFromOrder
|
||||||
|
import com.example.myapplication.database.entities.model.UserRole
|
||||||
import kotlinx.coroutines.flow.Flow
|
import kotlinx.coroutines.flow.Flow
|
||||||
|
|
||||||
class OfflineOrderRepository(private val orderDao: OrderDao) : OrderRepository {
|
class OfflineOrderRepository(private val orderDao: OrderDao) : OrderRepository {
|
||||||
override fun getAllOrders(): Flow<PagingData<Order>> = Pager(
|
override fun getAllOrders(): Flow<PagingData<OrderWithUser>> = Pager(
|
||||||
config = PagingConfig(
|
config = PagingConfig(
|
||||||
pageSize = AppContainer.LIMIT,
|
pageSize = AppContainer.LIMIT,
|
||||||
enablePlaceholders = false
|
enablePlaceholders = false
|
||||||
),
|
),
|
||||||
pagingSourceFactory = { orderDao.getAll(LiveStore.user.value?.uid ?: 0) }
|
pagingSourceFactory = { getAllOrdersPagingSource() }
|
||||||
).flow
|
).flow
|
||||||
|
|
||||||
override suspend fun getOrder(uid: Int): List<SessionFromOrder> = orderDao.getByUid(uid)
|
override suspend fun getOrder(uid: Int): List<SessionFromOrder> = orderDao.getByUid(uid)
|
||||||
|
|
||||||
override suspend fun insertOrder(order: Order): Long = orderDao.insert(order).first()
|
override suspend fun insertOrder(order: Order): Long = orderDao.insert(order).first()
|
||||||
|
|
||||||
fun getAllOrdersPagingSource(): PagingSource<Int, Order> {
|
fun getAllOrdersPagingSource(): PagingSource<Int, OrderWithUser> {
|
||||||
return orderDao.getAll(LiveStore.user.value?.uid ?: 0)
|
val user = LiveStore.user.value
|
||||||
|
if (user?.role == UserRole.ADMIN)
|
||||||
|
return orderDao.getAll()
|
||||||
|
return orderDao.getAll(user?.uid ?: 0)
|
||||||
}
|
}
|
||||||
|
|
||||||
suspend fun clearOrders() = orderDao.deleteAll()
|
suspend fun clearOrders() = orderDao.deleteAll()
|
||||||
|
@ -2,11 +2,12 @@ package com.example.myapplication.database.entities.repository
|
|||||||
|
|
||||||
import androidx.paging.PagingData
|
import androidx.paging.PagingData
|
||||||
import com.example.myapplication.database.entities.model.Order
|
import com.example.myapplication.database.entities.model.Order
|
||||||
|
import com.example.myapplication.database.entities.model.OrderWithUser
|
||||||
import com.example.myapplication.database.entities.model.SessionFromOrder
|
import com.example.myapplication.database.entities.model.SessionFromOrder
|
||||||
import kotlinx.coroutines.flow.Flow
|
import kotlinx.coroutines.flow.Flow
|
||||||
|
|
||||||
interface OrderRepository {
|
interface OrderRepository {
|
||||||
fun getAllOrders(): Flow<PagingData<Order>>
|
fun getAllOrders(): Flow<PagingData<OrderWithUser>>
|
||||||
suspend fun getOrder(uid: Int): List<SessionFromOrder>
|
suspend fun getOrder(uid: Int): List<SessionFromOrder>
|
||||||
suspend fun insertOrder(order: Order): Long
|
suspend fun insertOrder(order: Order): Long
|
||||||
}
|
}
|
@ -6,12 +6,10 @@ import androidx.room.TypeConverter
|
|||||||
import androidx.room.TypeConverters
|
import androidx.room.TypeConverters
|
||||||
import com.example.myapplication.database.entities.model.Cinema
|
import com.example.myapplication.database.entities.model.Cinema
|
||||||
import com.example.myapplication.database.entities.model.Order
|
import com.example.myapplication.database.entities.model.Order
|
||||||
import com.example.myapplication.database.entities.model.Session
|
|
||||||
|
|
||||||
enum class RemoteKeyType(private val type: String) {
|
enum class RemoteKeyType(private val type: String) {
|
||||||
CINEMA(Cinema::class.simpleName ?: "Cinema"),
|
CINEMA(Cinema::class.simpleName ?: "Cinema"),
|
||||||
ORDER(Order::class.simpleName ?: "Order"),
|
ORDER(Order::class.simpleName ?: "Order");
|
||||||
SESSION(Session::class.simpleName ?: "Session");
|
|
||||||
|
|
||||||
@TypeConverter
|
@TypeConverter
|
||||||
fun toRemoteKeyType(value: String) = RemoteKeyType.values().first { it.type == value }
|
fun toRemoteKeyType(value: String) = RemoteKeyType.values().first { it.type == value }
|
||||||
|
Loading…
Reference in New Issue
Block a user