Lab 04
This commit is contained in:
parent
16257cf1b6
commit
7707836c12
@ -14,6 +14,7 @@
|
|||||||
android:roundIcon="@mipmap/ic_launcher_round"
|
android:roundIcon="@mipmap/ic_launcher_round"
|
||||||
android:supportsRtl="true"
|
android:supportsRtl="true"
|
||||||
android:theme="@style/Theme.Mobile_Labs"
|
android:theme="@style/Theme.Mobile_Labs"
|
||||||
|
android:name=".TheatreApplication"
|
||||||
tools:targetApi="31">
|
tools:targetApi="31">
|
||||||
<activity
|
<activity
|
||||||
android:name=".MainActivity"
|
android:name=".MainActivity"
|
||||||
|
@ -10,7 +10,7 @@ import androidx.compose.material3.Text
|
|||||||
import androidx.compose.runtime.Composable
|
import androidx.compose.runtime.Composable
|
||||||
import androidx.compose.ui.Modifier
|
import androidx.compose.ui.Modifier
|
||||||
import androidx.compose.ui.tooling.preview.Preview
|
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
|
import com.example.mobile_labs.ui.theme.Mobile_LabsTheme
|
||||||
|
|
||||||
class MainActivity : ComponentActivity() {
|
class MainActivity : ComponentActivity() {
|
||||||
|
@ -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)
|
||||||
|
}
|
||||||
|
}
|
@ -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
|
||||||
|
}
|
||||||
|
}
|
@ -5,14 +5,14 @@ import androidx.room.Database
|
|||||||
import androidx.room.Room
|
import androidx.room.Room
|
||||||
import androidx.room.RoomDatabase
|
import androidx.room.RoomDatabase
|
||||||
import androidx.sqlite.db.SupportSQLiteDatabase
|
import androidx.sqlite.db.SupportSQLiteDatabase
|
||||||
import com.example.mobile_labs.event.dao.EventDao
|
import com.example.mobile_labs.database.event.dao.EventDao
|
||||||
import com.example.mobile_labs.event.model.Event
|
import com.example.mobile_labs.database.event.model.Event
|
||||||
import com.example.mobile_labs.performance.dao.PerformanceDao
|
import com.example.mobile_labs.database.performance.dao.PerformanceDao
|
||||||
import com.example.mobile_labs.performance.dao.PerformancePersonDao
|
import com.example.mobile_labs.database.performance.dao.PerformancePersonDao
|
||||||
import com.example.mobile_labs.performance.model.Performance
|
import com.example.mobile_labs.database.performance.model.Performance
|
||||||
import com.example.mobile_labs.performance.model.PerformancePersonCrossRef
|
import com.example.mobile_labs.database.performance.model.PerformancePersonCrossRef
|
||||||
import com.example.mobile_labs.person.dao.PersonDao
|
import com.example.mobile_labs.database.person.dao.PersonDao
|
||||||
import com.example.mobile_labs.person.model.Person
|
import com.example.mobile_labs.database.person.model.Person
|
||||||
import com.example.mobile_labs.user.dao.UserDao
|
import com.example.mobile_labs.user.dao.UserDao
|
||||||
import com.example.mobile_labs.user.model.User
|
import com.example.mobile_labs.user.model.User
|
||||||
import kotlinx.coroutines.CoroutineScope
|
import kotlinx.coroutines.CoroutineScope
|
||||||
|
@ -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.Dao
|
||||||
import androidx.room.Delete
|
import androidx.room.Delete
|
||||||
import androidx.room.Insert
|
import androidx.room.Insert
|
||||||
import androidx.room.Query
|
import androidx.room.Query
|
||||||
import androidx.room.Update
|
import androidx.room.Update
|
||||||
import com.example.mobile_labs.event.model.Event
|
import com.example.mobile_labs.database.event.model.Event
|
||||||
import com.example.mobile_labs.event.model.EventWithPerformance
|
import com.example.mobile_labs.database.event.model.EventWithPerformance
|
||||||
import com.example.mobile_labs.performance.model.Performance
|
import com.example.mobile_labs.database.performance.model.Performance
|
||||||
import kotlinx.coroutines.flow.Flow
|
import kotlinx.coroutines.flow.Flow
|
||||||
|
|
||||||
@Dao
|
@Dao
|
||||||
@ -19,7 +19,7 @@ interface EventDao {
|
|||||||
fun getAllWithPerformance(dateFrom: String): Flow<List<EventWithPerformance>>
|
fun getAllWithPerformance(dateFrom: String): Flow<List<EventWithPerformance>>
|
||||||
|
|
||||||
@Query("select * from events where events.uid = :uid")
|
@Query("select * from events where events.uid = :uid")
|
||||||
suspend fun getByUid(uid: Int): EventWithPerformance
|
fun getByUid(uid: Int): Flow<EventWithPerformance>
|
||||||
|
|
||||||
@Insert
|
@Insert
|
||||||
suspend fun insert(event: Event)
|
suspend fun insert(event: Event)
|
@ -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.ColumnInfo
|
||||||
import androidx.room.Entity
|
import androidx.room.Entity
|
||||||
@ -7,8 +7,8 @@ import androidx.room.PrimaryKey
|
|||||||
import androidx.room.TypeConverter
|
import androidx.room.TypeConverter
|
||||||
import androidx.room.TypeConverters
|
import androidx.room.TypeConverters
|
||||||
import com.example.mobile_labs.converters.LocalDateConverter
|
import com.example.mobile_labs.converters.LocalDateConverter
|
||||||
import com.example.mobile_labs.performance.model.Performance
|
import com.example.mobile_labs.database.performance.model.Performance
|
||||||
import com.example.mobile_labs.person.model.Person
|
import com.example.mobile_labs.database.person.model.Person
|
||||||
import java.io.Serializable
|
import java.io.Serializable
|
||||||
import java.time.LocalDate
|
import java.time.LocalDate
|
||||||
|
|
@ -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.Embedded
|
||||||
import androidx.room.Relation
|
import androidx.room.Relation
|
||||||
import com.example.mobile_labs.performance.model.Performance
|
import com.example.mobile_labs.database.performance.model.Performance
|
||||||
|
|
||||||
data class EventWithPerformance (
|
data class EventWithPerformance (
|
||||||
@Embedded
|
@Embedded
|
@ -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)
|
||||||
|
}
|
@ -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);
|
||||||
|
}
|
@ -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.Dao
|
||||||
import androidx.room.Delete
|
import androidx.room.Delete
|
||||||
import androidx.room.Insert
|
import androidx.room.Insert
|
||||||
import androidx.room.Query
|
import androidx.room.Query
|
||||||
import androidx.room.Update
|
import androidx.room.Update
|
||||||
import com.example.mobile_labs.performance.model.Performance
|
import com.example.mobile_labs.database.performance.model.Performance
|
||||||
import com.example.mobile_labs.performance.model.PerformanceWithPeople
|
import com.example.mobile_labs.database.performance.model.PerformanceWithPeople
|
||||||
import com.example.mobile_labs.person.model.Person
|
import com.example.mobile_labs.database.person.model.Person
|
||||||
import kotlinx.coroutines.flow.Flow
|
import kotlinx.coroutines.flow.Flow
|
||||||
|
|
||||||
@Dao
|
@Dao
|
||||||
@ -16,7 +16,7 @@ interface PerformanceDao {
|
|||||||
fun getAll(): Flow<List<Performance>>
|
fun getAll(): Flow<List<Performance>>
|
||||||
|
|
||||||
@Query("select * from performances where performances.performance_uid = :uid")
|
@Query("select * from performances where performances.performance_uid = :uid")
|
||||||
suspend fun getByUid(uid: Int): PerformanceWithPeople
|
fun getByUid(uid: Int): Flow<PerformanceWithPeople>
|
||||||
|
|
||||||
@Insert
|
@Insert
|
||||||
suspend fun insert(performance: Performance)
|
suspend fun insert(performance: Performance)
|
@ -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.Dao
|
||||||
import androidx.room.Delete
|
import androidx.room.Delete
|
||||||
import androidx.room.Insert
|
import androidx.room.Insert
|
||||||
import androidx.room.Query
|
import androidx.room.Query
|
||||||
import androidx.room.Update
|
import androidx.room.Update
|
||||||
import com.example.mobile_labs.performance.model.Performance
|
import com.example.mobile_labs.database.performance.model.Performance
|
||||||
import com.example.mobile_labs.performance.model.PerformancePersonCrossRef
|
import com.example.mobile_labs.database.performance.model.PerformancePersonCrossRef
|
||||||
import com.example.mobile_labs.performance.model.PerformanceWithPeople
|
import com.example.mobile_labs.database.performance.model.PerformanceWithPeople
|
||||||
import kotlinx.coroutines.flow.Flow
|
import kotlinx.coroutines.flow.Flow
|
||||||
|
|
||||||
@Dao
|
@Dao
|
@ -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.ColumnInfo
|
||||||
import androidx.room.Entity
|
import androidx.room.Entity
|
||||||
import androidx.room.ForeignKey
|
import androidx.room.ForeignKey
|
||||||
import androidx.room.PrimaryKey
|
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
|
import java.io.Serializable
|
||||||
|
|
||||||
@Entity(tableName = "performances", foreignKeys = [
|
@Entity(tableName = "performances", foreignKeys = [
|
@ -1,4 +1,4 @@
|
|||||||
package com.example.mobile_labs.performance.model
|
package com.example.mobile_labs.database.performance.model
|
||||||
|
|
||||||
import androidx.room.Entity
|
import androidx.room.Entity
|
||||||
|
|
@ -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.ColumnInfo
|
||||||
import androidx.room.Embedded
|
import androidx.room.Embedded
|
||||||
import androidx.room.Junction
|
import androidx.room.Junction
|
||||||
import androidx.room.Relation
|
import androidx.room.Relation
|
||||||
import com.example.mobile_labs.person.model.Person
|
import com.example.mobile_labs.database.person.model.Person
|
||||||
|
|
||||||
data class PerformanceWithPeople (
|
data class PerformanceWithPeople (
|
||||||
@Embedded
|
@Embedded
|
@ -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);
|
||||||
|
}
|
@ -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)
|
||||||
|
}
|
@ -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.Dao
|
||||||
import androidx.room.Delete
|
import androidx.room.Delete
|
||||||
import androidx.room.Insert
|
import androidx.room.Insert
|
||||||
import androidx.room.Query
|
import androidx.room.Query
|
||||||
import androidx.room.Update
|
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
|
import kotlinx.coroutines.flow.Flow
|
||||||
|
|
||||||
@Dao
|
@Dao
|
||||||
@ -14,7 +14,7 @@ interface PersonDao {
|
|||||||
fun getAll(): Flow<List<Person>>
|
fun getAll(): Flow<List<Person>>
|
||||||
|
|
||||||
@Query("select * from people where people.uid = :uid")
|
@Query("select * from people where people.uid = :uid")
|
||||||
suspend fun getByUid(uid: Int): Person
|
fun getByUid(uid: Int): Flow<Person>
|
||||||
|
|
||||||
@Insert
|
@Insert
|
||||||
suspend fun insert(person: Person)
|
suspend fun insert(person: Person)
|
@ -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.ColumnInfo
|
||||||
import androidx.room.Entity
|
import androidx.room.Entity
|
@ -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);
|
||||||
|
|
||||||
|
}
|
@ -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)
|
||||||
|
}
|
@ -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)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
@ -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)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
@ -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)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
@ -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)
|
@ -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.content.res.Configuration
|
||||||
import android.net.Uri
|
|
||||||
import android.widget.TextView
|
import android.widget.TextView
|
||||||
import androidx.compose.foundation.clickable
|
|
||||||
import androidx.compose.foundation.layout.Column
|
import androidx.compose.foundation.layout.Column
|
||||||
import androidx.compose.foundation.layout.Spacer
|
|
||||||
import androidx.compose.foundation.layout.fillMaxWidth
|
import androidx.compose.foundation.layout.fillMaxWidth
|
||||||
import androidx.compose.foundation.layout.padding
|
import androidx.compose.foundation.layout.padding
|
||||||
|
|
@ -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 = {})
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
@ -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())
|
@ -1,4 +1,4 @@
|
|||||||
package com.example.mobile_labs.composeui.navigation
|
package com.example.mobile_labs.ui.navigation
|
||||||
|
|
||||||
import android.content.res.Configuration
|
import android.content.res.Configuration
|
||||||
import androidx.compose.foundation.layout.PaddingValues
|
import androidx.compose.foundation.layout.PaddingValues
|
||||||
@ -33,11 +33,11 @@ import androidx.navigation.compose.rememberNavController
|
|||||||
import androidx.navigation.navArgument
|
import androidx.navigation.navArgument
|
||||||
import com.example.mobile_labs.ui.theme.Mobile_LabsTheme
|
import com.example.mobile_labs.ui.theme.Mobile_LabsTheme
|
||||||
import com.example.mobile_labs.R
|
import com.example.mobile_labs.R
|
||||||
import com.example.mobile_labs.composeui.About
|
import com.example.mobile_labs.ui.about.About
|
||||||
import com.example.mobile_labs.event.composeui.Schedule
|
import com.example.mobile_labs.ui.event.list.EventList
|
||||||
import com.example.mobile_labs.performance.composeui.PerformanceView
|
import com.example.mobile_labs.ui.performance.list.PerformanceList
|
||||||
import com.example.mobile_labs.performance.composeui.Repertoire
|
import com.example.mobile_labs.ui.performance.view.PerformanceView
|
||||||
import com.example.mobile_labs.person.composeui.PeopleList
|
import com.example.mobile_labs.ui.person.list.PeopleList
|
||||||
|
|
||||||
@OptIn(ExperimentalMaterial3Api::class)
|
@OptIn(ExperimentalMaterial3Api::class)
|
||||||
@Composable
|
@Composable
|
||||||
@ -107,15 +107,15 @@ fun Navhost(
|
|||||||
startDestination = Screen.Schedule.route,
|
startDestination = Screen.Schedule.route,
|
||||||
modifier.padding(innerPadding)
|
modifier.padding(innerPadding)
|
||||||
) {
|
) {
|
||||||
composable(Screen.Schedule.route) { Schedule(navController) }
|
composable(Screen.Schedule.route) { EventList(navController) }
|
||||||
composable(Screen.Repertoire.route) { Repertoire(navController) }
|
composable(Screen.Repertoire.route) { PerformanceList(navController) }
|
||||||
composable(Screen.PeopleList.route) { PeopleList(navController) }
|
composable(Screen.PeopleList.route) { PeopleList() }
|
||||||
composable(Screen.About.route) { About() }
|
composable(Screen.About.route) { About() }
|
||||||
composable(
|
composable(
|
||||||
Screen.PerformanceView.route,
|
Screen.PerformanceView.route,
|
||||||
arguments = listOf(navArgument("id") { type = NavType.IntType })
|
arguments = listOf(navArgument("id") { type = NavType.IntType })
|
||||||
) { backStackEntry ->
|
) { backStackEntry ->
|
||||||
backStackEntry.arguments?.let { PerformanceView(it.getInt("id")) }
|
backStackEntry.arguments?.let { PerformanceView() }
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
@ -1,4 +1,4 @@
|
|||||||
package com.example.mobile_labs.composeui.navigation
|
package com.example.mobile_labs.ui.navigation
|
||||||
|
|
||||||
import androidx.annotation.StringRes
|
import androidx.annotation.StringRes
|
||||||
import androidx.compose.material.icons.Icons
|
import androidx.compose.material.icons.Icons
|
@ -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 = {})
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
@ -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())
|
@ -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 android.content.res.Configuration
|
||||||
import androidx.compose.foundation.layout.Column
|
import androidx.compose.foundation.layout.Column
|
||||||
import androidx.compose.foundation.layout.Row
|
|
||||||
import androidx.compose.foundation.layout.fillMaxWidth
|
import androidx.compose.foundation.layout.fillMaxWidth
|
||||||
import androidx.compose.foundation.layout.height
|
|
||||||
import androidx.compose.foundation.layout.padding
|
import androidx.compose.foundation.layout.padding
|
||||||
import androidx.compose.foundation.layout.width
|
|
||||||
import androidx.compose.foundation.rememberScrollState
|
import androidx.compose.foundation.rememberScrollState
|
||||||
import androidx.compose.foundation.verticalScroll
|
|
||||||
import androidx.compose.material3.Button
|
|
||||||
import androidx.compose.material3.ExperimentalMaterial3Api
|
import androidx.compose.material3.ExperimentalMaterial3Api
|
||||||
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.LaunchedEffect
|
import androidx.compose.runtime.LaunchedEffect
|
||||||
import androidx.compose.runtime.getValue
|
|
||||||
import androidx.compose.runtime.mutableStateOf
|
import androidx.compose.runtime.mutableStateOf
|
||||||
import androidx.compose.runtime.remember
|
import androidx.compose.runtime.remember
|
||||||
import androidx.compose.runtime.setValue
|
import androidx.compose.runtime.rememberCoroutineScope
|
||||||
import androidx.compose.ui.Alignment
|
import androidx.compose.ui.Alignment
|
||||||
import androidx.compose.ui.Modifier
|
import androidx.compose.ui.Modifier
|
||||||
import androidx.compose.ui.layout.ContentScale
|
|
||||||
import androidx.compose.ui.platform.LocalContext
|
import androidx.compose.ui.platform.LocalContext
|
||||||
import androidx.compose.ui.res.stringResource
|
import androidx.compose.ui.res.stringResource
|
||||||
import androidx.compose.ui.text.style.TextAlign
|
import androidx.compose.ui.text.style.TextAlign
|
||||||
import androidx.compose.ui.tooling.preview.Preview
|
import androidx.compose.ui.tooling.preview.Preview
|
||||||
import androidx.compose.ui.unit.dp
|
import androidx.compose.ui.unit.dp
|
||||||
import androidx.compose.ui.unit.sp
|
import androidx.compose.ui.unit.sp
|
||||||
|
import androidx.lifecycle.viewmodel.compose.viewModel
|
||||||
import androidx.navigation.NavController
|
import androidx.navigation.NavController
|
||||||
import coil.compose.AsyncImage
|
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.R
|
||||||
import com.example.mobile_labs.database.AppDatabase
|
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.Dispatchers
|
||||||
import kotlinx.coroutines.withContext
|
import kotlinx.coroutines.withContext
|
||||||
|
|
||||||
@OptIn(ExperimentalMaterial3Api::class)
|
@OptIn(ExperimentalMaterial3Api::class)
|
||||||
@Composable
|
@Composable
|
||||||
fun PerformanceView(id: Int) {
|
fun PerformanceView(
|
||||||
val context = LocalContext.current
|
viewModel: PerformanceViewModel = viewModel(factory = AppViewModelProvider.Factory)
|
||||||
val (performaceWithPeople, setPerformanceWithPeople) = remember { mutableStateOf<PerformanceWithPeople?>(null) }
|
) {
|
||||||
LaunchedEffect(Unit) {
|
val performanceWithPeople = viewModel.performanceUiState.performanceDetails;
|
||||||
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}"
|
|
||||||
}
|
|
||||||
Column(
|
Column(
|
||||||
horizontalAlignment = Alignment.CenterHorizontally,
|
horizontalAlignment = Alignment.CenterHorizontally,
|
||||||
modifier = Modifier
|
modifier = Modifier
|
||||||
.padding(all = 10.dp)
|
.padding(all = 10.dp)) {
|
||||||
.verticalScroll(rememberScrollState())) {
|
Text(text = performanceWithPeople.authorName, textAlign = TextAlign.Center)
|
||||||
Text(text = "${performaceWithPeople?.author?.last_name} ${performaceWithPeople?.author?.first_name}", textAlign = TextAlign.Center)
|
Text(text = performanceWithPeople.title, textAlign = TextAlign.Center, fontSize = 30.sp)
|
||||||
Text(text = performaceWithPeople?.performance?.title ?: "", textAlign = TextAlign.Center, fontSize = 30.sp)
|
AsyncImage(model = performanceWithPeople.imageURL, contentDescription = "performance image")
|
||||||
AsyncImage(model = performaceWithPeople?.performance?.imageURL, contentDescription = "performance image")
|
OutlinedTextField(modifier = Modifier.fillMaxWidth(), value = performanceWithPeople.description, onValueChange = {}, readOnly = true,
|
||||||
OutlinedTextField(modifier = Modifier.fillMaxWidth(), value = performaceWithPeople?.performance?.description ?: "", onValueChange = {}, readOnly = true,
|
|
||||||
label = {
|
label = {
|
||||||
Text(stringResource(id = R.string.performance_description))
|
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 = {
|
label = {
|
||||||
Text(stringResource(id = R.string.performance_actors))
|
Text(stringResource(id = R.string.performance_actors))
|
||||||
}
|
}
|
||||||
@ -85,7 +68,7 @@ fun PerformanceViewPreview() {
|
|||||||
Surface(
|
Surface(
|
||||||
color = MaterialTheme.colorScheme.background
|
color = MaterialTheme.colorScheme.background
|
||||||
) {
|
) {
|
||||||
PerformanceView(id = 0)
|
PerformanceView()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
@ -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(),
|
||||||
|
)
|
@ -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())
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
@ -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())
|
@ -5,7 +5,7 @@ import androidx.room.Delete
|
|||||||
import androidx.room.Insert
|
import androidx.room.Insert
|
||||||
import androidx.room.Query
|
import androidx.room.Query
|
||||||
import androidx.room.Update
|
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 com.example.mobile_labs.user.model.User
|
||||||
import kotlinx.coroutines.flow.Flow
|
import kotlinx.coroutines.flow.Flow
|
||||||
|
|
||||||
|
@ -9,6 +9,9 @@
|
|||||||
<string name="people_main_title">Люди театра</string>
|
<string name="people_main_title">Люди театра</string>
|
||||||
<string name="about_main_title">О нас</string>
|
<string name="about_main_title">О нас</string>
|
||||||
<string name="performance_view_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">
|
<string name="about_text">
|
||||||
<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!
|
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!
|
||||||
|
Loading…
Reference in New Issue
Block a user