diff --git a/.idea/inspectionProfiles/Project_Default.xml b/.idea/inspectionProfiles/Project_Default.xml
new file mode 100644
index 0000000..d7a7dfa
--- /dev/null
+++ b/.idea/inspectionProfiles/Project_Default.xml
@@ -0,0 +1,9 @@
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/app/build.gradle b/app/build.gradle
index 3c14510..ddf3e1a 100644
--- a/app/build.gradle
+++ b/app/build.gradle
@@ -10,7 +10,7 @@ android {
applicationId "com.uam.wmi.findmytutor"
minSdkVersion 22
targetSdkVersion 27
- versionCode 1
+ versionCode 3
versionName "0.9.0-alpha"
testInstrumentationRunner "android.support.test.runner.AndroidJUnitRunner"
vectorDrawables.useSupportLibrary = true
@@ -31,6 +31,7 @@ repositories {
dependencies {
implementation fileTree(dir: 'libs', include: ['*.jar'])
+ implementation 'com.android.support:preference-v7:27.1.1'
implementation 'com.android.support:appcompat-v7:27.1.1'
implementation 'com.android.support:design:27.1.1'
implementation 'com.android.support:support-v4:27.1.1'
@@ -58,7 +59,7 @@ dependencies {
implementation 'com.auth0.android:jwtdecode:1.1.1'
implementation 'com.annimon:stream:1.2.1'
implementation 'com.google.android.gms:play-services-location:16.0.0'
-
+ implementation 'com.mapbox.mapboxsdk:mapbox-sdk-turf:4.0.0'
// FloatingBarMenu
implementation 'com.getbase:floatingactionbutton:1.10.1'
diff --git a/app/src/main/AndroidManifest.xml b/app/src/main/AndroidManifest.xml
index 54170df..ed85fed 100644
--- a/app/src/main/AndroidManifest.xml
+++ b/app/src/main/AndroidManifest.xml
@@ -10,7 +10,6 @@
-
@@ -45,18 +44,16 @@
android:label="@string/title_activity_login"
android:launchMode="singleTask"
android:noHistory="true" />
-
+ android:exported="false"
+ android:launchMode="singleTop" />
-
+
\ No newline at end of file
diff --git a/app/src/main/assets/building.geojson b/app/src/main/assets/building.geojson
new file mode 100644
index 0000000..a151032
--- /dev/null
+++ b/app/src/main/assets/building.geojson
@@ -0,0 +1,398 @@
+{
+ "features": [
+ {
+ "type": "Feature",
+ "properties": {
+ "name": "Skrzydło B",
+ "longitude" : 52.466669,
+ "latitude" : 16.926624
+ },
+ "geometry": {
+ "coordinates": [
+ [
+ [
+ 16.92618,
+ 52.466248
+ ],
+ [
+ 16.926435,
+ 52.466201
+ ],
+ [
+ 16.92646,
+ 52.466255
+ ],
+ [
+ 16.926516,
+ 52.466244
+ ],
+ [
+ 16.926999,
+ 52.46711
+ ],
+ [
+ 16.926796,
+ 52.467145
+ ],
+ [
+ 16.926782,
+ 52.467117
+ ],
+ [
+ 16.926784,
+ 52.467121
+ ],
+ [
+ 16.926691,
+ 52.467139
+ ],
+ [
+ 16.926662,
+ 52.46709
+ ],
+ [
+ 16.926757,
+ 52.467072
+ ],
+ [
+ 16.926544,
+ 52.466691
+ ],
+ [
+ 16.926434,
+ 52.46671
+ ],
+ [
+ 16.926396,
+ 52.466655
+ ],
+ [
+ 16.926519,
+ 52.466628
+ ],
+ [
+ 16.926323,
+ 52.466281
+ ],
+ [
+ 16.926213,
+ 52.466307
+ ],
+ [
+ 16.92618,
+ 52.466248
+ ]
+ ]
+ ],
+ "type": "Polygon"
+ },
+ "id": "41798cf663bc55c10e6c51c3fe174eda"
+ },
+ {
+ "type": "Feature",
+ "properties": {
+ "name": "Biblioteka",
+ "longitude" : 52.467351,
+ "latitude" : 16.926900
+ },
+ "geometry": {
+ "coordinates": [
+ [
+ [
+ 16.927048,
+ 52.46721
+ ],
+ [
+ 16.926627,
+ 52.467295
+ ],
+ [
+ 16.926732,
+ 52.467482
+ ],
+ [
+ 16.926876,
+ 52.467461
+ ],
+ [
+ 16.926967,
+ 52.467428
+ ],
+ [
+ 16.927014,
+ 52.467402
+ ],
+ [
+ 16.927171,
+ 52.467359
+ ],
+ [
+ 16.9271,
+ 52.467202
+ ],
+ [
+ 16.927048,
+ 52.46721
+ ]
+ ]
+ ],
+ "type": "Polygon"
+ },
+ "id": "7328c3c9dffd3e76be8d3dcef4f58ddc"
+ },
+ {
+ "type": "Feature",
+ "properties": {
+ "name": "Łącznik",
+ "longitude" : 52.466619,
+ "latitude" : 16.926860
+ },
+ "geometry": {
+ "coordinates": [
+ [
+ [
+ 16.926759,
+ 52.466683
+ ],
+ [
+ 16.927088,
+ 52.46661
+ ],
+ [
+ 16.927019,
+ 52.466502
+ ],
+ [
+ 16.9267,
+ 52.466571
+ ],
+ [
+ 16.926759,
+ 52.466683
+ ]
+ ]
+ ],
+ "type": "Polygon"
+ },
+ "id": "8c19ee28e4c07ece9756fd21f290713b"
+ },
+ {
+ "type": "Feature",
+ "properties": {
+ "name": "Skrzydło A",
+ "longitude" : 52.466559,
+ "latitude" : 16.927163
+ },
+ "geometry": {
+ "coordinates": [
+ [
+ [
+ 16.926771,
+ 52.466106
+ ],
+ [
+ 16.926898,
+ 52.466079
+ ],
+ [
+ 16.926926,
+ 52.466126
+ ],
+ [
+ 16.927026,
+ 52.466107
+ ],
+ [
+ 16.92723,
+ 52.466473
+ ],
+ [
+ 16.927184,
+ 52.466483
+ ],
+ [
+ 16.927243,
+ 52.466586
+ ],
+ [
+ 16.927334,
+ 52.46656
+ ],
+ [
+ 16.927602,
+ 52.466889
+ ],
+ [
+ 16.927275,
+ 52.466959
+ ],
+ [
+ 16.926771,
+ 52.466106
+ ]
+ ]
+ ],
+ "type": "Polygon"
+ },
+ "id": "c33bfba772c85cc38ae417843d31b1ff"
+ },
+ {
+ "type": "Feature",
+ "properties": {
+ "name": "Aule",
+ "longitude" : 52.467114,
+ "latitude" : 16.927621
+
+ },
+ "geometry": {
+ "coordinates": [
+ [
+ [
+ 16.92731,
+ 52.467158
+ ],
+ [
+ 16.927315,
+ 52.46718
+ ],
+ [
+ 16.927348,
+ 52.467199
+ ],
+ [
+ 16.927393,
+ 52.467224
+ ],
+ [
+ 16.927426,
+ 52.467239
+ ],
+ [
+ 16.927476,
+ 52.467258
+ ],
+ [
+ 16.92755,
+ 52.467264
+ ],
+ [
+ 16.927625,
+ 52.467263
+ ],
+ [
+ 16.927699,
+ 52.467246
+ ],
+ [
+ 16.92776,
+ 52.467212
+ ],
+ [
+ 16.927821,
+ 52.467158
+ ],
+ [
+ 16.927838,
+ 52.467099
+ ],
+ [
+ 16.927827,
+ 52.467059
+ ],
+ [
+ 16.927793,
+ 52.467012
+ ],
+ [
+ 16.927738,
+ 52.466976
+ ],
+ [
+ 16.927661,
+ 52.466949
+ ],
+ [
+ 16.927581,
+ 52.466939
+ ],
+ [
+ 16.927534,
+ 52.466938
+ ],
+ [
+ 16.927467,
+ 52.466949
+ ],
+ [
+ 16.927387,
+ 52.467047
+ ],
+ [
+ 16.927315,
+ 52.467153
+ ],
+ [
+ 16.92731,
+ 52.467158
+ ]
+ ]
+ ],
+ "type": "Polygon"
+ },
+ "id": "c779419e3fd7faef8555e1099547a82c"
+ },
+ {
+ "type": "Feature",
+ "properties": {
+ "name": "Hol",
+ "longitude" : 52.4671021,
+ "latitude" : 16.927122
+ },
+ "geometry": {
+ "coordinates": [
+ [
+ [
+ 16.926625,
+ 52.467294
+ ],
+ [
+ 16.926568,
+ 52.46719
+ ],
+ [
+ 16.927008,
+ 52.467108
+ ],
+ [
+ 16.926953,
+ 52.467024
+ ],
+ [
+ 16.927463,
+ 52.466919
+ ],
+ [
+ 16.927467,
+ 52.466956
+ ],
+ [
+ 16.927316,
+ 52.467153
+ ],
+ [
+ 16.926907,
+ 52.467235
+ ],
+ [
+ 16.926625,
+ 52.467294
+ ]
+ ]
+ ],
+ "type": "Polygon"
+ },
+ "id": "facdd5349991758b9ad99d4e123c91cc"
+ }
+ ],
+ "type": "FeatureCollection"
+}
\ No newline at end of file
diff --git a/app/src/main/java/com/uam/wmi/findmytutor/activity/BaseActivity.java b/app/src/main/java/com/uam/wmi/findmytutor/activity/BaseActivity.java
index 2f4cba0..c347afc 100644
--- a/app/src/main/java/com/uam/wmi/findmytutor/activity/BaseActivity.java
+++ b/app/src/main/java/com/uam/wmi/findmytutor/activity/BaseActivity.java
@@ -1,6 +1,7 @@
package com.uam.wmi.findmytutor.activity;
import android.Manifest;
+import android.annotation.SuppressLint;
import android.app.Fragment;
import android.app.FragmentTransaction;
import android.content.Intent;
@@ -24,15 +25,22 @@ import android.view.MenuItem;
import android.view.View;
import android.widget.FrameLayout;
import android.widget.Toast;
-
import com.uam.wmi.findmytutor.R;
import com.uam.wmi.findmytutor.service.BackgroundLocalizationService;
import com.uam.wmi.findmytutor.utils.ActiveFragment;
+import com.uam.wmi.findmytutor.utils.FeedbackUtils;
import com.uam.wmi.findmytutor.utils.PrefUtils;
+import com.uam.wmi.findmytutor.utils.RxSearchObservable;
+
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
+import java.util.concurrent.TimeUnit;
+
+import io.reactivex.android.schedulers.AndroidSchedulers;
+import io.reactivex.schedulers.Schedulers;
+
import static com.uam.wmi.findmytutor.utils.PrefUtils.storeBackgroundLocationStatus;
@@ -41,14 +49,10 @@ public abstract class BaseActivity
extends AppCompatActivity
implements BottomNavigationView.OnNavigationItemSelectedListener {
- String tag = getClass().getName();
-
protected static final int REQUEST_PERMISSIONS = 100;
private final static int REQUEST_CODE_ASK_PERMISSIONS = 1;
-
- private static final String[] REQUIRED_SDK_PERMISSIONS = new String[] {
- Manifest.permission.ACCESS_FINE_LOCATION, Manifest.permission.ACCESS_COARSE_LOCATION, Manifest.permission.ACCESS_LOCATION_EXTRA_COMMANDS };
-
+ private static final String[] REQUIRED_SDK_PERMISSIONS = new String[]{
+ Manifest.permission.ACCESS_FINE_LOCATION, Manifest.permission.ACCESS_COARSE_LOCATION, Manifest.permission.ACCESS_LOCATION_EXTRA_COMMANDS};
public DrawerLayout drawerLayout;
protected BottomNavigationView navigationView;
protected NavigationView drawerNavigationView;
@@ -56,43 +60,52 @@ public abstract class BaseActivity
protected Toolbar toolbar;
protected boolean isTutor;
+ String tag = getClass().getName();
+
+ protected FeedbackUtils feedbackUtils;
+
private ActionBarDrawerToggle actionBarDrawerToggle;
private SharingFragment sharingFragment;
private Fragment userListFragment;
private ActiveFragment activeFragment = ActiveFragment.NONE;
+ private SearchView searchView;
+ @SuppressLint("CheckResult")
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(getContentViewId());
drawerNavigationView = findViewById(R.id.nav_view);
sideDrawer = findViewById(R.id.activity_container);
-
+ feedbackUtils = new FeedbackUtils(BaseActivity.this);
drawerNavigationView.setNavigationItemSelectedListener(
item -> {
String itemName = (String) item.getTitle();
Intent launchIntent;
- if (itemName.equals(getResources().getString(R.string.navigation_item_whitelist))) {
+ if (itemName.equals(getResources().getString(R.string.navigation_item_whitelist))) {
/* launchIntent = new Intent(getApplicationContext(), WhitelistActivity.class);
startActivity(launchIntent);*/
- } else if (itemName.equals(getResources().getString(R.string.navigation_item_blacklist))) {
+ } else if (itemName.equals(getResources().getString(R.string.navigation_item_blacklist))) {
/* launchIntent = new Intent(getApplicationContext(), BlacklistActivity.class);
startActivity(launchIntent);*/
- } else if (itemName.equals(getResources().getString(R.string.navigation_item_profile))) {
+
+ } else if (itemName.equals(getResources().getString(R.string.navigation_item_profile))) {
+
/* launchIntent = new Intent(getApplicationContext(), ProfileActivity.class);
startActivity(launchIntent);*/
- } else if (itemName.equals(getResources().getString(R.string.navigation_item_settings))) {
+ } else if (itemName.equals(getResources().getString(R.string.navigation_item_settings))) {
launchIntent = new Intent(getApplicationContext(), SettingsActivity.class);
startActivity(launchIntent);
- } else if (itemName.equals(getResources().getString(R.string.navigation_item_logout))) {
+ } else if (itemName.equals(getResources().getString(R.string.navigation_item_logout))) {
if(PrefUtils.isBackgroundLocationServiceRunning(getApplicationContext())) {
+
stopBackgroundLocalizationTask();
}
- storeBackgroundLocationStatus(getApplication(),false);
- PrefUtils.storeIsLoggedIn(getApplicationContext(),false);
+ storeBackgroundLocationStatus(getApplication(), false);
+ PrefUtils.storeIsLoggedIn(getApplicationContext(), false);
Intent i = getBaseContext().getPackageManager()
.getLaunchIntentForPackage(getBaseContext().getPackageName());
@@ -101,8 +114,14 @@ public abstract class BaseActivity
}
startActivity(i);
finish();
+ } else if (itemName.equals(getResources().getString(R.string.navigation_item_feedback))) {
+ feedbackUtils.showNoteDialog("FEEDBACK");
- }
+ /*showNoteDialog(BaseActivity.this, );*/
+ } else if (itemName.equals(getResources().getString(R.string.navigation_item_bug))) {
+ feedbackUtils.showNoteDialog("BUG REPORT");
+ /*showNoteDialog(BaseActivity.this, "BUG REPORT");*/
+ }
sideDrawer.closeDrawers();
@@ -116,14 +135,13 @@ public abstract class BaseActivity
userListFragment = new UsersListFragment();
isTutor = PrefUtils.getIsTutor(getApplicationContext());
+
if (!isTutor) {
navigationView.findViewById(R.id.nav_profile).setVisibility(View.GONE);
+ drawerNavigationView.getMenu().setGroupVisible(R.id.drawer_group_tutor, false);
}
-
-
}
-
protected void checkPermissions() {
final List missingPermissions = new ArrayList();
@@ -187,9 +205,9 @@ public abstract class BaseActivity
Boolean shouldServiceRun = PrefUtils.isEnableSharingLocalization(getApplicationContext())
&& !PrefUtils.isBackgroundLocationServiceRunning(getApplicationContext());
- if (shouldServiceRun){
+ if (shouldServiceRun) {
startBackgroundLocalizationTask();
- } else if(PrefUtils.isBackgroundLocationServiceRunning(getApplicationContext()) &&
+ } else if (PrefUtils.isBackgroundLocationServiceRunning(getApplicationContext()) &&
!PrefUtils.isEnableSharingLocalization(getApplicationContext())) {
stopBackgroundLocalizationTask();
}
@@ -241,39 +259,44 @@ public abstract class BaseActivity
actionBarDrawerToggle.onConfigurationChanged(newConfig);
}
+ @SuppressLint("CheckResult")
@Override
public boolean onCreateOptionsMenu(Menu menu) {
getMenuInflater().inflate(R.menu.menu_main, menu);
MenuItem myActionMenuItem = menu.findItem(R.id.action_search);
- final SearchView searchView = (SearchView) myActionMenuItem.getActionView();
- searchView.setOnQueryTextListener(new SearchView.OnQueryTextListener() {
- @Override
- public boolean onQueryTextSubmit(String input) {
- if (activeFragment.equals(ActiveFragment.USER_LIST)) {
- executeUserListSearch(input);
- }
+ searchView = (SearchView) myActionMenuItem.getActionView();
- return false;
+ searchView.setOnQueryTextFocusChangeListener((v, hasFocus) -> {
+ if (!hasFocus && activeFragment.equals(ActiveFragment.NONE)) {
+ restoreMapMarkers();
}
-
- @Override
-
- public boolean onQueryTextChange(String input) {
- if (activeFragment.equals(ActiveFragment.USER_LIST)) {
- executeUserListSearch(input);
- }
-
- return true;
- }
-
});
+
+ RxSearchObservable.fromView(searchView)
+ .map(String::toLowerCase)
+ .debounce(300, TimeUnit.MILLISECONDS)
+ .distinctUntilChanged()
+ .subscribeOn(Schedulers.io())
+ .observeOn(AndroidSchedulers.mainThread())
+ .subscribe(this::executeSearch);
+
return true;
}
- private void executeUserListSearch(String input) {
- ((UsersListFragment) userListFragment).searchUser(input);
+ private void executeSearch(String input) {
+ if (activeFragment.equals(ActiveFragment.USER_LIST)) {
+ ((UsersListFragment) userListFragment).searchUser(input);
+ } else if (activeFragment.equals(ActiveFragment.NONE)) {
+ searchUser(input);
+ }
+ }
+
+ public void searchUser(String textToSearch) {
+ }
+
+ public void restoreMapMarkers() {
}
@Override
@@ -284,7 +307,6 @@ public abstract class BaseActivity
return super.onOptionsItemSelected(item);
}
-
@Override
protected void onStart() {
super.onStart();
@@ -306,13 +328,13 @@ public abstract class BaseActivity
@Override
public boolean onNavigationItemSelected(@NonNull MenuItem item) {
-
navigationView.postDelayed(() -> {
int itemId = item.getItemId();
if (itemId == R.id.nav_map) {
removeFragment(sharingFragment);
removeFragment(userListFragment);
+ activeFragment = ActiveFragment.NONE;
} else if (itemId == R.id.nav_profile) {
loadUserSettingsFragment();
} else if (itemId == R.id.nav_user_list) {
@@ -352,6 +374,8 @@ public abstract class BaseActivity
item.setChecked(true);
}
+
+
abstract int getNavigationMenuItemId();
abstract int getContentViewId();
diff --git a/app/src/main/java/com/uam/wmi/findmytutor/activity/LoginActivity.java b/app/src/main/java/com/uam/wmi/findmytutor/activity/LoginActivity.java
index 53eb050..912598a 100644
--- a/app/src/main/java/com/uam/wmi/findmytutor/activity/LoginActivity.java
+++ b/app/src/main/java/com/uam/wmi/findmytutor/activity/LoginActivity.java
@@ -33,6 +33,7 @@ import com.uam.wmi.findmytutor.service.UserService;
import com.uam.wmi.findmytutor.utils.PrefUtils;
import com.uam.wmi.findmytutor.utils.RestApiHelper;
+import java.util.Objects;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
@@ -72,12 +73,6 @@ public class LoginActivity extends AppCompatActivity {
return false;
});
- Switch tutorLogin = findViewById(R.id.tutor_login_switch);
-
- tutorLogin.setOnCheckedChangeListener((buttonView, isChecked) -> {
- PrefUtils.storeIsTutor(getApplicationContext(), isChecked);
- });
-
Button mEmailSignInButton = findViewById(R.id.email_sign_in_button);
mEmailSignInButton.setOnClickListener(view -> attemptLogin());
@@ -158,17 +153,9 @@ public class LoginActivity extends AppCompatActivity {
private void loginProcess(String email, String password) {
- Log.e("LOGIN", String.valueOf(PrefUtils.getIsTutor(getApplicationContext())));
+ ValidateUser user = new ValidateUser(email, password);
- //Fake validate
- LdapUser user = new LdapUser(email, password, "admin", (PrefUtils.getIsTutor(getApplicationContext())) ? "Tutor" : "Student", "Imię", "Nazwisko", email);
-
- // ValidateUser user = new ValidateUser(email, password);
-
- // LDAP logging
- // disposable.add(ldapService.validate(user)
-
- disposable.add(ldapService.fakeValidate(user)
+ disposable.add(ldapService.validate(user)
.subscribeOn(Schedulers.io())
.observeOn(AndroidSchedulers.mainThread())
.subscribe(this::handleResponse, this::handleError));
@@ -192,13 +179,18 @@ public class LoginActivity extends AppCompatActivity {
String token = jwtToken.getToken();
JWT jwt = new JWT(token);
- Claim role = jwt.getClaim("nameid");
+ Claim userId = jwt.getClaim("nameid");
+ Claim role = jwt.getClaim("http://schemas.microsoft.com/ws/2008/06/identity/claims/role");
+ if(!Objects.requireNonNull(role.asString()).equals("Student")){
+ PrefUtils.storeIsTutor(getApplicationContext(), true);
+ }
+
PrefUtils.storeIsLoggedIn(getApplicationContext(), true);
PrefUtils.storeApiKey(getApplicationContext(), token);
- PrefUtils.storeUserId(getApplicationContext(), role.asString());
+ PrefUtils.storeUserId(getApplicationContext(), userId.asString());
- getUserProfile(role.asString());
+ getUserProfile(userId.asString());
Intent data = new Intent();
String txt = "Main Activity";
diff --git a/app/src/main/java/com/uam/wmi/findmytutor/activity/MapActivity.java b/app/src/main/java/com/uam/wmi/findmytutor/activity/MapActivity.java
index 47da9ea..543bf03 100644
--- a/app/src/main/java/com/uam/wmi/findmytutor/activity/MapActivity.java
+++ b/app/src/main/java/com/uam/wmi/findmytutor/activity/MapActivity.java
@@ -4,13 +4,9 @@ import android.Manifest;
import android.animation.ObjectAnimator;
import android.animation.ValueAnimator;
import android.annotation.SuppressLint;
-import android.content.Context;
-import android.content.SharedPreferences;
-import android.graphics.Color;
import android.location.Location;
import android.os.Bundle;
import android.os.Handler;
-import android.support.design.widget.FloatingActionButton;
import android.support.v4.content.ContextCompat;
import android.support.v7.app.AlertDialog;
import android.util.Log;
@@ -21,6 +17,8 @@ import android.widget.Button;
import android.widget.TextView;
import android.widget.Toast;
+import com.annimon.stream.Stream;
+import com.getbase.floatingactionbutton.FloatingActionButton;
import com.jakewharton.retrofit2.adapter.rxjava2.HttpException;
import com.mapbox.android.core.permissions.PermissionsListener;
import com.mapbox.android.core.permissions.PermissionsManager;
@@ -29,8 +27,6 @@ import com.mapbox.mapboxsdk.annotations.Icon;
import com.mapbox.mapboxsdk.annotations.IconFactory;
import com.mapbox.mapboxsdk.annotations.Marker;
import com.mapbox.mapboxsdk.annotations.MarkerOptions;
-import com.mapbox.mapboxsdk.camera.CameraPosition;
-import com.mapbox.mapboxsdk.camera.CameraUpdateFactory;
import com.mapbox.mapboxsdk.geometry.LatLng;
import com.mapbox.mapboxsdk.location.LocationComponent;
import com.mapbox.mapboxsdk.location.LocationComponentOptions;
@@ -39,9 +35,6 @@ import com.mapbox.mapboxsdk.location.modes.RenderMode;
import com.mapbox.mapboxsdk.maps.MapView;
import com.mapbox.mapboxsdk.maps.MapboxMap;
import com.mapbox.mapboxsdk.maps.OnMapReadyCallback;
-import com.mapbox.mapboxsdk.style.layers.CircleLayer;
-import com.mapbox.mapboxsdk.style.layers.Layer;
-import com.mapbox.mapboxsdk.style.sources.VectorSource;
import com.uam.wmi.findmytutor.R;
import com.uam.wmi.findmytutor.model.Coordinate;
import com.uam.wmi.findmytutor.model.User;
@@ -56,6 +49,7 @@ import java.util.ArrayList;
import java.util.HashMap;
import java.util.HashSet;
import java.util.List;
+import java.util.Set;
import io.reactivex.android.schedulers.AndroidSchedulers;
import io.reactivex.disposables.CompositeDisposable;
@@ -63,13 +57,6 @@ import io.reactivex.observers.DisposableSingleObserver;
import io.reactivex.schedulers.Schedulers;
import okhttp3.ResponseBody;
import timber.log.Timber;
-import java.util.Set;
-
-import static com.mapbox.mapboxsdk.style.layers.Property.NONE;
-import static com.mapbox.mapboxsdk.style.layers.Property.VISIBLE;
-import static com.mapbox.mapboxsdk.style.layers.PropertyFactory.circleColor;
-import static com.mapbox.mapboxsdk.style.layers.PropertyFactory.circleRadius;
-import static com.mapbox.mapboxsdk.style.layers.PropertyFactory.visibility;
public class MapActivity extends BaseActivity
@@ -86,24 +73,30 @@ public class MapActivity extends BaseActivity
private int mInterval = 10000;
private Handler mHandler = new Handler();
private Runnable mStatusChecker;
+ private Handler manualLocHandler = new Handler();
+ private Runnable manualLocStatusChecker;
private MapView mapView;
private MapboxMap mapboxMap;
- private Marker droppedMarker;
+ private Button selectLocationButton;
+ private Button removeLocationButton;
+ private Marker tmpLocalMarker;
+ private Coordinate droppedMarkercoordinate;
private HashMap coordsMap = new HashMap<>();
private HashMap markerHash = new HashMap<>();
private Set previousCoordsIds = new HashSet<>();
-
+ // Camera Animation params
private int zoomParam = 17;
private int bearingParam = 180;
private int tiltParam = 30;
+ private String myID;
+
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
- final SharedPreferences sharedPref = getSharedPreferences("fmtPrefs", Context.MODE_PRIVATE);
-
+ myID = PrefUtils.getUserId(getApplicationContext());
// fetching coords service
coordinateService = ApiClient.getClient(getApplicationContext())
.create(CoordinateService.class);
@@ -119,8 +112,9 @@ public class MapActivity extends BaseActivity
}
};
- Bundle extras = getIntent().getExtras();
+ selectLocationButton = findViewById(R.id.select_location_button);
+ removeLocationButton = findViewById(R.id.remove_location_button);
Mapbox.getInstance(this, getString(R.string.access_token));
mapView = findViewById(R.id.mapView);
mapView.onCreate(savedInstanceState);
@@ -130,7 +124,6 @@ public class MapActivity extends BaseActivity
handleBackgroundTaskLifeCycle();
}
-
@Override
public void onMapReady(MapboxMap mapboxMap) {
MapActivity.this.mapboxMap = mapboxMap;
@@ -138,13 +131,36 @@ public class MapActivity extends BaseActivity
enableLocationPlugin();
mapboxMap.setOnMarkerClickListener(marker -> {
- createMarkerModal(marker.getTitle());
+ String id = marker.getTitle();
+ if (id.equals(myID)) {
+ selectLocationButton.setVisibility(View.GONE);
+ removeLocationButton.setVisibility(View.VISIBLE);
+
+ removeLocationButton.setOnClickListener(view -> {
+ Log.e(tag + "Manual", "manual coords sending stopped");
+ // TODO to remove after BGserv
+ manualLocHandler.removeCallbacks(manualLocStatusChecker);
+
+ removeLocationButton.setVisibility(View.GONE);
+ Toast.makeText(MapActivity.this, "Your marker will disappear in next couple minutes", Toast.LENGTH_SHORT).show();
+
+ });
+ } else {
+ createMarkerModal(id);
+ }
+
return true;
});
+ setToggleMapBoundsArea();
setOnMapLongClickListener();
-// addStaticLayer();
+ }
+
+ private void setToggleMapBoundsArea() {
+
+ mapUtils.setMapBoundsArea(getApplicationContext(), mapboxMap, mapView, true);
+
}
private void createMarkerModal(String userId) {
@@ -183,14 +199,13 @@ public class MapActivity extends BaseActivity
showError(error);
}
-
private void showError(Throwable e) {
String message;
if (e instanceof HttpException) {
ResponseBody responseBody = ((HttpException) e).response().errorBody();
message = RestApiHelper.getErrorMessage(responseBody);
- }else {
+ } else {
message = "Network Error!";
}
@@ -198,147 +213,104 @@ public class MapActivity extends BaseActivity
Toast.makeText(MapActivity.this, message, Toast.LENGTH_SHORT).show();
}
- private void setOnMapLongClickListener() {
- final boolean[] cancel = {false};
- Button selectLocationButton = findViewById(R.id.select_location_button);
+ private void setOnMapLongClickListener() {
mapboxMap.addOnMapLongClickListener((LatLng latLng) -> {
selectLocationButton.setVisibility(View.VISIBLE);
+ removeLocationButton.setVisibility(View.GONE);
Icon icon = IconFactory.getInstance(MapActivity.this).fromResource(R.drawable.green_marker);
+ if (tmpLocalMarker == null) {
- if (droppedMarker == null) {
-
- droppedMarker = mapboxMap.addMarker(new MarkerOptions()
+ tmpLocalMarker = mapboxMap.addMarker(new MarkerOptions()
.position(latLng)
.icon(icon)
.title("My Loc")
.setSnippet("Snipecik"));
- } else if (!cancel[0]) {
- ValueAnimator markerAnimator = ObjectAnimator.ofObject(droppedMarker, "position",
- new mapUtils.LatLngEvaluator(), droppedMarker.getPosition(), latLng);
+ } else {
+ ValueAnimator markerAnimator = ObjectAnimator.ofObject(tmpLocalMarker, "position",
+ new mapUtils.LatLngEvaluator(), tmpLocalMarker.getPosition(), latLng);
markerAnimator.setDuration(2000);
markerAnimator.start();
}
selectLocationButton.setOnClickListener((View view) -> {
-
- if (!cancel[0] && droppedMarker != null) {
+ if (tmpLocalMarker != null) {
// Toast instructing user to tap on the mapboxMap
-
-
// TODO PUT MANUAL CORD
try {
- Coordinate coordinate = new Coordinate(
+ droppedMarkercoordinate = new Coordinate(
latLng.getLatitude(),
latLng.getLongitude(),
latLng.getAltitude(),
+ "approx",
PrefUtils.getUserFirstName(getApplicationContext()) + " " + PrefUtils.getUserLastName(getApplicationContext()),
PrefUtils.getUserId(getApplicationContext()),
PrefUtils.getLocationLevel(getApplicationContext())
);
- disposable.add(
- coordinateService
- .postCoordinate(coordinate)
- .subscribeOn(Schedulers.io())
- .observeOn(AndroidSchedulers.mainThread())
- .subscribeWith(new DisposableSingleObserver() {
- @SuppressLint("LongLogTag")
- @Override
- public void onSuccess(Coordinate coord) {
- Log.e(tag + "POST", String.valueOf(coord));
- }
+ // TODO remove after BG sending
+ manualLocStatusChecker = () -> {
+ try {
+ Log.e(tag + "Manual", "sending manual coords");
+ // TODO ^^^ wrapper to removve
+ disposable.add(
+ coordinateService
+ .postCoordinate(droppedMarkercoordinate)
+ .subscribeOn(Schedulers.io())
+ .observeOn(AndroidSchedulers.mainThread())
+ .subscribeWith(new DisposableSingleObserver() {
+ @SuppressLint("LongLogTag")
+ @Override
+ public void onSuccess(Coordinate coord) {
+ Log.e(tag + "POST", String.valueOf(coord));
+ }
- @SuppressLint("LongLogTag")
- @Override
- public void onError(Throwable e) {
+ @SuppressLint("LongLogTag")
+ @Override
+ public void onError(Throwable e) {
- Log.e(tag + "onError", e.getMessage());
+ Log.e(tag + "onError", e.getMessage());
+
+ if (e instanceof HttpException) {
+ ResponseBody responseBody = ((HttpException) e).response().errorBody();
+ Log.e(tag + "onError", RestApiHelper.getErrorMessage(responseBody));
+
+ }
+ }
+ }));
+ // TODO \/\/\/\/\/ wrapper to removve
+ } finally {
+ manualLocHandler.postDelayed(manualLocStatusChecker, mInterval);
+ }
+ };
+ manualLocStatusChecker.run();
- if (e instanceof HttpException) {
- ResponseBody responseBody = ((HttpException) e).response().errorBody();
- Log.e(tag + "onError", RestApiHelper.getErrorMessage(responseBody));
- }
- }
- }));
} catch (IllegalArgumentException e) {
Timber.e(String.valueOf(e));
}
-
Toast.makeText(
MapActivity.this,
"Manual Locations selected!" + latLng,
Toast.LENGTH_LONG
).show();
- selectLocationButton.setBackgroundColor(
- ContextCompat.getColor(MapActivity.this, R.color.colorAccent));
- selectLocationButton.setText("Remove Manual location");
- selectLocationButton.setVisibility(View.VISIBLE);
- cancel[0] = true;
- } else {
-
- // TODO REMOVE Manual Locatio
- mapboxMap.removeMarker(droppedMarker);
- droppedMarker = null;
-
- Toast.makeText(
- MapActivity.this,
- "REMOVED!!" + latLng,
- Toast.LENGTH_LONG
- ).show();
-
- cancel[0] = false;
selectLocationButton.setVisibility(View.GONE);
- selectLocationButton.setText(R.string.select_a_location);
- selectLocationButton.setBackgroundColor(
- ContextCompat.getColor(MapActivity.this, R.color.colorPrimary));
+ mapboxMap.removeMarker(tmpLocalMarker);
+ tmpLocalMarker = null;
}
});
});
}
- private void addStaticLayer() {
- // Toggle layer button
- final FloatingActionButton button = findViewById(R.id.toggleMarkerLayerButton);
- button.setVisibility(View.VISIBLE);
-
- button.setOnClickListener(view -> {
-
- Layer layer = mapboxMap.getLayer("museums");
- if (layer != null) {
- if (VISIBLE.equals(layer.getVisibility().getValue())) {
- layer.setProperties(visibility(NONE));
- } else {
- layer.setProperties(visibility(VISIBLE));
- }
- }
- });
-
- // TODO here we create static layer, we are able to hide/show (but we cannot put markers inthere)
- VectorSource museums = new VectorSource("museums_source", "mapbox://mapbox.2opop9hr");
- mapboxMap.addSource(museums);
-
- CircleLayer museumsLayer = new CircleLayer("museums", "museums_source");
- museumsLayer.setSourceLayer("museum-cusco");
- museumsLayer.setProperties(
- visibility(VISIBLE),
- circleRadius(8f),
- circleColor(Color.argb(255, 55, 148, 179))
- );
- mapboxMap.addLayer(museumsLayer);
- }
-
private void fetchTopCoords() {
disposable.add(
- // coordinateService.getTopCoordinates()
coordinateService.getOnlineCoordinates()
.subscribeOn(Schedulers.io())
.observeOn(AndroidSchedulers.mainThread())
@@ -347,39 +319,37 @@ public class MapActivity extends BaseActivity
@Override
public void onSuccess(List coordsList) {
- if(coordsList.isEmpty()) {
- Log.e(tag, "200 empty []");
+
+ if (coordsList.isEmpty() && tmpLocalMarker != null) {
+ Timber.e("200 empty []");
mapboxMap.clear();
return;
}
-
ArrayList tmp = new ArrayList<>();
for (Coordinate coordinate : coordsList) {
tmp.add(coordinate.getUserId());
}
Set currentCoordsIds = new HashSet<>(tmp);
- if (previousCoordsIds.isEmpty()){
+ if (previousCoordsIds.isEmpty()) {
previousCoordsIds.addAll(currentCoordsIds);
} else {
- // here we clear + it returns bool if smthing was removed
+ // here we clear + it returns bool if sth was removed
if (previousCoordsIds.removeAll(currentCoordsIds)) {
- for (String toRemoveId: previousCoordsIds) {
- Log.e(tag+ "delete: " , "removing: " + toRemoveId + ": " + markerHash.get(toRemoveId));
+ for (String toRemoveId : previousCoordsIds) {
+ Log.e(tag + "delete: ", "removing: " + toRemoveId + ": " + markerHash.get(toRemoveId));
mapboxMap.removeMarker(markerHash.get(toRemoveId));
markerHash.remove(toRemoveId);
coordsMap.remove(toRemoveId);
}
} else {
// TODO double check when some markers api will change
- Log.e(tag+ "delete: ","nothing to remove");
+ Log.e(tag + "delete: ", "nothing to remove");
}
}
-
-
for (Coordinate element : coordsList) {
String id = element.getUserId();
String newLabel = element.getLabel();
@@ -390,9 +360,6 @@ public class MapActivity extends BaseActivity
if (coordinate != null) {
Log.e(tag, "Coordin: " + coordinate.getLatitude() + " | " + coordinate.getLongitude());
-// Log.e(tag, "Element: " + element.getLatitude()+" | " + element.getLongitude());
-// Log.e(tag, "isEqual: " + coordinate.getLatitude().equals(element.getLatitude()));
-// Log.e(tag, "isEqual: " + coordinate.getLongitude().equals(element.getLongitude()));
boolean statement = coordinate.getLatitude().equals(element.getLatitude()) || coordinate.getLongitude().equals(element.getLongitude());
Log.e(tag, "diff || diff: " + !statement);
@@ -418,13 +385,20 @@ public class MapActivity extends BaseActivity
}
} else {
-
Log.e(tag, "Marker Added: " + id);
coordsMap.put(id, element);
- Marker marker = mapboxMap.addMarker(new MarkerOptions()
+
+ MarkerOptions markerOptions = new MarkerOptions()
.title(id)
- .position(new LatLng(element.getLatitude(), element.getLongitude())));
+ .position(new LatLng(element.getLatitude(), element.getLongitude()));
+ // Check if this is me
+ if (id.equals(myID)) {
+ Icon icon = IconFactory.getInstance(MapActivity.this).fromResource(R.drawable.blue_marker);
+ markerOptions.setIcon(icon);
+ }
+ Marker marker = mapboxMap.addMarker(markerOptions);
+
markerHash.put(id, marker);
}
@@ -453,6 +427,67 @@ public class MapActivity extends BaseActivity
}
+ @SuppressWarnings({"MissingPermission"})
+ private void enableLocationPlugin() {
+ Log.e(tag, "enableLocationPlugin");
+
+ // Check if permissions are enabled and if not request
+ if (PermissionsManager.areLocationPermissionsGranted(this)) {
+ Log.e(tag, "enableLocationPlugin true");
+
+
+ LocationComponentOptions options = LocationComponentOptions.builder(this)
+ .trackingGesturesManagement(false)
+ .accuracyColor(ContextCompat.getColor(this, R.color.mapboxGray))
+ .build();
+
+ // Get an instance of the component
+ locationComponent = mapboxMap.getLocationComponent();
+
+ Log.e(tag + "Last", locationComponent.getLastKnownLocation() + "");
+
+ // Activate with options
+ locationComponent.activateLocationComponent(this, options);
+
+ // Enable to make component visible + camera animation
+ // https://www.mapbox.com/android-docs/maps/overview/location-component/
+ locationComponent.setLocationComponentEnabled(true);
+
+ // Set the component's camera mode
+ locationComponent.setCameraMode(CameraMode.NONE);
+ locationComponent.setRenderMode(RenderMode.COMPASS);
+
+ // Button 4 centring
+ FloatingActionButton myLocFAB = findViewById(R.id.myLocationButton);
+ myLocFAB.setVisibility(View.VISIBLE);
+ myLocFAB.setOnClickListener(v -> {
+
+ Location lastKnownLocation = locationComponent.getLastKnownLocation();
+ if (lastKnownLocation != null) {
+ mapUtils.makeNewCamera(mapboxMap,
+ lastKnownLocation.getLatitude(),
+ lastKnownLocation.getLongitude(),
+ zoomParam,
+ bearingParam,
+ tiltParam,
+ 4000);
+ }
+
+ // Camera aniamtion
+ zoomParam = (zoomParam == 17) ? 19 : 17;
+ bearingParam += 90;
+ tiltParam = (tiltParam == 30) ? 0 : 30;
+ });
+ } else {
+ Log.e(tag, "enableLocationPlugin false");
+
+ permissionsManager = new PermissionsManager(this);
+ permissionsManager.requestLocationPermissions(this);
+ permissionsManager.onRequestPermissionsResult(0, new String[]{Manifest.permission.ACCESS_FINE_LOCATION}, new int[]{0});
+
+ }
+ }
+
// Add the mapView lifecycle to the activity's lifecycle methods
@Override
public void onResume() {
@@ -489,6 +524,8 @@ public class MapActivity extends BaseActivity
super.onDestroy();
mapView.onDestroy();
mHandler.removeCallbacks(mStatusChecker);
+ // TODO remove after BG sending
+ manualLocHandler.removeCallbacks(manualLocStatusChecker);
disposable.dispose();
}
@@ -508,69 +545,6 @@ public class MapActivity extends BaseActivity
return R.id.nav_map;
}
- @SuppressWarnings({"MissingPermission"})
- private void enableLocationPlugin() {
- Log.e(tag, "enableLocationPlugin");
-
- // Check if permissions are enabled and if not request
- if (PermissionsManager.areLocationPermissionsGranted(this)) {
- Log.e(tag, "enableLocationPlugin true");
-
- FloatingActionButton myLocationButton = findViewById(R.id.myLocationButton);
- myLocationButton.setVisibility(View.VISIBLE);
-
- LocationComponentOptions options = LocationComponentOptions.builder(this)
- .trackingGesturesManagement(true)
- .accuracyColor(ContextCompat.getColor(this, R.color.mapboxGray))
- .build();
-
- // Get an instance of the component
- locationComponent = mapboxMap.getLocationComponent();
-
- //Log.e(tag + "Last", locationComponent.getLastKnownLocation() + "");
-
- // Activate with options
- locationComponent.activateLocationComponent(this, options);
- // Enable to make component visible
- locationComponent.setLocationComponentEnabled(true);
-
- // Set the component's camera mode
- locationComponent.setCameraMode(CameraMode.TRACKING);
- locationComponent.setRenderMode(RenderMode.COMPASS);
-
- // Button 4 centring
- FloatingActionButton myLocFAB = findViewById(R.id.myLocationButton);
- myLocFAB.setOnClickListener(v -> {
-
- Location lastKnownLocation = locationComponent.getLastKnownLocation();
- if (lastKnownLocation != null) {
-
- CameraPosition position = new CameraPosition.Builder()
- .target(new LatLng(lastKnownLocation.getLatitude(), lastKnownLocation.getLongitude())) // Sets the new camera position
- .zoom(zoomParam) // Sets the zoom
- .bearing(bearingParam) // Rotate the camera
- .tilt(tiltParam) // Set the camera tilt
- .build(); // Creates a CameraPosition from the builder
-
- mapboxMap.animateCamera(CameraUpdateFactory
- .newCameraPosition(position), 4000);
- }
-
- // Camera aniamtion
- zoomParam = (zoomParam == 17) ? 19 : 17;
- bearingParam += 90;
- tiltParam = (tiltParam == 30) ? 0 : 30;
- });
- } else {
- Log.e(tag, "enableLocationPlugin false");
-
- permissionsManager = new PermissionsManager(this);
- permissionsManager.requestLocationPermissions(this);
- permissionsManager.onRequestPermissionsResult(0, new String[]{Manifest.permission.ACCESS_FINE_LOCATION}, new int[]{0});
-
- }
- }
-
@Override
public void onRequestPermissionsResult(int requestCode, @android.support.annotation.NonNull String[] permissions, @android.support.annotation.NonNull int[] grantResults) {
super.onRequestPermissionsResult(requestCode, permissions, grantResults);
@@ -591,4 +565,53 @@ public class MapActivity extends BaseActivity
// finish();
// }
}
+
+
+ @Override
+ public void searchUser(String textToSearch) {
+ getUserFromApi(textToSearch);
+ }
+
+ private void getUserFromApi(String userNameToSearch) {
+ disposable.add(
+ userService.getAllTutors()
+ .subscribeOn(Schedulers.io())
+ .observeOn(AndroidSchedulers.mainThread())
+ .map(tutors -> Stream.of(tutors).filter(t ->
+ t.toSearchAbleUserName().toLowerCase().contains(userNameToSearch.toLowerCase())).toList())
+ .subscribeWith(new DisposableSingleObserver>() {
+ @Override
+ public void onSuccess(List users) {
+ filterMarkers(users);
+ }
+
+ @Override
+ public void onError(Throwable e) {
+ showError(e);
+ }
+ }));
+ }
+
+ private void filterMarkers(List users) {
+ restoreMapMarkers();
+
+ Icon icon1 = IconFactory.getInstance(MapActivity.this).fromResource(R.drawable.custom_marker);
+
+ List markersToSet = Stream.of(mapboxMap.getMarkers())
+ .filter(m -> Stream.of(users).anyMatch(u -> u.getId().equals(m.getTitle())))
+ .toList();
+
+ for (Marker marker : markersToSet) {
+ marker.setIcon(icon1);
+ }
+ }
+
+ public void restoreMapMarkers() {
+ Icon icon = IconFactory.getInstance(MapActivity.this).fromResource(R.drawable.red_marker);
+
+ for (Marker marker : mapboxMap.getMarkers()) {
+ marker.setIcon(icon);
+ }
+ }
+
}
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 839f673..e08ad48 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
@@ -2,6 +2,7 @@ package com.uam.wmi.findmytutor.activity;
import android.annotation.SuppressLint;
import android.app.Activity;
+import android.app.FragmentTransaction;
import android.content.Context;
import android.content.Intent;
import android.content.SharedPreferences;
@@ -9,17 +10,28 @@ import android.os.Build;
import android.os.Bundle;
import android.preference.ListPreference;
import android.preference.Preference;
+import android.preference.PreferenceCategory;
import android.preference.PreferenceFragment;
import android.util.Log;
import android.view.LayoutInflater;
import android.view.View;
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 com.uam.wmi.findmytutor.utils.SharingLevel;
+
import java.util.Arrays;
import java.util.HashMap;
import java.util.HashSet;
@@ -28,55 +40,145 @@ 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);
- locationLevelMapping = new HashMap();
- locationLevelMapping.put(0,"presence");
- locationLevelMapping.put(1,"approximated");
- locationLevelMapping.put(2,"exact");
-
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");
+
+ 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, SharingLevel.PRESENCE.toString());
+ locationLevelMapping.put(1, SharingLevel.APPROXIMATED.toString());
+ locationLevelMapping.put(2, SharingLevel.EXACT.toString());
+ locationLevelMapping.put(3, SharingLevel.MANUAL.toString());
- 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)));
+ if(PrefUtils.getLocationLevel(getApplicationContext()) == "manual"){
+ preferenceCategory.addPreference(manualLocationList);
+ preferenceCategory.addPreference(manualLocationButton);
+
+ }else{
+ preferenceCategory.removePreference(manualLocationList);
+ preferenceCategory.removePreference(manualLocationButton);
+ }
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));
+
return true;
});
- locationSharing.setOnPreferenceChangeListener((buttonView, newValue) -> {
- PrefUtils.storeEnableSharingLocalization(getApplicationContext(), (Boolean) newValue);
- ((MapActivity)getActivity()).handleBackgroundTaskLifeCycle();
- return true;
- });
}
public static SharingFragment newInstance() {
@@ -105,8 +207,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);
@@ -114,6 +217,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];
@@ -125,4 +229,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/activity/UsersListFragment.java b/app/src/main/java/com/uam/wmi/findmytutor/activity/UsersListFragment.java
index 82888b2..433ed70 100644
--- a/app/src/main/java/com/uam/wmi/findmytutor/activity/UsersListFragment.java
+++ b/app/src/main/java/com/uam/wmi/findmytutor/activity/UsersListFragment.java
@@ -169,7 +169,7 @@ public class UsersListFragment extends Fragment {
private void fetchAllTutors() {
disposable.add(
- userService.apiUsersGet()
+ userService.getAllTutors()
.subscribeOn(Schedulers.io())
.observeOn(AndroidSchedulers.mainThread())
.map(tutors -> {
diff --git a/app/src/main/java/com/uam/wmi/findmytutor/model/Coordinate.java b/app/src/main/java/com/uam/wmi/findmytutor/model/Coordinate.java
index 5c23701..9b9d580 100644
--- a/app/src/main/java/com/uam/wmi/findmytutor/model/Coordinate.java
+++ b/app/src/main/java/com/uam/wmi/findmytutor/model/Coordinate.java
@@ -44,15 +44,17 @@ public class Coordinate extends BaseResponse {
@SerializedName("label")
private String label;
- public Coordinate (Double latitude, Double longitude, Double altitude, String label, String userId, String displayMode) {
+ public Coordinate (Double latitude, Double longitude, Double altitude, String approximatedLocation, String label, String userId, String displayMode) {
//if (!latitudeRange.contains(latitude)) throw new IllegalArgumentException("Inappropriate latitude value" + latitude);
//if (!longtitudeRange.contains(longitude)) throw new IllegalArgumentException("Inappropriate longitude value" + longitude);
+ //if (approximatedLocation == null) throw new IllegalArgumentException("Inappropriate approximatedLocation");
this.latitude = latitude;
this.longitude = longitude;
this.altitude = altitude;
this.label = label;
this.userId = userId;
+ this.approximatedLocation = approximatedLocation;
this.displayMode = displayMode;
}
diff --git a/app/src/main/java/com/uam/wmi/findmytutor/model/Feedback.java b/app/src/main/java/com/uam/wmi/findmytutor/model/Feedback.java
new file mode 100644
index 0000000..1726c75
--- /dev/null
+++ b/app/src/main/java/com/uam/wmi/findmytutor/model/Feedback.java
@@ -0,0 +1,47 @@
+
+package com.uam.wmi.findmytutor.model;
+import com.google.gson.annotations.Expose;
+import com.google.gson.annotations.SerializedName;
+
+public class Feedback {
+
+ @SerializedName("isAnonymous")
+ @Expose
+ private Boolean isAnonymous;
+ @SerializedName("header")
+ @Expose
+ private String header;
+ @SerializedName("body")
+ @Expose
+ private String body;
+
+ public Feedback(boolean isAnonymous, String header, String body){
+ this.isAnonymous = isAnonymous;
+ this.header = header;
+ this.body = body;
+ }
+ public Boolean getIsAnonymous() {
+ return isAnonymous;
+ }
+
+ public void setIsAnonymous(Boolean isAnonymous) {
+ this.isAnonymous = isAnonymous;
+ }
+
+ public String getHeader() {
+ return header;
+ }
+
+ public void setHeader(String header) {
+ this.header = header;
+ }
+
+ public String getBody() {
+ return body;
+ }
+
+ public void setBody(String body) {
+ this.body = body;
+ }
+
+}
\ No newline at end of file
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/model/User.java b/app/src/main/java/com/uam/wmi/findmytutor/model/User.java
index 0e5c0d5..7788f61 100644
--- a/app/src/main/java/com/uam/wmi/findmytutor/model/User.java
+++ b/app/src/main/java/com/uam/wmi/findmytutor/model/User.java
@@ -712,6 +712,15 @@ public class User extends BaseResponse {
return sb.toString();
}
+ public String toSearchAbleUserName(){
+ StringBuilder sb = new StringBuilder();
+ sb.append(getFirstName());
+ sb.append(getLastName());
+
+ return sb.toString();
+ }
+
+
@Override
public String toString() {
StringBuilder sb = new StringBuilder();
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..b257bfd 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
@@ -27,14 +27,18 @@ import com.google.android.gms.location.FusedLocationProviderClient;
import com.google.android.gms.location.LocationServices;
import com.google.android.gms.tasks.OnSuccessListener;
import com.jakewharton.retrofit2.adapter.rxjava2.HttpException;
+import com.mapbox.geojson.Point;
import com.uam.wmi.findmytutor.model.Coordinate;
import com.uam.wmi.findmytutor.network.ApiClient;
+import com.uam.wmi.findmytutor.utils.ApproximatedLocalization;
+import com.uam.wmi.findmytutor.utils.Consts;
import com.uam.wmi.findmytutor.utils.PrefUtils;
import com.uam.wmi.findmytutor.utils.RestApiHelper;
+import com.uam.wmi.findmytutor.utils.SharingLevel;
+import com.uam.wmi.findmytutor.utils.mapUtils;
import java.util.ArrayList;
import java.util.List;
-import java.util.concurrent.Executor;
import io.reactivex.android.schedulers.AndroidSchedulers;
import io.reactivex.disposables.CompositeDisposable;
@@ -43,6 +47,9 @@ import io.reactivex.schedulers.Schedulers;
import okhttp3.ResponseBody;
import timber.log.Timber;
+import static com.uam.wmi.findmytutor.utils.Consts.presenceApproximatedName;
+import static com.uam.wmi.findmytutor.utils.Consts.presenceLatitude;
+import static com.uam.wmi.findmytutor.utils.Consts.presencelongitude;
import static com.uam.wmi.findmytutor.utils.PrefUtils.storeBackgroundLocationStatus;
public class BackgroundLocalizationService extends Service {
@@ -50,7 +57,6 @@ public class BackgroundLocalizationService extends Service {
private static final String TAG = "MyLocationService";
private static final int LOCATION_INTERVAL = 1000;
private static final float LOCATION_DISTANCE = 5f;
- public static String str_receiver = "background.location.broadcast";
private static long notify_interval = 10000;
Location mLastLocation;
Boolean stopService = false;
@@ -64,6 +70,7 @@ public class BackgroundLocalizationService extends Service {
private Runnable mStatusChecker;
private FusedLocationProviderClient mFusedLocationClient;
+
public BackgroundLocalizationService() {
providers.add(LocationManager.GPS_PROVIDER);
providers.add(LocationManager.NETWORK_PROVIDER);
@@ -74,6 +81,7 @@ public class BackgroundLocalizationService extends Service {
new LocationListener(LocationManager.NETWORK_PROVIDER),
new LocationListener(LocationManager.PASSIVE_PROVIDER)
};
+
}
@Override
@@ -90,7 +98,7 @@ public class BackgroundLocalizationService extends Service {
stopService = intent.getBooleanExtra("request_stop", false);
}
if (stopService) {
- storeBackgroundLocationStatus(getApplication(),false);
+ storeBackgroundLocationStatus(getApplication(), false);
stopForeground(true);
stopSelf();
return START_STICKY;
@@ -102,7 +110,7 @@ public class BackgroundLocalizationService extends Service {
@Override
public void onCreate() {
Log.e(TAG, "onCreate");
- storeBackgroundLocationStatus(getApplication(),true);
+ storeBackgroundLocationStatus(getApplication(), true);
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O)
startMyOwnForeground();
@@ -114,7 +122,6 @@ public class BackgroundLocalizationService extends Service {
mFusedLocationClient = LocationServices.getFusedLocationProviderClient(this);
-
initializeLocationManager();
Integer providerIndex = 0;
@@ -137,7 +144,7 @@ public class BackgroundLocalizationService extends Service {
providerIndex++;
}
- if(!stopService){
+ if (!stopService) {
mStatusChecker = () -> {
try {
fn_getlocation();
@@ -202,20 +209,12 @@ public class BackgroundLocalizationService extends Service {
Log.e("Best localization:", String.valueOf(bestLocation));
- /* if (bestLocation != null)
- fn_update(bestLocation);
-*/
-
mFusedLocationClient.getLastLocation().addOnSuccessListener(
- new OnSuccessListener() {
- @Override
- public void onSuccess(Location location) {
- if (location != null) {
- mLastLocation = location;
- fn_update(location);
- }
+ location -> {
+ if (location != null) {
+ mLastLocation = location;
+ fn_update(location);
}
-
});
}
@@ -283,11 +282,13 @@ public class BackgroundLocalizationService extends Service {
}
}
+ @SuppressLint("StaticFieldLeak")
private class Task extends AsyncTask {
+ ApproximatedLocalization approximatedLocalization;
private Double latitude;
private Double longitude;
private Double altitude;
-
+ private String approximatedBuildingPart = null;
private CompositeDisposable disposable = new CompositeDisposable();
private CoordinateService coordinateService = ApiClient.getClient(getApplicationContext())
.create(CoordinateService.class);
@@ -296,17 +297,31 @@ public class BackgroundLocalizationService extends Service {
latitude = location.getLatitude();
longitude = location.getLongitude();
altitude = location.getAltitude();
+ approximatedLocalization = new ApproximatedLocalization(mapUtils.loadJsonFromAsset(getApplicationContext(), "building.geojson"));
+ approximatedBuildingPart = approximatedLocalization.getNameOfBuildingPart(Point.fromLngLat(longitude, latitude));
}
@Override
protected Object doInBackground(Object[] objects) {
+ if (PrefUtils.getLocationLevel(getApplicationContext()).equals(SharingLevel.PRESENCE.toString())) {
+ latitude = presenceLatitude;
+ longitude = presencelongitude;
+ approximatedBuildingPart = presenceApproximatedName;
+ } else if (PrefUtils.getLocationLevel(getApplicationContext()).equals(SharingLevel.APPROXIMATED.toString())) {
+ List points = approximatedLocalization.getMiddlePointOfBuildingPart(approximatedBuildingPart);
+
+ latitude = points.get(0);
+ longitude = points.get(1);
+ }
+
try {
Coordinate coordinate = new Coordinate(
latitude,
longitude,
altitude,
- PrefUtils.getUserStatus(getApplicationContext()),
+ approximatedBuildingPart,
+ (PrefUtils.isStatusEnabled(getApplicationContext())) ? PrefUtils.getUserStatus(getApplicationContext()) : "",
PrefUtils.getUserId(getApplicationContext()),
PrefUtils.getLocationLevel(getApplicationContext())
);
diff --git a/app/src/main/java/com/uam/wmi/findmytutor/service/FeedbackService.java b/app/src/main/java/com/uam/wmi/findmytutor/service/FeedbackService.java
new file mode 100644
index 0000000..a6d166c
--- /dev/null
+++ b/app/src/main/java/com/uam/wmi/findmytutor/service/FeedbackService.java
@@ -0,0 +1,17 @@
+package com.uam.wmi.findmytutor.service;
+
+import com.uam.wmi.findmytutor.model.Feedback;
+import io.reactivex.Observable;
+import io.reactivex.Single;
+import retrofit2.Response;
+import retrofit2.http.Body;
+import retrofit2.http.GET;
+import retrofit2.http.POST;
+
+public interface FeedbackService {
+ @POST("api/Feedback")
+ Observable> postFeedback(@Body Feedback feedback);
+
+ @GET("api/Feedback")
+ Single getFeedback();
+}
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/service/UserService.java b/app/src/main/java/com/uam/wmi/findmytutor/service/UserService.java
index aca16a4..75671ed 100644
--- a/app/src/main/java/com/uam/wmi/findmytutor/service/UserService.java
+++ b/app/src/main/java/com/uam/wmi/findmytutor/service/UserService.java
@@ -27,6 +27,9 @@ public interface UserService {
@GET("api/users")
Single > apiUsersGet();
+ @GET("api/users/tutors")
+ Single > getAllTutors();
+
@POST("api/users")
Completable createUser(@Body User user);
diff --git a/app/src/main/java/com/uam/wmi/findmytutor/utils/ApproximatedLocalization.java b/app/src/main/java/com/uam/wmi/findmytutor/utils/ApproximatedLocalization.java
new file mode 100644
index 0000000..4a42bf3
--- /dev/null
+++ b/app/src/main/java/com/uam/wmi/findmytutor/utils/ApproximatedLocalization.java
@@ -0,0 +1,69 @@
+package com.uam.wmi.findmytutor.utils;
+
+import android.support.annotation.NonNull;
+
+import com.google.gson.GsonBuilder;
+import com.mapbox.geojson.BoundingBox;
+import com.mapbox.geojson.Feature;
+import com.mapbox.geojson.FeatureCollection;
+import com.mapbox.geojson.Geometry;
+import com.mapbox.geojson.Point;
+import com.mapbox.geojson.Polygon;
+import com.mapbox.geojson.gson.BoundingBoxDeserializer;
+import com.mapbox.geojson.gson.GeoJsonAdapterFactory;
+import com.mapbox.geojson.gson.GeometryDeserializer;
+import com.mapbox.geojson.gson.PointDeserializer;
+import com.mapbox.turf.TurfJoins;
+
+import java.util.Arrays;
+import java.util.List;
+import java.util.Objects;
+
+;
+
+public class ApproximatedLocalization {
+ private FeatureCollection buildingSchema = null;
+
+ public ApproximatedLocalization(String buildingObject) {
+ buildingSchema = fromJson(buildingObject);
+ }
+
+ private FeatureCollection fromJson(@NonNull String json) {
+ GsonBuilder gson = new GsonBuilder();
+
+ gson.registerTypeAdapterFactory(GeoJsonAdapterFactory.create());
+ gson.registerTypeAdapter(Point.class, new PointDeserializer());
+ gson.registerTypeAdapter(Geometry.class, new GeometryDeserializer());
+ gson.registerTypeAdapter(BoundingBox.class, new BoundingBoxDeserializer());
+
+ return gson.create().fromJson(json, FeatureCollection.class);
+ }
+
+ public String getNameOfBuildingPart(Point point) {
+
+ for (Feature feature : Objects.requireNonNull(buildingSchema.features())) {
+ boolean isInside = TurfJoins.inside(point, (Polygon) Objects.requireNonNull(feature.geometry()));
+
+ if (isInside)
+ return Objects.requireNonNull(Objects.requireNonNull(feature.getStringProperty("name")));
+ }
+
+ return null;
+ }
+
+ public List getMiddlePointOfBuildingPart(String buildingPart) {
+
+ for (Feature feature : Objects.requireNonNull(buildingSchema.features())) {
+ String partName = feature.getStringProperty("name");
+
+ if (buildingPart != null && buildingPart.equals(partName)) {
+ Double longitude = feature.getNumberProperty("longitude").doubleValue();
+ Double latitude = feature.getNumberProperty("latitude").doubleValue();
+
+ return Arrays.asList(longitude, latitude);
+ }
+ }
+
+ return Arrays.asList(0.0, 0.0);
+ }
+}
diff --git a/app/src/main/java/com/uam/wmi/findmytutor/utils/Consts.java b/app/src/main/java/com/uam/wmi/findmytutor/utils/Consts.java
new file mode 100644
index 0000000..bedd885
--- /dev/null
+++ b/app/src/main/java/com/uam/wmi/findmytutor/utils/Consts.java
@@ -0,0 +1,7 @@
+package com.uam.wmi.findmytutor.utils;
+
+public class Consts {
+ public final static Double presenceLatitude = 65.600244;
+ public final static Double presencelongitude = 480.032153;
+ public final static String presenceApproximatedName = "unknown";
+}
diff --git a/app/src/main/java/com/uam/wmi/findmytutor/utils/FeedbackUtils.java b/app/src/main/java/com/uam/wmi/findmytutor/utils/FeedbackUtils.java
new file mode 100644
index 0000000..ab12f54
--- /dev/null
+++ b/app/src/main/java/com/uam/wmi/findmytutor/utils/FeedbackUtils.java
@@ -0,0 +1,121 @@
+package com.uam.wmi.findmytutor.utils;
+
+import android.content.Context;
+import android.content.DialogInterface;
+import android.content.pm.PackageManager;
+import android.os.Build;
+import android.support.v7.app.AlertDialog;
+import android.text.TextUtils;
+import android.util.Log;
+import android.view.LayoutInflater;
+import android.view.View;
+import android.widget.Button;
+import android.widget.CheckBox;
+import android.widget.EditText;
+import android.widget.TextView;
+import android.widget.Toast;
+
+import com.jakewharton.retrofit2.adapter.rxjava2.HttpException;
+import com.uam.wmi.findmytutor.R;
+import com.uam.wmi.findmytutor.activity.BaseActivity;
+import com.uam.wmi.findmytutor.model.Feedback;
+import com.uam.wmi.findmytutor.network.ApiClient;
+import com.uam.wmi.findmytutor.service.FeedbackService;
+
+import io.reactivex.android.schedulers.AndroidSchedulers;
+import io.reactivex.disposables.CompositeDisposable;
+import io.reactivex.schedulers.Schedulers;
+import okhttp3.ResponseBody;
+import retrofit2.Response;
+
+public class FeedbackUtils {
+ private Context activityContext;
+ public FeedbackUtils(Context context){
+ activityContext = context;
+ }
+ public void showNoteDialog(String subject) {
+
+ LayoutInflater layoutInflaterAndroid = LayoutInflater.from(activityContext);
+ View view = layoutInflaterAndroid.inflate(R.layout.feedback_modal, null);
+ AlertDialog.Builder alertDialogBuilderUserInput = new AlertDialog.Builder(activityContext);
+ alertDialogBuilderUserInput.setView(view).setPositiveButton(activityContext.getString(R.string.modal_feedback_send),null);
+ final AlertDialog alertDialog = alertDialogBuilderUserInput.create();
+
+ EditText modalUserInput = view.findViewById(R.id.feedback_input);
+ CheckBox modalIsAnonymous = view.findViewById(R.id.feedback_is_anonymous);
+ TextView modalTitle = view.findViewById(R.id.feedback_modal_title);
+ TextView modalSubtitle = view.findViewById(R.id.feedback_modal_subtitle);
+ modalTitle.setText(subject);
+ if( subject.equals(activityContext.getString(R.string.title_bug_report)) ){
+ modalSubtitle.setText(activityContext.getString(R.string.title_bug_report_notice));
+ } else {
+ modalSubtitle.setText(activityContext.getString(R.string.title_feedback_report_notice));
+ }
+ alertDialog.setOnShowListener(new DialogInterface.OnShowListener() {
+ @Override
+ public void onShow(DialogInterface dialogInterface) {
+ Button sendButton = alertDialog.getButton(AlertDialog.BUTTON_POSITIVE);
+ sendButton.setOnClickListener(new View.OnClickListener() {
+ @Override
+ public void onClick(View view) {
+ String body = modalUserInput.getText().toString();
+ if(TextUtils.isEmpty(body)){
+ Toast.makeText(activityContext, activityContext.getString(R.string.modal_feedback_hint), Toast.LENGTH_SHORT).show();
+ modalUserInput.requestFocus();
+ }else{
+ boolean mode = modalIsAnonymous.isChecked();
+ sendFeedback(subject,body,mode);
+ alertDialog.dismiss();
+ }
+ }
+ });
+ }
+ });
+ alertDialog.show();
+ }
+
+ private void sendFeedback(String header, String body, boolean mode) {
+ String appVersion = null;
+ String metadata = null;
+ try {
+ appVersion = activityContext.getPackageManager().getPackageInfo(activityContext.getPackageName(), 0).versionName;
+ if( !mode ){
+ metadata = "\n-----------------------------\n" +
+ "User ID: " + PrefUtils.getUserId(activityContext) + "\n" +
+ "Device OS: Android\n" +
+ "Device OS version: " + Build.VERSION.RELEASE + "\n" +
+ "App Version: " + appVersion + "\n" +
+ "Device Model: " + Build.MODEL + "\n" +
+ "Device Manufacturer: " + Build.MANUFACTURER + "\n" +
+ "-----------------------------\n";
+ body = metadata + body;
+ header = header + " - " + PrefUtils.getUserFirstName(activityContext) + " " + PrefUtils.getUserLastName(activityContext);
+ }
+ } catch (PackageManager.NameNotFoundException e) {
+ }
+ FeedbackService feedbackService = ApiClient.getClient(activityContext).create(FeedbackService.class);
+ Feedback userFeedback = new Feedback(mode,header,body);
+ CompositeDisposable disposable = new CompositeDisposable();
+ disposable.add(feedbackService.postFeedback(userFeedback)
+ .subscribeOn(Schedulers.io())
+ .observeOn(AndroidSchedulers.mainThread())
+ .subscribe(this::handleResponse, this::handleError));
+ }
+ private void handleResponse(Response resp) {
+ Toast.makeText(activityContext, activityContext.getString(R.string.modal_feedback_thankyou), Toast.LENGTH_SHORT).show();
+ }
+
+ private void handleError(Throwable error) {
+ if (error instanceof HttpException) {
+
+ ResponseBody responseBody = ((HttpException) error).response().errorBody();
+ Toast.makeText(activityContext,
+ RestApiHelper.getErrorMessage(responseBody), Toast.LENGTH_SHORT).show();
+
+ } else {
+ Toast.makeText(activityContext,
+ "Network error " + error.getMessage(), Toast.LENGTH_SHORT).show();
+ Log.d("FEEDBACK",error.getMessage());
+ }
+ }
+}
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..6a8793b 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");
}
@@ -134,7 +138,7 @@ public class PrefUtils {
}
public static String getLocale(Context context) {
- return getSharedPreferences(context).getString("LOCALE", "pl");
+ return getSharedPreferences(context).getString("LOCALE", "en");
}
public static Boolean isBackgroundLocationServiceRunning(Context context) {
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
new file mode 100644
index 0000000..5fdf137
--- /dev/null
+++ b/app/src/main/java/com/uam/wmi/findmytutor/utils/RightButtonPreference.java
@@ -0,0 +1,40 @@
+package com.uam.wmi.findmytutor.utils;
+import android.content.Context;
+import android.preference.Preference;
+import android.util.AttributeSet;
+import android.view.View;
+import android.view.ViewGroup;
+import android.widget.Button;
+import com.uam.wmi.findmytutor.R;
+
+public class RightButtonPreference extends Preference {
+
+ public RightButtonPreference(Context context, AttributeSet attrs) {
+ super(context, attrs);
+ setWidgetLayoutResource(R.layout.preference_button_widget);
+ }
+ @Override
+ protected View onCreateView(ViewGroup parent) {
+ View view = super.onCreateView(parent);
+// LayoutInflater li = (LayoutInflater)getContext().getSystemService( Context.LAYOUT_INFLATER_SERVICE );
+// View temp =li.inflate( R.layout.preference_button_widget, parent, false);
+ return view;
+ }
+ @Override
+ protected void onBindView(View view)
+ {
+ super.onBindView(view);
+ Button button = (Button)view.findViewById(R.id.button_choose_from_map);
+ if(button != null)
+ {
+ button.setOnClickListener(new View.OnClickListener() {
+ @Override
+ public void onClick(View view) {
+ callChangeListener(null);
+ notifyChanged();
+ }
+ });
+ }
+ }
+
+}
diff --git a/app/src/main/java/com/uam/wmi/findmytutor/utils/RxSearchObservable.java b/app/src/main/java/com/uam/wmi/findmytutor/utils/RxSearchObservable.java
new file mode 100644
index 0000000..33d4aee
--- /dev/null
+++ b/app/src/main/java/com/uam/wmi/findmytutor/utils/RxSearchObservable.java
@@ -0,0 +1,39 @@
+package com.uam.wmi.findmytutor.utils;
+
+
+import android.support.v7.widget.SearchView;
+
+import io.reactivex.Observable;
+import io.reactivex.subjects.PublishSubject;
+
+
+public class RxSearchObservable {
+
+ private RxSearchObservable() {
+ // no instance
+ }
+
+ public static Observable fromView(SearchView searchView) {
+
+ final PublishSubject subject = PublishSubject.create();
+
+ searchView.setOnQueryTextListener(new SearchView.OnQueryTextListener() {
+ @Override
+ public boolean onQueryTextSubmit(String s) {
+ subject.onNext(s);
+ return false;
+ }
+
+ @Override
+ public boolean onQueryTextChange(String text) {
+ subject.onNext(text);
+ return false;
+ }
+
+
+ });
+
+
+ return subject;
+ }
+}
diff --git a/app/src/main/java/com/uam/wmi/findmytutor/utils/SharingLevel.java b/app/src/main/java/com/uam/wmi/findmytutor/utils/SharingLevel.java
new file mode 100644
index 0000000..b9b04f2
--- /dev/null
+++ b/app/src/main/java/com/uam/wmi/findmytutor/utils/SharingLevel.java
@@ -0,0 +1,19 @@
+package com.uam.wmi.findmytutor.utils;
+
+public enum SharingLevel {
+ PRESENCE("presence"),
+ APPROXIMATED("approximated"),
+ EXACT("exact"),
+ MANUAL("manual");
+
+ private final String text;
+
+ SharingLevel(final String text) {
+ this.text = text;
+ }
+
+ @Override
+ public String toString() {
+ return text;
+ }
+}
\ No newline at end of file
diff --git a/app/src/main/java/com/uam/wmi/findmytutor/utils/mapUtils.java b/app/src/main/java/com/uam/wmi/findmytutor/utils/mapUtils.java
index a58ca10..6d80d3e 100644
--- a/app/src/main/java/com/uam/wmi/findmytutor/utils/mapUtils.java
+++ b/app/src/main/java/com/uam/wmi/findmytutor/utils/mapUtils.java
@@ -2,30 +2,61 @@ package com.uam.wmi.findmytutor.utils;
import android.animation.TypeEvaluator;
import android.content.Context;
+import android.graphics.Color;
+import android.view.Gravity;
+import android.view.View;
+import android.widget.FrameLayout;
+import android.content.res.AssetManager;
+import com.mapbox.mapboxsdk.annotations.Polygon;
+import com.mapbox.mapboxsdk.annotations.PolygonOptions;
+import com.mapbox.mapboxsdk.camera.CameraPosition;
+import com.mapbox.mapboxsdk.camera.CameraUpdateFactory;
import com.mapbox.mapboxsdk.geometry.LatLng;
+import com.mapbox.mapboxsdk.geometry.LatLngBounds;
+import com.mapbox.mapboxsdk.maps.MapView;
+import com.mapbox.mapboxsdk.maps.MapboxMap;
+import com.mapbox.mapboxsdk.style.layers.FillLayer;
+import com.mapbox.mapboxsdk.style.layers.Layer;
import java.io.IOException;
import java.io.InputStream;
public class mapUtils {
+ // Boundires
+ private static final LatLngBounds WMI_BOUNDS = new LatLngBounds.Builder()
+ .include(new LatLng(52.46588041661952, 16.92543089389801))
+ .include(new LatLng(52.467824943492374, 16.928574442863464))
+ .build();
- public static class LatLngEvaluator implements TypeEvaluator {
- // Method is used to interpolate the marker animation.
+ // Map Bounds Area
+ public static void setMapBoundsArea(Context context, MapboxMap mapboxMap, MapView mapView, Boolean check) {
- private LatLng latLng = new LatLng();
-
- @Override
- public LatLng evaluate(float fraction, LatLng startValue, LatLng endValue) {
- latLng.setLatitude(startValue.getLatitude()
- + ((endValue.getLatitude() - startValue.getLatitude()) * fraction));
- latLng.setLongitude(startValue.getLongitude()
- + ((endValue.getLongitude() - startValue.getLongitude()) * fraction));
- return latLng;
+ if (check) {
+ // Set bounds to WMI
+ mapboxMap.setLatLngBoundsForCameraTarget(WMI_BOUNDS);
+ makeNewCamera(mapboxMap, 52.466799, 16.927002, 17, 0, 0, 4000);
+ mapboxMap.setMinZoomPreference(16); // TODO export to map config
+ } else {
+ mapboxMap.setLatLngBoundsForCameraTarget(null);
+ mapboxMap.setMinZoomPreference(2);
}
}
+ public static void makeNewCamera(MapboxMap mapboxMap, double lat, double lon, int zoomParam, int bearingParam, int tiltParam, int duration) {
+ CameraPosition position = new CameraPosition.Builder()
+ .target(new LatLng(lat, lon)) // Sets the new camera position
+ .zoom(zoomParam) // Sets the zoom
+ .bearing(bearingParam) // Rotate the camera
+ .tilt(tiltParam) // Set the camera tilt
+ .build(); // Creates a CameraPosition from the builder
+
+ mapboxMap.animateCamera(CameraUpdateFactory
+ .newCameraPosition(position), duration);
+ }
+
+ // read file to JSON
public static String loadJsonFromAsset(Context context, String filename) {
// Using this method to load in GeoJSON files from the assets folder.
try {
@@ -41,4 +72,21 @@ public class mapUtils {
return null;
}
}
+
+ // Function for marker animation
+ public static class LatLngEvaluator implements TypeEvaluator {
+ // Method is used to interpolate the marker animation.
+
+ private LatLng latLng = new LatLng();
+
+ @Override
+ public LatLng evaluate(float fraction, LatLng startValue, LatLng endValue) {
+ latLng.setLatitude(startValue.getLatitude()
+ + ((endValue.getLatitude() - startValue.getLatitude()) * fraction));
+ latLng.setLongitude(startValue.getLongitude()
+ + ((endValue.getLongitude() - startValue.getLongitude()) * fraction));
+ return latLng;
+ }
+ }
+
}
diff --git a/app/src/main/res/drawable/blue_marker.png b/app/src/main/res/drawable/blue_marker.png
index d7068f2..7bbbd9b 100644
Binary files a/app/src/main/res/drawable/blue_marker.png and b/app/src/main/res/drawable/blue_marker.png differ
diff --git a/app/src/main/res/drawable/bug_icon.xml b/app/src/main/res/drawable/bug_icon.xml
new file mode 100644
index 0000000..c3458e1
--- /dev/null
+++ b/app/src/main/res/drawable/bug_icon.xml
@@ -0,0 +1,4 @@
+
+
+
diff --git a/app/src/main/res/drawable/custom_marker.png b/app/src/main/res/drawable/custom_marker.png
index 1df09fd..8b1f284 100644
Binary files a/app/src/main/res/drawable/custom_marker.png and b/app/src/main/res/drawable/custom_marker.png differ
diff --git a/app/src/main/res/drawable/green_marker.png b/app/src/main/res/drawable/green_marker.png
index b8f9abb..0babab0 100644
Binary files a/app/src/main/res/drawable/green_marker.png and b/app/src/main/res/drawable/green_marker.png differ
diff --git a/app/src/main/res/drawable/red_marker.png b/app/src/main/res/drawable/red_marker.png
index be782e1..6b72939 100644
Binary files a/app/src/main/res/drawable/red_marker.png and b/app/src/main/res/drawable/red_marker.png differ
diff --git a/app/src/main/res/layout/activity_login.xml b/app/src/main/res/layout/activity_login.xml
index 0c0e1fe..3b298de 100644
--- a/app/src/main/res/layout/activity_login.xml
+++ b/app/src/main/res/layout/activity_login.xml
@@ -72,11 +72,6 @@
-
-
-
-
-
-
-
-
-
-
-
+
+
\ No newline at end of file
diff --git a/app/src/main/res/layout/feedback_modal.xml b/app/src/main/res/layout/feedback_modal.xml
new file mode 100644
index 0000000..375a923
--- /dev/null
+++ b/app/src/main/res/layout/feedback_modal.xml
@@ -0,0 +1,67 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/app/src/main/res/layout/pref_sharing.xml b/app/src/main/res/layout/pref_sharing.xml
index 95817ac..73f957b 100644
--- a/app/src/main/res/layout/pref_sharing.xml
+++ b/app/src/main/res/layout/pref_sharing.xml
@@ -6,7 +6,9 @@
android:layout_width="match_parent"
android:layout_height="match_parent">
-
+
+
+
@@ -32,7 +44,7 @@
android:title="@string/status_switch_title"/>
-
-
-
-
-
+
\ No newline at end of file
diff --git a/app/src/main/res/layout/preference_button_widget.xml b/app/src/main/res/layout/preference_button_widget.xml
new file mode 100644
index 0000000..afb935d
--- /dev/null
+++ b/app/src/main/res/layout/preference_button_widget.xml
@@ -0,0 +1,13 @@
+
+
+
+
diff --git a/app/src/main/res/menu/activity_main_drawer.xml b/app/src/main/res/menu/activity_main_drawer.xml
index d9c6b19..90a85ef 100644
--- a/app/src/main/res/menu/activity_main_drawer.xml
+++ b/app/src/main/res/menu/activity_main_drawer.xml
@@ -1,6 +1,6 @@