diff --git a/.idea/deploymentTargetDropDown.xml b/.idea/deploymentTargetDropDown.xml index d3e5064..758cc80 100644 --- a/.idea/deploymentTargetDropDown.xml +++ b/.idea/deploymentTargetDropDown.xml @@ -2,15 +2,6 @@ - - - - - - - - - @@ -25,7 +16,7 @@ - + diff --git a/app/src/main/java/com/ssb/simplitend/caregiverdashboard/CaregiverDashActivity.java b/app/src/main/java/com/ssb/simplitend/caregiverdashboard/CaregiverDashActivity.java index f1574cb..2c59885 100644 --- a/app/src/main/java/com/ssb/simplitend/caregiverdashboard/CaregiverDashActivity.java +++ b/app/src/main/java/com/ssb/simplitend/caregiverdashboard/CaregiverDashActivity.java @@ -51,6 +51,8 @@ public class CaregiverDashActivity extends AppCompatActivity implements startActivity(intent); finish(); return; + }else{ + Toast.makeText(this, "Subscription on.", Toast.LENGTH_SHORT).show(); } } diff --git a/app/src/main/java/com/ssb/simplitend/cg_subscription/CgSubscriptionActivity.java b/app/src/main/java/com/ssb/simplitend/cg_subscription/CgSubscriptionActivity.java index 3e8b25b..5d28406 100644 --- a/app/src/main/java/com/ssb/simplitend/cg_subscription/CgSubscriptionActivity.java +++ b/app/src/main/java/com/ssb/simplitend/cg_subscription/CgSubscriptionActivity.java @@ -8,7 +8,6 @@ import android.widget.Toast; import androidx.annotation.Nullable; import androidx.appcompat.app.AppCompatActivity; -import androidx.appcompat.app.AppCompatDelegate; import androidx.viewpager2.widget.ViewPager2; import com.ssb.simplitend.R; @@ -19,7 +18,6 @@ import com.ssb.simplitend.cg_subscription.mvp.SubscriptionContracts; import com.ssb.simplitend.cg_subscription.mvp.SubscriptionCredentials; import com.ssb.simplitend.cg_subscription.mvp.SubscriptionPresenter; import com.ssb.simplitend.databinding.CgSubscriptionLayoutBinding; -import com.ssb.simplitend.welcome.welcomecg.mvvm.CareGiverData; import com.stripe.android.PaymentConfiguration; import com.stripe.android.paymentsheet.PaymentSheet; import com.stripe.android.paymentsheet.PaymentSheetResult; @@ -31,8 +29,10 @@ import java.util.Map; import okhttp3.MediaType; import okhttp3.RequestBody; -public class CgSubscriptionActivity extends AppCompatActivity - implements SubscriptionContracts.GetSubPlansCallback, SubscriptionContracts.PaySubscriptionCallback { +public class CgSubscriptionActivity extends AppCompatActivity + implements SubscriptionContracts.GetSubPlansCallback, + SubscriptionContracts.PaySubscriptionCallback, + SubscriptionContracts.CreateSubscriptionCallback { private static final String TAG = "CgSubscriptionActivity"; @@ -46,6 +46,8 @@ public class CgSubscriptionActivity extends AppCompatActivity private PaymentSheet paymentSheet; + private String payment_intent_id, stripe_price_id; + @Override protected void onCreate(@Nullable Bundle savedInstanceState) { super.onCreate(savedInstanceState); @@ -59,7 +61,8 @@ public class CgSubscriptionActivity extends AppCompatActivity "Testing!", "Payment is in testing phase. So each time u open app it ill bring to subsription screen. This ill be updated in next build.", "Ok, got it.", - ((dialogInterface, i) -> {}), + ((dialogInterface, i) -> { + }), null, null); initViews(); @@ -81,7 +84,7 @@ public class CgSubscriptionActivity extends AppCompatActivity } int position = binding.viewPager.getCurrentItem(); - if (subscriptionPlans == null || position < 0 || position >= subscriptionPlans.size()){ + if (subscriptionPlans == null || position < 0 || position >= subscriptionPlans.size()) { Toast.makeText(this, "Couldn't load plan.", Toast.LENGTH_SHORT).show(); return; } @@ -101,10 +104,21 @@ public class CgSubscriptionActivity extends AppCompatActivity RequestBody email_body = RequestBody.create(UserDataCache.careGiverData.email, MediaType.parse("text/plain")); body.put("email", email_body); - RequestBody price_body = RequestBody.create("595", MediaType.parse("text/plain")); + // important part + String plan_price; + try { + float plan_price_float = Float.parseFloat(plan.plan_value); + plan_price_float *= 100; // converting from dollars to cents + + plan_price = "" + (int) plan_price_float; // converting to int to remove leading ".0" + } catch (Exception e) { + plan_price = getString(R.string.default_price); + } + + RequestBody price_body = RequestBody.create(plan_price, MediaType.parse("text/plain")); body.put("price", price_body); - RequestBody subscription_xid_body = RequestBody.create("4", MediaType.parse("text/plain")); + RequestBody subscription_xid_body = RequestBody.create(plan.id + "", MediaType.parse("text/plain")); body.put("subscription_xid", subscription_xid_body); RequestBody caregiver_xid_body = RequestBody.create("" + UserDataCache.careGiverData.caregiver_xid, MediaType.parse("text/plain")); @@ -112,6 +126,8 @@ public class CgSubscriptionActivity extends AppCompatActivity String token = "Bearer " + AppUtil.getCgToken(this); + this.stripe_price_id = plan.stripe_price_id; + presenter.getPaymentCred(token, body, this); } @@ -122,13 +138,13 @@ public class CgSubscriptionActivity extends AppCompatActivity public void onPageSelected(int position) { super.onPageSelected(position); if (subscriptionPlans == null - || position < 0 || position >= subscriptionPlans.size()) return; + || position < 0 || position >= subscriptionPlans.size()) return; String btn_text = "Make payment $" + subscriptionPlans.get(position).plan_value; binding.makePayment.setText(btn_text); } }); - + // loading subscription plans progressDialog = new ProgressDialog(this); @@ -157,28 +173,49 @@ public class CgSubscriptionActivity extends AppCompatActivity Log.d(TAG, "Payment successful"); Toast.makeText(this, "Payment successful.", Toast.LENGTH_SHORT).show(); - // TODO: 11-08-2023 do the api call - if (UserDataCache.careGiverData != null){ - UserDataCache.careGiverData.isCaregiverTakeSubscription = 1; - - Intent intent = new Intent(this, CaregiverDashActivity.class); - intent.setFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP); - startActivity(intent); - finish(); - } + // creating subscription + createSubscription(); } } + private void createSubscription() { + if (this.stripe_price_id == null || this.payment_intent_id == null){ + // something went wrong + Toast.makeText(this, "Something went wrong", Toast.LENGTH_SHORT).show(); + return; + } + + progressDialog.setTitle("Almost there..."); + progressDialog.setMessage("We are verifying your payment.\nDon't leave the app screen."); + progressDialog.setCancelable(false); + progressDialog.show(); + + Map bodyMap = new HashMap<>(); + + RequestBody pay_intent_id_body = RequestBody.create(this.payment_intent_id, MediaType.parse("text/plain")); + bodyMap.put("payment_intent_id", pay_intent_id_body); + + RequestBody price_id_body = RequestBody.create(this.stripe_price_id, MediaType.parse("text/plain")); + bodyMap.put("price_id", price_id_body); + + presenter.createSubscription(bodyMap, + "Bearer " + AppUtil.getCgToken(this), + this); + + } + // get payment credentials callback @Override public void onPaymentCredFetched(SubscriptionCredentials credentials) { - if (credentials == null){ + if (credentials == null) { progressDialog.dismiss(); Toast.makeText(this, "Something went wrong.", Toast.LENGTH_SHORT).show(); return; } + this.payment_intent_id = credentials.payment_intent_id; + final PaymentSheet.CustomerConfiguration customerConfig = new PaymentSheet.CustomerConfiguration( credentials.customerId, credentials.ephemeralKey @@ -222,4 +259,33 @@ public class CgSubscriptionActivity extends AppCompatActivity progressDialog.dismiss(); Toast.makeText(this, "" + message, Toast.LENGTH_SHORT).show(); } + + // subscription create callback + @Override + public void onSubscriptionCreated() { + // statically changing the flag of subscription to 1 + if (UserDataCache.careGiverData != null){ + UserDataCache.careGiverData.isCaregiverTakeSubscription = 1; + } + + Intent intent = new Intent(this, CaregiverDashActivity.class); + intent.setFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP); + + progressDialog.dismiss(); + + startActivity(intent); + finish(); + } + + @Override + public void onSubscriptionCreateFailed(Throwable throwable, String message) { + progressDialog.dismiss(); + AppUtil.showAlert(this, + getString(R.string.something_went_wrong), + message + "\nNegative response will be handled properly.", + "OK", + ((dialogInterface, i) -> { + + }), null, null); + } } diff --git a/app/src/main/java/com/ssb/simplitend/cg_subscription/mvp/SubscriptionApiService.java b/app/src/main/java/com/ssb/simplitend/cg_subscription/mvp/SubscriptionApiService.java index edd538d..745b9b9 100644 --- a/app/src/main/java/com/ssb/simplitend/cg_subscription/mvp/SubscriptionApiService.java +++ b/app/src/main/java/com/ssb/simplitend/cg_subscription/mvp/SubscriptionApiService.java @@ -5,6 +5,7 @@ import com.ssb.simplitend.welcome.welcomepatient.mvvm.models.CallResponse; import java.util.ArrayList; import java.util.Map; +import java.util.Objects; import okhttp3.RequestBody; import retrofit2.Call; @@ -25,4 +26,11 @@ public interface SubscriptionApiService { @Header("Authorization") String token, @PartMap Map body); + @Multipart + @POST("api/create-subscription") + Call> createSubscription( + @Header("Authorization") String token, + @PartMap Map bodyMap + ); + } diff --git a/app/src/main/java/com/ssb/simplitend/cg_subscription/mvp/SubscriptionContracts.java b/app/src/main/java/com/ssb/simplitend/cg_subscription/mvp/SubscriptionContracts.java index 75fe652..c9da4b1 100644 --- a/app/src/main/java/com/ssb/simplitend/cg_subscription/mvp/SubscriptionContracts.java +++ b/app/src/main/java/com/ssb/simplitend/cg_subscription/mvp/SubscriptionContracts.java @@ -22,4 +22,10 @@ public interface SubscriptionContracts { } + interface CreateSubscriptionCallback{ + void onSubscriptionCreated(); + + void onSubscriptionCreateFailed(Throwable throwable, String message); + } + } diff --git a/app/src/main/java/com/ssb/simplitend/cg_subscription/mvp/SubscriptionCredentials.java b/app/src/main/java/com/ssb/simplitend/cg_subscription/mvp/SubscriptionCredentials.java index e5861b7..3bf9550 100644 --- a/app/src/main/java/com/ssb/simplitend/cg_subscription/mvp/SubscriptionCredentials.java +++ b/app/src/main/java/com/ssb/simplitend/cg_subscription/mvp/SubscriptionCredentials.java @@ -6,5 +6,7 @@ public class SubscriptionCredentials{ public String ephemeralKey; public String stripe_publish_key; + public String payment_intent_id; + public SubscriptionCredentials(){} } diff --git a/app/src/main/java/com/ssb/simplitend/cg_subscription/mvp/SubscriptionPresenter.java b/app/src/main/java/com/ssb/simplitend/cg_subscription/mvp/SubscriptionPresenter.java index 0b1427d..cd9876c 100644 --- a/app/src/main/java/com/ssb/simplitend/cg_subscription/mvp/SubscriptionPresenter.java +++ b/app/src/main/java/com/ssb/simplitend/cg_subscription/mvp/SubscriptionPresenter.java @@ -86,4 +86,30 @@ public class SubscriptionPresenter { } + public void createSubscription(Map bodyMap, + @NonNull String token, + @NonNull SubscriptionContracts.CreateSubscriptionCallback createSubscriptionCallback){ + apiService.createSubscription(token, bodyMap) + .enqueue(new Callback>() { + @Override + public void onResponse(Call> call, Response> response) { + if (response.body() != null){ + if (response.body().status != 200){ + createSubscriptionCallback.onSubscriptionCreateFailed(new Exception(), response.body().message); + return; + } + + createSubscriptionCallback.onSubscriptionCreated(); + }else{ + createSubscriptionCallback.onSubscriptionCreateFailed(new Exception(), "Please try again later."); + } + } + + @Override + public void onFailure(Call> call, Throwable t) { + createSubscriptionCallback.onSubscriptionCreateFailed(new Exception(), "Please try again later."); + } + }); + } + } diff --git a/app/src/main/java/com/ssb/simplitend/patientprofile/medreminder/ReminderFragment.java b/app/src/main/java/com/ssb/simplitend/patientprofile/medreminder/ReminderFragment.java index 5ab83a7..4328f29 100644 --- a/app/src/main/java/com/ssb/simplitend/patientprofile/medreminder/ReminderFragment.java +++ b/app/src/main/java/com/ssb/simplitend/patientprofile/medreminder/ReminderFragment.java @@ -425,7 +425,7 @@ ReminderAdapter.ReminderCheckClickListener{ if (today_date == selected_date){ AppUtil.showAlert(requireContext(), "Are you sure?", - "Do yuo want to check this routine?\nThis cannot be undone.", + "Do yuo want to check this reminder?\nThis cannot be undone.", getString(R.string.yes), (dialog, which) -> { dialog.dismiss(); diff --git a/app/src/main/java/com/ssb/simplitend/patientprofile/medreminder/mvvm/ReminderAdapter.java b/app/src/main/java/com/ssb/simplitend/patientprofile/medreminder/mvvm/ReminderAdapter.java index f622759..37dba36 100644 --- a/app/src/main/java/com/ssb/simplitend/patientprofile/medreminder/mvvm/ReminderAdapter.java +++ b/app/src/main/java/com/ssb/simplitend/patientprofile/medreminder/mvvm/ReminderAdapter.java @@ -90,36 +90,40 @@ public class ReminderAdapter extends RecyclerView.Adapter 0) { switch (reminder.medication_type.get(0).title){ case "Capsule": binding.medImg.setImageResource(R.drawable.ic_capsules); + quantity = reminder.medication_quantity + " capsules"; break; case "Pill": binding.medImg.setImageResource(R.drawable.ic_pills); + quantity = reminder.medication_quantity + " pills"; break; case "Drops": binding.medImg.setImageResource(R.drawable.ic_drops); + quantity = reminder.medication_quantity + " drops"; break; } }else{ binding.medImg.setImageResource(R.drawable.ic_capsules); } + binding.quantity.setText(quantity); + if (reminder.reminder_marked != null){ /* This routine is done for some day. @@ -172,6 +176,118 @@ public class ReminderAdapter extends RecyclerView.Adapter c_t){ + // t1 time is passed and t2 time is yet to come for the same day + // thus, returning t2 + return time2; + }else if (t1 > c_t && t2 < c_t){ + // t1 is yet to come for this day, and t2 has already been passed + // thus, returning t1 + return time1; + }else if (t1 > c_t && t2 > c_t){ + // Both the times are greater than current time, yet to come + // In this case, we show the smallest time + + if (t1 < t2) return time1; + else return time2; + }else{ + // Last case would be both the times has passed the current time + // thus, showing the last reminder for this day + + if (t1 < t2) return time2; + else return time1; + } + + }catch (Exception e){ + // if something goes wrong, returning the time1 + return time1; + } + } + + + private String smallestTime(String time1, String time2) { + if (time1 == null && time2 == null) return null; + if (time1 == null) return time2; + if (time2 == null) return time1; + + // comparing this 2 times with current time + // first converting time string to calendar + SimpleDateFormat input_sdf = new SimpleDateFormat("HH:mm:ss", Locale.getDefault()); + + try { + Date date1 = input_sdf.parse(time1); + Date date2 = input_sdf.parse(time2); + + if (date2 == null || date1 == null) throw new Exception(); + + // All times above dates are of same date 01 Jan 1970 + // but, of different times i.e. hh:mm:ss + + long t1 = date1.getTime(); + long t2 = date2.getTime(); + + if (t2 < t1) return time2; + else return time1; + + }catch (Exception e){ + // if something goes wrong, returning the time1 + return time1; + } + } } public interface ReminderCheckClickListener{ diff --git a/app/src/main/java/com/ssb/simplitend/welcome/welcomecg/CgOnBoardAdapter.java b/app/src/main/java/com/ssb/simplitend/welcome/welcomecg/CgOnBoardAdapter.java index 574d96b..9bf8fea 100644 --- a/app/src/main/java/com/ssb/simplitend/welcome/welcomecg/CgOnBoardAdapter.java +++ b/app/src/main/java/com/ssb/simplitend/welcome/welcomecg/CgOnBoardAdapter.java @@ -2,6 +2,7 @@ package com.ssb.simplitend.welcome.welcomecg; import androidx.annotation.NonNull; import androidx.fragment.app.Fragment; +import androidx.fragment.app.FragmentActivity; import androidx.fragment.app.FragmentManager; import androidx.lifecycle.Lifecycle; import androidx.viewpager2.adapter.FragmentStateAdapter; @@ -12,8 +13,8 @@ import com.ssb.simplitend.welcome.welcomecg.fragments.onboardfragemts.OnBoardTwo public class CgOnBoardAdapter extends FragmentStateAdapter { - public CgOnBoardAdapter(@NonNull FragmentManager fragmentManager, @NonNull Lifecycle lifecycle) { - super(fragmentManager, lifecycle); + public CgOnBoardAdapter(@NonNull FragmentActivity fragmentActivity) { + super(fragmentActivity); } @NonNull diff --git a/app/src/main/java/com/ssb/simplitend/welcome/welcomecg/fragments/CgOnBoardFragment.java b/app/src/main/java/com/ssb/simplitend/welcome/welcomecg/fragments/CgOnBoardFragment.java index 0de863e..075e550 100644 --- a/app/src/main/java/com/ssb/simplitend/welcome/welcomecg/fragments/CgOnBoardFragment.java +++ b/app/src/main/java/com/ssb/simplitend/welcome/welcomecg/fragments/CgOnBoardFragment.java @@ -1,10 +1,13 @@ package com.ssb.simplitend.welcome.welcomecg.fragments; import android.os.Bundle; +import android.util.DisplayMetrics; +import android.util.TypedValue; import android.view.LayoutInflater; import android.view.View; import android.view.ViewGroup; import android.widget.ImageView; +import android.widget.Toast; import androidx.annotation.NonNull; import androidx.annotation.Nullable; @@ -58,8 +61,11 @@ public class CgOnBoardFragment extends Fragment { } private void initViews() { + + setUpDynamicTextSizes(); + // initiating view pager - CgOnBoardAdapter adapter = new CgOnBoardAdapter(getChildFragmentManager(), getLifecycle()); + CgOnBoardAdapter adapter = new CgOnBoardAdapter(requireActivity()); binding.viewPager.setAdapter(adapter); binding.indicators.setViewPager(binding.viewPager); @@ -92,8 +98,7 @@ public class CgOnBoardFragment extends Fragment { break; default: title = getString(R.string.reinventing_connected_ncaregiving); - subtitle = getString(R.string.you_are_always_connected_and_will_be_notified_when_your_loved_ones_need_you); - break; + subtitle = getString(R.string.no_new_gadgets_monitor_your_loved_one_s_activity_using_his_or_her_smartphone); } binding.title.setText(title); @@ -101,6 +106,31 @@ public class CgOnBoardFragment extends Fragment { } }); + + } + + private void setUpDynamicTextSizes() { + // Calculate screen dimensions in pixels + DisplayMetrics displayMetrics = getResources().getDisplayMetrics(); + int screenWidth = displayMetrics.widthPixels; + int screenHeight = displayMetrics.heightPixels; + + // Calculate aspect ratio + float aspectRatio = (float) screenHeight / (float) screenWidth; + + if (aspectRatio > 2.1){ + // screen is taller + binding.title.setTextSize(TypedValue.COMPLEX_UNIT_PX, getResources().getDimension(R.dimen.cg_title_tall)); + binding.subTitle.setTextSize(TypedValue.COMPLEX_UNIT_PX, getResources().getDimension(R.dimen.cg_sub_title_tall)); + }else if (aspectRatio > 2){ + // screen is normal size + binding.title.setTextSize(TypedValue.COMPLEX_UNIT_PX, getResources().getDimension(R.dimen.cg_title_tall_medium)); + binding.subTitle.setTextSize(TypedValue.COMPLEX_UNIT_PX, getResources().getDimension(R.dimen.cg_sub_title_tall_medium)); + }else { + // screen is smaller + binding.title.setTextSize(TypedValue.COMPLEX_UNIT_PX, getResources().getDimension(R.dimen.cg_title_small)); + binding.subTitle.setTextSize(TypedValue.COMPLEX_UNIT_PX, getResources().getDimension(R.dimen.cg_sub_title_small)); + } } } diff --git a/app/src/main/java/com/ssb/simplitend/welcome/welcomecg/fragments/CgRegisterFragment.java b/app/src/main/java/com/ssb/simplitend/welcome/welcomecg/fragments/CgRegisterFragment.java index 9f9ec86..8c4351c 100644 --- a/app/src/main/java/com/ssb/simplitend/welcome/welcomecg/fragments/CgRegisterFragment.java +++ b/app/src/main/java/com/ssb/simplitend/welcome/welcomecg/fragments/CgRegisterFragment.java @@ -32,6 +32,7 @@ import com.google.i18n.phonenumbers.Phonenumber; import com.ssb.simplitend.R; import com.ssb.simplitend.apputils.AppUtil; import com.ssb.simplitend.apputils.EditTextErrorRemover; +import com.ssb.simplitend.apputils.UserDataCache; import com.ssb.simplitend.databinding.CgRegisterFragmentBinding; import com.ssb.simplitend.databinding.PasswordPopUpBinding; import com.ssb.simplitend.welcome.welcomecg.WelcomeContracts; @@ -425,6 +426,8 @@ public class CgRegisterFragment extends Fragment implements WelcomeContracts.Reg public void onCareGiverRegistered(CareGiverData careGiverData, String token) { Toast.makeText(requireContext(), "Caregiver registered successfully.", Toast.LENGTH_SHORT).show(); + UserDataCache.careGiverData = careGiverData; + AppUtil.saveCgData(token, requireContext()); Bundle bundle = new Bundle(); diff --git a/app/src/main/java/com/ssb/simplitend/welcome/welcomepatient/fragments/contacts/ContactInfoFragment.java b/app/src/main/java/com/ssb/simplitend/welcome/welcomepatient/fragments/contacts/ContactInfoFragment.java index 4ae025d..7fa5bf3 100644 --- a/app/src/main/java/com/ssb/simplitend/welcome/welcomepatient/fragments/contacts/ContactInfoFragment.java +++ b/app/src/main/java/com/ssb/simplitend/welcome/welcomepatient/fragments/contacts/ContactInfoFragment.java @@ -82,7 +82,13 @@ public class ContactInfoFragment extends Fragment implements WelcomeContracts.De binding.name.setText(contactData.first_name); binding.phoneNumber.setText(contactData.phone_number); - binding.email.setText(contactData.email_address); + + if (contactData.email_address != null) + { + binding.email.setText(contactData.email_address); + }else{ + binding.email.setText("None"); + } if (contactData.relationship == null || contactData.relationship.trim().isEmpty()){ binding.relationship.setVisibility(View.GONE); diff --git a/app/src/main/java/com/ssb/simplitend/welcome/welcomepatient/fragments/contacts/CreateContactFragment.java b/app/src/main/java/com/ssb/simplitend/welcome/welcomepatient/fragments/contacts/CreateContactFragment.java index 1760335..5d6a62e 100644 --- a/app/src/main/java/com/ssb/simplitend/welcome/welcomepatient/fragments/contacts/CreateContactFragment.java +++ b/app/src/main/java/com/ssb/simplitend/welcome/welcomepatient/fragments/contacts/CreateContactFragment.java @@ -352,7 +352,7 @@ public class CreateContactFragment extends Fragment implements WelcomeContracts. } } - if (binding.email.getText().toString().trim().isEmpty()) { + if (mustBeeCaregiver && binding.email.getText().toString().trim().isEmpty()) { allOkay = false; binding.email.setError("Required"); } diff --git a/app/src/main/java/com/ssb/simplitend/welcome/welcomepatient/fragments/contacts/mvvm/ContactViewModel.java b/app/src/main/java/com/ssb/simplitend/welcome/welcomepatient/fragments/contacts/mvvm/ContactViewModel.java index b05bbef..24596fb 100644 --- a/app/src/main/java/com/ssb/simplitend/welcome/welcomepatient/fragments/contacts/mvvm/ContactViewModel.java +++ b/app/src/main/java/com/ssb/simplitend/welcome/welcomepatient/fragments/contacts/mvvm/ContactViewModel.java @@ -7,6 +7,8 @@ import android.view.LayoutInflater; import androidx.annotation.NonNull; import androidx.lifecycle.AndroidViewModel; +import androidx.lifecycle.LiveData; +import androidx.lifecycle.MutableLiveData; import com.bumptech.glide.Glide; import com.google.android.material.bottomsheet.BottomSheetDialog; @@ -23,6 +25,8 @@ import java.io.IOException; import java.io.InputStream; import java.io.InputStreamReader; import java.util.ArrayList; +import java.util.Collections; +import java.util.Comparator; import java.util.HashMap; import java.util.Map; import java.util.TreeMap; @@ -40,15 +44,24 @@ public class ContactViewModel extends AndroidViewModel { private SOSCheckInterface sosCheckInterface; + private final MutableLiveData>> mutableContactList; + private final LiveData>> live_contact_list; + public ContactViewModel(Application application){ super(application); this.contactRepository = UserContactRepository.getContactRepository(); + mutableContactList = new MutableLiveData<>(null); + live_contact_list = mutableContactList; + } + + public LiveData>> getLive_contact_list() { + return live_contact_list; } public ArrayList> getContactList(Context context) { ArrayList> contactLIst = new ArrayList<>(); - TreeMap> contactMap = this.contactRepository.getContactList(context); + HashMap> contactMap = this.contactRepository.getContactList(context); for (ArrayList contacts: contactMap.values()){ if (contacts != null && contacts.size() > 0){ @@ -56,6 +69,8 @@ public class ContactViewModel extends AndroidViewModel { } } + Collections.sort(contactLIst, (contacts, t1) -> contacts.get(0).first_name.compareTo(t1.get(0).first_name)); + return contactLIst; } diff --git a/app/src/main/java/com/ssb/simplitend/welcome/welcomepatient/fragments/contacts/mvvm/UserContactRepository.java b/app/src/main/java/com/ssb/simplitend/welcome/welcomepatient/fragments/contacts/mvvm/UserContactRepository.java index d38ea96..94d8a83 100644 --- a/app/src/main/java/com/ssb/simplitend/welcome/welcomepatient/fragments/contacts/mvvm/UserContactRepository.java +++ b/app/src/main/java/com/ssb/simplitend/welcome/welcomepatient/fragments/contacts/mvvm/UserContactRepository.java @@ -3,14 +3,12 @@ package com.ssb.simplitend.welcome.welcomepatient.fragments.contacts.mvvm; import android.content.ContentResolver; import android.content.Context; import android.database.Cursor; +import android.net.Uri; import android.provider.ContactsContract; -import android.telephony.PhoneNumberUtils; import android.util.Log; import androidx.annotation.NonNull; -import com.google.i18n.phonenumbers.PhoneNumberUtil; -import com.google.i18n.phonenumbers.Phonenumber; import com.ssb.simplitend.apputils.RetrofitHelper; import com.ssb.simplitend.welcome.welcomepatient.fragments.contacts.mvvm.models.ContactListResponse; import com.ssb.simplitend.welcome.welcomepatient.mvvm.WelcomeApiService; @@ -19,11 +17,8 @@ import com.ssb.simplitend.welcome.welcomepatient.mvvm.models.CallResponse; import java.util.ArrayList; import java.util.HashMap; -import java.util.HashSet; import java.util.List; -import java.util.Locale; import java.util.Map; -import java.util.TreeMap; import okhttp3.MultipartBody; import okhttp3.RequestBody; @@ -38,35 +33,35 @@ public class UserContactRepository { private static final String[] PROJECTION = new String[]{ ContactsContract.CommonDataKinds.Phone.CONTACT_ID, ContactsContract.Contacts.DISPLAY_NAME, - ContactsContract.CommonDataKinds.Phone.NUMBER, + ContactsContract.CommonDataKinds.Phone.NUMBER }; private static UserContactRepository contactRepository; private final WelcomeApiService apiService; - private UserContactRepository(){ + private UserContactRepository() { apiService = RetrofitHelper.getRetrofit().create(WelcomeApiService.class); } - public static synchronized UserContactRepository getContactRepository(){ - if (contactRepository == null){ + public static synchronized UserContactRepository getContactRepository() { + if (contactRepository == null) { contactRepository = new UserContactRepository(); } return contactRepository; } - public void getRemoteContactList(WelcomeContracts.ContactListContracts contactListContracts, String token){ + public void getRemoteContactList(WelcomeContracts.ContactListContracts contactListContracts, String token) { apiService.getContactList(token).enqueue(new Callback>>() { @Override public void onResponse(Call>> call, Response>> response) { - if (response.isSuccessful() && response.body() != null && response.body().result != null){ + if (response.isSuccessful() && response.body() != null && response.body().result != null) { contactListContracts.onResponse(response.body().result); - }else if (response.body() != null && response.body().result != null){ + } else if (response.body() != null && response.body().result != null) { Log.e(TAG, "onResponse: get contact list" + response); contactListContracts.onFailure(new Exception(response.toString()), response.body().message, response.code()); - }else{ + } else { Log.e(TAG, "onResponse: no success response and also response body is null"); contactListContracts.onFailure(new Exception("no success response and also response body is null"), "It's not you, it's us.\nPlease try again later", 1); } @@ -87,41 +82,39 @@ public class UserContactRepository { MultipartBody.Part userImage, WelcomeContracts.CreateContactInterface createContactInterface, WelcomeContracts.UpdateContactContracts updateContactContracts, - @NonNull String token){ + @NonNull String token) { apiService.createEditContact(URL, body, intBody, userImage, token).enqueue(new Callback>() { @Override public void onResponse(Call> call, Response> response) { - if (response.isSuccessful() && response.body() != null && response.body().result != null){ - if (createContactInterface != null) - { + if (response.isSuccessful() && response.body() != null && response.body().result != null) { + if (createContactInterface != null) { createContactInterface.onContactCreated(response.body().result); } - if (updateContactContracts != null){ + if (updateContactContracts != null) { updateContactContracts.onContactUpdated(); } - }else if (response.body() != null){ + } else if (response.body() != null) { Log.e(TAG, "onResponse: contact create or edit contact " + response); - if (createContactInterface != null) - { + if (createContactInterface != null) { createContactInterface.onContactCreateFailed(new Exception(response.toString()), response.body().message, response.code()); } - if (updateContactContracts != null){ + if (updateContactContracts != null) { updateContactContracts.onUpdateFailed(); } - }else{ + } else { Log.e(TAG, "onResponse: no success response and also response body is null"); - if (createContactInterface != null){ + if (createContactInterface != null) { createContactInterface.onContactCreateFailed(new Exception("no success response and also response body is null"), "It's not you, it's us.\nPlease try again later", 1); } - if (updateContactContracts != null){ + if (updateContactContracts != null) { updateContactContracts.onUpdateFailed(); } @@ -132,12 +125,11 @@ public class UserContactRepository { public void onFailure(Call> call, Throwable t) { Log.e(TAG, "onFailure: create or update contact ", t); - if (createContactInterface != null) - { + if (createContactInterface != null) { createContactInterface.onContactCreateFailed(t, "It's not you, it's us.\nPlease try again later.", 1); } - if (updateContactContracts != null){ + if (updateContactContracts != null) { updateContactContracts.onUpdateFailed(); } } @@ -146,14 +138,14 @@ public class UserContactRepository { } public void deleteContact(int contact_id, String token, - @NonNull WelcomeContracts.DeleteContactInterface deleteContactInterface){ + @NonNull WelcomeContracts.DeleteContactInterface deleteContactInterface) { apiService.deleteContact(token, contact_id) .enqueue(new Callback>() { @Override public void onResponse(Call> call, Response> response) { - if (response.isSuccessful()){ + if (response.isSuccessful()) { deleteContactInterface.onContactDelete(); - }else{ + } else { deleteContactInterface.onContactDeleteFailed(); Log.e(TAG, "onResponse: delete contact message " + response.message() + " " + "code " + response.code()); @@ -168,13 +160,13 @@ public class UserContactRepository { }); } - public TreeMap> getContactList(Context context) { + public HashMap> getContactList(Context context) { /* key -> name values -> different contacts with same name */ - TreeMap> contactMap = new TreeMap<>(); + HashMap> contactMap = new HashMap<>(); ContentResolver cr = context.getContentResolver(); @@ -187,12 +179,14 @@ public class UserContactRepository { if (cursor != null) { try { + final int c_id_index = cursor.getColumnIndex(ContactsContract.CommonDataKinds.Phone.CONTACT_ID); final int nameIndex = cursor.getColumnIndex(ContactsContract.Contacts.DISPLAY_NAME); final int numberIndex = cursor.getColumnIndex(ContactsContract.CommonDataKinds.Phone.NUMBER); while (cursor.moveToNext()) { String name = cursor.getString(nameIndex); String number = cursor.getString(numberIndex); + String c_id = cursor.getString(c_id_index); if (number == null) continue; if (name == null || name.isEmpty()) name = "No name"; @@ -201,28 +195,65 @@ public class UserContactRepository { ArrayList contactList; - if (contactMap.containsKey(name)){ + if (contactMap.containsKey(c_id)) { // there is already number associate with this name // thus, adding to the existing contact list against the name - contactList = contactMap.get(name); - }else{ + contactList = contactMap.get(c_id); + } else { contactList = new ArrayList<>(); } if (contactList == null) contactList = new ArrayList<>(); contactList.add(contact); - contactMap.put(name, contactList); + contactMap.put(c_id, contactList); } - }catch (Exception e){ + } catch (Exception e) { // do nothing - } - finally { + } finally { cursor.close(); } } + getEmailForContact(context, contactMap); + return contactMap; } + private void getEmailForContact(Context context, HashMap> contactMap) { + Uri emailUri = ContactsContract.CommonDataKinds.Email.CONTENT_URI; + String[] emailProjection = { + ContactsContract.CommonDataKinds.Email.ADDRESS, + ContactsContract.CommonDataKinds.Email.CONTACT_ID + }; + + try (Cursor emailCursor = context.getContentResolver().query(emailUri, emailProjection, null, null, null)) { + if (emailCursor != null) { + final int email_index = emailCursor.getColumnIndex(ContactsContract.CommonDataKinds.Email.ADDRESS); + final int c_id_index = emailCursor.getColumnIndex(ContactsContract.CommonDataKinds.Email.CONTACT_ID); + final int count = emailCursor.getCount(); + + if (emailCursor.moveToNext()) + { + String email = emailCursor.getString(email_index); + String c_id = emailCursor.getString(c_id_index); + + if (contactMap.containsKey(c_id)){ + ArrayList contacts = contactMap.get(c_id); + if (contacts != null){ + for (Contact contact: contacts){ + if (contact != null){ + contact.email_address = email; + } + } + } + } + } + + } + }catch (Exception e){ + Log.e(TAG, "getEmailForContact: ", e); + } + } + } diff --git a/app/src/main/java/com/ssb/simplitend/welcome/welcomepatient/fragments/contacts/mvvm/models/ContactData.java b/app/src/main/java/com/ssb/simplitend/welcome/welcomepatient/fragments/contacts/mvvm/models/ContactData.java index d7b6029..0a5901a 100644 --- a/app/src/main/java/com/ssb/simplitend/welcome/welcomepatient/fragments/contacts/mvvm/models/ContactData.java +++ b/app/src/main/java/com/ssb/simplitend/welcome/welcomepatient/fragments/contacts/mvvm/models/ContactData.java @@ -25,6 +25,7 @@ public class ContactData implements Serializable { public ContactData(Contact contact){ this.first_name = contact.first_name; this.phone_number = contact.phone_number; + this.email_address = contact.email_address; } public ContactData(int id) { diff --git a/app/src/main/java/com/ssb/simplitend/welcome/welcomepatient/fragments/register/SplashFragment.java b/app/src/main/java/com/ssb/simplitend/welcome/welcomepatient/fragments/register/SplashFragment.java index 9a632d4..7117042 100644 --- a/app/src/main/java/com/ssb/simplitend/welcome/welcomepatient/fragments/register/SplashFragment.java +++ b/app/src/main/java/com/ssb/simplitend/welcome/welcomepatient/fragments/register/SplashFragment.java @@ -179,7 +179,7 @@ public class SplashFragment extends Fragment // patient is linked with the caregiver int cg_security = AppUtil.getWantSecurityFlag(requireContext()); - if (cg_security == AppUtil.NOT_ASKED_CG_SECURITY){ + if (cg_security == AppUtil.NOT_ASKED_CG_SECURITY || cg_security == AppUtil.CG_SECURITY_NEEDED){ // user want their app to be secure gotoCgAuthScreen(); }else{ diff --git a/app/src/main/res/layout/add_reminder_fragment.xml b/app/src/main/res/layout/add_reminder_fragment.xml index 467fcd6..e0386a3 100644 --- a/app/src/main/res/layout/add_reminder_fragment.xml +++ b/app/src/main/res/layout/add_reminder_fragment.xml @@ -123,7 +123,7 @@ android:drawableStart="@drawable/ic_dosage" android:drawablePadding="10dp" - android:maxLength="3" + android:maxLength="6" android:autofillHints="@null" android:inputType="numberDecimal" diff --git a/app/src/main/res/layout/cg_onboard_fragment.xml b/app/src/main/res/layout/cg_onboard_fragment.xml index 24230cd..0d551cf 100644 --- a/app/src/main/res/layout/cg_onboard_fragment.xml +++ b/app/src/main/res/layout/cg_onboard_fragment.xml @@ -1,132 +1,139 @@ - + android:background="@color/white" + android:orientation="vertical" + android:weightSum="10"> + + android:layout_marginBottom="@dimen/_5sdp" + + app:layout_constraintBottom_toTopOf="@+id/indicators" + app:layout_constraintEnd_toEndOf="parent" + app:layout_constraintStart_toStartOf="parent" + app:layout_constraintTop_toTopOf="parent" /> + android:layout_marginBottom="@dimen/_10sdp" - + + + + android:layout_height="wrap_content" - - android:layout_marginHorizontal="15dp" + + android:layout_marginStart="@dimen/_15sdp" + android:layout_marginEnd="@dimen/_15sdp" + android:layout_marginBottom="@dimen/_15sdp" + android:fontFamily="@font/nunito_regular" - - - + android:textSize="@dimen/_18ssp" + app:layout_constraintBottom_toTopOf="@+id/relativeLayout2" + app:layout_constraintEnd_toEndOf="parent" + app:layout_constraintStart_toStartOf="parent" /> + android:layout_height="wrap_content" + android:layout_marginHorizontal="15dp" + android:layout_marginBottom="@dimen/_5sdp" + app:layout_constraintBottom_toBottomOf="parent" + app:layout_constraintEnd_toEndOf="parent" + app:layout_constraintStart_toStartOf="parent"> + + - - - \ No newline at end of file + \ No newline at end of file diff --git a/app/src/main/res/values/dimens.xml b/app/src/main/res/values/dimens.xml index 4777e33..461d546 100644 --- a/app/src/main/res/values/dimens.xml +++ b/app/src/main/res/values/dimens.xml @@ -12,4 +12,12 @@ @dimen/_16ssp @dimen/_14ssp + @dimen/_22ssp + @dimen/_20ssp + @dimen/_18ssp + + @dimen/_18ssp + @dimen/_16ssp + @dimen/_14ssp + \ No newline at end of file diff --git a/app/src/main/res/values/strings.xml b/app/src/main/res/values/strings.xml index 6c90b64..85072cd 100644 --- a/app/src/main/res/values/strings.xml +++ b/app/src/main/res/values/strings.xml @@ -249,10 +249,10 @@ Install Caregiver app to proceed. Your profile is being updated Reinventing connected\nCaregiving - Check your loved one’s medication schedule. + Update your loved one\'s profile information. Setup a geofence to\nprotect your loved one. - You are always connected and will be notified when your loved ones need you. - Application will notify you when it is time for your loved one to take his/her medication. + Be notified if your loved one ventures too far from home or a designated safe area + For example, you may use your phone to examine and verify your loved one\'s medication schedule. Be notified if your loved one ventures too far from home or a designated safe area. Skip Get started @@ -260,7 +260,7 @@ Accept invitation Accept your loved one\'s invitation to connect - Subscribe ! + Subscribe Complete application subscription You are ready! Your phone is linked to your loved one. @@ -307,5 +307,7 @@ Security To enhance the security of your account, please add biometric authentication using either Face ID or Fingerprint. Setup security + No new gadgets! monitor your loved one\'s activity using his or her smartphone + 595 \ No newline at end of file