From 662b8c29c407be09050c7265e1b63d0cc1e1b55c Mon Sep 17 00:00:00 2001 From: "marcin.jedynski" Date: Wed, 21 Nov 2018 03:38:53 +0100 Subject: [PATCH] predefined status service linked to backend --- .../findmytutor/activity/SharingFragment.java | 161 +++++++++++---- .../model/PredefinedCoordViewModel.java | 187 ++++++++++++++++++ .../BackgroundLocalizationService.java | 2 +- .../service/PredefinedStatusesService.java | 29 +++ .../uam/wmi/findmytutor/utils/PrefUtils.java | 4 + .../utils/RightButtonPreference.java | 5 - app/src/main/res/layout/pref_sharing.xml | 2 +- app/src/main/res/values-pl/strings.xml | 12 +- app/src/main/res/values/strings.xml | 40 +--- 9 files changed, 368 insertions(+), 74 deletions(-) create mode 100644 app/src/main/java/com/uam/wmi/findmytutor/model/PredefinedCoordViewModel.java create mode 100644 app/src/main/java/com/uam/wmi/findmytutor/service/PredefinedStatusesService.java diff --git a/app/src/main/java/com/uam/wmi/findmytutor/activity/SharingFragment.java b/app/src/main/java/com/uam/wmi/findmytutor/activity/SharingFragment.java index 0b5029e..3b2c681 100644 --- a/app/src/main/java/com/uam/wmi/findmytutor/activity/SharingFragment.java +++ b/app/src/main/java/com/uam/wmi/findmytutor/activity/SharingFragment.java @@ -19,9 +19,15 @@ import android.view.ViewGroup; import android.widget.Button; import android.widget.Toast; +import com.jakewharton.retrofit2.adapter.rxjava2.HttpException; import com.uam.wmi.findmytutor.R; +import com.uam.wmi.findmytutor.model.Feedback; +import com.uam.wmi.findmytutor.network.ApiClient; import com.uam.wmi.findmytutor.service.BackgroundLocalizationService; +import com.uam.wmi.findmytutor.service.FeedbackService; +import com.uam.wmi.findmytutor.service.PredefinedStatusesService; import com.uam.wmi.findmytutor.utils.PrefUtils; +import com.uam.wmi.findmytutor.utils.RestApiHelper; import com.uam.wmi.findmytutor.utils.RightButtonPreference; import java.util.Arrays; @@ -32,55 +38,84 @@ import java.util.Map; import java.util.Objects; import java.util.Set; +import io.reactivex.android.schedulers.AndroidSchedulers; +import io.reactivex.disposables.CompositeDisposable; +import io.reactivex.observers.DisposableSingleObserver; +import io.reactivex.schedulers.Schedulers; +import okhttp3.ResponseBody; +import retrofit2.Response; + import static com.mapbox.mapboxsdk.Mapbox.getApplicationContext; public class SharingFragment extends PreferenceFragment { private HashMap locationLevelMapping; -// private HashMap statusMapping; + private HashMap statusMapping; + private PredefinedStatusesService statusesService; + private CompositeDisposable disposable; + protected Preference locationSharing; + protected Preference locationMode; + protected Preference manualLocationList; + protected PreferenceCategory preferenceCategory; + protected RightButtonPreference manualLocationButton; + protected Preference manualStatus; + protected ListPreference statusList; + + void getStatuses(CompositeDisposable disposable){ + disposable.add(statusesService.getUserPredefinedStatuses(PrefUtils.getUserId(getApplicationContext())) + .subscribeOn(Schedulers.io()) + .observeOn(AndroidSchedulers.mainThread()) + .subscribeWith(new DisposableSingleObserver>() { + @Override + public void onSuccess(List strings) { + setListPreferenceData(statusList.getKey(),strings.toArray(new String[strings.size()])); + } + + @Override + public void onError(Throwable e) { + Toast.makeText(getApplicationContext(), "Error handling status fetch", Toast.LENGTH_SHORT).show(); + + } + })); + } @SuppressLint("ResourceType") @Override public void onCreate(final Bundle savedInstanceState) { super.onCreate(savedInstanceState); + addPreferencesFromResource(R.layout.pref_sharing); + + locationSharing = findPreference("key_sharing_enabled"); + locationMode = findPreference("key_location_level"); + preferenceCategory = (PreferenceCategory) findPreference("category_sharing"); + manualLocationList = findPreference("key_manual_location_value"); + manualLocationButton = (RightButtonPreference) findPreference("manual_location_button"); + manualStatus = findPreference("key_manual_status"); + statusList =(ListPreference) findPreference("key_status_value"); + + statusesService = ApiClient.getClient(getApplicationContext()).create(PredefinedStatusesService.class); + disposable = new CompositeDisposable(); + getStatuses(disposable); + locationLevelMapping = new HashMap(); locationLevelMapping.put(0,"presence"); locationLevelMapping.put(1,"approximated"); locationLevelMapping.put(2,"exact"); locationLevelMapping.put(3,"manual"); - addPreferencesFromResource(R.layout.pref_sharing); - Preference manualStatus = findPreference("key_manual_status"); - Preference locationSharing = findPreference("key_sharing_enabled"); - Preference locationMode = findPreference("key_location_level"); - Preference statusList = findPreference("key_status_value"); - Preference manualLocationList = findPreference("key_manual_location_value"); - - RightButtonPreference manualLocationButton = (RightButtonPreference) findPreference("manual_location_button"); - PreferenceCategory preferenceCategory = (PreferenceCategory) findPreference("category_sharing"); - String temp = PrefUtils.getLocationLevel(getApplicationContext()); - if(!temp.equals("manual")){ - preferenceCategory.removePreference(manualLocationList); - preferenceCategory.removePreference(manualLocationButton); - } - manualLocationButton.setOnPreferenceChangeListener(new Preference.OnPreferenceChangeListener() { - @Override - public boolean onPreferenceChange(Preference preference, Object o) { - //ToDO wywołanie wybierania lokalizacji z mapy - FragmentTransaction fragmentTransaction = getFragmentManager().beginTransaction(); - fragmentTransaction.hide(SharingFragment.this); - fragmentTransaction.commit(); - return true; - } - }); - manualStatus.setOnPreferenceChangeListener((preference, newValue) -> { - ListPreference lp = (ListPreference) findPreference("key_status_value"); - updateListPreference(lp, newValue, "manual_statuses"); - PrefUtils.storeStatus(getApplicationContext(),(String) newValue); + statusMapping = new HashMap(); + statusMapping.put(0,"available"); + statusMapping.put(1,"consultation"); + statusMapping.put(2,"busy"); + /** Main sharing switch**/ + locationSharing.setOnPreferenceChangeListener((buttonView, newValue) -> { + PrefUtils.storeEnableSharingLocalization(getApplicationContext(), (Boolean) newValue); + ((MapActivity)getActivity()).handleBackgroundTaskLifeCycle(); return true; }); + /** Sharing level list **/ locationMode.setOnPreferenceChangeListener((preference, newValue) -> { ListPreference lp = (ListPreference) preference; PrefUtils.storeLocationMode(getApplicationContext(),locationLevelMapping.get(Integer.parseInt((String) newValue))); @@ -95,17 +130,50 @@ public class SharingFragment extends PreferenceFragment { return true; }); + /** Manual location category hiding when location level is != manual **/ + if(!PrefUtils.getLocationLevel(getApplicationContext()).equals("manual")){ + preferenceCategory.removePreference(manualLocationList); + preferenceCategory.removePreference(manualLocationButton); + } + /** Custom manual location list change listener **/ + manualLocationList.setOnPreferenceChangeListener((preference, newValue) -> { + ListPreference lp = (ListPreference) preference; + //ToDo handle manual location change + return true; + }); + /** Button 'choose from map' button listener **/ + manualLocationButton.setOnPreferenceChangeListener(new Preference.OnPreferenceChangeListener() { + @Override + public boolean onPreferenceChange(Preference preference, Object o) { + //ToDO wywołanie wybierania lokalizacji z mapy + FragmentTransaction fragmentTransaction = getFragmentManager().beginTransaction(); + fragmentTransaction.hide(SharingFragment.this); + fragmentTransaction.commit(); + return true; + } + }); + + /** Status list change listener **/ statusList.setOnPreferenceChangeListener((preference, newValue) -> { ListPreference lp = (ListPreference) preference; CharSequence [] entries = lp.getEntries(); PrefUtils.storeStatus(getApplicationContext(),(String) entries[Integer.parseInt((String) newValue)]); +// PrefUtils.storeStatus(getApplicationContext(),statusMapping.get(Integer.parseInt((String) newValue))); + return true; }); + /** Custom status list change listener **/ + manualStatus.setOnPreferenceChangeListener((preference, newValue) -> { +// ListPreference lp = (ListPreference) findPreference("key_status_value"); +// updateListPreference(lp, newValue, "manual_statuses"); +// PrefUtils.storeStatus(getApplicationContext(),(String) newValue); +// statusList.setValue((String) newValue); + disposable.add(statusesService.postUserPredefinedStatus(PrefUtils.getUserId(getApplicationContext()),(String) newValue) + .subscribeOn(Schedulers.io()) + .observeOn(AndroidSchedulers.mainThread()) + .subscribe(this::handleResponse, this::handleError)); - locationSharing.setOnPreferenceChangeListener((buttonView, newValue) -> { - PrefUtils.storeEnableSharingLocalization(getApplicationContext(), (Boolean) newValue); - ((MapActivity)getActivity()).handleBackgroundTaskLifeCycle(); - return true; + return true; }); } @@ -136,8 +204,9 @@ public class SharingFragment extends PreferenceFragment { Set manualStatusSet = sharedPref.getStringSet(storageKey,defaultEntries); manualStatusSet.add((String) newValue); String [] manualStatusArr = manualStatusSet.toArray(new String[0]); - Arrays.sort(manualStatusArr); + //Arrays.sort(manualStatusArr); setListPreferenceData(lp.getKey(),manualStatusArr); +// lp.setValue((String) newValue); SharedPreferences.Editor editor = sharedPref.edit(); editor.putStringSet(storageKey,manualStatusSet); @@ -145,6 +214,7 @@ public class SharingFragment extends PreferenceFragment { } protected void setListPreferenceData(String lp_name, String [] entries) { + //todo bug z pustym statusem ListPreference lp = (ListPreference) findPreference(lp_name); lp.setEntries(entries); CharSequence[] entryValues = new CharSequence [entries.length]; @@ -156,4 +226,27 @@ public class SharingFragment extends PreferenceFragment { lp.setDefaultValue("1"); lp.setEntryValues(entryValues); } + private void handleResponse(List resp) { + getStatuses(disposable); + String newStatus = resp.toArray(new String[resp.size()])[resp.size()-1]; +// Toast.makeText(getApplicationContext(), newStatus, Toast.LENGTH_SHORT).show(); + + statusList.setValue(Integer.toString(resp.size()-1)); + statusList.setSummary(newStatus); + } + + private void handleError(Throwable error) { + if (error instanceof HttpException) { + + ResponseBody responseBody = ((HttpException) error).response().errorBody(); + Toast.makeText(getApplicationContext(), + RestApiHelper.getErrorMessage(responseBody), Toast.LENGTH_SHORT).show(); + + } else { + Toast.makeText(getApplicationContext(), + "Network error " + error.getMessage(), Toast.LENGTH_SHORT).show(); + Log.d("FEEDBACK",error.getMessage()); + } + } + } diff --git a/app/src/main/java/com/uam/wmi/findmytutor/model/PredefinedCoordViewModel.java b/app/src/main/java/com/uam/wmi/findmytutor/model/PredefinedCoordViewModel.java new file mode 100644 index 0000000..78b4897 --- /dev/null +++ b/app/src/main/java/com/uam/wmi/findmytutor/model/PredefinedCoordViewModel.java @@ -0,0 +1,187 @@ +package com.uam.wmi.findmytutor.model; +import java.util.UUID; +import com.google.gson.annotations.Expose; +import com.google.gson.annotations.SerializedName; + +public class PredefinedCoordViewModel { + + @SerializedName("predefinedCoordinateId") + @Expose + private UUID predefinedCoordinateId; + /** + * + * (Required) + * + */ + @SerializedName("latitude") + @Expose + private Double latitude; + /** + * + * (Required) + * + */ + @SerializedName("longitude") + @Expose + private Double longitude; + /** + * + * (Required) + * + */ + @SerializedName("altitude") + @Expose + private Double altitude; + /** + * + * (Required) + * + */ + @SerializedName("userId") + @Expose + private String userId; + @SerializedName("approximatedLocation") + @Expose + private String approximatedLocation; + @SerializedName("displayMode") + @Expose + private String displayMode = "predefined"; + @SerializedName("label") + @Expose + private String label; + + /** + * No args constructor for use in serialization + * + */ + public PredefinedCoordViewModel() { + } + + /** + * + * @param altitude + * @param userId + * @param displayMode + * @param label + * @param longitude + * @param latitude + * @param approximatedLocation + * @param predefinedCoordinateId + */ + public PredefinedCoordViewModel(UUID predefinedCoordinateId, Double latitude, Double longitude, Double altitude, String userId, String approximatedLocation, String displayMode, String label) { + super(); + this.predefinedCoordinateId = predefinedCoordinateId; + this.latitude = latitude; + this.longitude = longitude; + this.altitude = altitude; + this.userId = userId; + this.approximatedLocation = approximatedLocation; + this.displayMode = displayMode; + this.label = label; + } + + public UUID getPredefinedCoordinateId() { + return predefinedCoordinateId; + } + + public void setPredefinedCoordinateId(UUID predefinedCoordinateId) { + this.predefinedCoordinateId = predefinedCoordinateId; + } + + /** + * + * (Required) + * + */ + public Double getLatitude() { + return latitude; + } + + /** + * + * (Required) + * + */ + public void setLatitude(Double latitude) { + this.latitude = latitude; + } + + /** + * + * (Required) + * + */ + public Double getLongitude() { + return longitude; + } + + /** + * + * (Required) + * + */ + public void setLongitude(Double longitude) { + this.longitude = longitude; + } + + /** + * + * (Required) + * + */ + public Double getAltitude() { + return altitude; + } + + /** + * + * (Required) + * + */ + public void setAltitude(Double altitude) { + this.altitude = altitude; + } + + /** + * + * (Required) + * + */ + public String getUserId() { + return userId; + } + + /** + * + * (Required) + * + */ + public void setUserId(String userId) { + this.userId = userId; + } + + public String getApproximatedLocation() { + return approximatedLocation; + } + + public void setApproximatedLocation(String approximatedLocation) { + this.approximatedLocation = approximatedLocation; + } + + public String getDisplayMode() { + return displayMode; + } + + public void setDisplayMode(String displayMode) { + this.displayMode = displayMode; + } + + public String getLabel() { + return label; + } + + public void setLabel(String label) { + this.label = label; + } + +} \ No newline at end of file diff --git a/app/src/main/java/com/uam/wmi/findmytutor/service/BackgroundLocalizationService.java b/app/src/main/java/com/uam/wmi/findmytutor/service/BackgroundLocalizationService.java index 2b3ca3c..9d25777 100644 --- a/app/src/main/java/com/uam/wmi/findmytutor/service/BackgroundLocalizationService.java +++ b/app/src/main/java/com/uam/wmi/findmytutor/service/BackgroundLocalizationService.java @@ -306,7 +306,7 @@ public class BackgroundLocalizationService extends Service { latitude, longitude, altitude, - PrefUtils.getUserStatus(getApplicationContext()), + (PrefUtils.isStatusEnabled(getApplicationContext())) ? PrefUtils.getUserStatus(getApplicationContext()) : "", PrefUtils.getUserId(getApplicationContext()), PrefUtils.getLocationLevel(getApplicationContext()) ); diff --git a/app/src/main/java/com/uam/wmi/findmytutor/service/PredefinedStatusesService.java b/app/src/main/java/com/uam/wmi/findmytutor/service/PredefinedStatusesService.java new file mode 100644 index 0000000..b52d79e --- /dev/null +++ b/app/src/main/java/com/uam/wmi/findmytutor/service/PredefinedStatusesService.java @@ -0,0 +1,29 @@ +package com.uam.wmi.findmytutor.service; +import com.uam.wmi.findmytutor.model.PredefinedCoordViewModel; +import java.util.List; +import io.reactivex.Single; +import retrofit2.http.Body; +import retrofit2.http.DELETE; +import retrofit2.http.GET; +import retrofit2.http.POST; +import retrofit2.http.Path; + +public interface PredefinedStatusesService { + @GET("api/users/predefined/status/{tutorId}") + Single> getUserPredefinedStatuses(@Path("tutorId") String tutorId); + + @POST("api/users/predefined/status/{tutorId}") + Single> postUserPredefinedStatus(@Path("tutorId") String tutorId, @Body String status); + + @DELETE("api/users/predefined/status/{tutorId}") + Single> deleteUserPredefinedStatus(@Path("tutorId") String tutorId, @Body String status); + + @GET("api/users/predefined/coordinate/{tutorId}") + Single> getUserPredefinedCoords(@Path("tutorId") String tutorId); + + @POST("api/users/predefined/coordinate/{tutorId}") + Single> postUserPredefinedCoord(@Path("tutorId") String tutorId, @Body PredefinedCoordViewModel coord); + + @DELETE("api/users/predefined/coordinate/{tutorId}") + Single> deleteUserPredefinedCoord(@Path("tutorId") String tutorId, @Body PredefinedCoordViewModel coord); +} diff --git a/app/src/main/java/com/uam/wmi/findmytutor/utils/PrefUtils.java b/app/src/main/java/com/uam/wmi/findmytutor/utils/PrefUtils.java index 0982f5a..d2695de 100644 --- a/app/src/main/java/com/uam/wmi/findmytutor/utils/PrefUtils.java +++ b/app/src/main/java/com/uam/wmi/findmytutor/utils/PrefUtils.java @@ -54,6 +54,10 @@ public class PrefUtils { return getSharedPreferences(context).getString("USER_ID", null); } + public static boolean isStatusEnabled(Context context){ + return getSharedPreferences(context).getBoolean("key_status_enabled",false); + + } public static String getUserStatus(Context context) { return getSharedPreferences(context).getString("status_entry", "Available"); } diff --git a/app/src/main/java/com/uam/wmi/findmytutor/utils/RightButtonPreference.java b/app/src/main/java/com/uam/wmi/findmytutor/utils/RightButtonPreference.java index fb5f140..5fdf137 100644 --- a/app/src/main/java/com/uam/wmi/findmytutor/utils/RightButtonPreference.java +++ b/app/src/main/java/com/uam/wmi/findmytutor/utils/RightButtonPreference.java @@ -5,11 +5,8 @@ import android.util.AttributeSet; import android.view.View; import android.view.ViewGroup; import android.widget.Button; -import android.widget.Toast; import com.uam.wmi.findmytutor.R; -import static com.mapbox.mapboxsdk.Mapbox.getApplicationContext; - public class RightButtonPreference extends Preference { public RightButtonPreference(Context context, AttributeSet attrs) { @@ -30,11 +27,9 @@ public class RightButtonPreference extends Preference { Button button = (Button)view.findViewById(R.id.button_choose_from_map); if(button != null) { - button.setText("dupa"); button.setOnClickListener(new View.OnClickListener() { @Override public void onClick(View view) { - Toast.makeText(getApplicationContext(), "dupa4", Toast.LENGTH_SHORT).show(); callChangeListener(null); notifyChanged(); } diff --git a/app/src/main/res/layout/pref_sharing.xml b/app/src/main/res/layout/pref_sharing.xml index d36a96d..73f957b 100644 --- a/app/src/main/res/layout/pref_sharing.xml +++ b/app/src/main/res/layout/pref_sharing.xml @@ -44,7 +44,7 @@ android:title="@string/status_switch_title"/> Obecność Przybliżona Dokładna - Sczegółowość udostępniania + Poziom udostępniania key_location_level Opis key_description @@ -116,7 +116,7 @@ Dyżury Dyżury Zakład - Loading … + Ładowanie … Logo find my tutor Login (Ldap) Zaloguj! @@ -130,6 +130,14 @@ Wyślij nam feedback Zgłoś błąd Bounds OFF + Find My Tutor - feedback + Find My Tutor - zgłoszenie błędu + Proszę opisz swoje spostrzeżnia. + Wyślij anonimowo + Manualna + Wybierz z mapy + Odmowa dostępu + Uprawnienia powinny zostać przyznane. diff --git a/app/src/main/res/values/strings.xml b/app/src/main/res/values/strings.xml index 405d748..6eac9b5 100644 --- a/app/src/main/res/values/strings.xml +++ b/app/src/main/res/values/strings.xml @@ -44,7 +44,7 @@ White List Settings - findmytutorwmi@gmail.com + findmytutorwmi@gmail.com @@ -68,6 +68,7 @@ key_location_level Choose status + key_status_value Status Busy Available @@ -175,7 +176,7 @@ %d locations reported - Main2Activity + Main2Activity TODO @@ -199,35 +200,12 @@ Log in Users list Invalid login format. - Locale utils + Locale utils Permission denied - permission should be granted - - - MapActivity - - Enable social recommendations - Recommendations for people to contact - based on your message history - - - Display name - John Smith - - Add friends to messages - - Sync frequency - - System sync settings - - - Notifications - - New message notifications - - Ringtone - Silent - - Vibrate + permission should be granted + + + MapActivity + User profile