From 415bf3fbdb8534b9a91e2c44ca9d3612657081b8 Mon Sep 17 00:00:00 2001 From: abazov73 <92822431+abazov73@users.noreply.github.com> Date: Thu, 28 Dec 2023 10:46:15 +0400 Subject: [PATCH] Course work: fixes --- .../mobile_labs/api/MyServerService.kt | 6 +- .../api/events/EventRemoteMediator.kt | 2 - .../api/events/RestEventRepository.kt | 1 + .../api/people/PeopleRemoteMediator.kt | 2 - .../performance/PerformanceRemoteMediator.kt | 2 - .../common/AppViewModelProvider.kt | 4 + .../database/event/dao/EventDao.kt | 5 +- .../mobile_labs/ui/event/list/EventList.kt | 5 +- .../performance/list/AdminPerformanceList.kt | 9 +- .../list/AdminPerformanceListViewModel.kt | 2 +- .../ui/performance/list/PerformanceList.kt | 3 +- .../performance/view/AdminPerformanceView.kt | 108 +++++++++++++++--- .../performance/view/PerformanceViewModel.kt | 6 +- .../view/PersonDropDownViewModel.kt | 48 ++++++++ app/src/main/res/values/strings.xml | 12 +- 15 files changed, 171 insertions(+), 44 deletions(-) create mode 100644 app/src/main/java/com/example/mobile_labs/ui/performance/view/PersonDropDownViewModel.kt diff --git a/app/src/main/java/com/example/mobile_labs/api/MyServerService.kt b/app/src/main/java/com/example/mobile_labs/api/MyServerService.kt index e2733d7..83cba46 100644 --- a/app/src/main/java/com/example/mobile_labs/api/MyServerService.kt +++ b/app/src/main/java/com/example/mobile_labs/api/MyServerService.kt @@ -24,19 +24,19 @@ import java.util.concurrent.TimeUnit interface MyServerService { @GET("api/persons") suspend fun getPeople( - @Query("_page") page: Int, + @Query("page") page: Int, @Query("_limit") limit: Int, ): List @GET("api/performances") suspend fun getPerformances( - @Query("_page") page: Int, + @Query("page") page: Int, @Query("_limit") limit: Int, ): List @GET("api/events") suspend fun getEvents( - @Query("_page") page: Int, + @Query("page") page: Int, @Query("_limit") limit: Int, ): List diff --git a/app/src/main/java/com/example/mobile_labs/api/events/EventRemoteMediator.kt b/app/src/main/java/com/example/mobile_labs/api/events/EventRemoteMediator.kt index 1f0e35c..4b495e9 100644 --- a/app/src/main/java/com/example/mobile_labs/api/events/EventRemoteMediator.kt +++ b/app/src/main/java/com/example/mobile_labs/api/events/EventRemoteMediator.kt @@ -73,8 +73,6 @@ class EventRemoteMediator( nextKey = nextKey ) } - dbRemoteKeyRepository.deleteRemoteKey(RemoteKeyType.EVENT) - dbEventRepository.clearEvents() performanceRestRepository.getAllPerformances() dbRemoteKeyRepository.createRemoteKeys(keys) diff --git a/app/src/main/java/com/example/mobile_labs/api/events/RestEventRepository.kt b/app/src/main/java/com/example/mobile_labs/api/events/RestEventRepository.kt index 9168cde..2570605 100644 --- a/app/src/main/java/com/example/mobile_labs/api/events/RestEventRepository.kt +++ b/app/src/main/java/com/example/mobile_labs/api/events/RestEventRepository.kt @@ -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.remotekeys.repository.OfflineRemoteKeyRepository import kotlinx.coroutines.flow.Flow +import kotlinx.coroutines.flow.map class RestEventRepository( private val service: MyServerService, diff --git a/app/src/main/java/com/example/mobile_labs/api/people/PeopleRemoteMediator.kt b/app/src/main/java/com/example/mobile_labs/api/people/PeopleRemoteMediator.kt index 65ffb8b..94d0c9c 100644 --- a/app/src/main/java/com/example/mobile_labs/api/people/PeopleRemoteMediator.kt +++ b/app/src/main/java/com/example/mobile_labs/api/people/PeopleRemoteMediator.kt @@ -72,8 +72,6 @@ class PeopleRemoteMediator( ) } - dbRemoteKeyRepository.deleteRemoteKey(RemoteKeyType.PERSON) - dbPersonRepository.clearPeople() dbRemoteKeyRepository.createRemoteKeys(keys) dbPersonRepository.insertPeople(people) } diff --git a/app/src/main/java/com/example/mobile_labs/api/performance/PerformanceRemoteMediator.kt b/app/src/main/java/com/example/mobile_labs/api/performance/PerformanceRemoteMediator.kt index 138db2b..49b7bb4 100644 --- a/app/src/main/java/com/example/mobile_labs/api/performance/PerformanceRemoteMediator.kt +++ b/app/src/main/java/com/example/mobile_labs/api/performance/PerformanceRemoteMediator.kt @@ -75,8 +75,6 @@ class PerformanceRemoteMediator( nextKey = nextKey ) } - dbRemoteKeyRepository.deleteRemoteKey(RemoteKeyType.PERFORMANCE) - dbPerformanceRepository.clearPerformances() personRestRepository.getAllPeople() dbRemoteKeyRepository.createRemoteKeys(keys) diff --git a/app/src/main/java/com/example/mobile_labs/common/AppViewModelProvider.kt b/app/src/main/java/com/example/mobile_labs/common/AppViewModelProvider.kt index 5015d1b..7547fab 100644 --- a/app/src/main/java/com/example/mobile_labs/common/AppViewModelProvider.kt +++ b/app/src/main/java/com/example/mobile_labs/common/AppViewModelProvider.kt @@ -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.view.AdminPerformanceViewModel 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 object AppViewModelProvider { @@ -37,6 +38,9 @@ object AppViewModelProvider { initializer { AdminPerformanceViewModel(this.createSavedStateHandle(), theatreApplication().container.performanceRestRepository) } + initializer { + PersonDropDownViewModel(theatreApplication().container.personRestRepository) + } } } diff --git a/app/src/main/java/com/example/mobile_labs/database/event/dao/EventDao.kt b/app/src/main/java/com/example/mobile_labs/database/event/dao/EventDao.kt index 31ee127..25ce9e7 100644 --- a/app/src/main/java/com/example/mobile_labs/database/event/dao/EventDao.kt +++ b/app/src/main/java/com/example/mobile_labs/database/event/dao/EventDao.kt @@ -18,9 +18,8 @@ interface EventDao { @Query("select * from events order by date asc") fun getAll(): Flow> - @Query("select * from events where events.date > :dateFrom order by date collate nocase asc") - fun getAllWithPerformance(dateFrom: String? = LocalDate.now().format( - DateTimeFormatter.ofPattern("dd.MM"))): PagingSource + @Query("select * from events") + fun getAllWithPerformance(): PagingSource @Query("select * from events where events.uid = :uid") fun getByUid(uid: Int): Flow diff --git a/app/src/main/java/com/example/mobile_labs/ui/event/list/EventList.kt b/app/src/main/java/com/example/mobile_labs/ui/event/list/EventList.kt index ccd3896..edc359c 100644 --- a/app/src/main/java/com/example/mobile_labs/ui/event/list/EventList.kt +++ b/app/src/main/java/com/example/mobile_labs/ui/event/list/EventList.kt @@ -1,6 +1,7 @@ package com.example.mobile_labs.ui.event.list import android.content.res.Configuration +import android.util.Log import androidx.compose.foundation.layout.Column import androidx.compose.foundation.layout.fillMaxWidth import androidx.compose.foundation.layout.padding @@ -63,6 +64,7 @@ private fun EventList( eventList: LazyPagingItems, onClick: (uid: Int) -> Unit ) { + Log.d("events", eventList.itemCount.toString()) Column( modifier = modifier ) { @@ -100,7 +102,8 @@ private fun EventListItem( elevation = CardDefaults.cardElevation(defaultElevation = 2.dp) ) { Column( - modifier = modifier.padding(all = 10.dp) + modifier = modifier.padding(all = 10.dp), + horizontalAlignment = Alignment.CenterHorizontally, ) { Text( text = event.event.date.format(DateTimeFormatter.ofPattern("dd.MM")) diff --git a/app/src/main/java/com/example/mobile_labs/ui/performance/list/AdminPerformanceList.kt b/app/src/main/java/com/example/mobile_labs/ui/performance/list/AdminPerformanceList.kt index af7fc9d..8ce4f04 100644 --- a/app/src/main/java/com/example/mobile_labs/ui/performance/list/AdminPerformanceList.kt +++ b/app/src/main/java/com/example/mobile_labs/ui/performance/list/AdminPerformanceList.kt @@ -1,7 +1,6 @@ package com.example.mobile_labs.ui.performance.list import android.content.res.Configuration -import android.util.Log import androidx.compose.animation.AnimatedVisibility import androidx.compose.animation.core.spring import androidx.compose.animation.fadeOut @@ -56,7 +55,6 @@ import androidx.paging.compose.itemContentType import androidx.paging.compose.itemKey import coil.compose.AsyncImage import com.example.mobile_labs.R -import com.example.mobile_labs.api.MyServerService import com.example.mobile_labs.database.performance.model.Performance import com.example.mobile_labs.common.AppViewModelProvider import com.example.mobile_labs.ui.navigation.Screen @@ -96,7 +94,7 @@ fun AdminPerformanceList( }, onSwipe = { performance: Performance -> coroutineScope.launch { - viewModel.deleteStudent(performance) + viewModel.deletePerformance(performance) } } ) @@ -224,10 +222,11 @@ private fun PerformanceListItem( ) { Card( modifier = modifier.fillMaxWidth(), - elevation = CardDefaults.cardElevation(defaultElevation = 2.dp) + elevation = CardDefaults.cardElevation(defaultElevation = 2.dp), ) { Column( - modifier = modifier.padding(all = 10.dp) + modifier = modifier.padding(all = 10.dp), + horizontalAlignment = Alignment.CenterHorizontally ) { AsyncImage(model = performance.imageURL, contentDescription = "") Button( diff --git a/app/src/main/java/com/example/mobile_labs/ui/performance/list/AdminPerformanceListViewModel.kt b/app/src/main/java/com/example/mobile_labs/ui/performance/list/AdminPerformanceListViewModel.kt index 67ac2a1..21b2c84 100644 --- a/app/src/main/java/com/example/mobile_labs/ui/performance/list/AdminPerformanceListViewModel.kt +++ b/app/src/main/java/com/example/mobile_labs/ui/performance/list/AdminPerformanceListViewModel.kt @@ -11,7 +11,7 @@ class AdminPerformanceListViewModel( ) : ViewModel() { val performanceListUiState: Flow> = performanceRepository.getAllPerformances() - suspend fun deleteStudent(performance: Performance) { + suspend fun deletePerformance(performance: Performance) { performanceRepository.deletePerformance(performance) } } \ No newline at end of file diff --git a/app/src/main/java/com/example/mobile_labs/ui/performance/list/PerformanceList.kt b/app/src/main/java/com/example/mobile_labs/ui/performance/list/PerformanceList.kt index 88e299f..efd8436 100644 --- a/app/src/main/java/com/example/mobile_labs/ui/performance/list/PerformanceList.kt +++ b/app/src/main/java/com/example/mobile_labs/ui/performance/list/PerformanceList.kt @@ -101,7 +101,8 @@ private fun PerformanceListItem( elevation = CardDefaults.cardElevation(defaultElevation = 2.dp) ) { Column( - modifier = modifier.padding(all = 10.dp) + modifier = modifier.padding(all = 10.dp), + horizontalAlignment = Alignment.CenterHorizontally ) { AsyncImage(model = performance.imageURL, contentDescription = "") Button( diff --git a/app/src/main/java/com/example/mobile_labs/ui/performance/view/AdminPerformanceView.kt b/app/src/main/java/com/example/mobile_labs/ui/performance/view/AdminPerformanceView.kt index b1857d6..10e0428 100644 --- a/app/src/main/java/com/example/mobile_labs/ui/performance/view/AdminPerformanceView.kt +++ b/app/src/main/java/com/example/mobile_labs/ui/performance/view/AdminPerformanceView.kt @@ -1,20 +1,31 @@ package com.example.mobile_labs.ui.performance.view import android.content.res.Configuration +import androidx.compose.foundation.background import androidx.compose.foundation.layout.Column import androidx.compose.foundation.layout.fillMaxWidth import androidx.compose.foundation.layout.padding import androidx.compose.foundation.text.KeyboardOptions import androidx.compose.material3.Button +import androidx.compose.material3.DropdownMenu +import androidx.compose.material3.DropdownMenuItem import androidx.compose.material3.ExperimentalMaterial3Api +import androidx.compose.material3.ExposedDropdownMenuBox +import androidx.compose.material3.ExposedDropdownMenuDefaults import androidx.compose.material3.MaterialTheme import androidx.compose.material3.OutlinedTextField import androidx.compose.material3.Surface import androidx.compose.material3.Text +import androidx.compose.material3.TextField 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.setValue import androidx.compose.ui.Alignment import androidx.compose.ui.Modifier +import androidx.compose.ui.graphics.Color import androidx.compose.ui.res.stringResource import androidx.compose.ui.text.input.KeyboardType import androidx.compose.ui.text.style.TextAlign @@ -26,6 +37,7 @@ import androidx.navigation.NavController import coil.compose.AsyncImage import com.example.mobile_labs.R 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 kotlinx.coroutines.launch @@ -33,7 +45,9 @@ import kotlinx.coroutines.launch @Composable fun AdminPerformanceView( 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() PerformanceEdit( @@ -45,15 +59,77 @@ fun AdminPerformanceView( } }, 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) @Composable private fun PerformanceEdit( performanceUiState: AdminPerformanceUiState, onClick: () -> Unit, onUpdate: (AdminPerformanceDetails) -> Unit, + onAuthorUpdate: (Person) -> Unit, + onDirectorUpdate: (Person) -> Unit, + authorUiState: PersonUiState, + authorListUiState: PersonsListUiState, + directorUiState: PersonUiState, + directorListUiState: PersonsListUiState, ) { Column( Modifier @@ -88,21 +164,23 @@ private fun PerformanceEdit( label = {Text("URL превью")}, singleLine = true ) - OutlinedTextField( - modifier = Modifier.fillMaxWidth(), - value = performanceUiState.performanceDetails.authorId.toString(), - onValueChange = { onUpdate(performanceUiState.performanceDetails.copy(authorId = it.toInt())) }, - label = {Text("Автор")}, - singleLine = true, - keyboardOptions = KeyboardOptions(keyboardType = KeyboardType.Phone) + Text(text = "Автор") + PersonDropDown( + personUiState = authorUiState, + personsListUiState = authorListUiState, + onPersonUpdate = { + onUpdate(performanceUiState.performanceDetails.copy(authorId = it.uid !!)) + onAuthorUpdate(it) + } ) - OutlinedTextField( - modifier = Modifier.fillMaxWidth(), - value = performanceUiState.performanceDetails.directorId.toString(), - onValueChange = { onUpdate(performanceUiState.performanceDetails.copy(directorId = it.toInt())) }, - label = {Text("Режиссер")}, - singleLine = true, - keyboardOptions = KeyboardOptions(keyboardType = KeyboardType.Phone) + Text(text = "Режиссер") + PersonDropDown( + personUiState = directorUiState, + personsListUiState = directorListUiState, + onPersonUpdate = { + onUpdate(performanceUiState.performanceDetails.copy(directorId = it.uid !!)) + onDirectorUpdate(it) + } ) Button( onClick = onClick, diff --git a/app/src/main/java/com/example/mobile_labs/ui/performance/view/PerformanceViewModel.kt b/app/src/main/java/com/example/mobile_labs/ui/performance/view/PerformanceViewModel.kt index c07fbfc..3affe84 100644 --- a/app/src/main/java/com/example/mobile_labs/ui/performance/view/PerformanceViewModel.kt +++ b/app/src/main/java/com/example/mobile_labs/ui/performance/view/PerformanceViewModel.kt @@ -20,12 +20,12 @@ class PerformanceViewModel( var performanceUiState by mutableStateOf(PerformanceUiState()) private set - private val studentUid: Int = checkNotNull(savedStateHandle["id"]) + private val performanceUid: Int = checkNotNull(savedStateHandle["id"]) init { viewModelScope.launch { - if (studentUid > 0) { - performanceUiState = performanceRepository.getPerformance(studentUid) + if (performanceUid > 0) { + performanceUiState = performanceRepository.getPerformance(performanceUid) .toUiState() } } diff --git a/app/src/main/java/com/example/mobile_labs/ui/performance/view/PersonDropDownViewModel.kt b/app/src/main/java/com/example/mobile_labs/ui/performance/view/PersonDropDownViewModel.kt new file mode 100644 index 0000000..cfbd09f --- /dev/null +++ b/app/src/main/java/com/example/mobile_labs/ui/performance/view/PersonDropDownViewModel.kt @@ -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 = 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)) \ No newline at end of file diff --git a/app/src/main/res/values/strings.xml b/app/src/main/res/values/strings.xml index accd3d9..bc7efac 100644 --- a/app/src/main/res/values/strings.xml +++ b/app/src/main/res/values/strings.xml @@ -13,14 +13,14 @@ Данные о людях отсутствуют Данные о событиях отсутствуют Данные о представлениях отсутствуют + ... Логин Пароль -

- 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! -

-

- 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. -

+

Добро пожаловать в театр "Лира"! Мы - креативная и страстная труппа артистов, цель которой - вдохновлять, развлекать и затрагивать сердца нашей аудитории через искусство театра. Наша миссия - оставаться в центре культурной жизни, предоставляя высококачественные и умопомрачительные спектакли, которые затрагивают самые глубокие струны души.

+

В театре "Лира" мы стремимся восхищать и захватывать зрителей разнообразными постановками, начиная от классических произведений и заканчивая современными экспериментальными шедеврами. Наша команда творческих профессионалов охватывает широкий спектр талантливых актеров, режиссеров, дизайнеров и технических специалистов, которые работают сообща, чтобы создать неповторимый театральный опыт.

+

Мы верим в силу искусства и его способность изменять мир вокруг нас. Наша цель - не только представлять превосходные спектакли, но и стать платформой для обсуждения глубоких и важных вопросов, которые затрагивают каждого из нас. Мы призываем зрителей погрузиться в мир театральной магии и открыть для себя новые грани человеческого опыта

+

Мы гордимся качеством нашей работы и постоянно стремимся к тому, чтобы каждый спектакль был для наших зрителей уникальным и захватывающим. Мы глубоко ценим вашу поддержку и рады поделиться с вами нашим творческим путешествием.

+

Наш адрес: город Ульяновск, улица Спасская 12А

\ No newline at end of file