50 Commits

Author SHA1 Message Date
fff308000d Update Readme.md 2024-07-10 07:24:36 +00:00
c288ac1599 Update Readme.md 2024-07-10 07:15:49 +00:00
02a7d52c8c Add Readme.md 2024-07-10 07:06:03 +00:00
be1685e932 Google Play Store Vitals 2024-07-03 08:06:15 +00:00
Aditya7521
056a12fa30 Merge pull request #3 from adityagaikwad-1257/development
Merge pull request #2 from adityagaikwad-1257/master
2024-07-03 12:55:19 +05:30
Aditya7521
8c7ed49ea3 Merge pull request #2 from adityagaikwad-1257/master
Behind code
2024-07-03 12:52:48 +05:30
3a78852d3b . 2024-07-03 12:32:13 +05:30
meet2711
74e9a8b653 . 2024-04-11 19:36:46 +05:30
meet2711
dc26b40bfa . 2024-04-11 19:13:08 +05:30
meet2711
704467cd80 . 2024-04-10 19:46:22 +05:30
meet2711
327e856d27 . 2024-03-29 18:47:30 +05:30
meet2711
dd1deb5ddd . 2024-03-29 16:21:01 +05:30
ADITYA
539c82e708 home pc 2024-03-26 21:53:49 +05:30
ADITYA
e2f0cf4cb9 home pc 2024-03-24 23:24:07 +05:30
meet2711
26f2f6ccc2 . 2024-03-15 15:43:31 +05:30
meet2711
f3afd81571 . 2024-03-14 21:05:58 +05:30
meet2711
10519d88be . 2024-03-13 20:04:48 +05:30
meet2711
371e6bb6bb . 2024-03-13 20:04:44 +05:30
KajalBari
5159ad7c82 work pc 2 2024-03-13 19:21:12 +05:30
KajalBari
12be377465 work pc 2 2024-03-12 21:08:47 +05:30
jayeshkjain25
7d111cab69 . 2024-03-11 20:42:20 +05:30
jayeshkjain25
6b6d78deb8 . 2024-03-08 17:09:05 +05:30
jayeshkjain25
604f2785d9 . 2024-03-07 12:00:25 +05:30
ADITYA
dc24668a1a home pc 2024-03-04 12:44:52 +05:30
ADITYA
29b84d1041 home pc 2024-02-22 01:25:07 +05:30
Aditya Gaikwad
1a5f70c2e0 Merge pull request #1 from adityagaikwad-1257/master
.
2024-02-20 19:21:01 +05:30
14Sandee
14cdc90441 . 2024-02-19 19:56:58 +05:30
14Sandee
5b32a20b80 . 2024-02-02 20:48:08 +05:30
14Sandee
863e106e46 . 2024-01-22 20:33:28 +05:30
14Sandee
977fffa621 . 2024-01-19 15:40:33 +05:30
14Sandee
29d7052bfc . 2024-01-18 17:54:09 +05:30
14Sandee
bffd995ae7 . 2024-01-18 17:16:11 +05:30
14Sandee
dc04ec42bc Bug fixes - chat sender and receiver id to be principal ids 2024-01-17 16:30:45 +05:30
14Sandee
ad40f07c65 . 2024-01-16 21:13:33 +05:30
14Sandee
d99a495013 . 2024-01-16 14:59:35 +05:30
14Sandee
808f29cb80 . 2024-01-11 16:34:12 +05:30
14Sandee
20ed53591c . 2024-01-10 15:42:42 +05:30
14Sandee
6bfb8e4c30 . 2024-01-08 20:42:09 +05:30
14Sandee
76b31581bd . 2024-01-05 15:31:45 +05:30
14Sandee
876881dabc . 2024-01-04 20:59:10 +05:30
14Sandee
2e8390fbea . 2024-01-03 18:55:02 +05:30
14Sandee
64f22a1369 . 2024-01-02 15:40:52 +05:30
14Sandee
5611a29b71 . 2023-12-28 20:23:12 +05:30
14Sandee
0e75a2cbc7 . 2023-12-27 21:09:05 +05:30
14Sandee
59cfe7d675 location updates from home screen without home location and geofence for reference 2023-12-26 20:03:23 +05:30
14Sandee
c409e6380c location updates from home screen with home location and geofence for reference 2023-12-26 15:29:14 +05:30
14Sandee
243eb65568 location updates feature 2023-12-22 20:53:06 +05:30
14Sandee
d2db210ace location updates structure 2023-12-22 19:34:42 +05:30
14Sandee
ba26a56b5c support features 2023-12-22 12:17:46 +05:30
14Sandee
c8d788924f . 2023-12-19 15:50:23 +05:30
85 changed files with 4349 additions and 600 deletions

View File

@@ -1,28 +1,10 @@
<?xml version="1.0" encoding="UTF-8"?>
<project version="4">
<component name="deploymentTargetDropDown">
<targetSelectedWithDropDown>
<Target>
<type value="QUICK_BOOT_TARGET" />
<deviceKey>
<Key>
<type value="VIRTUAL_DEVICE_PATH" />
<value value="$USER_HOME$/.android/avd/Pixel_7_Pro_API_33.avd" />
</Key>
</deviceKey>
</Target>
</targetSelectedWithDropDown>
<timeTargetWasSelectedWithDropDown value="2023-12-21T15:11:48.465744Z" />
<targetsSelectedWithDialog>
<Target>
<type value="QUICK_BOOT_TARGET" />
<deviceKey>
<Key>
<type value="VIRTUAL_DEVICE_PATH" />
<value value="C:\Users\adity\.android\avd\Samsung_Z3_flip_API_34.avd" />
</Key>
</deviceKey>
</Target>
</targetsSelectedWithDialog>
<value>
<entry key="app">
<State />
</entry>
</value>
</component>
</project>

4
.idea/gradle.xml generated
View File

@@ -5,15 +5,15 @@
<option name="linkedExternalProjectsSettings">
<GradleProjectSettings>
<option name="testRunner" value="GRADLE" />
<option name="distributionType" value="DEFAULT_WRAPPED" />
<option name="externalProjectPath" value="$PROJECT_DIR$" />
<option name="gradleJvm" value="jbr-17" />
<option name="gradleJvm" value="#GRADLE_LOCAL_JAVA_HOME" />
<option name="modules">
<set>
<option value="$PROJECT_DIR$" />
<option value="$PROJECT_DIR$/app" />
</set>
</option>
<option name="resolveExternalAnnotations" value="false" />
</GradleProjectSettings>
</option>
</component>

View File

@@ -1,7 +1,6 @@
<component name="InspectionProjectProfileManager">
<profile version="1.0">
<option name="myName" value="Project Default" />
<inspection_tool class="AndroidLintWebViewLayout" enabled="false" level="ERROR" enabled_by_default="false" />
<inspection_tool class="AutoCloseableResource" enabled="true" level="WARNING" enabled_by_default="true">
<option name="METHOD_MATCHER_CONFIG" value="java.util.Formatter,format,java.io.Writer,append,com.google.common.base.Preconditions,checkNotNull,org.hibernate.Session,close,java.io.PrintWriter,printf,java.io.PrintStream,printf,android.provider.ContactsContract.Contacts,openContactPhotoInputStream" />
</inspection_tool>

31
Readme.md Normal file
View File

@@ -0,0 +1,31 @@
<h2><u>Simplitend Android (JAVA)</u></h2>
Android Version Supported :- **8+**
<h3><u>Installation Steps:-</u></h3>
1. Android Studio Latest Available Version.
<h3><u>Features :-</u></h3>
1. Senior :-
* Basic Chats 1-1 with eojis Using Socket.
* Call Blocking.
* App Blocking.
* Geofencing & Live location updates.
* CRUD of Medication and Activity Reminders with push notifications and Bottom Notifications if user is loginned.
* SOS.
* Directions to home.
2. Caregiver :-
* Basic Chats 1-1 with emojis Using Socket.
* Monitor Senior's location Realtime.
* SideBar & TabBar
* Set Geofence of the Senior.
* CRUD of Medication and Activity Reminders with push notifications and Bottom Notifications if user is loginned.
<h3><u>Notes :-</u></h3>
- Added Support for Android 14 in the latest Version.

BIN
SimplitendKeyStore Normal file

Binary file not shown.

View File

@@ -13,8 +13,8 @@ android {
applicationId "com.app.simplitend"
minSdk 24
targetSdk 33
versionCode 5
versionName "1.0"
versionCode 8
versionName "1.1.1"
testInstrumentationRunner "androidx.test.runner.AndroidJUnitRunner"
}

View File

@@ -7,9 +7,18 @@
<uses-permission android:name="android.permission.ACCESS_COARSE_LOCATION" />
<uses-permission android:name="android.permission.ACCESS_FINE_LOCATION" />
<uses-permission android:name="android.permission.READ_CONTACTS" />
<uses-permission android:name="android.permission.CALL_PHONE"/>
<uses-permission android:name="android.permission.FOREGROUND_SERVICE" /> <!-- For app blocking -> open new window over other apps to deny access -->
<uses-permission android:name="android.permission.RECEIVE_BOOT_COMPLETED"/>
<uses-permission android:name="android.permission.RECEIVE_BOOT_COMPLETED" />
<uses-permission android:name="android.permission.SYSTEM_ALERT_WINDOW" /> <!-- permissions for app blocking -->
<uses-permission android:name="android.permission.READ_PHONE_STATE"/>
<uses-permission android:name="android.permission.ANSWER_PHONE_CALLS" />
<uses-feature
android:name="android.hardware.telephony"
android:required="false" />
<uses-permission
android:name="android.permission.PACKAGE_USAGE_STATS"
tools:ignore="ProtectedPermissions" />
@@ -18,11 +27,10 @@
android:name="android.permission.WRITE_SECURE_SETTINGS"
tools:ignore="ProtectedPermissions" />
<!-- for retrieving all the apps having launcher screen-->
<queries>
<intent>
<action android:name="android.intent.action.MAIN" />
<category android:name="android.intent.category.LAUNCHER"/>
<category android:name="android.intent.category.LAUNCHER" />
</intent>
</queries>
@@ -39,11 +47,15 @@
android:theme="@style/Theme.SimpliTend"
android:usesCleartextTraffic="true"
tools:targetApi="31">
<activity
android:name=".cg_subscription.SubscriptionWebViewActivity"
android:exported="false"
android:screenOrientation="portrait"/>
<activity
android:name=".chats.ChatsActivity"
android:exported="false"
android:launchMode="singleTop"
android:screenOrientation="portrait"
android:exported="false" />
android:screenOrientation="portrait" />
<activity
android:name=".apputils.BottomNotificationActivity"
android:exported="false"
@@ -233,10 +245,11 @@
android:foregroundServiceType="location" />
<receiver android:name=".patientgeofencing.PatientLocationUpdatesReceiver" />
<receiver android:name=".apputils.BootCompleteReceiver"
<receiver
android:name=".apputils.BootCompleteReceiver"
android:exported="true">
<intent-filter>
<action android:name="android.intent.action.BOOT_COMPLETED"/>
<action android:name="android.intent.action.BOOT_COMPLETED" />
</intent-filter>
</receiver>
@@ -249,6 +262,17 @@
android:name="android.support.FILE_PROVIDER_PATHS"
android:resource="@xml/file_paths" />
</provider>
<receiver android:name=".patient_dashboard.foodreminders.FoodReminderYesReceiver"/>
<service android:name=".patient_dashboard.foodreminders.FoodReminderNotifyingService"/>
<receiver android:name=".patient_dashboard.CallReceiver"
android:enabled="true"
android:exported="true">
<intent-filter>
<action android:name="android.intent.action.PHONE_STATE" />
</intent-filter>
</receiver>
</application>
</manifest>

View File

@@ -29,6 +29,7 @@ import android.view.LayoutInflater;
import android.view.View;
import android.view.WindowManager;
import android.view.inputmethod.InputMethodManager;
import android.widget.Toast;
import androidx.annotation.NonNull;
import androidx.annotation.RawRes;
@@ -36,10 +37,13 @@ import androidx.annotation.RawRes;
import com.app.simplitend.R;
import com.app.simplitend.appblocking.TopAppDetectionService;
import com.app.simplitend.articles.ArticleShowerActivity;
import com.app.simplitend.caregiverdashboard.mvvm.CaregiverMainViewModel;
import com.app.simplitend.databinding.AlertDialogBinding;
import com.app.simplitend.databinding.DecisionBottomsheetBinding;
import com.app.simplitend.databinding.DoneBottomsheetBinding;
import com.app.simplitend.locationupdates.LocationService;
import com.app.simplitend.patient_dashboard.foodreminders.FoodScheduler;
import com.app.simplitend.patient_dashboard.PatientMainViewModel;
import com.app.simplitend.welcome.welcomepatient.fragments.contacts.mvvm.models.ContactData;
import com.app.simplitend.welcome.welcomepatient.mvvm.models.PatientData;
import com.bumptech.glide.Glide;
@@ -312,7 +316,7 @@ public abstract class AppUtil {
}
}
public static void dialPhone(Context activity, String phone_number) {
public static void dialPhone(Activity activity, String phone_number) {
Intent intent = new Intent(Intent.ACTION_DIAL, Uri.fromParts("tel",
phone_number, null));
if (activity != null) activity.startActivity(intent);
@@ -389,6 +393,13 @@ public abstract class AppUtil {
public static final String IS_CALL_BLOCKING_ENABLED = "is_call_blocking_enabled";
public static final String IS_BATTERY_LOW_NOTIFICATION_SENT = "battery_low_notification_sent";
public static final String IS_BATTERY_LOW_NOTIFICATION_SHOWN = "battery_low_notification_shown";
public static final String SKIPPED_UPDATE_VERSION = "skipped_update_version";
public static final String IS_USER_SUBSCRIBED = "is_user_subscribed";
public static void savePatientData(String token, int patient_uid, Context context, boolean isLoggedIn) {
SharedPreferences sp = context.getSharedPreferences(PATIENT_DETAILS, Context.MODE_PRIVATE);
SharedPreferences.Editor editor = sp.edit();
@@ -418,6 +429,48 @@ public abstract class AppUtil {
return sp.getBoolean(IS_PATIENT_LOGGED_IN, false);
}
public static void setBatteryLowNotificationSent(Context context, boolean sent){
SharedPreferences sp = context.getSharedPreferences(PATIENT_DETAILS, Context.MODE_PRIVATE);
SharedPreferences.Editor editor = sp.edit();
editor.putBoolean(IS_BATTERY_LOW_NOTIFICATION_SENT, sent);
editor.apply();
}
public static boolean isBatteryLowNotificationSent(Context context){
SharedPreferences sp = context.getSharedPreferences(PATIENT_DETAILS, Context.MODE_PRIVATE);
return sp.getBoolean(IS_BATTERY_LOW_NOTIFICATION_SENT, false);
}
public static void setBatteryLowNotificationShown(Context context, boolean sent){
SharedPreferences sp = context.getSharedPreferences(PATIENT_DETAILS, Context.MODE_PRIVATE);
SharedPreferences.Editor editor = sp.edit();
editor.putBoolean(IS_BATTERY_LOW_NOTIFICATION_SHOWN, sent);
editor.apply();
}
public static boolean isBatteryLowNotificationShown(Context context){
SharedPreferences sp = context.getSharedPreferences(PATIENT_DETAILS, Context.MODE_PRIVATE);
return sp.getBoolean(IS_BATTERY_LOW_NOTIFICATION_SHOWN, false);
}
public static void setUserSubscribed(Context context, boolean subscribed){
SharedPreferences sp = context.getSharedPreferences(PATIENT_DETAILS, Context.MODE_PRIVATE);
SharedPreferences.Editor editor = sp.edit();
editor.putBoolean(IS_USER_SUBSCRIBED, subscribed);
editor.apply();
}
public static boolean isUserSubscribed(Context context){
SharedPreferences sp = context.getSharedPreferences(PATIENT_DETAILS, Context.MODE_PRIVATE);
return sp.getBoolean(IS_USER_SUBSCRIBED, false);
}
public static void patientSignOut(Context context) {
clearAllNotifications(context);
clearAllChatNotificationsCount(context);
@@ -428,6 +481,11 @@ public abstract class AppUtil {
PatientDataCache.setPatientData(null);
PatientDataCache.setContactList(null);
PatientMainViewModel.remindersList = null;
PatientMainViewModel.activityList = null;
setUserSubscribed(context, false);
// turning off app_blocking accessibility permission
Intent stop_accessibility_intent = new Intent(context, TopAppDetectionService.class);
stop_accessibility_intent.setAction(TopAppDetectionService.STOP_ACCESSIBILITY_SERVICE);
@@ -440,7 +498,7 @@ public abstract class AppUtil {
// geofence details clear
updatePatientGeofence(context, null, null, null, null, null);
updatePatientGeofenceChatsCred(context, -1, -1, -1);
updatePatientGeofenceChatsCred(context, -1, -1, -1, -1);
// removing geofence of same tag
removeGeofence(context);
@@ -455,6 +513,8 @@ public abstract class AppUtil {
context.startService(intent);
}
}
FoodScheduler.removeFoodReminders(context);
}
public static boolean isLocationServiceRunning(Context activity){
@@ -546,6 +606,9 @@ public abstract class AppUtil {
CaregiverDataCache.setCareGiverData(null);
CaregiverMainViewModel.activityList = null;
CaregiverMainViewModel.remindersList = null;
clearAllNotifications(context);
clearAllChatNotificationsCount(context);
OneSignal.getNotifications().clearAllNotifications();
@@ -643,6 +706,20 @@ public abstract class AppUtil {
return sp.getBoolean(FUA_DIALOG, true);
}
public static void setSkippedUpdateVersion(Context context, int skipped_version){
SharedPreferences sp = context.getSharedPreferences(CAREGIVER_DETAILS, Context.MODE_PRIVATE);
SharedPreferences.Editor editor = sp.edit();
editor.putInt(SKIPPED_UPDATE_VERSION, skipped_version);
editor.apply();
}
public static int getSkippedVersion(Context context){
SharedPreferences sp = context.getSharedPreferences(CAREGIVER_DETAILS, Context.MODE_PRIVATE);
return sp.getInt(SKIPPED_UPDATE_VERSION, -1);
}
// patient geofencing
private static final String PATIENT_GEOFENCE_RADIUS = "patient_geofence_radius";
private static final String PATIENT_GEOFENCE_RADIUS_UNIT = "patient_geofence_radius_unit";
@@ -653,6 +730,7 @@ public abstract class AppUtil {
private static final String PATIENT_GEOFENCE_CG_ID = "pg_cg_uid";
private static final String PATIENT_GEOFENCE_CHANNEL_ID = "pg_channel_uid";
private static final String PATIENT_GEOFENCE_PATIENT_PRINCIPLE_ID = "pg_patient_geofence_uid";
private static final String PATIENT_GEOFENCE_CAREGIVER_PRINCIPLE_ID = "pg_caregiver_geofence_uid";
public static final String IS_SENIOR_OUT_OF_GEOFENCE = "is_senior_out_of_geofence";
@@ -672,13 +750,16 @@ public abstract class AppUtil {
public static void updatePatientGeofenceChatsCred(Context context,
int cg_id,
int channel_id, int patient_principal_id){
int channel_id,
int patient_principal_id,
int cg_principal_id){
SharedPreferences sp = context.getSharedPreferences(PATIENT_DETAILS, Context.MODE_PRIVATE);
SharedPreferences.Editor editor = sp.edit();
editor.putInt(PATIENT_GEOFENCE_CG_ID, cg_id);
editor.putInt(PATIENT_GEOFENCE_CHANNEL_ID, channel_id);
editor.putInt(PATIENT_GEOFENCE_PATIENT_PRINCIPLE_ID, patient_principal_id);
editor.putInt(PATIENT_GEOFENCE_CAREGIVER_PRINCIPLE_ID, cg_principal_id);
editor.apply();
}
@@ -689,13 +770,15 @@ public abstract class AppUtil {
// 1 -> caregiver_id
// 2 -> channel_id
// 3 -> patient_principal_id
// 4 -> cg_principal_id
@NonNull
public static int[] getPatientGeofenceChatCred(Context context){
SharedPreferences sp = context.getSharedPreferences(PATIENT_DETAILS, Context.MODE_PRIVATE);
return new int[]{sp.getInt(PATIENT_UID, -1),
sp.getInt(PATIENT_GEOFENCE_CG_ID, -1),
sp.getInt(PATIENT_GEOFENCE_CHANNEL_ID, -1),
sp.getInt(PATIENT_GEOFENCE_PATIENT_PRINCIPLE_ID, -1)};
sp.getInt(PATIENT_GEOFENCE_PATIENT_PRINCIPLE_ID, -1),
sp.getInt(PATIENT_GEOFENCE_CAREGIVER_PRINCIPLE_ID, -1)};
}
public static void updatePatientGeofence(Context context,

View File

@@ -2,30 +2,13 @@ package com.app.simplitend.apputils;
import static com.app.simplitend.locationupdates.LocationService.LOCATION_INTERVAL_BASE_TIME;
import static com.app.simplitend.locationupdates.LocationService.LOCATION_UPDATE_MIN_INTERVAL;
import static com.app.simplitend.patientgeofencing.GeoFenceHelper.GEOFENCE_ID;
import static com.app.simplitend.patientgeofencing.GeoFenceHelper.GEOFENCE_TAG;
import android.Manifest;
import android.app.PendingIntent;
import android.content.BroadcastReceiver;
import android.content.Context;
import android.content.Intent;
import android.content.pm.PackageManager;
import android.os.Build;
import android.util.Log;
import androidx.annotation.NonNull;
import androidx.annotation.RequiresPermission;
import androidx.core.app.ActivityCompat;
import androidx.core.content.ContextCompat;
import com.app.simplitend.locationupdates.LocationService;
import com.app.simplitend.patientgeofencing.GeoFenceHelper;
import com.google.android.gms.location.Geofence;
import com.google.android.gms.location.GeofencingClient;
import com.google.android.gms.location.GeofencingRequest;
import com.google.android.gms.location.LocationServices;
import com.google.android.gms.maps.model.LatLng;
public class BootCompleteReceiver extends BroadcastReceiver {
@Override
@@ -33,6 +16,11 @@ public class BootCompleteReceiver extends BroadcastReceiver {
if (Intent.ACTION_BOOT_COMPLETED.equals(intent.getAction())) {
if (!AppUtil.isPatientLoggedIn(context)){
// no senior is logged in
return;
}
AppUtil.updateSeniorOutOfGeofence(context, false);
// starting over the Location updates service again

View File

@@ -8,12 +8,17 @@ import static com.app.simplitend.apputils.AppUtil.MEDICATION_REFILL_NOTIFICATION
import static com.app.simplitend.apputils.AppUtil.SOS_NOTIFICATIONS;
import static com.app.simplitend.apputils.AppUtil.getCgNotificationPref;
import static com.app.simplitend.apputils.Constants.ACTIVITY_EXTRA_KEY;
import static com.app.simplitend.apputils.Constants.MEAL_REMINDER;
import static com.app.simplitend.apputils.Constants.MEDICATION_REFILL;
import static com.app.simplitend.apputils.Constants.REMINDER_EXTRA_KEY;
import static com.app.simplitend.apputils.NotificationService.CONTENT_TYPE_KEY;
import static com.app.simplitend.apputils.NotificationService.NOTIFICATION_CONTENT_ID_KEY;
import static com.app.simplitend.apputils.NotificationService.NOTIFICATION_MEAL_TYPE_KEY;
import static com.app.simplitend.apputils.NotificationService.NOTIFICATION_SENIOR_ADDRESS_KEY;
import static com.app.simplitend.locationupdates.LocationService.EXTRA_BATTERY_PERCENTAGE;
import static com.app.simplitend.patient_dashboard.foodreminders.FoodReminderYesReceiver.WHICH_FOOD_REMINDER;
import android.Manifest;
import android.content.Context;
import android.content.Intent;
import android.os.Bundle;
@@ -21,6 +26,8 @@ import android.view.LayoutInflater;
import android.view.View;
import android.widget.Toast;
import androidx.activity.result.ActivityResultLauncher;
import androidx.activity.result.contract.ActivityResultContracts;
import androidx.annotation.Nullable;
import androidx.appcompat.app.AppCompatActivity;
@@ -29,18 +36,31 @@ import com.app.simplitend.caregiverdashboard.mvvm.CaregiverMainViewModel;
import com.app.simplitend.chats.ChatsActivity;
import com.app.simplitend.databinding.BottomSheetAlertBinding;
import com.app.simplitend.patient_dashboard.PatientMainViewModel;
import com.app.simplitend.patient_dashboard.foodreminders.FoodReminderNotifyingService;
import com.app.simplitend.patientprofile.medreminder.mvvm.models.ReminderResult;
import com.app.simplitend.patientprofile.setuproutine.mvvm.RoutineDetails;
import com.app.simplitend.welcome.welcomepatient.mvvm.models.CallResponse;
import com.bumptech.glide.Glide;
import com.google.android.material.bottomsheet.BottomSheetDialog;
import java.text.SimpleDateFormat;
import java.util.Date;
import java.util.HashMap;
import java.util.Locale;
import java.util.Map;
import java.util.Objects;
import retrofit2.Call;
import retrofit2.Callback;
import retrofit2.Response;
public class BottomNotificationActivity extends AppCompatActivity {
private ActivityResultLauncher<String> callPermission;
private String selected_phone_number = null;
private BottomSheetDialog bsd = null;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
@@ -51,6 +71,14 @@ public class BottomNotificationActivity extends AppCompatActivity {
// setRequestedOrientation(ActivityInfo.SCREEN_ORIENTATION_PORTRAIT);
// }
callPermission = registerForActivityResult(new ActivityResultContracts.RequestPermission(),
isGranted -> {
if (selected_phone_number == null) return;
if (bsd != null) bsd.dismiss();
AppUtil.callPhone(this, selected_phone_number);
});
if (AppUtil.getCgToken(this) != null){
// handle caregiver bottom sheets
handleCaregiverBottomSheets();
@@ -153,7 +181,7 @@ public class BottomNotificationActivity extends AppCompatActivity {
if (content_type == null) return;
BottomSheetDialog bsd = new BottomSheetDialog(context, R.style.BottomSheetDialog);
bsd = new BottomSheetDialog(context, R.style.BottomSheetDialog);
BottomSheetAlertBinding binding = BottomSheetAlertBinding.inflate(LayoutInflater.from(context));
bsd.setContentView(binding.getRoot());
@@ -167,6 +195,22 @@ public class BottomNotificationActivity extends AppCompatActivity {
String body = intent.getStringExtra(NotificationService.NOTIFICATION_BODY_KEY);
switch (content_type) {
case Constants.BATTERY_LOW:
int percentage = intent.getIntExtra(NOTIFICATION_CONTENT_ID_KEY, -1);
setUpCgBottomSheet(binding,
R.drawable.ic_battery_low,
patient_name + "'s phone low battery reminder", "Phone battery remaining",
"" + (percentage>=0?percentage+"%":"Unknown"), "Text senior", view -> {
bsd.dismiss();
finish();
Intent chatsIntent = new Intent(this, ChatsActivity.class);
startActivity(chatsIntent);
});
bsd.show();
break;
case Constants.PATIENT_OUT_OF_GEOFENCE:
if (!getCgNotificationPref(context, GEOFENCE_NOTIFICATIONS)){
@@ -192,13 +236,13 @@ public class BottomNotificationActivity extends AppCompatActivity {
senior_distance, "Call senior",
v -> {
CaregiverDataCache.getCaregiverData(context, (careGiverData -> {
bsd.dismiss();
if (careGiverData == null || careGiverData.patientDetails == null) {
Toast.makeText(context, "Couldn't load data", Toast.LENGTH_SHORT).show();
return;
}
AppUtil.dialPhone(context, careGiverData.patientDetails.phone_number);
selected_phone_number = careGiverData.patientDetails.phone_number;
callPermission.launch(Manifest.permission.CALL_PHONE);
}), true);
});
@@ -319,13 +363,13 @@ public class BottomNotificationActivity extends AppCompatActivity {
doh_distance, "Call senior",
v -> {
CaregiverDataCache.getCaregiverData(context, (careGiverData -> {
bsd.dismiss();
if (careGiverData == null || careGiverData.patientDetails == null) {
Toast.makeText(context, "Couldn't load data", Toast.LENGTH_SHORT).show();
return;
}
AppUtil.dialPhone(context, careGiverData.patientDetails.phone_number);
selected_phone_number = careGiverData.patientDetails.phone_number;
callPermission.launch(Manifest.permission.CALL_PHONE);
}), true);
});
@@ -347,13 +391,13 @@ public class BottomNotificationActivity extends AppCompatActivity {
null, "Call senior",
v -> {
CaregiverDataCache.getCaregiverData(context, (careGiverData -> {
bsd.dismiss();
if (careGiverData == null || careGiverData.patientDetails == null) {
Toast.makeText(context, "Couldn't load data", Toast.LENGTH_SHORT).show();
return;
}
AppUtil.dialPhone(context, careGiverData.patientDetails.phone_number);
selected_phone_number = careGiverData.patientDetails.phone_number;
callPermission.launch(Manifest.permission.CALL_PHONE);
}), true);
});
@@ -400,6 +444,31 @@ public class BottomNotificationActivity extends AppCompatActivity {
bsd.show();
break;
case MEAL_REMINDER:
String mealType = intent.getStringExtra(NOTIFICATION_MEAL_TYPE_KEY);
if (mealType == null) body = patient_name + " skipped their meal!";
else body = patient_name + " skipped " + mealType + "!";
setUpCgBottomSheet(binding,
R.drawable.img_meal_reminder,
"Meal reminder", body,
null, "Call senior",
v -> {
CaregiverDataCache.getCaregiverData(context, (careGiverData -> {
if (careGiverData == null || careGiverData.patientDetails == null) {
Toast.makeText(context, "Couldn't load data", Toast.LENGTH_SHORT).show();
return;
}
selected_phone_number = careGiverData.patientDetails.phone_number;
callPermission.launch(Manifest.permission.CALL_PHONE);
}), true);
});
bsd.show();
break;
}
// already returning
@@ -425,7 +494,7 @@ public class BottomNotificationActivity extends AppCompatActivity {
if (content_type == null) return;
BottomSheetDialog bsd = new BottomSheetDialog(context, R.style.BottomSheetDialog);
bsd = new BottomSheetDialog(context, R.style.BottomSheetDialog);
BottomSheetAlertBinding binding = BottomSheetAlertBinding.inflate(LayoutInflater.from(context));
bsd.setContentView(binding.getRoot());
@@ -439,6 +508,20 @@ public class BottomNotificationActivity extends AppCompatActivity {
String body = intent.getStringExtra(NotificationService.NOTIFICATION_BODY_KEY);
switch (content_type) {
case Constants.BATTERY_LOW:
int percentage = intent.getIntExtra(EXTRA_BATTERY_PERCENTAGE, -1);
setUpSeniorBottomSheet(binding,
R.drawable.ic_battery_low,
"" + (percentage>=0?percentage+"% phone battery remaining":"Phone battery low"), "Connect to charger soon",
null, "Close", view -> {
bsd.dismiss();
finish();
}, null, null);
bsd.show();
break;
case Constants.ACTIVITY_TIME:
if (!getCgNotificationPref(context, ACTIVITY_NOTIFICATIONS)) {
@@ -470,6 +553,9 @@ public class BottomNotificationActivity extends AppCompatActivity {
body = routine.routine_title;
routine_description = start_time + " - " + end_time;
}else{
finish();
break;
}
} catch (Exception e) {
// do nothing
@@ -481,7 +567,7 @@ public class BottomNotificationActivity extends AppCompatActivity {
routine_description, "Close", view -> {
bsd.dismiss();
finish();
});
}, null, null);
bsd.show();
break;
@@ -515,6 +601,9 @@ public class BottomNotificationActivity extends AppCompatActivity {
if (reminder.medication_instruction == null)
reminder.medication_instruction = "None";
description = "Instructions: " + reminder.medication_instruction;
}else {
finish();
break;
}
} catch (Exception e) {
// do nothing
@@ -526,10 +615,36 @@ public class BottomNotificationActivity extends AppCompatActivity {
description, "Close", view -> {
bsd.dismiss();
finish();
});
},null, null);
bsd.show();
break;
case MEAL_REMINDER:
setUpSeniorBottomSheet(binding,
R.drawable.img_meal_reminder,
"Meal reminder", title,
null, "No", view -> {
bsd.dismiss();
int which_meal = intent.getIntExtra(WHICH_FOOD_REMINDER, -1);
if (which_meal == -1) return;
FoodReminderNotifyingService.NotificationsApiService apiService = RetrofitHelper.getRetrofit().create(FoodReminderNotifyingService.NotificationsApiService.class);
Map<String, Integer> requestBody = new HashMap<>();
requestBody.put("patient_id", AppUtil.getPatientUid(this));
requestBody.put("meal_type", which_meal);
apiService.sendMealNotification("Bearer " + AppUtil.getPatientToken(this), requestBody)
.enqueue(new Callback<CallResponse<Object>>() {
@Override
public void onResponse(Call<CallResponse<Object>> call, Response<CallResponse<Object>> response) {}
@Override
public void onFailure(Call<CallResponse<Object>> call, Throwable t) {}
});
}, "Yes",view -> {
bsd.dismiss();
});
bsd.show();
break;
}
}
@@ -537,7 +652,9 @@ public class BottomNotificationActivity extends AppCompatActivity {
int img_res,
String title, String description_title,
String description, String btn_text,
View.OnClickListener btn_clickListener) {
View.OnClickListener btn_clickListener,
String close_txt,
View.OnClickListener close_clickListener) {
// binding.image.setImageResource(img_res);
Glide.with(binding.image)
.load(img_res)
@@ -546,7 +663,13 @@ public class BottomNotificationActivity extends AppCompatActivity {
binding.descriptionTitle.setText(description_title);
binding.description.setText(description);
binding.close.setVisibility(View.GONE);
if (close_clickListener == null){
binding.close.setVisibility(View.GONE);
}else{
binding.close.setVisibility(View.VISIBLE);
binding.close.setText(close_txt);
binding.close.setOnClickListener(close_clickListener);
}
binding.btn.setText(btn_text);
binding.btn.setOnClickListener(btn_clickListener);

View File

@@ -23,7 +23,7 @@ public abstract class CaregiverDataCache {
careGiverData = data;
}
public static void getCaregiverData(Context context,
public synchronized static void getCaregiverData(Context context,
@NonNull GetCaregiverDataCallBack callBack,
boolean show_progress){
if (careGiverData != null && careGiverData.patientDetails != null){

View File

@@ -2,6 +2,8 @@ package com.app.simplitend.apputils;
public abstract class Constants {
public static final String NEW_SUBSCRIPTION = "new_subscription";
public static final String BATTERY_LOW = "battery_perentage";
public static final String ACTIVITY_TIME = "activity_time";
public static final String MEDICINE_TIME = "medicine_time";
public static final String GEOFENCING_RADIUS_UPDATED = "geofencing_radius_updated";
@@ -15,4 +17,6 @@ public abstract class Constants {
public static final String ACTIVITY_EXTRA_KEY = "activity_extra_key";
public static final String MEDICATION_REFILL = "medication_refill";
public static final String MEAL_REMINDER = "meals_time_reminder";
}

View File

@@ -3,31 +3,21 @@ package com.app.simplitend.apputils;
import static android.content.Context.NOTIFICATION_SERVICE;
import static com.app.simplitend.apputils.AppUtil.NOTIFICATION_ACTION;
import static com.app.simplitend.apputils.Constants.ACTIVITY_TIME;
import static com.app.simplitend.apputils.Constants.BATTERY_LOW;
import static com.app.simplitend.apputils.Constants.MEDICATION_REFILL;
import static com.app.simplitend.apputils.Constants.MEDICINE_TIME;
import static com.app.simplitend.patientgeofencing.GeoFenceHelper.GEOFENCE_ID;
import static com.app.simplitend.apputils.Constants.NEW_SUBSCRIPTION;
import static com.app.simplitend.patientgeofencing.GeoFenceHelper.GEOFENCE_TAG;
import android.Manifest;
import android.app.NotificationManager;
import android.app.PendingIntent;
import android.content.Context;
import android.content.Intent;
import android.content.pm.PackageManager;
import android.os.Build;
import android.service.notification.StatusBarNotification;
import android.util.Log;
import android.widget.Toast;
import androidx.annotation.NonNull;
import androidx.annotation.RequiresPermission;
import androidx.core.app.ActivityCompat;
import androidx.core.content.ContextCompat;
import com.app.simplitend.patientgeofencing.GeoFenceHelper;
import com.google.android.gms.location.Geofence;
import com.google.android.gms.location.GeofencingClient;
import com.google.android.gms.location.GeofencingRequest;
import com.google.android.gms.location.LocationServices;
import com.google.android.gms.maps.model.LatLng;
import com.app.simplitend.patient_dashboard.PatientMainViewModel;
import com.onesignal.OneSignal;
import com.onesignal.notifications.INotificationReceivedEvent;
import com.onesignal.notifications.INotificationServiceExtension;
@@ -36,7 +26,6 @@ import org.json.JSONException;
import org.json.JSONObject;
import java.util.Arrays;
import java.util.Comparator;
import java.util.List;
public class NotificationService implements INotificationServiceExtension {
@@ -48,6 +37,8 @@ public class NotificationService implements INotificationServiceExtension {
public static final String NOTIFICATION_SENIOR_ADDRESS_KEY = "notification_senior_address";
public static final String NOTIFICATION_MEAL_TYPE_KEY = "notification_meal_type_key";
@Override
public void onNotificationReceived(@NonNull INotificationReceivedEvent iNotificationReceivedEvent) {
// Log.d("aditya testing", "onNotificationReceived: " + iNotificationReceivedEvent.getNotification());
@@ -61,7 +52,7 @@ public class NotificationService implements INotificationServiceExtension {
{
List<StatusBarNotification> active_notifications = Arrays.asList(notificationManager.getActiveNotifications());
int minPostTime = Integer.MAX_VALUE;
long minPostTime = Long.MAX_VALUE;
StatusBarNotification notification = null;
for (StatusBarNotification not: active_notifications){
if (not.getPostTime() < minPostTime){
@@ -108,6 +99,15 @@ public class NotificationService implements INotificationServiceExtension {
AppUtil.incrementNoOfNotification(iNotificationReceivedEvent.getContext());
}
if (NEW_SUBSCRIPTION.equals(content_type)){
// sending local broadcast
Intent broadcastIntent = new Intent(NOTIFICATION_ACTION);
broadcastIntent.putExtra(CONTENT_TYPE_KEY, content_type);
iNotificationReceivedEvent.getContext().sendBroadcast(broadcastIntent);
return;
}
Intent intent = new Intent(iNotificationReceivedEvent.getContext(), BottomNotificationActivity.class);
intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
intent.setAction(NOTIFICATION_ACTION);
@@ -116,18 +116,24 @@ public class NotificationService implements INotificationServiceExtension {
intent.putExtra(NOTIFICATION_TITLE_KEY, iNotificationReceivedEvent.getNotification().getTitle());
intent.putExtra(NOTIFICATION_CONTENT_ID_KEY, id);
intent.putExtra(NOTIFICATION_SENIOR_ADDRESS_KEY, senior_current_address);
intent.putExtra(NOTIFICATION_MEAL_TYPE_KEY, senior_current_address);
// showing bottom sheet
try {
if (AppUtil.getCgToken(iNotificationReceivedEvent.getContext()) != null){
// when caregiver is logged in
iNotificationReceivedEvent.getContext().startActivity(intent);
}else{
// when patient is logged in
if (MEDICINE_TIME.equals(content_type) || ACTIVITY_TIME.equals(content_type)){
// Only for meds and activity reminders
if ( (PatientMainViewModel.remindersList != null && MEDICINE_TIME.equals(content_type)) ||
(PatientMainViewModel.remindersList != null && MEDICATION_REFILL.equals(content_type)) ||
(PatientMainViewModel.activityList != null && ACTIVITY_TIME.equals(content_type)) ||
BATTERY_LOW.equals(content_type)){
iNotificationReceivedEvent.getContext().startActivity(intent);
}
}
} catch (Exception e) {
// do nothing

View File

@@ -125,6 +125,11 @@ public class PatientDataCache {
}
if (callBack != null){
try {
AppUtil.setUserSubscribed(context, response.body().result.isCaregiverTakeSubscription == 1);
} catch (Exception e) {
// do nothing
}
setPatientData(response.body().result);
callBack.patientData(response.body().result);
}

View File

@@ -1,5 +1,6 @@
package com.app.simplitend.apputils;
import static com.app.simplitend.locationupdates.LocationService.FOOD_REMINDER_NOTIFICATION_CHANNEL_ID;
import static com.app.simplitend.locationupdates.LocationService.LOCATION_NOTIFICATION_CHANNEL_ID;
import android.app.Application;
@@ -7,10 +8,10 @@ import android.app.NotificationChannel;
import android.app.NotificationManager;
import android.os.Build;
import com.app.simplitend.R;
import com.onesignal.Continue;
import com.onesignal.OneSignal;
import com.onesignal.debug.LogLevel;
import com.app.simplitend.R;
public class SimpliTendApp extends Application {
@@ -35,11 +36,6 @@ public class SimpliTendApp extends Application {
}
}));
// click listener to notification
OneSignal.getNotifications().addClickListener(iNotificationClickEvent -> {
});
// creating notification channel for location share location updates from patient side
// using a foreground service
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O){
@@ -47,8 +43,13 @@ public class SimpliTendApp extends Application {
"Location updates",
NotificationManager.IMPORTANCE_HIGH);
NotificationChannel food_r_channel = new NotificationChannel(FOOD_REMINDER_NOTIFICATION_CHANNEL_ID,
"Food reminders",
NotificationManager.IMPORTANCE_HIGH);
NotificationManager notificationManager = (NotificationManager) getSystemService(NOTIFICATION_SERVICE);
notificationManager.createNotificationChannel(channel);
notificationManager.createNotificationChannel(food_r_channel);
}
}

View File

@@ -21,6 +21,7 @@ import java.util.concurrent.TimeUnit;
public class CallService extends CallScreeningService {
public static final String CONTACT_WHITE_LISTING_TAG = "CONTACT_WHITELISTING";
public static final long CALL_UNBLOCKING_INTERVAL = 30;
private static void endCall(CallResponse.Builder builder) {
builder.setDisallowCall(true)
@@ -33,9 +34,10 @@ public class CallService extends CallScreeningService {
if ("911".equals(callDetails.getHandle().getSchemeSpecificPart())){
Log.d(CALL_BLOCKING_WORk, "CALLED 911");
WorkManager.getInstance(this).cancelAllWork();
WorkManager.getInstance(this).cancelAllWorkByTag(CALL_BLOCKING_WORk);
WorkRequest workRequest = new OneTimeWorkRequest.Builder(CallUnBlockingWorker.class)
.setInitialDelay(1, TimeUnit.MINUTES)
.setInitialDelay(CALL_UNBLOCKING_INTERVAL, TimeUnit.MINUTES)
.addTag(CALL_BLOCKING_WORk)
.build();
WorkManager.getInstance(this).enqueue(workRequest);
@@ -71,7 +73,7 @@ public class CallService extends CallScreeningService {
Set<String> white_contacts = AppUtil.getWhiteListedContacts(this);
Log.d(CONTACT_WHITE_LISTING_TAG, "WHITE LISTED CONTACTS -> " + white_contacts);
if (white_contacts != null && !white_contacts.contains(phoneNumber)){
if (AppUtil.isUserSubscribed(this) && white_contacts != null && !white_contacts.contains(phoneNumber)){
endCall(builder);
Log.d(CONTACT_WHITE_LISTING_TAG, "CALL ENDED");
}

View File

@@ -5,7 +5,6 @@ import android.content.Intent;
import android.content.res.Configuration;
import android.os.Bundle;
import android.view.View;
import android.widget.Toast;
import androidx.annotation.NonNull;
import androidx.appcompat.app.AppCompatActivity;
@@ -41,6 +40,8 @@ public class CaregiverDashActivity extends AppCompatActivity implements
DragStateListener,
HomeBottomNav.OnBottomNavItemSelectListener, INotificationLifecycleListener {
private static final String TAG = "SOCKET_CaregiverDashActivity";
// view binding
protected CaregiverDashboardActivityBinding binding;
private CaregiverDashboardMenuBinding menuBinding;
@@ -60,6 +61,13 @@ public class CaregiverDashActivity extends AppCompatActivity implements
CaregiverDataCache.getCaregiverData(this, (careGiverData) -> {
this.careGiverData = careGiverData;
if (careGiverData != null && careGiverData.patientDetails != null){
SocketHelper.getInstance().establishConnection(null);
String uniqueKey = careGiverData.patientDetails.id + "medActivity" + careGiverData.id;
SocketHelper.getInstance().initializeSocket(this, uniqueKey);
}
watchSubscription();
}, true);
@@ -106,6 +114,9 @@ public class CaregiverDashActivity extends AppCompatActivity implements
super.onDestroy();
SocketHelper.getInstance().closeConnection();
OneSignal.getNotifications().removeForegroundLifecycleListener(this);
CaregiverMainViewModel.remindersList = null;
CaregiverMainViewModel.activityList = null;
}
private void initViews() {
@@ -316,8 +327,8 @@ public class CaregiverDashActivity extends AppCompatActivity implements
}
replaceFragment(new ChatFragment(
careGiverData1.caregiver_xid + "",
careGiverData1.patientId + "",
careGiverData1.id + "",
careGiverData1.patientDetails.id + "",
careGiverData1.link_id,
careGiverData1.patientDetails.id + "",
careGiverData1.first_name,

View File

@@ -246,8 +246,6 @@ public class EditProfileInfoActivity extends AppCompatActivity implements
} else if (result.getResultCode() == ImagePicker.RESULT_ERROR) {
Toast.makeText(this, ImagePicker.getError(result.getData()), Toast.LENGTH_SHORT).show();
} else {
Toast.makeText(this, "Task Cancelled", Toast.LENGTH_SHORT).show();
}
});
@@ -292,7 +290,6 @@ public class EditProfileInfoActivity extends AppCompatActivity implements
ImagePicker.with(this)
.cropSquare()
.maxResultSize(500, 500)
.galleryOnly()
.createIntent(intent -> {
imageSelector.launch(intent);
return null;

View File

@@ -1,10 +1,12 @@
package com.app.simplitend.caregiverdashboard.fragments;
import static com.app.simplitend.apputils.NotificationService.CONTENT_TYPE_KEY;
import static com.app.simplitend.apputils.RetrofitHelper.IMAGE_BASE_URL;
import static com.app.simplitend.articles.ArticleShowerActivity.ARTICLE_TITLE;
import static com.app.simplitend.articles.ArticleShowerActivity.ARTICLE_URL_KEY;
import static com.app.simplitend.caregiverdashboard.activities.EditProfileInfoActivity.IS_CAREGIVER;
import static com.app.simplitend.cg_geofencing.CgGeoFencingActivity.GEOFENCE_DETAILS_KEY;
import static com.app.simplitend.cg_geofencing.CgGeoFencingActivity.TO_SHOW_LOCATION_UPDATES_KEY;
import static com.app.simplitend.patient_dashboard.NotificationsActivity.USER_ID;
import static com.app.simplitend.patient_dashboard.NotificationsActivity.USER_TOKEN;
@@ -13,6 +15,7 @@ import android.content.BroadcastReceiver;
import android.content.Context;
import android.content.Intent;
import android.content.IntentFilter;
import android.graphics.drawable.Drawable;
import android.os.Bundle;
import android.util.Log;
import android.view.LayoutInflater;
@@ -22,6 +25,7 @@ import android.widget.Toast;
import androidx.annotation.NonNull;
import androidx.annotation.Nullable;
import androidx.appcompat.content.res.AppCompatResources;
import androidx.fragment.app.Fragment;
import androidx.lifecycle.ViewModelProvider;
@@ -39,6 +43,7 @@ import com.app.simplitend.caregiverdashboard.mvvm.CgHomeContracts;
import com.app.simplitend.caregiverdashboard.mvvm.models.GeoFenceDetails;
import com.app.simplitend.cg_geofencing.CgGeoFencingActivity;
import com.app.simplitend.databinding.CaregiverDashFragmentBinding;
import com.app.simplitend.databinding.MarkerBgSmallBinding;
import com.app.simplitend.patient_dashboard.NotificationsActivity;
import com.app.simplitend.patientprofile.ProfileContracts;
import com.app.simplitend.patientprofile.medreminder.mvvm.ReminderViewModel;
@@ -50,6 +55,10 @@ import com.app.simplitend.patientprofile.setuproutine.mvvm.RoutineViewModel;
import com.app.simplitend.welcome.welcomecg.mvvm.CareGiverData;
import com.app.simplitend.welcome.welcomepatient.mvvm.models.PatientData;
import com.bumptech.glide.Glide;
import com.bumptech.glide.load.DataSource;
import com.bumptech.glide.load.engine.GlideException;
import com.bumptech.glide.request.RequestListener;
import com.bumptech.glide.request.target.Target;
import com.google.android.gms.maps.CameraUpdateFactory;
import com.google.android.gms.maps.GoogleMap;
import com.google.android.gms.maps.OnMapReadyCallback;
@@ -57,6 +66,7 @@ import com.google.android.gms.maps.SupportMapFragment;
import com.google.android.gms.maps.model.BitmapDescriptorFactory;
import com.google.android.gms.maps.model.LatLng;
import com.google.android.gms.maps.model.MarkerOptions;
import com.google.maps.android.ui.IconGenerator;
import com.onesignal.OneSignal;
import com.onesignal.notifications.INotificationLifecycleListener;
import com.onesignal.notifications.INotificationWillDisplayEvent;
@@ -105,6 +115,7 @@ public class CgDashBoardFragment extends Fragment implements
@Override
public View onCreateView(@NonNull LayoutInflater inflater, @Nullable ViewGroup container, @Nullable Bundle savedInstanceState) {
binding = CaregiverDashFragmentBinding.inflate(inflater, container, false);
viewModel = new ViewModelProvider(requireActivity()).get(CaregiverMainViewModel.class);
reminderViewModel = new ViewModelProvider(requireActivity()).get(ReminderViewModel.class);
routineViewModel = new ViewModelProvider(requireActivity()).get(RoutineViewModel.class);
@@ -127,8 +138,18 @@ public class CgDashBoardFragment extends Fragment implements
CaregiverDataCache.getCaregiverData(requireActivity(), (careGiverData1 -> {
this.careGiverData = careGiverData1;
loadReminders();
loadActivities();
if (CaregiverMainViewModel.remindersList == null){
loadReminders();
}else {
onRemindersListFetched(CaregiverMainViewModel.remindersList);
}
if (CaregiverMainViewModel.activityList == null){
loadActivities();
}else {
onRoutinesFetched(CaregiverMainViewModel.activityList);
}
try {
requireContext().registerReceiver(notification_receiver, new IntentFilter(AppUtil.NOTIFICATION_ACTION));
} catch (Exception e) {
@@ -188,10 +209,14 @@ public class CgDashBoardFragment extends Fragment implements
binding.onGoingActivity.setText(viewModel.ongoingActivityText);
binding.upcomingActivity.setText(viewModel.upcomingActivityText);
routineViewModel.getRoutines(careGiverData.patientId,
"Bearer " + AppUtil.getCgToken(requireContext()),
Calendar.getInstance().get(Calendar.DAY_OF_WEEK)-1,
this);
try {
routineViewModel.getRoutines(careGiverData.patientId,
"Bearer " + AppUtil.getCgToken(requireContext()),
Calendar.getInstance().get(Calendar.DAY_OF_WEEK)-1,
this);
} catch (Exception e) {
// do nothing
}
}
private void loadReminders(){
@@ -199,10 +224,14 @@ public class CgDashBoardFragment extends Fragment implements
binding.nearestReminder.setText(viewModel.upcomingReminderText);
reminderViewModel.getRemindersList(careGiverData.patientId,
Calendar.getInstance().get(Calendar.DAY_OF_WEEK)-1,
"Bearer " + AppUtil.getCgToken(requireContext()),
this);
try {
reminderViewModel.getRemindersList(careGiverData.patientId,
Calendar.getInstance().get(Calendar.DAY_OF_WEEK)-1,
"Bearer " + AppUtil.getCgToken(requireContext()),
this);
} catch (Exception e) {
// do nothing
}
}
private void loadArticles() {
@@ -456,6 +485,7 @@ public class CgDashBoardFragment extends Fragment implements
gotoGeofenceActivity = false;
Intent intent = new Intent(requireActivity(), CgGeoFencingActivity.class);
intent.putExtra(GEOFENCE_DETAILS_KEY, geoFenceDetails);
intent.putExtra(TO_SHOW_LOCATION_UPDATES_KEY, true);
startActivity(intent);
}else{
// load into home screen map view
@@ -474,9 +504,47 @@ public class CgDashBoardFragment extends Fragment implements
MarkerOptions markerOptions = new MarkerOptions()
.position(pat_cur_latLng)
.icon(BitmapDescriptorFactory.fromResource(R.drawable.img_pat_curr_location));
.draggable(false);
if (patientData != null && patientData.profile_photo != null) {
MarkerBgSmallBinding markerBgBinding = MarkerBgSmallBinding.inflate(getLayoutInflater());
Glide.with(this)
.load(IMAGE_BASE_URL + patientData.profile_photo)
.error(R.drawable.img_pat_curr_location)
.placeholder(android.R.color.darker_gray)
.addListener(new RequestListener<Drawable>() {
@Override
public boolean onLoadFailed(@Nullable GlideException e, Object model, Target<Drawable> target, boolean isFirstResource) {
markerOptions.icon(BitmapDescriptorFactory.fromResource(R.drawable.img_pat_curr_location));
mGoogleMap.addMarker(markerOptions);
return false;
}
@Override
public boolean onResourceReady(Drawable resource, Object model, Target<Drawable> target, DataSource dataSource, boolean isFirstResource) {
try {
IconGenerator iconGenerator = new IconGenerator(requireContext());
markerBgBinding.markerBgImage.setImageDrawable(resource);
iconGenerator.setContentView(markerBgBinding.getRoot());
iconGenerator.setBackground(AppCompatResources.getDrawable(requireContext(), android.R.color.transparent));
markerOptions.icon(BitmapDescriptorFactory.fromBitmap(iconGenerator.makeIcon()));
mGoogleMap.addMarker(markerOptions);
} catch (Exception e) {
markerOptions.icon(BitmapDescriptorFactory.fromResource(R.drawable.img_pat_curr_location));
mGoogleMap.addMarker(markerOptions);
}
return false;
}
})
.into(markerBgBinding.markerBgImage);
} else {
markerOptions.icon(BitmapDescriptorFactory.fromResource(R.drawable.img_pat_curr_location));
mGoogleMap.addMarker(markerOptions);
}
mGoogleMap.addMarker(markerOptions);
mGoogleMap.animateCamera(CameraUpdateFactory.newLatLngZoom(pat_cur_latLng, 16));;
}
@@ -577,7 +645,7 @@ public class CgDashBoardFragment extends Fragment implements
@Override
public void onRoutinesFetched(List<RoutineDetails> routineList) {
viewModel.activityList = routineList;
CaregiverMainViewModel.activityList = routineList;
viewModel.getNearestActivity(routineList, this);
}

View File

@@ -6,6 +6,7 @@ import static com.app.simplitend.caregiverdashboard.activities.PatientProfileSho
import static com.app.simplitend.caregiverdashboard.activities.PatientProfileShowerActivity.MED_REMINDER_F;
import static com.app.simplitend.caregiverdashboard.activities.PatientProfileShowerActivity.WHICH_FRAGMENT;
import static com.app.simplitend.cg_geofencing.CgGeoFencingActivity.GEOFENCE_DETAILS_KEY;
import static com.app.simplitend.cg_subscription.SubscriptionWebViewActivity.EXTRA_CAREGIVER_XID;
import android.app.ProgressDialog;
import android.content.Intent;
@@ -32,6 +33,7 @@ import com.app.simplitend.caregiverdashboard.mvvm.CgHomeContracts;
import com.app.simplitend.caregiverdashboard.mvvm.models.GeoFenceDetails;
import com.app.simplitend.cg_geofencing.CgGeoFencingActivity;
import com.app.simplitend.cg_subscription.CgSubscriptionActivity;
import com.app.simplitend.cg_subscription.SubscriptionWebViewActivity;
import com.app.simplitend.databinding.MyPatientFragmentBinding;
import com.app.simplitend.welcome.welcomecg.mvvm.CareGiverData;
import com.bumptech.glide.Glide;
@@ -162,13 +164,20 @@ public class MyPatientFragment extends Fragment implements CgHomeContracts.GetGe
binding.phoneNumber.setOnClickListener(v -> {
if (careGiverData != null && careGiverData.patientDetails != null) {
AppUtil.dialPhone(requireActivity(), careGiverData.patientDetails.phone_number);
AppUtil.callPhone(requireActivity(), careGiverData.patientDetails.phone_number);
}
});
binding.subPlans.setOnClickListener(v -> {
Intent intent = new Intent(requireActivity(), CgSubscriptionActivity.class);
startActivity(intent);
// Intent intent = new Intent(requireActivity(), CgSubscriptionActivity.class);
// startActivity(intent);
CaregiverDataCache.getCaregiverData(requireContext(), careGiverData1 -> {
if (careGiverData1 == null) return;
Intent intent = new Intent(requireActivity(), SubscriptionWebViewActivity.class);
intent.putExtra(EXTRA_CAREGIVER_XID, careGiverData1.caregiver_xid);
startActivity(intent);
}, true);
});
}

View File

@@ -26,5 +26,8 @@ public interface NotificationApiService {
@Query("address") String address,
@Header("Authorization") String token);
@POST("api/battery-percentage")
Call<CallResponse<Object>> notifyBatteryLow(@Body Map<String, String> body,
@Header("Authorization") String token);
}

View File

@@ -1,5 +1,6 @@
package com.app.simplitend.cg_geofencing;
import static com.app.simplitend.apputils.RetrofitHelper.IMAGE_BASE_URL;
import static com.app.simplitend.patientgeofencing.PatientLocationUpdatesReceiver.LOCATION_REQUEST_TAG;
import android.app.Activity;
@@ -9,6 +10,7 @@ import android.content.Context;
import android.content.Intent;
import android.content.res.Configuration;
import android.graphics.Color;
import android.graphics.drawable.Drawable;
import android.location.Address;
import android.location.Geocoder;
import android.location.Location;
@@ -16,13 +18,17 @@ import android.os.Bundle;
import android.os.Handler;
import android.os.Looper;
import android.util.Log;
import android.util.Xml;
import android.view.View;
import android.widget.LinearLayout;
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.appcompat.app.AppCompatActivity;
import androidx.appcompat.content.res.AppCompatResources;
import androidx.lifecycle.ViewModelProvider;
import com.app.simplitend.BuildConfig;
@@ -31,12 +37,19 @@ import com.app.simplitend.apputils.AppUtil;
import com.app.simplitend.apputils.CaregiverDataCache;
import com.app.simplitend.caregiverdashboard.mvvm.CaregiverMainViewModel;
import com.app.simplitend.caregiverdashboard.mvvm.CgHomeContracts;
import com.app.simplitend.caregiverdashboard.mvvm.CgHomeRepository;
import com.app.simplitend.caregiverdashboard.mvvm.models.GeoFenceDetails;
import com.app.simplitend.chats.SocketHelper;
import com.app.simplitend.databinding.ActivityCgGeofencingBinding;
import com.app.simplitend.databinding.GeofenceBottomSheetBinding;
import com.app.simplitend.chats.SocketHelper;
import com.app.simplitend.databinding.MarkerBgBinding;
import com.app.simplitend.welcome.welcomecg.mvvm.CareGiverData;
import com.app.simplitend.welcome.welcomepatient.mvvm.models.PatientData;
import com.bumptech.glide.Glide;
import com.bumptech.glide.load.DataSource;
import com.bumptech.glide.load.engine.GlideException;
import com.bumptech.glide.request.RequestListener;
import com.bumptech.glide.request.target.Target;
import com.google.android.gms.maps.CameraUpdateFactory;
import com.google.android.gms.maps.GoogleMap;
import com.google.android.gms.maps.OnMapReadyCallback;
@@ -51,16 +64,24 @@ 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.google.android.material.bottomsheet.BottomSheetBehavior;
import com.google.android.material.bottomsheet.BottomSheetDialog;
import com.google.maps.android.ui.IconGenerator;
import com.stfalcon.chatkit.utils.DateFormatter;
import java.text.SimpleDateFormat;
import java.util.Arrays;
import java.util.Calendar;
import java.util.Date;
import java.util.HashMap;
import java.util.List;
import java.util.Locale;
import java.util.Map;
import java.util.Objects;
import java.util.TimeZone;
public class CgGeoFencingActivity extends AppCompatActivity implements OnMapReadyCallback,
CgHomeContracts.SaveGeoFenceCallback, CgHomeContracts.UpdatePatientAddressCallback {
CgHomeContracts.SaveGeoFenceCallback, CgHomeContracts.UpdatePatientAddressCallback, CgHomeContracts.GetGeoFenceCallback {
private static final String TAG = "CgGeoFencingActivity";
@@ -70,6 +91,7 @@ public class CgGeoFencingActivity extends AppCompatActivity implements OnMapRead
private CaregiverMainViewModel viewModel;
public static final String GEOFENCE_DETAILS_KEY = "geofence_details";
public static final String TO_SHOW_LOCATION_UPDATES_KEY = "to_show_location_updates";
private GeoFenceDetails geoFenceDetails;
private static final String MILES = "miles";
@@ -99,6 +121,10 @@ public class CgGeoFencingActivity extends AppCompatActivity implements OnMapRead
private String selectedStreet;
protected boolean showLocationUpdates;
private IconGenerator iconGenerator;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
@@ -118,6 +144,9 @@ public class CgGeoFencingActivity extends AppCompatActivity implements OnMapRead
} catch (Exception e) {
pat_cur_latLng = null;
}
showLocationUpdates = intent.getBooleanExtra(TO_SHOW_LOCATION_UPDATES_KEY, false);
} catch (Exception e) {
Toast.makeText(this, "Couldn't load Geofence.", Toast.LENGTH_SHORT).show();
geoFenceDetails = new GeoFenceDetails();
@@ -134,25 +163,183 @@ public class CgGeoFencingActivity extends AppCompatActivity implements OnMapRead
geofence_bs_binding = GeofenceBottomSheetBinding.inflate(getLayoutInflater());
geofence_bs_binding.unitSpinner.selectItemByIndex(1);
isTrackingSenior = false;
isTrackingSenior = showLocationUpdates;
CaregiverDataCache.getCaregiverData(this, (careGiverData -> {
if (careGiverData == null) return;
this.careGiverData = careGiverData;
this.patientData = careGiverData.patientDetails;
try {
if (patientData == null) throw new Exception();
double lat = Double.parseDouble(patientData.lat);
double lng = Double.parseDouble(patientData.lng);
mHomeLatLng = new LatLng(lat, lng);
if (patientData.profile_photo != null){
Glide.with(binding.patCurLoc)
.load(IMAGE_BASE_URL + patientData.profile_photo)
.error(R.drawable.img_pat_curr_location)
.placeholder(android.R.color.darker_gray)
.into(binding.patCurLoc);
}
} catch (Exception e) {
// do nothing
}
}), true);
initViews();
initBottomSheet();
if (!showLocationUpdates) {
initBottomSheet();
updatePatientCurrentLocationDetails();
}
clickEvents();
updatePatientCurrentLocationDetails();
establishSocketConnection();
if (showLocationUpdates){
changeToLocationUpdatesView();
}
}
private void changeToLocationUpdatesView() {
binding.seniorNameTitle.setVisibility(View.VISIBLE);
binding.lastUpdated.setVisibility(View.VISIBLE);
binding.geofencingSubTitle.setVisibility(View.GONE);
binding.geofencingTitle.setVisibility(View.GONE);
binding.updateGeofenceBox.setVisibility(View.GONE);
binding.homeLocationBtn.setVisibility(View.GONE);
binding.cgLocationBtn.setVisibility(View.GONE);
binding.locationBs.setVisibility(View.VISIBLE);
binding.refreshBtn.setVisibility(View.VISIBLE);
binding.refreshBtn.setOnClickListener(v -> {
progressDialog.setTitle("Please wait");
progressDialog.setMessage("while we refresh the details");
progressDialog.setCancelable(false);
progressDialog.show();
CaregiverDataCache.setCareGiverData(null);
CaregiverDataCache.getCaregiverData(this, careGiverData1 -> {
if (careGiverData1 != null && careGiverData1.patientDetails != null){
this.careGiverData = careGiverData1;
this.patientData = careGiverData.patientDetails;
try {
if (patientData == null) throw new Exception();
double lat = Double.parseDouble(patientData.lat);
double lng = Double.parseDouble(patientData.lng);
mHomeLatLng = new LatLng(lat, lng);
} catch (Exception e) {
// do nothing
}
CgHomeRepository.getHomeRepository().getGeoFenceDetails(AppUtil.getPatientUid(this) + "",
"", "Bearer " + AppUtil.getPatientToken(this),
this);
}
}, false);
});
BottomSheetBehavior<LinearLayout> bs_behavior = BottomSheetBehavior.from(binding.locationBs);
bs_behavior.setState(BottomSheetBehavior.STATE_EXPANDED);
CaregiverDataCache.getCaregiverData(this, careGiverData1 -> {
if (careGiverData1 != null && careGiverData1.patientDetails != null){
this.careGiverData = careGiverData1;
binding.seniorNameTitle.setText(careGiverData.patientDetails.first_name);
if (geoFenceDetails != null && geoFenceDetails.patient_radius_location != null){
String lastUpdatedTime;
try {
SimpleDateFormat inputSdf = new SimpleDateFormat("yyyy-MM-dd'T'HH:mm:ss.SSSSSS'Z'", Locale.getDefault());
inputSdf.setTimeZone(TimeZone.getTimeZone("UTC"));
Date lastUpdateDate = Objects.requireNonNull(inputSdf.parse(geoFenceDetails.patient_radius_location.updated_at));
if (DateFormatter.isToday(lastUpdateDate)){
lastUpdatedTime = "Last updated at " + DateFormatter.format(lastUpdateDate, "hh:mm a");
}else if (DateFormatter.isYesterday(lastUpdateDate)) {
lastUpdatedTime = "Last updated yesterday at " + DateFormatter.format(lastUpdateDate, "hh:mm a");
}else{
lastUpdatedTime = "Last updated on " + DateFormatter.format(lastUpdateDate, "dd MMM yyyy") + " at " + DateFormatter.format(lastUpdateDate, "hh:mm a");
}
} catch (Exception e) {
lastUpdatedTime = geoFenceDetails.patient_radius_location.updated_at;
}
binding.lastUpdated.setText(lastUpdatedTime);
}else{
binding.lastUpdated.setText("Last updated data nnt available");
}
Glide.with(this)
.load(IMAGE_BASE_URL + careGiverData1.patientDetails.profile_photo)
.error(R.drawable.senior_img)
.placeholder(android.R.color.darker_gray)
.into(binding.bsSeniorImage);
binding.bsSeniorName.setText(patientData.first_name);
}
}, true);
}
private void updateCurrentLocationBs() {
if (pat_cur_latLng != null && mHomeLatLng != null){
Location homeLocation = new Location("Home");
homeLocation.setLatitude(mHomeLatLng.latitude);
homeLocation.setLongitude(mHomeLatLng.longitude);
Location cureLocation = new Location("current");
cureLocation.setLatitude(pat_cur_latLng.latitude);
cureLocation.setLongitude(pat_cur_latLng.longitude);
float distance = homeLocation.distanceTo(cureLocation);
if (distance > 50){
distance = distance/1609; // meters to miles
binding.bsDistanceFromHome.setVisibility(View.VISIBLE);
binding.bsDistanceFromHome.setText(String.format(Locale.getDefault(), "%.2f miles away from home", distance));
binding.bsSeniorCurrentLocationTxt.setVisibility(View.VISIBLE);
Geocoder geocoder = new Geocoder(this);
try {
List<Address> addresses = geocoder.getFromLocation(cureLocation.getLatitude(), cureLocation.getLongitude(), 1);
if (addresses == null || addresses.isEmpty()) throw new Exception();
String location = addresses.get(0).getThoroughfare();
if (location == null || location.isEmpty()){
location = "Unknown";
}else{
location = "At " + location;
}
binding.bsSeniorCurrentLocationTxt.setText(location);
} catch (Exception e) {
binding.bsSeniorCurrentLocationTxt.setText("No location data");
}
}else{
binding.bsSeniorCurrentLocationTxt.setVisibility(View.GONE);
binding.bsDistanceFromHome.setText("At home");
}
}else {
binding.bsSeniorCurrentLocationTxt.setText("No location data");
binding.bsDistanceFromHome.setVisibility(View.GONE);
}
}
@Override
@@ -192,6 +379,10 @@ public class CgGeoFencingActivity extends AppCompatActivity implements OnMapRead
pat_cur_latLng = new LatLng(result.getLatitude(), result.getLongitude());
updateCurrentLocationPatientMarker();
updatePatientCurrentLocationDetails();
updateCurrentLocationBs();
// last updated at
binding.lastUpdated.setText(String.format("Last updated at %s", new SimpleDateFormat("hh:mm a", Locale.getDefault()).format(Calendar.getInstance().getTime())));
});
}
}
@@ -539,10 +730,16 @@ public class CgGeoFencingActivity extends AppCompatActivity implements OnMapRead
public void onMapReady(@NonNull GoogleMap googleMap) {
this.mMap = googleMap;
loadPatientsLocation();
if (!showLocationUpdates) {
loadPatientsLocation();// remove this if to also show patient home location along with geofence radius
}
updateCurrentLocationPatientMarker();
if (showLocationUpdates){
updateCurrentLocationBs();
}
mMap.setOnMapClickListener(latLng1 -> {
if (binding.search.getVisibility() != View.VISIBLE) {
// search bar is not visible
@@ -580,6 +777,10 @@ public class CgGeoFencingActivity extends AppCompatActivity implements OnMapRead
updateHomeMarker(this.mHomeLatLng);
addRadius();
});
if (showLocationUpdates && pat_cur_latLng != null){
mMap.animateCamera(CameraUpdateFactory.newLatLngZoom(pat_cur_latLng, 17));
}
}
private void updateCurrentLocationPatientMarker() {
@@ -588,14 +789,48 @@ public class CgGeoFencingActivity extends AppCompatActivity implements OnMapRead
if (patientData != null) name = patientData.first_name;
else name = "Senior's location";
MarkerOptions options = new MarkerOptions()
final MarkerOptions options = new MarkerOptions()
.position(pat_cur_latLng)
.icon(BitmapDescriptorFactory.fromResource(R.drawable.img_pat_curr_location))
.title(name)
.draggable(false);
if (patientData != null && patientData.profile_photo != null) {
if (curr_loc_marker != null) curr_loc_marker.remove();
curr_loc_marker = mMap.addMarker(options);
MarkerBgBinding markerBgBinding = MarkerBgBinding.inflate(getLayoutInflater());
Glide.with(this)
.load(IMAGE_BASE_URL + patientData.profile_photo)
.error(R.drawable.img_pat_curr_location)
.placeholder(android.R.color.darker_gray)
.addListener(new RequestListener<Drawable>() {
@Override
public boolean onLoadFailed(@Nullable GlideException e, Object model, Target<Drawable> target, boolean isFirstResource) {
options.icon(BitmapDescriptorFactory.fromResource(R.drawable.img_pat_curr_location));
if (curr_loc_marker != null) curr_loc_marker.remove();
curr_loc_marker = mMap.addMarker(options);
return false;
}
@Override
public boolean onResourceReady(Drawable resource, Object model, Target<Drawable> target, DataSource dataSource, boolean isFirstResource) {
if (iconGenerator == null) {
iconGenerator = new IconGenerator(CgGeoFencingActivity.this);
markerBgBinding.markerBgImage.setImageDrawable(resource);
iconGenerator.setContentView(markerBgBinding.getRoot());
iconGenerator.setBackground(AppCompatResources.getDrawable(CgGeoFencingActivity.this, android.R.color.transparent));
}
options.icon(BitmapDescriptorFactory.fromBitmap(iconGenerator.makeIcon()));
if (curr_loc_marker != null) curr_loc_marker.remove();
curr_loc_marker = mMap.addMarker(options);
return false;
}
})
.into(markerBgBinding.markerBgImage);
} else {
options.icon(BitmapDescriptorFactory.fromResource(R.drawable.img_pat_curr_location));
if (curr_loc_marker != null) curr_loc_marker.remove();
curr_loc_marker = mMap.addMarker(options);
}
if (isTrackingSenior) {
mMap.animateCamera(CameraUpdateFactory.newLatLng(pat_cur_latLng));
@@ -617,7 +852,7 @@ public class CgGeoFencingActivity extends AppCompatActivity implements OnMapRead
updateHomeMarker(home_lat_lng);
addRadius();
mMap.moveCamera(CameraUpdateFactory.newLatLngZoom(home_lat_lng, 14));
mMap.moveCamera(CameraUpdateFactory.newLatLngZoom(home_lat_lng, 17));
} catch (Exception e) {
// near marine drive
Toast.makeText(this, "Couldn't load home location", Toast.LENGTH_SHORT).show();
@@ -650,7 +885,7 @@ public class CgGeoFencingActivity extends AppCompatActivity implements OnMapRead
if (home_loc_marker != null) home_loc_marker.remove();
home_loc_marker = mMap.addMarker(markerOptions);
mMap.animateCamera(CameraUpdateFactory.newLatLngZoom(home_latLng, 14));
mMap.animateCamera(CameraUpdateFactory.newLatLngZoom(home_latLng, 17));
}
private void registerMapSearchResultLauncher() {
@@ -750,4 +985,44 @@ public class CgGeoFencingActivity extends AppCompatActivity implements OnMapRead
progressDialog.dismiss();
Toast.makeText(this, "Couldn't update patient's location.", Toast.LENGTH_SHORT).show();
}
@Override
public void onGeofenceDetailsFetched(GeoFenceDetails geoFenceDetails) {
progressDialog.dismiss();
updateCurrentLocationPatientMarker();
// updatePatientCurrentLocationDetails(); for also showing patient home location along with geofence radius
if (showLocationUpdates){
updateCurrentLocationBs();
// last updated at
if (geoFenceDetails != null && geoFenceDetails.patient_radius_location != null){
String lastUpdatedTime;
try {
SimpleDateFormat inputSdf = new SimpleDateFormat("yyyy-MM-dd'T'HH:mm:ss.SSSSSS'Z'", Locale.getDefault());
inputSdf.setTimeZone(TimeZone.getTimeZone("UTC"));
Date lastUpdateDate = Objects.requireNonNull(inputSdf.parse(geoFenceDetails.patient_radius_location.updated_at));
if (DateFormatter.isToday(lastUpdateDate)){
lastUpdatedTime = "Last updated at " + DateFormatter.format(lastUpdateDate, "hh:mm a");
}else if (DateFormatter.isYesterday(lastUpdateDate)) {
lastUpdatedTime = "Last updated yesterday at " + DateFormatter.format(lastUpdateDate, "hh:mm a");
}else{
lastUpdatedTime = "Last updated on " + DateFormatter.format(lastUpdateDate, "dd MMM yyyy") + " at " + DateFormatter.format(lastUpdateDate, "hh:mm a");
}
} catch (Exception e) {
lastUpdatedTime = geoFenceDetails.patient_radius_location.updated_at;
}
binding.lastUpdated.setText(lastUpdatedTime);
}else{
binding.lastUpdated.setText("Last updated data nnt available");
}
}
}
@Override
public void onGeofenceDetailsFetchFailed(Throwable throwable, String message) {
progressDialog.dismiss();
Toast.makeText(this, "Couldn't load senior's current location", Toast.LENGTH_SHORT).show();
}
}

View File

@@ -1,5 +1,7 @@
package com.app.simplitend.cg_subscription;
import static com.app.simplitend.cg_subscription.SubscriptionWebViewActivity.EXTRA_CAREGIVER_XID;
import android.app.ProgressDialog;
import android.content.Context;
import android.content.Intent;
@@ -7,14 +9,12 @@ import android.content.res.Configuration;
import android.net.Uri;
import android.os.Bundle;
import android.text.Html;
import android.text.SpannableString;
import android.text.Spanned;
import android.text.method.LinkMovementMethod;
import android.text.style.ClickableSpan;
import android.util.Log;
import android.view.View;
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.appcompat.app.AppCompatActivity;
@@ -63,6 +63,8 @@ public class CgSubscriptionActivity extends AppCompatActivity
private String current_subscription_plan_id;
private ActivityResultLauncher<Intent> webViewLauncher;
@Override
protected void onCreate(@Nullable Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
@@ -85,7 +87,7 @@ public class CgSubscriptionActivity extends AppCompatActivity
paymentSheet = new PaymentSheet(this, this::onPaymentSheetResult);
} else {
// Already subscribed thus, loading current plans
loadCurrentPlans();
// loadCurrentPlans();
}
} else {
binding.plansView.setVisibility(View.GONE);
@@ -95,6 +97,19 @@ public class CgSubscriptionActivity extends AppCompatActivity
// selecting default yearly pack
binding.yearCheck.setSelected(true);
webViewLauncher = registerForActivityResult(new ActivityResultContracts.StartActivityForResult(),
result -> {
CaregiverDataCache.setCareGiverData(null);
CaregiverDataCache.getCaregiverData(this, careGiverData1 -> {
if (careGiverData1 != null && careGiverData1.isCaregiverTakeSubscription == 1){
Intent intent = new Intent(this, CgProfileProgressActivity.class);
intent.setFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP);
startActivity(intent);
finish();
}
}, true);
});
}
@Override
@@ -148,8 +163,7 @@ public class CgSubscriptionActivity extends AppCompatActivity
Toast.makeText(this, "Please try again later.", Toast.LENGTH_SHORT).show();
}
} else {
payForSubscription(); // uses payment sheet
// showCardDetailsWidget(); // uses custom elements
openWebViewForSubscription(careGiverData1.caregiver_xid);
}
} else {
Toast.makeText(this, "Couldn't load data", Toast.LENGTH_SHORT).show();
@@ -184,6 +198,12 @@ public class CgSubscriptionActivity extends AppCompatActivity
}
private void openWebViewForSubscription(int caregiver_xid) {
Intent intent = new Intent(this, SubscriptionWebViewActivity.class);
intent.putExtra(EXTRA_CAREGIVER_XID, caregiver_xid);
webViewLauncher.launch(intent);
}
private void cancelSubscription() {
if (current_subscription_plan_id == null){
Toast.makeText(this, "Please try again later.", Toast.LENGTH_SHORT).show();
@@ -200,6 +220,9 @@ public class CgSubscriptionActivity extends AppCompatActivity
this);
}
/*
This method is no more used as subscription is handled on website
*/
private void payForSubscription() {
if (careGiverData == null || subscriptionPlans == null) {
Toast.makeText(this, "Something went wrong", Toast.LENGTH_SHORT).show();
@@ -270,7 +293,9 @@ public class CgSubscriptionActivity extends AppCompatActivity
// loading subscription plans
progressDialog = new ProgressDialog(this);
binding.description.setText(getString(R.string.subscribe_description));
binding.description.setText(getString(R.string.proceed_to_the_payment_website_to_select_a_subscription_option_and_pay));
// binding.makePayment.setVisibility(View.VISIBLE);
binding.makePayment.setText(getString(R.string.proceed_to_website));
// try {
// String description = getString(R.string.subscribe_description);
@@ -482,7 +507,7 @@ public class CgSubscriptionActivity extends AppCompatActivity
private void inflatePlans() {
binding.makePayment.setVisibility(View.VISIBLE);
binding.makePayment.setText(getString(R.string.subscribe));
binding.makePayment.setText(getString(R.string.proceed_to_website));
binding.yourPlan.setVisibility(View.GONE);
@@ -496,11 +521,13 @@ public class CgSubscriptionActivity extends AppCompatActivity
});
binding.monthCard.setVisibility(View.VISIBLE);
binding.yearCheck.setSelected(true);
binding.monthCard.setSelected(true);
binding.monthCard.setOnClickListener(v -> {
if (!binding.monthCheck.isActivated()) {
binding.yearCheck.setSelected(false);
binding.monthCheck.setSelected(true);
}
// if (!binding.monthCheck.isActivated()) {
// binding.yearCheck.setSelected(false);
// binding.monthCheck.setSelected(true);
// }
});
try {
@@ -521,7 +548,7 @@ public class CgSubscriptionActivity extends AppCompatActivity
if (monthly_price == null || yearly_price == null) throw new Exception();
binding.yearDiscountedPrice.setText(yearly_price);
binding.yearDiscountedPrice.setText("$" + yearly_price);
binding.monthlyPrice.setText("$" + monthly_price);
BigDecimal TWELVE = new BigDecimal(12);

View File

@@ -0,0 +1,112 @@
package com.app.simplitend.cg_subscription;
import static com.app.simplitend.apputils.AppUtil.NOTIFICATION_ACTION;
import static com.app.simplitend.apputils.Constants.MEDICINE_TIME;
import static com.app.simplitend.apputils.Constants.NEW_SUBSCRIPTION;
import static com.app.simplitend.apputils.NotificationService.CONTENT_TYPE_KEY;
import androidx.annotation.Nullable;
import androidx.appcompat.app.AppCompatActivity;
import android.content.BroadcastReceiver;
import android.content.Context;
import android.content.Intent;
import android.content.IntentFilter;
import android.net.http.SslError;
import android.os.Bundle;
import android.util.Log;
import android.view.View;
import android.webkit.SslErrorHandler;
import android.webkit.WebResourceError;
import android.webkit.WebResourceRequest;
import android.webkit.WebResourceResponse;
import android.webkit.WebView;
import android.webkit.WebViewClient;
import android.widget.Toast;
import com.app.simplitend.BuildConfig;
import com.app.simplitend.R;
import com.app.simplitend.apputils.AppUtil;
import com.app.simplitend.apputils.CaregiverDataCache;
import com.app.simplitend.caregiverdashboard.activities.CgProfileProgressActivity;
import com.app.simplitend.databinding.ActivitySubscriptionWebviewBinding;
import java.util.HashMap;
import java.util.Map;
public class SubscriptionWebViewActivity extends AppCompatActivity {
private static final String TAG = "aditya_sub_web_view";
public static final String EXTRA_CAREGIVER_XID = "extra_caregiver_xid";
protected ActivitySubscriptionWebviewBinding binding;
private BroadcastReceiver paymentCompleteReceiver;
private int caregiver_xid;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
binding = ActivitySubscriptionWebviewBinding.inflate(getLayoutInflater());
setContentView(binding.getRoot());
caregiver_xid = getIntent().getIntExtra(EXTRA_CAREGIVER_XID, -1);
paymentCompleteReceiver = new BroadcastReceiver() {
@Override
public void onReceive(Context context, Intent intent) {
if (intent != null){
String content_type = intent.getStringExtra(CONTENT_TYPE_KEY);
if (NEW_SUBSCRIPTION.equals(content_type)){
CaregiverDataCache.setCareGiverData(null);
CaregiverDataCache.getCaregiverData(SubscriptionWebViewActivity.this, careGiverData1 -> {
if (careGiverData1 != null && careGiverData1.isCaregiverTakeSubscription == 1){
setResult(RESULT_OK, null, null);
SubscriptionWebViewActivity.this.finish();
}
}, true);
}
}
}
};
registerReceiver(paymentCompleteReceiver, new IntentFilter(NOTIFICATION_ACTION));
loadUrl();
}
@Override
protected void onDestroy() {
super.onDestroy();
unregisterReceiver(paymentCompleteReceiver);
}
private void loadUrl() {
if (caregiver_xid == -1){
Toast.makeText(this, "Something went wrong, please try again later", Toast.LENGTH_SHORT).show();
return;
}
binding.progressBar.setVisibility(View.VISIBLE);
binding.webView.getSettings().setJavaScriptEnabled(true);
binding.webView.getSettings().setBuiltInZoomControls(true);
binding.webView.getSettings().setDisplayZoomControls(false);
binding.webView.setWebViewClient(new WebViewClient(){
@Override
public void onPageCommitVisible(WebView view, String url) {
super.onPageCommitVisible(view, url);
binding.progressBar.setVisibility(View.GONE);
}
});
Map<String, String> headers = new HashMap<>();
headers.put("Authorization", "Bearer " + AppUtil.getCgToken(this));
binding.webView.loadUrl(BuildConfig.SIMPLITEND_BASE_URL + "my-profile-ios?caregiver_xid="+caregiver_xid , headers);
}
}

View File

@@ -9,6 +9,7 @@ import com.app.simplitend.R;
import com.app.simplitend.apputils.AppUtil;
import com.app.simplitend.apputils.CaregiverDataCache;
import com.app.simplitend.apputils.Constants;
import com.app.simplitend.apputils.PatientDataCache;
import com.app.simplitend.apputils.RetrofitHelper;
import com.onesignal.OneSignal;
import com.onesignal.notifications.INotificationLifecycleListener;
@@ -18,43 +19,85 @@ import org.json.JSONObject;
public class ChatsActivity extends AppCompatActivity implements INotificationLifecycleListener {
public static final String IS_CHATS_FOR_PATIENT = "chats_for_extra";
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_chats);
CaregiverDataCache.getCaregiverData(this, (careGiverData1 -> {
if (careGiverData1 != null && careGiverData1.patientDetails != null){
boolean isPatient = getIntent().getBooleanExtra(IS_CHATS_FOR_PATIENT, false);
String sender_image;
if (careGiverData1.profile_photo == null){
sender_image = String.valueOf(R.drawable.caregiver_img);
}else{
sender_image = RetrofitHelper.IMAGE_BASE_URL + careGiverData1.profile_photo;
if (isPatient){
PatientDataCache.getPatientData(this, (patientData -> {
if (patientData != null){
try {
String sender_image;
if (patientData.profile_photo == null){
sender_image = String.valueOf(R.drawable.senior_img);
}else{
sender_image = RetrofitHelper.IMAGE_BASE_URL + patientData.profile_photo;
}
String receiver_image;
if (patientData.caregiver_profile_photo == null){
receiver_image = String.valueOf(R.drawable.caregiver_img);
}else{
receiver_image = RetrofitHelper.IMAGE_BASE_URL + patientData.caregiver_profile_photo;
}
getSupportFragmentManager().beginTransaction()
.add(R.id.chats_fcv, new ChatFragment(
patientData.id + "",
patientData.caregiver_iamprincipal_id,
patientData.link_id,
patientData.caregiver_iamprincipal_id,
patientData.first_name,
patientData.caregiver_name,
sender_image,
receiver_image
), "patient_chat")
.commitAllowingStateLoss();
} catch (Exception e) {
// do nothing
}
}
}), true);
}else{
CaregiverDataCache.getCaregiverData(this, (careGiverData1 -> {
if (careGiverData1 != null && careGiverData1.patientDetails != null){
String receiver_image;
if (careGiverData1.patientDetails.profile_photo == null){
receiver_image = String.valueOf(R.drawable.senior_img);
String sender_image;
if (careGiverData1.profile_photo == null){
sender_image = String.valueOf(R.drawable.caregiver_img);
}else{
sender_image = RetrofitHelper.IMAGE_BASE_URL + careGiverData1.profile_photo;
}
String receiver_image;
if (careGiverData1.patientDetails.profile_photo == null){
receiver_image = String.valueOf(R.drawable.senior_img);
}else{
receiver_image = RetrofitHelper.IMAGE_BASE_URL + careGiverData1.patientDetails.profile_photo;
}
getSupportFragmentManager().beginTransaction()
.add(R.id.chats_fcv, new ChatFragment(
careGiverData1.id + "",
careGiverData1.patientDetails.id + "",
careGiverData1.link_id,
careGiverData1.patientDetails.id + "",
careGiverData1.first_name,
careGiverData1.patientDetails.first_name,
sender_image,
receiver_image), "chat")
.commitAllowingStateLoss();
}else{
receiver_image = RetrofitHelper.IMAGE_BASE_URL + careGiverData1.patientDetails.profile_photo;
finish();
}
getSupportFragmentManager().beginTransaction()
.add(R.id.chats_fcv, new ChatFragment(
careGiverData1.caregiver_xid + "",
careGiverData1.patientId + "",
careGiverData1.link_id,
careGiverData1.patientDetails.id + "",
careGiverData1.first_name,
careGiverData1.patientDetails.first_name,
sender_image,
receiver_image), "chat")
.commitAllowingStateLoss();
}else{
finish();
}
}), true);
}), true);
}
OneSignal.getNotifications().addForegroundLifecycleListener(this);

View File

@@ -1,5 +1,10 @@
package com.app.simplitend.chats;
import static com.app.simplitend.apputils.AppUtil.NOTIFICATION_ACTION;
import static com.app.simplitend.apputils.NotificationService.CONTENT_TYPE_KEY;
import android.content.Context;
import android.content.Intent;
import android.location.Location;
import android.util.Log;
@@ -7,6 +12,8 @@ import androidx.annotation.NonNull;
import androidx.annotation.Nullable;
import com.app.simplitend.BuildConfig;
import com.app.simplitend.apputils.Constants;
import com.app.simplitend.caregiverdashboard.mvvm.CaregiverMainViewModel;
import com.app.simplitend.chats.mvvm.Author;
import com.app.simplitend.chats.mvvm.Message;
import com.app.simplitend.chats.mvvm.Receiver;
@@ -203,10 +210,42 @@ public class SocketHelper {
});
}
public void sendUpdates(String uniqueId, String contentType){
if (mSocket != null){
mSocket.emit("medActivity", contentType, uniqueId);
}
}
public void removeLocationUpdateListener(String patientId) {
mSocket.off(LOCATION_EVENT_PREFIX+patientId);
}
public void initializeSocket(Context context, String uniqueKey) {
mSocket.on(uniqueKey, args -> {
try {
if (args.length >= 1) {
String content_type = (String) args[0];
Log.d(TAG, "call: " + content_type);
Intent broadcastIntent = new Intent(NOTIFICATION_ACTION);
if ("0".equals(content_type)){
// medications
CaregiverMainViewModel.remindersList = null;
broadcastIntent.putExtra(CONTENT_TYPE_KEY, Constants.MEDICINE_TIME);
}else if ("1".equals(content_type)){
// activities
CaregiverMainViewModel.activityList = null;
broadcastIntent.putExtra(CONTENT_TYPE_KEY, Constants.ACTIVITY_TIME);
}
context.sendBroadcast(broadcastIntent);
}
} catch (Exception e) {
// do nothing
Log.d(TAG, "initializeSocket: ");
}
});
}
public interface Callback<T> {
void onMessageReceived(T result);
void onMessageSentSuccessfully();

View File

@@ -96,7 +96,7 @@ public class HomeBottomNav extends FrameLayout {
bottomNavigationCountTxt.setVisibility(GONE);
}else{
bottomNavigationCountTxt.setVisibility(VISIBLE);
bottomNavigationCountTxt.setText(count + "");
// bottomNavigationCountTxt.setText(count + "");
}
}

View File

@@ -1,6 +1,7 @@
package com.app.simplitend.locationupdates;
import static android.content.Intent.ACTION_BATTERY_CHANGED;
import static com.app.simplitend.apputils.NotificationService.CONTENT_TYPE_KEY;
import static com.app.simplitend.patientgeofencing.GeoFenceHelper.GEOFENCE_TAG;
import static com.app.simplitend.patientgeofencing.PatientLocationUpdatesReceiver.LOCATION_EXTRA_KEY;
import static com.app.simplitend.patientgeofencing.PatientLocationUpdatesReceiver.LOCATION_REQUEST_TAG;
@@ -20,10 +21,13 @@ import android.util.Log;
import androidx.annotation.NonNull;
import androidx.annotation.Nullable;
import androidx.core.app.NotificationCompat;
import androidx.core.app.NotificationManagerCompat;
import com.app.simplitend.BuildConfig;
import com.app.simplitend.R;
import com.app.simplitend.apputils.AppUtil;
import com.app.simplitend.apputils.BottomNotificationActivity;
import com.app.simplitend.apputils.Constants;
import com.app.simplitend.apputils.RetrofitHelper;
import com.app.simplitend.caregiverdashboard.mvvm.NotificationApiService;
import com.app.simplitend.chats.SocketHelper;
@@ -47,12 +51,15 @@ public class LocationService extends Service implements LocationClient.DefaultLo
public static final String ACTION_START_LOCATION_UPDATES = "com.simplitent.action_start_lu";
public static final String ACTION_STOP_LOCATION_UPDATES = "com.simplitent.action.stop_lu";
public static final String LOCATION_NOTIFICATION_CHANNEL_ID = "location";
public static final String FOOD_REMINDER_NOTIFICATION_CHANNEL_ID = "food_reminder_channel";
public static final String LOCATION_UPDATE_MIN_INTERVAL = "min_interval";
public static final int LOCATION_INTERVAL_BASE_TIME = 25 * 1000;
private static final int LOCATION_UPDATES_NOTIFICATION_ID = 112;
private static final int SENIOR_BATTERY_LOW_NOTIFICATION_ID = 2102;
public static final String EXTRA_BATTERY_PERCENTAGE = "extra_battery_percentage";
private DefaultLocationClient locationClient;
@@ -75,6 +82,17 @@ public class LocationService extends Service implements LocationClient.DefaultLo
int scale = intent.getIntExtra(BatteryManager.EXTRA_SCALE, -1);
float batteryPct = level * 100 / (float)scale;
if (batteryPct <= 25){
notifyPatientAboutBatteryLow(context, batteryPct);
notifyCaregiver(context, batteryPct);
}else{
AppUtil.setBatteryLowNotificationSent(context, false);
AppUtil.setBatteryLowNotificationShown(context, false);
}
}
}
};
@@ -86,6 +104,57 @@ public class LocationService extends Service implements LocationClient.DefaultLo
}
}
private void notifyPatientAboutBatteryLow(Context context, float batteryPct) {
if (AppUtil.isBatteryLowNotificationShown(context)) return;
Notification notification = new Notification.Builder(context, LOCATION_NOTIFICATION_CHANNEL_ID)
.setContentTitle(batteryPct + "% phone battery remaining")
.setContentText("Connect to charger soon")
.setSmallIcon(R.mipmap.ic_launcher_round)
.setOnlyAlertOnce(true)
.setPriority(Notification.PRIORITY_HIGH)
.build();
NotificationManagerCompat.from(context).notify(SENIOR_BATTERY_LOW_NOTIFICATION_ID, notification);
AppUtil.setBatteryLowNotificationShown(context, true);
// showing bottom sheet
Intent intent = new Intent(this, BottomNotificationActivity.class);
intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
intent.putExtra(EXTRA_BATTERY_PERCENTAGE, (int) batteryPct);
intent.putExtra(CONTENT_TYPE_KEY, Constants.BATTERY_LOW);
startActivity(intent);
}
private void notifyCaregiver(Context context, float batteryPct) {
if (AppUtil.isBatteryLowNotificationSent(context)) return;
int[] chatsCred = AppUtil.getPatientGeofenceChatCred(context);
Map<String, String> body = new HashMap<>();
body.put("battery_perentage", batteryPct + "");
body.put("caregiver_xid", chatsCred[1] + "");
NotificationApiService apiService = RetrofitHelper.getRetrofit().create(NotificationApiService.class);
apiService.notifyBatteryLow(body, "Bearer " + AppUtil.getPatientToken(context))
.enqueue(new Callback<CallResponse<Object>>() {
@Override
public void onResponse(Call<CallResponse<Object>> call, Response<CallResponse<Object>> response) {
if (response.code() == 200){
AppUtil.setBatteryLowNotificationSent(context, true);
}else{
AppUtil.setBatteryLowNotificationSent(context, false);
}
}
@Override
public void onFailure(Call<CallResponse<Object>> call, Throwable t) {
AppUtil.setBatteryLowNotificationSent(context, false);
}
});
}
@Override
public int onStartCommand(Intent intent, int flags, int startId) {
if (intent != null && intent.getAction() != null) {
@@ -123,7 +192,7 @@ public class LocationService extends Service implements LocationClient.DefaultLo
.setOngoing(true)
.build();
NotificationManager notificationManager = (NotificationManager) getSystemService(NOTIFICATION_SERVICE);
// NotificationManager notificationManager = (NotificationManager) getSystemService(NOTIFICATION_SERVICE);
try {
locationClient.getLocationUpdates(minInterval, this);
@@ -132,7 +201,7 @@ public class LocationService extends Service implements LocationClient.DefaultLo
}
startForeground(LOCATION_UPDATES_NOTIFICATION_ID, notification);
notificationManager.notify(LOCATION_UPDATES_NOTIFICATION_ID, notification);
// notificationManager.notify(LOCATION_UPDATES_NOTIFICATION_ID, notification);
}
@Override
@@ -237,14 +306,14 @@ public class LocationService extends Service implements LocationClient.DefaultLo
}
int[] chatsCred = AppUtil.getPatientGeofenceChatCred(context);
if (chatsCred[0] == -1 || chatsCred[1] == -1 || chatsCred[2] == -1) {
if (chatsCred[3] == -1 || chatsCred[4] == -1 || chatsCred[2] == -1) {
Log.d(GEOFENCE_TAG, "notifyPatient: CANNOT SEND MESSAGE AS EITHER PAT_ID, CG_ID OR CHANNEL_ID IS NOT AVAILABLE");
return;
}
Log.d(GEOFENCE_TAG, "notifyPatient: " + chatsCred[2]);
// sending message
sendMessage(message, chatsCred[0], chatsCred[1], chatsCred[2], chatsCred[3]);
sendMessage(message, chatsCred[3], chatsCred[4], chatsCred[2], chatsCred[3]);
}
private void sendMessage(@NonNull String message, int patientId, int cg_id, int channel_id, int patient_principal_id) {

View File

@@ -0,0 +1,198 @@
package com.app.simplitend.patient_dashboard;
import static com.app.simplitend.callwhitelisting.CallService.CALL_UNBLOCKING_INTERVAL;
import static com.app.simplitend.callwhitelisting.CallUnBlockingWorker.CALL_BLOCKING_WORk;
import android.content.BroadcastReceiver;
import android.content.Context;
import android.content.Intent;
import android.os.Binder;
import android.os.Bundle;
import android.os.IBinder;
import android.telephony.TelephonyManager;
import android.util.Log;
import androidx.work.OneTimeWorkRequest;
import androidx.work.WorkManager;
import androidx.work.WorkRequest;
import com.app.simplitend.apputils.AppUtil;
import com.app.simplitend.callwhitelisting.CallUnBlockingWorker;
import com.google.i18n.phonenumbers.PhoneNumberUtil;
import com.google.i18n.phonenumbers.Phonenumber;
import java.lang.reflect.Method;
import java.util.Date;
import java.util.Set;
import java.util.concurrent.TimeUnit;
public class CallReceiver extends BroadcastReceiver {
private static final String TAG = "CallReceiver";
private static int lastState = TelephonyManager.CALL_STATE_IDLE;
private static Date callStartTime;
private static boolean isIncoming;
private static String savedNumber; //because the passed incoming is only valid in ringing
@Override
public void onReceive(Context context, Intent intent) {
if (intent.getExtras() == null) {
Log.d(TAG, "onReceive: EXTRAS ARE NULL");
return;
}
// logBundle(intent.getExtras());
String stateStr = intent.getExtras().getString(TelephonyManager.EXTRA_STATE);
String number = intent.getExtras().getString(TelephonyManager.EXTRA_INCOMING_NUMBER);
int state = 0;
if (TelephonyManager.EXTRA_STATE_IDLE.equals(stateStr)) {
state = TelephonyManager.CALL_STATE_IDLE;
} else if (TelephonyManager.EXTRA_STATE_OFFHOOK.equals(stateStr)) {
state = TelephonyManager.CALL_STATE_OFFHOOK;
} else if (TelephonyManager.EXTRA_STATE_RINGING.equals(stateStr)) {
state = TelephonyManager.CALL_STATE_RINGING;
}
onCallStateChanged(context, state, number);
}
protected void logBundle(Bundle bundle) {
if (bundle != null) {
for (String key : bundle.keySet()) {
Log.e(TAG, key + " : " + (bundle.get(key) != null ? bundle.get(key) : "NULL"));
}
}
}
//Derived classes should override these to respond to specific events of interest
protected void onIncomingCallStarted(Context ctx, String number, Date start) {
Log.d(TAG, "onIncomingCallStarted: " + number);
if (!AppUtil.isCallBlockingEnabled(ctx)) {
// senior has deactivated the call blocking feature
Log.d(TAG, "onIncomingCallStarted: CALL BLOCKING IS DEACTIVATED");
return;
}
try {
Phonenumber.PhoneNumber parsed_phone = PhoneNumberUtil.getInstance().parse(number, "US");
number = "+" + parsed_phone.getCountryCode() + parsed_phone.getNationalNumber();
} catch (Exception e) {
// do nothing
}
Log.d(TAG, "AFTER FORMATTING PHONE NUMBER -> " + number);
Set<String> white_contacts = AppUtil.getWhiteListedContacts(ctx);
Log.d(TAG, "WHITE LISTED CONTACTS -> " + white_contacts);
if (AppUtil.isUserSubscribed(ctx) && white_contacts != null && !white_contacts.contains(number)) {
disconnectCall();
Log.d(TAG, "CALL ENDED");
}
}
public void disconnectCall(){
try {
String serviceManagerName = "android.os.ServiceManager";
String serviceManagerNativeName = "android.os.ServiceManagerNative";
String telephonyName = "com.android.internal.telephony.ITelephony";
Class<?> telephonyClass;
Class<?> telephonyStubClass;
Class<?> serviceManagerClass;
Class<?> serviceManagerNativeClass;
Method telephonyEndCall;
Object telephonyObject;
Object serviceManagerObject;
telephonyClass = Class.forName(telephonyName);
telephonyStubClass = telephonyClass.getClasses()[0];
serviceManagerClass = Class.forName(serviceManagerName);
serviceManagerNativeClass = Class.forName(serviceManagerNativeName);
Method getService = // getDefaults[29];
serviceManagerClass.getMethod("getService", String.class);
Method tempInterfaceMethod = serviceManagerNativeClass.getMethod("asInterface", IBinder.class);
Binder tmpBinder = new Binder();
tmpBinder.attachInterface(null, "fake");
serviceManagerObject = tempInterfaceMethod.invoke(null, tmpBinder);
IBinder retbinder = (IBinder) getService.invoke(serviceManagerObject, "phone");
Method serviceMethod = telephonyStubClass.getMethod("asInterface", IBinder.class);
telephonyObject = serviceMethod.invoke(null, retbinder);
telephonyEndCall = telephonyClass.getMethod("endCall");
telephonyEndCall.invoke(telephonyObject);
} catch (Exception e) {
Log.e(TAG,
"FATAL ERROR: could not connect to telephony subsystem");
Log.e(TAG, "Exception object: " + e);
}
}
protected void onOutgoingCallStarted(Context ctx, String number, Date start) {
Log.d(TAG, "onOutgoingCallStarted: " + number);
if ("911".equals(number)){
Log.d(TAG, "CALLED 911");
WorkManager.getInstance(ctx).cancelAllWorkByTag(TAG);
WorkRequest workRequest = new OneTimeWorkRequest.Builder(CallUnBlockingWorker.class)
.setInitialDelay(CALL_UNBLOCKING_INTERVAL, TimeUnit.MINUTES)
.addTag(CALL_BLOCKING_WORk)
.build();
WorkManager.getInstance(ctx).enqueue(workRequest);
AppUtil.setIsCallBlockingEnabled(ctx, false);
Log.d(TAG, "CALL BLOCKING DISABLED");
}
}
protected void onIncomingCallEnded(Context ctx, String number, Date start, Date end) {
}
protected void onOutgoingCallEnded(Context ctx, String number, Date start, Date end) {
}
protected void onMissedCall(Context ctx, String number, Date start) {
}
//Deals with actual events
//Incoming call- goes from IDLE to RINGING when it rings, to OFFHOOK when it's answered, to IDLE when its hung up
//Outgoing call- goes from IDLE to OFFHOOK when it dials out, to IDLE when hung up
public void onCallStateChanged(Context context, int state, String number) {
if (lastState == state) {
//No change, debounce extras
return;
}
switch (state) {
case TelephonyManager.CALL_STATE_RINGING:
isIncoming = true;
callStartTime = new Date();
savedNumber = number;
onIncomingCallStarted(context, number, callStartTime);
break;
case TelephonyManager.CALL_STATE_OFFHOOK:
//Transition of ringing->offhook are pickups of incoming calls. Nothing done on them
if (lastState != TelephonyManager.CALL_STATE_RINGING) {
isIncoming = false;
callStartTime = new Date();
onOutgoingCallStarted(context, number, callStartTime);
}
break;
case TelephonyManager.CALL_STATE_IDLE:
//Went to idle- this is the end of a call. What type depends on previous state(s)
if (lastState == TelephonyManager.CALL_STATE_RINGING) {
//Ring but no pickup- a miss
onMissedCall(context, savedNumber, callStartTime);
} else if (isIncoming) {
onIncomingCallEnded(context, savedNumber, callStartTime, new Date());
} else {
onOutgoingCallEnded(context, savedNumber, callStartTime, new Date());
}
break;
}
lastState = state;
}
}

View File

@@ -1,5 +1,7 @@
package com.app.simplitend.patient_dashboard;
import static com.app.simplitend.apputils.AppUtil.NOTIFICATION_ACTION;
import static com.app.simplitend.apputils.NotificationService.CONTENT_TYPE_KEY;
import static com.app.simplitend.patientgeofencing.GeoFenceHelper.GEOFENCE_TAG;
import android.Manifest;
@@ -16,22 +18,35 @@ import android.util.Log;
import androidx.activity.result.ActivityResultLauncher;
import androidx.activity.result.contract.ActivityResultContracts;
import androidx.annotation.NonNull;
import androidx.annotation.Nullable;
import androidx.appcompat.app.AppCompatActivity;
import androidx.core.app.ActivityCompat;
import androidx.lifecycle.ViewModelProvider;
import com.app.simplitend.BuildConfig;
import com.app.simplitend.R;
import com.app.simplitend.apputils.AppUtil;
import com.app.simplitend.apputils.Constants;
import com.app.simplitend.apputils.PatientDataCache;
import com.app.simplitend.caregiverdashboard.mvvm.CgHomeContracts;
import com.app.simplitend.caregiverdashboard.mvvm.models.GeoFenceDetails;
import com.app.simplitend.patient_dashboard.foodreminders.FoodScheduler;
import io.socket.client.IO;
import io.socket.client.Socket;
public class DashBoardActivity extends AppCompatActivity implements CgHomeContracts.GetGeoFenceCallback {
private static final String TAG = "DashBoardActivity_SOCKET";
public static final String FOOD_REMINDERS = "food_reminders";
protected PatientMainViewModel viewModel;
protected ActivityResultLauncher<String> finePermissionLauncher;
private Socket mSocket;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
@@ -39,6 +54,8 @@ public class DashBoardActivity extends AppCompatActivity implements CgHomeContra
viewModel = new ViewModelProvider(this).get(PatientMainViewModel.class);
FoodScheduler.scheduleFoodReminders(this);
updateGeofenceDetails();
finePermissionLauncher = registerForActivityResult(new ActivityResultContracts.RequestPermission(),
@@ -60,6 +77,7 @@ public class DashBoardActivity extends AppCompatActivity implements CgHomeContra
finePermissionLauncher.launch(Manifest.permission.ACCESS_FINE_LOCATION);
}), null, null);
}
});
registerForActivityResult(new ActivityResultContracts.RequestPermission(),
@@ -75,15 +93,18 @@ public class DashBoardActivity extends AppCompatActivity implements CgHomeContra
RoleManager roleManager = getSystemService(RoleManager.class);
Intent i = roleManager.createRequestRoleIntent(RoleManager.ROLE_CALL_SCREENING);
startActivityForResult(i, 1214, null);
} else {
Intent intent = new Intent(TelecomManager.ACTION_CHANGE_DEFAULT_DIALER);
intent.putExtra(TelecomManager.EXTRA_CHANGE_DEFAULT_DIALER_PACKAGE_NAME, getPackageName());
startActivity(intent);
}else{
requestPermissions(new String[]{Manifest.permission.CALL_PHONE, Manifest.permission.READ_PHONE_STATE, Manifest.permission.ANSWER_PHONE_CALLS}, 1212);
}
}
}).launch(Manifest.permission.READ_CONTACTS);
PatientDataCache.getPatientData(this, patientData -> {
if (patientData == null) return;
String uniqueKey = patientData.caregiver_iamprincipal_id + "medActivity" + patientData.id;
initSocket(uniqueKey);
}, false);
}
@Override
@@ -94,6 +115,76 @@ public class DashBoardActivity extends AppCompatActivity implements CgHomeContra
super.attachBaseContext(newBase);
}
@Override
protected void onDestroy() {
super.onDestroy();
if (mSocket != null) {
mSocket.disconnect();
}
PatientMainViewModel.activityList = null;
PatientMainViewModel.remindersList = null;
}
@Override
protected void onActivityResult(int requestCode, int resultCode, @Nullable Intent data) {
super.onActivityResult(requestCode, resultCode, data);
Log.d(TAG, "onActivityResult: " + resultCode);
}
private void initSocket(String uniqueKey) {
if (mSocket != null) return;
try {
IO.Options options = new IO.Options();
options.forceNew = true;
options.reconnection = true;
mSocket = IO.socket(BuildConfig.SIMPLITEND_SOKCET_HOST, options);
mSocket.on(uniqueKey, args -> {
try {
if (args.length >= 1) {
String content_type = (String) args[0];
Log.d(TAG, "call: " + content_type);
Intent broadcastIntent = new Intent(NOTIFICATION_ACTION);
if ("0".equals(content_type)) {
// medications
PatientMainViewModel.remindersList = null;
broadcastIntent.putExtra(CONTENT_TYPE_KEY, Constants.MEDICINE_TIME);
} else if ("1".equals(content_type)) {
// activities
PatientMainViewModel.activityList = null;
broadcastIntent.putExtra(CONTENT_TYPE_KEY, Constants.ACTIVITY_TIME);
}
sendBroadcast(broadcastIntent);
}
} catch (Exception e) {
// do nothing
Log.d(TAG, "initializeSocket: ");
}
});
mSocket.on(Socket.EVENT_CONNECT, args -> {
Log.d(TAG, "Socket connected ");
});
mSocket.on(Socket.EVENT_DISCONNECT, args -> {
Log.d(TAG, "Socket disconnected ");
});
mSocket.on(Socket.EVENT_CONNECT_ERROR, args -> {
Exception e = (Exception) args[0];
Log.e(TAG, "call: ", e);
});
mSocket.connect();
} catch (Exception e) {
e.printStackTrace();
Log.e(TAG, "SocketHelper: ", e);
}
}
// saves the geofence details
private void updateGeofenceDetails() {
// retrieving geofence

View File

@@ -1,10 +1,13 @@
package com.app.simplitend.patient_dashboard;
import static com.app.simplitend.apputils.RetrofitHelper.IMAGE_BASE_URL;
import android.Manifest;
import android.content.Context;
import android.content.Intent;
import android.content.pm.PackageManager;
import android.content.res.Configuration;
import android.graphics.drawable.Drawable;
import android.location.Address;
import android.location.Geocoder;
import android.location.Location;
@@ -19,8 +22,10 @@ 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.annotation.RequiresPermission;
import androidx.appcompat.app.AppCompatActivity;
import androidx.appcompat.content.res.AppCompatResources;
import androidx.core.app.ActivityCompat;
import androidx.lifecycle.ViewModelProvider;
@@ -29,6 +34,12 @@ import com.app.simplitend.R;
import com.app.simplitend.apputils.AppUtil;
import com.app.simplitend.apputils.PatientDataCache;
import com.app.simplitend.databinding.ActivityDirectionToHomeBinding;
import com.app.simplitend.databinding.MarkerBgSmallBinding;
import com.bumptech.glide.Glide;
import com.bumptech.glide.load.DataSource;
import com.bumptech.glide.load.engine.GlideException;
import com.bumptech.glide.request.RequestListener;
import com.bumptech.glide.request.target.Target;
import com.google.android.gms.location.FusedLocationProviderClient;
import com.google.android.gms.location.LocationListener;
import com.google.android.gms.location.LocationRequest;
@@ -47,6 +58,7 @@ import com.google.android.material.bottomsheet.BottomSheetBehavior;
import com.google.maps.DirectionsApi;
import com.google.maps.GeoApiContext;
import com.google.maps.android.PolyUtil;
import com.google.maps.android.ui.IconGenerator;
import com.google.maps.model.DirectionsResult;
import com.google.maps.model.DirectionsRoute;
@@ -279,7 +291,52 @@ public class DirectionToHomeActivity extends AppCompatActivity
private void addMarkersToMap(DirectionsResult results, GoogleMap mMap) throws Exception {
pat_cur_lat = results.routes[0].legs[0].startLocation.lat;
pat_cur_lng = results.routes[0].legs[0].startLocation.lng;
mMap.addMarker(new MarkerOptions().position(new com.google.android.gms.maps.model.LatLng(results.routes[0].legs[0].startLocation.lat ,results.routes[0].legs[0].startLocation.lng)).title("Your location").icon(BitmapDescriptorFactory.fromResource(R.drawable.img_pat_curr_location)));
PatientDataCache.getPatientData(this, patientData -> {
MarkerOptions markerOptions = new MarkerOptions()
.position(new com.google.android.gms.maps.model.LatLng(results.routes[0].legs[0].startLocation.lat ,results.routes[0].legs[0].startLocation.lng))
.title("Your location");
if (patientData != null && patientData.profile_photo != null) {
MarkerBgSmallBinding markerBgBinding = MarkerBgSmallBinding.inflate(getLayoutInflater());
Glide.with(this)
.load(IMAGE_BASE_URL + patientData.profile_photo)
.error(R.drawable.img_pat_curr_location)
.placeholder(android.R.color.darker_gray)
.addListener(new RequestListener<Drawable>() {
@Override
public boolean onLoadFailed(@Nullable GlideException e, Object model, Target<Drawable> target, boolean isFirstResource) {
markerOptions.icon(BitmapDescriptorFactory.fromResource(R.drawable.img_pat_curr_location));
mGoogleMap.addMarker(markerOptions);
return false;
}
@Override
public boolean onResourceReady(Drawable resource, Object model, Target<Drawable> target, DataSource dataSource, boolean isFirstResource) {
try {
IconGenerator iconGenerator = new IconGenerator(DirectionToHomeActivity.this);
markerBgBinding.markerBgImage.setImageDrawable(resource);
iconGenerator.setContentView(markerBgBinding.getRoot());
iconGenerator.setBackground(AppCompatResources.getDrawable(DirectionToHomeActivity.this, android.R.color.transparent));
markerOptions.icon(BitmapDescriptorFactory.fromBitmap(iconGenerator.makeIcon()));
mGoogleMap.addMarker(markerOptions);
} catch (Exception e) {
markerOptions.icon(BitmapDescriptorFactory.fromResource(R.drawable.img_pat_curr_location));
mGoogleMap.addMarker(markerOptions);
}
return false;
}
})
.into(markerBgBinding.markerBgImage);
} else {
markerOptions.icon(BitmapDescriptorFactory.fromResource(R.drawable.img_pat_curr_location));
mGoogleMap.addMarker(markerOptions);
}
}, false);
mMap.addMarker(new MarkerOptions().position(new com.google.android.gms.maps.model.LatLng(results.routes[0].legs[0].endLocation.lat ,results.routes[0].legs[0].endLocation.lng)).title("Home location").icon(BitmapDescriptorFactory.fromResource(R.drawable.img_home_marker)));
}

View File

@@ -1,14 +1,17 @@
package com.app.simplitend.patient_dashboard;
import static com.app.simplitend.callwhitelisting.CallUnBlockingWorker.CALL_BLOCKING_WORk;
import static com.app.simplitend.caregiverdashboard.activities.deactivateacc.DeActivateAccountActivity.IS_PATIENT_KEY;
import androidx.appcompat.app.AppCompatActivity;
import androidx.work.WorkManager;
import android.app.ProgressDialog;
import android.content.Context;
import android.content.Intent;
import android.content.res.Configuration;
import android.os.Bundle;
import android.widget.CompoundButton;
import android.widget.Toast;
import com.onesignal.OneSignal;
@@ -57,6 +60,32 @@ public class PatSettingsActivity extends AppCompatActivity implements CgHomeCont
OneSignal.getUser().getPushSubscription().optOut();
}
});
binding.callBlockCheck.setChecked(AppUtil.isCallBlockingEnabled(this));
binding.callBlockCheck.setOnCheckedChangeListener(new CompoundButton.OnCheckedChangeListener() {
@Override
public void onCheckedChanged(CompoundButton compoundButton, boolean b) {
if (b){
AppUtil.setIsCallBlockingEnabled(PatSettingsActivity.this, true);
}else{
AppUtil.showAlert(PatSettingsActivity.this,
"Turn off call blocking",
"Are you sure you want turn off call blocking?",
"No", ((dialogInterface, i) -> {
dialogInterface.dismiss();
binding.callBlockCheck.setOnCheckedChangeListener(null);
binding.callBlockCheck.setChecked(true);
binding.callBlockCheck.setOnCheckedChangeListener(this);
WorkManager.getInstance(PatSettingsActivity.this)
.cancelAllWorkByTag(CALL_BLOCKING_WORk);
}),
"Turn off", ((dialogInterface, i) -> {
AppUtil.setIsCallBlockingEnabled(PatSettingsActivity.this, false);
}));
}
}
});
}
private void clickEvents() {

View File

@@ -0,0 +1,80 @@
package com.app.simplitend.patient_dashboard.foodreminders;
import static com.app.simplitend.patient_dashboard.foodreminders.FoodReminderYesReceiver.WHICH_FOOD_REMINDER;
import static com.app.simplitend.patient_dashboard.foodreminders.FoodScheduler.FOOD_REMINDER_NOTIFICATION_ID;
import android.app.NotificationManager;
import android.app.Service;
import android.content.Context;
import android.content.Intent;
import android.os.IBinder;
import android.util.Log;
import androidx.annotation.Nullable;
import com.app.simplitend.apputils.AppUtil;
import com.app.simplitend.apputils.RetrofitHelper;
import com.app.simplitend.welcome.welcomepatient.mvvm.models.CallResponse;
import java.util.HashMap;
import java.util.Map;
import retrofit2.Call;
import retrofit2.Callback;
import retrofit2.Response;
import retrofit2.http.Body;
import retrofit2.http.Header;
import retrofit2.http.POST;
public class FoodReminderNotifyingService extends Service {
private static final String TAG = "FoodScheduler";
@Nullable
@Override
public IBinder onBind(Intent intent) {
return null;
}
@Override
public int onStartCommand(Intent intent, int flags, int startId) {
int which_meal = -1;
if (intent != null) {
which_meal = intent.getIntExtra(WHICH_FOOD_REMINDER, -1);
}
if (which_meal != -1){
Log.d(TAG, "NO clicked for " + which_meal);
NotificationManager notificationManager = (NotificationManager) getSystemService(Context.NOTIFICATION_SERVICE);
notificationManager.cancel(FOOD_REMINDER_NOTIFICATION_ID + which_meal);
NotificationsApiService apiService = RetrofitHelper.getRetrofit().create(NotificationsApiService.class);
Map<String, Integer> body = new HashMap<>();
body.put("patient_id", AppUtil.getPatientUid(this));
body.put("meal_type", which_meal);
apiService.sendMealNotification("Bearer " + AppUtil.getPatientToken(this), body)
.enqueue(new Callback<CallResponse<Object>>() {
@Override
public void onResponse(Call<CallResponse<Object>> call, Response<CallResponse<Object>> response) {
Log.d(TAG, "onResponse: " + response);
}
@Override
public void onFailure(Call<CallResponse<Object>> call, Throwable t) {
Log.d(TAG, "onFailure: " + t);
}
});
}
return super.onStartCommand(intent, flags, startId);
}
public interface NotificationsApiService{
@POST("api/send-notification-to-caregiver-meals-time")
Call<CallResponse<Object>> sendMealNotification(@Header("Authorization") String token, @Body Map<String, Integer> body);
}
}

View File

@@ -0,0 +1,25 @@
package com.app.simplitend.patient_dashboard.foodreminders;
import static com.app.simplitend.patient_dashboard.foodreminders.FoodScheduler.FOOD_REMINDER_NOTIFICATION_ID;
import android.app.NotificationManager;
import android.content.BroadcastReceiver;
import android.content.Context;
import android.content.Intent;
import android.util.Log;
public class FoodReminderYesReceiver extends BroadcastReceiver {
private static final String TAG = "FoodScheduler";
public static final String WHICH_FOOD_REMINDER = "which_food_reminder";
@Override
public void onReceive(Context context, Intent intent) {
int which = intent.getIntExtra(WHICH_FOOD_REMINDER, -1);
if (which != -1){
Log.d(TAG, "YES clicked for : " + which);
NotificationManager notificationManager = (NotificationManager) context.getSystemService(Context.NOTIFICATION_SERVICE);
notificationManager.cancel(FOOD_REMINDER_NOTIFICATION_ID + which);
}
}
}

View File

@@ -0,0 +1,235 @@
package com.app.simplitend.patient_dashboard.foodreminders;
import static android.content.Context.NOTIFICATION_SERVICE;
import static com.app.simplitend.apputils.Constants.MEAL_REMINDER;
import static com.app.simplitend.apputils.NotificationService.CONTENT_TYPE_KEY;
import static com.app.simplitend.apputils.NotificationService.NOTIFICATION_TITLE_KEY;
import static com.app.simplitend.locationupdates.LocationService.FOOD_REMINDER_NOTIFICATION_CHANNEL_ID;
import static com.app.simplitend.patient_dashboard.foodreminders.FoodReminderYesReceiver.WHICH_FOOD_REMINDER;
import android.app.Notification;
import android.app.NotificationManager;
import android.app.PendingIntent;
import android.content.Context;
import android.content.Intent;
import android.util.Log;
import androidx.annotation.IntRange;
import androidx.annotation.NonNull;
import androidx.work.ExistingPeriodicWorkPolicy;
import androidx.work.ExistingWorkPolicy;
import androidx.work.OneTimeWorkRequest;
import androidx.work.PeriodicWorkRequest;
import androidx.work.WorkManager;
import androidx.work.Worker;
import androidx.work.WorkerParameters;
import com.app.simplitend.R;
import com.app.simplitend.apputils.BottomNotificationActivity;
import com.app.simplitend.patient_dashboard.PatientMainViewModel;
import java.util.Calendar;
import java.util.concurrent.TimeUnit;
public abstract class FoodScheduler {
private static final String TAG = "FoodScheduler";
public static final int FOOD_REMINDER_NOTIFICATION_ID = 512;
enum FOOD_TIME {
BREAK_FAST, LUNCH, DINNER
}
private final static Meal breakFastMeal, lunchMeal, dinnerMeal;
static {
breakFastMeal = new Meal(FOOD_TIME.BREAK_FAST, 9, 0);
lunchMeal = new Meal(FOOD_TIME.LUNCH, 13, 0);
dinnerMeal = new Meal(FOOD_TIME.DINNER, 20, 0);
}
public static void scheduleFoodReminders(Context context) {
//breakfast
scheduleAt(context, breakFastMeal.hours, breakFastMeal.minutes, FOOD_TIME.BREAK_FAST);
//lunch
scheduleAt(context, lunchMeal.hours, lunchMeal.minutes, FOOD_TIME.LUNCH);
//dinner
scheduleAt(context, dinnerMeal.hours, dinnerMeal.minutes, FOOD_TIME.DINNER);
}
public static void removeFoodReminders(Context context) {
WorkManager.getInstance(context).cancelAllWorkByTag(FOOD_TIME.BREAK_FAST.name());
WorkManager.getInstance(context).cancelAllWorkByTag(FOOD_TIME.LUNCH.name());
WorkManager.getInstance(context).cancelAllWorkByTag(FOOD_TIME.DINNER.name());
}
private static void scheduleAt(Context context, @IntRange(from = 0, to = 23) int hours, @IntRange(from = 0, to = 59) int minutes, FOOD_TIME foodTime) {
Class<? extends Worker> workClass = null;
switch (foodTime) {
case BREAK_FAST:
workClass = BreakFastWorker.class;
break;
case LUNCH:
workClass = LunchWorker.class;
break;
case DINNER:
workClass = DinnerWorker.class;
break;
}
if (workClass == null) return;
long nextReminderAt = nextReminderInMilliSeconds(hours, minutes);
// one shot work and then invoking another work for next day
OneTimeWorkRequest workRequest = new OneTimeWorkRequest.Builder(workClass)
.setInitialDelay(nextReminderAt, TimeUnit.MILLISECONDS)
.addTag(foodTime.name())
.build();
WorkManager.getInstance(context).enqueueUniqueWork(
foodTime.name(),
ExistingWorkPolicy.REPLACE,
workRequest
);
Log.d(TAG, "Next reminder in MILLISECONDS = " + nextReminderAt);
Log.d(TAG, "SCHEDULED " + foodTime.name() + " at " + hours + " hrs and " + minutes + " mins");
}
private static long nextReminderInMilliSeconds(int hour, int minutes) {
Calendar currCal = Calendar.getInstance();
Calendar reminderCal = Calendar.getInstance();
reminderCal.set(Calendar.HOUR_OF_DAY, hour);
reminderCal.set(Calendar.MINUTE, minutes);
reminderCal.set(Calendar.SECOND, 0);
reminderCal.set(Calendar.MILLISECOND, 0);
if (reminderCal.before(currCal)) {
// reminder time has already passed
// thus, reminder for next day
reminderCal.add(Calendar.DATE, 1);
}
return (reminderCal.getTimeInMillis() - currCal.getTimeInMillis());
}
private static void showNotification(Context context, String title, int which) {
Intent yesIntent = new Intent(context, FoodReminderYesReceiver.class);
yesIntent.putExtra(WHICH_FOOD_REMINDER, which);
Intent noIntent = new Intent(context, FoodReminderNotifyingService.class);
noIntent.putExtra(WHICH_FOOD_REMINDER, which);
Notification notification = new Notification.Builder(context, FOOD_REMINDER_NOTIFICATION_CHANNEL_ID)
.setContentTitle(title)
.setSmallIcon(R.mipmap.ic_launcher_round)
.addAction(new Notification.Action.Builder(null, "Yes", PendingIntent.getBroadcast(context, which, yesIntent, PendingIntent.FLAG_MUTABLE | PendingIntent.FLAG_UPDATE_CURRENT)).build())
.addAction(new Notification.Action.Builder(null, "No", PendingIntent.getService(context, which, noIntent, PendingIntent.FLAG_MUTABLE | PendingIntent.FLAG_UPDATE_CURRENT)).build())
.setPriority(Notification.PRIORITY_HIGH)
.build();
NotificationManager notificationManager = (NotificationManager) context.getSystemService(NOTIFICATION_SERVICE);
notificationManager.notify(FOOD_REMINDER_NOTIFICATION_ID + which, notification);
}
public static class BreakFastWorker extends Worker {
private final Context context;
public BreakFastWorker(@NonNull Context context, @NonNull WorkerParameters workerParams) {
super(context, workerParams);
this.context = context;
}
@NonNull
@Override
public Result doWork() {
scheduleAt(context, breakFastMeal.hours, breakFastMeal.minutes, FOOD_TIME.BREAK_FAST);
Log.d(TAG, "doWork: BREAK_FAST");
if (PatientMainViewModel.remindersList == null) {
// app is not open
showNotification(context, "Have you done your breakfast?", 0);
} else {
Intent intent = new Intent(context, BottomNotificationActivity.class);
intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
intent.putExtra(CONTENT_TYPE_KEY, MEAL_REMINDER);
intent.putExtra(WHICH_FOOD_REMINDER, 0);
intent.putExtra(NOTIFICATION_TITLE_KEY, "Did you have your breakfast?");
context.startActivity(intent);
}
return Result.success();
}
}
public static class LunchWorker extends Worker {
private final Context context;
public LunchWorker(@NonNull Context context, @NonNull WorkerParameters workerParams) {
super(context, workerParams);
this.context = context;
}
@NonNull
@Override
public Result doWork() {
scheduleAt(context, lunchMeal.hours, lunchMeal.minutes, FOOD_TIME.LUNCH);
if (PatientMainViewModel.remindersList == null) {
// app is not open
showNotification(context, "Have you done your lunch?", 1);
} else {
Intent intent = new Intent(context, BottomNotificationActivity.class);
intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
intent.putExtra(CONTENT_TYPE_KEY, MEAL_REMINDER);
intent.putExtra(WHICH_FOOD_REMINDER, 1);
intent.putExtra(NOTIFICATION_TITLE_KEY, "Did you have your lunch?");
context.startActivity(intent);
}
return Result.success();
}
}
public static class DinnerWorker extends Worker {
private final Context context;
public DinnerWorker(@NonNull Context context, @NonNull WorkerParameters workerParams) {
super(context, workerParams);
this.context = context;
}
@NonNull
@Override
public Result doWork() {
scheduleAt(context, dinnerMeal.hours, dinnerMeal.minutes, FOOD_TIME.DINNER);
if (PatientMainViewModel.remindersList == null) {
// app is not open
showNotification(context, "Have you done your dinner?", 2);
} else {
Intent intent = new Intent(context, BottomNotificationActivity.class);
intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
intent.putExtra(CONTENT_TYPE_KEY, MEAL_REMINDER);
intent.putExtra(WHICH_FOOD_REMINDER, 2);
intent.putExtra(NOTIFICATION_TITLE_KEY, "Did you have your dinner?");
context.startActivity(intent);
}
return Result.success();
}
}
static class Meal {
public Meal(FOOD_TIME foodTime, int hours, int minutes) {
this.foodTime = foodTime;
this.hours = hours;
this.minutes = minutes;
}
public FOOD_TIME foodTime;
public int hours, minutes;
}
}

View File

@@ -1,30 +1,31 @@
package com.app.simplitend.patient_dashboard.fragments;
import static com.app.simplitend.chats.ChatsActivity.IS_CHATS_FOR_PATIENT;
import android.Manifest;
import android.app.role.RoleManager;
import android.content.Context;
import android.content.Intent;
import android.content.pm.PackageManager;
import android.content.res.Configuration;
import android.os.Bundle;
import android.telecom.TelecomManager;
import android.view.View;
import android.widget.ImageButton;
import android.widget.TableLayout;
import android.widget.Toast;
import androidx.activity.result.ActivityResultLauncher;
import androidx.activity.result.contract.ActivityResultContracts;
import androidx.appcompat.app.AppCompatActivity;
import androidx.core.content.ContextCompat;
import androidx.recyclerview.widget.GridLayoutManager;
import androidx.recyclerview.widget.LinearLayoutManager;
import com.app.simplitend.R;
import com.app.simplitend.apputils.AppUtil;
import com.app.simplitend.chats.ChatsActivity;
import com.app.simplitend.databinding.ActivityCallsBinding;
import com.app.simplitend.databinding.CallListDialogBinding;
import com.app.simplitend.databinding.CreateContactViewHolderBinding;
import com.app.simplitend.welcome.welcomepatient.fragments.contacts.mvvm.AddContactAdapter;
import com.app.simplitend.welcome.welcomepatient.fragments.contacts.AddContactAdapter;
import com.app.simplitend.welcome.welcomepatient.fragments.contacts.mvvm.FiftyContactsAdapter;
import com.app.simplitend.welcome.welcomepatient.fragments.contacts.mvvm.models.ContactData;
import com.google.android.material.bottomsheet.BottomSheetDialog;
@@ -35,12 +36,18 @@ public class CallsActivity extends AppCompatActivity implements AddContactAdapte
protected ActivityCallsBinding binding;
public static final String CALL_CONTACT_LIST_KEY = "contact_list_key";
public static final String IS_50_CONTACTS_VIEW = "is_50_contacts_view";
protected AddContactAdapter contactAdapter;
protected FiftyContactsAdapter fiftyContactsAdapter;
protected ArrayList<ContactData> contactList;
private boolean is50ContactsView;
private String select_phone_number;
private ActivityResultLauncher<String> permissionLauncher;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
@@ -49,6 +56,15 @@ public class CallsActivity extends AppCompatActivity implements AddContactAdapte
contactList = (ArrayList<ContactData>) getIntent().getSerializableExtra(CALL_CONTACT_LIST_KEY);
is50ContactsView = getIntent().getBooleanExtra(IS_50_CONTACTS_VIEW, false);
permissionLauncher = registerForActivityResult(new ActivityResultContracts.RequestPermission(),
granted -> {
if (select_phone_number != null){
AppUtil.callPhone(this, select_phone_number);
}
});
initViews();
clickEvents();
@@ -68,15 +84,28 @@ public class CallsActivity extends AppCompatActivity implements AddContactAdapte
}
private void initViews() {
binding.contactRv.setLayoutManager(new GridLayoutManager(this, 2, LinearLayoutManager.VERTICAL, false));
contactAdapter = new AddContactAdapter();
binding.contactRv.setAdapter(contactAdapter);
contactAdapter.setContactClickListener(this);
if (!is50ContactsView) {
binding.contactRv.setLayoutManager(new GridLayoutManager(this, 2, LinearLayoutManager.VERTICAL, false));
contactAdapter = new AddContactAdapter();
binding.contactRv.setAdapter(contactAdapter);
contactAdapter.setContactClickListener(this);
if (contactList != null){
contactAdapter.submitList(contactList);
}else{
Toast.makeText(this, "Couldn't load contact list", Toast.LENGTH_SHORT).show();
if (contactList != null){
contactAdapter.submitList(contactList);
}else{
Toast.makeText(this, "Couldn't load contact list", Toast.LENGTH_SHORT).show();
}
} else {
binding.contactRv.setLayoutManager(new LinearLayoutManager(this));
fiftyContactsAdapter = new FiftyContactsAdapter();
binding.contactRv.setAdapter(fiftyContactsAdapter);
fiftyContactsAdapter.setContactClickListener(this);
if (contactList != null){
fiftyContactsAdapter.submitList(contactList);
}else{
Toast.makeText(this, "Couldn't load contact list", Toast.LENGTH_SHORT).show();
}
}
}
@@ -106,7 +135,7 @@ public class CallsActivity extends AppCompatActivity implements AddContactAdapte
return;
}
AppUtil.dialPhone(this, select_phone_number);
permissionLauncher.launch(Manifest.permission.CALL_PHONE);
});
dialogBinding.messageBtn.setOnClickListener(v -> {
@@ -115,7 +144,15 @@ public class CallsActivity extends AppCompatActivity implements AddContactAdapte
return;
}
AppUtil.messageNumber(this, select_phone_number);
if (contactData.care_giver_data.id != null){
Intent chatsIntent = new Intent(this, ChatsActivity.class);
chatsIntent.putExtra(IS_CHATS_FOR_PATIENT, true);
startActivity(chatsIntent);
}else{
// not a caregiver
AppUtil.messageNumber(this, select_phone_number);
}
});
bsd.show();

View File

@@ -2,6 +2,7 @@ package com.app.simplitend.patient_dashboard.fragments;
import static com.app.simplitend.appblocking.FUAActivity.IS_FROM_DASHBOARD;
import static com.app.simplitend.apputils.NotificationService.CONTENT_TYPE_KEY;
import static com.app.simplitend.callwhitelisting.CallService.CALL_UNBLOCKING_INTERVAL;
import static com.app.simplitend.callwhitelisting.CallUnBlockingWorker.CALL_BLOCKING_WORk;
import static com.app.simplitend.caregiverdashboard.activities.EditProfileInfoActivity.IS_CAREGIVER;
import static com.app.simplitend.patient_dashboard.DirectionToHomeActivity.LAT_KEY;
@@ -9,7 +10,9 @@ import static com.app.simplitend.patient_dashboard.DirectionToHomeActivity.LNG_K
import static com.app.simplitend.patient_dashboard.NotificationsActivity.USER_ID;
import static com.app.simplitend.patient_dashboard.NotificationsActivity.USER_TOKEN;
import static com.app.simplitend.patient_dashboard.fragments.CallsActivity.CALL_CONTACT_LIST_KEY;
import static com.app.simplitend.patient_dashboard.fragments.CallsActivity.IS_50_CONTACTS_VIEW;
import android.Manifest;
import android.app.Activity;
import android.app.AlertDialog;
import android.content.BroadcastReceiver;
@@ -25,6 +28,8 @@ 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;
@@ -68,6 +73,7 @@ import java.util.Calendar;
import java.util.Date;
import java.util.List;
import java.util.Locale;
import java.util.UUID;
import java.util.concurrent.TimeUnit;
public class PatientDashboardFragment extends Fragment implements ProfileContracts.GetRemindersListCallback, CaregiverMainViewModel.GetNearestResultCallback, ProfileContracts.GetRoutinesCallback, CaregiverMainViewModel.GetNearestActivityCallback, INotificationLifecycleListener {
@@ -86,6 +92,10 @@ public class PatientDashboardFragment extends Fragment implements ProfileContrac
private BroadcastReceiver notification_receiver;
private ActivityResultLauncher<String> callPermissionLauncher;
private String sos_phone_number = "911";
// date suffixes
String[] suffixes =
// 0 1 2 3 4 5 6 7 8 9
@@ -122,13 +132,28 @@ public class PatientDashboardFragment extends Fragment implements ProfileContrac
reminderViewModel = new ViewModelProvider(requireActivity()).get(ReminderViewModel.class);
routineViewModel = new ViewModelProvider(requireActivity()).get(RoutineViewModel.class);
callPermissionLauncher = registerForActivityResult(new ActivityResultContracts.RequestPermission(),
isGranted -> {
if (sos_phone_number == null) return;
AppUtil.callPhone(requireActivity(), sos_phone_number);
});
initViews();
clickEvents();
loadReminders();
if (PatientMainViewModel.remindersList == null){
loadReminders();
}else {
onRemindersListFetched(PatientMainViewModel.remindersList);
}
loadActivities();
if (PatientMainViewModel.activityList == null){
loadActivities();
}else {
onRoutinesFetched(PatientMainViewModel.activityList);
}
notification_receiver = new BroadcastReceiver() {
@Override
@@ -168,7 +193,8 @@ public class PatientDashboardFragment extends Fragment implements ProfileContrac
requireContext(),
cg_id,
channel_id,
patientData.id
patientData.id,
patientData.caregiver_iamprincipal_id == null?-1:Integer.parseInt(patientData.caregiver_iamprincipal_id)
);
}
@@ -198,6 +224,11 @@ public class PatientDashboardFragment extends Fragment implements ProfileContrac
OneSignal.getNotifications().addForegroundLifecycleListener(this);
Activity activity = getActivity();
if (activity != null) {
activity.registerReceiver(timeTickReceiver, new IntentFilter(Intent.ACTION_TIME_TICK));
}
return binding.getRoot();
}
@@ -206,6 +237,11 @@ public class PatientDashboardFragment extends Fragment implements ProfileContrac
super.onDestroyView();
requireContext().unregisterReceiver(notification_receiver);
OneSignal.getNotifications().removeForegroundLifecycleListener(this);
Activity activity = getActivity();
if (activity != null) {
activity.unregisterReceiver(timeTickReceiver);
}
}
private void setDetails() {
@@ -235,10 +271,6 @@ public class PatientDashboardFragment extends Fragment implements ProfileContrac
super.onResume();
updateTime();
updateNotificationsCount();
Activity activity = getActivity();
if (activity != null) {
activity.registerReceiver(timeTickReceiver, new IntentFilter(Intent.ACTION_TIME_TICK));
}
}
private void updateNotificationsCount() {
@@ -260,15 +292,6 @@ public class PatientDashboardFragment extends Fragment implements ProfileContrac
}
}
@Override
public void onPause() {
super.onPause();
Activity activity = getActivity();
if (activity != null) {
activity.unregisterReceiver(timeTickReceiver);
}
}
private void clickEvents() {
binding.refreshBtn.setOnClickListener(v -> {
showLoadingProgress(true);
@@ -311,8 +334,8 @@ public class PatientDashboardFragment extends Fragment implements ProfileContrac
getParentFragmentManager().beginTransaction()
.replace(R.id.fragmentContainerView, new ChatFragment(
patientData1.patientId + "",
patientData1.caregiverId,
patientData1.id + "",
patientData1.caregiver_iamprincipal_id,
patientData1.link_id,
patientData1.caregiver_iamprincipal_id,
patientData1.first_name,
@@ -337,18 +360,17 @@ public class PatientDashboardFragment extends Fragment implements ProfileContrac
viewModel.notifyRequestedSOS(AppUtil.getPatientUid(requireContext()) + "",
AppUtil.getPatientToken(requireContext()));
String phone_number = "911";
for (ContactData contactData : contactList1) {
if (contactData.is_sos.equals("1")) {
phone_number = contactData.phone_number;
sos_phone_number = contactData.phone_number;
}
}
if ("911".equals(phone_number)){
WorkManager.getInstance(requireContext()).cancelAllWork();
if ("911".equals(sos_phone_number)){
WorkManager.getInstance(requireContext()).cancelAllWorkByTag(CALL_BLOCKING_WORk);
WorkRequest workRequest = new OneTimeWorkRequest.Builder(CallUnBlockingWorker.class)
.setInitialDelay(1, TimeUnit.MINUTES)
.setInitialDelay(CALL_UNBLOCKING_INTERVAL, TimeUnit.MINUTES)
.addTag(CALL_BLOCKING_WORk)
.build();
WorkManager.getInstance(requireContext()).enqueue(workRequest);
@@ -357,8 +379,7 @@ public class PatientDashboardFragment extends Fragment implements ProfileContrac
Log.d(CALL_BLOCKING_WORk, "CALL BLOCKING DISABLED");
}
AppUtil.callPhone(requireActivity(), phone_number);
callPermissionLauncher.launch(Manifest.permission.CALL_PHONE);
}), true);
});
@@ -372,6 +393,9 @@ public class PatientDashboardFragment extends Fragment implements ProfileContrac
if (contactList != null) {
Intent intent = new Intent(requireActivity(), CallsActivity.class);
intent.putExtra(CALL_CONTACT_LIST_KEY, contactList);
if (patientData != null){
intent.putExtra(IS_50_CONTACTS_VIEW, patientData.is_contact_view_updated == 1);
}
startActivity(intent);
} else {

View File

@@ -131,14 +131,14 @@ public class GeoFenceBroadcastReceiver extends BroadcastReceiver {
}
int[] chatsCred = AppUtil.getPatientGeofenceChatCred(context);
if (chatsCred[0] == -1 || chatsCred[1] == -1 || chatsCred[2] == -1) {
if (chatsCred[3] == -1 || chatsCred[4] == -1 || chatsCred[2] == -1) {
Log.d(GEOFENCE_TAG, "notifyPatient: CANNOT SEND MESSAGE AS EITHER PAT_ID, CG_ID OR CHANNEL_ID IS NOT AVAILABLE");
return;
}
Log.d(GEOFENCE_TAG, "notifyPatient: " + chatsCred[2]);
// sending message
sendMessage(message, chatsCred[0], chatsCred[1], chatsCred[2], chatsCred[3]);
sendMessage(message, chatsCred[3], chatsCred[4], chatsCred[2], chatsCred[3]);
}
private void sendMessage(@NonNull String message, int patientId, int cg_id, int channel_id, int patient_principal_id) {

View File

@@ -176,6 +176,12 @@ public class ProfileProgressFragment extends Fragment implements ProfileContract
// updating patient data
PatientDataCache.setPatientData(response.body().result);
try {
AppUtil.setUserSubscribed(requireContext(), response.body().result.isCaregiverTakeSubscription == 1);
} catch (Exception e) {
// do nothing
}
if (response.body().result.isCareGiverConnectedWithPatient == 1) {
if (response.body().result.isCaregiverTakeSubscription == 1){
try {
@@ -292,6 +298,12 @@ public class ProfileProgressFragment extends Fragment implements ProfileContract
binding.proceed.setText(btn_text);
try {
AppUtil.setUserSubscribed(requireContext(), patientData.isCaregiverTakeSubscription == 1);
} catch (Exception e) {
// do nothing
}
progressDialog.dismiss();
}

View File

@@ -192,6 +192,12 @@ public class RegisterCompleteFragment extends Fragment implements ProfileContrac
public void onProfileProgressFetched(PatientData patientData) {
progressDialog.dismiss();
try {
AppUtil.setUserSubscribed(requireContext(), patientData.isCaregiverTakeSubscription == 1);
} catch (Exception e) {
// do nothing
}
if (patientData.isCareGiverConnectedWithPatient == 1) {
if (patientData.isCaregiverTakeSubscription == 1){
gotoPatientDashBoard();

View File

@@ -411,21 +411,19 @@ public class AddReminderFragment extends Fragment implements CompoundButton.OnCh
binding.quantity.setError("Required");
}else{
try {
long quantity = Long.parseLong(binding.quantity.getText().toString().trim());
double quantity = Double.parseDouble(binding.quantity.getText().toString().trim());
if (quantity <= 0){
allOkay = false;
binding.quantity.setError("Must be greater than 0");
}
}catch (NumberFormatException e){
allOkay = false;
binding.quantity.setError("Invalid quantity");
}catch (Exception e){
// do nothing
}
}
// if (binding.getDate.getText().toString().trim().isEmpty()) {
// allOkay = false;
// binding.getDate.setError("Required");
// }
if (allOkay) {
boolean anyOneSelected = false;
for (int i = 0; i < week_state.length; i++) {
@@ -773,6 +771,12 @@ public class AddReminderFragment extends Fragment implements CompoundButton.OnCh
public void onReminderAdded(ReminderResult reminderDetails) {
progressDialog.dismiss();
try {
viewModel.sendReminderUpdatedMessage(requireContext());
} catch (Exception e) {
// do nothing
}
if (reminder == null) {
Toast.makeText(requireContext(), "Reminder added successfully.", Toast.LENGTH_SHORT).show();

View File

@@ -328,16 +328,15 @@ public class ReminderFragment extends Fragment implements RecyclerTouchListener.
public void onRemindersListFetched(List<ReminderResult> reminderResultList) {
progressDialog.dismiss();
// updating global list of reminders
if (reminderViewModel.selected_dow == 0){
// only updating global list of reminders with current day's reminder list
CaregiverMainViewModel.remindersList = reminderResultList;
PatientMainViewModel.remindersList = reminderResultList;
}
if (reminderResultList != null && reminderResultList.size() > 0) {
// reminders are present
// updating global list of reminders
if (reminderViewModel.selected_dow == 0){
// only updating global list of reminders with current day's reminder list
CaregiverMainViewModel.remindersList = reminderResultList;
PatientMainViewModel.remindersList = reminderResultList;
}
binding.remindersRv.setVisibility(View.VISIBLE);
binding.noData.setVisibility(View.GONE);
@@ -370,6 +369,11 @@ public class ReminderFragment extends Fragment implements RecyclerTouchListener.
Toast.makeText(requireContext(), "Reminder deleted.", Toast.LENGTH_SHORT).show();
progressDialog.dismiss();
loadReminderList(weekDayViewsList.get(reminderViewModel.selected_dow).day_of_week);
try {
reminderViewModel.sendReminderUpdatedMessage(requireContext());
} catch (Exception e) {
// do nothing
}
}
@Override
@@ -453,6 +457,11 @@ public class ReminderFragment extends Fragment implements RecyclerTouchListener.
public void onReminderAdded(ReminderResult reminderDetails) {
progressDialog.dismiss();
loadReminderList(weekDayViewsList.get(reminderViewModel.selected_dow).day_of_week);
try {
reminderViewModel.sendReminderUpdatedMessage(requireContext());
} catch (Exception e) {
// do nothing
}
}
@Override

View File

@@ -1,8 +1,14 @@
package com.app.simplitend.patientprofile.medreminder.mvvm;
import android.content.Context;
import androidx.annotation.NonNull;
import androidx.lifecycle.ViewModel;
import com.app.simplitend.apputils.AppUtil;
import com.app.simplitend.apputils.CaregiverDataCache;
import com.app.simplitend.apputils.PatientDataCache;
import com.app.simplitend.chats.SocketHelper;
import com.app.simplitend.patientprofile.ProfileContracts;
import com.app.simplitend.patientprofile.medreminder.mvvm.models.ReminderResult;
@@ -96,6 +102,60 @@ public class ReminderViewModel extends ViewModel {
return "";
}
// updating caregiver or senior about changes in reminders
public void sendReminderUpdatedMessage(Context context){
if (AppUtil.isPatientLoggedIn(context)){
// senior logged in
PatientDataCache.getPatientData(context, patientData -> {
if (patientData == null){
return;
}
String uniqueId = patientData.id + "medActivity" + patientData.caregiver_iamprincipal_id;
SocketHelper.getInstance().establishConnection(new SocketHelper.SockCallBack() {
@Override
public void onSocketConnected() {
SocketHelper.getInstance().sendUpdates(uniqueId, "0");
}
@Override
public void onConnectionError(Exception e) {
}
@Override
public void onDisconnected() {
}
});
}, false);
}else{
// caregiver logged in
CaregiverDataCache.getCaregiverData(context, careGiverData -> {
if (careGiverData == null || careGiverData.patientDetails == null){
return;
}
String uniqueId = careGiverData.id + "medActivity" + careGiverData.patientDetails.id;
SocketHelper.getInstance().establishConnection(new SocketHelper.SockCallBack() {
@Override
public void onSocketConnected() {
SocketHelper.getInstance().sendUpdates(uniqueId, "0");
}
@Override
public void onConnectionError(Exception e) {
}
@Override
public void onDisconnected() {
}
});
}, false);
}
}
}

View File

@@ -288,7 +288,7 @@ public class AddRoutineFragment extends Fragment implements CompoundButton.OnChe
if (start_date == null || end_date == null) throw new Exception();
if (start_date.getTime() >= end_date.getTime()){
Toast.makeText(requireContext(), "Emd time should be greater than start time.", Toast.LENGTH_SHORT).show();
Toast.makeText(requireContext(), "End time should be greater than start time.", Toast.LENGTH_SHORT).show();
allOkay = false;
}
@@ -475,6 +475,12 @@ public class AddRoutineFragment extends Fragment implements CompoundButton.OnChe
public void onRoutineAdded(RoutineDetails medicationInfo) {
progressDialog.dismiss();
try {
routineViewModel.sendReminderUpdatedMessage(requireContext());
} catch (Exception e) {
// do nothing
}
if (this.routine == null) {
Toast.makeText(requireContext(), "Activity saved successfully.", Toast.LENGTH_SHORT).show();

View File

@@ -321,6 +321,12 @@ public class RoutineFragment extends Fragment implements RoutineAdapter.ClickLis
Toast.makeText(requireContext(), "Reminder deleted.", Toast.LENGTH_SHORT).show();
progressDialog.dismiss();
loadRoutineList(weekDayViewsList.get(routineViewModel.selected_dow).day_of_week);
try {
routineViewModel.sendReminderUpdatedMessage(requireContext());
} catch (Exception e) {
// do nothing
}
}
@Override
@@ -341,15 +347,15 @@ public class RoutineFragment extends Fragment implements RoutineAdapter.ClickLis
public void onRoutinesFetched(List<RoutineDetails> routineList) {
progressDialog.dismiss();
// updating global list of activities for today's day
if (routineViewModel.selected_dow == 0) {
CaregiverMainViewModel.activityList = routineList;
PatientMainViewModel.activityList = routineList;
}
if (routineList != null && routineList.size() > 0) {
// reminders are present
// updating global list of activities for today's day
if (routineViewModel.selected_dow == 0) {
CaregiverMainViewModel.activityList = routineList;
PatientMainViewModel.activityList = routineList;
}
binding.routineRv.setVisibility(View.VISIBLE);
binding.noData.setVisibility(View.GONE);
@@ -507,6 +513,11 @@ public class RoutineFragment extends Fragment implements RoutineAdapter.ClickLis
public void onRoutineAdded(RoutineDetails medicationInfo) {
progressDialog.dismiss();
loadRoutineList(weekDayViewsList.get(routineViewModel.selected_dow).day_of_week);
try {
routineViewModel.sendReminderUpdatedMessage(requireContext());
} catch (Exception e) {
// do nothing
}
}
@Override

View File

@@ -1,8 +1,14 @@
package com.app.simplitend.patientprofile.setuproutine.mvvm;
import android.content.Context;
import androidx.annotation.NonNull;
import androidx.lifecycle.ViewModel;
import com.app.simplitend.apputils.AppUtil;
import com.app.simplitend.apputils.CaregiverDataCache;
import com.app.simplitend.apputils.PatientDataCache;
import com.app.simplitend.chats.SocketHelper;
import com.app.simplitend.patientprofile.ProfileContracts;
public class RoutineViewModel extends ViewModel {
@@ -93,4 +99,60 @@ public class RoutineViewModel extends ViewModel {
return "";
}
// updating caregiver or senior about changes in reminders
public void sendReminderUpdatedMessage(Context context){
if (AppUtil.isPatientLoggedIn(context)){
// senior logged in
PatientDataCache.getPatientData(context, patientData -> {
if (patientData == null){
return;
}
String uniqueId = patientData.id + "medActivity" + patientData.caregiver_iamprincipal_id;
SocketHelper.getInstance().establishConnection(new SocketHelper.SockCallBack() {
@Override
public void onSocketConnected() {
SocketHelper.getInstance().sendUpdates(uniqueId, "1");
}
@Override
public void onConnectionError(Exception e) {
}
@Override
public void onDisconnected() {
}
});
}, false);
}else{
// caregiver logged in
CaregiverDataCache.getCaregiverData(context, careGiverData -> {
if (careGiverData == null || careGiverData.patientDetails == null){
return;
}
String uniqueId = careGiverData.id + "medActivity" + careGiverData.patientDetails.id;
SocketHelper.getInstance().establishConnection(new SocketHelper.SockCallBack() {
@Override
public void onSocketConnected() {
SocketHelper.getInstance().sendUpdates(uniqueId, "1");
}
@Override
public void onConnectionError(Exception e) {
}
@Override
public void onDisconnected() {
}
});
}, false);
}
}
}

View File

@@ -42,4 +42,5 @@ public class CareGiverData{
public String caregiver_status, one_signal_player_id, link_id;
public PatientData patientDetails;
public int is_contact_view_updated;
}

View File

@@ -205,6 +205,12 @@ public class SignInFragment extends Fragment implements WelcomeContracts.Registe
Toast.makeText(requireContext(), "Log in successful.", Toast.LENGTH_SHORT).show();
try {
AppUtil.setUserSubscribed(requireContext(), patientResult.isCaregiverTakeSubscription == 1);
} catch (Exception e) {
// do nothing
}
if (patientResult.isCareGiverConnectedWithPatient == 1 && patientResult.isCaregiverTakeSubscription == 1){
// connected to caregiver
// thus, sending it to dashboard

View File

@@ -1,4 +1,4 @@
package com.app.simplitend.welcome.welcomepatient.fragments.contacts.mvvm;
package com.app.simplitend.welcome.welcomepatient.fragments.contacts;
import static com.app.simplitend.welcome.welcomepatient.fragments.contacts.CreateContactFragment.TO_EDIT_KEY;
@@ -17,7 +17,6 @@ import androidx.recyclerview.widget.RecyclerView;
import com.app.simplitend.apputils.RetrofitHelper;
import com.bumptech.glide.Glide;
import com.app.simplitend.R;
import com.app.simplitend.apputils.AppUtil;
import com.app.simplitend.databinding.AddContactViewholderBinding;
import com.app.simplitend.welcome.welcomepatient.fragments.contacts.mvvm.models.ContactData;

View File

@@ -9,6 +9,7 @@ import android.os.Bundle;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.PopupMenu;
import android.widget.Toast;
import androidx.annotation.NonNull;
@@ -17,14 +18,16 @@ import androidx.fragment.app.Fragment;
import androidx.lifecycle.ViewModelProvider;
import androidx.navigation.Navigation;
import androidx.recyclerview.widget.GridLayoutManager;
import androidx.recyclerview.widget.LinearLayoutManager;
import com.app.simplitend.R;
import com.app.simplitend.apputils.AppUtil;
import com.app.simplitend.apputils.CaregiverDataCache;
import com.app.simplitend.apputils.PatientDataCache;
import com.app.simplitend.databinding.AddContactFragmentBinding;
import com.app.simplitend.databinding.DoneBottomsheetBinding;
import com.app.simplitend.welcome.welcomepatient.fragments.contacts.mvvm.AddContactAdapter;
import com.app.simplitend.welcome.welcomepatient.fragments.contacts.mvvm.ContactViewModel;
import com.app.simplitend.welcome.welcomepatient.fragments.contacts.mvvm.FiftyContactsAdapter;
import com.app.simplitend.welcome.welcomepatient.fragments.contacts.mvvm.models.ContactData;
import com.app.simplitend.welcome.welcomepatient.fragments.contacts.mvvm.models.ContactListResponse;
import com.app.simplitend.welcome.welcomepatient.mvvm.WelcomeContracts;
@@ -33,7 +36,7 @@ import com.google.android.material.bottomsheet.BottomSheetDialog;
import java.util.ArrayList;
import java.util.List;
public class AddContactFragment extends Fragment implements WelcomeContracts.ContactListContracts, AddContactAdapter.ContactClickListener {
public class AddContactFragment extends Fragment implements WelcomeContracts.ContactListContracts, AddContactAdapter.ContactClickListener, WelcomeContracts.UpdateTo50ContactsCallback {
// view binding
protected AddContactFragmentBinding binding;
@@ -41,16 +44,17 @@ public class AddContactFragment extends Fragment implements WelcomeContracts.Con
public static final String CONTACT_INFO_F = "contact_info_f";
protected AddContactAdapter contactAdapter;
private ProgressDialog progressDialog;
protected FiftyContactsAdapter fiftyContactsAdapter;
private ContactViewModel contactViewModel;
private int contacts_count;
private boolean is_doctor_set;
private boolean is_doctor_set, is_contact_view_updated;
private boolean isSetupComplete;
private PopupMenu popupMenu;
public AddContactFragment(){
// required empty const.
}
@@ -69,21 +73,93 @@ public class AddContactFragment extends Fragment implements WelcomeContracts.Con
if (isSetupComplete) {
binding.titleTxt.setText("Contacts");
}
initViews();
clickEvents();
return binding.getRoot();
}
private void initViews() {
@Override
public void onViewCreated(@NonNull View view, @Nullable Bundle savedInstanceState) {
super.onViewCreated(view, savedInstanceState);
progressDialog = new ProgressDialog(requireContext());
if (AppUtil.isPatientLoggedIn(requireContext())){
// senior
PatientDataCache.getPatientData(requireContext(), patientData -> {
if (patientData != null){
binding.contactRv.setLayoutManager(new GridLayoutManager(requireContext(), 2));
contactAdapter = new AddContactAdapter();
binding.contactRv.setAdapter(contactAdapter);
initViews(patientData.is_contact_view_updated == 1);
clickEvents();
}
}, true);
}else{
// caregiver
CaregiverDataCache.getCaregiverData(requireContext(), careGiverData -> {
if (careGiverData != null){
initViews(careGiverData.is_contact_view_updated == 1);
clickEvents();
}
}, true);
}
}
private void initViews(boolean is_contact_view_updated) {
this.is_contact_view_updated = is_contact_view_updated;
if (isSetupComplete) {
if (!is_contact_view_updated) {
binding.openMenuBtn.setVisibility(View.VISIBLE);
popupMenu = new PopupMenu(requireContext(), binding.openMenuBtn);
popupMenu.inflate(R.menu.contacts_menu);
binding.openMenuBtn.setOnClickListener(v -> {
popupMenu.show();
});
popupMenu.setOnMenuItemClickListener(menuItem -> {
AppUtil.showAlert(requireContext(),
"Are you sure?", "Do you want to change the family & friends contact list to 50 contacts?\nThis cannot be undone.",
"Yes", ((dialogInterface, i) -> {
// yes
if (AppUtil.isPatientLoggedIn(requireContext())){
// senior
PatientDataCache.getPatientData(requireContext(), patientData -> {
if (patientData != null){
binding.progressBar.setVisibility(View.VISIBLE);
contactViewModel.updateTo50Contacts(this, patientData.patientId,
false, "Bearer " + AppUtil.getPatientToken(requireContext()));
}
}, true);
}else{
// caregiver
CaregiverDataCache.getCaregiverData(requireContext(), careGiverData -> {
if (careGiverData != null){
binding.progressBar.setVisibility(View.VISIBLE);
contactViewModel.updateTo50Contacts(this, careGiverData.caregiver_xid,
true, "Bearer " + AppUtil.getCgToken(requireContext()));
}
}, true);
}
}), "No", null);
return true;
});
}
}
if (is_contact_view_updated){
binding.contactRv.setLayoutManager(new LinearLayoutManager(requireContext()));
fiftyContactsAdapter = new FiftyContactsAdapter();
binding.contactRv.setAdapter(fiftyContactsAdapter);
}else{
binding.contactRv.setLayoutManager(new GridLayoutManager(requireContext(), 2));
contactAdapter = new AddContactAdapter();
binding.contactRv.setAdapter(contactAdapter);
}
loadContacts();
@@ -95,8 +171,12 @@ public class AddContactFragment extends Fragment implements WelcomeContracts.Con
contactViewModel.getRemoteContactList(this,
"Bearer " + AppUtil.getPatientToken(requireContext()));
contactAdapter.setContactClickListener(this);
if (contactAdapter != null) {
contactAdapter.setContactClickListener(this);
}else if (fiftyContactsAdapter != null){
fiftyContactsAdapter.setContactClickListener(this);
}
}
private void clickEvents() {
@@ -145,13 +225,19 @@ public class AddContactFragment extends Fragment implements WelcomeContracts.Con
// do nothing
}
for (int i = contactList.size(); i<10; i++){
contactList.add(new ContactData(-1));
}
binding.progressBar.setVisibility(View.GONE);
contactAdapter.submitList(contactList);
if (contactAdapter != null) {
for (int i = contactList.size(); i<10; i++){
contactList.add(new ContactData(-1));
}
contactAdapter.submitList(contactList);
} else if (fiftyContactsAdapter != null) {
for (int i = contactList.size(); i<50; i++){
contactList.add(new ContactData(-1));
}
fiftyContactsAdapter.submitList(contactList);
}
binding.nextBtn.setVisibility(View.VISIBLE);
}
@@ -172,7 +258,7 @@ public class AddContactFragment extends Fragment implements WelcomeContracts.Con
if (contactData.id == -1){
// a new contact should be added
if (contacts_count == 9 && !is_doctor_set){
if (contacts_count == 9 && !is_doctor_set && !is_contact_view_updated){
// last contact to be added
// and doctor not yet set
AppUtil.showAlert(requireContext(),
@@ -264,4 +350,49 @@ public class AddContactFragment extends Fragment implements WelcomeContracts.Con
bsd.show();
}
@Override
public void onUpdatedTo50Contacts() {
try {
Toast.makeText(requireContext(), "Contact list updated", Toast.LENGTH_SHORT).show();
binding.contactRv.setLayoutManager(new LinearLayoutManager(requireContext()));
fiftyContactsAdapter = new FiftyContactsAdapter();
binding.contactRv.setAdapter(fiftyContactsAdapter);
contactAdapter = null;
loadContacts();
binding.openMenuBtn.setVisibility(View.GONE);
if (AppUtil.isPatientLoggedIn(requireContext())){
PatientDataCache.getPatientData(requireContext(), patientData -> {
if (patientData != null){
patientData.is_contact_view_updated = 1;
PatientDataCache.setPatientData(patientData);
}
}, true);
}else{
CaregiverDataCache.getCaregiverData(requireContext(), careGiverData -> {
if (careGiverData != null){
careGiverData.is_contact_view_updated = 1;
CaregiverDataCache.setCareGiverData(careGiverData);
}
}, true);
}
} catch (Exception e) {
// do nothing
}
}
@Override
public void onUpdateTo50ContactFailed(String message) {
binding.progressBar.setVisibility(View.GONE);
try {
Toast.makeText(requireContext(), "" + message, Toast.LENGTH_SHORT).show();
} catch (Exception e) {
// do nothing
}
}
}

View File

@@ -26,6 +26,7 @@ import androidx.annotation.Nullable;
import androidx.fragment.app.Fragment;
import androidx.fragment.app.FragmentManager;
import androidx.lifecycle.ViewModelProvider;
import androidx.navigation.NavBackStackEntry;
import androidx.navigation.Navigation;
import com.app.simplitend.R;
@@ -186,8 +187,6 @@ public class CreateContactFragment extends Fragment implements WelcomeContracts.
Log.d(TAG, "initializeViews: " + selectedImageUri.getPath());
} else if (result.getResultCode() == ImagePicker.RESULT_ERROR) {
Toast.makeText(requireContext(), ImagePicker.getError(result.getData()), Toast.LENGTH_SHORT).show();
} else {
Toast.makeText(requireContext(), "Task Cancelled", Toast.LENGTH_SHORT).show();
}
});
}
@@ -247,7 +246,6 @@ public class CreateContactFragment extends Fragment implements WelcomeContracts.
ImagePicker.with(requireActivity())
.cropSquare()
.maxResultSize(500, 500)
.galleryOnly()
.createIntent(intent -> {
imageSelector.launch(intent);
return null;
@@ -442,13 +440,17 @@ public class CreateContactFragment extends Fragment implements WelcomeContracts.
// create contact callback
@Override
public void onContactCreated(Contact contact) {
Log.d(TAG, "onContactCreated: " + contact);
public void onContactCreated(Contact con) {
progressDialog.dismiss();
try {
NavBackStackEntry entry = Navigation.findNavController(binding.getRoot()).getBackStackEntry(R.id.addContactFragment);
Navigation.findNavController(binding.getRoot()).popBackStack(R.id.addContactFragment, false);
}catch (IllegalArgumentException e){
// addcontactFragment is not available in backstack
Navigation.findNavController(binding.getRoot()).navigate(R.id.action_createContactFragment_to_addContactFragment);
} catch (Exception e) {
}
catch (Exception e) {
// this fragment is opened from outside of welcome_nav_graph
try {
getParentFragmentManager().popBackStack(null, FragmentManager.POP_BACK_STACK_INCLUSIVE);

View File

@@ -260,6 +260,10 @@ public class ContactViewModel extends AndroidViewModel {
return returnString.toString();
}
public void updateTo50Contacts(@NonNull WelcomeContracts.UpdateTo50ContactsCallback contactsCallback, int id, boolean isCaregiver, @NonNull String token){
contactRepository.updateTo50Contacts(contactsCallback, id, isCaregiver, token);
}
// interfaces
public interface GotoAddContactInterface{

View File

@@ -0,0 +1,124 @@
package com.app.simplitend.welcome.welcomepatient.fragments.contacts.mvvm;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import androidx.annotation.NonNull;
import androidx.recyclerview.widget.DiffUtil;
import androidx.recyclerview.widget.ListAdapter;
import androidx.recyclerview.widget.RecyclerView;
import com.app.simplitend.R;
import com.app.simplitend.apputils.RetrofitHelper;
import com.app.simplitend.databinding.FiftyContactViewholderBinding;
import com.app.simplitend.welcome.welcomepatient.fragments.contacts.AddContactAdapter;
import com.app.simplitend.welcome.welcomepatient.fragments.contacts.mvvm.models.ContactData;
import com.bumptech.glide.Glide;
public class FiftyContactsAdapter extends ListAdapter<ContactData, FiftyContactsAdapter.ContactViewHolder> {
private static final DiffUtil.ItemCallback<ContactData> DIFF_UTIL = new DiffUtil.ItemCallback<ContactData>() {
@Override
public boolean areItemsTheSame(@NonNull ContactData oldItem, @NonNull ContactData newItem) {
return oldItem.first_name.equals(newItem.first_name);
}
@Override
public boolean areContentsTheSame(@NonNull ContactData oldItem, @NonNull ContactData newItem) {
return oldItem.equals(newItem);
}
};
private AddContactAdapter.ContactClickListener contactClickListener;
public FiftyContactsAdapter() {
super(DIFF_UTIL);
}
public void setContactClickListener(AddContactAdapter.ContactClickListener contactClickListener) {
this.contactClickListener = contactClickListener;
}
@NonNull
@Override
public ContactViewHolder onCreateViewHolder(@NonNull ViewGroup parent, int viewType) {
FiftyContactViewholderBinding binding = FiftyContactViewholderBinding.inflate(LayoutInflater.from(parent.getContext()), parent, false);
return new ContactViewHolder(binding);
}
@Override
public void onBindViewHolder(@NonNull ContactViewHolder holder, int position) {
holder.setData(getItem(position), position);
holder.binding.card.setOnClickListener(v -> {
if (contactClickListener != null){
contactClickListener.onContactClick(getItem(position), position);
}
});
}
public static class ContactViewHolder extends RecyclerView.ViewHolder {
public FiftyContactViewholderBinding binding;
public ContactViewHolder(FiftyContactViewholderBinding binding) {
super(binding.getRoot());
this.binding = binding;
}
public void setData(ContactData contact, int position) {
if (contact.id == -1){
// no contact yet added
binding.addImg.setVisibility(View.VISIBLE);
binding.image.setVisibility(View.GONE);
binding.name.setText(itemView.getContext().getString(R.string.add_contact));
binding.card.setCardBackgroundColor(itemView.getContext().getColor(R.color.color_accent));
binding.cgIc.setVisibility(View.GONE);
binding.docIc.setVisibility(View.GONE);
binding.sos.setVisibility(View.GONE);
}else{
binding.name.setText(contact.first_name);
if (contact.contact_photo == null || contact.contact_photo.isEmpty()){
binding.addImg.setVisibility(View.VISIBLE);
binding.image.setVisibility(View.GONE);
}else{
binding.addImg.setVisibility(View.GONE);
binding.image.setVisibility(View.VISIBLE);
Glide.with(itemView.getContext())
.load(RetrofitHelper.IMAGE_BASE_URL + contact.contact_photo)
.placeholder(android.R.color.darker_gray)
.error(R.drawable.ic_contact)
.fitCenter().into(binding.image);
}
binding.card.setCardBackgroundColor(itemView.getContext().getColor(R.color.white_bg));
if (contact.care_giver_data.id != null){
// this contact is caregiver
binding.cgIc.setVisibility(View.VISIBLE);
}else{
binding.cgIc.setVisibility(View.GONE);
}
if (contact.is_sos != null && contact.is_sos.equals("1")){
binding.sos.setVisibility(View.VISIBLE);
}else{
binding.sos.setVisibility(View.GONE);
}
if (contact.is_doctor != null && contact.is_doctor.equals("1")){
binding.docIc.setVisibility(View.VISIBLE);
}else{
binding.docIc.setVisibility(View.GONE);
}
}
}
}
}

View File

@@ -119,7 +119,11 @@ public class UserContactRepository {
Log.e(TAG, "onResponse: no success response and also response body is 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);
// 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);
// There's a chance that the contact was created but, with an server error
// thus, mimicking the contact was created
createContactInterface.onContactCreated(null);
}
if (updateContactContracts != null) {
@@ -282,4 +286,30 @@ public class UserContactRepository {
}
}
public void updateTo50Contacts(@NonNull WelcomeContracts.UpdateTo50ContactsCallback contactsCallback, int id, boolean isCaregiver, @NonNull String token){
Map<String, Integer> body = new HashMap<>();
body.put("id", id);
body.put("is_caregiver_or_patient", isCaregiver?2:1);
apiService.updateTo50Contacts(body, token).enqueue(new Callback<CallResponse<Object>>() {
@Override
public void onResponse(Call<CallResponse<Object>> call, Response<CallResponse<Object>> response) {
if (response.body() != null){
if (response.code() == 200 && response.body().error_code == 0){
// success
contactsCallback.onUpdatedTo50Contacts();
}else{
contactsCallback.onUpdateTo50ContactFailed(response.body().message);
}
}else{
contactsCallback.onUpdateTo50ContactFailed("Something went wrong");
}
}
@Override
public void onFailure(Call<CallResponse<Object>> call, Throwable t) {
contactsCallback.onUpdateTo50ContactFailed("Something went wrong");
}
});
}
}

View File

@@ -423,7 +423,6 @@ public class LocationFragment extends Fragment implements OnMapReadyCallback,
if ((fineLocationGranted != null && fineLocationGranted) || (coarseLocationGranted != null && coarseLocationGranted)) {
if (currentLocation == null) {
// one of the location access granted.
Toast.makeText(requireContext(), "Fetching your current location", Toast.LENGTH_SHORT).show();
if (googleMap != null) {
if (ActivityCompat.checkSelfPermission(requireContext(), Manifest.permission.ACCESS_FINE_LOCATION) != PackageManager.PERMISSION_GRANTED && ActivityCompat.checkSelfPermission(requireContext(), Manifest.permission.ACCESS_COARSE_LOCATION) != PackageManager.PERMISSION_GRANTED) {
return;

View File

@@ -8,6 +8,7 @@ import static com.app.simplitend.welcome.welcomepatient.fragments.register.ReAct
import android.app.AlertDialog;
import android.content.Intent;
import android.net.Uri;
import android.os.Bundle;
import android.view.LayoutInflater;
import android.view.View;
@@ -20,6 +21,7 @@ import androidx.fragment.app.Fragment;
import androidx.navigation.NavOptions;
import androidx.navigation.Navigation;
import com.app.simplitend.BuildConfig;
import com.app.simplitend.R;
import com.app.simplitend.apputils.AppUtil;
import com.app.simplitend.apputils.CaregiverDataCache;
@@ -36,14 +38,15 @@ import com.app.simplitend.welcome.welcomecg.WelcomeContracts;
import com.app.simplitend.welcome.welcomecg.fragments.CgAuthActivity;
import com.app.simplitend.welcome.welcomecg.mvvm.CareGiverData;
import com.app.simplitend.welcome.welcomepatient.mvvm.models.CallResponse;
import com.app.simplitend.welcome.welcomepatient.mvvm.models.NewUpdate;
import com.app.simplitend.welcome.welcomepatient.mvvm.models.PatientData;
import com.onesignal.OneSignal;
import okhttp3.MediaType;
import okhttp3.RequestBody;
import retrofit2.Call;
import retrofit2.Callback;
import retrofit2.Response;
import retrofit2.http.GET;
import retrofit2.http.Query;
public class SplashFragment extends Fragment
implements ProfileContracts.ProfileProgressCallback,
@@ -52,13 +55,15 @@ public class SplashFragment extends Fragment
// view binding
protected SplashFragmentBinding binding;
private int latest_version = -1;
@Nullable
@Override
public View onCreateView(@NonNull LayoutInflater inflater, @Nullable ViewGroup container, @Nullable Bundle savedInstanceState) {
binding = SplashFragmentBinding.inflate(inflater, container, false);
binding.retry.setOnClickListener(v -> {
checkIfAhyUser();
checkNewUpdates();
});
return binding.getRoot();
@@ -67,16 +72,111 @@ public class SplashFragment extends Fragment
@Override
public void onViewCreated(@NonNull View view, @Nullable Bundle savedInstanceState) {
super.onViewCreated(view, savedInstanceState);
checkIfAhyUser();
binding.newUpdateView.getRoot().setVisibility(View.GONE);
checkNewUpdates();
binding.newUpdateView.skipBtn.setOnClickListener(v -> {
AppUtil.setSkippedUpdateVersion(requireContext(), latest_version);
checkIfAhyUser();
});
binding.newUpdateView.updateBtn.setOnClickListener(v -> {
Intent intent = new Intent(Intent.ACTION_VIEW, Uri.parse("https://play.google.com/store/apps/details?id=com.app.simplitend"));
startActivity(intent);
});
}
private void checkIfAhyUser() {
private void checkNewUpdates() {
binding.newUpdateView.getRoot().setVisibility(View.GONE);
binding.retry.setVisibility(View.GONE);
binding.loadAnim.setVisibility(View.VISIBLE);
String patient_token = AppUtil.getPatientToken(requireContext());
String cg_token = AppUtil.getCgToken(requireContext());
boolean is_patient_logged_in = AppUtil.isPatientLoggedIn(requireContext());
NewUpdatesApiService apiService = RetrofitHelper.getRetrofit().create(NewUpdatesApiService.class);
apiService.checkNewUpdates(2)
.enqueue(new Callback<CallResponse<NewUpdate>>() {
@Override
public void onResponse(Call<CallResponse<NewUpdate>> call, Response<CallResponse<NewUpdate>> response) {
if (response.body() != null) {
if (response.code() != 200 || response.body().error_code != 0){
onFailure(call, new Exception("Response code is " + response.code() + " error code is " + response.body().error_code));
return;
}
if (response.body().result == null){
onFailure(call, new Exception("Received result is null"));
return;
}
latest_version = response.body().result.new_version;
if (BuildConfig.VERSION_CODE < response.body().result.new_version){
// current version is less than latest version
// update is required
try {
// checking if this update is already skipped by user
if (AppUtil.getSkippedVersion(requireContext()) == response.body().result.new_version){
// already skipped version
checkIfAhyUser();
return;
}
} catch (Exception e) {
// do nothing
return;
}
binding.newUpdateView.getRoot().setVisibility(View.VISIBLE);
if (response.body().result.force_update == 1 && BuildConfig.VERSION_CODE < response.body().result.force_update_version) {
// current version is less than forced latest version
// update is mandatory
binding.newUpdateView.skipBtn.setVisibility(View.GONE);
}else{
// current version is greater than or equal to force update version
// thus, this update can be skipped
binding.newUpdateView.skipBtn.setVisibility(View.VISIBLE);
}
}else{
// current version is equal to latest version
// no update is required
binding.newUpdateView.getRoot().setVisibility(View.GONE);
checkIfAhyUser();
}
} else {
onFailure(call, new Exception("Response body is null"));
}
}
@Override
public void onFailure(Call<CallResponse<NewUpdate>> call, Throwable t) {
try {
Toast.makeText(requireContext(), "Couldn't connect.", Toast.LENGTH_SHORT).show();
} catch (Exception e) {
// do nothing
}
binding.retry.setVisibility(View.VISIBLE);
binding.loadAnim.setVisibility(View.GONE);
}
});
}
private void checkIfAhyUser() {
binding.newUpdateView.getRoot().setVisibility(View.GONE);
binding.retry.setVisibility(View.GONE);
binding.loadAnim.setVisibility(View.VISIBLE);
String patient_token = null;
String cg_token = null;
boolean is_patient_logged_in = false;
try {
patient_token = AppUtil.getPatientToken(requireContext());
cg_token = AppUtil.getCgToken(requireContext());
is_patient_logged_in = AppUtil.isPatientLoggedIn(requireContext());
} catch (Exception e) {
// do nothing
}
if (patient_token != null && !patient_token.isEmpty() && is_patient_logged_in){
// user is already logged in as PATIENT
@@ -97,8 +197,10 @@ public class SplashFragment extends Fragment
}
onProfileProgressFetched(response.body().result);
} else {
} else if (response.code() == 401) {
sessionExpired();
}else{
onProfileProgressFetchFailed(new Exception("Response body is null"), response.message());
}
}
@@ -125,8 +227,10 @@ public class SplashFragment extends Fragment
}
onCgDataFetched(response.body().result);
} else {
} else if (response.code() == 401) {
sessionExpired();
}else{
onCgDataFetchFailed(new Exception("Response body is null"), response.message());
}
}
@@ -146,17 +250,21 @@ public class SplashFragment extends Fragment
binding.retry.setVisibility(View.VISIBLE);
binding.loadAnim.setVisibility(View.GONE);
new AlertDialog.Builder(requireContext())
.setTitle("Session Expired")
.setMessage("Your login session has expired.\nPlease login again.")
.setCancelable(true)
.setPositiveButton("OKAY", (dialogInterface, i) -> {
AppUtil.patientSignOut(requireContext());
AppUtil.cgSignOut(requireContext());
try {
new AlertDialog.Builder(requireContext())
.setTitle("Session Expired")
.setMessage("Your login session has expired.\nPlease login again.")
.setCancelable(true)
.setPositiveButton("OKAY", (dialogInterface, i) -> {
AppUtil.patientSignOut(requireContext());
AppUtil.cgSignOut(requireContext());
gotoWelcomeFragment();
})
.show();
gotoWelcomeFragment();
})
.show();
} catch (Exception e) {
// do nothing
}
}
private void gotoReActivateScreen(String cg_status, String token, int cg_xid, boolean is_caregiver){
@@ -194,24 +302,36 @@ public class SplashFragment extends Fragment
}
private void gotoPatientDashBoard() {
Intent intent = new Intent(requireActivity(), DashBoardActivity.class);
intent.setFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP);
startActivity(intent);
requireActivity().finish();
try {
Intent intent = new Intent(requireActivity(), DashBoardActivity.class);
intent.setFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP);
startActivity(intent);
requireActivity().finish();
} catch (Exception e) {
// do nothing
}
}
private void gotoCgAuthScreen(){
Intent intent = new Intent(requireActivity(), CgAuthActivity.class);
intent.setFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP);
startActivity(intent);
requireActivity().finish();
try {
Intent intent = new Intent(requireActivity(), CgAuthActivity.class);
intent.setFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP);
startActivity(intent);
requireActivity().finish();
} catch (Exception e) {
// do nothing
}
}
private void gotoCgDashBoard(){
Intent intent = new Intent(requireActivity(), CaregiverDashActivity.class);
intent.setFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP);
startActivity(intent);
requireActivity().finish();
try {
Intent intent = new Intent(requireActivity(), CaregiverDashActivity.class);
intent.setFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP);
startActivity(intent);
requireActivity().finish();
} catch (Exception e) {
// do nothing
}
}
// get cg user data callback
@@ -223,8 +343,12 @@ public class SplashFragment extends Fragment
if (!careGiverData.caregiver_status.equals(AccountPresenter.ACC_ACTIVE_STR)){
// account is not active
gotoReActivateScreen(careGiverData.caregiver_status, AppUtil.getCgToken(requireContext()),
careGiverData.caregiver_xid, true);
try {
gotoReActivateScreen(careGiverData.caregiver_status, AppUtil.getCgToken(requireContext()),
careGiverData.caregiver_xid, true);
} catch (Exception e) {
// do nothing
}
return;
}
@@ -234,7 +358,12 @@ public class SplashFragment extends Fragment
if (careGiverData.isPatientAndCareGiverConnected == 1){
// patient is linked with the caregiver
int cg_security = AppUtil.getWantSecurityFlag(requireContext());
int cg_security = 0;
try {
cg_security = AppUtil.getWantSecurityFlag(requireContext());
} catch (Exception e) {
return;
}
if (cg_security == AppUtil.NOT_ASKED_CG_SECURITY || cg_security == AppUtil.CG_SECURITY_NEEDED){
// user want their app to be secure
@@ -262,7 +391,11 @@ public class SplashFragment extends Fragment
@Override
public void onCgDataFetchFailed(Throwable t, String message) {
Toast.makeText(requireContext(), "Couldn't connect.", Toast.LENGTH_SHORT).show();
try {
Toast.makeText(requireContext(), "Couldn't connect.", Toast.LENGTH_SHORT).show();
} catch (Exception e) {
// do nothing
}
binding.retry.setVisibility(View.VISIBLE);
binding.loadAnim.setVisibility(View.GONE);
@@ -280,9 +413,13 @@ public class SplashFragment extends Fragment
if (!patientData.caregiver_status.equals(AccountPresenter.DEFAULT_ACTIVE_STATUS)) {
// account is in default state
gotoReActivateScreen(patientData.caregiver_status,
AppUtil.getPatientToken(requireContext()),
-1, false);
try {
gotoReActivateScreen(patientData.caregiver_status,
AppUtil.getPatientToken(requireContext()),
-1, false);
} catch (Exception e) {
// do nothing
}
return;
}
}
@@ -290,9 +427,19 @@ public class SplashFragment extends Fragment
binding.retry.setVisibility(View.GONE);
binding.loadAnim.setVisibility(View.GONE);
try {
AppUtil.setUserSubscribed(requireContext(), patientData.isCaregiverTakeSubscription == 1);
} catch (Exception e) {
return;
}
if (patientData.isCareGiverConnectedWithPatient == 1 && patientData.isCaregiverTakeSubscription == 1){
// go to dashboard
gotoPatientDashBoard();
try {
gotoPatientDashBoard();
} catch (Exception e) {
// do nothing
}
}else if (patientData.isCareGiverLink == 1){
// user has already added caregiver as a contact
// thus, sending it to dashboard
@@ -312,9 +459,20 @@ public class SplashFragment extends Fragment
@Override
public void onProfileProgressFetchFailed(Throwable t, String message) {
Toast.makeText(requireContext(), "Couldn't connect.", Toast.LENGTH_SHORT).show();
try {
Toast.makeText(requireContext(), "Couldn't connect.", Toast.LENGTH_SHORT).show();
} catch (Exception e) {
// do nothing
}
binding.retry.setVisibility(View.VISIBLE);
binding.loadAnim.setVisibility(View.GONE);
}
// new update api
interface NewUpdatesApiService{
@GET("api/auth/get-version-history")
Call<CallResponse<NewUpdate>> checkNewUpdates(@Query("device") int deviceId);
}
}

View File

@@ -59,4 +59,9 @@ public interface WelcomeApiService {
@Multipart
@POST("api/auth/change-patient-pin")
Call<CallResponse<PatientData>> updatePin(@PartMap Map<String, RequestBody> body);
@Multipart
@POST("api/change-view-of-contact-list")
Call<CallResponse<Object>> updateTo50Contacts(@PartMap Map<String, Integer> body,
@Header("Authorization") String token);
}

View File

@@ -74,4 +74,10 @@ public interface WelcomeContracts {
void onPinUpdateFailed(Throwable t, String message);
}
interface UpdateTo50ContactsCallback{
void onUpdatedTo50Contacts();
void onUpdateTo50ContactFailed(String message);
}
}

View File

@@ -0,0 +1,16 @@
package com.app.simplitend.welcome.welcomepatient.mvvm.models;
import java.io.Serializable;
public class NewUpdate implements Serializable {
public int id;
public String version_id;
public String release_date;
public int old_version;
public int new_version;
public int force_update_version;
public int force_update;
public String release_notes;
public String created_at;
public String updated_at;
}

View File

@@ -32,6 +32,8 @@ public class PatientData {
public String caregiver_name, caregiver_profile_photo, caregiverId, link_id, caregiver_iamprincipal_id;
public int is_contact_view_updated;
// progress flags
public int isCareGiverLink
, isPatientReminderData

View File

@@ -0,0 +1,417 @@
<vector xmlns:android="http://schemas.android.com/apk/res/android"
android:width="242dp"
android:height="250dp"
android:viewportWidth="242"
android:viewportHeight="250">
<path
android:pathData="M26.2,229.43v20.57h63.25L89.45,229.43Z"
android:fillColor="#f5f5f5"/>
<path
android:pathData="M23.54,223.68v5.75h68.12v-5.75L23.54,223.68Z"
android:fillColor="#e0e0e0"/>
<path
android:pathData="M57.51,250h31.85L89.36,229.43h2.21v-5.75L56.18,223.68v5.22Z"
android:fillColor="#e0e0e0"/>
<path
android:pathData="M35.04,232.75h12.83v3.09h-12.83z"
android:fillColor="#e0e0e0"/>
<path
android:pathData="M33.39,239.71h16.47v6.54h-16.47z"
android:fillColor="#fff"/>
<path
android:pathData="M35.93,203.14v20.57L99.18,223.71L99.18,203.14Z"
android:fillColor="#f5f5f5"/>
<path
android:pathData="M33.28,197.84v5.75h68.12v-5.75L33.28,197.84Z"
android:fillColor="#e0e0e0"/>
<path
android:pathData="M67.23,223.71h31.84L99.07,203.14h2.21v-5.75L65.89,197.39L65.89,202.6Z"
android:fillColor="#e0e0e0"/>
<path
android:pathData="M44.71,206.81h12.83v3.1h-12.83z"
android:fillColor="#e0e0e0"/>
<path
android:pathData="M43.06,213.42h16.47v6.54h-16.47z"
android:fillColor="#fff"/>
<path
android:pathData="M11.49,83.41h26.87v7.11h-26.87z"
android:fillColor="#f5f5f5"/>
<path
android:pathData="M27.01,96.9v-1.89c0,-1.23 0,-2.99 -0.04,-5.22l0.08,0.08 -26.87,0.05 0.14,-0.13h0v7.11l-0.13,-0.14 19.15,0.06 5.65,0.04h1.93a0.74,0.74 0,0 1,0.14 0h-0.51l-1.52,0.08 -5.62,0.04 -19.25,0.06L0,97.04v-7.24h0l0.14,-0.14 26.87,0.05h0.08v0.09c0,2.24 -0.03,4.03 -0.04,5.26v1.73a0.47,0.47 0,0 1,-0.04 0.11Z"
android:fillColor="#e0e0e0"/>
<path
android:pathData="M176.67,206.66h26.87v7.11h-26.87z"
android:fillColor="#f5f5f5"/>
<path
android:pathData="M192.2,220.91a1.18,1.18 0,0 1,0 -0.13v-1.76c0,-1.23 0,-2.99 -0.04,-5.22l0.08,0.08 -26.87,0.05 0.14,-0.14h0v7.1l-0.13,-0.13 19.15,0.06 5.65,0.04h0.07l-5.62,0.04 -19.25,0.06h-0.13L165.24,213.73h0l0.14,-0.13 26.87,0.05h0.08L192.33,213.73c0,2.25 -0.03,4.03 -0.04,5.27L192.29,220.73A0.28,0.28 0,0 1,192.2 220.91Z"
android:fillColor="#e0e0e0"/>
<path
android:pathData="M114.64,48.6v-1.89c0,-1.23 -0.03,-2.99 -0.05,-5.22l0.08,0.09 -26.87,0.05 0.14,-0.14h0v7.11l-0.13,-0.14 19.15,0.06 5.66,0.04h1.93a0.4,0.4 0,0 1,0.14 0h-2.01l-5.62,0.04 -19.25,0.06h-0.13L87.67,41.5h0l0.14,-0.13 26.87,0.05h0.09v0.08c0,2.25 -0.03,4.03 -0.04,5.27v1.73A0.47,0.47 0,0 1,114.64 48.6Z"
android:fillColor="#e0e0e0"/>
<path
android:pathData="M118.27,41.49a0.61,0.61 0,0 1,0 -0.13v-1.8c0,-1.25 -0.03,-3.01 -0.05,-5.18l0.1,0.1 -16.19,0.02 0.14,-0.14h0v7.1l-0.13,-0.13 11.55,0.06 3.36,0.04h1.23a1.81,1.81 0,0 1,-0.29 0h-0.88l-3.31,0.04 -11.64,0.06h-0.13L102.02,34.39h0c-0.03,0.03 0.26,-0.26 0.14,-0.13l16.15,0.04h0.1v0.09c0,2.21 -0.04,3.97 -0.05,5.24v1.4C118.35,41.37 118.27,41.5 118.27,41.49Z"
android:fillColor="#e0e0e0"/>
<path
android:pathData="M238.18,118.99a1.14,1.14 0,0 1,0 -0.13L238.18,117.1c0,-1.23 0,-2.99 -0.04,-5.22l0.08,0.08 -26.87,0.05 0.14,-0.14h0v7.12l-0.13,-0.13 19.15,0.06 5.65,0.04h0.07l-5.62,0.03 -19.25,0.06h-0.13v-7.24h0l0.14,-0.14 26.87,0.05h0.08v0.08c0,2.25 -0.03,4.03 -0.04,5.26v1.73A0.21,0.21 0,0 1,238.18 118.99Z"
android:fillColor="#e0e0e0"/>
<path
android:pathData="M241.83,111.95a0.75,0.75 0,0 1,0 -0.13v-1.81c0,-1.24 -0.03,-3 -0.05,-5.17l0.1,0.1 -16.15,0.04c-0.12,0.12 0.17,-0.17 0.13,-0.14h0v7.1l-0.13,-0.13 11.55,0.06 3.36,0.03h1.23a1.8,1.8 0,0 1,-0.29 0h-0.88l-3.31,0.04 -11.64,0.06h-0.13v-7.23h0l0.14,-0.14 16.15,0.04h0.1v0.1c0,2.21 -0.04,3.97 -0.05,5.23v1.4A1.05,1.05 0,0 1,241.83 111.95Z"
android:fillColor="#e0e0e0"/>
<path
android:pathData="M0.46,249.79L233.73,249.79"
android:fillColor="#ff725e"/>
<path
android:pathData="M233.73,249.79c0,0.08 -52.22,0.14 -116.63,0.14s-116.64,-0.07 -116.64,-0.14 52.21,-0.14 116.64,-0.14S233.73,249.71 233.73,249.79Z"
android:fillColor="#263238"/>
<path
android:pathData="M180.61,0h54.54v71.11h-54.54z"
android:fillColor="#455a64"/>
<path
android:pathData="M235.13,0a0.92,0.92 0,0 1,-0.15 0.19l-0.47,0.55 -1.84,2.04v0.03h-0.03c-4.74,0.05 -14.06,0.08 -24.75,0.08s-20.02,-0.03 -24.76,-0.08h-0.03v-0.03l-1.84,-2.04 -0.47,-0.55a0.92,0.92 0,0 1,-0.15 -0.19,0.88 0.88,0 0,1 0.18,0.17l0.5,0.5 1.89,1.99h-0.05c4.74,-0.05 14.06,-0.08 24.76,-0.08s20.01,0.03 24.75,0.08h-0.05l1.89,-1.99 0.5,-0.5a0.89,0.89 0,0 1,0.13 -0.17Z"
android:fillColor="#263238"/>
<path
android:pathData="M180.61,71.12a0.92,0.92 0,0 1,0.15 -0.19l0.47,-0.55 1.84,-2.04h0.03c4.74,-0.05 14.06,-0.08 24.75,-0.08s20.01,0.03 24.76,0.08h0.03l1.88,2.07 0.47,0.55a0.92,0.92 0,0 1,0.15 0.19,0.88 0.88,0 0,1 -0.18,-0.17l-0.5,-0.5 -1.89,-1.99h0.05c-4.74,0.05 -14.06,0.08 -24.76,0.08s-20.01,-0.03 -24.75,-0.08h0.05l-1.89,1.99 -0.5,0.5a0.88,0.88 0,0 1,-0.18 0.13Z"
android:fillColor="#263238"/>
<path
android:pathData="M183.12,2.71h49.51v65.7h-49.51z"
android:fillColor="#fff"/>
<path
android:pathData="M190.87,49.2a7.82,7.82 0,0 1,5.68 -1.77c2.03,0.05 4.05,0.49 6.08,0.46 3.25,-0.04 6.49,-1.26 9.69,-0.7a7.97,7.97 0,0 0,3.08 0.32c0.89,-0.19 1.66,-0.81 2.51,-1.07 2.26,-0.68 4.8,1.1 6.97,0.18v14.67h-34Z"
android:fillColor="#1b6dc1"/>
<path
android:pathData="M191.56,49.79c-0.09,0 -0.16,-8.69 -0.16,-19.4s0.07,-19.41 0.16,-19.41 0.16,8.69 0.16,19.41S191.64,49.79 191.56,49.79Z"
android:fillColor="#263238"/>
<path
android:pathData="M193.1,49.79c-0.09,0 -0.16,-8.69 -0.16,-19.4s0.07,-19.41 0.16,-19.41 0.16,8.69 0.16,19.41S193.19,49.79 193.1,49.79Z"
android:fillColor="#263238"/>
<path
android:pathData="M194.65,49.79c-0.08,0 -0.16,-8.69 -0.16,-19.4s0.07,-19.41 0.16,-19.41 0.16,8.69 0.16,19.41S194.74,49.79 194.65,49.79Z"
android:fillColor="#263238"/>
<path
android:pathData="M196.2,49.79c-0.09,0 -0.16,-8.69 -0.16,-19.4s0.07,-19.41 0.16,-19.41 0.16,8.69 0.16,19.41S196.29,49.79 196.2,49.79Z"
android:fillColor="#263238"/>
<path
android:pathData="M197.75,49.79c-0.09,0 -0.16,-8.69 -0.16,-19.4s0.07,-19.41 0.16,-19.41 0.16,8.69 0.16,19.41S197.84,49.79 197.75,49.79Z"
android:fillColor="#263238"/>
<path
android:pathData="M199.3,49.79c-0.08,0 -0.16,-8.69 -0.16,-19.4s0.07,-19.41 0.16,-19.41 0.16,8.69 0.16,19.41S199.38,49.79 199.3,49.79Z"
android:fillColor="#263238"/>
<path
android:pathData="M200.85,49.79c-0.09,0 -0.16,-8.69 -0.16,-19.4s0.07,-19.41 0.16,-19.41 0.16,8.69 0.16,19.41S200.94,49.79 200.85,49.79Z"
android:fillColor="#263238"/>
<path
android:pathData="M202.39,49.79c-0.09,0 -0.16,-8.69 -0.16,-19.4s0.07,-19.41 0.16,-19.41 0.16,8.69 0.16,19.41S202.48,49.79 202.39,49.79Z"
android:fillColor="#263238"/>
<path
android:pathData="M203.94,49.79c-0.08,0 -0.16,-8.69 -0.16,-19.4s0.07,-19.41 0.16,-19.41 0.16,8.69 0.16,19.41S204.03,49.79 203.94,49.79Z"
android:fillColor="#263238"/>
<path
android:pathData="M205.49,49.79c-0.09,0 -0.16,-8.69 -0.16,-19.4s0.07,-19.41 0.16,-19.41 0.16,8.69 0.16,19.41S205.58,49.79 205.49,49.79Z"
android:fillColor="#263238"/>
<path
android:pathData="M207.04,49.79c-0.09,0 -0.16,-8.69 -0.16,-19.4s0.07,-19.41 0.16,-19.41 0.16,8.69 0.16,19.41S207.13,49.79 207.04,49.79Z"
android:fillColor="#263238"/>
<path
android:pathData="M208.59,49.79c-0.08,0 -0.16,-8.69 -0.16,-19.4s0.07,-19.41 0.16,-19.41 0.16,8.69 0.16,19.41S208.67,49.79 208.59,49.79Z"
android:fillColor="#263238"/>
<path
android:pathData="M210.14,49.79c-0.09,0 -0.16,-8.69 -0.16,-19.4s0.07,-19.41 0.16,-19.41 0.16,8.69 0.16,19.41S210.23,49.79 210.14,49.79Z"
android:fillColor="#263238"/>
<path
android:pathData="M211.68,49.79c-0.09,0 -0.16,-8.69 -0.16,-19.4s0.07,-19.41 0.16,-19.41 0.16,8.69 0.16,19.41S211.77,49.79 211.68,49.79Z"
android:fillColor="#263238"/>
<path
android:pathData="M213.24,49.79c-0.09,0 -0.16,-8.69 -0.16,-19.4s0.07,-19.41 0.16,-19.41 0.16,8.69 0.16,19.41S213.32,49.79 213.24,49.79Z"
android:fillColor="#263238"/>
<path
android:pathData="M214.78,49.79c-0.09,0 -0.16,-8.69 -0.16,-19.4s0.07,-19.41 0.16,-19.41 0.16,8.69 0.16,19.41S214.87,49.79 214.78,49.79Z"
android:fillColor="#263238"/>
<path
android:pathData="M216.35,49.79c-0.09,0 -0.16,-8.69 -0.16,-19.4s0.07,-19.41 0.16,-19.41 0.16,8.69 0.16,19.41S216.42,49.79 216.35,49.79Z"
android:fillColor="#263238"/>
<path
android:pathData="M217.88,49.79c-0.09,0 -0.16,-8.69 -0.16,-19.4s0.07,-19.41 0.16,-19.41 0.16,8.69 0.16,19.41S217.97,49.79 217.88,49.79Z"
android:fillColor="#263238"/>
<path
android:pathData="M219.43,49.79c-0.09,0 -0.16,-8.69 -0.16,-19.4s0.07,-19.41 0.16,-19.41 0.16,8.69 0.16,19.41S219.52,49.79 219.43,49.79Z"
android:fillColor="#263238"/>
<path
android:pathData="M220.98,49.79c-0.09,0 -0.16,-8.69 -0.16,-19.4s0.07,-19.41 0.16,-19.41 0.16,8.69 0.16,19.41S221.07,49.79 220.98,49.79Z"
android:fillColor="#263238"/>
<path
android:pathData="M222.53,49.79c-0.09,0 -0.16,-8.69 -0.16,-19.4s0.07,-19.41 0.16,-19.41 0.16,8.69 0.16,19.41S222.61,49.79 222.53,49.79Z"
android:fillColor="#263238"/>
<path
android:pathData="M224.09,49.79c-0.09,0 -0.16,-8.69 -0.16,-19.4s0.07,-19.41 0.16,-19.41 0.16,8.69 0.16,19.41S224.16,49.79 224.09,49.79Z"
android:fillColor="#263238"/>
<path
android:pathData="M210.83,92.37L216.95,92.37A3.07,3.07 0,0 1,220.01 95.44L220.01,101.5A3.07,3.07 0,0 1,216.95 104.57L210.83,104.57A3.07,3.07 0,0 1,207.76 101.5L207.76,95.44A3.07,3.07 0,0 1,210.83 92.37z"
android:fillColor="#e0e0e0"/>
<path
android:pathData="M209.45,104.57a1.26,1.26 0,0 1,-0.47 -0.03,1.72 1.72,0 0,1 -1.06,-0.81 1.8,1.8 0,0 1,-0.24 -0.96L207.69,94.49a2.84,2.84 0,0 1,0.09 -0.99,1.83 1.83,0 0,1 1.62,-1.23h8.96a1.91,1.91 0,0 1,1.18 0.43,1.88 1.88,0 0,1 0.63,1.07 9.48,9.48 0,0 1,0.03 1.18v7.43a3.8,3.8 0,0 1,-0.07 0.99,1.78 1.78,0 0,1 -0.51,0.85 1.82,1.82 0,0 1,-0.84 0.44,4.14 4.14,0 0,1 -0.89,0.04h-1.66l-4.93,-0.04h-1.34a2.57,2.57 0,0 1,-0.47 -0.03,4.43 4.43,0 0,1 0.47,-0.03l1.34,-0.03 4.93,-0.04L217.88,104.51a3.8,3.8 0,0 0,0.84 -0.04,1.56 1.56,0 0,0 0.74,-0.39 1.53,1.53 0,0 0,0.44 -0.74,3.54 3.54,0 0,0 0.05,-0.92v-7.43a10.64,10.64 0,0 0,-0.03 -1.1,1.56 1.56,0 0,0 -1.53,-1.26h-8.94a1.57,1.57 0,0 0,-1.4 1.05,2.6 2.6,0 0,0 -0.09,0.91v7.15a4.35,4.35 0,0 0,0.18 2.06,1.7 1.7,0 0,0 0.98,0.81A1.14,1.14 0,0 1,209.45 104.57Z"
android:fillColor="#263238"/>
<path
android:pathData="M209.72,98.47a4.16,4.16 0,1 0,1.23 -2.94A4.18,4.18 0,0 0,209.72 98.47Z"
android:fillColor="#e0e0e0"/>
<path
android:pathData="M209.72,98.48a0.84,0.84 0,0 1,0 -0.26,3.05 3.05,0 0,1 0.09,-0.77 4.13,4.13 0,0 1,1.51 -2.36,4.28 4.28,0 1,1 0,6.78 4.16,4.16 0,0 1,-1.51 -2.36,3.08 3.08,0 0,1 -0.09,-0.77 0.84,0.84 0,0 1,0 -0.26,8.04 8.04,0 0,0 0.18,1 4.19,4.19 0,0 0,1.53 2.21,4.02 4.02,0 0,0 1.72,0.74 4.09,4.09 0,0 0,2.12 -0.18,4.03 4.03,0 0,0 0,-7.57 4.15,4.15 0,0 0,-2.12 -0.19,4.09 4.09,0 0,0 -1.72,0.75 4.19,4.19 0,0 0,-1.53 2.21A4.3,4.3 0,0 0,209.72 98.48Z"
android:fillColor="#263238"/>
<path
android:pathData="M215.52,98.49m-0.88,0a0.88,0.88 0,1 1,1.76 0a0.88,0.88 0,1 1,-1.76 0"
android:fillColor="#263238"/>
<path
android:pathData="M212.39,98.49m-0.88,0a0.88,0.88 0,1 1,1.76 0a0.88,0.88 0,1 1,-1.76 0"
android:fillColor="#263238"/>
<path
android:pathData="M33.5,11.05L89.7,11.05A14.8,14.8 0,0 1,104.5 25.85L104.5,167.26A14.8,14.8 0,0 1,89.7 182.06L33.5,182.06A14.8,14.8 0,0 1,18.7 167.26L18.7,25.85A14.8,14.8 0,0 1,33.5 11.05z"
android:fillColor="#263238"/>
<path
android:pathData="M103.15,25.81L103.15,167.3A13.4,13.4 0,0 1,89.75 180.7L33.45,180.7A13.4,13.4 0,0 1,20.05 167.3L20.05,25.81A13.4,13.4 0,0 1,33.45 12.41L89.75,12.41A13.4,13.4 0,0 1,103.15 25.81z"
android:fillColor="#263238"/>
<path
android:pathData="M55.44,17.8a0.96,0.96 0,1 1,0 -1.92L67.71,15.88a0.96,0.96 0,0 1,0 1.92Z"
android:fillColor="#455a64"/>
<path
android:pathData="M48.86,17.8a0.96,0.96 0,1 1,0.68 -0.29A0.96,0.96 0,0 1,48.86 17.8Z"
android:fillColor="#263238"/>
<path
android:pathData="M52.37,17.8a0.96,0.96 0,1 1,0.68 -0.29A0.96,0.96 0,0 1,52.37 17.8Z"
android:fillColor="#455a64"/>
<path
android:pathData="M74.34,17.8a0.96,0.96 0,1 1,0.68 -0.29A0.96,0.96 0,0 1,74.34 17.8Z"
android:fillColor="#455a64"/>
<path
android:pathData="M70.83,17.8a0.96,0.96 0,1 1,0.68 -0.29A0.96,0.96 0,0 1,70.83 17.8Z"
android:fillColor="#263238"/>
<path
android:pathData="M93.84,13.57L81.79,13.57a4.29,4.29 0,0 0,-4.11 3.12l-0.18,0.7a4.6,4.6 0,0 1,-4.42 3.31L50.13,20.7A4.59,4.59 0,0 1,45.71 17.38l-0.2,-0.71A4.3,4.3 0,0 0,41.39 13.56L30.47,13.56A8.52,8.52 0,0 0,21.99 22.11L21.99,170.39a8.01,8.01 0,0 0,8.01 8.04h64.02a7.25,7.25 0,0 0,7.22 -7.28L101.24,20.99a7.4,7.4 0,0 0,-7.4 -7.42Z"
android:fillColor="#f5f5f5"/>
<path
android:pathData="M104.59,67.87L104.5,67.87L104.5,48.22L104.59,48.22a0.47,0.47 0,0 1,0.47 0.47L105.06,67.4A0.47,0.47 0,0 1,104.59 67.87Z"
android:fillColor="#455a64"/>
<path
android:pathData="M18.6,60.33h0.1v12.44h-0.1a0.49,0.49 0,0 1,-0.49 -0.49L18.11,60.82A0.49,0.49 0,0 1,18.6 60.33Z"
android:fillColor="#263238"/>
<path
android:pathData="M18.6,44.08h0.1L18.7,56.52h-0.1a0.49,0.49 0,0 1,-0.49 -0.49L18.11,44.56A0.49,0.49 0,0 1,18.6 44.08Z"
android:fillColor="#263238"/>
<path
android:pathData="M18.62,31.87h0.08v5.79L18.62,37.66a0.42,0.42 0,0 1,-0.42 -0.42L18.2,32.27a0.42,0.42 0,0 1,0.42 -0.4Z"
android:fillColor="#263238"/>
<path
android:pathData="M44.08,136.69h0.83v2.76h1.73v0.65L44.08,140.1Z"
android:fillColor="#263238"/>
<path
android:pathData="M47.71,139.95a1.75,1.75 0,0 1,0 -3.09,2.02 2.02,0 0,1 0.97,-0.23 2,2 0,0 1,0.97 0.23,1.75 1.75,0 0,1 0.68,0.63 1.71,1.71 0,0 1,0.25 0.91,1.69 1.69,0 0,1 -0.25,0.91 1.75,1.75 0,0 1,-0.68 0.63,2 2,0 0,1 -0.97,0.23A2.02,2.02 0,0 1,47.71 139.95ZM49.23,139.37a1,1 0,0 0,0.39 -0.39,1.16 1.16,0 0,0 0.14,-0.55 1.11,1.11 0,0 0,-0.14 -0.55,1.02 1.02,0 0,0 -0.39,-0.39 1.17,1.17 0,0 0,-1.1 0,1.02 1.02,0 0,0 -0.39,0.39 1.1,1.1 0,0 0,-0.14 0.55,1.16 1.16,0 0,0 0.14,0.55 1,1 0,0 0,0.39 0.39,1.13 1.13,0 0,0 1.1,0Z"
android:fillColor="#263238"/>
<path
android:pathData="M56.29,136.69 L55.16,140.12h-0.86l-0.76,-2.32 -0.78,2.32h-0.86L50.76,136.69h0.83l0.78,2.41L53.19,136.69h0.74l0.79,2.43 0.81,-2.43Z"
android:fillColor="#263238"/>
<path
android:pathData="M61.22,138.65a0.85,0.85 0,0 1,0.17 0.55,0.78 0.78,0 0,1 -0.35,0.69 1.79,1.79 0,0 1,-1.03 0.24h-1.79L58.21,136.69h1.69a1.66,1.66 0,0 1,0.97 0.24,0.76 0.76,0 0,1 0.34,0.65 0.84,0.84 0,0 1,-0.12 0.44,0.83 0.83,0 0,1 -0.34,0.31A0.96,0.96 0,0 1,61.22 138.65ZM59.01,137.29v0.81h0.82a0.76,0.76 0,0 0,0.45 -0.1,0.34 0.34,0 0,0 0.16,-0.3 0.33,0.33 0,0 0,-0.16 -0.3,0.76 0.76,0 0,0 -0.45,-0.1ZM60.41,139.42a0.34,0.34 0,0 0,0.16 -0.31c0,-0.29 -0.21,-0.43 -0.63,-0.43h-0.93v0.85h0.93A0.85,0.85 0,0 0,60.41 139.42Z"
android:fillColor="#263238"/>
<path
android:pathData="M64.27,139.39h-1.61l-0.31,0.74L61.54,140.13l1.54,-3.43h0.79l1.55,3.43h-0.84ZM64.02,138.79 L63.46,137.48 62.91,138.79Z"
android:fillColor="#263238"/>
<path
android:pathData="M66.32,137.34h-1.1L65.22,136.69h3.02v0.65h-1.1v2.76h-0.8Z"
android:fillColor="#263238"/>
<path
android:pathData="M69.42,137.34h-1.1L68.32,136.69L71.34,136.69v0.65h-1.1v2.76h-0.8Z"
android:fillColor="#263238"/>
<path
android:pathData="M74.44,139.49v0.63L71.76,140.13L71.76,136.69h2.61v0.63h-1.82v0.75h1.63L74.19,138.69h-1.6v0.8Z"
android:fillColor="#263238"/>
<path
android:pathData="M77.28,140.12l-0.67,-0.96h-0.74v0.96h-0.8L75.08,136.69h1.5a1.86,1.86 0,0 1,0.8 0.16,1.1 1.1,0 0,1 0.71,1.1 1.13,1.13 0,0 1,-0.19 0.66,1.19 1.19,0 0,1 -0.52,0.43l0.78,1.1ZM77.08,137.49a0.86,0.86 0,0 0,-0.55 -0.16h-0.65v1.2h0.65a0.83,0.83 0,0 0,0.55 -0.16,0.61 0.61,0 0,0 0,-0.88Z"
android:fillColor="#263238"/>
<path
android:pathData="M80.32,138.9v1.22h-0.8L79.52,138.9L78.18,136.69h0.85l0.92,1.52 0.92,-1.52h0.78Z"
android:fillColor="#263238"/>
<path
android:pathData="M77.82,128.96L47.44,128.96a4.04,4.04 0,0 1,-4.03 -4.03L43.41,67.48a4.04,4.04 0,0 1,4.03 -4.03h30.38a4.04,4.04 0,0 1,4.04 4.03L81.86,124.93A4.04,4.04 0,0 1,77.82 128.96ZM47.44,63.99a3.49,3.49 0,0 0,-3.48 3.48v57.45a3.49,3.49 0,0 0,3.48 3.48h30.38a3.49,3.49 0,0 0,3.49 -3.48L81.31,67.47a3.49,3.49 0,0 0,-3.49 -3.48Z"
android:fillColor="#263238"/>
<path
android:pathData="M55.35,58.05h14.54a1.71,1.71 0,0 1,1.71 1.71v3.93L53.64,63.69L53.64,59.76A1.71,1.71 0,0 1,55.35 58.05Z"
android:fillColor="#263238"/>
<path
android:pathData="M45.77,116.87h33.7v6.87a2.61,2.61 0,0 1,-2.61 2.61L48.38,126.34a2.61,2.61 0,0 1,-2.61 -2.61Z"
android:fillColor="#1b6dc1"/>
<path
android:pathData="M60.32,92.7a1.88,1.88 0,0 1,0.55 1.38,2.03 2.03,0 0,1 -1.2,1.88 3.31,3.31 0,0 1,-1.46 0.29,4.73 4.73,0 0,1 -1.45,-0.23 3.14,3.14 0,0 1,-1.14 -0.63l0.46,-0.8a2.64,2.64 0,0 0,0.93 0.55,3.44 3.44,0 0,0 1.2,0.21 1.96,1.96 0,0 0,1.23 -0.34,1.1 1.1,0 0,0 0.44,-0.92 1.06,1.06 0,0 0,-0.44 -0.91,2.18 2.18,0 0,0 -1.31,-0.33h-0.55v-0.71l1.77,-2.21h-3.39L55.95,89.08h4.65v0.66l-1.88,2.32a2.52,2.52 0,0 1,1.6 0.65Z"
android:fillColor="#263238"/>
<path
android:pathData="M62.03,92.35a2.36,2.36 0,0 1,0 -2.8,1.59 1.59,0 0,1 2.37,0 2.42,2.42 0,0 1,0 2.81,1.57 1.57,0 0,1 -2.37,0ZM63.94,91.95a2.06,2.06 0,0 0,0 -2,0.91 0.91,0 0,0 -1.45,0 2,2 0,0 0,0 1.99,0.91 0.91,0 0,0 1.45,0ZM67.47,89.08h0.78l-4.82,7.09h-0.77ZM66.5,95.71a2.42,2.42 0,0 1,0 -2.81,1.47 1.47,0 0,1 1.19,-0.55 1.49,1.49 0,0 1,1.19 0.55,2.38 2.38,0 0,1 0,2.8 1.59,1.59 0,0 1,-2.38 0ZM68.4,95.3a2,2 0,0 0,0 -1.99,0.85 0.85,0 0,0 -0.72,-0.37 0.86,0.86 0,0 0,-0.73 0.36,2.06 2.06,0 0,0 0,2 0.86,0.86 0,0 0,0.73 0.36,0.85 0.85,0 0,0 0.72,-0.37Z"
android:fillColor="#263238"/>
<path
android:pathData="M136.45,23.45a2.89,2.89 0,0 1,3.12 -1.23,3.94 3.94,0 0,1 4.85,0.49 3.58,3.58 0,0 1,3.47 0.22,3.63 3.63,0 0,1 1.59,3.1A3.01,3.01 0,0 1,152.41 27.85a3.05,3.05 0,0 1,-0.78 3.38,2.85 2.85,0 0,1 -1.66,5.41l-13.27,-9.83A2.93,2.93 0,0 1,136.45 23.45Z"
android:fillColor="#263238"/>
<path
android:pathData="M150.37,37.06a12.02,12.02 0,0 0,-11.02 -12.04l-0.62,-0.05c-6.71,-0.16 -9.32,5.86 -9.3,12.6l-1.46,24.97h0l9.85,10.08 3.71,-6.63 1.32,-6.63s6.5,-0.48 7.11,-6.93C150.27,49.37 150.36,42.91 150.37,37.06Z"
android:fillColor="#ffbf9d"/>
<path
android:pathData="M142.92,59.41A15.54,15.54 0,0 1,134.7 56.24s1.35,4.97 7.8,4.92Z"
android:fillColor="#ff9a6c"/>
<path
android:pathData="M148.01,42.89a0.92,0.92 0,0 1,-0.96 0.86,0.88 0.88,0 0,1 -0.87,-0.91 0.92,0.92 0,0 1,0.96 -0.86,0.88 0.88,0 0,1 0.88,0.91Z"
android:fillColor="#263238"/>
<path
android:pathData="M148.77,40.44c-0.12,0.11 -0.77,-0.46 -1.76,-0.55s-1.75,0.36 -1.85,0.23 0.08,-0.26 0.42,-0.47a2.49,2.49 0,0 1,1.49 -0.33,2.43 2.43,0 0,1 1.39,0.55C148.75,40.16 148.83,40.39 148.77,40.44Z"
android:fillColor="#263238"/>
<path
android:pathData="M139.53,42.62a0.92,0.92 0,0 1,-0.96 0.86,0.88 0.88,0 0,1 -0.88,-0.91 0.93,0.93 0,0 1,0.96 -0.86,0.89 0.89,0 0,1 0.88,0.91Z"
android:fillColor="#263238"/>
<path
android:pathData="M139.35,39.53c-0.12,0.11 -0.77,-0.46 -1.76,-0.55s-1.75,0.35 -1.85,0.23 0.08,-0.26 0.42,-0.47a2.49,2.49 0,0 1,1.49 -0.33,2.36 2.36,0 0,1 1.39,0.55C139.32,39.25 139.41,39.47 139.35,39.53Z"
android:fillColor="#263238"/>
<path
android:pathData="M141.99,47.15a6.11,6.11 0,0 1,1.62 -0.16c0.25,0 0.5,-0.04 0.55,-0.2a1.27,1.27 0,0 0,-0.1 -0.77c-0.19,-0.63 -0.38,-1.29 -0.59,-1.99a32.77,32.77 0,0 1,-1.26 -5.18,31.07 31.07,0 0,1 1.66,5.07c0.19,0.7 0.38,1.36 0.55,2a1.48,1.48 0,0 1,0.04 1,0.62 0.62,0 0,1 -0.44,0.34 1.48,1.48 0,0 1,-0.43 0A6.63,6.63 0,0 1,141.99 47.15Z"
android:fillColor="#263238"/>
<path
android:pathData="M139.03,47.59c0.16,0 0.08,1.1 0.93,1.92s2.01,0.82 2,0.97 -0.27,0.19 -0.76,0.17a2.68,2.68 0,0 1,-1.66 -0.75,2.36 2.36,0 0,1 -0.71,-1.61C138.82,47.84 138.96,47.58 139.03,47.59Z"
android:fillColor="#263238"/>
<path
android:pathData="M139.59,36.71c-0.14,0.25 -0.97,-0.05 -2,-0.12s-1.91,0.08 -1.99,-0.19c-0.04,-0.13 0.16,-0.35 0.55,-0.55a3.12,3.12 0,0 1,1.56 -0.28,2.98 2.98,0 0,1 1.48,0.51C139.51,36.33 139.67,36.57 139.59,36.71Z"
android:fillColor="#263238"/>
<path
android:pathData="M148.77,37.7c-0.18,0.23 -0.86,0 -1.66,0s-1.51,0.15 -1.66,-0.08c-0.07,-0.12 0.04,-0.34 0.34,-0.55a2.41,2.41 0,0 1,2.7 0.08C148.75,37.36 148.85,37.59 148.77,37.7Z"
android:fillColor="#263238"/>
<path
android:pathData="M149.99,34.05s-1.36,-4.18 -3.22,-5.29c-2.25,-1.33 -3.47,1.18 -5.66,0.37s-4.33,-2.09 -6.76,-0.55c-2.66,1.7 -1.6,3.13 -1.98,5.98 -1.58,11.56 -3.96,14.67 -4.11,9.15 0,-0.6 -1.63,-1.22 -1.66,-3.77 -0.05,-3.31 0.16,-7.31 1.08,-9.58A9.21,9.21 0,0 1,131.79 25.85c3.35,-2.1 7.68,-1.8 10.6,-1.26S150.68,29.01 149.99,34.05Z"
android:fillColor="#263238"/>
<path
android:pathData="M129.49,43.64a1.76,1.76 0,0 0,-1.74 -1.85c-1.21,0 -2.6,0.59 -2.72,3.09 -0.22,4.42 4.24,3.73 4.25,3.6S129.42,45.49 129.49,43.64Z"
android:fillColor="#ffbf9d"/>
<path
android:pathData="M128.41,46.78a1.47,1.47 0,0 1,-0.21 0.1,0.77 0.77,0 0,1 -0.55,0 1.9,1.9 0,0 1,-0.79 -1.76,2.5 2.5,0 0,1 0.27,-1.1 0.88,0.88 0,0 1,0.6 -0.55,0.39 0.39,0 0,1 0.44,0.23c0.05,0.13 0,0.21 0.04,0.22s0.1,-0.07 0.07,-0.25a0.49,0.49 0,0 0,-0.16 -0.29,0.55 0.55,0 0,0 -0.41,-0.13 1.1,1.1 0,0 0,-0.86 0.65,2.71 2.71,0 0,0 -0.33,1.22 2.03,2.03 0,0 0,1.02 1.97,0.82 0.82,0 0,0 0.71,-0.08C128.4,46.89 128.43,46.79 128.41,46.78Z"
android:fillColor="#ff9a6c"/>
<path
android:pathData="M129.47,35.05A4.25,4.25 0,0 0,131.25 36.07a1.44,1.44 0,0 0,1.66 -0.88c0.08,-0.3 0.03,-0.66 0.25,-0.88s0.7,-0.14 1.06,-0.07a2.82,2.82 0,0 0,3.08 -1.78,1.17 1.17,0 0,0 1.56,0.28 6.14,6.14 0,0 0,1.3 -1.19,1.83 1.83,0 0,1 1.57,-0.63 4.2,4.2 0,0 0,0.94 0.29c0.58,0 0.92,-0.66 1.05,-1.23s0.26,-1.24 0.77,-1.51a2.19,2.19 0,0 1,1.57 0.08c0.52,0.12 1.22,0.05 1.4,-0.45a1.05,1.05 0,0 0,-0.13 -0.82,2.85 2.85,0 0,0 -3.25,-1.38 3.87,3.87 0,0 0,-7.02 -1.34,3.92 3.92,0 0,0 -6.37,0.92 2.9,2.9 0,0 0,-3.04 0.77,2.94 2.94,0 0,0 -0.5,3.12 2.76,2.76 0,0 0,-1.66 2.04c-0.09,0.91 0.72,1.89 1.62,1.72a1.58,1.58 0,0 0,2.59 1.8"
android:fillColor="#263238"/>
<path
android:pathData="M126.8,33.09a1.03,1.03 0,0 0,0.2 0.87,1.44 1.44,0 0,0 0.84,0.6 1.52,1.52 0,0 0,1.28 -0.26l-0.19,-0.04a4.42,4.42 0,0 0,0.79 1.18,2.51 2.51,0 0,0 0.76,0.55 1.72,1.72 0,0 0,0.9 0.18,1.74 1.74,0 0,0 1.33,-0.62 2.71,2.71 0,0 0,0.43 -0.89c0.06,-0.23 0.08,-0.35 0.06,-0.35a1.25,1.25 0,0 0,-0.16 0.32,3.19 3.19,0 0,1 -0.47,0.81 1.79,1.79 0,0 1,-2.64 -0.16,4.5 4.5,0 0,1 -0.75,-1.1L129.11,34.03l-0.12,0.09a1.35,1.35 0,0 1,-1.1 0.25,1.25 1.25,0 0,1 -0.76,-0.49 2.13,2.13 0,0 1,-0.33 -0.79Z"
android:fillColor="#455a64"/>
<path
android:pathData="M135.92,23.69a2.24,2.24 0,0 1,0.3 0.14,1.59 1.59,0 0,1 0.63,0.64l0.05,0.09 0.07,-0.08a5.52,5.52 0,0 1,2.27 -1.55,4.16 4.16,0 0,1 1.76,-0.24 3.55,3.55 0,0 1,1.82 0.69,3.63 3.63,0 0,1 1.02,1.14 3.08,3.08 0,0 1,0.38 1.37v0.14h0.14a2.45,2.45 0,0 1,1.81 0.38,2.41 2.41,0 0,1 0.91,1.15 3.24,3.24 0,0 1,0.17 1.33,0.95 0.95,0 0,0 0.08,-0.36 2.35,2.35 0,0 0,-0.12 -1.02,2.48 2.48,0 0,0 -0.93,-1.27 2.67,2.67 0,0 0,-1.96 -0.44l0.14,0.12a3.26,3.26 0,0 0,-0.39 -1.49,3.83 3.83,0 0,0 -1.1,-1.23 3.74,3.74 0,0 0,-1.94 -0.73,4.42 4.42,0 0,0 -1.86,0.28 5.36,5.36 0,0 0,-2.29 1.66h0.11a1.52,1.52 0,0 0,-0.72 -0.64A0.64,0.64 0,0 0,135.92 23.69Z"
android:fillColor="#455a64"/>
<path
android:pathData="M139.23,222.98l-3.87,13.98s12.4,8.79 11.91,11.45l-26.4,-6.85 5.2,-22.04Z"
android:fillColor="#455a64"/>
<path
android:pathData="M127.46,233.65a1.11,1.11 0,0 0,-0.03 2.21,1.19 1.19,0 0,0 1.1,-1.15c-0.05,-0.55 -0.66,-1.15 -1.19,-1.02"
android:fillColor="#e0e0e0"/>
<path
android:pathData="M120.85,241.56l0.61,-2.21 25.09,7.39s1.05,0.83 0.71,1.66Z"
android:strokeAlpha="0.6"
android:fillColor="#fff"
android:fillAlpha="0.6"/>
<path
android:pathData="M135.8,236.93c-0.04,0.13 -0.7,0.03 -1.44,0.29s-1.21,0.74 -1.32,0.65 0.27,-0.81 1.17,-1.1S135.86,236.82 135.8,236.93Z"
android:fillColor="#263238"/>
<path
android:pathData="M138.28,238.84c0,0.14 -0.61,0.22 -1.19,0.67s-0.85,1.02 -0.97,0.98 -0.03,-0.82 0.7,-1.36S138.31,238.71 138.28,238.84Z"
android:fillColor="#263238"/>
<path
android:pathData="M139.03,242.68c-0.13,0 -0.14,-0.72 0.37,-1.36s1.18,-0.78 1.21,-0.65 -0.44,0.42 -0.85,0.96S139.16,242.7 139.03,242.68Z"
android:fillColor="#263238"/>
<path
android:pathData="M136.35,233.64c-0.08,0.1 -0.63,-0.23 -1.37,-0.37s-1.36,-0.04 -1.4,-0.18 0.62,-0.47 1.49,-0.29S136.44,233.56 136.35,233.64Z"
android:fillColor="#263238"/>
<path
android:pathData="M129.97,226.27l-0.61,14.54s14.04,5.52 14.18,8.23l-27.22,-0.22 0.05,-22.69Z"
android:fillColor="#455a64"/>
<path
android:pathData="M120.95,239.51a1.15,1.15 0,0 0,-0.78 1.31,1.07 1.07,0 0,0 1.24,0.81 1.22,1.22 0,0 0,0.82 -1.39,1.1 1.1,0 0,0 -1.38,-0.7"
android:fillColor="#e0e0e0"/>
<path
android:pathData="M116.32,248.81l0.09,-2.29 26.06,1.07s1.21,0.55 1.07,1.44Z"
android:strokeAlpha="0.6"
android:fillColor="#fff"
android:fillAlpha="0.6"/>
<path
android:pathData="M129.8,240.67c0,0.14 -0.67,0.19 -1.33,0.63s-1.01,1.01 -1.13,0.96 0.08,-0.85 0.88,-1.36S129.83,240.54 129.8,240.67Z"
android:fillColor="#263238"/>
<path
android:pathData="M132.65,241.91c0,0.13 -0.55,0.37 -1,0.94s-0.59,1.19 -0.72,1.19 -0.21,-0.79 0.37,-1.5S132.65,241.78 132.65,241.91Z"
android:fillColor="#263238"/>
<path
android:pathData="M134.24,245.47c-0.12,0.03 -0.3,-0.66 0.04,-1.41s0.97,-1.05 1.03,-0.93 -0.33,0.52 -0.61,1.14S134.38,245.46 134.24,245.47Z"
android:fillColor="#263238"/>
<path
android:pathData="M129.59,237.34c-0.05,0.12 -0.66,-0.07 -1.41,-0.03s-1.34,0.29 -1.41,0.17 0.5,-0.61 1.38,-0.65S129.65,237.23 129.59,237.34Z"
android:fillColor="#263238"/>
<path
android:pathData="M129.93,237.17a23.97,23.97 0,0 1,0.04 3.5l-0.11,-0.17c1.59,0.63 3.71,1.48 5.95,2.57a31.9,31.9 0,0 1,6.03 3.6,6.45 6.45,0 0,1 1.49,1.58c0.28,0.45 0.25,0.8 0.2,0.78a2.07,2.07 0,0 0,-0.35 -0.68,7.7 7.7,0 0,0 -1.54,-1.41 38.58,38.58 0,0 0,-6.03 -3.44c-2.21,-1.1 -4.32,-1.97 -5.88,-2.67l-0.12,-0.05v-0.12a24.37,24.37 0,0 1,0.31 -3.49Z"
android:fillColor="#263238"/>
<path
android:pathData="M117.5,120.2l-2.65,19.29 2.72,40.67s-1.66,19.73 -2.71,30.86c-0.89,9.67 0.55,26.51 0.55,26.51h15.73l5.63,-56.17 3.5,-35.03 6.08,-15.94C141.1,129.71 129.06,124.81 117.5,120.2Z"
android:fillColor="#263238"/>
<path
android:pathData="M153.01,126.1l0.26,61.5 -15.92,42.48 -0.74,2.56 -9.4,-2.36 6.99,-100.52Z"
android:fillColor="#263238"/>
<path
android:pathData="M142.16,138.78a1.76,1.76 0,0 1,0 0.25v0.75c0,0.68 -0.05,1.66 -0.1,2.89 -0.07,2.51 -0.26,6.15 -0.55,10.63 -0.55,8.97 -1.66,21.35 -3.31,34.98s-3.5,25.92 -4.81,34.84c-0.67,4.42 -1.23,8.03 -1.61,10.53 -0.19,1.23 -0.34,2.21 -0.45,2.86 -0.05,0.31 -0.09,0.55 -0.13,0.75a0.92,0.92 0,0 1,-0.05 0.25,2.19 2.19,0 0,1 0,-0.26 6.77,6.77 0,0 1,0.09 -0.75c0.09,-0.67 0.22,-1.66 0.39,-2.87 0.35,-2.51 0.86,-6.11 1.49,-10.55 1.26,-8.91 3.05,-21.22 4.7,-34.85s2.79,-26 3.42,-34.96c0.31,-4.48 0.55,-8.11 0.66,-10.62 0.07,-1.24 0.13,-2.21 0.17,-2.89 0,-0.32 0.04,-0.55 0.05,-0.75A0.99,0.99 0,0 1,142.16 138.78Z"
android:fillColor="#455a64"/>
<path
android:pathData="M160.54,88.44l3.87,-2.55s2.08,-4.42 3.54,-4.97 7.29,-2.76 7.29,-2.76 0.83,1.57 -1.25,2.76a42.49,42.49 0,0 0,-3.87 2.48s0.32,4.46 -2.59,5.73l-5.68,2.47Z"
android:fillColor="#ffbf9d"/>
<path
android:pathData="M175.57,91.37a7.13,7.13 0,0 1,-3.47 1.55,46.56 46.56,0 0,1 -6.63,0c-0.15,0.05 -2.53,2.16 -2.53,2.16l-1.35,-5.19 9.73,-6.4 7.01,2.62 -1.75,2.99 -2.45,-0.46 -0.59,1.61Z"
android:fillColor="#ffbf9d"/>
<path
android:pathData="M162.97,85.63l1.77,9.71 -14.81,8.04 -0.61,-13.42Z"
android:fillColor="#f5faff"/>
<path
android:pathData="M144.89,68.55c0.28,0.66 4.15,13 5.45,19.37 1.05,5.15 2.81,37.31 2.81,37.31L153.15,132.4c-9.06,3.44 -22.29,1.48 -36.39,-1.62L115.36,126.7s2.65,-17.06 1.54,-23.89 -0.95,-21.75 -0.39,-28.58c0.44,-5.45 8.1,-11.32 10.93,-13.58l0.72,-1.72 13.91,3.96 0.35,2.07Z"
android:fillColor="#f5faff"/>
<path
android:pathData="M194.37,100.29L188.44,100.29a1.53,1.53 0,0 1,-1.53 -1.53l-0,-0.24a1.53,1.53 0,0 1,1.53 -1.53L194.37,96.99L194.37,100.29Z"
android:fillColor="#e0e0e0"/>
<path
android:pathData="M179.38,85.55l5.36,-6.15a0.41,0.41 0,0 0,-0.04 -0.55l-5.14,-4.34a0.4,0.4 0,0 0,-0.55 0.04l-10.62,12.1a0.4,0.4 0,0 0,0.04 0.55l5.02,4.39a0.4,0.4 0,0 0,0.55 -0.03l5.39,-6.02"
android:fillColor="#455a64"/>
<path
android:pathData="M171.38,89.72c-0.16,0.15 -1.83,1.8 -1.83,1.8l-1.23,-1.18 1.76,-1.76Z"
android:fillColor="#e0e0e0"/>
<path
android:pathData="M197.62,98.94L194.36,98.94L194.36,97.88L197.62,97.88a0.49,0.49 0,0 1,0.5 0.5L198.12,98.46A0.49,0.49 0,0 1,197.62 98.94Z"
android:fillColor="#263238"/>
<path
android:pathData="M173.5,102.62l4.39,-0.87s3.31,-3.91 5.41,-4.3a18.84,18.84 0,0 0,4.78 -1.96s1.24,0.06 1.17,1.19c-0.04,0.67 -0.63,0.95 -1.03,1.35l-2.56,1.56s5.23,-0.68 5.85,0.2 0.18,1.66 -1.04,1.96a18.5,18.5 0,0 1,-2.5 0.47s1.66,1.98 0.32,3.05c0,0 0.1,1.86 -1.46,2.25a3.2,3.2 0,0 1,-2.88 1.86,15.88 15.88,0 0,1 -4.34,-0.29c-1.46,-0.43 -5.23,1.26 -5.23,1.26Z"
android:fillColor="#ffbf9d"/>
<path
android:fillColor="#FF000000"
android:pathData="M121.59,82.91s3.11,25.12 15.58,32.96c3.42,2.15 15.58,2.21 15.58,2.21v-7.73Z"
android:strokeAlpha="0.3"
android:fillAlpha="0.3"/>
<path
android:pathData="M130.07,65.89c5.03,0.74 8.74,12.85 8.74,12.85l9.25,21.04s18.31,1.56 21.95,1.56a36.44,36.44 0,0 0,5.06 -0.85l0.14,0.26c1.87,3.42 1.66,9.94 1.66,9.94a127.97,127.97 0,0 1,-14.16 3.25c-7.18,0.99 -22.87,-0.51 -25.78,-3.35s-18.52,-31.49 -18.31,-36.25"
android:fillColor="#f5faff"/>
<path
android:pathData="M118.62,74.39a3.69,3.69 0,0 0,0.03 0.41,7.73 7.73,0 0,0 0.24,1.17 36.3,36.3 0,0 0,1.57 4.34c1.55,3.69 4.08,8.91 7.47,15.23 1.7,3.16 3.6,6.6 5.78,10.19q0.82,1.35 1.71,2.71c0.3,0.45 0.61,0.91 0.94,1.34a4.42,4.42 0,0 0,1.14 1.15,11.82 11.82,0 0,0 3.11,1.28c1.1,0.31 2.25,0.55 3.41,0.78a70.82,70.82 0,0 0,7.18 0.92,72.91 72.91,0 0,0 7.57,0.23 35.33,35.33 0,0 0,3.87 -0.29c1.29,-0.18 2.59,-0.42 3.87,-0.69 2.6,-0.55 5.23,-1.19 7.87,-1.89l2.4,-0.67 -0.1,0.14a35.5,35.5 0,0 0,-0.31 -5.27,14.09 14.09,0 0,0 -1.48,-4.89l0.13,0.08c-0.55,0.09 -1.18,0.25 -1.77,0.38s-1.19,0.24 -1.79,0.33a16.44,16.44 0,0 1,-3.61 0.06c-2.36,-0.13 -4.68,-0.29 -6.94,-0.46q-6.79,-0.51 -12.91,-1.04L147.92,99.92l-0.03,-0.07 -9.21,-21.06h0c-1.57,-4.83 -3.46,-8.46 -5.23,-10.56a7.47,7.47 0,0 0,-2.4 -1.98,5.55 5.55,0 0,0 -1.02,-0.34l0.27,0.04a3.61,3.61 0,0 1,0.77 0.25,7.3 7.3,0 0,1 2.45,1.96c1.81,2.1 3.73,5.72 5.33,10.57h0l9.33,21 -0.1,-0.07c4.07,0.34 8.39,0.69 12.91,1.02 2.27,0.17 4.58,0.33 6.94,0.45a16.58,16.58 0,0 0,3.55 -0.06c0.59,-0.09 1.18,-0.2 1.78,-0.33s1.15,-0.28 1.82,-0.39h0.07l0.05,0.09a14.26,14.26 0,0 1,1.51 4.97,35.35 35.35,0 0,1 0.31,5.31v0.1h-0.1l-2.41,0.67c-2.64,0.71 -5.27,1.36 -7.88,1.89 -1.3,0.26 -2.61,0.51 -3.91,0.69a36.02,36.02 0,0 1,-3.9 0.29,74.98 74.98,0 0,1 -7.6,-0.23 71.55,71.55 0,0 1,-7.23 -0.93c-1.17,-0.22 -2.32,-0.47 -3.43,-0.79a11.99,11.99 0,0 1,-3.18 -1.32,4.68 4.68,0 0,1 -1.2,-1.2c-0.34,-0.45 -0.65,-0.91 -0.95,-1.36 -0.6,-0.91 -1.17,-1.82 -1.71,-2.72 -2.18,-3.61 -4.07,-7.06 -5.76,-10.22 -3.37,-6.33 -5.87,-11.57 -7.4,-15.29a34.36,34.36 0,0 1,-1.52 -4.36,7.18 7.18,0 0,1 -0.21,-1.18C118.62,74.53 118.62,74.39 118.62,74.39Z"
android:fillColor="#263238"/>
<path
android:pathData="M172.81,108.38L172.35,108.38a7.82,7.82 0,0 1,-7.05 -5.47,6.78 6.78,0 0,1 1.2,-5.73 4.82,4.82 0,0 1,-0.31 -3.46,7.48 7.48,0 0,1 3.02,-3.89l0.24,0.34a7.08,7.08 0,0 0,-2.86 3.67,4.38 4.38,0 0,0 0.2,2.99 5.74,5.74 0,0 1,2.44 -1.68c1.17,-0.39 2.65,-0.22 3.12,0.88a2,2 0,0 1,-0.26 1.87,2.84 2.84,0 0,1 -1.98,1.18 3.42,3.42 0,0 1,-2.63 -0.68,3.51 3.51,0 0,1 -0.74,-0.82 6.34,6.34 0,0 0,-1.02 5.24,7.41 7.41,0 0,0 6.67,5.16 9.32,9.32 0,0 0,7.78 -3.87c0.35,-0.48 0.66,-1 0.97,-1.51a13.69,13.69 0,0 1,1.66 -2.33c1.06,-1.14 2.82,-2 4.36,-1.34l-0.17,0.38c-1.35,-0.58 -2.93,0.21 -3.9,1.24a13.65,13.65 0,0 0,-1.58 2.25c-0.31,0.51 -0.63,1.04 -0.99,1.54a9.68,9.68 0,0 1,-7.7 4.04ZM167.01,97.2a3.26,3.26 0,0 0,0.73 0.85,2.99 2.99,0 0,0 2.32,0.6 2.42,2.42 0,0 0,1.7 -1,1.6 1.6,0 0,0 0.23,-1.47c-0.35,-0.84 -1.6,-0.99 -2.6,-0.65A5.38,5.38 0,0 0,167.01 97.2Z"
android:fillColor="#e0e0e0"/>
<path
android:pathData="M183.68,79.01l-10.13,11.33 -4.41,-3.72L179.17,75.25Z"
android:fillColor="#263238"/>
<path
android:pathData="M178.51,85.3c0.16,0 1.54,0.25 1.86,0.7s0,1.8 -0.93,1.85a2.81,2.81 0,0 1,-2.4 -0.92C176.68,86.32 176.81,85.14 178.51,85.3Z"
android:fillColor="#ffbf9d"/>
<path
android:pathData="M173.65,88.24a1.02,1.02 0,0 1,1 -1.07c1.36,-0.05 4.35,-0.08 4.8,0.69 0.58,0.99 0.26,1.66 -0.8,1.75s-3.93,-0.1 -4.67,-0.75A0.9,0.9 0,0 1,173.65 88.24Z"
android:fillColor="#ffbf9d"/>
<path
android:pathData="M173.36,88.81s0.1,-0.5 1.54,0.22 3.19,0.87 2.76,1.66a1.76,1.76 0,0 1,-2.55 0.8C173.92,90.85 172.16,90.4 173.36,88.81Z"
android:fillColor="#ffbf9d"/>
<path
android:pathData="M149.95,85.37c0.08,0 0.49,3.31 0.91,7.39s0.71,7.43 0.62,7.43 -0.49,-3.31 -0.91,-7.39S149.87,85.38 149.95,85.37Z"
android:fillColor="#263238"/>
<path
android:pathData="M144.28,105.12a8.2,8.2 0,0 1,1.41 -3.06,8.32 8.32,0 0,1 2.33,-2.44c0.06,0.07 -1.06,1.08 -2.09,2.6S144.36,105.16 144.28,105.12Z"
android:fillColor="#263238"/>
<path
android:pathData="M127.43,61.15a2.3,2.3 0,0 1,0.6 0.14l1.59,0.49 5.2,1.66c2.04,0.65 3.87,1.21 5.23,1.61l1.59,0.49a2.57,2.57 0,0 1,0.55 0.21,2.21 2.21,0 0,1 -0.6,-0.1c-0.38,-0.08 -0.93,-0.22 -1.61,-0.4 -1.35,-0.35 -3.21,-0.88 -5.25,-1.53s-3.87,-1.28 -5.19,-1.75c-0.66,-0.24 -1.19,-0.44 -1.56,-0.55A2.76,2.76 0,0 1,127.43 61.15Z"
android:fillColor="#263238"/>
</vector>

View File

@@ -0,0 +1,5 @@
<vector xmlns:android="http://schemas.android.com/apk/res/android" android:height="24dp" android:tint="#000000" android:viewportHeight="24" android:viewportWidth="24" android:width="24dp">
<path android:fillColor="@android:color/white" android:pathData="M12,2C6.48,2 2,6.48 2,12s4.48,10 10,10 10,-4.48 10,-10S17.52,2 12,2zM4,12c0,-4.42 3.58,-8 8,-8 1.85,0 3.55,0.63 4.9,1.69L5.69,16.9C4.63,15.55 4,13.85 4,12zM12,20c-1.85,0 -3.55,-0.63 -4.9,-1.69L18.31,7.1C19.37,8.45 20,10.15 20,12c0,4.42 -3.58,8 -8,8z"/>
</vector>

Binary file not shown.

After

Width:  |  Height:  |  Size: 7.7 KiB

View File

@@ -0,0 +1,10 @@
<vector xmlns:android="http://schemas.android.com/apk/res/android"
android:width="29.96dp"
android:height="122.88dp"
android:viewportWidth="29.96"
android:viewportHeight="122.88">
<path
android:fillColor="#FF000000"
android:pathData="M15,0A15,15 0,1 1,0 15,15 15,0 0,1 15,0ZM15,92.93a15,15 0,1 1,-15 15,15 15,0 0,1 15,-15ZM15,46.46a15,15 0,1 1,-15 15,15 15,0 0,1 15,-15Z"
android:fillType="evenOdd"/>
</vector>

File diff suppressed because one or more lines are too long

Binary file not shown.

After

Width:  |  Height:  |  Size: 47 KiB

View File

@@ -0,0 +1,14 @@
<vector xmlns:android="http://schemas.android.com/apk/res/android"
android:width="22.746dp"
android:height="22.746dp"
android:viewportWidth="128"
android:viewportHeight="128">
<path
android:pathData="M14.4,19.4l-3.4,3.4 0,30.4c0,33.7 0,33.6 6.6,36.4 4.9,2.1 87.9,2.1 92.8,-0 6.6,-2.8 6.6,-2.7 6.6,-36.4l0,-30.4 -3.4,-3.4 -3.4,-3.4 -46.2,-0 -46.2,-0 -3.4,3.4zM37,37.5l0,5.5 -5,-0 -5,-0 0,-5.5 0,-5.5 5,-0 5,-0 0,5.5zM53,37.5l0,5.5 -5,-0 -5,-0 0,-5.5 0,-5.5 5,-0 5,-0 0,5.5zM69,37.5l0,5.5 -5,-0 -5,-0 0,-5.5 0,-5.5 5,-0 5,-0 0,5.5zM85,37.5l0,5.5 -5,-0 -5,-0 0,-5.5 0,-5.5 5,-0 5,-0 0,5.5zM101,37.5l0,5.5 -5,-0 -5,-0 0,-5.5 0,-5.5 5,-0 5,-0 0,5.5zM37,53.5l0,5.5 -5,-0 -5,-0 0,-5.5 0,-5.5 5,-0 5,-0 0,5.5zM53,53.5l0,5.5 -5,-0 -5,-0 0,-5.5 0,-5.5 5,-0 5,-0 0,5.5zM69,53.5l0,5.5 -5,-0 -5,-0 0,-5.5 0,-5.5 5,-0 5,-0 0,5.5zM85,53.5l0,5.5 -5,-0 -5,-0 0,-5.5 0,-5.5 5,-0 5,-0 0,5.5zM101,53.5l0,5.5 -5,-0 -5,-0 0,-5.5 0,-5.5 5,-0 5,-0 0,5.5zM85,74.5l0,5.5 -21,-0 -21,-0 0,-5.5 0,-5.5 21,-0 21,-0 0,5.5z"
android:fillColor="#000000"
android:strokeColor="#00000000"/>
<path
android:pathData="M53.3,111.7l10.7,10.8 10.7,-10.8 10.8,-10.7 -21.5,-0 -21.5,-0 10.8,10.7z"
android:fillColor="#000000"
android:strokeColor="#00000000"/>
</vector>

View File

@@ -47,6 +47,7 @@
android:id="@+id/contact_rv"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:layout_marginTop="10dp"
android:layout_marginHorizontal="15dp"
android:overScrollMode="never" />

View File

@@ -1,299 +1,485 @@
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
<androidx.coordinatorlayout.widget.CoordinatorLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
android:layout_width="match_parent"
android:layout_height="match_parent"
xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools"
android:orientation="vertical"
android:background="@color/white">
<ImageView
android:id="@+id/back_btn"
android:layout_width="35sp"
android:layout_height="35sp"
android:layout_margin="15dp"
android:contentDescription="@string/back_button"
android:padding="5dp"
android:paddingStart="-15dp"
android:paddingEnd="0dp"
android:src="@drawable/arrow_back" />
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="@string/geofencing"
android:fontFamily="@font/nunito_medium"
android:textColor="@color/black"
android:textSize="@dimen/_18ssp"
android:layout_marginHorizontal="15dp"
/>
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="@string/set_specific_geographic_areas_and_receive_instant_alerts_when_your_loved_one_leaves_the_geofenced_zone"
android:fontFamily="@font/nunito_regular"
android:layout_marginHorizontal="15dp"
android:textSize="@dimen/_14ssp"
android:layout_marginVertical="15dp"
/>
<RelativeLayout
<LinearLayout
android:layout_width="match_parent"
android:layout_height="match_parent">
android:layout_height="match_parent"
android:background="@color/white"
android:orientation="vertical">
<fragment
android:id="@+id/geofence_map"
android:name="com.google.android.gms.maps.SupportMapFragment"
<RelativeLayout
android:layout_width="match_parent"
android:layout_height="match_parent"/>
android:layout_height="?attr/actionBarSize"
android:gravity="center_vertical"
android:elevation="5dp"
android:orientation="horizontal">
<com.google.android.material.card.MaterialCardView
android:id="@+id/search"
android:visibility="gone"
android:layout_width="match_parent"
android:layout_height="wrap_content"
<ImageView
android:id="@+id/back_btn"
android:layout_width="40dp"
android:layout_height="40dp"
android:layout_marginStart="5dp"
android:contentDescription="@string/back_button"
android:padding="5dp"
android:layout_centerVertical="true"
android:src="@drawable/quantum_ic_arrow_back_grey600_24"
app:tint="@color/black" />
android:layout_marginHorizontal="@dimen/_10sdp"
android:layout_marginTop="@dimen/_10sdp"
app:cardBackgroundColor="@color/white"
app:cardElevation="5dp"
app:strokeWidth="0.5dp"
app:strokeColor="@color/color_accent"
app:cardCornerRadius="20dp"
>
<TextView
<LinearLayout
android:id="@+id/head_titles"
android:layout_centerVertical="true"
android:layout_toEndOf="@id/back_btn"
android:layout_toStartOf="@id/refresh_btn"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginEnd="15dp"
android:layout_marginStart="5dp"
android:orientation="vertical">
android:text="@string/enter_new_address_here"
android:fontFamily="@font/nunito_regular"
android:textColor="@android:color/darker_gray"
android:textSize="@dimen/_14ssp"
<TextView
android:id="@+id/senior_name_title"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginVertical="10dp"
android:layout_marginHorizontal="15dp"
android:visibility="gone"
app:drawableStartCompat="@drawable/ic_search_outline"
android:drawablePadding="15dp"
android:ellipsize="end"
android:fontFamily="@font/nunito_semibold"
android:singleLine="true"
tools:text="Aditya"
android:textAppearance="@style/TextAppearance.Material3.TitleMedium"
android:textColor="@color/black"
/>
<TextView
android:id="@+id/last_updated"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:visibility="gone"
tools:text="Last updated at 02 sep 2023 at 05:35 pm"
android:ellipsize="end"
android:fontFamily="@font/nunito_regular"
android:singleLine="true"
android:textAppearance="@style/TextAppearance.Material3.TitleSmall"
android:textColor="@android:color/black"
/>
</LinearLayout>
<ImageView
android:id="@+id/refresh_btn"
android:visibility="gone"
android:layout_centerVertical="true"
android:layout_alignParentEnd="true"
android:layout_width="30dp"
android:layout_height="30dp"
android:layout_marginEnd="15dp"
android:contentDescription="@string/back_button"
android:padding="5dp"
android:src="@drawable/ic_refresh"
/>
</com.google.android.material.card.MaterialCardView>
</RelativeLayout>
<com.google.android.material.card.MaterialCardView
android:layout_below="@id/search"
android:layout_width="match_parent"
<TextView
android:id="@+id/geofencing_title"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginHorizontal="@dimen/_10sdp"
android:layout_marginTop="@dimen/_10sdp"
android:layout_marginHorizontal="15dp"
android:fontFamily="@font/nunito_medium"
android:text="@string/geofencing"
android:textColor="@color/black"
app:cardBackgroundColor="@color/white"
app:cardElevation="5dp"
android:textSize="@dimen/_18ssp"
android:visibility="visible"
app:strokeWidth="1dp"
app:strokeColor="@color/color_accent"
/>
app:cardCornerRadius="10dp"
<TextView
android:id="@+id/geofencing_sub_title"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
>
android:layout_marginHorizontal="15dp"
android:layout_marginVertical="15dp"
android:fontFamily="@font/nunito_regular"
android:text="@string/set_specific_geographic_areas_and_receive_instant_alerts_when_your_loved_one_leaves_the_geofenced_zone"
<RelativeLayout
android:textSize="@dimen/_14ssp"
android:visibility="visible"
/>
<RelativeLayout
android:layout_width="match_parent"
android:layout_height="match_parent">
<fragment
android:id="@+id/geofence_map"
android:name="com.google.android.gms.maps.SupportMapFragment"
android:layout_width="match_parent"
android:layout_height="match_parent">
android:layout_height="match_parent" />
<com.google.android.material.card.MaterialCardView
android:id="@+id/search"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginHorizontal="@dimen/_10sdp"
android:layout_marginTop="@dimen/_10sdp"
android:visibility="gone"
app:cardBackgroundColor="@color/white"
app:cardCornerRadius="20dp"
app:cardElevation="5dp"
app:strokeColor="@color/color_accent"
app:strokeWidth="0.5dp"
>
<TextView
android:id="@+id/distance_away_txt"
android:visibility="gone"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="@string/destination_0_5m_away"
android:fontFamily="@font/nunito_regular"
android:textColor="@color/black"
android:textSize="@dimen/_14ssp"
android:layout_marginTop="15dp"
android:layout_marginHorizontal="15dp"
/>
<TextView
android:id="@+id/senior_title"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="@string/senior_address"
android:fontFamily="@font/nunito_bold"
android:textColor="@color/black"
android:textSize="@dimen/_14ssp"
android:layout_marginHorizontal="15dp"
android:layout_marginTop="5dp"
/>
<TextView
android:id="@+id/home_address"
android:layout_below="@id/senior_title"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_toStartOf="@id/set_gf"
android:text="@string/loading"
android:fontFamily="@font/nunito_regular"
android:textColor="@android:color/black"
android:textSize="@dimen/_14ssp"
android:layout_marginHorizontal="15dp"
android:layout_marginBottom="5dp"
android:layout_marginVertical="10dp"
android:drawablePadding="15dp"
android:fontFamily="@font/nunito_regular"
android:maxLines="2"
android:ellipsize="end"
android:text="@string/enter_new_address_here"
android:textColor="@android:color/darker_gray"
android:textSize="@dimen/_14ssp"
app:drawableStartCompat="@drawable/ic_search_outline"
/>
<ImageView
android:id="@+id/set_gf"
android:layout_width="25dp"
android:layout_height="25dp"
</com.google.android.material.card.MaterialCardView>
android:layout_alignParentEnd="true"
<com.google.android.material.card.MaterialCardView
android:id="@+id/update_geofence_box"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginVertical="8dp"
android:layout_marginEnd="8dp"
android:layout_below="@id/search"
android:layout_marginHorizontal="@dimen/_10sdp"
android:padding="3dp"
app:srcCompat="@drawable/ic_setting"
app:tint="@color/black" />
android:layout_marginTop="@dimen/_10sdp"
android:visibility="visible"
app:cardBackgroundColor="@color/white"
app:cardCornerRadius="10dp"
app:cardElevation="5dp"
app:strokeColor="@color/color_accent"
app:strokeWidth="1dp"
>
<RelativeLayout
android:layout_width="match_parent"
android:layout_height="match_parent">
<TextView
android:id="@+id/distance_away_txt"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginHorizontal="15dp"
android:layout_marginTop="15dp"
android:fontFamily="@font/nunito_regular"
android:text="@string/destination_0_5m_away"
android:textColor="@color/black"
android:textSize="@dimen/_14ssp"
android:visibility="gone"
/>
<TextView
android:id="@+id/senior_title"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginHorizontal="15dp"
android:layout_marginTop="5dp"
android:fontFamily="@font/nunito_bold"
android:text="@string/senior_address"
android:textColor="@color/black"
android:textSize="@dimen/_14ssp"
/>
<TextView
android:id="@+id/home_address"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_below="@id/senior_title"
android:layout_marginHorizontal="15dp"
android:layout_marginBottom="5dp"
android:layout_toStartOf="@id/set_gf"
android:ellipsize="end"
android:fontFamily="@font/nunito_regular"
android:maxLines="2"
android:text="@string/loading"
android:textColor="@android:color/black"
android:textSize="@dimen/_14ssp"
/>
<ImageView
android:id="@+id/set_gf"
android:layout_width="25dp"
android:layout_height="25dp"
android:layout_alignParentEnd="true"
android:layout_marginVertical="8dp"
android:layout_marginEnd="8dp"
android:padding="3dp"
app:srcCompat="@drawable/ic_setting"
app:tint="@color/black" />
<com.google.android.material.button.MaterialButton
android:id="@+id/change_btn"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_below="@+id/home_address"
android:layout_marginHorizontal="15dp"
android:layout_marginBottom="5dp"
android:fontFamily="@font/nunito_regular"
android:text="@string/change"
android:textAllCaps="false"
android:textColor="@color/white"
/>
</RelativeLayout>
</com.google.android.material.card.MaterialCardView>
<LinearLayout
android:id="@+id/update_btns_view"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_alignParentBottom="true"
android:layout_margin="15dp"
android:orientation="horizontal"
android:visibility="gone"
android:weightSum="2">
<com.google.android.material.button.MaterialButton
android:id="@+id/change_btn"
android:layout_width="match_parent"
android:id="@+id/reset_btn"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_weight="1"
android:layout_below="@+id/home_address"
android:layout_marginHorizontal="15dp"
android:layout_marginBottom="5dp"
android:text="@string/change"
android:fontFamily="@font/nunito_regular"
android:textColor="@color/white"
android:text="@string/cancel"
android:textAllCaps="false"
android:textColor="@color/black"
app:backgroundTint="@color/white"
app:cornerRadius="5dp"
/>
</RelativeLayout>
<com.google.android.material.button.MaterialButton
android:id="@+id/update_btn"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_marginStart="15dp"
</com.google.android.material.card.MaterialCardView>
android:layout_weight="1"
<LinearLayout
android:id="@+id/update_btns_view"
android:visibility="gone"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="horizontal"
android:layout_margin="15dp"
android:layout_alignParentBottom="true"
android:weightSum="2">
android:fontFamily="@font/nunito_regular"
android:text="@string/update"
android:textAllCaps="false"
android:textColor="@color/white"
<com.google.android.material.button.MaterialButton
android:id="@+id/reset_btn"
android:layout_width="0dp"
app:backgroundTint="@color/color_primary"
app:cornerRadius="5dp"
/>
</LinearLayout>
<com.google.android.material.card.MaterialCardView
android:id="@+id/home_location_btn"
android:visibility="visible"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_weight="1"
android:text="@string/cancel"
android:fontFamily="@font/nunito_regular"
android:textColor="@color/black"
android:textAllCaps="false"
app:backgroundTint="@color/white"
app:cornerRadius="5dp"
/>
<com.google.android.material.button.MaterialButton
android:id="@+id/update_btn"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_weight="1"
android:layout_alignParentBottom="true"
android:layout_marginStart="15dp"
android:text="@string/update"
android:fontFamily="@font/nunito_regular"
android:textColor="@color/white"
android:textAllCaps="false"
android:layout_marginTop="15dp"
app:backgroundTint="@color/color_primary"
app:cornerRadius="5dp"
/>
</LinearLayout>
<com.google.android.material.card.MaterialCardView
android:id="@+id/home_location_btn"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:src="@drawable/img_pat_curr_location"
android:layout_alignParentBottom="true"
android:layout_margin="15dp"
app:backgroundTint="@color/white"
app:cardCornerRadius="30dp"
app:cardElevation="5dp"
>
<ImageView
android:layout_width="40dp"
android:layout_height="40dp"
android:src="@drawable/img_home_marker"
android:layout_margin="8dp"/>
</com.google.android.material.card.MaterialCardView>
<com.google.android.material.card.MaterialCardView
android:id="@+id/cg_location_Btn"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:src="@drawable/img_pat_curr_location"
android:layout_alignParentBottom="true"
android:layout_alignParentEnd="true"
android:layout_margin="15dp"
app:backgroundTint="@color/white"
app:cardCornerRadius="30dp"
app:cardElevation="5dp"
>
<ImageView
android:layout_width="40dp"
android:layout_height="40dp"
android:layout_marginEnd="15dp"
android:layout_marginBottom="15dp"
android:src="@drawable/img_pat_curr_location"
android:layout_margin="8dp"/>
app:backgroundTint="@color/white"
app:cardCornerRadius="30dp"
app:cardElevation="5dp">
<ImageView
android:layout_width="40dp"
android:layout_height="40dp"
android:layout_margin="8dp"
android:src="@drawable/img_home_marker" />
</com.google.android.material.card.MaterialCardView>
<com.google.android.material.card.MaterialCardView
android:id="@+id/cg_location_Btn"
android:visibility="visible"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_alignParentEnd="true"
android:layout_alignParentBottom="true"
android:layout_margin="15dp"
android:src="@drawable/img_pat_curr_location"
app:backgroundTint="@color/white"
app:cardCornerRadius="30dp"
app:cardElevation="5dp">
<de.hdodenhof.circleimageview.CircleImageView
android:id="@+id/pat_cur_loc_"
android:layout_width="40dp"
android:layout_height="40dp"
android:layout_margin="8dp"
android:src="@drawable/img_pat_curr_location" />
</com.google.android.material.card.MaterialCardView>
</RelativeLayout>
</LinearLayout>
<LinearLayout
android:id="@+id/location_bs"
android:visibility="gone"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:padding="15dp"
android:orientation="vertical"
app:behavior_hideable="false"
app:behavior_peekHeight="50dp"
android:background="@drawable/top_round_corner"
app:layout_behavior="com.google.android.material.bottomsheet.BottomSheetBehavior">
<View
android:id="@+id/bs_dash"
android:layout_width="25dp"
android:layout_height="3dp"
android:layout_gravity="center_horizontal"
android:background="@android:color/darker_gray"
/>
<com.google.android.material.card.MaterialCardView
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginTop="25dp"
app:strokeWidth="1dp"
app:strokeColor="@color/color_accent"
app:cardCornerRadius="5dp"
>
<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="horizontal"
android:layout_margin="10dp"
>
<de.hdodenhof.circleimageview.CircleImageView
android:id="@+id/bs_senior_image"
android:layout_width="60dp"
android:layout_height="60dp"
android:src="@drawable/static_3" />
<LinearLayout
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginHorizontal="15dp"
android:orientation="vertical">
<TextView
android:id="@+id/bs_senior_name"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="@string/couldn_t_load"
android:textAppearance="@style/TextAppearance.Material3.TitleMedium"
android:textColor="@color/black"
android:fontFamily="@font/nunito_bold"
android:layout_gravity="center_vertical"
android:singleLine="true"
android:ellipsize="end"
/>
<TextView
android:id="@+id/bs_senior_current_location_txt"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="@string/couldn_t_load"
android:textAppearance="@style/TextAppearance.Material3.TitleMedium"
android:textColor="@color/black"
android:fontFamily="@font/nunito_medium"
android:layout_gravity="center_vertical"
/>
<TextView
android:id="@+id/bs_distance_from_home"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
tools:text="0.25 miles away from home"
android:textAppearance="@style/TextAppearance.Material3.TitleMedium"
android:textColor="@color/black"
android:fontFamily="@font/nunito_medium"
android:layout_gravity="center_vertical"
/>
</LinearLayout>
</LinearLayout>
</com.google.android.material.card.MaterialCardView>
</RelativeLayout>
</LinearLayout>
</LinearLayout>
</androidx.coordinatorlayout.widget.CoordinatorLayout>

View File

@@ -161,6 +161,34 @@
app:showText="false"
/>
<androidx.appcompat.widget.SwitchCompat
android:id="@+id/call_block_check"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:layout_gravity="center_vertical"
android:text="@string/call_blocking"
android:fontFamily="@font/nunito_medium"
android:textColor="@color/black"
android:textSize="@dimen/_14ssp"
android:drawablePadding="15dp"
app:drawableStartCompat="@drawable/ic_block"
android:layout_marginHorizontal="15dp"
android:layout_marginTop="25dp"
android:paddingHorizontal="15dp"
android:paddingVertical="15dp"
android:elevation="3dp"
android:background="@drawable/edit_text_bg_2"
app:switchMinWidth="60dp"
app:track="@drawable/switch_track_1"
app:thumbTint="@color/color_primary"
app:showText="false"
/>
<TextView
android:id="@+id/logout"
android:layout_width="match_parent"

View File

@@ -0,0 +1,21 @@
<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
tools:context=".cg_subscription.SubscriptionWebViewActivity">
<WebView
android:id="@+id/web_view"
android:layout_width="match_parent"
android:layout_height="match_parent"
/>
<ProgressBar
android:id="@+id/progress_bar"
android:layout_centerInParent="true"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
/>
</RelativeLayout>

View File

@@ -12,16 +12,35 @@
android:layout_above="@id/next_btn"
android:orientation="vertical">
<ImageView
android:id="@+id/back_btn"
android:layout_width="35sp"
android:layout_height="35sp"
<RelativeLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_margin="15dp"
android:contentDescription="@string/back_button"
android:padding="5dp"
android:paddingStart="-15dp"
android:paddingEnd="0dp"
android:src="@drawable/arrow_back" />
>
<ImageView
android:id="@+id/back_btn"
android:layout_width="30dp"
android:layout_height="30dp"
android:contentDescription="@string/back_button"
android:padding="5dp"
android:paddingStart="-15dp"
android:paddingEnd="0dp"
android:layout_centerVertical="true"
android:src="@drawable/arrow_back" />
<ImageView
android:id="@+id/open_menu_btn"
android:visibility="gone"
android:layout_width="25dp"
android:layout_height="25dp"
android:paddingHorizontal="10dp"
android:src="@drawable/ic_three_dots"
android:layout_alignParentEnd="true"
android:layout_centerVertical="true"
/>
</RelativeLayout>
<TextView
android:id="@+id/title_txt"

View File

@@ -123,10 +123,12 @@
<ImageView
android:id="@+id/year_check"
android:visibility="gone"
android:layout_width="@dimen/_25sdp"
android:layout_height="@dimen/_25sdp"
android:src="@drawable/sub_check_drawable"
android:layout_marginStart="15dp"
/>
@@ -140,8 +142,6 @@
android:textColor="@color/black"
android:textSize="@dimen/_14ssp"
android:layout_marginStart="15dp"
/>
</LinearLayout>
@@ -288,15 +288,17 @@
android:id="@+id/ll"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:gravity="center_vertical"
android:layout_centerVertical="true"
android:orientation="horizontal">
<ImageView
android:id="@+id/month_check"
android:visibility="gone"
android:layout_width="@dimen/_25sdp"
android:layout_height="@dimen/_25sdp"
android:src="@drawable/sub_check_drawable"
android:layout_marginEnd="15dp"
/>
@@ -310,8 +312,6 @@
android:textColor="@color/black"
android:textSize="@dimen/_14ssp"
android:layout_marginStart="15dp"
/>
</LinearLayout>
@@ -442,7 +442,7 @@
android:textColor="@color/black"
android:textSize="@dimen/_14ssp"
tools:text="@string/subscribe_description"
tools:text="@string/proceed_to_the_payment_website_to_select_a_subscription_option_and_pay"
/>
@@ -464,7 +464,7 @@
android:fontFamily="@font/nunito_regular"
android:paddingVertical="12dp"
android:text="@string/subscribe"
android:text="@string/subscribe_plus_tax"
android:textAllCaps="false"
android:textColor="@color/white"
android:textSize="@dimen/_12ssp"

View File

@@ -9,7 +9,7 @@
<androidx.cardview.widget.CardView
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_height="?android:attr/actionBarSize"
app:cardElevation="5dp">
<LinearLayout
@@ -134,7 +134,8 @@
android:autofillHints="@null"
android:background="@drawable/edit_text_bg_2"
android:drawableStart="@drawable/ic_smiley_outline"
android:drawableStart="@drawable/keyboard"
android:drawableTint="@android:color/darker_gray"
android:drawablePadding="15dp"
android:fontFamily="@font/nunito_regular"

View File

@@ -0,0 +1,106 @@
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="wrap_content"
xmlns:tools="http://schemas.android.com/tools"
xmlns:app="http://schemas.android.com/apk/res-auto">
<com.google.android.material.card.MaterialCardView
android:id="@+id/card"
android:layout_width="match_parent"
android:layout_height="wrap_content"
app:cardCornerRadius="5dp"
app:strokeColor="@color/color_accent"
app:strokeWidth="1dp"
app:cardBackgroundColor="@color/white"
app:cardElevation="3dp"
android:layout_marginBottom="10dp"
android:layout_marginHorizontal="3dp"
>
<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="horizontal"
android:gravity="center_vertical"
android:layout_marginHorizontal="15dp"
android:layout_marginVertical="10dp">
<ImageView
android:id="@+id/add_img"
android:layout_width="40dp"
android:layout_height="40dp"
android:visibility="gone"
android:src="@drawable/ic_contact"
/>
<de.hdodenhof.circleimageview.CircleImageView
android:id="@+id/image"
android:layout_width="40dp"
android:layout_height="40dp"
app:civ_border_width="0.5dp"
app:civ_border_color="@color/color_primary"
/>
<TextView
android:id="@+id/name"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
tools:text="Aditya gaikwad"
android:fontFamily="@font/nunito_regular"
android:textColor="@color/black"
android:textSize="@dimen/_12ssp"
android:layout_marginStart="10dp"
android:singleLine="true"
android:ellipsize="end"
/>
<ImageView
android:id="@+id/cg_ic"
android:visibility="gone"
android:layout_width="15dp"
android:layout_height="15dp"
android:contentDescription="@string/make_sos"
app:srcCompat="@drawable/ic_add_red"
android:layout_marginStart="10dp"
/>
<ImageView
android:id="@+id/doc_ic"
android:visibility="gone"
android:layout_width="20dp"
android:layout_height="20dp"
android:contentDescription="@string/make_sos"
app:srcCompat="@drawable/ic_doctor"
android:layout_marginStart="10dp"
/>
<ImageView
android:id="@+id/sos"
android:visibility="gone"
android:layout_width="15dp"
android:layout_height="15dp"
android:contentDescription="@string/make_sos"
app:srcCompat="@drawable/ic_sos"
android:layout_marginStart="10dp"
/>
</LinearLayout>
</com.google.android.material.card.MaterialCardView>
</LinearLayout>

View File

@@ -126,10 +126,10 @@
<RelativeLayout
android:id="@+id/notifications"
android:layout_width="wrap_content"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:gravity="center"
android:layout_marginHorizontal="15dp"
android:layout_marginHorizontal="5dp"
>
<LinearLayout
@@ -159,8 +159,9 @@
<TextView
android:id="@+id/bottom_notification_count"
android:layout_width="@dimen/_15sdp"
android:layout_height="@dimen/_15sdp"
android:layout_width="@dimen/_11sdp"
android:layout_height="@dimen/_11sdp"
android:background="@drawable/round_corners"
android:backgroundTint="@android:color/holo_red_light"
@@ -168,7 +169,6 @@
android:visibility="gone"
android:layout_alignParentEnd="true"
tools:text="9"
android:fontFamily="@font/nunito_regular"
android:textColor="@color/white"
android:textSize="11sp"

View File

@@ -0,0 +1,92 @@
<?xml version="1.0" encoding="utf-8"?>
<androidx.constraintlayout.widget.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
android:visibility="gone"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:background="@color/white"
>
<ImageView
android:id="@+id/imageView3"
android:layout_width="match_parent"
android:layout_height="0dp"
android:scaleType="fitXY"
android:layout_marginTop="25dp"
app:layout_constraintHeight_percent="0.6"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent"
app:srcCompat="@drawable/img_new_update" />
<TextView
android:id="@+id/title"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:fontFamily="@font/nunito_bold"
android:text="@string/new_update_available"
android:textColor="@color/black"
android:textSize="@dimen/_18ssp"
android:layout_marginTop="35dp"
android:textAlignment="center"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toBottomOf="@+id/imageView3" />
<TextView
android:id="@+id/sub_title"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:text="@string/unlock_enhanced_features_and_improved_performance_with_our_latest_app_update"
android:textColor="@color/black"
android:fontFamily="@font/nunito_regular"
android:textSize="@dimen/_14ssp"
android:textAlignment="center"
android:layout_marginHorizontal="25dp"
android:layout_marginTop="10dp"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toBottomOf="@+id/title" />
<com.google.android.material.button.MaterialButton
android:id="@+id/update_btn"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginHorizontal="15dp"
android:layout_marginTop="35dp"
android:fontFamily="@font/nunito_bold"
android:paddingHorizontal="50dp"
android:paddingVertical="10dp"
android:text="@string/update_app"
android:textColor="@color/white"
android:textSize="@dimen/_14ssp"
app:cornerRadius="25dp"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toBottomOf="@id/sub_title" />
<TextView
android:id="@+id/skip_btn"
android:visibility="gone"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="@string/skip_underline"
android:textColor="@color/black"
android:textSize="@dimen/_14ssp"
android:fontFamily="@font/nunito_regular"
android:paddingVertical="5dp"
android:paddingHorizontal="10dp"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toBottomOf="@+id/update_btn"
app:layout_constraintVertical_bias="0.100" />
</androidx.constraintlayout.widget.ConstraintLayout>

View File

@@ -0,0 +1,27 @@
<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools"
android:background="@android:color/transparent"
android:layout_width="wrap_content"
android:layout_height="wrap_content">
<de.hdodenhof.circleimageview.CircleImageView
android:id="@+id/marker_bg_image"
android:layout_width="60dp"
android:layout_height="60dp"
android:translationZ="1dp"
android:src="@drawable/senior_img"
app:civ_circle_background_color="#D2042D"
app:civ_border_color="#D2042D"
app:civ_border_width="2dp"/>
<ImageView
android:layout_width="60dp"
android:layout_height="60dp"
android:layout_marginTop="30dp"
android:src="@drawable/ic_marker_bg"
app:tint="#D2042D" />
</RelativeLayout>

View File

@@ -0,0 +1,26 @@
<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
android:background="@android:color/transparent"
android:layout_width="wrap_content"
android:layout_height="wrap_content">
<de.hdodenhof.circleimageview.CircleImageView
android:id="@+id/marker_bg_image"
android:layout_width="40dp"
android:layout_height="40dp"
android:translationZ="1dp"
android:src="@drawable/senior_img"
app:civ_circle_background_color="#D2042D"
app:civ_border_color="#D2042D"
app:civ_border_width="2dp"/>
<ImageView
android:layout_width="40dp"
android:layout_height="35dp"
android:layout_marginTop="20dp"
android:src="@drawable/ic_marker_bg"
app:tint="#D2042D"
/>
</RelativeLayout>

View File

@@ -108,26 +108,25 @@
<com.google.android.material.textfield.TextInputEditText
android:id="@+id/pin"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_height="match_parent"
android:autofillHints="password"
android:background="@drawable/edit_text_bg"
android:hint="@string/enter_your_pin"
android:paddingVertical="15sp"
android:paddingHorizontal="10dp"
android:fontFamily="@font/nunito_regular"
android:textColor="@color/black"
android:textColorHint="#5B5B5B"
android:textAppearance="@style/TextAppearance.Material3.TitleMedium"
android:drawableStart="@drawable/ic_lock_outline"
android:drawablePadding="20dp"
android:autofillHints="password"
android:fontFamily="@font/nunito_regular"
android:hint="@string/enter_your_pin"
android:inputType="numberPassword"
android:maxLines="1"
android:maxLength="4"
/>
android:maxLines="1"
android:paddingHorizontal="10dp"
android:paddingVertical="15sp"
android:textAppearance="@style/TextAppearance.Material3.TitleMedium"
android:textColor="@color/black"
android:textColorHint="#5B5B5B" />
</com.google.android.material.textfield.TextInputLayout>

View File

@@ -53,4 +53,9 @@
/>
<include
android:id="@+id/new_update_view"
layout="@layout/layout_new_update"
/>
</RelativeLayout>

View File

@@ -0,0 +1,7 @@
<?xml version="1.0" encoding="utf-8"?>
<menu xmlns:android="http://schemas.android.com/apk/res/android">
<item android:id="@+id/update_to_50_contacts"
android:title="@string/update_to_50_contacts"
/>
</menu>

View File

@@ -261,6 +261,7 @@
<string name="accept_invitation">Accept invitation</string>
<string name="accept_your_loved_one_s_invitation_to_connect">Accept your loved one\'s invitation to connect</string>
<string name="subscribe">Subscribe</string>
<string name="subscribe_plus_tax">Subscribe (+6.625% tax)</string>
<string name="complete_application_subscription">Complete application subscription</string>
<string name="you_are_ready">You are ready!</string>
<string name="your_phone_is_linked_to_your_loved_one">Your phone is linked to your loved one.</string>
@@ -417,7 +418,7 @@
<string name="your_location">Your location</string>
<string name="home_address_txt">Home Address</string>
<string name="go">go</string>
<string name="call_and_message_your_loved_ones">Call and message your loved ones</string>
<string name="call_and_message_your_loved_ones">Call or message your loved ones</string>
<string name="select_number_to_cal_or_message">Select number to call or message</string>
<string name="call">Call</string>
<string name="no_frequently_used_apps">No frequently used apps added\nPlease select an app from below list to unlock.</string>
@@ -486,5 +487,14 @@
<string name="enter_new_address_here">Enter new address here</string>
<string name="cancel">Cancel</string>
<string name="couldn_t_load_chats">Couldn\'t load chats</string>
<string name="couldn_t_load">Couldn\'t load</string>
<string name="new_update_available">New update available</string>
<string name="unlock_enhanced_features_and_improved_performance_with_our_latest_app_update">Unlock enhanced features and improved performance with our latest app update</string>
<string name="update_app">Update app</string>
<string name="skip_underline"><u>skip</u></string>
<string name="update_to_50_contacts">Update to 50 contacts</string>
<string name="proceed_to_the_payment_website_to_select_a_subscription_option_and_pay">Proceed to the payment website to select a subscription option and pay</string>
<string name="proceed_to_website">Proceed to website</string>
<string name="call_blocking">Call blocking</string>
</resources>

View File

@@ -22,13 +22,12 @@ android.nonTransitiveRClass=true
android.enableJetifier=true
# production
#SIMPLITEND_BASE_URL="https://app.simplitend.com/"
#SIMPLITEND_SOKCET_HOST="https://app.simplitend.com:3002/"
SIMPLITEND_BASE_URL="https://app.simplitend.com/"
SIMPLITEND_SOKCET_HOST="https://app.simplitend.com/"
# staging
SIMPLITEND_BASE_URL="https://staging.simplitend.com/"
SIMPLITEND_SOKCET_HOST="https://staging.simplitend.com:3002/"
#SIMPLITEND_BASE_URL="https://staging.simplitend.com/"
#SIMPLITEND_SOKCET_HOST="https://staging.simplitend.com/"
# development
#SIMPLITEND_BASE_URL="https://simplitend.betadelivery.com/"

BIN
keystorepassword.jpg Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 496 KiB