1
0

Compare commits

...

267 Commits

Author SHA1 Message Date
ff1e794820 Merge branch 'release/0.13.0' 2019-12-07 23:04:26 +01:00
ceba5f7fe8 Version 0.13.0 2019-12-07 23:04:17 +01:00
f570acbed6 Add FAQ link (#611) 2019-12-07 22:06:15 +01:00
2a7a472d90 Bump fragment-ktx from 1.2.0-rc02 to 1.2.0-rc03 (#610) 2019-12-07 16:07:36 +00:00
138fbe5bf5 Bump activity-ktx from 1.1.0-rc02 to 1.1.0-rc03 (#608) 2019-12-07 12:51:40 +00:00
ad99cc75eb Bump gradle from 3.5.2 to 3.5.3 (#609) 2019-12-07 12:51:24 +00:00
f6606e7a4f Bump coordinatorlayout from 1.1.0-rc01 to 1.1.0 (#607) 2019-12-07 12:51:09 +00:00
3690deef1e Bump mockito-android from 3.1.0 to 3.2.0 (#605) 2019-12-02 16:19:20 +00:00
cd1438587d Bump kotlin_version from 1.3.60 to 1.3.61 (#606) 2019-12-02 16:18:56 +00:00
8193a57227 Bump mockito-inline from 3.1.0 to 3.2.0 (#604) 2019-12-02 16:18:27 +00:00
8467f39ad9 Add russian language (#595) 2019-11-29 20:43:37 +01:00
0fc293f47a Bump assisted-inject-processor-dagger2 from 0.5.1 to 0.5.2 (#601) 2019-11-25 17:15:23 +00:00
9b063edb0b Bump rxjava from 2.2.14 to 2.2.15 (#603) 2019-11-25 16:48:56 +00:00
5d852eee87 Bump assisted-inject-annotations-dagger2 from 0.5.1 to 0.5.2 (#602) 2019-11-25 16:48:07 +00:00
54ab408135 Add error view showing on first loading in fragment view (#590) 2019-11-24 17:05:09 +01:00
41aa326f42 Add 0,00 grade modifier (#596) 2019-11-21 17:41:41 +01:00
24f605c71c Bump work_manager from 2.3.0-alpha03 to 2.3.0-beta01 (#600) 2019-11-21 11:00:11 +00:00
5c52dcc74f Bump room from 2.2.1 to 2.2.2 (#599) 2019-11-21 10:31:14 +00:00
667659fbe6 Bump core-ktx from 1.2.0-beta02 to 1.2.0-rc01 (#598) 2019-11-21 10:30:51 +00:00
d467bf096f Bump recyclerview from 1.1.0-rc01 to 1.1.0 (#597) 2019-11-21 10:28:54 +00:00
98d556bcd5 Bump kotlin_version from 1.3.50 to 1.3.60 (#594) 2019-11-18 10:57:50 +01:00
8c730be635 Bump google-services from 4.3.2 to 4.3.3 (#591) 2019-11-18 08:58:17 +00:00
377d24fbb4 Bump sonarqube-gradle-plugin from 2.8 to 2.8.0.1969 (#593) 2019-11-18 08:26:46 +00:00
bde810e031 Fix screens loading state (#589) 2019-11-17 01:07:43 +01:00
2f18d42c86 Update material design components (#587) 2019-11-10 16:45:53 +01:00
c708b0c20e Bump activity-ktx from 1.1.0-rc01 to 1.1.0-rc02 (#586) 2019-11-09 13:35:59 +00:00
ff8d55d4f8 Bump fragment-ktx from 1.2.0-rc01 to 1.2.0-rc02 (#585) 2019-11-09 13:08:02 +00:00
49bf911c84 Bump core-ktx from 1.2.0-beta01 to 1.2.0-beta02 (#584) 2019-11-09 13:07:27 +00:00
9e33ef419f Fix LuckyNumberWidget not showing ThemeDialog (#583) 2019-11-09 13:59:33 +01:00
40e95eac1e Add BaseDao interface (#581) 2019-11-06 23:52:14 +01:00
19e76a0b5d Bump rxjava from 2.2.13 to 2.2.14 (#580) 2019-11-04 19:23:50 +00:00
5feafe3907 Update gradle wrapper (#579) 2019-11-03 15:07:32 +01:00
b7206ed714 Add DatePicker to Timetable and Attendance modules. (#522) 2019-11-03 14:52:35 +01:00
38370d647d Add language change settings (#577) 2019-11-03 12:37:03 +01:00
323bc188b1 Bump assisted-inject-annotations-dagger2 from 0.5.0 to 0.5.1 (#576) 2019-11-01 20:20:09 +00:00
b17356591a Bump assisted-inject-processor-dagger2 from 0.5.0 to 0.5.1 (#575) 2019-11-01 19:50:28 +00:00
a02c444cf5 Merge tag '0.12.0' into develop
0.12.0
2019-10-29 00:25:17 +01:00
87a133beb9 Merge branch 'release/0.12.0' 2019-10-29 00:25:12 +01:00
1f4a208857 Version 0.12.0 2019-10-29 00:25:03 +01:00
a7c472989c Add support for edu.lublin.eu (#571) 2019-10-28 21:10:58 +01:00
747696e386 Bump firebase-core from 17.2.0 to 17.2.1 (#572) 2019-10-28 14:58:10 +00:00
a71a183160 Add school quick actions (#570) 2019-10-27 00:36:39 +02:00
125a010f03 Fix restoring state in exposed dropdown menu (#569) 2019-10-24 22:56:49 +02:00
5c5993cc2a Change FAB to extended FAB in messages (#536) 2019-10-24 18:45:05 +02:00
f234b71932 Bump dagger from 2.24 to 2.25.2 (#564) 2019-10-24 18:24:22 +02:00
497a3391d4 Bump fragment-ktx from 1.2.0-beta02 to 1.2.0-rc01 (#568) 2019-10-24 06:58:42 +00:00
a72c743c6f Bump work_manager from 2.3.0-alpha02 to 2.3.0-alpha03 (#563) 2019-10-24 06:37:24 +00:00
98fdfd001a Bump recyclerview from 1.1.0-beta05 to 1.1.0-rc01 (#566) 2019-10-24 06:17:11 +00:00
994b162ae3 Bump activity-ktx from 1.1.0-beta01 to 1.1.0-rc01 (#567) 2019-10-24 06:16:51 +00:00
90c60f399b Bump coordinatorlayout from 1.1.0-beta01 to 1.1.0-rc01 (#565) 2019-10-24 06:15:58 +00:00
b16b225a1a Bump room from 2.2.0 to 2.2.1 (#562) 2019-10-24 05:55:08 +00:00
7a4cf694ca Add school info (#557)
* Add db layer to school info

* Add base classes

* Add database migration

* Add base view

* Update icon

* Fix textviews height

* Handle error and empty results

* Improve school info look

* Add strings

* Fix action bar elevation in school fragment

* Add missing blank lines

* Reorganize strings

* Make field title first in order

* Make fields views selectable

* Rename SchoolInfo to School
2019-10-21 21:25:15 +02:00
1b492d50fe Bump aboutlibraries from 7.0.3 to 7.0.4 (#559) 2019-10-21 19:23:41 +00:00
d9b5e000f8 Bump gradle from 1.31.1 to 1.31.2 (#560) 2019-10-21 19:23:13 +00:00
7e30524876 Contact info after failed login (#556) 2019-10-20 19:10:32 +02:00
ce9b12eb93 Add system theme setting for Android 10 (#554) 2019-10-16 22:27:16 +02:00
b602657d55 Move default preferences values to separate file (#555) 2019-10-16 20:10:24 +02:00
360dfbcdb5 Update androidx dependencies (#553) 2019-10-15 19:15:28 +02:00
f466497970 Bump recyclerview from 1.1.0-beta04 to 1.1.0-beta05 (#551) 2019-10-11 21:56:19 +00:00
184a7ab200 Bump room from 2.2.0-rc01 to 2.2.0 (#552) 2019-10-11 21:55:28 +00:00
2e5ef7dfa2 Merge tag '0.11.0' into develop
Version 0.11.0
2019-10-07 00:11:59 +02:00
8f617f4ca1 Merge branch 'release/0.11.0' 2019-10-07 00:11:52 +02:00
fe5f96a394 Version 0.11.0 2019-10-07 00:11:33 +02:00
cb9c35d772 Add navigate up to login view (#547) 2019-10-06 22:43:16 +02:00
7cf7977cc6 Bump gson from 2.8.5 to 2.8.6 (#549) 2019-10-06 20:15:53 +00:00
1de747fa35 Add mark as read button enable logic (#534) 2019-10-06 21:25:24 +02:00
93750829d7 Fix duplicate percentage in attendance summary (#548) 2019-10-06 18:21:56 +02:00
798688e7dd Fix multidex in debug variant (#545) 2019-10-05 22:32:55 +02:00
6ab9c1d737 Update mockito to last version from maven central (#546) 2019-10-03 22:47:49 +02:00
b074ce99b7 Bump sonarqube-gradle-plugin from 2.7.1 to 2.8 (#543) 2019-10-03 20:21:43 +00:00
b03fd86be5 Bump gradle from 3.5.0 to 3.5.1 (#542) 2019-10-03 20:08:32 +00:00
3de2f5ff88 Bump githook from 1.1.0 to 1.2.0 (#539) 2019-10-03 19:54:16 +00:00
35adf83154 Bump rxjava from 2.2.12 to 2.2.13 (#538) 2019-10-03 19:43:12 +00:00
0162c8bbee Add better timetable changes display (#513) 2019-10-03 21:13:01 +02:00
736d570f26 Change timetable widget date format (#530) 2019-10-03 15:29:33 +02:00
5b0901e311 Clear Semesters table (#535) 2019-10-03 14:00:07 +02:00
f9474af39e Add points to class grades statistics (#512) 2019-10-03 00:46:08 +02:00
d411d86355 Add click to copy function (#531) 2019-10-02 23:42:38 +02:00
a50c6707cb Update readme badges (#532) 2019-10-01 22:19:28 +02:00
6991c68d3a Bump mockito-core from 3.0.8 to 3.0.11 (#525) 2019-09-30 10:31:07 +00:00
8b1e6f7bd6 Bump play-publisher from 2.4.1 to 2.4.2 (#528) 2019-09-30 10:16:38 +00:00
943fd9c622 Bump logging-interceptor from 3.12.5 to 3.12.6 (#529) 2019-09-30 10:09:57 +00:00
838e2781c0 Bump mockito-inline from 3.0.8 to 3.0.11 (#526) 2019-09-30 10:05:54 +00:00
66cfd7b52c Bump mockito-android from 3.0.8 to 3.0.11 (#527) 2019-09-30 10:04:50 +00:00
a45bc0eef6 Add teachers (#489) 2019-09-29 18:09:53 +02:00
ed7996299e Improve date navigation (#519) 2019-09-28 20:37:14 +02:00
d4b73fb73e Add dark theme for app widgets (#509) 2019-09-25 22:44:55 +02:00
d6ece78eff Bump mockito-android from 3.0.7 to 3.0.8 (#518) 2019-09-22 11:03:41 +00:00
2f44f3c4ba Bump gradle from 1.31.0 to 1.31.1 (#517) 2019-09-22 10:55:34 +00:00
23b49e4b8c Bump mockito-inline from 3.0.7 to 3.0.8 (#516) 2019-09-22 10:50:21 +00:00
5d33cefe1d Bump mockito-core from 3.0.7 to 3.0.8 (#515) 2019-09-22 10:49:39 +00:00
6089df9462 Fix wrong index in form host value (#507) 2019-09-16 23:27:58 +02:00
3ee98e2bd0 Fix privacy link position on small screens (#508) 2019-09-16 23:13:46 +02:00
53a5d02051 Fix attendance_excused_lateness pl typo (#511) 2019-09-16 23:06:37 +02:00
e332fd9cf9 Bump logging-interceptor from 3.12.4 to 3.12.5 (#510) 2019-09-16 08:29:32 +00:00
7232938c12 Update API 28 to API 29 (#506) 2019-09-12 16:36:32 +02:00
fd02f2253b Merge tag '0.10.2' into develop
Version 0.10.2
2019-09-10 13:01:52 +02:00
12046ef0a0 Merge branch 'release/0.10.2' 2019-09-10 13:01:38 +02:00
dfc84b4208 Version 0.10.2 2019-09-10 12:58:27 +02:00
f5f11d5130 Fix login in symbol view (#493) 2019-09-10 12:25:08 +02:00
81ce328abd Bump recyclerview from 1.1.0-beta03 to 1.1.0-beta04 (#504) 2019-09-09 14:05:04 +00:00
867951136a Bump gradle-play-publisher from cdaeb61 to 2.4.0 (#501) 2019-09-09 13:43:55 +00:00
8b41ab27bd Bump mockito-core from 3.0.6 to 3.0.7 (#502) 2019-09-09 09:25:52 +00:00
e542ef003c Bump mockito-android from 3.0.6 to 3.0.7 (#503) 2019-09-09 08:54:03 +00:00
a5f212e6be Bump room from 2.2.0-beta01 to 2.2.0-rc01 (#499) 2019-09-09 08:39:39 +00:00
385a320536 Bump google-services from 4.3.1 to 4.3.2 (#498) 2019-09-09 08:25:51 +00:00
e65000ec2c Bump mockito-inline from 3.0.6 to 3.0.7 (#497) 2019-09-09 08:25:29 +00:00
c87de7b3c2 Bump logging-interceptor from 3.12.3 to 3.12.4 (#496) 2019-09-09 08:23:22 +00:00
bb6023709f Fix grade details header unread info (#494) 2019-09-08 15:10:29 +02:00
e998e54d3e Merge tag '0.10.1' into develop
Version 0.10.1
2019-09-07 02:25:22 +02:00
e269886eae Merge branch 'release/0.10.1' 2019-09-07 02:25:12 +02:00
dabb83c522 Version 0.10.1 2019-09-07 02:23:44 +02:00
6350b72e23 Fix account icon color in widgets (#488) 2019-09-06 18:23:51 +02:00
e4100d940a Fix crashing tab layout on prelolipop (#492) 2019-09-06 13:55:26 +02:00
6575674169 Fix about_feedback_summary typo (#487) 2019-09-05 18:57:37 +02:00
a13aad984c Merge tag '0.10.0' into develop
Version 0.10.0
2019-09-04 22:59:40 +02:00
750fa9a76d Merge branch 'release/0.10.0' 2019-09-04 22:59:26 +02:00
d0ad4d9364 Version 0.10.0 2019-09-04 22:58:53 +02:00
4e0f41dcb2 Change marking current student in accounts dialog (#486) 2019-09-04 21:19:05 +02:00
c3bb489851 Mitigate disappearing teachers in timetable (#485) 2019-09-04 20:45:34 +02:00
e64e6676f3 Fix status bar color on xiaomi (#484) 2019-09-04 13:52:55 +02:00
108440b1ca Reduce grade color saturations (#482) 2019-09-03 22:43:17 +02:00
d54f5ed1aa Bump aboutlibraries from 7.0.2 to 7.0.3 (#480) 2019-09-03 22:39:05 +02:00
0aac6459f3 Fix elevation overlay on pre-lolipop (#475) 2019-09-02 12:56:13 +02:00
bb9ea7eda1 Fix spaming NoCurentStudentException (#476) 2019-09-02 12:38:09 +02:00
455b04f183 Fix empty hosts list after activity recreating (#477) 2019-09-02 10:05:42 +02:00
39fb4f5def Update dependencies (#474) 2019-09-01 13:24:21 +02:00
c60428e29b Add outline icons (#328) 2019-08-30 12:00:34 +02:00
5413ecabb4 Bump firebase-core from 17.1.0 to 17.2.0 (#473) 2019-08-28 17:03:51 +00:00
c6d9dfa0c9 Change app theme (#330) 2019-08-26 20:54:20 +02:00
b0033af048 Bump rxjava from 2.2.11 to 2.2.12 (#472) 2019-08-26 13:11:35 +00:00
405d37e822 Bump play-publisher from 2.2.1 to 2.3.0 (#446) 2019-08-23 18:57:45 +00:00
0d514b7dc9 Bump gradle from 3.4.2 to 3.5.0 (#469) 2019-08-23 18:37:05 +00:00
c3596aa45c Bump reactivenetwork-rx2 from 3.0.4 to 3.0.6 (#468) 2019-08-23 11:50:18 +00:00
d34bdb2ce3 Bump google-services from 4.3.0 to 4.3.1 (#470) 2019-08-23 11:49:51 +00:00
c91870cc04 Bump kotlin_version from 1.3.41 to 1.3.50 (#471) 2019-08-23 11:35:31 +00:00
2f6862967e Bump mockito-core from 3.0.5 to 3.0.6 (#466) 2019-08-20 10:24:11 +00:00
7525395665 Bump mockito-inline from 3.0.5 to 3.0.6 (#465) 2019-08-20 10:07:52 +00:00
657e2b280e Bump mockito-android from 3.0.5 to 3.0.6 (#467) 2019-08-20 10:06:40 +00:00
4ea9be582f Bump mockito-core from 3.0.4 to 3.0.5 (#464) 2019-08-19 09:16:34 +00:00
3dcc8247bf Bump mockito-inline from 3.0.4 to 3.0.5 (#463) 2019-08-19 08:50:35 +00:00
c45b7c04b9 Bump mockito-android from 3.0.4 to 3.0.5 (#462) 2019-08-19 08:42:55 +00:00
33d6ae8afc Bump firebase-core from 17.0.1 to 17.1.0 (#461) 2019-08-19 08:42:26 +00:00
6871606bef Bump work_manager from 2.1.0 to 2.2.0 (#460) 2019-08-17 18:31:53 +02:00
6e266acec9 Merge tag '0.9.4' into develop
0.9.4
2019-08-12 23:18:04 +02:00
ba84f2be6e Merge branch 'release/0.9.4' 2019-08-12 23:17:57 +02:00
db7b7dbadf Version 0.9.4 2019-08-12 23:17:02 +02:00
6bd07d2651 Fix day/week navigation on holiday (#459) 2019-08-12 12:17:39 +02:00
070fba734c Bump assisted-inject-annotations-dagger2 from 0.4.0 to 0.5.0 (#458) 2019-08-09 12:04:05 +00:00
72ef366829 Bump assisted-inject-processor-dagger2 from 0.4.0 to 0.5.0 (#457) 2019-08-09 11:28:33 +00:00
4adfb268a3 Update gitignore (#455) 2019-08-08 17:40:23 +02:00
bf0ea1b012 Bump reactivenetwork-rx2 from 3.0.3 to 3.0.4 (#456) 2019-08-07 17:09:26 +00:00
1267a39e32 Bump rxjava from 2.2.10 to 2.2.11 (#454) 2019-08-02 11:01:28 +00:00
462b917832 Bump mockito-core from 3.0.2 to 3.0.4 (#451) 2019-07-29 07:34:21 +00:00
c5b16bb0d0 Bump mockito-android from 3.0.2 to 3.0.4 (#450) 2019-07-29 07:04:29 +00:00
91268dcc67 Bump mockito-inline from 3.0.2 to 3.0.4 (#452) 2019-07-29 07:02:15 +00:00
13f9981be6 Bump dagger from 2.23.2 to 2.24 (#449) 2019-07-28 12:41:29 +02:00
f9b3bd7b3a Bump gradle from 1.30.0 to 1.31.0 (#448) 2019-07-26 08:14:13 +00:00
39916c2796 Update README (#447) 2019-07-17 13:41:47 +02:00
03f5ddaf0d Bump work_manager from 2.0.1 to 2.1.0 (#441) 2019-07-12 12:50:56 +00:00
ea4f55c06d Bump gradle from 1.29.0 to 1.30.0 (#443) 2019-07-12 08:48:33 +00:00
5b0232f77e Bump mockito-inline from 3.0.1 to 3.0.2 (#442) 2019-07-12 08:47:36 +00:00
0b68091e55 Bump mockito-android from 3.0.1 to 3.0.2 (#444) 2019-07-12 08:47:11 +00:00
7136c9282e Bump mockito-core from 3.0.1 to 3.0.2 (#445) 2019-07-12 08:46:52 +00:00
09303153a5 Bump firebase-core from 17.0.0 to 17.0.1 (#440) 2019-07-12 08:44:52 +00:00
bdf0fba95b Bump gradle from 3.4.1 to 3.4.2 (#438) 2019-07-10 07:22:59 +00:00
86f24e5821 Group dependencies versions in variables (#437) 2019-07-09 13:33:36 +02:00
35f094b983 Bump kotlin_version from 1.3.40 to 1.3.41 (#433) 2019-07-09 07:45:20 +00:00
12cf1e0b66 Bump mockito-inline from 2.28.2 to 3.0.1 (#434) 2019-07-09 07:40:24 +00:00
68b37fc5dd Bump mockito-android from 2.28.2 to 3.0.1 (#435) 2019-07-09 07:22:24 +00:00
ba5bad042a Bump mockito-core from 2.28.2 to 3.0.1 (#436) 2019-07-09 07:21:54 +00:00
c5323ee811 Bump google-services from 4.2.0 to 4.3.0 (#432) 2019-06-28 18:29:30 +00:00
df9c685217 Bump frag-nav from 3.2.0 to 3.3.0 (#430) 2019-06-26 11:44:23 +00:00
73fa21d45f Bump firebase-core from 16.0.9 to 17.0.0 (#423) 2019-06-21 14:06:24 +00:00
344fa1bbd7 Increase min SDK to 16 (#429) 2019-06-21 14:54:10 +02:00
01318c8c29 Bump rxjava from 2.2.9 to 2.2.10 (#428) 2019-06-21 10:08:49 +00:00
851486df28 Bump dagger-android-support from 2.23.1 to 2.23.2 (#424) 2019-06-20 22:00:35 +00:00
d8b3c5d9d6 Bump dagger-android-processor from 2.23.1 to 2.23.2 (#425) 2019-06-20 21:43:05 +00:00
2883b21ddf Bump dagger-compiler from 2.23.1 to 2.23.2 (#426) 2019-06-20 21:22:57 +00:00
4956cf3988 Bump kotlin_version from 1.3.31 to 1.3.40 (#427) 2019-06-20 21:17:57 +00:00
bdbcec786a Merge tag '0.9.3' into develop
0.9.3
2019-06-15 01:14:04 +02:00
c40bbf2398 Merge branch 'release/0.9.3' 2019-06-15 01:13:50 +02:00
08ecbb5341 Version 0.9.3 2019-06-15 01:13:36 +02:00
e38e458386 Fix crash on login when error message is null (#420) 2019-06-15 00:51:54 +02:00
14674b7778 Bump room-testing from 2.1.0-rc01 to 2.1.0 (#417) 2019-06-13 22:33:12 +00:00
c6f0588165 Bump room-compiler from 2.1.0-rc01 to 2.1.0 (#415) 2019-06-13 22:12:23 +00:00
7591af0de1 Bump room-rxjava2 from 2.1.0-rc01 to 2.1.0 (#411) 2019-06-13 21:52:32 +00:00
cbfed09b52 Bump room-runtime from 2.1.0-rc01 to 2.1.0 (#419) 2019-06-13 21:29:47 +00:00
5c185c5eca Merge branch 'release/0.9.2' 2019-06-08 11:38:42 +02:00
4a026e4a70 Merge tag '0.9.2' into develop
0.9.2 0.9.2
2019-06-08 11:38:42 +02:00
0bccbc6011 Version 0.9.2 2019-06-08 11:38:06 +02:00
ed6a0f8cd0 Add StackOverflowError to RxJava's error handler (#408) 2019-06-07 21:38:53 +02:00
58d5e4da0e Fix showing empty view in mobile device view (#407) 2019-06-07 19:03:26 +02:00
ba6fb1a4b9 Fix update of grades in GradeDetailsFragment (#406) 2019-06-07 14:46:11 +02:00
b6b862d4c3 Organize AndroidX libraries (#404) 2019-06-07 14:12:52 +02:00
9b044a19fe Fix typo in service interval (#405) 2019-06-06 22:47:45 +02:00
7485cb2a39 Fix change of worker specs after app update (#402) 2019-06-06 22:32:43 +02:00
75122d0dcd Fix crash TabLayout on Android 4.x in new version of material components (#403) 2019-06-06 19:16:00 +02:00
39af56484b Bump threetenabp from 1.2.0 to 1.2.1 (#401) 2019-06-04 11:23:50 +00:00
05f7e1d115 Merge tag '0.9.1' into develop
Version 0.9.1
2019-06-04 02:44:04 +02:00
9cd5377438 Merge branch 'release/0.9.1' 2019-06-04 02:43:54 +02:00
7a61b233f0 Version 0.9.1 2019-06-04 02:43:50 +02:00
83dbd9874e Add option to force calc average by app (#400) 2019-06-04 02:27:15 +02:00
1d9a49d552 Add githook plugin (#398) 2019-06-04 01:53:20 +02:00
6175081b88 Fix tab layout crash on prelolipop (#399) 2019-06-03 22:47:35 +02:00
116e551186 Merge tag '0.9.0' into develop
0.9.0 0.9.0
2019-06-03 18:15:42 +02:00
713500d892 Merge branch 'release/0.9.0' 2019-06-03 18:15:41 +02:00
dfdbe374c2 Version 0.9.0 2019-06-03 18:15:11 +02:00
b1e3bab5e7 Add F-Droid flavor (#349) 2019-06-03 14:12:48 +02:00
0b2ef367da Change timeout string (#397) 2019-06-03 13:15:21 +02:00
28f27db2b5 Add mobile access managment (#344) 2019-06-03 00:43:54 +02:00
5c70cd8b8c Add session expired dialog after password change (#389) 2019-05-31 15:12:10 +02:00
0f75ff3206 Show grades average from register if exist instead of calculating (#374) 2019-05-31 14:40:53 +02:00
383cab4dae Fix only wifi setting (#394) 2019-05-31 13:46:53 +02:00
e1b0db76c2 Bump material from 1.1.0-alpha06 to 1.1.0-alpha07 (#393) 2019-05-31 11:46:29 +02:00
f10684097c Bump dagger-compiler from 2.23 to 2.23.1 (#391) 2019-05-31 02:02:09 +00:00
35d4342bec Bump dagger-android-processor from 2.23 to 2.23.1 (#392) 2019-05-31 01:42:40 +00:00
068aee215a Bump dagger-android-support from 2.23 to 2.23.1 (#390) 2019-05-31 01:19:26 +00:00
033074c66b Bump room-testing from 2.1.0-beta01 to 2.1.0-rc01 (#377) 2019-05-30 16:46:54 +02:00
0de534cb66 Bump room-rxjava2 from 2.1.0-beta01 to 2.1.0-rc01 (#385) 2019-05-30 16:46:28 +02:00
26e4619dde Bump room-runtime from 2.1.0-beta01 to 2.1.0-rc01 (#388) 2019-05-30 14:06:06 +00:00
cf08d1ff24 Bump mockito-core from 2.28.1 to 2.28.2 (#387) 2019-05-30 13:58:42 +00:00
96c400a0bd Bump runner from 1.1.1 to 1.2.0 (#386) 2019-05-30 13:50:28 +00:00
e238f65dde Bump rxjava from 2.2.8 to 2.2.9 (#381) 2019-05-30 15:22:15 +02:00
ba7966125b Bump dagger-compiler from 2.22.1 to 2.23 (#380) 2019-05-30 12:01:15 +00:00
1536208e45 Bump core from 1.1.0 to 1.2.0 (#383) 2019-05-30 11:46:56 +00:00
24cc07264a Bump dagger-android-support from 2.22.1 to 2.23 (#384) 2019-05-30 11:31:22 +00:00
1ad5232520 Bump mockito-inline from 2.28.1 to 2.28.2 (#382) 2019-05-30 11:29:13 +00:00
07f3333029 Bump mockito-android from 2.28.1 to 2.28.2 (#379) 2019-05-30 11:12:44 +00:00
214afb82a6 Bump junit from 1.1.0 to 1.1.1 (#378) 2019-05-30 11:05:05 +00:00
7a69710261 Bump dagger-android-processor from 2.22.1 to 2.23 (#376) 2019-05-30 10:54:26 +00:00
64d3afbdb3 Bump room-compiler from 2.1.0-beta01 to 2.1.0-rc01 (#375) 2019-05-30 10:53:35 +00:00
387e46f72d Bump mockito-inline from 2.27.5 to 2.28.1 (#372) 2019-05-29 00:16:10 +00:00
89acc2f384 Bump mockito-android from 2.27.5 to 2.28.1 (#373) 2019-05-28 23:59:19 +00:00
4ef1439878 Bump mockito-core from 2.27.2 to 2.28.1 (#371) 2019-05-29 01:57:19 +02:00
6efd170e03 Bump mockito-inline from 2.27.0 to 2.27.5 (#367) 2019-05-28 14:57:39 +00:00
82cd39329a Bump mockito-android from 2.27.0 to 2.27.5 (#354) 2019-05-28 14:22:24 +00:00
b38e0d04e7 Bump threetenbp from 1.3.8 to 1.4.0 (#366) 2019-05-28 14:41:48 +02:00
90b2ffe250 Bump logging-interceptor from 3.12.1 to 3.12.3 (#369)
Bumps logging-interceptor from 3.12.1 to 3.12.3.
2019-05-28 14:41:27 +02:00
33951dff54 Bump crashlytics from 2.9.9 to 2.10.1 (#365) 2019-05-28 11:30:42 +00:00
9ced00c4d7 Bump room-runtime from 2.1.0-alpha07 to 2.1.0-beta01 (#364) 2019-05-28 11:06:56 +00:00
2ac1638911 Bump room-testing from 2.1.0-alpha07 to 2.1.0-beta01 (#363) 2019-05-28 10:48:37 +00:00
463a7e2744 Bump gradle from 1.28.1 to 1.29.0 (#355)
Bumps gradle from 1.28.1 to 1.29.0.
2019-05-28 02:24:36 +02:00
d14382f3b4 Bump firebase-core from 16.0.8 to 16.0.9 (#358)
Bumps firebase-core from 16.0.8 to 16.0.9.
2019-05-28 00:58:09 +02:00
efa0b19cc1 Bump room-rxjava2 from 2.1.0-alpha07 to 2.1.0-beta01 (#357)
Bumps room-rxjava2 from 2.1.0-alpha07 to 2.1.0-beta01.
2019-05-28 00:39:12 +02:00
7cb893a254 Bump play-publisher from 2.2.0 to 2.2.1 (#356)
Bumps play-publisher from 2.2.0 to 2.2.1.
2019-05-28 00:37:06 +02:00
f7371f7b73 Bump room-compiler from 2.1.0-alpha07 to 2.1.0-beta01 (#350)
Bumps room-compiler from 2.1.0-alpha07 to 2.1.0-beta01.
2019-05-27 23:04:12 +02:00
9c626ad517 Bump reactivenetwork-rx2 from 3.0.2 to 3.0.3 (#351)
Bumps [reactivenetwork-rx2](https://github.com/pwittchen/ReactiveNetwork) from 3.0.2 to 3.0.3.
- [Release notes](https://github.com/pwittchen/ReactiveNetwork/releases)
- [Changelog](https://github.com/pwittchen/ReactiveNetwork/blob/RxJava2.x/CHANGELOG.md)
- [Commits](https://github.com/pwittchen/ReactiveNetwork/commits)
2019-05-27 22:58:17 +02:00
9c4c6b0192 Bump material from 1.1.0-alpha05 to 1.1.0-alpha06 (#353)
Bumps [material](https://github.com/material-components/material-components-android) from 1.1.0-alpha05 to 1.1.0-alpha06.
- [Release notes](https://github.com/material-components/material-components-android/releases)
- [Commits](https://github.com/material-components/material-components-android/compare/1.1.0-alpha05...1.1.0-alpha06)
2019-05-27 22:49:16 +02:00
8efc4d750d Bump sonarqube-gradle-plugin from 2.7 to 2.7.1 (#352)
Bumps sonarqube-gradle-plugin from 2.7 to 2.7.1.
2019-05-27 22:41:16 +02:00
e4a6caa13e Version 0.8.4 2019-05-27 18:13:20 +02:00
209e75160a Fix network constraint in background sync (#348) 2019-05-25 14:34:17 +02:00
153e026a8d Version 0.8.3 2019-05-20 00:21:30 +02:00
8731c2e1f2 Change help text when entering the symbol to a more precise one (#345) 2019-05-19 22:47:57 +02:00
0977282a4b Fix no current student in services after logout all accounts (#342) 2019-05-18 23:42:47 +02:00
667c4b6af7 Fix empty maybe when loading message content (#343) 2019-05-18 23:32:37 +02:00
1f5088cfc9 Don't copy teacher from previous lesson to completed (#341) 2019-05-18 13:03:38 +02:00
bf6b857a3e Fix null returns in widgets (#340) 2019-05-18 00:22:07 +02:00
80cb94c434 Version 0.8.2 2019-05-15 19:26:25 +02:00
0cb4eda32b Fix crash on reselecting fragment (#339) 2019-05-15 15:11:28 +02:00
d169f964f2 Fix crash when no webview activity (#338) 2019-05-14 11:45:27 +02:00
103ab95c80 Fix not attached fragment (#337)
* Add condition for error dialog
* Add safe call of forEach in LuckyNumberWidgetProvider
2019-05-09 22:06:11 +02:00
a191f03cdf Version 0.8.1 2019-04-30 23:56:22 +02:00
63404b8576 Fix entity list comparing (#335) 2019-04-30 19:04:05 +02:00
1b7760ff88 Fix dark theme background with custom theme engine (#334) 2019-04-30 17:45:37 +02:00
24f58835e7 Fix menu view initialization and restoration (#333) 2019-04-30 17:28:09 +02:00
b032c459d1 Fix theme on release build (#332) 2019-04-30 11:16:23 +02:00
522 changed files with 18820 additions and 3672 deletions

View File

@ -7,7 +7,7 @@ references:
container_config: &container_config
docker:
- image: circleci/android:api-28
- image: circleci/android@sha256:5cdc8626cc6f13efe5ed982cdcdb432b0472f8740fed8743a6461e025ad6cdfc
working_directory: *workspace_root
environment:
environment:
@ -35,7 +35,7 @@ jobs:
command: ./gradlew dependencies --no-daemon --stacktrace --console=plain -PdisablePreDex || true
- run:
name: Initial build
command: ./gradlew build -x test -x lint -x fabricGenerateResourcesRelease -x packageRelease --no-daemon --stacktrace --console=plain -PdisablePreDex
command: ./gradlew build -x test -x lint -x fabricGenerateResourcesFdroidRelease -x fabricGenerateResourcesPlayRelease -x packageRelease --no-daemon --stacktrace --console=plain -PdisablePreDex
- run:
name: Run FOSSA
command: fossa --no-ansi || true
@ -56,7 +56,7 @@ jobs:
<<: *general_cache_key
- run:
name: Run lint
command: ./gradlew lint -x fabricGenerateResourcesRelease --no-daemon --stacktrace --console=plain -PdisablePreDex
command: ./gradlew lint -x fabricGenerateResourcesFdroidRelease -x fabricGenerateResourcesPlayRelease --no-daemon --stacktrace --console=plain -PdisablePreDex
- store_artifacts:
path: ./app/build/reports/
destination: lint_reports/app/
@ -75,7 +75,7 @@ jobs:
<<: *general_cache_key
- run:
name: Run app tests
command: ./gradlew :app:test :app:jacocoTestReport -x fabricGenerateResourcesRelease --no-daemon --stacktrace --console=plain -PdisablePreDex
command: ./gradlew :app:test :app:jacocoTestReport -x fabricGenerateResourcesFdroidRelease -x fabricGenerateResourcesPlayRelease --no-daemon --stacktrace --console=plain -PdisablePreDex
- run:
name: Upload unit code coverage to codecov
command: bash <(curl -s https://codecov.io/bash) -F app
@ -93,9 +93,12 @@ jobs:
<<: *container_config
steps:
- *attach_workspace
- run:
name: Accept licenses
command: yes | sdkmanager --licenses && yes | sdkmanager --update
- run:
name: Setup emulator
command: sdkmanager "system-images;android-19;default;armeabi-v7a" && echo "no" | avdmanager create avd -n test -k "system-images;android-19;default;armeabi-v7a"
command: sdkmanager "system-images;android-22;default;armeabi-v7a" && echo "no" | avdmanager create avd -n test -k "system-images;android-22;default;armeabi-v7a"
- run:
name: Launch emulator
command: export LD_LIBRARY_PATH=${ANDROID_HOME}/emulator/lib64:${ANDROID_HOME}/emulator/lib64/qt/lib && emulator64-arm -avd test -noaudio -no-boot-anim -no-window -accel on
@ -113,7 +116,7 @@ jobs:
adb shell input keyevent 82
- run:
name: Run instrumented tests
command: ./gradlew clean createDebugCoverageReport jacocoTestReport --no-daemon --stacktrace --console=plain -PdisablePreDex
command: ./gradlew clean createFdroidDebugCoverageReport jacocoTestReport --no-daemon --stacktrace --console=plain -PdisablePreDex
- run:
name: Collect logs from emulator
command: adb logcat -d > ./app/build/reports/logcat_emulator.txt
@ -159,7 +162,7 @@ jobs:
openssl aes-256-cbc -d -in ./app/upload-key-encrypted.jks -k $ENCRYPT_KEY >> ./app/upload-key.jks
- run:
name: Publish release
command: ./gradlew publish --no-daemon --stacktrace --console=plain -PenableCrashlytics -PdisablePreDex
command: ./gradlew publishPlayRelease --no-daemon --stacktrace --console=plain -PenableCrashlytics -PdisablePreDex
workflows:
version: 2

114
.gitignore vendored
View File

@ -1,39 +1,90 @@
/captures
.externalNativeBuild
## https://gist.github.com/iainconnor/8605514
# Created by https://www.gitignore.io
# Built application files
/build
/*/build/
*.apk
*.ap_
*.aab
# Crashlytics configuations
com_crashlytics_export_strings.xml
# Files for the ART/Dalvik VM
*.dex
# Java class files
*.class
# Generated files
bin/
gen/
out/
# Gradle files
.gradle/
build/
# Local configuration file (sdk path, etc)
local.properties
# Gradle generated files
.gradle/
# Proguard folder generated by Eclipse
proguard/
# Signing files
.signing/
# Log Files
*.log
# User-specific configurations
.idea/copyright/profiles_settings.xml
# Android Studio Navigation editor temp files
.navigation/
# Android Studio captures folder
captures/
# IntelliJ configurations
*.iml
.idea/workspace.xml
.idea/tasks.xml
.idea/gradle.xml
.idea/assetWizardSettings.xml
.idea/dictionaries
.idea/libraries
.idea/caches
.idea/modules.xml
.idea/navEditor.xml
.idea/caches/
.idea/libraries/
.idea/inspectionProfiles/
.idea/shelf/
.idea/.name
.idea/compiler.xml
.idea/copyright/profiles_settings.xml
.idea/encodings.xml
.idea/misc.xml
.idea/modules.xml
.idea/scopes/scope_settings.xml
.idea/tasks.xml
.idea/vcs.xml
.idea/workspace.xml
.idea/caches/
*.iml
.idea/jsLibraryMappings.xml
.idea/datasources.xml
.idea/dataSources.ids
.idea/sqlDataSources.xml
.idea/dynamic.xml
.idea/uiDesigner.xml
.idea/runConfigurations.xml
# Keystore files
*.jks
*.keystore
*.p12
# External native build folder generated in Android Studio 2.2 and later
.externalNativeBuild
# Version control
vcs.xml
# lint
lint/intermediates/
lint/generated/
lint/outputs/
lint/tmp/
lint/reports/
### Android Patch ###
gen-external-apklibs
output.json
# OS-specific files
.DS_Store
@ -43,8 +94,21 @@ local.properties
.Trashes
ehthumbs.db
Thumbs.db
.idea/caches/
app/key.p12
app/upload-key.jks
*.log
.idea/assetWizardSettings.xml
# Legacy Eclipse project files
.classpath
.project
.cproject
.settings/
# Mobile Tools for Java (J2ME)
.mtj.tmp/
# Package Files #
*.war
*.ear
### AndroidStudio Patch ###
!/gradle/wrapper/gradle-wrapper.jar
.idea/jarRepositories.xml

View File

@ -12,7 +12,7 @@ build:
script:
- ./gradlew --no-daemon --stacktrace dependencies || true
- ./gradlew --no-daemon --stacktrace assembleDebug
- mv app/build/outputs/apk/debug/app-debug.apk .
- mv app/build/outputs/apk/fdroid/debug/app-fdroid-debug.apk .
artifacts:
name: "${CI_PROJECT_NAME}_${CI_BUILD_REF_NAME}-${CI_BUILD_ID}"
paths:
@ -26,7 +26,7 @@ tests:
- .gradle
policy: pull
script:
- ./gradlew --no-daemon --stacktrace -x fabricGenerateResourcesRelease test
- ./gradlew --no-daemon --stacktrace -x fabricGenerateResourcesFdroidRelease -x fabricGenerateResourcesPlayRelease test
artifacts:
paths:
- app/build/reports/tests
@ -39,7 +39,7 @@ lint:
- .gradle
policy: pull
script:
- ./gradlew --no-daemon --stacktrace -x fabricGenerateResourcesRelease lint
- ./gradlew --no-daemon --stacktrace -x fabricGenerateResourcesFdroidRelease -x fabricGenerateResourcesPlayRelease lint
artifacts:
paths:
- app/build/reports

View File

@ -2,7 +2,7 @@
<code_scheme name="Project" version="173">
<option name="LINE_SEPARATOR" value="&#10;" />
<AndroidXmlCodeStyleSettings>
<option name="USE_CUSTOM_SETTINGS" value="true" />
<option name="ARRANGEMENT_SETTINGS_MIGRATED_TO_191" value="true" />
</AndroidXmlCodeStyleSettings>
<JetCodeStyleSettings>
<option name="PACKAGES_TO_USE_STAR_IMPORTS">
@ -21,13 +21,10 @@
<option name="CONTINUATION_INDENT_IN_ELVIS" value="false" />
<option name="WRAP_ELVIS_EXPRESSIONS" value="0" />
</JetCodeStyleSettings>
<XML>
<option name="XML_KEEP_LINE_BREAKS" value="false" />
<option name="XML_ALIGN_ATTRIBUTES" value="false" />
<option name="XML_SPACE_INSIDE_EMPTY_TAG" value="true" />
</XML>
<MarkdownNavigatorCodeStyleSettings>
<option name="RIGHT_MARGIN" value="72" />
</MarkdownNavigatorCodeStyleSettings>
<codeStyleSettings language="XML">
<option name="FORCE_REARRANGE_MODE" value="1" />
<indentOptions>
<option name="CONTINUATION_INDENT_SIZE" value="4" />
</indentOptions>
@ -38,6 +35,7 @@
<match>
<AND>
<NAME>xmlns:android</NAME>
<XML_ATTRIBUTE />
<XML_NAMESPACE>^$</XML_NAMESPACE>
</AND>
</match>
@ -48,6 +46,7 @@
<match>
<AND>
<NAME>xmlns:.*</NAME>
<XML_ATTRIBUTE />
<XML_NAMESPACE>^$</XML_NAMESPACE>
</AND>
</match>
@ -59,6 +58,7 @@
<match>
<AND>
<NAME>.*:id</NAME>
<XML_ATTRIBUTE />
<XML_NAMESPACE>http://schemas.android.com/apk/res/android</XML_NAMESPACE>
</AND>
</match>
@ -69,6 +69,7 @@
<match>
<AND>
<NAME>.*:name</NAME>
<XML_ATTRIBUTE />
<XML_NAMESPACE>http://schemas.android.com/apk/res/android</XML_NAMESPACE>
</AND>
</match>
@ -79,6 +80,7 @@
<match>
<AND>
<NAME>name</NAME>
<XML_ATTRIBUTE />
<XML_NAMESPACE>^$</XML_NAMESPACE>
</AND>
</match>
@ -89,6 +91,7 @@
<match>
<AND>
<NAME>style</NAME>
<XML_ATTRIBUTE />
<XML_NAMESPACE>^$</XML_NAMESPACE>
</AND>
</match>
@ -99,6 +102,7 @@
<match>
<AND>
<NAME>.*</NAME>
<XML_ATTRIBUTE />
<XML_NAMESPACE>^$</XML_NAMESPACE>
</AND>
</match>
@ -110,6 +114,7 @@
<match>
<AND>
<NAME>.*</NAME>
<XML_ATTRIBUTE />
<XML_NAMESPACE>http://schemas.android.com/apk/res/android</XML_NAMESPACE>
</AND>
</match>
@ -121,6 +126,7 @@
<match>
<AND>
<NAME>.*</NAME>
<XML_ATTRIBUTE />
<XML_NAMESPACE>.*</XML_NAMESPACE>
</AND>
</match>
@ -138,7 +144,6 @@
<option name="METHOD_PARAMETERS_LPAREN_ON_NEXT_LINE" value="true" />
<option name="METHOD_PARAMETERS_RPAREN_ON_NEXT_LINE" value="true" />
<option name="EXTENDS_LIST_WRAP" value="1" />
<option name="METHOD_CALL_CHAIN_WRAP" value="1" />
<indentOptions>
<option name="CONTINUATION_INDENT_SIZE" value="4" />
</indentOptions>

18
.idea/gradle.xml generated
View File

@ -1,18 +0,0 @@
<?xml version="1.0" encoding="UTF-8"?>
<project version="4">
<component name="GradleSettings">
<option name="linkedExternalProjectsSettings">
<GradleProjectSettings>
<option name="distributionType" value="DEFAULT_WRAPPED" />
<option name="externalProjectPath" value="$PROJECT_DIR$" />
<option name="modules">
<set>
<option value="$PROJECT_DIR$" />
<option value="$PROJECT_DIR$/app" />
</set>
</option>
<option name="resolveModulePerSourceSet" value="false" />
</GradleProjectSettings>
</option>
</component>
</project>

View File

@ -1,12 +0,0 @@
<?xml version="1.0" encoding="UTF-8"?>
<project version="4">
<component name="RunConfigurationProducerService">
<option name="ignoredProducers">
<set>
<option value="org.jetbrains.plugins.gradle.execution.test.runner.AllInPackageGradleConfigurationProducer" />
<option value="org.jetbrains.plugins.gradle.execution.test.runner.TestClassGradleConfigurationProducer" />
<option value="org.jetbrains.plugins.gradle.execution.test.runner.TestMethodGradleConfigurationProducer" />
</set>
</option>
</component>
</project>

View File

@ -3,18 +3,18 @@ jdk: oraclejdk8
env:
global:
- ANDROID_API_LEVEL=28
- ANDROID_BUILD_TOOLS_VERSION=28.0.3
- ANDROID_API_LEVEL=29
- ANDROID_BUILD_TOOLS_VERSION=29.0.2
cache:
directories:
- $HOME/.gradle/caches/
- $HOME/.gradle/wrapper/
#branches:
# only:
# - master
# - 0.7.x
branches:
only:
- develop
- 0.13.0
android:
licenses:
@ -34,12 +34,12 @@ android:
- extra-android-m2repository
- addon-google_apis-google-$ANDROID_API_LEVEL
# Android emulator
- android-19
- sys-img-armeabi-v7a-android-19
- android-22
- sys-img-armeabi-v7a-android-22
before_script:
# Launch emulator before the execution
- echo no | android create avd --force -n test -t android-19 --abi armeabi-v7a
- echo no | android create avd --force -n test -t android-22 --abi armeabi-v7a
- emulator -avd test -no-audio -no-window &
- android-wait-for-emulator
- adb shell input keyevent 82 &
@ -48,20 +48,20 @@ before_script:
script:
- ./gradlew dependencies --stacktrace --daemon
- fossa --no-ansi || true
- ./gradlew lint -x fabricGenerateResourcesRelease --stacktrace --daemon
- ./gradlew test -x fabricGenerateResourcesRelease --stacktrace --daemon
- ./gradlew createDebugCoverageReport --stacktrace --daemon
#- ./gradlew lintPlayRelease -x fabricGenerateResourcesPlayRelease --stacktrace --daemon
- ./gradlew testPlayDebugUnitTest -x fabricGenerateResourcesPlay --stacktrace --daemon
- ./gradlew createFdroidDebugCoverageReport --stacktrace --daemon
- ./gradlew jacocoTestReport --stacktrace --daemon
- if [ -z ${SONAR_HOST+x} ]; then echo "sonar scan skipped"; else
git fetch --unshallow;
./gradlew sonarqube -x test -x lint -x fabricGenerateResourcesRelease -Dsonar.host.url=$SONAR_HOST -Dsonar.organization=$SONAR_ORG -Dsonar.login=$SONAR_KEY -Dsonar.branch.name=${TRAVIS_PULL_REQUEST_BRANCH:-$TRAVIS_BRANCH} --stacktrace --daemon;
./gradlew sonarqube -x test -x lint -x fabricGenerateResourcesPlayRelease -x fabricGenerateResourcesFdroidRelease -Dsonar.host.url=$SONAR_HOST -Dsonar.organization=$SONAR_ORG -Dsonar.login=$SONAR_KEY -Dsonar.branch.name=${TRAVIS_PULL_REQUEST_BRANCH:-$TRAVIS_BRANCH} --stacktrace --daemon;
fi
- |
if [ $TRAVIS_TAG ]; then
gpg --yes --batch --passphrase=$SERVICES_ENCRYPT_KEY ./app/src/release/google-services.json.gpg;
gpg --yes --batch --passphrase=$ENCRYPT_KEY ./app/key.p12.gpg;
gpg --yes --batch --passphrase=$ENCRYPT_KEY ./app/upload-key.jks.gpg;
./gradlew publish -PenableCrashlytics --stacktrace;
./gradlew publishPlayRelease -PenableCrashlytics --stacktrace;
fi
after_success:

View File

@ -186,7 +186,7 @@
same "printed page" as the copyright notice for easier
identification within third-party archives.
Copyright 2017 wulkanowy
Copyright 2019 Wulkanowy
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.

61
README.en.md Normal file
View File

@ -0,0 +1,61 @@
[Polska wersja README](README.md)
# Wulkanowy
[![Travis](https://img.shields.io/travis/com/wulkanowy/wulkanowy/master.svg?style=flat-square)](https://travis-ci.com/wulkanowy/wulkanowy)
[![Codecov](https://img.shields.io/codecov/c/github/wulkanowy/wulkanowy/master.svg?style=flat-square)](https://codecov.io/gh/wulkanowy/wulkanowy)
[![Discord](https://img.shields.io/discord/390889354199040011.svg?style=flat-square)](https://discord.gg/vccAQBr)
[![F-Droid](https://img.shields.io/f-droid/v/io.github.wulkanowy.svg?style=flat-square)](https://f-droid.org/packages/io.github.wulkanowy/)
[![Last release](https://img.shields.io/github/release/wulkanowy/wulkanowy.svg?logo=github&style=flat-square)](https://github.com/wulkanowy/wulkanowy/releases)
Unofficial android VULCAN UONET+ register client for student and parent
## Features
* logging in using the email and password
* functions from the register website:
* grades
* grade statistics
* attendance
* percentage of attendance
* exams
* timetable
* completed lessons
* messages
* homework
* notes
* lucky number
* calculation of the average
* notifications, e.g. about a new grade
* dark and black (AMOLED) theme
* offline mode
* no ads
## Download
You can download the current beta from the Google Play or Fdroid store
[<img src="https://play.google.com/intl/en_us/badges/images/generic/en_badge_web_generic.png"
alt="Get it on Google Play"
height="80">](https://play.google.com/store/apps/details?id=io.github.wulkanowy)
[<img src="https://fdroid.gitlab.io/artwork/badge/get-it-on.png"
alt="Get it on Fdroid"
height="80">](https://f-droid.org/packages/io.github.wulkanowy/)
You can also download a [development version](https://wulkanowy.github.io/#download) that includes new features prepared for the next release
## Built With
* [Wulkanowy API](https://github.com/wulkanowy/api)
* [RxJava 2](https://github.com/ReactiveX/RxJava)
* [Dagger 2](https://github.com/google/dagger)
* [Room](https://developer.android.com/topic/libraries/architecture/room)
* [WorkManager](https://developer.android.com/topic/libraries/architecture/workmanager)
## Contributing
Please contribute to the project either by creating a PR or submitting an issue on GitHub.
## License
This project is licensed under the Apache License 2.0 - see the [LICENSE](LICENSE) file for details

View File

@ -1,22 +1,62 @@
[English version of README](README.en.md)
# Wulkanowy
[![CircleCI](https://img.shields.io/circleci/project/github/wulkanowy/wulkanowy/master.svg?style=flat-square)](https://circleci.com/gh/wulkanowy/wulkanowy)
[![Travis](https://img.shields.io/travis/com/wulkanowy/wulkanowy/master.svg?style=flat-square)](https://travis-ci.com/wulkanowy/wulkanowy)
[![Bitrise](https://img.shields.io/bitrise/daeff1893f3c8128/master.svg?token=Hjm1ACamk86JDeVVJHOeqQ&style=flat-square)](https://www.bitrise.io/app/daeff1893f3c8128)
[![Codecov](https://img.shields.io/codecov/c/github/wulkanowy/wulkanowy/master.svg?style=flat-square)](https://codecov.io/gh/wulkanowy/wulkanowy)
[![BCH compliance](https://bettercodehub.com/edge/badge/wulkanowy/wulkanowy?branch=master)](https://bettercodehub.com/)
[![Sonarcloud](https://sonarcloud.io/api/project_badges/measure?project=io.github.wulkanowy%3Aapp&metric=sqale_rating)](https://sonarcloud.io/dashboard?id=io.github.wulkanowy%3Aapp)
[![FOSSA Status](https://app.fossa.com/api/projects/custom%2B5644%2Fgithub.com%2Fwulkanowy%2Fwulkanowy.svg?type=shield)](https://app.fossa.com/projects/custom%2B5644%2Fgithub.com%2Fwulkanowy%2Fwulkanowy?ref=badge_shield)
[![Discord](https://img.shields.io/discord/390889354199040011.svg?style=flat-square)](https://discord.gg/vccAQBr)
[![F-Droid](https://img.shields.io/f-droid/v/io.github.wulkanowy.svg?style=flat-square)](https://f-droid.org/packages/io.github.wulkanowy/)
[![Last release](https://img.shields.io/github/release/wulkanowy/wulkanowy.svg?logo=github&style=flat-square)](https://github.com/wulkanowy/wulkanowy/releases)
[Pobierz wersję beta z Google Play](https://play.google.com/store/apps/details?id=io.github.wulkanowy&amp;utm_source=vcs)
Nieoficjalny klient dziennika VULCAN UONET+ dla ucznia i rodzica
[Pobierz wersję DEV](https://bitrise-redirector.herokuapp.com/v0.1/apps/f841f20d8f8b1dc8/builds/master/artifacts/0)
[(Więcej wersji DEV)](https://wulkanowy.github.io/dev.html)
## Funkcje
Androidowy klient dziennika VULCAN UONET+.
* logowanie za pomocą e-maila i hasła
* funkcje ze strony internetowej dziennika:
* oceny
* statystyki ocen
* frekwencja
* procent frekwencji
* sprawdziany
* plan lekcji
* lekcje zrealizowane
* wiadomości
* zadania domowe
* uwagi
* szczęśliwy numerek
* obliczanie średniej
* powiadomienia np. o nowej ocenie
* ciemny i czarny (AMOLED) motyw
* tryb offilne
* brak reklam
## Pobierz
Aktualną wersję beta możesz pobrać ze sklepu Google Play lub Fdroid
[<img src="https://play.google.com/intl/en_us/badges/images/generic/en_badge_web_generic.png"
alt="Pobierz z Google Play"
height="80">](https://play.google.com/store/apps/details?id=io.github.wulkanowy)
[<img src="https://fdroid.gitlab.io/artwork/badge/get-it-on.png"
alt="Pobierz z Fdroid"
height="80">](https://f-droid.org/packages/io.github.wulkanowy/)
## License
Możesz także pobrać [wersję rozwojową](https://wulkanowy.github.io/#download), która zawiera nowe funkcje przygotowywane do następnego wydania
[![FOSSA Status](https://app.fossa.com/api/projects/custom%2B5644%2Fgithub.com%2Fwulkanowy%2Fwulkanowy.svg?type=large)](https://app.fossa.com/projects/custom%2B5644%2Fgithub.com%2Fwulkanowy%2Fwulkanowy?ref=badge_large)
## Zbudowana za pomocą
* [Wulkanowy API](https://github.com/wulkanowy/api)
* [RxJava 2](https://github.com/ReactiveX/RxJava)
* [Dagger 2](https://github.com/google/dagger)
* [Room](https://developer.android.com/topic/libraries/architecture/room)
* [WorkManager](https://developer.android.com/topic/libraries/architecture/workmanager)
## Współpraca
Wnieś swój wkład w projekt, tworząc PR lub wysyłając issue na GitHub.
## Licencja
Ten projekt jest licencjonowany w ramach Apache License 2.0 - szczegóły w pliku [LICENSE](LICENSE)

1
app/.gitignore vendored
View File

@ -1 +0,0 @@
/build

View File

@ -6,18 +6,19 @@ apply plugin: 'io.fabric'
apply plugin: 'com.github.triplet.play'
apply from: 'jacoco.gradle'
apply from: 'sonarqube.gradle'
apply from: 'hooks.gradle'
android {
compileSdkVersion 28
buildToolsVersion '28.0.3'
compileSdkVersion 29
buildToolsVersion '29.0.2'
defaultConfig {
applicationId "io.github.wulkanowy"
testApplicationId "io.github.tests.wulkanowy"
minSdkVersion 15
targetSdkVersion 28
versionCode 33
versionName "0.8.0"
minSdkVersion 16
targetSdkVersion 29
versionCode 48
versionName "0.13.0"
multiDexEnabled true
testInstrumentationRunner "androidx.test.runner.AndroidJUnitRunner"
vectorDrawables.useSupportLibrary = true
@ -27,7 +28,10 @@ android {
]
javaCompileOptions {
annotationProcessorOptions {
arguments = ["room.schemaLocation": "$projectDir/schemas".toString()]
arguments = [
"room.schemaLocation": "$projectDir/schemas".toString(),
"room.incremental" : "true"
]
}
}
}
@ -59,7 +63,19 @@ android {
versionNameSuffix "-dev"
testCoverageEnabled = true
ext.enableCrashlytics = project.hasProperty("enableCrashlytics")
multiDexKeepProguard file('proguard-multidex-rules.pro')
}
}
flavorDimensions "platform"
productFlavors {
play {
dimension "platform"
}
fdroid {
buildConfigField "boolean", "CRASHLYTICS_ENABLED", "false"
dimension "platform"
}
}
@ -71,6 +87,15 @@ android {
sourceCompatibility JavaVersion.VERSION_1_8
targetCompatibility JavaVersion.VERSION_1_8
}
kotlinOptions {
jvmTarget = "1.8"
}
packagingOptions {
exclude 'META-INF/library_release.kotlin_module'
exclude 'META-INF/library-core_release.kotlin_module'
}
}
androidExtensions {
@ -80,75 +105,98 @@ androidExtensions {
play {
serviceAccountEmail = System.getenv("PLAY_SERVICE_ACCOUNT_EMAIL") ?: "jan@fakelog.cf"
serviceAccountCredentials = file('key.p12')
defaultToAppBundles = true
defaultToAppBundles = false
track = 'alpha'
}
ext {
work_manager = "2.3.0-beta01"
room = "2.2.2"
dagger = "2.25.2"
chucker = "2.0.4"
mockk = "1.9.2"
}
configurations.all {
resolutionStrategy.force "androidx.constraintlayout:constraintlayout:1.1.3"
}
dependencies {
implementation 'io.github.wulkanowy:api:0.8.0'
implementation "io.github.wulkanowy:api:0.13.0"
implementation "org.jetbrains.kotlin:kotlin-stdlib-jdk8:$kotlin_version"
implementation "androidx.legacy:legacy-support-v4:1.0.0"
implementation "androidx.appcompat:appcompat:1.0.2"
implementation 'androidx.multidex:multidex:2.0.1'
implementation "androidx.core:core-ktx:1.2.0-rc01"
implementation "androidx.activity:activity-ktx:1.1.0-rc03"
implementation "androidx.appcompat:appcompat:1.1.0"
implementation "androidx.appcompat:appcompat-resources:1.1.0"
implementation "androidx.fragment:fragment-ktx:1.2.0-rc03"
implementation "androidx.annotation:annotation:1.1.0"
implementation "androidx.multidex:multidex:2.0.1"
implementation "androidx.cardview:cardview:1.0.0"
implementation 'androidx.constraintlayout:constraintlayout:1.1.3'
implementation "com.google.android.material:material:1.1.0-alpha05"
implementation 'com.github.wulkanowy:MaterialChipsInput:b72fd0ee6f'
implementation 'com.github.PhilJay:MPAndroidChart:v3.1.0'
implementation "androidx.preference:preference-ktx:1.1.0"
implementation "androidx.recyclerview:recyclerview:1.1.0"
implementation "androidx.viewpager:viewpager:1.0.0"
implementation "androidx.swiperefreshlayout:swiperefreshlayout:1.1.0-alpha03"
implementation "androidx.constraintlayout:constraintlayout:1.1.3"
implementation "androidx.coordinatorlayout:coordinatorlayout:1.1.0"
implementation "com.google.android.material:material:1.1.0-beta02"
implementation "com.github.wulkanowy:material-chips-input:2.0.1"
implementation "com.github.PhilJay:MPAndroidChart:v3.1.0"
implementation "me.zhanghai.android.materialprogressbar:library:1.6.1"
implementation "androidx.work:work-runtime:2.0.1"
implementation "androidx.work:work-rxjava2:2.0.1"
implementation "androidx.work:work-runtime-ktx:$work_manager"
implementation "androidx.work:work-rxjava2:$work_manager"
implementation "androidx.work:work-gcm:$work_manager"
implementation "androidx.room:room-runtime:2.1.0-alpha07"
implementation "androidx.room:room-rxjava2:2.1.0-alpha07"
kapt "androidx.room:room-compiler:2.1.0-alpha07"
implementation "androidx.room:room-runtime:$room"
implementation "androidx.room:room-rxjava2:$room"
implementation "androidx.room:room-ktx:$room"
kapt "androidx.room:room-compiler:$room"
implementation "com.google.dagger:dagger-android-support:2.22.1"
kapt "com.google.dagger:dagger-compiler:2.22.1"
kapt "com.google.dagger:dagger-android-processor:2.22.1"
implementation 'com.squareup.inject:assisted-inject-annotations-dagger2:0.4.0'
kapt 'com.squareup.inject:assisted-inject-processor-dagger2:0.4.0'
implementation "com.google.dagger:dagger-android-support:$dagger"
kapt "com.google.dagger:dagger-compiler:$dagger"
kapt "com.google.dagger:dagger-android-processor:$dagger"
implementation "com.squareup.inject:assisted-inject-annotations-dagger2:0.5.2"
kapt "com.squareup.inject:assisted-inject-processor-dagger2:0.5.2"
implementation "eu.davidea:flexible-adapter:5.1.0"
implementation "eu.davidea:flexible-adapter-ui:1.0.0"
implementation "com.aurelhubert:ahbottomnavigation:2.3.4"
implementation 'com.ncapdevi:frag-nav:3.2.0'
implementation "com.ncapdevi:frag-nav:3.3.0"
implementation "com.github.YarikSOffice:lingver:1.1.0"
implementation 'com.github.pwittchen:reactivenetwork-rx2:3.0.2'
implementation 'io.reactivex.rxjava2:rxandroid:2.1.1'
implementation "io.reactivex.rxjava2:rxjava:2.2.8"
implementation "com.github.pwittchen:reactivenetwork-rx2:3.0.6"
implementation "io.reactivex.rxjava2:rxandroid:2.1.1"
implementation "io.reactivex.rxjava2:rxjava:2.2.15"
implementation 'com.google.code.gson:gson:2.8.5'
implementation "com.jakewharton.threetenabp:threetenabp:1.2.0"
implementation "com.google.code.gson:gson:2.8.6"
implementation "com.jakewharton.threetenabp:threetenabp:1.2.1"
implementation "com.jakewharton.timber:timber:4.7.1"
implementation "at.favre.lib:slf4j-timber:1.0.1"
implementation "com.squareup.okhttp3:logging-interceptor:3.12.1"
implementation "com.squareup.okhttp3:logging-interceptor:3.12.6"
implementation "com.mikepenz:aboutlibraries:7.0.4"
implementation 'com.wdullaer:materialdatetimepicker:4.2.3'
implementation "com.mikepenz:aboutlibraries:6.2.3"
implementation 'com.takisoft.preferencex:preferencex:1.0.0'
playImplementation "com.google.firebase:firebase-core:17.2.1"
playImplementation "com.crashlytics.sdk.android:crashlytics:2.10.1"
implementation 'com.google.firebase:firebase-core:16.0.8'
implementation 'com.crashlytics.sdk.android:crashlytics:2.9.9'
releaseImplementation "fr.o80.chucker:library-no-op:$chucker"
releaseImplementation 'fr.o80.chucker:library-no-op:2.0.4'
debugImplementation 'fr.o80.chucker:library:2.0.4'
debugImplementation "fr.o80.chucker:library:$chucker"
debugImplementation "com.amitshekhar.android:debug-db:1.0.6"
testImplementation "junit:junit:4.12"
testImplementation "io.mockk:mockk:1.9.2"
testImplementation "org.mockito:mockito-inline:2.27.0"
testImplementation 'org.threeten:threetenbp:1.3.8'
testImplementation "io.mockk:mockk:$mockk"
testImplementation "org.threeten:threetenbp:1.4.0"
testImplementation "org.mockito:mockito-inline:3.2.0"
androidTestImplementation 'androidx.test:core:1.1.0'
androidTestImplementation 'androidx.test:runner:1.1.1'
androidTestImplementation 'androidx.test.ext:junit:1.1.0'
androidTestImplementation "io.mockk:mockk-android:1.9.2"
androidTestImplementation 'org.mockito:mockito-android:2.27.0'
androidTestImplementation "androidx.room:room-testing:2.1.0-alpha07"
androidTestImplementation "androidx.test:core:1.2.0"
androidTestImplementation "androidx.test:runner:1.2.0"
androidTestImplementation "androidx.test.ext:junit:1.1.1"
androidTestImplementation "io.mockk:mockk-android:$mockk"
androidTestImplementation "androidx.room:room-testing:$room"
androidTestImplementation "org.jetbrains.kotlin:kotlin-test:$kotlin_version"
androidTestImplementation "org.mockito:mockito-android:3.2.0"
}
apply plugin: 'com.google.gms.google-services'

10
app/hooks.gradle Normal file
View File

@ -0,0 +1,10 @@
apply plugin: "com.star-zero.gradle.githook"
githook {
failOnMissingHooksDir = false
hooks {
"pre-push" {
shell = "./app/play-publish-lint.sh"
}
}
}

View File

@ -1,7 +1,7 @@
apply plugin: "jacoco"
jacoco {
toolVersion "0.8.3"
toolVersion "0.8.4"
reportsDir = file("$buildDir/reports")
}
@ -35,11 +35,14 @@ task jacocoTestReport(type: JacocoReport) {
dir: "$buildDir/intermediates/classes/debug",
excludes: excludes
) + fileTree(
dir: "$buildDir/tmp/kotlin-classes/debug",
dir: "$buildDir/tmp/kotlin-classes/playDebug",
excludes: excludes
))
sourceDirectories.setFrom(files("$project.projectDir/src/main/java"))
sourceDirectories.setFrom(files([
"src/main/java",
"src/play/java"
]))
executionData.setFrom(fileTree(
dir: project.projectDir,
includes: ["**/*.exec", "**/*.ec"]

Binary file not shown.

7
app/play-publish-lint.sh Executable file
View File

@ -0,0 +1,7 @@
#!/bin/bash -
content=$(cat < "app/src/main/play/release-notes/pl-PL/default.txt") || exit
if [[ "${#content}" -gt 500 ]]; then
echo >&2 "Release notes content has reached the limit of 500 characters"
exit 1
fi

View File

@ -1,3 +0,0 @@
-keep class android.support.test.internal** { *; }
-keep class org.junit.** { *; }
-keep public class io.github.wulkanowy** { *; }

View File

@ -11,6 +11,10 @@
-verbose
#Keep all wulkanowy files
-keep class io.github.wulkanowy.** {*;}
#Config for anallitycs
-keepattributes *Annotation*
-keepattributes SourceFile,LineNumberTable
@ -32,8 +36,10 @@
-dontwarn rx.internal.util.**
-dontwarn sun.misc.Unsafe
#Config for MPAndroidChart
-keep class com.github.mikephil.charting.** { *; }
#Config for API
-keep class io.github.wulkanowy.api.** {*;}
#Config for Material Components
-keep class com.google.android.material.tabs.** { *; }

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

View File

@ -29,5 +29,6 @@ sonarqube {
property "sonar.java.coveragePlugin", "jacoco"
property "sonar.android.lint.report", "build/reports/lint-results.xml"
property "sonar.jacoco.reportPaths", fileTree(dir: project.projectDir, includes: ['**/*.exec', '**/*.ec'])
property "sonar.coverage.jacoco.xmlReportPaths", "build/reports/jacocoTestReport/jacocoTestReport.xml"
}
}

View File

@ -22,7 +22,7 @@ abstract class AbstractMigrationTest {
fun getMigratedRoomDatabase(): AppDatabase {
val database = Room.databaseBuilder(ApplicationProvider.getApplicationContext(),
AppDatabase::class.java, dbName)
.addMigrations(Migration12(), Migration13())
.addMigrations(*AppDatabase.getMigrations())
.build()
// close the database and release any stream resources when the test finishes
helper.closeWhenFinished(database)

View File

@ -3,10 +3,14 @@ package io.github.wulkanowy.data.db.migrations
import android.content.ContentValues
import android.database.sqlite.SQLiteDatabase
import androidx.sqlite.db.SupportSQLiteDatabase
import io.github.wulkanowy.data.db.Converters
import io.github.wulkanowy.data.db.entities.Semester
import org.junit.Assert.assertEquals
import org.junit.Assert.assertFalse
import org.junit.Assert.assertTrue
import org.junit.Test
import org.threeten.bp.LocalDate.now
import org.threeten.bp.LocalDate.of
import kotlin.test.assertFalse
import kotlin.test.assertTrue
class Migration13Test : AbstractMigrationTest() {
@ -97,11 +101,9 @@ class Migration13Test : AbstractMigrationTest() {
close()
}
helper.runMigrationsAndValidate(dbName, 13, true, Migration13())
val db = helper.runMigrationsAndValidate(dbName, 13, true, Migration13())
val db = getMigratedRoomDatabase()
val semesters1 = db.semesterDao.loadAll(1, 5).blockingGet()
val semesters1 = getSemesters(db, "SELECT * FROM Semesters WHERE student_id = 1 AND class_id = 5")
assertTrue { semesters1.single { it.isCurrent }.isCurrent }
semesters1[0].run {
assertFalse(isCurrent)
@ -119,7 +121,7 @@ class Migration13Test : AbstractMigrationTest() {
assertEquals(2, diaryId)
}
db.semesterDao.loadAll(2, 5).blockingGet().let {
getSemesters(db, "SELECT * FROM Semesters WHERE student_id = 2 AND class_id = 5").let {
assertTrue { it.single { it.isCurrent }.isCurrent }
assertEquals(1970, it[0].schoolYear)
assertEquals(of(1970, 1, 1), it[0].end)
@ -130,7 +132,7 @@ class Migration13Test : AbstractMigrationTest() {
assertTrue(it[3].isCurrent)
}
db.semesterDao.loadAll(2, 5).blockingGet().let {
getSemesters(db, "SELECT * FROM Semesters WHERE student_id = 2 AND class_id = 5").let {
assertTrue { it.single { it.isCurrent }.isCurrent }
assertFalse(it[0].isCurrent)
assertFalse(it[1].isCurrent)
@ -139,6 +141,30 @@ class Migration13Test : AbstractMigrationTest() {
}
}
private fun getSemesters(db: SupportSQLiteDatabase, query: String): List<Semester> {
val semesters = mutableListOf<Semester>()
val cursor = db.query(query)
if (cursor.moveToFirst()) {
do {
semesters.add(Semester(
studentId = cursor.getInt(1),
diaryId = cursor.getInt(2),
diaryName = cursor.getString(3),
semesterId = cursor.getInt(4),
semesterName = cursor.getInt(5),
isCurrent = cursor.getInt(6) == 1,
classId = cursor.getInt(7),
unitId = cursor.getInt(8),
schoolYear = cursor.getInt(9),
start = Converters().timestampToDate(cursor.getLong(10))!!,
end = Converters().timestampToDate(cursor.getLong(11))!!
))
} while (cursor.moveToNext())
}
return semesters.toList()
}
private fun createStudent(db: SupportSQLiteDatabase, studentId: Int, schoolName: String = "", classId: Int = -1, schoolId: Int = 123) {
db.insert("Students", SQLiteDatabase.CONFLICT_FAIL, ContentValues().apply {
put("endpoint", "https://fakelog.cf")

View File

@ -22,6 +22,7 @@ import org.junit.Test
import org.junit.runner.RunWith
import org.threeten.bp.LocalDate.of
import org.threeten.bp.LocalDateTime
import kotlin.test.assertEquals
import kotlin.test.assertFalse
import kotlin.test.assertTrue
import io.github.wulkanowy.api.grades.Grade as GradeApi
@ -109,4 +110,73 @@ class GradeRepositoryTest {
assertTrue { grades[2].isRead }
assertTrue { grades[3].isRead }
}
@Test
fun subtractLocaleDuplicateGrades() {
gradeLocal.saveGrades(listOf(
createGradeLocal(5, 3.0, of(2019, 2, 25), "Taka sama ocena"),
createGradeLocal(5, 3.0, of(2019, 2, 25), "Taka sama ocena"),
createGradeLocal(3, 5.0, of(2019, 2, 26), "Jakaś inna ocena")
))
every { mockApi.getGrades(1) } returns Single.just(listOf(
createGradeApi(5, 3.0, of(2019, 2, 25), "Taka sama ocena"),
createGradeApi(3, 5.0, of(2019, 2, 26), "Jakaś inna ocena")
))
val grades = GradeRepository(settings, gradeLocal, gradeRemote)
.getGrades(studentMock, semesterMock, true).blockingGet()
assertEquals(2, grades.size)
}
@Test
fun subtractRemoteDuplicateGrades() {
gradeLocal.saveGrades(listOf(
createGradeLocal(5, 3.0, of(2019, 2, 25), "Taka sama ocena"),
createGradeLocal(3, 5.0, of(2019, 2, 26), "Jakaś inna ocena")
))
every { mockApi.getGrades(1) } returns Single.just(listOf(
createGradeApi(5, 3.0, of(2019, 2, 25), "Taka sama ocena"),
createGradeApi(5, 3.0, of(2019, 2, 25), "Taka sama ocena"),
createGradeApi(3, 5.0, of(2019, 2, 26), "Jakaś inna ocena")
))
val grades = GradeRepository(settings, gradeLocal, gradeRemote)
.getGrades(studentMock, semesterMock, true).blockingGet()
assertEquals(3, grades.size)
}
@Test
fun emptyLocal() {
gradeLocal.saveGrades(listOf())
every { mockApi.getGrades(1) } returns Single.just(listOf(
createGradeApi(5, 3.0, of(2019, 2, 25), "Taka sama ocena"),
createGradeApi(5, 3.0, of(2019, 2, 25), "Taka sama ocena"),
createGradeApi(3, 5.0, of(2019, 2, 26), "Jakaś inna ocena")
))
val grades = GradeRepository(settings, gradeLocal, gradeRemote)
.getGrades(studentMock, semesterMock, true).blockingGet()
assertEquals(3, grades.size)
}
@Test
fun emptyRemote() {
gradeLocal.saveGrades(listOf(
createGradeLocal(5, 3.0, of(2019, 2, 25), "Taka sama ocena"),
createGradeLocal(3, 5.0, of(2019, 2, 26), "Jakaś inna ocena")
))
every { mockApi.getGrades(1) } returns Single.just(listOf())
val grades = GradeRepository(settings, gradeLocal, gradeRemote)
.getGrades(studentMock, semesterMock, true).blockingGet()
assertEquals(0, grades.size)
}
}

View File

@ -4,6 +4,7 @@ import androidx.room.Room
import androidx.test.core.app.ApplicationProvider
import androidx.test.ext.junit.runners.AndroidJUnit4
import io.github.wulkanowy.data.db.AppDatabase
import io.github.wulkanowy.data.db.entities.GradePointsStatistics
import io.github.wulkanowy.data.db.entities.GradeStatistics
import io.github.wulkanowy.data.db.entities.Semester
import org.junit.After
@ -24,7 +25,7 @@ class GradeStatisticsLocalTest {
fun createDb() {
testDb = Room.inMemoryDatabaseBuilder(ApplicationProvider.getApplicationContext(), AppDatabase::class.java)
.build()
gradeStatisticsLocal = GradeStatisticsLocal(testDb.gradeStatistics)
gradeStatisticsLocal = GradeStatisticsLocal(testDb.gradeStatistics, testDb.gradePointsStatistics)
}
@After
@ -63,7 +64,52 @@ class GradeStatisticsLocalTest {
assertEquals(stats[0].subject, "Wszystkie")
}
@Test
fun saveAndRead_points() {
gradeStatisticsLocal.saveGradesPointsStatistics(listOf(
getGradePointsStatistics("Matematyka", 2, 1),
getGradePointsStatistics("Chemia", 2, 1),
getGradePointsStatistics("Fizyka", 1, 2)
))
val stats = gradeStatisticsLocal.getGradesPointsStatistics(
Semester(2, 2, "", 2019, 1, 2, true, LocalDate.now(), LocalDate.now(), 1, 1),
"Matematyka"
).blockingGet()
with(stats) {
assertEquals(subject, "Matematyka")
assertEquals(others, 5.0)
assertEquals(student, 5.0)
}
}
@Test
fun saveAndRead_subjectEmpty() {
gradeStatisticsLocal.saveGradesPointsStatistics(listOf())
val stats = gradeStatisticsLocal.getGradesPointsStatistics(
Semester(2, 2, "", 2019, 1, 2, true, LocalDate.now(), LocalDate.now(), 1, 1),
"Matematyka"
).blockingGet()
assertEquals(null, stats)
}
@Test
fun saveAndRead_allEmpty() {
gradeStatisticsLocal.saveGradesPointsStatistics(listOf())
val stats = gradeStatisticsLocal.getGradesPointsStatistics(
Semester(2, 2, "", 2019, 1, 2, true, LocalDate.now(), LocalDate.now(), 1, 1),
"Wszystkie"
).blockingGet()
assertEquals(null, stats)
}
private fun getGradeStatistics(subject: String, studentId: Int, semesterId: Int): GradeStatistics {
return GradeStatistics(studentId, semesterId, subject, 5, 5, false)
}
private fun getGradePointsStatistics(subject: String, studentId: Int, semesterId: Int): GradePointsStatistics {
return GradePointsStatistics(studentId, semesterId, subject, 5.0, 5.0)
}
}

View File

@ -5,7 +5,7 @@ import androidx.room.Room
import androidx.test.core.app.ApplicationProvider
import androidx.test.ext.junit.runners.AndroidJUnit4
import io.github.wulkanowy.data.db.AppDatabase
import io.github.wulkanowy.data.db.SharedPrefHelper
import io.github.wulkanowy.data.db.SharedPrefProvider
import io.github.wulkanowy.data.db.entities.Student
import org.junit.After
import org.junit.Before
@ -21,14 +21,14 @@ class StudentLocalTest {
private lateinit var testDb: AppDatabase
private lateinit var sharedHelper: SharedPrefHelper
private lateinit var sharedProvider: SharedPrefProvider
@Before
fun createDb() {
val context = ApplicationProvider.getApplicationContext<Context>()
testDb = Room.inMemoryDatabaseBuilder(context, AppDatabase::class.java)
.build()
sharedHelper = SharedPrefHelper(context.getSharedPreferences("TEST", Context.MODE_PRIVATE))
sharedProvider = SharedPrefProvider(context.getSharedPreferences("TEST", Context.MODE_PRIVATE))
studentLocal = StudentLocal(testDb.studentDao, context)
}

View File

@ -7,7 +7,7 @@ import org.threeten.bp.LocalDateTime.now
import io.github.wulkanowy.api.timetable.Timetable as TimetableRemote
import io.github.wulkanowy.data.db.entities.Timetable as TimetableLocal
fun createTimetableLocal(number: Int, start: LocalDateTime, room: String = "", subject: String = ""): TimetableLocal {
fun createTimetableLocal(number: Int, start: LocalDateTime, room: String = "", subject: String = "", teacher: String = "", changes: Boolean = false): TimetableLocal {
return TimetableLocal(
studentId = 1,
diaryId = 2,
@ -20,15 +20,15 @@ fun createTimetableLocal(number: Int, start: LocalDateTime, room: String = "", s
group = "",
room = room,
roomOld = "",
teacher = "",
teacher = teacher,
teacherOld = "",
info = "",
changes = false,
changes = changes,
canceled = false
)
}
fun createTimetableRemote(number: Int, start: LocalDateTime, room: String, subject: String = ""): TimetableRemote {
fun createTimetableRemote(number: Int, start: LocalDateTime, room: String, subject: String = "", teacher: String = "", changes: Boolean = false): TimetableRemote {
return TimetableRemote(
number = number,
start = start.toDate(),
@ -37,9 +37,9 @@ fun createTimetableRemote(number: Int, start: LocalDateTime, room: String, subje
subject = subject,
group = "",
room = room,
teacher = "",
teacher = teacher,
info = "",
changes = false,
changes = changes,
canceled = false
)
}

View File

@ -60,26 +60,55 @@ class TimetableRepositoryTest {
}
@Test
fun copyDetailsToCompletedFromPrevious() {
fun copyRoomToCompletedFromPrevious() {
timetableLocal.saveTimetable(listOf(
createTimetableLocal(1, of(2019, 3, 5, 8, 0), "123", "Przyroda"),
createTimetableLocal(1, of(2019, 3, 5, 8, 50), "321", "Religia"),
createTimetableLocal(1, of(2019, 3, 5, 9, 40), "213", "W-F")
createTimetableLocal(2, of(2019, 3, 5, 8, 50), "321", "Religia"),
createTimetableLocal(3, of(2019, 3, 5, 9, 40), "213", "W-F"),
createTimetableLocal(4, of(2019, 3, 5, 10, 30), "213", "W-F", "Jan Kowalski")
))
every { mockApi.getTimetable(any(), any()) } returns Single.just(listOf(
createTimetableRemote(1, of(2019, 3, 5, 8, 0), "", "Przyroda"),
createTimetableRemote(1, of(2019, 3, 5, 8, 50), "", "Religia"),
createTimetableRemote(1, of(2019, 3, 5, 9, 40), "", "W-F")
createTimetableRemote(2, of(2019, 3, 5, 8, 50), "", "Religia"),
createTimetableRemote(3, of(2019, 3, 5, 9, 40), "", "W-F"),
createTimetableRemote(4, of(2019, 3, 5, 10, 30), "", "W-F")
))
val lessons = TimetableRepository(settings, timetableLocal, timetableRemote)
.getTimetable(semesterMock, LocalDate.of(2019, 3, 5), LocalDate.of(2019, 3, 5), true)
.blockingGet()
assertEquals(3, lessons.size)
assertEquals(4, lessons.size)
assertEquals("123", lessons[0].room)
assertEquals("321", lessons[1].room)
assertEquals("213", lessons[2].room)
}
@Test
fun copyTeacherToCompletedFromPrevious() {
timetableLocal.saveTimetable(listOf(
createTimetableLocal(1, of(2019, 3, 5, 8, 0), "123", "Przyroda", "Jan Garnkiewicz", false),
createTimetableLocal(2, of(2019, 3, 5, 8, 50), "321", "Religia", "Paweł Jumper", false),
createTimetableLocal(3, of(2019, 3, 5, 9, 40), "213", "W-F", "", true),
createTimetableLocal(4, of(2019, 3, 5, 10, 30), "213", "W-F", "", false)
))
every { mockApi.getTimetable(any(), any()) } returns Single.just(listOf(
createTimetableRemote(1, of(2019, 3, 5, 8, 0), "", "Przyroda", "", true), // should override local
createTimetableRemote(2, of(2019, 3, 5, 8, 50), "", "Religia", "", false),
createTimetableRemote(3, of(2019, 3, 5, 9, 40), "", "W-F", "Jan Garnkiewicz", false),
createTimetableRemote(4, of(2019, 3, 5, 10, 30), "", "W-F", "Paweł Jumper", false)
))
val lessons = TimetableRepository(settings, timetableLocal, timetableRemote)
.getTimetable(semesterMock, LocalDate.of(2019, 3, 5), LocalDate.of(2019, 3, 5), true)
.blockingGet()
assertEquals(4, lessons.size)
assertEquals("", lessons[0].teacher)
assertEquals("Paweł Jumper", lessons[1].teacher)
assertEquals("Jan Garnkiewicz", lessons[2].teacher)
assertEquals("Paweł Jumper", lessons[3].teacher)
}
}

View File

@ -1,58 +0,0 @@
<vector xmlns:android="http://schemas.android.com/apk/res/android"
android:width="108dp"
android:height="108dp"
android:viewportWidth="1926.9231"
android:viewportHeight="1926.9231">
<group android:translateX="462.46155"
android:translateY="462.46155">
<path
android:pathData="M2000,1440.1V2002H1240.1L238.1,1000v0l-120,-120c0.2,-0.2 -0.7,-1.6 -0.6,-1.8 1.6,-3.1 3.4,-6 5,-9.1 0.4,-0.8 0.6,-1.6 0.6,-2.5 9.2,-15.1 20.2,-28.9 31.4,-42.6 0.1,-0.2 0.3,-0.3 0.4,-0.5 5.1,-6.3 10.3,-12.6 15.3,-18.9 1,-1.2 1.9,-2.4 2.9,-3.7 0.2,-0.2 0.3,-0.4 0.5,-0.6 7.6,-9.7 14.8,-19.7 21.2,-30.2 1,-1.7 2,-3.4 2.9,-5.1 0.1,-0.2 0.2,-0.3 0.3,-0.5 6.2,-11.4 11.3,-23.3 17.7,-34.6 4.5,-8 9.3,-15.9 13.8,-23.9 0.1,-0.2 0.2,-0.3 0.3,-0.5 0.8,-1.5 1.6,-3 2.4,-4.4 0.2,-0.3 0.3,-0.6 0.5,-0.9 2,-3.7 3.8,-7.4 5.6,-11.2 6.2,-13.4 10.2,-27.7 14,-41.9 0,-0.2 0.1,-0.3 0.1,-0.5 0.3,-1 0.5,-2 0.8,-2.9 4,-15.3 7.3,-31.4 13.5,-45.9 1.4,-3.3 3,-6.5 4.6,-9.6 0.1,-0.2 0.2,-0.3 0.3,-0.5 5,-9.7 10.6,-19.1 13.5,-29.7 2.6,-9.2 3.5,-19 3.6,-28.8 0,-0.2 0,-0.3 0,-0.5 0.1,-7.2 -0.1,-14.4 -0.4,-21.3 0.9,-5.6 1.9,-11.3 3,-16.9 0.2,-0.9 0.3,-1.7 0.5,-2.6 1.2,-5.9 2.5,-11.7 4.2,-17.4 0,-0.1 0.1,-0.3 0.1,-0.4 0,-0.2 0.1,-0.3 0.1,-0.5 0.2,-2.1 -0.8,-3.7 -2.4,-4.5l7.7,-7.6c1.2,0.9 2.7,1.3 4.3,0.9 12.8,-3.9 24.9,-9.9 36.3,-16.8 2.8,-1.7 5.6,-3.4 8.3,-5.2 0.2,-0.1 0.3,-0.2 0.5,-0.3 7.7,-4.9 15.2,-10.2 22.1,-16 3.1,-2.7 5.9,-5.6 8.3,-8.9 0.1,-0.2 0.2,-0.3 0.4,-0.5 2.3,-3.4 4.2,-7.2 5.3,-11.4 2.4,-9.2 1.9,-19 1.9,-28.4 0,-0.2 0,-0.4 0,-0.6l5.7,-5.6 -0.3,0.1 4.1,1.3 45.3,45 9.6,9.6 14.3,14.3 100.8,100.8 17.2,17.2 16.3,16.3 30.3,-30.3 -192.9,-191.5c0.5,-0.5 1.1,-1.6 1.4,-2.3 0.3,-0.6 0.5,-1.2 0.4,-1.9 0,-0.8 -0.2,-1.6 -0.6,-2.3 -0.1,-0.3 -0.3,-0.7 -0.4,-1 -0.2,-0.4 -0.5,-0.7 -0.9,-1.1l27.8,-27.8 191.1,-191.1c0.7,0.4 1.5,0.6 2.5,0.7 4.1,0 8.2,0.1 11.9,1.9 0.5,0.3 1.3,0.7 2.1,1.1 1.7,2.3 3.5,4.5 5.7,6.2 2.7,2.1 8.2,3 9.4,0.3z"
android:fillColor="#AD2A2A"/>
<path
android:pathData="m616.3,796.7c0.4,1.2 0.5,2.4 0.5,3.7l-5.8,73.3c-0.4,5.2 -5,9.3 -10.6,9.3h-187.2c-4,0 -7.7,-2.3 -9.5,-5.6l-30.9,-57.4c-0.2,-0.3 -0.3,-0.6 -0.4,-0.9l-29.1,-70.5c-1.1,-2.5 -0.9,-5.4 0.3,-7.8l48.3,-94.5c1.2,-2.3 1.4,-5 0.5,-7.4l-23.6,-65.4c-0.8,-2.3 -0.7,-4.9 0.3,-7.1l39.4,-83.9c4,-8.4 17.1,-7.7 19.9,1.1l12.3,38.2 37.5,100.4c1,2.8 3.4,5 6.4,6l80,27.3c3.1,1.1 5.5,3.4 6.5,6.3z"
android:fillColor="#FFFFFF"/>
<path
android:pathData="m386.7,253.5c0,-22.9 14.5,-42.6 35.3,-51.8 -1.5,-2.5 -2.4,-5.2 -2.4,-8.1 0,-11.1 12.8,-20.1 28.5,-20.1 0.4,0 0.7,0 1.1,0 6.5,-10.8 18.9,-18.1 33.1,-18.1 1,0 2,0 3,0.1 1.3,0.1 2.6,-0.5 3.3,-1.5 10.5,-16 37.1,-27.4 68.2,-27.4 11.5,0 22.4,1.6 32.1,4.3 2.3,-3.8 7.4,-6.4 13.3,-6.4 6.7,0 12.4,3.4 14.1,8.1 8.2,-9.5 22.1,-15.7 37.9,-15.7 25.2,0 45.6,15.9 45.6,35.5 0,2.4 -0.3,4.7 -0.9,7 -0.4,1.6 0.5,3.2 2.2,3.8 16.1,5.9 27,17.1 27,29.9 0,14.6 -14.1,27.1 -34,32 -1.6,0.4 -2.6,1.8 -2.6,3.3 0,0.1 0,0.2 0,0.3 0,11.3 -11.2,20.6 -25.6,21.6 0.1,0.5 0.1,1 0.1,1.6 0,21.7 -41.3,39.2 -92.2,39.2 -11,0 -21.5,-0.8 -31.2,-2.3 0,0.2 0,0.3 0,0.5 0,9 -11.6,16.3 -25.8,16.3 -0.8,0 -1.5,0 -2.2,-0.1 1,2.2 1.5,4.5 1.5,6.9 0,14 -17.7,25.3 -39.6,25.3 -2.4,0 -4.7,-0.1 -7,-0.4 -1.8,-0.2 -3.5,0.9 -3.9,2.6 -1.9,7 -8,12.1 -15.3,12.1 -8.8,0 -15.8,-7.5 -15.8,-16.7 0,-4.3 1.5,-8.2 4,-11.1 0.9,-1 1.2,-2.4 0.6,-3.6 -1.4,-2.6 -2,-5.3 -2,-8.2v0c0,-1.6 -1.3,-2.9 -2.9,-3.3 -27.1,-6 -47.5,-28.6 -47.5,-55.6z"
android:fillColor="#FFFFFF"/>
<path
android:pathData="m870.4,883h-124.4c-3.6,0 -6.9,-1.8 -8.9,-4.6l-83.7,-117.7c-0.5,-0.8 -1,-1.6 -1.3,-2.5l-41.5,-121.2c-0.8,-2.4 -2.7,-4.5 -5.1,-5.7l-101.6,-51.3c-2.8,-1.4 -4.8,-4 -5.4,-6.9l-15,-74.4c-0.2,-1.2 -0.7,-2.4 -1.5,-3.5l-34.5,-50.7c-1.9,-2.8 -2.2,-6.2 -0.8,-9.2l21,-44.9c1.6,-3.4 5.1,-5.7 9.1,-5.9l39,-2.3c2.3,-0.1 4.4,-0.9 6.1,-2.3l28.7,-22.3c5.4,-4.2 13.6,-2.4 16.5,3.5l98.9,201.2c0.4,0.9 0.7,1.8 0.9,2.7l12.2,80.9c0.3,1.9 1.1,3.6 2.4,5l197,215.6c5.8,6.4 0.9,16.5 -8.1,16.5z"
android:fillColor="#FFFFFF"/>
<path
android:pathData="m335.8,838.9c0.8,2.6 0.4,5.4 -1,7.7l-19.3,31.3c-1.9,3.1 -5.4,5.1 -9.2,5.1h-180.6c-8.4,0 -13.5,-8.8 -9,-15.4l116.3,-171.3c0.7,-1 1.1,-2.1 1.4,-3.2l53.3,-227.6c0.6,-2.7 2.4,-5 5,-6.4l72.2,-39.6c2.6,-1.4 4.4,-3.7 5,-6.5l9.7,-42.3c2,-8.8 14.6,-10.7 19.6,-3l3.5,5.6c1.5,2.4 1.9,5.4 0.9,8.1l-65.8,190.2c-0.5,1.5 -0.7,3.1 -0.4,4.7l16.4,91c0.3,1.8 0.1,3.7 -0.7,5.4l-39.1,87.8c-0.9,2.1 -1.1,4.4 -0.4,6.5z"
android:fillColor="#FFFFFF"/>
<path
android:pathData="m424.22,657.05 l1580.54,-0.05c0.54,0 0,292 0,292l-1580.54,-0.03c-10.78,0 -19.46,-8.68 -19.46,-19.46l0,-252.99c0,-10.78 8.68,-19.46 19.46,-19.46z"
android:strokeAlpha="0.49803922"
android:strokeLineJoin="round"
android:strokeWidth="4"
android:fillColor="#3f3f3f"
android:strokeColor="#00000000"
android:fillType="nonZero"
android:fillAlpha="1"
android:strokeLineCap="square"/>
<path
android:pathData="m728.71,710.91l0,19.89l-88.7,0l0,59.3l77.04,0L717.05,810l-77.04,0l0,65.39l89.84,0l0,19.9L616.56,895.29L616.56,791.16l-52.35,-52.35 -0.77,-0.18c5.41,6.64 9.65,14.32 12.69,23.09 3.72,10.39 5.62,21.92 5.7,34.6L581.84,809.87c-0.08,12.67 -1.98,24.25 -5.7,34.72 -3.63,10.39 -8.95,19.35 -15.97,26.87 -6.93,7.43 -15.46,13.26 -25.6,17.49 -7.54,3.1 -15.86,5.07 -24.97,5.89 -3.04,0.27 -6.16,0.42 -9.37,0.45L457.53,895.29l0,-6.55l-0.37,6.82 53.8,53.45l415.85,0c0.24,0 0.47,-0.02 0.69,-0.05L1132.91,948.97L953.5,769.55l-58.39,-58.39 -0.28,0.06 -58.03,184.06l-20.4,0l-44.66,-141.34zM783.29,711.07 L826.41,857.52 850.08,777.86zM509.6,711.29c1.52,0.15 3.01,0.33 4.49,0.54 -1.47,-0.21 -2.97,-0.39 -4.49,-0.54zM481.35,730.04l0,146.11l18.88,0c9.97,-0.08 18.59,-1.81 25.85,-5.19 7.27,-3.46 13.26,-8.15 17.99,-14.07 4.82,-5.91 8.36,-12.88 10.64,-20.91 2.37,-8.03 3.59,-16.73 3.68,-26.11l0,-13.81c-0.08,-9.38 -1.31,-18.04 -3.68,-25.98 -2.37,-8.03 -5.91,-14.95 -10.64,-20.78 -4.73,-5.91 -10.73,-10.56 -17.99,-13.94 -7.27,-3.38 -15.88,-5.15 -25.85,-5.32zM560.17,734.86c0.65,0.69 1.26,1.4 1.88,2.11 -0.61,-0.72 -1.23,-1.42 -1.88,-2.11z"
android:strokeAlpha="1"
android:strokeLineJoin="miter"
android:strokeWidth="1.94642854"
android:fillColor="#000000"
android:strokeColor="#00000000"
android:fillAlpha="0.18431373"
android:strokeLineCap="butt"/>
<path
android:pathData="m457.53,895.28l0,-184.51l42.7,0q19.26,0.25 34.34,6.59 15.21,6.21 25.6,17.49 10.52,11.15 15.97,26.86 5.58,15.59 5.7,34.59l0,13.56q-0.13,19.01 -5.7,34.72 -5.45,15.59 -15.97,26.86 -10.39,11.15 -25.6,17.49 -15.08,6.21 -34.34,6.34zM481.35,730.04l0,146.11l18.88,0q14.95,-0.13 25.85,-5.2 10.9,-5.2 17.99,-14.07 7.22,-8.87 10.64,-20.91 3.55,-12.04 3.67,-26.1l0,-13.81q-0.13,-14.07 -3.67,-25.98 -3.55,-12.04 -10.64,-20.78 -7.1,-8.87 -17.99,-13.94 -10.9,-5.07 -25.85,-5.32z"
android:fillColor="#ffffff"
android:strokeColor="#00000000"
android:fillAlpha="1"/>
<path
android:pathData="M717.05,810L640.01,810l0,65.39l89.84,0l0,19.9l-113.29,0l0,-184.51l112.15,0l0,20.02L640.01,730.8l0,59.31l77.05,0z"
android:fillColor="#ffffff"
android:strokeColor="#00000000"
android:fillAlpha="1"/>
<path
android:pathData="m826.41,857.52 l43.59,-146.74l24.96,0l-58.16,184.51L816.4,895.28l-58.29,-184.51l25.09,0z"
android:fillColor="#ffffff"
android:strokeColor="#00000000"
android:fillAlpha="1"/>
</group>
</vector>

View File

@ -0,0 +1,34 @@
<vector xmlns:android="http://schemas.android.com/apk/res/android"
android:width="108dp"
android:height="108dp"
android:viewportWidth="1926"
android:viewportHeight="1926">
<path
android:fillColor="#ad2a2a"
android:pathData="M2465,1904v561h-759L704,1463l-120,-120 -1,-1 5,-9 1,-3c9,-15 20,-29 31,-43l16,-19 3,-4 21,-30 3,-6c7,-11 12,-23 18,-35l14,-24 3,-4v-1a234,234 0,0 0,20 -53v-1l1,-3c4,-15 7,-31 13,-46l5,-9v-1c5,-10 11,-19 14, -30 2,-9 3,-19 3,-28v-1,-21l3,-17v-3l4,-17h1v-1c0,-2 -1,-4 -3,-4l8,-8 4,1c13,-4 25,-10 37,-17l8,-5 22,-16 9,-9v-1l5, -11c3,-9 2,-19 2,-29l6,-6 4,2 45,45 10,9 14,14 101,101 17,17 16,17 31,-31 -193,-191 1,-2 1,-2 -1,-3v-1l-1,-1 27,-27 192,-192 2,1a27,27 0,0 1,14 3l6,6c2,2 8,3 9,1l1310,1310z" />
<path
android:fillColor="#fff"
android:pathData="M1082,1260v4l-6,73c0,5 -5,9 -10,9H879c-4,0 -8,-2 -10,-5l-31,-58 -29,-71v-8l48,-94c2,-3 2,-5 1, -8l-24,-65c-1,-2 0,-5 1,-7l39,-84c4,-8 17,-8 20,1l12,38 38,101c1,2 3,5 6,6l80,27c3,1 6,3 7,6l45,135zM852,717c0,-23 15,-43 35,-52l-2,-8c0,-11 13,-20 29,-20h1a38,38 0,0 1,36 -18l3,-2c11,-16 37,-27 68,-27 12,0 23,2 32,4 3,-3 8,-6 14,-6s12,3 14,8c8,-9 22,-16 38,-16 25,0 45,16 45,36l-1,7 3,4c16,6 27,17 27,30 0,14 -15,27 -34,32 -2,0 -3,1 -3,3 0,11 -11,21 -26,22v1c0,22 -41,40 -92,40 -11,0 -21,-1 -31,-3v1c0,9 -12,16 -26,16h-2l2,7c0,14 -18,25 -40,25h-7l-4, 2c-2,7 -8,12 -15,12 -9,0 -16,-7 -16,-16 0,-5 1,-8 4,-11l1,-4c-2,-3 -2,-5 -2,-8 0,-2 -2,-3 -3,-3 -27,-6 -48,-29 -48,-56z" />
<path
android:fillColor="#fff"
android:pathData="M1336,1346h-125c-3,0 -6,-1 -8,-4l-84,-118 -1,-2 -42,-122 -5,-5 -102,-52 -5,-6 -15,-75 -2,-3 -34,-51c-2,-3 -2,-6 -1,-9l21,-45c2,-4 5,-6 9,-6l39,-2c3,0 5,-1 6,-3l29,-22c5,-4 14,-2 17,4l98,201 1,2 13,81 2,5 197,216c6,6 1,16 -8,16zM801,1302c1,3 1,6 -1,8l-19,31c-2,3 -5,5 -9,5H591c-8,0 -13,-8 -9,-15l116,-171 2,-3 53, -228c1,-3 3,-5 5,-6l72,-40c3,-1 5,-4 5,-7l10,-42c2,-9 15,-11 20,-3l3,6c2,2 2,5 1,8l-66,190v5l16,91v5l-40,88v6l22,72z" />
<path
android:fillColor="#3f3f3f"
android:pathData="M886.7,1119.5h1580.5c0.6,0 0,292 0,292H886.7a19.4,19.4 0,0 1,-19.5 -19.5v-253c0,-10.8 8.7,-19.5 19.5,-19.5z"
android:strokeWidth="4"
android:strokeAlpha=".5"
android:strokeColor="#000"
android:strokeLineCap="square"
android:strokeLineJoin="round" />
<path
android:fillAlpha=".2"
android:fillColor="#000"
android:pathData="M1191.2,1173.4v19.9h-88.7v59.3h77v19.9h-77v65.4h89.8v19.9L1079,1357.8v-104.2l-52.3,-52.3 -0.8, -0.2a75.1,75.1 0,0 1,12.7 23,104 104,0 0,1 5.7,34.7v13.5c0,12.7 -2,24.3 -5.7,34.8a72.8,72.8 0,0 1,-41.6 44.4,85.5 85.5,0 0,1 -34.3,6.3L920,1357.8v-6.6l-0.4,6.8 53.8,53.5h622L1416,1232l-58.4,-58.4h-0.3l-58,184.1h -20.4l-44.7,-141.3zM1245.8,1173.5l43,146.5 23.7,-79.7zM972.1,1173.8zM943.8,1192.5v146.1h18.9a62,62 0,0 0,25.8 -5.2,50.3 50.3,0 0,0 18,-14c4.9,-6 8.4,-13 10.7,-21 2.3,-8 3.6,-16.7 3.7,-26v-13.9c-0.1,-9.4 -1.4,-18 -3.7,-26 -2.4,-8 -6,-15 -10.7,-20.7a49.3,49.3 0,0 0,-18 -14,63.4 63.4,0 0,0 -25.8,-5.3zM1022.6,1197.3l2,2.1 -2,-2z"
android:strokeWidth="1.9"
android:strokeColor="#000" />
<path
android:fillColor="#fff"
android:pathData="M920,1357.7v-184.5h42.7q19.3,0.3 34.3,6.6 15.2,6.2 25.6,17.5 10.6,11.2 16,26.9 5.6,15.6 5.7, 34.6v13.5q-0.1,19 -5.7,34.7 -5.4,15.6 -16,26.9 -10.4,11.2 -25.6,17.5 -15,6.2 -34.3,6.3zM943.8,1192.5v146.1h18.9q15, -0.1 25.8,-5.2 11,-5.2 18,-14 7.3,-9 10.7,-21 3.5,-12 3.6,-26v-13.9q0,-14 -3.6,-26t-10.7,-20.7q-7,-9 -18,-14 -10.9,-5 -25.8,-5.3zM1179.5,1272.5h-77v65.4h89.8v19.9L1079,1357.8v-184.6h112.2v20h-88.7v59.4h77zM1288.9, 1320l43.6,-146.8h25l-58.2,184.6h-20.4l-58.3,-184.6h25z"
android:strokeWidth="1"
android:strokeColor="#000" />
</vector>

View File

@ -1,5 +1,5 @@
<?xml version="1.0" encoding="utf-8"?>
<adaptive-icon xmlns:android="http://schemas.android.com/apk/res/android">
<background android:drawable="@color/ic_launcher_background"/>
<foreground android:drawable="@drawable/ic_launcher_foreground"/>
<background android:drawable="@color/colorPrimary" />
<foreground android:drawable="@drawable/ic_launcher_foreground_dev" />
</adaptive-icon>

View File

@ -1,5 +1,5 @@
<?xml version="1.0" encoding="utf-8"?>
<adaptive-icon xmlns:android="http://schemas.android.com/apk/res/android">
<background android:drawable="@color/ic_launcher_background"/>
<foreground android:drawable="@drawable/ic_launcher_foreground"/>
<background android:drawable="@color/colorPrimary" />
<foreground android:drawable="@drawable/ic_launcher_foreground_dev" />
</adaptive-icon>

View File

@ -1,3 +0,0 @@
<resources>
<string name="app_name">Wulkanowy DEV</string>
</resources>

View File

@ -1,4 +0,0 @@
<?xml version="1.0" encoding="utf-8"?>
<resources>
<color name="ic_launcher_background">#D32F2F</color>
</resources>

View File

@ -0,0 +1,17 @@
@file:Suppress("UNUSED_PARAMETER")
package io.github.wulkanowy.utils
import android.content.Context
import timber.log.Timber
fun initCrashlytics(context: Context, appInfo: AppInfo) {
// do nothing
}
class CrashlyticsTree : Timber.Tree() {
override fun log(priority: Int, tag: String?, message: String, t: Throwable?) {
// do nothing
}
}

View File

@ -0,0 +1,13 @@
package io.github.wulkanowy.utils
import javax.inject.Inject
import javax.inject.Singleton
@Singleton
class FirebaseAnalyticsHelper @Inject constructor() {
@Suppress("UNUSED_PARAMETER")
fun logEvent(name: String, vararg params: Pair<String, Any?>) {
// do nothing
}
}

View File

@ -4,8 +4,6 @@
package="io.github.wulkanowy"
android:installLocation="internalOnly">
<uses-sdk tools:overrideLibrary="com.readystatesoftware.chuck" />
<uses-permission android:name="android.permission.INTERNET" />
<uses-permission android:name="android.permission.ACCESS_NETWORK_STATE" />
<uses-permission android:name="android.permission.RECEIVE_BOOT_COMPLETED" />
@ -45,11 +43,12 @@
android:name=".ui.modules.message.send.SendMessageActivity"
android:configChanges="orientation|screenSize"
android:label="@string/send_message_title"
android:windowSoftInputMode="adjustResize"
android:theme="@style/WulkanowyTheme.NoActionBar" />
<activity
android:name=".ui.modules.timetablewidget.TimetableWidgetConfigureActivity"
android:noHistory="true"
android:excludeFromRecents="true"
android:noHistory="true"
android:theme="@style/WulkanowyTheme.WidgetAccountSwitcher">
<intent-filter>
<action android:name="android.appwidget.action.APPWIDGET_CONFIGURE" />
@ -57,8 +56,8 @@
</activity>
<activity
android:name=".ui.modules.luckynumberwidget.LuckyNumberWidgetConfigureActivity"
android:noHistory="true"
android:excludeFromRecents="true"
android:noHistory="true"
android:theme="@style/WulkanowyTheme.WidgetAccountSwitcher">
<intent-filter>
<action android:name="android.appwidget.action.APPWIDGET_CONFIGURE" />
@ -80,7 +79,6 @@
android:name="android.appwidget.provider"
android:resource="@xml/provider_widget_timetable" />
</receiver>
<receiver
android:name=".ui.modules.luckynumberwidget.LuckyNumberWidgetProvider"
android:label="@string/lucky_number_title">

View File

@ -1,35 +1,46 @@
package io.github.wulkanowy
import android.content.Context
import android.util.Log.INFO
import android.util.Log.VERBOSE
import androidx.multidex.MultiDex
import androidx.work.Configuration
import androidx.work.WorkManager
import com.crashlytics.android.Crashlytics
import com.crashlytics.android.core.CrashlyticsCore
import com.jakewharton.threetenabp.AndroidThreeTen
import com.yariksoffice.lingver.Lingver
import dagger.android.AndroidInjector
import dagger.android.support.DaggerApplication
import eu.davidea.flexibleadapter.FlexibleAdapter
import eu.davidea.flexibleadapter.utils.Log
import io.fabric.sdk.android.Fabric
import io.github.wulkanowy.BuildConfig.CRASHLYTICS_ENABLED
import io.github.wulkanowy.BuildConfig.DEBUG
import io.github.wulkanowy.data.db.SharedPrefProvider
import io.github.wulkanowy.data.db.SharedPrefProvider.Companion.APP_VERSION_CODE_KEY
import io.github.wulkanowy.di.DaggerAppComponent
import io.github.wulkanowy.services.sync.SyncWorkerFactory
import io.github.wulkanowy.ui.base.ThemeManager
import io.github.wulkanowy.utils.ActivityLifecycleLogger
import io.github.wulkanowy.utils.AppInfo
import io.github.wulkanowy.utils.CrashlyticsTree
import io.github.wulkanowy.utils.DebugLogTree
import io.github.wulkanowy.utils.initCrashlytics
import io.reactivex.exceptions.UndeliverableException
import io.reactivex.plugins.RxJavaPlugins
import timber.log.Timber
import java.io.IOException
import javax.inject.Inject
class WulkanowyApp : DaggerApplication() {
class WulkanowyApp : DaggerApplication(), Configuration.Provider {
@Inject
lateinit var workerFactory: SyncWorkerFactory
@Inject
lateinit var themeManager: ThemeManager
@Inject
lateinit var sharedPrefProvider: SharedPrefProvider
@Inject
lateinit var appInfo: AppInfo
override fun attachBaseContext(base: Context?) {
super.attachBaseContext(base)
MultiDex.install(this)
@ -38,15 +49,17 @@ class WulkanowyApp : DaggerApplication() {
override fun onCreate() {
super.onCreate()
AndroidThreeTen.init(this)
WorkManager.initialize(this, Configuration.Builder().setWorkerFactory(workerFactory).build())
RxJavaPlugins.setErrorHandler(::onError)
Lingver.init(this)
themeManager.applyDefaultTheme()
migrateSharedPreferences()
initCrashlytics()
initLogging()
initCrashlytics(this, appInfo)
}
private fun initLogging() {
if (DEBUG) {
if (appInfo.isDebug) {
Timber.plant(DebugLogTree())
FlexibleAdapter.enableLogs(Log.Level.DEBUG)
} else {
@ -55,19 +68,27 @@ class WulkanowyApp : DaggerApplication() {
registerActivityLifecycleCallbacks(ActivityLifecycleLogger())
}
private fun initCrashlytics() {
Fabric.with(Fabric.Builder(this).kits(
Crashlytics.Builder().core(CrashlyticsCore.Builder().disabled(!CRASHLYTICS_ENABLED).build()).build()
).debuggable(DEBUG).build())
private fun migrateSharedPreferences() {
if (sharedPrefProvider.getLong(APP_VERSION_CODE_KEY, -1) < 48) { // #596
sharedPrefProvider.delete(getString(R.string.pref_key_grade_modifier_plus))
sharedPrefProvider.delete(getString(R.string.pref_key_grade_modifier_minus))
}
}
private fun onError(error: Throwable) {
if (error is UndeliverableException && error.cause is IOException || error.cause is InterruptedException) {
Timber.e(error.cause, "An undeliverable error occurred")
//RxJava's too deep stack traces may cause SOE on older android devices
val cause = error.cause
if (error is UndeliverableException && cause is IOException || cause is InterruptedException || cause is StackOverflowError) {
Timber.e(cause, "An undeliverable error occurred")
} else throw error
}
override fun applicationInjector(): AndroidInjector<out DaggerApplication> {
return DaggerAppComponent.factory().create(this)
}
override fun getWorkManagerConfiguration() = Configuration.Builder()
.setWorkerFactory(workerFactory)
.setMinimumLoggingLevel(if (appInfo.isDebug) VERBOSE else INFO)
.build()
}

View File

@ -85,6 +85,10 @@ internal class RepositoryModule {
@Provides
fun provideGradeStatisticsDao(database: AppDatabase) = database.gradeStatistics
@Singleton
@Provides
fun provideGradePointsStatisticsDao(database: AppDatabase) = database.gradePointsStatistics
@Singleton
@Provides
fun provideMessagesDao(database: AppDatabase) = database.messagesDao
@ -132,4 +136,16 @@ internal class RepositoryModule {
@Singleton
@Provides
fun provideRecipientDao(database: AppDatabase) = database.recipientDao
@Singleton
@Provides
fun provideMobileDevicesDao(database: AppDatabase) = database.mobileDeviceDao
@Singleton
@Provides
fun provideTeacherDao(database: AppDatabase) = database.teacherDao
@Singleton
@Provides
fun provideSchoolInfoDao(database: AppDatabase) = database.schoolDao
}

View File

@ -6,44 +6,58 @@ import androidx.room.Room
import androidx.room.RoomDatabase
import androidx.room.RoomDatabase.JournalMode.TRUNCATE
import androidx.room.TypeConverters
import androidx.room.migration.Migration
import io.github.wulkanowy.data.db.dao.AttendanceDao
import io.github.wulkanowy.data.db.dao.AttendanceSummaryDao
import io.github.wulkanowy.data.db.dao.CompletedLessonsDao
import io.github.wulkanowy.data.db.dao.ExamDao
import io.github.wulkanowy.data.db.dao.GradeDao
import io.github.wulkanowy.data.db.dao.GradePointsStatisticsDao
import io.github.wulkanowy.data.db.dao.GradeStatisticsDao
import io.github.wulkanowy.data.db.dao.GradeSummaryDao
import io.github.wulkanowy.data.db.dao.HomeworkDao
import io.github.wulkanowy.data.db.dao.LuckyNumberDao
import io.github.wulkanowy.data.db.dao.MessagesDao
import io.github.wulkanowy.data.db.dao.MobileDeviceDao
import io.github.wulkanowy.data.db.dao.NoteDao
import io.github.wulkanowy.data.db.dao.RecipientDao
import io.github.wulkanowy.data.db.dao.ReportingUnitDao
import io.github.wulkanowy.data.db.dao.SchoolDao
import io.github.wulkanowy.data.db.dao.SemesterDao
import io.github.wulkanowy.data.db.dao.StudentDao
import io.github.wulkanowy.data.db.dao.SubjectDao
import io.github.wulkanowy.data.db.dao.TeacherDao
import io.github.wulkanowy.data.db.dao.TimetableDao
import io.github.wulkanowy.data.db.entities.Attendance
import io.github.wulkanowy.data.db.entities.AttendanceSummary
import io.github.wulkanowy.data.db.entities.CompletedLesson
import io.github.wulkanowy.data.db.entities.Exam
import io.github.wulkanowy.data.db.entities.Grade
import io.github.wulkanowy.data.db.entities.GradePointsStatistics
import io.github.wulkanowy.data.db.entities.GradeStatistics
import io.github.wulkanowy.data.db.entities.GradeSummary
import io.github.wulkanowy.data.db.entities.Homework
import io.github.wulkanowy.data.db.entities.LuckyNumber
import io.github.wulkanowy.data.db.entities.Message
import io.github.wulkanowy.data.db.entities.MobileDevice
import io.github.wulkanowy.data.db.entities.Note
import io.github.wulkanowy.data.db.entities.Recipient
import io.github.wulkanowy.data.db.entities.ReportingUnit
import io.github.wulkanowy.data.db.entities.School
import io.github.wulkanowy.data.db.entities.Semester
import io.github.wulkanowy.data.db.entities.Student
import io.github.wulkanowy.data.db.entities.Subject
import io.github.wulkanowy.data.db.entities.Teacher
import io.github.wulkanowy.data.db.entities.Timetable
import io.github.wulkanowy.data.db.migrations.Migration10
import io.github.wulkanowy.data.db.migrations.Migration11
import io.github.wulkanowy.data.db.migrations.Migration12
import io.github.wulkanowy.data.db.migrations.Migration13
import io.github.wulkanowy.data.db.migrations.Migration14
import io.github.wulkanowy.data.db.migrations.Migration15
import io.github.wulkanowy.data.db.migrations.Migration16
import io.github.wulkanowy.data.db.migrations.Migration17
import io.github.wulkanowy.data.db.migrations.Migration18
import io.github.wulkanowy.data.db.migrations.Migration2
import io.github.wulkanowy.data.db.migrations.Migration3
import io.github.wulkanowy.data.db.migrations.Migration4
@ -66,6 +80,7 @@ import javax.inject.Singleton
Grade::class,
GradeSummary::class,
GradeStatistics::class,
GradePointsStatistics::class,
Message::class,
Note::class,
Homework::class,
@ -73,7 +88,10 @@ import javax.inject.Singleton
LuckyNumber::class,
CompletedLesson::class,
ReportingUnit::class,
Recipient::class
Recipient::class,
MobileDevice::class,
Teacher::class,
School::class
],
version = AppDatabase.VERSION_SCHEMA,
exportSchema = true
@ -82,27 +100,36 @@ import javax.inject.Singleton
abstract class AppDatabase : RoomDatabase() {
companion object {
const val VERSION_SCHEMA = 13
const val VERSION_SCHEMA = 18
fun getMigrations(): Array<Migration> {
return arrayOf(
Migration2(),
Migration3(),
Migration4(),
Migration5(),
Migration6(),
Migration7(),
Migration8(),
Migration9(),
Migration10(),
Migration11(),
Migration12(),
Migration13(),
Migration14(),
Migration15(),
Migration16(),
Migration17(),
Migration18()
)
}
fun newInstance(context: Context): AppDatabase {
return Room.databaseBuilder(context, AppDatabase::class.java, "wulkanowy_database")
.setJournalMode(TRUNCATE)
.fallbackToDestructiveMigrationFrom(VERSION_SCHEMA + 1)
.fallbackToDestructiveMigrationOnDowngrade()
.addMigrations(
Migration2(),
Migration3(),
Migration4(),
Migration5(),
Migration6(),
Migration7(),
Migration8(),
Migration9(),
Migration10(),
Migration11(),
Migration12(),
Migration13()
)
.addMigrations(*getMigrations())
.build()
}
}
@ -125,6 +152,8 @@ abstract class AppDatabase : RoomDatabase() {
abstract val gradeStatistics: GradeStatisticsDao
abstract val gradePointsStatistics: GradePointsStatisticsDao
abstract val messagesDao: MessagesDao
abstract val noteDao: NoteDao
@ -140,4 +169,10 @@ abstract class AppDatabase : RoomDatabase() {
abstract val reportingUnitDao: ReportingUnitDao
abstract val recipientDao: RecipientDao
abstract val mobileDeviceDao: MobileDeviceDao
abstract val teacherDao: TeacherDao
abstract val schoolDao: SchoolDao
}

View File

@ -1,18 +1,19 @@
package io.github.wulkanowy.data.db
import android.annotation.SuppressLint
import android.content.SharedPreferences
import androidx.core.content.edit
import javax.inject.Inject
import javax.inject.Singleton
@Singleton
@SuppressLint("ApplySharedPref")
class SharedPrefHelper @Inject constructor(private val sharedPref: SharedPreferences) {
class SharedPrefProvider @Inject constructor(private val sharedPref: SharedPreferences) {
companion object {
const val APP_VERSION_CODE_KEY = "app_version_code"
}
fun putLong(key: String, value: Long, sync: Boolean = false) {
sharedPref.edit().putLong(key, value).apply {
if (sync) commit() else apply()
}
sharedPref.edit(sync) { putLong(key, value) }
}
fun getLong(key: String, defaultValue: Long) = sharedPref.getLong(key, defaultValue)

View File

@ -1,8 +1,6 @@
package io.github.wulkanowy.data.db.dao
import androidx.room.Dao
import androidx.room.Delete
import androidx.room.Insert
import androidx.room.Query
import io.github.wulkanowy.data.db.entities.Attendance
import io.reactivex.Maybe
@ -11,13 +9,7 @@ import javax.inject.Singleton
@Singleton
@Dao
interface AttendanceDao {
@Insert
fun insertAll(exams: List<Attendance>): List<Long>
@Delete
fun deleteAll(exams: List<Attendance>)
interface AttendanceDao : BaseDao<Attendance> {
@Query("SELECT * FROM Attendance WHERE diary_id = :diaryId AND student_id = :studentId AND date >= :from AND date <= :end")
fun loadAll(diaryId: Int, studentId: Int, from: LocalDate, end: LocalDate): Maybe<List<Attendance>>

View File

@ -1,20 +1,12 @@
package io.github.wulkanowy.data.db.dao
import androidx.room.Dao
import androidx.room.Delete
import androidx.room.Insert
import androidx.room.Query
import io.github.wulkanowy.data.db.entities.AttendanceSummary
import io.reactivex.Maybe
@Dao
interface AttendanceSummaryDao {
@Insert
fun insertAll(exams: List<AttendanceSummary>): List<Long>
@Delete
fun deleteAll(exams: List<AttendanceSummary>)
interface AttendanceSummaryDao : BaseDao<AttendanceSummary> {
@Query("SELECT * FROM AttendanceSummary WHERE diary_id = :diaryId AND student_id = :studentId AND subject_id = :subjectId")
fun loadAll(diaryId: Int, studentId: Int, subjectId: Int): Maybe<List<AttendanceSummary>>

View File

@ -0,0 +1,17 @@
package io.github.wulkanowy.data.db.dao
import androidx.room.Delete
import androidx.room.Insert
import androidx.room.Update
interface BaseDao<T> {
@Insert
fun insertAll(items: List<T>): List<Long>
@Update
fun updateAll(items: List<T>)
@Delete
fun deleteAll(items: List<T>)
}

View File

@ -1,8 +1,6 @@
package io.github.wulkanowy.data.db.dao
import androidx.room.Dao
import androidx.room.Delete
import androidx.room.Insert
import androidx.room.Query
import io.github.wulkanowy.data.db.entities.CompletedLesson
import io.reactivex.Maybe
@ -11,13 +9,7 @@ import javax.inject.Singleton
@Singleton
@Dao
interface CompletedLessonsDao {
@Insert
fun insertAll(exams: List<CompletedLesson>)
@Delete
fun deleteAll(exams: List<CompletedLesson>)
interface CompletedLessonsDao : BaseDao<CompletedLesson> {
@Query("SELECT * FROM CompletedLesson WHERE diary_id = :diaryId AND student_id = :studentId AND date >= :from AND date <= :end")
fun loadAll(diaryId: Int, studentId: Int, from: LocalDate, end: LocalDate): Maybe<List<CompletedLesson>>

View File

@ -1,8 +1,6 @@
package io.github.wulkanowy.data.db.dao
import androidx.room.Dao
import androidx.room.Delete
import androidx.room.Insert
import androidx.room.Query
import io.github.wulkanowy.data.db.entities.Exam
import io.reactivex.Maybe
@ -11,13 +9,7 @@ import javax.inject.Singleton
@Singleton
@Dao
interface ExamDao {
@Insert
fun insertAll(exams: List<Exam>): List<Long>
@Delete
fun deleteAll(exams: List<Exam>)
interface ExamDao : BaseDao<Exam> {
@Query("SELECT * FROM Exams WHERE diary_id = :diaryId AND student_id = :studentId AND date >= :from AND date <= :end")
fun loadAll(diaryId: Int, studentId: Int, from: LocalDate, end: LocalDate): Maybe<List<Exam>>

View File

@ -1,26 +1,14 @@
package io.github.wulkanowy.data.db.dao
import androidx.room.Dao
import androidx.room.Delete
import androidx.room.Insert
import androidx.room.Query
import androidx.room.Update
import io.github.wulkanowy.data.db.entities.Grade
import io.reactivex.Maybe
import javax.inject.Singleton
@Singleton
@Dao
interface GradeDao {
@Insert
fun insertAll(grades: List<Grade>)
@Update
fun updateAll(grade: List<Grade>)
@Delete
fun deleteAll(grades: List<Grade>)
interface GradeDao : BaseDao<Grade> {
@Query("SELECT * FROM Grades WHERE semester_id = :semesterId AND student_id = :studentId")
fun loadAll(semesterId: Int, studentId: Int): Maybe<List<Grade>>

View File

@ -0,0 +1,18 @@
package io.github.wulkanowy.data.db.dao
import androidx.room.Dao
import androidx.room.Query
import io.github.wulkanowy.data.db.entities.GradePointsStatistics
import io.reactivex.Maybe
import javax.inject.Singleton
@Singleton
@Dao
interface GradePointsStatisticsDao : BaseDao<GradePointsStatistics> {
@Query("SELECT * FROM GradesPointsStatistics WHERE student_id = :studentId AND semester_id = :semesterId AND subject = :subjectName")
fun loadSubject(semesterId: Int, studentId: Int, subjectName: String): Maybe<GradePointsStatistics>
@Query("SELECT * FROM GradesPointsStatistics WHERE student_id = :studentId AND semester_id = :semesterId")
fun loadAll(semesterId: Int, studentId: Int): Maybe<List<GradePointsStatistics>>
}

View File

@ -1,8 +1,6 @@
package io.github.wulkanowy.data.db.dao
import androidx.room.Dao
import androidx.room.Delete
import androidx.room.Insert
import androidx.room.Query
import io.github.wulkanowy.data.db.entities.GradeStatistics
import io.reactivex.Maybe
@ -10,13 +8,7 @@ import javax.inject.Singleton
@Singleton
@Dao
interface GradeStatisticsDao {
@Insert
fun insertAll(gradesStatistics: List<GradeStatistics>)
@Delete
fun deleteAll(gradesStatistics: List<GradeStatistics>)
interface GradeStatisticsDao : BaseDao<GradeStatistics> {
@Query("SELECT * FROM GradesStatistics WHERE student_id = :studentId AND semester_id = :semesterId AND subject = :subjectName AND is_semester = :isSemester")
fun loadSubject(semesterId: Int, studentId: Int, subjectName: String, isSemester: Boolean): Maybe<List<GradeStatistics>>

View File

@ -1,8 +1,6 @@
package io.github.wulkanowy.data.db.dao
import androidx.room.Dao
import androidx.room.Delete
import androidx.room.Insert
import androidx.room.Query
import io.github.wulkanowy.data.db.entities.GradeSummary
import io.reactivex.Maybe
@ -10,13 +8,7 @@ import javax.inject.Singleton
@Singleton
@Dao
interface GradeSummaryDao {
@Insert
fun insertAll(gradesSummary: List<GradeSummary>)
@Delete
fun deleteAll(gradesSummary: List<GradeSummary>)
interface GradeSummaryDao : BaseDao<GradeSummary> {
@Query("SELECT * FROM GradesSummary WHERE student_id = :studentId AND semester_id = :semesterId")
fun loadAll(semesterId: Int, studentId: Int): Maybe<List<GradeSummary>>

View File

@ -1,8 +1,6 @@
package io.github.wulkanowy.data.db.dao
import androidx.room.Dao
import androidx.room.Delete
import androidx.room.Insert
import androidx.room.Query
import io.github.wulkanowy.data.db.entities.Homework
import io.reactivex.Maybe
@ -11,13 +9,7 @@ import javax.inject.Singleton
@Singleton
@Dao
interface HomeworkDao {
@Insert
fun insertAll(homework: List<Homework>)
@Delete
fun deleteAll(homework: List<Homework>)
interface HomeworkDao : BaseDao<Homework> {
@Query("SELECT * FROM Homework WHERE semester_id = :semesterId AND student_id = :studentId AND date >= :from AND date <= :end")
fun loadAll(semesterId: Int, studentId: Int, from: LocalDate, end: LocalDate): Maybe<List<Homework>>

View File

@ -1,10 +1,7 @@
package io.github.wulkanowy.data.db.dao
import androidx.room.Dao
import androidx.room.Delete
import androidx.room.Insert
import androidx.room.Query
import androidx.room.Update
import io.github.wulkanowy.data.db.entities.LuckyNumber
import io.reactivex.Maybe
import org.threeten.bp.LocalDate
@ -12,18 +9,8 @@ import javax.inject.Singleton
@Singleton
@Dao
interface LuckyNumberDao {
@Insert
fun insert(luckyNumber: LuckyNumber)
@Update
fun update(luckyNumber: LuckyNumber)
@Delete
fun delete(luckyNumber: LuckyNumber)
interface LuckyNumberDao : BaseDao<LuckyNumber> {
@Query("SELECT * FROM LuckyNumbers WHERE student_id = :studentId AND date = :date")
fun load(studentId: Int, date: LocalDate): Maybe<LuckyNumber>
}

View File

@ -1,30 +1,18 @@
package io.github.wulkanowy.data.db.dao
import androidx.room.Dao
import androidx.room.Delete
import androidx.room.Insert
import androidx.room.Query
import androidx.room.Update
import io.github.wulkanowy.data.db.entities.Message
import io.reactivex.Maybe
@Dao
interface MessagesDao {
@Insert
fun insertAll(messages: List<Message>)
@Delete
fun deleteAll(messages: List<Message>)
@Update
fun updateAll(messages: List<Message>)
interface MessagesDao : BaseDao<Message> {
@Query("SELECT * FROM Messages WHERE student_id = :studentId AND folder_id = :folder AND removed = 0 ORDER BY date DESC")
fun loadAll(studentId: Int, folder: Int): Maybe<List<Message>>
@Query("SELECT * FROM Messages WHERE student_id = :studentId AND real_id = :id")
fun load(studentId: Int, id: Int): Maybe<Message>
@Query("SELECT * FROM Messages WHERE id = :id")
fun load(id: Long): Maybe<Message>
@Query("SELECT * FROM Messages WHERE student_id = :studentId AND removed = 1 ORDER BY date DESC")
fun loadDeleted(studentId: Int): Maybe<List<Message>>

View File

@ -0,0 +1,13 @@
package io.github.wulkanowy.data.db.dao
import androidx.room.Dao
import androidx.room.Query
import io.github.wulkanowy.data.db.entities.MobileDevice
import io.reactivex.Maybe
@Dao
interface MobileDeviceDao : BaseDao<MobileDevice> {
@Query("SELECT * FROM MobileDevices WHERE student_id = :studentId ORDER BY date DESC")
fun loadAll(studentId: Int): Maybe<List<MobileDevice>>
}

View File

@ -1,28 +1,15 @@
package io.github.wulkanowy.data.db.dao
import androidx.room.Dao
import androidx.room.Delete
import androidx.room.Insert
import androidx.room.Query
import androidx.room.Update
import io.github.wulkanowy.data.db.entities.Note
import io.reactivex.Maybe
import javax.inject.Singleton
@Singleton
@Dao
interface NoteDao {
@Insert
fun insertAll(notes: List<Note>)
@Update
fun updateAll(notes: List<Note>)
@Delete
fun deleteAll(notes: List<Note>)
interface NoteDao : BaseDao<Note> {
@Query("SELECT * FROM Notes WHERE student_id = :studentId")
fun loadAll(studentId: Int): Maybe<List<Note>>
}

View File

@ -1,8 +1,6 @@
package io.github.wulkanowy.data.db.dao
import androidx.room.Dao
import androidx.room.Delete
import androidx.room.Insert
import androidx.room.Query
import io.github.wulkanowy.data.db.entities.Recipient
import io.reactivex.Maybe
@ -10,13 +8,7 @@ import javax.inject.Singleton
@Singleton
@Dao
interface RecipientDao {
@Insert
fun insertAll(messages: List<Recipient>)
@Delete
fun deleteAll(messages: List<Recipient>)
interface RecipientDao : BaseDao<Recipient> {
@Query("SELECT * FROM Recipients WHERE student_id = :studentId AND role = :role AND unit_id = :unitId")
fun load(studentId: Int, role: Int, unitId: Int): Maybe<List<Recipient>>

View File

@ -1,8 +1,6 @@
package io.github.wulkanowy.data.db.dao
import androidx.room.Dao
import androidx.room.Delete
import androidx.room.Insert
import androidx.room.Query
import io.github.wulkanowy.data.db.entities.ReportingUnit
import io.reactivex.Maybe
@ -10,13 +8,7 @@ import javax.inject.Singleton
@Singleton
@Dao
interface ReportingUnitDao {
@Insert
fun insertAll(reportingUnits: List<ReportingUnit>)
@Delete
fun deleteAll(reportingUnits: List<ReportingUnit>)
interface ReportingUnitDao : BaseDao<ReportingUnit> {
@Query("SELECT * FROM ReportingUnits WHERE student_id = :studentId")
fun load(studentId: Int): Maybe<List<ReportingUnit>>

View File

@ -0,0 +1,15 @@
package io.github.wulkanowy.data.db.dao
import androidx.room.Dao
import androidx.room.Query
import io.github.wulkanowy.data.db.entities.School
import io.reactivex.Maybe
import javax.inject.Singleton
@Singleton
@Dao
interface SchoolDao : BaseDao<School> {
@Query("SELECT * FROM School WHERE student_id = :studentId AND class_id = :classId")
fun load(studentId: Int, classId: Int): Maybe<School>
}

View File

@ -1,8 +1,6 @@
package io.github.wulkanowy.data.db.dao
import androidx.room.Dao
import androidx.room.Delete
import androidx.room.Insert
import androidx.room.Query
import io.github.wulkanowy.data.db.entities.Semester
import io.reactivex.Maybe
@ -10,13 +8,7 @@ import javax.inject.Singleton
@Singleton
@Dao
interface SemesterDao {
@Insert
fun insertAll(semester: List<Semester>)
@Delete
fun deleteAll(semester: List<Semester>)
interface SemesterDao : BaseDao<Semester> {
@Query("SELECT * FROM Semesters WHERE student_id = :studentId AND class_id = :classId")
fun loadAll(studentId: Int, classId: Int): Maybe<List<Semester>>

View File

@ -1,20 +1,12 @@
package io.github.wulkanowy.data.db.dao
import androidx.room.Dao
import androidx.room.Delete
import androidx.room.Insert
import androidx.room.Query
import io.github.wulkanowy.data.db.entities.Subject
import io.reactivex.Maybe
@Dao
interface SubjectDao {
@Insert
fun insertAll(subjects: List<Subject>): List<Long>
@Delete
fun deleteAll(subjects: List<Subject>)
interface SubjectDao : BaseDao<Subject> {
@Query("SELECT * FROM Subjects WHERE diary_id = :diaryId AND student_id = :studentId")
fun loadAll(diaryId: Int, studentId: Int): Maybe<List<Subject>>

View File

@ -0,0 +1,15 @@
package io.github.wulkanowy.data.db.dao
import androidx.room.Dao
import androidx.room.Query
import io.github.wulkanowy.data.db.entities.Teacher
import io.reactivex.Maybe
import javax.inject.Singleton
@Singleton
@Dao
interface TeacherDao : BaseDao<Teacher> {
@Query("SELECT * FROM Teachers WHERE student_id = :studentId AND class_id = :classId")
fun loadAll(studentId: Int, classId: Int): Maybe<List<Teacher>>
}

View File

@ -1,8 +1,6 @@
package io.github.wulkanowy.data.db.dao
import androidx.room.Dao
import androidx.room.Delete
import androidx.room.Insert
import androidx.room.Query
import io.github.wulkanowy.data.db.entities.Timetable
import io.reactivex.Maybe
@ -11,13 +9,7 @@ import javax.inject.Singleton
@Singleton
@Dao
interface TimetableDao {
@Insert
fun insertAll(exams: List<Timetable>): List<Long>
@Delete
fun deleteAll(exams: List<Timetable>)
interface TimetableDao : BaseDao<Timetable> {
@Query("SELECT * FROM Timetable WHERE diary_id = :diaryId AND student_id = :studentId AND date >= :from AND date <= :end")
fun loadAll(diaryId: Int, studentId: Int, from: LocalDate, end: LocalDate): Maybe<List<Timetable>>

View File

@ -0,0 +1,24 @@
package io.github.wulkanowy.data.db.entities
import androidx.room.ColumnInfo
import androidx.room.Entity
import androidx.room.PrimaryKey
@Entity(tableName = "GradesPointsStatistics")
data class GradePointsStatistics(
@ColumnInfo(name = "student_id")
val studentId: Int,
@ColumnInfo(name = "semester_id")
val semesterId: Int,
val subject: String,
val others: Double,
val student: Double
) {
@PrimaryKey(autoGenerate = true)
var id: Long = 0
}

View File

@ -13,11 +13,26 @@ data class GradeSummary(
@ColumnInfo(name = "student_id")
val studentId: Int,
val position: Int,
val subject: String,
@ColumnInfo(name = "predicted_grade")
val predictedGrade: String,
val finalGrade: String
@ColumnInfo(name = "final_grade")
val finalGrade: String,
@ColumnInfo(name = "proposed_points")
val proposedPoints: String,
@ColumnInfo(name = "final_points")
val finalPoints: String,
@ColumnInfo(name = "points_sum")
val pointsSum: String,
val average: Double
) {
@PrimaryKey(autoGenerate = true)
var id: Long = 0

View File

@ -0,0 +1,25 @@
package io.github.wulkanowy.data.db.entities
import androidx.room.ColumnInfo
import androidx.room.Entity
import androidx.room.PrimaryKey
import org.threeten.bp.LocalDateTime
import java.io.Serializable
@Entity(tableName = "MobileDevices")
data class MobileDevice(
@ColumnInfo(name = "student_id")
val studentId: Int,
@ColumnInfo(name = "device_id")
val deviceId: Int,
val name: String,
val date: LocalDateTime
) : Serializable {
@PrimaryKey(autoGenerate = true)
var id: Long = 0
}

View File

@ -0,0 +1,30 @@
package io.github.wulkanowy.data.db.entities
import androidx.room.ColumnInfo
import androidx.room.Entity
import androidx.room.PrimaryKey
import java.io.Serializable
@Entity(tableName = "School")
data class School(
@ColumnInfo(name = "student_id")
val studentId: Int,
@ColumnInfo(name = "class_id")
val classId: Int,
val name: String,
val address: String,
val contact: String,
val headmaster: String,
val pedagogue: String
) : Serializable {
@PrimaryKey(autoGenerate = true)
var id: Long = 0
}

View File

@ -0,0 +1,27 @@
package io.github.wulkanowy.data.db.entities
import androidx.room.ColumnInfo
import androidx.room.Entity
import androidx.room.PrimaryKey
import java.io.Serializable
@Entity(tableName = "Teachers")
data class Teacher(
@ColumnInfo(name = "student_id")
val studentId: Int,
@ColumnInfo(name = "class_id")
val classId: Int,
val subject: String,
val name: String,
@ColumnInfo(name = "short_name")
val shortName: String
) : Serializable {
@PrimaryKey(autoGenerate = true)
var id: Long = 0
}

View File

@ -0,0 +1,26 @@
package io.github.wulkanowy.data.db.migrations
import androidx.room.migration.Migration
import androidx.sqlite.db.SupportSQLiteDatabase
class Migration14 : Migration(13, 14) {
override fun migrate(database: SupportSQLiteDatabase) {
database.execSQL("DROP TABLE IF EXISTS GradesSummary")
database.execSQL("""
CREATE TABLE IF NOT EXISTS GradesSummary (
id INTEGER PRIMARY KEY AUTOINCREMENT NOT NULL,
semester_id INTEGER NOT NULL,
student_id INTEGER NOT NULL,
position INTEGER NOT NULL,
subject TEXT NOT NULL,
predicted_grade TEXT NOT NULL,
final_grade TEXT NOT NULL,
proposed_points TEXT NOT NULL,
final_points TEXT NOT NULL,
points_sum TEXT NOT NULL,
average REAL NOT NULL
)
""")
}
}

View File

@ -0,0 +1,19 @@
package io.github.wulkanowy.data.db.migrations
import androidx.room.migration.Migration
import androidx.sqlite.db.SupportSQLiteDatabase
class Migration15 : Migration(14, 15) {
override fun migrate(database: SupportSQLiteDatabase) {
database.execSQL("""
CREATE TABLE IF NOT EXISTS MobileDevices (
id INTEGER PRIMARY KEY AUTOINCREMENT NOT NULL,
student_id INTEGER NOT NULL,
device_id INTEGER NOT NULL,
name TEXT NOT NULL,
date INTEGER NOT NULL
)
""")
}
}

View File

@ -0,0 +1,20 @@
package io.github.wulkanowy.data.db.migrations
import androidx.room.migration.Migration
import androidx.sqlite.db.SupportSQLiteDatabase
class Migration16 : Migration(15, 16) {
override fun migrate(database: SupportSQLiteDatabase) {
database.execSQL("""
CREATE TABLE IF NOT EXISTS Teachers (
id INTEGER PRIMARY KEY AUTOINCREMENT NOT NULL,
student_id INTEGER NOT NULL,
class_id INTEGER NOT NULL,
subject TEXT NOT NULL,
name TEXT NOT NULL,
short_name TEXT NOT NULL
)
""")
}
}

View File

@ -0,0 +1,29 @@
package io.github.wulkanowy.data.db.migrations
import androidx.room.migration.Migration
import androidx.sqlite.db.SupportSQLiteDatabase
class Migration17 : Migration(16, 17) {
override fun migrate(database: SupportSQLiteDatabase) {
createGradesPointsStatisticsTable(database)
truncateSemestersTable(database)
}
private fun createGradesPointsStatisticsTable(database: SupportSQLiteDatabase) {
database.execSQL("""
CREATE TABLE IF NOT EXISTS GradesPointsStatistics(
id INTEGER PRIMARY KEY AUTOINCREMENT NOT NULL,
student_id INTEGER NOT NULL,
semester_id INTEGER NOT NULL,
subject TEXT NOT NULL,
others REAL NOT NULL,
student REAL NOT NULL
)
""")
}
private fun truncateSemestersTable(database: SupportSQLiteDatabase) {
database.execSQL("DELETE FROM Semesters")
}
}

View File

@ -0,0 +1,22 @@
package io.github.wulkanowy.data.db.migrations
import androidx.room.migration.Migration
import androidx.sqlite.db.SupportSQLiteDatabase
class Migration18 : Migration(17, 18) {
override fun migrate(database: SupportSQLiteDatabase) {
database.execSQL("""
CREATE TABLE IF NOT EXISTS School (
id INTEGER PRIMARY KEY AUTOINCREMENT NOT NULL,
student_id INTEGER NOT NULL,
class_id INTEGER NOT NULL,
name TEXT NOT NULL,
address TEXT NOT NULL,
contact TEXT NOT NULL,
headmaster TEXT NOT NULL,
pedagogue TEXT NOT NULL
)
""")
}
}

View File

@ -0,0 +1,12 @@
package io.github.wulkanowy.data.pojos
data class MobileDeviceToken(
val token: String,
val symbol: String,
val pin: String,
val qr: String
)

View File

@ -6,6 +6,7 @@ import io.github.wulkanowy.data.db.entities.Attendance
import io.github.wulkanowy.data.db.entities.Semester
import io.github.wulkanowy.utils.friday
import io.github.wulkanowy.utils.monday
import io.github.wulkanowy.utils.uniqueSubtract
import io.reactivex.Single
import org.threeten.bp.LocalDate
import java.net.UnknownHostException
@ -31,8 +32,8 @@ class AttendanceRepository @Inject constructor(
local.getAttendance(semester, dates.first, dates.second)
.toSingle(emptyList())
.doOnSuccess { oldAttendance ->
local.deleteAttendance(oldAttendance - newAttendance)
local.saveAttendance(newAttendance - oldAttendance)
local.deleteAttendance(oldAttendance.uniqueSubtract(newAttendance))
local.saveAttendance(newAttendance.uniqueSubtract(oldAttendance))
}
}.flatMap {
local.getAttendance(semester, dates.first, dates.second)

View File

@ -4,6 +4,7 @@ import com.github.pwittchen.reactivenetwork.library.rx2.ReactiveNetwork
import com.github.pwittchen.reactivenetwork.library.rx2.internet.observing.InternetObservingSettings
import io.github.wulkanowy.data.db.entities.AttendanceSummary
import io.github.wulkanowy.data.db.entities.Semester
import io.github.wulkanowy.utils.uniqueSubtract
import io.reactivex.Single
import java.net.UnknownHostException
import javax.inject.Inject
@ -25,8 +26,8 @@ class AttendanceSummaryRepository @Inject constructor(
}.flatMap { new ->
local.getAttendanceSummary(semester, subjectId).toSingle(emptyList())
.doOnSuccess { old ->
local.deleteAttendanceSummary(old - new)
local.saveAttendanceSummary(new - old)
local.deleteAttendanceSummary(old.uniqueSubtract(new))
local.saveAttendanceSummary(new.uniqueSubtract(old))
}
}.flatMap { local.getAttendanceSummary(semester, subjectId).toSingle(emptyList()) })
}

View File

@ -6,6 +6,7 @@ import io.github.wulkanowy.data.db.entities.CompletedLesson
import io.github.wulkanowy.data.db.entities.Semester
import io.github.wulkanowy.utils.friday
import io.github.wulkanowy.utils.monday
import io.github.wulkanowy.utils.uniqueSubtract
import io.reactivex.Single
import org.threeten.bp.LocalDate
import java.net.UnknownHostException
@ -31,8 +32,8 @@ class CompletedLessonsRepository @Inject constructor(
local.getCompletedLessons(semester, dates.first, dates.second)
.toSingle(emptyList())
.doOnSuccess { old ->
local.deleteCompleteLessons(old - new)
local.saveCompletedLessons(new - old)
local.deleteCompleteLessons(old.uniqueSubtract(new))
local.saveCompletedLessons(new.uniqueSubtract(old))
}
}.flatMap {
local.getCompletedLessons(semester, dates.first, dates.second)

View File

@ -6,6 +6,7 @@ import io.github.wulkanowy.data.db.entities.Exam
import io.github.wulkanowy.data.db.entities.Semester
import io.github.wulkanowy.utils.friday
import io.github.wulkanowy.utils.monday
import io.github.wulkanowy.utils.uniqueSubtract
import io.reactivex.Single
import org.threeten.bp.LocalDate
import java.net.UnknownHostException
@ -27,12 +28,12 @@ class ExamRepository @Inject constructor(
.flatMap {
if (it) remote.getExams(semester, dates.first, dates.second)
else Single.error(UnknownHostException())
}.flatMap { newExams ->
}.flatMap { new ->
local.getExams(semester, dates.first, dates.second)
.toSingle(emptyList())
.doOnSuccess { oldExams ->
local.deleteExams(oldExams - newExams)
local.saveExams(newExams - oldExams)
.doOnSuccess { old ->
local.deleteExams(old.uniqueSubtract(new))
local.saveExams(new.uniqueSubtract(old))
}
}.flatMap {
local.getExams(semester, dates.first, dates.second)

View File

@ -5,6 +5,7 @@ import com.github.pwittchen.reactivenetwork.library.rx2.internet.observing.Inter
import io.github.wulkanowy.data.db.entities.Grade
import io.github.wulkanowy.data.db.entities.Semester
import io.github.wulkanowy.data.db.entities.Student
import io.github.wulkanowy.utils.uniqueSubtract
import io.reactivex.Completable
import io.reactivex.Single
import java.net.UnknownHostException
@ -24,13 +25,12 @@ class GradeRepository @Inject constructor(
.flatMap {
if (it) remote.getGrades(semester)
else Single.error(UnknownHostException())
}.flatMap { newGrades ->
}.flatMap { new ->
local.getGrades(semester).toSingle(emptyList())
.doOnSuccess { oldGrades ->
val notifyBreakDate = oldGrades.maxBy { it.date }?.date
?: student.registrationDate.toLocalDate()
local.deleteGrades(oldGrades - newGrades)
local.saveGrades((newGrades - oldGrades)
.doOnSuccess { old ->
val notifyBreakDate = old.maxBy { it.date }?.date ?: student.registrationDate.toLocalDate()
local.deleteGrades(old.uniqueSubtract(new))
local.saveGrades(new.uniqueSubtract(old)
.onEach {
if (it.date >= notifyBreakDate) it.apply {
isRead = false

View File

@ -18,9 +18,14 @@ class GradeSummaryRemote @Inject constructor(private val api: Api) {
GradeSummary(
semesterId = semester.semesterId,
studentId = semester.studentId,
position = it.order,
subject = it.name,
predictedGrade = it.predicted,
finalGrade = it.final
finalGrade = it.final,
pointsSum = it.pointsSum,
proposedPoints = it.proposedPoints,
finalPoints = it.finalPoints,
average = it.average
)
}
}

View File

@ -4,6 +4,7 @@ import com.github.pwittchen.reactivenetwork.library.rx2.ReactiveNetwork
import com.github.pwittchen.reactivenetwork.library.rx2.internet.observing.InternetObservingSettings
import io.github.wulkanowy.data.db.entities.GradeSummary
import io.github.wulkanowy.data.db.entities.Semester
import io.github.wulkanowy.utils.uniqueSubtract
import io.reactivex.Single
import java.net.UnknownHostException
import javax.inject.Inject
@ -22,11 +23,11 @@ class GradeSummaryRepository @Inject constructor(
.flatMap {
if (it) remote.getGradeSummary(semester)
else Single.error(UnknownHostException())
}.flatMap { newGradesSummary ->
}.flatMap { new ->
local.getGradesSummary(semester).toSingle(emptyList())
.doOnSuccess { oldGradesSummary ->
local.deleteGradesSummary(oldGradesSummary - newGradesSummary)
local.saveGradesSummary(newGradesSummary - oldGradesSummary)
.doOnSuccess { old ->
local.deleteGradesSummary(old.uniqueSubtract(new))
local.saveGradesSummary(new.uniqueSubtract(old))
}
}.flatMap { local.getGradesSummary(semester).toSingle(emptyList()) })
}

View File

@ -1,6 +1,8 @@
package io.github.wulkanowy.data.repositories.gradestatistics
import io.github.wulkanowy.data.db.dao.GradePointsStatisticsDao
import io.github.wulkanowy.data.db.dao.GradeStatisticsDao
import io.github.wulkanowy.data.db.entities.GradePointsStatistics
import io.github.wulkanowy.data.db.entities.GradeStatistics
import io.github.wulkanowy.data.db.entities.Semester
import io.reactivex.Maybe
@ -8,27 +10,57 @@ import javax.inject.Inject
import javax.inject.Singleton
@Singleton
class GradeStatisticsLocal @Inject constructor(private val gradeStatisticsDb: GradeStatisticsDao) {
class GradeStatisticsLocal @Inject constructor(
private val gradeStatisticsDb: GradeStatisticsDao,
private val gradePointsStatisticsDb: GradePointsStatisticsDao
) {
fun getGradesStatistics(semester: Semester, isSemester: Boolean): Maybe<List<GradeStatistics>> {
return gradeStatisticsDb.loadAll(semester.semesterId, semester.studentId, isSemester)
.filter { !it.isEmpty() }
return gradeStatisticsDb.loadAll(semester.semesterId, semester.studentId, isSemester).filter { it.isNotEmpty() }
}
fun getGradesPointsStatistics(semester: Semester): Maybe<List<GradePointsStatistics>> {
return gradePointsStatisticsDb.loadAll(semester.semesterId, semester.studentId).filter { it.isNotEmpty() }
}
fun getGradesStatistics(semester: Semester, isSemester: Boolean, subjectName: String): Maybe<List<GradeStatistics>> {
return (if ("Wszystkie" == subjectName) gradeStatisticsDb.loadAll(semester.semesterId, semester.studentId, isSemester).map { list ->
list.groupBy { it.grade }.map {
GradeStatistics(semester.studentId, semester.semesterId, subjectName, it.key, it.value.fold(0) { acc, e -> acc + e.amount }, false)
return when (subjectName) {
"Wszystkie" -> gradeStatisticsDb.loadAll(semester.semesterId, semester.studentId, isSemester).map { list ->
list.groupBy { it.grade }.map {
GradeStatistics(semester.studentId, semester.semesterId, subjectName, it.key,
it.value.fold(0) { acc, e -> acc + e.amount }, false)
}
}
else -> gradeStatisticsDb.loadSubject(semester.semesterId, semester.studentId, subjectName, isSemester)
}.filter { it.isNotEmpty() }
}
fun getGradesPointsStatistics(semester: Semester, subjectName: String): Maybe<GradePointsStatistics> {
return when (subjectName) {
"Wszystkie" -> gradePointsStatisticsDb.loadAll(semester.semesterId, semester.studentId).flatMap { list ->
if (list.isEmpty()) return@flatMap Maybe.empty<GradePointsStatistics>()
Maybe.just(GradePointsStatistics(semester.studentId, semester.semesterId, subjectName,
list.fold(.0) { acc, e -> acc + e.others },
list.fold(.0) { acc, e -> acc + e.student })
)
}
else -> gradePointsStatisticsDb.loadSubject(semester.semesterId, semester.studentId, subjectName)
}
else gradeStatisticsDb.loadSubject(semester.semesterId, semester.studentId, subjectName, isSemester)).filter { !it.isEmpty() }
}
fun saveGradesStatistics(gradesStatistics: List<GradeStatistics>) {
gradeStatisticsDb.insertAll(gradesStatistics)
}
fun saveGradesPointsStatistics(gradePointsStatistics: List<GradePointsStatistics>) {
gradePointsStatisticsDb.insertAll(gradePointsStatistics)
}
fun deleteGradesStatistics(gradesStatistics: List<GradeStatistics>) {
gradeStatisticsDb.deleteAll(gradesStatistics)
}
fun deleteGradesPointsStatistics(gradesPointsStatistics: List<GradePointsStatistics>) {
gradePointsStatisticsDb.deleteAll(gradesPointsStatistics)
}
}

View File

@ -1,6 +1,7 @@
package io.github.wulkanowy.data.repositories.gradestatistics
import io.github.wulkanowy.api.Api
import io.github.wulkanowy.data.db.entities.GradePointsStatistics
import io.github.wulkanowy.data.db.entities.GradeStatistics
import io.github.wulkanowy.data.db.entities.Semester
import io.reactivex.Single
@ -12,7 +13,10 @@ class GradeStatisticsRemote @Inject constructor(private val api: Api) {
fun getGradeStatistics(semester: Semester, isSemester: Boolean): Single<List<GradeStatistics>> {
return Single.just(api.apply { diaryId = semester.diaryId })
.flatMap { it.getGradesStatistics(semester.semesterId, isSemester) }
.flatMap {
if (isSemester) it.getGradesAnnualStatistics(semester.semesterId)
else it.getGradesPartialStatistics(semester.semesterId)
}
.map { gradeStatistics ->
gradeStatistics.map {
GradeStatistics(
@ -26,4 +30,20 @@ class GradeStatisticsRemote @Inject constructor(private val api: Api) {
}
}
}
fun getGradePointsStatistics(semester: Semester): Single<List<GradePointsStatistics>> {
return Single.just(api.apply { diaryId = semester.diaryId })
.flatMap { it.getGradesPointsStatistics(semester.semesterId) }
.map { gradePointsStatistics ->
gradePointsStatistics.map {
GradePointsStatistics(
semesterId = semester.semesterId,
studentId = semester.studentId,
subject = it.subject,
others = it.others,
student = it.student
)
}
}
}
}

View File

@ -2,8 +2,11 @@ package io.github.wulkanowy.data.repositories.gradestatistics
import com.github.pwittchen.reactivenetwork.library.rx2.ReactiveNetwork
import com.github.pwittchen.reactivenetwork.library.rx2.internet.observing.InternetObservingSettings
import io.github.wulkanowy.data.db.entities.GradePointsStatistics
import io.github.wulkanowy.data.db.entities.GradeStatistics
import io.github.wulkanowy.data.db.entities.Semester
import io.github.wulkanowy.utils.uniqueSubtract
import io.reactivex.Maybe
import io.reactivex.Single
import java.net.UnknownHostException
import javax.inject.Inject
@ -22,12 +25,27 @@ class GradeStatisticsRepository @Inject constructor(
.flatMap {
if (it) remote.getGradeStatistics(semester, isSemester)
else Single.error(UnknownHostException())
}.flatMap { newGradesStats ->
}.flatMap { new ->
local.getGradesStatistics(semester, isSemester).toSingle(emptyList())
.doOnSuccess { oldGradesStats ->
local.deleteGradesStatistics(oldGradesStats - newGradesStats)
local.saveGradesStatistics(newGradesStats - oldGradesStats)
.doOnSuccess { old ->
local.deleteGradesStatistics(old.uniqueSubtract(new))
local.saveGradesStatistics(new.uniqueSubtract(old))
}
}.flatMap { local.getGradesStatistics(semester, isSemester, subjectName).toSingle(emptyList()) })
}
fun getGradesPointsStatistics(semester: Semester, subjectName: String, forceRefresh: Boolean): Maybe<GradePointsStatistics> {
return local.getGradesPointsStatistics(semester, subjectName).filter { !forceRefresh }
.switchIfEmpty(ReactiveNetwork.checkInternetConnectivity(settings)
.flatMapMaybe {
if (it) remote.getGradePointsStatistics(semester).toMaybe()
else Maybe.error(UnknownHostException())
}.flatMap { new ->
local.getGradesPointsStatistics(semester).defaultIfEmpty(emptyList())
.doOnSuccess { old ->
local.deleteGradesPointsStatistics(old.uniqueSubtract(new))
local.saveGradesPointsStatistics(new.uniqueSubtract(old))
}
}.flatMap { local.getGradesPointsStatistics(semester, subjectName) })
}
}

View File

@ -6,6 +6,7 @@ import io.github.wulkanowy.data.db.entities.Homework
import io.github.wulkanowy.data.db.entities.Semester
import io.github.wulkanowy.utils.friday
import io.github.wulkanowy.utils.monday
import io.github.wulkanowy.utils.uniqueSubtract
import io.reactivex.Single
import org.threeten.bp.LocalDate
import java.net.UnknownHostException
@ -26,11 +27,11 @@ class HomeworkRepository @Inject constructor(
.flatMap {
if (it) remote.getHomework(semester, monday, friday)
else Single.error(UnknownHostException())
}.flatMap { newGrades ->
}.flatMap { new ->
local.getHomework(semester, monday, friday).toSingle(emptyList())
.doOnSuccess { oldGrades ->
local.deleteHomework(oldGrades - newGrades)
local.saveHomework(newGrades - oldGrades)
.doOnSuccess { old ->
local.deleteHomework(old.uniqueSubtract(new))
local.saveHomework(new.uniqueSubtract(old))
}
}.flatMap { local.getHomework(semester, monday, friday).toSingle(emptyList()) })
}

View File

@ -12,15 +12,15 @@ import javax.inject.Singleton
class LuckyNumberLocal @Inject constructor(private val luckyNumberDb: LuckyNumberDao) {
fun saveLuckyNumber(luckyNumber: LuckyNumber) {
luckyNumberDb.insert(luckyNumber)
luckyNumberDb.insertAll(listOf(luckyNumber))
}
fun updateLuckyNumber(luckyNumber: LuckyNumber) {
luckyNumberDb.update(luckyNumber)
luckyNumberDb.updateAll(listOf(luckyNumber))
}
fun deleteLuckyNumber(luckyNumber: LuckyNumber) {
luckyNumberDb.delete(luckyNumber)
luckyNumberDb.deleteAll(listOf(luckyNumber))
}
fun getLuckyNumber(semester: Semester, date: LocalDate): Maybe<LuckyNumber> {

View File

@ -23,8 +23,8 @@ class MessageLocal @Inject constructor(private val messagesDb: MessagesDao) {
messagesDb.deleteAll(messages)
}
fun getMessage(student: Student, id: Int): Maybe<Message> {
return messagesDb.load(student.id.toInt(), id)
fun getMessage(id: Long): Maybe<Message> {
return messagesDb.load(id)
}
fun getMessages(student: Student, folder: MessageFolder): Maybe<List<Message>> {

View File

@ -11,7 +11,6 @@ import io.reactivex.Single
import org.threeten.bp.LocalDateTime.now
import javax.inject.Inject
import javax.inject.Singleton
import io.github.wulkanowy.api.messages.Message as ApiMessage
import io.github.wulkanowy.api.messages.Recipient as ApiRecipient
@Singleton

View File

@ -8,6 +8,7 @@ import io.github.wulkanowy.data.db.entities.Message
import io.github.wulkanowy.data.db.entities.Recipient
import io.github.wulkanowy.data.db.entities.Student
import io.github.wulkanowy.data.repositories.message.MessageFolder.RECEIVED
import io.github.wulkanowy.utils.uniqueSubtract
import io.reactivex.Completable
import io.reactivex.Maybe
import io.reactivex.Single
@ -34,8 +35,8 @@ class MessageRepository @Inject constructor(
}.flatMap { new ->
local.getMessages(student, folder).toSingle(emptyList())
.doOnSuccess { old ->
local.deleteMessages(old - new)
local.saveMessages((new - old)
local.deleteMessages(old.uniqueSubtract(new))
local.saveMessages(new.uniqueSubtract(old)
.onEach {
it.isNotified = !notify
})
@ -45,14 +46,14 @@ class MessageRepository @Inject constructor(
}
}
fun getMessage(student: Student, messageId: Int, markAsRead: Boolean = false): Single<Message> {
fun getMessage(student: Student, messageDbId: Long, markAsRead: Boolean = false): Single<Message> {
return Single.just(apiHelper.initApi(student))
.flatMap { _ ->
local.getMessage(student, messageId)
local.getMessage(messageDbId)
.filter { !it.content.isNullOrEmpty() }
.switchIfEmpty(ReactiveNetwork.checkInternetConnectivity(settings)
.flatMap {
if (it) local.getMessage(student, messageId).toSingle()
if (it) local.getMessage(messageDbId).toSingle()
else Single.error(UnknownHostException())
}
.flatMap { dbMessage ->
@ -63,7 +64,7 @@ class MessageRepository @Inject constructor(
}))
}
}.flatMap {
local.getMessage(student, messageId).toSingle()
local.getMessage(messageDbId).toSingle()
}
)
}

View File

@ -0,0 +1,24 @@
package io.github.wulkanowy.data.repositories.mobiledevice
import io.github.wulkanowy.data.db.dao.MobileDeviceDao
import io.github.wulkanowy.data.db.entities.MobileDevice
import io.github.wulkanowy.data.db.entities.Semester
import io.reactivex.Maybe
import javax.inject.Inject
import javax.inject.Singleton
@Singleton
class MobileDeviceLocal @Inject constructor(private val mobileDb: MobileDeviceDao) {
fun saveDevices(devices: List<MobileDevice>) {
mobileDb.insertAll(devices)
}
fun deleteDevices(devices: List<MobileDevice>) {
mobileDb.deleteAll(devices)
}
fun getDevices(semester: Semester): Maybe<List<MobileDevice>> {
return mobileDb.loadAll(semester.studentId).filter { it.isNotEmpty() }
}
}

View File

@ -0,0 +1,47 @@
package io.github.wulkanowy.data.repositories.mobiledevice
import io.github.wulkanowy.api.Api
import io.github.wulkanowy.data.db.entities.MobileDevice
import io.github.wulkanowy.data.db.entities.Semester
import io.github.wulkanowy.data.pojos.MobileDeviceToken
import io.github.wulkanowy.utils.toLocalDateTime
import io.reactivex.Single
import javax.inject.Inject
import javax.inject.Singleton
@Singleton
class MobileDeviceRemote @Inject constructor(private val api: Api) {
fun getDevices(semester: Semester): Single<List<MobileDevice>> {
return Single.just(api.apply { diaryId = semester.diaryId })
.flatMap { api.getRegisteredDevices() }
.map { devices ->
devices.map {
MobileDevice(
studentId = semester.studentId,
date = it.date.toLocalDateTime(),
deviceId = it.id,
name = it.name
)
}
}
}
fun unregisterDevice(semester: Semester, device: MobileDevice): Single<Boolean> {
return Single.just(api.apply { diaryId = semester.diaryId })
.flatMap { api.unregisterDevice(device.deviceId) }
}
fun getToken(semester: Semester): Single<MobileDeviceToken> {
return Single.just(api.apply { diaryId = semester.diaryId })
.flatMap { api.getToken() }
.map {
MobileDeviceToken(
token = it.token,
symbol = it.symbol,
pin = it.pin,
qr = it.qrCodeImage
)
}
}
}

View File

@ -0,0 +1,52 @@
package io.github.wulkanowy.data.repositories.mobiledevice
import com.github.pwittchen.reactivenetwork.library.rx2.ReactiveNetwork
import com.github.pwittchen.reactivenetwork.library.rx2.internet.observing.InternetObservingSettings
import io.github.wulkanowy.data.db.entities.MobileDevice
import io.github.wulkanowy.data.db.entities.Semester
import io.github.wulkanowy.data.pojos.MobileDeviceToken
import io.github.wulkanowy.utils.uniqueSubtract
import io.reactivex.Single
import java.net.UnknownHostException
import javax.inject.Inject
import javax.inject.Singleton
@Singleton
class MobileDeviceRepository @Inject constructor(
private val settings: InternetObservingSettings,
private val local: MobileDeviceLocal,
private val remote: MobileDeviceRemote
) {
fun getDevices(semester: Semester, forceRefresh: Boolean = false): Single<List<MobileDevice>> {
return local.getDevices(semester).filter { !forceRefresh }
.switchIfEmpty(ReactiveNetwork.checkInternetConnectivity(settings)
.flatMap {
if (it) remote.getDevices(semester)
else Single.error(UnknownHostException())
}.flatMap { new ->
local.getDevices(semester).toSingle(emptyList())
.doOnSuccess { old ->
local.deleteDevices(old uniqueSubtract new)
local.saveDevices(new uniqueSubtract old)
}
}
).flatMap { local.getDevices(semester).toSingle(emptyList()) }
}
fun unregisterDevice(semester: Semester, device: MobileDevice): Single<Boolean> {
return ReactiveNetwork.checkInternetConnectivity(settings)
.flatMap {
if (it) remote.unregisterDevice(semester, device)
else Single.error(UnknownHostException())
}
}
fun getToken(semester: Semester): Single<MobileDeviceToken> {
return ReactiveNetwork.checkInternetConnectivity(settings)
.flatMap {
if (it) remote.getToken(semester)
else Single.error(UnknownHostException())
}
}
}

View File

@ -5,6 +5,7 @@ import com.github.pwittchen.reactivenetwork.library.rx2.internet.observing.Inter
import io.github.wulkanowy.data.db.entities.Note
import io.github.wulkanowy.data.db.entities.Semester
import io.github.wulkanowy.data.db.entities.Student
import io.github.wulkanowy.utils.uniqueSubtract
import io.reactivex.Completable
import io.reactivex.Single
import java.net.UnknownHostException
@ -27,8 +28,8 @@ class NoteRepository @Inject constructor(
}.flatMap { new ->
local.getNotes(student).toSingle(emptyList())
.doOnSuccess { old ->
local.deleteNotes(old - new)
local.saveNotes((new - old)
local.deleteNotes(old.uniqueSubtract(new))
local.saveNotes(new.uniqueSubtract(old)
.onEach {
if (it.date >= student.registrationDate.toLocalDate()) it.apply {
isRead = false

View File

@ -12,49 +12,64 @@ class PreferencesRepository @Inject constructor(
val context: Context
) {
val startMenuIndex: Int
get() = sharedPref.getString(context.getString(R.string.pref_key_start_menu), "0")?.toIntOrNull() ?: 0
get() = getString(R.string.pref_key_start_menu, R.string.pref_default_startup).toInt()
val isShowPresent: Boolean
get() = sharedPref.getBoolean(context.getString(R.string.pref_key_attendance_present), true)
get() = getBoolean(R.string.pref_key_attendance_present, R.bool.pref_default_attendance_present)
val gradeAverageMode: String
get() = sharedPref.getString(context.getString(R.string.pref_key_grade_average_mode), "only_one_semester") ?: "only_one_semester"
get() = getString(R.string.pref_key_grade_average_mode, R.string.pref_default_grade_average_mode)
val gradeAverageForceCalc: Boolean
get() = getBoolean(R.string.pref_key_grade_average_force_calc, R.bool.pref_default_grade_average_force_calc)
val isGradeExpandable: Boolean
get() = !sharedPref.getBoolean(context.getString(R.string.pref_key_expand_grade), false)
get() = !getBoolean(R.string.pref_key_expand_grade, R.bool.pref_default_expand_grade)
val appThemeKey: String = context.getString(R.string.pref_key_app_theme)
val appThemeKey = context.getString(R.string.pref_key_app_theme)
val appTheme: String
get() = sharedPref.getString(appThemeKey, "light") ?: "light"
get() = getString(appThemeKey, R.string.pref_default_app_theme)
val gradeColorTheme: String
get() = sharedPref.getString(context.getString(R.string.pref_key_grade_color_scheme), "vulcan") ?: "vulcan"
get() = getString(R.string.pref_key_grade_color_scheme, R.string.pref_default_grade_color_scheme)
val serviceEnableKey: String = context.getString(R.string.pref_key_services_enable)
val appLanguageKey = context.getString(R.string.pref_key_app_language)
val appLanguage
get() = getString(appLanguageKey, R.string.pref_default_app_language)
val serviceEnableKey = context.getString(R.string.pref_key_services_enable)
val isServiceEnabled: Boolean
get() = sharedPref.getBoolean(serviceEnableKey, true)
get() = getBoolean(serviceEnableKey, R.bool.pref_default_services_enable)
val servicesIntervalKey: String = context.getString(R.string.pref_key_services_interval)
val servicesIntervalKey = context.getString(R.string.pref_key_services_interval)
val servicesInterval: Long
get() = sharedPref.getString(servicesIntervalKey, "60")?.toLongOrNull() ?: 60
get() = getString(servicesIntervalKey, R.string.pref_default_services_interval).toLong()
val servicesOnlyWifiKey: String = context.getString(R.string.pref_key_services_wifi_only)
val servicesOnlyWifiKey = context.getString(R.string.pref_key_services_wifi_only)
val isServicesOnlyWifi: Boolean
get() = sharedPref.getBoolean(servicesOnlyWifiKey, true)
get() = getBoolean(servicesOnlyWifiKey, R.bool.pref_default_services_wifi_only)
val isNotificationsEnable: Boolean
get() = sharedPref.getBoolean(context.getString(R.string.pref_key_notifications_enable), true)
get() = getBoolean(R.string.pref_key_notifications_enable, R.bool.pref_default_notifications_enable)
val isDebugNotificationEnableKey: String = context.getString(R.string.pref_key_notification_debug)
val isDebugNotificationEnableKey = context.getString(R.string.pref_key_notification_debug)
val isDebugNotificationEnable: Boolean
get() = sharedPref.getBoolean(isDebugNotificationEnableKey, false)
get() = getBoolean(isDebugNotificationEnableKey, R.bool.pref_default_notification_debug)
val gradePlusModifier: Double
get() = sharedPref.getString(context.getString(R.string.pref_key_grade_modifier_plus), "0.0")?.toDouble() ?: 0.0
get() = getString(R.string.pref_key_grade_modifier_plus, R.string.pref_default_grade_modifier_plus).toDouble()
val gradeMinusModifier: Double
get() = sharedPref.getString(context.getString(R.string.pref_key_grade_modifier_minus), "0.0")?.toDouble() ?: 0.0
get() = getString(R.string.pref_key_grade_modifier_minus, R.string.pref_default_grade_modifier_minus).toDouble()
val fillMessageContent: Boolean
get() = sharedPref.getBoolean(context.getString(R.string.pref_key_fill_message_content), true)
get() = getBoolean(R.string.pref_key_fill_message_content, R.bool.pref_default_fill_message_content)
private fun getString(id: Int, default: Int) = getString(context.getString(id), default)
private fun getString(id: String, default: Int) = sharedPref.getString(id, context.getString(default)) ?: context.getString(default)
private fun getBoolean(id: Int, default: Int) = getBoolean(context.getString(id), default)
private fun getBoolean(id: String, default: Int) = sharedPref.getBoolean(id, context.resources.getBoolean(default))
}

View File

@ -15,7 +15,7 @@ class RecipientLocal @Inject constructor(private val recipientDb: RecipientDao)
return recipientDb.load(student.studentId, role, unit.realId).filter { !it.isEmpty() }
}
fun saveRecipients(recipients: List<Recipient>) {
fun saveRecipients(recipients: List<Recipient>): List<Long> {
return recipientDb.insertAll(recipients)
}

View File

@ -7,6 +7,7 @@ import io.github.wulkanowy.data.db.entities.Message
import io.github.wulkanowy.data.db.entities.Recipient
import io.github.wulkanowy.data.db.entities.ReportingUnit
import io.github.wulkanowy.data.db.entities.Student
import io.github.wulkanowy.utils.uniqueSubtract
import io.reactivex.Single
import java.net.UnknownHostException
import javax.inject.Inject
@ -31,8 +32,8 @@ class RecipientRepository @Inject constructor(
}.flatMap { new ->
local.getRecipients(student, role, unit).toSingle(emptyList())
.doOnSuccess { old ->
local.deleteRecipients(old - new)
local.saveRecipients(new - old)
local.deleteRecipients(old.uniqueSubtract(new))
local.saveRecipients(new.uniqueSubtract(old))
}
}.flatMap {
local.getRecipients(student, role, unit).toSingle(emptyList())

View File

@ -18,7 +18,7 @@ class ReportingUnitLocal @Inject constructor(private val reportingUnitDb: Report
return reportingUnitDb.loadOne(student.studentId, unitId)
}
fun saveReportingUnits(reportingUnits: List<ReportingUnit>) {
fun saveReportingUnits(reportingUnits: List<ReportingUnit>): List<Long> {
return reportingUnitDb.insertAll(reportingUnits)
}

View File

@ -5,6 +5,7 @@ import com.github.pwittchen.reactivenetwork.library.rx2.internet.observing.Inter
import io.github.wulkanowy.data.ApiHelper
import io.github.wulkanowy.data.db.entities.ReportingUnit
import io.github.wulkanowy.data.db.entities.Student
import io.github.wulkanowy.utils.uniqueSubtract
import io.reactivex.Maybe
import io.reactivex.Single
import java.net.UnknownHostException
@ -30,8 +31,8 @@ class ReportingUnitRepository @Inject constructor(
}.flatMap { new ->
local.getReportingUnits(student).toSingle(emptyList())
.doOnSuccess { old ->
local.deleteReportingUnits(old - new)
local.saveReportingUnits(new - old)
local.deleteReportingUnits(old.uniqueSubtract(new))
local.saveReportingUnits(new.uniqueSubtract(old))
}
}.flatMap { local.getReportingUnits(student).toSingle(emptyList()) }
)

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