1
0
Fork 1

Compare commits

...

399 commits

Author SHA1 Message Date
Mikołaj Pich
16e3a877af Merge branch 'release/0.14.1' 2020-01-09 00:53:51 +01:00
Mikołaj Pich
2b5b87fe84
Version 0.14.1 2020-01-09 00:53:32 +01:00
Rafał Borcz
d706c000b9 Add missing translations (#642) 2020-01-09 00:42:16 +01:00
dependabot-preview[bot]
15184550f4
Bump junit from 4.12 to 4.13 (#640) 2020-01-08 23:25:02 +00:00
dependabot-preview[bot]
69a8e35150
Bump logging-interceptor from 3.12.6 to 3.12.7 (#641) 2020-01-08 23:05:59 +00:00
dependabot-preview[bot]
70166d0245
Bump fragment-ktx from 1.2.0-rc04 to 1.2.0-rc05 (#639) 2020-01-08 22:50:35 +00:00
dependabot-preview[bot]
e0657eb5b2
Bump work_manager from 2.3.0-beta02 to 2.3.0-rc01 (#638) 2020-01-08 22:48:37 +00:00
Dominik Korsa
f204264d2d Change grade header note to unread count (#634) 2020-01-04 01:46:42 +01:00
pcktm
b9378c24b5 Minor translation changes (#630) 2020-01-03 21:12:05 +01:00
dependabot-preview[bot]
8a6ceeb2e4
Bump aboutlibraries from 7.0.4 to 7.1.0 (#633) 2020-01-02 19:42:15 +00:00
dependabot-preview[bot]
a45c7bd3e3
Bump dagger from 2.25.3 to 2.25.4 (#632) 2019-12-31 22:04:35 +00:00
Mikołaj Pich
4df245755a Add fields validation in mobile api login (#629) 2019-12-31 17:31:26 +01:00
Mikołaj Pich
6be801d4a8 Fix error view which overlaps grade statistics content (#627) 2019-12-30 22:57:48 +01:00
Mikołaj Pich
54f3733b56 Merge tag '0.14.0' into develop
Version 0.14.0
2019-12-25 16:52:34 +01:00
Mikołaj Pich
4f60673e4e Merge branch 'release/0.14.0' 2019-12-25 16:52:28 +01:00
Mikołaj Pich
7bd4fd7cbd
Version 0.14.0 2019-12-25 16:52:17 +01:00
Nikolas Ostrowski
65995cdc6c Change Wulkanowy API link to SDK in README (#626) 2019-12-24 16:51:35 +01:00
Mikołaj Pich
9d27723f30 Don't copy teacher from previous lesson with changes if new one… (#622) 2019-12-22 20:19:31 +01:00
Mikołaj Pich
2e7d2b66f8 Fix lucky number empty screen (#623) 2019-12-22 20:18:48 +01:00
Mikołaj Pich
304c49d61e Migration to Wulkanowy SDK (#336) 2019-12-22 00:14:46 +01:00
dependabot-preview[bot]
826ea32fc0
Bump room from 2.2.2 to 2.2.3 (#618) 2019-12-20 10:18:00 +00:00
dependabot-preview[bot]
d70c4fa9fe
Bump work_manager from 2.3.0-beta01 to 2.3.0-beta02 (#620) 2019-12-20 09:46:28 +00:00
dependabot-preview[bot]
bc43359467
Bump mockito-inline from 3.2.0 to 3.2.4 (#621) 2019-12-20 09:44:18 +00:00
dependabot-preview[bot]
cf286f3c23
Bump mockito-android from 3.2.0 to 3.2.4 (#619) 2019-12-20 09:27:14 +00:00
dependabot-preview[bot]
57abd43214
Bump fragment-ktx from 1.2.0-rc03 to 1.2.0-rc04 (#617) 2019-12-20 09:24:51 +00:00
dependabot-preview[bot]
90bdc9d157
Bump material from 1.1.0-beta02 to 1.1.0-rc01 (#616) 2019-12-20 09:13:34 +00:00
dependabot-preview[bot]
93bce685bd
Bump dagger from 2.25.2 to 2.25.3 (#614) 2019-12-20 09:07:39 +00:00
dependabot-preview[bot]
4639a075b0
Bump rxjava from 2.2.15 to 2.2.16 (#615) 2019-12-20 09:06:52 +00:00
stha
91f63da6d0 Fixed capitalization in the about tab (en) (#613) 2019-12-09 17:35:18 +01:00
stha
3894c9d48e Fixed letter capitalization in the About tab (pl) (#612) 2019-12-09 17:34:58 +01:00
Mikołaj Pich
fb40701962 Merge tag '0.13.0' into develop
Version 0.13.0
2019-12-07 23:04:39 +01:00
Mikołaj Pich
ff1e794820 Merge branch 'release/0.13.0' 2019-12-07 23:04:26 +01:00
Mikołaj Pich
ceba5f7fe8
Version 0.13.0 2019-12-07 23:04:17 +01:00
Mikołaj Pich
f570acbed6 Add FAQ link (#611) 2019-12-07 22:06:15 +01:00
dependabot-preview[bot]
2a7a472d90
Bump fragment-ktx from 1.2.0-rc02 to 1.2.0-rc03 (#610) 2019-12-07 16:07:36 +00:00
dependabot-preview[bot]
138fbe5bf5
Bump activity-ktx from 1.1.0-rc02 to 1.1.0-rc03 (#608) 2019-12-07 12:51:40 +00:00
dependabot-preview[bot]
ad99cc75eb
Bump gradle from 3.5.2 to 3.5.3 (#609) 2019-12-07 12:51:24 +00:00
dependabot-preview[bot]
f6606e7a4f
Bump coordinatorlayout from 1.1.0-rc01 to 1.1.0 (#607) 2019-12-07 12:51:09 +00:00
dependabot-preview[bot]
3690deef1e
Bump mockito-android from 3.1.0 to 3.2.0 (#605) 2019-12-02 16:19:20 +00:00
dependabot-preview[bot]
cd1438587d
Bump kotlin_version from 1.3.60 to 1.3.61 (#606) 2019-12-02 16:18:56 +00:00
dependabot-preview[bot]
8193a57227
Bump mockito-inline from 3.1.0 to 3.2.0 (#604) 2019-12-02 16:18:27 +00:00
Rafał Borcz
8467f39ad9 Add russian language (#595) 2019-11-29 20:43:37 +01:00
dependabot-preview[bot]
0fc293f47a
Bump assisted-inject-processor-dagger2 from 0.5.1 to 0.5.2 (#601) 2019-11-25 17:15:23 +00:00
dependabot-preview[bot]
9b063edb0b
Bump rxjava from 2.2.14 to 2.2.15 (#603) 2019-11-25 16:48:56 +00:00
dependabot-preview[bot]
5d852eee87
Bump assisted-inject-annotations-dagger2 from 0.5.1 to 0.5.2 (#602) 2019-11-25 16:48:07 +00:00
Mikołaj Pich
54ab408135 Add error view showing on first loading in fragment view (#590) 2019-11-24 17:05:09 +01:00
Mikołaj Pich
41aa326f42 Add 0,00 grade modifier (#596) 2019-11-21 17:41:41 +01:00
dependabot-preview[bot]
24f605c71c
Bump work_manager from 2.3.0-alpha03 to 2.3.0-beta01 (#600) 2019-11-21 11:00:11 +00:00
dependabot-preview[bot]
5c52dcc74f
Bump room from 2.2.1 to 2.2.2 (#599) 2019-11-21 10:31:14 +00:00
dependabot-preview[bot]
667659fbe6
Bump core-ktx from 1.2.0-beta02 to 1.2.0-rc01 (#598) 2019-11-21 10:30:51 +00:00
dependabot-preview[bot]
d467bf096f
Bump recyclerview from 1.1.0-rc01 to 1.1.0 (#597) 2019-11-21 10:28:54 +00:00
dependabot-preview[bot]
98d556bcd5 Bump kotlin_version from 1.3.50 to 1.3.60 (#594) 2019-11-18 10:57:50 +01:00
dependabot-preview[bot]
8c730be635
Bump google-services from 4.3.2 to 4.3.3 (#591) 2019-11-18 08:58:17 +00:00
dependabot-preview[bot]
377d24fbb4
Bump sonarqube-gradle-plugin from 2.8 to 2.8.0.1969 (#593) 2019-11-18 08:26:46 +00:00
Mikołaj Pich
bde810e031
Fix screens loading state (#589) 2019-11-17 01:07:43 +01:00
Rafał Borcz
2f18d42c86 Update material design components (#587) 2019-11-10 16:45:53 +01:00
dependabot-preview[bot]
c708b0c20e
Bump activity-ktx from 1.1.0-rc01 to 1.1.0-rc02 (#586) 2019-11-09 13:35:59 +00:00
dependabot-preview[bot]
ff8d55d4f8
Bump fragment-ktx from 1.2.0-rc01 to 1.2.0-rc02 (#585) 2019-11-09 13:08:02 +00:00
dependabot-preview[bot]
49bf911c84
Bump core-ktx from 1.2.0-beta01 to 1.2.0-beta02 (#584) 2019-11-09 13:07:27 +00:00
Dinolek
9e33ef419f Fix LuckyNumberWidget not showing ThemeDialog (#583) 2019-11-09 13:59:33 +01:00
Mikołaj Pich
40e95eac1e Add BaseDao interface (#581) 2019-11-06 23:52:14 +01:00
dependabot-preview[bot]
19e76a0b5d
Bump rxjava from 2.2.13 to 2.2.14 (#580) 2019-11-04 19:23:50 +00:00
Rafał Borcz
5feafe3907 Update gradle wrapper (#579) 2019-11-03 15:07:32 +01:00
Piotr Romanowski
b7206ed714 Add DatePicker to Timetable and Attendance modules. (#522) 2019-11-03 14:52:35 +01:00
Rafał Borcz
38370d647d
Add language change settings (#577) 2019-11-03 12:37:03 +01:00
dependabot-preview[bot]
323bc188b1
Bump assisted-inject-annotations-dagger2 from 0.5.0 to 0.5.1 (#576) 2019-11-01 20:20:09 +00:00
dependabot-preview[bot]
b17356591a
Bump assisted-inject-processor-dagger2 from 0.5.0 to 0.5.1 (#575) 2019-11-01 19:50:28 +00:00
Mikołaj Pich
a02c444cf5 Merge tag '0.12.0' into develop
0.12.0
2019-10-29 00:25:17 +01:00
Mikołaj Pich
87a133beb9 Merge branch 'release/0.12.0' 2019-10-29 00:25:12 +01:00
Mikołaj Pich
1f4a208857
Version 0.12.0 2019-10-29 00:25:03 +01:00
Mikołaj Pich
a7c472989c Add support for edu.lublin.eu (#571) 2019-10-28 21:10:58 +01:00
dependabot-preview[bot]
747696e386
Bump firebase-core from 17.2.0 to 17.2.1 (#572) 2019-10-28 14:58:10 +00:00
Dominik Korsa
a71a183160 Add school quick actions (#570) 2019-10-27 00:36:39 +02:00
Rafał Borcz
125a010f03 Fix restoring state in exposed dropdown menu (#569) 2019-10-24 22:56:49 +02:00
doteq
5c5993cc2a Change FAB to extended FAB in messages (#536) 2019-10-24 18:45:05 +02:00
dependabot-preview[bot]
f234b71932 Bump dagger from 2.24 to 2.25.2 (#564) 2019-10-24 18:24:22 +02:00
dependabot-preview[bot]
497a3391d4
Bump fragment-ktx from 1.2.0-beta02 to 1.2.0-rc01 (#568) 2019-10-24 06:58:42 +00:00
dependabot-preview[bot]
a72c743c6f
Bump work_manager from 2.3.0-alpha02 to 2.3.0-alpha03 (#563) 2019-10-24 06:37:24 +00:00
dependabot-preview[bot]
98fdfd001a
Bump recyclerview from 1.1.0-beta05 to 1.1.0-rc01 (#566) 2019-10-24 06:17:11 +00:00
dependabot-preview[bot]
994b162ae3
Bump activity-ktx from 1.1.0-beta01 to 1.1.0-rc01 (#567) 2019-10-24 06:16:51 +00:00
dependabot-preview[bot]
90c60f399b
Bump coordinatorlayout from 1.1.0-beta01 to 1.1.0-rc01 (#565) 2019-10-24 06:15:58 +00:00
dependabot-preview[bot]
b16b225a1a
Bump room from 2.2.0 to 2.2.1 (#562) 2019-10-24 05:55:08 +00:00
Mikołaj Pich
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
dependabot-preview[bot]
1b492d50fe
Bump aboutlibraries from 7.0.3 to 7.0.4 (#559) 2019-10-21 19:23:41 +00:00
dependabot-preview[bot]
d9b5e000f8
Bump gradle from 1.31.1 to 1.31.2 (#560) 2019-10-21 19:23:13 +00:00
Dominik Korsa
7e30524876 Contact info after failed login (#556) 2019-10-20 19:10:32 +02:00
Rafał Borcz
ce9b12eb93 Add system theme setting for Android 10 (#554) 2019-10-16 22:27:16 +02:00
Mikołaj Pich
b602657d55 Move default preferences values to separate file (#555) 2019-10-16 20:10:24 +02:00
Rafał Borcz
360dfbcdb5 Update androidx dependencies (#553) 2019-10-15 19:15:28 +02:00
dependabot-preview[bot]
f466497970
Bump recyclerview from 1.1.0-beta04 to 1.1.0-beta05 (#551) 2019-10-11 21:56:19 +00:00
dependabot-preview[bot]
184a7ab200
Bump room from 2.2.0-rc01 to 2.2.0 (#552) 2019-10-11 21:55:28 +00:00
Mikołaj Pich
2e5ef7dfa2 Merge tag '0.11.0' into develop
Version 0.11.0
2019-10-07 00:11:59 +02:00
Mikołaj Pich
8f617f4ca1 Merge branch 'release/0.11.0' 2019-10-07 00:11:52 +02:00
Mikołaj Pich
fe5f96a394
Version 0.11.0 2019-10-07 00:11:33 +02:00
Rafał Borcz
cb9c35d772 Add navigate up to login view (#547) 2019-10-06 22:43:16 +02:00
dependabot-preview[bot]
7cf7977cc6
Bump gson from 2.8.5 to 2.8.6 (#549) 2019-10-06 20:15:53 +00:00
Dominik Korsa
1de747fa35 Add mark as read button enable logic (#534) 2019-10-06 21:25:24 +02:00
Rafał Borcz
93750829d7 Fix duplicate percentage in attendance summary (#548) 2019-10-06 18:21:56 +02:00
Rafał Borcz
798688e7dd Fix multidex in debug variant (#545) 2019-10-05 22:32:55 +02:00
Mikołaj Pich
6ab9c1d737 Update mockito to last version from maven central (#546) 2019-10-03 22:47:49 +02:00
dependabot-preview[bot]
b074ce99b7
Bump sonarqube-gradle-plugin from 2.7.1 to 2.8 (#543) 2019-10-03 20:21:43 +00:00
dependabot-preview[bot]
b03fd86be5
Bump gradle from 3.5.0 to 3.5.1 (#542) 2019-10-03 20:08:32 +00:00
dependabot-preview[bot]
3de2f5ff88
Bump githook from 1.1.0 to 1.2.0 (#539) 2019-10-03 19:54:16 +00:00
dependabot-preview[bot]
35adf83154
Bump rxjava from 2.2.12 to 2.2.13 (#538) 2019-10-03 19:43:12 +00:00
Dominik Korsa
0162c8bbee Add better timetable changes display (#513) 2019-10-03 21:13:01 +02:00
Dominik Korsa
736d570f26 Change timetable widget date format (#530) 2019-10-03 15:29:33 +02:00
Mikołaj Pich
5b0901e311 Clear Semesters table (#535) 2019-10-03 14:00:07 +02:00
Mikołaj Pich
f9474af39e Add points to class grades statistics (#512) 2019-10-03 00:46:08 +02:00
doteq
d411d86355 Add click to copy function (#531) 2019-10-02 23:42:38 +02:00
Dominik Korsa
a50c6707cb Update readme badges (#532) 2019-10-01 22:19:28 +02:00
dependabot-preview[bot]
6991c68d3a
Bump mockito-core from 3.0.8 to 3.0.11 (#525) 2019-09-30 10:31:07 +00:00
dependabot-preview[bot]
8b1e6f7bd6
Bump play-publisher from 2.4.1 to 2.4.2 (#528) 2019-09-30 10:16:38 +00:00
dependabot-preview[bot]
943fd9c622
Bump logging-interceptor from 3.12.5 to 3.12.6 (#529) 2019-09-30 10:09:57 +00:00
dependabot-preview[bot]
838e2781c0
Bump mockito-inline from 3.0.8 to 3.0.11 (#526) 2019-09-30 10:05:54 +00:00
dependabot-preview[bot]
66cfd7b52c
Bump mockito-android from 3.0.8 to 3.0.11 (#527) 2019-09-30 10:04:50 +00:00
Dominik Korsa
a45bc0eef6 Add teachers (#489) 2019-09-29 18:09:53 +02:00
Dominik Korsa
ed7996299e Improve date navigation (#519) 2019-09-28 20:37:14 +02:00
Rafał Borcz
d4b73fb73e Add dark theme for app widgets (#509) 2019-09-25 22:44:55 +02:00
dependabot-preview[bot]
d6ece78eff
Bump mockito-android from 3.0.7 to 3.0.8 (#518) 2019-09-22 11:03:41 +00:00
dependabot-preview[bot]
2f44f3c4ba
Bump gradle from 1.31.0 to 1.31.1 (#517) 2019-09-22 10:55:34 +00:00
dependabot-preview[bot]
23b49e4b8c
Bump mockito-inline from 3.0.7 to 3.0.8 (#516) 2019-09-22 10:50:21 +00:00
dependabot-preview[bot]
5d33cefe1d
Bump mockito-core from 3.0.7 to 3.0.8 (#515) 2019-09-22 10:49:39 +00:00
Rafał Borcz
6089df9462 Fix wrong index in form host value (#507) 2019-09-16 23:27:58 +02:00
Rafał Borcz
3ee98e2bd0 Fix privacy link position on small screens (#508) 2019-09-16 23:13:46 +02:00
Dominik Korsa
53a5d02051 Fix attendance_excused_lateness pl typo (#511) 2019-09-16 23:06:37 +02:00
dependabot-preview[bot]
e332fd9cf9
Bump logging-interceptor from 3.12.4 to 3.12.5 (#510) 2019-09-16 08:29:32 +00:00
Rafał Borcz
7232938c12 Update API 28 to API 29 (#506) 2019-09-12 16:36:32 +02:00
Mikołaj Pich
fd02f2253b Merge tag '0.10.2' into develop
Version 0.10.2
2019-09-10 13:01:52 +02:00
Mikołaj Pich
12046ef0a0 Merge branch 'release/0.10.2' 2019-09-10 13:01:38 +02:00
Mikołaj Pich
dfc84b4208
Version 0.10.2 2019-09-10 12:58:27 +02:00
Rafał Borcz
f5f11d5130 Fix login in symbol view (#493) 2019-09-10 12:25:08 +02:00
dependabot-preview[bot]
81ce328abd
Bump recyclerview from 1.1.0-beta03 to 1.1.0-beta04 (#504) 2019-09-09 14:05:04 +00:00
dependabot-preview[bot]
867951136a
Bump gradle-play-publisher from cdaeb61 to 2.4.0 (#501) 2019-09-09 13:43:55 +00:00
dependabot-preview[bot]
8b41ab27bd
Bump mockito-core from 3.0.6 to 3.0.7 (#502) 2019-09-09 09:25:52 +00:00
dependabot-preview[bot]
e542ef003c
Bump mockito-android from 3.0.6 to 3.0.7 (#503) 2019-09-09 08:54:03 +00:00
dependabot-preview[bot]
a5f212e6be
Bump room from 2.2.0-beta01 to 2.2.0-rc01 (#499) 2019-09-09 08:39:39 +00:00
dependabot-preview[bot]
385a320536
Bump google-services from 4.3.1 to 4.3.2 (#498) 2019-09-09 08:25:51 +00:00
dependabot-preview[bot]
e65000ec2c
Bump mockito-inline from 3.0.6 to 3.0.7 (#497) 2019-09-09 08:25:29 +00:00
dependabot-preview[bot]
c87de7b3c2
Bump logging-interceptor from 3.12.3 to 3.12.4 (#496) 2019-09-09 08:23:22 +00:00
Dominik Korsa
bb6023709f Fix grade details header unread info (#494) 2019-09-08 15:10:29 +02:00
Mikołaj Pich
e998e54d3e Merge tag '0.10.1' into develop
Version 0.10.1
2019-09-07 02:25:22 +02:00
Mikołaj Pich
e269886eae Merge branch 'release/0.10.1' 2019-09-07 02:25:12 +02:00
Mikołaj Pich
dabb83c522
Version 0.10.1 2019-09-07 02:23:44 +02:00
Rafał Borcz
6350b72e23 Fix account icon color in widgets (#488) 2019-09-06 18:23:51 +02:00
Rafał Borcz
e4100d940a Fix crashing tab layout on prelolipop (#492) 2019-09-06 13:55:26 +02:00
Dominik Korsa
6575674169 Fix about_feedback_summary typo (#487) 2019-09-05 18:57:37 +02:00
Mikołaj Pich
a13aad984c Merge tag '0.10.0' into develop
Version 0.10.0
2019-09-04 22:59:40 +02:00
Mikołaj Pich
750fa9a76d Merge branch 'release/0.10.0' 2019-09-04 22:59:26 +02:00
Mikołaj Pich
d0ad4d9364
Version 0.10.0 2019-09-04 22:58:53 +02:00
Rafał Borcz
4e0f41dcb2 Change marking current student in accounts dialog (#486) 2019-09-04 21:19:05 +02:00
Mikołaj Pich
c3bb489851 Mitigate disappearing teachers in timetable (#485) 2019-09-04 20:45:34 +02:00
Rafał Borcz
e64e6676f3 Fix status bar color on xiaomi (#484) 2019-09-04 13:52:55 +02:00
Dominik Korsa
108440b1ca Reduce grade color saturations (#482) 2019-09-03 22:43:17 +02:00
dependabot-preview[bot]
d54f5ed1aa Bump aboutlibraries from 7.0.2 to 7.0.3 (#480) 2019-09-03 22:39:05 +02:00
Rafał Borcz
0aac6459f3 Fix elevation overlay on pre-lolipop (#475) 2019-09-02 12:56:13 +02:00
Rafał Borcz
bb9ea7eda1 Fix spaming NoCurentStudentException (#476) 2019-09-02 12:38:09 +02:00
Rafał Borcz
455b04f183 Fix empty hosts list after activity recreating (#477) 2019-09-02 10:05:42 +02:00
Rafał Borcz
39fb4f5def
Update dependencies (#474) 2019-09-01 13:24:21 +02:00
Dominik Korsa
c60428e29b Add outline icons (#328) 2019-08-30 12:00:34 +02:00
dependabot-preview[bot]
5413ecabb4
Bump firebase-core from 17.1.0 to 17.2.0 (#473) 2019-08-28 17:03:51 +00:00
Rafał Borcz
c6d9dfa0c9 Change app theme (#330) 2019-08-26 20:54:20 +02:00
dependabot-preview[bot]
b0033af048
Bump rxjava from 2.2.11 to 2.2.12 (#472) 2019-08-26 13:11:35 +00:00
dependabot-preview[bot]
405d37e822
Bump play-publisher from 2.2.1 to 2.3.0 (#446) 2019-08-23 18:57:45 +00:00
dependabot-preview[bot]
0d514b7dc9
Bump gradle from 3.4.2 to 3.5.0 (#469) 2019-08-23 18:37:05 +00:00
dependabot-preview[bot]
c3596aa45c
Bump reactivenetwork-rx2 from 3.0.4 to 3.0.6 (#468) 2019-08-23 11:50:18 +00:00
dependabot-preview[bot]
d34bdb2ce3
Bump google-services from 4.3.0 to 4.3.1 (#470) 2019-08-23 11:49:51 +00:00
dependabot-preview[bot]
c91870cc04
Bump kotlin_version from 1.3.41 to 1.3.50 (#471) 2019-08-23 11:35:31 +00:00
dependabot-preview[bot]
2f6862967e
Bump mockito-core from 3.0.5 to 3.0.6 (#466) 2019-08-20 10:24:11 +00:00
dependabot-preview[bot]
7525395665
Bump mockito-inline from 3.0.5 to 3.0.6 (#465) 2019-08-20 10:07:52 +00:00
dependabot-preview[bot]
657e2b280e
Bump mockito-android from 3.0.5 to 3.0.6 (#467) 2019-08-20 10:06:40 +00:00
dependabot-preview[bot]
4ea9be582f
Bump mockito-core from 3.0.4 to 3.0.5 (#464) 2019-08-19 09:16:34 +00:00
dependabot-preview[bot]
3dcc8247bf
Bump mockito-inline from 3.0.4 to 3.0.5 (#463) 2019-08-19 08:50:35 +00:00
dependabot-preview[bot]
c45b7c04b9
Bump mockito-android from 3.0.4 to 3.0.5 (#462) 2019-08-19 08:42:55 +00:00
dependabot-preview[bot]
33d6ae8afc
Bump firebase-core from 17.0.1 to 17.1.0 (#461) 2019-08-19 08:42:26 +00:00
dependabot-preview[bot]
6871606bef Bump work_manager from 2.1.0 to 2.2.0 (#460) 2019-08-17 18:31:53 +02:00
Mikołaj Pich
6e266acec9 Merge tag '0.9.4' into develop
0.9.4
2019-08-12 23:18:04 +02:00
Mikołaj Pich
ba84f2be6e Merge branch 'release/0.9.4' 2019-08-12 23:17:57 +02:00
Mikołaj Pich
db7b7dbadf
Version 0.9.4 2019-08-12 23:17:02 +02:00
Mikołaj Pich
6bd07d2651 Fix day/week navigation on holiday (#459) 2019-08-12 12:17:39 +02:00
dependabot-preview[bot]
070fba734c
Bump assisted-inject-annotations-dagger2 from 0.4.0 to 0.5.0 (#458) 2019-08-09 12:04:05 +00:00
dependabot-preview[bot]
72ef366829
Bump assisted-inject-processor-dagger2 from 0.4.0 to 0.5.0 (#457) 2019-08-09 11:28:33 +00:00
Rafał Borcz
4adfb268a3 Update gitignore (#455) 2019-08-08 17:40:23 +02:00
dependabot-preview[bot]
bf0ea1b012
Bump reactivenetwork-rx2 from 3.0.3 to 3.0.4 (#456) 2019-08-07 17:09:26 +00:00
dependabot-preview[bot]
1267a39e32
Bump rxjava from 2.2.10 to 2.2.11 (#454) 2019-08-02 11:01:28 +00:00
dependabot-preview[bot]
462b917832
Bump mockito-core from 3.0.2 to 3.0.4 (#451) 2019-07-29 07:34:21 +00:00
dependabot-preview[bot]
c5b16bb0d0
Bump mockito-android from 3.0.2 to 3.0.4 (#450) 2019-07-29 07:04:29 +00:00
dependabot-preview[bot]
91268dcc67
Bump mockito-inline from 3.0.2 to 3.0.4 (#452) 2019-07-29 07:02:15 +00:00
dependabot-preview[bot]
13f9981be6 Bump dagger from 2.23.2 to 2.24 (#449) 2019-07-28 12:41:29 +02:00
dependabot-preview[bot]
f9b3bd7b3a
Bump gradle from 1.30.0 to 1.31.0 (#448) 2019-07-26 08:14:13 +00:00
Rafał Borcz
39916c2796 Update README (#447) 2019-07-17 13:41:47 +02:00
dependabot-preview[bot]
03f5ddaf0d
Bump work_manager from 2.0.1 to 2.1.0 (#441) 2019-07-12 12:50:56 +00:00
dependabot-preview[bot]
ea4f55c06d
Bump gradle from 1.29.0 to 1.30.0 (#443) 2019-07-12 08:48:33 +00:00
dependabot-preview[bot]
5b0232f77e
Bump mockito-inline from 3.0.1 to 3.0.2 (#442) 2019-07-12 08:47:36 +00:00
dependabot-preview[bot]
0b68091e55
Bump mockito-android from 3.0.1 to 3.0.2 (#444) 2019-07-12 08:47:11 +00:00
dependabot-preview[bot]
7136c9282e
Bump mockito-core from 3.0.1 to 3.0.2 (#445) 2019-07-12 08:46:52 +00:00
dependabot-preview[bot]
09303153a5
Bump firebase-core from 17.0.0 to 17.0.1 (#440) 2019-07-12 08:44:52 +00:00
dependabot-preview[bot]
bdf0fba95b
Bump gradle from 3.4.1 to 3.4.2 (#438) 2019-07-10 07:22:59 +00:00
Mikołaj Pich
86f24e5821 Group dependencies versions in variables (#437) 2019-07-09 13:33:36 +02:00
dependabot-preview[bot]
35f094b983
Bump kotlin_version from 1.3.40 to 1.3.41 (#433) 2019-07-09 07:45:20 +00:00
dependabot-preview[bot]
12cf1e0b66
Bump mockito-inline from 2.28.2 to 3.0.1 (#434) 2019-07-09 07:40:24 +00:00
dependabot-preview[bot]
68b37fc5dd
Bump mockito-android from 2.28.2 to 3.0.1 (#435) 2019-07-09 07:22:24 +00:00
dependabot-preview[bot]
ba5bad042a
Bump mockito-core from 2.28.2 to 3.0.1 (#436) 2019-07-09 07:21:54 +00:00
dependabot-preview[bot]
c5323ee811
Bump google-services from 4.2.0 to 4.3.0 (#432) 2019-06-28 18:29:30 +00:00
dependabot-preview[bot]
df9c685217
Bump frag-nav from 3.2.0 to 3.3.0 (#430) 2019-06-26 11:44:23 +00:00
dependabot-preview[bot]
73fa21d45f
Bump firebase-core from 16.0.9 to 17.0.0 (#423) 2019-06-21 14:06:24 +00:00
Rafał Borcz
344fa1bbd7 Increase min SDK to 16 (#429) 2019-06-21 14:54:10 +02:00
dependabot-preview[bot]
01318c8c29
Bump rxjava from 2.2.9 to 2.2.10 (#428) 2019-06-21 10:08:49 +00:00
dependabot-preview[bot]
851486df28
Bump dagger-android-support from 2.23.1 to 2.23.2 (#424) 2019-06-20 22:00:35 +00:00
dependabot-preview[bot]
d8b3c5d9d6
Bump dagger-android-processor from 2.23.1 to 2.23.2 (#425) 2019-06-20 21:43:05 +00:00
dependabot-preview[bot]
2883b21ddf
Bump dagger-compiler from 2.23.1 to 2.23.2 (#426) 2019-06-20 21:22:57 +00:00
dependabot-preview[bot]
4956cf3988
Bump kotlin_version from 1.3.31 to 1.3.40 (#427) 2019-06-20 21:17:57 +00:00
Mikołaj Pich
bdbcec786a Merge tag '0.9.3' into develop
0.9.3
2019-06-15 01:14:04 +02:00
Mikołaj Pich
c40bbf2398 Merge branch 'release/0.9.3' 2019-06-15 01:13:50 +02:00
Mikołaj Pich
08ecbb5341
Version 0.9.3 2019-06-15 01:13:36 +02:00
Rafał Borcz
e38e458386 Fix crash on login when error message is null (#420) 2019-06-15 00:51:54 +02:00
dependabot-preview[bot]
14674b7778
Bump room-testing from 2.1.0-rc01 to 2.1.0 (#417) 2019-06-13 22:33:12 +00:00
dependabot-preview[bot]
c6f0588165
Bump room-compiler from 2.1.0-rc01 to 2.1.0 (#415) 2019-06-13 22:12:23 +00:00
dependabot-preview[bot]
7591af0de1
Bump room-rxjava2 from 2.1.0-rc01 to 2.1.0 (#411) 2019-06-13 21:52:32 +00:00
dependabot-preview[bot]
cbfed09b52
Bump room-runtime from 2.1.0-rc01 to 2.1.0 (#419) 2019-06-13 21:29:47 +00:00
Rafał Borcz
5c185c5eca Merge branch 'release/0.9.2' 2019-06-08 11:38:42 +02:00
Rafał Borcz
4a026e4a70 Merge tag '0.9.2' into develop
0.9.2 0.9.2
2019-06-08 11:38:42 +02:00
Rafał Borcz
0bccbc6011 Version 0.9.2 2019-06-08 11:38:06 +02:00
Rafał Borcz
ed6a0f8cd0 Add StackOverflowError to RxJava's error handler (#408) 2019-06-07 21:38:53 +02:00
Rafał Borcz
58d5e4da0e Fix showing empty view in mobile device view (#407) 2019-06-07 19:03:26 +02:00
Rafał Borcz
ba6fb1a4b9 Fix update of grades in GradeDetailsFragment (#406) 2019-06-07 14:46:11 +02:00
Rafał Borcz
b6b862d4c3 Organize AndroidX libraries (#404) 2019-06-07 14:12:52 +02:00
Rafał Borcz
9b044a19fe Fix typo in service interval (#405) 2019-06-06 22:47:45 +02:00
Rafał Borcz
7485cb2a39 Fix change of worker specs after app update (#402) 2019-06-06 22:32:43 +02:00
Rafał Borcz
75122d0dcd Fix crash TabLayout on Android 4.x in new version of material components (#403) 2019-06-06 19:16:00 +02:00
dependabot-preview[bot]
39af56484b
Bump threetenabp from 1.2.0 to 1.2.1 (#401) 2019-06-04 11:23:50 +00:00
Mikołaj Pich
05f7e1d115 Merge tag '0.9.1' into develop
Version 0.9.1
2019-06-04 02:44:04 +02:00
Mikołaj Pich
9cd5377438 Merge branch 'release/0.9.1' 2019-06-04 02:43:54 +02:00
Mikołaj Pich
7a61b233f0
Version 0.9.1 2019-06-04 02:43:50 +02:00
Mikołaj Pich
83dbd9874e
Add option to force calc average by app (#400) 2019-06-04 02:27:15 +02:00
Mikołaj Pich
1d9a49d552 Add githook plugin (#398) 2019-06-04 01:53:20 +02:00
Rafał Borcz
6175081b88 Fix tab layout crash on prelolipop (#399) 2019-06-03 22:47:35 +02:00
Rafał Borcz
116e551186 Merge tag '0.9.0' into develop
0.9.0 0.9.0
2019-06-03 18:15:42 +02:00
Rafał Borcz
713500d892 Merge branch 'release/0.9.0' 2019-06-03 18:15:41 +02:00
Rafał Borcz
dfdbe374c2 Version 0.9.0 2019-06-03 18:15:11 +02:00
Mikołaj Pich
b1e3bab5e7 Add F-Droid flavor (#349) 2019-06-03 14:12:48 +02:00
Rafał Borcz
0b2ef367da Change timeout string (#397) 2019-06-03 13:15:21 +02:00
Mikołaj Pich
28f27db2b5 Add mobile access managment (#344) 2019-06-03 00:43:54 +02:00
Rafał Borcz
5c70cd8b8c Add session expired dialog after password change (#389) 2019-05-31 15:12:10 +02:00
Mikołaj Pich
0f75ff3206 Show grades average from register if exist instead of calculating (#374) 2019-05-31 14:40:53 +02:00
Rafał Borcz
383cab4dae Fix only wifi setting (#394) 2019-05-31 13:46:53 +02:00
dependabot-preview[bot]
e1b0db76c2 Bump material from 1.1.0-alpha06 to 1.1.0-alpha07 (#393) 2019-05-31 11:46:29 +02:00
dependabot-preview[bot]
f10684097c
Bump dagger-compiler from 2.23 to 2.23.1 (#391) 2019-05-31 02:02:09 +00:00
dependabot-preview[bot]
35d4342bec
Bump dagger-android-processor from 2.23 to 2.23.1 (#392) 2019-05-31 01:42:40 +00:00
dependabot-preview[bot]
068aee215a
Bump dagger-android-support from 2.23 to 2.23.1 (#390) 2019-05-31 01:19:26 +00:00
dependabot-preview[bot]
033074c66b Bump room-testing from 2.1.0-beta01 to 2.1.0-rc01 (#377) 2019-05-30 16:46:54 +02:00
dependabot-preview[bot]
0de534cb66 Bump room-rxjava2 from 2.1.0-beta01 to 2.1.0-rc01 (#385) 2019-05-30 16:46:28 +02:00
dependabot-preview[bot]
26e4619dde
Bump room-runtime from 2.1.0-beta01 to 2.1.0-rc01 (#388) 2019-05-30 14:06:06 +00:00
dependabot-preview[bot]
cf08d1ff24
Bump mockito-core from 2.28.1 to 2.28.2 (#387) 2019-05-30 13:58:42 +00:00
dependabot-preview[bot]
96c400a0bd
Bump runner from 1.1.1 to 1.2.0 (#386) 2019-05-30 13:50:28 +00:00
dependabot-preview[bot]
e238f65dde Bump rxjava from 2.2.8 to 2.2.9 (#381) 2019-05-30 15:22:15 +02:00
dependabot-preview[bot]
ba7966125b
Bump dagger-compiler from 2.22.1 to 2.23 (#380) 2019-05-30 12:01:15 +00:00
dependabot-preview[bot]
1536208e45
Bump core from 1.1.0 to 1.2.0 (#383) 2019-05-30 11:46:56 +00:00
dependabot-preview[bot]
24cc07264a
Bump dagger-android-support from 2.22.1 to 2.23 (#384) 2019-05-30 11:31:22 +00:00
dependabot-preview[bot]
1ad5232520
Bump mockito-inline from 2.28.1 to 2.28.2 (#382) 2019-05-30 11:29:13 +00:00
dependabot-preview[bot]
07f3333029
Bump mockito-android from 2.28.1 to 2.28.2 (#379) 2019-05-30 11:12:44 +00:00
dependabot-preview[bot]
214afb82a6
Bump junit from 1.1.0 to 1.1.1 (#378) 2019-05-30 11:05:05 +00:00
dependabot-preview[bot]
7a69710261
Bump dagger-android-processor from 2.22.1 to 2.23 (#376) 2019-05-30 10:54:26 +00:00
dependabot-preview[bot]
64d3afbdb3
Bump room-compiler from 2.1.0-beta01 to 2.1.0-rc01 (#375) 2019-05-30 10:53:35 +00:00
dependabot-preview[bot]
387e46f72d
Bump mockito-inline from 2.27.5 to 2.28.1 (#372) 2019-05-29 00:16:10 +00:00
dependabot-preview[bot]
89acc2f384
Bump mockito-android from 2.27.5 to 2.28.1 (#373) 2019-05-28 23:59:19 +00:00
dependabot-preview[bot]
4ef1439878 Bump mockito-core from 2.27.2 to 2.28.1 (#371) 2019-05-29 01:57:19 +02:00
dependabot-preview[bot]
6efd170e03
Bump mockito-inline from 2.27.0 to 2.27.5 (#367) 2019-05-28 14:57:39 +00:00
dependabot-preview[bot]
82cd39329a
Bump mockito-android from 2.27.0 to 2.27.5 (#354) 2019-05-28 14:22:24 +00:00
dependabot-preview[bot]
b38e0d04e7 Bump threetenbp from 1.3.8 to 1.4.0 (#366) 2019-05-28 14:41:48 +02:00
dependabot-preview[bot]
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
dependabot-preview[bot]
33951dff54
Bump crashlytics from 2.9.9 to 2.10.1 (#365) 2019-05-28 11:30:42 +00:00
dependabot-preview[bot]
9ced00c4d7
Bump room-runtime from 2.1.0-alpha07 to 2.1.0-beta01 (#364) 2019-05-28 11:06:56 +00:00
dependabot-preview[bot]
2ac1638911
Bump room-testing from 2.1.0-alpha07 to 2.1.0-beta01 (#363) 2019-05-28 10:48:37 +00:00
dependabot-preview[bot]
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
dependabot-preview[bot]
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
dependabot-preview[bot]
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
dependabot-preview[bot]
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
dependabot-preview[bot]
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
dependabot-preview[bot]
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
dependabot-preview[bot]
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
dependabot-preview[bot]
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
Mikołaj Pich
e4a6caa13e
Version 0.8.4 2019-05-27 18:13:20 +02:00
Mikołaj Pich
209e75160a Fix network constraint in background sync (#348) 2019-05-25 14:34:17 +02:00
Mikołaj Pich
153e026a8d
Version 0.8.3 2019-05-20 00:21:30 +02:00
Mikołaj Pich
8731c2e1f2 Change help text when entering the symbol to a more precise one (#345) 2019-05-19 22:47:57 +02:00
Rafał Borcz
0977282a4b Fix no current student in services after logout all accounts (#342) 2019-05-18 23:42:47 +02:00
Rafał Borcz
667c4b6af7 Fix empty maybe when loading message content (#343) 2019-05-18 23:32:37 +02:00
Mikołaj Pich
1f5088cfc9 Don't copy teacher from previous lesson to completed (#341) 2019-05-18 13:03:38 +02:00
Rafał Borcz
bf6b857a3e Fix null returns in widgets (#340) 2019-05-18 00:22:07 +02:00
Mikołaj Pich
80cb94c434
Version 0.8.2 2019-05-15 19:26:25 +02:00
Rafał Borcz
0cb4eda32b Fix crash on reselecting fragment (#339) 2019-05-15 15:11:28 +02:00
Rafał Borcz
d169f964f2 Fix crash when no webview activity (#338) 2019-05-14 11:45:27 +02:00
Rafał Borcz
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
Mikołaj Pich
a191f03cdf
Version 0.8.1 2019-04-30 23:56:22 +02:00
Mikołaj Pich
63404b8576 Fix entity list comparing (#335) 2019-04-30 19:04:05 +02:00
Rafał Borcz
1b7760ff88 Fix dark theme background with custom theme engine (#334) 2019-04-30 17:45:37 +02:00
Rafał Borcz
24f58835e7 Fix menu view initialization and restoration (#333) 2019-04-30 17:28:09 +02:00
Mikołaj Pich
b032c459d1 Fix theme on release build (#332) 2019-04-30 11:16:23 +02:00
Mikołaj Pich
df0a1e59cc
Version 0.8.0 2019-04-29 20:39:35 +02:00
Kacper Ziubryniewicz
dbbc8069b1 Add showing proper fragment in notifications (#331) 2019-04-29 19:56:23 +02:00
Mikołaj Pich
f84040109c Add lucky number widget (#292) 2019-04-29 14:33:33 +02:00
Dominik Korsa
baf1420193 Improve login student selection layout (#329) 2019-04-29 00:55:30 +02:00
Rafał Borcz
4a36d78709 Add activity and fragment lifecycle logging (#327) 2019-04-26 23:53:02 +02:00
Rafał Borcz
4464812651 Fix configure activity's theme (#325) 2019-04-22 09:27:25 +02:00
Rafał Borcz
72a35481e5 Fix showing last message after update (#326) 2019-04-22 09:13:26 +02:00
Mikołaj Pich
017c200115 Fix grade summary final grade string (#324) 2019-04-20 22:19:06 +02:00
Mikołaj Pich
2bf7755157 Add AMOLED mode (#279) 2019-04-19 23:52:34 +02:00
Rafał Borcz
269af4b7ba Update dependencies (#323) 2019-04-18 16:38:49 +02:00
Rafał Borcz
7431738366 Add a selection of multiple students to login (#318) 2019-04-18 12:18:58 +02:00
Rafał Borcz
034b99c7ab Add counting of the full-year average to the summary of grades (#322) 2019-04-18 00:32:43 +02:00
Rafał Borcz
74e98e4430 Change style of privacy policy link (#321) 2019-04-09 23:33:53 +02:00
Mikołaj Pich
cbf3215dd1
Merge branch '0.7.x' 2019-04-08 13:51:02 +02:00
Rafał Borcz
c18877466f Add account picker for timetable widget (#314)
Close #281
2019-04-08 00:18:45 +02:00
Mikołaj Pich
6cd6cae1e0
Version 0.7.6 2019-04-07 11:08:46 +02:00
Mikołaj Pich
333f7bfa16
Add privacy policy link (#320) 2019-04-07 10:59:27 +02:00
Mikołaj Pich
aa6dcaff94
Merge branch '0.7.x' 2019-04-06 01:18:03 +02:00
Mikołaj Pich
f2fa04105d
Version 0.7.5 2019-04-06 01:06:11 +02:00
Mikołaj Pich
7d97d71066 Fix message loading if student and parent are logged in (#319)
Fixes #316
2019-04-05 19:35:21 +02:00
Mikołaj Pich
8daea5c900 Add class name to student (#315) 2019-04-04 13:00:07 +02:00
Kacper Ziubryniewicz
2bff468e56 Add deleting messages (#290) 2019-03-31 22:01:04 +02:00
Mikołaj Pich
f2855d598d
Merge branch '0.7.x' 2019-03-30 20:19:34 +01:00
Mikołaj Pich
297a2909ba Version 0.7.4 2019-03-30 19:45:57 +01:00
Rafał Borcz
935bec3f5b Add 0,75 grade modifier (#313) 2019-03-30 19:26:19 +01:00
Mikołaj Pich
e71dd55066 Fix more than one current semester (#307) 2019-03-30 18:28:37 +01:00
Rafał Borcz
4e3864f26f Add opening login view on no current student (#312) 2019-03-30 09:31:30 +01:00
Rafał Borcz
8601093725 Again fix rejected execution in sync worker (#310) 2019-03-28 23:30:30 +01:00
Rafał Borcz
b97b94ae29 Fix more than one current student (#311)
Fix #309
2019-03-28 23:07:59 +01:00
Rafał Borcz
c6c7357623 Fix black spinner in login form (#308) 2019-03-28 18:27:17 +01:00
Mikołaj Pich
1ebc296bfe
Merge branch '0.7.x' 2019-03-26 21:22:17 +01:00
Mikołaj Pich
c2ab53cfeb
Version 0.7.3 2019-03-26 19:46:59 +01:00
Rafał Borcz
87268b3ef6 Fix rejected execution in sync worker (#305) 2019-03-26 16:47:14 +01:00
Rafał Borcz
b3cd7e8ac1 Fix undeliverable network exceptions (#306)
* Remove unnecessary this
2019-03-26 14:32:23 +01:00
Mikołaj Pich
a2a18e5652
Merge branch '0.7.x' 2019-03-24 23:22:44 +01:00
Mikołaj Pich
5a997dacb7
Version 0.7.2 2019-03-24 22:42:09 +01:00
Rafał Borcz
ed9458d9a5 Fix more than one current semester in database (#304) 2019-03-24 20:21:05 +01:00
Mikołaj Pich
3656d3161f Fix crash on duplicate items (#303) 2019-03-24 17:31:39 +01:00
Rafał Borcz
d178c15d2f Update dependencies (#302) 2019-03-24 16:03:51 +01:00
Rafał Borcz
1f65b8465e Add logging to sync worker (#300) 2019-03-23 18:35:56 +01:00
Mikołaj Pich
6bb03b3be8 Fix day navigation unevenition (#301) 2019-03-23 17:29:34 +01:00
Rafał Borcz
68b9847927 Fix reselecting root fragments (#299) 2019-03-23 16:35:33 +01:00
Rafał Borcz
e1a83927c4 Fix reset button in timetable widget (#298) 2019-03-23 14:44:52 +01:00
Mikołaj Pich
fc9981aa5d Fix issues when loading lucky number (#297) 2019-03-23 13:01:01 +01:00
Rafał Borcz
2d6610e05c Set max concurrency in sync worker (#296) 2019-03-23 01:12:17 +01:00
Rafał Borcz
316cd2f7f9 Add checking current student in background services (#295) 2019-03-23 00:37:13 +01:00
Rafał Borcz
36785f019a Fix restoring the grade fragment (#293) 2019-03-22 23:54:58 +01:00
Rafał Borcz
4b78862486 Remove retry sync work when completed lessons is disabled (#294) 2019-03-22 23:41:41 +01:00
Kacper Ziubryniewicz
cd1ceea860 Add messages forwarding (#288) 2019-03-21 22:55:47 +01:00
Rafał Borcz
20d0abba29 Fix empty container id in grade fragemnt adapter (#289) 2019-03-21 22:34:41 +01:00
Mikołaj Pich
5add95ece1
Version 0.7.1 2019-03-20 21:02:09 +01:00
Rafał Borcz
575e244b3a Add swipe refresh to grade fragment (#287) 2019-03-20 20:45:26 +01:00
Rafał Borcz
8db73e9459 Fix the application finish after selecting an account (#286) 2019-03-19 18:14:55 +01:00
Mikołaj Pich
040857ba20 Change grade weightValue type to double (#285) 2019-03-19 13:23:52 +01:00
Mikołaj Pich
4b0f0de52c
Version 0.7.0 2019-03-17 21:20:37 +01:00
Kacper Ziubryniewicz
ba76453e45 Add replying to messages (#263) 2019-03-17 21:02:41 +01:00
Dominik Korsa
824ed3f282 Centre the login form (#283) 2019-03-17 19:57:25 +01:00
Mikołaj Pich
d27d069ce2 Change homework view to weekly (#284) 2019-03-17 00:17:16 +01:00
Mikołaj Pich
38aa26a3ff Add homepage button in about fragment (#280) 2019-03-16 14:22:51 +01:00
Rafał Borcz
be807cb6c8 Change settings for checking the internet connection (#282) 2019-03-15 21:33:14 +01:00
Mikołaj Pich
35f1fe8d61 Follow current grade scheme in stats chart (#277) 2019-03-12 17:34:04 +01:00
Mikołaj Pich
2621e5680d Improve the display of changes in the timetable (#275)
Closes #264
2019-03-11 20:56:47 +01:00
Rafał Borcz
475e7dd6a3 Update dependencies (#274) 2019-03-10 20:18:40 +01:00
Mikołaj Pich
feb38b97e4 Change login progress bars (#272) 2019-03-10 11:57:11 +01:00
Mikołaj Pich
f773310cdb Disable swipe to refresh on data loading (#270) 2019-03-09 21:40:20 +01:00
Rafał Borcz
f21feabc49 Add debug notification for worker (#271) 2019-03-09 20:34:30 +01:00
Mikołaj Pich
ca23f92096 Add missing text when no grade description (#269) 2019-03-09 17:16:30 +01:00
Rafał Borcz
919680c766 Migration to WorkManager (#254)
Closes #241
2019-03-09 10:13:36 +01:00
Rafał Borcz
722f8d691a Fix timetable widget automatic day switching (#267) 2019-03-07 16:38:34 +01:00
Mikołaj Pich
4f0021919c Fix grade stats loading issues (#266) 2019-03-07 13:08:59 +01:00
Mikołaj Pich
1b7db4bfbb Mitigate disappearing room numbers in timetable (#265) 2019-03-07 13:08:11 +01:00
Mikołaj Pich
dcab8df4b9 Add grade statistics (#251) 2019-03-04 12:13:37 +01:00
Mikołaj Pich
cae4f140e6 Add option to change grade (background) color scheme (#259) 2019-03-03 15:11:20 +01:00
Dominik Korsa
1b30b00bb8 Settings rename view section (#262) 2019-03-02 19:55:32 +01:00
Dominik Korsa
514d1e11aa Update grade colors (#231) 2019-03-02 19:41:38 +01:00
Dominik Korsa
66bd566526 Update login error message (#260) 2019-03-02 19:18:26 +01:00
Mikołaj Pich
e910c7a48e Mitigate notifications from old grades (#258)
Fixes #257
2019-03-02 19:15:37 +01:00
Kacper Ziubryniewicz
f8ee5cb062 Add lucky number logging (#256) 2019-02-24 19:23:03 +01:00
Kacper Ziubryniewicz
c72c301039 Add sending messages (#232) 2019-02-24 15:11:32 +01:00
Mikołaj Pich
5ba12cf8c6 Fill login credentials with default values upon fakelog selection (#255)
Resolves #245
2019-02-23 14:39:22 +01:00
Mikołaj Pich
82d7cf94e8 Mark as read items older than student registration date (#253) 2019-02-20 15:34:24 +01:00
Dominik Korsa
c365564a77 Login form style fix (#252) 2019-02-17 19:15:26 +01:00
Rafał Borcz
5526691cb6 Fix timetable widget crash on update (#250) 2019-02-17 17:32:22 +01:00
Dominik Korsa
1d7585071d Update login form to Material Design 2 (#229) 2019-02-17 00:42:09 +01:00
Mikołaj Pich
11b6c00e4a Entities unification (#248)
* Remove default entieties params

* Change var to vals

* Fix indent in data classes

* Change message unread to val

* Make all fields in Message non-nullable

* Add destructive db migrations #246

* Fix password decrypting

* Fix tests

* Fix student logout

* Use orEmpty() on nullable strings

* Use var in Student password and Message unread
2019-02-16 21:20:23 +01:00
Mikołaj Pich
c56cfec564 Apply ripple effect on grade details header only if item is expandable (#239)
Resolves #234
2019-02-14 22:23:52 +01:00
Mikołaj Pich
f305a7a599 Sort repositories (#244) 2019-02-13 21:44:40 +01:00
Rafał Borcz
ad9b6d42f0 Fix no current student (#243) 2019-02-13 20:49:19 +01:00
Mikołaj Pich
297502056c Add completed lessons (#236) 2019-02-13 19:21:27 +01:00
Kacper Ziubryniewicz
52ed7dcb6c Fix lucky number crash (#242) 2019-02-13 14:10:21 +01:00
Rafał Borcz
9fcf245ecd Fix uninitialized fragment after restoring the activity (#237) 2019-02-12 00:41:02 +01:00
Rafał Borcz
1b1f2ae3bb Split login form for two fragments (#230) 2019-02-11 02:04:24 +01:00
Kacper Ziubryniewicz
2f87779647 Add Firebase Analytics for the loaded lucky number (#233) 2019-02-05 18:18:49 +01:00
Mikołaj Pich
79093ca6f2
Merge branch '0.6.x' 2019-01-26 00:04:11 +01:00
Mikołaj Pich
7f162441e2
Version 0.6.6 2019-01-25 22:12:19 +01:00
Kacper Ziubryniewicz
4da812af39 Add lucky numbers (#216) 2019-01-25 20:54:27 +01:00
Mikołaj Pich
43f6048c27 Upgrade to Gradle Play Publisher v2 (#228) 2019-01-25 20:41:03 +01:00
Rafał Borcz
ffc2ef9a4e Remove renaming source file in R8 (#227) 2019-01-25 19:20:13 +01:00
Rafał Borcz
d3c13b8fc3 Fix empty fragment list in fragment manager (#226) 2019-01-24 21:16:22 +01:00
Kacper Ziubryniewicz
c78fb83774 Fix receiving a lot of notifications after turning them off for a while (#225) 2019-01-24 18:32:51 +01:00
Rafał Borcz
941765a3a3 Fix empty Maybe in student repository (#224) 2019-01-23 18:28:51 +01:00
684 changed files with 35540 additions and 5743 deletions

View file

@ -7,11 +7,11 @@ references:
container_config: &container_config container_config: &container_config
docker: docker:
- image: circleci/android:api-28-alpha - image: circleci/android@sha256:5cdc8626cc6f13efe5ed982cdcdb432b0472f8740fed8743a6461e025ad6cdfc
working_directory: *workspace_root working_directory: *workspace_root
environment: environment:
environment: environment:
JVM_OPTS: -Xmx3200m _JAVA_OPTS: -Xmx3072m
attach_workspace: &attach_workspace attach_workspace: &attach_workspace
attach_workspace: attach_workspace:
@ -35,7 +35,7 @@ jobs:
command: ./gradlew dependencies --no-daemon --stacktrace --console=plain -PdisablePreDex || true command: ./gradlew dependencies --no-daemon --stacktrace --console=plain -PdisablePreDex || true
- run: - run:
name: Initial build 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: - run:
name: Run FOSSA name: Run FOSSA
command: fossa --no-ansi || true command: fossa --no-ansi || true
@ -56,7 +56,7 @@ jobs:
<<: *general_cache_key <<: *general_cache_key
- run: - run:
name: Run lint 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: - store_artifacts:
path: ./app/build/reports/ path: ./app/build/reports/
destination: lint_reports/app/ destination: lint_reports/app/
@ -75,7 +75,7 @@ jobs:
<<: *general_cache_key <<: *general_cache_key
- run: - run:
name: Run app tests 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: - run:
name: Upload unit code coverage to codecov name: Upload unit code coverage to codecov
command: bash <(curl -s https://codecov.io/bash) -F app command: bash <(curl -s https://codecov.io/bash) -F app
@ -93,9 +93,12 @@ jobs:
<<: *container_config <<: *container_config
steps: steps:
- *attach_workspace - *attach_workspace
- run:
name: Accept licenses
command: yes | sdkmanager --licenses && yes | sdkmanager --update
- run: - run:
name: Setup emulator 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: - run:
name: Launch emulator 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 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 adb shell input keyevent 82
- run: - run:
name: Run instrumented tests 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: - run:
name: Collect logs from emulator name: Collect logs from emulator
command: adb logcat -d > ./app/build/reports/logcat_emulator.txt 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 openssl aes-256-cbc -d -in ./app/upload-key-encrypted.jks -k $ENCRYPT_KEY >> ./app/upload-key.jks
- run: - run:
name: Publish release name: Publish release
command: ./gradlew publishRelease --no-daemon --stacktrace --console=plain -PenableCrashlytics -PdisablePreDex command: ./gradlew publishPlayRelease --no-daemon --stacktrace --console=plain -PenableCrashlytics -PdisablePreDex
workflows: workflows:
version: 2 version: 2

114
.gitignore vendored
View file

@ -1,39 +1,90 @@
/captures # Created by https://www.gitignore.io
.externalNativeBuild
## https://gist.github.com/iainconnor/8605514
# Built application files # Built application files
/build *.apk
/*/build/ *.ap_
*.aab
# Crashlytics configuations # Files for the ART/Dalvik VM
com_crashlytics_export_strings.xml *.dex
# Java class files
*.class
# Generated files
bin/
gen/
out/
# Gradle files
.gradle/
build/
# Local configuration file (sdk path, etc) # Local configuration file (sdk path, etc)
local.properties local.properties
# Gradle generated files # Proguard folder generated by Eclipse
.gradle/ proguard/
# Signing files # Log Files
.signing/ *.log
# User-specific configurations # Android Studio Navigation editor temp files
.idea/copyright/profiles_settings.xml .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/libraries/
.idea/inspectionProfiles/ .idea/shelf/
.idea/.name .idea/.name
.idea/compiler.xml .idea/compiler.xml
.idea/copyright/profiles_settings.xml
.idea/encodings.xml .idea/encodings.xml
.idea/misc.xml .idea/misc.xml
.idea/modules.xml
.idea/scopes/scope_settings.xml .idea/scopes/scope_settings.xml
.idea/tasks.xml
.idea/vcs.xml .idea/vcs.xml
.idea/workspace.xml .idea/jsLibraryMappings.xml
.idea/caches/ .idea/datasources.xml
*.iml .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 # OS-specific files
.DS_Store .DS_Store
@ -43,8 +94,21 @@ local.properties
.Trashes .Trashes
ehthumbs.db ehthumbs.db
Thumbs.db Thumbs.db
.idea/caches/
app/key.p12 # Legacy Eclipse project files
app/upload-key.jks .classpath
*.log .project
.idea/assetWizardSettings.xml .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: script:
- ./gradlew --no-daemon --stacktrace dependencies || true - ./gradlew --no-daemon --stacktrace dependencies || true
- ./gradlew --no-daemon --stacktrace assembleDebug - ./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: artifacts:
name: "${CI_PROJECT_NAME}_${CI_BUILD_REF_NAME}-${CI_BUILD_ID}" name: "${CI_PROJECT_NAME}_${CI_BUILD_REF_NAME}-${CI_BUILD_ID}"
paths: paths:
@ -26,7 +26,7 @@ tests:
- .gradle - .gradle
policy: pull policy: pull
script: script:
- ./gradlew --no-daemon --stacktrace -x fabricGenerateResourcesRelease test - ./gradlew --no-daemon --stacktrace -x fabricGenerateResourcesFdroidRelease -x fabricGenerateResourcesPlayRelease test
artifacts: artifacts:
paths: paths:
- app/build/reports/tests - app/build/reports/tests
@ -39,7 +39,7 @@ lint:
- .gradle - .gradle
policy: pull policy: pull
script: script:
- ./gradlew --no-daemon --stacktrace -x fabricGenerateResourcesRelease lint - ./gradlew --no-daemon --stacktrace -x fabricGenerateResourcesFdroidRelease -x fabricGenerateResourcesPlayRelease lint
artifacts: artifacts:
paths: paths:
- app/build/reports - app/build/reports

View file

@ -2,7 +2,7 @@
<code_scheme name="Project" version="173"> <code_scheme name="Project" version="173">
<option name="LINE_SEPARATOR" value="&#10;" /> <option name="LINE_SEPARATOR" value="&#10;" />
<AndroidXmlCodeStyleSettings> <AndroidXmlCodeStyleSettings>
<option name="USE_CUSTOM_SETTINGS" value="true" /> <option name="ARRANGEMENT_SETTINGS_MIGRATED_TO_191" value="true" />
</AndroidXmlCodeStyleSettings> </AndroidXmlCodeStyleSettings>
<JetCodeStyleSettings> <JetCodeStyleSettings>
<option name="PACKAGES_TO_USE_STAR_IMPORTS"> <option name="PACKAGES_TO_USE_STAR_IMPORTS">
@ -19,40 +19,12 @@
<option name="CONTINUATION_INDENT_IN_SUPERTYPE_LISTS" value="false" /> <option name="CONTINUATION_INDENT_IN_SUPERTYPE_LISTS" value="false" />
<option name="CONTINUATION_INDENT_IN_IF_CONDITIONS" value="false" /> <option name="CONTINUATION_INDENT_IN_IF_CONDITIONS" value="false" />
<option name="CONTINUATION_INDENT_IN_ELVIS" value="false" /> <option name="CONTINUATION_INDENT_IN_ELVIS" value="false" />
<option name="WRAP_EXPRESSION_BODY_FUNCTIONS" value="1" /> <option name="WRAP_ELVIS_EXPRESSIONS" value="0" />
</JetCodeStyleSettings> </JetCodeStyleSettings>
<Objective-C-extensions> <MarkdownNavigatorCodeStyleSettings>
<file> <option name="RIGHT_MARGIN" value="72" />
<option name="com.jetbrains.cidr.lang.util.OCDeclarationKind" value="Import" /> </MarkdownNavigatorCodeStyleSettings>
<option name="com.jetbrains.cidr.lang.util.OCDeclarationKind" value="Macro" />
<option name="com.jetbrains.cidr.lang.util.OCDeclarationKind" value="Typedef" />
<option name="com.jetbrains.cidr.lang.util.OCDeclarationKind" value="Enum" />
<option name="com.jetbrains.cidr.lang.util.OCDeclarationKind" value="Constant" />
<option name="com.jetbrains.cidr.lang.util.OCDeclarationKind" value="Global" />
<option name="com.jetbrains.cidr.lang.util.OCDeclarationKind" value="Struct" />
<option name="com.jetbrains.cidr.lang.util.OCDeclarationKind" value="FunctionPredecl" />
<option name="com.jetbrains.cidr.lang.util.OCDeclarationKind" value="Function" />
</file>
<class>
<option name="com.jetbrains.cidr.lang.util.OCDeclarationKind" value="Property" />
<option name="com.jetbrains.cidr.lang.util.OCDeclarationKind" value="Synthesize" />
<option name="com.jetbrains.cidr.lang.util.OCDeclarationKind" value="InitMethod" />
<option name="com.jetbrains.cidr.lang.util.OCDeclarationKind" value="StaticMethod" />
<option name="com.jetbrains.cidr.lang.util.OCDeclarationKind" value="InstanceMethod" />
<option name="com.jetbrains.cidr.lang.util.OCDeclarationKind" value="DeallocMethod" />
</class>
<extensions>
<pair source="cpp" header="h" fileNamingConvention="NONE" />
<pair source="c" header="h" fileNamingConvention="NONE" />
</extensions>
</Objective-C-extensions>
<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>
<codeStyleSettings language="XML"> <codeStyleSettings language="XML">
<option name="FORCE_REARRANGE_MODE" value="1" />
<indentOptions> <indentOptions>
<option name="CONTINUATION_INDENT_SIZE" value="4" /> <option name="CONTINUATION_INDENT_SIZE" value="4" />
</indentOptions> </indentOptions>
@ -63,6 +35,7 @@
<match> <match>
<AND> <AND>
<NAME>xmlns:android</NAME> <NAME>xmlns:android</NAME>
<XML_ATTRIBUTE />
<XML_NAMESPACE>^$</XML_NAMESPACE> <XML_NAMESPACE>^$</XML_NAMESPACE>
</AND> </AND>
</match> </match>
@ -73,6 +46,7 @@
<match> <match>
<AND> <AND>
<NAME>xmlns:.*</NAME> <NAME>xmlns:.*</NAME>
<XML_ATTRIBUTE />
<XML_NAMESPACE>^$</XML_NAMESPACE> <XML_NAMESPACE>^$</XML_NAMESPACE>
</AND> </AND>
</match> </match>
@ -84,6 +58,7 @@
<match> <match>
<AND> <AND>
<NAME>.*:id</NAME> <NAME>.*:id</NAME>
<XML_ATTRIBUTE />
<XML_NAMESPACE>http://schemas.android.com/apk/res/android</XML_NAMESPACE> <XML_NAMESPACE>http://schemas.android.com/apk/res/android</XML_NAMESPACE>
</AND> </AND>
</match> </match>
@ -94,6 +69,7 @@
<match> <match>
<AND> <AND>
<NAME>.*:name</NAME> <NAME>.*:name</NAME>
<XML_ATTRIBUTE />
<XML_NAMESPACE>http://schemas.android.com/apk/res/android</XML_NAMESPACE> <XML_NAMESPACE>http://schemas.android.com/apk/res/android</XML_NAMESPACE>
</AND> </AND>
</match> </match>
@ -104,6 +80,7 @@
<match> <match>
<AND> <AND>
<NAME>name</NAME> <NAME>name</NAME>
<XML_ATTRIBUTE />
<XML_NAMESPACE>^$</XML_NAMESPACE> <XML_NAMESPACE>^$</XML_NAMESPACE>
</AND> </AND>
</match> </match>
@ -114,6 +91,7 @@
<match> <match>
<AND> <AND>
<NAME>style</NAME> <NAME>style</NAME>
<XML_ATTRIBUTE />
<XML_NAMESPACE>^$</XML_NAMESPACE> <XML_NAMESPACE>^$</XML_NAMESPACE>
</AND> </AND>
</match> </match>
@ -124,6 +102,7 @@
<match> <match>
<AND> <AND>
<NAME>.*</NAME> <NAME>.*</NAME>
<XML_ATTRIBUTE />
<XML_NAMESPACE>^$</XML_NAMESPACE> <XML_NAMESPACE>^$</XML_NAMESPACE>
</AND> </AND>
</match> </match>
@ -135,6 +114,7 @@
<match> <match>
<AND> <AND>
<NAME>.*</NAME> <NAME>.*</NAME>
<XML_ATTRIBUTE />
<XML_NAMESPACE>http://schemas.android.com/apk/res/android</XML_NAMESPACE> <XML_NAMESPACE>http://schemas.android.com/apk/res/android</XML_NAMESPACE>
</AND> </AND>
</match> </match>
@ -146,6 +126,7 @@
<match> <match>
<AND> <AND>
<NAME>.*</NAME> <NAME>.*</NAME>
<XML_ATTRIBUTE />
<XML_NAMESPACE>.*</XML_NAMESPACE> <XML_NAMESPACE>.*</XML_NAMESPACE>
</AND> </AND>
</match> </match>
@ -163,7 +144,6 @@
<option name="METHOD_PARAMETERS_LPAREN_ON_NEXT_LINE" value="true" /> <option name="METHOD_PARAMETERS_LPAREN_ON_NEXT_LINE" value="true" />
<option name="METHOD_PARAMETERS_RPAREN_ON_NEXT_LINE" value="true" /> <option name="METHOD_PARAMETERS_RPAREN_ON_NEXT_LINE" value="true" />
<option name="EXTENDS_LIST_WRAP" value="1" /> <option name="EXTENDS_LIST_WRAP" value="1" />
<option name="METHOD_CALL_CHAIN_WRAP" value="1" />
<indentOptions> <indentOptions>
<option name="CONTINUATION_INDENT_SIZE" value="4" /> <option name="CONTINUATION_INDENT_SIZE" value="4" />
</indentOptions> </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,14 +3,19 @@ jdk: oraclejdk8
env: env:
global: global:
- ANDROID_API_LEVEL=28 - ANDROID_API_LEVEL=29
- ANDROID_BUILD_TOOLS_VERSION=28.0.3 - ANDROID_BUILD_TOOLS_VERSION=29.0.2
cache: cache:
directories: directories:
- $HOME/.gradle/caches/ - $HOME/.gradle/caches/
- $HOME/.gradle/wrapper/ - $HOME/.gradle/wrapper/
branches:
only:
- develop
- 0.14.1
android: android:
licenses: licenses:
- android-sdk-preview-license-.+ - android-sdk-preview-license-.+
@ -29,34 +34,34 @@ android:
- extra-android-m2repository - extra-android-m2repository
- addon-google_apis-google-$ANDROID_API_LEVEL - addon-google_apis-google-$ANDROID_API_LEVEL
# Android emulator # Android emulator
- android-19 - android-22
- sys-img-armeabi-v7a-android-19 - sys-img-armeabi-v7a-android-22
before_script: before_script:
# Launch emulator before the execution # 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 & - emulator -avd test -no-audio -no-window &
- android-wait-for-emulator - android-wait-for-emulator
- adb shell input keyevent 82 & - adb shell input keyevent 82 &
- "curl -H 'Cache-Control: no-cache' https://raw.githubusercontent.com/fossas/fossa-cli/master/install.sh | sudo bash" - "curl -H 'Cache-Control: no-cache' https://raw.githubusercontent.com/fossas/fossa-cli/master/install.sh | sudo bash"
script: script:
- ./gradlew build -x test -x lint -x fabricGenerateResourcesRelease -x packageRelease --stacktrace --daemon - ./gradlew dependencies --stacktrace --daemon
- fossa --no-ansi || true - fossa --no-ansi || true
- ./gradlew lint -x fabricGenerateResourcesRelease --stacktrace --daemon #- ./gradlew lintPlayRelease -x fabricGenerateResourcesPlayRelease --stacktrace --daemon
- ./gradlew test -x fabricGenerateResourcesRelease --stacktrace --daemon - ./gradlew testPlayDebugUnitTest -x fabricGenerateResourcesPlay --stacktrace --daemon
- ./gradlew createDebugCoverageReport --stacktrace --daemon - ./gradlew createFdroidDebugCoverageReport --stacktrace --daemon
- ./gradlew jacocoTestReport --stacktrace --daemon - ./gradlew jacocoTestReport --stacktrace --daemon
- if [ -z ${SONAR_HOST+x} ]; then echo "sonar scan skipped"; else - if [ -z ${SONAR_HOST+x} ]; then echo "sonar scan skipped"; else
git fetch --unshallow; 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 fi
- | - |
if [ $TRAVIS_TAG ]; then if [ $TRAVIS_TAG ]; then
gpg --yes --batch --passphrase=$SERVICES_ENCRYPT_KEY ./app/src/release/google-services.json.gpg; 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/key.p12.gpg;
gpg --yes --batch --passphrase=$ENCRYPT_KEY ./app/upload-key.jks.gpg; gpg --yes --batch --passphrase=$ENCRYPT_KEY ./app/upload-key.jks.gpg;
./gradlew publishRelease -PenableCrashlytics --stacktrace; ./gradlew publishPlayRelease -PenableCrashlytics --stacktrace;
fi fi
after_success: after_success:

View file

@ -186,7 +186,7 @@
same "printed page" as the copyright notice for easier same "printed page" as the copyright notice for easier
identification within third-party archives. identification within third-party archives.
Copyright 2017 wulkanowy Copyright 2019 Wulkanowy
Licensed under the Apache License, Version 2.0 (the "License"); Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with 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 both students and their parents
## Features
* logging in using the email and password OR using token and pin
* 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 independently of school's preferences
* notifications, e.g. about a new grade
* dark and black (AMOLED) theme
* offline mode
* no ads
## Download
You can download the current beta version from the Google Play or the F-Droid 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 F-Droid"
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 being prepared for the next release
## Built With
* [Wulkanowy SDK](https://github.com/wulkanowy/sdk)
* [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 # 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) [![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) [![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.io/api/projects/custom%2B5644%2Fgit%40github.com%3Awulkanowy%2Fwulkanowy.git.svg?type=shield)](https://app.fossa.io/projects/custom%2B5644%2Fgit%40github.com%3Awulkanowy%2Fwulkanowy.git?ref=badge_shield)
[![Discord](https://img.shields.io/discord/390889354199040011.svg?style=flat-square)](https://discord.gg/vccAQBr) [![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/daeff1893f3c8128/builds/master/artifacts/0) ## Funkcje
[(Więcej wersji DEV)](https://wulkanowy.github.io/dev.html)
Androidowy klient dziennika VULCAN UONET+. * logowanie za pomocą e-maila i hasła LUB tokena i pinu
* 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 niezależnie od preferencji szkoły
* 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 F-Droid
[<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 F-Droid"
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.io/api/projects/custom%2B5644%2Fgit%40github.com%3Awulkanowy%2Fwulkanowy.git.svg?type=large)](https://app.fossa.io/projects/custom%2B5644%2Fgit%40github.com%3Awulkanowy%2Fwulkanowy.git?ref=badge_large)
## Zbudowana za pomocą
* [Wulkanowy SDK](https://github.com/wulkanowy/SDK)
* [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 udostępniany jest na licencji Apache License 2.0 - szczegóły w pliku [LICENSE](LICENSE)

1
app/.gitignore vendored
View file

@ -1 +0,0 @@
/build

View file

@ -6,33 +6,38 @@ apply plugin: 'io.fabric'
apply plugin: 'com.github.triplet.play' apply plugin: 'com.github.triplet.play'
apply from: 'jacoco.gradle' apply from: 'jacoco.gradle'
apply from: 'sonarqube.gradle' apply from: 'sonarqube.gradle'
apply from: 'hooks.gradle'
android { android {
compileSdkVersion 28 compileSdkVersion 29
buildToolsVersion '28.0.3' buildToolsVersion '29.0.2'
playAccountConfigs {
defaultAccountConfig {
serviceAccountEmail = System.getenv("PLAY_SERVICE_ACCOUNT_EMAIL")
pk12File = file('key.p12')
}
}
defaultConfig { defaultConfig {
applicationId "io.github.wulkanowy" applicationId "io.github.wulkanowy"
testApplicationId "io.github.tests.wulkanowy" testApplicationId "io.github.tests.wulkanowy"
minSdkVersion 15 minSdkVersion 16
targetSdkVersion 28 targetSdkVersion 29
versionCode 24 versionCode 50
versionName "0.6.5" versionName "0.14.1"
multiDexEnabled true multiDexEnabled true
testInstrumentationRunner "androidx.test.runner.AndroidJUnitRunner" testInstrumentationRunner "androidx.test.runner.AndroidJUnitRunner"
vectorDrawables.useSupportLibrary = true vectorDrawables.useSupportLibrary = true
playAccountConfig = playAccountConfigs.defaultAccountConfig
manifestPlaceholders = [ manifestPlaceholders = [
fabric_api_key: System.getenv("FABRIC_API_KEY") ?: "null", fabric_api_key : System.getenv("FABRIC_API_KEY") ?: "null",
crashlytics_enabled: project.hasProperty("enableCrashlytics") crashlytics_enabled: project.hasProperty("enableCrashlytics")
] ]
javaCompileOptions {
annotationProcessorOptions {
arguments = [
"room.schemaLocation": "$projectDir/schemas".toString(),
"room.incremental" : "true"
]
}
}
}
sourceSets {
androidTest.assets.srcDirs += files("$projectDir/schemas".toString())
} }
signingConfigs { signingConfigs {
@ -58,13 +63,39 @@ android {
versionNameSuffix "-dev" versionNameSuffix "-dev"
testCoverageEnabled = true testCoverageEnabled = true
ext.enableCrashlytics = project.hasProperty("enableCrashlytics") 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"
} }
} }
lintOptions { lintOptions {
disable 'HardwareIds' disable 'HardwareIds'
} }
compileOptions {
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 { androidExtensions {
@ -72,66 +103,100 @@ androidExtensions {
} }
play { play {
serviceAccountEmail = System.getenv("PLAY_SERVICE_ACCOUNT_EMAIL") ?: "jan@fakelog.cf"
serviceAccountCredentials = file('key.p12')
defaultToAppBundles = false
track = 'alpha' track = 'alpha'
uploadImages = false }
ext {
work_manager = "2.3.0-rc01"
room = "2.2.3"
dagger = "2.25.4"
chucker = "2.0.4"
mockk = "1.9.2"
}
configurations.all {
resolutionStrategy.force "androidx.constraintlayout:constraintlayout:1.1.3"
} }
dependencies { dependencies {
implementation "io.github.wulkanowy:sdk:0.14.1"
implementation "org.jetbrains.kotlin:kotlin-stdlib-jdk8:$kotlin_version" implementation "org.jetbrains.kotlin:kotlin-stdlib-jdk8:$kotlin_version"
implementation "org.jetbrains.kotlin:kotlin-reflect:$kotlin_version" implementation "androidx.core:core-ktx:1.2.0-rc01"
implementation('io.github.wulkanowy:api:0.6.4') { exclude module: "threetenbp" } 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-rc05"
implementation "androidx.annotation:annotation:1.1.0"
implementation "androidx.multidex:multidex:2.0.1"
implementation "androidx.legacy:legacy-support-v4:1.0.0" implementation "androidx.preference:preference-ktx:1.1.0"
implementation "androidx.appcompat:appcompat:1.0.2" implementation "androidx.recyclerview:recyclerview:1.1.0"
implementation "androidx.cardview:cardview:1.0.0" implementation "androidx.viewpager:viewpager:1.0.0"
implementation "com.google.android.material:material:1.0.0" implementation "androidx.swiperefreshlayout:swiperefreshlayout:1.1.0-alpha03"
implementation 'androidx.multidex:multidex:2.0.1' implementation "androidx.constraintlayout:constraintlayout:1.1.3"
implementation "androidx.coordinatorlayout:coordinatorlayout:1.1.0"
implementation "com.google.android.material:material:1.1.0-rc01"
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 'com.takisoft.preferencex:preferencex:1.0.0' implementation "androidx.work:work-runtime-ktx:$work_manager"
implementation "com.mikepenz:aboutlibraries:6.2.0" implementation "androidx.work:work-rxjava2:$work_manager"
implementation "com.firebase:firebase-jobdispatcher:0.8.5" implementation "androidx.work:work-gcm:$work_manager"
implementation "com.google.dagger:dagger-android-support:2.21" implementation "androidx.room:room-runtime:$room"
kapt "com.google.dagger:dagger-compiler:2.21" implementation "androidx.room:room-rxjava2:$room"
kapt "com.google.dagger:dagger-android-processor:2.21" implementation "androidx.room:room-ktx:$room"
kapt "androidx.room:room-compiler:$room"
implementation "androidx.room:room-runtime:2.1.0-alpha03" implementation "com.google.dagger:dagger-android-support:$dagger"
implementation "androidx.room:room-rxjava2:2.1.0-alpha03" kapt "com.google.dagger:dagger-compiler:$dagger"
kapt "androidx.room:room-compiler:2.1.0-alpha03" 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:5.1.0"
implementation "eu.davidea:flexible-adapter-ui:1.0.0" implementation "eu.davidea:flexible-adapter-ui:1.0.0"
implementation "com.aurelhubert:ahbottomnavigation:2.3.4" implementation "com.aurelhubert:ahbottomnavigation:2.3.4"
implementation 'com.ncapdevi:frag-nav:3.1.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 "com.github.pwittchen:reactivenetwork-rx2:3.0.6"
implementation 'io.reactivex.rxjava2:rxandroid:2.1.0' implementation "io.reactivex.rxjava2:rxandroid:2.1.1"
implementation "io.reactivex.rxjava2:rxjava:2.2.5" implementation "io.reactivex.rxjava2:rxjava:2.2.16"
implementation "com.jakewharton.threetenabp:threetenabp:1.1.1"
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 "com.jakewharton.timber:timber:4.7.1"
implementation "at.favre.lib:slf4j-timber:1.0.1" implementation "at.favre.lib:slf4j-timber:1.0.1"
implementation "com.squareup.okhttp3:logging-interceptor:3.12.7"
implementation "com.mikepenz:aboutlibraries-core:7.1.0"
implementation 'com.wdullaer:materialdatetimepicker:4.2.3'
implementation 'com.google.firebase:firebase-core:16.0.6' playImplementation "com.google.firebase:firebase-core:17.2.1"
implementation 'com.crashlytics.sdk.android:crashlytics:2.9.8' playImplementation "com.crashlytics.sdk.android:crashlytics:2.10.1"
releaseImplementation 'fr.o80.chucker:library-no-op:2.0.3' releaseImplementation "fr.o80.chucker:library-no-op:$chucker"
debugImplementation 'fr.o80.chucker:library:2.0.3'
debugImplementation "com.amitshekhar.android:debug-db:1.0.4" debugImplementation "fr.o80.chucker:library:$chucker"
debugImplementation "com.amitshekhar.android:debug-db:1.0.6"
testImplementation "junit:junit:4.12" testImplementation "junit:junit:4.13"
testImplementation "io.mockk:mockk:1.9" testImplementation "io.mockk:mockk:$mockk"
testImplementation "org.mockito:mockito-inline:2.23.4" testImplementation "org.threeten:threetenbp:1.4.0"
testImplementation 'org.threeten:threetenbp:1.3.8' testImplementation "org.mockito:mockito-inline:3.2.4"
androidTestImplementation 'androidx.test:core:1.1.0' androidTestImplementation "androidx.test:core:1.2.0"
androidTestImplementation 'androidx.test:runner:1.1.1' androidTestImplementation "androidx.test:runner:1.2.0"
androidTestImplementation 'androidx.test.ext:junit:1.1.0' androidTestImplementation "androidx.test.ext:junit:1.1.1"
androidTestImplementation 'org.mockito:mockito-android:2.23.4' androidTestImplementation "io.mockk:mockk-android:$mockk"
androidTestImplementation "androidx.room:room-testing:$room"
androidTestImplementation "org.jetbrains.kotlin:kotlin-test:$kotlin_version" androidTestImplementation "org.jetbrains.kotlin:kotlin-test:$kotlin_version"
androidTestImplementation "org.mockito:mockito-android:3.2.4"
} }
apply plugin: 'com.google.gms.google-services' 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" apply plugin: "jacoco"
jacoco { jacoco {
toolVersion "0.8.2" toolVersion "0.8.4"
reportsDir = file("$buildDir/reports") reportsDir = file("$buildDir/reports")
} }
@ -31,17 +31,20 @@ task jacocoTestReport(type: JacocoReport) {
'**/*_Provide*Factory*.*', '**/*_Provide*Factory*.*',
'**/*_Factory.*'] '**/*_Factory.*']
classDirectories = fileTree( classDirectories.setFrom(fileTree(
dir: "$buildDir/intermediates/classes/debug", dir: "$buildDir/intermediates/classes/debug",
excludes: excludes excludes: excludes
) + fileTree( ) + fileTree(
dir: "$buildDir/tmp/kotlin-classes/debug", dir: "$buildDir/tmp/kotlin-classes/playDebug",
excludes: excludes excludes: excludes
) ))
sourceDirectories = files("$project.projectDir/src/main/java") sourceDirectories.setFrom(files([
executionData = fileTree( "src/main/java",
"src/play/java"
]))
executionData.setFrom(fileTree(
dir: project.projectDir, dir: project.projectDir,
includes: ["**/*.exec", "**/*.ec"] 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,10 +11,13 @@
-verbose -verbose
#Keep all wulkanowy files
-keep class io.github.wulkanowy.** {*;}
#Config for anallitycs #Config for anallitycs
-keepattributes *Annotation* -keepattributes *Annotation*
-keepattributes SourceFile,LineNumberTable -keepattributes SourceFile,LineNumberTable
-renamesourcefileattribute SourceFile
-keep class com.crashlytics.** {*;} -keep class com.crashlytics.** {*;}
-keep public class * extends java.lang.Exception -keep public class * extends java.lang.Exception
-dontwarn com.crashlytics.** -dontwarn com.crashlytics.**
@ -33,5 +36,10 @@
-dontwarn rx.internal.util.** -dontwarn rx.internal.util.**
-dontwarn sun.misc.Unsafe -dontwarn sun.misc.Unsafe
#Config for API
-keep class io.github.wulkanowy.api.** {*;} #Config for MPAndroidChart
-keep class com.github.mikephil.charting.** { *; }
#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

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.java.coveragePlugin", "jacoco"
property "sonar.android.lint.report", "build/reports/lint-results.xml" property "sonar.android.lint.report", "build/reports/lint-results.xml"
property "sonar.jacoco.reportPaths", fileTree(dir: project.projectDir, includes: ['**/*.exec', '**/*.ec']) property "sonar.jacoco.reportPaths", fileTree(dir: project.projectDir, includes: ['**/*.exec', '**/*.ec'])
property "sonar.coverage.jacoco.xmlReportPaths", "build/reports/jacocoTestReport/jacocoTestReport.xml"
} }
} }

View file

@ -0,0 +1,35 @@
package io.github.wulkanowy.data.db.migrations
import androidx.preference.PreferenceManager
import androidx.room.Room
import androidx.room.testing.MigrationTestHelper
import androidx.sqlite.db.framework.FrameworkSQLiteOpenHelperFactory
import androidx.test.core.app.ApplicationProvider
import androidx.test.platform.app.InstrumentationRegistry
import io.github.wulkanowy.data.db.AppDatabase
import io.github.wulkanowy.data.db.SharedPrefProvider
import org.junit.Rule
abstract class AbstractMigrationTest {
val dbName = "migration-test"
@get:Rule
val helper: MigrationTestHelper = MigrationTestHelper(
InstrumentationRegistry.getInstrumentation(),
AppDatabase::class.java.canonicalName,
FrameworkSQLiteOpenHelperFactory()
)
fun getMigratedRoomDatabase(): AppDatabase {
val database = Room.databaseBuilder(ApplicationProvider.getApplicationContext(),
AppDatabase::class.java, dbName)
.addMigrations(*AppDatabase.getMigrations(SharedPrefProvider(PreferenceManager
.getDefaultSharedPreferences(ApplicationProvider.getApplicationContext())))
)
.build()
// close the database and release any stream resources when the test finishes
helper.closeWhenFinished(database)
return database
}
}

View file

@ -0,0 +1,133 @@
package io.github.wulkanowy.data.db.migrations
import android.content.ContentValues
import android.database.sqlite.SQLiteDatabase.CONFLICT_FAIL
import androidx.sqlite.db.SupportSQLiteDatabase
import androidx.test.ext.junit.runners.AndroidJUnit4
import org.junit.Test
import org.junit.runner.RunWith
import kotlin.test.assertEquals
@RunWith(AndroidJUnit4::class)
class Migration12Test : AbstractMigrationTest() {
@Test
fun twoNotRelatedStudents() {
helper.createDatabase(dbName, 11).apply {
// user 1
createStudent(this, 1, true)
createSemester(this, 1, false, 5, 1)
createSemester(this, 1, true, 5, 2)
// user 2
createStudent(this, 2, true)
createSemester(this, 2, false, 6, 1)
createSemester(this, 2, true, 6, 2)
close()
}
helper.runMigrationsAndValidate(dbName, 12, true, Migration12())
val db = getMigratedRoomDatabase()
val students = db.studentDao.loadAll().blockingGet()
assertEquals(2, students.size)
students[0].run {
assertEquals(1, studentId)
assertEquals(5, classId)
}
students[1].run {
assertEquals(2, studentId)
assertEquals(6, classId)
}
}
@Test
fun removeStudentsWithoutClassId() {
helper.createDatabase(dbName, 11).apply {
// user 1
createStudent(this, 1, true)
createSemester(this, 1, false, 0, 2)
createStudent(this, 2, true)
createSemester(this, 2, true, 1, 2)
close()
}
helper.runMigrationsAndValidate(dbName, 12, true, Migration12())
val db = getMigratedRoomDatabase()
val students = db.studentDao.loadAll().blockingGet()
assertEquals(1, students.size)
students[0].run {
assertEquals(2, studentId)
assertEquals(1, classId)
}
}
@Test
fun ensureThereIsOnlyOneCurrentStudent() {
helper.createDatabase(dbName, 11).apply {
// user 1
createStudent(this, 1, true)
createSemester(this, 1, true, 5, 2)
createStudent(this, 2, true)
createSemester(this, 2, true, 6, 2)
createStudent(this, 3, true)
createSemester(this, 3, false, 7, 2)
close()
}
helper.runMigrationsAndValidate(dbName, 12, true, Migration12())
val db = getMigratedRoomDatabase()
val students = db.studentDao.loadAll().blockingGet()
assertEquals(3, students.size)
students[0].run {
assertEquals(studentId, 1)
assertEquals(false, isCurrent)
}
students[1].run {
assertEquals(studentId, 2)
assertEquals(false, isCurrent)
}
students[2].run {
assertEquals(studentId, 3)
assertEquals(true, isCurrent)
}
}
private fun createStudent(db: SupportSQLiteDatabase, studentId: Int, isCurrent: Boolean) {
db.insert("Students", CONFLICT_FAIL, ContentValues().apply {
put("endpoint", "https://fakelog.cf")
put("loginType", "STANDARD")
put("email", "jan@fakelog.cf")
put("password", "******")
put("symbol", "Default")
put("student_id", studentId)
put("student_name", "Jan Kowalski")
put("school_id", "000123")
put("school_name", "")
put("is_current", isCurrent)
put("registration_date", "0")
})
}
private fun createSemester(db: SupportSQLiteDatabase, studentId: Int, isCurrent: Boolean, classId: Int, diaryId: Int) {
db.insert("Semesters", CONFLICT_FAIL, ContentValues().apply {
put("student_id", studentId)
put("diary_id", diaryId)
put("diary_name", "IA")
put("semester_id", diaryId * 5)
put("semester_name", "1")
put("is_current", isCurrent)
put("class_id", classId)
put("unit_id", "99")
})
}
}

View file

@ -0,0 +1,197 @@
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.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() {
@Test
fun studentsWithSchoolNameWithClassName() {
helper.createDatabase(dbName, 12).apply {
createStudent(this, 1, "Klasa A - Publiczna szkoła Wulkanowego nr 1 w fakelog.cf", 1, 1)
createStudent(this, 2, "Klasa B - Publiczna szkoła Wulkanowego-fejka nr 1 w fakelog.cf", 2, 1)
createStudent(this, 2, "Klasa C - Publiczna szkoła Wulkanowego-fejka nr 2 w fakelog.cf", 1, 2)
close()
}
helper.runMigrationsAndValidate(dbName, 13, true, Migration13())
val db = getMigratedRoomDatabase()
val students = db.studentDao.loadAll().blockingGet()
assertEquals(3, students.size)
students[0].run {
assertEquals(1, studentId)
assertEquals("A", className)
assertEquals("Publiczna szkoła Wulkanowego nr 1 w fakelog.cf", schoolName)
}
students[1].run {
assertEquals(2, studentId)
assertEquals("B", className)
assertEquals("Publiczna szkoła Wulkanowego-fejka nr 1 w fakelog.cf", schoolName)
}
students[2].run {
assertEquals(2, studentId)
assertEquals("C", className)
assertEquals("Publiczna szkoła Wulkanowego-fejka nr 2 w fakelog.cf", schoolName)
}
}
@Test
fun studentsWithSchoolNameWithoutClassName() {
helper.createDatabase(dbName, 12).apply {
createStudent(this, 1, "Publiczna szkoła Wulkanowego nr 1 w fakelog.cf", 1)
createStudent(this, 2, "Publiczna szkoła Wulkanowego-fejka nr 1 w fakelog.cf", 1)
close()
}
helper.runMigrationsAndValidate(dbName, 13, true, Migration13())
val db = getMigratedRoomDatabase()
val students = db.studentDao.loadAll().blockingGet()
assertEquals(2, students.size)
students[0].run {
assertEquals(1, studentId)
assertEquals("", className)
assertEquals("Publiczna szkoła Wulkanowego nr 1 w fakelog.cf", schoolName)
}
students[1].run {
assertEquals(2, studentId)
assertEquals("", className)
assertEquals("Publiczna szkoła Wulkanowego-fejka nr 1 w fakelog.cf", schoolName)
}
}
@Test
fun markAtLeastAndOnlyOneSemesterAtCurrent() {
helper.createDatabase(dbName, 12).apply {
createStudent(this, 1, "", 5)
createSemester(this, 1, 5, 1, 1, false)
createSemester(this, 1, 5, 2, 1, false)
createSemester(this, 1, 5, 3, 2, false)
createSemester(this, 1, 5, 4, 2, false)
createStudent(this, 2, "", 5)
createSemester(this, 2, 5, 5, 5, true)
createSemester(this, 2, 5, 6, 5, true)
createSemester(this, 2, 5, 7, 55, true)
createSemester(this, 2, 5, 8, 55, true)
createStudent(this, 3, "", 5)
createSemester(this, 3, 5, 11, 99, false)
createSemester(this, 3, 5, 12, 99, false)
createSemester(this, 3, 5, 13, 100, false)
createSemester(this, 3, 5, 14, 100, true)
close()
}
val db = helper.runMigrationsAndValidate(dbName, 13, true, Migration13())
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)
assertEquals(1, semesterId)
assertEquals(1, diaryId)
}
semesters1[2].run {
assertFalse(isCurrent)
assertEquals(3, semesterId)
assertEquals(2, diaryId)
}
semesters1[3].run {
assertTrue(isCurrent)
assertEquals(4, semesterId)
assertEquals(2, diaryId)
}
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)
assertEquals(of(1970, 1, 1), it[0].start)
assertFalse(it[0].isCurrent)
assertFalse(it[1].isCurrent)
assertFalse(it[2].isCurrent)
assertTrue(it[3].isCurrent)
}
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)
assertFalse(it[2].isCurrent)
assertTrue(it[3].isCurrent)
}
}
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")
put("loginType", "STANDARD")
put("email", "jan@fakelog.cf")
put("password", "******")
put("symbol", "Default")
put("student_id", studentId)
put("class_id", classId)
put("student_name", "Jan Kowalski")
put("school_id", schoolId)
put("school_name", schoolName)
put("is_current", false)
put("registration_date", "0")
})
}
private fun createSemester(db: SupportSQLiteDatabase, studentId: Int, classId: Int, semesterId: Int, diaryId: Int, isCurrent: Boolean = false) {
db.insert("Semesters", SQLiteDatabase.CONFLICT_FAIL, ContentValues().apply {
put("student_id", studentId)
put("diary_id", diaryId)
put("diary_name", "IA")
put("semester_id", semesterId)
put("semester_name", "1")
put("is_current", isCurrent)
put("class_id", classId)
put("unit_id", "99")
})
}
}

View file

@ -0,0 +1,19 @@
package io.github.wulkanowy.data.repositories
import com.github.pwittchen.reactivenetwork.library.rx2.internet.observing.InternetObservingStrategy
import com.github.pwittchen.reactivenetwork.library.rx2.internet.observing.error.ErrorHandler
import io.reactivex.Observable
import io.reactivex.Single
class TestInternetObservingStrategy : InternetObservingStrategy {
override fun checkInternetConnectivity(host: String?, port: Int, timeoutInMs: Int, httpResponse: Int, errorHandler: ErrorHandler?): Single<Boolean> {
return Single.just(true)
}
override fun observeInternetConnectivity(initialIntervalInMs: Int, intervalInMs: Int, host: String?, port: Int, timeoutInMs: Int, httpResponse: Int, errorHandler: ErrorHandler?): Observable<Boolean> {
return Observable.just(true)
}
override fun getDefaultPingHost() = "localhost"
}

View file

@ -1,4 +1,4 @@
package io.github.wulkanowy.data.repositories.local package io.github.wulkanowy.data.repositories.attendance
import androidx.room.Room import androidx.room.Room
import androidx.test.core.app.ApplicationProvider import androidx.test.core.app.ApplicationProvider
@ -11,6 +11,7 @@ import org.junit.Before
import org.junit.Test import org.junit.Test
import org.junit.runner.RunWith import org.junit.runner.RunWith
import org.threeten.bp.LocalDate import org.threeten.bp.LocalDate
import org.threeten.bp.LocalDate.now
import kotlin.test.assertEquals import kotlin.test.assertEquals
@RunWith(AndroidJUnit4::class) @RunWith(AndroidJUnit4::class)
@ -34,13 +35,13 @@ class AttendanceLocalTest {
@Test @Test
fun saveAndReadTest() { fun saveAndReadTest() {
attendanceLocal.saveAttendance(listOf( attendanceLocal.saveAttendance(listOf(
Attendance(1, 2, LocalDate.of(2018, 9, 10), 0, "", ""), Attendance(1, 2, LocalDate.of(2018, 9, 10), 0, "", "", false, false, false, false, false, false),
Attendance(1, 2, LocalDate.of(2018, 9, 14), 0, "", ""), Attendance(1, 2, LocalDate.of(2018, 9, 14), 0, "", "", false, false, false, false, false, false),
Attendance(1, 2, LocalDate.of(2018, 9, 17), 0, "", "") Attendance(1, 2, LocalDate.of(2018, 9, 17), 0, "", "", false, false, false, false, false, false)
)) ))
val attendance = attendanceLocal val attendance = attendanceLocal
.getAttendance(Semester(1, 1, 2, "", 3, 1), .getAttendance(Semester(1, 2, "", 1, 3, 2019, true, now(), now(), 1, 1),
LocalDate.of(2018, 9, 10), LocalDate.of(2018, 9, 10),
LocalDate.of(2018, 9, 14) LocalDate.of(2018, 9, 14)
) )

View file

@ -0,0 +1,57 @@
package io.github.wulkanowy.data.repositories.completedlessons
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.CompletedLesson
import io.github.wulkanowy.data.db.entities.Semester
import org.junit.After
import org.junit.Before
import org.junit.Test
import org.junit.runner.RunWith
import org.threeten.bp.LocalDate
import kotlin.test.assertEquals
@RunWith(AndroidJUnit4::class)
class CompletedLessonsLocalTest {
private lateinit var completedLessonsLocal: CompletedLessonsLocal
private lateinit var testDb: AppDatabase
@Before
fun createDb() {
testDb = Room.inMemoryDatabaseBuilder(ApplicationProvider.getApplicationContext(), AppDatabase::class.java)
.build()
completedLessonsLocal = CompletedLessonsLocal(testDb.completedLessonsDao)
}
@After
fun closeDb() {
testDb.close()
}
@Test
fun saveAndReadTest() {
completedLessonsLocal.saveCompletedLessons(listOf(
getCompletedLesson(LocalDate.of(2018, 9, 10), 1),
getCompletedLesson(LocalDate.of(2018, 9, 14), 2),
getCompletedLesson(LocalDate.of(2018, 9, 17), 3)
))
val completed = completedLessonsLocal
.getCompletedLessons(Semester(1, 2, "", 1, 3, 2019, true, LocalDate.now(), LocalDate.now(), 1, 1),
LocalDate.of(2018, 9, 10),
LocalDate.of(2018, 9, 14)
)
.blockingGet()
assertEquals(2, completed.size)
assertEquals(completed[0].date, LocalDate.of(2018, 9, 10))
assertEquals(completed[1].date, LocalDate.of(2018, 9, 14))
}
private fun getCompletedLesson(date: LocalDate, number: Int): CompletedLesson {
return CompletedLesson(1, 2, date, number, "", "", "", "", "", "", "")
}
}

View file

@ -1,4 +1,4 @@
package io.github.wulkanowy.data.repositories.local package io.github.wulkanowy.data.repositories.exam
import androidx.room.Room import androidx.room.Room
import androidx.test.core.app.ApplicationProvider import androidx.test.core.app.ApplicationProvider
@ -40,7 +40,7 @@ class ExamLocalTest {
)) ))
val exams = examLocal val exams = examLocal
.getExams(Semester(1, 1, 2, "", 3, 1), .getExams(Semester(1, 2, "", 1, 3, 2019, true, LocalDate.now(), LocalDate.now(), 1, 1),
LocalDate.of(2018, 9, 10), LocalDate.of(2018, 9, 10),
LocalDate.of(2018, 9, 14) LocalDate.of(2018, 9, 14)
) )

View file

@ -0,0 +1,53 @@
package io.github.wulkanowy.data.repositories.grade
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.Semester
import org.junit.After
import org.junit.Before
import org.junit.Test
import org.junit.runner.RunWith
import org.threeten.bp.LocalDate
import org.threeten.bp.LocalDate.now
import kotlin.test.assertEquals
@RunWith(AndroidJUnit4::class)
class GradeLocalTest {
private lateinit var gradeLocal: GradeLocal
private lateinit var testDb: AppDatabase
@Before
fun createDb() {
testDb = Room.inMemoryDatabaseBuilder(ApplicationProvider.getApplicationContext(), AppDatabase::class.java)
.build()
gradeLocal = GradeLocal(testDb.gradeDao)
}
@After
fun closeDb() {
testDb.close()
}
@Test
fun saveAndReadTest() {
gradeLocal.saveGrades(listOf(
createGradeLocal(5, 3.0, LocalDate.of(2018, 9, 10), "", 1),
createGradeLocal(4, 4.0, LocalDate.of(2019, 2, 27), "", 2),
createGradeLocal(3, 5.0, LocalDate.of(2019, 2, 28), "", 2)
))
val semester = Semester(1, 2, "", 2019, 2, 1, true, now(), now(), 1, 1)
val grades = gradeLocal
.getGrades(semester)
.blockingGet()
assertEquals(2, grades.size)
assertEquals(grades[0].date, LocalDate.of(2019, 2, 27))
assertEquals(grades[1].date, LocalDate.of(2019, 2, 28))
}
}

View file

@ -0,0 +1,185 @@
package io.github.wulkanowy.data.repositories.grade
import android.os.Build.VERSION_CODES.P
import androidx.room.Room
import androidx.test.core.app.ApplicationProvider.getApplicationContext
import androidx.test.ext.junit.runners.AndroidJUnit4
import androidx.test.filters.SdkSuppress
import com.github.pwittchen.reactivenetwork.library.rx2.internet.observing.InternetObservingSettings
import io.github.wulkanowy.data.SdkHelper
import io.github.wulkanowy.data.db.AppDatabase
import io.github.wulkanowy.data.db.entities.Semester
import io.github.wulkanowy.data.db.entities.Student
import io.github.wulkanowy.data.repositories.TestInternetObservingStrategy
import io.github.wulkanowy.sdk.Sdk
import io.mockk.MockKAnnotations
import io.mockk.every
import io.mockk.impl.annotations.MockK
import io.mockk.impl.annotations.SpyK
import io.mockk.just
import io.mockk.runs
import io.reactivex.Single
import org.junit.After
import org.junit.Before
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
@SdkSuppress(minSdkVersion = P)
@RunWith(AndroidJUnit4::class)
class GradeRepositoryTest {
@MockK
private lateinit var mockSdk: Sdk
private val settings = InternetObservingSettings.builder()
.strategy(TestInternetObservingStrategy())
.build()
@MockK
private lateinit var semesterMock: Semester
@MockK
private lateinit var studentMock: Student
private lateinit var gradeRemote: GradeRemote
private lateinit var gradeLocal: GradeLocal
private lateinit var testDb: AppDatabase
@Before
fun initApi() {
MockKAnnotations.init(this)
testDb = Room.inMemoryDatabaseBuilder(getApplicationContext(), AppDatabase::class.java).build()
gradeLocal = GradeLocal(testDb.gradeDao)
gradeRemote = GradeRemote(mockSdk)
every { studentMock.registrationDate } returns LocalDateTime.of(2019, 2, 27, 12, 0)
every { semesterMock.studentId } returns 1
every { semesterMock.diaryId } returns 1
every { semesterMock.schoolYear } returns 2019
every { semesterMock.semesterId } returns 1
every { mockSdk.switchDiary(any(), any()) } returns mockSdk
}
@After
fun closeDb() {
testDb.close()
}
@Test
fun markOlderThanRegisterDateAsRead() {
every { mockSdk.getGrades(1) } returns Single.just(listOf(
createGradeApi(5, 4.0, of(2019, 2, 25), "Ocena pojawiła się"),
createGradeApi(5, 4.0, of(2019, 2, 26), "przed zalogowanie w aplikacji"),
createGradeApi(5, 4.0, of(2019, 2, 27), "Ocena z dnia logowania"),
createGradeApi(5, 4.0, of(2019, 2, 28), "Ocena jeszcze nowsza")
))
val grades = GradeRepository(settings, gradeLocal, gradeRemote)
.getGrades(studentMock, semesterMock, true).blockingGet().sortedByDescending { it.date }
assertFalse { grades[0].isRead }
assertFalse { grades[1].isRead }
assertTrue { grades[2].isRead }
assertTrue { grades[3].isRead }
}
@Test
fun mitigateOldGradesNotifications() {
gradeLocal.saveGrades(listOf(
createGradeLocal(5, 3.0, of(2019, 2, 25), "Jedna ocena"),
createGradeLocal(4, 4.0, of(2019, 2, 26), "Druga"),
createGradeLocal(3, 5.0, of(2019, 2, 27), "Trzecia")
))
every { mockSdk.getGrades(1) } returns Single.just(listOf(
createGradeApi(5, 2.0, of(2019, 2, 25), "Ocena ma datę, jest inna, ale nie zostanie powiadomiona"),
createGradeApi(4, 3.0, of(2019, 2, 26), "starszą niż ostatnia lokalnie"),
createGradeApi(3, 4.0, of(2019, 2, 27), "Ta jest z tego samego dnia co ostatnia lokalnie"),
createGradeApi(2, 5.0, of(2019, 2, 28), "Ta jest już w ogóle nowa")
))
val grades = GradeRepository(settings, gradeLocal, gradeRemote)
.getGrades(studentMock, semesterMock, true).blockingGet().sortedByDescending { it.date }
assertFalse { grades[0].isRead }
assertFalse { grades[1].isRead }
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 { mockSdk.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 { mockSdk.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 { mockSdk.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 { mockSdk.getGrades(1) } returns Single.just(listOf())
val grades = GradeRepository(settings, gradeLocal, gradeRemote)
.getGrades(studentMock, semesterMock, true).blockingGet()
assertEquals(0, grades.size)
}
}

View file

@ -0,0 +1,41 @@
package io.github.wulkanowy.data.repositories.grade
import org.threeten.bp.LocalDate
import io.github.wulkanowy.sdk.pojo.Grade as GradeRemote
import io.github.wulkanowy.data.db.entities.Grade as GradeLocal
fun createGradeLocal(value: Int, weight: Double, date: LocalDate, desc: String, semesterId: Int = 1): GradeLocal {
return GradeLocal(
semesterId = semesterId,
studentId = 1,
modifier = .0,
teacher = "",
subject = "",
date = date,
color = "",
comment = "",
description = desc,
entry = "",
gradeSymbol = "",
value = value.toDouble(),
weight = "",
weightValue = weight
)
}
fun createGradeApi(value: Int, weight: Double, date: LocalDate, desc: String): GradeRemote {
return GradeRemote(
subject = "",
color = "",
comment = "",
date = date,
description = desc,
entry = "",
modifier = .0,
symbol = "",
teacher = "",
value = value.toDouble(),
weight = weight.toString(),
weightValue = weight
)
}

View file

@ -0,0 +1,115 @@
package io.github.wulkanowy.data.repositories.gradestatistics
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
import org.junit.Before
import org.junit.Test
import org.junit.runner.RunWith
import org.threeten.bp.LocalDate
import kotlin.test.assertEquals
@RunWith(AndroidJUnit4::class)
class GradeStatisticsLocalTest {
private lateinit var gradeStatisticsLocal: GradeStatisticsLocal
private lateinit var testDb: AppDatabase
@Before
fun createDb() {
testDb = Room.inMemoryDatabaseBuilder(ApplicationProvider.getApplicationContext(), AppDatabase::class.java)
.build()
gradeStatisticsLocal = GradeStatisticsLocal(testDb.gradeStatistics, testDb.gradePointsStatistics)
}
@After
fun closeDb() {
testDb.close()
}
@Test
fun saveAndRead_subject() {
gradeStatisticsLocal.saveGradesStatistics(listOf(
getGradeStatistics("Matematyka", 2, 1),
getGradeStatistics("Fizyka", 1, 2)
))
val stats = gradeStatisticsLocal.getGradesStatistics(
Semester(2, 2, "", 2019, 1, 2, true, LocalDate.now(), LocalDate.now(), 1, 1), false,
"Matematyka"
).blockingGet()
assertEquals(1, stats.size)
assertEquals(stats[0].subject, "Matematyka")
}
@Test
fun saveAndRead_all() {
gradeStatisticsLocal.saveGradesStatistics(listOf(
getGradeStatistics("Matematyka", 2, 1),
getGradeStatistics("Chemia", 2, 1),
getGradeStatistics("Fizyka", 1, 2)
))
val stats = gradeStatisticsLocal.getGradesStatistics(
Semester(2, 2, "", 2019, 1, 2, true, LocalDate.now(), LocalDate.now(), 1, 1), false,
"Wszystkie"
).blockingGet()
assertEquals(1, stats.size)
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

@ -0,0 +1,47 @@
package io.github.wulkanowy.data.repositories.luckynumber
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.LuckyNumber
import io.github.wulkanowy.data.db.entities.Semester
import org.junit.After
import org.junit.Before
import org.junit.Test
import org.junit.runner.RunWith
import org.threeten.bp.LocalDate
import kotlin.test.assertEquals
@RunWith(AndroidJUnit4::class)
class LuckyNumberLocalTest {
private lateinit var luckyNumberLocal: LuckyNumberLocal
private lateinit var testDb: AppDatabase
@Before
fun createDb() {
testDb = Room.inMemoryDatabaseBuilder(ApplicationProvider.getApplicationContext(), AppDatabase::class.java)
.build()
luckyNumberLocal = LuckyNumberLocal(testDb.luckyNumberDao)
}
@After
fun closeDb() {
testDb.close()
}
@Test
fun saveAndReadTest() {
luckyNumberLocal.saveLuckyNumber(LuckyNumber(1, LocalDate.of(2019, 1, 20), 14))
val luckyNumber = luckyNumberLocal.getLuckyNumber(Semester(1, 1, "", 1, 3, 2019, true, LocalDate.now(), LocalDate.now(), 1, 1),
LocalDate.of(2019, 1, 20)
).blockingGet()
assertEquals(1, luckyNumber.studentId)
assertEquals(LocalDate.of(2019, 1, 20), luckyNumber.date)
assertEquals(14, luckyNumber.luckyNumber)
}
}

View file

@ -0,0 +1,60 @@
package io.github.wulkanowy.data.repositories.recipient
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.Recipient
import io.github.wulkanowy.data.db.entities.ReportingUnit
import io.github.wulkanowy.data.db.entities.Student
import org.junit.After
import org.junit.Before
import org.junit.Test
import org.junit.runner.RunWith
import org.threeten.bp.LocalDateTime
import kotlin.test.assertEquals
@RunWith(AndroidJUnit4::class)
class RecipientLocalTest {
private lateinit var recipientLocal: RecipientLocal
private lateinit var testDb: AppDatabase
@Before
fun createDb() {
testDb = Room.inMemoryDatabaseBuilder(ApplicationProvider.getApplicationContext(), AppDatabase::class.java)
.build()
recipientLocal = RecipientLocal(testDb.recipientDao)
}
@After
fun closeDb() {
testDb.close()
}
@Test
fun saveAndReadTest() {
recipientLocal.saveRecipients(listOf(
Recipient(1, "2rPracownik", "Kowalski Jan", "Kowalski Jan [KJ] - Pracownik (Fake123456)", 3, 4, 2, "hash"),
Recipient(1, "3rPracownik", "Kowalska Karolina", "Kowalska Karolina [KK] - Pracownik (Fake123456)", 4, 4, 2, "hash"),
Recipient(1, "4rPracownik", "Krupa Stanisław", "Krupa Stanisław [KS] - Uczeń (Fake123456)", 5, 4, 1, "hash")
))
val recipients = recipientLocal.getRecipients(
Student("fakelog.cf", "AUTO", "", "", "", "", false, "", "", "", 1, 0, "", "", "", "", 1, true, LocalDateTime.now()),
2,
ReportingUnit(1, 4, "", 0, "", emptyList())
).blockingGet()
assertEquals(2, recipients.size)
assertEquals(1, recipients[0].studentId)
assertEquals("3rPracownik", recipients[1].realId)
assertEquals("Kowalski Jan", recipients[0].name)
assertEquals("Kowalska Karolina [KK] - Pracownik (Fake123456)", recipients[1].realName)
assertEquals(3, recipients[0].loginId)
assertEquals(4, recipients[1].unitId)
assertEquals(2, recipients[0].role)
assertEquals("hash", recipients[1].hash)
}
}

View file

@ -1,16 +1,17 @@
package io.github.wulkanowy.data.repositories.local package io.github.wulkanowy.data.repositories.student
import android.content.Context import android.content.Context
import androidx.room.Room import androidx.room.Room
import androidx.test.core.app.ApplicationProvider import androidx.test.core.app.ApplicationProvider
import androidx.test.ext.junit.runners.AndroidJUnit4 import androidx.test.ext.junit.runners.AndroidJUnit4
import io.github.wulkanowy.data.db.AppDatabase 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 io.github.wulkanowy.data.db.entities.Student
import org.junit.After import org.junit.After
import org.junit.Before import org.junit.Before
import org.junit.Test import org.junit.Test
import org.junit.runner.RunWith import org.junit.runner.RunWith
import org.threeten.bp.LocalDateTime.now
import kotlin.test.assertEquals import kotlin.test.assertEquals
@RunWith(AndroidJUnit4::class) @RunWith(AndroidJUnit4::class)
@ -20,15 +21,15 @@ class StudentLocalTest {
private lateinit var testDb: AppDatabase private lateinit var testDb: AppDatabase
private lateinit var sharedHelper: SharedPrefHelper private lateinit var sharedProvider: SharedPrefProvider
@Before @Before
fun createDb() { fun createDb() {
val context = ApplicationProvider.getApplicationContext<Context>() val context = ApplicationProvider.getApplicationContext<Context>()
testDb = Room.inMemoryDatabaseBuilder(context, AppDatabase::class.java) testDb = Room.inMemoryDatabaseBuilder(context, AppDatabase::class.java)
.build() .build()
sharedHelper = SharedPrefHelper(context.getSharedPreferences("TEST", Context.MODE_PRIVATE)) sharedProvider = SharedPrefProvider(context.getSharedPreferences("TEST", Context.MODE_PRIVATE))
studentLocal = StudentLocal(testDb.studentDao, sharedHelper, context) studentLocal = StudentLocal(testDb.studentDao, context)
} }
@After @After
@ -38,9 +39,8 @@ class StudentLocalTest {
@Test @Test
fun saveAndReadTest() { fun saveAndReadTest() {
studentLocal.saveStudent(Student(email = "test", password = "test123", schoolSymbol = "23", endpoint = "fakelog.cf", loginType = "AUTO", isCurrent = true)) studentLocal.saveStudents(listOf(Student(email = "test", password = "test123", schoolSymbol = "23", scrapperBaseUrl = "fakelog.cf", loginType = "AUTO", isCurrent = true, studentName = "", schoolName = "", studentId = 0, classId = 1, symbol = "", registrationDate = now(), className = "", loginMode = "API", certificateKey = "", privateKey = "", mobileBaseUrl = "", userLoginId = 0, isParent = false)))
.blockingGet() .blockingGet()
assert(studentLocal.isStudentSaved)
val student = studentLocal.getCurrentStudent(true).blockingGet() val student = studentLocal.getCurrentStudent(true).blockingGet()
assertEquals("23", student.schoolSymbol) assertEquals("23", student.schoolSymbol)

View file

@ -0,0 +1,47 @@
package io.github.wulkanowy.data.repositories.timetable
import org.threeten.bp.LocalDateTime
import org.threeten.bp.LocalDateTime.now
import io.github.wulkanowy.sdk.pojo.Timetable as TimetableRemote
import io.github.wulkanowy.data.db.entities.Timetable as TimetableLocal
fun createTimetableLocal(start: LocalDateTime, number: Int, room: String = "", subject: String = "", teacher: String = "", changes: Boolean = false): TimetableLocal {
return TimetableLocal(
studentId = 1,
diaryId = 2,
number = number,
start = start,
end = now(),
date = start.toLocalDate(),
subject = subject,
subjectOld = "",
group = "",
room = room,
roomOld = "",
teacher = teacher,
teacherOld = "",
info = "",
changes = changes,
canceled = false
)
}
fun createTimetableRemote(start: LocalDateTime, number: Int = 1, room: String = "", subject: String = "", teacher: String = "", changes: Boolean = false): TimetableRemote {
return TimetableRemote(
number = number,
start = start,
end = start.plusMinutes(45),
date = start.toLocalDate(),
subject = subject,
group = "",
room = room,
teacher = teacher,
info = "",
changes = changes,
canceled = false,
roomOld = "",
subjectOld = "",
teacherOld = "",
studentPlan = true
)
}

View file

@ -1,17 +1,16 @@
package io.github.wulkanowy.data.repositories.local package io.github.wulkanowy.data.repositories.timetable
import androidx.room.Room import androidx.room.Room
import androidx.test.core.app.ApplicationProvider import androidx.test.core.app.ApplicationProvider
import androidx.test.ext.junit.runners.AndroidJUnit4 import androidx.test.ext.junit.runners.AndroidJUnit4
import io.github.wulkanowy.data.db.AppDatabase import io.github.wulkanowy.data.db.AppDatabase
import io.github.wulkanowy.data.db.entities.Semester import io.github.wulkanowy.data.db.entities.Semester
import io.github.wulkanowy.data.db.entities.Timetable
import org.junit.After import org.junit.After
import org.junit.Before import org.junit.Before
import org.junit.Test import org.junit.Test
import org.junit.runner.RunWith import org.junit.runner.RunWith
import org.threeten.bp.LocalDate import org.threeten.bp.LocalDate
import org.threeten.bp.LocalDateTime import org.threeten.bp.LocalDateTime.of
import kotlin.test.assertEquals import kotlin.test.assertEquals
@RunWith(AndroidJUnit4::class) @RunWith(AndroidJUnit4::class)
@ -23,7 +22,8 @@ class TimetableLocalTest {
@Before @Before
fun createDb() { fun createDb() {
testDb = Room.inMemoryDatabaseBuilder(ApplicationProvider.getApplicationContext(), AppDatabase::class.java).build() testDb = Room.inMemoryDatabaseBuilder(ApplicationProvider.getApplicationContext(), AppDatabase::class.java)
.build()
timetableDb = TimetableLocal(testDb.timetableDao) timetableDb = TimetableLocal(testDb.timetableDao)
} }
@ -35,19 +35,17 @@ class TimetableLocalTest {
@Test @Test
fun saveAndReadTest() { fun saveAndReadTest() {
timetableDb.saveTimetable(listOf( timetableDb.saveTimetable(listOf(
Timetable(1, 2, 1, LocalDateTime.now(), LocalDateTime.now(), createTimetableLocal(of(2018, 9, 10, 0, 0, 0), 1),
LocalDate.of(2018, 9, 10), "", "", "", "", ""), createTimetableLocal(of(2018, 9, 14, 0, 0, 0), 1),
Timetable(1, 2, 1, LocalDateTime.now(), LocalDateTime.now(), createTimetableLocal(of(2018, 9, 17, 0, 0, 0), 1)
LocalDate.of(2018, 9, 14), "", "", "", "", ""),
Timetable(1, 2, 1, LocalDateTime.now(), LocalDateTime.now(),
LocalDate.of(2018, 9, 17), "", "", "", "", "")
)) ))
val exams = timetableDb.getTimetable( val exams = timetableDb.getTimetable(
Semester(0, 1, 2, "3", 1, 1), Semester(1, 2, "", 1, 1, 2019, true, LocalDate.now(), LocalDate.now(), 1, 1),
LocalDate.of(2018, 9, 10), LocalDate.of(2018, 9, 10),
LocalDate.of(2018, 9, 14) LocalDate.of(2018, 9, 14)
).blockingGet() ).blockingGet()
assertEquals(2, exams.size) assertEquals(2, exams.size)
assertEquals(exams[0].date, LocalDate.of(2018, 9, 10)) assertEquals(exams[0].date, LocalDate.of(2018, 9, 10))
assertEquals(exams[1].date, LocalDate.of(2018, 9, 14)) assertEquals(exams[1].date, LocalDate.of(2018, 9, 14))

View file

@ -0,0 +1,147 @@
package io.github.wulkanowy.data.repositories.timetable
import android.os.Build.VERSION_CODES.P
import androidx.room.Room
import androidx.test.core.app.ApplicationProvider.getApplicationContext
import androidx.test.ext.junit.runners.AndroidJUnit4
import androidx.test.filters.SdkSuppress
import com.github.pwittchen.reactivenetwork.library.rx2.internet.observing.InternetObservingSettings
import io.github.wulkanowy.data.db.AppDatabase
import io.github.wulkanowy.data.db.entities.Semester
import io.github.wulkanowy.data.repositories.TestInternetObservingStrategy
import io.github.wulkanowy.sdk.Sdk
import io.mockk.MockKAnnotations
import io.mockk.every
import io.mockk.impl.annotations.MockK
import io.reactivex.Single
import org.junit.After
import org.junit.Before
import org.junit.Test
import org.junit.runner.RunWith
import org.threeten.bp.LocalDate
import org.threeten.bp.LocalDateTime.of
import kotlin.test.assertEquals
@SdkSuppress(minSdkVersion = P)
@RunWith(AndroidJUnit4::class)
class TimetableRepositoryTest {
@MockK
private lateinit var mockSdk: Sdk
private val settings = InternetObservingSettings.builder()
.strategy(TestInternetObservingStrategy())
.build()
@MockK
private lateinit var semesterMock: Semester
private lateinit var timetableRemote: TimetableRemote
private lateinit var timetableLocal: TimetableLocal
private lateinit var testDb: AppDatabase
@Before
fun initApi() {
MockKAnnotations.init(this)
testDb = Room.inMemoryDatabaseBuilder(getApplicationContext(), AppDatabase::class.java).build()
timetableLocal = TimetableLocal(testDb.timetableDao)
timetableRemote = TimetableRemote(mockSdk)
every { semesterMock.studentId } returns 1
every { semesterMock.diaryId } returns 2
every { semesterMock.schoolYear } returns 2019
every { semesterMock.semesterId } returns 1
every { mockSdk.switchDiary(any(), any()) } returns mockSdk
}
@After
fun closeDb() {
testDb.close()
}
@Test
fun copyRoomToCompletedFromPrevious() {
timetableLocal.saveTimetable(listOf(
createTimetableLocal(of(2019, 3, 5, 8, 0), 1, "123", "Przyroda"),
createTimetableLocal(of(2019, 3, 5, 8, 50), 2, "321", "Religia"),
createTimetableLocal(of(2019, 3, 5, 9, 40), 3, "213", "W-F"),
createTimetableLocal(of(2019, 3, 5, 10, 30),3, "213", "W-F", "Jan Kowalski")
))
every { mockSdk.getTimetable(any(), any()) } returns Single.just(listOf(
createTimetableRemote(of(2019, 3, 5, 8, 0), 1, "", "Przyroda"),
createTimetableRemote(of(2019, 3, 5, 8, 50), 2, "", "Religia"),
createTimetableRemote(of(2019, 3, 5, 9, 40), 3, "", "W-F"),
createTimetableRemote(of(2019, 3, 5, 10, 30), 4, "", "W-F")
))
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("123", lessons[0].room)
assertEquals("321", lessons[1].room)
assertEquals("213", lessons[2].room)
}
@Test
fun copyTeacherToCompletedFromPrevious() {
timetableLocal.saveTimetable(listOf(
createTimetableLocal(of(2019, 12, 23, 8, 0), 1, "123", "Matematyka", "Paweł Poniedziałkowski", false),
createTimetableLocal(of(2019, 12, 23, 8, 50), 2, "124", "Matematyka", "Paweł Poniedziałkowski", false),
createTimetableLocal(of(2019, 12, 23, 9, 40), 3, "125", "Język polski", "Joanna Wtorkowska", true),
createTimetableLocal(of(2019, 12, 23, 10, 40), 4, "126", "Język polski", "Joanna Wtorkowska", true),
createTimetableLocal(of(2019, 12, 24, 8, 0), 1, "123", "Język polski", "Joanna Wtorkowska", false),
createTimetableLocal(of(2019, 12, 24, 8, 50), 2, "124", "Język polski", "Joanna Wtorkowska", false),
createTimetableLocal(of(2019, 12, 24, 9, 40), 3, "125", "Język polski", "Joanna Środowska", true),
createTimetableLocal(of(2019, 12, 24, 10, 40), 4, "126", "Język polski", "Joanna Środowska", true),
createTimetableLocal(of(2019, 12, 25, 8, 0), 1, "123", "Matematyka", "", false),
createTimetableLocal(of(2019, 12, 25, 8, 50), 2, "124", "Matematyka", "", false),
createTimetableLocal(of(2019, 12, 25, 9, 40), 3, "125", "Matematyka", "", true),
createTimetableLocal(of(2019, 12, 25, 10, 40), 4, "126", "Matematyka", "", true)
))
every { mockSdk.getTimetable(any(), any()) } returns Single.just(listOf(
createTimetableRemote(of(2019, 12, 23, 8, 0), 1, "123", "Matematyka", "Paweł Poniedziałkowski", false),
createTimetableRemote(of(2019, 12, 23, 8, 50), 2, "124", "Matematyka", "Jakub Wtorkowski", true),
createTimetableRemote(of(2019, 12, 23, 9, 40), 3, "125", "Język polski", "Joanna Poniedziałkowska", false),
createTimetableRemote(of(2019, 12, 23, 10, 40), 4, "126", "Język polski", "Joanna Wtorkowska", true),
createTimetableRemote(of(2019, 12, 24, 8, 0), 1, "123", "Język polski", "", false),
createTimetableRemote(of(2019, 12, 24, 8, 50), 2, "124", "Język polski", "", true),
createTimetableRemote(of(2019, 12, 24, 9, 40), 3, "125", "Język polski", "", false),
createTimetableRemote(of(2019, 12, 24, 10, 40), 4, "126", "Język polski", "", true),
createTimetableRemote(of(2019, 12, 25, 8, 0), 1, "123", "Matematyka", "Paweł Środowski", false),
createTimetableRemote(of(2019, 12, 25, 8, 50), 2, "124", "Matematyka", "Paweł Czwartkowski", true),
createTimetableRemote(of(2019, 12, 25, 9, 40), 3, "125", "Matematyka", "Paweł Środowski", false),
createTimetableRemote(of(2019, 12, 25, 10, 40), 4, "126", "Matematyka", "Paweł Czwartkowski", true)
))
val lessons = TimetableRepository(settings, timetableLocal, timetableRemote)
.getTimetable(semesterMock, LocalDate.of(2019, 12, 23), LocalDate.of(2019, 12, 25), true)
.blockingGet()
assertEquals(12, lessons.size)
assertEquals("Paweł Poniedziałkowski", lessons[0].teacher)
assertEquals("Jakub Wtorkowski", lessons[1].teacher)
assertEquals("Joanna Poniedziałkowska", lessons[2].teacher)
assertEquals("Joanna Wtorkowska", lessons[3].teacher)
assertEquals("Joanna Wtorkowska", lessons[4].teacher)
assertEquals("", lessons[5].teacher)
assertEquals("", lessons[6].teacher)
assertEquals("", lessons[7].teacher)
assertEquals("Paweł Środowski", lessons[8].teacher)
assertEquals("Paweł Czwartkowski", lessons[9].teacher)
assertEquals("Paweł Środowski", lessons[10].teacher)
assertEquals("Paweł Czwartkowski", lessons[11].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"?> <?xml version="1.0" encoding="utf-8"?>
<adaptive-icon xmlns:android="http://schemas.android.com/apk/res/android"> <adaptive-icon xmlns:android="http://schemas.android.com/apk/res/android">
<background android:drawable="@color/ic_launcher_background"/> <background android:drawable="@color/colorPrimary" />
<foreground android:drawable="@drawable/ic_launcher_foreground"/> <foreground android:drawable="@drawable/ic_launcher_foreground_dev" />
</adaptive-icon> </adaptive-icon>

View file

@ -1,5 +1,5 @@
<?xml version="1.0" encoding="utf-8"?> <?xml version="1.0" encoding="utf-8"?>
<adaptive-icon xmlns:android="http://schemas.android.com/apk/res/android"> <adaptive-icon xmlns:android="http://schemas.android.com/apk/res/android">
<background android:drawable="@color/ic_launcher_background"/> <background android:drawable="@color/colorPrimary" />
<foreground android:drawable="@drawable/ic_launcher_foreground"/> <foreground android:drawable="@drawable/ic_launcher_foreground_dev" />
</adaptive-icon> </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" package="io.github.wulkanowy"
android:installLocation="internalOnly"> android:installLocation="internalOnly">
<uses-sdk tools:overrideLibrary="com.readystatesoftware.chuck"/>
<uses-permission android:name="android.permission.INTERNET" /> <uses-permission android:name="android.permission.INTERNET" />
<uses-permission android:name="android.permission.ACCESS_NETWORK_STATE" /> <uses-permission android:name="android.permission.ACCESS_NETWORK_STATE" />
<uses-permission android:name="android.permission.RECEIVE_BOOT_COMPLETED" /> <uses-permission android:name="android.permission.RECEIVE_BOOT_COMPLETED" />
@ -20,14 +18,13 @@
android:supportsRtl="false" android:supportsRtl="false"
android:theme="@style/WulkanowyTheme" android:theme="@style/WulkanowyTheme"
android:usesCleartextTraffic="true" android:usesCleartextTraffic="true"
tools:ignore="GoogleAppIndexingWarning"> tools:ignore="GoogleAppIndexingWarning,UnusedAttribute">
<activity <activity
android:name=".ui.modules.splash.SplashActivity" android:name=".ui.modules.splash.SplashActivity"
android:screenOrientation="portrait" android:screenOrientation="portrait"
android:theme="@style/WulkanowyTheme.SplashScreen"> android:theme="@style/WulkanowyTheme.SplashScreen">
<intent-filter> <intent-filter>
<action android:name="android.intent.action.MAIN" /> <action android:name="android.intent.action.MAIN" />
<category android:name="android.intent.category.LAUNCHER" /> <category android:name="android.intent.category.LAUNCHER" />
</intent-filter> </intent-filter>
</activity> </activity>
@ -35,26 +32,45 @@
android:name=".ui.modules.login.LoginActivity" android:name=".ui.modules.login.LoginActivity"
android:configChanges="orientation|screenSize" android:configChanges="orientation|screenSize"
android:label="@string/login_title" android:label="@string/login_title"
android:theme="@style/WulkanowyTheme.NoActionBar"
android:windowSoftInputMode="adjustResize" /> android:windowSoftInputMode="adjustResize" />
<activity <activity
android:name=".ui.modules.main.MainActivity" android:name=".ui.modules.main.MainActivity"
android:configChanges="orientation|screenSize" android:configChanges="orientation|screenSize"
android:label="@string/main_title" android:label="@string/main_title"
android:theme="@style/WulkanowyTheme.NoActionBar" /> android:theme="@style/WulkanowyTheme.NoActionBar" />
<activity
<service android:name=".ui.modules.message.send.SendMessageActivity"
android:name=".services.job.SyncWorker" android:configChanges="orientation|screenSize"
android:exported="false"> android:label="@string/send_message_title"
android:windowSoftInputMode="adjustResize"
android:theme="@style/WulkanowyTheme.NoActionBar" />
<activity
android:name=".ui.modules.timetablewidget.TimetableWidgetConfigureActivity"
android:excludeFromRecents="true"
android:noHistory="true"
android:theme="@style/WulkanowyTheme.WidgetAccountSwitcher">
<intent-filter> <intent-filter>
<action android:name="com.firebase.jobdispatcher.ACTION_EXECUTE" /> <action android:name="android.appwidget.action.APPWIDGET_CONFIGURE" />
</intent-filter> </intent-filter>
</service> </activity>
<activity
android:name=".ui.modules.luckynumberwidget.LuckyNumberWidgetConfigureActivity"
android:excludeFromRecents="true"
android:noHistory="true"
android:theme="@style/WulkanowyTheme.WidgetAccountSwitcher">
<intent-filter>
<action android:name="android.appwidget.action.APPWIDGET_CONFIGURE" />
</intent-filter>
</activity>
<service <service
android:name=".services.widgets.TimetableWidgetService" android:name=".services.widgets.TimetableWidgetService"
android:permission="android.permission.BIND_REMOTEVIEWS" /> android:permission="android.permission.BIND_REMOTEVIEWS" />
<receiver <receiver
android:name=".ui.widgets.timetable.TimetableWidgetProvider" android:name=".ui.modules.timetablewidget.TimetableWidgetProvider"
android:exported="true"
android:label="@string/timetable_title"> android:label="@string/timetable_title">
<intent-filter> <intent-filter>
<action android:name="android.appwidget.action.APPWIDGET_UPDATE" /> <action android:name="android.appwidget.action.APPWIDGET_UPDATE" />
@ -63,6 +79,22 @@
android:name="android.appwidget.provider" android:name="android.appwidget.provider"
android:resource="@xml/provider_widget_timetable" /> android:resource="@xml/provider_widget_timetable" />
</receiver> </receiver>
<receiver
android:name=".ui.modules.luckynumberwidget.LuckyNumberWidgetProvider"
android:label="@string/lucky_number_title">
<intent-filter>
<action android:name="android.appwidget.action.APPWIDGET_UPDATE" />
</intent-filter>
<meta-data
android:name="android.appwidget.provider"
android:resource="@xml/provider_widget_lucky_number" />
</receiver>
<provider
android:name="androidx.work.impl.WorkManagerInitializer"
android:authorities="${applicationId}.workmanager-init"
android:exported="false"
tools:node="remove" />
<meta-data <meta-data
android:name="io.fabric.ApiKey" android:name="io.fabric.ApiKey"

Binary file not shown.

Before

Width:  |  Height:  |  Size: 19 KiB

View file

@ -1,28 +1,40 @@
package io.github.wulkanowy package io.github.wulkanowy
import android.content.Context import android.content.Context
import androidx.appcompat.app.AppCompatDelegate import android.util.Log.INFO
import android.util.Log.VERBOSE
import androidx.multidex.MultiDex import androidx.multidex.MultiDex
import com.crashlytics.android.Crashlytics import androidx.work.Configuration
import com.crashlytics.android.core.CrashlyticsCore
import com.jakewharton.threetenabp.AndroidThreeTen import com.jakewharton.threetenabp.AndroidThreeTen
import com.yariksoffice.lingver.Lingver
import dagger.android.AndroidInjector import dagger.android.AndroidInjector
import dagger.android.support.DaggerApplication import dagger.android.support.DaggerApplication
import eu.davidea.flexibleadapter.FlexibleAdapter import eu.davidea.flexibleadapter.FlexibleAdapter
import eu.davidea.flexibleadapter.utils.Log import eu.davidea.flexibleadapter.utils.Log
import io.fabric.sdk.android.Fabric
import io.github.wulkanowy.BuildConfig.DEBUG
import io.github.wulkanowy.data.repositories.PreferencesRepository
import io.github.wulkanowy.di.DaggerAppComponent 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.CrashlyticsTree
import io.github.wulkanowy.utils.DebugLogTree 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 timber.log.Timber
import java.io.IOException
import javax.inject.Inject import javax.inject.Inject
class WulkanowyApp : DaggerApplication() { class WulkanowyApp : DaggerApplication(), Configuration.Provider {
@Inject @Inject
lateinit var prefRepository: PreferencesRepository lateinit var workerFactory: SyncWorkerFactory
@Inject
lateinit var themeManager: ThemeManager
@Inject
lateinit var appInfo: AppInfo
override fun attachBaseContext(base: Context?) { override fun attachBaseContext(base: Context?) {
super.attachBaseContext(base) super.attachBaseContext(base)
@ -32,24 +44,38 @@ class WulkanowyApp : DaggerApplication() {
override fun onCreate() { override fun onCreate() {
super.onCreate() super.onCreate()
AndroidThreeTen.init(this) AndroidThreeTen.init(this)
initializeFabric() RxJavaPlugins.setErrorHandler(::onError)
if (DEBUG) enableDebugLog() Lingver.init(this)
AppCompatDelegate.setDefaultNightMode(prefRepository.currentTheme) themeManager.applyDefaultTheme()
initLogging()
initCrashlytics(this, appInfo)
} }
private fun enableDebugLog() { private fun initLogging() {
Timber.plant(DebugLogTree()) if (appInfo.isDebug) {
FlexibleAdapter.enableLogs(Log.Level.DEBUG) Timber.plant(DebugLogTree())
FlexibleAdapter.enableLogs(Log.Level.DEBUG)
} else {
Timber.plant(CrashlyticsTree())
}
registerActivityLifecycleCallbacks(ActivityLifecycleLogger())
} }
private fun initializeFabric() { private fun onError(error: Throwable) {
Fabric.with(Fabric.Builder(this).kits( //RxJava's too deep stack traces may cause SOE on older android devices
Crashlytics.Builder().core(CrashlyticsCore.Builder().disabled(!BuildConfig.CRASHLYTICS_ENABLED).build()).build() val cause = error.cause
).debuggable(BuildConfig.DEBUG).build()) if (error is UndeliverableException && cause is IOException || cause is InterruptedException || cause is StackOverflowError) {
Timber.plant(CrashlyticsTree()) Timber.e(cause, "An undeliverable error occurred")
} else throw error
} }
override fun applicationInjector(): AndroidInjector<out DaggerApplication> { override fun applicationInjector(): AndroidInjector<out DaggerApplication> {
return DaggerAppComponent.builder().create(this) return DaggerAppComponent.factory().create(this)
} }
override fun getWorkManagerConfiguration() = Configuration.Builder()
.setWorkerFactory(workerFactory)
.setMinimumLoggingLevel(if (appInfo.isDebug) VERBOSE else INFO)
.build()
} }

View file

@ -1,27 +0,0 @@
package io.github.wulkanowy.data
import io.github.wulkanowy.api.Api
import io.github.wulkanowy.data.db.entities.Student
import java.net.URL
import javax.inject.Inject
class ApiHelper @Inject constructor(private val api: Api) {
fun initApi(student: Student) {
api.apply {
email = student.email
password = student.password
symbol = student.symbol
schoolSymbol = student.schoolSymbol
studentId = student.studentId
useNewStudent = false
host = URL(student.endpoint).run { host + ":$port".removeSuffix(":-1") }
ssl = student.endpoint.startsWith("https")
loginType = Api.LoginType.valueOf(student.loginType)
}
}
fun initApi(email: String, password: String, symbol: String, endpoint: String) {
initApi(Student(email = email, password = password, symbol = symbol, endpoint = endpoint, loginType = "AUTO"))
}
}

View file

@ -5,18 +5,16 @@ import android.content.SharedPreferences
import android.content.res.Resources import android.content.res.Resources
import androidx.preference.PreferenceManager import androidx.preference.PreferenceManager
import com.github.pwittchen.reactivenetwork.library.rx2.internet.observing.InternetObservingSettings import com.github.pwittchen.reactivenetwork.library.rx2.internet.observing.InternetObservingSettings
import com.github.pwittchen.reactivenetwork.library.rx2.internet.observing.strategy.SocketInternetObservingStrategy import com.github.pwittchen.reactivenetwork.library.rx2.internet.observing.strategy.WalledGardenInternetObservingStrategy
import com.readystatesoftware.chuck.api.ChuckCollector import com.readystatesoftware.chuck.api.ChuckCollector
import com.readystatesoftware.chuck.api.ChuckInterceptor import com.readystatesoftware.chuck.api.ChuckInterceptor
import com.readystatesoftware.chuck.api.RetentionManager import com.readystatesoftware.chuck.api.RetentionManager
import dagger.Module import dagger.Module
import dagger.Provides import dagger.Provides
import io.github.wulkanowy.api.Api
import io.github.wulkanowy.data.db.AppDatabase import io.github.wulkanowy.data.db.AppDatabase
import io.github.wulkanowy.data.repositories.PreferencesRepository import io.github.wulkanowy.data.db.SharedPrefProvider
import okhttp3.logging.HttpLoggingInterceptor import io.github.wulkanowy.data.repositories.preferences.PreferencesRepository
import okhttp3.logging.HttpLoggingInterceptor.Level.BASIC import io.github.wulkanowy.sdk.Sdk
import okhttp3.logging.HttpLoggingInterceptor.Level.NONE
import timber.log.Timber import timber.log.Timber
import javax.inject.Singleton import javax.inject.Singleton
@ -27,22 +25,20 @@ internal class RepositoryModule {
@Provides @Provides
fun provideInternetObservingSettings(): InternetObservingSettings { fun provideInternetObservingSettings(): InternetObservingSettings {
return InternetObservingSettings.builder() return InternetObservingSettings.builder()
.strategy(SocketInternetObservingStrategy()) .strategy(WalledGardenInternetObservingStrategy())
.host("www.google.com")
.build() .build()
} }
@Singleton @Singleton
@Provides @Provides
fun provideApi(chuckCollector: ChuckCollector, context: Context): Api { fun provideSdk(chuckCollector: ChuckCollector, context: Context): Sdk {
return Api().apply { return Sdk().apply {
logLevel = NONE
androidVersion = android.os.Build.VERSION.RELEASE androidVersion = android.os.Build.VERSION.RELEASE
buildTag = android.os.Build.MODEL buildTag = android.os.Build.MODEL
setInterceptor(HttpLoggingInterceptor(HttpLoggingInterceptor.Logger { Timber.d(it) }).setLevel(BASIC)) setSimpleHttpLogger { Timber.d(it) }
// for debug only // for debug only
setInterceptor(ChuckInterceptor(context, chuckCollector).maxContentLength(250000L), true, 0) addInterceptor(ChuckInterceptor(context, chuckCollector).maxContentLength(250000L), true)
} }
} }
@ -50,13 +46,13 @@ internal class RepositoryModule {
@Provides @Provides
fun provideChuckCollector(context: Context, prefRepository: PreferencesRepository): ChuckCollector { fun provideChuckCollector(context: Context, prefRepository: PreferencesRepository): ChuckCollector {
return ChuckCollector(context) return ChuckCollector(context)
.showNotification(prefRepository.isShowChuckerNotification) .showNotification(prefRepository.isDebugNotificationEnable)
.retentionManager(RetentionManager(context, ChuckCollector.Period.ONE_HOUR)) .retentionManager(RetentionManager(context, ChuckCollector.Period.ONE_HOUR))
} }
@Singleton @Singleton
@Provides @Provides
fun provideDatabase(context: Context) = AppDatabase.newInstance(context) fun provideDatabase(context: Context, sharedPrefProvider: SharedPrefProvider) = AppDatabase.newInstance(context, sharedPrefProvider)
@Singleton @Singleton
@Provides @Provides
@ -82,6 +78,14 @@ internal class RepositoryModule {
@Provides @Provides
fun provideGradeSummaryDao(database: AppDatabase) = database.gradeSummaryDao fun provideGradeSummaryDao(database: AppDatabase) = database.gradeSummaryDao
@Singleton
@Provides
fun provideGradeStatisticsDao(database: AppDatabase) = database.gradeStatistics
@Singleton
@Provides
fun provideGradePointsStatisticsDao(database: AppDatabase) = database.gradePointsStatistics
@Singleton @Singleton
@Provides @Provides
fun provideMessagesDao(database: AppDatabase) = database.messagesDao fun provideMessagesDao(database: AppDatabase) = database.messagesDao
@ -113,4 +117,32 @@ internal class RepositoryModule {
@Singleton @Singleton
@Provides @Provides
fun provideSubjectDao(database: AppDatabase) = database.subjectDao fun provideSubjectDao(database: AppDatabase) = database.subjectDao
@Singleton
@Provides
fun provideLuckyNumberDao(database: AppDatabase) = database.luckyNumberDao
@Singleton
@Provides
fun provideCompletedLessonsDao(database: AppDatabase) = database.completedLessonsDao
@Singleton
@Provides
fun provideReportingUnitDao(database: AppDatabase) = database.reportingUnitDao
@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

@ -0,0 +1,30 @@
package io.github.wulkanowy.data
import io.github.wulkanowy.data.db.entities.Student
import io.github.wulkanowy.sdk.Sdk
import javax.inject.Inject
class SdkHelper @Inject constructor(private val sdk: Sdk) {
fun init(student: Student) {
sdk.apply {
email = student.email
password = student.password
symbol = student.symbol
schoolSymbol = student.schoolSymbol
studentId = student.studentId
classId = student.classId
if (Sdk.Mode.valueOf(student.loginMode) != Sdk.Mode.API) {
scrapperBaseUrl = student.scrapperBaseUrl
loginType = Sdk.ScrapperLoginType.valueOf(student.loginType)
}
loginId = student.userLoginId
mode = Sdk.Mode.valueOf(student.loginMode)
mobileBaseUrl = student.mobileBaseUrl
certKey = student.certificateKey
privateKey = student.privateKey
}
}
}

View file

@ -6,30 +6,67 @@ import androidx.room.Room
import androidx.room.RoomDatabase import androidx.room.RoomDatabase
import androidx.room.RoomDatabase.JournalMode.TRUNCATE import androidx.room.RoomDatabase.JournalMode.TRUNCATE
import androidx.room.TypeConverters import androidx.room.TypeConverters
import androidx.room.migration.Migration
import io.github.wulkanowy.data.db.dao.AttendanceDao import io.github.wulkanowy.data.db.dao.AttendanceDao
import io.github.wulkanowy.data.db.dao.AttendanceSummaryDao 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.ExamDao
import io.github.wulkanowy.data.db.dao.GradeDao 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.GradeSummaryDao
import io.github.wulkanowy.data.db.dao.MessagesDao
import io.github.wulkanowy.data.db.dao.HomeworkDao 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.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.SemesterDao
import io.github.wulkanowy.data.db.dao.StudentDao import io.github.wulkanowy.data.db.dao.StudentDao
import io.github.wulkanowy.data.db.dao.SubjectDao 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.dao.TimetableDao
import io.github.wulkanowy.data.db.entities.Attendance import io.github.wulkanowy.data.db.entities.Attendance
import io.github.wulkanowy.data.db.entities.AttendanceSummary 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.Exam
import io.github.wulkanowy.data.db.entities.Grade 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.GradeSummary
import io.github.wulkanowy.data.db.entities.Message
import io.github.wulkanowy.data.db.entities.Homework 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.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.Semester
import io.github.wulkanowy.data.db.entities.Student import io.github.wulkanowy.data.db.entities.Student
import io.github.wulkanowy.data.db.entities.Subject 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.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.Migration19
import io.github.wulkanowy.data.db.migrations.Migration2
import io.github.wulkanowy.data.db.migrations.Migration3
import io.github.wulkanowy.data.db.migrations.Migration4
import io.github.wulkanowy.data.db.migrations.Migration5
import io.github.wulkanowy.data.db.migrations.Migration6
import io.github.wulkanowy.data.db.migrations.Migration7
import io.github.wulkanowy.data.db.migrations.Migration8
import io.github.wulkanowy.data.db.migrations.Migration9
import javax.inject.Singleton import javax.inject.Singleton
@Singleton @Singleton
@ -43,21 +80,58 @@ import javax.inject.Singleton
AttendanceSummary::class, AttendanceSummary::class,
Grade::class, Grade::class,
GradeSummary::class, GradeSummary::class,
GradeStatistics::class,
GradePointsStatistics::class,
Message::class, Message::class,
Note::class, Note::class,
Homework::class, Homework::class,
Subject::class Subject::class,
LuckyNumber::class,
CompletedLesson::class,
ReportingUnit::class,
Recipient::class,
MobileDevice::class,
Teacher::class,
School::class
], ],
version = 1, version = AppDatabase.VERSION_SCHEMA,
exportSchema = false exportSchema = true
) )
@TypeConverters(Converters::class) @TypeConverters(Converters::class)
abstract class AppDatabase : RoomDatabase() { abstract class AppDatabase : RoomDatabase() {
companion object { companion object {
fun newInstance(context: Context): AppDatabase { const val VERSION_SCHEMA = 19
fun getMigrations(sharedPrefProvider: SharedPrefProvider): Array<Migration> {
return arrayOf(
Migration2(),
Migration3(),
Migration4(),
Migration5(),
Migration6(),
Migration7(),
Migration8(),
Migration9(),
Migration10(),
Migration11(),
Migration12(),
Migration13(),
Migration14(),
Migration15(),
Migration16(),
Migration17(),
Migration18(),
Migration19(sharedPrefProvider)
)
}
fun newInstance(context: Context, sharedPrefProvider: SharedPrefProvider): AppDatabase {
return Room.databaseBuilder(context, AppDatabase::class.java, "wulkanowy_database") return Room.databaseBuilder(context, AppDatabase::class.java, "wulkanowy_database")
.setJournalMode(TRUNCATE) .setJournalMode(TRUNCATE)
.fallbackToDestructiveMigrationFrom(VERSION_SCHEMA + 1)
.fallbackToDestructiveMigrationOnDowngrade()
.addMigrations(*getMigrations(sharedPrefProvider))
.build() .build()
} }
} }
@ -78,6 +152,10 @@ abstract class AppDatabase : RoomDatabase() {
abstract val gradeSummaryDao: GradeSummaryDao abstract val gradeSummaryDao: GradeSummaryDao
abstract val gradeStatistics: GradeStatisticsDao
abstract val gradePointsStatistics: GradePointsStatisticsDao
abstract val messagesDao: MessagesDao abstract val messagesDao: MessagesDao
abstract val noteDao: NoteDao abstract val noteDao: NoteDao
@ -85,4 +163,18 @@ abstract class AppDatabase : RoomDatabase() {
abstract val homeworkDao: HomeworkDao abstract val homeworkDao: HomeworkDao
abstract val subjectDao: SubjectDao abstract val subjectDao: SubjectDao
abstract val luckyNumberDao: LuckyNumberDao
abstract val completedLessonsDao: CompletedLessonsDao
abstract val reportingUnitDao: ReportingUnitDao
abstract val recipientDao: RecipientDao
abstract val mobileDeviceDao: MobileDeviceDao
abstract val teacherDao: TeacherDao
abstract val schoolDao: SchoolDao
} }

View file

@ -1,6 +1,8 @@
package io.github.wulkanowy.data.db package io.github.wulkanowy.data.db
import androidx.room.TypeConverter import androidx.room.TypeConverter
import com.google.gson.Gson
import com.google.gson.reflect.TypeToken
import org.threeten.bp.DateTimeUtils import org.threeten.bp.DateTimeUtils
import org.threeten.bp.Instant import org.threeten.bp.Instant
import org.threeten.bp.LocalDate import org.threeten.bp.LocalDate
@ -36,4 +38,14 @@ class Converters {
@TypeConverter @TypeConverter
fun intToMonth(value: Int?) = value?.let { Month.of(it) } fun intToMonth(value: Int?) = value?.let { Month.of(it) }
@TypeConverter
fun intListToGson(list: List<Int>): String {
return Gson().toJson(list)
}
@TypeConverter
fun gsonToIntList(value: String): List<Int> {
return Gson().fromJson(value, object : TypeToken<List<Int>>() {}.type)
}
} }

View file

@ -1,33 +0,0 @@
package io.github.wulkanowy.data.db
import android.annotation.SuppressLint
import android.content.SharedPreferences
import javax.inject.Inject
import javax.inject.Singleton
@Singleton
class SharedPrefHelper @Inject constructor(private val sharedPref: SharedPreferences) {
@SuppressLint("ApplySharedPref")
fun putLong(key: String, value: Long, sync: Boolean = false) {
sharedPref.edit().putLong(key, value).apply {
if (sync) commit() else apply()
}
}
fun getLong(key: String, defaultValue: Long): Long {
return sharedPref.getLong(key, defaultValue)
}
fun putBoolean(key: String, value: Boolean) {
sharedPref.edit().putBoolean(key, value).apply()
}
fun getBoolean(key: String, defaultValue: Boolean): Boolean {
return sharedPref.getBoolean(key, defaultValue)
}
fun delete(key: String) {
sharedPref.edit().remove(key).apply()
}
}

View file

@ -0,0 +1,30 @@
package io.github.wulkanowy.data.db
import android.content.SharedPreferences
import androidx.core.content.edit
import javax.inject.Inject
import javax.inject.Singleton
@Singleton
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(sync) { putLong(key, value) }
}
fun getLong(key: String, defaultValue: Long) = sharedPref.getLong(key, defaultValue)
fun getString(key: String, defaultValue: String): String = sharedPref.getString(key, defaultValue) ?: defaultValue
fun putString(key: String, value: String, sync: Boolean = false) {
sharedPref.edit(sync) { putString(key, value) }
}
fun delete(key: String) {
sharedPref.edit().remove(key).apply()
}
}

View file

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

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

View file

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

@ -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.GradeStatistics
import io.reactivex.Maybe
import javax.inject.Singleton
@Singleton
@Dao
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>>
@Query("SELECT * FROM GradesStatistics WHERE student_id = :studentId AND semester_id = :semesterId AND is_semester = :isSemester")
fun loadAll(semesterId: Int, studentId: Int, isSemester: Boolean): Maybe<List<GradeStatistics>>
}

View file

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

View file

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

View file

@ -0,0 +1,16 @@
package io.github.wulkanowy.data.db.dao
import androidx.room.Dao
import androidx.room.Query
import io.github.wulkanowy.data.db.entities.LuckyNumber
import io.reactivex.Maybe
import org.threeten.bp.LocalDate
import javax.inject.Singleton
@Singleton
@Dao
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,37 +1,19 @@
package io.github.wulkanowy.data.db.dao package io.github.wulkanowy.data.db.dao
import androidx.room.Dao import androidx.room.Dao
import androidx.room.Delete
import androidx.room.Insert
import androidx.room.Query import androidx.room.Query
import androidx.room.Update
import io.github.wulkanowy.data.db.entities.Message import io.github.wulkanowy.data.db.entities.Message
import io.reactivex.Maybe import io.reactivex.Maybe
@Dao @Dao
interface MessagesDao { interface MessagesDao : BaseDao<Message> {
@Insert @Query("SELECT * FROM Messages WHERE student_id = :studentId AND folder_id = :folder AND removed = 0 ORDER BY date DESC")
fun insertAll(messages: List<Message>): List<Long> fun loadAll(studentId: Int, folder: Int): Maybe<List<Message>>
@Delete @Query("SELECT * FROM Messages WHERE id = :id")
fun deleteAll(messages: List<Message>) fun load(id: Long): Maybe<Message>
@Update
fun update(message: Message)
@Update
fun updateAll(messages: List<Message>)
@Query("SELECT * FROM Messages WHERE student_id = :studentId AND real_id = :id")
fun loadOne(studentId: Int, id: Int): Maybe<Message>
@Query("SELECT * FROM Messages WHERE student_id = :studentId AND folder_id = :folder ORDER BY date DESC")
fun load(studentId: Int, folder: Int): Maybe<List<Message>>
@Query("SELECT * FROM Messages WHERE student_id = :studentId AND removed = 1 ORDER BY date DESC") @Query("SELECT * FROM Messages WHERE student_id = :studentId AND removed = 1 ORDER BY date DESC")
fun loadDeleted(studentId: Int): Maybe<List<Message>> fun loadDeleted(studentId: Int): Maybe<List<Message>>
@Query("SELECT * FROM Messages WHERE unread = 1 AND student_id = :studentId")
fun loadNewMessages(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,33 +1,15 @@
package io.github.wulkanowy.data.db.dao package io.github.wulkanowy.data.db.dao
import androidx.room.Dao import androidx.room.Dao
import androidx.room.Delete
import androidx.room.Insert
import androidx.room.Query import androidx.room.Query
import androidx.room.Update
import io.github.wulkanowy.data.db.entities.Note import io.github.wulkanowy.data.db.entities.Note
import io.reactivex.Maybe import io.reactivex.Maybe
import javax.inject.Singleton import javax.inject.Singleton
@Singleton @Singleton
@Dao @Dao
interface NoteDao { interface NoteDao : BaseDao<Note> {
@Insert @Query("SELECT * FROM Notes WHERE student_id = :studentId")
fun insertAll(notes: List<Note>) fun loadAll(studentId: Int): Maybe<List<Note>>
@Update
fun update(note: Note)
@Update
fun updateAll(notes: List<Note>)
@Delete
fun deleteAll(notes: List<Note>)
@Query("SELECT * FROM Notes WHERE semester_id = :semesterId AND student_id = :studentId")
fun loadAll(semesterId: Int, studentId: Int): Maybe<List<Note>>
@Query("SELECT * FROM Notes WHERE is_read = 0 AND semester_id = :semesterId AND student_id = :studentId")
fun loadNew(semesterId: Int, studentId: Int): Maybe<List<Note>>
} }

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.Recipient
import io.reactivex.Maybe
import javax.inject.Singleton
@Singleton
@Dao
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

@ -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.ReportingUnit
import io.reactivex.Maybe
import javax.inject.Singleton
@Singleton
@Dao
interface ReportingUnitDao : BaseDao<ReportingUnit> {
@Query("SELECT * FROM ReportingUnits WHERE student_id = :studentId")
fun load(studentId: Int): Maybe<List<ReportingUnit>>
@Query("SELECT * FROM ReportingUnits WHERE student_id = :studentId AND real_id = :unitId")
fun loadOne(studentId: Int, unitId: Int): Maybe<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 package io.github.wulkanowy.data.db.dao
import androidx.room.Dao import androidx.room.Dao
import androidx.room.Insert
import androidx.room.OnConflictStrategy.IGNORE
import androidx.room.Query import androidx.room.Query
import io.github.wulkanowy.data.db.entities.Semester import io.github.wulkanowy.data.db.entities.Semester
import io.reactivex.Maybe import io.reactivex.Maybe
@ -10,17 +8,8 @@ import javax.inject.Singleton
@Singleton @Singleton
@Dao @Dao
interface SemesterDao { interface SemesterDao : BaseDao<Semester> {
@Insert(onConflict = IGNORE) @Query("SELECT * FROM Semesters WHERE student_id = :studentId AND class_id = :classId")
fun insertAll(semester: List<Semester>) fun loadAll(studentId: Int, classId: Int): Maybe<List<Semester>>
@Query("SELECT * FROM Semesters WHERE student_id = :studentId")
fun loadAll(studentId: Int): Maybe<List<Semester>>
@Query("UPDATE Semesters SET is_current = 1 WHERE semester_id = :semesterId AND diary_id = :diaryId")
fun updateCurrent(semesterId: Int, diaryId: Int)
@Query("UPDATE Semesters SET is_current = 0 WHERE student_id = :studentId")
fun resetCurrent(studentId: Int)
} }

View file

@ -3,7 +3,7 @@ package io.github.wulkanowy.data.db.dao
import androidx.room.Dao import androidx.room.Dao
import androidx.room.Delete import androidx.room.Delete
import androidx.room.Insert import androidx.room.Insert
import androidx.room.OnConflictStrategy.FAIL import androidx.room.OnConflictStrategy.ABORT
import androidx.room.Query import androidx.room.Query
import io.github.wulkanowy.data.db.entities.Student import io.github.wulkanowy.data.db.entities.Student
import io.reactivex.Maybe import io.reactivex.Maybe
@ -13,8 +13,8 @@ import javax.inject.Singleton
@Dao @Dao
interface StudentDao { interface StudentDao {
@Insert(onConflict = FAIL) @Insert(onConflict = ABORT)
fun insert(student: Student): Long fun insertAll(student: List<Student>): List<Long>
@Delete @Delete
fun delete(student: Student) fun delete(student: Student)
@ -25,8 +25,8 @@ interface StudentDao {
@Query("SELECT * FROM Students") @Query("SELECT * FROM Students")
fun loadAll(): Maybe<List<Student>> fun loadAll(): Maybe<List<Student>>
@Query("UPDATE Students SET is_current = 1 WHERE student_id = :studentId") @Query("UPDATE Students SET is_current = 1 WHERE id = :id")
fun updateCurrent(studentId: Int) fun updateCurrent(id: Long)
@Query("UPDATE Students SET is_current = 0") @Query("UPDATE Students SET is_current = 0")
fun resetCurrent() fun resetCurrent()

View file

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

View file

@ -10,30 +10,30 @@ import java.io.Serializable
data class Attendance( data class Attendance(
@ColumnInfo(name = "student_id") @ColumnInfo(name = "student_id")
var studentId: Int, val studentId: Int,
@ColumnInfo(name = "diary_id") @ColumnInfo(name = "diary_id")
var diaryId: Int, val diaryId: Int,
var date: LocalDate, val date: LocalDate,
var number: Int, val number: Int,
var subject: String, val subject: String,
var name: String, val name: String,
var presence: Boolean = false, val presence: Boolean,
var absence: Boolean = false, val absence: Boolean,
var exemption: Boolean = false, val exemption: Boolean,
var lateness: Boolean = false, val lateness: Boolean,
var excused: Boolean = false, val excused: Boolean,
var deleted: Boolean = false val deleted: Boolean
) : Serializable { ) : Serializable {
@PrimaryKey(autoGenerate = true) @PrimaryKey(autoGenerate = true)

View file

@ -10,13 +10,13 @@ import java.io.Serializable
data class AttendanceSummary( data class AttendanceSummary(
@ColumnInfo(name = "student_id") @ColumnInfo(name = "student_id")
var studentId: Int, val studentId: Int,
@ColumnInfo(name = "diary_id") @ColumnInfo(name = "diary_id")
var diaryId: Int, val diaryId: Int,
@ColumnInfo(name = "subject_id") @ColumnInfo(name = "subject_id")
var subjectId: Int = 0, val subjectId: Int,
val month: Month, val month: Month,

View file

@ -0,0 +1,40 @@
package io.github.wulkanowy.data.db.entities
import androidx.room.ColumnInfo
import androidx.room.Entity
import androidx.room.PrimaryKey
import org.threeten.bp.LocalDate
import java.io.Serializable
@Entity(tableName = "CompletedLesson")
data class CompletedLesson(
@ColumnInfo(name = "student_id")
val studentId: Int,
@ColumnInfo(name = "diary_id")
val diaryId: Int,
val date: LocalDate,
val number: Int,
val subject: String,
val topic: String,
val teacher: String,
@ColumnInfo(name = "teacher_symbol")
val teacherSymbol: String,
val substitution: String,
val absence: String,
val resources: String
) : Serializable {
@PrimaryKey(autoGenerate = true)
var id: Long = 0
}

View file

@ -9,29 +9,29 @@ import java.io.Serializable
@Entity(tableName = "Exams") @Entity(tableName = "Exams")
data class Exam( data class Exam(
@ColumnInfo(name = "student_id") @ColumnInfo(name = "student_id")
var studentId: Int, val studentId: Int,
@ColumnInfo(name = "diary_id") @ColumnInfo(name = "diary_id")
var diaryId: Int, val diaryId: Int,
var date: LocalDate, val date: LocalDate,
@ColumnInfo(name = "entry_date") @ColumnInfo(name = "entry_date")
var entryDate: LocalDate = LocalDate.now(), val entryDate: LocalDate,
var subject: String, val subject: String,
var group: String, val group: String,
var type: String, val type: String,
var description: String, val description: String,
var teacher: String, val teacher: String,
@ColumnInfo(name = "teacher_symbol") @ColumnInfo(name = "teacher_symbol")
var teacherSymbol: String val teacherSymbol: String
) : Serializable { ) : Serializable {
@PrimaryKey(autoGenerate = true) @PrimaryKey(autoGenerate = true)

View file

@ -10,35 +10,35 @@ import java.io.Serializable
data class Grade( data class Grade(
@ColumnInfo(name = "semester_id") @ColumnInfo(name = "semester_id")
var semesterId: Int, val semesterId: Int,
@ColumnInfo(name = "student_id") @ColumnInfo(name = "student_id")
var studentId: Int, val studentId: Int,
var subject: String, val subject: String,
var entry: String, val entry: String,
var value: Int, val value: Double,
var modifier: Double, val modifier: Double,
var comment: String, val comment: String,
var color: String, val color: String,
@ColumnInfo(name = "grade_symbol") @ColumnInfo(name = "grade_symbol")
var gradeSymbol: String, val gradeSymbol: String,
var description: String, val description: String,
var weight: String, val weight: String,
var weightValue: Int, val weightValue: Double,
var date: LocalDate, val date: LocalDate,
var teacher: String val teacher: String
) : Serializable { ) : Serializable {
@PrimaryKey(autoGenerate = true) @PrimaryKey(autoGenerate = true)

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

@ -0,0 +1,27 @@
package io.github.wulkanowy.data.db.entities
import androidx.room.ColumnInfo
import androidx.room.Entity
import androidx.room.PrimaryKey
@Entity(tableName = "GradesStatistics")
data class GradeStatistics(
@ColumnInfo(name = "student_id")
val studentId: Int,
@ColumnInfo(name = "semester_id")
val semesterId: Int,
val subject: String,
val grade: Int,
val amount: Int,
@ColumnInfo(name = "is_semester")
val semester: Boolean
) {
@PrimaryKey(autoGenerate = true)
var id: Long = 0
}

View file

@ -4,22 +4,36 @@ import androidx.room.ColumnInfo
import androidx.room.Entity import androidx.room.Entity
import androidx.room.PrimaryKey import androidx.room.PrimaryKey
@Entity(tableName = "Grades_Summary") @Entity(tableName = "GradesSummary")
data class GradeSummary( data class GradeSummary(
@ColumnInfo(name = "semester_id") @ColumnInfo(name = "semester_id")
var semesterId: Int, val semesterId: Int,
@ColumnInfo(name = "student_id") @ColumnInfo(name = "student_id")
var studentId: Int, val studentId: Int,
var subject: String, val position: Int,
var predictedGrade: String, val subject: String,
var finalGrade: String @ColumnInfo(name = "predicted_grade")
val predictedGrade: 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) @PrimaryKey(autoGenerate = true)
var id: Long = 0 var id: Long = 0
} }

View file

@ -10,24 +10,24 @@ import java.io.Serializable
data class Homework( data class Homework(
@ColumnInfo(name = "semester_id") @ColumnInfo(name = "semester_id")
var semesterId: Int, val semesterId: Int,
@ColumnInfo(name = "student_id") @ColumnInfo(name = "student_id")
var studentId: Int, val studentId: Int,
var date: LocalDate, val date: LocalDate,
@ColumnInfo(name = "entry_date") @ColumnInfo(name = "entry_date")
var entryDate: LocalDate, val entryDate: LocalDate,
var subject: String, val subject: String,
var content: String, val content: String,
var teacher: String, val teacher: String,
@ColumnInfo(name = "teacher_symbol") @ColumnInfo(name = "teacher_symbol")
var teacherSymbol: String val teacherSymbol: String
) : Serializable { ) : Serializable {

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 org.threeten.bp.LocalDate
import java.io.Serializable
@Entity(tableName = "LuckyNumbers")
data class LuckyNumber (
@ColumnInfo(name = "student_id")
val studentId: Int,
val date: LocalDate,
@ColumnInfo(name = "lucky_number")
val luckyNumber: Int
) : Serializable {
@PrimaryKey(autoGenerate = true)
var id: Long = 0
@ColumnInfo(name = "is_notified")
var isNotified: Boolean = true
}

View file

@ -10,40 +10,41 @@ import java.io.Serializable
data class Message( data class Message(
@ColumnInfo(name = "student_id") @ColumnInfo(name = "student_id")
var studentId: Int? = null, val studentId: Int,
@ColumnInfo(name = "real_id") @ColumnInfo(name = "real_id")
val realId: Int? = null, val realId: Int,
@ColumnInfo(name = "message_id") @ColumnInfo(name = "message_id")
val messageId: Int? = null, val messageId: Int,
@ColumnInfo(name = "sender_name") @ColumnInfo(name = "sender_name")
val sender: String? = null, val sender: String,
@ColumnInfo(name = "sender_id") @ColumnInfo(name = "sender_id")
val senderId: Int? = null, val senderId: Int,
@ColumnInfo(name = "recipient_id")
val recipientId: Int? = null,
@ColumnInfo(name = "recipient_name") @ColumnInfo(name = "recipient_name")
val recipient: String? = "", val recipient: String,
val subject: String = "", val subject: String,
val date: LocalDateTime? = null, var content: String,
val date: LocalDateTime,
@ColumnInfo(name = "folder_id") @ColumnInfo(name = "folder_id")
val folderId: Int = 0, val folderId: Int,
var unread: Boolean? = false, var unread: Boolean,
val unreadBy: Int? = 0, @ColumnInfo(name = "unread_by")
val unreadBy: Int,
val readBy: Int? = 0, @ColumnInfo(name = "read_by")
val readBy: Int,
val removed: Boolean = false val removed: Boolean
) : Serializable { ) : Serializable {
@PrimaryKey(autoGenerate = true) @PrimaryKey(autoGenerate = true)
@ -51,6 +52,4 @@ data class Message(
@ColumnInfo(name = "is_notified") @ColumnInfo(name = "is_notified")
var isNotified: Boolean = true var isNotified: Boolean = true
var content: String? = null
} }

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

@ -9,26 +9,23 @@ import java.io.Serializable
@Entity(tableName = "Notes") @Entity(tableName = "Notes")
data class Note( data class Note(
@ColumnInfo(name = "semester_id")
var semesterId: Int,
@ColumnInfo(name = "student_id") @ColumnInfo(name = "student_id")
var studentId: Int, val studentId: Int,
var date: LocalDate, val date: LocalDate,
var teacher: String, val teacher: String,
var category: String, val category: String,
var content: String val content: String
) : Serializable { ) : Serializable {
@PrimaryKey(autoGenerate = true) @PrimaryKey(autoGenerate = true)
var id: Long = 0 var id: Long = 0
@ColumnInfo(name = "is_read") @ColumnInfo(name = "is_read")
var isRead: Boolean = false var isRead: Boolean = true
@ColumnInfo(name = "is_notified") @ColumnInfo(name = "is_notified")
var isNotified: Boolean = true var isNotified: Boolean = true

View file

@ -0,0 +1,38 @@
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 = "Recipients")
data class Recipient(
@ColumnInfo(name = "student_id")
val studentId: Int,
@ColumnInfo(name = "real_id")
val realId: String,
val name: String,
@ColumnInfo(name = "real_name")
val realName: String,
@ColumnInfo(name = "login_id")
val loginId: Int,
@ColumnInfo(name = "unit_id")
val unitId: Int,
val role: Int,
val hash: String
) : Serializable {
@PrimaryKey(autoGenerate = true)
var id: Long = 0
override fun toString() = name
}

View file

@ -0,0 +1,32 @@
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 = "ReportingUnits")
data class ReportingUnit(
@ColumnInfo(name = "student_id")
val studentId: Int,
@ColumnInfo(name = "real_id")
val realId: Int,
@ColumnInfo(name = "short")
val shortName: String,
@ColumnInfo(name = "sender_id")
val senderId: Int,
@ColumnInfo(name = "sender_name")
val senderName: String,
val roles: List<Int>
) : Serializable {
@PrimaryKey(autoGenerate = true)
var id: Long = 0
}

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