1
0
Fork 1

Compare commits

...

280 commits
1.0.1 ... 1.2.1

Author SHA1 Message Date
Mikołaj Pich
3d0dcead50 Merge branch 'release/1.2.1' 2021-09-05 23:29:23 +02:00
Mikołaj Pich
b64b41c11c Version 1.2.1 2021-09-05 23:29:15 +02:00
Rafał Borcz
77c5330f91
Dashboard fixes (#1463) 2021-09-05 23:24:03 +02:00
Rafał Borcz
2b55ec02ff
New translations strings.xml (Polish) (#1474) 2021-09-05 23:06:44 +02:00
Rafał Borcz
49ebae6e63
Fix overlaping empty and error view in grade statistics (#1475)
Co-authored-by: Mikołaj Pich <m.pich@outlook.com>
2021-09-05 19:59:03 +00:00
dependabot[bot]
44a9db48a6
Bump hianalytics from 6.2.0.300 to 6.2.0.301 (#1476) 2021-09-05 18:17:18 +00:00
dependabot[bot]
0008a72be1
Bump kotlinx-coroutines-test from 1.5.1 to 1.5.2 (#1477) 2021-09-05 18:10:22 +00:00
dependabot[bot]
a43acaaa07
Bump kotlinx-coroutines-android from 1.5.1 to 1.5.2 (#1479) 2021-09-05 18:10:05 +00:00
dependabot[bot]
e6c9abb4e5
Bump core from 1.10.0 to 1.10.1 (#1480) 2021-09-05 18:09:42 +00:00
Mikołaj Pich
3b9451184c
Fix preview of second student guardian when first guardian is null (#1473) 2021-09-05 03:15:40 +02:00
Mikołaj Pich
45d1727dbe
Add missing school announcement dialog (#1470) 2021-09-04 15:54:37 +02:00
Mikołaj Pich
8d7b611c44
Fix showing error view in timetable (#1472) 2021-09-04 15:54:05 +02:00
Rafał Borcz
c3adb9b6d6
Bump agp to 7.0.2 (#1469) 2021-09-03 22:54:29 +02:00
Mikołaj Pich
d87283eb31
Fix opening twitter link from about on android 11 (#1460) 2021-08-30 00:20:13 +02:00
dependabot[bot]
d139c22782
Bump hianalytics from 6.1.1.300 to 6.2.0.300 (#1457) 2021-08-29 19:37:18 +00:00
dependabot[bot]
e557021ad9
Bump huawei-publish-gradle-plugin from 1.2.4 to 1.3.0 (#1458) 2021-08-29 19:37:01 +00:00
Mikołaj Pich
37af5de25c Merge branch 'release/1.2.0' into develop 2021-08-29 21:08:23 +02:00
Mikołaj Pich
db6c84775b Merge branch 'release/1.2.0' 2021-08-29 21:08:18 +02:00
Mikołaj Pich
72d8b4aa84 Version 1.2.0 2021-08-29 21:08:08 +02:00
Rafał Borcz
170b7c4379
New Crowdin updates (#1459) 2021-08-29 21:06:33 +02:00
Rafał Borcz
79e9e1a780
New Crowdin updates (#1321) 2021-08-29 20:01:36 +02:00
Mateusz Idziejczak
98dcc62bb7
Add excuse function to "not excusable" account (#1429) 2021-08-29 19:47:14 +02:00
Mikołaj Pich
ea0fb00bde
Fix crash on opening date pickers during holidays (#1456) 2021-08-29 19:31:28 +02:00
Mikołaj Pich
4aa6b0b995
Hide keyboard on opening login host dropdown (#1455) 2021-08-29 19:00:30 +02:00
Mikołaj Pich
57d11e825b
Update readBy and unreadBy fields during message list fetch (#1452) 2021-08-29 15:40:28 +02:00
Daniel Olczyk
2f43b6e552
Change display name for MRmlik12 (#1451) 2021-08-29 14:08:48 +02:00
Mateusz Idziejczak
765f8a2d1f
Add in app review (#1435) 2021-08-29 00:43:58 +02:00
Tomasz F
04c727a0c8
Exams and homework notification fixes (#1292) 2021-08-29 00:41:58 +02:00
Rafał Borcz
55518cb044
Add missing dashboard item in default view settings (#1450) 2021-08-28 21:43:10 +02:00
Rafał Borcz
cebd1aa75d
Remove lithuanian lang (#1449) 2021-08-28 12:14:01 +02:00
Piotr Romanowski
4a38a0be70
Add change password snackbar (#1336) 2021-08-26 17:35:41 +00:00
Rafał Borcz
b4b9d91ea6
Update dependencies (#1448) 2021-08-25 20:49:44 +02:00
Rafał Borcz
a6a2bcff3b
Remove Zachowanie from all count of subjects (#1447) 2021-08-24 19:51:08 +02:00
Mateusz Idziejczak
2979d8b62a
Show information when the recipient has read the message (#1430) 2021-08-23 16:16:41 +00:00
killerkeemstar
aba2068a84
New timetable widget design (#1384) 2021-08-23 16:02:21 +00:00
dependabot[bot]
076948a680
Bump gradle from 7.0.0 to 7.0.1 (#1445) 2021-08-23 13:53:04 +00:00
Mateusz Idziejczak
1cfabe43a5
Add captions for averages from how many items have been counted (#1437) 2021-08-23 15:48:48 +02:00
dependabot[bot]
02b87c8c6a
Bump firebase-bom from 28.3.1 to 28.4.0 (#1446) 2021-08-23 13:42:20 +00:00
Mateusz Idziejczak
eb94e06d54
Fix buggy timers in timetable (#1428)
Co-authored-by: Rafał Borcz <RafalBO99@outlook.com>
2021-08-22 16:33:12 +02:00
dependabot[bot]
d3b3939d26
Bump timber from 4.7.1 to 5.0.1 (#1440) 2021-08-17 13:44:06 +00:00
dependabot[bot]
9c5d2fbf84
Bump google-services from 4.3.9 to 4.3.10 (#1439) 2021-08-17 13:32:48 +00:00
dependabot[bot]
428e40d7fe
Bump hianalytics from 6.1.0.300 to 6.1.1.300 (#1441) 2021-08-17 13:32:34 +00:00
Mateusz Idziejczak
9c819835ca
Add last sync date in sync settings (#1436) 2021-08-15 13:59:32 +00:00
Rafał Borcz
626169de11
Add drag and drop to dashboard tiles (#1415) 2021-08-10 11:55:51 +02:00
dependabot[bot]
72ef5f428e
Bump firebase-bom from 28.3.0 to 28.3.1 (#1431) 2021-08-09 13:55:03 +00:00
dependabot[bot]
4ae3f7b016
Bump google-services from 4.3.8 to 4.3.9 (#1432) 2021-08-09 13:54:48 +00:00
dependabot[bot]
7c94837af0
Bump coil from 1.3.1 to 1.3.2 (#1433) 2021-08-09 13:54:31 +00:00
dependabot[bot]
2a91346155
Bump activity-ktx from 1.3.0 to 1.3.1 (#1434) 2021-08-09 13:53:54 +00:00
Mateusz Idziejczak
ec6d18968f
Fix filter search bug (#1427)
* Fix filter search bug

* refractor
2021-08-07 10:27:51 +02:00
Mateusz Idziejczak
b61e63249c
Add messages sorting (#1262) 2021-08-04 15:16:54 +02:00
Damian Czupryn
d73aa605f9
Change dashboard no data strings (#1426) 2021-08-03 18:55:20 +02:00
Mikołaj Pich
14f4808434
Add student nick-or-name to notification summary (#1425) 2021-08-03 15:48:11 +02:00
dependabot[bot]
2bc6d7ad0d
Bump gradle from 4.2.2 to 7.0.0 (#1419) 2021-08-02 16:28:12 +00:00
dependabot[bot]
888052cd9c
Bump agcp from 1.5.3.200 to 1.6.0.300 (#1424) 2021-08-02 15:18:29 +00:00
dependabot[bot]
bdc2281fdc
Bump agconnect-crash from 1.5.3.200 to 1.6.0.300 (#1423) 2021-08-02 15:18:18 +00:00
dependabot[bot]
d01edc2312
Bump activity-ktx from 1.2.4 to 1.3.0 (#1422) 2021-08-02 15:17:05 +00:00
dependabot[bot]
484a3aa731
Bump chucker from 3.5.1 to 3.5.2 (#1417) 2021-08-02 13:26:33 +00:00
dependabot[bot]
51be23470f
Bump hilt_version from 2.38 to 2.38.1 (#1418) 2021-08-02 13:25:19 +00:00
dependabot[bot]
19495ffce9
Bump constraintlayout from 2.1.0-beta02 to 2.1.0 (#1420) 2021-08-02 13:24:31 +00:00
dependabot[bot]
bd766d33db
Bump coil from 1.3.0 to 1.3.1 (#1421) 2021-08-02 13:23:25 +00:00
Mikołaj Pich
ff8b3f8837
Send mutltiple notifications instead of summary notification (#1365) 2021-08-01 13:19:46 +02:00
Rafał Borcz
e678e6d7f9
Fix margin and attedance destination (#1414) 2021-07-31 20:19:05 +02:00
Mikołaj Pich
f6f3447f1d
Fix sorting notes in loading state (#1413) 2021-07-31 18:08:35 +02:00
MRmlik12
e1c1f305c4
Add draft message (#1306) 2021-07-31 18:00:22 +02:00
MRmlik12
c8c9001277
Add twitter page link to about fragment (#1411) 2021-07-30 19:13:06 +02:00
Rafał Borcz
3422951e47
Add dashboard (#1267) 2021-07-30 18:49:19 +02:00
dependabot[bot]
3278c11cce
Bump hilt_version from 2.37 to 2.38 (#1405) 2021-07-27 08:39:37 +00:00
dependabot[bot]
e00dea51f1
Bump appcompat from 1.3.0 to 1.3.1 (#1409) 2021-07-26 19:55:08 +00:00
dependabot[bot]
5bf411039d
Bump fragment-ktx from 1.3.5 to 1.3.6 (#1404) 2021-07-26 19:54:50 +00:00
dependabot[bot]
62ca394c9a
Bump appcompat-resources from 1.3.0 to 1.3.1 (#1403) 2021-07-26 19:48:14 +00:00
dependabot[bot]
255b89bbb3
Bump about_libraries from 8.9.0 to 8.9.1 (#1406) 2021-07-26 19:42:25 +00:00
dependabot[bot]
f7987f4b29
Bump chucker from 3.5.0 to 3.5.1 (#1407) 2021-07-26 19:42:11 +00:00
dependabot[bot]
0b583439dd
Bump firebase-bom from 28.2.1 to 28.3.0 (#1408) 2021-07-26 19:41:55 +00:00
dependabot[bot]
ca481dc6f5
Bump activity-ktx from 1.2.3 to 1.2.4 (#1410) 2021-07-26 19:41:28 +00:00
dependabot[bot]
f6a92a4cc3
Bump hianalytics from 6.0.0.301 to 6.1.0.300 (#1402) 2021-07-21 07:21:49 +00:00
dependabot[bot]
55a6219a42
Bump kotlin_version from 1.5.20 to 1.5.21 (#1401) 2021-07-21 07:21:25 +00:00
dependabot[bot]
ad653f10df
Bump firebase-bom from 28.2.0 to 28.2.1 (#1400) 2021-07-12 22:44:06 +02:00
dependabot[bot]
7a780486f6
Bump kotlinx-coroutines-android from 1.5.0 to 1.5.1-native-mt (#1395) 2021-07-12 19:54:35 +00:00
dependabot[bot]
c01b0eff9d
Bump agconnect-crash from 1.5.2.300 to 1.5.3.200 (#1399) 2021-07-12 19:53:03 +00:00
dependabot[bot]
3a4614e2b7
Bump robolectric from 4.5.1 to 4.6.1 (#1392) 2021-07-12 19:52:39 +00:00
dependabot[bot]
44ee8859b1
Bump junit from 1.1.2 to 1.1.3 (#1389) 2021-07-12 19:52:25 +00:00
dependabot[bot]
3dd7878ae5
Bump mockk from 1.11.0 to 1.12.0 (#1387) 2021-07-12 19:47:16 +00:00
dependabot[bot]
0305a005ab
Bump agcp from 1.5.2.300 to 1.5.3.200 (#1398) 2021-07-12 19:47:04 +00:00
dependabot[bot]
2229f0e3e9
Bump coil from 1.2.2 to 1.3.0 (#1397) 2021-07-12 19:46:13 +00:00
dependabot[bot]
d9aab7afa2
Bump runner from 1.3.0 to 1.4.0 (#1386) 2021-07-12 19:45:36 +00:00
dependabot[bot]
0558f30646
Bump material from 1.3.0 to 1.4.0 (#1390) 2021-07-12 19:44:04 +00:00
dependabot[bot]
238f257c6c
Bump hianalytics from 5.3.1.300 to 6.0.0.301 (#1394) 2021-07-12 19:43:46 +00:00
dependabot[bot]
40372e7cea
Bump core-ktx from 1.5.0 to 1.6.0 (#1388) 2021-07-12 19:40:32 +00:00
dependabot[bot]
b65a060fca
Bump chucker from 3.4.0 to 3.5.0 (#1385) 2021-07-12 19:40:15 +00:00
dependabot[bot]
c1ed748188
Bump gradle from 4.2.1 to 4.2.2 (#1393) 2021-07-12 19:39:19 +00:00
dependabot[bot]
b911521ccc
Bump core from 1.3.0 to 1.4.0 (#1391) 2021-07-12 19:39:02 +00:00
dependabot[bot]
b046679542
Bump kotlin_version from 1.5.10 to 1.5.20 (#1381) 2021-06-27 20:09:46 +00:00
dependabot[bot]
3decc95a20
Bump firebase-crashlytics-gradle from 2.7.0 to 2.7.1 (#1382) 2021-06-27 19:37:24 +00:00
dependabot[bot]
c301198006
Bump firebase-bom from 28.1.0 to 28.2.0 (#1383) 2021-06-27 19:33:51 +00:00
dependabot[bot]
190a5f2067
Bump fragment-ktx from 1.3.4 to 1.3.5 (#1380) 2021-06-22 20:37:21 +00:00
Mikołaj Pich
27e1a07eec
Add notifications debug screen (#1370) 2021-06-21 10:29:04 +02:00
dependabot[bot]
64feae9f1c
Bump hilt_version from 2.36 to 2.37 (#1376) 2021-06-12 12:31:59 +00:00
dependabot[bot]
085158721e
Bump sonarqube-gradle-plugin from 3.2.0 to 3.3 (#1378) 2021-06-11 11:45:25 +00:00
MRmlik12
44888b048d
Add "I forgot my password" button in upper bar (#1375) 2021-06-11 09:53:11 +02:00
Rafał Borcz
b9a12e46bf
Upgrade gradle to 6.9 (#1371) 2021-06-09 09:46:16 +02:00
dependabot[bot]
2fe5e62e72
Bump recyclerview from 1.2.0 to 1.2.1 (#1366) 2021-06-08 10:02:09 +00:00
dependabot[bot]
6305e1a908
Bump firebase-bom from 28.0.1 to 28.1.0 (#1367) 2021-06-08 10:01:12 +00:00
dependabot[bot]
6bf7a2e26c
Bump firebase-crashlytics-gradle from 2.6.1 to 2.7.0 (#1368) 2021-06-08 10:00:27 +00:00
dependabot[bot]
34487175d8
Bump coil from 1.2.1 to 1.2.2 (#1369) 2021-06-08 10:00:10 +00:00
Rafał Borcz
f02db914bf
Fix treessence upgrade (#1361) 2021-06-02 12:45:16 +02:00
dependabot[bot]
18e0a59e2b
Bump hilt_version from 2.35.1 to 2.36 (#1362) 2021-06-02 09:12:01 +00:00
dependabot[bot]
e4371af284
Bump about_libraries from 8.8.5 to 8.9.0 (#1363) 2021-06-02 08:21:34 +00:00
Rafał Borcz
44d5f69de1
Remove jcenter repository and unused code from gradle config (#1360) 2021-05-28 10:57:25 +02:00
dependabot[bot]
d13e0adb00
Bump appcompat from 1.2.0 to 1.3.0 (#1357) 2021-05-28 07:09:47 +00:00
dependabot[bot]
e60e573ac0
Bump appcompat-resources from 1.2.0 to 1.3.0 (#1359) 2021-05-28 07:01:57 +00:00
dependabot[bot]
91dbc9e3d7
Bump core-ktx from 1.3.2 to 1.5.0 (#1356) 2021-05-28 06:15:18 +00:00
dependabot[bot]
8ccbea2c21
Bump fragment-ktx from 1.3.3 to 1.3.4 (#1358) 2021-05-25 11:10:52 +00:00
Mikołaj Pich
211cb5e4f2 Merge branch 'hotfix/messages-send' into develop 2021-05-21 14:09:45 +02:00
Mikołaj Pich
b60c59216d Merge branch 'hotfix/messages-send' 2021-05-21 14:08:00 +02:00
Mikołaj Pich
d20f3180cf Version 1.1.6 2021-05-21 14:03:13 +02:00
Mikołaj Pich
17761af9d6 Bump sdk 2021-05-21 12:35:57 +02:00
dependabot[bot]
067817bace Bump huawei-publish-gradle-plugin from 1.2.2 to 1.2.4 (#1314)
Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
Co-authored-by: Mikołaj Pich <m.pich@outlook.com>
(cherry picked from commit 022a4d1ea2)
2021-05-21 12:30:36 +02:00
dependabot[bot]
51800d91b2
Bump gradle from 4.1.3 to 4.2.1 (#1339) 2021-05-19 22:40:21 +00:00
Rafał Borcz
3640c4f249
Update dependabot config (#1353) 2021-05-18 09:40:08 +00:00
Dominik Korsa
05aa38b591
Add arrows to student family list items (#1338) 2021-05-17 15:35:36 +02:00
Damian Czupryn
983dcd8656
Add conferences and announcements notifications (#1330) 2021-05-17 15:19:39 +02:00
dependabot[bot]
59cf4fb222
Bump kotlinx-coroutines-android from 1.5.0-RC to 1.5.0 (#1348) 2021-05-17 11:33:27 +00:00
dependabot[bot]
d6ebcc97e3
Bump firebase-crashlytics-gradle from 2.5.2 to 2.6.1 (#1342) 2021-05-17 11:32:03 +00:00
dependabot[bot]
047579c394
Bump agcp from 1.5.2.201 to 1.5.2.300 (#1349) 2021-05-17 11:24:31 +00:00
dependabot[bot]
a90fd4b776
Bump agconnect-crash from 1.5.2.201 to 1.5.2.300 (#1350) 2021-05-17 11:21:48 +00:00
dependabot[bot]
03d3a5db11
Bump firebase-bom from 27.1.0 to 28.0.1 (#1341) 2021-05-17 11:21:31 +00:00
dependabot[bot]
bf5e61490d
Bump google-services from 4.3.5 to 4.3.8 (#1344) 2021-05-17 11:18:08 +00:00
dependabot[bot]
d87fa589a8
Bump hianalytics from 5.3.0.300 to 5.3.1.300 (#1332) 2021-05-10 11:50:20 +00:00
dependabot[bot]
1fff1c2b14
Bump kotlin_version from 1.4.32 to 1.5.0 (#1310) 2021-05-06 11:02:08 +00:00
dependabot[bot]
58d66b6e70
Bump work_hilt from 1.0.0-beta01 to 1.0.0 (#1329) 2021-05-05 22:23:31 +00:00
dependabot[bot]
202d13d509
Bump activity-ktx from 1.2.2 to 1.2.3 (#1328) 2021-05-05 22:21:48 +00:00
Damian Czupryn
db808de06c
Fix no info text position in school announcements (#1327) 2021-05-05 20:18:16 +02:00
Mateusz Idziejczak
d8dae09f39
Add notification icons (#1276)
Co-authored-by: Mikołaj Pich <m.pich@outlook.com>
2021-05-03 18:24:54 +02:00
Damian Czupryn
32640e0796
Change mobile devices item order (#1324)
* Change more items order

* Resolve conflicts
2021-05-03 18:23:09 +02:00
Mikołaj Pich
4e80441167
Add school announcements (#1323) 2021-05-03 17:24:01 +02:00
Rafał Borcz
075cfb20b1
Fix missing snackbar in sync settings fragment (#1325) 2021-05-03 16:42:59 +02:00
Damian Czupryn
56e4e9be5e
Fix homework dialog attachments margin (#1322) 2021-05-02 21:56:41 +02:00
Mateusz Idziejczak
53c798ebdb
Change titles in Student Info (#1121) 2021-05-02 14:09:42 +00:00
dependabot[bot]
022a4d1ea2
Bump huawei-publish-gradle-plugin from 1.2.2 to 1.2.4 (#1314)
Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
Co-authored-by: Mikołaj Pich <m.pich@outlook.com>
2021-05-02 13:49:28 +02:00
Rafał Borcz
dfa25d8445
New Crowdin updates (#1268) 2021-05-02 12:53:53 +02:00
Mateusz Idziejczak
b2efe0d981
Probably fix list divider color (#1270)
Co-authored-by: Rafał Borcz <RafalBO99@outlook.com>
2021-05-02 12:33:27 +02:00
dependabot[bot]
2a7f846d3f
Bump hilt_version from 2.35 to 2.35.1 (#1313) 2021-04-30 14:05:08 +00:00
dependabot[bot]
da5817d08a
Bump sonarqube-gradle-plugin from 3.1.1 to 3.2.0 (#1315) 2021-04-30 13:59:46 +00:00
dependabot[bot]
cacf2f651a
Bump agcp from 1.5.1.300 to 1.5.2.201 (#1311) 2021-04-30 13:57:51 +00:00
dependabot[bot]
605c816a32
Bump coil from 1.2.0 to 1.2.1 (#1312) 2021-04-30 13:57:35 +00:00
dependabot[bot]
1587be2fa8
Bump hianalytics from 5.2.0.301 to 5.3.0.300 (#1319) 2021-04-30 13:53:54 +00:00
dependabot[bot]
00b23ca20c
Bump agconnect-crash from 1.5.1.300 to 1.5.2.201 (#1316) 2021-04-30 13:46:30 +00:00
dependabot-preview[bot]
34db20ab0c
Upgrade to GitHub-native Dependabot (#1309) 2021-04-30 13:23:57 +00:00
dependabot-preview[bot]
0d271d925a
Bump room from 2.3.0-rc01 to 2.3.0 (#1302) 2021-04-25 01:31:48 +02:00
dependabot-preview[bot]
b7da43a52a
Bump hilt_version from 2.34.1-beta to 2.35 (#1303) 2021-04-24 12:57:55 +00:00
dependabot-preview[bot]
44af5d59fb
Bump fragment-ktx from 1.3.2 to 1.3.3 (#1304) 2021-04-24 12:57:41 +00:00
dependabot-preview[bot]
bc776993a9
Bump firebase-bom from 27.0.0 to 27.1.0 (#1305) 2021-04-24 12:57:21 +00:00
Damian Czupryn
9a19ce9ca4
Fix Homework dialog buttons layout (#1297) 2021-04-19 16:09:14 +00:00
Mikołaj Pich
6855296de4 Merge branch 'hotfix/all-year-average' into develop 2021-04-18 20:43:29 +02:00
Mikołaj Pich
800a31f160 Merge branch 'hotfix/all-year-average' 2021-04-18 20:40:02 +02:00
Mikołaj Pich
8b83b37b09 Version 1.1.5 2021-04-18 20:38:18 +02:00
Faierbel
43e95cfdc6 Fix all year average 2021-04-18 19:36:02 +02:00
Rafał Borcz
ae2a697e01
Merge pull request #1295 from wulkanowy/rbo/update-workflow
Update github action workflow
2021-04-18 19:34:32 +02:00
dependabot-preview[bot]
b695c7f600
Bump hilt_version from 2.34-beta to 2.34.1-beta (#1293) 2021-04-17 20:45:38 +00:00
dependabot-preview[bot]
3a1a383383
Bump recyclerview from 1.1.0 to 1.2.0 (#1287) 2021-04-14 18:59:12 +00:00
dependabot-preview[bot]
97810d02ab
Bump moshi from 1.11.0 to 1.12.0 (#1284) 2021-04-14 18:58:54 +00:00
dependabot-preview[bot]
30b337a364
Bump about_libraries from 8.8.4 to 8.8.5 (#1281) 2021-04-13 11:55:39 +00:00
dependabot-preview[bot]
8f6c847562
Bump agconnect-crash from 1.5.1.200 to 1.5.1.300 (#1283) 2021-04-13 11:44:01 +00:00
dependabot-preview[bot]
e5d54c95f3
Bump firebase-bom from 26.8.0 to 27.0.0 (#1285) 2021-04-13 11:43:09 +00:00
dependabot-preview[bot]
eb5ad81ec1
Bump agcp from 1.5.1.200 to 1.5.1.300 (#1286) 2021-04-13 11:42:48 +00:00
dependabot-preview[bot]
3aa9f0ca2f
Bump coil from 1.1.1 to 1.2.0 (#1282) 2021-04-13 11:42:21 +00:00
dependabot-preview[bot]
8e587358aa
Bump hilt_version from 2.33-beta to 2.34-beta (#1280) 2021-04-13 11:39:14 +00:00
Damian Czupryn
4492f4a864
Dialogs adjustments to meet MD rules (#1227) 2021-04-12 20:06:28 +00:00
Damian Czupryn
b453225941
Student info and Teachers screens unification (#1279) 2021-04-12 19:58:58 +00:00
Mateusz Idziejczak
13ccfda009
Migrate material date picker (#1277) 2021-04-12 21:43:52 +02:00
Rafał Borcz
95ffb0a687
Ignore all throwable from WebView (#1275) 2021-04-08 10:41:49 +02:00
Mateusz Idziejczak
f131edf857
Add system settings shortcut (#1271) 2021-04-07 11:56:33 +00:00
Mikołaj Pich
bd2d26418a
Cleanup github workflows (#1272) 2021-04-07 13:25:48 +02:00
Mikołaj Pich
aeb3b2a030
Display day header from website in timetable (#1269) 2021-04-05 15:07:29 +02:00
Tomasz F
7bc5219d81
Add new notifications (#1243) 2021-04-04 14:15:07 +00:00
Rafał Borcz
6cb4ea4b0f
Drop support for android 4.x (#1232) 2021-04-03 09:56:07 +00:00
Rafał Borcz
0bdd33ef4a
Migrate to material components bottom navigation (#1244) 2021-04-03 11:46:36 +02:00
Mikołaj Pich
792de4cd3d Merge branch 'hotfix/fix-recovery-visibility' into develop 2021-04-01 22:40:33 +02:00
Mikołaj Pich
3f5fbbc71b Merge branch 'hotfix/fix-recovery-visibility' 2021-04-01 22:40:20 +02:00
Rafał Borcz
206b40ce1b Change version in changelog 2021-04-01 22:38:35 +02:00
Rafał Borcz
43c56b5534 Version 1.1.4 2021-04-01 22:36:51 +02:00
Rafał Borcz
a1076539dc Fix content visibility in login recovery 2021-04-01 22:30:09 +02:00
Kamil Studziński
3071e19584
Implement a toggleable setting to count an arithmetic average of grades when all weights are equal to zero (#1186) 2021-03-30 13:59:36 +02:00
dependabot-preview[bot]
f2130998ec
Bump firebase-crashlytics-gradle from 2.5.1 to 2.5.2 (#1264) 2021-03-30 10:49:40 +00:00
dependabot-preview[bot]
8a5ca8c91f
Bump firebase-bom from 26.7.0 to 26.8.0 (#1263) 2021-03-30 10:48:12 +00:00
Mateusz Idziejczak
fada13e2d3
Update issue templates (#1257) 2021-03-29 18:39:08 +02:00
Mikołaj Pich
6e19eb943d
Add deploy to AppGallery github actions config (#1259) 2021-03-29 17:37:26 +02:00
Mikołaj Pich
c70fe3430c Merge branch 'release/1.1.3' into develop 2021-03-28 20:13:43 +02:00
Mikołaj Pich
3c48264539 Merge branch 'release/1.1.3' 2021-03-28 20:13:37 +02:00
Mikołaj Pich
539cf2207b Version 1.1.3 2021-03-28 20:13:32 +02:00
Rafał Borcz
f0e897713c
New Crowdin updates (#1233) 2021-03-28 19:52:38 +02:00
Mikołaj Pich
a448092008
Allow special login format in login form (#1258) 2021-03-28 19:46:56 +02:00
Patryk
f5b46707ff
Fixing README.md (#1255) 2021-03-28 15:56:44 +02:00
Rafał Borcz
e6247d4428
Fix clearing no existing dialog fragment (#1242) 2021-03-28 08:18:07 +02:00
Mikołaj Pich
d0869b235a
Use db student id to distinguish reporting units and recipients (#1254) 2021-03-27 13:43:25 +01:00
dependabot-preview[bot]
464900d95b
Bump annotation from 1.1.0 to 1.2.0 (#1245) 2021-03-25 10:12:05 +00:00
dependabot-preview[bot]
368274239e
Bump agconnect-crash from 1.5.0.300 to 1.5.1.200 (#1247) 2021-03-25 10:11:19 +00:00
dependabot-preview[bot]
ee33197494
Bump room from 2.3.0-beta03 to 2.3.0-rc01 (#1246) 2021-03-25 10:09:21 +00:00
dependabot-preview[bot]
d3ea743707
Bump kotlin_version from 1.4.31 to 1.4.32 (#1253) 2021-03-25 10:07:43 +00:00
dependabot-preview[bot]
976d4b8ce2
Bump fragment-ktx from 1.3.1 to 1.3.2 (#1248) 2021-03-25 11:05:14 +01:00
dependabot-preview[bot]
b77fc0d32a
Bump activity-ktx from 1.2.1 to 1.2.2 (#1249) 2021-03-25 11:04:37 +01:00
dependabot-preview[bot]
bd3716609e
Bump hianalytics from 5.2.0.300 to 5.2.0.301 (#1250) 2021-03-25 11:04:04 +01:00
dependabot-preview[bot]
5b87cc9009
Bump agcp from 1.5.0.300 to 1.5.1.200 (#1251) 2021-03-25 11:03:37 +01:00
dependabot-preview[bot]
4f7be8d2cb
Bump lifecycle-livedata-ktx from 2.3.0 to 2.3.1 (#1252) 2021-03-25 11:02:39 +01:00
Rafał Borcz
8733e7782f
Fix colorPrimary and class name in widget account manager (#1241) 2021-03-21 22:37:34 +01:00
Rafał Borcz
e03b0dfa01
Fix missing avatars in widgets (#1238) 2021-03-21 12:04:55 +01:00
Rafał Borcz
efafd2094a
Add dialog with info about dropping support for android 4 (#1221) 2021-03-20 14:01:17 +01:00
Rafał Borcz
1560335749
Fix very rare crash in login recovery (#1231) 2021-03-20 13:27:47 +01:00
Rafał Borcz
5bee155f1e
Remove listenablefuture from dependencies (#1237) 2021-03-20 12:10:53 +00:00
dependabot-preview[bot]
c9dc9a323f
Bump gradle from 4.1.2 to 4.1.3 (#1234) 2021-03-19 15:02:28 +00:00
MRmlik12
87e7e00705
Remove firebase inappmessage dependency (#1235) 2021-03-19 15:57:12 +01:00
dependabot-preview[bot]
57681b35ea
Bump mockk from 1.10.6 to 1.11.0 (#1229) 2021-03-17 22:58:17 +00:00
Mikołaj Pich
8fb09d7b7d Merge branch 'release/1.1.2' into develop 2021-03-16 12:59:00 +01:00
Mikołaj Pich
168f750863 Merge branch 'release/1.1.2' 2021-03-16 12:58:56 +01:00
Mikołaj Pich
3e1acbd3bf Version 1.1.2 2021-03-16 12:58:52 +01:00
Rafał Borcz
21ef2adcf6
Disable optimization in r8 config and fix crash in grade fragment (#1226) 2021-03-16 11:49:17 +00:00
Mikołaj Pich
3f6159e976
Fix show error details button in additional lessons (#1225) 2021-03-16 12:47:51 +01:00
Mikołaj Pich
555b5ec112 Merge branch 'release/1.1.1' into develop 2021-03-16 00:43:39 +01:00
Mikołaj Pich
60a9bcae46 Merge branch 'release/1.1.1' 2021-03-16 00:43:33 +01:00
Mikołaj Pich
eeb1341c1f Version 1.1.1 2021-03-16 00:43:28 +01:00
Rafał Borcz
c77b50d51b
New Crowdin updates (#1204) 2021-03-16 00:30:28 +01:00
Rafał Borcz
8644ce32d5
Fix semester switch when student have only one semester (#1215) 2021-03-15 23:58:50 +01:00
Mikołaj Pich
94506aca52
Add github actions config to deploy apk to App Center (#1220) 2021-03-15 18:18:08 +01:00
Rafał Borcz
eee4e1f4b5
Fix empty view in attendance (#1217) 2021-03-15 00:33:40 +01:00
Rafał Borcz
c1942d012f
Maybe fix fragment commits after activity state is saved (#1216) 2021-03-13 20:15:12 +01:00
Rafał Borcz
fe846b463a
Update material chips input (#1214) 2021-03-13 20:14:36 +01:00
Rafał Borcz
0ea2e68249
Fix and clean proguard/r8 file (#1213) 2021-03-13 20:14:10 +01:00
Kamil Studziński
be0445b227
Change the absence request confirmation message string (#1212) 2021-03-13 20:13:57 +01:00
Rafał Borcz
48249f3093
Update kotlin coroutines (#1211) 2021-03-13 20:13:48 +01:00
Rafał Borcz
8d7110735d
Ignore no current student during avatar loading (#1210) 2021-03-13 20:13:37 +01:00
dependabot-preview[bot]
94957850c3
Bump fragment-ktx from 1.3.0 to 1.3.1 (#1205) 2021-03-12 21:50:59 +00:00
dependabot-preview[bot]
fa2cfc8427
Bump room from 2.3.0-beta02 to 2.3.0-beta03 (#1207) 2021-03-12 21:33:30 +00:00
Rafał Borcz
3d467c43ba
Use new kotlin compiler backend (#1202) 2021-03-12 22:07:27 +01:00
dependabot-preview[bot]
b76032044d
Bump activity-ktx from 1.2.0 to 1.2.1 (#1206) 2021-03-12 21:06:33 +00:00
dependabot-preview[bot]
495b84204c
Bump work_hilt from 1.0.0-alpha03 to 1.0.0-beta01 (#1208) 2021-03-12 21:06:27 +00:00
dependabot-preview[bot]
ea4b299de6
Bump firebase-bom from 26.6.0 to 26.7.0 (#1209) 2021-03-12 12:39:01 +00:00
Damian Czupryn
acb5e2afd4
Replace dash mark with no data string in SchoolFragment (#1203) 2021-03-09 17:49:24 +01:00
Mikołaj Pich
50863d6ac2 Merge branch 'release/1.1.0' into develop 2021-03-07 21:58:30 +01:00
Mikołaj Pich
e15eb03299 Merge branch 'release/1.1.0' 2021-03-07 21:58:23 +01:00
Mikołaj Pich
be48791d51 Version 1.1.0 2021-03-07 21:58:14 +01:00
Rafał Borcz
c0e1a5b401
New Crowdin updates (#1167) 2021-03-07 20:48:29 +00:00
Kamil Studziński
cb1b467a21
Add studzinskik to contributors (#1198) 2021-03-07 20:31:14 +00:00
Mikołaj Pich
f14346ff32
Fix duplicate items after running automatic and manual sync at the same time (#1197) 2021-03-07 20:47:18 +01:00
MRmlik12
af8108a649
Add lucky number history (#1184) 2021-03-07 20:17:03 +01:00
Damian Czupryn
5743928126
Fix notification and status bars colors (#1196) 2021-03-07 14:04:37 +00:00
Rafał Borcz
388d37bf9c
Fix date picker theme (#1194) 2021-03-07 13:41:54 +01:00
Damian Czupryn
d572fc737f
Fix typo (#1193) 2021-03-07 00:07:57 +01:00
Damian Czupryn
47b0f1b527
Settings revamp (#1160) 2021-03-06 17:18:42 +00:00
Rafał Borcz
1afa7ecf3c
Fix OOM in grade statistics (#1192) 2021-03-06 16:50:06 +01:00
Mikołaj Pich
9139febbdf
Migrate database migrations from androidTest to roboelectric (#1191) 2021-03-06 14:34:07 +00:00
dependabot-preview[bot]
2dd0b56333
Bump agconnect-crash from 1.5.0.200 to 1.5.0.300 (#1190) 2021-03-06 12:08:43 +00:00
Rafał Borcz
3b970209a5
Fix grade fragment subtitle (#1185) 2021-03-06 13:01:41 +01:00
Rafał Borcz
6f590eb194
Fix empty license dialogs (#1182) 2021-03-06 13:01:17 +01:00
dependabot-preview[bot]
b20b8fb243
Bump firebase-bom from 26.5.0 to 26.6.0 (#1189) 2021-03-06 11:23:16 +00:00
dependabot-preview[bot]
7e4a212951
Bump agcp from 1.5.0.200 to 1.5.0.300 (#1187) 2021-03-06 10:55:37 +00:00
Kamil Studziński
6dfeed3a26
Fix API host key capitalisation for powiat krasnostawski (#1181) 2021-03-04 20:32:17 +00:00
Kamil Studziński
06a27199ee
Add early validation for special mail domains (#1000) (#1176) 2021-03-03 22:37:58 +01:00
Rafał Borcz
76039e5eb9
Remove hardcoded strings (#1177) 2021-03-03 20:18:03 +01:00
Kamil Studziński
6a4aaff8d6
Fix no system theme option in Czech and Slovak (#1178) 2021-03-03 19:16:46 +00:00
Rafał Borcz
9e2985864a
Add avatars (#1146) 2021-03-02 23:34:25 +00:00
Rafał Borcz
412057b512
Remove deprecations (#1170) 2021-03-02 17:28:47 +01:00
dependabot-preview[bot]
963caadced
Bump firebase-crashlytics-gradle from 2.5.0 to 2.5.1 (#1171) 2021-03-01 22:19:31 +00:00
Rafał Borcz
8388a8a5fc
Fix calling of binding outside lifecycle (#1169) 2021-03-01 21:57:47 +00:00
Rafał Borcz
a801c8f8be
Add exception ignoring to UpdateHelper when PendingIntent is duplicated (#1168) 2021-03-01 21:35:49 +00:00
dependabot-preview[bot]
9d8ad73e63
Bump hilt_version from 2.32-alpha to 2.33-beta (#1163)
* Bump hilt_version from 2.32-alpha to 2.33-beta

Bumps `hilt_version` from 2.32-alpha to 2.33-beta.

Updates `hilt-android-gradle-plugin` from 2.32-alpha to 2.33-beta
- [Release notes](https://github.com/google/dagger/releases)
- [Changelog](https://github.com/google/dagger/blob/master/CHANGELOG.md)
- [Commits](https://github.com/google/dagger/commits)

Updates `hilt-android` from 2.32-alpha to 2.33-beta
- [Release notes](https://github.com/google/dagger/releases)
- [Changelog](https://github.com/google/dagger/blob/master/CHANGELOG.md)
- [Commits](https://github.com/google/dagger/commits)

Updates `hilt-android-compiler` from 2.32-alpha to 2.33-beta
- [Release notes](https://github.com/google/dagger/releases)
- [Changelog](https://github.com/google/dagger/blob/master/CHANGELOG.md)
- [Commits](https://github.com/google/dagger/commits)

Signed-off-by: dependabot-preview[bot] <support@dependabot.com>

* Add inject before super.onCreate() in activity

* Fix format

Co-authored-by: dependabot-preview[bot] <27856297+dependabot-preview[bot]@users.noreply.github.com>
Co-authored-by: Rafał Borcz <RafalBO99@outlook.com>
2021-02-27 22:49:50 +01:00
dependabot-preview[bot]
182f6c8a81
Bump kotlin_version from 1.4.30 to 1.4.31 (#1166) 2021-02-26 19:21:02 +00:00
dependabot-preview[bot]
1e4a3536cf
Bump desugar_jdk_libs from 1.1.1 to 1.1.5 (#1164) 2021-02-26 18:50:58 +00:00
dependabot-preview[bot]
169a314664
Bump about_libraries from 8.8.2 to 8.8.3 (#1165) 2021-02-26 18:49:43 +00:00
dependabot-preview[bot]
904eed648b
Bump hianalytics from 5.1.0.301 to 5.2.0.300 (#1161) 2021-02-24 23:00:00 +00:00
dependabot-preview[bot]
3bb94adece
Bump room from 2.3.0-beta01 to 2.3.0-beta02 (#1158) 2021-02-22 23:07:37 +00:00
Damian Czupryn
105b70fcad
Add Daxxxis to contributors (#1156) 2021-02-18 21:25:46 +01:00
Damian Czupryn
b4bf7c7589
Add Slovak to dialog (#1154) 2021-02-18 00:05:40 +01:00
Damian Czupryn
ff425d6d2b
Change background color of navigation and notification bars (#1120) 2021-02-18 00:05:27 +01:00
dependabot-preview[bot]
4fceb854b3
Bump activity-ktx from 1.1.0 to 1.2.0 (#1134) 2021-02-17 12:08:10 +00:00
dependabot-preview[bot]
3adac154b4
Bump firebase-crashlytics-gradle from 2.4.1 to 2.5.0 (#1147) 2021-02-17 11:55:27 +00:00
dependabot-preview[bot]
a320cf8f7c
Bump fragment-ktx from 1.2.5 to 1.3.0 (#1148) 2021-02-17 11:39:26 +00:00
dependabot-preview[bot]
1ed0884dfd
Bump hilt_version from 2.31.2-alpha to 2.32-alpha (#1133) 2021-02-17 11:38:51 +00:00
dependabot-preview[bot]
021e9726c6
Bump lifecycle-livedata-ktx from 2.2.0 to 2.3.0 (#1136) 2021-02-17 11:38:33 +00:00
dependabot-preview[bot]
3c438757e3
Bump firebase-bom from 26.4.0 to 26.5.0 (#1151) 2021-02-17 11:31:05 +00:00
Faierbel
99c4a65df5 Merge tag '1.0.1' into develop
Version 1.0.1
2021-02-16 12:46:54 +01:00
499 changed files with 26441 additions and 3419 deletions

View file

@ -1,3 +1,12 @@
---
name: Bug report
about: Utwórz raport błędu, aby pomóc nam ulepszyć Wulkanowego
title: ''
labels: ''
assignees: ''
---
## Co powinno się dziać

View file

@ -0,0 +1,20 @@
---
name: Feature request
about: Zaproponuj nowy pomysł dla Wulkanowego
title: ''
labels: ''
assignees: ''
---
** Czy Twoja prośba o funkcję jest związana z problemem? Proszę opisz.**
Jasny i zwięzły opis problemu. Np. Zawsze jestem sfrustrowany, gdy [...]
** Opisz żądane rozwiązanie **
Jasny i zwięzły opis tego, co chcesz, aby się wydarzyło.
** Opisz alternatywy, które rozważałeś **
Jasny i zwięzły opis wszelkich rozważanych alternatywnych rozwiązań lub funkcji.
** Dodatkowy kontekst **
Dodaj inny kontekst lub zrzuty ekranu dotyczące żądania funkcji tutaj.

12
.github/dependabot.yml vendored Normal file
View file

@ -0,0 +1,12 @@
version: 2
updates:
- package-ecosystem: gradle
directory: "/"
schedule:
interval: weekly
open-pull-requests-limit: 10
target-branch: develop
ignore:
- dependency-name: io.github.wulkanowy:sdk
reviewers:
- Faierbel

74
.github/workflows/deploy-store.yml vendored Normal file
View file

@ -0,0 +1,74 @@
name: Deploy to app stores
on:
release:
types: [ created ]
jobs:
deploy-google-play:
name: Deploy to google play
runs-on: ubuntu-latest
timeout-minutes: 10
environment: google-play
steps:
- uses: actions/checkout@v2
- uses: actions/setup-java@v1
with:
java-version: 11
- uses: actions/cache@v2
with:
path: |
~/.gradle/caches
~/.gradle/wrapper
key: gradle-${{ runner.os }}-${{ hashFiles('**/*.gradle*') }}
- name: Decrypt keys
env:
ENCRYPT_KEY: ${{ secrets.ENCRYPT_KEY }}
SERVICES_ENCRYPT_KEY: ${{ secrets.SERVICES_ENCRYPT_KEY }}
run: |
gpg --yes --batch --passphrase=$SERVICES_ENCRYPT_KEY ./app/src/release/google-services.json.gpg
gpg --yes --batch --passphrase=$ENCRYPT_KEY ./app/key.p12.gpg
gpg --yes --batch --passphrase=$ENCRYPT_KEY ./app/upload-key.jks.gpg
- name: Upload apk to google play
env:
PLAY_KEY_ALIAS: ${{ secrets.PLAY_KEY_ALIAS }}
PLAY_KEY_PASSWORD: ${{ secrets.PLAY_KEY_PASSWORD }}
PLAY_SERVICE_ACCOUNT_EMAIL: ${{ secrets.PLAY_SERVICE_ACCOUNT_EMAIL }}
PLAY_STORE_PASSWORD: ${{ secrets.PLAY_STORE_PASSWORD }}
run: ./gradlew publishPlayRelease -PenableFirebase --stacktrace;
deploy-app-gallery:
name: Deploy to AppGallery
runs-on: ubuntu-latest
timeout-minutes: 10
environment: app-gallery
steps:
- uses: actions/checkout@v2
- uses: actions/setup-java@v1
with:
java-version: 11
- uses: actions/cache@v2
with:
path: |
~/.gradle/caches
~/.gradle/wrapper
key: gradle-${{ runner.os }}-${{ hashFiles('**/*.gradle*') }}
- name: Decrypt keys
env:
ENCRYPT_KEY: ${{ secrets.ENCRYPT_KEY }}
SERVICES_ENCRYPT_KEY: ${{ secrets.SERVICES_ENCRYPT_KEY }}
run: |
gpg --yes --batch --passphrase=$SERVICES_ENCRYPT_KEY ./app/src/release/agconnect-services.json.gpg
gpg --yes --batch --passphrase=$ENCRYPT_KEY ./app/key.p12.gpg
gpg --yes --batch --passphrase=$ENCRYPT_KEY ./app/upload-key.jks.gpg
- name: Prepare credentials
env:
AGC_CREDENTIALS: ${{ secrets.AGC_CREDENTIALS }}
run: echo $AGC_CREDENTIALS > ./app/src/release/agconnect-credentials.json
- name: Build and publish HMS version
env:
PLAY_KEY_ALIAS: ${{ secrets.PLAY_KEY_ALIAS }}
PLAY_KEY_PASSWORD: ${{ secrets.PLAY_KEY_PASSWORD }}
PLAY_STORE_PASSWORD: ${{ secrets.PLAY_STORE_PASSWORD }}
run: ./gradlew assembleHmsRelease --stacktrace && ./gradlew publishHuaweiAppGalleryHmsRelease --stacktrace

144
.github/workflows/deploy-test.yml vendored Normal file
View file

@ -0,0 +1,144 @@
name: Deploy to app tests
on:
push:
# branches: [ develop ]
branches: [ '!*' ]
pull_request_target:
# branches: [ develop ]
branches: [ '!*' ]
workflow_dispatch:
jobs:
deploy-appcenter:
name: App Center
runs-on: ubuntu-latest
timeout-minutes: 10
environment: app-center
steps:
- uses: actions/checkout@v2
- uses: actions/setup-java@v1
with:
java-version: 11
- uses: actions/cache@v2
with:
path: |
~/.gradle/caches
~/.gradle/wrapper
key: gradle-${{ runner.os }}-${{ hashFiles('**/*.gradle*') }}
- name: Set run number with offset
env:
BUILD_NUMBER_OFFSET: ${{ secrets.BUILD_NUMBER_OFFSET }}
run: echo "RUN_NUMBER=$((GITHUB_RUN_NUMBER+BUILD_NUMBER_OFFSET))" >> $GITHUB_ENV
- name: Prepare build configuration
run: |
sed -i -e "s#applicationIdSuffix \".dev\"#applicationIdSuffix \".${GITHUB_HEAD_REF//[-.\/]/_}\"#" app/build.gradle
sed -i -e "s#.dev\"#.${GITHUB_HEAD_REF//[-.\/]/_}\"#" app/src/debug/google-services.json
sed -i -e "s#.dev\"#.${GITHUB_HEAD_REF//[-.\/]/_}\"#" app/src/debug/agconnect-services.json
sed -i -e '/versionNameSuffix/d' app/build.gradle
- name: Add signing config
run: |
cat >> app/build.gradle <<EOF
android.signingConfigs.debug {
storeFile file("bitrise.jks")
storePassword System.getenv("BITRISE_KEYSTORE_PASSWORD")
keyAlias System.getenv("BITRISE_KEY_ALIAS")
keyPassword System.getenv("BITRISE_KEY_PASSWORD")
}
EOF
- name: Decrypt keys
env:
BITRISE_ENCRYPT_KEY: ${{ secrets.BITRISE_ENCRYPT_KEY }}
run: |
gpg --yes --batch --passphrase=$BITRISE_ENCRYPT_KEY ./app/bitrise.jks.gpg
- name: Bump version
uses: chkfung/android-version-actions@v1.1
with:
gradlePath: app/build.gradle
versionCode: ${{ env.RUN_NUMBER }}
versionName: ${{ env.RUN_NUMBER }}-${{ github.head_ref }}
- name: Build apk
env:
BITRISE_KEYSTORE_PASSWORD: ${{ secrets.BITRISE_KEYSTORE_PASSWORD }}
BITRISE_KEY_ALIAS: ${{ secrets.BITRISE_KEY_ALIAS }}
BITRISE_KEY_PASSWORD: ${{ secrets.BITRISE_KEY_PASSWORD }}
run: ./gradlew assembleFdroidDebug --stacktrace
- name: Upload apk to github artifacts
uses: actions/upload-artifact@v2
with:
name: wulkanowyDEV-${{ env.RUN_NUMBER }}.apk
path: app/build/outputs/apk/fdroid/debug/app-fdroid-debug.apk
- name: Deploy to app center
uses: wzieba/AppCenter-Github-Action@v1
with:
appName: wulkanowy/wulkanowy
token: ${{ secrets.APP_CENTER_TOKEN }}
group: Testers
file: app/build/outputs/apk/fdroid/debug/app-fdroid-debug.apk
notifyTesters: true
debug: true
deploy-app-distribution:
name: App Distribution
runs-on: ubuntu-latest
timeout-minutes: 10
environment: app-distribution
if: github.event_name != 'pull_request_target'
steps:
- uses: actions/checkout@v2
- uses: actions/setup-java@v1
with:
java-version: 11
- uses: actions/cache@v2
with:
path: |
~/.gradle/caches
~/.gradle/wrapper
key: gradle-${{ runner.os }}-${{ hashFiles('**/*.gradle*') }}
- name: Set run number with offset
env:
BUILD_NUMBER_OFFSET: ${{ secrets.BUILD_NUMBER_OFFSET }}
run: echo "RUN_NUMBER=$((GITHUB_RUN_NUMBER+BUILD_NUMBER_OFFSET))" >> $GITHUB_ENV
- name: Add signing config
run: |
cat >> app/build.gradle <<EOF
android.signingConfigs.debug {
storeFile file("bitrise.jks")
storePassword System.getenv("BITRISE_KEYSTORE_PASSWORD")
keyAlias System.getenv("BITRISE_KEY_ALIAS")
keyPassword System.getenv("BITRISE_KEY_PASSWORD")
}
EOF
- name: Decrypt keys
env:
BITRISE_ENCRYPT_KEY: ${{ secrets.BITRISE_ENCRYPT_KEY }}
BITRISE_SERVICES_ENCRYPT_KEY: ${{ secrets.BITRISE_SERVICES_ENCRYPT_KEY }}
run: |
gpg --yes --batch --passphrase=$BITRISE_SERVICES_ENCRYPT_KEY ./app/src/debug/google-services.json.gpg
gpg --yes --batch --passphrase=$BITRISE_ENCRYPT_KEY ./app/bitrise.jks.gpg
- name: Bump version
uses: chkfung/android-version-actions@v1.1
with:
gradlePath: app/build.gradle
versionCode: ${{ env.RUN_NUMBER }}
versionName: ${{ env.RUN_NUMBER }}
- name: Build apk
env:
BITRISE_KEYSTORE_PASSWORD: ${{ secrets.BITRISE_KEYSTORE_PASSWORD }}
BITRISE_KEY_ALIAS: ${{ secrets.BITRISE_KEY_ALIAS }}
BITRISE_KEY_PASSWORD: ${{ secrets.BITRISE_KEY_PASSWORD }}
run: ./gradlew assemblePlayDebug -PenableFirebase --stacktrace
- name: Upload apk to github artifacts
uses: actions/upload-artifact@v2
with:
name: wulkanowyDEV-${{ env.RUN_NUMBER }}-dev.apk
path: app/build/outputs/apk/play/debug/app-play-debug.apk
- name: Deploy to app distribution
uses: wzieba/Firebase-Distribution-Github-Action@v1
with:
appId: ${{ secrets.FIREBASE_APP_ID }}
token: ${{ secrets.FIREBASE_TOKEN }}
groups: discord
file: app/build/outputs/apk/play/debug/app-play-debug.apk

View file

@ -1,48 +1,21 @@
name: Test and deploy
name: Tests
on:
push:
branches: [ develop ]
branches: [ master, develop ]
tags: [ '*' ]
pull_request:
branches: [ develop ]
workflow_dispatch:
branches: [ master, develop ]
jobs:
build:
name: Pre-build
runs-on: ubuntu-latest
timeout-minutes: 10
steps:
- uses: fkirc/skip-duplicate-actions@master
- uses: actions/checkout@v2
- uses: gradle/wrapper-validation-action@v1
- uses: actions/setup-java@v1
with:
java-version: 11
- uses: actions/cache@v2
with:
path: |
~/.gradle/caches
~/.gradle/wrapper
key: gradle-${{ runner.os }}-${{ hashFiles('**/*.gradle*') }}
- name: Build
run: ./gradlew --build-cache compileFdroidDebugUnitTestKotlin preFdroidDebugAndroidTestBuild dexBuilderFdroidDebugAndroidTest packageFdroidDebug packageFdroidDebugAndroidTest
- name: Prepare build cache
run: tar -cf prebuild.tar .build-cache .gradle app/build
- uses: actions/upload-artifact@v2
with:
name: prebuild.tar
path: prebuild.tar
unit-tests:
name: Unit tests
runs-on: ubuntu-latest
timeout-minutes: 10
needs: [ build ]
steps:
- uses: fkirc/skip-duplicate-actions@master
- uses: actions/checkout@v2
- uses: gradle/wrapper-validation-action@v1
- uses: actions/setup-java@v1
with:
java-version: 11
@ -52,91 +25,10 @@ jobs:
~/.gradle/caches
~/.gradle/wrapper
key: gradle-${{ runner.os }}-${{ hashFiles('**/*.gradle*') }}
- uses: actions/download-artifact@v2
with:
name: prebuild.tar
- name: Extract build cache
run: tar -xf prebuild.tar
- name: Unit tests
run: |
./gradlew --build-cache -Pcoverage testFdroidDebugUnitTest --stacktrace
./gradlew --build-cache -Pcoverage jacocoTestReport --stacktrace
./gradlew testFdroidDebugUnitTest --stacktrace
./gradlew jacocoTestReport --stacktrace
- uses: codecov/codecov-action@v1
with:
flags: unit
instrumentation-tests:
name: Instrumentation tests
runs-on: macOS-latest
timeout-minutes: 15
needs: [ build ]
strategy:
fail-fast: true
matrix:
api-level: [21, 29]
steps:
- uses: actions/checkout@v2
- uses: actions/setup-java@v1
with:
java-version: 11
- uses: actions/cache@v2
with:
path: |
~/.gradle/caches
~/.gradle/wrapper
key: gradle-${{ runner.os }}-${{ hashFiles('**/*.gradle*') }}
- uses: actions/download-artifact@v2
with:
name: prebuild.tar
- name: Extract build cache
run: tar -xf prebuild.tar
- name: Instrumentation tests
uses: reactivecircus/android-emulator-runner@v2
with:
api-level: ${{ matrix.api-level }}
arch: x86
script: |
./gradlew --build-cache -Pcoverage connectedFdroidDebugAndroidTest --stacktrace
./gradlew --build-cache -Pcoverage jacocoTestReport --stacktrace
- uses: codecov/codecov-action@v1
with:
flags: instrumented,api-${{ matrix.api-level }}
deploy-google-play:
name: Deploy to google play
runs-on: ubuntu-latest
timeout-minutes: 10
environment: google-play
needs: [ build, unit-tests, instrumentation-tests ]
if: github.event_name == 'push' && contains(github.ref, 'refs/tags/')
steps:
- uses: actions/checkout@v2
- uses: actions/setup-java@v1
with:
java-version: 11
- uses: actions/cache@v2
with:
path: |
~/.gradle/caches
~/.gradle/wrapper
key: gradle-${{ runner.os }}-${{ hashFiles('**/*.gradle*') }}
- uses: actions/download-artifact@v2
with:
name: prebuild.tar
- name: Extract build cache
run: tar -xf prebuild.tar
- name: Decrypt keys
env:
ENCRYPT_KEY: ${{ secrets.ENCRYPT_KEY }}
SERVICES_ENCRYPT_KEY: ${{ secrets.SERVICES_ENCRYPT_KEY }}
run: |
gpg --yes --batch --passphrase=$SERVICES_ENCRYPT_KEY ./app/src/release/google-services.json.gpg
gpg --yes --batch --passphrase=$ENCRYPT_KEY ./app/key.p12.gpg
gpg --yes --batch --passphrase=$ENCRYPT_KEY ./app/upload-key.jks.gpg
- name: Upload apk to google play
env:
PLAY_KEY_ALIAS: ${{ secrets.PLAY_KEY_ALIAS }}
PLAY_KEY_PASSWORD: ${{ secrets.PLAY_KEY_PASSWORD }}
PLAY_SERVICE_ACCOUNT_EMAIL: ${{ secrets.PLAY_SERVICE_ACCOUNT_EMAIL }}
PLAY_STORE_PASSWORD: ${{ secrets.PLAY_STORE_PASSWORD }}
run: ./gradlew publishPlayRelease -PenableFirebase --stacktrace;

2
.gitignore vendored
View file

@ -117,3 +117,5 @@ Thumbs.db
app/src/release/agconnect-services.json
app/src/release/agconnect-credentials.json
.idea/deploymentTargetDropDown.xml

View file

@ -7,15 +7,6 @@
<package name="kotlinx.android.synthetic" alias="false" withSubpackages="true" />
</value>
</option>
<option name="PACKAGES_IMPORT_LAYOUT">
<value>
<package name="" alias="false" withSubpackages="true" />
<package name="java" alias="false" withSubpackages="true" />
<package name="javax" alias="false" withSubpackages="true" />
<package name="kotlin" alias="false" withSubpackages="true" />
<package name="" alias="true" withSubpackages="true" />
</value>
</option>
<option name="NAME_COUNT_TO_USE_STAR_IMPORT" value="2147483647" />
<option name="NAME_COUNT_TO_USE_STAR_IMPORT_FOR_MEMBERS" value="2147483647" />
<option name="WRAP_ELVIS_EXPRESSIONS" value="0" />

View file

@ -2,7 +2,7 @@
# Wulkanowy
[![GitHub Workflow Status](https://img.shields.io/github/workflow/status/wulkanowy/wulkanowy/Test%20and%20deploy/develop?style=flat-square)](https://github.com/wulkanowy/wulkanowy/actions)
[![GitHub Workflow Status](https://img.shields.io/github/workflow/status/wulkanowy/wulkanowy/Tests/develop?style=flat-square)](https://github.com/wulkanowy/wulkanowy/actions)
[![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/)

View file

@ -2,7 +2,7 @@
# Wulkanowy
[![GitHub Workflow Status](https://img.shields.io/github/workflow/status/wulkanowy/wulkanowy/Test%20and%20deploy/develop?style=flat-square)](https://github.com/wulkanowy/wulkanowy/actions)
[![GitHub Workflow Status](https://img.shields.io/github/workflow/status/wulkanowy/wulkanowy/Tests/develop?style=flat-square)](https://github.com/wulkanowy/wulkanowy/actions)
[![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/)
@ -32,7 +32,7 @@ Nieoficjalny klient dziennika VULCAN UONET+ dla ucznia i rodzica
* powiadomienia np. o nowej ocenie
* obsługa wielu kont wraz z możliwością zmiany nazwy ucznia
* ciemny i czarny (AMOLED) motyw
* tryb offilne
* tryb offline
* brak reklam
## Pobierz

BIN
app/bitrise.jks.gpg Normal file

Binary file not shown.

View file

@ -1,26 +1,28 @@
apply plugin: 'com.android.application'
apply plugin: 'kotlin-android'
apply plugin: 'kotlin-parcelize'
apply plugin: 'kotlin-kapt'
apply plugin: 'dagger.hilt.android.plugin'
apply plugin: 'com.google.gms.google-services'
apply plugin: 'com.google.firebase.crashlytics'
apply plugin: 'com.github.triplet.play'
apply plugin: 'ru.cian.huawei-publish'
apply plugin: 'com.mikepenz.aboutlibraries.plugin'
apply plugin: 'com.huawei.agconnect'
apply from: 'jacoco.gradle'
apply from: 'sonarqube.gradle'
apply from: 'hooks.gradle'
android {
compileSdkVersion 30
buildToolsVersion '30.0.3'
defaultConfig {
applicationId "io.github.wulkanowy"
testApplicationId "io.github.tests.wulkanowy"
minSdkVersion 17
minSdkVersion 21
targetSdkVersion 30
versionCode 85
versionName "1.0.1"
multiDexEnabled true
versionCode 94
versionName "1.2.1"
testInstrumentationRunner "androidx.test.runner.AndroidJUnitRunner"
vectorDrawables.useSupportLibrary = true
@ -41,7 +43,8 @@ android {
}
sourceSets {
androidTest.assets.srcDirs += files("$projectDir/schemas".toString())
// https://github.com/robolectric/robolectric/issues/3928#issuecomment-395309991
debug.assets.srcDirs += files("$projectDir/schemas".toString())
}
signingConfigs {
@ -64,7 +67,6 @@ android {
resValue "string", "app_name", "Wulkanowy DEV " + defaultConfig.versionCode
applicationIdSuffix ".dev"
versionNameSuffix "-dev"
testCoverageEnabled = project.hasProperty('coverage')
ext.enableCrashlytics = project.hasProperty("enableFirebase")
}
}
@ -74,7 +76,6 @@ android {
productFlavors {
hms {
dimension "platform"
minSdkVersion 19
manifestPlaceholders = [
install_channel: "AppGallery"
]
@ -96,21 +97,21 @@ android {
}
buildFeatures {
viewBinding = true
viewBinding true
}
lintOptions {
disable 'HardwareIds'
testOptions.unitTests {
includeAndroidResources = true
}
compileOptions {
coreLibraryDesugaringEnabled true
sourceCompatibility JavaVersion.VERSION_1_8
targetCompatibility JavaVersion.VERSION_1_8
sourceCompatibility JavaVersion.VERSION_11
targetCompatibility JavaVersion.VERSION_11
}
kotlinOptions {
jvmTarget = "1.8"
jvmTarget = "11"
freeCompilerArgs += ["-Xopt-in=kotlin.RequiresOptIn", "-Xjvm-default=all"]
}
@ -124,53 +125,66 @@ android {
}
}
kapt {
correctErrorTypes true
}
play {
serviceAccountEmail = System.getenv("PLAY_SERVICE_ACCOUNT_EMAIL") ?: "jan@fakelog.cf"
serviceAccountCredentials = file('key.p12')
defaultToAppBundles = false
track = 'alpha'
track = 'production'
updatePriority = 3
}
huaweiPublish {
instances {
hmsRelease {
credentialsPath = "$rootDir/app/src/release/agconnect-credentials.json"
buildFormat = "apk"
deployType = "draft"
}
}
}
ext {
work_manager = "2.5.0"
work_hilt = "1.0.0-alpha03"
room = "2.3.0-beta01"
chucker = "3.4.0"
mockk = "1.10.6"
moshi = "1.11.0"
android_hilt = "1.0.0"
room = "2.3.0"
chucker = "3.5.2"
mockk = "1.12.0"
moshi = "1.12.0"
}
dependencies {
implementation "io.github.wulkanowy:sdk:1.0.1"
implementation "io.github.wulkanowy:sdk:1.2.1"
coreLibraryDesugaring 'com.android.tools:desugar_jdk_libs:1.1.1'
coreLibraryDesugaring 'com.android.tools:desugar_jdk_libs:1.1.5'
implementation "org.jetbrains.kotlin:kotlin-stdlib-jdk8:$kotlin_version"
implementation 'org.jetbrains.kotlinx:kotlinx-coroutines-android:1.4.2'
implementation "org.jetbrains.kotlinx:kotlinx-coroutines-android:1.5.2"
implementation "androidx.core:core-ktx:1.3.2"
implementation "androidx.activity:activity-ktx:1.1.0"
implementation "androidx.appcompat:appcompat:1.2.0"
implementation "androidx.appcompat:appcompat-resources:1.2.0"
implementation "androidx.fragment:fragment-ktx:1.2.5"
implementation "androidx.annotation:annotation:1.1.0"
implementation "androidx.multidex:multidex:2.0.1"
implementation "androidx.core:core-ktx:1.6.0"
implementation "androidx.activity:activity-ktx:1.3.1"
implementation "androidx.appcompat:appcompat:1.3.1"
implementation "androidx.appcompat:appcompat-resources:1.3.1"
implementation "androidx.fragment:fragment-ktx:1.3.6"
implementation "androidx.annotation:annotation:1.2.0"
implementation "androidx.preference:preference-ktx:1.1.1"
implementation "androidx.recyclerview:recyclerview:1.1.0"
implementation "androidx.recyclerview:recyclerview:1.2.1"
implementation "androidx.viewpager:viewpager:1.0.0"
implementation "androidx.swiperefreshlayout:swiperefreshlayout:1.1.0"
implementation "androidx.constraintlayout:constraintlayout:2.0.4"
implementation "androidx.constraintlayout:constraintlayout:2.1.0"
implementation "androidx.coordinatorlayout:coordinatorlayout:1.1.0"
implementation "com.google.android.material:material:1.3.0"
implementation "com.github.wulkanowy:material-chips-input:2.1.1"
implementation "com.google.android.material:material:1.4.0"
implementation "com.github.wulkanowy:material-chips-input:2.2.0"
implementation "com.github.PhilJay:MPAndroidChart:v3.1.0"
implementation 'com.github.lopspower:CircularImageView:4.2.0'
implementation "androidx.work:work-runtime-ktx:$work_manager"
playImplementation "androidx.work:work-gcm:$work_manager"
implementation "androidx.lifecycle:lifecycle-livedata-ktx:2.2.0"
implementation "androidx.lifecycle:lifecycle-livedata-ktx:2.3.1"
implementation "androidx.room:room-runtime:$room"
implementation "androidx.room:room-ktx:$room"
@ -178,54 +192,56 @@ dependencies {
implementation "com.google.dagger:hilt-android:$hilt_version"
kapt "com.google.dagger:hilt-android-compiler:$hilt_version"
implementation "androidx.hilt:hilt-work:$work_hilt"
kapt "androidx.hilt:hilt-compiler:$work_hilt"
kapt "androidx.hilt:hilt-compiler:$android_hilt"
implementation "androidx.hilt:hilt-work:$android_hilt"
implementation "com.aurelhubert:ahbottomnavigation:2.3.4"
implementation "com.ncapdevi:frag-nav:3.3.0"
implementation 'com.github.ncapdevi:FragNav:3.3.0'
implementation "com.github.YarikSOffice:lingver:1.3.0"
implementation "com.squareup.moshi:moshi:$moshi"
implementation "com.squareup.moshi:moshi-adapters:$moshi"
kapt "com.squareup.moshi:moshi-kotlin-codegen:$moshi"
implementation "com.jakewharton.timber:timber:4.7.1"
implementation "com.jakewharton.timber:timber:5.0.1"
implementation "at.favre.lib:slf4j-timber:1.0.1"
implementation "fr.bipi.treessence:treessence:0.3.2"
implementation 'com.github.bastienpaulfr:Treessence:1.0.4'
implementation "com.mikepenz:aboutlibraries-core:$about_libraries"
implementation 'com.wdullaer:materialdatetimepicker:4.2.3'
implementation "io.coil-kt:coil:1.1.1"
implementation "io.coil-kt:coil:1.3.2"
implementation "io.github.wulkanowy:AppKillerManager:3.0.0"
implementation 'me.xdrop:fuzzywuzzy:1.3.1'
implementation 'com.fredporciuncula:flow-preferences:1.5.0'
playImplementation platform('com.google.firebase:firebase-bom:26.4.0')
playImplementation platform('com.google.firebase:firebase-bom:28.4.0')
playImplementation 'com.google.firebase:firebase-analytics-ktx'
playImplementation 'com.google.firebase:firebase-inappmessaging-display-ktx'
playImplementation "com.google.firebase:firebase-inappmessaging-ktx"
playImplementation 'com.google.firebase:firebase-messaging:'
playImplementation 'com.google.firebase:firebase-crashlytics:'
playImplementation 'com.google.android.play:core:1.10.1'
playImplementation 'com.google.android.play:core-ktx:1.8.1'
playImplementation 'com.google.guava:listenablefuture:9999.0-empty-to-avoid-conflict-with-guava'
hmsImplementation 'com.huawei.hms:hianalytics:5.1.0.301'
hmsImplementation 'com.huawei.agconnect:agconnect-crash:1.5.0.200'
hmsImplementation 'com.huawei.hms:hianalytics:6.2.0.301'
hmsImplementation 'com.huawei.agconnect:agconnect-crash:1.6.0.300'
releaseImplementation "com.github.ChuckerTeam.Chucker:library-no-op:$chucker"
debugImplementation "com.github.ChuckerTeam.Chucker:library:$chucker"
debugImplementation "com.amitshekhar.android:debug-db:1.0.6"
debugImplementation 'com.github.amitshekhariitbhu.Android-Debug-Database:debug-db:v1.0.6'
testImplementation "junit:junit:4.13.2"
testImplementation "io.mockk:mockk:$mockk"
testImplementation 'org.jetbrains.kotlinx:kotlinx-coroutines-test:1.4.2'
testImplementation 'org.jetbrains.kotlinx:kotlinx-coroutines-test:1.5.2'
testImplementation "org.jetbrains.kotlin:kotlin-test:$kotlin_version"
androidTestImplementation "androidx.test:core:1.3.0"
androidTestImplementation "androidx.test:runner:1.3.0"
androidTestImplementation "androidx.test.ext:junit:1.1.2"
testImplementation 'org.robolectric:robolectric:4.6.1'
testImplementation "androidx.test:runner:1.4.0"
testImplementation "androidx.test.ext:junit:1.1.3"
testImplementation "androidx.test:core:1.4.0"
testImplementation "androidx.room:room-testing:$room"
testImplementation "com.google.dagger:hilt-android-testing:$hilt_version"
kaptTest "com.google.dagger:hilt-android-compiler:$hilt_version"
androidTestImplementation "androidx.test:core:1.4.0"
androidTestImplementation "androidx.test:runner:1.4.0"
androidTestImplementation "androidx.test.ext:junit:1.1.3"
androidTestImplementation "io.mockk:mockk-android:$mockk"
androidTestImplementation "androidx.room:room-testing:$room"
androidTestImplementation "org.jetbrains.kotlin:kotlin-test:$kotlin_version"
}
apply plugin: 'com.google.gms.google-services'
apply plugin: 'com.huawei.agconnect'

View file

@ -1,8 +1,8 @@
apply plugin: "jacoco"
jacoco {
toolVersion "0.8.5"
reportsDir = file("$buildDir/reports")
toolVersion "0.8.7"
reportsDirectory.set(file("$buildDir/reports"))
}
tasks.withType(Test) {
@ -16,8 +16,8 @@ task jacocoTestReport(type: JacocoReport) {
description = "Generate Jacoco coverage reports"
reports {
xml.enabled = true
html.enabled = true
xml.required.set(true)
html.required.set(true)
}
def excludes = ['**/R.class',

View file

@ -1,33 +1,21 @@
# Optimizations
-optimizationpasses 5
-optimizations !code/simplification/arithmetic,!field/*,!class/merging/*
-dontusemixedcaseclassnames
-dontskipnonpubliclibraryclasses
-dontskipnonpubliclibraryclassmembers
-dontpreverify
# General
-dontobfuscate
-allowaccessmodification
-repackageclasses ''
-verbose
#Keep all wulkanowy files
#Config for wulkanowy
-keep class io.github.wulkanowy.** {*;}
#Config for anallitycs
-keepattributes *Annotation*
#Config for firebase crashlitycs
-keepattributes SourceFile,LineNumberTable
-keep class com.crashlytics.** {*;}
-keep public class * extends java.lang.Exception
-dontwarn com.crashlytics.**
#Config for OkHttp
#Config for Okio and OkHttp
-dontwarn javax.annotation.**
-keepnames class okhttp3.internal.publicsuffix.PublicSuffixDatabase
-dontwarn org.codehaus.mojo.animal_sniffer.*
-dontwarn okhttp3.internal.platform.ConscryptPlatform
-dontwarn javax.annotation.**
#Config for MPAndroidChart
@ -36,10 +24,3 @@
#Config for Material Components
-keep class com.google.android.material.tabs.** { *; }
#Config for About Libraries
-keep class .R
-keep class **.R$* {
<fields>;
}

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

Binary file not shown.

Before

Width:  |  Height:  |  Size: 478 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 652 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 384 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 460 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 426 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 355 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 451 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 297 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 339 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 335 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 588 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 897 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 508 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 586 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 519 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 781 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 1.3 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 692 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 805 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 700 B

View file

@ -0,0 +1,17 @@
package io.github.wulkanowy.utils
import android.content.Context
import dagger.hilt.android.qualifiers.ApplicationContext
import io.github.wulkanowy.ui.modules.main.MainActivity
import javax.inject.Singleton
import javax.inject.Inject
@Singleton
class InAppReviewHelper @Inject constructor(
@ApplicationContext private val context: Context
) {
fun showInAppReview(activity: MainActivity) {
// do nothing
}
}

View file

@ -3,11 +3,6 @@ package io.github.wulkanowy.utils
import android.util.Log
import com.huawei.agconnect.crash.AGConnectCrash
import fr.bipi.tressence.base.FormatterPriorityTree
import io.github.wulkanowy.sdk.exception.FeatureNotAvailableException
import io.github.wulkanowy.sdk.scrapper.exception.FeatureDisabledException
import java.io.InterruptedIOException
import java.net.SocketTimeoutException
import java.net.UnknownHostException
class CrashLogTree : FormatterPriorityTree(Log.VERBOSE) {
@ -20,21 +15,10 @@ class CrashLogTree : FormatterPriorityTree(Log.VERBOSE) {
}
}
class CrashLogExceptionTree : FormatterPriorityTree(Log.ERROR) {
class CrashLogExceptionTree : FormatterPriorityTree(Log.ERROR, ExceptionFilter) {
private val connectCrash by lazy { AGConnectCrash.getInstance() }
override fun skipLog(priority: Int, tag: String?, message: String, t: Throwable?): Boolean {
return when (t) {
is FeatureDisabledException,
is FeatureNotAvailableException,
is UnknownHostException,
is SocketTimeoutException,
is InterruptedIOException -> true
else -> super.skipLog(priority, tag, message, t)
}
}
override fun log(priority: Int, tag: String?, message: String, t: Throwable?) {
if (skipLog(priority, tag, message, t)) return

View file

@ -0,0 +1,17 @@
package io.github.wulkanowy.utils
import android.content.Context
import dagger.hilt.android.qualifiers.ApplicationContext
import io.github.wulkanowy.ui.modules.main.MainActivity
import javax.inject.Inject
import javax.inject.Singleton
@Singleton
class InAppReviewHelper @Inject constructor(
@ApplicationContext private val context: Context
) {
fun showInAppReview(activity: MainActivity) {
// do nothing
}
}

View file

@ -6,6 +6,7 @@
<uses-permission android:name="android.permission.INTERNET" />
<uses-permission android:name="android.permission.ACCESS_NETWORK_STATE" />
<uses-permission android:name="android.permission.WAKE_LOCK" />
<uses-permission android:name="android.permission.RECEIVE_BOOT_COMPLETED" />
<uses-permission android:name="android.permission.VIBRATE" />
@ -56,7 +57,7 @@
android:name=".ui.modules.login.LoginActivity"
android:configChanges="orientation|screenSize"
android:label="@string/login_title"
android:theme="@style/WulkanowyTheme.NoActionBar"
android:theme="@style/WulkanowyTheme.Login"
android:windowSoftInputMode="adjustResize" />
<activity
android:name=".ui.modules.main.MainActivity"
@ -68,7 +69,7 @@
android:name=".ui.modules.message.send.SendMessageActivity"
android:configChanges="orientation|screenSize"
android:label="@string/send_message_title"
android:theme="@style/WulkanowyTheme.NoActionBar"
android:theme="@style/WulkanowyTheme.MessageSend"
android:windowSoftInputMode="adjustResize" />
<activity
android:name=".ui.modules.timetablewidget.TimetableWidgetConfigureActivity"
@ -167,7 +168,7 @@
<meta-data
android:name="com.google.firebase.messaging.default_notification_icon"
android:resource="@drawable/ic_stat_push" />
android:resource="@drawable/ic_stat_all" />
<meta-data
android:name="com.google.firebase.messaging.default_notification_channel_id"

View file

@ -36,7 +36,19 @@
"githubUsername": "Luncenok"
},
{
"displayName": "MRmlik12",
"displayName": "Daniel Olczyk",
"githubUsername": "MRmlik12"
},
{
"displayName": "Damian Czupryn",
"githubUsername": "Daxxxis"
},
{
"displayName": "Kamil Studziński",
"githubUsername": "studzinskik"
},
{
"displayName": "Tomasz F.",
"githubUsername": "Pengwius"
}
]

View file

@ -1,13 +1,13 @@
package io.github.wulkanowy
import android.annotation.SuppressLint
import android.app.Application
import android.content.Context
import android.util.Log.DEBUG
import android.util.Log.INFO
import android.util.Log.VERBOSE
import android.webkit.WebView
import androidx.fragment.app.FragmentManager
import androidx.hilt.work.HiltWorkerFactory
import androidx.multidex.MultiDex
import androidx.work.Configuration
import com.yariksoffice.lingver.Lingver
import dagger.hilt.android.HiltAndroidApp
@ -41,14 +41,10 @@ class WulkanowyApp : Application(), Configuration.Provider {
@Inject
lateinit var analyticsHelper: AnalyticsHelper
override fun attachBaseContext(base: Context?) {
super.attachBaseContext(base)
MultiDex.install(this)
}
@SuppressLint("UnsafeOptInUsageWarning")
override fun onCreate() {
super.onCreate()
FragmentManager.enableNewStateManager(false)
initializeAppLanguage()
themeManager.applyDefaultTheme()
initLogging()
@ -88,7 +84,7 @@ class WulkanowyApp : Application(), Configuration.Provider {
//https://stackoverflow.com/questions/40398528/android-webview-language-changes-abruptly-on-android-7-0-and-above
try {
WebView(this).destroy()
} catch (e: Exception) {
} catch (e: Throwable) {
//Ignore exceptions
}
}

View file

@ -8,6 +8,8 @@ import androidx.preference.PreferenceManager
import com.chuckerteam.chucker.api.ChuckerCollector
import com.chuckerteam.chucker.api.ChuckerInterceptor
import com.chuckerteam.chucker.api.RetentionManager
import com.squareup.moshi.Moshi
import com.fredporciuncula.flow.preferences.FlowSharedPreferences
import dagger.Module
import dagger.Provides
import dagger.hilt.InstallIn
@ -17,6 +19,8 @@ import io.github.wulkanowy.data.db.AppDatabase
import io.github.wulkanowy.data.db.SharedPrefProvider
import io.github.wulkanowy.data.repositories.PreferencesRepository
import io.github.wulkanowy.sdk.Sdk
import io.github.wulkanowy.utils.AppInfo
import kotlinx.coroutines.ExperimentalCoroutinesApi
import timber.log.Timber
import javax.inject.Singleton
@ -60,7 +64,8 @@ internal class RepositoryModule {
fun provideDatabase(
@ApplicationContext context: Context,
sharedPrefProvider: SharedPrefProvider,
) = AppDatabase.newInstance(context, sharedPrefProvider)
appInfo: AppInfo
) = AppDatabase.newInstance(context, sharedPrefProvider, appInfo)
@Singleton
@Provides
@ -75,6 +80,16 @@ internal class RepositoryModule {
fun provideSharedPref(@ApplicationContext context: Context): SharedPreferences =
PreferenceManager.getDefaultSharedPreferences(context)
@OptIn(ExperimentalCoroutinesApi::class)
@Singleton
@Provides
fun provideFlowSharedPref(sharedPreferences: SharedPreferences) =
FlowSharedPreferences(sharedPreferences)
@Singleton
@Provides
fun provideMoshi() = Moshi.Builder().build()
@Singleton
@Provides
fun provideStudentDao(database: AppDatabase) = database.studentDao
@ -179,4 +194,12 @@ internal class RepositoryModule {
@Singleton
@Provides
fun provideStudentInfoDao(database: AppDatabase) = database.studentInfoDao
@Singleton
@Provides
fun provideTimetableHeaderDao(database: AppDatabase) = database.timetableHeaderDao
@Singleton
@Provides
fun provideSchoolAnnouncementDao(database: AppDatabase) = database.schoolAnnouncementDao
}

View file

@ -6,11 +6,11 @@ import androidx.room.Room
import androidx.room.RoomDatabase
import androidx.room.RoomDatabase.JournalMode.TRUNCATE
import androidx.room.TypeConverters
import androidx.room.migration.Migration
import io.github.wulkanowy.data.db.dao.AttendanceDao
import io.github.wulkanowy.data.db.dao.AttendanceSummaryDao
import io.github.wulkanowy.data.db.dao.CompletedLessonsDao
import io.github.wulkanowy.data.db.dao.ConferenceDao
import io.github.wulkanowy.data.db.dao.SchoolAnnouncementDao
import io.github.wulkanowy.data.db.dao.ExamDao
import io.github.wulkanowy.data.db.dao.GradeDao
import io.github.wulkanowy.data.db.dao.GradePartialStatisticsDao
@ -33,10 +33,12 @@ import io.github.wulkanowy.data.db.dao.SubjectDao
import io.github.wulkanowy.data.db.dao.TeacherDao
import io.github.wulkanowy.data.db.dao.TimetableAdditionalDao
import io.github.wulkanowy.data.db.dao.TimetableDao
import io.github.wulkanowy.data.db.dao.TimetableHeaderDao
import io.github.wulkanowy.data.db.entities.Attendance
import io.github.wulkanowy.data.db.entities.AttendanceSummary
import io.github.wulkanowy.data.db.entities.CompletedLesson
import io.github.wulkanowy.data.db.entities.Conference
import io.github.wulkanowy.data.db.entities.SchoolAnnouncement
import io.github.wulkanowy.data.db.entities.Exam
import io.github.wulkanowy.data.db.entities.Grade
import io.github.wulkanowy.data.db.entities.GradePartialStatistics
@ -59,6 +61,7 @@ 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.TimetableAdditional
import io.github.wulkanowy.data.db.entities.TimetableHeader
import io.github.wulkanowy.data.db.migrations.Migration10
import io.github.wulkanowy.data.db.migrations.Migration11
import io.github.wulkanowy.data.db.migrations.Migration12
@ -86,12 +89,18 @@ import io.github.wulkanowy.data.db.migrations.Migration31
import io.github.wulkanowy.data.db.migrations.Migration32
import io.github.wulkanowy.data.db.migrations.Migration33
import io.github.wulkanowy.data.db.migrations.Migration34
import io.github.wulkanowy.data.db.migrations.Migration35
import io.github.wulkanowy.data.db.migrations.Migration36
import io.github.wulkanowy.data.db.migrations.Migration37
import io.github.wulkanowy.data.db.migrations.Migration38
import io.github.wulkanowy.data.db.migrations.Migration39
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 io.github.wulkanowy.utils.AppInfo
import javax.inject.Singleton
@Singleton
@ -123,6 +132,8 @@ import javax.inject.Singleton
Conference::class,
TimetableAdditional::class,
StudentInfo::class,
TimetableHeader::class,
SchoolAnnouncement::class,
],
version = AppDatabase.VERSION_SCHEMA,
exportSchema = true
@ -131,54 +142,59 @@ import javax.inject.Singleton
abstract class AppDatabase : RoomDatabase() {
companion object {
const val VERSION_SCHEMA = 34
const val VERSION_SCHEMA = 39
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),
Migration20(),
Migration21(),
Migration22(),
Migration23(),
Migration24(),
Migration25(),
Migration26(),
Migration27(),
Migration28(),
Migration29(),
Migration30(),
Migration31(),
Migration32(),
Migration33(),
Migration34()
)
}
fun getMigrations(sharedPrefProvider: SharedPrefProvider, appInfo: AppInfo) = arrayOf(
Migration2(),
Migration3(),
Migration4(),
Migration5(),
Migration6(),
Migration7(),
Migration8(),
Migration9(),
Migration10(),
Migration11(),
Migration12(),
Migration13(),
Migration14(),
Migration15(),
Migration16(),
Migration17(),
Migration18(),
Migration19(sharedPrefProvider),
Migration20(),
Migration21(),
Migration22(),
Migration23(),
Migration24(),
Migration25(),
Migration26(),
Migration27(),
Migration28(),
Migration29(),
Migration30(),
Migration31(),
Migration32(),
Migration33(),
Migration34(),
Migration35(appInfo),
Migration36(),
Migration37(),
Migration38(),
Migration39(),
)
fun newInstance(context: Context, sharedPrefProvider: SharedPrefProvider): AppDatabase {
return Room.databaseBuilder(context, AppDatabase::class.java, "wulkanowy_database")
.setJournalMode(TRUNCATE)
.fallbackToDestructiveMigrationFrom(VERSION_SCHEMA + 1)
.fallbackToDestructiveMigrationOnDowngrade()
.addMigrations(*getMigrations(sharedPrefProvider))
.build()
}
fun newInstance(
context: Context,
sharedPrefProvider: SharedPrefProvider,
appInfo: AppInfo
) = Room.databaseBuilder(context, AppDatabase::class.java, "wulkanowy_database")
.setJournalMode(TRUNCATE)
.fallbackToDestructiveMigrationFrom(VERSION_SCHEMA + 1)
.fallbackToDestructiveMigrationOnDowngrade()
.addMigrations(*getMigrations(sharedPrefProvider, appInfo))
.build()
}
abstract val studentDao: StudentDao
@ -232,4 +248,8 @@ abstract class AppDatabase : RoomDatabase() {
abstract val timetableAdditionalDao: TimetableAdditionalDao
abstract val studentInfoDao: StudentInfoDao
abstract val timetableHeaderDao: TimetableHeaderDao
abstract val schoolAnnouncementDao: SchoolAnnouncementDao
}

View file

@ -20,9 +20,15 @@ class SharedPrefProvider @Inject constructor(
fun getLong(key: String, defaultValue: Long) = sharedPref.getLong(key, defaultValue)
fun getString(key: String) = sharedPref.getString(key, null)
fun getString(key: String, defaultValue: String): String = sharedPref.getString(key, defaultValue) ?: defaultValue
fun putString(key: String, value: String, sync: Boolean = false) {
fun getBoolean(key: String, defaultValue: Boolean): Boolean = sharedPref.getBoolean(key, defaultValue)
fun putBoolean(key: String, value: Boolean, sync: Boolean = false) = sharedPref.edit(sync) { putBoolean(key, value) }
fun putString(key: String, value: String?, sync: Boolean = false) {
sharedPref.edit(sync) { putString(key, value) }
}

View file

@ -4,12 +4,13 @@ import androidx.room.Dao
import androidx.room.Query
import io.github.wulkanowy.data.db.entities.Conference
import kotlinx.coroutines.flow.Flow
import java.time.LocalDateTime
import javax.inject.Singleton
@Dao
@Singleton
interface ConferenceDao : BaseDao<Conference> {
@Query("SELECT * FROM Conferences WHERE diary_id = :diaryId AND student_id = :studentId")
fun loadAll(diaryId: Int, studentId: Int): Flow<List<Conference>>
@Query("SELECT * FROM Conferences WHERE diary_id = :diaryId AND student_id = :studentId AND date >= :startDate")
fun loadAll(diaryId: Int, studentId: Int, startDate: LocalDateTime): Flow<List<Conference>>
}

View file

@ -13,4 +13,7 @@ interface LuckyNumberDao : BaseDao<LuckyNumber> {
@Query("SELECT * FROM LuckyNumbers WHERE student_id = :studentId AND date = :date")
fun load(studentId: Int, date: LocalDate): Flow<LuckyNumber?>
@Query("SELECT * FROM LuckyNumbers WHERE student_id = :studentId AND date >= :start AND date <= :end")
fun getAll(studentId: Int, start: LocalDate, end: LocalDate): Flow<List<LuckyNumber>>
}

View file

@ -9,6 +9,6 @@ import javax.inject.Singleton
@Dao
interface RecipientDao : BaseDao<Recipient> {
@Query("SELECT * FROM Recipients WHERE student_id = :userLoginId AND unit_id = :unitId AND role = :role")
suspend fun loadAll(userLoginId: Int, unitId: Int, role: Int): List<Recipient>
@Query("SELECT * FROM Recipients WHERE student_id = :studentId AND unit_id = :unitId AND role = :role")
suspend fun loadAll(studentId: Int, unitId: Int, role: Int): List<Recipient>
}

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.SchoolAnnouncement
import kotlinx.coroutines.flow.Flow
import javax.inject.Singleton
@Dao
@Singleton
interface SchoolAnnouncementDao : BaseDao<SchoolAnnouncement> {
@Query("SELECT * FROM SchoolAnnouncements WHERE student_id = :studentId")
fun loadAll(studentId: Int): Flow<List<SchoolAnnouncement>>
}

View file

@ -8,7 +8,7 @@ import androidx.room.Query
import androidx.room.Transaction
import androidx.room.Update
import io.github.wulkanowy.data.db.entities.Student
import io.github.wulkanowy.data.db.entities.StudentNick
import io.github.wulkanowy.data.db.entities.StudentNickAndAvatar
import io.github.wulkanowy.data.db.entities.StudentWithSemesters
import javax.inject.Singleton
@ -23,13 +23,13 @@ interface StudentDao {
suspend fun delete(student: Student)
@Update(entity = Student::class)
suspend fun update(studentNick: StudentNick)
suspend fun update(studentNickAndAvatar: StudentNickAndAvatar)
@Query("SELECT * FROM Students WHERE is_current = 1")
suspend fun loadCurrent(): Student?
@Query("SELECT * FROM Students WHERE id = :id")
suspend fun loadById(id: Int): Student?
suspend fun loadById(id: Long): Student?
@Query("SELECT * FROM Students")
suspend fun loadAll(): List<Student>

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.TimetableHeader
import kotlinx.coroutines.flow.Flow
import java.time.LocalDate
import javax.inject.Singleton
@Dao
@Singleton
interface TimetableHeaderDao : BaseDao<TimetableHeader> {
@Query("SELECT * FROM TimetableHeaders WHERE diary_id = :diaryId AND student_id = :studentId AND date >= :from AND date <= :end")
fun loadAll(diaryId: Int, studentId: Int, from: LocalDate, end: LocalDate): Flow<List<TimetableHeader>>
}

View file

@ -32,4 +32,7 @@ data class Conference(
@PrimaryKey(autoGenerate = true)
var id: Long = 0
@ColumnInfo(name = "is_notified")
var isNotified: Boolean = true
}

View file

@ -36,4 +36,7 @@ data class Exam(
@PrimaryKey(autoGenerate = true)
var id: Long = 0
@ColumnInfo(name = "is_notified")
var isNotified: Boolean = true
}

View file

@ -37,4 +37,7 @@ data class Homework(
@ColumnInfo(name = "is_done")
var isDone: Boolean = false
@ColumnInfo(name = "is_notified")
var isNotified: Boolean = true
}

View file

@ -10,7 +10,7 @@ import java.time.LocalDateTime
data class Message(
@ColumnInfo(name = "student_id")
val studentId: Int,
val studentId: Long,
@ColumnInfo(name = "real_id")
val realId: Int,

View file

@ -3,13 +3,15 @@ package io.github.wulkanowy.data.db.entities
import androidx.room.ColumnInfo
import androidx.room.Entity
import androidx.room.PrimaryKey
import com.squareup.moshi.JsonClass
import java.io.Serializable
@JsonClass(generateAdapter = true)
@Entity(tableName = "Recipients")
data class Recipient(
@ColumnInfo(name = "student_id")
val userLoginId: Int,
val studentId: Int,
@ColumnInfo(name = "real_id")
val realId: String,

View file

@ -0,0 +1,27 @@
package io.github.wulkanowy.data.db.entities
import androidx.room.ColumnInfo
import androidx.room.Entity
import androidx.room.PrimaryKey
import java.io.Serializable
import java.time.LocalDate
@Entity(tableName = "SchoolAnnouncements")
data class SchoolAnnouncement(
@ColumnInfo(name = "student_id")
val studentId: Int,
val date: LocalDate,
val subject: String,
val content: String
) : Serializable {
@PrimaryKey(autoGenerate = true)
var id: Long = 0
@ColumnInfo(name = "is_notified")
var isNotified: Boolean = true
}

View file

@ -81,4 +81,7 @@ data class Student(
var id: Long = 0
var nick = ""
@ColumnInfo(name = "avatar_color")
var avatarColor = 0L
}

View file

@ -1,13 +1,17 @@
package io.github.wulkanowy.data.db.entities
import androidx.room.ColumnInfo
import androidx.room.Entity
import androidx.room.PrimaryKey
import java.io.Serializable
@Entity
data class StudentNick(
data class StudentNickAndAvatar(
val nick: String
val nick: String,
@ColumnInfo(name = "avatar_color")
var avatarColor: Long
) : Serializable {

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 java.io.Serializable
import java.time.LocalDate
@Entity(tableName = "TimetableHeaders")
data class TimetableHeader(
@ColumnInfo(name = "student_id")
val studentId: Int,
@ColumnInfo(name = "diary_id")
val diaryId: Int,
val date: LocalDate,
val content: String,
) : Serializable {
@PrimaryKey(autoGenerate = true)
var id: Long = 0
}

View file

@ -0,0 +1,24 @@
package io.github.wulkanowy.data.db.migrations
import androidx.core.database.getLongOrNull
import androidx.room.migration.Migration
import androidx.sqlite.db.SupportSQLiteDatabase
import io.github.wulkanowy.utils.AppInfo
class Migration35(private val appInfo: AppInfo) : Migration(34, 35) {
override fun migrate(database: SupportSQLiteDatabase) {
database.execSQL("ALTER TABLE Students ADD COLUMN `avatar_color` INTEGER NOT NULL DEFAULT 0")
val studentsCursor = database.query("SELECT * FROM Students")
while (studentsCursor.moveToNext()) {
val studentId = studentsCursor.getLongOrNull(0)
database.execSQL(
"""UPDATE Students
SET avatar_color = ${appInfo.defaultColorsForAvatar.random()}
WHERE id = $studentId"""
)
}
}
}

View file

@ -0,0 +1,12 @@
package io.github.wulkanowy.data.db.migrations
import androidx.room.migration.Migration
import androidx.sqlite.db.SupportSQLiteDatabase
class Migration36 : Migration(35, 36) {
override fun migrate(database: SupportSQLiteDatabase) {
database.execSQL("ALTER TABLE Exams ADD COLUMN is_notified INTEGER NOT NULL DEFAULT 1")
database.execSQL("ALTER TABLE Homework ADD COLUMN is_notified INTEGER NOT NULL DEFAULT 1")
}
}

View file

@ -0,0 +1,21 @@
package io.github.wulkanowy.data.db.migrations
import androidx.room.migration.Migration
import androidx.sqlite.db.SupportSQLiteDatabase
class Migration37 : Migration(36, 37) {
override fun migrate(database: SupportSQLiteDatabase) {
database.execSQL(
"""
CREATE TABLE IF NOT EXISTS TimetableHeaders (
id INTEGER PRIMARY KEY AUTOINCREMENT NOT NULL,
student_id INTEGER NOT NULL,
diary_id INTEGER NOT NULL,
date INTEGER NOT NULL,
content TEXT NOT NULL
)
"""
)
}
}

View file

@ -0,0 +1,19 @@
package io.github.wulkanowy.data.db.migrations
import androidx.room.migration.Migration
import androidx.sqlite.db.SupportSQLiteDatabase
class Migration38 : Migration(37, 38) {
override fun migrate(database: SupportSQLiteDatabase) {
database.execSQL("""
CREATE TABLE IF NOT EXISTS `SchoolAnnouncements` (
`id` INTEGER PRIMARY KEY AUTOINCREMENT NOT NULL,
`student_id` INTEGER NOT NULL,
`date` INTEGER NOT NULL,
`subject` TEXT NOT NULL,
`content` TEXT NOT NULL
)
""")
}
}

View file

@ -0,0 +1,12 @@
package io.github.wulkanowy.data.db.migrations
import androidx.room.migration.Migration
import androidx.sqlite.db.SupportSQLiteDatabase
class Migration39 : Migration(38, 39) {
override fun migrate(database: SupportSQLiteDatabase) {
database.execSQL("ALTER TABLE Conferences ADD COLUMN is_notified INTEGER NOT NULL DEFAULT 1")
database.execSQL("ALTER TABLE SchoolAnnouncements ADD COLUMN is_notified INTEGER NOT NULL DEFAULT 1")
}
}

View file

@ -0,0 +1,14 @@
package io.github.wulkanowy.data.mappers
import io.github.wulkanowy.data.db.entities.SchoolAnnouncement
import io.github.wulkanowy.data.db.entities.Student
import io.github.wulkanowy.sdk.pojo.DirectorInformation as SdkDirectorInformation
fun List<SdkDirectorInformation>.mapToEntities(student: Student) = map {
SchoolAnnouncement(
studentId = student.studentId,
date = it.date,
subject = it.subject,
content = it.content,
)
}

View file

@ -5,10 +5,9 @@ import io.github.wulkanowy.data.db.entities.GradePointsStatistics
import io.github.wulkanowy.data.db.entities.GradeSemesterStatistics
import io.github.wulkanowy.data.db.entities.Semester
import io.github.wulkanowy.data.pojos.GradeStatisticsItem
import io.github.wulkanowy.ui.modules.grade.statistics.ViewType
import io.github.wulkanowy.sdk.pojo.GradeStatisticsSubject as SdkGradeStatisticsSubject
import io.github.wulkanowy.sdk.pojo.GradeStatisticsSemester as SdkGradeStatisticsSemester
import io.github.wulkanowy.sdk.pojo.GradePointsStatistics as SdkGradePointsStatistics
import io.github.wulkanowy.sdk.pojo.GradeStatisticsSemester as SdkGradeStatisticsSemester
import io.github.wulkanowy.sdk.pojo.GradeStatisticsSubject as SdkGradeStatisticsSubject
@JvmName("mapToEntitiesSubject")
fun List<SdkGradeStatisticsSubject>.mapToEntities(semester: Semester) = map {
@ -51,7 +50,7 @@ fun List<SdkGradePointsStatistics>.mapToEntities(semester: Semester) = map {
fun List<GradePartialStatistics>.mapPartialToStatisticItems() = filterNot { it.classAmounts.isEmpty() }.map {
GradeStatisticsItem(
type = ViewType.PARTIAL,
type = GradeStatisticsItem.DataType.PARTIAL,
average = it.classAverage,
partial = it,
points = null,
@ -61,7 +60,7 @@ fun List<GradePartialStatistics>.mapPartialToStatisticItems() = filterNot { it.c
fun List<GradeSemesterStatistics>.mapSemesterToStatisticItems() = filterNot { it.amounts.isEmpty() }.map {
GradeStatisticsItem(
type = ViewType.SEMESTER,
type = GradeStatisticsItem.DataType.SEMESTER,
partial = null,
points = null,
average = "",
@ -71,7 +70,7 @@ fun List<GradeSemesterStatistics>.mapSemesterToStatisticItems() = filterNot { it
fun List<GradePointsStatistics>.mapPointsToStatisticsItems() = map {
GradeStatisticsItem(
type = ViewType.POINTS,
type = GradeStatisticsItem.DataType.POINTS,
partial = null,
semester = null,
average = "",

View file

@ -4,14 +4,14 @@ import io.github.wulkanowy.data.db.entities.Message
import io.github.wulkanowy.data.db.entities.MessageAttachment
import io.github.wulkanowy.data.db.entities.Recipient
import io.github.wulkanowy.data.db.entities.Student
import io.github.wulkanowy.sdk.pojo.Recipient as SdkRecipient
import io.github.wulkanowy.sdk.pojo.MessageAttachment as SdkMessageAttachment
import java.time.LocalDateTime
import io.github.wulkanowy.sdk.pojo.Message as SdkMessage
import io.github.wulkanowy.sdk.pojo.MessageAttachment as SdkMessageAttachment
import io.github.wulkanowy.sdk.pojo.Recipient as SdkRecipient
fun List<SdkMessage>.mapToEntities(student: Student) = map {
Message(
studentId = student.id.toInt(),
studentId = student.id,
realId = it.id ?: 0,
messageId = it.messageId ?: 0,
sender = it.sender?.name.orEmpty(),

View file

@ -5,7 +5,7 @@ import io.github.wulkanowy.sdk.pojo.Recipient as SdkRecipient
fun List<SdkRecipient>.mapToEntities(userLoginId: Int) = map {
Recipient(
userLoginId = userLoginId,
studentId = userLoginId,
realId = it.id,
realName = it.name,
name = it.shortName,

View file

@ -6,7 +6,7 @@ import io.github.wulkanowy.sdk.pojo.ReportingUnit as SdkReportingUnit
fun List<SdkReportingUnit>.mapToEntities(student: Student) = map {
ReportingUnit(
studentId = student.studentId,
studentId = student.id.toInt(),
unitId = it.id,
roles = it.roles,
senderId = it.senderId,

View file

@ -5,7 +5,7 @@ import io.github.wulkanowy.data.db.entities.StudentWithSemesters
import java.time.LocalDateTime
import io.github.wulkanowy.sdk.pojo.Student as SdkStudent
fun List<SdkStudent>.mapToEntities(password: String = "") = map {
fun List<SdkStudent>.mapToEntities(password: String = "", colors: List<Long>) = map {
StudentWithSemesters(
student = Student(
email = it.email,
@ -28,8 +28,10 @@ fun List<SdkStudent>.mapToEntities(password: String = "") = map {
mobileBaseUrl = it.mobileBaseUrl,
privateKey = it.privateKey,
certificateKey = it.certificateKey,
loginMode = it.loginMode.name
),
loginMode = it.loginMode.name,
).apply {
avatarColor = colors.random()
},
semesters = it.semesters.mapToEntities(it.studentId)
)
}

View file

@ -3,9 +3,19 @@ package io.github.wulkanowy.data.mappers
import io.github.wulkanowy.data.db.entities.Semester
import io.github.wulkanowy.data.db.entities.Timetable
import io.github.wulkanowy.data.db.entities.TimetableAdditional
import io.github.wulkanowy.data.db.entities.TimetableHeader
import io.github.wulkanowy.data.pojos.TimetableFull
import io.github.wulkanowy.sdk.pojo.TimetableFull as SdkTimetableFull
import io.github.wulkanowy.sdk.pojo.TimetableDayHeader as SdkTimetableHeader
import io.github.wulkanowy.sdk.pojo.Timetable as SdkTimetable
import io.github.wulkanowy.sdk.pojo.TimetableAdditional as SdkTimetableAdditional
fun SdkTimetableFull.mapToEntities(semester: Semester) = TimetableFull(
lessons = lessons.mapToEntities(semester),
additional = additional.mapToEntities(semester),
headers = headers.mapToEntities(semester)
)
fun List<SdkTimetable>.mapToEntities(semester: Semester) = map {
Timetable(
studentId = semester.studentId,
@ -39,3 +49,13 @@ fun List<SdkTimetableAdditional>.mapToEntities(semester: Semester) = map {
end = it.end
)
}
@JvmName("mapToEntitiesTimetableHeaders")
fun List<SdkTimetableHeader>.mapToEntities(semester: Semester) = map {
TimetableHeader(
studentId = semester.studentId,
diaryId = semester.diaryId,
date = it.date,
content = it.content
)
}

View file

@ -3,11 +3,10 @@ package io.github.wulkanowy.data.pojos
import io.github.wulkanowy.data.db.entities.GradePartialStatistics
import io.github.wulkanowy.data.db.entities.GradePointsStatistics
import io.github.wulkanowy.data.db.entities.GradeSemesterStatistics
import io.github.wulkanowy.ui.modules.grade.statistics.ViewType
data class GradeStatisticsItem(
val type: ViewType,
val type: DataType,
val average: String,
@ -16,4 +15,11 @@ data class GradeStatisticsItem(
val semester: GradeSemesterStatistics?,
val points: GradePointsStatistics?
)
) {
enum class DataType {
SEMESTER,
PARTIAL,
POINTS,
}
}

View file

@ -0,0 +1,11 @@
package io.github.wulkanowy.data.pojos
import com.squareup.moshi.JsonClass
import io.github.wulkanowy.ui.modules.message.send.RecipientChipItem
@JsonClass(generateAdapter = true)
data class MessageDraft(
val recipients: List<RecipientChipItem>,
val subject: String,
val content: String,
)

View file

@ -0,0 +1,36 @@
package io.github.wulkanowy.data.pojos
import androidx.annotation.DrawableRes
import androidx.annotation.PluralsRes
import androidx.annotation.StringRes
import io.github.wulkanowy.services.sync.notifications.NotificationType
import io.github.wulkanowy.ui.modules.main.MainView
sealed interface Notification {
val type: NotificationType
val startMenu: MainView.Section
val icon: Int
val titleStringRes: Int
val contentStringRes: Int
}
data class MultipleNotifications(
override val type: NotificationType,
override val startMenu: MainView.Section,
@DrawableRes override val icon: Int,
@PluralsRes override val titleStringRes: Int,
@PluralsRes override val contentStringRes: Int,
@PluralsRes val summaryStringRes: Int,
val lines: List<String>,
) : Notification
data class OneNotification(
override val type: NotificationType,
override val startMenu: MainView.Section,
@DrawableRes override val icon: Int,
@StringRes override val titleStringRes: Int,
@StringRes override val contentStringRes: Int,
val contentValues: List<String>,
) : Notification

View file

@ -0,0 +1,11 @@
package io.github.wulkanowy.data.pojos
import io.github.wulkanowy.data.db.entities.Timetable
import io.github.wulkanowy.data.db.entities.TimetableAdditional
import io.github.wulkanowy.data.db.entities.TimetableHeader
data class TimetableFull(
val lessons: List<Timetable>,
val additional: List<TimetableAdditional>,
val headers: List<TimetableHeader>,
)

View file

@ -15,6 +15,7 @@ class AppCreatorRepository @Inject constructor(
private val dispatchers: DispatchersProvider
) {
@Suppress("BlockingMethodInNonBlockingContext")
suspend fun getAppCreators() = withContext(dispatchers.backgroundThread) {
val moshi = Moshi.Builder().build()
val type = Types.newParameterizedType(List::class.java, Contributor::class.java)

View file

@ -14,6 +14,7 @@ import io.github.wulkanowy.utils.monday
import io.github.wulkanowy.utils.networkBoundResource
import io.github.wulkanowy.utils.sunday
import io.github.wulkanowy.utils.uniqueSubtract
import kotlinx.coroutines.sync.Mutex
import java.time.LocalDate
import java.time.LocalDateTime
import java.time.LocalTime
@ -27,9 +28,12 @@ class AttendanceRepository @Inject constructor(
private val refreshHelper: AutoRefreshHelper,
) {
private val saveFetchResultMutex = Mutex()
private val cacheKey = "attendance"
fun getAttendance(student: Student, semester: Semester, start: LocalDate, end: LocalDate, forceRefresh: Boolean) = networkBoundResource(
mutex = saveFetchResultMutex,
shouldFetch = { it.isEmpty() || forceRefresh || refreshHelper.isShouldBeRefreshed(getRefreshKey(cacheKey, semester, start, end)) },
query = { attendanceDb.loadAll(semester.diaryId, semester.studentId, start.monday, end.sunday) },
fetch = {

View file

@ -10,6 +10,7 @@ import io.github.wulkanowy.utils.getRefreshKey
import io.github.wulkanowy.utils.init
import io.github.wulkanowy.utils.networkBoundResource
import io.github.wulkanowy.utils.uniqueSubtract
import kotlinx.coroutines.sync.Mutex
import javax.inject.Inject
import javax.inject.Singleton
@ -20,10 +21,21 @@ class AttendanceSummaryRepository @Inject constructor(
private val refreshHelper: AutoRefreshHelper,
) {
private val saveFetchResultMutex = Mutex()
private val cacheKey = "attendance_summary"
fun getAttendanceSummary(student: Student, semester: Semester, subjectId: Int, forceRefresh: Boolean) = networkBoundResource(
shouldFetch = { it.isEmpty() || forceRefresh || refreshHelper.isShouldBeRefreshed(getRefreshKey(cacheKey, semester)) },
fun getAttendanceSummary(
student: Student,
semester: Semester,
subjectId: Int,
forceRefresh: Boolean
) = networkBoundResource(
mutex = saveFetchResultMutex,
shouldFetch = {
it.isEmpty() || forceRefresh
|| refreshHelper.isShouldBeRefreshed(getRefreshKey(cacheKey, semester))
},
query = { attendanceDb.loadAll(semester.diaryId, semester.studentId, subjectId) },
fetch = {
sdk.init(student).switchDiary(semester.diaryId, semester.schoolYear)

View file

@ -12,6 +12,7 @@ import io.github.wulkanowy.utils.monday
import io.github.wulkanowy.utils.networkBoundResource
import io.github.wulkanowy.utils.sunday
import io.github.wulkanowy.utils.uniqueSubtract
import kotlinx.coroutines.sync.Mutex
import java.time.LocalDate
import javax.inject.Inject
import javax.inject.Singleton
@ -23,9 +24,12 @@ class CompletedLessonsRepository @Inject constructor(
private val refreshHelper: AutoRefreshHelper,
) {
private val saveFetchResultMutex = Mutex()
private val cacheKey = "completed"
fun getCompletedLessons(student: Student, semester: Semester, start: LocalDate, end: LocalDate, forceRefresh: Boolean) = networkBoundResource(
mutex = saveFetchResultMutex,
shouldFetch = { it.isEmpty() || forceRefresh || refreshHelper.isShouldBeRefreshed(getRefreshKey(cacheKey, semester, start, end)) },
query = { completedLessonsDb.loadAll(semester.studentId, semester.diaryId, start.monday, end.sunday) },
fetch = {

View file

@ -1,6 +1,7 @@
package io.github.wulkanowy.data.repositories
import io.github.wulkanowy.data.db.dao.ConferenceDao
import io.github.wulkanowy.data.db.entities.Conference
import io.github.wulkanowy.data.db.entities.Semester
import io.github.wulkanowy.data.db.entities.Student
import io.github.wulkanowy.data.mappers.mapToEntities
@ -10,6 +11,11 @@ import io.github.wulkanowy.utils.getRefreshKey
import io.github.wulkanowy.utils.init
import io.github.wulkanowy.utils.networkBoundResource
import io.github.wulkanowy.utils.uniqueSubtract
import kotlinx.coroutines.flow.Flow
import kotlinx.coroutines.sync.Mutex
import java.time.Instant
import java.time.LocalDateTime
import java.time.ZoneOffset
import javax.inject.Inject
import javax.inject.Singleton
@ -20,20 +26,48 @@ class ConferenceRepository @Inject constructor(
private val refreshHelper: AutoRefreshHelper,
) {
private val saveFetchResultMutex = Mutex()
private val cacheKey = "conference"
fun getConferences(student: Student, semester: Semester, forceRefresh: Boolean) = networkBoundResource(
shouldFetch = { it.isEmpty() || forceRefresh || refreshHelper.isShouldBeRefreshed(getRefreshKey(cacheKey, semester)) },
query = { conferenceDb.loadAll(semester.diaryId, student.studentId) },
fun getConferences(
student: Student,
semester: Semester,
forceRefresh: Boolean,
notify: Boolean = false,
startDate: LocalDateTime = LocalDateTime.ofInstant(Instant.EPOCH, ZoneOffset.UTC)
) = networkBoundResource(
mutex = saveFetchResultMutex,
shouldFetch = {
it.isEmpty() || forceRefresh
|| refreshHelper.isShouldBeRefreshed(getRefreshKey(cacheKey, semester))
},
query = {
conferenceDb.loadAll(semester.diaryId, student.studentId, startDate)
},
fetch = {
sdk.init(student).switchDiary(semester.diaryId, semester.schoolYear)
.getConferences()
.mapToEntities(semester)
.filter { it.date >= startDate }
},
saveFetchResult = { old, new ->
val conferencesToSave = (new uniqueSubtract old).onEach {
if (notify) it.isNotified = false
}
conferenceDb.deleteAll(old uniqueSubtract new)
conferenceDb.insertAll(new uniqueSubtract old)
conferenceDb.insertAll(conferencesToSave)
refreshHelper.updateLastRefreshTimestamp(getRefreshKey(cacheKey, semester))
}
)
fun getConferenceFromDatabase(semester: Semester): Flow<List<Conference>> =
conferenceDb.loadAll(
diaryId = semester.diaryId,
studentId = semester.studentId,
startDate = LocalDateTime.ofInstant(Instant.EPOCH, ZoneOffset.UTC)
)
suspend fun updateConference(conference: List<Conference>) = conferenceDb.updateAll(conference)
}

View file

@ -1,6 +1,7 @@
package io.github.wulkanowy.data.repositories
import io.github.wulkanowy.data.db.dao.ExamDao
import io.github.wulkanowy.data.db.entities.Exam
import io.github.wulkanowy.data.db.entities.Semester
import io.github.wulkanowy.data.db.entities.Student
import io.github.wulkanowy.data.mappers.mapToEntities
@ -12,6 +13,8 @@ import io.github.wulkanowy.utils.init
import io.github.wulkanowy.utils.networkBoundResource
import io.github.wulkanowy.utils.startExamsDay
import io.github.wulkanowy.utils.uniqueSubtract
import kotlinx.coroutines.flow.Flow
import kotlinx.coroutines.sync.Mutex
import java.time.LocalDate
import javax.inject.Inject
import javax.inject.Singleton
@ -23,21 +26,58 @@ class ExamRepository @Inject constructor(
private val refreshHelper: AutoRefreshHelper,
) {
private val saveFetchResultMutex = Mutex()
private val cacheKey = "exam"
fun getExams(student: Student, semester: Semester, start: LocalDate, end: LocalDate, forceRefresh: Boolean) = networkBoundResource(
shouldFetch = { it.isEmpty() || forceRefresh || refreshHelper.isShouldBeRefreshed(getRefreshKey(cacheKey, semester, start, end)) },
query = { examDb.loadAll(semester.diaryId, semester.studentId, start.startExamsDay, start.endExamsDay) },
fun getExams(
student: Student,
semester: Semester,
start: LocalDate,
end: LocalDate,
forceRefresh: Boolean,
notify: Boolean = false
) = networkBoundResource(
mutex = saveFetchResultMutex,
shouldFetch = {
val isShouldBeRefreshed = refreshHelper.isShouldBeRefreshed(
key = getRefreshKey(cacheKey, semester, start, end)
)
it.isEmpty() || forceRefresh || isShouldBeRefreshed
},
query = {
examDb.loadAll(
diaryId = semester.diaryId,
studentId = semester.studentId,
from = start.startExamsDay,
end = start.endExamsDay
)
},
fetch = {
sdk.init(student).switchDiary(semester.diaryId, semester.schoolYear)
.getExams(start.startExamsDay, start.endExamsDay, semester.semesterId)
.mapToEntities(semester)
},
saveFetchResult = { old, new ->
val examsToSave = (new uniqueSubtract old).onEach {
if (notify) it.isNotified = false
}
examDb.deleteAll(old uniqueSubtract new)
examDb.insertAll(new uniqueSubtract old)
examDb.insertAll(examsToSave)
refreshHelper.updateLastRefreshTimestamp(getRefreshKey(cacheKey, semester, start, end))
},
filterResult = { it.filter { item -> item.date in start..end } }
)
fun getExamsFromDatabase(semester: Semester, start: LocalDate): Flow<List<Exam>> {
return examDb.loadAll(
diaryId = semester.diaryId,
studentId = semester.studentId,
from = start.startExamsDay,
end = start.endExamsDay
)
}
suspend fun updateExam(exam: List<Exam>) = examDb.updateAll(exam)
}

View file

@ -16,6 +16,7 @@ import io.github.wulkanowy.utils.uniqueSubtract
import kotlinx.coroutines.flow.Flow
import kotlinx.coroutines.flow.combine
import kotlinx.coroutines.flow.map
import kotlinx.coroutines.sync.Mutex
import java.time.LocalDateTime
import javax.inject.Inject
import javax.inject.Singleton
@ -28,14 +29,26 @@ class GradeRepository @Inject constructor(
private val refreshHelper: AutoRefreshHelper,
) {
private val saveFetchResultMutex = Mutex()
private val cacheKey = "grade"
fun getGrades(student: Student, semester: Semester, forceRefresh: Boolean, notify: Boolean = false) = networkBoundResource(
shouldFetch = { (details, summaries) -> details.isEmpty() || summaries.isEmpty() || forceRefresh || refreshHelper.isShouldBeRefreshed(getRefreshKey(cacheKey, semester)) },
fun getGrades(
student: Student,
semester: Semester,
forceRefresh: Boolean,
notify: Boolean = false
) = networkBoundResource(
mutex = saveFetchResultMutex,
shouldFetch = { (details, summaries) ->
val isShouldBeRefreshed =
refreshHelper.isShouldBeRefreshed(getRefreshKey(cacheKey, semester))
details.isEmpty() || summaries.isEmpty() || forceRefresh || isShouldBeRefreshed
},
query = {
gradeDb.loadAll(semester.semesterId, semester.studentId).combine(gradeSummaryDb.loadAll(semester.semesterId, semester.studentId)) { details, summaries ->
details to summaries
}
val detailsFlow = gradeDb.loadAll(semester.semesterId, semester.studentId)
val summaryFlow = gradeSummaryDb.loadAll(semester.semesterId, semester.studentId)
detailsFlow.combine(summaryFlow) { details, summaries -> details to summaries }
},
fetch = {
val (details, summary) = sdk.init(student)
@ -52,8 +65,14 @@ class GradeRepository @Inject constructor(
}
)
private suspend fun refreshGradeDetails(student: Student, oldGrades: List<Grade>, newDetails: List<Grade>, notify: Boolean) {
val notifyBreakDate = oldGrades.maxByOrNull { it.date }?.date ?: student.registrationDate.toLocalDate()
private suspend fun refreshGradeDetails(
student: Student,
oldGrades: List<Grade>,
newDetails: List<Grade>,
notify: Boolean
) {
val notifyBreakDate =
oldGrades.maxByOrNull { it.date }?.date ?: student.registrationDate.toLocalDate()
gradeDb.deleteAll(oldGrades uniqueSubtract newDetails)
gradeDb.insertAll((newDetails uniqueSubtract oldGrades).onEach {
if (it.date >= notifyBreakDate) it.apply {
@ -63,10 +82,15 @@ class GradeRepository @Inject constructor(
})
}
private suspend fun refreshGradeSummaries(oldSummaries: List<GradeSummary>, newSummary: List<GradeSummary>, notify: Boolean) {
private suspend fun refreshGradeSummaries(
oldSummaries: List<GradeSummary>,
newSummary: List<GradeSummary>,
notify: Boolean
) {
gradeSummaryDb.deleteAll(oldSummaries uniqueSubtract newSummary)
gradeSummaryDb.insertAll((newSummary uniqueSubtract oldSummaries).onEach { summary ->
val oldSummary = oldSummaries.find { oldSummary -> oldSummary.subject == summary.subject }
val oldSummary =
oldSummaries.find { oldSummary -> oldSummary.subject == summary.subject }
summary.isPredictedGradeNotified = when {
summary.predictedGrade.isEmpty() -> true
notify && oldSummary?.predictedGrade != summary.predictedGrade -> false
@ -92,19 +116,21 @@ class GradeRepository @Inject constructor(
}
fun getUnreadGrades(semester: Semester): Flow<List<Grade>> {
return gradeDb.loadAll(semester.semesterId, semester.studentId).map { it.filter { grade -> !grade.isRead } }
return gradeDb.loadAll(semester.semesterId, semester.studentId).map {
it.filter { grade -> !grade.isRead }
}
}
fun getNotNotifiedGrades(semester: Semester): Flow<List<Grade>> {
return gradeDb.loadAll(semester.semesterId, semester.studentId).map { it.filter { grade -> !grade.isNotified } }
fun getGradesFromDatabase(semester: Semester): Flow<List<Grade>> {
return gradeDb.loadAll(semester.semesterId, semester.studentId)
}
fun getNotNotifiedPredictedGrades(semester: Semester): Flow<List<GradeSummary>> {
return gradeSummaryDb.loadAll(semester.semesterId, semester.studentId).map { it.filter { gradeSummary -> !gradeSummary.isPredictedGradeNotified } }
fun getGradesPredictedFromDatabase(semester: Semester): Flow<List<GradeSummary>> {
return gradeSummaryDb.loadAll(semester.semesterId, semester.studentId)
}
fun getNotNotifiedFinalGrades(semester: Semester): Flow<List<GradeSummary>> {
return gradeSummaryDb.loadAll(semester.semesterId, semester.studentId).map { it.filter { gradeSummary -> !gradeSummary.isFinalGradeNotified } }
fun getGradesFinalFromDatabase(semester: Semester): Flow<List<GradeSummary>> {
return gradeSummaryDb.loadAll(semester.semesterId, semester.studentId)
}
suspend fun updateGrade(grade: Grade) {

View file

@ -17,6 +17,7 @@ import io.github.wulkanowy.utils.getRefreshKey
import io.github.wulkanowy.utils.init
import io.github.wulkanowy.utils.networkBoundResource
import io.github.wulkanowy.utils.uniqueSubtract
import kotlinx.coroutines.sync.Mutex
import java.util.Locale
import javax.inject.Inject
import javax.inject.Singleton
@ -30,11 +31,16 @@ class GradeStatisticsRepository @Inject constructor(
private val refreshHelper: AutoRefreshHelper,
) {
private val partialMutex = Mutex()
private val semesterMutex = Mutex()
private val pointsMutex = Mutex()
private val partialCacheKey = "grade_stats_partial"
private val semesterCacheKey = "grade_stats_semester"
private val pointsCacheKey = "grade_stats_points"
fun getGradesPartialStatistics(student: Student, semester: Semester, subjectName: String, forceRefresh: Boolean) = networkBoundResource(
mutex = partialMutex,
shouldFetch = { it.isEmpty() || forceRefresh || refreshHelper.isShouldBeRefreshed(getRefreshKey(partialCacheKey, semester)) },
query = { gradePartialStatisticsDb.loadAll(semester.semesterId, semester.studentId) },
fetch = {
@ -71,6 +77,7 @@ class GradeStatisticsRepository @Inject constructor(
)
fun getGradesSemesterStatistics(student: Student, semester: Semester, subjectName: String, forceRefresh: Boolean) = networkBoundResource(
mutex = semesterMutex,
shouldFetch = { it.isEmpty() || forceRefresh || refreshHelper.isShouldBeRefreshed(getRefreshKey(semesterCacheKey, semester)) },
query = { gradeSemesterStatisticsDb.loadAll(semester.semesterId, semester.studentId) },
fetch = {
@ -112,6 +119,7 @@ class GradeStatisticsRepository @Inject constructor(
)
fun getGradesPointsStatistics(student: Student, semester: Semester, subjectName: String, forceRefresh: Boolean) = networkBoundResource(
mutex = pointsMutex,
shouldFetch = { it.isEmpty() || forceRefresh || refreshHelper.isShouldBeRefreshed(getRefreshKey(pointsCacheKey, semester)) },
query = { gradePointsStatisticsDb.loadAll(semester.semesterId, semester.studentId) },
fetch = {

View file

@ -13,6 +13,7 @@ import io.github.wulkanowy.utils.monday
import io.github.wulkanowy.utils.networkBoundResource
import io.github.wulkanowy.utils.sunday
import io.github.wulkanowy.utils.uniqueSubtract
import kotlinx.coroutines.sync.Mutex
import java.time.LocalDate
import javax.inject.Inject
import javax.inject.Singleton
@ -24,19 +25,42 @@ class HomeworkRepository @Inject constructor(
private val refreshHelper: AutoRefreshHelper,
) {
private val saveFetchResultMutex = Mutex()
private val cacheKey = "homework"
fun getHomework(student: Student, semester: Semester, start: LocalDate, end: LocalDate, forceRefresh: Boolean) = networkBoundResource(
shouldFetch = { it.isEmpty() || forceRefresh || refreshHelper.isShouldBeRefreshed(getRefreshKey(cacheKey, semester, start, end)) },
query = { homeworkDb.loadAll(semester.semesterId, semester.studentId, start.monday, end.sunday) },
fun getHomework(
student: Student, semester: Semester,
start: LocalDate, end: LocalDate,
forceRefresh: Boolean, notify: Boolean = false
) = networkBoundResource(
mutex = saveFetchResultMutex,
shouldFetch = {
val isShouldBeRefreshed = refreshHelper.isShouldBeRefreshed(
key = getRefreshKey(cacheKey, semester, start, end)
)
it.isEmpty() || forceRefresh || isShouldBeRefreshed
},
query = {
homeworkDb.loadAll(
semesterId = semester.semesterId,
studentId = semester.studentId,
from = start.monday,
end = end.sunday
)
},
fetch = {
sdk.init(student).switchDiary(semester.diaryId, semester.schoolYear)
.getHomework(start.monday, end.sunday)
.mapToEntities(semester)
},
saveFetchResult = { old, new ->
val homeWorkToSave = (new uniqueSubtract old).onEach {
if (notify) it.isNotified = false
}
homeworkDb.deleteAll(old uniqueSubtract new)
homeworkDb.insertAll(new uniqueSubtract old)
homeworkDb.insertAll(homeWorkToSave)
refreshHelper.updateLastRefreshTimestamp(getRefreshKey(cacheKey, semester, start, end))
}
@ -47,4 +71,9 @@ class HomeworkRepository @Inject constructor(
isDone = !isDone
}))
}
fun getHomeworkFromDatabase(semester: Semester, start: LocalDate, end: LocalDate) =
homeworkDb.loadAll(semester.semesterId, semester.studentId, start.monday, end.sunday)
suspend fun updateHomework(homework: List<Homework>) = homeworkDb.updateAll(homework)
}

View file

@ -9,6 +9,8 @@ import io.github.wulkanowy.utils.init
import io.github.wulkanowy.utils.networkBoundResource
import kotlinx.coroutines.flow.first
import kotlinx.coroutines.flow.map
import kotlinx.coroutines.sync.Mutex
import java.time.LocalDate
import java.time.LocalDate.now
import javax.inject.Inject
import javax.inject.Singleton
@ -19,7 +21,10 @@ class LuckyNumberRepository @Inject constructor(
private val sdk: Sdk
) {
private val saveFetchResultMutex = Mutex()
fun getLuckyNumber(student: Student, forceRefresh: Boolean, notify: Boolean = false) = networkBoundResource(
mutex = saveFetchResultMutex,
shouldFetch = { it == null || forceRefresh },
query = { luckyNumberDb.load(student.studentId, now()) },
fetch = { sdk.init(student).getLuckyNumber(student.schoolShortName)?.mapToEntity(student) },
@ -33,6 +38,9 @@ class LuckyNumberRepository @Inject constructor(
}
)
fun getLuckyNumberHistory(student: Student, start: LocalDate, end: LocalDate) =
luckyNumberDb.getAll(student.studentId, start, end)
suspend fun getNotNotifiedLuckyNumber(student: Student) = luckyNumberDb.load(student.studentId, now()).map {
if (it?.isNotified == false) it else null
}.first()

View file

@ -1,8 +1,15 @@
package io.github.wulkanowy.data.repositories
import android.content.Context
import com.squareup.moshi.Moshi
import dagger.hilt.android.qualifiers.ApplicationContext
import io.github.wulkanowy.R
import io.github.wulkanowy.data.Resource
import io.github.wulkanowy.data.db.SharedPrefProvider
import io.github.wulkanowy.data.db.dao.MessageAttachmentDao
import io.github.wulkanowy.data.db.dao.MessagesDao
import io.github.wulkanowy.data.db.entities.Message
import io.github.wulkanowy.data.db.entities.MessageWithAttachment
import io.github.wulkanowy.data.db.entities.Recipient
import io.github.wulkanowy.data.db.entities.Semester
import io.github.wulkanowy.data.db.entities.Student
@ -10,6 +17,8 @@ import io.github.wulkanowy.data.enums.MessageFolder
import io.github.wulkanowy.data.enums.MessageFolder.RECEIVED
import io.github.wulkanowy.data.mappers.mapFromEntities
import io.github.wulkanowy.data.mappers.mapToEntities
import io.github.wulkanowy.data.pojos.MessageDraft
import io.github.wulkanowy.data.pojos.MessageDraftJsonAdapter
import io.github.wulkanowy.sdk.Sdk
import io.github.wulkanowy.sdk.pojo.Folder
import io.github.wulkanowy.sdk.pojo.SentMessage
@ -19,7 +28,7 @@ import io.github.wulkanowy.utils.init
import io.github.wulkanowy.utils.networkBoundResource
import io.github.wulkanowy.utils.uniqueSubtract
import kotlinx.coroutines.flow.Flow
import kotlinx.coroutines.flow.map
import kotlinx.coroutines.sync.Mutex
import timber.log.Timber
import java.time.LocalDateTime.now
import javax.inject.Inject
@ -30,27 +39,65 @@ class MessageRepository @Inject constructor(
private val messagesDb: MessagesDao,
private val messageAttachmentDao: MessageAttachmentDao,
private val sdk: Sdk,
@ApplicationContext private val context: Context,
private val refreshHelper: AutoRefreshHelper,
private val sharedPrefProvider: SharedPrefProvider,
private val moshi: Moshi,
) {
private val saveFetchResultMutex = Mutex()
private val cacheKey = "message"
@Suppress("UNUSED_PARAMETER")
fun getMessages(student: Student, semester: Semester, folder: MessageFolder, forceRefresh: Boolean, notify: Boolean = false) = networkBoundResource(
shouldFetch = { it.isEmpty() || forceRefresh || refreshHelper.isShouldBeRefreshed(getRefreshKey(cacheKey, student, folder)) },
fun getMessages(
student: Student, semester: Semester,
folder: MessageFolder, forceRefresh: Boolean, notify: Boolean = false
): Flow<Resource<List<Message>>> = networkBoundResource(
mutex = saveFetchResultMutex,
shouldFetch = {
it.isEmpty() || forceRefresh || refreshHelper.isShouldBeRefreshed(
getRefreshKey(cacheKey, student, folder)
)
},
query = { messagesDb.loadAll(student.id.toInt(), folder.id) },
fetch = { sdk.init(student).getMessages(Folder.valueOf(folder.name), now().minusMonths(3), now()).mapToEntities(student) },
fetch = {
sdk.init(student).getMessages(Folder.valueOf(folder.name), now().minusMonths(3), now())
.mapToEntities(student)
},
saveFetchResult = { old, new ->
messagesDb.deleteAll(old uniqueSubtract new)
messagesDb.insertAll((new uniqueSubtract old).onEach {
it.isNotified = !notify
})
messagesDb.updateAll(getMessagesWithReadByChange(old, new, !notify))
refreshHelper.updateLastRefreshTimestamp(getRefreshKey(cacheKey, student, folder))
}
)
fun getMessage(student: Student, message: Message, markAsRead: Boolean = false) = networkBoundResource(
private fun getMessagesWithReadByChange(
old: List<Message>, new: List<Message>,
setNotified: Boolean
): List<Message> {
val oldMeta = old.map { Triple(it, it.readBy, it.unreadBy) }
val newMeta = new.map { Triple(it, it.readBy, it.unreadBy) }
val updatedItems = newMeta uniqueSubtract oldMeta
return updatedItems.map {
val oldItem = old.find { item -> item.messageId == it.first.messageId }
it.first.apply {
id = oldItem?.id ?: 0
isNotified = oldItem?.isNotified ?: setNotified
content = oldItem?.content.orEmpty()
}
}
}
fun getMessage(
student: Student, message: Message, markAsRead: Boolean = false
): Flow<Resource<MessageWithAttachment?>> = networkBoundResource(
shouldFetch = {
checkNotNull(it, { "This message no longer exist!" })
Timber.d("Message content in db empty: ${it.message.content.isEmpty()}")
@ -58,14 +105,20 @@ class MessageRepository @Inject constructor(
},
query = { messagesDb.loadMessageWithAttachment(student.id.toInt(), message.messageId) },
fetch = {
sdk.init(student).getMessageDetails(it!!.message.messageId, message.folderId, markAsRead, message.realId).let { details ->
sdk.init(student).getMessageDetails(
messageId = it!!.message.messageId,
folderId = message.folderId,
read = markAsRead,
id = message.realId
).let { details ->
details.content to details.attachments.mapToEntities()
}
},
saveFetchResult = { old, (downloadedMessage, attachments) ->
checkNotNull(old, { "Fetched message no longer exist!" })
messagesDb.updateAll(listOf(old.message.copy(unread = !markAsRead).apply {
messagesDb.updateAll(listOf(old.message.apply {
id = old.message.id
unread = !markAsRead
content = content.ifBlank { downloadedMessage }
}))
messageAttachmentDao.insertAttachments(attachments)
@ -73,30 +126,42 @@ class MessageRepository @Inject constructor(
}
)
fun getNotNotifiedMessages(student: Student): Flow<List<Message>> {
return messagesDb.loadAll(student.id.toInt(), RECEIVED.id).map { it.filter { message -> !message.isNotified && message.unread } }
fun getMessagesFromDatabase(student: Student): Flow<List<Message>> {
return messagesDb.loadAll(student.id.toInt(), RECEIVED.id)
}
suspend fun updateMessages(messages: List<Message>) {
return messagesDb.updateAll(messages)
}
suspend fun sendMessage(student: Student, subject: String, content: String, recipients: List<Recipient>): SentMessage {
return sdk.init(student).sendMessage(
subject = subject,
content = content,
recipients = recipients.mapFromEntities()
)
}
suspend fun sendMessage(
student: Student, subject: String, content: String,
recipients: List<Recipient>
): SentMessage = sdk.init(student).sendMessage(
subject = subject,
content = content,
recipients = recipients.mapFromEntities()
)
suspend fun deleteMessage(student: Student, message: Message) {
val isDeleted = sdk.init(student).deleteMessages(listOf(message.messageId), message.folderId)
val isDeleted = sdk.init(student).deleteMessages(
messages = listOf(message.messageId), message.folderId
)
if (message.folderId != MessageFolder.TRASHED.id) {
if (isDeleted) messagesDb.updateAll(listOf(message.copy(folderId = MessageFolder.TRASHED.id).apply {
if (message.folderId != MessageFolder.TRASHED.id && isDeleted) {
val deletedMessage = message.copy(folderId = MessageFolder.TRASHED.id).apply {
id = message.id
content = message.content
}))
}
messagesDb.updateAll(listOf(deletedMessage))
} else messagesDb.deleteAll(listOf(message))
}
var draftMessage: MessageDraft?
get() = sharedPrefProvider.getString(context.getString(R.string.pref_key_message_send_draft))
?.let { MessageDraftJsonAdapter(moshi).fromJson(it) }
set(value) = sharedPrefProvider.putString(
context.getString(R.string.pref_key_message_send_draft),
value?.let { MessageDraftJsonAdapter(moshi).toJson(it) }
)
}

View file

@ -13,6 +13,7 @@ import io.github.wulkanowy.utils.getRefreshKey
import io.github.wulkanowy.utils.init
import io.github.wulkanowy.utils.networkBoundResource
import io.github.wulkanowy.utils.uniqueSubtract
import kotlinx.coroutines.sync.Mutex
import javax.inject.Inject
import javax.inject.Singleton
@ -23,9 +24,12 @@ class MobileDeviceRepository @Inject constructor(
private val refreshHelper: AutoRefreshHelper,
) {
private val saveFetchResultMutex = Mutex()
private val cacheKey = "devices"
fun getDevices(student: Student, semester: Semester, forceRefresh: Boolean) = networkBoundResource(
mutex = saveFetchResultMutex,
shouldFetch = { it.isEmpty() || forceRefresh || refreshHelper.isShouldBeRefreshed(getRefreshKey(cacheKey, student)) },
query = { mobileDb.loadAll(student.userLoginId.takeIf { it != 0 } ?: student.studentId) },
fetch = {

View file

@ -13,6 +13,7 @@ import io.github.wulkanowy.utils.networkBoundResource
import io.github.wulkanowy.utils.uniqueSubtract
import kotlinx.coroutines.flow.Flow
import kotlinx.coroutines.flow.map
import kotlinx.coroutines.sync.Mutex
import javax.inject.Inject
import javax.inject.Singleton
@ -23,9 +24,12 @@ class NoteRepository @Inject constructor(
private val refreshHelper: AutoRefreshHelper,
) {
private val saveFetchResultMutex = Mutex()
private val cacheKey = "note"
fun getNotes(student: Student, semester: Semester, forceRefresh: Boolean, notify: Boolean = false) = networkBoundResource(
mutex = saveFetchResultMutex,
shouldFetch = { it.isEmpty() || forceRefresh || refreshHelper.isShouldBeRefreshed(getRefreshKey(cacheKey, semester)) },
query = { noteDb.loadAll(student.studentId) },
fetch = {
@ -46,8 +50,8 @@ class NoteRepository @Inject constructor(
}
)
fun getNotNotifiedNotes(student: Student): Flow<List<Note>> {
return noteDb.loadAll(student.studentId).map { it.filter { note -> !note.isNotified } }
fun getNotesFromDatabase(student: Student): Flow<List<Note>> {
return noteDb.loadAll(student.studentId)
}
suspend fun updateNote(note: Note) {

View file

@ -2,42 +2,83 @@ package io.github.wulkanowy.data.repositories
import android.content.Context
import android.content.SharedPreferences
import androidx.core.content.edit
import com.fredporciuncula.flow.preferences.FlowSharedPreferences
import com.fredporciuncula.flow.preferences.Preference
import com.squareup.moshi.JsonAdapter
import com.squareup.moshi.Moshi
import com.squareup.moshi.adapter
import dagger.hilt.android.qualifiers.ApplicationContext
import io.github.wulkanowy.R
import io.github.wulkanowy.sdk.toLocalDate
import io.github.wulkanowy.ui.modules.dashboard.DashboardItem
import io.github.wulkanowy.ui.modules.grade.GradeAverageMode
import io.github.wulkanowy.ui.modules.grade.GradeSortingMode
import io.github.wulkanowy.utils.toTimestamp
import io.github.wulkanowy.utils.toLocalDateTime
import io.github.wulkanowy.utils.toTimestamp
import kotlinx.coroutines.ExperimentalCoroutinesApi
import kotlinx.coroutines.flow.Flow
import kotlinx.coroutines.flow.map
import java.time.LocalDate
import java.time.LocalDateTime
import javax.inject.Inject
import javax.inject.Singleton
@OptIn(ExperimentalCoroutinesApi::class)
@Singleton
class PreferencesRepository @Inject constructor(
private val sharedPref: SharedPreferences,
@ApplicationContext val context: Context
private val flowSharedPref: FlowSharedPreferences,
@ApplicationContext val context: Context,
moshi: Moshi
) {
@OptIn(ExperimentalStdlibApi::class)
private val dashboardItemsPositionAdapter: JsonAdapter<Map<DashboardItem.Type, Int>> =
moshi.adapter()
val startMenuIndex: Int
get() = getString(R.string.pref_key_start_menu, R.string.pref_default_startup).toInt()
val isShowPresent: Boolean
get() = getBoolean(R.string.pref_key_attendance_present, R.bool.pref_default_attendance_present)
get() = getBoolean(
R.string.pref_key_attendance_present,
R.bool.pref_default_attendance_present
)
val gradeAverageMode: GradeAverageMode
get() = GradeAverageMode.getByValue(getString(R.string.pref_key_grade_average_mode, R.string.pref_default_grade_average_mode))
get() = GradeAverageMode.getByValue(
getString(
R.string.pref_key_grade_average_mode,
R.string.pref_default_grade_average_mode
)
)
val gradeAverageForceCalc: Boolean
get() = getBoolean(R.string.pref_key_grade_average_force_calc, R.bool.pref_default_grade_average_force_calc)
get() = getBoolean(
R.string.pref_key_grade_average_force_calc,
R.bool.pref_default_grade_average_force_calc
)
val isGradeExpandable: Boolean
get() = !getBoolean(R.string.pref_key_expand_grade, R.bool.pref_default_expand_grade)
val showAllSubjectsOnStatisticsList: Boolean
get() = getBoolean(R.string.pref_key_grade_statistics_list, R.bool.pref_default_grade_statistics_list)
get() = getBoolean(
R.string.pref_key_grade_statistics_list,
R.bool.pref_default_grade_statistics_list
)
val appThemeKey = context.getString(R.string.pref_key_app_theme)
val appTheme: String
get() = getString(appThemeKey, R.string.pref_default_app_theme)
val gradeColorTheme: String
get() = getString(R.string.pref_key_grade_color_scheme, R.string.pref_default_grade_color_scheme)
get() = getString(
R.string.pref_key_grade_color_scheme,
R.string.pref_default_grade_color_scheme
)
val appLanguageKey = context.getString(R.string.pref_key_app_language)
val appLanguage
@ -55,50 +96,170 @@ class PreferencesRepository @Inject constructor(
val isServicesOnlyWifi: Boolean
get() = getBoolean(servicesOnlyWifiKey, R.bool.pref_default_services_wifi_only)
val notificationsEnableKey = context.getString(R.string.pref_key_notifications_enable)
val isNotificationsEnable: Boolean
get() = getBoolean(R.string.pref_key_notifications_enable, R.bool.pref_default_notifications_enable)
get() = getBoolean(notificationsEnableKey, R.bool.pref_default_notifications_enable)
val isUpcomingLessonsNotificationsEnableKey = context.getString(R.string.pref_key_notifications_upcoming_lessons_enable)
val isUpcomingLessonsNotificationsEnableKey =
context.getString(R.string.pref_key_notifications_upcoming_lessons_enable)
val isUpcomingLessonsNotificationsEnable: Boolean
get() = getBoolean(isUpcomingLessonsNotificationsEnableKey, R.bool.pref_default_notification_upcoming_lessons_enable)
get() = getBoolean(
isUpcomingLessonsNotificationsEnableKey,
R.bool.pref_default_notification_upcoming_lessons_enable
)
val isDebugNotificationEnableKey = context.getString(R.string.pref_key_notification_debug)
val isDebugNotificationEnable: Boolean
get() = getBoolean(isDebugNotificationEnableKey, R.bool.pref_default_notification_debug)
val gradePlusModifier: Double
get() = getString(R.string.pref_key_grade_modifier_plus, R.string.pref_default_grade_modifier_plus).toDouble()
get() = getString(
R.string.pref_key_grade_modifier_plus,
R.string.pref_default_grade_modifier_plus
).toDouble()
val gradeMinusModifier: Double
get() = getString(R.string.pref_key_grade_modifier_minus, R.string.pref_default_grade_modifier_minus).toDouble()
get() = getString(
R.string.pref_key_grade_modifier_minus,
R.string.pref_default_grade_modifier_minus
).toDouble()
val fillMessageContent: Boolean
get() = getBoolean(R.string.pref_key_fill_message_content, R.bool.pref_default_fill_message_content)
get() = getBoolean(
R.string.pref_key_fill_message_content,
R.bool.pref_default_fill_message_content
)
val showGroupsInPlan: Boolean
get() = getBoolean(R.string.pref_key_timetable_show_groups, R.bool.pref_default_timetable_show_groups)
get() = getBoolean(
R.string.pref_key_timetable_show_groups,
R.bool.pref_default_timetable_show_groups
)
val showWholeClassPlan: String
get() = getString(R.string.pref_key_timetable_show_whole_class, R.string.pref_default_timetable_show_whole_class)
get() = getString(
R.string.pref_key_timetable_show_whole_class,
R.string.pref_default_timetable_show_whole_class
)
val gradeSortingMode: GradeSortingMode
get() = GradeSortingMode.getByValue(getString(R.string.pref_key_grade_sorting_mode, R.string.pref_default_grade_sorting_mode))
get() = GradeSortingMode.getByValue(
getString(
R.string.pref_key_grade_sorting_mode,
R.string.pref_default_grade_sorting_mode
)
)
val showTimetableTimers: Boolean
get() = getBoolean(R.string.pref_key_timetable_show_timers, R.bool.pref_default_timetable_show_timers)
get() = getBoolean(
R.string.pref_key_timetable_show_timers,
R.bool.pref_default_timetable_show_timers
)
var isHomeworkFullscreen: Boolean
get() = getBoolean(R.string.pref_key_homework_fullscreen, R.bool.pref_default_homework_fullscreen)
get() = getBoolean(
R.string.pref_key_homework_fullscreen,
R.bool.pref_default_homework_fullscreen
)
set(value) = sharedPref.edit().putBoolean("homework_fullscreen", value).apply()
val showSubjectsWithoutGrades: Boolean
get() = getBoolean(R.string.pref_key_subjects_without_grades, R.bool.pref_default_subjects_without_grades)
get() = getBoolean(
R.string.pref_key_subjects_without_grades,
R.bool.pref_default_subjects_without_grades
)
val isOptionalArithmeticAverage: Boolean
get() = getBoolean(
R.string.pref_key_optional_arithmetic_average,
R.bool.pref_default_optional_arithmetic_average
)
var lasSyncDate: LocalDateTime
get() = getLong(
R.string.pref_key_last_sync_date,
R.string.pref_default_last_sync_date
).toLocalDateTime()
set(value) = sharedPref.edit().putLong("last_sync_date", value.toTimestamp()).apply()
var dashboardItemsPosition: Map<DashboardItem.Type, Int>?
get() {
val json = sharedPref.getString(PREF_KEY_DASHBOARD_ITEMS_POSITION, null) ?: return null
return dashboardItemsPositionAdapter.fromJson(json)
}
set(value) = sharedPref.edit {
putString(
PREF_KEY_DASHBOARD_ITEMS_POSITION,
dashboardItemsPositionAdapter.toJson(value)
)
}
val selectedDashboardTilesFlow: Flow<Set<DashboardItem.Tile>>
get() = selectedDashboardTilesPreference.asFlow()
.map { set ->
set.map { DashboardItem.Tile.valueOf(it) }
.plus(DashboardItem.Tile.ACCOUNT)
.toSet()
}
var selectedDashboardTiles: Set<DashboardItem.Tile>
get() = selectedDashboardTilesPreference.get()
.map { DashboardItem.Tile.valueOf(it) }
.plus(DashboardItem.Tile.ACCOUNT)
.toSet()
set(value) {
val filteredValue = value.filterNot { it == DashboardItem.Tile.ACCOUNT }
.map { it.name }
.toSet()
selectedDashboardTilesPreference.set(filteredValue)
}
private val selectedDashboardTilesPreference: Preference<Set<String>>
get() {
val defaultSet =
context.resources.getStringArray(R.array.pref_default_dashboard_tiles).toSet()
val prefKey = context.getString(R.string.pref_key_dashboard_tiles)
return flowSharedPref.getStringSet(prefKey, defaultSet)
}
var inAppReviewCount: Int
get() = sharedPref.getInt(PREF_KEY_IN_APP_REVIEW_COUNT, 0)
set(value) = sharedPref.edit().putInt(PREF_KEY_IN_APP_REVIEW_COUNT, value).apply()
var inAppReviewDate: LocalDate?
get() = sharedPref.getLong(PREF_KEY_IN_APP_REVIEW_DATE, 0).takeIf { it != 0L }?.toLocalDate()
set(value) = sharedPref.edit().putLong(PREF_KEY_IN_APP_REVIEW_DATE, value!!.toTimestamp()).apply()
var isAppReviewDone: Boolean
get() = sharedPref.getBoolean(PREF_KEY_IN_APP_REVIEW_DONE, false)
set(value) = sharedPref.edit().putBoolean(PREF_KEY_IN_APP_REVIEW_DONE, value).apply()
private fun getLong(id: Int, default: Int) = getLong(context.getString(id), default)
private fun getLong(id: String, default: Int) =
sharedPref.getLong(id, context.resources.getString(default).toLong())
private fun getString(id: Int, default: Int) = getString(context.getString(id), default)
private fun getString(id: String, default: Int) = sharedPref.getString(id, context.getString(default)) ?: context.getString(default)
private fun getString(id: String, default: Int) =
sharedPref.getString(id, context.getString(default)) ?: context.getString(default)
private fun getBoolean(id: Int, default: Int) = getBoolean(context.getString(id), default)
private fun getBoolean(id: String, default: Int) = sharedPref.getBoolean(id, context.resources.getBoolean(default))
private fun getBoolean(id: String, default: Int) =
sharedPref.getBoolean(id, context.resources.getBoolean(default))
private companion object {
private const val PREF_KEY_DASHBOARD_ITEMS_POSITION = "dashboard_items_position"
private const val PREF_KEY_IN_APP_REVIEW_COUNT = "in_app_review_count"
private const val PREF_KEY_IN_APP_REVIEW_DATE = "in_app_review_date"
private const val PREF_KEY_IN_APP_REVIEW_DONE = "in_app_review_done"
}
}

View file

@ -19,22 +19,22 @@ class RecipientRepository @Inject constructor(
) {
suspend fun refreshRecipients(student: Student, unit: ReportingUnit, role: Int) {
val new = sdk.init(student).getRecipients(unit.unitId, role).mapToEntities(unit.senderId)
val old = recipientDb.loadAll(unit.senderId, unit.unitId, role)
val new = sdk.init(student).getRecipients(unit.unitId, role).mapToEntities(unit.studentId)
val old = recipientDb.loadAll(unit.studentId, unit.unitId, role)
recipientDb.deleteAll(old uniqueSubtract new)
recipientDb.insertAll(new uniqueSubtract old)
}
suspend fun getRecipients(student: Student, unit: ReportingUnit, role: Int): List<Recipient> {
return recipientDb.loadAll(unit.senderId, unit.unitId, role).ifEmpty {
return recipientDb.loadAll(unit.studentId, unit.unitId, role).ifEmpty {
refreshRecipients(student, unit, role)
recipientDb.loadAll(unit.senderId, unit.unitId, role)
recipientDb.loadAll(unit.studentId, unit.unitId, role)
}
}
suspend fun getMessageRecipients(student: Student, message: Message): List<Recipient> {
return sdk.init(student).getMessageRecipients(message.messageId, message.senderId).mapToEntities(student.userLoginId)
return sdk.init(student).getMessageRecipients(message.messageId, message.senderId).mapToEntities(student.studentId)
}
}

View file

@ -18,25 +18,25 @@ class ReportingUnitRepository @Inject constructor(
suspend fun refreshReportingUnits(student: Student) {
val new = sdk.init(student).getReportingUnits().mapToEntities(student)
val old = reportingUnitDb.load(student.studentId)
val old = reportingUnitDb.load(student.id.toInt())
reportingUnitDb.deleteAll(old.uniqueSubtract(new))
reportingUnitDb.insertAll(new.uniqueSubtract(old))
}
suspend fun getReportingUnits(student: Student): List<ReportingUnit> {
return reportingUnitDb.load(student.studentId).ifEmpty {
return reportingUnitDb.load(student.id.toInt()).ifEmpty {
refreshReportingUnits(student)
reportingUnitDb.load(student.studentId)
reportingUnitDb.load(student.id.toInt())
}
}
suspend fun getReportingUnit(student: Student, unitId: Int): ReportingUnit? {
return reportingUnitDb.loadOne(student.studentId, unitId) ?: run {
return reportingUnitDb.loadOne(student.id.toInt(), unitId) ?: run {
refreshReportingUnits(student)
return reportingUnitDb.loadOne(student.studentId, unitId)
return reportingUnitDb.loadOne(student.id.toInt(), unitId)
}
}
}

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