Compare commits

..

204 Commits

Author SHA1 Message Date
faed9e05b7 Merge branch 'develop' of s416084/find-my-tutor-android into master 2019-01-13 15:09:06 +00:00
1095386659 Merge branch 'fix-battery-prompt-5.1' of s416084/find-my-tutor-android into develop 2019-01-13 15:08:19 +00:00
b7e1e4a984 Fix 5.1 2019-01-13 16:06:58 +01:00
4473834218 Merge branch 'develop' of s416084/find-my-tutor-android into master 2019-01-13 13:39:56 +00:00
5a96d93d37 Merge branch 'fix-info-battery-prompt' of s416084/find-my-tutor-android into develop 2019-01-13 13:38:16 +00:00
33cfa90a28 Update gradle 2019-01-13 14:37:15 +01:00
6fa458d198 show prompt only for tutors 2019-01-13 14:36:51 +01:00
2ca95e0ba0 Merge branch 'develop' of s416084/find-my-tutor-android into master 2019-01-13 13:14:13 +00:00
eb30100183 Merge branch 'presence-wifi-approach' of s416084/find-my-tutor-android into develop 2019-01-13 13:11:38 +00:00
e1c266263a Fix low battery mode 2019-01-13 14:10:50 +01:00
d88525a764 Add presence which works with Wifi 2019-01-13 13:44:10 +01:00
430914bab1 Merge branch 'fix-acra' of s416084/find-my-tutor-android into develop 2019-01-13 10:34:55 +00:00
786a73c963 Fix acra 2019-01-13 11:31:36 +01:00
1f2867cb43 Merge branch 'develop' into fix-acra 2019-01-13 02:09:31 +01:00
5770217c45 Merge branch 'fix-battery-prompt' of s416084/find-my-tutor-android into develop 2019-01-12 20:16:40 +00:00
17b7f4c9a2 fix 2019-01-12 21:15:37 +01:00
f46d9cc60e Merge branch 'add-beta-student-security' of s416084/find-my-tutor-android into develop 2019-01-12 19:23:39 +00:00
325f8a99a2 master version 2019-01-12 20:23:03 +01:00
0ec0e95798 Add logout security 2019-01-12 20:22:30 +01:00
085dc1e4d6 Merge branch 'fix-login-form' of s416084/find-my-tutor-android into develop 2019-01-12 18:37:55 +00:00
9f78eaf688 Fix login form 2019-01-12 19:37:25 +01:00
b528ec68bb Merge branch 'batteryExclusion' of s416084/find-my-tutor-android into develop 2019-01-12 18:27:16 +00:00
7b79a5339a merge develop 2019-01-12 19:26:49 +01:00
6e98eeff16 Merge branch 'fix-last-seen' of s416084/find-my-tutor-android into develop 2019-01-12 18:24:01 +00:00
5fccb72843 fix statuses 2019-01-12 19:15:40 +01:00
377ee3bcbc Change to one get 2019-01-12 18:46:52 +01:00
282f74f5e0 Remove shadow from buttons 2019-01-12 16:42:51 +01:00
b126cbfe31 Fix tutors list 2019-01-12 16:38:28 +01:00
fae7a5f0fe pop up with battery exc + transaltions 2019-01-12 14:56:54 +01:00
e64f5d380c Commit to check out on production 2019-01-11 00:34:27 +01:00
2f25f06d18 On Attach fix 2019-01-11 00:34:04 +01:00
a27c18b468 Merge branch 'fix-acra' of s416084/find-my-tutor-android into develop 2019-01-10 23:26:18 +00:00
311cd7868b Fix acra 2019-01-11 00:25:43 +01:00
be58fba3ad Merge branch 'fix-back-button' of s416084/find-my-tutor-android into develop 2019-01-10 23:00:32 +00:00
2f93dc5d54 Update gradle 2019-01-10 23:59:35 +01:00
c8cdc3aac0 fix return button 2019-01-10 23:58:33 +01:00
f872b08acc Merge branch 'users-list-last-seen' of s416084/find-my-tutor-android into develop 2019-01-10 22:41:47 +00:00
97bb141a81 Update gradle 2019-01-10 23:40:40 +01:00
a98b188978 Merge branch 'develop' into users-list-last-seen 2019-01-10 23:39:02 +01:00
20f585509c Fix tutor tab fixes 2019-01-10 23:36:44 +01:00
ad83c5ed88 Change loaders 2019-01-10 23:32:45 +01:00
623957bcb2 Fix tutor tab 2019-01-10 21:31:31 +01:00
ec68ae14ef Fix resources 2019-01-10 00:51:14 +01:00
393f25b1f9 Merge branch 'userListEnchancment' of s416084/find-my-tutor-android into develop 2019-01-09 23:41:41 +00:00
3379faf59b Update gradle version 2019-01-10 00:40:00 +01:00
1f888ad1f2 Merge branch 'develop' into userListEnchancment 2019-01-10 00:39:29 +01:00
ebe2266036 Merge branch 'fix-offline-box' of s416084/find-my-tutor-android into develop 2019-01-09 23:35:24 +00:00
f36a811d03 Merge branch 'develop' into fix-offline-box 2019-01-10 00:33:38 +01:00
ffff380560 Fix gps box 2019-01-10 00:33:10 +01:00
6d73598d5e code clean up and string translations for last seen 2019-01-10 00:11:37 +01:00
f98e4289fb last seen working just fine 2019-01-09 23:44:05 +01:00
d583c807d5 Merge branch 'add-toggle-password-login' of s416084/find-my-tutor-android into develop 2019-01-09 21:52:01 +00:00
86b6a1a86f Add toggle password 2019-01-09 22:50:51 +01:00
4300c33d65 show on map modal fix, Status added 2019-01-09 21:20:48 +01:00
b7b284252b Merge branch 'fix-trans' of s416084/find-my-tutor-android into develop 2019-01-08 22:42:12 +00:00
5dcaca9dd2 Fix strings 2019-01-08 23:41:30 +01:00
c55578c8ae Fix typo 2019-01-08 23:31:07 +01:00
59cb517ac7 Merge branch 'bottomNavHighlighytAndBlackListStringsFix' of s416084/find-my-tutor-android into develop 2019-01-08 22:10:48 +00:00
ae3c355259 Merge branch 'develop' into bottomNavHighlighytAndBlackListStringsFix 2019-01-08 23:08:08 +01:00
022669c6ee rdy2m 2019-01-08 22:59:15 +01:00
9c03d84b0a Merge branch 'fix-strings' of s416084/find-my-tutor-android into develop 2019-01-08 21:56:18 +00:00
b978ee560c Fix strings 2019-01-08 22:55:40 +01:00
c188ce38a8 Merge branch 'change-user-list' of s416084/find-my-tutor-android into develop 2019-01-08 21:29:40 +00:00
f02afb5e56 Fix map search 2019-01-08 22:28:19 +01:00
59c28e35d8 Merge branch 'fix-bg' of s416084/find-my-tutor-android into develop 2019-01-07 09:22:27 +00:00
76d008e098 Update version 2019-01-07 10:20:33 +01:00
d87a08a9e8 Merge branch 'fix-bg' of s416084/find-my-tutor-android into develop 2019-01-07 08:56:35 +00:00
a98ec8de47 Update version 2019-01-07 09:53:29 +01:00
d0b714731b Add battery saver 2019-01-07 09:46:14 +01:00
aaca6c008e Merge branch 'fix-manual-without-pref' of s416084/find-my-tutor-android into develop 2019-01-06 23:16:25 +00:00
413fc7d49a Update version 2019-01-07 00:15:59 +01:00
cf016bc6f4 Merge branch 'fix-manual-without-pref' of s416084/find-my-tutor-android into develop 2019-01-06 23:06:13 +00:00
d78ae83877 Fix scenario when user doesn't have prefs 2019-01-07 00:05:37 +01:00
6bd109e1cc Merge branch 'beta-release' of s416084/find-my-tutor-android into develop 2019-01-06 22:51:36 +00:00
1ba6cdf6f0 Update gradle 2019-01-06 23:50:38 +01:00
7a41dcbb1f Merge branch 'fix-manula-bg' of s416084/find-my-tutor-android into develop 2019-01-06 22:46:12 +00:00
4bb9452cbc Fix blacklists 2019-01-06 23:45:47 +01:00
701ee6e9d5 Merge branch 'profileUIfix' of s416084/find-my-tutor-android into develop 2019-01-06 22:41:42 +00:00
8da6ca8c0d fixed padding 2019-01-06 23:40:28 +01:00
654bcb3653 Merge branch 'sharingTabFixes' of s416084/find-my-tutor-android into develop 2019-01-06 21:56:44 +00:00
3e7e77a430 revered sharing tab UI disabling to wait for api response, minor fix 2019-01-06 22:55:36 +01:00
2d93b23197 revered sharing tab UI disabling to wait for api response 2019-01-06 22:54:01 +01:00
66fa45baa0 Fix BG handle 2019-01-06 22:47:03 +01:00
065fff7867 Merge branch 'newProfile' of s416084/find-my-tutor-android into develop 2019-01-06 20:14:51 +00:00
51dcefcc62 Merge branch 'develop' into newProfile 2019-01-06 20:56:57 +01:00
489901dca1 added timepicker, email validation, new UI 2019-01-06 20:56:01 +01:00
a4c0881300 Merge branch 'develop' of s416084/find-my-tutor-android into master 2019-01-06 18:03:06 +00:00
8ab7e526e6 Merge branch 'fix-pref-sharing' of s416084/find-my-tutor-android into develop 2019-01-06 17:58:56 +00:00
bca6885591 Fix right button preferences 2019-01-06 18:52:14 +01:00
e2f15ea772 Merge branch 'bottomNavFix' of s416084/find-my-tutor-android into develop 2019-01-06 14:39:21 +00:00
fac7ae0fdf bottom nav focus fixed 2019-01-06 15:36:49 +01:00
7e043c9826 Merge branch 'develop' of s416084/find-my-tutor-android into master 2019-01-06 11:02:30 +00:00
e9f71d5790 Merge branch 'fix-pref-sharing' of s416084/find-my-tutor-android into develop 2019-01-06 10:59:25 +00:00
3b4bb9cbae Fix sharing buttons 2019-01-06 11:58:22 +01:00
72eea53a8c Merge branch 'fix-bugs-related-to-network' of s416084/find-my-tutor-android into develop 2019-01-05 19:39:01 +00:00
9a96f474d9 Increase build version 2019-01-05 20:28:43 +01:00
5c5b9c745e Merge branch 'develop' into fix-bugs-related-to-network 2019-01-05 20:27:46 +01:00
e4b0bb1f3d Fix networks issues 2019-01-05 20:22:34 +01:00
331e7b5fe3 Merge branch 'fix-bugs-related-to-network' of s416084/find-my-tutor-android into develop 2019-01-05 14:54:57 +00:00
9525d47600 Fix 2019-01-05 15:52:56 +01:00
1f5ac834e5 Merge branch 'fix-imports' of s416084/find-my-tutor-android into develop 2019-01-05 07:24:10 +00:00
25e8d42ee0 Fix imports 2019-01-05 08:22:48 +01:00
eb4147557b Merge branch 'addRemovingManuals' of s416084/find-my-tutor-android into develop 2019-01-04 23:45:41 +00:00
3f0ccda50b Merge branch 'improve-rx-java-blacklists' of s416084/find-my-tutor-android into develop 2019-01-04 23:36:48 +00:00
da018120f1 Update gradle 2019-01-05 00:35:52 +01:00
dfc30c3790 Merge branch 'develop' into improve-rx-java-blacklists 2019-01-05 00:12:52 +01:00
46cdaa8ef9 Add wrapper override 2019-01-05 00:12:33 +01:00
cb1e7bcdef Convert multiple api calls to flatMap with rxJava 2019-01-04 21:05:23 +01:00
5db5d2f8e0 Merge branch 'showOnMap' of s416084/find-my-tutor-android into develop 2019-01-04 13:03:57 +00:00
ec29191342 tutor tap show on map and status indicator 2019-01-04 13:58:04 +01:00
42f501f8e2 Merge branch 'extend-bg-history' of s416084/find-my-tutor-android into develop 2019-01-04 10:13:56 +00:00
35ef25b2b7 Extend history 2019-01-04 11:11:55 +01:00
9e32a909d9 merge develop 2019-01-04 08:46:20 +01:00
bc6e5179c7 minor adjustments 2019-01-04 03:48:16 +01:00
8a88629b9a managed hiding/disabling preferences depending on contents of response from api 2019-01-04 03:04:26 +01:00
87e0be8e79 Merge branch 'release-beta' of s416084/find-my-tutor-android into develop 2019-01-03 22:58:45 +00:00
39d2d78ad8 Update gradle 2019-01-03 23:58:03 +01:00
ed2ec41d8d Merge branch 'fix-blacklists' of s416084/find-my-tutor-android into develop 2019-01-03 22:42:02 +00:00
4fceb4195f Fix blacklists 2019-01-03 23:41:24 +01:00
8e610c52ca Merge branch 'add-slider' of s416084/find-my-tutor-android into develop 2019-01-03 22:08:53 +00:00
7d1460353d Merge branch 'develop' into add-slider 2019-01-03 23:02:18 +01:00
f9226262ed Fix UI whitelist 2019-01-03 23:01:55 +01:00
cff66ef70d Merge branch 'blackNwhiteLists' of s416084/find-my-tutor-android into develop 2019-01-03 21:18:10 +00:00
a0934638b3 toast and icon changed 2019-01-03 22:17:30 +01:00
0147a83034 Merge branch 'develop' into add-slider 2019-01-03 21:57:56 +01:00
81af3360f7 Add slider 2019-01-03 21:57:23 +01:00
7d74d46d27 Merge branch 'blackNwhiteLists' of s416084/find-my-tutor-android into develop 2019-01-03 20:56:28 +00:00
2338e484f8 Merge confict 2019-01-03 21:53:15 +01:00
1eed752b1a Merge branch 'develop' into blackNwhiteLists 2019-01-03 21:47:50 +01:00
6902a62d07 Merge branch 'user-search-query-approach' of s416084/find-my-tutor-android into develop 2019-01-03 20:33:46 +00:00
af1e1a53b4 Add proper search 2019-01-03 21:32:28 +01:00
3a6f20d12e strings fixes and toast removed 2019-01-03 21:30:43 +01:00
d9ada9319b white list finished, toogle on/off related to blacklsits 2019-01-03 21:07:32 +01:00
a908623064 Merge branch 'bg-fused-done' of s416084/find-my-tutor-android into develop 2019-01-03 19:04:20 +00:00
8e94d86968 Fix corner case 2019-01-03 20:03:46 +01:00
77d15a734e Merge branch 'bg-fused-done' of s416084/find-my-tutor-android into develop 2019-01-03 18:52:14 +00:00
b81e28cd61 Fix online logic 2019-01-03 19:51:48 +01:00
4d921f7321 Merge branch 'bg-fused-done' of s416084/find-my-tutor-android into develop 2019-01-03 18:50:47 +00:00
8bcecbbed5 Change online trigger 2019-01-03 19:50:11 +01:00
88d016779f Merge branch 'bg-fused-done' of s416084/find-my-tutor-android into develop 2019-01-03 18:40:06 +00:00
ea0d6e1e96 Add save battery mode 2019-01-03 19:34:55 +01:00
88f263217a Use fused and change loc mode 2019-01-03 17:39:34 +01:00
a4fd031a36 resolved case when selected entries are deleted, working towards enabling/disabling views when there are no items 2019-01-03 10:38:58 +01:00
94368b05d1 deleting works, needs some polishing like refreshing summaries and hiding buttons depending on the level of sharing 2019-01-03 02:12:17 +01:00
6bdf402df8 Merge branch 'text-fixes' of s416084/find-my-tutor-android into develop 2019-01-02 22:29:57 +00:00
Maciej Wanat
b323939067 Text fixes 2019-01-02 19:16:04 +01:00
b366c0a17c Merge branch 'search-user-backend' of s416084/find-my-tutor-android into develop 2019-01-02 17:24:05 +00:00
44e392c027 Add search on backend 2019-01-02 18:23:03 +01:00
be7a0cec0a Merge branch 'fix-users-list-UI' of s416084/find-my-tutor-android into develop 2019-01-02 16:43:06 +00:00
9059cbd01d Fix online icon 2019-01-02 17:42:10 +01:00
96e31166c6 Merge branch 'blackNwhiteLists' of s416084/find-my-tutor-android into develop 2019-01-02 11:22:10 +00:00
aec9eaae19 string fixes 2019-01-02 12:21:05 +01:00
fce812f3ce Merge branch 'blackNwhiteLists' of s416084/find-my-tutor-android into develop 2019-01-02 11:06:18 +00:00
c8e68e3bb6 Merge branch 'develop' into blackNwhiteLists 2019-01-02 11:49:55 +01:00
150caf187d Merge branch 'fix-keyboard-layout' of s416084/find-my-tutor-android into develop 2019-01-02 08:12:08 +00:00
1a5c85c213 Adjust keyboard latout 2019-01-02 09:10:47 +01:00
0bf3d147f0 Don't use GPS when manual sharing has been choosen 2019-01-02 09:03:44 +01:00
540536a4a8 Merge branch 'online-offline-list' of s416084/find-my-tutor-android into develop 2019-01-02 07:47:45 +00:00
4fd2795377 Add translation 2019-01-02 08:46:28 +01:00
9dd2a62d43 Add checkbox online/offline users 2019-01-02 00:17:03 +01:00
598e603dfb Merge branch 'fix-bg-power-saving' of s416084/find-my-tutor-android into develop 2019-01-01 19:07:27 +00:00
18547a3c52 Remove unnecessary code 2019-01-01 20:03:30 +01:00
7f169e5b61 Choose only fused location 2018-12-31 17:25:06 +01:00
87642c5d7a blacklist ready to test 2018-12-30 21:14:10 +01:00
84e6b95675 Black list ready to test 2018-12-30 21:13:23 +01:00
2178b4d61d Merge branch 'minor-text-fixes' of s416084/find-my-tutor-android into develop 2018-12-19 18:53:55 +00:00
Maciej Wanat
552badf5a9 Minor text fixes 2018-12-19 19:51:14 +01:00
ee815260a4 Merge branch 'improve-BG-battery' of s416084/find-my-tutor-android into develop 2018-12-18 21:38:42 +00:00
69c42b323d Add new build 2018-12-18 22:37:49 +01:00
381f7b0033 Merge branch 'improve-BG-battery' of s416084/find-my-tutor-android into develop 2018-12-18 20:47:09 +00:00
956cd83f9b Destroy listeners after fetching loclization 2018-12-18 21:43:15 +01:00
8d7ba2e947 Merge branch 'develop' of s416084/find-my-tutor-android into master 2018-12-18 19:06:27 +00:00
fa0b69920f Merge branch 'fix-presence-mode' of s416084/find-my-tutor-android into develop 2018-12-18 19:04:51 +00:00
6334706165 Add release version 2018-12-18 20:01:54 +01:00
3eb8c922c9 Merge branch 'fix-presence-mode' of s416084/find-my-tutor-android into develop 2018-12-18 18:15:17 +00:00
ac3e8310d1 On presence mode only on WMI 2018-12-18 19:13:59 +01:00
6030ec6d84 Merge branch 'fix-hints-content' of s416084/find-my-tutor-android into develop 2018-12-18 17:42:42 +00:00
d80b83f2b5 Merge branch 'add-scrap-button' of s416084/find-my-tutor-android into develop 2018-12-18 17:41:49 +00:00
7ac5ac2d6f Convert to develop 2018-12-18 18:31:57 +01:00
bf6c8c3f51 Merge branch 'develop' into add-scrap-button 2018-12-18 00:03:43 +01:00
41c5dcebfd Add scrap button 2018-12-18 00:01:35 +01:00
Maciej Wanat
020ec1d41e Fix some of the messages content 2018-12-17 16:36:57 +01:00
8fdcdf4f80 almost working button, need to handle response 2018-12-17 16:20:58 +01:00
9255da3969 Merge branch 'develop' of s416084/find-my-tutor-android into master 2018-12-17 10:23:54 +00:00
303841c14e Merge branch 'betaRelease' of s416084/find-my-tutor-android into develop 2018-12-17 10:21:09 +00:00
4d33a07a30 version code inc 2018-12-17 11:17:20 +01:00
1eeaee7da1 Merge branch 'fix-colors' of s416084/find-my-tutor-android into develop 2018-12-17 09:55:10 +00:00
60c7283ba1 Fix colors 2018-12-17 10:54:22 +01:00
cae8a22c25 Merge branch 'fix-tutor-tab-develop' of s416084/find-my-tutor-android into develop 2018-12-17 09:44:03 +00:00
ce14928bc6 fix duty hours 2018-12-17 10:41:09 +01:00
4bdebcf52d Add strings 2018-12-17 10:39:37 +01:00
48ce4c76c8 Merge from develop 2018-12-17 10:34:25 +01:00
6b1537cd77 Merge branch 'tempBranch' of s416084/find-my-tutor-android into develop 2018-12-17 00:37:51 +00:00
5bf380b666 git history fix 2018-12-17 01:36:58 +01:00
2d9c8aa6cc Fix empty binding 2018-12-17 00:56:07 +01:00
00ea68379b rmved test hint 2018-12-17 00:51:11 +01:00
3ddcccb176 minor adjustments 2018-12-17 00:48:35 +01:00
c1bf626bbc changed hint strings 2018-12-17 00:45:38 +01:00
fe0115122d Merge branch 'fix-manual-sharing' of s416084/find-my-tutor-android into develop 2018-12-16 22:33:46 +00:00
c1e20934e4 recycle view crash 2018-12-16 22:44:00 +01:00
962a222fa8 minor cleanup 2018-12-16 18:19:58 +01:00
caa60e6f25 Merge branch 'develop' of s416084/find-my-tutor-android into master 2018-12-10 21:05:52 +00:00
e5f7a81c9a Merge branch 'develop' of s416084/find-my-tutor-android into master 2018-12-07 18:01:01 +00:00
26e12d68f3 Merge branch 'PR-master-auto-online' of s416084/find-my-tutor-android into master 2018-12-06 22:38:02 +00:00
83 changed files with 5129 additions and 673 deletions

View File

@ -10,10 +10,11 @@ android {
applicationId "com.uam.wmi.findmytutor"
minSdkVersion 22
targetSdkVersion 27
versionCode 17
versionName "0.9.2-alpha"
versionCode 66
versionName "1.0.0"
testInstrumentationRunner "android.support.test.runner.AndroidJUnitRunner"
vectorDrawables.useSupportLibrary = true
resConfigs "en", "pl"
}
buildTypes {
release {
@ -37,10 +38,8 @@ dependencies {
implementation "ch.acra:acra-limiter:$acraVersion"
implementation fileTree(include: ['*.jar'], dir: 'libs')
implementation 'com.android.support:preference-v7:27.1.1'
implementation 'com.android.support:appcompat-v7:27.1.1'
implementation 'com.android.support:cardview-v7:27.1.1'
implementation 'com.android.support:design:27.1.1'
implementation 'com.android.support:support-v4:27.1.1'
@ -72,4 +71,10 @@ dependencies {
// FloatingBarMenu
implementation 'com.getbase:floatingactionbutton:1.10.1'
implementation 'org.apache.commons:commons-collections4:4.0'
implementation 'com.android.support:design:27.1.1'
// spinner loaders library
implementation 'com.github.ybq:Android-SpinKit:1.2.0'
// rx binding
implementation 'com.jakewharton.rxbinding:rxbinding:0.3.0'
}

Binary file not shown.

Binary file not shown.

View File

@ -4,10 +4,10 @@
package="com.uam.wmi.findmytutor">
<uses-permission android:name="android.permission.INTERNET" />
<uses-permission android:name="android.permission.FOREGROUND_SERVICE" />
<uses-permission android:name="android.permission.ACCESS_COARSE_LOCATION" />
<uses-permission android:name="android.permission.ACCESS_FINE_LOCATION" />
<uses-permission android:name="android.permission.WAKE_LOCK" />
<uses-permission android:name="android.permission.FOREGROUND_SERVICE" />
<uses-permission android:name="android.permission.ACCESS_COARSE_UPDATES" />
<uses-permission android:name="android.permission.ACCESS_NETWORK_STATE" />
<uses-permission android:name="android.permission.CHANGE_WIFI_STATE" />
@ -24,13 +24,14 @@
android:roundIcon="@mipmap/ic_launcher_round"
android:supportsRtl="true"
android:theme="@style/AppTheme"
android:configChanges="locale"
tools:ignore="AllowBackup,GoogleAppIndexingWarning">
<activity
android:name=".activity.StartupActivity"
android:configChanges="keyboardHidden|orientation|screenSize"
android:launchMode="singleInstance"
android:theme="@style/AppTheme.NoActionBar"
android:screenOrientation="portrait"
android:configChanges="keyboardHidden|orientation|screenSize">
android:theme="@style/AppTheme.NoActionBar">
<intent-filter>
<action android:name="android.intent.action.MAIN" />
@ -39,20 +40,21 @@
</activity>
<activity
android:name=".activity.MapActivity"
android:configChanges="keyboardHidden|orientation|screenSize"
android:launchMode="singleTop"
android:screenOrientation="portrait"
android:configChanges="keyboardHidden|orientation|screenSize"/>
android:windowSoftInputMode="adjustPan" />
<activity
android:name=".activity.LoginActivity"
android:configChanges="keyboardHidden|orientation|screenSize"
android:excludeFromRecents="true"
android:launchMode="singleTask"
android:noHistory="true"
android:screenOrientation="portrait"
android:configChanges="keyboardHidden|orientation|screenSize"/>
android:screenOrientation="portrait" />
<activity
android:name=".activity.SettingsActivity"
android:screenOrientation="portrait"
android:configChanges="keyboardHidden|orientation|screenSize"/>
android:configChanges="keyboardHidden|orientation|screenSize"
android:screenOrientation="portrait" />
<service
android:name=".service.BackgroundLocalizationService"
@ -62,9 +64,21 @@
<activity
android:name=".activity.TutorTab"
android:theme="@style/AppTheme"
android:configChanges="keyboardHidden|orientation|screenSize"
android:windowSoftInputMode="stateHidden|adjustPan"
android:screenOrientation="portrait"
android:configChanges="keyboardHidden|orientation|screenSize"/>
android:theme="@style/AppTheme" />
<activity
android:name=".activity.WhiteList"
android:configChanges="keyboardHidden|orientation|screenSize"
android:screenOrientation="portrait"
android:theme="@style/AppTheme" />
<activity
android:name=".activity.BlackList"
android:configChanges="keyboardHidden|orientation|screenSize"
android:screenOrientation="portrait"
android:theme="@style/AppTheme" />
</application>
</manifest>

View File

@ -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"
}

View File

@ -6,8 +6,9 @@ import android.content.SharedPreferences;
import android.content.res.Configuration;
import com.uam.wmi.findmytutor.utils.Const;
import com.uam.wmi.findmytutor.utils.MapUtils;
import com.uam.wmi.findmytutor.utils.PrefUtils;
import static org.acra.ReportField.*;
import org.acra.ACRA;
import org.acra.annotation.AcraLimiter;
import org.acra.annotation.AcraNotification;
@ -16,18 +17,32 @@ import org.acra.config.HttpSenderConfigurationBuilder;
import org.acra.config.ToastConfigurationBuilder;
import org.acra.data.StringFormat;
import org.acra.sender.HttpSender;
import java.util.HashMap;
import java.util.Map;
import static org.acra.ReportField.ANDROID_VERSION;
import static org.acra.ReportField.BUILD_CONFIG;
import static org.acra.ReportField.CUSTOM_DATA;
import static org.acra.ReportField.LOGCAT;
import static org.acra.ReportField.PHONE_MODEL;
import static org.acra.ReportField.REPORT_ID;
import static org.acra.ReportField.SHARED_PREFERENCES;
import static org.acra.ReportField.STACK_TRACE;
import static org.acra.ReportField.USER_APP_START_DATE;
import static org.acra.ReportField.USER_CRASH_DATE;
@AcraNotification(resText = R.string.notification_text,
resTitle = R.string.notification_title,
resChannelName = R.string.notification_channel)
@AcraLimiter(failedReportLimit = 2)
public class FindMyTutor extends Application {
@Override
protected void attachBaseContext(Context base) {
super.attachBaseContext(base);
//super.attachBaseContext(LocaleHelper.onAttach(base));
// ACRA core
CoreConfigurationBuilder builder = new CoreConfigurationBuilder(this)
@ -43,16 +58,17 @@ public class FindMyTutor extends Application {
ToastConfigurationBuilder.class
).setResText(R.string.acra_toast_text);
SharedPreferences sharedPreferences = base.getSharedPreferences("com.uam.wmi.findmytutor_preferences", Context.MODE_PRIVATE);
Map header = new HashMap();
String token = sharedPreferences.getString("API_KEY", "KEY_EMPTY");
header.put("Authorization","Bearer " + token);
header.put("Authorization", "Bearer " + token);
// Api POST
builder.getPluginConfigurationBuilder(
HttpSenderConfigurationBuilder.class
// ).setUri("http://192.168.0.15:3000/api/acra")
).setUri(Const.BASE_URL +"api/Feedback/autoFeedback")
).setUri(Const.BASE_URL + "api/Feedback/autoFeedback")
.setHttpMethod(HttpSender.Method.POST)
.setHttpHeaders(header)
.setEnabled(true);

View File

@ -1,5 +1,6 @@
package com.uam.wmi.findmytutor.activity;
import android.content.Context;
import android.content.SharedPreferences;
import android.content.res.Configuration;
import android.os.Bundle;
@ -13,6 +14,8 @@ import android.view.MenuInflater;
import android.view.View;
import android.view.ViewGroup;
import com.uam.wmi.findmytutor.utils.LocaleHelper;
/**
* A {@link android.preference.PreferenceActivity} which implements and proxies the necessary calls
* to be used with AppCompat.

View File

@ -4,6 +4,7 @@ import android.Manifest;
import android.annotation.SuppressLint;
import android.app.Fragment;
import android.app.FragmentTransaction;
import android.content.Context;
import android.content.Intent;
import android.content.pm.PackageManager;
import android.content.res.Configuration;
@ -35,6 +36,9 @@ import com.uam.wmi.findmytutor.R;
import com.uam.wmi.findmytutor.service.BackgroundLocalizationService;
import com.uam.wmi.findmytutor.utils.ActiveFragment;
import com.uam.wmi.findmytutor.utils.FeedbackUtils;
import com.uam.wmi.findmytutor.utils.LocaleHelper;
import com.uam.wmi.findmytutor.utils.LocaleUtils;
import com.uam.wmi.findmytutor.utils.MapUtils;
import com.uam.wmi.findmytutor.utils.PrefUtils;
import com.uam.wmi.findmytutor.utils.RxSearchObservable;
@ -53,6 +57,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;
@ -79,11 +84,16 @@ public abstract class BaseActivity
private SharingFragment sharingFragment;
private Fragment userListFragment;
private ActiveFragment activeFragment = ActiveFragment.NONE;
public ActiveFragment activeFragment = ActiveFragment.NONE;
private Fragment activeBottomMenu = null;
private SearchView searchView;
public SearchView searchView;
public MenuItem infoMenuItem;
@Override
protected void attachBaseContext(Context base) {
super.attachBaseContext(LocaleHelper.onAttach(base));
}
@SuppressLint("CheckResult")
@Override
protected void onCreate(Bundle savedInstanceState) {
@ -99,11 +109,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))) {
@ -117,17 +127,9 @@ public abstract class BaseActivity
if(PrefUtils.isBackgroundLocationServiceRunning(getApplicationContext())) {
stopBackgroundLocalizationTask();
}
logout();
storeBackgroundLocationStatus(getApplication(), false);
PrefUtils.storeIsLoggedIn(getApplicationContext(), false);
Intent i = getBaseContext().getPackageManager()
.getLaunchIntentForPackage(getBaseContext().getPackageName());
if (i != null) {
i.addFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP);
}
startActivity(i);
finish();
} else if (itemName.equals(getResources().getString(R.string.navigation_item_feedback))) {
feedbackUtils.showNoteDialog("FEEDBACK");
@ -156,6 +158,21 @@ public abstract class BaseActivity
}
}
protected void logout(){
storeBackgroundLocationStatus(getApplication(), false);
PrefUtils.storeIsLoggedIn(getApplicationContext(), false);
PrefUtils.setBatteryExlusionInfoStatus(getApplicationContext(), true);
Intent i = getBaseContext().getPackageManager()
.getLaunchIntentForPackage(getBaseContext().getPackageName());
if (i != null) {
i.addFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP);
}
startActivity(i);
finish();
}
protected void checkPermissions() {
final List<String> missingPermissions = new ArrayList<String>();
@ -198,9 +215,10 @@ public abstract class BaseActivity
}
public void stopBackgroundLocalizationTask() {
PrefUtils.storeEnableSharingLocalization(getApplicationContext(), false);
Intent stopIntent = new Intent(getApplicationContext(), BackgroundLocalizationService.class);
stopIntent.putExtra("request_stop", true);
Log.e("Localization", "JEstem w stop BG");
stopService(stopIntent);
@ -208,10 +226,12 @@ public abstract class BaseActivity
public void startBackgroundLocalizationTask() {
checkPermissions();
PrefUtils.storeEnableSharingLocalization(getApplicationContext(), true);
Intent startIntent = new Intent(getApplicationContext(), BackgroundLocalizationService.class);
startIntent.putExtra("notify_interval", onlineBackgroundLocationInterval);
if (Build.VERSION.SDK_INT > Build.VERSION_CODES.O) {
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
startForegroundService(startIntent);
} else {
startService(startIntent);
@ -219,17 +239,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");
}
}
@ -270,7 +285,6 @@ public abstract class BaseActivity
setUpNav();
actionBarDrawerToggle.syncState();
}
@Override
@ -285,7 +299,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 +308,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 +320,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 +407,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);
@ -406,8 +427,8 @@ public abstract class BaseActivity
sharingFragment = SharingFragment.newInstance();
FragmentTransaction ft = getFragmentManager().beginTransaction();
ft.replace(R.id.activity_content, sharingFragment);
//ft.addToBackStack(null);
ft.commit();
}
private void loadUserListFragment() {
@ -416,11 +437,12 @@ public abstract class BaseActivity
userListFragment = UsersListFragment.newInstance();
FragmentTransaction ft = getFragmentManager().beginTransaction();
ft.replace(R.id.activity_content, userListFragment);
//ft.addToBackStack(null);
ft.commit();
}
private void updateNavigationBarState() {
public void updateNavigationBarState() {
int actionId = getNavigationMenuItemId();
selectBottomNavigationBarItem(actionId);
}
@ -432,4 +454,8 @@ public abstract class BaseActivity
abstract int getNavigationMenuItemId();
abstract int getContentViewId();
}

View File

@ -0,0 +1,370 @@
package com.uam.wmi.findmytutor.activity;
import android.annotation.SuppressLint;
import android.content.Context;
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.github.ybq.android.spinkit.SpinKitView;
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.LocaleHelper;
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.disposables.Disposable;
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;
@BindView(R.id.loader)
SpinKitView loader;
private Integer prevSize;
private BlackListAdapter mAdapter;
private List<User> blacklistedUsers = new ArrayList<>();
private Collator plCollator = Collator.getInstance(Locale.forLanguageTag("pl-PL"));
@Override
protected void attachBaseContext(Context base) {
super.attachBaseContext(LocaleHelper.onAttach(base));
}
@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) + " " +getString(R.string.on));
aSwitch.setChecked(true);
handleChangeRequest(true);
}else{
aSwitch.setText(getString(R.string.action_black_list) + " " +getString(R.string.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);
noNotesView.setVisibility(View.GONE);
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<List<String>> getListOfBlacklistedUsers(String userId) {
return userService.getTutorBlacklistedByID(userId)
.toObservable()
.subscribeOn(Schedulers.io())
.observeOn(AndroidSchedulers.mainThread());
}
private Observable<User> getUserObservable(String userId) {
return userService
.getUserById(userId)
.toObservable()
.subscribeOn(Schedulers.io())
.observeOn(AndroidSchedulers.mainThread());
}
private void fetchBlackListedUsers() {
disposable.add(getListOfBlacklistedUsers(tutorId)
.doOnSubscribe(this::handleDoOnSubscribe)
.subscribeOn(Schedulers.io())
.observeOn(AndroidSchedulers.mainThread())
.flatMap(Observable::fromIterable)
.flatMap(this::getUserObservable)
.subscribe(user -> blacklistedUsers.add(user), this::handleError,this::handleComplete));
}
private void handleDoOnSubscribe(Disposable disposable) {
prevSize = blacklistedUsers.size();
blacklistedUsers.clear();
didFetched = false;
}
private void handleComplete() {
Collections.sort(blacklistedUsers, this::sortByUserName);
didFetched = true;
refreshUI();
}
private void handleError(Throwable e){
showError(e);
didFetched = false;
}
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.setVisibility(View.VISIBLE);
noNotesView.setText(R.string.list_is_empty);
loader.setVisibility(View.GONE);
}else if (blacklistedUsers.size() > 0) {
noNotesView.setVisibility(View.GONE);
loader.setVisibility(View.GONE);
} else {
loader.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();
}
}

View File

@ -27,6 +27,7 @@ import com.uam.wmi.findmytutor.model.ValidateUser;
import com.uam.wmi.findmytutor.network.ApiClient;
import com.uam.wmi.findmytutor.service.LdapService;
import com.uam.wmi.findmytutor.service.UserService;
import com.uam.wmi.findmytutor.utils.MapUtils;
import com.uam.wmi.findmytutor.utils.PrefUtils;
import com.uam.wmi.findmytutor.utils.RestApiHelper;
@ -149,9 +150,9 @@ 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)
//disposable.add(ldapService.fakeValidate(fakeUser)
.subscribeOn(Schedulers.io())
.observeOn(AndroidSchedulers.mainThread())
.subscribe(this::handleResponse, this::handleError));
@ -190,6 +191,7 @@ public class LoginActivity extends AppCompatActivity {
getUserProfile(userId.asString());
Intent data = new Intent();
String txt = "Main Activity";
data.setData(Uri.parse(txt));

View File

@ -4,9 +4,11 @@ import android.Manifest;
import android.animation.ObjectAnimator;
import android.animation.ValueAnimator;
import android.annotation.SuppressLint;
import android.content.Context;
import android.location.Location;
import android.os.Bundle;
import android.os.Handler;
import android.os.PowerManager;
import android.support.v4.content.ContextCompat;
import android.support.v7.app.AlertDialog;
import android.text.TextUtils;
@ -44,12 +46,12 @@ 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.PredefinedStatusesService;
import com.uam.wmi.findmytutor.service.PredefinedCoordinatesService;
import com.uam.wmi.findmytutor.service.UserService;
import com.uam.wmi.findmytutor.utils.ApproximatedLocalization;
import com.uam.wmi.findmytutor.utils.EnableSharingDialog;
import com.uam.wmi.findmytutor.utils.LocaleHelper;
import com.uam.wmi.findmytutor.utils.LocaleUtils;
import com.uam.wmi.findmytutor.utils.ManualLocationUtils;
import com.uam.wmi.findmytutor.utils.MapMarker;
import com.uam.wmi.findmytutor.utils.MapUtils;
@ -70,17 +72,19 @@ 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 {
private HashMap<Long, String> markerUserHash = new HashMap<>();
private String tag = getClass().getName();
private PermissionsManager permissionsManager;
private LocationComponent locationComponent;
private CoordinateService coordinateService;
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;
@ -89,9 +93,8 @@ public class MapActivity extends BaseActivity
private Button removeLocationButton;
private Marker tmpLocalMarker;
private Coordinate droppedMarkercoordinate;
private HashMap<String, Coordinate> coordsMap = new HashMap<>();
public HashMap<String, Coordinate> coordsMap = new HashMap<>();
private HashMap<String, MapMarker> markerHash = new HashMap<>();
private HashMap<Long, String> markerUserHash = new HashMap<>();
private Set<String> previousCoordsIds = new HashSet<>();
private ManualLocationUtils manualLocationUtils;
// Camera Animation params
@ -103,6 +106,11 @@ public class MapActivity extends BaseActivity
private ApproximatedLocalization approximatedLocalization;
private boolean shouldFetchNewCoords = true;
@Override
protected void attachBaseContext(Context base) {
super.attachBaseContext(LocaleHelper.onAttach(base));
}
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
@ -119,6 +127,7 @@ public class MapActivity extends BaseActivity
mStatusChecker = () -> {
try {
if (shouldFetchNewCoords) {
checkIfUsesCanBeTutor();
fetchTopCoords();
}
} finally {
@ -127,7 +136,6 @@ public class MapActivity extends BaseActivity
};
selectLocationButton = findViewById(R.id.select_location_button);
removeLocationButton = findViewById(R.id.remove_location_button);
mapView = findViewById(R.id.mapView);
@ -138,6 +146,11 @@ public class MapActivity extends BaseActivity
handleBackgroundTaskLifeCycle();
manualLocationUtils = new ManualLocationUtils(MapActivity.this);
approximatedLocalization = new ApproximatedLocalization(MapUtils.loadJsonFromAsset(getApplicationContext(), "building.geojson"));
if(isTutor){
MapUtils.BatteryOptimizationsExceptionCheck(this);
}
}
@Override
@ -148,22 +161,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;
});
@ -216,13 +214,28 @@ public class MapActivity extends BaseActivity
userName.setText(String.format("%s %s", user.getFirstName(), user.getLastName()));
if(cordStatus.equals("")){
if (cordStatus.equals("")) {
status.setText(String.format("%s: %s", getResources().getString(R.string.status_switch_title), getString(R.string.lack_of_status)));
}else{
} else {
status.setText(String.format("%s: %s", getResources().getString(R.string.status_switch_title), cordStatus));
}
sharingLevelView.setText(String.format("%s: %s", getResources().getString(R.string.settings_location_level), sharingLevel));
String sharingLevelToRender = sharingLevel;
Log.e("LOCALE",PrefUtils.getLocale(getApplicationContext()));
if (PrefUtils.getLocale(getApplicationContext()).equals("pl") ||
PrefUtils.getLocale(getApplicationContext()).equals("pl-PL") ||
PrefUtils.getLocale(getApplicationContext()).equals("[pl-PL]")) {
if (sharingLevel.equals(SharingLevel.MANUAL.toString())) {
sharingLevelToRender = getString(R.string.manual_mode);
} else if (sharingLevel.equals(SharingLevel.EXACT.toString())) {
sharingLevelToRender = getString(R.string.exact_mode);
} else if (sharingLevel.equals(SharingLevel.APPROXIMATED.toString())) {
sharingLevelToRender = getString(R.string.approx_mode);
}
}
sharingLevelView.setText(String.format("%s: %s", getResources().getString(R.string.settings_location_level), sharingLevelToRender));
final AlertDialog alertDialog = alertDialogBuilderUserInput.create();
alertDialog.show();
@ -246,7 +259,12 @@ 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);
restoreMapMarkers();
});
}
private void setOnMapLongClickListener() {
@ -333,14 +351,14 @@ 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);
Button dismissButton = alertDialog.getButton(AlertDialog.BUTTON_NEGATIVE);
dismissButton.setOnClickListener(view1 -> {
PrefUtils.putCurrentManualLocationName(getApplicationContext(), "Inne");
PrefUtils.putCurrentManualLocationName(getApplicationContext(), getString(R.string.other_location));
PrefUtils.putCurrentManualLocation(getApplicationContext(), "-1");
alertDialog.dismiss();
@ -365,7 +383,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 +397,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)
@ -391,6 +409,30 @@ public class MapActivity extends BaseActivity
PrefUtils.putCurrentManualLocation(getApplicationContext(), resp.getPredefinedCoordinateId());
}
private void checkIfUsesCanBeTutor(){
disposable.add(
userService.getSelf(myId)
.subscribeOn(Schedulers.io())
.observeOn(AndroidSchedulers.mainThread())
.subscribeWith(new DisposableSingleObserver<User>() {
@Override
public void onSuccess(User user) {
boolean tutorFromBackend = user.getTitle().equals("tutor");
if(tutorFromBackend != PrefUtils.getIsTutor(getApplicationContext())){
logout();
}
}
@Override
public void onError(Throwable e) {
showError(e);
}
}));
}
private void fetchTopCoords() {
disposable.add(
@ -603,47 +645,6 @@ public class MapActivity extends BaseActivity
}
}
// Add the mapView lifecycle to the activity's lifecycle methods
@Override
public void onResume() {
super.onResume();
mapView.onResume();
shouldFetchNewCoords = true;
}
@Override
protected void onStart() {
super.onStart();
mapView.onStart();
}
@Override
protected void onStop() {
super.onStop();
mapView.onStop();
shouldFetchNewCoords = false;
}
@Override
public void onPause() {
super.onPause();
mapView.onPause();
shouldFetchNewCoords = false;
}
@Override
public void onLowMemory() {
super.onLowMemory();
mapView.onLowMemory();
}
@Override
protected void onDestroy() {
super.onDestroy();
mapView.onDestroy();
mHandler.removeCallbacks(mStatusChecker);
disposable.dispose();
}
@Override
protected void onSaveInstanceState(Bundle outState) {
@ -686,11 +687,13 @@ public class MapActivity extends BaseActivity
@Override
public void searchUser(String textToSearch) {
getUserFromApi(textToSearch);
Log.e("LOCALE", LocaleUtils.getCurrentLocale());
}
private void getUserFromApi(String userNameToSearch) {
disposable.add(
userService.getAllTutors()
userService.getAllOnlineTutors()
.subscribeOn(Schedulers.io())
.observeOn(AndroidSchedulers.mainThread())
.map(tutors -> Stream.of(tutors).filter(t ->
@ -698,6 +701,7 @@ public class MapActivity extends BaseActivity
.subscribeWith(new DisposableSingleObserver<List<User>>() {
@Override
public void onSuccess(List<User> users) {
Log.e("USERS", String.valueOf(users));
filterMarkers(users);
}
@ -708,7 +712,7 @@ public class MapActivity extends BaseActivity
}));
}
private void filterMarkers(List<User> users) {
public void filterMarkers(List<User> users) {
restoreMapMarkers();
Icon markedMarker = IconFactory.getInstance(MapActivity.this).fromResource(R.drawable.search_marker);
@ -729,19 +733,65 @@ public class MapActivity extends BaseActivity
}
public void restoreMapMarkers() {
try {
for (Marker marker : mapboxMap.getMarkers()) {
MapMarker markerMap = markerHash.get(markerUserHash.get(marker.getId()));
for (Marker marker : mapboxMap.getMarkers()) {
MapMarker markerMap = markerHash.get(markerUserHash.get(marker.getId()));
markerMap.restoreDefaultIcon();
mapboxMap.deselectMarker(marker);
}
markerMap.restoreDefaultIcon();
mapboxMap.deselectMarker(marker);
mapboxMap.getMarkerViewManager().update();
} catch (Exception e) {
Log.e("MAP", String.valueOf(e));
}
mapboxMap.getMarkerViewManager().update();
}
public void adjustMapToSearch(Integer zoom) {
MapUtils.setZoom(mapboxMap, zoom);
}
@Override
public void onResume() {
super.onResume();
mapView.onResume();
shouldFetchNewCoords = true;
}
@Override
protected void onStart() {
super.onStart();
mapView.onStart();
shouldFetchNewCoords = true;
}
@Override
protected void onStop() {
super.onStop();
mapView.onStop();
shouldFetchNewCoords = false;
}
@Override
public void onPause() {
super.onPause();
mapView.onPause();
shouldFetchNewCoords = false;
}
@Override
public void onLowMemory() {
super.onLowMemory();
mapView.onLowMemory();
}
@Override
protected void onDestroy() {
super.onDestroy();
mapView.onDestroy();
mHandler.removeCallbacks(mStatusChecker);
disposable.dispose();
}
}

View File

@ -1,6 +1,7 @@
package com.uam.wmi.findmytutor.activity;
import android.annotation.SuppressLint;
import android.content.Context;
import android.content.Intent;
import android.content.res.Configuration;
import android.content.res.Resources;
@ -15,12 +16,15 @@ import android.util.Log;
import android.view.MenuItem;
import com.uam.wmi.findmytutor.R;
import com.uam.wmi.findmytutor.utils.LocaleHelper;
import com.uam.wmi.findmytutor.utils.LocaleUtils;
import com.uam.wmi.findmytutor.utils.PrefUtils;
import java.util.Locale;
public class SettingsActivity extends AppCompatPreferenceActivity {
private static final String TAG = SettingsActivity.class.getSimpleName();
@ -33,9 +37,15 @@ public class SettingsActivity extends AppCompatPreferenceActivity {
getFragmentManager().beginTransaction().replace(android.R.id.content, new MainPreferenceFragment()).commit();
}
@Override
protected void attachBaseContext(Context base) {
super.attachBaseContext(LocaleHelper.onAttach(base));
}
public void setLocale(String localeName) {
Context context = LocaleHelper.setLocale(this, localeName);
Resources res = context.getResources();
Locale myLocale = new Locale(localeName);
Resources res = getResources();
DisplayMetrics dm = res.getDisplayMetrics();
Configuration conf = res.getConfiguration();
conf.locale = myLocale;
@ -62,9 +72,12 @@ public class SettingsActivity extends AppCompatPreferenceActivity {
languagesList.setOnPreferenceChangeListener((preference, newValue) -> {
if (!newValue.toString().equals("0")){
LocaleHelper.setLocale(getActivity(), "pl");
((SettingsActivity)getActivity()).setLocale("pl");
PrefUtils.storeLocale(getActivity(),"pl");
LocaleHelper.setLocale(getActivity(), "pl");
}else{
LocaleHelper.setLocale(getActivity(), "en");
((SettingsActivity)getActivity()).setLocale("en");
PrefUtils.storeLocale(getActivity(),"en");
}

View File

@ -1,7 +1,10 @@
package com.uam.wmi.findmytutor.activity;
import android.annotation.SuppressLint;
import android.app.AlertDialog;
import android.app.FragmentTransaction;
import android.content.Context;
import android.content.DialogInterface;
import android.content.SharedPreferences;
import android.os.Bundle;
import android.preference.ListPreference;
@ -21,15 +24,17 @@ import com.jakewharton.retrofit2.adapter.rxjava2.HttpException;
import com.uam.wmi.findmytutor.R;
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.LocaleHelper;
import com.uam.wmi.findmytutor.utils.PrefUtils;
import com.uam.wmi.findmytutor.utils.RestApiHelper;
import com.uam.wmi.findmytutor.utils.RightButtonPreference;
import com.uam.wmi.findmytutor.utils.SharingLevel;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.HashMap;
import java.util.List;
import java.util.Objects;
@ -45,17 +50,27 @@ 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;
protected List<PredefinedCoordViewModel> predefinedCoordsList = new ArrayList<>();
private HashMap<String, String> locationMap;
private ArrayList<String> locationUUIDs;
private HashMap<Integer, String> locationLevelMapping;
private HashMap<Integer, String> statusMapping;
private PredefinedStatusesService statusesService;
private PredefinedCoordinatesService locationService;
private CompositeDisposable disposable;
private AlertDialog.Builder builder;
private String[] statusesArray;
private boolean statusSwitchFlag;
private ArrayList<String> predefinedLocationsList;
public static SharingFragment newInstance() {
return new SharingFragment();
@ -69,7 +84,13 @@ public class SharingFragment extends PreferenceFragment implements SharedPrefere
.subscribeWith(new DisposableSingleObserver<List<String>>() {
@Override
public void onSuccess(List<String> 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,29 +103,48 @@ 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<List<PredefinedCoordViewModel>>() {
@Override
public void onSuccess(List<PredefinedCoordViewModel> coords) {
String currentCoordId = PrefUtils.getCurrentManualLocation(getApplicationContext());
locationMap = new HashMap<String, String>();
locationUUIDs = new ArrayList<String>();
for (PredefinedCoordViewModel i : coords)
locationMap.put(i.getPredefinedCoordinateId(), i.getName());
for (PredefinedCoordViewModel i : coords)
locationUUIDs.add(i.getPredefinedCoordinateId());
List<String> predefinedLocationsNames = Stream.of(coords).map(PredefinedCoordViewModel::getName).toList();
List<String> predefinedLocationsUUIDs = Stream.of(coords).map(PredefinedCoordViewModel::getPredefinedCoordinateId).toList();
predefinedCoordsList.addAll(coords);
if (!PrefUtils.getLocationLevel(getApplicationContext()).equals("manual")) {
preferenceCategory.removePreference(manualLocationList);
preferenceCategory.removePreference(removeManualLocation);
preferenceCategory.removePreference(manualLocationButton);
} else {
if (!predefinedCoordsList.isEmpty()) {
manualLocationList.setEnabled(true);
manualLocationList.setSummary(PrefUtils.getCurrentManualLocationName(getApplicationContext()));
removeManualLocation.setEnabled(true);
locationSharing.setEnabled(true);
}
}
String[] stringnames = predefinedLocationsNames.toArray(new String[0]);
predefinedLocationsList = new ArrayList<>(Arrays.asList(stringnames));
List<Integer> activesId = Stream.of(coords).indexed()
.filter(v -> v.getSecond().getPredefinedCoordinateId().equals(currentCoordId)).map(IntPair::getFirst).toList();
if( activesId.size() == 0){
if (activesId.size() == 0) {
setListPreferenceData(manualLocationList, stringnames, null);
}
else {
} else {
setListPreferenceData(manualLocationList, stringnames, activesId.get(0));
}
}
@Override
@ -114,20 +154,28 @@ public class SharingFragment extends PreferenceFragment implements SharedPrefere
}));
}
@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);
locationService = ApiClient.getClient(getApplicationContext()).create(PredefinedCoordinatesService.class);
disposable = new CompositeDisposable();
statusesArray = new String[0];
predefinedLocationsList = new ArrayList<String>();
getStatuses(disposable);
getLocations(disposable);
locationLevelMapping = new HashMap<Integer, String>();
@ -144,6 +192,7 @@ public class SharingFragment extends PreferenceFragment implements SharedPrefere
statusList.setSummary(PrefUtils.getUserStatus(getApplicationContext()));
manualLocationList.setSummary(PrefUtils.getCurrentManualLocationName(getApplicationContext()));
/** Main sharing switch**/
locationSharing.setOnPreferenceChangeListener((buttonView, newValue) -> {
PrefUtils.storeEnableSharingLocalization(getApplicationContext(), (Boolean) newValue);
@ -153,28 +202,27 @@ 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(removeManualLocation);
}
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) -> {
@ -197,16 +245,15 @@ public class SharingFragment extends PreferenceFragment implements SharedPrefere
return true;
});
/** Button 'choose from map' button listener **/
manualLocationButton.setOnPreferenceChangeListener((preference, o) -> {
FragmentTransaction fragmentTransaction = getFragmentManager().beginTransaction();
fragmentTransaction.hide(SharingFragment.this);
fragmentTransaction.commit();
((MapActivity) getActivity()).updateNavigationBarState();
return true;
});
statusSwitch.setOnPreferenceChangeListener((preference, newValue) -> true);
/** Status list change listener **/
statusList.setOnPreferenceChangeListener((preference, newValue) -> {
ListPreference lp = (ListPreference) preference;
@ -215,8 +262,17 @@ public class SharingFragment extends PreferenceFragment implements SharedPrefere
lp.setSummary(entries[Integer.parseInt((String) newValue)]);
return true;
});
statusList.setOnPreferenceClickListener(new Preference.OnPreferenceClickListener() {
@Override
public boolean onPreferenceClick(Preference preference) {
/** Custom status list change listener **/
if (statusesArray.length == 0) {
builder.setTitle("nie ma wody na pustyni");
}
return true;
}
});
/** Custom status edittext change listener **/
manualStatus.setOnPreferenceChangeListener((preference, newValue) -> {
disposable.add(statusesService.postUserPredefinedStatus(PrefUtils.getUserId(getApplicationContext()), (String) newValue)
@ -226,6 +282,41 @@ 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<String> tobeDeleted = new ArrayList<String>();
// 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 +327,36 @@ public class SharingFragment extends PreferenceFragment implements SharedPrefere
return view;
}
protected void removeEntries(String service, ArrayList<String> 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<String> uuidsToBeDeleted = new ArrayList<String>();
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 +382,15 @@ public class SharingFragment extends PreferenceFragment implements SharedPrefere
;
private void handleResponse(List<String> 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()));
@ -282,11 +408,83 @@ public class SharingFragment extends PreferenceFragment implements SharedPrefere
}
}
@Override
public void onSharedPreferenceChanged(SharedPreferences sharedPreferences, String key) {
locationSharing.setChecked(PrefUtils.isEnableSharingLocalization(getApplicationContext()));
private void handleDeleteStatuses(List<String> 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<PredefinedCoordViewModel> 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) {
locationSharing.setChecked(PrefUtils.isEnableSharingLocalization(getApplicationContext()));
}
@Override
public void onResume() {
@ -300,4 +498,11 @@ public class SharingFragment extends PreferenceFragment implements SharedPrefere
getPreferenceManager().getSharedPreferences().unregisterOnSharedPreferenceChangeListener(this);
super.onPause();
}
@Override
public void onDestroy() {
super.onDestroy();
disposable.dispose();
}
}

View File

@ -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();
}

View File

@ -1,15 +1,29 @@
package com.uam.wmi.findmytutor.activity;
import android.app.Activity;
import android.app.AlertDialog;
import android.app.Dialog;
import android.content.Context;
import android.content.DialogInterface;
import android.content.Intent;
import android.content.res.Configuration;
import android.content.res.Resources;
import android.net.Uri;
import android.os.Build;
import android.os.Bundle;
import android.os.PowerManager;
import android.provider.Settings;
import android.support.v4.app.DialogFragment;
import android.support.v4.app.FragmentManager;
import android.support.v7.app.AppCompatActivity;
import android.util.DisplayMetrics;
import android.widget.ScrollView;
import android.widget.Toast;
import com.uam.wmi.findmytutor.R;
import com.uam.wmi.findmytutor.utils.LocaleHelper;
import com.uam.wmi.findmytutor.utils.MapUtils;
import com.uam.wmi.findmytutor.utils.PrefUtils;
import java.util.Locale;
@ -18,6 +32,11 @@ public class StartupActivity extends AppCompatActivity {
private static final int AUTHENTICATION_REQUEST_CODE = 666;
String currentLang;
@Override
protected void attachBaseContext(Context base) {
super.attachBaseContext(LocaleHelper.onAttach(base));
}
@Override
protected void onCreate(Bundle savedInstanceState) {
@ -31,10 +50,10 @@ public class StartupActivity extends AppCompatActivity {
} else {
Intent loginIntent = new Intent(this, LoginActivity.class);
startActivityForResult(loginIntent, AUTHENTICATION_REQUEST_CODE);
}
super.onCreate(savedInstanceState);
}
@Override
@ -47,4 +66,8 @@ public class StartupActivity extends AppCompatActivity {
finish();
}
}

View File

@ -0,0 +1,49 @@
package com.uam.wmi.findmytutor.activity;
import android.annotation.SuppressLint;
import android.app.Dialog;
import android.app.DialogFragment;
import android.app.TimePickerDialog;
import android.os.Bundle;
import android.text.format.DateFormat;
import android.widget.TextView;
import android.widget.TimePicker;
import com.uam.wmi.findmytutor.model.DutyHourViewModel;
import java.util.Calendar;
@SuppressLint("ValidFragment")
public class TimePickerFragment extends DialogFragment
implements TimePickerDialog.OnTimeSetListener {
private TextView textView;
private String field;
private DutyHourViewModel duty;
@SuppressLint("ValidFragment")
public TimePickerFragment(TextView view, DutyHourViewModel duty, String field){
this.textView = view;
this.duty=duty;
this.field=field;
}
@Override
public Dialog onCreateDialog(Bundle savedInstanceState) {
// Use the current time as the default values for the picker
final Calendar c = Calendar.getInstance();
int hour = c.get(Calendar.HOUR_OF_DAY);
int minute = c.get(Calendar.MINUTE);
// Create a new instance of TimePickerDialog and return it
return new TimePickerDialog(getActivity(), this, hour, minute,
DateFormat.is24HourFormat(getActivity()));
}
public void onTimeSet(TimePicker view, int hourOfDay, int minute) {
String time = String.format("%d:%02d",hourOfDay,minute);
textView.setText(time);
if(field.equals("start")){
duty.setStart(time);
}else{
duty.setEnd(time);
}
// Do something with the time chosen by the user
}
}

View File

@ -1,36 +1,50 @@
package com.uam.wmi.findmytutor.activity;
import android.content.Context;
import android.graphics.drawable.ColorDrawable;
import android.os.Bundle;
import android.support.design.widget.TextInputEditText;
import android.support.v7.app.AppCompatActivity;
import android.support.v7.widget.LinearLayoutManager;
import android.support.v7.widget.RecyclerView;
import android.support.v7.widget.Toolbar;
import android.util.Log;
import android.view.Gravity;
import android.view.Menu;
import android.view.MenuItem;
import android.view.View;
import android.widget.Button;
import android.widget.EditText;
import android.widget.LinearLayout;
import android.widget.PopupWindow;
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.DutyHoursAdapter;
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.LocaleHelper;
import com.uam.wmi.findmytutor.utils.PrefUtils;
import com.uam.wmi.findmytutor.utils.RestApiHelper;
import java.util.Arrays;
import java.util.ArrayList;
import java.util.List;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
import butterknife.ButterKnife;
import io.reactivex.android.schedulers.AndroidSchedulers;
import io.reactivex.disposables.CompositeDisposable;
import io.reactivex.observers.DisposableSingleObserver;
import io.reactivex.schedulers.Schedulers;
import okhttp3.ResponseBody;
import retrofit2.Response;
import static java.lang.String.valueOf;
public class TutorTab extends AppCompatActivity {
private TutorTabApi tutorTabService;
@ -38,60 +52,54 @@ public class TutorTab extends AppCompatActivity {
private CompositeDisposable disposable = new CompositeDisposable();
private TextView userName;
private TextView userDutyHours;
private EditText userNote;
private TextInputEditText userNote;
private TextView userRoom;
private TextView userEmail;
private TextView department;
private Button addDutyButton;
private Button saveButon;
private Button scrapButton;
private Boolean ifTutorTabExists = true;
private List<DutyHourViewModel> dutyHourList;
private RecyclerView dutyHoursRecycller;
private DutyHoursAdapter dutyHoursAdapter;
private RecyclerView.LayoutManager dutyHoursLayoutManager;
private TutorTabViewModel newTab;
@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);
Toolbar toolbar = findViewById(R.id.toolbar);
toolbar.setTitle(R.string.profile_activity_title);
setSupportActionBar(toolbar);
userName = findViewById(R.id.userName);
userNote = findViewById(R.id.userNote);
userRoom = findViewById(R.id.userRoom);
userEmail = findViewById(R.id.userEmail);
department = findViewById(R.id.userDepartment);
saveButon = findViewById(R.id.saveButton);
scrapButton = findViewById(R.id.scrapTutorTab);
addDutyButton = findViewById(R.id.addDuty);
dutyHoursRecycller = findViewById(R.id.dutyHourView);
dutyHoursLayoutManager = new LinearLayoutManager(this);
dutyHoursRecycller.setLayoutManager(dutyHoursLayoutManager);
tutorTabService = ApiClient.getClient(getApplicationContext())
.create(TutorTabApi.class);
userService = ApiClient.getClient(getApplicationContext())
.create(UserService.class);
setContentView(R.layout.content_tutor_tab);
TextView userName = findViewById(R.id.userName);
TextView userDutyHours = findViewById(R.id.userDutyHours);
EditText userNote = findViewById(R.id.userNote);
TextView userRoom = findViewById(R.id.userRoom);
TextView userEmail = findViewById(R.id.userEmail);
TextView department = findViewById(R.id.userDepartment);
Button saveButon = findViewById(R.id.saveButon);
findViewById(R.id.contentTutorTabInfoImageButton).setOnClickListener(v-> InfoHelperUtils.infoPopUp(v,R.layout.info_popup_tutor_tab));
getTutorTab();
userName.setText(String.format("%s %s", PrefUtils.getUserFirstName(getApplicationContext()), PrefUtils.getUserLastName(getApplicationContext())));
disposable.add(
tutorTabService.apiUsersTutorTabByTutorIdGet(PrefUtils.getUserId(getApplicationContext()))
.subscribeOn(Schedulers.io())
.observeOn(AndroidSchedulers.mainThread())
.subscribeWith(new DisposableSingleObserver<TutorTabViewModel>() {
@Override
public void onSuccess(TutorTabViewModel tutorTabViewModel) {
List<String> dutyHoursList = Stream.of(tutorTabViewModel.getDutyHours())
.map(DutyHourViewModel::getSummary).toList();
userRoom.setText(String.format("%s: %s", getString(R.string.userRoom), tutorTabViewModel.getRoom()));
userEmail.setText(String.format("%s: %s", getString(R.string.userEmail), tutorTabViewModel.getEmailTutorTab()));
if (!tutorTabViewModel.getNote().equals("")) {
userNote.setText(String.format("%s", tutorTabViewModel.getNote()));
}
userDutyHours.setText(String.format("%s: %s", getString(R.string.userDutyHoursHeader), Arrays.toString(dutyHoursList.toArray())));
}
@Override
public void onError(Throwable e) {
showError(e);
}
}));
disposable.add(
userService.getUserById(PrefUtils.getUserId(getApplicationContext()))
userService.getUserById(PrefUtils.getUserId(getApplicationContext()))
.subscribeOn(Schedulers.io())
.observeOn(AndroidSchedulers.mainThread())
.subscribeWith(new DisposableSingleObserver<User>() {
@ -104,34 +112,143 @@ public class TutorTab extends AppCompatActivity {
@Override
public void onError(Throwable e) {
showError(e);
}
}));
setUpSaveListener(saveButon, userNote);
setUpSaveListener(saveButon);
scrapButton.setOnClickListener(view -> scrapTutorTab());
}
private void setUpSaveListener(Button button, EditText note) {
button.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View view) {
newTab = new TutorTabViewModel(PrefUtils.getUserId(getApplicationContext()),note.getText().toString());
putUserTab(newTab);
@Override
public boolean onCreateOptionsMenu(Menu menu) {
getMenuInflater().inflate(R.menu.menu_profile, menu);
return true;
}
@Override
public boolean onOptionsItemSelected(MenuItem item) {
if (item.getItemId()==R.id.action_profile_info_popup){
int layoutID = R.layout.info_popup_tutor_tab;
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 getTutorTab(){
disposable.add(
tutorTabService.apiUsersTutorTabByTutorIdGet(PrefUtils.getUserId(getApplicationContext()))
.subscribeOn(Schedulers.io())
.observeOn(AndroidSchedulers.mainThread())
.subscribeWith(new DisposableSingleObserver<TutorTabViewModel>() {
@Override
public void onSuccess(TutorTabViewModel tutorTabViewModel) {
dutyHourList = tutorTabViewModel.getDutyHours();
if(dutyHourList != null){
dutyHoursAdapter = new DutyHoursAdapter(getApplicationContext(),dutyHourList, getFragmentManager());
dutyHoursRecycller.setAdapter(dutyHoursAdapter);
addDutyButton.setOnClickListener(v -> addEmptyDuty(dutyHoursAdapter));
}
userRoom.setText(String.format("%s", tutorTabViewModel.getRoom()));
userEmail.setText(String.format("%s", tutorTabViewModel.getEmailTutorTab()));
if (!tutorTabViewModel.getNote().equals("")) {
userNote.setText(String.format("%s", tutorTabViewModel.getNote()));
}
}
@Override
public void onError(Throwable e) {
int code = 0;
if (e instanceof HttpException) {
code = ((HttpException) e).response().code();
}
if( code == 404){
ifTutorTabExists = false;
dutyHoursAdapter = new DutyHoursAdapter(getApplicationContext(),new ArrayList<DutyHourViewModel>(), getFragmentManager());
dutyHoursRecycller.setAdapter(dutyHoursAdapter);
addDutyButton.setOnClickListener(v -> addEmptyDuty(dutyHoursAdapter));
}
showError(e);
}
}));
}
private void addEmptyDuty(DutyHoursAdapter adapter){
adapter.addDuty(new DutyHourViewModel());
adapter.notifyItemInserted(adapter.getItemCount());
dutyHoursRecycller.scrollToPosition(adapter.getItemCount()-1);
}
private void setUpSaveListener(Button button) {
button.setOnClickListener(view -> {
if( isEmailValid(userEmail.getText().toString())){
newTab = new TutorTabViewModel(PrefUtils.getUserId(getApplicationContext()),
userRoom.getText().toString(),
userEmail.getText().toString(),
userNote.getText().toString(),
dutyHoursAdapter.getDutyList());
if(ifTutorTabExists){
putUserTab(newTab);
}else{
postUserTab(newTab);
ifTutorTabExists=true;
}
}else{
userEmail.setError(getString(R.string.error_invalid_email));
}
});
}
private void putUserTab(TutorTabViewModel tutorTabViewModel) {
disposable.add(tutorTabService.apiUsersTutorTabByTutorIdPut(PrefUtils.getUserId(getApplicationContext()), tutorTabViewModel)
.subscribeOn(Schedulers.io())
.observeOn(AndroidSchedulers.mainThread())
.subscribe(this::handleResponse, this::handleError));
.subscribe(this::handleResponsePut, this::handleError));
}
private void handleResponse(TutorTabViewModel tutorTabViewModel) {
Toast.makeText(getApplicationContext(), getApplicationContext().getString(R.string.modal_feedback_thankyou), Toast.LENGTH_SHORT).show();
private void postUserTab(TutorTabViewModel tutorTabViewModel) {
disposable.add(tutorTabService.apiUsersTutorTabByTutorIdPost(PrefUtils.getUserId(getApplicationContext()), tutorTabViewModel)
.subscribeOn(Schedulers.io())
.observeOn(AndroidSchedulers.mainThread())
.subscribe(this::handleResponsePost, this::handleError));
}
private void scrapTutorTab() {
disposable.add(tutorTabService.apiUsersScrapTutorTabByTutorIdPost(PrefUtils.getUserId(getApplicationContext()))
.subscribeOn(Schedulers.io())
.observeOn(AndroidSchedulers.mainThread())
.subscribe(this::handleResponseScrap, this::handleError));
}
private void handleResponseScrap() {
Toast.makeText(getApplicationContext(), getApplicationContext().getString(R.string.scrap_tutor_msg), Toast.LENGTH_SHORT).show();
getTutorTab();
}
private void handleResponsePut(Response<Void> resp) {
Toast.makeText(getApplicationContext(), getApplicationContext().getString(R.string.updateToast), Toast.LENGTH_SHORT).show();
}
private void handleResponsePost(TutorTabViewModel tutorTabViewModel ) {
Toast.makeText(getApplicationContext(), getApplicationContext().getString(R.string.updateToast), Toast.LENGTH_SHORT).show();
}
private void handleError(Throwable error) {
if (error instanceof HttpException) {
@ -143,6 +260,9 @@ public class TutorTab extends AppCompatActivity {
} else {
Toast.makeText(getApplicationContext(),
"Network error " + error.getMessage(), Toast.LENGTH_SHORT).show();
Log.e("WMI SUCC", String.valueOf(error));
}
}
@ -155,10 +275,29 @@ public class TutorTab extends AppCompatActivity {
} else {
message = "Network Error!";
}
// Snackbar.make(coordinatorLayout, message, Snackbar.LENGTH_LONG)
// .show();
Toast.makeText(getApplicationContext(), message, Toast.LENGTH_SHORT).show();
}
@Override
protected void attachBaseContext(Context base) {
super.attachBaseContext(LocaleHelper.onAttach(base));
}
public boolean isEmailValid(String email)
{
String regExpn =
"^(([\\w-]+\\.)+[\\w-]+|([a-zA-Z]{1}|[\\w-]{2,}))@"
+"((([0-1]?[0-9]{1,2}|25[0-5]|2[0-4][0-9])\\.([0-1]?"
+"[0-9]{1,2}|25[0-5]|2[0-4][0-9])\\."
+"([0-1]?[0-9]{1,2}|25[0-5]|2[0-4][0-9])\\.([0-1]?"
+"[0-9]{1,2}|25[0-5]|2[0-4][0-9])){1}|"
+"([a-zA-Z]+[\\w-]+\\.)+[a-zA-Z]{2,4})$";
CharSequence inputStr = email;
Pattern pattern = Pattern.compile(regExpn,Pattern.CASE_INSENSITIVE);
Matcher matcher = pattern.matcher(inputStr);
return matcher.matches();
}
}

View File

@ -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;
}
}

View File

@ -1,7 +1,10 @@
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.os.SystemClock;
import android.support.annotation.NonNull;
import android.support.design.widget.CoordinatorLayout;
import android.support.design.widget.Snackbar;
@ -9,40 +12,60 @@ 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.format.DateFormat;
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.LinearLayout;
import android.widget.ListView;
import android.widget.TextView;
import android.widget.Toast;
import com.annimon.stream.Stream;
import com.github.ybq.android.spinkit.SpinKitView;
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.Coordinate;
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.CoordinateService;
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.ActiveFragment;
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 java.text.Collator;
import java.util.ArrayList;
import java.util.Calendar;
import java.util.Collections;
import java.util.HashMap;
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.disposables.Disposable;
import io.reactivex.functions.Function;
import io.reactivex.observers.DisposableObserver;
import io.reactivex.observers.DisposableSingleObserver;
import io.reactivex.schedulers.Schedulers;
import okhttp3.ResponseBody;
@ -58,14 +81,20 @@ public class UsersListFragment extends Fragment {
RecyclerView recyclerView;
@BindView(R.id.txt_empty_notes_view)
TextView noNotesView;
@BindView(R.id.loader)
SpinKitView loader;
private SearchView searchView;
private UserService userService;
private TutorTabApi tutorTabService;
private CoordinateService coordinateService;
private CompositeDisposable disposable = new CompositeDisposable();
private TutorsListAdapter mAdapter;
private List<User> tutorsList = new ArrayList<>();
private List<User> tutorsFiltered = new ArrayList<>();
private HashMap<String, String> tutorsTimeStamps = new HashMap<>();
private Collator plCollator = Collator.getInstance(Locale.forLanguageTag("pl-PL"));
private Boolean fetchOnlyOnlineUsers = PrefUtils.getShowOnlyOnlineUsers(getApplicationContext());
public UsersListFragment() {
}
@ -75,10 +104,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, tutorsTimeStamps);
View view = inflater.inflate(R.layout.users_list, container, false);
view.setBackgroundColor(getResources().getColor(android.R.color.white));
setHasOptionsMenu(true);
return view;
}
@ -87,23 +116,27 @@ public class UsersListFragment extends Fragment {
userService = ApiClient.getClient(getApplicationContext())
.create(UserService.class);
tutorTabService = ApiClient.getClient(getActivity().getApplicationContext())
.create(TutorTabApi.class);
coordinateService = ApiClient.getClient(getApplicationContext())
.create(CoordinateService.class);
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);
noNotesView.setVisibility(View.GONE);
fetchAllTutors();
fetchTopCords();
recyclerView.addOnItemTouchListener(new RecyclerTouchListener(getActivity().getApplicationContext(),
recyclerView, new RecyclerTouchListener.ClickListener() {
@Override
public void onClick(View view, final int position) {
showNoteDialog(tutorsFiltered.get(position));
showNoteDialog(tutorsList.get(position));
}
@Override
@ -113,12 +146,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 +205,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);
@ -139,9 +213,30 @@ public class UsersListFragment extends Fragment {
TextView userRoom = view.findViewById(R.id.userRoom);
TextView userEmail = view.findViewById(R.id.userEmail);
TextView department = view.findViewById(R.id.userDepartment);
TextView userStatusLabel = view.findViewById(R.id.user_status_label);
LinearLayout userStatusLabelLL = view.findViewById(R.id.user_status_label_linearLayout);
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 +244,21 @@ public class UsersListFragment extends Fragment {
.subscribeWith(new DisposableSingleObserver<TutorTabViewModel>() {
@Override
public void onSuccess(TutorTabViewModel tutorTabViewModel) {
final AlertDialog alertDialog = alertDialogBuilderUserInput.create();
final AlertDialog alertDialog;
if (((MapActivity) getActivity()).coordsMap.containsKey(user.getId())) {
alertDialogBuilderUserInput.setPositiveButton(R.string.show_on_map, (dialog, id) -> {
// User cancelled the dialog
((MapActivity) getActivity()).activeFragment = ActiveFragment.NONE;
FragmentTransaction fragmentTransaction = getFragmentManager().beginTransaction();
fragmentTransaction.hide(usersListFragment);
fragmentTransaction.commit();
((MapActivity) getActivity()).searchUser(user.getFirstName());
((MapActivity) getActivity()).updateNavigationBarState();
});
}
alertDialog = alertDialogBuilderUserInput.create();
String userNoteText = tutorTabViewModel.getNote();
List<String> dutyHoursList = Stream.of(tutorTabViewModel.getDutyHours())
.map(DutyHourViewModel::getSummary).toList();
@ -168,6 +277,16 @@ public class UsersListFragment extends Fragment {
department.setText(String.format("%s: %s", getString(R.string.userDepartment), user.getDepartment()));
userDutyHoursTitle.setText(String.format("%s:", getString(R.string.userDutyHoursHeader)));
Coordinate coordinate = ((MapActivity) getActivity()).coordsMap.get(user.getId());
if (coordinate != null){
String label = coordinate.getLabel();
if (!label.isEmpty()) {
userStatusLabelLL.setVisibility(View.VISIBLE);
userStatusLabel.setText(String.format("%s: %s", getString(R.string.user_status_label),label));
}
}
final ArrayAdapter<String> arrayAdapter = new ArrayAdapter<>(getActivity(),
R.layout.duty_hours_item, dutyHoursList);
@ -185,39 +304,20 @@ public class UsersListFragment extends Fragment {
private void fetchAllTutors() {
disposable.add(
userService.getAllTutors()
(fetchOnlyOnlineUsers ?
userService.getAllActiveTutors() :
userService.getAllTutors())
.subscribeOn(Schedulers.io())
.observeOn(AndroidSchedulers.mainThread())
.map(tutors -> {
List<User> tutorsList = new ArrayList<>(tutors);
List<User> onlineTutors = Stream.of(tutorsList).filter(User::isIsOnline).toList();
List<User> activeNotOnlineTutors = Stream.of(tutorsList)
.filter(t -> t.isIsActive() && !onlineTutors.contains(t)).toList();
List<User> notActiveTutors = Stream.of(tutorsList)
.filterNot(User::isIsActive).toList();
Collections.sort(onlineTutors, this::sortByUserName);
Collections.sort(activeNotOnlineTutors, this::sortByUserName);
Collections.sort(notActiveTutors, this::sortByUserName);
List<User> sortedUserList = new ArrayList<>(onlineTutors);
sortedUserList.addAll(activeNotOnlineTutors);
sortedUserList.addAll(notActiveTutors);
return sortedUserList;
})
.map(this::mapUsersToSortedList)
.subscribeWith(new DisposableSingleObserver<List<User>>() {
@Override
public void onSuccess(List<User> users) {
tutorsList.clear();
tutorsFiltered.clear();
tutorsList.addAll(users);
tutorsFiltered.addAll(users);
mAdapter.notifyDataSetChanged();
toggleEmptyNotes();
fetchTopCords();
}
@Override
@ -227,6 +327,50 @@ public class UsersListFragment extends Fragment {
}));
}
private List<User> mapUsersToSortedList(List<User> tutors) {
List<User> tutorsList = new ArrayList<>(tutors);
List<User> onlineTutors = Stream.of(tutorsList).filter(User::isIsOnline).toList();
List<User> activeNotOnlineTutors = Stream.of(tutorsList)
.filter(t -> t.isIsActive() && !onlineTutors.contains(t)).toList();
List<User> notActiveTutors = Stream.of(tutorsList)
.filterNot(User::isIsActive).toList();
Collections.sort(onlineTutors, this::sortByUserName);
Collections.sort(activeNotOnlineTutors, this::sortByUserName);
Collections.sort(notActiveTutors, this::sortByUserName);
List<User> sortedUserList = new ArrayList<>(onlineTutors);
sortedUserList.addAll(activeNotOnlineTutors);
sortedUserList.addAll(notActiveTutors);
return sortedUserList;
}
private void searchTutorInBackend(String searchString) {
disposable.add(
userService.searchUser(searchString)
.subscribeOn(Schedulers.io())
.observeOn(AndroidSchedulers.mainThread())
.subscribeWith(new DisposableSingleObserver<List<User>>() {
@Override
public void onSuccess(List<User> users) {
tutorsList.clear();
tutorsList.addAll(users);
mAdapter.notifyDataSetChanged();
}
@Override
public void onError(Throwable e) {
showSearchError(e);
}
}));
}
public void restoreUsersList() {
fetchAllTutors();
fetchTopCords();
}
private int sortByUserName(User t1, User t2) {
return plCollator.compare(t1.getLastName(), t2.getLastName());
@ -234,26 +378,84 @@ public class UsersListFragment extends Fragment {
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() {
if (tutorsList.size() > 0) {
noNotesView.setVisibility(View.GONE);
} else {
loader.setVisibility(View.GONE);
noNotesView.setVisibility(View.GONE);
if (tutorsList.size() == 0) {
noNotesView.setVisibility(View.VISIBLE);
if (fetchOnlyOnlineUsers)
noNotesView.setText(R.string.no_online_users);
else {
noNotesView.setText(R.string.no_offline_users);
}
}
}
public void onSaveInstanceState(Bundle outState) {
super.onSaveInstanceState(outState);
}
private void fetchTopCords(){
disposable.add(
coordinateService.getTopCoordinates()
.subscribeOn(Schedulers.io())
.observeOn(AndroidSchedulers.mainThread())
.subscribe(this::addTimestamps,this::showError));
}
private void addTimestamps(List<Coordinate> coordinates) {
for (Coordinate crd :
coordinates) {
Long ts = crd.getTimeStamp();
tutorsTimeStamps.put(crd.getUserId(), getDate(ts));
}
mAdapter.notifyDataSetChanged();
}
private String getDate(long time) {
Calendar cal = Calendar.getInstance(Locale.ENGLISH);
cal.setTimeInMillis(time);
return DateFormat.format("HH:mm dd/MM", cal).toString();
}
@Override
public void onDestroy() {
super.onDestroy();
@ -276,7 +478,4 @@ public class UsersListFragment extends Fragment {
super.onStop();
}
public void onSaveInstanceState(Bundle outState) {
super.onSaveInstanceState(outState);
}
}
}

View File

@ -0,0 +1,363 @@
package com.uam.wmi.findmytutor.activity;
import android.annotation.SuppressLint;
import android.content.Context;
import android.graphics.drawable.ColorDrawable;
import android.os.Build;
import android.os.Bundle;
import android.support.annotation.RequiresApi;
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.github.ybq.android.spinkit.SpinKitView;
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.LocaleHelper;
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.disposables.Disposable;
import io.reactivex.functions.Function;
import io.reactivex.observers.DisposableObserver;
import io.reactivex.schedulers.Schedulers;
import okhttp3.ResponseBody;
public class WhiteList extends AppCompatActivity {
@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;
@BindView(R.id.loader)
SpinKitView loader;
private CompositeDisposable disposable = new CompositeDisposable();
private UserService userService;
private boolean didFetched = false;
private String tutorId;
private WhiteListAdapter mAdapter;
private Integer prevSize;
private List<User> whitelistedUsers = new ArrayList<>();
private Collator plCollator = Collator.getInstance(Locale.forLanguageTag("pl-PL"));
@Override
protected void attachBaseContext(Context base) {
super.attachBaseContext(LocaleHelper.onAttach(base));
}
@RequiresApi(api = Build.VERSION_CODES.M)
@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) +" "+getString(R.string.on) );
aSwitch.setChecked(true);
handleChangeRequest(true);
} else {
aSwitch.setText(getString(R.string.action_white_list) +" "+getString(R.string.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);
noNotesView.setVisibility(View.GONE);
/**
* 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<List<String>> getListOfWhitelistedUsers(String userId) {
return userService.getTutorWhitelistedByID(userId)
.toObservable()
.subscribeOn(Schedulers.io())
.observeOn(AndroidSchedulers.mainThread());
}
private Observable<User> getUserObservable(String userId) {
return userService
.getUserById(userId)
.toObservable()
.subscribeOn(Schedulers.io())
.observeOn(AndroidSchedulers.mainThread());
}
private void fetchWhiteListedUsers() {
disposable.add(getListOfWhitelistedUsers(tutorId)
.doOnSubscribe(this::handleDoOnSubscribe)
.subscribeOn(Schedulers.io())
.observeOn(AndroidSchedulers.mainThread())
.flatMap(Observable::fromIterable)
.flatMap(this::getUserObservable)
.subscribe(user -> whitelistedUsers.add(user), this::handleError,this::handleComplete));
}
private void handleDoOnSubscribe(Disposable disposable) {
prevSize = whitelistedUsers.size();
whitelistedUsers.clear();
didFetched = false;
}
private void handleComplete() {
Collections.sort(whitelistedUsers, this::sortByUserName);
didFetched = true;
refreshUI();
}
private void handleError(Throwable e){
showError(e);
didFetched = false;
}
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.setVisibility(View.VISIBLE);
noNotesView.setText(R.string.list_is_empty);
loader.setVisibility(View.GONE);
} else if (whitelistedUsers.size() > 0) {
noNotesView.setVisibility(View.GONE);
loader.setVisibility(View.GONE);
} else {
loader.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;
}
}

View File

@ -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<BlackListAdapter.MyViewHolder> {
private Context context;
private List<User> tutorsList;
private CompositeDisposable disposable = new CompositeDisposable();
private UserService userService;
public BlackListAdapter(Context context, List<User> 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();
}
}

View File

@ -0,0 +1,181 @@
package com.uam.wmi.findmytutor.adapters;
import android.app.DialogFragment;
import android.app.FragmentManager;
import android.content.Context;
import android.os.Bundle;
import android.support.annotation.NonNull;
import android.support.v7.widget.RecyclerView;
import android.text.Editable;
import android.text.TextWatcher;
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 com.annimon.stream.Collectors;
import com.annimon.stream.Stream;
import com.uam.wmi.findmytutor.R;
import com.uam.wmi.findmytutor.activity.TimePickerFragment;
import com.uam.wmi.findmytutor.model.DutyHourViewModel;
import java.util.ArrayList;
import java.util.List;
import butterknife.BindView;
import butterknife.ButterKnife;
public class DutyHoursAdapter extends RecyclerView.Adapter<DutyHoursAdapter.MyViewHolder> {
private Context context;
private List<DutyHourViewModel> hours;
private FragmentManager fragmentManager;
public DutyHoursAdapter(Context context, List<DutyHourViewModel> hours, FragmentManager fragmentManager) {
this.context = context;
this.hours = new ArrayList<DutyHourViewModel>(hours);
this.fragmentManager = fragmentManager;
}
public List<DutyHourViewModel> getDutyList(){
ArrayList<DutyHourViewModel> notEmpty = Stream.of(hours).filter(DutyHourViewModel::isValid).collect(Collectors.toCollection(ArrayList::new));
return notEmpty;
}
public void addDuty(DutyHourViewModel duty){
hours.add(duty);
}
private void removeDuty(int pos){
hours.remove(pos);
this.notifyItemRemoved(pos);
Log.d("DutyIndex af rm size",Integer.toString(getItemCount()));
}
@NonNull
@Override
public MyViewHolder onCreateViewHolder(@NonNull ViewGroup parent, int viewType) {
View itemView = LayoutInflater.from(parent.getContext())
.inflate(R.layout.duty_hour_row, parent, false);
return new MyViewHolder(itemView);
}
@Override
public void onBindViewHolder(@NonNull MyViewHolder holder, int position) {
DutyHourViewModel duty = hours.get(position);
holder.dutyDay.setText(duty.getDay());
holder.dutyDay.addTextChangedListener(new TextWatcher() {
@Override
public void beforeTextChanged(CharSequence s, int start, int count, int after) {
}
@Override
public void onTextChanged(CharSequence s, int start, int before, int count) {
}
@Override
public void afterTextChanged(Editable s) {
duty.setDay(holder.dutyDay.getText().toString());
}
});
holder.dutyStart.setText(duty.getStart());
/* holder.dutyStart.addTextChangedListener(new TextWatcher() {
@Override
public void beforeTextChanged(CharSequence s, int start, int count, int after) {
}
@Override
public void onTextChanged(CharSequence s, int start, int before, int count) {
}
@Override
public void afterTextChanged(Editable s) {
duty.setStart(holder.dutyStart.getText().toString());
}
});*/
holder.dutyStart.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
DialogFragment picker = new TimePickerFragment(holder.dutyStart,duty,"start");
picker.show(fragmentManager,"time picker");
}
});
holder.dutyStop.setText(duty.getEnd());
holder.dutyStop.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
DialogFragment picker = new TimePickerFragment(holder.dutyStop,duty,"stop");
picker.show(fragmentManager,"time picker");
}
});
/* holder.dutyStop.addTextChangedListener(new TextWatcher() {
@Override
public void beforeTextChanged(CharSequence s, int start, int count, int after) {
}
@Override
public void onTextChanged(CharSequence s, int start, int before, int count) {
}
@Override
public void afterTextChanged(Editable s) {
duty.setEnd(holder.dutyStop.getText().toString());
}
});*/
holder.deleteRow.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
try{
// Log.d("DutyIndex bf rm size",Integer.toString(getItemCount()));
// Log.d("DutyIndex bf rm pos",Integer.toString(holder.getLayoutPosition()));
removeDuty(holder.getLayoutPosition());
// Log.d("DutyIndex af rm pos",Integer.toString(holder.getLayoutPosition()));
}catch(Error e){
// Log.e("DutyIndex error",e.getMessage());
// Log.e("DutyIndex size",Integer.toString(getItemCount()));
// Log.e("DutyIndex pos",Integer.toString(holder.getAdapterPosition()));
}
}
});
}
@Override
public int getItemCount() {
return hours.size();
}
class MyViewHolder extends RecyclerView.ViewHolder {
@BindView(R.id.duty_day_value)
TextView dutyDay;
@BindView(R.id.duty_start_value)
TextView dutyStart;
@BindView(R.id.duty_stop_value)
TextView dutyStop;
@BindView(R.id.deleteRow)
ImageButton deleteRow;
MyViewHolder(View view) {
super(view);
ButterKnife.bind(this, view);
}
}
}

View File

@ -1,3 +1,4 @@
/*
package com.uam.wmi.findmytutor.adapters;
import android.content.Context;
@ -9,9 +10,11 @@ import android.view.View;
import android.view.ViewGroup;
import android.widget.TextView;
import com.github.ybq.android.spinkit.SpinKitView;
import com.uam.wmi.findmytutor.R;
import com.uam.wmi.findmytutor.model.User;
import java.util.HashMap;
import java.util.List;
import butterknife.BindView;
@ -22,10 +25,12 @@ public class TutorsListAdapter extends RecyclerView.Adapter<TutorsListAdapter.My
private Context context;
private List<User> tutorsList;
private HashMap<String, String> tutorsTimeStamps;
public TutorsListAdapter(Context context, List<User> tutors) {
public TutorsListAdapter(Context context, List<User> tutors, HashMap<String,String> tutorsTimeStamps) {
this.context = context;
this.tutorsList = tutors;
this.tutorsTimeStamps = tutorsTimeStamps;
}
@NonNull
@Override
@ -37,21 +42,36 @@ public class TutorsListAdapter extends RecyclerView.Adapter<TutorsListAdapter.My
}
@Override
public void onBindViewHolder(@NonNull MyViewHolder holder, int position) {
public void onBindViewHolder(@NonNull MyViewHolder holder, int position) {
Drawable image = null;
User tutor = tutorsList.get(position);
holder.firstName.setText(tutor.getFirstName());
holder.lastName.setText(tutor.getLastName());
holder.firstName.setText(String.format("%s %s", tutor.getFirstName(), tutor.getLastName()));
String ts = tutorsTimeStamps.get(tutor.getId());
if (tutor.isIsOnline()) {
image = context.getResources().getDrawable(R.drawable.user_list_online);
holder.lastSeen.setText(R.string.available_now);
holder.loader.setVisibility(View.GONE);
} else {
image = context.getResources().getDrawable(R.drawable.user_list_offline);
if (ts != null){
holder.lastSeen.setText(R.string.last_sign);
holder.lastSeen.append(String.format(": %s", ts));
holder.loader.setVisibility(View.GONE);
}
}
if (!tutor.isIsActive()) {
image = context.getResources().getDrawable(R.drawable.user_list_off);
if(ts != null){
holder.lastSeen.setText(R.string.last_sign);
holder.lastSeen.append(String.format(": %s", ts));
}else{
holder.lastSeen.setVisibility(View.GONE);
}
holder.loader.setVisibility(View.GONE);
}
image.setBounds(0, 0, image.getIntrinsicWidth(), image.getIntrinsicHeight());
@ -68,17 +88,132 @@ public class TutorsListAdapter extends RecyclerView.Adapter<TutorsListAdapter.My
@BindView(R.id.firstName)
TextView firstName;
@BindView(R.id.lastName)
TextView lastName;
@BindView(R.id.lastSeen)
TextView lastSeen;
@BindView(R.id.isOnline)
TextView isOnline;
@BindView(R.id.loader)
SpinKitView loader;
MyViewHolder(View view) {
super(view);
ButterKnife.bind(this, view);
}
}
}
*/
package com.uam.wmi.findmytutor.adapters;
import android.content.Context;
import android.graphics.drawable.Drawable;
import android.support.annotation.NonNull;
import android.support.v7.widget.RecyclerView;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.TextView;
import android.widget.Toast;
import com.github.ybq.android.spinkit.SpinKitView;
import com.uam.wmi.findmytutor.R;
import com.uam.wmi.findmytutor.model.User;
import java.util.HashMap;
import java.util.List;
import butterknife.BindView;
import butterknife.ButterKnife;
public class TutorsListAdapter extends RecyclerView.Adapter<TutorsListAdapter.MyViewHolder> {
private Context context;
private List<User> tutorsList;
private HashMap<String, String> tutorsTimeStamps;
public TutorsListAdapter(Context context, List<User> tutors, HashMap<String,String> tutorsTimeStamps) {
this.context = context;
this.tutorsList = tutors;
this.tutorsTimeStamps = tutorsTimeStamps;
}
@NonNull
@Override
public MyViewHolder onCreateViewHolder(@NonNull ViewGroup parent, int viewType) {
View itemView = LayoutInflater.from(parent.getContext())
.inflate(R.layout.tutor_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(String.format("%s %s", tutor.getFirstName(), tutor.getLastName()));
String ts = tutorsTimeStamps.get(tutor.getId());
if (tutor.isIsOnline()) {
image = context.getResources().getDrawable(R.drawable.user_list_online);
holder.lastSeen.setText(R.string.available_now);
holder.lastSeen.setVisibility(View.VISIBLE);
holder.loader.setVisibility(View.GONE);
} else if(tutor.isIsActive()){
image = context.getResources().getDrawable(R.drawable.user_list_offline);
if (ts != null){
holder.lastSeen.setText(R.string.last_sign);
holder.lastSeen.append(String.format(": %s", ts));
holder.loader.setVisibility(View.GONE);
}
} else {
image = context.getResources().getDrawable(R.drawable.user_list_off);
if(ts == null){
holder.lastSeen.setText(R.string.never_logged_in);
}else{
holder.lastSeen.setText(R.string.last_sign);
holder.lastSeen.append(String.format(": %s", ts));
}
holder.loader.setVisibility(View.GONE);
}
image.setBounds(0, 0, image.getIntrinsicWidth(), image.getIntrinsicHeight());
holder.isOnline.setCompoundDrawables(image, null, null, null);
}
@Override
public int getItemCount() {
return tutorsList.size();
}
class MyViewHolder extends RecyclerView.ViewHolder {
@BindView(R.id.firstName)
TextView firstName;
@BindView(R.id.lastSeen)
TextView lastSeen;
@BindView(R.id.isOnline)
TextView isOnline;
@BindView(R.id.loader)
SpinKitView loader;
MyViewHolder(View view) {
super(view);
ButterKnife.bind(this, view);
}
}
}
}

View File

@ -0,0 +1,117 @@
package com.uam.wmi.findmytutor.adapters;
import android.content.Context;
import android.graphics.drawable.Drawable;
import android.support.annotation.NonNull;
import android.support.v7.widget.RecyclerView;
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 WhiteListAdapter extends RecyclerView.Adapter<WhiteListAdapter.MyViewHolder> {
private Context context;
private List<User> tutorsList;
private CompositeDisposable disposable = new CompositeDisposable();
private UserService userService;
public WhiteListAdapter(Context context, List<User> 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();
}
}

View File

@ -24,6 +24,20 @@ public class DutyHourViewModel {
this.day = day;
return this;
}
public Boolean isValid(){
if(this.day.isEmpty()){
return false;
}else if( !this.start.isEmpty() && this.end.isEmpty() ){
return false;
}else{
return true;
}
}
public DutyHourViewModel(){
day="";
start="";
end="";
}
/**
* Get day
@ -94,10 +108,11 @@ public class DutyHourViewModel {
return Objects.hash(day, start, end);
}
public String getSummary() {
return this.getDay() + ": " + this.getStart() + " - " + this.getEnd();
}
@Override
public String toString() {
StringBuilder sb = new StringBuilder();

View File

@ -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;

View File

@ -33,11 +33,12 @@ public class TutorTabViewModel {
@SerializedName("dutyHours")
private List<DutyHourViewModel> dutyHours = null;
public TutorTabViewModel(String userId, String note){
public TutorTabViewModel(String userId, String room, String email, String note, List<DutyHourViewModel> dutyHours){
this.userId=userId;
// this.room=room;
// this.emailTutorTab=emailTutorTab;
this.room=room;
this.emailTutorTab=email;
this.note=note;
this.dutyHours = new ArrayList<DutyHourViewModel>(dutyHours);
}
public TutorTabViewModel tutorTabId(UUID tutorTabId) {

View File

@ -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,30 +25,30 @@ 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;
import com.uam.wmi.findmytutor.network.ApiClient;
import com.uam.wmi.findmytutor.utils.ApproximatedLocalization;
import com.uam.wmi.findmytutor.utils.Const;
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 com.uam.wmi.findmytutor.utils.WifiUtils;
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 +61,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<String> providers = new ArrayList<String>();
private LocationListener[] mLocationListeners;
private CircularFifoQueue<Location> coordinatesHistory = new CircularFifoQueue<Location>(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 +102,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 +115,26 @@ 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();
//Restart service when a user started using presence in GPS mode and wmi is currently available
if (WifiUtils.checkIfUserIsInRangeOfWmiWifi(getApplicationContext())
&& PrefUtils.getLocationLevel(getApplicationContext()).equals(SharingLevel.PRESENCE.toString())) {
restartService();
}
}
}
};
}
@Override
public void onCreate() {
Log.e(TAG, "onCreate");
@ -124,57 +148,107 @@ public class BackgroundLocalizationService extends Service {
startForeground(1001, notification);
}
mFusedLocationClient = LocationServices.getFusedLocationProviderClient(this);
if (!stopService) {
if (PrefUtils.getLocationLevel(getApplicationContext()).equals(SharingLevel.PRESENCE.toString())) {
if (WifiUtils.checkIfUserIsInRangeOfWmiWifi(getApplicationContext())) {
Location presenceFakeLoc = new Location("");
initializeLocationManager();
presenceFakeLoc.setLatitude(Const.presenceLatitude);
presenceFakeLoc.setLongitude(Const.presenceLongitude);
presenceFakeLoc.setAltitude(0);
createPresenceLooper(presenceFakeLoc);
} else {
createFusedLocationClient();
}
} else if (PrefUtils.getLocationLevel(getApplicationContext()).equals(SharingLevel.EXACT.toString())
|| PrefUtils.getLocationLevel(getApplicationContext()).equals(SharingLevel.APPROXIMATED.toString())
) {
createFusedLocationClient();
} else if (PrefUtils.getLocationLevel(getApplicationContext()).equals(SharingLevel.MANUAL.toString())) {
Location manualFakeLoc = new Location("");
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());
manualFakeLoc.setLatitude(0);
manualFakeLoc.setLongitude(0);
manualFakeLoc.setAltitude(0);
createLowBatteryLooper(manualFakeLoc);
}
}
}
providerIndex++;
private void createLowBatteryLooper(Location fakeLoc) {
mStatusChecker = () -> {
try {
sendCoordinateToBackend(fakeLoc);
} finally {
mHandler.postDelayed(mStatusChecker, notify_interval);
}
};
AsyncTask.execute(mStatusChecker);
}
private void createPresenceLooper(Location fakeLoc) {
mStatusChecker = () -> {
try {
if (WifiUtils.checkIfUserIsInRangeOfWmiWifi(getApplicationContext())) {
sendCoordinateToBackend(fakeLoc);
} else {
restartService();
}
} finally {
mHandler.postDelayed(mStatusChecker, notify_interval);
}
};
AsyncTask.execute(mStatusChecker);
}
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;
}
if (!stopService) {
mStatusChecker = () -> {
try {
getLocalizationFromListeners();
changeBackgroundMode();
} finally {
mHandler.postDelayed(mStatusChecker, notify_interval);
}
};
mLocationRequest = new LocationRequest();
AsyncTask.execute(mStatusChecker);
if (saveMode != 0) {
mLocationRequest.setPriority(LocationRequest.PRIORITY_HIGH_ACCURACY);
} else {
mLocationRequest.setPriority(LocationRequest.PRIORITY_LOW_POWER);
}
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() == coordinatesHistoryLength;
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 (shouldExtendTimeInterval) {
notify_interval = notify_interval_outside_building;
}
if (shouldAbbreviateTimeInterval) {
notify_interval = notify_interval_inside_building;
}
Integer changedMode = Long.valueOf(prevInterval).compareTo(Long.valueOf(notify_interval));
if (changedMode != 0) {
updateListeners();
}
}
@ -198,50 +272,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<String> providers1 = mLocationManager.getProviders(true);
Location bestLocation = null;
AtomicReference<Boolean> 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 +282,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 +340,7 @@ public class BackgroundLocalizationService extends Service {
latitude = location.getLatitude();
longitude = location.getLongitude();
altitude = location.getAltitude();
Log.e(TAG, "TASK" + latitude + " " + longitude);
approximatedLocalization = new ApproximatedLocalization(MapUtils.loadJsonFromAsset(getApplicationContext(), "building.geojson"));
approximatedBuildingPart = approximatedLocalization.getNameOfBuildingPart(Point.fromLngLat(longitude, latitude));
}
@ -331,6 +352,11 @@ public class BackgroundLocalizationService extends Service {
String status = (PrefUtils.isStatusEnabled(getApplicationContext())) ? PrefUtils.getUserStatus(getApplicationContext()) : "";
if (locationLevel.equals(SharingLevel.PRESENCE.toString())) {
if (!MapUtils.checkIfCoordinateIsValid(latitude, longitude)) {
coordinatesHistory.add(fakeLoc);
return null;
}
latitude = presenceLatitude;
longitude = presenceLongitude;
approximatedBuildingPart = presenceApproximatedName;
@ -345,6 +371,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,
@ -362,7 +394,6 @@ public class BackgroundLocalizationService extends Service {
.subscribeOn(Schedulers.io())
.observeOn(AndroidSchedulers.mainThread())
.subscribeWith(new DisposableCompletableObserver() {
@Override
public void onComplete() {
Log.e(TAG, "CoordinateSuccess");
@ -370,9 +401,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) {

View File

@ -25,7 +25,7 @@ public interface CoordinateService {
Single<List<Coordinate>> getCoordinatesByUserId(@Path("userId") String userId);
@GET("api/coordinates/userTop/{userId}")
Single<List<Coordinate>> getTopCoordinatesByUserId(@Path("userId") String userId);
Single <Coordinate> getTopCoordinateByUserId(@Path("userId") String userId);
@GET("api/coordinates/top")
Single<List<Coordinate>> getTopCoordinates();
@ -42,4 +42,6 @@ public interface CoordinateService {
@DELETE("api/coordinates/{id}")
Completable deleteCoordinatesById(@Path("id") String id);
}

View File

@ -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<List<PredefinedCoordViewModel>> getUserPredefinedCoords(@Path("tutorId") String tutorId);
@POST("api/users/predefined/coordinate/{tutorId}")
Single <PredefinedCoordViewModel> postUserPredefinedCoord(@Path("tutorId") String tutorId, @Body PredefinedCoordViewModel coord);
@HTTP(method = "DELETE", path = "api/users/predefined/coordinate/{tutorId}", hasBody = true)
Single<List<PredefinedCoordViewModel>> deleteUserPredefinedCoord(@Path("tutorId") String tutorId, @Body String uuid);
}

View File

@ -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<List<String>> getUserPredefinedStatuses(@Path("tutorId") String tutorId);
@POST("api/users/predefined/status/{tutorId}")
Single<List<String>> 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<List<String>> deleteUserPredefinedStatus(@Path("tutorId") String tutorId, @Body String status);
@GET("api/users/predefined/coordinate/{tutorId}")
/* @GET("api/users/predefined/coordinate/{tutorId}")
Single<List<PredefinedCoordViewModel>> getUserPredefinedCoords(@Path("tutorId") String tutorId);
@POST("api/users/predefined/coordinate/{tutorId}")
Single <PredefinedCoordViewModel> postUserPredefinedCoord(@Path("tutorId") String tutorId, @Body PredefinedCoordViewModel coord);
@DELETE("api/users/predefined/coordinate/{tutorId}")
Single<List<PredefinedCoordViewModel>> deleteUserPredefinedCoord(@Path("tutorId") String tutorId, @Body PredefinedCoordViewModel coord);
Single<List<PredefinedCoordViewModel>> deleteUserPredefinedCoord(@Path("tutorId") String tutorId, @Body PredefinedCoordViewModel coord);*/
}

View File

@ -3,8 +3,10 @@ package com.uam.wmi.findmytutor.service;
import com.uam.wmi.findmytutor.model.TutorTabViewModel;
import io.reactivex.Completable;
import io.reactivex.Observable;
import io.reactivex.Single;
import retrofit2.Response;
import retrofit2.http.*;
@ -16,7 +18,7 @@ public interface TutorTabApi {
* @return Call&lt;Void&gt;
*/
@POST("api/users/scrapTutorTab/{tutorId}")
Observable<Void> apiUsersScrapTutorTabByTutorIdPost(
Completable apiUsersScrapTutorTabByTutorIdPost(
@retrofit2.http.Path("tutorId") String tutorId
);
@ -26,7 +28,7 @@ public interface TutorTabApi {
* @return Call&lt;Void&gt;
*/
@POST("api/users/scrapTutorTab")
Observable<Void> apiUsersScrapTutorTabPost();
Single<Void> apiUsersScrapTutorTabPost();
/**
@ -40,6 +42,10 @@ public interface TutorTabApi {
@retrofit2.http.Path("tutorId") String tutorId
);
@POST("api/users/tutorTab/{tutorId}")
Single<TutorTabViewModel> apiUsersTutorTabByTutorIdPost(
@retrofit2.http.Path("tutorId") String tutorId, @retrofit2.http.Body TutorTabViewModel tutorTab
);
/**
*
*
@ -51,7 +57,7 @@ public interface TutorTabApi {
"Content-Type:application/json"
})
@PUT("api/users/tutorTab/{tutorId}")
Observable<TutorTabViewModel> apiUsersTutorTabByTutorIdPut(
Observable<Response<Void>> apiUsersTutorTabByTutorIdPut(
@retrofit2.http.Path("tutorId") String tutorId, @retrofit2.http.Body TutorTabViewModel tutorTab
);

View File

@ -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,21 @@ public interface UserService {
@GET("api/users/tutors")
Single <List<User>> getAllTutors();
@GET("api/users/tutors/online")
Single <List<User>> getAllOnlineTutors();
@GET("api/users/tutors/active")
Single <List<User>> getAllActiveTutors();
@GET("api/users/tutors/offline")
Single <List<User>> getAllOfflineTutors();
@GET("api/users/tutors/search")
Single <List<User>> searchUser(@Query(value = "searchString", encoded = true) String searchString);
@POST("api/users")
Completable createUser(@Body User user);
@ -45,6 +63,9 @@ public interface UserService {
@GET("api/users/{id}")
Single <User> getUserById(@Path("id") String userID);
@GET("api/users/self/{id}")
Single <User> getSelf(@Path("id") String userID);
@PUT("api/users/{id}")
Completable updateUserByID(@Path("id") String userID, @Body User user);
@ -61,26 +82,28 @@ public interface UserService {
Completable setUserInActive(@Path("userID") String userID);
@GET("api/users/blacklist/{tutorID}")
Single<List<User>> getTutorBlacklistedByID(@Path("tutorID") String tutorID);
Single <List<String>> 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 <User> 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<List<User>> getTutorwhitelistedByID(@Path("tutorID") String tutorID);
Single<List<String>> 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 <User> 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);
}

View File

@ -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;
@ -16,8 +17,10 @@ public class Const {
public final static String presenceApproximatedName = "Unknown";
public final static Range<Double> buildingLatitudeRange = Range.create(52.466092, 52.467529);
public final static Range<Double> buildingLongitudeRange = Range.create(16.926159, 16.927759);
public final static Range<Double> outsideLatitudeRange = Range.create(52.463512, 52.468837);
public final static Range<Double> outsideLongitudeRange = Range.create(16.922372, 16.936004);
public final static Range<Double> outsideLatitudeRange = Range.create(52.4651, 52.468837);
public final static Range<Double> outsideLongitudeRange = Range.create(16.9186, 16.936004);
public final static List<String> validApproximatedLocations = Arrays.asList("Skrzydło B", "Skrzydło A", "Aule", "Łącznik", "Biblioteka", "Hol", "Unknown");
public final static String WMI_SSID_NAME = "wmi";
}

View File

@ -0,0 +1,80 @@
package com.uam.wmi.findmytutor.utils;
import android.annotation.TargetApi;
import android.content.Context;
import android.content.SharedPreferences;
import android.content.res.Configuration;
import android.content.res.Resources;
import android.os.Build;
import android.preference.PreferenceManager;
import java.util.Locale;
public class LocaleHelper {
private static final String SELECTED_LANGUAGE = "Locale.Helper.Selected.Language";
public static Context onAttach(Context context) {
String lang = getPersistedData(context, Locale.getDefault().getLanguage());
return setLocale(context, lang);
}
public static Context onAttach(Context context, String defaultLanguage) {
String lang = getPersistedData(context, defaultLanguage);
return setLocale(context, lang);
}
public static String getLanguage(Context context) {
return getPersistedData(context, Locale.getDefault().getLanguage());
}
public static Context setLocale(Context context, String language) {
persist(context, language);
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.N) {
return updateResources(context, language);
}
return updateResourcesLegacy(context, language);
}
private static String getPersistedData(Context context, String defaultLanguage) {
SharedPreferences preferences = PreferenceManager.getDefaultSharedPreferences(context);
return preferences.getString(SELECTED_LANGUAGE, defaultLanguage);
}
private static void persist(Context context, String language) {
SharedPreferences preferences = PreferenceManager.getDefaultSharedPreferences(context);
SharedPreferences.Editor editor = preferences.edit();
editor.putString(SELECTED_LANGUAGE, language);
editor.apply();
}
@TargetApi(Build.VERSION_CODES.N)
private static Context updateResources(Context context, String language) {
Locale locale = new Locale(language);
Locale.setDefault(locale);
Configuration configuration = context.getResources().getConfiguration();
configuration.setLocale(locale);
return context.createConfigurationContext(configuration);
}
@SuppressWarnings("deprecation")
private static Context updateResourcesLegacy(Context context, String language) {
Locale locale = new Locale(language);
Locale.setDefault(locale);
Resources resources = context.getResources();
Configuration configuration = resources.getConfiguration();
configuration.locale = locale;
resources.updateConfiguration(configuration, resources.getDisplayMetrics());
return context;
}
}

View File

@ -1,10 +1,32 @@
package com.uam.wmi.findmytutor.utils;
import android.content.Context;
import android.content.res.Configuration;
import android.content.res.Resources;
import android.os.Build;
import android.support.v4.os.ConfigurationCompat;
import java.util.Locale;
public class LocaleUtils {
public static String getCurrentLocale(){
return String.valueOf(ConfigurationCompat.getLocales(Resources.getSystem().getConfiguration()));
public static String getCurrentLocale() {
return String.valueOf(ConfigurationCompat.getLocales(Resources.getSystem().getConfiguration()));
}
private static Context updateResources(Context context, String language) {
Locale locale = new Locale(language);
Locale.setDefault(locale);
Resources res = context.getResources();
Configuration config = new Configuration(res.getConfiguration());
if (Build.VERSION.SDK_INT >= 22) {
config.setLocale(locale);
context = context.createConfigurationContext(config);
} else {
config.locale = locale;
res.updateConfiguration(config, res.getDisplayMetrics());
}
return context;
}
}

View File

@ -1,8 +1,12 @@
package com.uam.wmi.findmytutor.utils;
import android.animation.TypeEvaluator;
import android.app.AlertDialog;
import android.content.Context;
import android.content.Intent;
import android.location.Location;
import android.net.Uri;
import android.provider.Settings;
import com.mapbox.mapboxsdk.camera.CameraPosition;
import com.mapbox.mapboxsdk.camera.CameraUpdateFactory;
@ -10,12 +14,15 @@ import com.mapbox.mapboxsdk.geometry.LatLng;
import com.mapbox.mapboxsdk.geometry.LatLngBounds;
import com.mapbox.mapboxsdk.maps.MapView;
import com.mapbox.mapboxsdk.maps.MapboxMap;
import com.uam.wmi.findmytutor.R;
import java.io.IOException;
import java.io.InputStream;
import static com.uam.wmi.findmytutor.utils.Const.outsideLongitudeRange;
import static com.mapbox.mapboxsdk.Mapbox.getApplicationContext;
import static com.uam.wmi.findmytutor.utils.Const.outsideLatitudeRange;
import static com.uam.wmi.findmytutor.utils.Const.outsideLongitudeRange;
import static com.uam.wmi.findmytutor.utils.PrefUtils.shouldBatteryExclusionBeShown;
public class MapUtils {
@ -41,8 +48,8 @@ public class MapUtils {
// Map Bounds Area
public static void setZoom(MapboxMap mapboxMap, Integer zoom) {
makeNewCamera(mapboxMap, 52.466799, 16.927002, zoom, 0, 0, 1000);
mapboxMap.setMinZoomPreference(16); // TODO export to map config
makeNewCamera(mapboxMap, 52.466799, 16.927002, zoom, 0, 0, 1000);
mapboxMap.setMinZoomPreference(16); // TODO export to map config
}
public static void makeNewCamera(MapboxMap mapboxMap, double lat, double lon, int zoomParam, int bearingParam, int tiltParam, int duration) {
@ -73,8 +80,32 @@ public class MapUtils {
}
}
public static Boolean checkIfCoordinateIsValid(Location coordinate){
return outsideLatitudeRange.contains(coordinate.getLatitude()) && outsideLongitudeRange.contains(coordinate.getLongitude());
public static Boolean checkIfCoordinateIsValid(Location coordinate) {
return outsideLatitudeRange.contains(coordinate.getLatitude()) && outsideLongitudeRange.contains(coordinate.getLongitude());
}
public static Boolean checkIfCoordinateIsValid(Double latitude, Double longitude) {
return Const.buildingLatitudeRange.contains(latitude) && Const.buildingLongitudeRange.contains(longitude);
}
public static void BatteryOptimizationsExceptionCheck(Context context) {
if (shouldBatteryExclusionBeShown(getApplicationContext())) {
PrefUtils.setBatteryExlusionInfoStatus(getApplicationContext(), false);
AlertDialog.Builder builder = new AlertDialog.Builder(context);
builder.setTitle(R.string.batter_exclusions_title);
builder.setMessage(R.string.batter_exclusions_message)
.setPositiveButton(R.string.ok, (dialog, id) -> {
Intent intent = new Intent();
intent.setAction(Settings.ACTION_APPLICATION_DETAILS_SETTINGS);
Uri uri = Uri.fromParts("package", getApplicationContext().getPackageName(), null);
intent.setData(uri);
context.startActivity(intent);
})
.setNegativeButton(R.string.cancel, (dialog, id) -> {
}).show();
}
}
// Function for marker animation

View File

@ -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,44 @@ 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);
}
public static Boolean shouldBatteryExclusionBeShown(Context context) {
return getSharedPreferences(context).getBoolean("show_battery_exclusion", false);
}
public static void setBatteryExlusionInfoStatus(Context context, Boolean flag) {
SharedPreferences.Editor editor = getSharedPreferences(context).edit();
editor.putBoolean("show_battery_exclusion", flag);
editor.apply();
}
}

View File

@ -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,63 @@ 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);
init(context, attrs);
}
private void init(Context context, AttributeSet attrs){
for (int i=0;i<attrs.getAttributeCount();i++) {
String attr = attrs.getAttributeName(i);
try {
if(attr.equalsIgnoreCase("key")){
Log.e("BUTTON_ERR",attr);
String val = attrs.getAttributeValue(i);
switch (val) {
case "remove_manual_status":
buttonText = context.getResources().getString(R.string.preference_manual_location_button_remove);
break;
case "manual_location_button":
buttonText = context.getResources().getString(R.string.preference_manual_location_button);
break;
case "remove_manual_location":
buttonText = context.getResources().getString(R.string.preference_manual_location_button_remove);
break;
}
}
} catch (Exception e) {
buttonText = "";
Log.e("BUTTON_ERR", String.valueOf(e));
}
}
}
public void setText(String text){
prefButton.setText(text);
}
@Override
protected View onCreateView(ViewGroup parent) {
View view = super.onCreateView(parent);
// LayoutInflater li = (LayoutInflater)getContext().getSystemService( Context.LAYOUT_INFLATER_SERVICE );
// View temp =li.inflate( R.layout.preference_button_widget, parent, false);
return view;
return super.onCreateView(parent);
}
@Override
protected void onBindView(View view)
{
super.onBindView(view);
Button button = (Button)view.findViewById(R.id.button_choose_from_map);
if(button != null)
prefButton = view.findViewById(R.id.button_choose_from_map);
prefButton.setText(buttonText);
if(prefButton != null)
{
button.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View view) {
callChangeListener(null);
notifyChanged();
}
});
prefButton.setOnClickListener(view1 -> {
callChangeListener(null);
notifyChanged();
});
}
}

View File

@ -1,16 +1,13 @@
package com.uam.wmi.findmytutor.utils;
import android.support.v7.widget.SearchView;
import io.reactivex.Observable;
import io.reactivex.subjects.PublishSubject;
public class RxSearchObservable {
private RxSearchObservable() {
// no instance
}
public static Observable<String> fromView(SearchView searchView) {
@ -21,6 +18,7 @@ public class RxSearchObservable {
@Override
public boolean onQueryTextSubmit(String s) {
subject.onNext(s);
searchView.clearFocus();
return false;
}
@ -29,11 +27,8 @@ public class RxSearchObservable {
subject.onNext(text);
return false;
}
});
return subject;
}
}

View File

@ -0,0 +1,30 @@
package com.uam.wmi.findmytutor.utils;
import android.content.Context;
import android.net.NetworkInfo;
import android.net.wifi.WifiInfo;
import android.net.wifi.WifiManager;
import android.util.Log;
import java.util.Objects;
public class WifiUtils {
public static String getWifiName(Context context) {
WifiManager manager = (WifiManager) context.getApplicationContext().getSystemService(Context.WIFI_SERVICE);
if (Objects.requireNonNull(manager).isWifiEnabled()) {
WifiInfo wifiInfo = manager.getConnectionInfo();
if (wifiInfo != null) {
NetworkInfo.DetailedState state = WifiInfo.getDetailedStateOf(wifiInfo.getSupplicantState());
if (state == NetworkInfo.DetailedState.CONNECTED || state == NetworkInfo.DetailedState.OBTAINING_IPADDR) {
return wifiInfo.getSSID();
}
}
}
return null;
}
public static Boolean checkIfUserIsInRangeOfWmiWifi(Context context) {
return Objects.equals(getWifiName(context), Const.WMI_SSID_NAME);
}
}

View File

@ -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();
}
}
}

View File

@ -0,0 +1,13 @@
<?xml version="1.0" encoding="utf-8"?>
<vector xmlns:android="http://schemas.android.com/apk/res/android"
android:width="24dp"
android:height="24dp"
android:viewportWidth="24"
android:viewportHeight="24">
<path
android:pathData="M0 0h24v24H0z" />
<path
android:fillColor="#FFFFFF"
android:pathData="M15 12c2.21 0 4-1.79 4-4s-1.79-4-4-4-4 1.79-4 4 1.79 4 4 4zm-9-2V7H4v3H1v2h3v3h2v-3h3v-2H6zm9 4c-2.67 0-8 1.34-8 4v2h16v-2c0-2.66-5.33-4-8-4z" />
</vector>

View File

@ -0,0 +1,15 @@
<?xml version="1.0" encoding="utf-8"?>
<vector xmlns:android="http://schemas.android.com/apk/res/android"
android:width="24dp"
android:height="24dp"
android:viewportWidth="24"
android:viewportHeight="24">
<path
android:pathData="M0 0h24v24H0z" />
<path
android:fillColor="#FFFF"
android:pathData="M2 12C2 6.48 6.48 2 12 2s10 4.48 10 10-4.48 10-10 10S2 17.52 2 12zm10 6c3.31 0 6-2.69 6-6s-2.69-6-6-6-6 2.69-6 6 2.69 6 6 6z" />
<path
android:pathData="M0 0h24v24H0z" />
</vector>

View File

@ -0,0 +1,13 @@
<?xml version="1.0" encoding="utf-8"?>
<vector xmlns:android="http://schemas.android.com/apk/res/android"
android:width="24dp"
android:height="24dp"
android:viewportWidth="24"
android:viewportHeight="24">
<path
android:fillColor="#ffffff"
android:pathData="M22 10l-6-6H4c-1.1 0-2 0.9-2 2v12.01c0 1.1 0.9 1.99 2 1.99l16-0.01c1.1 0 2-0.89 2-1.99v-8zm-7-4.5l5.5 5.5H15V5.5z" />
<path
android:pathData="M0 0h24v24H0V0z" />
</vector>

View File

@ -0,0 +1,83 @@
<?xml version="1.0" encoding="utf-8"?>
<android.support.design.widget.CoordinatorLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:fitsSystemWindows="true"
android:id="@+id/activity_blacklist_container"
tools:context=".activity.BlackList">
<android.support.design.widget.AppBarLayout
android:id="@+id/app_bar"
android:layout_width="match_parent"
android:layout_height="@dimen/app_bar_height"
android:fitsSystemWindows="true"
android:theme="@style/AppTheme.AppBarOverlay">
<android.support.design.widget.CollapsingToolbarLayout
android:id="@+id/toolbar_layout"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:fitsSystemWindows="true"
app:contentScrim="?attr/colorPrimary"
app:layout_scrollFlags="scroll|exitUntilCollapsed"
app:expandedTitleGravity="top|right"
app:toolbarId="@+id/toolbar"
>
<LinearLayout
android:layout_width="match_parent"
android:layout_height="match_parent"
android:gravity="left|bottom"
android:orientation="vertical"
android:padding="10dp"
android:layout_marginBottom="20dp"
app:layout_collapseMode="parallax">
<TextView
android:id="@+id/tv_title"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_alignParentRight="true"
android:text="@string/block_the_users"
android:textSize="15sp"/>
<Switch
android:id="@+id/switch_blacklist_toggle"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:thumbTextPadding="45dp"
android:text="BLACKLIST TEXT SWITCH" />
</LinearLayout>
<android.support.v7.widget.Toolbar
android:id="@+id/toolbar"
android:layout_width="match_parent"
android:layout_height="?attr/actionBarSize"
app:layout_collapseMode="pin"
app:popupTheme="@style/AppTheme.PopupOverlay"
/>
</android.support.design.widget.CollapsingToolbarLayout>
</android.support.design.widget.AppBarLayout>
<include layout="@layout/content_black_list" />
<android.support.design.widget.FloatingActionButton
android:id="@+id/add_to_black_list_fab"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_margin="@dimen/fab_margin"
android:layout_marginTop="-322dp"
app:layout_anchor="@id/app_bar"
app:layout_anchorGravity="bottom|end"
app:srcCompat="@drawable/ic_add_person"
app:useCompatPadding="true"
tools:srcCompat="@tools:sample/backgrounds/scenic" />
<!-- A RecyclerView with some commonly used attributes -->
</android.support.design.widget.CoordinatorLayout>

View File

@ -4,13 +4,13 @@
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:fontFamily="@font/lato_regular"
android:gravity="center_horizontal"
android:orientation="vertical"
android:paddingBottom="@dimen/activity_vertical_margin"
android:paddingLeft="@dimen/activity_horizontal_margin"
android:paddingRight="@dimen/activity_horizontal_margin"
android:paddingTop="@dimen/activity_vertical_margin"
android:fontFamily="@font/lato_regular"
android:paddingRight="@dimen/activity_horizontal_margin"
android:paddingBottom="@dimen/activity_vertical_margin"
tools:context=".activity.LoginActivity">
@ -58,6 +58,7 @@
<android.support.design.widget.TextInputLayout
android:layout_width="match_parent"
app:passwordToggleEnabled="true"
android:layout_height="wrap_content">
<EditText
@ -74,7 +75,6 @@
</android.support.design.widget.TextInputLayout>
<Button
android:id="@+id/email_sign_in_button"
style="?android:textAppearanceSmall"
@ -84,7 +84,6 @@
android:text="@string/action_log_in"
android:textStyle="bold" />
</LinearLayout>
</ScrollView>
</LinearLayout>

View File

@ -5,30 +5,29 @@
android:layout_width="match_parent"
android:layout_height="match_parent"
android:fontFamily="@font/lato_regular"
android:id="@+id/activity_tutor_tab"
tools:context=".activity.TutorTab">
<android.support.design.widget.AppBarLayout
android:id="@+id/app_bar"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_height="@dimen/app_bar_height"
android:fitsSystemWindows="true"
android:theme="@style/AppTheme.AppBarOverlay">
<android.support.v7.widget.Toolbar
android:id="@+id/toolbar"
<android.support.design.widget.CollapsingToolbarLayout
android:id="@+id/toolbar_layout"
android:layout_width="match_parent"
android:layout_height="?attr/actionBarSize"
android:background="?attr/colorPrimary"
app:popupTheme="@style/AppTheme.PopupOverlay" />
android:layout_height="match_parent"
android:fitsSystemWindows="true"
app:contentScrim="?attr/colorPrimary"
app:layout_scrollFlags="scroll|exitUntilCollapsed"
app:expandedTitleGravity="top|right"
app:toolbarId="@+id/toolbar"
/>
</android.support.design.widget.AppBarLayout>
<include layout="@layout/content_tutor_tab" />
<android.support.design.widget.FloatingActionButton
android:id="@+id/fab"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_gravity="bottom|end"
android:layout_margin="@dimen/fab_margin"
app:srcCompat="@android:drawable/ic_dialog_email" />
</android.support.design.widget.CoordinatorLayout>

View File

@ -0,0 +1,83 @@
<?xml version="1.0" encoding="utf-8"?>
<android.support.design.widget.CoordinatorLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:fitsSystemWindows="true"
android:id="@+id/activity_whitelist_container"
tools:context=".activity.WhiteList">
<android.support.design.widget.AppBarLayout
android:id="@+id/app_bar"
android:layout_width="match_parent"
android:layout_height="@dimen/app_bar_height"
android:fitsSystemWindows="true"
android:theme="@style/AppTheme.AppBarOverlay">
<android.support.design.widget.CollapsingToolbarLayout
android:id="@+id/toolbar_layout"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:fitsSystemWindows="true"
app:contentScrim="?attr/colorPrimary"
app:layout_scrollFlags="scroll|exitUntilCollapsed"
app:expandedTitleGravity="top|right"
app:toolbarId="@+id/toolbar"
>
<LinearLayout
android:layout_width="match_parent"
android:layout_height="match_parent"
android:gravity="left|bottom"
android:orientation="vertical"
android:padding="10dp"
android:layout_marginBottom="20dp"
app:layout_collapseMode="parallax">
<TextView
android:id="@+id/tv_title"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_alignParentRight="true"
android:text="@string/be_visible_for_these_users"
android:textSize="15sp"/>
<Switch
android:id="@+id/switch_whitelist_toggle"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:thumbTextPadding="45dp"
android:text="WHITELIST TEXT SWITCH" />
</LinearLayout>
<android.support.v7.widget.Toolbar
android:id="@+id/toolbar"
android:layout_width="match_parent"
android:layout_height="?attr/actionBarSize"
app:layout_collapseMode="pin"
app:popupTheme="@style/AppTheme.PopupOverlay"
/>
</android.support.design.widget.CollapsingToolbarLayout>
</android.support.design.widget.AppBarLayout>
<include layout="@layout/content_white_list" />
<android.support.design.widget.FloatingActionButton
android:id="@+id/add_to_white_list_fab"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_margin="@dimen/fab_margin"
android:layout_marginTop="-322dp"
app:layout_anchor="@id/app_bar"
app:layout_anchorGravity="bottom|end"
app:srcCompat="@drawable/ic_add_person"
app:useCompatPadding="true"
tools:srcCompat="@tools:sample/backgrounds/scenic" />
<!-- A RecyclerView with some commonly used attributes -->
</android.support.design.widget.CoordinatorLayout>

View File

@ -0,0 +1,42 @@
<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:fontFamily="@font/lato_regular"
android:orientation="vertical"
android:paddingLeft="@dimen/activity_horizontal_margin"
android:paddingTop="@dimen/activity_vertical_margin"
android:paddingRight="@dimen/activity_horizontal_margin"
android:paddingBottom="@dimen/activity_vertical_margin">
<TextView
android:id="@+id/black_list_modal_title"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_alignStart="@+id/black_list_modal_input"
android:layout_marginBottom="@dimen/dimen_10"
android:fontFamily="sans-serif-medium"
android:lineSpacingExtra="8sp"
android:text="@string/black_list_title"
android:textColor="@color/colorAccent"
android:textSize="@dimen/lbl_new_note_title"
android:textStyle="normal" />
<EditText
android:id="@+id/black_list_modal_input"
android:layout_width="315dp"
android:layout_height="wrap_content"
android:layout_alignParentTop="true"
android:layout_centerHorizontal="true"
android:layout_marginTop="50dp"
android:ems="10"
android:hint="@string/index_user"
android:maxLength="30"
android:maxLines="1"
android:requiresFadingEdge="vertical"
android:scrollbars="vertical"
android:textColor="@color/note_list_text" />
</RelativeLayout>

View File

@ -0,0 +1,48 @@
<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
android:layout_width="match_parent"
android:layout_height="90dp"
android:clickable="true"
android:focusable="true"
android:paddingLeft="10dp"
android:paddingTop="@dimen/dimen_10"
android:paddingRight="10dp"
android:fontFamily="@font/lato_regular"
android:paddingBottom="@dimen/dimen_10">
<TextView
android:id="@+id/firstName"
android:layout_width="271dp"
android:layout_height="22dp"
android:layout_alignParentStart="true"
android:layout_alignParentTop="true"
android:layout_marginStart="12dp"
android:layout_marginTop="10dp"
android:textColor="@color/note_list_text"
android:textSize="15sp" />
<TextView
android:id="@+id/lastName"
android:layout_width="270dp"
android:layout_height="22dp"
android:layout_below="@+id/firstName"
android:layout_alignEnd="@+id/firstName"
android:layout_marginTop="10dp"
android:layout_marginEnd="0dp"
android:textColor="@color/note_list_text"
android:textSize="15sp" />
<ImageButton
android:id="@+id/removeUserImageButton"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_below="@+id/firstName"
android:layout_toEndOf="@+id/firstName"
android:background="@null"
android:layout_alignParentEnd="true"
app:srcCompat="@drawable/abc_ic_clear_material" />
</RelativeLayout>

View File

@ -0,0 +1,48 @@
<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
app:layout_behavior="@string/appbar_scrolling_view_behavior"
tools:context=".activity.UsersListFragment"
android:fontFamily="@font/lato_regular"
tools:showIn="@layout/users_list_main">
<android.support.v7.widget.RecyclerView
android:id="@+id/recycler_view_blacklist"
android:layout_width="match_parent"
android:layout_height="match_parent" />
<TextView
android:id="@+id/black_list_empty_text_view"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_centerHorizontal="true"
android:layout_marginTop="@dimen/margin_top_no_notes"
android:fontFamily="sans-serif-light"
android:text="@string/loading"
android:textColor="@color/msg_no_notes"
android:textSize="@dimen/msg_no_notes" />
<com.github.ybq.android.spinkit.SpinKitView
xmlns:app="http://schemas.android.com/apk/res-auto"
android:id="@+id/loader"
style="@style/SpinKitView.Large.Wave"
android:layout_width="150dp"
android:layout_height="150dp"
app:SpinKit_Color="@color/msg_no_notes"
android:layout_centerHorizontal="true"
android:layout_marginTop="@dimen/margin_top_no_notes"
android:fontFamily="sans-serif-light"
android:text="@string/loading"
android:textColor="@color/msg_no_notes"
android:textSize="@dimen/msg_no_notes" />
</RelativeLayout>

View File

@ -1,93 +1,61 @@
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:mapbox="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical"
android:fontFamily="@font/lato_regular"
android:paddingLeft="@dimen/activity_margin"
android:paddingRight="@dimen/activity_margin"
android:paddingTop="@dimen/activity_margin">
<ImageButton
android:id="@+id/contentTutorTabInfoImageButton"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_gravity="right"
mapbox:srcCompat="@drawable/outline_info_24"/>
<TextView android:id="@+id/userName"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginBottom="@dimen/dimen_10"
android:fontFamily="sans-serif-medium"
android:lineSpacingExtra="8sp"
android:textColor="@color/mapboxRedDark"
android:textSize="@dimen/lbl_new_note_title"
android:textStyle="normal" />
<TextView
android:id="@+id/userDepartment"
<android.support.design.widget.CoordinatorLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:lineSpacingExtra="8sp"
android:paddingTop="5dp"
android:textColor="@color/note_list_text"
/>
android:layout_height="match_parent"
android:fitsSystemWindows="true"
android:id="@+id/activity_tutor_content"
tools:context=".activity.TutorTab">
<TextView
android:id="@+id/userRoom"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:lineSpacingExtra="8sp"
android:paddingTop="5dp"
android:textColor="@color/note_list_text"
/>
<TextView
android:id="@+id/userEmail"
<android.support.design.widget.AppBarLayout
android:id="@+id/app_bar"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:lineSpacingExtra="8sp"
android:paddingTop="5dp"
android:textColor="@color/note_list_text" />
android:layout_height="132dp"
android:fitsSystemWindows="true"
android:theme="@style/AppTheme.AppBarOverlay">
<TextView
android:id="@+id/userDutyHours"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:lineSpacingExtra="8sp"
android:paddingTop="5dp"
android:textColor="@color/note_list_text"
tools:text="@string/dutyHours" />
<android.support.design.widget.CollapsingToolbarLayout
android:id="@+id/toolbar_layout"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:fitsSystemWindows="true"
app:contentScrim="?attr/colorPrimary"
app:expandedTitleGravity="top|right"
app:layout_scrollFlags="scroll|exitUntilCollapsed"
app:toolbarId="@+id/toolbar">
<TextView
android:id="@+id/userNoteTitle"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:paddingTop="0dp"
android:paddingBottom="0dp"
android:paddingStart="@dimen/activity_margin"
android:textColor="@color/note_list_text" />
<EditText
android:id="@+id/userNote"
android:layout_width="match_parent"
android:layout_height="150dp"
android:lineSpacingExtra="8sp"
android:paddingTop="5dp"
android:textColor="@color/note_list_text"
android:hint="@string/tutorTabHint"
android:inputType="textMultiLine"
android:maxLength="1000"
android:maxLines="7"
android:requiresFadingEdge="vertical"
android:scrollbars="vertical"/>
<LinearLayout
android:layout_width="match_parent"
android:layout_height="match_parent"
android:layout_marginBottom="20dp"
android:gravity="left|bottom"
android:orientation="vertical"
android:padding="10dp"
app:layout_collapseMode="parallax">
<Button
android:id="@+id/saveButon"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:text="@string/saveButton" />
<TextView
android:id="@+id/userName"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_alignParentRight="true"
android:text="User Name"
android:textSize="22sp" />
</LinearLayout>
</LinearLayout>
<android.support.v7.widget.Toolbar
android:id="@+id/toolbar"
android:layout_width="match_parent"
android:layout_height="?attr/actionBarSize"
app:layout_collapseMode="pin"
app:popupTheme="@style/AppTheme.PopupOverlay" />
</android.support.design.widget.CollapsingToolbarLayout>
</android.support.design.widget.AppBarLayout>
<include layout="@layout/content_tutor_tab_layout" />
</android.support.design.widget.CoordinatorLayout>

View File

@ -0,0 +1,215 @@
<?xml version="1.0" encoding="utf-8"?>
<android.support.v4.widget.NestedScrollView xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
xmlns:app="http://schemas.android.com/apk/res-auto"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:fillViewport="true"
app:layout_behavior="@string/appbar_scrolling_view_behavior"
tools:context=".activity.TutorTab"
android:fontFamily="@font/lato_regular"
tools:showIn="@layout/content_tutor_tab">
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:fontFamily="@font/lato_regular"
app:layout_behavior="@string/appbar_scrolling_view_behavior"
tools:context=".activity.TutorTab">
<android.support.design.widget.TextInputLayout
android:id="@+id/userDepartmentLayout"
android:layout_width="189dp"
android:layout_height="wrap_content"
android:layout_below="@+id/userEmailLayout"
android:layout_alignParentEnd="true"
android:layout_marginStart="25dp"
android:layout_marginTop="10dp"
android:layout_marginEnd="30dp"
android:layout_toEndOf="@+id/userRoomLayout">
<android.support.design.widget.TextInputEditText
android:id="@+id/userDepartment"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_below="@+id/userDepartmentLayout"
android:layout_alignStart="@+id/userDepartmentLayout"
android:layout_alignTop="@+id/userDepartmentLayout"
android:hint="@string/hint_department"
android:inputType="text"
android:lineSpacingExtra="8sp"
android:maxLines="1"
android:paddingTop="5dp"
android:textColor="@color/note_list_text" />
</android.support.design.widget.TextInputLayout>
<android.support.design.widget.TextInputLayout
android:id="@+id/userRoomLayout"
android:layout_width="115dp"
android:layout_height="wrap_content"
android:layout_below="@+id/userEmailLayout"
android:layout_alignParentStart="true"
android:layout_marginStart="30dp"
android:layout_marginTop="10dp">
<android.support.design.widget.TextInputEditText
android:id="@+id/userRoom"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:layout_below="@+id/userRoomLayout"
android:layout_alignTop="@+id/userRoomLayout"
android:hint="@string/hint_room"
android:inputType="text"
android:lineSpacingExtra="8sp"
android:maxLines="1"
android:paddingTop="5dp"
android:textColor="@color/note_list_text" />
</android.support.design.widget.TextInputLayout>
<TextView
android:id="@+id/personalInfoTitle"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_alignStart="@+id/userRoomLayout"
android:layout_alignParentTop="true"
android:layout_marginTop="30dp"
android:layout_marginStart="5dp"
android:text="@string/personalInfoTitle"
android:textColor="@color/mapboxRedDark"
android:textSize="18sp"
android:textStyle="bold" />
<android.support.design.widget.TextInputLayout
android:id="@+id/userEmailLayout"
android:layout_width="326dp"
android:layout_height="wrap_content"
android:layout_alignParentStart="true"
android:layout_alignParentTop="true"
android:layout_alignParentEnd="true"
android:layout_marginStart="30dp"
android:layout_marginTop="70dp"
android:layout_marginEnd="30dp">
<android.support.design.widget.TextInputEditText
android:id="@+id/userEmail"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_alignStart="@+id/userEmailLayout"
android:layout_alignTop="@+id/userEmailLayout"
android:hint="@string/hint_email"
android:inputType="textEmailAddress"
android:lineSpacingExtra="8sp"
android:maxLines="1"
android:paddingTop="5dp"
android:textColor="@color/note_list_text" />
</android.support.design.widget.TextInputLayout>
<TextView
android:id="@+id/dutyTitle"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_below="@+id/userRoomLayout"
android:layout_alignStart="@+id/userRoomLayout"
android:layout_marginStart="5dp"
android:layout_marginEnd="30dp"
android:layout_marginTop="10dp"
android:gravity="center"
android:text="@string/dutyTitle"
android:textColor="@color/mapboxRedDark"
android:textSize="18sp"
android:textStyle="bold" />
<android.support.v7.widget.RecyclerView
android:id="@+id/dutyHourView"
android:layout_width="match_parent"
android:layout_height="120dp"
android:layout_below="@+id/addDuty"
android:layout_alignParentStart="true"
android:layout_marginStart="30dp"
android:layout_marginTop="15dp"
android:layout_marginEnd="50dp"
android:scrollbars="vertical" />
<TextView
android:id="@+id/userNoteTitle"
android:textStyle="bold"
android:layout_marginStart="5dp"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_below="@+id/dutyHourView"
android:layout_alignStart="@+id/userRoomLayout"
android:text="@string/userNoteTitle"
android:textColor="@color/mapboxRedDark"
android:textSize="18sp" />
<android.support.v7.widget.AppCompatButton
android:id="@+id/addDuty"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:textColor="@color/white"
app:backgroundTint="@color/colorPrimary"
android:layout_alignBaseline="@+id/dutyTitle"
android:layout_toEndOf="@+id/dutyTitle"
android:stateListAnimator="@null"
android:text="@string/addDuty" />
<android.support.design.widget.TextInputLayout
android:id="@+id/userNoteLayout"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_below="@+id/userNoteTitle"
android:layout_alignParentStart="true"
android:layout_marginStart="30dp"
android:layout_marginEnd="30dp"
android:layout_marginTop="15dp"
app:counterEnabled="true"
app:counterMaxLength="1000">
<android.support.design.widget.TextInputEditText
android:id="@+id/userNote"
android:layout_width="match_parent"
android:layout_height="100dp"
android:layout_alignStart="@+id/userNoteLayout"
android:hint="@string/tutorTabHint"
android:inputType="textMultiLine"
android:lineSpacingExtra="8sp"
android:maxLength="1000"
android:maxLines="7"
android:paddingTop="15dp"
android:requiresFadingEdge="vertical"
android:scrollbars="vertical"
android:textColor="@color/note_list_text" />
</android.support.design.widget.TextInputLayout>
<android.support.v7.widget.AppCompatButton
android:id="@+id/scrapTutorTab"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_alignBaseline="@+id/personalInfoTitle"
android:layout_alignEnd="@+id/userEmailLayout"
android:textColor="@color/white"
app:backgroundTint="@color/colorPrimary"
android:stateListAnimator="@null"
android:text="@string/scrap_tutor_tab" />
<android.support.v7.widget.AppCompatButton
android:id="@+id/saveButton"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginStart="30dp"
android:layout_marginEnd="-20dp"
android:layout_below="@+id/userNoteLayout"
android:layout_alignEnd="@+id/dutyHourView"
android:textColor="@color/white"
app:backgroundTint="@color/colorPrimary"
android:stateListAnimator="@null"
android:text="@string/saveButton" />
</RelativeLayout>
</android.support.v4.widget.NestedScrollView>

View File

@ -0,0 +1,47 @@
<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
app:layout_behavior="@string/appbar_scrolling_view_behavior"
tools:context=".activity.UsersListFragment"
android:fontFamily="@font/lato_regular"
tools:showIn="@layout/users_list_main">
<android.support.v7.widget.RecyclerView
android:id="@+id/recycler_view_whitelist"
android:layout_width="match_parent"
android:layout_height="match_parent" />
<TextView
android:id="@+id/white_list_empty_text_view"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_centerHorizontal="true"
android:layout_marginTop="@dimen/margin_top_no_notes"
android:fontFamily="sans-serif-light"
android:text="@string/loading"
android:textColor="@color/msg_no_notes"
android:textSize="@dimen/msg_no_notes" />
<com.github.ybq.android.spinkit.SpinKitView
xmlns:app="http://schemas.android.com/apk/res-auto"
android:id="@+id/loader"
style="@style/SpinKitView.Large.Wave"
android:layout_width="150dp"
android:layout_height="150dp"
app:SpinKit_Color="@color/msg_no_notes"
android:layout_centerHorizontal="true"
android:layout_marginTop="@dimen/margin_top_no_notes"
android:fontFamily="sans-serif-light"
android:text="@string/loading"
android:textColor="@color/msg_no_notes"
android:textSize="@dimen/msg_no_notes" />
</RelativeLayout>

View File

@ -0,0 +1,65 @@
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="horizontal">
<android.support.design.widget.TextInputLayout
android:id="@+id/duty_day"
android:layout_width="95dp"
android:layout_height="wrap_content"
android:hint="@string/hint_duty_day">
<android.support.design.widget.TextInputEditText
android:id="@+id/duty_day_value"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:inputType="text"
android:maxLines="1"
tools:text="@tools:sample/date/day_of_week" />
</android.support.design.widget.TextInputLayout>
<android.support.design.widget.TextInputLayout
android:id="@+id/duty_start"
android:layout_width="65dp"
android:layout_height="wrap_content"
android:hint="@string/hint_duty_start">
<android.support.design.widget.TextInputEditText
android:id="@+id/duty_start_value"
android:maxLines="1"
android:inputType="text"
android:layout_width="match_parent"
android:layout_height="match_parent"
tools:text="@tools:sample/date/hhmm"
android:focusableInTouchMode="false"
/>
</android.support.design.widget.TextInputLayout>
<android.support.design.widget.TextInputLayout
android:id="@+id/duty_stop"
android:layout_width="65dp"
android:layout_height="wrap_content"
android:hint="@string/hint_duty_end">
<android.support.design.widget.TextInputEditText
android:id="@+id/duty_stop_value"
android:maxLines="1"
android:inputType="text"
android:layout_width="match_parent"
android:layout_height="match_parent"
tools:text="@tools:sample/date/hhmm"
android:focusableInTouchMode="false"
/>
</android.support.design.widget.TextInputLayout>
<ImageButton
android:id="@+id/deleteRow"
android:layout_width="wrap_content"
android:layout_height="match_parent"
android:scaleX="0.7"
android:scaleY="0.7"
app:srcCompat="@android:drawable/ic_delete" />
</LinearLayout>

View File

@ -0,0 +1,13 @@
<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical">
<TextView
android:id="@+id/textView"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_centerInParent="true"
android:text="Homw Tab"
android:textAppearance="?android:attr/textAppearanceLarge"/>
</RelativeLayout>

View File

@ -0,0 +1,39 @@
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:background="@drawable/layout_bg"
android:orientation="vertical"
android:padding="10dp"
android:textColor="@color/half_black">
<TextView
android:id="@+id/textViewP1_info_icon_blacklist_p1"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginLeft="5dp"
android:layout_marginTop="5dp"
android:layout_weight="1"
android:text="@string/info_icon_blacklist_p1"
android:textColor="@color/half_black" />
<TextView
android:id="@+id/textViewP2_info_icon_blacklist_p2"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginLeft="5dp"
android:layout_marginTop="20dp"
android:layout_weight="1"
android:text="@string/info_icon_blacklist_p2"
android:textColor="@color/half_black" />
<TextView
android:id="@+id/textViewP3_info_icon_blacklist_p3"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginLeft="5dp"
android:layout_marginTop="20dp"
android:layout_weight="1"
android:text="@string/info_icon_blacklist_p3"
android:textColor="@color/half_black" />
</LinearLayout>

View File

@ -72,4 +72,6 @@
android:text="@string/info_icon_userlist_summary"
android:textColor="@color/half_black"/>
</LinearLayout>

View File

@ -0,0 +1,39 @@
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:background="@drawable/layout_bg"
android:orientation="vertical"
android:padding="10dp"
android:textColor="@color/half_black">
<TextView
android:id="@+id/textViewP1_info_icon_whitelist_p1"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginLeft="5dp"
android:layout_marginTop="5dp"
android:layout_weight="1"
android:text="@string/info_icon_whitelist_p1"
android:textColor="@color/half_black" />
<TextView
android:id="@+id/textViewP2_info_icon_whitelist_p2"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginLeft="5dp"
android:layout_marginTop="20dp"
android:layout_weight="1"
android:text="@string/info_icon_whitelist_p2"
android:textColor="@color/half_black" />
<TextView
android:id="@+id/textViewP3_info_icon_whitelist_p3"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginLeft="5dp"
android:layout_marginTop="20dp"
android:layout_weight="1"
android:text="@string/info_icon_whitelist_p3"
android:textColor="@color/half_black" />
</LinearLayout>

View File

@ -24,14 +24,14 @@
android:textStyle="normal" />
<EditText
android:id="@+id/feedback_input"
android:id="@+id/manual_input"
android:layout_width="315dp"
android:layout_height="wrap_content"
android:layout_alignParentTop="true"
android:layout_centerHorizontal="true"
android:layout_marginTop="50dp"
android:ems="10"
android:hint="@string/modal_feedback_hint"
android:hint="@string/modal_manual_hint"
android:maxLength="30"
android:maxLines="1"
android:requiresFadingEdge="vertical"

View File

@ -1,13 +1,23 @@
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:gravity="right"
android:fontFamily="@font/lato_regular"
>
<Button xmlns:android="http://schemas.android.com/apk/res/android"
<android.support.v7.widget.AppCompatButton
xmlns:android="http://schemas.android.com/apk/res/android"
android:id="@+id/button_choose_from_map"
android:text="@string/preference_manual_location_button"
android:layout_width="wrap_content"
android:textColor="@color/white"
app:backgroundTint="@color/top_user_modal"
android:layout_height="wrap_content"
android:stateListAnimator="@null"
/>
</LinearLayout>

View File

@ -1,6 +1,6 @@
<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_width="wrap_content"
android:layout_height="90dp"
android:clickable="true"
android:focusable="true"
@ -13,36 +13,48 @@
<TextView
android:id="@+id/firstName"
android:layout_width="271dp"
android:layout_width="270dp"
android:layout_height="22dp"
android:layout_alignParentStart="true"
android:layout_alignParentTop="true"
android:layout_marginStart="12dp"
android:layout_marginTop="10dp"
android:textColor="@color/note_list_text"
android:textSize="15sp" />
<com.github.ybq.android.spinkit.SpinKitView xmlns:app="http://schemas.android.com/apk/res-auto"
android:id="@+id/loader"
style="@style/SpinKitView.Large.Wave"
android:layout_marginStart="12dp"
android:layout_marginTop="35dp"
android:layout_width="30dp"
android:layout_height="30dp"
app:SpinKit_Color="@color/colorAccent" />
<TextView
android:id="@+id/lastName"
android:id="@+id/lastSeen"
android:layout_width="270dp"
android:layout_height="22dp"
android:layout_marginStart="12dp"
android:layout_below="@+id/firstName"
android:layout_alignEnd="@+id/firstName"
android:layout_marginTop="10dp"
android:layout_marginEnd="0dp"
android:textColor="@color/note_list_text"
android:textSize="15sp" />
android:layout_alignParentStart="true"
android:textColor="#979797"
android:textSize="13sp" />
<TextView
android:id="@+id/isOnline"
android:layout_width="48dp"
android:layout_width="50dp"
android:layout_height="30dp"
android:layout_below="@+id/firstName"
android:layout_marginStart="7dp"
android:layout_marginTop="-10dp"
android:layout_toEndOf="@+id/firstName"
android:textColor="@color/note_list_text"
android:layout_alignParentEnd="true"
android:textSize="@dimen/note_list_text" />

View File

@ -0,0 +1,56 @@
<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout
xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="wrap_content"
android:layout_height="wrap_content">
<android.support.v4.app.FragmentTabHost
android:id="@+id/tabHost"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:layout_alignParentTop="true"
android:layout_centerHorizontal="true">
<LinearLayout
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical">
<TabWidget
android:id="@android:id/tabs"
android:layout_width="match_parent"
android:layout_height="30dp"/>
<FrameLayout
android:id="@android:id/tabcontent"
android:layout_width="match_parent"
android:layout_height="match_parent">
<LinearLayout
android:id="@+id/tab1"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical">
</LinearLayout>
<LinearLayout
android:id="@+id/tab2"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical">
</LinearLayout>
</FrameLayout>
</LinearLayout>
<FrameLayout
android:id="@+id/realtabcontent"
android:layout_width="match_parent"
android:layout_height="50dp"
android:layout_below="@+id/tabLinear"/>
</android.support.v4.app.FragmentTabHost>
</RelativeLayout>

View File

@ -32,12 +32,15 @@
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginBottom="15dp"
android:drawablePadding="10dp"
android:gravity="center_horizontal"
android:text="Name Surname"
android:textColor="@color/white"
android:textSize="@dimen/lbl_new_note_title"
android:textStyle="normal"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintStart_toStartOf="parent" />
</android.support.constraint.ConstraintLayout>
</RelativeLayout>
@ -48,6 +51,28 @@
android:layout_marginTop="25dp"
android:orientation="vertical">
<LinearLayout
android:id="@+id/user_status_label_linearLayout"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="horizontal"
android:visibility="gone"
android:paddingLeft="20dp">
<ImageView
android:layout_width="25dp"
android:layout_height="25dp"
android:src="@drawable/user_modal_title" />
<TextView
android:id="@+id/user_status_label"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_gravity="center_vertical"
android:paddingLeft="10dp"
android:textColor="@color/mapboxWhite" />
</LinearLayout>
<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
@ -57,14 +82,15 @@
<ImageView
android:layout_width="25dp"
android:layout_height="25dp"
android:src="@drawable/user_modal_department"/>
android:src="@drawable/user_modal_department" />
<TextView
android:id="@+id/userDepartment"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_gravity="center_vertical"
android:paddingLeft="10dp"
/>
android:textColor="@color/mapboxWhite" />
</LinearLayout>
<LinearLayout
@ -77,14 +103,15 @@
<ImageView
android:layout_width="25dp"
android:layout_height="25dp"
android:src="@drawable/user_modal_room"/>
android:src="@drawable/user_modal_room" />
<TextView
android:id="@+id/userRoom"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_gravity="center_vertical"
android:paddingLeft="10dp"
/>
android:textColor="@color/mapboxWhite" />
</LinearLayout>
<LinearLayout
@ -97,14 +124,15 @@
<ImageView
android:layout_width="25dp"
android:layout_height="25dp"
android:src="@drawable/user_modal_email"/>
android:src="@drawable/user_modal_email" />
<TextView
android:id="@+id/userEmail"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_gravity="center_vertical"
android:paddingLeft="10dp"
/>
android:textColor="@color/mapboxWhite" />
</LinearLayout>
@ -118,14 +146,14 @@
<ImageView
android:layout_width="25dp"
android:layout_height="25dp"
android:src="@drawable/user_modal_duty"/>
android:src="@drawable/user_modal_duty" />
<TextView
android:id="@+id/userDutyHoursTitle"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:paddingLeft="10dp"
/>
android:textColor="@color/mapboxWhite" />
</LinearLayout>
<LinearLayout
@ -145,12 +173,11 @@
android:id="@+id/userDutyHours"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:paddingLeft="25dp"
android:paddingTop="-10dp"
android:divider="@color/background_user_modal"
android:dividerHeight="1dp"
android:textColor="@color/mapboxWhite"
/>
android:paddingLeft="25dp"
android:paddingTop="-10dp"
android:textColor="@color/mapboxWhite" />
</LinearLayout>
<LinearLayout
@ -163,14 +190,15 @@
<ImageView
android:layout_width="25dp"
android:layout_height="25dp"
android:src="@drawable/user_modal_note"/>
android:src="@drawable/user_modal_note" />
<TextView
android:id="@+id/userNote"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_gravity="center_vertical"
android:paddingLeft="10dp"
/>
android:textColor="@color/mapboxWhite" />
</LinearLayout>

View File

@ -10,6 +10,7 @@
<include layout="@layout/users_list_main" />
</android.support.design.widget.CoordinatorLayout>

View File

@ -12,6 +12,7 @@
<android.support.v7.widget.RecyclerView
android:id="@+id/recycler_view"
android:layout_width="match_parent"
android:scrollbars="vertical"
android:layout_height="match_parent" />
<TextView
@ -26,5 +27,20 @@
android:textSize="@dimen/msg_no_notes" />
<com.github.ybq.android.spinkit.SpinKitView
xmlns:app="http://schemas.android.com/apk/res-auto"
android:id="@+id/loader"
style="@style/SpinKitView.Large.Wave"
android:layout_width="150dp"
android:layout_height="150dp"
app:SpinKit_Color="@color/msg_no_notes"
android:layout_centerHorizontal="true"
android:layout_marginTop="@dimen/margin_top_no_notes"
android:fontFamily="sans-serif-light"
android:text="@string/loading"
android:textColor="@color/msg_no_notes"
android:textSize="@dimen/msg_no_notes" />
</RelativeLayout>

View File

@ -0,0 +1,27 @@
<?xml version="1.0" encoding="utf-8"?>
<android.support.design.widget.CoordinatorLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
xmlns:mapbox="http://schemas.android.com/apk/res-auto"
android:id="@+id/coordinator_layout"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:fontFamily="@font/lato_regular"
tools:context=".activity.UsersListFragment">
<android.support.design.widget.TabLayout
android:id="@+id/tabs"
android:layout_width="match_parent"
android:layout_height="wrap_content"
/>
<android.support.v4.view.ViewPager
android:id="@+id/viewpager"
android:layout_width="match_parent"
android:layout_height="match_parent"
/>
</android.support.design.widget.CoordinatorLayout>

View File

@ -0,0 +1,42 @@
<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:fontFamily="@font/lato_regular"
android:orientation="vertical"
android:paddingLeft="@dimen/activity_horizontal_margin"
android:paddingTop="@dimen/activity_vertical_margin"
android:paddingRight="@dimen/activity_horizontal_margin"
android:paddingBottom="@dimen/activity_vertical_margin">
<TextView
android:id="@+id/white_list_modal_title"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_alignStart="@+id/white_list_modal_input"
android:layout_marginBottom="@dimen/dimen_10"
android:fontFamily="sans-serif-medium"
android:lineSpacingExtra="8sp"
android:text="@string/white_list_title"
android:textColor="@color/colorAccent"
android:textSize="@dimen/lbl_new_note_title"
android:textStyle="normal" />
<EditText
android:id="@+id/white_list_modal_input"
android:layout_width="315dp"
android:layout_height="wrap_content"
android:layout_alignParentTop="true"
android:layout_centerHorizontal="true"
android:layout_marginTop="50dp"
android:ems="10"
android:hint="@string/index_user"
android:maxLength="30"
android:maxLines="1"
android:requiresFadingEdge="vertical"
android:scrollbars="vertical"
android:textColor="@color/note_list_text" />
</RelativeLayout>

View File

@ -0,0 +1,47 @@
<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
android:layout_width="match_parent"
android:layout_height="90dp"
android:clickable="true"
android:focusable="true"
android:paddingLeft="10dp"
android:paddingTop="@dimen/dimen_10"
android:paddingRight="10dp"
android:fontFamily="@font/lato_regular"
android:paddingBottom="@dimen/dimen_10">
<TextView
android:id="@+id/firstName"
android:layout_width="271dp"
android:layout_height="22dp"
android:layout_alignParentStart="true"
android:layout_alignParentTop="true"
android:layout_marginStart="12dp"
android:layout_marginTop="10dp"
android:textColor="@color/note_list_text"
android:textSize="15sp" />
<TextView
android:id="@+id/lastName"
android:layout_width="270dp"
android:layout_height="22dp"
android:layout_below="@+id/firstName"
android:layout_alignEnd="@+id/firstName"
android:layout_marginTop="10dp"
android:layout_marginEnd="0dp"
android:textColor="@color/note_list_text"
android:textSize="15sp" />
<ImageButton
android:id="@+id/removeUserImageButton"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_below="@+id/firstName"
android:layout_toEndOf="@+id/firstName"
android:background="@null"
android:layout_alignParentEnd="true"
app:srcCompat="@drawable/abc_ic_clear_material" />
</RelativeLayout>

View File

@ -1,14 +1,14 @@
<?xml version="1.0" encoding="utf-8"?>
<menu xmlns:android="http://schemas.android.com/apk/res/android">
<group android:id="@+id/drawer_group_tutor">
<!-- <item
<item
android:id="@+id/nav_item_one"
android:icon="@drawable/ic_people_white"
android:title="@string/navigation_item_whitelist" />
<item
android:id="@+id/nav_item_two"
android:icon="@drawable/ic_people_black"
android:title="@string/navigation_item_blacklist" />-->
android:title="@string/navigation_item_blacklist" />
<item
android:id="@+id/nav_item_three"
android:icon="@drawable/outline_person_white_24dp"

View File

@ -0,0 +1,11 @@
<menu xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools"
tools:context="com.uam.wmi.findmytutor.activity.BlackList">
<item
android:id="@+id/action_blacklist_info_popup"
android:orderInCategory="100"
android:title="Popup info icon"
android:icon="@drawable/outline_info_24"
app:showAsAction="ifRoom" />
</menu>

View File

@ -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"/>
<item

View File

@ -0,0 +1,11 @@
<menu xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools"
tools:context="com.uam.wmi.findmytutor.activity.TutorTab">
<item
android:id="@+id/action_profile_info_popup"
android:orderInCategory="100"
android:title="Popup info icon"
android:icon="@drawable/outline_info_24"
app:showAsAction="ifRoom" />
</menu>

View File

@ -0,0 +1,11 @@
<menu xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools"
tools:context="com.uam.wmi.findmytutor.activity.BlackList">
<item
android:id="@+id/action_whitelist_info_popup"
android:orderInCategory="100"
android:title="Popup info icon"
android:icon="@drawable/outline_info_24"
app:showAsAction="ifRoom" />
</menu>

View File

@ -0,0 +1,11 @@
<?xml version="1.0" encoding="utf-8"?>
<menu xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:android="http://schemas.android.com/apk/res/android">
<item
android:id="@+id/showOnlineUsersOnly"
android:checkable="true"
android:title="@string/only_online_users"
app:actionViewClass="android.widget.CheckBox"
app:showAsAction="never" />
</menu>

View File

@ -29,7 +29,7 @@
<string name="mockup_location_string">\"\"</string>
<string name="pref_header_about">O aplikacji</string>
<string name="summary_about">
Jesteśmy grupą studentów, która chce pomoć w rozwoju naszego wydziału.\nDziękujemy za używanie naszej aplikacji.\nZespół FMT.!</string>
Jesteśmy grupą studentów, która chce pomoć w rozwoju naszego wydziału.\nDziękujemy za używanie naszej aplikacji.\nZespół FMT</string>
<string name="app_version">0.1.0</string>
<string name="summary_support">Masz jakieś pytania? Uwagi? Chętnie odpiszemy!</string>
<string name="title_send_feedback">Skontaktuj się z nami</string>
@ -57,7 +57,7 @@
<string name="navigation_item_blacklist">Czarna lista</string>
<string name="navigation_item_whitelist">Biała lista</string>
<string name="navigation_item_settings">Ustawienia</string>
<string name="navigation_item_profile">Profil uzytkownika</string>
<string name="navigation_item_profile">Profil użytkownika</string>
<string name="navigation_item_logout">Wyloguj</string>
<!-- Tutors list -->
<string name="action_settings">Ustawienia</string>
@ -92,9 +92,9 @@
<string name="title_manual_location">Dodaj ręczną lokalizacje</string>
<string name="assembly_a">Skrzydło A</string>
<string name="assembly_c">Skrzydło C</string>
<string name="passage_d">ŁącznikD</string>
<string name="passage_d">Łącznik D</string>
<string name="key_language">LOCALE</string>
<string name="key_language">key_language</string>
<string name="title_activity_settings2">Ustawienia</string>
<!-- Example General settings -->
@ -118,7 +118,7 @@
<string name="userDepartment">Zakład</string>
<string name="loading">Ładowanie …</string>
<string name="logo_find_my_tutor">Logo find my tutor</string>
<string name="prompt_login">Login (Ldap)</string>
<string name="prompt_login">Login (LDAP WMI)</string>
<string name="action_log_in">Zaloguj!</string>
<string name="error_invalid_login_name">Niepoprawny format loginu.</string>
<string name="user_list_nav">Kadra</string>
@ -132,14 +132,14 @@
<string name="fab_title_bound_area">Bounds OFF</string>
<string name="email_subject_feedback">Find My Tutor - feedback</string>
<string name="email_subject_bug">Find My Tutor - zgłoszenie błędu</string>
<string name="modal_feedback_hint">Proszę opisz swoje spostrzeżnia.</string>
<string name="modal_feedback_hint">Opisz proszę swoje spostrzeżenia.</string>
<string name="modal_feedback_question">Wyślij anonimowo</string>
<string name="location_level_manual">Manualna</string>
<string name="preference_manual_location_button">Wybierz z mapy</string>
<string name="permission_denied_explanation">Odmowa dostępu</string>
<string name="permission_rationale">Uprawnienia powinny zostać przyznane.</string>
<string name="title_feedback_report_notice">Powiedz nam co myślisz!(max 1000 znaków)</string>
<string name="title_bug_report_notice">Powiedz nam co zauważyłeś!(max 1000 znaków)</string>
<string name="title_feedback_report_notice">Powiedz nam co myślisz! (max 1000 znaków)</string>
<string name="title_bug_report_notice">Powiedz nam co zauważyłeś! (max 1000 znaków)</string>
<string name="title_bug_report">ZGŁOŚ BUG</string>
<string name="title_feedback_report">FEEDBACK</string>
<string name="modal_feedback_send">WYŚLIJ</string>
@ -147,7 +147,7 @@
<string name="remove_manual_location">Usuń manualną lokację</string>
<string name="title_activity_tutor_tab">Profil</string>
<string name="saveButton">Zapisz!</string>
<string name="tutorTabHint">Tutaj możesz dodać swoją notatkę. Będzie widoczna dla innych użytkowników.</string>
<string name="tutorTabHint">Edytuj swoją notatkę. Będzie widoczna dla innych.</string>
<string name="modal_location_send">WYŚLIJ</string>
<string name="modal_location_hint">Proszę nazwać wybraną lokację.</string>
<string name="manual_modal_title">Czy chcesz zapisać tę lokalizację?</string>
@ -159,7 +159,7 @@
<string name="network_error">Błąd sieci!</string>
<string name="manual_status_error">Błąd podczas pobierania danych.</string>
<string name="error_status_fetch">Błąd podczas pobierania statusów.</string>
<string name="notification_text">Upss. Coś poszło nie tak. Pracujemy nad tym!</string>
<string name="notification_text">Upss. Coś poszło nie tak!</string>
<string name="lack_duty_hours">Brak informacji o dyżurze.</string>
<string name="lack_note">Brak notatki.</string>
<string name="search">Wyszukiwarka</string>
@ -172,9 +172,9 @@
<string name="map_info_text_p1">Na mapie wyświetlane są markery reprezentujące profesorów udostępniających w tej chwili swoją lokalizację.</string>
<string name="map_info_text_p2">Po kliknięciu w marker możemy sprawdzić kto udostępnia lokalizację, oraz status opisowy (jeśli profesor go ustawił).</string>
<string name="map_info_text_p3">W aplikacji dostępne są 3 rodzaje lokalizacji, które reprezentowane są przez markery różnego koloru.</string>
<string name="map_info_text_marker_exact">- lokalizacja dokładna\n(udostępniana z GPS telefonu)</string>
<string name="map_info_text_marker_approximated">- lokalizacja przybliżona</string>
<string name="map_info_text_marker_manual">- lokalizacja manualna (wybrana ręcznie)</string>
<string name="map_info_text_marker_exact">lokalizacja dokładna (udostępniana z GPS telefonu)</string>
<string name="map_info_text_marker_approximated">lokalizacja przybliżona</string>
<string name="map_info_text_marker_manual"> lokalizacja manualna (wybrana ręcznie)</string>
<!--(PL) Blacklist info helper-->
<string name="info_icon_blacklist_p1">W tym panelu możesz dodać użytkowników do swojej czarnej listy. Użytkownicy z czarnej listy nie będą widzieć żadnych danych które udostępniasz - lokalizacji, twojego statusu online, czy informacji o obecności.</string>
@ -194,43 +194,105 @@
<!--(PL) Sharing Tab info helper-->
<string name="info_icon_sharing_tab_p1">W tej zakładce możesz włączyć/wyłączyć udostępnianie swojej lokalizacji oraz ją skonfigurować.</string>
<string name="info_icon_sharing_tab_p2">Niektóre zmiany mogą nie być widoczne od razu! Odświeżanie informacji zajmuje do 2 minut.</string>
<string name="info_icon_sharing_tab_p2">Niektóre zmiany mogą nie być widoczne od razu! Wyłączenie wysyłania ma skutek natychmiastowy, lecz odświeżanie informacji zajmuje serwerowi do 2 minut.</string>
<string name="info_icon_sharing_tab_p3">Udostępniać możesz na jednym z 4 poziomów:</string>
<string name="info_icon_sharing_tab_p3_level_exact"><b>dokładny </b> - lokalizacja wyświetlana na mapie na podstawie GPS</string>
<string name="info_icon_sharing_tab_p3_level_approximate"><b>przybliżony</b> - przybliżona lokalizacja wyświetlana na podstawie GPS</string>
<string name="info_icon_sharing_tab_p3_level_manual"><b>manualny</b> - udostępnianie z ręcznie wybranego punktu na mapie</string>
<string name="info_icon_sharing_tab_p3_level_presence"><b>tylko obecność</b> - udostępnianie jedynie informacji o pojawieniu się na wydziale (aktywny na liście), bez udostępniania lokalizacji</string>
<string name="info_icon_sharing_tab_p4">Każdy poziom z wyjątkiem manualnie wybranej lokalizacji automatycznie zaczyna udostępniać po wejściu na wydział i przestaje udostępniać po jego opuszczeniu. Wystarczy włączyć udostępnianie, a lokalizacja nie będzie udostępniana tylko przy obecności na wydziale.</string>
<string name="info_icon_sharing_tab_p4">Każdy poziom z wyjątkiem manualnie wybranej lokalizacji automatycznie zaczyna udostępniać po wejściu na wydział i przestaje udostępniać po jego opuszczeniu. Wystarczy włączyć udostępnianie, a lokalizacja będzie udostępniana tylko przy obecności na wydziale.</string>
<string name="info_icon_sharing_tab_p5">Udostępnianie w dowolnym momencie można wyłączyć za pomocą przełącznika.</string>
<string name="info_icon_sharing_tab_p6">Dodatkowo, do Twojej lokalizacji możesz dodać status opisowy (będzie on widoczny dla użytkowników po kliknięciu w marker).</string>
<string name="info_icon_sharing_tab_p7">Zarówno manualne lokalizacje jak i statusy możesz dodać do listy, które potem możesz wybrać w wygodny sposób.</string>
<string name="info_icon_sharing_tab_p7">Zarówno manualne lokalizacje jak i statusy możesz dodać do listy, z której możesz potem je wybrać w wygodny sposób.</string>
<!--(PL) Userlist Tab info helper-->
<string name="info_icon_userlist_tab_p1">W tym panelu znajduje się listę profesorów.</string>
<string name="info_icon_userlist_tab_p1">W tym panelu znajduje się lista profesorów.</string>
<string name="info_icon_userlist_tab_p2">Ich status symbolizowany jest przez kolorowe kropki:</string>
<string name="info_icon_userlist_tab_level_status_online">- użytkownik jest obecnie online</string>
<string name="info_icon_userlist_tab_level_status_offline">- użytkownik jest obecnie offline</string>
<string name="info_icon_userlist_tab_level_status_inactive">- użytkownik jest nieaktywny</string>
<string name="info_icon_userlist_tab_level_status_inactive_tip">(nie udostępnił żadnych danych o lokalizacji od co najmniej tygodnia)</string>
<string name="info_icon_userlist_tab_level_status_inactive_tip">(nie udostępnił żadnych danych o lokalizacji od conajmniej tygodnia)</string>
<string name="add">Dodaj</string>
<string name="index_user">Index użytkownika</string>
<string name="black_list_title">Dodaj użytkownika do Blacklsi</string>
<string name="info_icon_userlist_summary">Po kliknięciu w imię i nazwisko, wyświetli się karta zawierająca dokładne informacje o profesorze.</string>
<string name="lack_of_status">Użytkownik nie zdefiniował statusu.</string>
<string name="possitive_dialog_button">Tak</string>
<string name="negative_dialog_button">Nie</string>
<string name="enable_sharing_question">Aby skorzystać z tej funkcji musisz pozwolić na udostępnianie lokalizacji. Zgadzasz sie?</string>
<string name="sharing_modal_title">Udostępnianie</string>
<!--ACRA ON/OFF switch-->
<string name="pref_acra_disabled" translatable="false">Pozwól na wysyłanie raportów o błędach.</string>
<string name="pref_acra_enabled" translatable="false">Pozwól na wysyłanie raportów o błędach.</string>
<string name="pref_title_acra" translatable="false">Raportowanie błędów.</string>
<string name="acra_toast_text" translatable="false">Błąd aplikacji. Informacje o błędzie zostanie wysłana do twórców.</string>
<string name="acra_toast_text" translatable="false">Błąd aplikacji. Informacje o błędzie zostaną wysłane do twórców.</string>
<string name="hint_duty_day">Dzień</string>
<string name="hint_duty_start">Start</string>
<string name="hint_duty_end">Koniec</string>
<string name="hint_department">Zakład</string>
<string name="hint_room">Pokój</string>
<string name="addDuty">DODAJ DYŻUR</string>
<string name="dutyTitle">Godziny dyżurów</string>
<string name="personalInfoTitle">Dane kontaktowe</string>
<string name="userNoteTitle">Twoja notka</string>
<string name="updateToast">Dziękujemy za aktualizację profilu</string>
<string name="error_location_fetch">Błąd podczas pobierania lokalizacji.</string>
<string name="lack_of_status">Użytkownik nie zdefiniował statusu.</string>
<string name="possitive_dialog_button">Tak</string>
<string name="negative_dialog_button">Nie</string>
<string name="enable_sharing_question">Aby skorzystać z tej funkcji musisz pozwolić na udostępnianie lokalizacji. Zgadzasz sie?</string>
<string name="sharing_modal_title">Udostępnianie</string>
<string name="preference_manual_location_button_remove">Zarządzaj zapisanymi</string>
<string name="preference_manual_status_button_remove">Zarządzaj zapisanymi</string>
<string name="blacklist">Czarna lista</string>
<string name="can_not_be_empty">Pole nie może być puste</string>
<string name="user_added">Użytkownik dodany</string>
<string name="list_is_empty">Lista jest pusta</string>
<string name="on">WŁĄCZONA</string>
<string name="off">WYŁĄCZONA</string>
<string name="title_activity_black_list">Czarna lista</string>
<string name="scrap_tutor_tab">Pobierz dane z WMI</string>
<string name="scrap_tutor_msg">Dane zostały zaktualizwane!</string>
<!--(ENG) Checkbox online users list -->
<string name="no_online_users">Brak aktywnych użytkowników.</string>
<string name="no_offline_users">Brak użytkowników offline.</string>
<string name="activity_title_blacklist">Czarna lista</string>
<string name="activity_title_whitelist">Biała lista</string>
<string name="title_activity_white_list">Biała lista</string>
<string name="white_list_title">Dodaj użytkownika do białej listy</string>
<string name="no_such_a_user">Nie ma takiego użytkownika</string>
<string name="only_online_users">Tylko aktywni użytkownicy</string>
<string name="network_err">Błąd sieci!</string>
<string name="search_null">Brak wyników!</string>
<string name="modal_manual_hint">Nadaj nazwę tej lokalizacji.</string>
<string name="online">Dostępny</string>
<string name="offline">Niedostępny</string>
<string name="inactive">Nieaktywny</string>
<string name="show_on_map">POKAŻ NA MAPIE</string>
<!--(ENG) Blacked/Whited users -->
<string name="add_user_to_list">Użytkownik został dodany!</string>
<string name="user_removed">Użytkownik usunięty!</string>
<string name="floor">Piętro</string>
<string name="block_the_users">Zablokuj użytkowników</string>
<string name="be_visible_for_these_users">Bądź dostępny dla użytkowników</string>
<string name="manual_mode">manualny</string>
<string name="exact_mode">dokładny</string>
<string name="approx_mode">przybliżony</string>
<string name="other_location">Niezapisana lokalizacja.</string>
<string name="last_sign">Ostatnio</string>
<string name="available_now">Dostępny teraz</string>
<string name="profile_activity_title">Profil użytkownika</string>
<string name="batter_exclusions_title">Uwaga</string>
<string name="batter_exclusions_message">Aby aplikacja była w pełni funkcjonalna, dodaj FMT do wyjątków w oszczędzaniu baterii. Po wciśnięciu przycisku \"ok\" zostaniesz przeniesiony do opcji zarządzania baterią. W panelu \"Bateria\" upewnij się, że opcja optymalizacji jest wyłączona.</string>
<string name="never_logged_in">Nigdy</string>
</resources>

View File

@ -55,23 +55,15 @@
</string-array>
<string-array name="status_entries">
<item>@string/description_available</item>
<item>@string/description_busy</item>
<item>@string/description_consultation</item>
</string-array>
<string-array name="status_values">
<item>0</item>
<item>1</item>
<item>2</item>
</string-array>
<string-array name="manual_location_entries">
<item>@string/assembly_c</item>
<item>@string/assembly_a</item>
<item>@string/passage_d</item>
</string-array>
<string-array name="manual_location_values">
<item>0</item>
<item>1</item>
<item>2</item>
</string-array>
<string-array name="language_entries">
<item>@string/lang_eng</item>
@ -81,4 +73,19 @@
<item>0</item>
<item>1</item>
</string-array>
<string-array name="yourArray">
<item>Item 1</item>
<item>Item 2</item>
<item>Item 3</item>
<item>Item 4</item>
</string-array>
<string-array name="yourValues">
<item>0</item>
<item>1</item>
<item>2</item>
<item>3</item>
</string-array>
</resources>

View File

@ -19,4 +19,6 @@
<dimen name="note_list_text">13sp</dimen>
<dimen name="default_margin">12dp</dimen>
<dimen name="text_large">10dp</dimen>
<dimen name="app_bar_height">180dp</dimen>
<dimen name="text_margin">16dp</dimen>
</resources>

View File

@ -32,7 +32,8 @@
<!-- Tutors list -->
<string name="action_settings">Settings</string>
<string name="activity_title_home">Notes</string>
<string name="activity_title_blacklist">Blacklist</string>
<string name="activity_title_whitelist">Whitelist</string>
<string name="prompt_password">Password</string>
<string name="action_sign_in">Sign in or register</string>
<string name="action_sign_out">Sign out</string>
@ -53,12 +54,10 @@
<!-- Strings related to SharingActivity -->
<string name="title_activity_sharing">Sharing</string>
<!-- Strings related to settings -->
<string name="title_sharing">Sharing</string>
<string name="settings_category_location">Location sharing</string>
<string name="settings_category_status">Status settings</string>
@ -69,6 +68,9 @@
<string name="location_level_precise">Exact</string>
<string name="location_level_manual">Manual</string>
<string name="preference_manual_location_button">Choose from map</string>
<string name="preference_manual_location_button_remove">Manage saved</string>
<string name="preference_manual_status_button_remove">Manage saved</string>
<string name="settings_location_level">Location level</string>
<string name="key_location_level">key_location_level</string>
@ -86,13 +88,10 @@
<string name="title_manual_status">Add custom status</string>
<string name="settings_description">Descrition</string>
<string name="settings_description">Description</string>
<string name="saveButton">Save</string>
<string name="tutorTabHint">Here you can add your note. It will be visible to the other users.</string>
<string name="tutorTabHint">Edit your note. It will be shown in the users list.</string>
<string name="key_description">key_description</string>
<string name="manual_location">Manual location</string>
<string name="title_list_manual_location">Choose manual location</string>
<string name="title_manual_location">Add custom location</string>
@ -109,7 +108,7 @@
<string name="lang_eng">English</string>
<string name="lang_pol">Polish</string>
<string name="settings_language">Choose language</string>
<string name="key_language">LOCALE</string>
<string name="key_language">key_language</string>
<string name="pref_header_about">About</string>
@ -127,7 +126,6 @@
<string name="title_activity_settings2">Settings</string>
<string name="modal_location_send">SEND</string>
<string name="modal_location_hint">Please name choosen location.</string>
modal_feedback_send
<!-- Strings related to Settings -->
<!-- Example General settings -->
@ -224,17 +222,21 @@
<string name="nav_profile">User profile</string>
<string name="remove_manual_location">Remove Manual location</string>
<string name="title_activity_tutor_tab">TutorTab</string>
<string name="manual_modal_title">Do you want to save this localization?</string>
<string name="lbl_ok">Save!</string>
<string name="lbl_cancel">Cancel!</string>
<string name="manual_modal_title">Manual localization</string>
<string name="lbl_ok">Save</string>
<string name="lbl_cancel">Cancel</string>
<string name="manual_marker_info">Your marker will disappear in next couple minutes</string>
<string name="manual_location_selected">Manual Locations selected!</string>
<string name="location_saved">Location saved!</string>
<string name="network_error">Network Error!</string>
<string name="manual_status_error">Error handling status fetch</string>
<string name="error_status_fetch">Error handling status fetch</string>
<string name="error_location_fetch" translatable="false">Error handling status fetch</string>
<string name="error_location_fetch">Error handling status fetch</string>
<!--<string name="pref_acra_disabled" translatable="false">Auto reporting on issue is OFF</string>-->
<!--<string name="pref_acra_enabled" translatable="false">Auto reporting on issue is ON</string>-->
<!--<string name="pref_disable_acra" translatable="false">ACRA reporting tool</string>-->
<string name="acra_toast_text" translatable="false">Sorry, the application crashed. A report will be sent to the developers</string>
<string name="notification_text">Sorry, the application crashed. A report will be sent to the developers</string>
<string name="notification_title" translatable="false">FMT Issue</string>
<string name="notification_channel" translatable="false">FMT</string>
@ -244,18 +246,17 @@
<string name="mockup_location_string" translatable="false">mock location string</string>
<!--ACRA ON/OFF switch-->
<string name="pref_acra_disabled" translatable="false">Allow to send report to developers is ON</string>
<string name="pref_acra_enabled" translatable="false">Allow to send report to developers is OFF</string>
<string name="pref_title_acra" translatable="false">App issues reporting</string>
<string name="acra_toast_text" translatable="false">Sorry, the application crashed. A report will be sent to the developers</string>
<string name="pref_acra_disabled" translatable="false">Allow to send raport to developers is ON</string>
<string name="pref_acra_enabled" translatable="false">Allow to send raport to developers is OFF</string>
<string name="pref_disable_acra" translatable="false">App issues reporting</string>
<!--(ENG) Map Activity info helper-->
<string name="map_info_text_p1">On the map there are markers which represents tutors sharing their location right now.</string>
<string name="map_info_text_p1">On the map there are markers which represent tutors sharing their location right now.</string>
<string name="map_info_text_p2">After clicking on a marker, you can check who is sharing it and the descriptive status (if the tutor have set one).</string>
<string name="map_info_text_p3">In the app there are 3 possible types of localization, represented by various colors.</string>
<string name="map_info_text_marker_exact">- exact localization (from mobile GPS)</string>
<string name="map_info_text_marker_approximated">- approximated localization</string>
<string name="map_info_text_marker_manual">- manual localization (manually picked)</string>
<string name="map_info_text_marker_exact">exact localization (from mobile GPS)</string>
<string name="map_info_text_marker_approximated">approximated localization</string>
<string name="map_info_text_marker_manual">manual localization (manually picked)</string>
<!--(ENG) Blacklist info helper-->
<string name="info_icon_blacklist_p1">In this panel you can add users to your blacklist. Users from the blacklist cant see any data that you share - localization, online status, or information about presence.</string>
@ -275,7 +276,7 @@
<!--(ENG) Sharing Tab info helper-->
<string name="info_icon_sharing_tab_p1">In this tab you can turn on/off sharing your localization and configure it.</string>
<string name="info_icon_sharing_tab_p2">Some of the changes may not happen immediately! Refreshing information takes up to 2 minutes.</string>
<string name="info_icon_sharing_tab_p2">Some of the changes may not be visible immediately! Turning sharing off is stopping the sharing immediately, but refreshing information by server takes up to 2 minutes.</string>
<string name="info_icon_sharing_tab_p3">You can share your localization on one of the 4 levels:</string>
<string name="info_icon_sharing_tab_p3_level_exact"><b>exact</b> - localization displayed on a map, based on GPS</string>
<string name="info_icon_sharing_tab_p3_level_approximate"><b>approximated</b> - approximated localization based on GPS</string>
@ -284,7 +285,7 @@
<string name="info_icon_sharing_tab_p4">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.</string>
<string name="info_icon_sharing_tab_p5">Sharing can be turned off at any time with the switch.</string>
<string name="info_icon_sharing_tab_p6">Additionally, you can add descriptive status to your localization (visible for users after clicking on a marker).</string>
<string name="info_icon_sharing_tab_p7">Both manual localizations and statuses can be added to a list, and then used them in a convenient way. </string>
<string name="info_icon_sharing_tab_p7">Both manual localizations and statuses can be added to a list, and then used in a convenient way. </string>
<!--(ENG) Userlist tab info helper-->
<string name="info_icon_userlist_tab_p1">This panel contains the list of tutors.</string>
@ -293,14 +294,169 @@
<string name="info_icon_userlist_tab_level_status_offline">- user is currently offline</string>
<string name="info_icon_userlist_tab_level_status_inactive">- user is inactive </string>
<string name="info_icon_userlist_tab_level_status_inactive_tip">(didnt share any localization data since 7 days)</string>
<string name="info_icon_userlist_summary">After clicking on a name, the tutor tab will pop up, containing details about selected tutor.</string>
<string name="title_activity_black_list">BlackList</string>
<string name="title_activity_white_list">Whitelist</string>
<string name="white_list_title">Add user to Whitelist</string>
<string name="possitive_dialog_button">yes</string>
<string name="info_icon_userlist_summary">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.</string>
<!--(ENG) Blacklist -->
<string name="index_user">User index</string>
<string name="black_list_title">Add user to blacklist</string>
<string name="add">Add</string>
<string name="possitive_dialog_button">Yes</string>
<string name="pref_title_acra" translatable="false">App issues reporting</string>
<!--(ENG) Profile Activity strings-->
<string name="profile_activity_title">Profile</string>
<string name="hint_duty_day">Day</string>
<string name="hint_duty_start">Start</string>
<string name="hint_duty_end">End</string>
<string name="hint_department">Department</string>
<string name="hint_room">Room</string>
<string name="hint_email" translatable="false">Email</string>
<string name="addDuty">ADD DUTY</string>
<string name="dutyTitle">Duty hours</string>
<string name="personalInfoTitle">Personal info</string>
<string name="userNoteTitle">Your note</string>
<string name="updateToast">Thank you for updating your profile.</string>
<string name="negative_dialog_button">No</string>
<string name="enable_sharing_question">In order to use this function, you have to enable localization sharing. May I do it for you?</string>
<string name="sharing_modal_title">Sharing</string>
<string name="lack_of_status">The user hasn\'t defined a status.</string>
<string name="can_not_be_empty">Field can not be empty</string>
<string name="user_added">User added</string>
<string name="list_is_empty">The list is empty</string>
<string name="activity_title_home">Map</string>
<string name="on">ON</string>
<string name="off">OFF</string>
<string name="scrap_tutor_tab">Scrap from WMI</string>
<string name="scrap_tutor_msg">Data updated!</string>
<!--(ENG) Checkbox online users list -->
<string name="no_online_users">Currently, there are no\nactive users.</string>
<string name="no_offline_users">Currently, there are no\noffline users.</string>
<string name="only_online_users">Only active users</string>
<string name="no_such_a_user">No such a user</string>
<string name="network_err">Network Error !</string>
<string name="search_null">Search response is empty!</string>
<string name="modal_manual_hint">Name the localization</string>
<string name="online">Online</string>
<string name="offline">Offline</string>
<string name="inactive">Inactive</string>
<string name="show_on_map">SHOW ON MAP</string>
<!--(ENG) Blacked/Whited users -->
<string name="add_user_to_list">User has been added!</string>
<string name="user_removed">User removed!</string>
<string name="floor">Floor</string>
<string name="block_the_users">Block the users</string>
<string name="be_visible_for_these_users">Be visible for these users</string>
<string name="title_activity_scrolling">ScrollingActivity</string>
<string name="large_text">
"Material is the metaphor.\n\n"
"A material metaphor is the unifying theory of a rationalized space and a system of motion."
"The material is grounded in tactile reality, inspired by the study of paper and ink, yet "
"technologically advanced and open to imagination and magic.\n"
"Surfaces and edges of the material provide visual cues that are grounded in reality. The "
"use of familiar tactile attributes helps users quickly understand affordances. Yet the "
"flexibility of the material creates new affordances that supercede those in the physical "
"world, without breaking the rules of physics.\n"
"The fundamentals of light, surface, and movement are key to conveying how objects move, "
"interact, and exist in space and in relation to each other. Realistic lighting shows "
"seams, divides space, and indicates moving parts.\n\n"
"Bold, graphic, intentional.\n\n"
"The foundational elements of print based design typography, grids, space, scale, color, "
"and use of imagery guide visual treatments. These elements do far more than please the "
"eye. They create hierarchy, meaning, and focus. Deliberate color choices, edge to edge "
"imagery, large scale typography, and intentional white space create a bold and graphic "
"interface that immerse the user in the experience.\n"
"An emphasis on user actions makes core functionality immediately apparent and provides "
"waypoints for the user.\n\n"
"Motion provides meaning.\n\n"
"Motion respects and reinforces the user as the prime mover. Primary user actions are "
"inflection points that initiate motion, transforming the whole design.\n"
"All action takes place in a single environment. Objects are presented to the user without "
"breaking the continuity of experience even as they transform and reorganize.\n"
"Motion is meaningful and appropriate, serving to focus attention and maintain continuity. "
"Feedback is subtle yet clear. Transitions are efficient yet coherent.\n\n"
"3D world.\n\n"
"The material environment is a 3D space, which means all objects have x, y, and z "
"dimensions. The z-axis is perpendicularly aligned to the plane of the display, with the "
"positive z-axis extending towards the viewer. Every sheet of material occupies a single "
"position along the z-axis and has a standard 1dp thickness.\n"
"On the web, the z-axis is used for layering and not for perspective. The 3D world is "
"emulated by manipulating the y-axis.\n\n"
"Light and shadow.\n\n"
"Within the material environment, virtual lights illuminate the scene. Key lights create "
"directional shadows, while ambient light creates soft shadows from all angles.\n"
"Shadows in the material environment are cast by these two light sources. In Android "
"development, shadows occur when light sources are blocked by sheets of material at "
"various positions along the z-axis. On the web, shadows are depicted by manipulating the "
"y-axis only. The following example shows the card with a height of 6dp.\n\n"
"Resting elevation.\n\n"
"All material objects, regardless of size, have a resting elevation, or default elevation "
"that does not change. If an object changes elevation, it should return to its resting "
"elevation as soon as possible.\n\n"
"Component elevations.\n\n"
"The resting elevation for a component type is consistent across apps (e.g., FAB elevation "
"does not vary from 6dp in one app to 16dp in another app).\n"
"Components may have different resting elevations across platforms, depending on the depth "
"of the environment (e.g., TV has a greater depth than mobile or desktop).\n\n"
"Responsive elevation and dynamic elevation offsets.\n\n"
"Some component types have responsive elevation, meaning they change elevation in response "
"to user input (e.g., normal, focused, and pressed) or system events. These elevation "
"changes are consistently implemented using dynamic elevation offsets.\n"
"Dynamic elevation offsets are the goal elevation that a component moves towards, relative "
"to the components resting state. They ensure that elevation changes are consistent "
"across actions and component types. For example, all components that lift on press have "
"the same elevation change relative to their resting elevation.\n"
"Once the input event is completed or cancelled, the component will return to its resting "
"elevation.\n\n"
"Avoiding elevation interference.\n\n"
"Components with responsive elevations may encounter other components as they move between "
"their resting elevations and dynamic elevation offsets. Because material cannot pass "
"through other material, components avoid interfering with one another any number of ways, "
"whether on a per component basis or using the entire app layout.\n"
"On a component level, components can move or be removed before they cause interference. "
"For example, a floating action button (FAB) can disappear or move off screen before a "
"user picks up a card, or it can move if a snackbar appears.\n"
"On the layout level, design your app layout to minimize opportunities for interference. "
"For example, position the FAB to one side of stream of a cards so the FAB wont interfere "
"when a user tries to pick up one of cards.\n\n"
</string>
<!--(ENG) Sharing Modes -->
<string name="manual_mode">manual</string>
<string name="exact_mode">exact</string>
<string name="approx_mode">approximate</string>
<!--(ENG) Undefined manual -->
<string name="other_location">Not saved location.</string>
<string name="user_status_label" translatable="false">Status</string>
<string name="available_now">Available now</string>
<string name="last_sign">Last seen</string>
<string name="batter_exclusions_message">To make app fully functional add FMT to battery saving exclusions. You can change battery options in \"Optimise battery usage\". Unfortunately, you have to do it manually. Click \"ok\" to open battery settings and make sure that the application is not optimised.</string>
<string name="batter_exclusions_title">Please note</string>
<string name="never_logged_in">Never</string>
</resources>

View File

@ -22,4 +22,5 @@
<item name="android:background">@drawable/fab_label_background</item>
<item name="android:textColor">@color/mapboxWhite</item>
</style>
</resources>

View File

@ -1,22 +1,22 @@
<?xml version="1.0" encoding="utf-8"?>
<PreferenceScreen xmlns:tools="http://schemas.android.com/tools"
xmlns:android="http://schemas.android.com/apk/res/android"
tools:ignore="MissingDefaultResource"
<PreferenceScreen xmlns:android="http://schemas.android.com/apk/res/android"
android:id="@+id/pref_screen"
xmlns:app="http://schemas.android.com/apk/res-auto"
android:layout_width="match_parent"
android:fontFamily="@font/lato_regular"
android:layout_height="match_parent">
android:layout_height="match_parent"
android:fontFamily="@font/lato_regular">
<PreferenceCategory
android:title="@string/settings_category_location"
android:key="category_sharing">
android:key="category_sharing"
android:title="@string/settings_category_location">
<SwitchPreference
android:defaultValue="false"
android:disableDependentsState="false"
android:key="key_sharing_enabled"
android:persistent="true"
android:title="@string/title_sharing"/>
android:title="@string/title_sharing" />
<ListPreference
android:defaultValue="1"
android:defaultValue="2"
android:dialogTitle="@string/settings_location_level"
android:entries="@array/location_level_entries"
android:entryValues="@array/location_level_values"
@ -25,23 +25,30 @@
android:title="@string/title_location_level" />
<ListPreference
android:defaultValue="0"
android:entries="@array/manual_location_entries"
android:entryValues="@array/manual_location_values"
android:key="key_manual_location_value"
android:summary="%s"
android:title="@string/title_list_manual_location" />
<com.uam.wmi.findmytutor.utils.RightButtonPreference
android:key="manual_location_button"
/>
android:text="@string/preference_manual_location_button" />
<com.uam.wmi.findmytutor.utils.RightButtonPreference
android:key="remove_manual_location"
android:text="@string/preference_manual_location_button_remove" />
</PreferenceCategory>
<PreferenceCategory android:title="@string/settings_category_status">
<SwitchPreference
<SwitchPreference
android:defaultValue="false"
android:disableDependentsState="false"
android:key="key_status_enabled"
android:persistent="true"
android:title="@string/status_switch_title"/>
android:title="@string/status_switch_title" />
<ListPreference
android:defaultValue="2"
android:defaultValue="0"
android:entries="@array/status_entries"
android:entryValues="@array/status_values"
android:key="@string/key_status_value"
android:summary="%s"
android:title="@string/status_list_title" />
@ -49,10 +56,12 @@
android:key="key_manual_status"
android:selectAllOnFocus="true"
android:singleLine="true"
android:title="@string/title_manual_status"
/>
android:title="@string/title_manual_status" />
<com.uam.wmi.findmytutor.utils.RightButtonPreference
android:key="remove_manual_status"
android:textColor="@color/white"
app:backgroundTint="@color/mapboxRedDark"
android:text="@string/preference_manual_status_button_remove" />
</PreferenceCategory>
</PreferenceScreen>

View File

@ -8,7 +8,6 @@ buildscript {
}
dependencies {
classpath 'com.android.tools.build:gradle:3.2.1'
// NOTE: Do not place your application dependencies here; they belong
// in the individual module build.gradle files