diff --git a/app/build.gradle b/app/build.gradle index 86437d7..bd05672 100644 --- a/app/build.gradle +++ b/app/build.gradle @@ -19,7 +19,13 @@ android { minSdk 26 targetSdk 30 versionCode 1 - versionName "1.0" + versionName "0.2.1" + + configurations.all { + resolutionStrategy { + force 'androidx.appcompat:appcompat:1.4.2' + } + } testInstrumentationRunner "androidx.test.runner.AndroidJUnitRunner" } @@ -43,7 +49,7 @@ dependencies { implementation 'androidx.core:core-splashscreen:1.0.0' - implementation 'androidx.appcompat:appcompat:1.4.1' + implementation 'androidx.appcompat:appcompat:1.4.2' implementation 'com.google.android.material:material:1.6.0' implementation 'androidx.constraintlayout:constraintlayout:2.1.4' @@ -55,6 +61,7 @@ dependencies { testImplementation 'junit:junit:4.13.2' androidTestImplementation 'androidx.test.ext:junit:1.1.5' androidTestImplementation 'androidx.test.espresso:espresso-core:3.5.1' + implementation "androidx.swiperefreshlayout:swiperefreshlayout:1.1.0" implementation 'com.makeramen:roundedimageview:2.3.0' implementation 'com.squareup.retrofit2:retrofit:2.9.0' @@ -63,6 +70,10 @@ dependencies { implementation 'com.github.gabriel-TheCode:AestheticDialogs:1.3.6' implementation 'com.saadahmedev.popup-dialog:popup-dialog:1.0.2' implementation 'com.squareup.picasso:picasso:2.71828' + implementation 'com.github.techinessoverloaded:progress-dialog:1.5.1' implementation 'com.google.android.gms:play-services-location:21.0.1' + + // ADD the API-only library to all variants + implementation 'com.google.firebase:firebase-appdistribution:16.0.0-beta08' } \ No newline at end of file diff --git a/app/release/output-metadata.json b/app/release/output-metadata.json index f9f09c5..581f929 100644 --- a/app/release/output-metadata.json +++ b/app/release/output-metadata.json @@ -12,7 +12,7 @@ "filters": [], "attributes": [], "versionCode": 1, - "versionName": "1.0", + "versionName": "0.2.1", "outputFile": "app-release.apk" } ], diff --git a/app/src/main/AndroidManifest.xml b/app/src/main/AndroidManifest.xml index f0df2d0..c7489d2 100644 --- a/app/src/main/AndroidManifest.xml +++ b/app/src/main/AndroidManifest.xml @@ -9,7 +9,7 @@ - + + + + - + android:exported="false" /> + android:exported="false" + /> + + \ No newline at end of file diff --git a/app/src/main/java/com/capstone/foodify/shipper/Activity/AccountAndProfileActivity.java b/app/src/main/java/com/capstone/foodify/shipper/Activity/AccountAndProfileActivity.java index 9143db5..0fe1660 100644 --- a/app/src/main/java/com/capstone/foodify/shipper/Activity/AccountAndProfileActivity.java +++ b/app/src/main/java/com/capstone/foodify/shipper/Activity/AccountAndProfileActivity.java @@ -61,7 +61,6 @@ public class AccountAndProfileActivity extends AppCompatActivity { final private StorageReference storageReference = FirebaseStorage.getInstance().getReference(); ConstraintLayout progressLayout; FirebaseAuth mAuth; - FirebaseUser firebaseUser; @Override protected void onCreate(Bundle savedInstanceState) { diff --git a/app/src/main/java/com/capstone/foodify/shipper/Activity/ForgotPasswordActivity.java b/app/src/main/java/com/capstone/foodify/shipper/Activity/ForgotPasswordActivity.java new file mode 100644 index 0000000..70e33c8 --- /dev/null +++ b/app/src/main/java/com/capstone/foodify/shipper/Activity/ForgotPasswordActivity.java @@ -0,0 +1,134 @@ +package com.capstone.foodify.shipper.Activity; + +import androidx.annotation.NonNull; +import androidx.appcompat.app.AppCompatActivity; +import androidx.constraintlayout.widget.ConstraintLayout; + +import android.os.Bundle; +import android.view.View; +import android.widget.EditText; +import android.widget.ImageView; + +import com.capstone.foodify.shipper.Common; +import com.capstone.foodify.shipper.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.auth.FirebaseAuth; +import com.google.firebase.auth.SignInMethodQueryResult; +import com.thecode.aestheticdialogs.DialogStyle; +import com.thecode.aestheticdialogs.DialogType; + +import java.util.regex.Matcher; +import java.util.regex.Pattern; + +public class ForgotPasswordActivity extends AppCompatActivity { + private FirebaseAuth mAuth; + TextInputLayout textInput_email; + EditText edt_email; + MaterialButton send_code_button; + ConstraintLayout progress_layout; + ImageView back_image; + @Override + protected void onCreate(Bundle savedInstanceState) { + super.onCreate(savedInstanceState); + setContentView(R.layout.activity_forgot_password); + + initComponent(); + + mAuth = FirebaseAuth.getInstance(); + + //Back button + back_image.setOnClickListener(new View.OnClickListener() { + @Override + public void onClick(View view) { + onBackPressed(); + finish(); + } + }); + + send_code_button.setOnClickListener(new View.OnClickListener() { + @Override + public void onClick(View view) { + progress_layout.setVisibility(View.VISIBLE); + if(checkEmailValid()){ + mAuth.setLanguageCode("vi"); + + mAuth.fetchSignInMethodsForEmail(edt_email.getText().toString()) + .addOnCompleteListener(new OnCompleteListener() { + @Override + public void onComplete(@NonNull Task task) { + + boolean isNewUser = task.getResult().getSignInMethods().isEmpty(); + + if (isNewUser) { + + 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(); + } + + } + }); + } + } + }); + + setFontUI(); + } + + private void sendEmail(){ + + mAuth.sendPasswordResetEmail(edt_email.getText().toString()).addOnCompleteListener(new OnCompleteListener() { + @Override + public void onComplete(@NonNull Task task) { + if(task.isSuccessful()){ + 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); + } + } + }); + + } + + private boolean checkEmailValid() { + boolean dataHasValidate = true; + + //Check phone number + if (edt_email.getText().toString().isEmpty()) { + textInput_email.setError("Email không được bỏ trống!"); + dataHasValidate = false; + } else { + + //Check email valid + Pattern patternEmail = Pattern.compile(Common.VALID_EMAIL_ADDRESS_REGEX, Pattern.CASE_INSENSITIVE); + Matcher matcherEmail = patternEmail.matcher(edt_email.getText().toString()); + if (!matcherEmail.matches()) { + textInput_email.setError("Địa chỉ email không đúng định dạng. Xin vui lòng kiểm tra lại!"); + dataHasValidate = false; + } else { + textInput_email.setErrorEnabled(false); + } + } + + return dataHasValidate; + } + private void setFontUI() { + + textInput_email.setTypeface(Common.setFontBebas(getAssets())); + } + + private void initComponent() { + textInput_email = findViewById(R.id.textInput_email); + back_image = findViewById(R.id.back_image); + send_code_button = findViewById(R.id.send_code_button); + edt_email = findViewById(R.id.edt_email); + progress_layout = findViewById(R.id.progress_layout); + } +} \ No newline at end of file diff --git a/app/src/main/java/com/capstone/foodify/shipper/Activity/MainActivity.java b/app/src/main/java/com/capstone/foodify/shipper/Activity/MainActivity.java index 66327e6..edf0836 100644 --- a/app/src/main/java/com/capstone/foodify/shipper/Activity/MainActivity.java +++ b/app/src/main/java/com/capstone/foodify/shipper/Activity/MainActivity.java @@ -2,6 +2,8 @@ package com.capstone.foodify.shipper.Activity; import android.Manifest; import android.annotation.SuppressLint; +import android.app.job.JobInfo; +import android.app.job.JobScheduler; import android.content.ComponentName; import android.content.Context; import android.content.DialogInterface; @@ -26,20 +28,31 @@ import androidx.appcompat.widget.AppCompatCheckBox; import androidx.core.app.ActivityCompat; import androidx.core.app.NotificationManagerCompat; import androidx.core.content.ContextCompat; +import androidx.fragment.app.Fragment; +import androidx.fragment.app.FragmentTransaction; import androidx.viewpager2.widget.ViewPager2; import com.capstone.foodify.shipper.API.FoodApiToken; import com.capstone.foodify.shipper.BuildConfig; import com.capstone.foodify.shipper.Common; +import com.capstone.foodify.shipper.Fragment.OrderFragment; import com.capstone.foodify.shipper.Model.CustomResponse; import com.capstone.foodify.shipper.R; +import com.capstone.foodify.shipper.RefreshTokenService; import com.capstone.foodify.shipper.ViewPagerAdapter; import com.google.android.gms.tasks.OnCompleteListener; 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.AppDistributionRelease; +import com.google.firebase.appdistribution.FirebaseAppDistribution; +import com.google.firebase.appdistribution.InterruptionLevel; +import com.google.firebase.appdistribution.OnProgressListener; +import com.google.firebase.appdistribution.UpdateProgress; import com.google.firebase.messaging.FirebaseMessaging; +import com.techiness.progressdialoglibrary.ProgressDialog; +import java.sql.SQLOutput; import java.util.Arrays; import java.util.List; @@ -50,10 +63,12 @@ import retrofit2.Response; public class MainActivity extends AppCompatActivity { private static final String TAG = "MainActivity"; + private static final int JOB_ID = 123; ViewPager2 viewPager2; ViewPagerAdapter viewPagerAdapter; BottomNavigationView bottomNavigationView; + //Location private static final int LOCATION_REQUEST_CODE = 100; @Override @@ -61,8 +76,57 @@ public class MainActivity extends AppCompatActivity { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); + if(Common.firebaseAppDistribution.isTesterSignedIn()){ - //Init Component + //Customise progress dialog + ProgressDialog progressDialog = new ProgressDialog(this); + progressDialog.setTheme(ProgressDialog.THEME_LIGHT); + progressDialog.setMode(ProgressDialog.MODE_DETERMINATE); + progressDialog.setProgress(0); + progressDialog.setMessage("Xin vui lòng chờ..."); + progressDialog.showProgressTextAsFraction(true); + progressDialog.setProgressTintList(getColorStateList(R.color.primaryColor)); + progressDialog.setSecondaryProgressTintList(getColorStateList(R.color.primaryLightColor)); + + Common.firebaseAppDistribution.checkForNewRelease().addOnCompleteListener(new OnCompleteListener() { + @Override + public void onComplete(@NonNull Task task) { + if(task.isSuccessful()){ + AppDistributionRelease appDistributionRelease = task.getResult(); + + if(appDistributionRelease != null){ + progressDialog.show(); + } + } + } + }); + + Common.firebaseAppDistribution.updateIfNewReleaseAvailable().addOnProgressListener(new OnProgressListener() { + @Override + public void onProgressUpdate(@NonNull UpdateProgress updateProgress) { + double totalBytes = updateProgress.getApkFileTotalBytes(); + + double number = (updateProgress.getApkBytesDownloaded() / totalBytes) * 100; + + progressDialog.setProgress((int) number); + progressDialog.setSecondaryProgress((int) number + 10); + + if(number == 100){ + progressDialog.dismiss(); + } + } + }).addOnCompleteListener(new OnCompleteListener() { + @Override + public void onComplete(@NonNull Task task) { + if(!task.isSuccessful()){ + progressDialog.dismiss(); + } + } + }); + } + + +// Init Component bottomNavigationView = findViewById(R.id.bottom_nav); viewPager2 = findViewById(R.id.viewPager); @@ -72,7 +136,25 @@ public class MainActivity extends AppCompatActivity { checkNotificationPermission(); startPowerSaverIntent(this); getTokenFCM(); + startRefreshTokenService(); } + + private void startRefreshTokenService() { + ComponentName componentName = new ComponentName(this, RefreshTokenService.class); + + JobInfo jobInfo = new JobInfo.Builder(JOB_ID, componentName) + .setPeriodic(59 * 60 * 1000) + .build(); + + JobScheduler jobScheduler = (JobScheduler) getSystemService(JOB_SCHEDULER_SERVICE); + jobScheduler.schedule(jobInfo); + } + + private void stopRefreshTokenService() { + JobScheduler jobScheduler = (JobScheduler) getSystemService(JOB_SCHEDULER_SERVICE); + jobScheduler.cancel(JOB_ID); + } + private void bottomNavigation() { viewPagerAdapter = new ViewPagerAdapter(this); viewPager2.setAdapter(viewPagerAdapter); @@ -288,5 +370,17 @@ public class MainActivity extends AppCompatActivity { return list.size() > 0; } + @Override + protected void onResume() { + super.onResume(); + Log.e("Tag", "Resume"); + } + + @Override + protected void onDestroy() { + super.onDestroy(); + + stopRefreshTokenService(); + } } \ No newline at end of file diff --git a/app/src/main/java/com/capstone/foodify/shipper/Activity/OrderDetailActivity.java b/app/src/main/java/com/capstone/foodify/shipper/Activity/OrderDetailActivity.java index b1599f4..1af1e2a 100644 --- a/app/src/main/java/com/capstone/foodify/shipper/Activity/OrderDetailActivity.java +++ b/app/src/main/java/com/capstone/foodify/shipper/Activity/OrderDetailActivity.java @@ -7,6 +7,7 @@ import static com.capstone.foodify.shipper.Common.REQUEST_CHECK_SETTINGS; import android.annotation.SuppressLint; import android.app.ActivityManager; +import android.app.FragmentManager; import android.app.PendingIntent; import android.content.Context; import android.content.Intent; @@ -35,6 +36,7 @@ import com.capstone.foodify.shipper.API.GoogleMapApi; import com.capstone.foodify.shipper.API.TokenFCMFirebaseAPI; import com.capstone.foodify.shipper.Adapter.OrderDetailAdapter; import com.capstone.foodify.shipper.Common; +import com.capstone.foodify.shipper.Fragment.OrderFragment; import com.capstone.foodify.shipper.GoogleMap.GeofenceHelper; import com.capstone.foodify.shipper.LocationService; import com.capstone.foodify.shipper.Model.CustomResponse; @@ -135,23 +137,43 @@ public class OrderDetailActivity extends AppCompatActivity { stopLocationService(); startActivity(new Intent(OrderDetailActivity.this, MainActivity.class)); finish(); + overridePendingTransition(0,0); } }); btn_shipping.setOnClickListener(new View.OnClickListener() { @Override public void onClick(View v) { if (Common.CURRENT_ORDER == null) { - LatLng latLng = new LatLng(order.getLat(), order.getLng()); - addGeofence(latLng, GEOFENCE_RADIUS); - Common.CURRENT_ORDER = order; + //Change order status + FoodApiToken.apiService.changeStatusOrder(order.getUser().getId(), order.getId(), "SHIPPING").enqueue(new Callback() { + @Override + public void onResponse(Call call, Response response) { + if(response.code() == 200){ + //If success - startLocationService(); + LatLng latLng = new LatLng(order.getLat(), order.getLng()); + addGeofence(latLng, GEOFENCE_RADIUS); - Intent intent = new Intent(Intent.ACTION_VIEW, - Uri.parse("google.navigation:q=" + order.getLat() + "," + order.getLng() + "&mode=l")); - intent.setPackage("com.google.android.apps.maps"); - startActivity(intent); + Common.CURRENT_ORDER = order; + + startLocationService(); + + Intent intent = new Intent(Intent.ACTION_VIEW, + Uri.parse("google.navigation:q=" + order.getLat() + "," + order.getLng() + "&mode=l")); + intent.setPackage("com.google.android.apps.maps"); + startActivity(intent); + } else { + //If error + Toast.makeText(OrderDetailActivity.this, "", Toast.LENGTH_SHORT).show(); + } + } + + @Override + public void onFailure(Call call, Throwable t) { + Toast.makeText(OrderDetailActivity.this, Common.ERROR_CONNECT_SERVER, Toast.LENGTH_SHORT).show(); + } + }); } else{ Common.showErrorDialog(OrderDetailActivity.this, "Không thể lấy được thông tin đơn, vui lòng thử lại sau!"); } @@ -249,6 +271,7 @@ public class OrderDetailActivity extends AppCompatActivity { startActivity(new Intent(OrderDetailActivity.this, MainActivity.class)); builder.dismiss(); finish(); + overridePendingTransition(0,0); } }).show(); } diff --git a/app/src/main/java/com/capstone/foodify/shipper/Activity/SignInActivity.java b/app/src/main/java/com/capstone/foodify/shipper/Activity/SignInActivity.java index fd6b1d6..2fc33ca 100644 --- a/app/src/main/java/com/capstone/foodify/shipper/Activity/SignInActivity.java +++ b/app/src/main/java/com/capstone/foodify/shipper/Activity/SignInActivity.java @@ -6,6 +6,7 @@ import android.text.Editable; import android.text.TextWatcher; import android.util.Log; import android.view.View; +import android.widget.TextView; import android.widget.Toast; import androidx.annotation.NonNull; @@ -43,13 +44,16 @@ import retrofit2.Response; public class SignInActivity extends AppCompatActivity { private FirebaseAuth mAuth; - TextInputLayout textInput_email, textInput_password; - TextInputEditText edt_email, edt_password; - ConstraintLayout progressLayout; - String email, password = null; - MaterialButton btn_sign_in; + private TextInputLayout textInput_email, textInput_password; + private TextInputEditText edt_email, edt_password; + private ConstraintLayout progressLayout; + private String email, password = null; + private MaterialButton btn_sign_in; private FirebaseUser user; + private TextView txt_forgot_password; + + @Override public void onStart() { super.onStart(); @@ -105,6 +109,12 @@ public class SignInActivity extends AppCompatActivity { }); + txt_forgot_password.setOnClickListener(new View.OnClickListener() { + @Override + public void onClick(View view) { + startActivity(new Intent(SignInActivity.this, ForgotPasswordActivity.class)); + } + }); edt_password.addTextChangedListener(new TextWatcher() { @Override public void beforeTextChanged(CharSequence s, int start, int count, int after) { @@ -234,6 +244,7 @@ public class SignInActivity extends AppCompatActivity { btn_sign_in = findViewById(R.id.sign_in_button); textInput_email = findViewById(R.id.textInput_email); textInput_password = findViewById(R.id.textInput_password); + txt_forgot_password = findViewById(R.id.txt_forgot_password); edt_email = findViewById(R.id.edt_email); edt_password = findViewById(R.id.edt_password); diff --git a/app/src/main/java/com/capstone/foodify/shipper/Adapter/OrderAdapter.java b/app/src/main/java/com/capstone/foodify/shipper/Adapter/OrderAdapter.java index 25bc2aa..eaaa5ed 100644 --- a/app/src/main/java/com/capstone/foodify/shipper/Adapter/OrderAdapter.java +++ b/app/src/main/java/com/capstone/foodify/shipper/Adapter/OrderAdapter.java @@ -68,6 +68,7 @@ public class OrderAdapter extends RecyclerView.Adapter LIST_ORDER = new ArrayList<>(); - public static final String SHIPPING_COMPLETED = "1"; public static final int REQUEST_CHECK_SETTINGS = 100; public static final long UPDATE_INTERVAL_IN_MILLISECONDS = 10000; public static final long FASTEST_UPDATE_IN_MILLISECONDS = 3000; public static final long MAX_WAIT_TIME_IN_MILLISECONDS = 1000; - public static final int LOCATION_REQUEST_CODE = 100; public static final int LOCATION_SERVICE_ID = 175; public static final String ACTION_START_LOCATION_SERVICE = "startLocationService"; public static final String ACTION_STOP_LOCATION_SERVICE = "stopLocationService"; @@ -75,4 +74,12 @@ public class Common { return fmt.format(price); } + public static void notificationDialog(Activity activity, DialogStyle dialogStyle, DialogType dialogType, String title, String message){ + new AestheticDialog.Builder(activity, dialogStyle, dialogType) + .setTitle(title) + .setMessage(message) + .setCancelable(true) + .show(); + } + } diff --git a/app/src/main/java/com/capstone/foodify/shipper/Fragment/Order/ShippingFragment.java b/app/src/main/java/com/capstone/foodify/shipper/Fragment/Order/CancelOrder.java similarity index 97% rename from app/src/main/java/com/capstone/foodify/shipper/Fragment/Order/ShippingFragment.java rename to app/src/main/java/com/capstone/foodify/shipper/Fragment/Order/CancelOrder.java index 87278d2..3178072 100644 --- a/app/src/main/java/com/capstone/foodify/shipper/Fragment/Order/ShippingFragment.java +++ b/app/src/main/java/com/capstone/foodify/shipper/Fragment/Order/CancelOrder.java @@ -30,7 +30,7 @@ import retrofit2.Call; import retrofit2.Callback; import retrofit2.Response; -public class ShippingFragment extends Fragment { +public class CancelOrder extends Fragment { private static int CURRENT_PAGE = 0; private static final int PAGE_SIZE = 8; private static final String SORT_BY = "id"; @@ -47,7 +47,7 @@ public class ShippingFragment extends Fragment { public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) { // Inflate the layout for this fragment - View view = inflater.inflate(R.layout.fragment_waiting_order, container, false); + View view = inflater.inflate(R.layout.fragment_cancel, container, false); //Init component recyclerView = view.findViewById(R.id.rcv_list_order); diff --git a/app/src/main/java/com/capstone/foodify/shipper/Fragment/Order/CompletedOrder.java b/app/src/main/java/com/capstone/foodify/shipper/Fragment/Order/CompletedOrder.java index bc3c20a..7344fb7 100644 --- a/app/src/main/java/com/capstone/foodify/shipper/Fragment/Order/CompletedOrder.java +++ b/app/src/main/java/com/capstone/foodify/shipper/Fragment/Order/CompletedOrder.java @@ -47,7 +47,7 @@ public class CompletedOrder extends Fragment { public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) { // Inflate the layout for this fragment - View view = inflater.inflate(R.layout.fragment_waiting_order, container, false); + View view = inflater.inflate(R.layout.fragment_confirmed_order, container, false); //Init component recyclerView = view.findViewById(R.id.rcv_list_order); @@ -80,7 +80,7 @@ public class CompletedOrder extends Fragment { }); } - + swipeRefreshLayout.setColorSchemeColors(getResources().getColor(R.color.primaryColor, null)); swipeRefreshLayout.setOnRefreshListener(new SwipeRefreshLayout.OnRefreshListener() { @Override public void onRefresh() { diff --git a/app/src/main/java/com/capstone/foodify/shipper/Fragment/Order/AwaitingOrder.java b/app/src/main/java/com/capstone/foodify/shipper/Fragment/Order/ConfirmedOrder.java similarity index 93% rename from app/src/main/java/com/capstone/foodify/shipper/Fragment/Order/AwaitingOrder.java rename to app/src/main/java/com/capstone/foodify/shipper/Fragment/Order/ConfirmedOrder.java index 50c37b6..5bbb67f 100644 --- a/app/src/main/java/com/capstone/foodify/shipper/Fragment/Order/AwaitingOrder.java +++ b/app/src/main/java/com/capstone/foodify/shipper/Fragment/Order/ConfirmedOrder.java @@ -24,14 +24,13 @@ import com.capstone.foodify.shipper.Model.Response.Orders; import com.capstone.foodify.shipper.R; import java.util.ArrayList; -import java.util.Currency; import java.util.List; import retrofit2.Call; import retrofit2.Callback; import retrofit2.Response; -public class AwaitingOrder extends Fragment { +public class ConfirmedOrder extends Fragment { private static int CURRENT_PAGE = 0; private static final int PAGE_SIZE = 8; private static final String SORT_BY = "id"; @@ -48,7 +47,7 @@ public class AwaitingOrder extends Fragment { public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) { // Inflate the layout for this fragment - View view = inflater.inflate(R.layout.fragment_waiting_order, container, false); + View view = inflater.inflate(R.layout.fragment_confirmed_order, container, false); //Init component recyclerView = view.findViewById(R.id.rcv_list_order); @@ -81,7 +80,7 @@ public class AwaitingOrder extends Fragment { }); } - + swipeRefreshLayout.setColorSchemeColors(getResources().getColor(R.color.primaryColor, null)); swipeRefreshLayout.setOnRefreshListener(new SwipeRefreshLayout.OnRefreshListener() { @Override public void onRefresh() { @@ -102,7 +101,7 @@ public class AwaitingOrder extends Fragment { private void getListOrder(){ if(Common.CURRENT_SHIPPER != null){ - FoodApiToken.apiService.getListOrder(Common.CURRENT_SHIPPER.getId(), "AWAITING", CURRENT_PAGE++, PAGE_SIZE, SORT_BY, SORT_DIR).enqueue(new Callback() { + FoodApiToken.apiService.getListOrder(Common.CURRENT_SHIPPER.getId(), "CONFIRMED", CURRENT_PAGE++, PAGE_SIZE, SORT_BY, SORT_DIR).enqueue(new Callback() { @Override public void onResponse(Call call, Response response) { if(response.code() == 200){ @@ -143,10 +142,6 @@ public class AwaitingOrder extends Fragment { end_of_list_text_view.setVisibility(View.VISIBLE); } - private void defaultLayout(){ - - } - private void dataLoadMore() { if(!LAST_PAGE){ getListOrder(); diff --git a/app/src/main/java/com/capstone/foodify/shipper/Fragment/Order/OrderViewPagerAdapter.java b/app/src/main/java/com/capstone/foodify/shipper/Fragment/Order/OrderViewPagerAdapter.java index e6c4810..ae87180 100644 --- a/app/src/main/java/com/capstone/foodify/shipper/Fragment/Order/OrderViewPagerAdapter.java +++ b/app/src/main/java/com/capstone/foodify/shipper/Fragment/Order/OrderViewPagerAdapter.java @@ -15,9 +15,9 @@ public class OrderViewPagerAdapter extends FragmentStateAdapter { @Override public Fragment createFragment(int position) { switch(position) { - case 1: return new ShippingFragment(); - case 2: return new CompletedOrder(); - default: return new AwaitingOrder(); + case 1: return new CompletedOrder(); + case 2: return new CancelOrder(); + default: return new ConfirmedOrder(); } } @Override diff --git a/app/src/main/java/com/capstone/foodify/shipper/Fragment/OrderFragment.java b/app/src/main/java/com/capstone/foodify/shipper/Fragment/OrderFragment.java index a40ae69..258b524 100644 --- a/app/src/main/java/com/capstone/foodify/shipper/Fragment/OrderFragment.java +++ b/app/src/main/java/com/capstone/foodify/shipper/Fragment/OrderFragment.java @@ -1,8 +1,11 @@ package com.capstone.foodify.shipper.Fragment; +import android.app.Activity; +import android.content.Intent; import android.os.Bundle; import androidx.annotation.NonNull; +import androidx.cardview.widget.CardView; import androidx.core.widget.NestedScrollView; import androidx.fragment.app.Fragment; import androidx.recyclerview.widget.LinearLayoutManager; @@ -12,12 +15,14 @@ import androidx.viewpager2.widget.ViewPager2; import android.view.LayoutInflater; import android.view.View; import android.view.ViewGroup; +import android.widget.LinearLayout; import android.widget.ProgressBar; import android.widget.TextView; import android.widget.Toast; import com.capstone.foodify.shipper.API.FoodApiToken; import com.capstone.foodify.shipper.Activity.MainActivity; +import com.capstone.foodify.shipper.Activity.OrderDetailActivity; import com.capstone.foodify.shipper.Adapter.OrderAdapter; import com.capstone.foodify.shipper.Common; import com.capstone.foodify.shipper.Fragment.Order.OrderViewPagerAdapter; @@ -27,6 +32,10 @@ import com.capstone.foodify.shipper.R; import com.capstone.foodify.shipper.ViewPagerAdapter; import com.google.android.material.tabs.TabLayout; import com.squareup.picasso.Picasso; +import com.thecode.aestheticdialogs.AestheticDialog; +import com.thecode.aestheticdialogs.DialogStyle; +import com.thecode.aestheticdialogs.DialogType; +import com.thecode.aestheticdialogs.OnDialogClickListener; import java.util.ArrayList; import java.util.List; @@ -39,7 +48,13 @@ public class OrderFragment extends Fragment { TabLayout tabLayout; ViewPager2 viewPager2; OrderViewPagerAdapter orderViewPagerAdapter; - TextView welcome_text; + TextView welcome_text, order_tracking_number, user_name, phone, address, orderTime, total; + CardView card_view_order_shipping; + Order orderShipping; + LinearLayout order_shipping_layout; + private static final int PAGE_SIZE = 8; + private static final String SORT_BY = "id"; + private static final String SORT_DIR = "asc"; @Override public View onCreateView(LayoutInflater inflater, ViewGroup container, @@ -48,11 +63,14 @@ public class OrderFragment extends Fragment { View view = inflater.inflate(R.layout.fragment_order, container, false); //Init Component - welcome_text = view.findViewById(R.id.welcome_text); + initComponent(view); + welcome_text = view.findViewById(R.id.welcome_text); tabLayout = view.findViewById(R.id.tab_layout); viewPager2 = view.findViewById(R.id.view_pager); + getOrderShipping(); + orderViewPagerAdapter = new OrderViewPagerAdapter(getActivity()); viewPager2.setAdapter(orderViewPagerAdapter); @@ -82,19 +100,107 @@ public class OrderFragment extends Fragment { }); if(Common.CURRENT_USER != null){ - welcome_text.setText("Xin chào, " + Common.CURRENT_USER.getFullName() + "!"); + setNameUser(); } return view; } + private void initComponent(View view) { + welcome_text = view.findViewById(R.id.welcome_text); + tabLayout = view.findViewById(R.id.tab_layout); + viewPager2 = view.findViewById(R.id.view_pager); + card_view_order_shipping = view.findViewById(R.id.card_view_order_shipping); + order_shipping_layout = view.findViewById(R.id.order_shipping_layout); + + order_tracking_number = view.findViewById(R.id.order_tracking_number); + user_name = view.findViewById(R.id.user_name); + phone = view.findViewById(R.id.phone); + address = view.findViewById(R.id.address); + orderTime = view.findViewById(R.id.order_time); + total = view.findViewById(R.id.total); + } + + public void getOrderShipping(){ + if(Common.CURRENT_SHIPPER != null){ + FoodApiToken.apiService.getListOrder(Common.CURRENT_SHIPPER.getId(), "SHIPPING", 0, PAGE_SIZE, SORT_BY, SORT_DIR).enqueue(new Callback() { + @Override + public void onResponse(Call call, Response response) { + if(response.code() == 200){ + + assert response.body() != null; + if(response.body().getOrders().size() == 1){ + //Get order shipping + orderShipping = response.body().getOrders().get(0); + + initData(); + + order_shipping_layout.setVisibility(View.VISIBLE); + } else { + order_shipping_layout.setVisibility(View.GONE); + } + } else { + Toast.makeText(getContext(), "Đã có lỗi hệ thống! Mã lỗi: " + response.code(), Toast.LENGTH_SHORT).show(); + } + } + + @Override + public void onFailure(Call call, Throwable t) { + Toast.makeText(getContext(), Common.ERROR_CONNECT_SERVER, Toast.LENGTH_SHORT).show(); + } + }); + } + } + + private void initData() { + order_tracking_number.setText("Order Id: #" + orderShipping.getOrderTrackingNumber()); + user_name.setText("Tên: " + orderShipping.getUser().getFullName()); + phone.setText("Số điện thoại: " + orderShipping.getUser().getPhoneNumber()); + address.setText("Địa chỉ: " + orderShipping.getAddress()); + orderTime.setText("Thời gian đặt: " + orderShipping.getOrderTime()); + total.setText("Tổng: " + Common.changeCurrencyUnit(orderShipping.getTotal())); + + Activity activity = getActivity(); + + card_view_order_shipping.setOnClickListener(new View.OnClickListener() { + @Override + public void onClick(View view) { + if(activity instanceof MainActivity){ + if(((MainActivity)activity).checkPermission()){ + Intent intent = new Intent(activity, OrderDetailActivity.class); + intent.putExtra("order", orderShipping); + activity.startActivity(intent); + } else { + new AestheticDialog.Builder(activity, DialogStyle.TOASTER, DialogType.WARNING) + .setTitle("THÔNG BÁO!") + .setMessage("Bạn cần cấp quyền vị trí cho ứng dụng để có thể tiếp tục!") + .setCancelable(false) + .setOnClickListener(new OnDialogClickListener() { + @Override + public void onClick(@NonNull AestheticDialog.Builder builder) { + builder.dismiss(); + } + }).show(); + } + } + } + }); + } + + private void setNameUser(){ + String[] namePart = Common.CURRENT_USER.getFullName().split(" "); + + welcome_text.setText("Xin chào, " + namePart[namePart.length - 1]); + + } + @Override public void onResume() { super.onResume(); //Update user name on textview - welcome_text.setText("Xin chào, " + Common.CURRENT_USER.getFullName() + "!"); + setNameUser(); } } \ No newline at end of file diff --git a/app/src/main/java/com/capstone/foodify/shipper/Fragment/ProfileFragment.java b/app/src/main/java/com/capstone/foodify/shipper/Fragment/ProfileFragment.java index c50e81e..586c48d 100644 --- a/app/src/main/java/com/capstone/foodify/shipper/Fragment/ProfileFragment.java +++ b/app/src/main/java/com/capstone/foodify/shipper/Fragment/ProfileFragment.java @@ -1,5 +1,7 @@ package com.capstone.foodify.shipper.Fragment; +import static com.capstone.foodify.shipper.Common.firebaseAppDistribution; + import android.app.Activity; import android.app.Dialog; import android.content.Intent; @@ -27,7 +29,7 @@ import com.squareup.picasso.Picasso; public class ProfileFragment extends Fragment { EditText edt_birthday, edt_phone, edt_fullName, edt_email; - LinearLayout changePasswordLayout, changeInformationLayout, logOutLayout; + LinearLayout changePasswordLayout, changeInformationLayout, logOutLayout, feed_back; RoundedImageView profile_avatar; @Override public View onCreateView(LayoutInflater inflater, ViewGroup container, @@ -57,6 +59,13 @@ public class ProfileFragment extends Fragment { } }); + feed_back.setOnClickListener(new View.OnClickListener() { + @Override + public void onClick(View v) { + firebaseAppDistribution.startFeedback("Cảm ơn vì sự đóng góp ý kiến từ các bạn!"); + } + }); + logOutLayout.setOnClickListener(new View.OnClickListener() { @Override public void onClick(View v) { @@ -77,6 +86,7 @@ public class ProfileFragment extends Fragment { changePasswordLayout = view.findViewById(R.id.change_password); changeInformationLayout = view.findViewById(R.id.change_information); logOutLayout = view.findViewById(R.id.log_out); + feed_back = view.findViewById(R.id.feedback); edt_phone = view.findViewById(R.id.edt_phone); edt_birthday = view.findViewById(R.id.edt_birthDay); diff --git a/app/src/main/java/com/capstone/foodify/shipper/RefreshTokenService.java b/app/src/main/java/com/capstone/foodify/shipper/RefreshTokenService.java new file mode 100644 index 0000000..98ef8eb --- /dev/null +++ b/app/src/main/java/com/capstone/foodify/shipper/RefreshTokenService.java @@ -0,0 +1,55 @@ +package com.capstone.foodify.shipper; + +import android.app.job.JobParameters; +import android.app.job.JobService; +import android.util.Log; + +import androidx.annotation.NonNull; + +import com.google.android.gms.tasks.OnCompleteListener; +import com.google.android.gms.tasks.Task; +import com.google.firebase.auth.GetTokenResult; + +public class RefreshTokenService extends JobService { + + private static final String TAG = "RefreshTokenService"; + + @Override + public boolean onStartJob(JobParameters params) { + + Log.d(TAG, "Refresh token service started!"); + + refreshToken(params); + + return true; + } + + private void refreshToken(JobParameters params) { + + if(Common.FIREBASE_USER != null){ + Common.FIREBASE_USER.getIdToken(true).addOnCompleteListener(new OnCompleteListener() { + @Override + public void onComplete(@NonNull Task task) { + if(task.isSuccessful()){ + Common.TOKEN = task.getResult().getToken(); + + Log.i(TAG, "Refresh token completed!"); + } else { + Log.e(TAG, "Error when refresh token!"); + } + + jobFinished(params, false); + } + }); + } + + } + + @Override + public boolean onStopJob(JobParameters params) { + + Log.d(TAG, "Stop serviced!"); + + return true; + } +} diff --git a/app/src/main/res/drawable/feedback.png b/app/src/main/res/drawable/feedback.png new file mode 100644 index 0000000..d5bf1bf Binary files /dev/null and b/app/src/main/res/drawable/feedback.png differ diff --git a/app/src/main/res/layout/activity_forgot_password.xml b/app/src/main/res/layout/activity_forgot_password.xml new file mode 100644 index 0000000..efed212 --- /dev/null +++ b/app/src/main/res/layout/activity_forgot_password.xml @@ -0,0 +1,119 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/app/src/main/res/layout/activity_sign_in.xml b/app/src/main/res/layout/activity_sign_in.xml index e517f7f..e9bd6c7 100644 --- a/app/src/main/res/layout/activity_sign_in.xml +++ b/app/src/main/res/layout/activity_sign_in.xml @@ -61,7 +61,7 @@ android:fontFamily="@font/bebas" android:textSize="35sp" android:textColor="@color/black" - android:layout_marginTop="40dp" + android:layout_marginTop="30dp" android:layout_marginEnd="15dp" android:layout_width="wrap_content" android:layout_height="wrap_content" @@ -74,7 +74,7 @@ android:id="@+id/textInput_email" android:layout_width="match_parent" android:layout_height="wrap_content" - android:layout_marginTop="20dp" + android:layout_marginTop="50dp" android:layout_marginRight="20dp" android:layout_marginLeft="20dp" android:layout_marginBottom="10dp" @@ -118,6 +118,19 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + @@ -66,17 +200,17 @@ > diff --git a/app/src/main/res/layout/fragment_profile.xml b/app/src/main/res/layout/fragment_profile.xml index 36c8cfe..94c73db 100644 --- a/app/src/main/res/layout/fragment_profile.xml +++ b/app/src/main/res/layout/fragment_profile.xml @@ -225,6 +225,50 @@ + + + + + + + + + + diff --git a/app/src/main/res/values/colors.xml b/app/src/main/res/values/colors.xml index e489787..36ffd99 100644 --- a/app/src/main/res/values/colors.xml +++ b/app/src/main/res/values/colors.xml @@ -5,6 +5,7 @@ #53BBFF #CF2E33 + #78CAFF #A3A3A3 #F99928 #ACA5A5