much done, need fixes
This commit is contained in:
parent
889e80ad9e
commit
ef95904c6f
@ -5,7 +5,7 @@
|
|||||||
<option name="linkedExternalProjectsSettings">
|
<option name="linkedExternalProjectsSettings">
|
||||||
<GradleProjectSettings>
|
<GradleProjectSettings>
|
||||||
<option name="externalProjectPath" value="$PROJECT_DIR$" />
|
<option name="externalProjectPath" value="$PROJECT_DIR$" />
|
||||||
<option name="gradleJvm" value="#GRADLE_LOCAL_JAVA_HOME" />
|
<option name="gradleJvm" value="jbr-17" />
|
||||||
<option name="modules">
|
<option name="modules">
|
||||||
<set>
|
<set>
|
||||||
<option value="$PROJECT_DIR$" />
|
<option value="$PROJECT_DIR$" />
|
||||||
|
@ -1,3 +1,4 @@
|
|||||||
|
<?xml version="1.0" encoding="UTF-8"?>
|
||||||
<project version="4">
|
<project version="4">
|
||||||
<component name="ExternalStorageConfigurationManager" enabled="true" />
|
<component name="ExternalStorageConfigurationManager" enabled="true" />
|
||||||
<component name="ProjectRootManager" version="2" languageLevel="JDK_17" default="true" project-jdk-name="jbr-17" project-jdk-type="JavaSDK">
|
<component name="ProjectRootManager" version="2" languageLevel="JDK_17" default="true" project-jdk-name="jbr-17" project-jdk-type="JavaSDK">
|
||||||
|
@ -51,10 +51,18 @@ android {
|
|||||||
}
|
}
|
||||||
|
|
||||||
kotlin {
|
kotlin {
|
||||||
jvmToolchain(17)
|
jvmToolchain( 17)
|
||||||
}
|
}
|
||||||
|
|
||||||
dependencies {
|
dependencies {
|
||||||
|
// Retrofit
|
||||||
|
implementation("com.jakewharton.retrofit:retrofit2-kotlinx-serialization-converter:1.0.0")
|
||||||
|
implementation("com.squareup.retrofit2:retrofit:2.9.0")
|
||||||
|
implementation("io.coil-kt:coil-compose:2.5.0")
|
||||||
|
implementation("org.jetbrains.kotlinx:kotlinx-serialization-json:1.6.2")
|
||||||
|
|
||||||
|
implementation("com.jcraft:jsch:0.1.55")
|
||||||
|
|
||||||
// Core
|
// Core
|
||||||
implementation("androidx.core:core-ktx:1.12.0")
|
implementation("androidx.core:core-ktx:1.12.0")
|
||||||
implementation("androidx.lifecycle:lifecycle-runtime-ktx:2.6.2")
|
implementation("androidx.lifecycle:lifecycle-runtime-ktx:2.6.2")
|
||||||
@ -66,22 +74,15 @@ dependencies {
|
|||||||
implementation("androidx.compose.ui:ui:1.6.0-beta02")
|
implementation("androidx.compose.ui:ui:1.6.0-beta02")
|
||||||
implementation("androidx.compose.ui:ui-graphics:1.6.0-beta02")
|
implementation("androidx.compose.ui:ui-graphics:1.6.0-beta02")
|
||||||
implementation("androidx.compose.ui:ui-tooling-preview:1.6.0-beta02")
|
implementation("androidx.compose.ui:ui-tooling-preview:1.6.0-beta02")
|
||||||
implementation("androidx.compose.material3:material3:1.2.0-alpha12")
|
implementation("androidx.compose.material3:material3:1.1.2")
|
||||||
|
|
||||||
// Retrofit
|
|
||||||
implementation("com.jakewharton.retrofit:retrofit2-kotlinx-serialization-converter:1.0.0")
|
|
||||||
implementation("com.squareup.retrofit2:retrofit:2.9.0")
|
|
||||||
implementation("io.coil-kt:coil-compose:2.5.0")
|
|
||||||
implementation("org.jetbrains.kotlinx:kotlinx-serialization-json:1.6.2")
|
|
||||||
|
|
||||||
implementation("com.jcraft:jsch:0.1.55")
|
|
||||||
|
|
||||||
// Room
|
// Room
|
||||||
implementation("androidx.room:room-runtime:2.6.1")
|
val room_version = "2.6.1"
|
||||||
annotationProcessor("androidx.room:room-compiler:2.6.1")
|
implementation("androidx.room:room-runtime:$room_version")
|
||||||
ksp("androidx.room:room-compiler:2.6.1")
|
annotationProcessor("androidx.room:room-compiler:$room_version")
|
||||||
implementation("androidx.room:room-ktx:2.6.1")
|
ksp("androidx.room:room-compiler:$room_version")
|
||||||
implementation("androidx.room:room-paging:2.6.1")
|
implementation("androidx.room:room-ktx:$room_version")
|
||||||
|
implementation("androidx.room:room-paging:$room_version")
|
||||||
|
|
||||||
// Tests
|
// Tests
|
||||||
testImplementation("junit:junit:4.13.2")
|
testImplementation("junit:junit:4.13.2")
|
||||||
|
@ -7,7 +7,8 @@
|
|||||||
<uses-permission android:name="android.permission.ACCESS_WIFI_STATE" />
|
<uses-permission android:name="android.permission.ACCESS_WIFI_STATE" />
|
||||||
<uses-permission android:name="com.google.android.gms.persmission.AD_ID" />
|
<uses-permission android:name="com.google.android.gms.persmission.AD_ID" />
|
||||||
<application
|
<application
|
||||||
android:allowBackup="true"
|
android:name=".CoffeeApplication"
|
||||||
|
android:allowBackup="false"
|
||||||
android:dataExtractionRules="@xml/data_extraction_rules"
|
android:dataExtractionRules="@xml/data_extraction_rules"
|
||||||
android:fullBackupContent="@xml/backup_rules"
|
android:fullBackupContent="@xml/backup_rules"
|
||||||
android:icon="@mipmap/ic_launcher"
|
android:icon="@mipmap/ic_launcher"
|
||||||
@ -17,11 +18,12 @@
|
|||||||
android:theme="@style/Theme.CoffeePreorder"
|
android:theme="@style/Theme.CoffeePreorder"
|
||||||
tools:targetApi="31">
|
tools:targetApi="31">
|
||||||
<activity
|
<activity
|
||||||
android:name=".MainActivity"
|
android:name=".MainComposeActivity"
|
||||||
android:exported="true"
|
android:exported="true"
|
||||||
android:theme="@style/Theme.CoffeePreorder">
|
android:theme="@style/Theme.CoffeePreorder">
|
||||||
<intent-filter>
|
<intent-filter>
|
||||||
<action android:name="android.intent.action.MAIN" />
|
<action android:name="android.intent.action.MAIN" />
|
||||||
|
|
||||||
<category android:name="android.intent.category.LAUNCHER" />
|
<category android:name="android.intent.category.LAUNCHER" />
|
||||||
</intent-filter>
|
</intent-filter>
|
||||||
</activity>
|
</activity>
|
||||||
|
@ -13,7 +13,7 @@ import androidx.compose.ui.tooling.preview.Preview
|
|||||||
import com.zyzf.coffeepreorder.ui.navigation.MainNavbar
|
import com.zyzf.coffeepreorder.ui.navigation.MainNavbar
|
||||||
import com.zyzf.coffeepreorder.ui.theme.CoffeePreorderTheme
|
import com.zyzf.coffeepreorder.ui.theme.CoffeePreorderTheme
|
||||||
|
|
||||||
class MainActivity : ComponentActivity() {
|
class MainComposeActivity : ComponentActivity() {
|
||||||
override fun onCreate(savedInstanceState: Bundle?) {
|
override fun onCreate(savedInstanceState: Bundle?) {
|
||||||
super.onCreate(savedInstanceState)
|
super.onCreate(savedInstanceState)
|
||||||
setContent {
|
setContent {
|
||||||
@ -27,18 +27,4 @@ class MainActivity : ComponentActivity() {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
@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 MainNavbarPreview() {
|
|
||||||
CoffeePreorderTheme {
|
|
||||||
Surface(
|
|
||||||
color = MaterialTheme.colorScheme.background
|
|
||||||
) {
|
|
||||||
MainNavbar()
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
@ -16,8 +16,7 @@ data class Cart(
|
|||||||
if (this === other) return true
|
if (this === other) return true
|
||||||
if (javaClass != other?.javaClass) return false
|
if (javaClass != other?.javaClass) return false
|
||||||
other as Cart
|
other as Cart
|
||||||
if (uid != other.uid) return false
|
return uid == other.uid
|
||||||
return true
|
|
||||||
}
|
}
|
||||||
|
|
||||||
override fun hashCode(): Int {
|
override fun hashCode(): Int {
|
||||||
|
@ -19,11 +19,11 @@ data class Coffee(
|
|||||||
@PrimaryKey(autoGenerate = true)
|
@PrimaryKey(autoGenerate = true)
|
||||||
val uid: Int?,
|
val uid: Int?,
|
||||||
@ColumnInfo(name = "name")
|
@ColumnInfo(name = "name")
|
||||||
val name: String,
|
var name: String,
|
||||||
@ColumnInfo(name = "cost")
|
@ColumnInfo(name = "cost")
|
||||||
val cost: Double,
|
var cost: Double,
|
||||||
@ColumnInfo(name = "ingredients")
|
@ColumnInfo(name = "ingredients")
|
||||||
val ingredients: String,
|
var ingredients: String,
|
||||||
@ColumnInfo(name = "cart_id", index = true)
|
@ColumnInfo(name = "cart_id", index = true)
|
||||||
val cartId: Int?,
|
val cartId: Int?,
|
||||||
@ColumnInfo(name = "count")
|
@ColumnInfo(name = "count")
|
||||||
|
@ -30,8 +30,7 @@ data class UserLogined(
|
|||||||
if (this === other) return true
|
if (this === other) return true
|
||||||
if (javaClass != other?.javaClass) return false
|
if (javaClass != other?.javaClass) return false
|
||||||
other as UserLogined
|
other as UserLogined
|
||||||
if (uid != other.uid) return false
|
return uid == other.uid
|
||||||
return true
|
|
||||||
}
|
}
|
||||||
|
|
||||||
override fun hashCode(): Int {
|
override fun hashCode(): Int {
|
||||||
|
@ -6,16 +6,12 @@ import androidx.lifecycle.viewmodel.initializer
|
|||||||
import androidx.lifecycle.viewmodel.viewModelFactory
|
import androidx.lifecycle.viewmodel.viewModelFactory
|
||||||
import com.zyzf.coffeepreorder.CoffeeApplication
|
import com.zyzf.coffeepreorder.CoffeeApplication
|
||||||
import com.zyzf.coffeepreorder.ui.coffee.CoffeeListViewModel
|
import com.zyzf.coffeepreorder.ui.coffee.CoffeeListViewModel
|
||||||
import com.zyzf.coffeepreorder.ui.login.LoginViewModel
|
|
||||||
|
|
||||||
object AppViewModelProvider {
|
object AppViewModelProvider {
|
||||||
val Factory = viewModelFactory {
|
val Factory = viewModelFactory {
|
||||||
initializer {
|
initializer {
|
||||||
CoffeeListViewModel(coffeeApplication().container.coffeeRepository, coffeeApplication().container.cartRepository)
|
CoffeeListViewModel(coffeeApplication().container.coffeeRepository, coffeeApplication().container.cartRepository)
|
||||||
}
|
}
|
||||||
initializer {
|
|
||||||
LoginViewModel(coffeeApplication().container.userRepository)
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -79,6 +79,7 @@ fun CoffeeList(
|
|||||||
val coffeeListUiState = viewModel.coffeeListUiState.collectAsState()
|
val coffeeListUiState = viewModel.coffeeListUiState.collectAsState()
|
||||||
val sheetState = rememberModalBottomSheetState()
|
val sheetState = rememberModalBottomSheetState()
|
||||||
val openDialog = remember { mutableStateOf(false) }
|
val openDialog = remember { mutableStateOf(false) }
|
||||||
|
val coffee = remember { mutableStateOf(Coffee.getCoffee()) }
|
||||||
val photoPicker = rememberLauncherForActivityResult(
|
val photoPicker = rememberLauncherForActivityResult(
|
||||||
contract = ActivityResultContracts.PickVisualMedia()
|
contract = ActivityResultContracts.PickVisualMedia()
|
||||||
) {
|
) {
|
||||||
@ -95,7 +96,8 @@ fun CoffeeList(
|
|||||||
FloatingActionButton(
|
FloatingActionButton(
|
||||||
onClick = {
|
onClick = {
|
||||||
coroutineScope.launch {
|
coroutineScope.launch {
|
||||||
viewModel.cleanCurrentCoffee()
|
coffee.value = Coffee.getCoffee()
|
||||||
|
openDialog.value = true
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
Modifier
|
Modifier
|
||||||
@ -109,7 +111,7 @@ fun CoffeeList(
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
) { innerPadding ->
|
) { innerPadding ->
|
||||||
coffeeListUiState?.value?.coffeeList?.let {
|
coffeeListUiState.value.coffeeList.let {
|
||||||
CoffeeList(
|
CoffeeList(
|
||||||
modifier = Modifier
|
modifier = Modifier
|
||||||
.padding(innerPadding)
|
.padding(innerPadding)
|
||||||
@ -120,15 +122,16 @@ fun CoffeeList(
|
|||||||
viewModel.addCoffeeToCart(coffeeUid = coffeeUid)
|
viewModel.addCoffeeToCart(coffeeUid = coffeeUid)
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
onEditClick = { coffee: Coffee ->
|
onEditClick = { curcoffee: Coffee ->
|
||||||
coroutineScope.launch {
|
coroutineScope.launch {
|
||||||
viewModel.editCoffee(coffee = coffee)
|
coffee.value = curcoffee
|
||||||
|
openDialog.value = true
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
AddEditModalBottomSheet(
|
AddEditModalBottomSheet(
|
||||||
coffee = viewModel.currentCoffee,
|
coffee = coffee,
|
||||||
sheetState = sheetState,
|
sheetState = sheetState,
|
||||||
openDialog = openDialog,
|
openDialog = openDialog,
|
||||||
onAddClick = { coffee: Coffee, context: Context ->
|
onAddClick = { coffee: Coffee, context: Context ->
|
||||||
@ -155,7 +158,7 @@ fun CoffeeList(
|
|||||||
@OptIn(ExperimentalMaterial3Api::class)
|
@OptIn(ExperimentalMaterial3Api::class)
|
||||||
@Composable
|
@Composable
|
||||||
private fun AddEditModalBottomSheet(
|
private fun AddEditModalBottomSheet(
|
||||||
coffee: Coffee,
|
coffee: MutableState<Coffee>,
|
||||||
sheetState: SheetState,
|
sheetState: SheetState,
|
||||||
openDialog: MutableState<Boolean>,
|
openDialog: MutableState<Boolean>,
|
||||||
onAddClick: (coffee: Coffee, context: Context) -> Unit,
|
onAddClick: (coffee: Coffee, context: Context) -> Unit,
|
||||||
@ -165,9 +168,12 @@ private fun AddEditModalBottomSheet(
|
|||||||
imageUri: Any?,
|
imageUri: Any?,
|
||||||
modifier: Modifier = Modifier
|
modifier: Modifier = Modifier
|
||||||
) {
|
) {
|
||||||
var name by remember { mutableStateOf(coffee.name) }
|
var name: String by remember { mutableStateOf("")}
|
||||||
var cost by remember { mutableDoubleStateOf(coffee.cost) }
|
var cost: Double by remember { mutableDoubleStateOf(0.0) }
|
||||||
var ingredients by remember { mutableStateOf(coffee.ingredients) }
|
var ingredients: String by remember { mutableStateOf("")}
|
||||||
|
name = coffee.value.name
|
||||||
|
cost = coffee.value.cost
|
||||||
|
ingredients = coffee.value.ingredients
|
||||||
val context = LocalContext.current
|
val context = LocalContext.current
|
||||||
if (openDialog.value) {
|
if (openDialog.value) {
|
||||||
ModalBottomSheet(
|
ModalBottomSheet(
|
||||||
@ -227,28 +233,28 @@ private fun AddEditModalBottomSheet(
|
|||||||
placeholder = painterResource(R.drawable.loading_img),
|
placeholder = painterResource(R.drawable.loading_img),
|
||||||
contentScale = ContentScale.Crop,
|
contentScale = ContentScale.Crop,
|
||||||
model = ImageRequest.Builder(LocalContext.current)
|
model = ImageRequest.Builder(LocalContext.current)
|
||||||
.data(if (coffee.name != "") "https://zyzf.space/s/zXgFRTmbR4KMxMH/download?path=&files=coffee_image_" + coffee.uid +".png" else imageUri)
|
.data(if (coffee.value.uid != 0) "https://zyzf.space/s/zXgFRTmbR4KMxMH/download?path=&files=coffee_image_" + coffee.value.uid +".png" else imageUri)
|
||||||
.crossfade(enable = true)
|
.crossfade(enable = true)
|
||||||
.build(),
|
.build(),
|
||||||
)
|
)
|
||||||
Row(modifier = Modifier.fillMaxWidth(), horizontalArrangement = Arrangement.Center) {
|
Row(modifier = Modifier.fillMaxWidth(), horizontalArrangement = Arrangement.Center) {
|
||||||
if (coffee.uid == 0) {
|
if (coffee.value.uid == 0) {
|
||||||
Button(onClick = {
|
Button(onClick = {
|
||||||
onAddClick(coffee, context)
|
onAddClick(Coffee(coffee.value.uid, name, cost, ingredients, coffee.value.cartId, coffee.value.count), context)
|
||||||
openDialog.value = false
|
openDialog.value = false
|
||||||
}, modifier = Modifier.padding(0.dp, 10.dp, 0.dp, 30.dp)) {
|
}, modifier = Modifier.padding(0.dp, 10.dp, 0.dp, 30.dp)) {
|
||||||
Text("Добавить")
|
Text("Добавить")
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
Button(onClick = {
|
Button(onClick = {
|
||||||
onEditClick(coffee, context)
|
onEditClick(Coffee(coffee.value.uid, name, cost, ingredients, coffee.value.cartId, coffee.value.count), context)
|
||||||
openDialog.value = false
|
openDialog.value = false
|
||||||
}, modifier = Modifier.padding(0.dp, 10.dp, 0.dp, 30.dp)) {
|
}, modifier = Modifier.padding(0.dp, 10.dp, 0.dp, 30.dp)) {
|
||||||
Text("Изменить")
|
Text("Изменить")
|
||||||
}
|
}
|
||||||
Spacer(modifier = Modifier.padding(all = 20.dp))
|
Spacer(modifier = Modifier.padding(all = 20.dp))
|
||||||
Button(onClick = {
|
Button(onClick = {
|
||||||
onDeleteClick(coffee)
|
onDeleteClick(coffee.value)
|
||||||
openDialog.value = false
|
openDialog.value = false
|
||||||
}, modifier = Modifier.padding(0.dp, 10.dp, 0.dp, 30.dp)) {
|
}, modifier = Modifier.padding(0.dp, 10.dp, 0.dp, 30.dp)) {
|
||||||
Text("Удалить")
|
Text("Удалить")
|
||||||
|
@ -41,19 +41,12 @@ class CoffeeListViewModel(
|
|||||||
started = SharingStarted.WhileSubscribed(stopTimeoutMillis = AppDataContainer.TIMEOUT),
|
started = SharingStarted.WhileSubscribed(stopTimeoutMillis = AppDataContainer.TIMEOUT),
|
||||||
initialValue = CoffeeListUiState()
|
initialValue = CoffeeListUiState()
|
||||||
)
|
)
|
||||||
var currentCoffee: Coffee = Coffee.getCoffee()
|
|
||||||
var imageUri: Any? = R.drawable.img
|
var imageUri: Any? = R.drawable.img
|
||||||
|
|
||||||
suspend fun addCoffeeToCart(coffeeUid: Int) {
|
suspend fun addCoffeeToCart(coffeeUid: Int) {
|
||||||
val cart: Cart = cartRepository.get()
|
val cart: Cart = cartRepository.get()
|
||||||
cart.uid?.let { cartRepository.insertCoffee(it, coffeeUid, 1) }
|
cart.uid?.let { cartRepository.insertCoffee(it, coffeeUid, 1) }
|
||||||
}
|
}
|
||||||
fun cleanCurrentCoffee() {
|
|
||||||
currentCoffee = Coffee.getCoffee()
|
|
||||||
}
|
|
||||||
fun editCoffee(coffee: Coffee) {
|
|
||||||
currentCoffee = coffee
|
|
||||||
}
|
|
||||||
suspend fun createCoffee(coffee: Coffee, context: Context) {
|
suspend fun createCoffee(coffee: Coffee, context: Context) {
|
||||||
val newCoffee: Long = coffeeRepository.insert(coffee.name, coffee.cost, coffee.ingredients)
|
val newCoffee: Long = coffeeRepository.insert(coffee.name, coffee.cost, coffee.ingredients)
|
||||||
val inputStream = context.contentResolver.openInputStream(imageUri as Uri)
|
val inputStream = context.contentResolver.openInputStream(imageUri as Uri)
|
||||||
|
@ -1,6 +1,5 @@
|
|||||||
package com.zyzf.coffeepreorder.ui.login
|
package com.zyzf.coffeepreorder.composeui
|
||||||
|
|
||||||
import android.annotation.SuppressLint
|
|
||||||
import android.content.res.Configuration
|
import android.content.res.Configuration
|
||||||
import androidx.compose.foundation.layout.Column
|
import androidx.compose.foundation.layout.Column
|
||||||
import androidx.compose.foundation.layout.Spacer
|
import androidx.compose.foundation.layout.Spacer
|
||||||
@ -17,15 +16,13 @@ import androidx.compose.material3.ButtonDefaults
|
|||||||
import androidx.compose.material3.Icon
|
import androidx.compose.material3.Icon
|
||||||
import androidx.compose.material3.MaterialTheme
|
import androidx.compose.material3.MaterialTheme
|
||||||
import androidx.compose.material3.OutlinedTextField
|
import androidx.compose.material3.OutlinedTextField
|
||||||
import androidx.compose.material3.Scaffold
|
|
||||||
import androidx.compose.material3.Surface
|
import androidx.compose.material3.Surface
|
||||||
import androidx.compose.material3.Text
|
import androidx.compose.material3.Text
|
||||||
import androidx.compose.runtime.Composable
|
import androidx.compose.runtime.Composable
|
||||||
import androidx.compose.runtime.collectAsState
|
import androidx.compose.runtime.LaunchedEffect
|
||||||
import androidx.compose.runtime.getValue
|
import androidx.compose.runtime.getValue
|
||||||
import androidx.compose.runtime.mutableStateOf
|
import androidx.compose.runtime.mutableStateOf
|
||||||
import androidx.compose.runtime.remember
|
import androidx.compose.runtime.remember
|
||||||
import androidx.compose.runtime.rememberCoroutineScope
|
|
||||||
import androidx.compose.runtime.setValue
|
import androidx.compose.runtime.setValue
|
||||||
import androidx.compose.ui.Alignment
|
import androidx.compose.ui.Alignment
|
||||||
import androidx.compose.ui.Modifier
|
import androidx.compose.ui.Modifier
|
||||||
@ -37,104 +34,106 @@ import androidx.compose.ui.text.input.KeyboardType
|
|||||||
import androidx.compose.ui.text.input.PasswordVisualTransformation
|
import androidx.compose.ui.text.input.PasswordVisualTransformation
|
||||||
import androidx.compose.ui.tooling.preview.Preview
|
import androidx.compose.ui.tooling.preview.Preview
|
||||||
import androidx.compose.ui.unit.dp
|
import androidx.compose.ui.unit.dp
|
||||||
import androidx.lifecycle.viewmodel.compose.viewModel
|
|
||||||
import androidx.navigation.NavController
|
import androidx.navigation.NavController
|
||||||
import coil.compose.AsyncImage
|
import coil.compose.AsyncImage
|
||||||
import coil.request.ImageRequest
|
import coil.request.ImageRequest
|
||||||
import com.zyzf.coffeepreorder.R
|
import com.zyzf.coffeepreorder.R
|
||||||
import com.zyzf.coffeepreorder.ui.AppViewModelProvider
|
import com.zyzf.coffeepreorder.database.AppDatabase
|
||||||
|
import com.zyzf.coffeepreorder.database.model.User
|
||||||
import com.zyzf.coffeepreorder.ui.navigation.Screen
|
import com.zyzf.coffeepreorder.ui.navigation.Screen
|
||||||
import com.zyzf.coffeepreorder.ui.theme.CoffeePreorderTheme
|
import com.zyzf.coffeepreorder.ui.theme.CoffeePreorderTheme
|
||||||
|
import kotlinx.coroutines.DelicateCoroutinesApi
|
||||||
|
import kotlinx.coroutines.Dispatchers
|
||||||
|
import kotlinx.coroutines.GlobalScope
|
||||||
import kotlinx.coroutines.launch
|
import kotlinx.coroutines.launch
|
||||||
|
import kotlinx.coroutines.withContext
|
||||||
|
|
||||||
@SuppressLint("UnusedMaterial3ScaffoldPaddingParameter")
|
@OptIn(DelicateCoroutinesApi::class)
|
||||||
@Composable
|
@Composable
|
||||||
fun Login(
|
fun Login(navController: NavController?) {
|
||||||
navController: NavController?,
|
val context = LocalContext.current
|
||||||
viewModel: LoginViewModel = viewModel(factory = AppViewModelProvider.Factory)
|
|
||||||
) {
|
|
||||||
val coroutineScope = rememberCoroutineScope()
|
|
||||||
val userListUiState = viewModel.userListUiState.collectAsState()
|
|
||||||
var login by remember { mutableStateOf("") }
|
var login by remember { mutableStateOf("") }
|
||||||
var password by remember { mutableStateOf("") }
|
var password by remember { mutableStateOf("") }
|
||||||
Scaffold(
|
LaunchedEffect(Unit) {
|
||||||
topBar = {},
|
withContext(Dispatchers.IO) {
|
||||||
floatingActionButton = {}
|
AppDatabase.getInstance(context).userDao().getAll()
|
||||||
) {
|
}
|
||||||
Column(Modifier.padding(all = 10.dp), horizontalAlignment = Alignment.CenterHorizontally) {
|
}
|
||||||
AsyncImage(
|
Column(Modifier.padding(all = 10.dp), horizontalAlignment = Alignment.CenterHorizontally) {
|
||||||
model = ImageRequest.Builder(context = LocalContext.current)
|
AsyncImage(
|
||||||
.data("https://zyzf.space/s/YsHjPo3NDmoptSk/download/coffee_image.png")
|
model = ImageRequest.Builder(context = LocalContext.current).data("https://zyzf.space/s/YsHjPo3NDmoptSk/download/coffee_image.png")
|
||||||
.crossfade(true).build(),
|
.crossfade(true).build(),
|
||||||
error = painterResource(R.drawable.ic_broken_image),
|
error = painterResource(R.drawable.ic_broken_image),
|
||||||
placeholder = painterResource(R.drawable.loading_img),
|
placeholder = painterResource(R.drawable.loading_img),
|
||||||
contentDescription = "Кофе",
|
contentDescription = "Кофе",
|
||||||
contentScale = ContentScale.Crop,
|
contentScale = ContentScale.Crop,
|
||||||
modifier = Modifier.size(150.dp)
|
modifier = Modifier.size(150.dp)
|
||||||
)
|
)
|
||||||
|
|
||||||
Spacer(modifier = Modifier.padding(all = 20.dp))
|
Spacer(modifier = Modifier.padding(all = 20.dp))
|
||||||
OutlinedTextField(
|
OutlinedTextField(modifier = Modifier.fillMaxWidth(),
|
||||||
modifier = Modifier.fillMaxWidth(),
|
value = login, onValueChange = {login = it},
|
||||||
value = login, onValueChange = { login = it },
|
label = {
|
||||||
label = {
|
Text(stringResource(id = R.string.profile_login_label))
|
||||||
Text(stringResource(id = R.string.profile_login_label))
|
},
|
||||||
},
|
keyboardOptions = KeyboardOptions(keyboardType = KeyboardType.Text)
|
||||||
keyboardOptions = KeyboardOptions(keyboardType = KeyboardType.Text)
|
)
|
||||||
)
|
OutlinedTextField(modifier = Modifier.fillMaxWidth(),
|
||||||
OutlinedTextField(
|
value = password, onValueChange = {password = it},
|
||||||
modifier = Modifier.fillMaxWidth(),
|
label = {
|
||||||
value = password, onValueChange = { password = it },
|
Text(stringResource(id = R.string.profile_passw_label))
|
||||||
label = {
|
},
|
||||||
Text(stringResource(id = R.string.profile_passw_label))
|
keyboardOptions = KeyboardOptions(keyboardType = KeyboardType.Password),
|
||||||
},
|
visualTransformation = PasswordVisualTransformation()
|
||||||
keyboardOptions = KeyboardOptions(keyboardType = KeyboardType.Password),
|
)
|
||||||
visualTransformation = PasswordVisualTransformation()
|
Spacer(modifier = Modifier.padding(all = 20.dp))
|
||||||
)
|
Button(
|
||||||
Spacer(modifier = Modifier.padding(all = 20.dp))
|
onClick = {
|
||||||
Button(
|
var user: User?
|
||||||
onClick = {
|
GlobalScope.launch (Dispatchers.Main) {
|
||||||
coroutineScope.launch {
|
user = AppDatabase.getInstance(context).userDao().tryLogin(login, password)
|
||||||
if (viewModel.tryLogin(login, password)) {
|
if (user != null) {
|
||||||
navController?.navigate(Screen.CoffeeList.route)
|
AppDatabase.getInstance(context).userDao().logout()
|
||||||
} else {
|
AppDatabase.getInstance(context).userDao().setLogined(user!!.uid!!)
|
||||||
password = ""
|
navController?.navigate(Screen.CoffeeList.route)
|
||||||
login = "Неверный логин или пароль"
|
} else {
|
||||||
}
|
password = ""
|
||||||
|
login = "Неверный логин или пароль"
|
||||||
}
|
}
|
||||||
},
|
}
|
||||||
shape = CircleShape,
|
},
|
||||||
modifier = Modifier.fillMaxWidth(fraction = 0.75f),
|
shape = CircleShape,
|
||||||
colors = ButtonDefaults.buttonColors(
|
modifier = Modifier.fillMaxWidth(fraction = 0.75f),
|
||||||
containerColor = MaterialTheme.colorScheme.primaryContainer,
|
colors = ButtonDefaults.buttonColors(
|
||||||
contentColor = MaterialTheme.colorScheme.primary
|
containerColor = MaterialTheme.colorScheme.primaryContainer,
|
||||||
)
|
contentColor = MaterialTheme.colorScheme.primary
|
||||||
) {
|
)
|
||||||
Icon(
|
) {
|
||||||
imageVector = Icons.Default.Check,
|
Icon(
|
||||||
contentDescription = "Favorite",
|
imageVector = Icons.Default.Check,
|
||||||
modifier = Modifier.size(20.dp)
|
contentDescription = "Favorite",
|
||||||
)
|
modifier = Modifier.size(20.dp)
|
||||||
Spacer(Modifier.size(ButtonDefaults.IconSpacing))
|
)
|
||||||
Text(text = "Войти")
|
Spacer(Modifier.size(ButtonDefaults.IconSpacing))
|
||||||
}
|
Text(text = "Войти")
|
||||||
Button(
|
}
|
||||||
onClick = { navController?.navigate(Screen.Register.route) },
|
Button(
|
||||||
shape = CircleShape,
|
onClick = { navController?.navigate(Screen.Register.route) },
|
||||||
modifier = Modifier.fillMaxWidth(fraction = 0.75f),
|
shape = CircleShape,
|
||||||
colors = ButtonDefaults.buttonColors(
|
modifier = Modifier.fillMaxWidth(fraction = 0.75f),
|
||||||
containerColor = MaterialTheme.colorScheme.secondaryContainer,
|
colors = ButtonDefaults.buttonColors(
|
||||||
contentColor = MaterialTheme.colorScheme.secondary
|
containerColor = MaterialTheme.colorScheme.secondaryContainer,
|
||||||
)
|
contentColor = MaterialTheme.colorScheme.secondary
|
||||||
) {
|
)
|
||||||
Icon(
|
) {
|
||||||
imageVector = Icons.Default.Add,
|
// Inner content including an icon and a text label
|
||||||
contentDescription = "Favorite",
|
Icon(
|
||||||
modifier = Modifier.size(20.dp)
|
imageVector = Icons.Default.Add,
|
||||||
)
|
contentDescription = "Favorite",
|
||||||
Spacer(Modifier.size(ButtonDefaults.IconSpacing))
|
modifier = Modifier.size(20.dp)
|
||||||
Text(text = "Зарегистрироваться")
|
)
|
||||||
}
|
Spacer(Modifier.size(ButtonDefaults.IconSpacing))
|
||||||
|
Text(text = "Зарегистрироваться")
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -1,36 +0,0 @@
|
|||||||
package com.zyzf.coffeepreorder.ui.login
|
|
||||||
|
|
||||||
import androidx.lifecycle.ViewModel
|
|
||||||
import androidx.lifecycle.viewModelScope
|
|
||||||
import com.zyzf.coffeepreorder.database.AppDataContainer
|
|
||||||
import com.zyzf.coffeepreorder.database.model.User
|
|
||||||
import com.zyzf.coffeepreorder.database.repository.UserRepository
|
|
||||||
import kotlinx.coroutines.flow.SharingStarted
|
|
||||||
import kotlinx.coroutines.flow.StateFlow
|
|
||||||
import kotlinx.coroutines.flow.map
|
|
||||||
import kotlinx.coroutines.flow.stateIn
|
|
||||||
|
|
||||||
class LoginViewModel(
|
|
||||||
private val userRepository: UserRepository
|
|
||||||
) : ViewModel() {
|
|
||||||
val userListUiState: StateFlow<UserListUiState> = userRepository.getAll().map {
|
|
||||||
UserListUiState(it)
|
|
||||||
}.stateIn(
|
|
||||||
scope = viewModelScope,
|
|
||||||
started = SharingStarted.WhileSubscribed(stopTimeoutMillis = AppDataContainer.TIMEOUT),
|
|
||||||
initialValue = UserListUiState()
|
|
||||||
)
|
|
||||||
var user: User? = null
|
|
||||||
suspend fun tryLogin(login: String, password: String): Boolean {
|
|
||||||
user = userRepository.tryLogin(login, password)
|
|
||||||
return if (user != null) {
|
|
||||||
userRepository.logout()
|
|
||||||
userRepository.setLogined(user!!.uid!!)
|
|
||||||
true
|
|
||||||
} else {
|
|
||||||
false
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
data class UserListUiState(val userList: List<User> = listOf())
|
|
@ -4,7 +4,7 @@ import android.content.res.Configuration
|
|||||||
import androidx.compose.foundation.layout.PaddingValues
|
import androidx.compose.foundation.layout.PaddingValues
|
||||||
import androidx.compose.foundation.layout.padding
|
import androidx.compose.foundation.layout.padding
|
||||||
import androidx.compose.material.icons.Icons
|
import androidx.compose.material.icons.Icons
|
||||||
import androidx.compose.material.icons.automirrored.filled.ArrowBack
|
import androidx.compose.material.icons.filled.ArrowBack
|
||||||
import androidx.compose.material3.ExperimentalMaterial3Api
|
import androidx.compose.material3.ExperimentalMaterial3Api
|
||||||
import androidx.compose.material3.Icon
|
import androidx.compose.material3.Icon
|
||||||
import androidx.compose.material3.IconButton
|
import androidx.compose.material3.IconButton
|
||||||
@ -30,9 +30,9 @@ import androidx.navigation.compose.composable
|
|||||||
import androidx.navigation.compose.currentBackStackEntryAsState
|
import androidx.navigation.compose.currentBackStackEntryAsState
|
||||||
import androidx.navigation.compose.rememberNavController
|
import androidx.navigation.compose.rememberNavController
|
||||||
import com.zyzf.coffeepreorder.R
|
import com.zyzf.coffeepreorder.R
|
||||||
|
import com.zyzf.coffeepreorder.composeui.Login
|
||||||
import com.zyzf.coffeepreorder.ui.cart.Cart
|
import com.zyzf.coffeepreorder.ui.cart.Cart
|
||||||
import com.zyzf.coffeepreorder.ui.coffee.CoffeeList
|
import com.zyzf.coffeepreorder.ui.coffee.CoffeeList
|
||||||
import com.zyzf.coffeepreorder.ui.login.Login
|
|
||||||
import com.zyzf.coffeepreorder.ui.order.Order
|
import com.zyzf.coffeepreorder.ui.order.Order
|
||||||
import com.zyzf.coffeepreorder.ui.profile.Profile
|
import com.zyzf.coffeepreorder.ui.profile.Profile
|
||||||
import com.zyzf.coffeepreorder.ui.register.Register
|
import com.zyzf.coffeepreorder.ui.register.Register
|
||||||
@ -45,7 +45,7 @@ fun Topbar(
|
|||||||
currentScreen: Screen?
|
currentScreen: Screen?
|
||||||
) {
|
) {
|
||||||
TopAppBar(
|
TopAppBar(
|
||||||
colors = TopAppBarDefaults.mediumTopAppBarColors(
|
colors = TopAppBarDefaults.topAppBarColors(
|
||||||
containerColor = MaterialTheme.colorScheme.primary,
|
containerColor = MaterialTheme.colorScheme.primary,
|
||||||
titleContentColor = MaterialTheme.colorScheme.onPrimary,
|
titleContentColor = MaterialTheme.colorScheme.onPrimary,
|
||||||
),
|
),
|
||||||
@ -59,7 +59,7 @@ fun Topbar(
|
|||||||
) {
|
) {
|
||||||
IconButton(onClick = { navController.navigateUp() }) {
|
IconButton(onClick = { navController.navigateUp() }) {
|
||||||
Icon(
|
Icon(
|
||||||
imageVector = Icons.AutoMirrored.Filled.ArrowBack,
|
imageVector = Icons.Filled.ArrowBack,
|
||||||
contentDescription = null,
|
contentDescription = null,
|
||||||
tint = MaterialTheme.colorScheme.onPrimary
|
tint = MaterialTheme.colorScheme.onPrimary
|
||||||
)
|
)
|
||||||
@ -115,6 +115,7 @@ fun Navhost(
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@OptIn(ExperimentalMaterial3Api::class)
|
||||||
@Composable
|
@Composable
|
||||||
fun MainNavbar() {
|
fun MainNavbar() {
|
||||||
val navController = rememberNavController()
|
val navController = rememberNavController()
|
||||||
@ -134,17 +135,4 @@ fun MainNavbar() {
|
|||||||
) { innerPadding ->
|
) { innerPadding ->
|
||||||
Navhost(navController, innerPadding)
|
Navhost(navController, innerPadding)
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
@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 MainNavbarPreview() {
|
|
||||||
CoffeePreorderTheme {
|
|
||||||
Surface(
|
|
||||||
color = MaterialTheme.colorScheme.background
|
|
||||||
) {
|
|
||||||
MainNavbar()
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
@ -32,21 +32,18 @@ enum class Screen(
|
|||||||
),
|
),
|
||||||
Order(
|
Order(
|
||||||
"order", R.string.coffee_order, Icons.Filled.ShoppingCart
|
"order", R.string.coffee_order, Icons.Filled.ShoppingCart
|
||||||
),
|
|
||||||
CoffeeView(
|
|
||||||
"coffee-view/{id}", R.string.coffee_view_title, showInBottomBar = false
|
|
||||||
);
|
);
|
||||||
|
|
||||||
companion object {
|
companion object {
|
||||||
val bottomBarItems = listOf(
|
val bottomBarItems = listOf(
|
||||||
CoffeeList,
|
CoffeeList,
|
||||||
Profile,
|
Profile,
|
||||||
Cart,
|
Cart
|
||||||
)
|
)
|
||||||
|
|
||||||
fun getItem(route: String): Screen? {
|
fun getItem(route: String): Screen? {
|
||||||
val findRoute = route.split("/").first()
|
val findRoute = route.split("/").first()
|
||||||
return entries.find { value -> value.route.startsWith(findRoute) }
|
return values().find { value -> value.route.startsWith(findRoute) }
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
Loading…
Reference in New Issue
Block a user