From dc89f3e57a153bb448dfeac6cf0fdcc63e37082e Mon Sep 17 00:00:00 2001 From: Nafisul Nazrul Date: Tue, 10 Oct 2023 13:10:35 +0300 Subject: [PATCH 01/32] Changed Oncreate component --- .idea/deploymentTargetDropDown.xml | 17 ----------------- .../java/com/example/mycloset/MainActivity.kt | 3 ++- 2 files changed, 2 insertions(+), 18 deletions(-) delete mode 100644 .idea/deploymentTargetDropDown.xml diff --git a/.idea/deploymentTargetDropDown.xml b/.idea/deploymentTargetDropDown.xml deleted file mode 100644 index 6f66088..0000000 --- a/.idea/deploymentTargetDropDown.xml +++ /dev/null @@ -1,17 +0,0 @@ - - - - - - - - - - - - - - - - - \ No newline at end of file diff --git a/app/src/main/java/com/example/mycloset/MainActivity.kt b/app/src/main/java/com/example/mycloset/MainActivity.kt index 8d5b467..68b1f51 100644 --- a/app/src/main/java/com/example/mycloset/MainActivity.kt +++ b/app/src/main/java/com/example/mycloset/MainActivity.kt @@ -41,6 +41,7 @@ import androidx.core.content.ContextCompat import androidx.navigation.NavHost import androidx.navigation.NavHostController import androidx.navigation.compose.rememberNavController +import com.example.mycloset.App.LoginApp import com.example.mycloset.Views.MainScreen import com.example.mycloset.ui.theme.AppTheme import com.google.mlkit.vision.barcode.BarcodeScannerOptions @@ -72,7 +73,7 @@ class MainActivity : ComponentActivity() { // Add Navigation navController = rememberNavController() // SetupNavGraph(navController = navController) - MainScreen() + LoginApp() /*CameraView( cameraController = cameraController, barcodesFlow = viewModel.barcodesFlow, From b9ed625f8f61fed0445af6637576d120ee945eec Mon Sep 17 00:00:00 2001 From: Liideli Date: Wed, 11 Oct 2023 12:27:49 +0300 Subject: [PATCH 02/32] Get Items with user email and bind them to homeScreen cards in progress. --- .../java/com/example/mycloset/AppContainer.kt | 4 +++ .../example/mycloset/AppViewModelProvider.kt | 3 +- .../java/com/example/mycloset/BarcodeModel.kt | 2 +- .../com/example/mycloset/BarcodeRepository.kt | 2 +- .../java/com/example/mycloset/ImgDisplay.kt | 5 ++- .../java/com/example/mycloset/MainActivity.kt | 2 +- .../mycloset/OfflineProductRepository.kt | 8 +++++ .../java/com/example/mycloset/ProductDao.kt | 6 +++- .../com/example/mycloset/ProductDatabase.kt | 8 ----- .../com/example/mycloset/ProductEntity.kt | 1 + .../com/example/mycloset/ProductRepository.kt | 10 ++++++ .../com/example/mycloset/ProductViewModel.kt | 36 +++++++++++++++++-- .../com/example/mycloset/Views/HomeScreen.kt | 19 ++++++---- .../example/mycloset/Views/ProductScanView.kt | 31 ++++++++++++---- .../mycloset/Views/SingleItemScreen.kt | 6 ++-- 15 files changed, 112 insertions(+), 31 deletions(-) create mode 100644 app/src/main/java/com/example/mycloset/OfflineProductRepository.kt create mode 100644 app/src/main/java/com/example/mycloset/ProductRepository.kt diff --git a/app/src/main/java/com/example/mycloset/AppContainer.kt b/app/src/main/java/com/example/mycloset/AppContainer.kt index 87b7307..296bc4e 100644 --- a/app/src/main/java/com/example/mycloset/AppContainer.kt +++ b/app/src/main/java/com/example/mycloset/AppContainer.kt @@ -9,6 +9,7 @@ import android.content.Context */ interface AppContainer { val appDatabase: ProductDatabase + val productRepository: ProductRepository } class AppDataContainer(private val context: Context) : @@ -17,4 +18,7 @@ class AppDataContainer(private val context: Context) : override val appDatabase: ProductDatabase by lazy { ProductDatabase.getInstance(context) } + override val productRepository: ProductRepository by lazy { + OfflineProductRepository(ProductDatabase.getInstance(context).productDao()) + } } \ No newline at end of file diff --git a/app/src/main/java/com/example/mycloset/AppViewModelProvider.kt b/app/src/main/java/com/example/mycloset/AppViewModelProvider.kt index 51c8e9e..871539e 100644 --- a/app/src/main/java/com/example/mycloset/AppViewModelProvider.kt +++ b/app/src/main/java/com/example/mycloset/AppViewModelProvider.kt @@ -13,7 +13,8 @@ object AppViewModelProvider { val Factory = viewModelFactory { initializer { ProductViewModel( - productDao = MyApplication().container.appDatabase.productDao() + productDao = MyApplication().container.appDatabase.productDao(), + productRepository = MyApplication().container.productRepository ) } } diff --git a/app/src/main/java/com/example/mycloset/BarcodeModel.kt b/app/src/main/java/com/example/mycloset/BarcodeModel.kt index 1c7a171..f9c23a1 100644 --- a/app/src/main/java/com/example/mycloset/BarcodeModel.kt +++ b/app/src/main/java/com/example/mycloset/BarcodeModel.kt @@ -1,3 +1,3 @@ package com.example.mycloset -data class BarcodeModel(val barcode: String) \ No newline at end of file +data class BarcodeModel(var barcode: String) \ No newline at end of file diff --git a/app/src/main/java/com/example/mycloset/BarcodeRepository.kt b/app/src/main/java/com/example/mycloset/BarcodeRepository.kt index 4afacbc..312f67f 100644 --- a/app/src/main/java/com/example/mycloset/BarcodeRepository.kt +++ b/app/src/main/java/com/example/mycloset/BarcodeRepository.kt @@ -1,7 +1,7 @@ package com.example.mycloset // -var APY_KEY:String="3nupb3et7t5lbqlhhhspyrh3si1wu0" +var APY_KEY:String="5gk0yh025ap4ft1figtfganr7b7g2o" //class for using the barcode-lookup API class BarcodeRepository{ diff --git a/app/src/main/java/com/example/mycloset/ImgDisplay.kt b/app/src/main/java/com/example/mycloset/ImgDisplay.kt index 6e8c6b0..fd349cb 100644 --- a/app/src/main/java/com/example/mycloset/ImgDisplay.kt +++ b/app/src/main/java/com/example/mycloset/ImgDisplay.kt @@ -4,14 +4,17 @@ import android.graphics.Bitmap import android.graphics.BitmapFactory import android.util.Log import androidx.compose.foundation.Image +import androidx.compose.foundation.layout.size import androidx.compose.runtime.Composable import androidx.compose.runtime.LaunchedEffect import androidx.compose.runtime.getValue import androidx.compose.runtime.mutableStateOf import androidx.compose.runtime.remember import androidx.compose.runtime.setValue +import androidx.compose.ui.Modifier import androidx.compose.ui.graphics.ImageBitmap import androidx.compose.ui.graphics.asImageBitmap +import androidx.compose.ui.unit.dp import kotlinx.coroutines.Dispatchers import kotlinx.coroutines.withContext import java.io.InputStream @@ -29,7 +32,7 @@ class ImgDisplay { bitmap= showImg(url)?.asImageBitmap() } bitmap?.let { bitmap -> - Image(bitmap = bitmap, contentDescription = "downloaded picture") + Image(modifier = Modifier.size(200.dp), bitmap = bitmap, contentDescription = "downloaded picture") } } diff --git a/app/src/main/java/com/example/mycloset/MainActivity.kt b/app/src/main/java/com/example/mycloset/MainActivity.kt index f76335e..6409968 100644 --- a/app/src/main/java/com/example/mycloset/MainActivity.kt +++ b/app/src/main/java/com/example/mycloset/MainActivity.kt @@ -28,7 +28,6 @@ class MainActivity : ComponentActivity() { // ViewModel for handling camera and barcode scanning logic private val viewModel: CameraScanViewModel by viewModels() - private val productViewModel: ProductViewModel by viewModels() override fun onCreate(savedInstanceState: Bundle?) { super.onCreate(savedInstanceState) @@ -46,6 +45,7 @@ class MainActivity : ComponentActivity() { navController = rememberNavController() // SetupNavGraph(navController = navController) val productViewModel: ProductViewModel = viewModel(factory = AppViewModelProvider.Factory) + //HomeScreen(navController = navController, viewModel = productViewModel) ProductScanView( productViewModel, barcodesFlow = viewModel.barcodesFlow, diff --git a/app/src/main/java/com/example/mycloset/OfflineProductRepository.kt b/app/src/main/java/com/example/mycloset/OfflineProductRepository.kt new file mode 100644 index 0000000..ac57ad7 --- /dev/null +++ b/app/src/main/java/com/example/mycloset/OfflineProductRepository.kt @@ -0,0 +1,8 @@ +package com.example.mycloset + +class OfflineProductRepository(private val productDao: ProductDao) : ProductRepository { + override fun getAllProductsStream() = productDao.getAllProducts() + + override fun getAllProductsWithEmailStream(userEmail: String) = productDao.getProductsWithEmail(userEmail) + +} \ No newline at end of file diff --git a/app/src/main/java/com/example/mycloset/ProductDao.kt b/app/src/main/java/com/example/mycloset/ProductDao.kt index a06cc3a..cdb212c 100644 --- a/app/src/main/java/com/example/mycloset/ProductDao.kt +++ b/app/src/main/java/com/example/mycloset/ProductDao.kt @@ -4,6 +4,7 @@ import androidx.room.Dao import androidx.room.Insert import androidx.room.OnConflictStrategy import androidx.room.Query +import kotlinx.coroutines.flow.Flow @Dao interface ProductDao { @@ -11,5 +12,8 @@ interface ProductDao { suspend fun insertProduct(product: ProductEntity) @Query("SELECT * FROM products") - suspend fun getAllProducts(): List + fun getAllProducts(): Flow> + + @Query("SELECT * from products WHERE userEmail = :userEmail") + fun getProductsWithEmail(userEmail: String): Flow> } diff --git a/app/src/main/java/com/example/mycloset/ProductDatabase.kt b/app/src/main/java/com/example/mycloset/ProductDatabase.kt index d6b75a5..14add78 100644 --- a/app/src/main/java/com/example/mycloset/ProductDatabase.kt +++ b/app/src/main/java/com/example/mycloset/ProductDatabase.kt @@ -26,12 +26,4 @@ abstract class ProductDatabase : RoomDatabase() { .build() } } -} - -class DatabaseManager(context: Context) { - private val database = ProductDatabase.getInstance(context) - - suspend fun insertProduct(product: ProductEntity) { - database.productDao().insertProduct(product) - } } \ No newline at end of file diff --git a/app/src/main/java/com/example/mycloset/ProductEntity.kt b/app/src/main/java/com/example/mycloset/ProductEntity.kt index dc9f0f5..0503a66 100644 --- a/app/src/main/java/com/example/mycloset/ProductEntity.kt +++ b/app/src/main/java/com/example/mycloset/ProductEntity.kt @@ -6,6 +6,7 @@ import androidx.room.PrimaryKey @Entity(tableName = "products") data class ProductEntity( @PrimaryKey val barcodeNumber: String, + val userEmail: String, val model: String, val title: String, val category: String, diff --git a/app/src/main/java/com/example/mycloset/ProductRepository.kt b/app/src/main/java/com/example/mycloset/ProductRepository.kt new file mode 100644 index 0000000..08bde6d --- /dev/null +++ b/app/src/main/java/com/example/mycloset/ProductRepository.kt @@ -0,0 +1,10 @@ +package com.example.mycloset + +import kotlinx.coroutines.flow.Flow + +// Repository that provides insert, update, delete, and retrieve of [Product] from a given data source. +interface ProductRepository { + fun getAllProductsStream(): Flow> + + fun getAllProductsWithEmailStream(userEmail: String): Flow> +} \ No newline at end of file diff --git a/app/src/main/java/com/example/mycloset/ProductViewModel.kt b/app/src/main/java/com/example/mycloset/ProductViewModel.kt index 9a25be8..e0ad68e 100644 --- a/app/src/main/java/com/example/mycloset/ProductViewModel.kt +++ b/app/src/main/java/com/example/mycloset/ProductViewModel.kt @@ -11,12 +11,15 @@ import kotlinx.coroutines.Dispatchers import kotlinx.coroutines.launch //view-model used for the take the information about one product from its barcode -class ProductViewModel(val productDao: ProductDao) : ViewModel() { +class ProductViewModel(val productDao: ProductDao, val productRepository: ProductRepository) : + ViewModel() { private val repository: BarcodeRepository = BarcodeRepository() var informationProductMap by mutableStateOf(emptyMap()) + var products by mutableStateOf(emptyList()) fun saveToDatabase( barcodeNumber: String, + userEmail: String, model: String, title: String, category: String, @@ -27,12 +30,41 @@ class ProductViewModel(val productDao: ProductDao) : ViewModel() { images: String ) { viewModelScope.launch(Dispatchers.IO) { - val productInformation = ProductEntity(barcodeNumber, model, title, category, brand, color, material, size, images) + val productInformation = ProductEntity( + barcodeNumber, + userEmail, + model, + title, + category, + brand, + color, + material, + size, + images + ) productDao.insertProduct(productInformation) Log.i("SAV", "Saved to database") } } + // Get all products + fun getProducts() { + viewModelScope.launch { + productRepository.getAllProductsStream().collect() { response -> + products = response + } + } + } + + // Get products with logged in email + fun getProductsWithEmail(userEmail: String) { + viewModelScope.launch { + productRepository.getAllProductsWithEmailStream(userEmail).collect() { response -> + products = response + } + } + } + //the result will be an array of strings fun getInfo(barcode: String) { // Code for API call and conversion diff --git a/app/src/main/java/com/example/mycloset/Views/HomeScreen.kt b/app/src/main/java/com/example/mycloset/Views/HomeScreen.kt index ce4d5d8..479ef1a 100644 --- a/app/src/main/java/com/example/mycloset/Views/HomeScreen.kt +++ b/app/src/main/java/com/example/mycloset/Views/HomeScreen.kt @@ -21,10 +21,12 @@ import androidx.compose.runtime.* import androidx.compose.ui.Alignment import androidx.compose.ui.Modifier import androidx.compose.ui.text.style.TextAlign -import androidx.compose.ui.tooling.preview.Preview import androidx.compose.ui.unit.dp import androidx.navigation.NavController -import androidx.navigation.compose.rememberNavController +import com.example.mycloset.ProductViewModel +import kotlinx.coroutines.flow.* + + //import com.example.mycloset.Screen @@ -67,7 +69,10 @@ fun EmptyHomeScreen() { @OptIn(ExperimentalMaterial3Api::class) @Composable -fun HomeScreen(navController: NavController) { +fun HomeScreen(navController: NavController, viewModel: ProductViewModel) { + // Observe the products list from the ViewModel + viewModel.getProductsWithEmail(userEmail) + val products = viewModel.products Scaffold(topBar = { TopAppBar( // colors = topAppBarColors( @@ -91,13 +96,15 @@ fun HomeScreen(navController: NavController) { .fillMaxSize() .padding(16.dp) ) { - items(10) { - ItemCard("https://media.istockphoto.com/id/1303978937/fi/valokuva/valkoinen-lenkkari-sinisell%C3%A4-kaltevuustaustalla-miesten-muoti-urheilukenk%C3%A4-lenkkarit.jpg?s=612x612&w=0&k=20&c=X_lwi6td_xtFUGXjOmAU8WzH-MKPZ-OeWKtKUshe-SI=", "nike") + items(products.size) { index -> + val product = products[index] + ItemCard(product.images, product.title) } } } } +/* @Preview @Composable fun PrevHome() { @@ -111,4 +118,4 @@ fun PrevHome() { fun PreEmpty() { EmptyHomeScreen() } - +*/ diff --git a/app/src/main/java/com/example/mycloset/Views/ProductScanView.kt b/app/src/main/java/com/example/mycloset/Views/ProductScanView.kt index c8d50a4..7ae1cfa 100644 --- a/app/src/main/java/com/example/mycloset/Views/ProductScanView.kt +++ b/app/src/main/java/com/example/mycloset/Views/ProductScanView.kt @@ -224,14 +224,16 @@ fun ProductScanView( contentPadding = PaddingValues(16.dp) ) { informationProductMap.forEach { (key, value) -> - if (key != "title" && key != "images") { + if (key != "title" && key != "images" && key != "barcodeNumber") { item { Row( modifier = Modifier.fillMaxWidth(), horizontalArrangement = Arrangement.SpaceBetween ) { - Text(text = key, fontWeight = FontWeight.Bold) - Text(text = value) + if (value.isNotEmpty()) { + Text(text = "$key: ", fontWeight = FontWeight.Bold) + Text(text = value) + } } Spacer(modifier = Modifier.height(8.dp)) } @@ -244,10 +246,27 @@ fun ProductScanView( modifier = Modifier.fillMaxWidth(), horizontalArrangement = Arrangement.SpaceBetween ) { - Button(onClick = { showProductInfo = false }) { - Text(text = "Cancel") + Button(onClick = { + showProductInfo = false + }) { + Text(text = "Back") } - Button(onClick = { productViewModel.saveToDatabase(barcodeNumber, model, title, category, brand, color, material, size, images) }) { + Button(onClick = { + productViewModel.saveToDatabase( + barcodeNumber, + userEmail, + model, + title, + category, + brand, + color, + material, + size, + images + ) + Toast.makeText(context, "Item added!", Toast.LENGTH_SHORT) + .show() + }) { Text(text = "Add") } } diff --git a/app/src/main/java/com/example/mycloset/Views/SingleItemScreen.kt b/app/src/main/java/com/example/mycloset/Views/SingleItemScreen.kt index 099062f..e7485ad 100644 --- a/app/src/main/java/com/example/mycloset/Views/SingleItemScreen.kt +++ b/app/src/main/java/com/example/mycloset/Views/SingleItemScreen.kt @@ -65,14 +65,14 @@ fun SingleItemScreen(productViewModel: ProductViewModel) { contentPadding = PaddingValues(16.dp) ) { informationProductMap.forEach { (key, value) -> - if (key != "title" && key != "images") { + if (key != "title" && key != "images" && key != "barcodeNumber") { item { Row( modifier = Modifier.fillMaxWidth(), horizontalArrangement = Arrangement.SpaceBetween ) { Text(text = key, fontWeight = FontWeight.Bold) - Text(text = value.toString()) + Text(text = value) } Spacer(modifier = Modifier.height(8.dp)) } @@ -86,7 +86,7 @@ fun SingleItemScreen(productViewModel: ProductViewModel) { Text(text = "Cancel") } Button(onClick = { /*TODO*/ }) { - Text(text = "Add") + Text(text = "Delete") } } From 4704e7f2f956fbc3908c0b8b8e671b5424936e0e Mon Sep 17 00:00:00 2001 From: Liideli Date: Wed, 11 Oct 2023 14:06:21 +0300 Subject: [PATCH 03/32] Get Items with user email and bind them to homeScreen cards in progress. --- .../java/com/example/mycloset/AppContainer.kt | 2 ++ .../OfflineProductRepository.kt | 2 +- .../mycloset/DatabaseWorkingset/ProductDao.kt | 3 +- .../ProductRepository.kt | 2 +- .../java/com/example/mycloset/MainActivity.kt | 3 +- .../mycloset/Views/ClothesDetailScreen.kt | 30 ------------------- .../com/example/mycloset/Views/HomeScreen.kt | 8 ++--- 7 files changed, 12 insertions(+), 38 deletions(-) rename app/src/main/java/com/example/mycloset/{ => DatabaseWorkingset}/OfflineProductRepository.kt (85%) rename app/src/main/java/com/example/mycloset/{ => DatabaseWorkingset}/ProductRepository.kt (86%) diff --git a/app/src/main/java/com/example/mycloset/AppContainer.kt b/app/src/main/java/com/example/mycloset/AppContainer.kt index afff05d..c5e17ab 100644 --- a/app/src/main/java/com/example/mycloset/AppContainer.kt +++ b/app/src/main/java/com/example/mycloset/AppContainer.kt @@ -1,7 +1,9 @@ package com.example.mycloset import android.content.Context +import com.example.mycloset.DatabaseWorkingset.OfflineProductRepository import com.example.mycloset.DatabaseWorkingset.ProductDatabase +import com.example.mycloset.DatabaseWorkingset.ProductRepository /** diff --git a/app/src/main/java/com/example/mycloset/OfflineProductRepository.kt b/app/src/main/java/com/example/mycloset/DatabaseWorkingset/OfflineProductRepository.kt similarity index 85% rename from app/src/main/java/com/example/mycloset/OfflineProductRepository.kt rename to app/src/main/java/com/example/mycloset/DatabaseWorkingset/OfflineProductRepository.kt index ac57ad7..b386be7 100644 --- a/app/src/main/java/com/example/mycloset/OfflineProductRepository.kt +++ b/app/src/main/java/com/example/mycloset/DatabaseWorkingset/OfflineProductRepository.kt @@ -1,4 +1,4 @@ -package com.example.mycloset +package com.example.mycloset.DatabaseWorkingset class OfflineProductRepository(private val productDao: ProductDao) : ProductRepository { override fun getAllProductsStream() = productDao.getAllProducts() diff --git a/app/src/main/java/com/example/mycloset/DatabaseWorkingset/ProductDao.kt b/app/src/main/java/com/example/mycloset/DatabaseWorkingset/ProductDao.kt index 231389d..a96df40 100644 --- a/app/src/main/java/com/example/mycloset/DatabaseWorkingset/ProductDao.kt +++ b/app/src/main/java/com/example/mycloset/DatabaseWorkingset/ProductDao.kt @@ -5,16 +5,17 @@ import androidx.room.Insert import androidx.room.OnConflictStrategy import androidx.room.Query import kotlinx.coroutines.flow.Flow -import com.example.mycloset.DatabaseWorkingset.ProductEntity @Dao interface ProductDao { @Insert(onConflict = OnConflictStrategy.REPLACE) suspend fun insertProduct(product: ProductEntity) + // Get all products @Query("SELECT * FROM products") fun getAllProducts(): Flow> + // Get products of logged in user @Query("SELECT * from products WHERE userEmail = :userEmail") fun getProductsWithEmail(userEmail: String): Flow> } diff --git a/app/src/main/java/com/example/mycloset/ProductRepository.kt b/app/src/main/java/com/example/mycloset/DatabaseWorkingset/ProductRepository.kt similarity index 86% rename from app/src/main/java/com/example/mycloset/ProductRepository.kt rename to app/src/main/java/com/example/mycloset/DatabaseWorkingset/ProductRepository.kt index 08bde6d..158d7d2 100644 --- a/app/src/main/java/com/example/mycloset/ProductRepository.kt +++ b/app/src/main/java/com/example/mycloset/DatabaseWorkingset/ProductRepository.kt @@ -1,4 +1,4 @@ -package com.example.mycloset +package com.example.mycloset.DatabaseWorkingset import kotlinx.coroutines.flow.Flow diff --git a/app/src/main/java/com/example/mycloset/MainActivity.kt b/app/src/main/java/com/example/mycloset/MainActivity.kt index 0ec7a6a..1d3e068 100644 --- a/app/src/main/java/com/example/mycloset/MainActivity.kt +++ b/app/src/main/java/com/example/mycloset/MainActivity.kt @@ -26,7 +26,7 @@ import com.google.mlkit.vision.barcode.common.Barcode class MainActivity : ComponentActivity() { lateinit var navController: NavHostController -// val navController = rememberNavController() + //val navController = rememberNavController() // ViewModel for handling camera and barcode scanning logic private val viewModel: CameraScanViewModel by viewModels() @@ -48,6 +48,7 @@ class MainActivity : ComponentActivity() { // SetupNavGraph(navController = navController) val productViewModel: ProductViewModel = viewModel(factory = AppViewModelProvider.Factory) //HomeScreen(navController = navController, viewModel = productViewModel) + //LoginScreen() ProductScanView( productViewModel, barcodesFlow = viewModel.barcodesFlow, diff --git a/app/src/main/java/com/example/mycloset/Views/ClothesDetailScreen.kt b/app/src/main/java/com/example/mycloset/Views/ClothesDetailScreen.kt index 110d101..7087676 100644 --- a/app/src/main/java/com/example/mycloset/Views/ClothesDetailScreen.kt +++ b/app/src/main/java/com/example/mycloset/Views/ClothesDetailScreen.kt @@ -1,35 +1,5 @@ package com.example.mycloset.Views -import android.os.Bundle -import androidx.activity.ComponentActivity -import androidx.activity.compose.setContent -import androidx.compose.foundation.layout.Arrangement -import androidx.compose.foundation.layout.Column -import androidx.compose.foundation.layout.Row -import androidx.compose.foundation.layout.Spacer -import androidx.compose.foundation.layout.fillMaxSize -import androidx.compose.foundation.layout.fillMaxWidth -import androidx.compose.foundation.layout.padding -import androidx.compose.foundation.layout.width -import androidx.compose.foundation.shape.RoundedCornerShape -import androidx.compose.material3.Button -import androidx.compose.material3.Card -import androidx.compose.material3.MaterialTheme -import androidx.compose.material3.Surface -import androidx.compose.material3.Text -import androidx.compose.runtime.Composable -import androidx.compose.runtime.mutableStateOf -import androidx.compose.runtime.remember -import androidx.compose.ui.Alignment -import androidx.compose.ui.Modifier -import androidx.compose.ui.graphics.Color -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 androidx.navigation.NavHostController -import com.example.mycloset.DatabaseWorkingset.ui.theme.MyClosetTheme - /*@Composable fun clothesDetailScreen( navController: NavHostController, diff --git a/app/src/main/java/com/example/mycloset/Views/HomeScreen.kt b/app/src/main/java/com/example/mycloset/Views/HomeScreen.kt index 479ef1a..744a550 100644 --- a/app/src/main/java/com/example/mycloset/Views/HomeScreen.kt +++ b/app/src/main/java/com/example/mycloset/Views/HomeScreen.kt @@ -1,8 +1,6 @@ -@file:OptIn(ExperimentalFoundationApi::class) package com.example.mycloset.Views -import androidx.compose.foundation.ExperimentalFoundationApi import androidx.compose.foundation.layout.Box import androidx.compose.foundation.layout.fillMaxSize import androidx.compose.foundation.layout.padding @@ -23,10 +21,12 @@ import androidx.compose.ui.Modifier import androidx.compose.ui.text.style.TextAlign import androidx.compose.ui.unit.dp import androidx.navigation.NavController -import com.example.mycloset.ProductViewModel +import com.example.mycloset.DatabaseWorkingset.ProductViewModel +import com.example.mycloset.LoginWorkingSet.LoggedUser import kotlinx.coroutines.flow.* + //import com.example.mycloset.Screen @@ -71,7 +71,7 @@ fun EmptyHomeScreen() { @Composable fun HomeScreen(navController: NavController, viewModel: ProductViewModel) { // Observe the products list from the ViewModel - viewModel.getProductsWithEmail(userEmail) + viewModel.getProductsWithEmail(LoggedUser.loggedUserEmail) val products = viewModel.products Scaffold(topBar = { TopAppBar( From ceff5969ecc97a73fe08a4cd77a0f9687c65ffa6 Mon Sep 17 00:00:00 2001 From: Nafisul Nazrul Date: Wed, 11 Oct 2023 14:12:58 +0300 Subject: [PATCH 04/32] navigation --- app/src/main/res/drawable/airfocrce.jpeg | Bin 0 -> 39396 bytes 1 file changed, 0 insertions(+), 0 deletions(-) create mode 100644 app/src/main/res/drawable/airfocrce.jpeg diff --git a/app/src/main/res/drawable/airfocrce.jpeg b/app/src/main/res/drawable/airfocrce.jpeg new file mode 100644 index 0000000000000000000000000000000000000000..2d51706c78a84fb816947d7b9e1eb3b8cd77d39c GIT binary patch literal 39396 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

O?6u@GqlcFWm7xs8pfXJTF%YeR5NBr&WMuBI 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 AoB#j- literal 0 HcmV?d00001 From 63d138b5e2e302ad81623e79f04a11edcbcdb33c Mon Sep 17 00:00:00 2001 From: matti Date: Wed, 11 Oct 2023 13:36:57 +0200 Subject: [PATCH 05/32] Update and delate are now in the DAO, viewmodel and repository (Database), The Offline Product reoisutory is commented --- .../DatabaseWorkingset/OfflineProductRepository.kt | 4 ++-- .../mycloset/DatabaseWorkingset/ProductDao.kt | 8 ++++++++ .../DatabaseWorkingset/ProductRepository.kt | 3 ++- .../DatabaseWorkingset/ProductViewModel.kt | 14 ++++++++++++++ 4 files changed, 26 insertions(+), 3 deletions(-) diff --git a/app/src/main/java/com/example/mycloset/DatabaseWorkingset/OfflineProductRepository.kt b/app/src/main/java/com/example/mycloset/DatabaseWorkingset/OfflineProductRepository.kt index b386be7..cd30359 100644 --- a/app/src/main/java/com/example/mycloset/DatabaseWorkingset/OfflineProductRepository.kt +++ b/app/src/main/java/com/example/mycloset/DatabaseWorkingset/OfflineProductRepository.kt @@ -1,8 +1,8 @@ package com.example.mycloset.DatabaseWorkingset -class OfflineProductRepository(private val productDao: ProductDao) : ProductRepository { +/*class OfflineProductRepository(private val productDao: ProductDao) : ProductRepository { override fun getAllProductsStream() = productDao.getAllProducts() override fun getAllProductsWithEmailStream(userEmail: String) = productDao.getProductsWithEmail(userEmail) -} \ No newline at end of file +}*/ \ No newline at end of file diff --git a/app/src/main/java/com/example/mycloset/DatabaseWorkingset/ProductDao.kt b/app/src/main/java/com/example/mycloset/DatabaseWorkingset/ProductDao.kt index a96df40..3217455 100644 --- a/app/src/main/java/com/example/mycloset/DatabaseWorkingset/ProductDao.kt +++ b/app/src/main/java/com/example/mycloset/DatabaseWorkingset/ProductDao.kt @@ -1,9 +1,11 @@ package com.example.mycloset.DatabaseWorkingset import androidx.room.Dao +import androidx.room.Delete import androidx.room.Insert import androidx.room.OnConflictStrategy import androidx.room.Query +import androidx.room.Update import kotlinx.coroutines.flow.Flow @Dao @@ -18,4 +20,10 @@ interface ProductDao { // Get products of logged in user @Query("SELECT * from products WHERE userEmail = :userEmail") fun getProductsWithEmail(userEmail: String): Flow> + + @Update + suspend fun updateProductDetails(product: ProductEntity) + + @Delete + suspend fun deleteProduct(product: ProductEntity) } diff --git a/app/src/main/java/com/example/mycloset/DatabaseWorkingset/ProductRepository.kt b/app/src/main/java/com/example/mycloset/DatabaseWorkingset/ProductRepository.kt index 158d7d2..97987fc 100644 --- a/app/src/main/java/com/example/mycloset/DatabaseWorkingset/ProductRepository.kt +++ b/app/src/main/java/com/example/mycloset/DatabaseWorkingset/ProductRepository.kt @@ -5,6 +5,7 @@ import kotlinx.coroutines.flow.Flow // Repository that provides insert, update, delete, and retrieve of [Product] from a given data source. interface ProductRepository { fun getAllProductsStream(): Flow> - fun getAllProductsWithEmailStream(userEmail: String): Flow> + fun updateProductDetailsStream(product: ProductEntity) + fun deleteProductStream(product: ProductEntity) } \ No newline at end of file diff --git a/app/src/main/java/com/example/mycloset/DatabaseWorkingset/ProductViewModel.kt b/app/src/main/java/com/example/mycloset/DatabaseWorkingset/ProductViewModel.kt index 9a19ad8..e202eb1 100644 --- a/app/src/main/java/com/example/mycloset/DatabaseWorkingset/ProductViewModel.kt +++ b/app/src/main/java/com/example/mycloset/DatabaseWorkingset/ProductViewModel.kt @@ -56,6 +56,20 @@ class ProductViewModel(val productDao: ProductDao, val productRepository: Produc } } + //update + fun updateProductDetails(product:ProductEntity){ + viewModelScope.launch { + productRepository.updateProductDetailsStream(product) + } + } + + //delete + fun deleteProduct(product:ProductEntity){ + viewModelScope.launch { + productRepository.deleteProductStream(product) + } + } + //the result will be an array of strings fun getInfo(barcode: String) { // Code for API call and conversion From 9ac1cbc08e63e14171414906b25eb2b7a5b05419 Mon Sep 17 00:00:00 2001 From: matti Date: Wed, 11 Oct 2023 13:37:23 +0200 Subject: [PATCH 06/32] Update and delate are now in the DAO, viewmodel and repository (Database), The Offline Product repository is commented --- .../DatabaseWorkingset/ui/theme/Color.kt | 11 +++ .../DatabaseWorkingset/ui/theme/Theme.kt | 70 +++++++++++++++++++ .../DatabaseWorkingset/ui/theme/Type.kt | 34 +++++++++ 3 files changed, 115 insertions(+) create mode 100644 app/src/main/java/com/example/mycloset/DatabaseWorkingset/ui/theme/Color.kt create mode 100644 app/src/main/java/com/example/mycloset/DatabaseWorkingset/ui/theme/Theme.kt create mode 100644 app/src/main/java/com/example/mycloset/DatabaseWorkingset/ui/theme/Type.kt diff --git a/app/src/main/java/com/example/mycloset/DatabaseWorkingset/ui/theme/Color.kt b/app/src/main/java/com/example/mycloset/DatabaseWorkingset/ui/theme/Color.kt new file mode 100644 index 0000000..b6046c6 --- /dev/null +++ b/app/src/main/java/com/example/mycloset/DatabaseWorkingset/ui/theme/Color.kt @@ -0,0 +1,11 @@ +package com.example.mycloset.DatabaseWorkingset.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) \ No newline at end of file diff --git a/app/src/main/java/com/example/mycloset/DatabaseWorkingset/ui/theme/Theme.kt b/app/src/main/java/com/example/mycloset/DatabaseWorkingset/ui/theme/Theme.kt new file mode 100644 index 0000000..c0e609a --- /dev/null +++ b/app/src/main/java/com/example/mycloset/DatabaseWorkingset/ui/theme/Theme.kt @@ -0,0 +1,70 @@ +package com.example.mycloset.DatabaseWorkingset.ui.theme + +import android.app.Activity +import android.os.Build +import androidx.compose.foundation.isSystemInDarkTheme +import androidx.compose.material3.MaterialTheme +import androidx.compose.material3.darkColorScheme +import androidx.compose.material3.dynamicDarkColorScheme +import androidx.compose.material3.dynamicLightColorScheme +import androidx.compose.material3.lightColorScheme +import androidx.compose.runtime.Composable +import androidx.compose.runtime.SideEffect +import androidx.compose.ui.graphics.toArgb +import androidx.compose.ui.platform.LocalContext +import androidx.compose.ui.platform.LocalView +import androidx.core.view.WindowCompat + +private val DarkColorScheme = darkColorScheme( + primary = Purple80, + secondary = PurpleGrey80, + tertiary = Pink80 +) + +private val LightColorScheme = lightColorScheme( + primary = Purple40, + secondary = PurpleGrey40, + tertiary = Pink40 + + /* Other default colors to override + background = Color(0xFFFFFBFE), + surface = Color(0xFFFFFBFE), + onPrimary = Color.White, + onSecondary = Color.White, + onTertiary = Color.White, + onBackground = Color(0xFF1C1B1F), + onSurface = Color(0xFF1C1B1F), + */ +) + +@Composable +fun MyClosetTheme( + darkTheme: Boolean = isSystemInDarkTheme(), + // Dynamic color is available on Android 12+ + dynamicColor: Boolean = true, + content: @Composable () -> Unit +) { + val colorScheme = when { + dynamicColor && Build.VERSION.SDK_INT >= Build.VERSION_CODES.S -> { + val context = LocalContext.current + if (darkTheme) dynamicDarkColorScheme(context) else dynamicLightColorScheme(context) + } + + darkTheme -> DarkColorScheme + else -> LightColorScheme + } + val view = LocalView.current + if (!view.isInEditMode) { + SideEffect { + val window = (view.context as Activity).window + window.statusBarColor = colorScheme.primary.toArgb() + WindowCompat.getInsetsController(window, view).isAppearanceLightStatusBars = darkTheme + } + } + + MaterialTheme( + colorScheme = colorScheme, + typography = Typography, + content = content + ) +} \ No newline at end of file diff --git a/app/src/main/java/com/example/mycloset/DatabaseWorkingset/ui/theme/Type.kt b/app/src/main/java/com/example/mycloset/DatabaseWorkingset/ui/theme/Type.kt new file mode 100644 index 0000000..8a04c50 --- /dev/null +++ b/app/src/main/java/com/example/mycloset/DatabaseWorkingset/ui/theme/Type.kt @@ -0,0 +1,34 @@ +package com.example.mycloset.DatabaseWorkingset.ui.theme + +import androidx.compose.material3.Typography +import androidx.compose.ui.text.TextStyle +import androidx.compose.ui.text.font.FontFamily +import androidx.compose.ui.text.font.FontWeight +import androidx.compose.ui.unit.sp + +// Set of Material typography styles to start with +val Typography = Typography( + bodyLarge = TextStyle( + fontFamily = FontFamily.Default, + fontWeight = FontWeight.Normal, + fontSize = 16.sp, + lineHeight = 24.sp, + letterSpacing = 0.5.sp + ) + /* Other default text styles to override + titleLarge = TextStyle( + fontFamily = FontFamily.Default, + fontWeight = FontWeight.Normal, + fontSize = 22.sp, + lineHeight = 28.sp, + letterSpacing = 0.sp + ), + labelSmall = TextStyle( + fontFamily = FontFamily.Default, + fontWeight = FontWeight.Medium, + fontSize = 11.sp, + lineHeight = 16.sp, + letterSpacing = 0.5.sp + ) + */ +) \ No newline at end of file From 6cb2efbff354793bd4eabf104ea9c6e89b2aa648 Mon Sep 17 00:00:00 2001 From: Nafisul Nazrul Date: Wed, 11 Oct 2023 14:49:56 +0300 Subject: [PATCH 07/32] Changed navigation and added SingleItemScreen --- .../com/example/mycloset/Views/HomeScreen.kt | 62 ++++--- .../mycloset/Views/SingleItemScreen.kt | 152 ++++++++++-------- 2 files changed, 131 insertions(+), 83 deletions(-) diff --git a/app/src/main/java/com/example/mycloset/Views/HomeScreen.kt b/app/src/main/java/com/example/mycloset/Views/HomeScreen.kt index ce4d5d8..09b8cbb 100644 --- a/app/src/main/java/com/example/mycloset/Views/HomeScreen.kt +++ b/app/src/main/java/com/example/mycloset/Views/HomeScreen.kt @@ -3,14 +3,18 @@ package com.example.mycloset.Views import androidx.compose.foundation.ExperimentalFoundationApi +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.grid.GridCells import androidx.compose.foundation.lazy.grid.LazyVerticalGrid import androidx.compose.material.* import androidx.compose.material.icons.Icons import androidx.compose.material.icons.filled.Camera +import androidx.compose.material.icons.filled.Logout import androidx.compose.material3.ExperimentalMaterial3Api import androidx.compose.material3.Icon import androidx.compose.material3.IconButton @@ -23,8 +27,12 @@ import androidx.compose.ui.Modifier import androidx.compose.ui.text.style.TextAlign import androidx.compose.ui.tooling.preview.Preview import androidx.compose.ui.unit.dp +import androidx.lifecycle.viewmodel.compose.viewModel import androidx.navigation.NavController import androidx.navigation.compose.rememberNavController +import com.example.mycloset.data.SignupViewModel +import com.example.mycloset.navigation.Screen + //import com.example.mycloset.Screen @@ -64,28 +72,42 @@ fun EmptyHomeScreen() { } } - @OptIn(ExperimentalMaterial3Api::class) @Composable -fun HomeScreen(navController: NavController) { - Scaffold(topBar = { - TopAppBar( -// colors = topAppBarColors( -// containerColor = MaterialTheme.colorScheme.primaryContainer, -// titleContentColor = MaterialTheme.colorScheme.primary, -// ), - title = { - Text("MyCloset", modifier = Modifier.padding(2.dp)) - }, actions = { - IconButton( - onClick = { /* Navigate to the scanner screen - navController.navigate(route = Screen.Camera.route)*/} - ) { - Icon(Icons.Default.Camera, contentDescription = null) + +fun HomeScreen() { + var viewModel: SignupViewModel = viewModel() + Scaffold( + topBar = { + TopAppBar( + title = { + Text( + text = "MyCloset", + modifier = Modifier.fillMaxWidth(), + textAlign = TextAlign.Center + ) + }, + actions = { + IconButton( + onClick = { + + } + ) { + Icon(Icons.Default.Logout, contentDescription = "Logout") + } + }, + navigationIcon = { + IconButton( + onClick = { + viewModel.logout() + } + ) { + Icon(Icons.Default.Camera, contentDescription = "Camera") + } } - } - ) - }) { padding -> + ) + } + ) { padding -> LazyVerticalGrid( columns = GridCells.Fixed(2), modifier = Modifier .fillMaxSize() @@ -102,7 +124,7 @@ fun HomeScreen(navController: NavController) { @Composable fun PrevHome() { HomeScreen( - navController = rememberNavController() + ) } diff --git a/app/src/main/java/com/example/mycloset/Views/SingleItemScreen.kt b/app/src/main/java/com/example/mycloset/Views/SingleItemScreen.kt index a6c2d6e..fa3d26c 100644 --- a/app/src/main/java/com/example/mycloset/Views/SingleItemScreen.kt +++ b/app/src/main/java/com/example/mycloset/Views/SingleItemScreen.kt @@ -1,5 +1,6 @@ package com.example.mycloset.Views +import androidx.compose.foundation.Image import androidx.compose.foundation.layout.Arrangement import androidx.compose.foundation.layout.Column import androidx.compose.foundation.layout.PaddingValues @@ -10,95 +11,120 @@ import androidx.compose.foundation.layout.fillMaxWidth import androidx.compose.foundation.layout.height import androidx.compose.foundation.layout.padding import androidx.compose.foundation.lazy.LazyColumn +import androidx.compose.material.icons.Icons +import androidx.compose.material.icons.filled.ArrowBack +import androidx.compose.material.icons.filled.Camera +import androidx.compose.material.icons.filled.Logout import androidx.compose.material3.Button import androidx.compose.material3.Divider +import androidx.compose.material3.ExperimentalMaterial3Api +import androidx.compose.material3.Icon +import androidx.compose.material3.IconButton +import androidx.compose.material3.Scaffold import androidx.compose.material3.Text +import androidx.compose.material3.TopAppBar import androidx.compose.runtime.Composable import androidx.compose.runtime.getValue import androidx.compose.runtime.mutableStateOf import androidx.compose.runtime.remember import androidx.compose.runtime.rememberUpdatedState import androidx.compose.runtime.setValue +import androidx.compose.ui.Alignment import androidx.compose.ui.Modifier +import androidx.compose.ui.graphics.painter.Painter +import androidx.compose.ui.res.painterResource import androidx.compose.ui.text.font.FontWeight +import androidx.compose.ui.tooling.preview.Preview import androidx.compose.ui.unit.dp +import androidx.lifecycle.viewmodel.compose.viewModel import com.example.mycloset.ImgDisplay.Companion.DisplayPicture import com.example.mycloset.ProductViewModel +import com.example.mycloset.R +import com.example.mycloset.data.SignupViewModel +@OptIn(ExperimentalMaterial3Api::class, ExperimentalMaterial3Api::class) @Composable -fun SingleItemScreen(productViewModel: ProductViewModel) { - val informationProductMap by rememberUpdatedState(newValue = productViewModel.informationProductMap) - var showProductInfo by remember { mutableStateOf(false) } +fun SingleItemScreen() { + var viewModel: SignupViewModel = viewModel() + val imagePainter: Painter = painterResource(id = R.drawable.airfocrce) - Column( - modifier = Modifier - .fillMaxSize() - .padding(16.dp) - ) { - Button(onClick = { - productViewModel.getInfo() - showProductInfo = true - }) - { - Text("Fetch Product Info") + Scaffold( + topBar = { + // TopAppBar (the top bar) + TopAppBar( + navigationIcon = { + IconButton(onClick = { }) { + Icon( + Icons.Default.ArrowBack, + contentDescription = "Back" + ) + } + }, + title = { + Text("MyCloset") + }, + actions = { + IconButton(onClick = { /* Handle camera navigation here */ }) { + Icon( + Icons.Default.Camera, + contentDescription = "Camera" + ) + } + IconButton( + onClick = { + viewModel.logout() + } + ) { + Icon(Icons.Default.Logout, contentDescription = "Logout") + } + } + ) } - Spacer(modifier = Modifier.height(16.dp)) - Divider(modifier = Modifier.padding(vertical = 20.dp)) + ) { padding -> + // Content to be displayed below the top bar + Column( + modifier = Modifier + .fillMaxSize() + .padding(16.dp) + ) { + // Add an Image + Image( + painter = imagePainter, + contentDescription = "Your Image", + modifier = Modifier + .fillMaxWidth() + .height(200.dp) // Adjust the height as needed + ) - if (showProductInfo) { - if (informationProductMap.isNotEmpty()) { - Column { + Spacer(modifier = Modifier.height(24.dp)) - //Title - val title: String = informationProductMap["title"].toString() - Text( - text = title, - modifier = Modifier.padding(16.dp) - ) + // Add text components or any other content + Text("Brand: Nike", modifier = Modifier.align(Alignment.CenterHorizontally)) + Text("Size: 40", modifier = Modifier.align(Alignment.CenterHorizontally)) - //Image - DisplayPicture(informationProductMap["images"].toString()) - - //Table - LazyColumn( - modifier = Modifier.fillMaxWidth(), - contentPadding = PaddingValues(16.dp) - ) { - informationProductMap.forEach { (key, value) -> - if (key != "title" && key != "images") { - item { - Row( - modifier = Modifier.fillMaxWidth(), - horizontalArrangement = Arrangement.SpaceBetween - ) { - Text(text = key, fontWeight = FontWeight.Bold) - Text(text = value.toString()) - } - Spacer(modifier = Modifier.height(8.dp)) - } - } - } - } - - //Button - Row { - Button(onClick = { /*TODO*/ }) { - Text(text = "Cancel") - } - Button(onClick = { /*TODO*/ }) { - Text(text = "Add") - } + Spacer(modifier = Modifier.height(16.dp)) + // Add more text components or other content as needed + Row( + modifier = Modifier + .fillMaxWidth() + .padding(16.dp), + horizontalArrangement = Arrangement.Center + ) { + Button( + onClick = { + // Handle the delete action here } + ) { + Text("Delete Item") } } } } - } -//@Preview -//@Composable -//fun Info() { -// SingleItemScreen() -//} \ No newline at end of file +@Composable +@Preview +fun SingleItemView(){ + SingleItemScreen() +} \ No newline at end of file From 53848663a6a4299f08e9a15b6c5b969c601c156b Mon Sep 17 00:00:00 2001 From: Liideli Date: Wed, 11 Oct 2023 17:32:30 +0300 Subject: [PATCH 08/32] Navigation fixed, modified CameraScanViewModel initializing, some styling fixes. Product ADDING and GETTING working now with user email. --- .../example/mycloset/App/LoginPreviewApp.kt | 34 ++- .../example/mycloset/AppViewModelProvider.kt | 4 + .../BarcodeWorkingSet/BarcodeRepository.kt | 2 +- .../DatabaseWorkingset/ProductDatabase.kt | 2 +- .../DatabaseWorkingset/ProductRepository.kt | 2 +- .../DatabaseWorkingset/ProductViewModel.kt | 4 +- .../LoginWorkingSet/Login/LoginViewModel.kt | 4 + .../java/com/example/mycloset/MainActivity.kt | 139 +-------- .../com/example/mycloset/Views/HomeScreen.kt | 79 +++-- .../example/mycloset/Views/ProductScanView.kt | 289 +++++++++++------- .../com/example/mycloset/navigation/Screen.kt | 1 + 11 files changed, 261 insertions(+), 299 deletions(-) diff --git a/app/src/main/java/com/example/mycloset/App/LoginPreviewApp.kt b/app/src/main/java/com/example/mycloset/App/LoginPreviewApp.kt index edaec43..5f35bb2 100644 --- a/app/src/main/java/com/example/mycloset/App/LoginPreviewApp.kt +++ b/app/src/main/java/com/example/mycloset/App/LoginPreviewApp.kt @@ -1,22 +1,34 @@ package com.example.mycloset.App +import androidx.camera.view.LifecycleCameraController import androidx.compose.animation.Crossfade import androidx.compose.foundation.layout.fillMaxSize import androidx.compose.material3.Surface import androidx.compose.runtime.Composable import androidx.compose.ui.Modifier import androidx.compose.ui.graphics.Color +import androidx.lifecycle.viewmodel.compose.viewModel +import com.example.mycloset.AppViewModelProvider +import com.example.mycloset.BarcodeWorkingSet.CameraScanViewModel +import com.example.mycloset.DatabaseWorkingset.ProductViewModel +import com.example.mycloset.Views.HomeScreen import com.example.mycloset.Views.LoginScreen +import com.example.mycloset.Views.ProductScanView import com.example.mycloset.Views.SignUpScreen import com.example.mycloset.navigation.LoginAppRouter import com.example.mycloset.navigation.Screen + @Composable -fun LoginApp(){ +fun LoginApp(cameraController: LifecycleCameraController){ + val productViewModel: ProductViewModel = viewModel(factory = AppViewModelProvider.Factory) + // ViewModel for handling camera and barcode scanning logic + val viewModel: CameraScanViewModel = viewModel(factory = AppViewModelProvider.Factory) + Surface(modifier = Modifier.fillMaxSize(), color = Color.White ) { - Crossfade(targetState = LoginAppRouter.currentScreen) { currentState -> + Crossfade(targetState = LoginAppRouter.currentScreen, label = "") { currentState -> when(currentState.value){ is Screen.SignupScreen ->{ SignUpScreen() @@ -25,10 +37,24 @@ fun LoginApp(){ LoginScreen() } is Screen.HomeScreen ->{ - //HomeScreen() + HomeScreen(productViewModel) + } + is Screen.ProductScanView ->{ + ProductScanView( + productViewModel, + barcodesFlow = viewModel.barcodesFlow, + cameraController, + torchEnabledFlow = viewModel.torchFlow, + onTorchButtonClicked = { + // Toggle torch status when the button is clicked + cameraController.enableTorch(!viewModel.torchFlow.value) + viewModel.updateTorchEnabled() + } + ) } } } } -} \ No newline at end of file +} + diff --git a/app/src/main/java/com/example/mycloset/AppViewModelProvider.kt b/app/src/main/java/com/example/mycloset/AppViewModelProvider.kt index 75891d5..9220821 100644 --- a/app/src/main/java/com/example/mycloset/AppViewModelProvider.kt +++ b/app/src/main/java/com/example/mycloset/AppViewModelProvider.kt @@ -5,6 +5,7 @@ import androidx.lifecycle.ViewModelProvider.AndroidViewModelFactory import androidx.lifecycle.viewmodel.CreationExtras import androidx.lifecycle.viewmodel.initializer import androidx.lifecycle.viewmodel.viewModelFactory +import com.example.mycloset.BarcodeWorkingSet.CameraScanViewModel import com.example.mycloset.DatabaseWorkingset.ProductViewModel /** @@ -18,6 +19,9 @@ object AppViewModelProvider { productRepository = MyApplication().container.productRepository ) } + addInitializer(CameraScanViewModel::class) { + CameraScanViewModel() + } } } diff --git a/app/src/main/java/com/example/mycloset/BarcodeWorkingSet/BarcodeRepository.kt b/app/src/main/java/com/example/mycloset/BarcodeWorkingSet/BarcodeRepository.kt index 795b544..6f4ed13 100644 --- a/app/src/main/java/com/example/mycloset/BarcodeWorkingSet/BarcodeRepository.kt +++ b/app/src/main/java/com/example/mycloset/BarcodeWorkingSet/BarcodeRepository.kt @@ -3,7 +3,7 @@ package com.example.mycloset.BarcodeWorkingSet import com.example.mycloset.ApiWorkingSet.RetrofitObject // -var APY_KEY:String="5gk0yh025ap4ft1figtfganr7b7g2o" +var APY_KEY:String="yblmhszzc78rg1mggfylbnsqudb6uf" //class for using the barcode-lookup API class BarcodeRepository{ diff --git a/app/src/main/java/com/example/mycloset/DatabaseWorkingset/ProductDatabase.kt b/app/src/main/java/com/example/mycloset/DatabaseWorkingset/ProductDatabase.kt index bc6bdd6..5146378 100644 --- a/app/src/main/java/com/example/mycloset/DatabaseWorkingset/ProductDatabase.kt +++ b/app/src/main/java/com/example/mycloset/DatabaseWorkingset/ProductDatabase.kt @@ -6,7 +6,7 @@ import androidx.room.Room import androidx.room.RoomDatabase -@Database(entities = [ProductEntity::class], version = 1, exportSchema = false) +@Database(entities = [ProductEntity::class], version = 2, exportSchema = false) abstract class ProductDatabase : RoomDatabase() { abstract fun productDao(): ProductDao diff --git a/app/src/main/java/com/example/mycloset/DatabaseWorkingset/ProductRepository.kt b/app/src/main/java/com/example/mycloset/DatabaseWorkingset/ProductRepository.kt index 158d7d2..83de98b 100644 --- a/app/src/main/java/com/example/mycloset/DatabaseWorkingset/ProductRepository.kt +++ b/app/src/main/java/com/example/mycloset/DatabaseWorkingset/ProductRepository.kt @@ -6,5 +6,5 @@ import kotlinx.coroutines.flow.Flow interface ProductRepository { fun getAllProductsStream(): Flow> - fun getAllProductsWithEmailStream(userEmail: String): Flow> + fun getAllProductsWithEmailStream(userEmail: String): Flow?> } \ No newline at end of file diff --git a/app/src/main/java/com/example/mycloset/DatabaseWorkingset/ProductViewModel.kt b/app/src/main/java/com/example/mycloset/DatabaseWorkingset/ProductViewModel.kt index 9a19ad8..d7ed61a 100644 --- a/app/src/main/java/com/example/mycloset/DatabaseWorkingset/ProductViewModel.kt +++ b/app/src/main/java/com/example/mycloset/DatabaseWorkingset/ProductViewModel.kt @@ -51,7 +51,9 @@ class ProductViewModel(val productDao: ProductDao, val productRepository: Produc fun getProductsWithEmail(userEmail: String) { viewModelScope.launch { productRepository.getAllProductsWithEmailStream(userEmail).collect() { response -> - products = response + if (response != null) { + products = response + } } } } diff --git a/app/src/main/java/com/example/mycloset/LoginWorkingSet/Login/LoginViewModel.kt b/app/src/main/java/com/example/mycloset/LoginWorkingSet/Login/LoginViewModel.kt index 14a59ec..e84baf0 100644 --- a/app/src/main/java/com/example/mycloset/LoginWorkingSet/Login/LoginViewModel.kt +++ b/app/src/main/java/com/example/mycloset/LoginWorkingSet/Login/LoginViewModel.kt @@ -1,5 +1,6 @@ package com.example.mycloset.LoginWorkingSet.Login +import android.util.Log import androidx.compose.runtime.mutableStateOf import androidx.lifecycle.ViewModel import com.example.mycloset.LoginWorkingSet.LoggedUser @@ -46,13 +47,16 @@ class LoginViewModel: ViewModel() { if (it.isSuccessful){ //if the login work, i set the object that contain the email(i need it for view, add, delete the product from a specific user) LoggedUser.loggedUserEmail =loginUiState.value.email + Log.i("EMAIL", loginUiState.value.email) loginInProgress.value = false LoginAppRouter.navigateTo(Screen.HomeScreen) + Log.i("SUCCESS", "Login success") } } .addOnFailureListener{ loginInProgress.value = false + Log.i("FAIL", "Login failed") } } private fun validateLoginUIDataWithRules(){ diff --git a/app/src/main/java/com/example/mycloset/MainActivity.kt b/app/src/main/java/com/example/mycloset/MainActivity.kt index 1d3e068..4d9edd9 100644 --- a/app/src/main/java/com/example/mycloset/MainActivity.kt +++ b/app/src/main/java/com/example/mycloset/MainActivity.kt @@ -11,12 +11,10 @@ import androidx.camera.view.CameraController.COORDINATE_SYSTEM_VIEW_REFERENCED import androidx.camera.view.LifecycleCameraController import androidx.core.app.ActivityCompat import androidx.core.content.ContextCompat -import androidx.lifecycle.viewmodel.compose.viewModel import androidx.navigation.NavHostController import androidx.navigation.compose.rememberNavController +import com.example.mycloset.App.LoginApp import com.example.mycloset.BarcodeWorkingSet.CameraScanViewModel -import com.example.mycloset.DatabaseWorkingset.ProductViewModel -import com.example.mycloset.Views.ProductScanView import com.example.mycloset.ui.theme.AppTheme import com.google.mlkit.vision.barcode.BarcodeScannerOptions import com.google.mlkit.vision.barcode.BarcodeScanning @@ -25,7 +23,7 @@ import com.google.mlkit.vision.barcode.common.Barcode class MainActivity : ComponentActivity() { - lateinit var navController: NavHostController + private lateinit var navController: NavHostController //val navController = rememberNavController() // ViewModel for handling camera and barcode scanning logic @@ -40,41 +38,12 @@ class MainActivity : ComponentActivity() { // Build a camera controller for handling camera operations val cameraController = buildCameraController() - // Set the content of the activity to be a CameraView + // Set the content of the activity to be the App setContent { AppTheme { // Add Navigation navController = rememberNavController() -// SetupNavGraph(navController = navController) - val productViewModel: ProductViewModel = viewModel(factory = AppViewModelProvider.Factory) - //HomeScreen(navController = navController, viewModel = productViewModel) - //LoginScreen() - ProductScanView( - productViewModel, - barcodesFlow = viewModel.barcodesFlow, - cameraController, - torchEnabledFlow = viewModel.torchFlow, - onTorchButtonClicked = { - // Toggle torch status when the button is clicked - cameraController.enableTorch(!viewModel.torchFlow.value) - viewModel.updateTorchEnabled() - } - ) - /*CameraView( - cameraController = cameraController, - //MainScreen() - val productViewModel: ProductViewModel = viewModel(factory = AppViewModelProvider.Factory) - ProductScanView( - productViewModel, - barcodesFlow = viewModel.barcodesFlow, - cameraController, - torchEnabledFlow = viewModel.torchFlow, - onTorchButtonClicked = { - // Toggle torch status when the button is clicked - cameraController.enableTorch(!viewModel.torchFlow.value) - viewModel.updateTorchEnabled() - } - )*/ + LoginApp(cameraController = cameraController) } } } else { @@ -145,102 +114,4 @@ class MainActivity : ComponentActivity() { } } } -} - -// Product Info Screen Composable -/* -@Composable -fun ProductInfoScreen(productViewModel: ProductViewModel) { - val informationProductMap by rememberUpdatedState(newValue = productViewModel.informationProductMap) - var showProductInfo by remember { mutableStateOf(false) } - - Column( - modifier = Modifier - .fillMaxSize() - .padding(16.dp) - ) { - Button(onClick = { - productViewModel.getInfo() - showProductInfo = true - }) - { - Text("Fetch Product Info") - } - Spacer(modifier = Modifier.height(16.dp)) - Divider(modifier = Modifier.padding(vertical = 20.dp)) - - if (showProductInfo) { - if (informationProductMap.isNotEmpty()) { - Column { - - //Title - val title: String = informationProductMap["title"].toString() - Text( - text = title, - modifier = Modifier.padding(16.dp) - ) - - //Image - DisplayPicture(informationProductMap["images"].toString()) - - //Table - LazyColumn( - modifier = Modifier.fillMaxWidth(), - contentPadding = PaddingValues(16.dp) - ) { - informationProductMap.forEach { (key, value) -> - if (key != "title" && key != "images") { - item { - Row( - modifier = Modifier.fillMaxWidth(), - horizontalArrangement = Arrangement.SpaceBetween - ) { - Text(text = key, fontWeight = FontWeight.Bold) - Text(text = value.toString()) - } - Spacer(modifier = Modifier.height(8.dp)) - } - } - } - } - - //Button - Row { - Button(onClick = { /*TODO*/ }) { - Text(text = "Cancel") - } - Button(onClick = { /*TODO*/ }) { - Text(text = "Add") - } - - } - } - } - } - } -}*/ - -//@Composable -//fun MyNavHost(navController: NavHostController) { -// NavHost( -// navController = navController, -// startDestination = "home" -// ) { -// composable("HomeScreen") { -// HomeScreen(viewModel.items) -// } -// composable("scanner") { -// // Your scanner screen -// } -// // Add more destinations as needed -// } -//} -// -//val navController = rememberNavController() -// -//// ... -// -//setContent { -// MyNavHost(navController) -//} - +} \ No newline at end of file diff --git a/app/src/main/java/com/example/mycloset/Views/HomeScreen.kt b/app/src/main/java/com/example/mycloset/Views/HomeScreen.kt index 744a550..7db805b 100644 --- a/app/src/main/java/com/example/mycloset/Views/HomeScreen.kt +++ b/app/src/main/java/com/example/mycloset/Views/HomeScreen.kt @@ -1,6 +1,7 @@ package com.example.mycloset.Views +import android.util.Log import androidx.compose.foundation.layout.Box import androidx.compose.foundation.layout.fillMaxSize import androidx.compose.foundation.layout.padding @@ -20,59 +21,56 @@ import androidx.compose.ui.Alignment import androidx.compose.ui.Modifier import androidx.compose.ui.text.style.TextAlign import androidx.compose.ui.unit.dp -import androidx.navigation.NavController import com.example.mycloset.DatabaseWorkingset.ProductViewModel import com.example.mycloset.LoginWorkingSet.LoggedUser +import com.example.mycloset.navigation.LoginAppRouter +import com.example.mycloset.navigation.Screen import kotlinx.coroutines.flow.* //import com.example.mycloset.Screen - -// @OptIn(ExperimentalMaterial3Api::class) @Composable -fun EmptyHomeScreen() { - Scaffold( - topBar = { - TopAppBar( +fun HomeScreen(viewModel: ProductViewModel) { + // Observe the products list from the ViewModel + //viewModel.getProducts() + viewModel.getProductsWithEmail(LoggedUser.loggedUserEmail) + val products = viewModel.products + Log.i("PROD", products.toString()) + if (products.isEmpty()) { + Scaffold( + topBar = { + TopAppBar( // colors = topAppBarColors( // containerColor = MaterialTheme.colorScheme.primaryContainer, // titleContentColor = MaterialTheme.colorScheme.primary, // ), - title = { - Text("MyCloset") - }, actions = { - IconButton( - onClick = { /* Navigate to the scanner screen */ } - ) { - Icon(Icons.Default.Camera, contentDescription = null) + title = { + Text("MyCloset") + }, actions = { + IconButton( + onClick = { LoginAppRouter.navigateTo(Screen.ProductScanView) } + ) { + Icon(Icons.Default.Camera, contentDescription = null) + } } - } - ) - }) { innerPadding -> - Box( - modifier = Modifier - .fillMaxSize() - .padding(innerPadding), - contentAlignment = Alignment.Center - ) { - Text( - text = "You don't have any items yet...", - textAlign = TextAlign.Center, - ) + ) + }) { innerPadding -> + Box( + modifier = Modifier + .fillMaxSize() + .padding(innerPadding), + contentAlignment = Alignment.Center + ) { + Text( + text = "You don't have any items yet...", + textAlign = TextAlign.Center, + ) + } } - } -} - - -@OptIn(ExperimentalMaterial3Api::class) -@Composable -fun HomeScreen(navController: NavController, viewModel: ProductViewModel) { - // Observe the products list from the ViewModel - viewModel.getProductsWithEmail(LoggedUser.loggedUserEmail) - val products = viewModel.products + } else { Scaffold(topBar = { TopAppBar( // colors = topAppBarColors( @@ -83,17 +81,17 @@ fun HomeScreen(navController: NavController, viewModel: ProductViewModel) { Text("MyCloset", modifier = Modifier.padding(2.dp)) }, actions = { IconButton( - onClick = { /* Navigate to the scanner screen - navController.navigate(route = Screen.Camera.route)*/} + onClick = { LoginAppRouter.navigateTo(Screen.ProductScanView)} ) { Icon(Icons.Default.Camera, contentDescription = null) } } ) - }) { padding -> + }) { innerPadding -> LazyVerticalGrid( columns = GridCells.Fixed(2), modifier = Modifier .fillMaxSize() + .padding(innerPadding) .padding(16.dp) ) { items(products.size) { index -> @@ -102,6 +100,7 @@ fun HomeScreen(navController: NavController, viewModel: ProductViewModel) { } } } + } } /* diff --git a/app/src/main/java/com/example/mycloset/Views/ProductScanView.kt b/app/src/main/java/com/example/mycloset/Views/ProductScanView.kt index 1fd7789..18cc745 100644 --- a/app/src/main/java/com/example/mycloset/Views/ProductScanView.kt +++ b/app/src/main/java/com/example/mycloset/Views/ProductScanView.kt @@ -1,6 +1,5 @@ package com.example.mycloset.Views -import android.util.Log import android.view.ViewGroup import android.widget.LinearLayout import android.widget.Toast @@ -20,16 +19,22 @@ import androidx.compose.foundation.layout.size import androidx.compose.foundation.lazy.LazyColumn import androidx.compose.foundation.shape.RoundedCornerShape import androidx.compose.material.icons.Icons +import androidx.compose.material.icons.filled.Camera import androidx.compose.material.icons.filled.FlashOff import androidx.compose.material.icons.filled.FlashOn +import androidx.compose.material.icons.filled.Home import androidx.compose.material3.Button import androidx.compose.material3.ButtonDefaults import androidx.compose.material3.Card import androidx.compose.material3.CardDefaults import androidx.compose.material3.CircularProgressIndicator +import androidx.compose.material3.ExperimentalMaterial3Api import androidx.compose.material3.Icon +import androidx.compose.material3.IconButton import androidx.compose.material3.MaterialTheme +import androidx.compose.material3.Scaffold import androidx.compose.material3.Text +import androidx.compose.material3.TopAppBar import androidx.compose.runtime.Composable import androidx.compose.runtime.State import androidx.compose.runtime.collectAsState @@ -44,12 +49,15 @@ import androidx.compose.ui.platform.LocalContext import androidx.compose.ui.text.font.FontWeight import androidx.compose.ui.unit.dp import androidx.compose.ui.viewinterop.AndroidView -import com.example.mycloset.BarcodeWorkingSet.BarcodeModel import com.example.mycloset.ApiWorkingSet.ImgDisplay +import com.example.mycloset.BarcodeWorkingSet.BarcodeModel import com.example.mycloset.DatabaseWorkingset.ProductViewModel -import kotlinx.coroutines.flow.StateFlow import com.example.mycloset.LoginWorkingSet.LoggedUser +import com.example.mycloset.navigation.LoginAppRouter +import com.example.mycloset.navigation.Screen +import kotlinx.coroutines.flow.StateFlow +@OptIn(ExperimentalMaterial3Api::class) @Composable fun ProductScanView( // Parameters required for the composable @@ -92,93 +100,112 @@ fun ProductScanView( if (!showProductInfo) { - // AndroidView to display the camera preview - AndroidView(factory = { context -> - PreviewView(context).apply { - layoutParams = LinearLayout.LayoutParams( - ViewGroup.LayoutParams.MATCH_PARENT, - ViewGroup.LayoutParams.MATCH_PARENT - ) - scaleType = PreviewView.ScaleType.FILL_START - implementationMode = PreviewView.ImplementationMode.COMPATIBLE - this.controller = cameraController - } - }) - - // Column to organize UI elements vertically with space between them - Column( - modifier = Modifier - .fillMaxHeight() - .padding(16.dp), - verticalArrangement = Arrangement.Bottom, - horizontalAlignment = Alignment.CenterHorizontally - ) { + Scaffold(topBar = { + TopAppBar( +// colors = topAppBarColors( +// containerColor = MaterialTheme.colorScheme.primaryContainer, +// titleContentColor = MaterialTheme.colorScheme.primary, +// ), + title = { + Text("MyCloset", modifier = Modifier.padding(2.dp)) + }, actions = { + IconButton( + onClick = { LoginAppRouter.navigateTo(Screen.HomeScreen) } + ) { + Icon(Icons.Default.Home, contentDescription = null) + } + } + ) + }) { innerPadding -> + // AndroidView to display the camera preview + AndroidView(factory = { context -> + PreviewView(context).apply { + layoutParams = LinearLayout.LayoutParams( + ViewGroup.LayoutParams.MATCH_PARENT, + ViewGroup.LayoutParams.MATCH_PARENT + ) + scaleType = PreviewView.ScaleType.FILL_START + implementationMode = PreviewView.ImplementationMode.COMPATIBLE + this.controller = cameraController + } + }) + // Column to organize UI elements vertically with space between them Column( modifier = Modifier - .fillMaxHeight(), - verticalArrangement = Arrangement.SpaceBetween, + .fillMaxHeight() + .padding(innerPadding) + .padding(16.dp), + verticalArrangement = Arrangement.Bottom, horizontalAlignment = Alignment.CenterHorizontally ) { - // Card composable to display barcode information - Card( - colors = CardDefaults.cardColors( - containerColor = MaterialTheme.colorScheme.surfaceVariant, - ), - shape = RoundedCornerShape(10.dp) + Column( + modifier = Modifier + .fillMaxHeight(), + verticalArrangement = Arrangement.SpaceBetween, + horizontalAlignment = Alignment.CenterHorizontally ) { - Column( - modifier = Modifier.padding(16.dp) + + // Card composable to display barcode information + Card( + colors = CardDefaults.cardColors( + containerColor = MaterialTheme.colorScheme.surfaceVariant, + ), + shape = RoundedCornerShape(10.dp) ) { - if (barcode.value.barcode.isNotEmpty()) { - Text(text = "Barcode: ${barcode.value.barcode}") - } else { - Text(text = "Point camera at a barcode") + Column( + modifier = Modifier.padding(16.dp) + ) { + if (barcode.value.barcode.isNotEmpty()) { + Text(text = "Barcode: ${barcode.value.barcode}") + } else { + Text(text = "Point camera at a barcode") + } } } - } - // Row for torch button and search button - Row( - modifier = Modifier.fillMaxWidth(), - horizontalArrangement = Arrangement.SpaceBetween - ) { - - // Button to toggle the torch - Button( - onClick = onTorchButtonClicked, - colors = ButtonDefaults.buttonColors( - containerColor = MaterialTheme.colorScheme.primary, - contentColor = MaterialTheme.colorScheme.onPrimary - ) + // Row for torch button and search button + Row( + modifier = Modifier.fillMaxWidth(), + horizontalArrangement = Arrangement.SpaceBetween ) { - if (torchEnabled.value) { - Icon( - imageVector = Icons.Default.FlashOff, - contentDescription = "Flash off icon" - ) - } else { - Icon( - imageVector = Icons.Default.FlashOn, - contentDescription = "Flash on icon" + // Button to toggle the torch + Button( + onClick = onTorchButtonClicked, + colors = ButtonDefaults.buttonColors( + containerColor = MaterialTheme.colorScheme.primary, + contentColor = MaterialTheme.colorScheme.onPrimary ) + ) { + if (torchEnabled.value) { + Icon( + imageVector = Icons.Default.FlashOff, + contentDescription = "Flash off icon" + ) + + } else { + Icon( + imageVector = Icons.Default.FlashOn, + contentDescription = "Flash on icon" + ) + } } - } - // Button to search for product info - Button(onClick = { - if (barcode.value.barcode.isNotEmpty()) { - isLoading = true - networkResult = null - productViewModel.getInfo(barcode.value.barcode) - showProductInfo = true - } else { - Toast.makeText(context, "No barcode found", Toast.LENGTH_SHORT) - .show() + // Button to search for product info + Button(onClick = { + if (barcode.value.barcode.isNotEmpty()) { + isLoading = true + networkResult = null + productViewModel.getInfo(barcode.value.barcode) + showProductInfo = true + } else { + Toast.makeText(context, "No barcode found", Toast.LENGTH_SHORT) + .show() + } + }) { + Text(text = "Search Product Info") } - }) { - Text(text = "Search Product Info") } } } @@ -207,60 +234,88 @@ fun ProductScanView( // Display the product information if there is a successful result if (showProductInfo && informationProductMap.isNotEmpty()) { isLoading = false - Column( - modifier = Modifier - .fillMaxSize() - .padding(16.dp) - ) { - - Text( - text = title, - modifier = Modifier.padding(16.dp) + Scaffold(topBar = { + TopAppBar( +// colors = topAppBarColors( +// containerColor = MaterialTheme.colorScheme.primaryContainer, +// titleContentColor = MaterialTheme.colorScheme.primary, +// ), + title = { + Text("MyCloset", modifier = Modifier.padding(2.dp)) + }, actions = { + IconButton( + onClick = { LoginAppRouter.navigateTo(Screen.ProductScanView) } + ) { + Icon(Icons.Default.Camera, contentDescription = null) + } + } ) + }) { innerPadding -> + Column( + modifier = Modifier + .padding(innerPadding) + .fillMaxSize() + ) { - // Image of the product - ImgDisplay.DisplayPicture(informationProductMap["images"].toString()) + Text( + text = title, + modifier = Modifier.padding(16.dp) + ) - LazyColumn( - modifier = Modifier.fillMaxWidth(), - contentPadding = PaddingValues(16.dp) - ) { - informationProductMap.forEach { (key, value) -> - if (key != "title" && key != "images" && key != "barcodeNumber") { - item { - Row( - modifier = Modifier.fillMaxWidth(), - horizontalArrangement = Arrangement.SpaceBetween - ) { - if (value.isNotEmpty()) { - Text(text = "$key: ", fontWeight = FontWeight.Bold) - Text(text = value) + // Image of the product + ImgDisplay.DisplayPicture(informationProductMap["images"].toString()) + + LazyColumn( + modifier = Modifier.fillMaxWidth(), + contentPadding = PaddingValues(16.dp) + ) { + informationProductMap.forEach { (key, value) -> + if (key != "title" && key != "images" && key != "barcodeNumber") { + item { + Row( + modifier = Modifier.fillMaxWidth(), + horizontalArrangement = Arrangement.SpaceBetween + ) { + if (value.isNotEmpty()) { + Text(text = "$key: ", fontWeight = FontWeight.Bold) + Text(text = value) + } } + Spacer(modifier = Modifier.height(8.dp)) } - Spacer(modifier = Modifier.height(8.dp)) } } } - } - // Buttons for cancel and add actions - Row( - modifier = Modifier.fillMaxWidth(), - horizontalArrangement = Arrangement.SpaceBetween - ) { - Button(onClick = { - showProductInfo = false - }) { - Text(text = "Back") - } - if(LoggedUser.loggedUserEmail!=""){ - Button(onClick = { productViewModel.saveToDatabase(barcodeNumber, LoggedUser.loggedUserEmail, model, title, category, brand, color, material, size, images) + // Buttons for cancel and add actions + Row( + modifier = Modifier.fillMaxWidth(), + horizontalArrangement = Arrangement.SpaceBetween + ) { + Button(onClick = { + showProductInfo = false + }) { + Text(text = "Back") + } + Button(onClick = { + productViewModel.saveToDatabase( + barcodeNumber, + LoggedUser.loggedUserEmail, + model, + title, + category, + brand, + color, + material, + size, + images + ) Toast.makeText(context, "Item added!", Toast.LENGTH_SHORT) - .show()}) { + .show() + }) { Text(text = "Add") - } - }else{ - Log.i("LOGIN_ERROR","You can't add a new item to your wardrobe because you aren't logged") + } + } } } diff --git a/app/src/main/java/com/example/mycloset/navigation/Screen.kt b/app/src/main/java/com/example/mycloset/navigation/Screen.kt index cb12dac..21c19ef 100644 --- a/app/src/main/java/com/example/mycloset/navigation/Screen.kt +++ b/app/src/main/java/com/example/mycloset/navigation/Screen.kt @@ -7,6 +7,7 @@ sealed class Screen(){ object SignupScreen: Screen() object LoginScreen: Screen() object HomeScreen : Screen() + object ProductScanView : Screen() } object LoginAppRouter{ From 17a41e18fec81452b9cf903e4eecc50ab98d7f4a Mon Sep 17 00:00:00 2001 From: Liideli Date: Wed, 11 Oct 2023 17:43:21 +0300 Subject: [PATCH 09/32] Merge latest updates on branch singleItemScreen. --- .../mycloset/DatabaseWorkingset/OfflineProductRepository.kt | 6 ++++-- .../mycloset/DatabaseWorkingset/ProductRepository.kt | 4 ++-- .../main/java/com/example/mycloset/Views/ProductScanView.kt | 2 +- 3 files changed, 7 insertions(+), 5 deletions(-) diff --git a/app/src/main/java/com/example/mycloset/DatabaseWorkingset/OfflineProductRepository.kt b/app/src/main/java/com/example/mycloset/DatabaseWorkingset/OfflineProductRepository.kt index cd30359..aa2cc2a 100644 --- a/app/src/main/java/com/example/mycloset/DatabaseWorkingset/OfflineProductRepository.kt +++ b/app/src/main/java/com/example/mycloset/DatabaseWorkingset/OfflineProductRepository.kt @@ -1,8 +1,10 @@ package com.example.mycloset.DatabaseWorkingset -/*class OfflineProductRepository(private val productDao: ProductDao) : ProductRepository { +class OfflineProductRepository(private val productDao: ProductDao) : ProductRepository { override fun getAllProductsStream() = productDao.getAllProducts() override fun getAllProductsWithEmailStream(userEmail: String) = productDao.getProductsWithEmail(userEmail) + override suspend fun updateProductDetailsStream(product: ProductEntity) = productDao.updateProductDetails(product) + override suspend fun deleteProductStream(product: ProductEntity) = productDao.deleteProduct(product) -}*/ \ No newline at end of file +} \ No newline at end of file diff --git a/app/src/main/java/com/example/mycloset/DatabaseWorkingset/ProductRepository.kt b/app/src/main/java/com/example/mycloset/DatabaseWorkingset/ProductRepository.kt index d6a74eb..b54ebef 100644 --- a/app/src/main/java/com/example/mycloset/DatabaseWorkingset/ProductRepository.kt +++ b/app/src/main/java/com/example/mycloset/DatabaseWorkingset/ProductRepository.kt @@ -6,7 +6,7 @@ import kotlinx.coroutines.flow.Flow interface ProductRepository { fun getAllProductsStream(): Flow> fun getAllProductsWithEmailStream(userEmail: String): Flow?> - fun updateProductDetailsStream(product: ProductEntity) - fun deleteProductStream(product: ProductEntity) + suspend fun updateProductDetailsStream(product: ProductEntity) + suspend fun deleteProductStream(product: ProductEntity) } \ No newline at end of file diff --git a/app/src/main/java/com/example/mycloset/Views/ProductScanView.kt b/app/src/main/java/com/example/mycloset/Views/ProductScanView.kt index 18cc745..61e3c00 100644 --- a/app/src/main/java/com/example/mycloset/Views/ProductScanView.kt +++ b/app/src/main/java/com/example/mycloset/Views/ProductScanView.kt @@ -244,7 +244,7 @@ fun ProductScanView( Text("MyCloset", modifier = Modifier.padding(2.dp)) }, actions = { IconButton( - onClick = { LoginAppRouter.navigateTo(Screen.ProductScanView) } + onClick = { showProductInfo = false } ) { Icon(Icons.Default.Camera, contentDescription = null) } From feeb04b5b8a9317b8f0ac7ec5d7900215ea96247 Mon Sep 17 00:00:00 2001 From: matti Date: Thu, 12 Oct 2023 09:35:16 +0200 Subject: [PATCH 10/32] Update and delate are now in the DAO, viewmodel and repository (Database), The Offline Product repository is commented --- .idea/deploymentTargetDropDown.xml | 28 ---------------------------- 1 file changed, 28 deletions(-) delete mode 100644 .idea/deploymentTargetDropDown.xml diff --git a/.idea/deploymentTargetDropDown.xml b/.idea/deploymentTargetDropDown.xml deleted file mode 100644 index 35c0538..0000000 --- a/.idea/deploymentTargetDropDown.xml +++ /dev/null @@ -1,28 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - \ No newline at end of file From 47269a9d359256e899ac6f307fecaa28c4f40688 Mon Sep 17 00:00:00 2001 From: matti Date: Thu, 12 Oct 2023 09:35:47 +0200 Subject: [PATCH 11/32] Update and delate are now in the DAO, viewmodel and repository (Database), The Offline Product repository is commented --- .../example/mycloset/App/LoginPreviewApp.kt | 5 +- .../BarcodeWorkingSet/BarcodeRepository.kt | 2 +- .../OfflineProductRepository.kt | 7 +- .../DatabaseWorkingset/ProductRepository.kt | 4 +- .../DatabaseWorkingset/ProductViewModel.kt | 62 ++++++------ .../mycloset/LoginWorkingSet/LoggedUser.kt | 2 +- .../java/com/example/mycloset/MainActivity.kt | 83 ++-------------- .../com/example/mycloset/Views/HomeScreen.kt | 6 +- .../example/mycloset/Views/ProductScanView.kt | 90 +++++++++++------- .../mycloset/Views/SingleItemScreen.kt | 94 +++++++++++++++---- 10 files changed, 184 insertions(+), 171 deletions(-) diff --git a/app/src/main/java/com/example/mycloset/App/LoginPreviewApp.kt b/app/src/main/java/com/example/mycloset/App/LoginPreviewApp.kt index edaec43..f3cbe2d 100644 --- a/app/src/main/java/com/example/mycloset/App/LoginPreviewApp.kt +++ b/app/src/main/java/com/example/mycloset/App/LoginPreviewApp.kt @@ -6,6 +6,7 @@ import androidx.compose.material3.Surface import androidx.compose.runtime.Composable import androidx.compose.ui.Modifier import androidx.compose.ui.graphics.Color +import com.example.mycloset.Views.HomeScreenView import com.example.mycloset.Views.LoginScreen import com.example.mycloset.Views.SignUpScreen import com.example.mycloset.navigation.LoginAppRouter @@ -16,7 +17,7 @@ fun LoginApp(){ Surface(modifier = Modifier.fillMaxSize(), color = Color.White ) { - Crossfade(targetState = LoginAppRouter.currentScreen) { currentState -> + Crossfade(targetState = LoginAppRouter.currentScreen, label = "") { currentState -> when(currentState.value){ is Screen.SignupScreen ->{ SignUpScreen() @@ -25,7 +26,7 @@ fun LoginApp(){ LoginScreen() } is Screen.HomeScreen ->{ - //HomeScreen() + HomeScreenView() } } diff --git a/app/src/main/java/com/example/mycloset/BarcodeWorkingSet/BarcodeRepository.kt b/app/src/main/java/com/example/mycloset/BarcodeWorkingSet/BarcodeRepository.kt index 795b544..1ae0ccd 100644 --- a/app/src/main/java/com/example/mycloset/BarcodeWorkingSet/BarcodeRepository.kt +++ b/app/src/main/java/com/example/mycloset/BarcodeWorkingSet/BarcodeRepository.kt @@ -3,7 +3,7 @@ package com.example.mycloset.BarcodeWorkingSet import com.example.mycloset.ApiWorkingSet.RetrofitObject // -var APY_KEY:String="5gk0yh025ap4ft1figtfganr7b7g2o" +var APY_KEY:String="dl8mxnhxbvfg5zxt7gh9h3ndw31jx5" //class for using the barcode-lookup API class BarcodeRepository{ diff --git a/app/src/main/java/com/example/mycloset/DatabaseWorkingset/OfflineProductRepository.kt b/app/src/main/java/com/example/mycloset/DatabaseWorkingset/OfflineProductRepository.kt index cd30359..6251878 100644 --- a/app/src/main/java/com/example/mycloset/DatabaseWorkingset/OfflineProductRepository.kt +++ b/app/src/main/java/com/example/mycloset/DatabaseWorkingset/OfflineProductRepository.kt @@ -1,8 +1,11 @@ package com.example.mycloset.DatabaseWorkingset -/*class OfflineProductRepository(private val productDao: ProductDao) : ProductRepository { +class OfflineProductRepository(private val productDao: ProductDao) : ProductRepository { override fun getAllProductsStream() = productDao.getAllProducts() override fun getAllProductsWithEmailStream(userEmail: String) = productDao.getProductsWithEmail(userEmail) + override suspend fun updateProductDetailsStream(product: ProductEntity) =productDao.updateProductDetails(product) -}*/ \ No newline at end of file + override suspend fun deleteProductStream(product: ProductEntity) =productDao.deleteProduct(product) + +} \ No newline at end of file diff --git a/app/src/main/java/com/example/mycloset/DatabaseWorkingset/ProductRepository.kt b/app/src/main/java/com/example/mycloset/DatabaseWorkingset/ProductRepository.kt index 97987fc..d9199e2 100644 --- a/app/src/main/java/com/example/mycloset/DatabaseWorkingset/ProductRepository.kt +++ b/app/src/main/java/com/example/mycloset/DatabaseWorkingset/ProductRepository.kt @@ -6,6 +6,6 @@ import kotlinx.coroutines.flow.Flow interface ProductRepository { fun getAllProductsStream(): Flow> fun getAllProductsWithEmailStream(userEmail: String): Flow> - fun updateProductDetailsStream(product: ProductEntity) - fun deleteProductStream(product: ProductEntity) + suspend fun updateProductDetailsStream(product: ProductEntity) + suspend fun deleteProductStream(product: ProductEntity) } \ No newline at end of file diff --git a/app/src/main/java/com/example/mycloset/DatabaseWorkingset/ProductViewModel.kt b/app/src/main/java/com/example/mycloset/DatabaseWorkingset/ProductViewModel.kt index e202eb1..272ad6f 100644 --- a/app/src/main/java/com/example/mycloset/DatabaseWorkingset/ProductViewModel.kt +++ b/app/src/main/java/com/example/mycloset/DatabaseWorkingset/ProductViewModel.kt @@ -9,6 +9,7 @@ import androidx.lifecycle.ViewModel import androidx.lifecycle.viewModelScope import com.example.mycloset.ApiWorkingSet.RetrofitObject import com.example.mycloset.BarcodeWorkingSet.BarcodeRepository +import com.example.mycloset.LoginWorkingSet.LoggedUser import kotlinx.coroutines.Dispatchers import kotlinx.coroutines.launch @@ -16,23 +17,14 @@ import kotlinx.coroutines.launch class ProductViewModel(val productDao: ProductDao, val productRepository: ProductRepository) : ViewModel() { private val repository: BarcodeRepository = BarcodeRepository() - var informationProductMap by mutableStateOf(emptyMap()) + var informationProductObject by mutableStateOf(ProductObject("","","","","", "", "","","","")) var products by mutableStateOf(emptyList()) fun saveToDatabase( - barcodeNumber: String, - userEmail: String, - model: String, - title: String, - category: String, - brand: String, - color: String, - material: String, - size: String, - images: String + obj:ProductObject ) { viewModelScope.launch(Dispatchers.IO) { - val productInformation = ProductEntity(barcodeNumber, userEmail, model, title, category, brand, color, material, size, images) + val productInformation = ProductEntity(obj.barcodeNumber,obj.userEmail,obj.model,obj.title,obj.category,obj.brand,obj.color,obj.material,obj.size,obj.images) productDao.insertProduct(productInformation) Log.i("SAV", "Saved to database") } @@ -64,9 +56,10 @@ class ProductViewModel(val productDao: ProductDao, val productRepository: Produc } //delete - fun deleteProduct(product:ProductEntity){ + fun deleteProduct(obj:ProductObject){ viewModelScope.launch { - productRepository.deleteProductStream(product) + productRepository.deleteProductStream(ProductEntity(obj.barcodeNumber,obj.userEmail,obj.model,obj.title,obj.category,obj.brand,obj.color,obj.material,obj.size,obj.images) + ) } } @@ -77,7 +70,7 @@ class ProductViewModel(val productDao: ProductDao, val productRepository: Produc try { val serverResp = repository.takeInformation(barcode) val result = convertFromApi(serverResp.products) - informationProductMap = result + informationProductObject = result } catch (e: Exception) { Log.e("Error", "Exception: ${e.message}") } @@ -86,18 +79,31 @@ class ProductViewModel(val productDao: ProductDao, val productRepository: Produc } } +data class ProductObject( +val barcodeNumber: String, +val userEmail: String, +val model: String, +val title: String, +val category: String, +val brand: String, +val color: String, +val material: String, +val size: String, +val images: String +) + //Function for convert from the Api result to a map with all the information about a product -fun convertFromApi(products: List): Map { - val result = mutableMapOf() - //save the data from the call in the new Map - result["barcodeNumber"] = products[0].barcode_number - result["model"] = products[0].model - result["title"] = products[0].title - result["category"] = products[0].category - result["brand"] = products[0].brand - result["color"] = products[0].color - result["material"] = products[0].material - result["size"] = products[0].size - result["images"] = products[0].images[0] - return result +fun convertFromApi(products: List): ProductObject { + return ProductObject( + products[0].barcode_number, + LoggedUser.loggedUserEmail, + products[0].model, + products[0].title, + products[0].category, + products[0].brand, + products[0].color, + products[0].material, + products[0].size, + products[0].images[0] + ) } \ No newline at end of file diff --git a/app/src/main/java/com/example/mycloset/LoginWorkingSet/LoggedUser.kt b/app/src/main/java/com/example/mycloset/LoginWorkingSet/LoggedUser.kt index eb1a0cb..eadfba1 100644 --- a/app/src/main/java/com/example/mycloset/LoginWorkingSet/LoggedUser.kt +++ b/app/src/main/java/com/example/mycloset/LoginWorkingSet/LoggedUser.kt @@ -1,5 +1,5 @@ package com.example.mycloset.LoginWorkingSet object LoggedUser { - var loggedUserEmail: String = "" + var loggedUserEmail: String = "mattia@d.it" } \ No newline at end of file diff --git a/app/src/main/java/com/example/mycloset/MainActivity.kt b/app/src/main/java/com/example/mycloset/MainActivity.kt index 5cf4848..e7b05ab 100644 --- a/app/src/main/java/com/example/mycloset/MainActivity.kt +++ b/app/src/main/java/com/example/mycloset/MainActivity.kt @@ -14,6 +14,7 @@ import androidx.core.content.ContextCompat import androidx.lifecycle.viewmodel.compose.viewModel import androidx.navigation.NavHostController import androidx.navigation.compose.rememberNavController +import com.example.mycloset.App.LoginApp import com.example.mycloset.BarcodeWorkingSet.CameraScanViewModel import com.example.mycloset.DatabaseWorkingset.ProductViewModel import com.example.mycloset.Views.ProductScanView @@ -47,8 +48,9 @@ class MainActivity : ComponentActivity() { navController = rememberNavController() // SetupNavGraph(navController = navController) val productViewModel: ProductViewModel = viewModel(factory = AppViewModelProvider.Factory) - //HomeScreen(navController = navController, viewModel = productViewModel) - //LoginScreen() + //HomeScreen() + LoginApp() + ProductScanView( productViewModel, barcodesFlow = viewModel.barcodesFlow, @@ -60,6 +62,8 @@ class MainActivity : ComponentActivity() { viewModel.updateTorchEnabled() } ) + + /*CameraView( cameraController = cameraController, //MainScreen() @@ -147,81 +151,6 @@ class MainActivity : ComponentActivity() { } } -// Product Info Screen Composable - -/* -@Composable -fun ProductInfoScreen(productViewModel: ProductViewModel) { - val informationProductMap by rememberUpdatedState(newValue = productViewModel.informationProductMap) - var showProductInfo by remember { mutableStateOf(false) } - - Column( - modifier = Modifier - .fillMaxSize() - .padding(16.dp) - ) { - Button(onClick = { - productViewModel.getInfo() - showProductInfo = true - }) - { - Text("Fetch Product Info") - } - - Spacer(modifier = Modifier.height(16.dp)) - - Divider(modifier = Modifier.padding(vertical = 20.dp)) - - if (showProductInfo) { - if (informationProductMap.isNotEmpty()) { - Column { - - //Title - val title: String = informationProductMap["title"].toString() - Text( - text = title, - modifier = Modifier.padding(16.dp) - ) - - //Image - DisplayPicture(informationProductMap["images"].toString()) - - //Table - LazyColumn( - modifier = Modifier.fillMaxWidth(), - contentPadding = PaddingValues(16.dp) - ) { - informationProductMap.forEach { (key, value) -> - if (key != "title" && key != "images") { - item { - Row( - modifier = Modifier.fillMaxWidth(), - horizontalArrangement = Arrangement.SpaceBetween - ) { - Text(text = key, fontWeight = FontWeight.Bold) - Text(text = value.toString()) - } - Spacer(modifier = Modifier.height(8.dp)) - } - } - } - } - - //Button - Row { - Button(onClick = { /*TODO*/ }) { - Text(text = "Cancel") - } - Button(onClick = { /*TODO*/ }) { - Text(text = "Add") - } - - } - } - } - } - } -}*/ //@Composable //fun MyNavHost(navController: NavHostController) { diff --git a/app/src/main/java/com/example/mycloset/Views/HomeScreen.kt b/app/src/main/java/com/example/mycloset/Views/HomeScreen.kt index ad97271..5c29757 100644 --- a/app/src/main/java/com/example/mycloset/Views/HomeScreen.kt +++ b/app/src/main/java/com/example/mycloset/Views/HomeScreen.kt @@ -30,7 +30,7 @@ import androidx.compose.ui.unit.dp import androidx.lifecycle.viewmodel.compose.viewModel import androidx.navigation.NavController import androidx.navigation.compose.rememberNavController -import com.example.mycloset.data.SignupViewModel +import com.example.mycloset.LoginWorkingSet.Signup.SignupViewModel import com.example.mycloset.navigation.Screen //import com.example.mycloset.Screen @@ -76,7 +76,7 @@ fun EmptyHomeScreen() { @OptIn(ExperimentalMaterial3Api::class) @Composable -fun HomeScreen() { +fun HomeScreenView() { var viewModel: SignupViewModel = viewModel() Scaffold( topBar = { @@ -124,7 +124,7 @@ fun HomeScreen() { @Preview @Composable fun PrevHome() { - HomeScreen( + HomeScreenView( ) } diff --git a/app/src/main/java/com/example/mycloset/Views/ProductScanView.kt b/app/src/main/java/com/example/mycloset/Views/ProductScanView.kt index 1fd7789..e8b66b8 100644 --- a/app/src/main/java/com/example/mycloset/Views/ProductScanView.kt +++ b/app/src/main/java/com/example/mycloset/Views/ProductScanView.kt @@ -43,12 +43,15 @@ import androidx.compose.ui.Modifier import androidx.compose.ui.platform.LocalContext import androidx.compose.ui.text.font.FontWeight import androidx.compose.ui.unit.dp +import androidx.compose.ui.unit.sp import androidx.compose.ui.viewinterop.AndroidView import com.example.mycloset.BarcodeWorkingSet.BarcodeModel import com.example.mycloset.ApiWorkingSet.ImgDisplay import com.example.mycloset.DatabaseWorkingset.ProductViewModel import kotlinx.coroutines.flow.StateFlow import com.example.mycloset.LoginWorkingSet.LoggedUser +import com.example.mycloset.navigation.LoginAppRouter +import com.example.mycloset.navigation.Screen @Composable fun ProductScanView( @@ -60,7 +63,7 @@ fun ProductScanView( onTorchButtonClicked: () -> Unit // Lambda function for torch button click event ) { // State for managing informationProductMap - val informationProductMap by rememberUpdatedState(newValue = productViewModel.informationProductMap) + val informationProductObject by rememberUpdatedState(newValue = productViewModel.informationProductObject) // State for managing whether to show product information var showProductInfo by remember { mutableStateOf(false) } @@ -79,18 +82,6 @@ fun ProductScanView( val context = LocalContext.current - val barcodeNumber: String = informationProductMap["barcodeNumber"].toString() - val model: String = informationProductMap["model"].toString() - val title: String = informationProductMap["title"].toString() - val category: String = informationProductMap["category"].toString() - val brand: String = informationProductMap["brand"].toString() - val color: String = informationProductMap["color"].toString() - val material: String = informationProductMap["material"].toString() - val size: String = informationProductMap["size"].toString() - val images: String = informationProductMap["images"].toString() - - - if (!showProductInfo) { // AndroidView to display the camera preview AndroidView(factory = { context -> @@ -185,7 +176,7 @@ fun ProductScanView( } } - if (informationProductMap.isEmpty()) { + if (informationProductObject.barcodeNumber!="") { // Display a loading indicator while loading product info if (isLoading) { Column( @@ -205,7 +196,7 @@ fun ProductScanView( } // Display the product information if there is a successful result - if (showProductInfo && informationProductMap.isNotEmpty()) { + if (showProductInfo && informationProductObject.barcodeNumber!="") { isLoading = false Column( modifier = Modifier @@ -214,33 +205,55 @@ fun ProductScanView( ) { Text( - text = title, + text = informationProductObject.title, modifier = Modifier.padding(16.dp) ) // Image of the product - ImgDisplay.DisplayPicture(informationProductMap["images"].toString()) + ImgDisplay.DisplayPicture(informationProductObject.images) LazyColumn( modifier = Modifier.fillMaxWidth(), contentPadding = PaddingValues(16.dp) ) { - informationProductMap.forEach { (key, value) -> - if (key != "title" && key != "images" && key != "barcodeNumber") { - item { - Row( - modifier = Modifier.fillMaxWidth(), - horizontalArrangement = Arrangement.SpaceBetween - ) { - if (value.isNotEmpty()) { - Text(text = "$key: ", fontWeight = FontWeight.Bold) - Text(text = value) - } - } - Spacer(modifier = Modifier.height(8.dp)) - } - } + item { + Text( + text = "Product Information", + fontWeight = FontWeight.Bold, + fontSize = 18.sp, + modifier = Modifier.padding(bottom = 8.dp) + ) + } + + item { + Text("Barcode: ${informationProductObject.barcodeNumber}") + } + + item { + Text("Model: ${informationProductObject.model}") + } + + item { + Text("Category: ${informationProductObject.category}") + } + + item { + Text("Brand: ${informationProductObject.brand}") } + + item { + Text("Color: ${informationProductObject.color}") + } + + item { + Text("Material: ${informationProductObject.material}") + } + + item { + Text("Size: ${informationProductObject.size}") + } + + } } // Buttons for cancel and add actions @@ -254,10 +267,15 @@ fun ProductScanView( Text(text = "Back") } if(LoggedUser.loggedUserEmail!=""){ - Button(onClick = { productViewModel.saveToDatabase(barcodeNumber, LoggedUser.loggedUserEmail, model, title, category, brand, color, material, size, images) - Toast.makeText(context, "Item added!", Toast.LENGTH_SHORT) - .show()}) { + Button(onClick = { + + LoginAppRouter.navigateTo(Screen.HomeScreen) + Log.i("eeeeeeeeee","rrrrr") + productViewModel.saveToDatabase(informationProductObject) + Toast.makeText(context, "Item added!", Toast.LENGTH_SHORT).show() + }) { Text(text = "Add") + } }else{ Log.i("LOGIN_ERROR","You can't add a new item to your wardrobe because you aren't logged") @@ -265,4 +283,4 @@ fun ProductScanView( } } } -} + diff --git a/app/src/main/java/com/example/mycloset/Views/SingleItemScreen.kt b/app/src/main/java/com/example/mycloset/Views/SingleItemScreen.kt index c607c00..4c68c08 100644 --- a/app/src/main/java/com/example/mycloset/Views/SingleItemScreen.kt +++ b/app/src/main/java/com/example/mycloset/Views/SingleItemScreen.kt @@ -1,5 +1,7 @@ package com.example.mycloset.Views +import android.widget.Toast +import androidx.camera.view.LifecycleCameraController import androidx.compose.foundation.Image import androidx.compose.foundation.layout.Arrangement import androidx.compose.foundation.layout.Column @@ -32,21 +34,29 @@ import androidx.compose.runtime.setValue import androidx.compose.ui.Alignment import androidx.compose.ui.Modifier import androidx.compose.ui.graphics.painter.Painter +import androidx.compose.ui.platform.LocalContext import androidx.compose.ui.res.painterResource 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 androidx.lifecycle.viewmodel.compose.viewModel -import com.example.mycloset.ImgDisplay.Companion.DisplayPicture -import com.example.mycloset.ProductViewModel +import com.example.mycloset.ApiWorkingSet.ImgDisplay +import com.example.mycloset.ApiWorkingSet.ImgDisplay.Companion.DisplayPicture +import com.example.mycloset.BarcodeWorkingSet.BarcodeModel +import com.example.mycloset.DatabaseWorkingset.ProductEntity +import com.example.mycloset.LoginWorkingSet.Signup.SignupViewModel +import com.example.mycloset.DatabaseWorkingset.ProductViewModel +import com.example.mycloset.LoginWorkingSet.LoggedUser import com.example.mycloset.R -import com.example.mycloset.data.SignupViewModel +import kotlinx.coroutines.flow.StateFlow @OptIn(ExperimentalMaterial3Api::class, ExperimentalMaterial3Api::class) @Composable -fun SingleItemScreen() { +fun SingleItemScreen(productViewModel: ProductViewModel) { var viewModel: SignupViewModel = viewModel() - val imagePainter: Painter = painterResource(id = R.drawable.airfocrce) + val informationProductObject by rememberUpdatedState(newValue = productViewModel.informationProductObject) + val context = LocalContext.current Scaffold( topBar = { @@ -87,20 +97,55 @@ fun SingleItemScreen() { .fillMaxSize() .padding(16.dp) ) { - // Add an Image - Image( - painter = imagePainter, - contentDescription = "Your Image", - modifier = Modifier - .fillMaxWidth() - .height(200.dp) // Adjust the height as needed - ) + + DisplayPicture(informationProductObject.images) Spacer(modifier = Modifier.height(24.dp)) - // Add text components or any other content - Text("Brand: Nike", modifier = Modifier.align(Alignment.CenterHorizontally)) - Text("Size: 40", modifier = Modifier.align(Alignment.CenterHorizontally)) + + LazyColumn( + modifier = Modifier.fillMaxWidth(), + contentPadding = PaddingValues(16.dp) + ) { + item { + Text( + text = "Product Information", + fontWeight = FontWeight.Bold, + fontSize = 18.sp, + modifier = Modifier.padding(bottom = 8.dp) + ) + } + + item { + Text("Barcode: ${informationProductObject.barcodeNumber}") + } + + item { + Text("Model: ${informationProductObject.model}") + } + + item { + Text("Category: ${informationProductObject.category}") + } + + item { + Text("Brand: ${informationProductObject.brand}") + } + + item { + Text("Color: ${informationProductObject.color}") + } + + item { + Text("Material: ${informationProductObject.material}") + } + + item { + Text("Size: ${informationProductObject.size}") + } + + } + Spacer(modifier = Modifier.height(16.dp)) @@ -113,21 +158,32 @@ fun SingleItemScreen() { ) { Button( onClick = { - // Handle the delete action here + productViewModel.deleteProduct(informationProductObject) + Toast.makeText(context, "Item Delated!", Toast.LENGTH_SHORT).show() } ) { Text("Delete Item") } + + //i have to implement the window for update all the field and after save it + /*Button( + onClick = { + productViewModel.saveToDatabase(barcodeNumber, LoggedUser.loggedUserEmail, model, title, category, brand, color, material, size, images) + + } + ) { + Text("Update Item") + }*/ } } } } -@Composable +/*@Composable @Preview fun SingleItemView(){ SingleItemScreen() -} +}*/ //@Preview //@Composable From 12cabbf70b14e776ec7722ccdfd290eb7b17139d Mon Sep 17 00:00:00 2001 From: Nafisul Nazrul Date: Thu, 12 Oct 2023 10:55:29 +0300 Subject: [PATCH 12/32] Added logout --- .../LoginWorkingSet/Signup/SignupViewModel.kt | 5 +- .../com/example/mycloset/Views/HomeScreen.kt | 96 ++++++++++--------- 2 files changed, 56 insertions(+), 45 deletions(-) diff --git a/app/src/main/java/com/example/mycloset/LoginWorkingSet/Signup/SignupViewModel.kt b/app/src/main/java/com/example/mycloset/LoginWorkingSet/Signup/SignupViewModel.kt index 2ec1411..6430f87 100644 --- a/app/src/main/java/com/example/mycloset/LoginWorkingSet/Signup/SignupViewModel.kt +++ b/app/src/main/java/com/example/mycloset/LoginWorkingSet/Signup/SignupViewModel.kt @@ -106,8 +106,11 @@ class SignupViewModel: ViewModel() { val authStateListener = AuthStateListener{ if (it.currentUser == null){ LoginAppRouter.navigateTo(Screen.LoginScreen) + Log.d(TAG, "Inside sign outSuccess") + } else{ + Log.d(TAG, "Inside sign out is not complete") } } - firebaseAuth.addAuthStateListener { authStateListener } + firebaseAuth.addAuthStateListener(authStateListener) } } \ No newline at end of file diff --git a/app/src/main/java/com/example/mycloset/Views/HomeScreen.kt b/app/src/main/java/com/example/mycloset/Views/HomeScreen.kt index 7db805b..e7e3faf 100644 --- a/app/src/main/java/com/example/mycloset/Views/HomeScreen.kt +++ b/app/src/main/java/com/example/mycloset/Views/HomeScreen.kt @@ -10,6 +10,7 @@ import androidx.compose.foundation.lazy.grid.LazyVerticalGrid import androidx.compose.material.* import androidx.compose.material.icons.Icons import androidx.compose.material.icons.filled.Camera +import androidx.compose.material.icons.filled.Logout import androidx.compose.material3.ExperimentalMaterial3Api import androidx.compose.material3.Icon import androidx.compose.material3.IconButton @@ -20,9 +21,12 @@ import androidx.compose.runtime.* import androidx.compose.ui.Alignment import androidx.compose.ui.Modifier import androidx.compose.ui.text.style.TextAlign +import androidx.compose.ui.tooling.preview.Preview import androidx.compose.ui.unit.dp +import androidx.lifecycle.viewmodel.compose.viewModel import com.example.mycloset.DatabaseWorkingset.ProductViewModel import com.example.mycloset.LoginWorkingSet.LoggedUser +import com.example.mycloset.LoginWorkingSet.Signup.SignupViewModel import com.example.mycloset.navigation.LoginAppRouter import com.example.mycloset.navigation.Screen import kotlinx.coroutines.flow.* @@ -33,28 +37,33 @@ import kotlinx.coroutines.flow.* @OptIn(ExperimentalMaterial3Api::class) @Composable -fun HomeScreen(viewModel: ProductViewModel) { +fun HomeScreen(productviewModel: ProductViewModel) { // Observe the products list from the ViewModel //viewModel.getProducts() - viewModel.getProductsWithEmail(LoggedUser.loggedUserEmail) - val products = viewModel.products + val signupViewModel: SignupViewModel = viewModel() + productviewModel.getProductsWithEmail(LoggedUser.loggedUserEmail) + val products = productviewModel.products Log.i("PROD", products.toString()) if (products.isEmpty()) { Scaffold( topBar = { TopAppBar( -// colors = topAppBarColors( -// containerColor = MaterialTheme.colorScheme.primaryContainer, -// titleContentColor = MaterialTheme.colorScheme.primary, -// ), title = { Text("MyCloset") - }, actions = { + }, + actions = { IconButton( onClick = { LoginAppRouter.navigateTo(Screen.ProductScanView) } ) { Icon(Icons.Default.Camera, contentDescription = null) } + IconButton( + onClick = { + signupViewModel.logout() + } + ) { + Icon(Icons.Default.Logout, contentDescription = "Logout") + } } ) }) { innerPadding -> @@ -71,50 +80,49 @@ fun HomeScreen(viewModel: ProductViewModel) { } } } else { - Scaffold(topBar = { - TopAppBar( -// colors = topAppBarColors( -// containerColor = MaterialTheme.colorScheme.primaryContainer, -// titleContentColor = MaterialTheme.colorScheme.primary, -// ), - title = { - Text("MyCloset", modifier = Modifier.padding(2.dp)) - }, actions = { - IconButton( - onClick = { LoginAppRouter.navigateTo(Screen.ProductScanView)} - ) { - Icon(Icons.Default.Camera, contentDescription = null) + Scaffold(topBar = { + TopAppBar( + title = { + Text("MyCloset", modifier = Modifier.padding(2.dp)) + }, + actions = { + IconButton( + onClick = { LoginAppRouter.navigateTo(Screen.ProductScanView)} + ) { + Icon(Icons.Default.Camera, contentDescription = "Camera") + } + IconButton( + onClick = { + signupViewModel.logout() + } + ) { + Icon(Icons.Default.Logout, contentDescription = "Logout") + } + } + ) + }) { innerPadding -> + LazyVerticalGrid( + columns = GridCells.Fixed(2), modifier = Modifier + .fillMaxSize() + .padding(innerPadding) + .padding(16.dp) + ) { + items(products.size) { index -> + val product = products[index] + ItemCard(product.images, product.title) } - } - ) - }) { innerPadding -> - LazyVerticalGrid( - columns = GridCells.Fixed(2), modifier = Modifier - .fillMaxSize() - .padding(innerPadding) - .padding(16.dp) - ) { - items(products.size) { index -> - val product = products[index] - ItemCard(product.images, product.title) } } } - } } -/* -@Preview + +/*@Preview @Composable fun PrevHome() { HomeScreen( - navController = rememberNavController() + viewModel: ProductViewModel ) -} +}*/ + -@Preview -@Composable -fun PreEmpty() { - EmptyHomeScreen() -} -*/ From 1664d0828060ecb3e2403659b91e60ca9f08fbea Mon Sep 17 00:00:00 2001 From: Liideli Date: Thu, 12 Oct 2023 11:26:13 +0300 Subject: [PATCH 13/32] Navigation from ItemCard to clothesDetailScreen. --- .../com/example/mycloset/App/LoginPreviewApp.kt | 3 +++ .../mycloset/Views/ClothesDetailScreen.kt | 14 ++++++++------ .../com/example/mycloset/Views/HomeScreen.kt | 17 +++++++---------- .../java/com/example/mycloset/Views/ItemCard.kt | 9 ++++++--- .../com/example/mycloset/navigation/Screen.kt | 1 + 5 files changed, 25 insertions(+), 19 deletions(-) diff --git a/app/src/main/java/com/example/mycloset/App/LoginPreviewApp.kt b/app/src/main/java/com/example/mycloset/App/LoginPreviewApp.kt index 5f35bb2..940c880 100644 --- a/app/src/main/java/com/example/mycloset/App/LoginPreviewApp.kt +++ b/app/src/main/java/com/example/mycloset/App/LoginPreviewApp.kt @@ -52,6 +52,9 @@ fun LoginApp(cameraController: LifecycleCameraController){ } ) } + is Screen.ClothesDetailScreen ->{ + Screen.ClothesDetailScreen + } } } diff --git a/app/src/main/java/com/example/mycloset/Views/ClothesDetailScreen.kt b/app/src/main/java/com/example/mycloset/Views/ClothesDetailScreen.kt index 7087676..da47d27 100644 --- a/app/src/main/java/com/example/mycloset/Views/ClothesDetailScreen.kt +++ b/app/src/main/java/com/example/mycloset/Views/ClothesDetailScreen.kt @@ -1,13 +1,15 @@ package com.example.mycloset.Views -/*@Composable +import androidx.compose.runtime.Composable + +@Composable fun clothesDetailScreen( - navController: NavHostController, + /*navController: NavHostController, clothesViewModel:ClothesViewModel, - barcode: String? + barcode: String?*/ ) { - clothesViewModel.findClothesByBarcode(barcode!!) + /*clothesViewModel.findClothesByBarcode(barcode!!) val selectedClothes = clothesViewModel.foundClothes.observeAsState().value; @@ -60,6 +62,6 @@ fun clothesDetailScreen( } } } - } + }*/ } - */ + diff --git a/app/src/main/java/com/example/mycloset/Views/HomeScreen.kt b/app/src/main/java/com/example/mycloset/Views/HomeScreen.kt index e7e3faf..b8bd6b9 100644 --- a/app/src/main/java/com/example/mycloset/Views/HomeScreen.kt +++ b/app/src/main/java/com/example/mycloset/Views/HomeScreen.kt @@ -1,7 +1,6 @@ package com.example.mycloset.Views -import android.util.Log import androidx.compose.foundation.layout.Box import androidx.compose.foundation.layout.fillMaxSize import androidx.compose.foundation.layout.padding @@ -21,7 +20,6 @@ import androidx.compose.runtime.* import androidx.compose.ui.Alignment import androidx.compose.ui.Modifier import androidx.compose.ui.text.style.TextAlign -import androidx.compose.ui.tooling.preview.Preview import androidx.compose.ui.unit.dp import androidx.lifecycle.viewmodel.compose.viewModel import com.example.mycloset.DatabaseWorkingset.ProductViewModel @@ -32,18 +30,17 @@ import com.example.mycloset.navigation.Screen import kotlinx.coroutines.flow.* - -//import com.example.mycloset.Screen - @OptIn(ExperimentalMaterial3Api::class) @Composable -fun HomeScreen(productviewModel: ProductViewModel) { +fun HomeScreen(productViewModel: ProductViewModel) { + // Observe the products list from the ViewModel - //viewModel.getProducts() val signupViewModel: SignupViewModel = viewModel() - productviewModel.getProductsWithEmail(LoggedUser.loggedUserEmail) - val products = productviewModel.products - Log.i("PROD", products.toString()) + + productViewModel.getProductsWithEmail(LoggedUser.loggedUserEmail) + + val products = productViewModel.products + if (products.isEmpty()) { Scaffold( topBar = { diff --git a/app/src/main/java/com/example/mycloset/Views/ItemCard.kt b/app/src/main/java/com/example/mycloset/Views/ItemCard.kt index 6ea6137..ed2782d 100644 --- a/app/src/main/java/com/example/mycloset/Views/ItemCard.kt +++ b/app/src/main/java/com/example/mycloset/Views/ItemCard.kt @@ -15,6 +15,9 @@ import androidx.compose.ui.Modifier import androidx.compose.ui.tooling.preview.Preview import androidx.compose.ui.unit.dp import coil.compose.rememberAsyncImagePainter +import com.example.mycloset.navigation.LoginAppRouter +import com.example.mycloset.navigation.Screen + data class Item(val id: Int, val title: String, val imageUrl: String) @@ -31,9 +34,9 @@ fun ItemCard( ), modifier = Modifier.padding(5.dp), shape = RoundedCornerShape(10.dp), -// onClick = { - // open single item screen -// } + onClick = { + LoginAppRouter.navigateTo(Screen.ClothesDetailScreen) + } ) { Column(modifier = Modifier.padding(10.dp)) { Image( diff --git a/app/src/main/java/com/example/mycloset/navigation/Screen.kt b/app/src/main/java/com/example/mycloset/navigation/Screen.kt index 21c19ef..436ada8 100644 --- a/app/src/main/java/com/example/mycloset/navigation/Screen.kt +++ b/app/src/main/java/com/example/mycloset/navigation/Screen.kt @@ -8,6 +8,7 @@ sealed class Screen(){ object LoginScreen: Screen() object HomeScreen : Screen() object ProductScanView : Screen() + object ClothesDetailScreen : Screen() } object LoginAppRouter{ From b7d518246dd6217c9a4e29d611ff960f2646e731 Mon Sep 17 00:00:00 2001 From: matti Date: Thu, 12 Oct 2023 10:31:43 +0200 Subject: [PATCH 14/32] Roope modification --- .../com/example/mycloset/Views/HomeScreen.kt | 1 - .../example/mycloset/Views/ProductScanView.kt | 11 +- .../mycloset/Views/SingleItemScreen.kt | 10 +- .../mycloset/Views/UpdateSingleItem.kt | 180 ++++++++++++++++++ 4 files changed, 187 insertions(+), 15 deletions(-) create mode 100644 app/src/main/java/com/example/mycloset/Views/UpdateSingleItem.kt diff --git a/app/src/main/java/com/example/mycloset/Views/HomeScreen.kt b/app/src/main/java/com/example/mycloset/Views/HomeScreen.kt index 8bec209..43a3110 100644 --- a/app/src/main/java/com/example/mycloset/Views/HomeScreen.kt +++ b/app/src/main/java/com/example/mycloset/Views/HomeScreen.kt @@ -38,7 +38,6 @@ import androidx.lifecycle.viewmodel.compose.viewModel import androidx.navigation.NavController import androidx.navigation.compose.rememberNavController import com.example.mycloset.LoginWorkingSet.Signup.SignupViewModel -import com.example.mycloset.navigation.Screen //import com.example.mycloset.Screen diff --git a/app/src/main/java/com/example/mycloset/Views/ProductScanView.kt b/app/src/main/java/com/example/mycloset/Views/ProductScanView.kt index 158e82e..36cf774 100644 --- a/app/src/main/java/com/example/mycloset/Views/ProductScanView.kt +++ b/app/src/main/java/com/example/mycloset/Views/ProductScanView.kt @@ -51,11 +51,9 @@ import com.example.mycloset.DatabaseWorkingset.ProductViewModel import com.example.mycloset.LoginWorkingSet.LoggedUser import com.example.mycloset.navigation.LoginAppRouter import com.example.mycloset.navigation.Screen -import com.example.mycloset.navigation.LoginAppRouter -import com.example.mycloset.navigation.Screen import kotlinx.coroutines.flow.StateFlow -@OptIn(ExperimentalMaterial3Api::class) +//@OptIn(ExperimentalMaterial3Api::class) @Composable fun ProductScanView( // Parameters required for the composable @@ -255,10 +253,8 @@ fun ProductScanView( item { Text("Size: ${informationProductObject.size}") } - } } - // Buttons for cancel and add actions Row( modifier = Modifier.fillMaxWidth(), @@ -271,14 +267,11 @@ fun ProductScanView( } if(LoggedUser.loggedUserEmail!=""){ Button(onClick = { - - LoginAppRouter.navigateTo(Screen.HomeScreen) - Log.i("eeeeeeeeee","rrrrr") productViewModel.saveToDatabase(informationProductObject) Toast.makeText(context, "Item added!", Toast.LENGTH_SHORT).show() + LoginAppRouter.navigateTo(Screen.HomeScreen) }) { Text(text = "Add") - } }else{ Log.i("LOGIN_ERROR","You can't add a new item to your wardrobe because you aren't logged") diff --git a/app/src/main/java/com/example/mycloset/Views/SingleItemScreen.kt b/app/src/main/java/com/example/mycloset/Views/SingleItemScreen.kt index 4c68c08..00b064f 100644 --- a/app/src/main/java/com/example/mycloset/Views/SingleItemScreen.kt +++ b/app/src/main/java/com/example/mycloset/Views/SingleItemScreen.kt @@ -49,6 +49,8 @@ import com.example.mycloset.LoginWorkingSet.Signup.SignupViewModel import com.example.mycloset.DatabaseWorkingset.ProductViewModel import com.example.mycloset.LoginWorkingSet.LoggedUser import com.example.mycloset.R +import com.example.mycloset.navigation.LoginAppRouter +import com.example.mycloset.navigation.Screen import kotlinx.coroutines.flow.StateFlow @OptIn(ExperimentalMaterial3Api::class, ExperimentalMaterial3Api::class) @@ -160,20 +162,18 @@ fun SingleItemScreen(productViewModel: ProductViewModel) { onClick = { productViewModel.deleteProduct(informationProductObject) Toast.makeText(context, "Item Delated!", Toast.LENGTH_SHORT).show() + LoginAppRouter.navigateTo(Screen.HomeScreen) } ) { Text("Delete Item") } - - //i have to implement the window for update all the field and after save it - /*Button( + Button( onClick = { - productViewModel.saveToDatabase(barcodeNumber, LoggedUser.loggedUserEmail, model, title, category, brand, color, material, size, images) } ) { Text("Update Item") - }*/ + } } } } diff --git a/app/src/main/java/com/example/mycloset/Views/UpdateSingleItem.kt b/app/src/main/java/com/example/mycloset/Views/UpdateSingleItem.kt new file mode 100644 index 0000000..9e2957a --- /dev/null +++ b/app/src/main/java/com/example/mycloset/Views/UpdateSingleItem.kt @@ -0,0 +1,180 @@ +package com.example.mycloset.Views + +import android.widget.Toast +import androidx.camera.view.LifecycleCameraController +import androidx.compose.foundation.Image +import androidx.compose.foundation.layout.Arrangement +import androidx.compose.foundation.layout.Column +import androidx.compose.foundation.layout.PaddingValues +import androidx.compose.foundation.layout.Row +import androidx.compose.foundation.layout.Spacer +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.lazy.LazyColumn +import androidx.compose.material.icons.Icons +import androidx.compose.material.icons.filled.ArrowBack +import androidx.compose.material.icons.filled.Camera +import androidx.compose.material.icons.filled.Logout +import androidx.compose.material3.Button +import androidx.compose.material3.Divider +import androidx.compose.material3.ExperimentalMaterial3Api +import androidx.compose.material3.Icon +import androidx.compose.material3.IconButton +import androidx.compose.material3.Scaffold +import androidx.compose.material3.Text +import androidx.compose.material3.TopAppBar +import androidx.compose.runtime.Composable +import androidx.compose.runtime.getValue +import androidx.compose.runtime.mutableStateOf +import androidx.compose.runtime.remember +import androidx.compose.runtime.rememberUpdatedState +import androidx.compose.runtime.setValue +import androidx.compose.ui.Alignment +import androidx.compose.ui.Modifier +import androidx.compose.ui.graphics.painter.Painter +import androidx.compose.ui.platform.LocalContext +import androidx.compose.ui.res.painterResource +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 androidx.lifecycle.viewmodel.compose.viewModel +import com.example.mycloset.ApiWorkingSet.ImgDisplay +import com.example.mycloset.ApiWorkingSet.ImgDisplay.Companion.DisplayPicture +import com.example.mycloset.BarcodeWorkingSet.BarcodeModel +import com.example.mycloset.DatabaseWorkingset.ProductEntity +import com.example.mycloset.LoginWorkingSet.Signup.SignupViewModel +import com.example.mycloset.DatabaseWorkingset.ProductViewModel +import com.example.mycloset.LoginWorkingSet.LoggedUser +import com.example.mycloset.R +import com.example.mycloset.navigation.LoginAppRouter +import com.example.mycloset.navigation.Screen +import kotlinx.coroutines.flow.StateFlow + +@OptIn(ExperimentalMaterial3Api::class, ExperimentalMaterial3Api::class) +@Composable +fun SingleItemScreen(productViewModel: ProductViewModel) { + var viewModel: SignupViewModel = viewModel() + val informationProductObject by rememberUpdatedState(newValue = productViewModel.informationProductObject) + val context = LocalContext.current + + Scaffold( + topBar = { + // TopAppBar (the top bar) + TopAppBar( + navigationIcon = { + IconButton(onClick = { }) { + Icon( + Icons.Default.ArrowBack, + contentDescription = "Back" + ) + } + }, + title = { + Text("MyCloset") + }, + actions = { + IconButton(onClick = { /* Handle camera navigation here */ }) { + Icon( + Icons.Default.Camera, + contentDescription = "Camera" + ) + } + IconButton( + onClick = { + viewModel.logout() + } + ) { + Icon(Icons.Default.Logout, contentDescription = "Logout") + } + } + ) + } + ) { padding -> + // Content to be displayed below the top bar + Column( + modifier = Modifier + .fillMaxSize() + .padding(16.dp) + ) { + + DisplayPicture(informationProductObject.images) + + Spacer(modifier = Modifier.height(24.dp)) + + + LazyColumn( + modifier = Modifier.fillMaxWidth(), + contentPadding = PaddingValues(16.dp) + ) { + item { + Text( + text = "Product Information", + fontWeight = FontWeight.Bold, + fontSize = 18.sp, + modifier = Modifier.padding(bottom = 8.dp) + ) + } + + item { + Text("Barcode: ${informationProductObject.barcodeNumber}") + } + + item { + Text("Model: ${informationProductObject.model}") + } + + item { + Text("Category: ${informationProductObject.category}") + } + + item { + Text("Brand: ${informationProductObject.brand}") + } + + item { + Text("Color: ${informationProductObject.color}") + } + + item { + Text("Material: ${informationProductObject.material}") + } + + item { + Text("Size: ${informationProductObject.size}") + } + + } + + + Spacer(modifier = Modifier.height(16.dp)) + + // Add more text components or other content as needed + Row( + modifier = Modifier + .fillMaxWidth() + .padding(16.dp), + horizontalArrangement = Arrangement.Center + ) { + Button( + onClick = { + productViewModel.deleteProduct(informationProductObject) + Toast.makeText(context, "Item Delated!", Toast.LENGTH_SHORT).show() + LoginAppRouter.navigateTo(Screen.HomeScreen) + } + ) { + Text("Delete Item") + } + Button( + onClick = { + + } + ) { + Text("Update Item") + } + } + } + } +} From 6b98e9bb33bc569dff48f06cbfe4fda367ad470f Mon Sep 17 00:00:00 2001 From: matti Date: Thu, 12 Oct 2023 10:58:22 +0200 Subject: [PATCH 15/32] delate is working --- .../example/mycloset/App/LoginPreviewApp.kt | 5 +- .../mycloset/Views/ClothesDetailScreen.kt | 67 ------------------- .../com/example/mycloset/Views/ItemCard.kt | 2 +- .../example/mycloset/Views/ProductScanView.kt | 1 - .../mycloset/Views/SingleItemScreen.kt | 16 ----- .../mycloset/Views/UpdateSingleItem.kt | 2 + .../com/example/mycloset/navigation/Screen.kt | 2 +- 7 files changed, 7 insertions(+), 88 deletions(-) delete mode 100644 app/src/main/java/com/example/mycloset/Views/ClothesDetailScreen.kt diff --git a/app/src/main/java/com/example/mycloset/App/LoginPreviewApp.kt b/app/src/main/java/com/example/mycloset/App/LoginPreviewApp.kt index 940c880..488d46d 100644 --- a/app/src/main/java/com/example/mycloset/App/LoginPreviewApp.kt +++ b/app/src/main/java/com/example/mycloset/App/LoginPreviewApp.kt @@ -15,6 +15,7 @@ import com.example.mycloset.Views.HomeScreen import com.example.mycloset.Views.LoginScreen import com.example.mycloset.Views.ProductScanView import com.example.mycloset.Views.SignUpScreen +import com.example.mycloset.Views.SingleItemScreen import com.example.mycloset.navigation.LoginAppRouter import com.example.mycloset.navigation.Screen @@ -52,8 +53,8 @@ fun LoginApp(cameraController: LifecycleCameraController){ } ) } - is Screen.ClothesDetailScreen ->{ - Screen.ClothesDetailScreen + is Screen.SingleItemScreen ->{ + SingleItemScreen(productViewModel) } } diff --git a/app/src/main/java/com/example/mycloset/Views/ClothesDetailScreen.kt b/app/src/main/java/com/example/mycloset/Views/ClothesDetailScreen.kt deleted file mode 100644 index da47d27..0000000 --- a/app/src/main/java/com/example/mycloset/Views/ClothesDetailScreen.kt +++ /dev/null @@ -1,67 +0,0 @@ -package com.example.mycloset.Views - -import androidx.compose.runtime.Composable - -@Composable -fun clothesDetailScreen( - /*navController: NavHostController, - clothesViewModel:ClothesViewModel, - barcode: String?*/ -) { - - /*clothesViewModel.findClothesByBarcode(barcode!!) - - val selectedClothes = clothesViewModel.foundClothes.observeAsState().value; - - if (selectedClothes != null) { - Surface(color = Color.White, modifier = Modifier.fillMaxSize()) { - Card( - modifier = Modifier - .padding(10.dp) - .fillMaxWidth(), - shape = RoundedCornerShape(10.dp), - ) { - Column( - modifier = Modifier.padding(20.dp), - horizontalAlignment = Alignment.CenterHorizontally, - verticalArrangement = Arrangement.Center - ) { - - Spacer(modifier = Modifier.weight(1f)) - Row() { - Button( - onClick = { - /*homeViewModel.deleteEmployee(selectedEmployee) - navController.popBackStack()*/ - }, - modifier = Modifier - .weight(1f) - ) { - Text( - text = "Delete Employee", - fontSize = 16.sp, - ) - } - Spacer(modifier = Modifier.width(10.dp)) - Text( - text = "(${selectedClothes.brand})", - fontSize = 20.sp, - fontWeight = FontWeight.SemiBold, - ) - Spacer(modifier = Modifier.width(10.dp)) - Button( - onClick = { - /*navController.navigate(AppScreens.AddEditEmployeeScreen.route + "/" + selectedEmployee.employeeId + "/" + true)*/ - }, - modifier = Modifier - .weight(1f) - ) { - Text(text = "Update Details", fontSize = 16.sp) - } - } - } - } - } - }*/ - } - diff --git a/app/src/main/java/com/example/mycloset/Views/ItemCard.kt b/app/src/main/java/com/example/mycloset/Views/ItemCard.kt index ed2782d..35176e3 100644 --- a/app/src/main/java/com/example/mycloset/Views/ItemCard.kt +++ b/app/src/main/java/com/example/mycloset/Views/ItemCard.kt @@ -35,7 +35,7 @@ fun ItemCard( modifier = Modifier.padding(5.dp), shape = RoundedCornerShape(10.dp), onClick = { - LoginAppRouter.navigateTo(Screen.ClothesDetailScreen) + LoginAppRouter.navigateTo(Screen.SingleItemScreen) } ) { Column(modifier = Modifier.padding(10.dp)) { diff --git a/app/src/main/java/com/example/mycloset/Views/ProductScanView.kt b/app/src/main/java/com/example/mycloset/Views/ProductScanView.kt index 36cf774..06bedef 100644 --- a/app/src/main/java/com/example/mycloset/Views/ProductScanView.kt +++ b/app/src/main/java/com/example/mycloset/Views/ProductScanView.kt @@ -279,4 +279,3 @@ fun ProductScanView( } } } - diff --git a/app/src/main/java/com/example/mycloset/Views/SingleItemScreen.kt b/app/src/main/java/com/example/mycloset/Views/SingleItemScreen.kt index 00b064f..886f630 100644 --- a/app/src/main/java/com/example/mycloset/Views/SingleItemScreen.kt +++ b/app/src/main/java/com/example/mycloset/Views/SingleItemScreen.kt @@ -1,8 +1,6 @@ package com.example.mycloset.Views import android.widget.Toast -import androidx.camera.view.LifecycleCameraController -import androidx.compose.foundation.Image import androidx.compose.foundation.layout.Arrangement import androidx.compose.foundation.layout.Column import androidx.compose.foundation.layout.PaddingValues @@ -18,7 +16,6 @@ import androidx.compose.material.icons.filled.ArrowBack import androidx.compose.material.icons.filled.Camera import androidx.compose.material.icons.filled.Logout import androidx.compose.material3.Button -import androidx.compose.material3.Divider import androidx.compose.material3.ExperimentalMaterial3Api import androidx.compose.material3.Icon import androidx.compose.material3.IconButton @@ -27,31 +24,18 @@ import androidx.compose.material3.Text import androidx.compose.material3.TopAppBar import androidx.compose.runtime.Composable import androidx.compose.runtime.getValue -import androidx.compose.runtime.mutableStateOf -import androidx.compose.runtime.remember import androidx.compose.runtime.rememberUpdatedState -import androidx.compose.runtime.setValue -import androidx.compose.ui.Alignment import androidx.compose.ui.Modifier -import androidx.compose.ui.graphics.painter.Painter import androidx.compose.ui.platform.LocalContext -import androidx.compose.ui.res.painterResource 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 androidx.lifecycle.viewmodel.compose.viewModel -import com.example.mycloset.ApiWorkingSet.ImgDisplay import com.example.mycloset.ApiWorkingSet.ImgDisplay.Companion.DisplayPicture -import com.example.mycloset.BarcodeWorkingSet.BarcodeModel -import com.example.mycloset.DatabaseWorkingset.ProductEntity import com.example.mycloset.LoginWorkingSet.Signup.SignupViewModel import com.example.mycloset.DatabaseWorkingset.ProductViewModel -import com.example.mycloset.LoginWorkingSet.LoggedUser -import com.example.mycloset.R import com.example.mycloset.navigation.LoginAppRouter import com.example.mycloset.navigation.Screen -import kotlinx.coroutines.flow.StateFlow @OptIn(ExperimentalMaterial3Api::class, ExperimentalMaterial3Api::class) @Composable diff --git a/app/src/main/java/com/example/mycloset/Views/UpdateSingleItem.kt b/app/src/main/java/com/example/mycloset/Views/UpdateSingleItem.kt index 9e2957a..dabc0ed 100644 --- a/app/src/main/java/com/example/mycloset/Views/UpdateSingleItem.kt +++ b/app/src/main/java/com/example/mycloset/Views/UpdateSingleItem.kt @@ -53,6 +53,7 @@ import com.example.mycloset.navigation.LoginAppRouter import com.example.mycloset.navigation.Screen import kotlinx.coroutines.flow.StateFlow +/* @OptIn(ExperimentalMaterial3Api::class, ExperimentalMaterial3Api::class) @Composable fun SingleItemScreen(productViewModel: ProductViewModel) { @@ -178,3 +179,4 @@ fun SingleItemScreen(productViewModel: ProductViewModel) { } } } +*/ \ No newline at end of file diff --git a/app/src/main/java/com/example/mycloset/navigation/Screen.kt b/app/src/main/java/com/example/mycloset/navigation/Screen.kt index 436ada8..cb6f976 100644 --- a/app/src/main/java/com/example/mycloset/navigation/Screen.kt +++ b/app/src/main/java/com/example/mycloset/navigation/Screen.kt @@ -8,7 +8,7 @@ sealed class Screen(){ object LoginScreen: Screen() object HomeScreen : Screen() object ProductScanView : Screen() - object ClothesDetailScreen : Screen() + object SingleItemScreen : Screen() } object LoginAppRouter{ From 48885a6c8f4add9d09ea056200b929f1ee549343 Mon Sep 17 00:00:00 2001 From: Liideli Date: Thu, 12 Oct 2023 16:20:11 +0300 Subject: [PATCH 16/32] In progress. --- .../OfflineProductRepository.kt | 6 +- .../mycloset/DatabaseWorkingset/ProductDao.kt | 8 +- .../DatabaseWorkingset/ProductDatabase.kt | 2 +- .../DatabaseWorkingset/ProductEntity.kt | 5 +- .../DatabaseWorkingset/ProductRepository.kt | 4 +- .../DatabaseWorkingset/ProductViewModel.kt | 22 +- .../com/example/mycloset/Views/HomeScreen.kt | 5 +- .../com/example/mycloset/Views/ItemCard.kt | 8 +- .../example/mycloset/Views/ProductScanView.kt | 317 ++++++++++-------- .../mycloset/Views/SingleItemScreen.kt | 108 +++--- 10 files changed, 260 insertions(+), 225 deletions(-) diff --git a/app/src/main/java/com/example/mycloset/DatabaseWorkingset/OfflineProductRepository.kt b/app/src/main/java/com/example/mycloset/DatabaseWorkingset/OfflineProductRepository.kt index 6251878..3a052df 100644 --- a/app/src/main/java/com/example/mycloset/DatabaseWorkingset/OfflineProductRepository.kt +++ b/app/src/main/java/com/example/mycloset/DatabaseWorkingset/OfflineProductRepository.kt @@ -4,8 +4,12 @@ class OfflineProductRepository(private val productDao: ProductDao) : ProductRepo override fun getAllProductsStream() = productDao.getAllProducts() override fun getAllProductsWithEmailStream(userEmail: String) = productDao.getProductsWithEmail(userEmail) + + override fun getAllProductWithBarcodeStream(barcodeNumber: String) = productDao.getProductWithBarcode(barcodeNumber) + + // override fun getAllProductWithBarcodeStream(barcodeNumber: String ,userEmail: String)=productDao.getProductWithBarcode(barcodeNumber, userEmail) override suspend fun updateProductDetailsStream(product: ProductEntity) =productDao.updateProductDetails(product) - override suspend fun deleteProductStream(product: ProductEntity) =productDao.deleteProduct(product) + //override suspend fun deleteProductStream(product: ProductEntity) =productDao.deleteProduct(product) } \ No newline at end of file diff --git a/app/src/main/java/com/example/mycloset/DatabaseWorkingset/ProductDao.kt b/app/src/main/java/com/example/mycloset/DatabaseWorkingset/ProductDao.kt index 3217455..6bf044a 100644 --- a/app/src/main/java/com/example/mycloset/DatabaseWorkingset/ProductDao.kt +++ b/app/src/main/java/com/example/mycloset/DatabaseWorkingset/ProductDao.kt @@ -1,7 +1,6 @@ package com.example.mycloset.DatabaseWorkingset import androidx.room.Dao -import androidx.room.Delete import androidx.room.Insert import androidx.room.OnConflictStrategy import androidx.room.Query @@ -21,9 +20,12 @@ interface ProductDao { @Query("SELECT * from products WHERE userEmail = :userEmail") fun getProductsWithEmail(userEmail: String): Flow> + @Query("SELECT * from products WHERE barcodeNumber=:barcodeNumber") + fun getProductWithBarcode(barcodeNumber: String): Flow> + @Update suspend fun updateProductDetails(product: ProductEntity) - @Delete - suspend fun deleteProduct(product: ProductEntity) + /*@Query("DELETE FROM products WHERE barcodeNumber = :barcodeNumber") + suspend fun deleteProduct(product: ProductEntity)*/ } diff --git a/app/src/main/java/com/example/mycloset/DatabaseWorkingset/ProductDatabase.kt b/app/src/main/java/com/example/mycloset/DatabaseWorkingset/ProductDatabase.kt index 5146378..abd39f0 100644 --- a/app/src/main/java/com/example/mycloset/DatabaseWorkingset/ProductDatabase.kt +++ b/app/src/main/java/com/example/mycloset/DatabaseWorkingset/ProductDatabase.kt @@ -6,7 +6,7 @@ import androidx.room.Room import androidx.room.RoomDatabase -@Database(entities = [ProductEntity::class], version = 2, exportSchema = false) +@Database(entities = [ProductEntity::class], version = 3, exportSchema = false) abstract class ProductDatabase : RoomDatabase() { abstract fun productDao(): ProductDao diff --git a/app/src/main/java/com/example/mycloset/DatabaseWorkingset/ProductEntity.kt b/app/src/main/java/com/example/mycloset/DatabaseWorkingset/ProductEntity.kt index 6090606..fd52170 100644 --- a/app/src/main/java/com/example/mycloset/DatabaseWorkingset/ProductEntity.kt +++ b/app/src/main/java/com/example/mycloset/DatabaseWorkingset/ProductEntity.kt @@ -1,11 +1,10 @@ package com.example.mycloset.DatabaseWorkingset import androidx.room.Entity -import androidx.room.PrimaryKey -@Entity(tableName = "products") +@Entity(tableName = "products",primaryKeys = ["barcodeNumber", "userEmail"]) data class ProductEntity( - @PrimaryKey val barcodeNumber: String, + val barcodeNumber: String, val userEmail: String, val model: String, val title: String, diff --git a/app/src/main/java/com/example/mycloset/DatabaseWorkingset/ProductRepository.kt b/app/src/main/java/com/example/mycloset/DatabaseWorkingset/ProductRepository.kt index d9199e2..825228d 100644 --- a/app/src/main/java/com/example/mycloset/DatabaseWorkingset/ProductRepository.kt +++ b/app/src/main/java/com/example/mycloset/DatabaseWorkingset/ProductRepository.kt @@ -6,6 +6,8 @@ import kotlinx.coroutines.flow.Flow interface ProductRepository { fun getAllProductsStream(): Flow> fun getAllProductsWithEmailStream(userEmail: String): Flow> + fun getAllProductWithBarcodeStream(barcodeNumber: String): Flow> + // fun getAllProductWithBarcodeStream(barcodeNumber: String, userEmail: String):ProductEntity suspend fun updateProductDetailsStream(product: ProductEntity) - suspend fun deleteProductStream(product: ProductEntity) + //suspend fun deleteProductStream(product: ProductEntity) } \ No newline at end of file diff --git a/app/src/main/java/com/example/mycloset/DatabaseWorkingset/ProductViewModel.kt b/app/src/main/java/com/example/mycloset/DatabaseWorkingset/ProductViewModel.kt index e4e8b29..4a3ab44 100644 --- a/app/src/main/java/com/example/mycloset/DatabaseWorkingset/ProductViewModel.kt +++ b/app/src/main/java/com/example/mycloset/DatabaseWorkingset/ProductViewModel.kt @@ -20,6 +20,13 @@ class ProductViewModel(val productDao: ProductDao, val productRepository: Produc var informationProductObject by mutableStateOf(ProductObject("","","","","", "", "","","","")) var products by mutableStateOf(emptyList()) + + var selectedProduct by mutableStateOf(String()) + fun setSelectedProduct(product: String): String { + selectedProduct = product + return selectedProduct + } + fun saveToDatabase( obj:ProductObject ) { @@ -43,9 +50,16 @@ class ProductViewModel(val productDao: ProductDao, val productRepository: Produc fun getProductsWithEmail(userEmail: String) { viewModelScope.launch { productRepository.getAllProductsWithEmailStream(userEmail).collect() { response -> - if (response != null) { products = response - } + } + } + } + + // Get product with barcode + fun getProductWithBarcode(barcodeNumber: String) { + viewModelScope.launch { + productRepository.getAllProductWithBarcodeStream(barcodeNumber).collect() { response -> + products = response } } } @@ -58,12 +72,12 @@ class ProductViewModel(val productDao: ProductDao, val productRepository: Produc } //delete - fun deleteProduct(obj:ProductObject){ + /*fun deleteProduct(obj:ProductObject){ viewModelScope.launch { productRepository.deleteProductStream(ProductEntity(obj.barcodeNumber,obj.userEmail,obj.model,obj.title,obj.category,obj.brand,obj.color,obj.material,obj.size,obj.images) ) } - } + }*/ //the result will be an array of strings fun getInfo(barcode: String) { diff --git a/app/src/main/java/com/example/mycloset/Views/HomeScreen.kt b/app/src/main/java/com/example/mycloset/Views/HomeScreen.kt index b8bd6b9..a6dc847 100644 --- a/app/src/main/java/com/example/mycloset/Views/HomeScreen.kt +++ b/app/src/main/java/com/example/mycloset/Views/HomeScreen.kt @@ -84,7 +84,8 @@ fun HomeScreen(productViewModel: ProductViewModel) { }, actions = { IconButton( - onClick = { LoginAppRouter.navigateTo(Screen.ProductScanView)} + onClick = { + LoginAppRouter.navigateTo(Screen.ProductScanView)} ) { Icon(Icons.Default.Camera, contentDescription = "Camera") } @@ -106,7 +107,7 @@ fun HomeScreen(productViewModel: ProductViewModel) { ) { items(products.size) { index -> val product = products[index] - ItemCard(product.images, product.title) + ItemCard(product.images, product.title, product.barcodeNumber, productViewModel) } } } diff --git a/app/src/main/java/com/example/mycloset/Views/ItemCard.kt b/app/src/main/java/com/example/mycloset/Views/ItemCard.kt index 35176e3..eefaee3 100644 --- a/app/src/main/java/com/example/mycloset/Views/ItemCard.kt +++ b/app/src/main/java/com/example/mycloset/Views/ItemCard.kt @@ -12,9 +12,9 @@ import androidx.compose.material3.MaterialTheme import androidx.compose.material3.Text import androidx.compose.runtime.Composable import androidx.compose.ui.Modifier -import androidx.compose.ui.tooling.preview.Preview import androidx.compose.ui.unit.dp import coil.compose.rememberAsyncImagePainter +import com.example.mycloset.DatabaseWorkingset.ProductViewModel import com.example.mycloset.navigation.LoginAppRouter import com.example.mycloset.navigation.Screen @@ -26,6 +26,8 @@ data class Item(val id: Int, val title: String, val imageUrl: String) fun ItemCard( imageUrl: String?, name: String?, + barcodeNumber: String, + productViewModel: ProductViewModel // onClick: () -> Unit ) { Card( @@ -35,6 +37,7 @@ fun ItemCard( modifier = Modifier.padding(5.dp), shape = RoundedCornerShape(10.dp), onClick = { + productViewModel.setSelectedProduct(barcodeNumber) LoginAppRouter.navigateTo(Screen.SingleItemScreen) } ) { @@ -51,9 +54,10 @@ fun ItemCard( - +/* @Preview @Composable fun MyPrev() { ItemCard("https://media.istockphoto.com/id/1303978937/fi/valokuva/valkoinen-lenkkari-sinisell%C3%A4-kaltevuustaustalla-miesten-muoti-urheilukenk%C3%A4-lenkkarit.jpg?s=612x612&w=0&k=20&c=X_lwi6td_xtFUGXjOmAU8WzH-MKPZ-OeWKtKUshe-SI=", "nike") } +*/ \ No newline at end of file diff --git a/app/src/main/java/com/example/mycloset/Views/ProductScanView.kt b/app/src/main/java/com/example/mycloset/Views/ProductScanView.kt index 06bedef..29e3c9f 100644 --- a/app/src/main/java/com/example/mycloset/Views/ProductScanView.kt +++ b/app/src/main/java/com/example/mycloset/Views/ProductScanView.kt @@ -10,26 +10,30 @@ import androidx.compose.foundation.layout.Arrangement import androidx.compose.foundation.layout.Column import androidx.compose.foundation.layout.PaddingValues import androidx.compose.foundation.layout.Row -import androidx.compose.foundation.layout.Spacer import androidx.compose.foundation.layout.fillMaxHeight 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.shape.RoundedCornerShape import androidx.compose.material.icons.Icons +import androidx.compose.material.icons.filled.Camera import androidx.compose.material.icons.filled.FlashOff import androidx.compose.material.icons.filled.FlashOn +import androidx.compose.material.icons.filled.Home import androidx.compose.material3.Button import androidx.compose.material3.ButtonDefaults import androidx.compose.material3.Card import androidx.compose.material3.CardDefaults import androidx.compose.material3.CircularProgressIndicator +import androidx.compose.material3.ExperimentalMaterial3Api import androidx.compose.material3.Icon +import androidx.compose.material3.IconButton import androidx.compose.material3.MaterialTheme +import androidx.compose.material3.Scaffold import androidx.compose.material3.Text +import androidx.compose.material3.TopAppBar import androidx.compose.runtime.Composable import androidx.compose.runtime.State import androidx.compose.runtime.collectAsState @@ -54,6 +58,7 @@ import com.example.mycloset.navigation.Screen import kotlinx.coroutines.flow.StateFlow //@OptIn(ExperimentalMaterial3Api::class) +@OptIn(ExperimentalMaterial3Api::class) @Composable fun ProductScanView( // Parameters required for the composable @@ -84,100 +89,116 @@ fun ProductScanView( val context = LocalContext.current if (!showProductInfo) { - // AndroidView to display the camera preview - AndroidView(factory = { context -> - PreviewView(context).apply { - layoutParams = LinearLayout.LayoutParams( - ViewGroup.LayoutParams.MATCH_PARENT, - ViewGroup.LayoutParams.MATCH_PARENT - ) - scaleType = PreviewView.ScaleType.FILL_START - implementationMode = PreviewView.ImplementationMode.COMPATIBLE - this.controller = cameraController - } - }) - - // Column to organize UI elements vertically with space between them - Column( - modifier = Modifier - .fillMaxHeight() - .padding(16.dp), - verticalArrangement = Arrangement.Bottom, - horizontalAlignment = Alignment.CenterHorizontally - ) { + Scaffold(topBar = { + TopAppBar( + title = { + Text("MyCloset", modifier = Modifier.padding(2.dp)) + }, + actions = { + IconButton( + onClick = { LoginAppRouter.navigateTo(Screen.HomeScreen) } + ) { + Icon(Icons.Default.Home, contentDescription = "Camera") + } + } + ) + }) { innerPadding -> + // AndroidView to display the camera preview + AndroidView(factory = { context -> + PreviewView(context).apply { + layoutParams = LinearLayout.LayoutParams( + ViewGroup.LayoutParams.MATCH_PARENT, + ViewGroup.LayoutParams.MATCH_PARENT + ) + scaleType = PreviewView.ScaleType.FILL_START + implementationMode = PreviewView.ImplementationMode.COMPATIBLE + this.controller = cameraController + } + }) + // Column to organize UI elements vertically with space between them Column( modifier = Modifier - .fillMaxHeight(), - verticalArrangement = Arrangement.SpaceBetween, + .fillMaxHeight() + .padding(innerPadding) + .padding(16.dp), + verticalArrangement = Arrangement.Bottom, horizontalAlignment = Alignment.CenterHorizontally ) { - // Card composable to display barcode information - Card( - colors = CardDefaults.cardColors( - containerColor = MaterialTheme.colorScheme.surfaceVariant, - ), - shape = RoundedCornerShape(10.dp) + Column( + modifier = Modifier + .fillMaxHeight(), + verticalArrangement = Arrangement.SpaceBetween, + horizontalAlignment = Alignment.CenterHorizontally ) { - Column( - modifier = Modifier.padding(16.dp) + + // Card composable to display barcode information + Card( + colors = CardDefaults.cardColors( + containerColor = MaterialTheme.colorScheme.surfaceVariant, + ), + shape = RoundedCornerShape(10.dp) ) { - if (barcode.value.barcode.isNotEmpty()) { - Text(text = "Barcode: ${barcode.value.barcode}") - } else { - Text(text = "Point camera at a barcode") + Column( + modifier = Modifier.padding(16.dp) + ) { + if (barcode.value.barcode.isNotEmpty()) { + Text(text = "Barcode: ${barcode.value.barcode}") + } else { + Text(text = "Point camera at a barcode") + } } } - } - // Row for torch button and search button - Row( - modifier = Modifier.fillMaxWidth(), - horizontalArrangement = Arrangement.SpaceBetween - ) { - - // Button to toggle the torch - Button( - onClick = onTorchButtonClicked, - colors = ButtonDefaults.buttonColors( - containerColor = MaterialTheme.colorScheme.primary, - contentColor = MaterialTheme.colorScheme.onPrimary - ) + // Row for torch button and search button + Row( + modifier = Modifier.fillMaxWidth(), + horizontalArrangement = Arrangement.SpaceBetween ) { - if (torchEnabled.value) { - Icon( - imageVector = Icons.Default.FlashOff, - contentDescription = "Flash off icon" - ) - } else { - Icon( - imageVector = Icons.Default.FlashOn, - contentDescription = "Flash on icon" + // Button to toggle the torch + Button( + onClick = onTorchButtonClicked, + colors = ButtonDefaults.buttonColors( + containerColor = MaterialTheme.colorScheme.primary, + contentColor = MaterialTheme.colorScheme.onPrimary ) + ) { + if (torchEnabled.value) { + Icon( + imageVector = Icons.Default.FlashOff, + contentDescription = "Flash off icon" + ) + + } else { + Icon( + imageVector = Icons.Default.FlashOn, + contentDescription = "Flash on icon" + ) + } } - } - // Button to search for product info - Button(onClick = { - if (barcode.value.barcode.isNotEmpty()) { - isLoading = true - networkResult = null - productViewModel.getInfo(barcode.value.barcode) - showProductInfo = true - } else { - Toast.makeText(context, "No barcode found", Toast.LENGTH_SHORT) - .show() + // Button to search for product info + Button(onClick = { + if (barcode.value.barcode.isNotEmpty()) { + isLoading = true + networkResult = null + productViewModel.getInfo(barcode.value.barcode) + showProductInfo = true + } else { + Toast.makeText(context, "No barcode found", Toast.LENGTH_SHORT) + .show() + } + }) { + Text(text = "Search Product Info") } - }) { - Text(text = "Search Product Info") } } } } } - if (informationProductObject.barcodeNumber!="") { + if (informationProductObject.barcodeNumber != "") { // Display a loading indicator while loading product info if (isLoading) { Column( @@ -197,85 +218,105 @@ fun ProductScanView( } // Display the product information if there is a successful result - if (showProductInfo && informationProductObject.barcodeNumber!="") { + if (showProductInfo && informationProductObject.barcodeNumber != "") { isLoading = false - Column( - modifier = Modifier - .fillMaxSize() - .padding(16.dp) - ) { - - Text( - text = informationProductObject.title, - modifier = Modifier.padding(16.dp) + Scaffold(topBar = { + TopAppBar( + title = { + Text("MyCloset", modifier = Modifier.padding(2.dp)) + }, + actions = { + IconButton( + onClick = { LoginAppRouter.navigateTo(Screen.ProductScanView) } + ) { + Icon(Icons.Default.Camera, contentDescription = "Camera") + } + } ) + }) { innerPadding -> - // Image of the product - ImgDisplay.DisplayPicture(informationProductObject.images) - - LazyColumn( - modifier = Modifier.fillMaxWidth(), - contentPadding = PaddingValues(16.dp) + Column( + modifier = Modifier + .fillMaxSize() + .padding(innerPadding) + .padding(16.dp) ) { - item { - Text( - text = "Product Information", - fontWeight = FontWeight.Bold, - fontSize = 18.sp, - modifier = Modifier.padding(bottom = 8.dp) - ) - } - item { - Text("Barcode: ${informationProductObject.barcodeNumber}") - } + Text( + text = informationProductObject.title, + modifier = Modifier.padding(16.dp) + ) - item { - Text("Model: ${informationProductObject.model}") - } + // Image of the product + ImgDisplay.DisplayPicture(informationProductObject.images) - item { - Text("Category: ${informationProductObject.category}") - } + LazyColumn( + modifier = Modifier.fillMaxWidth(), + contentPadding = PaddingValues(16.dp) + ) { + item { + Text( + text = "Product Information", + fontWeight = FontWeight.Bold, + fontSize = 18.sp, + modifier = Modifier.padding(bottom = 8.dp) + ) + } - item { - Text("Brand: ${informationProductObject.brand}") - } + item { + Text("Barcode: ${informationProductObject.barcodeNumber}") + } - item { - Text("Color: ${informationProductObject.color}") - } + item { + Text("Model: ${informationProductObject.model}") + } - item { - Text("Material: ${informationProductObject.material}") - } + item { + Text("Category: ${informationProductObject.category}") + } - item { - Text("Size: ${informationProductObject.size}") - } - } - } - // Buttons for cancel and add actions - Row( - modifier = Modifier.fillMaxWidth(), - horizontalArrangement = Arrangement.SpaceBetween - ) { - Button(onClick = { - showProductInfo = false - }) { - Text(text = "Back") + item { + Text("Brand: ${informationProductObject.brand}") + } + + item { + Text("Color: ${informationProductObject.color}") + } + + item { + Text("Material: ${informationProductObject.material}") + } + + item { + Text("Size: ${informationProductObject.size}") + } } - if(LoggedUser.loggedUserEmail!=""){ + // Buttons for cancel and add actions + Row( + modifier = Modifier.fillMaxWidth(), + horizontalArrangement = Arrangement.SpaceBetween + ) { Button(onClick = { - productViewModel.saveToDatabase(informationProductObject) - Toast.makeText(context, "Item added!", Toast.LENGTH_SHORT).show() - LoginAppRouter.navigateTo(Screen.HomeScreen) + showProductInfo = false }) { - Text(text = "Add") - } - }else{ - Log.i("LOGIN_ERROR","You can't add a new item to your wardrobe because you aren't logged") + Text(text = "Back") + } + if (LoggedUser.loggedUserEmail != "") { + Button(onClick = { + productViewModel.saveToDatabase(informationProductObject) + Toast.makeText(context, "Item added!", Toast.LENGTH_SHORT).show() + LoginAppRouter.navigateTo(Screen.HomeScreen) + }) { + Text(text = "Add") + } + } else { + Log.i( + "LOGIN_ERROR", + "You can't add a new item to your wardrobe because you aren't logged" + ) + } } } } } +} diff --git a/app/src/main/java/com/example/mycloset/Views/SingleItemScreen.kt b/app/src/main/java/com/example/mycloset/Views/SingleItemScreen.kt index 886f630..71ca79e 100644 --- a/app/src/main/java/com/example/mycloset/Views/SingleItemScreen.kt +++ b/app/src/main/java/com/example/mycloset/Views/SingleItemScreen.kt @@ -3,14 +3,14 @@ package com.example.mycloset.Views import android.widget.Toast import androidx.compose.foundation.layout.Arrangement import androidx.compose.foundation.layout.Column -import androidx.compose.foundation.layout.PaddingValues import androidx.compose.foundation.layout.Row import androidx.compose.foundation.layout.Spacer 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.lazy.LazyColumn +import androidx.compose.foundation.lazy.grid.GridCells +import androidx.compose.foundation.lazy.grid.LazyVerticalGrid import androidx.compose.material.icons.Icons import androidx.compose.material.icons.filled.ArrowBack import androidx.compose.material.icons.filled.Camera @@ -27,13 +27,10 @@ import androidx.compose.runtime.getValue import androidx.compose.runtime.rememberUpdatedState import androidx.compose.ui.Modifier import androidx.compose.ui.platform.LocalContext -import androidx.compose.ui.text.font.FontWeight import androidx.compose.ui.unit.dp -import androidx.compose.ui.unit.sp import androidx.lifecycle.viewmodel.compose.viewModel -import com.example.mycloset.ApiWorkingSet.ImgDisplay.Companion.DisplayPicture -import com.example.mycloset.LoginWorkingSet.Signup.SignupViewModel import com.example.mycloset.DatabaseWorkingset.ProductViewModel +import com.example.mycloset.LoginWorkingSet.Signup.SignupViewModel import com.example.mycloset.navigation.LoginAppRouter import com.example.mycloset.navigation.Screen @@ -42,6 +39,8 @@ import com.example.mycloset.navigation.Screen fun SingleItemScreen(productViewModel: ProductViewModel) { var viewModel: SignupViewModel = viewModel() val informationProductObject by rememberUpdatedState(newValue = productViewModel.informationProductObject) + productViewModel.getProductWithBarcode(productViewModel.selectedProduct) + val products = productViewModel.products val context = LocalContext.current Scaffold( @@ -49,7 +48,7 @@ fun SingleItemScreen(productViewModel: ProductViewModel) { // TopAppBar (the top bar) TopAppBar( navigationIcon = { - IconButton(onClick = { }) { + IconButton(onClick = { LoginAppRouter.navigateTo(Screen.HomeScreen) }) { Icon( Icons.Default.ArrowBack, contentDescription = "Back" @@ -60,7 +59,7 @@ fun SingleItemScreen(productViewModel: ProductViewModel) { Text("MyCloset") }, actions = { - IconButton(onClick = { /* Handle camera navigation here */ }) { + IconButton(onClick = { LoginAppRouter.navigateTo(Screen.ProductScanView) }) { Icon( Icons.Default.Camera, contentDescription = "Camera" @@ -84,84 +83,53 @@ fun SingleItemScreen(productViewModel: ProductViewModel) { .padding(16.dp) ) { - DisplayPicture(informationProductObject.images) + //DisplayPicture(informationProductObject.images) Spacer(modifier = Modifier.height(24.dp)) - LazyColumn( - modifier = Modifier.fillMaxWidth(), - contentPadding = PaddingValues(16.dp) + LazyVerticalGrid( + columns = GridCells.Fixed(2), modifier = Modifier + .fillMaxSize() + .padding(16.dp) ) { - item { - Text( - text = "Product Information", - fontWeight = FontWeight.Bold, - fontSize = 18.sp, - modifier = Modifier.padding(bottom = 8.dp) - ) - } - - item { - Text("Barcode: ${informationProductObject.barcodeNumber}") - } - - item { - Text("Model: ${informationProductObject.model}") - } - - item { - Text("Category: ${informationProductObject.category}") - } - - item { - Text("Brand: ${informationProductObject.brand}") - } - - item { - Text("Color: ${informationProductObject.color}") - } - - item { - Text("Material: ${informationProductObject.material}") - } - - item { - Text("Size: ${informationProductObject.size}") + items(products.size) { index -> + val product = products[index] + ItemCard(product.images, product.title, product.barcodeNumber, productViewModel) } - } + Spacer(modifier = Modifier.height(16.dp)) - Spacer(modifier = Modifier.height(16.dp)) - - // Add more text components or other content as needed - Row( - modifier = Modifier - .fillMaxWidth() - .padding(16.dp), - horizontalArrangement = Arrangement.Center - ) { - Button( - onClick = { - productViewModel.deleteProduct(informationProductObject) - Toast.makeText(context, "Item Delated!", Toast.LENGTH_SHORT).show() - LoginAppRouter.navigateTo(Screen.HomeScreen) - } + // Add more text components or other content as needed + Row( + modifier = Modifier + .fillMaxWidth() + .padding(16.dp), + horizontalArrangement = Arrangement.Center ) { - Text("Delete Item") - } - Button( - onClick = { + Button( + onClick = { + //productViewModel.deleteProduct(informationProductObject) + Toast.makeText(context, "Item Deleted!", Toast.LENGTH_SHORT).show() + LoginAppRouter.navigateTo(Screen.HomeScreen) + } + ) { + Text("Delete Item") + } + Button( + onClick = { + } + ) { + Text("Update Item") } - ) { - Text("Update Item") } } } } -} + + /*@Composable @Preview From 19001c2d6e5f6a5845821b5894a5fad84d3f1dbd Mon Sep 17 00:00:00 2001 From: matti Date: Thu, 12 Oct 2023 15:21:51 +0200 Subject: [PATCH 17/32] Delate doesn't work --- .../example/mycloset/App/LoginPreviewApp.kt | 4 + .../OfflineProductRepository.kt | 6 +- .../mycloset/DatabaseWorkingset/ProductDao.kt | 3 + .../DatabaseWorkingset/ProductDatabase.kt | 2 +- .../DatabaseWorkingset/ProductEntity.kt | 4 +- .../DatabaseWorkingset/ProductRepository.kt | 2 +- .../DatabaseWorkingset/ProductViewModel.kt | 51 +++---- .../com/example/mycloset/Views/HomeScreen.kt | 2 +- .../com/example/mycloset/Views/ItemCard.kt | 13 +- .../mycloset/Views/SingleItemScreen.kt | 22 +-- .../mycloset/Views/UpdateSingleItem.kt | 130 ++++++++---------- .../com/example/mycloset/navigation/Screen.kt | 1 + 12 files changed, 116 insertions(+), 124 deletions(-) diff --git a/app/src/main/java/com/example/mycloset/App/LoginPreviewApp.kt b/app/src/main/java/com/example/mycloset/App/LoginPreviewApp.kt index 488d46d..1c539c0 100644 --- a/app/src/main/java/com/example/mycloset/App/LoginPreviewApp.kt +++ b/app/src/main/java/com/example/mycloset/App/LoginPreviewApp.kt @@ -16,6 +16,7 @@ import com.example.mycloset.Views.LoginScreen import com.example.mycloset.Views.ProductScanView import com.example.mycloset.Views.SignUpScreen import com.example.mycloset.Views.SingleItemScreen +import com.example.mycloset.Views.UpdateSingleItem import com.example.mycloset.navigation.LoginAppRouter import com.example.mycloset.navigation.Screen @@ -56,6 +57,9 @@ fun LoginApp(cameraController: LifecycleCameraController){ is Screen.SingleItemScreen ->{ SingleItemScreen(productViewModel) } + is Screen.UpdateSingleScreen->{ + UpdateSingleItem(productViewModel) + } } } diff --git a/app/src/main/java/com/example/mycloset/DatabaseWorkingset/OfflineProductRepository.kt b/app/src/main/java/com/example/mycloset/DatabaseWorkingset/OfflineProductRepository.kt index 6251878..9e3d9dc 100644 --- a/app/src/main/java/com/example/mycloset/DatabaseWorkingset/OfflineProductRepository.kt +++ b/app/src/main/java/com/example/mycloset/DatabaseWorkingset/OfflineProductRepository.kt @@ -1,11 +1,13 @@ package com.example.mycloset.DatabaseWorkingset -class OfflineProductRepository(private val productDao: ProductDao) : ProductRepository { - override fun getAllProductsStream() = productDao.getAllProducts() +import androidx.room.Query +import kotlinx.coroutines.flow.Flow +class OfflineProductRepository(private val productDao: ProductDao) : ProductRepository { override fun getAllProductsWithEmailStream(userEmail: String) = productDao.getProductsWithEmail(userEmail) override suspend fun updateProductDetailsStream(product: ProductEntity) =productDao.updateProductDetails(product) override suspend fun deleteProductStream(product: ProductEntity) =productDao.deleteProduct(product) + override fun getSingleProductStream(barcode:String,userEmail: String)=productDao.getSingleProduct(barcode,userEmail) } \ No newline at end of file diff --git a/app/src/main/java/com/example/mycloset/DatabaseWorkingset/ProductDao.kt b/app/src/main/java/com/example/mycloset/DatabaseWorkingset/ProductDao.kt index 3217455..3de02f2 100644 --- a/app/src/main/java/com/example/mycloset/DatabaseWorkingset/ProductDao.kt +++ b/app/src/main/java/com/example/mycloset/DatabaseWorkingset/ProductDao.kt @@ -21,6 +21,9 @@ interface ProductDao { @Query("SELECT * from products WHERE userEmail = :userEmail") fun getProductsWithEmail(userEmail: String): Flow> + //Get single product + @Query("SELECT * from products WHERE userEmail = :userEmail AND barcodeNumber=:barcode") + fun getSingleProduct(barcode:String,userEmail: String): ProductEntity @Update suspend fun updateProductDetails(product: ProductEntity) diff --git a/app/src/main/java/com/example/mycloset/DatabaseWorkingset/ProductDatabase.kt b/app/src/main/java/com/example/mycloset/DatabaseWorkingset/ProductDatabase.kt index 5146378..abd39f0 100644 --- a/app/src/main/java/com/example/mycloset/DatabaseWorkingset/ProductDatabase.kt +++ b/app/src/main/java/com/example/mycloset/DatabaseWorkingset/ProductDatabase.kt @@ -6,7 +6,7 @@ import androidx.room.Room import androidx.room.RoomDatabase -@Database(entities = [ProductEntity::class], version = 2, exportSchema = false) +@Database(entities = [ProductEntity::class], version = 3, exportSchema = false) abstract class ProductDatabase : RoomDatabase() { abstract fun productDao(): ProductDao diff --git a/app/src/main/java/com/example/mycloset/DatabaseWorkingset/ProductEntity.kt b/app/src/main/java/com/example/mycloset/DatabaseWorkingset/ProductEntity.kt index 6090606..3e71d65 100644 --- a/app/src/main/java/com/example/mycloset/DatabaseWorkingset/ProductEntity.kt +++ b/app/src/main/java/com/example/mycloset/DatabaseWorkingset/ProductEntity.kt @@ -3,9 +3,9 @@ package com.example.mycloset.DatabaseWorkingset import androidx.room.Entity import androidx.room.PrimaryKey -@Entity(tableName = "products") +@Entity(tableName = "products",primaryKeys = ["barcodeNumber", "userEmail"]) data class ProductEntity( - @PrimaryKey val barcodeNumber: String, + val barcodeNumber: String, val userEmail: String, val model: String, val title: String, diff --git a/app/src/main/java/com/example/mycloset/DatabaseWorkingset/ProductRepository.kt b/app/src/main/java/com/example/mycloset/DatabaseWorkingset/ProductRepository.kt index d9199e2..e18f42e 100644 --- a/app/src/main/java/com/example/mycloset/DatabaseWorkingset/ProductRepository.kt +++ b/app/src/main/java/com/example/mycloset/DatabaseWorkingset/ProductRepository.kt @@ -4,8 +4,8 @@ import kotlinx.coroutines.flow.Flow // Repository that provides insert, update, delete, and retrieve of [Product] from a given data source. interface ProductRepository { - fun getAllProductsStream(): Flow> fun getAllProductsWithEmailStream(userEmail: String): Flow> suspend fun updateProductDetailsStream(product: ProductEntity) suspend fun deleteProductStream(product: ProductEntity) + fun getSingleProductStream(barcode:String,userEmail: String):ProductEntity } \ No newline at end of file diff --git a/app/src/main/java/com/example/mycloset/DatabaseWorkingset/ProductViewModel.kt b/app/src/main/java/com/example/mycloset/DatabaseWorkingset/ProductViewModel.kt index e4e8b29..ecf4744 100644 --- a/app/src/main/java/com/example/mycloset/DatabaseWorkingset/ProductViewModel.kt +++ b/app/src/main/java/com/example/mycloset/DatabaseWorkingset/ProductViewModel.kt @@ -11,6 +11,7 @@ import com.example.mycloset.ApiWorkingSet.RetrofitObject import com.example.mycloset.BarcodeWorkingSet.BarcodeRepository import com.example.mycloset.LoginWorkingSet.LoggedUser import kotlinx.coroutines.Dispatchers +import kotlinx.coroutines.flow.Flow import kotlinx.coroutines.launch //view-model used for the take the information about one product from its barcode @@ -20,6 +21,10 @@ class ProductViewModel(val productDao: ProductDao, val productRepository: Produc var informationProductObject by mutableStateOf(ProductObject("","","","","", "", "","","","")) var products by mutableStateOf(emptyList()) + var singleProduct by mutableStateOf(ProductEntity( + "","","","","", "", "","","","")) + + fun saveToDatabase( obj:ProductObject ) { @@ -30,16 +35,7 @@ class ProductViewModel(val productDao: ProductDao, val productRepository: Produc } } - // Get all products - fun getProducts() { - viewModelScope.launch { - productRepository.getAllProductsStream().collect() { response -> - products = response - } - } - } - - // Get products with logged in email + // Get all the products from an account fun getProductsWithEmail(userEmail: String) { viewModelScope.launch { productRepository.getAllProductsWithEmailStream(userEmail).collect() { response -> @@ -50,6 +46,12 @@ class ProductViewModel(val productDao: ProductDao, val productRepository: Produc } } + // Get a single product from an account + fun getSingleProduct(barcode:String,userEmail: String) { + viewModelScope.launch { + singleProduct=productRepository.getSingleProductStream(barcode,userEmail) + } + } //update fun updateProductDetails(product:ProductEntity){ viewModelScope.launch { @@ -60,8 +62,8 @@ class ProductViewModel(val productDao: ProductDao, val productRepository: Produc //delete fun deleteProduct(obj:ProductObject){ viewModelScope.launch { - productRepository.deleteProductStream(ProductEntity(obj.barcodeNumber,obj.userEmail,obj.model,obj.title,obj.category,obj.brand,obj.color,obj.material,obj.size,obj.images) - ) + productRepository.deleteProductStream(singleProduct) + } } @@ -80,18 +82,21 @@ class ProductViewModel(val productDao: ProductDao, val productRepository: Produc } } } - +data class SelectedObject( + val barcodeNumber:String, + val userEmail: String +) data class ProductObject( -val barcodeNumber: String, -val userEmail: String, -val model: String, -val title: String, -val category: String, -val brand: String, -val color: String, -val material: String, -val size: String, -val images: String + val barcodeNumber: String, + val userEmail: String, + val model: String, + val title: String, + val category: String, + val brand: String, + val color: String, + val material: String, + val size: String, + val images: String ) //Function for convert from the Api result to a map with all the information about a product diff --git a/app/src/main/java/com/example/mycloset/Views/HomeScreen.kt b/app/src/main/java/com/example/mycloset/Views/HomeScreen.kt index b8bd6b9..0fe91a6 100644 --- a/app/src/main/java/com/example/mycloset/Views/HomeScreen.kt +++ b/app/src/main/java/com/example/mycloset/Views/HomeScreen.kt @@ -106,7 +106,7 @@ fun HomeScreen(productViewModel: ProductViewModel) { ) { items(products.size) { index -> val product = products[index] - ItemCard(product.images, product.title) + ItemCard(product.images, product.title,product.barcodeNumber,product.userEmail,productViewModel) } } } diff --git a/app/src/main/java/com/example/mycloset/Views/ItemCard.kt b/app/src/main/java/com/example/mycloset/Views/ItemCard.kt index 35176e3..7cd361e 100644 --- a/app/src/main/java/com/example/mycloset/Views/ItemCard.kt +++ b/app/src/main/java/com/example/mycloset/Views/ItemCard.kt @@ -15,18 +15,19 @@ import androidx.compose.ui.Modifier import androidx.compose.ui.tooling.preview.Preview import androidx.compose.ui.unit.dp import coil.compose.rememberAsyncImagePainter +import com.example.mycloset.DatabaseWorkingset.ProductViewModel import com.example.mycloset.navigation.LoginAppRouter import com.example.mycloset.navigation.Screen -data class Item(val id: Int, val title: String, val imageUrl: String) - @OptIn(ExperimentalMaterial3Api::class) @Composable fun ItemCard( imageUrl: String?, name: String?, -// onClick: () -> Unit + barcode:String, + userEmail:String, + productViewModel: ProductViewModel ) { Card( colors = CardDefaults.cardColors( @@ -51,9 +52,3 @@ fun ItemCard( - -@Preview -@Composable -fun MyPrev() { - ItemCard("https://media.istockphoto.com/id/1303978937/fi/valokuva/valkoinen-lenkkari-sinisell%C3%A4-kaltevuustaustalla-miesten-muoti-urheilukenk%C3%A4-lenkkarit.jpg?s=612x612&w=0&k=20&c=X_lwi6td_xtFUGXjOmAU8WzH-MKPZ-OeWKtKUshe-SI=", "nike") -} diff --git a/app/src/main/java/com/example/mycloset/Views/SingleItemScreen.kt b/app/src/main/java/com/example/mycloset/Views/SingleItemScreen.kt index 886f630..b11fcd4 100644 --- a/app/src/main/java/com/example/mycloset/Views/SingleItemScreen.kt +++ b/app/src/main/java/com/example/mycloset/Views/SingleItemScreen.kt @@ -32,6 +32,7 @@ import androidx.compose.ui.unit.dp import androidx.compose.ui.unit.sp import androidx.lifecycle.viewmodel.compose.viewModel import com.example.mycloset.ApiWorkingSet.ImgDisplay.Companion.DisplayPicture +import com.example.mycloset.AppViewModelProvider import com.example.mycloset.LoginWorkingSet.Signup.SignupViewModel import com.example.mycloset.DatabaseWorkingset.ProductViewModel import com.example.mycloset.navigation.LoginAppRouter @@ -41,7 +42,8 @@ import com.example.mycloset.navigation.Screen @Composable fun SingleItemScreen(productViewModel: ProductViewModel) { var viewModel: SignupViewModel = viewModel() - val informationProductObject by rememberUpdatedState(newValue = productViewModel.informationProductObject) + val singleProduct by rememberUpdatedState(newValue = productViewModel.singleProduct) + val context = LocalContext.current Scaffold( @@ -84,7 +86,7 @@ fun SingleItemScreen(productViewModel: ProductViewModel) { .padding(16.dp) ) { - DisplayPicture(informationProductObject.images) + DisplayPicture(singleProduct.images) Spacer(modifier = Modifier.height(24.dp)) @@ -103,31 +105,31 @@ fun SingleItemScreen(productViewModel: ProductViewModel) { } item { - Text("Barcode: ${informationProductObject.barcodeNumber}") + Text("Barcode: ${singleProduct.barcodeNumber}") } item { - Text("Model: ${informationProductObject.model}") + Text("Model: ${singleProduct.model}") } item { - Text("Category: ${informationProductObject.category}") + Text("Category: ${singleProduct.category}") } item { - Text("Brand: ${informationProductObject.brand}") + Text("Brand: ${singleProduct.brand}") } item { - Text("Color: ${informationProductObject.color}") + Text("Color: ${singleProduct.color}") } item { - Text("Material: ${informationProductObject.material}") + Text("Material: ${singleProduct.material}") } item { - Text("Size: ${informationProductObject.size}") + Text("Size: ${singleProduct.size}") } } @@ -144,7 +146,7 @@ fun SingleItemScreen(productViewModel: ProductViewModel) { ) { Button( onClick = { - productViewModel.deleteProduct(informationProductObject) + //productViewModel.deleteProduct(singleProduct) Toast.makeText(context, "Item Delated!", Toast.LENGTH_SHORT).show() LoginAppRouter.navigateTo(Screen.HomeScreen) } diff --git a/app/src/main/java/com/example/mycloset/Views/UpdateSingleItem.kt b/app/src/main/java/com/example/mycloset/Views/UpdateSingleItem.kt index dabc0ed..02d7d1d 100644 --- a/app/src/main/java/com/example/mycloset/Views/UpdateSingleItem.kt +++ b/app/src/main/java/com/example/mycloset/Views/UpdateSingleItem.kt @@ -24,6 +24,7 @@ import androidx.compose.material3.Icon import androidx.compose.material3.IconButton import androidx.compose.material3.Scaffold import androidx.compose.material3.Text +import androidx.compose.material3.TextField import androidx.compose.material3.TopAppBar import androidx.compose.runtime.Composable import androidx.compose.runtime.getValue @@ -53,20 +54,20 @@ import com.example.mycloset.navigation.LoginAppRouter import com.example.mycloset.navigation.Screen import kotlinx.coroutines.flow.StateFlow -/* -@OptIn(ExperimentalMaterial3Api::class, ExperimentalMaterial3Api::class) + +@OptIn(ExperimentalMaterial3Api::class) @Composable -fun SingleItemScreen(productViewModel: ProductViewModel) { - var viewModel: SignupViewModel = viewModel() - val informationProductObject by rememberUpdatedState(newValue = productViewModel.informationProductObject) +fun UpdateSingleItem( + productViewModel: ProductViewModel, +) { + var editedProduct by remember { mutableStateOf(productViewModel.singleProduct.copy()) } val context = LocalContext.current - Scaffold( topBar = { // TopAppBar (the top bar) TopAppBar( navigationIcon = { - IconButton(onClick = { }) { + IconButton(onClick = { onBack() }) { Icon( Icons.Default.ArrowBack, contentDescription = "Back" @@ -74,85 +75,65 @@ fun SingleItemScreen(productViewModel: ProductViewModel) { } }, title = { - Text("MyCloset") - }, - actions = { - IconButton(onClick = { /* Handle camera navigation here */ }) { - Icon( - Icons.Default.Camera, - contentDescription = "Camera" - ) - } - IconButton( - onClick = { - viewModel.logout() - } - ) { - Icon(Icons.Default.Logout, contentDescription = "Logout") - } + Text("Edit Product") } ) } ) { padding -> - // Content to be displayed below the top bar Column( modifier = Modifier .fillMaxSize() .padding(16.dp) ) { - - DisplayPicture(informationProductObject.images) + DisplayPicture(editedProduct.images) Spacer(modifier = Modifier.height(24.dp)) + Text( + text = "Edit Product Information", + fontWeight = FontWeight.Bold, + fontSize = 18.sp, + modifier = Modifier.padding(bottom = 8.dp) + ) - LazyColumn( - modifier = Modifier.fillMaxWidth(), - contentPadding = PaddingValues(16.dp) - ) { - item { - Text( - text = "Product Information", - fontWeight = FontWeight.Bold, - fontSize = 18.sp, - modifier = Modifier.padding(bottom = 8.dp) - ) - } - - item { - Text("Barcode: ${informationProductObject.barcodeNumber}") - } - - item { - Text("Model: ${informationProductObject.model}") - } - - item { - Text("Category: ${informationProductObject.category}") - } - - item { - Text("Brand: ${informationProductObject.brand}") - } + TextField( + value = editedProduct.model, + onValueChange = { editedProduct.model = it }, + label = { Text("Model") } + ) - item { - Text("Color: ${informationProductObject.color}") - } + TextField( + value = editedProduct.category, + onValueChange = { editedProduct.category = it }, + label = { Text("Category") } + ) - item { - Text("Material: ${informationProductObject.material}") - } + TextField( + value = editedProduct.brand, + onValueChange = { editedProduct.brand = it }, + label = { Text("Brand") } + ) - item { - Text("Size: ${informationProductObject.size}") - } + TextField( + value = editedProduct.color, + onValueChange = { editedProduct.color = it }, + label = { Text("Color") } + ) - } + TextField( + value = editedProduct.material, + onValueChange = { editedProduct.material = it }, + label = { Text("Material") } + ) + TextField( + value = editedProduct.size, + onValueChange = { editedProduct.size = it }, + label = { Text("Size") } + ) Spacer(modifier = Modifier.height(16.dp)) - // Add more text components or other content as needed Row( modifier = Modifier .fillMaxWidth() @@ -160,23 +141,22 @@ fun SingleItemScreen(productViewModel: ProductViewModel) { horizontalArrangement = Arrangement.Center ) { Button( - onClick = { - productViewModel.deleteProduct(informationProductObject) - Toast.makeText(context, "Item Delated!", Toast.LENGTH_SHORT).show() - LoginAppRouter.navigateTo(Screen.HomeScreen) - } + onClick = {LoginAppRouter.navigateTo(Screen.SingleItemScreen) } ) { - Text("Delete Item") + Text("Cancel") } Button( onClick = { - + // Save the edited product + productViewModel.updateProductDetails(editedProduct) + Toast.makeText(context, "Item Delated!", Toast.LENGTH_SHORT).show() + LoginAppRouter.navigateTo(Screen.SingleItemScreen) } ) { - Text("Update Item") + Text("Save") } + } } } -} -*/ \ No newline at end of file +} \ No newline at end of file diff --git a/app/src/main/java/com/example/mycloset/navigation/Screen.kt b/app/src/main/java/com/example/mycloset/navigation/Screen.kt index cb6f976..45c25cd 100644 --- a/app/src/main/java/com/example/mycloset/navigation/Screen.kt +++ b/app/src/main/java/com/example/mycloset/navigation/Screen.kt @@ -9,6 +9,7 @@ sealed class Screen(){ object HomeScreen : Screen() object ProductScanView : Screen() object SingleItemScreen : Screen() + object UpdateSingleScreen : Screen() } object LoginAppRouter{ From b4ae8452fc06f7e1e6c42659337ceb414a26795d Mon Sep 17 00:00:00 2001 From: Liideli Date: Thu, 12 Oct 2023 17:15:45 +0300 Subject: [PATCH 18/32] In progress Yes. --- .../OfflineProductRepository.kt | 4 +- .../mycloset/DatabaseWorkingset/ProductDao.kt | 5 +- .../DatabaseWorkingset/ProductRepository.kt | 2 +- .../DatabaseWorkingset/ProductViewModel.kt | 7 +- .../com/example/mycloset/Views/ItemCard.kt | 2 +- .../example/mycloset/Views/ProductScanView.kt | 2 + .../mycloset/Views/SingleItemScreen.kt | 105 ++++++++++++------ 7 files changed, 83 insertions(+), 44 deletions(-) diff --git a/app/src/main/java/com/example/mycloset/DatabaseWorkingset/OfflineProductRepository.kt b/app/src/main/java/com/example/mycloset/DatabaseWorkingset/OfflineProductRepository.kt index 3a052df..796b736 100644 --- a/app/src/main/java/com/example/mycloset/DatabaseWorkingset/OfflineProductRepository.kt +++ b/app/src/main/java/com/example/mycloset/DatabaseWorkingset/OfflineProductRepository.kt @@ -8,8 +8,8 @@ class OfflineProductRepository(private val productDao: ProductDao) : ProductRepo override fun getAllProductWithBarcodeStream(barcodeNumber: String) = productDao.getProductWithBarcode(barcodeNumber) // override fun getAllProductWithBarcodeStream(barcodeNumber: String ,userEmail: String)=productDao.getProductWithBarcode(barcodeNumber, userEmail) - override suspend fun updateProductDetailsStream(product: ProductEntity) =productDao.updateProductDetails(product) + override suspend fun updateProductDetailsStream(product: ProductEntity) = productDao.updateProductDetails(product) - //override suspend fun deleteProductStream(product: ProductEntity) =productDao.deleteProduct(product) + override suspend fun deleteProductStream(barcodeNumber: String) = productDao.deleteProduct(barcodeNumber) } \ No newline at end of file diff --git a/app/src/main/java/com/example/mycloset/DatabaseWorkingset/ProductDao.kt b/app/src/main/java/com/example/mycloset/DatabaseWorkingset/ProductDao.kt index 6bf044a..1b712ca 100644 --- a/app/src/main/java/com/example/mycloset/DatabaseWorkingset/ProductDao.kt +++ b/app/src/main/java/com/example/mycloset/DatabaseWorkingset/ProductDao.kt @@ -26,6 +26,7 @@ interface ProductDao { @Update suspend fun updateProductDetails(product: ProductEntity) - /*@Query("DELETE FROM products WHERE barcodeNumber = :barcodeNumber") - suspend fun deleteProduct(product: ProductEntity)*/ + //@Query("DELETE FROM products WHERE barcodeNumber = :barcodeNumber") + @Query("DELETE FROM products WHERE barcodeNumber = :barcodeNumber") + suspend fun deleteProduct(barcodeNumber: String) } diff --git a/app/src/main/java/com/example/mycloset/DatabaseWorkingset/ProductRepository.kt b/app/src/main/java/com/example/mycloset/DatabaseWorkingset/ProductRepository.kt index 825228d..3f8aa3a 100644 --- a/app/src/main/java/com/example/mycloset/DatabaseWorkingset/ProductRepository.kt +++ b/app/src/main/java/com/example/mycloset/DatabaseWorkingset/ProductRepository.kt @@ -9,5 +9,5 @@ interface ProductRepository { fun getAllProductWithBarcodeStream(barcodeNumber: String): Flow> // fun getAllProductWithBarcodeStream(barcodeNumber: String, userEmail: String):ProductEntity suspend fun updateProductDetailsStream(product: ProductEntity) - //suspend fun deleteProductStream(product: ProductEntity) + suspend fun deleteProductStream(barcodeNumber: String) } \ No newline at end of file diff --git a/app/src/main/java/com/example/mycloset/DatabaseWorkingset/ProductViewModel.kt b/app/src/main/java/com/example/mycloset/DatabaseWorkingset/ProductViewModel.kt index 4a3ab44..9a75a18 100644 --- a/app/src/main/java/com/example/mycloset/DatabaseWorkingset/ProductViewModel.kt +++ b/app/src/main/java/com/example/mycloset/DatabaseWorkingset/ProductViewModel.kt @@ -72,12 +72,11 @@ class ProductViewModel(val productDao: ProductDao, val productRepository: Produc } //delete - /*fun deleteProduct(obj:ProductObject){ + fun deleteProduct(barcodeNumber: String){ viewModelScope.launch { - productRepository.deleteProductStream(ProductEntity(obj.barcodeNumber,obj.userEmail,obj.model,obj.title,obj.category,obj.brand,obj.color,obj.material,obj.size,obj.images) - ) + productRepository.deleteProductStream(barcodeNumber) } - }*/ + } //the result will be an array of strings fun getInfo(barcode: String) { diff --git a/app/src/main/java/com/example/mycloset/Views/ItemCard.kt b/app/src/main/java/com/example/mycloset/Views/ItemCard.kt index eefaee3..cb60206 100644 --- a/app/src/main/java/com/example/mycloset/Views/ItemCard.kt +++ b/app/src/main/java/com/example/mycloset/Views/ItemCard.kt @@ -37,7 +37,7 @@ fun ItemCard( modifier = Modifier.padding(5.dp), shape = RoundedCornerShape(10.dp), onClick = { - productViewModel.setSelectedProduct(barcodeNumber) + productViewModel.setSelectedProduct(barcodeNumber) LoginAppRouter.navigateTo(Screen.SingleItemScreen) } ) { diff --git a/app/src/main/java/com/example/mycloset/Views/ProductScanView.kt b/app/src/main/java/com/example/mycloset/Views/ProductScanView.kt index 29e3c9f..2c0eada 100644 --- a/app/src/main/java/com/example/mycloset/Views/ProductScanView.kt +++ b/app/src/main/java/com/example/mycloset/Views/ProductScanView.kt @@ -88,6 +88,8 @@ fun ProductScanView( val context = LocalContext.current + val topAppBarColor = MaterialTheme.colorScheme.onTertiary + if (!showProductInfo) { Scaffold(topBar = { TopAppBar( diff --git a/app/src/main/java/com/example/mycloset/Views/SingleItemScreen.kt b/app/src/main/java/com/example/mycloset/Views/SingleItemScreen.kt index 71ca79e..2dc0398 100644 --- a/app/src/main/java/com/example/mycloset/Views/SingleItemScreen.kt +++ b/app/src/main/java/com/example/mycloset/Views/SingleItemScreen.kt @@ -3,14 +3,14 @@ package com.example.mycloset.Views import android.widget.Toast import androidx.compose.foundation.layout.Arrangement import androidx.compose.foundation.layout.Column +import androidx.compose.foundation.layout.PaddingValues import androidx.compose.foundation.layout.Row import androidx.compose.foundation.layout.Spacer 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.lazy.grid.GridCells -import androidx.compose.foundation.lazy.grid.LazyVerticalGrid +import androidx.compose.foundation.lazy.LazyColumn import androidx.compose.material.icons.Icons import androidx.compose.material.icons.filled.ArrowBack import androidx.compose.material.icons.filled.Camera @@ -25,10 +25,14 @@ import androidx.compose.material3.TopAppBar import androidx.compose.runtime.Composable import androidx.compose.runtime.getValue import androidx.compose.runtime.rememberUpdatedState +import androidx.compose.ui.Alignment import androidx.compose.ui.Modifier import androidx.compose.ui.platform.LocalContext +import androidx.compose.ui.text.font.FontWeight import androidx.compose.ui.unit.dp +import androidx.compose.ui.unit.sp import androidx.lifecycle.viewmodel.compose.viewModel +import com.example.mycloset.ApiWorkingSet.ImgDisplay.Companion.DisplayPicture import com.example.mycloset.DatabaseWorkingset.ProductViewModel import com.example.mycloset.LoginWorkingSet.Signup.SignupViewModel import com.example.mycloset.navigation.LoginAppRouter @@ -75,60 +79,93 @@ fun SingleItemScreen(productViewModel: ProductViewModel) { } ) } - ) { padding -> + ) { innerPadding -> // Content to be displayed below the top bar Column( modifier = Modifier .fillMaxSize() + .padding(innerPadding) .padding(16.dp) ) { + val product = products[0] - //DisplayPicture(informationProductObject.images) + Column(modifier = Modifier.fillMaxWidth(), horizontalAlignment = Alignment.CenterHorizontally) { + DisplayPicture(product.images) + } Spacer(modifier = Modifier.height(24.dp)) - LazyVerticalGrid( - columns = GridCells.Fixed(2), modifier = Modifier - .fillMaxSize() - .padding(16.dp) + LazyColumn( + modifier = Modifier.fillMaxWidth(), + contentPadding = PaddingValues(16.dp) ) { - items(products.size) { index -> - val product = products[index] - ItemCard(product.images, product.title, product.barcodeNumber, productViewModel) + item { + Text( + text = "Product Information", + fontWeight = FontWeight.Bold, + fontSize = 18.sp, + modifier = Modifier.padding(bottom = 8.dp) + ) } - } - Spacer(modifier = Modifier.height(16.dp)) + item { + Text("Barcode: ${product.barcodeNumber}") + } - // Add more text components or other content as needed - Row( - modifier = Modifier - .fillMaxWidth() - .padding(16.dp), - horizontalArrangement = Arrangement.Center - ) { - Button( - onClick = { - //productViewModel.deleteProduct(informationProductObject) - Toast.makeText(context, "Item Deleted!", Toast.LENGTH_SHORT).show() - LoginAppRouter.navigateTo(Screen.HomeScreen) - } - ) { - Text("Delete Item") + item { + Text("Model: ${product.model}") + } + + item { + Text("Category: ${product.category}") + } + + item { + Text("Brand: ${product.brand}") + } + + item { + Text("Color: ${product.color}") + } + + item { + Text("Material: ${product.material}") + } + + item { + Text("Size: ${product.size}") + } + + } + + // Add more text components or other content as needed + Row( + modifier = Modifier + .fillMaxWidth() + .padding(16.dp), + horizontalArrangement = Arrangement.SpaceBetween + ) { + Button( + onClick = { + productViewModel.deleteProduct(productViewModel.selectedProduct) + Toast.makeText(context, "Item Deleted!", Toast.LENGTH_SHORT).show() + LoginAppRouter.navigateTo(Screen.HomeScreen) } - Button( - onClick = { + ) { + Text("Delete Item") + } + Button( + onClick = { - } - ) { - Text("Update Item") } + ) { + Text("Update Item") } } } } - +} /*@Composable From a8d0148e57f697019eccea0fcb2a7f75c390f42c Mon Sep 17 00:00:00 2001 From: matti Date: Thu, 12 Oct 2023 16:16:13 +0200 Subject: [PATCH 19/32] Delate doesn't work --- .../mycloset/DatabaseWorkingset/ProductViewModel.kt | 10 ++++++---- .../main/java/com/example/mycloset/Views/ItemCard.kt | 1 + .../com/example/mycloset/Views/SingleItemScreen.kt | 1 - .../com/example/mycloset/Views/UpdateSingleItem.kt | 4 ++-- 4 files changed, 9 insertions(+), 7 deletions(-) diff --git a/app/src/main/java/com/example/mycloset/DatabaseWorkingset/ProductViewModel.kt b/app/src/main/java/com/example/mycloset/DatabaseWorkingset/ProductViewModel.kt index 8c73b47..5a5b96f 100644 --- a/app/src/main/java/com/example/mycloset/DatabaseWorkingset/ProductViewModel.kt +++ b/app/src/main/java/com/example/mycloset/DatabaseWorkingset/ProductViewModel.kt @@ -48,12 +48,14 @@ class ProductViewModel(val productDao: ProductDao, val productRepository: Produc } } - // Get a single product from an account - /*fun getSingleProduct(barcode:String,userEmail: String) { + fun getProductWithBarcode(barcodeNumber: String) { viewModelScope.launch { - singleProduct=productRepository.getSingleProductStream(barcode,userEmail) + productRepository.getAllProductWithBarcodeStream(barcodeNumber).collect() { response -> + products = response + } } - }*/ + } + //update fun updateProductDetails(product:ProductEntity){ diff --git a/app/src/main/java/com/example/mycloset/Views/ItemCard.kt b/app/src/main/java/com/example/mycloset/Views/ItemCard.kt index fdc5b40..1763924 100644 --- a/app/src/main/java/com/example/mycloset/Views/ItemCard.kt +++ b/app/src/main/java/com/example/mycloset/Views/ItemCard.kt @@ -15,6 +15,7 @@ import androidx.compose.ui.Modifier import androidx.compose.ui.tooling.preview.Preview import androidx.compose.ui.unit.dp import coil.compose.rememberAsyncImagePainter +import com.example.mycloset.DatabaseWorkingset.ProductViewModel import com.example.mycloset.navigation.LoginAppRouter import com.example.mycloset.navigation.Screen diff --git a/app/src/main/java/com/example/mycloset/Views/SingleItemScreen.kt b/app/src/main/java/com/example/mycloset/Views/SingleItemScreen.kt index 7d0edfd..6b389bc 100644 --- a/app/src/main/java/com/example/mycloset/Views/SingleItemScreen.kt +++ b/app/src/main/java/com/example/mycloset/Views/SingleItemScreen.kt @@ -33,7 +33,6 @@ import com.example.mycloset.ApiWorkingSet.ImgDisplay.Companion.DisplayPicture import com.example.mycloset.AppViewModelProvider import com.example.mycloset.LoginWorkingSet.Signup.SignupViewModel import com.example.mycloset.DatabaseWorkingset.ProductViewModel -import com.example.mycloset.LoginWorkingSet.Signup.SignupViewModel import com.example.mycloset.navigation.LoginAppRouter import com.example.mycloset.navigation.Screen diff --git a/app/src/main/java/com/example/mycloset/Views/UpdateSingleItem.kt b/app/src/main/java/com/example/mycloset/Views/UpdateSingleItem.kt index 02d7d1d..43948cb 100644 --- a/app/src/main/java/com/example/mycloset/Views/UpdateSingleItem.kt +++ b/app/src/main/java/com/example/mycloset/Views/UpdateSingleItem.kt @@ -60,14 +60,14 @@ import kotlinx.coroutines.flow.StateFlow fun UpdateSingleItem( productViewModel: ProductViewModel, ) { - var editedProduct by remember { mutableStateOf(productViewModel.singleProduct.copy()) } + var editedProduct by remember { mutableStateOf(productViewModel.informationProductObject.copy()) } val context = LocalContext.current Scaffold( topBar = { // TopAppBar (the top bar) TopAppBar( navigationIcon = { - IconButton(onClick = { onBack() }) { + IconButton(onClick = { }) { Icon( Icons.Default.ArrowBack, contentDescription = "Back" From 9afcde7d68d88fe0c0a5c78b0bbf03cf0eb9e840 Mon Sep 17 00:00:00 2001 From: Nafisul Nazrul Date: Thu, 12 Oct 2023 17:18:15 +0300 Subject: [PATCH 20/32] Addition --- app/build.gradle.kts | 1 + .../example/mycloset/App/LoginPreviewApp.kt | 6 ++ .../mycloset/Views/CreateAccountPage.kt | 38 ++++++-- .../com/example/mycloset/Views/HomeScreen.kt | 2 +- .../com/example/mycloset/Views/LoginPage.kt | 31 +++++- .../com/example/mycloset/Views/MainPage.kt | 91 +++++++++++++----- .../mycloset/components/AppComponents.kt | 7 +- .../com/example/mycloset/navigation/Screen.kt | 3 +- .../com/example/mycloset/ui/theme/Theme.kt | 4 +- .../com/example/mycloset/ui/theme/Type.kt | 49 +++++++--- app/src/main/res/drawable/mycloset.png | Bin 0 -> 85725 bytes app/src/main/res/drawable/t_shirt.png | Bin 0 -> 1794 bytes app/src/main/res/values/font_certs.xml | 17 ++++ 13 files changed, 196 insertions(+), 53 deletions(-) create mode 100644 app/src/main/res/drawable/mycloset.png create mode 100644 app/src/main/res/drawable/t_shirt.png create mode 100644 app/src/main/res/values/font_certs.xml diff --git a/app/build.gradle.kts b/app/build.gradle.kts index b23e67e..4a1e4ed 100644 --- a/app/build.gradle.kts +++ b/app/build.gradle.kts @@ -75,6 +75,7 @@ dependencies { implementation("androidx.compose.ui:ui-tooling-preview") implementation("androidx.compose.material3:material3") implementation("androidx.appcompat:appcompat:1.6.1") + implementation("androidx.compose.ui:ui-text-google-fonts:1.5.3") testImplementation("junit:junit:4.13.2") androidTestImplementation("androidx.test.ext:junit:1.1.5") androidTestImplementation("androidx.test.espresso:espresso-core:3.5.1") diff --git a/app/src/main/java/com/example/mycloset/App/LoginPreviewApp.kt b/app/src/main/java/com/example/mycloset/App/LoginPreviewApp.kt index 5f35bb2..49812a6 100644 --- a/app/src/main/java/com/example/mycloset/App/LoginPreviewApp.kt +++ b/app/src/main/java/com/example/mycloset/App/LoginPreviewApp.kt @@ -13,6 +13,7 @@ import com.example.mycloset.BarcodeWorkingSet.CameraScanViewModel import com.example.mycloset.DatabaseWorkingset.ProductViewModel import com.example.mycloset.Views.HomeScreen import com.example.mycloset.Views.LoginScreen +import com.example.mycloset.Views.MainScreen import com.example.mycloset.Views.ProductScanView import com.example.mycloset.Views.SignUpScreen import com.example.mycloset.navigation.LoginAppRouter @@ -52,6 +53,11 @@ fun LoginApp(cameraController: LifecycleCameraController){ } ) } + is Screen.MainScreen -> { + MainScreen() + } + + } } diff --git a/app/src/main/java/com/example/mycloset/Views/CreateAccountPage.kt b/app/src/main/java/com/example/mycloset/Views/CreateAccountPage.kt index f092642..fbfdfed 100644 --- a/app/src/main/java/com/example/mycloset/Views/CreateAccountPage.kt +++ b/app/src/main/java/com/example/mycloset/Views/CreateAccountPage.kt @@ -1,5 +1,6 @@ package com.example.mycloset.Views +import androidx.compose.foundation.Image import androidx.compose.foundation.background import androidx.compose.foundation.layout.Box import androidx.compose.foundation.layout.Column @@ -7,15 +8,19 @@ import androidx.compose.foundation.layout.Spacer import androidx.compose.foundation.layout.fillMaxSize import androidx.compose.foundation.layout.height import androidx.compose.foundation.layout.padding +import androidx.compose.foundation.layout.size import androidx.compose.material.icons.Icons import androidx.compose.material.icons.filled.Email import androidx.compose.material.icons.filled.Person import androidx.compose.material3.CircularProgressIndicator +import androidx.compose.material3.MaterialTheme import androidx.compose.material3.Surface +import androidx.compose.material3.Text import androidx.compose.runtime.Composable import androidx.compose.ui.Alignment import androidx.compose.ui.Modifier import androidx.compose.ui.graphics.Color +import androidx.compose.ui.res.painterResource import androidx.compose.ui.res.stringResource import androidx.compose.ui.tooling.preview.Preview import androidx.compose.ui.unit.dp @@ -38,13 +43,12 @@ import com.example.mycloset.navigation.Screen fun SignUpScreen(signupViewModel: SignupViewModel = viewModel()) { Box(modifier = Modifier.fillMaxSize(), contentAlignment = Alignment.Center) { Surface( - color = Color.White, + color = MaterialTheme.colorScheme.primary, modifier = Modifier - .fillMaxSize() - .background(Color.White) - .padding(28.dp) + ) { Column(modifier = Modifier.fillMaxSize()) { + Spacer(modifier = Modifier.padding(24.dp)) HeadingTextComponent(value = stringResource(id = R.string.my_closet)) NormalTextComponent(value = stringResource(id = R.string.create_account)) Spacer(modifier = Modifier.height(20.dp)) @@ -53,19 +57,35 @@ fun SignUpScreen(signupViewModel: SignupViewModel = viewModel()) { imageVector = Icons.Default.Person, onTextSelected = { signupViewModel.onEvent(SignupUIEvent.FirstNameChanged(it)) }, errorStatus = signupViewModel.registrationUIState.value.firstNameError - - ) + if (!signupViewModel.registrationUIState.value.firstNameError){ + Text( + text = "Pleace enter a first name", + color = Color.Red + ) + } TextField(lableValue = stringResource(id = R.string.last_name), imageVector = Icons.Default.Person, onTextSelected = { signupViewModel.onEvent(SignupUIEvent.LastNameChanged(it)) }, errorStatus = signupViewModel.registrationUIState.value.lastNameError) + if (!signupViewModel.registrationUIState.value.lastNameError){ + Text( + text = "Pleace enter a last name", + color = Color.Red + ) + } TextField(lableValue = stringResource(id = R.string.email), imageVector = Icons.Default.Email, onTextSelected = { signupViewModel.onEvent(SignupUIEvent.EmailChanged(it)) }, errorStatus = signupViewModel.registrationUIState.value.emailError) + if (!signupViewModel.registrationUIState.value.emailError){ + Text( + text = "Pleace enter a valid email", + color = Color.Red + ) + } PasswordTextField( labelValue = stringResource(id = R.string.password), onTextSelected = { @@ -73,6 +93,12 @@ fun SignUpScreen(signupViewModel: SignupViewModel = viewModel()) { }, errorStatus = signupViewModel.registrationUIState.value.passwordError ) + if (!signupViewModel.registrationUIState.value.passwordError){ + Text( + text = "Pleace enter a password with min 6 characters", + color = Color.Red + ) + } Spacer(modifier = Modifier.height(20.dp)) ButtonComponent( value = stringResource(id = R.string.register), onButtonClicked = { diff --git a/app/src/main/java/com/example/mycloset/Views/HomeScreen.kt b/app/src/main/java/com/example/mycloset/Views/HomeScreen.kt index e7e3faf..3063555 100644 --- a/app/src/main/java/com/example/mycloset/Views/HomeScreen.kt +++ b/app/src/main/java/com/example/mycloset/Views/HomeScreen.kt @@ -33,7 +33,7 @@ import kotlinx.coroutines.flow.* -//import com.example.mycloset.Screen + @OptIn(ExperimentalMaterial3Api::class) @Composable diff --git a/app/src/main/java/com/example/mycloset/Views/LoginPage.kt b/app/src/main/java/com/example/mycloset/Views/LoginPage.kt index 0faa19b..5f471a8 100644 --- a/app/src/main/java/com/example/mycloset/Views/LoginPage.kt +++ b/app/src/main/java/com/example/mycloset/Views/LoginPage.kt @@ -1,20 +1,26 @@ package com.example.mycloset.Views +import androidx.compose.foundation.Image import androidx.compose.foundation.background +import androidx.compose.foundation.layout.Box import androidx.compose.foundation.layout.Column import androidx.compose.foundation.layout.Spacer 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.material.icons.Icons import androidx.compose.material.icons.filled.Email import androidx.compose.material3.MaterialTheme import androidx.compose.material3.Surface import androidx.compose.runtime.Composable +import androidx.compose.ui.Alignment import androidx.compose.ui.Modifier import androidx.compose.ui.tooling.preview.Preview import androidx.compose.ui.unit.dp import androidx.compose.ui.graphics.Color +import androidx.compose.ui.res.painterResource import androidx.compose.ui.res.stringResource import androidx.lifecycle.viewmodel.compose.viewModel import com.example.mycloset.LoginWorkingSet.Login.LoginViewModel @@ -32,12 +38,27 @@ import com.example.mycloset.navigation.Screen @Composable fun LoginScreen(loginViewModel: LoginViewModel = viewModel()){ - Surface(modifier = Modifier - .fillMaxSize() - .background(Color.White) - .padding(28.dp) + Surface( + modifier = Modifier.fillMaxSize(), + color = MaterialTheme.colorScheme.primary, ) { - Column(modifier = Modifier.fillMaxSize()) { + Column( + modifier = Modifier.fillMaxSize() + ) { + Box( + modifier = Modifier + .fillMaxWidth() + .height(30.dp), // Adjust the height of the image container as needed + contentAlignment = Alignment.TopCenter + ) { + // Add your image here + Image( + painter = painterResource(id = R.drawable.t_shirt), // Replace with your image resource + contentDescription = "Image", + modifier = Modifier.size(50.dp) // Adjust the size of the image as needed + ) + } + Spacer(modifier = Modifier.padding(16.dp)) NormalTextComponent(value = stringResource(id = R.string.my_closet)) HeadingTextComponent(value = stringResource(id = R.string.welcome_back)) diff --git a/app/src/main/java/com/example/mycloset/Views/MainPage.kt b/app/src/main/java/com/example/mycloset/Views/MainPage.kt index ca41416..2809040 100644 --- a/app/src/main/java/com/example/mycloset/Views/MainPage.kt +++ b/app/src/main/java/com/example/mycloset/Views/MainPage.kt @@ -1,5 +1,6 @@ package com.example.mycloset.Views +import androidx.compose.foundation.Image import androidx.compose.foundation.background import androidx.compose.foundation.layout.Arrangement import androidx.compose.foundation.layout.Column @@ -8,53 +9,93 @@ 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.material3.Button +import androidx.compose.material3.ButtonDefaults import androidx.compose.material3.ExperimentalMaterial3Api import androidx.compose.material3.MaterialTheme import androidx.compose.material3.Scaffold +import androidx.compose.material3.Surface import androidx.compose.material3.Text import androidx.compose.runtime.Composable import androidx.compose.ui.Alignment import androidx.compose.ui.Modifier +import androidx.compose.ui.graphics.Color +import androidx.compose.ui.res.painterResource +import androidx.compose.ui.text.font.FontWeight import androidx.compose.ui.tooling.preview.Preview import androidx.compose.ui.unit.dp +import com.example.mycloset.R +import com.example.mycloset.navigation.LoginAppRouter +import com.example.mycloset.navigation.Screen +import com.example.mycloset.ui.theme.fontFamily +import com.example.mycloset.ui.theme.fontFamilyText +import com.example.mycloset.ui.theme.textType @OptIn(ExperimentalMaterial3Api::class) @Composable -fun MainScreen(){ - Column(modifier = Modifier - .fillMaxSize() - .padding(16.dp), verticalArrangement = Arrangement.Center, horizontalAlignment = Alignment.CenterHorizontally) { - Text(text = "MyCloset", modifier = Modifier - .padding(bottom = 16.dp), style = MaterialTheme.typography.displayLarge) - - Spacer(modifier = Modifier.height(16.dp)) - - Button(onClick = {}, modifier = Modifier - .fillMaxWidth() - .padding(8.dp)) { - Text(text = "Login") - } - - Button(onClick = {}, modifier = Modifier - .fillMaxWidth() - .padding(8.dp)) { - Text(text = "Create an account") - } - } +fun MainScreen() { + Surface( + modifier = Modifier.fillMaxSize(), + color = MaterialTheme.colorScheme.primary, // Set the background color of the Surface + ) { + Column( + modifier = Modifier + .fillMaxSize() + .padding(16.dp), + verticalArrangement = Arrangement.Center, + horizontalAlignment = Alignment.CenterHorizontally + ) { + // Logo and title + Image( + painter = painterResource(id = R.drawable.t_shirt), // Replace with your logo resource + contentDescription = "Logo", + modifier = Modifier + .size(150.dp) + .padding(top = 36.dp) + ) + Text( + fontFamily = fontFamily, + text = "MyCloset", + modifier = Modifier.padding(vertical = 16.dp), + fontWeight = FontWeight.Bold, + style = MaterialTheme.typography.displayLarge, + color = MaterialTheme.colorScheme.onPrimaryContainer + ) + Spacer(modifier = Modifier.height(16.dp)) + // Buttons + Button( + onClick = { LoginAppRouter.navigateTo(Screen.LoginScreen) }, + modifier = Modifier + .fillMaxWidth() + .padding(8.dp) + .height(50.dp), + ) { + Text(text = "Login", style = textType.bodyLarge) + } + + Button( + onClick = { LoginAppRouter.navigateTo(Screen.SignupScreen) }, + modifier = Modifier + .fillMaxWidth() + .padding(8.dp) + .height(50.dp), + ) { + Text(text = "Create an account", style = textType.bodyLarge) + } + } + } } + @Preview(showSystemUi = true, showBackground = true) @Composable fun Preview(){ - Column(modifier = Modifier - .fillMaxSize() - .background(MaterialTheme.colorScheme.background)) { + MainScreen() } -} \ No newline at end of file diff --git a/app/src/main/java/com/example/mycloset/components/AppComponents.kt b/app/src/main/java/com/example/mycloset/components/AppComponents.kt index 0ce5744..88c19f8 100644 --- a/app/src/main/java/com/example/mycloset/components/AppComponents.kt +++ b/app/src/main/java/com/example/mycloset/components/AppComponents.kt @@ -55,6 +55,7 @@ import androidx.compose.ui.text.withStyle import androidx.compose.ui.unit.dp import androidx.compose.ui.unit.min import androidx.compose.ui.unit.sp +import com.example.mycloset.ui.theme.fontFamilyText @Composable fun NormalTextComponent(value: String){ @@ -76,7 +77,7 @@ fun HeadingTextComponent(value: String){ Text(text = value, modifier = Modifier.fillMaxWidth(), style = TextStyle( - fontSize = 30.sp, + fontSize = 32.sp, fontWeight = FontWeight.Bold, fontStyle = FontStyle.Normal ), @@ -202,7 +203,9 @@ fun ClickableTextComponent(tryingToLogin: Boolean = true, onTextSelected: (Stri style = TextStyle( fontSize = 21.sp, fontWeight = FontWeight.Normal, - fontStyle = FontStyle.Normal + fontStyle = FontStyle.Normal, + fontFamily = fontFamilyText + ), text = annotatedString, onClick = { offset -> diff --git a/app/src/main/java/com/example/mycloset/navigation/Screen.kt b/app/src/main/java/com/example/mycloset/navigation/Screen.kt index 21c19ef..205ab61 100644 --- a/app/src/main/java/com/example/mycloset/navigation/Screen.kt +++ b/app/src/main/java/com/example/mycloset/navigation/Screen.kt @@ -8,10 +8,11 @@ sealed class Screen(){ object LoginScreen: Screen() object HomeScreen : Screen() object ProductScanView : Screen() + object MainScreen: Screen() } object LoginAppRouter{ - val currentScreen: MutableState = mutableStateOf(Screen.SignupScreen) + val currentScreen: MutableState = mutableStateOf(Screen.MainScreen) fun navigateTo(destination: Screen){ currentScreen.value = destination diff --git a/app/src/main/java/com/example/mycloset/ui/theme/Theme.kt b/app/src/main/java/com/example/mycloset/ui/theme/Theme.kt index cfdf74f..3e777b1 100644 --- a/app/src/main/java/com/example/mycloset/ui/theme/Theme.kt +++ b/app/src/main/java/com/example/mycloset/ui/theme/Theme.kt @@ -8,8 +8,8 @@ import androidx.compose.runtime.Composable private val LightColors = lightColorScheme( - primary = md_theme_light_primary, - onPrimary = md_theme_light_onPrimary, + primary = md_theme_light_outline, + onPrimary = md_theme_light_primaryContainer, primaryContainer = md_theme_light_primaryContainer, onPrimaryContainer = md_theme_light_onPrimaryContainer, secondary = md_theme_light_secondary, diff --git a/app/src/main/java/com/example/mycloset/ui/theme/Type.kt b/app/src/main/java/com/example/mycloset/ui/theme/Type.kt index 0cf7677..93842df 100644 --- a/app/src/main/java/com/example/mycloset/ui/theme/Type.kt +++ b/app/src/main/java/com/example/mycloset/ui/theme/Type.kt @@ -2,33 +2,60 @@ package com.example.mycloset.ui.theme import androidx.compose.material3.Typography import androidx.compose.ui.text.TextStyle +import androidx.compose.ui.text.font.Font import androidx.compose.ui.text.font.FontFamily import androidx.compose.ui.text.font.FontWeight +import androidx.compose.ui.text.googlefonts.Font +import androidx.compose.ui.text.googlefonts.GoogleFont import androidx.compose.ui.unit.sp +import com.example.mycloset.R // Set of Material typography styles to start with -val Typography = Typography( + + +val provider = GoogleFont.Provider( + providerAuthority = "com.google.android.gms.fonts", + providerPackage = "com.google.android.gms", + certificates = R.array.com_google_android_gms_fonts_certs +) + +val fontFamilyText = FontFamily( + Font( + googleFont = GoogleFont("Saira Condensed"), + fontProvider = provider + ) +) + +val fontFamily = FontFamily( + Font( + googleFont = GoogleFont("Satisfy"), + fontProvider = provider + ) +) + +// Set of Material typography styles to start with +val textType = Typography( + bodyLarge = TextStyle( - fontFamily = FontFamily.Default, + fontFamily = fontFamilyText, fontWeight = FontWeight.Normal, - fontSize = 16.sp, - lineHeight = 24.sp, + fontSize = 24.sp, + lineHeight = 15.sp, letterSpacing = 0.5.sp - ) - /* Other default text styles to override + ), + titleLarge = TextStyle( - fontFamily = FontFamily.Default, + fontFamily = fontFamily, fontWeight = FontWeight.Normal, - fontSize = 22.sp, + fontSize = 50.sp, lineHeight = 28.sp, letterSpacing = 0.sp ), labelSmall = TextStyle( - fontFamily = FontFamily.Default, - fontWeight = FontWeight.Medium, + fontFamily = fontFamilyText, + fontWeight = FontWeight.Thin, fontSize = 11.sp, lineHeight = 16.sp, letterSpacing = 0.5.sp ) - */ ) \ No newline at end of file diff --git a/app/src/main/res/drawable/mycloset.png b/app/src/main/res/drawable/mycloset.png new file mode 100644 index 0000000000000000000000000000000000000000..06d484e4a67121ad4d88809f74bf8977a7bb0edc GIT binary patch literal 85725 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 z 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 literal 0 HcmV?d00001 diff --git a/app/src/main/res/drawable/t_shirt.png b/app/src/main/res/drawable/t_shirt.png new file mode 100644 index 0000000000000000000000000000000000000000..39535da4a19454a6d409f76da8872fbf4f35670c GIT binary patch literal 1794 zcmds2`!~}I0N-pj>_JJ5p@|aGq{(A>KiXR4*>Fk<8@V2r@`ziT4pt)6?liAxIv(j^ z9`i`wj*?=zDX(Q&xOy>*l-SzUA8_vzkM$H`W!%M=xKmJAQYM8;lG}J zzoZ6R_r~Bm73%>_b|VL>ts_${lC|E|6G0+;zpwS$`aqbPZM{ZCf64U~L-9WrZ*_HxDSZwn#@p30Z&@hI3)@0@<~cMRQbYw@50*ty-Ny{!A~ai3Z+t^oONCxE(|bC$i@H82%2gl zLS}vsUSb*6$uI!ofJc@CxlrJDz!+$o!LQbg3<3dwy?X`L`(8gI4mdu8mz@~N0OkSL zo>Ft~OFD$S_mIUcNpF@NWmbt_eQ7=s^NA8C33hQy{OGc&OeIkY@N4h$H>V+2vgO&K zRbi^Tw??|z7#2V(px>;=vd(U>yB8dXO+3U0h`=zV;#mIeX(l~7>S#631Ci&z1o=wlngq*i`yRhc0Br9!uI+6 zy>@`BGzBN_i@U1_=hH)pH43!J#=~oi&FKe_& z9WYpY(fLGp-BxB^u9YSSU+3opE* zZ2!v5CvXr{nyqytpMd!J2Y0D{lsTwed*dZJDAACpNJw7O!Ir&-T>O=lU7baKZRK)0 zv7!7d3N_=us98N6&+b0ou-dB76H-w5cQwuAo*USZBnKPk=k@P8H>MePUJOI`#pA3t zQtb(w+Gw`-@Ik4CW)cc_urO9W4;`V~zN8Er%p65NH3@;26^T9YL69WR6v(Fu&vDdO ze;ZsWAM5*m-}+F>Fr%zO%y38zO@TZJ+)u8o{_)%Q`Z=%HbqQuGI&M0th0}ZVuSQ!6 z9qBcJNY><-ZToYBwM$^L^!CH$b{3t?Y;zcIg3oe@a9Ne0t=pfg@rBaz>QhJ(z^Hw#S9@9~ zR!4ZaCJ52kVdKu!?WhV-8hR z`P$~BOJF&;NTts76U<|{24=DZO?Q-ePff=Xc;`^Qv%hwp+XeR#o|O$SuB|*S@p2PA zHJWfGXbin@N3y(JMd;!)#nObT*gf4U1;RARZG%YT9Crl~7F_-X2mybA9?N4d7Vo#f z#c<{cO*_nS8CMOdH$Pvw3>P|(owWoxv*NG&G6Z^p?k7t8m`0a)N?EDe4NCzjn^)|# zKe}?&TSX1TH77meooh7DIs#;yDw4Iy3g-_nNZ|iR>2<^fjH9BP^D|t|3FE_6Ov#KIs?m@#ZE78`Idf_1{+7Tx& k?ZEKI^GW~l3s)t_|IRibM + + + @array/com_google_android_gms_fonts_certs_dev + @array/com_google_android_gms_fonts_certs_prod + + + + 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 + + + From 9393038372fa0c7296d1604bbf95367e77dec5ff Mon Sep 17 00:00:00 2001 From: Nafisul Nazrul Date: Thu, 12 Oct 2023 17:34:59 +0300 Subject: [PATCH 21/32] Addition --- .../com/example/mycloset/BarcodeWorkingSet/BarcodeRepository.kt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/app/src/main/java/com/example/mycloset/BarcodeWorkingSet/BarcodeRepository.kt b/app/src/main/java/com/example/mycloset/BarcodeWorkingSet/BarcodeRepository.kt index 1ae0ccd..92af66e 100644 --- a/app/src/main/java/com/example/mycloset/BarcodeWorkingSet/BarcodeRepository.kt +++ b/app/src/main/java/com/example/mycloset/BarcodeWorkingSet/BarcodeRepository.kt @@ -3,7 +3,7 @@ package com.example.mycloset.BarcodeWorkingSet import com.example.mycloset.ApiWorkingSet.RetrofitObject // -var APY_KEY:String="dl8mxnhxbvfg5zxt7gh9h3ndw31jx5" +var APY_KEY:String="82m5dj79cuxyk3ql4nbtxvgpsv4a1l" //class for using the barcode-lookup API class BarcodeRepository{ From 955c2030d70863d6e03d01e7a45ca9ac764212dd Mon Sep 17 00:00:00 2001 From: Nafisul Nazrul Date: Thu, 12 Oct 2023 18:49:54 +0300 Subject: [PATCH 22/32] Addition --- .../mycloset/Views/CreateAccountPage.kt | 28 ++++++- .../com/example/mycloset/Views/HomeScreen.kt | 79 +++++-------------- .../com/example/mycloset/Views/LoginPage.kt | 55 +++++++++---- 3 files changed, 83 insertions(+), 79 deletions(-) diff --git a/app/src/main/java/com/example/mycloset/Views/CreateAccountPage.kt b/app/src/main/java/com/example/mycloset/Views/CreateAccountPage.kt index fbfdfed..3c588be 100644 --- a/app/src/main/java/com/example/mycloset/Views/CreateAccountPage.kt +++ b/app/src/main/java/com/example/mycloset/Views/CreateAccountPage.kt @@ -6,6 +6,7 @@ import androidx.compose.foundation.layout.Box import androidx.compose.foundation.layout.Column import androidx.compose.foundation.layout.Spacer 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 @@ -22,6 +23,8 @@ import androidx.compose.ui.Modifier import androidx.compose.ui.graphics.Color import androidx.compose.ui.res.painterResource import androidx.compose.ui.res.stringResource +import androidx.compose.ui.text.font.FontWeight +import androidx.compose.ui.text.style.TextAlign import androidx.compose.ui.tooling.preview.Preview import androidx.compose.ui.unit.dp import androidx.lifecycle.viewmodel.compose.viewModel @@ -37,6 +40,7 @@ import com.example.mycloset.LoginWorkingSet.Signup.SignupViewModel import com.example.mycloset.LoginWorkingSet.Signup.SignupUIEvent import com.example.mycloset.navigation.LoginAppRouter import com.example.mycloset.navigation.Screen +import com.example.mycloset.ui.theme.fontFamily @Composable @@ -45,11 +49,29 @@ fun SignUpScreen(signupViewModel: SignupViewModel = viewModel()) { Surface( color = MaterialTheme.colorScheme.primary, modifier = Modifier - ) { - Column(modifier = Modifier.fillMaxSize()) { + Column(modifier = Modifier.fillMaxSize().padding(8.dp)) { + Box( + modifier = Modifier + .fillMaxWidth() + .height(20.dp), // Adjust the height of the image container as needed + contentAlignment = Alignment.TopCenter + ) { + // Add your image here + + } Spacer(modifier = Modifier.padding(24.dp)) - HeadingTextComponent(value = stringResource(id = R.string.my_closet)) + Text( + fontFamily = fontFamily, + text = "MyCloset", + modifier = Modifier + .fillMaxWidth() + .padding(vertical = 16.dp), + fontWeight = FontWeight.Bold, + style = MaterialTheme.typography.displayLarge, + color = MaterialTheme.colorScheme.onPrimaryContainer, + textAlign = TextAlign.Center // Center align the text + ) NormalTextComponent(value = stringResource(id = R.string.create_account)) Spacer(modifier = Modifier.height(20.dp)) TextField( diff --git a/app/src/main/java/com/example/mycloset/Views/HomeScreen.kt b/app/src/main/java/com/example/mycloset/Views/HomeScreen.kt index 29bf4ee..54f01e7 100644 --- a/app/src/main/java/com/example/mycloset/Views/HomeScreen.kt +++ b/app/src/main/java/com/example/mycloset/Views/HomeScreen.kt @@ -38,83 +38,42 @@ import kotlinx.coroutines.flow.* @OptIn(ExperimentalMaterial3Api::class) @Composable fun HomeScreen(productViewModel: ProductViewModel) { - - // Observe the products list from the ViewModel - //viewModel.getProducts() val signupViewModel: SignupViewModel = viewModel() - productViewModel.getProductsWithEmail(LoggedUser.loggedUserEmail) - val products = productViewModel.products - if (products.isEmpty()) { - Scaffold( - topBar = { - TopAppBar( - title = { - Text("MyCloset") - }, - actions = { - IconButton( - onClick = { LoginAppRouter.navigateTo(Screen.ProductScanView) } - ) { - Icon(Icons.Default.Camera, contentDescription = null) - } - IconButton( - onClick = { - signupViewModel.logout() - } - ) { - Icon(Icons.Default.Logout, contentDescription = "Logout") - } - } - ) - }) { innerPadding -> - Box( - modifier = Modifier - .fillMaxSize() - .padding(innerPadding), - contentAlignment = Alignment.Center - ) { - Text( - text = "You don't have any items yet...", - textAlign = TextAlign.Center, - ) - } - } - } else { - Scaffold(topBar = { + Scaffold( + topBar = { TopAppBar( title = { Text("MyCloset", modifier = Modifier.padding(2.dp)) }, actions = { IconButton( - onClick = { - LoginAppRouter.navigateTo(Screen.ProductScanView)} + onClick = { signupViewModel.logout() } ) { - Icon(Icons.Default.Camera, contentDescription = "Camera") + Icon(Icons.Default.Logout, contentDescription = "Logout") } + }, + navigationIcon = { IconButton( - onClick = { - signupViewModel.logout() - } + onClick = { LoginAppRouter.navigateTo(Screen.ProductScanView) } ) { - Icon(Icons.Default.Logout, contentDescription = "Logout") + Icon(Icons.Default.Camera, contentDescription = "Camera") } } ) - }) { innerPadding -> - LazyVerticalGrid( - columns = GridCells.Fixed(2), modifier = Modifier - .fillMaxSize() - .padding(innerPadding) - .padding(16.dp) - ) { - items(products.size) { index -> - val product = products[index] - ItemCard(product.images, product.title, product.barcodeNumber, productViewModel) - } + } + ) { innerPadding -> + LazyVerticalGrid( + columns = GridCells.Fixed(2), modifier = Modifier + .fillMaxSize() + .padding(innerPadding) + .padding(16.dp) + ) { + items(products.size) { index -> + val product = products[index] + ItemCard(product.images, product.title, product.barcodeNumber, productViewModel) } } } diff --git a/app/src/main/java/com/example/mycloset/Views/LoginPage.kt b/app/src/main/java/com/example/mycloset/Views/LoginPage.kt index 5f471a8..3944ba5 100644 --- a/app/src/main/java/com/example/mycloset/Views/LoginPage.kt +++ b/app/src/main/java/com/example/mycloset/Views/LoginPage.kt @@ -2,6 +2,7 @@ package com.example.mycloset.Views 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.Spacer @@ -14,6 +15,7 @@ import androidx.compose.material.icons.Icons import androidx.compose.material.icons.filled.Email import androidx.compose.material3.MaterialTheme import androidx.compose.material3.Surface +import androidx.compose.material3.Text import androidx.compose.runtime.Composable import androidx.compose.ui.Alignment import androidx.compose.ui.Modifier @@ -22,6 +24,7 @@ import androidx.compose.ui.unit.dp import androidx.compose.ui.graphics.Color import androidx.compose.ui.res.painterResource import androidx.compose.ui.res.stringResource +import androidx.compose.ui.text.font.FontWeight import androidx.lifecycle.viewmodel.compose.viewModel import com.example.mycloset.LoginWorkingSet.Login.LoginViewModel import com.example.mycloset.R @@ -35,6 +38,7 @@ import com.example.mycloset.components.TextField import com.example.mycloset.LoginWorkingSet.Login.LoginUIEvent import com.example.mycloset.navigation.LoginAppRouter import com.example.mycloset.navigation.Screen +import com.example.mycloset.ui.theme.fontFamily @Composable fun LoginScreen(loginViewModel: LoginViewModel = viewModel()){ @@ -43,37 +47,56 @@ fun LoginScreen(loginViewModel: LoginViewModel = viewModel()){ color = MaterialTheme.colorScheme.primary, ) { Column( - modifier = Modifier.fillMaxSize() + modifier = Modifier.fillMaxSize().padding(8.dp), + verticalArrangement = Arrangement.Center, + horizontalAlignment = Alignment.CenterHorizontally ) { Box( modifier = Modifier .fillMaxWidth() - .height(30.dp), // Adjust the height of the image container as needed + .height(50.dp), contentAlignment = Alignment.TopCenter ) { - // Add your image here Image( - painter = painterResource(id = R.drawable.t_shirt), // Replace with your image resource + painter = painterResource(id = R.drawable.t_shirt), contentDescription = "Image", - modifier = Modifier.size(50.dp) // Adjust the size of the image as needed + modifier = Modifier.size(100.dp) ) } - Spacer(modifier = Modifier.padding(16.dp)) - NormalTextComponent(value = stringResource(id = R.string.my_closet)) + Spacer(modifier = Modifier.height(16.dp)) // Adjust the spacing as needed + Text( + fontFamily = fontFamily, + text = "MyCloset", + modifier = Modifier.padding(vertical = 16.dp), + fontWeight = FontWeight.Bold, + style = MaterialTheme.typography.displayLarge, + color = MaterialTheme.colorScheme.onPrimaryContainer + ) HeadingTextComponent(value = stringResource(id = R.string.welcome_back)) - - TextField(lableValue = stringResource(id = R.string.email), onTextSelected = {loginViewModel.onEvent( - LoginUIEvent.EmailChanged(it))}, errorStatus = loginViewModel.loginUiState.value.emailError , imageVector = Icons.Default.Email) - PasswordTextField(labelValue = stringResource(id = R.string.password), onTextSelected = {loginViewModel.onEvent( - LoginUIEvent.PasswordChanged(it))}, errorStatus = loginViewModel.loginUiState.value.passwordError) + TextField( + lableValue = stringResource(id = R.string.email), + onTextSelected = { loginViewModel.onEvent(LoginUIEvent.EmailChanged(it)) }, + errorStatus = loginViewModel.loginUiState.value.emailError, + imageVector = Icons.Default.Email + ) + PasswordTextField( + labelValue = stringResource(id = R.string.password), + onTextSelected = { loginViewModel.onEvent(LoginUIEvent.PasswordChanged(it)) }, + errorStatus = loginViewModel.loginUiState.value.passwordError + ) Spacer(modifier = Modifier.height(40.dp)) - ButtonComponent(value = stringResource(id = R.string.login), onButtonClicked = { loginViewModel.onEvent( - LoginUIEvent.LoginButtonClicked) }, isEnabled = loginViewModel.allValidationPassed.value) + ButtonComponent( + value = stringResource(id = R.string.login), + onButtonClicked = { loginViewModel.onEvent(LoginUIEvent.LoginButtonClicked) }, + isEnabled = loginViewModel.allValidationPassed.value + ) Spacer(modifier = Modifier.height(20.dp)) DividerTextComponent() - ClickableTextComponent(onTextSelected = {LoginAppRouter.navigateTo(Screen.SignupScreen)} , tryingToLogin = false) + ClickableTextComponent( + onTextSelected = { LoginAppRouter.navigateTo(Screen.SignupScreen) }, + tryingToLogin = false + ) } - } } From 1ca9041132a3c78412a8591126bbf055edc315e5 Mon Sep 17 00:00:00 2001 From: Liideli Date: Thu, 12 Oct 2023 18:54:20 +0300 Subject: [PATCH 23/32] Added icons. --- app/src/main/ic_launcher-playstore.png | Bin 0 -> 15010 bytes .../res/mipmap-anydpi-v26/ic_launcher.xml | 5 ++--- .../mipmap-anydpi-v26/ic_launcher_round.xml | 5 ++--- app/src/main/res/mipmap-hdpi/ic_launcher.webp | Bin 1404 -> 930 bytes .../mipmap-hdpi/ic_launcher_foreground.webp | Bin 0 -> 496 bytes .../res/mipmap-hdpi/ic_launcher_round.webp | Bin 2898 -> 2786 bytes app/src/main/res/mipmap-mdpi/ic_launcher.webp | Bin 982 -> 706 bytes .../mipmap-mdpi/ic_launcher_foreground.webp | Bin 0 -> 344 bytes .../res/mipmap-mdpi/ic_launcher_round.webp | Bin 1772 -> 1786 bytes .../main/res/mipmap-xhdpi/ic_launcher.webp | Bin 1900 -> 1418 bytes .../mipmap-xhdpi/ic_launcher_foreground.webp | Bin 0 -> 684 bytes .../res/mipmap-xhdpi/ic_launcher_round.webp | Bin 3918 -> 3928 bytes .../main/res/mipmap-xxhdpi/ic_launcher.webp | Bin 2884 -> 2128 bytes .../mipmap-xxhdpi/ic_launcher_foreground.webp | Bin 0 -> 1156 bytes .../res/mipmap-xxhdpi/ic_launcher_round.webp | Bin 5914 -> 5958 bytes .../main/res/mipmap-xxxhdpi/ic_launcher.webp | Bin 3844 -> 2876 bytes .../ic_launcher_foreground.webp | Bin 0 -> 1644 bytes .../res/mipmap-xxxhdpi/ic_launcher_round.webp | Bin 7778 -> 8398 bytes .../res/values/ic_launcher_background.xml | 4 ++++ 19 files changed, 8 insertions(+), 6 deletions(-) create mode 100644 app/src/main/ic_launcher-playstore.png create mode 100644 app/src/main/res/mipmap-hdpi/ic_launcher_foreground.webp create mode 100644 app/src/main/res/mipmap-mdpi/ic_launcher_foreground.webp create mode 100644 app/src/main/res/mipmap-xhdpi/ic_launcher_foreground.webp create mode 100644 app/src/main/res/mipmap-xxhdpi/ic_launcher_foreground.webp create mode 100644 app/src/main/res/mipmap-xxxhdpi/ic_launcher_foreground.webp create mode 100644 app/src/main/res/values/ic_launcher_background.xml diff --git a/app/src/main/ic_launcher-playstore.png b/app/src/main/ic_launcher-playstore.png new file mode 100644 index 0000000000000000000000000000000000000000..b569f43ba448932e30d46b1000cad30591a1ebdf GIT binary patch literal 15010 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 C_C>n@ literal 0 HcmV?d00001 diff --git a/app/src/main/res/mipmap-anydpi-v26/ic_launcher.xml b/app/src/main/res/mipmap-anydpi-v26/ic_launcher.xml index 6f3b755..036d09b 100644 --- a/app/src/main/res/mipmap-anydpi-v26/ic_launcher.xml +++ b/app/src/main/res/mipmap-anydpi-v26/ic_launcher.xml @@ -1,6 +1,5 @@ - - - + + \ No newline at end of file diff --git a/app/src/main/res/mipmap-anydpi-v26/ic_launcher_round.xml b/app/src/main/res/mipmap-anydpi-v26/ic_launcher_round.xml index 6f3b755..036d09b 100644 --- a/app/src/main/res/mipmap-anydpi-v26/ic_launcher_round.xml +++ b/app/src/main/res/mipmap-anydpi-v26/ic_launcher_round.xml @@ -1,6 +1,5 @@ - - - + + \ No newline at end of file diff --git a/app/src/main/res/mipmap-hdpi/ic_launcher.webp b/app/src/main/res/mipmap-hdpi/ic_launcher.webp index c209e78ecd372343283f4157dcfd918ec5165bb3..0989a1a373609bfb948f8e36138ed4cd1a9a8f50 100644 GIT binary patch literal 930 zcmV;T16}-5Nk&GR0{{S5MM6+kP&iDE0{{RoN5ByfN9H(^ZB>~$_v34dAPACVb?5FD z1nfw*RaG-tQ=k9voHj?B>ikv<1PGtYqylL+*m)SJj+O}0I^L+OYAx*ez z2h>0}S_K&qRe0zvkh$wUZ2&-k009F0A_4*t5JWIR6a}OF0Yf@MdZ|f}svyBW+ zE1H@l9Yd1pC{|KQNXNvGieiFvH-~1vXlfG0#E?olLTkPtN;;|3Bqr4{K@?3*lYps? zp(fF!0}dI|2$4@!I`i(WwU|h3Tp%Pt6i7`{lb9%of~mraVq#Drh@wCYh=2$PqCgZF z7y-e6zt`Y324yTXFS7)7KuG1q%)Ewx$@A;3@;|p}FX`hb-_B28e_Nou5d8B(F!smw zW7cn<`$D|F{v18VY%nB)7ec2%)Az4E{`?)U!IL&u(>dr}|Lz|i_VNDaXLR}ayf@rl zb9{OWcqtQJQw>2A1PBnI0@|Pf0@Oyw^Ic6UaQVn|WivY^e76RRW4hh_=lp&;{kb<3 z61HtS-sTHx+n#N9_EyZQZQD)l**0t2_+L#vJnzgrc_R8h0o;%Go-QUygl=S%1QB9m zQ_Hnx(ApLqa@Z|^u;F?QR>Q}e_qc9eJ%~4I>Y2n_a;}F@7v8O@uV%8g;04#kOLm8q zy7K2Te)8MZjF9S?oS*UmD|M>3N&yeqc_rjAJ8wW#q?|c&So5*>xvW$q9PlwQv(#u| zV7vZwb`=9v@xIP_h&v-SUU1Vx{T2Rs;F9*a=q+BCt5tvA3K7w0<=J9T#izVX^wip% ztW=Y_R!_a{j#xlN`yKQ&yB^P~)>cGsG1Y)Z%fsOWI_UAWUbXwsHg`iko(5|&pcJmw zli1u3N~FD1xE)HMxn#>!Kn@y8=9CU(tDfY>5irV@N@oxNBi&It+*=7E%ml!uQV@Oy z0G8xIQ2FWsbV!C!x)B0?gplJ6;sk^wI}p3d0DRC_FPcv6hI{~pF;R>6h~;rHYH?yE z0F6h*@=4P2{}akNPd9Nlr-Lg=h!Z!h3LI1s9DPM2JL4 zNQ6j)L_|o0NQ8t$h(t(uHK?_HY;cMbD4Xmb9vKC%!@dQX5XAYJiE;3{8RA5hG06Q$ E1@s)Zb^rhX literal 1404 zcmV-?1%vuhNk&F=1pok7MM6+kP&il$0000G0000-002h-06|PpNX!5L00Dqw+t%{r zzW2vH!KF=w&cMnnN@{whkTw+#mAh0SV?YL=)3MimFYCWp#fpdtz~8$hD5VPuQgtcN zXl<@<#Cme5f5yr2h%@8TWh?)bSK`O z^Z@d={gn7J{iyxL_y_%J|L>ep{dUxUP8a{byupH&!UNR*OutO~0{*T4q5R6@ApLF! z5{w?Z150gC7#>(VHFJZ-^6O@PYp{t!jH(_Z*nzTK4 zkc{fLE4Q3|mA2`CWQ3{8;gxGizgM!zccbdQoOLZc8hThi-IhN90RFT|zlxh3Ty&VG z?Fe{#9RrRnxzsu|Lg2ddugg7k%>0JeD+{XZ7>Z~{=|M+sh1MF7~ zz>To~`~LVQe1nNoR-gEzkpe{Ak^7{{ZBk2i_<+`Bq<^GB!RYG+z)h;Y3+<{zlMUYd zrd*W4w&jZ0%kBuDZ1EW&KLpyR7r2=}fF2%0VwHM4pUs}ZI2egi#DRMYZPek*^H9YK zay4Iy3WXFG(F14xYsoDA|KXgGc5%2DhmQ1gFCkrgHBm!lXG8I5h*uf{rn48Z!_@ z4Bk6TJAB2CKYqPjiX&mWoW>OPFGd$wqroa($ne7EUK;#3VYkXaew%Kh^3OrMhtjYN?XEoY`tRPQsAkH-DSL^QqyN0>^ zmC>{#F14jz4GeW{pJoRpLFa_*GI{?T93^rX7SPQgT@LbLqpNA}<@2wH;q493)G=1Y z#-sCiRNX~qf3KgiFzB3I>4Z%AfS(3$`-aMIBU+6?gbgDb!)L~A)je+;fR0jWLL-Fu z4)P{c7{B4Hp91&%??2$v9iRSFnuckHUm}or9seH6 z>%NbT+5*@L5(I9j@06@(!{ZI?U0=pKn8uwIg&L{JV14+8s2hnvbRrU|hZCd}IJu7*;;ECgO%8_*W Kmw_-CKmY()leWbG diff --git a/app/src/main/res/mipmap-hdpi/ic_launcher_foreground.webp b/app/src/main/res/mipmap-hdpi/ic_launcher_foreground.webp new file mode 100644 index 0000000000000000000000000000000000000000..b0c5785e13dbd9f81ad304ebda2bf4e3ce1f693a GIT binary patch literal 496 zcmVBMuB|59c5RqE*|u%lo^0Fp_dXK<_w)a6gYft`DO7$^AtwR|F9I?JN%kRd z7IG|u7TODdMpvar@Si?(vcy&ngSmE};Gt?x`)d9G;Lj8X9L3O?>-G(vN`>2({s;j7 zX4qgYg-lnAPq1hnV++&LGXVS=WQJM@k%}TOU>U}EiwU#>fOn-75!&Dq;|lDW!@hyt z0@!sb0!J6h2K!)Zg%((Jfa5UBYWOkZr^X5l9M_Je1Y1AnF7(T#1EwJ`*%Y=4G`x-SPNRZAFq>Be zg~MbtKs7W>A94YFHiucmTY#LGVV=kqU;&0hObdvb2888f1M2+%-y#D literal 0 HcmV?d00001 diff --git a/app/src/main/res/mipmap-hdpi/ic_launcher_round.webp b/app/src/main/res/mipmap-hdpi/ic_launcher_round.webp index b2dfe3d1ba5cf3ee31b3ecc1ced89044a1f3b7a9..73eb679e3ce9bab7ee0640837ff088ad9b422147 100644 GIT binary patch literal 2786 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 literal 2898 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 diff --git a/app/src/main/res/mipmap-mdpi/ic_launcher.webp b/app/src/main/res/mipmap-mdpi/ic_launcher.webp index 4f0f1d64e58ba64d180ce43ee13bf9a17835fbca..7c31037654908640f81826244e00ef5d3fb94147 100644 GIT binary patch literal 706 zcmV;z0zLgwNk&Gx0ssJ4MM6+kP&iDj0ssInFTe{BhvYVrBt@#~K6sGce|O%NSDDcb zw~-{f%FN!okFazIgibhQfrX3tm4ir=0B5ClIU0RkWhLZE~e0tA7fX$KLI_M#mVC6#tk8IKDjm0^mBg5au| z^tU`!R{uFQFlm9L7K*Jk0MklKKb=$%!AcUOos7gFChJ~Ta%rx#laW+R6xOAg?fc)+ ze-7*0f6Nx?SR^2evj(*es$nXquk-tzC(K-DS}%t@AKwO0?`VRgq992SlXeuC3u5{Y zh5ibFtmL%zg<`g{C2;Ip7v)5zi!#Q zJtzf-qwITK*_`s3t!*k+}$LntPA=Z7RkQN!&3TcMg8Luf2Evz2f zR>00^X{05+QkZ6mD6;SHnkf%g6Xow65@EiYD6DLj&v2Al7~F7hc+h}qA~HtXd8}B~ z;(qbDai|uzE^}xzO324{xcxFUY{dcCW(H8^CfITeQ0y|;R0vS$G+3`Mkfjf-Rt;ST zwO<5QvJbS8VkRJ@erA6Y3 oG(VW2l0ecLl5?^Vv%s?vDaoL9GHLSY^xSpmWU_58?!>-J0KZ{PcK`qY literal 982 zcmV;{11bDcNk&G_0{{S5MM6+kP&il$0000G0000l001ul06|PpNU8t;00Dqo+t#w^ z^1csucXz7-Qrhzl9HuHB%l>&>1tG2^vb*E&k^T3$FG1eQZ51g$uv4V+kI`0<^1Z@N zk?Jjh$olyC%l>)Xq;7!>{iBj&BjJ`P&$fsCfpve_epJOBkTF?nu-B7D!hO=2ZR}

C%4 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

FJ$wK}0tWNB{uH;AM~i diff --git a/app/src/main/res/mipmap-xhdpi/ic_launcher.webp b/app/src/main/res/mipmap-xhdpi/ic_launcher.webp index 948a3070fe34c611c42c0d3ad3013a0dce358be0..1c6e38a0c95b0b361455353c701c07e5eab5fbad 100644 GIT binary patch literal 1418 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 diff --git a/app/src/main/res/mipmap-xhdpi/ic_launcher_foreground.webp b/app/src/main/res/mipmap-xhdpi/ic_launcher_foreground.webp new file mode 100644 index 0000000000000000000000000000000000000000..ad5b97e3dd5d530e4becfb1e14dbbd3dcb63c5bb GIT binary patch literal 684 zcmV;d0#p4`Nk&Gb0ssJ4MM6+kP&iDO0ssIn*T6LpfZ(=`B#Hlj_smq)wBxRg6YN>SxEfGq(G@=ZZ z_-GIh2k{1dRnMGcUsw*d5TI~gtD}O5bw!?!OS4-tXx7>Ab;2D=y`uK<|!UJA)> zNOE__2&~$&%MMsI>5Tv~#V~SMH>~?Zbq_UvmjDbn$)FT0Et_>9u+h9#M0OCd2Dbqa zEtXQPM39##?A60+2Wx$>7jchYALP}WKw-C^OxBqC1-nt>8pxMH)B)qLAN7^N3Paz} zZ2%_hCtL+ZC-87oyIKmbP*A5Gj^gYl*MwS=a2V&IV#1FIEAbEqhm9#Of`ef=kC-B` zPoYBl2uvYx-Y};cNI8ML!CRxwl5IhNAqZ<2B@kJD1NLUJqXBO+ zc~$@kZJ9I^osX5FOa__EC&6SU6Qbs`1eeL2`tgW44w+F0iA+bu(@@|(#p#&%m&#uT z({VPD${_pcq(N#_)O6Oz0*j_|FP96$5%E8lU&Arhn@bn<*@PO+Wr*i&YRu&_Eq^q^ zcB8ov>#&nia2JBRM0zqhekSvt#$>DwCDXxtGC@c(9M8$rLv-bnS&3gpu7u#1EuM@F zZ$W|=ZMl-wf)@qxB0bqgIad;osrL5Y?Z4k7WL!yXH;i;4S3z~t?*_})2D>h5lK^Zt S7z`mI7bT3j{eS!a_Wz{gcsY0g literal 0 HcmV?d00001 diff --git a/app/src/main/res/mipmap-xhdpi/ic_launcher_round.webp b/app/src/main/res/mipmap-xhdpi/ic_launcher_round.webp index 1b9a6956b3acdc11f40ce2bb3f6efbd845cc243f..7bc1ae7255c3d1c4867d5e9c0d7e0a3c42781ba8 100644 GIT binary patch literal 3928 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 literal 3918 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 literal 5914 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�(p-{x$&=IACIfoAR!za)F-^da-t3#0Dycnp zwO~NVXwXCl;jE<}>%@xz|=8fIJAB?>+E{7)|4l${4ngA3G|=r z2Dyv;VVWSgZx9Wj>qUjleGl3Ei9K4>h!(lPS%8VOG>Xu0%6VDz^O=bjJmuP7>DeUv zrbI}MlHB^^d?{zv6d=@_ZD2lg1&G7UjnVN{1}9WkaM3H~btX0GtSzB+tZ^qRgWo4m z!GmimlG$=wgXCnr6j@m<1gAL46#T~5Bnm=2{^@>|t&`9mkEPddj zAvG~@Tv~TAm2i%VW}R-g(Z0)z-Y|szHr@rk>4MAyG*Ma*7Yh#H7(!-5>DZ@8r;_dx z{prSe<>~099F8vsYd2xff7uAS%7{S)f(|@me3t2$iy&NEc7OUEchp@9A|X;;IA>8!oX+y(BKJ$EzV* znR$z;!L$s7uy@{OT~nG#B!NRraT8(X##Ho!0r_o@gg0CA-9H^;-uE&?$2$nHv_00o z%cbuUc-tCx$Uh&EZ4Nf4Zgqv)Y6>usG3>GeQnxx_Z6+PcbX-+ysbt1hQ`K1LDpOE? zrAhIZhSN9yVIAOa22gn577tbc&i3|3V8NWy&!tw##`}9*x}gtI^h1DzZRA>UuaJG) zaZ7j)dq!O}{?#8Y7~7i6fHh4{`pL?>-18|p!S75Y#^DM>-S3)vuZG+Q7l@ek zQP~#cBpWgg#mApc_sPYjpw8odQuRokmTkzcNl`^CcKB7e&;zViV;{Y{o^Y$%7i0m# z62%#1Lq!RC?}lK>%mp}T!3Xv;L*0v*>USLm``N%>w>@fwC+#T&Tx2bN4w(20JB}oU zuSa6v^kXi0xPs?pbaOHnyiqq6By1EZY9OZ^^QA>{q-Hsd&m`pbQ%8121aWG-F5xf zlZ%;B{;C>X19|`^_?dVyCq>n+41w7|!tUS!{9rHlbhX=SZO5CQ^;!Du_E7*`GiR^Q w)2!4MKjfSAeNsfF7Ga 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 axy@2-Bf>FI#28}}&=@1aF;@u4TXhko$bYo} literal 3844 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 literal 0 HcmV?d00001 diff --git a/app/src/main/res/mipmap-xxxhdpi/ic_launcher_round.webp b/app/src/main/res/mipmap-xxxhdpi/ic_launcher_round.webp index 9126ae37cbc3587421d6889eadd1d91fbf1994d4..55897692bdc7e5852f63ad51e5175e6a47fc5f65 100644 GIT binary patch literal 8398 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 z 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 literal 7778 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

UmY2RIYtNPVDpE$%vda+HD#3m z&VuXJ{BK&Qe+rBa7eq}Q(bq|tn(RrJAk|ztj2(i{d>nmQnM?;HF2k&9sA6up5tmjl z7lySlzMbifH17-m-Lwa_F&e7nOH?ESi3#ckR3tsM+jsck3`oG!uMS}|eAwVXv>}qxwq?QY%QJ0}r@^;fhuUA9W z*BVl>TGo&N004@xSiwDUXUvp51sVmqO3m)=B55aPwf@0=e}cN+$-BdKxY`YrT_4)0 z_d10#i44Q*rFr8MC>*)v$EJvz``(pb{e&*6k+b zsMz%($|1+8hn8c2?P(l@;Rb&CsZeYoCI3?2!LqjbwPXW3z4G$Qfj=cT5Yb%vY0(AX oeb?AaKtwrnc|$|zzw9vfvn^aJJ!zd)XFXqqy0000001=f@-~a#s diff --git a/app/src/main/res/values/ic_launcher_background.xml b/app/src/main/res/values/ic_launcher_background.xml new file mode 100644 index 0000000..7784b37 --- /dev/null +++ b/app/src/main/res/values/ic_launcher_background.xml @@ -0,0 +1,4 @@ + + + #FF9C41 + \ No newline at end of file From b338eedee8ce29867a842458e44e049689289bd2 Mon Sep 17 00:00:00 2001 From: Liideli Date: Thu, 12 Oct 2023 18:55:08 +0300 Subject: [PATCH 24/32] Added icons. --- AppOpen.png | Bin 0 -> 60416 bytes 1 file changed, 0 insertions(+), 0 deletions(-) create mode 100644 AppOpen.png diff --git a/AppOpen.png b/AppOpen.png new file mode 100644 index 0000000000000000000000000000000000000000..202bc5b343fb6aedb465f035a8e2104374129d8d GIT binary patch literal 60416 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 literal 0 HcmV?d00001 From 323f8d17fbcf294ea8ec118bc7a591d945a0950c Mon Sep 17 00:00:00 2001 From: Yana Krylova Date: Thu, 12 Oct 2023 18:55:37 +0300 Subject: [PATCH 25/32] Design --- .../mycloset/ApiWorkingSet/ImgDisplay.kt | 5 +- .../com/example/mycloset/Views/HomeScreen.kt | 132 ++++++----- .../com/example/mycloset/Views/ItemCard.kt | 32 ++- .../example/mycloset/Views/ProductScanView.kt | 21 +- .../mycloset/Views/SingleItemScreen.kt | 205 +++++++++--------- 5 files changed, 228 insertions(+), 167 deletions(-) diff --git a/app/src/main/java/com/example/mycloset/ApiWorkingSet/ImgDisplay.kt b/app/src/main/java/com/example/mycloset/ApiWorkingSet/ImgDisplay.kt index 4a869e5..0d30cc2 100644 --- a/app/src/main/java/com/example/mycloset/ApiWorkingSet/ImgDisplay.kt +++ b/app/src/main/java/com/example/mycloset/ApiWorkingSet/ImgDisplay.kt @@ -5,6 +5,7 @@ import android.graphics.BitmapFactory import android.util.Log import androidx.compose.foundation.Image import androidx.compose.foundation.layout.size +import androidx.compose.foundation.shape.RoundedCornerShape import androidx.compose.runtime.Composable import androidx.compose.runtime.LaunchedEffect import androidx.compose.runtime.getValue @@ -12,6 +13,7 @@ import androidx.compose.runtime.mutableStateOf import androidx.compose.runtime.remember import androidx.compose.runtime.setValue import androidx.compose.ui.Modifier +import androidx.compose.ui.draw.clip import androidx.compose.ui.graphics.ImageBitmap import androidx.compose.ui.graphics.asImageBitmap import androidx.compose.ui.unit.dp @@ -32,7 +34,8 @@ class ImgDisplay { bitmap= showImg(url)?.asImageBitmap() } bitmap?.let { bitmap -> - Image(modifier = Modifier.size(200.dp), bitmap = bitmap, contentDescription = "downloaded picture") + Image(modifier = Modifier.size(300.dp) + .clip(RoundedCornerShape(16.dp)), bitmap = bitmap, contentDescription = "downloaded picture" ) } } diff --git a/app/src/main/java/com/example/mycloset/Views/HomeScreen.kt b/app/src/main/java/com/example/mycloset/Views/HomeScreen.kt index 29bf4ee..10c1960 100644 --- a/app/src/main/java/com/example/mycloset/Views/HomeScreen.kt +++ b/app/src/main/java/com/example/mycloset/Views/HomeScreen.kt @@ -1,12 +1,13 @@ - package com.example.mycloset.Views import android.util.Log +import androidx.compose.foundation.background import androidx.compose.foundation.layout.Box import androidx.compose.foundation.layout.fillMaxSize import androidx.compose.foundation.layout.padding import androidx.compose.foundation.lazy.grid.GridCells import androidx.compose.foundation.lazy.grid.LazyVerticalGrid +import androidx.compose.foundation.shape.RoundedCornerShape import androidx.compose.material.* import androidx.compose.material.icons.Icons import androidx.compose.material.icons.filled.Camera @@ -14,14 +15,15 @@ import androidx.compose.material.icons.filled.Logout import androidx.compose.material3.ExperimentalMaterial3Api import androidx.compose.material3.Icon import androidx.compose.material3.IconButton +import androidx.compose.material3.MaterialTheme import androidx.compose.material3.Scaffold +import androidx.compose.material3.Surface import androidx.compose.material3.Text import androidx.compose.material3.TopAppBar import androidx.compose.runtime.* import androidx.compose.ui.Alignment import androidx.compose.ui.Modifier import androidx.compose.ui.text.style.TextAlign -import androidx.compose.ui.tooling.preview.Preview import androidx.compose.ui.unit.dp import androidx.lifecycle.viewmodel.compose.viewModel import com.example.mycloset.DatabaseWorkingset.ProductViewModel @@ -29,10 +31,12 @@ import com.example.mycloset.LoginWorkingSet.LoggedUser import com.example.mycloset.LoginWorkingSet.Signup.SignupViewModel import com.example.mycloset.navigation.LoginAppRouter import com.example.mycloset.navigation.Screen +import com.example.mycloset.ui.theme.md_theme_light_outline +import com.example.mycloset.ui.theme.md_theme_light_primary +import com.example.mycloset.ui.theme.textType import kotlinx.coroutines.flow.* - //import com.example.mycloset.Screen @OptIn(ExperimentalMaterial3Api::class) @@ -48,17 +52,72 @@ fun HomeScreen(productViewModel: ProductViewModel) { val products = productViewModel.products if (products.isEmpty()) { - Scaffold( - topBar = { + Surface( + modifier = Modifier.fillMaxSize(), + color = md_theme_light_outline + ) { + Scaffold( + topBar = { + TopAppBar( + title = { + Text( + "MyCloset", + modifier = Modifier, + style = textType.titleLarge, + ) + }, + actions = { + IconButton( + onClick = { LoginAppRouter.navigateTo(Screen.ProductScanView) } + ) { + Icon(Icons.Default.Camera, contentDescription = null) + } + IconButton( + onClick = { + signupViewModel.logout() + } + ) { + Icon(Icons.Default.Logout, contentDescription = "Logout") + } + } + ) + }) { innerPadding -> + Box( + modifier = Modifier + .fillMaxSize() + .padding(innerPadding) + .background(md_theme_light_outline), + contentAlignment = Alignment.Center, + ) { + Text( + text = "You don't have any items yet...", + textAlign = TextAlign.Center, + style = textType.bodyLarge + ) + } + } + } + } else { + Surface( + modifier = Modifier.fillMaxSize(), + color = md_theme_light_outline + ) { + Scaffold(topBar = { TopAppBar( title = { - Text("MyCloset") + Text( + "MyCloset", + modifier = Modifier.padding(2.dp), + style = textType.titleLarge, + ) }, actions = { IconButton( - onClick = { LoginAppRouter.navigateTo(Screen.ProductScanView) } + onClick = { + LoginAppRouter.navigateTo(Screen.ProductScanView) + } ) { - Icon(Icons.Default.Camera, contentDescription = null) + Icon(Icons.Default.Camera, contentDescription = "Camera") } IconButton( onClick = { @@ -70,51 +129,22 @@ fun HomeScreen(productViewModel: ProductViewModel) { } ) }) { innerPadding -> - Box( - modifier = Modifier - .fillMaxSize() - .padding(innerPadding), - contentAlignment = Alignment.Center - ) { - Text( - text = "You don't have any items yet...", - textAlign = TextAlign.Center, - ) - } - } - } else { - Scaffold(topBar = { - TopAppBar( - title = { - Text("MyCloset", modifier = Modifier.padding(2.dp)) - }, - actions = { - IconButton( - onClick = { - LoginAppRouter.navigateTo(Screen.ProductScanView)} - ) { - Icon(Icons.Default.Camera, contentDescription = "Camera") - } - IconButton( - onClick = { - signupViewModel.logout() - } - ) { - Icon(Icons.Default.Logout, contentDescription = "Logout") + LazyVerticalGrid( + columns = GridCells.Fixed(2), modifier = Modifier + .fillMaxSize() + .padding(innerPadding) + .background(md_theme_light_outline) + ) { + items(products.size) { index -> + val product = products[index] + ItemCard( + product.images, + product.title, + product.barcodeNumber, + productViewModel + ) } } - ) - }) { innerPadding -> - LazyVerticalGrid( - columns = GridCells.Fixed(2), modifier = Modifier - .fillMaxSize() - .padding(innerPadding) - .padding(16.dp) - ) { - items(products.size) { index -> - val product = products[index] - ItemCard(product.images, product.title, product.barcodeNumber, productViewModel) - } } } } diff --git a/app/src/main/java/com/example/mycloset/Views/ItemCard.kt b/app/src/main/java/com/example/mycloset/Views/ItemCard.kt index cb60206..3b3476b 100644 --- a/app/src/main/java/com/example/mycloset/Views/ItemCard.kt +++ b/app/src/main/java/com/example/mycloset/Views/ItemCard.kt @@ -1,7 +1,9 @@ package com.example.mycloset.Views import androidx.compose.foundation.Image +import androidx.compose.foundation.background import androidx.compose.foundation.layout.Column +import androidx.compose.foundation.layout.aspectRatio import androidx.compose.foundation.layout.padding import androidx.compose.foundation.layout.size import androidx.compose.foundation.shape.RoundedCornerShape @@ -11,12 +13,20 @@ import androidx.compose.material3.ExperimentalMaterial3Api import androidx.compose.material3.MaterialTheme import androidx.compose.material3.Text import androidx.compose.runtime.Composable +import androidx.compose.ui.Alignment import androidx.compose.ui.Modifier import androidx.compose.ui.unit.dp import coil.compose.rememberAsyncImagePainter import com.example.mycloset.DatabaseWorkingset.ProductViewModel import com.example.mycloset.navigation.LoginAppRouter import com.example.mycloset.navigation.Screen +import com.example.mycloset.ui.theme.md_theme_dark_onTertiaryContainer +import com.example.mycloset.ui.theme.md_theme_dark_secondaryContainer +import com.example.mycloset.ui.theme.md_theme_light_outline +import com.example.mycloset.ui.theme.md_theme_light_primary +import com.example.mycloset.ui.theme.md_theme_light_primaryContainer +import com.example.mycloset.ui.theme.md_theme_light_secondaryContainer +import com.example.mycloset.ui.theme.textType data class Item(val id: Int, val title: String, val imageUrl: String) @@ -31,29 +41,35 @@ fun ItemCard( // onClick: () -> Unit ) { Card( - colors = CardDefaults.cardColors( - containerColor = MaterialTheme.colorScheme.surfaceVariant, - ), - modifier = Modifier.padding(5.dp), + modifier = Modifier + .padding(5.dp) + .background(md_theme_light_outline), shape = RoundedCornerShape(10.dp), onClick = { productViewModel.setSelectedProduct(barcodeNumber) LoginAppRouter.navigateTo(Screen.SingleItemScreen) } ) { - Column(modifier = Modifier.padding(10.dp)) { + Column( + modifier = Modifier + .padding(10.dp) + .background(md_theme_light_secondaryContainer), + horizontalAlignment = Alignment.CenterHorizontally + ) { Image( painter = rememberAsyncImagePainter(imageUrl), contentDescription = null, - modifier = Modifier.size(120.dp) + modifier = Modifier + .size(120.dp) + .aspectRatio(16f / 9f) + .background(md_theme_light_secondaryContainer) ) - name?.let { Text(text = it) } + name?.let { Text(text = it, style = textType.bodyMedium) } } } } - /* @Preview @Composable diff --git a/app/src/main/java/com/example/mycloset/Views/ProductScanView.kt b/app/src/main/java/com/example/mycloset/Views/ProductScanView.kt index 2c0eada..4d66174 100644 --- a/app/src/main/java/com/example/mycloset/Views/ProductScanView.kt +++ b/app/src/main/java/com/example/mycloset/Views/ProductScanView.kt @@ -55,6 +55,7 @@ import com.example.mycloset.DatabaseWorkingset.ProductViewModel import com.example.mycloset.LoginWorkingSet.LoggedUser import com.example.mycloset.navigation.LoginAppRouter import com.example.mycloset.navigation.Screen +import com.example.mycloset.ui.theme.textType import kotlinx.coroutines.flow.StateFlow //@OptIn(ExperimentalMaterial3Api::class) @@ -94,7 +95,7 @@ fun ProductScanView( Scaffold(topBar = { TopAppBar( title = { - Text("MyCloset", modifier = Modifier.padding(2.dp)) + Text("MyCloset", modifier = Modifier.padding(2.dp), style = textType.titleLarge) }, actions = { IconButton( @@ -225,7 +226,7 @@ fun ProductScanView( Scaffold(topBar = { TopAppBar( title = { - Text("MyCloset", modifier = Modifier.padding(2.dp)) + Text("MyCloset", modifier = Modifier.padding(2.dp), style = textType.titleLarge) }, actions = { IconButton( @@ -266,31 +267,31 @@ fun ProductScanView( } item { - Text("Barcode: ${informationProductObject.barcodeNumber}") + Text("Barcode: ${informationProductObject.barcodeNumber}", style = textType.bodyMedium) } item { - Text("Model: ${informationProductObject.model}") + Text("Model: ${informationProductObject.model}", style = textType.bodyMedium) } item { - Text("Category: ${informationProductObject.category}") + Text("Category: ${informationProductObject.category}", style = textType.bodyMedium) } item { - Text("Brand: ${informationProductObject.brand}") + Text("Brand: ${informationProductObject.brand}", style = textType.bodyMedium) } item { - Text("Color: ${informationProductObject.color}") + Text("Color: ${informationProductObject.color}", style = textType.bodyMedium) } item { - Text("Material: ${informationProductObject.material}") + Text("Material: ${informationProductObject.material}", style = textType.bodyMedium) } item { - Text("Size: ${informationProductObject.size}") + Text("Size: ${informationProductObject.size}", style = textType.bodyMedium) } } // Buttons for cancel and add actions @@ -301,7 +302,7 @@ fun ProductScanView( Button(onClick = { showProductInfo = false }) { - Text(text = "Back") + Text(text = "Back", style = textType.bodyMedium) } if (LoggedUser.loggedUserEmail != "") { Button(onClick = { diff --git a/app/src/main/java/com/example/mycloset/Views/SingleItemScreen.kt b/app/src/main/java/com/example/mycloset/Views/SingleItemScreen.kt index 2dc0398..aaf7bd6 100644 --- a/app/src/main/java/com/example/mycloset/Views/SingleItemScreen.kt +++ b/app/src/main/java/com/example/mycloset/Views/SingleItemScreen.kt @@ -1,6 +1,7 @@ package com.example.mycloset.Views import android.widget.Toast +import androidx.compose.foundation.background import androidx.compose.foundation.layout.Arrangement import androidx.compose.foundation.layout.Column import androidx.compose.foundation.layout.PaddingValues @@ -20,6 +21,7 @@ import androidx.compose.material3.ExperimentalMaterial3Api import androidx.compose.material3.Icon import androidx.compose.material3.IconButton import androidx.compose.material3.Scaffold +import androidx.compose.material3.Surface import androidx.compose.material3.Text import androidx.compose.material3.TopAppBar import androidx.compose.runtime.Composable @@ -37,6 +39,10 @@ import com.example.mycloset.DatabaseWorkingset.ProductViewModel import com.example.mycloset.LoginWorkingSet.Signup.SignupViewModel import com.example.mycloset.navigation.LoginAppRouter import com.example.mycloset.navigation.Screen +import com.example.mycloset.ui.theme.fontFamily +import com.example.mycloset.ui.theme.fontFamilyText +import com.example.mycloset.ui.theme.md_theme_light_outline +import com.example.mycloset.ui.theme.textType @OptIn(ExperimentalMaterial3Api::class, ExperimentalMaterial3Api::class) @Composable @@ -46,121 +52,126 @@ fun SingleItemScreen(productViewModel: ProductViewModel) { productViewModel.getProductWithBarcode(productViewModel.selectedProduct) val products = productViewModel.products val context = LocalContext.current - - Scaffold( - topBar = { - // TopAppBar (the top bar) - TopAppBar( - navigationIcon = { - IconButton(onClick = { LoginAppRouter.navigateTo(Screen.HomeScreen) }) { - Icon( - Icons.Default.ArrowBack, - contentDescription = "Back" - ) - } - }, - title = { - Text("MyCloset") - }, - actions = { - IconButton(onClick = { LoginAppRouter.navigateTo(Screen.ProductScanView) }) { - Icon( - Icons.Default.Camera, - contentDescription = "Camera" - ) - } - IconButton( - onClick = { - viewModel.logout() + Surface(modifier = Modifier.background(md_theme_light_outline)) { + Scaffold( + topBar = { + // TopAppBar (the top bar) + TopAppBar( + navigationIcon = { + IconButton(onClick = { LoginAppRouter.navigateTo(Screen.HomeScreen) }) { + Icon( + Icons.Default.ArrowBack, + contentDescription = "Back" + ) + } + }, + title = { + Text("MyCloset", style = textType.titleLarge) + }, + actions = { + IconButton(onClick = { LoginAppRouter.navigateTo(Screen.ProductScanView) }) { + Icon( + Icons.Default.Camera, + contentDescription = "Camera" + ) + } + IconButton( + onClick = { + viewModel.logout() + } + ) { + Icon(Icons.Default.Logout, contentDescription = "Logout") } - ) { - Icon(Icons.Default.Logout, contentDescription = "Logout") } - } - ) - } - ) { innerPadding -> - // Content to be displayed below the top bar - Column( - modifier = Modifier - .fillMaxSize() - .padding(innerPadding) - .padding(16.dp) - ) { - val product = products[0] - - Column(modifier = Modifier.fillMaxWidth(), horizontalAlignment = Alignment.CenterHorizontally) { - DisplayPicture(product.images) + ) } - - Spacer(modifier = Modifier.height(24.dp)) - - - LazyColumn( - modifier = Modifier.fillMaxWidth(), - contentPadding = PaddingValues(16.dp) + ) { innerPadding -> + // Content to be displayed below the top bar + Column( + modifier = Modifier + .fillMaxSize() + .padding(innerPadding) + .background(md_theme_light_outline) ) { - item { - Text( - text = "Product Information", - fontWeight = FontWeight.Bold, - fontSize = 18.sp, - modifier = Modifier.padding(bottom = 8.dp) - ) - } + val product = products[0] - item { - Text("Barcode: ${product.barcodeNumber}") + Column( + modifier = Modifier.fillMaxWidth(), + horizontalAlignment = Alignment.CenterHorizontally + ) { + DisplayPicture(product.images) } - item { - Text("Model: ${product.model}") - } + Spacer(modifier = Modifier.height(24.dp)) - item { - Text("Category: ${product.category}") - } - item { - Text("Brand: ${product.brand}") - } + LazyColumn( + modifier = Modifier.fillMaxWidth(), + contentPadding = PaddingValues(16.dp) + ) { + item { + Text( + text = "Product Information", + style = textType.bodyMedium, + fontWeight = FontWeight.Bold, + fontSize = 18.sp, + modifier = Modifier.padding(bottom = 8.dp) + ) + } - item { - Text("Color: ${product.color}") - } + item { + Text("Barcode: ${product.barcodeNumber}", style = textType.bodyMedium) + } - item { - Text("Material: ${product.material}") - } + item { + Text("Model: ${product.model}", style = textType.bodyMedium) + } - item { - Text("Size: ${product.size}") - } + item { + Text("Category: ${product.category}", style = textType.bodyMedium) + } - } + item { + Text("Brand: ${product.brand}", style = textType.bodyMedium) + } - // Add more text components or other content as needed - Row( - modifier = Modifier - .fillMaxWidth() - .padding(16.dp), - horizontalArrangement = Arrangement.SpaceBetween - ) { - Button( - onClick = { - productViewModel.deleteProduct(productViewModel.selectedProduct) - Toast.makeText(context, "Item Deleted!", Toast.LENGTH_SHORT).show() - LoginAppRouter.navigateTo(Screen.HomeScreen) + item { + Text("Color: ${product.color}", style = textType.bodyMedium) + } + + item { + Text("Material: ${product.material}", style = textType.bodyMedium) } - ) { - Text("Delete Item") - } - Button( - onClick = { + item { + Text("Size: ${product.size}", style = textType.bodyMedium) } + + } + + // Add more text components or other content as needed + Row( + modifier = Modifier + .fillMaxWidth() + .padding(16.dp), + horizontalArrangement = Arrangement.SpaceBetween ) { - Text("Update Item") + Button( + onClick = { + productViewModel.deleteProduct(productViewModel.selectedProduct) + Toast.makeText(context, "Item Deleted!", Toast.LENGTH_SHORT).show() + LoginAppRouter.navigateTo(Screen.HomeScreen) + } + ) { + Text("Delete Item") + } + Button( + onClick = { + + } + ) { + Text("Update Item") + } } } } From 83cc3ba46d02747c1a0a8bc53d6c1f59609af8ea Mon Sep 17 00:00:00 2001 From: matti Date: Thu, 12 Oct 2023 17:59:26 +0200 Subject: [PATCH 26/32] Graphics adaptation --- app/src/main/AndroidManifest.xml | 1 + .../BarcodeWorkingSet/BarcodeRepository.kt | 2 +- .../OfflineProductRepository.kt | 3 +- .../DatabaseWorkingset/ProductRepository.kt | 2 - .../DatabaseWorkingset/ProductViewModel.kt | 24 ++-- .../com/example/mycloset/Views/HomeScreen.kt | 2 +- .../example/mycloset/Views/ProductScanView.kt | 133 ++++++++++++++---- .../mycloset/Views/SingleItemScreen.kt | 101 ++++++++++--- .../mycloset/Views/UpdateSingleItem.kt | 4 +- 9 files changed, 212 insertions(+), 60 deletions(-) diff --git a/app/src/main/AndroidManifest.xml b/app/src/main/AndroidManifest.xml index 7fc1006..a01517f 100644 --- a/app/src/main/AndroidManifest.xml +++ b/app/src/main/AndroidManifest.xml @@ -12,6 +12,7 @@ > fun getAllProductsWithEmailStream(userEmail: String): Flow> fun getAllProductWithBarcodeStream(barcodeNumber: String): Flow> - // fun getAllProductWithBarcodeStream(barcodeNumber: String, userEmail: String):ProductEntity suspend fun updateProductDetailsStream(product: ProductEntity) suspend fun deleteProductStream(barcodeNumber: String) } \ No newline at end of file diff --git a/app/src/main/java/com/example/mycloset/DatabaseWorkingset/ProductViewModel.kt b/app/src/main/java/com/example/mycloset/DatabaseWorkingset/ProductViewModel.kt index 9a75a18..68dda10 100644 --- a/app/src/main/java/com/example/mycloset/DatabaseWorkingset/ProductViewModel.kt +++ b/app/src/main/java/com/example/mycloset/DatabaseWorkingset/ProductViewModel.kt @@ -31,18 +31,22 @@ class ProductViewModel(val productDao: ProductDao, val productRepository: Produc obj:ProductObject ) { viewModelScope.launch(Dispatchers.IO) { - val productInformation = ProductEntity(obj.barcodeNumber,obj.userEmail,obj.model,obj.title,obj.category,obj.brand,obj.color,obj.material,obj.size,obj.images) - productDao.insertProduct(productInformation) - Log.i("SAV", "Saved to database") - } - } - // Get all products - fun getProducts() { - viewModelScope.launch { - productRepository.getAllProductsStream().collect() { response -> - products = response + //If the title is to big, make it shorter + val title = obj.title + val titleModified = if ("," in title) { + title.substringBefore(",") + } else { + title } + + //Same for the category + val categoryText = obj.category + val category = categoryText.substringAfterLast(">") + + val productInformation = ProductEntity(obj.barcodeNumber,obj.userEmail,obj.model,titleModified,category,obj.brand,obj.color,obj.material,obj.size,obj.images) + productDao.insertProduct(productInformation) + Log.i("SAV", "Saved to database") } } diff --git a/app/src/main/java/com/example/mycloset/Views/HomeScreen.kt b/app/src/main/java/com/example/mycloset/Views/HomeScreen.kt index b8bd6b9..ff1c206 100644 --- a/app/src/main/java/com/example/mycloset/Views/HomeScreen.kt +++ b/app/src/main/java/com/example/mycloset/Views/HomeScreen.kt @@ -106,7 +106,7 @@ fun HomeScreen(productViewModel: ProductViewModel) { ) { items(products.size) { index -> val product = products[index] - ItemCard(product.images, product.title) + ItemCard(product.images, product.title,product.barcodeNumber,productViewModel) } } } diff --git a/app/src/main/java/com/example/mycloset/Views/ProductScanView.kt b/app/src/main/java/com/example/mycloset/Views/ProductScanView.kt index 2c0eada..c7bd7ec 100644 --- a/app/src/main/java/com/example/mycloset/Views/ProductScanView.kt +++ b/app/src/main/java/com/example/mycloset/Views/ProductScanView.kt @@ -6,13 +6,17 @@ import android.widget.LinearLayout import android.widget.Toast import androidx.camera.view.LifecycleCameraController import androidx.camera.view.PreviewView +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.PaddingValues import androidx.compose.foundation.layout.Row +import androidx.compose.foundation.layout.Spacer import androidx.compose.foundation.layout.fillMaxHeight 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 @@ -44,6 +48,7 @@ import androidx.compose.runtime.rememberUpdatedState import androidx.compose.runtime.setValue import androidx.compose.ui.Alignment import androidx.compose.ui.Modifier +import androidx.compose.ui.graphics.Color import androidx.compose.ui.platform.LocalContext import androidx.compose.ui.text.font.FontWeight import androidx.compose.ui.unit.dp @@ -98,8 +103,11 @@ fun ProductScanView( }, actions = { IconButton( - onClick = { LoginAppRouter.navigateTo(Screen.HomeScreen) } + onClick = { + LoginAppRouter.navigateTo(Screen.HomeScreen) + } ) { + Icon(Icons.Default.Home, contentDescription = "Camera") } } @@ -229,7 +237,9 @@ fun ProductScanView( }, actions = { IconButton( - onClick = { LoginAppRouter.navigateTo(Screen.ProductScanView) } + onClick = { + showProductInfo=false + } ) { Icon(Icons.Default.Camera, contentDescription = "Camera") } @@ -241,58 +251,130 @@ fun ProductScanView( modifier = Modifier .fillMaxSize() .padding(innerPadding) - .padding(16.dp) + .padding(18.dp) ) { + //If the title is to big, make it shorter + val title = informationProductObject.title + val textToDisplay = if ("," in title) { + title.substringBefore(",") + } else { + title + } + //Title Text( - text = informationProductObject.title, - modifier = Modifier.padding(16.dp) + text = textToDisplay, + fontWeight = FontWeight.Bold, + fontSize = 18.sp, ) - + Spacer(modifier = Modifier.height(24.dp)) // Image of the product - ImgDisplay.DisplayPicture(informationProductObject.images) - + Column(modifier = Modifier.fillMaxWidth(), horizontalAlignment = Alignment.CenterHorizontally) { + ImgDisplay.DisplayPicture(informationProductObject.images) + } + Spacer(modifier = Modifier.height(24.dp)) LazyColumn( modifier = Modifier.fillMaxWidth(), contentPadding = PaddingValues(16.dp) ) { item { Text( - text = "Product Information", + text = "Product Information :", fontWeight = FontWeight.Bold, fontSize = 18.sp, modifier = Modifier.padding(bottom = 8.dp) ) } - + //the barcode always exist item { - Text("Barcode: ${informationProductObject.barcodeNumber}") + Box( + modifier = Modifier + .fillMaxWidth() + .padding(4.dp) + .background(MaterialTheme.colorScheme.surfaceVariant) // Colore di sfondo personalizzato per Model + ) { + Text("Barcode: ${informationProductObject.barcodeNumber}") + } } - item { - Text("Model: ${informationProductObject.model}") + if(informationProductObject.model!=""){ + item { + Box( + modifier = Modifier + .fillMaxWidth() + .padding(4.dp) + .background(MaterialTheme.colorScheme.surfaceVariant) // Colore di sfondo personalizzato per Model + ) { + Text("Model: ${informationProductObject.model}") + } + } } item { - Text("Category: ${informationProductObject.category}") + Box( + modifier = Modifier + .fillMaxWidth() + .padding(4.dp) + .background(MaterialTheme.colorScheme.surfaceVariant) // Colore di sfondo personalizzato per Model + ) { + val categoryText = informationProductObject.category + val category = categoryText.substringAfterLast(">") + Text("Category: $category") + } } - item { - Text("Brand: ${informationProductObject.brand}") + if(informationProductObject.brand!=""){ + item { + Box( + modifier = Modifier + .fillMaxWidth() + .padding(4.dp) + .background(MaterialTheme.colorScheme.surfaceVariant) // Colore di sfondo personalizzato per Model + ) { + Text("Brand: ${informationProductObject.brand}") + } + } } - - item { - Text("Color: ${informationProductObject.color}") + if(informationProductObject.color!="") { + item { + Box( + modifier = Modifier + .fillMaxWidth() + .padding(4.dp) + .background(MaterialTheme.colorScheme.surfaceVariant) // Colore di sfondo personalizzato per Model + ) { + Text("Color: ${informationProductObject.color}") + } + } } - - item { - Text("Material: ${informationProductObject.material}") + if(informationProductObject.material!="") { + item { + Box( + modifier = Modifier + .fillMaxWidth() + .padding(4.dp) + .background(MaterialTheme.colorScheme.surfaceVariant) // Colore di sfondo personalizzato per Model + ) { + Text("Material: ${informationProductObject.material}") + } + } } - - item { - Text("Size: ${informationProductObject.size}") + if(informationProductObject.size!=""){ + item { + Box( + modifier = Modifier + .fillMaxWidth() + .padding(4.dp) + .background(MaterialTheme.colorScheme.surfaceVariant) // Colore di sfondo personalizzato per Model + ) { + Text("Size: ${informationProductObject.size}") + } + } } + } + + Spacer(modifier = Modifier.weight(1f)) // Buttons for cancel and add actions Row( modifier = Modifier.fillMaxWidth(), @@ -322,3 +404,4 @@ fun ProductScanView( } } } + diff --git a/app/src/main/java/com/example/mycloset/Views/SingleItemScreen.kt b/app/src/main/java/com/example/mycloset/Views/SingleItemScreen.kt index 2dc0398..8e2ec58 100644 --- a/app/src/main/java/com/example/mycloset/Views/SingleItemScreen.kt +++ b/app/src/main/java/com/example/mycloset/Views/SingleItemScreen.kt @@ -1,7 +1,9 @@ package com.example.mycloset.Views import android.widget.Toast +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.PaddingValues import androidx.compose.foundation.layout.Row @@ -19,6 +21,7 @@ import androidx.compose.material3.Button import androidx.compose.material3.ExperimentalMaterial3Api import androidx.compose.material3.Icon import androidx.compose.material3.IconButton +import androidx.compose.material3.MaterialTheme import androidx.compose.material3.Scaffold import androidx.compose.material3.Text import androidx.compose.material3.TopAppBar @@ -89,6 +92,14 @@ fun SingleItemScreen(productViewModel: ProductViewModel) { ) { val product = products[0] + Text( + text = product.title, + fontWeight = FontWeight.Bold, + fontSize = 18.sp, + ) + + Spacer(modifier = Modifier.height(24.dp)) + Column(modifier = Modifier.fillMaxWidth(), horizontalAlignment = Alignment.CenterHorizontally) { DisplayPicture(product.images) } @@ -102,7 +113,7 @@ fun SingleItemScreen(productViewModel: ProductViewModel) { ) { item { Text( - text = "Product Information", + text = "Product Information :", fontWeight = FontWeight.Bold, fontSize = 18.sp, modifier = Modifier.padding(bottom = 8.dp) @@ -110,35 +121,91 @@ fun SingleItemScreen(productViewModel: ProductViewModel) { } item { - Text("Barcode: ${product.barcodeNumber}") + Box( + modifier = Modifier + .fillMaxWidth() + .padding(4.dp) + .background(MaterialTheme.colorScheme.surfaceVariant) // Colore di sfondo personalizzato per Model + ) { + Text("Barcode: ${product.barcodeNumber}") + } } - item { - Text("Model: ${product.model}") + if(product.model!=""){ + item { + Box( + modifier = Modifier + .fillMaxWidth() + .padding(4.dp) + .background(MaterialTheme.colorScheme.surfaceVariant) // Colore di sfondo personalizzato per Model + ) { + Text("Model: ${product.model}") + } + } } item { - Text("Category: ${product.category}") + Box( + modifier = Modifier + .fillMaxWidth() + .padding(4.dp) + .background(MaterialTheme.colorScheme.surfaceVariant) // Colore di sfondo personalizzato per Model + ) { + Text("Category: ${product.category}") + } } - - item { - Text("Brand: ${product.brand}") + if(product.brand!=""){ + item { + Box( + modifier = Modifier + .fillMaxWidth() + .padding(4.dp) + .background(MaterialTheme.colorScheme.surfaceVariant) // Colore di sfondo personalizzato per Model + ) { + Text("Brand: ${product.brand}") + } + } } - item { - Text("Color: ${product.color}") + if(product.color!="") { + item { + Box( + modifier = Modifier + .fillMaxWidth() + .padding(4.dp) + .background(MaterialTheme.colorScheme.surfaceVariant) // Colore di sfondo personalizzato per Model + ) { + Text("Color: ${product.color}") + } + } } - - item { - Text("Material: ${product.material}") + if(product.material!="") { + item { + Box( + modifier = Modifier + .fillMaxWidth() + .padding(4.dp) + .background(MaterialTheme.colorScheme.surfaceVariant) // Colore di sfondo personalizzato per Model + ) { + Text("Material: ${product.material}") + } + } } - - item { - Text("Size: ${product.size}") + if(informationProductObject.size!=""){ + item { + Box( + modifier = Modifier + .fillMaxWidth() + .padding(4.dp) + .background(MaterialTheme.colorScheme.surfaceVariant) // Colore di sfondo personalizzato per Model + ) { + Text("Size: ${informationProductObject.size}") + } + } } } - + Spacer(modifier = Modifier.weight(1f)) // Add more text components or other content as needed Row( modifier = Modifier diff --git a/app/src/main/java/com/example/mycloset/Views/UpdateSingleItem.kt b/app/src/main/java/com/example/mycloset/Views/UpdateSingleItem.kt index 43948cb..9ca60f1 100644 --- a/app/src/main/java/com/example/mycloset/Views/UpdateSingleItem.kt +++ b/app/src/main/java/com/example/mycloset/Views/UpdateSingleItem.kt @@ -59,7 +59,7 @@ import kotlinx.coroutines.flow.StateFlow @Composable fun UpdateSingleItem( productViewModel: ProductViewModel, -) { +) {/* var editedProduct by remember { mutableStateOf(productViewModel.informationProductObject.copy()) } val context = LocalContext.current Scaffold( @@ -158,5 +158,5 @@ fun UpdateSingleItem( } } - } + }*/ } \ No newline at end of file From 869753f0dd88b7f6765be649eaa4ed9ee7dd2f1a Mon Sep 17 00:00:00 2001 From: matti Date: Thu, 12 Oct 2023 19:35:57 +0200 Subject: [PATCH 27/32] Update --- .../BarcodeWorkingSet/BarcodeRepository.kt | 2 +- .../DatabaseWorkingset/ProductEntity.kt | 14 +- .../DatabaseWorkingset/ProductViewModel.kt | 6 +- .../example/mycloset/Views/ProductScanView.kt | 27 ++- .../mycloset/Views/SingleItemScreen.kt | 35 +-- .../mycloset/Views/UpdateSingleItem.kt | 199 +++++++++++++----- 6 files changed, 203 insertions(+), 80 deletions(-) diff --git a/app/src/main/java/com/example/mycloset/BarcodeWorkingSet/BarcodeRepository.kt b/app/src/main/java/com/example/mycloset/BarcodeWorkingSet/BarcodeRepository.kt index 92af66e..0c9a0b8 100644 --- a/app/src/main/java/com/example/mycloset/BarcodeWorkingSet/BarcodeRepository.kt +++ b/app/src/main/java/com/example/mycloset/BarcodeWorkingSet/BarcodeRepository.kt @@ -3,7 +3,7 @@ package com.example.mycloset.BarcodeWorkingSet import com.example.mycloset.ApiWorkingSet.RetrofitObject // -var APY_KEY:String="82m5dj79cuxyk3ql4nbtxvgpsv4a1l" +var APY_KEY:String="i4fwimwj7nx49wkp564w68s0xaf04q" //class for using the barcode-lookup API class BarcodeRepository{ diff --git a/app/src/main/java/com/example/mycloset/DatabaseWorkingset/ProductEntity.kt b/app/src/main/java/com/example/mycloset/DatabaseWorkingset/ProductEntity.kt index fd52170..7bb1cdd 100644 --- a/app/src/main/java/com/example/mycloset/DatabaseWorkingset/ProductEntity.kt +++ b/app/src/main/java/com/example/mycloset/DatabaseWorkingset/ProductEntity.kt @@ -6,12 +6,12 @@ import androidx.room.Entity data class ProductEntity( val barcodeNumber: String, val userEmail: String, - val model: String, - val title: String, - val category: String, - val brand: String, - val color: String, - val material: String, - val size: String, + var model: String, + var title: String, + var category: String, + var brand: String, + var color: String, + var material: String, + var size: String, val images: String ) diff --git a/app/src/main/java/com/example/mycloset/DatabaseWorkingset/ProductViewModel.kt b/app/src/main/java/com/example/mycloset/DatabaseWorkingset/ProductViewModel.kt index 68dda10..dbc59c7 100644 --- a/app/src/main/java/com/example/mycloset/DatabaseWorkingset/ProductViewModel.kt +++ b/app/src/main/java/com/example/mycloset/DatabaseWorkingset/ProductViewModel.kt @@ -37,7 +37,11 @@ class ProductViewModel(val productDao: ProductDao, val productRepository: Produc val titleModified = if ("," in title) { title.substringBefore(",") } else { - title + if ("-" in title) { + title.substringBefore("-") + } else { + title + } } //Same for the category diff --git a/app/src/main/java/com/example/mycloset/Views/ProductScanView.kt b/app/src/main/java/com/example/mycloset/Views/ProductScanView.kt index c7bd7ec..e55ab78 100644 --- a/app/src/main/java/com/example/mycloset/Views/ProductScanView.kt +++ b/app/src/main/java/com/example/mycloset/Views/ProductScanView.kt @@ -259,7 +259,11 @@ fun ProductScanView( val textToDisplay = if ("," in title) { title.substringBefore(",") } else { - title + if ("-" in title) { + title.substringBefore("-") + } else { + title + } } //Title Text( @@ -267,16 +271,22 @@ fun ProductScanView( fontWeight = FontWeight.Bold, fontSize = 18.sp, ) + Spacer(modifier = Modifier.height(24.dp)) + // Image of the product Column(modifier = Modifier.fillMaxWidth(), horizontalAlignment = Alignment.CenterHorizontally) { ImgDisplay.DisplayPicture(informationProductObject.images) } + Spacer(modifier = Modifier.height(24.dp)) + LazyColumn( modifier = Modifier.fillMaxWidth(), contentPadding = PaddingValues(16.dp) ) { + + //information item { Text( text = "Product Information :", @@ -285,7 +295,8 @@ fun ProductScanView( modifier = Modifier.padding(bottom = 8.dp) ) } - //the barcode always exist + + //barcode number item { Box( modifier = Modifier @@ -297,6 +308,7 @@ fun ProductScanView( } } + //model if(informationProductObject.model!=""){ item { Box( @@ -310,6 +322,7 @@ fun ProductScanView( } } + //category item { Box( modifier = Modifier @@ -323,6 +336,7 @@ fun ProductScanView( } } + //brand if(informationProductObject.brand!=""){ item { Box( @@ -335,6 +349,8 @@ fun ProductScanView( } } } + + //color if(informationProductObject.color!="") { item { Box( @@ -347,6 +363,8 @@ fun ProductScanView( } } } + + //material if(informationProductObject.material!="") { item { Box( @@ -359,6 +377,8 @@ fun ProductScanView( } } } + + //size if(informationProductObject.size!=""){ item { Box( @@ -375,7 +395,8 @@ fun ProductScanView( } Spacer(modifier = Modifier.weight(1f)) - // Buttons for cancel and add actions + + //button Row( modifier = Modifier.fillMaxWidth(), horizontalArrangement = Arrangement.SpaceBetween diff --git a/app/src/main/java/com/example/mycloset/Views/SingleItemScreen.kt b/app/src/main/java/com/example/mycloset/Views/SingleItemScreen.kt index 8e2ec58..168033e 100644 --- a/app/src/main/java/com/example/mycloset/Views/SingleItemScreen.kt +++ b/app/src/main/java/com/example/mycloset/Views/SingleItemScreen.kt @@ -92,6 +92,7 @@ fun SingleItemScreen(productViewModel: ProductViewModel) { ) { val product = products[0] + //title Text( text = product.title, fontWeight = FontWeight.Bold, @@ -100,6 +101,7 @@ fun SingleItemScreen(productViewModel: ProductViewModel) { Spacer(modifier = Modifier.height(24.dp)) + //images Column(modifier = Modifier.fillMaxWidth(), horizontalAlignment = Alignment.CenterHorizontally) { DisplayPicture(product.images) } @@ -111,6 +113,8 @@ fun SingleItemScreen(productViewModel: ProductViewModel) { modifier = Modifier.fillMaxWidth(), contentPadding = PaddingValues(16.dp) ) { + + //product information item { Text( text = "Product Information :", @@ -120,6 +124,7 @@ fun SingleItemScreen(productViewModel: ProductViewModel) { ) } + //barcode number item { Box( modifier = Modifier @@ -131,6 +136,7 @@ fun SingleItemScreen(productViewModel: ProductViewModel) { } } + //model if(product.model!=""){ item { Box( @@ -144,6 +150,7 @@ fun SingleItemScreen(productViewModel: ProductViewModel) { } } + //category item { Box( modifier = Modifier @@ -154,6 +161,8 @@ fun SingleItemScreen(productViewModel: ProductViewModel) { Text("Category: ${product.category}") } } + + //brand if(product.brand!=""){ item { Box( @@ -167,6 +176,7 @@ fun SingleItemScreen(productViewModel: ProductViewModel) { } } + //color if(product.color!="") { item { Box( @@ -179,6 +189,8 @@ fun SingleItemScreen(productViewModel: ProductViewModel) { } } } + + //material if(product.material!="") { item { Box( @@ -191,6 +203,8 @@ fun SingleItemScreen(productViewModel: ProductViewModel) { } } } + + //size if(informationProductObject.size!=""){ item { Box( @@ -205,8 +219,10 @@ fun SingleItemScreen(productViewModel: ProductViewModel) { } } + Spacer(modifier = Modifier.weight(1f)) - // Add more text components or other content as needed + + //buttons Row( modifier = Modifier .fillMaxWidth() @@ -224,7 +240,7 @@ fun SingleItemScreen(productViewModel: ProductViewModel) { } Button( onClick = { - + LoginAppRouter.navigateTo(Screen.UpdateSingleScreen) } ) { Text("Update Item") @@ -232,17 +248,4 @@ fun SingleItemScreen(productViewModel: ProductViewModel) { } } } -} - - -/*@Composable -@Preview -fun SingleItemView(){ - SingleItemScreen() -}*/ - -//@Preview -//@Composable -//fun Info() { -// SingleItemScreen() -//} \ No newline at end of file +} \ No newline at end of file diff --git a/app/src/main/java/com/example/mycloset/Views/UpdateSingleItem.kt b/app/src/main/java/com/example/mycloset/Views/UpdateSingleItem.kt index 9ca60f1..20cca58 100644 --- a/app/src/main/java/com/example/mycloset/Views/UpdateSingleItem.kt +++ b/app/src/main/java/com/example/mycloset/Views/UpdateSingleItem.kt @@ -3,7 +3,9 @@ package com.example.mycloset.Views import android.widget.Toast import androidx.camera.view.LifecycleCameraController 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.PaddingValues import androidx.compose.foundation.layout.Row @@ -22,6 +24,7 @@ import androidx.compose.material3.Divider import androidx.compose.material3.ExperimentalMaterial3Api import androidx.compose.material3.Icon import androidx.compose.material3.IconButton +import androidx.compose.material3.MaterialTheme import androidx.compose.material3.Scaffold import androidx.compose.material3.Text import androidx.compose.material3.TextField @@ -58,16 +61,22 @@ import kotlinx.coroutines.flow.StateFlow @OptIn(ExperimentalMaterial3Api::class) @Composable fun UpdateSingleItem( - productViewModel: ProductViewModel, -) {/* - var editedProduct by remember { mutableStateOf(productViewModel.informationProductObject.copy()) } + productViewModel: ProductViewModel +) { + var viewModel: SignupViewModel = viewModel() + val informationProductObject by rememberUpdatedState(newValue = productViewModel.informationProductObject) + productViewModel.getProductWithBarcode(productViewModel.selectedProduct) + val products = productViewModel.products val context = LocalContext.current + //used for keeping trak of the edits + var text by remember { mutableStateOf("") } + Scaffold( topBar = { // TopAppBar (the top bar) TopAppBar( navigationIcon = { - IconButton(onClick = { }) { + IconButton(onClick = { LoginAppRouter.navigateTo(Screen.HomeScreen) }) { Icon( Icons.Default.ArrowBack, contentDescription = "Back" @@ -75,88 +84,174 @@ fun UpdateSingleItem( } }, title = { - Text("Edit Product") + Text("MyCloset") + }, + actions = { + IconButton(onClick = { LoginAppRouter.navigateTo(Screen.ProductScanView) }) { + Icon( + Icons.Default.Camera, + contentDescription = "Camera" + ) + } + IconButton( + onClick = { + viewModel.logout() + } + ) { + Icon(Icons.Default.Logout, contentDescription = "Logout") + } } ) } - ) { padding -> + ) { innerPadding -> + // Content to be displayed below the top bar Column( modifier = Modifier .fillMaxSize() + .padding(innerPadding) .padding(16.dp) ) { - DisplayPicture(editedProduct.images) - - Spacer(modifier = Modifier.height(24.dp)) + val product = products[0] + //title Text( - text = "Edit Product Information", + text = product.title, fontWeight = FontWeight.Bold, fontSize = 18.sp, - modifier = Modifier.padding(bottom = 8.dp) ) - TextField( - value = editedProduct.model, - onValueChange = { editedProduct.model = it }, - label = { Text("Model") } - ) + Spacer(modifier = Modifier.height(24.dp)) - TextField( - value = editedProduct.category, - onValueChange = { editedProduct.category = it }, - label = { Text("Category") } - ) + //image + Column( + modifier = Modifier.fillMaxWidth(), + horizontalAlignment = Alignment.CenterHorizontally + ) { + DisplayPicture(product.images) + } - TextField( - value = editedProduct.brand, - onValueChange = { editedProduct.brand = it }, - label = { Text("Brand") } - ) + Spacer(modifier = Modifier.height(24.dp)) - TextField( - value = editedProduct.color, - onValueChange = { editedProduct.color = it }, - label = { Text("Color") } - ) - TextField( - value = editedProduct.material, - onValueChange = { editedProduct.material = it }, - label = { Text("Material") } - ) + LazyColumn( + modifier = Modifier.fillMaxWidth(), + contentPadding = PaddingValues(16.dp) + ) { - TextField( - value = editedProduct.size, - onValueChange = { editedProduct.size = it }, - label = { Text("Size") } - ) + //info + item { + Text( + text = "Edit the fields :", + fontWeight = FontWeight.Bold, + fontSize = 18.sp, + modifier = Modifier.padding(bottom = 8.dp) + ) + } - Spacer(modifier = Modifier.height(16.dp)) + //prepare the object for save the update + var product = products[0] + //model + if (product.model != "") { + item { + EditableTextField( + initialValue = product.model, + onValueChange = { newValue: String -> + product.model = newValue + } + ) + } + } + + //category + item { + EditableTextField( + initialValue = product.category, + onValueChange = { newValue: String -> + product.category = newValue + } + ) + } + + //brand + if (product.brand != "") { + item { + EditableTextField( + initialValue = product.brand, + onValueChange = { newValue: String -> + product.brand = newValue + } + ) + } + } + + //color + if (product.color != "") { + item { + EditableTextField( + initialValue = product.color, + onValueChange = { newValue: String -> + product.color = newValue + } + ) + } + } + + //material + if (product.material != "") { + item { + EditableTextField( + initialValue = product.material, + onValueChange = { newValue: String -> + product.material = newValue + } + ) + } + } + + //size + if (informationProductObject.size != "") { + item { + EditableTextField( + initialValue = product.size, + onValueChange = { newValue: String -> + product.size = newValue + } + ) + } + } + + } + + Spacer(modifier = Modifier.weight(1f)) + + //bitton Row( modifier = Modifier .fillMaxWidth() .padding(16.dp), - horizontalArrangement = Arrangement.Center + horizontalArrangement = Arrangement.SpaceBetween ) { Button( - onClick = {LoginAppRouter.navigateTo(Screen.SingleItemScreen) } + onClick = { + LoginAppRouter.navigateTo(Screen.SingleItemScreen) + } ) { Text("Cancel") } Button( onClick = { - // Save the edited product - productViewModel.updateProductDetails(editedProduct) - Toast.makeText(context, "Item Delated!", Toast.LENGTH_SHORT).show() - LoginAppRouter.navigateTo(Screen.SingleItemScreen) + productViewModel.updateProductDetails(product) + Toast.makeText(context, "Item Updated!", Toast.LENGTH_SHORT).show() + LoginAppRouter.navigateTo(Screen.HomeScreen) } ) { - Text("Save") + Text("Confirm") } - } } - }*/ -} \ No newline at end of file + } +} + + + From 09beaff64b28e508f96551107e73fcad073c33ad Mon Sep 17 00:00:00 2001 From: Liideli Date: Thu, 12 Oct 2023 23:16:08 +0300 Subject: [PATCH 28/32] This is the version with delete button. Modify button is not working in this version. --- app/src/main/ic_launcher-playstore.png | Bin 15010 -> 13509 bytes .../BarcodeWorkingSet/BarcodeRepository.kt | 2 +- .../com/example/mycloset/Views/HomeScreen.kt | 78 ++++++-- .../com/example/mycloset/Views/ItemCard.kt | 15 +- .../example/mycloset/Views/ProductScanView.kt | 18 +- .../example/mycloset/Views/SingleItemCard.kt | 114 ++++++++++++ .../mycloset/Views/SingleItemScreen.kt | 173 +++--------------- app/src/main/res/mipmap-hdpi/ic_launcher.webp | Bin 930 -> 876 bytes .../res/mipmap-hdpi/ic_launcher_round.webp | Bin 2786 -> 2144 bytes app/src/main/res/mipmap-mdpi/ic_launcher.webp | Bin 706 -> 666 bytes .../res/mipmap-mdpi/ic_launcher_round.webp | Bin 1786 -> 1384 bytes .../main/res/mipmap-xhdpi/ic_launcher.webp | Bin 1418 -> 1152 bytes .../res/mipmap-xhdpi/ic_launcher_round.webp | Bin 3928 -> 3036 bytes .../main/res/mipmap-xxhdpi/ic_launcher.webp | Bin 2128 -> 1508 bytes .../res/mipmap-xxhdpi/ic_launcher_round.webp | Bin 5958 -> 4730 bytes .../main/res/mipmap-xxxhdpi/ic_launcher.webp | Bin 2876 -> 2108 bytes .../res/mipmap-xxxhdpi/ic_launcher_round.webp | Bin 8398 -> 6804 bytes .../res/values/ic_launcher_background.xml | 2 +- 18 files changed, 231 insertions(+), 171 deletions(-) create mode 100644 app/src/main/java/com/example/mycloset/Views/SingleItemCard.kt diff --git a/app/src/main/ic_launcher-playstore.png b/app/src/main/ic_launcher-playstore.png index b569f43ba448932e30d46b1000cad30591a1ebdf..135431d5be0c36fc841ba46c789f370a2758fb9f 100644 GIT binary patch literal 13509 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 literal 15010 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 C_C>n@ diff --git a/app/src/main/java/com/example/mycloset/BarcodeWorkingSet/BarcodeRepository.kt b/app/src/main/java/com/example/mycloset/BarcodeWorkingSet/BarcodeRepository.kt index 92af66e..5fc9385 100644 --- a/app/src/main/java/com/example/mycloset/BarcodeWorkingSet/BarcodeRepository.kt +++ b/app/src/main/java/com/example/mycloset/BarcodeWorkingSet/BarcodeRepository.kt @@ -3,7 +3,7 @@ package com.example.mycloset.BarcodeWorkingSet import com.example.mycloset.ApiWorkingSet.RetrofitObject // -var APY_KEY:String="82m5dj79cuxyk3ql4nbtxvgpsv4a1l" +var APY_KEY:String="s3lr5ttzopcg5a10yr4bukjjzebrbm" //class for using the barcode-lookup API class BarcodeRepository{ diff --git a/app/src/main/java/com/example/mycloset/Views/HomeScreen.kt b/app/src/main/java/com/example/mycloset/Views/HomeScreen.kt index 1cc2abf..278a99c 100644 --- a/app/src/main/java/com/example/mycloset/Views/HomeScreen.kt +++ b/app/src/main/java/com/example/mycloset/Views/HomeScreen.kt @@ -1,7 +1,6 @@ package com.example.mycloset.Views -import android.util.Log import androidx.compose.foundation.layout.Box import androidx.compose.foundation.layout.fillMaxSize import androidx.compose.foundation.layout.padding @@ -14,14 +13,15 @@ import androidx.compose.material.icons.filled.Logout import androidx.compose.material3.ExperimentalMaterial3Api import androidx.compose.material3.Icon import androidx.compose.material3.IconButton +import androidx.compose.material3.MaterialTheme import androidx.compose.material3.Scaffold import androidx.compose.material3.Text import androidx.compose.material3.TopAppBar import androidx.compose.runtime.* import androidx.compose.ui.Alignment import androidx.compose.ui.Modifier +import androidx.compose.ui.text.font.FontWeight import androidx.compose.ui.text.style.TextAlign -import androidx.compose.ui.tooling.preview.Preview import androidx.compose.ui.unit.dp import androidx.lifecycle.viewmodel.compose.viewModel import com.example.mycloset.DatabaseWorkingset.ProductViewModel @@ -29,6 +29,7 @@ import com.example.mycloset.LoginWorkingSet.LoggedUser import com.example.mycloset.LoginWorkingSet.Signup.SignupViewModel import com.example.mycloset.navigation.LoginAppRouter import com.example.mycloset.navigation.Screen +import com.example.mycloset.ui.theme.fontFamily import kotlinx.coroutines.flow.* @@ -39,11 +40,58 @@ fun HomeScreen(productViewModel: ProductViewModel) { productViewModel.getProductsWithEmail(LoggedUser.loggedUserEmail) val products = productViewModel.products - Scaffold( - topBar = { + if (products.isEmpty()) { + Scaffold( + topBar = { + TopAppBar( + title = { + Text( + text = "MyCloset", + fontFamily = fontFamily, + modifier = Modifier.padding(vertical = 16.dp), + fontWeight = FontWeight.Bold, + style = MaterialTheme.typography.displayMedium, + color = MaterialTheme.colorScheme.onPrimaryContainer) + }, + actions = { + IconButton( + onClick = { LoginAppRouter.navigateTo(Screen.ProductScanView) } + ) { + Icon(Icons.Default.Camera, contentDescription = "Camera") + } + IconButton( + onClick = { + signupViewModel.logout() + } + ) { + Icon(Icons.Default.Logout, contentDescription = "Logout") + } + } + ) + }) { innerPadding -> + Box( + modifier = Modifier + .fillMaxSize() + .padding(innerPadding), + contentAlignment = Alignment.Center + ) { + Text( + text = "You don't have any items yet...", + textAlign = TextAlign.Center, + ) + } + } + } else { + Scaffold(topBar = { TopAppBar( title = { - Text("MyCloset", modifier = Modifier.padding(2.dp)) + Text( + text = "MyCloset", + fontFamily = fontFamily, + modifier = Modifier.padding(vertical = 16.dp), + fontWeight = FontWeight.Bold, + style = MaterialTheme.typography.displayMedium, + color = MaterialTheme.colorScheme.onPrimaryContainer) }, actions = { IconButton( @@ -61,16 +109,16 @@ fun HomeScreen(productViewModel: ProductViewModel) { } ) } - ) { innerPadding -> - LazyVerticalGrid( - columns = GridCells.Fixed(2), modifier = Modifier - .fillMaxSize() - .padding(innerPadding) - .padding(16.dp) - ) { - items(products.size) { index -> - val product = products[index] - ItemCard(product.images, product.title, product.barcodeNumber, productViewModel) + ) { innerPadding -> + LazyVerticalGrid( + columns = GridCells.Fixed(2), modifier = Modifier + .fillMaxSize() + .padding(innerPadding) + ) { + items(products.size) { index -> + val product = products[index] + ItemCard(product.images, product.title, product.barcodeNumber, productViewModel) + } } } } diff --git a/app/src/main/java/com/example/mycloset/Views/ItemCard.kt b/app/src/main/java/com/example/mycloset/Views/ItemCard.kt index cb60206..1222edb 100644 --- a/app/src/main/java/com/example/mycloset/Views/ItemCard.kt +++ b/app/src/main/java/com/example/mycloset/Views/ItemCard.kt @@ -11,12 +11,15 @@ import androidx.compose.material3.ExperimentalMaterial3Api import androidx.compose.material3.MaterialTheme import androidx.compose.material3.Text import androidx.compose.runtime.Composable +import androidx.compose.ui.Alignment import androidx.compose.ui.Modifier +import androidx.compose.ui.draw.clip import androidx.compose.ui.unit.dp import coil.compose.rememberAsyncImagePainter import com.example.mycloset.DatabaseWorkingset.ProductViewModel import com.example.mycloset.navigation.LoginAppRouter import com.example.mycloset.navigation.Screen +import com.example.mycloset.ui.theme.textType data class Item(val id: Int, val title: String, val imageUrl: String) @@ -41,19 +44,23 @@ fun ItemCard( LoginAppRouter.navigateTo(Screen.SingleItemScreen) } ) { - Column(modifier = Modifier.padding(10.dp)) { + Column( + modifier = Modifier.padding(8.dp), + horizontalAlignment = Alignment.CenterHorizontally + ) { Image( painter = rememberAsyncImagePainter(imageUrl), contentDescription = null, - modifier = Modifier.size(120.dp) + modifier = Modifier + .size(120.dp) + .clip(RoundedCornerShape(8.dp)) ) - name?.let { Text(text = it) } + name?.let { Text(text = it, style = textType.bodyMedium) } } } } - /* @Preview @Composable diff --git a/app/src/main/java/com/example/mycloset/Views/ProductScanView.kt b/app/src/main/java/com/example/mycloset/Views/ProductScanView.kt index c7bd7ec..066f63a 100644 --- a/app/src/main/java/com/example/mycloset/Views/ProductScanView.kt +++ b/app/src/main/java/com/example/mycloset/Views/ProductScanView.kt @@ -48,7 +48,6 @@ import androidx.compose.runtime.rememberUpdatedState import androidx.compose.runtime.setValue import androidx.compose.ui.Alignment import androidx.compose.ui.Modifier -import androidx.compose.ui.graphics.Color import androidx.compose.ui.platform.LocalContext import androidx.compose.ui.text.font.FontWeight import androidx.compose.ui.unit.dp @@ -60,6 +59,7 @@ import com.example.mycloset.DatabaseWorkingset.ProductViewModel import com.example.mycloset.LoginWorkingSet.LoggedUser import com.example.mycloset.navigation.LoginAppRouter import com.example.mycloset.navigation.Screen +import com.example.mycloset.ui.theme.fontFamily import kotlinx.coroutines.flow.StateFlow //@OptIn(ExperimentalMaterial3Api::class) @@ -99,7 +99,13 @@ fun ProductScanView( Scaffold(topBar = { TopAppBar( title = { - Text("MyCloset", modifier = Modifier.padding(2.dp)) + Text( + text = "MyCloset", + fontFamily = fontFamily, + modifier = Modifier.padding(vertical = 16.dp), + fontWeight = FontWeight.Bold, + style = MaterialTheme.typography.displayMedium, + color = MaterialTheme.colorScheme.onPrimaryContainer) }, actions = { IconButton( @@ -233,7 +239,13 @@ fun ProductScanView( Scaffold(topBar = { TopAppBar( title = { - Text("MyCloset", modifier = Modifier.padding(2.dp)) + Text( + text = "MyCloset", + fontFamily = fontFamily, + modifier = Modifier.padding(vertical = 16.dp), + fontWeight = FontWeight.Bold, + style = MaterialTheme.typography.displayMedium, + color = MaterialTheme.colorScheme.onPrimaryContainer) }, actions = { IconButton( diff --git a/app/src/main/java/com/example/mycloset/Views/SingleItemCard.kt b/app/src/main/java/com/example/mycloset/Views/SingleItemCard.kt new file mode 100644 index 0000000..4660f7d --- /dev/null +++ b/app/src/main/java/com/example/mycloset/Views/SingleItemCard.kt @@ -0,0 +1,114 @@ +package com.example.mycloset.Views + +import android.widget.Toast +import androidx.compose.foundation.Image +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.shape.RoundedCornerShape +import androidx.compose.material3.Button +import androidx.compose.material3.Card +import androidx.compose.material3.CardDefaults +import androidx.compose.material3.Divider +import androidx.compose.material3.ExperimentalMaterial3Api +import androidx.compose.material3.MaterialTheme +import androidx.compose.material3.Text +import androidx.compose.runtime.Composable +import androidx.compose.ui.Alignment +import androidx.compose.ui.Modifier +import androidx.compose.ui.draw.clip +import androidx.compose.ui.platform.LocalContext +import androidx.compose.ui.text.font.FontWeight +import androidx.compose.ui.unit.dp +import androidx.compose.ui.unit.sp +import coil.compose.rememberAsyncImagePainter +import com.example.mycloset.DatabaseWorkingset.ProductViewModel +import com.example.mycloset.navigation.LoginAppRouter +import com.example.mycloset.navigation.Screen + +@OptIn(ExperimentalMaterial3Api::class) +@Composable +fun SingleItemCard( + imageUrl: String?, + model: String?, + name: String?, + category: String?, + brand: String?, + size: String?, + barcodeNumber: String, + productViewModel: ProductViewModel +// onClick: () -> Unit +) { + val context = LocalContext.current + Card( + colors = CardDefaults.cardColors( + containerColor = MaterialTheme.colorScheme.onPrimary, + ), + modifier = Modifier + .fillMaxSize(), + shape = RoundedCornerShape(10.dp), + + ) { + Column(modifier = Modifier.padding(8.dp)) { + Column( + modifier = Modifier.fillMaxWidth(), + horizontalAlignment = Alignment.CenterHorizontally + ) { + Image( + painter = rememberAsyncImagePainter(imageUrl), + contentDescription = null, + modifier = Modifier + .size(300.dp) + .clip(RoundedCornerShape(18.dp)), + ) + } + Divider(Modifier.padding(8.dp)) + Text( + text = "Product Information:", + fontWeight = FontWeight.Bold, + fontSize = 18.sp, + modifier = Modifier.padding(bottom = 8.dp) + ) + name?.let { Text(text = "Name: $it") } + + model?.let { Text(text = "Model: $it") } + + category?.let { Text(text = "Category: $it") } + + brand?.let { Text(text = "Brand: $it") } + + size?.let { Text(text = "Size: $it") } + + Divider(Modifier.padding(8.dp)) + + // Add more text components or other content as needed + Row( + modifier = Modifier + .fillMaxWidth() + .padding(16.dp), + horizontalArrangement = Arrangement.SpaceBetween + ) { + Button( + onClick = { + productViewModel.deleteProduct(productViewModel.selectedProduct) + Toast.makeText(context, "Item Deleted!", Toast.LENGTH_SHORT).show() + LoginAppRouter.navigateTo(Screen.HomeScreen) + } + ) { + Text("Delete Item") + } + Button( + onClick = { + + } + ) { + Text("Update Item") + } + } + } + } +} diff --git a/app/src/main/java/com/example/mycloset/Views/SingleItemScreen.kt b/app/src/main/java/com/example/mycloset/Views/SingleItemScreen.kt index 8e2ec58..6ef0152 100644 --- a/app/src/main/java/com/example/mycloset/Views/SingleItemScreen.kt +++ b/app/src/main/java/com/example/mycloset/Views/SingleItemScreen.kt @@ -3,20 +3,19 @@ package com.example.mycloset.Views import android.widget.Toast 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.PaddingValues import androidx.compose.foundation.layout.Row import androidx.compose.foundation.layout.Spacer 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.lazy.LazyColumn +import androidx.compose.foundation.layout.paddingFromBaseline +import androidx.compose.foundation.lazy.grid.GridCells +import androidx.compose.foundation.lazy.grid.LazyVerticalGrid import androidx.compose.material.icons.Icons import androidx.compose.material.icons.filled.ArrowBack import androidx.compose.material.icons.filled.Camera -import androidx.compose.material.icons.filled.Logout import androidx.compose.material3.Button import androidx.compose.material3.ExperimentalMaterial3Api import androidx.compose.material3.Icon @@ -26,26 +25,21 @@ import androidx.compose.material3.Scaffold import androidx.compose.material3.Text import androidx.compose.material3.TopAppBar import androidx.compose.runtime.Composable -import androidx.compose.runtime.getValue -import androidx.compose.runtime.rememberUpdatedState -import androidx.compose.ui.Alignment import androidx.compose.ui.Modifier import androidx.compose.ui.platform.LocalContext import androidx.compose.ui.text.font.FontWeight import androidx.compose.ui.unit.dp -import androidx.compose.ui.unit.sp import androidx.lifecycle.viewmodel.compose.viewModel -import com.example.mycloset.ApiWorkingSet.ImgDisplay.Companion.DisplayPicture import com.example.mycloset.DatabaseWorkingset.ProductViewModel import com.example.mycloset.LoginWorkingSet.Signup.SignupViewModel import com.example.mycloset.navigation.LoginAppRouter import com.example.mycloset.navigation.Screen +import com.example.mycloset.ui.theme.fontFamily @OptIn(ExperimentalMaterial3Api::class, ExperimentalMaterial3Api::class) @Composable fun SingleItemScreen(productViewModel: ProductViewModel) { - var viewModel: SignupViewModel = viewModel() - val informationProductObject by rememberUpdatedState(newValue = productViewModel.informationProductObject) + val viewModel: SignupViewModel = viewModel() productViewModel.getProductWithBarcode(productViewModel.selectedProduct) val products = productViewModel.products val context = LocalContext.current @@ -63,7 +57,13 @@ fun SingleItemScreen(productViewModel: ProductViewModel) { } }, title = { - Text("MyCloset") + Text( + text = "MyCloset", + fontFamily = fontFamily, + modifier = Modifier.padding(vertical = 16.dp), + fontWeight = FontWeight.Bold, + style = MaterialTheme.typography.displayMedium, + color = MaterialTheme.colorScheme.onPrimaryContainer) }, actions = { IconButton(onClick = { LoginAppRouter.navigateTo(Screen.ProductScanView) }) { @@ -72,13 +72,6 @@ fun SingleItemScreen(productViewModel: ProductViewModel) { contentDescription = "Camera" ) } - IconButton( - onClick = { - viewModel.logout() - } - ) { - Icon(Icons.Default.Logout, contentDescription = "Logout") - } } ) } @@ -88,134 +81,33 @@ fun SingleItemScreen(productViewModel: ProductViewModel) { modifier = Modifier .fillMaxSize() .padding(innerPadding) - .padding(16.dp) + .paddingFromBaseline(16.dp) + .background(MaterialTheme.colorScheme.onPrimary) ) { - val product = products[0] - - Text( - text = product.title, - fontWeight = FontWeight.Bold, - fontSize = 18.sp, - ) - - Spacer(modifier = Modifier.height(24.dp)) - - Column(modifier = Modifier.fillMaxWidth(), horizontalAlignment = Alignment.CenterHorizontally) { - DisplayPicture(product.images) - } - - Spacer(modifier = Modifier.height(24.dp)) - - LazyColumn( - modifier = Modifier.fillMaxWidth(), - contentPadding = PaddingValues(16.dp) + LazyVerticalGrid( + columns = GridCells.Fixed(1), modifier = Modifier + .fillMaxSize() + .padding(8.dp) ) { - item { - Text( - text = "Product Information :", - fontWeight = FontWeight.Bold, - fontSize = 18.sp, - modifier = Modifier.padding(bottom = 8.dp) - ) - } - - item { - Box( - modifier = Modifier - .fillMaxWidth() - .padding(4.dp) - .background(MaterialTheme.colorScheme.surfaceVariant) // Colore di sfondo personalizzato per Model - ) { - Text("Barcode: ${product.barcodeNumber}") - } - } - - if(product.model!=""){ - item { - Box( - modifier = Modifier - .fillMaxWidth() - .padding(4.dp) - .background(MaterialTheme.colorScheme.surfaceVariant) // Colore di sfondo personalizzato per Model - ) { - Text("Model: ${product.model}") - } - } + items(products.size) { index -> + val product = products[index] + SingleItemCard(product.images, product.model, product.title, product.category, product.brand, product.size, product.barcodeNumber, productViewModel) } + } - item { - Box( - modifier = Modifier - .fillMaxWidth() - .padding(4.dp) - .background(MaterialTheme.colorScheme.surfaceVariant) // Colore di sfondo personalizzato per Model - ) { - Text("Category: ${product.category}") - } - } - if(product.brand!=""){ - item { - Box( - modifier = Modifier - .fillMaxWidth() - .padding(4.dp) - .background(MaterialTheme.colorScheme.surfaceVariant) // Colore di sfondo personalizzato per Model - ) { - Text("Brand: ${product.brand}") - } - } - } + Spacer(modifier = Modifier.height(16.dp)) - if(product.color!="") { - item { - Box( - modifier = Modifier - .fillMaxWidth() - .padding(4.dp) - .background(MaterialTheme.colorScheme.surfaceVariant) // Colore di sfondo personalizzato per Model - ) { - Text("Color: ${product.color}") - } - } - } - if(product.material!="") { - item { - Box( - modifier = Modifier - .fillMaxWidth() - .padding(4.dp) - .background(MaterialTheme.colorScheme.surfaceVariant) // Colore di sfondo personalizzato per Model - ) { - Text("Material: ${product.material}") - } - } - } - if(informationProductObject.size!=""){ - item { - Box( - modifier = Modifier - .fillMaxWidth() - .padding(4.dp) - .background(MaterialTheme.colorScheme.surfaceVariant) // Colore di sfondo personalizzato per Model - ) { - Text("Size: ${informationProductObject.size}") - } - } - } - - } - Spacer(modifier = Modifier.weight(1f)) // Add more text components or other content as needed Row( modifier = Modifier .fillMaxWidth() .padding(16.dp), - horizontalArrangement = Arrangement.SpaceBetween + horizontalArrangement = Arrangement.Center ) { Button( onClick = { - productViewModel.deleteProduct(productViewModel.selectedProduct) + //productViewModel.deleteProduct(informationProductObject) Toast.makeText(context, "Item Deleted!", Toast.LENGTH_SHORT).show() LoginAppRouter.navigateTo(Screen.HomeScreen) } @@ -232,17 +124,4 @@ fun SingleItemScreen(productViewModel: ProductViewModel) { } } } -} - - -/*@Composable -@Preview -fun SingleItemView(){ - SingleItemScreen() -}*/ - -//@Preview -//@Composable -//fun Info() { -// SingleItemScreen() -//} \ No newline at end of file +} \ No newline at end of file diff --git a/app/src/main/res/mipmap-hdpi/ic_launcher.webp b/app/src/main/res/mipmap-hdpi/ic_launcher.webp index 0989a1a373609bfb948f8e36138ed4cd1a9a8f50..814383e9910a31465729d2c2967ea2994ee3fa1a 100644 GIT binary patch literal 876 zcmV-y1C#txNk&Fw0{{S5MM6+kP&iCi0{{RoN5ByfXXPrAB*m)gBLh$7lTF{u@9iFW za2!dJqg3@E9l%^X#1CHlwAgmsNRlFD){+Bj=9+!*X1*)PwQVhH_WN*$MwmIpFrx=L zV9^I7Yr>L|CzZH=YTLG9+@{nw06+i%1Q5UvLZnh5L?NhF~{#4u7BiIOnt_p@dOs!WIwq9lyk%?KefQe{Gw#C-5vmxL-4 znV{?mtQkoE_5Y`Q569&#Ng2svLUPQ%<4ajRmUdexiqa~r(qi#w%tG!Mzx_8?u8Zg6*(>+1ch}vld|UYae>cGA>;L*Vo{nWMG=K^aKmY+GpaztI z0E(3R?Ri^mW?cfwA>rD#vysx7Mq_Jj+s3SIn`7hKE!MVe7XPx1-fzwH?U%O^{ht8o z$9p8srDsD7Idv_$h!-!MJ$D|oCsHV(Yr)0Kr-K-Pk7uq(F;fx5Q^Av5;?*oEVkRzK z3Q~Z}Q0HzbZps(sCEU9!Z7%CtfD>XnJ#+qByoA%+{1&eBv%|^_ezt>P4J+r)F`j?0 zjTcrot6J4^4RgHwQ7c-xI6k#lMx3IT)d zxKfpq<}XUtI0BRBPdo}p%q*0ROBb}bF55F+GeEW90XWMGWwUuhr_7#ErlLu2cng%y zVY0(|EtGu)PT@o-%XG*3G9a^5$BLSPOpqN{_rvJzV>>bw(uDkA-y-fjdP;I!)&sHlpc%k%mD>s9jc)eS!+z)ssco3o1hyJ@} zBH3^6uuz!8G&}r06ETAiUOhR|(!;>_;-ROn9!ut*zx(`X^Tti5JZ9mkq|_J zh)56#K_o~J2|*-CY)E;T&+mqyMc?2zA3lBp@6zi5J}ZbXpA8xaKINs+Rv(A>BNYH2 CSfBm? literal 930 zcmV;T16}-5Nk&GR0{{S5MM6+kP&iDE0{{RoN5ByfN9H(^ZB>~$_v34dAPACVb?5FD z1nfw*RaG-tQ=k9voHj?B>ikv<1PGtYqylL+*m)SJj+O}0I^L+OYAx*ez z2h>0}S_K&qRe0zvkh$wUZ2&-k009F0A_4*t5JWIR6a}OF0Yf@MdZ|f}svyBW+ zE1H@l9Yd1pC{|KQNXNvGieiFvH-~1vXlfG0#E?olLTkPtN;;|3Bqr4{K@?3*lYps? zp(fF!0}dI|2$4@!I`i(WwU|h3Tp%Pt6i7`{lb9%of~mraVq#Drh@wCYh=2$PqCgZF z7y-e6zt`Y324yTXFS7)7KuG1q%)Ewx$@A;3@;|p}FX`hb-_B28e_Nou5d8B(F!smw zW7cn<`$D|F{v18VY%nB)7ec2%)Az4E{`?)U!IL&u(>dr}|Lz|i_VNDaXLR}ayf@rl zb9{OWcqtQJQw>2A1PBnI0@|Pf0@Oyw^Ic6UaQVn|WivY^e76RRW4hh_=lp&;{kb<3 z61HtS-sTHx+n#N9_EyZQZQD)l**0t2_+L#vJnzgrc_R8h0o;%Go-QUygl=S%1QB9m zQ_Hnx(ApLqa@Z|^u;F?QR>Q}e_qc9eJ%~4I>Y2n_a;}F@7v8O@uV%8g;04#kOLm8q zy7K2Te)8MZjF9S?oS*UmD|M>3N&yeqc_rjAJ8wW#q?|c&So5*>xvW$q9PlwQv(#u| zV7vZwb`=9v@xIP_h&v-SUU1Vx{T2Rs;F9*a=q+BCt5tvA3K7w0<=J9T#izVX^wip% ztW=Y_R!_a{j#xlN`yKQ&yB^P~)>cGsG1Y)Z%fsOWI_UAWUbXwsHg`iko(5|&pcJmw zli1u3N~FD1xE)HMxn#>!Kn@y8=9CU(tDfY>5irV@N@oxNBi&It+*=7E%ml!uQV@Oy z0G8xIQ2FWsbV!C!x)B0?gplJ6;sk^wI}p3d0DRC_FPcv6hI{~pF;R>6h~;rHYH?yE z0F6h*@=4P2{}akNPd9Nlr-Lg=h!Z!h3LI1s9DPM2JL4 zNQ6j)L_|o0NQ8t$h(t(uHK?_HY;cMbD4Xmb9vKC%!@dQX5XAYJiE;3{8RA5hG06Q$ E1@s)Zb^rhX diff --git a/app/src/main/res/mipmap-hdpi/ic_launcher_round.webp b/app/src/main/res/mipmap-hdpi/ic_launcher_round.webp index 73eb679e3ce9bab7ee0640837ff088ad9b422147..fa972f3352d886c1f0313b72dc8b2c478badfeda 100644 GIT binary patch literal 2144 zcmV-m2%q;-Nk&Fk2mkK_wiTK>!vGB5%%0NFGpnz86@+^<9XT{;JcO?=%XN-o-4n zDiMmH7GfJ!&zHL&An?uNxd5vAD~~HvvsMUHB;;*!MW#X#Dzeh)bZ9r_JdG$WoOL$< z*E59=pzdL+KB_`sQyyZ>A#aK(c31_#H_mmT;(e5=hfE+(W1Q0*QJlLFxUNA(PZ?lp zZB=%gNb@urnC59z)qWH}%8(SyNDq~-1S;%8!?P%q{d##w8IS^5sjBitHbfJKS-iV~ zX^@JW4~oX_DY9tNEGlX*(>USa*R<{cgdL zx{OS@7^KnRK^uU8P7k^|p=>wdv<1368Lm^`kq8BHQK5pm?gegaie8B<(pHe#ivb%Q z9*~6NIHOPU0{tdIj|InZY9u;88NSmvNa$e}OXDqpJr*A%Z4p_d{H*R`fX4og=Aeza zP`8k@mvA&YIT&S780euIU7zLqF7T;5P$N=RD~1#W!3k&A0FL$tQy4nsWSD`YyHrnw ziHr)N6S8u)HePYy(aE|mvZ()MAB8p(4rO2`APrP8v8m91Hn{!0zgJAgK>SMV4ME>7n45ap#c-39U41UYA3_)AB)% zOM;_*?L`L%rf~YKJg$X2lkYdd*Knc92R}vC7*b4d({{ofU7Z}N6RM&_HRCH3+$bN) zeTA@5KQYqa5p(RH=jfms;_(LeM)0G&oWy5>Q+zg1!!ajGL<~KSdH#mL;Q>GZk>xF` z3`2_MJ!VYej5*N@S#ea1d<8)O;6YIg7ipv{Bpn@?W$?~tI`~HO$eIYFy-EN+lybM= zH1!udo8^H+_2h^7S-m)t^8vhMnQkK0gg1^^yUA>$$1{!me$s;=AaF|jNtGC`VVaH- zA5e&V|4X0*K>)o$la!?ho1%HY4b!xhn8?txS%Gr8f*S;taKJdzUtt9*5)@ZNqtA?}3464nMhq#&zUd*O-Tr|Ar>?c5=822wgsLcE)5tX$ z+yLHGqJnDU5~AIA!GJcwL^sVe4@HU+uN)~yeCCqn z4M7kPxRmo3a%*wXIQ|p32LVLhoCJCiZ(A-?#~e2LsjJX6O%5O}%( z06u|Hdu>76N-9M;nPBeQzX)?eQQAB2Wmto5W4z)>%^~ z5qr4p#-Qo#KiW0vM3J_Nye-yj*fDE=R}1?3s}ckj_-93Mt8lDiKM8_<0bQ5CZPYPa zA|h>#Iao4r{WQcW07z6Wo&M#RH^&+>QI(@G-lMwG@Pwq_+(RS$_SsxB%YIMolGHQ-$ zcIcG$sqNh7N$*R%ubW7*FEKN^H;UZfx!e)kMJP~CrBB(Ew5?ci(PEY zREafhd0Vl}Ve|ReXKU27??aW9&n@@pFJOGGWrs6>Aetb3(7I@{`#}>gzcs8j+!xk`h^EUtOKJL>J{syeuWK3@k+yUs@4AmA{9g!MYlgNG@r#+w%>_s4bD-$tI9 z7o`PJQydNdAD-`}kNz^HJ^uR0b$@$vx$8Ds2TYwLf7DiIJk**XG1WG@w~gNG_MFG` zn#a$w@49WH*LtZ7TR(J0s~3`B{v`RQY_vkR@b3_TCq1;>#~&~E&`Gl|xWYy^Cc(0~ WBzcv{Q|=3DZ_sYeHvKr61A_qxWej!z literal 2786 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 diff --git a/app/src/main/res/mipmap-mdpi/ic_launcher.webp b/app/src/main/res/mipmap-mdpi/ic_launcher.webp index 7c31037654908640f81826244e00ef5d3fb94147..4dc74d52ddf2e5065a1268470a30f04f418b4454 100644 GIT binary patch literal 666 zcmV;L0%iSDNk&GJ0ssJ4MM6+kP&iD50ssInFTe{B7vw6EB*m)grQe7C-H`%*@5qFs zMv@#UvugGn56>Udy$*qG$BiT@Qf3W(cMtscjx6B2hFjaVs%l-q-6gWftqEfKAfg8i zX@!(FTw@}4`Tr73(p1|q0Du4_@B$jP;BKki8?7RGU z;x6<(BAF0T2NGRfTyjRi=urdd=HcXsJKfzd)Ve>|H{-2E?SrmQ_jmVpIHNpR?q(l~ zC-!o@zeC)`!Ad84QtLT0Nt+HdNh{RmXkC$d?Z}1+wnF7G-ppzxQglghlh;&blugQ_ zEh54~o0O3i(|m?wZOX8weWE6m%D5np#dw>#FDYO6q&hBgXt%)~*lk z1fax4u<>x9hzYP>FA(*C)!U#Optg&_%Ai)$y+p=5M3k`xL<^HbH2Mt$nkR)=ASh)= zz(^OV|KE+37U(ZUm@_@_;y|`(^&gw0MeT#$&JT9?b~vLvoU38)3VO7^ZXO;8&LlR5 z9FI)RnmjPGG%vVHF*}%I)gW}ZQ}Ylp7d#IU)1>2(X=9Gl#oZ~9biY4ye`nt%0802g AuK)l5 literal 706 zcmV;z0zLgwNk&Gx0ssJ4MM6+kP&iDj0ssInFTe{BhvYVrBt@#~K6sGce|O%NSDDcb zw~-{f%FN!okFazIgibhQfrX3tm4ir=0B5ClIU0RkWhLZE~e0tA7fX$KLI_M#mVC6#tk8IKDjm0^mBg5au| z^tU`!R{uFQFlm9L7K*Jk0MklKKb=$%!AcUOos7gFChJ~Ta%rx#laW+R6xOAg?fc)+ ze-7*0f6Nx?SR^2evj(*es$nXquk-tzC(K-DS}%t@AKwO0?`VRgq992SlXeuC3u5{Y zh5ibFtmL%zg<`g{C2;Ip7v)5zi!#Q zJtzf-qwITK*_`s3t!*k+}$LntPA=Z7RkQN!&3TcMg8Luf2Evz2f zR>00^X{05+QkZ6mD6;SHnkf%g6Xow65@EiYD6DLj&v2Al7~F7hc+h}qA~HtXd8}B~ z;(qbDai|uzE^}xzO324{xcxFUY{dcCW(H8^CfITeQ0y|;R0vS$G+3`Mkfjf-Rt;ST zwO<5QvJbS8VkRJ@erA6Y3 oG(VW2l0ecLl5?^Vv%s?vDaoL9GHLSY^xSpmWU_58?!>-J0KZ{PcK`qY diff --git a/app/src/main/res/mipmap-mdpi/ic_launcher_round.webp b/app/src/main/res/mipmap-mdpi/ic_launcher_round.webp index ebf3ebaf1aae511f4d684b1088f62149f5b22a86..d31195d27a5416fefbd86d746eca05eb976bf012 100644 GIT binary patch literal 1384 zcmV-u1(*6#Nk&Fs1pok7MM6+kP&iCe1pojqFTe{B716o=f32kaad&rz&fVQzM%KoC z<|aX2z`XbPeFa~1PVnimlEYfCZja_{wI|3Iskr4FU2;eenC_F#x?#@GUC?1B&t#AIScu2-z5Y^yew(f2spzYtk6$ zIjU56m6NiCEXiO<^5&;gB&h{4ATK}Jk8{eFWc|x%IEym!qkDkZR17F?l-GY|()v#e zD;d9B2E-;}Kw4utqmY({5n0d#5F7FVd9CJ|OU;6*4{9g6b)+Cvq?@teH33-xnb<%I zNFLAKjOrdUY_j{w`h~SJYZo-9V%LM(phu{fx$NfTCjv65UIJ+~`z2kH92N|$o)HPp^S0aQ79_dg zVbAlt)iMLa1Cn&}g8sLTK$JCnK;~mcBv})zSD5apR{#fIbP4kLyMI@C)7Pu~LXr`? z;;Dcfd{u&iD)KBOSs!dr@buR&>~=5*p8g$mgk(5P63wa=kVydeX!}ulVm0D)b$D0f)6CM|P_tlPM4Gq@7v4T7I`<+s$RB8%zj_dBgDYEKWZ?xz*j?)mVn=!Xu z<_^bk9BOsy?UBqbZ2L@XF=Ce(NHcHZp@BS1j8L-&h_&3r7NhD1Q2mGedP z_V8E{P)y3744<_O!{P|XjX$%sd{T~a!tEjH3uQ~iAxlzBC%+za`Qz}XLJ9$m_Bdr! z91-i|LO>fSl4Uim?(Hxv25AY!qQ{)tT9ze1FXXT}EIWM7N-{IWq#R&lT5HM|x=Zx%&SRXG1EKmh`6_SyMT#4QKlUM92y!{V4^yh#p zZDbo1p`8fmoG}K*D;BOju42(6P97uQCD2X9OJ2aNcCIc|EV(3G$rhDWGp4t!EFtM$ zIsPne+`2f`gD;>cU^{edjt~AP7mf(31JmI`^8a9bZQB;Go81Sa@kjyt>b~X#k+cLY z?TZ5Etg#{BF!J!H0*w131#F(^$!+w-kv`1!LQXuCZr%ILs*mSR zJ{Y;Og^|#W26Lx=KHu}ox%KHP$isYE1tkGp0oRjSZkDt4-PLFH)#s~KcxcvQEzxb1bjea7aD4_NCivq5zZ(dv0upQ6v q$8hPC7yo`>cH#@j*qk2zRH%9=ji3FRfVzO@Q#ZUedwkhXVHyDHl&%2) literal 1786 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 SQ@Mu6i+qTWvwr$(CZ96-? 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 literal 3928 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 diff --git a/app/src/main/res/mipmap-xxhdpi/ic_launcher.webp b/app/src/main/res/mipmap-xxhdpi/ic_launcher.webp index f96c4a2a1a581ebf854b97de4d2ff34c1747cea2..b83a51188833fe37b7a779c1081494a6ecbb060a 100644 GIT binary patch literal 1508 zcmVUM5WTJ@4z{+{+sdvN3w0zN?pJAV6?m7f_A|kgDI1$W+BK$cT zx;y#zbN@RNAZ^>Wvyp7uwr#In+jjf^KhJFPPI9lm&Kz0qv$k#TcFaJMl*VZm30^>0 zqyH1YPpHK|$w3btEbyCCAEh~XGn3eyq&`WQIfuTZtefw7GI9g{oLQzqJ*_EqCzcX3Wdzg#PdGPiIS8rBShVqrWQiKwOrKWG7P6G5CSvo%7FmBmt7OhtJay{Dik zowN8>c`_1&brLFU=COA8o?^b3&gd>!NkS``C^_1j>I(7{61v*%&z$v{mS$jb&p!O0 zq$@2=luTTf)uU5Hh}zS)*PhYxsqpX)f6r_$L-Z^|+e2QDP61)+&*09}XT(u?7$}N3 zKFiXc)YKnv5n6g;7wKo>+!>+E>rY2;Axe~d9educBlB?KE3;%Fp6O6k^zx9dq=6ez zyu$YVzJVnf`*JFXe~mkbhqG&p_+RNrV@sIUl~rO1AeNUuNF1aOmx<-Z>UNZfq}MNq zakVQd!js(iQEkMyKvg9HGW9AkPe*H<_|5I3w0r+}Z9O37&+p?2urCvZ9VH+c*;;MQ z@hYB-4PyW7rk`-$$4T6oDyta5q(l3e$mmP(f^kgwBC(g*2QZ401<}RT1!n)3ETT)n z!5_=|6B7UQUWXE3X9DQXAfb4t$^cZG1jW+%3qXNd8;Yzl0pO{kpzL{*0U$;8en@VN zY(hBptOL2a1))720dY^+f>2?e0b=Ym2)Sx*AV(`55HfJ0fXqIhA;jlj9O2uSgz@J( zjNN(%(d>bN;hcg6qS(H|(4Gthkp*MJIPj+mh%_AiVT|uYfcQMKQG|J&Q1)hoAbeA0 zFzWm&hz~h{k*}@+@h%lG(nNni9R5?0D4YfNjPv%<0`W*yvf}!<$^=&9M}ApxRh{=B zc>1R$1lFDb-dWja{<|RNeNPIkFGGZP$8>sklMA_L8~YBv7{B}pUICYj1b{vNZcEh5 z1bQwyEZ$uz*23MEQ6uD~=Un&}^>()akv|*^=qaS%s*g-4OiML8kw3K*Iy`y)0IkJ< zgsbJwyt1^2vgHGI4ift#1+$3=kM3RY+oI#`lK=7kL+!%^3#M>Jg zKuA$0{5oXcqbU1`4{a3yF^NQwwRSA_6&s6G6rCw7?WoO~ax)X>leDhGe3g@~0}z+4K_ z(F#XVIfQCZT|+H_fA#-DUFra{YS?NAqCpbK1bJvBLns?^uMB*HR@@FU`&*s1tlDZI zfvYtH$uUUltqb(t-nc#lF&*97vU+PZ5I_Ob0V3XHf&S)A$M-^6Tg$$*Hi|TXQDiOq K*b>N(D+K`C{_BAN literal 2128 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

WXFRObYM~xpk{e;a-N#ss=sb&5=gQ; zr)}_d%@N+BLML<>tX@hO(B+L`F3JAM>X=NLe?Z@~6I;F%) zlM{AwMZ4(I?cS;oV%l+E0S+Mi(@XP@s#Cs8m&5`zVp>M5I5|4^&2KfAK5ZBY@f{pE z`hbXZ(t#Weg~xsMtxt%ALY+5B%D8)Itk+N+jZgQ5{1FEd@ptxxXPxPnH24mW8DF|% z3Tez0%O(NJ)yE8N#+)W3nqK#LlEvKW$NH6rH zlrsm&U)>+dw(~kcO3;&~B(GJSo(=D{$D@y+C-;tY3RF0>0I&}N@oD4$dGlNK(YdNH z7@MGFPAK`wp}BTmtE*2ta;pacyH$n5%}^T<0>q_}4diO@?YzIx#=s0IgQQR>u%bg{ zNsbL{y}#)Ja=jgw+bpLujL9J21)^t>o^s@A&|W;RJ!%^Zk}KTOon53PV`E<(w$0C< zH$)%&_0Qi1C+&~g^-cv`(?DVxx%CZRf)w$y*0*O&nnzvKpF-xqWx&xX zJe|`bI2`7k8hkJ8*B!9=+8og(a*U)<9PUt*XpGHhW8}bG_`-g@*&7}XTK90O(*rmM z2jEIiC4Wjo!RzN82ghQq58fXe;#)ho_ceD(qP4*TbII$+UG-Cq!GXa(kG0q7&dTZP z6f#rM?$tkk-mrH}$g+m>K|c}g?T&INre#FiS)wTTanG3e{CQ*jJ?SSPVYRlM3ggXQT;;0up~}oa)g~^y+#0?&tTDwlCL*Z}rQ3D9WcQHrpwRa+#Be@-a0r zo*TnMJLm7O9(Ua9nQHv$ZdcQYXVSt;nGqg^D?ODw4O+BbL-A|p-P`BSM{Ls>Z!Jj1 z``x5q*J804Nl{aitf{fci<&;^vDh`nl!PuROtPc(sBNr#^}JU@NxcRwno3>}NC-Cp z4!~k%QD%&f0N#cHAUTEXMmY0(>NOND*)LgrKeMO*ad@uDnkTiGN1yMk;=iY4j>7xjFdCCG3Cey z^3ADJ_ij$iW6a`q*-EZl(XO7je6#sUDm0Y-Wy+ij_@bqQ_l%5(>MSj44Rbp0 z079mL=;{`@(o)D8XiPnPsc2C+v}iQi!z&u)KLzQZ8wc1}OZA_pFY_LAzNJOKqYZEl zH}wLMKupJIi|gUo7mRtmjD0co(A6^9@hIHeG~CxF>=A>bZZhNntblz4a1A$I9_($H z4)dCB=pDS=G~7H=74(EA>x4Yw3Gu0up-#_uFxY0HU~t^i8JgsCg=1n%<=dH6$IEY4 IB;xE`35sh@7ytkO literal 5958 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 diff --git a/app/src/main/res/mipmap-xxxhdpi/ic_launcher.webp b/app/src/main/res/mipmap-xxxhdpi/ic_launcher.webp index f5f3bb449433ef1fb7a83ed9e377c5708712480e..42e9b41d8677884faead546e113831146077226d 100644 GIT binary patch literal 2108 zcmV-C2*dYMNk&FA2mkuhu|y?ArNar_4^3ol1xA7F)h{@5;l>zE3R0EUu#MT(=XR z(H1zpe)_k6GN(wTm~C}xt?kr^tr4k_K#^M4&1$VhbTOw0`OGV|{!DD0NRUR6I$KJe zoD)Mpk9{(ozFDa4)FqNq>HaZaFn#qKzmrPd%)5-$I+2u2SI-iRRhr2Y>12S|+R&dR zrE}{%!DQbDxap*kH*4+m5~NLIn;OcQ*)2=J zxQhnQ7>NN~i=j|_bjEc!_*oXaW{jUkFTo_xDi=ls5Iw(ye7O~@z)NGfp~Sq0nJbUb|B)F z-TphMCqAUcy>j;wm3UU;ZVw-$HukFg5SfA>SNeLC3{#gH0r75n_Fdq1A@%!6yfX{T z_zVd3MBgnW3;EFHzBKeVj2mB4oeq$WM;c#HAzq@Bd~b!ZUTL$7IBYDiZ?{ zv5#i(;3Fe(vS1yyh-h9}oFRah7P%ge$5EF-L}9uUk3Qvq1oEcdjmGCvp9j;t?|Ll8 zzl5v8r2d_T#f9?>CKe*=u^2fnL_oVy4;H<86IAxpx3Q>p9aPp>8(3_e2i1c-Lt^5_ z8-t1^-p@FE3049-RJw53<;ie)^HUsJb1qyz+X{tAyXpa4zb~Qid94bU3FLm7#b8>b zcEhFqpN7E&cV=+0uJsrgtdRh>!I6tWTUr2QOM4dv#lI;)_Mkj4NH!HRHNy}XzgG$L zaMi&#bh=>k;}HvAue=SL3-vAdYSR*6vw_A0PxBTr*woS=yc^%Y!p8RLpu6BJ1pL*P z(2ZFegw7eqE_8#NL3eD#0H@iyB=B2HhE13E!B^~`VVf4M@Fmy{*n0c~zCanfu>D#I zpF0g~*m{=>G44`h+*f{p?d9}};GAolq~%EY_LTFw2@9Jdf98DOjiu$ur$2L+72tU6 z-xsCj#e+r>?_2(R%YUz87(6~Ktp~#zznA%D4N|g#jYsiQF7&GUtV`*x+plN=iXux` z5jA93PEo;@TJCOyE)KLPk#ae)Lwj_>Qry}zidVx>xcHR<>>b6^$`36kR>Bznx$Hc& zc>WVj03i4x76GGqaVjN3U`yLMV%`CZMffBY0e}riA(#=PN7GU=J>U^r2u{W%E=3Fm zS>gNyZEc-=h}0b&x8T-R9bAlrf{Ag%0z+Usb)9@^U8+La2)~;dFmT=iha9fB*bo5d zp|dasR`>RzXrYi+GQ#ziV3fg4t!Cqym>lv*018W5ffaBXXd_bs=BKV9l!w2H0T6^3#UhP%Ey8QgD6Ep7!CE4C;S0AG|VKkR`E z@P5#y#x9s1U?r?yzdqgI`04ce^+#s}jBvPT%mbf4R_6fQs+geh00l%~T2`EadkH=_ zw%UR7K9~|PTW~U|9sj5$m?M}PFvj7L@o-(MPrqGOoKqi1o}s`1XC~eHY(l{Eh?_~7)T0*pB%hUD15x4xG35ZE5p={ mQC{4-rM5P5_}bbnt+A(!;TmX+Qp%G+rIayTbBzS@n_UE<<`Urm literal 2876 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 axy@2-Bf>FI#28}}&=@1aF;@u4TXhko$bYo} diff --git a/app/src/main/res/mipmap-xxxhdpi/ic_launcher_round.webp b/app/src/main/res/mipmap-xxxhdpi/ic_launcher_round.webp index 55897692bdc7e5852f63ad51e5175e6a47fc5f65..344ea36f265bf2683da019b55c40f269d26e6c60 100644 GIT binary patch literal 6804 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 z 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 diff --git a/app/src/main/res/values/ic_launcher_background.xml b/app/src/main/res/values/ic_launcher_background.xml index 7784b37..4067bcb 100644 --- a/app/src/main/res/values/ic_launcher_background.xml +++ b/app/src/main/res/values/ic_launcher_background.xml @@ -1,4 +1,4 @@ - #FF9C41 + #827070 \ No newline at end of file From 8844e2ff69298167abd4620fe78b9b003e201cc9 Mon Sep 17 00:00:00 2001 From: matti Date: Thu, 12 Oct 2023 22:24:55 +0200 Subject: [PATCH 29/32] Update- no delate --- .../example/mycloset/Views/ProductScanView.kt | 519 +++++++++--------- .../mycloset/Views/SingleItemScreen.kt | 235 ++++---- .../mycloset/Views/UpdateSingleItem.kt | 20 +- 3 files changed, 382 insertions(+), 392 deletions(-) diff --git a/app/src/main/java/com/example/mycloset/Views/ProductScanView.kt b/app/src/main/java/com/example/mycloset/Views/ProductScanView.kt index 3784c0f..584aa85 100644 --- a/app/src/main/java/com/example/mycloset/Views/ProductScanView.kt +++ b/app/src/main/java/com/example/mycloset/Views/ProductScanView.kt @@ -36,6 +36,7 @@ import androidx.compose.material3.Icon import androidx.compose.material3.IconButton import androidx.compose.material3.MaterialTheme import androidx.compose.material3.Scaffold +import androidx.compose.material3.Surface import androidx.compose.material3.Text import androidx.compose.material3.TopAppBar import androidx.compose.runtime.Composable @@ -60,6 +61,7 @@ import com.example.mycloset.DatabaseWorkingset.ProductViewModel import com.example.mycloset.LoginWorkingSet.LoggedUser import com.example.mycloset.navigation.LoginAppRouter import com.example.mycloset.navigation.Screen +import com.example.mycloset.ui.theme.md_theme_light_outline import com.example.mycloset.ui.theme.textType import kotlinx.coroutines.flow.StateFlow @@ -95,223 +97,226 @@ fun ProductScanView( val context = LocalContext.current val topAppBarColor = MaterialTheme.colorScheme.onTertiary + Surface(modifier = Modifier.background(md_theme_light_outline)) { + if (!showProductInfo) { + Scaffold(topBar = { + TopAppBar( + title = { + Text("MyCloset", modifier = Modifier.padding(2.dp)) + }, + actions = { + IconButton( + onClick = { + LoginAppRouter.navigateTo(Screen.HomeScreen) + } + ) { - if (!showProductInfo) { - Scaffold(topBar = { - TopAppBar( - title = { - Text("MyCloset", modifier = Modifier.padding(2.dp), style = textType.titleLarge) - }, - actions = { - IconButton( - onClick = { - LoginAppRouter.navigateTo(Screen.HomeScreen) + Icon(Icons.Default.Home, contentDescription = "Camera") } - ) { - - Icon(Icons.Default.Home, contentDescription = "Camera") } - } - ) - }) { innerPadding -> - // AndroidView to display the camera preview - AndroidView(factory = { context -> - PreviewView(context).apply { - layoutParams = LinearLayout.LayoutParams( - ViewGroup.LayoutParams.MATCH_PARENT, - ViewGroup.LayoutParams.MATCH_PARENT - ) - scaleType = PreviewView.ScaleType.FILL_START - implementationMode = PreviewView.ImplementationMode.COMPATIBLE - this.controller = cameraController - } - }) - - // Column to organize UI elements vertically with space between them - Column( - modifier = Modifier - .fillMaxHeight() - .padding(innerPadding) - .padding(16.dp), - verticalArrangement = Arrangement.Bottom, - horizontalAlignment = Alignment.CenterHorizontally - ) { + ) + }) { innerPadding -> + // AndroidView to display the camera preview + AndroidView(factory = { context -> + PreviewView(context).apply { + layoutParams = LinearLayout.LayoutParams( + ViewGroup.LayoutParams.MATCH_PARENT, + ViewGroup.LayoutParams.MATCH_PARENT + ) + scaleType = PreviewView.ScaleType.FILL_START + implementationMode = PreviewView.ImplementationMode.COMPATIBLE + this.controller = cameraController + } + }) + // Column to organize UI elements vertically with space between them Column( modifier = Modifier - .fillMaxHeight(), - verticalArrangement = Arrangement.SpaceBetween, + .fillMaxHeight() + .padding(innerPadding) + .padding(16.dp), + verticalArrangement = Arrangement.Bottom, horizontalAlignment = Alignment.CenterHorizontally ) { - // Card composable to display barcode information - Card( - colors = CardDefaults.cardColors( - containerColor = MaterialTheme.colorScheme.surfaceVariant, - ), - shape = RoundedCornerShape(10.dp) + Column( + modifier = Modifier + .fillMaxHeight(), + verticalArrangement = Arrangement.SpaceBetween, + horizontalAlignment = Alignment.CenterHorizontally ) { - Column( - modifier = Modifier.padding(16.dp) + + // Card composable to display barcode information + Card( + colors = CardDefaults.cardColors( + containerColor = MaterialTheme.colorScheme.surfaceVariant, + ), + shape = RoundedCornerShape(10.dp) ) { - if (barcode.value.barcode.isNotEmpty()) { - Text(text = "Barcode: ${barcode.value.barcode}") - } else { - Text(text = "Point camera at a barcode") + Column( + modifier = Modifier.padding(16.dp) + ) { + if (barcode.value.barcode.isNotEmpty()) { + Text(text = "Barcode: ${barcode.value.barcode}") + } else { + Text(text = "Point camera at a barcode") + } } } - } - // Row for torch button and search button - Row( - modifier = Modifier.fillMaxWidth(), - horizontalArrangement = Arrangement.SpaceBetween - ) { - - // Button to toggle the torch - Button( - onClick = onTorchButtonClicked, - colors = ButtonDefaults.buttonColors( - containerColor = MaterialTheme.colorScheme.primary, - contentColor = MaterialTheme.colorScheme.onPrimary - ) + // Row for torch button and search button + Row( + modifier = Modifier.fillMaxWidth(), + horizontalArrangement = Arrangement.SpaceBetween ) { - if (torchEnabled.value) { - Icon( - imageVector = Icons.Default.FlashOff, - contentDescription = "Flash off icon" - ) - } else { - Icon( - imageVector = Icons.Default.FlashOn, - contentDescription = "Flash on icon" + // Button to toggle the torch + Button( + onClick = onTorchButtonClicked, + colors = ButtonDefaults.buttonColors( + containerColor = MaterialTheme.colorScheme.primary, + contentColor = MaterialTheme.colorScheme.onPrimary ) + ) { + if (torchEnabled.value) { + Icon( + imageVector = Icons.Default.FlashOff, + contentDescription = "Flash off icon" + ) + + } else { + Icon( + imageVector = Icons.Default.FlashOn, + contentDescription = "Flash on icon" + ) + } } - } - // Button to search for product info - Button(onClick = { - if (barcode.value.barcode.isNotEmpty()) { - isLoading = true - networkResult = null - productViewModel.getInfo(barcode.value.barcode) - showProductInfo = true - } else { - Toast.makeText(context, "No barcode found", Toast.LENGTH_SHORT) - .show() + // Button to search for product info + Button(onClick = { + if (barcode.value.barcode.isNotEmpty()) { + isLoading = true + networkResult = null + productViewModel.getInfo(barcode.value.barcode) + showProductInfo = true + } else { + Toast.makeText(context, "No barcode found", Toast.LENGTH_SHORT) + .show() + } + }) { + Text(text = "Search Product Info") } - }) { - Text(text = "Search Product Info") } } } } } - } - if (informationProductObject.barcodeNumber != "") { - // Display a loading indicator while loading product info - if (isLoading) { - Column( - modifier = Modifier - .fillMaxSize() - .padding(16.dp), - verticalArrangement = Arrangement.Center, - horizontalAlignment = Alignment.CenterHorizontally - - ) { - CircularProgressIndicator( + if (informationProductObject.barcodeNumber != "") { + // Display a loading indicator while loading product info + if (isLoading) { + Column( modifier = Modifier - .size(50.dp) - ) + .fillMaxSize() + .padding(16.dp), + verticalArrangement = Arrangement.Center, + horizontalAlignment = Alignment.CenterHorizontally + + ) { + CircularProgressIndicator( + modifier = Modifier + .size(50.dp) + ) + } } } - } - // Display the product information if there is a successful result - if (showProductInfo && informationProductObject.barcodeNumber != "") { - isLoading = false - Scaffold(topBar = { - TopAppBar( - title = { - Text("MyCloset", modifier = Modifier.padding(2.dp), style = textType.titleLarge) - }, - actions = { - IconButton( - onClick = { - showProductInfo=false + // Display the product information if there is a successful result + if (showProductInfo && informationProductObject.barcodeNumber != "") { + isLoading = false + Scaffold(topBar = { + TopAppBar( + title = { + Text("MyCloset", style = textType.titleLarge) + }, + actions = { + IconButton( + onClick = { + showProductInfo = false + } + ) { + Icon(Icons.Default.Camera, contentDescription = "Camera") } - ) { - Icon(Icons.Default.Camera, contentDescription = "Camera") } - } - ) - }) { innerPadding -> - - Column( - modifier = Modifier - .fillMaxSize() - .padding(innerPadding) - .padding(18.dp) - ) { - - //If the title is to big, make it shorter - val title = informationProductObject.title - val textToDisplay = if ("," in title) { - title.substringBefore(",") - } else { - if ("-" in title) { - title.substringBefore("-") + ) + }) { innerPadding -> + + Column( + modifier = Modifier + .fillMaxSize() + .padding(innerPadding) + .background(md_theme_light_outline) + ) { + + //If the title is to big, make it shorter + val title = informationProductObject.title + val textToDisplay = if ("," in title) { + title.substringBefore(",") } else { - title + if ("-" in title) { + title.substringBefore("-") + } else { + title + } } - } - //Title - Text( - text = textToDisplay, - fontWeight = FontWeight.Bold, - fontSize = 18.sp, - ) + //Title + Text( + text = textToDisplay, + fontWeight = FontWeight.Bold, + fontSize = 18.sp, + modifier = Modifier.padding(16.dp) + ) - Spacer(modifier = Modifier.height(24.dp)) + Spacer(modifier = Modifier.height(24.dp)) - // Image of the product - Column(modifier = Modifier.fillMaxWidth(), horizontalAlignment = Alignment.CenterHorizontally) { - ImgDisplay.DisplayPicture(informationProductObject.images) - } + // Image of the product + Column( + modifier = Modifier.fillMaxWidth(), + horizontalAlignment = Alignment.CenterHorizontally + ) { + ImgDisplay.DisplayPicture(informationProductObject.images) + } - Spacer(modifier = Modifier.height(24.dp)) + Spacer(modifier = Modifier.height(24.dp)) - LazyColumn( - modifier = Modifier.fillMaxWidth(), - contentPadding = PaddingValues(16.dp) - ) { + LazyColumn( + modifier = Modifier.fillMaxWidth(), + contentPadding = PaddingValues(16.dp) + ) { - //information - item { - Text( - text = "Product Information :", - fontWeight = FontWeight.Bold, - fontSize = 18.sp, - modifier = Modifier.padding(bottom = 8.dp) - ) - } + //information + item { + Text( + text = "Product Information :", + fontWeight = FontWeight.Bold, + fontSize = 18.sp, + modifier = Modifier.padding(bottom = 8.dp) + ) + } - //barcode number - item { - Box( - modifier = Modifier - .fillMaxWidth() - .padding(4.dp) - .background(MaterialTheme.colorScheme.surfaceVariant) // Colore di sfondo personalizzato per Model - ) { - Text("Barcode: ${informationProductObject.barcodeNumber}") + //barcode number + item { + Box( + modifier = Modifier + .fillMaxWidth() + .padding(4.dp) + .background(MaterialTheme.colorScheme.surfaceVariant) // Colore di sfondo personalizzato per Model + ) { + Text("Barcode: ${informationProductObject.barcodeNumber}") + } } - Text("Barcode: ${informationProductObject.barcodeNumber}", style = textType.bodyMedium) - } - //model - if(informationProductObject.model!=""){ + //model + if (informationProductObject.model != "") { item { Box( modifier = Modifier @@ -319,30 +324,12 @@ fun ProductScanView( .padding(4.dp) .background(MaterialTheme.colorScheme.surfaceVariant) // Colore di sfondo personalizzato per Model ) { - Text("Model: ${informationProductObject.model}") + Text("Model: ${informationProductObject.model}") + } } } - item { - Text("Model: ${informationProductObject.model}", style = textType.bodyMedium) - } - //category - item { - Box( - modifier = Modifier - .fillMaxWidth() - .padding(4.dp) - .background(MaterialTheme.colorScheme.surfaceVariant) // Colore di sfondo personalizzato per Model - ) { - val categoryText = informationProductObject.category - val category = categoryText.substringAfterLast(">") - Text("Category: $category") - } - Text("Category: ${informationProductObject.category}", style = textType.bodyMedium) - } - - //brand - if(informationProductObject.brand!=""){ + //category item { Box( modifier = Modifier @@ -350,95 +337,99 @@ fun ProductScanView( .padding(4.dp) .background(MaterialTheme.colorScheme.surfaceVariant) // Colore di sfondo personalizzato per Model ) { - Text("Brand: ${informationProductObject.brand}") + val categoryText = informationProductObject.category + val category = categoryText.substringAfterLast(">") + Text("Category: $category") } } - item { - Text("Brand: ${informationProductObject.brand}", style = textType.bodyMedium) - } - //color - if(informationProductObject.color!="") { - item { - Box( - modifier = Modifier - .fillMaxWidth() - .padding(4.dp) - .background(MaterialTheme.colorScheme.surfaceVariant) // Colore di sfondo personalizzato per Model - ) { - Text("Color: ${informationProductObject.color}") + //brand + if (informationProductObject.brand != "") { + item { + Box( + modifier = Modifier + .fillMaxWidth() + .padding(4.dp) + .background(MaterialTheme.colorScheme.surfaceVariant) // Colore di sfondo personalizzato per Model + ) { + Text("Brand: ${informationProductObject.brand}") + } } } - item { - Text("Color: ${informationProductObject.color}", style = textType.bodyMedium) - } - - //material - if(informationProductObject.material!="") { - item { - Box( - modifier = Modifier - .fillMaxWidth() - .padding(4.dp) - .background(MaterialTheme.colorScheme.surfaceVariant) // Colore di sfondo personalizzato per Model - ) { - Text("Material: ${informationProductObject.material}") + //color + if (informationProductObject.color != "") { + item { + Box( + modifier = Modifier + .fillMaxWidth() + .padding(4.dp) + .background(MaterialTheme.colorScheme.surfaceVariant) // Colore di sfondo personalizzato per Model + ) { + Text("Color: ${informationProductObject.color}") + } } } - item { - Text("Material: ${informationProductObject.material}", style = textType.bodyMedium) - } + //material + if (informationProductObject.material != "") { + item { + Box( + modifier = Modifier + .fillMaxWidth() + .padding(4.dp) + .background(MaterialTheme.colorScheme.surfaceVariant) // Colore di sfondo personalizzato per Model + ) { + Text("Material: ${informationProductObject.material}") + } + } + } - //size - if(informationProductObject.size!=""){ - item { - Box( - modifier = Modifier - .fillMaxWidth() - .padding(4.dp) - .background(MaterialTheme.colorScheme.surfaceVariant) // Colore di sfondo personalizzato per Model - ) { - Text("Size: ${informationProductObject.size}") + //size + if (informationProductObject.size != "") { + item { + Box( + modifier = Modifier + .fillMaxWidth() + .padding(4.dp) + .background(MaterialTheme.colorScheme.surfaceVariant) // Colore di sfondo personalizzato per Model + ) { + Text("Size: ${informationProductObject.size}") + } } } - item { - Text("Size: ${informationProductObject.size}", style = textType.bodyMedium) } - } - - Spacer(modifier = Modifier.weight(1f)) + Spacer(modifier = Modifier.weight(1f)) - //button - Row( - modifier = Modifier.fillMaxWidth(), - horizontalArrangement = Arrangement.SpaceBetween - ) { - Button(onClick = { - showProductInfo = false - }) { - Text(text = "Back", style = textType.bodyMedium) - } - if (LoggedUser.loggedUserEmail != "") { + //button + Row( + modifier = Modifier.fillMaxWidth(), + horizontalArrangement = Arrangement.SpaceBetween + ) { Button(onClick = { - productViewModel.saveToDatabase(informationProductObject) - Toast.makeText(context, "Item added!", Toast.LENGTH_SHORT).show() - LoginAppRouter.navigateTo(Screen.HomeScreen) + showProductInfo = false }) { - Text(text = "Add") + Text(text = "Back") + } + if (LoggedUser.loggedUserEmail != "") { + Button(onClick = { + productViewModel.saveToDatabase(informationProductObject) + Toast.makeText(context, "Item added!", Toast.LENGTH_SHORT).show() + LoginAppRouter.navigateTo(Screen.HomeScreen) + }) { + Text(text = "Add") + } + } else { + Log.i( + "LOGIN_ERROR", + "You can't add a new item to your wardrobe because you aren't logged" + ) } - } else { - Log.i( - "LOGIN_ERROR", - "You can't add a new item to your wardrobe because you aren't logged" - ) } } } } } } - diff --git a/app/src/main/java/com/example/mycloset/Views/SingleItemScreen.kt b/app/src/main/java/com/example/mycloset/Views/SingleItemScreen.kt index 23cc4a3..b8f5bb0 100644 --- a/app/src/main/java/com/example/mycloset/Views/SingleItemScreen.kt +++ b/app/src/main/java/com/example/mycloset/Views/SingleItemScreen.kt @@ -97,52 +97,43 @@ fun SingleItemScreen(productViewModel: ProductViewModel) { ) { val product = products[0] - //title - Text( - text = product.title, - fontWeight = FontWeight.Bold, - fontSize = 18.sp, - ) - - Spacer(modifier = Modifier.height(24.dp)) + //title + Text( + text = product.title, + fontWeight = FontWeight.Bold, + fontSize = 18.sp, + modifier = Modifier.padding(16.dp) + ) - //images - Column(modifier = Modifier.fillMaxWidth(), horizontalAlignment = Alignment.CenterHorizontally) { - DisplayPicture(product.images) - } + Spacer(modifier = Modifier.height(24.dp)) - Spacer(modifier = Modifier.height(24.dp)) + //images + Column( + modifier = Modifier.fillMaxWidth(), + horizontalAlignment = Alignment.CenterHorizontally + ) { + DisplayPicture(product.images) + } + Spacer(modifier = Modifier.height(24.dp)) - LazyColumn( - modifier = Modifier.fillMaxWidth(), - contentPadding = PaddingValues(16.dp) - ) { - //product information - item { - Text( - text = "Product Information :", - fontWeight = FontWeight.Bold, - fontSize = 18.sp, - modifier = Modifier.padding(bottom = 8.dp) - ) - } + LazyColumn( + modifier = Modifier.fillMaxWidth(), + contentPadding = PaddingValues(16.dp) + ) { - //barcode number - item { - Box( - modifier = Modifier - .fillMaxWidth() - .padding(4.dp) - .background(MaterialTheme.colorScheme.surfaceVariant) // Colore di sfondo personalizzato per Model - ) { - Text("Barcode: ${product.barcodeNumber}") + //product information + item { + Text( + text = "Product Information :", + fontWeight = FontWeight.Bold, + fontSize = 18.sp, + modifier = Modifier.padding(bottom = 8.dp) + ) } - } - //model - if(product.model!=""){ + //barcode number item { Box( modifier = Modifier @@ -150,25 +141,25 @@ fun SingleItemScreen(productViewModel: ProductViewModel) { .padding(4.dp) .background(MaterialTheme.colorScheme.surfaceVariant) // Colore di sfondo personalizzato per Model ) { - Text("Model: ${product.model}") + Text("Barcode: ${product.barcodeNumber}") } } - } - //category - item { - Box( - modifier = Modifier - .fillMaxWidth() - .padding(4.dp) - .background(MaterialTheme.colorScheme.surfaceVariant) // Colore di sfondo personalizzato per Model - ) { - Text("Category: ${product.category}") + //model + if (product.model != "") { + item { + Box( + modifier = Modifier + .fillMaxWidth() + .padding(4.dp) + .background(MaterialTheme.colorScheme.surfaceVariant) // Colore di sfondo personalizzato per Model + ) { + Text("Model: ${product.model}") + } + } } - } - //brand - if(product.brand!=""){ + //category item { Box( modifier = Modifier @@ -176,94 +167,96 @@ fun SingleItemScreen(productViewModel: ProductViewModel) { .padding(4.dp) .background(MaterialTheme.colorScheme.surfaceVariant) // Colore di sfondo personalizzato per Model ) { - Text("Brand: ${product.brand}") + Text("Category: ${product.category}") } } - } - //color - if(product.color!="") { - item { - Box( - modifier = Modifier - .fillMaxWidth() - .padding(4.dp) - .background(MaterialTheme.colorScheme.surfaceVariant) // Colore di sfondo personalizzato per Model - ) { - Text("Color: ${product.color}") + //brand + if (product.brand != "") { + item { + Box( + modifier = Modifier + .fillMaxWidth() + .padding(4.dp) + .background(MaterialTheme.colorScheme.surfaceVariant) // Colore di sfondo personalizzato per Model + ) { + Text("Brand: ${product.brand}") + } } } - } - //material - if(product.material!="") { - item { - Box( - modifier = Modifier - .fillMaxWidth() - .padding(4.dp) - .background(MaterialTheme.colorScheme.surfaceVariant) // Colore di sfondo personalizzato per Model - ) { - Text("Material: ${product.material}") + //color + if (product.color != "") { + item { + Box( + modifier = Modifier + .fillMaxWidth() + .padding(4.dp) + .background(MaterialTheme.colorScheme.surfaceVariant) // Colore di sfondo personalizzato per Model + ) { + Text("Color: ${product.color}") + } } } - } - //size - if(informationProductObject.size!=""){ - item { - Box( - modifier = Modifier - .fillMaxWidth() - .padding(4.dp) - .background(MaterialTheme.colorScheme.surfaceVariant) // Colore di sfondo personalizzato per Model - ) { - Text("Size: ${informationProductObject.size}") + //material + if (product.material != "") { + item { + Box( + modifier = Modifier + .fillMaxWidth() + .padding(4.dp) + .background(MaterialTheme.colorScheme.surfaceVariant) // Colore di sfondo personalizzato per Model + ) { + Text("Material: ${product.material}") + } + } + } + + //size + if (informationProductObject.size != "") { + item { + Box( + modifier = Modifier + .fillMaxWidth() + .padding(4.dp) + .background(MaterialTheme.colorScheme.surfaceVariant) // Colore di sfondo personalizzato per Model + ) { + Text("Size: ${informationProductObject.size}") + } } } + } - } - Spacer(modifier = Modifier.weight(1f)) - //buttons - Row( - modifier = Modifier - .fillMaxWidth() - .padding(16.dp), - horizontalArrangement = Arrangement.SpaceBetween - ) { - Button( - onClick = { - productViewModel.deleteProduct(productViewModel.selectedProduct) - Toast.makeText(context, "Item Deleted!", Toast.LENGTH_SHORT).show() - LoginAppRouter.navigateTo(Screen.HomeScreen) - } + //buttons + Row( + modifier = Modifier + .fillMaxWidth() + .padding(16.dp), + horizontalArrangement = Arrangement.SpaceBetween ) { - Text("Delete Item") - } - Button( - onClick = { - LoginAppRouter.navigateTo(Screen.UpdateSingleScreen) + Button( + onClick = { + productViewModel.deleteProduct(productViewModel.selectedProduct) + Toast.makeText(context, "Item Deleted!", Toast.LENGTH_SHORT).show() + LoginAppRouter.navigateTo(Screen.HomeScreen) + } + ) { + Text("Delete Item") + } + Button( + onClick = { + LoginAppRouter.navigateTo(Screen.UpdateSingleScreen) + } + ) { + Text("Update Item") } - ) { - Text("Update Item") } } } } -} - - -/*@Composable -@Preview -fun SingleItemView(){ - SingleItemScreen() -}*/ -//@Preview -//@Composable -//fun Info() { -// SingleItemScreen() -//} \ No newline at end of file +} \ No newline at end of file diff --git a/app/src/main/java/com/example/mycloset/Views/UpdateSingleItem.kt b/app/src/main/java/com/example/mycloset/Views/UpdateSingleItem.kt index 20cca58..4bf5825 100644 --- a/app/src/main/java/com/example/mycloset/Views/UpdateSingleItem.kt +++ b/app/src/main/java/com/example/mycloset/Views/UpdateSingleItem.kt @@ -14,6 +14,7 @@ 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.material.icons.Icons import androidx.compose.material.icons.filled.ArrowBack @@ -26,6 +27,7 @@ import androidx.compose.material3.Icon import androidx.compose.material3.IconButton import androidx.compose.material3.MaterialTheme import androidx.compose.material3.Scaffold +import androidx.compose.material3.Surface import androidx.compose.material3.Text import androidx.compose.material3.TextField import androidx.compose.material3.TopAppBar @@ -55,6 +57,8 @@ import com.example.mycloset.LoginWorkingSet.LoggedUser import com.example.mycloset.R import com.example.mycloset.navigation.LoginAppRouter import com.example.mycloset.navigation.Screen +import com.example.mycloset.ui.theme.md_theme_light_outline +import com.example.mycloset.ui.theme.textType import kotlinx.coroutines.flow.StateFlow @@ -70,7 +74,7 @@ fun UpdateSingleItem( val context = LocalContext.current //used for keeping trak of the edits var text by remember { mutableStateOf("") } - + Surface(modifier = Modifier.background(md_theme_light_outline)) { Scaffold( topBar = { // TopAppBar (the top bar) @@ -84,7 +88,7 @@ fun UpdateSingleItem( } }, title = { - Text("MyCloset") + Text("MyCloset", style = textType.titleLarge) }, actions = { IconButton(onClick = { LoginAppRouter.navigateTo(Screen.ProductScanView) }) { @@ -109,7 +113,7 @@ fun UpdateSingleItem( modifier = Modifier .fillMaxSize() .padding(innerPadding) - .padding(16.dp) + .background(md_theme_light_outline) ) { val product = products[0] @@ -118,9 +122,10 @@ fun UpdateSingleItem( text = product.title, fontWeight = FontWeight.Bold, fontSize = 18.sp, + modifier = Modifier.padding(16.dp) ) - Spacer(modifier = Modifier.height(24.dp)) + //Spacer(modifier = Modifier.height(24.dp)) //image Column( @@ -134,7 +139,7 @@ fun UpdateSingleItem( LazyColumn( - modifier = Modifier.fillMaxWidth(), + modifier = Modifier.fillMaxSize(), contentPadding = PaddingValues(16.dp) ) { @@ -223,9 +228,9 @@ fun UpdateSingleItem( } - Spacer(modifier = Modifier.weight(1f)) + //Spacer(modifier = Modifier.weight(1f)) - //bitton + //button Row( modifier = Modifier .fillMaxWidth() @@ -252,6 +257,7 @@ fun UpdateSingleItem( } } } +} From 820c236a4f557c3191bf6ee4267ac1687575b2a5 Mon Sep 17 00:00:00 2001 From: matti Date: Thu, 12 Oct 2023 23:18:45 +0200 Subject: [PATCH 30/32] Update- no delate --- .../com/example/mycloset/Views/HomeScreen.kt | 3 + .../example/mycloset/Views/ProductScanView.kt | 1 - .../mycloset/Views/SingleItemScreen.kt | 56 +++++++++---------- .../mycloset/Views/UpdateSingleItem.kt | 2 - 4 files changed, 28 insertions(+), 34 deletions(-) diff --git a/app/src/main/java/com/example/mycloset/Views/HomeScreen.kt b/app/src/main/java/com/example/mycloset/Views/HomeScreen.kt index c2d9497..50d0071 100644 --- a/app/src/main/java/com/example/mycloset/Views/HomeScreen.kt +++ b/app/src/main/java/com/example/mycloset/Views/HomeScreen.kt @@ -14,12 +14,14 @@ import androidx.compose.material.icons.filled.Logout import androidx.compose.material3.ExperimentalMaterial3Api import androidx.compose.material3.Icon import androidx.compose.material3.IconButton +import androidx.compose.material3.MaterialTheme import androidx.compose.material3.Scaffold import androidx.compose.material3.Text import androidx.compose.material3.TopAppBar import androidx.compose.runtime.* import androidx.compose.ui.Alignment import androidx.compose.ui.Modifier +import androidx.compose.ui.text.font.FontWeight import androidx.compose.ui.text.style.TextAlign import androidx.compose.ui.tooling.preview.Preview import androidx.compose.ui.unit.dp @@ -29,6 +31,7 @@ import com.example.mycloset.LoginWorkingSet.LoggedUser import com.example.mycloset.LoginWorkingSet.Signup.SignupViewModel import com.example.mycloset.navigation.LoginAppRouter import com.example.mycloset.navigation.Screen +import com.example.mycloset.ui.theme.fontFamily import kotlinx.coroutines.flow.* diff --git a/app/src/main/java/com/example/mycloset/Views/ProductScanView.kt b/app/src/main/java/com/example/mycloset/Views/ProductScanView.kt index f78fb7b..e0cdf2d 100644 --- a/app/src/main/java/com/example/mycloset/Views/ProductScanView.kt +++ b/app/src/main/java/com/example/mycloset/Views/ProductScanView.kt @@ -444,4 +444,3 @@ fun ProductScanView( } } } -} \ No newline at end of file diff --git a/app/src/main/java/com/example/mycloset/Views/SingleItemScreen.kt b/app/src/main/java/com/example/mycloset/Views/SingleItemScreen.kt index 17b676e..febbbfa 100644 --- a/app/src/main/java/com/example/mycloset/Views/SingleItemScreen.kt +++ b/app/src/main/java/com/example/mycloset/Views/SingleItemScreen.kt @@ -1,9 +1,13 @@ package com.example.mycloset.Views +import android.util.Log import android.widget.Toast +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.PaddingValues import androidx.compose.foundation.layout.Row import androidx.compose.foundation.layout.Spacer import androidx.compose.foundation.layout.fillMaxSize @@ -11,11 +15,15 @@ import androidx.compose.foundation.layout.fillMaxWidth import androidx.compose.foundation.layout.height import androidx.compose.foundation.layout.padding import androidx.compose.foundation.layout.paddingFromBaseline +import androidx.compose.foundation.layout.size +import androidx.compose.foundation.lazy.LazyColumn import androidx.compose.foundation.lazy.grid.GridCells import androidx.compose.foundation.lazy.grid.LazyVerticalGrid +import androidx.compose.foundation.shape.RoundedCornerShape import androidx.compose.material.icons.Icons import androidx.compose.material.icons.filled.ArrowBack import androidx.compose.material.icons.filled.Camera +import androidx.compose.material.icons.filled.Logout import androidx.compose.material3.Button import androidx.compose.material3.ExperimentalMaterial3Api import androidx.compose.material3.Icon @@ -26,11 +34,16 @@ import androidx.compose.material3.Surface import androidx.compose.material3.Text import androidx.compose.material3.TopAppBar import androidx.compose.runtime.Composable +import androidx.compose.ui.Alignment import androidx.compose.ui.Modifier +import androidx.compose.ui.draw.clip import androidx.compose.ui.platform.LocalContext import androidx.compose.ui.text.font.FontWeight import androidx.compose.ui.unit.dp +import androidx.compose.ui.unit.sp import androidx.lifecycle.viewmodel.compose.viewModel +import coil.compose.rememberAsyncImagePainter +import com.example.mycloset.ApiWorkingSet.ImgDisplay.Companion.DisplayPicture import com.example.mycloset.DatabaseWorkingset.ProductViewModel import com.example.mycloset.LoginWorkingSet.Signup.SignupViewModel import com.example.mycloset.navigation.LoginAppRouter @@ -90,32 +103,6 @@ fun SingleItemScreen(productViewModel: ProductViewModel) { } ) { innerPadding -> - // Content to be displayed below the top bar - - /* - innerPadding -> - // Content to be displayed below the top bar - Column( - modifier = Modifier - .fillMaxSize() - .padding(innerPadding) - .paddingFromBaseline(16.dp) - .background(MaterialTheme.colorScheme.onPrimary) - ) { - - LazyVerticalGrid( - columns = GridCells.Fixed(1), modifier = Modifier - .fillMaxSize() - .padding(8.dp) - ) { - items(products.size) { index -> - val product = products[index] - SingleItemCard(product.images, product.model, product.title, product.category, product.brand, product.size, product.barcodeNumber, productViewModel) - } - } - - - */ Column( modifier = Modifier @@ -133,14 +120,20 @@ fun SingleItemScreen(productViewModel: ProductViewModel) { modifier = Modifier.padding(16.dp) ) - Spacer(modifier = Modifier.height(24.dp)) - //images Column( modifier = Modifier.fillMaxWidth(), horizontalAlignment = Alignment.CenterHorizontally ) { - DisplayPicture(product.images) + //Log.i("IMAGE",product.images) + //DisplayPicture(product.images) + Image( + painter = rememberAsyncImagePainter(product.images), + contentDescription = null, + modifier = Modifier + .size(300.dp) + .clip(RoundedCornerShape(18.dp)), + ) } Spacer(modifier = Modifier.height(24.dp)) @@ -242,7 +235,7 @@ fun SingleItemScreen(productViewModel: ProductViewModel) { } //size - if (informationProductObject.size != "") { + if (product.size != "") { item { Box( modifier = Modifier @@ -250,13 +243,14 @@ fun SingleItemScreen(productViewModel: ProductViewModel) { .padding(4.dp) .background(MaterialTheme.colorScheme.surfaceVariant) // Colore di sfondo personalizzato per Model ) { - Text("Size: ${informationProductObject.size}") + Text("Size: ${product.size}") } } } } + Spacer(modifier = Modifier.weight(1f)) //buttons diff --git a/app/src/main/java/com/example/mycloset/Views/UpdateSingleItem.kt b/app/src/main/java/com/example/mycloset/Views/UpdateSingleItem.kt index 4bf5825..f96edab 100644 --- a/app/src/main/java/com/example/mycloset/Views/UpdateSingleItem.kt +++ b/app/src/main/java/com/example/mycloset/Views/UpdateSingleItem.kt @@ -135,8 +135,6 @@ fun UpdateSingleItem( DisplayPicture(product.images) } - Spacer(modifier = Modifier.height(24.dp)) - LazyColumn( modifier = Modifier.fillMaxSize(), From 2736ef24d1487183365ea043762d0406e7e43ae0 Mon Sep 17 00:00:00 2001 From: matti Date: Thu, 12 Oct 2023 23:25:40 +0200 Subject: [PATCH 31/32] Update- no delate --- .../mycloset/Views/SingleItemScreen.kt | 2 - .../mycloset/Views/UpdateSingleItem.kt | 133 +++++++++--------- 2 files changed, 68 insertions(+), 67 deletions(-) diff --git a/app/src/main/java/com/example/mycloset/Views/SingleItemScreen.kt b/app/src/main/java/com/example/mycloset/Views/SingleItemScreen.kt index febbbfa..ed84170 100644 --- a/app/src/main/java/com/example/mycloset/Views/SingleItemScreen.kt +++ b/app/src/main/java/com/example/mycloset/Views/SingleItemScreen.kt @@ -262,7 +262,6 @@ fun SingleItemScreen(productViewModel: ProductViewModel) { ) { Button( onClick = { - //productViewModel.deleteProduct(informationProductObject) productViewModel.deleteProduct(productViewModel.selectedProduct) Toast.makeText(context, "Item Deleted!", Toast.LENGTH_SHORT).show() LoginAppRouter.navigateTo(Screen.HomeScreen) @@ -281,5 +280,4 @@ fun SingleItemScreen(productViewModel: ProductViewModel) { } } } - } \ No newline at end of file diff --git a/app/src/main/java/com/example/mycloset/Views/UpdateSingleItem.kt b/app/src/main/java/com/example/mycloset/Views/UpdateSingleItem.kt index f96edab..8e93a86 100644 --- a/app/src/main/java/com/example/mycloset/Views/UpdateSingleItem.kt +++ b/app/src/main/java/com/example/mycloset/Views/UpdateSingleItem.kt @@ -135,29 +135,32 @@ fun UpdateSingleItem( DisplayPicture(product.images) } - - LazyColumn( - modifier = Modifier.fillMaxSize(), - contentPadding = PaddingValues(16.dp) + Box( + modifier = Modifier + .weight(1f) ) { + LazyColumn( + modifier = Modifier.fillMaxSize(), + contentPadding = PaddingValues(16.dp) + ) { - //info - item { - Text( - text = "Edit the fields :", - fontWeight = FontWeight.Bold, - fontSize = 18.sp, - modifier = Modifier.padding(bottom = 8.dp) - ) - } + //info + item { + Text( + text = "Edit the fields :", + fontWeight = FontWeight.Bold, + fontSize = 18.sp, + modifier = Modifier.padding(bottom = 8.dp) + ) + } - //prepare the object for save the update - var product = products[0] + //prepare the object for save the update + var product = products[0] - //model - if (product.model != "") { - item { - EditableTextField( + //model + if (product.model != "") { + item { + EditableTextField( initialValue = product.model, onValueChange = { newValue: String -> product.model = newValue @@ -166,66 +169,66 @@ fun UpdateSingleItem( } } - //category - item { - EditableTextField( - initialValue = product.category, - onValueChange = { newValue: String -> - product.category = newValue - } - ) - } - - //brand - if (product.brand != "") { + //category item { EditableTextField( - initialValue = product.brand, + initialValue = product.category, onValueChange = { newValue: String -> - product.brand = newValue + product.category = newValue } ) } - } - //color - if (product.color != "") { - item { - EditableTextField( - initialValue = product.color, - onValueChange = { newValue: String -> - product.color = newValue - } - ) + //brand + if (product.brand != "") { + item { + EditableTextField( + initialValue = product.brand, + onValueChange = { newValue: String -> + product.brand = newValue + } + ) + } } - } - //material - if (product.material != "") { - item { - EditableTextField( - initialValue = product.material, - onValueChange = { newValue: String -> - product.material = newValue - } - ) + //color + if (product.color != "") { + item { + EditableTextField( + initialValue = product.color, + onValueChange = { newValue: String -> + product.color = newValue + } + ) + } } - } - //size - if (informationProductObject.size != "") { - item { - EditableTextField( - initialValue = product.size, - onValueChange = { newValue: String -> - product.size = newValue - } - ) + //material + if (product.material != "") { + item { + EditableTextField( + initialValue = product.material, + onValueChange = { newValue: String -> + product.material = newValue + } + ) + } } - } - } + //size + if (informationProductObject.size != "") { + item { + EditableTextField( + initialValue = product.size, + onValueChange = { newValue: String -> + product.size = newValue + } + ) + } + } + } + } //Spacer(modifier = Modifier.weight(1f)) //button From 5c33a84696df66d4b4fbec991b7d8b30ba20eff7 Mon Sep 17 00:00:00 2001 From: matti Date: Fri, 13 Oct 2023 00:14:33 +0200 Subject: [PATCH 32/32] Update- no delate --- .../com/example/mycloset/Views/ItemCard.kt | 5 ++- .../mycloset/Views/UpdateSingleItem.kt | 45 ++++++++++++------- 2 files changed, 33 insertions(+), 17 deletions(-) diff --git a/app/src/main/java/com/example/mycloset/Views/ItemCard.kt b/app/src/main/java/com/example/mycloset/Views/ItemCard.kt index 4977c9b..8af6589 100644 --- a/app/src/main/java/com/example/mycloset/Views/ItemCard.kt +++ b/app/src/main/java/com/example/mycloset/Views/ItemCard.kt @@ -14,6 +14,7 @@ import androidx.compose.runtime.Composable import androidx.compose.ui.Alignment import androidx.compose.ui.Modifier import androidx.compose.ui.draw.clip +import androidx.compose.ui.text.font.FontWeight import androidx.compose.ui.unit.dp import coil.compose.rememberAsyncImagePainter import com.example.mycloset.DatabaseWorkingset.ProductViewModel @@ -45,7 +46,7 @@ fun ItemCard( } ) { Column( - modifier = Modifier.padding(8.dp), + modifier = Modifier.padding(3.dp), horizontalAlignment = Alignment.CenterHorizontally ) { Image( @@ -55,7 +56,7 @@ fun ItemCard( .size(120.dp) .clip(RoundedCornerShape(8.dp)) ) - name?.let { Text(text = it, style = textType.bodyMedium) } + name?.let { Text(text = it, style = textType.bodyMedium,fontWeight = FontWeight.Bold,) } } } } diff --git a/app/src/main/java/com/example/mycloset/Views/UpdateSingleItem.kt b/app/src/main/java/com/example/mycloset/Views/UpdateSingleItem.kt index 8e93a86..e6f2f4d 100644 --- a/app/src/main/java/com/example/mycloset/Views/UpdateSingleItem.kt +++ b/app/src/main/java/com/example/mycloset/Views/UpdateSingleItem.kt @@ -57,6 +57,7 @@ import com.example.mycloset.LoginWorkingSet.LoggedUser import com.example.mycloset.R import com.example.mycloset.navigation.LoginAppRouter import com.example.mycloset.navigation.Screen +import com.example.mycloset.ui.theme.fontFamily import com.example.mycloset.ui.theme.md_theme_light_outline import com.example.mycloset.ui.theme.textType import kotlinx.coroutines.flow.StateFlow @@ -88,7 +89,13 @@ fun UpdateSingleItem( } }, title = { - Text("MyCloset", style = textType.titleLarge) + Text( + text = "MyCloset", + fontFamily = fontFamily, + modifier = Modifier.padding(vertical = 16.dp), + fontWeight = FontWeight.Bold, + style = MaterialTheme.typography.displayMedium, + color = MaterialTheme.colorScheme.onPrimaryContainer) }, actions = { IconButton(onClick = { LoginAppRouter.navigateTo(Screen.ProductScanView) }) { @@ -134,7 +141,14 @@ fun UpdateSingleItem( ) { DisplayPicture(product.images) } - + Column (modifier=Modifier.padding(horizontal = 20.dp)){ + Text( + text = "Edit the fields :", + fontWeight = FontWeight.Bold, + fontSize = 18.sp, + modifier = Modifier.padding(bottom = 8.dp) + ) + } Box( modifier = Modifier .weight(1f) @@ -146,12 +160,7 @@ fun UpdateSingleItem( //info item { - Text( - text = "Edit the fields :", - fontWeight = FontWeight.Bold, - fontSize = 18.sp, - modifier = Modifier.padding(bottom = 8.dp) - ) + } //prepare the object for save the update @@ -164,7 +173,8 @@ fun UpdateSingleItem( initialValue = product.model, onValueChange = { newValue: String -> product.model = newValue - } + }, + "Model" ) } } @@ -175,7 +185,8 @@ fun UpdateSingleItem( initialValue = product.category, onValueChange = { newValue: String -> product.category = newValue - } + }, + "Category" ) } @@ -186,7 +197,8 @@ fun UpdateSingleItem( initialValue = product.brand, onValueChange = { newValue: String -> product.brand = newValue - } + }, + "Brand" ) } } @@ -198,7 +210,8 @@ fun UpdateSingleItem( initialValue = product.color, onValueChange = { newValue: String -> product.color = newValue - } + }, + "Color" ) } } @@ -210,26 +223,28 @@ fun UpdateSingleItem( initialValue = product.material, onValueChange = { newValue: String -> product.material = newValue - } + }, + "Material" ) } } //size - if (informationProductObject.size != "") { + if (product.size != "") { item { EditableTextField( initialValue = product.size, onValueChange = { newValue: String -> product.size = newValue } + , + "Size" ) } } } } - //Spacer(modifier = Modifier.weight(1f)) //button Row(