Compare commits

..

462 commits
1.2.2 ... 1.8.0

Author SHA1 Message Date
Mikołaj Pich
4bce35f810 Merge branch 'release/1.8.0' 2022-11-16 20:31:09 +01:00
Mikołaj Pich
2d83218f61 Version 1.8.0 2022-11-16 20:31:02 +01:00
Rafał Borcz
d3e276d6fc
New Crowdin updates (#2049)
Co-authored-by: Mikołaj Pich <m.pich@outlook.com>
2022-11-16 20:13:48 +01:00
Mikołaj Pich
51a1097bb4
Add mailbox chooser to messages (#2002) 2022-11-16 13:46:47 +01:00
Mikołaj Pich
db4f172fb8
Fix unread status in sent messages (#2048) 2022-11-16 12:54:55 +01:00
dependabot[bot]
4d49e956b8
Bump junit from 1.1.3 to 1.1.4 (#2043) 2022-11-14 20:48:12 +00:00
dependabot[bot]
b8296ac02f
Bump kotlin_version from 1.7.20 to 1.7.21 (#2042) 2022-11-14 20:31:26 +00:00
dependabot[bot]
d6385e8cdd
Bump core from 1.4.0 to 1.5.0 (#2045) 2022-11-14 20:31:02 +00:00
dependabot[bot]
885319a885
Bump hilt_version from 2.44 to 2.44.1 (#2044) 2022-11-14 18:36:20 +00:00
dependabot[bot]
fded5007c1
Bump firebase-bom from 31.0.2 to 31.0.3 (#2041) 2022-11-14 18:22:25 +00:00
dependabot[bot]
66ff14f719
Bump agcp from 1.7.3.300 to 1.7.3.301 (#2046) 2022-11-14 18:21:35 +00:00
dependabot[bot]
1257dc63d3
Bump runner from 1.4.0 to 1.5.1 (#2047) 2022-11-14 18:21:17 +00:00
Rafał Borcz
50b6d380b6
Fix unexpected error in support ad when no internet (#2030) 2022-11-02 16:44:05 +01:00
Rafał Borcz
62b7d42a73
New Crowdin updates (#1966) 2022-11-01 20:57:05 +01:00
dependabot[bot]
21fe209246
Bump firebase-bom from 31.0.1 to 31.0.2 (#2032) 2022-11-01 19:51:28 +00:00
dependabot[bot]
02cd4e4e06
Bump sonarqube-gradle-plugin from 3.4.0.2513 to 3.5.0.2730 (#2033) 2022-11-01 19:50:59 +00:00
dependabot[bot]
86fe2b61cb
Bump agcp from 1.7.2.300 to 1.7.3.300 (#2034) 2022-11-01 19:50:37 +00:00
dependabot[bot]
4113bd9b53
Bump agconnect-crash from 1.7.2.300 to 1.7.3.300 (#2035) 2022-11-01 19:50:17 +00:00
dependabot[bot]
d924902dac
Bump CircularImageView from 4.2.0 to 4.3.0 (#2036) 2022-11-01 19:49:56 +00:00
Damian Czupryn
b269360ecb
Langs placement in README adjustments (#2029) 2022-10-30 03:00:39 +01:00
Damian Czupryn
ffd5addadb
Add Crowdin badges to README (#2025) 2022-10-28 11:10:35 +02:00
Mikołaj Pich
c5e2b18695
Fix SSL certificate out-of-date detection (#2028) 2022-10-28 11:10:05 +02:00
Mikołaj Pich
515a3973b7
Use text color, font face and red dot to differentiate unread messages (#2027) 2022-10-28 11:09:38 +02:00
Mikołaj Pich
7bee10d5ce
Hide room view in timetable item if there is no room in API (#2026) 2022-10-28 11:08:40 +02:00
Mikołaj Pich
22a4f509dc
Add installation id to crashlytics and bug report emails (#2024) 2022-10-27 12:41:33 +02:00
Damian Czupryn
3925a6261b
Add missing CS and SK links in German README (#2018) 2022-10-26 22:27:37 +02:00
dependabot[bot]
49b383fbe5
Bump firebase-bom from 31.0.0 to 31.0.1 (#2019) 2022-10-26 18:22:53 +00:00
dependabot[bot]
4a484dc2ce
Bump fragment-ktx from 1.5.3 to 1.5.4 (#2020) 2022-10-26 18:22:34 +00:00
dependabot[bot]
a14c4b489b
Bump material from 1.6.1 to 1.7.0 (#2022) 2022-10-26 18:22:16 +00:00
dependabot[bot]
e91cd18804
Bump firebase-bom from 30.5.0 to 31.0.0 (#2013) 2022-10-18 19:41:15 +00:00
dependabot[bot]
4c24363599
Bump about_libraries from 10.5.0 to 10.5.1 (#2012) 2022-10-18 19:40:28 +00:00
dependabot[bot]
e20c232f8f
Bump kotlinx-serialization-json from 1.4.0 to 1.4.1 (#2014) 2022-10-18 19:39:54 +00:00
dependabot[bot]
1f11eea9b5
Bump gradle from 7.3.0 to 7.3.1 (#2015) 2022-10-18 19:39:36 +00:00
dependabot[bot]
42f9a00e8c
Bump play-services-ads from 21.2.0 to 21.3.0 (#2016) 2022-10-18 19:39:16 +00:00
Daniel Olczyk
ad487e680c
Fix grade weight text truncation in grade dialog with large font set (#2009) 2022-10-05 22:25:09 +02:00
dependabot[bot]
3f431022a5
Bump about_libraries from 10.4.0 to 10.5.0 (#2005) 2022-10-04 08:08:21 +00:00
dependabot[bot]
cd037f0ce0
Bump kotlin_version from 1.7.10 to 1.7.20 (#2003) 2022-10-04 07:58:58 +00:00
Mikołaj Pich
37f7f21a03
Reorder action buttons on the message preview screen to hide the forward button in overflow menu (#2000) 2022-10-04 09:51:30 +02:00
dependabot[bot]
c653039590
Bump coil from 2.2.1 to 2.2.2 (#2004) 2022-10-04 07:50:05 +00:00
dependabot[bot]
95a90a7a79
Bump mockk from 1.13.1 to 1.13.2 (#2006) 2022-10-04 07:49:41 +00:00
dependabot[bot]
4dc80595ac
Bump robolectric from 4.8.2 to 4.9 (#2007) 2022-10-04 07:49:22 +00:00
dependabot[bot]
8114a2376e
Bump gradle from 7.2.2 to 7.3.0 (#1985) 2022-09-28 21:43:45 +00:00
dependabot[bot]
a523850216
Bump annotation from 1.4.0 to 1.5.0 (#1998) 2022-09-28 23:34:06 +02:00
Michael
354f51dd70
Fix student average calculation error in grade statistics (#1981)
Co-authored-by: Mikołaj Pich <m.pich@outlook.com>
2022-09-28 23:33:05 +02:00
dependabot[bot]
b271c12ebc
Bump hilt_version from 2.43.2 to 2.44 (#1994) 2022-09-28 20:28:31 +00:00
dependabot[bot]
8ca41b5ba3
Bump hianalytics from 6.7.0.300 to 6.8.0.300 (#1995) 2022-09-28 20:28:01 +00:00
dependabot[bot]
edbe45332a
Bump mockk from 1.12.8 to 1.13.1 (#1996) 2022-09-28 20:27:43 +00:00
dependabot[bot]
1bbd249275
Bump fragment-ktx from 1.5.2 to 1.5.3 (#1997) 2022-09-28 20:25:58 +00:00
dependabot[bot]
5148ff291b
Bump google-services from 4.3.13 to 4.3.14 (#1992) 2022-09-21 20:59:41 +00:00
dependabot[bot]
a1dc00af42
Bump agcp from 1.7.1.300 to 1.7.2.300 (#1989) 2022-09-21 20:49:36 +00:00
dependabot[bot]
f1db993fee
Bump agconnect-crash from 1.7.1.300 to 1.7.2.300 (#1990) 2022-09-21 20:40:36 +00:00
dependabot[bot]
4f0519552e
Bump firebase-crashlytics-gradle from 2.9.1 to 2.9.2 (#1988) 2022-09-21 20:39:29 +00:00
dependabot[bot]
3625c5c518
Bump firebase-bom from 30.4.1 to 30.5.0 (#1991) 2022-09-21 20:39:08 +00:00
dependabot[bot]
afbfb9761f
Bump mockk from 1.12.7 to 1.12.8 (#1986) 2022-09-21 20:38:55 +00:00
dependabot[bot]
a5c636853a
Bump coil from 2.2.0 to 2.2.1 (#1973) 2022-09-14 11:19:05 +00:00
dependabot[bot]
d5d45ed1ba
Bump play-services-ads from 21.1.0 to 21.2.0 (#1972) 2022-09-14 11:18:29 +00:00
dependabot[bot]
d3f869c6c2
Bump firebase-bom from 30.4.0 to 30.4.1 (#1971) 2022-09-14 11:18:09 +00:00
dependabot[bot]
46c29c438e
Bump appcompat from 1.5.0 to 1.5.1 (#1975) 2022-09-14 11:17:19 +00:00
dependabot[bot]
73a7255d3a
Bump firebase-bom from 30.3.2 to 30.4.0 (#1968) 2022-09-05 19:49:30 +00:00
Mikołaj Pich
c7af85e0e1 Merge branch 'release/1.7.5' into develop 2022-09-02 21:31:39 +02:00
Mikołaj Pich
afc16e3d17 Merge branch 'release/1.7.5' 2022-09-02 21:31:31 +02:00
Mikołaj Pich
59f6f5c212 Version 1.7.5 2022-09-02 21:31:27 +02:00
Mikołaj Pich
86f8763e69
Display lesson number in attendance notification if subject is blank (#1965) 2022-09-02 21:30:30 +02:00
Mikołaj Pich
157becb017
Fix matching mailboxes when there is more than one space between words (#1964) 2022-09-02 20:19:19 +02:00
Mikołaj Pich
83ca9a7060 Merge branch 'release/1.7.4' into develop 2022-09-01 17:57:30 +02:00
Mikołaj Pich
1033be4503 Merge branch 'release/1.7.4' 2022-09-01 17:57:24 +02:00
Mikołaj Pich
e67066f3ae Version 1.7.4 2022-09-01 17:57:20 +02:00
Mikołaj Pich
bc22808b0e
Add support for matching last kingergarten semester if there is no any current (#1962) 2022-09-01 17:48:46 +02:00
Mikołaj Pich
e05abb3539
Fix showing empty view in grade details when there is no grades (#1963) 2022-09-01 17:48:03 +02:00
Mikołaj Pich
6153c7b97d
Add support for match mailboxes with more different names (#1961) 2022-09-01 14:55:00 +02:00
Mikołaj Pich
e574e5e2ec Merge branch 'release/1.7.3' into develop 2022-08-31 19:31:39 +02:00
Mikołaj Pich
e6571a1dfc Merge branch 'release/1.7.3' 2022-08-31 19:31:33 +02:00
Mikołaj Pich
d566de0282 Version 1.7.3 2022-08-31 19:31:28 +02:00
Mikołaj Pich
558db061f5
Fix marking message as read (#1960)
* Fix marking message as read

* Update sdk

* Update sdk

* Fix tests

* Use many recipients strings instead of first recipient
2022-08-31 18:31:12 +02:00
Mikołaj Pich
190f40ede8 Merge branch 'release/1.7.2' into develop 2022-08-30 13:34:28 +02:00
Mikołaj Pich
4b795d6ef5 Merge branch 'release/1.7.2' 2022-08-30 13:34:20 +02:00
Mikołaj Pich
d139bd5b14 Version 1.7.2 2022-08-30 13:34:10 +02:00
Rafał Borcz
bf34cb0c1e
New Crowdin updates (#1953)
Co-authored-by: Mikołaj Pich <m.pich@outlook.com>
2022-08-30 12:11:32 +02:00
Mikołaj Pich
eed091aad2
Update row in mailboxes table on primary key conflict (#1954) 2022-08-30 09:07:24 +02:00
Mikołaj Pich
535206056d
Fix selecting student mailbox based on studentName field (#1958) 2022-08-30 09:07:07 +02:00
Mikołaj Pich
f2cb3b4f9e
Change message draft key in shared preferences (#1959) 2022-08-30 09:06:29 +02:00
dependabot[bot]
54372e0a55
Bump kotlinx-serialization-json from 1.3.3 to 1.4.0 (#1950) 2022-08-29 13:40:14 +00:00
dependabot[bot]
5c17c38d1d
Bump mockk from 1.12.5 to 1.12.7 (#1955) 2022-08-29 13:30:56 +00:00
dependabot[bot]
f68a8e4215
Bump robolectric from 4.8.1 to 4.8.2 (#1956) 2022-08-29 13:30:28 +00:00
dependabot[bot]
70c2cb7dbf
Bump desugar_jdk_libs from 1.1.6 to 1.1.8 (#1957) 2022-08-29 13:30:00 +00:00
Mikołaj Pich
7f6fd60821 Merge branch 'release/1.7.1' into develop 2022-08-23 00:56:29 +02:00
Mikołaj Pich
62c04fb205 Merge branch 'release/1.7.1' 2022-08-23 00:56:20 +02:00
Mikołaj Pich
10c36f19bf Version 1.7.1 2022-08-23 00:56:12 +02:00
Rafał Borcz
37d756b8fe
New Crowdin updates (#1952) 2022-08-23 00:54:19 +02:00
Mikołaj Pich
de1bc4809f
Fix ads translations (#1951) 2022-08-23 00:08:39 +02:00
Mikołaj Pich
3d6ec93cde Merge branch 'release/1.7.0' into develop 2022-08-22 17:58:51 +02:00
Mikołaj Pich
c293c76398 Merge branch 'release/1.7.0' 2022-08-22 17:58:41 +02:00
Mikołaj Pich
09e07a1713 Version 1.7.0 2022-08-22 17:58:35 +02:00
Rafał Borcz
71f1a55437
New Crowdin updates (#1895) 2022-08-22 16:45:59 +02:00
dependabot[bot]
d9e22af5ef
Bump desugar_jdk_libs from 1.1.5 to 1.1.6 (#1948) 2022-08-22 13:28:58 +00:00
dependabot[bot]
bc0689a30d
Bump coil from 2.1.0 to 2.2.0 (#1949) 2022-08-22 13:28:27 +00:00
Mikołaj Pich
9d47127921
Add support for messages plus API (#1945) 2022-08-22 14:30:50 +02:00
dependabot[bot]
08a3bd77bd
Bump appcompat from 1.4.2 to 1.5.0 (#1946) 2022-08-22 07:00:10 +00:00
dependabot[bot]
9fe1151a04
Bump fragment-ktx from 1.5.1 to 1.5.2 (#1947) 2022-08-19 22:22:47 +00:00
Patryk
793952cb44
Fix typo in README DE.md (#1936)
* Update README.de.md

* Change in README-DE.md file
2022-08-14 22:16:47 +02:00
dependabot[bot]
d64a21b50c
Bump hianalytics from 6.6.0.300 to 6.7.0.300 (#1944) 2022-08-10 09:56:20 +00:00
dependabot[bot]
274f9dde07
Bump agconnect-crash from 1.7.0.300 to 1.7.1.300 (#1943) 2022-08-10 09:48:02 +00:00
dependabot[bot]
5a884a4c56
Bump agcp from 1.7.0.300 to 1.7.1.300 (#1938) 2022-08-10 09:38:15 +00:00
dependabot[bot]
c55fd98179
Bump about_libraries from 10.3.1 to 10.4.0 (#1941) 2022-08-10 09:37:53 +00:00
Patryk
ffc0cd840b
Update workflow dependency (#1937)
Co-authored-by: Mikołaj Pich <m.pich@outlook.com>
2022-08-10 11:28:22 +02:00
dependabot[bot]
96067946d0
Bump firebase-bom from 30.3.1 to 30.3.2 (#1940) 2022-08-10 09:27:46 +00:00
dependabot[bot]
9339e7d916
Bump gradle from 7.2.1 to 7.2.2 (#1942) 2022-08-10 09:27:24 +00:00
dependabot[bot]
b4117aa62e
Bump flow-preferences from 1.7.0 to 1.8.0 (#1925) 2022-08-03 10:56:41 +00:00
dependabot[bot]
dc3a941e24
Bump core-splashscreen from 1.0.0-rc01 to 1.0.0 (#1929) 2022-08-01 21:36:28 +00:00
dependabot[bot]
b67ecbba4b
Bump room from 2.4.2 to 2.4.3 (#1928) 2022-08-01 21:26:37 +00:00
dependabot[bot]
1175740ba2
Bump activity-ktx from 1.5.0 to 1.5.1 (#1926) 2022-08-01 21:26:34 +00:00
dependabot[bot]
378ed0100f
Bump huawei-publish-gradle-plugin from 1.3.3 to 1.3.4 (#1934) 2022-08-01 21:26:15 +00:00
dependabot[bot]
cf87339ac4
Bump hilt_version from 2.43 to 2.43.1 (#1927) 2022-08-01 21:18:52 +00:00
dependabot[bot]
c23a90f104
Bump fragment-ktx from 1.5.0 to 1.5.1 (#1930) 2022-08-01 21:17:35 +00:00
dependabot[bot]
d337be0f40
Bump firebase-bom from 30.3.0 to 30.3.1 (#1931) 2022-08-01 21:17:20 +00:00
dependabot[bot]
cf7c6f78ea
Bump lifecycle-livedata-ktx from 2.5.0 to 2.5.1 (#1932) 2022-08-01 21:17:00 +00:00
dependabot[bot]
efa68f5044
Bump mockk from 1.12.4 to 1.12.5 (#1933) 2022-08-01 21:16:46 +00:00
dependabot[bot]
b9be85d99c
Bump hilt_version from 2.42 to 2.43 (#1923) 2022-07-27 10:09:28 +00:00
dependabot[bot]
dfc4553fc6
Bump firebase-bom from 30.2.0 to 30.3.0 (#1920) 2022-07-21 21:28:53 +00:00
dependabot[bot]
08c9539abe
Bump coroutines from 1.6.3 to 1.6.4 (#1921) 2022-07-21 21:28:37 +00:00
dependabot[bot]
fd18583df2
Bump play-services-ads from 21.0.0 to 21.1.0 (#1922) 2022-07-21 21:28:20 +00:00
Mikołaj Pich
7c4f1c7b22
Add auto refresh to reporting units (#1916) 2022-07-12 12:23:55 +02:00
dependabot[bot]
bdb6c962ea
Bump hianalytics from 6.5.0.300 to 6.6.0.300 (#1919) 2022-07-12 10:20:42 +00:00
dependabot[bot]
f1c217b087
Bump kotlin_version from 1.7.0 to 1.7.10 (#1918) 2022-07-12 10:20:28 +00:00
dependabot[bot]
4b6277abf5
Bump activity-ktx from 1.4.0 to 1.5.0 (#1912) 2022-07-09 07:34:24 +00:00
dependabot[bot]
344e0d55ff
Bump lifecycle-livedata-ktx from 2.4.1 to 2.5.0 (#1911) 2022-07-09 07:34:03 +00:00
dependabot[bot]
89a6a98bbf
Bump google-services from 4.3.10 to 4.3.13 (#1913) 2022-07-09 07:33:46 +00:00
dependabot[bot]
fcc7dc0913
Bump fragment-ktx from 1.4.1 to 1.5.0 (#1915) 2022-07-09 07:33:27 +00:00
Rafał Borcz
1b74bffc06
Fix no mobile devices on parent account (#1896) 2022-07-02 19:10:57 +02:00
dependabot[bot]
0f11f14c3e
Bump firebase-bom from 30.1.0 to 30.2.0 (#1909) 2022-06-28 15:07:33 +00:00
dependabot[bot]
e70fe6f097
Bump firebase-crashlytics-gradle from 2.9.0 to 2.9.1 (#1910) 2022-06-28 15:06:20 +00:00
dependabot[bot]
b70649f136
Bump about_libraries from 10.3.0 to 10.3.1 (#1907) 2022-06-28 15:05:51 +00:00
Rafał Borcz
7b13684137
Fix ads tile (#1905) 2022-06-26 15:50:35 +02:00
dependabot[bot]
c4689fcbb3
Bump agconnect-crash from 1.6.6.200 to 1.7.0.300 (#1899) 2022-06-26 12:44:06 +00:00
Rafał Borcz
d8f644c5b4
Add ads to dashboard (#1815) 2022-06-26 13:28:35 +02:00
Michael
c808bf2e61
Fix timetable widget day reset (#1862)
Co-authored-by: Rafał Borcz <RafalBO99@outlook.com>
2022-06-26 13:06:43 +02:00
Rafał Borcz
0fb55bd6c6
Fix doubled announcements (#1897) 2022-06-26 12:12:11 +02:00
dependabot[bot]
c5dfea788c
Bump annotation from 1.3.0 to 1.4.0 (#1900) 2022-06-23 12:09:50 +00:00
dependabot[bot]
120e5c9171
Bump coroutines from 1.6.2 to 1.6.3 (#1902) 2022-06-23 12:09:25 +00:00
Rafał Borcz
a97039a727
Fix jumping point in notes on refresh (#1898) 2022-06-19 21:04:05 +02:00
Rafał Borcz
e9ba65f8f6
Fix multiline address in student info (#1891) 2022-06-18 12:12:21 +02:00
Rafał Borcz
a264abf814
Fix typo in average description (#1892) 2022-06-18 12:12:04 +02:00
Rafał Borcz
0a2eb07844
Fix date in attendance and timetable when day is changing (#1893) 2022-06-18 12:11:46 +02:00
Rafał Borcz
bfab265ccf
Fix case sensitive domain checker (#1894) 2022-06-18 11:54:08 +02:00
dependabot[bot]
cd59166efb
Bump sonarqube-gradle-plugin from 3.3 to 3.4.0.2513 (#1888) 2022-06-16 22:15:18 +00:00
dependabot[bot]
06ed5f6079
Bump logging-interceptor from 4.9.3 to 4.10.0 (#1889) 2022-06-16 21:53:21 +00:00
Rafał Borcz
6b70583573
New Crowdin updates (#1873) 2022-06-13 07:43:40 +02:00
Rafał Borcz
c3cbaa6ac2
Update dependencies (#1887) 2022-06-13 07:43:12 +02:00
dependabot[bot]
f61d820d6f
Bump core-ktx from 1.7.0 to 1.8.0 (#1882) 2022-06-13 05:07:54 +00:00
dependabot[bot]
03ad5527f8
Bump appcompat from 1.4.1 to 1.4.2 (#1883) 2022-06-13 04:59:50 +00:00
dependabot[bot]
cce736410b
Bump material from 1.6.0 to 1.6.1 (#1884) 2022-06-13 04:59:31 +00:00
dependabot[bot]
8c515bd03f
Bump coroutines from 1.6.1 to 1.6.2 (#1875) 2022-05-31 13:52:09 +00:00
dependabot[bot]
8dcb3ed45d
Bump firebase-crashlytics-gradle from 2.8.1 to 2.9.0 (#1874) 2022-05-31 13:51:12 +00:00
dependabot[bot]
4f3f24ac10
Bump about_libraries from 10.2.0 to 10.3.0 (#1876) 2022-05-31 13:50:52 +00:00
dependabot[bot]
d074e5c9b3
Bump play-services-ads from 20.6.0 to 21.0.0 (#1877) 2022-05-31 13:50:22 +00:00
dependabot[bot]
d2d1d1dba7
Bump firebase-bom from 30.0.2 to 30.1.0 (#1878) 2022-05-31 13:50:03 +00:00
Michael
891e241d1a
Hide account selector in MessagePreviewView and SendMessageView (#1866)
Co-authored-by: Rafał Borcz <RafalBO99@outlook.com>
2022-05-28 02:03:42 +02:00
Michael
5c4a3d578b
Add grade sorting by average (#1863) 2022-05-27 22:19:22 +02:00
dependabot[bot]
fcf0adfd80
Bump gradle from 7.1.3 to 7.2.0 (#1857) 2022-05-26 05:26:52 +00:00
dependabot[bot]
c42a47ac48
Bump material from 1.5.0 to 1.6.0 (#1846) 2022-05-26 04:18:37 +00:00
dependabot[bot]
fa48b033af
Bump constraintlayout from 2.1.3 to 2.1.4 (#1869) 2022-05-24 08:44:17 +00:00
dependabot[bot]
808927a58a
Bump coil from 2.0.0 to 2.1.0 (#1870) 2022-05-24 08:43:52 +00:00
dependabot[bot]
dc717c9fb5
Bump core-splashscreen from 1.0.0-beta02 to 1.0.0-rc01 (#1871) 2022-05-24 08:43:32 +00:00
dependabot[bot]
a2804d813a
Bump firebase-bom from 30.0.1 to 30.0.2 (#1872) 2022-05-24 08:41:23 +00:00
Mikołaj Pich
847ab6149a Merge branch 'release/1.6.4' into develop 2022-05-16 23:42:51 +02:00
Mikołaj Pich
dc74d2877b Merge branch 'release/1.6.4' 2022-05-16 23:42:46 +02:00
Mikołaj Pich
6534176685 Version 1.6.4 2022-05-16 23:42:40 +02:00
Mikołaj Pich
9542b9f231
Set "no data" string if attendance subject is blank (#1864) 2022-05-16 23:23:49 +02:00
dependabot[bot]
dbba61a99f
Bump coil from 1.4.0 to 2.0.0 (#1855) 2022-05-14 14:48:58 +00:00
dependabot[bot]
c2496a15b8
Bump flow-preferences from 1.6.0 to 1.7.0 (#1859) 2022-05-14 14:36:09 +00:00
dependabot[bot]
facf84d9a8
Bump about_libraries from 8.9.4 to 10.2.0 (#1858) 2022-05-14 14:35:58 +00:00
dependabot[bot]
459c8330f9
Bump hianalytics from 6.4.1.302 to 6.5.0.300 (#1852) 2022-05-14 13:53:13 +00:00
dependabot[bot]
0c8e2632a2
Bump firebase-bom from 30.0.0 to 30.0.1 (#1851) 2022-05-14 13:52:58 +00:00
dependabot[bot]
b17e9deca0
Bump kotlinx-serialization-json from 1.3.2 to 1.3.3 (#1853) 2022-05-14 13:52:41 +00:00
dependabot[bot]
c296e72c30
Bump mockk from 1.12.2 to 1.12.4 (#1854) 2022-05-14 13:52:16 +00:00
dependabot[bot]
637125e1fc
Bump hilt_version from 2.41 to 2.42 (#1856) 2022-05-14 13:51:39 +00:00
Rafał Borcz
445bfda801
New Crowdin updates (#1840) 2022-05-12 21:07:14 +02:00
dependabot[bot]
ebde42328a
Bump agcp from 1.6.5.300 to 1.6.6.200 (#1845) 2022-05-12 19:06:15 +00:00
dependabot[bot]
a0bf14b576
Bump agconnect-crash from 1.6.5.300 to 1.6.6.200 (#1843) 2022-05-12 19:05:59 +00:00
dependabot[bot]
2e7caabde3
Bump firebase-bom from 29.3.1 to 30.0.0 (#1844) 2022-05-12 19:05:40 +00:00
dependabot[bot]
bb052fd4c9
Bump robolectric from 4.8 to 4.8.1 (#1842) 2022-05-12 19:05:20 +00:00
dependabot[bot]
28ef8c6761
Bump kotlin_version from 1.6.20 to 1.6.21 (#1837) 2022-05-03 11:46:03 +00:00
dependabot[bot]
15e8e096ed
Bump robolectric from 4.7.3 to 4.8 (#1839) 2022-05-03 11:38:18 +00:00
Mikołaj Pich
6007de017f Merge branch 'release/1.6.3' into develop 2022-04-19 09:56:12 +02:00
Mikołaj Pich
775b5122ef Merge branch 'release/1.6.3' 2022-04-19 09:56:06 +02:00
Mikołaj Pich
fed00122d7 Version 1.6.3 2022-04-19 09:56:01 +02:00
Mikołaj Pich
426bee882c
Display timetable header as HTML on dashboard tile (#1835) 2022-04-18 16:52:28 +02:00
dependabot[bot]
d37de197fc
Bump firebase-bom from 29.3.0 to 29.3.1 (#1836) 2022-04-18 14:52:06 +00:00
Rafał Borcz
447ece3696
Replace destination parcelable with destination json string (#1833) 2022-04-16 12:17:22 +02:00
dependabot[bot]
a73f39e59c
Bump agconnect-crash from 1.6.5.200 to 1.6.5.300 (#1830) 2022-04-14 02:13:09 +00:00
dependabot[bot]
f912aac140
Bump gradle from 7.1.2 to 7.1.3 (#1829) 2022-04-14 02:12:20 +00:00
dependabot[bot]
3caabd3e0e
Bump coroutines from 1.6.0 to 1.6.1 (#1828) 2022-04-14 02:06:04 +00:00
dependabot[bot]
88576271e2
Bump agcp from 1.6.5.200 to 1.6.5.300 (#1831) 2022-04-14 02:05:12 +00:00
dependabot[bot]
b088551005
Bump hianalytics from 6.4.1.301 to 6.4.1.302 (#1832) 2022-04-14 02:04:53 +00:00
Mikołaj Pich
130e11a629 Merge branch 'release/1.6.2' into develop 2022-04-10 20:37:21 +02:00
Mikołaj Pich
d5e0ae7b37 Merge branch 'release/1.6.2' 2022-04-10 20:37:17 +02:00
Mikołaj Pich
e6f56a74a4 Version 1.6.2 2022-04-10 20:37:10 +02:00
Rafał Borcz
1bc59cfa7f
Another attempt to fix destination crash (#1826) 2022-04-10 20:23:46 +02:00
Mikołaj Pich
41bae262a5 Merge branch 'release/1.6.1' into develop 2022-04-06 17:28:55 +02:00
Mikołaj Pich
ae65228805 Merge branch 'release/1.6.1' 2022-04-06 17:28:50 +02:00
Mikołaj Pich
391ee6e621 Version 1.6.1 2022-04-06 17:27:27 +02:00
Rafał Borcz
0a87df3d82
New Crowdin updates (#1817) 2022-04-06 17:19:38 +02:00
Rafał Borcz
cb4ae21903
Replace Serializable to Parcelable in Destination (#1823) 2022-04-06 08:01:41 +02:00
Rafał Borcz
679cf2554d
Fix text in lucky number widget (#1825) 2022-04-06 08:01:11 +02:00
Rafał Borcz
d473d53879
Add standard register variant as translatable string (#1824) 2022-04-05 13:56:11 +02:00
Mat Lee
6531061b48
Fix text aligment in exam dialog (#1821) 2022-04-05 10:30:49 +02:00
dependabot[bot]
3347e8fba8
Bump kotlin_version from 1.6.10 to 1.6.20 (#1818) 2022-04-05 08:10:07 +00:00
dependabot[bot]
84067126a1
Bump hianalytics from 6.4.1.300 to 6.4.1.301 (#1819) 2022-04-05 08:09:46 +00:00
Mikołaj Pich
da9bebe923 Merge branch 'release/1.6.0' into develop 2022-04-02 22:02:01 +02:00
Mikołaj Pich
b371fd6709 Merge branch 'release/1.6.0' 2022-04-02 22:01:53 +02:00
Mikołaj Pich
884d443c5b Version 1.6.0 2022-04-02 22:01:34 +02:00
Rafał Borcz
df58aa78ae
New Crowdin updates (#1783) 2022-03-31 09:00:41 +02:00
Rafał Borcz
2131e892ad
Add option to select multiple messages to delete (#1780) 2022-03-28 19:30:20 +02:00
dependabot[bot]
63380d3e12
Bump agcp from 1.6.4.300 to 1.6.5.200 (#1812) 2022-03-28 13:53:57 +00:00
dependabot[bot]
c572a91b38
Bump agconnect-crash from 1.6.4.300 to 1.6.5.200 (#1811) 2022-03-28 13:53:42 +00:00
Michael
20dde6e896
Resource refactor (#1589) 2022-03-27 15:33:32 +02:00
dependabot[bot]
042b66ca5c
Bump core-splashscreen from 1.0.0-beta01 to 1.0.0-beta02 (#1810) 2022-03-26 22:37:53 +00:00
dependabot[bot]
8d8990761a
Bump firebase-bom from 29.2.1 to 29.3.0 (#1809) 2022-03-26 22:37:22 +00:00
dependabot[bot]
a07741b5c5
Bump WhatTheStack from 1.0.0-alpha03 to 1.0.0-alpha04 (#1807) 2022-03-22 17:49:32 +00:00
dependabot[bot]
f851a4d2c5
Bump huawei-publish-gradle-plugin from 1.3.1 to 1.3.3 (#1806) 2022-03-22 12:47:27 -05:00
dependabot[bot]
c8d069c787
Bump hianalytics from 6.4.0.300 to 6.4.1.300 (#1805) 2022-03-20 00:25:31 +00:00
dependabot[bot]
5ce30a3000
Bump firebase-bom from 29.2.0 to 29.2.1 (#1804) 2022-03-20 00:25:11 +00:00
dependabot[bot]
26e0f43fa0
Bump firebase-bom from 29.1.0 to 29.2.0 (#1803) 2022-03-17 18:28:26 +00:00
Mikołaj Pich
08c1bedca1
Add the option to quickly add a calendar event from the exam details (#1802)
* Extract intent utils to separate file

* Add add to calendar button in exam details dialog

* Set 8:00-8:45 start/end time
2022-03-14 00:38:40 +01:00
Mikołaj Pich
15537586c4
Add exam date field to exam details dialog (#1801) 2022-03-13 22:47:54 +01:00
Mikołaj Pich
a04ba4ae10
Login improvements (#1800)
* Update sdk

* Change default register variant name

* Change symbol hint message and email template
2022-03-13 22:43:57 +01:00
Mikołaj Pich
57ea6379ab
Timetable timer refactor (#1785) 2022-03-13 04:01:14 +01:00
dependabot[bot]
c3abe50ed4
Bump gradle from 7.1.1 to 7.1.2 (#1790) 2022-02-28 18:59:53 +00:00
dependabot[bot]
f48caf9f70
Bump play-services-ads from 20.5.0 to 20.6.0 (#1792) 2022-02-28 18:41:16 +00:00
dependabot[bot]
9a413c14c3
Bump agcp from 1.6.4.200 to 1.6.4.300 (#1791) 2022-02-28 18:37:29 +00:00
dependabot[bot]
8915c5dd8e
Bump agconnect-crash from 1.6.4.200 to 1.6.4.300 (#1793) 2022-02-28 18:32:31 +00:00
dependabot[bot]
e7561d4794
Bump room from 2.4.1 to 2.4.2 (#1794) 2022-02-28 18:32:08 +00:00
dependabot[bot]
820b99dbc7
Bump hilt_version from 2.40.5 to 2.41 (#1786) 2022-02-21 19:35:02 +00:00
Michael
aff0fb3a60
Add information about student in grade statistics pie chart (#1749)
Co-authored-by: Mikołaj Pich <m.pich@outlook.com>
2022-02-15 13:08:44 +01:00
dependabot[bot]
d3bf5c3e0a
Bump lifecycle-livedata-ktx from 2.4.0 to 2.4.1 (#1781) 2022-02-14 20:06:05 +00:00
dependabot[bot]
dec2703cc7
Bump firebase-bom from 29.0.4 to 29.1.0 (#1782) 2022-02-14 20:05:45 +00:00
Rafał Borcz
edd1c9442e
Fix calc vulcan average in second semester (#1779) 2022-02-12 22:22:15 +01:00
Rafał Borcz
18568c86be
New Crowdin updates (#1776) 2022-02-12 12:19:25 +01:00
Rafał Borcz
84d0ba525f
Fix blank description in exam details (#1778) 2022-02-10 07:36:44 +01:00
dependabot[bot]
6290663f02
Bump gradle from 7.1.0 to 7.1.1 (#1777) 2022-02-07 04:41:09 +00:00
Patryk
be046a1ddd
Update date in LICENSE file (#1775) 2022-02-07 03:16:17 +01:00
Michael
96ee4bd9e5
Keep reacting to live changes in dashboard after a force refresh (#1594)
Co-authored-by: Rafał Borcz <RafalBO99@outlook.com>
2022-02-02 02:44:14 +00:00
dependabot[bot]
923af85d18
Bump fragment-ktx from 1.4.0 to 1.4.1 (#1774) 2022-02-02 01:53:16 +00:00
dependabot[bot]
ce36e86bb2
Bump preference-ktx from 1.1.1 to 1.2.0 (#1773) 2022-01-29 05:38:55 +00:00
dependabot[bot]
a4f455b38f
Bump hianalytics from 6.3.2.300 to 6.4.0.300 (#1771) 2022-01-29 04:55:02 +00:00
dependabot[bot]
01b8bd9d4a
Bump agconnect-crash from 1.6.3.300 to 1.6.4.200 (#1770) 2022-01-29 04:47:56 +00:00
dependabot[bot]
cfcc051ce4
Bump gradle from 7.0.4 to 7.1.0 (#1769) 2022-01-29 04:47:26 +00:00
dependabot[bot]
0b0993be9a
Bump agcp from 1.6.3.300 to 1.6.4.200 (#1772) 2022-01-29 04:47:00 +00:00
dependabot[bot]
d07b0dbc98
Bump WhatTheStack from 1.0.0-alpha02 to 1.0.0-alpha03 (#1768) 2022-01-29 04:46:09 +00:00
Michael
daa7b54dab
Refactor notification destinations (#1709)
Co-authored-by: Rafał Borcz <RafalBO99@outlook.com>
2022-01-28 13:43:56 +01:00
Rafał Borcz
de9fcb9af9
Add what-the-stack library (#1767) 2022-01-28 12:07:48 +01:00
dependabot[bot]
40e0934504
Bump fuzzywuzzy from 1.3.3 to 1.4.0 (#1765) 2022-01-28 11:07:22 +00:00
dependabot[bot]
009ec433be
Bump firebase-bom from 29.0.3 to 29.0.4 (#1766) 2022-01-27 12:06:30 +00:00
Rafał Borcz
e1d82d70ee
New translations strings.xml (German) (#1746) 2022-01-23 20:04:01 +01:00
dependabot[bot]
7a9ba04ff4
Bump material from 1.4.0 to 1.5.0 (#1757) 2022-01-23 02:17:14 +00:00
dependabot[bot]
513b4b7d3e
Bump coordinatorlayout from 1.1.0 to 1.2.0 (#1756) 2022-01-23 01:43:30 +00:00
dependabot[bot]
ce4157933f
Bump core-splashscreen from 1.0.0-alpha02 to 1.0.0-beta01 (#1752) 2022-01-23 01:39:16 +00:00
dependabot[bot]
5d1085a64a
Bump fuzzywuzzy from 1.3.1 to 1.3.3 (#1754) 2022-01-23 00:58:12 +00:00
dependabot[bot]
a00f2dcbda
Bump core from 1.10.2 to 1.10.3 (#1753) 2022-01-23 00:57:40 +00:00
dependabot[bot]
b52a6f7f61
Bump room from 2.4.0 to 2.4.1 (#1755) 2022-01-23 00:57:17 +00:00
dependabot[bot]
5146e44574
Bump agconnect-crash from 1.6.3.200 to 1.6.3.300 (#1758) 2022-01-23 00:56:57 +00:00
dependabot[bot]
90e1cea679
Bump appcompat from 1.4.0 to 1.4.1 (#1759) 2022-01-23 00:56:37 +00:00
dependabot[bot]
c9b506ae10
Bump agcp from 1.6.3.200 to 1.6.3.300 (#1760) 2022-01-23 00:56:16 +00:00
dependabot[bot]
14ebdad7b2
Bump constraintlayout from 2.1.2 to 2.1.3 (#1761) 2022-01-23 00:55:58 +00:00
dependabot[bot]
210308695b
Bump huawei-publish-gradle-plugin from 1.3.0 to 1.3.1 (#1750) 2022-01-11 11:12:48 +00:00
dependabot[bot]
d5cc2263f5
Bump mockk from 1.12.1 to 1.12.2 (#1747) 2022-01-04 10:13:31 +00:00
Mikołaj Pich
47e3f2dc58 Merge branch 'release/1.5.0' into develop 2022-01-01 17:51:19 +01:00
Mikołaj Pich
6dc16b288d Merge branch 'release/1.5.0' 2022-01-01 17:51:11 +01:00
Mikołaj Pich
daf97be9ad Version 1.5.0 2022-01-01 17:50:02 +01:00
Rafał Borcz
2bb2190410
New Crowdin updates (#1745) 2022-01-01 17:48:58 +01:00
Mikołaj Pich
aff1a7030d
Add a custom error message for ssl errors due to invalid clock setting (#1742) 2022-01-01 15:46:08 +01:00
Mikołaj Pich
8877322357
Differentiate school announcements by userLoginId (#1744) 2022-01-01 13:52:51 +01:00
Mikołaj Pich
bc672e94f8
Strip html from school announcements notifications (#1743) 2022-01-01 13:48:58 +01:00
Mikołaj Pich
a03bcf8e62
Display comment after entry in grade notifications (#1741) 2021-12-31 11:36:14 +00:00
Mikołaj Pich
20673c4ead
Add basic support for kindergarten students (#1738) 2021-12-31 12:21:52 +01:00
Rafał Borcz
5321d00ee9
Fix play flavor build (#1740) 2021-12-31 12:10:56 +01:00
Michael
e6b2acabd5
Block app timezone to polish timezone (#1598) 2021-12-31 11:53:09 +01:00
Mikołaj Pich
bfd7f688ab
Move webview locale fix to account recovery fragment (#1739) 2021-12-31 10:24:02 +00:00
Mikołaj Pich
ba02531aa4
Fix timetable widget crash when there are no lessons for the day (#1737) 2021-12-31 09:40:15 +01:00
Michael
210c3a0e28
Remove HiltBroadcastReceiver (#1736) 2021-12-30 12:50:06 +01:00
Michael
68f0ecc45c
If only one student exists, don't show student name in timetable notification (#1711)
Co-authored-by: Rafał Borcz <RafalBO99@outlook.com>
2021-12-29 15:44:43 +01:00
Rafał Borcz
0965d03f1a
New Crowdin updates (#1734) 2021-12-29 11:57:17 +01:00
Michael
496641f594
Fix notification spam after login (#1715) 2021-12-29 08:31:43 +01:00
Rafał Borcz
684c258e2d
Remove admin message offline first cache (#1735) 2021-12-28 18:56:59 +01:00
Michael
5e96917508
Fix overlapping text in the error dialog (#1708) 2021-12-28 12:16:52 +01:00
Rafał Borcz
17096ad11b
New Crowdin updates (#1729) 2021-12-27 14:06:20 +01:00
Michael
bd883c9f38
Add option to remove notifications captured from vulcan.hebe (#1716) 2021-12-27 07:48:47 +00:00
Michael
6520f8a0d7
Fix that an incorrect day would be selected in MaterialDatePicker (#1723) 2021-12-27 08:10:30 +01:00
Mikołaj Pich
2eee50ad81
Replace view pager in login activity with simple fragment transactions (#1686) 2021-12-27 07:58:57 +01:00
dependabot[bot]
8560fd7e81
Bump coroutines from 1.5.2 to 1.6.0 (#1731) 2021-12-25 08:38:27 +00:00
dependabot[bot]
f718147ae9
Bump agcp from 1.6.2.300 to 1.6.3.200 (#1730) 2021-12-25 05:55:01 +00:00
dependabot[bot]
cd12c4c891
Bump agconnect-crash from 1.6.2.300 to 1.6.3.200 (#1732) 2021-12-25 05:54:34 +00:00
dependabot[bot]
65f114ce05
Bump kotlinx-serialization-json from 1.3.1 to 1.3.2 (#1733) 2021-12-25 05:54:17 +00:00
Mateusz Idziejczak
497083be97
Update timetable to next day if there is no more lessons today (#1551) 2021-12-25 05:46:24 +00:00
Michael
e26860ea5a
Fix state restoring in GradeStatistics (#1667)
Co-authored-by: Mikołaj Pich <m.pich@outlook.com>
2021-12-23 13:58:26 +01:00
Mateusz Idziejczak
094df212b4
Add additional lessons feature (#1550) 2021-12-21 00:36:59 +01:00
dependabot[bot]
cc22985dc5
Bump firebase-bom from 29.0.2 to 29.0.3 (#1728) 2021-12-20 20:22:56 +00:00
Rafał Borcz
ad9a2711c4
New Crowdin updates (#1687) 2021-12-19 22:46:41 +01:00
Mikołaj Pich
daf44c531c Merge branch 'release/1.4.4' into develop 2021-12-19 22:25:56 +01:00
Mikołaj Pich
4e12eb1552 Merge branch 'release/1.4.4' 2021-12-19 22:25:52 +01:00
Mikołaj Pich
c846cc999f Version 1.4.4 2021-12-19 22:25:47 +01:00
Mikołaj Pich
47d430292c
Update template of login issue email (#1724)
* Update sdk

* Update template of login issue email
2021-12-19 22:08:39 +01:00
Michael
5e1ff2243f
Fix exception in TimetableAdapter (#1721) 2021-12-12 23:09:34 +01:00
dependabot[bot]
a35bef58f2
Bump gradle from 7.0.3 to 7.0.4 (#1718) 2021-12-12 14:06:15 +00:00
dependabot[bot]
0005d84974
Bump hilt_version from 2.40.4 to 2.40.5 (#1719) 2021-12-12 14:05:53 +00:00
dependabot[bot]
19558cb871
Bump firebase-bom from 29.0.1 to 29.0.2 (#1720) 2021-12-12 14:05:35 +00:00
Michael
45e884127f
After deselecting fakelog, clear credentials from login form (#1713) 2021-12-12 15:04:31 +01:00
Michael
c87085a226
Fix invalid order of school announcements (#1689) 2021-12-11 17:35:55 +01:00
Michael
79b970256f
More strongly typed data in preferences (#1697) 2021-12-11 16:14:46 +00:00
Michael
70f038f15f
Remove useless group property from NotificationType (#1714) 2021-12-11 17:12:47 +01:00
Michael
9cabd7ef08
Deduplicate timetable time left string (#1710) 2021-12-11 16:42:33 +01:00
Rafał Borcz
d89e4ccfdf
Fix grade sorting by date (#1717) 2021-12-11 11:54:07 +01:00
Michael
1bcc4d199e
When replying to a message use Re instead of RE (#1712) 2021-12-10 16:24:39 +01:00
dependabot[bot]
2e85e88c5d
Bump agcp from 1.6.2.200 to 1.6.2.300 (#1693) 2021-12-08 10:21:00 +00:00
dependabot[bot]
6ab67fe25b
Bump firebase-bom from 29.0.0 to 29.0.1 (#1696) 2021-12-08 10:04:29 +00:00
dependabot[bot]
8563277a89
Bump robolectric from 4.7.2 to 4.7.3 (#1695) 2021-12-08 10:04:10 +00:00
dependabot[bot]
e458cc90b0
Bump agconnect-crash from 1.6.2.200 to 1.6.2.300 (#1694) 2021-12-08 10:03:42 +00:00
dependabot[bot]
651e3a21b9
Bump firebase-crashlytics-gradle from 2.8.0 to 2.8.1 (#1692) 2021-12-08 10:03:06 +00:00
dependabot[bot]
f6b969cfb1
Bump hilt_version from 2.40.2 to 2.40.4 (#1691) 2021-12-08 10:02:43 +00:00
Michael
d2aa940d46
Convert from a stringly typed grade color to enum GradeColorTheme (#1672) 2021-11-27 10:11:17 +01:00
Mikołaj Pich
ab435a72ea Merge branch 'release/1.4.3' into develop 2021-11-26 22:29:13 +01:00
Mikołaj Pich
a56f4b8745 Merge branch 'release/1.4.3' 2021-11-26 22:29:09 +01:00
Mikołaj Pich
d003b0897c Version 1.4.3 2021-11-26 22:29:03 +01:00
Rafał Borcz
581bb2de77
New Crowdin updates (#1669) 2021-11-26 20:22:54 +01:00
Rafał Borcz
495e385228
Fix snackbar crash in grade statistics view (#1682) 2021-11-25 23:48:08 +01:00
dependabot[bot]
10ba36ba44
Bump hianalytics from 6.3.0.303 to 6.3.2.300 (#1684) 2021-11-25 22:46:30 +00:00
dependabot[bot]
eae396424f
Bump hilt_version from 2.40.1 to 2.40.2 (#1683) 2021-11-25 22:46:17 +00:00
Michael
a7891bb266
Update viewpager2 library to fix duplicated menu bug (#1681) 2021-11-24 09:53:16 +01:00
dependabot[bot]
6e82409dbc
Bump play-services-ads from 20.4.0 to 20.5.0 (#1675) 2021-11-23 02:02:03 +00:00
dependabot[bot]
984db18be3
Bump agcp from 1.6.1.300 to 1.6.2.200 (#1674) 2021-11-23 01:55:49 +00:00
dependabot[bot]
c99bc96c08
Bump logging-interceptor from 4.9.2 to 4.9.3 (#1676) 2021-11-23 01:55:10 +00:00
dependabot[bot]
3e7030abc2
Bump agconnect-crash from 1.6.1.300 to 1.6.2.200 (#1677) 2021-11-23 01:54:47 +00:00
dependabot[bot]
6dad3b299b
Bump robolectric from 4.7 to 4.7.2 (#1678) 2021-11-23 01:54:26 +00:00
Mikołaj Pich
5e997f5a3e Merge branch 'release/1.4.2' into develop 2021-11-21 13:31:56 +01:00
Mikołaj Pich
601d573283 Merge branch 'release/1.4.2' 2021-11-21 13:31:51 +01:00
Mikołaj Pich
6ae6ca7fbb Version 1.4.2 2021-11-21 13:31:45 +01:00
Rafał Borcz
c3d38afc3d
New Crowdin updates (#1658) 2021-11-21 13:23:43 +01:00
Rafał Borcz
4e19964249
Make admin messages dissmisable (#1661) 2021-11-21 09:02:12 +01:00
Rafał Borcz
a6c0efcb81
Fix empty student list in LoginStudentSelect view (#1668) 2021-11-21 07:47:23 +00:00
Rafał Borcz
fcc71c0d5f
Add ads limit (#1662) 2021-11-21 08:34:28 +01:00
Rafał Borcz
a59d10b6c1
Disable personalized ads in single support advert (#1665) 2021-11-20 16:46:14 +01:00
Rafał Borcz
a48e4eb4ee
Probably fix snackbar crash in grade statistics view (#1663) 2021-11-20 16:42:21 +01:00
Rafał Borcz
2a3668bb18
Fix nul login data in login symbol view (#1664) 2021-11-20 16:41:12 +01:00
Rafał Borcz
804d0d9113
Add multiline to support ad preference (#1651) 2021-11-18 20:23:09 +01:00
Mikołaj Pich
88b893e6c0
Fix upcoming lesson notifications on Android 12 (#1650) 2021-11-18 20:22:15 +01:00
Damian Czupryn
2874a7495e
Add Czech and Slovak README (#1631) 2021-11-18 19:38:51 +01:00
Robi321
40d8f7a93d
German readme version (#1629) 2021-11-18 16:31:59 +01:00
dependabot[bot]
84cd51205f
Bump appcompat from 1.4.0-rc01 to 1.4.0 (#1654) 2021-11-18 01:02:12 +00:00
dependabot[bot]
bac1832f27
Bump mockk from 1.12.0 to 1.12.1 (#1653) 2021-11-18 00:40:59 +00:00
dependabot[bot]
8bf1e22407
Bump flow-preferences from 1.5.0 to 1.6.0 (#1657) 2021-11-18 00:40:38 +00:00
dependabot[bot]
e9f43f925c
Bump constraintlayout from 2.1.1 to 2.1.2 (#1656) 2021-11-18 00:37:26 +00:00
dependabot[bot]
aa632edf5c
Bump fragment-ktx from 1.4.0-rc01 to 1.4.0 (#1655) 2021-11-18 00:36:18 +00:00
dependabot[bot]
57315d75c6
Bump work_manager from 2.7.0 to 2.7.1 (#1652) 2021-11-18 00:36:00 +00:00
dependabot[bot]
4552bc85b0
Bump kotlin_version from 1.5.31 to 1.6.0 (#1635) 2021-11-18 01:34:55 +01:00
Mikołaj Pich
6b7795118c Merge branch 'release/1.4.1' into develop 2021-11-16 23:29:22 +01:00
Mikołaj Pich
1960782d8e Merge branch 'release/1.4.1' 2021-11-16 23:29:17 +01:00
Mikołaj Pich
8836be3766 Version 1.4.1 2021-11-16 23:29:12 +01:00
Rafał Borcz
8697993149
Add missing env for google play build (#1647) 2021-11-16 23:28:03 +01:00
Mikołaj Pich
b88c7eb4e4 Merge branch 'release/1.4.0' into develop 2021-11-16 22:49:58 +01:00
Mikołaj Pich
9066bce0d5 Merge branch 'release/1.4.0' 2021-11-16 22:49:53 +01:00
Mikołaj Pich
f15b90782a Version 1.4.0 2021-11-16 22:40:30 +01:00
Rafał Borcz
0642bf7d73
New Crowdin updates (#1646) 2021-11-16 22:38:53 +01:00
Mikołaj Pich
981d6d559c
Login improvements (#1645) 2021-11-16 21:05:00 +00:00
Mikołaj Pich
39327ff3ea
School and teachers UI fixes (#1644) 2021-11-16 21:45:14 +01:00
Michael
b098ac029b
Fix displaying errors in GradeDetailsPresenter (#1600) 2021-11-16 20:42:06 +00:00
Rafał Borcz
7e0e2fbb67
Fix saved state in main and splash activity (#1633) 2021-11-16 18:13:10 +01:00
Rafał Borcz
8a181c747c
Remove deprecated usage of LifecycleObserver (#1641) 2021-11-16 00:38:52 +01:00
Rafał Borcz
68fdb167c2
Sort items in homework and grade tiles on the dashboard (#1634) 2021-11-15 22:35:01 +01:00
dependabot[bot]
17563d1a4b
Bump hianalytics from 6.3.0.302 to 6.3.0.303 (#1636) 2021-11-15 13:56:39 +00:00
dependabot[bot]
370881104e
Bump hilt_version from 2.40 to 2.40.1 (#1637) 2021-11-15 13:56:03 +00:00
dependabot[bot]
62b1b18326
Bump kotlinx-serialization-json from 1.3.0 to 1.3.1 (#1638) 2021-11-15 13:55:45 +00:00
dependabot[bot]
214e43bd4b
Bump robolectric from 4.6.1 to 4.7 (#1639) 2021-11-15 13:55:18 +00:00
dependabot[bot]
358e0850ad
Bump appcompat from 1.4.0-beta01 to 1.4.0-rc01 (#1640) 2021-11-15 13:40:51 +00:00
Michael
c183428107
Prevent changing the current day by accident when excusing absences (#1599) 2021-11-13 19:56:17 +01:00
Mikołaj Pich
6de937703a
Fix admin messages caching (#1632) 2021-11-13 19:50:26 +01:00
Rafał Borcz
10cb2b70f1
New Crowdin updates (#1630) 2021-11-13 10:36:19 +01:00
Michael
9230db3f99
Do not show student's name in notifications if there's only one student (#1609) 2021-11-13 10:06:59 +01:00
dependabot[bot]
66e58ab74e
Bump activity-ktx from 1.3.1 to 1.4.0 (#1620) 2021-11-13 03:15:14 +00:00
dependabot[bot]
99b7af64c0
Bump lifecycle-livedata-ktx from 2.3.1 to 2.4.0 (#1618) 2021-11-13 02:25:38 +00:00
Rafał Borcz
4295dd6246
New Crowdin updates (#1566) 2021-11-11 15:56:56 +01:00
Rafał Borcz
fb2d92c749
Fix homework sync (#1627) 2021-11-11 15:52:46 +01:00
dependabot[bot]
07b1969a35
Bump core-ktx from 1.6.0 to 1.7.0 (#1622) 2021-11-11 14:33:01 +00:00
dependabot[bot]
886403bf1e
Bump annotation from 1.2.0 to 1.3.0 (#1628) 2021-11-11 14:32:19 +00:00
dependabot[bot]
e8b21c1429
Bump coil from 1.3.2 to 1.4.0 (#1573) 2021-11-11 14:32:04 +00:00
Rafał Borcz
007d62e61d
Update project to Android SDK 31 (#1570) 2021-11-11 15:23:20 +01:00
Mateusz Idziejczak
f88d44f0ec
Add timetable changes, attendance notifications and refactor notification deeplinks (#1547) 2021-11-06 22:21:34 +01:00
Michael
4401df6203
Migrate from ViewPager to ViewPager2 (#1601) 2021-11-06 19:07:26 +01:00
Patryk
e6f23ab35b
Add support for user ca in debug flavor(#1624) 2021-11-04 03:09:47 +01:00
Damian Czupryn
eea20ced57
Notifications settings reorganize and strings update (#1616) 2021-11-04 03:06:54 +01:00
dependabot[bot]
b7134221cb
Bump hilt_version from 2.39.1 to 2.40 (#1617) 2021-11-01 17:05:57 +00:00
dependabot[bot]
8be605629a
Bump firebase-crashlytics-gradle from 2.7.1 to 2.8.0 (#1623) 2021-11-01 16:56:18 +00:00
dependabot[bot]
1a3d580116
Bump firebase-bom from 28.4.2 to 29.0.0 (#1619) 2021-11-01 16:54:43 +00:00
dependabot[bot]
a62ed54d07
Bump hianalytics from 6.3.0.301 to 6.3.0.302 (#1621) 2021-11-01 16:54:10 +00:00
Damian Czupryn
36a570eeb0
Allow selecting text in error dialog (#1615) 2021-11-01 01:46:23 +01:00
Damian Czupryn
8ed8b5a33c
Error messages content wrap in error dialog (#1577) 2021-10-31 20:28:01 +01:00
Michael
26c749c219
Fix about header layout to support long app names (for DEV builds) (#1602)
Co-authored-by: Mikołaj Pich <m.pich@outlook.com>
2021-10-29 20:30:27 +02:00
Michael
1d910f8d66
Fix excuse button showing up despite no lessons available to excuse (#1607)
This was happening when there was an unexcused lesson that you excused until the teacher sent a response (accepted or denied it)
2021-10-27 10:07:04 +02:00
dependabot[bot]
de11644e9b
Bump agconnect-crash from 1.6.1.200 to 1.6.1.300 (#1605) 2021-10-26 09:53:16 +00:00
dependabot[bot]
621db49fbf
Bump agcp from 1.6.1.200 to 1.6.1.300 (#1606) 2021-10-26 09:52:55 +00:00
dependabot[bot]
b593795844
Bump about_libraries from 8.9.3 to 8.9.4 (#1604) 2021-10-26 09:51:36 +00:00
Michael
0f800b61f6
Allow expanding multiple subject' grades at once (#1584) 2021-10-24 01:23:36 +02:00
Rafał Borcz
94fd303f8e
Add single support advert (#1484) 2021-10-21 10:51:00 +02:00
Rafał Borcz
09a134d442
Fix last sync date to save only successful sync (#1595) 2021-10-21 10:47:37 +02:00
dependabot[bot]
58ea2c530e
Bump hianalytics from 6.3.0.300 to 6.3.0.301 (#1593) 2021-10-19 06:36:46 +00:00
Mikołaj Pich
84e4167dbd
Mi Band notification improvements (#1579) 2021-10-18 00:11:46 +02:00
Michael
54e9ea6478
Use FloatingActionButton.{show,hide} instead of using setVisibility (#1591) 2021-10-16 11:17:00 +02:00
Rafał Borcz
4c8d9c8f7f
Fix infinite refresh when admin messages list is empty (#1587) 2021-10-14 16:25:09 +02:00
dependabot[bot]
e7550f7a43
Bump gradle from 7.0.2 to 7.0.3 (#1586) 2021-10-14 00:10:22 +00:00
Michael
ac86737050
Fix NPE in SyncPresenter (#1582) 2021-10-14 01:44:34 +02:00
Rafał Borcz
e3122127c0
Add admin messages (#1553) 2021-10-13 23:58:24 +02:00
Stanisław Jelnicki
d6918077bf
Set upcoming lesson notification visibility to public (#1581) 2021-10-13 21:47:03 +02:00
dependabot[bot]
9d0366d010
Bump firebase-bom from 28.4.1 to 28.4.2 (#1574) 2021-10-11 15:44:19 +00:00
dependabot[bot]
3d0cd11ba4
Bump Treessence from 1.0.4 to 1.0.5 (#1575) 2021-10-11 15:44:03 +00:00
dependabot[bot]
64dbbd54b4
Bump hianalytics from 6.2.0.301 to 6.3.0.300 (#1576) 2021-10-11 15:43:29 +00:00
Rafał Borcz
539be586ce
Fix text color of time left indicator on dashboard timetable card (#1572) 2021-10-11 14:39:54 +02:00
Rafał Borcz
a240fd5d5f
Add build timestamp as build config field (#1567) 2021-10-09 18:37:27 +02:00
Damian Czupryn
4e69cfe23c
Change text when there are no lessons today and tomorrow in dashboard (#1571) 2021-10-09 15:36:22 +00:00
Damian Czupryn
2ab0a57a41
Separate calculated average settings (#1558) 2021-10-09 01:55:00 +02:00
Damian Czupryn
ebf9e741c2
Fix homework last item padding (#1568) 2021-10-09 01:04:04 +02:00
Mateusz Idziejczak
e8075e30e4
Add "add homework" feature (#1564) 2021-10-08 11:19:49 +02:00
Mikołaj Pich
1839d7cb8f
Migrate from moshi to kotlinx serialization (#1557) 2021-10-04 17:13:31 +02:00
dependabot[bot]
2d84b0775a
Bump hilt_version from 2.38.1 to 2.39.1 (#1561) 2021-10-04 14:51:31 +00:00
dependabot[bot]
426379ec17
Bump about_libraries from 8.9.1 to 8.9.3 (#1560) 2021-10-04 14:45:09 +00:00
dependabot[bot]
8315759c83
Bump agcp from 1.6.0.300 to 1.6.1.200 (#1562) 2021-10-04 14:44:15 +00:00
dependabot[bot]
04393e60bb
Bump agconnect-crash from 1.6.0.300 to 1.6.1.200 (#1563) 2021-10-04 14:43:46 +00:00
Damian Czupryn
031a17ea50
Change text to bold in notifications center (#1546) 2021-10-04 16:35:37 +02:00
Mikołaj Pich
60501fcd72
Set buildTimestamp through manifest meta (#1556) 2021-10-03 14:13:42 +02:00
Rafał Borcz
8e607d48f7
Add coroutines scope to presenter (#1554) 2021-10-03 10:36:17 +02:00
Damian Czupryn
e02d93f979
Add Czech and Slovak listings (#1555) 2021-10-03 01:07:45 +02:00
Mikołaj Pich
76514e2d72 Merge branch 'release/1.3.0' into develop 2021-09-28 23:26:22 +02:00
Mikołaj Pich
689012131f Merge branch 'release/1.3.0' 2021-09-28 23:26:18 +02:00
Mikołaj Pich
6cdcf92782 Version 1.3.0 2021-09-28 23:26:10 +02:00
Rafał Borcz
9c8bcbfdd3
New Crowdin updates (#1544) 2021-09-28 21:11:59 +00:00
Mikołaj Pich
0b83a66b85
Remove disappearing teachers workaround from timetable repository (#1545) 2021-09-28 23:10:11 +02:00
Rafał Borcz
9711cc868c
New Crowdin updates (#1522) 2021-09-28 22:42:06 +02:00
Mikołaj Pich
f8cb7599e6
Add missing auto refresh to recipients, subjects and teachers (#1540) 2021-09-28 22:40:43 +02:00
Patryk
7636618e23
Update License (#1542) 2021-09-28 21:55:40 +02:00
Mateusz Idziejczak
5bc54c12f1
Add option to make upcoming lesson notification not persistent (#1537) 2021-09-28 11:48:25 +02:00
Rafał Borcz
e10e530dee
Remove seconds from timetable timer (#1539) 2021-09-27 23:03:59 +02:00
Rafał Borcz
d69118b085
Add notifications center (#1524) 2021-09-27 20:58:25 +02:00
Mateusz Idziejczak
dc90549b9d
Fix hiding last element in messages (#1538) 2021-09-27 17:56:43 +02:00
dependabot[bot]
b552dbc904
Bump constraintlayout from 2.1.0 to 2.1.1 (#1535) 2021-09-27 15:56:11 +00:00
dependabot[bot]
a6a1678b47
Bump core from 1.10.1 to 1.10.2 (#1536) 2021-09-27 15:51:06 +00:00
Piotr Romanowski
7a46ef5f19
Add calculated average help dialog (#1379)
Co-authored-by: Rafał Borcz <RafalBO99@outlook.com>
2021-09-25 17:19:21 +02:00
Mikołaj Pich
f9e0f7b390
Don't stop loading the timetable when error occurs in upcoming lessons notification scheduling (#1532) 2021-09-25 15:18:40 +02:00
Rafał Borcz
9211baf7ec
Add notification piggyback (#1503) 2021-09-25 14:02:38 +02:00
Mateusz Idziejczak
de6131f4f5
Add transparency to lucky number widget (#1530) 2021-09-25 13:46:35 +02:00
Mateusz Idziejczak
2cb11e443c
Mark teacher with yellow when new and old are the same (#1529) 2021-09-25 13:46:11 +02:00
Mikołaj Pich
a43ffcdef4
Display bad credentials error in the message box above login form (#1525) 2021-09-24 21:02:51 +02:00
dependabot[bot]
6615e68430
Bump kotlin_version from 1.5.30 to 1.5.31 (#1528) 2021-09-22 09:25:54 +02:00
Mikołaj Pich
36daa7ccc1
Always include all language resources in app bundle (#1527) 2021-09-22 09:25:16 +02:00
Mikołaj Pich
6e5481f345
Upgrade Gradle Play Publisher to 3.6.0 (#1526) 2021-09-20 11:38:13 +02:00
Mikołaj Pich
ba1c14ca0e Merge branch 'release/1.2.3' into develop 2021-09-16 12:01:58 +02:00
Mikołaj Pich
c69bb2ef71 Merge branch 'release/1.2.3' 2021-09-16 12:01:54 +02:00
Mikołaj Pich
9cb4754132 Version 1.2.3 2021-09-16 12:01:49 +02:00
Mikołaj Pich
5ba8289c87
Display info in timetable as-is when lesson has change flag (#1521) 2021-09-16 11:59:23 +02:00
Rafał Borcz
258782c648
New Crowdin updates (#1482) 2021-09-16 11:30:05 +02:00
Rafał Borcz
c568bc1515
Fix ghost account after logout not current student (#1518) 2021-09-16 11:29:11 +02:00
Rafał Borcz
da668f93cf
Fix bugs in dashboard (#1517) 2021-09-16 11:24:52 +02:00
Rafał Borcz
037dbd792f
Add conference dialog (#1519) 2021-09-16 10:51:38 +02:00
dependabot[bot]
7ec7afed87
Bump firebase-bom from 28.4.0 to 28.4.1 (#1520) 2021-09-16 08:22:06 +00:00
Mikołaj Pich
bea50e6db5 Merge branch 'release/1.2.2' into develop 2021-09-13 14:53:38 +02:00
532 changed files with 50228 additions and 8216 deletions

12
.editorconfig Normal file
View file

@ -0,0 +1,12 @@
[*]
charset=utf-8
end_of_line=lf
insert_final_newline=true
indent_style=space
indent_size=4
[*.json]
indent_size=2
[*.{kt,kts}]
disabled_rules=import-ordering,no-wildcard-imports

View file

@ -1,4 +1,4 @@
name: Deploy to app stores
name: Deploy release
on:
release:
@ -7,16 +7,17 @@ on:
jobs:
deploy-google-play:
name: Deploy to google play
name: Google Play
runs-on: ubuntu-latest
timeout-minutes: 10
environment: google-play
steps:
- uses: actions/checkout@v2
- uses: actions/setup-java@v1
- uses: actions/checkout@v3
- uses: actions/setup-java@v2
with:
distribution: 'zulu'
java-version: 11
- uses: actions/cache@v2
- uses: actions/cache@v3
with:
path: |
~/.gradle/caches
@ -28,27 +29,31 @@ jobs:
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_STORE_PASSWORD: ${{ secrets.PLAY_STORE_PASSWORD }}
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;
ANDROID_PUBLISHER_CREDENTIALS: ${{ secrets.ANDROID_PUBLISHER_CREDENTIALS }}
ADMOB_PROJECT_ID: ${{ secrets.ADMOB_PROJECT_ID }}
SINGLE_SUPPORT_AD_ID: ${{ secrets.SINGLE_SUPPORT_AD_ID }}
DASHBOARD_TILE_AD_ID: ${{ secrets.DASHBOARD_TILE_AD_ID }}
SET_BUILD_TIMESTAMP: ${{ secrets.SET_BUILD_TIMESTAMP }}
run: ./gradlew publishPlayReleaseApps -PenableFirebase --stacktrace;
deploy-app-gallery:
name: Deploy to AppGallery
name: AppGallery
runs-on: ubuntu-latest
timeout-minutes: 10
environment: app-gallery
steps:
- uses: actions/checkout@v2
- uses: actions/setup-java@v1
- uses: actions/checkout@v3
- uses: actions/setup-java@v2
with:
distribution: 'zulu'
java-version: 11
- uses: actions/cache@v2
- uses: actions/cache@v3
with:
path: |
~/.gradle/caches
@ -60,7 +65,6 @@ jobs:
SERVICES_ENCRYPT_KEY: ${{ secrets.SERVICES_ENCRYPT_KEY }}
run: |
gpg --yes --batch --passphrase=$SERVICES_ENCRYPT_KEY ./app/src/release/agconnect-services.json.gpg
gpg --yes --batch --passphrase=$ENCRYPT_KEY ./app/key.p12.gpg
gpg --yes --batch --passphrase=$ENCRYPT_KEY ./app/upload-key.jks.gpg
- name: Prepare credentials
env:
@ -68,7 +72,8 @@ jobs:
run: echo $AGC_CREDENTIALS > ./app/src/release/agconnect-credentials.json
- name: Build and publish HMS version
env:
PLAY_STORE_PASSWORD: ${{ secrets.PLAY_STORE_PASSWORD }}
PLAY_KEY_ALIAS: ${{ secrets.PLAY_KEY_ALIAS }}
PLAY_KEY_PASSWORD: ${{ secrets.PLAY_KEY_PASSWORD }}
PLAY_STORE_PASSWORD: ${{ secrets.PLAY_STORE_PASSWORD }}
SET_BUILD_TIMESTAMP: ${{ secrets.SET_BUILD_TIMESTAMP }}
run: ./gradlew bundleHmsRelease --stacktrace && ./gradlew publishHuaweiAppGalleryHmsRelease --stacktrace

View file

@ -1,4 +1,4 @@
name: Deploy to app tests
name: Deploy DEV
on:
push:
@ -18,11 +18,12 @@ jobs:
timeout-minutes: 10
environment: app-center
steps:
- uses: actions/checkout@v2
- uses: actions/setup-java@v1
- uses: actions/checkout@v3
- uses: actions/setup-java@v2
with:
distribution: 'zulu'
java-version: 11
- uses: actions/cache@v2
- uses: actions/cache@v3
with:
path: |
~/.gradle/caches
@ -66,7 +67,7 @@ jobs:
BITRISE_KEY_PASSWORD: ${{ secrets.BITRISE_KEY_PASSWORD }}
run: ./gradlew assembleFdroidDebug --stacktrace
- name: Upload apk to github artifacts
uses: actions/upload-artifact@v2
uses: actions/upload-artifact@v3
with:
name: wulkanowyDEV-${{ env.RUN_NUMBER }}.apk
path: app/build/outputs/apk/fdroid/debug/app-fdroid-debug.apk
@ -87,11 +88,12 @@ jobs:
environment: app-distribution
if: github.event_name != 'pull_request_target'
steps:
- uses: actions/checkout@v2
- uses: actions/setup-java@v1
- uses: actions/checkout@v3
- uses: actions/setup-java@v2
with:
distribution: 'zulu'
java-version: 11
- uses: actions/cache@v2
- uses: actions/cache@v3
with:
path: |
~/.gradle/caches
@ -131,7 +133,7 @@ jobs:
BITRISE_KEY_PASSWORD: ${{ secrets.BITRISE_KEY_PASSWORD }}
run: ./gradlew assemblePlayDebug -PenableFirebase --stacktrace
- name: Upload apk to github artifacts
uses: actions/upload-artifact@v2
uses: actions/upload-artifact@v3
with:
name: wulkanowyDEV-${{ env.RUN_NUMBER }}-dev.apk
path: app/build/outputs/apk/play/debug/app-play-debug.apk

View file

@ -8,18 +8,20 @@ on:
branches: [ master, develop ]
jobs:
unit-tests:
name: Unit tests
tests-fdroid:
name: F-Droid
runs-on: ubuntu-latest
timeout-minutes: 10
steps:
- uses: fkirc/skip-duplicate-actions@master
- uses: actions/checkout@v2
- uses: actions/checkout@v3
- uses: gradle/wrapper-validation-action@v1
- uses: actions/setup-java@v1
- uses: actions/setup-java@v2
with:
distribution: 'zulu'
java-version: 11
- uses: actions/cache@v2
- uses: actions/cache@v3
with:
path: |
~/.gradle/caches
@ -29,6 +31,58 @@ jobs:
run: |
./gradlew testFdroidDebugUnitTest --stacktrace
./gradlew jacocoTestReport --stacktrace
- uses: codecov/codecov-action@v1
- uses: codecov/codecov-action@v3
with:
flags: unit
tests-play:
name: Play
runs-on: ubuntu-latest
timeout-minutes: 10
steps:
- uses: fkirc/skip-duplicate-actions@master
- uses: actions/checkout@v3
- uses: gradle/wrapper-validation-action@v1
- uses: actions/setup-java@v2
with:
distribution: 'zulu'
java-version: 11
- uses: actions/cache@v3
with:
path: |
~/.gradle/caches
~/.gradle/wrapper
key: gradle-${{ runner.os }}-${{ hashFiles('**/*.gradle*') }}
- name: Unit tests
run: |
./gradlew testPlayDebugUnitTest --stacktrace
./gradlew jacocoTestReport --stacktrace
- uses: codecov/codecov-action@v3
with:
flags: unit
tests-hms:
name: HMS
runs-on: ubuntu-latest
timeout-minutes: 10
steps:
- uses: fkirc/skip-duplicate-actions@master
- uses: actions/checkout@v3
- uses: gradle/wrapper-validation-action@v1
- uses: actions/setup-java@v2
with:
distribution: 'zulu'
java-version: 11
- uses: actions/cache@v3
with:
path: |
~/.gradle/caches
~/.gradle/wrapper
key: gradle-${{ runner.os }}-${{ hashFiles('**/*.gradle*') }}
- name: Unit tests
run: |
./gradlew testHmsDebugUnitTest --stacktrace
./gradlew jacocoTestReport --stacktrace
- uses: codecov/codecov-action@v3
with:
flags: unit

View file

@ -2,14 +2,6 @@
<code_scheme name="Project" version="173">
<option name="LINE_SEPARATOR" value="&#10;" />
<JetCodeStyleSettings>
<option name="PACKAGES_TO_USE_STAR_IMPORTS">
<value>
<package name="kotlinx.android.synthetic" alias="false" withSubpackages="true" />
</value>
</option>
<option name="NAME_COUNT_TO_USE_STAR_IMPORT" value="2147483647" />
<option name="NAME_COUNT_TO_USE_STAR_IMPORT_FOR_MEMBERS" value="2147483647" />
<option name="WRAP_ELVIS_EXPRESSIONS" value="0" />
<option name="CODE_STYLE_DEFAULTS" value="KOTLIN_OFFICIAL" />
</JetCodeStyleSettings>
<codeStyleSettings language="XML">
@ -126,13 +118,6 @@
</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" />
<indentOptions>
<option name="CONTINUATION_INDENT_SIZE" value="4" />
</indentOptions>
</codeStyleSettings>
</code_scheme>
</component>

View file

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

73
README.cs.md Normal file
View file

@ -0,0 +1,73 @@
Česká verze / [Deutsche Version](README.de.md) / [English version](README.en.md) / [Polska wersja](README.md) / [Slovenská verzia](README.sk.md)
# Wulkanowy
[![GitHub Workflow Status](https://img.shields.io/github/workflow/status/wulkanowy/wulkanowy/Tests/develop?style=flat-square)](https://github.com/wulkanowy/wulkanowy/actions)
[![Codecov](https://img.shields.io/codecov/c/github/wulkanowy/wulkanowy/master.svg?style=flat-square)](https://codecov.io/gh/wulkanowy/wulkanowy)
[![Discord](https://img.shields.io/discord/390889354199040011.svg?style=flat-square)](https://discord.gg/vccAQBr)
[![F-Droid](https://img.shields.io/f-droid/v/io.github.wulkanowy.svg?style=flat-square)](https://f-droid.org/packages/io.github.wulkanowy/)
[![Last release](https://img.shields.io/github/release/wulkanowy/wulkanowy.svg?logo=github&style=flat-square)](https://github.com/wulkanowy/wulkanowy/releases)
[![Crowdin](https://badges.crowdin.net/wulkanowy2/localized.svg)](https://translate.wulkanowy.net.pl)
Neoficiální klient deníku VULCAN UONET+ pro žáka a rodiče
## Funkce
* přihlášení pomocí emailu a hesla
* funkce z webové stránky deníku:
* známky
* statistiky známek
* frekvence
* procento frekvence
* zkoušky
* plán lekce
* dokončené lekce
* zprávy
* domácí úkoly
* poznámky
* šťastné číslo
* další lekce
* školní setkání
* informace o žáku a škole
* výpočet průměru nezávisle na preferencích školy
* upozornění, např. o nových známkách
* podpora více účtů s možností přejmenování žáků
* tmavý a černý (AMOLED) motiv
* offline režim
* žádné reklamy
## Stáhnout
Aktuální verzi si můžete stáhnout z Google Play, F-Droid nebo Huawei AppGallery
[<img src="https://play.google.com/intl/cs-CZ/badges/images/generic/cs_badge_web_generic.png"
alt="Nyní na Google Play"
height="80">](https://play.google.com/store/apps/details?id=io.github.wulkanowy)
[<img src="https://fdroid.gitlab.io/artwork/badge/get-it-on.png"
alt="Stáhnout s F-Droid"
height="80">](https://f-droid.org/packages/io.github.wulkanowy/)
[<img src="https://i.imgur.com/baTGiDP.png"
alt="Objevuj v AppGallery"
height="80">](https://appgallery.cloud.huawei.com/ag/n/app/C101440411?channelId=Badge&id=1b3f7fbb700849a9be0dba6b520b2282&s=EB1D3BF9ED9D1564D869B7B94B18016D3CABFCA5AEFB8E29F675FA04E0DC131D&detailType=0&v=)
Můžete si také stáhnout [vývojovou verzi](https://wulkanowy.github.io/#download), která zahrnuje nové funkce připravované pro příští vydání
## Postaveno s pomocí
* [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)
## Spolupráce
Přispějte do projektu vytvořením PR nebo odesláním issue na GitHub.
Pro zájemce o překlad aplikace do různých jazyků poskytujeme Crowdin:
https://crowdin.com/project/wulkanowy2
## Licence
Tento projekt je licencován pod licencí Apache License 2.0 - podrobnosti v souboru [LICENSE](LICENSE)

73
README.de.md Normal file
View file

@ -0,0 +1,73 @@
[Česká verze](README.cs.md) / Deutsche Version / [English version](README.en.md) / [Polska wersja](README.md) / [Slovenská verzia](README.sk.md)
# Wulkanowy
[![GitHub Workflow Status](https://img.shields.io/github/workflow/status/wulkanowy/wulkanowy/Tests/develop?style=flat-square)](https://github.com/wulkanowy/wulkanowy/actions)
[![Codecov](https://img.shields.io/codecov/c/github/wulkanowy/wulkanowy/master.svg?style=flat-square)](https://codecov.io/gh/wulkanowy/wulkanowy)
[![Discord](https://img.shields.io/discord/390889354199040011.svg?style=flat-square)](https://discord.gg/vccAQBr)
[![F-Droid](https://img.shields.io/f-droid/v/io.github.wulkanowy.svg?style=flat-square)](https://f-droid.org/packages/io.github.wulkanowy/)
[![Last release](https://img.shields.io/github/release/wulkanowy/wulkanowy.svg?logo=github&style=flat-square)](https://github.com/wulkanowy/wulkanowy/releases)
[![Crowdin](https://badges.crowdin.net/wulkanowy2/localized.svg)](https://translate.wulkanowy.net.pl)
Inoffizieller Android VULCAN UONET+ Registrierungsclient für Schüler und ihre Eltern
## Merkmale
* Einloggen mit E-Mail und Passwort
* Funktionen von der Registerwebsite:
* Noten
* Notenstatistik
* Anwesenheit
* Prozentsatz der Anwesenheit
* Prüfungen
* Stundenplan
* Unterricht abgeschlossen
* Nachrichten
* Hausaufgaben
* Anmerkungen
* Glückszahl
* Zusätzliche Lektionen
* Schulkonferenzen
* Schüler- und Schulinformationen
* Berechnung des Durchschnitts unabhängig von den Präferenzen der Schule
* Benachrichtigungen, z. B. über eine neue Note
* Unterstützung für mehrere Konten mit der Möglichkeit, den Namen des Schülers zu ändern
* dunkles und schwarzes (AMOLED) Thema
* Offline-Modus
* keine Werbung
## Herunterladen
Die aktuelle Version können Sie von der Google Play, F-Droid oder Huawei AppGallery store herunterladen
[<img src="https://play.google.com/intl/en_us/badges/images/generic/en_badge_web_generic.png"
alt="Get it on Google Play"
height="80">](https://play.google.com/store/apps/details?id=io.github.wulkanowy)
[<img src="https://fdroid.gitlab.io/artwork/badge/get-it-on.png"
alt="Get it on F-Droid"
height="80">](https://f-droid.org/packages/io.github.wulkanowy/)
[<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=)
Sie können auch eine [Entwicklungsversion herunterladen](https://wulkanowy.github.io/#download) die beinhaltet neue Funktionen, die für die nächste Version vorbereitet werden
## Gebaut mit
* [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)
## Beitragen
Bitte tragen Sie zum Projekt bei, indem Sie entweder eine PR erstellen oder ein Issue auf GitHub einreichen.
Für Personen, die daran interessiert sind, die Anwendung in verschiedene Sprachen zu übersetzen, bieten wir Crowdin
https://crowdin.com/project/wulkanowy2
## Lizenz
Dieses Projekt ist unter der Apache License 2.0 lizenziert - siehe die [LIZENZ](LICENSE) Datei für Details

View file

@ -1,4 +1,4 @@
[Polska wersja README](README.md)
[Česká verze](README.cs.md) / [Deutsche Version](README.de.md) / English version / [Polska wersja](README.md) / [Slovenská verzia](README.sk.md)
# Wulkanowy
@ -7,6 +7,7 @@
[![Discord](https://img.shields.io/discord/390889354199040011.svg?style=flat-square)](https://discord.gg/vccAQBr)
[![F-Droid](https://img.shields.io/f-droid/v/io.github.wulkanowy.svg?style=flat-square)](https://f-droid.org/packages/io.github.wulkanowy/)
[![Last release](https://img.shields.io/github/release/wulkanowy/wulkanowy.svg?logo=github&style=flat-square)](https://github.com/wulkanowy/wulkanowy/releases)
[![Crowdin](https://badges.crowdin.net/wulkanowy2/localized.svg)](https://translate.wulkanowy.net.pl)
Unofficial android VULCAN UONET+ register client for both students and their parents

View file

@ -1,4 +1,4 @@
[English version of README](README.en.md)
[Česká verze](README.cs.md) / [Deutsche Version](README.de.md) / [English version](README.en.md) / Polska wersja / [Slovenská verzia](README.sk.md)
# Wulkanowy
@ -7,6 +7,7 @@
[![Discord](https://img.shields.io/discord/390889354199040011.svg?style=flat-square)](https://discord.gg/vccAQBr)
[![F-Droid](https://img.shields.io/f-droid/v/io.github.wulkanowy.svg?style=flat-square)](https://f-droid.org/packages/io.github.wulkanowy/)
[![Last release](https://img.shields.io/github/release/wulkanowy/wulkanowy.svg?logo=github&style=flat-square)](https://github.com/wulkanowy/wulkanowy/releases)
[![Crowdin](https://badges.crowdin.net/wulkanowy2/localized.svg)](https://translate.wulkanowy.net.pl)
Nieoficjalny klient dziennika VULCAN UONET+ dla ucznia i rodzica

73
README.sk.md Normal file
View file

@ -0,0 +1,73 @@
[Česká verze](README.cs.md) / [Deutsche Version](README.de.md) / [English version](README.en.md) / [Polska wersja](README.md) / Slovenská verzia
# Wulkanowy
[![GitHub Workflow Status](https://img.shields.io/github/workflow/status/wulkanowy/wulkanowy/Tests/develop?style=flat-square)](https://github.com/wulkanowy/wulkanowy/actions)
[![Codecov](https://img.shields.io/codecov/c/github/wulkanowy/wulkanowy/master.svg?style=flat-square)](https://codecov.io/gh/wulkanowy/wulkanowy)
[![Discord](https://img.shields.io/discord/390889354199040011.svg?style=flat-square)](https://discord.gg/vccAQBr)
[![F-Droid](https://img.shields.io/f-droid/v/io.github.wulkanowy.svg?style=flat-square)](https://f-droid.org/packages/io.github.wulkanowy/)
[![Last release](https://img.shields.io/github/release/wulkanowy/wulkanowy.svg?logo=github&style=flat-square)](https://github.com/wulkanowy/wulkanowy/releases)
[![Crowdin](https://badges.crowdin.net/wulkanowy2/localized.svg)](https://translate.wulkanowy.net.pl)
Neoficiálny klient denníka VULCAN UONET+ pre žiaka a rodičov
## Funkcie
* prihlásenie pomocou emailu a hesla
* funkcie z webovej stránky denníka:
* známky
* štatistiky známok
* frekvencia
* percento frekvencie
* skúšky
* plán lekcie
* dokončené lekcie
* správy
* domáce úlohy
* poznámky
* šťastné číslo
* ďalšie lekcie
* školské stretnutie
* informácie o žiakovi a škole
* výpočet priemeru nezávisle od preferencií školy
* upozornenia, napr. o nových známkach
* podpora viacerých účtov s možnosťou premenovania žiakov
* tmavý a čierny (AMOLED) motív
* offline režim
* žiadne reklamy
## Stiahnuť
Aktuálnu verziu si môžete stiahnuť z Google Play, F-Droid alebo Huawei AppGallery
[<img src="https://play.google.com/intl/sk/badges/images/generic/sk_badge_web_generic.png"
alt="Nyní na Google Play"
height="80">](https://play.google.com/store/apps/details?id=io.github.wulkanowy)
[<img src="https://fdroid.gitlab.io/artwork/badge/get-it-on.png"
alt="Stiahnuť s F-Droid"
height="80">](https://f-droid.org/packages/io.github.wulkanowy/)
[<img src="https://i.imgur.com/sX8UyAw.png"
alt="Objavíte v AppGallery"
height="80">](https://appgallery.cloud.huawei.com/ag/n/app/C101440411?channelId=Badge&id=1b3f7fbb700849a9be0dba6b520b2282&s=EB1D3BF9ED9D1564D869B7B94B18016D3CABFCA5AEFB8E29F675FA04E0DC131D&detailType=0&v=)
Môžete si tiež stiahnuť [vývojovú verziu](https://wulkanowy.github.io/#download), ktorá zahrňuje nové funkcie pripravované pre budúce vydanie
## Postavené s pomocou
* [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)
## Spolupráca
Prispejte do projektu vytvorením PR alebo odoslaním issue na GitHub.
Pre záujemcov o preklad aplikácie do rôznych jazykov poskytujeme Crowdin:
https://crowdin.com/project/wulkanowy2
## Licencia
Tento projekt je licencovaný pod licenciou Apache License 2.0 - podrobnosti v súbore [LICENSE](LICENSE)

View file

@ -1,5 +1,6 @@
apply plugin: 'com.android.application'
apply plugin: 'kotlin-android'
apply plugin: 'kotlinx-serialization'
apply plugin: 'kotlin-parcelize'
apply plugin: 'kotlin-kapt'
apply plugin: 'dagger.hilt.android.plugin'
@ -14,32 +15,41 @@ apply from: 'sonarqube.gradle'
apply from: 'hooks.gradle'
android {
compileSdkVersion 30
namespace 'io.github.wulkanowy'
compileSdkVersion 32
defaultConfig {
applicationId "io.github.wulkanowy"
testApplicationId "io.github.tests.wulkanowy"
minSdkVersion 21
targetSdkVersion 30
versionCode 95
versionName "1.2.2"
targetSdkVersion 32
versionCode 115
versionName "1.8.0"
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")
firebase_enabled: project.hasProperty("enableFirebase"),
admob_project_id: ""
]
javaCompileOptions {
annotationProcessorOptions {
arguments += [
"room.schemaLocation": "$projectDir/schemas".toString(),
"room.incremental" : "true"
"room.schemaLocation": "$projectDir/schemas".toString(),
"room.incremental" : "true"
]
}
}
buildConfigField "String", "SINGLE_SUPPORT_AD_ID", "null"
buildConfigField "String", "DASHBOARD_TILE_AD_ID", "null"
if (System.env.SET_BUILD_TIMESTAMP) {
buildConfigField "long", "BUILD_TIMESTAMP", String.valueOf(System.currentTimeMillis())
} else {
buildConfigField "long", "BUILD_TIMESTAMP", "1486235849000"
}
}
sourceSets {
@ -62,12 +72,16 @@ android {
shrinkResources true
proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro'
signingConfig signingConfigs.release
buildConfigField "String", "MESSAGES_BASE_URL", "\"https://messages.wulkanowy.net.pl\""
}
debug {
resValue "string", "app_name", "Wulkanowy DEV " + defaultConfig.versionCode
minifyEnabled false
shrinkResources false
resValue "string", "app_name", "Wulkanowy DEV"
applicationIdSuffix ".dev"
versionNameSuffix "-dev"
ext.enableCrashlytics = project.hasProperty("enableFirebase")
buildConfigField "String", "MESSAGES_BASE_URL", "\"https://messages.wulkanowy.net.pl\""
}
}
@ -76,32 +90,44 @@ android {
productFlavors {
hms {
dimension "platform"
manifestPlaceholders = [
install_channel: "AppGallery"
]
manifestPlaceholders = [install_channel: "AppGallery"]
}
play {
dimension "platform"
manifestPlaceholders = [
install_channel: "Google Play"
install_channel : "Google Play",
admob_project_id: System.getenv("ADMOB_PROJECT_ID") ?: "ca-app-pub-3940256099942544~3347511713"
]
buildConfigField "String", "SINGLE_SUPPORT_AD_ID", "\"${System.getenv("SINGLE_SUPPORT_AD_ID") ?: "ca-app-pub-3940256099942544/5354046379"}\""
buildConfigField "String", "DASHBOARD_TILE_AD_ID", "\"${System.getenv("DASHBOARD_TILE_AD_ID") ?: "ca-app-pub-3940256099942544/6300978111"}\""
}
fdroid {
dimension "platform"
manifestPlaceholders = [
install_channel: "F-Droid"
]
manifestPlaceholders = [install_channel: "F-Droid"]
}
}
playConfigs {
play { enabled.set(true) }
}
buildFeatures {
viewBinding true
}
bundle {
language {
enableSplit = false
}
}
testOptions.unitTests {
includeAndroidResources = true
// workaround HMS test errors https://github.com/robolectric/robolectric/issues/2750
all { jvmArgs '-noverify' }
}
compileOptions {
@ -112,12 +138,14 @@ android {
kotlinOptions {
jvmTarget = "11"
freeCompilerArgs += ["-Xopt-in=kotlin.RequiresOptIn", "-Xjvm-default=all"]
freeCompilerArgs += ["-opt-in=kotlin.RequiresOptIn", "-Xjvm-default=all"]
}
packagingOptions {
exclude 'META-INF/library_release.kotlin_module'
exclude 'META-INF/library-core_release.kotlin_module'
resources {
excludes += ['META-INF/library_release.kotlin_module',
'META-INF/library-core_release.kotlin_module']
}
}
aboutLibraries {
@ -130,11 +158,12 @@ kapt {
}
play {
serviceAccountEmail = System.getenv("PLAY_SERVICE_ACCOUNT_EMAIL") ?: "jan@fakelog.cf"
serviceAccountCredentials = file('key.p12')
defaultToAppBundles = false
track = 'production'
updatePriority = 3
releaseStatus = com.github.triplet.gradle.androidpublisher.ReleaseStatus.IN_PROGRESS
userFraction = 0.25d
updatePriority = 4
enabled.set(false)
}
huaweiPublish {
@ -148,43 +177,44 @@ huaweiPublish {
}
ext {
work_manager = "2.6.0"
work_manager = "2.7.1"
android_hilt = "1.0.0"
room = "2.3.0"
room = "2.4.3"
chucker = "3.5.2"
mockk = "1.12.0"
moshi = "1.12.0"
mockk = "1.13.2"
coroutines = "1.6.4"
}
dependencies {
implementation "io.github.wulkanowy:sdk:1.2.2"
implementation "io.github.wulkanowy:sdk:1.8.0"
coreLibraryDesugaring 'com.android.tools:desugar_jdk_libs:1.1.5'
coreLibraryDesugaring 'com.android.tools:desugar_jdk_libs:1.1.8'
implementation "org.jetbrains.kotlinx:kotlinx-coroutines-android:1.5.2"
implementation "org.jetbrains.kotlinx:kotlinx-serialization-json:1.4.1"
implementation "org.jetbrains.kotlinx:kotlinx-coroutines-android:$coroutines"
implementation "androidx.core:core-ktx:1.6.0"
implementation "androidx.activity:activity-ktx:1.3.1"
implementation "androidx.appcompat:appcompat:1.3.1"
implementation "androidx.appcompat:appcompat-resources:1.3.1"
implementation "androidx.fragment:fragment-ktx:1.3.6"
implementation "androidx.annotation:annotation:1.2.0"
implementation "androidx.core:core-ktx:1.8.0"
implementation 'androidx.core:core-splashscreen:1.0.0'
implementation "androidx.activity:activity-ktx:1.5.1"
implementation "androidx.appcompat:appcompat:1.5.1"
implementation "androidx.fragment:fragment-ktx:1.5.4"
implementation "androidx.annotation:annotation:1.5.0"
implementation "androidx.preference:preference-ktx:1.1.1"
implementation "androidx.preference:preference-ktx:1.2.0"
implementation "androidx.recyclerview:recyclerview:1.2.1"
implementation "androidx.viewpager:viewpager:1.0.0"
implementation "androidx.viewpager2:viewpager2:1.1.0-beta01"
implementation "androidx.swiperefreshlayout:swiperefreshlayout:1.1.0"
implementation "androidx.constraintlayout:constraintlayout:2.1.0"
implementation "androidx.coordinatorlayout:coordinatorlayout:1.1.0"
implementation "com.google.android.material:material:1.4.0"
implementation "androidx.constraintlayout:constraintlayout:2.1.4"
implementation "androidx.coordinatorlayout:coordinatorlayout:1.2.0"
implementation "com.google.android.material:material:1.7.0"
implementation "com.github.wulkanowy:material-chips-input:2.3.1"
implementation "com.github.PhilJay:MPAndroidChart:v3.1.0"
implementation 'com.github.lopspower:CircularImageView:4.2.0'
implementation 'com.github.lopspower:CircularImageView:4.3.0'
implementation "androidx.work:work-runtime-ktx:$work_manager"
playImplementation "androidx.work:work-gcm:$work_manager"
implementation "androidx.lifecycle:lifecycle-livedata-ktx:2.3.1"
implementation "androidx.lifecycle:lifecycle-livedata-ktx:2.5.1"
implementation "androidx.room:room-runtime:$room"
implementation "androidx.room:room-ktx:$room"
@ -198,43 +228,45 @@ dependencies {
implementation 'com.github.ncapdevi:FragNav:3.3.0'
implementation "com.github.YarikSOffice:lingver:1.3.0"
implementation "com.squareup.moshi:moshi:$moshi"
implementation "com.squareup.moshi:moshi-adapters:$moshi"
kapt "com.squareup.moshi:moshi-kotlin-codegen:$moshi"
implementation 'com.squareup.retrofit2:retrofit:2.9.0'
implementation "com.jakewharton.retrofit:retrofit2-kotlinx-serialization-converter:0.8.0"
implementation "com.squareup.okhttp3:logging-interceptor:4.10.0"
implementation "com.jakewharton.timber:timber:5.0.1"
implementation "at.favre.lib:slf4j-timber:1.0.1"
implementation 'com.github.bastienpaulfr:Treessence:1.0.4'
implementation 'com.github.bastienpaulfr:Treessence:1.0.5'
implementation "com.mikepenz:aboutlibraries-core:$about_libraries"
implementation "io.coil-kt:coil:1.3.2"
implementation "io.coil-kt:coil:2.2.2"
implementation "io.github.wulkanowy:AppKillerManager:3.0.0"
implementation 'me.xdrop:fuzzywuzzy:1.3.1'
implementation 'com.fredporciuncula:flow-preferences:1.5.0'
implementation 'me.xdrop:fuzzywuzzy:1.4.0'
implementation 'com.fredporciuncula:flow-preferences:1.8.0'
playImplementation platform('com.google.firebase:firebase-bom:28.4.0')
playImplementation platform('com.google.firebase:firebase-bom:31.0.3')
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:1.10.1'
playImplementation 'com.google.android.play:core:1.10.3'
playImplementation 'com.google.android.play:core-ktx:1.8.1'
playImplementation 'com.google.android.gms:play-services-ads:21.3.0'
hmsImplementation 'com.huawei.hms:hianalytics:6.2.0.301'
hmsImplementation 'com.huawei.agconnect:agconnect-crash:1.6.0.300'
hmsImplementation 'com.huawei.hms:hianalytics:6.8.0.300'
hmsImplementation 'com.huawei.agconnect:agconnect-crash:1.7.3.300'
releaseImplementation "com.github.ChuckerTeam.Chucker:library-no-op:$chucker"
debugImplementation "com.github.ChuckerTeam.Chucker:library:$chucker"
debugImplementation 'com.github.amitshekhariitbhu.Android-Debug-Database:debug-db:v1.0.6'
debugImplementation 'com.github.amitshekhariitbhu.Android-Debug-Database:debug-db:1.0.6'
debugImplementation 'com.github.haroldadmin:WhatTheStack:1.0.0-alpha04'
testImplementation "junit:junit:4.13.2"
testImplementation "io.mockk:mockk:$mockk"
testImplementation 'org.jetbrains.kotlinx:kotlinx-coroutines-test:1.5.2'
testImplementation "org.jetbrains.kotlinx:kotlinx-coroutines-test:$coroutines"
testImplementation "org.jetbrains.kotlin:kotlin-test:$kotlin_version"
testImplementation 'org.robolectric:robolectric:4.6.1'
testImplementation "androidx.test:runner:1.4.0"
testImplementation "androidx.test.ext:junit:1.1.3"
testImplementation "androidx.test:core:1.4.0"
testImplementation 'org.robolectric:robolectric:4.9'
testImplementation "androidx.test:runner:1.5.1"
testImplementation "androidx.test.ext:junit:1.1.4"
testImplementation "androidx.test:core:1.5.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"

Binary file not shown.

File diff suppressed because it is too large Load diff

File diff suppressed because it is too large Load diff

File diff suppressed because it is too large Load diff

File diff suppressed because it is too large Load diff

File diff suppressed because it is too large Load diff

File diff suppressed because it is too large Load diff

File diff suppressed because it is too large Load diff

File diff suppressed because it is too large Load diff

File diff suppressed because it is too large Load diff

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,33 +1,92 @@
{
"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":""
},
"agcgw": {
"backurl": "connect-dre.hispace.hicloud.com",
"url": "connect-dre.dbankcloud.cn",
"websocketbackurl": "connect-ws-dre.hispace.dbankcloud.com",
"websocketurl": "connect-ws-dre.hispace.dbankcloud.cn"
},
"agcgw_all": {
"CN": "connect-drcn.dbankcloud.cn",
"CN_back": "connect-drcn.hispace.hicloud.com",
"DE": "connect-dre.dbankcloud.cn",
"DE_back": "connect-dre.hispace.hicloud.com",
"RU": "connect-drru.hispace.dbankcloud.ru",
"RU_back": "connect-drru.hispace.dbankcloud.cn",
"SG": "connect-dra.dbankcloud.cn",
"SG_back": "connect-dra.hispace.hicloud.com"
},
"websocketgw_all": {
"CN": "connect-ws-drcn.hispace.dbankcloud.cn",
"CN_back": "connect-ws-drcn.hispace.dbankcloud.com",
"DE": "connect-ws-dre.hispace.dbankcloud.cn",
"DE_back": "connect-ws-dre.hispace.dbankcloud.com",
"RU": "connect-ws-drru.hispace.dbankcloud.ru",
"RU_back": "connect-ws-drru.hispace.dbankcloud.cn",
"SG": "connect-ws-dra.hispace.dbankcloud.cn",
"SG_back": "connect-ws-dra.hispace.dbankcloud.com"
},
"client": {
"cp_id": "890048000024105546",
"product_id": "736430079244736562",
"client_id": "514530959291319360",
"client_secret": "C42522DBF17D3D4BBE9D9C1783A54484B7E6844B388B7A67502D36A633A4186B",
"project_id": "736430079244736562",
"app_id": "106552551",
"api_key": "CgB6e3x9BUNiq+r8ebCHNojjjYsMT4pJSjjNDOkm9owtBb6rVI6LjnASoZBRxbjjhObcrV5gANo99fI/eKZDTbWS",
"package_name": "io.github.wulkanowy.dev"
},
"oauth_client": {
"client_id": "106552551",
"client_type": 1
},
"app_info": {
"app_id": "106552551",
"package_name": "io.github.wulkanowy.dev"
},
"service": {
"analytics": {
"collector_url": "datacollector-dre.dt.hicloud.com,datacollector-dre.dt.dbankcloud.cn",
"collector_url_ru": "datacollector-drru.dt.dbankcloud.ru,datacollector-drru.dt.hicloud.com",
"collector_url_sg": "datacollector-dra.dt.hicloud.com,datacollector-dra.dt.dbankcloud.cn",
"collector_url_de": "datacollector-dre.dt.hicloud.com,datacollector-dre.dt.dbankcloud.cn",
"collector_url_cn": "datacollector-drcn.dt.hicloud.com,datacollector-drcn.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"
"cloudstorage": {
"storage_url_sg_back": "https://agc-storage-dra.cloud.huawei.asia",
"storage_url_ru_back": "https://agc-storage-drru.cloud.huawei.ru",
"storage_url_ru": "https://agc-storage-drru.cloud.huawei.ru",
"storage_url_de_back": "https://agc-storage-dre.cloud.huawei.eu",
"storage_url_de": "https://ops-dre.agcstorage.link",
"storage_url": "https://agc-storage-drcn.platform.dbankcloud.cn",
"storage_url_sg": "https://ops-dra.agcstorage.link",
"storage_url_cn_back": "https://agc-storage-drcn.cloud.huawei.com.cn",
"storage_url_cn": "https://agc-storage-drcn.platform.dbankcloud.cn"
},
"ml": {
"mlservice_url": "ml-api-dre.ai.dbankcloud.com,ml-api-dre.ai.dbankcloud.cn"
}
},
"region": "DE",
"configuration_version": "3.0",
"appInfos": [
{
"package_name": "io.github.wulkanowy.dev",
"client": {
"app_id": "106552551"
},
"app_info": {
"package_name": "io.github.wulkanowy.dev",
"app_id": "106552551"
},
"oauth_client": {
"client_type": 1,
"client_id": "106552551"
}
}
]
}

View file

@ -0,0 +1,28 @@
package io.github.wulkanowy.utils
import android.content.Context
import android.view.View
import dagger.hilt.android.qualifiers.ApplicationContext
import io.github.wulkanowy.data.repositories.PreferencesRepository
import io.github.wulkanowy.ui.modules.dashboard.DashboardItem
import javax.inject.Inject
@Suppress("unused")
class AdsHelper @Inject constructor(
@ApplicationContext private val context: Context,
private val preferencesRepository: PreferencesRepository
) {
fun initialize() {
preferencesRepository.isAdsEnabled = false
preferencesRepository.isAgreeToProcessData = false
preferencesRepository.selectedDashboardTiles -= DashboardItem.Tile.ADS
}
@Suppress("RedundantSuspendModifier", "UNUSED_PARAMETER")
suspend fun getDashboardTileAdBanner(width: Int): AdBanner {
throw IllegalStateException("Can't get ad banner (F-droid)")
}
}
data class AdBanner(val view: View)

View file

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

View file

@ -6,6 +6,7 @@ import io.github.wulkanowy.ui.modules.main.MainActivity
import javax.inject.Singleton
import javax.inject.Inject
@Suppress("UNUSED_PARAMETER", "unused")
@Singleton
class InAppReviewHelper @Inject constructor(
@ApplicationContext private val context: Context

View file

@ -0,0 +1,28 @@
package io.github.wulkanowy.utils
import android.content.Context
import android.view.View
import dagger.hilt.android.qualifiers.ApplicationContext
import io.github.wulkanowy.data.repositories.PreferencesRepository
import io.github.wulkanowy.ui.modules.dashboard.DashboardItem
import javax.inject.Inject
@Suppress("unused")
class AdsHelper @Inject constructor(
@ApplicationContext private val context: Context,
private val preferencesRepository: PreferencesRepository
) {
fun initialize() {
preferencesRepository.isAdsEnabled = false
preferencesRepository.isAgreeToProcessData = false
preferencesRepository.selectedDashboardTiles -= DashboardItem.Tile.ADS
}
@Suppress("RedundantSuspendModifier", "UNUSED_PARAMETER")
suspend fun getDashboardTileAdBanner(width: Int): AdBanner {
throw IllegalStateException("Can't get ad banner (HMS)")
}
}
data class AdBanner(val view: View)

View file

@ -3,26 +3,38 @@ package io.github.wulkanowy.utils
import android.app.Activity
import android.content.Context
import android.os.Bundle
import com.huawei.agconnect.crash.AGConnectCrash
import com.huawei.hms.analytics.HiAnalytics
import dagger.hilt.android.qualifiers.ApplicationContext
import io.github.wulkanowy.data.repositories.PreferencesRepository
import javax.inject.Inject
import javax.inject.Singleton
@Singleton
class AnalyticsHelper @Inject constructor(
@ApplicationContext private val context: Context
@ApplicationContext private val context: Context,
preferencesRepository: PreferencesRepository,
appInfo: AppInfo,
) {
private val analytics by lazy { HiAnalytics.getInstance(context) }
private val connectCrash by lazy { AGConnectCrash.getInstance() }
init {
if (!appInfo.isDebug) {
connectCrash.setUserId(preferencesRepository.installationId)
}
}
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)
params.forEach { (key, value) ->
if (value == null) return@forEach
when (value) {
is String -> putString(key, value)
is Int -> putInt(key, value)
is Boolean -> putBoolean(key, value)
}
}
analytics.onEvent(name, this)

View file

@ -3,6 +3,7 @@ package io.github.wulkanowy.utils
import android.util.Log
import com.huawei.agconnect.crash.AGConnectCrash
import fr.bipi.tressence.base.FormatterPriorityTree
import fr.bipi.tressence.common.StackTraceRecorder
class CrashLogTree : FormatterPriorityTree(Log.VERBOSE) {
@ -22,16 +23,10 @@ class CrashLogExceptionTree : FormatterPriorityTree(Log.ERROR, ExceptionFilter)
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

@ -7,6 +7,7 @@ import javax.inject.Inject
import javax.inject.Singleton
@Singleton
@Suppress("UNUSED_PARAMETER", "unused")
class InAppReviewHelper @Inject constructor(
@ApplicationContext private val context: Context
) {

View file

@ -1,7 +1,6 @@
<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
package="io.github.wulkanowy"
android:installLocation="internalOnly">
<uses-permission android:name="android.permission.INTERNET" />
@ -9,6 +8,7 @@
<uses-permission android:name="android.permission.WAKE_LOCK" />
<uses-permission android:name="android.permission.RECEIVE_BOOT_COMPLETED" />
<uses-permission android:name="android.permission.VIBRATE" />
<uses-permission android:name="android.permission.SCHEDULE_EXACT_ALARM"/>
<queries>
<intent>
@ -38,13 +38,14 @@
android:allowBackup="false"
android:icon="@mipmap/ic_launcher"
android:label="@string/app_name"
android:networkSecurityConfig="@xml/network_security_config"
android:roundIcon="@mipmap/ic_launcher_round"
android:supportsRtl="false"
android:theme="@style/WulkanowyTheme"
android:usesCleartextTraffic="true"
tools:ignore="GoogleAppIndexingWarning,UnusedAttribute">
<activity
android:name=".ui.modules.splash.SplashActivity"
android:exported="true"
android:screenOrientation="portrait"
android:theme="@style/WulkanowyTheme.SplashScreen"
tools:ignore="LockedOrientationActivity">
@ -74,6 +75,7 @@
<activity
android:name=".ui.modules.timetablewidget.TimetableWidgetConfigureActivity"
android:excludeFromRecents="true"
android:exported="true"
android:noHistory="true"
android:theme="@style/WulkanowyTheme.WidgetAccountSwitcher">
<intent-filter>
@ -83,6 +85,7 @@
<activity
android:name=".ui.modules.luckynumberwidget.LuckyNumberWidgetConfigureActivity"
android:excludeFromRecents="true"
android:exported="true"
android:noHistory="true"
android:theme="@style/WulkanowyTheme.WidgetAccountSwitcher">
<intent-filter>
@ -93,6 +96,22 @@
<service
android:name=".services.widgets.TimetableWidgetService"
android:permission="android.permission.BIND_REMOTEVIEWS" />
<service
android:name=".services.piggyback.VulcanNotificationListenerService"
android:exported="true"
android:permission="android.permission.BIND_NOTIFICATION_LISTENER_SERVICE">
<intent-filter>
<action android:name="android.service.notification.NotificationListenerService" />
</intent-filter>
</service>
<service
android:name=".services.messaging.AppMessagingService"
android:exported="false"
tools:ignore="MissingClass">
<intent-filter>
<action android:name="com.google.firebase.MESSAGING_EVENT" />
</intent-filter>
</service>
<receiver
android:name=".ui.modules.timetablewidget.TimetableWidgetProvider"
@ -107,6 +126,7 @@
</receiver>
<receiver
android:name=".ui.modules.luckynumberwidget.LuckyNumberWidgetProvider"
android:exported="true"
android:label="@string/lucky_number_title">
<intent-filter>
<action android:name="android.appwidget.action.APPWIDGET_UPDATE" />
@ -132,44 +152,44 @@
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
android:name="com.google.firebase.provider.FirebaseInitProvider"
android:authorities="${applicationId}.firebaseinitprovider"
android:enabled="${firebase_enabled}"
android:exported="false" />
android:exported="false"
tools:ignore="MissingClass" />
<meta-data
android:name="install_channel"
android:value="${install_channel}" />
<meta-data
android:name="firebase_analytics_collection_enabled"
android:value="${firebase_enabled}" />
<meta-data
android:name="google_analytics_adid_collection_enabled"
android:value="${firebase_enabled}" />
<meta-data
android:name="firebase_crashlytics_collection_enabled"
android:value="${firebase_enabled}" />
<meta-data
android:name="firebase_messaging_auto_init_enabled"
android:value="${firebase_enabled}" />
<meta-data
android:name="firebase_inapp_messaging_auto_data_collection_enabled"
android:value="${firebase_enabled}" />
<meta-data
android:name="com.google.firebase.messaging.default_notification_icon"
android:resource="@drawable/ic_stat_all" />
<meta-data
android:name="com.google.firebase.messaging.default_notification_channel_id"
android:value="push_channel" />
<meta-data
android:name="com.google.android.gms.ads.APPLICATION_ID"
android:value="${admob_project_id}" />
<meta-data
android:name="com.google.android.gms.ads.DELAY_APP_MEASUREMENT_INIT"
android:value="true" />
</application>
</manifest>

View file

@ -1,12 +1,7 @@
package io.github.wulkanowy
import android.annotation.SuppressLint
import android.app.Application
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 android.util.Log.*
import androidx.hilt.work.HiltWorkerFactory
import androidx.work.Configuration
import com.yariksoffice.lingver.Lingver
@ -14,12 +9,7 @@ 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.CrashLogExceptionTree
import io.github.wulkanowy.utils.CrashLogTree
import io.github.wulkanowy.utils.DebugLogTree
import io.github.wulkanowy.utils.*
import timber.log.Timber
import javax.inject.Inject
@ -41,14 +31,15 @@ class WulkanowyApp : Application(), Configuration.Provider {
@Inject
lateinit var analyticsHelper: AnalyticsHelper
@SuppressLint("UnsafeOptInUsageWarning")
@Inject
lateinit var adsHelper: AdsHelper
override fun onCreate() {
super.onCreate()
FragmentManager.enableNewStateManager(false)
initializeAppLanguage()
themeManager.applyDefaultTheme()
adsHelper.initialize()
initLogging()
fixWebViewLocale()
}
private fun initLogging() {
@ -80,15 +71,6 @@ class WulkanowyApp : Application(), Configuration.Provider {
}
}
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: Throwable) {
//Ignore exceptions
}
}
override fun getWorkManagerConfiguration() = Configuration.Builder()
.setWorkerFactory(workerFactory)
.setMinimumLoggingLevel(if (appInfo.isDebug) VERBOSE else INFO)

View file

@ -2,62 +2,99 @@ package io.github.wulkanowy.data
import android.content.Context
import android.content.SharedPreferences
import android.content.res.AssetManager
import android.content.res.Resources
import androidx.preference.PreferenceManager
import com.chuckerteam.chucker.api.ChuckerCollector
import com.chuckerteam.chucker.api.ChuckerInterceptor
import com.chuckerteam.chucker.api.RetentionManager
import com.squareup.moshi.Moshi
import com.fredporciuncula.flow.preferences.FlowSharedPreferences
import com.jakewharton.retrofit2.converter.kotlinx.serialization.asConverterFactory
import dagger.Module
import dagger.Provides
import dagger.hilt.InstallIn
import dagger.hilt.android.qualifiers.ApplicationContext
import dagger.hilt.components.SingletonComponent
import io.github.wulkanowy.data.api.AdminMessageService
import io.github.wulkanowy.data.db.AppDatabase
import io.github.wulkanowy.data.db.SharedPrefProvider
import io.github.wulkanowy.data.repositories.PreferencesRepository
import io.github.wulkanowy.sdk.Sdk
import io.github.wulkanowy.utils.AppInfo
import kotlinx.coroutines.ExperimentalCoroutinesApi
import kotlinx.serialization.ExperimentalSerializationApi
import kotlinx.serialization.json.Json
import okhttp3.MediaType.Companion.toMediaType
import okhttp3.OkHttpClient
import okhttp3.logging.HttpLoggingInterceptor
import retrofit2.Retrofit
import retrofit2.create
import timber.log.Timber
import java.util.concurrent.TimeUnit
import javax.inject.Singleton
@Module
@InstallIn(SingletonComponent::class)
internal class RepositoryModule {
internal class DataModule {
@Singleton
@Provides
fun provideSdk(chuckerCollector: ChuckerCollector, @ApplicationContext context: Context): Sdk {
return Sdk().apply {
fun provideSdk(chuckerInterceptor: ChuckerInterceptor) =
Sdk().apply {
androidVersion = android.os.Build.VERSION.RELEASE
buildTag = android.os.Build.MODEL
setSimpleHttpLogger { Timber.d(it) }
// for debug only
addInterceptor(
ChuckerInterceptor.Builder(context)
.collector(chuckerCollector)
.alwaysReadResponseBody(true)
.build(), network = true
)
addInterceptor(chuckerInterceptor, network = true)
}
}
@Singleton
@Provides
fun provideChuckerCollector(
@ApplicationContext context: Context,
prefRepository: PreferencesRepository
): ChuckerCollector {
return ChuckerCollector(
context = context,
showNotification = prefRepository.isDebugNotificationEnable,
retentionPeriod = RetentionManager.Period.ONE_HOUR
)
}
) = ChuckerCollector(
context = context,
showNotification = prefRepository.isDebugNotificationEnable,
retentionPeriod = RetentionManager.Period.ONE_HOUR
)
@Singleton
@Provides
fun provideChuckerInterceptor(
@ApplicationContext context: Context,
chuckerCollector: ChuckerCollector
) = ChuckerInterceptor.Builder(context)
.collector(chuckerCollector)
.alwaysReadResponseBody(true)
.build()
@Singleton
@Provides
fun provideOkHttpClient(chuckerInterceptor: ChuckerInterceptor): OkHttpClient =
OkHttpClient.Builder()
.addNetworkInterceptor(chuckerInterceptor)
.addInterceptor(HttpLoggingInterceptor().apply {
level = HttpLoggingInterceptor.Level.BASIC
})
.connectTimeout(30, TimeUnit.SECONDS)
.readTimeout(30, TimeUnit.SECONDS)
.build()
@OptIn(ExperimentalSerializationApi::class)
@Singleton
@Provides
fun provideRetrofit(
okHttpClient: OkHttpClient,
json: Json,
appInfo: AppInfo
): Retrofit = Retrofit.Builder()
.baseUrl(appInfo.messagesBaseUrl)
.client(okHttpClient)
.addConverterFactory(json.asConverterFactory("application/json".toMediaType()))
.build()
@Singleton
@Provides
fun provideAdminMessageService(retrofit: Retrofit): AdminMessageService = retrofit.create()
@Singleton
@Provides
@ -67,20 +104,11 @@ internal class RepositoryModule {
appInfo: AppInfo
) = AppDatabase.newInstance(context, sharedPrefProvider, appInfo)
@Singleton
@Provides
fun provideResources(@ApplicationContext context: Context): Resources = context.resources
@Singleton
@Provides
fun provideAssets(@ApplicationContext context: Context): AssetManager = context.assets
@Singleton
@Provides
fun provideSharedPref(@ApplicationContext context: Context): SharedPreferences =
PreferenceManager.getDefaultSharedPreferences(context)
@OptIn(ExperimentalCoroutinesApi::class)
@Singleton
@Provides
fun provideFlowSharedPref(sharedPreferences: SharedPreferences) =
@ -88,7 +116,9 @@ internal class RepositoryModule {
@Singleton
@Provides
fun provideMoshi() = Moshi.Builder().build()
fun provideJson() = Json {
ignoreUnknownKeys = true
}
@Singleton
@Provides
@ -165,7 +195,7 @@ internal class RepositoryModule {
@Singleton
@Provides
fun provideReportingUnitDao(database: AppDatabase) = database.reportingUnitDao
fun provideMailboxesDao(database: AppDatabase) = database.mailboxDao
@Singleton
@Provides
@ -202,4 +232,12 @@ internal class RepositoryModule {
@Singleton
@Provides
fun provideSchoolAnnouncementDao(database: AppDatabase) = database.schoolAnnouncementDao
@Singleton
@Provides
fun provideNotificationDao(database: AppDatabase) = database.notificationDao
@Singleton
@Provides
fun provideAdminMessageDao(database: AppDatabase) = database.adminMessagesDao
}

View file

@ -1,23 +1,173 @@
package io.github.wulkanowy.data
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)
}
import kotlinx.coroutines.flow.*
import kotlinx.coroutines.sync.Mutex
import kotlinx.coroutines.sync.withLock
import timber.log.Timber
fun <T> error(error: Throwable?, data: T? = null): Resource<T> {
return Resource(Status.ERROR, data, error)
}
sealed class Resource<T> {
fun <T> loading(data: T? = null): Resource<T> {
return Resource(Status.LOADING, data, null)
}
open class Loading<T> : Resource<T>()
data class Intermediate<T>(val data: T) : Loading<T>()
data class Success<T>(val data: T) : Resource<T>()
data class Error<T>(val error: Throwable) : Resource<T>()
}
val <T> Resource<T>.dataOrNull: T?
get() = when (this) {
is Resource.Success -> this.data
is Resource.Intermediate -> this.data
is Resource.Loading -> null
is Resource.Error -> null
}
val <T> Resource<T>.errorOrNull: Throwable?
get() = when (this) {
is Resource.Error -> this.error
else -> null
}
fun <T> resourceFlow(block: suspend () -> T) = flow {
emit(Resource.Loading())
emit(Resource.Success(block()))
}.catch { emit(Resource.Error(it)) }
fun <T> flatResourceFlow(block: suspend () -> Flow<Resource<T>>) = flow {
emit(Resource.Loading())
emitAll(block().filter { it is Resource.Intermediate || it !is Resource.Loading })
}.catch { emit(Resource.Error(it)) }
fun <T, U> Resource<T>.mapData(block: (T) -> U) = when (this) {
is Resource.Success -> Resource.Success(block(this.data))
is Resource.Intermediate -> Resource.Intermediate(block(this.data))
is Resource.Loading -> Resource.Loading()
is Resource.Error -> Resource.Error(this.error)
}
fun <T> Flow<Resource<T>>.logResourceStatus(name: String, showData: Boolean = false) = onEach {
val description = when (it) {
is Resource.Loading -> "started"
is Resource.Intermediate -> "intermediate data received" + if (showData) " (data: `${it.data}`)" else ""
is Resource.Success -> "success" + if (showData) " (data: `${it.data}`)" else ""
is Resource.Error -> "exception occurred: ${it.error}"
}
Timber.i("$name: $description")
}
fun <T, U> Flow<Resource<T>>.mapResourceData(block: (T) -> U) = map {
it.mapData(block)
}
fun <T> Flow<Resource<T>>.onResourceData(block: suspend (T) -> Unit) = onEach {
when (it) {
is Resource.Success -> block(it.data)
is Resource.Intermediate -> block(it.data)
is Resource.Error,
is Resource.Loading -> Unit
}
}
enum class Status {
LOADING,
SUCCESS,
ERROR
fun <T> Flow<Resource<T>>.onResourceLoading(block: suspend () -> Unit) = onEach {
if (it is Resource.Loading) {
block()
}
}
fun <T> Flow<Resource<T>>.onResourceIntermediate(block: suspend (T) -> Unit) = onEach {
if (it is Resource.Intermediate) {
block(it.data)
}
}
fun <T> Flow<Resource<T>>.onResourceSuccess(block: suspend (T) -> Unit) = onEach {
if (it is Resource.Success) {
block(it.data)
}
}
fun <T> Flow<Resource<T>>.onResourceError(block: (Throwable) -> Unit) = onEach {
if (it is Resource.Error) {
block(it.error)
}
}
fun <T> Flow<Resource<T>>.onResourceNotLoading(block: () -> Unit) = onEach {
if (it !is Resource.Loading) {
block()
}
}
suspend fun <T> Flow<Resource<T>>.toFirstResult() = filter { it !is Resource.Loading }.first()
suspend fun <T> Flow<Resource<T>>.waitForResult() = takeWhile { it is Resource.Loading }.collect()
inline fun <ResultType, RequestType> networkBoundResource(
mutex: Mutex = Mutex(),
showSavedOnLoading: Boolean = true,
crossinline isResultEmpty: (ResultType) -> Boolean,
crossinline query: () -> Flow<ResultType>,
crossinline fetch: suspend (ResultType) -> RequestType,
crossinline saveFetchResult: suspend (old: ResultType, new: RequestType) -> Unit,
crossinline onFetchFailed: (Throwable) -> Unit = { },
crossinline shouldFetch: (ResultType) -> Boolean = { true },
crossinline filterResult: (ResultType) -> ResultType = { it }
) = flow {
emit(Resource.Loading())
val data = query().first()
emitAll(if (shouldFetch(data)) {
val filteredResult = filterResult(data)
if (showSavedOnLoading && !isResultEmpty(filteredResult)) {
emit(Resource.Intermediate(filteredResult))
}
try {
val newData = fetch(data)
mutex.withLock { saveFetchResult(query().first(), newData) }
query().map { Resource.Success(filterResult(it)) }
} catch (throwable: Throwable) {
onFetchFailed(throwable)
query().map { Resource.Error(throwable) }
}
} else {
query().map { Resource.Success(filterResult(it)) }
})
}
@JvmName("networkBoundResourceWithMap")
inline fun <ResultType, RequestType, T> networkBoundResource(
mutex: Mutex = Mutex(),
showSavedOnLoading: Boolean = true,
crossinline isResultEmpty: (T) -> Boolean,
crossinline query: () -> Flow<ResultType>,
crossinline fetch: suspend (ResultType) -> RequestType,
crossinline saveFetchResult: suspend (old: ResultType, new: RequestType) -> Unit,
crossinline onFetchFailed: (Throwable) -> Unit = { },
crossinline shouldFetch: (ResultType) -> Boolean = { true },
crossinline mapResult: (ResultType) -> T
) = flow {
emit(Resource.Loading())
val data = query().first()
emitAll(if (shouldFetch(data)) {
val mappedResult = mapResult(data)
if (showSavedOnLoading && !isResultEmpty(mappedResult)) {
emit(Resource.Intermediate(mappedResult))
}
try {
val newData = fetch(data)
mutex.withLock { saveFetchResult(query().first(), newData) }
query().map { Resource.Success(mapResult(it)) }
} catch (throwable: Throwable) {
onFetchFailed(throwable)
query().map { Resource.Error(throwable) }
}
} else {
query().map { Resource.Success(mapResult(it)) }
})
}

View file

@ -0,0 +1,12 @@
package io.github.wulkanowy.data.api
import io.github.wulkanowy.data.db.entities.AdminMessage
import retrofit2.http.GET
import javax.inject.Singleton
@Singleton
interface AdminMessageService {
@GET("/v1.json")
suspend fun getAdminMessages(): List<AdminMessage>
}

View file

@ -1,105 +1,11 @@
package io.github.wulkanowy.data.db
import android.content.Context
import androidx.room.Database
import androidx.room.Room
import androidx.room.RoomDatabase
import androidx.room.*
import androidx.room.RoomDatabase.JournalMode.TRUNCATE
import androidx.room.TypeConverters
import io.github.wulkanowy.data.db.dao.AttendanceDao
import io.github.wulkanowy.data.db.dao.AttendanceSummaryDao
import io.github.wulkanowy.data.db.dao.CompletedLessonsDao
import io.github.wulkanowy.data.db.dao.ConferenceDao
import io.github.wulkanowy.data.db.dao.SchoolAnnouncementDao
import io.github.wulkanowy.data.db.dao.ExamDao
import io.github.wulkanowy.data.db.dao.GradeDao
import io.github.wulkanowy.data.db.dao.GradePartialStatisticsDao
import io.github.wulkanowy.data.db.dao.GradePointsStatisticsDao
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
import io.github.wulkanowy.data.db.dao.MessageAttachmentDao
import io.github.wulkanowy.data.db.dao.MessagesDao
import io.github.wulkanowy.data.db.dao.MobileDeviceDao
import io.github.wulkanowy.data.db.dao.NoteDao
import io.github.wulkanowy.data.db.dao.RecipientDao
import io.github.wulkanowy.data.db.dao.ReportingUnitDao
import io.github.wulkanowy.data.db.dao.SchoolDao
import io.github.wulkanowy.data.db.dao.SemesterDao
import io.github.wulkanowy.data.db.dao.StudentDao
import io.github.wulkanowy.data.db.dao.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.dao.TimetableHeaderDao
import io.github.wulkanowy.data.db.entities.Attendance
import io.github.wulkanowy.data.db.entities.AttendanceSummary
import io.github.wulkanowy.data.db.entities.CompletedLesson
import io.github.wulkanowy.data.db.entities.Conference
import io.github.wulkanowy.data.db.entities.SchoolAnnouncement
import io.github.wulkanowy.data.db.entities.Exam
import io.github.wulkanowy.data.db.entities.Grade
import io.github.wulkanowy.data.db.entities.GradePartialStatistics
import io.github.wulkanowy.data.db.entities.GradePointsStatistics
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
import io.github.wulkanowy.data.db.entities.Message
import io.github.wulkanowy.data.db.entities.MessageAttachment
import io.github.wulkanowy.data.db.entities.MobileDevice
import io.github.wulkanowy.data.db.entities.Note
import io.github.wulkanowy.data.db.entities.Recipient
import io.github.wulkanowy.data.db.entities.ReportingUnit
import io.github.wulkanowy.data.db.entities.School
import io.github.wulkanowy.data.db.entities.Semester
import io.github.wulkanowy.data.db.entities.Student
import io.github.wulkanowy.data.db.entities.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.entities.TimetableHeader
import io.github.wulkanowy.data.db.migrations.Migration10
import io.github.wulkanowy.data.db.migrations.Migration11
import io.github.wulkanowy.data.db.migrations.Migration12
import io.github.wulkanowy.data.db.migrations.Migration13
import io.github.wulkanowy.data.db.migrations.Migration14
import io.github.wulkanowy.data.db.migrations.Migration15
import io.github.wulkanowy.data.db.migrations.Migration16
import io.github.wulkanowy.data.db.migrations.Migration17
import io.github.wulkanowy.data.db.migrations.Migration18
import io.github.wulkanowy.data.db.migrations.Migration19
import io.github.wulkanowy.data.db.migrations.Migration2
import io.github.wulkanowy.data.db.migrations.Migration20
import io.github.wulkanowy.data.db.migrations.Migration21
import io.github.wulkanowy.data.db.migrations.Migration22
import io.github.wulkanowy.data.db.migrations.Migration23
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.Migration36
import io.github.wulkanowy.data.db.migrations.Migration37
import io.github.wulkanowy.data.db.migrations.Migration38
import io.github.wulkanowy.data.db.migrations.Migration39
import io.github.wulkanowy.data.db.migrations.Migration4
import io.github.wulkanowy.data.db.migrations.Migration5
import io.github.wulkanowy.data.db.migrations.Migration6
import io.github.wulkanowy.data.db.migrations.Migration7
import io.github.wulkanowy.data.db.migrations.Migration8
import io.github.wulkanowy.data.db.migrations.Migration9
import io.github.wulkanowy.data.db.dao.*
import io.github.wulkanowy.data.db.entities.*
import io.github.wulkanowy.data.db.migrations.*
import io.github.wulkanowy.utils.AppInfo
import javax.inject.Singleton
@ -124,7 +30,7 @@ import javax.inject.Singleton
Subject::class,
LuckyNumber::class,
CompletedLesson::class,
ReportingUnit::class,
Mailbox::class,
Recipient::class,
MobileDevice::class,
Teacher::class,
@ -134,6 +40,14 @@ import javax.inject.Singleton
StudentInfo::class,
TimetableHeader::class,
SchoolAnnouncement::class,
Notification::class,
AdminMessage::class
],
autoMigrations = [
AutoMigration(from = 44, to = 45),
AutoMigration(from = 46, to = 47),
AutoMigration(from = 47, to = 48),
AutoMigration(from = 51, to = 52),
],
version = AppDatabase.VERSION_SCHEMA,
exportSchema = true
@ -142,7 +56,7 @@ import javax.inject.Singleton
abstract class AppDatabase : RoomDatabase() {
companion object {
const val VERSION_SCHEMA = 39
const val VERSION_SCHEMA = 53
fun getMigrations(sharedPrefProvider: SharedPrefProvider, appInfo: AppInfo) = arrayOf(
Migration2(),
@ -183,6 +97,16 @@ abstract class AppDatabase : RoomDatabase() {
Migration37(),
Migration38(),
Migration39(),
Migration40(),
Migration41(sharedPrefProvider),
Migration42(),
Migration43(),
Migration44(),
Migration46(),
Migration49(),
Migration50(),
Migration51(),
Migration53(),
)
fun newInstance(
@ -233,7 +157,7 @@ abstract class AppDatabase : RoomDatabase() {
abstract val completedLessonsDao: CompletedLessonsDao
abstract val reportingUnitDao: ReportingUnitDao
abstract val mailboxDao: MailboxDao
abstract val recipientDao: RecipientDao
@ -252,4 +176,8 @@ abstract class AppDatabase : RoomDatabase() {
abstract val timetableHeaderDao: TimetableHeaderDao
abstract val schoolAnnouncementDao: SchoolAnnouncementDao
abstract val notificationDao: NotificationDao
abstract val adminMessagesDao: AdminMessageDao
}

View file

@ -1,47 +1,36 @@
package io.github.wulkanowy.data.db
import androidx.room.TypeConverter
import com.squareup.moshi.Moshi
import com.squareup.moshi.Types
import io.github.wulkanowy.data.db.adapters.PairAdapterFactory
import io.github.wulkanowy.ui.modules.Destination
import io.github.wulkanowy.utils.toTimestamp
import kotlinx.serialization.SerializationException
import kotlinx.serialization.decodeFromString
import kotlinx.serialization.encodeToString
import kotlinx.serialization.json.Json
import java.time.*
import java.util.*
import java.time.Instant
import java.time.LocalDate
import java.time.LocalDateTime
import java.time.Month
import java.time.ZoneOffset
import java.util.Date
import java.util.*
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))
}
private val json = Json
@TypeConverter
fun timestampToDate(value: Long?): LocalDate? = value?.run {
Date(value).toInstant().atZone(ZoneOffset.UTC).toLocalDate()
}
fun timestampToLocalDate(value: Long?): LocalDate? =
value?.let(::Date)?.toInstant()?.atZone(ZoneOffset.UTC)?.toLocalDate()
@TypeConverter
fun dateToTimestamp(date: LocalDate?): Long? {
return date?.atStartOfDay()?.toInstant(ZoneOffset.UTC)?.toEpochMilli()
}
fun dateToTimestamp(date: LocalDate?): Long? = date?.toTimestamp()
@TypeConverter
fun timestampToTime(value: Long?): LocalDateTime? = value?.let {
LocalDateTime.ofInstant(Instant.ofEpochMilli(value), ZoneOffset.UTC)
}
fun instantToTimestamp(instant: Instant?): Long? = instant?.toEpochMilli()
@TypeConverter
fun timeToTimestamp(date: LocalDateTime?): Long? {
return date?.atZone(ZoneOffset.UTC)?.toInstant()?.toEpochMilli()
}
fun timestampToInstant(timestamp: Long?): Instant? = timestamp?.let(Instant::ofEpochMilli)
@TypeConverter
fun monthToInt(month: Month?) = month?.value
@ -51,21 +40,32 @@ class Converters {
@TypeConverter
fun intListToJson(list: List<Int>): String {
return integerListAdapter.toJson(list)
return json.encodeToString(list)
}
@TypeConverter
fun jsonToIntList(value: String): List<Int> {
return integerListAdapter.fromJson(value).orEmpty()
return json.decodeFromString(value)
}
@TypeConverter
fun stringPairListToJson(list: List<Pair<String, String>>): String {
return stringListPairAdapter.toJson(list)
return json.encodeToString(list)
}
@TypeConverter
fun jsonToStringPairList(value: String): List<Pair<String, String>> {
return stringListPairAdapter.fromJson(value).orEmpty()
return try {
json.decodeFromString(value)
} catch (e: SerializationException) {
emptyList() // handle errors from old gson Pair serialized data
}
}
@TypeConverter
fun destinationToString(destination: Destination) = json.encodeToString(destination)
@TypeConverter
fun stringToDestination(destination: String): Destination = json.decodeFromString(destination)
}

View file

@ -22,11 +22,14 @@ class SharedPrefProvider @Inject constructor(
fun getString(key: String) = sharedPref.getString(key, null)
fun getString(key: String, defaultValue: String): String = sharedPref.getString(key, defaultValue) ?: defaultValue
fun getString(key: String, defaultValue: String): String =
sharedPref.getString(key, defaultValue) ?: defaultValue
fun getBoolean(key: String, defaultValue: Boolean): Boolean = sharedPref.getBoolean(key, defaultValue)
fun getBoolean(key: String, defaultValue: Boolean): Boolean =
sharedPref.getBoolean(key, defaultValue)
fun putBoolean(key: String, value: Boolean, sync: Boolean = false) = sharedPref.edit(sync) { putBoolean(key, value) }
fun putBoolean(key: String, value: Boolean, sync: Boolean = false) =
sharedPref.edit(sync) { putBoolean(key, value) }
fun putString(key: String, value: String?, sync: Boolean = false) {
sharedPref.edit(sync) { putString(key, value) }

View file

@ -1,68 +0,0 @@
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

@ -0,0 +1,25 @@
package io.github.wulkanowy.data.db.dao
import androidx.room.Dao
import androidx.room.Query
import androidx.room.Transaction
import io.github.wulkanowy.data.db.entities.AdminMessage
import kotlinx.coroutines.flow.Flow
import javax.inject.Singleton
@Singleton
@Dao
abstract class AdminMessageDao : BaseDao<AdminMessage> {
@Query("SELECT * FROM AdminMessages")
abstract fun loadAll(): Flow<List<AdminMessage>>
@Transaction
open suspend fun removeOldAndSaveNew(
oldMessages: List<AdminMessage>,
newMessages: List<AdminMessage>
) {
deleteAll(oldMessages)
insertAll(newMessages)
}
}

View file

@ -11,6 +11,11 @@ import javax.inject.Singleton
@Dao
interface AttendanceDao : BaseDao<Attendance> {
@Query("SELECT * FROM Attendance WHERE diary_id = :diaryId AND student_id = :studentId AND date >= :from AND date <= :end")
fun loadAll(diaryId: Int, studentId: Int, from: LocalDate, end: LocalDate): Flow<List<Attendance>>
@Query("SELECT * FROM Attendance WHERE diary_id = :diaryId AND student_id = :studentId AND date >= :start AND date <= :end")
fun loadAll(
diaryId: Int,
studentId: Int,
start: LocalDate,
end: LocalDate
): Flow<List<Attendance>>
}

View file

@ -2,11 +2,12 @@ package io.github.wulkanowy.data.db.dao
import androidx.room.Delete
import androidx.room.Insert
import androidx.room.OnConflictStrategy
import androidx.room.Update
interface BaseDao<T> {
@Insert
@Insert(onConflict = OnConflictStrategy.REPLACE)
suspend fun insertAll(items: List<T>): List<Long>
@Update

View file

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

View file

@ -0,0 +1,18 @@
package io.github.wulkanowy.data.db.dao
import androidx.room.Dao
import androidx.room.Query
import io.github.wulkanowy.data.db.entities.Mailbox
import kotlinx.coroutines.flow.Flow
import javax.inject.Singleton
@Singleton
@Dao
interface MailboxDao : BaseDao<Mailbox> {
@Query("SELECT * FROM Mailboxes WHERE email = :email")
suspend fun loadAll(email: String): List<Mailbox>
@Query("SELECT * FROM Mailboxes WHERE email = :email AND symbol = :symbol AND schoolId = :schoolId")
fun loadAll(email: String, symbol: String, schoolId: String): Flow<List<Mailbox>>
}

View file

@ -11,9 +11,12 @@ import kotlinx.coroutines.flow.Flow
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?>
@Query("SELECT * FROM Messages WHERE message_global_key = :messageGlobalKey")
fun loadMessageWithAttachment(messageGlobalKey: String): 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>>
@Query("SELECT * FROM Messages WHERE mailbox_key = :mailboxKey AND folder_id = :folder ORDER BY date DESC")
fun loadAll(mailboxKey: String, folder: Int): Flow<List<Message>>
@Query("SELECT * FROM Messages WHERE email = :email AND folder_id = :folder ORDER BY date DESC")
fun loadAll(folder: Int, email: String): 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 = :userLoginId ORDER BY date DESC")
@Query("SELECT * FROM MobileDevices WHERE user_login_id = :userLoginId ORDER BY date DESC")
fun loadAll(userLoginId: Int): Flow<List<MobileDevice>>
}

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.Notification
import kotlinx.coroutines.flow.Flow
import javax.inject.Singleton
@Singleton
@Dao
interface NotificationDao : BaseDao<Notification> {
@Query("SELECT * FROM Notifications WHERE student_id = :studentId OR student_id = -1")
fun loadAll(studentId: Long): Flow<List<Notification>>
}

View file

@ -2,6 +2,7 @@ package io.github.wulkanowy.data.db.dao
import androidx.room.Dao
import androidx.room.Query
import io.github.wulkanowy.data.db.entities.MailboxType
import io.github.wulkanowy.data.db.entities.Recipient
import javax.inject.Singleton
@ -9,6 +10,6 @@ import javax.inject.Singleton
@Dao
interface RecipientDao : BaseDao<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>
@Query("SELECT * FROM Recipients WHERE type = :type AND studentMailboxGlobalKey = :studentMailboxGlobalKey")
suspend fun loadAll(type: MailboxType, studentMailboxGlobalKey: String): List<Recipient>
}

View file

@ -1,17 +0,0 @@
package io.github.wulkanowy.data.db.dao
import androidx.room.Dao
import androidx.room.Query
import io.github.wulkanowy.data.db.entities.ReportingUnit
import javax.inject.Singleton
@Singleton
@Dao
interface ReportingUnitDao : BaseDao<ReportingUnit> {
@Query("SELECT * FROM ReportingUnits WHERE student_id = :studentId")
suspend fun load(studentId: Int): List<ReportingUnit>
@Query("SELECT * FROM ReportingUnits WHERE student_id = :studentId AND real_id = :unitId")
suspend fun loadOne(studentId: Int, unitId: Int): ReportingUnit?
}

View file

@ -10,6 +10,6 @@ import javax.inject.Singleton
@Singleton
interface SchoolAnnouncementDao : BaseDao<SchoolAnnouncement> {
@Query("SELECT * FROM SchoolAnnouncements WHERE student_id = :studentId")
fun loadAll(studentId: Int): Flow<List<SchoolAnnouncement>>
@Query("SELECT * FROM SchoolAnnouncements WHERE user_login_id = :userLoginId ORDER BY date DESC")
fun loadAll(userLoginId: Int): Flow<List<SchoolAnnouncement>>
}

View file

@ -1,12 +1,7 @@
package io.github.wulkanowy.data.db.dao
import androidx.room.Dao
import androidx.room.Delete
import androidx.room.Insert
import androidx.room.*
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
@ -38,6 +33,10 @@ abstract class StudentDao {
@Query("SELECT * FROM Students")
abstract suspend fun loadStudentsWithSemesters(): List<StudentWithSemesters>
@Transaction
@Query("SELECT * FROM Students WHERE id = :id")
abstract suspend fun loadStudentWithSemestersById(id: Long): StudentWithSemesters?
@Query("UPDATE Students SET is_current = 1 WHERE id = :id")
abstract suspend fun updateCurrent(id: Long)

View file

@ -5,6 +5,7 @@ import androidx.room.Query
import io.github.wulkanowy.data.db.entities.TimetableAdditional
import kotlinx.coroutines.flow.Flow
import java.time.LocalDate
import java.util.UUID
import javax.inject.Singleton
@Dao
@ -12,5 +13,13 @@ import javax.inject.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>>
fun loadAll(
diaryId: Int,
studentId: Int,
from: LocalDate,
end: LocalDate
): Flow<List<TimetableAdditional>>
@Query("DELETE FROM TimetableAdditional WHERE repeat_id = :repeatId")
suspend fun deleteAllByRepeatId(repeatId: UUID)
}

View file

@ -0,0 +1,40 @@
package io.github.wulkanowy.data.db.entities
import androidx.room.ColumnInfo
import androidx.room.Entity
import androidx.room.PrimaryKey
import kotlinx.serialization.Serializable
@Serializable
@Entity(tableName = "AdminMessages")
data class AdminMessage(
@PrimaryKey
val id: Int,
val title: String,
val content: String,
@ColumnInfo(name = "version_name")
val versionMin: Int? = null,
@ColumnInfo(name = "version_max")
val versionMax: Int? = null,
@ColumnInfo(name = "target_register_host")
val targetRegisterHost: String? = null,
@ColumnInfo(name = "target_flavor")
val targetFlavor: String? = null,
@ColumnInfo(name = "destination_url")
val destinationUrl: String? = null,
val priority: String,
val type: String,
@ColumnInfo(name = "is_dismissible")
val isDismissible: Boolean = false
)

View file

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

View file

@ -4,7 +4,7 @@ import androidx.room.ColumnInfo
import androidx.room.Entity
import androidx.room.PrimaryKey
import java.io.Serializable
import java.time.LocalDateTime
import java.time.Instant
@Entity(tableName = "Conferences")
data class Conference(
@ -27,7 +27,7 @@ data class Conference(
@ColumnInfo(name = "conference_id")
val conferenceId: Int,
val date: LocalDateTime
val date: Instant,
) : Serializable {
@PrimaryKey(autoGenerate = true)

View file

@ -24,5 +24,8 @@ data class GradeSemesterStatistics(
var id: Long = 0
@Transient
var average: String = ""
var classAverage: String = ""
@Transient
var studentAverage: String = ""
}

View file

@ -3,7 +3,7 @@ package io.github.wulkanowy.data.db.entities
import androidx.room.ColumnInfo
import androidx.room.Entity
import androidx.room.PrimaryKey
import java.time.LocalDateTime
import java.time.Instant
@Entity(tableName = "GradesSummary")
data class GradeSummary(
@ -45,8 +45,8 @@ data class GradeSummary(
var isFinalGradeNotified: Boolean = true
@ColumnInfo(name = "predicted_grade_last_change")
var predictedGradeLastChange: LocalDateTime = LocalDateTime.now()
var predictedGradeLastChange: Instant = Instant.now()
@ColumnInfo(name = "final_grade_last_change")
var finalGradeLastChange: LocalDateTime = LocalDateTime.now()
var finalGradeLastChange: Instant = Instant.now()
}

View file

@ -40,4 +40,7 @@ data class Homework(
@ColumnInfo(name = "is_notified")
var isNotified: Boolean = true
@ColumnInfo(name = "is_added_by_user")
var isAddedByUser: Boolean = false
}

View file

@ -0,0 +1,32 @@
package io.github.wulkanowy.data.db.entities
import android.os.Parcelable
import androidx.room.Entity
import androidx.room.PrimaryKey
import kotlinx.parcelize.Parcelize
@Parcelize
@Entity(tableName = "Mailboxes")
data class Mailbox(
@PrimaryKey
val globalKey: String,
val email: String,
val symbol: String,
val schoolId: String,
val fullName: String,
val userName: String,
val studentName: String,
val schoolNameShort: String,
val type: MailboxType,
) : java.io.Serializable, Parcelable
enum class MailboxType {
STUDENT,
PARENT,
GUARDIAN,
EMPLOYEE,
UNKNOWN,
}

View file

@ -4,39 +4,39 @@ import androidx.room.ColumnInfo
import androidx.room.Entity
import androidx.room.PrimaryKey
import java.io.Serializable
import java.time.LocalDateTime
import java.time.Instant
@Entity(tableName = "Messages")
data class Message(
@ColumnInfo(name = "student_id")
val studentId: Long,
@ColumnInfo(name = "email")
val email: String,
@ColumnInfo(name = "real_id")
val realId: Int,
@ColumnInfo(name = "message_global_key")
val messageGlobalKey: String,
@ColumnInfo(name = "mailbox_key")
val mailboxKey: String,
@ColumnInfo(name = "message_id")
val messageId: Int,
@ColumnInfo(name = "sender_name")
val sender: String,
@ColumnInfo(name = "sender_id")
val senderId: Int,
@ColumnInfo(name = "recipient_name")
val recipient: String,
val correspondents: String,
val subject: String,
val date: LocalDateTime,
val date: Instant,
@ColumnInfo(name = "folder_id")
val folderId: Int,
var unread: Boolean,
val removed: Boolean,
@ColumnInfo(name = "read_by")
val readBy: Int?,
@ColumnInfo(name = "unread_by")
val unreadBy: Int?,
@ColumnInfo(name = "has_attachments")
val hasAttachments: Boolean
@ -48,11 +48,7 @@ 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 = ""
var sender: String? = null
var recipients: String? = null
}

View file

@ -12,11 +12,8 @@ data class MessageAttachment(
@ColumnInfo(name = "real_id")
val realId: Int,
@ColumnInfo(name = "message_id")
val messageId: Int,
@ColumnInfo(name = "one_drive_id")
val oneDriveId: String,
@ColumnInfo(name = "message_global_key")
val messageGlobalKey: String,
@ColumnInfo(name = "url")
val url: String,

View file

@ -7,6 +7,6 @@ data class MessageWithAttachment(
@Embedded
val message: Message,
@Relation(parentColumn = "message_id", entityColumn = "message_id")
@Relation(parentColumn = "message_global_key", entityColumn = "message_global_key")
val attachments: List<MessageAttachment>
)

View file

@ -4,12 +4,12 @@ import androidx.room.ColumnInfo
import androidx.room.Entity
import androidx.room.PrimaryKey
import java.io.Serializable
import java.time.LocalDateTime
import java.time.Instant
@Entity(tableName = "MobileDevices")
data class MobileDevice(
@ColumnInfo(name = "student_id")
@ColumnInfo(name = "user_login_id")
val userLoginId: Int,
@ColumnInfo(name = "device_id")
@ -17,7 +17,7 @@ data class MobileDevice(
val name: String,
val date: LocalDateTime
val date: Instant,
) : Serializable {
@PrimaryKey(autoGenerate = true)

View file

@ -0,0 +1,31 @@
package io.github.wulkanowy.data.db.entities
import androidx.room.ColumnInfo
import androidx.room.Entity
import androidx.room.PrimaryKey
import io.github.wulkanowy.services.sync.notifications.NotificationType
import io.github.wulkanowy.ui.modules.Destination
import java.time.Instant
@Entity(tableName = "Notifications")
data class Notification(
@ColumnInfo(name = "student_id")
val studentId: Long,
val title: String,
val content: String,
val type: NotificationType,
@ColumnInfo(defaultValue = "{\"type\":\"io.github.wulkanowy.ui.modules.Destination.Dashboard\"}")
val destination: Destination,
val date: Instant,
val data: String? = null
) {
@PrimaryKey(autoGenerate = true)
var id: Long = 0
}

View file

@ -1,40 +1,22 @@
package io.github.wulkanowy.data.db.entities
import androidx.room.ColumnInfo
import androidx.room.Entity
import androidx.room.PrimaryKey
import com.squareup.moshi.JsonClass
import java.io.Serializable
@JsonClass(generateAdapter = true)
@kotlinx.serialization.Serializable
@Entity(tableName = "Recipients")
data class Recipient(
@ColumnInfo(name = "student_id")
val studentId: Int,
@ColumnInfo(name = "real_id")
val realId: String,
val name: String,
@ColumnInfo(name = "real_name")
val realName: String,
@ColumnInfo(name = "login_id")
val loginId: Int,
@ColumnInfo(name = "unit_id")
val unitId: Int,
val role: Int,
val hash: String
val mailboxGlobalKey: String,
val studentMailboxGlobalKey: String,
val fullName: String,
val userName: String,
val schoolShortName: String,
val type: MailboxType,
) : Serializable {
@PrimaryKey(autoGenerate = true)
var id: Long = 0
override fun toString() = name
override fun toString() = userName
}

View file

@ -1,32 +0,0 @@
package io.github.wulkanowy.data.db.entities
import androidx.room.ColumnInfo
import androidx.room.Entity
import androidx.room.PrimaryKey
import java.io.Serializable
@Entity(tableName = "ReportingUnits")
data class ReportingUnit(
@ColumnInfo(name = "student_id")
val studentId: Int,
@ColumnInfo(name = "real_id")
val unitId: Int,
@ColumnInfo(name = "short")
val shortName: String,
@ColumnInfo(name = "sender_id")
val senderId: Int,
@ColumnInfo(name = "sender_name")
val senderName: String,
val roles: List<Int>
) : Serializable {
@PrimaryKey(autoGenerate = true)
var id: Long = 0
}

View file

@ -9,8 +9,8 @@ import java.time.LocalDate
@Entity(tableName = "SchoolAnnouncements")
data class SchoolAnnouncement(
@ColumnInfo(name = "student_id")
val studentId: Int,
@ColumnInfo(name = "user_login_id")
val userLoginId: Int,
val date: LocalDate,

View file

@ -7,7 +7,12 @@ import androidx.room.PrimaryKey
import java.io.Serializable
import java.time.LocalDate
@Entity(tableName = "Semesters", indices = [Index(value = ["student_id", "diary_id", "semester_id"], unique = true)])
@Entity(
tableName = "Semesters", indices = [Index(
value = ["student_id", "diary_id", "kindergarten_diary_id", "semester_id"],
unique = true
)]
)
data class Semester(
@ColumnInfo(name = "student_id")
@ -16,6 +21,9 @@ data class Semester(
@ColumnInfo(name = "diary_id")
val diaryId: Int,
@ColumnInfo(name = "kindergarten_diary_id", defaultValue = "0")
val kindergartenDiaryId: Int,
@ColumnInfo(name = "diary_name")
val diaryName: String,
@ -37,12 +45,11 @@ data class Semester(
@ColumnInfo(name = "unit_id")
val unitId: Int
): Serializable {
) : Serializable {
@PrimaryKey(autoGenerate = true)
var id: Long = 0
@ColumnInfo(name = "is_current")
var current: Boolean = false
}

View file

@ -5,7 +5,7 @@ import androidx.room.Entity
import androidx.room.Index
import androidx.room.PrimaryKey
import java.io.Serializable
import java.time.LocalDateTime
import java.time.Instant
@Entity(
tableName = "Students",
@ -74,7 +74,7 @@ data class Student(
val isCurrent: Boolean,
@ColumnInfo(name = "registration_date")
val registrationDate: LocalDateTime
val registrationDate: Instant,
) : Serializable {
@PrimaryKey(autoGenerate = true)

View file

@ -4,8 +4,8 @@ import androidx.room.ColumnInfo
import androidx.room.Entity
import androidx.room.PrimaryKey
import java.io.Serializable
import java.time.Instant
import java.time.LocalDate
import java.time.LocalDateTime
@Entity(tableName = "Timetable")
data class Timetable(
@ -18,9 +18,9 @@ data class Timetable(
val number: Int,
val start: LocalDateTime,
val start: Instant,
val end: LocalDateTime,
val end: Instant,
val date: LocalDate,
@ -50,4 +50,7 @@ data class Timetable(
@PrimaryKey(autoGenerate = true)
var id: Long = 0
@ColumnInfo(name = "is_notified")
var isNotified: Boolean = true
}

View file

@ -4,8 +4,9 @@ import androidx.room.ColumnInfo
import androidx.room.Entity
import androidx.room.PrimaryKey
import java.io.Serializable
import java.time.Instant
import java.time.LocalDate
import java.time.LocalDateTime
import java.util.*
@Entity(tableName = "TimetableAdditional")
data class TimetableAdditional(
@ -16,9 +17,9 @@ data class TimetableAdditional(
@ColumnInfo(name = "diary_id")
val diaryId: Int,
val start: LocalDateTime,
val start: Instant,
val end: LocalDateTime,
val end: Instant,
val date: LocalDate,
@ -27,4 +28,10 @@ data class TimetableAdditional(
@PrimaryKey(autoGenerate = true)
var id: Long = 0
@ColumnInfo(name = "repeat_id", defaultValue = "NULL")
var repeatId: UUID? = null
@ColumnInfo(name = "is_added_by_user", defaultValue = "0")
var isAddedByUser: Boolean = false
}

View file

@ -43,12 +43,14 @@ class Migration12 : Migration(11, 12) {
private fun getStudentsIds(database: SupportSQLiteDatabase): List<Int> {
val students = mutableListOf<Int>()
val studentsCursor = database.query("SELECT student_id FROM Students")
if (studentsCursor.moveToFirst()) {
do {
students.add(studentsCursor.getInt(0))
} while (studentsCursor.moveToNext())
database.query("SELECT student_id FROM Students").use {
if (it.moveToFirst()) {
do {
students.add(it.getInt(0))
} while (it.moveToNext())
}
}
return students
}

View file

@ -25,12 +25,14 @@ class Migration13 : Migration(12, 13) {
private fun getStudentsIds(database: SupportSQLiteDatabase): MutableList<Pair<Int, String>> {
val students = mutableListOf<Pair<Int, String>>()
val studentsCursor = database.query("SELECT id, school_name FROM Students")
if (studentsCursor.moveToFirst()) {
do {
students.add(studentsCursor.getInt(0) to studentsCursor.getString(1))
} while (studentsCursor.moveToNext())
database.query("SELECT id, school_name FROM Students").use {
if (it.moveToFirst()) {
do {
students.add(it.getInt(0) to it.getString(1))
} while (it.moveToNext())
}
}
return students
}
@ -42,12 +44,14 @@ class Migration13 : Migration(12, 13) {
private fun getStudentsAndClassIds(database: SupportSQLiteDatabase): List<Pair<Int, Int>> {
val students = mutableListOf<Pair<Int, Int>>()
val studentsCursor = database.query("SELECT student_id, class_id FROM Students")
if (studentsCursor.moveToFirst()) {
do {
students.add(studentsCursor.getInt(0) to studentsCursor.getInt(1))
} while (studentsCursor.moveToNext())
database.query("SELECT student_id, class_id FROM Students").use {
if (it.moveToFirst()) {
do {
students.add(it.getInt(0) to it.getInt(1))
} while (it.moveToNext())
}
}
return students
}

View file

@ -22,24 +22,28 @@ class Migration27 : Migration(26, 27) {
private fun getStudentsIdsAndNames(database: SupportSQLiteDatabase): MutableList<Triple<Long, Int, String>> {
val students = mutableListOf<Triple<Long, Int, String>>()
val studentsCursor = database.query("SELECT id, user_login_id, student_name FROM Students")
if (studentsCursor.moveToFirst()) {
do {
students.add(Triple(studentsCursor.getLong(0), studentsCursor.getInt(1), studentsCursor.getString(2)))
} while (studentsCursor.moveToNext())
database.query("SELECT id, user_login_id, student_name FROM Students").use {
if (it.moveToFirst()) {
do {
students.add(Triple(it.getLong(0), it.getInt(1), it.getString(2)))
} while (it.moveToNext())
}
}
return students
}
private fun getReportingUnits(database: SupportSQLiteDatabase): MutableList<Pair<Int, String>> {
val units = mutableListOf<Pair<Int, String>>()
val unitsCursor = database.query("SELECT sender_id, sender_name FROM ReportingUnits")
if (unitsCursor.moveToFirst()) {
do {
units.add(unitsCursor.getInt(0) to unitsCursor.getString(1))
} while (unitsCursor.moveToNext())
database.query("SELECT sender_id, sender_name FROM ReportingUnits").use {
if (it.moveToFirst()) {
do {
units.add(it.getInt(0) to it.getString(1))
} while (it.moveToNext())
}
}
return units
}
}

View file

@ -10,15 +10,17 @@ 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"""
)
database.query("SELECT * FROM Students").use {
while (it.moveToNext()) {
val studentId = it.getLongOrNull(0)
database.execSQL(
"""
UPDATE Students
SET avatar_color = ${appInfo.defaultColorsForAvatar.random()}
WHERE id = $studentId
"""
)
}
}
}
}

View file

@ -0,0 +1,23 @@
package io.github.wulkanowy.data.db.migrations
import androidx.room.migration.Migration
import androidx.sqlite.db.SupportSQLiteDatabase
class Migration40 : Migration(39, 40) {
override fun migrate(database: SupportSQLiteDatabase) {
database.execSQL(
"""
CREATE TABLE IF NOT EXISTS `Notifications` (
`student_id` INTEGER NOT NULL,
`title` TEXT NOT NULL,
`content` TEXT NOT NULL,
`type` TEXT NOT NULL,
`date` INTEGER NOT NULL,
`data` TEXT,
`id` INTEGER PRIMARY KEY AUTOINCREMENT 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
import io.github.wulkanowy.data.db.SharedPrefProvider
import io.github.wulkanowy.data.enums.GradeExpandMode
class Migration41(private val sharedPrefProvider: SharedPrefProvider) : Migration(40, 41) {
override fun migrate(database: SupportSQLiteDatabase) {
migrateSharedPreferences()
database.execSQL("ALTER TABLE Homework ADD COLUMN is_added_by_user INTEGER NOT NULL DEFAULT 0")
}
private fun migrateSharedPreferences() {
if (sharedPrefProvider.getBoolean("pref_key_expand_grade", false)) {
sharedPrefProvider.putString("pref_key_expand_grade_mode", GradeExpandMode.ALWAYS_EXPANDED.value)
}
sharedPrefProvider.delete("pref_key_expand_grade")
}
}

View file

@ -0,0 +1,24 @@
package io.github.wulkanowy.data.db.migrations
import androidx.room.migration.Migration
import androidx.sqlite.db.SupportSQLiteDatabase
class Migration42 : Migration(41, 42) {
override fun migrate(database: SupportSQLiteDatabase) {
database.execSQL(
"""CREATE TABLE IF NOT EXISTS `AdminMessages` (
`id` INTEGER NOT NULL,
`title` TEXT NOT NULL,
`content` TEXT NOT NULL,
`version_name` INTEGER,
`version_max` INTEGER,
`target_register_host` TEXT,
`target_flavor` TEXT,
`destination_url` TEXT,
`priority` TEXT NOT NULL,
`type` TEXT NOT NULL,
PRIMARY KEY(`id`))"""
)
}
}

View file

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

View file

@ -0,0 +1,11 @@
package io.github.wulkanowy.data.db.migrations
import androidx.room.migration.Migration
import androidx.sqlite.db.SupportSQLiteDatabase
class Migration44 : Migration(43, 44) {
override fun migrate(database: SupportSQLiteDatabase) {
database.execSQL("ALTER TABLE AdminMessages ADD COLUMN is_dismissible INTEGER NOT NULL DEFAULT 0")
}
}

View file

@ -0,0 +1,102 @@
package io.github.wulkanowy.data.db.migrations
import androidx.room.migration.Migration
import androidx.sqlite.db.SupportSQLiteDatabase
import java.time.Instant
import java.time.ZoneId
import java.time.ZoneOffset
class Migration46 : Migration(45, 46) {
override fun migrate(database: SupportSQLiteDatabase) {
migrateConferences(database)
migrateMessages(database)
migrateMobileDevices(database)
migrateNotifications(database)
migrateTimetable(database)
migrateTimetableAdditional(database)
}
private fun migrateConferences(database: SupportSQLiteDatabase) {
database.query("SELECT * FROM Conferences").use {
while (it.moveToNext()) {
val id = it.getLong(it.getColumnIndexOrThrow("id"))
val timestampLocal = it.getLong(it.getColumnIndexOrThrow("date"))
val timestampUtc = timestampLocal.timestampLocalToUTC()
database.execSQL("UPDATE Conferences SET date = $timestampUtc WHERE id = $id")
}
}
}
private fun migrateMessages(database: SupportSQLiteDatabase) {
database.query("SELECT * FROM Messages").use {
while (it.moveToNext()) {
val id = it.getLong(it.getColumnIndexOrThrow("id"))
val timestampLocal = it.getLong(it.getColumnIndexOrThrow("date"))
val timestampUtc = timestampLocal.timestampLocalToUTC()
database.execSQL("UPDATE Messages SET date = $timestampUtc WHERE id = $id")
}
}
}
private fun migrateMobileDevices(database: SupportSQLiteDatabase) {
database.query("SELECT * FROM MobileDevices").use {
while (it.moveToNext()) {
val id = it.getLong(it.getColumnIndexOrThrow("id"))
val timestampLocal = it.getLong(it.getColumnIndexOrThrow("date"))
val timestampUtc = timestampLocal.timestampLocalToUTC()
database.execSQL("UPDATE MobileDevices SET date = $timestampUtc WHERE id = $id")
}
}
}
private fun migrateNotifications(database: SupportSQLiteDatabase) {
database.query("SELECT * FROM Notifications").use {
while (it.moveToNext()) {
val id = it.getLong(it.getColumnIndexOrThrow("id"))
val timestampLocal = it.getLong(it.getColumnIndexOrThrow("date"))
val timestampUtc = timestampLocal.timestampLocalToUTC()
database.execSQL("UPDATE Notifications SET date = $timestampUtc WHERE id = $id")
}
}
}
private fun migrateTimetable(database: SupportSQLiteDatabase) {
database.query("SELECT * FROM Timetable").use {
while (it.moveToNext()) {
val id = it.getLong(it.getColumnIndexOrThrow("id"))
val timestampLocalStart = it.getLong(it.getColumnIndexOrThrow("start"))
val timestampLocalEnd = it.getLong(it.getColumnIndexOrThrow("end"))
val timestampUtcStart = timestampLocalStart.timestampLocalToUTC()
val timestampUtcEnd = timestampLocalEnd.timestampLocalToUTC()
database.execSQL("UPDATE Timetable SET start = $timestampUtcStart, end = $timestampUtcEnd WHERE id = $id")
}
}
}
private fun migrateTimetableAdditional(database: SupportSQLiteDatabase) {
database.query("SELECT * FROM TimetableAdditional").use {
while (it.moveToNext()) {
val id = it.getLong(it.getColumnIndexOrThrow("id"))
val timestampLocalStart = it.getLong(it.getColumnIndexOrThrow("start"))
val timestampLocalEnd = it.getLong(it.getColumnIndexOrThrow("end"))
val timestampUtcStart = timestampLocalStart.timestampLocalToUTC()
val timestampUtcEnd = timestampLocalEnd.timestampLocalToUTC()
database.execSQL("UPDATE TimetableAdditional SET start = $timestampUtcStart, end = $timestampUtcEnd WHERE id = $id")
}
}
}
private fun Long.timestampLocalToUTC(): Long = Instant.ofEpochMilli(this)
.atZone(ZoneOffset.UTC)
.withZoneSameLocal(ZoneId.of("Europe/Warsaw"))
.withZoneSameInstant(ZoneId.systemDefault())
.toInstant()
.toEpochMilli()
}

View file

@ -0,0 +1,23 @@
package io.github.wulkanowy.data.db.migrations
import androidx.room.migration.Migration
import androidx.sqlite.db.SupportSQLiteDatabase
class Migration49 : Migration(48, 49) {
override fun migrate(database: SupportSQLiteDatabase) {
database.execSQL("DROP TABLE IF EXISTS SchoolAnnouncements")
database.execSQL(
"""
CREATE TABLE IF NOT EXISTS `SchoolAnnouncements` (
`user_login_id` INTEGER NOT NULL,
`date` INTEGER NOT NULL,
`subject` TEXT NOT NULL,
`content` TEXT NOT NULL,
`id` INTEGER PRIMARY KEY AUTOINCREMENT NOT NULL,
`is_notified` INTEGER NOT NULL)
""".trimIndent()
)
}
}

View file

@ -0,0 +1,21 @@
package io.github.wulkanowy.data.db.migrations
import androidx.room.migration.Migration
import androidx.sqlite.db.SupportSQLiteDatabase
class Migration50 : Migration(49, 50) {
override fun migrate(database: SupportSQLiteDatabase) {
database.execSQL("DROP TABLE IF EXISTS MobileDevices")
database.execSQL(
"""
CREATE TABLE IF NOT EXISTS `MobileDevices` (
`user_login_id` INTEGER NOT NULL,
`device_id` INTEGER NOT NULL,
`name` TEXT NOT NULL,
`date` INTEGER NOT NULL,
`id` INTEGER PRIMARY KEY AUTOINCREMENT NOT NULL)
""".trimIndent()
)
}
}

View file

@ -0,0 +1,88 @@
package io.github.wulkanowy.data.db.migrations
import androidx.room.migration.Migration
import androidx.sqlite.db.SupportSQLiteDatabase
class Migration51 : Migration(50, 51) {
override fun migrate(database: SupportSQLiteDatabase) {
createMailboxTable(database)
recreateMessagesTable(database)
recreateMessageAttachmentsTable(database)
recreateRecipientsTable(database)
deleteReportingUnitTable(database)
}
private fun createMailboxTable(database: SupportSQLiteDatabase) {
database.execSQL("DROP TABLE IF EXISTS Mailboxes")
database.execSQL(
"""
CREATE TABLE IF NOT EXISTS `Mailboxes` (
`globalKey` TEXT NOT NULL,
`fullName` TEXT NOT NULL,
`userName` TEXT NOT NULL,
`userLoginId` INTEGER NOT NULL,
`studentName` TEXT NOT NULL,
`schoolNameShort` TEXT NOT NULL,
`type` TEXT NOT NULL,
PRIMARY KEY(`globalKey`)
)""".trimIndent()
)
}
private fun recreateMessagesTable(database: SupportSQLiteDatabase) {
database.execSQL("DROP TABLE IF EXISTS Messages")
database.execSQL(
"""
CREATE TABLE IF NOT EXISTS `Messages` (
`message_global_key` TEXT NOT NULL,
`mailbox_key` TEXT NOT NULL,
`message_id` INTEGER NOT NULL,
`correspondents` TEXT NOT NULL,
`subject` TEXT NOT NULL,
`date` INTEGER NOT NULL,
`folder_id` INTEGER NOT NULL,
`unread` INTEGER NOT NULL,
`has_attachments` INTEGER NOT NULL,
`id` INTEGER PRIMARY KEY AUTOINCREMENT NOT NULL,
`is_notified` INTEGER NOT NULL,
`content` TEXT NOT NULL,
`sender` TEXT, `recipients` TEXT
)""".trimIndent()
)
}
private fun recreateMessageAttachmentsTable(database: SupportSQLiteDatabase) {
database.execSQL("DROP TABLE IF EXISTS MessageAttachments")
database.execSQL(
"""
CREATE TABLE IF NOT EXISTS `MessageAttachments` (
`real_id` INTEGER NOT NULL,
`message_global_key` TEXT NOT NULL,
`url` TEXT NOT NULL,
`filename` TEXT NOT NULL,
PRIMARY KEY(`real_id`)
)""".trimIndent()
)
}
private fun recreateRecipientsTable(database: SupportSQLiteDatabase) {
database.execSQL("DROP TABLE IF EXISTS Recipients")
database.execSQL(
"""
CREATE TABLE IF NOT EXISTS `Recipients` (
`mailboxGlobalKey` TEXT NOT NULL,
`studentMailboxGlobalKey` TEXT NOT NULL,
`fullName` TEXT NOT NULL,
`userName` TEXT NOT NULL,
`schoolShortName` TEXT NOT NULL,
`type` TEXT NOT NULL,
`id` INTEGER PRIMARY KEY AUTOINCREMENT NOT NULL
)""".trimIndent()
)
}
private fun deleteReportingUnitTable(database: SupportSQLiteDatabase) {
database.execSQL("DROP TABLE IF EXISTS ReportingUnits")
}
}

View file

@ -0,0 +1,57 @@
package io.github.wulkanowy.data.db.migrations
import androidx.room.migration.Migration
import androidx.sqlite.db.SupportSQLiteDatabase
class Migration53 : Migration(52, 53) {
override fun migrate(database: SupportSQLiteDatabase) {
createMailboxTable(database)
recreateMessagesTable(database)
}
private fun createMailboxTable(database: SupportSQLiteDatabase) {
database.execSQL("DROP TABLE IF EXISTS Mailboxes")
database.execSQL(
"""
CREATE TABLE IF NOT EXISTS `Mailboxes` (
`globalKey` TEXT NOT NULL,
`email` TEXT NOT NULL,
`symbol` TEXT NOT NULL,
`schoolId` TEXT NOT NULL,
`fullName` TEXT NOT NULL,
`userName` TEXT NOT NULL,
`studentName` TEXT NOT NULL,
`schoolNameShort` TEXT NOT NULL,
`type` TEXT NOT NULL,
PRIMARY KEY(`globalKey`)
)""".trimIndent()
)
}
private fun recreateMessagesTable(database: SupportSQLiteDatabase) {
database.execSQL("DROP TABLE IF EXISTS Messages")
database.execSQL(
"""
CREATE TABLE IF NOT EXISTS `Messages` (
`email` TEXT NOT NULL,
`message_global_key` TEXT NOT NULL,
`mailbox_key` TEXT NOT NULL,
`message_id` INTEGER NOT NULL,
`correspondents` TEXT NOT NULL,
`subject` TEXT NOT NULL,
`date` INTEGER NOT NULL,
`folder_id` INTEGER NOT NULL,
`unread` INTEGER NOT NULL,
`read_by` INTEGER,
`unread_by` INTEGER,
`has_attachments` INTEGER NOT NULL,
`id` INTEGER PRIMARY KEY AUTOINCREMENT NOT NULL,
`is_notified` INTEGER NOT NULL,
`content` TEXT NOT NULL,
`sender` TEXT,
`recipients` TEXT
)""".trimIndent()
)
}
}

View file

@ -0,0 +1,12 @@
package io.github.wulkanowy.data.enums
enum class AppTheme(val value: String) {
SYSTEM("system"),
LIGHT("light"),
DARK("dark"),
BLACK("black");
companion object {
fun getByValue(value: String) = values().find { it.value == value } ?: LIGHT
}
}

View file

@ -0,0 +1,13 @@
package io.github.wulkanowy.data.enums
import java.io.Serializable
enum class GradeColorTheme(val value: String) : Serializable {
VULCAN("vulcan"),
MATERIAL("material"),
GRADE_COLOR("grade_color");
companion object {
fun getByValue(value: String) = values().find { it.value == value } ?: VULCAN
}
}

View file

@ -0,0 +1,11 @@
package io.github.wulkanowy.data.enums
enum class GradeExpandMode(val value: String) {
ONE("one"),
UNLIMITED("any"),
ALWAYS_EXPANDED("always");
companion object {
fun getByValue(value: String) = values().find { it.value == value } ?: ONE
}
}

View file

@ -0,0 +1,11 @@
package io.github.wulkanowy.data.enums
enum class GradeSortingMode(val value: String) {
ALPHABETIC("alphabetic"),
DATE("date"),
AVERAGE("average");
companion object {
fun getByValue(value: String) = values().find { it.value == value } ?: ALPHABETIC
}
}

View file

@ -0,0 +1,11 @@
package io.github.wulkanowy.data.enums
enum class TimetableMode(val value: String) {
WHOLE_PLAN("yes"),
ONLY_CURRENT_GROUP("no"),
SMALL_OTHER_GROUP("small");
companion object {
fun getByValue(value: String) = values().find { it.value == value } ?: ONLY_CURRENT_GROUP
}
}

View file

@ -10,7 +10,7 @@ fun List<SdkConference>.mapToEntities(semester: Semester) = map {
diaryId = semester.diaryId,
agenda = it.agenda,
conferenceId = it.id,
date = it.date,
date = it.dateZoned.toInstant(),
presentOnConference = it.presentOnConference,
subject = it.subject,
title = it.title

View file

@ -6,7 +6,7 @@ import io.github.wulkanowy.sdk.pojo.DirectorInformation as SdkDirectorInformatio
fun List<SdkDirectorInformation>.mapToEntities(student: Student) = map {
SchoolAnnouncement(
studentId = student.studentId,
userLoginId = student.userLoginId,
date = it.date,
subject = it.subject,
content = it.content,

View file

@ -0,0 +1,20 @@
package io.github.wulkanowy.data.mappers
import io.github.wulkanowy.data.db.entities.Mailbox
import io.github.wulkanowy.data.db.entities.MailboxType
import io.github.wulkanowy.data.db.entities.Student
import io.github.wulkanowy.sdk.pojo.Mailbox as SdkMailbox
fun List<SdkMailbox>.mapToEntities(student: Student) = map {
Mailbox(
globalKey = it.globalKey,
fullName = it.fullName,
userName = it.userName,
studentName = it.studentName,
schoolNameShort = it.schoolNameShort,
type = MailboxType.valueOf(it.type.name),
email = student.email,
symbol = student.symbol,
schoolId = student.schoolSymbol,
)
}

View file

@ -1,40 +1,36 @@
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.data.db.entities.*
import io.github.wulkanowy.sdk.pojo.MailboxType
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 {
fun List<SdkMessage>.mapToEntities(student: Student, mailbox: Mailbox?, allMailboxes: List<Mailbox>) = 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",
messageGlobalKey = it.globalKey,
mailboxKey = mailbox?.globalKey ?: allMailboxes.find { box ->
box.fullName == it.mailbox
}?.globalKey!!,
email = student.email,
messageId = it.id,
correspondents = it.correspondents,
subject = it.subject.trim(),
date = it.date ?: LocalDateTime.now(),
date = it.dateZoned.toInstant(),
folderId = it.folderId,
unread = it.unread ?: false,
removed = it.removed,
hasAttachments = it.hasAttachments
unread = it.unread,
unreadBy = it.unreadBy,
readBy = it.readBy,
hasAttachments = it.hasAttachments,
).apply {
content = it.content.orEmpty()
unreadBy = it.unreadBy ?: 0
readBy = it.readBy ?: 0
}
}
fun List<SdkMessageAttachment>.mapToEntities() = map {
fun List<SdkMessageAttachment>.mapToEntities(messageGlobalKey: String) = map {
MessageAttachment(
realId = it.id,
messageId = it.messageId,
oneDriveId = it.oneDriveId,
messageGlobalKey = messageGlobalKey,
realId = it.url.hashCode(),
url = it.url,
filename = it.filename
)
@ -42,12 +38,11 @@ fun List<SdkMessageAttachment>.mapToEntities() = map {
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
fullName = it.fullName,
userName = it.userName,
studentName = it.userName,
mailboxGlobalKey = it.mailboxGlobalKey,
schoolNameShort = it.schoolShortName,
type = MailboxType.valueOf(it.type.name),
)
}

View file

@ -1,15 +1,15 @@
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.db.entities.Student
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
import io.github.wulkanowy.sdk.pojo.Token as SdkToken
fun List<SdkDevice>.mapToEntities(semester: Semester) = map {
fun List<SdkDevice>.mapToEntities(student: Student) = map {
MobileDevice(
userLoginId = semester.studentId,
date = it.createDate,
userLoginId = student.userLoginId,
date = it.createDateZoned.toInstant(),
deviceId = it.id,
name = it.name
)

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