Compare commits

..

1 Commits
laba5 ... main

Author SHA1 Message Date
894ed223e2 Обновить README.md 2024-12-26 00:22:49 +04:00
70 changed files with 253 additions and 2257 deletions

View File

@ -1,2 +1,11 @@
# MobileDev
# Разработка мобильного приложения "Пиццерия"
Данное приложение будет разработано на языке Kotlin с использованием бд h2
## Дизайн
Простой и приятный дизайн, основными достоинствами которого являются
- Яркость
- Лаконичность
- Насыщенность

View File

@ -4,7 +4,6 @@ plugins {
id("org.jetbrains.kotlin.android")
id("androidx.navigation.safeargs.kotlin")
id("kotlin-kapt")
kotlin("plugin.serialization") version "1.4.21"
}
android {
@ -52,8 +51,6 @@ dependencies {
implementation("androidx.lifecycle:lifecycle-livedata-ktx:2.6.2")
implementation("androidx.lifecycle:lifecycle-viewmodel-ktx:2.6.2")
implementation ("org.jetbrains.kotlinx:kotlinx-coroutines-core:1.3.5")
implementation("com.google.android.material:material:1.9.0")
implementation("androidx.navigation:navigation-fragment-ktx:2.6.0")
implementation("androidx.navigation:navigation-ui-ktx:2.6.0")
@ -76,16 +73,6 @@ dependencies {
// optional - RxJava3 support
implementation("androidx.paging:paging-rxjava3:$paging_version")
//retrofit
val retrofitVersion = "2.9.0"
implementation("com.squareup.retrofit2:retrofit:$retrofitVersion")
implementation("com.squareup.retrofit2:adapter-rxjava3:$retrofitVersion")
implementation("com.squareup.retrofit2:converter-moshi:$retrofitVersion")
implementation("com.squareup.okhttp3:logging-interceptor:4.11.0")
implementation("org.jetbrains.kotlinx:kotlinx-serialization-json:1.5.1")
implementation("com.jakewharton.retrofit:retrofit2-kotlinx-serialization-converter:1.0.0")
implementation("com.squareup.retrofit2:converter-gson:2.9.0")
// Test
testImplementation("junit:junit:4.13.2")
androidTestImplementation("androidx.test.ext:junit:1.1.5")

View File

@ -1,13 +1,8 @@
<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools">
<uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE"/>
<uses-permission android:name="android.permission.INTERNET" />
<uses-permission android:name="android.permission.ACCESS_NETWORK_STATE" />
<application
android:name=".PizzaApplication"
android:allowBackup="true"
android:dataExtractionRules="@xml/data_extraction_rules"
android:fullBackupContent="@xml/backup_rules"
@ -16,8 +11,6 @@
android:roundIcon="@drawable/icon"
android:supportsRtl="true"
android:theme="@style/Theme.Pizza"
android:usesCleartextTraffic="true"
android:networkSecurityConfig="@xml/network_security_config"
tools:targetApi="31">
<activity
android:name=".MainActivity"

View File

@ -1,8 +1,6 @@
package com.example.pizza
import android.annotation.SuppressLint
import android.content.Intent
import android.net.Uri
import android.os.Bundle
import android.view.LayoutInflater
import android.view.View
@ -13,44 +11,26 @@ import android.widget.Toast
import androidx.fragment.app.Fragment
import androidx.fragment.app.activityViewModels
import androidx.fragment.app.viewModels
import androidx.lifecycle.LiveData
import androidx.lifecycle.MutableLiveData
import androidx.lifecycle.Observer
import androidx.lifecycle.ViewModelProvider
import androidx.lifecycle.ViewModelStore
import androidx.lifecycle.ViewModelStoreOwner
import androidx.navigation.Navigation
import androidx.paging.PagingData
import com.example.pizza.Model.Pizza.Pizza
import com.example.pizza.Model.User.User
import com.example.pizza.Model.User.UserDao
import com.example.pizza.ViewModels.AppViewModelProvider
import com.example.pizza.ViewModels.UserViewModel
import com.example.pizza.database.AppDatabase
import io.reactivex.rxjava3.android.schedulers.AndroidSchedulers
import io.reactivex.rxjava3.core.Observable
import io.reactivex.rxjava3.schedulers.Schedulers
import kotlinx.coroutines.runBlocking
class Auth : Fragment() {
private var userViewModel : UserViewModel? = null
val viewModel: myViewModel by activityViewModels()
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
val viewModel : UserViewModel by viewModels(
factoryProducer = {AppViewModelProvider.Factory}
)
userViewModel = viewModel
}
private var userDao: UserDao? = null
override fun onCreateView(
inflater: LayoutInflater, container: ViewGroup?,
savedInstanceState: Bundle?
): View? {
// Inflate the layout for this fragment
userDao = context?.let { AppDatabase.getInstance(it).userDao() }
val view = inflater.inflate(R.layout.fragment_auth, container, false)
view.findViewById<Button>(R.id.button_auth).setOnClickListener {buttonClick(view)}
view.findViewById<TextView>(R.id.link_to_reg).setOnClickListener{TextViewClick(view)}
@ -62,38 +42,31 @@ class Auth : Fragment() {
private fun buttonClick(view: View) {
val login = view.findViewById<TextView>(R.id.auth_user_login)?.text.toString().trim()
val pass = view.findViewById<TextView>(R.id.auth_user_pass)?.text.toString().trim()
val viewModel: myViewModel by activityViewModels()
if(login.length == 0 || pass.length ==0){
Toast.makeText(view.context, "Укажите логин или пароль", Toast.LENGTH_SHORT).show()
return
}
userViewModel!!.getUserByLP(login,pass,
onLoad =
{data: User -> viewModel.setId(data.uid!!)
if (data.role == "admin")
viewModel.setRole(true)
Toast.makeText(view.context, "Добро пожаловать", Toast.LENGTH_SHORT).show()
val action = AuthDirections
.actionNavigationAuthToNavigationPizzaList()
Navigation.findNavController(view).navigate(action)
},
onError = { Toast.makeText(view.context, "Неверно указаны дынные", Toast.LENGTH_SHORT).show() }
)
userDao?.getByLoginAndPassword(login, pass)?.subscribeOn(Schedulers.io())
?.observeOn(AndroidSchedulers.mainThread())
?.doOnError { Toast.makeText(view.context, "Неверный логин или пароль", Toast.LENGTH_SHORT).show() }
?.doOnSuccess { Toast.makeText(view.context, "Добро пожаловать", Toast.LENGTH_SHORT).show() }
?.onErrorComplete()
?.subscribe{user ->
viewModel.setId(user.uid!!)
if(user.role.equals("admin"))
viewModel.setRole(true)
val action = AuthDirections
.actionNavigationAuthToNavigationPizzaList()
Navigation.findNavController(view).navigate(action)
}
}
override fun onStart() {
super.onStart()
}
private fun TextViewClick(view: View) {
val action = AuthDirections
.actionNavigationAuthToNavigationReg(-1)
.actionNavigationAuthToNavigationReg()
Navigation.findNavController(view).navigate(action)
}
fun openURL() {
val openURL = Intent(Intent.ACTION_VIEW)
openURL.data = Uri.parse("https://ulstu.ru/")
startActivity(openURL)
}
}

View File

@ -15,9 +15,7 @@ import androidx.core.graphics.drawable.toBitmap
import androidx.core.graphics.drawable.toDrawable
import androidx.fragment.app.activityViewModels
import androidx.fragment.app.viewModels
import androidx.lifecycle.LiveData
import androidx.navigation.Navigation
import androidx.paging.PagingData
import androidx.recyclerview.widget.LinearLayoutManager
import androidx.recyclerview.widget.RecyclerView
import com.example.pizza.Model.Pizza.Pizza
@ -25,9 +23,6 @@ import com.example.pizza.Model.Pizza.PizzaDao
import com.example.pizza.Model.PizzaAdapter
import com.example.pizza.Model.User.User
import com.example.pizza.Model.User.UserDao
import com.example.pizza.ViewModels.AppViewModelProvider
import com.example.pizza.ViewModels.BasketEditViewModel
import com.example.pizza.ViewModels.PizzaListViewModel
import com.example.pizza.database.AppDatabase
import io.reactivex.rxjava3.android.schedulers.AndroidSchedulers
import io.reactivex.rxjava3.schedulers.Schedulers
@ -35,30 +30,13 @@ import io.reactivex.rxjava3.schedulers.Schedulers
class ListPizza : Fragment() {
private var pizzaDao: PizzaDao? = null
private var userDao: UserDao? = null
private var pizzaViewModel: PizzaListViewModel? = null
private var pizzaAdapter: PizzaAdapter? = null
private var basketViewModel : BasketEditViewModel? = null
private var currentUser: User? = null
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
val viewModel: PizzaListViewModel by viewModels(
factoryProducer = { AppViewModelProvider.Factory }
)
pizzaViewModel = viewModel
val viewModel2: BasketEditViewModel by viewModels(
factoryProducer = { AppViewModelProvider.Factory }
)
basketViewModel = viewModel2
}
override fun onStart() {
super.onStart()
val pizzas: LiveData<PagingData<Pizza>>? = pizzaViewModel?.getPizzas()
pizzas?.observe(viewLifecycleOwner) { data ->
data?.let {
pizzaAdapter?.submitData(lifecycle, it)
}
}
}
@SuppressLint("CheckResult")
override fun onCreateView(
inflater: LayoutInflater, container: ViewGroup?,
@ -72,25 +50,18 @@ class ListPizza : Fragment() {
val view = inflater.inflate(R.layout.fragment_list_pizza, container, false)
val itemsList : RecyclerView = view.findViewById(R.id.pizzasList)
if(!viewModel.getRole()) {
if(!viewModel.getRole())
view.findViewById<Button>(R.id.button_add).visibility = View.GONE
pizzaAdapter = PizzaAdapter(view.context, viewModel.getId()!!, basketViewModel!!,
onSave = {Toast.makeText(view.context, "Пицца добавлена в корзину ", Toast.LENGTH_SHORT).show()},
onClick = {})
var items = pizzaDao?.getAll()
if (items != null) {
items.subscribeOn(Schedulers.io())
.observeOn(AndroidSchedulers.mainThread())
.subscribe { pizzas ->
itemsList.adapter = PizzaAdapter(pizzas,view.context, viewModel.getId()!!) }
}
else{
pizzaAdapter = PizzaAdapter(view.context, viewModel.getId()!!, basketViewModel!!,
onSave = {Toast.makeText(view.context, "Пицца добавлена в корзину ", Toast.LENGTH_SHORT).show()},
onClick = {data : Int -> val action = ListPizzaDirections
.actionNavigationListToNavigationCreatePizza(data)
Navigation.findNavController(view).navigate(action)})
}
itemsList.adapter = pizzaAdapter
view.findViewById<Button>(R.id.button_add).setOnClickListener{
val action = ListPizzaDirections
.actionNavigationListToNavigationCreatePizza(-1)
.actionNavigationListToNavigationCreatePizza()
Navigation.findNavController(view).navigate(action)
}
itemsList.layoutManager = LinearLayoutManager(view.context)

View File

@ -14,14 +14,14 @@ import com.example.pizza.Model.User.User
entity = Pizza::class,
parentColumns = ["uid"],
childColumns = ["pizza_id"],
onDelete = ForeignKey.CASCADE,
onUpdate = ForeignKey.CASCADE),
onDelete = ForeignKey.RESTRICT,
onUpdate = ForeignKey.RESTRICT),
ForeignKey(
entity = User::class,
parentColumns = ["uid"],
childColumns = ["user_id"],
onDelete = ForeignKey.CASCADE,
onUpdate = ForeignKey.CASCADE),
onDelete = ForeignKey.RESTRICT,
onUpdate = ForeignKey.RESTRICT),
],
primaryKeys = ["user_id", "pizza_id"])
data class Basket(

View File

@ -1,25 +1,19 @@
package com.example.pizza.Model.Basket
import androidx.paging.rxjava3.RxPagingSource
import androidx.room.Dao
import androidx.room.Delete
import androidx.room.Insert
import androidx.room.Query
import androidx.room.Update
import com.example.pizza.Model.Pizza.Pizza
import io.reactivex.rxjava3.core.Completable
import io.reactivex.rxjava3.core.Flowable
@Dao
interface BasketDao {
@Query("select * from basket inner join pizzas on basket.pizza_id = pizzas.uid where basket.user_id = :uid")
fun getUserBasket(uid: Int): Flowable<List<PizzaBasket>>
@Query("select * from basket inner join pizzas on basket.pizza_id = pizzas.uid where basket.user_id = :uid")
fun getUserAllBasket(uid: Int): Flowable<List<PizzaBasket>>
fun getUserBasket(uid: Int): Flowable<List<PizzaBasket>>
@Insert
fun insert(group: Basket): Completable
@Insert
fun insertAll(group: List<Basket>): Completable
@Update
fun update(group: Basket): Completable
@ -28,8 +22,6 @@ interface BasketDao {
fun delete(group: Basket): Completable
@Query("delete from basket where basket.user_id = :uid")
fun deleteByUser(uid : Int): Completable
@Query("delete from basket ")
fun deleteAll(): Completable
@Query("delete from basket where basket.user_id = :uid and basket.pizza_id = :pid")
fun deleteByUserAndPizza(uid : Int, pid:Int): Completable
}

View File

@ -1,22 +0,0 @@
package com.example.pizza.Model.Dto
import com.example.pizza.Model.Basket.Basket
import com.example.pizza.Model.Pizza.Pizza
import com.google.gson.annotations.SerializedName
import kotlinx.serialization.Serializable
@Serializable
data class BasketDto(
@SerializedName("user")val user: Int,
@SerializedName("pizza")val pizza: Int,
@SerializedName("count")val countPizza: Int = 1
){
}
fun BasketDto.toBasket(): Basket = Basket(
user, pizza, countPizza)
fun Basket.toBasketDto(): BasketDto = BasketDto(
user, pizza, countPizza
)

View File

@ -1,23 +0,0 @@
package com.example.pizza.Model.Dto
import com.example.pizza.Model.Order.Order
import com.example.pizza.Model.Pizza.Pizza
import com.google.gson.annotations.SerializedName
import kotlinx.serialization.Serializable
import java.util.Date
@Serializable
data class OrderDto(
@SerializedName("id") val uid : Int?,
@SerializedName("date")val date: Long ,
@SerializedName("pizza")val pizza: Int,
@SerializedName("user")val user: Int ,
@SerializedName("price")val price : Int
)
fun OrderDto.toOrder(): Order = Order(
uid, Date(date), pizza, user, price)
fun Order.toOrderDto(): OrderDto = OrderDto(
uid, date.time, pizza, user, price
)

View File

@ -1,45 +0,0 @@
package com.example.pizza.Model.Dto
import android.graphics.Bitmap
import android.graphics.BitmapFactory
import android.os.Build
import androidx.annotation.RequiresApi
import com.example.pizza.Model.Pizza.Pizza
import com.example.pizza.Model.User.User
import kotlinx.serialization.Serializable
import java.io.ByteArrayOutputStream
import java.util.Base64
@Serializable
data class PizzaDto(
val id : Int?,
val title : String,
val price : Int,
val image : String,
val ingredients : String
){
constructor(
title : String,
price : Int,
image : String,
ingredients : String
) : this(null, title,price, image, ingredients)
}
@RequiresApi(Build.VERSION_CODES.O)
fun PizzaDto.toPizza(): Pizza = Pizza(
id,
title, BitmapFactory.decodeByteArray(Base64.getDecoder().decode(image), 0, Base64.getDecoder().decode(image).size),ingredients,price)
@RequiresApi(Build.VERSION_CODES.O)
fun Pizza.toPizzaDto(): PizzaDto {
val outputStream = ByteArrayOutputStream()
image?.compress(Bitmap.CompressFormat.PNG, 100, outputStream)
val encoded = Base64.getEncoder().encodeToString(outputStream.toByteArray())
return PizzaDto(uid, title,price, encoded, ingredients, )
}

View File

@ -1,31 +0,0 @@
package com.example.pizza.Model.Dto
import com.example.pizza.Model.User.User
import com.google.gson.annotations.SerializedName
import kotlinx.serialization.Serializable
@Serializable
data class UserDto(
@SerializedName("id")val id : Int?,
@SerializedName("login")val login : String?,
@SerializedName("email")val email : String?,
@SerializedName("password")val password : String?,
@SerializedName("role")val role : String?
){
constructor(
login: String,
email : String,
password: String,
role : String
) : this(null, login,email,password,role)
}
fun UserDto.toUser(): User = User(
id,
login?:"", email?:"", password?:"", role?:"")
fun User.toUserDto(): UserDto = UserDto(
uid,
login, email, password, role
)

View File

@ -5,50 +5,32 @@ import android.view.LayoutInflater
import android.view.View
import android.view.ViewGroup
import android.widget.TextView
import androidx.paging.PagingDataAdapter
import androidx.recyclerview.widget.DiffUtil
import androidx.recyclerview.widget.RecyclerView
import com.example.pizza.Model.Basket.PizzaBasket
import com.example.pizza.Model.Order.Order
import com.example.pizza.Model.Order.PizzaOrder
import com.example.pizza.R
import java.text.SimpleDateFormat
import java.util.Objects
class HistoryAdapter(var context: Context,
diffUtil: DiffUtil.ItemCallback<PizzaOrder> = HistoryAdapter.OrderComparator()
) : PagingDataAdapter<PizzaOrder, HistoryAdapter.MyViewHolder>(diffUtil) {
class HistoryAdapter(var orders: List<PizzaOrder>, var context: Context) : RecyclerView.Adapter<HistoryAdapter.MyViewHolder>() {
class MyViewHolder(view: View) : RecyclerView.ViewHolder(view){
val date: TextView = view.findViewById(R.id.date_order)
val pizzas: TextView = view.findViewById(R.id.pizza_order)
val price: TextView = view.findViewById(R.id.price_order)
}
class OrderComparator : DiffUtil.ItemCallback<PizzaOrder>() {
override fun areItemsTheSame(oldItem: PizzaOrder, newItem: PizzaOrder): Boolean {
return Objects.equals(oldItem.date.toString()+ oldItem.pizzas, newItem.date.toString() + newItem.pizzas)
}
override fun areContentsTheSame(oldItem: PizzaOrder, newItem: PizzaOrder): Boolean {
return Objects.equals(oldItem.date.toString() + oldItem.pizzas, newItem.date.toString() + newItem.pizzas)
}
}
override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): MyViewHolder {
val view = LayoutInflater.from(parent.context).inflate(R.layout.history_list,parent,false)
return MyViewHolder(view)
}
override fun getItemCount(): Int {
return orders.count()
}
override fun onBindViewHolder(holder: MyViewHolder, position: Int) {
val pizza = getItem(position)
pizza?.let{
val sdf = SimpleDateFormat("dd.M.yyyy")
holder.date.text = sdf.format(it.date)
holder.pizzas.text = it.pizzas
holder.price.text = it.price.toString()
}
holder.date.text = orders[position].date
holder.pizzas.text = orders[position].pizzas
holder.price.text = orders[position].price.toString()
}
}

View File

@ -1,18 +0,0 @@
package com.example.pizza.Model.Order
import android.graphics.Bitmap
import android.graphics.BitmapFactory
import androidx.room.TypeConverter
import java.io.ByteArrayOutputStream
import java.util.Date
class DateConverter {
@TypeConverter
fun getLongFromDate(time: Date): Long {
return time.time
}
@TypeConverter
fun getDateFromLong(data: Long): Date {
return Date(data)
}
}

View File

@ -5,8 +5,6 @@ import androidx.room.Entity
import androidx.room.ForeignKey
import androidx.room.Ignore
import androidx.room.PrimaryKey
import androidx.room.TypeConverters
import com.example.pizza.Model.Pizza.ImageConverter
import com.example.pizza.Model.Pizza.Pizza
import com.example.pizza.Model.User.User
import java.util.Date
@ -17,25 +15,24 @@ import java.util.Date
entity = Pizza::class,
parentColumns = ["uid"],
childColumns = ["pizza_id"],
onDelete = ForeignKey.CASCADE,
onUpdate = ForeignKey.CASCADE),
onDelete = ForeignKey.RESTRICT,
onUpdate = ForeignKey.RESTRICT),
ForeignKey(
entity = User::class,
parentColumns = ["uid"],
childColumns = ["user_id"],
onDelete = ForeignKey.CASCADE,
onUpdate = ForeignKey.CASCADE),
onDelete = ForeignKey.RESTRICT,
onUpdate = ForeignKey.RESTRICT),
])
@TypeConverters(DateConverter::class)
class Order(
@PrimaryKey(autoGenerate = true)
val uid : Int?,
@ColumnInfo(name = "date")
val date: Date,
val date: String,
@ColumnInfo(name = "pizza_id", index = true)
val pizza: Int ,
val pizza: Int? ,
@ColumnInfo(name = "user_id", index = true)
val user: Int ,
val user: Int? ,
val price : Int ) {
@Ignore
constructor(
@ -43,7 +40,7 @@ class Order(
Pizza : Pizza,
User : User,
Price : Int
) : this(null , Date, Pizza.uid!!, User.uid!!, Price)
) : this(null , Date.toString(), Pizza.uid, User.uid, Price)
override fun equals(other: Any?): Boolean {
if (this === other) return true
if (javaClass != other?.javaClass) return false

View File

@ -1,10 +1,8 @@
package com.example.pizza.Model.Order
import androidx.paging.rxjava3.RxPagingSource
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 com.example.pizza.Model.Basket.Basket
@ -13,21 +11,20 @@ import io.reactivex.rxjava3.core.Flowable
@Dao
interface OrderDao {
@Query("select orders.date as date, group_concat(pizzas.pizza_title) as pizzas, Sum(orders.price) as price from orders" +
" join pizzas on orders.pizza_id = pizzas.uid where orders.user_id = :uid group by orders.date ")
fun getUserHistory(uid: Int): Flowable<List<PizzaOrder>>
// @Query("select orders.date as date, group_concat(pizzas.pizza_title) as pizzas, Sum(orders.price) as price from orders" +
// " join pizzas on orders.pizza_id = pizzas.uid where orders.user_id = :uid group by orders.date order by orders.date desc")
@Query("select orders.uid as uid, orders.date as date, pizzas.pizza_title as pizzas, orders.price as price from orders" +
" join pizzas on orders.pizza_id = pizzas.uid where orders.user_id = :uid ")
fun getUserHistory(uid: Int): RxPagingSource<Int, PizzaOrder>
@Query("select * from orders")
fun getAll(): Flowable<List<Order>>
@Insert
fun insert(group: Order): Completable
@Delete
fun delete(group: Order): Completable
@Query("DELETE FROM orders")
fun deleteAll(): Completable
@Insert
fun insertAll(group: List<Order>): Completable
fun insertMany(group: List<Order>): Completable
@Update
fun update(group: Order): Completable
@Delete
fun delete(group: Order): Completable
}

View File

@ -1,6 +1,4 @@
package com.example.pizza.Model.Order
import java.util.Date
class PizzaOrder(val uid: Int,val date: Date, val pizzas : String, val price : Int) {
class PizzaOrder(val date: String, val pizzas : String, val price : Int) {
}

View File

@ -7,21 +7,20 @@ import android.view.View
import android.view.ViewGroup
import android.widget.Button
import android.widget.TextView
import androidx.lifecycle.LiveData
import androidx.lifecycle.map
import androidx.paging.PagingData
import androidx.paging.PagingDataAdapter
import androidx.recyclerview.widget.DiffUtil
import androidx.recyclerview.widget.RecyclerView
import com.example.pizza.Model.Basket.Basket
import com.example.pizza.Model.Basket.BasketDao
import com.example.pizza.Model.Basket.PizzaBasket
import com.example.pizza.Model.Order.Order
import com.example.pizza.Model.Pizza.Pizza
import com.example.pizza.R
import com.example.pizza.ViewModels.BasketListViewModel
import java.util.Objects
class OrderAdapter( var context: Context, val resSum: TextView, val basketVm : BasketListViewModel,
diffUtil: DiffUtil.ItemCallback<PizzaBasket> = OrderAdapter.PizzaComparator()
) : PagingDataAdapter<PizzaBasket, OrderAdapter.MyViewHolder>(diffUtil) {
import com.example.pizza.database.AppDatabase
import io.reactivex.rxjava3.android.schedulers.AndroidSchedulers
import io.reactivex.rxjava3.schedulers.Schedulers
import kotlinx.coroutines.flow.combineTransform
import java.util.function.ToIntFunction
class OrderAdapter(var orders: List<PizzaBasket>, var context: Context, val resSum: TextView ) : RecyclerView.Adapter<OrderAdapter.MyViewHolder>() {
class MyViewHolder(view: View) : RecyclerView.ViewHolder(view) {
val title: TextView = view.findViewById(R.id.order_title)
val btnP: TextView = view.findViewById(R.id.plus)
@ -30,75 +29,51 @@ class OrderAdapter( var context: Context, val resSum: TextView, val basketVm : B
val sum: TextView = view.findViewById(R.id.order_sum)
val btnTrash : Button = view.findViewById(R.id.button_trash)
}
override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): MyViewHolder {
val view = LayoutInflater.from(parent.context).inflate(R.layout.table_order, parent, false)
return MyViewHolder(view)
}
class PizzaComparator : DiffUtil.ItemCallback<PizzaBasket>() {
override fun areItemsTheSame(oldItem: PizzaBasket, newItem: PizzaBasket): Boolean {
return Objects.equals(oldItem.pizza_id, newItem.pizza_id)
}
override fun areContentsTheSame(oldItem: PizzaBasket, newItem: PizzaBasket): Boolean {
return Objects.equals(oldItem.pizza_id, newItem.pizza_id)
}
override fun getItemCount(): Int {
return orders.count()
}
override fun onBindViewHolder(holder: MyViewHolder, position: Int) {
val pizza = getItem(position)
pizza?.let{
holder.btnM.setOnClickListener{btnMinus(holder,position)}
holder.btnP.setOnClickListener{btnPlus(holder,position)}
holder.title.text = it.pizza_title
holder.count.text = it.count_pizza.toString()
holder.sum.text = it.pizza_price.toString()
resSum.text = (resSum.text.toString().toInt() + it.pizza_price).toString()
holder.btnTrash.setOnClickListener{deleteFromBasket(holder,pizza.user_id,pizza.pizza_id,pizza.pizza_price)}
}
holder.btnM.setOnClickListener{btnMinus(holder,position)}
holder.btnP.setOnClickListener{btnPlus(holder,position)}
holder.title.text = orders[position].pizza_title
holder.count.text = orders[position].count_pizza.toString()
holder.sum.text = orders[position].pizza_price.toString()
resSum.text = (resSum.text.toString().toInt() + orders[position].pizza_price).toString()
holder.btnTrash.setOnClickListener{deleteFromBasket(holder,position)}
}
public fun getItemFromPosition(position: Int): PizzaBasket? {
return getItem(position)
}
@SuppressLint("SetTextI18n")
fun btnPlus(holder:MyViewHolder, position: Int){
val pizza = getItem(position)
pizza?.let {
var count = holder.count.text.toString().toInt()
count++
holder.count.text = count.toString()
holder.sum.text = (count * it.pizza_price).toString()
resSum.text = (resSum.text.toString().toInt() + it.pizza_price).toString() }
fun btnPlus(holder:MyViewHolder,position: Int){
var count = holder.count.text.toString().toInt()
count++
holder.count.text = count.toString()
holder.sum.text = (count * orders[position].pizza_price).toString()
resSum.text = (resSum.text.toString().toInt() + orders[position].pizza_price).toString()
}
fun btnMinus(holder:MyViewHolder,position: Int){
val pizza = getItem(position)
pizza?.let {
var count = holder.count.text.toString().toInt()
if(count == 0)
return
count--
holder.count.text = count.toString()
holder.sum.text = (count * it.pizza_price).toString()
resSum.text = (resSum.text.toString().toInt() - it.pizza_price).toString()
}
var count = holder.count.text.toString().toInt()
if(count == 0)
return
count--
holder.count.text = count.toString()
holder.sum.text = (count * orders[position].pizza_price).toString()
resSum.text = (resSum.text.toString().toInt() - orders[position].pizza_price).toString()
}
@SuppressLint("CheckResult", "NotifyDataSetChanged")
fun deleteFromBasket(holder: OrderAdapter.MyViewHolder, uid:Int,pid:Int,price:Int){
val count = holder.count.text.toString().toInt()
val sum = price*count
basketVm.deletePizza(uid,pid)
{
val oldSum = resSum.text.toString().toInt()
val newSum = oldSum - sum
resSum.text = newSum.toString()
}
@SuppressLint("CheckResult")
fun deleteFromBasket(holder: OrderAdapter.MyViewHolder, position: Int){
val basketDao : BasketDao? = context?.let { AppDatabase.getInstance(it).basketDao() }
basketDao?.deleteByUserAndPizza(orders[position].user_id,orders[position].pizza_id)?.subscribeOn(Schedulers.io())
?.observeOn(AndroidSchedulers.mainThread())
?.doOnComplete({})
?.doOnError({})
?.onErrorComplete()
?.subscribe({resSum.text = "0"} )
}
}

View File

@ -12,7 +12,7 @@ class ImageConverter {
@TypeConverter
fun getByteArrayFromBitmap(bitmap: Bitmap): ByteArray {
val outputStream = ByteArrayOutputStream()
bitmap.compress(Bitmap.CompressFormat.PNG, 100, outputStream)
bitmap.compress(Bitmap.CompressFormat.PNG, 70, outputStream)
return outputStream.toByteArray()
}
@TypeConverter

View File

@ -13,13 +13,13 @@ class Pizza(
@PrimaryKey(autoGenerate = true)
val uid: Int?,
@ColumnInfo(name = "pizza_title")
var title:String,
val title:String,
var image : Bitmap?,
val image : Bitmap?,
@ColumnInfo(name = "pizza_ingredients")
var ingredients: String,
val ingredients: String,
@ColumnInfo(name = "pizza_price")
var price: Int
val price: Int
){
@Ignore
constructor(

View File

@ -1,6 +1,5 @@
package com.example.pizza.Model.Pizza
import androidx.paging.rxjava3.RxPagingSource
import androidx.room.Dao
import androidx.room.Delete
import androidx.room.Insert
@ -15,21 +14,13 @@ import io.reactivex.rxjava3.core.Single
@Dao
interface PizzaDao {
@Query("select * from pizzas")
fun getAll(): RxPagingSource<Int, Pizza>
@Query("select * from pizzas where pizzas.uid = :uid")
fun getById(uid : Int): Single<Pizza>
fun getAll(): Flowable<List<Pizza>>
@Insert(onConflict = OnConflictStrategy.REPLACE)
fun insert(group: Pizza): Completable
@Insert
fun insertAll(group: List<Pizza>): Completable
@Update
fun update(group: Pizza): Completable
@Delete
fun delete(group: Pizza): Completable
@Query("DELETE FROM pizzas")
fun deleteAll(): Completable
}

View File

@ -10,28 +10,20 @@ import android.widget.Button
import android.widget.ImageView
import android.widget.TextView
import android.widget.Toast
import androidx.navigation.Navigation
import androidx.paging.PagingDataAdapter
import androidx.recyclerview.widget.DiffUtil
import androidx.recyclerview.widget.RecyclerView
import com.example.pizza.ListPizzaDirections
import com.example.pizza.Model.Basket.Basket
import com.example.pizza.Model.Basket.BasketDao
import com.example.pizza.Model.Pizza.Pizza
import com.example.pizza.Model.Pizza.PizzaDao
import com.example.pizza.Model.User.User
import com.example.pizza.R
import com.example.pizza.ViewModels.BasketEditViewModel
import com.example.pizza.ViewModels.BasketListViewModel
import com.example.pizza.database.AppDatabase
import io.reactivex.rxjava3.android.schedulers.AndroidSchedulers
import io.reactivex.rxjava3.core.Single
import io.reactivex.rxjava3.schedulers.Schedulers
import java.util.Objects
class PizzaAdapter(var context: Context,
var user : Int, val basketVm : BasketEditViewModel, var onClick: (id : Int) -> Unit,
diffUtil: DiffUtil.ItemCallback<Pizza> = PizzaComparator(), var onSave: () -> Unit) : PagingDataAdapter<Pizza, PizzaAdapter.MyViewHolder>(diffUtil) {
class PizzaAdapter(var pizzas: List<Pizza>, var context: Context, var user : Int) : RecyclerView.Adapter<PizzaAdapter.MyViewHolder>() {
val basketDao : BasketDao? = context?.let { AppDatabase.getInstance(it).basketDao() }
class MyViewHolder(view: View) : RecyclerView.ViewHolder(view){
val image: ImageView = view.findViewById(R.id.pizza_list_image)
val title: TextView = view.findViewById(R.id.pizza_list_title)
@ -40,36 +32,30 @@ class PizzaAdapter(var context: Context,
val btn : Button = view.findViewById(R.id.item_list_botton)
}
class PizzaComparator : DiffUtil.ItemCallback<Pizza>() {
override fun areItemsTheSame(oldItem: Pizza, newItem: Pizza): Boolean {
return Objects.equals(oldItem.uid, newItem.uid)
}
override fun areContentsTheSame(oldItem: Pizza, newItem: Pizza): Boolean {
return Objects.equals(oldItem, newItem)
}
}
override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): MyViewHolder {
val view = LayoutInflater.from(parent.context).inflate(R.layout.pizza_in_list,parent,false)
return MyViewHolder(view)
}
override fun getItemCount(): Int {
return pizzas.count()
}
override fun onBindViewHolder(holder: MyViewHolder, position: Int) {
val pizza = getItem(position)
pizza?.let { currentPizza ->
holder.title.text = currentPizza.title
holder.ingredients.text = currentPizza.ingredients.toString()
holder.price.text = currentPizza.price.toString()
holder.image.setImageBitmap(currentPizza.image)
holder.btn.setOnClickListener { addToBasket(holder, position) }
holder.image.setOnClickListener{ onClick(pizza.uid!!) }
}
holder.title.text = pizzas[position].title
holder.ingredients.text = pizzas[position].ingredients.toString()
holder.price.text = pizzas[position].price.toString()
holder.image.setImageBitmap(pizzas[position].image)
holder.btn.setOnClickListener { addToBasket(holder, position) }
}
fun addToBasket(holder: PizzaAdapter.MyViewHolder, position: Int){
val currentPizza = getItem(position)
val pizza = Basket(user,currentPizza?.uid!!,1)
basketVm.savePizza(pizza){onSave}
val pizza : Basket = Basket(user,pizzas[position].uid!!,1)
basketDao?.insert(pizza)?.subscribeOn(Schedulers.io())
?.observeOn(AndroidSchedulers.mainThread())
?.doOnComplete({})
?.doOnError({})
?.onErrorComplete()
?.subscribe()
}
}

View File

@ -1,19 +0,0 @@
package com.example.pizza.Model.Repository
import androidx.paging.rxjava3.RxPagingSource
import com.example.pizza.Model.Basket.Basket
import com.example.pizza.Model.Basket.PizzaBasket
import io.reactivex.rxjava3.core.Completable
import io.reactivex.rxjava3.core.Flowable
interface BasketRepository {
fun getUserBasket(uid: Int): Flowable<List<PizzaBasket>>
fun insert(group: Basket): Completable
fun getUserAllBasket(uid: Int): Flowable<List<PizzaBasket>>
fun update(group: Basket): Completable
fun delete(group: Basket): Completable
fun deleteByUser(uid : Int): Completable
fun deleteByUserAndPizza(uid : Int, pid:Int): Completable
}

View File

@ -1,26 +0,0 @@
package com.example.pizza.Model.Repository
import androidx.paging.rxjava3.RxPagingSource
import com.example.pizza.Model.Basket.Basket
import com.example.pizza.Model.Basket.BasketDao
import com.example.pizza.Model.Basket.PizzaBasket
import com.example.pizza.Model.Pizza.PizzaDao
import io.reactivex.rxjava3.core.Completable
import io.reactivex.rxjava3.core.Flowable
class OfflineBasketRepository(private val basketDao : BasketDao) : BasketRepository {
override fun getUserBasket(uid: Int): Flowable<List<PizzaBasket>> = basketDao.getUserBasket(uid)
override fun getUserAllBasket(uid: Int): Flowable<List<PizzaBasket>> = basketDao.getUserAllBasket(uid)
override fun insert(group: Basket): Completable = basketDao.insert(group)
fun insertAll(group: List<Basket>): Completable = basketDao.insertAll(group)
override fun update(group: Basket): Completable = basketDao.update(group)
override fun delete(group: Basket): Completable = basketDao.delete(group)
override fun deleteByUser(uid: Int): Completable = basketDao.deleteByUser(uid)
fun deleteAll(): Completable = basketDao.deleteAll()
override fun deleteByUserAndPizza(uid: Int, pid: Int): Completable = basketDao.deleteByUserAndPizza(uid,pid)
}

View File

@ -1,18 +0,0 @@
package com.example.pizza.Model.Repository
import androidx.paging.rxjava3.RxPagingSource
import com.example.pizza.Model.Basket.BasketDao
import com.example.pizza.Model.Order.Order
import com.example.pizza.Model.Order.OrderDao
import com.example.pizza.Model.Order.PizzaOrder
import io.reactivex.rxjava3.core.Completable
class OfflineOrderRepository(private val orderDao: OrderDao) : OrderRepository {
override fun getUserHistory(uid: Int): RxPagingSource<Int, PizzaOrder> = orderDao.getUserHistory(uid)
override fun insert(group: Order): Completable = orderDao.insert(group)
override fun insertAll(group: List<Order>): Completable = orderDao.insertAll(group)
fun delete(group: Order): Completable = orderDao.delete(group)
fun deleteAll(): Completable = orderDao.deleteAll()
}

View File

@ -1,21 +0,0 @@
package com.example.pizza.Model.Repository
import androidx.paging.rxjava3.RxPagingSource
import com.example.pizza.Model.Pizza.Pizza
import com.example.pizza.Model.Pizza.PizzaDao
import io.reactivex.rxjava3.core.Completable
import io.reactivex.rxjava3.core.Single
class OfflinePizzaRepository(private val pizzaDao : PizzaDao) : PizzaRepository {
override fun getAll(): RxPagingSource<Int, Pizza> = pizzaDao.getAll()
override fun getById(uid: Int): Single<Pizza> = pizzaDao.getById(uid)
override fun insert(group: Pizza): Completable = pizzaDao.insert(group)
override fun update(group: Pizza): Completable = pizzaDao.update(group)
override fun delete(group: Pizza): Completable = pizzaDao.delete(group)
override fun deleteAll(): Completable = pizzaDao.deleteAll()
override fun insertAll(pizzas: List<Pizza>): Completable = pizzaDao.insertAll(pizzas)
}

View File

@ -1,24 +0,0 @@
package com.example.pizza.Model.Repository
import com.example.pizza.Model.Pizza.PizzaDao
import com.example.pizza.Model.User.User
import com.example.pizza.Model.User.UserDao
import io.reactivex.rxjava3.core.Completable
import io.reactivex.rxjava3.core.Flowable
import io.reactivex.rxjava3.core.Maybe
import io.reactivex.rxjava3.core.Single
class OfflineUserRepository(private val userDao : UserDao) : UserRepository {
override fun getById(uid: Int): Single<User> = userDao.getById(uid)
fun getAll(): Flowable<List<User>> = throw Exception()
override fun getByLoginAndPassword(login: String, pass: String): Single<User> = userDao.getByLoginAndPassword(login,pass)
override fun insert(group: User): Completable = userDao.insert(group)
fun deleteAll(): Completable = userDao.deleteAll()
override fun update(group: User): Completable = userDao.update(group)
override fun delete(group: User): Completable = userDao.delete(group)
}

View File

@ -1,15 +0,0 @@
package com.example.pizza.Model.Repository
import androidx.paging.rxjava3.RxPagingSource
import com.example.pizza.Model.Order.Order
import com.example.pizza.Model.Order.PizzaOrder
import io.reactivex.rxjava3.core.Completable
interface OrderRepository {
fun getUserHistory(uid: Int): RxPagingSource<Int, PizzaOrder>
fun insert(group: Order): Completable
fun insertAll(group: List<Order>): Completable
}

View File

@ -1,16 +0,0 @@
package com.example.pizza.Model.Repository
import androidx.paging.rxjava3.RxPagingSource
import com.example.pizza.Model.Pizza.Pizza
import io.reactivex.rxjava3.core.Completable
import io.reactivex.rxjava3.core.Single
interface PizzaRepository {
fun getAll(): RxPagingSource<Int, Pizza>
fun getById(uid : Int): Single<Pizza>
fun insert(group: Pizza): Completable
fun update(group: Pizza): Completable
fun delete(group: Pizza): Completable
fun deleteAll() : Completable
fun insertAll(pizzas: List<Pizza>) : Completable
}

View File

@ -1,163 +0,0 @@
package com.example.pizza.Model.Repository.Rest.Mediators
import android.annotation.SuppressLint
import android.os.Build
import android.util.Log
import androidx.annotation.RequiresApi
import androidx.lifecycle.LiveData
import androidx.paging.ExperimentalPagingApi
import androidx.paging.LoadType
import androidx.paging.PagingState
import androidx.paging.RemoteMediator
import androidx.paging.rxjava3.RxRemoteMediator
import com.example.pizza.Model.Dto.UserDto
import com.example.pizza.Model.Dto.toOrder
import com.example.pizza.Model.Dto.toPizza
import com.example.pizza.Model.Dto.toUser
import com.example.pizza.Model.Order.Order
import com.example.pizza.Model.Order.PizzaOrder
import com.example.pizza.Model.Pizza.Pizza
import com.example.pizza.Model.Repository.OfflineOrderRepository
import com.example.pizza.Model.Repository.OfflinePizzaRepository
import com.example.pizza.Model.Repository.OfflineUserRepository
import com.example.pizza.Model.Rest.MyServerService
import com.example.pizza.RemoteKeys.OfflineRemoteKeyRepository
import com.example.pizza.RemoteKeys.RemoteKeyType
import com.example.pizza.RemoteKeys.RemoteKeys
import com.example.pizza.database.AppDatabase
import io.reactivex.rxjava3.core.Flowable
import io.reactivex.rxjava3.core.Maybe
import io.reactivex.rxjava3.core.Observable
import io.reactivex.rxjava3.core.Single
import io.reactivex.rxjava3.schedulers.Schedulers
import java.io.InvalidObjectException
import java.util.concurrent.atomic.AtomicInteger
@OptIn(ExperimentalPagingApi::class)
class OrderRemoteMediator(
private val service: MyServerService,
private val dbOrderRepository: OfflineOrderRepository,
private val dbPizzaRepository: OfflinePizzaRepository,
private val dbRemoteKeyRepository: OfflineRemoteKeyRepository,
private val database: AppDatabase,
private val id : Int
): RxRemoteMediator<Int, PizzaOrder>() {
@RequiresApi(Build.VERSION_CODES.O)
override fun loadSingle(
loadType: LoadType,
state: PagingState<Int, PizzaOrder>
): Single<MediatorResult> {
Log.d(this::class.simpleName, state.toString())
return when (loadType){
LoadType.REFRESH -> getRemoteKeyClosestToCurrentPosition(state).subscribeOn(Schedulers.io()).toSingle().map{
Log.d("StudentRemoteMediator", "Refresh" + it.toString())
val page = AtomicInteger(it?.nextKey?.minus(1)?:1)
getMediatorResout(loadType,page,state).blockingGet()
}.onErrorReturn {
data -> Log.d(this::class.simpleName, data.message?:"not message this")
getMediatorResout(loadType, AtomicInteger(1),state).blockingGet() }
LoadType.PREPEND ->
getRemoteKeyForFirstItem(state).subscribeOn(Schedulers.io()).toSingle().map {
Log.d("StudentRemoteMediator", "PREPEND" + it.toString())
if(it?.prevKey != null) {
getMediatorResout(loadType, AtomicInteger(it.prevKey),state).blockingGet()
}
else {
MediatorResult.Success(endOfPaginationReached = it != null)
}
}.onErrorReturn{
data ->Log.d("StudentRemoteMediator", data.message?:"not message this")
MediatorResult.Success(false)}
LoadType.APPEND ->
getRemoteKeyForLastItem(state).subscribeOn(Schedulers.io()).toSingle().map{
Log.d("StudentRemoteMediator", "APPEND" + it.toString())
Log.d(this::class.simpleName, "trying to load more")
if(it?.nextKey != null) {
getMediatorResout(loadType,AtomicInteger(it.nextKey),state).blockingGet()
}
else {
MediatorResult.Success(endOfPaginationReached = it != null)
}
}
.onErrorReturn{
data ->
Log.d(this::class.simpleName, data.message?:"not message this")
MediatorResult.Success(false)}
}
}
@SuppressLint("CheckResult")
@RequiresApi(Build.VERSION_CODES.O)
fun getMediatorResout(loadType: LoadType, page : AtomicInteger, state: PagingState<Int, PizzaOrder>)
: Single<MediatorResult> {
Log.d(OrderRemoteMediator::class.simpleName,"Load")
return service.getAllPizzas()
.subscribeOn(Schedulers.io())
.map {
if(loadType == LoadType.REFRESH){
database.runInTransaction {
dbPizzaRepository.deleteAll().blockingAwait()
Log.d(OrderRemoteMediator::class.simpleName,"pizzas deleted")
dbPizzaRepository.insertAll(it.map { it.toPizza() }).blockingAwait()
Log.d(OrderRemoteMediator::class.simpleName,"pizzas loaded ${it.size}")
}
}
}
.flatMap { service.getUserOrders(id,state.config.pageSize,(page.get()-1)*state.config.pageSize) }
.map{
database.runInTransaction {
if(loadType == LoadType.REFRESH) {
dbOrderRepository.deleteAll().blockingAwait()
dbRemoteKeyRepository.deleteRemoteKey(RemoteKeyType.ORDER).blockingAwait()
Log.d(OrderRemoteMediator::class.simpleName,"orders deleted")
}
Log.d(OrderRemoteMediator::class.simpleName,"start load orders")
dbOrderRepository.insertAll(it.map { it.toOrder() }).blockingAwait()
val prevKey = if (page.get() == 1) null else page.get() - 1
val nextKey = if (it.isEmpty()) null else page.get() + 1
val keys = it.map {
RemoteKeys(
entityId = it.uid!!,
type = RemoteKeyType.ORDER,
prevKey = prevKey,
nextKey = nextKey
)
}
dbRemoteKeyRepository.createRemoteKeys(keys).blockingAwait()
}
MediatorResult.Success(it.isEmpty()) as MediatorResult
}.singleOrError()
.onErrorResumeNext {
e->
Single.just(MediatorResult.Error(e) as MediatorResult)
}
}
private fun getRemoteKeyForLastItem(state: PagingState<Int, PizzaOrder>): Maybe<RemoteKeys> {
return state.pages.lastOrNull { it.data.isNotEmpty() }?.data?.lastOrNull()
?.let { group ->
dbRemoteKeyRepository.getAllRemoteKeys(group.uid!!, RemoteKeyType.ORDER)
} ?: Maybe.empty()
}
private fun getRemoteKeyForFirstItem(state: PagingState<Int, PizzaOrder>): Maybe<RemoteKeys> {
return state.pages.firstOrNull { it.data.isNotEmpty() }?.data?.firstOrNull()
?.let { group ->
dbRemoteKeyRepository.getAllRemoteKeys(group.uid!!, RemoteKeyType.ORDER)
}?: Maybe.empty()
}
private fun getRemoteKeyClosestToCurrentPosition( state: PagingState<Int, PizzaOrder>): Maybe<RemoteKeys> {
return state.anchorPosition?.let { position ->
state.closestItemToPosition(position)?.uid?.let { studentUid ->
dbRemoteKeyRepository.getAllRemoteKeys(studentUid, RemoteKeyType.ORDER)
}
}?: Maybe.empty()
}
}

View File

@ -1,140 +0,0 @@
package com.example.pizza.Model.Repository.Rest.Mediators
import android.annotation.SuppressLint
import android.os.Build
import android.util.Log
import androidx.annotation.RequiresApi
import androidx.paging.ExperimentalPagingApi
import androidx.paging.LoadType
import androidx.paging.PagingState
import androidx.paging.RemoteMediator
import androidx.paging.rxjava3.RxRemoteMediator
import com.example.pizza.Model.Dto.PizzaDto
import com.example.pizza.Model.Dto.toPizza
import com.example.pizza.Model.Pizza.Pizza
import com.example.pizza.Model.Repository.OfflinePizzaRepository
import com.example.pizza.Model.Repository.OfflineUserRepository
import com.example.pizza.Model.Rest.MyServerService
import com.example.pizza.Model.User.User
import com.example.pizza.RemoteKeys.OfflineRemoteKeyRepository
import com.example.pizza.RemoteKeys.RemoteKeyType
import com.example.pizza.RemoteKeys.RemoteKeys
import com.example.pizza.database.AppDatabase
import io.reactivex.rxjava3.android.schedulers.AndroidSchedulers
import io.reactivex.rxjava3.core.Maybe
import io.reactivex.rxjava3.core.Observable
import io.reactivex.rxjava3.core.Single
import io.reactivex.rxjava3.schedulers.Schedulers
import java.io.InvalidObjectException
import java.util.concurrent.atomic.AtomicInteger
@OptIn(ExperimentalPagingApi::class)
class PizzaRemoteMediator(
private val service: MyServerService,
private val dbPizzaRepository: OfflinePizzaRepository,
private val dbRemoteKeyRepository: OfflineRemoteKeyRepository,
private val database: AppDatabase
) : RxRemoteMediator<Int, Pizza>(){
@RequiresApi(Build.VERSION_CODES.O)
override fun loadSingle(
loadType: LoadType,
state: PagingState<Int, Pizza>
): Single<MediatorResult> {
Log.d(this::class.simpleName, state.toString())
return when (loadType){
LoadType.REFRESH -> getRemoteKeyClosestToCurrentPosition(state).subscribeOn(Schedulers.io()).toSingle().map{
Log.d("StudentRemoteMediator", "Refresh" + it.toString())
val page = AtomicInteger(it?.nextKey?.minus(1)?:1)
getMediatorResout(loadType,page,state).blockingGet()
}.onErrorReturn {
data -> Log.d(this::class.simpleName, data.message?:"not message this")
getMediatorResout(loadType, AtomicInteger(1),state).blockingGet() }
LoadType.PREPEND ->
getRemoteKeyForFirstItem(state).subscribeOn(Schedulers.io()).toSingle().map {
Log.d("StudentRemoteMediator", "PREPEND" + it.toString())
if(it?.prevKey != null) {
getMediatorResout(loadType, AtomicInteger(it.prevKey),state).blockingGet()
}
else {
MediatorResult.Success(endOfPaginationReached = it != null)
}
}.onErrorReturn{
data ->Log.d("StudentRemoteMediator", data.message?:"not message this")
MediatorResult.Success(false)}
LoadType.APPEND ->
getRemoteKeyForLastItem(state).subscribeOn(Schedulers.io()).toSingle().map{
Log.d("StudentRemoteMediator", "APPEND" + it.toString())
Log.d(this::class.simpleName, "trying to load more")
if(it?.nextKey != null) {
getMediatorResout(loadType,AtomicInteger(it.nextKey),state).blockingGet()
}
else {
MediatorResult.Success(endOfPaginationReached = it != null)
}
}
.onErrorReturn{
data ->
Log.d(this::class.simpleName, data.message?:"not message this")
MediatorResult.Success(false)}
}
}
@SuppressLint("CheckResult")
@RequiresApi(Build.VERSION_CODES.O)
fun getMediatorResout(loadType: LoadType, page : AtomicInteger, state: PagingState<Int, Pizza>)
: Single<MediatorResult> {
Log.d(PizzaRemoteMediator::class.simpleName,"Load")
return service.getPizzas(state.config.pageSize,(page.get()-1)*state.config.pageSize)
.subscribeOn(Schedulers.io())
.map{
database.runInTransaction {
if(loadType == LoadType.REFRESH) {
dbPizzaRepository.deleteAll().blockingAwait()
dbRemoteKeyRepository.deleteRemoteKey(RemoteKeyType.PIZZA).blockingAwait()
}
dbPizzaRepository.insertAll(it.map { it.toPizza() }).blockingAwait()
val prevKey = if (page.get() == 1) null else page.get() - 1
val nextKey = if (it.isEmpty()) null else page.get() + 1
val keys = it.map {
RemoteKeys(
entityId = it.id!!,
type = RemoteKeyType.PIZZA,
prevKey = prevKey,
nextKey = nextKey
)
}
dbRemoteKeyRepository.createRemoteKeys(keys).blockingAwait()
}
MediatorResult.Success(it.isEmpty()) as MediatorResult
}.singleOrError()
.onErrorResumeNext {
e->
Single.just(MediatorResult.Error(e) as MediatorResult)
}
}
private fun getRemoteKeyForLastItem(state: PagingState<Int, Pizza>): Maybe<RemoteKeys> {
return state.pages.lastOrNull { it.data.isNotEmpty() }?.data?.lastOrNull()
?.let { group ->
dbRemoteKeyRepository.getAllRemoteKeys(group.uid!!, RemoteKeyType.PIZZA)
} ?: Maybe.empty()
}
private fun getRemoteKeyForFirstItem(state: PagingState<Int, Pizza>): Maybe<RemoteKeys> {
return state.pages.firstOrNull { it.data.isNotEmpty() }?.data?.firstOrNull()
?.let { group ->
dbRemoteKeyRepository.getAllRemoteKeys(group.uid!!, RemoteKeyType.PIZZA)
}?: Maybe.empty()
}
private fun getRemoteKeyClosestToCurrentPosition( state: PagingState<Int, Pizza>): Maybe<RemoteKeys> {
return state.anchorPosition?.let { position ->
state.closestItemToPosition(position)?.uid?.let { studentUid ->
dbRemoteKeyRepository.getAllRemoteKeys(studentUid, RemoteKeyType.PIZZA)
}
}?: Maybe.empty()
}
}

View File

@ -1,90 +0,0 @@
package com.example.pizza.Model.Repository.Rest
import android.annotation.SuppressLint
import android.os.Build
import android.util.Log
import androidx.annotation.RequiresApi
import androidx.lifecycle.MutableLiveData
import androidx.paging.rxjava3.RxPagingSource
import com.example.pizza.Model.Basket.Basket
import com.example.pizza.Model.Basket.PizzaBasket
import com.example.pizza.Model.Dto.BasketDto
import com.example.pizza.Model.Dto.toBasket
import com.example.pizza.Model.Dto.toBasketDto
import com.example.pizza.Model.Dto.toPizza
import com.example.pizza.Model.Dto.toUser
import com.example.pizza.Model.Dto.toUserDto
import com.example.pizza.Model.Pizza.Pizza
import com.example.pizza.Model.Repository.BasketRepository
import com.example.pizza.Model.Repository.OfflineBasketRepository
import com.example.pizza.Model.Repository.OfflinePizzaRepository
import com.example.pizza.Model.Repository.OfflineUserRepository
import com.example.pizza.Model.Rest.MyServerService
import com.example.pizza.RemoteKeys.OfflineRemoteKeyRepository
import com.example.pizza.database.AppDatabase
import io.reactivex.rxjava3.core.Completable
import io.reactivex.rxjava3.core.Flowable
import io.reactivex.rxjava3.core.Observable
import io.reactivex.rxjava3.schedulers.Schedulers
import okhttp3.internal.wait
class RestBasketRepository(private val service: MyServerService,
private val dbBasketRepository: OfflineBasketRepository,
private val dbPizzaRepository: OfflinePizzaRepository,
private val dbUserRepository: OfflineUserRepository,
private val dbRemoteKeyRepository: OfflineRemoteKeyRepository,
private val database: AppDatabase
) : BasketRepository {
@RequiresApi(Build.VERSION_CODES.O)
@SuppressLint("CheckResult")
override fun getUserBasket(uid: Int): Flowable<List<PizzaBasket>> {
Log.d("RestBasketRepository", "Insert All")
var fff = service.getAllPizzas()
.map{data ->
val ps = data.map { it.toPizza() }
database.runInTransaction{
dbPizzaRepository.deleteAll().blockingAwait()
dbPizzaRepository.insertAll(ps).blockingAwait()
Log.d("RestBasketRepository", ps.toString())
}
}
.flatMap { service.getUserBaskets(uid) }
.map{data ->
val bks = data.map { it.toBasket() }
database.runInTransaction{
dbBasketRepository.deleteAll().blockingAwait()
dbBasketRepository.insertAll(bks).blockingAwait()
Log.d("RestBasketRepository", bks.toString())
}
}
.flatMap { dbBasketRepository.getUserBasket(uid) }
return fff
}
@SuppressLint("CheckResult")
override fun insert(group: Basket): Completable = Completable.fromObservable(service.createBasket(group.toBasketDto()))
override fun getUserAllBasket(uid: Int): Flowable<List<PizzaBasket>> {
return dbBasketRepository.getUserAllBasket(uid)
}
override fun update(group: Basket): Completable = throw Exception()
override fun delete(group: Basket): Completable {
throw Exception()
}
@SuppressLint("CheckResult")
override fun deleteByUser(uid: Int): Completable {
return Completable.fromObservable(service.deleteUserBaskets(uid)).andThen { dbBasketRepository.deleteByUser(uid).blockingAwait() }
}
@SuppressLint("CheckResult")
override fun deleteByUserAndPizza(uid: Int, pid: Int): Completable {
return Completable.fromObservable( service.deleteBasket(uid, pid)).andThen {dbBasketRepository.deleteByUserAndPizza(uid, pid).blockingAwait() }
}
}

View File

@ -1,59 +0,0 @@
package com.example.pizza.Model.Repository.Rest
import android.annotation.SuppressLint
import android.os.Build
import androidx.annotation.RequiresApi
import androidx.paging.rxjava3.RxPagingSource
import androidx.room.Index
import com.example.pizza.Model.Dto.OrderDto
import com.example.pizza.Model.Dto.toOrderDto
import com.example.pizza.Model.Dto.toPizza
import com.example.pizza.Model.Order.Order
import com.example.pizza.Model.Order.PizzaOrder
import com.example.pizza.Model.Repository.OfflineOrderRepository
import com.example.pizza.Model.Repository.OfflinePizzaRepository
import com.example.pizza.Model.Repository.OfflineUserRepository
import com.example.pizza.Model.Repository.OrderRepository
import com.example.pizza.Model.Repository.Rest.Mediators.OrderRemoteMediator
import com.example.pizza.Model.Repository.Rest.Mediators.PizzaRemoteMediator
import com.example.pizza.Model.Rest.MyServerService
import com.example.pizza.RemoteKeys.OfflineRemoteKeyRepository
import com.example.pizza.database.AppDatabase
import io.reactivex.rxjava3.core.Completable
import io.reactivex.rxjava3.schedulers.Schedulers
class RestOrderRepository(private val service: MyServerService,
private val dbOrderRepository: OfflineOrderRepository,
private val dbPizzaRepository: OfflinePizzaRepository,
private val dbRemoteKeyRepository: OfflineRemoteKeyRepository,
private val database: AppDatabase
) : OrderRepository {
var mediator: OrderRemoteMediator? = null
@RequiresApi(Build.VERSION_CODES.O)
@SuppressLint("CheckResult")
override fun getUserHistory(uid: Int): RxPagingSource<Int, PizzaOrder> {
if (mediator==null){
mediator = OrderRemoteMediator(
service,
dbOrderRepository,
dbPizzaRepository,
dbRemoteKeyRepository,
database,
uid
)
}
return dbOrderRepository.getUserHistory(uid)
}
override fun insert(group: Order): Completable = Completable.fromObservable(service.createOrder(group.toOrderDto()))
override fun insertAll(group: List<Order>): Completable
{
var list = group.map{it.toOrderDto()}
return Completable.fromObservable(service.createOrders(list))
}
}

View File

@ -1,62 +0,0 @@
package com.example.pizza.Model.Repository.Rest
import android.annotation.SuppressLint
import android.os.Build
import androidx.annotation.RequiresApi
import androidx.paging.rxjava3.RxPagingSource
import com.example.pizza.Model.Dto.toPizza
import com.example.pizza.Model.Dto.toPizzaDto
import com.example.pizza.Model.Pizza.Pizza
import com.example.pizza.Model.Repository.OfflinePizzaRepository
import com.example.pizza.Model.Repository.PizzaRepository
import com.example.pizza.Model.Repository.Rest.Mediators.PizzaRemoteMediator
import com.example.pizza.Model.Rest.MyServerService
import com.example.pizza.RemoteKeys.OfflineRemoteKeyRepository
import com.example.pizza.database.AppDatabase
import io.reactivex.rxjava3.core.Completable
import io.reactivex.rxjava3.core.Single
import io.reactivex.rxjava3.schedulers.Schedulers
import java.net.ConnectException
import java.net.SocketTimeoutException
class RestPizzaRepository(
private val service: MyServerService,
private val dbPizzaRepository: OfflinePizzaRepository,
private val dbRemoteKeyRepository: OfflineRemoteKeyRepository,
private val database: AppDatabase
) : PizzaRepository{
var mediator: PizzaRemoteMediator? = null
override fun getAll(): RxPagingSource<Int, Pizza> {
if (mediator==null){
mediator = PizzaRemoteMediator(
service,
dbPizzaRepository,
dbRemoteKeyRepository,
database,
)
}
return dbPizzaRepository.getAll()
}
@RequiresApi(Build.VERSION_CODES.O)
@SuppressLint("CheckResult")
override fun getById(uid: Int): Single<Pizza> {
return service.getPizza(uid).subscribeOn(Schedulers.io()).map { it.toPizza() }
}
@RequiresApi(Build.VERSION_CODES.O)
override fun insert(group: Pizza): Completable = Completable.fromObservable(
service.createPizza(group.toPizzaDto()))
@RequiresApi(Build.VERSION_CODES.O)
override fun update(group: Pizza): Completable = Completable.fromObservable(
service.updatePizza(group.uid!!,group.toPizzaDto()))
override fun delete(group: Pizza): Completable = throw Exception()
override fun deleteAll(): Completable = throw Exception()
override fun insertAll(pizzas: List<Pizza>): Completable = throw Exception()
}

View File

@ -1,51 +0,0 @@
package com.example.pizza.Model.Repository.Rest
import android.annotation.SuppressLint
import android.util.Log
import androidx.paging.ExperimentalPagingApi
import androidx.paging.Pager
import androidx.paging.PagingConfig
import androidx.paging.PagingData
import com.example.pizza.Model.Dto.toUser
import com.example.pizza.Model.Dto.toUserDto
import com.example.pizza.Model.Repository.OfflineUserRepository
import com.example.pizza.Model.Repository.UserRepository
import com.example.pizza.Model.Rest.MyServerService
import com.example.pizza.Model.User.User
import com.example.pizza.RemoteKeys.OfflineRemoteKeyRepository
import com.example.pizza.database.AppDatabase
import io.reactivex.rxjava3.core.Completable
import io.reactivex.rxjava3.core.Flowable
import io.reactivex.rxjava3.core.Single
class RestUserRepository (
private val service: MyServerService,
private val dbUserRepository: OfflineUserRepository,
private val dbRemoteKeyRepository: OfflineRemoteKeyRepository,
private val database: AppDatabase
) : UserRepository {
@SuppressLint("CheckResult")
override fun getById(uid: Int): Single<User> = service.getUser(uid).map {
Log.d(RestUserRepository::class.simpleName ,"load user by id")
database.runInTransaction{
dbUserRepository.deleteAll().blockingAwait()
dbUserRepository.insert(it.toUser()).blockingAwait()
}
it.toUser() }
override fun getByLoginAndPassword(login: String, pass: String): Single<User> {
return service.getUserLP(login, pass).map {
Log.d(RestUserRepository::class.simpleName ,"load user by lp")
database.runInTransaction{
dbUserRepository.deleteAll().blockingAwait()
dbUserRepository.insert(it.toUser()).blockingAwait()
}
it.toUser() }
}
override fun insert(group: User): Completable = Completable.fromObservable(service.createUser(group.toUserDto()))
override fun update(group: User): Completable = Completable.fromObservable(service.updateUser(group.uid!!,group.toUserDto()))
override fun delete(group: User): Completable = Completable.fromObservable(service.updateUser(group.uid!!,group.toUserDto()))
}

View File

@ -1,21 +0,0 @@
package com.example.pizza.Model.Repository
import androidx.room.Delete
import androidx.room.Insert
import androidx.room.Query
import androidx.room.Update
import com.example.pizza.Model.User.User
import io.reactivex.rxjava3.core.Completable
import io.reactivex.rxjava3.core.Flowable
import io.reactivex.rxjava3.core.Maybe
import io.reactivex.rxjava3.core.Single
interface UserRepository {
fun getById(uid : Int): Single<User>
fun getByLoginAndPassword(login : String, pass : String): Single<User>
fun insert(group: User): Completable
fun update(group: User): Completable
fun delete(group: User): Completable
}

View File

@ -1,150 +0,0 @@
package com.example.pizza.Model.Rest
import com.example.pizza.Model.Dto.BasketDto
import com.example.pizza.Model.Dto.OrderDto
import com.example.pizza.Model.Dto.PizzaDto
import com.example.pizza.Model.Dto.UserDto
import com.google.gson.GsonBuilder
import com.jakewharton.retrofit2.converter.kotlinx.serialization.asConverterFactory
import io.reactivex.rxjava3.core.Flowable
import io.reactivex.rxjava3.core.Observable
import io.reactivex.rxjava3.core.Single
import kotlinx.serialization.json.Json
import okhttp3.MediaType.Companion.toMediaType
import okhttp3.OkHttpClient
import okhttp3.logging.HttpLoggingInterceptor
import retrofit2.Retrofit
import retrofit2.adapter.rxjava3.RxJava3CallAdapterFactory
import retrofit2.converter.gson.GsonConverterFactory
import retrofit2.http.Body
import retrofit2.http.DELETE
import retrofit2.http.Field
import retrofit2.http.GET
import retrofit2.http.POST
import retrofit2.http.PUT
import retrofit2.http.Path
import retrofit2.http.Query
interface MyServerService {
@GET("pizzas")
fun getPizzas(
@Query("limit") limit: Int,
@Query("offset") offset: Int,
): Flowable<List<PizzaDto>>
@GET("allpizzas")
fun getAllPizzas(
): Flowable<List<PizzaDto>>
@GET("baskets/{id}")
fun getUserBaskets(
@Path("id") id: Int,
): Flowable<List<BasketDto>>
@GET("pizza/{id}")
fun getPizza(
@Path("id") id: Int,
): Single<PizzaDto>
@GET("baskets")
fun getAllBaskets(
): Observable<List<BasketDto>>
@GET("orders/{id}")
fun getUserOrders(
@Path("id") id: Int,
@Query("limit") limit: Int,
@Query("offset") offset: Int,
): Flowable<List<OrderDto>>
@GET("orders")
fun getAllOrders(
): Observable<List<OrderDto>>
@GET("users")
fun getAllUsers(
): Observable<UserDto>
@GET("user/{id}")
fun getUser(
@Path("id") id: Int,
): Single<UserDto>
@GET("user")
fun getUserLP(
@Query("login") login : String ,
@Query("password") password : String
): Single<UserDto>
@POST("user")
fun createUser(
@Body user: UserDto,
): Observable<UserDto>
@POST("pizza")
fun createPizza(
@Body pizza: PizzaDto,
): Observable<PizzaDto>
@POST("basket")
fun createBasket(
@Body basket: BasketDto,
): Observable<BasketDto>
@POST("order")
fun createOrder(
@Body order: OrderDto,
): Observable<OrderDto>
@POST("orders")
fun createOrders(
@Body order: List<OrderDto>,
): Observable<OrderDto>
@PUT("user/{id}")
fun updateUser(
@Path("id") id: Int,
@Body user: UserDto,
): Observable<UserDto>
@PUT("pizza/{id}")
fun updatePizza(
@Path("id") id: Int,
@Body user: PizzaDto,
): Observable<PizzaDto>
@DELETE("baskets/{id}")
fun deleteUserBaskets(
@Path("id") id: Int,
): Observable<List<BasketDto>>
@DELETE("basket")
fun deleteBasket(
@Query("uid") uid : Int ,
@Query("pid") pid : Int
): Observable<BasketDto>
companion object {
private const val BASE_URL = "http://192.168.42.168:8080/api/"
@Volatile
private var INSTANCE: MyServerService? = null
fun getInstance(): MyServerService {
return INSTANCE ?: synchronized(this) {
val logger = HttpLoggingInterceptor()
logger.level = HttpLoggingInterceptor.Level.BASIC
val client = OkHttpClient.Builder()
.addInterceptor(logger)
.build()
val gsonBuilder = GsonBuilder()
gsonBuilder.setLenient()
val gson = gsonBuilder.create()
return Retrofit.Builder()
.baseUrl(BASE_URL)
.client(client)
//.addConverterFactory(Json.asConverterFactory("application/json".toMediaType()))
.addCallAdapterFactory(RxJava3CallAdapterFactory.create())
.addConverterFactory(GsonConverterFactory.create(gson))
//.addCallAdapterFactory(RxJavaCallAdapterFactory.create())
.build()
.create(MyServerService::class.java)
.also { INSTANCE = it }
}
}
}
}

View File

@ -12,11 +12,11 @@ data class User(
@PrimaryKey(autoGenerate = true)
public val uid: Int?,
@ColumnInfo(name = "login")
var login:String ,
val login:String ,
@ColumnInfo(name = "email")
var email : String ,
val email : String ,
@ColumnInfo(name = "password")
var password: String ,
val password: String ,
@ColumnInfo(name = "role")
val role : String ) {
@Ignore

View File

@ -7,7 +7,6 @@ import androidx.room.Query
import androidx.room.Update
import io.reactivex.rxjava3.core.Completable
import io.reactivex.rxjava3.core.Flowable
import io.reactivex.rxjava3.core.Maybe
import io.reactivex.rxjava3.core.Single
@Dao
@ -26,8 +25,7 @@ interface UserDao {
@Update
fun update(group: User): Completable
@Query("DELETE FROM users")
fun deleteAll(): Completable
@Delete
fun delete(group: User): Completable
}

View File

@ -1,21 +0,0 @@
package com.example.pizza
import android.app.Application
import androidx.lifecycle.MutableLiveData
import com.example.pizza.database.AppContainer
import com.example.pizza.database.AppDataContainer
class PizzaApplication : Application() {
lateinit var container: AppContainer
override fun onCreate() {
super.onCreate()
container = AppDataContainer(this)
}
}
operator fun <T> MutableLiveData<ArrayList<T>>.plusAssign(values: List<T>) {
val value = this.value ?: arrayListOf()
value.addAll(values)
this.value = value
}

View File

@ -12,13 +12,10 @@ import android.widget.TextView
import android.widget.Toast
import androidx.constraintlayout.widget.StateSet.TAG
import androidx.fragment.app.activityViewModels
import androidx.fragment.app.viewModels
import androidx.navigation.Navigation
import com.example.pizza.Model.PizzaAdapter
import com.example.pizza.Model.User.User
import com.example.pizza.Model.User.UserDao
import com.example.pizza.ViewModels.AppViewModelProvider
import com.example.pizza.ViewModels.UserViewModel
import com.example.pizza.database.AppDatabase
import io.reactivex.rxjava3.android.schedulers.AndroidSchedulers
import io.reactivex.rxjava3.core.Completable
@ -26,39 +23,14 @@ import io.reactivex.rxjava3.schedulers.Schedulers
class Reg : Fragment() {
private var userViewModel : UserViewModel? = null
private var editing = false
private var editUser : User? = null
val viewModel: myViewModel by activityViewModels()
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
val viewUserModel : UserViewModel by viewModels(
factoryProducer = { AppViewModelProvider.Factory}
)
userViewModel = viewUserModel
}
override fun onStart() {
super.onStart()
}
private var userDao: UserDao? = null
@SuppressLint("CheckResult")
override fun onCreateView(
inflater: LayoutInflater, container: ViewGroup?,
savedInstanceState: Bundle?
): View? {
userDao = context?.let { AppDatabase.getInstance(it).userDao() }
val view = inflater.inflate(R.layout.fragment_reg, container, false)
val args = RegArgs.fromBundle(requireArguments())
if(args.id != -1) {
editing = true
userViewModel?.getUserById(viewModel.getId()!!,{data: User ->
editUser = data
view.findViewById<TextView>(R.id.reg_user_login).text = editUser?.login
view.findViewById<TextView>(R.id.reg_user_email).text = editUser?.email
view.findViewById<TextView>(R.id.reg_user_pass).text = editUser?.password
},{})
}
view.findViewById<Button>(R.id.button_reg).setOnClickListener {buttonClick(view)}
view.findViewById<TextView>(R.id.link_to_auth).setOnClickListener{TextViewClick(view)}
@ -71,59 +43,34 @@ class Reg : Fragment() {
val login = view.findViewById<TextView>(R.id.reg_user_login)?.text.toString().trim()
val email = view.findViewById<TextView>(R.id.reg_user_email)?.text.toString().trim()
val pass = view.findViewById<TextView>(R.id.reg_user_pass)?.text.toString().trim()
val viewModel: myViewModel by activityViewModels()
if(login.length == 0 || pass.length ==0 || email.length == 0){
Toast.makeText(view.context, "Укажите данные", Toast.LENGTH_SHORT).show()
return
}
if(!editing) {
val user1 = User(login, email, pass, "user")
userViewModel?.saveUser(user1,
onSave = {
userViewModel?.getUserByLP(login, pass,
onLoad = { user: User ->
viewModel.setId(user.uid!!)
if (user.role == ("admin"))
viewModel.setRole(true)
Toast.makeText(
view.context,
"Регистрация прошла успешно",
Toast.LENGTH_SHORT
).show()
val action = RegDirections
.actionNavigationRegToNavigationPizzaList()
Navigation.findNavController(view).navigate(action)
},
onError = {
Toast.makeText(
view.context,
"Сбой Системы!!!",
Toast.LENGTH_SHORT
).show()
})
},
onError = {
Toast.makeText(view.context, "Данный логин уже занят -_-", Toast.LENGTH_SHORT)
.show()
})
}else
{
editUser?.login = login
editUser?.password = pass
editUser?.email = email
userViewModel?.updateUser(editUser!!,
onSave = {Toast.makeText(
view.context,
"Изменения успешно приняты",
Toast.LENGTH_SHORT
).show()
val action = RegDirections
.actionNavigationRegToNavigationUser()
Navigation.findNavController(view).navigate(action)},
onError = {Toast.makeText(view.context, "Данный логин уже занят -_-", Toast.LENGTH_SHORT)
.show()})
}
val user1 = User(login, email,pass, "user")
userDao?.insert(user1)?.subscribeOn(Schedulers.io())
?.observeOn(AndroidSchedulers.mainThread())
?.subscribe(
{Toast.makeText(view.context, "Регистрация прошла успешно", Toast.LENGTH_SHORT).show()
userDao?.getByLoginAndPassword(login, pass)?.subscribeOn(Schedulers.io())
?.observeOn(AndroidSchedulers.mainThread())
?.doOnSuccess({})
?.onErrorComplete()
?.subscribe { user ->
viewModel.setId(user.uid!!)
if (user.role.equals("admin"))
viewModel.setRole(true)
val action = RegDirections
.actionNavigationRegToNavigationPizzaList()
Navigation.findNavController(view).navigate(action)
}},
{Toast.makeText(view.context, "Данный логин уже занят", Toast.LENGTH_SHORT).show()}
)
}
private fun TextViewClick(view: View) {

View File

@ -1,15 +0,0 @@
package com.example.pizza.RemoteKeys
import io.reactivex.rxjava3.core.Completable
import io.reactivex.rxjava3.core.Maybe
class OfflineRemoteKeyRepository(private val remoteKeysDao: RemoteKeysDao) : RemoteKeyRepository {
override fun getAllRemoteKeys(id: Int, type: RemoteKeyType) =
remoteKeysDao.getRemoteKeys(id, type)
override fun createRemoteKeys(remoteKeys: List<RemoteKeys>) =
remoteKeysDao.insertAll(remoteKeys)
override fun deleteRemoteKey(type: RemoteKeyType) =
remoteKeysDao.clearRemoteKeys(type)
}

View File

@ -1,10 +0,0 @@
package com.example.pizza.RemoteKeys
import io.reactivex.rxjava3.core.Completable
import io.reactivex.rxjava3.core.Maybe
interface RemoteKeyRepository {
fun getAllRemoteKeys(id: Int, type: RemoteKeyType): Maybe<RemoteKeys>
fun createRemoteKeys(remoteKeys: List<RemoteKeys>) : Completable
fun deleteRemoteKey(type: RemoteKeyType) : Completable
}

View File

@ -1,32 +0,0 @@
package com.example.pizza.RemoteKeys
import androidx.room.Entity
import androidx.room.PrimaryKey
import androidx.room.TypeConverter
import androidx.room.TypeConverters
import com.example.pizza.Model.User.User
import com.example.pizza.Model.Pizza.Pizza
import com.example.pizza.Model.Basket.Basket
import com.example.pizza.Model.Order.Order
@Entity(tableName = "remote_keys")
data class RemoteKeys(
@PrimaryKey val entityId: Int,
@TypeConverters(RemoteKeyType::class)
val type: RemoteKeyType,
val prevKey: Int?,
val nextKey: Int?
)
enum class RemoteKeyType(private val type: String) {
USER(User::class.simpleName ?: "User"),
PIZZA(Pizza::class.simpleName ?: "Pizza"),
ORDER(Order::class.simpleName ?: "Order"),
BASKET(Basket::class.simpleName ?: "Basket");
@TypeConverter
fun toRemoteKeyType(value: String) = RemoteKeyType.values().first { it.type == value }
@TypeConverter
fun fromRemoteKeyType(value: RemoteKeyType) = value.type
}

View File

@ -1,20 +0,0 @@
package com.example.pizza.RemoteKeys
import androidx.room.Dao
import androidx.room.Insert
import androidx.room.OnConflictStrategy
import androidx.room.Query
import io.reactivex.rxjava3.core.Completable
import io.reactivex.rxjava3.core.Maybe
@Dao
interface RemoteKeysDao {
@Query("SELECT * FROM remote_keys WHERE entityId = :entityId AND type = :type")
fun getRemoteKeys(entityId: Int, type: RemoteKeyType): Maybe<RemoteKeys>
@Insert(onConflict = OnConflictStrategy.REPLACE)
fun insertAll(remoteKey: List<RemoteKeys>) : Completable
@Query("DELETE FROM remote_keys WHERE type = :type")
fun clearRemoteKeys(type: RemoteKeyType) : Completable
}

View File

@ -1,37 +0,0 @@
package com.example.pizza.ViewModels
import androidx.lifecycle.ViewModelProvider
import androidx.lifecycle.viewmodel.CreationExtras
import androidx.lifecycle.viewmodel.initializer
import androidx.lifecycle.viewmodel.viewModelFactory
import com.example.pizza.PizzaApplication
object AppViewModelProvider {
val Factory = viewModelFactory {
initializer {
PizzaListViewModel(studentApplication().container.pizzaRepository)
}
initializer {
PizzaEditViewModel(studentApplication().container.pizzaRepository)
}
initializer {
BasketEditViewModel(studentApplication().container.basketRepository)
}
initializer {
BasketListViewModel(studentApplication().container.basketRepository)
}
initializer {
OrderEditViewModel(studentApplication().container.orderRepository)
}
initializer {
OrderListViewModel(studentApplication().container.orderRepository)
}
initializer {
UserViewModel(studentApplication().container.userRepository)
}
}
}
fun CreationExtras.studentApplication(): PizzaApplication =
(this[ViewModelProvider.AndroidViewModelFactory.APPLICATION_KEY] as PizzaApplication)

View File

@ -1,38 +0,0 @@
package com.example.pizza.ViewModels
import androidx.lifecycle.LiveData
import androidx.lifecycle.MutableLiveData
import androidx.lifecycle.ViewModel
import com.example.pizza.Model.Basket.Basket
import com.example.pizza.Model.Basket.PizzaBasket
import com.example.pizza.Model.Pizza.Pizza
import com.example.pizza.Model.Repository.BasketRepository
import com.example.pizza.Model.Repository.PizzaRepository
import io.reactivex.rxjava3.android.schedulers.AndroidSchedulers
import io.reactivex.rxjava3.core.Completable
import io.reactivex.rxjava3.disposables.CompositeDisposable
import io.reactivex.rxjava3.schedulers.Schedulers
class BasketEditViewModel(
private val basketRepository: BasketRepository
) : ViewModel() {
private val mDisposable = CompositeDisposable()
fun savePizza(pizza: Basket, onSave: () -> Unit) {
val completable: Completable = basketRepository.insert(pizza)
val disposable = completable
.subscribeOn(Schedulers.io())
.observeOn(AndroidSchedulers.mainThread())
.doOnComplete({})
.onErrorComplete()
.subscribe(onSave)
}
override fun onCleared() {
super.onCleared()
mDisposable.clear()
}
}

View File

@ -1,80 +0,0 @@
package com.example.pizza.ViewModels
import android.annotation.SuppressLint
import androidx.lifecycle.LiveData
import androidx.lifecycle.MutableLiveData
import androidx.lifecycle.ViewModel
import androidx.lifecycle.viewModelScope
import androidx.paging.Pager
import androidx.paging.PagingConfig
import androidx.paging.PagingData
import androidx.paging.rxjava3.RxPagingSource
import androidx.paging.rxjava3.cachedIn
import androidx.paging.rxjava3.flowable
import com.example.pizza.Model.Basket.Basket
import com.example.pizza.Model.Basket.PizzaBasket
import com.example.pizza.Model.Pizza.Pizza
import com.example.pizza.Model.Repository.BasketRepository
import com.example.pizza.Model.Repository.PizzaRepository
import io.reactivex.rxjava3.android.schedulers.AndroidSchedulers
import io.reactivex.rxjava3.disposables.CompositeDisposable
import io.reactivex.rxjava3.schedulers.Schedulers
import kotlinx.coroutines.ExperimentalCoroutinesApi
class BasketListViewModel(private val basketRepository: BasketRepository): ViewModel() {
private val mDisposable = CompositeDisposable()
private val pizzas: MutableLiveData<PagingData<PizzaBasket>?> = MutableLiveData()
fun getPizzas(uid: Int ): LiveData<PagingData<PizzaBasket>?> {
if (pizzas.value == null) {
loadPizzas(uid)
}
return pizzas
}
@SuppressLint("CheckResult")
fun getAllBaskets(uid : Int, onLoad: (data : List<PizzaBasket>) -> Unit, onError: () -> Unit){
basketRepository.getUserBasket(uid)
.subscribeOn(Schedulers.io())
.observeOn(AndroidSchedulers.mainThread())
.subscribe( { data ->
onLoad(data)
},{onError()})
}
@OptIn(ExperimentalCoroutinesApi::class)
private fun loadPizzas(uid: Int) {
val disposable = basketRepository.getUserBasket(uid)
.subscribeOn(Schedulers.io())
.observeOn(AndroidSchedulers.mainThread())
.doOnError({pizzas.value = null})
.subscribe { data ->
val ps = PagingData.from<PizzaBasket>(data)
pizzas.postValue(ps)
}
mDisposable.add(disposable)
}
fun deletePizza(uid:Int, pid: Int, onDelete: () -> Unit) {
val disposable = basketRepository.deleteByUserAndPizza(uid,pid)
.subscribeOn(Schedulers.io())
.observeOn(AndroidSchedulers.mainThread())
.subscribe { onDelete() }
mDisposable.add(disposable)
}
fun deleteAllPizza(uid:Int) {
val disposable = basketRepository.deleteByUser(uid)
.subscribeOn(Schedulers.io())
.observeOn(AndroidSchedulers.mainThread())
.subscribe()
mDisposable.add(disposable)
}
override fun onCleared() {
super.onCleared()
mDisposable.clear()
}
}

View File

@ -1,35 +0,0 @@
package com.example.pizza.ViewModels
import androidx.lifecycle.ViewModel
import com.example.pizza.Model.Basket.Basket
import com.example.pizza.Model.Order.Order
import com.example.pizza.Model.Repository.BasketRepository
import com.example.pizza.Model.Repository.OrderRepository
import io.reactivex.rxjava3.android.schedulers.AndroidSchedulers
import io.reactivex.rxjava3.core.Completable
import io.reactivex.rxjava3.disposables.CompositeDisposable
import io.reactivex.rxjava3.schedulers.Schedulers
class OrderEditViewModel(
private val orderRepository: OrderRepository
) : ViewModel() {
private val mDisposable = CompositeDisposable()
fun savePizza(pizzas: List<Order>, onSave: () -> Unit) {
val completable: Completable = orderRepository.insertAll(pizzas)
val disposable = completable
.subscribeOn(Schedulers.io())
.observeOn(AndroidSchedulers.mainThread())
.doOnComplete({})
.onErrorComplete()
.subscribe(onSave)
}
override fun onCleared() {
super.onCleared()
mDisposable.clear()
}
}

View File

@ -1,64 +0,0 @@
package com.example.pizza.ViewModels
import android.os.Build
import androidx.annotation.RequiresApi
import androidx.lifecycle.LiveData
import androidx.lifecycle.MutableLiveData
import androidx.lifecycle.ViewModel
import androidx.lifecycle.viewModelScope
import androidx.paging.ExperimentalPagingApi
import androidx.paging.Pager
import androidx.paging.PagingConfig
import androidx.paging.PagingData
import androidx.paging.rxjava3.cachedIn
import androidx.paging.rxjava3.flowable
import com.example.pizza.Model.Order.PizzaOrder
import com.example.pizza.Model.Repository.OrderRepository
import com.example.pizza.Model.Repository.Rest.RestOrderRepository
import io.reactivex.rxjava3.android.schedulers.AndroidSchedulers
import io.reactivex.rxjava3.disposables.CompositeDisposable
import io.reactivex.rxjava3.schedulers.Schedulers
import kotlinx.coroutines.ExperimentalCoroutinesApi
class OrderListViewModel(private val orderRepository: OrderRepository): ViewModel() {
private val mDisposable = CompositeDisposable()
private val pizzas: MutableLiveData<PagingData<PizzaOrder>?> = MutableLiveData()
@RequiresApi(Build.VERSION_CODES.O)
fun getPizzas(uid: Int): LiveData<PagingData<PizzaOrder>?> {
loadPizzas(uid)
return pizzas
}
@OptIn(ExperimentalCoroutinesApi::class, ExperimentalPagingApi::class)
@RequiresApi(Build.VERSION_CODES.O)
private fun loadPizzas(uid: Int) {
val pageSize = 10
val placeholders = true
var config = PagingConfig(
pageSize = pageSize,
enablePlaceholders =placeholders
)
val disposable = Pager(
config = config,
pagingSourceFactory = {orderRepository.getUserHistory(uid)},
remoteMediator = (orderRepository as RestOrderRepository).mediator
).flowable
.cachedIn(viewModelScope)
.subscribeOn(Schedulers.io())
.observeOn(AndroidSchedulers.mainThread())
.doOnError({pizzas.value = null})
.subscribe { data ->
pizzas.postValue(data)
}
mDisposable.add(disposable)
}
override fun onCleared() {
super.onCleared()
mDisposable.clear()
}
}

View File

@ -1,63 +0,0 @@
package com.example.pizza.ViewModels
import androidx.databinding.BaseObservable
import androidx.databinding.Bindable
import androidx.lifecycle.LiveData
import androidx.lifecycle.MutableLiveData
import androidx.lifecycle.ViewModel
import com.example.pizza.Model.Pizza.Pizza
import com.example.pizza.Model.Repository.PizzaRepository
import io.reactivex.rxjava3.android.schedulers.AndroidSchedulers
import io.reactivex.rxjava3.core.Completable
import io.reactivex.rxjava3.disposables.CompositeDisposable
import io.reactivex.rxjava3.schedulers.Schedulers
class PizzaEditViewModel(
private val pizzaRepository: PizzaRepository
) : ViewModel() {
private val mDisposable = CompositeDisposable()
private val pizza: MutableLiveData<Pizza> = MutableLiveData()
fun getPizza(uid: Int, onSave: (data : Pizza) -> Unit): LiveData<Pizza> {
if (pizza.value == null) {
loadPizza(uid,onSave)
}
return pizza
}
private fun loadPizza(uid: Int,onSave: (data : Pizza) -> Unit) {
val disposable = pizzaRepository.getById(uid)
.subscribeOn(Schedulers.io())
.observeOn(AndroidSchedulers.mainThread())
.subscribe { data ->
pizza.postValue(data)
onSave(data)
}
mDisposable.add(disposable)
}
fun savePizza(pizza: Pizza, onSave: () -> Unit,onError: () -> Unit) {
val completable: Completable = pizzaRepository.insert(pizza)
val disposable = completable
.subscribeOn(Schedulers.io())
.observeOn(AndroidSchedulers.mainThread())
.subscribe({ onSave() },{onError()})
mDisposable.add(disposable)
}
fun updatePizza(pizza: Pizza, onSave: () -> Unit, onError: () -> Unit) {
val completable: Completable = pizzaRepository.update(pizza)
val disposable = completable
.subscribeOn(Schedulers.io())
.observeOn(AndroidSchedulers.mainThread())
.subscribe({ onSave() },{onError()})
mDisposable.add(disposable)
}
override fun onCleared() {
super.onCleared()
mDisposable.clear()
}
}

View File

@ -1,69 +0,0 @@
package com.example.pizza.ViewModels
import androidx.lifecycle.LiveData
import androidx.lifecycle.MutableLiveData
import androidx.lifecycle.ViewModel
import androidx.lifecycle.viewModelScope
import androidx.paging.ExperimentalPagingApi
import androidx.paging.Pager
import androidx.paging.PagingConfig
import androidx.paging.PagingData
import androidx.paging.rxjava3.cachedIn
import androidx.paging.rxjava3.flowable
import com.example.pizza.Model.Pizza.Pizza
import com.example.pizza.Model.Repository.PizzaRepository
import com.example.pizza.Model.Repository.Rest.RestPizzaRepository
import io.reactivex.rxjava3.android.schedulers.AndroidSchedulers
import io.reactivex.rxjava3.disposables.CompositeDisposable
import io.reactivex.rxjava3.schedulers.Schedulers
import kotlinx.coroutines.ExperimentalCoroutinesApi
class PizzaListViewModel(private val pizzaRepository: PizzaRepository): ViewModel() {
private val mDisposable = CompositeDisposable()
private val pizzas: MutableLiveData<PagingData<Pizza>> = MutableLiveData()
fun getPizzas(): LiveData<PagingData<Pizza>> {
loadPizzas()
return pizzas
}
@OptIn(ExperimentalCoroutinesApi::class, ExperimentalPagingApi::class)
private fun loadPizzas() {
var meditator = (pizzaRepository as RestPizzaRepository).mediator
var pagingSourceFactory = {pizzaRepository.getAll()}
val pageSize = 3
val placeholders = true
var config = PagingConfig(
pageSize = pageSize,
enablePlaceholders =placeholders
)
val disposable = Pager(
config = config,
pagingSourceFactory = pagingSourceFactory,
remoteMediator = meditator,
).flowable
.cachedIn(viewModelScope)
.subscribeOn(Schedulers.io())
.observeOn(AndroidSchedulers.mainThread())
.subscribe { data ->
pizzas.postValue(data)
}
mDisposable.add(disposable)
}
fun deletePizza(pizza: Pizza, onDelete: () -> Unit) {
val disposable = pizzaRepository.delete(pizza)
.subscribeOn(Schedulers.io())
.observeOn(AndroidSchedulers.mainThread())
.subscribe(onDelete)
mDisposable.add(disposable)
}
override fun onCleared() {
super.onCleared()
mDisposable.clear()
}
}

View File

@ -1,96 +0,0 @@
package com.example.pizza.ViewModels
import android.annotation.SuppressLint
import android.util.Log
import androidx.lifecycle.LiveData
import androidx.lifecycle.MutableLiveData
import androidx.lifecycle.ViewModel
import com.example.pizza.Model.Pizza.Pizza
import com.example.pizza.Model.Repository.PizzaRepository
import com.example.pizza.Model.Repository.UserRepository
import com.example.pizza.Model.User.User
import io.reactivex.rxjava3.android.schedulers.AndroidSchedulers
import io.reactivex.rxjava3.core.Completable
import io.reactivex.rxjava3.core.Observable
import io.reactivex.rxjava3.core.Single
import io.reactivex.rxjava3.disposables.CompositeDisposable
import io.reactivex.rxjava3.schedulers.Schedulers
class UserViewModel(
private val userRepository: UserRepository
) : ViewModel() {
private val mDisposable = CompositeDisposable()
private val user: MutableLiveData<User?> = MutableLiveData()
fun getUserById(uid: Int, onLoad: (data : User)-> Unit, onError: () -> Unit): LiveData<User?> {
if (user.value == null) {
loadUserById(uid,onLoad, onError)
}
return user
}
fun getUserByLP(login : String, pass : String,onLoad: (data : User) -> Unit,onError: () -> Unit): LiveData<User?> {
if (user.value == null) {
loadUserByLP(login, pass,onLoad, onError)
}
return user
}
private fun loadUserById(uid: Int,onLoad: (data : User) -> Unit, onError: () -> Unit) {
val disposable = userRepository.getById(uid)
.subscribeOn(Schedulers.io())
.observeOn(AndroidSchedulers.mainThread())
.subscribe ({ data ->
user.postValue(data)
onLoad(data)
},{onError()})
mDisposable.add(disposable)
}
@SuppressLint("SuspiciousIndentation", "CheckResult")
private fun loadUserByLP(login : String, pass : String,onLoad: (data : User) -> Unit,onError: () -> Unit) {
val disposable = userRepository.getByLoginAndPassword(login, pass)
.subscribeOn(Schedulers.io())
.observeOn(AndroidSchedulers.mainThread())
.subscribe ({ data ->
user.postValue(data)
onLoad(data)
},{onError()})
mDisposable.add(disposable)
}
@SuppressLint("CheckResult")
fun saveUser(user: User, onSave: () -> Unit, onError: () -> Unit) {
userRepository.insert(user)
.subscribeOn(Schedulers.io())
.observeOn(AndroidSchedulers.mainThread())
.subscribe ({onSave() },{ onError()})
}
@SuppressLint("CheckResult")
fun updateUser(user: User, onSave: () -> Unit, onError: () -> Unit) {
userRepository.update(user)
.subscribeOn(Schedulers.io())
.observeOn(AndroidSchedulers.mainThread())
.subscribe ({onSave() },{ onError()})
}
@SuppressLint("CheckResult")
fun deleteUser(user: User, onSave: () -> Unit, onError: () -> Unit) {
userRepository.delete(user)
.subscribeOn(Schedulers.io())
.observeOn(AndroidSchedulers.mainThread())
.subscribe ({onSave() },{ onError()})
}
override fun onCleared() {
super.onCleared()
mDisposable.clear()
}
}

View File

@ -11,9 +11,7 @@ import android.widget.TextView
import android.widget.Toast
import androidx.fragment.app.activityViewModels
import androidx.fragment.app.viewModels
import androidx.lifecycle.LiveData
import androidx.navigation.Navigation
import androidx.paging.PagingData
import androidx.recyclerview.widget.LinearLayoutManager
import androidx.recyclerview.widget.RecyclerView
import androidx.recyclerview.widget.RecyclerView.ViewHolder
@ -25,11 +23,6 @@ import com.example.pizza.Model.Order.OrderDao
import com.example.pizza.Model.OrderAdapter
import com.example.pizza.Model.Pizza.Pizza
import com.example.pizza.Model.PizzaAdapter
import com.example.pizza.ViewModels.AppViewModelProvider
import com.example.pizza.ViewModels.BasketEditViewModel
import com.example.pizza.ViewModels.BasketListViewModel
import com.example.pizza.ViewModels.OrderEditViewModel
import com.example.pizza.ViewModels.PizzaListViewModel
import com.example.pizza.database.AppDatabase
import io.reactivex.rxjava3.android.schedulers.AndroidSchedulers
import io.reactivex.rxjava3.schedulers.Schedulers
@ -38,48 +31,30 @@ import java.util.Date
class crate : Fragment() {
private var basketDao: BasketDao? = null
lateinit var itemsList : RecyclerView
private var orderAdapter : OrderAdapter? = null
lateinit var listPizzas : List<PizzaBasket>
val viewModel: myViewModel by activityViewModels()
private var orderDao : OrderDao? = null
private var basketVM : BasketListViewModel? = null
private var orderViewModel : OrderEditViewModel? = null
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
val viewModel: BasketListViewModel by viewModels(
factoryProducer = { AppViewModelProvider.Factory }
)
basketVM = viewModel
val viewModel2: OrderEditViewModel by viewModels(
factoryProducer = { AppViewModelProvider.Factory }
)
orderViewModel = viewModel2
}
override fun onStart() {
super.onStart()
val pizzas: LiveData<PagingData<PizzaBasket>?>? = basketVM?.getPizzas(viewModel.getId()!!)
pizzas?.observe(viewLifecycleOwner) { data ->
data?.let {
orderAdapter?.submitData(lifecycle, it)
}
}
}
@SuppressLint("CheckResult")
override fun onCreateView(
inflater: LayoutInflater, container: ViewGroup?,
savedInstanceState: Bundle?
): View? {
basketDao = context?.let { AppDatabase.getInstance(it).basketDao() }
orderDao = context?.let { AppDatabase.getInstance(it).orderDao() }
val view = inflater.inflate(R.layout.fragment_crate, container, false)
itemsList = view.findViewById(R.id.inOrderList)
var resSum = view.findViewById<TextView>(R.id.sum_pizzas)
val button : Button = view.findViewById<Button>(R.id.button_buy)
itemsList.layoutManager = LinearLayoutManager(view.context)
orderAdapter = OrderAdapter(view.context, resSum, basketVM!!)
itemsList.adapter = orderAdapter
basketDao?.getUserBasket(viewModel.getId()!!)?.subscribeOn(Schedulers.io())
?.observeOn(AndroidSchedulers.mainThread())
?.subscribe { pizzas ->
listPizzas = pizzas
itemsList.layoutManager = LinearLayoutManager(view.context)
itemsList.adapter = OrderAdapter(pizzas,view.context, resSum)
}
button.setOnClickListener{buttonClick(view)}
@ -89,30 +64,35 @@ class crate : Fragment() {
@SuppressLint("CheckResult")
private fun buttonClick(view : View){
var list = arrayListOf<Order>()
val currentDate =Date()
val sdf = SimpleDateFormat("dd.M.yyyy")
val currentDate = sdf.format(Date())
val x = itemsList.childCount
if(x == 0){
return
}
basketVM?.getAllBaskets(viewModel.getId()!!,
onLoad = {listPizzas: List<PizzaBasket> ->
for(i in 0..<x){
val child = itemsList.getChildAt(i)
val price = child.findViewById<TextView>(R.id.order_sum).text.toString().toInt()
list.add(Order(null, currentDate, listPizzas.get(i).pizza_id,
viewModel.getId()!!, price))
}
basketVM!!.deleteAllPizza(viewModel.getId()!!)
orderViewModel!!.savePizza(list){
Toast.makeText(view.context, "Заказ прошел успешно ", Toast.LENGTH_SHORT).show()
val action = crateDirections
.actionNavigationCretePizzaToListNavigation()
Navigation.findNavController(view).navigate(action)
}
},
onError = {})
for(i in 0..<x){
var child = itemsList.getChildAt(i)
var price = child.findViewById<TextView>(R.id.order_sum).text.toString().toInt()
list.add(Order(null, currentDate, listPizzas[i].pizza_id,
viewModel.getId(), price))
}
basketDao?.deleteByUser(viewModel.getId()!!)?.subscribeOn(Schedulers.io())
?.observeOn(AndroidSchedulers.mainThread())
?.doOnError({ Toast.makeText(view.context, "Error", Toast.LENGTH_SHORT).show()})
?.doOnComplete({})
?.onErrorComplete()
?.subscribe {}
orderDao?.insertMany(list)?.subscribeOn(Schedulers.io())
?.observeOn(AndroidSchedulers.mainThread())
?.doOnComplete({})
?.doOnError({ Toast.makeText(view.context, "Error", Toast.LENGTH_SHORT).show()})
?.onErrorComplete()
?.subscribe {
Toast.makeText(view.context, "Заказ прошел успешно ", Toast.LENGTH_SHORT).show()
val action = crateDirections
.actionNavigationCretePizzaToListNavigation()
Navigation.findNavController(view).navigate(action)
}
}
}

View File

@ -13,21 +13,15 @@ import android.view.ViewGroup
import android.widget.Button
import android.widget.EditText
import android.widget.ImageView
import android.widget.TextView
import android.widget.Toast
import androidx.activity.result.contract.ActivityResultContracts
import androidx.appcompat.widget.AppCompatImageView
import androidx.core.graphics.drawable.toBitmap
import androidx.fragment.app.Fragment
import androidx.fragment.app.viewModels
import androidx.navigation.Navigation
import com.example.pizza.Model.Pizza.Pizza
import com.example.pizza.Model.Pizza.PizzaDao
import com.example.pizza.Model.User.User
import com.example.pizza.Model.User.UserDao
import com.example.pizza.ViewModels.AppViewModelProvider
import com.example.pizza.ViewModels.PizzaEditViewModel
import com.example.pizza.ViewModels.PizzaListViewModel
import com.example.pizza.database.AppDatabase
import io.reactivex.rxjava3.android.schedulers.AndroidSchedulers
import io.reactivex.rxjava3.schedulers.Schedulers
@ -35,20 +29,12 @@ import io.reactivex.rxjava3.schedulers.Schedulers
private lateinit var selectedImage: AppCompatImageView
class create_pizza : Fragment() {
private var pizzaViewModel: PizzaEditViewModel? = null
private var editing = false
private var editPizza : Pizza? = null
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
val viewModel: PizzaEditViewModel by viewModels(
factoryProducer = { AppViewModelProvider.Factory }
)
pizzaViewModel = viewModel
}
private var pizzaDao: PizzaDao? = null
override fun onCreateView(
inflater: LayoutInflater, container: ViewGroup?,
savedInstanceState: Bundle?
): View? {
pizzaDao = context?.let { AppDatabase.getInstance(it).pizzaDao() }
val view = inflater.inflate(R.layout.fragment_create_pizza, container, false)
val button = view.findViewById<Button>(R.id.button_save)
button.setOnClickListener {buttonClick(view)}
@ -57,17 +43,7 @@ class create_pizza : Fragment() {
val pickImg = Intent(Intent.ACTION_PICK, MediaStore.Images.Media.INTERNAL_CONTENT_URI)
changeImage.launch(pickImg)
}
val args = RegArgs.fromBundle(requireArguments())
if(args.id != -1) {
editing = true
pizzaViewModel?.getPizza(args.id) { data: Pizza ->
editPizza = data
view.findViewById<TextView>(R.id.pizza_title).text = editPizza?.title
view.findViewById<TextView>(R.id.pizza_price).text = editPizza?.price.toString()
view.findViewById<TextView>(R.id.pizza_ingredients).text = editPizza?.ingredients
view.findViewById<ImageView>(R.id.pizza_image).setImageBitmap(editPizza?.image)
}
}
//TODO добавление в бд
return view
}
@SuppressLint("CheckResult")
@ -82,33 +58,18 @@ class create_pizza : Fragment() {
Toast.makeText(view.context, "Укажите данные", Toast.LENGTH_SHORT).show()
return
}
if(!editing) {
pizzaViewModel!!.savePizza(pizza1,
onSave = {
pizzaDao?.insert(pizza1)?.subscribeOn(Schedulers.io())
?.observeOn(AndroidSchedulers.mainThread())
?.doOnComplete({})
?.doOnError({ Toast.makeText(view.context, "Error", Toast.LENGTH_SHORT).show()})
?.onErrorComplete()
?.subscribe {
Toast.makeText(view.context, "Пицца успешно добавлена", Toast.LENGTH_SHORT).show()
val action = create_pizzaDirections
.actionNavigationCreatePizzaToListNavigation()
Navigation.findNavController(view).navigate(action)
},
onError = {Toast.makeText(view.context, "Ошибка!!!", Toast.LENGTH_SHORT).show()}
)
}
else
{
editPizza?.title = title
editPizza?.ingredients = ingredients
editPizza?.price = price
editPizza?.image = bitmap
pizzaViewModel?.updatePizza(editPizza!!,
onSave = {
Toast.makeText(view.context, "Пицца успешно обновлена", Toast.LENGTH_SHORT).show()
val action = create_pizzaDirections
.actionNavigationCreatePizzaToListNavigation()
Navigation.findNavController(view).navigate(action)
},
onError = {Toast.makeText(view.context, "Такая пицца уже есть", Toast.LENGTH_SHORT).show()})
}
}
}
private val changeImage =

View File

@ -1,69 +0,0 @@
package com.example.pizza.database
import android.content.Context
import com.example.pizza.Model.Repository.BasketRepository
import com.example.pizza.Model.Repository.OfflineBasketRepository
import com.example.pizza.Model.Repository.OfflineOrderRepository
import com.example.pizza.Model.Repository.OfflinePizzaRepository
import com.example.pizza.Model.Repository.OfflineUserRepository
import com.example.pizza.Model.Repository.OrderRepository
import com.example.pizza.Model.Repository.PizzaRepository
import com.example.pizza.Model.Repository.Rest.RestBasketRepository
import com.example.pizza.Model.Repository.Rest.RestOrderRepository
import com.example.pizza.Model.Repository.Rest.RestPizzaRepository
import com.example.pizza.Model.Repository.Rest.RestUserRepository
import com.example.pizza.Model.Repository.UserRepository
import com.example.pizza.Model.Rest.MyServerService
import com.example.pizza.RemoteKeys.OfflineRemoteKeyRepository
import com.example.pizza.RemoteKeys.RemoteKeyRepository
interface AppContainer {
val pizzaRepository: PizzaRepository
val userRepository: UserRepository
val basketRepository: BasketRepository
val orderRepository : OrderRepository
val remoteKeyRepository: RemoteKeyRepository
}
class AppDataContainer(private val context: Context) : AppContainer {
override val pizzaRepository: PizzaRepository by lazy {
RestPizzaRepository(
MyServerService.getInstance(),
OfflinePizzaRepository(AppDatabase.getInstance(context).pizzaDao()),
OfflineRemoteKeyRepository(AppDatabase.getInstance(context).remoteKeysDao()),
AppDatabase.getInstance(context))
}
override val userRepository: UserRepository by lazy {
RestUserRepository(
MyServerService.getInstance(),
OfflineUserRepository(AppDatabase.getInstance(context).userDao()),
OfflineRemoteKeyRepository(AppDatabase.getInstance(context).remoteKeysDao()),
AppDatabase.getInstance(context)
)
}
override val basketRepository: BasketRepository by lazy {
RestBasketRepository(
MyServerService.getInstance(),
OfflineBasketRepository(AppDatabase.getInstance(context).basketDao()),
OfflinePizzaRepository(AppDatabase.getInstance(context).pizzaDao()),
OfflineUserRepository(AppDatabase.getInstance(context).userDao()),
OfflineRemoteKeyRepository(AppDatabase.getInstance(context).remoteKeysDao()),
AppDatabase.getInstance(context))
}
override val orderRepository: OrderRepository by lazy {
RestOrderRepository(
MyServerService.getInstance(),
OfflineOrderRepository(AppDatabase.getInstance(context).orderDao()),
OfflinePizzaRepository(AppDatabase.getInstance(context).pizzaDao()),
OfflineRemoteKeyRepository(AppDatabase.getInstance(context).remoteKeysDao()),
AppDatabase.getInstance(context))
}
override val remoteKeyRepository: RemoteKeyRepository by lazy {
OfflineRemoteKeyRepository(AppDatabase.getInstance(context).remoteKeysDao())
}
}

View File

@ -17,7 +17,6 @@ import androidx.room.TypeConverters
import androidx.sqlite.db.SupportSQLiteDatabase
import com.example.pizza.Model.Basket.Basket
import com.example.pizza.Model.Basket.BasketDao
import com.example.pizza.Model.Order.DateConverter
import com.example.pizza.Model.Order.Order
import com.example.pizza.Model.Order.OrderDao
import com.example.pizza.Model.Pizza.ImageConverter
@ -26,30 +25,22 @@ import com.example.pizza.Model.Pizza.PizzaDao
import com.example.pizza.Model.Pizza.Singleton
import com.example.pizza.Model.User.User
import com.example.pizza.Model.User.UserDao
import com.example.pizza.RemoteKeys.RemoteKeys
import com.example.pizza.RemoteKeys.RemoteKeysDao
import java.io.ByteArrayOutputStream
import java.text.SimpleDateFormat
import java.util.Date
import java.util.concurrent.Executors
@Database(entities = [
User::class,
Pizza::class,
Basket::class,
Order::class,
RemoteKeys::class,
], version = 1, exportSchema = false)
@TypeConverters(ImageConverter::class, DateConverter::class)
@Database(entities = [User::class, Pizza::class,Basket::class,Order::class], version = 1, exportSchema = false)
@TypeConverters(ImageConverter::class)
abstract class AppDatabase : RoomDatabase() {
abstract fun userDao(): UserDao
abstract fun pizzaDao(): PizzaDao
abstract fun basketDao(): BasketDao
abstract fun orderDao(): OrderDao
abstract fun remoteKeysDao(): RemoteKeysDao
companion object {
private const val DB_NAME: String = "dp14"
private const val DB_NAME: String = "dp7"
@Volatile
private var INSTANCE: AppDatabase? = null
@ -89,11 +80,11 @@ abstract class AppDatabase : RoomDatabase() {
val orderDao = database.orderDao()
val sdf = SimpleDateFormat("dd.M.yyyy")
val currentDate = Date()
val currentDate = sdf.format(Date())
val order1 = Order(1,currentDate,pizza1.uid,user1.uid,300)
val order2 = Order(2,currentDate,pizza2.uid,user1.uid,300)
val order3 = Order(3,currentDate,pizza1.uid,user2.uid,300)
val order1 = Order(1,currentDate.toString(),pizza1.uid,user1.uid,300)
val order2 = Order(2,currentDate.toString(),pizza2.uid,user1.uid,300)
val order3 = Order(3,currentDate.toString(),pizza1.uid,user2.uid,300)
orderDao.insert(order1).subscribe().dispose()
orderDao.insert(order2).subscribe().dispose()
orderDao.insert(order3).subscribe().dispose()
@ -109,7 +100,7 @@ abstract class AppDatabase : RoomDatabase() {
.addCallback(object : Callback() {
override fun onCreate(db: SupportSQLiteDatabase) {
super.onCreate(db)
//Executors.newSingleThreadExecutor().execute { populateDatabase() }
Executors.newSingleThreadExecutor().execute { populateDatabase() }
}
})
.build()

View File

@ -1,7 +1,6 @@
package com.example.pizza
import android.annotation.SuppressLint
import android.os.Build
import android.os.Bundle
import androidx.fragment.app.Fragment
import android.view.LayoutInflater
@ -9,16 +8,10 @@ import android.view.View
import android.view.ViewGroup
import android.widget.Button
import android.widget.TextView
import android.widget.Toast
import androidx.annotation.RequiresApi
import androidx.fragment.app.activityViewModels
import androidx.fragment.app.viewModels
import androidx.lifecycle.LiveData
import androidx.navigation.Navigation
import androidx.paging.PagingData
import androidx.recyclerview.widget.LinearLayoutManager
import androidx.recyclerview.widget.RecyclerView
import com.example.pizza.Model.Basket.PizzaBasket
import com.example.pizza.Model.Order.Order
import com.example.pizza.Model.HistoryAdapter
import com.example.pizza.Model.Order.OrderDao
@ -26,45 +19,15 @@ import com.example.pizza.Model.Order.PizzaOrder
import com.example.pizza.Model.OrderAdapter
import com.example.pizza.Model.Pizza.PizzaDao
import com.example.pizza.Model.PizzaAdapter
import com.example.pizza.Model.User.User
import com.example.pizza.Model.User.UserDao
import com.example.pizza.ViewModels.AppViewModelProvider
import com.example.pizza.ViewModels.BasketListViewModel
import com.example.pizza.ViewModels.OrderEditViewModel
import com.example.pizza.ViewModels.OrderListViewModel
import com.example.pizza.ViewModels.UserViewModel
import com.example.pizza.database.AppDatabase
import io.reactivex.rxjava3.android.schedulers.AndroidSchedulers
import io.reactivex.rxjava3.schedulers.Schedulers
class user : Fragment() {
private var orderViewModel : OrderListViewModel? = null
private var userViewModel : UserViewModel? = null
private var orderDao: OrderDao? = null
private var userDao: UserDao? = null
private val viewModel: myViewModel by activityViewModels()
private var historyAdapter : HistoryAdapter? = null
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
val viewModel: UserViewModel by viewModels(
factoryProducer = { AppViewModelProvider.Factory }
)
userViewModel = viewModel
val viewModel2: OrderListViewModel by viewModels(
factoryProducer = { AppViewModelProvider.Factory }
)
orderViewModel = viewModel2
}
@RequiresApi(Build.VERSION_CODES.O)
override fun onStart() {
super.onStart()
val pizzas: LiveData<PagingData<PizzaOrder>?>? = orderViewModel?.getPizzas(viewModel.getId()!!)
pizzas?.observe(viewLifecycleOwner) { data ->
data?.let {
historyAdapter?.submitData(lifecycle, it)
}
}
}
@SuppressLint("CheckResult", "SetTextI18n")
override fun onCreateView(
inflater: LayoutInflater, container: ViewGroup?,
@ -72,19 +35,32 @@ class user : Fragment() {
): View? {
userDao = context?.let { AppDatabase.getInstance(it).userDao() }
orderDao = context?.let { AppDatabase.getInstance(it).orderDao() }
val view = inflater.inflate(R.layout.fragment_user, container, false)
val itemsList : RecyclerView = view.findViewById(R.id.historyList)
userViewModel?.getUserById(viewModel.getId()!!,
onLoad = {data: User ->
view.findViewById<TextView>(R.id.user_login).text = "Логин: "+ data?.login
view.findViewById<TextView>(R.id.user_email).text = "Почта: " + data?.email },
onError = { Toast.makeText(view.context, "Сбой Системы!!!", Toast.LENGTH_SHORT).show()}
)
historyAdapter = HistoryAdapter(view.context)
itemsList.adapter = historyAdapter
userDao?.getById(viewModel.getId()!!)
?.subscribeOn(Schedulers.io())
?.observeOn(AndroidSchedulers.mainThread())
?.doOnError { }
?.doOnSuccess { }
?.onErrorComplete()
?.subscribe { user ->
view.findViewById<TextView>(R.id.user_login).text = "Логин: "+ user.login
view.findViewById<TextView>(R.id.user_email).text = "Почта: " + user.email
}
orderDao?.getUserHistory(viewModel.getId()!!)?.subscribeOn(Schedulers.io())
?.observeOn(AndroidSchedulers.mainThread())
?.subscribe { pizzas ->
itemsList.adapter = HistoryAdapter(pizzas,view.context)
}
itemsList.layoutManager = LinearLayoutManager(view.context)
view.findViewById<Button>(R.id.button_exit).setOnClickListener {buttonClick(view)}
view.findViewById<Button>(R.id.button_edit).setOnClickListener {buttonEdit(view)}
return view
@ -97,13 +73,5 @@ class user : Fragment() {
.actionNavigationUserToNavigationAuth()
Navigation.findNavController(view).navigate(action)
}
@SuppressLint("ResourceType")
private fun buttonEdit(view: View) {
val action = userDirections
.actionNavigationUserToNavigationReg(viewModel.getId()!!)
Navigation.findNavController(view).navigate(action)
}
}

View File

@ -36,32 +36,16 @@
android:layout_gravity="left"
android:text="Почта: "
/>
<LinearLayout
android:layout_width="wrap_content"
android:layout_height="wrap_content">
<Button
android:id="@+id/button_exit"
android:layout_width="150dp"
android:layout_marginTop="15dp"
android:layout_marginRight="15dp"
android:fontFamily="@font/inter_bold"
android:layout_height="wrap_content"
android:layout_gravity="center"
android:backgroundTint="#BD350A"
android:text="Выход" />
<Button
android:id="@+id/button_edit"
android:layout_width="wrap_content"
android:layout_marginTop="15dp"
android:layout_marginRight="15dp"
android:fontFamily="@font/inter_bold"
android:layout_height="wrap_content"
android:layout_gravity="center"
android:backgroundTint="#BD350A"
android:text="Редактировать" />
</LinearLayout>
<Button
android:id="@+id/button_exit"
android:layout_width="150dp"
android:layout_marginTop="15dp"
android:layout_marginRight="15dp"
android:fontFamily="@font/inter_bold"
android:layout_height="wrap_content"
android:layout_gravity="right"
android:backgroundTint="#BD350A"
android:text="Выход" />
<androidx.recyclerview.widget.RecyclerView
android:id="@+id/historyList"

View File

@ -19,7 +19,6 @@
app:destination="@id/navigation_reg"
app:popUpTo="@id/nav_graph"
app:popUpToInclusive="true" />
</fragment>
<fragment
@ -37,14 +36,6 @@
app:destination="@id/navigation_auth"
app:popUpTo="@id/nav_graph"
app:popUpToInclusive="true" />
<action
android:id="@+id/action_navigation_reg_to_navigation_user"
app:destination="@id/navigation_user"
app:popUpTo="@id/nav_graph"
app:popUpToInclusive="true" />
<argument
android:name="id"
app:argType="integer" />
</fragment>
<fragment
@ -79,9 +70,6 @@
app:destination="@id/navigation_pizza_list"
app:popUpTo="@id/nav_graph"
app:popUpToInclusive="true" />
<argument
android:name="id"
app:argType="integer" />
</fragment>
<fragment
@ -94,11 +82,6 @@
app:destination="@id/navigation_auth"
app:popUpTo="@id/nav_graph"
app:popUpToInclusive="true" />
<action
android:id="@+id/action_navigation_user_to_navigation_reg"
app:destination="@id/navigation_reg"
app:popUpTo="@id/nav_graph"
app:popUpToInclusive="true" />
</fragment>
</navigation>

View File

@ -1,4 +0,0 @@
<?xml version="1.0" encoding="utf-8"?>
<network-security-config>
<base-config cleartextTrafficPermitted="true"/>
</network-security-config>

Binary file not shown.

Before

Width:  |  Height:  |  Size: 1.5 MiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 146 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 145 KiB

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Before

Width:  |  Height:  |  Size: 138 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 129 KiB