4 Lab Recover Old Functional
This commit is contained in:
parent
7f9450d02e
commit
756cfa14c0
@ -3,6 +3,7 @@
|
|||||||
xmlns:tools="http://schemas.android.com/tools">
|
xmlns:tools="http://schemas.android.com/tools">
|
||||||
|
|
||||||
<application
|
<application
|
||||||
|
android:name=".FoodWarriorsApplication"
|
||||||
android:allowBackup="true"
|
android:allowBackup="true"
|
||||||
android:dataExtractionRules="@xml/data_extraction_rules"
|
android:dataExtractionRules="@xml/data_extraction_rules"
|
||||||
android:fullBackupContent="@xml/backup_rules"
|
android:fullBackupContent="@xml/backup_rules"
|
||||||
|
@ -0,0 +1,32 @@
|
|||||||
|
package com.example.myapplication
|
||||||
|
|
||||||
|
import androidx.lifecycle.ViewModelProvider
|
||||||
|
import androidx.lifecycle.viewmodel.CreationExtras
|
||||||
|
import androidx.lifecycle.viewmodel.initializer
|
||||||
|
import androidx.lifecycle.viewmodel.viewModelFactory
|
||||||
|
import com.example.myapplication.ui.dishes.list.DishListViewModel
|
||||||
|
import com.example.myapplication.ui.dishes.view.DishViewModel
|
||||||
|
import com.example.myapplication.ui.extra.ErrorsViewModel
|
||||||
|
import com.example.myapplication.ui.user.UserViewModel
|
||||||
|
|
||||||
|
|
||||||
|
object AppViewModelProvider {
|
||||||
|
val Factory = viewModelFactory {
|
||||||
|
initializer {
|
||||||
|
DishListViewModel(foodWarriorsApplication().container.dishRepository,
|
||||||
|
foodWarriorsApplication().container.userFavoritesRepository)
|
||||||
|
}
|
||||||
|
initializer {
|
||||||
|
ErrorsViewModel()
|
||||||
|
}
|
||||||
|
initializer {
|
||||||
|
UserViewModel(foodWarriorsApplication().container.userRepository)
|
||||||
|
}
|
||||||
|
initializer {
|
||||||
|
DishViewModel(foodWarriorsApplication().container.dishRepository)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
fun CreationExtras.foodWarriorsApplication(): FoodWarriorsApplication =
|
||||||
|
(this[ViewModelProvider.AndroidViewModelFactory.APPLICATION_KEY] as FoodWarriorsApplication)
|
@ -1,195 +0,0 @@
|
|||||||
package com.example.myapplication.Dishes.ui
|
|
||||||
|
|
||||||
import android.os.Build
|
|
||||||
import androidx.annotation.RequiresApi
|
|
||||||
import androidx.compose.foundation.Image
|
|
||||||
import androidx.compose.foundation.ScrollState
|
|
||||||
import androidx.compose.foundation.clickable
|
|
||||||
import androidx.compose.foundation.layout.Arrangement
|
|
||||||
import androidx.compose.foundation.layout.Column
|
|
||||||
import androidx.compose.foundation.layout.Row
|
|
||||||
import androidx.compose.foundation.layout.fillMaxSize
|
|
||||||
import androidx.compose.foundation.layout.fillMaxWidth
|
|
||||||
import androidx.compose.foundation.layout.padding
|
|
||||||
import androidx.compose.foundation.layout.width
|
|
||||||
import androidx.compose.foundation.verticalScroll
|
|
||||||
import androidx.compose.material.icons.Icons
|
|
||||||
import androidx.compose.material.icons.filled.Favorite
|
|
||||||
import androidx.compose.material.icons.filled.FavoriteBorder
|
|
||||||
import androidx.compose.material.icons.filled.Warning
|
|
||||||
import androidx.compose.material3.Icon
|
|
||||||
import androidx.compose.material3.MaterialTheme
|
|
||||||
import androidx.compose.material3.Surface
|
|
||||||
import androidx.compose.material3.Text
|
|
||||||
import androidx.compose.runtime.Composable
|
|
||||||
import androidx.compose.runtime.LaunchedEffect
|
|
||||||
import androidx.compose.runtime.mutableStateListOf
|
|
||||||
import androidx.compose.runtime.remember
|
|
||||||
import androidx.compose.runtime.rememberCoroutineScope
|
|
||||||
import androidx.compose.ui.Alignment
|
|
||||||
import androidx.compose.ui.Modifier
|
|
||||||
import androidx.compose.ui.graphics.asImageBitmap
|
|
||||||
import androidx.compose.ui.platform.LocalContext
|
|
||||||
import androidx.compose.ui.res.painterResource
|
|
||||||
import androidx.compose.ui.res.stringResource
|
|
||||||
import androidx.compose.ui.text.style.TextAlign
|
|
||||||
import androidx.compose.ui.text.style.TextOverflow
|
|
||||||
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 androidx.navigation.NavController
|
|
||||||
import com.example.myapplication.Dishes.Model.Dish
|
|
||||||
//import com.example.myapplication.Dishes.Model.getAllDishes
|
|
||||||
import com.example.myapplication.R
|
|
||||||
import com.example.myapplication.User.Model.User
|
|
||||||
import com.example.myapplication.User.Model.UserFavorites
|
|
||||||
import com.example.myapplication.database.AppDatabase
|
|
||||||
import com.example.myapplication.ui.theme.MyApplicationTheme
|
|
||||||
import com.example.myapplication.ui.theme.textFont
|
|
||||||
import kotlinx.coroutines.Dispatchers
|
|
||||||
import kotlinx.coroutines.launch
|
|
||||||
import kotlinx.coroutines.withContext
|
|
||||||
|
|
||||||
|
|
||||||
@RequiresApi(Build.VERSION_CODES.Q)
|
|
||||||
@Composable
|
|
||||||
fun DishList(navController: NavController?, onlyFavorites: Boolean = false, someUser: Int? = remember { null }, userPage: Boolean = false) {
|
|
||||||
val context = LocalContext.current
|
|
||||||
val dishes = remember { mutableStateListOf<Dish>() }
|
|
||||||
val favoriteDishes = remember { mutableStateListOf<Dish>() }
|
|
||||||
val scope = rememberCoroutineScope()
|
|
||||||
LaunchedEffect(Unit) {
|
|
||||||
withContext(Dispatchers.IO) {
|
|
||||||
|
|
||||||
if (someUser != null && onlyFavorites) {
|
|
||||||
AppDatabase.getInstance(context).userFavoritesDao().getUserFavorites(someUser).collect() {data ->
|
|
||||||
dishes.clear()
|
|
||||||
favoriteDishes.clear()
|
|
||||||
dishes.addAll(data)
|
|
||||||
favoriteDishes.addAll(data)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
else if (someUser != null && userPage) {
|
|
||||||
AppDatabase.getInstance(context).dishDao().getAllOFUser(someUser).collect() {data ->
|
|
||||||
dishes.clear()
|
|
||||||
favoriteDishes.clear()
|
|
||||||
dishes.addAll(data)
|
|
||||||
AppDatabase.getInstance(context).userFavoritesDao().getUserFavorites(someUser).collect() {data ->
|
|
||||||
favoriteDishes.addAll(data)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
AppDatabase.getInstance(context).dishDao().getAll().collect() { data ->
|
|
||||||
dishes.clear()
|
|
||||||
favoriteDishes.clear()
|
|
||||||
dishes.addAll(data)
|
|
||||||
AppDatabase.getInstance(context).userFavoritesDao().getUserFavorites(someUser).collect() {data ->
|
|
||||||
favoriteDishes.addAll(data)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
}
|
|
||||||
}
|
|
||||||
Column(
|
|
||||||
Modifier
|
|
||||||
.fillMaxSize()
|
|
||||||
.verticalScroll(ScrollState(0))) {
|
|
||||||
|
|
||||||
Row(horizontalArrangement = Arrangement.Center, modifier = Modifier.fillMaxWidth()) {
|
|
||||||
Column {
|
|
||||||
var text = stringResource(R.string.all_dishes)
|
|
||||||
if (onlyFavorites) text = stringResource(id = R.string.favorite_dishes)
|
|
||||||
if (userPage) text = stringResource(id = R.string.user_dishes)
|
|
||||||
Text(text, fontFamily= textFont,
|
|
||||||
fontSize=26.sp, textAlign = TextAlign.Start)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
dishes.forEachIndexed() {index, dish ->
|
|
||||||
Row(
|
|
||||||
Modifier
|
|
||||||
.padding(vertical = 5.dp)
|
|
||||||
.fillMaxSize()
|
|
||||||
.clickable {
|
|
||||||
navController?.navigate("dish/" + dish.uid!!)
|
|
||||||
}) {
|
|
||||||
|
|
||||||
Column() {
|
|
||||||
if (dish.image != null) { // TODO Image input check
|
|
||||||
Image(
|
|
||||||
bitmap = dish.getBitmapFromByteArray()!!.asImageBitmap(),
|
|
||||||
contentDescription = "Dish Image",
|
|
||||||
Modifier.width(150.dp)
|
|
||||||
)
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
Image(
|
|
||||||
Icons.Filled.Warning,
|
|
||||||
contentDescription = "Dish Image",
|
|
||||||
Modifier.width(150.dp)
|
|
||||||
)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
Column {
|
|
||||||
Text(dish.name, fontFamily=textFont,
|
|
||||||
fontSize=15.sp, textAlign=TextAlign.Center )
|
|
||||||
Text(
|
|
||||||
dish.description, fontFamily=textFont,
|
|
||||||
fontSize = 12.sp,
|
|
||||||
softWrap = true,
|
|
||||||
overflow = TextOverflow.Ellipsis,
|
|
||||||
maxLines = 3)
|
|
||||||
}
|
|
||||||
Column(
|
|
||||||
Modifier
|
|
||||||
.clickable {
|
|
||||||
scope.launch {
|
|
||||||
if (favoriteDishes.contains(dish)) {
|
|
||||||
AppDatabase
|
|
||||||
.getInstance(context)
|
|
||||||
.userFavoritesDao()
|
|
||||||
.delete(
|
|
||||||
UserFavorites(someUser!!, dish.uid!!)
|
|
||||||
).run { favoriteDishes.clear() }
|
|
||||||
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
AppDatabase
|
|
||||||
.getInstance(context)
|
|
||||||
.userFavoritesDao()
|
|
||||||
.insert(
|
|
||||||
UserFavorites(someUser!!, dish.uid!!)
|
|
||||||
).run { favoriteDishes.clear() }
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
.padding(horizontal = 5.dp)
|
|
||||||
) {
|
|
||||||
if (favoriteDishes.contains(dish)) {
|
|
||||||
Icon(Icons.Filled.Favorite, contentDescription = "")
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
Icon(Icons.Filled.FavoriteBorder, contentDescription = "")
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
@RequiresApi(Build.VERSION_CODES.Q)
|
|
||||||
@Preview
|
|
||||||
@Composable
|
|
||||||
fun ListDishes() {
|
|
||||||
MyApplicationTheme {
|
|
||||||
Surface(
|
|
||||||
color = MaterialTheme.colorScheme.background
|
|
||||||
) {
|
|
||||||
DishList(navController = null, onlyFavorites = false)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
@ -0,0 +1,14 @@
|
|||||||
|
package com.example.myapplication
|
||||||
|
|
||||||
|
import android.app.Application
|
||||||
|
import com.example.myapplication.database.AppContainer
|
||||||
|
import com.example.myapplication.database.AppDataContainer
|
||||||
|
|
||||||
|
class FoodWarriorsApplication : Application() {
|
||||||
|
lateinit var container: AppContainer
|
||||||
|
|
||||||
|
override fun onCreate() {
|
||||||
|
super.onCreate()
|
||||||
|
container = AppDataContainer(this)
|
||||||
|
}
|
||||||
|
}
|
@ -0,0 +1,42 @@
|
|||||||
|
package com.example.myapplication.database
|
||||||
|
|
||||||
|
import android.content.Context
|
||||||
|
import com.example.myapplication.database.repository.CategoryRepository
|
||||||
|
import com.example.myapplication.database.repository.DishRepository
|
||||||
|
import com.example.myapplication.database.repository.OfflineCategoryRepository
|
||||||
|
import com.example.myapplication.database.repository.OfflineDishRepository
|
||||||
|
import com.example.myapplication.database.repository.OfflineUserFavoritesRepository
|
||||||
|
import com.example.myapplication.database.repository.OfflineUserRepository
|
||||||
|
import com.example.myapplication.database.repository.UserRepository
|
||||||
|
import com.example.myapplication.database.repository.UserWithFavoritesRepository
|
||||||
|
|
||||||
|
|
||||||
|
interface AppContainer {
|
||||||
|
val userRepository : UserRepository
|
||||||
|
val dishRepository : DishRepository
|
||||||
|
val categoryRepository : CategoryRepository
|
||||||
|
val userFavoritesRepository: UserWithFavoritesRepository
|
||||||
|
}
|
||||||
|
|
||||||
|
class AppDataContainer(private val context: Context) : AppContainer {
|
||||||
|
|
||||||
|
override val userRepository: UserRepository by lazy {
|
||||||
|
OfflineUserRepository(AppDatabase.getInstance(context).userDao())
|
||||||
|
}
|
||||||
|
|
||||||
|
override val dishRepository: DishRepository by lazy {
|
||||||
|
OfflineDishRepository(AppDatabase.getInstance(context).dishDao())
|
||||||
|
}
|
||||||
|
|
||||||
|
override val categoryRepository: CategoryRepository by lazy {
|
||||||
|
OfflineCategoryRepository(AppDatabase.getInstance(context).categoryDao())
|
||||||
|
}
|
||||||
|
|
||||||
|
override val userFavoritesRepository: UserWithFavoritesRepository by lazy {
|
||||||
|
OfflineUserFavoritesRepository(AppDatabase.getInstance(context).userFavoritesDao())
|
||||||
|
}
|
||||||
|
|
||||||
|
companion object {
|
||||||
|
const val TIMEOUT = 5000L
|
||||||
|
}
|
||||||
|
}
|
@ -5,15 +5,14 @@ import androidx.room.Database
|
|||||||
import androidx.room.Room
|
import androidx.room.Room
|
||||||
import androidx.room.RoomDatabase
|
import androidx.room.RoomDatabase
|
||||||
import androidx.sqlite.db.SupportSQLiteDatabase
|
import androidx.sqlite.db.SupportSQLiteDatabase
|
||||||
import com.example.myapplication.Dishes.Model.Category
|
import com.example.myapplication.database.model.Category
|
||||||
import com.example.myapplication.Dishes.Model.Dish
|
import com.example.myapplication.database.model.Dish
|
||||||
import com.example.myapplication.Dishes.dao.CategoryDao
|
import com.example.myapplication.database.dao.CategoryDao
|
||||||
import com.example.myapplication.Dishes.dao.DishDao
|
import com.example.myapplication.database.dao.DishDao
|
||||||
import com.example.myapplication.User.Model.User
|
import com.example.myapplication.database.model.User
|
||||||
import com.example.myapplication.User.Model.UserFavorites
|
import com.example.myapplication.database.model.UserFavorites
|
||||||
import com.example.myapplication.User.Model.UserWithFavorites
|
import com.example.myapplication.database.dao.UserDao
|
||||||
import com.example.myapplication.User.dao.UserDao
|
import com.example.myapplication.database.dao.UserFavoritesDao
|
||||||
import com.example.myapplication.User.dao.UserFavoritesDao
|
|
||||||
import kotlinx.coroutines.CoroutineScope
|
import kotlinx.coroutines.CoroutineScope
|
||||||
import kotlinx.coroutines.Dispatchers
|
import kotlinx.coroutines.Dispatchers
|
||||||
import kotlinx.coroutines.launch
|
import kotlinx.coroutines.launch
|
||||||
|
@ -1,16 +1,17 @@
|
|||||||
package com.example.myapplication.Dishes.dao
|
package com.example.myapplication.database.dao
|
||||||
|
|
||||||
import androidx.room.Dao
|
import androidx.room.Dao
|
||||||
import androidx.room.Delete
|
import androidx.room.Delete
|
||||||
import androidx.room.Insert
|
import androidx.room.Insert
|
||||||
import androidx.room.Query
|
import androidx.room.Query
|
||||||
import androidx.room.Update
|
import androidx.room.Update
|
||||||
import com.example.myapplication.Dishes.Model.Category
|
import com.example.myapplication.database.model.Category
|
||||||
|
import kotlinx.coroutines.flow.Flow
|
||||||
|
|
||||||
@Dao
|
@Dao
|
||||||
interface CategoryDao {
|
interface CategoryDao {
|
||||||
@Query("select * from categories order by category_name collate nocase asc")
|
@Query("select * from categories order by category_name collate nocase asc")
|
||||||
fun getAll(): List<Category>
|
fun getAll(): Flow<List<Category>>
|
||||||
|
|
||||||
@Insert
|
@Insert
|
||||||
suspend fun insert(category: Category)
|
suspend fun insert(category: Category)
|
@ -1,12 +1,12 @@
|
|||||||
package com.example.myapplication.Dishes.dao
|
package com.example.myapplication.database.dao
|
||||||
|
|
||||||
import androidx.room.Dao
|
import androidx.room.Dao
|
||||||
import androidx.room.Delete
|
import androidx.room.Delete
|
||||||
import androidx.room.Insert
|
import androidx.room.Insert
|
||||||
import androidx.room.Query
|
import androidx.room.Query
|
||||||
import androidx.room.Update
|
import androidx.room.Update
|
||||||
import com.example.myapplication.Dishes.Model.Dish
|
import com.example.myapplication.database.model.Dish
|
||||||
import com.example.myapplication.Dishes.Model.DishWithCategoryAndUser
|
import com.example.myapplication.database.model.DishWithCategoryAndUser
|
||||||
import kotlinx.coroutines.flow.Flow
|
import kotlinx.coroutines.flow.Flow
|
||||||
|
|
||||||
@Dao
|
@Dao
|
||||||
@ -16,7 +16,7 @@ interface DishDao {
|
|||||||
|
|
||||||
@Query("select * from dishes left join categories on dishes.category_id = categories.category_id " +
|
@Query("select * from dishes left join categories on dishes.category_id = categories.category_id " +
|
||||||
"left join users on dishes.user_id = users.user_id where dishes.dish_id = :uid")
|
"left join users on dishes.user_id = users.user_id where dishes.dish_id = :uid")
|
||||||
suspend fun getByUid(uid: Int): DishWithCategoryAndUser
|
fun getByUid(uid: Int): Flow<DishWithCategoryAndUser?>
|
||||||
|
|
||||||
@Query("select * from dishes where dishes.user_id = :uid")
|
@Query("select * from dishes where dishes.user_id = :uid")
|
||||||
fun getAllOFUser(uid: Int): Flow<List<Dish>>
|
fun getAllOFUser(uid: Int): Flow<List<Dish>>
|
@ -1,13 +1,12 @@
|
|||||||
package com.example.myapplication.User.dao
|
package com.example.myapplication.database.dao
|
||||||
|
|
||||||
import androidx.room.Dao
|
import androidx.room.Dao
|
||||||
import androidx.room.Delete
|
import androidx.room.Delete
|
||||||
import androidx.room.Insert
|
import androidx.room.Insert
|
||||||
import androidx.room.Query
|
import androidx.room.Query
|
||||||
import androidx.room.Update
|
import androidx.room.Update
|
||||||
import com.example.myapplication.Dishes.Model.Dish
|
import com.example.myapplication.database.model.User
|
||||||
import com.example.myapplication.User.Model.User
|
import com.example.myapplication.database.model.UserWithFavorites
|
||||||
import com.example.myapplication.User.Model.UserWithFavorites
|
|
||||||
import kotlinx.coroutines.flow.Flow
|
import kotlinx.coroutines.flow.Flow
|
||||||
|
|
||||||
@Dao
|
@Dao
|
||||||
@ -16,7 +15,7 @@ interface UserDao {
|
|||||||
fun getAll(): Flow<List<User>>
|
fun getAll(): Flow<List<User>>
|
||||||
|
|
||||||
@Query("select * from users where users.user_id = :uid")
|
@Query("select * from users where users.user_id = :uid")
|
||||||
suspend fun getByUid(uid: Int): User
|
fun getByUid(uid: Int): Flow<User?>
|
||||||
|
|
||||||
|
|
||||||
@Query("select * from user_favorites left join users on user_favorites.user_id = users.user_id " +
|
@Query("select * from user_favorites left join users on user_favorites.user_id = users.user_id " +
|
@ -1,4 +1,4 @@
|
|||||||
package com.example.myapplication.User.dao
|
package com.example.myapplication.database.dao
|
||||||
|
|
||||||
import androidx.room.Dao
|
import androidx.room.Dao
|
||||||
import androidx.room.Delete
|
import androidx.room.Delete
|
||||||
@ -6,9 +6,9 @@ import androidx.room.Insert
|
|||||||
import androidx.room.Query
|
import androidx.room.Query
|
||||||
import androidx.room.Transaction
|
import androidx.room.Transaction
|
||||||
import androidx.room.Update
|
import androidx.room.Update
|
||||||
import com.example.myapplication.Dishes.Model.Dish
|
import com.example.myapplication.database.model.Dish
|
||||||
import com.example.myapplication.User.Model.User
|
import com.example.myapplication.database.model.User
|
||||||
import com.example.myapplication.User.Model.UserFavorites
|
import com.example.myapplication.database.model.UserFavorites
|
||||||
import kotlinx.coroutines.flow.Flow
|
import kotlinx.coroutines.flow.Flow
|
||||||
|
|
||||||
@Dao
|
@Dao
|
||||||
@ -29,4 +29,8 @@ interface UserFavoritesDao {
|
|||||||
@Transaction
|
@Transaction
|
||||||
@Query("SELECT * FROM user_favorites us JOIN dishes d ON d.dish_id = us.dish_id WHERE us.user_id = :uid")
|
@Query("SELECT * FROM user_favorites us JOIN dishes d ON d.dish_id = us.dish_id WHERE us.user_id = :uid")
|
||||||
fun getUserFavorites(uid: Int?): Flow<List<Dish>>
|
fun getUserFavorites(uid: Int?): Flow<List<Dish>>
|
||||||
|
|
||||||
|
@Transaction
|
||||||
|
@Query("SELECT * FROM user_favorites us WHERE us.user_id = :userUid AND us.dish_id = :dishUid")
|
||||||
|
fun getUserFavorite(userUid: Int?, dishUid: Int?): Flow<UserFavorites?>
|
||||||
}
|
}
|
@ -1,4 +1,4 @@
|
|||||||
package com.example.myapplication.Dishes.Model
|
package com.example.myapplication.database.model
|
||||||
|
|
||||||
import androidx.room.ColumnInfo
|
import androidx.room.ColumnInfo
|
||||||
import androidx.room.Entity
|
import androidx.room.Entity
|
@ -1,4 +1,4 @@
|
|||||||
package com.example.myapplication.Dishes.Model
|
package com.example.myapplication.database.model
|
||||||
|
|
||||||
import android.graphics.Bitmap
|
import android.graphics.Bitmap
|
||||||
import android.graphics.BitmapFactory
|
import android.graphics.BitmapFactory
|
||||||
@ -7,9 +7,6 @@ import androidx.room.Entity
|
|||||||
import androidx.room.ForeignKey
|
import androidx.room.ForeignKey
|
||||||
import androidx.room.Ignore
|
import androidx.room.Ignore
|
||||||
import androidx.room.PrimaryKey
|
import androidx.room.PrimaryKey
|
||||||
import com.example.myapplication.R
|
|
||||||
import com.example.myapplication.User.Model.User
|
|
||||||
import java.io.Serializable
|
|
||||||
|
|
||||||
//data class Dish (
|
//data class Dish (
|
||||||
// val name: String,
|
// val name: String,
|
@ -1,4 +1,4 @@
|
|||||||
package com.example.myapplication.Dishes.Model
|
package com.example.myapplication.database.model
|
||||||
|
|
||||||
import androidx.room.ColumnInfo
|
import androidx.room.ColumnInfo
|
||||||
import androidx.room.Embedded
|
import androidx.room.Embedded
|
@ -1,8 +1,7 @@
|
|||||||
package com.example.myapplication.User.Model
|
package com.example.myapplication.database.model
|
||||||
|
|
||||||
import androidx.room.ColumnInfo
|
import androidx.room.ColumnInfo
|
||||||
import androidx.room.Entity
|
import androidx.room.Entity
|
||||||
import androidx.room.Ignore
|
|
||||||
import androidx.room.PrimaryKey
|
import androidx.room.PrimaryKey
|
||||||
|
|
||||||
//data class User (
|
//data class User (
|
@ -1,11 +1,8 @@
|
|||||||
package com.example.myapplication.User.Model;
|
package com.example.myapplication.database.model;
|
||||||
|
|
||||||
import androidx.room.ColumnInfo
|
import androidx.room.ColumnInfo
|
||||||
import androidx.room.Entity;
|
import androidx.room.Entity;
|
||||||
import androidx.room.ForeignKey
|
|
||||||
import androidx.room.Ignore
|
import androidx.room.Ignore
|
||||||
import androidx.room.PrimaryKey
|
|
||||||
import com.example.myapplication.Dishes.Model.Dish
|
|
||||||
|
|
||||||
@Entity(tableName = "user_favorites", primaryKeys = ["user_id", "dish_id"])
|
@Entity(tableName = "user_favorites", primaryKeys = ["user_id", "dish_id"])
|
||||||
data class UserFavorites(
|
data class UserFavorites(
|
@ -1,13 +1,8 @@
|
|||||||
package com.example.myapplication.User.Model
|
package com.example.myapplication.database.model
|
||||||
|
|
||||||
import androidx.room.ColumnInfo
|
|
||||||
import androidx.room.Embedded
|
import androidx.room.Embedded
|
||||||
import androidx.room.Entity
|
|
||||||
import androidx.room.Ignore
|
|
||||||
import androidx.room.Junction
|
import androidx.room.Junction
|
||||||
import androidx.room.PrimaryKey
|
|
||||||
import androidx.room.Relation
|
import androidx.room.Relation
|
||||||
import com.example.myapplication.Dishes.Model.Dish
|
|
||||||
|
|
||||||
data class FavoriteWithUsers(
|
data class FavoriteWithUsers(
|
||||||
@Embedded
|
@Embedded
|
@ -0,0 +1,8 @@
|
|||||||
|
package com.example.myapplication.database.repository
|
||||||
|
|
||||||
|
import com.example.myapplication.database.model.Category
|
||||||
|
import kotlinx.coroutines.flow.Flow
|
||||||
|
|
||||||
|
interface CategoryRepository {
|
||||||
|
fun getAllCategories(): Flow<List<Category>>
|
||||||
|
}
|
@ -0,0 +1,15 @@
|
|||||||
|
package com.example.myapplication.database.repository
|
||||||
|
|
||||||
|
import com.example.myapplication.database.model.Dish
|
||||||
|
import com.example.myapplication.database.model.DishWithCategoryAndUser
|
||||||
|
import kotlinx.coroutines.flow.Flow
|
||||||
|
|
||||||
|
interface DishRepository {
|
||||||
|
fun getAllDishes(): Flow<List<Dish>>
|
||||||
|
fun getDish(uid: Int): Flow<DishWithCategoryAndUser?>
|
||||||
|
|
||||||
|
fun getUserDishes(userUid: Int) : Flow<List<Dish>>
|
||||||
|
suspend fun insertDish(dish: Dish)
|
||||||
|
suspend fun updateDish(dish: Dish)
|
||||||
|
suspend fun deleteDish(dish: Dish)
|
||||||
|
}
|
@ -0,0 +1,11 @@
|
|||||||
|
package com.example.myapplication.database.repository
|
||||||
|
|
||||||
|
import com.example.myapplication.database.dao.CategoryDao
|
||||||
|
import com.example.myapplication.database.model.Category
|
||||||
|
import kotlinx.coroutines.flow.Flow
|
||||||
|
|
||||||
|
class OfflineCategoryRepository(private val categoryDao: CategoryDao) : CategoryRepository {
|
||||||
|
override fun getAllCategories(): Flow<List<Category>> {
|
||||||
|
return categoryDao.getAll();
|
||||||
|
}
|
||||||
|
}
|
@ -0,0 +1,32 @@
|
|||||||
|
package com.example.myapplication.database.repository
|
||||||
|
|
||||||
|
import com.example.myapplication.database.dao.DishDao
|
||||||
|
import com.example.myapplication.database.model.Dish
|
||||||
|
import com.example.myapplication.database.model.DishWithCategoryAndUser
|
||||||
|
import kotlinx.coroutines.flow.Flow
|
||||||
|
|
||||||
|
class OfflineDishRepository(private val dishDao: DishDao) : DishRepository {
|
||||||
|
override fun getAllDishes(): Flow<List<Dish>> {
|
||||||
|
return dishDao.getAll()
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun getDish(uid: Int): Flow<DishWithCategoryAndUser?> {
|
||||||
|
return dishDao.getByUid(uid)
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun getUserDishes(userUid: Int): Flow<List<Dish>> {
|
||||||
|
return dishDao.getAllOFUser(userUid);
|
||||||
|
}
|
||||||
|
|
||||||
|
override suspend fun insertDish(dish: Dish) {
|
||||||
|
dishDao.insert(dish)
|
||||||
|
}
|
||||||
|
|
||||||
|
override suspend fun updateDish(dish: Dish) {
|
||||||
|
dishDao.update(dish)
|
||||||
|
}
|
||||||
|
|
||||||
|
override suspend fun deleteDish(dish: Dish) {
|
||||||
|
dishDao.delete(dish)
|
||||||
|
}
|
||||||
|
}
|
@ -0,0 +1,24 @@
|
|||||||
|
package com.example.myapplication.database.repository
|
||||||
|
|
||||||
|
import com.example.myapplication.database.dao.UserFavoritesDao
|
||||||
|
import com.example.myapplication.database.model.Dish
|
||||||
|
import com.example.myapplication.database.model.UserFavorites
|
||||||
|
import kotlinx.coroutines.flow.Flow
|
||||||
|
|
||||||
|
class OfflineUserFavoritesRepository(private val userFavoritesDao: UserFavoritesDao) : UserWithFavoritesRepository {
|
||||||
|
override fun getUserFavorites(userUid: Int): Flow<List<Dish>> {
|
||||||
|
return userFavoritesDao.getUserFavorites(userUid)
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun getUserFavorite(userUid: Int, dishUid: Int): Flow<UserFavorites?> {
|
||||||
|
return userFavoritesDao.getUserFavorite(userUid, dishUid)
|
||||||
|
}
|
||||||
|
|
||||||
|
override suspend fun deleteUserFavorites(userUid: Int, dishUid: Int) {
|
||||||
|
userFavoritesDao.delete(UserFavorites(userUid, dishUid))
|
||||||
|
}
|
||||||
|
|
||||||
|
override suspend fun insertUserFavorites(userUid: Int, dishUid: Int) {
|
||||||
|
userFavoritesDao.insert(UserFavorites(userUid, dishUid))
|
||||||
|
}
|
||||||
|
}
|
@ -0,0 +1,27 @@
|
|||||||
|
package com.example.myapplication.database.repository
|
||||||
|
|
||||||
|
import com.example.myapplication.database.dao.UserDao
|
||||||
|
import com.example.myapplication.database.model.User
|
||||||
|
import kotlinx.coroutines.flow.Flow
|
||||||
|
|
||||||
|
class OfflineUserRepository(private val userDao: UserDao) : UserRepository {
|
||||||
|
override fun getAllUsers(): Flow<List<User>> {
|
||||||
|
return userDao.getAll()
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun getUser(uid: Int): Flow<User?> {
|
||||||
|
return userDao.getByUid(uid)
|
||||||
|
}
|
||||||
|
|
||||||
|
override suspend fun insertUser(user: User) {
|
||||||
|
userDao.insert(user)
|
||||||
|
}
|
||||||
|
|
||||||
|
override suspend fun updateUser(user: User) {
|
||||||
|
userDao.update(user)
|
||||||
|
}
|
||||||
|
|
||||||
|
override suspend fun deleteUser(user: User) {
|
||||||
|
userDao.delete(user)
|
||||||
|
}
|
||||||
|
}
|
@ -0,0 +1,12 @@
|
|||||||
|
package com.example.myapplication.database.repository
|
||||||
|
|
||||||
|
import com.example.myapplication.database.model.User
|
||||||
|
import kotlinx.coroutines.flow.Flow
|
||||||
|
|
||||||
|
interface UserRepository {
|
||||||
|
fun getAllUsers(): Flow<List<User>>
|
||||||
|
fun getUser(uid: Int): Flow<User?>
|
||||||
|
suspend fun insertUser(user: User)
|
||||||
|
suspend fun updateUser(user: User)
|
||||||
|
suspend fun deleteUser(user: User)
|
||||||
|
}
|
@ -0,0 +1,15 @@
|
|||||||
|
package com.example.myapplication.database.repository
|
||||||
|
|
||||||
|
import com.example.myapplication.database.model.Dish
|
||||||
|
import com.example.myapplication.database.model.UserFavorites
|
||||||
|
import kotlinx.coroutines.flow.Flow
|
||||||
|
|
||||||
|
interface UserWithFavoritesRepository {
|
||||||
|
fun getUserFavorites(userUid: Int): Flow<List<Dish>>
|
||||||
|
|
||||||
|
fun getUserFavorite(userUid: Int, dishUid: Int): Flow<UserFavorites?>
|
||||||
|
|
||||||
|
suspend fun deleteUserFavorites(userUid: Int, dishUid: Int)
|
||||||
|
|
||||||
|
suspend fun insertUserFavorites(userUid: Int, dishUid: Int)
|
||||||
|
}
|
@ -0,0 +1,208 @@
|
|||||||
|
package com.example.myapplication.ui.dishes.list
|
||||||
|
|
||||||
|
import android.os.Build
|
||||||
|
import androidx.annotation.RequiresApi
|
||||||
|
import androidx.compose.foundation.Image
|
||||||
|
import androidx.compose.foundation.ScrollState
|
||||||
|
import androidx.compose.foundation.clickable
|
||||||
|
import androidx.compose.foundation.layout.Arrangement
|
||||||
|
import androidx.compose.foundation.layout.Column
|
||||||
|
import androidx.compose.foundation.layout.Row
|
||||||
|
import androidx.compose.foundation.layout.fillMaxSize
|
||||||
|
import androidx.compose.foundation.layout.fillMaxWidth
|
||||||
|
import androidx.compose.foundation.layout.padding
|
||||||
|
import androidx.compose.foundation.layout.width
|
||||||
|
import androidx.compose.foundation.verticalScroll
|
||||||
|
import androidx.compose.material.icons.Icons
|
||||||
|
import androidx.compose.material.icons.filled.Favorite
|
||||||
|
import androidx.compose.material.icons.filled.FavoriteBorder
|
||||||
|
import androidx.compose.material.icons.filled.Warning
|
||||||
|
import androidx.compose.material3.ExperimentalMaterial3Api
|
||||||
|
import androidx.compose.material3.Icon
|
||||||
|
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.runtime.LaunchedEffect
|
||||||
|
import androidx.compose.runtime.collectAsState
|
||||||
|
import androidx.compose.runtime.getValue
|
||||||
|
import androidx.compose.runtime.mutableStateListOf
|
||||||
|
import androidx.compose.runtime.remember
|
||||||
|
import androidx.compose.runtime.rememberCoroutineScope
|
||||||
|
import androidx.compose.ui.Modifier
|
||||||
|
import androidx.compose.ui.graphics.asImageBitmap
|
||||||
|
import androidx.compose.ui.platform.LocalContext
|
||||||
|
import androidx.compose.ui.res.stringResource
|
||||||
|
import androidx.compose.ui.text.style.TextAlign
|
||||||
|
import androidx.compose.ui.text.style.TextOverflow
|
||||||
|
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 androidx.navigation.NavController
|
||||||
|
import com.example.myapplication.AppViewModelProvider
|
||||||
|
import com.example.myapplication.database.model.Dish
|
||||||
|
import com.example.myapplication.R
|
||||||
|
import com.example.myapplication.database.model.UserFavorites
|
||||||
|
import com.example.myapplication.database.AppDatabase
|
||||||
|
import com.example.myapplication.database.model.User
|
||||||
|
import com.example.myapplication.ui.extra.ErrorElement
|
||||||
|
import com.example.myapplication.ui.extra.ErrorsType
|
||||||
|
import com.example.myapplication.ui.navigation.Screen
|
||||||
|
import com.example.myapplication.ui.theme.MyApplicationTheme
|
||||||
|
import com.example.myapplication.ui.theme.textFont
|
||||||
|
import kotlinx.coroutines.Dispatchers
|
||||||
|
import kotlinx.coroutines.launch
|
||||||
|
import kotlinx.coroutines.withContext
|
||||||
|
|
||||||
|
@OptIn(ExperimentalMaterial3Api::class)
|
||||||
|
@RequiresApi(Build.VERSION_CODES.Q)
|
||||||
|
@Composable
|
||||||
|
fun DishList(
|
||||||
|
navController: NavController,
|
||||||
|
viewModel: DishListViewModel = viewModel(factory = AppViewModelProvider.Factory),
|
||||||
|
typeDishList: TypeDishList = TypeDishList.AllDishes,
|
||||||
|
userUid: Int?
|
||||||
|
) {
|
||||||
|
val coroutineScope = rememberCoroutineScope()
|
||||||
|
val dishListUiState by viewModel.dishListUiState.collectAsState()
|
||||||
|
val userDishes by viewModel.userDishes(userUid ?: 0).collectAsState()
|
||||||
|
val favorites by viewModel.dishFavorites(userUid ?: 0).collectAsState()
|
||||||
|
Scaffold(
|
||||||
|
) { innerPadding ->
|
||||||
|
if (typeDishList != TypeDishList.AllDishes && userUid == null) {
|
||||||
|
ErrorElement(navController = navController, typeErrorsType = ErrorsType.NOT_AUTH)
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
DishList(
|
||||||
|
modifier = Modifier
|
||||||
|
.padding(innerPadding)
|
||||||
|
.fillMaxSize()
|
||||||
|
.verticalScroll(ScrollState(0)),
|
||||||
|
typeDishList = typeDishList,
|
||||||
|
dishList = when (typeDishList) {
|
||||||
|
TypeDishList.AllDishes -> dishListUiState.dishList
|
||||||
|
TypeDishList.FavoritesDishes -> favorites.dishList
|
||||||
|
TypeDishList.UserDishes -> userDishes.dishList
|
||||||
|
else -> dishListUiState.dishList
|
||||||
|
},
|
||||||
|
favorites = favorites.dishList,
|
||||||
|
addToFavorites = {uid: Int ->
|
||||||
|
if (userUid != null) {
|
||||||
|
coroutineScope.launch {
|
||||||
|
viewModel.addFavoritesToUser(userUid, uid)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
onClick = {uid: Int ->
|
||||||
|
val route = Screen.DishView.route.replace("{id}", uid.toString())
|
||||||
|
navController.navigate(route)
|
||||||
|
}
|
||||||
|
)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@RequiresApi(Build.VERSION_CODES.Q)
|
||||||
|
@Composable
|
||||||
|
private fun DishList(
|
||||||
|
modifier: Modifier = Modifier,
|
||||||
|
typeDishList: TypeDishList,
|
||||||
|
dishList: List<Dish>,
|
||||||
|
favorites: List<Dish>,
|
||||||
|
addToFavorites: (uid : Int) -> Unit,
|
||||||
|
onClick: (uid : Int) -> Unit
|
||||||
|
) {
|
||||||
|
Column(
|
||||||
|
modifier
|
||||||
|
) {
|
||||||
|
Row(horizontalArrangement = Arrangement.Center, modifier = Modifier.fillMaxWidth()) {
|
||||||
|
Column {
|
||||||
|
val text: String = when (typeDishList) {
|
||||||
|
TypeDishList.AllDishes -> stringResource(R.string.all_dishes)
|
||||||
|
TypeDishList.FavoritesDishes -> stringResource(id = R.string.favorite_dishes)
|
||||||
|
TypeDishList.UserDishes -> stringResource(id = R.string.user_dishes)
|
||||||
|
else -> ""
|
||||||
|
}
|
||||||
|
|
||||||
|
Text(text, fontFamily= textFont,
|
||||||
|
fontSize=26.sp, textAlign = TextAlign.Start)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
dishList.forEachIndexed() {index, dish ->
|
||||||
|
DishListItem(index=index, dish = dish, favorites = favorites, addToFavorites, onClick = onClick)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@RequiresApi(Build.VERSION_CODES.Q)
|
||||||
|
@Composable
|
||||||
|
private fun DishListItem(
|
||||||
|
index: Int,
|
||||||
|
dish: Dish,
|
||||||
|
favorites: List<Dish>,
|
||||||
|
addToFavorites: (uid : Int) -> Unit,
|
||||||
|
onClick: (uid: Int) -> Unit
|
||||||
|
) {
|
||||||
|
Row(
|
||||||
|
Modifier
|
||||||
|
.padding(vertical = 5.dp)
|
||||||
|
.fillMaxSize()
|
||||||
|
.clickable {
|
||||||
|
onClick(dish.uid!!)
|
||||||
|
}) {
|
||||||
|
|
||||||
|
Column() {
|
||||||
|
if (dish.image != null) { // TODO Image input check
|
||||||
|
Image(
|
||||||
|
bitmap = dish.getBitmapFromByteArray()!!.asImageBitmap(),
|
||||||
|
contentDescription = "Dish Image",
|
||||||
|
Modifier.width(150.dp)
|
||||||
|
)
|
||||||
|
} else {
|
||||||
|
Image(
|
||||||
|
Icons.Filled.Warning,
|
||||||
|
contentDescription = "Dish Image",
|
||||||
|
Modifier.width(150.dp)
|
||||||
|
)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
Column {
|
||||||
|
Text(
|
||||||
|
dish.name, fontFamily = textFont,
|
||||||
|
fontSize = 15.sp, textAlign = TextAlign.Center
|
||||||
|
)
|
||||||
|
Text(
|
||||||
|
dish.description, fontFamily = textFont,
|
||||||
|
fontSize = 12.sp,
|
||||||
|
softWrap = true,
|
||||||
|
overflow = TextOverflow.Ellipsis,
|
||||||
|
maxLines = 3
|
||||||
|
)
|
||||||
|
}
|
||||||
|
Column(
|
||||||
|
Modifier.clickable { addToFavorites(dish.uid!!) }
|
||||||
|
) {
|
||||||
|
if (favorites.contains(dish)) {
|
||||||
|
Icon(Icons.Filled.Favorite, contentDescription = "")
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
Icon(Icons.Filled.FavoriteBorder, contentDescription = "")
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@RequiresApi(Build.VERSION_CODES.Q)
|
||||||
|
@Preview
|
||||||
|
@Composable
|
||||||
|
fun ListDishes() {
|
||||||
|
// MyApplicationTheme {
|
||||||
|
// Surface(
|
||||||
|
// color = MaterialTheme.colorScheme.background
|
||||||
|
// ) {
|
||||||
|
// DishList(navController = null, onlyFavorites = false)
|
||||||
|
// }
|
||||||
|
// }
|
||||||
|
}
|
@ -0,0 +1,69 @@
|
|||||||
|
package com.example.myapplication.ui.dishes.list
|
||||||
|
|
||||||
|
import androidx.lifecycle.ViewModel
|
||||||
|
import androidx.lifecycle.viewModelScope
|
||||||
|
import com.example.myapplication.database.AppDataContainer
|
||||||
|
import com.example.myapplication.database.model.Dish
|
||||||
|
import com.example.myapplication.database.repository.DishRepository
|
||||||
|
import com.example.myapplication.database.repository.UserWithFavoritesRepository
|
||||||
|
import kotlinx.coroutines.flow.SharingStarted
|
||||||
|
import kotlinx.coroutines.flow.StateFlow
|
||||||
|
import kotlinx.coroutines.flow.collect
|
||||||
|
import kotlinx.coroutines.flow.map
|
||||||
|
import kotlinx.coroutines.flow.stateIn
|
||||||
|
|
||||||
|
enum class TypeDishList {
|
||||||
|
AllDishes,
|
||||||
|
FavoritesDishes,
|
||||||
|
UserDishes
|
||||||
|
}
|
||||||
|
class DishListViewModel(
|
||||||
|
private val dishRepository: DishRepository,
|
||||||
|
private val userWithFavoritesRepository: UserWithFavoritesRepository
|
||||||
|
) : ViewModel() {
|
||||||
|
val dishListUiState: StateFlow<DishListUiState> = dishRepository.getAllDishes().map {
|
||||||
|
DishListUiState(it)
|
||||||
|
}.stateIn(
|
||||||
|
scope = viewModelScope,
|
||||||
|
started = SharingStarted.WhileSubscribed(stopTimeoutMillis = AppDataContainer.TIMEOUT),
|
||||||
|
initialValue = DishListUiState()
|
||||||
|
)
|
||||||
|
|
||||||
|
fun dishFavorites(userUid: Int) : StateFlow<DishListUiState> {
|
||||||
|
return userWithFavoritesRepository.getUserFavorites(userUid).map {
|
||||||
|
DishListUiState(it)
|
||||||
|
}.stateIn(
|
||||||
|
scope = viewModelScope,
|
||||||
|
started = SharingStarted.WhileSubscribed(stopTimeoutMillis = AppDataContainer.TIMEOUT),
|
||||||
|
initialValue = DishListUiState()
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
|
fun userDishes(userUid: Int) : StateFlow<DishListUiState> {
|
||||||
|
return dishRepository.getUserDishes(userUid).map {
|
||||||
|
DishListUiState(it)
|
||||||
|
}.stateIn(
|
||||||
|
scope = viewModelScope,
|
||||||
|
started = SharingStarted.WhileSubscribed(stopTimeoutMillis = AppDataContainer.TIMEOUT),
|
||||||
|
initialValue = DishListUiState()
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
|
suspend fun addFavoritesToUser(userUid: Int, dishUid: Int) {
|
||||||
|
var flag = true;
|
||||||
|
userWithFavoritesRepository.getUserFavorite(userUid, dishUid).collect {
|
||||||
|
if (flag) {
|
||||||
|
if (it == null) {
|
||||||
|
flag = false
|
||||||
|
userWithFavoritesRepository.insertUserFavorites(userUid, dishUid)
|
||||||
|
} else {
|
||||||
|
flag = false
|
||||||
|
userWithFavoritesRepository.deleteUserFavorites(userUid, dishUid)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
data class DishListUiState(val dishList: List<Dish> = listOf())
|
@ -1,4 +1,4 @@
|
|||||||
package com.example.myapplication.Dishes.ui
|
package com.example.myapplication.ui.dishes
|
||||||
|
|
||||||
import android.os.Build
|
import android.os.Build
|
||||||
import androidx.annotation.RequiresApi
|
import androidx.annotation.RequiresApi
|
||||||
@ -10,59 +10,86 @@ import androidx.compose.foundation.layout.Row
|
|||||||
import androidx.compose.foundation.layout.fillMaxSize
|
import androidx.compose.foundation.layout.fillMaxSize
|
||||||
import androidx.compose.foundation.layout.fillMaxWidth
|
import androidx.compose.foundation.layout.fillMaxWidth
|
||||||
import androidx.compose.foundation.layout.padding
|
import androidx.compose.foundation.layout.padding
|
||||||
import androidx.compose.foundation.layout.width
|
|
||||||
import androidx.compose.foundation.verticalScroll
|
import androidx.compose.foundation.verticalScroll
|
||||||
import androidx.compose.material.icons.Icons
|
import androidx.compose.material3.ExperimentalMaterial3Api
|
||||||
import androidx.compose.material.icons.filled.Warning
|
|
||||||
import androidx.compose.material3.MaterialTheme
|
import androidx.compose.material3.MaterialTheme
|
||||||
|
import androidx.compose.material3.Scaffold
|
||||||
import androidx.compose.material3.Surface
|
import androidx.compose.material3.Surface
|
||||||
import androidx.compose.material3.Text
|
import androidx.compose.material3.Text
|
||||||
import androidx.compose.runtime.Composable
|
import androidx.compose.runtime.Composable
|
||||||
import androidx.compose.runtime.LaunchedEffect
|
import androidx.compose.runtime.LaunchedEffect
|
||||||
|
import androidx.compose.runtime.collectAsState
|
||||||
|
import androidx.compose.runtime.getValue
|
||||||
import androidx.compose.runtime.mutableStateOf
|
import androidx.compose.runtime.mutableStateOf
|
||||||
import androidx.compose.runtime.remember
|
import androidx.compose.runtime.remember
|
||||||
|
import androidx.compose.runtime.rememberCoroutineScope
|
||||||
import androidx.compose.ui.Modifier
|
import androidx.compose.ui.Modifier
|
||||||
import androidx.compose.ui.graphics.asImageBitmap
|
import androidx.compose.ui.graphics.asImageBitmap
|
||||||
import androidx.compose.ui.platform.LocalContext
|
import androidx.compose.ui.platform.LocalContext
|
||||||
import androidx.compose.ui.res.painterResource
|
import androidx.compose.ui.res.painterResource
|
||||||
import androidx.compose.ui.res.stringResource
|
|
||||||
import androidx.compose.ui.text.style.TextAlign
|
import androidx.compose.ui.text.style.TextAlign
|
||||||
import androidx.compose.ui.text.style.TextOverflow
|
import androidx.compose.ui.text.style.TextOverflow
|
||||||
import androidx.compose.ui.tooling.preview.Preview
|
import androidx.compose.ui.tooling.preview.Preview
|
||||||
import androidx.compose.ui.unit.dp
|
import androidx.compose.ui.unit.dp
|
||||||
import androidx.compose.ui.unit.sp
|
import androidx.compose.ui.unit.sp
|
||||||
import com.example.myapplication.Dishes.Model.Dish
|
import androidx.lifecycle.viewmodel.compose.viewModel
|
||||||
import com.example.myapplication.Dishes.Model.DishWithCategoryAndUser
|
import androidx.navigation.NavController
|
||||||
|
import com.example.myapplication.AppViewModelProvider
|
||||||
|
import com.example.myapplication.database.model.Dish
|
||||||
|
import com.example.myapplication.database.model.DishWithCategoryAndUser
|
||||||
import com.example.myapplication.R
|
import com.example.myapplication.R
|
||||||
import com.example.myapplication.database.AppDatabase
|
import com.example.myapplication.database.AppDatabase
|
||||||
|
import com.example.myapplication.ui.dishes.view.DishViewModel
|
||||||
|
import com.example.myapplication.ui.extra.ErrorElement
|
||||||
|
import com.example.myapplication.ui.extra.ErrorsType
|
||||||
//import com.example.myapplication.Dishes.Model.getAllDishes
|
//import com.example.myapplication.Dishes.Model.getAllDishes
|
||||||
import com.example.myapplication.ui.theme.MyApplicationTheme
|
import com.example.myapplication.ui.theme.MyApplicationTheme
|
||||||
import com.example.myapplication.ui.theme.textFont
|
import com.example.myapplication.ui.theme.textFont
|
||||||
|
import com.example.myapplication.ui.user.UserViewModel
|
||||||
import kotlinx.coroutines.Dispatchers
|
import kotlinx.coroutines.Dispatchers
|
||||||
import kotlinx.coroutines.withContext
|
import kotlinx.coroutines.withContext
|
||||||
|
|
||||||
@RequiresApi(Build.VERSION_CODES.Q)
|
@RequiresApi(Build.VERSION_CODES.Q)
|
||||||
|
@OptIn(ExperimentalMaterial3Api::class)
|
||||||
@Composable
|
@Composable
|
||||||
fun DishView(id: Int) {
|
fun DishView(navController: NavController,
|
||||||
var dish = remember { mutableStateOf(DishWithCategoryAndUser(
|
viewModel: DishViewModel = viewModel(factory = AppViewModelProvider.Factory),
|
||||||
Dish(0, "", "", null, null, null),
|
userUid: Int?,
|
||||||
null, null))
|
dishUid: Int?) {
|
||||||
|
val coroutineScope = rememberCoroutineScope()
|
||||||
|
val dishUiState by viewModel.getDish(dishUid ?: 0).collectAsState()
|
||||||
|
Scaffold(
|
||||||
|
|
||||||
|
){ innerPadding ->
|
||||||
|
if (dishUiState.dish == null) {
|
||||||
|
ErrorElement(navController = navController, typeErrorsType = ErrorsType.NOT_FOUND)
|
||||||
}
|
}
|
||||||
val context = LocalContext.current
|
else {
|
||||||
LaunchedEffect(Unit) {
|
DishView(
|
||||||
withContext(Dispatchers.IO) {
|
modifier = Modifier
|
||||||
dish.value = AppDatabase.getInstance(context).dishDao().getByUid(id)
|
.padding(innerPadding)
|
||||||
|
.fillMaxSize(),
|
||||||
|
dish = dishUiState.dish!!
|
||||||
|
)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@RequiresApi(Build.VERSION_CODES.Q)
|
||||||
|
@Composable
|
||||||
|
private fun DishView(
|
||||||
|
modifier: Modifier,
|
||||||
|
dish : DishWithCategoryAndUser
|
||||||
|
) {
|
||||||
Column(
|
Column(
|
||||||
Modifier
|
Modifier
|
||||||
.fillMaxWidth()
|
.fillMaxWidth()
|
||||||
.padding(vertical = 5.dp, horizontal = 10.dp)
|
.padding(vertical = 5.dp, horizontal = 10.dp)
|
||||||
.verticalScroll(ScrollState(0))) {
|
.verticalScroll(ScrollState(0))) {
|
||||||
Row(Modifier.padding(vertical = 5.dp)) {
|
Row(Modifier.padding(vertical = 5.dp)) {
|
||||||
if (dish.value.dish?.image != null) { // TODO Image input check
|
if (dish.dish?.image != null) {
|
||||||
Image(
|
Image(
|
||||||
bitmap = dish.value.dish!!.getBitmapFromByteArray()!!.asImageBitmap(),
|
bitmap = dish.dish.getBitmapFromByteArray()!!.asImageBitmap(),
|
||||||
contentDescription = "Dish Image",
|
contentDescription = "Dish Image",
|
||||||
Modifier.fillMaxSize()
|
Modifier.fillMaxSize()
|
||||||
)
|
)
|
||||||
@ -77,11 +104,11 @@ fun DishView(id: Int) {
|
|||||||
}
|
}
|
||||||
Row(horizontalArrangement = Arrangement.SpaceAround, modifier = Modifier.fillMaxWidth()) {
|
Row(horizontalArrangement = Arrangement.SpaceAround, modifier = Modifier.fillMaxWidth()) {
|
||||||
Column {
|
Column {
|
||||||
Text(dish.value.dish!!.name, fontFamily=textFont,
|
Text(dish.dish!!.name, fontFamily=textFont,
|
||||||
fontSize=15.sp, textAlign = TextAlign.Start)
|
fontSize=15.sp, textAlign = TextAlign.Start)
|
||||||
}
|
}
|
||||||
Column {
|
Column {
|
||||||
Text("@" + dish.value.nickname, fontFamily=textFont,
|
Text("@" + dish.nickname, fontFamily=textFont,
|
||||||
fontSize=15.sp, textAlign = TextAlign.End)
|
fontSize=15.sp, textAlign = TextAlign.End)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -89,9 +116,10 @@ fun DishView(id: Int) {
|
|||||||
.fillMaxSize()
|
.fillMaxSize()
|
||||||
.padding(
|
.padding(
|
||||||
horizontal = 30.dp, vertical = 10.dp
|
horizontal = 30.dp, vertical = 10.dp
|
||||||
)) {
|
)
|
||||||
|
) {
|
||||||
Text(
|
Text(
|
||||||
dish.value.dish!!.description,
|
dish.dish!!.description,
|
||||||
fontFamily=textFont,
|
fontFamily=textFont,
|
||||||
fontSize = 13.sp,
|
fontSize = 13.sp,
|
||||||
softWrap = true,
|
softWrap = true,
|
||||||
@ -100,16 +128,3 @@ fun DishView(id: Int) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@RequiresApi(Build.VERSION_CODES.Q)
|
|
||||||
@Preview
|
|
||||||
@Composable
|
|
||||||
fun DishPreview() {
|
|
||||||
MyApplicationTheme {
|
|
||||||
Surface(
|
|
||||||
color = MaterialTheme.colorScheme.background
|
|
||||||
) {
|
|
||||||
DishView(id = 0)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
@ -0,0 +1,29 @@
|
|||||||
|
package com.example.myapplication.ui.dishes.view
|
||||||
|
|
||||||
|
import androidx.lifecycle.ViewModel
|
||||||
|
import androidx.lifecycle.viewModelScope
|
||||||
|
import com.example.myapplication.database.AppDataContainer
|
||||||
|
import com.example.myapplication.database.model.Dish
|
||||||
|
import com.example.myapplication.database.model.DishWithCategoryAndUser
|
||||||
|
import com.example.myapplication.database.repository.DishRepository
|
||||||
|
import com.example.myapplication.ui.user.UserUiState
|
||||||
|
import kotlinx.coroutines.flow.SharingStarted
|
||||||
|
import kotlinx.coroutines.flow.StateFlow
|
||||||
|
import kotlinx.coroutines.flow.map
|
||||||
|
import kotlinx.coroutines.flow.stateIn
|
||||||
|
|
||||||
|
class DishViewModel(
|
||||||
|
private val dishRepository: DishRepository
|
||||||
|
) : ViewModel() {
|
||||||
|
fun getDish(uid: Int) : StateFlow<DishUiState> {
|
||||||
|
return dishRepository.getDish(uid).map {
|
||||||
|
DishUiState(it!!)
|
||||||
|
}.stateIn(
|
||||||
|
scope = viewModelScope,
|
||||||
|
started = SharingStarted.WhileSubscribed(stopTimeoutMillis = AppDataContainer.TIMEOUT),
|
||||||
|
initialValue = DishUiState()
|
||||||
|
)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
data class DishUiState(val dish: DishWithCategoryAndUser? = null)
|
@ -0,0 +1,43 @@
|
|||||||
|
package com.example.myapplication.ui.extra
|
||||||
|
|
||||||
|
import androidx.compose.foundation.ScrollState
|
||||||
|
import androidx.compose.foundation.layout.fillMaxSize
|
||||||
|
import androidx.compose.foundation.layout.padding
|
||||||
|
import androidx.compose.foundation.verticalScroll
|
||||||
|
import androidx.compose.material3.ExperimentalMaterial3Api
|
||||||
|
import androidx.compose.material3.Scaffold
|
||||||
|
import androidx.compose.material3.Text
|
||||||
|
import androidx.compose.runtime.Composable
|
||||||
|
import androidx.compose.ui.Modifier
|
||||||
|
import androidx.lifecycle.viewmodel.compose.viewModel
|
||||||
|
import androidx.navigation.NavController
|
||||||
|
import com.example.myapplication.AppViewModelProvider
|
||||||
|
import com.example.myapplication.ui.dishes.list.DishList
|
||||||
|
import com.example.myapplication.ui.dishes.list.DishListViewModel
|
||||||
|
|
||||||
|
|
||||||
|
@OptIn(ExperimentalMaterial3Api::class)
|
||||||
|
@Composable
|
||||||
|
fun ErrorElement(
|
||||||
|
navController: NavController,
|
||||||
|
viewModel: ErrorsViewModel = viewModel(factory = AppViewModelProvider.Factory),
|
||||||
|
typeErrorsType: ErrorsType
|
||||||
|
) {
|
||||||
|
Scaffold(
|
||||||
|
) { innerPadding ->
|
||||||
|
ErrorElement(
|
||||||
|
modifier = Modifier
|
||||||
|
.padding(innerPadding)
|
||||||
|
.fillMaxSize(),
|
||||||
|
text = viewModel.getError(typeErrorsType).errorText
|
||||||
|
)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Composable
|
||||||
|
private fun ErrorElement(
|
||||||
|
modifier: Modifier,
|
||||||
|
text: String
|
||||||
|
) {
|
||||||
|
Text(text = text)
|
||||||
|
}
|
@ -0,0 +1,27 @@
|
|||||||
|
package com.example.myapplication.ui.extra
|
||||||
|
|
||||||
|
import androidx.lifecycle.ViewModel
|
||||||
|
import androidx.lifecycle.viewModelScope
|
||||||
|
import com.example.myapplication.database.AppDataContainer
|
||||||
|
import com.example.myapplication.database.model.Dish
|
||||||
|
import com.example.myapplication.ui.dishes.list.DishListUiState
|
||||||
|
import kotlinx.coroutines.flow.SharingStarted
|
||||||
|
import kotlinx.coroutines.flow.StateFlow
|
||||||
|
import kotlinx.coroutines.flow.map
|
||||||
|
import kotlinx.coroutines.flow.stateIn
|
||||||
|
|
||||||
|
enum class ErrorsType {
|
||||||
|
NOT_AUTH,
|
||||||
|
NOT_FOUND
|
||||||
|
}
|
||||||
|
class ErrorsViewModel : ViewModel() {
|
||||||
|
fun getError(type: ErrorsType) : ErrorUiState {
|
||||||
|
return when (type) {
|
||||||
|
ErrorsType.NOT_AUTH -> ErrorUiState("Auth first")
|
||||||
|
ErrorsType.NOT_FOUND -> ErrorUiState("Not found")
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
data class ErrorUiState(val errorText: String = "")
|
@ -1,7 +1,6 @@
|
|||||||
package com.example.myapplication.ui.navigation
|
package com.example.myapplication.ui.navigation
|
||||||
|
|
||||||
import android.annotation.SuppressLint
|
import android.annotation.SuppressLint
|
||||||
import android.content.res.Configuration
|
|
||||||
import android.os.Build
|
import android.os.Build
|
||||||
import androidx.annotation.RequiresApi
|
import androidx.annotation.RequiresApi
|
||||||
import androidx.compose.foundation.background
|
import androidx.compose.foundation.background
|
||||||
@ -12,9 +11,7 @@ import androidx.compose.material3.MaterialTheme
|
|||||||
import androidx.compose.material3.Scaffold
|
import androidx.compose.material3.Scaffold
|
||||||
import androidx.compose.material3.Surface
|
import androidx.compose.material3.Surface
|
||||||
import androidx.compose.runtime.Composable
|
import androidx.compose.runtime.Composable
|
||||||
import androidx.compose.runtime.LaunchedEffect
|
|
||||||
import androidx.compose.runtime.getValue
|
import androidx.compose.runtime.getValue
|
||||||
import androidx.compose.runtime.rememberCoroutineScope
|
|
||||||
import androidx.compose.ui.Modifier
|
import androidx.compose.ui.Modifier
|
||||||
import androidx.compose.ui.platform.LocalContext
|
import androidx.compose.ui.platform.LocalContext
|
||||||
import androidx.compose.ui.tooling.preview.Preview
|
import androidx.compose.ui.tooling.preview.Preview
|
||||||
@ -25,16 +22,15 @@ import androidx.navigation.compose.composable
|
|||||||
import androidx.navigation.compose.currentBackStackEntryAsState
|
import androidx.navigation.compose.currentBackStackEntryAsState
|
||||||
import androidx.navigation.compose.rememberNavController
|
import androidx.navigation.compose.rememberNavController
|
||||||
import androidx.navigation.navArgument
|
import androidx.navigation.navArgument
|
||||||
import com.example.myapplication.Dishes.ui.DishList
|
import com.example.myapplication.ui.dishes.list.DishList
|
||||||
import com.example.myapplication.Dishes.ui.DishView
|
//import com.example.myapplication.ui.dishes.DishView
|
||||||
import com.example.myapplication.User.Model.User
|
import com.example.myapplication.database.model.User
|
||||||
import com.example.myapplication.User.ui.UserView
|
//import com.example.myapplication.ui.user.UserView
|
||||||
import com.example.myapplication.database.AppDatabase
|
|
||||||
import com.example.myapplication.ui.components.Navbar
|
import com.example.myapplication.ui.components.Navbar
|
||||||
|
import com.example.myapplication.ui.dishes.DishView
|
||||||
|
import com.example.myapplication.ui.dishes.list.TypeDishList
|
||||||
import com.example.myapplication.ui.theme.MyApplicationTheme
|
import com.example.myapplication.ui.theme.MyApplicationTheme
|
||||||
import kotlinx.coroutines.Dispatchers
|
import com.example.myapplication.ui.user.UserView
|
||||||
import kotlinx.coroutines.launch
|
|
||||||
import kotlinx.coroutines.withContext
|
|
||||||
|
|
||||||
@RequiresApi(Build.VERSION_CODES.Q)
|
@RequiresApi(Build.VERSION_CODES.Q)
|
||||||
@Composable
|
@Composable
|
||||||
@ -43,8 +39,7 @@ fun Navhost(
|
|||||||
innerPadding: PaddingValues, modifier:
|
innerPadding: PaddingValues, modifier:
|
||||||
Modifier = Modifier
|
Modifier = Modifier
|
||||||
) {
|
) {
|
||||||
val context = LocalContext.current
|
val userUid = 1;
|
||||||
var someUser: User? = null
|
|
||||||
NavHost(
|
NavHost(
|
||||||
navController,
|
navController,
|
||||||
startDestination = Screen.AllDishes.route,
|
startDestination = Screen.AllDishes.route,
|
||||||
@ -52,14 +47,14 @@ fun Navhost(
|
|||||||
) {
|
) {
|
||||||
|
|
||||||
|
|
||||||
composable(Screen.AllDishes.route) { DishList(navController, someUser = 1) }
|
composable(Screen.AllDishes.route) { DishList(navController, userUid = userUid) }
|
||||||
composable(Screen.FavoriteDishes.route) { DishList(navController, true, 1)}
|
composable(Screen.FavoriteDishes.route) { DishList(navController, userUid = userUid, typeDishList = TypeDishList.FavoritesDishes) }
|
||||||
composable(Screen.UserPage.route) {UserView(id = 1, navController = navController)} // TODO Remove hardcode
|
composable(Screen.UserPage.route) { UserView(navController, userUid = userUid) }
|
||||||
|
|
||||||
composable(Screen.DishView.route,
|
composable(Screen.DishView.route,
|
||||||
arguments = listOf(navArgument("id") { type = NavType.IntType })
|
arguments = listOf(navArgument("id") { type = NavType.IntType })
|
||||||
) { backStackEntry ->
|
) { backStackEntry ->
|
||||||
backStackEntry.arguments?.let { DishView(it.getInt("id")) }
|
backStackEntry.arguments?.let { DishView(navController, userUid = userUid, dishUid = it.getInt("id")) }
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -1,38 +1,42 @@
|
|||||||
package com.example.myapplication.User.ui
|
package com.example.myapplication.ui.user
|
||||||
|
|
||||||
import android.os.Build
|
import android.os.Build
|
||||||
import androidx.annotation.RequiresApi
|
import androidx.annotation.RequiresApi
|
||||||
import androidx.compose.foundation.Image
|
|
||||||
import androidx.compose.foundation.layout.Arrangement
|
import androidx.compose.foundation.layout.Arrangement
|
||||||
import androidx.compose.foundation.layout.Column
|
import androidx.compose.foundation.layout.Column
|
||||||
import androidx.compose.foundation.layout.Row
|
import androidx.compose.foundation.layout.Row
|
||||||
import androidx.compose.foundation.layout.fillMaxSize
|
import androidx.compose.foundation.layout.fillMaxSize
|
||||||
import androidx.compose.foundation.layout.fillMaxWidth
|
import androidx.compose.foundation.layout.fillMaxWidth
|
||||||
import androidx.compose.foundation.layout.padding
|
import androidx.compose.foundation.layout.padding
|
||||||
import androidx.compose.material3.Button
|
import androidx.compose.material3.ExperimentalMaterial3Api
|
||||||
import androidx.compose.material3.MaterialTheme
|
import androidx.compose.material3.MaterialTheme
|
||||||
|
import androidx.compose.material3.Scaffold
|
||||||
import androidx.compose.material3.Surface
|
import androidx.compose.material3.Surface
|
||||||
import androidx.compose.material3.Text
|
import androidx.compose.material3.Text
|
||||||
import androidx.compose.runtime.Composable
|
import androidx.compose.runtime.Composable
|
||||||
import androidx.compose.runtime.LaunchedEffect
|
import androidx.compose.runtime.LaunchedEffect
|
||||||
import androidx.compose.runtime.MutableState
|
import androidx.compose.runtime.collectAsState
|
||||||
|
import androidx.compose.runtime.getValue
|
||||||
import androidx.compose.runtime.mutableStateOf
|
import androidx.compose.runtime.mutableStateOf
|
||||||
import androidx.compose.runtime.remember
|
import androidx.compose.runtime.remember
|
||||||
import androidx.compose.runtime.setValue
|
import androidx.compose.runtime.rememberCoroutineScope
|
||||||
import androidx.compose.ui.Modifier
|
import androidx.compose.ui.Modifier
|
||||||
import androidx.compose.ui.modifier.modifierLocalConsumer
|
|
||||||
import androidx.compose.ui.platform.LocalContext
|
import androidx.compose.ui.platform.LocalContext
|
||||||
import androidx.compose.ui.res.painterResource
|
|
||||||
import androidx.compose.ui.text.style.TextAlign
|
import androidx.compose.ui.text.style.TextAlign
|
||||||
import androidx.compose.ui.text.style.TextOverflow
|
|
||||||
import androidx.compose.ui.tooling.preview.Preview
|
import androidx.compose.ui.tooling.preview.Preview
|
||||||
import androidx.compose.ui.unit.dp
|
import androidx.compose.ui.unit.dp
|
||||||
import androidx.compose.ui.unit.sp
|
import androidx.compose.ui.unit.sp
|
||||||
|
import androidx.lifecycle.viewmodel.compose.viewModel
|
||||||
import androidx.navigation.NavController
|
import androidx.navigation.NavController
|
||||||
|
import com.example.myapplication.AppViewModelProvider
|
||||||
//import com.example.myapplication.Dishes.Model.getAllDishes
|
//import com.example.myapplication.Dishes.Model.getAllDishes
|
||||||
import com.example.myapplication.Dishes.ui.DishList
|
import com.example.myapplication.ui.dishes.list.DishList
|
||||||
import com.example.myapplication.User.Model.User
|
import com.example.myapplication.database.model.User
|
||||||
import com.example.myapplication.database.AppDatabase
|
import com.example.myapplication.database.AppDatabase
|
||||||
|
import com.example.myapplication.ui.dishes.list.DishListViewModel
|
||||||
|
import com.example.myapplication.ui.dishes.list.TypeDishList
|
||||||
|
import com.example.myapplication.ui.extra.ErrorElement
|
||||||
|
import com.example.myapplication.ui.extra.ErrorsType
|
||||||
//import com.example.myapplication.User.Model.getAllUsers
|
//import com.example.myapplication.User.Model.getAllUsers
|
||||||
import com.example.myapplication.ui.theme.MyApplicationTheme
|
import com.example.myapplication.ui.theme.MyApplicationTheme
|
||||||
import com.example.myapplication.ui.theme.textFont
|
import com.example.myapplication.ui.theme.textFont
|
||||||
@ -40,46 +44,54 @@ import kotlinx.coroutines.Dispatchers
|
|||||||
import kotlinx.coroutines.withContext
|
import kotlinx.coroutines.withContext
|
||||||
|
|
||||||
@RequiresApi(Build.VERSION_CODES.Q)
|
@RequiresApi(Build.VERSION_CODES.Q)
|
||||||
|
@OptIn(ExperimentalMaterial3Api::class)
|
||||||
@Composable
|
@Composable
|
||||||
fun UserView(id: Int, navController: NavController?) {
|
fun UserView (
|
||||||
var user = remember { mutableStateOf(User(0, "", "", "")) }
|
navController: NavController,
|
||||||
val context = LocalContext.current
|
viewModel: UserViewModel = viewModel(factory = AppViewModelProvider.Factory),
|
||||||
LaunchedEffect(Unit) {
|
userUid: Int?
|
||||||
withContext(Dispatchers.IO) {
|
) {
|
||||||
user.value = AppDatabase.getInstance(context).userDao().getByUid(id)
|
val coroutineScope = rememberCoroutineScope()
|
||||||
|
val userUiState by viewModel.getUser(userUid ?: 0).collectAsState()
|
||||||
|
|
||||||
|
Scaffold(
|
||||||
|
|
||||||
|
) {innerPadding ->
|
||||||
|
if (userUiState.user == null) {
|
||||||
|
ErrorElement(navController = navController, typeErrorsType = ErrorsType.NOT_AUTH)
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
UserView(
|
||||||
|
navController = navController,
|
||||||
|
modifier = Modifier
|
||||||
|
.padding(innerPadding)
|
||||||
|
.fillMaxSize(),
|
||||||
|
user = userUiState.user!!
|
||||||
|
)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@RequiresApi(Build.VERSION_CODES.Q)
|
||||||
|
@Composable
|
||||||
|
private fun UserView(
|
||||||
|
navController: NavController,
|
||||||
|
modifier: Modifier,
|
||||||
|
user: User
|
||||||
|
) {
|
||||||
Column(
|
Column(
|
||||||
Modifier
|
Modifier
|
||||||
.fillMaxWidth()
|
.fillMaxWidth()
|
||||||
.padding(vertical = 5.dp, horizontal = 10.dp)) {
|
.padding(vertical = 5.dp, horizontal = 10.dp)) {
|
||||||
Row(horizontalArrangement = Arrangement.Center, modifier = Modifier.fillMaxWidth()) {
|
Row(horizontalArrangement = Arrangement.Center, modifier = Modifier.fillMaxWidth()) {
|
||||||
Column {
|
Column {
|
||||||
Text(user.value.nickname, fontFamily= textFont,
|
Text(user.nickname, fontFamily= textFont,
|
||||||
fontSize=26.sp, textAlign = TextAlign.Start)
|
fontSize=26.sp, textAlign = TextAlign.Start)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
Row(modifier = Modifier.fillMaxWidth()) {
|
|
||||||
// Button(onClick = { }, Modifier.fillMaxWidth()) {
|
|
||||||
// Text("Create New Dish")
|
|
||||||
// }
|
|
||||||
}
|
|
||||||
Row(modifier = Modifier.fillMaxSize()) {
|
Row(modifier = Modifier.fillMaxSize()) {
|
||||||
DishList(navController, someUser = id, userPage = true)
|
DishList(navController, userUid = user.uid, typeDishList = TypeDishList.UserDishes)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@RequiresApi(Build.VERSION_CODES.Q)
|
|
||||||
@Preview
|
|
||||||
@Composable
|
|
||||||
fun UserPreview() {
|
|
||||||
MyApplicationTheme {
|
|
||||||
Surface(
|
|
||||||
color = MaterialTheme.colorScheme.background
|
|
||||||
) {
|
|
||||||
UserView(id = 0, null)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
@ -0,0 +1,31 @@
|
|||||||
|
package com.example.myapplication.ui.user
|
||||||
|
|
||||||
|
import androidx.lifecycle.ViewModel
|
||||||
|
import androidx.lifecycle.viewModelScope
|
||||||
|
import com.example.myapplication.database.AppDataContainer
|
||||||
|
import com.example.myapplication.database.model.Dish
|
||||||
|
import com.example.myapplication.database.model.User
|
||||||
|
import com.example.myapplication.database.repository.DishRepository
|
||||||
|
import com.example.myapplication.database.repository.UserRepository
|
||||||
|
import com.example.myapplication.database.repository.UserWithFavoritesRepository
|
||||||
|
import com.example.myapplication.ui.dishes.list.DishListUiState
|
||||||
|
import kotlinx.coroutines.flow.SharingStarted
|
||||||
|
import kotlinx.coroutines.flow.StateFlow
|
||||||
|
import kotlinx.coroutines.flow.map
|
||||||
|
import kotlinx.coroutines.flow.stateIn
|
||||||
|
|
||||||
|
class UserViewModel(
|
||||||
|
private val userRepository: UserRepository,
|
||||||
|
) : ViewModel() {
|
||||||
|
fun getUser(uid: Int) : StateFlow<UserUiState> {
|
||||||
|
return userRepository.getUser(uid).map {
|
||||||
|
UserUiState(it!!)
|
||||||
|
}.stateIn(
|
||||||
|
scope = viewModelScope,
|
||||||
|
started = SharingStarted.WhileSubscribed(stopTimeoutMillis = AppDataContainer.TIMEOUT),
|
||||||
|
initialValue = UserUiState()
|
||||||
|
)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
data class UserUiState(val user: User? = null)
|
Loading…
Reference in New Issue
Block a user