Compare commits

...

322 commits

Author SHA1 Message Date
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
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
Faierbel
2c442fc87b Merge branch 'release/1.0.1' 2021-02-16 12:44:34 +01:00
Faierbel
44ba0d76de Version 1.0.1 2021-02-16 12:44:24 +01:00
Rafał Borcz
17aa77ad41
New Crowdin updates (#1152) 2021-02-16 12:12:35 +01:00
dependabot-preview[bot]
c18302b812
Bump junit from 4.13.1 to 4.13.2 (#1150) 2021-02-14 12:14:28 +00:00
dependabot-preview[bot]
de8e9bde49
Bump mockk from 1.10.5 to 1.10.6 (#1149) 2021-02-14 12:13:21 +00:00
Rafał Borcz
000cbd11a2
Fix EOF error in messages (#1145) 2021-02-13 20:39:52 +01:00
Rafał Borcz
5e3b89636f
Add checking vulcan average from both semesters (#1140) 2021-02-13 12:33:53 +01:00
Rafał Borcz
dd085a14fa
Revert "Bump fragment-ktx from 1.2.5 to 1.3.0 (#1138)" (#1144)
This reverts commit cac76857c4.
2021-02-13 10:58:01 +00:00
Rafał Borcz
bfe558d887
Update README (#1143) 2021-02-12 19:14:45 +01:00
Rafał Borcz
4841a0439d
New Crowdin updates (#1131) 2021-02-12 19:07:36 +01:00
dependabot-preview[bot]
cac76857c4
Bump fragment-ktx from 1.2.5 to 1.3.0 (#1138) 2021-02-12 18:05:33 +00:00
dependabot-preview[bot]
6b8b7c9143
Bump material from 1.3.0-rc01 to 1.3.0 (#1137) 2021-02-12 10:12:35 +01:00
dependabot-preview[bot]
53584026dc
Bump about_libraries from 8.7.0 to 8.8.2 (#1135) 2021-02-12 09:11:52 +00:00
dependabot-preview[bot]
7900ad913f
Bump kotlin_version from 1.4.21 to 1.4.30 (#1139) 2021-02-11 12:20:45 +00:00
Mikołaj Pich
8ec844a8fe Merge branch 'release/1.0.0' into develop 2021-02-07 23:48:43 +01:00
Mikołaj Pich
19ff953ab2 Merge branch 'release/1.0.0' 2021-02-07 23:48:38 +01:00
Mikołaj Pich
e29c211cf2 Version 1.0.0 2021-02-07 23:48:32 +01:00
Mikołaj Pich
2492a9c204
Update screenshots (#1130) 2021-02-07 22:08:39 +00:00
Rafał Borcz
61de1de532
New Crowdin updates (#1129) 2021-02-07 12:01:34 +00:00
Mikołaj Pich
b5862da776 Merge branch 'release/0.25.1' into develop 2021-02-06 16:54:26 +01:00
Mikołaj Pich
e0c802bf67 Merge branch 'release/0.25.1' 2021-02-06 16:54:22 +01:00
Mikołaj Pich
dcac138ff8 Version 0.25.1 2021-02-06 16:54:17 +01:00
Rafał Borcz
23411a608f
Fix nullable student guardians (#1128) 2021-02-06 16:19:50 +01:00
MRmlik12
87facd2663
Add MRmlik12 to contributors (#1126) 2021-02-05 15:49:29 +00:00
MRmlik12
bad0776cab
Add final average grades calculation with modifiers (#1125) 2021-02-05 10:50:35 +01:00
Rafał Borcz
a063aabc7c
Ignore webview init exceptions (#1124) 2021-02-03 20:59:24 +01:00
Mikołaj Pich
1fdbdf34b9 Merge branch 'release/0.25.0' into develop 2021-02-02 00:47:40 +01:00
Mikołaj Pich
624fd71dbb Merge branch 'release/0.25.0' 2021-02-02 00:47:35 +01:00
Mikołaj Pich
dfa10883d3 Version 0.25.0 2021-02-02 00:47:30 +01:00
Rafał Borcz
aff40df707
New Crowdin updates (#1095) 2021-02-02 00:25:27 +01:00
Mateusz Idziejczak
42f9594210
Fix empty message bug (#1122) 2021-02-02 00:11:34 +01:00
Rafał Borcz
3e3a080b70
Add nick for student (#1119) 2021-02-01 23:58:44 +01:00
Mateusz Idziejczak
39534aeda4
Add dark mode to swipe refresh layout (#1118) 2021-02-01 18:13:11 +01:00
Dominik Korsa
e39b053d2d
Change timetable icon (#1115) 2021-02-01 13:15:36 +01:00
Mateusz Idziejczak
28fd7460cb
Replace progressBar with CircularProgressIndicator (#1117) 2021-02-01 11:45:10 +01:00
Rafał Borcz
82b207b03a
Fix follow system language setting (#1113) 2021-01-31 22:38:30 +01:00
Mikołaj Pich
4984cb9b26
Update auto update priority policy (#1051) 2021-01-31 20:46:24 +00:00
Mikołaj Pich
e2ba265048
Add build date to version info (#1114) 2021-01-31 17:12:38 +01:00
Rafał Borcz
d1cd497a23
Fix null data in Status.SUCCESS in emission from average provider (#1105) 2021-01-30 16:07:37 +01:00
Rafał Borcz
dd5ce752da
Update gradle and build tools (#1108) 2021-01-30 15:26:31 +01:00
dependabot-preview[bot]
e5e95e7dec
Bump room from 2.3.0-alpha04 to 2.3.0-beta01 (#1112) 2021-01-30 14:22:08 +00:00
dependabot-preview[bot]
f5e4c63fed
Bump about_libraries from 8.6.9 to 8.7.0 (#1111) 2021-01-30 14:18:28 +00:00
dependabot-preview[bot]
70d42bb864
Bump agcp from 1.4.2.301 to 1.5.0.200 (#1109) 2021-01-30 14:14:08 +00:00
dependabot-preview[bot]
82df5b9515
Bump agconnect-crash from 1.4.2.301 to 1.5.0.200 (#1110) 2021-01-30 14:13:35 +00:00
dependabot-preview[bot]
6568c4abf8
Bump hilt-work from 1.0.0-alpha02 to 1.0.0-alpha03 (#1099) 2021-01-29 21:24:30 +00:00
Rafał Borcz
d79b1c9a58
Add account manager (#671) 2021-01-29 21:53:46 +01:00
dependabot-preview[bot]
26565b627a
Bump work_manager from 2.4.0 to 2.5.0 (#1103) 2021-01-28 20:58:15 +00:00
dependabot-preview[bot]
c0a53cb90c
Bump sonarqube-gradle-plugin from 3.1 to 3.1.1 (#1100) 2021-01-28 20:57:53 +00:00
dependabot-preview[bot]
2bcbac5ab3
Bump about_libraries from 8.6.7 to 8.6.9 (#1098) 2021-01-28 20:57:22 +00:00
dependabot-preview[bot]
5581fdcab8
Bump google-services from 4.3.4 to 4.3.5 (#1104) 2021-01-28 20:56:54 +00:00
dependabot-preview[bot]
6a8161cd98
Bump firebase-bom from 26.3.0 to 26.4.0 (#1102) 2021-01-28 20:26:38 +00:00
Rafał Borcz
e0b067fadd
Fix selected semester after change account (#1097) 2021-01-27 00:18:56 +01:00
Damian Czupryn
f37ddfe00f
Disable vibrations in data picker (#1093) 2021-01-24 20:01:18 +01:00
dependabot-preview[bot]
3a887f597b
Bump hilt_version from 2.30.1-alpha to 2.31.2-alpha (#1094) 2021-01-24 16:52:16 +00:00
Mikołaj Pich
52d359827e
Fix translations of month name in attendance summary (#1091) 2021-01-24 17:21:02 +01:00
Mikołaj Pich
a70ccbb0d0
Make strings in grade class stats translatable (#1092) 2021-01-24 17:20:26 +01:00
Mikołaj Pich
2b6386c522 Merge branch 'release/0.24.3' into develop 2021-01-21 14:24:45 +01:00
Mikołaj Pich
60ae14719d Merge branch 'release/0.24.3' 2021-01-21 14:24:41 +01:00
Mikołaj Pich
a4594b2853 Version 0.24.3 2021-01-21 14:14:39 +01:00
Mikołaj Pich
6578d2eb49 Merge branch 'release/0.24.2' into develop 2021-01-21 13:49:48 +01:00
Mikołaj Pich
e543c0aa2c Merge branch 'release/0.24.2' 2021-01-21 13:49:42 +01:00
Mikołaj Pich
17c80416fe Version 0.24.2 2021-01-21 13:49:35 +01:00
Mikołaj Pich
f2cb7f741b Merge branch 'release/0.24.1' into develop 2021-01-21 10:46:20 +01:00
Mikołaj Pich
51d9e9b9af Merge branch 'release/0.24.1' 2021-01-21 10:46:16 +01:00
Mikołaj Pich
b1e1b801b5 Version 0.24.1 2021-01-21 10:46:11 +01:00
Mikołaj Pich
04ff05c22a
Fix google play deploy config (#1089) 2021-01-21 10:24:38 +01:00
Mikołaj Pich
81c9144448 Merge branch 'release/0.24.0' into develop 2021-01-20 18:29:24 +01:00
Mikołaj Pich
70d456a6dc Merge branch 'release/0.24.0' 2021-01-20 18:29:19 +01:00
Mikołaj Pich
b55c05aaed Version 0.24.0 2021-01-20 18:29:13 +01:00
Rafał Borcz
01fd146c99
New Crowdin updates (#1088) 2021-01-20 18:03:18 +01:00
Rafał Borcz
5d849b3ada
Fix endless loading in grades (#1084) 2021-01-20 17:42:19 +01:00
dependabot-preview[bot]
1a4eaec47f
Bump gradle from 4.1.1 to 4.1.2 (#1086) 2021-01-20 10:53:33 +00:00
dependabot-preview[bot]
5b9d40a4f9
Bump about_libraries from 8.6.6 to 8.6.7 (#1085) 2021-01-20 10:50:20 +00:00
Mateusz Idziejczak
e6e9d201ce
Show appropriate message when message does not exist (#1083) 2021-01-20 11:49:06 +01:00
dependabot-preview[bot]
9128e0b55f
Bump about_libraries from 8.6.5 to 8.6.6 (#1080) 2021-01-16 14:10:49 +00:00
dependabot-preview[bot]
7f893a8868
Bump hianalytics from 5.1.0.300 to 5.1.0.301 (#1082) 2021-01-16 13:54:36 +00:00
dependabot-preview[bot]
89f92ed027
Bump sonarqube-gradle-plugin from 3.0 to 3.1 (#1081) 2021-01-16 13:52:33 +00:00
dependabot-preview[bot]
99e06f6539
Bump mockk from 1.10.4 to 1.10.5 (#1077) 2021-01-16 13:24:15 +00:00
dependabot-preview[bot]
12da5e5381
Bump firebase-bom from 26.2.0 to 26.3.0 (#1078) 2021-01-16 13:04:54 +00:00
Mikołaj Pich
a7bb026c1b
Use senderId to differentiate saved recipients between accounts (#1075) 2021-01-14 18:37:02 +01:00
Mikołaj Pich
8ce59a3098
Use userLoginId to differentiate saved mobiles devices between accounts (#1076) 2021-01-14 18:36:32 +01:00
Mikołaj Pich
a1d4b3d19e
Auto-refresh displayed data after some time (#1068)
* Auto-refresh displayed data after some time

* Use refresh interval from settings

* Auto-refresh exams

* Add refresh utils

* Auto-refresh timetable

* Auto-refresh grade details and summary

* Auto-refresh grades

* Auto-refresh attendance summary

* Add cacheKey variables

* Auto-refres completed lessons

* Auto-refres conferences

* Auto-refres homework

* Auto-refresh messages

* Auto-refresh mobile devices

* Auto-refresh notes

* Fix tests

* Fix instrumentation tests

* Create AutoRefreshHelper
2021-01-13 10:01:45 +00:00
dependabot-preview[bot]
64cc49055b
Bump coil from 1.1.0 to 1.1.1 (#1072) 2021-01-13 09:47:46 +00:00
dependabot-preview[bot]
91ece39517
Bump about_libraries from 8.6.3 to 8.6.5 (#1074) 2021-01-13 07:25:59 +00:00
Mikołaj Pich
a99e742472
Handle URLs from FCM push notification (#1070) 2021-01-11 10:41:17 +01:00
Mikołaj Pich
d332369872
Disable force dark theme on Android >9 (#1071) 2021-01-11 09:53:19 +01:00
Mikołaj Pich
205bcf9c22
Use work-gcm dependency in play flavor only (#1069) 2021-01-11 09:52:44 +01:00
dependabot-preview[bot]
344d404238
Bump hianalytics from 5.0.5.301 to 5.1.0.300 (#1060) 2021-01-05 04:37:48 +00:00
Mikołaj Pich
8b2dc514f4
Use Firebase Android BoM (#1064)
* Use Firebase Android BoM

* Use androidx-bom to resolve androidx versions

* Revert "Use androidx-bom to resolve androidx versions"

This reverts commit 55a79a61cfa55090e157c66d4aed94322d44ac69.
2021-01-03 23:21:25 +00:00
Mikołaj Pich
bee62d4769
Remove remote and local repositories (#1065)
* Remove remote and local repos

* Move repositories out of sub-packages

* Update chucker config

* Move repositories tests from androidTest to unit tests

* Rewrite grades tests

* Fix more tests

* Update grade statistics tests
2021-01-03 23:13:50 +00:00
dependabot-preview[bot]
fb36fb379a
Bump room from 2.2.5 to 2.2.6 (#1058) 2021-01-03 22:57:41 +00:00
dependabot-preview[bot]
a2c4f4a51d
Bump mockk from 1.10.3-jdk8 to 1.10.4 (#1059) 2021-01-02 12:49:57 +00:00
Rafał Borcz
b0d713dc0c
New Crowdin updates (#1053) 2020-12-28 23:34:35 +01:00
Mikołaj Pich
5a2a0e3d6d
Github workflow config improvements (#1056) 2020-12-28 22:45:21 +01:00
Mikołaj Pich
7fe638130e
Configure github actions (#1055)
* Create test.yml

* Change list of emulator api levels

* Downgrade emulator with api 30 to 29

* Exclude jdk.internal in jacoco config

* Use jdk 15

* Downgrade jdk to 11 due to jacoco incompatibility

gradle/gradle#15038

* Fix tests on jdk11

* Add codecov

* Add missing jacoco report generaction command

* Add flags to codecov uploads

* Add deploy config

* Replace travis badge with gh actions badge

* Add info about coroutines to readme, replace dagger with hilt

* Decrease instrumentation tests to 15 minutes

* Skip duplicate actions

* Remove comment

* Change os of instrumentation tests

* Downgrade android emulator runner to v2.13.0

* Add pre-build job

* Pass prebuild files between jobs

* Fix gh actions yaml config

* Tar build cache

* Fix upload-artifact filename

* Fix prebuild cache name

* Add more to cache, change cache key
2020-12-27 17:30:50 +00:00
Mikołaj Pich
9763208688
Add additional lessons to timetable (#1019) 2020-12-27 14:06:07 +01:00
Rafał Borcz
295fd0fd90
Add language event (#1052)
* Add log event to language

* Add log event to app
2020-12-26 22:40:21 +01:00
Mikołaj Pich
c052f31424 Merge branch 'release/0.23.1' into develop 2020-12-16 21:19:57 +01:00
Mikołaj Pich
3486d52a26 Merge branch 'release/0.23.1' 2020-12-16 21:19:52 +01:00
Mikołaj Pich
88c5c7d9dc Version 0.23.1 2020-12-16 21:19:47 +01:00
Mikołaj Pich
315e9b0595
Fix username label on registers other than default (#1050) 2020-12-16 20:48:01 +01:00
Rafał Borcz
3eba89aeb9
Disable recordException in HMS (#1048) 2020-12-10 21:12:59 +01:00
Rafał Borcz
1680ad233e
New translations strings.xml (Czech) (#1049) 2020-12-10 21:12:14 +01:00
dependabot-preview[bot]
93bc4e92a9
Bump kotlin_version from 1.4.20 to 1.4.21 (#1047) 2020-12-09 15:38:06 +00:00
Mikołaj Pich
7536f98e6e Merge branch 'release/0.23.0' into develop 2020-12-06 22:21:42 +01:00
Mikołaj Pich
afee97a706 Merge branch 'release/0.23.0' 2020-12-06 22:21:36 +01:00
Mikołaj Pich
73a92497ed Version 0.23.0 2020-12-06 22:12:18 +01:00
Mikołaj Pich
67cef0f6d9
Add register variant auto-matching based on email (#1041) 2020-12-06 21:23:02 +01:00
Rafał Borcz
6ca5e11371
Fix HMS analytics and crashlytics (#1042) 2020-12-06 19:31:35 +01:00
dependabot-preview[bot]
05a597313b
Bump hilt_version from 2.29.1-alpha to 2.30.1-alpha (#1035) 2020-12-06 17:54:09 +00:00
dependabot-preview[bot]
33d540e1c9
Bump desugar_jdk_libs from 1.0.10 to 1.1.1 (#1039) 2020-12-06 15:04:43 +00:00
dependabot-preview[bot]
d115372c3b
Bump coil from 1.0.0 to 1.1.0 (#1040) 2020-12-06 14:57:50 +00:00
dependabot-preview[bot]
e637896ad3
Bump firebase-crashlytics from 17.2.2 to 17.3.0 (#1038) 2020-12-06 14:50:57 +00:00
dependabot-preview[bot]
ce802cc737
Bump about_libraries from 8.6.2 to 8.6.3 (#1037) 2020-12-06 14:43:48 +00:00
dependabot-preview[bot]
bf342ed289
Bump kotlinx-coroutines-test from 1.4.0 to 1.4.2-native-mt (#1031) 2020-12-06 14:32:08 +00:00
dependabot-preview[bot]
40ec5bbe86
Bump kotlinx-coroutines-android from 1.4.0 to 1.4.2-native-mt (#1032) 2020-12-06 14:29:32 +00:00
Rafał Borcz
41dbd2d25f
New Crowdin updates (#1033) 2020-12-06 15:14:58 +01:00
dependabot-preview[bot]
f263b5534a
Bump mockk from 1.10.2 to 1.10.3-jdk8 (#1034) 2020-12-06 14:08:26 +00:00
dependabot-preview[bot]
7ed4787496
Bump chucker from 3.3.0 to 3.4.0 (#1027) 2020-12-03 14:19:21 +00:00
dependabot-preview[bot]
1428887204
Bump agconnect-crash from 1.4.1.300 to 1.4.2.301 (#1030) 2020-12-03 13:57:37 +00:00
dependabot-preview[bot]
0fc828f006
Bump agcp from 1.4.1.300 to 1.4.2.301 (#1024) 2020-12-03 13:48:25 +00:00
dependabot-preview[bot]
13906a7d62
Bump about_libraries from 8.4.3 to 8.6.2 (#1025) 2020-12-03 13:47:26 +00:00
dependabot-preview[bot]
3c0dda9a82
Bump hianalytics from 5.0.4.301 to 5.0.5.301 (#1023) 2020-12-03 13:29:49 +00:00
dependabot-preview[bot]
c42333cd35
Bump firebase-crashlytics-gradle from 2.3.0 to 2.4.1 (#1029) 2020-12-03 13:28:10 +00:00
dependabot-preview[bot]
c675dc8b84
Bump kotlin_version from 1.4.10 to 1.4.20 (#1026) 2020-12-03 13:27:47 +00:00
Rafał Borcz
5e9853b043
New Crowdin updates (#1022) 2020-11-21 15:50:18 +01:00
Rafał Borcz
c7fdcc2bbd
Add facebook link to about (#1021) 2020-11-17 16:58:24 +01:00
Stanisław Jelnicki
8a00ae95b8
Update contributor's username (#1020) 2020-11-13 23:59:45 +01:00
Mikołaj Pich
a1ebf6c6ad
Add average in class grades statistics (#1017) 2020-11-11 16:03:52 +01:00
Rafał Borcz
ada5854d10
New Crowdin updates (#1013) 2020-11-02 17:54:02 +01:00
dependabot-preview[bot]
fe191bb0df
Bump firebase-analytics from 17.6.0 to 18.0.0 (#1009) 2020-11-01 18:36:55 +00:00
dependabot-preview[bot]
9eb091fbf4
Bump kotlinx-coroutines-android from 1.3.9 to 1.4.0 (#1005) 2020-11-01 18:16:21 +00:00
dependabot-preview[bot]
57e760844f
Bump kotlinx-coroutines-test from 1.3.9 to 1.4.0 (#1012) 2020-11-01 18:15:52 +00:00
Rafał Borcz
20644a7a67
Update english strings (#1014) 2020-11-01 19:05:05 +01:00
dependabot-preview[bot]
b3109aed0b
Bump firebase-messaging from 20.3.0 to 21.0.0 (#1008) 2020-11-01 16:40:39 +00:00
dependabot-preview[bot]
9ba999feb0
Bump about_libraries from 8.4.2 to 8.4.3 (#1011) 2020-11-01 16:28:32 +00:00
dependabot-preview[bot]
7c9e85793b
Bump firebase-inappmessaging-display-ktx from 19.1.1 to 19.1.2 (#1007) 2020-11-01 16:15:17 +00:00
dependabot-preview[bot]
6af8263952
Bump firebase-inappmessaging-ktx from 19.1.1 to 19.1.2 (#1010) 2020-11-01 15:55:51 +00:00
dependabot-preview[bot]
83d1d860a6
Bump coil from 1.0.0-rc3 to 1.0.0 (#1006) 2020-11-01 15:55:36 +00:00
Mikołaj Pich
8830240182
Add conferences (#1004) 2020-11-01 16:53:31 +01:00
Mikołaj Pich
c3061e75b5 Merge branch 'release/0.22.2' into develop 2020-10-30 12:31:58 +01:00
Mikołaj Pich
5f1bb7c1d0 Merge branch 'release/0.22.2' into master 2020-10-30 12:31:50 +01:00
Mikołaj Pich
c6f4c868b2 Version 0.22.2 2020-10-30 12:31:41 +01:00
Mikołaj Pich
c634c64e70
Update hianalytics to 5.0.4.301 (#1003) 2020-10-30 12:24:00 +01:00
Mikołaj Pich
da2b7dbf7e Merge branch 'release/0.22.1' into develop 2020-10-30 01:49:56 +01:00
Mikołaj Pich
26267507eb Merge branch 'release/0.22.1' into master 2020-10-30 01:49:42 +01:00
Mikołaj Pich
24d0c5057b Version 0.22.1 2020-10-30 01:49:30 +01:00
Rafał Borcz
b05026a6e6
New Crowdin updates (#1002) 2020-10-30 00:54:35 +01:00
Mikołaj Pich
8036f3d7f7
Add HMS flavor (#998) 2020-10-29 13:58:56 +01:00
Rafał Borcz
23e309d38e
New Crowdin updates (#993) 2020-10-26 11:54:27 +01:00
Mikołaj Pich
bf92c6b2e9
Fix grade header item object comparision (#999) 2020-10-25 12:16:19 +01:00
Kacper Ziubryniewicz
c00b5edaf7
Make AppGallery badge background transparent. (#997) 2020-10-22 16:17:52 +02:00
dependabot-preview[bot]
cb09ca13dc
Bump junit from 4.13 to 4.13.1 (#995) 2020-10-15 18:36:31 +00:00
dependabot-preview[bot]
3d68b8e629
Bump gradle from 4.0.2 to 4.1.0 (#996) 2020-10-15 18:36:13 +00:00
Mikołaj Pich
b3173581e5 Merge tag '0.22.0' into develop
Version 0.22.0
2020-10-15 17:54:27 +02:00
Mikołaj Pich
ddac1d0f98 Merge branch 'release/0.22.0' into master 2020-10-15 17:54:22 +02:00
Mikołaj Pich
db6a359bea Version 0.22.0 2020-10-15 17:54:14 +02:00
Mikołaj Pich
e7221e6a32
Add Vulcan and Scrapper Exceptions to known exceptions (#994) 2020-10-15 15:55:59 +02:00
Mikołaj Pich
db9c2640c7
Add in-app updates support (#914) 2020-10-15 01:00:41 +02:00
Mikołaj Pich
ca67e144e4
Add ConnectException and StreamResetException to known exceptions (#992) 2020-10-13 22:32:15 +02:00
Rafał Borcz
da2346ed83
New Crowdin updates (#987) 2020-10-11 21:00:48 +02:00
Mikołaj Pich
a87818f3d0
Cancel scheduled lesson notifications which turned into canceled (#991) 2020-10-11 20:51:03 +02:00
Mikołaj Pich
5092f8c0bf
Reload grade list on mark all as read (#990) 2020-10-11 20:33:18 +02:00
Mateusz Idziejczak
af0787c0b1
Add support for BIG font (#989)
Co-authored-by: Faierbel <RafalBO99@outlook.com>
2020-10-10 02:53:25 +02:00
Mateusz Idziejczak
721b4ac797
Add support for night mode in account switcher dialog (#988) 2020-10-09 21:24:58 +02:00
Rafał Borcz
26a69092cc
Add AppGallery badge (#986) 2020-10-07 11:19:34 +02:00
dependabot-preview[bot]
2bd0c75055
Bump about_libraries from 8.3.1 to 8.4.2 (#985) 2020-10-06 21:56:46 +00:00
dependabot-preview[bot]
d6f3c57293
Bump moshi from 1.10.0 to 1.11.0 (#984) 2020-10-06 21:45:38 +00:00
dependabot-preview[bot]
518387e7bb
Bump gradle from 4.0.1 to 4.0.2 (#982) 2020-10-06 21:43:56 +00:00
dependabot-preview[bot]
ca6dfbf2d0
Bump core-ktx from 1.3.1 to 1.3.2 (#983) 2020-10-06 21:43:50 +00:00
Rafał Borcz
da6d8a74fd
New Crowdin updates (#981) 2020-10-06 23:34:27 +02:00
Rafał Borcz
e35e4ef152
New Crowdin updates (#948) 2020-10-03 13:01:11 +02:00
Rafał Borcz
40fc6ec2e0
Upgrade android sdk to 30 (#966) 2020-10-03 01:08:57 +02:00
dependabot-preview[bot]
b91973aec3
Bump chucker from 3.2.0 to 3.3.0 (#979) 2020-10-01 15:38:29 +00:00
dependabot-preview[bot]
047e70ad46
Bump firebase-crashlytics from 17.2.1 to 17.2.2 (#974) 2020-09-30 20:13:18 +00:00
dependabot-preview[bot]
112c1eb793
Bump moshi from 1.9.3 to 1.10.0 (#972) 2020-09-30 20:13:01 +00:00
dependabot-preview[bot]
c479b31670
Bump coil from 1.0.0-rc2 to 1.0.0-rc3 (#976) 2020-09-30 20:01:45 +00:00
dependabot-preview[bot]
43ed8c8fce
Bump firebase-messaging from 20.2.4 to 20.3.0 (#973) 2020-09-30 19:52:02 +00:00
dependabot-preview[bot]
613fa44c27
Bump about_libraries from 8.3.0 to 8.3.1 (#975) 2020-09-30 19:34:53 +00:00
dependabot-preview[bot]
f21216286d
Bump mockk from 1.10.0 to 1.10.2 (#977) 2020-09-30 19:34:13 +00:00
dependabot-preview[bot]
7298d0d75a
Bump google-services from 4.3.3 to 4.3.4 (#978) 2020-09-30 19:33:22 +00:00
Mikołaj Pich
ee0fbcdfd6 Merge tag '0.21.2' into develop
Version 0.21.2
2020-09-29 21:10:17 +02:00
Mikołaj Pich
c362ad12c7 Merge branch 'release/0.21.2' into master 2020-09-29 21:10:11 +02:00
Mikołaj Pich
8a1a712d6d Version 0.21.2 2020-09-29 21:10:05 +02:00
Mikołaj Pich
1f0f6b3e51
Fix string pair list type converter (#971) 2020-09-29 21:02:49 +02:00
Mikołaj Pich
11487e77ca Merge tag '0.21.1' into develop
Version 0.21.1
2020-09-29 11:43:58 +02:00
Mikołaj Pich
fd0fd4df55 Merge branch 'release/0.21.1' into master 2020-09-29 11:43:54 +02:00
Mikołaj Pich
d95a33787b Version 0.21.1 2020-09-29 11:43:49 +02:00
Mikołaj Pich
e5661098d9
Fix string pair list type converter (#970) 2020-09-29 11:42:54 +02:00
Mikołaj Pich
d020b01794 Merge tag '0.21.0' into develop
Version 0.21.0
2020-09-27 22:12:31 +02:00
Mikołaj Pich
d8b1264024 Merge branch 'release/0.21.0' into master 2020-09-27 22:12:27 +02:00
Mikołaj Pich
cddd17650b Version 0.21.0 2020-09-27 22:11:55 +02:00
Mikołaj Pich
a0f9c70036
Migrate from gson to moshi (#969) 2020-09-27 20:59:27 +02:00
Mateusz Idziejczak
2e05416fb5
Show groups next to subjects in timetable (#953) 2020-09-27 16:33:36 +02:00
Mateusz Idziejczak
d32ebd66de
Add subjects sorting in grades (#946) 2020-09-27 16:28:39 +02:00
Mateusz Idziejczak
c6a99f1000
Add remembering the full screen mode in homework (#956)
Co-authored-by: Faierbel <RafalBO99@outlook.com>
2020-09-27 14:49:19 +02:00
Mateusz Idziejczak
bafe52e310
Different notification for notes and praises (#952) 2020-09-25 15:46:08 +02:00
Mateusz Idziejczak
e08abc1fc2
Show subjects without grades in "Grades" (#947) 2020-09-25 15:45:07 +02:00
Mateusz Idziejczak
2a74b11cce
Add app shortcuts (#939)
Co-authored-by: Faierbel <RafalBO99@outlook.com>
2020-09-25 15:37:19 +02:00
Mikołaj Pich
b0b3ccfd53
Upgrade gradle wrapper to 6.6.1 (#968) 2020-09-20 21:54:59 +02:00
Mikołaj Pich
6c68456f7a Merge tag '0.20.5' into develop
Version 0.20.5
2020-09-19 13:03:32 +02:00
Mikołaj Pich
3e8e9b4ecc Merge branch 'release/0.20.5' into master 2020-09-19 13:03:28 +02:00
Mikołaj Pich
d6ebc343d5 Version 0.20.5 2020-09-19 01:25:34 +02:00
Mikołaj Pich
73be416807
Fix crash in flowWithResourceIn() (#967) 2020-09-19 00:57:55 +02:00
Mikołaj Pich
0cb65a29ba Merge tag '0.20.4' into develop
Version 0.20.4
2020-09-13 19:00:45 +02:00
Mikołaj Pich
13198f2ab4 Merge branch 'release/0.20.4' into master 2020-09-13 19:00:39 +02:00
Mikołaj Pich
cd92f37435 Version 0.20.4 2020-09-13 19:00:32 +02:00
Mikołaj Pich
5d8fb376ab
Expand exam sync date range to next month (#960) 2020-09-13 18:37:34 +02:00
Mikołaj Pich
47150364d8
Fix lifecycle of timer tasks in timetable lessons (#958)
Co-authored-by: Faierbel <RafalBO99@outlook.com>
2020-09-13 16:27:53 +02:00
dependabot-preview[bot]
792b123598
Bump coil from 1.0.0-rc1 to 1.0.0-rc2 (#961) 2020-09-13 14:07:30 +00:00
dependabot-preview[bot]
acf5c8e9ba
Bump firebase-crashlytics-gradle from 2.2.1 to 2.3.0 (#964) 2020-09-13 14:04:41 +00:00
dependabot-preview[bot]
53561668fc
Bump hilt_version from 2.28.3-alpha to 2.29.1-alpha (#962) 2020-09-13 14:03:09 +00:00
dependabot-preview[bot]
7cfe58d311
Bump material from 1.2.0 to 1.2.1 (#963) 2020-09-13 14:02:31 +00:00
Mikołaj Pich
cd51fac621
Add eduportal.koszalin.pl register (#959) 2020-09-13 13:46:45 +02:00
Mikołaj Pich
adde5541e2
Move timetable notifications scheduling to background thread (#954) 2020-09-11 13:02:16 +02:00
Mikołaj Pich
6e56d3ff06
Ignore empty semesters on refresh (#955) 2020-09-09 13:28:44 +02:00
Mateusz Idziejczak
ec761f6329
Fix bug in grade statistics (#951) 2020-09-08 20:13:17 +02:00
Mateusz Idziejczak
6363c90e37
Disable sound of upcoming lessons notification (fix) (#950) 2020-09-07 20:28:32 +02:00
Mikołaj Pich
c30f105be5
Fix crash on unknown attendance category type (#949) 2020-09-07 09:35:26 +02:00
Mikołaj Pich
9f85b2206a Merge tag '0.20.3' into develop
Version 0.20.3
2020-09-04 23:42:12 +02:00
Mikołaj Pich
42515fd084 Merge branch 'release/0.20.3' into master 2020-09-04 23:42:07 +02:00
Mikołaj Pich
9a7c04fe7b Version 0.20.3 2020-09-04 23:42:01 +02:00
Mikołaj Pich
debb21f5f9
Add full stacktrace to errors list in sync now (#945) 2020-09-03 21:10:39 +02:00
Mikołaj Pich
18b9bf42e1
Fix crash in flowWithResourceIn() (#944) 2020-09-03 20:54:28 +02:00
Mikołaj Pich
6ded83d132
Fix attendance item description (#943) 2020-09-03 20:52:24 +02:00
Mikołaj Pich
71d37a1c6c Merge tag '0.20.2' into develop
Version 0.20.2
2020-09-02 00:23:49 +02:00
597 changed files with 32904 additions and 6643 deletions

202
.github/workflows/test.yml vendored Normal file
View file

@ -0,0 +1,202 @@
name: Test and deploy
on:
push:
branches: [ develop ]
tags: [ '*' ]
pull_request:
branches: [ develop ]
workflow_dispatch:
jobs:
unit-tests:
name: Unit tests
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: Unit tests
run: |
./gradlew --build-cache -Pcoverage testFdroidDebugUnitTest --stacktrace
./gradlew --build-cache -Pcoverage jacocoTestReport --stacktrace
- uses: codecov/codecov-action@v1
with:
flags: unit
deploy-google-play:
name: Deploy to google play
runs-on: ubuntu-latest
timeout-minutes: 10
environment: google-play
needs: [ unit-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*') }}
- 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-appcenter:
name: Deploy to App Center
runs-on: ubuntu-latest
timeout-minutes: 10
environment: app-center
if: github.ref != 'refs/heads/develop'
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: Deploy to AppDistribution
runs-on: ubuntu-latest
timeout-minutes: 10
environment: app-distribution
if: github.ref == 'refs/heads/develop'
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

4
.gitignore vendored
View file

@ -19,6 +19,7 @@ out/
# Gradle files
.gradle/
build/
.build-cache
# Local configuration file (sdk path, etc)
local.properties
@ -113,3 +114,6 @@ Thumbs.db
!/gradle/wrapper/gradle-wrapper.jar
.idea/jarRepositories.xml
app/src/release/agconnect-services.json

View file

@ -18,18 +18,9 @@
</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="CONTINUATION_INDENT_IN_PARAMETER_LISTS" value="false" />
<option name="CONTINUATION_INDENT_IN_ARGUMENT_LISTS" value="false" />
<option name="CONTINUATION_INDENT_FOR_EXPRESSION_BODIES" value="false" />
<option name="CONTINUATION_INDENT_FOR_CHAINED_CALLS" value="false" />
<option name="CONTINUATION_INDENT_IN_SUPERTYPE_LISTS" value="false" />
<option name="CONTINUATION_INDENT_IN_IF_CONDITIONS" value="false" />
<option name="CONTINUATION_INDENT_IN_ELVIS" value="false" />
<option name="WRAP_ELVIS_EXPRESSIONS" value="0" />
<option name="CODE_STYLE_DEFAULTS" value="KOTLIN_OFFICIAL" />
</JetCodeStyleSettings>
<MarkdownNavigatorCodeStyleSettings>
<option name="RIGHT_MARGIN" value="72" />
</MarkdownNavigatorCodeStyleSettings>
<codeStyleSettings language="XML">
<indentOptions>
<option name="CONTINUATION_INDENT_SIZE" value="4" />
@ -143,13 +134,11 @@
</arrangement>
</codeStyleSettings>
<codeStyleSettings language="kotlin">
<option name="CODE_STYLE_DEFAULTS" value="KOTLIN_OFFICIAL" />
<option name="KEEP_BLANK_LINES_IN_DECLARATIONS" value="1" />
<option name="KEEP_BLANK_LINES_IN_CODE" value="1" />
<option name="KEEP_BLANK_LINES_BEFORE_RBRACE" value="0" />
<option name="ALIGN_MULTILINE_PARAMETERS" value="false" />
<option name="METHOD_PARAMETERS_LPAREN_ON_NEXT_LINE" value="true" />
<option name="METHOD_PARAMETERS_RPAREN_ON_NEXT_LINE" value="true" />
<option name="EXTENDS_LIST_WRAP" value="1" />
<indentOptions>
<option name="CONTINUATION_INDENT_SIZE" value="4" />
</indentOptions>

View file

@ -3,8 +3,8 @@ jdk: oraclejdk8
env:
global:
- ANDROID_API_LEVEL=29
- ANDROID_BUILD_TOOLS_VERSION=29.0.3
- ANDROID_API_LEVEL=30
- ANDROID_BUILD_TOOLS_VERSION=30.0.2
cache:
directories:
@ -14,7 +14,7 @@ cache:
branches:
only:
- develop
- 0.20.2
- 0.24.0
android:
licenses:
@ -37,6 +37,10 @@ android:
- android-22
- sys-img-armeabi-v7a-android-22
before_install:
- yes | sdkmanager "platforms;android-30"
- yes | sdkmanager "build-tools;30.0.2"
before_script:
# Launch emulator before the execution
- echo no | android create avd --force -n test -t android-22 --abi armeabi-v7a
@ -48,12 +52,13 @@ before_script:
script:
- ./gradlew dependencies --stacktrace --daemon
- fossa --no-ansi || true
- ./gradlew -Pcoverage testPlayDebugUnitTest --stacktrace --daemon
- ./gradlew -Pcoverage createFdroidDebugCoverageReport --stacktrace --daemon
- ./gradlew -Pcoverage testFdroidDebugUnitTest --stacktrace --daemon
- ./gradlew -Pcoverage connectedFdroidDebugAndroidTest --stacktrace --daemon
- ./gradlew -Pcoverage jacocoTestReport --stacktrace --daemon
- |
if [ $TRAVIS_TAG ]; then
gpg --yes --batch --passphrase=$SERVICES_ENCRYPT_KEY ./app/src/release/google-services.json.gpg;
gpg --yes --batch --passphrase=$SERVICES_ENCRYPT_KEY ./app/src/release/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;
./gradlew publishPlayRelease -PenableFirebase --stacktrace;

View file

@ -1,7 +1,8 @@
[Polska wersja README](README.md)
# Wulkanowy
[![Travis](https://img.shields.io/travis/com/wulkanowy/wulkanowy/master.svg?style=flat-square)](https://travis-ci.com/wulkanowy/wulkanowy)
[![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)
[![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/)
@ -11,7 +12,7 @@ Unofficial android VULCAN UONET+ register client for both students and their par
## Features
* logging in using the email and password OR using token and pin
* logging in using the email and password
* functions from the register website:
* grades
* grade statistics
@ -24,15 +25,19 @@ Unofficial android VULCAN UONET+ register client for both students and their par
* homework
* notes
* lucky number
* additional lessons
* school conferences
* student and school information
* calculation of the average independently of school's preferences
* notifications, e.g. about a new grade
* support for multiple accounts with the ability to rename students
* dark and black (AMOLED) theme
* offline mode
* no ads
## Download
You can download the current beta version from the Google Play or the F-Droid store
You can download the current version from the Google Play, F-Droid or Huawei AppGallery store
[<img src="https://play.google.com/intl/en_us/badges/images/generic/en_badge_web_generic.png"
alt="Get it on Google Play"
@ -40,6 +45,9 @@ You can download the current beta version from the Google Play or the F-Droid st
[<img src="https://fdroid.gitlab.io/artwork/badge/get-it-on.png"
alt="Get it on F-Droid"
height="80">](https://f-droid.org/packages/io.github.wulkanowy/)
[<img src="appgallery_badge.png"
alt="Explore it on AppGallery"
height="80">](https://appgallery.cloud.huawei.com/ag/n/app/C101440411?channelId=Badge&id=1b3f7fbb700849a9be0dba6b520b2282&s=EB1D3BF9ED9D1564D869B7B94B18016D3CABFCA5AEFB8E29F675FA04E0DC131D&detailType=0&v=)
You can also download a [development version](https://wulkanowy.github.io/#download) that includes new features being prepared for the next release
@ -47,7 +55,8 @@ You can also download a [development version](https://wulkanowy.github.io/#downl
* [Wulkanowy SDK](https://github.com/wulkanowy/sdk)
* [Dagger 2](https://github.com/google/dagger)
* [Kotlin Coroutines](https://kotlinlang.org/docs/reference/coroutines-overview.html)
* [Hilt](https://dagger.dev/hilt/)
* [Room](https://developer.android.com/topic/libraries/architecture/room)
* [WorkManager](https://developer.android.com/topic/libraries/architecture/workmanager)
@ -55,6 +64,9 @@ You can also download a [development version](https://wulkanowy.github.io/#downl
Please contribute to the project either by creating a PR or submitting an issue on GitHub.
For people interested in translating the application into different languages, we provide Crowdin
https://crowdin.com/project/wulkanowy2
## License
This project is licensed under the Apache License 2.0 - see the [LICENSE](LICENSE) file for details

View file

@ -1,7 +1,8 @@
[English version of README](README.en.md)
# Wulkanowy
[![Travis](https://img.shields.io/travis/com/wulkanowy/wulkanowy/master.svg?style=flat-square)](https://travis-ci.com/wulkanowy/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)
[![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/)
@ -11,7 +12,7 @@ Nieoficjalny klient dziennika VULCAN UONET+ dla ucznia i rodzica
## Funkcje
* logowanie za pomocą e-maila i hasła LUB tokena i pinu
* logowanie za pomocą e-maila i hasła
* funkcje ze strony internetowej dziennika:
* oceny
* statystyki ocen
@ -24,15 +25,19 @@ Nieoficjalny klient dziennika VULCAN UONET+ dla ucznia i rodzica
* zadania domowe
* uwagi
* szczęśliwy numerek
* dodatkowe lekcje
* zebrania w szkole
* informacje o uczniu i szkole
* obliczanie średniej niezależnie od preferencji szkoły
* 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
Aktualną wersję beta możesz pobrać ze sklepu Google Play lub F-Droid
Aktualną wersję możesz pobrać ze sklepu Google Play, F-Droid lub Huawei AppGallery
[<img src="https://play.google.com/intl/en_us/badges/images/generic/en_badge_web_generic.png"
alt="Pobierz z Google Play"
@ -40,6 +45,9 @@ Aktualną wersję beta możesz pobrać ze sklepu Google Play lub F-Droid
[<img src="https://fdroid.gitlab.io/artwork/badge/get-it-on.png"
alt="Pobierz z F-Droid"
height="80">](https://f-droid.org/packages/io.github.wulkanowy/)
[<img src="appgallery_badge.png"
alt="Odkrywaj w AppGallery"
height="80">](https://appgallery.cloud.huawei.com/ag/n/app/C101440411?channelId=Badge&id=1b3f7fbb700849a9be0dba6b520b2282&s=EB1D3BF9ED9D1564D869B7B94B18016D3CABFCA5AEFB8E29F675FA04E0DC131D&detailType=0&v=)
Możesz także pobrać [wersję rozwojową](https://wulkanowy.github.io/#download), która zawiera nowe funkcje przygotowywane do następnego wydania
@ -47,8 +55,9 @@ Możesz także pobrać [wersję rozwojową](https://wulkanowy.github.io/#downloa
## Zbudowana za pomocą
* [Wulkanowy SDK](https://github.com/wulkanowy/SDK)
* [Dagger 2](https://github.com/google/dagger)
* [Wulkanowy SDK](https://github.com/wulkanowy/sdk)
* [Kotlin Coroutines](https://kotlinlang.org/docs/reference/coroutines-overview.html)
* [Hilt](https://dagger.dev/hilt/)
* [Room](https://developer.android.com/topic/libraries/architecture/room)
* [WorkManager](https://developer.android.com/topic/libraries/architecture/workmanager)
@ -56,6 +65,9 @@ Możesz także pobrać [wersję rozwojową](https://wulkanowy.github.io/#downloa
Wnieś swój wkład w projekt, tworząc PR lub wysyłając issue na GitHub.
Dla osób zainteresowanych tłumaczeniem aplikacji na różne języki udostępniamy Crowdina
https://crowdin.com/project/wulkanowy2
## Licencja
Ten projekt udostępniany jest na licencji Apache License 2.0 - szczegóły w pliku [LICENSE](LICENSE)

BIN
app/bitrise.jks Normal file

Binary file not shown.

BIN
app/bitrise.jks.gpg Normal file

Binary file not shown.

View file

@ -5,25 +5,30 @@ apply plugin: 'dagger.hilt.android.plugin'
apply plugin: 'com.google.firebase.crashlytics'
apply plugin: 'com.github.triplet.play'
apply plugin: 'com.mikepenz.aboutlibraries.plugin'
apply plugin: 'com.google.gms.google-services'
apply plugin: 'com.huawei.agconnect'
apply from: 'jacoco.gradle'
apply from: 'sonarqube.gradle'
apply from: 'hooks.gradle'
android {
compileSdkVersion 29
buildToolsVersion '29.0.3'
compileSdkVersion 30
buildToolsVersion '30.0.3'
defaultConfig {
applicationId "io.github.wulkanowy"
testApplicationId "io.github.tests.wulkanowy"
minSdkVersion 17
targetSdkVersion 29
versionCode 66
versionName "0.20.2"
targetSdkVersion 30
versionCode 90
versionName "1.1.4"
multiDexEnabled true
resValue "string", "app_name", "Wulkanowy"
testInstrumentationRunner "androidx.test.runner.AndroidJUnitRunner"
vectorDrawables.useSupportLibrary = true
resValue "string", "app_name", "Wulkanowy"
buildConfigField "long", "BUILD_TIMESTAMP", String.valueOf(System.currentTimeMillis())
manifestPlaceholders = [
firebase_enabled: project.hasProperty("enableFirebase")
]
@ -38,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 {
@ -69,12 +75,26 @@ android {
flavorDimensions "platform"
productFlavors {
hms {
dimension "platform"
minSdkVersion 19
manifestPlaceholders = [
install_channel: "AppGallery"
]
}
play {
dimension "platform"
manifestPlaceholders = [
install_channel: "Google Play"
]
}
fdroid {
dimension "platform"
manifestPlaceholders = [
install_channel: "F-Droid"
]
}
}
@ -86,6 +106,10 @@ android {
disable 'HardwareIds'
}
testOptions.unitTests {
includeAndroidResources = true
}
compileOptions {
coreLibraryDesugaringEnabled true
sourceCompatibility JavaVersion.VERSION_1_8
@ -93,6 +117,7 @@ android {
}
kotlinOptions {
useIR = true
jvmTarget = "1.8"
freeCompilerArgs += ["-Xopt-in=kotlin.RequiresOptIn", "-Xjvm-default=all"]
}
@ -111,51 +136,50 @@ play {
serviceAccountEmail = System.getenv("PLAY_SERVICE_ACCOUNT_EMAIL") ?: "jan@fakelog.cf"
serviceAccountCredentials = file('key.p12')
defaultToAppBundles = false
track = 'alpha'
track = 'production'
updatePriority = 3
}
ext {
work_manager = "2.4.0"
room = "2.2.5"
chucker = "3.2.0"
mockk = "1.10.0"
}
configurations.all {
resolutionStrategy.force "androidx.constraintlayout:constraintlayout:1.1.3"
work_manager = "2.5.0"
work_hilt = "1.0.0-beta01"
room = "2.3.0-rc01"
chucker = "3.4.0"
mockk = "1.11.0"
moshi = "1.11.0"
}
dependencies {
implementation "io.github.wulkanowy:sdk:0.20.2"
implementation "io.github.wulkanowy:sdk:1.1.3"
coreLibraryDesugaring 'com.android.tools:desugar_jdk_libs:1.0.10'
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.3.9'
implementation 'org.jetbrains.kotlinx:kotlinx-coroutines-android:1.4.3'
implementation "androidx.core:core-ktx:1.3.1"
implementation "androidx.activity:activity-ktx:1.1.0"
implementation "androidx.core:core-ktx:1.3.2"
implementation "androidx.activity:activity-ktx:1.2.2"
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.fragment:fragment-ktx:1.3.2"
implementation "androidx.annotation:annotation:1.2.0"
implementation "androidx.multidex:multidex:2.0.1"
implementation "androidx.preference:preference-ktx:1.1.1"
implementation "androidx.recyclerview:recyclerview:1.1.0"
implementation "androidx.viewpager:viewpager:1.0.0"
implementation "androidx.swiperefreshlayout:swiperefreshlayout:1.1.0"
implementation "androidx.constraintlayout:constraintlayout:2.0.1"
implementation "androidx.constraintlayout:constraintlayout:2.0.4"
implementation "androidx.coordinatorlayout:coordinatorlayout:1.1.0"
implementation "com.google.android.material:material:1.2.0"
implementation "com.github.wulkanowy:material-chips-input:2.1.1"
implementation "com.google.android.material:material:1.3.0"
implementation "com.github.wulkanowy:material-chips-input:2.2.0"
implementation "com.github.PhilJay:MPAndroidChart:v3.1.0"
implementation "me.zhanghai.android.materialprogressbar:library:1.6.1"
implementation 'com.mikhaellopez:circularimageview:4.2.0'
implementation "androidx.work:work-runtime-ktx:$work_manager"
implementation "androidx.work:work-gcm:$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"
@ -163,45 +187,55 @@ dependencies {
implementation "com.google.dagger:hilt-android:$hilt_version"
kapt "com.google.dagger:hilt-android-compiler:$hilt_version"
implementation 'androidx.hilt:hilt-work:1.0.0-alpha02'
kapt 'androidx.hilt:hilt-compiler:1.0.0-alpha02'
implementation "androidx.hilt:hilt-work:$work_hilt"
kapt "androidx.hilt:hilt-compiler:$work_hilt"
implementation "com.aurelhubert:ahbottomnavigation:2.3.4"
implementation "com.ncapdevi:frag-nav:3.3.0"
implementation "com.github.YarikSOffice:lingver:1.2.2"
implementation "com.github.YarikSOffice:lingver:1.3.0"
implementation "com.google.code.gson:gson:2.8.6"
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 "at.favre.lib:slf4j-timber:1.0.1"
implementation "fr.bipi.treessence:treessence:0.3.2"
implementation "com.mikepenz:aboutlibraries-core:$about_libraries"
implementation 'com.wdullaer:materialdatetimepicker:4.2.3'
implementation "io.coil-kt:coil:1.0.0-rc1"
implementation "io.coil-kt:coil:1.1.1"
implementation "io.github.wulkanowy:AppKillerManager:3.0.0"
implementation 'me.xdrop:fuzzywuzzy:1.3.1'
playImplementation 'com.google.firebase:firebase-analytics:17.5.0'
playImplementation 'com.google.firebase:firebase-inappmessaging-display-ktx:19.1.1'
playImplementation "com.google.firebase:firebase-inappmessaging-ktx:19.1.1"
playImplementation 'com.google.firebase:firebase-messaging:20.2.4'
playImplementation 'com.google.firebase:firebase-crashlytics:17.2.1'
playImplementation 'com.google.guava:listenablefuture:9999.0-empty-to-avoid-conflict-with-guava'
playImplementation platform('com.google.firebase:firebase-bom:26.7.0')
playImplementation 'com.google.firebase:firebase-analytics-ktx'
playImplementation 'com.google.firebase:firebase-messaging:'
playImplementation 'com.google.firebase:firebase-crashlytics:'
playImplementation 'com.google.android.play:core-ktx:1.8.1'
hmsImplementation 'com.huawei.hms:hianalytics:5.2.0.301'
hmsImplementation 'com.huawei.agconnect:agconnect-crash:1.5.1.200'
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"
testImplementation "junit:junit:4.13"
testImplementation "junit:junit:4.13.2"
testImplementation "io.mockk:mockk:$mockk"
testImplementation 'org.jetbrains.kotlinx:kotlinx-coroutines-test:1.3.9'
testImplementation 'org.jetbrains.kotlinx:kotlinx-coroutines-test:1.4.2'
testImplementation "org.jetbrains.kotlin:kotlin-test:$kotlin_version"
testImplementation 'org.robolectric:robolectric:4.5.1'
testImplementation "androidx.test:runner:1.3.0"
testImplementation "androidx.test.ext:junit:1.1.2"
testImplementation "androidx.test:core:1.3.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.3.0"
androidTestImplementation "androidx.test:runner:1.3.0"
androidTestImplementation "androidx.test.ext:junit:1.1.2"
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'

View file

@ -7,6 +7,7 @@ jacoco {
tasks.withType(Test) {
jacoco.includeNoLocationClasses = true
jacoco.excludes = ['jdk.internal.*']
}
task jacocoTestReport(type: JacocoReport) {
@ -35,13 +36,13 @@ task jacocoTestReport(type: JacocoReport) {
dir: "$buildDir/intermediates/classes/debug",
excludes: excludes
) + fileTree(
dir: "$buildDir/tmp/kotlin-classes/playDebug",
dir: "$buildDir/tmp/kotlin-classes/fdroidDebug",
excludes: excludes
))
sourceDirectories.setFrom(files([
"src/main/java",
"src/play/java"
"src/fdroid/java"
]))
executionData.setFrom(fileTree(
dir: project.projectDir,

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

File diff suppressed because it is too large Load diff

File diff suppressed because it is too large Load diff

File diff suppressed because it is too large Load diff

View file

@ -1,11 +0,0 @@
package io.github.wulkanowy.data
import io.github.wulkanowy.utils.DispatchersProvider
import kotlinx.coroutines.CoroutineDispatcher
import kotlinx.coroutines.Dispatchers
class TestDispatchersProvider : DispatchersProvider() {
override val backgroundThread: CoroutineDispatcher
get() = Dispatchers.Unconfined
}

View file

@ -1,45 +0,0 @@
package io.github.wulkanowy.data.repositories
import io.github.wulkanowy.data.db.entities.Semester
import io.github.wulkanowy.data.db.entities.Student
import java.time.LocalDate.now
import java.time.LocalDateTime
fun getStudent(): Student {
return Student(
email = "test",
password = "test123",
schoolSymbol = "23",
scrapperBaseUrl = "fakelog.cf",
loginType = "AUTO",
isCurrent = true,
userName = "",
studentName = "",
schoolShortName = "",
schoolName = "",
studentId = 0,
classId = 1,
symbol = "",
registrationDate = LocalDateTime.now(),
className = "",
loginMode = "API",
certificateKey = "",
privateKey = "",
mobileBaseUrl = "",
userLoginId = 0,
isParent = false
)
}
fun getSemester() = Semester(
semesterId = 1,
studentId = 1,
classId = 1,
diaryId = 2,
diaryName = "",
end = now(),
schoolYear = 2019,
semesterName = 1,
start = now(),
unitId = 1
)

View file

@ -1,83 +0,0 @@
package io.github.wulkanowy.data.repositories.attendance
import androidx.room.Room
import androidx.test.core.app.ApplicationProvider
import androidx.test.ext.junit.runners.AndroidJUnit4
import io.github.wulkanowy.data.db.AppDatabase
import io.github.wulkanowy.data.db.entities.Attendance
import io.github.wulkanowy.data.db.entities.Semester
import kotlinx.coroutines.flow.first
import kotlinx.coroutines.runBlocking
import org.junit.After
import org.junit.Before
import org.junit.Test
import org.junit.runner.RunWith
import java.time.LocalDate
import java.time.LocalDate.now
import java.time.LocalDate.of
import kotlin.test.assertEquals
@RunWith(AndroidJUnit4::class)
class AttendanceLocalTest {
private lateinit var attendanceLocal: AttendanceLocal
private lateinit var testDb: AppDatabase
@Before
fun createDb() {
testDb = Room.inMemoryDatabaseBuilder(ApplicationProvider.getApplicationContext(), AppDatabase::class.java).build()
attendanceLocal = AttendanceLocal(testDb.attendanceDao)
}
@After
fun closeDb() {
testDb.close()
}
@Test
fun saveAndReadTest() {
val list = listOf(
getAttendanceEntity(
of(2018, 9, 10),
SentExcuseStatus.ACCEPTED
),
getAttendanceEntity(
of(2018, 9, 14),
SentExcuseStatus.WAITING
),
getAttendanceEntity(
of(2018, 9, 17),
SentExcuseStatus.ACCEPTED
)
)
runBlocking { attendanceLocal.saveAttendance(list) }
val semester = Semester(1, 2, "", 1, 3, 2019, now(), now(), 1, 1)
val attendance = runBlocking { attendanceLocal.getAttendance(semester, of(2018, 9, 10), of(2018, 9, 14)).first() }
assertEquals(2, attendance.size)
assertEquals(attendance[0].date, of(2018, 9, 10))
assertEquals(attendance[1].date, of(2018, 9, 14))
}
private fun getAttendanceEntity(
date: LocalDate,
excuseStatus: SentExcuseStatus
) = Attendance(
studentId = 1,
diaryId = 2,
timeId = 3,
date = date,
number = 0,
subject = "",
name = "",
presence = false,
absence = false,
exemption = false,
lateness = false,
excused = false,
deleted = false,
excusable = false,
excuseStatus = excuseStatus.name
)
}

View file

@ -1,59 +0,0 @@
package io.github.wulkanowy.data.repositories.completedlessons
import androidx.room.Room
import androidx.test.core.app.ApplicationProvider
import androidx.test.ext.junit.runners.AndroidJUnit4
import io.github.wulkanowy.data.db.AppDatabase
import io.github.wulkanowy.data.db.entities.CompletedLesson
import io.github.wulkanowy.data.db.entities.Semester
import kotlinx.coroutines.flow.first
import kotlinx.coroutines.runBlocking
import org.junit.After
import org.junit.Before
import org.junit.Test
import org.junit.runner.RunWith
import java.time.LocalDate
import java.time.LocalDate.now
import java.time.LocalDate.of
import kotlin.test.assertEquals
@RunWith(AndroidJUnit4::class)
class CompletedLessonsLocalTest {
private lateinit var completedLessonsLocal: CompletedLessonsLocal
private lateinit var testDb: AppDatabase
@Before
fun createDb() {
testDb = Room
.inMemoryDatabaseBuilder(ApplicationProvider.getApplicationContext(), AppDatabase::class.java)
.build()
completedLessonsLocal = CompletedLessonsLocal(testDb.completedLessonsDao)
}
@After
fun closeDb() {
testDb.close()
}
@Test
fun saveAndReadTest() {
val list = listOf(
getCompletedLesson(of(2018, 9, 10), 1),
getCompletedLesson(of(2018, 9, 14), 2),
getCompletedLesson(of(2018, 9, 17), 3)
)
runBlocking { completedLessonsLocal.saveCompletedLessons(list) }
val semester = Semester(1, 2, "", 1, 3, 2019, now(), now(), 1, 1)
val completed = runBlocking { completedLessonsLocal.getCompletedLessons(semester, of(2018, 9, 10), of(2018, 9, 14)).first() }
assertEquals(2, completed.size)
assertEquals(completed[0].date, of(2018, 9, 10))
assertEquals(completed[1].date, of(2018, 9, 14))
}
private fun getCompletedLesson(date: LocalDate, number: Int): CompletedLesson {
return CompletedLesson(1, 2, date, number, "", "", "", "", "", "", "")
}
}

View file

@ -1,52 +0,0 @@
package io.github.wulkanowy.data.repositories.exam
import androidx.room.Room
import androidx.test.core.app.ApplicationProvider
import androidx.test.ext.junit.runners.AndroidJUnit4
import io.github.wulkanowy.data.db.AppDatabase
import io.github.wulkanowy.data.db.entities.Exam
import io.github.wulkanowy.data.db.entities.Semester
import kotlinx.coroutines.flow.first
import kotlinx.coroutines.runBlocking
import org.junit.After
import org.junit.Before
import org.junit.Test
import org.junit.runner.RunWith
import java.time.LocalDate.now
import java.time.LocalDate.of
import kotlin.test.assertEquals
@RunWith(AndroidJUnit4::class)
class ExamLocalTest {
private lateinit var examLocal: ExamLocal
private lateinit var testDb: AppDatabase
@Before
fun createDb() {
testDb = Room.inMemoryDatabaseBuilder(ApplicationProvider.getApplicationContext(), AppDatabase::class.java).build()
examLocal = ExamLocal(testDb.examsDao)
}
@After
fun closeDb() {
testDb.close()
}
@Test
fun saveAndReadTest() {
val list = listOf(
Exam(1, 2, of(2018, 9, 10), now(), "", "", "", "", "", ""),
Exam(1, 2, of(2018, 9, 14), now(), "", "", "", "", "", ""),
Exam(1, 2, of(2018, 9, 17), now(), "", "", "", "", "", "")
)
runBlocking { examLocal.saveExams(list) }
val semester = Semester(1, 2, "", 1, 3, 2019, now(), now(), 1, 1)
val exams = runBlocking { examLocal.getExams(semester, of(2018, 9, 10), of(2018, 9, 14)).first() }
assertEquals(2, exams.size)
assertEquals(exams[0].date, of(2018, 9, 10))
assertEquals(exams[1].date, of(2018, 9, 14))
}
}

View file

@ -1,55 +0,0 @@
package io.github.wulkanowy.data.repositories.grade
import androidx.room.Room
import androidx.test.core.app.ApplicationProvider
import androidx.test.ext.junit.runners.AndroidJUnit4
import io.github.wulkanowy.data.db.AppDatabase
import io.github.wulkanowy.data.db.entities.Semester
import kotlinx.coroutines.flow.first
import kotlinx.coroutines.runBlocking
import org.junit.After
import org.junit.Before
import org.junit.Test
import org.junit.runner.RunWith
import java.time.LocalDate
import java.time.LocalDate.now
import kotlin.test.assertEquals
@RunWith(AndroidJUnit4::class)
class GradeLocalTest {
private lateinit var gradeLocal: GradeLocal
private lateinit var testDb: AppDatabase
@Before
fun createDb() {
testDb = Room
.inMemoryDatabaseBuilder(ApplicationProvider.getApplicationContext(), AppDatabase::class.java)
.build()
gradeLocal = GradeLocal(testDb.gradeDao, testDb.gradeSummaryDao)
}
@After
fun closeDb() {
testDb.close()
}
@Test
fun saveAndReadTest() {
val list = listOf(
createGradeLocal(5, 3.0, LocalDate.of(2018, 9, 10), "", 1),
createGradeLocal(4, 4.0, LocalDate.of(2019, 2, 27), "", 2),
createGradeLocal(3, 5.0, LocalDate.of(2019, 2, 28), "", 2)
)
runBlocking { gradeLocal.saveGrades(list) }
val semester = Semester(1, 2, "", 2019, 2, 1, now(), now(), 1, 1)
val grades = runBlocking { gradeLocal.getGradesDetails(semester).first() }
assertEquals(2, grades.size)
assertEquals(grades[0].date, LocalDate.of(2019, 2, 27))
assertEquals(grades[1].date, LocalDate.of(2019, 2, 28))
}
}

View file

@ -1,221 +0,0 @@
package io.github.wulkanowy.data.repositories.grade
import android.os.Build.VERSION_CODES.P
import androidx.room.Room
import androidx.test.core.app.ApplicationProvider.getApplicationContext
import androidx.test.ext.junit.runners.AndroidJUnit4
import androidx.test.filters.SdkSuppress
import io.github.wulkanowy.data.Status
import io.github.wulkanowy.data.db.AppDatabase
import io.github.wulkanowy.data.db.entities.Grade
import io.github.wulkanowy.data.db.entities.Semester
import io.github.wulkanowy.data.db.entities.Student
import io.github.wulkanowy.sdk.Sdk
import io.mockk.MockKAnnotations
import io.mockk.coEvery
import io.mockk.every
import io.mockk.impl.annotations.MockK
import kotlinx.coroutines.flow.filter
import kotlinx.coroutines.flow.first
import kotlinx.coroutines.runBlocking
import org.junit.After
import org.junit.Before
import org.junit.Test
import org.junit.runner.RunWith
import java.time.LocalDate.of
import java.time.LocalDateTime
import kotlin.test.assertEquals
import kotlin.test.assertFalse
import kotlin.test.assertTrue
@SdkSuppress(minSdkVersion = P)
@RunWith(AndroidJUnit4::class)
class GradeRepositoryTest {
@MockK
private lateinit var semesterMock: Semester
private lateinit var studentMock: Student
@MockK
private lateinit var gradeRemote: GradeRemote
private lateinit var gradeLocal: GradeLocal
private lateinit var testDb: AppDatabase
@Before
fun initApi() {
MockKAnnotations.init(this)
testDb = Room.inMemoryDatabaseBuilder(getApplicationContext(), AppDatabase::class.java).build()
gradeLocal = GradeLocal(testDb.gradeDao, testDb.gradeSummaryDao)
studentMock = getStudentMock()
every { semesterMock.studentId } returns 1
every { semesterMock.diaryId } returns 1
every { semesterMock.schoolYear } returns 2019
every { semesterMock.semesterId } returns 1
}
@After
fun closeDb() {
testDb.close()
}
@Test
fun markOlderThanRegisterDateAsRead() {
coEvery { gradeRemote.getGrades(studentMock, semesterMock) } returns (listOf(
createGradeLocal(5, 4.0, of(2019, 2, 25), "Ocena pojawiła się"),
createGradeLocal(5, 4.0, of(2019, 2, 26), "przed zalogowanie w aplikacji"),
createGradeLocal(5, 4.0, of(2019, 2, 27), "Ocena z dnia logowania"),
createGradeLocal(5, 4.0, of(2019, 2, 28), "Ocena jeszcze nowsza")
) to emptyList())
val grades = runBlocking {
GradeRepository(gradeLocal, gradeRemote)
.getGrades(studentMock, semesterMock, true)
.filter { it.status == Status.SUCCESS }.first().data!!.first.sortedByDescending { it.date }
}
assertFalse { grades[0].isRead }
assertFalse { grades[1].isRead }
assertTrue { grades[2].isRead }
assertTrue { grades[3].isRead }
}
@Test
fun mitigateOldGradesNotifications() {
val list = listOf(
createGradeLocal(5, 3.0, of(2019, 2, 25), "Jedna ocena"),
createGradeLocal(4, 4.0, of(2019, 2, 26), "Druga"),
createGradeLocal(3, 5.0, of(2019, 2, 27), "Trzecia")
)
runBlocking { gradeLocal.saveGrades(list) }
coEvery { gradeRemote.getGrades(studentMock, semesterMock) } returns (listOf(
createGradeLocal(5, 2.0, of(2019, 2, 25), "Ocena ma datę, jest inna, ale nie zostanie powiadomiona"),
createGradeLocal(4, 3.0, of(2019, 2, 26), "starszą niż ostatnia lokalnie"),
createGradeLocal(3, 4.0, of(2019, 2, 27), "Ta jest z tego samego dnia co ostatnia lokalnie"),
createGradeLocal(2, 5.0, of(2019, 2, 28), "Ta jest już w ogóle nowa")
) to emptyList())
val grades = runBlocking {
GradeRepository(gradeLocal, gradeRemote)
.getGrades(studentMock, semesterMock, true)
.filter { it.status == Status.SUCCESS }.first().data!!.first.sortedByDescending { it.date }
}
assertFalse { grades[0].isRead }
assertFalse { grades[1].isRead }
assertTrue { grades[2].isRead }
assertTrue { grades[3].isRead }
}
@Test
fun subtractLocaleDuplicateGrades() {
val list = listOf(
createGradeLocal(5, 3.0, of(2019, 2, 25), "Taka sama ocena"),
createGradeLocal(5, 3.0, of(2019, 2, 25), "Taka sama ocena"),
createGradeLocal(3, 5.0, of(2019, 2, 26), "Jakaś inna ocena")
)
runBlocking { gradeLocal.saveGrades(list) }
coEvery { gradeRemote.getGrades(studentMock, semesterMock) } returns (listOf(
createGradeLocal(5, 3.0, of(2019, 2, 25), "Taka sama ocena"),
createGradeLocal(3, 5.0, of(2019, 2, 26), "Jakaś inna ocena")
) to emptyList())
val grades = runBlocking {
GradeRepository(gradeLocal, gradeRemote)
.getGrades(studentMock, semesterMock, true)
.filter { it.status == Status.SUCCESS }.first().data!!
}
assertEquals(2, grades.first.size)
}
@Test
fun subtractRemoteDuplicateGrades() {
val list = listOf(
createGradeLocal(5, 3.0, of(2019, 2, 25), "Taka sama ocena"),
createGradeLocal(3, 5.0, of(2019, 2, 26), "Jakaś inna ocena")
)
runBlocking { gradeLocal.saveGrades(list) }
coEvery { gradeRemote.getGrades(studentMock, semesterMock) } returns (listOf(
createGradeLocal(5, 3.0, of(2019, 2, 25), "Taka sama ocena"),
createGradeLocal(5, 3.0, of(2019, 2, 25), "Taka sama ocena"),
createGradeLocal(3, 5.0, of(2019, 2, 26), "Jakaś inna ocena")
) to emptyList())
val grades = runBlocking {
GradeRepository(gradeLocal, gradeRemote)
.getGrades(studentMock, semesterMock, true)
.filter { it.status == Status.SUCCESS }.first().data!!
}
assertEquals(3, grades.first.size)
}
@Test
fun emptyLocal() {
runBlocking { gradeLocal.saveGrades(listOf()) }
coEvery { gradeRemote.getGrades(studentMock, semesterMock) } returns (listOf(
createGradeLocal(5, 3.0, of(2019, 2, 25), "Taka sama ocena"),
createGradeLocal(5, 3.0, of(2019, 2, 25), "Taka sama ocena"),
createGradeLocal(3, 5.0, of(2019, 2, 26), "Jakaś inna ocena")
) to emptyList())
val grades = runBlocking {
GradeRepository(gradeLocal, gradeRemote)
.getGrades(studentMock, semesterMock, true)
.filter { it.status == Status.SUCCESS }.first().data!!
}
assertEquals(3, grades.first.size)
}
@Test
fun emptyRemote() {
val list = listOf(
createGradeLocal(5, 3.0, of(2019, 2, 25), "Taka sama ocena"),
createGradeLocal(3, 5.0, of(2019, 2, 26), "Jakaś inna ocena")
)
runBlocking { gradeLocal.saveGrades(list) }
coEvery { gradeRemote.getGrades(studentMock, semesterMock) } returns (emptyList<Grade>() to emptyList())
val grades = runBlocking {
GradeRepository(gradeLocal, gradeRemote)
.getGrades(studentMock, semesterMock, true)
.filter { it.status == Status.SUCCESS }.first().data!!
}
assertEquals(0, grades.first.size)
}
private fun getStudentMock() = Student(
scrapperBaseUrl = "http://fakelog.cf",
email = "jan@fakelog.cf",
certificateKey = "",
classId = 0,
className = "",
isCurrent = false,
isParent = false,
loginMode = Sdk.Mode.SCRAPPER.name,
loginType = "STANDARD",
mobileBaseUrl = "",
password = "",
privateKey = "",
registrationDate = LocalDateTime.of(2019, 2, 27, 12, 0),
schoolName = "",
schoolShortName = "test",
schoolSymbol = "",
studentId = 0,
studentName = "",
symbol = "",
userLoginId = 0,
userName = ""
)
}

View file

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

View file

@ -1,112 +0,0 @@
package io.github.wulkanowy.data.repositories.gradestatistics
import androidx.room.Room
import androidx.test.core.app.ApplicationProvider
import androidx.test.ext.junit.runners.AndroidJUnit4
import io.github.wulkanowy.data.db.AppDatabase
import io.github.wulkanowy.data.db.entities.GradePointsStatistics
import io.github.wulkanowy.data.db.entities.GradeStatistics
import io.github.wulkanowy.data.db.entities.Semester
import kotlinx.coroutines.flow.first
import kotlinx.coroutines.runBlocking
import org.junit.After
import org.junit.Before
import org.junit.Test
import org.junit.runner.RunWith
import java.time.LocalDate.now
import kotlin.test.assertEquals
@RunWith(AndroidJUnit4::class)
class GradeStatisticsLocalTest {
private lateinit var gradeStatisticsLocal: GradeStatisticsLocal
private lateinit var testDb: AppDatabase
@Before
fun createDb() {
testDb = Room.inMemoryDatabaseBuilder(ApplicationProvider.getApplicationContext(), AppDatabase::class.java)
.build()
gradeStatisticsLocal = GradeStatisticsLocal(testDb.gradeStatistics, testDb.gradePointsStatistics)
}
@After
fun closeDb() {
testDb.close()
}
@Test
fun saveAndRead_subject() {
val list = listOf(
getGradeStatistics("Matematyka", 2, 1),
getGradeStatistics("Fizyka", 1, 2)
)
runBlocking { gradeStatisticsLocal.saveGradesStatistics(list) }
val stats = runBlocking { gradeStatisticsLocal.getGradesStatistics(getSemester(), false).first() }
assertEquals(1, stats.size)
assertEquals(stats[0].subject, "Matematyka")
}
@Test
fun saveAndRead_all() {
val list = listOf(
getGradeStatistics("Matematyka", 2, 1),
getGradeStatistics("Chemia", 2, 1),
getGradeStatistics("Fizyka", 1, 2)
)
runBlocking { gradeStatisticsLocal.saveGradesStatistics(list) }
val stats = runBlocking { gradeStatisticsLocal.getGradesStatistics(getSemester(), false).first() }
assertEquals(2, stats.size)
// assertEquals(3, stats.size)
// assertEquals(stats[0].subject, "Wszystkie") // now in main repo
assertEquals(stats[0].subject, "Matematyka")
assertEquals(stats[1].subject, "Chemia")
}
@Test
fun saveAndRead_points() {
val list = listOf(
getGradePointsStatistics("Matematyka", 2, 1),
getGradePointsStatistics("Chemia", 2, 1),
getGradePointsStatistics("Fizyka", 1, 2)
)
runBlocking { gradeStatisticsLocal.saveGradesPointsStatistics(list) }
val stats = runBlocking { gradeStatisticsLocal.getGradesPointsStatistics(getSemester()).first() }
with(stats[0]) {
assertEquals(subject, "Matematyka")
assertEquals(others, 5.0)
assertEquals(student, 5.0)
}
}
@Test
fun saveAndRead_subjectEmpty() {
runBlocking { gradeStatisticsLocal.saveGradesPointsStatistics(listOf()) }
val stats = runBlocking { gradeStatisticsLocal.getGradesPointsStatistics(getSemester()).first() }
assertEquals(emptyList(), stats)
}
@Test
fun saveAndRead_allEmpty() {
runBlocking { gradeStatisticsLocal.saveGradesPointsStatistics(listOf()) }
val stats = runBlocking { gradeStatisticsLocal.getGradesPointsStatistics(getSemester()).first() }
assertEquals(emptyList(), stats)
}
private fun getSemester(): Semester {
return Semester(2, 2, "", 2019, 1, 2, now(), now(), 1, 1)
}
private fun getGradeStatistics(subject: String, studentId: Int, semesterId: Int): GradeStatistics {
return GradeStatistics(studentId, semesterId, subject, 5, 5, false)
}
private fun getGradePointsStatistics(subject: String, studentId: Int, semesterId: Int): GradePointsStatistics {
return GradePointsStatistics(studentId, semesterId, subject, 5.0, 5.0)
}
}

View file

@ -1,51 +0,0 @@
package io.github.wulkanowy.data.repositories.luckynumber
import androidx.room.Room
import androidx.test.core.app.ApplicationProvider
import androidx.test.ext.junit.runners.AndroidJUnit4
import io.github.wulkanowy.data.db.AppDatabase
import io.github.wulkanowy.data.db.entities.LuckyNumber
import io.github.wulkanowy.data.db.entities.Student
import kotlinx.coroutines.flow.first
import kotlinx.coroutines.runBlocking
import org.junit.After
import org.junit.Before
import org.junit.Test
import org.junit.runner.RunWith
import java.time.LocalDate
import java.time.LocalDateTime.now
import kotlin.test.assertEquals
@RunWith(AndroidJUnit4::class)
class LuckyNumberLocalTest {
private lateinit var luckyNumberLocal: LuckyNumberLocal
private lateinit var testDb: AppDatabase
@Before
fun createDb() {
testDb = Room
.inMemoryDatabaseBuilder(ApplicationProvider.getApplicationContext(), AppDatabase::class.java)
.build()
luckyNumberLocal = LuckyNumberLocal(testDb.luckyNumberDao)
}
@After
fun closeDb() {
testDb.close()
}
@Test
fun saveAndReadTest() {
val number = LuckyNumber(1, LocalDate.of(2019, 1, 20), 14)
runBlocking { luckyNumberLocal.saveLuckyNumber(number) }
val student = Student("", "", "", "", "", "", false, "", "", "", 1, 1, "", "", "", "", "", "", 1, false, now())
val luckyNumber = runBlocking { luckyNumberLocal.getLuckyNumber(student, LocalDate.of(2019, 1, 20)).first() }
assertEquals(1, luckyNumber?.studentId)
assertEquals(LocalDate.of(2019, 1, 20), luckyNumber?.date)
assertEquals(14, luckyNumber?.luckyNumber)
}
}

View file

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

View file

@ -1,46 +0,0 @@
package io.github.wulkanowy.data.repositories.student
import android.content.Context
import androidx.room.Room
import androidx.test.core.app.ApplicationProvider
import androidx.test.ext.junit.runners.AndroidJUnit4
import io.github.wulkanowy.data.TestDispatchersProvider
import io.github.wulkanowy.data.db.AppDatabase
import io.github.wulkanowy.data.repositories.getStudent
import kotlinx.coroutines.runBlocking
import org.junit.After
import org.junit.Before
import org.junit.Test
import org.junit.runner.RunWith
import kotlin.test.assertEquals
@RunWith(AndroidJUnit4::class)
class StudentLocalTest {
private lateinit var studentLocal: StudentLocal
private lateinit var testDb: AppDatabase
private val student = getStudent()
@Before
fun createDb() {
val context = ApplicationProvider.getApplicationContext<Context>()
testDb = Room.inMemoryDatabaseBuilder(context, AppDatabase::class.java)
.build()
studentLocal = StudentLocal(testDb.studentDao, TestDispatchersProvider(), context)
}
@After
fun closeDb() {
testDb.close()
}
@Test
fun saveAndReadTest() {
runBlocking { studentLocal.saveStudents(listOf(student)) }
val student = runBlocking { studentLocal.getCurrentStudent(true) }
assertEquals("23", student?.schoolSymbol)
}
}

View file

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

View file

@ -1,59 +0,0 @@
package io.github.wulkanowy.data.repositories.timetable
import androidx.room.Room
import androidx.test.core.app.ApplicationProvider
import androidx.test.ext.junit.runners.AndroidJUnit4
import io.github.wulkanowy.data.db.AppDatabase
import io.github.wulkanowy.data.db.entities.Semester
import kotlinx.coroutines.flow.first
import kotlinx.coroutines.runBlocking
import org.junit.After
import org.junit.Before
import org.junit.Test
import org.junit.runner.RunWith
import java.time.LocalDate
import java.time.LocalDateTime.of
import kotlin.test.assertEquals
@RunWith(AndroidJUnit4::class)
class TimetableLocalTest {
private lateinit var timetableDb: TimetableLocal
private lateinit var testDb: AppDatabase
@Before
fun createDb() {
testDb = Room.inMemoryDatabaseBuilder(ApplicationProvider.getApplicationContext(), AppDatabase::class.java)
.build()
timetableDb = TimetableLocal(testDb.timetableDao)
}
@After
fun closeDb() {
testDb.close()
}
@Test
fun saveAndReadTest() {
val list = listOf(
createTimetableLocal(of(2018, 9, 10, 0, 0, 0), 1),
createTimetableLocal(of(2018, 9, 14, 0, 0, 0), 1),
createTimetableLocal(of(2018, 9, 17, 0, 0, 0), 1)
)
runBlocking { timetableDb.saveTimetable(list) }
val semester = Semester(1, 2, "", 1, 1, 2019, LocalDate.now(), LocalDate.now(), 1, 1)
val exams = runBlocking {
timetableDb.getTimetable(
semester = semester,
startDate = LocalDate.of(2018, 9, 10),
endDate = LocalDate.of(2018, 9, 14)
).first()
}
assertEquals(2, exams.size)
assertEquals(exams[0].date, LocalDate.of(2018, 9, 10))
assertEquals(exams[1].date, LocalDate.of(2018, 9, 14))
}
}

View file

@ -1,155 +0,0 @@
package io.github.wulkanowy.data.repositories.timetable
import android.os.Build.VERSION_CODES.P
import androidx.room.Room
import androidx.test.core.app.ApplicationProvider.getApplicationContext
import androidx.test.ext.junit.runners.AndroidJUnit4
import androidx.test.filters.SdkSuppress
import io.github.wulkanowy.data.Status
import io.github.wulkanowy.data.db.AppDatabase
import io.github.wulkanowy.data.repositories.getSemester
import io.github.wulkanowy.data.repositories.getStudent
import io.github.wulkanowy.services.alarm.TimetableNotificationSchedulerHelper
import io.mockk.MockKAnnotations
import io.mockk.coEvery
import io.mockk.impl.annotations.MockK
import kotlinx.coroutines.flow.filter
import kotlinx.coroutines.flow.first
import kotlinx.coroutines.runBlocking
import org.junit.After
import org.junit.Before
import org.junit.Test
import org.junit.runner.RunWith
import java.time.LocalDate
import java.time.LocalDateTime.of
import kotlin.test.assertEquals
@SdkSuppress(minSdkVersion = P)
@RunWith(AndroidJUnit4::class)
class TimetableRepositoryTest {
@MockK(relaxed = true)
private lateinit var timetableNotificationSchedulerHelper: TimetableNotificationSchedulerHelper
@MockK
private lateinit var timetableRemote: TimetableRemote
private lateinit var timetableLocal: TimetableLocal
private lateinit var testDb: AppDatabase
private val student = getStudent()
private val semester = getSemester()
@Before
fun initApi() {
MockKAnnotations.init(this)
testDb = Room.inMemoryDatabaseBuilder(getApplicationContext(), AppDatabase::class.java).build()
timetableLocal = TimetableLocal(testDb.timetableDao)
}
@After
fun closeDb() {
testDb.close()
}
@Test
fun copyRoomToCompletedFromPrevious() {
runBlocking {
timetableLocal.saveTimetable(listOf(
createTimetableLocal(of(2019, 3, 5, 8, 0), 1, "123", "Przyroda"),
createTimetableLocal(of(2019, 3, 5, 8, 50), 2, "321", "Religia"),
createTimetableLocal(of(2019, 3, 5, 9, 40), 3, "213", "W-F"),
createTimetableLocal(of(2019, 3, 5, 10, 30), 3, "213", "W-F", "Jan Kowalski")
))
}
coEvery { timetableRemote.getTimetable(student, semester, any(), any()) } returns listOf(
createTimetableLocal(of(2019, 3, 5, 8, 0), 1, "", "Przyroda"),
createTimetableLocal(of(2019, 3, 5, 8, 50), 2, "", "Religia"),
createTimetableLocal(of(2019, 3, 5, 9, 40), 3, "", "W-F"),
createTimetableLocal(of(2019, 3, 5, 10, 30), 4, "", "W-F")
)
val lessons = runBlocking {
TimetableRepository(timetableLocal, timetableRemote, timetableNotificationSchedulerHelper).getTimetable(
student = student,
semester = semester,
start = LocalDate.of(2019, 3, 5),
end = LocalDate.of(2019, 3, 5),
forceRefresh = true
).filter { it.status == Status.SUCCESS }.first().data.orEmpty()
}
assertEquals(4, lessons.size)
assertEquals("123", lessons[0].room)
assertEquals("321", lessons[1].room)
assertEquals("213", lessons[2].room)
}
@Test
fun copyTeacherToCompletedFromPrevious() {
val list = listOf(
createTimetableLocal(of(2019, 12, 23, 8, 0), 1, "123", "Matematyka", "Paweł Poniedziałkowski", false),
createTimetableLocal(of(2019, 12, 23, 8, 50), 2, "124", "Matematyka", "Paweł Poniedziałkowski", false),
createTimetableLocal(of(2019, 12, 23, 9, 40), 3, "125", "Język polski", "Joanna Wtorkowska", true),
createTimetableLocal(of(2019, 12, 23, 10, 40), 4, "126", "Język polski", "Joanna Wtorkowska", true),
createTimetableLocal(of(2019, 12, 24, 8, 0), 1, "123", "Język polski", "Joanna Wtorkowska", false),
createTimetableLocal(of(2019, 12, 24, 8, 50), 2, "124", "Język polski", "Joanna Wtorkowska", false),
createTimetableLocal(of(2019, 12, 24, 9, 40), 3, "125", "Język polski", "Joanna Środowska", true),
createTimetableLocal(of(2019, 12, 24, 10, 40), 4, "126", "Język polski", "Joanna Środowska", true),
createTimetableLocal(of(2019, 12, 25, 8, 0), 1, "123", "Matematyka", "", false),
createTimetableLocal(of(2019, 12, 25, 8, 50), 2, "124", "Matematyka", "", false),
createTimetableLocal(of(2019, 12, 25, 9, 40), 3, "125", "Matematyka", "", true),
createTimetableLocal(of(2019, 12, 25, 10, 40), 4, "126", "Matematyka", "", true)
)
runBlocking { timetableLocal.saveTimetable(list) }
coEvery { timetableRemote.getTimetable(student, semester, any(), any()) } returns listOf(
createTimetableLocal(of(2019, 12, 23, 8, 0), 1, "123", "Matematyka", "Paweł Poniedziałkowski", false),
createTimetableLocal(of(2019, 12, 23, 8, 50), 2, "124", "Matematyka", "Jakub Wtorkowski", true),
createTimetableLocal(of(2019, 12, 23, 9, 40), 3, "125", "Język polski", "Joanna Poniedziałkowska", false),
createTimetableLocal(of(2019, 12, 23, 10, 40), 4, "126", "Język polski", "Joanna Wtorkowska", true),
createTimetableLocal(of(2019, 12, 24, 8, 0), 1, "123", "Język polski", "", false),
createTimetableLocal(of(2019, 12, 24, 8, 50), 2, "124", "Język polski", "", true),
createTimetableLocal(of(2019, 12, 24, 9, 40), 3, "125", "Język polski", "", false),
createTimetableLocal(of(2019, 12, 24, 10, 40), 4, "126", "Język polski", "", true),
createTimetableLocal(of(2019, 12, 25, 8, 0), 1, "123", "Matematyka", "Paweł Środowski", false),
createTimetableLocal(of(2019, 12, 25, 8, 50), 2, "124", "Matematyka", "Paweł Czwartkowski", true),
createTimetableLocal(of(2019, 12, 25, 9, 40), 3, "125", "Matematyka", "Paweł Środowski", false),
createTimetableLocal(of(2019, 12, 25, 10, 40), 4, "126", "Matematyka", "Paweł Czwartkowski", true)
)
val lessons = runBlocking {
TimetableRepository(timetableLocal, timetableRemote, timetableNotificationSchedulerHelper).getTimetable(
student = student,
semester = semester,
start = LocalDate.of(2019, 12, 23),
end = LocalDate.of(2019, 12, 25),
forceRefresh = true
).filter { it.status == Status.SUCCESS }.first().data.orEmpty()
}
assertEquals(12, lessons.size)
assertEquals("Paweł Poniedziałkowski", lessons[0].teacher)
assertEquals("Jakub Wtorkowski", lessons[1].teacher)
assertEquals("Joanna Poniedziałkowska", lessons[2].teacher)
assertEquals("Joanna Wtorkowska", lessons[3].teacher)
assertEquals("Joanna Wtorkowska", lessons[4].teacher)
assertEquals("", lessons[5].teacher)
assertEquals("", lessons[6].teacher)
assertEquals("", lessons[7].teacher)
assertEquals("Paweł Środowski", lessons[8].teacher)
assertEquals("Paweł Czwartkowski", lessons[9].teacher)
assertEquals("Paweł Środowski", lessons[10].teacher)
assertEquals("Paweł Czwartkowski", lessons[11].teacher)
}
}

View file

@ -0,0 +1,33 @@
{
"agcgw":{
"backurl":"connect-dre.dbankcloud.cn",
"url":"connect-dre.hispace.hicloud.com"
},
"client":{
"cp_id":"890048000024105546",
"product_id":"",
"client_id":"",
"client_secret":"",
"app_id":"101440411",
"package_name":"io.github.wulkanowy.dev",
"api_key":""
},
"service":{
"analytics":{
"collector_url":"datacollector-dre.dt.hicloud.com,datacollector-dre.dt.dbankcloud.cn",
"resource_id":"p1",
"channel_id":""
},
"search":{
"url":"https://search-dre.cloud.huawei.com"
},
"cloudstorage":{
"storage_url":"https://ops-dre.agcstorage.link"
},
"ml":{
"mlservice_url":"ml-api-dre.ai.dbankcloud.com,ml-api-dre.ai.dbankcloud.cn"
}
},
"region":"DE",
"configuration_version":"1.0"
}

View file

@ -0,0 +1,19 @@
<vector xmlns:android="http://schemas.android.com/apk/res/android"
android:width="24dp"
android:height="24dp"
android:tint="#FFFFFF"
android:viewportWidth="24"
android:viewportHeight="24">
<group
android:scaleX="0.92"
android:scaleY="0.92"
android:translateX="0.96"
android:translateY="0.96">
<path
android:fillColor="#FFF"
android:pathData="M3.9512,2A2,2 0,0 0,2 4L2,18A2,2 0,0 0,4 20L10.0996,20C11.3596,21.24 13.09,22 15,22A7,7 0,0 0,15.7988 21.9551L15.7988,19.7832A4.85,4.85 0,0 1,15 19.8496C12.32,19.8496 10.1504,17.68 10.1504,15A4.85,4.85 0,0 1,15 10.1504C17.4677,10.1504 19.4978,11.9912 19.8047,14.375C20.566,14.3758 21.3108,14.5325 21.9922,14.834C21.9491,12.9905 21.2036,11.3226 20,10.0996L20,4A2,2 0,0 0,18 2L4,2A2,2 0,0 0,3.9512 2zM4,5L10,5L10,8L4,8L4,5zM12,5L18,5L18,8L12,8L12,5zM4,10L10.0996,10C9.2596,10.82 8.6291,11.85 8.2891,13L4,13L4,10zM14,12L14,15.6895L15.7988,16.7266L15.7988,14.9922L15.5,14.8203L15.5,12L14,12zM4,15L8,15C8,16.07 8.2399,17.09 8.6699,18L4,18L4,15z" />
<path
android:fillColor="#FFF"
android:pathData="m17.298,24v-8.1249h2.5c0.7143,0 1.3523,0.1618 1.9141,0.4855 0.5655,0.3199 1.0063,0.7775 1.3225,1.3728 0.3162,0.5915 0.4743,1.2649 0.4743,2.0201v0.3739c0,0.7552 -0.1562,1.4267 -0.4687,2.0145 -0.3088,0.5878 -0.7459,1.0435 -1.3114,1.3672C21.1633,23.8326 20.5253,23.9963 19.8148,24ZM18.9721,17.2311v5.4241h0.8091c0.6548,0 1.1551,-0.2139 1.5011,-0.6417 0.346,-0.4278 0.5227,-1.0398 0.5301,-1.8359v-0.4297c0,-0.8259 -0.1711,-1.4509 -0.5134,-1.875 -0.3423,-0.4278 -0.8426,-0.6417 -1.5011,-0.6417z" />
</group>
</vector>

Binary file not shown.

After

Width:  |  Height:  |  Size: 426 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 335 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 519 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 700 B

View file

@ -6,7 +6,7 @@ import javax.inject.Singleton
@Singleton
@Suppress("UNUSED_PARAMETER")
class FirebaseAnalyticsHelper @Inject constructor() {
class AnalyticsHelper @Inject constructor() {
fun logEvent(name: String, vararg params: Pair<String, Any?>) {
// do nothing
@ -15,4 +15,8 @@ class FirebaseAnalyticsHelper @Inject constructor() {
fun setCurrentScreen(activity: Activity, name: String?) {
// do nothing
}
fun popCurrentScreen(name: String?) {
// do nothing
}
}

View file

@ -8,6 +8,6 @@ open class TimberTreeNoOp : Timber.Tree() {
override fun log(priority: Int, tag: String?, message: String, t: Throwable?) {}
}
class CrashlyticsTree : TimberTreeNoOp()
class CrashLogTree : TimberTreeNoOp()
class CrashlyticsExceptionTree : TimberTreeNoOp()
class CrashLogExceptionTree : TimberTreeNoOp()

View file

@ -0,0 +1,17 @@
package io.github.wulkanowy.utils
import android.app.Activity
import android.view.View
import javax.inject.Inject
@Suppress("UNUSED_PARAMETER")
class UpdateHelper @Inject constructor() {
lateinit var messageContainer: View
fun checkAndInstallUpdates(activity: Activity) {}
fun onActivityResult(requestCode: Int, resultCode: Int) {}
fun onResume(activity: Activity) {}
}

View file

@ -0,0 +1,39 @@
package io.github.wulkanowy.utils
import android.app.Activity
import android.content.Context
import android.os.Bundle
import com.huawei.hms.analytics.HiAnalytics
import dagger.hilt.android.qualifiers.ApplicationContext
import javax.inject.Inject
import javax.inject.Singleton
@Singleton
class AnalyticsHelper @Inject constructor(
@ApplicationContext private val context: Context
) {
private val analytics by lazy { HiAnalytics.getInstance(context) }
fun logEvent(name: String, vararg params: Pair<String, Any?>) {
Bundle().apply {
params.forEach {
if (it.second == null) return@forEach
when (it.second) {
is String, is String? -> putString(it.first, it.second as String)
is Int, is Int? -> putInt(it.first, it.second as Int)
is Boolean, is Boolean? -> putBoolean(it.first, it.second as Boolean)
}
}
analytics.onEvent(name, this)
}
}
fun setCurrentScreen(activity: Activity, name: String?) {
analytics.pageStart(name, activity::class.simpleName)
}
fun popCurrentScreen(name: String?) {
analytics.pageEnd(name)
}
}

View file

@ -0,0 +1,53 @@
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) {
private val connectCrash by lazy { AGConnectCrash.getInstance() }
override fun log(priority: Int, tag: String?, message: String, t: Throwable?) {
if (skipLog(priority, tag, message, t)) return
connectCrash.log(format(priority, tag, message))
}
}
class CrashLogExceptionTree : FormatterPriorityTree(Log.ERROR) {
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
// Disabled due to a bug in the Huawei library
/*connectCrash.setCustomKey("priority", priority)
connectCrash.setCustomKey("tag", tag.orEmpty())
connectCrash.setCustomKey("message", message)
if (t != null) {
connectCrash.recordException(t)
} else {
connectCrash.recordException(StackTraceRecorder(format(priority, tag, message)))
}*/
}
}

View file

@ -0,0 +1,17 @@
package io.github.wulkanowy.utils
import android.app.Activity
import android.view.View
import javax.inject.Inject
@Suppress("UNUSED_PARAMETER")
class UpdateHelper @Inject constructor() {
lateinit var messageContainer: View
fun checkAndInstallUpdates(activity: Activity) {}
fun onActivityResult(requestCode: Int, resultCode: Int) {}
fun onResume(activity: Activity) {}
}

View file

@ -9,6 +9,29 @@
<uses-permission android:name="android.permission.RECEIVE_BOOT_COMPLETED" />
<uses-permission android:name="android.permission.VIBRATE" />
<queries>
<intent>
<action android:name="android.intent.action.VIEW" />
<data android:scheme="http" />
</intent>
<intent>
<action android:name="android.intent.action.VIEW" />
<data android:scheme="https" />
</intent>
<intent>
<action android:name="android.intent.action.VIEW" />
<data android:scheme="mailto" />
</intent>
<intent>
<action android:name="android.intent.action.VIEW" />
<data android:scheme="tel" />
</intent>
<intent>
<action android:name="android.intent.action.VIEW" />
<data android:scheme="geo" />
</intent>
</queries>
<application
android:name=".WulkanowyApp"
android:allowBackup="false"
@ -33,7 +56,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"
@ -45,7 +68,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"
@ -110,6 +133,10 @@
android:resource="@xml/provider_paths" />
</provider>
<meta-data
android:name="install_channel"
android:value="${install_channel}" />
<!-- workaround for https://github.com/firebase/firebase-android-sdk/issues/473 enabled:false -->
<!-- https://firebase.googleblog.com/2017/03/take-control-of-your-firebase-init-on.html -->
<provider

View file

@ -33,6 +33,18 @@
},
{
"displayName": "Mateusz Idziejczak",
"githubUsername": "PanTajemnic"
"githubUsername": "Luncenok"
},
{
"displayName": "MRmlik12",
"githubUsername": "MRmlik12"
},
{
"displayName": "Damian Czupryn",
"githubUsername": "Daxxxis"
},
{
"displayName": "Kamil Studziński",
"githubUsername": "studzinskik"
}
]

View file

@ -1,21 +1,26 @@
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
import fr.bipi.tressence.file.FileLoggerTree
import io.github.wulkanowy.data.repositories.PreferencesRepository
import io.github.wulkanowy.ui.base.ThemeManager
import io.github.wulkanowy.utils.ActivityLifecycleLogger
import io.github.wulkanowy.utils.AnalyticsHelper
import io.github.wulkanowy.utils.AppInfo
import io.github.wulkanowy.utils.CrashlyticsExceptionTree
import io.github.wulkanowy.utils.CrashlyticsTree
import io.github.wulkanowy.utils.CrashLogExceptionTree
import io.github.wulkanowy.utils.CrashLogTree
import io.github.wulkanowy.utils.DebugLogTree
import timber.log.Timber
import javax.inject.Inject
@ -32,23 +37,32 @@ class WulkanowyApp : Application(), Configuration.Provider {
@Inject
lateinit var appInfo: AppInfo
@Inject
lateinit var preferencesRepository: PreferencesRepository
@Inject
lateinit var analyticsHelper: AnalyticsHelper
override fun attachBaseContext(base: Context?) {
super.attachBaseContext(base)
MultiDex.install(this)
}
@SuppressLint("UnsafeOptInUsageWarning")
override fun onCreate() {
super.onCreate()
Lingver.init(this)
FragmentManager.enableNewStateManager(false)
initializeAppLanguage()
themeManager.applyDefaultTheme()
initLogging()
fixWebViewLocale()
}
private fun initLogging() {
if (appInfo.isDebug) {
Timber.plant(DebugLogTree())
Timber.plant(FileLoggerTree.Builder()
Timber.plant(
FileLoggerTree.Builder()
.withFileName("wulkanowy.%g.log")
.withDirName(applicationContext.filesDir.absolutePath)
.withFileLimit(10)
@ -56,12 +70,32 @@ class WulkanowyApp : Application(), Configuration.Provider {
.build()
)
} else {
Timber.plant(CrashlyticsExceptionTree())
Timber.plant(CrashlyticsTree())
Timber.plant(CrashLogExceptionTree())
Timber.plant(CrashLogTree())
}
registerActivityLifecycleCallbacks(ActivityLifecycleLogger())
}
private fun initializeAppLanguage() {
Lingver.init(this)
if (preferencesRepository.appLanguage == "system") {
Lingver.getInstance().setFollowSystemLocale(this)
analyticsHelper.logEvent("language", "startup" to appInfo.systemLanguage)
} else {
analyticsHelper.logEvent("language", "startup" to preferencesRepository.appLanguage)
}
}
private fun fixWebViewLocale() {
//https://stackoverflow.com/questions/40398528/android-webview-language-changes-abruptly-on-android-7-0-and-above
try {
WebView(this).destroy()
} catch (e: Exception) {
//Ignore exceptions
}
}
override fun getWorkManagerConfiguration() = Configuration.Builder()
.setWorkerFactory(workerFactory)
.setMinimumLoggingLevel(if (appInfo.isDebug) VERBOSE else INFO)

View file

@ -11,17 +11,18 @@ import com.chuckerteam.chucker.api.RetentionManager
import dagger.Module
import dagger.Provides
import dagger.hilt.InstallIn
import dagger.hilt.android.components.ApplicationComponent
import dagger.hilt.android.qualifiers.ApplicationContext
import dagger.hilt.components.SingletonComponent
import io.github.wulkanowy.data.db.AppDatabase
import io.github.wulkanowy.data.db.SharedPrefProvider
import io.github.wulkanowy.data.repositories.preferences.PreferencesRepository
import io.github.wulkanowy.data.repositories.PreferencesRepository
import io.github.wulkanowy.sdk.Sdk
import io.github.wulkanowy.utils.AppInfo
import timber.log.Timber
import javax.inject.Singleton
@Module
@InstallIn(ApplicationComponent::class)
@InstallIn(SingletonComponent::class)
internal class RepositoryModule {
@Singleton
@ -33,13 +34,21 @@ internal class RepositoryModule {
setSimpleHttpLogger { Timber.d(it) }
// for debug only
addInterceptor(ChuckerInterceptor(context, chuckerCollector), true)
addInterceptor(
ChuckerInterceptor.Builder(context)
.collector(chuckerCollector)
.alwaysReadResponseBody(true)
.build(), network = true
)
}
}
@Singleton
@Provides
fun provideChuckerCollector(@ApplicationContext context: Context, prefRepository: PreferencesRepository): ChuckerCollector {
fun provideChuckerCollector(
@ApplicationContext context: Context,
prefRepository: PreferencesRepository
): ChuckerCollector {
return ChuckerCollector(
context = context,
showNotification = prefRepository.isDebugNotificationEnable,
@ -49,7 +58,11 @@ internal class RepositoryModule {
@Singleton
@Provides
fun provideDatabase(@ApplicationContext context: Context, sharedPrefProvider: SharedPrefProvider) = AppDatabase.newInstance(context, sharedPrefProvider)
fun provideDatabase(
@ApplicationContext context: Context,
sharedPrefProvider: SharedPrefProvider,
appInfo: AppInfo
) = AppDatabase.newInstance(context, sharedPrefProvider, appInfo)
@Singleton
@Provides
@ -61,7 +74,8 @@ internal class RepositoryModule {
@Singleton
@Provides
fun provideSharedPref(@ApplicationContext context: Context): SharedPreferences = PreferenceManager.getDefaultSharedPreferences(context)
fun provideSharedPref(@ApplicationContext context: Context): SharedPreferences =
PreferenceManager.getDefaultSharedPreferences(context)
@Singleton
@Provides
@ -81,11 +95,16 @@ internal class RepositoryModule {
@Singleton
@Provides
fun provideGradeStatisticsDao(database: AppDatabase) = database.gradeStatistics
fun provideGradePartialStatisticsDao(database: AppDatabase) = database.gradePartialStatisticsDao
@Singleton
@Provides
fun provideGradePointsStatisticsDao(database: AppDatabase) = database.gradePointsStatistics
fun provideGradeSemesterStatisticsDao(database: AppDatabase) =
database.gradeSemesterStatisticsDao
@Singleton
@Provides
fun provideGradePointsStatisticsDao(database: AppDatabase) = database.gradePointsStatisticsDao
@Singleton
@Provides
@ -150,4 +169,16 @@ internal class RepositoryModule {
@Singleton
@Provides
fun provideSchoolInfoDao(database: AppDatabase) = database.schoolDao
@Singleton
@Provides
fun provideConferenceDao(database: AppDatabase) = database.conferenceDao
@Singleton
@Provides
fun provideTimetableAdditionalDao(database: AppDatabase) = database.timetableAdditionalDao
@Singleton
@Provides
fun provideStudentInfoDao(database: AppDatabase) = database.studentInfoDao
}

View file

@ -1,6 +1,6 @@
package io.github.wulkanowy.data
data class Resource<out T>(val status: Status, val data: T?, val error: Throwable?) {
data class Resource<T>(val status: Status, val data: T?, val error: Throwable?) {
companion object {
fun <T> success(data: T?): Resource<T> {
return Resource(Status.SUCCESS, data, null)

View file

@ -6,14 +6,15 @@ 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.ExamDao
import io.github.wulkanowy.data.db.dao.GradeDao
import io.github.wulkanowy.data.db.dao.GradePartialStatisticsDao
import io.github.wulkanowy.data.db.dao.GradePointsStatisticsDao
import io.github.wulkanowy.data.db.dao.GradeStatisticsDao
import io.github.wulkanowy.data.db.dao.GradeSemesterStatisticsDao
import io.github.wulkanowy.data.db.dao.GradeSummaryDao
import io.github.wulkanowy.data.db.dao.HomeworkDao
import io.github.wulkanowy.data.db.dao.LuckyNumberDao
@ -26,16 +27,20 @@ import io.github.wulkanowy.data.db.dao.ReportingUnitDao
import io.github.wulkanowy.data.db.dao.SchoolDao
import io.github.wulkanowy.data.db.dao.SemesterDao
import io.github.wulkanowy.data.db.dao.StudentDao
import io.github.wulkanowy.data.db.dao.StudentInfoDao
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.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.Exam
import io.github.wulkanowy.data.db.entities.Grade
import io.github.wulkanowy.data.db.entities.GradePartialStatistics
import io.github.wulkanowy.data.db.entities.GradePointsStatistics
import io.github.wulkanowy.data.db.entities.GradeStatistics
import io.github.wulkanowy.data.db.entities.GradeSemesterStatistics
import io.github.wulkanowy.data.db.entities.GradeSummary
import io.github.wulkanowy.data.db.entities.Homework
import io.github.wulkanowy.data.db.entities.LuckyNumber
@ -48,9 +53,11 @@ import io.github.wulkanowy.data.db.entities.ReportingUnit
import io.github.wulkanowy.data.db.entities.School
import io.github.wulkanowy.data.db.entities.Semester
import io.github.wulkanowy.data.db.entities.Student
import io.github.wulkanowy.data.db.entities.StudentInfo
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.migrations.Migration10
import io.github.wulkanowy.data.db.migrations.Migration11
import io.github.wulkanowy.data.db.migrations.Migration12
@ -70,13 +77,22 @@ import io.github.wulkanowy.data.db.migrations.Migration24
import io.github.wulkanowy.data.db.migrations.Migration25
import io.github.wulkanowy.data.db.migrations.Migration26
import io.github.wulkanowy.data.db.migrations.Migration27
import io.github.wulkanowy.data.db.migrations.Migration28
import io.github.wulkanowy.data.db.migrations.Migration29
import io.github.wulkanowy.data.db.migrations.Migration3
import io.github.wulkanowy.data.db.migrations.Migration30
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.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
@ -90,8 +106,9 @@ import javax.inject.Singleton
AttendanceSummary::class,
Grade::class,
GradeSummary::class,
GradeStatistics::class,
GradePartialStatistics::class,
GradePointsStatistics::class,
GradeSemesterStatistics::class,
Message::class,
MessageAttachment::class,
Note::class,
@ -103,7 +120,10 @@ import javax.inject.Singleton
Recipient::class,
MobileDevice::class,
Teacher::class,
School::class
School::class,
Conference::class,
TimetableAdditional::class,
StudentInfo::class,
],
version = AppDatabase.VERSION_SCHEMA,
exportSchema = true
@ -112,10 +132,9 @@ import javax.inject.Singleton
abstract class AppDatabase : RoomDatabase() {
companion object {
const val VERSION_SCHEMA = 27
const val VERSION_SCHEMA = 35
fun getMigrations(sharedPrefProvider: SharedPrefProvider): Array<Migration> {
return arrayOf(
fun getMigrations(sharedPrefProvider: SharedPrefProvider, appInfo: AppInfo) = arrayOf(
Migration2(),
Migration3(),
Migration4(),
@ -142,18 +161,27 @@ abstract class AppDatabase : RoomDatabase() {
Migration25(),
Migration26(),
Migration27(),
Migration28(),
Migration29(),
Migration30(),
Migration31(),
Migration32(),
Migration33(),
Migration34(),
Migration35(appInfo)
)
}
fun newInstance(context: Context, sharedPrefProvider: SharedPrefProvider): AppDatabase {
return Room.databaseBuilder(context, AppDatabase::class.java, "wulkanowy_database")
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))
.addMigrations(*getMigrations(sharedPrefProvider, appInfo))
.build()
}
}
abstract val studentDao: StudentDao
@ -171,9 +199,11 @@ abstract class AppDatabase : RoomDatabase() {
abstract val gradeSummaryDao: GradeSummaryDao
abstract val gradeStatistics: GradeStatisticsDao
abstract val gradePartialStatisticsDao: GradePartialStatisticsDao
abstract val gradePointsStatistics: GradePointsStatisticsDao
abstract val gradePointsStatisticsDao: GradePointsStatisticsDao
abstract val gradeSemesterStatisticsDao: GradeSemesterStatisticsDao
abstract val messagesDao: MessagesDao
@ -198,4 +228,10 @@ abstract class AppDatabase : RoomDatabase() {
abstract val teacherDao: TeacherDao
abstract val schoolDao: SchoolDao
abstract val conferenceDao: ConferenceDao
abstract val timetableAdditionalDao: TimetableAdditionalDao
abstract val studentInfoDao: StudentInfoDao
}

View file

@ -1,8 +1,9 @@
package io.github.wulkanowy.data.db
import androidx.room.TypeConverter
import com.google.gson.Gson
import com.google.gson.reflect.TypeToken
import com.squareup.moshi.Moshi
import com.squareup.moshi.Types
import io.github.wulkanowy.data.db.adapters.PairAdapterFactory
import java.time.Instant
import java.time.LocalDate
import java.time.LocalDateTime
@ -12,6 +13,16 @@ import java.util.Date
class Converters {
private val moshi by lazy { Moshi.Builder().add(PairAdapterFactory).build() }
private val integerListAdapter by lazy {
moshi.adapter<List<Int>>(Types.newParameterizedType(List::class.java, Integer::class.java))
}
private val stringListPairAdapter by lazy {
moshi.adapter<List<Pair<String, String>>>(Types.newParameterizedType(List::class.java, Pair::class.java, String::class.java, String::class.java))
}
@TypeConverter
fun timestampToDate(value: Long?): LocalDate? = value?.run {
Date(value).toInstant().atZone(ZoneOffset.UTC).toLocalDate()
@ -39,22 +50,22 @@ class Converters {
fun intToMonth(value: Int?) = value?.let { Month.of(it) }
@TypeConverter
fun intListToGson(list: List<Int>): String {
return Gson().toJson(list)
fun intListToJson(list: List<Int>): String {
return integerListAdapter.toJson(list)
}
@TypeConverter
fun gsonToIntList(value: String): List<Int> {
return Gson().fromJson(value, object : TypeToken<List<Int>>() {}.type)
fun jsonToIntList(value: String): List<Int> {
return integerListAdapter.fromJson(value).orEmpty()
}
@TypeConverter
fun stringPairListToGson(list: List<Pair<String, String>>): String {
return Gson().toJson(list)
fun stringPairListToJson(list: List<Pair<String, String>>): String {
return stringListPairAdapter.toJson(list)
}
@TypeConverter
fun gsonToStringPairList(value: String): List<Pair<String, String>> {
return Gson().fromJson(value, object : TypeToken<List<Pair<String, String>>>() {}.type)
fun jsonToStringPairList(value: String): List<Pair<String, String>> {
return stringListPairAdapter.fromJson(value).orEmpty()
}
}

View file

@ -6,7 +6,9 @@ import javax.inject.Inject
import javax.inject.Singleton
@Singleton
class SharedPrefProvider @Inject constructor(private val sharedPref: SharedPreferences) {
class SharedPrefProvider @Inject constructor(
private val sharedPref: SharedPreferences
) {
companion object {
const val APP_VERSION_CODE_KEY = "app_version_code"

View file

@ -0,0 +1,68 @@
package io.github.wulkanowy.data.db.adapters
import com.squareup.moshi.JsonAdapter
import com.squareup.moshi.JsonReader
import com.squareup.moshi.JsonWriter
import com.squareup.moshi.Moshi
import com.squareup.moshi.Types
import java.lang.reflect.ParameterizedType
import java.lang.reflect.Type
object PairAdapterFactory : JsonAdapter.Factory {
override fun create(type: Type, annotations: MutableSet<out Annotation>, moshi: Moshi): JsonAdapter<*>? {
if (type !is ParameterizedType || List::class.java != type.rawType) return null
if (type.actualTypeArguments[0] != Pair::class.java) return null
val listType = Types.newParameterizedType(List::class.java, Map::class.java, String::class.java)
val listAdapter = moshi.adapter<List<Map<String, String>>>(listType)
val mapType = Types.newParameterizedType(MutableMap::class.java, String::class.java, String::class.java)
val mapAdapter = moshi.adapter<Map<String, String>>(mapType)
return PairAdapter(listAdapter, mapAdapter)
}
private class PairAdapter(
private val listAdapter: JsonAdapter<List<Map<String, String>>>,
private val mapAdapter: JsonAdapter<Map<String, String>>,
) : JsonAdapter<List<Pair<String, String>>>() {
override fun toJson(writer: JsonWriter, value: List<Pair<String, String>>?) {
writer.beginArray()
value?.forEach {
writer.beginObject()
writer.name("first").value(it.first)
writer.name("second").value(it.second)
writer.endObject()
}
writer.endArray()
}
override fun fromJson(reader: JsonReader): List<Pair<String, String>>? {
return if (reader.peek() == JsonReader.Token.BEGIN_OBJECT) deserializeMoshiMap(reader)
else deserializeGsonPair(reader)
}
// for compatibility with 0.21.0
private fun deserializeMoshiMap(reader: JsonReader): List<Pair<String, String>>? {
val map = mapAdapter.fromJson(reader) ?: return null
return map.entries.map {
it.key to it.value
}
}
private fun deserializeGsonPair(reader: JsonReader): List<Pair<String, String>>? {
val list = listAdapter.fromJson(reader) ?: return null
return list.map {
require(it.size == 2) {
"pair with more or less than two elements: $list"
}
it["first"].orEmpty() to it["second"].orEmpty()
}
}
}
}

View file

@ -12,5 +12,5 @@ import javax.inject.Singleton
interface CompletedLessonsDao : BaseDao<CompletedLesson> {
@Query("SELECT * FROM CompletedLesson WHERE diary_id = :diaryId AND student_id = :studentId AND date >= :from AND date <= :end")
fun loadAll(diaryId: Int, studentId: Int, from: LocalDate, end: LocalDate): Flow<List<CompletedLesson>>
fun loadAll(studentId: Int, diaryId: Int, from: LocalDate, end: LocalDate): Flow<List<CompletedLesson>>
}

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.Conference
import kotlinx.coroutines.flow.Flow
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>>
}

View file

@ -0,0 +1,13 @@
package io.github.wulkanowy.data.db.dao
import androidx.room.Dao
import androidx.room.Query
import io.github.wulkanowy.data.db.entities.GradePartialStatistics
import kotlinx.coroutines.flow.Flow
@Dao
interface GradePartialStatisticsDao : BaseDao<GradePartialStatistics> {
@Query("SELECT * FROM GradePartialStatistics WHERE student_id = :studentId AND semester_id = :semesterId")
fun loadAll(semesterId: Int, studentId: Int): Flow<List<GradePartialStatistics>>
}

View file

@ -0,0 +1,13 @@
package io.github.wulkanowy.data.db.dao
import androidx.room.Dao
import androidx.room.Query
import io.github.wulkanowy.data.db.entities.GradeSemesterStatistics
import kotlinx.coroutines.flow.Flow
@Dao
interface GradeSemesterStatisticsDao : BaseDao<GradeSemesterStatistics> {
@Query("SELECT * FROM GradeSemesterStatistics WHERE student_id = :studentId AND semester_id = :semesterId")
fun loadAll(semesterId: Int, studentId: Int): Flow<List<GradeSemesterStatistics>>
}

View file

@ -1,18 +0,0 @@
package io.github.wulkanowy.data.db.dao
import androidx.room.Dao
import androidx.room.Query
import io.github.wulkanowy.data.db.entities.GradeStatistics
import kotlinx.coroutines.flow.Flow
import javax.inject.Singleton
@Singleton
@Dao
interface GradeStatisticsDao : BaseDao<GradeStatistics> {
@Query("SELECT * FROM GradesStatistics WHERE student_id = :studentId AND semester_id = :semesterId AND subject = :subjectName AND is_semester = :isSemester")
fun loadSubject(semesterId: Int, studentId: Int, subjectName: String, isSemester: Boolean): Flow<List<GradeStatistics>>
@Query("SELECT * FROM GradesStatistics WHERE student_id = :studentId AND semester_id = :semesterId AND is_semester = :isSemester")
fun loadAll(semesterId: Int, studentId: Int, isSemester: Boolean): Flow<List<GradeStatistics>>
}

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

@ -12,7 +12,7 @@ interface MessagesDao : BaseDao<Message> {
@Transaction
@Query("SELECT * FROM Messages WHERE student_id = :studentId AND message_id = :messageId")
fun loadMessageWithAttachment(studentId: Int, messageId: Int): Flow<MessageWithAttachment>
fun loadMessageWithAttachment(studentId: Int, messageId: Int): Flow<MessageWithAttachment?>
@Query("SELECT * FROM Messages WHERE student_id = :studentId AND folder_id = :folder ORDER BY date DESC")
fun loadAll(studentId: Int, folder: Int): Flow<List<Message>>

View file

@ -8,6 +8,6 @@ import kotlinx.coroutines.flow.Flow
@Dao
interface MobileDeviceDao : BaseDao<MobileDevice> {
@Query("SELECT * FROM MobileDevices WHERE student_id = :studentId ORDER BY date DESC")
fun loadAll(studentId: Int): Flow<List<MobileDevice>>
@Query("SELECT * FROM MobileDevices WHERE student_id = :userLoginId ORDER BY date DESC")
fun loadAll(userLoginId: Int): Flow<List<MobileDevice>>
}

View file

@ -9,6 +9,6 @@ import javax.inject.Singleton
@Dao
interface RecipientDao : BaseDao<Recipient> {
@Query("SELECT * FROM Recipients WHERE student_id = :studentId AND role = :role AND unit_id = :unitId")
suspend fun load(studentId: Int, role: Int, unitId: 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

@ -6,7 +6,9 @@ import androidx.room.Insert
import androidx.room.OnConflictStrategy.ABORT
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.StudentNickAndAvatar
import io.github.wulkanowy.data.db.entities.StudentWithSemesters
import javax.inject.Singleton
@ -20,11 +22,14 @@ interface StudentDao {
@Delete
suspend fun delete(student: Student)
@Update(entity = Student::class)
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,15 @@
package io.github.wulkanowy.data.db.dao
import androidx.room.Dao
import androidx.room.Query
import io.github.wulkanowy.data.db.entities.StudentInfo
import kotlinx.coroutines.flow.Flow
import javax.inject.Singleton
@Singleton
@Dao
interface StudentInfoDao : BaseDao<StudentInfo> {
@Query("SELECT * FROM StudentInfo WHERE student_id = :studentId")
fun loadStudentInfo(studentId: Int): Flow<StudentInfo?>
}

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.TimetableAdditional
import kotlinx.coroutines.flow.Flow
import java.time.LocalDate
import javax.inject.Singleton
@Dao
@Singleton
interface TimetableAdditionalDao : BaseDao<TimetableAdditional> {
@Query("SELECT * FROM TimetableAdditional 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<TimetableAdditional>>
}

View file

@ -0,0 +1,35 @@
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.LocalDateTime
@Entity(tableName = "Conferences")
data class Conference(
@ColumnInfo(name = "student_id")
val studentId: Int,
@ColumnInfo(name = "diary_id")
val diaryId: Int,
val title: String,
val subject: String,
val agenda: String,
@ColumnInfo(name = "present_on_conference")
val presentOnConference: String,
@ColumnInfo(name = "conference_id")
val conferenceId: Int,
val date: LocalDateTime
) : Serializable {
@PrimaryKey(autoGenerate = true)
var id: Long = 0
}

View file

@ -0,0 +1,33 @@
package io.github.wulkanowy.data.db.entities
import androidx.room.ColumnInfo
import androidx.room.Entity
import androidx.room.PrimaryKey
@Entity(tableName = "GradePartialStatistics")
data class GradePartialStatistics(
@ColumnInfo(name = "student_id")
val studentId: Int,
@ColumnInfo(name = "semester_id")
val semesterId: Int,
val subject: String,
@ColumnInfo(name = "class_average")
val classAverage: String,
@ColumnInfo(name = "student_average")
val studentAverage: String,
@ColumnInfo(name = "class_amounts")
val classAmounts: List<Int>,
@ColumnInfo(name = "student_amounts")
val studentAmounts: List<Int>
) {
@PrimaryKey(autoGenerate = true)
var id: Long = 0
}

View file

@ -4,8 +4,8 @@ import androidx.room.ColumnInfo
import androidx.room.Entity
import androidx.room.PrimaryKey
@Entity(tableName = "GradesStatistics")
data class GradeStatistics(
@Entity(tableName = "GradeSemesterStatistics")
data class GradeSemesterStatistics(
@ColumnInfo(name = "student_id")
val studentId: Int,
@ -15,13 +15,14 @@ data class GradeStatistics(
val subject: String,
val grade: Int,
val amounts: List<Int>,
val amount: Int,
@ColumnInfo(name = "is_semester")
val semester: Boolean
@ColumnInfo(name = "student_grade")
val studentGrade: Int
) {
@PrimaryKey(autoGenerate = true)
var id: Long = 0
@Transient
var average: String = ""
}

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,
@ -36,12 +36,6 @@ data class Message(
var unread: Boolean,
@ColumnInfo(name = "unread_by")
val unreadBy: Int,
@ColumnInfo(name = "read_by")
val readBy: Int,
val removed: Boolean,
@ColumnInfo(name = "has_attachments")
@ -54,5 +48,11 @@ data class Message(
@ColumnInfo(name = "is_notified")
var isNotified: Boolean = true
@ColumnInfo(name = "unread_by")
var unreadBy: Int = 0
@ColumnInfo(name = "read_by")
var readBy: Int = 0
var content: String = ""
}

View file

@ -10,7 +10,7 @@ import java.time.LocalDateTime
data class MobileDevice(
@ColumnInfo(name = "student_id")
val studentId: Int,
val userLoginId: Int,
@ColumnInfo(name = "device_id")
val deviceId: Int,

View file

@ -12,7 +12,7 @@ data class ReportingUnit(
val studentId: Int,
@ColumnInfo(name = "real_id")
val realId: Int,
val unitId: Int,
@ColumnInfo(name = "short")
val shortName: String,

View file

@ -7,7 +7,13 @@ import androidx.room.PrimaryKey
import java.io.Serializable
import java.time.LocalDateTime
@Entity(tableName = "Students", indices = [Index(value = ["email", "symbol", "student_id", "school_id", "class_id"], unique = true)])
@Entity(
tableName = "Students",
indices = [Index(
value = ["email", "symbol", "student_id", "school_id", "class_id"],
unique = true
)]
)
data class Student(
@ColumnInfo(name = "scrapper_base_url")
@ -73,4 +79,9 @@ data class Student(
@PrimaryKey(autoGenerate = true)
var id: Long = 0
var nick = ""
@ColumnInfo(name = "avatar_color")
var avatarColor = 0L
}

View file

@ -0,0 +1,85 @@
package io.github.wulkanowy.data.db.entities
import androidx.room.ColumnInfo
import androidx.room.Embedded
import androidx.room.Entity
import androidx.room.PrimaryKey
import io.github.wulkanowy.data.enums.Gender
import java.io.Serializable
import java.time.LocalDate
@Entity(tableName = "StudentInfo")
data class StudentInfo(
@ColumnInfo(name = "student_id")
val studentId: Int,
@ColumnInfo(name = "full_name")
val fullName: String,
@ColumnInfo(name = "first_name")
val firstName: String,
@ColumnInfo(name = "second_name")
val secondName: String,
val surname: String,
@ColumnInfo(name = "birth_date")
val birthDate: LocalDate,
@ColumnInfo(name = "birth_place")
val birthPlace: String,
val gender: Gender,
@ColumnInfo(name = "has_polish_citizenship")
val hasPolishCitizenship: Boolean,
@ColumnInfo(name = "family_name")
val familyName: String,
@ColumnInfo(name = "parents_names")
val parentsNames: String,
val address: String,
@ColumnInfo(name = "registered_address")
val registeredAddress: String,
@ColumnInfo(name = "correspondence_address")
val correspondenceAddress: String,
@ColumnInfo(name = "phone_number")
val phoneNumber: String,
@ColumnInfo(name = "cell_phone_number")
val cellPhoneNumber: String,
val email: String,
@Embedded(prefix = "first_guardian_")
val firstGuardian: StudentGuardian?,
@Embedded(prefix = "second_guardian_")
val secondGuardian: StudentGuardian?
) : Serializable {
@PrimaryKey(autoGenerate = true)
var id: Long = 0
}
data class StudentGuardian(
@ColumnInfo(name = "full_name")
val fullName: String,
val kinship: String,
val address: String,
val phones: String,
val email: String
) : Serializable

View file

@ -0,0 +1,20 @@
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 StudentNickAndAvatar(
val nick: String,
@ColumnInfo(name = "avatar_color")
var avatarColor: Long
) : Serializable {
@PrimaryKey
var id: Long = 0
}

View file

@ -0,0 +1,30 @@
package io.github.wulkanowy.data.db.entities
import androidx.room.ColumnInfo
import androidx.room.Entity
import androidx.room.PrimaryKey
import java.io.Serializable
import java.time.LocalDate
import java.time.LocalDateTime
@Entity(tableName = "TimetableAdditional")
data class TimetableAdditional(
@ColumnInfo(name = "student_id")
val studentId: Int,
@ColumnInfo(name = "diary_id")
val diaryId: Int,
val start: LocalDateTime,
val end: LocalDateTime,
val date: LocalDate,
val subject: String,
) : Serializable {
@PrimaryKey(autoGenerate = true)
var id: Long = 0
}

View file

@ -0,0 +1,23 @@
package io.github.wulkanowy.data.db.migrations
import androidx.room.migration.Migration
import androidx.sqlite.db.SupportSQLiteDatabase
class Migration28 : Migration(27, 28) {
override fun migrate(database: SupportSQLiteDatabase) {
database.execSQL("""
CREATE TABLE IF NOT EXISTS Conferences (
id INTEGER PRIMARY KEY AUTOINCREMENT NOT NULL,
student_id INTEGER NOT NULL,
diary_id INTEGER NOT NULL,
title TEXT NOT NULL,
subject TEXT NOT NULL,
agenda TEXT NOT NULL,
present_on_conference TEXT NOT NULL,
conference_id INTEGER NOT NULL,
date INTEGER NOT NULL
)
""")
}
}

View file

@ -0,0 +1,33 @@
package io.github.wulkanowy.data.db.migrations
import androidx.room.migration.Migration
import androidx.sqlite.db.SupportSQLiteDatabase
class Migration29 : Migration(28, 29) {
override fun migrate(database: SupportSQLiteDatabase) {
database.execSQL("DROP TABLE IF EXISTS GradesStatistics")
database.execSQL("""
CREATE TABLE IF NOT EXISTS GradeSemesterStatistics (
id INTEGER PRIMARY KEY AUTOINCREMENT NOT NULL,
student_id INTEGER NOT NULL,
semester_id INTEGER NOT NULL,
subject TEXT NOT NULL,
amounts TEXT NOT NULL,
student_grade INTEGER NOT NULL
)
""")
database.execSQL("""
CREATE TABLE IF NOT EXISTS GradePartialStatistics (
id INTEGER PRIMARY KEY AUTOINCREMENT NOT NULL,
student_id INTEGER NOT NULL,
semester_id INTEGER NOT NULL,
subject TEXT NOT NULL,
class_average TEXT NOT NULL,
student_average TEXT NOT NULL,
class_amounts TEXT NOT NULL,
student_amounts TEXT NOT NULL
)
""")
}
}

View file

@ -0,0 +1,21 @@
package io.github.wulkanowy.data.db.migrations
import androidx.room.migration.Migration
import androidx.sqlite.db.SupportSQLiteDatabase
class Migration30 : Migration(29, 30) {
override fun migrate(database: SupportSQLiteDatabase) {
database.execSQL("""
CREATE TABLE TimetableAdditional (
id INTEGER PRIMARY KEY AUTOINCREMENT NOT NULL,
student_id INTEGER NOT NULL,
diary_id INTEGER NOT NULL,
start INTEGER NOT NULL,
`end` INTEGER NOT NULL,
date INTEGER NOT NULL,
subject TEXT NOT NULL
)
""")
}
}

View file

@ -0,0 +1,42 @@
package io.github.wulkanowy.data.db.migrations
import androidx.room.migration.Migration
import androidx.sqlite.db.SupportSQLiteDatabase
class Migration31 : Migration(30, 31) {
override fun migrate(database: SupportSQLiteDatabase) {
database.execSQL(
"""CREATE TABLE IF NOT EXISTS StudentInfo (
id INTEGER PRIMARY KEY AUTOINCREMENT NOT NULL,
student_id INTEGER NOT NULL,
full_name TEXT NOT NULL,
first_name TEXT NOT NULL,
second_name TEXT NOT NULL,
surname TEXT NOT NULL,
birth_date INTEGER NOT NULL,
birth_place TEXT NOT NULL,
gender TEXT NOT NULL,
has_polish_citizenship INTEGER NOT NULL,
family_name TEXT NOT NULL,
parents_names TEXT NOT NULL,
address TEXT NOT NULL,
registered_address TEXT NOT NULL,
correspondence_address TEXT NOT NULL,
phone_number TEXT NOT NULL,
cell_phone_number TEXT NOT NULL,
email TEXT NOT NULL,
first_guardian_full_name TEXT NOT NULL,
first_guardian_kinship TEXT NOT NULL,
first_guardian_address TEXT NOT NULL,
first_guardian_phones TEXT NOT NULL,
first_guardian_email TEXT NOT NULL,
second_guardian_full_name TEXT NOT NULL,
second_guardian_kinship TEXT NOT NULL,
second_guardian_address TEXT NOT NULL,
second_guardian_phones TEXT NOT NULL,
second_guardian_email 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 Migration32 : Migration(31, 32) {
override fun migrate(database: SupportSQLiteDatabase) {
database.execSQL("ALTER TABLE Students ADD COLUMN nick TEXT NOT NULL DEFAULT \"\"")
}
}

View file

@ -0,0 +1,45 @@
package io.github.wulkanowy.data.db.migrations
import androidx.room.migration.Migration
import androidx.sqlite.db.SupportSQLiteDatabase
class Migration33 : Migration(32, 33) {
override fun migrate(database: SupportSQLiteDatabase) {
database.execSQL("DROP TABLE IF EXISTS StudentInfo")
database.execSQL(
"""CREATE TABLE IF NOT EXISTS StudentInfo (
id INTEGER PRIMARY KEY AUTOINCREMENT NOT NULL,
student_id INTEGER NOT NULL,
full_name TEXT NOT NULL,
first_name TEXT NOT NULL,
second_name TEXT NOT NULL,
surname TEXT NOT NULL,
birth_date INTEGER NOT NULL,
birth_place TEXT NOT NULL,
gender TEXT NOT NULL,
has_polish_citizenship INTEGER NOT NULL,
family_name TEXT NOT NULL,
parents_names TEXT NOT NULL,
address TEXT NOT NULL,
registered_address TEXT NOT NULL,
correspondence_address TEXT NOT NULL,
phone_number TEXT NOT NULL,
cell_phone_number TEXT NOT NULL,
email TEXT NOT NULL,
first_guardian_full_name TEXT,
first_guardian_kinship TEXT,
first_guardian_address TEXT,
first_guardian_phones TEXT,
first_guardian_email TEXT,
second_guardian_full_name TEXT,
second_guardian_kinship TEXT,
second_guardian_address TEXT,
second_guardian_phones TEXT,
second_guardian_email TEXT)
"""
)
}
}

View file

@ -0,0 +1,13 @@
package io.github.wulkanowy.data.db.migrations
import androidx.room.migration.Migration
import androidx.sqlite.db.SupportSQLiteDatabase
class Migration34 : Migration(33, 34) {
override fun migrate(database: SupportSQLiteDatabase) {
database.execSQL("DELETE FROM ReportingUnits")
database.execSQL("DELETE FROM Recipients")
}
}

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,3 @@
package io.github.wulkanowy.data.enums
enum class Gender { MALE, FEMALE }

View file

@ -1,4 +1,4 @@
package io.github.wulkanowy.data.repositories.message
package io.github.wulkanowy.data.enums
enum class MessageFolder(val id: Int = 1) {
RECEIVED(1),

View file

@ -1,4 +1,4 @@
package io.github.wulkanowy.data.repositories.attendance
package io.github.wulkanowy.data.enums
enum class SentExcuseStatus(val id: Int = 0) {
WAITING,

View file

@ -0,0 +1,43 @@
package io.github.wulkanowy.data.mappers
import io.github.wulkanowy.data.db.entities.Attendance
import io.github.wulkanowy.data.db.entities.AttendanceSummary
import io.github.wulkanowy.data.db.entities.Semester
import io.github.wulkanowy.sdk.pojo.Attendance as SdkAttendance
import io.github.wulkanowy.sdk.pojo.AttendanceSummary as SdkAttendanceSummary
fun List<SdkAttendance>.mapToEntities(semester: Semester) = map {
Attendance(
studentId = semester.studentId,
diaryId = semester.diaryId,
date = it.date,
timeId = it.timeId,
number = it.number,
subject = it.subject,
name = it.name,
presence = it.presence,
absence = it.absence,
exemption = it.exemption,
lateness = it.lateness,
excused = it.excused,
deleted = it.deleted,
excusable = it.excusable,
excuseStatus = it.excuseStatus?.name
)
}
fun List<SdkAttendanceSummary>.mapToEntities(semester: Semester, subjectId: Int) = map {
AttendanceSummary(
studentId = semester.studentId,
diaryId = semester.diaryId,
subjectId = subjectId,
month = it.month,
presence = it.presence,
absence = it.absence,
absenceExcused = it.absenceExcused,
absenceForSchoolReasons = it.absenceForSchoolReasons,
lateness = it.lateness,
latenessExcused = it.latenessExcused,
exemption = it.exemption
)
}

View file

@ -0,0 +1,21 @@
package io.github.wulkanowy.data.mappers
import io.github.wulkanowy.data.db.entities.CompletedLesson
import io.github.wulkanowy.data.db.entities.Semester
import io.github.wulkanowy.sdk.pojo.CompletedLesson as SdkCompletedLesson
fun List<SdkCompletedLesson>.mapToEntities(semester: Semester) = map {
CompletedLesson(
studentId = semester.studentId,
diaryId = semester.diaryId,
date = it.date,
number = it.number,
subject = it.subject,
topic = it.topic,
teacher = it.teacher,
teacherSymbol = it.teacherSymbol,
substitution = it.substitution,
absence = it.absence,
resources = it.resources
)
}

View file

@ -0,0 +1,18 @@
package io.github.wulkanowy.data.mappers
import io.github.wulkanowy.data.db.entities.Conference
import io.github.wulkanowy.data.db.entities.Semester
import io.github.wulkanowy.sdk.pojo.Conference as SdkConference
fun List<SdkConference>.mapToEntities(semester: Semester) = map {
Conference(
studentId = semester.studentId,
diaryId = semester.diaryId,
agenda = it.agenda,
conferenceId = it.id,
date = it.date,
presentOnConference = it.presentOnConference,
subject = it.subject,
title = it.title
)
}

View file

@ -0,0 +1,20 @@
package io.github.wulkanowy.data.mappers
import io.github.wulkanowy.data.db.entities.Exam
import io.github.wulkanowy.data.db.entities.Semester
import io.github.wulkanowy.sdk.pojo.Exam as SdkExam
fun List<SdkExam>.mapToEntities(semester: Semester) = map {
Exam(
studentId = semester.studentId,
diaryId = semester.diaryId,
date = it.date,
entryDate = it.entryDate,
subject = it.subject,
group = it.group,
type = it.type,
description = it.description,
teacher = it.teacher,
teacherSymbol = it.teacherSymbol
)
}

View file

@ -0,0 +1,42 @@
package io.github.wulkanowy.data.mappers
import io.github.wulkanowy.data.db.entities.Grade
import io.github.wulkanowy.data.db.entities.GradeSummary
import io.github.wulkanowy.data.db.entities.Semester
import io.github.wulkanowy.sdk.pojo.GradeSummary as SdkGradeSummary
import io.github.wulkanowy.sdk.pojo.Grade as SdkGrade
fun List<SdkGrade>.mapToEntities(semester: Semester) = map {
Grade(
studentId = semester.studentId,
semesterId = semester.semesterId,
subject = it.subject,
entry = it.entry,
value = it.value,
modifier = it.modifier,
comment = it.comment,
color = it.color,
gradeSymbol = it.symbol,
description = it.description,
weight = it.weight,
weightValue = it.weightValue,
date = it.date,
teacher = it.teacher
)
}
@JvmName("mapGradeSummaryToEntities")
fun List<SdkGradeSummary>.mapToEntities(semester: Semester) = map {
GradeSummary(
semesterId = semester.semesterId,
studentId = semester.studentId,
position = 0,
subject = it.name,
predictedGrade = it.predicted,
finalGrade = it.final,
pointsSum = it.pointsSum,
proposedPoints = it.proposedPoints,
finalPoints = it.finalPoints,
average = it.average
)
}

View file

@ -0,0 +1,79 @@
package io.github.wulkanowy.data.mappers
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.data.db.entities.Semester
import io.github.wulkanowy.data.pojos.GradeStatisticsItem
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 {
GradePartialStatistics(
semesterId = semester.semesterId,
studentId = semester.studentId,
subject = it.subject,
classAverage = it.classAverage,
studentAverage = it.studentAverage,
classAmounts = it.classItems
.sortedBy { item -> item.grade }
.map { item -> item.amount },
studentAmounts = it.studentItems.map { item -> item.amount }
)
}
@JvmName("mapToEntitiesSemester")
fun List<SdkGradeStatisticsSemester>.mapToEntities(semester: Semester) = map {
GradeSemesterStatistics(
semesterId = semester.semesterId,
studentId = semester.studentId,
subject = it.subject,
amounts = it.items
.sortedBy { item -> item.grade }
.map { item -> item.amount },
studentGrade = it.items.singleOrNull { item -> item.isStudentHere }?.grade ?: 0
)
}
@JvmName("mapToEntitiesPoints")
fun List<SdkGradePointsStatistics>.mapToEntities(semester: Semester) = map {
GradePointsStatistics(
semesterId = semester.semesterId,
studentId = semester.studentId,
subject = it.subject,
others = it.others,
student = it.student
)
}
fun List<GradePartialStatistics>.mapPartialToStatisticItems() = filterNot { it.classAmounts.isEmpty() }.map {
GradeStatisticsItem(
type = GradeStatisticsItem.DataType.PARTIAL,
average = it.classAverage,
partial = it,
points = null,
semester = null
)
}
fun List<GradeSemesterStatistics>.mapSemesterToStatisticItems() = filterNot { it.amounts.isEmpty() }.map {
GradeStatisticsItem(
type = GradeStatisticsItem.DataType.SEMESTER,
partial = null,
points = null,
average = "",
semester = it
)
}
fun List<GradePointsStatistics>.mapPointsToStatisticsItems() = map {
GradeStatisticsItem(
type = GradeStatisticsItem.DataType.POINTS,
partial = null,
semester = null,
average = "",
points = it
)
}

View file

@ -0,0 +1,21 @@
package io.github.wulkanowy.data.mappers
import io.github.wulkanowy.sdk.pojo.Homework as SdkHomework
import io.github.wulkanowy.data.db.entities.Homework
import io.github.wulkanowy.data.db.entities.Semester
fun List<SdkHomework>.mapToEntities(semester: Semester) = map {
Homework(
semesterId = semester.semesterId,
studentId = semester.studentId,
date = it.date,
entryDate = it.entryDate,
subject = it.subject,
content = it.content,
teacher = it.teacher,
teacherSymbol = it.teacherSymbol,
attachments = it.attachments.map { attachment ->
attachment.url to attachment.name
}
)
}

View file

@ -0,0 +1,12 @@
package io.github.wulkanowy.data.mappers
import io.github.wulkanowy.data.db.entities.LuckyNumber
import io.github.wulkanowy.data.db.entities.Student
import java.time.LocalDate
import io.github.wulkanowy.sdk.pojo.LuckyNumber as SdkLuckyNumber
fun SdkLuckyNumber.mapToEntity(student: Student) = LuckyNumber(
studentId = student.studentId,
date = LocalDate.now(),
luckyNumber = number
)

View file

@ -0,0 +1,53 @@
package io.github.wulkanowy.data.mappers
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 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,
realId = it.id ?: 0,
messageId = it.messageId ?: 0,
sender = it.sender?.name.orEmpty(),
senderId = it.sender?.loginId ?: 0,
recipient = it.recipients.singleOrNull()?.name ?: "Wielu adresatów",
subject = it.subject.trim(),
date = it.date ?: LocalDateTime.now(),
folderId = it.folderId,
unread = it.unread ?: false,
removed = it.removed,
hasAttachments = it.hasAttachments
).apply {
content = it.content.orEmpty()
unreadBy = it.unreadBy ?: 0
readBy = it.readBy ?: 0
}
}
fun List<SdkMessageAttachment>.mapToEntities() = map {
MessageAttachment(
realId = it.id,
messageId = it.messageId,
oneDriveId = it.oneDriveId,
url = it.url,
filename = it.filename
)
}
fun List<Recipient>.mapFromEntities() = map {
SdkRecipient(
id = it.realId,
name = it.realName,
loginId = it.loginId,
reportingUnitId = it.unitId,
role = it.role,
hash = it.hash,
shortName = it.name
)
}

View file

@ -0,0 +1,23 @@
package io.github.wulkanowy.data.mappers
import io.github.wulkanowy.data.db.entities.MobileDevice
import io.github.wulkanowy.data.db.entities.Semester
import io.github.wulkanowy.data.pojos.MobileDeviceToken
import io.github.wulkanowy.sdk.pojo.Token as SdkToken
import io.github.wulkanowy.sdk.pojo.Device as SdkDevice
fun List<SdkDevice>.mapToEntities(semester: Semester) = map {
MobileDevice(
userLoginId = semester.studentId,
date = it.createDate,
deviceId = it.id,
name = it.name
)
}
fun SdkToken.mapToMobileDeviceToken() = MobileDeviceToken(
token = token,
symbol = symbol,
pin = pin,
qr = qrCodeImage
)

View file

@ -0,0 +1,19 @@
package io.github.wulkanowy.data.mappers
import io.github.wulkanowy.data.db.entities.Note
import io.github.wulkanowy.data.db.entities.Semester
import io.github.wulkanowy.sdk.pojo.Note as SdkNote
fun List<SdkNote>.mapToEntities(semester: Semester) = map {
Note(
studentId = semester.studentId,
date = it.date,
teacher = it.teacher,
teacherSymbol = it.teacherSymbol,
category = it.category,
categoryType = it.categoryType.id,
isPointsShow = it.showPoints,
points = it.points,
content = it.content
)
}

View file

@ -0,0 +1,17 @@
package io.github.wulkanowy.data.mappers
import io.github.wulkanowy.data.db.entities.Recipient
import io.github.wulkanowy.sdk.pojo.Recipient as SdkRecipient
fun List<SdkRecipient>.mapToEntities(userLoginId: Int) = map {
Recipient(
studentId = userLoginId,
realId = it.id,
realName = it.name,
name = it.shortName,
hash = it.hash,
loginId = it.loginId,
role = it.role,
unitId = it.reportingUnitId ?: 0
)
}

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