much done, need fixes

This commit is contained in:
zyzf 2023-12-04 01:52:39 +04:00
parent 889e80ad9e
commit ef95904c6f
15 changed files with 144 additions and 213 deletions

View File

@ -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$" />

View File

@ -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">

View File

@ -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")

View File

@ -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>

View File

@ -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()
}
}
} }

View File

@ -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 {

View File

@ -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")

View File

@ -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 {

View File

@ -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)
}
} }
} }

View File

@ -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("Удалить")

View File

@ -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)

View File

@ -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 = "Зарегистрироваться")
} }
} }
} }

View File

@ -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())

View File

@ -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()
}
}
} }

View File

@ -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) }
} }
} }
} }