Skip to content
This repository was archived by the owner on Jan 11, 2024. It is now read-only.
Open
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
62 commits
Select commit Hold shift + click to select a range
7a1c261
chetan stuff
Ckalia11 Mar 7, 2023
bb0d16c
Created barebones front end for Search and Filter
Mar 8, 2023
d22b5fc
got an additional itemSum field working on all screens.
Ckalia11 Mar 8, 2023
e7d6834
Added Search Bar and Filter Buttons to Home page
Mar 8, 2023
a3396f9
Search Bar and harizontal filters Front End
Mar 8, 2023
f619363
Add Button send to top of search
Mar 8, 2023
4a97b9f
Horizontal Padding added to Filter Buttons
Mar 8, 2023
295aea9
Fixed Button Styling
Mar 9, 2023
a10702d
updated form and all screens to use food expiry information. fixed it…
Ckalia11 Mar 9, 2023
5f6456a
Merge pull request #1 from Ckalia11/chetan-branch
Ckalia11 Mar 9, 2023
1a98ee5
Added push notification button on details page
FaizaanRehman Mar 9, 2023
db102f6
Minimal implementation of image mock
Mar 9, 2023
81b901f
Added new fields to Database schema
FaizaanRehman Mar 9, 2023
e6e2726
Fixed ordering of Labels and Owner fields in homepage UI
Ckalia11 Mar 9, 2023
432c80f
Merge pull request #6 from Ckalia11/feature/update-database
FaizaanRehman Mar 9, 2023
c4cd20f
Merge branch 'main' into feature/push-notifications
FaizaanRehman Mar 10, 2023
ad0fbc2
Merge pull request #7 from Ckalia11/fix_homepage_ui
Ckalia11 Mar 10, 2023
cc1727c
Merge pull request #5 from Ckalia11/feature/demo-camera
Ckalia11 Mar 10, 2023
2db39e8
Merge branch 'main' into feature/push-notifications
FaizaanRehman Mar 10, 2023
35e8ad3
Merge pull request #8 from Ckalia11/feature/push-notifications
FaizaanRehman Mar 10, 2023
bda7ecd
Added file upload, need help persisting images
Mar 11, 2023
43ae832
Updated layout of columns and alignment on main page
FaizaanRehman Mar 11, 2023
4c84b68
Merge pull request #10 from Ckalia11/feature/align-columns
BenjaminLuo Mar 11, 2023
86d97c6
Merge pull request #11 from Ckalia11/feature/file_upload
BenjaminLuo Mar 13, 2023
b97fc01
Update AddItemFragment.kt
BenjaminLuo Mar 13, 2023
b23dbf2
renaming db attributes throughout app
t-tanveer Mar 13, 2023
1a57927
Add DatePicker dialog to set expiry date
Mar 13, 2023
0f51cfe
Merge pull request #12 from Ckalia11/task/refactor-db
t-tanveer Mar 13, 2023
46dfb9e
Merge branch 'demo' into feature/datepicker
Mar 13, 2023
d82a087
Update naming
Mar 13, 2023
298acea
testing permissions
tayyaab-wonolo Mar 13, 2023
e459bea
Merge pull request #15 from tayyaab-wonolo/patch-1
tayyaab-wonolo Mar 13, 2023
d59fee2
Revert "testing permissions"
tayyaab-wonolo Mar 13, 2023
bfd5f41
Merge pull request #16 from Ckalia11/revert-15-patch-1
tayyaab-wonolo Mar 13, 2023
8d45f89
Merge pull request #14 from Ckalia11/demo
tayyaab-wonolo Mar 13, 2023
b14f65a
Add buttons on the detail screen to increment and decrement quantity …
Ckalia11 Mar 13, 2023
ec149e9
renamed sell item id in detail layout to decrement item
Ckalia11 Mar 13, 2023
4efb5b5
minor fix - date formatting
t-tanveer Mar 13, 2023
0c1f9f4
Merge pull request #17 from Ckalia11/change_quantity_button
BenjaminLuo Mar 13, 2023
80ac5a0
Merge pull request #13 from Ckalia11/feature/datepicker
Ckalia11 Mar 13, 2023
52248c6
changed homescreen display to show days from expiry instead of expiry…
Ckalia11 Mar 14, 2023
31135d0
Merge pull request #18 from Ckalia11/fix_display_of_expiry_dates
Ckalia11 Mar 14, 2023
50f21f6
Make push notifications automatic by running a periodic function to c…
FaizaanRehman Mar 18, 2023
e025e18
display error messages in add/upload forms
Ckalia11 Mar 19, 2023
d9f478d
allowed users to type in a 2 decimal double instead of an int for the…
Ckalia11 Mar 19, 2023
cd9c79e
Merge pull request #21 from Ckalia11/allow_decimal_values_for_quantit…
BenjaminLuo Mar 19, 2023
cccc4c6
Merge pull request #20 from Ckalia11/display_errors_in_add_form
BenjaminLuo Mar 19, 2023
3332f18
Enabled image persistence upon app restart
Mar 19, 2023
c4c7539
Hotfix for app crashing when not uploading any photos
Mar 19, 2023
87b3c17
Merge pull request #19 from Ckalia11/feature/automatic-notifications
FaizaanRehman Mar 20, 2023
43d42c9
Fixed app crashing upon edit
Mar 21, 2023
5ae5741
Merge branch 'main' into hotfix/upload-picture
BenjaminLuo Mar 23, 2023
abc1189
Merge pull request #25 from Ckalia11/hotfix/upload-picture
BenjaminLuo Mar 23, 2023
556952e
Fixed disappearing image bug upon edit
Mar 23, 2023
74ef538
Add button to launch google maps and search for food banks
FaizaanRehman Mar 23, 2023
98bf510
Merge pull request #27 from Ckalia11/feature/map
Ckalia11 Mar 24, 2023
6f9a801
Merge pull request #26 from Ckalia11/hotfix/disappearing-image-on-edit
Ckalia11 Mar 24, 2023
c09a6c0
Format ingredients in list based on expired or consumed
FaizaanRehman Mar 24, 2023
7a7ee24
Merge pull request #28 from Ckalia11/feature/consume-ingredient
BenjaminLuo Mar 25, 2023
53f94ef
Add messages to expired/consumed ingredients. Prompt delete when quan…
FaizaanRehman Mar 25, 2023
3effa56
Merge pull request #30 from Ckalia11/feature/messages
Ckalia11 Mar 27, 2023
f1eaa64
search bar implemented
anushkatayal Mar 27, 2023
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
5 changes: 4 additions & 1 deletion app/build.gradle
Original file line number Diff line number Diff line change
Expand Up @@ -26,7 +26,7 @@ android {

defaultConfig {
applicationId "com.example.inventory"
minSdkVersion 19
minSdkVersion 26
targetSdkVersion 33
versionCode 1
versionName "1.0"
Expand Down Expand Up @@ -61,6 +61,9 @@ dependencies {
implementation "androidx.core:core-ktx:$core_ktx_version"
implementation "com.google.android.material:material:$material_version"

// Worker libraries
implementation "androidx.work:work-runtime-ktx:$work_version"

// Lifecycle libraries
implementation "androidx.lifecycle:lifecycle-viewmodel-ktx:$lifecycle_version"
implementation "androidx.lifecycle:lifecycle-livedata-ktx:$lifecycle_version"
Expand Down
3 changes: 2 additions & 1 deletion app/src/main/AndroidManifest.xml
Original file line number Diff line number Diff line change
Expand Up @@ -15,11 +15,12 @@
-->
<manifest xmlns:android="http://schemas.android.com/apk/res/android">

<uses-permission android:name="android.permission.POST_NOTIFICATIONS" />
<application
android:name="com.example.inventory.InventoryApplication"
android:allowBackup="true"
android:icon="@mipmap/ic_launcher"
android:label="@string/app_name"
android:label="Food Expiry Tracker"
android:roundIcon="@mipmap/ic_launcher_round"
android:supportsRtl="true"
android:theme="@style/Theme.InventoryApp">
Expand Down
196 changes: 181 additions & 15 deletions app/src/main/java/com/example/inventory/AddItemFragment.kt
Original file line number Diff line number Diff line change
Expand Up @@ -15,8 +15,19 @@
*/
package com.example.inventory

import android.app.Activity.RESULT_OK
import android.app.DatePickerDialog
import android.content.Context.INPUT_METHOD_SERVICE
import android.content.Intent
import android.graphics.Bitmap
import android.graphics.BitmapFactory
import android.graphics.ImageDecoder
import android.net.Uri
import android.os.Build
import android.os.Bundle
import android.provider.MediaStore
import android.text.Editable
import android.text.TextWatcher
import android.view.LayoutInflater
import android.view.View
import android.view.ViewGroup
Expand All @@ -28,6 +39,8 @@ import androidx.navigation.fragment.findNavController
import androidx.navigation.fragment.navArgs
import com.example.inventory.data.Item
import com.example.inventory.databinding.FragmentAddItemBinding
import java.io.ByteArrayOutputStream
import java.util.*

/**
* Fragment to add or update an item in the Inventory database.
Expand All @@ -52,6 +65,13 @@ class AddItemFragment : Fragment() {
private var _binding: FragmentAddItemBinding? = null
private val binding get() = _binding!!

// For file upload
private val pickImage = 100
private var imagePath: Uri? = null
private var imageBitmap: Bitmap? = null
private var imageByte: ByteArray? = null
private var bos: ByteArrayOutputStream? = ByteArrayOutputStream();

override fun onCreateView(
inflater: LayoutInflater,
container: ViewGroup?,
Expand All @@ -65,24 +85,65 @@ class AddItemFragment : Fragment() {
* Returns true if the EditTexts are not empty
*/
private fun isEntryValid(): Boolean {
return viewModel.isEntryValid(
binding.itemName.text.toString(),
binding.itemPrice.text.toString(),
binding.itemCount.text.toString(),
)
val nameValid = (viewModel.isEntryValid(
binding.name.text.toString()
))
val expiryDateValid = (viewModel.isEntryValid(
binding.expiryDate.text.toString()
))
val quantityValid = (viewModel.isEntryValid(
binding.quantity.text.toString()
))
var formValid = true
if (!nameValid || !expiryDateValid || !quantityValid) {
formValid = false
if (!nameValid) {
binding.name.error = "ingredient name cannot be empty"
}
if (!expiryDateValid) {
binding.expiryDate.error = "expiry date cannot be empty"
}
if (!quantityValid) {
binding.quantity.error = "quantity cannot be empty"
}

}
return formValid
}

/**
* Binds views with the passed in [item] information.
*/
private fun bind(item: Item) {
val price = "%.2f".format(item.itemPrice)

// Use the uploaded user image if this is the add screen, otherwise take from database
var loadImageByte = if (navigationArgs.itemId > 0) {
// Check if the user added an image with this item
if (item.imageByte == null) {
null
} else {
BitmapFactory.decodeByteArray(item.imageByte, 0, item.imageByte!!.size)
}
} else {
BitmapFactory.decodeByteArray(imageByte, 0, imageByte!!.size)
}

binding.apply {
itemName.setText(item.itemName, TextView.BufferType.SPANNABLE)
itemPrice.setText(price, TextView.BufferType.SPANNABLE)
itemCount.setText(item.quantityInStock.toString(), TextView.BufferType.SPANNABLE)
name.setText(item.name, TextView.BufferType.SPANNABLE)
expiryDate.setText(item.expiryDate, TextView.BufferType.SPANNABLE)
label.setText(item.label.toString(), TextView.BufferType.SPANNABLE)
quantity.setText(item.quantity.toString(), TextView.BufferType.SPANNABLE)
binding.imageView.setImageBitmap(loadImageByte)
saveAction.setOnClickListener { updateItem() }
}

if (item.imageByte == null) {
binding.imageView.visibility = View.GONE
} else {
binding.imageView.visibility = View.VISIBLE
imageByte = item.imageByte
}

}

/**
Expand All @@ -91,9 +152,11 @@ class AddItemFragment : Fragment() {
private fun addNewItem() {
if (isEntryValid()) {
viewModel.addNewItem(
binding.itemName.text.toString(),
binding.itemPrice.text.toString(),
binding.itemCount.text.toString(),
binding.name.text.toString(),
binding.expiryDate.text.toString(),
binding.label.text.toString(),
binding.quantity.text.toString(),
imageByte
)
val action = AddItemFragmentDirections.actionAddItemFragmentToItemListFragment()
findNavController().navigate(action)
Expand All @@ -107,15 +170,96 @@ class AddItemFragment : Fragment() {
if (isEntryValid()) {
viewModel.updateItem(
this.navigationArgs.itemId,
this.binding.itemName.text.toString(),
this.binding.itemPrice.text.toString(),
this.binding.itemCount.text.toString()
this.binding.name.text.toString(),
this.binding.expiryDate.text.toString(),
this.binding.label.text.toString(),
this.binding.quantity.text.toString(),
this.imageByte,
)
val action = AddItemFragmentDirections.actionAddItemFragmentToItemListFragment()
findNavController().navigate(action)
}
}

/**
* Calls the Date Picker pop up for setting expiry date.
*/
private fun callDatePicker() {
val expiryDate = binding.expiryDate
val calendar = Calendar.getInstance()
val year = calendar.get(Calendar.YEAR)
val month = calendar.get(Calendar.MONTH)
val day = calendar.get(Calendar.DAY_OF_MONTH)

val dateSetListener =
DatePickerDialog.OnDateSetListener { _, year, monthOfYear, dayOfMonth ->
var month = (monthOfYear+1).toString()
var day = dayOfMonth.toString()
if (monthOfYear < 10) {
month = "0$month"
}
if (dayOfMonth < 10) {
day = "0$day"
}
val selectedDate = "$year-${month}-$day"
expiryDate.setText(selectedDate)
}

val datePickerDialog =
DatePickerDialog(requireContext(), dateSetListener, year, month, day)
datePickerDialog.datePicker.minDate = calendar.timeInMillis
datePickerDialog.show()
}

private val MAX_DECIMAL_PLACES = 2 // Set the maximum number of decimal places here

private fun setUpQuantityText() {
val editQuantity = binding.quantity

editQuantity.addTextChangedListener(object : TextWatcher {
override fun afterTextChanged(s: Editable?) {
// Nothing to do here
}

override fun beforeTextChanged(s: CharSequence?, start: Int, count: Int, after: Int) {
// Nothing to do here
}

override fun onTextChanged(s: CharSequence?, start: Int, before: Int, count: Int) {
val decimalIndex = s?.indexOf(".") ?: -1

if (s != null) {
if (decimalIndex != -1 && s.length - decimalIndex - 1 > MAX_DECIMAL_PLACES) {
// Too many decimal places, remove the extra ones
val truncatedString = s.substring(0, decimalIndex + MAX_DECIMAL_PLACES + 1)
editQuantity.setText(truncatedString)
editQuantity.setSelection(truncatedString.length)
}
}
}
})
}


// File upload: Stores the image the user selects from their gallery into the 'imagePath' variable
override fun onActivityResult(requestCode: Int, resultCode: Int, data: Intent?) {
super.onActivityResult(requestCode, resultCode, data)
if (resultCode == RESULT_OK && requestCode == pickImage) {
imagePath = data?.data
// binding.imageView.setImageURI(imagePath)
imageBitmap = if (Build.VERSION.SDK_INT >= 28) {
val source = ImageDecoder.createSource(requireActivity().contentResolver,imagePath!!)
ImageDecoder.decodeBitmap(source)
} else {
MediaStore.Images.Media.getBitmap(requireActivity().contentResolver,imagePath!!)
}
binding.imageView.setImageBitmap(imageBitmap)
imageBitmap?.compress(Bitmap.CompressFormat.JPEG, 33, bos)
imageByte = bos?.toByteArray();
binding.imageView.visibility = View.VISIBLE
}
}

/**
* Called when the view is created.
* The itemId Navigation argument determines the edit item or add new item.
Expand All @@ -125,17 +269,39 @@ class AddItemFragment : Fragment() {
override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
super.onViewCreated(view, savedInstanceState)

val expiryDate = binding.expiryDate
expiryDate.setOnFocusChangeListener { _, hasFocus ->
if (hasFocus) {
callDatePicker()
}
}
val quantity = binding.quantity
quantity.setOnFocusChangeListener { _, hasFocus ->
if (hasFocus) {
setUpQuantityText()
}
}
val id = navigationArgs.itemId

// Protocol for editing an existing item
if (id > 0) {
viewModel.retrieveItem(id).observe(this.viewLifecycleOwner) { selectedItem ->
item = selectedItem
bind(item)
}

// Protocol for adding a new item
} else {
binding.saveAction.setOnClickListener {
addNewItem()
}
}

// Opens the phone's gallery
binding.uploadPhoto.setOnClickListener{
val gallery = Intent(Intent.ACTION_PICK, MediaStore.Images.Media.INTERNAL_CONTENT_URI)
startActivityForResult(gallery, pickImage)
}
}

/**
Expand Down
Loading