diff --git a/.idea/deploymentTargetDropDown.xml b/.idea/deploymentTargetDropDown.xml new file mode 100644 index 0000000..c1c2a07 --- /dev/null +++ b/.idea/deploymentTargetDropDown.xml @@ -0,0 +1,17 @@ + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/app/src/main/java/com/capstone/foodify/API/FoodApi.java b/app/src/main/java/com/capstone/foodify/API/FoodApi.java index d4cb7b3..3f8b27a 100644 --- a/app/src/main/java/com/capstone/foodify/API/FoodApi.java +++ b/app/src/main/java/com/capstone/foodify/API/FoodApi.java @@ -26,7 +26,7 @@ public interface FoodApi { Gson gson = new GsonBuilder().setDateFormat("HH:mm:ss dd-MM-yyyy").create(); FoodApi apiService = new Retrofit.Builder() - .baseUrl("http://10.0.2.2:8080/api/").addConverterFactory(GsonConverterFactory.create(gson)) + .baseUrl("http://192.168.1.183:8080/api/").addConverterFactory(GsonConverterFactory.create(gson)) .build() .create(FoodApi.class); @@ -39,17 +39,17 @@ public interface FoodApi { @GET("shops?pageNo=0&pageSize=10&sortBy=id&sortDir=asc") Call allShops(); - @GET("products/search/") - Call> listFood(@Path("search") String search, @Query("pageNo") int pageNo, @Query("pageSize") int pageSize, @Query("sortBy") String sortBy, @Query("sortDir") String sortDir); + @GET("products/search/{name}") + Call searchFoodByName(@Path("name") String name, @Query("pageNo") int pageNo, @Query("pageSize") int pageSize, @Query("sortBy") String sortBy, @Query("sortDir") String sortDir); - @GET("listFood") - Call> listFood(@Query("page") int page, @Query("limit") int limit); + @GET("products") + Call listFood(@Query("pageNo") int pageNo, @Query("pageSize") int pageSize, @Query("sortBy") String sortBy, @Query("sortDir") String sortDir); - @GET("Category") + @GET("categories") Call> listCategory(); - @GET("Category/{id}/food") - Call> listFoodByCategory(@Path("id") String id); + @GET("products/categories") + Call listFoodByCategory(@Query("id") List id, @Query("pageNo") int pageNo, @Query("pageSize") int pageSize, @Query("sortBy") String sortBy, @Query("sortDir") String sortDir); @GET("detail/{id}") Call detailFood(@Path("id") String id); diff --git a/app/src/main/java/com/capstone/foodify/Fragment/SearchFragment.java b/app/src/main/java/com/capstone/foodify/Fragment/SearchFragment.java index 707ef9d..7df441a 100644 --- a/app/src/main/java/com/capstone/foodify/Fragment/SearchFragment.java +++ b/app/src/main/java/com/capstone/foodify/Fragment/SearchFragment.java @@ -7,6 +7,7 @@ import android.view.LayoutInflater; import android.view.View; import android.view.ViewGroup; import android.widget.CompoundButton; +import android.widget.LinearLayout; import android.widget.ProgressBar; import android.widget.TextView; import android.widget.Toast; @@ -25,10 +26,12 @@ import com.capstone.foodify.Common; import com.capstone.foodify.Model.Category.Category; import com.capstone.foodify.Model.Food.Food; import com.capstone.foodify.Model.Food.FoodSearchAdapter; +import com.capstone.foodify.Model.Response.Foods; import com.capstone.foodify.R; import com.google.android.material.chip.Chip; import com.google.android.material.chip.ChipGroup; +import java.nio.file.LinkOption; import java.util.ArrayList; import java.util.List; @@ -38,13 +41,15 @@ import retrofit2.Response; public class SearchFragment extends Fragment { - private static int CURRENT_PAGE = 1; - private static final int LIMIT = 18; - private static int TOTAL_PAGE = 5; + private static int CURRENT_PAGE = 0; + private static final int LIMIT = 8; + private static int TOTAL_PAGE = 0; private static int ACTION_CODE = -1; private static final int LIST_FOOD = -1; private static final int SEARCH_FOOD = 0; + private static final int LIST_FOOD_BY_CATEGORY = 2; private String searchQuery = ""; + private LinearLayout searchNotFound; private RecyclerView recycler_view_search; private NestedScrollView nestedScrollView; private TextView end_of_list_text_view; @@ -52,7 +57,7 @@ public class SearchFragment extends Fragment { private ProgressBar progressBar; private static final List listFoodSearch = new ArrayList<>(); private ChipGroup list_Category; - private final List statusCategoryChecked = new ArrayList<>(); + private final List statusCategoryChecked = new ArrayList<>(); @Override public View onCreateView(LayoutInflater inflater, ViewGroup container, @@ -67,6 +72,7 @@ public class SearchFragment extends Fragment { foodAdapter = new FoodSearchAdapter(getContext()); progressBar = view.findViewById(R.id.progress_bar); end_of_list_text_view = view.findViewById(R.id.end_of_list_text); + searchNotFound = view.findViewById(R.id.search_not_found); getListCategory(); @@ -76,10 +82,11 @@ public class SearchFragment extends Fragment { RecyclerView.ItemDecoration itemDecoration = new DividerItemDecoration(requireContext(), DividerItemDecoration.VERTICAL); recycler_view_search.addItemDecoration(itemDecoration); + //Fix for lagging when scrolling recycler_view_search.setNestedScrollingEnabled(false); recycler_view_search.setAdapter(foodAdapter); - getListFoodByPagination(1); + getListFood(0); if (nestedScrollView != null) { nestedScrollView.setOnScrollChangeListener(new NestedScrollView.OnScrollChangeListener() { @Override @@ -94,8 +101,13 @@ public class SearchFragment extends Fragment { searchView.setOnQueryTextListener(new SearchView.OnQueryTextListener() { @Override public boolean onQueryTextSubmit(String query) { + + //Hide UI search not found + searchNotFound.setVisibility(View.GONE); + + //Set action code ACTION_CODE = SEARCH_FOOD; - CURRENT_PAGE = 1; + CURRENT_PAGE = 0; listFoodSearch.clear(); showProgressBarAndHideEndOfListText(); if (!query.isEmpty()) { @@ -110,12 +122,14 @@ public class SearchFragment extends Fragment { if (searchView.getQuery().length() == 0) { listFoodSearch.clear(); - CURRENT_PAGE = 1; + CURRENT_PAGE = 0; ACTION_CODE = LIST_FOOD; showProgressBarAndHideEndOfListText(); - foodAdapter.setData(listFood); - foodAdapter.notifyDataSetChanged(); - hideProgressBarAndShowEndOfListText(); + + //Hide UI search not found + searchNotFound.setVisibility(View.GONE); + + getListFood(0); } return true; } @@ -134,27 +148,44 @@ public class SearchFragment extends Fragment { end_of_list_text_view.setVisibility(View.VISIBLE); } + private void getListFoodBySearch(String query, int page) { - FoodApi.apiService.listFood(query, page, LIMIT, "id", "asc").enqueue(new Callback>() { + FoodApi.apiService.searchFoodByName(query, page, LIMIT, "id", "asc").enqueue(new Callback() { @Override - public void onResponse(Call> call, Response> response) { + public void onResponse(Call call, Response response) { + //Init total page and total elements value + TOTAL_PAGE = response.body().getPage().getTotalPages(); + loadFoodAdapter(response); + } @Override - public void onFailure(Call> call, Throwable t) { - Toast.makeText(getContext(), "Lỗi" + t, Toast.LENGTH_LONG).show(); + public void onFailure(Call call, Throwable t) { + } }); } - private void loadFoodAdapter(Response> response) { - List foodData = response.body(); + private void loadFoodAdapter(Response response) { + Foods foodData = response.body(); - listFoodSearch.addAll(foodData); + List tempFood = foodData.getProducts(); + + listFoodSearch.addAll(tempFood); foodAdapter.setData(listFoodSearch); foodAdapter.notifyDataSetChanged(); - hideProgressBarAndShowEndOfListText(); + + //If list data don't have pagination + if(TOTAL_PAGE == 1) + hideProgressBarAndShowEndOfListText(); + + //If search not found + if(listFoodSearch.size() == 0){ + searchNotFound.setVisibility(View.VISIBLE); + progressBar.setVisibility(View.GONE); + } + } private void getListCategory() { @@ -174,12 +205,19 @@ public class SearchFragment extends Fragment { chip.setOnCheckedChangeListener(new CompoundButton.OnCheckedChangeListener() { @Override public void onCheckedChanged(CompoundButton compoundButton, boolean b) { - loadFoodByCategory(tempCategory.getId()); + //Add category to list category have checked if(b) { - statusCategoryChecked.add(tempCategory.getId()); + statusCategoryChecked.add(Integer.parseInt(tempCategory.getId())); } else { - statusCategoryChecked.remove(tempCategory.getId()); + statusCategoryChecked.remove(Integer.valueOf(tempCategory.getId())); } + + ACTION_CODE = LIST_FOOD_BY_CATEGORY; + listFoodSearch.clear(); + CURRENT_PAGE = 0; + showProgressBarAndHideEndOfListText(); + getListFoodByCategory(CURRENT_PAGE); + Toast.makeText(getContext(), "Category check: " + statusCategoryChecked, Toast.LENGTH_SHORT).show(); } }); @@ -203,16 +241,17 @@ public class SearchFragment extends Fragment { }); } - private void loadFoodByCategory(String id) { - - FoodApi.apiService.listFoodByCategory(id).enqueue(new Callback>() { + private void getListFoodByCategory(int page) { + FoodApi.apiService.listFoodByCategory(statusCategoryChecked, page, LIMIT, "id", "asc").enqueue(new Callback() { @Override - public void onResponse(Call> call, Response> response) { + public void onResponse(Call call, Response response) { + //Init total page and total elements value + TOTAL_PAGE = response.body().getPage().getTotalPages(); loadFoodAdapter(response); } @Override - public void onFailure(Call> call, Throwable t) { + public void onFailure(Call call, Throwable t) { //Check internet connection if(Common.checkInternetConnection(getContext())){ //Has internet connection @@ -225,15 +264,16 @@ public class SearchFragment extends Fragment { }); } - private void getListFoodByPagination(int page){ - FoodApi.apiService.listFood(page, LIMIT).enqueue(new Callback>() { + private void getListFood(int page){ + FoodApi.apiService.listFood(page, LIMIT, "id", "asc").enqueue(new Callback() { @Override - public void onResponse(Call> call, Response> response) { + public void onResponse(Call call, Response response) { + TOTAL_PAGE = response.body().getPage().getTotalPages(); loadFoodAdapter(response); } @Override - public void onFailure(Call> call, Throwable t) { + public void onFailure(Call call, Throwable t) { //Check internet connection if(Common.checkInternetConnection(getContext())){ //Has internet connection @@ -249,21 +289,29 @@ public class SearchFragment extends Fragment { private void dataLoadMore() { switch (ACTION_CODE){ case LIST_FOOD:{ - if(CURRENT_PAGE < TOTAL_PAGE){ - getListFoodByPagination(++CURRENT_PAGE); + if(CURRENT_PAGE < TOTAL_PAGE - 1){ + getListFood(++CURRENT_PAGE); } else { hideProgressBarAndShowEndOfListText(); } break; } case SEARCH_FOOD:{ - if(CURRENT_PAGE < TOTAL_PAGE){ + if(CURRENT_PAGE < TOTAL_PAGE - 1){ getListFoodBySearch(searchQuery, ++CURRENT_PAGE); } else { hideProgressBarAndShowEndOfListText(); } break; } + case LIST_FOOD_BY_CATEGORY:{ + if(CURRENT_PAGE < TOTAL_PAGE - 1){ + getListFoodByCategory(++CURRENT_PAGE); + } else { + hideProgressBarAndShowEndOfListText(); + } + break; + } } } diff --git a/app/src/main/java/com/capstone/foodify/Model/Category/Category.java b/app/src/main/java/com/capstone/foodify/Model/Category/Category.java index 984dfaa..3235f34 100644 --- a/app/src/main/java/com/capstone/foodify/Model/Category/Category.java +++ b/app/src/main/java/com/capstone/foodify/Model/Category/Category.java @@ -3,6 +3,7 @@ package com.capstone.foodify.Model.Category; public class Category { private String id; private String name; + private String imageUrl; public String getId() { return id; @@ -19,4 +20,12 @@ public class Category { public void setName(String name) { this.name = name; } + + public String getImageUrl() { + return imageUrl; + } + + public void setImageUrl(String imageUrl) { + this.imageUrl = imageUrl; + } } diff --git a/app/src/main/java/com/capstone/foodify/Model/Food/Food.java b/app/src/main/java/com/capstone/foodify/Model/Food/Food.java index 85e5526..17db296 100644 --- a/app/src/main/java/com/capstone/foodify/Model/Food/Food.java +++ b/app/src/main/java/com/capstone/foodify/Model/Food/Food.java @@ -116,4 +116,21 @@ public class Food implements Comparable{ } return getName().compareTo(food.getName()); } + + @Override + public String toString() { + return "Food{" + + "id='" + id + '\'' + + ", name='" + name + '\'' + + ", description='" + description + '\'' + + ", isEnabled=" + isEnabled + + ", discountPercent=" + discountPercent + + ", cost=" + cost + + ", averageRating=" + averageRating + + ", reviewCount='" + reviewCount + '\'' + + ", shop=" + shop + + ", categories=" + categories + + ", images=" + images + + '}'; + } } diff --git a/app/src/main/java/com/capstone/foodify/Model/Food/FoodSearchAdapter.java b/app/src/main/java/com/capstone/foodify/Model/Food/FoodSearchAdapter.java index b27ba6e..a2a2e82 100644 --- a/app/src/main/java/com/capstone/foodify/Model/Food/FoodSearchAdapter.java +++ b/app/src/main/java/com/capstone/foodify/Model/Food/FoodSearchAdapter.java @@ -18,6 +18,7 @@ import java.util.List; public class FoodSearchAdapter extends RecyclerView.Adapter{ + public static final int LENGTH_CHARACTER = 40; private List listFood; private Context context; @@ -45,18 +46,38 @@ public class FoodSearchAdapter extends RecyclerView.Adapter= 19){ + if(foodName.length() >= LENGTH_CHARACTER){ StringBuilder stringBuilder = new StringBuilder(food.getName()); - stringBuilder.replace(19, food.getName().length(), "..." ); + stringBuilder.replace(LENGTH_CHARACTER, food.getName().length(), "..." ); holder.name.setText(stringBuilder); } else { holder.name.setText(foodName); } -// Picasso.get().load(food.getImg()).into(holder.image); -// -// -// holder.price.setText(Common.changeCurrencyUnit(Float.parseFloat(food.getPrice()))); + + //When food does not have image + if(food.getImages().size() == 0){ + holder.image.setImageResource(R.drawable.default_image_food); + } else { + Picasso.get().load(food.getImages().get(0).getImageUrl()).into(holder.image); + } + + //Check value discountPercent + float cost = 0; + if(food.getDiscountPercent() > 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)); } @Override @@ -70,7 +91,7 @@ public class FoodSearchAdapter extends RecyclerView.Adapter + + + + + + + + + + + diff --git a/app/src/main/res/layout/fragment_search.xml b/app/src/main/res/layout/fragment_search.xml index 0a57e16..28b3ae9 100644 --- a/app/src/main/res/layout/fragment_search.xml +++ b/app/src/main/res/layout/fragment_search.xml @@ -9,8 +9,10 @@ > + android:layout_height="match_parent" + > + + + + + + + + + android:layout_height="wrap_content" + /> diff --git a/app/src/main/res/layout/item_food.xml b/app/src/main/res/layout/item_food.xml index 578d135..ba32f02 100644 --- a/app/src/main/res/layout/item_food.xml +++ b/app/src/main/res/layout/item_food.xml @@ -1,14 +1,14 @@ @@ -18,8 +18,8 @@