Compare commits

..

311 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
4fc348af56 Fix strings 2018-12-16 23:28:10 +01:00
5f48949014 Merge branch 'develop' into fix-manual-sharing 2018-12-16 22:47:22 +01:00
df1b380152 Change duty hours model 2018-12-16 22:46:44 +01:00
9d82261be9 Fix duty hours 2018-12-16 22:45:44 +01:00
c1e20934e4 recycle view crash 2018-12-16 22:44:00 +01:00
e7a2ecf86a Add new infoboxes 2018-12-16 22:14:55 +01:00
a0f78aef2d Revert "Merge branch 'extendTutorTab' of s416084/find-my-tutor-android into develop"
This reverts commit 264f752b20, reversing
changes made to 6498f2e58d.
2018-12-16 18:31:04 +01:00
962a222fa8 minor cleanup 2018-12-16 18:19:58 +01:00
9f0ef0590d Fix strings 2018-12-16 17:42:05 +01:00
264f752b20 Merge branch 'extendTutorTab' of s416084/find-my-tutor-android into develop 2018-12-16 16:38:28 +00:00
7f16515074 translated strings, fixed validation filter 2018-12-16 17:37:18 +01:00
80b0948033 working on duty hours validation 2018-12-16 16:56:54 +01:00
e2a6bfd56c Fix enabling BG 2018-12-16 16:19:32 +01:00
f7edee0c56 Fix handle BG 2018-12-16 14:47:14 +01:00
6498f2e58d Merge branch 'infoIcons' of s416084/find-my-tutor-android into develop 2018-12-16 09:43:06 +00:00
b0ccb9cf4f Merge branch 'develop' into infoIcons 2018-12-16 10:39:19 +01:00
dee33a2ec3 info icon at toolbar + clean up 2018-12-16 00:13:49 +01:00
c8145323c5 refresh sharing tab 2018-12-15 23:45:02 +01:00
f37fe44f2e added strings and adjusted layout but needs fixing for smaller screens 2018-12-15 22:59:34 +01:00
672a6bee06 teraz 2018-12-15 22:47:23 +01:00
41288f000b Add modal to ask for BG 2018-12-15 21:49:08 +01:00
90aa21be1d Info button on toolbar 2018-12-15 21:35:00 +01:00
39da105bc8 Merge branch 'infoIcons' of s416084/find-my-tutor-android into develop 2018-12-15 17:34:20 +00:00
baa8cac0e4 working dutyhour adapter 2018-12-15 17:35:20 +01:00
3139d41ba4 strings fixed, base url server moved to Const class 2018-12-15 15:29:29 +01:00
7dd3e0cc00 Merge branch 'develop' into infoIcons 2018-12-15 14:48:05 +01:00
0884fc4873 Merge branch 'extendTutorTab' of git.wmi.amu.edu.pl:s416084/find-my-tutor-android into extendTutorTab 2018-12-15 00:33:41 +01:00
e775961ed2 created duty hour adapter 2018-12-15 00:33:09 +01:00
Marcin Jedynski
a3a847fdeb moved duty hours to the center of the screen 2018-12-13 10:33:02 +01:00
Adam Domagalski
f568cea711 popups text color half black 2018-12-12 11:23:45 +01:00
2f4f3c13b6 work in progress 2018-12-12 03:27:04 +01:00
8e5b33793d Merge branch 'fixUXSharingTab' of s416084/find-my-tutor-android into develop 2018-12-11 23:10:39 +00:00
355d800909 added fix for acre double strings 2018-12-12 00:09:01 +01:00
f15e86cb21 Merge branch 'develop' into fixUXSharingTab 2018-12-11 21:33:24 +01:00
afd3463bec sharing tab stable version 1.1 2018-12-11 21:32:27 +01:00
Adam Domagalski
0c1bfb46c2 no opacity 2018-12-11 19:28:35 +01:00
Adam Domagalski
2147f533be Merge branch 'develop' into infoIcons 2018-12-11 19:25:21 +01:00
Adam Domagalski
2332823ba8 removed duplicated acra 2018-12-11 19:24:45 +01:00
9ffa64e793 Merge branch 'infoIcons' of s416084/find-my-tutor-android into develop 2018-12-10 23:22:54 +00:00
5f8e03986a Merge branch 'develop' into infoIcons 2018-12-11 00:22:35 +01:00
e34642fd6e info popups without on off switch 2018-12-11 00:04:01 +01:00
caa60e6f25 Merge branch 'develop' of s416084/find-my-tutor-android into master 2018-12-10 21:05:52 +00:00
2dda6ef65f Merge branch 'one-coord-master' of s416084/find-my-tutor-android into develop 2018-12-10 21:04:51 +00:00
041375b53f Put version adjusted to master 2018-12-10 22:02:10 +01:00
1803ac13b6 Merge branch 'fix-user-list' of s416084/find-my-tutor-android into develop 2018-12-10 20:14:13 +00:00
f757f36312 Clear list during fetch 2018-12-10 21:11:42 +01:00
ba73d08cd4 Merge branch 'develop' of ssh://git.wmi.amu.edu.pl/s416084/find-my-tutor-android into develop 2018-12-10 20:52:25 +01:00
Adam Domagalski
9aa9e8e0df moving from mac 2018-12-10 19:52:32 +01:00
03c5a9a3ce code clean up 2018-12-10 19:05:09 +01:00
b0927c174a Merge branch 'infoIcons' of https://git.wmi.amu.edu.pl/s416084/find-my-tutor-android into infoIcons 2018-12-10 18:25:22 +01:00
a6d4ef55d2 map info icon 2018-12-10 18:21:01 +01:00
Adam Domagalski
3f725cd3b3 tranlation without map updated 2018-12-10 13:32:57 +01:00
023926e36c Merge branch 'one-cord-per-user' of s416084/find-my-tutor-android into develop 2018-12-10 09:49:55 +00:00
844d636d6e Merge branch 'develop' of ssh://git.wmi.amu.edu.pl/s416084/find-my-tutor-android into develop 2018-12-10 09:45:30 +01:00
f4a0c71a18 Merge branch 'fixUXSharingTab' of s416084/find-my-tutor-android into develop 2018-12-10 00:53:24 +00:00
930876a2f5 sharing tab stable release 2018-12-10 01:16:18 +01:00
4c2f706422 Add put for cord 2018-12-10 00:00:04 +01:00
764518d49c :Merge branch 'develop' into fixUXSharingTab 2018-12-09 23:47:33 +01:00
5ffdf75b66 polished sharing tab 2018-12-09 23:45:16 +01:00
385df14b2f Merge 2018-12-09 18:54:18 +01:00
fc428451a9 map info pop up 2018-12-08 13:20:03 +01:00
5fe12a3f4b Merge branch 'fixUXSharingTab' of s416084/find-my-tutor-android into develop 2018-12-08 09:57:43 +00:00
Marcin Jedynski
3344449bf4 fixed choosing/viewing values from sharing tab 2018-12-08 10:55:53 +01:00
1abae28ae9 Merge branch 'mapboxUpgrade' of s416084/find-my-tutor-android into develop 2018-12-08 09:13:31 +00:00
3a38c1052d mapbox update + acra switch in settings 2018-12-08 10:10:53 +01:00
c8e49af5da Increase build version 2018-12-07 19:16:29 +01:00
e5f7a81c9a Merge branch 'develop' of s416084/find-my-tutor-android into master 2018-12-07 18:01:01 +00:00
80cd393cc9 Merge branch 'PR-master-auto-online' of s416084/find-my-tutor-android into develop 2018-12-07 18:00:13 +00:00
fd49c66ee1 Adjust to master 2018-12-07 18:59:30 +01:00
77ddbc39a5 Merge branch 'develop' into PR-master-auto-online 2018-12-07 18:58:02 +01:00
527701420b Add onfline and offline zones 2018-12-07 18:57:26 +01:00
Adam Domagalski
f177b80fa4 Merge branch 'develop' into infoIcons 2018-12-07 15:18:15 +01:00
f8abf61553 no misleading values but summary mising on fragment reload 2018-12-07 02:59:01 +01:00
5a8ec2d9fc Merge branch 'fmt-296' of s416084/find-my-tutor-android into develop 2018-12-06 23:08:27 +00:00
a9469cce76 reverted api url back to master 2018-12-06 23:58:47 +01:00
26e12d68f3 Merge branch 'PR-master-auto-online' of s416084/find-my-tutor-android into master 2018-12-06 22:38:02 +00:00
d735950e7a Merge 2018-12-06 23:37:22 +01:00
ca91124b8f Merge branch 'master' into PR-master-auto-online 2018-12-06 23:28:21 +01:00
8f6a07acea Merge branch 'develop' of git.wmi.amu.edu.pl:s416084/find-my-tutor-android into develop 2018-12-06 22:45:15 +01:00
8a44eaa8d0 Merge branch 'bg-task-increase-interval' of s416084/find-my-tutor-android into develop 2018-12-06 21:39:57 +00:00
c96e19cb2d Fix map 2018-12-06 22:38:22 +01:00
367bc7518e fixed toast on send feedback, minor model adjustment of feedback 2018-12-06 22:31:02 +01:00
0182d2e041 Merge branch 'develop' into bg-task-increase-interval 2018-12-06 22:00:04 +01:00
d9909a66bd Adjust to develop 2018-12-06 21:59:37 +01:00
0cec17dd16 Create handlers for coming in and out from building 2018-12-06 21:32:13 +01:00
8be7d3aa11 Merge branch 'fix-fetching-coords-in-map' of s416084/find-my-tutor-android into develop 2018-12-05 23:59:19 +00:00
b4dd785504 map ico info in progress 2018-12-06 00:57:53 +01:00
57702fd3a1 Merge branch 'develop' into fix-fetching-coords-in-map 2018-12-05 23:39:04 +01:00
381373b4b7 Fetch markers only when screen is on 2018-12-05 23:38:13 +01:00
45dac22ec4 Merge branch 'acraReporter' of s416084/find-my-tutor-android into develop 2018-12-05 21:49:52 +00:00
0dd0b0dc23 added some translation and removed throwing error for testing 2018-12-05 22:45:11 +01:00
d1adf451a0 Merge branch 'develop' into acraReporter 2018-12-05 21:26:12 +01:00
261002d131 Merge branch 'develop' of s416084/find-my-tutor-android into master 2018-12-05 13:25:24 +00:00
899fb9958b Merge branch 'fix-sharing-active-id' of s416084/find-my-tutor-android into develop 2018-12-05 13:23:49 +00:00
ce3d261c48 Merge branch 'develop' into fix-sharing-active-id 2018-12-05 14:22:37 +01:00
7fb1d90ab7 Increase build version 2018-12-05 14:22:04 +01:00
e095e9069f Merge branch 'fix-sharing-active-id' of s416084/find-my-tutor-android into develop 2018-12-05 13:18:56 +00:00
f0f1e59947 Fix default value 2018-12-05 14:17:34 +01:00
118296aa03 Merge branch 'develop' of s416084/find-my-tutor-android into master 2018-12-05 11:41:14 +00:00
9c9402c8c1 Merge branch 'fix-ssl-config' of s416084/find-my-tutor-android into develop 2018-12-05 11:40:56 +00:00
2ca64a66ba Rollback ssl config 2018-12-05 12:25:31 +01:00
3eed883079 Merge branch 'develop' of s416084/find-my-tutor-android into master 2018-12-05 09:04:20 +00:00
fc4f49c3e0 Merge branch 'fix-approx-loc' of s416084/find-my-tutor-android into develop 2018-12-05 09:03:45 +00:00
b2e5a0e0c5 Fix unknown location 2018-12-05 09:59:18 +01:00
5e51be5d0b First attempt 2018-12-05 00:45:16 +01:00
5fc5140866 Merge branch 'improve-user-modal' of s416084/find-my-tutor-android into develop 2018-12-04 21:23:09 +00:00
15529eccb4 Merge branch 'master' of s416084/find-my-tutor-android into develop 2018-12-04 20:37:06 +00:00
7174d7d117 Merge branch 'android7okhttpQuickFix3dec' of s416084/find-my-tutor-android into master 2018-12-03 15:04:47 +00:00
Adam Domagalski
e3e88d168f eliptic curve cipher TLS change for android 7 nougat 2018-12-03 16:00:35 +01:00
Adam Domagalski
f3f2f3b90a acra wtih intented crash on manual loc select 2018-12-02 21:29:47 +01:00
7c1b9e4494 Merge branch 'develop' of s416084/find-my-tutor-android into master 2018-12-01 16:13:12 +00:00
a7ba5bf27c Merge branch 'developMieszko27nov' of s416084/find-my-tutor-android into master 2018-11-29 21:35:16 +00:00
124 changed files with 6076 additions and 816 deletions

View File

@ -10,10 +10,11 @@ android {
applicationId "com.uam.wmi.findmytutor"
minSdkVersion 22
targetSdkVersion 27
versionCode 8
versionName "0.9.1-alpha"
versionCode 66
versionName "1.0.0"
testInstrumentationRunner "android.support.test.runner.AndroidJUnitRunner"
vectorDrawables.useSupportLibrary = true
resConfigs "en", "pl"
}
buildTypes {
release {
@ -28,11 +29,17 @@ repositories {
url 'http://dl.bintray.com/amulyakhare/maven'
}
}
def acraVersion = '5.2.1'
dependencies {
implementation "ch.acra:acra-http:$acraVersion"
implementation "ch.acra:acra-toast:$acraVersion"
implementation "ch.acra:acra-notification:$acraVersion"
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'
@ -46,7 +53,8 @@ dependencies {
implementation 'com.squareup.retrofit2:converter-gson:2.4.0'
implementation 'io.swagger:swagger-annotations:1.5.15'
implementation 'org.threeten:threetenbp:1.3.5'
implementation 'com.mapbox.mapboxsdk:mapbox-android-sdk:6.6.5'
implementation 'com.mapbox.mapboxsdk:mapbox-android-sdk:6.7.2'
implementation 'com.mapbox.mapboxsdk:mapbox-sdk-turf:4.0.0'
implementation 'io.reactivex.rxjava2:rxjava:2.2.0'
implementation 'com.android.support:recyclerview-v7:27.1.1'
implementation 'io.reactivex.rxjava2:rxandroid:2.1.0'
@ -60,8 +68,13 @@ dependencies {
implementation 'com.auth0.android:jwtdecode:1.1.1'
implementation 'com.annimon:stream:1.2.1'
implementation 'com.google.android.gms:play-services-location:16.0.0'
implementation 'com.mapbox.mapboxsdk:mapbox-sdk-turf:4.0.0'
// FloatingBarMenu
implementation 'com.getbase:floatingactionbutton:1.10.1'
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" />
@ -17,16 +17,20 @@
<uses-feature android:name="android.hardware.location.gps" />
<application
android:name=".FindMyTutor"
android:allowBackup="true"
android:icon="@mipmap/ic_launcher"
android:label="@string/app_name"
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:screenOrientation="portrait"
android:theme="@style/AppTheme.NoActionBar">
<intent-filter>
<action android:name="android.intent.action.MAIN" />
@ -36,14 +40,21 @@
</activity>
<activity
android:name=".activity.MapActivity"
android:launchMode="singleTop" />
android:configChanges="keyboardHidden|orientation|screenSize"
android:launchMode="singleTop"
android:screenOrientation="portrait"
android:windowSoftInputMode="adjustPan" />
<activity
android:name=".activity.LoginActivity"
android:configChanges="keyboardHidden|orientation|screenSize"
android:excludeFromRecents="true"
android:launchMode="singleTask"
android:noHistory="true" />
android:noHistory="true"
android:screenOrientation="portrait" />
<activity
android:name=".activity.SettingsActivity" />
android:name=".activity.SettingsActivity"
android:configChanges="keyboardHidden|orientation|screenSize"
android:screenOrientation="portrait" />
<service
android:name=".service.BackgroundLocalizationService"
@ -53,7 +64,21 @@
<activity
android:name=".activity.TutorTab"
android:theme="@style/AppTheme"></activity>
android:configChanges="keyboardHidden|orientation|screenSize"
android:windowSoftInputMode="stateHidden|adjustPan"
android:screenOrientation="portrait"
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

@ -0,0 +1,95 @@
package com.uam.wmi.findmytutor;
import android.app.Application;
import android.content.Context;
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 org.acra.ACRA;
import org.acra.annotation.AcraLimiter;
import org.acra.annotation.AcraNotification;
import org.acra.config.CoreConfigurationBuilder;
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)
.setBuildConfigClass(BuildConfig.class)
.setReportContent(REPORT_ID, PHONE_MODEL, LOGCAT, USER_APP_START_DATE, USER_CRASH_DATE, SHARED_PREFERENCES,
ANDROID_VERSION, STACK_TRACE, CUSTOM_DATA, BUILD_CONFIG)
.setReportFormat(StringFormat.JSON);
// Toast for user
builder.setBuildConfigClass(BuildConfig.class)
.setReportFormat(StringFormat.JSON);
builder.getPluginConfigurationBuilder(
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);
// Api POST
builder.getPluginConfigurationBuilder(
HttpSenderConfigurationBuilder.class
// ).setUri("http://192.168.0.15:3000/api/acra")
).setUri(Const.BASE_URL + "api/Feedback/autoFeedback")
.setHttpMethod(HttpSender.Method.POST)
.setHttpHeaders(header)
.setEnabled(true);
ACRA.init(this, builder);
//Shared preferences
ACRA.getErrorReporter().putCustomData("USER_ID", sharedPreferences.getString("USER_ID", "no user id"));
}
// Called by the system when the device configuration changes while your component is running.
// Overriding this method is totally optional!
@Override
public void onConfigurationChanged(Configuration newConfig) {
super.onConfigurationChanged(newConfig);
}
// This is called when the overall system is running low on memory,
// and would like actively running processes to tighten their belts.
// Overriding this method is totally optional!
@Override
public void onLowMemory() {
super.onLowMemory();
}
}

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,9 +4,11 @@ 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;
import android.graphics.drawable.ColorDrawable;
import android.os.Build;
import android.os.Bundle;
import android.support.annotation.NonNull;
@ -21,17 +23,21 @@ import android.support.v7.app.AppCompatActivity;
import android.support.v7.widget.SearchView;
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.FrameLayout;
import android.widget.LinearLayout;
import android.widget.PopupWindow;
import android.widget.Toast;
import com.mapbox.mapboxsdk.Mapbox;
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;
@ -49,8 +55,10 @@ import io.reactivex.functions.Function;
import io.reactivex.schedulers.Schedulers;
import static com.uam.wmi.findmytutor.utils.Consts.deafultMapZoom;
import static com.uam.wmi.findmytutor.utils.Consts.searchMapZoom;
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;
@ -76,27 +84,36 @@ public abstract class BaseActivity
private SharingFragment sharingFragment;
private Fragment userListFragment;
private ActiveFragment activeFragment = ActiveFragment.NONE;
private SearchView searchView;
public ActiveFragment activeFragment = ActiveFragment.NONE;
private Fragment activeBottomMenu = null;
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) {
super.onCreate(savedInstanceState);
setContentView(getContentViewId());
drawerNavigationView = findViewById(R.id.nav_view);
sideDrawer = findViewById(R.id.activity_container);
feedbackUtils = new FeedbackUtils(BaseActivity.this);
drawerNavigationView.setNavigationItemSelectedListener(
item -> {
String itemName = (String) item.getTitle();
Intent launchIntent;
if (itemName.equals(getResources().getString(R.string.navigation_item_whitelist))) {
/* 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))) {
@ -110,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");
@ -149,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>();
@ -191,17 +215,23 @@ public abstract class BaseActivity
}
public void stopBackgroundLocalizationTask() {
PrefUtils.storeEnableSharingLocalization(getApplicationContext(), false);
Intent stopIntent = new Intent(getApplicationContext(), BackgroundLocalizationService.class);
stopIntent.putExtra("request_stop", true);
startService(stopIntent);
stopService(stopIntent);
}
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);
@ -255,7 +285,6 @@ public abstract class BaseActivity
setUpNav();
actionBarDrawerToggle.syncState();
}
@Override
@ -268,6 +297,7 @@ public abstract class BaseActivity
@Override
public boolean onCreateOptionsMenu(Menu menu) {
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();
@ -275,7 +305,11 @@ public abstract class BaseActivity
searchView.setOnQueryTextFocusChangeListener((v, hasFocus) -> {
if (!hasFocus && activeFragment.equals(ActiveFragment.NONE)) {
restoreMapMarkers();
adjustMapToSearch(deafultMapZoom);
adjustMapToSearch(defaultMapZoom);
}
if (!hasFocus && activeFragment.equals(ActiveFragment.USER_LIST)) {
((UsersListFragment) userListFragment).restoreUsersList();
}
if(hasFocus && activeFragment.equals(ActiveFragment.NONE)){
@ -286,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())
@ -315,6 +350,33 @@ public abstract class BaseActivity
if (actionBarDrawerToggle.onOptionsItemSelected(item)) {
return true;
}
if (item.getItemId()==R.id.action_info){
int layoutID;
switch (activeFragment){
case SHARED_PREFERENCES:
layoutID = R.layout.info_popup_sharing_tab;
break;
case USER_LIST:
layoutID = R.layout.info_popup_userlist;
break;
default:
layoutID = R.layout.info_popup_map;
}
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);
}
@ -346,12 +408,15 @@ public abstract class BaseActivity
removeFragment(sharingFragment);
removeFragment(userListFragment);
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);
return true;
@ -362,6 +427,7 @@ public abstract class BaseActivity
sharingFragment = SharingFragment.newInstance();
FragmentTransaction ft = getFragmentManager().beginTransaction();
ft.replace(R.id.activity_content, sharingFragment);
//ft.addToBackStack(null);
ft.commit();
}
@ -371,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);
}
@ -385,9 +452,10 @@ public abstract class BaseActivity
item.setChecked(true);
}
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,8 +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);
disposable.add(ldapService.validate(user)
//disposable.add(ldapService.fakeValidate(fakeUser)
.subscribeOn(Schedulers.io())
.observeOn(AndroidSchedulers.mainThread())
.subscribe(this::handleResponse, this::handleError));
@ -189,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,15 +46,18 @@ 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;
import com.uam.wmi.findmytutor.utils.PrefUtils;
import com.uam.wmi.findmytutor.utils.RestApiHelper;
import com.uam.wmi.findmytutor.utils.SharingLevel;
import com.uam.wmi.findmytutor.utils.MapUtils;
import java.util.ArrayList;
import java.util.HashMap;
@ -67,30 +72,29 @@ 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 Handler manualLocHandler = new Handler();
private Runnable manualLocStatusChecker;
private MapView mapView;
private MapboxMap mapboxMap;
private Button selectLocationButton;
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
@ -100,10 +104,17 @@ public class MapActivity extends BaseActivity
private String myId;
private boolean isTutor;
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);
isTutor = PrefUtils.getIsTutor(this);
myId = PrefUtils.getUserId(getApplicationContext());
@ -115,17 +126,18 @@ public class MapActivity extends BaseActivity
mStatusChecker = () -> {
try {
fetchTopCoords();
if (shouldFetchNewCoords) {
checkIfUsesCanBeTutor();
fetchTopCoords();
}
} finally {
mHandler.postDelayed(mStatusChecker, mInterval);
}
};
selectLocationButton = findViewById(R.id.select_location_button);
removeLocationButton = findViewById(R.id.remove_location_button);
Mapbox.getInstance(this, getString(R.string.access_token));
mapView = findViewById(R.id.mapView);
mapView.onCreate(savedInstanceState);
mapView.getMapAsync(this);
@ -134,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
@ -144,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;
});
@ -211,14 +213,34 @@ public class MapActivity extends BaseActivity
TextView sharingLevelView = view.findViewById(R.id.sharing_level);
userName.setText(String.format("%s %s", user.getFirstName(), user.getLastName()));
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));
if (cordStatus.equals("")) {
status.setText(String.format("%s: %s", getResources().getString(R.string.status_switch_title), getString(R.string.lack_of_status)));
} else {
status.setText(String.format("%s: %s", getResources().getString(R.string.status_switch_title), cordStatus));
}
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();
}
private void handleError(Throwable error) {
showError(error);
}
@ -226,8 +248,6 @@ public class MapActivity extends BaseActivity
private void showError(Throwable e) {
String message;
Log.e("ERR",e.toString());
if (e instanceof HttpException) {
ResponseBody responseBody = ((HttpException) e).response().errorBody();
message = RestApiHelper.getErrorMessage(responseBody);
@ -239,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() {
@ -282,6 +307,11 @@ public class MapActivity extends BaseActivity
PrefUtils.getLocationLevel(getApplicationContext())
);
if (!PrefUtils.isEnableSharingLocalization(getApplicationContext())) {
EnableSharingDialog sharingDialog = new EnableSharingDialog();
sharingDialog.show(getFragmentManager(), "Sharing");
}
PrefUtils.putManualLocation(this, latLng, approximatedLocation);
handleBackgroundTaskLifeCycle();
@ -321,14 +351,18 @@ 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 -> alertDialog.dismiss());
dismissButton.setOnClickListener(view1 -> {
PrefUtils.putCurrentManualLocationName(getApplicationContext(), getString(R.string.other_location));
PrefUtils.putCurrentManualLocation(getApplicationContext(), "-1");
alertDialog.dismiss();
});
sendButton.setOnClickListener(view1 -> {
String body = modalUserInput.getText().toString();
@ -338,18 +372,18 @@ public class MapActivity extends BaseActivity
modalUserInput.requestFocus();
} else {
sendLocation(body, latLng);
PrefUtils.putCurrentManualLocationName(getApplicationContext(), body);
alertDialog.dismiss();
}
});
});
alertDialog.show();
}
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(),
@ -363,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)
@ -372,7 +406,31 @@ public class MapActivity extends BaseActivity
private void SaveCurrentManualLocation(PredefinedCoordViewModel resp) {
Toast.makeText(getApplicationContext(), R.string.location_saved, Toast.LENGTH_SHORT).show();
PrefUtils.putCurrentManualLocation(getApplicationContext(),resp.getPredefinedCoordinateId());
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() {
@ -389,7 +447,7 @@ public class MapActivity extends BaseActivity
public void onSuccess(List<Coordinate> coordsList) {
if (tmpLocalMarker != null && coordsList.isEmpty()) {
Timber.e("200 empty []");
Log.e("MapActivity", "200 empty []");
mapboxMap.clear();
}
@ -439,7 +497,7 @@ public class MapActivity extends BaseActivity
}
LatLng toDestination = new LatLng(element.getLatitude(), element.getLongitude());
// TODO fix flickiering markers
ValueAnimator markerAnimator = ObjectAnimator.ofObject(marker, "position",
new MapUtils.LatLngEvaluator(),
marker.getPosition(),
@ -587,46 +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();
}
@Override
protected void onStart() {
super.onStart();
mapView.onStart();
}
@Override
protected void onStop() {
super.onStop();
mapView.onStop();
}
@Override
public void onPause() {
super.onPause();
mapView.onPause();
}
@Override
public void onLowMemory() {
super.onLowMemory();
mapView.onLowMemory();
}
@Override
protected void onDestroy() {
super.onDestroy();
mapView.onDestroy();
mHandler.removeCallbacks(mStatusChecker);
// TODO remove after BG sending
manualLocHandler.removeCallbacks(manualLocStatusChecker);
disposable.dispose();
}
@Override
protected void onSaveInstanceState(Bundle outState) {
@ -636,6 +654,7 @@ public class MapActivity extends BaseActivity
@Override
protected int getContentViewId() {
Mapbox.getInstance(this, getString(R.string.access_token));
return R.layout.activity_map;
}
@ -668,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 ->
@ -680,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);
}
@ -690,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);
@ -711,18 +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);
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;
@ -11,15 +12,19 @@ import android.preference.Preference;
import android.preference.PreferenceFragment;
import android.preference.PreferenceManager;
import android.util.DisplayMetrics;
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();
@ -32,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;
@ -54,16 +65,19 @@ public class SettingsActivity extends AppCompatPreferenceActivity {
Preference languagesList = findPreference(getResources().getString(R.string.key_language));
languagesList.setDefaultValue(0);
if(PrefUtils.getLocale(getActivity()).equals("pl")){
if(PrefUtils.getLocale(getActivity()).equals("1")){
languagesList.setDefaultValue(1);
}
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,12 +1,17 @@
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;
import android.preference.Preference;
import android.preference.PreferenceCategory;
import android.preference.PreferenceFragment;
import android.preference.SwitchPreference;
import android.util.Log;
import android.view.LayoutInflater;
import android.view.View;
@ -19,13 +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.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;
@ -39,19 +48,29 @@ import okhttp3.ResponseBody;
import static com.mapbox.mapboxsdk.Mapbox.getApplicationContext;
public class SharingFragment extends PreferenceFragment {
protected Preference locationSharing;
public class SharingFragment extends PreferenceFragment implements SharedPreferences.OnSharedPreferenceChangeListener {
protected SwitchPreference locationSharing;
protected SwitchPreference statusSwitch;
protected Preference locationMode;
protected Preference manualLocationList;
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();
@ -65,8 +84,14 @@ public class SharingFragment extends PreferenceFragment {
.subscribeWith(new DisposableSingleObserver<List<String>>() {
@Override
public void onSuccess(List<String> strings) {
String[] statusesArray = strings.toArray(new String[strings.size()]);
setListPreferenceData(statusList.getKey(), statusesArray,strings.size() -1);
statusesArray = strings.toArray(new String[strings.size()]);
if (strings.isEmpty()) {
disableStatusPreferences();
} else {
enableStatusPreferences();
}
// Log.d("STATUSES",Integer.toString(statusesArray.length ));
setListPreferenceData(statusList, statusesArray, null);
}
@Override
@ -78,57 +103,81 @@ public class SharingFragment extends PreferenceFragment {
}
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) {
List<String> names = Stream.of(coords).map(PredefinedCoordViewModel::getName).collect(com.annimon.stream.Collectors.toList());
predefinedCoordsList.addAll(coords);
String[] stringnames = names.toArray(new String[0]);
String currentCoordId = PrefUtils.getCurrentManualLocation(getApplicationContext());
List<Integer> activeId = Stream.of(coords).indexed()
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(activeId.size() > 0)
setListPreferenceData(manualLocationList.getKey(), stringnames, activeId.get(0));
else{
setListPreferenceData(manualLocationList.getKey(), stringnames,null);
if (activesId.size() == 0) {
setListPreferenceData(manualLocationList, stringnames, null);
} else {
setListPreferenceData(manualLocationList, stringnames, activesId.get(0));
}
}
@Override
public void onError(Throwable e) {
Toast.makeText(getApplicationContext(), R.string.manual_status_error, Toast.LENGTH_SHORT).show();
Toast.makeText(getApplicationContext(), R.string.error_location_fetch, Toast.LENGTH_SHORT).show();
}
}));
}
@SuppressLint("ResourceType")
@Override
public void onCreate(final Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
addPreferencesFromResource(R.layout.pref_sharing);
locationSharing = findPreference("key_sharing_enabled");
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 = findPreference("key_manual_location_value");
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);
if (PrefUtils.getLocationLevel(getApplicationContext()).equals("manual")) {
getLocations(disposable);
}
getLocations(disposable);
locationLevelMapping = new HashMap<Integer, String>();
locationLevelMapping.put(0, SharingLevel.PRESENCE.toString());
locationLevelMapping.put(1, SharingLevel.APPROXIMATED.toString());
@ -140,6 +189,10 @@ public class SharingFragment extends PreferenceFragment {
statusMapping.put(1, "consultation");
statusMapping.put(2, "busy");
statusList.setSummary(PrefUtils.getUserStatus(getApplicationContext()));
manualLocationList.setSummary(PrefUtils.getCurrentManualLocationName(getApplicationContext()));
/** Main sharing switch**/
locationSharing.setOnPreferenceChangeListener((buttonView, newValue) -> {
PrefUtils.storeEnableSharingLocalization(getApplicationContext(), (Boolean) newValue);
@ -149,35 +202,45 @@ public class SharingFragment extends PreferenceFragment {
/** 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("manual")) {
preferenceCategory.addPreference(manualLocationList);
getLocations(disposable);
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) -> {
ListPreference lp = (ListPreference) preference;
CharSequence[] entries = lp.getEntries();
PredefinedCoordViewModel temp = Stream.of(predefinedCoordsList).filter(p -> p.getName().equals(lp.getEntries()[Integer.parseInt((String) newValue)].toString())).toList().get(0);
PrefUtils.putManualLocation(getApplicationContext(), temp.getGeoData(), temp.getApproximatedLocation() );
PrefUtils.putCurrentManualLocation(getApplicationContext(),temp.getPredefinedCoordinateId());
//sharing dialog -> ask for start BG
if (!PrefUtils.isEnableSharingLocalization(getApplicationContext())) {
EnableSharingDialog sharingDialog = new EnableSharingDialog();
sharingDialog.show(getFragmentManager(), "Sharing");
}
PrefUtils.putManualLocation(getApplicationContext(), temp.getGeoData(), temp.getApproximatedLocation());
PrefUtils.putCurrentManualLocation(getApplicationContext(), temp.getPredefinedCoordinateId());
PrefUtils.putCurrentManualLocationName(getApplicationContext(), (String) lp.getEntries()[Integer.parseInt((String) newValue)]);
lp.setSummary(lp.getEntries()[Integer.parseInt((String) newValue)]);
((MapActivity) getActivity()).handleBackgroundTaskLifeCycle();
return true;
});
@ -187,18 +250,29 @@ public class SharingFragment extends PreferenceFragment {
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;
CharSequence[] entries = lp.getEntries();
PrefUtils.storeStatus(getApplicationContext(), (String) entries[Integer.parseInt((String) newValue)]);
lp.setSummary(entries[Integer.parseInt((String) newValue)]);
return true;
});
/** Custom status list change listener **/
statusList.setOnPreferenceClickListener(new Preference.OnPreferenceClickListener() {
@Override
public boolean onPreferenceClick(Preference preference) {
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)
@ -206,10 +280,43 @@ public class SharingFragment extends PreferenceFragment {
.observeOn(AndroidSchedulers.mainThread())
.subscribe(this::handleResponse, this::handleError));
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
@ -220,30 +327,73 @@ public class SharingFragment extends PreferenceFragment {
return view;
}
protected void setListPreferenceData(String lp_name, String[] entries, Integer activeId) {
ListPreference lp = (ListPreference) findPreference(lp_name);
lp.setEntries(entries);
CharSequence[] entryValues = new CharSequence[entries.length];
protected void removeEntries(String service, ArrayList<String> toBeDeleted) {
for (int i = 0; i < entries.length; i++) {
entryValues[i] = Integer.toString(i);
// 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 {
lp.setEntries(entries);
CharSequence[] entryValues = new CharSequence[entries.length];
for (int i = 0; i < entries.length; i++) {
entryValues[i] = Integer.toString(i);
}
lp.setDefaultValue(0);
lp.setEntryValues(entryValues);
if (entries.length > 0 && activeId != null)
lp.setValueIndex(activeId);
} catch (Exception e) {
Log.e("Failed to set listPref", e.getMessage());
}
lp.setDefaultValue(0);
lp.setEntryValues(entryValues);
}
if(entries.length > 0)
lp.setValueIndex(activeId);
};
;
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.getKey(), statusesArray,resp.size() - 1);
setListPreferenceData(statusList, statusesArray, resp.size() - 1);
statusList.setValueIndex(resp.size() - 1);
PrefUtils.storeStatus(getApplicationContext(), resp.get(resp.size() - 1));
statusList.setSummary(PrefUtils.getUserStatus(getApplicationContext()));
}
private void handleError(Throwable error) {
@ -258,4 +408,101 @@ public class SharingFragment extends PreferenceFragment {
}
}
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() {
super.onResume();
getPreferenceManager().getSharedPreferences().registerOnSharedPreferenceChangeListener(this);
}
@Override
public void onPause() {
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,11 +32,17 @@ 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) {
if (PrefUtils.isLoggedIn(getApplicationContext())){
Intent startupIntent = new Intent(this, MapActivity.class);
PrefUtils.storeLocale(getApplicationContext(),PrefUtils.getLocale(getApplicationContext()));
startupIntent.putExtra(currentLang, PrefUtils.getLocale(getApplicationContext()));
startupIntent.setFlags(Intent.FLAG_ACTIVITY_CLEAR_TASK | Intent.FLAG_ACTIVITY_NEW_TASK | Intent.FLAG_ACTIVITY_CLEAR_TOP);
startActivity(startupIntent);
@ -30,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
@ -46,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,35 +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.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;
@ -37,59 +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);
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>() {
@ -102,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) {
@ -141,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));
}
}
@ -153,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,38 +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 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.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;
@ -56,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() {
}
@ -73,9 +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;
}
@ -84,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
@ -110,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) {
@ -129,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);
@ -136,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())
@ -146,16 +244,30 @@ 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();
if(dutyHoursList.isEmpty()){
if (dutyHoursList.isEmpty()) {
dutyHoursList.add(getString(R.string.lack_duty_hours));
}
if(tutorTabViewModel.getNote().isEmpty()){
if (tutorTabViewModel.getNote().isEmpty()) {
userNoteText = getString(R.string.lack_note);
}
@ -165,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);
@ -182,38 +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();
tutorsList.addAll(users);
tutorsFiltered.addAll(users);
mAdapter.notifyDataSetChanged();
toggleEmptyNotes();
fetchTopCords();
}
@Override
@ -223,33 +327,135 @@ 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());
return plCollator.compare(t1.getLastName(), t2.getLastName());
}
private void showError(Throwable e) {
String message;
Log.e(TAG, String.valueOf(e));
if (e instanceof HttpException) {
ResponseBody responseBody = ((HttpException) e).response().errorBody();
message = RestApiHelper.getErrorMessage(responseBody);
}else{
message = "Network Error !";
} else {
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();
@ -272,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

@ -3,7 +3,9 @@ package com.uam.wmi.findmytutor.model;
import android.util.Range;
import com.google.gson.annotations.SerializedName;
import com.uam.wmi.findmytutor.utils.Const;
import java.util.List;
import java.util.Objects;
import java.util.UUID;
@ -14,11 +16,9 @@ import io.swagger.annotations.ApiModelProperty;
*/
public class Coordinate extends BaseResponse {
Range<Double> latitudeRange = Range.create(52.46598, 52.467545);
Range<Double> longtitudeRange = Range.create(16.926099, 16.927794);
@SerializedName("coordinateId")
private UUID coordinateId = null;
private Range<Double> latitudeRange = Const.buildingLatitudeRange;
private Range<Double> longtitudeRange = Const.buildingLongitudeRange;
private List<String> allowedApproximatedLocations = Const.validApproximatedLocations;
@SerializedName("latitude")
private Double latitude;
@ -47,7 +47,7 @@ public class Coordinate extends BaseResponse {
public Coordinate (Double latitude, Double longitude, Double altitude, String approximatedLocation, String label, String userId, String displayMode) {
if (!latitudeRange.contains(latitude)) throw new IllegalArgumentException("Inappropriate latitude value" + latitude);
if (!longtitudeRange.contains(longitude)) throw new IllegalArgumentException("Inappropriate longitude value" + longitude);
//if (approximatedLocation == null) throw new IllegalArgumentException("Inappropriate approximatedLocation");
if (!allowedApproximatedLocations.contains(approximatedLocation)) throw new IllegalArgumentException("Inappropriate approximatedLocation");
this.latitude = latitude;
this.longitude = longitude;
@ -63,23 +63,9 @@ public class Coordinate extends BaseResponse {
}
public Coordinate coordinateId(UUID coordinateId) {
this.coordinateId = coordinateId;
return this;
}
/**
* Get coordinateId
* @return coordinateId
**/
@ApiModelProperty(required = true, value = "")
public UUID getCoordinateId() {
return coordinateId;
}
public void setCoordinateId(UUID coordinateId) {
this.coordinateId = coordinateId;
}
public Coordinate latitude(Double latitude) {
this.latitude = latitude;
return this;
@ -233,8 +219,7 @@ public class Coordinate extends BaseResponse {
return false;
}
Coordinate coordinate = (Coordinate) o;
return Objects.equals(this.coordinateId, coordinate.coordinateId) &&
Objects.equals(this.latitude, coordinate.latitude) &&
return Objects.equals(this.latitude, coordinate.latitude) &&
Objects.equals(this.longitude, coordinate.longitude) &&
Objects.equals(this.altitude, coordinate.altitude) &&
Objects.equals(this.userId, coordinate.userId) &&
@ -246,7 +231,7 @@ public class Coordinate extends BaseResponse {
@Override
public int hashCode() {
return Objects.hash(coordinateId, latitude, longitude, altitude, userId, approximatedLocation, displayMode, timeStamp, label);
return Objects.hash( latitude, longitude, altitude, userId, approximatedLocation, displayMode, timeStamp, label);
}
@ -255,7 +240,6 @@ public class Coordinate extends BaseResponse {
StringBuilder sb = new StringBuilder();
sb.append("class Coordinate {\n");
sb.append(" coordinateId: ").append(toIndentedString(coordinateId)).append("\n");
sb.append(" latitude: ").append(toIndentedString(latitude)).append("\n");
sb.append(" longitude: ").append(toIndentedString(longitude)).append("\n");
sb.append(" altitude: ").append(toIndentedString(altitude)).append("\n");

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,12 +108,11 @@ public class DutyHourViewModel {
return Objects.hash(day, start, end);
}
public String getSummary() {
return this.getDay() + " " + this.getStart() + " " + this.getEnd();
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

@ -4,15 +4,20 @@ import android.content.Context;
import android.text.TextUtils;
import com.jakewharton.retrofit2.adapter.rxjava2.RxJava2CallAdapterFactory;
import com.uam.wmi.findmytutor.utils.Const;
import com.uam.wmi.findmytutor.utils.PrefUtils;
import java.io.IOException;
import java.util.Collections;
import java.util.concurrent.TimeUnit;
import okhttp3.CipherSuite;
import okhttp3.ConnectionSpec;
import okhttp3.Interceptor;
import okhttp3.OkHttpClient;
import okhttp3.Request;
import okhttp3.Response;
import okhttp3.TlsVersion;
import okhttp3.logging.HttpLoggingInterceptor;
import retrofit2.Retrofit;
import retrofit2.converter.gson.GsonConverterFactory;
@ -22,7 +27,6 @@ public class ApiClient {
private static Retrofit retrofit = null;
private static int REQUEST_TIMEOUT = 60;
private static OkHttpClient okHttpClient;
private static final String BASE_URL = "https://s416084.projektstudencki.pl/master/";
public static Retrofit getClient(Context context) {
@ -31,43 +35,45 @@ public class ApiClient {
if (retrofit == null) {
retrofit = new Retrofit.Builder()
.baseUrl(BASE_URL)
.baseUrl(Const.BASE_URL)
.client(okHttpClient)
.addConverterFactory(GsonConverterFactory.create())
.addCallAdapterFactory(RxJava2CallAdapterFactory.create())
.build();
}
return retrofit;
}
private static void initOkHttp(final Context context) {
OkHttpClient.Builder httpClient = new OkHttpClient().newBuilder()
.connectTimeout(REQUEST_TIMEOUT, TimeUnit.SECONDS)
.readTimeout(REQUEST_TIMEOUT, TimeUnit.SECONDS)
.writeTimeout(REQUEST_TIMEOUT, TimeUnit.SECONDS);
private static void initOkHttp(final Context context) {
HttpLoggingInterceptor interceptor = new HttpLoggingInterceptor();
interceptor.setLevel(HttpLoggingInterceptor.Level.BODY);
OkHttpClient.Builder httpClient = new OkHttpClient().newBuilder()
.connectTimeout(REQUEST_TIMEOUT, TimeUnit.SECONDS)
.readTimeout(REQUEST_TIMEOUT, TimeUnit.SECONDS)
.writeTimeout(REQUEST_TIMEOUT, TimeUnit.SECONDS);
httpClient.addInterceptor(interceptor);
HttpLoggingInterceptor interceptor = new HttpLoggingInterceptor();
interceptor.setLevel(HttpLoggingInterceptor.Level.BODY);
httpClient.addInterceptor(chain -> {
Request original = chain.request();
Request.Builder requestBuilder = original.newBuilder()
.addHeader("Accept", "application/json")
.addHeader("Content-Type", "application/json");
httpClient.addInterceptor(interceptor);
httpClient.addInterceptor(chain -> {
Request original = chain.request();
Request.Builder requestBuilder = original.newBuilder()
.addHeader("Accept", "application/json")
.addHeader("Content-Type", "application/json");
// Adding Authorization token (API Key)
// Requests will be denied without API key
if (!TextUtils.isEmpty(PrefUtils.getApiKey(context))) {
requestBuilder.addHeader("Authorization", "Bearer " + PrefUtils.getApiKey(context));
}
// Adding Authorization token (API Key)
// Requests will be denied without API key
if (!TextUtils.isEmpty(PrefUtils.getApiKey(context))) {
requestBuilder.addHeader("Authorization", "Bearer " + PrefUtils.getApiKey(context));
}
Request request = requestBuilder.build();
return chain.proceed(request);
});
Request request = requestBuilder.build();
return chain.proceed(request);
});
okHttpClient = httpClient.build();
}
};
okHttpClient = httpClient.build();
}
};

View File

@ -11,78 +11,83 @@ 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.HandlerThread;
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;
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.PrefUtils;
import com.uam.wmi.findmytutor.utils.RestApiHelper;
import com.uam.wmi.findmytutor.utils.SharingLevel;
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.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.TimerTask;
import io.reactivex.android.schedulers.AndroidSchedulers;
import io.reactivex.disposables.CompositeDisposable;
import io.reactivex.observers.DisposableSingleObserver;
import io.reactivex.observers.DisposableCompletableObserver;
import io.reactivex.schedulers.Schedulers;
import okhttp3.ResponseBody;
import timber.log.Timber;
import static com.uam.wmi.findmytutor.utils.Consts.presenceApproximatedName;
import static com.uam.wmi.findmytutor.utils.Consts.presenceLatitude;
import static com.uam.wmi.findmytutor.utils.Consts.presenceLongitude;
import static com.uam.wmi.findmytutor.utils.Const.offlineBackgroundLocationInterval;
import static com.uam.wmi.findmytutor.utils.Const.onlineBackgroundLocationInterval;
import static com.uam.wmi.findmytutor.utils.Const.presenceApproximatedName;
import static com.uam.wmi.findmytutor.utils.Const.presenceLatitude;
import static com.uam.wmi.findmytutor.utils.Const.presenceLongitude;
import static com.uam.wmi.findmytutor.utils.PrefUtils.storeBackgroundLocationStatus;
import static java.lang.String.valueOf;
public class BackgroundLocalizationService extends Service {
private static final String TAG = "MyLocationService";
private static final int LOCATION_INTERVAL = 1000;
private static final float LOCATION_DISTANCE = 5f;
public static String str_receiver = "background.location.broadcast";
private static long notify_interval = 10000;
Location mLastLocation;
Boolean stopService = false;
Intent intent;
ArrayList<String> providers = new ArrayList<String>();
LocationListener[] mLocationListeners;
private LocationManager mLocationManager = null;
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 CircularFifoQueue<Location> coordinatesHistory = new CircularFifoQueue<Location>(coordinatesHistoryLength);
private Handler mHandler = new Handler();
private HandlerThread mHandlerThread = null;
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
@ -97,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);
@ -108,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");
@ -121,53 +148,114 @@ 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;
}
mLocationRequest = new LocationRequest();
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() {
Integer prevInterval = notify_interval;
Boolean shouldExtendTimeInterval = Stream.of(coordinatesHistory)
.map(MapUtils::checkIfCoordinateIsValid).takeWhile(s -> !s).toList().size() == coordinatesHistoryLength;
mStatusChecker = () -> {
try {
fn_getlocation();
} finally {
mHandler.postDelayed(mStatusChecker, notify_interval);
}
};
Boolean shouldAbbreviateTimeInterval = Stream.of(coordinatesHistory).
map(MapUtils::checkIfCoordinateIsValid).filter(x -> x).toList().size() > 0;
AsyncTask.execute(mStatusChecker);
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();
}
}
@RequiresApi(api = Build.VERSION_CODES.O)
private void startMyOwnForeground() {
String NOTIFICATION_CHANNEL_ID = "com.example.simpleapp";
String channelName = "My Background Service";
String NOTIFICATION_CHANNEL_ID = "com.example.fmt";
String channelName = "FMT Background location service";
NotificationChannel chan = new NotificationChannel(NOTIFICATION_CHANNEL_ID, channelName, NotificationManager.IMPORTANCE_NONE);
chan.setLightColor(Color.BLUE);
chan.setLockscreenVisibility(Notification.VISIBILITY_PRIVATE);
@ -184,46 +272,7 @@ public class BackgroundLocalizationService extends Service {
startForeground(2, notification);
}
private void fn_getlocation() {
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;
for (String provider : providers1) {
Location location = mLocationManager.getLastKnownLocation(provider);
if (location == null) {
continue;
}
if (bestLocation == null || location.getAccuracy() < bestLocation.getAccuracy()) {
bestLocation = location;
}
}
Log.e("Best localization:", String.valueOf(bestLocation));
mFusedLocationClient.getLastLocation().addOnSuccessListener(
location -> {
if (location != null) {
mLastLocation = location;
fn_update(location);
}
});
}
private void fn_update(Location location) {
private void sendCoordinateToBackend(Location location) {
new Task(location).execute();
}
@ -233,66 +282,48 @@ 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);
Log.i(TAG, "Removed");
} 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 TimerTaskToGetLocation extends TimerTask {
@Override
public void run() {
mHandler.post(BackgroundLocalizationService.this::fn_getlocation);
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);
}
}
private class LocationListener implements android.location.LocationListener {
public LocationListener(String provider) {
Log.e(TAG, "LocationListener " + provider);
mLastLocation = new Location(provider);
}
@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 {
@ -309,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));
}
@ -317,8 +349,14 @@ public class BackgroundLocalizationService extends Service {
protected Object doInBackground(Object[] objects) {
String locationLevel = PrefUtils.getLocationLevel(getApplicationContext());
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;
@ -333,44 +371,41 @@ 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,
longitude,
altitude,
approximatedBuildingPart,
(PrefUtils.isStatusEnabled(getApplicationContext())) ? PrefUtils.getUserStatus(getApplicationContext()) : "",
status,
PrefUtils.getUserId(getApplicationContext()),
locationLevel
);
disposable.add(
coordinateService
.postCoordinate(coordinate)
.putCoordinate(coordinate, PrefUtils.getUserId(getApplicationContext()))
.subscribeOn(Schedulers.io())
.observeOn(AndroidSchedulers.mainThread())
.subscribeWith(new DisposableSingleObserver<Coordinate>() {
@SuppressLint("LongLogTag")
.subscribeWith(new DisposableCompletableObserver() {
@Override
public void onSuccess(Coordinate coord) {
Log.e("CoordinateService onSuccess", String.valueOf(coord));
public void onComplete() {
Log.e(TAG, "CoordinateSuccess");
}
@SuppressLint("LongLogTag")
@Override
public void onError(Throwable e) {
Log.e("CoordinateService onError", e.getMessage());
if (e instanceof HttpException) {
ResponseBody responseBody = ((HttpException) e).response().errorBody();
Log.e("CoordinateService onError", RestApiHelper.getErrorMessage(responseBody));
}
Log.e(TAG, "onErr" + valueOf(e));
}
}));
} catch (IllegalArgumentException e) {
Log.e(TAG,e.toString());
Log.e(TAG, e.toString());
}
return null;

View File

@ -3,6 +3,7 @@ package com.uam.wmi.findmytutor.service;
import com.uam.wmi.findmytutor.model.Coordinate;
import java.util.List;
import io.reactivex.Completable;
import io.reactivex.Single;
import retrofit2.http.Body;
import retrofit2.http.DELETE;
@ -24,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();
@ -36,9 +37,11 @@ public interface CoordinateService {
Single <Coordinate> postCoordinate(@Body Coordinate coordinate);
@PUT("api/coordinates/{id}")
Single<Coordinate> putCoordinatesById(@Path("id") String id);
Completable putCoordinate(@Body Coordinate coordinate, @Path("id") String id);
@DELETE("api/coordinates/{id}")
Single<Coordinate> deleteCoordinatesById(@Path("id") String id);
Completable deleteCoordinatesById(@Path("id") String id);
}

View File

@ -10,7 +10,7 @@ import retrofit2.http.POST;
public interface FeedbackService {
@POST("api/Feedback")
Observable<Void> postFeedback(@Body Feedback feedback);
Observable<Response<Void>> postFeedback(@Body Feedback feedback);
@GET("api/Feedback")
Observable<Void> getFeedback();

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

@ -1,25 +1,18 @@
package com.uam.wmi.findmytutor.utils;
import android.support.annotation.NonNull;
import com.google.gson.GsonBuilder;
import com.mapbox.geojson.BoundingBox;
import com.mapbox.geojson.Feature;
import com.mapbox.geojson.FeatureCollection;
import com.mapbox.geojson.Geometry;
import com.mapbox.geojson.Point;
import com.mapbox.geojson.Polygon;
import com.mapbox.geojson.gson.BoundingBoxDeserializer;
import com.mapbox.geojson.gson.GeoJsonAdapterFactory;
import com.mapbox.geojson.gson.GeometryDeserializer;
import com.mapbox.geojson.gson.PointDeserializer;
import com.mapbox.turf.TurfClassification;
import com.mapbox.turf.TurfJoins;
import com.mapbox.turf.TurfMeasurement;
import java.util.Arrays;
import java.util.List;
import java.util.Objects;
;
;import static com.mapbox.geojson.FeatureCollection.fromJson;
public class ApproximatedLocalization {
private FeatureCollection buildingSchema = null;
@ -28,17 +21,6 @@ public class ApproximatedLocalization {
buildingSchema = fromJson(buildingObject);
}
private FeatureCollection fromJson(@NonNull String json) {
GsonBuilder gson = new GsonBuilder();
gson.registerTypeAdapterFactory(GeoJsonAdapterFactory.create());
gson.registerTypeAdapter(Point.class, new PointDeserializer());
gson.registerTypeAdapter(Geometry.class, new GeometryDeserializer());
gson.registerTypeAdapter(BoundingBox.class, new BoundingBoxDeserializer());
return gson.create().fromJson(json, FeatureCollection.class);
}
public String getNameOfBuildingPart(Point point) {
for (Feature feature : Objects.requireNonNull(buildingSchema.features())) {
@ -48,7 +30,7 @@ public class ApproximatedLocalization {
return Objects.requireNonNull(Objects.requireNonNull(feature.getStringProperty("name")));
}
return null;
return Const.presenceApproximatedName;
}
public List<Double> getMiddlePointOfBuildingPart(String buildingPart) {
@ -56,7 +38,9 @@ public class ApproximatedLocalization {
for (Feature feature : Objects.requireNonNull(buildingSchema.features())) {
String partName = feature.getStringProperty("name");
if (buildingPart != null && buildingPart.equals(partName)) {
Double longitude = feature.getNumberProperty("longitude").doubleValue();
Double latitude = feature.getNumberProperty("latitude").doubleValue();

View File

@ -0,0 +1,26 @@
package com.uam.wmi.findmytutor.utils;
import android.util.Range;
import java.util.Arrays;
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 = 360000;
public final static Integer defaultMapZoom = 17;
public final static Integer searchMapZoom = 13;
public final static Double presenceLatitude = 52.466365;
public final static Double presenceLongitude = 16.926792;
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.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

@ -1,14 +0,0 @@
package com.uam.wmi.findmytutor.utils;
import android.util.Range;
public class Consts {
public final static Integer deafultMapZoom = 17;
public final static Integer searchMapZoom = 13;
public final static Double presenceLatitude = 52.466365;
public final static Double presenceLongitude = 16.926792;
public final static String presenceApproximatedName = "unknown";
public final static Range<Double> latitudeRange = Range.create(52.466709, 52.467007);
public final static Range<Double> longtitudeRange = Range.create(16.926159, 16.926976);
}

View File

@ -0,0 +1,31 @@
package com.uam.wmi.findmytutor.utils;
import android.app.Dialog;
import android.app.DialogFragment;
import android.content.Context;
import android.os.Bundle;
import android.support.v7.app.AlertDialog;
import android.widget.Toast;
import com.uam.wmi.findmytutor.R;
import com.uam.wmi.findmytutor.activity.MapActivity;
public class EnableSharingDialog extends DialogFragment {
@Override
public Dialog onCreateDialog(Bundle savedInstanceState) {
return new AlertDialog.Builder(getActivity())
.setTitle(R.string.sharing_modal_title)
.setMessage(R.string.enable_sharing_question)
.setPositiveButton(R.string.possitive_dialog_button, (dialog, which) ->
dialogPositiveAnswer(getActivity())
)
.setNegativeButton(R.string.negative_dialog_button, (dialog, which) -> dialog.cancel()).create();
}
private void dialogPositiveAnswer(Context context) {
PrefUtils.storeEnableSharingLocalization(context, true);
((MapActivity) getActivity()).handleBackgroundTaskLifeCycle();
}
}

View File

@ -82,10 +82,9 @@ public class FeedbackUtils {
try {
appVersion = activityContext.getPackageManager().getPackageInfo(activityContext.getPackageName(), 0).versionName;
if( !mode ){
body = PrefUtils.getUserFirstName(activityContext) + " " + PrefUtils.getUserLastName(activityContext) + "\n" + body;
userFeedback = new Feedback(mode,
header,
PrefUtils.getUserId(activityContext),
PrefUtils.getUserFirstName(activityContext) + " " + PrefUtils.getUserLastName(activityContext) + " | " + PrefUtils.getUserId(activityContext),
"Android "+ Build.VERSION.RELEASE,
appVersion,
Build.MODEL,
@ -113,8 +112,10 @@ public class FeedbackUtils {
.observeOn(AndroidSchedulers.mainThread())
.subscribe(this::handleResponse, this::handleError));
}
private void handleResponse( Void resp) {
private void handleResponse( Response<Void> resp) {
Toast.makeText(activityContext, activityContext.getString(R.string.modal_feedback_thankyou), Toast.LENGTH_SHORT).show();
Log.d("FEEDBACK toast","gdzie jest mój tost");
}
private void handleError(Throwable error) {

View File

@ -0,0 +1,35 @@
package com.uam.wmi.findmytutor.utils;
import android.content.Context;
import android.graphics.drawable.ColorDrawable;
import android.view.Gravity;
import android.view.LayoutInflater;
import android.view.View;
import android.widget.LinearLayout;
import android.widget.PopupWindow;
import java.util.Objects;
import static com.mapbox.mapboxsdk.Mapbox.getApplicationContext;
public class InfoHelperUtils {
public static void infoPopUp(View anchorView, int layoutId) {
LayoutInflater layoutInflater = (LayoutInflater)getApplicationContext().getSystemService( Context.LAYOUT_INFLATER_SERVICE );
View popupView = Objects.requireNonNull(layoutInflater).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());
int location[] = new int[2];
// Get the View's(the one that was clicked in the Fragment) location
anchorView.getLocationOnScreen(location);
// Using location, the PopupWindow will be displayed right under anchorView
popupWindow.showAtLocation(anchorView, Gravity.NO_GRAVITY,
location[0] + anchorView.getWidth() / 2, location[1] + anchorView.getHeight());
}
}

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,15 +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(Context context){
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.N){
return String.valueOf(context.getResources().getConfiguration().getLocales().get(0));
} else{
//noinspection deprecation
return String.valueOf(context.getResources().getConfiguration().locale);
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

@ -44,8 +44,6 @@ public class ManualLocationUtils {
activityContext = context;
}
private void handleError(Throwable error) {
if (error instanceof HttpException) {

View File

@ -1,31 +1,28 @@
package com.uam.wmi.findmytutor.utils;
import android.animation.TypeEvaluator;
import android.app.AlertDialog;
import android.content.Context;
import android.graphics.Color;
import android.content.Intent;
import android.location.Location;
import android.view.Gravity;
import android.view.View;
import android.widget.FrameLayout;
import android.content.res.AssetManager;
import android.net.Uri;
import android.provider.Settings;
import com.mapbox.mapboxsdk.annotations.Polygon;
import com.mapbox.mapboxsdk.annotations.PolygonOptions;
import com.mapbox.mapboxsdk.camera.CameraPosition;
import com.mapbox.mapboxsdk.camera.CameraUpdateFactory;
import com.mapbox.mapboxsdk.geometry.LatLng;
import com.mapbox.mapboxsdk.geometry.LatLngBounds;
import com.mapbox.mapboxsdk.maps.MapView;
import com.mapbox.mapboxsdk.maps.MapboxMap;
import com.mapbox.mapboxsdk.style.layers.FillLayer;
import com.mapbox.mapboxsdk.style.layers.Layer;
import com.uam.wmi.findmytutor.model.Coordinate;
import com.uam.wmi.findmytutor.R;
import java.io.IOException;
import java.io.InputStream;
import static com.uam.wmi.findmytutor.utils.Consts.latitudeRange;
import static com.uam.wmi.findmytutor.utils.Consts.longtitudeRange;
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 {
@ -51,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) {
@ -69,7 +66,6 @@ public class MapUtils {
// read file to JSON
public static String loadJsonFromAsset(Context context, String filename) {
// Using this method to load in GeoJSON files from the assets folder.
try {
InputStream is = context.getAssets().open(filename);
int size = is.available();
@ -84,8 +80,32 @@ public class MapUtils {
}
}
public static Boolean checkIfCoordinateIsValid(Location coordinate){
return (!latitudeRange.contains(coordinate.getLatitude()) && !longtitudeRange.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,9 +60,19 @@ 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", "Available");
return getSharedPreferences(context).getString("status_entry", "Dostępny");
}
public static void storeStatus(Context context, String status) {
@ -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();
@ -144,7 +159,7 @@ public class PrefUtils {
}
public static String getLocale(Context context) {
return getSharedPreferences(context).getString("LOCALE", LocaleUtils.getCurrentLocale(context));
return getSharedPreferences(context).getString("LOCALE", LocaleUtils.getCurrentLocale());
}
public static Boolean isBackgroundLocationServiceRunning(Context context) {
@ -162,7 +177,7 @@ public class PrefUtils {
editor.putString("key_location_level","3");
editor.putString("location_mode", "manual");
editor.putString("approx_manual_loc", approximatedLocation);
editor.putBoolean("key_sharing_enabled", true);
/*editor.putBoolean("key_sharing_enabled", true);*/
editor.putLong("longitude_manual_location", Double.doubleToRawLongBits(latLng.getLongitude()));
editor.putLong("latitude_manual_location", Double.doubleToRawLongBits(latLng.getLatitude()));
editor.apply();
@ -188,5 +203,53 @@ public class PrefUtils {
public static String getCurrentManualLocation(Context context) {
return getSharedPreferences(context).getString("current_manual_location", null);
}
public static void putCurrentManualLocationName(Context context, String locationName) {
SharedPreferences.Editor editor = getSharedPreferences(context).edit();
editor.putString("current_manual_location_name", locationName);
editor.apply();
}
public static String getCurrentManualLocationName(Context context) {
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,44 @@
package com.uam.wmi.findmytutor.utils;
import android.content.Context;
import android.graphics.drawable.ColorDrawable;
import android.preference.Preference;
import android.util.AttributeSet;
import android.view.Gravity;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.Button;
import android.widget.ImageButton;
import android.widget.LinearLayout;
import android.widget.PopupWindow;
import android.widget.Toast;
import com.uam.wmi.findmytutor.R;
import static com.mapbox.mapboxsdk.Mapbox.getApplicationContext;
public class SharingInfoPopupButtonPreference extends Preference {
public SharingInfoPopupButtonPreference(Context context, AttributeSet attrs) {
super(context, attrs);
setWidgetLayoutResource(R.layout.preference_popup_info_button_widget);
}
@Override
protected View onCreateView(ViewGroup parent) {
View view = super.onCreateView(parent);
// LayoutInflater li = (LayoutInflater)getContext().getSystemService( Context.LAYOUT_INFLATER_SERVICE );
// View temp =li.inflate( R.layout.preference_button_widget, parent, false);
return view;
}
@Override
protected void onBindView(View view)
{
super.onBindView(view);
ImageButton button = view.findViewById(R.id.sharingTabInfoImageButton);
button.setOnClickListener(v-> {
InfoHelperUtils.infoPopUp(v,R.layout.info_popup_sharing_tab);
});
}
}

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

Binary file not shown.

After

Width:  |  Height:  |  Size: 381 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 447 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 660 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 830 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 259 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 306 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 447 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 595 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 447 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 595 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 830 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.1 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 660 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 830 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.2 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.7 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 830 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.1 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.7 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.3 KiB

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

@ -1,9 +1,9 @@
<vector xmlns:android="http://schemas.android.com/apk/res/android"
android:width="24dp"
android:height="24dp"
android:viewportHeight="24.0"
android:viewportWidth="24.0">
<path
android:fillColor="#FF000000"
android:pathData="M12,2C6.48,2 2,6.48 2,12s4.48,10 10,10 10,-4.48 10,-10S17.52,2 12,2zm1,15h-2v-6h2v6zm0,-8h-2V7h2v2z" />
android:width="24dp"
android:height="24dp"
android:viewportHeight="24.0"
android:viewportWidth="24.0">
<path
android:fillColor="#FF000000"
android:pathData="M12,2C6.48,2 2,6.48 2,12s4.48,10 10,10 10,-4.48 10,-10S17.52,2 12,2zm1,15h-2v-6h2v6zm0,-8h-2V7h2v2z" />
</vector>

View File

@ -0,0 +1,7 @@
<?xml version="1.0" encoding="UTF-8"?>
<shape xmlns:android="http://schemas.android.com/apk/res/android">
<solid android:color="#ffffff"/>
<stroke android:width="3dp" android:color="#b1bcbe" />
<corners android:radius="10dp"/>
<padding android:left="0dp" android:top="0dp" android:right="0dp" android:bottom="0dp" />
</shape>

View File

@ -0,0 +1,10 @@
<vector xmlns:android="http://schemas.android.com/apk/res/android"
android:width="24dp"
android:height="24dp"
android:viewportWidth="24.0"
android:viewportHeight="24.0"
android:tint="?attr/colorControlNormal">
<path
android:fillColor="@android:color/white"
android:pathData="M11,7h2v2h-2zM11,11h2v6h-2zM12,2C6.48,2 2,6.48 2,12s4.48,10 10,10 10,-4.48 10,-10S17.52,2 12,2zM12,20c-4.41,0 -8,-3.59 -8,-8s3.59,-8 8,-8 8,3.59 8,8 -3.59,8 -8,8z"/>
</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

@ -2,7 +2,6 @@
<android.support.constraint.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:mapbox="http://schemas.android.com/apk/res-auto"
xmlns:fab="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
@ -22,12 +21,13 @@
</com.mapbox.mapboxsdk.maps.MapView>
<LinearLayout
android:id="@+id/linearLayout2"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:gravity="bottom"
android:orientation="vertical"
tools:layout_editor_absoluteX="0dp"
tools:layout_editor_absoluteY="1dp">
tools:layout_editor_absoluteY="0dp">
<!-- Implementation of find my location button -->

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,85 +1,61 @@
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
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">
<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

@ -3,8 +3,8 @@
android:id="@android:id/text1"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:textAppearance="?android:attr/textAppearanceListItemSmall"
android:gravity="center_vertical"
android:textSize="16sp"
android:textSize="14sp"
android:paddingTop="2dp"
android:fontFamily="@font/lato_regular"
android:textColor="@color/mapboxWhite" />

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

@ -0,0 +1,77 @@
<?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"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginLeft="20dp"
android:layout_marginTop="20dp"
android:layout_weight="1"
android:text="@string/map_info_text_p1"
android:textColor="@color/half_black" />
<TextView
android:id="@+id/textViewP2"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginLeft="20dp"
android:layout_marginTop="20dp"
android:layout_weight="1"
android:text="@string/map_info_text_p2"
android:textColor="@color/half_black" />
<TextView
android:id="@+id/textViewP3"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginLeft="20dp"
android:layout_marginTop="20dp"
android:layout_weight="1"
android:text="@string/map_info_text_p3"
android:textColor="@color/half_black" />
<TextView
android:id="@+id/exactMarkerTextView"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginLeft="5dp"
android:drawableLeft="@drawable/exact_localization_marker"
android:drawablePadding="5dp"
android:layout_marginBottom="5dp"
android:gravity="center"
android:text="@string/map_info_text_marker_exact"
android:textColor="@color/half_black" />
<TextView
android:id="@+id/approximateTextView"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginLeft="5dp"
android:drawableLeft="@drawable/approximate_localization_marker"
android:drawablePadding="5dp"
android:layout_marginBottom="5dp"
android:gravity="center"
android:text="@string/map_info_text_marker_approximated"
android:textColor="@color/half_black" />
<TextView
android:id="@+id/manualMarkerTextView"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginLeft="5dp"
android:layout_marginBottom="5dp"
android:drawableLeft="@drawable/manual_localization_marker"
android:drawablePadding="0dp"
android:gravity="center"
android:text="@string/map_info_text_marker_manual"
android:textColor="@color/half_black" />
</LinearLayout>

View File

@ -0,0 +1,108 @@
<?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">
<TextView
android:id="@+id/textViewP1"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginTop="5dp"
android:layout_weight="1"
android:text="@string/info_icon_sharing_tab_p1"
android:textColor="@color/half_black" />
<TextView
android:id="@+id/textViewP2"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginTop="5dp"
android:layout_weight="1"
android:text="@string/info_icon_sharing_tab_p2"
android:textColor="@color/half_black"/>
<TextView
android:id="@+id/textViewP3"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginTop="5dp"
android:layout_weight="1"
android:text="@string/info_icon_sharing_tab_p3"
android:textColor="@color/half_black"/>
<TextView
android:id="@+id/textViewP3exactlvl"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginTop="5dp"
android:layout_weight="1"
android:text="@string/info_icon_sharing_tab_p3_level_exact"
android:textColor="@color/half_black"/>
<TextView
android:id="@+id/textViewP3approximatelvl"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginTop="5dp"
android:layout_weight="1"
android:text="@string/info_icon_sharing_tab_p3_level_approximate"
android:textColor="@color/half_black"/>
<TextView
android:id="@+id/textViewP3manuallvl"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginTop="5dp"
android:layout_weight="1"
android:text="@string/info_icon_sharing_tab_p3_level_manual"
android:textColor="@color/half_black"/>
<TextView
android:id="@+id/textViewP3presencelvl"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginTop="5dp"
android:layout_weight="1"
android:text="@string/info_icon_sharing_tab_p3_level_presence"
android:textColor="@color/half_black"/>
<TextView
android:id="@+id/textViewP4"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginTop="5dp"
android:layout_weight="1"
android:text="@string/info_icon_sharing_tab_p4"
android:textColor="@color/half_black"/>
<TextView
android:id="@+id/textViewP5"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginTop="5dp"
android:layout_weight="1"
android:text="@string/info_icon_sharing_tab_p5"
android:textColor="@color/half_black"/>
<TextView
android:id="@+id/textViewP6"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginTop="5dp"
android:layout_weight="1"
android:text="@string/info_icon_sharing_tab_p6"
android:textColor="@color/half_black"/>
<TextView
android:id="@+id/textViewP7"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginTop="5dp"
android:layout_weight="1"
android:text="@string/info_icon_sharing_tab_p7"
android:textColor="@color/half_black"/>
</LinearLayout>

View File

@ -0,0 +1,49 @@
<?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">
<TextView
android:id="@+id/textViewP1"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginLeft="5dp"
android:layout_marginTop="15dp"
android:layout_weight="1"
android:text="@string/info_icon_tutor_tab_p1"
android:textColor="@color/half_black"/>
<TextView
android:id="@+id/textViewP2"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginLeft="5dp"
android:layout_marginTop="15dp"
android:layout_weight="1"
android:text="@string/info_icon_tutor_tab_p2"
android:textColor="@color/half_black"/>
<TextView
android:id="@+id/textViewP3"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginLeft="5dp"
android:layout_marginTop="15dp"
android:layout_weight="1"
android:text="@string/info_icon_tutor_tab_p3"
android:textColor="@color/half_black"/>
<TextView
android:id="@+id/textViewP4"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginLeft="5dp"
android:layout_marginTop="15dp"
android:layout_marginBottom="15dp"
android:layout_weight="1"
android:text="@string/info_icon_tutor_tab_p4"
android:textColor="@color/half_black"/>
</LinearLayout>

View File

@ -0,0 +1,77 @@
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:orientation="vertical"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:padding="20dp"
android:background="@drawable/layout_bg">
<TextView
android:id="@+id/userListPopupInfoTextViewP1"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_weight="1"
android:text="@string/info_icon_userlist_tab_p1"
android:textColor="@color/half_black"/>
<TextView
android:id="@+id/userListPopupInfoTextViewP2"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_weight="1"
android:text="@string/info_icon_userlist_tab_p2"
android:textColor="@color/half_black"/>
<TextView
android:id="@+id/userListPopupInfoTextViewOnline"
android:gravity="center"
android:drawableLeft="@drawable/online_user"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:drawablePadding="5dp"
android:layout_weight="1"
android:text="@string/info_icon_userlist_tab_level_status_online"
android:textColor="@color/half_black"/>
<TextView
android:id="@+id/userListPopupInfoTextVieOffline"
android:gravity="center"
android:drawableLeft="@drawable/user_list_offline"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:drawablePadding="5dp"
android:layout_weight="1"
android:text="@string/info_icon_userlist_tab_level_status_offline"
android:textColor="@color/half_black"/>
<TextView
android:id="@+id/userListPopupInfoTextViewInactive"
android:gravity="center"
android:drawableLeft="@drawable/user_list_off"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:drawablePadding="5dp"
android:layout_weight="1"
android:text="@string/info_icon_userlist_tab_level_status_inactive"
android:textColor="@color/half_black"/>
<TextView
android:id="@+id/userListPopupInfoTextViewTip"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_weight="1"
android:text="@string/info_icon_userlist_tab_level_status_inactive_tip"
android:textColor="@color/half_black"/>
<TextView
android:id="@+id/userListPopupInfoTextViewSummary"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_weight="1"
android:layout_marginTop="10dp"
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

@ -7,7 +7,6 @@
<PreferenceCategory android:title="@string/settings_category_general">
<ListPreference
android:defaultValue="0"
android:dialogTitle="@string/settings_language"
android:entries="@array/language_entries"
android:entryValues="@array/language_values"
@ -15,5 +14,12 @@
android:summary="%s"
android:title="@string/title_language" />
<SwitchPreference
android:key="acra.enable"
android:title="@string/pref_title_acra"
android:summaryOn="@string/pref_acra_disabled"
android:summaryOff="@string/pref_acra_enabled"
android:defaultValue="true"/>
</PreferenceCategory>
</PreferenceScreen>

Some files were not shown because too many files have changed in this diff Show More