Compare commits
No commits in common. "lw3" and "master" have entirely different histories.
123
.idea/codeStyles/Project.xml
generated
Normal file
123
.idea/codeStyles/Project.xml
generated
Normal file
@ -0,0 +1,123 @@
|
|||||||
|
<component name="ProjectCodeStyleConfiguration">
|
||||||
|
<code_scheme name="Project" version="173">
|
||||||
|
<JetCodeStyleSettings>
|
||||||
|
<option name="CODE_STYLE_DEFAULTS" value="KOTLIN_OFFICIAL" />
|
||||||
|
</JetCodeStyleSettings>
|
||||||
|
<codeStyleSettings language="XML">
|
||||||
|
<option name="FORCE_REARRANGE_MODE" value="1" />
|
||||||
|
<indentOptions>
|
||||||
|
<option name="CONTINUATION_INDENT_SIZE" value="4" />
|
||||||
|
</indentOptions>
|
||||||
|
<arrangement>
|
||||||
|
<rules>
|
||||||
|
<section>
|
||||||
|
<rule>
|
||||||
|
<match>
|
||||||
|
<AND>
|
||||||
|
<NAME>xmlns:android</NAME>
|
||||||
|
<XML_ATTRIBUTE />
|
||||||
|
<XML_NAMESPACE>^$</XML_NAMESPACE>
|
||||||
|
</AND>
|
||||||
|
</match>
|
||||||
|
</rule>
|
||||||
|
</section>
|
||||||
|
<section>
|
||||||
|
<rule>
|
||||||
|
<match>
|
||||||
|
<AND>
|
||||||
|
<NAME>xmlns:.*</NAME>
|
||||||
|
<XML_ATTRIBUTE />
|
||||||
|
<XML_NAMESPACE>^$</XML_NAMESPACE>
|
||||||
|
</AND>
|
||||||
|
</match>
|
||||||
|
<order>BY_NAME</order>
|
||||||
|
</rule>
|
||||||
|
</section>
|
||||||
|
<section>
|
||||||
|
<rule>
|
||||||
|
<match>
|
||||||
|
<AND>
|
||||||
|
<NAME>.*:id</NAME>
|
||||||
|
<XML_ATTRIBUTE />
|
||||||
|
<XML_NAMESPACE>http://schemas.android.com/apk/res/android</XML_NAMESPACE>
|
||||||
|
</AND>
|
||||||
|
</match>
|
||||||
|
</rule>
|
||||||
|
</section>
|
||||||
|
<section>
|
||||||
|
<rule>
|
||||||
|
<match>
|
||||||
|
<AND>
|
||||||
|
<NAME>.*:name</NAME>
|
||||||
|
<XML_ATTRIBUTE />
|
||||||
|
<XML_NAMESPACE>http://schemas.android.com/apk/res/android</XML_NAMESPACE>
|
||||||
|
</AND>
|
||||||
|
</match>
|
||||||
|
</rule>
|
||||||
|
</section>
|
||||||
|
<section>
|
||||||
|
<rule>
|
||||||
|
<match>
|
||||||
|
<AND>
|
||||||
|
<NAME>name</NAME>
|
||||||
|
<XML_ATTRIBUTE />
|
||||||
|
<XML_NAMESPACE>^$</XML_NAMESPACE>
|
||||||
|
</AND>
|
||||||
|
</match>
|
||||||
|
</rule>
|
||||||
|
</section>
|
||||||
|
<section>
|
||||||
|
<rule>
|
||||||
|
<match>
|
||||||
|
<AND>
|
||||||
|
<NAME>style</NAME>
|
||||||
|
<XML_ATTRIBUTE />
|
||||||
|
<XML_NAMESPACE>^$</XML_NAMESPACE>
|
||||||
|
</AND>
|
||||||
|
</match>
|
||||||
|
</rule>
|
||||||
|
</section>
|
||||||
|
<section>
|
||||||
|
<rule>
|
||||||
|
<match>
|
||||||
|
<AND>
|
||||||
|
<NAME>.*</NAME>
|
||||||
|
<XML_ATTRIBUTE />
|
||||||
|
<XML_NAMESPACE>^$</XML_NAMESPACE>
|
||||||
|
</AND>
|
||||||
|
</match>
|
||||||
|
<order>BY_NAME</order>
|
||||||
|
</rule>
|
||||||
|
</section>
|
||||||
|
<section>
|
||||||
|
<rule>
|
||||||
|
<match>
|
||||||
|
<AND>
|
||||||
|
<NAME>.*</NAME>
|
||||||
|
<XML_ATTRIBUTE />
|
||||||
|
<XML_NAMESPACE>http://schemas.android.com/apk/res/android</XML_NAMESPACE>
|
||||||
|
</AND>
|
||||||
|
</match>
|
||||||
|
<order>ANDROID_ATTRIBUTE_ORDER</order>
|
||||||
|
</rule>
|
||||||
|
</section>
|
||||||
|
<section>
|
||||||
|
<rule>
|
||||||
|
<match>
|
||||||
|
<AND>
|
||||||
|
<NAME>.*</NAME>
|
||||||
|
<XML_ATTRIBUTE />
|
||||||
|
<XML_NAMESPACE>.*</XML_NAMESPACE>
|
||||||
|
</AND>
|
||||||
|
</match>
|
||||||
|
<order>BY_NAME</order>
|
||||||
|
</rule>
|
||||||
|
</section>
|
||||||
|
</rules>
|
||||||
|
</arrangement>
|
||||||
|
</codeStyleSettings>
|
||||||
|
<codeStyleSettings language="kotlin">
|
||||||
|
<option name="CODE_STYLE_DEFAULTS" value="KOTLIN_OFFICIAL" />
|
||||||
|
</codeStyleSettings>
|
||||||
|
</code_scheme>
|
||||||
|
</component>
|
5
.idea/codeStyles/codeStyleConfig.xml
generated
Normal file
5
.idea/codeStyles/codeStyleConfig.xml
generated
Normal file
@ -0,0 +1,5 @@
|
|||||||
|
<component name="ProjectCodeStyleConfiguration">
|
||||||
|
<state>
|
||||||
|
<option name="USE_PER_PROJECT_SETTINGS" value="true" />
|
||||||
|
</state>
|
||||||
|
</component>
|
41
.idea/inspectionProfiles/Project_Default.xml
generated
41
.idea/inspectionProfiles/Project_Default.xml
generated
@ -1,41 +0,0 @@
|
|||||||
<component name="InspectionProjectProfileManager">
|
|
||||||
<profile version="1.0">
|
|
||||||
<option name="myName" value="Project Default" />
|
|
||||||
<inspection_tool class="PreviewAnnotationInFunctionWithParameters" enabled="true" level="ERROR" enabled_by_default="true">
|
|
||||||
<option name="composableFile" value="true" />
|
|
||||||
<option name="previewFile" value="true" />
|
|
||||||
</inspection_tool>
|
|
||||||
<inspection_tool class="PreviewApiLevelMustBeValid" enabled="true" level="ERROR" enabled_by_default="true">
|
|
||||||
<option name="composableFile" value="true" />
|
|
||||||
<option name="previewFile" value="true" />
|
|
||||||
</inspection_tool>
|
|
||||||
<inspection_tool class="PreviewDimensionRespectsLimit" enabled="true" level="WARNING" enabled_by_default="true">
|
|
||||||
<option name="composableFile" value="true" />
|
|
||||||
<option name="previewFile" value="true" />
|
|
||||||
</inspection_tool>
|
|
||||||
<inspection_tool class="PreviewFontScaleMustBeGreaterThanZero" enabled="true" level="ERROR" enabled_by_default="true">
|
|
||||||
<option name="composableFile" value="true" />
|
|
||||||
<option name="previewFile" value="true" />
|
|
||||||
</inspection_tool>
|
|
||||||
<inspection_tool class="PreviewMultipleParameterProviders" enabled="true" level="ERROR" enabled_by_default="true">
|
|
||||||
<option name="composableFile" value="true" />
|
|
||||||
<option name="previewFile" value="true" />
|
|
||||||
</inspection_tool>
|
|
||||||
<inspection_tool class="PreviewMustBeTopLevelFunction" enabled="true" level="ERROR" enabled_by_default="true">
|
|
||||||
<option name="composableFile" value="true" />
|
|
||||||
<option name="previewFile" value="true" />
|
|
||||||
</inspection_tool>
|
|
||||||
<inspection_tool class="PreviewNeedsComposableAnnotation" enabled="true" level="ERROR" enabled_by_default="true">
|
|
||||||
<option name="composableFile" value="true" />
|
|
||||||
<option name="previewFile" value="true" />
|
|
||||||
</inspection_tool>
|
|
||||||
<inspection_tool class="PreviewNotSupportedInUnitTestFiles" enabled="true" level="ERROR" enabled_by_default="true">
|
|
||||||
<option name="composableFile" value="true" />
|
|
||||||
<option name="previewFile" value="true" />
|
|
||||||
</inspection_tool>
|
|
||||||
<inspection_tool class="PreviewPickerAnnotation" enabled="true" level="ERROR" enabled_by_default="true">
|
|
||||||
<option name="composableFile" value="true" />
|
|
||||||
<option name="previewFile" value="true" />
|
|
||||||
</inspection_tool>
|
|
||||||
</profile>
|
|
||||||
</component>
|
|
2
.idea/kotlinc.xml
generated
2
.idea/kotlinc.xml
generated
@ -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.20" />
|
<option name="version" value="1.8.10" />
|
||||||
</component>
|
</component>
|
||||||
</project>
|
</project>
|
6
.idea/vcs.xml
generated
6
.idea/vcs.xml
generated
@ -1,6 +0,0 @@
|
|||||||
<?xml version="1.0" encoding="UTF-8"?>
|
|
||||||
<project version="4">
|
|
||||||
<component name="VcsDirectoryMappings">
|
|
||||||
<mapping directory="$PROJECT_DIR$" vcs="Git" />
|
|
||||||
</component>
|
|
||||||
</project>
|
|
@ -1,7 +1,6 @@
|
|||||||
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 {
|
||||||
@ -24,24 +23,21 @@ android {
|
|||||||
buildTypes {
|
buildTypes {
|
||||||
release {
|
release {
|
||||||
isMinifyEnabled = false
|
isMinifyEnabled = false
|
||||||
proguardFiles(
|
proguardFiles(getDefaultProguardFile("proguard-android-optimize.txt"), "proguard-rules.pro")
|
||||||
getDefaultProguardFile("proguard-android-optimize.txt"),
|
|
||||||
"proguard-rules.pro"
|
|
||||||
)
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
compileOptions {
|
compileOptions {
|
||||||
sourceCompatibility = JavaVersion.VERSION_17
|
sourceCompatibility = JavaVersion.VERSION_1_8
|
||||||
targetCompatibility = JavaVersion.VERSION_17
|
targetCompatibility = JavaVersion.VERSION_1_8
|
||||||
}
|
}
|
||||||
kotlinOptions {
|
kotlinOptions {
|
||||||
jvmTarget = "17"
|
jvmTarget = "1.8"
|
||||||
}
|
}
|
||||||
buildFeatures {
|
buildFeatures {
|
||||||
compose = true
|
compose = true
|
||||||
}
|
}
|
||||||
composeOptions {
|
composeOptions {
|
||||||
kotlinCompilerExtensionVersion = "1.4.5"
|
kotlinCompilerExtensionVersion = "1.4.3"
|
||||||
}
|
}
|
||||||
packaging {
|
packaging {
|
||||||
resources {
|
resources {
|
||||||
@ -51,30 +47,15 @@ android {
|
|||||||
}
|
}
|
||||||
|
|
||||||
dependencies {
|
dependencies {
|
||||||
implementation("com.jakewharton.threetenabp:threetenabp:1.2.1")
|
|
||||||
implementation("androidx.datastore:datastore-preferences:1.0.0")
|
|
||||||
// Core
|
|
||||||
implementation("androidx.core:core-ktx:1.9.0")
|
|
||||||
implementation("androidx.lifecycle:lifecycle-runtime-ktx:2.6.2")
|
|
||||||
|
|
||||||
// UI
|
implementation("androidx.core:core-ktx:1.9.0")
|
||||||
implementation("androidx.activity:activity-compose:1.7.2")
|
implementation("androidx.lifecycle:lifecycle-runtime-ktx:2.6.1")
|
||||||
|
implementation("androidx.activity:activity-compose:1.7.0")
|
||||||
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.compose.ui:ui")
|
implementation("androidx.compose.ui:ui")
|
||||||
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")
|
||||||
|
Binary file not shown.
Before Width: | Height: | Size: 31 KiB |
@ -10,13 +10,13 @@
|
|||||||
android:label="@string/app_name"
|
android:label="@string/app_name"
|
||||||
android:roundIcon="@mipmap/ic_launcher_round"
|
android:roundIcon="@mipmap/ic_launcher_round"
|
||||||
android:supportsRtl="true"
|
android:supportsRtl="true"
|
||||||
android:theme="@style/Theme.Pmudemo"
|
android:theme="@style/Theme.MyApplication"
|
||||||
tools:targetApi="31">
|
tools:targetApi="31">
|
||||||
<activity
|
<activity
|
||||||
android:name=".MainComposeActivity"
|
android:name=".MainActivity"
|
||||||
android:exported="true"
|
android:exported="true"
|
||||||
android:label="@string/app_name"
|
android:label="@string/app_name"
|
||||||
android:theme="@style/Theme.Pmudemo">
|
android:theme="@style/Theme.MyApplication">
|
||||||
<intent-filter>
|
<intent-filter>
|
||||||
<action android:name="android.intent.action.MAIN" />
|
<action android:name="android.intent.action.MAIN" />
|
||||||
|
|
||||||
|
43
app/src/main/java/com/example/myapplication/MainActivity.kt
Normal file
43
app/src/main/java/com/example/myapplication/MainActivity.kt
Normal file
@ -0,0 +1,43 @@
|
|||||||
|
package com.example.myapplication
|
||||||
|
|
||||||
|
import android.os.Bundle
|
||||||
|
import androidx.activity.ComponentActivity
|
||||||
|
import androidx.activity.compose.setContent
|
||||||
|
import androidx.compose.foundation.layout.fillMaxSize
|
||||||
|
import androidx.compose.material3.MaterialTheme
|
||||||
|
import androidx.compose.material3.Surface
|
||||||
|
import androidx.compose.material3.Text
|
||||||
|
import androidx.compose.runtime.Composable
|
||||||
|
import androidx.compose.ui.Modifier
|
||||||
|
import androidx.compose.ui.tooling.preview.Preview
|
||||||
|
import com.example.myapplication.ui.theme.MyApplicationTheme
|
||||||
|
|
||||||
|
class MainActivity : ComponentActivity() {
|
||||||
|
override fun onCreate(savedInstanceState: Bundle?) {
|
||||||
|
super.onCreate(savedInstanceState)
|
||||||
|
setContent {
|
||||||
|
MyApplicationTheme {
|
||||||
|
// A surface container using the 'background' color from the theme
|
||||||
|
Surface(modifier = Modifier.fillMaxSize(), color = MaterialTheme.colorScheme.background) {
|
||||||
|
Greeting("Android")
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Composable
|
||||||
|
fun Greeting(name: String, modifier: Modifier = Modifier) {
|
||||||
|
Text(
|
||||||
|
text = "Hello $name!",
|
||||||
|
modifier = modifier
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
|
@Preview(showBackground = true)
|
||||||
|
@Composable
|
||||||
|
fun GreetingPreview() {
|
||||||
|
MyApplicationTheme {
|
||||||
|
Greeting("Android")
|
||||||
|
}
|
||||||
|
}
|
@ -1,43 +0,0 @@
|
|||||||
package com.example.myapplication
|
|
||||||
|
|
||||||
import android.os.Bundle
|
|
||||||
import androidx.activity.ComponentActivity
|
|
||||||
import androidx.activity.compose.setContent
|
|
||||||
import androidx.compose.foundation.layout.fillMaxSize
|
|
||||||
import androidx.compose.material3.MaterialTheme
|
|
||||||
import androidx.compose.material3.Surface
|
|
||||||
import androidx.compose.runtime.LaunchedEffect
|
|
||||||
import androidx.compose.runtime.mutableStateOf
|
|
||||||
import androidx.compose.ui.Modifier
|
|
||||||
import com.example.myapplication.composeui.navigation.MainNavbar
|
|
||||||
import com.example.myapplication.datastore.DataStoreManager
|
|
||||||
import com.example.myapplication.ui.theme.PmudemoTheme
|
|
||||||
import com.jakewharton.threetenabp.AndroidThreeTen
|
|
||||||
|
|
||||||
class MainComposeActivity : ComponentActivity() {
|
|
||||||
private val dataStoreManager = DataStoreManager(this)
|
|
||||||
private val isDarkTheme = mutableStateOf(true)
|
|
||||||
override fun onCreate(savedInstanceState: Bundle?) {
|
|
||||||
super.onCreate(savedInstanceState)
|
|
||||||
application.deleteDatabase("pmy-db")
|
|
||||||
AndroidThreeTen.init(this)
|
|
||||||
setContent {
|
|
||||||
PmudemoTheme(darkTheme = isDarkTheme.value) {
|
|
||||||
LaunchedEffect(key1 = true) {
|
|
||||||
dataStoreManager.getSettings().collect { setting ->
|
|
||||||
isDarkTheme.value = setting.isDarkTheme
|
|
||||||
}
|
|
||||||
}
|
|
||||||
Surface(
|
|
||||||
modifier = Modifier.fillMaxSize(),
|
|
||||||
color = MaterialTheme.colorScheme.background
|
|
||||||
) {
|
|
||||||
MainNavbar(
|
|
||||||
isDarkTheme = isDarkTheme,
|
|
||||||
dataStoreManager = dataStoreManager
|
|
||||||
)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
@ -1,190 +0,0 @@
|
|||||||
package com.example.myapplication.composeui
|
|
||||||
|
|
||||||
import android.content.res.Configuration
|
|
||||||
import android.graphics.BitmapFactory
|
|
||||||
import androidx.compose.foundation.Image
|
|
||||||
import androidx.compose.foundation.background
|
|
||||||
import androidx.compose.foundation.layout.Arrangement
|
|
||||||
import androidx.compose.foundation.layout.Box
|
|
||||||
import androidx.compose.foundation.layout.Column
|
|
||||||
import androidx.compose.foundation.layout.Row
|
|
||||||
import androidx.compose.foundation.layout.Spacer
|
|
||||||
import androidx.compose.foundation.layout.fillMaxWidth
|
|
||||||
import androidx.compose.foundation.layout.padding
|
|
||||||
import androidx.compose.foundation.layout.size
|
|
||||||
import androidx.compose.foundation.lazy.LazyColumn
|
|
||||||
import androidx.compose.foundation.lazy.items
|
|
||||||
import androidx.compose.foundation.shape.RoundedCornerShape
|
|
||||||
import androidx.compose.material.icons.Icons
|
|
||||||
import androidx.compose.material.icons.filled.Add
|
|
||||||
import androidx.compose.material3.Button
|
|
||||||
import androidx.compose.material3.Icon
|
|
||||||
import androidx.compose.material3.IconButton
|
|
||||||
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.getValue
|
|
||||||
import androidx.compose.runtime.mutableStateListOf
|
|
||||||
import androidx.compose.runtime.mutableStateOf
|
|
||||||
import androidx.compose.runtime.remember
|
|
||||||
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.asImageBitmap
|
|
||||||
import androidx.compose.ui.graphics.vector.ImageVector
|
|
||||||
import androidx.compose.ui.platform.LocalContext
|
|
||||||
import androidx.compose.ui.res.vectorResource
|
|
||||||
import androidx.compose.ui.tooling.preview.Preview
|
|
||||||
import androidx.compose.ui.unit.dp
|
|
||||||
import com.example.myapplication.R
|
|
||||||
import com.example.myapplication.database.AppDatabase
|
|
||||||
import com.example.myapplication.entities.model.SessionFromCart
|
|
||||||
import com.example.myapplication.ui.theme.PmudemoTheme
|
|
||||||
import kotlinx.coroutines.Dispatchers
|
|
||||||
import kotlinx.coroutines.withContext
|
|
||||||
import org.threeten.bp.format.DateTimeFormatter
|
|
||||||
|
|
||||||
@Composable
|
|
||||||
fun Cart(id: Int) {
|
|
||||||
val context = LocalContext.current
|
|
||||||
val sessions = remember { mutableStateListOf<SessionFromCart>() }
|
|
||||||
LaunchedEffect(Unit) {
|
|
||||||
withContext(Dispatchers.IO) {
|
|
||||||
AppDatabase.getInstance(context).userDao().getCartByUid(id).collect { data ->
|
|
||||||
sessions.clear()
|
|
||||||
sessions.addAll(data)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
LazyColumn(
|
|
||||||
modifier = Modifier
|
|
||||||
.padding(all = 10.dp)
|
|
||||||
) {
|
|
||||||
items(sessions) { session ->
|
|
||||||
var currentCount by remember { mutableStateOf(session.count) }
|
|
||||||
|
|
||||||
val dateFormatter = DateTimeFormatter.ofPattern("dd.MM.yyyy HH:mm")
|
|
||||||
val formattedDate = dateFormatter.format(session.dateTime)
|
|
||||||
|
|
||||||
Text(
|
|
||||||
text = formattedDate,
|
|
||||||
color = MaterialTheme.colorScheme.onBackground,
|
|
||||||
)
|
|
||||||
Box(
|
|
||||||
modifier = Modifier
|
|
||||||
.fillMaxWidth()
|
|
||||||
.padding(10.dp)
|
|
||||||
.clip(RoundedCornerShape(16.dp))
|
|
||||||
.background(MaterialTheme.colorScheme.secondary)
|
|
||||||
) {
|
|
||||||
Row(
|
|
||||||
modifier = Modifier
|
|
||||||
.fillMaxWidth()
|
|
||||||
.padding(8.dp),
|
|
||||||
verticalAlignment = Alignment.CenterVertically,
|
|
||||||
horizontalArrangement = Arrangement.SpaceBetween
|
|
||||||
) {
|
|
||||||
if (session.cinema.image != null)
|
|
||||||
Image(
|
|
||||||
bitmap = BitmapFactory.decodeByteArray(
|
|
||||||
session.cinema.image,
|
|
||||||
0,
|
|
||||||
session.cinema.image.size
|
|
||||||
).asImageBitmap(),
|
|
||||||
contentDescription = null,
|
|
||||||
modifier = Modifier
|
|
||||||
.size(90.dp)
|
|
||||||
.padding(4.dp)
|
|
||||||
)
|
|
||||||
|
|
||||||
Column(
|
|
||||||
modifier = Modifier.weight(1f),
|
|
||||||
verticalArrangement = Arrangement.spacedBy(4.dp)
|
|
||||||
) {
|
|
||||||
Text(
|
|
||||||
text = "${session.cinema.name}, ${session.cinema.year}\n" +
|
|
||||||
"Цена: ${session.price}\n" +
|
|
||||||
"${currentCount}/${session.availableCount}",
|
|
||||||
color = MaterialTheme.colorScheme.onSecondary
|
|
||||||
)
|
|
||||||
}
|
|
||||||
|
|
||||||
Box(
|
|
||||||
modifier = Modifier
|
|
||||||
.background(
|
|
||||||
color = MaterialTheme.colorScheme.background,
|
|
||||||
shape = RoundedCornerShape(10.dp)
|
|
||||||
) // Задаем фон для кнопок
|
|
||||||
) {
|
|
||||||
Row(
|
|
||||||
verticalAlignment = Alignment.CenterVertically
|
|
||||||
) {
|
|
||||||
IconButton(
|
|
||||||
onClick = {
|
|
||||||
if (currentCount > 0) {
|
|
||||||
currentCount--
|
|
||||||
}
|
|
||||||
}
|
|
||||||
) {
|
|
||||||
Icon(
|
|
||||||
imageVector = ImageVector.vectorResource(id = R.drawable.minus),
|
|
||||||
contentDescription = "Уменьшить",
|
|
||||||
tint = MaterialTheme.colorScheme.onBackground,
|
|
||||||
modifier = Modifier.size(10.dp)
|
|
||||||
)
|
|
||||||
}
|
|
||||||
|
|
||||||
Text(
|
|
||||||
text = "$currentCount",
|
|
||||||
color = MaterialTheme.colorScheme.onBackground
|
|
||||||
)
|
|
||||||
|
|
||||||
IconButton(
|
|
||||||
onClick = {
|
|
||||||
if (currentCount < session.availableCount) {
|
|
||||||
currentCount++
|
|
||||||
}
|
|
||||||
}
|
|
||||||
) {
|
|
||||||
Icon(
|
|
||||||
imageVector = Icons.Default.Add,
|
|
||||||
contentDescription = "Увеличить",
|
|
||||||
tint = MaterialTheme.colorScheme.onBackground,
|
|
||||||
modifier = Modifier.size(10.dp)
|
|
||||||
)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
Column {
|
|
||||||
Spacer(modifier = Modifier.weight(1f))
|
|
||||||
|
|
||||||
Button(
|
|
||||||
onClick = { },
|
|
||||||
modifier = Modifier
|
|
||||||
.padding(16.dp)
|
|
||||||
.fillMaxWidth()
|
|
||||||
) { Text("Купить") }
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
@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 CartPreview() {
|
|
||||||
PmudemoTheme {
|
|
||||||
Surface(
|
|
||||||
color = MaterialTheme.colorScheme.background
|
|
||||||
) {
|
|
||||||
Cart(1)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
@ -1,218 +0,0 @@
|
|||||||
package com.example.myapplication.composeui.navigation
|
|
||||||
|
|
||||||
import androidx.compose.foundation.background
|
|
||||||
import androidx.compose.foundation.clickable
|
|
||||||
import androidx.compose.foundation.layout.Box
|
|
||||||
import androidx.compose.foundation.layout.PaddingValues
|
|
||||||
import androidx.compose.foundation.layout.Row
|
|
||||||
import androidx.compose.foundation.layout.Spacer
|
|
||||||
import androidx.compose.foundation.layout.fillMaxWidth
|
|
||||||
import androidx.compose.foundation.layout.height
|
|
||||||
import androidx.compose.foundation.layout.padding
|
|
||||||
import androidx.compose.foundation.layout.size
|
|
||||||
import androidx.compose.foundation.layout.width
|
|
||||||
import androidx.compose.foundation.shape.RoundedCornerShape
|
|
||||||
import androidx.compose.foundation.text.BasicTextField
|
|
||||||
import androidx.compose.foundation.text.KeyboardActions
|
|
||||||
import androidx.compose.foundation.text.KeyboardOptions
|
|
||||||
import androidx.compose.material.icons.Icons
|
|
||||||
import androidx.compose.material.icons.filled.ArrowBack
|
|
||||||
import androidx.compose.material.icons.filled.Person
|
|
||||||
import androidx.compose.material.icons.filled.Search
|
|
||||||
import androidx.compose.material3.ExperimentalMaterial3Api
|
|
||||||
import androidx.compose.material3.Icon
|
|
||||||
import androidx.compose.material3.MaterialTheme
|
|
||||||
import androidx.compose.material3.NavigationBar
|
|
||||||
import androidx.compose.material3.NavigationBarItem
|
|
||||||
import androidx.compose.material3.Scaffold
|
|
||||||
import androidx.compose.material3.Text
|
|
||||||
import androidx.compose.runtime.Composable
|
|
||||||
import androidx.compose.runtime.MutableState
|
|
||||||
import androidx.compose.runtime.getValue
|
|
||||||
import androidx.compose.runtime.mutableStateOf
|
|
||||||
import androidx.compose.runtime.remember
|
|
||||||
import androidx.compose.runtime.setValue
|
|
||||||
import androidx.compose.ui.Alignment
|
|
||||||
import androidx.compose.ui.Modifier
|
|
||||||
import androidx.compose.ui.res.stringResource
|
|
||||||
import androidx.compose.ui.unit.dp
|
|
||||||
import androidx.navigation.NavDestination
|
|
||||||
import androidx.navigation.NavDestination.Companion.hierarchy
|
|
||||||
import androidx.navigation.NavGraph.Companion.findStartDestination
|
|
||||||
import androidx.navigation.NavHostController
|
|
||||||
import androidx.navigation.NavType
|
|
||||||
import androidx.navigation.compose.NavHost
|
|
||||||
import androidx.navigation.compose.composable
|
|
||||||
import androidx.navigation.compose.currentBackStackEntryAsState
|
|
||||||
import androidx.navigation.compose.rememberNavController
|
|
||||||
import androidx.navigation.navArgument
|
|
||||||
import com.example.myapplication.composeui.Cart
|
|
||||||
import com.example.myapplication.datastore.DataStoreManager
|
|
||||||
import com.example.myapplication.entities.composeui.CinemaList
|
|
||||||
import com.example.myapplication.entities.composeui.CinemaView
|
|
||||||
import com.example.myapplication.entities.composeui.OrderList
|
|
||||||
import com.example.myapplication.entities.composeui.OrderView
|
|
||||||
import com.example.myapplication.user.composeui.UserProfile
|
|
||||||
|
|
||||||
@Composable
|
|
||||||
fun Topbar(
|
|
||||||
navController: NavHostController,
|
|
||||||
currentScreen: Screen?
|
|
||||||
) {
|
|
||||||
var searchQuery by remember { mutableStateOf("") }
|
|
||||||
Box(
|
|
||||||
modifier = Modifier
|
|
||||||
.fillMaxWidth()
|
|
||||||
.background(color = MaterialTheme.colorScheme.primary)
|
|
||||||
) {
|
|
||||||
Row(
|
|
||||||
modifier = Modifier
|
|
||||||
.fillMaxWidth()
|
|
||||||
.padding(10.dp),
|
|
||||||
verticalAlignment = Alignment.CenterVertically
|
|
||||||
) {
|
|
||||||
if (
|
|
||||||
navController.previousBackStackEntry != null
|
|
||||||
&& (currentScreen == null || !currentScreen.showInBottomBar)
|
|
||||||
) {
|
|
||||||
Icon(
|
|
||||||
imageVector = Icons.Filled.ArrowBack,
|
|
||||||
contentDescription = null,
|
|
||||||
modifier = Modifier
|
|
||||||
.size(30.dp)
|
|
||||||
.clickable { navController.navigateUp() },
|
|
||||||
tint = MaterialTheme.colorScheme.secondary
|
|
||||||
)
|
|
||||||
} else
|
|
||||||
Icon(
|
|
||||||
imageVector = Icons.Default.Person,
|
|
||||||
contentDescription = null,
|
|
||||||
modifier = Modifier
|
|
||||||
.size(30.dp)
|
|
||||||
.clickable { navController.navigate(Screen.UserProfile.route) },
|
|
||||||
tint = MaterialTheme.colorScheme.secondary
|
|
||||||
)
|
|
||||||
|
|
||||||
Spacer(modifier = Modifier.width(16.dp))
|
|
||||||
|
|
||||||
BasicTextField(
|
|
||||||
value = searchQuery,
|
|
||||||
onValueChange = { newValue -> searchQuery = newValue },
|
|
||||||
modifier = Modifier
|
|
||||||
.weight(1f)
|
|
||||||
.height(36.dp)
|
|
||||||
.background(
|
|
||||||
color = MaterialTheme.colorScheme.onPrimary,
|
|
||||||
RoundedCornerShape(18.dp)
|
|
||||||
)
|
|
||||||
.padding(start = 13.dp, top = 8.dp),
|
|
||||||
keyboardOptions = KeyboardOptions.Default.copy(
|
|
||||||
imeAction = androidx.compose.ui.text.input.ImeAction.Search
|
|
||||||
),
|
|
||||||
keyboardActions = KeyboardActions(
|
|
||||||
onSearch = { }
|
|
||||||
)
|
|
||||||
)
|
|
||||||
|
|
||||||
Spacer(modifier = Modifier.width(16.dp))
|
|
||||||
|
|
||||||
Icon(
|
|
||||||
imageVector = Icons.Default.Search,
|
|
||||||
contentDescription = null,
|
|
||||||
modifier = Modifier
|
|
||||||
.size(30.dp)
|
|
||||||
.clickable { },
|
|
||||||
tint = MaterialTheme.colorScheme.secondary
|
|
||||||
)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
@Composable
|
|
||||||
fun Navbar(
|
|
||||||
navController: NavHostController,
|
|
||||||
currentDestination: NavDestination?,
|
|
||||||
modifier: Modifier = Modifier
|
|
||||||
) {
|
|
||||||
NavigationBar(modifier = modifier, containerColor = MaterialTheme.colorScheme.primary) {
|
|
||||||
Screen.bottomBarItems.forEach { screen ->
|
|
||||||
NavigationBarItem(
|
|
||||||
icon = {
|
|
||||||
Icon(
|
|
||||||
screen.icon,
|
|
||||||
contentDescription = null,
|
|
||||||
tint = MaterialTheme.colorScheme.secondary
|
|
||||||
)
|
|
||||||
},
|
|
||||||
label = { Text(stringResource(screen.resourceId)) },
|
|
||||||
selected = currentDestination?.hierarchy?.any { it.route == screen.route } == true,
|
|
||||||
onClick = {
|
|
||||||
navController.navigate(screen.route) {
|
|
||||||
popUpTo(navController.graph.findStartDestination().id) {
|
|
||||||
saveState = true
|
|
||||||
}
|
|
||||||
launchSingleTop = true
|
|
||||||
restoreState = true
|
|
||||||
}
|
|
||||||
}
|
|
||||||
)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
@Composable
|
|
||||||
fun Navhost(
|
|
||||||
navController: NavHostController,
|
|
||||||
innerPadding: PaddingValues,
|
|
||||||
isDarkTheme: MutableState<Boolean>,
|
|
||||||
dataStore: DataStoreManager,
|
|
||||||
modifier: Modifier = Modifier,
|
|
||||||
) {
|
|
||||||
NavHost(
|
|
||||||
navController,
|
|
||||||
startDestination = Screen.CinemaList.route,
|
|
||||||
modifier.padding(innerPadding)
|
|
||||||
) {
|
|
||||||
composable(Screen.CinemaList.route) { CinemaList(navController) }
|
|
||||||
composable(Screen.OrderList.route) { OrderList(navController, 1) }
|
|
||||||
composable(Screen.Cart.route) { Cart(1) }
|
|
||||||
composable(Screen.UserProfile.route) { UserProfile(isDarkTheme, dataStore) }
|
|
||||||
composable(
|
|
||||||
Screen.CinemaView.route,
|
|
||||||
arguments = listOf(navArgument("id") { type = NavType.IntType })
|
|
||||||
) { backStackEntry ->
|
|
||||||
backStackEntry.arguments?.let { CinemaView(it.getInt("id")) }
|
|
||||||
}
|
|
||||||
composable(
|
|
||||||
Screen.OrderView.route,
|
|
||||||
arguments = listOf(navArgument("id") { type = NavType.IntType })
|
|
||||||
) { backStackEntry ->
|
|
||||||
backStackEntry.arguments?.let { OrderView(it.getInt("id")) }
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
@OptIn(ExperimentalMaterial3Api::class)
|
|
||||||
@Composable
|
|
||||||
fun MainNavbar(
|
|
||||||
isDarkTheme: MutableState<Boolean>,
|
|
||||||
dataStoreManager: DataStoreManager
|
|
||||||
) {
|
|
||||||
val navController = rememberNavController()
|
|
||||||
val navBackStackEntry by navController.currentBackStackEntryAsState()
|
|
||||||
val currentDestination = navBackStackEntry?.destination
|
|
||||||
val currentScreen = currentDestination?.route?.let { Screen.getItem(it) }
|
|
||||||
|
|
||||||
Scaffold(
|
|
||||||
topBar = {
|
|
||||||
Topbar(navController, currentScreen)
|
|
||||||
},
|
|
||||||
bottomBar = {
|
|
||||||
if (currentScreen == null || currentScreen.showInBottomBar) {
|
|
||||||
Navbar(navController, currentDestination)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
) { innerPadding ->
|
|
||||||
Navhost(navController, innerPadding, isDarkTheme, dataStoreManager)
|
|
||||||
}
|
|
||||||
}
|
|
@ -1,52 +0,0 @@
|
|||||||
package com.example.myapplication.composeui.navigation
|
|
||||||
|
|
||||||
import androidx.annotation.StringRes
|
|
||||||
import androidx.compose.material.icons.Icons
|
|
||||||
import androidx.compose.material.icons.filled.Favorite
|
|
||||||
import androidx.compose.material.icons.filled.Home
|
|
||||||
import androidx.compose.material.icons.filled.List
|
|
||||||
import androidx.compose.material.icons.filled.ShoppingCart
|
|
||||||
import androidx.compose.ui.graphics.vector.ImageVector
|
|
||||||
import com.example.myapplication.R
|
|
||||||
|
|
||||||
enum class Screen(
|
|
||||||
val route: String,
|
|
||||||
@StringRes val resourceId: Int,
|
|
||||||
val icon: ImageVector = Icons.Filled.Favorite,
|
|
||||||
val showInBottomBar: Boolean = true
|
|
||||||
) {
|
|
||||||
CinemaList(
|
|
||||||
"Cinema-list", R.string.Cinema_main_title, Icons.Filled.Home
|
|
||||||
),
|
|
||||||
SessionList(
|
|
||||||
"Session-list", R.string.Sessions_title, showInBottomBar = false
|
|
||||||
),
|
|
||||||
Cart(
|
|
||||||
"cart", R.string.Cart_title, Icons.Filled.ShoppingCart
|
|
||||||
),
|
|
||||||
OrderList(
|
|
||||||
"Order-list", R.string.Order_title, Icons.Filled.List
|
|
||||||
),
|
|
||||||
CinemaView(
|
|
||||||
"Cinema-view/{id}", R.string.Cinema_view_title, showInBottomBar = false
|
|
||||||
),
|
|
||||||
OrderView(
|
|
||||||
"Order-view/{id}", R.string.Order_view_title, showInBottomBar = false
|
|
||||||
),
|
|
||||||
UserProfile(
|
|
||||||
"User-profile", R.string.Profile_title, showInBottomBar = false
|
|
||||||
);
|
|
||||||
|
|
||||||
companion object {
|
|
||||||
val bottomBarItems = listOf(
|
|
||||||
CinemaList,
|
|
||||||
Cart,
|
|
||||||
OrderList
|
|
||||||
)
|
|
||||||
|
|
||||||
fun getItem(route: String): Screen? {
|
|
||||||
val findRoute = route.split("/").first()
|
|
||||||
return values().find { value -> value.route.startsWith(findRoute) }
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
@ -1,147 +0,0 @@
|
|||||||
package com.example.myapplication.database
|
|
||||||
|
|
||||||
import android.content.Context
|
|
||||||
import android.graphics.Bitmap
|
|
||||||
import android.graphics.Color
|
|
||||||
import androidx.room.Database
|
|
||||||
import androidx.room.Room
|
|
||||||
import androidx.room.RoomDatabase
|
|
||||||
import androidx.room.TypeConverters
|
|
||||||
import androidx.sqlite.db.SupportSQLiteDatabase
|
|
||||||
import com.example.myapplication.entities.dao.CinemaDao
|
|
||||||
import com.example.myapplication.entities.dao.OrderDao
|
|
||||||
import com.example.myapplication.entities.dao.OrderSessionCrossRefDao
|
|
||||||
import com.example.myapplication.entities.dao.SessionDao
|
|
||||||
import com.example.myapplication.entities.dao.UserDao
|
|
||||||
import com.example.myapplication.entities.dao.UserSessionCrossRefDao
|
|
||||||
import com.example.myapplication.entities.model.Cinema
|
|
||||||
import com.example.myapplication.entities.model.LocalDateTimeConverter
|
|
||||||
import com.example.myapplication.entities.model.Order
|
|
||||||
import com.example.myapplication.entities.model.OrderSessionCrossRef
|
|
||||||
import com.example.myapplication.entities.model.Session
|
|
||||||
import com.example.myapplication.entities.model.User
|
|
||||||
import com.example.myapplication.entities.model.UserSessionCrossRef
|
|
||||||
import kotlinx.coroutines.CoroutineScope
|
|
||||||
import kotlinx.coroutines.Dispatchers
|
|
||||||
import kotlinx.coroutines.launch
|
|
||||||
import org.threeten.bp.LocalDateTime
|
|
||||||
import java.io.ByteArrayOutputStream
|
|
||||||
|
|
||||||
@Database(
|
|
||||||
entities = [Cinema::class, Session::class, Order::class,
|
|
||||||
OrderSessionCrossRef::class, User::class, UserSessionCrossRef::class],
|
|
||||||
version = 1,
|
|
||||||
exportSchema = false
|
|
||||||
)
|
|
||||||
@TypeConverters(LocalDateTimeConverter::class)
|
|
||||||
abstract class AppDatabase : RoomDatabase() {
|
|
||||||
abstract fun cinemaDao(): CinemaDao
|
|
||||||
abstract fun sessionDao(): SessionDao
|
|
||||||
abstract fun orderDao(): OrderDao
|
|
||||||
abstract fun orderSessionCrossRefDao(): OrderSessionCrossRefDao
|
|
||||||
abstract fun userDao(): UserDao
|
|
||||||
abstract fun userSessionCrossRefDao(): UserSessionCrossRefDao
|
|
||||||
|
|
||||||
companion object {
|
|
||||||
private const val DB_NAME: String = "pmy-db"
|
|
||||||
|
|
||||||
@Volatile
|
|
||||||
private var INSTANCE: AppDatabase? = null
|
|
||||||
|
|
||||||
private suspend fun populateDatabase() {
|
|
||||||
INSTANCE?.let { database ->
|
|
||||||
// Users
|
|
||||||
val userDao = database.userDao()
|
|
||||||
val user1 = User(1, "Login", "password")
|
|
||||||
val user2 = User(2, "Login123", "password123")
|
|
||||||
userDao.insert(user1)
|
|
||||||
userDao.insert(user2)
|
|
||||||
// Cinemas
|
|
||||||
val cinemaDao = database.cinemaDao()
|
|
||||||
val cinema1 = Cinema(1, "BLUE 1", "Desc1", createColoredImage(Color.BLUE), 2023)
|
|
||||||
val cinema2 = Cinema(2, "GREEN 2", "Desc2", createColoredImage(Color.GREEN), 2023)
|
|
||||||
val cinema3 = Cinema(3, "RED 3", "Desc3", createColoredImage(Color.RED), 2023)
|
|
||||||
cinemaDao.insert(cinema1)
|
|
||||||
cinemaDao.insert(cinema2)
|
|
||||||
cinemaDao.insert(cinema3)
|
|
||||||
// Orders
|
|
||||||
val orderDao = database.orderDao()
|
|
||||||
val order1 = Order(1, 1)
|
|
||||||
val order2 = Order(2, 1)
|
|
||||||
val order3 = Order(3, 1)
|
|
||||||
val order4 = Order(4, 1)
|
|
||||||
orderDao.insert(order1)
|
|
||||||
orderDao.insert(order2)
|
|
||||||
orderDao.insert(order3)
|
|
||||||
orderDao.insert(order4)
|
|
||||||
// Sessions
|
|
||||||
val sessionDao = database.sessionDao()
|
|
||||||
val session1 = Session(1, LocalDateTime.now(), 150.0, 120, cinema1.uid)
|
|
||||||
val session2 = Session(2, LocalDateTime.now(), 200.0, 110, cinema2.uid)
|
|
||||||
val session3 = Session(3, LocalDateTime.now(), 300.0, 100, cinema3.uid)
|
|
||||||
val session4 = Session(4, LocalDateTime.now(), 320.0, 1150, cinema1.uid)
|
|
||||||
sessionDao.insert(session1)
|
|
||||||
sessionDao.insert(session2)
|
|
||||||
sessionDao.insert(session3)
|
|
||||||
sessionDao.insert(session4)
|
|
||||||
// OrderSessionCrossRef для связи заказов с сеансами
|
|
||||||
val orderSessionCrossRefDao = database.orderSessionCrossRefDao()
|
|
||||||
if (session1.uid != null && session2.uid != null && session3.uid != null && session4.uid != null) {
|
|
||||||
val orderSessionCrossRef1 = OrderSessionCrossRef(order1.uid, session3.uid, 150.0, 5)
|
|
||||||
val orderSessionCrossRef2 = OrderSessionCrossRef(order1.uid, session2.uid, 300.0, 10)
|
|
||||||
val orderSessionCrossRef3 = OrderSessionCrossRef(order2.uid, session2.uid, 350.0, 6)
|
|
||||||
val orderSessionCrossRef4 = OrderSessionCrossRef(order3.uid, session1.uid, 250.0, 10)
|
|
||||||
val orderSessionCrossRef5 = OrderSessionCrossRef(order3.uid, session3.uid, 150.0, 16)
|
|
||||||
val orderSessionCrossRef6 = OrderSessionCrossRef(order4.uid, session3.uid, 150.0, 2)
|
|
||||||
//val orderSessionCrossRef7 = OrderSessionCrossRef(order4.uid, session4.uid, 110.0, 1)
|
|
||||||
orderSessionCrossRefDao.insert(orderSessionCrossRef1)
|
|
||||||
orderSessionCrossRefDao.insert(orderSessionCrossRef2)
|
|
||||||
orderSessionCrossRefDao.insert(orderSessionCrossRef3)
|
|
||||||
orderSessionCrossRefDao.insert(orderSessionCrossRef4)
|
|
||||||
orderSessionCrossRefDao.insert(orderSessionCrossRef5)
|
|
||||||
orderSessionCrossRefDao.insert(orderSessionCrossRef6)
|
|
||||||
//orderSessionCrossRefDao.insert(orderSessionCrossRef7)
|
|
||||||
}
|
|
||||||
// UserSessions
|
|
||||||
val userSessionCrossRefDao = database.userSessionCrossRefDao()
|
|
||||||
val userSessionCrossRef1 = UserSessionCrossRef(1, 1, 5)
|
|
||||||
val userSessionCrossRef2 = UserSessionCrossRef(1, 3, 15)
|
|
||||||
userSessionCrossRefDao.insert(userSessionCrossRef1)
|
|
||||||
userSessionCrossRefDao.insert(userSessionCrossRef2)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
fun getInstance(appContext: Context): AppDatabase {
|
|
||||||
return INSTANCE ?: synchronized(this) {
|
|
||||||
Room.databaseBuilder(
|
|
||||||
appContext,
|
|
||||||
AppDatabase::class.java,
|
|
||||||
DB_NAME
|
|
||||||
)
|
|
||||||
.addCallback(object : Callback() {
|
|
||||||
override fun onCreate(db: SupportSQLiteDatabase) {
|
|
||||||
super.onCreate(db)
|
|
||||||
CoroutineScope(Dispatchers.IO).launch {
|
|
||||||
populateDatabase()
|
|
||||||
}
|
|
||||||
}
|
|
||||||
})
|
|
||||||
.build()
|
|
||||||
.also { INSTANCE = it }
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
private fun createColoredImage(color: Int): ByteArray {
|
|
||||||
val width = 100
|
|
||||||
val height = 100
|
|
||||||
|
|
||||||
val bmp = Bitmap.createBitmap(width, height, Bitmap.Config.ARGB_8888)
|
|
||||||
bmp.eraseColor(color)
|
|
||||||
|
|
||||||
val stream = ByteArrayOutputStream()
|
|
||||||
bmp.compress(Bitmap.CompressFormat.PNG, 100, stream)
|
|
||||||
|
|
||||||
return stream.toByteArray()
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
@ -1,25 +0,0 @@
|
|||||||
package com.example.myapplication.datastore
|
|
||||||
|
|
||||||
import android.content.Context
|
|
||||||
import androidx.datastore.core.DataStore
|
|
||||||
import androidx.datastore.preferences.core.Preferences
|
|
||||||
import androidx.datastore.preferences.core.booleanPreferencesKey
|
|
||||||
import androidx.datastore.preferences.core.edit
|
|
||||||
import androidx.datastore.preferences.preferencesDataStore
|
|
||||||
import kotlinx.coroutines.flow.map
|
|
||||||
|
|
||||||
private val Context.dataStore: DataStore<Preferences> by preferencesDataStore("data_store")
|
|
||||||
|
|
||||||
class DataStoreManager(private val context: Context) {
|
|
||||||
suspend fun saveSettings(settingData: SettingData) {
|
|
||||||
context.dataStore.edit { pref ->
|
|
||||||
pref[booleanPreferencesKey("isDarkTheme")] = settingData.isDarkTheme
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
fun getSettings() = context.dataStore.data.map { pref ->
|
|
||||||
return@map SettingData(
|
|
||||||
pref[booleanPreferencesKey("isDarkTheme")] ?: true
|
|
||||||
)
|
|
||||||
}
|
|
||||||
}
|
|
@ -1,5 +0,0 @@
|
|||||||
package com.example.myapplication.datastore
|
|
||||||
|
|
||||||
data class SettingData(
|
|
||||||
val isDarkTheme: Boolean
|
|
||||||
)
|
|
@ -1,109 +0,0 @@
|
|||||||
package com.example.myapplication.entities.composeui
|
|
||||||
|
|
||||||
import android.content.res.Configuration
|
|
||||||
import android.graphics.BitmapFactory
|
|
||||||
import androidx.compose.foundation.Image
|
|
||||||
import androidx.compose.foundation.background
|
|
||||||
import androidx.compose.foundation.clickable
|
|
||||||
import androidx.compose.foundation.layout.Arrangement
|
|
||||||
import androidx.compose.foundation.layout.Box
|
|
||||||
import androidx.compose.foundation.layout.Row
|
|
||||||
import androidx.compose.foundation.layout.fillMaxSize
|
|
||||||
import androidx.compose.foundation.layout.fillMaxWidth
|
|
||||||
import androidx.compose.foundation.layout.padding
|
|
||||||
import androidx.compose.foundation.layout.size
|
|
||||||
import androidx.compose.foundation.lazy.LazyColumn
|
|
||||||
import androidx.compose.foundation.lazy.items
|
|
||||||
import androidx.compose.foundation.shape.RoundedCornerShape
|
|
||||||
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.graphics.asImageBitmap
|
|
||||||
import androidx.compose.ui.platform.LocalContext
|
|
||||||
import androidx.compose.ui.tooling.preview.Preview
|
|
||||||
import androidx.compose.ui.unit.dp
|
|
||||||
import androidx.navigation.NavController
|
|
||||||
import com.example.myapplication.composeui.navigation.Screen
|
|
||||||
import com.example.myapplication.database.AppDatabase
|
|
||||||
import com.example.myapplication.entities.model.Cinema
|
|
||||||
import com.example.myapplication.ui.theme.PmudemoTheme
|
|
||||||
import kotlinx.coroutines.Dispatchers
|
|
||||||
import kotlinx.coroutines.withContext
|
|
||||||
|
|
||||||
@Composable
|
|
||||||
fun CinemaList(navController: NavController?) {
|
|
||||||
val context = LocalContext.current
|
|
||||||
val cinemas = remember { mutableStateListOf<Cinema>() }
|
|
||||||
LaunchedEffect(Unit) {
|
|
||||||
withContext(Dispatchers.IO) {
|
|
||||||
AppDatabase.getInstance(context).cinemaDao().getAll().collect { data ->
|
|
||||||
cinemas.clear()
|
|
||||||
cinemas.addAll(data)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
LazyColumn(
|
|
||||||
modifier = Modifier
|
|
||||||
.fillMaxSize()
|
|
||||||
.padding(all = 10.dp)
|
|
||||||
) {
|
|
||||||
items(cinemas) { cinema ->
|
|
||||||
val cinemaId = Screen.CinemaView.route.replace("{id}", cinema.uid.toString())
|
|
||||||
Box(
|
|
||||||
modifier = Modifier
|
|
||||||
.fillMaxWidth()
|
|
||||||
.padding(all = 10.dp)
|
|
||||||
.clickable { navController?.navigate(cinemaId) }
|
|
||||||
.background(
|
|
||||||
color = MaterialTheme.colorScheme.secondary,
|
|
||||||
shape = RoundedCornerShape(16.dp)
|
|
||||||
)
|
|
||||||
) {
|
|
||||||
Row(
|
|
||||||
modifier = Modifier
|
|
||||||
.fillMaxWidth()
|
|
||||||
.padding(8.dp),
|
|
||||||
verticalAlignment = Alignment.CenterVertically,
|
|
||||||
horizontalArrangement = Arrangement.spacedBy(8.dp)
|
|
||||||
) {
|
|
||||||
if (cinema.image != null)
|
|
||||||
Image(
|
|
||||||
bitmap = BitmapFactory.decodeByteArray(
|
|
||||||
cinema.image,
|
|
||||||
0,
|
|
||||||
cinema.image.size
|
|
||||||
).asImageBitmap(),
|
|
||||||
contentDescription = null,
|
|
||||||
modifier = Modifier
|
|
||||||
.size(90.dp)
|
|
||||||
.padding(4.dp)
|
|
||||||
)
|
|
||||||
|
|
||||||
Text(
|
|
||||||
"${cinema.name}, ${cinema.year}",
|
|
||||||
color = MaterialTheme.colorScheme.onSecondary
|
|
||||||
)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
@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 CinemaListPreview() {
|
|
||||||
PmudemoTheme {
|
|
||||||
Surface(
|
|
||||||
color = MaterialTheme.colorScheme.background
|
|
||||||
) {
|
|
||||||
CinemaList(navController = null)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
@ -1,209 +0,0 @@
|
|||||||
package com.example.myapplication.entities.composeui
|
|
||||||
|
|
||||||
import android.content.res.Configuration
|
|
||||||
import android.graphics.BitmapFactory
|
|
||||||
import androidx.compose.foundation.Image
|
|
||||||
import androidx.compose.foundation.background
|
|
||||||
import androidx.compose.foundation.clickable
|
|
||||||
import androidx.compose.foundation.layout.Arrangement
|
|
||||||
import androidx.compose.foundation.layout.Box
|
|
||||||
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.size
|
|
||||||
import androidx.compose.foundation.lazy.LazyColumn
|
|
||||||
import androidx.compose.foundation.lazy.items
|
|
||||||
import androidx.compose.foundation.shape.RoundedCornerShape
|
|
||||||
import androidx.compose.material.icons.Icons
|
|
||||||
import androidx.compose.material.icons.filled.ShoppingCart
|
|
||||||
import androidx.compose.material3.Icon
|
|
||||||
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.mutableStateOf
|
|
||||||
import androidx.compose.runtime.remember
|
|
||||||
import androidx.compose.ui.Alignment
|
|
||||||
import androidx.compose.ui.Modifier
|
|
||||||
import androidx.compose.ui.draw.clip
|
|
||||||
import androidx.compose.ui.graphics.asImageBitmap
|
|
||||||
import androidx.compose.ui.platform.LocalContext
|
|
||||||
import androidx.compose.ui.text.TextStyle
|
|
||||||
import androidx.compose.ui.text.font.FontWeight
|
|
||||||
import androidx.compose.ui.tooling.preview.Preview
|
|
||||||
import androidx.compose.ui.unit.dp
|
|
||||||
import androidx.compose.ui.unit.sp
|
|
||||||
import com.example.myapplication.database.AppDatabase
|
|
||||||
import com.example.myapplication.entities.model.Cinema
|
|
||||||
import com.example.myapplication.entities.model.SessionFromCinema
|
|
||||||
import com.example.myapplication.ui.theme.PmudemoTheme
|
|
||||||
import kotlinx.coroutines.Dispatchers
|
|
||||||
import kotlinx.coroutines.withContext
|
|
||||||
import org.threeten.bp.format.DateTimeFormatter
|
|
||||||
|
|
||||||
@Composable
|
|
||||||
fun CinemaView(id: Int) {
|
|
||||||
val context = LocalContext.current
|
|
||||||
val cinemaWithSessions = remember {
|
|
||||||
mutableStateListOf<Pair<Cinema, List<SessionFromCinema>>>()
|
|
||||||
}
|
|
||||||
LaunchedEffect(Unit) {
|
|
||||||
withContext(Dispatchers.IO) {
|
|
||||||
cinemaWithSessions.clear()
|
|
||||||
cinemaWithSessions
|
|
||||||
.addAll(AppDatabase.getInstance(context).cinemaDao().getByUid(id).map { (cinema, sessionFromCinema) ->
|
|
||||||
Pair(cinema, sessionFromCinema)
|
|
||||||
})
|
|
||||||
}
|
|
||||||
}
|
|
||||||
val cinema = cinemaWithSessions.firstOrNull()?.first
|
|
||||||
val sessions = cinemaWithSessions.firstOrNull()?.second
|
|
||||||
|
|
||||||
LazyColumn(
|
|
||||||
modifier = Modifier
|
|
||||||
.fillMaxSize()
|
|
||||||
.padding(16.dp)
|
|
||||||
) {
|
|
||||||
item {
|
|
||||||
Box(
|
|
||||||
modifier = Modifier
|
|
||||||
.fillMaxSize()
|
|
||||||
.background(
|
|
||||||
color = MaterialTheme.colorScheme.secondary,
|
|
||||||
shape = RoundedCornerShape(16.dp)
|
|
||||||
)
|
|
||||||
) {
|
|
||||||
Column(
|
|
||||||
modifier = Modifier
|
|
||||||
.fillMaxWidth()
|
|
||||||
.padding(16.dp)
|
|
||||||
.background(color = MaterialTheme.colorScheme.secondary),
|
|
||||||
verticalArrangement = Arrangement.spacedBy(8.dp)
|
|
||||||
) {
|
|
||||||
Text(
|
|
||||||
text = "${cinema?.name ?: ""}, ${cinema?.year ?: 1930}",
|
|
||||||
style = TextStyle(
|
|
||||||
fontWeight = FontWeight.Bold,
|
|
||||||
fontSize = 18.sp,
|
|
||||||
color = MaterialTheme.colorScheme.onSecondary
|
|
||||||
),
|
|
||||||
modifier = Modifier
|
|
||||||
.fillMaxWidth()
|
|
||||||
.padding(bottom = 8.dp)
|
|
||||||
)
|
|
||||||
if (cinema?.image != null)
|
|
||||||
Image(
|
|
||||||
bitmap = BitmapFactory.decodeByteArray(
|
|
||||||
cinema.image,
|
|
||||||
0,
|
|
||||||
cinema.image.size
|
|
||||||
).asImageBitmap(),
|
|
||||||
contentDescription = null,
|
|
||||||
modifier = Modifier
|
|
||||||
.fillMaxWidth()
|
|
||||||
.height(200.dp)
|
|
||||||
.padding(4.dp)
|
|
||||||
)
|
|
||||||
|
|
||||||
Text(
|
|
||||||
text = cinema?.description ?: "",
|
|
||||||
color = MaterialTheme.colorScheme.onSecondary
|
|
||||||
)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
item {
|
|
||||||
Text(
|
|
||||||
text = "Сеансы",
|
|
||||||
style = TextStyle(
|
|
||||||
fontWeight = FontWeight.Bold,
|
|
||||||
fontSize = 18.sp,
|
|
||||||
color = MaterialTheme.colorScheme.onBackground
|
|
||||||
),
|
|
||||||
modifier = Modifier
|
|
||||||
.fillMaxWidth()
|
|
||||||
.padding(top = 8.dp, bottom = 8.dp),
|
|
||||||
)
|
|
||||||
}
|
|
||||||
|
|
||||||
if (sessions != null) {
|
|
||||||
items(sessions) { session ->
|
|
||||||
val dateFormatter = DateTimeFormatter.ofPattern("dd.MM.yyyy HH:mm")
|
|
||||||
val formattedDate = dateFormatter.format(session.dateTime)
|
|
||||||
Text(
|
|
||||||
text = formattedDate,
|
|
||||||
color = MaterialTheme.colorScheme.onBackground,
|
|
||||||
)
|
|
||||||
Box(
|
|
||||||
modifier = Modifier
|
|
||||||
.fillMaxWidth()
|
|
||||||
.padding(10.dp)
|
|
||||||
.clip(RoundedCornerShape(16.dp))
|
|
||||||
.background(MaterialTheme.colorScheme.secondary)
|
|
||||||
) {
|
|
||||||
Row(
|
|
||||||
modifier = Modifier
|
|
||||||
.fillMaxWidth()
|
|
||||||
.padding(8.dp),
|
|
||||||
verticalAlignment = Alignment.CenterVertically,
|
|
||||||
horizontalArrangement = Arrangement.SpaceBetween
|
|
||||||
) {
|
|
||||||
if (cinema?.image != null)
|
|
||||||
Image(
|
|
||||||
bitmap = BitmapFactory.decodeByteArray(
|
|
||||||
cinema.image,
|
|
||||||
0,
|
|
||||||
cinema.image.size
|
|
||||||
).asImageBitmap(),
|
|
||||||
contentDescription = null,
|
|
||||||
modifier = Modifier
|
|
||||||
.size(90.dp)
|
|
||||||
.padding(4.dp)
|
|
||||||
)
|
|
||||||
|
|
||||||
Column(
|
|
||||||
modifier = Modifier.weight(1f),
|
|
||||||
verticalArrangement = Arrangement.spacedBy(4.dp)
|
|
||||||
) {
|
|
||||||
Text(
|
|
||||||
text = "Цена: ${session.price}\n" +
|
|
||||||
"Билетов: ${session.availableCount}",
|
|
||||||
color = MaterialTheme.colorScheme.onSecondary
|
|
||||||
)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
Icon(
|
|
||||||
imageVector = Icons.Filled.ShoppingCart,
|
|
||||||
contentDescription = null,
|
|
||||||
modifier = Modifier
|
|
||||||
.padding(10.dp)
|
|
||||||
.size(24.dp)
|
|
||||||
.clickable {}
|
|
||||||
.align(Alignment.CenterEnd),
|
|
||||||
tint = MaterialTheme.colorScheme.onSecondary
|
|
||||||
)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
@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 CinemaViewPreview() {
|
|
||||||
PmudemoTheme {
|
|
||||||
Surface(
|
|
||||||
color = MaterialTheme.colorScheme.background
|
|
||||||
) {
|
|
||||||
CinemaView(id = 0)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
@ -1,89 +0,0 @@
|
|||||||
package com.example.myapplication.entities.composeui
|
|
||||||
|
|
||||||
import android.content.res.Configuration
|
|
||||||
import androidx.compose.foundation.background
|
|
||||||
import androidx.compose.foundation.clickable
|
|
||||||
import androidx.compose.foundation.layout.Arrangement
|
|
||||||
import androidx.compose.foundation.layout.Box
|
|
||||||
import androidx.compose.foundation.layout.Row
|
|
||||||
import androidx.compose.foundation.layout.fillMaxSize
|
|
||||||
import androidx.compose.foundation.layout.fillMaxWidth
|
|
||||||
import androidx.compose.foundation.layout.padding
|
|
||||||
import androidx.compose.foundation.lazy.LazyColumn
|
|
||||||
import androidx.compose.foundation.lazy.items
|
|
||||||
import androidx.compose.foundation.shape.RoundedCornerShape
|
|
||||||
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.platform.LocalContext
|
|
||||||
import androidx.compose.ui.tooling.preview.Preview
|
|
||||||
import androidx.compose.ui.unit.dp
|
|
||||||
import androidx.navigation.NavController
|
|
||||||
import com.example.myapplication.composeui.navigation.Screen
|
|
||||||
import com.example.myapplication.database.AppDatabase
|
|
||||||
import com.example.myapplication.entities.model.Order
|
|
||||||
import com.example.myapplication.ui.theme.PmudemoTheme
|
|
||||||
import kotlinx.coroutines.Dispatchers
|
|
||||||
import kotlinx.coroutines.withContext
|
|
||||||
|
|
||||||
@Composable
|
|
||||||
fun OrderList(navController: NavController?, userId: Int?) {
|
|
||||||
val context = LocalContext.current
|
|
||||||
val orders = remember { mutableStateListOf<Order>() }
|
|
||||||
LaunchedEffect(Unit) {
|
|
||||||
withContext(Dispatchers.IO) {
|
|
||||||
AppDatabase.getInstance(context).orderDao().getAll(userId).collect { data ->
|
|
||||||
orders.clear()
|
|
||||||
orders.addAll(data)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
LazyColumn(
|
|
||||||
modifier = Modifier
|
|
||||||
.fillMaxSize()
|
|
||||||
.padding(all = 10.dp)
|
|
||||||
) {
|
|
||||||
items(orders) { order ->
|
|
||||||
val orderId = Screen.OrderView.route.replace("{id}", order.uid.toString())
|
|
||||||
Box(
|
|
||||||
modifier = Modifier
|
|
||||||
.fillMaxWidth()
|
|
||||||
.padding(all = 10.dp)
|
|
||||||
.clickable { navController?.navigate(orderId) }
|
|
||||||
.background(
|
|
||||||
color = MaterialTheme.colorScheme.secondary,
|
|
||||||
shape = RoundedCornerShape(16.dp)
|
|
||||||
)
|
|
||||||
) {
|
|
||||||
Row(
|
|
||||||
modifier = Modifier
|
|
||||||
.fillMaxWidth()
|
|
||||||
.padding(8.dp),
|
|
||||||
verticalAlignment = Alignment.CenterVertically,
|
|
||||||
horizontalArrangement = Arrangement.spacedBy(8.dp)
|
|
||||||
) {
|
|
||||||
Text("Заказ №${order.uid}", color = MaterialTheme.colorScheme.onSecondary)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
@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 OrderListPreview() {
|
|
||||||
PmudemoTheme {
|
|
||||||
Surface(
|
|
||||||
color = MaterialTheme.colorScheme.background
|
|
||||||
) {
|
|
||||||
OrderList(navController = null, 1)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
@ -1,123 +0,0 @@
|
|||||||
package com.example.myapplication.entities.composeui
|
|
||||||
|
|
||||||
import android.content.res.Configuration
|
|
||||||
import android.graphics.BitmapFactory
|
|
||||||
import androidx.compose.foundation.Image
|
|
||||||
import androidx.compose.foundation.background
|
|
||||||
import androidx.compose.foundation.layout.Arrangement
|
|
||||||
import androidx.compose.foundation.layout.Box
|
|
||||||
import androidx.compose.foundation.layout.Column
|
|
||||||
import androidx.compose.foundation.layout.Row
|
|
||||||
import androidx.compose.foundation.layout.fillMaxWidth
|
|
||||||
import androidx.compose.foundation.layout.padding
|
|
||||||
import androidx.compose.foundation.layout.size
|
|
||||||
import androidx.compose.foundation.lazy.LazyColumn
|
|
||||||
import androidx.compose.foundation.lazy.items
|
|
||||||
import androidx.compose.foundation.shape.RoundedCornerShape
|
|
||||||
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.mutableStateOf
|
|
||||||
import androidx.compose.runtime.remember
|
|
||||||
import androidx.compose.ui.Alignment
|
|
||||||
import androidx.compose.ui.Modifier
|
|
||||||
import androidx.compose.ui.draw.clip
|
|
||||||
import androidx.compose.ui.graphics.asImageBitmap
|
|
||||||
import androidx.compose.ui.platform.LocalContext
|
|
||||||
import androidx.compose.ui.tooling.preview.Preview
|
|
||||||
import androidx.compose.ui.unit.dp
|
|
||||||
import com.example.myapplication.database.AppDatabase
|
|
||||||
import com.example.myapplication.entities.model.SessionFromOrder
|
|
||||||
import com.example.myapplication.ui.theme.PmudemoTheme
|
|
||||||
import kotlinx.coroutines.Dispatchers
|
|
||||||
import kotlinx.coroutines.withContext
|
|
||||||
import org.threeten.bp.format.DateTimeFormatter
|
|
||||||
|
|
||||||
@Composable
|
|
||||||
fun OrderView(id: Int) {
|
|
||||||
val context = LocalContext.current
|
|
||||||
val sessions = remember {
|
|
||||||
mutableStateListOf<SessionFromOrder>()
|
|
||||||
}
|
|
||||||
LaunchedEffect(Unit) {
|
|
||||||
withContext(Dispatchers.IO) {
|
|
||||||
sessions.clear()
|
|
||||||
sessions.addAll(AppDatabase.getInstance(context).orderDao().getByUid(id))
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
LazyColumn(
|
|
||||||
modifier = Modifier
|
|
||||||
.padding(10.dp)
|
|
||||||
) {
|
|
||||||
items(sessions) { session ->
|
|
||||||
val count = remember { mutableStateOf(session.count) }
|
|
||||||
val dateFormatter = DateTimeFormatter.ofPattern("dd.MM.yyyy HH:mm")
|
|
||||||
val formattedDate = dateFormatter.format(session.dateTime)
|
|
||||||
|
|
||||||
Text(
|
|
||||||
text = formattedDate,
|
|
||||||
color = MaterialTheme.colorScheme.onBackground,
|
|
||||||
)
|
|
||||||
Box(
|
|
||||||
modifier = Modifier
|
|
||||||
.fillMaxWidth()
|
|
||||||
.padding(10.dp)
|
|
||||||
.clip(RoundedCornerShape(16.dp))
|
|
||||||
.background(MaterialTheme.colorScheme.secondary)
|
|
||||||
) {
|
|
||||||
Row(
|
|
||||||
modifier = Modifier
|
|
||||||
.fillMaxWidth()
|
|
||||||
.padding(8.dp),
|
|
||||||
verticalAlignment = Alignment.CenterVertically,
|
|
||||||
horizontalArrangement = Arrangement.SpaceBetween
|
|
||||||
) {
|
|
||||||
if (session.cinema.image != null)
|
|
||||||
Image(
|
|
||||||
bitmap = BitmapFactory.decodeByteArray(
|
|
||||||
session.cinema.image,
|
|
||||||
0,
|
|
||||||
session.cinema.image.size
|
|
||||||
).asImageBitmap(),
|
|
||||||
contentDescription = null,
|
|
||||||
modifier = Modifier
|
|
||||||
.size(90.dp)
|
|
||||||
.padding(4.dp)
|
|
||||||
)
|
|
||||||
|
|
||||||
Column(
|
|
||||||
modifier = Modifier
|
|
||||||
.weight(1f)
|
|
||||||
.padding(start = 8.dp),
|
|
||||||
verticalArrangement = Arrangement.spacedBy(4.dp)
|
|
||||||
) {
|
|
||||||
Text(
|
|
||||||
text = "${session.cinema.name}, ${session.cinema.year}\n" +
|
|
||||||
"Цена: ${session.frozenPrice}\n" +
|
|
||||||
"Количество: ${count.value}",
|
|
||||||
color = MaterialTheme.colorScheme.onSecondary
|
|
||||||
)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
@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 OrderViewPreview() {
|
|
||||||
PmudemoTheme {
|
|
||||||
Surface(
|
|
||||||
color = MaterialTheme.colorScheme.background
|
|
||||||
) {
|
|
||||||
OrderView(id = 1)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
@ -1,166 +0,0 @@
|
|||||||
package com.example.myapplication.user.composeui
|
|
||||||
|
|
||||||
import androidx.compose.foundation.background
|
|
||||||
import androidx.compose.foundation.clickable
|
|
||||||
import androidx.compose.foundation.layout.Arrangement
|
|
||||||
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.padding
|
|
||||||
import androidx.compose.foundation.layout.size
|
|
||||||
import androidx.compose.foundation.lazy.LazyColumn
|
|
||||||
import androidx.compose.foundation.shape.RoundedCornerShape
|
|
||||||
import androidx.compose.foundation.text.BasicTextField
|
|
||||||
import androidx.compose.material3.Button
|
|
||||||
import androidx.compose.material3.MaterialTheme
|
|
||||||
import androidx.compose.material3.Switch
|
|
||||||
import androidx.compose.material3.SwitchDefaults
|
|
||||||
import androidx.compose.material3.Text
|
|
||||||
import androidx.compose.runtime.Composable
|
|
||||||
import androidx.compose.runtime.MutableState
|
|
||||||
import androidx.compose.runtime.getValue
|
|
||||||
import androidx.compose.runtime.mutableStateOf
|
|
||||||
import androidx.compose.runtime.remember
|
|
||||||
import androidx.compose.runtime.rememberCoroutineScope
|
|
||||||
import androidx.compose.runtime.setValue
|
|
||||||
import androidx.compose.ui.Alignment
|
|
||||||
import androidx.compose.ui.Modifier
|
|
||||||
import androidx.compose.ui.text.input.PasswordVisualTransformation
|
|
||||||
import androidx.compose.ui.unit.dp
|
|
||||||
import androidx.navigation.NavController
|
|
||||||
import com.example.myapplication.datastore.DataStoreManager
|
|
||||||
import com.example.myapplication.datastore.SettingData
|
|
||||||
import kotlinx.coroutines.launch
|
|
||||||
|
|
||||||
@Composable
|
|
||||||
fun UserProfile(
|
|
||||||
isDarkTheme: MutableState<Boolean>,
|
|
||||||
dataStoreManager: DataStoreManager
|
|
||||||
) {
|
|
||||||
var username by remember { mutableStateOf("") }
|
|
||||||
var password by remember { mutableStateOf("") }
|
|
||||||
var isRegistration by remember { mutableStateOf(false) }
|
|
||||||
|
|
||||||
LazyColumn {
|
|
||||||
item {
|
|
||||||
Column(
|
|
||||||
modifier = Modifier
|
|
||||||
.fillMaxSize()
|
|
||||||
.padding(16.dp),
|
|
||||||
verticalArrangement = Arrangement.spacedBy(16.dp)
|
|
||||||
) {
|
|
||||||
Text(
|
|
||||||
text = "Логин",
|
|
||||||
modifier = Modifier.align(Alignment.CenterHorizontally)
|
|
||||||
)
|
|
||||||
BasicTextField(
|
|
||||||
value = username,
|
|
||||||
onValueChange = { newValue -> username = newValue },
|
|
||||||
modifier = Modifier
|
|
||||||
.fillMaxWidth()
|
|
||||||
.size(36.dp)
|
|
||||||
.background(MaterialTheme.colorScheme.secondary, RoundedCornerShape(18.dp))
|
|
||||||
.padding(start = 13.dp, top = 8.dp)
|
|
||||||
)
|
|
||||||
|
|
||||||
Text(
|
|
||||||
text = "Пароль",
|
|
||||||
modifier = Modifier.align(Alignment.CenterHorizontally)
|
|
||||||
)
|
|
||||||
BasicTextField(
|
|
||||||
value = password,
|
|
||||||
onValueChange = { newValue -> password = newValue },
|
|
||||||
modifier = Modifier
|
|
||||||
.fillMaxWidth()
|
|
||||||
.size(36.dp)
|
|
||||||
.background(MaterialTheme.colorScheme.secondary, RoundedCornerShape(18.dp))
|
|
||||||
.padding(start = 13.dp, top = 8.dp),
|
|
||||||
visualTransformation = PasswordVisualTransformation()
|
|
||||||
)
|
|
||||||
|
|
||||||
if (isRegistration) {
|
|
||||||
Button(
|
|
||||||
onClick = { },
|
|
||||||
modifier = Modifier
|
|
||||||
.fillMaxWidth()
|
|
||||||
.padding(8.dp)
|
|
||||||
) {
|
|
||||||
Text("Регистрация")
|
|
||||||
}
|
|
||||||
Text(
|
|
||||||
text = "Уже есть аккаунт? Войти",
|
|
||||||
modifier = Modifier
|
|
||||||
.clickable {
|
|
||||||
isRegistration = false
|
|
||||||
}
|
|
||||||
.align(Alignment.CenterHorizontally),
|
|
||||||
color = MaterialTheme.colorScheme.onBackground
|
|
||||||
)
|
|
||||||
} else {
|
|
||||||
Button(
|
|
||||||
onClick = { },
|
|
||||||
modifier = Modifier
|
|
||||||
.fillMaxWidth()
|
|
||||||
.padding(8.dp)
|
|
||||||
) {
|
|
||||||
Text("Вход")
|
|
||||||
}
|
|
||||||
Text(
|
|
||||||
text = "Нет аккаунта? Зарегистрироваться",
|
|
||||||
modifier = Modifier
|
|
||||||
.clickable {
|
|
||||||
isRegistration = true
|
|
||||||
}
|
|
||||||
.align(Alignment.CenterHorizontally),
|
|
||||||
color = MaterialTheme.colorScheme.onBackground
|
|
||||||
)
|
|
||||||
}
|
|
||||||
val switchColors = SwitchDefaults.colors(
|
|
||||||
checkedThumbColor = MaterialTheme.colorScheme.primary, // Change the color when the switch is checked
|
|
||||||
checkedTrackColor = MaterialTheme.colorScheme.secondary, // Change the color of the track when the switch is checked
|
|
||||||
uncheckedThumbColor = MaterialTheme.colorScheme.primary, // Change the color when the switch is unchecked
|
|
||||||
uncheckedTrackColor = MaterialTheme.colorScheme.onPrimary // Change the color of the track when the switch is unchecked
|
|
||||||
)
|
|
||||||
Row(
|
|
||||||
modifier = Modifier
|
|
||||||
.fillMaxWidth()
|
|
||||||
.padding(16.dp),
|
|
||||||
horizontalArrangement = Arrangement.End
|
|
||||||
) {
|
|
||||||
Text(
|
|
||||||
"Темная тема", modifier = Modifier
|
|
||||||
.align(Alignment.CenterVertically)
|
|
||||||
.padding(5.dp)
|
|
||||||
)
|
|
||||||
|
|
||||||
val coroutine = rememberCoroutineScope()
|
|
||||||
|
|
||||||
Switch(
|
|
||||||
checked = isDarkTheme.value,
|
|
||||||
onCheckedChange = {
|
|
||||||
isDarkTheme.value = !isDarkTheme.value
|
|
||||||
coroutine.launch {
|
|
||||||
dataStoreManager.saveSettings(SettingData(isDarkTheme = isDarkTheme.value))
|
|
||||||
}
|
|
||||||
},
|
|
||||||
colors = switchColors
|
|
||||||
)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/*@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 UserProfilePreview() {
|
|
||||||
PmudemoTheme {
|
|
||||||
Surface(
|
|
||||||
color = MaterialTheme.colorScheme.background
|
|
||||||
) {
|
|
||||||
UserProfile(navController = null, isDarkTheme = remember { mutableStateOf(true) })
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}*/
|
|
@ -1,33 +0,0 @@
|
|||||||
package com.example.myapplication.entities.dao
|
|
||||||
|
|
||||||
import androidx.room.Dao
|
|
||||||
import androidx.room.Delete
|
|
||||||
import androidx.room.Insert
|
|
||||||
import androidx.room.Query
|
|
||||||
import androidx.room.Update
|
|
||||||
import com.example.myapplication.entities.model.Cinema
|
|
||||||
import com.example.myapplication.entities.model.SessionFromCinema
|
|
||||||
import kotlinx.coroutines.flow.Flow
|
|
||||||
|
|
||||||
@Dao
|
|
||||||
interface CinemaDao {
|
|
||||||
@Query("select * from cinemas order by name")
|
|
||||||
fun getAll(): Flow<List<Cinema>>
|
|
||||||
|
|
||||||
@Query("SELECT c.*, s.date_time, s.price, s.max_count-IFNULL(SUM(os.count), 0) as available_count " +
|
|
||||||
"FROM cinemas AS c " +
|
|
||||||
"JOIN sessions AS s ON s.cinema_id = c.uid " +
|
|
||||||
"LEFT JOIN orders_sessions AS os ON os.session_id = s.uid " +
|
|
||||||
"WHERE c.uid = :cinemaId " +
|
|
||||||
"GROUP BY os.session_id")
|
|
||||||
suspend fun getByUid(cinemaId: Int?): Map<Cinema, List<SessionFromCinema>>
|
|
||||||
|
|
||||||
@Insert
|
|
||||||
suspend fun insert(cinema: Cinema)
|
|
||||||
|
|
||||||
@Update
|
|
||||||
suspend fun update(cinema: Cinema)
|
|
||||||
|
|
||||||
@Delete
|
|
||||||
suspend fun delete(cinema: Cinema)
|
|
||||||
}
|
|
@ -1,32 +0,0 @@
|
|||||||
package com.example.myapplication.entities.dao
|
|
||||||
|
|
||||||
import androidx.room.Dao
|
|
||||||
import androidx.room.Delete
|
|
||||||
import androidx.room.Insert
|
|
||||||
import androidx.room.Query
|
|
||||||
import androidx.room.Update
|
|
||||||
import com.example.myapplication.entities.model.Order
|
|
||||||
import com.example.myapplication.entities.model.SessionFromOrder
|
|
||||||
import kotlinx.coroutines.flow.Flow
|
|
||||||
|
|
||||||
@Dao
|
|
||||||
interface OrderDao {
|
|
||||||
@Query("select * from orders where user_id = :userId")
|
|
||||||
fun getAll(userId: Int?): Flow<List<Order>>
|
|
||||||
|
|
||||||
@Query("SELECT o.*, s.*, os.count, os.frozen_price " +
|
|
||||||
"FROM orders AS o " +
|
|
||||||
"JOIN orders_sessions AS os ON os.order_id = o.uid " +
|
|
||||||
"JOIN sessions AS s ON s.uid = os.session_id " +
|
|
||||||
"WHERE o.uid = :orderId")
|
|
||||||
fun getByUid(orderId: Int?): List<SessionFromOrder>
|
|
||||||
|
|
||||||
@Insert
|
|
||||||
suspend fun insert(order: Order)
|
|
||||||
|
|
||||||
@Update
|
|
||||||
suspend fun update(order: Order)
|
|
||||||
|
|
||||||
@Delete
|
|
||||||
suspend fun delete(order: Order)
|
|
||||||
}
|
|
@ -1,20 +0,0 @@
|
|||||||
package com.example.myapplication.entities.dao
|
|
||||||
|
|
||||||
import androidx.room.Dao
|
|
||||||
import androidx.room.Delete
|
|
||||||
import androidx.room.Insert
|
|
||||||
import androidx.room.Query
|
|
||||||
import androidx.room.Update
|
|
||||||
import com.example.myapplication.entities.model.OrderSessionCrossRef
|
|
||||||
|
|
||||||
@Dao
|
|
||||||
interface OrderSessionCrossRefDao {
|
|
||||||
@Insert
|
|
||||||
suspend fun insert(orderSessionCrossRef: OrderSessionCrossRef)
|
|
||||||
|
|
||||||
@Update
|
|
||||||
suspend fun update(orderSessionCrossRef: OrderSessionCrossRef)
|
|
||||||
|
|
||||||
@Delete
|
|
||||||
suspend fun delete(orderSessionCrossRef: OrderSessionCrossRef)
|
|
||||||
}
|
|
@ -1,19 +0,0 @@
|
|||||||
package com.example.myapplication.entities.dao
|
|
||||||
|
|
||||||
import androidx.room.Dao
|
|
||||||
import androidx.room.Delete
|
|
||||||
import androidx.room.Insert
|
|
||||||
import androidx.room.Update
|
|
||||||
import com.example.myapplication.entities.model.Session
|
|
||||||
|
|
||||||
@Dao
|
|
||||||
interface SessionDao {
|
|
||||||
@Insert
|
|
||||||
suspend fun insert(session: Session)
|
|
||||||
|
|
||||||
@Update
|
|
||||||
suspend fun update(session: Session)
|
|
||||||
|
|
||||||
@Delete
|
|
||||||
suspend fun delete(session: Session)
|
|
||||||
}
|
|
@ -1,35 +0,0 @@
|
|||||||
package com.example.myapplication.entities.dao
|
|
||||||
|
|
||||||
import androidx.room.Dao
|
|
||||||
import androidx.room.Delete
|
|
||||||
import androidx.room.Insert
|
|
||||||
import androidx.room.Query
|
|
||||||
import androidx.room.Update
|
|
||||||
import com.example.myapplication.entities.model.SessionFromCart
|
|
||||||
import com.example.myapplication.entities.model.User
|
|
||||||
import kotlinx.coroutines.flow.Flow
|
|
||||||
|
|
||||||
@Dao
|
|
||||||
interface UserDao {
|
|
||||||
@Query("select * from users order by login collate nocase asc")
|
|
||||||
fun getAll(): Flow<List<User>>
|
|
||||||
|
|
||||||
@Query(
|
|
||||||
"SELECT sessions.*, sessions.max_count-sum(orders_sessions.count) as available_count, " +
|
|
||||||
"users_sessions.count FROM sessions " +
|
|
||||||
"join users_sessions on sessions.uid = users_sessions.session_id " +
|
|
||||||
"join orders_sessions on sessions.uid = orders_sessions.session_id " +
|
|
||||||
"where users_sessions.user_id = :userId " +
|
|
||||||
"GROUP BY orders_sessions.session_id "
|
|
||||||
)
|
|
||||||
fun getCartByUid(userId: Int): Flow<List<SessionFromCart>>
|
|
||||||
|
|
||||||
@Insert
|
|
||||||
suspend fun insert(user: User)
|
|
||||||
|
|
||||||
@Update
|
|
||||||
suspend fun update(user: User)
|
|
||||||
|
|
||||||
@Delete
|
|
||||||
suspend fun delete(user: User)
|
|
||||||
}
|
|
@ -1,22 +0,0 @@
|
|||||||
package com.example.myapplication.entities.dao
|
|
||||||
|
|
||||||
import androidx.room.Dao
|
|
||||||
import androidx.room.Delete
|
|
||||||
import androidx.room.Insert
|
|
||||||
import androidx.room.Query
|
|
||||||
import androidx.room.Update
|
|
||||||
import com.example.myapplication.entities.model.SessionFromCart
|
|
||||||
import com.example.myapplication.entities.model.UserSessionCrossRef
|
|
||||||
import kotlinx.coroutines.flow.Flow
|
|
||||||
|
|
||||||
@Dao
|
|
||||||
interface UserSessionCrossRefDao {
|
|
||||||
@Insert
|
|
||||||
suspend fun insert(userSessionCrossRef: UserSessionCrossRef)
|
|
||||||
|
|
||||||
@Update
|
|
||||||
suspend fun update(userSessionCrossRef: UserSessionCrossRef)
|
|
||||||
|
|
||||||
@Delete
|
|
||||||
suspend fun delete(userSessionCrossRef: UserSessionCrossRef)
|
|
||||||
}
|
|
@ -1,38 +0,0 @@
|
|||||||
package com.example.myapplication.entities.model
|
|
||||||
|
|
||||||
import androidx.room.ColumnInfo
|
|
||||||
import androidx.room.Entity
|
|
||||||
import androidx.room.Ignore
|
|
||||||
import androidx.room.PrimaryKey
|
|
||||||
|
|
||||||
@Entity(tableName = "cinemas")
|
|
||||||
data class Cinema(
|
|
||||||
@PrimaryKey(autoGenerate = true)
|
|
||||||
val uid: Int?,
|
|
||||||
val name: String,
|
|
||||||
val description: String,
|
|
||||||
@ColumnInfo(typeAffinity = ColumnInfo.BLOB)
|
|
||||||
val image: ByteArray?,
|
|
||||||
val year: Long
|
|
||||||
) {
|
|
||||||
@Ignore
|
|
||||||
constructor(
|
|
||||||
name: String,
|
|
||||||
description: String,
|
|
||||||
image: ByteArray?,
|
|
||||||
year: Long
|
|
||||||
) : this(null, name, description, image, year)
|
|
||||||
|
|
||||||
override fun equals(other: Any?): Boolean {
|
|
||||||
if (this === other) return true
|
|
||||||
if (javaClass != other?.javaClass) return false
|
|
||||||
other as Cinema
|
|
||||||
if (uid != other.uid) return false
|
|
||||||
return true
|
|
||||||
}
|
|
||||||
|
|
||||||
override fun hashCode(): Int {
|
|
||||||
return uid ?: -1
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
@ -1,16 +0,0 @@
|
|||||||
package com.example.myapplication.entities.model
|
|
||||||
|
|
||||||
import androidx.room.TypeConverter
|
|
||||||
import org.threeten.bp.LocalDateTime
|
|
||||||
|
|
||||||
class LocalDateTimeConverter {
|
|
||||||
@TypeConverter
|
|
||||||
fun fromLocalDateTime(value: LocalDateTime?): String? {
|
|
||||||
return value?.toString()
|
|
||||||
}
|
|
||||||
|
|
||||||
@TypeConverter
|
|
||||||
fun toLocalDateTime(value: String?): LocalDateTime? {
|
|
||||||
return value?.let { LocalDateTime.parse(it) }
|
|
||||||
}
|
|
||||||
}
|
|
@ -1,37 +0,0 @@
|
|||||||
package com.example.myapplication.entities.model
|
|
||||||
|
|
||||||
import androidx.room.ColumnInfo
|
|
||||||
import androidx.room.Entity
|
|
||||||
import androidx.room.ForeignKey
|
|
||||||
import androidx.room.PrimaryKey
|
|
||||||
|
|
||||||
@Entity(
|
|
||||||
tableName = "orders", foreignKeys = [
|
|
||||||
ForeignKey(
|
|
||||||
entity = User::class,
|
|
||||||
parentColumns = ["uid"],
|
|
||||||
childColumns = ["user_id"],
|
|
||||||
onDelete = ForeignKey.RESTRICT,
|
|
||||||
onUpdate = ForeignKey.RESTRICT
|
|
||||||
)
|
|
||||||
]
|
|
||||||
)
|
|
||||||
data class Order(
|
|
||||||
@PrimaryKey(autoGenerate = true)
|
|
||||||
val uid: Int,
|
|
||||||
@ColumnInfo(name = "user_id", index = true)
|
|
||||||
val userId: Int?,
|
|
||||||
) {
|
|
||||||
override fun equals(other: Any?): Boolean {
|
|
||||||
if (this === other) return true
|
|
||||||
if (javaClass != other?.javaClass) return false
|
|
||||||
other as Order
|
|
||||||
if (uid != other.uid) return false
|
|
||||||
return true
|
|
||||||
}
|
|
||||||
|
|
||||||
override fun hashCode(): Int {
|
|
||||||
return uid
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
@ -1,37 +0,0 @@
|
|||||||
package com.example.myapplication.entities.model
|
|
||||||
|
|
||||||
import androidx.room.ColumnInfo
|
|
||||||
import androidx.room.Entity
|
|
||||||
import java.util.Objects
|
|
||||||
|
|
||||||
@Entity(
|
|
||||||
tableName = "orders_sessions",
|
|
||||||
primaryKeys = ["order_id", "session_id"]
|
|
||||||
)
|
|
||||||
data class OrderSessionCrossRef(
|
|
||||||
@ColumnInfo(name = "order_id", index = true)
|
|
||||||
val orderId: Int,
|
|
||||||
@ColumnInfo(name = "session_id", index = true)
|
|
||||||
val sessionId: Int,
|
|
||||||
@ColumnInfo(name = "frozen_price")
|
|
||||||
val frozenPrice: Double,
|
|
||||||
val count: Int
|
|
||||||
) {
|
|
||||||
override fun equals(other: Any?): Boolean {
|
|
||||||
if (this === other) {
|
|
||||||
return true
|
|
||||||
}
|
|
||||||
if (javaClass != other?.javaClass) {
|
|
||||||
return false
|
|
||||||
}
|
|
||||||
other as OrderSessionCrossRef
|
|
||||||
if (orderId == other.orderId && sessionId == other.sessionId) {
|
|
||||||
return true
|
|
||||||
}
|
|
||||||
return false
|
|
||||||
}
|
|
||||||
|
|
||||||
override fun hashCode(): Int {
|
|
||||||
return Objects.hash(orderId, sessionId)
|
|
||||||
}
|
|
||||||
}
|
|
@ -1,52 +0,0 @@
|
|||||||
package com.example.myapplication.entities.model
|
|
||||||
|
|
||||||
import androidx.room.ColumnInfo
|
|
||||||
import androidx.room.Entity
|
|
||||||
import androidx.room.ForeignKey
|
|
||||||
import androidx.room.Ignore
|
|
||||||
import androidx.room.PrimaryKey
|
|
||||||
import org.threeten.bp.LocalDateTime
|
|
||||||
|
|
||||||
@Entity(
|
|
||||||
tableName = "sessions", foreignKeys = [
|
|
||||||
ForeignKey(
|
|
||||||
entity = Cinema::class,
|
|
||||||
parentColumns = ["uid"],
|
|
||||||
childColumns = ["cinema_id"],
|
|
||||||
onDelete = ForeignKey.RESTRICT,
|
|
||||||
onUpdate = ForeignKey.RESTRICT
|
|
||||||
)
|
|
||||||
]
|
|
||||||
)
|
|
||||||
data class Session(
|
|
||||||
@PrimaryKey(autoGenerate = true)
|
|
||||||
val uid: Int?,
|
|
||||||
@ColumnInfo(name = "date_time")
|
|
||||||
val dateTime: LocalDateTime,
|
|
||||||
val price: Double,
|
|
||||||
@ColumnInfo(name = "max_count")
|
|
||||||
val maxCount: Int,
|
|
||||||
@ColumnInfo(name = "cinema_id", index = true)
|
|
||||||
val cinemaId: Int?,
|
|
||||||
) {
|
|
||||||
@Ignore
|
|
||||||
constructor(
|
|
||||||
dateTime: LocalDateTime,
|
|
||||||
price: Double,
|
|
||||||
maxCount: Int,
|
|
||||||
cinema: Cinema,
|
|
||||||
) : this(null, dateTime, price, maxCount, cinema.uid)
|
|
||||||
|
|
||||||
override fun equals(other: Any?): Boolean {
|
|
||||||
if (this === other) return true
|
|
||||||
if (javaClass != other?.javaClass) return false
|
|
||||||
other as Session
|
|
||||||
if (uid != other.uid) return false
|
|
||||||
return true
|
|
||||||
}
|
|
||||||
|
|
||||||
override fun hashCode(): Int {
|
|
||||||
return uid ?: -1
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
@ -1,23 +0,0 @@
|
|||||||
package com.example.myapplication.entities.model
|
|
||||||
|
|
||||||
import androidx.room.ColumnInfo
|
|
||||||
import androidx.room.Relation
|
|
||||||
import org.threeten.bp.LocalDateTime
|
|
||||||
|
|
||||||
data class SessionFromCart(
|
|
||||||
@ColumnInfo(name = "uid")
|
|
||||||
val uid: Int?,
|
|
||||||
@ColumnInfo(name = "date_time")
|
|
||||||
val dateTime: LocalDateTime,
|
|
||||||
val price: Double,
|
|
||||||
@ColumnInfo(name = "available_count")
|
|
||||||
val availableCount: Int,
|
|
||||||
val count: Int,
|
|
||||||
@ColumnInfo(name = "cinema_id")
|
|
||||||
val cinemaId: Int?,
|
|
||||||
@Relation(
|
|
||||||
parentColumn = "cinema_id",
|
|
||||||
entity = Cinema::class,
|
|
||||||
entityColumn = "uid"
|
|
||||||
) val cinema: Cinema
|
|
||||||
)
|
|
@ -1,14 +0,0 @@
|
|||||||
package com.example.myapplication.entities.model
|
|
||||||
|
|
||||||
import androidx.room.ColumnInfo
|
|
||||||
import org.threeten.bp.LocalDateTime
|
|
||||||
|
|
||||||
data class SessionFromCinema (
|
|
||||||
@ColumnInfo(name = "uid")
|
|
||||||
val uid: Int?,
|
|
||||||
@ColumnInfo(name = "date_time")
|
|
||||||
val dateTime: LocalDateTime,
|
|
||||||
val price: Double,
|
|
||||||
@ColumnInfo(name = "available_count")
|
|
||||||
val availableCount: Int,
|
|
||||||
)
|
|
@ -1,23 +0,0 @@
|
|||||||
package com.example.myapplication.entities.model
|
|
||||||
|
|
||||||
import androidx.room.ColumnInfo
|
|
||||||
import androidx.room.Relation
|
|
||||||
import org.threeten.bp.LocalDateTime
|
|
||||||
|
|
||||||
data class SessionFromOrder(
|
|
||||||
@ColumnInfo(name = "uid")
|
|
||||||
val uid: Int?,
|
|
||||||
@ColumnInfo(name = "date_time")
|
|
||||||
val dateTime: LocalDateTime,
|
|
||||||
@ColumnInfo(name = "frozen_price")
|
|
||||||
val frozenPrice: Double,
|
|
||||||
val count: Int,
|
|
||||||
@ColumnInfo(name = "cinema_id")
|
|
||||||
val cinemaId: Int?,
|
|
||||||
@Relation(
|
|
||||||
parentColumn = "cinema_id",
|
|
||||||
entity = Cinema::class,
|
|
||||||
entityColumn = "uid"
|
|
||||||
)
|
|
||||||
val cinema: Cinema
|
|
||||||
)
|
|
@ -1,24 +0,0 @@
|
|||||||
package com.example.myapplication.entities.model
|
|
||||||
|
|
||||||
import androidx.room.Entity
|
|
||||||
import androidx.room.PrimaryKey
|
|
||||||
|
|
||||||
@Entity(tableName = "users")
|
|
||||||
data class User(
|
|
||||||
@PrimaryKey(autoGenerate = true)
|
|
||||||
val uid: Int?,
|
|
||||||
val login: String,
|
|
||||||
val password: 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
|
|
||||||
}
|
|
||||||
}
|
|
@ -1,17 +0,0 @@
|
|||||||
package com.example.myapplication.entities.model
|
|
||||||
|
|
||||||
import androidx.room.ColumnInfo
|
|
||||||
import androidx.room.Entity
|
|
||||||
|
|
||||||
@Entity(
|
|
||||||
tableName = "users_sessions",
|
|
||||||
primaryKeys = ["user_id", "session_id"]
|
|
||||||
)
|
|
||||||
data class UserSessionCrossRef(
|
|
||||||
@ColumnInfo(name = "user_id", index = true)
|
|
||||||
val userId: Int,
|
|
||||||
@ColumnInfo(name = "session_id", index = true)
|
|
||||||
val sessionId: Int,
|
|
||||||
@ColumnInfo(name = "count")
|
|
||||||
val count: Int,
|
|
||||||
)
|
|
@ -1,11 +0,0 @@
|
|||||||
package com.example.myapplication.ui.theme
|
|
||||||
|
|
||||||
import androidx.compose.ui.graphics.Color
|
|
||||||
|
|
||||||
val LightGray = Color(0xFFB2CCD6)
|
|
||||||
val LightBlueGray = Color(0xFF70A3B2)
|
|
||||||
val LightBgGray = Color(0xFFCED6DC)
|
|
||||||
|
|
||||||
val Gray = Color(0xFFD6D6D6)
|
|
||||||
val DarkGray = Color(0xFF191A1F)
|
|
||||||
val BgGray = Color(0xFF2A2D32)
|
|
@ -0,0 +1,11 @@
|
|||||||
|
package com.example.myapplication.ui.theme
|
||||||
|
|
||||||
|
import androidx.compose.ui.graphics.Color
|
||||||
|
|
||||||
|
val Purple80 = Color(0xFFD0BCFF)
|
||||||
|
val PurpleGrey80 = Color(0xFFCCC2DC)
|
||||||
|
val Pink80 = Color(0xFFEFB8C8)
|
||||||
|
|
||||||
|
val Purple40 = Color(0xFF6650a4)
|
||||||
|
val PurpleGrey40 = Color(0xFF625b71)
|
||||||
|
val Pink40 = Color(0xFF7D5260)
|
@ -10,33 +10,23 @@ import androidx.compose.material3.dynamicLightColorScheme
|
|||||||
import androidx.compose.material3.lightColorScheme
|
import androidx.compose.material3.lightColorScheme
|
||||||
import androidx.compose.runtime.Composable
|
import androidx.compose.runtime.Composable
|
||||||
import androidx.compose.runtime.SideEffect
|
import androidx.compose.runtime.SideEffect
|
||||||
import androidx.compose.ui.graphics.Color
|
|
||||||
import androidx.compose.ui.graphics.toArgb
|
import androidx.compose.ui.graphics.toArgb
|
||||||
import androidx.compose.ui.platform.LocalContext
|
import androidx.compose.ui.platform.LocalContext
|
||||||
import androidx.compose.ui.platform.LocalView
|
import androidx.compose.ui.platform.LocalView
|
||||||
import androidx.core.view.WindowCompat
|
import androidx.core.view.WindowCompat
|
||||||
|
|
||||||
private val DarkColorScheme = darkColorScheme(
|
private val DarkColorScheme = darkColorScheme(
|
||||||
primary = DarkGray,
|
primary = Purple80,
|
||||||
onPrimary = Color.White,
|
secondary = PurpleGrey80,
|
||||||
|
tertiary = Pink80
|
||||||
secondary = Gray,
|
|
||||||
onSecondary = Color.Black,
|
|
||||||
|
|
||||||
background = BgGray,
|
|
||||||
onBackground = Color.White,
|
|
||||||
)
|
)
|
||||||
|
|
||||||
private val LightColorScheme = lightColorScheme(
|
private val LightColorScheme = lightColorScheme(
|
||||||
primary = LightBlueGray,
|
primary = Purple40,
|
||||||
onPrimary = Color.White,
|
secondary = PurpleGrey40,
|
||||||
|
tertiary = Pink40
|
||||||
|
|
||||||
secondary = LightGray,
|
/* Other default colors to override
|
||||||
onSecondary = Color.Black,
|
|
||||||
|
|
||||||
onBackground = Color.Black,
|
|
||||||
|
|
||||||
/* Other default colors to override
|
|
||||||
background = Color(0xFFFFFBFE),
|
background = Color(0xFFFFFBFE),
|
||||||
surface = Color(0xFFFFFBFE),
|
surface = Color(0xFFFFFBFE),
|
||||||
onPrimary = Color.White,
|
onPrimary = Color.White,
|
||||||
@ -48,11 +38,11 @@ private val LightColorScheme = lightColorScheme(
|
|||||||
)
|
)
|
||||||
|
|
||||||
@Composable
|
@Composable
|
||||||
fun PmudemoTheme(
|
fun MyApplicationTheme(
|
||||||
darkTheme: Boolean = isSystemInDarkTheme(),
|
darkTheme: Boolean = isSystemInDarkTheme(),
|
||||||
// Dynamic color is available on Android 12+
|
// Dynamic color is available on Android 12+
|
||||||
dynamicColor: Boolean = false,
|
dynamicColor: Boolean = true,
|
||||||
content: @Composable () -> Unit
|
content: @Composable () -> Unit
|
||||||
) {
|
) {
|
||||||
val colorScheme = when {
|
val colorScheme = when {
|
||||||
dynamicColor && Build.VERSION.SDK_INT >= Build.VERSION_CODES.S -> {
|
dynamicColor && Build.VERSION.SDK_INT >= Build.VERSION_CODES.S -> {
|
||||||
@ -73,8 +63,8 @@ fun PmudemoTheme(
|
|||||||
}
|
}
|
||||||
|
|
||||||
MaterialTheme(
|
MaterialTheme(
|
||||||
colorScheme = colorScheme,
|
colorScheme = colorScheme,
|
||||||
typography = Typography,
|
typography = Typography,
|
||||||
content = content
|
content = content
|
||||||
)
|
)
|
||||||
}
|
}
|
@ -8,14 +8,14 @@ import androidx.compose.ui.unit.sp
|
|||||||
|
|
||||||
// Set of Material typography styles to start with
|
// Set of Material typography styles to start with
|
||||||
val Typography = Typography(
|
val Typography = Typography(
|
||||||
bodyLarge = TextStyle(
|
bodyLarge = TextStyle(
|
||||||
fontFamily = FontFamily.Default,
|
fontFamily = FontFamily.Default,
|
||||||
fontWeight = FontWeight.Normal,
|
fontWeight = FontWeight.Normal,
|
||||||
fontSize = 16.sp,
|
fontSize = 16.sp,
|
||||||
lineHeight = 24.sp,
|
lineHeight = 24.sp,
|
||||||
letterSpacing = 0.5.sp
|
letterSpacing = 0.5.sp
|
||||||
)
|
)
|
||||||
/* Other default text styles to override
|
/* Other default text styles to override
|
||||||
titleLarge = TextStyle(
|
titleLarge = TextStyle(
|
||||||
fontFamily = FontFamily.Default,
|
fontFamily = FontFamily.Default,
|
||||||
fontWeight = FontWeight.Normal,
|
fontWeight = FontWeight.Normal,
|
@ -1,8 +0,0 @@
|
|||||||
<vector xmlns:android="http://schemas.android.com/apk/res/android"
|
|
||||||
android:width="24dp"
|
|
||||||
android:height="24dp"
|
|
||||||
android:viewportWidth="24"
|
|
||||||
android:viewportHeight="24">
|
|
||||||
<path android:fillColor="#000000"
|
|
||||||
android:pathData="M19,13H5v-2h14v2z"/>
|
|
||||||
</vector>
|
|
Binary file not shown.
Before Width: | Height: | Size: 31 KiB |
@ -1,25 +0,0 @@
|
|||||||
<vector xmlns:android="http://schemas.android.com/apk/res/android"
|
|
||||||
android:width="64dp"
|
|
||||||
android:height="64dp"
|
|
||||||
android:viewportWidth="64"
|
|
||||||
android:viewportHeight="64">
|
|
||||||
|
|
||||||
<svg xmlns="http://www.w3.org/2000/svg" width="64" height="64" viewBox="0 0 64 64">
|
|
||||||
<!-- Зона фона -->
|
|
||||||
<rect width="64" height="64" rx="8" ry="8" fill="#FFC107" />
|
|
||||||
|
|
||||||
<!-- Билет -->
|
|
||||||
<rect x="8" y="12" width="48" height="40" rx="4" ry="4" fill="#FFFFFF" />
|
|
||||||
|
|
||||||
<!-- Линия для разделения -->
|
|
||||||
<line x1="8" y1="32" x2="56" y2="32" stroke="#FFA000" stroke-width="2" />
|
|
||||||
|
|
||||||
<!-- Линия для номера билета -->
|
|
||||||
<line x1="16" y1="48" x2="48" y2="48" stroke="#FFA000" stroke-width="2" />
|
|
||||||
|
|
||||||
<!-- Текст для номера билета -->
|
|
||||||
<text x="32" y="53" fill="#FFA000" font-size="12" text-anchor="middle">
|
|
||||||
</text>
|
|
||||||
</svg>
|
|
||||||
|
|
||||||
</vector>
|
|
@ -1,14 +1,3 @@
|
|||||||
<resources>
|
<resources>
|
||||||
<string name="app_name">pmu-demo</string>
|
<string name="app_name">My Application</string>
|
||||||
<string name="Cinema_main_title">Фильмы</string>
|
|
||||||
<string name="Cinema_view_title">Фильм</string>
|
|
||||||
<string name="Order_view_title">Заказ</string>
|
|
||||||
<string name="Cinema_name">Название</string>
|
|
||||||
<string name="Cinema_year">Год</string>
|
|
||||||
<string name="Cinema_description">Описание</string>
|
|
||||||
<string name="Cinema_image">Изображение</string>
|
|
||||||
<string name="Cart_title">Корзина</string>
|
|
||||||
<string name="Order_title">Мои заказы</string>
|
|
||||||
<string name="Profile_title">Профиль</string>
|
|
||||||
<string name="Sessions_title">Сеансы</string>
|
|
||||||
</resources>
|
</resources>
|
@ -1,5 +1,5 @@
|
|||||||
<?xml version="1.0" encoding="utf-8"?>
|
<?xml version="1.0" encoding="utf-8"?>
|
||||||
<resources>
|
<resources>
|
||||||
|
|
||||||
<style name="Theme.Pmudemo" parent="android:Theme.Material.Light.NoActionBar" />
|
<style name="Theme.MyApplication" parent="android:Theme.Material.Light.NoActionBar" />
|
||||||
</resources>
|
</resources>
|
@ -1,6 +1,5 @@
|
|||||||
// Top-level build file where you can add configuration options common to all sub-projects/modules.
|
// Top-level build file where you can add configuration options common to all sub-projects/modules.
|
||||||
plugins {
|
plugins {
|
||||||
id("com.android.application") version "8.1.2" apply false
|
id("com.android.application") version "8.1.1" apply false
|
||||||
id("org.jetbrains.kotlin.android") version "1.8.20" 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
|
|
||||||
}
|
}
|
2
gradle/wrapper/gradle-wrapper.properties
vendored
2
gradle/wrapper/gradle-wrapper.properties
vendored
@ -1,4 +1,4 @@
|
|||||||
#Sun Oct 01 15:07:08 GMT+04:00 2023
|
#Mon Sep 18 13:48:19 GMT+04:00 2023
|
||||||
distributionBase=GRADLE_USER_HOME
|
distributionBase=GRADLE_USER_HOME
|
||||||
distributionPath=wrapper/dists
|
distributionPath=wrapper/dists
|
||||||
distributionUrl=https\://services.gradle.org/distributions/gradle-8.0-bin.zip
|
distributionUrl=https\://services.gradle.org/distributions/gradle-8.0-bin.zip
|
||||||
|
Binary file not shown.
Binary file not shown.
@ -15,4 +15,3 @@ dependencyResolutionManagement {
|
|||||||
|
|
||||||
rootProject.name = "My Application"
|
rootProject.name = "My Application"
|
||||||
include(":app")
|
include(":app")
|
||||||
|
|
Loading…
x
Reference in New Issue
Block a user