Merge branch 'master' of git.reim.ar:ReiMerc/easyeat
This commit is contained in:
commit
2a4b0c671d
@ -94,6 +94,6 @@ inline fun <reified Req, reified Res> requestJson(ctx: Context, method: String,
|
||||
Log.e("EasyEat", e.message!!)
|
||||
Log.e("EasyEat", response.body)
|
||||
|
||||
throw ApiRequestException("Failed to parse response: $response", e)
|
||||
throw ApiRequestException("Failed to parse response: ${response.body}", e)
|
||||
}
|
||||
}
|
||||
|
@ -11,12 +11,16 @@ fun getShoppingList(ctx: Context): Array<ShoppingListItem> {
|
||||
@Serializable
|
||||
data class AddShoppingItemRequest(val name: String, val amount: Double?, val unit: String?, val checked: Boolean)
|
||||
|
||||
fun addShoppingItem(ctx: Context, name: String, amount: Double?, unit: String?) {
|
||||
fun addShoppingItem(ctx: Context, name: String, amount: Double?, unit: String?): ShoppingListItem {
|
||||
val request = AddShoppingItemRequest(name, amount, unit, false)
|
||||
|
||||
requestJson<AddShoppingItemRequest, Boolean>(ctx, "POST", "/api/ShoppingList/add", request)
|
||||
return requestJson<AddShoppingItemRequest, ShoppingListItem>(ctx, "POST", "/api/ShoppingList/add", request)
|
||||
}
|
||||
|
||||
fun toggleShoppingItemChecked(ctx: Context, item: ShoppingListItem) {
|
||||
requestJson<Unit, Boolean>(ctx, "PUT", "/api/ShoppingList/check?itemId=${item.id}", null)
|
||||
}
|
||||
|
||||
fun deleteShoppingItem(ctx: Context, item: ShoppingListItem) {
|
||||
requestJson<Unit, Boolean>(ctx, "DELETE", "/api/ShoppingList/delete?itemId=${item.id}", null)
|
||||
}
|
||||
|
@ -1,13 +1,13 @@
|
||||
package tech.mercantec.easyeat.ui.shopping_list
|
||||
|
||||
import android.app.AlertDialog
|
||||
import android.app.Dialog
|
||||
import android.os.Bundle
|
||||
import android.view.LayoutInflater
|
||||
import android.view.View
|
||||
import android.view.ViewGroup
|
||||
import android.widget.ArrayAdapter
|
||||
import android.widget.EditText
|
||||
import android.widget.PopupMenu
|
||||
import android.widget.Spinner
|
||||
import android.widget.Toast
|
||||
import androidx.fragment.app.Fragment
|
||||
@ -15,29 +15,27 @@ import tech.mercantec.easyeat.R
|
||||
import tech.mercantec.easyeat.databinding.FragmentShoppingListBinding
|
||||
import tech.mercantec.easyeat.helpers.ApiRequestException
|
||||
import tech.mercantec.easyeat.helpers.addShoppingItem
|
||||
import tech.mercantec.easyeat.helpers.deleteShoppingItem
|
||||
import tech.mercantec.easyeat.helpers.getShoppingList
|
||||
import tech.mercantec.easyeat.helpers.toggleShoppingItemChecked
|
||||
import tech.mercantec.easyeat.models.Dish
|
||||
import tech.mercantec.easyeat.models.ShoppingListItem
|
||||
import java.util.ArrayList
|
||||
import kotlin.concurrent.thread
|
||||
|
||||
class ShoppingListFragment : Fragment() {
|
||||
|
||||
private var _binding: FragmentShoppingListBinding? = null
|
||||
|
||||
// This property is only valid between onCreateView and
|
||||
// onDestroyView.
|
||||
private val binding get() = _binding!!
|
||||
|
||||
override fun onCreateView(
|
||||
inflater: LayoutInflater,
|
||||
container: ViewGroup?,
|
||||
savedInstanceState: Bundle?
|
||||
): View {
|
||||
_binding = FragmentShoppingListBinding.inflate(inflater, container, false)
|
||||
val root: View = binding.root
|
||||
val binding = FragmentShoppingListBinding.inflate(inflater, container, false)
|
||||
|
||||
binding.shoppingList.visibility = View.GONE
|
||||
binding.emptyShoppingList.visibility = View.GONE
|
||||
binding.addToShoppingList.visibility = View.GONE
|
||||
binding.loading.visibility = View.VISIBLE
|
||||
|
||||
// Fetch shopping list items
|
||||
thread {
|
||||
val items: Array<ShoppingListItem>
|
||||
try {
|
||||
@ -45,16 +43,25 @@ class ShoppingListFragment : Fragment() {
|
||||
} catch (e: ApiRequestException) {
|
||||
activity?.runOnUiThread {
|
||||
Toast.makeText(context, e.message, Toast.LENGTH_LONG).show()
|
||||
|
||||
binding.loading.visibility = View.GONE
|
||||
}
|
||||
|
||||
return@thread
|
||||
}
|
||||
|
||||
activity?.runOnUiThread {
|
||||
binding.shoppingList.visibility = View.VISIBLE
|
||||
binding.emptyShoppingList.visibility = View.VISIBLE
|
||||
binding.addToShoppingList.visibility = View.VISIBLE
|
||||
binding.loading.visibility = View.GONE
|
||||
|
||||
binding.shoppingList.emptyView = binding.emptyShoppingList
|
||||
binding.shoppingList.adapter = ShoppingItemAdapter(requireContext(), ArrayList(items.toMutableList()))
|
||||
}
|
||||
}
|
||||
|
||||
// Check / uncheck when clicking shopping item
|
||||
binding.shoppingList.setOnItemClickListener { parent, view, position, id ->
|
||||
val item = parent.getItemAtPosition(position) as ShoppingListItem
|
||||
item.checked = !item.checked
|
||||
@ -73,6 +80,41 @@ class ShoppingListFragment : Fragment() {
|
||||
adapter.insert(item, position)
|
||||
}
|
||||
|
||||
// Show context menu when long clicking shopping item
|
||||
binding.shoppingList.setOnItemLongClickListener { parent, view, position, id ->
|
||||
val item = parent.getItemAtPosition(position) as ShoppingListItem
|
||||
|
||||
val popup = PopupMenu(requireActivity(), view)
|
||||
popup.apply {
|
||||
menuInflater.inflate(R.menu.shopping_item_context_menu, menu)
|
||||
setOnMenuItemClickListener {
|
||||
when (it.itemId) {
|
||||
R.id.remove_shopping_item -> {
|
||||
(parent.adapter as ShoppingItemAdapter).remove(item)
|
||||
|
||||
thread {
|
||||
try {
|
||||
deleteShoppingItem(requireContext(), item)
|
||||
} catch (e: ApiRequestException) {
|
||||
activity?.runOnUiThread {
|
||||
Toast.makeText(context, e.message, Toast.LENGTH_LONG).show()
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
true
|
||||
}
|
||||
else -> false
|
||||
}
|
||||
}
|
||||
show()
|
||||
}
|
||||
|
||||
|
||||
return@setOnItemLongClickListener true
|
||||
}
|
||||
|
||||
// Show new item dialog when clicking add
|
||||
binding.addToShoppingList.setOnClickListener {
|
||||
val view = requireActivity().layoutInflater.inflate(R.layout.dialog_add_to_shopping_list, null)
|
||||
|
||||
@ -89,17 +131,25 @@ class ShoppingListFragment : Fragment() {
|
||||
dialog.getButton(AlertDialog.BUTTON_NEGATIVE).isEnabled = false
|
||||
|
||||
thread {
|
||||
val item: ShoppingListItem
|
||||
try {
|
||||
addShoppingItem(requireContext(), name, amount, unit)
|
||||
item = addShoppingItem(requireContext(), name, amount, unit)
|
||||
} catch (e: ApiRequestException) {
|
||||
activity?.runOnUiThread {
|
||||
Toast.makeText(context, e.message, Toast.LENGTH_LONG).show()
|
||||
}
|
||||
|
||||
return@thread
|
||||
} finally {
|
||||
activity?.runOnUiThread {
|
||||
dialog.dismiss()
|
||||
}
|
||||
}
|
||||
|
||||
activity?.runOnUiThread {
|
||||
val adapter = binding.shoppingList.adapter as ShoppingItemAdapter
|
||||
adapter.insert(item, adapter.count)
|
||||
}
|
||||
}
|
||||
}
|
||||
.setNegativeButton(R.string.cancel_label) { dialog, _ ->
|
||||
@ -115,11 +165,6 @@ class ShoppingListFragment : Fragment() {
|
||||
dialog.findViewById<Spinner>(R.id.unit_selector).adapter = adapter
|
||||
}
|
||||
|
||||
return root
|
||||
}
|
||||
|
||||
override fun onDestroyView() {
|
||||
super.onDestroyView()
|
||||
_binding = null
|
||||
return binding.root
|
||||
}
|
||||
}
|
10
app/app/src/main/res/drawable/ic_delete_24px.xml
Normal file
10
app/app/src/main/res/drawable/ic_delete_24px.xml
Normal file
@ -0,0 +1,10 @@
|
||||
<vector xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
android:width="24dp"
|
||||
android:height="24dp"
|
||||
android:viewportWidth="960"
|
||||
android:viewportHeight="960"
|
||||
android:tint="?attr/colorControlNormal">
|
||||
<path
|
||||
android:fillColor="@android:color/white"
|
||||
android:pathData="M280,840Q247,840 223.5,816.5Q200,793 200,760L200,240L160,240L160,160L360,160L360,120L600,120L600,160L800,160L800,240L760,240L760,760Q760,793 736.5,816.5Q713,840 680,840L280,840ZM360,680L440,680L440,320L360,320L360,680ZM520,680L600,680L600,320L520,320L520,680Z"/>
|
||||
</vector>
|
@ -1,10 +1,19 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<FrameLayout
|
||||
<RelativeLayout
|
||||
xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
xmlns:app="http://schemas.android.com/apk/res-auto"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="match_parent">
|
||||
|
||||
<ProgressBar
|
||||
android:id="@+id/loading"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_centerInParent="true"
|
||||
android:visibility="gone"
|
||||
android:indeterminate="true"
|
||||
/>
|
||||
|
||||
<ListView
|
||||
android:id="@+id/shopping_list"
|
||||
android:layout_width="match_parent"
|
||||
@ -13,15 +22,24 @@
|
||||
android:dividerHeight="1dp"
|
||||
/>
|
||||
|
||||
<TextView
|
||||
android:id="@+id/empty_shopping_list"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_centerInParent="true"
|
||||
android:text="@string/empty_shopping_list"
|
||||
/>
|
||||
|
||||
<com.google.android.material.floatingactionbutton.FloatingActionButton
|
||||
android:id="@+id/add_to_shopping_list"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_gravity="bottom|end"
|
||||
android:layout_alignParentBottom="true"
|
||||
android:layout_alignParentEnd="true"
|
||||
android:layout_margin="16dp"
|
||||
android:backgroundTint="@color/cyan"
|
||||
app:srcCompat="@android:drawable/ic_input_add"
|
||||
app:tint="@android:color/white"
|
||||
/>
|
||||
|
||||
</FrameLayout>
|
||||
</RelativeLayout>
|
||||
|
8
app/app/src/main/res/menu/shopping_item_context_menu.xml
Normal file
8
app/app/src/main/res/menu/shopping_item_context_menu.xml
Normal file
@ -0,0 +1,8 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<menu xmlns:android="http://schemas.android.com/apk/res/android">
|
||||
<item
|
||||
android:id="@+id/remove_shopping_item"
|
||||
android:icon="@drawable/ic_delete_24px"
|
||||
android:title="@string/delete_label"
|
||||
/>
|
||||
</menu>
|
@ -39,6 +39,8 @@
|
||||
<string name="change_password_label">Change password</string>
|
||||
<string name="logout_label">Log out</string>
|
||||
<string name="checked_desc">Checked</string>
|
||||
<string name="delete_label">Delete</string>
|
||||
<string name="empty_shopping_list">Your shopping list is empty</string>
|
||||
<string-array name="units">
|
||||
<item></item>
|
||||
<item>g</item>
|
||||
|
Loading…
Reference in New Issue
Block a user