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 {
@GET("api/persons")
suspend fun getPeople(
@Query("_page") page: Int,
@Query("page") page: Int,
@Query("_limit") limit: Int,
): List<PersonRemote>
@GET("api/performances")
suspend fun getPerformances(
@Query("_page") page: Int,
@Query("page") page: Int,
@Query("_limit") limit: Int,
): List<PerformanceRemote>
@GET("api/events")
suspend fun getEvents(
@Query("_page") page: Int,
@Query("page") page: Int,
@Query("_limit") limit: Int,
): List<EventRemote>

View File

@ -73,8 +73,6 @@ class EventRemoteMediator(
nextKey = nextKey
)
}
dbRemoteKeyRepository.deleteRemoteKey(RemoteKeyType.EVENT)
dbEventRepository.clearEvents()
performanceRestRepository.getAllPerformances()
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.remotekeys.repository.OfflineRemoteKeyRepository
import kotlinx.coroutines.flow.Flow
import kotlinx.coroutines.flow.map
class RestEventRepository(
private val service: MyServerService,

View File

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

View File

@ -75,8 +75,6 @@ class PerformanceRemoteMediator(
nextKey = nextKey
)
}
dbRemoteKeyRepository.deleteRemoteKey(RemoteKeyType.PERFORMANCE)
dbPerformanceRepository.clearPerformances()
personRestRepository.getAllPeople()
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.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)
}
}
}

View File

@ -18,9 +18,8 @@ interface EventDao {
@Query("select * from events order by date asc")
fun getAll(): Flow<List<Event>>
@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<Int, EventWithPerformance>
@Query("select * from events")
fun getAllWithPerformance(): PagingSource<Int, EventWithPerformance>
@Query("select * from events where events.uid = :uid")
fun getByUid(uid: Int): Flow<EventWithPerformance>

View File

@ -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<EventWithPerformance>,
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"))

View File

@ -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(

View File

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

View File

@ -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(

View File

@ -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,

View File

@ -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()
}
}

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="events_missing_description">Данные о событиях отсутствуют</string>
<string name="performance_missing_description">Данные о представлениях отсутствуют</string>
<string name="person_not_selected">...</string>
<string name="login">Логин</string>
<string name="password">Пароль</string>
<string name="about_text">
<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>
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>
<p>Добро пожаловать в театр "Лира"! Мы - креативная и страстная труппа артистов, цель которой - вдохновлять, развлекать и затрагивать сердца нашей аудитории через искусство театра. Наша миссия - оставаться в центре культурной жизни, предоставляя высококачественные и умопомрачительные спектакли, которые затрагивают самые глубокие струны души.</p>
<p>В театре "Лира" мы стремимся восхищать и захватывать зрителей разнообразными постановками, начиная от классических произведений и заканчивая современными экспериментальными шедеврами. Наша команда творческих профессионалов охватывает широкий спектр талантливых актеров, режиссеров, дизайнеров и технических специалистов, которые работают сообща, чтобы создать неповторимый театральный опыт.</p>
<p>Мы верим в силу искусства и его способность изменять мир вокруг нас. Наша цель - не только представлять превосходные спектакли, но и стать платформой для обсуждения глубоких и важных вопросов, которые затрагивают каждого из нас. Мы призываем зрителей погрузиться в мир театральной магии и открыть для себя новые грани человеческого опыта</p>
<p>Мы гордимся качеством нашей работы и постоянно стремимся к тому, чтобы каждый спектакль был для наших зрителей уникальным и захватывающим. Мы глубоко ценим вашу поддержку и рады поделиться с вами нашим творческим путешествием.</p>
<p><b>Наш адрес:</b> город Ульяновск, улица Спасская 12А</p>
</string>
</resources>