From ebd313e32c649f47483d62c7e5e0956b5080d66f Mon Sep 17 00:00:00 2001 From: Nezumi <123229563+Nez27@users.noreply.github.com> Date: Thu, 16 Mar 2023 17:59:33 +0700 Subject: [PATCH] Add favorite food --- app/src/main/AndroidManifest.xml | 4 +- .../Activity/FavoriteFoodActivity.java | 121 ++++++++++++----- .../capstone/foodify/Adapter/FoodAdapter.java | 8 +- .../foodify/Adapter/FoodFavoriteAdapter.java | 127 +++++++++++++----- .../res/layout/activity_favorite_food.xml | 116 +++++++++++----- app/src/main/res/layout/fragment_search.xml | 2 +- .../main/res/layout/item_food_favorite.xml | 34 +++-- 7 files changed, 300 insertions(+), 112 deletions(-) diff --git a/app/src/main/AndroidManifest.xml b/app/src/main/AndroidManifest.xml index 00ef14c..3ba6a1c 100644 --- a/app/src/main/AndroidManifest.xml +++ b/app/src/main/AndroidManifest.xml @@ -30,7 +30,9 @@ tools:targetApi="31"> + android:exported="false" + android:noHistory="true" + /> diff --git a/app/src/main/java/com/capstone/foodify/Activity/FavoriteFoodActivity.java b/app/src/main/java/com/capstone/foodify/Activity/FavoriteFoodActivity.java index 4a34491..fff7ad1 100644 --- a/app/src/main/java/com/capstone/foodify/Activity/FavoriteFoodActivity.java +++ b/app/src/main/java/com/capstone/foodify/Activity/FavoriteFoodActivity.java @@ -1,37 +1,59 @@ package com.capstone.foodify.Activity; +import androidx.annotation.NonNull; import androidx.appcompat.app.AppCompatActivity; +import androidx.constraintlayout.widget.ConstraintLayout; import androidx.core.widget.NestedScrollView; import androidx.recyclerview.widget.DividerItemDecoration; import androidx.recyclerview.widget.ItemTouchHelper; import androidx.recyclerview.widget.LinearLayoutManager; import androidx.recyclerview.widget.RecyclerView; +import android.app.Dialog; import android.content.Intent; import android.graphics.Color; import android.os.Bundle; import android.view.View; import android.widget.ImageView; +import android.widget.ProgressBar; +import android.widget.TextView; +import android.widget.Toast; +import com.capstone.foodify.API.FoodApiToken; import com.capstone.foodify.Adapter.FoodFavoriteAdapter; import com.capstone.foodify.Adapter.RecyclerViewItemTouchHelperFavoriteFood; import com.capstone.foodify.Common; import com.capstone.foodify.ItemTouchHelperListener; import com.capstone.foodify.Model.Food; +import com.capstone.foodify.Model.Response.Foods; import com.capstone.foodify.R; import com.google.android.material.snackbar.Snackbar; +import com.saadahmedsoft.popupdialog.PopupDialog; +import com.saadahmedsoft.popupdialog.Styles; +import com.saadahmedsoft.popupdialog.listener.OnDialogButtonClickListener; import java.util.ArrayList; +import java.util.Collections; import java.util.List; -public class FavoriteFoodActivity extends AppCompatActivity implements ItemTouchHelperListener { +import retrofit2.Call; +import retrofit2.Callback; +import retrofit2.Response; +public class FavoriteFoodActivity extends AppCompatActivity implements ItemTouchHelperListener { + private static int CURRENT_PAGE = 0; + private static final int PAGE_SIZE = 8; + private static final String SORT_BY = "name"; + private static final String SORT_DIR = "asc"; + private static boolean LAST_PAGE; private RecyclerView recyclerView_favorite_food; private FoodFavoriteAdapter adapter; private final List listFavoriteFood = new ArrayList<>(); private ImageView back_image; - private NestedScrollView listFavoriteFoodView; - + private ConstraintLayout listFavoriteFoodView, progressLayout; + private NestedScrollView nestedScrollView; + private ProgressBar progressBar; + private TextView endOfListText; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); @@ -39,6 +61,24 @@ public class FavoriteFoodActivity extends AppCompatActivity implements ItemTouch //Init component back_image = findViewById(R.id.back_image); + progressLayout = findViewById(R.id.progress_layout); + nestedScrollView = findViewById(R.id.nestedScrollView); + progressBar = findViewById(R.id.progress_bar); + endOfListText = findViewById(R.id.end_of_list_text); + + //Set event when user scroll down + if (nestedScrollView != null) { + nestedScrollView.setOnScrollChangeListener(new NestedScrollView.OnScrollChangeListener() { + @Override + public void onScrollChange(@NonNull NestedScrollView v, int scrollX, int scrollY, int oldScrollX, int oldScrollY) { + if (scrollY == (v.getChildAt(0).getMeasuredHeight() - v.getMeasuredHeight())) { + //When user scroll to bottom, load more data + dataLoadMore(); + } + } + }); + } + //Set event for back image back_image.setOnClickListener(new View.OnClickListener() { @@ -56,12 +96,12 @@ public class FavoriteFoodActivity extends AppCompatActivity implements ItemTouch listFavoriteFoodView = findViewById(R.id.list_favorite_food_view); //Get list favorite food - getListFavoriteFood(); + getListFavoriteFood(CURRENT_PAGE); //Set layout recyclerview LinearLayoutManager linearLayoutManager = new LinearLayoutManager(this); recyclerView_favorite_food.setLayoutManager(linearLayoutManager); - adapter = new FoodFavoriteAdapter(); + adapter = new FoodFavoriteAdapter(this); RecyclerView.ItemDecoration itemDecoration = new DividerItemDecoration(this, DividerItemDecoration.VERTICAL); recyclerView_favorite_food.addItemDecoration(itemDecoration); @@ -70,38 +110,47 @@ public class FavoriteFoodActivity extends AppCompatActivity implements ItemTouch new ItemTouchHelper(simpleCallback).attachToRecyclerView(recyclerView_favorite_food); } - private void getListFavoriteFood() { - //Get data from api -// FoodApiToken.apiService.getListFavoriteFood().enqueue(new Callback>() { -// @Override -// public void onResponse(@NonNull Call> call, @NonNull Response> response) { -// List listFoodData = response.body(); -// if(listFoodData != null){ -// listFavoriteFood.addAll(listFoodData); -// } -// Collections.sort(listFavoriteFood); -// -// adapter.setData(listFavoriteFood); -// recyclerView_favorite_food.setAdapter(adapter); -// } -// -// @Override -// public void onFailure(Call> call, Throwable t) { -// //Check internet connection -// if(Common.checkInternetConnection(getContext())){ -// //Has internet connection -// Toast.makeText(getContext(), "Error: " + t, Toast.LENGTH_SHORT).show(); -// } else { -// //No internet, show notification -// Common.showErrorInternetConnectionNotification(getActivity()); -// -// Log.e("ERROR", "Get list favorite food error!"); -// -// } -// } -// }); + private void dataLoadMore() { + if(!LAST_PAGE){ + getListFavoriteFood(++CURRENT_PAGE); + } else { + progressBar.setVisibility(View.GONE); + endOfListText.setVisibility(View.VISIBLE); + } } + private void getListFavoriteFood(int page) { + //Get data from api + FoodApiToken.apiService.getListFavoriteFood(Common.CURRENT_USER.getId(), page, PAGE_SIZE, SORT_BY, SORT_DIR).enqueue(new Callback() { + @Override + public void onResponse(Call call, Response response) { + //Dismiss progress + progressLayout.setVisibility(View.GONE); + + Foods foodData = response.body(); + + if(foodData != null){ + listFavoriteFood.addAll(foodData.getProducts()); + LAST_PAGE = foodData.getPage().isLast(); + } + + + Collections.sort(listFavoriteFood); + + adapter.setData(listFavoriteFood); + recyclerView_favorite_food.setAdapter(adapter); + } + + @Override + public void onFailure(Call call, Throwable t) { + Toast.makeText(FavoriteFoodActivity.this, "Đã có lỗi từ hệ thống! Vui lòng thử lại sau!", Toast.LENGTH_SHORT).show(); + } + }); + + } + + + @Override public void onSwiped(RecyclerView.ViewHolder viewHolder) { if(viewHolder instanceof FoodFavoriteAdapter.FoodFavoriteViewHolder){ @@ -111,7 +160,7 @@ public class FavoriteFoodActivity extends AppCompatActivity implements ItemTouch int indexDelete = viewHolder.getAdapterPosition(); //Remove Item - adapter.removeItem(indexDelete, this); + adapter.removeItem(foodDelete, indexDelete, this); //Show notification food has been delete Snackbar snackbar = Snackbar.make(listFavoriteFoodView, foodNameDelete + " remove!", Snackbar.LENGTH_LONG); diff --git a/app/src/main/java/com/capstone/foodify/Adapter/FoodAdapter.java b/app/src/main/java/com/capstone/foodify/Adapter/FoodAdapter.java index cfd026f..901548a 100644 --- a/app/src/main/java/com/capstone/foodify/Adapter/FoodAdapter.java +++ b/app/src/main/java/com/capstone/foodify/Adapter/FoodAdapter.java @@ -56,7 +56,13 @@ public class FoodAdapter extends RecyclerView.Adapter { private List listFavoriteFood; + private Context context; - public FoodFavoriteAdapter(){} + public FoodFavoriteAdapter(Context context){ + this.context = context; + } public void setData(List listFavoriteFood){ this.listFavoriteFood = listFavoriteFood; @@ -45,10 +52,67 @@ public class FoodFavoriteAdapter extends RecyclerView.Adapter 0){ + + //Calculate final cost when apply discountPercent + cost = food.getCost() - (food.getCost() * food.getDiscountPercent()/100); + + //Show discountPercent value on screen + holder.discount.setVisibility(View.VISIBLE); + holder.discount.setText("-" + food.getDiscountPercent()+ "%"); + } else { + cost = food.getCost(); + } + holder.price.setText(Common.changeCurrencyUnit(cost)); + + //When food does not have image + if(food.getImages().size() == 0){ + holder.imageView.setImageResource(R.drawable.default_image_food); + } else { + Picasso.get().load(food.getImages().get(0).getImageUrl()).into(holder.imageView); + } + + //Set event basket icon + holder.basket_icon.setOnClickListener(new View.OnClickListener() { + @Override + public void onClick(View view) { + Basket foodInBasket = Common.getFoodExistInBasket(food.getId()); + if(foodInBasket == null){ + //If item is not exist in basket + + //Check food image is null or not + String imageTemp = null; + if(food.getImages().size() > 0) + imageTemp = food.getImages().get(0).getImageUrl(); + + Common.LIST_BASKET_FOOD.add(new Basket(food.getId(), imageTemp, food.getName(), food.getCost(), food.getShop().getName(), + "1", food.getDiscountPercent())); + } else { + //If item is exist in basket + + for(int i = 0; i < Common.LIST_BASKET_FOOD.size(); i++){ + String foodId = Common.LIST_BASKET_FOOD.get(i).getId(); + //Find foodId exist + if(foodId.equals(food.getId())){ + //Get quantity food from basket + String quantity = Common.LIST_BASKET_FOOD.get(i).getQuantity(); + + //Change quantity food from basket + int quantityInt = Integer.parseInt(quantity) + 1; + Common.LIST_BASKET_FOOD.get(i).setQuantity(String.valueOf(quantityInt)); + break; + } + } + + } + Toast.makeText(context, "Đã thêm " + food.getName() + " vào giỏ hàng!", Toast.LENGTH_SHORT).show(); + } + }); } @Override @@ -61,9 +125,9 @@ public class FoodFavoriteAdapter extends RecyclerView.Adapter() { -// @Override -// public void onResponse(Call call, Response response) { -// Toast.makeText(context, "Remove successful!", Toast.LENGTH_SHORT).show(); -// } -// -// @Override -// public void onFailure(Call call, Throwable t) { -// Toast.makeText(context, "Error: " + t, Toast.LENGTH_SHORT).show(); -// } -// }); + FoodApiToken.apiService.removeFoodFromFavorite(Common.CURRENT_USER.getId(), Integer.parseInt(food.getId())).enqueue(new Callback() { + @Override + public void onResponse(Call call, Response response) { + Toast.makeText(context, "Đã xoá " + food.getName() + " khỏi danh sách yêu thích!", Toast.LENGTH_SHORT).show(); + } + + @Override + public void onFailure(Call call, Throwable t) { + Toast.makeText(context, "Oops! Đã có lỗi, vui lòng thử lại sau!", Toast.LENGTH_SHORT).show(); + } + }); } public void undoItem(Food food, int index, Context context){ listFavoriteFood.add(index, food); notifyItemInserted(index); -// FoodApiToken.apiService.addFoodToFavorite(food.getId()).enqueue(new Callback() { -// @Override -// public void onResponse(@NonNull Call call, @NonNull Response response) { -// Toast.makeText(context, "Add successful!", Toast.LENGTH_SHORT).show(); -// } -// -// @Override -// public void onFailure(@NonNull Call call, @NonNull Throwable t) { -// Toast.makeText(context, "Error: " + t, Toast.LENGTH_SHORT).show(); -// } -// }); + FoodApiToken.apiService.addFoodToFavorite(Common.CURRENT_USER.getId(), Integer.parseInt(food.getId())).enqueue(new Callback() { + @Override + public void onResponse(Call call, Response response) { + Toast.makeText(context, "Đã thêm " + food.getName() + " vào danh sách yêu thích!", Toast.LENGTH_SHORT).show(); + } + + @Override + public void onFailure(Call call, Throwable t) { + Toast.makeText(context, "Oops! Đã có lỗi, vui lòng thử lại sau!", Toast.LENGTH_SHORT).show(); + } + }); } } diff --git a/app/src/main/res/layout/activity_favorite_food.xml b/app/src/main/res/layout/activity_favorite_food.xml index da3cff5..9cda551 100644 --- a/app/src/main/res/layout/activity_favorite_food.xml +++ b/app/src/main/res/layout/activity_favorite_food.xml @@ -1,5 +1,5 @@ - + + + + + + + + + + + + + + + + + android:layout_height="match_parent" + android:background="#80000000" + android:id="@+id/progress_layout" + > - - - - - - - - \ No newline at end of file + \ No newline at end of file diff --git a/app/src/main/res/layout/fragment_search.xml b/app/src/main/res/layout/fragment_search.xml index 28b3ae9..bb0d988 100644 --- a/app/src/main/res/layout/fragment_search.xml +++ b/app/src/main/res/layout/fragment_search.xml @@ -48,7 +48,7 @@ - + > + + + + +