diff --git a/app/src/main/java/com/example/projectfigma/Activity/FavoritesActivity.kt b/app/src/main/java/com/example/projectfigma/Activity/FavoritesActivity.kt index d64e910..e08eaf0 100644 --- a/app/src/main/java/com/example/projectfigma/Activity/FavoritesActivity.kt +++ b/app/src/main/java/com/example/projectfigma/Activity/FavoritesActivity.kt @@ -20,12 +20,6 @@ class FavoritesActivity : AppCompatActivity() { setContentView(binding.root) StatusBar.hideStatusBar(window) - val dateBase = DataBase.getDb(this) - - val rv = findViewById(R.id.rvFoods).apply { - layoutManager = GridLayoutManager(context, 2) - } - supportFragmentManager.beginTransaction() .replace(R.id.buttonPanel, BottomPanelFragment()) .commit() diff --git a/app/src/main/java/com/example/projectfigma/Activity/RegActivity.kt b/app/src/main/java/com/example/projectfigma/Activity/RegActivity.kt index b58a444..e97fa84 100644 --- a/app/src/main/java/com/example/projectfigma/Activity/RegActivity.kt +++ b/app/src/main/java/com/example/projectfigma/Activity/RegActivity.kt @@ -85,7 +85,8 @@ class RegActivity() : AppCompatActivity(){ binding.passwordEditText.text.toString(), email, binding.mobileNumberEdit.text.toString(), - selectedDate ?: Date() + selectedDate ?: Date(), + favoriteDishesId = emptyList() ) Thread { diff --git a/app/src/main/java/com/example/projectfigma/Adapters/FavoriteDishesAdapter.kt b/app/src/main/java/com/example/projectfigma/Adapters/FavoriteDishesAdapter.kt index 62b7beb..e06498b 100644 --- a/app/src/main/java/com/example/projectfigma/Adapters/FavoriteDishesAdapter.kt +++ b/app/src/main/java/com/example/projectfigma/Adapters/FavoriteDishesAdapter.kt @@ -7,11 +7,15 @@ import android.widget.ImageView import android.widget.TextView import androidx.recyclerview.widget.RecyclerView import com.bumptech.glide.Glide +import com.example.projectfigma.DataBase.DataBase import com.example.projectfigma.Entites.Dishes +import com.example.projectfigma.Entites.User import com.example.projectfigma.R +import kotlin.coroutines.coroutineContext class FavoriteFoodAdapter( - private val items: MutableList + private val items: MutableList, + private val onFavoriteClick: (dish: Dishes) -> Unit ) : RecyclerView.Adapter() { inner class VH(view: View) : RecyclerView.ViewHolder(view) { @@ -34,16 +38,14 @@ class FavoriteFoodAdapter( holder.tvTitle.text = dish.name holder.tvDesc.text = dish.description - // загрузка изображения блюда Glide.with(holder.itemView) .load(dish.imageUri) .into(holder.imgFood) - // иконка категории holder.imgTag.setImageResource(dish.category.iconRes) - // иконка «избранное»— всегда заполнена holder.imgFavorite.setImageResource(R.drawable.ic_heart_border) + holder.imgFavorite.setOnClickListener { onFavoriteClick(dish) } } override fun getItemCount(): Int = items.size @@ -54,4 +56,5 @@ class FavoriteFoodAdapter( items.addAll(newItems) notifyDataSetChanged() } + } \ No newline at end of file diff --git a/app/src/main/java/com/example/projectfigma/Converters/ConvertersList.kt b/app/src/main/java/com/example/projectfigma/Converters/ConvertersList.kt new file mode 100644 index 0000000..37f8820 --- /dev/null +++ b/app/src/main/java/com/example/projectfigma/Converters/ConvertersList.kt @@ -0,0 +1,11 @@ +package com.example.projectfigma.Converters + +import androidx.room.TypeConverter + +class ConvertersList { + @TypeConverter + fun fromIntList(value: List?): String = value?.joinToString(",") ?: "" + @TypeConverter + fun toIntList(value: String): List = + if (value.isEmpty()) emptyList() else value.split(",").map { it.toInt() } +} \ No newline at end of file diff --git a/app/src/main/java/com/example/projectfigma/DAO/DishesDao.kt b/app/src/main/java/com/example/projectfigma/DAO/DishesDao.kt index f59e898..ee99af3 100644 --- a/app/src/main/java/com/example/projectfigma/DAO/DishesDao.kt +++ b/app/src/main/java/com/example/projectfigma/DAO/DishesDao.kt @@ -7,6 +7,7 @@ import androidx.room.OnConflictStrategy import androidx.room.Query import androidx.room.Update import com.example.projectfigma.Entites.Dishes +import com.example.projectfigma.Enums.DishCategory @Dao interface DishesDao { @@ -31,6 +32,12 @@ interface DishesDao { @Query("SELECT * FROM dishes b WHERE b.isRecommend = 1") fun getRecommend(): LiveData> + @Query("SELECT * FROM dishes d WHERE d.id = :id") + fun getDishById(id : Int) : Dishes + + @Query("SELECT * FROM dishes WHERE id IN (:ids)") + fun getDishesByIds(ids: List): List + @Update suspend fun update(item: Dishes) } \ No newline at end of file diff --git a/app/src/main/java/com/example/projectfigma/DAO/UserDao.kt b/app/src/main/java/com/example/projectfigma/DAO/UserDao.kt index 24a9c92..0badd54 100644 --- a/app/src/main/java/com/example/projectfigma/DAO/UserDao.kt +++ b/app/src/main/java/com/example/projectfigma/DAO/UserDao.kt @@ -2,16 +2,21 @@ package com.example.projectfigma.DAO import androidx.room.Dao import androidx.room.Insert +import androidx.room.OnConflictStrategy import androidx.room.Query import androidx.room.Update +import com.example.projectfigma.Entites.Dishes import com.example.projectfigma.Entites.User @Dao interface UserDao { - @Insert + @Insert(onConflict = OnConflictStrategy.REPLACE) fun insertUser(item: User) + @Insert(onConflict = OnConflictStrategy.REPLACE) + fun insertAll(items: List) + @Update fun updateUser(user: User) diff --git a/app/src/main/java/com/example/projectfigma/DataBase/DataBase.kt b/app/src/main/java/com/example/projectfigma/DataBase/DataBase.kt index 497b03d..cf15fbd 100644 --- a/app/src/main/java/com/example/projectfigma/DataBase/DataBase.kt +++ b/app/src/main/java/com/example/projectfigma/DataBase/DataBase.kt @@ -1,12 +1,14 @@ package com.example.projectfigma.DataBase import android.content.Context +import android.text.style.TtsSpan import androidx.room.Database import androidx.room.Room import androidx.room.RoomDatabase import androidx.room.TypeConverters import androidx.sqlite.db.SupportSQLiteDatabase import com.example.projectfigma.Converters.ConvertToDishesCategory +import com.example.projectfigma.Converters.ConvertersList import com.example.projectfigma.DAO.DishesDao import com.example.projectfigma.DAO.SettingsDao import com.example.projectfigma.DAO.SessionDao @@ -22,12 +24,17 @@ import kotlinx.coroutines.CoroutineScope import kotlinx.coroutines.Dispatchers import kotlinx.coroutines.SupervisorJob import kotlinx.coroutines.launch +import java.util.Date @Database( entities = [User::class, Dishes::class, Session::class, AppSettings::class], - version = 5 + version = 6 +) +@TypeConverters( + ConvertersToDateTime::class, + ConvertToDishesCategory::class, + ConvertersList::class ) -@TypeConverters(ConvertersToDateTime::class, ConvertToDishesCategory::class) abstract class DataBase : RoomDatabase() { abstract fun getUserDao(): UserDao @@ -41,6 +48,17 @@ abstract class DataBase : RoomDatabase() { private val applicationScope = CoroutineScope(SupervisorJob() + Dispatchers.IO) + private fun prepopulateUsers(): List = listOf( + User( + name = "TestUser", + gmail = "test@yandex.ru", + password = "1111", + mobileNumber = "818412481", + dateOfBirth = Date(), + favoriteDishesId = listOf(1,2,3) + ) + ) + private fun prepopulateBestSellers(packageName: String) = listOf( Dishes( imageUri = "android.resource://$packageName/${R.drawable.best_seller_card_1}", @@ -92,6 +110,16 @@ abstract class DataBase : RoomDatabase() { description = "Бургер", category = DishCategory.MEAL ), + Dishes( + imageUri = "android.resource://$packageName/${R.drawable.roll}", + price = 25.0, + isBestSeller = false, + isRecommend = true, + rating = 5.0, + name = "Роллы", + description = "Роллы", + category = DishCategory.VEGAN + ), Dishes( imageUri = "android.resource://$packageName/${R.drawable.roll}", price = 25.0, @@ -121,10 +149,16 @@ abstract class DataBase : RoomDatabase() { applicationScope.launch { val database = getDb(appContext) - val bestSellerDao = database.getDishesDao() - if (bestSellerDao.getAll().isEmpty()) { - bestSellerDao.insertAll(prepopulateBestSellers(pkg)) + val dishesDao = database.getDishesDao() + if (dishesDao.getAll().isEmpty()) { + dishesDao.insertAll(prepopulateBestSellers(pkg)) + } + + val userDao = database.getUserDao() + if (userDao.getAllUsers().isEmpty()) { + userDao.insertAll(prepopulateUsers()) } + val settingsDao = database.getSettingsDao() settingsDao.upsert(AppSettings(id = 0, isFirstRun = true)) diff --git a/app/src/main/java/com/example/projectfigma/Entites/Dishes.kt b/app/src/main/java/com/example/projectfigma/Entites/Dishes.kt index c4edbb5..cee6616 100644 --- a/app/src/main/java/com/example/projectfigma/Entites/Dishes.kt +++ b/app/src/main/java/com/example/projectfigma/Entites/Dishes.kt @@ -12,7 +12,7 @@ data class Dishes( val rating: Double, val isRecommend: Boolean, val isBestSeller: Boolean, - val name : String, - val description : String, + val name: String, + val description: String, val category: DishCategory ) \ No newline at end of file diff --git a/app/src/main/java/com/example/projectfigma/Entites/User.kt b/app/src/main/java/com/example/projectfigma/Entites/User.kt index 2d252a6..b21ced1 100644 --- a/app/src/main/java/com/example/projectfigma/Entites/User.kt +++ b/app/src/main/java/com/example/projectfigma/Entites/User.kt @@ -18,5 +18,6 @@ data class User( @ColumnInfo(name = "mobileNumber") var mobileNumber : String, @ColumnInfo(name = "dateOfBirth") - var dateOfBirth : Date + var dateOfBirth : Date, + var favoriteDishesId: List ) diff --git a/app/src/main/java/com/example/projectfigma/Fragments/BottomPanelActivity.kt b/app/src/main/java/com/example/projectfigma/Fragments/BottomPanelActivity.kt index 8219490..48a43a5 100644 --- a/app/src/main/java/com/example/projectfigma/Fragments/BottomPanelActivity.kt +++ b/app/src/main/java/com/example/projectfigma/Fragments/BottomPanelActivity.kt @@ -16,7 +16,7 @@ class BottomPanelFragment : Fragment() { inflater: LayoutInflater, container: ViewGroup?, savedInstanceState: Bundle? - ): View? = inflater.inflate(R.layout.activity_bottom_panel, container, false) + ): View? = inflater.inflate(R.layout.fragment_bottom_panel, container, false) override fun onViewCreated(view: View, savedInstanceState: Bundle?) { super.onViewCreated(view, savedInstanceState) diff --git a/app/src/main/java/com/example/projectfigma/Fragments/FavoriteListFragment.kt b/app/src/main/java/com/example/projectfigma/Fragments/FavoriteListFragment.kt index 92d458d..8f55b5b 100644 --- a/app/src/main/java/com/example/projectfigma/Fragments/FavoriteListFragment.kt +++ b/app/src/main/java/com/example/projectfigma/Fragments/FavoriteListFragment.kt @@ -1,16 +1,20 @@ package com.example.projectfigma.Fragments + import android.content.Context + import android.os.Build import android.os.Bundle import androidx.fragment.app.Fragment import android.view.LayoutInflater import android.view.View import android.view.ViewGroup + import androidx.annotation.RequiresApi import androidx.lifecycle.lifecycleScope import androidx.recyclerview.widget.GridLayoutManager import androidx.recyclerview.widget.RecyclerView import com.example.projectfigma.Adapters.FavoriteFoodAdapter import com.example.projectfigma.DataBase.DataBase import com.example.projectfigma.Entites.Dishes + import com.example.projectfigma.Entites.User import com.example.projectfigma.R import com.example.projectfigma.databinding.FragmentBestSellerBinding import com.example.projectfigma.databinding.FragmentFavoriteListBinding @@ -24,6 +28,8 @@ private val binding get() = _binding!! private lateinit var adapter: FavoriteFoodAdapter + private var currentUser: User? = null + private lateinit var dataBase: DataBase override fun onCreateView( inflater: LayoutInflater, @@ -34,23 +40,57 @@ return binding.root } + override fun onAttach(context: Context) { + super.onAttach(context) + dataBase = DataBase.getDb(context) + } + override fun onViewCreated(view: View, savedInstanceState: Bundle?) { super.onViewCreated(view, savedInstanceState) - - adapter = FavoriteFoodAdapter(mutableListOf()) + // 1) Загрузить текущего пользователя из БД + lifecycleScope.launch(Dispatchers.IO) { + currentUser = dataBase + .getUserDao().getUserByEmail( + dataBase.getSessionDao().getSession()?.userEmail.toString() + ) + withContext(Dispatchers.Main) { + setupRecycler() + loadFavorites() + } + } + } + private fun setupRecycler() { + adapter = FavoriteFoodAdapter(mutableListOf()) { dish -> + currentUser?.let { user -> + // 2) Удаляем ID блюда из списка + val newList = user.favoriteDishesId.toMutableList() + newList.remove(dish.id.toInt()) + user.favoriteDishesId = newList + // 3) Сохраняем пользователя в БД и обновляем UI + lifecycleScope.launch(Dispatchers.IO) { + DataBase.getDb(requireContext()).getUserDao().updateUser(user) + val all = DataBase.getDb(requireContext()).getDishesDao().getAll() + val fav = all.filter { it.id.toInt() in newList } + withContext(Dispatchers.Main) { adapter.updateList(fav) } + } + } + } binding.rvFoods.layoutManager = GridLayoutManager(requireContext(), 2) binding.rvFoods.adapter = adapter + } - lifecycleScope.launch { - val dishesList = withContext(Dispatchers.IO) { - DataBase.getDb(requireContext()) - .getDishesDao() - .getAll() + private fun loadFavorites() { + currentUser?.let { user -> + lifecycleScope.launch(Dispatchers.IO) { + val all = dataBase.getDishesDao().getDishesByIds(user.favoriteDishesId) + println(" FFFFFFFFFFFFFFFF " + all.toString()) + println(" FFFFFFFFFFFFFFFF " + user) + withContext(Dispatchers.Main) { adapter.updateList(all) } } - adapter.updateList(dishesList) } } + override fun onDestroyView() { super.onDestroyView() _binding = null diff --git a/app/src/main/res/layout/activity_favorites.xml b/app/src/main/res/layout/activity_favorites.xml index f36a95c..0b0fbe2 100644 --- a/app/src/main/res/layout/activity_favorites.xml +++ b/app/src/main/res/layout/activity_favorites.xml @@ -85,7 +85,7 @@