diff --git a/app/build.gradle b/app/build.gradle index 03572dc..a07d847 100644 --- a/app/build.gradle +++ b/app/build.gradle @@ -5,6 +5,14 @@ plugins { } android { + signingConfigs { + release { + storeFile file('C:\\Users\\phanh\\Desktop\\mykeystore\\foodify-keystore.jks') + storePassword 'Phanhuuloi2@@1' + keyAlias 'foodify' + keyPassword 'Phanhuuloi2@@1' + } + } namespace 'com.capstone.foodify' compileSdk 33 @@ -16,11 +24,12 @@ android { defaultConfig { applicationId "com.capstone.foodify" minSdk 26 - targetSdk 31 + targetSdk 32 versionCode 1 - versionName "1.0" + versionName "0.1.0" testInstrumentationRunner "androidx.test.runner.AndroidJUnitRunner" + signingConfig signingConfigs.release } buildTypes { @@ -67,8 +76,9 @@ dependencies { implementation 'androidx.core:core-splashscreen:1.0.0' + implementation "androidx.swiperefreshlayout:swiperefreshlayout:1.1.0" implementation 'com.google.code.gson:gson:2.10.1' - implementation 'com.google.android.material:material:1.7.0' + implementation 'com.google.android.material:material:1.8.0' implementation 'com.squareup.retrofit2:retrofit:2.9.0' implementation 'com.squareup.retrofit2:converter-gson:2.9.0' implementation 'com.squareup.retrofit2:converter-scalars:2.9.0' @@ -95,4 +105,7 @@ dependencies { implementation platform('com.google.firebase:firebase-bom:31.2.3') implementation("com.squareup.okhttp3:okhttp:4.10.0") + // ADD the API-only library to all variants + implementation 'com.google.firebase:firebase-appdistribution-api:16.0.0-beta07' + } \ No newline at end of file diff --git a/app/release/app-release.apk b/app/release/app-release.apk new file mode 100644 index 0000000..8580297 Binary files /dev/null and b/app/release/app-release.apk differ diff --git a/app/release/output-metadata.json b/app/release/output-metadata.json new file mode 100644 index 0000000..6830f46 --- /dev/null +++ b/app/release/output-metadata.json @@ -0,0 +1,20 @@ +{ + "version": 3, + "artifactType": { + "type": "APK", + "kind": "Directory" + }, + "applicationId": "com.capstone.foodify", + "variantName": "release", + "elements": [ + { + "type": "SINGLE", + "filters": [], + "attributes": [], + "versionCode": 1, + "versionName": "0.1.0", + "outputFile": "app-release.apk" + } + ], + "elementType": "File" +} \ No newline at end of file diff --git a/app/src/main/AndroidManifest.xml b/app/src/main/AndroidManifest.xml index 7d8b877..cc7bec3 100644 --- a/app/src/main/AndroidManifest.xml +++ b/app/src/main/AndroidManifest.xml @@ -1,6 +1,7 @@ + xmlns:tools="http://schemas.android.com/tools" + tools:ignore="LockedOrientationActivity"> @@ -70,45 +73,58 @@ 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 a2d448c..85f6cad 100644 --- a/app/src/main/java/com/capstone/foodify/API/FoodApi.java +++ b/app/src/main/java/com/capstone/foodify/API/FoodApi.java @@ -96,4 +96,7 @@ public interface FoodApi { @GET("products/{productId}/user") Call checkUserBuyProduct(@Path("productId") int productId, @Query("userId") int userId); + + @GET("auth/check") + Call checkIdentifiedCode(@Query("code") String code); } diff --git a/app/src/main/java/com/capstone/foodify/Activity/AccountAndProfileActivity.java b/app/src/main/java/com/capstone/foodify/Activity/AccountAndProfileActivity.java index 74d9089..4b3d62e 100644 --- a/app/src/main/java/com/capstone/foodify/Activity/AccountAndProfileActivity.java +++ b/app/src/main/java/com/capstone/foodify/Activity/AccountAndProfileActivity.java @@ -296,12 +296,7 @@ public class AccountAndProfileActivity extends AppCompatActivity { } private void showDialogCaution() { - new AestheticDialog.Builder(this, DialogStyle.FLAT, DialogType.WARNING) - .setTitle("Email chưa được xác thực!") - .setMessage("Vui lòng xác thực email để bạn có thể thực hiện việc lấy lại mật khẩu nếu quên!") - .setAnimation(DialogAnimation.SHRINK) - .setCancelable(true) - .show(); + Common.notificationDialog(this, DialogStyle.FLAT, DialogType.WARNING, "Email chưa được xác thực!", "Vui lòng xác thực email để bảo vệ tài khoản của bạn!"); } private void updateUser(String imageUrl) { diff --git a/app/src/main/java/com/capstone/foodify/Activity/ChangePasswordActivity.java b/app/src/main/java/com/capstone/foodify/Activity/ChangePasswordActivity.java index 1c45491..c25d6df 100644 --- a/app/src/main/java/com/capstone/foodify/Activity/ChangePasswordActivity.java +++ b/app/src/main/java/com/capstone/foodify/Activity/ChangePasswordActivity.java @@ -155,11 +155,7 @@ public class ChangePasswordActivity extends AppCompatActivity { @Override public void onComplete(@NonNull Task task) { if (task.isSuccessful()) { - new AestheticDialog.Builder(ChangePasswordActivity.this, DialogStyle.RAINBOW, DialogType.SUCCESS) - .setTitle("Thàng công!") - .setMessage("Đã thay đổi mật khẩu thành công!") - .setCancelable(true) - .show(); + Common.notificationDialog(ChangePasswordActivity.this, DialogStyle.RAINBOW, DialogType.SUCCESS, "Thành công!", "Đã thay đổi mật khẩu thành công!"); progressLayout.setVisibility(View.GONE); } else { @@ -169,11 +165,8 @@ public class ChangePasswordActivity extends AppCompatActivity { } }); } else { - new AestheticDialog.Builder(ChangePasswordActivity.this, DialogStyle.RAINBOW, DialogType.ERROR) - .setTitle("Lỗi!") - .setMessage("Mật khẩu không đúng! Xin vui lòng thử lại!") - .setCancelable(true) - .show(); + Common.notificationDialog(ChangePasswordActivity.this, DialogStyle.RAINBOW, DialogType.ERROR, "Lỗi!", "Mật khẩu không đúng! Xin vui lòng thử lại!"); + progressLayout.setVisibility(View.GONE); } } diff --git a/app/src/main/java/com/capstone/foodify/Activity/FoodDetailActivity.java b/app/src/main/java/com/capstone/foodify/Activity/FoodDetailActivity.java index 54d9ae4..0a60d5f 100644 --- a/app/src/main/java/com/capstone/foodify/Activity/FoodDetailActivity.java +++ b/app/src/main/java/com/capstone/foodify/Activity/FoodDetailActivity.java @@ -26,6 +26,7 @@ import androidx.constraintlayout.widget.ConstraintLayout; import androidx.core.widget.NestedScrollView; import androidx.recyclerview.widget.LinearLayoutManager; import androidx.recyclerview.widget.RecyclerView; +import androidx.swiperefreshlayout.widget.SwipeRefreshLayout; import com.capstone.foodify.API.FoodApi; import com.capstone.foodify.API.FoodApiToken; @@ -66,7 +67,6 @@ import retrofit2.Response; public class FoodDetailActivity extends AppCompatActivity { ArrayList listComment = new ArrayList<>(); - private static final int ACTION_CODE = 0; private static final int CREATE_COMMENT = 1; private static final int EDIT_COMMENT = 2; private static int CURRENT_PAGE = 0; @@ -94,6 +94,7 @@ public class FoodDetailActivity extends AppCompatActivity { private CardView user_comment_layout; private Comment commentUser = null; private ChipGroup list_category; + private SwipeRefreshLayout swipeRefreshLayout; private void initComponent() { horizontalQuantitizer = findViewById(R.id.quantity_option); @@ -124,6 +125,7 @@ public class FoodDetailActivity extends AppCompatActivity { edt_button = findViewById(R.id.edit_button); list_category = findViewById(R.id.list_category); count_sold_txt = findViewById(R.id.count_sold); + swipeRefreshLayout = findViewById(R.id.swipe_refresh); } @Override protected void onCreate(Bundle savedInstanceState) { @@ -143,14 +145,23 @@ public class FoodDetailActivity extends AppCompatActivity { if (getIntent() != null) foodId = getIntent().getStringExtra("FoodId"); - commentAdapter.setData(getListComment(0)); recyclerView_comment.setAdapter(commentAdapter); - hideUI(); - checkUserBuyThisProduct(); + getData(); + swipeRefreshLayout.setColorSchemeColors(getResources().getColor(R.color.primaryColor, null)); + + swipeRefreshLayout.setOnRefreshListener(new SwipeRefreshLayout.OnRefreshListener() { + @Override + public void onRefresh() { + listComment.clear(); + + getData(); + swipeRefreshLayout.setRefreshing(false); + } + }); if(Common.CURRENT_USER == null){ @@ -183,8 +194,6 @@ public class FoodDetailActivity extends AppCompatActivity { } }); - getFoodById(foodId); - //Turn previous action when click back_image.setOnClickListener(new View.OnClickListener() { @Override @@ -203,10 +212,10 @@ public class FoodDetailActivity extends AppCompatActivity { openCommentDialog(Gravity.CENTER, CREATE_COMMENT); } else { //If not - Toast.makeText(FoodDetailActivity.this, "Bạn cần phải mua sản phẩm trước khi bình luận!", Toast.LENGTH_SHORT).show(); + Common.notificationDialog(FoodDetailActivity.this, DialogStyle.TOASTER, DialogType.INFO, "Thông báo!", "Bạn cần phải mua sản phẩm này trước khi bình luận!"); } } else - Toast.makeText(FoodDetailActivity.this, "Bạn cần phải đăng nhập để thực hiện hành động này!", Toast.LENGTH_SHORT).show(); + Common.notificationDialog(FoodDetailActivity.this, DialogStyle.TOASTER, DialogType.WARNING, "Thông báo!", "Bạn cần phải đăng nhập trước khi thực hiện hành động này!"); } }); @@ -275,6 +284,13 @@ public class FoodDetailActivity extends AppCompatActivity { }); } + private void getData() { + CURRENT_PAGE = 0; + commentAdapter.setData(getListComment(0)); + checkUserBuyThisProduct(); + getFoodById(foodId); + } + private void checkUserBuyThisProduct(){ if(Common.CURRENT_USER != null){ @@ -347,12 +363,7 @@ public class FoodDetailActivity extends AppCompatActivity { if(Common.FINAL_SHOP.equals(food.getShop().getName())){ addFood(); } else { - new AestheticDialog.Builder(this, DialogStyle.FLAT, DialogType.INFO) - .setTitle("Thông báo!") - .setMessage("Bạn chỉ có thể đặt những món ăn cùng cửa hàng, xin vui lòng kiểm tra lại giỏ hàng!") - .setAnimation(DialogAnimation.SHRINK) - .setCancelable(true) - .show(); + Common.notificationDialog(this, DialogStyle.FLAT, DialogType.INFO, "Thông báo!", "Bạn chỉ có thể đặt những món ăn cùng cửa hàng, xin vui lòng kiểm tra lại giỏ hàng!"); } } else { @@ -512,6 +523,7 @@ public class FoodDetailActivity extends AppCompatActivity { count_sold_txt.setText(food.getSold() + " đã bán"); } + list_category.removeAllViews(); //Init category for(Category category: food.getCategories()){ Chip chip = (Chip) inflater.inflate(R.layout.chip_item, null, false); diff --git a/app/src/main/java/com/capstone/foodify/Activity/ForgotPasswordActivity.java b/app/src/main/java/com/capstone/foodify/Activity/ForgotPasswordActivity.java index 791c654..5102c17 100644 --- a/app/src/main/java/com/capstone/foodify/Activity/ForgotPasswordActivity.java +++ b/app/src/main/java/com/capstone/foodify/Activity/ForgotPasswordActivity.java @@ -78,10 +78,11 @@ public class ForgotPasswordActivity extends AppCompatActivity { boolean isNewUser = task.getResult().getSignInMethods().isEmpty(); if (isNewUser) { - new AestheticDialog.Builder(ForgotPasswordActivity.this, DialogStyle.TOASTER, DialogType.ERROR) - .setTitle("Thông báo!") - .setMessage("Tài khoản chưa được đăng ký ở hệ thống! Vui lòng kiểm tra lại") - .setCancelable(true).show(); + + Common.notificationDialog(ForgotPasswordActivity.this, DialogStyle.FLAT, DialogType.ERROR, "Thông báo!", "Email " + + "này chưa được đăng ký ở hệ thống! Vui lòng kiểm tra lại!"); + + progress_layout.setVisibility(View.GONE); } else { sendEmail(); } @@ -101,10 +102,8 @@ public class ForgotPasswordActivity extends AppCompatActivity { @Override public void onComplete(@NonNull Task task) { if(task.isSuccessful()){ - new AestheticDialog.Builder(ForgotPasswordActivity.this, DialogStyle.TOASTER, DialogType.SUCCESS) - .setTitle("Email đã được gửi!") - .setMessage("Vui lòng kiểm tra hộp thư và làm theo hướng dẫn để tiếp tục!") - .setCancelable(true).show(); + Common.notificationDialog(ForgotPasswordActivity.this, DialogStyle.FLAT, DialogType.SUCCESS, "Email đã được gửi", "Vui lòng kiểm tra " + + "hộp thư và làm theo hướng dẫn để tiếp tục!"); progress_layout.setVisibility(View.GONE); } diff --git a/app/src/main/java/com/capstone/foodify/Activity/MainActivity.java b/app/src/main/java/com/capstone/foodify/Activity/MainActivity.java index 9d65aee..37ac8fe 100644 --- a/app/src/main/java/com/capstone/foodify/Activity/MainActivity.java +++ b/app/src/main/java/com/capstone/foodify/Activity/MainActivity.java @@ -23,7 +23,9 @@ import android.view.MenuItem; import android.view.View; import android.widget.Toast; +import androidx.annotation.NonNull; import androidx.appcompat.app.AlertDialog; +import androidx.appcompat.app.AppCompatActivity; import androidx.appcompat.app.AppCompatDelegate; import androidx.appcompat.widget.AppCompatCheckBox; import androidx.constraintlayout.widget.ConstraintLayout; @@ -31,9 +33,6 @@ import androidx.core.app.ActivityCompat; import androidx.core.app.NotificationManagerCompat; import androidx.core.content.ContextCompat; import androidx.core.splashscreen.SplashScreen; - -import androidx.annotation.NonNull; -import androidx.appcompat.app.AppCompatActivity; import androidx.viewpager2.widget.ViewPager2; import com.capstone.foodify.API.FoodApiToken; @@ -56,20 +55,19 @@ import com.google.android.gms.location.LocationSettingsResponse; import com.google.android.gms.location.LocationSettingsStatusCodes; import com.google.android.gms.location.Priority; import com.google.android.gms.location.SettingsClient; -import com.google.android.gms.maps.model.LatLng; import com.google.android.gms.tasks.OnCompleteListener; import com.google.android.gms.tasks.OnFailureListener; import com.google.android.gms.tasks.OnSuccessListener; import com.google.android.gms.tasks.Task; import com.google.android.material.bottomnavigation.BottomNavigationView; import com.google.android.material.navigation.NavigationBarView; +import com.google.firebase.appdistribution.FirebaseAppDistribution; +import com.google.firebase.appdistribution.InterruptionLevel; import com.google.firebase.auth.FirebaseAuth; import com.google.firebase.auth.FirebaseUser; import com.google.firebase.auth.GetTokenResult; import com.google.firebase.messaging.FirebaseMessaging; -import org.objectweb.asm.Handle; - import java.util.Arrays; import java.util.List; @@ -80,6 +78,7 @@ import retrofit2.Response; public class MainActivity extends AppCompatActivity { + FirebaseAppDistribution firebaseAppDistribution = FirebaseAppDistribution.getInstance(); ViewPager2 viewPager2; ViewPagerAdapter viewPagerAdapter; BottomNavigationView bottomNavigationView; @@ -131,8 +130,6 @@ public class MainActivity extends AppCompatActivity { HomeFragment.setNameUser(); getTokenFCM(); - - progressLayout.setVisibility(View.GONE); } } @@ -168,6 +165,13 @@ public class MainActivity extends AppCompatActivity { startPowerSaverIntent(this); checkNotificationPermission(); + firebaseAppDistribution.showFeedbackNotification( + // Text providing notice to your testers about collection and + // processing of their feedback data + "Nhấp vào đây để đánh giá app Foodify!", + // The level of interruption for the notification + InterruptionLevel.HIGH); + if (Common.CURRENT_LOCATION == null) { mFusedLocationClient = LocationServices.getFusedLocationProviderClient(this); @@ -206,8 +210,10 @@ public class MainActivity extends AppCompatActivity { stopLocationUpdates(); } + progressLayout.setVisibility(View.GONE); + } - }, 5000); + }, 4000); } @@ -230,6 +236,8 @@ public class MainActivity extends AppCompatActivity { public void onResponse(Call call, Response response) { if(response.code() != 200) Toast.makeText(MainActivity.this, "Không thể cập nhật FCM Token. Mã lỗi: " + response.code(), Toast.LENGTH_SHORT).show(); + + progressLayout.setVisibility(View.GONE); } @Override diff --git a/app/src/main/java/com/capstone/foodify/Activity/OrderCheckOutActivity.java b/app/src/main/java/com/capstone/foodify/Activity/OrderCheckOutActivity.java index 1a1dd47..d92c590 100644 --- a/app/src/main/java/com/capstone/foodify/Activity/OrderCheckOutActivity.java +++ b/app/src/main/java/com/capstone/foodify/Activity/OrderCheckOutActivity.java @@ -102,7 +102,7 @@ public class OrderCheckOutActivity extends AppCompatActivity { spn_ward = findViewById(R.id.ward); edt_address_detect = findViewById(R.id.edt_address_detect); manual_input_address_layout = findViewById(R.id.manual_input_address_layout); - adapter = new OrderDetailAdapter(); + adapter = new OrderDetailAdapter(OrderCheckOutActivity.this); recyclerView = findViewById(R.id.list_order); back_image = findViewById(R.id.back_image); change_address_button = findViewById(R.id.change_address_button); @@ -144,10 +144,8 @@ public class OrderCheckOutActivity extends AppCompatActivity { //Check current location is null or not if(Common.CURRENT_LOCATION == null){ auto_detect_location.setEnabled(false); - new AestheticDialog.Builder(OrderCheckOutActivity.this, DialogStyle.FLAT, DialogType.INFO) - .setTitle("Thông báo") - .setMessage("Tính năng \"Lấy vị trí theo thiết bị của bạn\" sẽ không khả dụng do ứng dụng chưa được cấp quyền vị trí!") - .setCancelable(true).show(); + + Common.notificationDialog(OrderCheckOutActivity.this, DialogStyle.FLAT, DialogType.INFO, "Thông báo", "Tính năng \"Lấy vị trí theo thiết bị của bạn\" sẽ không khả dụng do ứng dụng chưa được cấp quyền vị trí!"); } @@ -254,12 +252,9 @@ public class OrderCheckOutActivity extends AppCompatActivity { btn_Pay.setEnabled(true); btn_ZaloPay.setEnabled(true); } else { - new AestheticDialog.Builder(OrderCheckOutActivity.this, DialogStyle.FLAT, DialogType.INFO) - .setTitle("Thông báo!") - .setMessage("Chưa thể lấy được vị trí shop, vui lòng thử lại hoặc có thể chọn \"Đến shop lấy\" để tiếp tục!") - .setAnimation(DialogAnimation.SHRINK) - .setCancelable(true) - .show(); + + Common.notificationDialog(OrderCheckOutActivity.this, DialogStyle.FLAT, DialogType.INFO, "Thông báo!", "Chưa thể lấy được vị trí shop, vui lòng thử lại hoặc có thể chọn \"Đến shop lấy\" để tiếp tục!"); + progress_layout.setVisibility(View.GONE); btn_Pay.setEnabled(false); @@ -395,11 +390,7 @@ public class OrderCheckOutActivity extends AppCompatActivity { @Override public void onPaymentCanceled(String zpTransToken, String appTransID) { - new AestheticDialog.Builder(OrderCheckOutActivity.this, DialogStyle.RAINBOW, DialogType.INFO) - .setTitle("Thông báo!") - .setMessage("Huỷ thanh toán thành công!") - .setCancelable(true) - .show(); + Common.notificationDialog(OrderCheckOutActivity.this, DialogStyle.RAINBOW, DialogType.INFO, "Thông báo!", "Huỷ thanh toán thành công!"); progress_layout.setVisibility(View.GONE); } diff --git a/app/src/main/java/com/capstone/foodify/Activity/OrderDetailActivity.java b/app/src/main/java/com/capstone/foodify/Activity/OrderDetailActivity.java index 6d205e2..62bc662 100644 --- a/app/src/main/java/com/capstone/foodify/Activity/OrderDetailActivity.java +++ b/app/src/main/java/com/capstone/foodify/Activity/OrderDetailActivity.java @@ -189,7 +189,7 @@ public class OrderDetailActivity extends AppCompatActivity { address = findViewById(R.id.address); orderTime = findViewById(R.id.order_time); total = findViewById(R.id.total); - adapter = new OrderDetailAdapter(); + adapter = new OrderDetailAdapter(OrderDetailActivity.this); recyclerView = findViewById(R.id.recycler_view_order_detail); back_image = findViewById(R.id.back_image); btn_cancel_order = findViewById(R.id.cancel_order_button); diff --git a/app/src/main/java/com/capstone/foodify/Activity/SignUpActivity.java b/app/src/main/java/com/capstone/foodify/Activity/SignUpActivity.java index 68eed04..57d5cb6 100644 --- a/app/src/main/java/com/capstone/foodify/Activity/SignUpActivity.java +++ b/app/src/main/java/com/capstone/foodify/Activity/SignUpActivity.java @@ -29,6 +29,8 @@ import com.capstone.foodify.Model.DistrictWardResponse; import com.capstone.foodify.Model.Response.CustomResponse; import com.capstone.foodify.Model.User; import com.capstone.foodify.R; +import com.google.android.gms.tasks.OnCompleteListener; +import com.google.android.gms.tasks.Task; import com.google.android.material.button.MaterialButton; import com.google.android.material.textfield.TextInputLayout; import com.google.firebase.FirebaseException; @@ -36,6 +38,7 @@ import com.google.firebase.auth.FirebaseAuth; import com.google.firebase.auth.PhoneAuthCredential; import com.google.firebase.auth.PhoneAuthOptions; import com.google.firebase.auth.PhoneAuthProvider; +import com.google.firebase.auth.SignInMethodQueryResult; import java.text.SimpleDateFormat; import java.time.LocalDate; @@ -45,6 +48,7 @@ import java.util.ArrayList; import java.util.Calendar; import java.util.List; import java.util.Locale; +import java.util.Objects; import java.util.concurrent.TimeUnit; import java.util.regex.Matcher; import java.util.regex.Pattern; @@ -64,7 +68,7 @@ public class SignUpActivity extends AppCompatActivity { private MaterialButton signUpButton; private ConstraintLayout progressLayout; private String email, phone, name, dateOfBirth, address, district, ward, password = null, identifiedCode; - + private static boolean validIdentifiedCode, validPhone, validEmail = false; private static final ArrayList wardList = new ArrayList<>(); private static final ArrayList districtList = new ArrayList<>(); @@ -157,7 +161,10 @@ public class SignUpActivity extends AppCompatActivity { public void onClick(View v) { if(validateData()){ loading(); - checkEmailOrPhoneExist(); + + checkIdentifiedCodeExist(); + checkPhoneExist(); + checkEmailExist(); } } }); @@ -197,7 +204,55 @@ public class SignUpActivity extends AppCompatActivity { }); } - private void checkEmailOrPhoneExist(){ + private void checkEmailExist(){ + FirebaseAuth.getInstance().fetchSignInMethodsForEmail(email).addOnCompleteListener(new OnCompleteListener() { + @Override + public void onComplete(@NonNull Task task) { + + boolean isNewUser = Objects.requireNonNull(task.getResult().getSignInMethods()).isEmpty(); + + if (!isNewUser) { + textInput_email.setError("Email này đã được đăng ký sử dụng!"); + validEmail = false; + + } else { + + validEmail = true; + signUp(); + } + + } + }); + } + + private void checkIdentifiedCodeExist(){ + FoodApi.apiService.checkIdentifiedCode(identifiedCode).enqueue(new Callback() { + @Override + public void onResponse(Call call, Response response) { + if(response.code() == 200){ + CustomResponse tempData = response.body(); + + assert tempData != null; + if(tempData.isTrue()){ + //Have identifiedCode exist + validIdentifiedCode = false; + textInput_id_card.setError("Số này đã được đăng ký!"); + } else { + validIdentifiedCode = true; + textInput_id_card.setErrorEnabled(false); + + signUp(); + } + } + } + + @Override + public void onFailure(Call call, Throwable t) { + + } + }); + } + private void checkPhoneExist(){ //Create user object User user = new User(new Address(address, ward, district), dateOfBirth, email, name, identifiedCode, phone); @@ -206,17 +261,16 @@ public class SignUpActivity extends AppCompatActivity { public void onResponse(Call call, Response response) { CustomResponse dataTemp = response.body(); - boolean isExist = false; - - if(dataTemp != null) - isExist = dataTemp.isTrue(); - - if(!isExist){ - //If user not exist on database, the app will create account - signUp(user); + loadCompleted(); + assert dataTemp != null; + if(dataTemp.isTrue()){ + textInput_phone.setError("Số điện thoại đã được đăng ký!"); + validPhone = false; } else { - loadCompleted(); - Toast.makeText(SignUpActivity.this, "Địa chỉ email hoặc số điện thoại đã trùng, vui lòng kiểm tra lại!", Toast.LENGTH_SHORT).show(); + validPhone = true; + textInput_phone.setErrorEnabled(false); + + signUp(); } } @@ -269,7 +323,7 @@ public class SignUpActivity extends AppCompatActivity { } //Check identified Code - if(identifiedCode.length() < 9 && identifiedCode.length() > 10){ + if(identifiedCode.length() < 8 || identifiedCode.length() > 11){ textInput_id_card.setError("CCCD / CMND không hợp lệ!"); dataHasValidate = false; } else { @@ -355,47 +409,52 @@ public class SignUpActivity extends AppCompatActivity { } } - private void signUp(User user){ - FirebaseAuth auth = FirebaseAuth.getInstance(); - auth.setLanguageCode("vi"); - PhoneAuthOptions options = PhoneAuthOptions.newBuilder(auth) - .setPhoneNumber(Common.PHONE_CODE + edt_phone.getText().toString()) - .setTimeout(0L, TimeUnit.SECONDS) - .setActivity(this) - .setCallbacks(new PhoneAuthProvider.OnVerificationStateChangedCallbacks() { - @Override - public void onCodeSent(@NonNull String verificationId, - @NonNull PhoneAuthProvider.ForceResendingToken forceResendingToken) { - loadCompleted(); + private void signUp(){ - Intent intent = new Intent(SignUpActivity.this, VerifyAccountActivity.class); - intent.putExtra("user", user); - intent.putExtra("phone", edt_phone.getText().toString()); - intent.putExtra("verificationId", verificationId); - intent.putExtra("token", forceResendingToken); - intent.putExtra("password", password); - startActivity(intent); - finish(); - } + if(validEmail && validIdentifiedCode && validPhone){ + User user = new User(new Address(address, ward, district), dateOfBirth, email, name, identifiedCode, phone); - @Override - public void onVerificationCompleted(@NonNull PhoneAuthCredential phoneAuthCredential) { - loadCompleted(); - } + FirebaseAuth auth = FirebaseAuth.getInstance(); + auth.setLanguageCode("vi"); + PhoneAuthOptions options = PhoneAuthOptions.newBuilder(auth) + .setPhoneNumber(Common.PHONE_CODE + edt_phone.getText().toString()) + .setTimeout(0L, TimeUnit.SECONDS) + .setActivity(this) + .setCallbacks(new PhoneAuthProvider.OnVerificationStateChangedCallbacks() { + @Override + public void onCodeSent(@NonNull String verificationId, + @NonNull PhoneAuthProvider.ForceResendingToken forceResendingToken) { + loadCompleted(); - @Override - public void onVerificationFailed(@NonNull FirebaseException e) { - // ... - loadCompleted(); - showError(e.toString()); - } -}) - .build(); - PhoneAuthProvider.verifyPhoneNumber(options); - // [END auth_test_phone_verify] + Intent intent = new Intent(SignUpActivity.this, VerifyAccountActivity.class); + intent.putExtra("user", user); + intent.putExtra("phone", edt_phone.getText().toString()); + intent.putExtra("verificationId", verificationId); + intent.putExtra("token", forceResendingToken); + intent.putExtra("password", password); + startActivity(intent); + finish(); + } + + @Override + public void onVerificationCompleted(@NonNull PhoneAuthCredential phoneAuthCredential) { + loadCompleted(); + } + + @Override + public void onVerificationFailed(@NonNull FirebaseException e) { + // ... + loadCompleted(); + showError(e.toString()); + } + }).build(); + + PhoneAuthProvider.verifyPhoneNumber(options); + // [END auth_test_phone_verify] } + } -private void showError(String msg){ + private void showError(String msg){ errorText.setText(msg); } 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 98b12ad..e58a016 100644 --- a/app/src/main/java/com/capstone/foodify/Adapter/BasketAdapter.java +++ b/app/src/main/java/com/capstone/foodify/Adapter/BasketAdapter.java @@ -1,7 +1,9 @@ package com.capstone.foodify.Adapter; import android.annotation.SuppressLint; +import android.content.ContentResolver; import android.content.Context; +import android.content.Intent; import android.view.LayoutInflater; import android.view.View; import android.view.ViewGroup; @@ -12,6 +14,7 @@ import android.widget.TextView; import androidx.annotation.NonNull; import androidx.recyclerview.widget.RecyclerView; +import com.capstone.foodify.Activity.FoodDetailActivity; import com.capstone.foodify.Common; import com.capstone.foodify.Fragment.BasketFragment; import com.capstone.foodify.Model.Basket; @@ -27,9 +30,11 @@ public class BasketAdapter extends RecyclerView.Adapter listBasketFood; private final BasketFragment basketFragment; + private Context context; - public BasketAdapter(BasketFragment basketFragment) { + public BasketAdapter(BasketFragment basketFragment, Context context) { this.basketFragment = basketFragment; + this.context = context; } @SuppressLint("NotifyDataSetChanged") @@ -123,6 +128,15 @@ public class BasketAdapter extends RecyclerView.Adapter{ public List listFoodInBasket; - - public OrderDetailAdapter(){} + public Context context; + public OrderDetailAdapter(Context context){ + this.context = context; + } public void setData(List listFoodInBasket){ this.listFoodInBasket = listFoodInBasket; @@ -65,6 +70,15 @@ public class OrderDetailAdapter extends RecyclerView.Adapter> call, Throwable t) { - //Dismiss progress bar - progressLayout.setVisibility(View.GONE); } }); } @@ -157,8 +151,6 @@ public class HomeFragment extends Fragment { if(getActivity() != null) Common.showNotificationError(getContext(), getActivity()); - //Dismiss progress bar - progressLayout.setVisibility(View.GONE); } }); } diff --git a/app/src/main/java/com/capstone/foodify/Fragment/Order/CancelOrderFragment.java b/app/src/main/java/com/capstone/foodify/Fragment/Order/CancelOrderFragment.java index 46273eb..aa8194e 100644 --- a/app/src/main/java/com/capstone/foodify/Fragment/Order/CancelOrderFragment.java +++ b/app/src/main/java/com/capstone/foodify/Fragment/Order/CancelOrderFragment.java @@ -7,6 +7,7 @@ import androidx.core.widget.NestedScrollView; import androidx.fragment.app.Fragment; import androidx.recyclerview.widget.LinearLayoutManager; import androidx.recyclerview.widget.RecyclerView; +import androidx.swiperefreshlayout.widget.SwipeRefreshLayout; import android.view.LayoutInflater; import android.view.View; @@ -44,6 +45,7 @@ public class CancelOrderFragment extends Fragment { private ProgressBar progressBar; private TextView endOfListText; private LinearLayout empty_layout; + private SwipeRefreshLayout swipeRefreshLayout; @Override public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) { @@ -53,7 +55,7 @@ public class CancelOrderFragment extends Fragment { //Init Component initComponent(view); - getOrderUser(0); + getOrderUser(CURRENT_PAGE); orderAdapter = new OrderAdapter(getContext()); @@ -73,6 +75,22 @@ public class CancelOrderFragment extends Fragment { }); } + swipeRefreshLayout.setColorSchemeColors(getResources().getColor(R.color.primaryColor, null)); + swipeRefreshLayout.setOnRefreshListener(new SwipeRefreshLayout.OnRefreshListener() { + @Override + public void onRefresh() { + listOrders.clear(); + CURRENT_PAGE = 0; + + getOrderUser(CURRENT_PAGE); + + nestedScrollView.setVisibility(View.VISIBLE); + empty_layout.setVisibility(View.GONE); + + swipeRefreshLayout.setRefreshing(false); + } + }); + return view; } @@ -82,6 +100,7 @@ public class CancelOrderFragment extends Fragment { progressBar = view.findViewById(R.id.progress_bar); endOfListText = view.findViewById(R.id.end_of_list_text); empty_layout = view.findViewById(R.id.empty_layout); + swipeRefreshLayout = view.findViewById(R.id.swipe_refresh); } private void getOrderUser(int page){ diff --git a/app/src/main/java/com/capstone/foodify/Fragment/Order/CompleteOrderFragment.java b/app/src/main/java/com/capstone/foodify/Fragment/Order/CompleteOrderFragment.java index f7ac704..249df1e 100644 --- a/app/src/main/java/com/capstone/foodify/Fragment/Order/CompleteOrderFragment.java +++ b/app/src/main/java/com/capstone/foodify/Fragment/Order/CompleteOrderFragment.java @@ -7,6 +7,7 @@ import androidx.core.widget.NestedScrollView; import androidx.fragment.app.Fragment; import androidx.recyclerview.widget.LinearLayoutManager; import androidx.recyclerview.widget.RecyclerView; +import androidx.swiperefreshlayout.widget.SwipeRefreshLayout; import android.view.LayoutInflater; import android.view.View; @@ -45,6 +46,7 @@ public class CompleteOrderFragment extends Fragment { private ProgressBar progressBar; private TextView endOfListText; private LinearLayout empty_layout; + private SwipeRefreshLayout swipeRefreshLayout; @Override public View onCreateView(LayoutInflater inflater, ViewGroup container, @@ -55,7 +57,7 @@ public class CompleteOrderFragment extends Fragment { //Init Component initComponent(view); - getOrderUser(0); + getOrderUser(CURRENT_PAGE); orderAdapter = new OrderAdapter(getContext()); @@ -75,6 +77,22 @@ public class CompleteOrderFragment extends Fragment { }); } + swipeRefreshLayout.setColorSchemeColors(getResources().getColor(R.color.primaryColor, null)); + swipeRefreshLayout.setOnRefreshListener(new SwipeRefreshLayout.OnRefreshListener() { + @Override + public void onRefresh() { + listOrders.clear(); + CURRENT_PAGE = 0; + + getOrderUser(CURRENT_PAGE); + + nestedScrollView.setVisibility(View.VISIBLE); + empty_layout.setVisibility(View.GONE); + + swipeRefreshLayout.setRefreshing(false); + } + }); + return view; } @@ -84,6 +102,7 @@ public class CompleteOrderFragment extends Fragment { progressBar = view.findViewById(R.id.progress_bar); endOfListText = view.findViewById(R.id.end_of_list_text); empty_layout = view.findViewById(R.id.empty_layout); + swipeRefreshLayout = view.findViewById(R.id.swipe_refresh); } private void getOrderUser(int page){ diff --git a/app/src/main/java/com/capstone/foodify/Fragment/Order/PreparingFragment.java b/app/src/main/java/com/capstone/foodify/Fragment/Order/PreparingFragment.java index 2e830a5..eca719b 100644 --- a/app/src/main/java/com/capstone/foodify/Fragment/Order/PreparingFragment.java +++ b/app/src/main/java/com/capstone/foodify/Fragment/Order/PreparingFragment.java @@ -7,6 +7,7 @@ import androidx.core.widget.NestedScrollView; import androidx.fragment.app.Fragment; import androidx.recyclerview.widget.LinearLayoutManager; import androidx.recyclerview.widget.RecyclerView; +import androidx.swiperefreshlayout.widget.SwipeRefreshLayout; import android.view.LayoutInflater; import android.view.View; @@ -45,6 +46,8 @@ public class PreparingFragment extends Fragment { private TextView endOfListText; private LinearLayout empty_layout; + private SwipeRefreshLayout swipeRefreshLayout; + @Override public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) { @@ -54,7 +57,7 @@ public class PreparingFragment extends Fragment { //Init Component initComponent(view); - getOrderUser(0); + getOrderUser(CURRENT_PAGE); orderAdapter = new OrderAdapter(getContext()); @@ -74,6 +77,22 @@ public class PreparingFragment extends Fragment { }); } + swipeRefreshLayout.setColorSchemeColors(getResources().getColor(R.color.primaryColor, null)); + swipeRefreshLayout.setOnRefreshListener(new SwipeRefreshLayout.OnRefreshListener() { + @Override + public void onRefresh() { + listOrders.clear(); + CURRENT_PAGE = 0; + + getOrderUser(CURRENT_PAGE); + + nestedScrollView.setVisibility(View.VISIBLE); + empty_layout.setVisibility(View.GONE); + + swipeRefreshLayout.setRefreshing(false); + } + }); + return view; } @@ -83,6 +102,7 @@ public class PreparingFragment extends Fragment { progressBar = view.findViewById(R.id.progress_bar); endOfListText = view.findViewById(R.id.end_of_list_text); empty_layout = view.findViewById(R.id.empty_layout); + swipeRefreshLayout = view.findViewById(R.id.swipe_refresh); } private void getOrderUser(int page){ diff --git a/app/src/main/java/com/capstone/foodify/Fragment/Order/ProcessOderFragment.java b/app/src/main/java/com/capstone/foodify/Fragment/Order/ProcessOderFragment.java index d0a345d..2eb7eb1 100644 --- a/app/src/main/java/com/capstone/foodify/Fragment/Order/ProcessOderFragment.java +++ b/app/src/main/java/com/capstone/foodify/Fragment/Order/ProcessOderFragment.java @@ -15,6 +15,7 @@ import androidx.core.widget.NestedScrollView; import androidx.fragment.app.Fragment; import androidx.recyclerview.widget.LinearLayoutManager; import androidx.recyclerview.widget.RecyclerView; +import androidx.swiperefreshlayout.widget.SwipeRefreshLayout; import com.capstone.foodify.API.FoodApiToken; import com.capstone.foodify.Adapter.OrderAdapter; @@ -44,6 +45,7 @@ public class ProcessOderFragment extends Fragment { private ProgressBar progressBar; private TextView endOfListText; private LinearLayout empty_layout; + private SwipeRefreshLayout swipeRefreshLayout; @Override public View onCreateView(LayoutInflater inflater, ViewGroup container, @@ -54,10 +56,10 @@ public class ProcessOderFragment extends Fragment { //Init Component initComponent(view); - getOrderUser(0); - orderAdapter = new OrderAdapter(getContext()); + getOrderUser(CURRENT_PAGE); + LinearLayoutManager linearLayoutManager = new LinearLayoutManager(getContext(), RecyclerView.VERTICAL, false); recyclerView.setLayoutManager(linearLayoutManager); @@ -74,6 +76,23 @@ public class ProcessOderFragment extends Fragment { }); } + swipeRefreshLayout.setColorSchemeColors(getResources().getColor(R.color.primaryColor, null)); + + swipeRefreshLayout.setOnRefreshListener(new SwipeRefreshLayout.OnRefreshListener() { + @Override + public void onRefresh() { + listOrders.clear(); + CURRENT_PAGE = 0; + + getOrderUser(CURRENT_PAGE); + + nestedScrollView.setVisibility(View.VISIBLE); + empty_layout.setVisibility(View.GONE); + + swipeRefreshLayout.setRefreshing(false); + } + }); + return view; } @@ -85,6 +104,7 @@ public class ProcessOderFragment extends Fragment { progressBar = view.findViewById(R.id.progress_bar); endOfListText = view.findViewById(R.id.end_of_list_text); empty_layout = view.findViewById(R.id.empty_layout); + swipeRefreshLayout = view.findViewById(R.id.swipe_refresh); } private void getOrderUser(int page){ diff --git a/app/src/main/java/com/capstone/foodify/Fragment/Order/ShipOrderFragment.java b/app/src/main/java/com/capstone/foodify/Fragment/Order/ShipOrderFragment.java index 498c3f6..00dfc31 100644 --- a/app/src/main/java/com/capstone/foodify/Fragment/Order/ShipOrderFragment.java +++ b/app/src/main/java/com/capstone/foodify/Fragment/Order/ShipOrderFragment.java @@ -7,6 +7,7 @@ import androidx.core.widget.NestedScrollView; import androidx.fragment.app.Fragment; import androidx.recyclerview.widget.LinearLayoutManager; import androidx.recyclerview.widget.RecyclerView; +import androidx.swiperefreshlayout.widget.SwipeRefreshLayout; import android.view.LayoutInflater; import android.view.View; @@ -45,6 +46,7 @@ public class ShipOrderFragment extends Fragment { private ProgressBar progressBar; private TextView endOfListText; private LinearLayout empty_layout; + private SwipeRefreshLayout swipeRefreshLayout; @Override public View onCreateView(LayoutInflater inflater, ViewGroup container, @@ -55,7 +57,7 @@ public class ShipOrderFragment extends Fragment { //Init Component initComponent(view); - getOrderUser(0); + getOrderUser(CURRENT_PAGE); orderAdapter = new OrderAdapter(getContext()); @@ -74,6 +76,23 @@ public class ShipOrderFragment extends Fragment { } }); } + + swipeRefreshLayout.setColorSchemeColors(getResources().getColor(R.color.primaryColor, null)); + swipeRefreshLayout.setOnRefreshListener(new SwipeRefreshLayout.OnRefreshListener() { + @Override + public void onRefresh() { + listOrders.clear(); + CURRENT_PAGE = 0; + + getOrderUser(CURRENT_PAGE); + + nestedScrollView.setVisibility(View.VISIBLE); + empty_layout.setVisibility(View.GONE); + + swipeRefreshLayout.setRefreshing(false); + } + }); + return view; } @@ -83,6 +102,7 @@ public class ShipOrderFragment extends Fragment { progressBar = view.findViewById(R.id.progress_bar); endOfListText = view.findViewById(R.id.end_of_list_text); empty_layout = view.findViewById(R.id.empty_layout); + swipeRefreshLayout = view.findViewById(R.id.swipe_refresh); } private void getOrderUser(int page){ diff --git a/app/src/main/res/layout/activity_food_detail.xml b/app/src/main/res/layout/activity_food_detail.xml index df6a038..96a3280 100644 --- a/app/src/main/res/layout/activity_food_detail.xml +++ b/app/src/main/res/layout/activity_food_detail.xml @@ -44,427 +44,436 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + - - - - - - - - - - - - - - - - - - - - - - -