This commit is contained in:
abazov73 2023-12-04 00:20:47 +04:00
parent 16257cf1b6
commit 7707836c12
38 changed files with 798 additions and 364 deletions

View File

@ -14,6 +14,7 @@
android:roundIcon="@mipmap/ic_launcher_round"
android:supportsRtl="true"
android:theme="@style/Theme.Mobile_Labs"
android:name=".TheatreApplication"
tools:targetApi="31">
<activity
android:name=".MainActivity"

View File

@ -10,7 +10,7 @@ import androidx.compose.material3.Text
import androidx.compose.runtime.Composable
import androidx.compose.ui.Modifier
import androidx.compose.ui.tooling.preview.Preview
import com.example.mobile_labs.composeui.navigation.MainNavbar
import com.example.mobile_labs.ui.navigation.MainNavbar
import com.example.mobile_labs.ui.theme.Mobile_LabsTheme
class MainActivity : ComponentActivity() {

View File

@ -0,0 +1,14 @@
package com.example.mobile_labs
import android.app.Application
import com.example.mobile_labs.database.AppContainer
import com.example.mobile_labs.database.AppDataContainer
class TheatreApplication : Application() {
lateinit var container: AppContainer
override fun onCreate() {
super.onCreate()
container = AppDataContainer(this)
}
}

View File

@ -0,0 +1,33 @@
package com.example.mobile_labs.database
import android.content.Context
import com.example.mobile_labs.database.event.repository.EventRepository
import com.example.mobile_labs.database.event.repository.OfflineEventRepository
import com.example.mobile_labs.database.performance.repository.OfflinePerformanceRepository
import com.example.mobile_labs.database.performance.repository.PerformanceRepository
import com.example.mobile_labs.database.person.repository.OfflinePersonRepository
import com.example.mobile_labs.database.person.repository.PersonRepository
interface AppContainer {
val personRepository: PersonRepository
val eventRepository: EventRepository
val performanceRepository: PerformanceRepository
}
class AppDataContainer(private val context: Context) : AppContainer {
override val eventRepository: EventRepository by lazy {
OfflineEventRepository(AppDatabase.getInstance(context).eventDao())
}
override val performanceRepository: PerformanceRepository by lazy {
OfflinePerformanceRepository(AppDatabase.getInstance(context).performanceDao())
}
override val personRepository: PersonRepository by lazy {
OfflinePersonRepository(AppDatabase.getInstance(context).personDao())
}
companion object {
const val TIMEOUT = 5000L
}
}

View File

@ -5,14 +5,14 @@ import androidx.room.Database
import androidx.room.Room
import androidx.room.RoomDatabase
import androidx.sqlite.db.SupportSQLiteDatabase
import com.example.mobile_labs.event.dao.EventDao
import com.example.mobile_labs.event.model.Event
import com.example.mobile_labs.performance.dao.PerformanceDao
import com.example.mobile_labs.performance.dao.PerformancePersonDao
import com.example.mobile_labs.performance.model.Performance
import com.example.mobile_labs.performance.model.PerformancePersonCrossRef
import com.example.mobile_labs.person.dao.PersonDao
import com.example.mobile_labs.person.model.Person
import com.example.mobile_labs.database.event.dao.EventDao
import com.example.mobile_labs.database.event.model.Event
import com.example.mobile_labs.database.performance.dao.PerformanceDao
import com.example.mobile_labs.database.performance.dao.PerformancePersonDao
import com.example.mobile_labs.database.performance.model.Performance
import com.example.mobile_labs.database.performance.model.PerformancePersonCrossRef
import com.example.mobile_labs.database.person.dao.PersonDao
import com.example.mobile_labs.database.person.model.Person
import com.example.mobile_labs.user.dao.UserDao
import com.example.mobile_labs.user.model.User
import kotlinx.coroutines.CoroutineScope

View File

@ -1,13 +1,13 @@
package com.example.mobile_labs.event.dao
package com.example.mobile_labs.database.event.dao
import androidx.room.Dao
import androidx.room.Delete
import androidx.room.Insert
import androidx.room.Query
import androidx.room.Update
import com.example.mobile_labs.event.model.Event
import com.example.mobile_labs.event.model.EventWithPerformance
import com.example.mobile_labs.performance.model.Performance
import com.example.mobile_labs.database.event.model.Event
import com.example.mobile_labs.database.event.model.EventWithPerformance
import com.example.mobile_labs.database.performance.model.Performance
import kotlinx.coroutines.flow.Flow
@Dao
@ -19,7 +19,7 @@ interface EventDao {
fun getAllWithPerformance(dateFrom: String): Flow<List<EventWithPerformance>>
@Query("select * from events where events.uid = :uid")
suspend fun getByUid(uid: Int): EventWithPerformance
fun getByUid(uid: Int): Flow<EventWithPerformance>
@Insert
suspend fun insert(event: Event)

View File

@ -1,4 +1,4 @@
package com.example.mobile_labs.event.model
package com.example.mobile_labs.database.event.model
import androidx.room.ColumnInfo
import androidx.room.Entity
@ -7,8 +7,8 @@ import androidx.room.PrimaryKey
import androidx.room.TypeConverter
import androidx.room.TypeConverters
import com.example.mobile_labs.converters.LocalDateConverter
import com.example.mobile_labs.performance.model.Performance
import com.example.mobile_labs.person.model.Person
import com.example.mobile_labs.database.performance.model.Performance
import com.example.mobile_labs.database.person.model.Person
import java.io.Serializable
import java.time.LocalDate

View File

@ -1,8 +1,8 @@
package com.example.mobile_labs.event.model
package com.example.mobile_labs.database.event.model
import androidx.room.Embedded
import androidx.room.Relation
import com.example.mobile_labs.performance.model.Performance
import com.example.mobile_labs.database.performance.model.Performance
data class EventWithPerformance (
@Embedded

View File

@ -0,0 +1,14 @@
package com.example.mobile_labs.database.event.repository
import com.example.mobile_labs.database.event.model.Event
import com.example.mobile_labs.database.event.model.EventWithPerformance
import kotlinx.coroutines.flow.Flow
interface EventRepository {
fun getAll(): Flow<List<Event>>
fun getAllWithPerformance(): Flow<List<EventWithPerformance>>
fun getEvent(uid: Int): Flow<EventWithPerformance?>
suspend fun insertEvent(event: Event)
suspend fun updateEvent(event: Event)
suspend fun deleteEvent(event: Event)
}

View File

@ -0,0 +1,22 @@
package com.example.mobile_labs.database.event.repository
import com.example.mobile_labs.database.event.dao.EventDao
import com.example.mobile_labs.database.event.model.Event
import com.example.mobile_labs.database.event.model.EventWithPerformance
import kotlinx.coroutines.flow.Flow
import java.time.LocalDate
import java.time.format.DateTimeFormatter
class OfflineEventRepository(private val eventDao: EventDao) : EventRepository {
override fun getAll(): Flow<List<Event>> = eventDao.getAll();
override fun getAllWithPerformance(): Flow<List<EventWithPerformance>> = eventDao.getAllWithPerformance(LocalDate.now().format(
DateTimeFormatter.ofPattern("dd.MM")
))
override fun getEvent(uid: Int): Flow<EventWithPerformance?> = eventDao.getByUid(uid);
override suspend fun insertEvent(event: Event) = eventDao.insert(event);
override suspend fun updateEvent(event: Event) = eventDao.update(event);
override suspend fun deleteEvent(event: Event) = eventDao.delete(event);
}

View File

@ -1,13 +1,13 @@
package com.example.mobile_labs.performance.dao
package com.example.mobile_labs.database.performance.dao
import androidx.room.Dao
import androidx.room.Delete
import androidx.room.Insert
import androidx.room.Query
import androidx.room.Update
import com.example.mobile_labs.performance.model.Performance
import com.example.mobile_labs.performance.model.PerformanceWithPeople
import com.example.mobile_labs.person.model.Person
import com.example.mobile_labs.database.performance.model.Performance
import com.example.mobile_labs.database.performance.model.PerformanceWithPeople
import com.example.mobile_labs.database.person.model.Person
import kotlinx.coroutines.flow.Flow
@Dao
@ -16,7 +16,7 @@ interface PerformanceDao {
fun getAll(): Flow<List<Performance>>
@Query("select * from performances where performances.performance_uid = :uid")
suspend fun getByUid(uid: Int): PerformanceWithPeople
fun getByUid(uid: Int): Flow<PerformanceWithPeople>
@Insert
suspend fun insert(performance: Performance)

View File

@ -1,13 +1,13 @@
package com.example.mobile_labs.performance.dao
package com.example.mobile_labs.database.performance.dao
import androidx.room.Dao
import androidx.room.Delete
import androidx.room.Insert
import androidx.room.Query
import androidx.room.Update
import com.example.mobile_labs.performance.model.Performance
import com.example.mobile_labs.performance.model.PerformancePersonCrossRef
import com.example.mobile_labs.performance.model.PerformanceWithPeople
import com.example.mobile_labs.database.performance.model.Performance
import com.example.mobile_labs.database.performance.model.PerformancePersonCrossRef
import com.example.mobile_labs.database.performance.model.PerformanceWithPeople
import kotlinx.coroutines.flow.Flow
@Dao

View File

@ -1,10 +1,10 @@
package com.example.mobile_labs.performance.model
package com.example.mobile_labs.database.performance.model
import androidx.room.ColumnInfo
import androidx.room.Entity
import androidx.room.ForeignKey
import androidx.room.PrimaryKey
import com.example.mobile_labs.person.model.Person
import com.example.mobile_labs.database.person.model.Person
import java.io.Serializable
@Entity(tableName = "performances", foreignKeys = [

View File

@ -1,4 +1,4 @@
package com.example.mobile_labs.performance.model
package com.example.mobile_labs.database.performance.model
import androidx.room.Entity

View File

@ -1,10 +1,10 @@
package com.example.mobile_labs.performance.model
package com.example.mobile_labs.database.performance.model
import androidx.room.ColumnInfo
import androidx.room.Embedded
import androidx.room.Junction
import androidx.room.Relation
import com.example.mobile_labs.person.model.Person
import com.example.mobile_labs.database.person.model.Person
data class PerformanceWithPeople (
@Embedded

View File

@ -0,0 +1,17 @@
package com.example.mobile_labs.database.performance.repository
import com.example.mobile_labs.database.performance.dao.PerformanceDao
import com.example.mobile_labs.database.performance.model.Performance
import com.example.mobile_labs.database.performance.model.PerformanceWithPeople
import kotlinx.coroutines.flow.Flow
class OfflinePerformanceRepository(private val performanceDao: PerformanceDao) : PerformanceRepository {
override fun getAllPerformances(): Flow<List<Performance>> = performanceDao.getAll();
override fun getPerformance(uid: Int): Flow<PerformanceWithPeople?> = performanceDao.getByUid(uid);
override suspend fun insertPerformance(performance: Performance) = performanceDao.insert(performance);
override suspend fun updatePerformance(performance: Performance) = performanceDao.update(performance);
override suspend fun deletePerformance(performance: Performance) = performanceDao.delete(performance);
}

View File

@ -0,0 +1,13 @@
package com.example.mobile_labs.database.performance.repository
import com.example.mobile_labs.database.performance.model.Performance
import com.example.mobile_labs.database.performance.model.PerformanceWithPeople
import kotlinx.coroutines.flow.Flow
interface PerformanceRepository {
fun getAllPerformances(): Flow<List<Performance>>
fun getPerformance(uid: Int): Flow<PerformanceWithPeople?>
suspend fun insertPerformance(performance: Performance)
suspend fun updatePerformance(performance: Performance)
suspend fun deletePerformance(performance: Performance)
}

View File

@ -1,11 +1,11 @@
package com.example.mobile_labs.person.dao
package com.example.mobile_labs.database.person.dao
import androidx.room.Dao
import androidx.room.Delete
import androidx.room.Insert
import androidx.room.Query
import androidx.room.Update
import com.example.mobile_labs.person.model.Person
import com.example.mobile_labs.database.person.model.Person
import kotlinx.coroutines.flow.Flow
@Dao
@ -14,7 +14,7 @@ interface PersonDao {
fun getAll(): Flow<List<Person>>
@Query("select * from people where people.uid = :uid")
suspend fun getByUid(uid: Int): Person
fun getByUid(uid: Int): Flow<Person>
@Insert
suspend fun insert(person: Person)

View File

@ -1,4 +1,4 @@
package com.example.mobile_labs.person.model
package com.example.mobile_labs.database.person.model
import androidx.room.ColumnInfo
import androidx.room.Entity

View File

@ -0,0 +1,17 @@
package com.example.mobile_labs.database.person.repository
import com.example.mobile_labs.database.person.dao.PersonDao
import com.example.mobile_labs.database.person.model.Person
import kotlinx.coroutines.flow.Flow
class OfflinePersonRepository(private val personDao: PersonDao) : PersonRepository {
override fun getAllPeople(): Flow<List<Person>> = personDao.getAll();
override fun getPerson(uid: Int): Flow<Person?> = personDao.getByUid(uid);
override suspend fun insertPerson(person: Person) = personDao.insert(person);
override suspend fun updatePerson(person: Person) = personDao.update(person);
override suspend fun deletePerson(person: Person) = personDao.delete(person);
}

View File

@ -0,0 +1,12 @@
package com.example.mobile_labs.database.person.repository
import com.example.mobile_labs.database.person.model.Person
import kotlinx.coroutines.flow.Flow
interface PersonRepository {
fun getAllPeople(): Flow<List<Person>>
fun getPerson(uid: Int): Flow<Person?>
suspend fun insertPerson(person: Person)
suspend fun updatePerson(person: Person)
suspend fun deletePerson(person: Person)
}

View File

@ -1,92 +0,0 @@
package com.example.mobile_labs.event.composeui
import android.content.res.Configuration
import androidx.compose.foundation.layout.Column
import androidx.compose.foundation.layout.Row
import androidx.compose.foundation.layout.fillMaxWidth
import androidx.compose.foundation.layout.height
import androidx.compose.foundation.layout.padding
import androidx.compose.foundation.layout.width
import androidx.compose.foundation.rememberScrollState
import androidx.compose.foundation.verticalScroll
import androidx.compose.material3.Button
import androidx.compose.material3.ExperimentalMaterial3Api
import androidx.compose.material3.MaterialTheme
import androidx.compose.material3.Surface
import androidx.compose.material3.Text
import androidx.compose.runtime.Composable
import androidx.compose.runtime.LaunchedEffect
import androidx.compose.runtime.mutableStateListOf
import androidx.compose.runtime.remember
import androidx.compose.ui.Alignment
import androidx.compose.ui.Modifier
import androidx.compose.ui.layout.ContentScale
import androidx.compose.ui.platform.LocalContext
import androidx.compose.ui.text.style.TextAlign
import androidx.compose.ui.tooling.preview.Preview
import androidx.compose.ui.unit.dp
import androidx.navigation.NavController
import coil.compose.AsyncImage
import com.example.mobile_labs.composeui.navigation.Screen
import com.example.mobile_labs.database.AppDatabase
import com.example.mobile_labs.event.model.EventWithPerformance
import com.example.mobile_labs.person.model.Person
import com.example.mobile_labs.ui.theme.Mobile_LabsTheme
import kotlinx.coroutines.Dispatchers
import kotlinx.coroutines.withContext
import java.time.LocalDate
import java.time.format.DateTimeFormatter
import java.util.Calendar
@Composable
fun Schedule(navController: NavController?) {
val context = LocalContext.current
val events = remember { mutableStateListOf<EventWithPerformance>() }
LaunchedEffect(Unit) {
withContext(Dispatchers.IO) {
val dateNow = LocalDate.now().toString()
AppDatabase.getInstance(context).eventDao().getAllWithPerformance(dateNow).collect { data ->
events.clear()
events.addAll(data)
}
}
}
Column(
horizontalAlignment = Alignment.CenterHorizontally,
modifier = Modifier
.padding(all = 10.dp)
.verticalScroll(rememberScrollState())) {
events.forEachIndexed() { _, event ->
val performanceId = Screen.PerformanceView.route.replace("{id}", event.performance.performance_uid.toString())
Row(Modifier.padding(all = 10.dp)) {
Text(modifier = Modifier.padding(all = 5.dp), textAlign = TextAlign.Center, text = event.event.date.format(DateTimeFormatter.ofPattern("dd.MM")))
AsyncImage(model = event.performance.previewImageURL,
contentDescription = "performance preview image",
contentScale = ContentScale.Crop,
modifier = Modifier
.height(100.dp)
.width(100.dp))
Button(
modifier = Modifier
.fillMaxWidth()
.padding(all = 10.dp),
onClick = { navController?.navigate(performanceId) }) {
Text(event.performance.title)
}
}
}
}
}
@Preview(name = "Light Mode", showBackground = true, uiMode = Configuration.UI_MODE_NIGHT_NO)
@Preview(name = "Dark Mode", showBackground = true, uiMode = Configuration.UI_MODE_NIGHT_YES)
@Composable
fun SchedulePreview() {
Mobile_LabsTheme {
Surface(
color = MaterialTheme.colorScheme.background
) {
Schedule(navController = null)
}
}
}

View File

@ -1,108 +0,0 @@
package com.example.mobile_labs.performance.composeui
import android.content.res.Configuration
import android.util.Log
import androidx.compose.foundation.layout.Column
import androidx.compose.foundation.layout.Row
import androidx.compose.foundation.layout.fillMaxWidth
import androidx.compose.foundation.layout.height
import androidx.compose.foundation.layout.padding
import androidx.compose.foundation.layout.width
import androidx.compose.foundation.rememberScrollState
import androidx.compose.foundation.verticalScroll
import androidx.compose.material3.Button
import androidx.compose.material3.ExperimentalMaterial3Api
import androidx.compose.material3.MaterialTheme
import androidx.compose.material3.Surface
import androidx.compose.material3.Text
import androidx.compose.material3.TextField
import androidx.compose.runtime.Composable
import androidx.compose.runtime.LaunchedEffect
import androidx.compose.runtime.State
import androidx.compose.runtime.getValue
import androidx.compose.runtime.mutableStateListOf
import androidx.compose.runtime.mutableStateOf
import androidx.compose.runtime.remember
import androidx.compose.runtime.saveable.rememberSaveable
import androidx.compose.runtime.setValue
import androidx.compose.ui.Alignment
import androidx.compose.ui.Modifier
import androidx.compose.ui.draw.clip
import androidx.compose.ui.graphics.RectangleShape
import androidx.compose.ui.layout.ContentScale
import androidx.compose.ui.platform.LocalContext
import androidx.compose.ui.tooling.preview.Preview
import androidx.compose.ui.unit.dp
import androidx.navigation.NavController
import coil.compose.AsyncImage
import com.example.mobile_labs.composeui.navigation.Screen
import com.example.mobile_labs.database.AppDatabase
import com.example.mobile_labs.performance.model.Performance
import com.example.mobile_labs.person.model.Person
import com.example.mobile_labs.ui.theme.Mobile_LabsTheme
import kotlinx.coroutines.Dispatchers
import kotlinx.coroutines.withContext
@OptIn(ExperimentalMaterial3Api::class)
@Composable
fun Repertoire(navController: NavController?) {
val context = LocalContext.current
val performances = remember { mutableStateListOf<Performance>() }
var performancesFiltered = remember { mutableStateListOf<Performance>() }
var title by remember { mutableStateOf("") }
LaunchedEffect(Unit) {
withContext(Dispatchers.IO) {
AppDatabase.getInstance(context).performanceDao().getAll().collect { data ->
performances.clear()
performances.addAll(data)
performancesFiltered.addAll(data)
}
}
}
Column(
horizontalAlignment = Alignment.CenterHorizontally,
modifier = Modifier
.padding(all = 10.dp)
.verticalScroll(rememberScrollState())) {
TextField(value = title, label = {Text(text = "Поиск...")}, onValueChange = { title = it;
if (title != "") {
val data = performances.filter { performance -> performance.title.contains(title) }
performancesFiltered.clear()
performancesFiltered.addAll(data)
} else {
performancesFiltered.clear()
performancesFiltered.addAll(performances)
} })
performancesFiltered.forEachIndexed() { index, performance ->
val performanceId = Screen.PerformanceView.route.replace("{id}", performance.performance_uid.toString())
Row(Modifier.padding(all = 10.dp)) {
AsyncImage(model = performance.previewImageURL,
contentDescription = "performance preview image",
contentScale = ContentScale.Crop,
modifier = Modifier
.height(100.dp)
.width(100.dp))
Button(
modifier = Modifier
.fillMaxWidth()
.padding(all = 10.dp),
onClick = { navController?.navigate(performanceId) }) {
Text(performance.title)
}
}
}
}
}
@Preview(name = "Light Mode", showBackground = true, uiMode = Configuration.UI_MODE_NIGHT_NO)
@Preview(name = "Dark Mode", showBackground = true, uiMode = Configuration.UI_MODE_NIGHT_YES)
@Composable
fun RepertoirePreview() {
Mobile_LabsTheme {
Surface(
color = MaterialTheme.colorScheme.background
) {
Repertoire(navController = null)
}
}
}

View File

@ -1,76 +0,0 @@
package com.example.mobile_labs.person.composeui
import android.content.res.Configuration
import androidx.compose.foundation.layout.Column
import androidx.compose.foundation.layout.Row
import androidx.compose.foundation.layout.fillMaxWidth
import androidx.compose.foundation.layout.height
import androidx.compose.foundation.layout.padding
import androidx.compose.foundation.layout.width
import androidx.compose.foundation.lazy.grid.GridCells
import androidx.compose.foundation.lazy.grid.LazyVerticalGrid
import androidx.compose.foundation.lazy.grid.items
import androidx.compose.material3.Button
import androidx.compose.material3.MaterialTheme
import androidx.compose.material3.Surface
import androidx.compose.material3.Text
import androidx.compose.runtime.Composable
import androidx.compose.runtime.LaunchedEffect
import androidx.compose.runtime.mutableStateListOf
import androidx.compose.runtime.remember
import androidx.compose.ui.Alignment
import androidx.compose.ui.Modifier
import androidx.compose.ui.layout.ContentScale
import androidx.compose.ui.platform.LocalContext
import androidx.compose.ui.text.style.TextAlign
import androidx.compose.ui.tooling.preview.Preview
import androidx.compose.ui.unit.dp
import androidx.navigation.NavController
import coil.compose.AsyncImage
import com.example.mobile_labs.composeui.navigation.Screen
import com.example.mobile_labs.database.AppDatabase
import com.example.mobile_labs.performance.composeui.Repertoire
import com.example.mobile_labs.person.model.Person
import com.example.mobile_labs.ui.theme.Mobile_LabsTheme
import kotlinx.coroutines.Dispatchers
import kotlinx.coroutines.withContext
@Composable
fun PeopleList(navController: NavController?) {
val context = LocalContext.current
val people = remember { mutableStateListOf<Person>() }
LaunchedEffect(Unit) {
withContext(Dispatchers.IO) {
AppDatabase.getInstance(context).personDao().getAll().collect { data ->
people.clear()
people.addAll(data)
}
}
}
Column(Modifier.padding(all = 10.dp)) {
LazyVerticalGrid(columns = GridCells.Adaptive(minSize = 100.dp))
{
items(people) {
Column(horizontalAlignment = Alignment.CenterHorizontally, modifier = Modifier
.width(300.dp)
.height(200.dp)) {
AsyncImage(model = it.imageURL, contentDescription = "person image")
Text(text = "${it.last_name} ${it.first_name}", textAlign = TextAlign.Center)
}
}
}
}
}
@Preview(name = "Light Mode", showBackground = true, uiMode = Configuration.UI_MODE_NIGHT_NO)
@Preview(name = "Dark Mode", showBackground = true, uiMode = Configuration.UI_MODE_NIGHT_YES)
@Composable
fun PeopleListPreview() {
Mobile_LabsTheme {
Surface(
color = MaterialTheme.colorScheme.background
) {
Repertoire(navController = null)
}
}
}

View File

@ -0,0 +1,32 @@
package com.example.mobile_labs.ui
import androidx.lifecycle.ViewModelProvider
import androidx.lifecycle.createSavedStateHandle
import androidx.lifecycle.viewmodel.CreationExtras
import androidx.lifecycle.viewmodel.initializer
import androidx.lifecycle.viewmodel.viewModelFactory
import com.example.mobile_labs.TheatreApplication
import com.example.mobile_labs.ui.event.list.EventListViewModel
import com.example.mobile_labs.ui.performance.list.PerformanceListViewModel
import com.example.mobile_labs.ui.performance.view.PerformanceViewModel
import com.example.mobile_labs.ui.person.list.PeopleListViewModel
object AppViewModelProvider {
val Factory = viewModelFactory {
initializer {
PeopleListViewModel(theatreApplication().container.personRepository)
}
initializer {
EventListViewModel(theatreApplication().container.eventRepository)
}
initializer {
PerformanceListViewModel(theatreApplication().container.performanceRepository)
}
initializer {
PerformanceViewModel(this.createSavedStateHandle(), theatreApplication().container.performanceRepository)
}
}
}
fun CreationExtras.theatreApplication(): TheatreApplication =
(this[ViewModelProvider.AndroidViewModelFactory.APPLICATION_KEY] as TheatreApplication)

View File

@ -1,12 +1,8 @@
package com.example.mobile_labs.composeui
package com.example.mobile_labs.ui.about
import android.content.Intent
import android.content.res.Configuration
import android.net.Uri
import android.widget.TextView
import androidx.compose.foundation.clickable
import androidx.compose.foundation.layout.Column
import androidx.compose.foundation.layout.Spacer
import androidx.compose.foundation.layout.fillMaxWidth
import androidx.compose.foundation.layout.padding

View File

@ -0,0 +1,139 @@
package com.example.mobile_labs.ui.event.list
import android.content.res.Configuration
import androidx.compose.foundation.layout.Column
import androidx.compose.foundation.layout.Row
import androidx.compose.foundation.layout.fillMaxWidth
import androidx.compose.foundation.layout.height
import androidx.compose.foundation.layout.padding
import androidx.compose.foundation.layout.width
import androidx.compose.foundation.lazy.LazyColumn
import androidx.compose.foundation.lazy.items
import androidx.compose.foundation.rememberScrollState
import androidx.compose.foundation.verticalScroll
import androidx.compose.material3.Button
import androidx.compose.material3.Card
import androidx.compose.material3.CardDefaults
import androidx.compose.material3.ExperimentalMaterial3Api
import androidx.compose.material3.MaterialTheme
import androidx.compose.material3.Surface
import androidx.compose.material3.Text
import androidx.compose.runtime.Composable
import androidx.compose.runtime.LaunchedEffect
import androidx.compose.runtime.collectAsState
import androidx.compose.runtime.getValue
import androidx.compose.runtime.mutableStateListOf
import androidx.compose.runtime.remember
import androidx.compose.runtime.rememberCoroutineScope
import androidx.compose.ui.Alignment
import androidx.compose.ui.Modifier
import androidx.compose.ui.layout.ContentScale
import androidx.compose.ui.platform.LocalContext
import androidx.compose.ui.res.stringResource
import androidx.compose.ui.text.style.TextAlign
import androidx.compose.ui.tooling.preview.Preview
import androidx.compose.ui.unit.dp
import androidx.lifecycle.viewmodel.compose.viewModel
import androidx.navigation.NavController
import coil.compose.AsyncImage
import com.example.mobile_labs.R
import com.example.mobile_labs.database.AppDatabase
import com.example.mobile_labs.database.event.model.Event
import com.example.mobile_labs.database.event.model.EventWithPerformance
import com.example.mobile_labs.database.person.model.Person
import com.example.mobile_labs.ui.AppViewModelProvider
import com.example.mobile_labs.ui.navigation.Screen
import com.example.mobile_labs.ui.person.list.PeopleListViewModel
import com.example.mobile_labs.ui.theme.Mobile_LabsTheme
import kotlinx.coroutines.Dispatchers
import kotlinx.coroutines.withContext
import java.time.LocalDate
import java.time.format.DateTimeFormatter
@Composable
fun EventList(
navController: NavController,
viewModel: EventListViewModel = viewModel(factory = AppViewModelProvider.Factory)
) {
val eventListUiState by viewModel.eventListUiState.collectAsState()
Column(
horizontalAlignment = Alignment.CenterHorizontally,
modifier = Modifier
.padding(all = 10.dp)) {
EventList(
eventList = eventListUiState.eventList,
onClick = {uid : Int ->
val route = Screen.PerformanceView.route.replace("{id}", uid.toString())
navController.navigate(route)
}
)
}
}
@OptIn(ExperimentalMaterial3Api::class)
@Composable
private fun EventList(
modifier: Modifier = Modifier,
eventList: List<EventWithPerformance>,
onClick: (uid: Int) -> Unit
) {
Column(
modifier = modifier
) {
if (eventList.isEmpty()) {
Text(
text = stringResource(R.string.events_missing_description),
textAlign = TextAlign.Center,
style = MaterialTheme.typography.titleLarge
)
} else {
LazyColumn(modifier = Modifier.padding(all = 10.dp)) {
items(items = eventList, key = { it.event.uid !! }) { event ->
EventListItem(event = event, modifier = Modifier
.padding(vertical = 7.dp), onClick = onClick)
}
}
}
}
}
@Composable
private fun EventListItem(
event: EventWithPerformance, modifier: Modifier = Modifier,
onClick: (uid: Int) -> Unit
) {
Card(
modifier = modifier.fillMaxWidth(),
elevation = CardDefaults.cardElevation(defaultElevation = 2.dp)
) {
Column(
modifier = modifier.padding(all = 10.dp)
) {
Text(
text = event.event.date.format(DateTimeFormatter.ofPattern("dd.MM"))
)
AsyncImage(model = event.performance.imageURL, contentDescription = "")
Button(
modifier = Modifier
.fillMaxWidth()
.padding(all = 10.dp),
onClick = { onClick(event.event.performanceId !!) }) {
Text(event.performance.title)
}
}
}
}
@Preview(name = "Light Mode", showBackground = true, uiMode = Configuration.UI_MODE_NIGHT_NO)
@Preview(name = "Dark Mode", showBackground = true, uiMode = Configuration.UI_MODE_NIGHT_YES)
@Composable
fun SchedulePreview() {
Mobile_LabsTheme {
Surface(
color = MaterialTheme.colorScheme.background
) {
EventList(eventList = listOf(), onClick = {})
}
}
}

View File

@ -0,0 +1,26 @@
package com.example.mobile_labs.ui.event.list
import androidx.lifecycle.ViewModel
import androidx.lifecycle.viewModelScope
import com.example.mobile_labs.database.AppDataContainer
import com.example.mobile_labs.database.event.repository.EventRepository
import com.example.mobile_labs.database.event.model.Event
import com.example.mobile_labs.database.event.model.EventWithPerformance
import kotlinx.coroutines.flow.SharingStarted
import kotlinx.coroutines.flow.StateFlow
import kotlinx.coroutines.flow.map
import kotlinx.coroutines.flow.stateIn
class EventListViewModel(
private val eventRepository: EventRepository
) : ViewModel() {
val eventListUiState: StateFlow<EventListUiState> = eventRepository.getAllWithPerformance().map {
EventListUiState(it)
}.stateIn(
scope = viewModelScope,
started = SharingStarted.WhileSubscribed(stopTimeoutMillis = AppDataContainer.TIMEOUT),
initialValue = EventListUiState()
)
}
data class EventListUiState(val eventList: List<EventWithPerformance> = listOf())

View File

@ -1,4 +1,4 @@
package com.example.mobile_labs.composeui.navigation
package com.example.mobile_labs.ui.navigation
import android.content.res.Configuration
import androidx.compose.foundation.layout.PaddingValues
@ -33,11 +33,11 @@ import androidx.navigation.compose.rememberNavController
import androidx.navigation.navArgument
import com.example.mobile_labs.ui.theme.Mobile_LabsTheme
import com.example.mobile_labs.R
import com.example.mobile_labs.composeui.About
import com.example.mobile_labs.event.composeui.Schedule
import com.example.mobile_labs.performance.composeui.PerformanceView
import com.example.mobile_labs.performance.composeui.Repertoire
import com.example.mobile_labs.person.composeui.PeopleList
import com.example.mobile_labs.ui.about.About
import com.example.mobile_labs.ui.event.list.EventList
import com.example.mobile_labs.ui.performance.list.PerformanceList
import com.example.mobile_labs.ui.performance.view.PerformanceView
import com.example.mobile_labs.ui.person.list.PeopleList
@OptIn(ExperimentalMaterial3Api::class)
@Composable
@ -107,15 +107,15 @@ fun Navhost(
startDestination = Screen.Schedule.route,
modifier.padding(innerPadding)
) {
composable(Screen.Schedule.route) { Schedule(navController) }
composable(Screen.Repertoire.route) { Repertoire(navController) }
composable(Screen.PeopleList.route) { PeopleList(navController) }
composable(Screen.Schedule.route) { EventList(navController) }
composable(Screen.Repertoire.route) { PerformanceList(navController) }
composable(Screen.PeopleList.route) { PeopleList() }
composable(Screen.About.route) { About() }
composable(
Screen.PerformanceView.route,
arguments = listOf(navArgument("id") { type = NavType.IntType })
) { backStackEntry ->
backStackEntry.arguments?.let { PerformanceView(it.getInt("id")) }
backStackEntry.arguments?.let { PerformanceView() }
}
}
}

View File

@ -1,4 +1,4 @@
package com.example.mobile_labs.composeui.navigation
package com.example.mobile_labs.ui.navigation
import androidx.annotation.StringRes
import androidx.compose.material.icons.Icons

View File

@ -0,0 +1,138 @@
package com.example.mobile_labs.ui.performance.list
import com.example.mobile_labs.ui.event.list.EventListViewModel
import android.content.res.Configuration
import androidx.compose.foundation.layout.Column
import androidx.compose.foundation.layout.Row
import androidx.compose.foundation.layout.fillMaxWidth
import androidx.compose.foundation.layout.height
import androidx.compose.foundation.layout.padding
import androidx.compose.foundation.layout.width
import androidx.compose.foundation.lazy.LazyColumn
import androidx.compose.foundation.lazy.items
import androidx.compose.foundation.rememberScrollState
import androidx.compose.foundation.verticalScroll
import androidx.compose.material3.Button
import androidx.compose.material3.Card
import androidx.compose.material3.CardDefaults
import androidx.compose.material3.ExperimentalMaterial3Api
import androidx.compose.material3.MaterialTheme
import androidx.compose.material3.Surface
import androidx.compose.material3.Text
import androidx.compose.runtime.Composable
import androidx.compose.runtime.LaunchedEffect
import androidx.compose.runtime.collectAsState
import androidx.compose.runtime.getValue
import androidx.compose.runtime.mutableStateListOf
import androidx.compose.runtime.remember
import androidx.compose.runtime.rememberCoroutineScope
import androidx.compose.ui.Alignment
import androidx.compose.ui.Modifier
import androidx.compose.ui.layout.ContentScale
import androidx.compose.ui.platform.LocalContext
import androidx.compose.ui.res.stringResource
import androidx.compose.ui.text.style.TextAlign
import androidx.compose.ui.tooling.preview.Preview
import androidx.compose.ui.unit.dp
import androidx.lifecycle.viewmodel.compose.viewModel
import androidx.navigation.NavController
import coil.compose.AsyncImage
import com.example.mobile_labs.R
import com.example.mobile_labs.database.AppDatabase
import com.example.mobile_labs.database.event.model.Event
import com.example.mobile_labs.database.event.model.EventWithPerformance
import com.example.mobile_labs.database.performance.model.Performance
import com.example.mobile_labs.database.person.model.Person
import com.example.mobile_labs.ui.AppViewModelProvider
import com.example.mobile_labs.ui.navigation.Screen
import com.example.mobile_labs.ui.person.list.PeopleListViewModel
import com.example.mobile_labs.ui.theme.Mobile_LabsTheme
import kotlinx.coroutines.Dispatchers
import kotlinx.coroutines.withContext
import java.time.LocalDate
import java.time.format.DateTimeFormatter
@Composable
fun PerformanceList(
navController: NavController,
viewModel: PerformanceListViewModel = viewModel(factory = AppViewModelProvider.Factory)
) {
val performanceListUiState by viewModel.performanceListUiState.collectAsState()
Column(
horizontalAlignment = Alignment.CenterHorizontally,
modifier = Modifier
.padding(all = 10.dp)) {
PerformanceList(
performanceList = performanceListUiState.performanceList,
onClick = {uid : Int ->
val route = Screen.PerformanceView.route.replace("{id}", uid.toString())
navController.navigate(route)
}
)
}
}
@OptIn(ExperimentalMaterial3Api::class)
@Composable
private fun PerformanceList(
modifier: Modifier = Modifier,
performanceList: List<Performance>,
onClick: (uid: Int) -> Unit
) {
Column(
modifier = modifier
) {
if (performanceList.isEmpty()) {
Text(
text = stringResource(R.string.performance_missing_description),
textAlign = TextAlign.Center,
style = MaterialTheme.typography.titleLarge
)
} else {
LazyColumn(modifier = Modifier.padding(all = 10.dp)) {
items(items = performanceList, key = { it.performance_uid !! }) { performance ->
PerformanceListItem(performance = performance, modifier = Modifier
.padding(vertical = 7.dp), onClick = onClick)
}
}
}
}
}
@Composable
private fun PerformanceListItem(
performance: Performance, modifier: Modifier = Modifier,
onClick: (uid: Int) -> Unit
) {
Card(
modifier = modifier.fillMaxWidth(),
elevation = CardDefaults.cardElevation(defaultElevation = 2.dp)
) {
Column(
modifier = modifier.padding(all = 10.dp)
) {
AsyncImage(model = performance.imageURL, contentDescription = "")
Button(
modifier = Modifier
.fillMaxWidth()
.padding(all = 10.dp),
onClick = { onClick(performance.performance_uid !!) }) {
Text(performance.title)
}
}
}
}
@Preview(name = "Light Mode", showBackground = true, uiMode = Configuration.UI_MODE_NIGHT_NO)
@Preview(name = "Dark Mode", showBackground = true, uiMode = Configuration.UI_MODE_NIGHT_YES)
@Composable
fun SchedulePreview() {
Mobile_LabsTheme {
Surface(
color = MaterialTheme.colorScheme.background
) {
PerformanceList(performanceList = listOf(), onClick = {})
}
}
}

View File

@ -0,0 +1,29 @@
package com.example.mobile_labs.ui.performance.list
import androidx.lifecycle.ViewModel
import androidx.lifecycle.viewModelScope
import com.example.mobile_labs.database.AppDataContainer
import com.example.mobile_labs.database.performance.model.Performance
import com.example.mobile_labs.database.performance.repository.PerformanceRepository
import kotlinx.coroutines.flow.SharingStarted
import kotlinx.coroutines.flow.StateFlow
import kotlinx.coroutines.flow.map
import kotlinx.coroutines.flow.stateIn
class PerformanceListViewModel(
private val performanceRepository: PerformanceRepository
) : ViewModel() {
val performanceListUiState: StateFlow<PerformanceListUiState> = performanceRepository.getAllPerformances().map {
PerformanceListUiState(it)
}.stateIn(
scope = viewModelScope,
started = SharingStarted.WhileSubscribed(stopTimeoutMillis = AppDataContainer.TIMEOUT),
initialValue = PerformanceListUiState()
)
// suspend fun deleteStudent(student: Student) {
// studentRepository.deleteStudent(student)
// }
}
data class PerformanceListUiState(val performanceList: List<Performance> = listOf())

View File

@ -1,75 +1,58 @@
package com.example.mobile_labs.performance.composeui
package com.example.mobile_labs.ui.performance.view
import android.content.res.Configuration
import androidx.compose.foundation.layout.Column
import androidx.compose.foundation.layout.Row
import androidx.compose.foundation.layout.fillMaxWidth
import androidx.compose.foundation.layout.height
import androidx.compose.foundation.layout.padding
import androidx.compose.foundation.layout.width
import androidx.compose.foundation.rememberScrollState
import androidx.compose.foundation.verticalScroll
import androidx.compose.material3.Button
import androidx.compose.material3.ExperimentalMaterial3Api
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.LaunchedEffect
import androidx.compose.runtime.getValue
import androidx.compose.runtime.mutableStateOf
import androidx.compose.runtime.remember
import androidx.compose.runtime.setValue
import androidx.compose.runtime.rememberCoroutineScope
import androidx.compose.ui.Alignment
import androidx.compose.ui.Modifier
import androidx.compose.ui.layout.ContentScale
import androidx.compose.ui.platform.LocalContext
import androidx.compose.ui.res.stringResource
import androidx.compose.ui.text.style.TextAlign
import androidx.compose.ui.tooling.preview.Preview
import androidx.compose.ui.unit.dp
import androidx.compose.ui.unit.sp
import androidx.lifecycle.viewmodel.compose.viewModel
import androidx.navigation.NavController
import coil.compose.AsyncImage
import com.example.mobile_labs.composeui.navigation.Screen
import com.example.mobile_labs.ui.theme.Mobile_LabsTheme
import com.example.mobile_labs.R
import com.example.mobile_labs.database.AppDatabase
import com.example.mobile_labs.performance.model.PerformanceWithPeople
import com.example.mobile_labs.database.performance.model.PerformanceWithPeople
import com.example.mobile_labs.ui.AppViewModelProvider
import com.example.mobile_labs.ui.theme.Mobile_LabsTheme
import kotlinx.coroutines.Dispatchers
import kotlinx.coroutines.withContext
@OptIn(ExperimentalMaterial3Api::class)
@Composable
fun PerformanceView(id: Int) {
val context = LocalContext.current
val (performaceWithPeople, setPerformanceWithPeople) = remember { mutableStateOf<PerformanceWithPeople?>(null) }
LaunchedEffect(Unit) {
withContext(Dispatchers.IO) {
setPerformanceWithPeople(AppDatabase.getInstance(context).performanceDao().getByUid(id))
}
}
var actorsText = ""
performaceWithPeople?.actors?.forEach {
if (actorsText != "") actorsText += "\n"
actorsText += "${it.last_name} ${it.first_name}"
}
fun PerformanceView(
viewModel: PerformanceViewModel = viewModel(factory = AppViewModelProvider.Factory)
) {
val performanceWithPeople = viewModel.performanceUiState.performanceDetails;
Column(
horizontalAlignment = Alignment.CenterHorizontally,
modifier = Modifier
.padding(all = 10.dp)
.verticalScroll(rememberScrollState())) {
Text(text = "${performaceWithPeople?.author?.last_name} ${performaceWithPeople?.author?.first_name}", textAlign = TextAlign.Center)
Text(text = performaceWithPeople?.performance?.title ?: "", textAlign = TextAlign.Center, fontSize = 30.sp)
AsyncImage(model = performaceWithPeople?.performance?.imageURL, contentDescription = "performance image")
OutlinedTextField(modifier = Modifier.fillMaxWidth(), value = performaceWithPeople?.performance?.description ?: "", onValueChange = {}, readOnly = true,
.padding(all = 10.dp)) {
Text(text = performanceWithPeople.authorName, textAlign = TextAlign.Center)
Text(text = performanceWithPeople.title, textAlign = TextAlign.Center, fontSize = 30.sp)
AsyncImage(model = performanceWithPeople.imageURL, contentDescription = "performance image")
OutlinedTextField(modifier = Modifier.fillMaxWidth(), value = performanceWithPeople.description, onValueChange = {}, readOnly = true,
label = {
Text(stringResource(id = R.string.performance_description))
}
)
OutlinedTextField(modifier = Modifier.fillMaxWidth(), value = actorsText, onValueChange = {}, readOnly = true,
OutlinedTextField(modifier = Modifier.fillMaxWidth(), value = performanceWithPeople.actorsList, onValueChange = {}, readOnly = true,
label = {
Text(stringResource(id = R.string.performance_actors))
}
@ -85,7 +68,7 @@ fun PerformanceViewPreview() {
Surface(
color = MaterialTheme.colorScheme.background
) {
PerformanceView(id = 0)
PerformanceView()
}
}
}

View File

@ -0,0 +1,60 @@
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.SavedStateHandle
import androidx.lifecycle.ViewModel
import androidx.lifecycle.viewModelScope
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.repository.PerformanceRepository
import kotlinx.coroutines.flow.filterNotNull
import kotlinx.coroutines.flow.first
import kotlinx.coroutines.launch
class PerformanceViewModel(
savedStateHandle: SavedStateHandle,
private val performanceRepository: PerformanceRepository
) : ViewModel() {
var performanceUiState by mutableStateOf(PerformanceUiState())
private set
private val studentUid: Int = checkNotNull(savedStateHandle["id"])
init {
viewModelScope.launch {
if (studentUid > 0) {
performanceUiState = performanceRepository.getPerformance(studentUid)
.filterNotNull()
.first()
.toUiState()
}
}
}
}
data class PerformanceUiState(
val performanceDetails: PerformanceDetails = PerformanceDetails(),
)
data class PerformanceDetails(
val title: String = "",
val authorName: String = "",
val actorsList: String = "",
val imageURL: String = "",
val description: String = ""
)
fun PerformanceWithPeople.toDetails(): PerformanceDetails = PerformanceDetails(
title = performance.title,
authorName = String.format("%s %s", author.last_name, author.first_name),
actorsList = buildString { for (actor in actors) append(actor.last_name + " " + actor.first_name + "\n") },
imageURL = performance.imageURL,
description = performance.description,
)
fun PerformanceWithPeople.toUiState(): PerformanceUiState = PerformanceUiState(
performanceDetails = this.toDetails(),
)

View File

@ -0,0 +1,136 @@
package com.example.mobile_labs.ui.person.list
import android.content.res.Configuration
import androidx.compose.foundation.layout.Column
import androidx.compose.foundation.layout.Row
import androidx.compose.foundation.layout.fillMaxSize
import androidx.compose.foundation.layout.fillMaxWidth
import androidx.compose.foundation.layout.height
import androidx.compose.foundation.layout.padding
import androidx.compose.foundation.layout.width
import androidx.compose.foundation.lazy.LazyColumn
import androidx.compose.foundation.lazy.grid.GridCells
import androidx.compose.foundation.lazy.grid.LazyVerticalGrid
import androidx.compose.foundation.lazy.grid.items
import androidx.compose.foundation.lazy.items
import androidx.compose.foundation.rememberScrollState
import androidx.compose.foundation.verticalScroll
import androidx.compose.material3.Button
import androidx.compose.material3.Card
import androidx.compose.material3.CardDefaults
import androidx.compose.material3.ExperimentalMaterial3Api
import androidx.compose.material3.FloatingActionButton
import androidx.compose.material3.MaterialTheme
import androidx.compose.material3.Scaffold
import androidx.compose.material3.Surface
import androidx.compose.material3.Text
import androidx.compose.runtime.Composable
import androidx.compose.runtime.LaunchedEffect
import androidx.compose.runtime.collectAsState
import androidx.compose.runtime.getValue
import androidx.compose.runtime.mutableStateListOf
import androidx.compose.runtime.remember
import androidx.compose.runtime.rememberCoroutineScope
import androidx.compose.ui.Alignment
import androidx.compose.ui.Modifier
import androidx.compose.ui.layout.ContentScale
import androidx.compose.ui.platform.LocalContext
import androidx.compose.ui.res.stringResource
import androidx.compose.ui.text.style.TextAlign
import androidx.compose.ui.tooling.preview.Preview
import androidx.compose.ui.unit.dp
import androidx.lifecycle.viewmodel.compose.viewModel
import androidx.navigation.NavController
import coil.compose.AsyncImage
import com.example.mobile_labs.R
import com.example.mobile_labs.ui.navigation.Screen
import com.example.mobile_labs.database.AppDatabase
import com.example.mobile_labs.database.event.model.EventWithPerformance
import com.example.mobile_labs.database.person.model.Person
import com.example.mobile_labs.ui.AppViewModelProvider
import com.example.mobile_labs.ui.theme.Mobile_LabsTheme
import kotlinx.coroutines.Dispatchers
import kotlinx.coroutines.withContext
import java.time.LocalDate
import java.time.format.DateTimeFormatter
@Composable
fun PeopleList(
viewModel: PeopleListViewModel = viewModel(factory = AppViewModelProvider.Factory)
) {
val peopleListUiState by viewModel.personListUiState.collectAsState()
Column(
horizontalAlignment = Alignment.CenterHorizontally,
modifier = Modifier
.padding(all = 10.dp)) {
PeopleList(
modifier = Modifier
.fillMaxSize(),
peopleList = peopleListUiState.personList
)
}
}
@OptIn(ExperimentalMaterial3Api::class)
@Composable
private fun PeopleList(
modifier: Modifier = Modifier,
peopleList: List<Person>,
) {
Column(
modifier = modifier
) {
if (peopleList.isEmpty()) {
Text(
text = stringResource(R.string.people_missing_description),
textAlign = TextAlign.Center,
style = MaterialTheme.typography.titleLarge
)
} else {
LazyColumn(modifier = Modifier.padding(all = 10.dp)) {
items(items = peopleList, key = { it.uid !! }) { person ->
PeopleListItem(person = person, modifier = Modifier
.padding(vertical = 7.dp))
}
}
}
}
}
@Composable
private fun PeopleListItem(
person: Person, modifier: Modifier = Modifier
) {
Card(
modifier = modifier.fillMaxWidth(),
elevation = CardDefaults.cardElevation(defaultElevation = 2.dp)
) {
Column(
modifier = modifier.padding(all = 10.dp)
) {
Row {
AsyncImage(model = person.imageURL, contentDescription = "")
Text(
text = String.format("%s %s", person.first_name, person.last_name),
textAlign = TextAlign.Center,
modifier = Modifier.padding(10.dp),
style = MaterialTheme.typography.displaySmall
)
}
}
}
}
@Preview(name = "Light Mode", showBackground = true, uiMode = Configuration.UI_MODE_NIGHT_NO)
@Preview(name = "Dark Mode", showBackground = true, uiMode = Configuration.UI_MODE_NIGHT_YES)
@Composable
fun PeopleListPreview() {
Mobile_LabsTheme {
Surface(
color = MaterialTheme.colorScheme.background
) {
PeopleList(peopleList = listOf())
}
}
}

View File

@ -0,0 +1,25 @@
package com.example.mobile_labs.ui.person.list
import androidx.lifecycle.ViewModel
import androidx.lifecycle.viewModelScope
import com.example.mobile_labs.database.AppDataContainer
import com.example.mobile_labs.database.person.model.Person
import com.example.mobile_labs.database.person.repository.PersonRepository
import kotlinx.coroutines.flow.SharingStarted
import kotlinx.coroutines.flow.StateFlow
import kotlinx.coroutines.flow.map
import kotlinx.coroutines.flow.stateIn
class PeopleListViewModel(
private val personRepository: PersonRepository
) : ViewModel() {
val personListUiState: StateFlow<PersonListUiState> = personRepository.getAllPeople().map {
PersonListUiState(it)
}.stateIn(
scope = viewModelScope,
started = SharingStarted.WhileSubscribed(stopTimeoutMillis = AppDataContainer.TIMEOUT),
initialValue = PersonListUiState()
)
}
data class PersonListUiState(val personList: List<Person> = listOf())

View File

@ -5,7 +5,7 @@ import androidx.room.Delete
import androidx.room.Insert
import androidx.room.Query
import androidx.room.Update
import com.example.mobile_labs.person.model.Person
import com.example.mobile_labs.database.person.model.Person
import com.example.mobile_labs.user.model.User
import kotlinx.coroutines.flow.Flow

View File

@ -9,6 +9,9 @@
<string name="people_main_title">Люди театра</string>
<string name="about_main_title">О нас</string>
<string name="performance_view_main_title">Представление</string>
<string name="people_missing_description">Данные о людях отсутствуют</string>
<string name="events_missing_description">Данные о событиях отсутствуют</string>
<string name="performance_missing_description">Данные о представлениях отсутствуют</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!