From abc3070b1819bc87f5ba996117b3d64f15ca3841 Mon Sep 17 00:00:00 2001 From: ADITYA Date: Thu, 13 Jul 2023 21:12:17 +0530 Subject: [PATCH] . --- app/build.gradle | 19 +- app/src/main/AndroidManifest.xml | 11 + .../com/ssb/simplitend/apputils/AppUtil.java | 53 +++ .../simplitend/apputils/RetrofitHelper.java | 46 +++ .../chats/ChatFragment.java | 99 +++++ .../chats/ChatListAdapter.java | 22 + .../chats/ChatListFragment.java | 15 +- .../chats/mvvm/Author.java | 21 + .../chats/mvvm/ChatItem.java | 4 +- .../chats/mvvm/Message.java | 37 ++ .../chats/mvvm/Receiver.java | 22 + .../welcome/activities/WelcomeActivity.java | 3 +- .../welcome/fragments/WelcomeFragment.java | 4 + .../contacts/ContactListFragment.java | 4 +- .../contacts/CreateContactFragment.java | 269 +++++-------- .../contacts/mvvm/AddContactAdapter.java | 1 - .../fragments/contacts/mvvm/Contact.java | 24 +- .../contacts/mvvm/ContactViewModel.java | 184 ++++++++- .../contacts/mvvm/UserContactRepository.java | 84 +++- .../mvvm/models/ContactListResponse.java | 76 ++++ .../fragments/register/CreatePinFragment.java | 100 ++++- .../fragments/register/LocationFragment.java | 380 +++++++++++++++++- .../fragments/register/RegisterFragment.java | 105 ++++- .../fragments/register/ThankYouFragment.java | 4 - .../simplitend/welcome/mvvm/APIService.java | 29 ++ .../welcome/mvvm/WelcomeContracts.java | 34 ++ .../welcome/mvvm/WelcomeRepository.java | 64 +++ .../welcome/mvvm/WelcomeViewModel.java | 54 +++ .../welcome/mvvm/models/CallResponse.java | 13 + .../welcome/mvvm/models/PatientData.java | 58 +++ .../welcome/mvvm/models/PatientResult.java | 19 + .../main/res/drawable/ic_smiley_outline.xml | 34 ++ .../layout/caregiver_dashboard_fragment.xml | 16 +- .../main/res/layout/chat_card_viewholder.xml | 1 + app/src/main/res/layout/chat_fragment.xml | 109 +++++ .../main/res/layout/create_pin_fragment.xml | 2 + app/src/main/res/layout/location_fragment.xml | 75 +++- app/src/main/res/layout/register_fragment.xml | 74 +++- .../main/res/layout/sender_msg_viewholder.xml | 43 ++ .../main/res/layout/thank_you_fragment.xml | 15 +- .../res/navigation/cp_dashboard_graph.xml | 10 +- .../main/res/navigation/welcome_nav_graph.xml | 7 +- app/src/main/res/values/strings.xml | 15 +- build.gradle | 1 + 44 files changed, 1994 insertions(+), 266 deletions(-) create mode 100644 app/src/main/java/com/ssb/simplitend/apputils/RetrofitHelper.java create mode 100644 app/src/main/java/com/ssb/simplitend/careperson_dashboard/chats/ChatFragment.java create mode 100644 app/src/main/java/com/ssb/simplitend/careperson_dashboard/chats/mvvm/Author.java create mode 100644 app/src/main/java/com/ssb/simplitend/careperson_dashboard/chats/mvvm/Message.java create mode 100644 app/src/main/java/com/ssb/simplitend/careperson_dashboard/chats/mvvm/Receiver.java create mode 100644 app/src/main/java/com/ssb/simplitend/welcome/fragments/contacts/mvvm/models/ContactListResponse.java create mode 100644 app/src/main/java/com/ssb/simplitend/welcome/mvvm/APIService.java create mode 100644 app/src/main/java/com/ssb/simplitend/welcome/mvvm/WelcomeContracts.java create mode 100644 app/src/main/java/com/ssb/simplitend/welcome/mvvm/WelcomeRepository.java create mode 100644 app/src/main/java/com/ssb/simplitend/welcome/mvvm/WelcomeViewModel.java create mode 100644 app/src/main/java/com/ssb/simplitend/welcome/mvvm/models/CallResponse.java create mode 100644 app/src/main/java/com/ssb/simplitend/welcome/mvvm/models/PatientData.java create mode 100644 app/src/main/java/com/ssb/simplitend/welcome/mvvm/models/PatientResult.java create mode 100644 app/src/main/res/drawable/ic_smiley_outline.xml create mode 100644 app/src/main/res/layout/chat_fragment.xml create mode 100644 app/src/main/res/layout/sender_msg_viewholder.xml diff --git a/app/build.gradle b/app/build.gradle index 3fbb5bc..edf8af1 100644 --- a/app/build.gradle +++ b/app/build.gradle @@ -1,5 +1,6 @@ plugins { id 'com.android.application' + id 'com.google.android.libraries.mapsplatform.secrets-gradle-plugin' } android { @@ -64,7 +65,23 @@ dependencies { // cicle image view implementation 'de.hdodenhof:circleimageview:3.1.0' - implementation 'com.github.stfalcon-studio:Chatkit:0.4.1' + // chat view + implementation 'com.github.stfalcon-studio:Chatkit:v0.4.1' + + // mapview + implementation 'com.google.android.gms:play-services-maps:18.1.0' + + // location + implementation 'com.google.android.gms:play-services-location:21.0.1' + + // places api + implementation 'com.google.android.libraries.places:places:3.1.0' + + // retrofit + implementation 'com.squareup.retrofit2:retrofit:2.9.0' + + // gson converter + implementation 'com.squareup.retrofit2:converter-gson:2.9.0' implementation 'androidx.appcompat:appcompat:1.6.0' implementation 'com.google.android.material:material:1.8.0' diff --git a/app/src/main/AndroidManifest.xml b/app/src/main/AndroidManifest.xml index 2636ab4..a22ad85 100644 --- a/app/src/main/AndroidManifest.xml +++ b/app/src/main/AndroidManifest.xml @@ -2,6 +2,8 @@ + + + + + + + { + Request request = chain.request().newBuilder() + .addHeader("Accept", "*/*") + .addHeader("Accept-Encoding", "gzip, deflate, br") + .addHeader("Connection", "keep-alive") + .addHeader("Content-Type", "multipart/form-data") + .build(); + return chain.proceed(request); + }).build()) + .build(); + } + + return retrofit; + } + +} diff --git a/app/src/main/java/com/ssb/simplitend/careperson_dashboard/chats/ChatFragment.java b/app/src/main/java/com/ssb/simplitend/careperson_dashboard/chats/ChatFragment.java new file mode 100644 index 0000000..a787619 --- /dev/null +++ b/app/src/main/java/com/ssb/simplitend/careperson_dashboard/chats/ChatFragment.java @@ -0,0 +1,99 @@ +package com.ssb.simplitend.careperson_dashboard.chats; + +import android.os.Bundle; +import android.view.LayoutInflater; +import android.view.View; +import android.view.ViewGroup; +import android.widget.Toast; + +import androidx.annotation.NonNull; +import androidx.annotation.Nullable; +import androidx.fragment.app.Fragment; +import androidx.navigation.Navigation; + +import com.ssb.simplitend.R; +import com.ssb.simplitend.careperson_dashboard.chats.mvvm.Author; +import com.ssb.simplitend.careperson_dashboard.chats.mvvm.ChatItem; +import com.ssb.simplitend.careperson_dashboard.chats.mvvm.Message; +import com.ssb.simplitend.careperson_dashboard.chats.mvvm.Receiver; +import com.ssb.simplitend.databinding.ChatFragmentBinding; +import com.stfalcon.chatkit.messages.MessagesListAdapter; + +public class ChatFragment extends Fragment { + + // view binding + protected ChatFragmentBinding binding; + + // chat item + private ChatItem chatItem; + public static final String CHAT_ITEM_KEY = "chat_item_key"; + + private MessagesListAdapter messageAdapter; + + public ChatFragment() { + // required + } + + @Nullable + @Override + public View onCreateView(@NonNull LayoutInflater inflater, @Nullable ViewGroup container, @Nullable Bundle savedInstanceState) { + binding = ChatFragmentBinding.inflate(inflater, container, false); + + initViews(); + + clickEvents(); + + return binding.getRoot(); + } + + private void clickEvents() { + binding.backBtn.setOnClickListener(v -> Navigation.findNavController(v).popBackStack()); + + binding.sendBtn.setOnClickListener(v -> { + if (!binding.messageEt.getText().toString().trim().isEmpty()){ + messageAdapter.addToStart(new Message(new Author(), binding.messageEt.getText().toString().trim()), true); + binding.messageEt.setText(null); + } + }); + + } + + private void initViews() { + + Bundle bundle = getArguments(); + + if (bundle == null) { + Toast.makeText(requireActivity(), "Something went wrong", Toast.LENGTH_SHORT).show(); + return; + } + + chatItem = (ChatItem) bundle.getSerializable(CHAT_ITEM_KEY); + + if (chatItem == null) { + Toast.makeText(requireActivity(), "Something went wrong", Toast.LENGTH_SHORT).show(); + return; + } + + binding.chatTitle.setText(chatItem.name); + + MessagesListAdapter.HoldersConfig holdersConfig = new MessagesListAdapter.HoldersConfig(); + holdersConfig.setOutcomingLayout(R.layout.sender_msg_viewholder); + + messageAdapter = new MessagesListAdapter<>("sender", holdersConfig, (imageView, url, payload) -> { + if (url != null) imageView.setImageResource(Integer.parseInt(url)); + }); + binding.messageList.setAdapter(messageAdapter); + + // static + messageAdapter.addToStart(new Message(new Author(), "Good morning"), true); + messageAdapter.addToStart(new Message(new Receiver(), "Good morning mate! I am fine here how are you there"), true); + messageAdapter.addToStart(new Message(new Author(), "Good morning"), true); + messageAdapter.addToStart(new Message(new Receiver(), "Good morning mate!"), true); + messageAdapter.addToStart(new Message(new Author(), "Good morning"), true); + messageAdapter.addToStart(new Message(new Receiver(), "Good morning mate!"), true); + messageAdapter.addToStart(new Message(new Author(), "Good morning"), true); + messageAdapter.addToStart(new Message(new Receiver(), "Good morning mate!"), true); + + messageAdapter.addToStart(new Message(new Receiver(), chatItem.last_message), true); + } +} \ No newline at end of file diff --git a/app/src/main/java/com/ssb/simplitend/careperson_dashboard/chats/ChatListAdapter.java b/app/src/main/java/com/ssb/simplitend/careperson_dashboard/chats/ChatListAdapter.java index cc08d37..02e7042 100644 --- a/app/src/main/java/com/ssb/simplitend/careperson_dashboard/chats/ChatListAdapter.java +++ b/app/src/main/java/com/ssb/simplitend/careperson_dashboard/chats/ChatListAdapter.java @@ -13,6 +13,8 @@ import com.ssb.simplitend.databinding.ChatCardViewholderBinding; public class ChatListAdapter extends ListAdapter { + private OnChatItemClickListener chatItemClickListener; + private static final DiffUtil.ItemCallback DIFF_UTIL = new DiffUtil.ItemCallback() { @Override public boolean areItemsTheSame(@NonNull ChatItem oldItem, @NonNull ChatItem newItem) { @@ -41,6 +43,12 @@ public class ChatListAdapter extends ListAdapter { + if (chatItemClickListener != null){ + chatItemClickListener.onChatItemClick(getItem(position), position); + } + }); } public static class ChatCardViewHolder extends RecyclerView.ViewHolder{ @@ -61,4 +69,18 @@ public class ChatListAdapter extends ListAdapter imageSelector; + private ContactViewModel contactViewModel; + + private ArrayList countryCodeList; + public CreateContactFragment() { // required empty const. } @@ -59,6 +66,12 @@ public class CreateContactFragment extends Fragment { public View onCreateView(@NonNull LayoutInflater inflater, @Nullable ViewGroup container, @Nullable Bundle savedInstanceState) { binding = CreateEditContactFragmentBinding.inflate(inflater, container, false); + contactViewModel = new ViewModelProvider(requireActivity()).get(ContactViewModel.class); + + // interfaces + contactViewModel.setSosCheckInterface(this); + contactViewModel.setGotoAddContactInterface(this); + initializeViews(); clickEvents(); @@ -66,106 +79,6 @@ public class CreateContactFragment extends Fragment { return binding.getRoot(); } - private void clickEvents() { - - binding.backBtn.setOnClickListener(v -> Navigation.findNavController(v).popBackStack()); - - binding.nextBtn.setOnClickListener(v -> { - - if (to_edit){ - // editing existing contact - showSaveEditDecision(); - }else { - // saving new contact - Navigation.findNavController(v).popBackStack(); - } - - }); - - binding.image.setOnClickListener(v -> imageSelector.launch("image/*")); - - } - - private void showSaveEditDecision() { - - DecisionBottomsheetBinding binding = DecisionBottomsheetBinding.inflate(getLayoutInflater()); - - BottomSheetDialog bsd = new BottomSheetDialog(requireContext(), R.style.BottomSheetDialog); - bsd.setContentView(binding.getRoot()); - - binding.text.setText(getString(R.string.make_changes)); - - binding.positiveBtn.setText(getString(R.string.yes)); - binding.negativeBtn.setText(getString(R.string.no)); - - binding.negativeBtn.setOnClickListener(v -> bsd.dismiss()); - - binding.positiveBtn.setOnClickListener(v -> { - bsd.dismiss(); - showDoneBottomSheet(); - }); - - bsd.show(); - - } - - private void showDoneBottomSheet() { - DoneBottomsheetBinding binding = DoneBottomsheetBinding.inflate(getLayoutInflater()); - - BottomSheetDialog bsd = new BottomSheetDialog(requireContext(), R.style.BottomSheetDialog); - bsd.setContentView(binding.getRoot()); - bsd.setCancelable(false); - - binding.text.setText(getString(R.string.changes_successful)); - - Glide.with(requireContext()) - .asGif() - .load(R.raw.done_anim_primary) - .into(binding.doneAnim); - - bsd.show(); - - gotoAddContactFragment(3000, bsd); - - } - - private void gotoAddContactFragment(long inMsm, BottomSheetDialog bsd){ - - new Handler().postDelayed(() -> { - if (bsd != null) bsd.dismiss(); - Navigation.findNavController(binding.getRoot()) - .navigate(R.id.action_createContactFragment_to_addContactFragment); - - }, inMsm); - } - - private void showSOSDecision() { - - DecisionBottomsheetBinding binding = DecisionBottomsheetBinding.inflate(getLayoutInflater()); - - BottomSheetDialog bsd = new BottomSheetDialog(requireContext(), R.style.BottomSheetDialog); - bsd.setContentView(binding.getRoot()); - bsd.setCancelable(false); - - binding.text.setText(getString(R.string.make_sos)); - - binding.positiveBtn.setText(getString(R.string.yes)); - binding.negativeBtn.setText(getString(R.string.no)); - - binding.negativeBtn.setOnClickListener(v -> { - bsd.dismiss(); - this.binding.sosCheck.setChecked(false); - }); - - binding.positiveBtn.setOnClickListener(v -> { - bsd.dismiss(); - this.binding.sosCheck.setChecked(true); - }); - - bsd.show(); - - } - private void initializeViews() { Bundle bundle = getArguments(); @@ -184,14 +97,14 @@ public class CreateContactFragment extends Fragment { } } + progressDialog = new ProgressDialog(requireContext()); + binding.sosCheck.setOnCheckedChangeListener((buttonView, isChecked) -> { if (isChecked){ - showSOSDecision(); + contactViewModel.showSOSDecision(requireContext()); } }); - loadCountryCodeDropDown(); - // image selector launcher imageSelector = registerForActivityResult(new ActivityResultContracts.GetContent(), uri -> { @@ -201,32 +114,8 @@ public class CreateContactFragment extends Fragment { } }); - } - - private void loadCountryCodeDropDown() { - - ArrayList countryCodeList = new ArrayList<>(); - - try { - - String countryCodeStr = readCountryCodes(requireContext()); - JSONArray jsonArray = new JSONArray(countryCodeStr); - - for (int i = 0; i < jsonArray.length(); i++) { - - JSONObject code = jsonArray.getJSONObject(i); - - countryCodeList.add(code.getString("dial_code")); - - } - - } catch (Exception e) { - - // if cannot load all country codes showing only india's dial code - countryCodeList.add("+91"); - - Log.e(TAG, "loadCountryCodeDropDown: ", e); - } + // country code loading + countryCodeList = contactViewModel.loadCountryCodeDropDown(requireContext()); binding.countryCodes.setLifecycleOwner(this); @@ -238,39 +127,99 @@ public class CreateContactFragment extends Fragment { binding.countryCodes.setIsFocusable(true); + loadRemoteContactList(); + } - public String readCountryCodes(Context context) throws IOException { - StringBuilder returnString = new StringBuilder(); + private void clickEvents() { - InputStream fIn = context.getResources().openRawResource(R.raw.country_code); - InputStreamReader isr = new InputStreamReader(fIn); - BufferedReader input = new BufferedReader(isr); + binding.backBtn.setOnClickListener(v -> Navigation.findNavController(v).popBackStack()); - String line = ""; + binding.nextBtn.setOnClickListener(v -> { - while ((line = input.readLine()) != null) { - returnString.append(line); + if (to_edit){ + // editing existing contact + contactViewModel.showSaveEditDecision(requireContext()); + }else { + // saving new contact + Navigation.findNavController(v).popBackStack(); + } + + }); + + binding.image.setOnClickListener(v -> imageSelector.launch("image/*")); + + } + + @Override + public void gotoAddFragment(BottomSheetDialog bsd) { + new Handler().postDelayed(() -> { + if (bsd != null) bsd.dismiss(); + Navigation.findNavController(binding.getRoot()) + .navigate(R.id.action_createContactFragment_to_addContactFragment); + + }, 3000); + } + + @Override + public void onCheckChange(boolean state) { + binding.sosCheck.setChecked(state); + } + + // remote call back fetching callBack + @Override + public void onResponse(List contactList) { + Log.d(TAG, "onResponse: " + contactList); + if (contactList.size() == 0){ + // there are no contacts in remote database + // thus, this contact has to be a caregiver + binding.relationship.setText(getString(R.string.caregiver)); + binding.relationship.setEnabled(false); + + binding.caregiverCheck.setChecked(true); + binding.caregiverCheck.setEnabled(false); } - try { - isr.close(); + progressDialog.dismiss(); + } - if (fIn != null) fIn.close(); + @Override + public void onFailure(Throwable t, String message, int error_code) { + Log.e(TAG, "onFailure: message : " + message + "\n", t); - input.close(); + progressDialog.dismiss(); + Navigation.findNavController(binding.getRoot()).popBackStack(); + Toast.makeText(requireContext(), "Couldn't load contact", Toast.LENGTH_SHORT).show(); + } - } catch (Exception e) { - Log.e(TAG, "readCountryCodes: ", e); - } + // create contact callback - return returnString.toString(); + @Override + public void onContactCreated(Contact contact) { + + } + + @Override + public void onContactCreateFailed(Throwable t, String message, int error_code) { + + } + + // loading remote contact list to know whether this is user's first contact + private void loadRemoteContactList() { + + progressDialog.setTitle("Please wait"); + progressDialog.setMessage("Loading contact details"); + progressDialog.setCancelable(false); + progressDialog.show(); + + String token = "Bearer " + AppUtil.getUserToken(requireContext()); + contactViewModel.getRemoteContactList(GET_CONTACT_LIST, this, token); } private void setDetails(Contact contact) { - binding.name.setText(contact.name); - binding.phoneNumber.setText(contact.phoneNumber); - binding.email.setText(contact.email); + binding.name.setText(contact.first_name); + binding.phoneNumber.setText(contact.phone_number); + binding.email.setText(contact.email_address); binding.relationship.setText(contact.relationship); } diff --git a/app/src/main/java/com/ssb/simplitend/welcome/fragments/contacts/mvvm/AddContactAdapter.java b/app/src/main/java/com/ssb/simplitend/welcome/fragments/contacts/mvvm/AddContactAdapter.java index 1858ece..d77a63e 100644 --- a/app/src/main/java/com/ssb/simplitend/welcome/fragments/contacts/mvvm/AddContactAdapter.java +++ b/app/src/main/java/com/ssb/simplitend/welcome/fragments/contacts/mvvm/AddContactAdapter.java @@ -1,6 +1,5 @@ package com.ssb.simplitend.welcome.fragments.contacts.mvvm; -import static com.ssb.simplitend.welcome.fragments.contacts.CreateContactFragment.CONTACT_KEY; import static com.ssb.simplitend.welcome.fragments.contacts.CreateContactFragment.TO_EDIT_KEY; import android.app.AlertDialog; diff --git a/app/src/main/java/com/ssb/simplitend/welcome/fragments/contacts/mvvm/Contact.java b/app/src/main/java/com/ssb/simplitend/welcome/fragments/contacts/mvvm/Contact.java index 452800c..be8e3da 100644 --- a/app/src/main/java/com/ssb/simplitend/welcome/fragments/contacts/mvvm/Contact.java +++ b/app/src/main/java/com/ssb/simplitend/welcome/fragments/contacts/mvvm/Contact.java @@ -5,17 +5,21 @@ import java.util.Objects; public class Contact implements Serializable { - public String name, imageUri, phoneNumber, relationship, email; + public String first_name, imageUri, phone_number, relationship, email_address; + + public String is_sos, updated_at, created_at; + + public long id; public Contact(){} public Contact(String name){ - this.name = name; + this.first_name = first_name; } - public Contact(String name, String phoneNumber){ - this.name = name; - this.phoneNumber = phoneNumber; + public Contact(String first_name, String phoneNumber){ + this.first_name= first_name; + this.phone_number = phoneNumber; } @Override @@ -23,22 +27,22 @@ public class Contact implements Serializable { if (this == o) return true; if (o == null || getClass() != o.getClass()) return false; Contact contact = (Contact) o; - return name.equals(contact.name) && Objects.equals(imageUri, contact.imageUri) && phoneNumber.equals(contact.phoneNumber) && Objects.equals(relationship, contact.relationship) && Objects.equals(email, contact.email); + return first_name.equals(contact.first_name) && Objects.equals(imageUri, contact.imageUri) && phone_number.equals(contact.phone_number) && Objects.equals(relationship, contact.relationship) && Objects.equals(email_address, contact.email_address); } @Override public int hashCode() { - return Objects.hash(name, imageUri, phoneNumber, relationship, email); + return Objects.hash(first_name, imageUri, phone_number, relationship, email_address); } @Override public String toString() { return "Contact{" + - "name='" + name + '\'' + + "first_name='" + first_name + '\'' + ", imageUri='" + imageUri + '\'' + - ", phoneNumber='" + phoneNumber + '\'' + + ", phone_number='" + phone_number + '\'' + ", relationship='" + relationship + '\'' + - ", email='" + email + '\'' + + ", email_address='" + email_address + '\'' + '}'; } } diff --git a/app/src/main/java/com/ssb/simplitend/welcome/fragments/contacts/mvvm/ContactViewModel.java b/app/src/main/java/com/ssb/simplitend/welcome/fragments/contacts/mvvm/ContactViewModel.java index 29840c7..0dd90d5 100644 --- a/app/src/main/java/com/ssb/simplitend/welcome/fragments/contacts/mvvm/ContactViewModel.java +++ b/app/src/main/java/com/ssb/simplitend/welcome/fragments/contacts/mvvm/ContactViewModel.java @@ -2,18 +2,42 @@ package com.ssb.simplitend.welcome.fragments.contacts.mvvm; import android.app.Application; import android.content.Context; +import android.util.Log; +import android.view.LayoutInflater; +import androidx.annotation.NonNull; import androidx.lifecycle.AndroidViewModel; +import com.bumptech.glide.Glide; +import com.google.android.material.bottomsheet.BottomSheetDialog; +import com.ssb.simplitend.R; +import com.ssb.simplitend.databinding.DecisionBottomsheetBinding; +import com.ssb.simplitend.databinding.DoneBottomsheetBinding; +import com.ssb.simplitend.welcome.mvvm.WelcomeContracts; + +import org.json.JSONArray; +import org.json.JSONObject; + +import java.io.BufferedReader; +import java.io.IOException; +import java.io.InputStream; +import java.io.InputStreamReader; import java.util.ArrayList; +import java.util.Map; public class ContactViewModel extends AndroidViewModel { + private static final String TAG = "ContactViewModel"; + private final UserContactRepository contactRepository; + private GotoAddContactInterface gotoAddContactInterface; + + private SOSCheckInterface sosCheckInterface; + public ContactViewModel(Application application){ super(application); - this.contactRepository = new UserContactRepository(); + this.contactRepository = UserContactRepository.getContactRepository(); } public ArrayList getContactList(Context context) { @@ -23,4 +47,162 @@ public class ContactViewModel extends AndroidViewModel { public UserContactRepository getContactRepository() { return contactRepository; } + + public void setGotoAddContactInterface(GotoAddContactInterface gotoAddContactInterface) { + this.gotoAddContactInterface = gotoAddContactInterface; + } + + public void setSosCheckInterface(SOSCheckInterface sosCheckInterface) { + this.sosCheckInterface = sosCheckInterface; + } + + public void getRemoteContactList(String URL, WelcomeContracts.ContactListContracts contactListContracts, String token){ + contactRepository.getRemoteContactList(URL, contactListContracts, token); + } + + public void createContact(@NonNull String URL, + @NonNull Map body, + @NonNull WelcomeContracts.CreateContactInterface createContactInterface, + @NonNull String token){ + contactRepository.createContact(URL, body, createContactInterface, token); + } + + public void showSaveEditDecision(Context context) { + + DecisionBottomsheetBinding binding = DecisionBottomsheetBinding.inflate(LayoutInflater.from(context)); + + BottomSheetDialog bsd = new BottomSheetDialog(context, R.style.BottomSheetDialog); + bsd.setContentView(binding.getRoot()); + + binding.text.setText(context.getString(R.string.make_changes)); + + binding.positiveBtn.setText(context.getString(R.string.yes)); + binding.negativeBtn.setText(context.getString(R.string.no)); + + binding.negativeBtn.setOnClickListener(v -> bsd.dismiss()); + + binding.positiveBtn.setOnClickListener(v -> { + bsd.dismiss(); + showDoneBottomSheet(context); + }); + + bsd.show(); + + } + + private void showDoneBottomSheet(Context context) { + DoneBottomsheetBinding binding = DoneBottomsheetBinding.inflate(LayoutInflater.from(context)); + + BottomSheetDialog bsd = new BottomSheetDialog(context, R.style.BottomSheetDialog); + bsd.setContentView(binding.getRoot()); + bsd.setCancelable(false); + + binding.text.setText(context.getString(R.string.changes_successful)); + + Glide.with(context) + .asGif() + .load(R.raw.done_anim_primary) + .into(binding.doneAnim); + + bsd.show(); + + gotoAddContactFragment(3000, bsd); + } + + private void gotoAddContactFragment(long inMsm, BottomSheetDialog bsd){ + if (gotoAddContactInterface != null) gotoAddContactInterface.gotoAddFragment(bsd); + } + + public void showSOSDecision(Context context) { + + DecisionBottomsheetBinding binding = DecisionBottomsheetBinding.inflate(LayoutInflater.from(context)); + + BottomSheetDialog bsd = new BottomSheetDialog(context, R.style.BottomSheetDialog); + bsd.setContentView(binding.getRoot()); + bsd.setCancelable(false); + + binding.text.setText(context.getString(R.string.make_sos)); + + binding.positiveBtn.setText(context.getString(R.string.yes)); + binding.negativeBtn.setText(context.getString(R.string.no)); + + binding.negativeBtn.setOnClickListener(v -> { + bsd.dismiss(); + if (sosCheckInterface != null) sosCheckInterface.onCheckChange(false); + }); + + binding.positiveBtn.setOnClickListener(v -> { + bsd.dismiss(); + if (sosCheckInterface != null) sosCheckInterface.onCheckChange(true); + }); + + bsd.show(); + + } + + public ArrayList loadCountryCodeDropDown(Context context) { + + ArrayList countryCodeList = new ArrayList<>(); + + try { + + String countryCodeStr = readCountryCodes(context); + JSONArray jsonArray = new JSONArray(countryCodeStr); + + for (int i = 0; i < jsonArray.length(); i++) { + + JSONObject code = jsonArray.getJSONObject(i); + + countryCodeList.add(code.getString("dial_code")); + + } + + } catch (Exception e) { + + // if cannot load all country codes showing only india's dial code + countryCodeList.add("+91"); + + Log.e(TAG, "loadCountryCodeDropDown: ", e); + } + + return countryCodeList; + } + + public String readCountryCodes(Context context) throws IOException { + StringBuilder returnString = new StringBuilder(); + + InputStream fIn = context.getResources().openRawResource(R.raw.country_code); + InputStreamReader isr = new InputStreamReader(fIn); + BufferedReader input = new BufferedReader(isr); + + String line = ""; + + while ((line = input.readLine()) != null) { + returnString.append(line); + } + + try { + isr.close(); + + if (fIn != null) fIn.close(); + + input.close(); + + } catch (Exception e) { + Log.e(TAG, "readCountryCodes: ", e); + } + + return returnString.toString(); + } + + + // interfaces + public interface GotoAddContactInterface{ + void gotoAddFragment(BottomSheetDialog bsd); + } + + public interface SOSCheckInterface{ + void onCheckChange(boolean state); + } + } diff --git a/app/src/main/java/com/ssb/simplitend/welcome/fragments/contacts/mvvm/UserContactRepository.java b/app/src/main/java/com/ssb/simplitend/welcome/fragments/contacts/mvvm/UserContactRepository.java index c5bb1fb..bf4275a 100644 --- a/app/src/main/java/com/ssb/simplitend/welcome/fragments/contacts/mvvm/UserContactRepository.java +++ b/app/src/main/java/com/ssb/simplitend/welcome/fragments/contacts/mvvm/UserContactRepository.java @@ -2,23 +2,31 @@ package com.ssb.simplitend.welcome.fragments.contacts.mvvm; import android.content.ContentResolver; import android.content.Context; -import android.database.ContentObserver; import android.database.Cursor; -import android.net.Uri; import android.provider.ContactsContract; import android.util.Log; import androidx.annotation.NonNull; -import androidx.annotation.Nullable; -import com.ssb.simplitend.welcome.fragments.contacts.mvvm.Contact; +import com.ssb.simplitend.apputils.RetrofitHelper; +import com.ssb.simplitend.welcome.fragments.contacts.mvvm.models.ContactListResponse; +import com.ssb.simplitend.welcome.mvvm.APIService; +import com.ssb.simplitend.welcome.mvvm.WelcomeContracts; +import com.ssb.simplitend.welcome.mvvm.models.CallResponse; import java.util.ArrayList; -import java.util.Collection; import java.util.HashSet; +import java.util.List; +import java.util.Map; + +import retrofit2.Call; +import retrofit2.Callback; +import retrofit2.Response; public class UserContactRepository { + private static final String TAG = "UserContactRepository"; + private static final String[] PROJECTION = new String[]{ ContactsContract.CommonDataKinds.Phone.CONTACT_ID, ContactsContract.Contacts.DISPLAY_NAME, @@ -26,7 +34,71 @@ public class UserContactRepository { ContactsContract.CommonDataKinds.Phone.PHOTO_URI }; - public UserContactRepository(){} + private static UserContactRepository contactRepository; + private final APIService apiService; + + private UserContactRepository(){ + apiService = RetrofitHelper.getRetrofit().create(APIService.class); + } + + public static synchronized UserContactRepository getContactRepository(){ + if (contactRepository == null){ + contactRepository = new UserContactRepository(); + } + + return contactRepository; + } + + public void getRemoteContactList(String URL, WelcomeContracts.ContactListContracts contactListContracts, String token){ + + apiService.getContactList(URL, token).enqueue(new Callback>>() { + @Override + public void onResponse(Call>> call, Response>> response) { + if (response.isSuccessful() && response.body() != null && response.body().result != null){ + contactListContracts.onResponse(response.body().result); + }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{ + 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); + } + } + + @Override + public void onFailure(Call>> call, Throwable t) { + Log.e(TAG, "onFailure: ", t); + contactListContracts.onFailure(t, t.getMessage(), 1); + } + }); + + } + + public void createContact(@NonNull String URL, + @NonNull Map body, + @NonNull WelcomeContracts.CreateContactInterface createContactInterface, + @NonNull String token){ + apiService.createContact(URL, body, token).enqueue(new Callback>() { + @Override + public void onResponse(Call> call, Response> response) { + if (response.isSuccessful() && response.body() != null && response.body().result != null){ + createContactInterface.onContactCreated(response.body().result); + }else if (response.body() != null && response.body().result != null){ + Log.e(TAG, "onResponse: contact create " + response); + createContactInterface.onContactCreateFailed(new Exception(response.toString()), response.body().message, response.code()); + }else{ + Log.e(TAG, "onResponse: no success response and also response body is 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); + } + } + + @Override + public void onFailure(Call> call, Throwable t) { + Log.e(TAG, "onFailure: ", t); + createContactInterface.onContactCreateFailed(t, t.getMessage(), 1); + } + }); + } public ArrayList getContactList(Context context) { final ArrayList contactList = new ArrayList<>(); diff --git a/app/src/main/java/com/ssb/simplitend/welcome/fragments/contacts/mvvm/models/ContactListResponse.java b/app/src/main/java/com/ssb/simplitend/welcome/fragments/contacts/mvvm/models/ContactListResponse.java new file mode 100644 index 0000000..2f1637e --- /dev/null +++ b/app/src/main/java/com/ssb/simplitend/welcome/fragments/contacts/mvvm/models/ContactListResponse.java @@ -0,0 +1,76 @@ +package com.ssb.simplitend.welcome.fragments.contacts.mvvm.models; + +import androidx.annotation.NonNull; + +public class ContactListResponse{ + public int id; + public String patient_xid; + public String contact_xid; + public String is_sos_contact; + public ContactData contact_data; + + public ContactListResponse() { + } + + @NonNull + @Override + public String toString() { + return "ContactListResponse{" + + "id=" + id + + ", patient_xid='" + patient_xid + '\'' + + ", contact_xid='" + contact_xid + '\'' + + ", is_sos_contact='" + is_sos_contact + '\'' + + ", contact_data=" + contact_data + + '}'; + } +} + +class CareGiverData{ + public int contact_xid; + public String id; + public String principalXid; + + public CareGiverData() { + } + + @NonNull + @Override + public String toString() { + return "CareGiverData{" + + "contact_xid=" + contact_xid + + ", id='" + id + '\'' + + ", principalXid='" + principalXid + '\'' + + '}'; + } +} + +class ContactData{ + public int id; + public String first_name; + public String phone_number; + public String email_address; + public String relationship; + public String is_sos; + public String contact_photo; + public CareGiverData care_giver_data; + + public ContactData() { + } + + @NonNull + @Override + public String toString() { + return "ContactData{" + + "id=" + id + + ", first_name='" + first_name + '\'' + + ", phone_number='" + phone_number + '\'' + + ", email_address='" + email_address + '\'' + + ", relationship='" + relationship + '\'' + + ", is_sos='" + is_sos + '\'' + + ", contact_photo='" + contact_photo + '\'' + + ", care_giver_data=" + care_giver_data + + '}'; + } +} + + diff --git a/app/src/main/java/com/ssb/simplitend/welcome/fragments/register/CreatePinFragment.java b/app/src/main/java/com/ssb/simplitend/welcome/fragments/register/CreatePinFragment.java index e0e15d4..e045ada 100644 --- a/app/src/main/java/com/ssb/simplitend/welcome/fragments/register/CreatePinFragment.java +++ b/app/src/main/java/com/ssb/simplitend/welcome/fragments/register/CreatePinFragment.java @@ -1,6 +1,8 @@ package com.ssb.simplitend.welcome.fragments.register; +import android.app.ProgressDialog; import android.os.Bundle; +import android.util.Log; import android.view.LayoutInflater; import android.view.View; import android.view.ViewGroup; @@ -8,17 +10,31 @@ import android.view.ViewGroup; import androidx.annotation.NonNull; import androidx.annotation.Nullable; import androidx.fragment.app.Fragment; +import androidx.lifecycle.ViewModelProvider; import androidx.navigation.Navigation; import com.ssb.simplitend.R; +import com.ssb.simplitend.apputils.AppUtil; +import com.ssb.simplitend.apputils.RetrofitHelper; import com.ssb.simplitend.databinding.CreatePinFragmentBinding; +import com.ssb.simplitend.welcome.mvvm.WelcomeContracts; +import com.ssb.simplitend.welcome.mvvm.WelcomeViewModel; +import com.ssb.simplitend.welcome.mvvm.models.PatientData; +import com.ssb.simplitend.welcome.mvvm.models.PatientResult; -public class CreatePinFragment extends Fragment { +public class CreatePinFragment extends Fragment implements WelcomeContracts.RegisterPatientContract { + + private static final String TAG = "CreatePinFragment"; // view binding protected CreatePinFragmentBinding binding; - public CreatePinFragment(){ + // view model (common for this activity) + private WelcomeViewModel welcomeViewModel; + + private ProgressDialog progressDialog; + + public CreatePinFragment() { // required empty const. } @@ -27,18 +43,96 @@ public class CreatePinFragment extends Fragment { public View onCreateView(@NonNull LayoutInflater inflater, @Nullable ViewGroup container, @Nullable Bundle savedInstanceState) { binding = CreatePinFragmentBinding.inflate(inflater, container, false); + welcomeViewModel = new ViewModelProvider(requireActivity()).get(WelcomeViewModel.class); + + initViews(); + clickEvents(); return binding.getRoot(); } + private void initViews() { + loadPinsSavedState(); + + progressDialog = new ProgressDialog(requireContext()); + } + + private void loadPinsSavedState() { + PatientData patientData = welcomeViewModel.getPatientData(); + + binding.pin.setText(patientData.pin_code); + binding.confirmPin.setText(patientData.c_pin_code); + + } + private void clickEvents() { binding.backBtn.setOnClickListener(v -> Navigation.findNavController(v).popBackStack()); binding.setPin.setOnClickListener(v -> - Navigation.findNavController(v).navigate(R.id.action_createPinFragment_to_thankYouFragment) + { + if (allOkay() && binding.pin.getText() != null && binding.confirmPin.getText() != null) { + + AppUtil.closeKeyboard(requireActivity()); + + PatientData patientData = welcomeViewModel.getPatientData(); + + patientData.pin_code = binding.pin.getText().toString(); + patientData.c_pin_code = binding.confirmPin.getText().toString(); + + progressDialog.setTitle("Please wait"); + progressDialog.setMessage("while we sign you up"); + progressDialog.setCancelable(false); + + progressDialog.show(); + + welcomeViewModel.registerPatient(RetrofitHelper.REGISTER_PATIENT, this); + } + } ); } + + private boolean allOkay() { + boolean allOkay = true; + + if (binding.pin.getText() == null || binding.pin.getText().toString().length() != 4) { + allOkay = false; + binding.pin.setError("Invalid pin"); + } else if (binding.confirmPin.getText() == null || + !binding.confirmPin.getText().toString().equals(binding.pin.getText().toString())) { + allOkay = false; + binding.confirmPin.setError("Pin doesn't match"); + } + + return allOkay; + } + + @Override + public void onResponse(PatientResult patientResult, String token) { + Log.d(TAG, "onResponse: " + patientResult); + Log.d(TAG, "onResponse: Token " + token); + + progressDialog.setMessage("Almost there..."); + + AppUtil.saveToken(token, requireContext()); + + progressDialog.dismiss(); + + Navigation.findNavController(binding.getRoot()).navigate(R.id.action_createPinFragment_to_thankYouFragment); + } + + @Override + public void onFailure(Throwable t, @NonNull String message, int error_code) { + Log.d(TAG, "onFailure: " + t); + + progressDialog.dismiss(); + + AppUtil.showAlert(requireContext(), + "Something went wrong", + message, "OK", (dialog, which) -> { + dialog.dismiss(); + }, null, null); + } } diff --git a/app/src/main/java/com/ssb/simplitend/welcome/fragments/register/LocationFragment.java b/app/src/main/java/com/ssb/simplitend/welcome/fragments/register/LocationFragment.java index f856e4f..3ed6de9 100644 --- a/app/src/main/java/com/ssb/simplitend/welcome/fragments/register/LocationFragment.java +++ b/app/src/main/java/com/ssb/simplitend/welcome/fragments/register/LocationFragment.java @@ -1,20 +1,53 @@ package com.ssb.simplitend.welcome.fragments.register; +import static android.content.Context.LOCATION_SERVICE; + +import android.Manifest; +import android.annotation.SuppressLint; +import android.app.Activity; import android.content.Context; +import android.content.Intent; +import android.location.Location; +import android.location.LocationManager; import android.os.Bundle; +import android.provider.Settings; import android.util.Log; import android.view.LayoutInflater; import android.view.View; import android.view.ViewGroup; +import android.widget.Toast; +import androidx.activity.result.ActivityResultLauncher; +import androidx.activity.result.contract.ActivityResultContracts; import androidx.annotation.NonNull; import androidx.annotation.Nullable; import androidx.fragment.app.Fragment; +import androidx.lifecycle.ViewModelProvider; import androidx.navigation.Navigation; +import com.google.android.gms.location.FusedLocationProviderClient; +import com.google.android.gms.location.LocationListener; +import com.google.android.gms.location.LocationRequest; +import com.google.android.gms.location.LocationServices; +import com.google.android.gms.maps.CameraUpdateFactory; +import com.google.android.gms.maps.GoogleMap; +import com.google.android.gms.maps.GoogleMapOptions; +import com.google.android.gms.maps.OnMapReadyCallback; +import com.google.android.gms.maps.SupportMapFragment; +import com.google.android.gms.maps.model.CameraPosition; +import com.google.android.gms.maps.model.LatLng; +import com.google.android.gms.maps.model.Marker; +import com.google.android.gms.maps.model.MarkerOptions; +import com.google.android.libraries.places.api.Places; +import com.google.android.libraries.places.api.model.Place; +import com.google.android.libraries.places.widget.Autocomplete; +import com.google.android.libraries.places.widget.model.AutocompleteActivityMode; import com.skydoves.powerspinner.OnSpinnerItemSelectedListener; import com.ssb.simplitend.R; +import com.ssb.simplitend.apputils.AppUtil; import com.ssb.simplitend.databinding.LocationFragmentBinding; +import com.ssb.simplitend.welcome.mvvm.WelcomeViewModel; +import com.ssb.simplitend.welcome.mvvm.models.PatientData; import org.json.JSONArray; import org.json.JSONObject; @@ -24,10 +57,12 @@ import java.io.IOException; import java.io.InputStream; import java.io.InputStreamReader; import java.util.ArrayList; +import java.util.Arrays; import java.util.HashMap; -import java.util.HashSet; +import java.util.List; -public class LocationFragment extends Fragment { +public class LocationFragment extends Fragment implements OnMapReadyCallback, + GoogleMap.OnMapClickListener, LocationListener { private static final String TAG = "LocationFragment"; @@ -35,10 +70,28 @@ public class LocationFragment extends Fragment { protected LocationFragmentBinding binding; // country list - ArrayList countryList; + private ArrayList countryList; // Map for country and their states - HashMap> country_N_states_map; + private HashMap> country_N_states_map; + + // user location selection marker + private Marker marker = null; + + // Google map object + private GoogleMap googleMap; + + // user selected current location + private LatLng currentLocation; + + // Fused location object + private FusedLocationProviderClient fusedLocationProviderClient; + private LocationRequest locationRequest; + + private ActivityResultLauncher startAutocompleteMapSearch; + + // viewmodel + private WelcomeViewModel viewModel; public LocationFragment(){ // required empty const. @@ -49,6 +102,10 @@ public class LocationFragment extends Fragment { public View onCreateView(@NonNull LayoutInflater inflater, @Nullable ViewGroup container, @Nullable Bundle savedInstanceState) { binding = LocationFragmentBinding.inflate(inflater, container, false); + viewModel = new ViewModelProvider(requireActivity()).get(WelcomeViewModel.class); + + Log.d(TAG, "onCreateView: " + viewModel.getPatientData()); + initViews(); clickEvents(); @@ -56,10 +113,309 @@ public class LocationFragment extends Fragment { return binding.getRoot(); } + @Override + public void onDestroyView() { + super.onDestroyView(); + Log.d(TAG, "location updates removed"); + fusedLocationProviderClient.removeLocationUpdates(this); + } + + @SuppressLint("ClickableViewAccessibility") private void initViews() { loadCountriesAndStates(); + try { + loadPatientAddressSavedState(); + } catch (Exception e) { + Log.e(TAG, "initViews: ", e); + } + + // requesting scroll view to stop listening to gestures for mapview + binding.transImg.setOnTouchListener((v, event) -> { + binding.scrollView.requestDisallowInterceptTouchEvent(true); + return false; + }); + + fusedLocationProviderClient = LocationServices.getFusedLocationProviderClient(requireContext()); + locationRequest = new LocationRequest.Builder(LocationRequest.PRIORITY_HIGH_ACCURACY, 5000) + .build(); + + registerMapSearchResultLauncher(); + + getLocationPermission(); + + // default current location // Mumbai marine drive + currentLocation = new LatLng(19.026452, 72.838845); + + // initializing maps + GoogleMapOptions gmo = new GoogleMapOptions(); + gmo.mapType(GoogleMap.MAP_TYPE_NORMAL) + .compassEnabled(true) + .useViewLifecycleInFragment(true); + + SupportMapFragment mapFragment = SupportMapFragment.newInstance(gmo); + + getParentFragmentManager().beginTransaction() + .add(R.id.map_frag_cont, mapFragment) + .commit(); + + mapFragment.getMapAsync(this); + + } + + // load data from watcher + private void loadPatientAddressSavedState() throws Exception { + PatientData patientData = viewModel.getPatientData(); + + if (patientData.country != null){ + binding.countrySpinner.selectItemByIndex(countryList.indexOf(patientData.country)); + + if (patientData.state != null){ + binding.stateSpinner.selectItemByIndex(country_N_states_map.get(patientData.country).indexOf(patientData.state)); + } + } + + if (patientData.lat != null && patientData.lng != null){ + double lat = Double.parseDouble(patientData.lat); + double lng = Double.parseDouble(patientData.lng); + + currentLocation = new LatLng(lat, lng); + } + + if (patientData.address_line1 != null){ + binding.street.setText(patientData.address_line1); + } + + if (patientData.city != null){ + binding.town.setText(patientData.city); + } + + if (patientData.post_code != null){ + binding.zipCode.setText(patientData.post_code); + } + } + + private void registerMapSearchResultLauncher() { + + // initializing places + + // Initialize the SDK + Places.initialize(requireContext(), getString(R.string.GOOGLE_MAPS_API_KEY)); + + startAutocompleteMapSearch = registerForActivityResult( + new ActivityResultContracts.StartActivityForResult(), + result -> { + if (result.getResultCode() == Activity.RESULT_OK) { + Intent intent = result.getData(); + if (intent != null) { + Place place = Autocomplete.getPlaceFromIntent(intent); + Log.d(TAG, "Place: selected" + place.getLatLng()); + + if (place.getLatLng() == null) return; + + // animating camera to selected location + CameraPosition camPos = new CameraPosition.Builder() + .target(place.getLatLng()) + .zoom(15) + .build(); + + googleMap.animateCamera(CameraUpdateFactory.newCameraPosition(camPos)); + + // updating current location and adding a land mark + addMarker(place.getLatLng(), place.getName()); + + } + } else if (result.getResultCode() == Activity.RESULT_CANCELED) { + // The user canceled the operation. + Log.d(TAG, "User canceled autocomplete"); + } + }); + + + } + + private void clickEvents() { + + binding.backBtn.setOnClickListener(v -> Navigation.findNavController(v).popBackStack()); + + binding.submit.setOnClickListener(v -> + { + if (allOkay()){ + + PatientData patientData = viewModel.getPatientData(); + + patientData.address_line1 = binding.street.getText().toString(); + patientData.city = binding.town.getText().toString(); + patientData.post_code = binding.zipCode.getText().toString(); + + patientData.country = countryList.get(binding.countrySpinner.getSelectedIndex()); + patientData.state = country_N_states_map.get(patientData.country).get(binding.countrySpinner.getSelectedIndex()); + + patientData.lat = String.valueOf(currentLocation.latitude); + patientData.lng = String.valueOf(currentLocation.longitude); + + Navigation.findNavController(v).navigate(R.id.action_locationFragment_to_createPinFragment); + } + } + ); + + binding.search.setOnClickListener(v -> { + + List fields = Arrays.asList(Place.Field.ID, Place.Field.NAME, Place.Field.LAT_LNG); + + Intent intent = new Autocomplete.IntentBuilder(AutocompleteActivityMode.OVERLAY, fields) + .build(requireContext()); + + startAutocompleteMapSearch.launch(intent); + }); + + } + + private boolean allOkay() { + boolean allOkay = true; + + if (binding.street.getText().toString().trim().isEmpty()){ + allOkay = false; + binding.street.setError("Required"); + } + + if (binding.town.getText().toString().trim().isEmpty()){ + allOkay = false; + binding.town.setError("Required"); + } + + if (binding.zipCode.getText().toString().trim().isEmpty()){ + allOkay = false; + binding.zipCode.setError("Required"); + } + + if (binding.countrySpinner.getSelectedIndex() == -1){ + allOkay = false; + binding.countrySpinner.setError("Required"); + } + + if (binding.stateSpinner.getSelectedIndex() == -1){ + allOkay = false; + binding.stateSpinner.setError("Required"); + } + + if (currentLocation == null && allOkay){ + allOkay = false; + Toast.makeText(requireContext(), "Please click on map to select a location.", Toast.LENGTH_SHORT).show(); + } + + return allOkay; + } + + private void getLocationPermission() { + // launching request to location permissions + registerForActivityResult(new ActivityResultContracts + .RequestMultiplePermissions(), result -> { + + Boolean fineLocationGranted; + + if (result.containsKey(Manifest.permission.ACCESS_FINE_LOCATION)){ + fineLocationGranted = result.get(Manifest.permission.ACCESS_FINE_LOCATION); + }else{ + fineLocationGranted = false; + } + + Boolean coarseLocationGranted; + + if (result.containsKey(Manifest.permission.ACCESS_COARSE_LOCATION)){ + coarseLocationGranted = result.get(Manifest.permission.ACCESS_COARSE_LOCATION); + }else{ + coarseLocationGranted = false; + } + + if ((fineLocationGranted != null && fineLocationGranted) || (coarseLocationGranted != null && coarseLocationGranted)) { + // one of the location access granted. + Toast.makeText(requireContext(), "Fetching your current location", Toast.LENGTH_SHORT).show(); + requestLocations(); + } + + } + ).launch(new String[]{Manifest.permission.ACCESS_COARSE_LOCATION, Manifest.permission.ACCESS_FINE_LOCATION}); + } + + @Override + public void onLocationChanged(@NonNull Location location) { + Log.d(TAG, "onLocationChanged: " + location); + this.currentLocation = new LatLng(location.getLatitude(), location.getLongitude()); + fusedLocationProviderClient.removeLocationUpdates(this); + Log.d(TAG, "onLocationChanged: location updates removed"); + + CameraPosition default_map_pos = new CameraPosition.Builder() + .target(currentLocation) + .zoom(15) + .build(); + + googleMap.animateCamera(CameraUpdateFactory.newCameraPosition(default_map_pos)); + + addMarker(currentLocation, "Current location"); + + } + + @Override + public void onMapReady(@NonNull GoogleMap googleMap) { + this.googleMap = googleMap; + CameraPosition default_map_pos = new CameraPosition.Builder() + .target(currentLocation) + .zoom(15) + .build(); + + googleMap.animateCamera(CameraUpdateFactory.newCameraPosition(default_map_pos)); + + googleMap.setOnMapClickListener(this); + + if (currentLocation != null){ + addMarker(currentLocation, "Selected location"); + } + } + + @Override + public void onMapClick(@NonNull LatLng latLng) { + addMarker(latLng, "Selected location"); + } + + private void addMarker(LatLng latLng, String title){ + // updating current location + this.currentLocation = latLng; + if (marker != null && marker.isVisible()) marker.remove(); + marker = null; + marker = googleMap.addMarker(new MarkerOptions() + .position(latLng).draggable(false) + .title(title)); + } + + private void requestLocations(){ + if (!isLocationProviderEnabled(requireContext())){ + AppUtil.showAlert(requireContext(), + getString(R.string.GPS_ENABLE_REQUIRED), + getString(R.string.GPS_ENABLE_MESSAGE), + getString(R.string.SETTINGS), + (dialog, which) -> { + // Settings button click callback + // Sending user to turn location on + + Intent intent = new Intent(); + intent.setAction(Settings.ACTION_LOCATION_SOURCE_SETTINGS); + + startActivity(intent); + }, + getString(R.string.NOT_NOW), + (dialog, which) -> dialog.dismiss() + ); + } + + fusedLocationProviderClient.requestLocationUpdates(locationRequest, this, null); + } + + public boolean isLocationProviderEnabled(Context context) { + LocationManager locationManager = (LocationManager) context.getSystemService(LOCATION_SERVICE); + + return locationManager.isProviderEnabled(LocationManager.NETWORK_PROVIDER); } // loads all countries and their states into the spinners @@ -112,6 +468,8 @@ public class LocationFragment extends Fragment { binding.countrySpinner.setIsFocusable(true); binding.countrySpinner.setOnSpinnerItemSelectedListener((OnSpinnerItemSelectedListener) (i, s, i1, t1) -> { + + binding.countrySpinner.setError(null); ArrayList stateList; @@ -126,6 +484,10 @@ public class LocationFragment extends Fragment { binding.stateSpinner.clearSelectedItem(); } }); + + binding.stateSpinner.setOnSpinnerItemSelectedListener((OnSpinnerItemSelectedListener) (i, s, i1, t1) -> { + binding.stateSpinner.setError(null); + }); } @@ -155,14 +517,4 @@ public class LocationFragment extends Fragment { return returnString.toString(); } - - private void clickEvents() { - - binding.backBtn.setOnClickListener(v -> Navigation.findNavController(v).popBackStack()); - - binding.submit.setOnClickListener(v -> - Navigation.findNavController(v).navigate(R.id.action_locationFragment_to_createPinFragment) - ); - - } } diff --git a/app/src/main/java/com/ssb/simplitend/welcome/fragments/register/RegisterFragment.java b/app/src/main/java/com/ssb/simplitend/welcome/fragments/register/RegisterFragment.java index 1d846ad..bf39aeb 100644 --- a/app/src/main/java/com/ssb/simplitend/welcome/fragments/register/RegisterFragment.java +++ b/app/src/main/java/com/ssb/simplitend/welcome/fragments/register/RegisterFragment.java @@ -2,23 +2,29 @@ package com.ssb.simplitend.welcome.fragments.register; import android.app.DatePickerDialog; import android.content.Context; +import android.content.Intent; +import android.net.Uri; import android.os.Build; import android.os.Bundle; import android.util.Log; +import android.util.Patterns; import android.view.LayoutInflater; import android.view.View; import android.view.ViewGroup; +import android.widget.Toast; import androidx.annotation.NonNull; import androidx.annotation.Nullable; import androidx.annotation.RequiresApi; import androidx.fragment.app.Fragment; +import androidx.lifecycle.ViewModelProvider; import androidx.navigation.Navigation; -import com.skydoves.powerspinner.OnSpinnerDismissListener; import com.ssb.simplitend.R; import com.ssb.simplitend.apputils.AppUtil; import com.ssb.simplitend.databinding.RegisterFragmentBinding; +import com.ssb.simplitend.welcome.mvvm.WelcomeViewModel; +import com.ssb.simplitend.welcome.mvvm.models.PatientData; import org.json.JSONArray; import org.json.JSONObject; @@ -36,8 +42,14 @@ public class RegisterFragment extends Fragment { private static final String TAG = "RegisterFragment"; + // view binding protected RegisterFragmentBinding binding; + // view model + private WelcomeViewModel viewModel; + + private ArrayList countryCodeList; + public RegisterFragment() { // required empty const. } @@ -47,6 +59,8 @@ public class RegisterFragment extends Fragment { public View onCreateView(@NonNull LayoutInflater inflater, @Nullable ViewGroup container, @Nullable Bundle savedInstanceState) { binding = RegisterFragmentBinding.inflate(inflater, container, false); + viewModel = new ViewModelProvider(requireActivity()).get(WelcomeViewModel.class); + initViews(); clickEvents(); @@ -58,27 +72,110 @@ public class RegisterFragment extends Fragment { loadCountryCodeDropDown(); + loadPatientDataSavedState(); + + } + + private void loadPatientDataSavedState() { + // loading data from view model + PatientData patientData = viewModel.getPatientData(); + + binding.name.setText(patientData.first_name); + binding.dob.setText(patientData.date_of_birth); + + if (patientData.phone_number != null){ + String[] contact = patientData.phone_number.split(" "); + if (contact.length == 2){ + binding.contactNumber.setText(contact[1]); + binding.countryCodes.selectItemByIndex(countryCodeList.indexOf(contact[0])); + } + } + + binding.email.setText(patientData.email); } private void clickEvents() { binding.backBtn.setOnClickListener(v -> Navigation.findNavController(v).popBackStack()); - binding.nextBtn.setOnClickListener(v -> - Navigation.findNavController(v).navigate(R.id.action_registerFragment_to_locationFragment)); + binding.nextBtn.setOnClickListener(v -> { + if (allOkay()){ + PatientData patientData = viewModel.getPatientData(); + + patientData.first_name = patientData.user_name = binding.name.getText().toString(); + patientData.phone_number = countryCodeList.get(binding.countryCodes.getSelectedIndex()) + + " " + binding.contactNumber.getText().toString(); + patientData.date_of_birth = binding.dob.getText().toString(); + patientData.email = binding.email.getText().toString(); + + Navigation.findNavController(v).navigate(R.id.action_registerFragment_to_locationFragment); + } + }); binding.dob.setOnClickListener(v -> { + binding.dob.setError(null); if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.N) { AppUtil.closeKeyboard(requireActivity()); pickDate(); } }); + binding.tncBtn.setOnClickListener(v -> { + Intent intent = new Intent(Intent.ACTION_VIEW); + intent.setData(Uri.parse("https://www.google.com")); + startActivity(intent); + }); + + // static thing for lower android versions + // todo should be removed afterwards + binding.dob.setOnLongClickListener(v -> { + binding.dob.setText("12-12-2001"); + return false; + }); + + } + + private boolean allOkay() { + + boolean allOkay = true; + + if (binding.name.getText().toString().trim().isEmpty()){ + binding.name.setError("Required"); + allOkay = false; + } + + if (binding.dob.getText().toString().trim().isEmpty()){ + binding.dob.setError("Required"); + allOkay = false; + } + + if (binding.contactNumber.getText().toString().trim().isEmpty()){ + binding.contactNumber.setError("Required"); + allOkay = false; + }else if (!Patterns.PHONE.matcher(binding.contactNumber.getText().toString()).matches()){ + binding.contactNumber.setError("Invalid contact"); + allOkay = false; + } + + if (binding.email.getText().toString().trim().isEmpty()){ + binding.email.setError("Required"); + allOkay = false; + }else if (!Patterns.EMAIL_ADDRESS.matcher(binding.email.getText().toString()).matches()){ + binding.email.setError("Invalid email"); + allOkay = false; + } + + if (!binding.tncCheck.isChecked() && allOkay){ + Toast.makeText(requireContext(), "Please check terms and conditions to continue.", Toast.LENGTH_SHORT).show(); + allOkay = false; + } + + return allOkay; } private void loadCountryCodeDropDown() { - ArrayList countryCodeList = new ArrayList<>(); + countryCodeList = new ArrayList<>(); try { diff --git a/app/src/main/java/com/ssb/simplitend/welcome/fragments/register/ThankYouFragment.java b/app/src/main/java/com/ssb/simplitend/welcome/fragments/register/ThankYouFragment.java index e08326c..6b3e401 100644 --- a/app/src/main/java/com/ssb/simplitend/welcome/fragments/register/ThankYouFragment.java +++ b/app/src/main/java/com/ssb/simplitend/welcome/fragments/register/ThankYouFragment.java @@ -44,13 +44,9 @@ public class ThankYouFragment extends Fragment { } private void clickEvents() { - - binding.backBtn.setOnClickListener(v -> Navigation.findNavController(v).popBackStack()); - binding.proceed.setOnClickListener(v -> Navigation.findNavController(v).navigate(R.id.action_thankYouFragment_to_contactListFragment) ); - } } diff --git a/app/src/main/java/com/ssb/simplitend/welcome/mvvm/APIService.java b/app/src/main/java/com/ssb/simplitend/welcome/mvvm/APIService.java new file mode 100644 index 0000000..b0d356d --- /dev/null +++ b/app/src/main/java/com/ssb/simplitend/welcome/mvvm/APIService.java @@ -0,0 +1,29 @@ +package com.ssb.simplitend.welcome.mvvm; + +import com.ssb.simplitend.welcome.fragments.contacts.mvvm.Contact; +import com.ssb.simplitend.welcome.fragments.contacts.mvvm.models.ContactListResponse; +import com.ssb.simplitend.welcome.mvvm.models.CallResponse; +import com.ssb.simplitend.welcome.mvvm.models.PatientResult; + +import java.util.List; +import java.util.Map; + +import retrofit2.Call; +import retrofit2.http.Body; +import retrofit2.http.GET; +import retrofit2.http.Header; +import retrofit2.http.POST; +import retrofit2.http.Url; + +public interface APIService { + + @POST + Call> registerPatient(@Url String URL, @Body Map body); + + @POST + Call> createContact(@Url String URL, @Body Map body, + @Header("Authorization") String token); + + @GET + Call>> getContactList(@Url String URL, @Header("Authorization") String token); +} diff --git a/app/src/main/java/com/ssb/simplitend/welcome/mvvm/WelcomeContracts.java b/app/src/main/java/com/ssb/simplitend/welcome/mvvm/WelcomeContracts.java new file mode 100644 index 0000000..3d2b264 --- /dev/null +++ b/app/src/main/java/com/ssb/simplitend/welcome/mvvm/WelcomeContracts.java @@ -0,0 +1,34 @@ +package com.ssb.simplitend.welcome.mvvm; + +import com.ssb.simplitend.welcome.fragments.contacts.mvvm.Contact; +import com.ssb.simplitend.welcome.fragments.contacts.mvvm.models.ContactListResponse; +import com.ssb.simplitend.welcome.mvvm.models.PatientResult; + +import java.util.List; + +public interface WelcomeContracts { + + interface RegisterPatientContract{ + + void onResponse(PatientResult patientResult, String token); + + void onFailure(Throwable t, String message, int error_code); + } + + interface ContactListContracts{ + + void onResponse(List contactList); + + void onFailure(Throwable t, String message, int error_code); + + } + + interface CreateContactInterface{ + + void onContactCreated(Contact contact); + + void onContactCreateFailed(Throwable t, String message, int error_code); + + } + +} diff --git a/app/src/main/java/com/ssb/simplitend/welcome/mvvm/WelcomeRepository.java b/app/src/main/java/com/ssb/simplitend/welcome/mvvm/WelcomeRepository.java new file mode 100644 index 0000000..327560c --- /dev/null +++ b/app/src/main/java/com/ssb/simplitend/welcome/mvvm/WelcomeRepository.java @@ -0,0 +1,64 @@ +package com.ssb.simplitend.welcome.mvvm; + +import java.util.Map; + +import static com.ssb.simplitend.apputils.RetrofitHelper.*; + +import android.util.Log; + +import androidx.annotation.NonNull; + +import com.ssb.simplitend.welcome.mvvm.models.CallResponse; +import com.ssb.simplitend.welcome.mvvm.models.PatientResult; + +import retrofit2.Call; +import retrofit2.Callback; +import retrofit2.Response; + +public class WelcomeRepository { + + private static final String TAG = "WelcomeRepository"; + + private static WelcomeRepository welcomeRepository; + + private WelcomeRepository() {} + + public static synchronized WelcomeRepository getWelcomeRepository(){ + if (welcomeRepository == null){ + welcomeRepository = new WelcomeRepository(); + } + + return welcomeRepository; + } + + public void registerPatient(@NonNull String URL, + @NonNull Map body, + @NonNull WelcomeContracts.RegisterPatientContract registerPatient){ + + APIService welcomeService = getRetrofit().create(APIService.class); + + welcomeService.registerPatient(URL, body).enqueue(new Callback>() { + @Override + public void onResponse(Call> call, Response> response) { + if (response.isSuccessful() && response.body() != null && response.body().result != null) + { + registerPatient.onResponse(response.body().result, response.body().token); + }else if (response.body() != null){ + Log.e(TAG, "onResponse: " + response); + registerPatient.onFailure(new Exception(response.toString()), response.body().message, response.code()); + }else{ + Log.e(TAG, "onResponse: no success response and also response body is null"); + registerPatient.onFailure(new Exception("no success response and also response body is null"), "It's not you, it's us.\nPlease try again later", 1); + } + } + + @Override + public void onFailure(Call> call, Throwable t) { + Log.e(TAG, "onFailure: ", t); + registerPatient.onFailure(t, t.getMessage(), 1); + } + }); + + } + +} diff --git a/app/src/main/java/com/ssb/simplitend/welcome/mvvm/WelcomeViewModel.java b/app/src/main/java/com/ssb/simplitend/welcome/mvvm/WelcomeViewModel.java new file mode 100644 index 0000000..e822ae4 --- /dev/null +++ b/app/src/main/java/com/ssb/simplitend/welcome/mvvm/WelcomeViewModel.java @@ -0,0 +1,54 @@ +package com.ssb.simplitend.welcome.mvvm; + +import androidx.annotation.NonNull; +import androidx.lifecycle.ViewModel; + +import com.ssb.simplitend.welcome.mvvm.models.PatientData; + +import java.util.HashMap; +import java.util.Map; + +public class WelcomeViewModel extends ViewModel { + + private final WelcomeRepository welcomeRepository; + + // Patient data watcher + private PatientData patientData; + + public WelcomeViewModel(){ + this.welcomeRepository = WelcomeRepository.getWelcomeRepository(); + } + + public void registerPatient(@NonNull String URL, @NonNull WelcomeContracts.RegisterPatientContract registerPatientContract){ + Map body = new HashMap<>(); + + PatientData patientData = getPatientData(); + + body.put("full_name", patientData.first_name); + body.put("date_of_birth", patientData.date_of_birth); + body.put("contact_number", patientData.phone_number); + body.put("email", patientData.email); + body.put("street", patientData.address_line1); + body.put("town", patientData.city); + body.put("state", patientData.state); + body.put("country", patientData.country); + body.put("zip_code", patientData.post_code); + body.put("pin_code", patientData.pin_code); + body.put("cpin_code", patientData.c_pin_code); + body.put("lat", patientData.lat); + body.put("lng", patientData.lng); + + welcomeRepository.registerPatient(URL, body, registerPatientContract); + + } + + public synchronized PatientData getPatientData(){ + + if (patientData == null){ + patientData = new PatientData(); + } + + return patientData; + } + +} diff --git a/app/src/main/java/com/ssb/simplitend/welcome/mvvm/models/CallResponse.java b/app/src/main/java/com/ssb/simplitend/welcome/mvvm/models/CallResponse.java new file mode 100644 index 0000000..efd0918 --- /dev/null +++ b/app/src/main/java/com/ssb/simplitend/welcome/mvvm/models/CallResponse.java @@ -0,0 +1,13 @@ +package com.ssb.simplitend.welcome.mvvm.models; + +// base class for response +public class CallResponse { + + public String message; + public int error_code, status; + public T result; + public String token; + + public CallResponse() {} + +} diff --git a/app/src/main/java/com/ssb/simplitend/welcome/mvvm/models/PatientData.java b/app/src/main/java/com/ssb/simplitend/welcome/mvvm/models/PatientData.java new file mode 100644 index 0000000..9032824 --- /dev/null +++ b/app/src/main/java/com/ssb/simplitend/welcome/mvvm/models/PatientData.java @@ -0,0 +1,58 @@ +package com.ssb.simplitend.welcome.mvvm.models; + +public class PatientData { + // fields + public String user_name; + public String first_name; + public String date_of_birth; + public String phone_number; + public String email; + public String password; + public String address_line1; + public String city; + public String state; + public String country; + public String post_code; + public String lat; + public String lng; + public int is_patient; + public String updated_at; + public String created_at; + public int id; + + // for payload purpose + public String pin_code, c_pin_code; + + public PatientData() { + } + + public PatientData(String user_name, String first_name, String date_of_birth, String phone_number) { + this.user_name = user_name; + this.first_name = first_name; + this.date_of_birth = date_of_birth; + this.phone_number = phone_number; + } + + @Override + public String toString() { + return "PatientData{" + + "user_name='" + user_name + '\'' + + ", first_name='" + first_name + '\'' + + ", date_of_birth='" + date_of_birth + '\'' + + ", phone_number='" + phone_number + '\'' + + ", email='" + email + '\'' + + ", password='" + password + '\'' + + ", address_line1='" + address_line1 + '\'' + + ", city='" + city + '\'' + + ", state='" + state + '\'' + + ", country='" + country + '\'' + + ", post_code='" + post_code + '\'' + + ", lat='" + lat + '\'' + + ", lng='" + lng + '\'' + + ", is_patient=" + is_patient + + ", updated_at='" + updated_at + '\'' + + ", created_at='" + created_at + '\'' + + ", id=" + id + + '}'; + } +} diff --git a/app/src/main/java/com/ssb/simplitend/welcome/mvvm/models/PatientResult.java b/app/src/main/java/com/ssb/simplitend/welcome/mvvm/models/PatientResult.java new file mode 100644 index 0000000..d893539 --- /dev/null +++ b/app/src/main/java/com/ssb/simplitend/welcome/mvvm/models/PatientResult.java @@ -0,0 +1,19 @@ +package com.ssb.simplitend.welcome.mvvm.models; + +import com.google.gson.annotations.SerializedName; + +public class PatientResult { + @SerializedName("PatientData") + public PatientData patientData; + public int patientId; + + public PatientResult(){} + + @Override + public String toString() { + return "PatientResult{" + + "patientData=" + patientData + + ", patientId=" + patientId + + '}'; + } +} diff --git a/app/src/main/res/drawable/ic_smiley_outline.xml b/app/src/main/res/drawable/ic_smiley_outline.xml new file mode 100644 index 0000000..4143f38 --- /dev/null +++ b/app/src/main/res/drawable/ic_smiley_outline.xml @@ -0,0 +1,34 @@ + + + + + + diff --git a/app/src/main/res/layout/caregiver_dashboard_fragment.xml b/app/src/main/res/layout/caregiver_dashboard_fragment.xml index 8b1d131..f82c1ae 100644 --- a/app/src/main/res/layout/caregiver_dashboard_fragment.xml +++ b/app/src/main/res/layout/caregiver_dashboard_fragment.xml @@ -254,8 +254,8 @@ android:gravity="center"> @@ -304,8 +304,8 @@ android:gravity="center"> @@ -359,8 +359,8 @@ android:gravity="center"> @@ -405,8 +405,8 @@ android:gravity="center"> diff --git a/app/src/main/res/layout/chat_card_viewholder.xml b/app/src/main/res/layout/chat_card_viewholder.xml index 454593f..a63390f 100644 --- a/app/src/main/res/layout/chat_card_viewholder.xml +++ b/app/src/main/res/layout/chat_card_viewholder.xml @@ -7,6 +7,7 @@ android:background="@color/white_bg"> + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/app/src/main/res/layout/create_pin_fragment.xml b/app/src/main/res/layout/create_pin_fragment.xml index bd96ee2..7067971 100644 --- a/app/src/main/res/layout/create_pin_fragment.xml +++ b/app/src/main/res/layout/create_pin_fragment.xml @@ -98,6 +98,8 @@ android:inputType="numberPassword" android:maxLines="1" android:maxLength="4" + + android:nextFocusDown="@id/confirm_pin" /> diff --git a/app/src/main/res/layout/location_fragment.xml b/app/src/main/res/layout/location_fragment.xml index a460eba..699f8f6 100644 --- a/app/src/main/res/layout/location_fragment.xml +++ b/app/src/main/res/layout/location_fragment.xml @@ -1,6 +1,7 @@ - - + > + + + + + + + + + + + + - \ No newline at end of file + \ No newline at end of file diff --git a/app/src/main/res/layout/register_fragment.xml b/app/src/main/res/layout/register_fragment.xml index 98277d9..ba4eb29 100644 --- a/app/src/main/res/layout/register_fragment.xml +++ b/app/src/main/res/layout/register_fragment.xml @@ -55,6 +55,7 @@ /> - + + + + + + + + + - + android:gravity="center_vertical" + > + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/app/src/main/res/layout/thank_you_fragment.xml b/app/src/main/res/layout/thank_you_fragment.xml index 672f951..3d98434 100644 --- a/app/src/main/res/layout/thank_you_fragment.xml +++ b/app/src/main/res/layout/thank_you_fragment.xml @@ -11,24 +11,15 @@ android:layout_height="wrap_content" android:orientation="vertical" android:gravity="center_horizontal" + android:layout_centerInParent="true" > - - @@ -48,8 +39,8 @@ android:text="@string/let_s_add_your_caregiver_contact_information" android:textColor="@color/black" android:textAppearance="@style/TextAppearance.Material3.TitleLarge" - android:textAlignment="center" android:fontFamily="@font/nunito_regular" + android:textAlignment="center" android:layout_marginBottom="25dp" android:layout_marginTop="5dp"/> diff --git a/app/src/main/res/navigation/cp_dashboard_graph.xml b/app/src/main/res/navigation/cp_dashboard_graph.xml index e5f0eda..1fb958e 100644 --- a/app/src/main/res/navigation/cp_dashboard_graph.xml +++ b/app/src/main/res/navigation/cp_dashboard_graph.xml @@ -15,5 +15,13 @@ + android:label="ChatListFragment" > + + + \ No newline at end of file diff --git a/app/src/main/res/navigation/welcome_nav_graph.xml b/app/src/main/res/navigation/welcome_nav_graph.xml index b0da61a..e76e518 100644 --- a/app/src/main/res/navigation/welcome_nav_graph.xml +++ b/app/src/main/res/navigation/welcome_nav_graph.xml @@ -2,7 +2,7 @@ + app:startDestination="@id/thankYouFragment"> + app:destination="@id/thankYouFragment" + app:popUpTo="@id/splashFragment" + app:popUpToInclusive="true" + /> Login Welcome to SimpliTend Sign in to continue. - Email address + Email address* Enter your email. Enter pin Enter your pin @@ -212,5 +212,18 @@ Direction sos Search chats + Type a message + Send + + Enable to fetch location + It seems like your Location is turned off.\n\nTap on Settings and turn Location on. + Settings + Not now + + + AIzaSyDQvd4THJsS62DeDidNzfP3rrnKe7zmM-4 + Search places + I accept + terms and conditions \ No newline at end of file diff --git a/build.gradle b/build.gradle index 71b99f4..9e4adc6 100644 --- a/build.gradle +++ b/build.gradle @@ -2,4 +2,5 @@ plugins { id 'com.android.application' version '7.3.1' apply false id 'com.android.library' version '7.3.1' apply false + id 'com.google.android.libraries.mapsplatform.secrets-gradle-plugin' version '2.0.1' apply false } \ No newline at end of file