.
This commit is contained in:
12
.idea/deploymentTargetDropDown.xml
generated
12
.idea/deploymentTargetDropDown.xml
generated
@@ -1,18 +1,6 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<project version="4">
|
||||
<component name="deploymentTargetDropDown">
|
||||
<runningDeviceTargetSelectedWithDropDown>
|
||||
<Target>
|
||||
<type value="RUNNING_DEVICE_TARGET" />
|
||||
<deviceKey>
|
||||
<Key>
|
||||
<type value="SERIAL_NUMBER" />
|
||||
<value value="RZCW41EJRPN" />
|
||||
</Key>
|
||||
</deviceKey>
|
||||
</Target>
|
||||
</runningDeviceTargetSelectedWithDropDown>
|
||||
<timeTargetWasSelectedWithDropDown value="2023-10-04T15:19:03.332740900Z" />
|
||||
<runningDeviceTargetsSelectedWithDialog>
|
||||
<Target>
|
||||
<type value="RUNNING_DEVICE_TARGET" />
|
||||
|
||||
8
.idea/inspectionProfiles/Project_Default.xml
generated
Normal file
8
.idea/inspectionProfiles/Project_Default.xml
generated
Normal file
@@ -0,0 +1,8 @@
|
||||
<component name="InspectionProjectProfileManager">
|
||||
<profile version="1.0">
|
||||
<option name="myName" value="Project Default" />
|
||||
<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>
|
||||
</profile>
|
||||
</component>
|
||||
@@ -11,7 +11,9 @@ import android.provider.Settings;
|
||||
import android.text.TextUtils;
|
||||
import android.util.Log;
|
||||
import android.view.View;
|
||||
import android.view.ViewGroup;
|
||||
import android.widget.LinearLayout;
|
||||
import android.widget.TextView;
|
||||
import android.widget.Toast;
|
||||
|
||||
import androidx.appcompat.app.AppCompatActivity;
|
||||
@@ -36,20 +38,28 @@ public class FUAActivity extends AppCompatActivity {
|
||||
MySharedPref mySharedPref;
|
||||
List<AppList> whiteList;
|
||||
|
||||
TextView all_apps_title;
|
||||
|
||||
LinearLayout no_fua;
|
||||
|
||||
List<AppList> installed_app_list;
|
||||
|
||||
public static final String IS_FROM_DASHBOARD = "is_from_dashboard";
|
||||
protected boolean isFromDashboard;
|
||||
|
||||
@Override
|
||||
protected void onCreate(Bundle savedInstanceState) {
|
||||
super.onCreate(savedInstanceState);
|
||||
setContentView(R.layout.activity_fua);
|
||||
|
||||
isFromDashboard = getIntent().getBooleanExtra(IS_FROM_DASHBOARD, false);
|
||||
|
||||
// swBlock = (SwitchCompat) findViewById(R.id.swBlock);
|
||||
rvApps = (RecyclerView) findViewById(R.id.rvApps);
|
||||
rvWhiteApps = (RecyclerView) findViewById(R.id.rv_white_apps);
|
||||
mySharedPref = new MySharedPref(FUAActivity.this);
|
||||
no_fua = findViewById(R.id.no_fua);
|
||||
all_apps_title = findViewById(R.id.all_app_tile);
|
||||
|
||||
if (!isAccessibilityAppBlockingEnabled()) {
|
||||
openAccessibilityDialog();
|
||||
@@ -69,25 +79,6 @@ public class FUAActivity extends AppCompatActivity {
|
||||
rvWhiteApps.setVisibility(View.GONE);
|
||||
}
|
||||
|
||||
adapter = new MyAppsAdapter(FUAActivity.this, getInstalledApps(), false, appList -> {
|
||||
if (!isContainsWhiteList(appList)) {
|
||||
whiteList.add(appList);
|
||||
Collections.sort(whiteList, (o1, o2) -> o1.getName().compareToIgnoreCase(o2.getName()));
|
||||
} else {
|
||||
whiteList.remove(getPosition(appList));
|
||||
}
|
||||
|
||||
if (whiteList.size() > 0) {
|
||||
no_fua.setVisibility(View.GONE);
|
||||
rvWhiteApps.setVisibility(View.VISIBLE);
|
||||
} else {
|
||||
no_fua.setVisibility(View.VISIBLE);
|
||||
rvWhiteApps.setVisibility(View.GONE);
|
||||
}
|
||||
|
||||
whiteListAdapter.notifyDataSetChanged();
|
||||
});
|
||||
|
||||
whiteListAdapter = new MyAppsAdapter(FUAActivity.this, whiteList, true, new MyAppsAdapter.ItemClicked() {
|
||||
@Override
|
||||
public void onCLick(AppList appList) {
|
||||
@@ -100,41 +91,50 @@ public class FUAActivity extends AppCompatActivity {
|
||||
}
|
||||
});
|
||||
|
||||
rvApps.setLayoutManager(new GridLayoutManager(this, 4));
|
||||
rvApps.setAdapter(adapter);
|
||||
|
||||
rvWhiteApps.setLayoutManager(new GridLayoutManager(this, 4));
|
||||
rvWhiteApps.setAdapter(whiteListAdapter);
|
||||
|
||||
// swBlock.setOnCheckedChangeListener((buttonView, isChecked) -> {
|
||||
//
|
||||
// if (!isAccessibilityAppBlockingEnabled() && isChecked) {
|
||||
// Intent accessibilityIntent = new Intent(Settings.ACTION_ACCESSIBILITY_SETTINGS);
|
||||
// startActivity(accessibilityIntent);
|
||||
// }
|
||||
//
|
||||
// // Intent serviceIntent = new Intent(getApplicationContext(), service.class);
|
||||
//// ContextCompat.startForegroundService(getApplicationContext(), serviceIntent);
|
||||
//
|
||||
// // if (isChecked) {
|
||||
//
|
||||
// // startService(new Intent(MainActivity.this, ServiceTest.class));
|
||||
//
|
||||
//// Intent serviceIntent = new Intent(MainActivity.this, OverlayService.class);
|
||||
//// if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
|
||||
//// getApplicationContext().startForegroundService(serviceIntent);
|
||||
//// } else {
|
||||
//// getApplicationContext().startService(serviceIntent);
|
||||
//// }
|
||||
//
|
||||
// /* Intent serviceIntent = new Intent(MainActivity.this, OverlayService.class);
|
||||
// startService(serviceIntent);*/
|
||||
//
|
||||
// /* } else {
|
||||
// stopService(new Intent(MainActivity.this, OverlayService.class));
|
||||
// }*/
|
||||
if (!isFromDashboard) {
|
||||
// from settings page
|
||||
rvApps.setVisibility(View.VISIBLE);
|
||||
all_apps_title.setVisibility(View.VISIBLE);
|
||||
findViewById(R.id.done_btn).setVisibility(View.VISIBLE);
|
||||
|
||||
// });
|
||||
adapter = new MyAppsAdapter(FUAActivity.this, getInstalledApps(), false, appList -> {
|
||||
if (!isContainsWhiteList(appList)) {
|
||||
whiteList.add(appList);
|
||||
Collections.sort(whiteList, (o1, o2) -> o1.getName().compareToIgnoreCase(o2.getName()));
|
||||
} else {
|
||||
whiteList.remove(getPosition(appList));
|
||||
}
|
||||
|
||||
if (whiteList.size() > 0) {
|
||||
no_fua.setVisibility(View.GONE);
|
||||
rvWhiteApps.setVisibility(View.VISIBLE);
|
||||
} else {
|
||||
no_fua.setVisibility(View.VISIBLE);
|
||||
rvWhiteApps.setVisibility(View.GONE);
|
||||
}
|
||||
|
||||
whiteListAdapter.notifyDataSetChanged();
|
||||
});
|
||||
|
||||
rvApps.setLayoutManager(new GridLayoutManager(this, 4));
|
||||
rvApps.setAdapter(adapter);
|
||||
} else {
|
||||
// from dashboard
|
||||
rvApps.setVisibility(View.GONE);
|
||||
all_apps_title.setVisibility(View.GONE);
|
||||
findViewById(R.id.done_btn).setVisibility(View.GONE);
|
||||
|
||||
LinearLayout.LayoutParams p1 = (LinearLayout.LayoutParams) no_fua.getLayoutParams();
|
||||
p1.weight = 10;
|
||||
no_fua.setLayoutParams(p1);
|
||||
|
||||
LinearLayout.LayoutParams p2 = (LinearLayout.LayoutParams) rvWhiteApps.getLayoutParams();
|
||||
p2.weight = 10;
|
||||
rvWhiteApps.setLayoutParams(p2);
|
||||
}
|
||||
|
||||
findViewById(R.id.done_btn).setOnClickListener(v -> {
|
||||
onBackPressed();
|
||||
|
||||
@@ -272,9 +272,11 @@ public abstract class AppUtil {
|
||||
switch (content_type) {
|
||||
case Constants.PATIENT_OUT_OF_GEOFENCE:
|
||||
|
||||
title = patient_name + " is out of Geofence!";
|
||||
|
||||
setupBottomSheet(binding,
|
||||
R.drawable.img_medication_time,
|
||||
title, "Current location of patient",
|
||||
title, "Current location",
|
||||
"Unknown", "Call patient",
|
||||
v -> {
|
||||
CaregiverDataCache.getCaregiverData(context, (careGiverData -> {
|
||||
|
||||
@@ -5,6 +5,7 @@ public abstract class Constants {
|
||||
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";
|
||||
public static final String GEOFENCING_RADIUS_ADDED = "geofencing_radius_add";
|
||||
public static final String HOME_LOCATION_UPDATED = "home_location_updated";
|
||||
public static final String PATIENT_OUT_OF_GEOFENCE = "patient_outof_geofence";
|
||||
public static final String PATIENT_REQUESTED_DIRECTION = "patient_requested_help";
|
||||
|
||||
@@ -57,7 +57,10 @@ public class NotificationService implements INotificationServiceExtension {
|
||||
|
||||
iNotificationReceivedEvent.getContext().sendBroadcast(intent);
|
||||
|
||||
if (Constants.GEOFENCING_RADIUS_UPDATED.equals(content_type) || Constants.HOME_LOCATION_UPDATED.equals(content_type)) {
|
||||
if (Constants.GEOFENCING_RADIUS_ADDED.equals(content_type)
|
||||
|| Constants.GEOFENCING_RADIUS_UPDATED.equals(content_type)
|
||||
|| Constants.HOME_LOCATION_UPDATED.equals(content_type)) {
|
||||
|
||||
if (AppUtil.isPatientLoggedIn(iNotificationReceivedEvent.getContext())){
|
||||
// Either Geofence radius or Patient's location has changed.
|
||||
Log.d(GEOFENCE_TAG, "Adding geo fence...");
|
||||
|
||||
@@ -47,7 +47,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 (white_contacts != null && !white_contacts.contains(phoneNumber)){
|
||||
endCall(builder);
|
||||
Log.d(CONTACT_WHITE_LISTING_TAG, "CALL ENDED");
|
||||
}
|
||||
|
||||
@@ -20,6 +20,7 @@ public class AccountPresenter {
|
||||
public static final String ACC_ACTIVE_STR = "1";
|
||||
public static final int ACC_DEACTIVATE_BY_USER = 2;
|
||||
public static final int ACC_DEACTIVATE_BY_ADMIN = 3;
|
||||
public static final String DEFAULT_ACTIVE_STATUS = "0";
|
||||
|
||||
private static AccountPresenter accountPresenter;
|
||||
|
||||
|
||||
@@ -1,6 +1,10 @@
|
||||
package com.app.simplitend.caregiverdashboard.fragments;
|
||||
|
||||
import static com.app.simplitend.caregiverdashboard.activities.PatientProfileShowerActivity.*;
|
||||
import static com.app.simplitend.caregiverdashboard.activities.PatientProfileShowerActivity.ACTIVITY_F;
|
||||
import static com.app.simplitend.caregiverdashboard.activities.PatientProfileShowerActivity.CONTACTS_F;
|
||||
import static com.app.simplitend.caregiverdashboard.activities.PatientProfileShowerActivity.MED_INFO_F;
|
||||
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 android.app.ProgressDialog;
|
||||
@@ -17,7 +21,6 @@ import androidx.annotation.Nullable;
|
||||
import androidx.fragment.app.Fragment;
|
||||
import androidx.lifecycle.ViewModelProvider;
|
||||
|
||||
import com.bumptech.glide.Glide;
|
||||
import com.app.simplitend.R;
|
||||
import com.app.simplitend.apputils.AppUtil;
|
||||
import com.app.simplitend.apputils.CaregiverDataCache;
|
||||
@@ -27,8 +30,10 @@ import com.app.simplitend.caregiverdashboard.mvvm.CaregiverMainViewModel;
|
||||
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.databinding.MyPatientFragmentBinding;
|
||||
import com.app.simplitend.welcome.welcomecg.mvvm.CareGiverData;
|
||||
import com.bumptech.glide.Glide;
|
||||
|
||||
public class MyPatientFragment extends Fragment implements CgHomeContracts.GetGeoFenceCallback {
|
||||
|
||||
@@ -150,6 +155,11 @@ public class MyPatientFragment extends Fragment implements CgHomeContracts.GetGe
|
||||
}
|
||||
});
|
||||
|
||||
binding.subPlans.setOnClickListener(v -> {
|
||||
Intent intent = new Intent(requireActivity(), CgSubscriptionActivity.class);
|
||||
startActivity(intent);
|
||||
});
|
||||
|
||||
}
|
||||
|
||||
private void gotoProfileShower(String which_f) {
|
||||
|
||||
@@ -21,6 +21,7 @@ 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.cg_subscription.mvp.CurrentPlan;
|
||||
import com.app.simplitend.cg_subscription.mvp.SubscriptionContracts;
|
||||
import com.app.simplitend.cg_subscription.mvp.SubscriptionCredentials;
|
||||
import com.app.simplitend.cg_subscription.mvp.SubscriptionPresenter;
|
||||
@@ -42,7 +43,7 @@ import okhttp3.RequestBody;
|
||||
public class CgSubscriptionActivity extends AppCompatActivity
|
||||
implements SubscriptionContracts.GetSubPlansCallback,
|
||||
SubscriptionContracts.PaySubscriptionCallback,
|
||||
SubscriptionContracts.CreateSubscriptionCallback {
|
||||
SubscriptionContracts.CreateSubscriptionCallback, SubscriptionContracts.GetCurrentPlanCallback {
|
||||
|
||||
private static final String TAG = "CgSubscriptionActivity";
|
||||
|
||||
@@ -68,43 +69,89 @@ public class CgSubscriptionActivity extends AppCompatActivity
|
||||
|
||||
presenter = SubscriptionPresenter.getPresenter();
|
||||
|
||||
CaregiverDataCache.getCaregiverData(this, (careGiverData -> {
|
||||
this.careGiverData = careGiverData;
|
||||
}), true);
|
||||
|
||||
initViews();
|
||||
|
||||
clickEvents();
|
||||
|
||||
CaregiverDataCache.getCaregiverData(this, (careGiverData -> {
|
||||
this.careGiverData = careGiverData;
|
||||
|
||||
if (careGiverData != null){
|
||||
if (careGiverData.isCaregiverTakeSubscription != 1){
|
||||
// not subscribed thus, load plans
|
||||
loadPlans();
|
||||
paymentSheet = new PaymentSheet(this, this::onPaymentSheetResult);
|
||||
}else{
|
||||
// Already subscribed thus, loading current plans
|
||||
loadCurrentPlans();
|
||||
}
|
||||
}else{
|
||||
binding.plansView.setVisibility(View.GONE);
|
||||
}
|
||||
|
||||
}), true);
|
||||
|
||||
// selecting default yearly pack
|
||||
binding.yearCheck.setSelected(true);
|
||||
}
|
||||
|
||||
private void loadCurrentPlans() {
|
||||
CaregiverDataCache.getCaregiverData(this, (careGiverData1 -> {
|
||||
this.careGiverData = careGiverData1;
|
||||
|
||||
if (careGiverData1 == null){
|
||||
binding.plansView.setVisibility(View.GONE);
|
||||
return;
|
||||
}
|
||||
|
||||
progressDialog.setTitle("Please wait....");
|
||||
progressDialog.setMessage("while we fetch your subscription details");
|
||||
progressDialog.setCancelable(false);
|
||||
progressDialog.show();
|
||||
|
||||
String token = "Bearer " + AppUtil.getCgToken(this);
|
||||
presenter.getCurrentSubscriptionPlan(careGiverData.caregiver_xid,
|
||||
token, this);
|
||||
}), true);
|
||||
}
|
||||
|
||||
private void clickEvents() {
|
||||
binding.makePayment.setOnClickListener(view -> {
|
||||
payForSubscription();
|
||||
});
|
||||
|
||||
binding.yearCard.setOnClickListener(v -> {
|
||||
if (!binding.yearCheck.isSelected()){
|
||||
// not selected
|
||||
binding.monthCheck.setSelected(false);
|
||||
binding.yearCheck.setSelected(true);
|
||||
}
|
||||
});
|
||||
|
||||
binding.monthCard.setOnClickListener(v -> {
|
||||
if (!binding.monthCheck.isActivated()){
|
||||
binding.yearCheck.setSelected(false);
|
||||
binding.monthCheck.setSelected(true);
|
||||
}
|
||||
CaregiverDataCache.getCaregiverData(this, (careGiverData1 -> {
|
||||
this.careGiverData = careGiverData1;
|
||||
if (careGiverData1 != null){
|
||||
if (careGiverData.isCaregiverTakeSubscription == 1){
|
||||
// no sub
|
||||
Toast.makeText(this, "Cancel subscription", Toast.LENGTH_SHORT).show();
|
||||
}else{
|
||||
payForSubscription();
|
||||
}
|
||||
}else{
|
||||
Toast.makeText(this, "Couldn't load data", Toast.LENGTH_SHORT).show();
|
||||
}
|
||||
}), true);
|
||||
});
|
||||
|
||||
binding.contactAdmin.setOnClickListener(view -> {
|
||||
contactMail();
|
||||
});
|
||||
|
||||
binding.retry.setOnClickListener(v -> loadPlans());
|
||||
binding.retry.setOnClickListener(v -> {
|
||||
CaregiverDataCache.getCaregiverData(this, (careGiverData1 -> {
|
||||
this.careGiverData = careGiverData1;
|
||||
|
||||
if (careGiverData != null){
|
||||
if (careGiverData.isCaregiverTakeSubscription != 1){
|
||||
// no sub
|
||||
loadPlans();
|
||||
}else{
|
||||
loadCurrentPlans();
|
||||
}
|
||||
}else{
|
||||
Toast.makeText(this, "Couldn't load data", Toast.LENGTH_SHORT).show();
|
||||
}
|
||||
}), true);
|
||||
});
|
||||
|
||||
}
|
||||
|
||||
@@ -177,10 +224,6 @@ public class CgSubscriptionActivity extends AppCompatActivity
|
||||
// loading subscription plans
|
||||
progressDialog = new ProgressDialog(this);
|
||||
|
||||
loadPlans();
|
||||
|
||||
paymentSheet = new PaymentSheet(this, this::onPaymentSheetResult);
|
||||
|
||||
try {
|
||||
String description = getString(R.string.subscribe_description);
|
||||
String contact_email = getString(R.string.contact_email);
|
||||
@@ -208,6 +251,11 @@ public class CgSubscriptionActivity extends AppCompatActivity
|
||||
CaregiverDataCache.getCaregiverData(this, (careGiverData1 -> {
|
||||
this.careGiverData = careGiverData1;
|
||||
|
||||
if (careGiverData1 == null){
|
||||
binding.plansView.setVisibility(View.GONE);
|
||||
return;
|
||||
}
|
||||
|
||||
progressDialog.setTitle("Please wait....");
|
||||
progressDialog.setMessage("while we fetch subscription plans for you.");
|
||||
progressDialog.setCancelable(false);
|
||||
@@ -274,7 +322,76 @@ public class CgSubscriptionActivity extends AppCompatActivity
|
||||
|
||||
}
|
||||
|
||||
private void inflateCurrentPlan(CurrentPlan currentPlan){
|
||||
binding.makePayment.setVisibility(View.VISIBLE);
|
||||
binding.makePayment.setText(R.string.cancel_subscription);
|
||||
|
||||
binding.yourPlan.setVisibility(View.VISIBLE);
|
||||
|
||||
SubscriptionPlan plan = currentPlan.plan;
|
||||
|
||||
if (getString(R.string.monthly).equals(plan.plan_name)){
|
||||
// monthly
|
||||
binding.monthlyName.setText(plan.plan_name);
|
||||
|
||||
binding.monthCheck.setSelected(true);
|
||||
|
||||
String price = "$" + plan.plan_value;
|
||||
binding.monthlyPrice.setText(price);
|
||||
|
||||
binding.monthCard.setVisibility(View.VISIBLE);
|
||||
binding.yearCard.setVisibility(View.GONE);
|
||||
|
||||
}else if (getString(R.string.year).equals(plan.plan_name)){
|
||||
// yearly
|
||||
binding.yearlyName.setText(plan.plan_name);
|
||||
|
||||
binding.yearCheck.setSelected(true);
|
||||
|
||||
String price = "$" + plan.plan_value;
|
||||
binding.yearDiscountedPrice.setText(price);
|
||||
|
||||
binding.yearActualPrice.setVisibility(View.GONE);
|
||||
binding.yearDiscount.setVisibility(View.GONE);
|
||||
|
||||
try {
|
||||
BigDecimal year_price_d = new BigDecimal(plan.plan_value);
|
||||
String yearly_month_price = year_price_d.divide(new BigDecimal(12), RoundingMode.DOWN).toString();
|
||||
yearly_month_price = "$" + yearly_month_price;
|
||||
binding.yearlyMonthPrice.setText(yearly_month_price);
|
||||
}catch (Exception e){
|
||||
binding.yearlyMonthPrice.setVisibility(View.GONE);
|
||||
}
|
||||
|
||||
binding.monthCard.setVisibility(View.GONE);
|
||||
binding.yearCard.setVisibility(View.VISIBLE);
|
||||
}
|
||||
}
|
||||
|
||||
private void inflatePlans() {
|
||||
|
||||
binding.makePayment.setVisibility(View.VISIBLE);
|
||||
binding.makePayment.setText(getString(R.string.subscribe));
|
||||
|
||||
binding.yourPlan.setVisibility(View.GONE);
|
||||
|
||||
binding.yearCard.setVisibility(View.VISIBLE);
|
||||
binding.yearCard.setOnClickListener(v -> {
|
||||
if (!binding.yearCheck.isSelected()){
|
||||
// not selected
|
||||
binding.monthCheck.setSelected(false);
|
||||
binding.yearCheck.setSelected(true);
|
||||
}
|
||||
});
|
||||
|
||||
binding.monthCard.setVisibility(View.VISIBLE);
|
||||
binding.monthCard.setOnClickListener(v -> {
|
||||
if (!binding.monthCheck.isActivated()){
|
||||
binding.yearCheck.setSelected(false);
|
||||
binding.monthCheck.setSelected(true);
|
||||
}
|
||||
});
|
||||
|
||||
try {
|
||||
String monthly_price = null;
|
||||
String yearly_price = null;
|
||||
@@ -397,10 +514,22 @@ public class CgSubscriptionActivity extends AppCompatActivity
|
||||
progressDialog.dismiss();
|
||||
AppUtil.showAlert(this,
|
||||
getString(R.string.something_went_wrong),
|
||||
message + "\nNegative response will be handled properly.",
|
||||
message ,
|
||||
"OK",
|
||||
((dialogInterface, i) -> {
|
||||
|
||||
}), null, null);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void currentPlan(@NonNull CurrentPlan currentPlan) {
|
||||
progressDialog.dismiss();
|
||||
inflateCurrentPlan(currentPlan);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void failedCurrentPlan(Throwable t, String message) {
|
||||
progressDialog.dismiss();
|
||||
binding.plansView.setVisibility(View.GONE);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -0,0 +1,18 @@
|
||||
package com.app.simplitend.cg_subscription.mvp;
|
||||
|
||||
import com.app.simplitend.cg_subscription.SubscriptionPlan;
|
||||
|
||||
public class CurrentPlan{
|
||||
public String subscription_id;
|
||||
public SubscriptionPlan plan;
|
||||
public String current_period_start;
|
||||
public String current_period_end;
|
||||
public String customer_name;
|
||||
public String customer_email;
|
||||
public double amount;
|
||||
public String metadata;
|
||||
public String subscription_status;
|
||||
public String pay_status;
|
||||
public String ended_at;
|
||||
public String is_subscription_completed;
|
||||
}
|
||||
@@ -13,6 +13,8 @@ import retrofit2.http.Header;
|
||||
import retrofit2.http.Multipart;
|
||||
import retrofit2.http.POST;
|
||||
import retrofit2.http.PartMap;
|
||||
import retrofit2.http.Path;
|
||||
import retrofit2.http.Query;
|
||||
|
||||
public interface SubscriptionApiService {
|
||||
|
||||
@@ -32,4 +34,8 @@ public interface SubscriptionApiService {
|
||||
@PartMap Map<String, RequestBody> bodyMap
|
||||
);
|
||||
|
||||
@GET("api/get-subscription-details")
|
||||
Call<CallResponse<CurrentPlan>> getCurrentPlan(@Query("caregiver_id") long c_id,
|
||||
@Header("Authorization") String token);
|
||||
|
||||
}
|
||||
|
||||
@@ -1,5 +1,7 @@
|
||||
package com.app.simplitend.cg_subscription.mvp;
|
||||
|
||||
import androidx.annotation.NonNull;
|
||||
|
||||
import com.app.simplitend.cg_subscription.SubscriptionPlan;
|
||||
|
||||
import java.util.ArrayList;
|
||||
@@ -28,4 +30,8 @@ public interface SubscriptionContracts {
|
||||
void onSubscriptionCreateFailed(Throwable throwable, String message);
|
||||
}
|
||||
|
||||
interface GetCurrentPlanCallback{
|
||||
void currentPlan(@NonNull CurrentPlan currentPlan);
|
||||
void failedCurrentPlan(Throwable t, String message);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -110,4 +110,30 @@ public class SubscriptionPresenter {
|
||||
});
|
||||
}
|
||||
|
||||
public void getCurrentSubscriptionPlan(long c_id,
|
||||
@NonNull String token,
|
||||
@NonNull SubscriptionContracts.GetCurrentPlanCallback callback){
|
||||
apiService.getCurrentPlan(c_id, token)
|
||||
.enqueue(new Callback<CallResponse<CurrentPlan>>() {
|
||||
@Override
|
||||
public void onResponse(Call<CallResponse<CurrentPlan>> call, Response<CallResponse<CurrentPlan>> response) {
|
||||
if (response.body() != null){
|
||||
if (response.body().status != 200 || response.body().error_code == 1 || response.body().result == null){
|
||||
callback.failedCurrentPlan(new Exception(), response.body().message);
|
||||
return;
|
||||
}
|
||||
|
||||
callback.currentPlan(response.body().result);
|
||||
}else{
|
||||
callback.failedCurrentPlan(new Exception(), "Please try again later.");
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onFailure(Call<CallResponse<CurrentPlan>> call, Throwable t) {
|
||||
callback.failedCurrentPlan(new Exception(), "Please try again later.");
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -81,7 +81,7 @@ public class PatSettingsActivity extends AppCompatActivity implements CgHomeCont
|
||||
progressDialog.setCancelable(false);
|
||||
progressDialog.show();
|
||||
|
||||
accountPresenter.signOut("Bearer " + AppUtil.getCgToken(this),
|
||||
accountPresenter.signOut("Bearer " + AppUtil.getPatientToken(this),
|
||||
this);
|
||||
}));
|
||||
});
|
||||
|
||||
@@ -131,7 +131,7 @@ public class PatientMainViewModel extends ViewModel {
|
||||
|
||||
geofencingClient.addGeofences(geofencingRequest, pendingIntent)
|
||||
.addOnSuccessListener(aVoid -> {
|
||||
Log.d(GEOFENCE_TAG, "Geofence added successfully.");
|
||||
Log.d(GEOFENCE_TAG, "Geofence added successfully. " + latLng + " Radius: " + GEOFENCING_RADIUS + " meters");
|
||||
AppUtil.updatePatientGeofence(activity, latLng.latitude+"", latLng.longitude+"",
|
||||
GEOFENCING_RADIUS+"", unit);
|
||||
})
|
||||
|
||||
@@ -1,5 +1,6 @@
|
||||
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.caregiverdashboard.activities.EditProfileInfoActivity.IS_CAREGIVER;
|
||||
import static com.app.simplitend.patient_dashboard.DirectionToHomeActivity.LAT_KEY;
|
||||
@@ -14,6 +15,7 @@ import android.content.BroadcastReceiver;
|
||||
import android.content.Context;
|
||||
import android.content.Intent;
|
||||
import android.content.IntentFilter;
|
||||
import android.content.res.Resources;
|
||||
import android.os.Bundle;
|
||||
import android.telecom.TelecomManager;
|
||||
import android.view.LayoutInflater;
|
||||
@@ -243,6 +245,7 @@ public class PatientDashboardFragment extends Fragment implements ProfileContrac
|
||||
|
||||
binding.apps.setOnClickListener(v -> {
|
||||
Intent intent = new Intent(requireActivity(), FUAActivity.class);
|
||||
intent.putExtra(IS_FROM_DASHBOARD, true);
|
||||
startActivity(intent);
|
||||
});
|
||||
|
||||
@@ -327,11 +330,13 @@ public class PatientDashboardFragment extends Fragment implements ProfileContrac
|
||||
private void removeReminder() {
|
||||
binding.homeReminder.setVisibility(View.GONE);
|
||||
|
||||
ViewGroup.LayoutParams layoutParams = binding.bgImg.getLayoutParams();
|
||||
|
||||
layoutParams.height = (int) getResources().getDimension(com.intuit.sdp.R.dimen._140sdp);
|
||||
|
||||
binding.bgImg.setLayoutParams(layoutParams);
|
||||
try {
|
||||
ViewGroup.LayoutParams layoutParams = binding.bgImg.getLayoutParams();
|
||||
layoutParams.height = (int) getResources().getDimension(com.intuit.sdp.R.dimen._140sdp);
|
||||
binding.bgImg.setLayoutParams(layoutParams);
|
||||
} catch (Exception e) {
|
||||
// do nothing
|
||||
}
|
||||
|
||||
viewModel.message_title = null;
|
||||
}
|
||||
|
||||
@@ -1,7 +1,12 @@
|
||||
package com.app.simplitend.patientprofile;
|
||||
|
||||
import static com.app.simplitend.apputils.NotificationService.CONTENT_TYPE_KEY;
|
||||
|
||||
import android.app.ProgressDialog;
|
||||
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.view.LayoutInflater;
|
||||
@@ -14,6 +19,7 @@ import androidx.annotation.Nullable;
|
||||
import androidx.fragment.app.Fragment;
|
||||
import androidx.vectordrawable.graphics.drawable.Animatable2Compat;
|
||||
|
||||
import com.app.simplitend.apputils.Constants;
|
||||
import com.bumptech.glide.Glide;
|
||||
import com.bumptech.glide.load.DataSource;
|
||||
import com.bumptech.glide.load.engine.GlideException;
|
||||
@@ -45,6 +51,8 @@ public class RegisterCompleteFragment extends Fragment implements ProfileContrac
|
||||
|
||||
private ProgressDialog progressDialog;
|
||||
|
||||
private BroadcastReceiver notification_receiver;
|
||||
|
||||
public RegisterCompleteFragment() {
|
||||
// required
|
||||
}
|
||||
@@ -96,9 +104,29 @@ public class RegisterCompleteFragment extends Fragment implements ProfileContrac
|
||||
checkConnectionStatus();
|
||||
});
|
||||
|
||||
notification_receiver = new BroadcastReceiver() {
|
||||
@Override
|
||||
public void onReceive(Context context, Intent intent) {
|
||||
String content_type = intent.getStringExtra(CONTENT_TYPE_KEY);
|
||||
|
||||
if (Constants.NEW_SUBSCRIPTION.equals(content_type)){
|
||||
// new subscription was bought by caregiver
|
||||
gotoPatientDashBoard();
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
requireContext().registerReceiver(notification_receiver, new IntentFilter(AppUtil.NOTIFICATION_ACTION));
|
||||
|
||||
return binding.getRoot();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onDestroyView() {
|
||||
super.onDestroyView();
|
||||
requireContext().unregisterReceiver(notification_receiver);
|
||||
}
|
||||
|
||||
private void checkConnectionStatus() {
|
||||
progressDialog = new ProgressDialog(requireContext());
|
||||
progressDialog.setTitle("Please wait...");
|
||||
|
||||
@@ -1,5 +1,6 @@
|
||||
package com.app.simplitend.welcome.welcomepatient.fragments.contacts;
|
||||
|
||||
import android.net.Uri;
|
||||
import android.view.LayoutInflater;
|
||||
import android.view.ViewGroup;
|
||||
|
||||
@@ -8,8 +9,10 @@ import androidx.recyclerview.widget.DiffUtil;
|
||||
import androidx.recyclerview.widget.ListAdapter;
|
||||
import androidx.recyclerview.widget.RecyclerView;
|
||||
|
||||
import com.app.simplitend.R;
|
||||
import com.app.simplitend.databinding.ContactViewHolderBinding;
|
||||
import com.app.simplitend.welcome.welcomepatient.fragments.contacts.mvvm.Contact;
|
||||
import com.bumptech.glide.Glide;
|
||||
|
||||
import java.util.ArrayList;
|
||||
|
||||
@@ -132,6 +135,12 @@ public class ContactListAdapter extends ListAdapter<ArrayList<Contact>, ContactL
|
||||
|
||||
binding.name.setText(contact.first_name);
|
||||
binding.initial.setText(contact.first_name.toUpperCase());
|
||||
|
||||
if (contact.imageUri != null){
|
||||
binding.image.setImageURI(Uri.parse(contact.imageUri));
|
||||
}else{
|
||||
binding.image.setImageResource(R.drawable.ic_user_filled);
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -473,6 +473,15 @@ public class CreateContactFragment extends Fragment implements WelcomeContracts.
|
||||
.placeholder(android.R.color.darker_gray)
|
||||
.error(R.drawable.ic_contact)
|
||||
.fitCenter().into(binding.image);
|
||||
}else if (contactData.photo_uri != null){
|
||||
Glide.with(requireContext())
|
||||
.load(contactData.photo_uri)
|
||||
.placeholder(android.R.color.darker_gray)
|
||||
.error(R.drawable.ic_contact)
|
||||
.fitCenter().into(binding.image);
|
||||
|
||||
selectedImageUri = contactViewModel.accessPHotoUri(requireContext(), contactData.photo_uri);
|
||||
Log.d(TAG, "setDetails: ");
|
||||
}
|
||||
|
||||
if (contactData.first_name != null) {
|
||||
|
||||
@@ -22,6 +22,7 @@ public class Contact implements Serializable {
|
||||
if (contacts != null && !contacts.isEmpty()){
|
||||
this.first_name = contacts.get(0).first_name;
|
||||
this.email_address = contacts.get(0).email_address;
|
||||
this.imageUri = contacts.get(0).imageUri;
|
||||
|
||||
StringBuilder stringBuilder = new StringBuilder();
|
||||
|
||||
|
||||
@@ -1,7 +1,11 @@
|
||||
package com.app.simplitend.welcome.welcomepatient.fragments.contacts.mvvm;
|
||||
|
||||
import android.app.Application;
|
||||
import android.content.ContentResolver;
|
||||
import android.content.Context;
|
||||
import android.graphics.Bitmap;
|
||||
import android.graphics.BitmapFactory;
|
||||
import android.net.Uri;
|
||||
import android.util.Log;
|
||||
import android.view.LayoutInflater;
|
||||
|
||||
@@ -21,6 +25,8 @@ import org.json.JSONArray;
|
||||
import org.json.JSONObject;
|
||||
|
||||
import java.io.BufferedReader;
|
||||
import java.io.File;
|
||||
import java.io.FileOutputStream;
|
||||
import java.io.IOException;
|
||||
import java.io.InputStream;
|
||||
import java.io.InputStreamReader;
|
||||
@@ -73,6 +79,43 @@ public class ContactViewModel extends AndroidViewModel {
|
||||
return contactLIst;
|
||||
}
|
||||
|
||||
public Uri accessPHotoUri(Context context, String photo_uri) {
|
||||
// Create a ContentResolver
|
||||
ContentResolver contentResolver = context.getContentResolver();
|
||||
|
||||
try {
|
||||
// Convert the PHOTO_URI string to a Uri object
|
||||
Uri uri = Uri.parse(photo_uri);
|
||||
|
||||
// Use ContentResolver to open an InputStream from the Uri
|
||||
InputStream inputStream = contentResolver.openInputStream(uri);
|
||||
|
||||
if (inputStream != null) {
|
||||
// Decode the InputStream into a Bitmap
|
||||
Bitmap contactPhoto = BitmapFactory.decodeStream(inputStream);
|
||||
|
||||
File file = new File(context.getCacheDir(), "img_temp_contact");
|
||||
// Create an output stream to write the Bitmap data to the file
|
||||
FileOutputStream outputStream = new FileOutputStream(file);
|
||||
|
||||
// Compress and save the Bitmap as a PNG file (you can choose a different format)
|
||||
contactPhoto.compress(Bitmap.CompressFormat.PNG, 100, outputStream);
|
||||
|
||||
// Close the output stream and input stream when done
|
||||
outputStream.close();
|
||||
|
||||
// Close the InputStream when done
|
||||
inputStream.close();
|
||||
|
||||
return Uri.fromFile(file);
|
||||
}
|
||||
} catch (Exception e) {
|
||||
// do nothing
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
public UserContactRepository getContactRepository() {
|
||||
return contactRepository;
|
||||
}
|
||||
|
||||
@@ -3,6 +3,8 @@ package com.app.simplitend.welcome.welcomepatient.fragments.contacts.mvvm;
|
||||
import android.content.ContentResolver;
|
||||
import android.content.Context;
|
||||
import android.database.Cursor;
|
||||
import android.graphics.Bitmap;
|
||||
import android.graphics.BitmapFactory;
|
||||
import android.net.Uri;
|
||||
import android.provider.ContactsContract;
|
||||
import android.util.Log;
|
||||
@@ -17,6 +19,8 @@ import com.app.simplitend.welcome.welcomepatient.mvvm.WelcomeApiService;
|
||||
import com.app.simplitend.welcome.welcomepatient.mvvm.WelcomeContracts;
|
||||
import com.app.simplitend.welcome.welcomepatient.mvvm.models.CallResponse;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.io.InputStream;
|
||||
import java.util.HashMap;
|
||||
import java.util.HashSet;
|
||||
import java.util.List;
|
||||
@@ -36,7 +40,8 @@ public class UserContactRepository {
|
||||
private static final String[] PROJECTION = new String[]{
|
||||
ContactsContract.CommonDataKinds.Phone.CONTACT_ID,
|
||||
ContactsContract.Contacts.DISPLAY_NAME,
|
||||
ContactsContract.CommonDataKinds.Phone.NUMBER
|
||||
ContactsContract.CommonDataKinds.Phone.NUMBER,
|
||||
ContactsContract.CommonDataKinds.Phone.PHOTO_URI
|
||||
};
|
||||
|
||||
private static UserContactRepository contactRepository;
|
||||
@@ -185,11 +190,13 @@ public class UserContactRepository {
|
||||
final int c_id_index = cursor.getColumnIndex(ContactsContract.CommonDataKinds.Phone.CONTACT_ID);
|
||||
final int nameIndex = cursor.getColumnIndex(ContactsContract.Contacts.DISPLAY_NAME);
|
||||
final int numberIndex = cursor.getColumnIndex(ContactsContract.CommonDataKinds.Phone.NUMBER);
|
||||
final int photoIndex = cursor.getColumnIndex(ContactsContract.CommonDataKinds.Phone.PHOTO_URI);
|
||||
|
||||
while (cursor.moveToNext()) {
|
||||
String name = cursor.getString(nameIndex);
|
||||
String number = cursor.getString(numberIndex);
|
||||
String c_id = cursor.getString(c_id_index);
|
||||
String photo_uri = cursor.getString(photoIndex);
|
||||
|
||||
if (number == null) continue;
|
||||
if (name == null || name.isEmpty()) name = "No name";
|
||||
@@ -203,6 +210,7 @@ public class UserContactRepository {
|
||||
}
|
||||
|
||||
Contact contact = new Contact(name, number);
|
||||
contact.imageUri = photo_uri;
|
||||
|
||||
Set<Contact> contactList;
|
||||
|
||||
|
||||
@@ -14,7 +14,7 @@ public class ContactData implements Serializable {
|
||||
public String email_address;
|
||||
public String relationship;
|
||||
public String is_sos;
|
||||
public String contact_photo;
|
||||
public String contact_photo, photo_uri;
|
||||
public CareGiverData care_giver_data;
|
||||
|
||||
public String extra_phone_numbers;
|
||||
@@ -31,6 +31,7 @@ public class ContactData implements Serializable {
|
||||
this.phone_number = contact.phone_number;
|
||||
this.email_address = contact.email_address;
|
||||
this.extra_phone_numbers = contact.extra_phone_numbers;
|
||||
this.photo_uri = contact.imageUri;
|
||||
}
|
||||
|
||||
public ContactData(int id) {
|
||||
|
||||
@@ -270,10 +270,14 @@ public class SplashFragment extends Fragment
|
||||
if (!patientData.caregiver_status.equals(AccountPresenter.ACC_ACTIVE_STR)){
|
||||
// account is not active
|
||||
|
||||
gotoReActivateScreen(patientData.caregiver_status,
|
||||
AppUtil.getPatientToken(requireContext()),
|
||||
-1, false);
|
||||
return;
|
||||
if (!patientData.caregiver_status.equals(AccountPresenter.DEFAULT_ACTIVE_STATUS)) {
|
||||
// account is in default state
|
||||
|
||||
gotoReActivateScreen(patientData.caregiver_status,
|
||||
AppUtil.getPatientToken(requireContext()),
|
||||
-1, false);
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
binding.retry.setVisibility(View.GONE);
|
||||
|
||||
@@ -63,8 +63,25 @@
|
||||
android:layout_height="wrap_content"
|
||||
android:orientation="vertical">
|
||||
|
||||
<TextView
|
||||
android:id="@+id/your_plan"
|
||||
android:visibility="gone"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
|
||||
android:text="@string/your_plan"
|
||||
android:fontFamily="@font/nunito_bold"
|
||||
android:textColor="@color/black"
|
||||
android:textSize="@dimen/_18ssp"
|
||||
|
||||
android:layout_marginHorizontal="15dp"
|
||||
android:layout_marginTop="15dp"
|
||||
|
||||
/>
|
||||
|
||||
<com.google.android.material.card.MaterialCardView
|
||||
android:id="@+id/year_card"
|
||||
android:visibility="gone"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
|
||||
@@ -157,6 +174,8 @@
|
||||
android:textColor="@color/black"
|
||||
android:textSize="@dimen/_18ssp"
|
||||
|
||||
android:layout_marginEnd="10dp"
|
||||
|
||||
android:maxLines="1"
|
||||
|
||||
/>
|
||||
@@ -166,7 +185,6 @@
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
|
||||
android:layout_marginStart="10dp"
|
||||
android:fontFamily="@font/nunito_bold"
|
||||
tools:text="@string/_53_5"
|
||||
android:textColor="@color/color_primary_dark"
|
||||
@@ -233,6 +251,7 @@
|
||||
|
||||
<com.google.android.material.card.MaterialCardView
|
||||
android:id="@+id/month_card"
|
||||
android:visibility="gone"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
|
||||
@@ -362,6 +381,7 @@
|
||||
|
||||
<com.google.android.material.button.MaterialButton
|
||||
android:id="@+id/make_payment"
|
||||
android:visibility="gone"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
|
||||
|
||||
@@ -32,13 +32,14 @@
|
||||
android:maxLines="1"
|
||||
/>
|
||||
|
||||
<ImageView
|
||||
<de.hdodenhof.circleimageview.CircleImageView
|
||||
android:id="@+id/image"
|
||||
android:layout_width="30dp"
|
||||
android:layout_height="30dp"
|
||||
android:layout_width="@dimen/_30sdp"
|
||||
android:layout_height="@dimen/_30sdp"
|
||||
android:src="@drawable/ic_user_filled"
|
||||
android:layout_marginVertical="5dp"
|
||||
android:contentDescription="@string/onboard_image"
|
||||
app:tint="@color/color_primary" />
|
||||
/>
|
||||
|
||||
<TextView
|
||||
android:id="@+id/name"
|
||||
|
||||
@@ -484,6 +484,7 @@
|
||||
|
||||
<LinearLayout
|
||||
android:id="@+id/freq_used_apps"
|
||||
android:visibility="gone"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:orientation="horizontal"
|
||||
|
||||
@@ -432,5 +432,7 @@
|
||||
<string name="notifications">Notifications</string>
|
||||
<string name="couldn_t_load_notifications">Couldn\'t load notifications</string>
|
||||
<string name="no_notifications">No notifications</string>
|
||||
<string name="your_plan">Your plan</string>
|
||||
<string name="cancel_subscription">Cancel subscription</string>
|
||||
|
||||
</resources>
|
||||
Reference in New Issue
Block a user