diff --git a/.idea/androidTestResultsUserPreferences.xml b/.idea/androidTestResultsUserPreferences.xml
new file mode 100644
index 0000000..abd2b2e
--- /dev/null
+++ b/.idea/androidTestResultsUserPreferences.xml
@@ -0,0 +1,22 @@
+
+
+
+
+
+
\ No newline at end of file
diff --git a/app/src/main/AndroidManifest.xml b/app/src/main/AndroidManifest.xml
index 5df1573..e6a3e84 100644
--- a/app/src/main/AndroidManifest.xml
+++ b/app/src/main/AndroidManifest.xml
@@ -19,7 +19,8 @@
tools:targetApi="31">
+ android:exported="false"
+ />
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 93cb508..e776f42 100644
--- a/app/src/main/java/com/capstone/foodify/API/FoodApi.java
+++ b/app/src/main/java/com/capstone/foodify/API/FoodApi.java
@@ -5,6 +5,7 @@ import com.capstone.foodify.Model.DistrictWard.DistrictWardResponse;
import com.capstone.foodify.Model.Food.Food;
import com.capstone.foodify.Model.Response.Foods;
import com.capstone.foodify.Model.Response.Shops;
+import com.capstone.foodify.Model.Shop.Shop;
import com.google.gson.Gson;
import com.google.gson.GsonBuilder;
@@ -54,8 +55,11 @@ public interface FoodApi {
@GET("products/{id}")
Call detailFood(@Path("id") String id);
-// @GET("detail/{id}/image")
-// Call> getImageFoodById(@Path("id") String id);
+ @GET("shops/{id}")
+ Call detailShop(@Path("id") int id);
+
+ @GET("products/shops/{id}")
+ Call listFoodByShopId(@Path("id") int id, @Query("pageNo") int pageNo, @Query("pageSize") int pageSize, @Query("sortBy") String sortBy, @Query("sortDir") String sortDir);
@GET("district/{districtId}/ward")
Call> wardResponse(@Path("districtId") int district_id);
diff --git a/app/src/main/java/com/capstone/foodify/Activity/ShopDetailActivity.java b/app/src/main/java/com/capstone/foodify/Activity/ShopDetailActivity.java
index afadec7..d806031 100644
--- a/app/src/main/java/com/capstone/foodify/Activity/ShopDetailActivity.java
+++ b/app/src/main/java/com/capstone/foodify/Activity/ShopDetailActivity.java
@@ -1,6 +1,8 @@
package com.capstone.foodify.Activity;
+import androidx.annotation.NonNull;
import androidx.appcompat.app.AppCompatActivity;
+import androidx.core.widget.NestedScrollView;
import androidx.recyclerview.widget.DividerItemDecoration;
import androidx.recyclerview.widget.LinearLayoutManager;
import androidx.recyclerview.widget.RecyclerView;
@@ -8,21 +10,48 @@ import androidx.recyclerview.widget.RecyclerView;
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.FoodApi;
+import com.capstone.foodify.Common;
import com.capstone.foodify.Model.Food.Food;
import com.capstone.foodify.Adapter.FoodShopAdapter;
+import com.capstone.foodify.Model.Response.Foods;
+import com.capstone.foodify.Model.Response.Shops;
+import com.capstone.foodify.Model.Shop.Shop;
import com.capstone.foodify.R;
+import com.google.android.material.appbar.CollapsingToolbarLayout;
+import com.saadahmedsoft.popupdialog.PopupDialog;
+import com.saadahmedsoft.popupdialog.Styles;
import com.squareup.picasso.Picasso;
import java.util.ArrayList;
import java.util.List;
+import retrofit2.Call;
+import retrofit2.Callback;
+import retrofit2.Response;
+
public class ShopDetailActivity extends AppCompatActivity {
+ private static int CURRENT_PAGE;
+ private static int PAGE_SIZE = 8;
+ private static String SORT_BY = "name";
+ private static String SORT_DIR = "asc";
+ private static boolean LAST_PAGE = false;
+ private int shopId;
private List listFood = new ArrayList<>();
+ TextView content_description_text_view, student_shop_text_view, end_of_list_text_view;
ImageView imageShop, back_image;
RecyclerView recycler_view_food_shop;
FoodShopAdapter adapter;
+ private CollapsingToolbarLayout collapsingToolbarLayout;
+ private PopupDialog popupDialog;
+ private NestedScrollView nestedScrollView;
+ private ProgressBar progressBar;
+ private Shop shop;
@Override
protected void onCreate(Bundle savedInstanceState) {
@@ -33,14 +62,26 @@ public class ShopDetailActivity extends AppCompatActivity {
imageShop = findViewById(R.id.image_shop);
recycler_view_food_shop = findViewById(R.id.recycler_view_food_shop);
back_image = findViewById(R.id.back_image);
- adapter = new FoodShopAdapter();
+ adapter = new FoodShopAdapter(this);
+ collapsingToolbarLayout = findViewById(R.id.collapsing);
+ content_description_text_view = findViewById(R.id.content_description_text_view);
+ student_shop_text_view = findViewById(R.id.student_shop_text_view);
+ nestedScrollView = findViewById(R.id.food_detail);
+ progressBar = findViewById(R.id.progress_bar);
+ end_of_list_text_view = findViewById(R.id.end_of_list_text);
- //Init temp data
- Picasso.get().load("https://firebasestorage.googleapis.com/v0/b/foodify-55954.appspot.com/o/Free%20Food%20Advertising%20Banner%20Template.jpg?alt=media&token=8b836fd7-f18f-46c6-a14f-27680e51a1d5").into(imageShop);
+ popupDialog = PopupDialog.getInstance(this);
+ popupDialog.setStyle(Styles.PROGRESS).setProgressDialogTint(getResources().getColor(R.color.primaryColor, null))
+ .setCancelable(false).showDialog();
-// for(int i = 1; i <= 10; i++){
-// listFood.add(new Food("https://images.unsplash.com/photo-1546069901-ba9599a7e63c?ixlib=rb-4.0.3&ixid=MnwxMjA3fDB8MHxleHBsb3JlLWZlZWR8MXx8fGVufDB8fHx8&w=1000&q=80", "Food " + i, "50.000đ"));
-// }
+ //Get data
+ if (getIntent() != null)
+ shopId = getIntent().getIntExtra("ShopId", 0);
+
+ //Set the first page after call api
+ CURRENT_PAGE = 0;
+ getDetailShop(shopId);
+ nestedScrollView.setVisibility(View.GONE);
LinearLayoutManager linearLayoutManager = new LinearLayoutManager(this);
recycler_view_food_shop.setLayoutManager(linearLayoutManager);
@@ -48,9 +89,6 @@ public class ShopDetailActivity extends AppCompatActivity {
RecyclerView.ItemDecoration itemDecoration = new DividerItemDecoration(this, DividerItemDecoration.VERTICAL);
recycler_view_food_shop.addItemDecoration(itemDecoration);
- adapter.setData(listFood);
- recycler_view_food_shop.setAdapter(adapter);
-
back_image.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View view) {
@@ -58,5 +96,98 @@ public class ShopDetailActivity extends AppCompatActivity {
}
});
+ 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();
+ }
+ }
+ });
+ }
+
+ }
+
+ private void getListFood(int shopId){
+ FoodApi.apiService.listFoodByShopId(shopId, CURRENT_PAGE++, PAGE_SIZE, SORT_BY, SORT_DIR).enqueue(new Callback() {
+ @Override
+ public void onResponse(Call call, Response response) {
+ Foods tempFood = response.body();
+
+ if(tempFood == null)
+ return;
+
+ //Init last page from api
+ LAST_PAGE = tempFood.getPage().isLast();
+
+ //Add food to list
+ listFood.addAll(tempFood.getProducts());
+
+ adapter.setData(listFood);
+ recycler_view_food_shop.setAdapter(adapter);
+
+ initData(shop);
+ }
+
+ @Override
+ public void onFailure(Call call, Throwable t) {
+ //Check internet connection
+ Common.showNotificationError(t, getBaseContext(), ShopDetailActivity.this);
+ }
+ });
+ }
+
+ private void getDetailShop(int shopId) {
+ FoodApi.apiService.detailShop(shopId).enqueue(new Callback() {
+ @Override
+ public void onResponse(Call call, Response response) {
+ Shop tempShop = response.body();
+
+ //Init shop data to "local data" shop;
+ if(tempShop != null)
+ shop = tempShop;
+
+ getListFood(shopId);
+ }
+
+ @Override
+ public void onFailure(Call call, Throwable t) {
+ Common.showNotificationError(t, getBaseContext(), ShopDetailActivity.this);
+ }
+ });
+ }
+
+ private void initData(Shop shop) {
+ //Init data
+ Picasso.get().load(shop.getImageUrl()).into(imageShop);
+ collapsingToolbarLayout.setTitle(shop.getName());
+ content_description_text_view.setText(shop.getDescription());
+
+ //If shop is studentShop, enable tag student shop
+ if(shop.isStudent()){
+ student_shop_text_view.setVisibility(View.VISIBLE);
+ }
+
+ //If list data don't have pagination
+ if(LAST_PAGE)
+ hideProgressBarAndShowEndOfListText();
+
+ nestedScrollView.setVisibility(View.VISIBLE);
+ popupDialog.dismissDialog();
+ }
+
+ private void hideProgressBarAndShowEndOfListText(){
+ progressBar.setVisibility(View.GONE);
+ end_of_list_text_view.setVisibility(View.VISIBLE);
+ }
+
+ private void dataLoadMore() {
+ if(!LAST_PAGE){
+ getListFood(shopId);
+ } else {
+ hideProgressBarAndShowEndOfListText();
+ }
}
}
\ No newline at end of file
diff --git a/app/src/main/java/com/capstone/foodify/Adapter/BasketAdapter.java b/app/src/main/java/com/capstone/foodify/Adapter/BasketAdapter.java
index 7dc4f3e..57ca176 100644
--- a/app/src/main/java/com/capstone/foodify/Adapter/BasketAdapter.java
+++ b/app/src/main/java/com/capstone/foodify/Adapter/BasketAdapter.java
@@ -55,9 +55,15 @@ public class BasketAdapter extends RecyclerView.Adapter {
private List listFoodShop;
+ private Context context;
- public FoodShopAdapter() {
+ public FoodShopAdapter(Context context) {
+ this.context = context;
}
public void setData(List listFoodShop){
@@ -39,10 +48,61 @@ public class FoodShopAdapter extends RecyclerView.Adapter 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
@@ -54,7 +114,7 @@ public class FoodShopAdapter extends RecyclerView.Adapter call, Response response) {
//Init total page and total elements value
- TOTAL_PAGE = response.body().getPage().getTotalPages();
+ LAST_PAGE = response.body().getPage().isLast();
loadFoodAdapter(response);
@@ -158,7 +158,8 @@ public class SearchFragment extends Fragment {
@Override
public void onFailure(Call call, Throwable t) {
-
+ //Check internet connection
+ Common.showNotificationError(t, getContext(), getActivity());
}
});
}
@@ -173,7 +174,7 @@ public class SearchFragment extends Fragment {
foodAdapter.notifyDataSetChanged();
//If list data don't have pagination
- if(TOTAL_PAGE == 1)
+ if(LAST_PAGE)
hideProgressBarAndShowEndOfListText();
//If search not found
@@ -236,13 +237,7 @@ public class SearchFragment extends Fragment {
@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());
- }
+ Common.showNotificationError(t, getContext(), getActivity());
}
});
}
@@ -252,20 +247,15 @@ public class SearchFragment extends Fragment {
@Override
public void onResponse(Call call, Response response) {
//Init total page and total elements value
- TOTAL_PAGE = response.body().getPage().getTotalPages();
+ LAST_PAGE = response.body().getPage().isLast();
loadFoodAdapter(response);
}
@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());
- }
+ //Check internet connection
+ Common.showNotificationError(t, getContext(), getActivity());
}
});
}
@@ -274,20 +264,14 @@ public class SearchFragment extends Fragment {
FoodApi.apiService.listFood(page, LIMIT, "id", "asc").enqueue(new Callback() {
@Override
public void onResponse(Call call, Response response) {
- TOTAL_PAGE = response.body().getPage().getTotalPages();
+ LAST_PAGE = response.body().getPage().isLast();
loadFoodAdapter(response);
}
@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());
- }
+ Common.showNotificationError(t, getContext(), getActivity());
}
});
}
@@ -295,7 +279,7 @@ public class SearchFragment extends Fragment {
private void dataLoadMore() {
switch (ACTION_CODE){
case LIST_FOOD:{
- if(CURRENT_PAGE < TOTAL_PAGE - 1){
+ if(!LAST_PAGE){
getListFood(++CURRENT_PAGE);
} else {
hideProgressBarAndShowEndOfListText();
@@ -303,7 +287,7 @@ public class SearchFragment extends Fragment {
break;
}
case SEARCH_FOOD:{
- if(CURRENT_PAGE < TOTAL_PAGE - 1){
+ if(!LAST_PAGE){
getListFoodBySearch(searchQuery, ++CURRENT_PAGE);
} else {
hideProgressBarAndShowEndOfListText();
@@ -311,7 +295,7 @@ public class SearchFragment extends Fragment {
break;
}
case LIST_FOOD_BY_CATEGORY:{
- if(CURRENT_PAGE < TOTAL_PAGE - 1){
+ if(!LAST_PAGE){
getListFoodByCategory(++CURRENT_PAGE);
} else {
hideProgressBarAndShowEndOfListText();
diff --git a/app/src/main/res/layout/activity_shop_detail.xml b/app/src/main/res/layout/activity_shop_detail.xml
index 3ab1780..1c5dc20 100644
--- a/app/src/main/res/layout/activity_shop_detail.xml
+++ b/app/src/main/res/layout/activity_shop_detail.xml
@@ -76,6 +76,7 @@
android:layout_height="wrap_content"
app:layout_constraintTop_toTopOf="parent"
app:layout_constraintEnd_toEndOf="parent"
+ android:visibility="gone"
/>
+
+
+
+
diff --git a/app/src/main/res/layout/item_food_shop.xml b/app/src/main/res/layout/item_food_shop.xml
index 2b26d31..34ecc86 100644
--- a/app/src/main/res/layout/item_food_shop.xml
+++ b/app/src/main/res/layout/item_food_shop.xml
@@ -122,6 +122,7 @@
android:layout_height="wrap_content"
android:src="@drawable/basket_icon"
android:layout_gravity="center_vertical"
+ android:id="@+id/basket_icon"
/>