Course work: fixes

This commit is contained in:
abazov73 2023-12-28 10:46:15 +04:00
parent 2eca8db087
commit 415bf3fbdb
15 changed files with 171 additions and 44 deletions

View File

@ -24,19 +24,19 @@ import java.util.concurrent.TimeUnit
interface MyServerService { interface MyServerService {
@GET("api/persons") @GET("api/persons")
suspend fun getPeople( suspend fun getPeople(
@Query("_page") page: Int, @Query("page") page: Int,
@Query("_limit") limit: Int, @Query("_limit") limit: Int,
): List<PersonRemote> ): List<PersonRemote>
@GET("api/performances") @GET("api/performances")
suspend fun getPerformances( suspend fun getPerformances(
@Query("_page") page: Int, @Query("page") page: Int,
@Query("_limit") limit: Int, @Query("_limit") limit: Int,
): List<PerformanceRemote> ): List<PerformanceRemote>
@GET("api/events") @GET("api/events")
suspend fun getEvents( suspend fun getEvents(
@Query("_page") page: Int, @Query("page") page: Int,
@Query("_limit") limit: Int, @Query("_limit") limit: Int,
): List<EventRemote> ): List<EventRemote>

View File

@ -73,8 +73,6 @@ class EventRemoteMediator(
nextKey = nextKey nextKey = nextKey
) )
} }
dbRemoteKeyRepository.deleteRemoteKey(RemoteKeyType.EVENT)
dbEventRepository.clearEvents()
performanceRestRepository.getAllPerformances() performanceRestRepository.getAllPerformances()
dbRemoteKeyRepository.createRemoteKeys(keys) dbRemoteKeyRepository.createRemoteKeys(keys)

View File

@ -18,6 +18,7 @@ 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 com.example.mobile_labs.database.remotekeys.repository.OfflineRemoteKeyRepository import com.example.mobile_labs.database.remotekeys.repository.OfflineRemoteKeyRepository
import kotlinx.coroutines.flow.Flow import kotlinx.coroutines.flow.Flow
import kotlinx.coroutines.flow.map
class RestEventRepository( class RestEventRepository(
private val service: MyServerService, private val service: MyServerService,

View File

@ -72,8 +72,6 @@ class PeopleRemoteMediator(
) )
} }
dbRemoteKeyRepository.deleteRemoteKey(RemoteKeyType.PERSON)
dbPersonRepository.clearPeople()
dbRemoteKeyRepository.createRemoteKeys(keys) dbRemoteKeyRepository.createRemoteKeys(keys)
dbPersonRepository.insertPeople(people) dbPersonRepository.insertPeople(people)
} }

View File

@ -75,8 +75,6 @@ class PerformanceRemoteMediator(
nextKey = nextKey nextKey = nextKey
) )
} }
dbRemoteKeyRepository.deleteRemoteKey(RemoteKeyType.PERFORMANCE)
dbPerformanceRepository.clearPerformances()
personRestRepository.getAllPeople() personRestRepository.getAllPeople()
dbRemoteKeyRepository.createRemoteKeys(keys) dbRemoteKeyRepository.createRemoteKeys(keys)

View File

@ -12,6 +12,7 @@ import com.example.mobile_labs.ui.performance.list.AdminPerformanceListViewModel
import com.example.mobile_labs.ui.performance.list.PerformanceListViewModel import com.example.mobile_labs.ui.performance.list.PerformanceListViewModel
import com.example.mobile_labs.ui.performance.view.AdminPerformanceViewModel import com.example.mobile_labs.ui.performance.view.AdminPerformanceViewModel
import com.example.mobile_labs.ui.performance.view.PerformanceViewModel import com.example.mobile_labs.ui.performance.view.PerformanceViewModel
import com.example.mobile_labs.ui.performance.view.PersonDropDownViewModel
import com.example.mobile_labs.ui.person.list.PeopleListViewModel import com.example.mobile_labs.ui.person.list.PeopleListViewModel
object AppViewModelProvider { object AppViewModelProvider {
@ -37,6 +38,9 @@ object AppViewModelProvider {
initializer { initializer {
AdminPerformanceViewModel(this.createSavedStateHandle(), theatreApplication().container.performanceRestRepository) AdminPerformanceViewModel(this.createSavedStateHandle(), theatreApplication().container.performanceRestRepository)
} }
initializer {
PersonDropDownViewModel(theatreApplication().container.personRestRepository)
}
} }
} }

View File

@ -18,9 +18,8 @@ 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 collate nocase asc") @Query("select * from events")
fun getAllWithPerformance(dateFrom: String? = LocalDate.now().format( fun getAllWithPerformance(): PagingSource<Int, EventWithPerformance>
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,6 +1,7 @@
package com.example.mobile_labs.ui.event.list package com.example.mobile_labs.ui.event.list
import android.content.res.Configuration import android.content.res.Configuration
import android.util.Log
import androidx.compose.foundation.layout.Column import androidx.compose.foundation.layout.Column
import androidx.compose.foundation.layout.fillMaxWidth import androidx.compose.foundation.layout.fillMaxWidth
import androidx.compose.foundation.layout.padding import androidx.compose.foundation.layout.padding
@ -63,6 +64,7 @@ private fun EventList(
eventList: LazyPagingItems<EventWithPerformance>, eventList: LazyPagingItems<EventWithPerformance>,
onClick: (uid: Int) -> Unit onClick: (uid: Int) -> Unit
) { ) {
Log.d("events", eventList.itemCount.toString())
Column( Column(
modifier = modifier modifier = modifier
) { ) {
@ -100,7 +102,8 @@ private fun EventListItem(
elevation = CardDefaults.cardElevation(defaultElevation = 2.dp) elevation = CardDefaults.cardElevation(defaultElevation = 2.dp)
) { ) {
Column( Column(
modifier = modifier.padding(all = 10.dp) modifier = modifier.padding(all = 10.dp),
horizontalAlignment = Alignment.CenterHorizontally,
) { ) {
Text( Text(
text = event.event.date.format(DateTimeFormatter.ofPattern("dd.MM")) text = event.event.date.format(DateTimeFormatter.ofPattern("dd.MM"))

View File

@ -1,7 +1,6 @@
package com.example.mobile_labs.ui.performance.list package com.example.mobile_labs.ui.performance.list
import android.content.res.Configuration import android.content.res.Configuration
import android.util.Log
import androidx.compose.animation.AnimatedVisibility import androidx.compose.animation.AnimatedVisibility
import androidx.compose.animation.core.spring import androidx.compose.animation.core.spring
import androidx.compose.animation.fadeOut import androidx.compose.animation.fadeOut
@ -56,7 +55,6 @@ import androidx.paging.compose.itemContentType
import androidx.paging.compose.itemKey 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.api.MyServerService
import com.example.mobile_labs.database.performance.model.Performance import com.example.mobile_labs.database.performance.model.Performance
import com.example.mobile_labs.common.AppViewModelProvider import com.example.mobile_labs.common.AppViewModelProvider
import com.example.mobile_labs.ui.navigation.Screen import com.example.mobile_labs.ui.navigation.Screen
@ -96,7 +94,7 @@ fun AdminPerformanceList(
}, },
onSwipe = { performance: Performance -> onSwipe = { performance: Performance ->
coroutineScope.launch { coroutineScope.launch {
viewModel.deleteStudent(performance) viewModel.deletePerformance(performance)
} }
} }
) )
@ -224,10 +222,11 @@ private fun PerformanceListItem(
) { ) {
Card( Card(
modifier = modifier.fillMaxWidth(), modifier = modifier.fillMaxWidth(),
elevation = CardDefaults.cardElevation(defaultElevation = 2.dp) elevation = CardDefaults.cardElevation(defaultElevation = 2.dp),
) { ) {
Column( Column(
modifier = modifier.padding(all = 10.dp) modifier = modifier.padding(all = 10.dp),
horizontalAlignment = Alignment.CenterHorizontally
) { ) {
AsyncImage(model = performance.imageURL, contentDescription = "") AsyncImage(model = performance.imageURL, contentDescription = "")
Button( Button(

View File

@ -11,7 +11,7 @@ class AdminPerformanceListViewModel(
) : ViewModel() { ) : ViewModel() {
val performanceListUiState: Flow<PagingData<Performance>> = performanceRepository.getAllPerformances() val performanceListUiState: Flow<PagingData<Performance>> = performanceRepository.getAllPerformances()
suspend fun deleteStudent(performance: Performance) { suspend fun deletePerformance(performance: Performance) {
performanceRepository.deletePerformance(performance) performanceRepository.deletePerformance(performance)
} }
} }

View File

@ -101,7 +101,8 @@ private fun PerformanceListItem(
elevation = CardDefaults.cardElevation(defaultElevation = 2.dp) elevation = CardDefaults.cardElevation(defaultElevation = 2.dp)
) { ) {
Column( Column(
modifier = modifier.padding(all = 10.dp) modifier = modifier.padding(all = 10.dp),
horizontalAlignment = Alignment.CenterHorizontally
) { ) {
AsyncImage(model = performance.imageURL, contentDescription = "") AsyncImage(model = performance.imageURL, contentDescription = "")
Button( Button(

View File

@ -1,20 +1,31 @@
package com.example.mobile_labs.ui.performance.view package com.example.mobile_labs.ui.performance.view
import android.content.res.Configuration import android.content.res.Configuration
import androidx.compose.foundation.background
import androidx.compose.foundation.layout.Column import androidx.compose.foundation.layout.Column
import androidx.compose.foundation.layout.fillMaxWidth import androidx.compose.foundation.layout.fillMaxWidth
import androidx.compose.foundation.layout.padding import androidx.compose.foundation.layout.padding
import androidx.compose.foundation.text.KeyboardOptions import androidx.compose.foundation.text.KeyboardOptions
import androidx.compose.material3.Button import androidx.compose.material3.Button
import androidx.compose.material3.DropdownMenu
import androidx.compose.material3.DropdownMenuItem
import androidx.compose.material3.ExperimentalMaterial3Api import androidx.compose.material3.ExperimentalMaterial3Api
import androidx.compose.material3.ExposedDropdownMenuBox
import androidx.compose.material3.ExposedDropdownMenuDefaults
import androidx.compose.material3.MaterialTheme import androidx.compose.material3.MaterialTheme
import androidx.compose.material3.OutlinedTextField import androidx.compose.material3.OutlinedTextField
import androidx.compose.material3.Surface import androidx.compose.material3.Surface
import androidx.compose.material3.Text import androidx.compose.material3.Text
import androidx.compose.material3.TextField
import androidx.compose.runtime.Composable import androidx.compose.runtime.Composable
import androidx.compose.runtime.getValue
import androidx.compose.runtime.mutableStateOf
import androidx.compose.runtime.remember
import androidx.compose.runtime.rememberCoroutineScope import androidx.compose.runtime.rememberCoroutineScope
import androidx.compose.runtime.setValue
import androidx.compose.ui.Alignment import androidx.compose.ui.Alignment
import androidx.compose.ui.Modifier import androidx.compose.ui.Modifier
import androidx.compose.ui.graphics.Color
import androidx.compose.ui.res.stringResource import androidx.compose.ui.res.stringResource
import androidx.compose.ui.text.input.KeyboardType import androidx.compose.ui.text.input.KeyboardType
import androidx.compose.ui.text.style.TextAlign import androidx.compose.ui.text.style.TextAlign
@ -26,6 +37,7 @@ import androidx.navigation.NavController
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.common.AppViewModelProvider import com.example.mobile_labs.common.AppViewModelProvider
import com.example.mobile_labs.database.person.model.Person
import com.example.mobile_labs.ui.theme.Mobile_LabsTheme import com.example.mobile_labs.ui.theme.Mobile_LabsTheme
import kotlinx.coroutines.launch import kotlinx.coroutines.launch
@ -33,7 +45,9 @@ import kotlinx.coroutines.launch
@Composable @Composable
fun AdminPerformanceView( fun AdminPerformanceView(
navController: NavController, navController: NavController,
viewModel: AdminPerformanceViewModel = viewModel(factory = AppViewModelProvider.Factory) viewModel: AdminPerformanceViewModel = viewModel(factory = AppViewModelProvider.Factory),
authorViewModel: PersonDropDownViewModel = viewModel(factory = AppViewModelProvider.Factory),
directorViewModel: PersonDropDownViewModel = viewModel(factory = AppViewModelProvider.Factory),
) { ) {
val coroutineScope = rememberCoroutineScope() val coroutineScope = rememberCoroutineScope()
PerformanceEdit( PerformanceEdit(
@ -45,15 +59,77 @@ fun AdminPerformanceView(
} }
}, },
onUpdate = viewModel::updateUiState, onUpdate = viewModel::updateUiState,
onAuthorUpdate = authorViewModel::updateUiState,
onDirectorUpdate = directorViewModel::updateUiState,
authorUiState = authorViewModel.personUiState,
authorListUiState = authorViewModel.personListUiState,
directorUiState = directorViewModel.personUiState,
directorListUiState = directorViewModel.personListUiState,
) )
} }
@OptIn(ExperimentalMaterial3Api::class)
@Composable
private fun PersonDropDown(
personUiState: PersonUiState,
personsListUiState: PersonsListUiState,
onPersonUpdate: (Person) -> Unit
) {
var expanded: Boolean by remember { mutableStateOf(false) }
ExposedDropdownMenuBox(
modifier = Modifier
.padding(top = 7.dp),
expanded = expanded,
onExpandedChange = {
expanded = !expanded
}
) {
TextField(
value = personUiState.person?.last_name
?: stringResource(id = R.string.person_not_selected),
onValueChange = {},
readOnly = true,
trailingIcon = {
ExposedDropdownMenuDefaults.TrailingIcon(expanded = expanded)
},
modifier = Modifier
.fillMaxWidth()
.menuAnchor()
)
DropdownMenu(
expanded = expanded,
onDismissRequest = { expanded = false },
modifier = Modifier
.background(Color.White)
.exposedDropdownSize()
) {
personsListUiState.personList.forEach { person ->
DropdownMenuItem(
text = {
Text(text = person.last_name)
},
onClick = {
onPersonUpdate(person)
expanded = false
}
)
}
}
}
}
@OptIn(ExperimentalMaterial3Api::class) @OptIn(ExperimentalMaterial3Api::class)
@Composable @Composable
private fun PerformanceEdit( private fun PerformanceEdit(
performanceUiState: AdminPerformanceUiState, performanceUiState: AdminPerformanceUiState,
onClick: () -> Unit, onClick: () -> Unit,
onUpdate: (AdminPerformanceDetails) -> Unit, onUpdate: (AdminPerformanceDetails) -> Unit,
onAuthorUpdate: (Person) -> Unit,
onDirectorUpdate: (Person) -> Unit,
authorUiState: PersonUiState,
authorListUiState: PersonsListUiState,
directorUiState: PersonUiState,
directorListUiState: PersonsListUiState,
) { ) {
Column( Column(
Modifier Modifier
@ -88,21 +164,23 @@ private fun PerformanceEdit(
label = {Text("URL превью")}, label = {Text("URL превью")},
singleLine = true singleLine = true
) )
OutlinedTextField( Text(text = "Автор")
modifier = Modifier.fillMaxWidth(), PersonDropDown(
value = performanceUiState.performanceDetails.authorId.toString(), personUiState = authorUiState,
onValueChange = { onUpdate(performanceUiState.performanceDetails.copy(authorId = it.toInt())) }, personsListUiState = authorListUiState,
label = {Text("Автор")}, onPersonUpdate = {
singleLine = true, onUpdate(performanceUiState.performanceDetails.copy(authorId = it.uid !!))
keyboardOptions = KeyboardOptions(keyboardType = KeyboardType.Phone) onAuthorUpdate(it)
}
) )
OutlinedTextField( Text(text = "Режиссер")
modifier = Modifier.fillMaxWidth(), PersonDropDown(
value = performanceUiState.performanceDetails.directorId.toString(), personUiState = directorUiState,
onValueChange = { onUpdate(performanceUiState.performanceDetails.copy(directorId = it.toInt())) }, personsListUiState = directorListUiState,
label = {Text("Режиссер")}, onPersonUpdate = {
singleLine = true, onUpdate(performanceUiState.performanceDetails.copy(directorId = it.uid !!))
keyboardOptions = KeyboardOptions(keyboardType = KeyboardType.Phone) onDirectorUpdate(it)
}
) )
Button( Button(
onClick = onClick, onClick = onClick,

View File

@ -20,12 +20,12 @@ class PerformanceViewModel(
var performanceUiState by mutableStateOf(PerformanceUiState()) var performanceUiState by mutableStateOf(PerformanceUiState())
private set private set
private val studentUid: Int = checkNotNull(savedStateHandle["id"]) private val performanceUid: Int = checkNotNull(savedStateHandle["id"])
init { init {
viewModelScope.launch { viewModelScope.launch {
if (studentUid > 0) { if (performanceUid > 0) {
performanceUiState = performanceRepository.getPerformance(studentUid) performanceUiState = performanceRepository.getPerformance(performanceUid)
.toUiState() .toUiState()
} }
} }

View File

@ -0,0 +1,48 @@
package com.example.mobile_labs.ui.performance.view
import androidx.compose.runtime.getValue
import androidx.compose.runtime.mutableStateOf
import androidx.compose.runtime.setValue
import androidx.lifecycle.ViewModel
import androidx.lifecycle.viewModelScope
import com.example.mobile_labs.api.MyServerService
import com.example.mobile_labs.api.models.toPerson
import com.example.mobile_labs.common.PersonRepository
import com.example.mobile_labs.database.person.model.Person
import kotlinx.coroutines.launch
class PersonDropDownViewModel(
private val personRepository: PersonRepository
) : ViewModel() {
var personListUiState by mutableStateOf(PersonsListUiState())
private set
var personUiState by mutableStateOf(PersonUiState())
private set
init {
viewModelScope.launch {
personListUiState = PersonsListUiState(MyServerService.getInstance().getPeople(1, 10000000).map {it.toPerson()})
}
}
fun setCurrentPerson(personId: Int) {
val person: Person? =
personListUiState.personList.firstOrNull { person -> person.uid == personId }
person?.let { updateUiState(it) }
}
fun updateUiState(person: Person) {
personUiState = PersonUiState(
person = person
)
}
}
data class PersonsListUiState(val personList: List<Person> = listOf())
data class PersonUiState(
val person: Person? = null
)
fun Person.toUiState() = PersonUiState(person = Person(uid = uid, last_name = last_name, first_name = first_name, imageURL = imageURL))

View File

@ -13,14 +13,14 @@
<string name="people_missing_description">Данные о людях отсутствуют</string> <string name="people_missing_description">Данные о людях отсутствуют</string>
<string name="events_missing_description">Данные о событиях отсутствуют</string> <string name="events_missing_description">Данные о событиях отсутствуют</string>
<string name="performance_missing_description">Данные о представлениях отсутствуют</string> <string name="performance_missing_description">Данные о представлениях отсутствуют</string>
<string name="person_not_selected">...</string>
<string name="login">Логин</string> <string name="login">Логин</string>
<string name="password">Пароль</string> <string name="password">Пароль</string>
<string name="about_text"> <string name="about_text">
<p> <p>Добро пожаловать в театр "Лира"! Мы - креативная и страстная труппа артистов, цель которой - вдохновлять, развлекать и затрагивать сердца нашей аудитории через искусство театра. Наша миссия - оставаться в центре культурной жизни, предоставляя высококачественные и умопомрачительные спектакли, которые затрагивают самые глубокие струны души.</p>
Netus quis congue nascetur ullamcorper nibh, nostra iaculis turpis! Facilisi pretium vehicula purus porttitor vitae aliquet dignissim. Donec diam molestie litora magnis dolor aptent scelerisque mus. Sit mi, venenatis interdum. Commodo vel malesuada tincidunt eget. Aenean laoreet lacinia platea sem? Libero urna odio diam? Nisl, sodales nisi gravida. Interdum elementum libero turpis dapibus tristique per sed maecenas ante integer massa? Tortor molestie sapien himenaeos condimentum. Facilisis accumsan ullamcorper semper fermentum elementum quisque. Curae;, vivamus ante hac elit fringilla odio ornare curabitur quisque magna commodo. Placerat proin! <p>В театре "Лира" мы стремимся восхищать и захватывать зрителей разнообразными постановками, начиная от классических произведений и заканчивая современными экспериментальными шедеврами. Наша команда творческих профессионалов охватывает широкий спектр талантливых актеров, режиссеров, дизайнеров и технических специалистов, которые работают сообща, чтобы создать неповторимый театральный опыт.</p>
</p> <p>Мы верим в силу искусства и его способность изменять мир вокруг нас. Наша цель - не только представлять превосходные спектакли, но и стать платформой для обсуждения глубоких и важных вопросов, которые затрагивают каждого из нас. Мы призываем зрителей погрузиться в мир театральной магии и открыть для себя новые грани человеческого опыта</p>
<p> <p>Мы гордимся качеством нашей работы и постоянно стремимся к тому, чтобы каждый спектакль был для наших зрителей уникальным и захватывающим. Мы глубоко ценим вашу поддержку и рады поделиться с вами нашим творческим путешествием.</p>
Malesuada dui ultrices consequat felis morbi litora aenean hac. Vehicula justo vulputate ad nibh sociosqu a potenti ridiculus. Porta ligula mollis dolor. Imperdiet tincidunt tempus luctus luctus vehicula magnis malesuada. Augue convallis massa condimentum cum nunc platea cursus turpis turpis. Penatibus cras arcu nostra porta massa bibendum inceptos! Lacus sociis consectetur felis, potenti sit. Duis commodo nisl sem aliquet tellus integer ultricies curabitur felis tempor. Feugiat porttitor congue commodo eget, ornare ligula ullamcorper pulvinar enim nibh. Sodales in suscipit rhoncus mollis posuere sociosqu. <p><b>Наш адрес:</b> город Ульяновск, улица Спасская 12А</p>
</p>
</string> </string>
</resources> </resources>