Third lab
This commit is contained in:
parent
5a820b661e
commit
16257cf1b6
@ -1,6 +1,6 @@
|
|||||||
<?xml version="1.0" encoding="UTF-8"?>
|
<?xml version="1.0" encoding="UTF-8"?>
|
||||||
<project version="4">
|
<project version="4">
|
||||||
<component name="KotlinJpsPluginSettings">
|
<component name="KotlinJpsPluginSettings">
|
||||||
<option name="version" value="1.8.10" />
|
<option name="version" value="1.8.20" />
|
||||||
</component>
|
</component>
|
||||||
</project>
|
</project>
|
@ -1,6 +1,7 @@
|
|||||||
plugins {
|
plugins {
|
||||||
id("com.android.application")
|
id("com.android.application")
|
||||||
id("org.jetbrains.kotlin.android")
|
id("org.jetbrains.kotlin.android")
|
||||||
|
id("com.google.devtools.ksp")
|
||||||
}
|
}
|
||||||
|
|
||||||
android {
|
android {
|
||||||
@ -30,17 +31,17 @@ android {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
compileOptions {
|
compileOptions {
|
||||||
sourceCompatibility = JavaVersion.VERSION_1_8
|
sourceCompatibility = JavaVersion.VERSION_17
|
||||||
targetCompatibility = JavaVersion.VERSION_1_8
|
targetCompatibility = JavaVersion.VERSION_17
|
||||||
}
|
}
|
||||||
kotlinOptions {
|
kotlinOptions {
|
||||||
jvmTarget = "1.8"
|
jvmTarget = "17"
|
||||||
}
|
}
|
||||||
buildFeatures {
|
buildFeatures {
|
||||||
compose = true
|
compose = true
|
||||||
}
|
}
|
||||||
composeOptions {
|
composeOptions {
|
||||||
kotlinCompilerExtensionVersion = "1.4.3"
|
kotlinCompilerExtensionVersion = "1.4.5"
|
||||||
}
|
}
|
||||||
packaging {
|
packaging {
|
||||||
resources {
|
resources {
|
||||||
@ -48,11 +49,16 @@ android {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
kotlin {
|
||||||
|
jvmToolchain(17)
|
||||||
|
}
|
||||||
|
|
||||||
dependencies {
|
dependencies {
|
||||||
|
//Core
|
||||||
implementation("androidx.core:core-ktx:1.9.0")
|
implementation("androidx.core:core-ktx:1.9.0")
|
||||||
implementation("androidx.lifecycle:lifecycle-runtime-ktx:2.6.2")
|
implementation("androidx.lifecycle:lifecycle-runtime-ktx:2.6.2")
|
||||||
|
|
||||||
|
//UI
|
||||||
implementation("androidx.activity:activity-compose:1.7.2")
|
implementation("androidx.activity:activity-compose:1.7.2")
|
||||||
implementation(platform("androidx.compose:compose-bom:2023.03.00"))
|
implementation(platform("androidx.compose:compose-bom:2023.03.00"))
|
||||||
implementation("androidx.navigation:navigation-compose:2.6.0")
|
implementation("androidx.navigation:navigation-compose:2.6.0")
|
||||||
@ -61,6 +67,16 @@ dependencies {
|
|||||||
implementation("androidx.compose.ui:ui-graphics")
|
implementation("androidx.compose.ui:ui-graphics")
|
||||||
implementation("androidx.compose.ui:ui-tooling-preview")
|
implementation("androidx.compose.ui:ui-tooling-preview")
|
||||||
implementation("androidx.compose.material3:material3")
|
implementation("androidx.compose.material3:material3")
|
||||||
|
|
||||||
|
// Room
|
||||||
|
val room_version = "2.5.2"
|
||||||
|
implementation("androidx.room:room-runtime:$room_version")
|
||||||
|
annotationProcessor("androidx.room:room-compiler:$room_version")
|
||||||
|
ksp("androidx.room:room-compiler:$room_version")
|
||||||
|
implementation("androidx.room:room-ktx:$room_version")
|
||||||
|
implementation("androidx.room:room-paging:$room_version")
|
||||||
|
|
||||||
|
//Tests
|
||||||
testImplementation("junit:junit:4.13.2")
|
testImplementation("junit:junit:4.13.2")
|
||||||
androidTestImplementation("androidx.test.ext:junit:1.1.5")
|
androidTestImplementation("androidx.test.ext:junit:1.1.5")
|
||||||
androidTestImplementation("androidx.test.espresso:espresso-core:3.5.1")
|
androidTestImplementation("androidx.test.espresso:espresso-core:3.5.1")
|
||||||
|
@ -0,0 +1,24 @@
|
|||||||
|
package com.example.mobile_labs.converters
|
||||||
|
|
||||||
|
import androidx.room.TypeConverter
|
||||||
|
import java.time.LocalDate
|
||||||
|
import java.time.LocalDateTime
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
class LocalDateConverter {
|
||||||
|
@TypeConverter
|
||||||
|
fun toDate(dateString: String?): LocalDate? {
|
||||||
|
return if (dateString == null) {
|
||||||
|
null
|
||||||
|
} else {
|
||||||
|
LocalDate.parse(dateString)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@TypeConverter
|
||||||
|
fun toDateString(date: LocalDate?): String? {
|
||||||
|
return date?.toString()
|
||||||
|
}
|
||||||
|
}
|
@ -0,0 +1,118 @@
|
|||||||
|
package com.example.mobile_labs.database
|
||||||
|
|
||||||
|
import android.content.Context
|
||||||
|
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.user.dao.UserDao
|
||||||
|
import com.example.mobile_labs.user.model.User
|
||||||
|
import kotlinx.coroutines.CoroutineScope
|
||||||
|
import kotlinx.coroutines.Dispatchers
|
||||||
|
import kotlinx.coroutines.launch
|
||||||
|
import java.time.LocalDate
|
||||||
|
|
||||||
|
@Database(entities = [Performance::class, Person::class, Event::class, PerformancePersonCrossRef::class, User::class], version = 1, exportSchema = false)
|
||||||
|
abstract class AppDatabase : RoomDatabase() {
|
||||||
|
abstract fun personDao(): PersonDao
|
||||||
|
abstract fun performanceDao(): PerformanceDao
|
||||||
|
abstract fun eventDao(): EventDao
|
||||||
|
abstract fun performancePersonDao(): PerformancePersonDao
|
||||||
|
abstract fun userDao(): UserDao
|
||||||
|
|
||||||
|
companion object {
|
||||||
|
private const val DB_NAME: String = "theatre-db"
|
||||||
|
|
||||||
|
@Volatile
|
||||||
|
private var INSTANCE: AppDatabase? = null
|
||||||
|
|
||||||
|
private suspend fun populateDatabase() {
|
||||||
|
INSTANCE?.let { database ->
|
||||||
|
//people
|
||||||
|
val personDao = database.personDao()
|
||||||
|
val person1 = Person(1, "Иванов", "Иван", "https://bolshoi.ru/media/members/photos/86_ru_twyyatusbnifnzi_300x300_p.jpg")
|
||||||
|
val person2 = Person(2, "Ксения", "Дудникова", "https://bolshoi.ru/media/members/photos/1756_ru_wkznwzklgosnbiq_300x300_p.jpg")
|
||||||
|
val person3 = Person(3, "Евгения", "Сегенюк", "https://bolshoi.ru/media/members/photos/2908_ru_rycynrihdpzvgdj_300x300_p.jpg")
|
||||||
|
val person4 = Person(4, "Петров", "Петр", "https://bolshoi.ru/media/members/photos/15820_ru_zvewuwadyjuywkh_300x300_p.jpg")
|
||||||
|
|
||||||
|
personDao.insert(person1)
|
||||||
|
personDao.insert(person2)
|
||||||
|
personDao.insert(person3)
|
||||||
|
personDao.insert(person4)
|
||||||
|
|
||||||
|
val performanceDao = database.performanceDao()
|
||||||
|
val performance1 = Performance(1, "Представление 1", "Описание представления 1", 1, 2, "https://img.freepik.com/free-photo/empty-stage-with-few-props-red-seats_181624-57595.jpg?w=1380&t=st=1696959739~exp=1696960339~hmac=2107448a1d874f1315b5cf246c71df70dc653707c7c8be4a38581d3b73f842ba", "https://www.theatreinparis.com/uploads/images/article/theatre-de-l-athenee-dr.jpg")
|
||||||
|
val performance2 = Performance(2, "Представление 2", "Описание представления 2", 2, 3, "https://img.freepik.com/free-photo/empty-stage-with-few-props-red-seats_181624-57595.jpg?w=1380&t=st=1696959739~exp=1696960339~hmac=2107448a1d874f1315b5cf246c71df70dc653707c7c8be4a38581d3b73f842ba", "https://www.theatreinparis.com/uploads/images/article/theatre-de-l-athenee-dr.jpg")
|
||||||
|
val performance3 = Performance(3, "Представление 3", "Описание представления 1", 3, 4, "https://img.freepik.com/free-photo/empty-stage-with-few-props-red-seats_181624-57595.jpg?w=1380&t=st=1696959739~exp=1696960339~hmac=2107448a1d874f1315b5cf246c71df70dc653707c7c8be4a38581d3b73f842ba", "https://www.theatreinparis.com/uploads/images/article/theatre-de-l-athenee-dr.jpg")
|
||||||
|
|
||||||
|
performanceDao.insert(performance1)
|
||||||
|
performanceDao.insert(performance2)
|
||||||
|
performanceDao.insert(performance3)
|
||||||
|
|
||||||
|
val performancePersonDao = database.performancePersonDao()
|
||||||
|
val performancePerson1 = PerformancePersonCrossRef(1, 1)
|
||||||
|
val performancePerson2 = PerformancePersonCrossRef(1, 2)
|
||||||
|
val performancePerson3 = PerformancePersonCrossRef(1, 3)
|
||||||
|
val performancePerson4 = PerformancePersonCrossRef(1, 4)
|
||||||
|
|
||||||
|
performancePersonDao.insert(performancePerson1)
|
||||||
|
performancePersonDao.insert(performancePerson2)
|
||||||
|
performancePersonDao.insert(performancePerson3)
|
||||||
|
performancePersonDao.insert(performancePerson4)
|
||||||
|
|
||||||
|
val eventDao = database.eventDao()
|
||||||
|
val event1 = Event(1, LocalDate.parse("2023-10-23"), 1)
|
||||||
|
val event2 = Event(2, LocalDate.parse("2023-10-11"), 2)
|
||||||
|
val event3 = Event(3, LocalDate.parse("2023-10-15"), 3)
|
||||||
|
val event4 = Event(4, LocalDate.parse("2023-10-27"), 1)
|
||||||
|
val event5 = Event(5, LocalDate.parse("2023-10-03"), 2)
|
||||||
|
val event6 = Event(6, LocalDate.parse("2023-10-09"), 3)
|
||||||
|
val event7 = Event(7, LocalDate.parse("2023-11-03"), 2)
|
||||||
|
val event8 = Event(8, LocalDate.parse("2023-11-09"), 3)
|
||||||
|
|
||||||
|
eventDao.insert(event1)
|
||||||
|
eventDao.insert(event2)
|
||||||
|
eventDao.insert(event3)
|
||||||
|
eventDao.insert(event4)
|
||||||
|
eventDao.insert(event5)
|
||||||
|
eventDao.insert(event6)
|
||||||
|
eventDao.insert(event7)
|
||||||
|
eventDao.insert(event8)
|
||||||
|
|
||||||
|
val userDao = database.userDao()
|
||||||
|
val user1 = User(1, "test@example.com", "1234", "John", "Doe")
|
||||||
|
val user2 = User(2, "test@example.com", "1234", "John", "Doe")
|
||||||
|
userDao.insert(user1)
|
||||||
|
userDao.insert(user2)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
fun getInstance(appContext: Context): AppDatabase {
|
||||||
|
return INSTANCE ?: synchronized(this) {
|
||||||
|
Room.databaseBuilder(
|
||||||
|
appContext,
|
||||||
|
AppDatabase::class.java,
|
||||||
|
DB_NAME
|
||||||
|
)
|
||||||
|
.addCallback(object : RoomDatabase.Callback() {
|
||||||
|
override fun onCreate(db: SupportSQLiteDatabase) {
|
||||||
|
super.onCreate(db)
|
||||||
|
CoroutineScope(Dispatchers.IO).launch {
|
||||||
|
populateDatabase()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
})
|
||||||
|
.build()
|
||||||
|
.also { INSTANCE = it }
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
@ -15,30 +15,51 @@ import androidx.compose.material3.MaterialTheme
|
|||||||
import androidx.compose.material3.Surface
|
import androidx.compose.material3.Surface
|
||||||
import androidx.compose.material3.Text
|
import androidx.compose.material3.Text
|
||||||
import androidx.compose.runtime.Composable
|
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.Alignment
|
||||||
import androidx.compose.ui.Modifier
|
import androidx.compose.ui.Modifier
|
||||||
import androidx.compose.ui.layout.ContentScale
|
import androidx.compose.ui.layout.ContentScale
|
||||||
|
import androidx.compose.ui.platform.LocalContext
|
||||||
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.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.composeui.navigation.Screen
|
||||||
import com.example.mobile_labs.event.model.getTestEvents
|
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 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.time.format.DateTimeFormatter
|
||||||
|
import java.util.Calendar
|
||||||
|
|
||||||
@Composable
|
@Composable
|
||||||
fun Schedule(navController: NavController?) {
|
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(
|
Column(
|
||||||
horizontalAlignment = Alignment.CenterHorizontally,
|
horizontalAlignment = Alignment.CenterHorizontally,
|
||||||
modifier = Modifier
|
modifier = Modifier
|
||||||
.padding(all = 10.dp)
|
.padding(all = 10.dp)
|
||||||
.verticalScroll(rememberScrollState())) {
|
.verticalScroll(rememberScrollState())) {
|
||||||
getTestEvents().forEachIndexed() { _, event ->
|
events.forEachIndexed() { _, event ->
|
||||||
val performanceId = Screen.PerformanceView.route.replace("{id}", event.performance.id.toString())
|
val performanceId = Screen.PerformanceView.route.replace("{id}", event.performance.performance_uid.toString())
|
||||||
Row(Modifier.padding(all = 10.dp)) {
|
Row(Modifier.padding(all = 10.dp)) {
|
||||||
Text(modifier = Modifier.padding(all = 5.dp), textAlign = TextAlign.Center, text = event.date.format(DateTimeFormatter.ofPattern("dd.MM")))
|
Text(modifier = Modifier.padding(all = 5.dp), textAlign = TextAlign.Center, text = event.event.date.format(DateTimeFormatter.ofPattern("dd.MM")))
|
||||||
AsyncImage(model = event.performance.previewImageURL,
|
AsyncImage(model = event.performance.previewImageURL,
|
||||||
contentDescription = "performance preview image",
|
contentDescription = "performance preview image",
|
||||||
contentScale = ContentScale.Crop,
|
contentScale = ContentScale.Crop,
|
||||||
|
@ -0,0 +1,32 @@
|
|||||||
|
package com.example.mobile_labs.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 kotlinx.coroutines.flow.Flow
|
||||||
|
|
||||||
|
@Dao
|
||||||
|
interface EventDao {
|
||||||
|
@Query("select * from events order by date asc")
|
||||||
|
fun getAll(): Flow<List<Event>>
|
||||||
|
|
||||||
|
@Query("select * from events where events.date > :dateFrom order by date asc")
|
||||||
|
fun getAllWithPerformance(dateFrom: String): Flow<List<EventWithPerformance>>
|
||||||
|
|
||||||
|
@Query("select * from events where events.uid = :uid")
|
||||||
|
suspend fun getByUid(uid: Int): EventWithPerformance
|
||||||
|
|
||||||
|
@Insert
|
||||||
|
suspend fun insert(event: Event)
|
||||||
|
|
||||||
|
@Update
|
||||||
|
suspend fun update(event: Event)
|
||||||
|
|
||||||
|
@Delete
|
||||||
|
suspend fun delete(event: Event)
|
||||||
|
}
|
@ -1,27 +1,32 @@
|
|||||||
package com.example.mobile_labs.event.model
|
package com.example.mobile_labs.event.model
|
||||||
|
|
||||||
|
import androidx.room.ColumnInfo
|
||||||
|
import androidx.room.Entity
|
||||||
|
import androidx.room.ForeignKey
|
||||||
|
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.performance.model.Performance
|
||||||
import com.example.mobile_labs.person.model.Person
|
import com.example.mobile_labs.person.model.Person
|
||||||
import java.io.Serializable
|
import java.io.Serializable
|
||||||
import java.time.LocalDate
|
import java.time.LocalDate
|
||||||
|
|
||||||
|
@TypeConverters(LocalDateConverter::class)
|
||||||
|
@Entity(tableName = "events", foreignKeys = [
|
||||||
|
ForeignKey(
|
||||||
|
entity = Performance::class,
|
||||||
|
parentColumns = ["performance_uid"],
|
||||||
|
childColumns = ["performance_id"],
|
||||||
|
onDelete = ForeignKey.RESTRICT,
|
||||||
|
onUpdate = ForeignKey.RESTRICT,
|
||||||
|
),
|
||||||
|
])
|
||||||
data class Event(
|
data class Event(
|
||||||
|
@PrimaryKey(autoGenerate = true)
|
||||||
|
val uid: Int?,
|
||||||
val date: LocalDate,
|
val date: LocalDate,
|
||||||
val performance: Performance,
|
@ColumnInfo(name = "performance_id")
|
||||||
) : Serializable
|
val performanceId: Int?,
|
||||||
|
)
|
||||||
|
|
||||||
fun getTestEvents(): List<Event> {
|
|
||||||
val director = Person("Иванов", "Иван", "https://bolshoi.ru/media/members/photos/86_ru_twyyatusbnifnzi_300x300_p.jpg");
|
|
||||||
val author = Person("Петров", "Петр", "https://bolshoi.ru/media/members/photos/86_ru_twyyatusbnifnzi_300x300_p.jpg");
|
|
||||||
val actors = listOf(director, author);
|
|
||||||
val performances = listOf(
|
|
||||||
Performance(0,"Представление #1", "Netus quis congue nascetur ullamcorper nibh, nostra iaculis turpis!", author, director, actors, "https://img.freepik.com/free-photo/empty-stage-with-few-props-red-seats_181624-57595.jpg?w=1380&t=st=1696959739~exp=1696960339~hmac=2107448a1d874f1315b5cf246c71df70dc653707c7c8be4a38581d3b73f842ba", "https://www.theatreinparis.com/uploads/images/article/theatre-de-l-athenee-dr.jpg"),
|
|
||||||
Performance(1,"Представление #2", "Netus quis congue nascetur ullamcorper nibh, nostra iaculis turpis!", author, director, actors, "https://img.freepik.com/free-photo/empty-stage-with-few-props-red-seats_181624-57595.jpg?w=1380&t=st=1696959739~exp=1696960339~hmac=2107448a1d874f1315b5cf246c71df70dc653707c7c8be4a38581d3b73f842ba", "https://www.theatreinparis.com/uploads/images/article/theatre-de-l-athenee-dr.jpg"),
|
|
||||||
Performance(2,"Представление #3", "Netus quis congue nascetur ullamcorper nibh, nostra iaculis turpis!", author, director, actors, "https://img.freepik.com/free-photo/empty-stage-with-few-props-red-seats_181624-57595.jpg?w=1380&t=st=1696959739~exp=1696960339~hmac=2107448a1d874f1315b5cf246c71df70dc653707c7c8be4a38581d3b73f842ba", "https://www.theatreinparis.com/uploads/images/article/theatre-de-l-athenee-dr.jpg"),
|
|
||||||
)
|
|
||||||
return listOf(
|
|
||||||
Event(LocalDate.parse("2023-10-15"), performances[0]),
|
|
||||||
Event(LocalDate.parse("2023-10-16"), performances[1]),
|
|
||||||
Event(LocalDate.parse("2023-10-17"), performances[2])
|
|
||||||
)
|
|
||||||
}
|
|
@ -0,0 +1,12 @@
|
|||||||
|
package com.example.mobile_labs.event.model
|
||||||
|
|
||||||
|
import androidx.room.Embedded
|
||||||
|
import androidx.room.Relation
|
||||||
|
import com.example.mobile_labs.performance.model.Performance
|
||||||
|
|
||||||
|
data class EventWithPerformance (
|
||||||
|
@Embedded
|
||||||
|
val event: Event,
|
||||||
|
@Relation(entity = Performance::class, parentColumn = "performance_id", entityColumn = "performance_uid")
|
||||||
|
val performance: Performance,
|
||||||
|
)
|
@ -17,6 +17,7 @@ import androidx.compose.material3.Surface
|
|||||||
import androidx.compose.material3.Text
|
import androidx.compose.material3.Text
|
||||||
import androidx.compose.material3.TextField
|
import androidx.compose.material3.TextField
|
||||||
import androidx.compose.runtime.Composable
|
import androidx.compose.runtime.Composable
|
||||||
|
import androidx.compose.runtime.LaunchedEffect
|
||||||
import androidx.compose.runtime.getValue
|
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
|
||||||
@ -24,6 +25,7 @@ import androidx.compose.runtime.setValue
|
|||||||
import androidx.compose.ui.Alignment
|
import androidx.compose.ui.Alignment
|
||||||
import androidx.compose.ui.Modifier
|
import androidx.compose.ui.Modifier
|
||||||
import androidx.compose.ui.layout.ContentScale
|
import androidx.compose.ui.layout.ContentScale
|
||||||
|
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
|
||||||
@ -32,16 +34,25 @@ import androidx.compose.ui.unit.sp
|
|||||||
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.composeui.navigation.Screen
|
||||||
import com.example.mobile_labs.performance.model.getTestPerformances
|
|
||||||
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.database.AppDatabase
|
||||||
|
import com.example.mobile_labs.performance.model.PerformanceWithPeople
|
||||||
|
import kotlinx.coroutines.Dispatchers
|
||||||
|
import kotlinx.coroutines.withContext
|
||||||
|
|
||||||
@OptIn(ExperimentalMaterial3Api::class)
|
@OptIn(ExperimentalMaterial3Api::class)
|
||||||
@Composable
|
@Composable
|
||||||
fun PerformanceView(id: Int) {
|
fun PerformanceView(id: Int) {
|
||||||
var performance = getTestPerformances()[id]
|
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 = ""
|
var actorsText = ""
|
||||||
performance.actors.forEach {
|
performaceWithPeople?.actors?.forEach {
|
||||||
if (actorsText != "") actorsText += "\n"
|
if (actorsText != "") actorsText += "\n"
|
||||||
actorsText += "${it.last_name} ${it.first_name}"
|
actorsText += "${it.last_name} ${it.first_name}"
|
||||||
}
|
}
|
||||||
@ -50,10 +61,10 @@ fun PerformanceView(id: Int) {
|
|||||||
modifier = Modifier
|
modifier = Modifier
|
||||||
.padding(all = 10.dp)
|
.padding(all = 10.dp)
|
||||||
.verticalScroll(rememberScrollState())) {
|
.verticalScroll(rememberScrollState())) {
|
||||||
Text(text = "${performance.author.last_name} ${performance.author.first_name}", textAlign = TextAlign.Center)
|
Text(text = "${performaceWithPeople?.author?.last_name} ${performaceWithPeople?.author?.first_name}", textAlign = TextAlign.Center)
|
||||||
Text(text = performance.title, textAlign = TextAlign.Center, fontSize = 30.sp)
|
Text(text = performaceWithPeople?.performance?.title ?: "", textAlign = TextAlign.Center, fontSize = 30.sp)
|
||||||
AsyncImage(model = performance.imageURL, contentDescription = "performance image")
|
AsyncImage(model = performaceWithPeople?.performance?.imageURL, contentDescription = "performance image")
|
||||||
OutlinedTextField(modifier = Modifier.fillMaxWidth(), value = performance.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))
|
||||||
}
|
}
|
||||||
|
@ -1,6 +1,7 @@
|
|||||||
package com.example.mobile_labs.performance.composeui
|
package com.example.mobile_labs.performance.composeui
|
||||||
|
|
||||||
import android.content.res.Configuration
|
import android.content.res.Configuration
|
||||||
|
import android.util.Log
|
||||||
import androidx.compose.foundation.layout.Column
|
import androidx.compose.foundation.layout.Column
|
||||||
import androidx.compose.foundation.layout.Row
|
import androidx.compose.foundation.layout.Row
|
||||||
import androidx.compose.foundation.layout.fillMaxWidth
|
import androidx.compose.foundation.layout.fillMaxWidth
|
||||||
@ -16,6 +17,7 @@ import androidx.compose.material3.Surface
|
|||||||
import androidx.compose.material3.Text
|
import androidx.compose.material3.Text
|
||||||
import androidx.compose.material3.TextField
|
import androidx.compose.material3.TextField
|
||||||
import androidx.compose.runtime.Composable
|
import androidx.compose.runtime.Composable
|
||||||
|
import androidx.compose.runtime.LaunchedEffect
|
||||||
import androidx.compose.runtime.State
|
import androidx.compose.runtime.State
|
||||||
import androidx.compose.runtime.getValue
|
import androidx.compose.runtime.getValue
|
||||||
import androidx.compose.runtime.mutableStateListOf
|
import androidx.compose.runtime.mutableStateListOf
|
||||||
@ -28,30 +30,51 @@ import androidx.compose.ui.Modifier
|
|||||||
import androidx.compose.ui.draw.clip
|
import androidx.compose.ui.draw.clip
|
||||||
import androidx.compose.ui.graphics.RectangleShape
|
import androidx.compose.ui.graphics.RectangleShape
|
||||||
import androidx.compose.ui.layout.ContentScale
|
import androidx.compose.ui.layout.ContentScale
|
||||||
|
import androidx.compose.ui.platform.LocalContext
|
||||||
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.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.composeui.navigation.Screen
|
||||||
|
import com.example.mobile_labs.database.AppDatabase
|
||||||
import com.example.mobile_labs.performance.model.Performance
|
import com.example.mobile_labs.performance.model.Performance
|
||||||
import com.example.mobile_labs.performance.model.getTestPerformances
|
import com.example.mobile_labs.person.model.Person
|
||||||
import com.example.mobile_labs.ui.theme.Mobile_LabsTheme
|
import com.example.mobile_labs.ui.theme.Mobile_LabsTheme
|
||||||
|
import kotlinx.coroutines.Dispatchers
|
||||||
var performances by mutableStateOf(getTestPerformances())
|
import kotlinx.coroutines.withContext
|
||||||
|
|
||||||
@OptIn(ExperimentalMaterial3Api::class)
|
@OptIn(ExperimentalMaterial3Api::class)
|
||||||
@Composable
|
@Composable
|
||||||
fun Repertoire(navController: NavController?) {
|
fun Repertoire(navController: NavController?) {
|
||||||
|
val context = LocalContext.current
|
||||||
|
val performances = remember { mutableStateListOf<Performance>() }
|
||||||
|
var performancesFiltered = remember { mutableStateListOf<Performance>() }
|
||||||
var title by remember { mutableStateOf("") }
|
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(
|
Column(
|
||||||
horizontalAlignment = Alignment.CenterHorizontally,
|
horizontalAlignment = Alignment.CenterHorizontally,
|
||||||
modifier = Modifier
|
modifier = Modifier
|
||||||
.padding(all = 10.dp)
|
.padding(all = 10.dp)
|
||||||
.verticalScroll(rememberScrollState())) {
|
.verticalScroll(rememberScrollState())) {
|
||||||
TextField(value = title, label = {Text(text = "Поиск...")}, onValueChange = { title = it; performances =
|
TextField(value = title, label = {Text(text = "Поиск...")}, onValueChange = { title = it;
|
||||||
if (title != "") getTestPerformances().filter { performance -> performance.title.contains(title) } else getTestPerformances() })
|
if (title != "") {
|
||||||
performances.forEachIndexed() { index, performance ->
|
val data = performances.filter { performance -> performance.title.contains(title) }
|
||||||
val performanceId = Screen.PerformanceView.route.replace("{id}", performance.id.toString())
|
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)) {
|
Row(Modifier.padding(all = 10.dp)) {
|
||||||
AsyncImage(model = performance.previewImageURL,
|
AsyncImage(model = performance.previewImageURL,
|
||||||
contentDescription = "performance preview image",
|
contentDescription = "performance preview image",
|
||||||
|
@ -0,0 +1,29 @@
|
|||||||
|
package com.example.mobile_labs.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 kotlinx.coroutines.flow.Flow
|
||||||
|
|
||||||
|
@Dao
|
||||||
|
interface PerformanceDao {
|
||||||
|
@Query("select * from performances order by title collate nocase asc")
|
||||||
|
fun getAll(): Flow<List<Performance>>
|
||||||
|
|
||||||
|
@Query("select * from performances where performances.performance_uid = :uid")
|
||||||
|
suspend fun getByUid(uid: Int): PerformanceWithPeople
|
||||||
|
|
||||||
|
@Insert
|
||||||
|
suspend fun insert(performance: Performance)
|
||||||
|
|
||||||
|
@Update
|
||||||
|
suspend fun update(performance: Performance)
|
||||||
|
|
||||||
|
@Delete
|
||||||
|
suspend fun delete(performance: Performance)
|
||||||
|
}
|
@ -0,0 +1,26 @@
|
|||||||
|
package com.example.mobile_labs.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 kotlinx.coroutines.flow.Flow
|
||||||
|
|
||||||
|
@Dao
|
||||||
|
interface PerformancePersonDao {
|
||||||
|
@Query("select * from performance_person")
|
||||||
|
fun getAll(): Flow<List<PerformancePersonCrossRef>>
|
||||||
|
|
||||||
|
@Insert
|
||||||
|
suspend fun insert(performancePersonCrossRef: PerformancePersonCrossRef)
|
||||||
|
|
||||||
|
@Update
|
||||||
|
suspend fun update(performancePersonCrossRef: PerformancePersonCrossRef)
|
||||||
|
|
||||||
|
@Delete
|
||||||
|
suspend fun delete(performancePersonCrossRef: PerformancePersonCrossRef)
|
||||||
|
}
|
@ -1,34 +1,52 @@
|
|||||||
package com.example.mobile_labs.performance.model
|
package com.example.mobile_labs.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.person.model.Person
|
||||||
import java.io.Serializable
|
import java.io.Serializable
|
||||||
|
|
||||||
|
@Entity(tableName = "performances", foreignKeys = [
|
||||||
|
ForeignKey(
|
||||||
|
entity = Person::class,
|
||||||
|
parentColumns = ["uid"],
|
||||||
|
childColumns = ["director_id"],
|
||||||
|
onDelete = ForeignKey.RESTRICT,
|
||||||
|
onUpdate = ForeignKey.RESTRICT,
|
||||||
|
),
|
||||||
|
ForeignKey(
|
||||||
|
entity = Person::class,
|
||||||
|
parentColumns = ["uid"],
|
||||||
|
childColumns = ["author_id"],
|
||||||
|
onDelete = ForeignKey.RESTRICT,
|
||||||
|
onUpdate = ForeignKey.RESTRICT,
|
||||||
|
),
|
||||||
|
]
|
||||||
|
)
|
||||||
data class Performance(
|
data class Performance(
|
||||||
val id: Int,
|
@PrimaryKey(autoGenerate = true)
|
||||||
|
val performance_uid: Int?,
|
||||||
val title: String,
|
val title: String,
|
||||||
val description: String,
|
val description: String,
|
||||||
val author: Person,
|
@ColumnInfo(name = "author_id", index = true)
|
||||||
val director: Person,
|
val authorId: Int?,
|
||||||
val actors: List<Person>,
|
@ColumnInfo(name = "director_id", index = true)
|
||||||
|
val directorId: Int?,
|
||||||
|
@ColumnInfo(name = "image_url")
|
||||||
val imageURL: String,
|
val imageURL: String,
|
||||||
|
@ColumnInfo(name = "preview_image_url")
|
||||||
val previewImageURL: String,
|
val previewImageURL: String,
|
||||||
) : Serializable
|
) {
|
||||||
|
override fun equals(other: Any?): Boolean {
|
||||||
|
if (this === other) return true
|
||||||
|
if (javaClass != other?.javaClass) return false
|
||||||
|
other as Performance
|
||||||
|
if (performance_uid != other.performance_uid) return false
|
||||||
|
return true
|
||||||
|
}
|
||||||
|
|
||||||
fun getTestPerformances(): List<Performance> {
|
override fun hashCode(): Int {
|
||||||
val director = Person("Иванов", "Иван", "https://bolshoi.ru/media/members/photos/86_ru_twyyatusbnifnzi_300x300_p.jpg");
|
return performance_uid ?: -1
|
||||||
val author = Person("Петров", "Петр", "https://bolshoi.ru/media/members/photos/86_ru_twyyatusbnifnzi_300x300_p.jpg");
|
}
|
||||||
val actors = listOf(director, author);
|
|
||||||
return listOf(
|
|
||||||
Performance(0,"Представление #1", "Netus quis congue nascetur ullamcorper nibh, nostra iaculis turpis!", author, director, actors, "https://img.freepik.com/free-photo/empty-stage-with-few-props-red-seats_181624-57595.jpg?w=1380&t=st=1696959739~exp=1696960339~hmac=2107448a1d874f1315b5cf246c71df70dc653707c7c8be4a38581d3b73f842ba", "https://www.theatreinparis.com/uploads/images/article/theatre-de-l-athenee-dr.jpg"),
|
|
||||||
Performance(1,"Представление #2", "Netus quis congue nascetur ullamcorper nibh, nostra iaculis turpis!", author, director, actors, "https://img.freepik.com/free-photo/empty-stage-with-few-props-red-seats_181624-57595.jpg?w=1380&t=st=1696959739~exp=1696960339~hmac=2107448a1d874f1315b5cf246c71df70dc653707c7c8be4a38581d3b73f842ba", "https://www.theatreinparis.com/uploads/images/article/theatre-de-l-athenee-dr.jpg"),
|
|
||||||
Performance(2,"Представление #3", "Netus quis congue nascetur ullamcorper nibh, nostra iaculis turpis!", author, director, actors, "https://img.freepik.com/free-photo/empty-stage-with-few-props-red-seats_181624-57595.jpg?w=1380&t=st=1696959739~exp=1696960339~hmac=2107448a1d874f1315b5cf246c71df70dc653707c7c8be4a38581d3b73f842ba", "https://www.theatreinparis.com/uploads/images/article/theatre-de-l-athenee-dr.jpg"),
|
|
||||||
Performance(3,"Представление #3", "Netus quis congue nascetur ullamcorper nibh, nostra iaculis turpis!", author, director, actors, "https://img.freepik.com/free-photo/empty-stage-with-few-props-red-seats_181624-57595.jpg?w=1380&t=st=1696959739~exp=1696960339~hmac=2107448a1d874f1315b5cf246c71df70dc653707c7c8be4a38581d3b73f842ba", "https://www.theatreinparis.com/uploads/images/article/theatre-de-l-athenee-dr.jpg"),
|
|
||||||
Performance(4,"Представление #3", "Netus quis congue nascetur ullamcorper nibh, nostra iaculis turpis!", author, director, actors, "https://img.freepik.com/free-photo/empty-stage-with-few-props-red-seats_181624-57595.jpg?w=1380&t=st=1696959739~exp=1696960339~hmac=2107448a1d874f1315b5cf246c71df70dc653707c7c8be4a38581d3b73f842ba", "https://www.theatreinparis.com/uploads/images/article/theatre-de-l-athenee-dr.jpg"),
|
|
||||||
Performance(5,"Представление #3", "Netus quis congue nascetur ullamcorper nibh, nostra iaculis turpis!", author, director, actors, "https://img.freepik.com/free-photo/empty-stage-with-few-props-red-seats_181624-57595.jpg?w=1380&t=st=1696959739~exp=1696960339~hmac=2107448a1d874f1315b5cf246c71df70dc653707c7c8be4a38581d3b73f842ba", "https://www.theatreinparis.com/uploads/images/article/theatre-de-l-athenee-dr.jpg"),
|
|
||||||
Performance(6,"Представление #3", "Netus quis congue nascetur ullamcorper nibh, nostra iaculis turpis!", author, director, actors, "https://img.freepik.com/free-photo/empty-stage-with-few-props-red-seats_181624-57595.jpg?w=1380&t=st=1696959739~exp=1696960339~hmac=2107448a1d874f1315b5cf246c71df70dc653707c7c8be4a38581d3b73f842ba", "https://www.theatreinparis.com/uploads/images/article/theatre-de-l-athenee-dr.jpg"),
|
|
||||||
Performance(7,"Представление #3", "Netus quis congue nascetur ullamcorper nibh, nostra iaculis turpis!", author, director, actors, "https://img.freepik.com/free-photo/empty-stage-with-few-props-red-seats_181624-57595.jpg?w=1380&t=st=1696959739~exp=1696960339~hmac=2107448a1d874f1315b5cf246c71df70dc653707c7c8be4a38581d3b73f842ba", "https://www.theatreinparis.com/uploads/images/article/theatre-de-l-athenee-dr.jpg"),
|
|
||||||
Performance(8,"Представление #3", "Netus quis congue nascetur ullamcorper nibh, nostra iaculis turpis!", author, director, actors, "https://img.freepik.com/free-photo/empty-stage-with-few-props-red-seats_181624-57595.jpg?w=1380&t=st=1696959739~exp=1696960339~hmac=2107448a1d874f1315b5cf246c71df70dc653707c7c8be4a38581d3b73f842ba", "https://www.theatreinparis.com/uploads/images/article/theatre-de-l-athenee-dr.jpg"),
|
|
||||||
Performance(9,"Представление #3", "Netus quis congue nascetur ullamcorper nibh, nostra iaculis turpis!", author, director, actors, "https://img.freepik.com/free-photo/empty-stage-with-few-props-red-seats_181624-57595.jpg?w=1380&t=st=1696959739~exp=1696960339~hmac=2107448a1d874f1315b5cf246c71df70dc653707c7c8be4a38581d3b73f842ba", "https://www.theatreinparis.com/uploads/images/article/theatre-de-l-athenee-dr.jpg"),
|
|
||||||
Performance(10,"Представление #3", "Netus quis congue nascetur ullamcorper nibh, nostra iaculis turpis!", author, director, actors, "https://img.freepik.com/free-photo/empty-stage-with-few-props-red-seats_181624-57595.jpg?w=1380&t=st=1696959739~exp=1696960339~hmac=2107448a1d874f1315b5cf246c71df70dc653707c7c8be4a38581d3b73f842ba", "https://www.theatreinparis.com/uploads/images/article/theatre-de-l-athenee-dr.jpg"),
|
|
||||||
)
|
|
||||||
}
|
}
|
@ -0,0 +1,9 @@
|
|||||||
|
package com.example.mobile_labs.performance.model
|
||||||
|
|
||||||
|
import androidx.room.Entity
|
||||||
|
|
||||||
|
@Entity(tableName = "performance_person", primaryKeys = ["performance_uid", "uid"])
|
||||||
|
data class PerformancePersonCrossRef(
|
||||||
|
val performance_uid: Int,
|
||||||
|
val uid: Int,
|
||||||
|
)
|
@ -0,0 +1,22 @@
|
|||||||
|
package com.example.mobile_labs.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
|
||||||
|
|
||||||
|
data class PerformanceWithPeople (
|
||||||
|
@Embedded
|
||||||
|
val performance: Performance,
|
||||||
|
@Relation(entity = Person::class, parentColumn = "author_id", entityColumn = "uid")
|
||||||
|
val author: Person,
|
||||||
|
@Relation(entity = Person::class, parentColumn = "director_id", entityColumn = "uid")
|
||||||
|
val director: Person,
|
||||||
|
@Relation(
|
||||||
|
parentColumn = "performance_uid",
|
||||||
|
entityColumn = "uid",
|
||||||
|
associateBy = Junction(PerformancePersonCrossRef::class),
|
||||||
|
)
|
||||||
|
val actors: List<Person>
|
||||||
|
)
|
@ -15,26 +15,42 @@ import androidx.compose.material3.MaterialTheme
|
|||||||
import androidx.compose.material3.Surface
|
import androidx.compose.material3.Surface
|
||||||
import androidx.compose.material3.Text
|
import androidx.compose.material3.Text
|
||||||
import androidx.compose.runtime.Composable
|
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.Alignment
|
||||||
import androidx.compose.ui.Modifier
|
import androidx.compose.ui.Modifier
|
||||||
import androidx.compose.ui.layout.ContentScale
|
import androidx.compose.ui.layout.ContentScale
|
||||||
|
import androidx.compose.ui.platform.LocalContext
|
||||||
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.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.composeui.navigation.Screen
|
||||||
|
import com.example.mobile_labs.database.AppDatabase
|
||||||
import com.example.mobile_labs.performance.composeui.Repertoire
|
import com.example.mobile_labs.performance.composeui.Repertoire
|
||||||
import com.example.mobile_labs.performance.model.getTestPerformances
|
import com.example.mobile_labs.person.model.Person
|
||||||
import com.example.mobile_labs.person.model.getTestPerson
|
|
||||||
import com.example.mobile_labs.ui.theme.Mobile_LabsTheme
|
import com.example.mobile_labs.ui.theme.Mobile_LabsTheme
|
||||||
|
import kotlinx.coroutines.Dispatchers
|
||||||
|
import kotlinx.coroutines.withContext
|
||||||
|
|
||||||
@Composable
|
@Composable
|
||||||
fun PeopleList(navController: NavController?) {
|
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)) {
|
Column(Modifier.padding(all = 10.dp)) {
|
||||||
LazyVerticalGrid(columns = GridCells.Adaptive(minSize = 100.dp))
|
LazyVerticalGrid(columns = GridCells.Adaptive(minSize = 100.dp))
|
||||||
{
|
{
|
||||||
items(getTestPerson()) {
|
items(people) {
|
||||||
Column(horizontalAlignment = Alignment.CenterHorizontally, modifier = Modifier
|
Column(horizontalAlignment = Alignment.CenterHorizontally, modifier = Modifier
|
||||||
.width(300.dp)
|
.width(300.dp)
|
||||||
.height(200.dp)) {
|
.height(200.dp)) {
|
||||||
|
@ -0,0 +1,27 @@
|
|||||||
|
package com.example.mobile_labs.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 kotlinx.coroutines.flow.Flow
|
||||||
|
|
||||||
|
@Dao
|
||||||
|
interface PersonDao {
|
||||||
|
@Query("select * from people order by last_name collate nocase asc")
|
||||||
|
fun getAll(): Flow<List<Person>>
|
||||||
|
|
||||||
|
@Query("select * from people where people.uid = :uid")
|
||||||
|
suspend fun getByUid(uid: Int): Person
|
||||||
|
|
||||||
|
@Insert
|
||||||
|
suspend fun insert(person: Person)
|
||||||
|
|
||||||
|
@Update
|
||||||
|
suspend fun update(person: Person)
|
||||||
|
|
||||||
|
@Delete
|
||||||
|
suspend fun delete(person: Person)
|
||||||
|
}
|
@ -1,26 +1,29 @@
|
|||||||
package com.example.mobile_labs.person.model
|
package com.example.mobile_labs.person.model
|
||||||
|
|
||||||
|
import androidx.room.ColumnInfo
|
||||||
|
import androidx.room.Entity
|
||||||
|
import androidx.room.Ignore
|
||||||
|
import androidx.room.PrimaryKey
|
||||||
import java.io.Serializable
|
import java.io.Serializable
|
||||||
|
|
||||||
|
@Entity(tableName = "people")
|
||||||
data class Person(
|
data class Person(
|
||||||
|
@PrimaryKey(autoGenerate = true)
|
||||||
|
val uid: Int?,
|
||||||
val last_name: String,
|
val last_name: String,
|
||||||
val first_name: String,
|
val first_name: String,
|
||||||
|
@ColumnInfo(name = "image_url")
|
||||||
val imageURL: String,
|
val imageURL: String,
|
||||||
) : Serializable
|
) {
|
||||||
|
override fun equals(other: Any?): Boolean {
|
||||||
|
if (this === other) return true
|
||||||
|
if (javaClass != other?.javaClass) return false
|
||||||
|
other as Person
|
||||||
|
if (uid != other.uid) return false
|
||||||
|
return true
|
||||||
|
}
|
||||||
|
|
||||||
fun getTestPerson(): List<Person> {
|
override fun hashCode(): Int {
|
||||||
return listOf(
|
return uid ?: -1
|
||||||
Person("Иванов", "Иван", "https://bolshoi.ru/media/members/photos/86_ru_twyyatusbnifnzi_300x300_p.jpg"),
|
}
|
||||||
Person("Ксения", "Дудникова", "https://bolshoi.ru/media/members/photos/1756_ru_wkznwzklgosnbiq_300x300_p.jpg"),
|
|
||||||
Person("Евгения", "Сегенюк", "https://bolshoi.ru/media/members/photos/2908_ru_rycynrihdpzvgdj_300x300_p.jpg"),
|
|
||||||
Person("Петров", "Петр", "https://bolshoi.ru/media/members/photos/15820_ru_zvewuwadyjuywkh_300x300_p.jpg"),
|
|
||||||
Person("Иванов", "Иван", "https://bolshoi.ru/media/members/photos/86_ru_twyyatusbnifnzi_300x300_p.jpg"),
|
|
||||||
Person("Ксения", "Дудникова", "https://bolshoi.ru/media/members/photos/1756_ru_wkznwzklgosnbiq_300x300_p.jpg"),
|
|
||||||
Person("Евгения", "Сегенюк", "https://bolshoi.ru/media/members/photos/2908_ru_rycynrihdpzvgdj_300x300_p.jpg"),
|
|
||||||
Person("Петров", "Петр", "https://bolshoi.ru/media/members/photos/15820_ru_zvewuwadyjuywkh_300x300_p.jpg"),
|
|
||||||
Person("Иванов", "Иван", "https://bolshoi.ru/media/members/photos/86_ru_twyyatusbnifnzi_300x300_p.jpg"),
|
|
||||||
Person("Ксения", "Дудникова", "https://bolshoi.ru/media/members/photos/1756_ru_wkznwzklgosnbiq_300x300_p.jpg"),
|
|
||||||
Person("Евгения", "Сегенюк", "https://bolshoi.ru/media/members/photos/2908_ru_rycynrihdpzvgdj_300x300_p.jpg"),
|
|
||||||
Person("Петров", "Петр", "https://bolshoi.ru/media/members/photos/15820_ru_zvewuwadyjuywkh_300x300_p.jpg"),
|
|
||||||
)
|
|
||||||
}
|
}
|
@ -0,0 +1,28 @@
|
|||||||
|
package com.example.mobile_labs.user.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.user.model.User
|
||||||
|
import kotlinx.coroutines.flow.Flow
|
||||||
|
|
||||||
|
@Dao
|
||||||
|
interface UserDao {
|
||||||
|
@Query("select * from users order by last_name collate nocase asc")
|
||||||
|
fun getAll(): Flow<List<User>>
|
||||||
|
|
||||||
|
@Query("select * from users where users.uid = :uid")
|
||||||
|
suspend fun getByUid(uid: Int): User
|
||||||
|
|
||||||
|
@Insert
|
||||||
|
suspend fun insert(user: User)
|
||||||
|
|
||||||
|
@Update
|
||||||
|
suspend fun update(user: User)
|
||||||
|
|
||||||
|
@Delete
|
||||||
|
suspend fun delete(user: User)
|
||||||
|
}
|
26
app/src/main/java/com/example/mobile_labs/user/model/User.kt
Normal file
26
app/src/main/java/com/example/mobile_labs/user/model/User.kt
Normal file
@ -0,0 +1,26 @@
|
|||||||
|
package com.example.mobile_labs.user.model
|
||||||
|
|
||||||
|
import androidx.room.Entity
|
||||||
|
import androidx.room.PrimaryKey
|
||||||
|
|
||||||
|
@Entity(tableName = "users")
|
||||||
|
data class User(
|
||||||
|
@PrimaryKey(autoGenerate = true)
|
||||||
|
val uid: Int?,
|
||||||
|
val email: String,
|
||||||
|
val password: String,
|
||||||
|
val last_name: String,
|
||||||
|
val first_name: String,
|
||||||
|
) {
|
||||||
|
override fun equals(other: Any?): Boolean {
|
||||||
|
if (this === other) return true
|
||||||
|
if (javaClass != other?.javaClass) return false
|
||||||
|
other as User
|
||||||
|
if (uid != other.uid) return false
|
||||||
|
return true
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun hashCode(): Int {
|
||||||
|
return uid ?: -1
|
||||||
|
}
|
||||||
|
}
|
@ -2,4 +2,5 @@
|
|||||||
plugins {
|
plugins {
|
||||||
id("com.android.application") version "8.1.1" apply false
|
id("com.android.application") version "8.1.1" apply false
|
||||||
id("org.jetbrains.kotlin.android") version "1.8.10" apply false
|
id("org.jetbrains.kotlin.android") version "1.8.10" apply false
|
||||||
|
id("com.google.devtools.ksp") version "1.8.20-1.0.11" apply false
|
||||||
}
|
}
|
Loading…
Reference in New Issue
Block a user