diff --git a/app/build.gradle b/app/build.gradle
index 4d7fcf2..f019038 100644
--- a/app/build.gradle
+++ b/app/build.gradle
@@ -10,8 +10,8 @@ android {
applicationId "com.uam.wmi.findmytutor"
minSdkVersion 22
targetSdkVersion 27
- versionCode 21
- versionName "0.9.5-beta"
+ versionCode 37
+ versionName "0.9.6-beta"
testInstrumentationRunner "android.support.test.runner.AndroidJUnitRunner"
vectorDrawables.useSupportLibrary = true
}
@@ -72,4 +72,6 @@ dependencies {
// FloatingBarMenu
implementation 'com.getbase:floatingactionbutton:1.10.1'
implementation 'org.apache.commons:commons-collections4:4.0'
+ implementation 'com.android.support:appcompat-v7:27.1.1'
+ implementation 'com.android.support:design:27.1.1'
}
diff --git a/app/release/release/app.aab b/app/release/release/app.aab
index 0f22d91..0b58fd8 100644
Binary files a/app/release/release/app.aab and b/app/release/release/app.aab differ
diff --git a/app/release/release/fmtBeta0.9.5v18.aab b/app/release/release/fmtBeta0.9.5v18.aab
new file mode 100644
index 0000000..fb0edf9
Binary files /dev/null and b/app/release/release/fmtBeta0.9.5v18.aab differ
diff --git a/app/src/main/AndroidManifest.xml b/app/src/main/AndroidManifest.xml
index 5ccbfb9..d209b5a 100644
--- a/app/src/main/AndroidManifest.xml
+++ b/app/src/main/AndroidManifest.xml
@@ -27,10 +27,10 @@
tools:ignore="AllowBackup,GoogleAppIndexingWarning">
+ android:theme="@style/AppTheme.NoActionBar">
@@ -38,33 +38,43 @@
+ android:screenOrientation="portrait" />
+ android:screenOrientation="portrait" />
+ android:configChanges="keyboardHidden|orientation|screenSize"
+ android:screenOrientation="portrait" />
-
+ android:theme="@style/AppTheme" />
+
+
\ No newline at end of file
diff --git a/app/src/main/assets/wmi1floor.geojson b/app/src/main/assets/wmi1floor.geojson
new file mode 100644
index 0000000..f099ad5
--- /dev/null
+++ b/app/src/main/assets/wmi1floor.geojson
@@ -0,0 +1,727 @@
+{
+ "features": [
+ {
+ "type": "Feature",
+ "properties": {
+ "name": "Pokoje profesorskie"
+ },
+ "geometry": {
+ "coordinates": [
+ [
+ [
+ 16.926707,
+ 52.46657
+ ],
+ [
+ 16.92652,
+ 52.466244
+ ],
+ [
+ 16.926459,
+ 52.466255
+ ],
+ [
+ 16.926645,
+ 52.466582
+ ],
+ [
+ 16.926707,
+ 52.46657
+ ]
+ ]
+ ],
+ "type": "Polygon"
+ },
+ "id": "07f45cd94d45bb5ad0b6b285b0f6fbbb"
+ },
+ {
+ "type": "Feature",
+ "properties": {
+ "name": "Skrzydło B"
+ },
+ "geometry": {
+ "coordinates": [
+ [
+ [
+ 16.926961,
+ 52.467026
+ ],
+ [
+ 16.92677,
+ 52.466682
+ ],
+ [
+ 16.92652,
+ 52.466244
+ ],
+ [
+ 16.926459,
+ 52.466255
+ ],
+ [
+ 16.926428,
+ 52.466203
+ ],
+ [
+ 16.926175,
+ 52.46625
+ ],
+ [
+ 16.92621,
+ 52.466306
+ ],
+ [
+ 16.926323,
+ 52.466282
+ ],
+ [
+ 16.926515,
+ 52.466632
+ ],
+ [
+ 16.926408,
+ 52.466654
+ ],
+ [
+ 16.92644,
+ 52.466712
+ ],
+ [
+ 16.926543,
+ 52.46669
+ ],
+ [
+ 16.926754,
+ 52.467067
+ ],
+ [
+ 16.926961,
+ 52.467026
+ ]
+ ]
+ ],
+ "type": "Polygon"
+ },
+ "id": "143facf35f322434cfc5776f70f1db36"
+ },
+ {
+ "type": "Feature",
+ "properties": {
+ "name": "Winda"
+ },
+ "geometry": {
+ "coordinates": [
+ [
+ [
+ 16.92669,
+ 52.467141
+ ],
+ [
+ 16.92666,
+ 52.467089
+ ],
+ [
+ 16.926755,
+ 52.46707
+ ],
+ [
+ 16.926786,
+ 52.467121
+ ],
+ [
+ 16.92669,
+ 52.467141
+ ]
+ ]
+ ],
+ "type": "Polygon"
+ },
+ "id": "1a35bfafd619b80ffb8b36f03549e9e3"
+ },
+ {
+ "type": "Feature",
+ "properties": {
+ "name": "D2"
+ },
+ "geometry": {
+ "coordinates": [
+ [
+ [
+ 16.926876,
+ 52.466659
+ ],
+ [
+ 16.926984,
+ 52.466635
+ ],
+ [
+ 16.92694,
+ 52.466557
+ ],
+ [
+ 16.926831,
+ 52.46658
+ ],
+ [
+ 16.926876,
+ 52.466659
+ ]
+ ]
+ ],
+ "type": "Polygon"
+ },
+ "id": "3e0a32a0583254e9e7c47fea1f402472"
+ },
+ {
+ "type": "Feature",
+ "properties": {
+ "name": "Sale A"
+ },
+ "geometry": {
+ "coordinates": [
+ [
+ [
+ 16.92714,
+ 52.466489
+ ],
+ [
+ 16.926925,
+ 52.466127
+ ],
+ [
+ 16.927027,
+ 52.466106
+ ],
+ [
+ 16.927232,
+ 52.466472
+ ],
+ [
+ 16.92714,
+ 52.466489
+ ]
+ ]
+ ],
+ "type": "Polygon"
+ },
+ "id": "3e56cb54baf90049a3ce2f16577c2cd8"
+ },
+ {
+ "type": "Feature",
+ "properties": {
+ "name": "D1"
+ },
+ "geometry": {
+ "coordinates": [
+ [
+ [
+ 16.926984,
+ 52.466635
+ ],
+ [
+ 16.927084,
+ 52.466614
+ ],
+ [
+ 16.92704,
+ 52.466536
+ ],
+ [
+ 16.92694,
+ 52.466557
+ ],
+ [
+ 16.926984,
+ 52.466635
+ ]
+ ]
+ ],
+ "type": "Polygon"
+ },
+ "id": "56c2a7ab4e4d2ac14a46448d523470dc"
+ },
+ {
+ "type": "Feature",
+ "properties": {
+ "name": "Hol"
+ },
+ "geometry": {
+ "coordinates": [
+ [
+ [
+ 16.927104,
+ 52.467081
+ ],
+ [
+ 16.927039,
+ 52.467095
+ ],
+ [
+ 16.9268,
+ 52.467145
+ ],
+ [
+ 16.926754,
+ 52.467067
+ ],
+ [
+ 16.926961,
+ 52.467026
+ ],
+ [
+ 16.927277,
+ 52.46696
+ ],
+ [
+ 16.927272,
+ 52.466951
+ ],
+ [
+ 16.927451,
+ 52.466918
+ ],
+ [
+ 16.927494,
+ 52.467002
+ ],
+ [
+ 16.927278,
+ 52.467047
+ ],
+ [
+ 16.927144,
+ 52.467073
+ ],
+ [
+ 16.927104,
+ 52.467081
+ ]
+ ]
+ ],
+ "type": "Polygon"
+ },
+ "id": "6f1db27a4df5a46f7a6913556b01effe"
+ },
+ {
+ "type": "Feature",
+ "properties": {
+ "name": "Pokoje profesorskie"
+ },
+ "geometry": {
+ "coordinates": [
+ [
+ [
+ 16.92677,
+ 52.466683
+ ],
+ [
+ 16.926961,
+ 52.467026
+ ],
+ [
+ 16.926887,
+ 52.467041
+ ],
+ [
+ 16.926695,
+ 52.466699
+ ],
+ [
+ 16.92677,
+ 52.466683
+ ]
+ ]
+ ],
+ "type": "Polygon"
+ },
+ "id": "94f310dcaa6cee75d9e7800bf8d94155"
+ },
+ {
+ "type": "Feature",
+ "properties": {
+ "name": "Biblioteka"
+ },
+ "geometry": {
+ "coordinates": [
+ [
+ [
+ 16.926801,
+ 52.467144
+ ],
+ [
+ 16.926971,
+ 52.467424
+ ],
+ [
+ 16.926956,
+ 52.46743
+ ],
+ [
+ 16.926944,
+ 52.467436
+ ],
+ [
+ 16.92693,
+ 52.467441
+ ],
+ [
+ 16.926903,
+ 52.467452
+ ],
+ [
+ 16.926861,
+ 52.467464
+ ],
+ [
+ 16.926778,
+ 52.467476
+ ],
+ [
+ 16.926731,
+ 52.467485
+ ],
+ [
+ 16.926567,
+ 52.467194
+ ],
+ [
+ 16.926801,
+ 52.467144
+ ]
+ ]
+ ],
+ "type": "Polygon"
+ },
+ "id": "aadab5775bdeb4eaf82c940255ddadd7"
+ },
+ {
+ "type": "Feature",
+ "properties": {
+ "name": "Sale A"
+ },
+ "geometry": {
+ "coordinates": [
+ [
+ [
+ 16.927082,
+ 52.466492
+ ],
+ [
+ 16.926999,
+ 52.466509
+ ],
+ [
+ 16.926771,
+ 52.466109
+ ],
+ [
+ 16.926857,
+ 52.466088
+ ],
+ [
+ 16.927082,
+ 52.466492
+ ]
+ ]
+ ],
+ "type": "Polygon"
+ },
+ "id": "b39857ed605e5794fa6c9cdee5d7d6cf"
+ },
+ {
+ "type": "Feature",
+ "properties": {
+ "name": "Pokoje profesorskie"
+ },
+ "geometry": {
+ "coordinates": [
+ [
+ [
+ 16.926754,
+ 52.467066
+ ],
+ [
+ 16.926814,
+ 52.467054
+ ],
+ [
+ 16.926605,
+ 52.466676
+ ],
+ [
+ 16.926542,
+ 52.46669
+ ],
+ [
+ 16.926564,
+ 52.466728
+ ],
+ [
+ 16.926754,
+ 52.467066
+ ]
+ ]
+ ],
+ "type": "Polygon"
+ },
+ "id": "b754d867fde3826e72fe8c243399ff26"
+ },
+ {
+ "type": "Feature",
+ "properties": {
+ "name": "Sale A"
+ },
+ "geometry": {
+ "coordinates": [
+ [
+ [
+ 16.927272,
+ 52.46695
+ ],
+ [
+ 16.927083,
+ 52.466613
+ ],
+ [
+ 16.927167,
+ 52.466595
+ ],
+ [
+ 16.92735,
+ 52.466936
+ ],
+ [
+ 16.927272,
+ 52.46695
+ ]
+ ]
+ ],
+ "type": "Polygon"
+ },
+ "id": "c3726b2a2b3a589995fd3f17eecd1f53"
+ },
+ {
+ "type": "Feature",
+ "properties": {
+ "name": "D3"
+ },
+ "geometry": {
+ "coordinates": [
+ [
+ [
+ 16.92677,
+ 52.466682
+ ],
+ [
+ 16.926876,
+ 52.466659
+ ],
+ [
+ 16.926832,
+ 52.46658
+ ],
+ [
+ 16.926725,
+ 52.466604
+ ],
+ [
+ 16.92677,
+ 52.466682
+ ]
+ ]
+ ],
+ "type": "Polygon"
+ },
+ "id": "c73d9bdbccc15d9907e24b8bb731118a"
+ },
+ {
+ "type": "Feature",
+ "properties": {
+ "name": "Pokoje profesorskie"
+ },
+ "geometry": {
+ "coordinates": [
+ [
+ [
+ 16.926324,
+ 52.466282
+ ],
+ [
+ 16.926503,
+ 52.46661
+ ],
+ [
+ 16.926579,
+ 52.466595
+ ],
+ [
+ 16.926398,
+ 52.466268
+ ],
+ [
+ 16.926324,
+ 52.466282
+ ]
+ ]
+ ],
+ "type": "Polygon"
+ },
+ "id": "d54475cedfa0a866e13933c56bf35d76"
+ },
+ {
+ "type": "Feature",
+ "properties": {
+ "name": "Sale A"
+ },
+ "geometry": {
+ "coordinates": [
+ [
+ [
+ 16.927607,
+ 52.466891
+ ],
+ [
+ 16.92734,
+ 52.466562
+ ],
+ [
+ 16.927242,
+ 52.466585
+ ],
+ [
+ 16.927451,
+ 52.466918
+ ],
+ [
+ 16.927607,
+ 52.466891
+ ]
+ ]
+ ],
+ "type": "Polygon"
+ },
+ "id": "d97989e446002de50bc8844d2d9cdf5c"
+ },
+ {
+ "type": "Feature",
+ "properties": {
+ "name": "Winda"
+ },
+ "geometry": {
+ "coordinates": [
+ [
+ [
+ 16.92669,
+ 52.467141
+ ],
+ [
+ 16.92666,
+ 52.467089
+ ],
+ [
+ 16.926755,
+ 52.46707
+ ],
+ [
+ 16.926786,
+ 52.467121
+ ],
+ [
+ 16.92669,
+ 52.467141
+ ]
+ ]
+ ],
+ "type": "Polygon"
+ },
+ "id": "dfdba4ee1ee0c55193b8dd04f8b00f6c"
+ },
+ {
+ "type": "Feature",
+ "properties": {
+ "name": "Skrzydło A"
+ },
+ "geometry": {
+ "coordinates": [
+ [
+ [
+ 16.927606,
+ 52.466891
+ ],
+ [
+ 16.927339,
+ 52.466562
+ ],
+ [
+ 16.927242,
+ 52.466585
+ ],
+ [
+ 16.92718,
+ 52.466482
+ ],
+ [
+ 16.927232,
+ 52.466473
+ ],
+ [
+ 16.927025,
+ 52.466105
+ ],
+ [
+ 16.926924,
+ 52.466126
+ ],
+ [
+ 16.926896,
+ 52.466078
+ ],
+ [
+ 16.92677,
+ 52.466108
+ ],
+ [
+ 16.926998,
+ 52.466509
+ ],
+ [
+ 16.927041,
+ 52.466537
+ ],
+ [
+ 16.927075,
+ 52.466595
+ ],
+ [
+ 16.927082,
+ 52.466614
+ ],
+ [
+ 16.927277,
+ 52.46696
+ ],
+ [
+ 16.927358,
+ 52.466942
+ ],
+ [
+ 16.927354,
+ 52.466935
+ ],
+ [
+ 16.92745,
+ 52.466918
+ ],
+ [
+ 16.927606,
+ 52.466891
+ ]
+ ]
+ ],
+ "type": "Polygon"
+ },
+ "id": "faaa569e3642a741f70a77071f19f131"
+ }
+ ],
+ "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 3a5956e..31d11e0 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
@@ -53,6 +53,7 @@ import io.reactivex.schedulers.Schedulers;
import static com.mapbox.mapboxsdk.Mapbox.getApplicationContext;
import static com.uam.wmi.findmytutor.utils.Const.defaultMapZoom;
+import static com.uam.wmi.findmytutor.utils.Const.onlineBackgroundLocationInterval;
import static com.uam.wmi.findmytutor.utils.Const.searchMapZoom;
import static com.uam.wmi.findmytutor.utils.PrefUtils.storeBackgroundLocationStatus;
@@ -99,11 +100,11 @@ public abstract class BaseActivity
String itemName = (String) item.getTitle();
Intent launchIntent;
if (itemName.equals(getResources().getString(R.string.navigation_item_whitelist))) {
- /* launchIntent = new Intent(getApplicationContext(), WhitelistActivity.class);
- startActivity(launchIntent);*/
+ launchIntent = new Intent(getApplicationContext(), WhiteList.class);
+ startActivity(launchIntent);
} else if (itemName.equals(getResources().getString(R.string.navigation_item_blacklist))) {
- /* launchIntent = new Intent(getApplicationContext(), BlacklistActivity.class);
- startActivity(launchIntent);*/
+ launchIntent = new Intent(getApplicationContext(),BlackList.class);
+ startActivity(launchIntent);
} else if (itemName.equals(getResources().getString(R.string.navigation_item_profile))) {
@@ -200,7 +201,6 @@ public abstract class BaseActivity
public void stopBackgroundLocalizationTask() {
Intent stopIntent = new Intent(getApplicationContext(), BackgroundLocalizationService.class);
stopIntent.putExtra("request_stop", true);
- Log.e("Localization", "JEstem w stop BG");
stopService(stopIntent);
@@ -210,6 +210,7 @@ public abstract class BaseActivity
checkPermissions();
Intent startIntent = new Intent(getApplicationContext(), BackgroundLocalizationService.class);
+ startIntent.putExtra("notify_interval", onlineBackgroundLocationInterval);
if (Build.VERSION.SDK_INT > Build.VERSION_CODES.O) {
startForegroundService(startIntent);
@@ -219,17 +220,12 @@ public abstract class BaseActivity
}
public void handleBackgroundTaskLifeCycle() {
- Log.e("Localization", String.valueOf(PrefUtils.isEnableSharingLocalization(getApplicationContext())));
Boolean shouldServiceRun = PrefUtils.isEnableSharingLocalization(getApplicationContext()) && isTutor;
- Log.e("Localization", String.valueOf(shouldServiceRun));
if (shouldServiceRun) {
startBackgroundLocalizationTask();
- Log.e("Localization", "JEstem i odpalam");
-
} else {
stopBackgroundLocalizationTask();
- Log.e("Localization", "JEstem i nie odpalam");
}
}
@@ -285,7 +281,6 @@ public abstract class BaseActivity
getMenuInflater().inflate(R.menu.menu_main, menu);
infoMenuItem = menu.findItem(R.id.action_info);
-
MenuItem myActionMenuItem = menu.findItem(R.id.action_search);
searchView = (SearchView) myActionMenuItem.getActionView();
@@ -295,6 +290,10 @@ public abstract class BaseActivity
adjustMapToSearch(defaultMapZoom);
}
+ if (!hasFocus && activeFragment.equals(ActiveFragment.USER_LIST)) {
+ ((UsersListFragment) userListFragment).restoreUsersList();
+ }
+
if(hasFocus && activeFragment.equals(ActiveFragment.NONE)){
adjustMapToSearch(searchMapZoom);
}
@@ -303,6 +302,7 @@ public abstract class BaseActivity
RxSearchObservable.fromView(searchView)
.skip(0)
.map(String::toLowerCase)
+ .filter(t -> !t.isEmpty())
.debounce(250, TimeUnit.MILLISECONDS)
.subscribeOn(Schedulers.io())
.observeOn(AndroidSchedulers.mainThread())
@@ -389,11 +389,14 @@ public abstract class BaseActivity
if (itemId == R.id.nav_map) {
removeFragment(sharingFragment);
removeFragment(userListFragment);
- activeFragment = ActiveFragment.NONE;
+ activeFragment = ActiveFragment.NONE;
+ findViewById(R.id.action_search).setVisibility(View.VISIBLE);
} else if (itemId == R.id.nav_profile) {
loadUserSettingsFragment();
+ findViewById(R.id.action_search).setVisibility(View.GONE);
} else if (itemId == R.id.nav_user_list) {
loadUserListFragment();
+ findViewById(R.id.action_search).setVisibility(View.VISIBLE);
}
selectBottomNavigationBarItem(itemId);
}, 300);
diff --git a/app/src/main/java/com/uam/wmi/findmytutor/activity/BlackList.java b/app/src/main/java/com/uam/wmi/findmytutor/activity/BlackList.java
new file mode 100644
index 0000000..ce91562
--- /dev/null
+++ b/app/src/main/java/com/uam/wmi/findmytutor/activity/BlackList.java
@@ -0,0 +1,363 @@
+package com.uam.wmi.findmytutor.activity;
+
+import android.annotation.SuppressLint;
+import android.graphics.drawable.ColorDrawable;
+import android.os.Bundle;
+import android.support.design.widget.CoordinatorLayout;
+import android.support.design.widget.FloatingActionButton;
+import android.support.design.widget.Snackbar;
+import android.support.v7.app.ActionBar;
+import android.support.v7.app.AlertDialog;
+import android.support.v7.app.AppCompatActivity;
+import android.support.v7.widget.DefaultItemAnimator;
+import android.support.v7.widget.LinearLayoutManager;
+import android.support.v7.widget.RecyclerView;
+import android.support.v7.widget.Toolbar;
+import android.text.TextUtils;
+import android.util.Log;
+import android.view.Gravity;
+import android.view.LayoutInflater;
+import android.view.Menu;
+import android.view.MenuItem;
+import android.view.View;
+import android.view.WindowManager;
+import android.widget.Button;
+import android.widget.CompoundButton;
+import android.widget.EditText;
+import android.widget.LinearLayout;
+import android.widget.PopupWindow;
+import android.widget.Switch;
+import android.widget.TextView;
+import android.widget.Toast;
+import android.widget.ToggleButton;
+
+import com.jakewharton.retrofit2.adapter.rxjava2.HttpException;
+import com.mapbox.geojson.Point;
+import com.mapbox.mapboxsdk.geometry.LatLng;
+import com.uam.wmi.findmytutor.R;
+import com.uam.wmi.findmytutor.adapters.BlackListAdapter;
+import com.uam.wmi.findmytutor.model.IsUsingListBool;
+import com.uam.wmi.findmytutor.model.PredefinedCoordViewModel;
+import com.uam.wmi.findmytutor.model.StudentIdModel;
+import com.uam.wmi.findmytutor.model.User;
+import com.uam.wmi.findmytutor.model.UserResponseModel;
+import com.uam.wmi.findmytutor.network.ApiClient;
+import com.uam.wmi.findmytutor.service.PredefinedStatusesService;
+import com.uam.wmi.findmytutor.service.UserService;
+import com.uam.wmi.findmytutor.utils.MyDividerItemDecoration;
+import com.uam.wmi.findmytutor.utils.PrefUtils;
+import com.uam.wmi.findmytutor.utils.RecyclerTouchListener;
+import com.uam.wmi.findmytutor.utils.RestApiHelper;
+import com.uam.wmi.findmytutor.utils.SharingLevel;
+import com.uam.wmi.findmytutor.utils.WrapContentLinearLayoutManager;
+
+import java.text.Collator;
+import java.util.ArrayList;
+import java.util.Collections;
+import java.util.HashSet;
+import java.util.List;
+import java.util.Locale;
+import java.util.Set;
+
+import butterknife.BindView;
+import butterknife.ButterKnife;
+import io.reactivex.Observable;
+import io.reactivex.ObservableSource;
+import io.reactivex.android.schedulers.AndroidSchedulers;
+import io.reactivex.disposables.CompositeDisposable;
+import io.reactivex.functions.Function;
+import io.reactivex.observers.DisposableObserver;
+import io.reactivex.observers.DisposableSingleObserver;
+import io.reactivex.schedulers.Schedulers;
+import okhttp3.ResponseBody;
+
+public class BlackList extends AppCompatActivity {
+
+ private CompositeDisposable disposable = new CompositeDisposable();
+ private UserService userService;
+ private boolean didFetched = false;
+ private String tutorId;
+
+ @BindView(R.id.recycler_view_blacklist)
+ RecyclerView recyclerView;
+ @BindView(R.id.black_list_empty_text_view)
+ TextView noNotesView;
+ @BindView(R.id.switch_blacklist_toggle)
+ Switch aSwitch;
+ @BindView(R.id.add_to_black_list_fab)
+ FloatingActionButton addToBlackListFab;
+
+ private Integer prevSize;
+ private BlackListAdapter mAdapter;
+ private List blacklistedUsers = new ArrayList<>();
+ private Collator plCollator = Collator.getInstance(Locale.forLanguageTag("pl-PL"));
+
+ @Override
+ protected void onCreate(Bundle savedInstanceState) {
+ super.onCreate(savedInstanceState);
+ getWindow().getDecorView().setSystemUiVisibility(View.SYSTEM_UI_FLAG_LIGHT_STATUS_BAR);
+ setContentView(R.layout.activity_black_list);
+ ButterKnife.bind(this);
+
+ tutorId = PrefUtils.getUserId(getApplicationContext());
+ userService = ApiClient.getClient(getApplicationContext())
+ .create(UserService.class);
+
+ if (PrefUtils.isBlackListing(this)){
+ aSwitch.setText(getString(R.string.action_black_list) +" ON");
+ aSwitch.setChecked(true);
+ handleChangeRequest(true);
+ }else{
+ aSwitch.setText(getString(R.string.action_black_list) +" OFF");
+ aSwitch.setChecked(false);
+ handleChangeRequest(false);
+ }
+
+ Toolbar toolbar = findViewById(R.id.toolbar);
+ toolbar.setTitle(getString(R.string.activity_title_blacklist));
+ setSupportActionBar(toolbar);
+
+ mAdapter = new BlackListAdapter(this, blacklistedUsers);
+ recyclerView.setLayoutManager(new WrapContentLinearLayoutManager(getApplicationContext()));
+ recyclerView.setItemAnimator(new DefaultItemAnimator());
+ recyclerView.addItemDecoration(new MyDividerItemDecoration(this, LinearLayoutManager.VERTICAL, 16));
+ recyclerView.setAdapter(mAdapter);
+
+ fetchBlackListedUsers();
+ /**
+ * On long press on RecyclerView item, open alert dialog
+ * with options to choose
+ * Edit and Delete
+ * */
+ recyclerView.addOnItemTouchListener(new RecyclerTouchListener(this,
+ recyclerView, new RecyclerTouchListener.ClickListener() {
+ @Override
+ public void onClick(View view, final int position) {
+ }
+
+ @Override
+ public void onLongClick(View view, int position) {
+ }
+ }));
+
+ addToBlackListFab.setOnClickListener(this::showFabDialog);
+
+ handleSwitch();
+ }
+
+ private Observable> getListOfBlacklistedUsers(String userId) {
+ return userService.getTutorBlacklistedByID(userId)
+ .toObservable()
+ .subscribeOn(Schedulers.io())
+ .observeOn(AndroidSchedulers.mainThread());
+ }
+
+ private Observable getUserObservable(String userId) {
+ return userService
+ .getUserById(userId)
+ .toObservable()
+ .subscribeOn(Schedulers.io())
+ .observeOn(AndroidSchedulers.mainThread());
+ }
+
+ private void fetchBlackListedUsers() {
+ prevSize = blacklistedUsers.size();
+
+ blacklistedUsers.clear();
+
+ disposable.add(getListOfBlacklistedUsers(tutorId)
+ .subscribeOn(Schedulers.io())
+ .observeOn(AndroidSchedulers.mainThread())
+ .flatMap((Function, Observable>) Observable::fromIterable)
+ .flatMap((Function>) this::getUserObservable)
+ .subscribeWith(new DisposableObserver() {
+ @Override
+ public void onNext(User user) {
+ blacklistedUsers.add(user);
+ }
+
+ @Override
+ public void onError(Throwable e) {
+ showError(e);
+ }
+
+ @Override
+ public void onComplete() {
+ Collections.sort(blacklistedUsers, (a, b) -> sortByUserName(a,b));
+ refreshUI();
+ }
+ }));
+ }
+
+ private void refreshUI(){
+ toggleEmptyNotes();
+ mAdapter.notifyItemRangeInserted(prevSize, blacklistedUsers.size() - prevSize);
+ mAdapter.notifyDataSetChanged();
+ }
+
+ private int sortByUserName(User t1, User t2) {
+ return plCollator.compare(t1.getLastName(), t2.getLastName());
+ }
+
+ private void showFabDialog(View v){
+ LayoutInflater layoutInflaterAndroid = LayoutInflater.from(getApplicationContext());
+ @SuppressLint("InflateParams") View view = layoutInflaterAndroid.inflate(R.layout.black_list_fab_modal, null);
+ AlertDialog.Builder alertDialogBuilderUserInput = new android.support.v7.app.AlertDialog.Builder(this);
+
+ alertDialogBuilderUserInput.setView(view).setPositiveButton(getApplicationContext().getString(R.string.modal_location_send), null);
+
+ alertDialogBuilderUserInput
+ .setPositiveButton(R.string.add, null)
+ .setNegativeButton(R.string.cancel, null);
+
+ final AlertDialog alertDialog = alertDialogBuilderUserInput.create();
+ alertDialog.getWindow().setSoftInputMode(WindowManager.LayoutParams.SOFT_INPUT_STATE_VISIBLE);
+
+ EditText modalUserInput = view.findViewById(R.id.black_list_modal_input);
+
+ alertDialog.setOnShowListener(dialogInterface -> {
+ Button sendButton = alertDialog.getButton(AlertDialog.BUTTON_POSITIVE);
+
+ Button dismissButton = alertDialog.getButton(AlertDialog.BUTTON_NEGATIVE);
+
+ dismissButton.setOnClickListener(view1 -> alertDialog.dismiss());
+
+ sendButton.setOnClickListener(view1 -> {
+ String body = modalUserInput.getText().toString();
+
+ if (TextUtils.isEmpty(body)) {
+ Toast.makeText(getApplicationContext(), R.string.can_not_be_empty, Toast.LENGTH_SHORT).show();
+ modalUserInput.requestFocus();
+ } else {
+ sendUserToBlacklist(body);
+ alertDialog.dismiss();
+ }
+ });
+ });
+
+ alertDialog.show();
+ }
+
+ private void sendUserToBlacklist(String body) {
+ StudentIdModel studentIdModel = new StudentIdModel(body);
+ disposable.add(
+ userService.addStudentToBlacklist(PrefUtils.getUserId(getApplicationContext()), studentIdModel)
+ .subscribeOn(Schedulers.io())
+ .observeOn(AndroidSchedulers.mainThread())
+ .subscribe(this::handleAddUser,this::showError)
+ );
+ }
+
+
+ private void handleAddUser(User user) {
+ Toast.makeText(this, R.string.add_user_to_list, Snackbar.LENGTH_LONG).show();
+
+ blacklistedUsers.clear();
+ fetchBlackListedUsers();
+ }
+
+ private void showError(Throwable e) {
+ String message;
+
+ if (e instanceof HttpException) {
+ ResponseBody responseBody = ((HttpException) e).response().errorBody();
+ message = RestApiHelper.getErrorMessage(responseBody);
+ if (((HttpException) e).response().code() == 404) {
+ message = getString(R.string.no_such_a_user);
+ }
+ } else {
+ message = "Network Error !";
+ }
+
+ Toast.makeText(this, message, Snackbar.LENGTH_LONG).show();
+ }
+
+ private void toggleEmptyNotes() {
+
+ if (didFetched && blacklistedUsers.size() == 0) {
+ noNotesView.setText(R.string.list_is_empty);
+ noNotesView.setVisibility(View.VISIBLE);
+ }else if (blacklistedUsers.size() > 0) {
+ noNotesView.setVisibility(View.GONE);
+ } else {
+ noNotesView.setText(getString(R.string.loading));
+ noNotesView.setVisibility(View.VISIBLE);
+ }
+ }
+
+ @Override
+ public boolean onCreateOptionsMenu(Menu menu) {
+ // Inflate the menu; this adds items to the action bar if it is present.
+ getMenuInflater().inflate(R.menu.menu_black_list, menu);
+ return true;
+ }
+
+ @Override
+ public boolean onOptionsItemSelected(MenuItem item) {
+
+ if (item.getItemId()==R.id.action_blacklist_info_popup){
+ int layoutID = R.layout.info_popup_blacklist;
+
+ View popupView = getLayoutInflater().inflate(layoutID,null);
+
+ PopupWindow popupWindow = new PopupWindow(popupView,
+ LinearLayout.LayoutParams.WRAP_CONTENT, LinearLayout.LayoutParams.WRAP_CONTENT);
+ // If the PopupWindow should be focusable
+ popupWindow.setFocusable(true);
+ // If you need the PopupWindow to dismiss when when touched outside
+ popupWindow.setBackgroundDrawable(new ColorDrawable());
+ // Get the View's(the one that was clicked in the Fragment) location
+ View anchorView= getWindow().getDecorView().findViewById(android.R.id.content);
+ popupWindow.showAtLocation(anchorView,Gravity.TOP|Gravity.END, 0, 0);
+ }
+
+ return super.onOptionsItemSelected(item);
+ }
+
+ private void handleSwitch(){
+ aSwitch.setOnCheckedChangeListener((buttonView, isChecked) -> {
+ if (isChecked){
+ aSwitch.setText(getString(R.string.action_black_list) + " "+ getString(R.string.on));
+ handleChangeRequest(true);
+ PrefUtils.useBlacklist(this,true);
+ }else {
+ aSwitch.setText(getString(R.string.action_black_list) + " "+getString(R.string.off));
+ handleChangeRequest(false);
+ PrefUtils.useBlacklist(this,false);
+ }
+ });
+ }
+
+ private void handleChangeRequest(boolean value){
+ IsUsingListBool isUsingListBool = new IsUsingListBool();
+ isUsingListBool.setIsUsing(value);
+ disposable.add(
+ userService.setTutorBlacklist(tutorId, isUsingListBool)
+ .subscribeOn(Schedulers.io())
+ .observeOn(AndroidSchedulers.mainThread())
+ .subscribe(()->{
+ },this::showError)
+ );
+ }
+
+ @Override
+ public void onResume() {
+ super.onResume();
+ }
+
+ @Override
+ public void onPause() {
+ super.onPause();
+ }
+
+ @Override
+ public void onStop() {
+ super.onStop();
+ }
+
+ @Override
+ public void onDestroy() {
+ super.onDestroy();
+ disposable.dispose();
+ }
+}
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 189f28a..fda30bf 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
@@ -149,7 +149,7 @@ public class LoginActivity extends AppCompatActivity {
private void loginProcess(String email, String password) {
ValidateUser user = new ValidateUser(email, password);
- //LdapUser fakeUser = new LdapUser(email, password,"wmi","tutor",email,"Fałszywy",email);
+ // LdapUser fakeUser = new LdapUser(email, password,"wmi","tutor",email,"Fałszywy",email);
disposable.add(ldapService.validate(user)
//disposable.add(ldapService.fakeValidate(fakeUser)
.subscribeOn(Schedulers.io())
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 b1e9a32..2822ed9 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
@@ -44,6 +44,7 @@ import com.uam.wmi.findmytutor.model.PredefinedCoordViewModel;
import com.uam.wmi.findmytutor.model.User;
import com.uam.wmi.findmytutor.network.ApiClient;
import com.uam.wmi.findmytutor.service.CoordinateService;
+import com.uam.wmi.findmytutor.service.PredefinedCoordinatesService;
import com.uam.wmi.findmytutor.service.PredefinedStatusesService;
import com.uam.wmi.findmytutor.service.UserService;
import com.uam.wmi.findmytutor.utils.ApproximatedLocalization;
@@ -70,6 +71,8 @@ import io.reactivex.schedulers.Schedulers;
import okhttp3.ResponseBody;
import timber.log.Timber;
+import static com.uam.wmi.findmytutor.utils.Const.mapRefreshInterval;
+
public class MapActivity extends BaseActivity
implements PermissionsListener, OnMapReadyCallback {
@@ -80,7 +83,7 @@ public class MapActivity extends BaseActivity
private UserService userService;
private CompositeDisposable disposable = new CompositeDisposable();
- private int mInterval = 10000;
+ private int mInterval = mapRefreshInterval;
private Handler mHandler = new Handler();
private Runnable mStatusChecker;
private MapView mapView;
@@ -91,7 +94,7 @@ public class MapActivity extends BaseActivity
private Coordinate droppedMarkercoordinate;
private HashMap coordsMap = new HashMap<>();
private HashMap markerHash = new HashMap<>();
- private HashMap markerUserHash = new HashMap<>();
+ public HashMap markerUserHash = new HashMap<>();
private Set previousCoordsIds = new HashSet<>();
private ManualLocationUtils manualLocationUtils;
// Camera Animation params
@@ -148,22 +151,7 @@ public class MapActivity extends BaseActivity
mapboxMap.setOnMarkerClickListener(marker -> {
String id = markerUserHash.get(marker.getId());
- String locationLevel = PrefUtils.getLocationLevel(getApplicationContext());
-
- /* if (id.equals(myId) && (locationLevel.equals(SharingLevel.MANUAL.toString()) || locationLevel.equals(SharingLevel.PREDEFINED.toString()))) {
- selectLocationButton.setVisibility(View.GONE);
- removeLocationButton.setVisibility(View.VISIBLE);
-
- removeLocationButton.setOnClickListener(view -> {
- stopBackgroundLocalizationTask();
-
- removeLocationButton.setVisibility(View.GONE);
- Toast.makeText(MapActivity.this, R.string.manual_marker_info, Toast.LENGTH_SHORT).show();
-
- });
- } else {*/
- createMarkerModal(id);
- /* }*/
+ createMarkerModal(id);
return true;
});
@@ -246,7 +234,11 @@ public class MapActivity extends BaseActivity
}
private void setOnMapClickListener() {
- mapboxMap.addOnMapClickListener(e -> removeLocationButton.setVisibility(View.GONE));
+
+ mapboxMap.addOnMapClickListener(e -> {
+ removeLocationButton.setVisibility(View.GONE);
+ selectLocationButton.setVisibility(View.GONE);
+ });
}
private void setOnMapLongClickListener() {
@@ -333,7 +325,7 @@ public class MapActivity extends BaseActivity
final AlertDialog alertDialog = alertDialogBuilderUserInput.create();
- EditText modalUserInput = view.findViewById(R.id.feedback_input);
+ EditText modalUserInput = view.findViewById(R.id.manual_input);
alertDialog.setOnShowListener(dialogInterface -> {
Button sendButton = alertDialog.getButton(AlertDialog.BUTTON_POSITIVE);
@@ -365,7 +357,7 @@ public class MapActivity extends BaseActivity
private void sendLocation(String body, LatLng latLng) {
- PredefinedStatusesService predefinedStatusesService = ApiClient.getClient(getApplicationContext()).create(PredefinedStatusesService.class);
+ PredefinedCoordinatesService predefinedCoordinatesService = ApiClient.getClient(getApplicationContext()).create(PredefinedCoordinatesService.class);
PredefinedCoordViewModel droppedMarkercoordinate = new PredefinedCoordViewModel(
latLng.getLatitude(),
@@ -379,7 +371,7 @@ public class MapActivity extends BaseActivity
CompositeDisposable disposable = new CompositeDisposable();
disposable.add(
- predefinedStatusesService.postUserPredefinedCoord(PrefUtils.getUserId(getApplicationContext()), droppedMarkercoordinate)
+ predefinedCoordinatesService.postUserPredefinedCoord(PrefUtils.getUserId(getApplicationContext()), droppedMarkercoordinate)
.subscribeOn(Schedulers.io())
.observeOn(AndroidSchedulers.mainThread())
.subscribe(this::SaveCurrentManualLocation, this::handleError)
@@ -603,7 +595,6 @@ public class MapActivity extends BaseActivity
}
}
- // Add the mapView lifecycle to the activity's lifecycle methods
@Override
public void onResume() {
super.onResume();
@@ -615,6 +606,7 @@ public class MapActivity extends BaseActivity
protected void onStart() {
super.onStart();
mapView.onStart();
+ shouldFetchNewCoords = true;
}
@Override
@@ -708,7 +700,7 @@ public class MapActivity extends BaseActivity
}));
}
- private void filterMarkers(List users) {
+ public void filterMarkers(List users) {
restoreMapMarkers();
Icon markedMarker = IconFactory.getInstance(MapActivity.this).fromResource(R.drawable.search_marker);
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 1eee441..8882bfd 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
@@ -1,7 +1,9 @@
package com.uam.wmi.findmytutor.activity;
import android.annotation.SuppressLint;
+import android.app.AlertDialog;
import android.app.FragmentTransaction;
+import android.content.DialogInterface;
import android.content.SharedPreferences;
import android.os.Bundle;
import android.preference.ListPreference;
@@ -9,6 +11,7 @@ import android.preference.Preference;
import android.preference.PreferenceCategory;
import android.preference.PreferenceFragment;
import android.preference.SwitchPreference;
+import android.support.annotation.NonNull;
import android.util.Log;
import android.view.LayoutInflater;
import android.view.View;
@@ -19,17 +22,21 @@ import com.annimon.stream.IntPair;
import com.annimon.stream.Stream;
import com.jakewharton.retrofit2.adapter.rxjava2.HttpException;
import com.uam.wmi.findmytutor.R;
+import com.uam.wmi.findmytutor.adapters.TutorsListAdapter;
import com.uam.wmi.findmytutor.model.PredefinedCoordViewModel;
import com.uam.wmi.findmytutor.network.ApiClient;
+import com.uam.wmi.findmytutor.service.PredefinedCoordinatesService;
import com.uam.wmi.findmytutor.service.PredefinedStatusesService;
-import com.uam.wmi.findmytutor.utils.Const;
import com.uam.wmi.findmytutor.utils.EnableSharingDialog;
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 org.apache.commons.collections4.BidiMap;
+
import java.util.ArrayList;
+import java.util.Arrays;
import java.util.HashMap;
import java.util.List;
import java.util.Objects;
@@ -39,25 +46,34 @@ import io.reactivex.disposables.CompositeDisposable;
import io.reactivex.observers.DisposableSingleObserver;
import io.reactivex.schedulers.Schedulers;
import okhttp3.ResponseBody;
-
import static com.mapbox.mapboxsdk.Mapbox.getApplicationContext;
public class SharingFragment extends PreferenceFragment implements SharedPreferences.OnSharedPreferenceChangeListener {
protected SwitchPreference locationSharing;
+ protected SwitchPreference statusSwitch;
protected Preference locationMode;
protected ListPreference manualLocationList;
protected PreferenceCategory preferenceCategory;
protected RightButtonPreference manualLocationButton;
+ protected RightButtonPreference removeManualLocation;
+ protected RightButtonPreference removeManualStatus;
protected Preference manualStatus;
protected ListPreference statusList;
+ private HashMap locationMap;
+ private ArrayList locationUUIDs;
protected List predefinedCoordsList = new ArrayList<>();
private HashMap locationLevelMapping;
private HashMap statusMapping;
private PredefinedStatusesService statusesService;
+ private PredefinedCoordinatesService locationService;
private CompositeDisposable disposable;
+ private AlertDialog.Builder builder;
+ private String[] statusesArray;
+ private boolean statusSwitchFlag;
+ private ArrayList predefinedLocationsList;
- public static SharingFragment newInstance() {
+ public static SharingFragment newInstance() {
return new SharingFragment();
}
@@ -69,7 +85,13 @@ public class SharingFragment extends PreferenceFragment implements SharedPrefere
.subscribeWith(new DisposableSingleObserver>() {
@Override
public void onSuccess(List strings) {
- String[] statusesArray = strings.toArray(new String[strings.size()]);
+ statusesArray = strings.toArray(new String[strings.size()]);
+ if(strings.isEmpty()){
+ disableStatusPreferences();
+ }else{
+ enableStatusPreferences();
+ }
+// Log.d("STATUSES",Integer.toString(statusesArray.length ));
setListPreferenceData(statusList, statusesArray, null);
}
@@ -82,20 +104,47 @@ public class SharingFragment extends PreferenceFragment implements SharedPrefere
}
void getLocations(CompositeDisposable disposable) {
- disposable.add(statusesService.getUserPredefinedCoords(PrefUtils.getUserId(getApplicationContext()))
+ disposable.add(locationService.getUserPredefinedCoords(PrefUtils.getUserId(getApplicationContext()))
.subscribeOn(Schedulers.io())
.observeOn(AndroidSchedulers.mainThread())
.subscribeWith(new DisposableSingleObserver>() {
@Override
public void onSuccess(List coords) {
- String currentCoordId = PrefUtils.getCurrentManualLocation(getApplicationContext());
- List predefinedLocationsNames = Stream.of(coords).map(PredefinedCoordViewModel::getName).toList();
+ String currentCoordId = PrefUtils.getCurrentManualLocation(getApplicationContext());
+ locationMap = new HashMap();
+ locationUUIDs = new ArrayList();
+ for (PredefinedCoordViewModel i : coords) locationMap.put(i.getPredefinedCoordinateId(),i.getName());
+ for (PredefinedCoordViewModel i : coords) locationUUIDs.add(i.getPredefinedCoordinateId());
+ List predefinedLocationsNames = Stream.of(coords).map(PredefinedCoordViewModel::getName).toList();
+ List predefinedLocationsUUIDs = Stream.of(coords).map(PredefinedCoordViewModel::getPredefinedCoordinateId).toList();
predefinedCoordsList.addAll(coords);
String[] stringnames = predefinedLocationsNames.toArray(new String[0]);
+ predefinedLocationsList = new ArrayList<>(Arrays.asList(stringnames));
+ if (!PrefUtils.getLocationLevel(getApplicationContext()).equals("manual")) {
+ preferenceCategory.removePreference(manualLocationList);
+ preferenceCategory.removePreference(removeManualLocation);
+ preferenceCategory.removePreference(manualLocationButton);
+ }else{
+ if(predefinedCoordsList.isEmpty()){
+ locationSharing.setEnabled(false);
+ locationSharing.setChecked(false);
+ PrefUtils.disableSharing(getApplicationContext());
+ ((MapActivity) getActivity()).handleBackgroundTaskLifeCycle();
+ removeManualLocation.setEnabled(false);
+ manualLocationList.setEnabled(false);
+ manualLocationList.setSummary("");
+ }else{
+ manualLocationList.setEnabled(true);
+ manualLocationList.setSummary(PrefUtils.getCurrentManualLocationName(getApplicationContext()));
+ removeManualLocation.setEnabled(true);
+ locationSharing.setEnabled(true);
+
+ }
+ }
List activesId = Stream.of(coords).indexed()
.filter(v -> v.getSecond().getPredefinedCoordinateId().equals(currentCoordId)).map(IntPair::getFirst).toList();
@@ -105,29 +154,39 @@ public class SharingFragment extends PreferenceFragment implements SharedPrefere
else {
setListPreferenceData(manualLocationList, stringnames, activesId.get(0));
}
+
}
@Override
public void onError(Throwable e) {
Toast.makeText(getApplicationContext(), R.string.error_location_fetch, Toast.LENGTH_SHORT).show();
}
+
}));
}
+
@SuppressLint("ResourceType")
@Override
public void onCreate(final Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
- addPreferencesFromResource(R.layout.pref_sharing);
+ addPreferencesFromResource(R.xml.pref_sharing);
locationSharing = (SwitchPreference) findPreference("key_sharing_enabled");
+ statusSwitch = (SwitchPreference) findPreference("key_status_enabled");
locationMode = findPreference("key_location_level");
preferenceCategory = (PreferenceCategory) findPreference("category_sharing");
manualLocationList = (ListPreference) findPreference("key_manual_location_value");
manualLocationButton = (RightButtonPreference) findPreference("manual_location_button");
+ removeManualLocation = (RightButtonPreference) findPreference("remove_manual_location");
+ builder = new AlertDialog.Builder(getActivity());
+ removeManualStatus = (RightButtonPreference) findPreference("remove_manual_status");
manualStatus = findPreference("key_manual_status");
statusList = (ListPreference) findPreference("key_status_value");
- statusesService = ApiClient.getClient(getApplicationContext()).create(PredefinedStatusesService.class);
+ statusesService = ApiClient.getClient(getApplicationContext()).create(PredefinedStatusesService.class);
+ locationService = ApiClient.getClient(getApplicationContext()).create(PredefinedCoordinatesService.class);
disposable = new CompositeDisposable();
+ statusesArray = new String[0];
+ predefinedLocationsList = new ArrayList();
getStatuses(disposable);
getLocations(disposable);
locationLevelMapping = new HashMap();
@@ -153,28 +212,33 @@ public class SharingFragment extends PreferenceFragment implements SharedPrefere
/** Sharing level list **/
locationMode.setOnPreferenceChangeListener((preference, newValue) -> {
+ ((MapActivity) getActivity()).stopBackgroundLocalizationTask();
+ ((MapActivity) getActivity()).startBackgroundLocalizationTask();
PrefUtils.storeLocationMode(getApplicationContext(), locationLevelMapping.get(Integer.parseInt((String) newValue)));
-
if (PrefUtils.getLocationLevel(getApplicationContext()).equals(SharingLevel.MANUAL.toString())) {
if (!predefinedCoordsList.isEmpty()) {
- preferenceCategory.addPreference(manualLocationList);
+ preferenceCategory.addPreference(manualLocationList);
+ preferenceCategory.addPreference(removeManualLocation);
+ }else{
+ locationSharing.setEnabled(false);
+ locationSharing.setChecked(false);
+ PrefUtils.disableSharing(getApplicationContext());
+ ((MapActivity) getActivity()).handleBackgroundTaskLifeCycle();
+
}
-
preferenceCategory.addPreference(manualLocationButton);
-
} else {
+ locationSharing.setEnabled(true);
preferenceCategory.removePreference(manualLocationList);
preferenceCategory.removePreference(manualLocationButton);
+ preferenceCategory.removePreference(removeManualLocation);
}
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) -> {
@@ -199,6 +263,7 @@ public class SharingFragment extends PreferenceFragment implements SharedPrefere
+
/** Button 'choose from map' button listener **/
manualLocationButton.setOnPreferenceChangeListener((preference, o) -> {
FragmentTransaction fragmentTransaction = getFragmentManager().beginTransaction();
@@ -206,7 +271,9 @@ public class SharingFragment extends PreferenceFragment implements SharedPrefere
fragmentTransaction.commit();
return true;
});
-
+ statusSwitch.setOnPreferenceChangeListener((preference, newValue) -> {
+ return true;
+ });
/** Status list change listener **/
statusList.setOnPreferenceChangeListener((preference, newValue) -> {
ListPreference lp = (ListPreference) preference;
@@ -216,7 +283,7 @@ public class SharingFragment extends PreferenceFragment implements SharedPrefere
return true;
});
- /** Custom status list change listener **/
+ /** Custom status edittext change listener **/
manualStatus.setOnPreferenceChangeListener((preference, newValue) -> {
disposable.add(statusesService.postUserPredefinedStatus(PrefUtils.getUserId(getApplicationContext()), (String) newValue)
@@ -226,6 +293,40 @@ public class SharingFragment extends PreferenceFragment implements SharedPrefere
return true;
});
+ removeManualStatus.setOnPreferenceChangeListener((preference, newValue) -> {
+ showRemoveDialog(statusList.getEntries(),"status");
+ return true;
+ });
+
+ removeManualLocation.setOnPreferenceChangeListener(((preference, newValue) -> {
+ showRemoveDialog(manualLocationList.getEntries(),"location");
+ return true;
+
+ }));
+ }
+ public void showRemoveDialog(CharSequence[] entries, String service){
+ boolean [] checked = new boolean[entries.length];
+ ArrayList tobeDeleted = new ArrayList();
+// Log.d("sharingDialog", "no to siup");
+ builder.setPositiveButton("DELETE", new DialogInterface.OnClickListener() {
+ @Override
+ public void onClick(DialogInterface dialog, int which) {
+ for (int i=0; i< entries.length; i++){
+ if(checked[i] == true) {
+ tobeDeleted.add((String) entries[i]);
+ }
+ }
+ removeEntries(service,tobeDeleted);
+// Log.d("MANAGE-PREF",tobeDeleted.toString());
+ }
+ });
+ builder.setMultiChoiceItems(entries, checked, new DialogInterface.OnMultiChoiceClickListener() {
+ @Override
+ public void onClick(DialogInterface dialog, int which, boolean isChecked) {
+
+ }
+ });
+ builder.create().show();
}
@Override
@@ -236,6 +337,36 @@ public class SharingFragment extends PreferenceFragment implements SharedPrefere
return view;
}
+ protected void removeEntries(String service, ArrayList toBeDeleted){
+
+// Log.d("MANAGE-PREF", toBeDeleted.toString());
+ if(service.equals("status")){
+ for (String uuid:toBeDeleted) {
+ disposable.add(statusesService.deleteUserPredefinedStatus(PrefUtils.getUserId(getApplicationContext()), uuid)
+ .subscribeOn(Schedulers.io())
+ .observeOn(AndroidSchedulers.mainThread())
+ .subscribe(this::handleDeleteStatuses, this::handleError));
+ }
+ }else {
+ ArrayList uuidsToBeDeleted = new ArrayList();
+ for (String name:toBeDeleted) {
+ for (String uuid:locationUUIDs) {
+ if(locationMap.get(uuid).equals(name)){
+ uuidsToBeDeleted.add(uuid);
+ }
+ }
+ }
+ for (String uuid : uuidsToBeDeleted) {
+// predefinedCoordsList.removeIf(x -> x.getPredefinedCoordinateId().equals(uuid));
+ predefinedCoordsList.removeAll(Stream.of(predefinedCoordsList).filter(x -> x.getPredefinedCoordinateId().equals(uuid)).toList());
+ disposable.add(locationService.deleteUserPredefinedCoord(PrefUtils.getUserId(getApplicationContext()), uuid)
+ .subscribeOn(Schedulers.io())
+ .observeOn(AndroidSchedulers.mainThread())
+ .subscribe(this::handleDeleteLocations, this::handleError));
+ }
+ }
+ }
+
protected void setListPreferenceData(ListPreference lp, String[] entries, Integer activeId) {
try {
@@ -261,10 +392,15 @@ public class SharingFragment extends PreferenceFragment implements SharedPrefere
;
private void handleResponse(List resp) {
+ if(resp.size() == 1){
+ enableStatusPreferences();
+ if(PrefUtils.isStatusEnabled(getApplicationContext()) == false){
+ PrefUtils.enableStatus(getApplicationContext());
+ statusSwitch.setChecked(true);
+ }
+ }
String[] statusesArray = resp.toArray(new String[resp.size()]);
-
setListPreferenceData(statusList, statusesArray, resp.size() - 1);
-
statusList.setValueIndex(resp.size() - 1);
PrefUtils.storeStatus(getApplicationContext(), resp.get(resp.size() - 1));
statusList.setSummary(PrefUtils.getUserStatus(getApplicationContext()));
@@ -281,6 +417,73 @@ public class SharingFragment extends PreferenceFragment implements SharedPrefere
"Network error " + error.getMessage(), Toast.LENGTH_SHORT).show();
}
}
+ private void handleDeleteStatuses(List resp){
+ if(resp.isEmpty()){
+ disableStatusPreferences();
+ }else{
+ String[] statusesArray = resp.toArray(new String[resp.size()]);
+ setListPreferenceData(statusList, statusesArray, null);
+ String currentEntry = PrefUtils.getUserStatus(getApplicationContext());
+ if(resp.contains(currentEntry)){
+ statusList.setValueIndex(resp.indexOf(currentEntry));
+ }else{
+ statusList.setValueIndex(0);
+ statusList.setSummary(resp.get(0));
+ }
+ }
+
+ }
+ private void handleDeleteLocations(List resp){
+ getLocations(disposable);
+ String currentEntry = PrefUtils.getCurrentManualLocation(getApplicationContext());
+ if(resp.isEmpty()){
+ disableManualLocationPreferences();
+ }else{
+ if(!Stream.of(resp).filter(x -> x.getName().equals(currentEntry)).toList().isEmpty())
+ {
+ for (PredefinedCoordViewModel location: resp) {
+ if(location.getName().equals(currentEntry)){
+ manualLocationList.setValueIndex(resp.indexOf(location));
+ break;
+ }
+ }
+ }else{
+ manualLocationList.setValueIndex(0);
+ manualLocationList.setSummary(resp.get(0).getName());
+ //todo czy na pewno w shared pref sa dobre wartosci
+ }
+
+ }
+ }
+ private void disableStatusPreferences(){
+ removeManualStatus.setEnabled(false);
+ statusList.setEnabled(false);
+ statusSwitch.setEnabled(false);
+ statusList.setSummary("");
+ PrefUtils.disableStatus(getApplicationContext());
+
+ }
+ private void enableStatusPreferences(){
+ removeManualStatus.setEnabled(true);
+ statusList.setEnabled(true);
+ statusSwitch.setEnabled(true);
+ statusList.setSummary(PrefUtils.getUserStatus(getApplicationContext()));
+ }
+ private void disableManualLocationPreferences(){
+ removeManualLocation.setEnabled(false);
+ manualLocationList.setEnabled(false);
+ manualLocationList.setSummary("");
+ locationSharing.setChecked(false);
+ locationSharing.setEnabled(false);
+ PrefUtils.disableSharing(getApplicationContext());
+ ((MapActivity) getActivity()).handleBackgroundTaskLifeCycle();
+
+ }
+ private void enableManualLocationPreferences(){
+ removeManualLocation.setEnabled(true);
+ manualLocationList.setEnabled(true);
+
+ }
@Override
public void onSharedPreferenceChanged(SharedPreferences sharedPreferences, String key) {
@@ -300,4 +503,10 @@ public class SharingFragment extends PreferenceFragment implements SharedPrefere
getPreferenceManager().getSharedPreferences().unregisterOnSharedPreferenceChangeListener(this);
super.onPause();
}
+
+ @Override
+ public void onDestroy() {
+ super.onDestroy();
+ disposable.dispose();
+ }
}
diff --git a/app/src/main/java/com/uam/wmi/findmytutor/activity/SpecialList.java b/app/src/main/java/com/uam/wmi/findmytutor/activity/SpecialList.java
new file mode 100644
index 0000000..ec12a92
--- /dev/null
+++ b/app/src/main/java/com/uam/wmi/findmytutor/activity/SpecialList.java
@@ -0,0 +1,19 @@
+package com.uam.wmi.findmytutor.activity;
+
+import android.os.Bundle;
+import android.support.v7.app.AppCompatActivity;
+
+import com.uam.wmi.findmytutor.R;
+
+public abstract class SpecialList extends AppCompatActivity {
+ @Override
+ protected void onCreate(Bundle savedInstanceState){
+ super.onCreate(savedInstanceState);
+ setContentView(getContentViewId());
+
+ }
+
+ abstract int getContentViewId();
+
+
+}
diff --git a/app/src/main/java/com/uam/wmi/findmytutor/activity/TutorTab.java b/app/src/main/java/com/uam/wmi/findmytutor/activity/TutorTab.java
index 4db2335..575ff5d 100644
--- a/app/src/main/java/com/uam/wmi/findmytutor/activity/TutorTab.java
+++ b/app/src/main/java/com/uam/wmi/findmytutor/activity/TutorTab.java
@@ -29,6 +29,7 @@ import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
+import butterknife.ButterKnife;
import io.reactivex.android.schedulers.AndroidSchedulers;
import io.reactivex.disposables.CompositeDisposable;
import io.reactivex.observers.DisposableCompletableObserver;
@@ -61,9 +62,10 @@ public class TutorTab extends AppCompatActivity {
@Override
protected void onCreate(Bundle savedInstanceState) {
-
super.onCreate(savedInstanceState);
+ getWindow().getDecorView().setSystemUiVisibility(View.SYSTEM_UI_FLAG_LIGHT_STATUS_BAR);
setContentView(R.layout.content_tutor_tab);
+ ButterKnife.bind(this);
userName = findViewById(R.id.userName);
userNote = (TextInputEditText) findViewById(R.id.userNote);
@@ -134,7 +136,12 @@ public class TutorTab extends AppCompatActivity {
@Override
public void onError(Throwable e) {
- int code = ((HttpException) e).response().code();
+ int code = 0;
+
+ if (e instanceof HttpException) {
+ code = ((HttpException) e).response().code();
+ }
+
if( code == 404){
ifTutorTabExists = false;
dutyHoursAdapter = new DutyHoursAdapter(getApplicationContext(),new ArrayList());
@@ -144,7 +151,6 @@ public class TutorTab extends AppCompatActivity {
showError(e);
}
}));
-
}
private void addEmptyDuty(DutyHoursAdapter adapter){
diff --git a/app/src/main/java/com/uam/wmi/findmytutor/activity/TutorsListTab.java b/app/src/main/java/com/uam/wmi/findmytutor/activity/TutorsListTab.java
new file mode 100644
index 0000000..06e39cc
--- /dev/null
+++ b/app/src/main/java/com/uam/wmi/findmytutor/activity/TutorsListTab.java
@@ -0,0 +1,46 @@
+package com.uam.wmi.findmytutor.activity;
+
+//import android.app.Fragment;
+import android.support.v4.app.Fragment;
+import android.os.Bundle;
+import android.support.v4.app.FragmentTabHost;
+import android.view.LayoutInflater;
+import android.view.View;
+import android.view.ViewGroup;
+
+import com.uam.wmi.findmytutor.R;
+
+public class TutorsListTab extends Fragment {
+ private FragmentTabHost mTabHost;
+
+ public TutorsListTab() {
+ }
+
+ public static TutorsListTab newInstance() {
+ return new TutorsListTab();
+ }
+
+ public void onCreate(Bundle savedInstanceState) {
+ super.onCreate(savedInstanceState);
+
+ }
+
+ public View onCreateView(LayoutInflater inflater, ViewGroup container,
+ Bundle savedInstanceState) {
+
+ View rootView = inflater.inflate(R.layout.tutors_list_tabs, container, false);
+
+ mTabHost = rootView.findViewById(android.R.id.tabhost);
+ mTabHost.setup(getActivity(), getFragmentManager(), R.id.realtabcontent);
+
+ mTabHost.addTab(mTabHost.newTabSpec("fragmentb").setIndicator("Fragment B"),
+ UsersListFragment.class, null);
+ mTabHost.addTab(mTabHost.newTabSpec("fragmentc").setIndicator("Fragment C"),
+ UsersListFragment.class, null);
+
+
+
+ return rootView;
+ }
+}
+
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 0ed27fc..c0f9ac0 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
@@ -1,6 +1,8 @@
package com.uam.wmi.findmytutor.activity;
import android.app.Fragment;
+import android.app.FragmentTransaction;
+import android.graphics.drawable.Drawable;
import android.os.Bundle;
import android.support.annotation.NonNull;
import android.support.design.widget.CoordinatorLayout;
@@ -9,27 +11,36 @@ import android.support.v7.app.AlertDialog;
import android.support.v7.widget.DefaultItemAnimator;
import android.support.v7.widget.LinearLayoutManager;
import android.support.v7.widget.RecyclerView;
+import android.support.v7.widget.SearchView;
+import android.text.Spannable;
+import android.text.SpannableString;
+import android.text.style.ImageSpan;
+import android.util.Log;
+import android.view.Gravity;
import android.view.LayoutInflater;
+import android.view.Menu;
+import android.view.MenuInflater;
+import android.view.MenuItem;
import android.view.View;
import android.view.ViewGroup;
import android.widget.ArrayAdapter;
+import android.widget.Button;
+import android.widget.ImageView;
import android.widget.ListView;
import android.widget.TextView;
-import android.widget.Toast;
import com.annimon.stream.Stream;
import com.jakewharton.retrofit2.adapter.rxjava2.HttpException;
import com.uam.wmi.findmytutor.R;
import com.uam.wmi.findmytutor.adapters.TutorsListAdapter;
-
import com.uam.wmi.findmytutor.model.DutyHourViewModel;
import com.uam.wmi.findmytutor.model.TutorTabViewModel;
import com.uam.wmi.findmytutor.model.User;
import com.uam.wmi.findmytutor.network.ApiClient;
import com.uam.wmi.findmytutor.service.TutorTabApi;
import com.uam.wmi.findmytutor.service.UserService;
-import com.uam.wmi.findmytutor.utils.InfoHelperUtils;
import com.uam.wmi.findmytutor.utils.MyDividerItemDecoration;
+import com.uam.wmi.findmytutor.utils.PrefUtils;
import com.uam.wmi.findmytutor.utils.RecyclerTouchListener;
import com.uam.wmi.findmytutor.utils.RestApiHelper;
@@ -59,13 +70,14 @@ public class UsersListFragment extends Fragment {
@BindView(R.id.txt_empty_notes_view)
TextView noNotesView;
+ private SearchView searchView;
private UserService userService;
private TutorTabApi tutorTabService;
private CompositeDisposable disposable = new CompositeDisposable();
private TutorsListAdapter mAdapter;
private List tutorsList = new ArrayList<>();
- private List tutorsFiltered = new ArrayList<>();
private Collator plCollator = Collator.getInstance(Locale.forLanguageTag("pl-PL"));
+ private Boolean fetchOnlyOnlineUsers = PrefUtils.getShowOnlyOnlineUsers(getApplicationContext());
public UsersListFragment() {
}
@@ -75,10 +87,10 @@ public class UsersListFragment extends Fragment {
}
public View onCreateView(@NonNull LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
- mAdapter = new TutorsListAdapter(getActivity().getApplicationContext(), tutorsFiltered);
+ mAdapter = new TutorsListAdapter(getActivity().getApplicationContext(), tutorsList);
View view = inflater.inflate(R.layout.users_list, container, false);
view.setBackgroundColor(getResources().getColor(android.R.color.white));
-
+ setHasOptionsMenu(true);
return view;
}
@@ -94,6 +106,7 @@ public class UsersListFragment extends Fragment {
RecyclerView.LayoutManager mLayoutManager = new LinearLayoutManager(getActivity());
recyclerView.setLayoutManager(mLayoutManager);
recyclerView.setItemAnimator(new DefaultItemAnimator());
+ recyclerView.setVerticalScrollBarEnabled(true);
recyclerView.addItemDecoration(new MyDividerItemDecoration(getActivity(), LinearLayoutManager.VERTICAL, 16));
recyclerView.setAdapter(mAdapter);
@@ -103,7 +116,7 @@ public class UsersListFragment extends Fragment {
recyclerView, new RecyclerTouchListener.ClickListener() {
@Override
public void onClick(View view, final int position) {
- showNoteDialog(tutorsFiltered.get(position));
+ showNoteDialog(tutorsList.get(position));
}
@Override
@@ -113,12 +126,52 @@ public class UsersListFragment extends Fragment {
}
- public void searchUser(String textToSearch) {
- tutorsFiltered.clear();
- tutorsFiltered.addAll(Stream.of(tutorsList).filter(t ->
- t.toSearchAbleString().toLowerCase().contains(textToSearch.toLowerCase())).toList());
- mAdapter.notifyDataSetChanged();
+ @Override
+ public void onPrepareOptionsMenu(Menu menu) {
+ super.onPrepareOptionsMenu(menu);
+ try {
+ menu.findItem(R.id.showOnlineUsersOnly).setChecked(fetchOnlyOnlineUsers);
+ } catch (Exception e) {
+ Log.e(TAG, "onPrepareOptionsMenu error");
+ }
+ }
+
+ @Override
+ public boolean onOptionsItemSelected(MenuItem item) {
+ //item.setChecked(fetchOnlyOnlineUsers);
+ switch (item.getItemId()) {
+ case R.id.showOnlineUsersOnly:
+
+ if (item.isChecked()) {
+ fetchOnlyOnlineUsers = false;
+ item.setChecked(false);
+ } else {
+ item.setChecked(true);
+ fetchOnlyOnlineUsers = true;
+ }
+
+ PrefUtils.putShowOnlyOnlineUsers(getApplicationContext(), fetchOnlyOnlineUsers);
+ fetchAllTutors();
+ break;
+ }
+
+ return false;
+ }
+
+ @Override
+ public void onCreateOptionsMenu(Menu menu, MenuInflater inflater) {
+ inflater.inflate(R.menu.users_list_menu, menu);
+ menu.getItem(0).setChecked(fetchOnlyOnlineUsers);
+
+ MenuItem myActionMenuItem = menu.findItem(R.id.action_search);
+ searchView = (SearchView) myActionMenuItem.getActionView();
+
+ super.onCreateOptionsMenu(menu, inflater);
+ }
+
+ public void searchUser(String textToSearch) {
+ searchTutorInBackend(textToSearch);
}
private void showNoteDialog(final User user) {
@@ -132,6 +185,7 @@ public class UsersListFragment extends Fragment {
// User cancelled the dialog
});
+
TextView userName = view.findViewById(R.id.userName);
ListView userDutyHours = view.findViewById(R.id.userDutyHours);
TextView userDutyHoursTitle = view.findViewById(R.id.userDutyHoursTitle);
@@ -140,8 +194,26 @@ public class UsersListFragment extends Fragment {
TextView userEmail = view.findViewById(R.id.userEmail);
TextView department = view.findViewById(R.id.userDepartment);
- userName.setText(String.format("%s %s", user.getFirstName(), user.getLastName()));
+ userName.setText(String.format("%s %s", user.getFirstName(), user.getLastName()));
+ Drawable image;
+ if (user.isIsOnline()) {
+ image = this.getResources().getDrawable(R.drawable.user_list_online);
+ } else {
+ image = this.getResources().getDrawable(R.drawable.user_list_offline);
+ }
+
+ if (!user.isIsActive()) {
+ image = this.getResources().getDrawable(R.drawable.user_list_off);
+ }
+
+ Spannable span = new SpannableString(" " + userName.getText()); // or set your text manually
+ image.setBounds(0, 0, image.getIntrinsicWidth(), image.getIntrinsicHeight());
+ ImageSpan imageSpan = new ImageSpan(image);
+ span.setSpan(imageSpan, 0, 1, Spannable.SPAN_INCLUSIVE_EXCLUSIVE);
+ userName.setText(span);
+
+ UsersListFragment usersListFragment = this;
disposable.add(
tutorTabService.apiUsersTutorTabByTutorIdGet(user.getId())
.subscribeOn(Schedulers.io())
@@ -149,7 +221,20 @@ public class UsersListFragment extends Fragment {
.subscribeWith(new DisposableSingleObserver() {
@Override
public void onSuccess(TutorTabViewModel tutorTabViewModel) {
- final AlertDialog alertDialog = alertDialogBuilderUserInput.create();
+ final AlertDialog alertDialog;
+ if (((MapActivity) getActivity()).markerUserHash.containsValue(user.getId())) {
+ alertDialogBuilderUserInput.setPositiveButton(R.string.show_on_map, (dialog, id) -> {
+ // User cancelled the dialog
+ FragmentTransaction fragmentTransaction = getFragmentManager().beginTransaction();
+ fragmentTransaction.hide(usersListFragment);
+ fragmentTransaction.commit();
+ List list = new ArrayList();
+ list.add(user);
+ ((MapActivity) getActivity()).filterMarkers(list);
+ });
+ }
+ alertDialog = alertDialogBuilderUserInput.create();
+
String userNoteText = tutorTabViewModel.getNote();
List dutyHoursList = Stream.of(tutorTabViewModel.getDutyHours())
.map(DutyHourViewModel::getSummary).toList();
@@ -185,17 +270,16 @@ public class UsersListFragment extends Fragment {
private void fetchAllTutors() {
disposable.add(
- userService.getAllTutors()
+ (fetchOnlyOnlineUsers ?
+ userService.getAllActiveTutors() :
+ userService.getAllOfflineTutors())
.subscribeOn(Schedulers.io())
.observeOn(AndroidSchedulers.mainThread())
.map(tutors -> {
List tutorsList = new ArrayList<>(tutors);
-
List onlineTutors = Stream.of(tutorsList).filter(User::isIsOnline).toList();
-
List activeNotOnlineTutors = Stream.of(tutorsList)
.filter(t -> t.isIsActive() && !onlineTutors.contains(t)).toList();
-
List notActiveTutors = Stream.of(tutorsList)
.filterNot(User::isIsActive).toList();
@@ -213,9 +297,7 @@ public class UsersListFragment extends Fragment {
@Override
public void onSuccess(List users) {
tutorsList.clear();
- tutorsFiltered.clear();
tutorsList.addAll(users);
- tutorsFiltered.addAll(users);
mAdapter.notifyDataSetChanged();
toggleEmptyNotes();
}
@@ -228,22 +310,70 @@ public class UsersListFragment extends Fragment {
}
+ private void searchTutorInBackend(String searchString) {
+ disposable.add(
+ userService.searchUser(searchString)
+ .subscribeOn(Schedulers.io())
+ .observeOn(AndroidSchedulers.mainThread())
+ .subscribeWith(new DisposableSingleObserver>() {
+ @Override
+ public void onSuccess(List users) {
+ tutorsList.clear();
+ tutorsList.addAll(users);
+ mAdapter.notifyDataSetChanged();
+ }
+
+ @Override
+ public void onError(Throwable e) {
+ showSearchError(e);
+ }
+ }));
+ }
+
+
+ public void restoreUsersList() {
+ fetchAllTutors();
+ }
+
private int sortByUserName(User t1, User t2) {
return plCollator.compare(t1.getLastName(), t2.getLastName());
}
private void showError(Throwable e) {
String message;
+ Log.e(TAG, String.valueOf(e));
if (e instanceof HttpException) {
ResponseBody responseBody = ((HttpException) e).response().errorBody();
message = RestApiHelper.getErrorMessage(responseBody);
} else {
- message = "Network Error !";
+ message = getString(R.string.network_err);
}
- Snackbar.make(coordinatorLayout, message, Snackbar.LENGTH_LONG)
- .show();
+ createSnackbar(message);
+ }
+
+ private void showSearchError(Throwable e) {
+ String message;
+ Log.e(TAG, String.valueOf(e));
+
+ if (e instanceof HttpException) {
+ ResponseBody responseBody = ((HttpException) e).response().errorBody();
+ message = RestApiHelper.getErrorMessage(responseBody);
+ } else {
+ message = getString(R.string.search_null);
+ }
+
+ createSnackbar(message);
+ }
+
+ private void createSnackbar(String msg) {
+ Snackbar snackbar = Snackbar.make(coordinatorLayout, msg, Snackbar.LENGTH_LONG);
+ View view = snackbar.getView();
+ CoordinatorLayout.LayoutParams params = (CoordinatorLayout.LayoutParams) view.getLayoutParams();
+ params.gravity = Gravity.TOP;
+ view.setLayoutParams(params);
+ snackbar.show();
}
private void toggleEmptyNotes() {
@@ -251,6 +381,11 @@ public class UsersListFragment extends Fragment {
noNotesView.setVisibility(View.GONE);
} else {
noNotesView.setVisibility(View.VISIBLE);
+ if (fetchOnlyOnlineUsers)
+ noNotesView.setText(R.string.no_online_users);
+ else {
+ noNotesView.setText(R.string.no_offline_users);
+ }
}
}
diff --git a/app/src/main/java/com/uam/wmi/findmytutor/activity/WhiteList.java b/app/src/main/java/com/uam/wmi/findmytutor/activity/WhiteList.java
new file mode 100644
index 0000000..aad7e70
--- /dev/null
+++ b/app/src/main/java/com/uam/wmi/findmytutor/activity/WhiteList.java
@@ -0,0 +1,345 @@
+package com.uam.wmi.findmytutor.activity;
+
+import android.annotation.SuppressLint;
+import android.graphics.drawable.ColorDrawable;
+import android.os.Bundle;
+import android.support.design.widget.FloatingActionButton;
+import android.support.design.widget.Snackbar;
+import android.support.v7.app.AlertDialog;
+import android.support.v7.app.AppCompatActivity;
+import android.support.v7.widget.DefaultItemAnimator;
+import android.support.v7.widget.LinearLayoutManager;
+import android.support.v7.widget.RecyclerView;
+import android.support.v7.widget.Toolbar;
+import android.text.TextUtils;
+import android.util.Log;
+import android.view.Gravity;
+import android.view.LayoutInflater;
+import android.view.Menu;
+import android.view.MenuItem;
+import android.view.View;
+import android.view.WindowManager;
+import android.widget.Button;
+import android.widget.EditText;
+import android.widget.LinearLayout;
+import android.widget.PopupWindow;
+import android.widget.Switch;
+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.adapters.WhiteListAdapter;
+import com.uam.wmi.findmytutor.model.IsUsingListBool;
+import com.uam.wmi.findmytutor.model.StudentIdModel;
+import com.uam.wmi.findmytutor.model.User;
+import com.uam.wmi.findmytutor.network.ApiClient;
+import com.uam.wmi.findmytutor.service.UserService;
+import com.uam.wmi.findmytutor.utils.MyDividerItemDecoration;
+import com.uam.wmi.findmytutor.utils.PrefUtils;
+import com.uam.wmi.findmytutor.utils.RecyclerTouchListener;
+import com.uam.wmi.findmytutor.utils.RestApiHelper;
+import com.uam.wmi.findmytutor.utils.WrapContentLinearLayoutManager;
+
+import java.text.Collator;
+import java.util.ArrayList;
+import java.util.Collections;
+
+import java.util.List;
+import java.util.Locale;
+
+import butterknife.BindView;
+import butterknife.ButterKnife;
+import io.reactivex.Observable;
+import io.reactivex.ObservableSource;
+import io.reactivex.android.schedulers.AndroidSchedulers;
+import io.reactivex.disposables.CompositeDisposable;
+import io.reactivex.functions.Function;
+import io.reactivex.observers.DisposableObserver;
+import io.reactivex.schedulers.Schedulers;
+import okhttp3.ResponseBody;
+
+public class WhiteList extends AppCompatActivity {
+
+ private CompositeDisposable disposable = new CompositeDisposable();
+ private UserService userService;
+ private boolean didFetched = false;
+ private String tutorId;
+
+ @BindView(R.id.recycler_view_whitelist)
+ RecyclerView recyclerView;
+ @BindView(R.id.white_list_empty_text_view)
+ TextView noNotesView;
+ @BindView(R.id.switch_whitelist_toggle)
+ Switch aSwitch;
+ @BindView(R.id.add_to_white_list_fab)
+ FloatingActionButton addToWhiteListFab;
+
+ private WhiteListAdapter mAdapter;
+ private Integer prevSize;
+ private List whitelistedUsers = new ArrayList<>();
+ private Collator plCollator = Collator.getInstance(Locale.forLanguageTag("pl-PL"));
+
+ @Override
+ protected void onCreate(Bundle savedInstanceState) {
+ super.onCreate(savedInstanceState);
+ getWindow().getDecorView().setSystemUiVisibility(View.SYSTEM_UI_FLAG_LIGHT_STATUS_BAR);
+ setContentView(R.layout.activity_white_list);
+ ButterKnife.bind(this);
+ tutorId = PrefUtils.getUserId(getApplicationContext());
+ userService = ApiClient.getClient(getApplicationContext())
+ .create(UserService.class);
+
+ if (PrefUtils.isWhiteListing(this)){
+ aSwitch.setText(getString(R.string.action_white_list) +" ON");
+ aSwitch.setChecked(true);
+ handleChangeRequest(true);
+ }else{
+ aSwitch.setText(getString(R.string.action_white_list) +" OFF");
+ aSwitch.setChecked(false);
+ handleChangeRequest(false);
+ }
+
+ Toolbar toolbar = findViewById(R.id.toolbar);
+ toolbar.setTitle(getString(R.string.activity_title_whitelist));
+ setSupportActionBar(toolbar);
+
+ mAdapter = new WhiteListAdapter(this, whitelistedUsers);
+ recyclerView.setLayoutManager(new WrapContentLinearLayoutManager(getApplicationContext()));
+ recyclerView.setItemAnimator(new DefaultItemAnimator());
+ recyclerView.addItemDecoration(new MyDividerItemDecoration(this, LinearLayoutManager.VERTICAL, 16));
+ recyclerView.setAdapter(mAdapter);
+
+ /**
+ * On long press on RecyclerView item, open alert dialog
+ * with options to choose
+ * Edit and Delete
+ * */
+ recyclerView.addOnItemTouchListener(new RecyclerTouchListener(this,
+ recyclerView, new RecyclerTouchListener.ClickListener() {
+ @Override
+ public void onClick(View view, final int position) {
+ }
+
+ @Override
+ public void onLongClick(View view, int position) {
+ }
+ }));
+
+ addToWhiteListFab.setOnClickListener(this::showFabDialog);
+ fetchWhiteListedUsers();
+ handleSwitch();
+ }
+
+ private Observable> getListOfWhitelistedUsers(String userId) {
+ return userService.getTutorWhitelistedByID(userId)
+ .toObservable()
+ .subscribeOn(Schedulers.io())
+ .observeOn(AndroidSchedulers.mainThread());
+ }
+
+ private Observable getUserObservable(String userId) {
+ return userService
+ .getUserById(userId)
+ .toObservable()
+ .subscribeOn(Schedulers.io())
+ .observeOn(AndroidSchedulers.mainThread());
+ }
+
+ private void fetchWhiteListedUsers() {
+ prevSize = whitelistedUsers.size();
+ whitelistedUsers.clear();
+
+ disposable.add(getListOfWhitelistedUsers(tutorId)
+ .subscribeOn(Schedulers.io())
+ .observeOn(AndroidSchedulers.mainThread())
+ .flatMap((Function, Observable>) Observable::fromIterable)
+ .flatMap((Function>) this::getUserObservable)
+ .subscribeWith(new DisposableObserver() {
+ @Override
+ public void onNext(User user) {
+ whitelistedUsers.add(user);
+ }
+
+ @Override
+ public void onError(Throwable e) {
+ showError(e);
+ }
+
+ @Override
+ public void onComplete() {
+ Collections.sort(whitelistedUsers, (a, b) -> sortByUserName(a,b));
+ refreshUI();
+ }
+ }));
+ }
+
+ private void refreshUI(){
+ toggleEmptyNotes();
+ mAdapter.notifyItemRangeInserted(prevSize, whitelistedUsers.size() - prevSize);
+ mAdapter.notifyDataSetChanged();
+ }
+
+ private int sortByUserName(User t1, User t2) {
+ return plCollator.compare(t1.getLastName(), t2.getLastName());
+ }
+
+ private void showFabDialog(View v){
+ LayoutInflater layoutInflaterAndroid = LayoutInflater.from(getApplicationContext());
+ @SuppressLint("InflateParams") View view = layoutInflaterAndroid.inflate(R.layout.white_list_fab_modal, null);
+ AlertDialog.Builder alertDialogBuilderUserInput = new AlertDialog.Builder(this);
+
+ alertDialogBuilderUserInput.setView(view).setPositiveButton(getApplicationContext().getString(R.string.modal_location_send), null);
+
+ alertDialogBuilderUserInput
+ .setPositiveButton(R.string.add, null)
+ .setNegativeButton(R.string.cancel, null);
+
+ final AlertDialog alertDialog = alertDialogBuilderUserInput.create();
+ alertDialog.getWindow().setSoftInputMode(WindowManager.LayoutParams.SOFT_INPUT_STATE_VISIBLE);
+
+ EditText modalUserInput = view.findViewById(R.id.white_list_modal_input);
+
+ alertDialog.setOnShowListener(dialogInterface -> {
+ Button sendButton = alertDialog.getButton(AlertDialog.BUTTON_POSITIVE);
+
+ Button dismissButton = alertDialog.getButton(AlertDialog.BUTTON_NEGATIVE);
+
+ dismissButton.setOnClickListener(view1 -> alertDialog.dismiss());
+
+ sendButton.setOnClickListener(view1 -> {
+ String body = modalUserInput.getText().toString();
+
+ if (TextUtils.isEmpty(body)) {
+ Toast.makeText(getApplicationContext(), R.string.can_not_be_empty, Toast.LENGTH_SHORT).show();
+ modalUserInput.requestFocus();
+ } else {
+ sendUserToWhitelist(body);
+ alertDialog.dismiss();
+ }
+ });
+ });
+
+ alertDialog.show();
+ }
+
+ private void sendUserToWhitelist(String body) {
+ StudentIdModel studentIdModel = new StudentIdModel(body);
+
+ disposable.add(
+ userService.addStudentToWhitelist(tutorId, studentIdModel)
+ .subscribeOn(Schedulers.io())
+ .observeOn(AndroidSchedulers.mainThread())
+ .subscribe(this::handleAddUser,this::showError)
+ );
+ }
+
+ private void handleAddUser(User user) {
+ Toast.makeText(this, R.string.add_user_to_list, Snackbar.LENGTH_LONG).show();
+ fetchWhiteListedUsers();
+ }
+
+ private void showError(Throwable e) {
+ String message;
+
+ if (e instanceof HttpException) {
+ ResponseBody responseBody = ((HttpException) e).response().errorBody();
+ message = RestApiHelper.getErrorMessage(responseBody);
+ if (((HttpException) e).response().code() == 404) {
+ message = getString(R.string.no_such_a_user);
+ }
+ } else {
+ message = "Network Error !";
+ }
+ Log.e("ERR",message);
+ Toast.makeText(this, message, Snackbar.LENGTH_LONG).show();
+ }
+
+ private void toggleEmptyNotes() {
+ if (didFetched && whitelistedUsers.size() == 0) {
+ noNotesView.setText(R.string.list_is_empty);
+ noNotesView.setVisibility(View.VISIBLE);
+ }else if (whitelistedUsers.size() > 0) {
+ noNotesView.setVisibility(View.GONE);
+ } else {
+ noNotesView.setText(getString(R.string.loading));
+ noNotesView.setVisibility(View.VISIBLE);
+ }
+ }
+
+
+ @Override
+ public boolean onOptionsItemSelected(MenuItem item) {
+
+ if (item.getItemId()==R.id.action_whitelist_info_popup){
+ int layoutID = R.layout.info_popup_whitelist;
+
+ View popupView = getLayoutInflater().inflate(layoutID,null);
+
+ PopupWindow popupWindow = new PopupWindow(popupView,
+ LinearLayout.LayoutParams.WRAP_CONTENT, LinearLayout.LayoutParams.WRAP_CONTENT);
+ // If the PopupWindow should be focusable
+ popupWindow.setFocusable(true);
+ // If you need the PopupWindow to dismiss when when touched outside
+ popupWindow.setBackgroundDrawable(new ColorDrawable());
+ // Get the View's(the one that was clicked in the Fragment) location
+ View anchorView= getWindow().getDecorView().findViewById(android.R.id.content);
+ popupWindow.showAtLocation(anchorView,Gravity.TOP|Gravity.END, 0, 0);
+ }
+
+ return super.onOptionsItemSelected(item);
+ }
+
+ private void handleSwitch(){
+ aSwitch.setOnCheckedChangeListener((buttonView, isChecked) -> {
+ if (isChecked){
+ aSwitch.setText(getString(R.string.action_white_list) + " "+ getString(R.string.on));
+ handleChangeRequest(true);
+ PrefUtils.useWhitelist(this, true);
+ }else {
+ aSwitch.setText(getString(R.string.action_white_list) + " "+getString(R.string.off));
+ handleChangeRequest(false);
+ PrefUtils.useWhitelist(this, false);
+ }
+ });
+ }
+
+ private void handleChangeRequest(boolean value){
+ IsUsingListBool isUsingListBool = new IsUsingListBool();
+ isUsingListBool.setIsUsing(value);
+ disposable.add(
+ userService.setTutorWhitelist(tutorId, isUsingListBool)
+ .subscribeOn(Schedulers.io())
+ .observeOn(AndroidSchedulers.mainThread())
+ .subscribe(()->{
+ },this::showError)
+ );
+ }
+
+ @Override
+ public void onResume() {
+ super.onResume();
+ }
+
+ @Override
+ public void onPause() {
+ super.onPause();
+ }
+
+ @Override
+ public void onStop() {
+ super.onStop();
+ }
+
+ @Override
+ public void onDestroy() {
+ super.onDestroy();
+ disposable.dispose();
+ }
+
+ @Override
+ public boolean onCreateOptionsMenu(Menu menu) {
+ getMenuInflater().inflate(R.menu.menu_white_list, menu);
+ return true;
+ }
+}
diff --git a/app/src/main/java/com/uam/wmi/findmytutor/adapters/BlackListAdapter.java b/app/src/main/java/com/uam/wmi/findmytutor/adapters/BlackListAdapter.java
new file mode 100644
index 0000000..f42c9a7
--- /dev/null
+++ b/app/src/main/java/com/uam/wmi/findmytutor/adapters/BlackListAdapter.java
@@ -0,0 +1,119 @@
+package com.uam.wmi.findmytutor.adapters;
+
+import android.content.Context;
+import android.graphics.drawable.Drawable;
+import android.support.annotation.NonNull;
+import android.support.design.widget.Snackbar;
+import android.support.v7.widget.RecyclerView;
+import android.util.Log;
+import android.view.LayoutInflater;
+import android.view.View;
+import android.view.ViewGroup;
+import android.widget.ImageButton;
+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.model.StudentIdModel;
+import com.uam.wmi.findmytutor.model.User;
+import com.uam.wmi.findmytutor.network.ApiClient;
+import com.uam.wmi.findmytutor.service.UserService;
+import com.uam.wmi.findmytutor.utils.PrefUtils;
+import com.uam.wmi.findmytutor.utils.RestApiHelper;
+
+import java.util.List;
+
+import butterknife.BindView;
+import butterknife.ButterKnife;
+import io.reactivex.android.schedulers.AndroidSchedulers;
+import io.reactivex.disposables.CompositeDisposable;
+import io.reactivex.schedulers.Schedulers;
+import okhttp3.ResponseBody;
+
+import static com.mapbox.mapboxsdk.Mapbox.getApplicationContext;
+
+
+public class BlackListAdapter extends RecyclerView.Adapter {
+
+ private Context context;
+ private List tutorsList;
+ private CompositeDisposable disposable = new CompositeDisposable();
+ private UserService userService;
+
+ public BlackListAdapter(Context context, List tutors) {
+ this.context = context;
+ this.tutorsList = tutors;
+ }
+
+ @NonNull
+ @Override
+ public MyViewHolder onCreateViewHolder(@NonNull ViewGroup parent, int viewType) {
+ userService = ApiClient.getClient(getApplicationContext())
+ .create(UserService.class);
+ View itemView = LayoutInflater.from(parent.getContext())
+ .inflate(R.layout.black_list_row, parent, false);
+
+ return new MyViewHolder(itemView);
+ }
+
+ @Override
+ public void onBindViewHolder(@NonNull MyViewHolder holder, int position) {
+ Drawable image = null;
+ User tutor = tutorsList.get(position);
+
+ holder.firstName.setText(tutor.getFirstName() + " " + tutor.getLastName());
+ holder.lastName.setText("Index: " + tutor.getLdapLogin() + " Email: " + tutor.getEmail());
+//"s416196"
+ holder.imageButton.setOnClickListener(l ->{
+ StudentIdModel studentIdModel = new StudentIdModel(tutor.getLdapLogin());
+ String tutorId = PrefUtils.getUserId(getApplicationContext());
+ disposable.add(
+ userService.removeStudentFromBlacklist(tutorId, studentIdModel)
+ .subscribeOn(Schedulers.io())
+ .observeOn(AndroidSchedulers.mainThread())
+ .subscribe(()->{
+ Toast.makeText(getApplicationContext(), R.string.user_removed, Toast.LENGTH_SHORT).show();
+ tutorsList.remove(position);
+ notifyDataSetChanged();
+ },this::showError)
+ );
+ });
+ }
+
+ @Override
+ public int getItemCount() {
+ return tutorsList.size();
+ }
+
+ class MyViewHolder extends RecyclerView.ViewHolder {
+
+ @BindView(R.id.firstName)
+ TextView firstName;
+
+ @BindView(R.id.lastName)
+ TextView lastName;
+
+ @BindView(R.id.removeUserImageButton)
+ ImageButton imageButton;
+
+ MyViewHolder(View view) {
+ super(view);
+ ButterKnife.bind(this, view);
+ }
+ }
+
+ private void showError(Throwable e) {
+ String message;
+
+ if (e instanceof HttpException) {
+ ResponseBody responseBody = ((HttpException) e).response().errorBody();
+ message = RestApiHelper.getErrorMessage(responseBody);
+ } else {
+ message = "Network Error !";
+ }
+
+ Toast.makeText(getApplicationContext(), message, Toast.LENGTH_SHORT).show();
+
+ }
+}
\ No newline at end of file
diff --git a/app/src/main/java/com/uam/wmi/findmytutor/adapters/DutyHoursAdapter.java b/app/src/main/java/com/uam/wmi/findmytutor/adapters/DutyHoursAdapter.java
index ae2d465..eaa95f1 100644
--- a/app/src/main/java/com/uam/wmi/findmytutor/adapters/DutyHoursAdapter.java
+++ b/app/src/main/java/com/uam/wmi/findmytutor/adapters/DutyHoursAdapter.java
@@ -11,12 +11,10 @@ import android.view.View;
import android.view.ViewGroup;
import android.widget.ImageButton;
import android.widget.TextView;
-
import com.annimon.stream.Collectors;
import com.annimon.stream.Stream;
import com.uam.wmi.findmytutor.R;
import com.uam.wmi.findmytutor.model.DutyHourViewModel;
-
import java.util.ArrayList;
import java.util.List;
import butterknife.BindView;
@@ -29,7 +27,7 @@ public class DutyHoursAdapter extends RecyclerView.Adapter hours) {
this.context = context;
- this.hours = new ArrayList(hours);
+ this.hours = new ArrayList<>(hours);
}
@@ -114,16 +112,16 @@ public class DutyHoursAdapter extends RecyclerView.Adapter {
+
+ private Context context;
+ private List tutorsList;
+ private CompositeDisposable disposable = new CompositeDisposable();
+ private UserService userService;
+
+ public WhiteListAdapter(Context context, List tutors) {
+ this.context = context;
+ this.tutorsList = tutors;
+ }
+ @NonNull
+ @Override
+ public MyViewHolder onCreateViewHolder(@NonNull ViewGroup parent, int viewType) {
+ userService = ApiClient.getClient(getApplicationContext())
+ .create(UserService.class);
+ View itemView = LayoutInflater.from(parent.getContext())
+ .inflate(R.layout.white_list_row, parent, false);
+
+ return new MyViewHolder(itemView);
+ }
+
+ @Override
+ public void onBindViewHolder(@NonNull MyViewHolder holder, int position) {
+ Drawable image = null;
+ User tutor = tutorsList.get(position);
+
+ holder.firstName.setText(tutor.getFirstName() + " " + tutor.getLastName());
+ holder.lastName.setText("Index: " + tutor.getLdapLogin() + " Email: " + tutor.getEmail());
+//""
+ holder.imageButton.setOnClickListener(l ->{
+ StudentIdModel studentIdModel = new StudentIdModel(tutor.getLdapLogin());
+ String tutorId = PrefUtils.getUserId(getApplicationContext());
+ disposable.add(
+ userService.removeStudentFromWhitelist(tutorId, studentIdModel)
+ .subscribeOn(Schedulers.io())
+ .observeOn(AndroidSchedulers.mainThread())
+ .subscribe(()->{
+ Toast.makeText(getApplicationContext(), R.string.user_removed, Toast.LENGTH_SHORT).show();
+ tutorsList.remove(position);
+ notifyDataSetChanged();
+ },this::showError)
+ );
+ });
+
+ }
+
+ @Override
+ public int getItemCount() {
+ return tutorsList.size();
+ }
+
+ class MyViewHolder extends RecyclerView.ViewHolder {
+
+ @BindView(R.id.firstName)
+ TextView firstName;
+
+ @BindView(R.id.lastName)
+ TextView lastName;
+
+ @BindView(R.id.removeUserImageButton)
+ ImageButton imageButton;
+
+ MyViewHolder(View view) {
+ super(view);
+ ButterKnife.bind(this, view);
+ }
+ }
+
+ private void showError(Throwable e) {
+ String message;
+
+ if (e instanceof HttpException) {
+ ResponseBody responseBody = ((HttpException) e).response().errorBody();
+ message = RestApiHelper.getErrorMessage(responseBody);
+ } else {
+ message = "Network Error !";
+ }
+ Toast.makeText(getApplicationContext(), message, Toast.LENGTH_SHORT).show();
+
+ }
+
+}
\ No newline at end of file
diff --git a/app/src/main/java/com/uam/wmi/findmytutor/model/StudentIdModel.java b/app/src/main/java/com/uam/wmi/findmytutor/model/StudentIdModel.java
index 3eea407..ab1f37c 100644
--- a/app/src/main/java/com/uam/wmi/findmytutor/model/StudentIdModel.java
+++ b/app/src/main/java/com/uam/wmi/findmytutor/model/StudentIdModel.java
@@ -18,6 +18,15 @@ public class StudentIdModel extends BaseResponse{
@SerializedName("ldapLogin")
private String ldapLogin = null;
+ /**
+ *
+ * @param str
+ */
+ public StudentIdModel(String str){
+// this.studentId = str;
+ this.ldapLogin = str;
+ }
+
public StudentIdModel studentId(String studentId) {
this.studentId = studentId;
return this;
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 0417d17..81fecf3 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
@@ -11,12 +11,13 @@ import android.content.Intent;
import android.content.pm.PackageManager;
import android.graphics.Color;
import android.location.Location;
+import android.location.LocationListener;
import android.location.LocationManager;
import android.os.AsyncTask;
import android.os.Build;
-import android.os.Bundle;
import android.os.Handler;
import android.os.IBinder;
+import android.os.Looper;
import android.support.annotation.RequiresApi;
import android.support.v4.app.ActivityCompat;
import android.support.v4.app.NotificationCompat;
@@ -24,8 +25,10 @@ import android.util.Log;
import com.annimon.stream.Stream;
import com.google.android.gms.location.FusedLocationProviderClient;
+import com.google.android.gms.location.LocationCallback;
+import com.google.android.gms.location.LocationRequest;
+import com.google.android.gms.location.LocationResult;
import com.google.android.gms.location.LocationServices;
-import com.jakewharton.retrofit2.adapter.rxjava2.HttpException;
import com.mapbox.geojson.Point;
import com.mapbox.mapboxsdk.geometry.LatLng;
import com.uam.wmi.findmytutor.model.Coordinate;
@@ -33,21 +36,17 @@ import com.uam.wmi.findmytutor.network.ApiClient;
import com.uam.wmi.findmytutor.utils.ApproximatedLocalization;
import com.uam.wmi.findmytutor.utils.MapUtils;
import com.uam.wmi.findmytutor.utils.PrefUtils;
-import com.uam.wmi.findmytutor.utils.RestApiHelper;
import com.uam.wmi.findmytutor.utils.SharingLevel;
import org.apache.commons.collections4.queue.CircularFifoQueue;
import java.util.ArrayList;
import java.util.List;
-import java.util.concurrent.atomic.AtomicReference;
import io.reactivex.android.schedulers.AndroidSchedulers;
import io.reactivex.disposables.CompositeDisposable;
import io.reactivex.observers.DisposableCompletableObserver;
-import io.reactivex.observers.DisposableSingleObserver;
import io.reactivex.schedulers.Schedulers;
-import okhttp3.ResponseBody;
import static com.uam.wmi.findmytutor.utils.Const.offlineBackgroundLocationInterval;
import static com.uam.wmi.findmytutor.utils.Const.onlineBackgroundLocationInterval;
@@ -60,32 +59,33 @@ import static java.lang.String.valueOf;
public class BackgroundLocalizationService extends Service {
private static final String TAG = "MyLocationService";
- private static final float LOCATION_DISTANCE = 1f;
- private static long notify_interval = onlineBackgroundLocationInterval;
- private static long notify_interval_inside_building = onlineBackgroundLocationInterval;
- private static long notify_interval_outside_building = offlineBackgroundLocationInterval;
- private static int coordinatesHistoryLength = 5;
- private static final Long LOCATION_INTERVAL = notify_interval;
+ private static Integer notify_interval = onlineBackgroundLocationInterval;
+ private static Integer notify_interval_inside_building = onlineBackgroundLocationInterval;
+ private static Integer notify_interval_outside_building = offlineBackgroundLocationInterval;
+ private static int coordinatesHistoryLength = 10;
+ private Boolean highAccuracyMode;
private Location mLastLocation;
private Boolean stopService = false;
private ArrayList providers = new ArrayList();
- private LocationListener[] mLocationListeners;
private CircularFifoQueue coordinatesHistory = new CircularFifoQueue(coordinatesHistoryLength);
- private LocationManager mLocationManager = null;
private Handler mHandler = new Handler();
private Runnable mStatusChecker;
private FusedLocationProviderClient mFusedLocationClient;
+ private Location fakeLoc = null;
+ private LocationRequest mLocationRequest;
+ private Location mCurrentLocation;
+ private LocationCallback mLocationCallback;
+ private LocationListener mLocationListener;
public BackgroundLocalizationService() {
providers.add(LocationManager.GPS_PROVIDER);
providers.add(LocationManager.NETWORK_PROVIDER);
providers.add(LocationManager.PASSIVE_PROVIDER);
+ fakeLoc = new Location("");
- mLocationListeners = new LocationListener[]{
- new LocationListener(LocationManager.GPS_PROVIDER),
- new LocationListener(LocationManager.NETWORK_PROVIDER),
- new LocationListener(LocationManager.PASSIVE_PROVIDER)
- };
+ fakeLoc.setLatitude(0);
+ fakeLoc.setLongitude(0);
+ fakeLoc.setAltitude(0);
}
@Override
@@ -100,7 +100,9 @@ public class BackgroundLocalizationService extends Service {
if (intent != null) {
stopService = intent.getBooleanExtra("request_stop", false);
+ notify_interval = intent.getIntExtra("notify_interval", onlineBackgroundLocationInterval);
}
+
if (stopService) {
storeBackgroundLocationStatus(getApplication(), false);
stopForeground(true);
@@ -111,6 +113,20 @@ public class BackgroundLocalizationService extends Service {
return START_STICKY;
}
+ private void createLocationCallback() {
+ mLocationCallback = new LocationCallback() {
+ @Override
+ public void onLocationResult(LocationResult locationResult) {
+ super.onLocationResult(locationResult);
+ if (locationResult != null) {
+ mCurrentLocation = locationResult.getLastLocation();
+ sendCoordinateToBackend(mCurrentLocation);
+ changeBackgroundMode();
+ }
+ }
+ };
+ }
+
@Override
public void onCreate() {
Log.e(TAG, "onCreate");
@@ -124,35 +140,13 @@ public class BackgroundLocalizationService extends Service {
startForeground(1001, notification);
}
- mFusedLocationClient = LocationServices.getFusedLocationProviderClient(this);
-
- initializeLocationManager();
-
- Integer providerIndex = 0;
-
- for (LocationListener listener : mLocationListeners) {
- try {
- mLocationManager.requestLocationUpdates(
- providers.get(providerIndex),
- LOCATION_INTERVAL,
- LOCATION_DISTANCE,
- listener
- );
-
- } catch (java.lang.SecurityException ex) {
- Log.i(TAG, "fail to request location update, ignore", ex);
- } catch (IllegalArgumentException ex) {
- Log.d(TAG, "network provider does not exist, " + ex.getMessage());
- }
-
- providerIndex++;
- }
-
- if (!stopService) {
+ if (!stopService && !PrefUtils.getLocationLevel(getApplicationContext()).equals(SharingLevel.MANUAL.toString())) {
+ createFusedLocationClient();
+ } else if (!stopService &&
+ PrefUtils.getLocationLevel(getApplicationContext()).equals(SharingLevel.MANUAL.toString())) {
mStatusChecker = () -> {
try {
- getLocalizationFromListeners();
- changeBackgroundMode();
+ sendCoordinateToBackend(fakeLoc);
} finally {
mHandler.postDelayed(mStatusChecker, notify_interval);
}
@@ -162,19 +156,52 @@ public class BackgroundLocalizationService extends Service {
}
}
+ private void createFusedLocationClient() {
+ Integer saveMode = Long.valueOf(notify_interval).compareTo(Long.valueOf(offlineBackgroundLocationInterval));
+
+ if (ActivityCompat.checkSelfPermission(this, Manifest.permission.ACCESS_FINE_LOCATION) != PackageManager.PERMISSION_GRANTED && ActivityCompat.checkSelfPermission(this, Manifest.permission.ACCESS_COARSE_LOCATION) != PackageManager.PERMISSION_GRANTED) {
+ return;
+ }
+
+ mLocationRequest = new LocationRequest();
+
+ if (saveMode != 0) {
+ mLocationRequest.setPriority(LocationRequest.PRIORITY_HIGH_ACCURACY);
+ } else {
+ mLocationRequest.setPriority(LocationRequest.PRIORITY_BALANCED_POWER_ACCURACY);
+ }
+
+ mLocationRequest.setFastestInterval(notify_interval);
+ mLocationRequest.setInterval(notify_interval);
+
+ createLocationCallback();
+
+ if (!stopService) {
+ mFusedLocationClient = LocationServices.getFusedLocationProviderClient(this);
+ mFusedLocationClient.requestLocationUpdates(mLocationRequest,
+ mLocationCallback, Looper.getMainLooper());
+ }
+ }
+
private void changeBackgroundMode() {
- if (coordinatesHistory.size() > 4) {
- Boolean shouldExtendTimeInterval = Stream.of(coordinatesHistory)
- .map(MapUtils::checkIfCoordinateIsValid).takeWhile(s -> !s).toList().size() == coordinatesHistory.size();
+ Integer prevInterval = notify_interval;
+ Boolean shouldExtendTimeInterval = Stream.of(coordinatesHistory)
+ .map(MapUtils::checkIfCoordinateIsValid).takeWhile(s -> !s).toList().size() == coordinatesHistory.size();
- Boolean shouldAbbreviateTimeInterval = Stream.of(coordinatesHistory).
- map(MapUtils::checkIfCoordinateIsValid).toList().get(coordinatesHistory.size() - 1);
+ Boolean shouldAbbreviateTimeInterval = Stream.of(coordinatesHistory).
+ map(MapUtils::checkIfCoordinateIsValid).filter(x -> x).toList().size() > 0;
- if (shouldExtendTimeInterval) {
- notify_interval = notify_interval_outside_building;
- } else if (shouldAbbreviateTimeInterval) {
- notify_interval = notify_interval_inside_building;
- }
+ if (shouldAbbreviateTimeInterval) {
+ notify_interval = notify_interval_inside_building;
+ }
+
+ if (coordinatesHistory.size() > coordinatesHistoryLength && shouldExtendTimeInterval) {
+ notify_interval = notify_interval_outside_building;
+ }
+
+ Integer changedMode = Long.valueOf(prevInterval).compareTo(Long.valueOf(notify_interval));
+ if (changedMode != 0) {
+ updateListeners();
}
}
@@ -198,50 +225,6 @@ public class BackgroundLocalizationService extends Service {
startForeground(2, notification);
}
- private void getLocalizationFromListeners() {
- if (ActivityCompat.checkSelfPermission(this, Manifest.permission.ACCESS_FINE_LOCATION) != PackageManager.PERMISSION_GRANTED && ActivityCompat.checkSelfPermission(this, Manifest.permission.ACCESS_COARSE_LOCATION) != PackageManager.PERMISSION_GRANTED) {
- // TODO: Consider calling
- // ActivityCompat#requestPermissions
- // here to request the missing permissions, and then overriding
- // public void onRequestPermissionsResult(int requestCode, String[] permissions,
- // int[] grantResults)
- // to handle the case where the user grants the permission. See the documentation
- // for ActivityCompat#requestPermissions for more details.
- return;
- }
-
- List providers1 = mLocationManager.getProviders(true);
- Location bestLocation = null;
- AtomicReference triggerAnotherLocationListener = new AtomicReference<>(false);
-
- mFusedLocationClient.getLastLocation().addOnSuccessListener(
- location -> {
- if (location != null) {
- mLastLocation = location;
- coordinatesHistory.add(location);
- sendCoordinateToBackend(location);
- }
-
- triggerAnotherLocationListener.set(true);
- });
-
- if (triggerAnotherLocationListener.get()) {
- for (String provider : providers1) {
- Location location = mLocationManager.getLastKnownLocation(provider);
-
- if (location == null) {
- continue;
- }
- if (bestLocation == null || location.getAccuracy() < bestLocation.getAccuracy()) {
- bestLocation = location;
- }
- }
-
- coordinatesHistory.add(bestLocation);
- }
-
- }
-
private void sendCoordinateToBackend(Location location) {
new Task(location).execute();
}
@@ -252,59 +235,49 @@ public class BackgroundLocalizationService extends Service {
super.onDestroy();
mHandler.removeCallbacks(mStatusChecker);
+ destroyLocationListeners();
+ }
- if (mLocationManager != null) {
- for (LocationListener listener : mLocationListeners) {
- try {
- if (ActivityCompat.checkSelfPermission(this, android.Manifest.permission.ACCESS_FINE_LOCATION) != PackageManager.PERMISSION_GRANTED && ActivityCompat.checkSelfPermission(this, android.Manifest.permission.ACCESS_COARSE_LOCATION) != PackageManager.PERMISSION_GRANTED) {
- return;
- }
- mLocationManager.removeUpdates(listener);
-
- } catch (Exception ex) {
- Log.i(TAG, "fail to remove location listener, ignore", ex);
- }
- }
+ private void destroyLocationListeners() {
+ if (mFusedLocationClient != null) {
+ mFusedLocationClient.removeLocationUpdates(mLocationCallback);
+ mFusedLocationClient = null;
+ mLocationCallback = null;
+ mLocationRequest = null;
}
}
- private void initializeLocationManager() {
- Log.e(TAG, "initializeLocationManager - LOCATION_INTERVAL: " + LOCATION_INTERVAL + " LOCATION_DISTANCE: " + LOCATION_DISTANCE);
-
- if (mLocationManager == null) {
- mLocationManager = (LocationManager) getApplicationContext().getSystemService(Context.LOCATION_SERVICE);
+ private void updateListeners() {
+ if (mFusedLocationClient != null) {
+ mFusedLocationClient.removeLocationUpdates(mLocationCallback)
+ .addOnCompleteListener(task -> {
+ restartService();
+ mFusedLocationClient = null;
+ mLocationCallback = null;
+ mLocationRequest = null;
+ });
}
}
-
- private class LocationListener implements android.location.LocationListener {
- LocationListener(String provider) {
- Log.e(TAG, "LocationListener " + provider);
- mLastLocation = new Location(provider);
+ private void restartService() {
+
+ Intent stopIntent = new Intent(getApplicationContext(), BackgroundLocalizationService.class);
+ stopIntent.putExtra("request_stop", true);
+
+ stopService(stopIntent);
+
+ Intent startIntent = new Intent(getApplicationContext(), BackgroundLocalizationService.class);
+ startIntent.putExtra("notify_interval", notify_interval);
+
+ if (Build.VERSION.SDK_INT > Build.VERSION_CODES.O) {
+ startForegroundService(startIntent);
+ } else {
+ startService(startIntent);
}
- @Override
- public void onLocationChanged(Location location) {
- Log.e(TAG, "onLocationChanged: " + location);
- mLastLocation.set(location);
- }
-
- @Override
- public void onProviderDisabled(String provider) {
- Log.e(TAG, "onProviderDisabled: " + provider);
- }
-
- @Override
- public void onProviderEnabled(String provider) {
- Log.e(TAG, "onProviderEnabled: " + provider);
- }
-
- @Override
- public void onStatusChanged(String provider, int status, Bundle extras) {
- Log.e(TAG, "onStatusChanged: " + provider);
- }
}
+
@SuppressLint("StaticFieldLeak")
private class Task extends AsyncTask {
private ApproximatedLocalization approximatedLocalization;
@@ -320,6 +293,7 @@ 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));
}
@@ -330,9 +304,8 @@ public class BackgroundLocalizationService extends Service {
String locationLevel = PrefUtils.getLocationLevel(getApplicationContext());
String status = (PrefUtils.isStatusEnabled(getApplicationContext())) ? PrefUtils.getUserStatus(getApplicationContext()) : "";
-
if (locationLevel.equals(SharingLevel.PRESENCE.toString())) {
- if(!MapUtils.checkIfCoordinateIsValid(latitude,longitude)){
+ if (!MapUtils.checkIfCoordinateIsValid(latitude, longitude)) {
return null;
}
@@ -350,6 +323,12 @@ public class BackgroundLocalizationService extends Service {
approximatedBuildingPart = PrefUtils.getManualLocationApproximation(getApplicationContext());
}
+ Location fakeLoc = new Location("");
+
+ fakeLoc.setLatitude(latitude);
+ fakeLoc.setLongitude(longitude);
+ coordinatesHistory.add(fakeLoc);
+
try {
Coordinate coordinate = new Coordinate(
latitude,
@@ -367,7 +346,6 @@ public class BackgroundLocalizationService extends Service {
.subscribeOn(Schedulers.io())
.observeOn(AndroidSchedulers.mainThread())
.subscribeWith(new DisposableCompletableObserver() {
-
@Override
public void onComplete() {
Log.e(TAG, "CoordinateSuccess");
@@ -375,9 +353,7 @@ public class BackgroundLocalizationService extends Service {
@Override
public void onError(Throwable e) {
-
- Log.e(TAG,"onErr" + valueOf(e));
-
+ Log.e(TAG, "onErr" + valueOf(e));
}
}));
} catch (IllegalArgumentException e) {
diff --git a/app/src/main/java/com/uam/wmi/findmytutor/service/PredefinedCoordinatesService.java b/app/src/main/java/com/uam/wmi/findmytutor/service/PredefinedCoordinatesService.java
new file mode 100644
index 0000000..0ea2b7b
--- /dev/null
+++ b/app/src/main/java/com/uam/wmi/findmytutor/service/PredefinedCoordinatesService.java
@@ -0,0 +1,24 @@
+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.HTTP;
+import retrofit2.http.POST;
+import retrofit2.http.Path;
+
+public interface PredefinedCoordinatesService {
+ @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);
+
+ @HTTP(method = "DELETE", path = "api/users/predefined/coordinate/{tutorId}", hasBody = true)
+ Single> deleteUserPredefinedCoord(@Path("tutorId") String tutorId, @Body String uuid);
+}
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
index 5af0c22..2a3e8cf 100644
--- a/app/src/main/java/com/uam/wmi/findmytutor/service/PredefinedStatusesService.java
+++ b/app/src/main/java/com/uam/wmi/findmytutor/service/PredefinedStatusesService.java
@@ -5,25 +5,27 @@ import io.reactivex.Single;
import retrofit2.http.Body;
import retrofit2.http.DELETE;
import retrofit2.http.GET;
+import retrofit2.http.HTTP;
import retrofit2.http.POST;
import retrofit2.http.Path;
-public interface PredefinedStatusesService {
+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}")
+// @DELETE("api/users/predefined/status/{tutorId}")
+ @HTTP(method = "DELETE", path = "api/users/predefined/status/{tutorId}", hasBody = true)
Single> deleteUserPredefinedStatus(@Path("tutorId") String tutorId, @Body String status);
- @GET("api/users/predefined/coordinate/{tutorId}")
+/* @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);
+ 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 75671ed..f4092b4 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
@@ -10,14 +10,17 @@ import java.util.List;
import io.reactivex.Completable;
import io.reactivex.Observable;
+import io.reactivex.ObservableEmitter;
import io.reactivex.Single;
import retrofit2.Response;
import retrofit2.http.Body;
import retrofit2.http.DELETE;
import retrofit2.http.GET;
+import retrofit2.http.HTTP;
import retrofit2.http.POST;
import retrofit2.http.PUT;
import retrofit2.http.Path;
+import retrofit2.http.Query;
public interface UserService {
@@ -30,6 +33,18 @@ public interface UserService {
@GET("api/users/tutors")
Single > getAllTutors();
+ @GET("api/users/tutors/online")
+ Single > getAllOnlineTutors();
+
+ @GET("api/users/tutors/active")
+ Single > getAllActiveTutors();
+
+ @GET("api/users/tutors/offline")
+ Single > getAllOfflineTutors();
+
+ @GET("api/users/tutors/search")
+ Single > searchUser(@Query(value = "searchString", encoded = true) String searchString);
+
@POST("api/users")
Completable createUser(@Body User user);
@@ -61,26 +76,28 @@ public interface UserService {
Completable setUserInActive(@Path("userID") String userID);
@GET("api/users/blacklist/{tutorID}")
- Single> getTutorBlacklistedByID(@Path("tutorID") String tutorID);
+ Single > getTutorBlacklistedByID(@Path("tutorID") String tutorID);
@PUT("api/users/blacklist/{tutorID}")
Completable setTutorBlacklist(@Path("tutorID") String tutorID, @Body IsUsingListBool isUsing);
@POST("api/users/blacklist/{tutorID}")
- Completable addStudentToBlacklist(@Path("tutorID") String tutorID, @Body StudentIdModel student);
+ Observable addStudentToBlacklist(@Path("tutorID") String tutorID, @Body StudentIdModel student);
- @DELETE("api/users/blacklist/{tutorID}")
+// @DELETE("api/users/blacklist/{tutorID}")
+ @HTTP(method = "DELETE", path = "api/users/blacklist/{tutorID}", hasBody = true)
Completable removeStudentFromBlacklist(@Path("tutorID") String tutorID, @Body StudentIdModel student);
@GET("api/users/whitelist/{tutorID}")
- Single> getTutorwhitelistedByID(@Path("tutorID") String tutorID);
+ Single> getTutorWhitelistedByID(@Path("tutorID") String tutorID);
@PUT("api/users/whitelist/{tutorID}")
Completable setTutorWhitelist(@Path("tutorID") String tutorID, @Body IsUsingListBool isUsing);
@POST("api/users/whitelist/{tutorID}")
- Completable addStudentTowhitelist(@Path("tutorID") String tutorID, @Body StudentIdModel student);
+ Observable addStudentToWhitelist(@Path("tutorID") String tutorID, @Body StudentIdModel student);
- @DELETE("api/users/whitelist/{tutorID}")
+// @DELETE("api/users/whitelist/{tutorID}")
+ @HTTP(method = "DELETE", path = "api/users/whitelist/{tutorID}", hasBody = true)
Completable removeStudentFromWhitelist(@Path("tutorID") String tutorID, @Body StudentIdModel student);
}
diff --git a/app/src/main/java/com/uam/wmi/findmytutor/utils/Const.java b/app/src/main/java/com/uam/wmi/findmytutor/utils/Const.java
index 48fd35f..b6c0dab 100644
--- a/app/src/main/java/com/uam/wmi/findmytutor/utils/Const.java
+++ b/app/src/main/java/com/uam/wmi/findmytutor/utils/Const.java
@@ -7,8 +7,9 @@ import java.util.List;
public class Const {
public final static String BASE_URL = "https://s416084.projektstudencki.pl/master/";
+ public final static Integer mapRefreshInterval = 6000;
public final static Integer onlineBackgroundLocationInterval = 7000;
- public final static Integer offlineBackgroundLocationInterval = 36000;
+ public final static Integer offlineBackgroundLocationInterval = 360000;
public final static Integer defaultMapZoom = 17;
public final static Integer searchMapZoom = 13;
public final static Double presenceLatitude = 52.466365;
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 5d45d85..2ae7c57 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
@@ -60,6 +60,16 @@ public class PrefUtils {
return getSharedPreferences(context).getBoolean("key_status_enabled", false);
}
+ public static void enableStatus(Context context){
+ SharedPreferences.Editor editor = getSharedPreferences(context).edit();
+ editor.putBoolean("key_status_enabled", true);
+ editor.apply();
+ }
+ public static void disableStatus(Context context) {
+ SharedPreferences.Editor editor = getSharedPreferences(context).edit();
+ editor.putBoolean("key_status_enabled", false);
+ editor.apply();
+ }
public static String getUserStatus(Context context) {
return getSharedPreferences(context).getString("status_entry", "Dostępny");
@@ -94,6 +104,11 @@ public class PrefUtils {
public static boolean isEnableSharingLocalization(Context context) {
return getSharedPreferences(context).getBoolean("key_sharing_enabled", false);
}
+ public static void disableSharing(Context context){
+ SharedPreferences.Editor editor = getSharedPreferences(context).edit();
+ editor.putBoolean("key_sharing_enabled", false);
+ editor.apply();
+ }
public static void storeEnableSharingLocalization(Context context, Boolean isChecked) {
SharedPreferences.Editor editor = getSharedPreferences(context).edit();
@@ -197,4 +212,35 @@ public class PrefUtils {
return getSharedPreferences(context).getString("current_manual_location_name", null);
}
+ public static void putShowOnlyOnlineUsers(Context context, Boolean flag) {
+ SharedPreferences.Editor editor = getSharedPreferences(context).edit();
+ editor.putBoolean("show_only_online_users_in_list", flag);
+ editor.apply();
+ }
+
+ public static Boolean getShowOnlyOnlineUsers(Context context) {
+ return getSharedPreferences(context).getBoolean("show_only_online_users_in_list", true);
+ }
+
+ public static void useBlacklist(Context context, Boolean flag) {
+ SharedPreferences.Editor editor = getSharedPreferences(context).edit();
+ editor.putBoolean("blacklisting", flag);
+ editor.putBoolean("whitelisting", false);
+ editor.apply();
+ }
+
+ public static void useWhitelist(Context context, Boolean flag) {
+ SharedPreferences.Editor editor = getSharedPreferences(context).edit();
+ editor.putBoolean("whitelisting", flag);
+ editor.putBoolean("blacklisting", false);
+ editor.apply();
+ }
+
+ public static Boolean isBlackListing(Context context) {
+ return getSharedPreferences(context).getBoolean("blacklisting", false);
+ }
+ public static Boolean isWhiteListing(Context context) {
+ return getSharedPreferences(context).getBoolean("whitelisting", false);
+ }
+
}
\ No newline at end of file
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 5fdf137..3814e03 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
@@ -2,6 +2,8 @@ package com.uam.wmi.findmytutor.utils;
import android.content.Context;
import android.preference.Preference;
import android.util.AttributeSet;
+import android.util.Log;
+import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.Button;
@@ -9,31 +11,40 @@ import com.uam.wmi.findmytutor.R;
public class RightButtonPreference extends Preference {
+ private Button prefButton;
+ private String buttonText;
+
public RightButtonPreference(Context context, AttributeSet attrs) {
super(context, attrs);
setWidgetLayoutResource(R.layout.preference_button_widget);
+ for (int i=0;i {
+ 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
index 33d4aee..5d0d5b4 100644
--- a/app/src/main/java/com/uam/wmi/findmytutor/utils/RxSearchObservable.java
+++ b/app/src/main/java/com/uam/wmi/findmytutor/utils/RxSearchObservable.java
@@ -21,6 +21,7 @@ public class RxSearchObservable {
@Override
public boolean onQueryTextSubmit(String s) {
subject.onNext(s);
+ searchView.clearFocus();
return false;
}
@@ -31,6 +32,8 @@ public class RxSearchObservable {
}
+
+
});
diff --git a/app/src/main/java/com/uam/wmi/findmytutor/utils/WrapContentLinearLayoutManager.java b/app/src/main/java/com/uam/wmi/findmytutor/utils/WrapContentLinearLayoutManager.java
new file mode 100644
index 0000000..e289bda
--- /dev/null
+++ b/app/src/main/java/com/uam/wmi/findmytutor/utils/WrapContentLinearLayoutManager.java
@@ -0,0 +1,22 @@
+package com.uam.wmi.findmytutor.utils;
+
+import android.content.Context;
+import android.support.v7.widget.LinearLayoutManager;
+import android.support.v7.widget.RecyclerView;
+import android.util.AttributeSet;
+import android.util.Log;
+
+public class WrapContentLinearLayoutManager extends LinearLayoutManager {
+ public WrapContentLinearLayoutManager(Context context) {
+ super(context);
+ }
+
+ @Override
+ public void onLayoutChildren(RecyclerView.Recycler recycler, RecyclerView.State state) {
+ try {
+ super.onLayoutChildren(recycler, state);
+ } catch (IndexOutOfBoundsException e) {
+ e.printStackTrace();
+ }
+ }
+}
diff --git a/app/src/main/res/drawable/ic_add_person.xml b/app/src/main/res/drawable/ic_add_person.xml
new file mode 100644
index 0000000..cc6dd3f
--- /dev/null
+++ b/app/src/main/res/drawable/ic_add_person.xml
@@ -0,0 +1,13 @@
+
+
+
+
+
+
\ No newline at end of file
diff --git a/app/src/main/res/drawable/trip_orgin.xml b/app/src/main/res/drawable/trip_orgin.xml
new file mode 100644
index 0000000..110d9dc
--- /dev/null
+++ b/app/src/main/res/drawable/trip_orgin.xml
@@ -0,0 +1,15 @@
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/app/src/main/res/layout/activity_black_list.xml b/app/src/main/res/layout/activity_black_list.xml
new file mode 100644
index 0000000..b4c9188
--- /dev/null
+++ b/app/src/main/res/layout/activity_black_list.xml
@@ -0,0 +1,83 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/app/src/main/res/layout/activity_white_list.xml b/app/src/main/res/layout/activity_white_list.xml
new file mode 100644
index 0000000..7c196c5
--- /dev/null
+++ b/app/src/main/res/layout/activity_white_list.xml
@@ -0,0 +1,83 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/app/src/main/res/layout/black_list_fab_modal.xml b/app/src/main/res/layout/black_list_fab_modal.xml
new file mode 100644
index 0000000..5d49f4f
--- /dev/null
+++ b/app/src/main/res/layout/black_list_fab_modal.xml
@@ -0,0 +1,42 @@
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/app/src/main/res/layout/black_list_row.xml b/app/src/main/res/layout/black_list_row.xml
new file mode 100644
index 0000000..ded676c
--- /dev/null
+++ b/app/src/main/res/layout/black_list_row.xml
@@ -0,0 +1,48 @@
+
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/app/src/main/res/layout/content_black_list.xml b/app/src/main/res/layout/content_black_list.xml
new file mode 100644
index 0000000..e7cc148
--- /dev/null
+++ b/app/src/main/res/layout/content_black_list.xml
@@ -0,0 +1,33 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/app/src/main/res/layout/content_tutor_tab.xml b/app/src/main/res/layout/content_tutor_tab.xml
index 3862c1f..f22e5e7 100644
--- a/app/src/main/res/layout/content_tutor_tab.xml
+++ b/app/src/main/res/layout/content_tutor_tab.xml
@@ -7,8 +7,6 @@
android:layout_width="match_parent"
android:layout_height="match_parent">
-
-
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/app/src/main/res/layout/home_layout.xml b/app/src/main/res/layout/home_layout.xml
new file mode 100644
index 0000000..d26e4eb
--- /dev/null
+++ b/app/src/main/res/layout/home_layout.xml
@@ -0,0 +1,13 @@
+
+
+
+
\ No newline at end of file
diff --git a/app/src/main/res/layout/info_popup_blacklist.xml b/app/src/main/res/layout/info_popup_blacklist.xml
new file mode 100644
index 0000000..d014fd3
--- /dev/null
+++ b/app/src/main/res/layout/info_popup_blacklist.xml
@@ -0,0 +1,39 @@
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/app/src/main/res/layout/info_popup_userlist.xml b/app/src/main/res/layout/info_popup_userlist.xml
index afd1c17..19761d7 100644
--- a/app/src/main/res/layout/info_popup_userlist.xml
+++ b/app/src/main/res/layout/info_popup_userlist.xml
@@ -72,4 +72,6 @@
android:text="@string/info_icon_userlist_summary"
android:textColor="@color/half_black"/>
+
+
\ No newline at end of file
diff --git a/app/src/main/res/layout/info_popup_whitelist.xml b/app/src/main/res/layout/info_popup_whitelist.xml
new file mode 100644
index 0000000..b61cb8f
--- /dev/null
+++ b/app/src/main/res/layout/info_popup_whitelist.xml
@@ -0,0 +1,39 @@
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/app/src/main/res/layout/location_modal.xml b/app/src/main/res/layout/location_modal.xml
index 51949bd..a4af220 100644
--- a/app/src/main/res/layout/location_modal.xml
+++ b/app/src/main/res/layout/location_modal.xml
@@ -24,14 +24,14 @@
android:textStyle="normal" />
diff --git a/app/src/main/res/layout/tutors_list_tabs.xml b/app/src/main/res/layout/tutors_list_tabs.xml
new file mode 100644
index 0000000..c09a3b2
--- /dev/null
+++ b/app/src/main/res/layout/tutors_list_tabs.xml
@@ -0,0 +1,56 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/app/src/main/res/layout/user_list_modal.xml b/app/src/main/res/layout/user_list_modal.xml
index c95e45e..b92f8eb 100644
--- a/app/src/main/res/layout/user_list_modal.xml
+++ b/app/src/main/res/layout/user_list_modal.xml
@@ -27,17 +27,19 @@
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent" />
-
+
+
@@ -158,25 +160,25 @@
+ android:layout_width="match_parent"
+ android:layout_height="wrap_content"
+ android:layout_marginTop="5dp"
+ android:orientation="horizontal"
+ android:paddingLeft="20dp">
-
-
-
+
+
+
diff --git a/app/src/main/res/layout/users_list.xml b/app/src/main/res/layout/users_list.xml
index daed3cd..6618359 100644
--- a/app/src/main/res/layout/users_list.xml
+++ b/app/src/main/res/layout/users_list.xml
@@ -10,6 +10,7 @@
+
diff --git a/app/src/main/res/layout/users_list_main.xml b/app/src/main/res/layout/users_list_main.xml
index 7e767f0..651b942 100644
--- a/app/src/main/res/layout/users_list_main.xml
+++ b/app/src/main/res/layout/users_list_main.xml
@@ -12,6 +12,7 @@
+
+
+
+
+
+
+
+
+
+
diff --git a/app/src/main/res/layout/white_list_fab_modal.xml b/app/src/main/res/layout/white_list_fab_modal.xml
new file mode 100644
index 0000000..f0380e6
--- /dev/null
+++ b/app/src/main/res/layout/white_list_fab_modal.xml
@@ -0,0 +1,42 @@
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/app/src/main/res/layout/white_list_row.xml b/app/src/main/res/layout/white_list_row.xml
new file mode 100644
index 0000000..35dad88
--- /dev/null
+++ b/app/src/main/res/layout/white_list_row.xml
@@ -0,0 +1,47 @@
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/app/src/main/res/menu/activity_main_drawer.xml b/app/src/main/res/menu/activity_main_drawer.xml
index c6e0307..90a85ef 100644
--- a/app/src/main/res/menu/activity_main_drawer.xml
+++ b/app/src/main/res/menu/activity_main_drawer.xml
@@ -1,14 +1,14 @@
diff --git a/app/src/main/res/menu/menu_main.xml b/app/src/main/res/menu/menu_main.xml
index 96cd955..985b8dd 100644
--- a/app/src/main/res/menu/menu_main.xml
+++ b/app/src/main/res/menu/menu_main.xml
@@ -6,6 +6,8 @@
android:id="@+id/action_search"
android:icon="@drawable/ic_menu_search"
app:showAsAction="always"
+ android:focusable="true"
+ android:focusableInTouchMode="true"
app:actionViewClass="android.support.v7.widget.SearchView"
android:title="@string/search"/>
-
+
+
diff --git a/app/src/main/res/menu/users_list_menu.xml b/app/src/main/res/menu/users_list_menu.xml
new file mode 100644
index 0000000..6e6a220
--- /dev/null
+++ b/app/src/main/res/menu/users_list_menu.xml
@@ -0,0 +1,11 @@
+
+
\ No newline at end of file
diff --git a/app/src/main/res/values-pl/strings.xml b/app/src/main/res/values-pl/strings.xml
index ac53573..ba3c288 100644
--- a/app/src/main/res/values-pl/strings.xml
+++ b/app/src/main/res/values-pl/strings.xml
@@ -132,7 +132,7 @@
Bounds OFF
Find My Tutor - feedback
Find My Tutor - zgłoszenie błędu
- Proszę opisz swoje spostrzeżnia.
+ Opisz proszę swoje spostrzeżenia.
Wyślij anonimowo
Manualna
Wybierz z mapy
@@ -205,12 +205,16 @@
Dodatkowo, do Twojej lokalizacji możesz dodać status opisowy (będzie on widoczny dla użytkowników po kliknięciu w marker).
Zarówno manualne lokalizacje jak i statusy możesz dodać do listy, z której możesz potem je wybrać w wygodny sposób.
- W tym panelu znajduje się listę profesorów.
+ W tym panelu znajduje się lista profesorów.
Ich status symbolizowany jest przez kolorowe kropki:
- użytkownik jest obecnie online
- użytkownik jest obecnie offline
- użytkownik jest nieaktywny
(nie udostępnił żadnych danych o lokalizacji od conajmniej tygodnia)
+ Dodaj
+ Index użytkownika
+ Dodaj użytkownika do Blacklsi
+
Po kliknięciu w imię i nazwisko, wyświetli się karta zawierająca dokładne informacje o profesorze.
@@ -239,9 +243,39 @@
Nie
Aby skorzystać z tej funkcji musisz pozwolić na udostępnianie lokalizacji. Zgadzasz sie?
Udostępnianie
+ Zarządzaj zapisanymi
+ Zarządzaj zapisanymi
+
+ Czarna lista
+ Pole nie może być puste
+ Użytkownik dodany
+ Lista jest pusta
+ WŁĄCZONA
+ WYŁĄCZONA
+ Czarna lista
Pobierz dane z WMI
Dane zostały zaktualizwane!
+
+ Brak aktywnych użytkowników.
+ Brak użytkowników offline.
+ Czarna lista
+ Biała lista
+ Biała lista
+ Dodaj użytkownika do białej listy
+ Nie ma takiego użytkownika
+ Tylko aktywni użytkownicy
+ Błąd sieci!
+ Brak wyników!
+ Nadaj nazwę tej lokalizacji.
+ Dostępny
+ Niedostępny
+ Nieaktywny
+ POKAŻ NA MAPIE
+
+
+ Użytkownik został dodany!
+ Użytkownik usunięty!
+
-
diff --git a/app/src/main/res/values/array.xml b/app/src/main/res/values/array.xml
index 5de90b6..2f967d2 100644
--- a/app/src/main/res/values/array.xml
+++ b/app/src/main/res/values/array.xml
@@ -55,23 +55,15 @@
- @string/description_available
- - @string/description_busy
- - @string/description_consultation
- 0
- - 1
- - 2
- @string/assembly_c
- - @string/assembly_a
- - @string/passage_d
- 0
- - 1
- - 2
- @string/lang_eng
@@ -81,4 +73,19 @@
- 0
- 1
+
+
+
+ - Item 1
+ - Item 2
+ - Item 3
+ - Item 4
+
+
+
+ - 0
+ - 1
+ - 2
+ - 3
+
diff --git a/app/src/main/res/values/dimens.xml b/app/src/main/res/values/dimens.xml
index bcc07bd..5bc97f5 100644
--- a/app/src/main/res/values/dimens.xml
+++ b/app/src/main/res/values/dimens.xml
@@ -19,4 +19,6 @@
13sp
12dp
10dp
+ 180dp
+ 16dp
diff --git a/app/src/main/res/values/strings.xml b/app/src/main/res/values/strings.xml
index 32686d4..52f5d89 100644
--- a/app/src/main/res/values/strings.xml
+++ b/app/src/main/res/values/strings.xml
@@ -32,7 +32,8 @@
Settings
- Notes
+ Blacklist
+ Whitelist
Password
Sign in or register
Sign out
@@ -53,12 +54,10 @@
-
Sharing
-
Sharing
Location sharing
Status settings
@@ -69,6 +68,9 @@
Exact
Manual
Choose from map
+ Manage saved
+ Manage saved
+
Location level
key_location_level
@@ -86,14 +88,10 @@
Add custom status
- Descrition
+ Description
Save
Edit your note. It will be shown in the users list.
-
-
key_description
-
-
Manual location
Choose manual location
Add custom location
@@ -254,7 +252,7 @@
App issues reporting
- On the map there are markers which represents tutors sharing their location right now.
+ On the map there are markers which represent tutors sharing their location right now.
After clicking on a marker, you can check who is sharing it and the descriptive status (if the tutor have set one).
In the app there are 3 possible types of localization, represented by various colors.
exact localization (from mobile GPS)
@@ -288,7 +286,7 @@
Each level, except from manual, will be automatically turned on when entering, and turn off when leaving the faculty. You only need to make sure that sharing is on, and the localization will be shared only when on the faculty.
Sharing can be turned off at any time with the switch.
Additionally, you can add descriptive status to your localization (visible for users after clicking on a marker).
- Both manual localizations and statuses can be added to a list, and then used them in a convenient way.
+ Both manual localizations and statuses can be added to a list, and then used in a convenient way.
This panel contains the list of tutors.
@@ -297,10 +295,18 @@
- user is currently offline
- user is inactive
(didn’t share any localization data since 7 days)
- After clicking on a name, the tutor tab will pop up, containing details about selected tutor.
+ BlackList
+ Whitelist
+ Add user to Whitelist
+
+ After clicking on a name, the tutor tab will pop up, containing details about selected tutor.\n\nYou can search for any tutor on the map by entering his name and surname in the search field.\n\nBy default, only active users are shown. You can change that in menu (three dots icon).\n\nYou can also search for a tutor directly, by entering name and surname of person that you look for.
+
+
+ User index
+ Add user to blacklist
+ Add
Yes
-
App issues reporting
@@ -319,7 +325,31 @@
In order to use this function, you have to enable localization sharing. May I do it for you?
Sharing
The user hasn\'t defined a status.
+ Field can not be empty
+ User added
+ The list is empty
+ Map
+ ON
+ OFF
Scrap!
- Thank you for scraping your tab!
+ Data updated!
+
+
+ Currently, there are no\nactive users.
+ Currently, there are no\noffline users.
+ Only online users
+ No such a user
+
+ Network Error !
+ Search response is empty!
+ Insert a name for this localization.
+ Online
+ Offline
+ Inactive
+ SHOW ON MAP
+
+
+ User has been added!
+ User removed!
diff --git a/app/src/main/res/values/styles.xml b/app/src/main/res/values/styles.xml
index ad4f49e..703fa27 100644
--- a/app/src/main/res/values/styles.xml
+++ b/app/src/main/res/values/styles.xml
@@ -22,4 +22,5 @@
- @drawable/fab_label_background
- @color/mapboxWhite
+
diff --git a/app/src/main/res/layout/pref_sharing.xml b/app/src/main/res/xml/pref_sharing.xml
similarity index 73%
rename from app/src/main/res/layout/pref_sharing.xml
rename to app/src/main/res/xml/pref_sharing.xml
index 3e952df..4a6cee4 100644
--- a/app/src/main/res/layout/pref_sharing.xml
+++ b/app/src/main/res/xml/pref_sharing.xml
@@ -1,8 +1,8 @@
@@ -16,7 +16,7 @@
android:persistent="true"
android:title="@string/title_sharing"/>
+
@@ -41,9 +48,11 @@
android:persistent="true"
android:title="@string/status_switch_title"/>
+
+
-
-
-
\ No newline at end of file