Compare commits
980 commits
Author | SHA1 | Date | |
---|---|---|---|
![]() |
afc16e3d17 | ||
![]() |
59f6f5c212 | ||
![]() |
86f8763e69 | ||
![]() |
157becb017 | ||
![]() |
83ca9a7060 | ||
![]() |
1033be4503 | ||
![]() |
e67066f3ae | ||
![]() |
bc22808b0e | ||
![]() |
e05abb3539 | ||
![]() |
6153c7b97d | ||
![]() |
e574e5e2ec | ||
![]() |
e6571a1dfc | ||
![]() |
d566de0282 | ||
![]() |
558db061f5 | ||
![]() |
190f40ede8 | ||
![]() |
4b795d6ef5 | ||
![]() |
d139bd5b14 | ||
![]() |
bf34cb0c1e | ||
![]() |
eed091aad2 | ||
![]() |
535206056d | ||
![]() |
f2cb3b4f9e | ||
![]() |
54372e0a55 | ||
![]() |
5c17c38d1d | ||
![]() |
f68a8e4215 | ||
![]() |
70c2cb7dbf | ||
![]() |
7f6fd60821 | ||
![]() |
62c04fb205 | ||
![]() |
10c36f19bf | ||
![]() |
37d756b8fe | ||
![]() |
de1bc4809f | ||
![]() |
3d6ec93cde | ||
![]() |
c293c76398 | ||
![]() |
09e07a1713 | ||
![]() |
71f1a55437 | ||
![]() |
d9e22af5ef | ||
![]() |
bc0689a30d | ||
![]() |
9d47127921 | ||
![]() |
08a3bd77bd | ||
![]() |
9fe1151a04 | ||
![]() |
793952cb44 | ||
![]() |
d64a21b50c | ||
![]() |
274f9dde07 | ||
![]() |
5a884a4c56 | ||
![]() |
c55fd98179 | ||
![]() |
ffc0cd840b | ||
![]() |
96067946d0 | ||
![]() |
9339e7d916 | ||
![]() |
b4117aa62e | ||
![]() |
dc3a941e24 | ||
![]() |
b67ecbba4b | ||
![]() |
1175740ba2 | ||
![]() |
378ed0100f | ||
![]() |
cf87339ac4 | ||
![]() |
c23a90f104 | ||
![]() |
d337be0f40 | ||
![]() |
cf7c6f78ea | ||
![]() |
efa68f5044 | ||
![]() |
b9be85d99c | ||
![]() |
dfc4553fc6 | ||
![]() |
08c9539abe | ||
![]() |
fd18583df2 | ||
![]() |
7c4f1c7b22 | ||
![]() |
bdb6c962ea | ||
![]() |
f1c217b087 | ||
![]() |
4b6277abf5 | ||
![]() |
344e0d55ff | ||
![]() |
89a6a98bbf | ||
![]() |
fcc7dc0913 | ||
![]() |
1b74bffc06 | ||
![]() |
0f11f14c3e | ||
![]() |
e70fe6f097 | ||
![]() |
b70649f136 | ||
![]() |
7b13684137 | ||
![]() |
c4689fcbb3 | ||
![]() |
d8f644c5b4 | ||
![]() |
c808bf2e61 | ||
![]() |
0fb55bd6c6 | ||
![]() |
c5dfea788c | ||
![]() |
120e5c9171 | ||
![]() |
a97039a727 | ||
![]() |
e9ba65f8f6 | ||
![]() |
a264abf814 | ||
![]() |
0a2eb07844 | ||
![]() |
bfab265ccf | ||
![]() |
cd59166efb | ||
![]() |
06ed5f6079 | ||
![]() |
6b70583573 | ||
![]() |
c3cbaa6ac2 | ||
![]() |
f61d820d6f | ||
![]() |
03ad5527f8 | ||
![]() |
cce736410b | ||
![]() |
8c515bd03f | ||
![]() |
8dcb3ed45d | ||
![]() |
4f3f24ac10 | ||
![]() |
d074e5c9b3 | ||
![]() |
d2d1d1dba7 | ||
![]() |
891e241d1a | ||
![]() |
5c4a3d578b | ||
![]() |
fcf0adfd80 | ||
![]() |
c42a47ac48 | ||
![]() |
fa48b033af | ||
![]() |
808927a58a | ||
![]() |
dc717c9fb5 | ||
![]() |
a2804d813a | ||
![]() |
847ab6149a | ||
![]() |
dc74d2877b | ||
![]() |
6534176685 | ||
![]() |
9542b9f231 | ||
![]() |
dbba61a99f | ||
![]() |
c2496a15b8 | ||
![]() |
facf84d9a8 | ||
![]() |
459c8330f9 | ||
![]() |
0c8e2632a2 | ||
![]() |
b17e9deca0 | ||
![]() |
c296e72c30 | ||
![]() |
637125e1fc | ||
![]() |
445bfda801 | ||
![]() |
ebde42328a | ||
![]() |
a0bf14b576 | ||
![]() |
2e7caabde3 | ||
![]() |
bb052fd4c9 | ||
![]() |
28ef8c6761 | ||
![]() |
15e8e096ed | ||
![]() |
6007de017f | ||
![]() |
775b5122ef | ||
![]() |
fed00122d7 | ||
![]() |
426bee882c | ||
![]() |
d37de197fc | ||
![]() |
447ece3696 | ||
![]() |
a73f39e59c | ||
![]() |
f912aac140 | ||
![]() |
3caabd3e0e | ||
![]() |
88576271e2 | ||
![]() |
b088551005 | ||
![]() |
130e11a629 | ||
![]() |
d5e0ae7b37 | ||
![]() |
e6f56a74a4 | ||
![]() |
1bc59cfa7f | ||
![]() |
41bae262a5 | ||
![]() |
ae65228805 | ||
![]() |
391ee6e621 | ||
![]() |
0a87df3d82 | ||
![]() |
cb4ae21903 | ||
![]() |
679cf2554d | ||
![]() |
d473d53879 | ||
![]() |
6531061b48 | ||
![]() |
3347e8fba8 | ||
![]() |
84067126a1 | ||
![]() |
da9bebe923 | ||
![]() |
b371fd6709 | ||
![]() |
884d443c5b | ||
![]() |
df58aa78ae | ||
![]() |
2131e892ad | ||
![]() |
63380d3e12 | ||
![]() |
c572a91b38 | ||
![]() |
20dde6e896 | ||
![]() |
042b66ca5c | ||
![]() |
8d8990761a | ||
![]() |
a07741b5c5 | ||
![]() |
f851a4d2c5 | ||
![]() |
c8d069c787 | ||
![]() |
5ce30a3000 | ||
![]() |
26e0f43fa0 | ||
![]() |
08c1bedca1 | ||
![]() |
15537586c4 | ||
![]() |
a04ba4ae10 | ||
![]() |
57ea6379ab | ||
![]() |
c3abe50ed4 | ||
![]() |
f48caf9f70 | ||
![]() |
9a413c14c3 | ||
![]() |
8915c5dd8e | ||
![]() |
e7561d4794 | ||
![]() |
820b99dbc7 | ||
![]() |
aff0fb3a60 | ||
![]() |
d3bf5c3e0a | ||
![]() |
dec2703cc7 | ||
![]() |
edd1c9442e | ||
![]() |
18568c86be | ||
![]() |
84d0ba525f | ||
![]() |
6290663f02 | ||
![]() |
be046a1ddd | ||
![]() |
96ee4bd9e5 | ||
![]() |
923af85d18 | ||
![]() |
ce36e86bb2 | ||
![]() |
a4f455b38f | ||
![]() |
01b8bd9d4a | ||
![]() |
cfcc051ce4 | ||
![]() |
0b0993be9a | ||
![]() |
d07b0dbc98 | ||
![]() |
daa7b54dab | ||
![]() |
de9fcb9af9 | ||
![]() |
40e0934504 | ||
![]() |
009ec433be | ||
![]() |
e1d82d70ee | ||
![]() |
7a9ba04ff4 | ||
![]() |
513b4b7d3e | ||
![]() |
ce4157933f | ||
![]() |
5d1085a64a | ||
![]() |
a00f2dcbda | ||
![]() |
b52a6f7f61 | ||
![]() |
5146e44574 | ||
![]() |
90e1cea679 | ||
![]() |
c9b506ae10 | ||
![]() |
14ebdad7b2 | ||
![]() |
210308695b | ||
![]() |
d5cc2263f5 | ||
![]() |
47e3f2dc58 | ||
![]() |
6dc16b288d | ||
![]() |
daf97be9ad | ||
![]() |
2bb2190410 | ||
![]() |
aff1a7030d | ||
![]() |
8877322357 | ||
![]() |
bc672e94f8 | ||
![]() |
a03bcf8e62 | ||
![]() |
20673c4ead | ||
![]() |
5321d00ee9 | ||
![]() |
e6b2acabd5 | ||
![]() |
bfd7f688ab | ||
![]() |
ba02531aa4 | ||
![]() |
210c3a0e28 | ||
![]() |
68f0ecc45c | ||
![]() |
0965d03f1a | ||
![]() |
496641f594 | ||
![]() |
684c258e2d | ||
![]() |
5e96917508 | ||
![]() |
17096ad11b | ||
![]() |
bd883c9f38 | ||
![]() |
6520f8a0d7 | ||
![]() |
2eee50ad81 | ||
![]() |
8560fd7e81 | ||
![]() |
f718147ae9 | ||
![]() |
cd12c4c891 | ||
![]() |
65f114ce05 | ||
![]() |
497083be97 | ||
![]() |
e26860ea5a | ||
![]() |
094df212b4 | ||
![]() |
cc22985dc5 | ||
![]() |
ad9a2711c4 | ||
![]() |
daf44c531c | ||
![]() |
4e12eb1552 | ||
![]() |
c846cc999f | ||
![]() |
47d430292c | ||
![]() |
5e1ff2243f | ||
![]() |
a35bef58f2 | ||
![]() |
0005d84974 | ||
![]() |
19558cb871 | ||
![]() |
45e884127f | ||
![]() |
c87085a226 | ||
![]() |
79b970256f | ||
![]() |
70f038f15f | ||
![]() |
9cabd7ef08 | ||
![]() |
d89e4ccfdf | ||
![]() |
1bcc4d199e | ||
![]() |
2e85e88c5d | ||
![]() |
6ab67fe25b | ||
![]() |
8563277a89 | ||
![]() |
e458cc90b0 | ||
![]() |
651e3a21b9 | ||
![]() |
f6b969cfb1 | ||
![]() |
d2aa940d46 | ||
![]() |
ab435a72ea | ||
![]() |
a56f4b8745 | ||
![]() |
d003b0897c | ||
![]() |
581bb2de77 | ||
![]() |
495e385228 | ||
![]() |
10ba36ba44 | ||
![]() |
eae396424f | ||
![]() |
a7891bb266 | ||
![]() |
6e82409dbc | ||
![]() |
984db18be3 | ||
![]() |
c99bc96c08 | ||
![]() |
3e7030abc2 | ||
![]() |
6dad3b299b | ||
![]() |
5e997f5a3e | ||
![]() |
601d573283 | ||
![]() |
6ae6ca7fbb | ||
![]() |
c3d38afc3d | ||
![]() |
4e19964249 | ||
![]() |
a6c0efcb81 | ||
![]() |
fcc71c0d5f | ||
![]() |
a59d10b6c1 | ||
![]() |
a48e4eb4ee | ||
![]() |
2a3668bb18 | ||
![]() |
804d0d9113 | ||
![]() |
88b893e6c0 | ||
![]() |
2874a7495e | ||
![]() |
40d8f7a93d | ||
![]() |
84cd51205f | ||
![]() |
bac1832f27 | ||
![]() |
8bf1e22407 | ||
![]() |
e9f43f925c | ||
![]() |
aa632edf5c | ||
![]() |
57315d75c6 | ||
![]() |
4552bc85b0 | ||
![]() |
6b7795118c | ||
![]() |
1960782d8e | ||
![]() |
8836be3766 | ||
![]() |
8697993149 | ||
![]() |
b88c7eb4e4 | ||
![]() |
9066bce0d5 | ||
![]() |
f15b90782a | ||
![]() |
0642bf7d73 | ||
![]() |
981d6d559c | ||
![]() |
39327ff3ea | ||
![]() |
b098ac029b | ||
![]() |
7e0e2fbb67 | ||
![]() |
8a181c747c | ||
![]() |
68fdb167c2 | ||
![]() |
17563d1a4b | ||
![]() |
370881104e | ||
![]() |
62b1b18326 | ||
![]() |
214e43bd4b | ||
![]() |
358e0850ad | ||
![]() |
c183428107 | ||
![]() |
6de937703a | ||
![]() |
10cb2b70f1 | ||
![]() |
9230db3f99 | ||
![]() |
66e58ab74e | ||
![]() |
99b7af64c0 | ||
![]() |
4295dd6246 | ||
![]() |
fb2d92c749 | ||
![]() |
07b1969a35 | ||
![]() |
886403bf1e | ||
![]() |
e8b21c1429 | ||
![]() |
007d62e61d | ||
![]() |
f88d44f0ec | ||
![]() |
4401df6203 | ||
![]() |
e6f23ab35b | ||
![]() |
eea20ced57 | ||
![]() |
b7134221cb | ||
![]() |
8be605629a | ||
![]() |
1a3d580116 | ||
![]() |
a62ed54d07 | ||
![]() |
36a570eeb0 | ||
![]() |
8ed8b5a33c | ||
![]() |
26c749c219 | ||
![]() |
1d910f8d66 | ||
![]() |
de11644e9b | ||
![]() |
621db49fbf | ||
![]() |
b593795844 | ||
![]() |
0f800b61f6 | ||
![]() |
94fd303f8e | ||
![]() |
09a134d442 | ||
![]() |
58ea2c530e | ||
![]() |
84e4167dbd | ||
![]() |
54e9ea6478 | ||
![]() |
4c8d9c8f7f | ||
![]() |
e7550f7a43 | ||
![]() |
ac86737050 | ||
![]() |
e3122127c0 | ||
![]() |
d6918077bf | ||
![]() |
9d0366d010 | ||
![]() |
3d0cd11ba4 | ||
![]() |
64dbbd54b4 | ||
![]() |
539be586ce | ||
![]() |
a240fd5d5f | ||
![]() |
4e69cfe23c | ||
![]() |
2ab0a57a41 | ||
![]() |
ebf9e741c2 | ||
![]() |
e8075e30e4 | ||
![]() |
1839d7cb8f | ||
![]() |
2d84b0775a | ||
![]() |
426379ec17 | ||
![]() |
8315759c83 | ||
![]() |
04393e60bb | ||
![]() |
031a17ea50 | ||
![]() |
60501fcd72 | ||
![]() |
8e607d48f7 | ||
![]() |
e02d93f979 | ||
![]() |
76514e2d72 | ||
![]() |
689012131f | ||
![]() |
6cdcf92782 | ||
![]() |
9c8bcbfdd3 | ||
![]() |
0b83a66b85 | ||
![]() |
9711cc868c | ||
![]() |
f8cb7599e6 | ||
![]() |
7636618e23 | ||
![]() |
5bc54c12f1 | ||
![]() |
e10e530dee | ||
![]() |
d69118b085 | ||
![]() |
dc90549b9d | ||
![]() |
b552dbc904 | ||
![]() |
a6a1678b47 | ||
![]() |
7a46ef5f19 | ||
![]() |
f9e0f7b390 | ||
![]() |
9211baf7ec | ||
![]() |
de6131f4f5 | ||
![]() |
2cb11e443c | ||
![]() |
a43ffcdef4 | ||
![]() |
6615e68430 | ||
![]() |
36daa7ccc1 | ||
![]() |
6e5481f345 | ||
![]() |
ba1c14ca0e | ||
![]() |
c69bb2ef71 | ||
![]() |
9cb4754132 | ||
![]() |
5ba8289c87 | ||
![]() |
258782c648 | ||
![]() |
c568bc1515 | ||
![]() |
da668f93cf | ||
![]() |
037dbd792f | ||
![]() |
7ec7afed87 | ||
![]() |
bea50e6db5 | ||
![]() |
6a00e75816 | ||
![]() |
957adaf6ee | ||
![]() |
827fb33eeb | ||
![]() |
19c96ee83f | ||
![]() |
5a7f52c773 | ||
![]() |
dddeff802f | ||
![]() |
91f6310892 | ||
![]() |
0389642543 | ||
![]() |
8528e0beff | ||
![]() |
e665a8f18b | ||
![]() |
6d5acbad2c | ||
![]() |
7217d0f753 | ||
![]() |
16a5d88dfb | ||
![]() |
646a46727f | ||
![]() |
f5e9197f98 | ||
![]() |
b47f26684b | ||
![]() |
3a03b5f1c6 | ||
![]() |
3d0dcead50 | ||
![]() |
b64b41c11c | ||
![]() |
77c5330f91 | ||
![]() |
2b55ec02ff | ||
![]() |
49ebae6e63 | ||
![]() |
44a9db48a6 | ||
![]() |
0008a72be1 | ||
![]() |
a43acaaa07 | ||
![]() |
e6c9abb4e5 | ||
![]() |
3b9451184c | ||
![]() |
45d1727dbe | ||
![]() |
8d7b611c44 | ||
![]() |
c3adb9b6d6 | ||
![]() |
d87283eb31 | ||
![]() |
d139c22782 | ||
![]() |
e557021ad9 | ||
![]() |
37af5de25c | ||
![]() |
db6c84775b | ||
![]() |
72d8b4aa84 | ||
![]() |
170b7c4379 | ||
![]() |
79e9e1a780 | ||
![]() |
98dcc62bb7 | ||
![]() |
ea0fb00bde | ||
![]() |
4aa6b0b995 | ||
![]() |
57d11e825b | ||
![]() |
2f43b6e552 | ||
![]() |
765f8a2d1f | ||
![]() |
04c727a0c8 | ||
![]() |
55518cb044 | ||
![]() |
cebd1aa75d | ||
![]() |
4a38a0be70 | ||
![]() |
b4b9d91ea6 | ||
![]() |
a6a2bcff3b | ||
![]() |
2979d8b62a | ||
![]() |
aba2068a84 | ||
![]() |
076948a680 | ||
![]() |
1cfabe43a5 | ||
![]() |
02b87c8c6a | ||
![]() |
eb94e06d54 | ||
![]() |
d3b3939d26 | ||
![]() |
9c5d2fbf84 | ||
![]() |
428e40d7fe | ||
![]() |
9c819835ca | ||
![]() |
626169de11 | ||
![]() |
72ef5f428e | ||
![]() |
4ae3f7b016 | ||
![]() |
7c94837af0 | ||
![]() |
2a91346155 | ||
![]() |
ec6d18968f | ||
![]() |
b61e63249c | ||
![]() |
d73aa605f9 | ||
![]() |
14f4808434 | ||
![]() |
2bc6d7ad0d | ||
![]() |
888052cd9c | ||
![]() |
bdc2281fdc | ||
![]() |
d01edc2312 | ||
![]() |
484a3aa731 | ||
![]() |
51be23470f | ||
![]() |
19495ffce9 | ||
![]() |
bd766d33db | ||
![]() |
ff8b3f8837 | ||
![]() |
e678e6d7f9 | ||
![]() |
f6f3447f1d | ||
![]() |
e1c1f305c4 | ||
![]() |
c8c9001277 | ||
![]() |
3422951e47 | ||
![]() |
3278c11cce | ||
![]() |
e00dea51f1 | ||
![]() |
5bf411039d | ||
![]() |
62ca394c9a | ||
![]() |
255b89bbb3 | ||
![]() |
f7987f4b29 | ||
![]() |
0b583439dd | ||
![]() |
ca481dc6f5 | ||
![]() |
f6a92a4cc3 | ||
![]() |
55a6219a42 | ||
![]() |
ad653f10df | ||
![]() |
7a780486f6 | ||
![]() |
c01b0eff9d | ||
![]() |
3a4614e2b7 | ||
![]() |
44ee8859b1 | ||
![]() |
3dd7878ae5 | ||
![]() |
0305a005ab | ||
![]() |
2229f0e3e9 | ||
![]() |
d9aab7afa2 | ||
![]() |
0558f30646 | ||
![]() |
238f257c6c | ||
![]() |
40372e7cea | ||
![]() |
b65a060fca | ||
![]() |
c1ed748188 | ||
![]() |
b911521ccc | ||
![]() |
b046679542 | ||
![]() |
3decc95a20 | ||
![]() |
c301198006 | ||
![]() |
190a5f2067 | ||
![]() |
27e1a07eec | ||
![]() |
64feae9f1c | ||
![]() |
085158721e | ||
![]() |
44888b048d | ||
![]() |
b9a12e46bf | ||
![]() |
2fe5e62e72 | ||
![]() |
6305e1a908 | ||
![]() |
6bf7a2e26c | ||
![]() |
34487175d8 | ||
![]() |
f02db914bf | ||
![]() |
18e0a59e2b | ||
![]() |
e4371af284 | ||
![]() |
44d5f69de1 | ||
![]() |
d13e0adb00 | ||
![]() |
e60e573ac0 | ||
![]() |
91dbc9e3d7 | ||
![]() |
8ccbea2c21 | ||
![]() |
211cb5e4f2 | ||
![]() |
b60c59216d | ||
![]() |
d20f3180cf | ||
![]() |
17761af9d6 | ||
![]() |
067817bace | ||
![]() |
51800d91b2 | ||
![]() |
3640c4f249 | ||
![]() |
05aa38b591 | ||
![]() |
983dcd8656 | ||
![]() |
59cf4fb222 | ||
![]() |
d6ebcc97e3 | ||
![]() |
047579c394 | ||
![]() |
a90fd4b776 | ||
![]() |
03d3a5db11 | ||
![]() |
bf5e61490d | ||
![]() |
d87fa589a8 | ||
![]() |
1fff1c2b14 | ||
![]() |
58d66b6e70 | ||
![]() |
202d13d509 | ||
![]() |
db808de06c | ||
![]() |
d8dae09f39 | ||
![]() |
32640e0796 | ||
![]() |
4e80441167 | ||
![]() |
075cfb20b1 | ||
![]() |
56e4e9be5e | ||
![]() |
53c798ebdb | ||
![]() |
022a4d1ea2 | ||
![]() |
dfa25d8445 | ||
![]() |
b2efe0d981 | ||
![]() |
2a7f846d3f | ||
![]() |
da5817d08a | ||
![]() |
cacf2f651a | ||
![]() |
605c816a32 | ||
![]() |
1587be2fa8 | ||
![]() |
00b23ca20c | ||
![]() |
34db20ab0c | ||
![]() |
0d271d925a | ||
![]() |
b7da43a52a | ||
![]() |
44af5d59fb | ||
![]() |
bc776993a9 | ||
![]() |
9a19ce9ca4 | ||
![]() |
6855296de4 | ||
![]() |
800a31f160 | ||
![]() |
8b83b37b09 | ||
![]() |
43e95cfdc6 | ||
![]() |
ae2a697e01 | ||
![]() |
b695c7f600 | ||
![]() |
3a1a383383 | ||
![]() |
97810d02ab | ||
![]() |
30b337a364 | ||
![]() |
8f6c847562 | ||
![]() |
e5d54c95f3 | ||
![]() |
eb5ad81ec1 | ||
![]() |
3aa9f0ca2f | ||
![]() |
8e587358aa | ||
![]() |
4492f4a864 | ||
![]() |
b453225941 | ||
![]() |
13ccfda009 | ||
![]() |
95ffb0a687 | ||
![]() |
f131edf857 | ||
![]() |
bd2d26418a | ||
![]() |
aeb3b2a030 | ||
![]() |
7bc5219d81 | ||
![]() |
6cb4ea4b0f | ||
![]() |
0bdd33ef4a | ||
![]() |
792de4cd3d | ||
![]() |
3f5fbbc71b | ||
![]() |
206b40ce1b | ||
![]() |
43c56b5534 | ||
![]() |
a1076539dc | ||
![]() |
3071e19584 | ||
![]() |
f2130998ec | ||
![]() |
8a5ca8c91f | ||
![]() |
fada13e2d3 | ||
![]() |
6e19eb943d | ||
![]() |
c70fe3430c | ||
![]() |
3c48264539 | ||
![]() |
539cf2207b | ||
![]() |
f0e897713c | ||
![]() |
a448092008 | ||
![]() |
f5b46707ff | ||
![]() |
e6247d4428 | ||
![]() |
d0869b235a | ||
![]() |
464900d95b | ||
![]() |
368274239e | ||
![]() |
ee33197494 | ||
![]() |
d3ea743707 | ||
![]() |
976d4b8ce2 | ||
![]() |
b77fc0d32a | ||
![]() |
bd3716609e | ||
![]() |
5b87cc9009 | ||
![]() |
4f7be8d2cb | ||
![]() |
8733e7782f | ||
![]() |
e03b0dfa01 | ||
![]() |
efafd2094a | ||
![]() |
1560335749 | ||
![]() |
5bee155f1e | ||
![]() |
c9dc9a323f | ||
![]() |
87e7e00705 | ||
![]() |
57681b35ea | ||
![]() |
8fb09d7b7d | ||
![]() |
168f750863 | ||
![]() |
3e1acbd3bf | ||
![]() |
21ef2adcf6 | ||
![]() |
3f6159e976 | ||
![]() |
555b5ec112 | ||
![]() |
60a9bcae46 | ||
![]() |
eeb1341c1f | ||
![]() |
c77b50d51b | ||
![]() |
8644ce32d5 | ||
![]() |
94506aca52 | ||
![]() |
eee4e1f4b5 | ||
![]() |
c1942d012f | ||
![]() |
fe846b463a | ||
![]() |
0ea2e68249 | ||
![]() |
be0445b227 | ||
![]() |
48249f3093 | ||
![]() |
8d7110735d | ||
![]() |
94957850c3 | ||
![]() |
fa2cfc8427 | ||
![]() |
3d467c43ba | ||
![]() |
b76032044d | ||
![]() |
495b84204c | ||
![]() |
ea4b299de6 | ||
![]() |
acb5e2afd4 | ||
![]() |
50863d6ac2 | ||
![]() |
e15eb03299 | ||
![]() |
be48791d51 | ||
![]() |
c0e1a5b401 | ||
![]() |
cb1b467a21 | ||
![]() |
f14346ff32 | ||
![]() |
af8108a649 | ||
![]() |
5743928126 | ||
![]() |
388d37bf9c | ||
![]() |
d572fc737f | ||
![]() |
47b0f1b527 | ||
![]() |
1afa7ecf3c | ||
![]() |
9139febbdf | ||
![]() |
2dd0b56333 | ||
![]() |
3b970209a5 | ||
![]() |
6f590eb194 | ||
![]() |
b20b8fb243 | ||
![]() |
7e4a212951 | ||
![]() |
6dfeed3a26 | ||
![]() |
06a27199ee | ||
![]() |
76039e5eb9 | ||
![]() |
6a4aaff8d6 | ||
![]() |
9e2985864a | ||
![]() |
412057b512 | ||
![]() |
963caadced | ||
![]() |
8388a8a5fc | ||
![]() |
a801c8f8be | ||
![]() |
9d8ad73e63 | ||
![]() |
182f6c8a81 | ||
![]() |
1e4a3536cf | ||
![]() |
169a314664 | ||
![]() |
904eed648b | ||
![]() |
3bb94adece | ||
![]() |
105b70fcad | ||
![]() |
b4bf7c7589 | ||
![]() |
ff425d6d2b | ||
![]() |
4fceb854b3 | ||
![]() |
3adac154b4 | ||
![]() |
a320cf8f7c | ||
![]() |
1ed0884dfd | ||
![]() |
021e9726c6 | ||
![]() |
3c438757e3 | ||
![]() |
99c4a65df5 | ||
![]() |
2c442fc87b | ||
![]() |
44ba0d76de | ||
![]() |
17aa77ad41 | ||
![]() |
c18302b812 | ||
![]() |
de8e9bde49 | ||
![]() |
000cbd11a2 | ||
![]() |
5e3b89636f | ||
![]() |
dd085a14fa | ||
![]() |
bfe558d887 | ||
![]() |
4841a0439d | ||
![]() |
cac76857c4 | ||
![]() |
6b8b7c9143 | ||
![]() |
53584026dc | ||
![]() |
7900ad913f | ||
![]() |
8ec844a8fe | ||
![]() |
19ff953ab2 | ||
![]() |
e29c211cf2 | ||
![]() |
2492a9c204 | ||
![]() |
61de1de532 | ||
![]() |
b5862da776 | ||
![]() |
e0c802bf67 | ||
![]() |
dcac138ff8 | ||
![]() |
23411a608f | ||
![]() |
87facd2663 | ||
![]() |
bad0776cab | ||
![]() |
a063aabc7c | ||
![]() |
1fdbdf34b9 | ||
![]() |
624fd71dbb | ||
![]() |
dfa10883d3 | ||
![]() |
aff40df707 | ||
![]() |
42f9594210 | ||
![]() |
3e3a080b70 | ||
![]() |
39534aeda4 | ||
![]() |
e39b053d2d | ||
![]() |
28fd7460cb | ||
![]() |
82b207b03a | ||
![]() |
4984cb9b26 | ||
![]() |
e2ba265048 | ||
![]() |
d1cd497a23 | ||
![]() |
dd5ce752da | ||
![]() |
e5e95e7dec | ||
![]() |
f5e4c63fed | ||
![]() |
70d42bb864 | ||
![]() |
82df5b9515 | ||
![]() |
6568c4abf8 | ||
![]() |
d79b1c9a58 | ||
![]() |
26565b627a | ||
![]() |
c0a53cb90c | ||
![]() |
2bcbac5ab3 | ||
![]() |
5581fdcab8 | ||
![]() |
6a8161cd98 | ||
![]() |
e0b067fadd | ||
![]() |
f37ddfe00f | ||
![]() |
3a887f597b | ||
![]() |
52d359827e | ||
![]() |
a70ccbb0d0 | ||
![]() |
2b6386c522 | ||
![]() |
60ae14719d | ||
![]() |
a4594b2853 | ||
![]() |
6578d2eb49 | ||
![]() |
e543c0aa2c | ||
![]() |
17c80416fe | ||
![]() |
f2cb7f741b | ||
![]() |
51d9e9b9af | ||
![]() |
b1e1b801b5 | ||
![]() |
04ff05c22a | ||
![]() |
81c9144448 | ||
![]() |
70d456a6dc | ||
![]() |
b55c05aaed | ||
![]() |
01fd146c99 | ||
![]() |
5d849b3ada | ||
![]() |
1a4eaec47f | ||
![]() |
5b9d40a4f9 | ||
![]() |
e6e9d201ce | ||
![]() |
9128e0b55f | ||
![]() |
7f893a8868 | ||
![]() |
89f92ed027 | ||
![]() |
99e06f6539 | ||
![]() |
12da5e5381 | ||
![]() |
a7bb026c1b | ||
![]() |
8ce59a3098 | ||
![]() |
a1d4b3d19e | ||
![]() |
64cc49055b | ||
![]() |
91ece39517 | ||
![]() |
a99e742472 | ||
![]() |
d332369872 | ||
![]() |
205bcf9c22 | ||
![]() |
344d404238 | ||
![]() |
8b2dc514f4 | ||
![]() |
bee62d4769 | ||
![]() |
fb36fb379a | ||
![]() |
a2c4f4a51d | ||
![]() |
b0d713dc0c | ||
![]() |
5a2a0e3d6d | ||
![]() |
7fe638130e | ||
![]() |
9763208688 | ||
![]() |
295fd0fd90 | ||
![]() |
c052f31424 | ||
![]() |
3486d52a26 | ||
![]() |
88c5c7d9dc | ||
![]() |
315e9b0595 | ||
![]() |
3eba89aeb9 | ||
![]() |
1680ad233e | ||
![]() |
93bc4e92a9 | ||
![]() |
7536f98e6e | ||
![]() |
afee97a706 | ||
![]() |
73a92497ed | ||
![]() |
67cef0f6d9 | ||
![]() |
6ca5e11371 | ||
![]() |
05a597313b | ||
![]() |
33d540e1c9 | ||
![]() |
d115372c3b | ||
![]() |
e637896ad3 | ||
![]() |
ce802cc737 | ||
![]() |
bf342ed289 | ||
![]() |
40ec5bbe86 | ||
![]() |
41dbd2d25f | ||
![]() |
f263b5534a | ||
![]() |
7ed4787496 | ||
![]() |
1428887204 | ||
![]() |
0fc828f006 | ||
![]() |
13906a7d62 | ||
![]() |
3c0dda9a82 | ||
![]() |
c42333cd35 | ||
![]() |
c675dc8b84 | ||
![]() |
5e9853b043 | ||
![]() |
c7fdcc2bbd | ||
![]() |
8a00ae95b8 | ||
![]() |
a1ebf6c6ad | ||
![]() |
ada5854d10 | ||
![]() |
fe191bb0df | ||
![]() |
9eb091fbf4 | ||
![]() |
57e760844f | ||
![]() |
20644a7a67 | ||
![]() |
b3109aed0b | ||
![]() |
9ba999feb0 | ||
![]() |
7c9e85793b | ||
![]() |
6af8263952 | ||
![]() |
83d1d860a6 | ||
![]() |
8830240182 | ||
![]() |
c3061e75b5 | ||
![]() |
5f1bb7c1d0 | ||
![]() |
c6f4c868b2 | ||
![]() |
c634c64e70 | ||
![]() |
da2b7dbf7e | ||
![]() |
26267507eb | ||
![]() |
24d0c5057b | ||
![]() |
b05026a6e6 | ||
![]() |
8036f3d7f7 | ||
![]() |
23e309d38e | ||
![]() |
bf92c6b2e9 | ||
![]() |
c00b5edaf7 | ||
![]() |
cb09ca13dc | ||
![]() |
3d68b8e629 | ||
![]() |
b3173581e5 | ||
![]() |
ddac1d0f98 | ||
![]() |
db6a359bea | ||
![]() |
e7221e6a32 | ||
![]() |
db9c2640c7 | ||
![]() |
ca67e144e4 | ||
![]() |
da2346ed83 | ||
![]() |
a87818f3d0 | ||
![]() |
5092f8c0bf | ||
![]() |
af0787c0b1 | ||
![]() |
721b4ac797 | ||
![]() |
26a69092cc | ||
![]() |
2bd0c75055 | ||
![]() |
d6f3c57293 | ||
![]() |
518387e7bb | ||
![]() |
ca6dfbf2d0 | ||
![]() |
da6d8a74fd | ||
![]() |
e35e4ef152 | ||
![]() |
40fc6ec2e0 | ||
![]() |
b91973aec3 | ||
![]() |
047e70ad46 | ||
![]() |
112c1eb793 | ||
![]() |
c479b31670 | ||
![]() |
43ed8c8fce | ||
![]() |
613fa44c27 | ||
![]() |
f21216286d | ||
![]() |
7298d0d75a | ||
![]() |
ee0fbcdfd6 | ||
![]() |
c362ad12c7 | ||
![]() |
8a1a712d6d | ||
![]() |
1f0f6b3e51 | ||
![]() |
11487e77ca | ||
![]() |
fd0fd4df55 | ||
![]() |
d95a33787b | ||
![]() |
e5661098d9 | ||
![]() |
d020b01794 | ||
![]() |
d8b1264024 | ||
![]() |
cddd17650b | ||
![]() |
a0f9c70036 | ||
![]() |
2e05416fb5 | ||
![]() |
d32ebd66de | ||
![]() |
c6a99f1000 | ||
![]() |
bafe52e310 | ||
![]() |
e08abc1fc2 | ||
![]() |
2a74b11cce | ||
![]() |
b0b3ccfd53 | ||
![]() |
6c68456f7a | ||
![]() |
3e8e9b4ecc | ||
![]() |
d6ebc343d5 | ||
![]() |
73be416807 | ||
![]() |
0cb65a29ba | ||
![]() |
13198f2ab4 | ||
![]() |
cd92f37435 | ||
![]() |
5d8fb376ab | ||
![]() |
47150364d8 | ||
![]() |
792b123598 | ||
![]() |
acf5c8e9ba | ||
![]() |
53561668fc | ||
![]() |
7cfe58d311 | ||
![]() |
cd51fac621 | ||
![]() |
adde5541e2 | ||
![]() |
6e56d3ff06 | ||
![]() |
ec761f6329 | ||
![]() |
6363c90e37 | ||
![]() |
c30f105be5 | ||
![]() |
9f85b2206a | ||
![]() |
42515fd084 | ||
![]() |
9a7c04fe7b | ||
![]() |
debb21f5f9 | ||
![]() |
18b9bf42e1 | ||
![]() |
6ded83d132 | ||
![]() |
71d37a1c6c | ||
![]() |
3975d06cde | ||
![]() |
ee168bafe0 | ||
![]() |
42ed7e0ae1 | ||
![]() |
0e92447974 | ||
![]() |
40492e6c01 | ||
![]() |
69a1193154 | ||
![]() |
0f65af8958 | ||
![]() |
2ad1d086e0 | ||
![]() |
f8b7baef24 | ||
![]() |
90be9d1add | ||
![]() |
20f931c5cc | ||
![]() |
9997b1adbb | ||
![]() |
eb616eedc7 | ||
![]() |
a5de39a366 | ||
![]() |
57bc2b2533 | ||
![]() |
d1ce16d2b1 | ||
![]() |
54fb01cd0d | ||
![]() |
370cfbf22a | ||
![]() |
d198a2ba21 | ||
![]() |
580ad58dd6 | ||
![]() |
b5f7c5f318 | ||
![]() |
7e2de594a4 | ||
![]() |
36984e08b5 | ||
![]() |
f8031e1eca | ||
![]() |
5bc49b2e74 | ||
![]() |
ba81b4b465 | ||
![]() |
5cc31a7c5e | ||
![]() |
de70719d38 | ||
![]() |
9f315b3af1 | ||
![]() |
d5187d1808 | ||
![]() |
ca7d977342 | ||
![]() |
062985c5a0 | ||
![]() |
8922d7d48d | ||
![]() |
3ba16f2903 | ||
![]() |
6a1a347579 | ||
![]() |
6c4f27aff5 | ||
![]() |
f6dce0fbda | ||
![]() |
1ac42bb56d | ||
![]() |
b0a674b471 | ||
![]() |
1c1a90c12f | ||
![]() |
d4ee1f8b98 | ||
![]() |
152382a0c9 | ||
![]() |
776972514a | ||
![]() |
e072bf9fe3 | ||
![]() |
927415f9a3 | ||
![]() |
76b2ab1f25 | ||
![]() |
c9a0bbda01 | ||
![]() |
cbabe44461 | ||
![]() |
5c313f986c | ||
![]() |
f2682c6d30 | ||
![]() |
3571f8bd04 | ||
![]() |
dfcd5fc4d0 | ||
![]() |
b8ea0ab0f9 | ||
![]() |
4434d6f024 | ||
![]() |
8cee882c08 |
12
.editorconfig
Normal 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
|
|
@ -1,3 +1,12 @@
|
|||
---
|
||||
name: Bug report
|
||||
about: Utwórz raport błędu, aby pomóc nam ulepszyć Wulkanowego
|
||||
title: ''
|
||||
labels: ''
|
||||
assignees: ''
|
||||
|
||||
---
|
||||
|
||||
## Co powinno się dziać
|
||||
|
||||
|
20
.github/ISSUE_TEMPLATE/feature_request.md
vendored
Normal file
|
@ -0,0 +1,20 @@
|
|||
---
|
||||
name: Feature request
|
||||
about: Zaproponuj nowy pomysł dla Wulkanowego
|
||||
title: ''
|
||||
labels: ''
|
||||
assignees: ''
|
||||
|
||||
---
|
||||
|
||||
** Czy Twoja prośba o funkcję jest związana z problemem? Proszę opisz.**
|
||||
Jasny i zwięzły opis problemu. Np. Zawsze jestem sfrustrowany, gdy [...]
|
||||
|
||||
** Opisz żądane rozwiązanie **
|
||||
Jasny i zwięzły opis tego, co chcesz, aby się wydarzyło.
|
||||
|
||||
** Opisz alternatywy, które rozważałeś **
|
||||
Jasny i zwięzły opis wszelkich rozważanych alternatywnych rozwiązań lub funkcji.
|
||||
|
||||
** Dodatkowy kontekst **
|
||||
Dodaj inny kontekst lub zrzuty ekranu dotyczące żądania funkcji tutaj.
|
12
.github/dependabot.yml
vendored
Normal file
|
@ -0,0 +1,12 @@
|
|||
version: 2
|
||||
updates:
|
||||
- package-ecosystem: gradle
|
||||
directory: "/"
|
||||
schedule:
|
||||
interval: weekly
|
||||
open-pull-requests-limit: 10
|
||||
target-branch: develop
|
||||
ignore:
|
||||
- dependency-name: io.github.wulkanowy:sdk
|
||||
reviewers:
|
||||
- Faierbel
|
79
.github/workflows/deploy-store.yml
vendored
Normal file
|
@ -0,0 +1,79 @@
|
|||
name: Deploy release
|
||||
|
||||
on:
|
||||
release:
|
||||
types: [ created ]
|
||||
|
||||
jobs:
|
||||
|
||||
deploy-google-play:
|
||||
name: Google Play
|
||||
runs-on: ubuntu-latest
|
||||
timeout-minutes: 10
|
||||
environment: google-play
|
||||
steps:
|
||||
- uses: actions/checkout@v3
|
||||
- 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: Decrypt keys
|
||||
env:
|
||||
ENCRYPT_KEY: ${{ secrets.ENCRYPT_KEY }}
|
||||
SERVICES_ENCRYPT_KEY: ${{ secrets.SERVICES_ENCRYPT_KEY }}
|
||||
run: |
|
||||
gpg --yes --batch --passphrase=$SERVICES_ENCRYPT_KEY ./app/src/release/google-services.json.gpg
|
||||
gpg --yes --batch --passphrase=$ENCRYPT_KEY ./app/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 }}
|
||||
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: AppGallery
|
||||
runs-on: ubuntu-latest
|
||||
timeout-minutes: 10
|
||||
environment: app-gallery
|
||||
steps:
|
||||
- uses: actions/checkout@v3
|
||||
- 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: Decrypt keys
|
||||
env:
|
||||
ENCRYPT_KEY: ${{ secrets.ENCRYPT_KEY }}
|
||||
SERVICES_ENCRYPT_KEY: ${{ secrets.SERVICES_ENCRYPT_KEY }}
|
||||
run: |
|
||||
gpg --yes --batch --passphrase=$SERVICES_ENCRYPT_KEY ./app/src/release/agconnect-services.json.gpg
|
||||
gpg --yes --batch --passphrase=$ENCRYPT_KEY ./app/upload-key.jks.gpg
|
||||
- name: Prepare credentials
|
||||
env:
|
||||
AGC_CREDENTIALS: ${{ secrets.AGC_CREDENTIALS }}
|
||||
run: echo $AGC_CREDENTIALS > ./app/src/release/agconnect-credentials.json
|
||||
- name: Build and publish HMS version
|
||||
env:
|
||||
PLAY_STORE_PASSWORD: ${{ secrets.PLAY_STORE_PASSWORD }}
|
||||
PLAY_KEY_ALIAS: ${{ secrets.PLAY_KEY_ALIAS }}
|
||||
PLAY_KEY_PASSWORD: ${{ secrets.PLAY_KEY_PASSWORD }}
|
||||
SET_BUILD_TIMESTAMP: ${{ secrets.SET_BUILD_TIMESTAMP }}
|
||||
run: ./gradlew bundleHmsRelease --stacktrace && ./gradlew publishHuaweiAppGalleryHmsRelease --stacktrace
|
146
.github/workflows/deploy-test.yml
vendored
Normal file
|
@ -0,0 +1,146 @@
|
|||
name: Deploy DEV
|
||||
|
||||
on:
|
||||
push:
|
||||
# branches: [ develop ]
|
||||
branches: [ '!*' ]
|
||||
pull_request_target:
|
||||
# branches: [ develop ]
|
||||
branches: [ '!*' ]
|
||||
|
||||
workflow_dispatch:
|
||||
|
||||
jobs:
|
||||
|
||||
deploy-appcenter:
|
||||
name: App Center
|
||||
runs-on: ubuntu-latest
|
||||
timeout-minutes: 10
|
||||
environment: app-center
|
||||
steps:
|
||||
- uses: actions/checkout@v3
|
||||
- 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: Set run number with offset
|
||||
env:
|
||||
BUILD_NUMBER_OFFSET: ${{ secrets.BUILD_NUMBER_OFFSET }}
|
||||
run: echo "RUN_NUMBER=$((GITHUB_RUN_NUMBER+BUILD_NUMBER_OFFSET))" >> $GITHUB_ENV
|
||||
- name: Prepare build configuration
|
||||
run: |
|
||||
sed -i -e "s#applicationIdSuffix \".dev\"#applicationIdSuffix \".${GITHUB_HEAD_REF//[-.\/]/_}\"#" app/build.gradle
|
||||
sed -i -e "s#.dev\"#.${GITHUB_HEAD_REF//[-.\/]/_}\"#" app/src/debug/google-services.json
|
||||
sed -i -e "s#.dev\"#.${GITHUB_HEAD_REF//[-.\/]/_}\"#" app/src/debug/agconnect-services.json
|
||||
sed -i -e '/versionNameSuffix/d' app/build.gradle
|
||||
- name: Add signing config
|
||||
run: |
|
||||
cat >> app/build.gradle <<EOF
|
||||
android.signingConfigs.debug {
|
||||
storeFile file("bitrise.jks")
|
||||
storePassword System.getenv("BITRISE_KEYSTORE_PASSWORD")
|
||||
keyAlias System.getenv("BITRISE_KEY_ALIAS")
|
||||
keyPassword System.getenv("BITRISE_KEY_PASSWORD")
|
||||
}
|
||||
EOF
|
||||
- name: Decrypt keys
|
||||
env:
|
||||
BITRISE_ENCRYPT_KEY: ${{ secrets.BITRISE_ENCRYPT_KEY }}
|
||||
run: |
|
||||
gpg --yes --batch --passphrase=$BITRISE_ENCRYPT_KEY ./app/bitrise.jks.gpg
|
||||
- name: Bump version
|
||||
uses: chkfung/android-version-actions@v1.1
|
||||
with:
|
||||
gradlePath: app/build.gradle
|
||||
versionCode: ${{ env.RUN_NUMBER }}
|
||||
versionName: ${{ env.RUN_NUMBER }}-${{ github.head_ref }}
|
||||
- name: Build apk
|
||||
env:
|
||||
BITRISE_KEYSTORE_PASSWORD: ${{ secrets.BITRISE_KEYSTORE_PASSWORD }}
|
||||
BITRISE_KEY_ALIAS: ${{ secrets.BITRISE_KEY_ALIAS }}
|
||||
BITRISE_KEY_PASSWORD: ${{ secrets.BITRISE_KEY_PASSWORD }}
|
||||
run: ./gradlew assembleFdroidDebug --stacktrace
|
||||
- name: Upload apk to github artifacts
|
||||
uses: actions/upload-artifact@v3
|
||||
with:
|
||||
name: wulkanowyDEV-${{ env.RUN_NUMBER }}.apk
|
||||
path: app/build/outputs/apk/fdroid/debug/app-fdroid-debug.apk
|
||||
- name: Deploy to app center
|
||||
uses: wzieba/AppCenter-Github-Action@v1
|
||||
with:
|
||||
appName: wulkanowy/wulkanowy
|
||||
token: ${{ secrets.APP_CENTER_TOKEN }}
|
||||
group: Testers
|
||||
file: app/build/outputs/apk/fdroid/debug/app-fdroid-debug.apk
|
||||
notifyTesters: true
|
||||
debug: true
|
||||
|
||||
deploy-app-distribution:
|
||||
name: App Distribution
|
||||
runs-on: ubuntu-latest
|
||||
timeout-minutes: 10
|
||||
environment: app-distribution
|
||||
if: github.event_name != 'pull_request_target'
|
||||
steps:
|
||||
- uses: actions/checkout@v3
|
||||
- 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: Set run number with offset
|
||||
env:
|
||||
BUILD_NUMBER_OFFSET: ${{ secrets.BUILD_NUMBER_OFFSET }}
|
||||
run: echo "RUN_NUMBER=$((GITHUB_RUN_NUMBER+BUILD_NUMBER_OFFSET))" >> $GITHUB_ENV
|
||||
- name: Add signing config
|
||||
run: |
|
||||
cat >> app/build.gradle <<EOF
|
||||
android.signingConfigs.debug {
|
||||
storeFile file("bitrise.jks")
|
||||
storePassword System.getenv("BITRISE_KEYSTORE_PASSWORD")
|
||||
keyAlias System.getenv("BITRISE_KEY_ALIAS")
|
||||
keyPassword System.getenv("BITRISE_KEY_PASSWORD")
|
||||
}
|
||||
EOF
|
||||
- name: Decrypt keys
|
||||
env:
|
||||
BITRISE_ENCRYPT_KEY: ${{ secrets.BITRISE_ENCRYPT_KEY }}
|
||||
BITRISE_SERVICES_ENCRYPT_KEY: ${{ secrets.BITRISE_SERVICES_ENCRYPT_KEY }}
|
||||
run: |
|
||||
gpg --yes --batch --passphrase=$BITRISE_SERVICES_ENCRYPT_KEY ./app/src/debug/google-services.json.gpg
|
||||
gpg --yes --batch --passphrase=$BITRISE_ENCRYPT_KEY ./app/bitrise.jks.gpg
|
||||
- name: Bump version
|
||||
uses: chkfung/android-version-actions@v1.1
|
||||
with:
|
||||
gradlePath: app/build.gradle
|
||||
versionCode: ${{ env.RUN_NUMBER }}
|
||||
versionName: ${{ env.RUN_NUMBER }}
|
||||
- name: Build apk
|
||||
env:
|
||||
BITRISE_KEYSTORE_PASSWORD: ${{ secrets.BITRISE_KEYSTORE_PASSWORD }}
|
||||
BITRISE_KEY_ALIAS: ${{ secrets.BITRISE_KEY_ALIAS }}
|
||||
BITRISE_KEY_PASSWORD: ${{ secrets.BITRISE_KEY_PASSWORD }}
|
||||
run: ./gradlew assemblePlayDebug -PenableFirebase --stacktrace
|
||||
- name: Upload apk to github artifacts
|
||||
uses: actions/upload-artifact@v3
|
||||
with:
|
||||
name: wulkanowyDEV-${{ env.RUN_NUMBER }}-dev.apk
|
||||
path: app/build/outputs/apk/play/debug/app-play-debug.apk
|
||||
- name: Deploy to app distribution
|
||||
uses: wzieba/Firebase-Distribution-Github-Action@v1
|
||||
with:
|
||||
appId: ${{ secrets.FIREBASE_APP_ID }}
|
||||
token: ${{ secrets.FIREBASE_TOKEN }}
|
||||
groups: discord
|
||||
file: app/build/outputs/apk/play/debug/app-play-debug.apk
|
88
.github/workflows/test.yml
vendored
Normal file
|
@ -0,0 +1,88 @@
|
|||
name: Tests
|
||||
|
||||
on:
|
||||
push:
|
||||
branches: [ master, develop ]
|
||||
tags: [ '*' ]
|
||||
pull_request:
|
||||
branches: [ master, develop ]
|
||||
|
||||
jobs:
|
||||
|
||||
tests-fdroid:
|
||||
name: F-Droid
|
||||
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 testFdroidDebugUnitTest --stacktrace
|
||||
./gradlew jacocoTestReport --stacktrace
|
||||
- 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
|
6
.gitignore
vendored
|
@ -19,6 +19,7 @@ out/
|
|||
# Gradle files
|
||||
.gradle/
|
||||
build/
|
||||
.build-cache
|
||||
|
||||
# Local configuration file (sdk path, etc)
|
||||
local.properties
|
||||
|
@ -113,3 +114,8 @@ Thumbs.db
|
|||
|
||||
!/gradle/wrapper/gradle-wrapper.jar
|
||||
.idea/jarRepositories.xml
|
||||
|
||||
|
||||
app/src/release/agconnect-services.json
|
||||
app/src/release/agconnect-credentials.json
|
||||
.idea/deploymentTargetDropDown.xml
|
||||
|
|
30
.idea/codeStyles/Project.xml
generated
|
@ -2,25 +2,8 @@
|
|||
<code_scheme name="Project" version="173">
|
||||
<option name="LINE_SEPARATOR" value=" " />
|
||||
<JetCodeStyleSettings>
|
||||
<option name="PACKAGES_TO_USE_STAR_IMPORTS">
|
||||
<value>
|
||||
<package name="kotlinx.android.synthetic" withSubpackages="true" static="false" />
|
||||
</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="CONTINUATION_INDENT_IN_PARAMETER_LISTS" value="false" />
|
||||
<option name="CONTINUATION_INDENT_IN_ARGUMENT_LISTS" value="false" />
|
||||
<option name="CONTINUATION_INDENT_FOR_EXPRESSION_BODIES" value="false" />
|
||||
<option name="CONTINUATION_INDENT_FOR_CHAINED_CALLS" value="false" />
|
||||
<option name="CONTINUATION_INDENT_IN_SUPERTYPE_LISTS" value="false" />
|
||||
<option name="CONTINUATION_INDENT_IN_IF_CONDITIONS" value="false" />
|
||||
<option name="CONTINUATION_INDENT_IN_ELVIS" value="false" />
|
||||
<option name="WRAP_ELVIS_EXPRESSIONS" value="0" />
|
||||
<option name="CODE_STYLE_DEFAULTS" value="KOTLIN_OFFICIAL" />
|
||||
</JetCodeStyleSettings>
|
||||
<MarkdownNavigatorCodeStyleSettings>
|
||||
<option name="RIGHT_MARGIN" value="72" />
|
||||
</MarkdownNavigatorCodeStyleSettings>
|
||||
<codeStyleSettings language="XML">
|
||||
<indentOptions>
|
||||
<option name="CONTINUATION_INDENT_SIZE" value="4" />
|
||||
|
@ -134,16 +117,7 @@
|
|||
</arrangement>
|
||||
</codeStyleSettings>
|
||||
<codeStyleSettings language="kotlin">
|
||||
<option name="KEEP_BLANK_LINES_IN_DECLARATIONS" value="1" />
|
||||
<option name="KEEP_BLANK_LINES_IN_CODE" value="1" />
|
||||
<option name="KEEP_BLANK_LINES_BEFORE_RBRACE" value="0" />
|
||||
<option name="ALIGN_MULTILINE_PARAMETERS" value="false" />
|
||||
<option name="METHOD_PARAMETERS_LPAREN_ON_NEXT_LINE" value="true" />
|
||||
<option name="METHOD_PARAMETERS_RPAREN_ON_NEXT_LINE" value="true" />
|
||||
<option name="EXTENDS_LIST_WRAP" value="1" />
|
||||
<indentOptions>
|
||||
<option name="CONTINUATION_INDENT_SIZE" value="4" />
|
||||
</indentOptions>
|
||||
<option name="CODE_STYLE_DEFAULTS" value="KOTLIN_OFFICIAL" />
|
||||
</codeStyleSettings>
|
||||
</code_scheme>
|
||||
</component>
|
31
.travis.yml
|
@ -3,8 +3,8 @@ jdk: oraclejdk8
|
|||
|
||||
env:
|
||||
global:
|
||||
- ANDROID_API_LEVEL=29
|
||||
- ANDROID_BUILD_TOOLS_VERSION=29.0.3
|
||||
- ANDROID_API_LEVEL=30
|
||||
- ANDROID_BUILD_TOOLS_VERSION=30.0.2
|
||||
|
||||
cache:
|
||||
directories:
|
||||
|
@ -14,7 +14,7 @@ cache:
|
|||
branches:
|
||||
only:
|
||||
- develop
|
||||
- 0.19.0
|
||||
- 0.24.0
|
||||
|
||||
android:
|
||||
licenses:
|
||||
|
@ -28,32 +28,37 @@ android:
|
|||
- build-tools-$ANDROID_BUILD_TOOLS_VERSION
|
||||
# The SDK version used to compile your project
|
||||
- android-$ANDROID_API_LEVEL
|
||||
# Additional components
|
||||
# Additional components
|
||||
- extra-google-google_play_services
|
||||
- extra-google-m2repository
|
||||
- extra-android-m2repository
|
||||
- addon-google_apis-google-$ANDROID_API_LEVEL
|
||||
# Android emulator
|
||||
# Android emulator
|
||||
- android-22
|
||||
- sys-img-armeabi-v7a-android-22
|
||||
|
||||
before_install:
|
||||
- yes | sdkmanager "platforms;android-30"
|
||||
- yes | sdkmanager "build-tools;30.0.2"
|
||||
|
||||
before_script:
|
||||
# Launch emulator before the execution
|
||||
- echo no | android create avd --force -n test -t android-22 --abi armeabi-v7a
|
||||
- emulator -avd test -no-audio -no-window &
|
||||
- android-wait-for-emulator
|
||||
- adb shell input keyevent 82 &
|
||||
- "curl -H 'Cache-Control: no-cache' https://raw.githubusercontent.com/fossas/fossa-cli/master/install.sh | sudo bash"
|
||||
# Launch emulator before the execution
|
||||
- echo no | android create avd --force -n test -t android-22 --abi armeabi-v7a
|
||||
- emulator -avd test -no-audio -no-window &
|
||||
- android-wait-for-emulator
|
||||
- adb shell input keyevent 82 &
|
||||
- "curl -H 'Cache-Control: no-cache' https://raw.githubusercontent.com/fossas/fossa-cli/master/install.sh | sudo bash"
|
||||
|
||||
script:
|
||||
- ./gradlew dependencies --stacktrace --daemon
|
||||
- fossa --no-ansi || true
|
||||
- ./gradlew -Pcoverage testPlayDebugUnitTest --stacktrace --daemon
|
||||
- ./gradlew -Pcoverage createFdroidDebugCoverageReport --stacktrace --daemon
|
||||
- ./gradlew -Pcoverage testFdroidDebugUnitTest --stacktrace --daemon
|
||||
- ./gradlew -Pcoverage connectedFdroidDebugAndroidTest --stacktrace --daemon
|
||||
- ./gradlew -Pcoverage jacocoTestReport --stacktrace --daemon
|
||||
- |
|
||||
if [ $TRAVIS_TAG ]; then
|
||||
gpg --yes --batch --passphrase=$SERVICES_ENCRYPT_KEY ./app/src/release/google-services.json.gpg;
|
||||
gpg --yes --batch --passphrase=$SERVICES_ENCRYPT_KEY ./app/src/release/agconnect-services.json.gpg;
|
||||
gpg --yes --batch --passphrase=$ENCRYPT_KEY ./app/key.p12.gpg;
|
||||
gpg --yes --batch --passphrase=$ENCRYPT_KEY ./app/upload-key.jks.gpg;
|
||||
./gradlew publishPlayRelease -PenableFirebase --stacktrace;
|
||||
|
|
2
LICENSE
|
@ -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.
|
||||
|
|
78
README.cs.md
Normal file
|
@ -0,0 +1,78 @@
|
|||
[English version of README](README.en.md)
|
||||
|
||||
[Deutsche Version von README](README.de.md)
|
||||
|
||||
[Polska wersja README](README.md)
|
||||
|
||||
[Slovenská verzia README](README.sk.md)
|
||||
|
||||
# Wulkanowy
|
||||
|
||||
[](https://github.com/wulkanowy/wulkanowy/actions)
|
||||
[](https://codecov.io/gh/wulkanowy/wulkanowy)
|
||||
[](https://discord.gg/vccAQBr)
|
||||
[](https://f-droid.org/packages/io.github.wulkanowy/)
|
||||
[](https://github.com/wulkanowy/wulkanowy/releases)
|
||||
|
||||
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
|
||||
|
||||
|
||||
* [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)
|
74
README.de.md
Normal file
|
@ -0,0 +1,74 @@
|
|||
[Polska wersja README](README.md)
|
||||
|
||||
[English version of README](README.en.md)
|
||||
|
||||
# Wulkanowy
|
||||
|
||||
[](https://github.com/wulkanowy/wulkanowy/actions)
|
||||
[](https://codecov.io/gh/wulkanowy/wulkanowy)
|
||||
[](https://discord.gg/vccAQBr)
|
||||
[](https://f-droid.org/packages/io.github.wulkanowy/)
|
||||
[](https://github.com/wulkanowy/wulkanowy/releases)
|
||||
|
||||
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
|
31
README.en.md
|
@ -1,7 +1,14 @@
|
|||
[Polska wersja README](README.md)
|
||||
|
||||
[Deutsche Version von README](README.de.md)
|
||||
|
||||
[Česká verze README](README.cs.md)
|
||||
|
||||
[Slovenská verzia README](README.sk.md)
|
||||
|
||||
# Wulkanowy
|
||||
[](https://travis-ci.com/wulkanowy/wulkanowy)
|
||||
|
||||
[](https://github.com/wulkanowy/wulkanowy/actions)
|
||||
[](https://codecov.io/gh/wulkanowy/wulkanowy)
|
||||
[](https://discord.gg/vccAQBr)
|
||||
[](https://f-droid.org/packages/io.github.wulkanowy/)
|
||||
|
@ -11,7 +18,7 @@ Unofficial android VULCAN UONET+ register client for both students and their par
|
|||
|
||||
## Features
|
||||
|
||||
* logging in using the email and password OR using token and pin
|
||||
* logging in using the email and password
|
||||
* functions from the register website:
|
||||
* grades
|
||||
* grade statistics
|
||||
|
@ -24,22 +31,29 @@ Unofficial android VULCAN UONET+ register client for both students and their par
|
|||
* homework
|
||||
* notes
|
||||
* lucky number
|
||||
* additional lessons
|
||||
* school conferences
|
||||
* student and school information
|
||||
* calculation of the average independently of school's preferences
|
||||
* notifications, e.g. about a new grade
|
||||
* support for multiple accounts with the ability to rename students
|
||||
* dark and black (AMOLED) theme
|
||||
* offline mode
|
||||
* no ads
|
||||
|
||||
## Download
|
||||
|
||||
You can download the current beta version from the Google Play or the F-Droid store
|
||||
You can download the current version from the Google Play, F-Droid or Huawei AppGallery store
|
||||
|
||||
[<img src="https://play.google.com/intl/en_us/badges/images/generic/en_badge_web_generic.png"
|
||||
alt="Get it on Google Play"
|
||||
height="80">](https://play.google.com/store/apps/details?id=io.github.wulkanowy)
|
||||
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=)
|
||||
|
||||
You can also download a [development version](https://wulkanowy.github.io/#download) that includes new features being prepared for the next release
|
||||
|
||||
|
@ -47,8 +61,8 @@ You can also download a [development version](https://wulkanowy.github.io/#downl
|
|||
|
||||
|
||||
* [Wulkanowy SDK](https://github.com/wulkanowy/sdk)
|
||||
* [RxJava 2](https://github.com/ReactiveX/RxJava)
|
||||
* [Dagger 2](https://github.com/google/dagger)
|
||||
* [Kotlin Coroutines](https://kotlinlang.org/docs/reference/coroutines-overview.html)
|
||||
* [Hilt](https://dagger.dev/hilt/)
|
||||
* [Room](https://developer.android.com/topic/libraries/architecture/room)
|
||||
* [WorkManager](https://developer.android.com/topic/libraries/architecture/workmanager)
|
||||
|
||||
|
@ -56,6 +70,9 @@ You can also download a [development version](https://wulkanowy.github.io/#downl
|
|||
|
||||
Please contribute to the project either by creating a PR or submitting an issue on GitHub.
|
||||
|
||||
For people interested in translating the application into different languages, we provide Crowdin
|
||||
https://crowdin.com/project/wulkanowy2
|
||||
|
||||
## License
|
||||
|
||||
This project is licensed under the Apache License 2.0 - see the [LICENSE](LICENSE) file for details
|
||||
|
|
35
README.md
|
@ -1,7 +1,14 @@
|
|||
[English version of README](README.en.md)
|
||||
|
||||
[Deutsche Version von README](README.de.md)
|
||||
|
||||
[Česká verze README](README.cs.md)
|
||||
|
||||
[Slovenská verzia README](README.sk.md)
|
||||
|
||||
# Wulkanowy
|
||||
[](https://travis-ci.com/wulkanowy/wulkanowy)
|
||||
|
||||
[](https://github.com/wulkanowy/wulkanowy/actions)
|
||||
[](https://codecov.io/gh/wulkanowy/wulkanowy)
|
||||
[](https://discord.gg/vccAQBr)
|
||||
[](https://f-droid.org/packages/io.github.wulkanowy/)
|
||||
|
@ -11,7 +18,7 @@ Nieoficjalny klient dziennika VULCAN UONET+ dla ucznia i rodzica
|
|||
|
||||
## Funkcje
|
||||
|
||||
* logowanie za pomocą e-maila i hasła LUB tokena i pinu
|
||||
* logowanie za pomocą e-maila i hasła
|
||||
* funkcje ze strony internetowej dziennika:
|
||||
* oceny
|
||||
* statystyki ocen
|
||||
|
@ -24,22 +31,29 @@ Nieoficjalny klient dziennika VULCAN UONET+ dla ucznia i rodzica
|
|||
* zadania domowe
|
||||
* uwagi
|
||||
* szczęśliwy numerek
|
||||
* dodatkowe lekcje
|
||||
* zebrania w szkole
|
||||
* informacje o uczniu i szkole
|
||||
* obliczanie średniej niezależnie od preferencji szkoły
|
||||
* powiadomienia np. o nowej ocenie
|
||||
* obsługa wielu kont wraz z możliwością zmiany nazwy ucznia
|
||||
* ciemny i czarny (AMOLED) motyw
|
||||
* tryb offilne
|
||||
* tryb offline
|
||||
* brak reklam
|
||||
|
||||
## Pobierz
|
||||
|
||||
Aktualną wersję beta możesz pobrać ze sklepu Google Play lub F-Droid
|
||||
Aktualną wersję możesz pobrać ze sklepu Google Play, F-Droid lub Huawei AppGallery
|
||||
|
||||
[<img src="https://play.google.com/intl/en_us/badges/images/generic/en_badge_web_generic.png"
|
||||
alt="Pobierz z Google Play"
|
||||
height="80">](https://play.google.com/store/apps/details?id=io.github.wulkanowy)
|
||||
alt="Pobierz z Google Play"
|
||||
height="80">](https://play.google.com/store/apps/details?id=io.github.wulkanowy)
|
||||
[<img src="https://fdroid.gitlab.io/artwork/badge/get-it-on.png"
|
||||
alt="Pobierz z F-Droid"
|
||||
height="80">](https://f-droid.org/packages/io.github.wulkanowy/)
|
||||
[<img src="appgallery_badge.png"
|
||||
alt="Odkrywaj w AppGallery"
|
||||
height="80">](https://appgallery.cloud.huawei.com/ag/n/app/C101440411?channelId=Badge&id=1b3f7fbb700849a9be0dba6b520b2282&s=EB1D3BF9ED9D1564D869B7B94B18016D3CABFCA5AEFB8E29F675FA04E0DC131D&detailType=0&v=)
|
||||
|
||||
|
||||
Możesz także pobrać [wersję rozwojową](https://wulkanowy.github.io/#download), która zawiera nowe funkcje przygotowywane do następnego wydania
|
||||
|
@ -47,9 +61,9 @@ Możesz także pobrać [wersję rozwojową](https://wulkanowy.github.io/#downloa
|
|||
|
||||
## Zbudowana za pomocą
|
||||
|
||||
* [Wulkanowy SDK](https://github.com/wulkanowy/SDK)
|
||||
* [RxJava 2](https://github.com/ReactiveX/RxJava)
|
||||
* [Dagger 2](https://github.com/google/dagger)
|
||||
* [Wulkanowy SDK](https://github.com/wulkanowy/sdk)
|
||||
* [Kotlin Coroutines](https://kotlinlang.org/docs/reference/coroutines-overview.html)
|
||||
* [Hilt](https://dagger.dev/hilt/)
|
||||
* [Room](https://developer.android.com/topic/libraries/architecture/room)
|
||||
* [WorkManager](https://developer.android.com/topic/libraries/architecture/workmanager)
|
||||
|
||||
|
@ -57,6 +71,9 @@ Możesz także pobrać [wersję rozwojową](https://wulkanowy.github.io/#downloa
|
|||
|
||||
Wnieś swój wkład w projekt, tworząc PR lub wysyłając issue na GitHub.
|
||||
|
||||
Dla osób zainteresowanych tłumaczeniem aplikacji na różne języki udostępniamy Crowdina
|
||||
https://crowdin.com/project/wulkanowy2
|
||||
|
||||
## Licencja
|
||||
|
||||
Ten projekt udostępniany jest na licencji Apache License 2.0 - szczegóły w pliku [LICENSE](LICENSE)
|
||||
|
|
78
README.sk.md
Normal file
|
@ -0,0 +1,78 @@
|
|||
[English version of README](README.en.md)
|
||||
|
||||
[Deutsche Version von README](README.de.md)
|
||||
|
||||
[Polska wersja README](README.md)
|
||||
|
||||
[Česká verze README](README.cs.md)
|
||||
|
||||
# Wulkanowy
|
||||
|
||||
[](https://github.com/wulkanowy/wulkanowy/actions)
|
||||
[](https://codecov.io/gh/wulkanowy/wulkanowy)
|
||||
[](https://discord.gg/vccAQBr)
|
||||
[](https://f-droid.org/packages/io.github.wulkanowy/)
|
||||
[](https://github.com/wulkanowy/wulkanowy/releases)
|
||||
|
||||
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
|
||||
|
||||
|
||||
* [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)
|
BIN
app/bitrise.jks.gpg
Normal file
256
app/build.gradle
|
@ -1,43 +1,60 @@
|
|||
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'
|
||||
apply plugin: 'com.google.gms.google-services'
|
||||
apply plugin: 'com.google.firebase.crashlytics'
|
||||
apply plugin: 'com.github.triplet.play'
|
||||
apply plugin: 'ru.cian.huawei-publish'
|
||||
apply plugin: 'com.mikepenz.aboutlibraries.plugin'
|
||||
apply plugin: 'com.huawei.agconnect'
|
||||
apply from: 'jacoco.gradle'
|
||||
apply from: 'sonarqube.gradle'
|
||||
apply from: 'hooks.gradle'
|
||||
|
||||
android {
|
||||
compileSdkVersion 29
|
||||
buildToolsVersion '29.0.3'
|
||||
namespace 'io.github.wulkanowy'
|
||||
compileSdkVersion 32
|
||||
|
||||
defaultConfig {
|
||||
applicationId "io.github.wulkanowy"
|
||||
testApplicationId "io.github.tests.wulkanowy"
|
||||
minSdkVersion 17
|
||||
targetSdkVersion 29
|
||||
versionCode 63
|
||||
versionName "0.19.0"
|
||||
multiDexEnabled true
|
||||
resValue "string", "app_name", "Wulkanowy"
|
||||
minSdkVersion 21
|
||||
targetSdkVersion 32
|
||||
versionCode 114
|
||||
versionName "1.7.5"
|
||||
testInstrumentationRunner "androidx.test.runner.AndroidJUnitRunner"
|
||||
vectorDrawables.useSupportLibrary = true
|
||||
|
||||
resValue "string", "app_name", "Wulkanowy"
|
||||
|
||||
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"
|
||||
arguments += [
|
||||
"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 {
|
||||
androidTest.assets.srcDirs += files("$projectDir/schemas".toString())
|
||||
// https://github.com/robolectric/robolectric/issues/3928#issuecomment-395309991
|
||||
debug.assets.srcDirs += files("$projectDir/schemas".toString())
|
||||
}
|
||||
|
||||
signingConfigs {
|
||||
|
@ -55,48 +72,80 @@ 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"
|
||||
testCoverageEnabled = project.hasProperty('coverage')
|
||||
ext.enableCrashlytics = project.hasProperty("enableFirebase")
|
||||
buildConfigField "String", "MESSAGES_BASE_URL", "\"https://messages.wulkanowy.net.pl\""
|
||||
}
|
||||
}
|
||||
|
||||
flavorDimensions "platform"
|
||||
|
||||
productFlavors {
|
||||
hms {
|
||||
dimension "platform"
|
||||
manifestPlaceholders = [install_channel: "AppGallery"]
|
||||
}
|
||||
|
||||
play {
|
||||
dimension "platform"
|
||||
manifestPlaceholders = [
|
||||
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"]
|
||||
}
|
||||
}
|
||||
|
||||
buildFeatures {
|
||||
viewBinding = true
|
||||
playConfigs {
|
||||
play { enabled.set(true) }
|
||||
}
|
||||
|
||||
lintOptions {
|
||||
disable 'HardwareIds'
|
||||
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 {
|
||||
sourceCompatibility JavaVersion.VERSION_1_8
|
||||
targetCompatibility JavaVersion.VERSION_1_8
|
||||
coreLibraryDesugaringEnabled true
|
||||
sourceCompatibility JavaVersion.VERSION_11
|
||||
targetCompatibility JavaVersion.VERSION_11
|
||||
}
|
||||
|
||||
kotlinOptions {
|
||||
jvmTarget = "1.8"
|
||||
jvmTarget = "11"
|
||||
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 {
|
||||
|
@ -104,108 +153,127 @@ android {
|
|||
}
|
||||
}
|
||||
|
||||
kapt {
|
||||
correctErrorTypes true
|
||||
}
|
||||
|
||||
play {
|
||||
serviceAccountEmail = System.getenv("PLAY_SERVICE_ACCOUNT_EMAIL") ?: "jan@fakelog.cf"
|
||||
serviceAccountCredentials = file('key.p12')
|
||||
defaultToAppBundles = false
|
||||
track = 'alpha'
|
||||
track = 'production'
|
||||
// releaseStatus = com.github.triplet.gradle.androidpublisher.ReleaseStatus.IN_PROGRESS
|
||||
// userFraction = 0.05d
|
||||
updatePriority = 4
|
||||
enabled.set(false)
|
||||
}
|
||||
|
||||
huaweiPublish {
|
||||
instances {
|
||||
hmsRelease {
|
||||
credentialsPath = "$rootDir/app/src/release/agconnect-credentials.json"
|
||||
buildFormat = "aab"
|
||||
deployType = "draft"
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
ext {
|
||||
work_manager = "2.3.4"
|
||||
room = "2.2.5"
|
||||
dagger = "2.28"
|
||||
chucker = "3.2.0"
|
||||
mockk = "1.9.2"
|
||||
}
|
||||
|
||||
configurations.all {
|
||||
resolutionStrategy.force "androidx.constraintlayout:constraintlayout:1.1.3"
|
||||
work_manager = "2.7.1"
|
||||
android_hilt = "1.0.0"
|
||||
room = "2.4.3"
|
||||
chucker = "3.5.2"
|
||||
mockk = "1.12.7"
|
||||
coroutines = "1.6.4"
|
||||
}
|
||||
|
||||
dependencies {
|
||||
implementation "io.github.wulkanowy:sdk:0.19.0"
|
||||
implementation "io.github.wulkanowy:sdk:1.7.5"
|
||||
|
||||
implementation "org.jetbrains.kotlin:kotlin-stdlib-jdk8:$kotlin_version"
|
||||
implementation "androidx.core:core-ktx:1.2.0"
|
||||
implementation "androidx.activity:activity-ktx:1.1.0"
|
||||
implementation "androidx.appcompat:appcompat:1.2.0-rc01"
|
||||
implementation "androidx.appcompat:appcompat-resources:1.1.0"
|
||||
implementation "androidx.fragment:fragment-ktx:1.2.5"
|
||||
implementation "androidx.annotation:annotation:1.1.0"
|
||||
implementation "androidx.multidex:multidex:2.0.1"
|
||||
coreLibraryDesugaring 'com.android.tools:desugar_jdk_libs:1.1.8'
|
||||
|
||||
implementation "androidx.preference:preference-ktx:1.1.1"
|
||||
implementation "androidx.recyclerview:recyclerview:1.1.0"
|
||||
implementation "androidx.viewpager:viewpager:1.0.0"
|
||||
implementation "androidx.swiperefreshlayout:swiperefreshlayout:1.1.0-rc01"
|
||||
implementation "androidx.constraintlayout:constraintlayout:1.1.3"
|
||||
implementation "androidx.coordinatorlayout:coordinatorlayout:1.1.0"
|
||||
implementation "com.google.android.material:material:1.1.0"
|
||||
implementation "com.github.wulkanowy:material-chips-input:2.1.1"
|
||||
implementation "org.jetbrains.kotlinx:kotlinx-serialization-json:1.4.0"
|
||||
implementation "org.jetbrains.kotlinx:kotlinx-coroutines-android:$coroutines"
|
||||
|
||||
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.0"
|
||||
implementation "androidx.fragment:fragment-ktx:1.5.2"
|
||||
implementation "androidx.annotation:annotation:1.4.0"
|
||||
|
||||
implementation "androidx.preference:preference-ktx:1.2.0"
|
||||
implementation "androidx.recyclerview:recyclerview:1.2.1"
|
||||
implementation "androidx.viewpager2:viewpager2:1.1.0-beta01"
|
||||
implementation "androidx.swiperefreshlayout:swiperefreshlayout:1.1.0"
|
||||
implementation "androidx.constraintlayout:constraintlayout:2.1.4"
|
||||
implementation "androidx.coordinatorlayout:coordinatorlayout:1.2.0"
|
||||
implementation "com.google.android.material:material:1.6.1"
|
||||
implementation "com.github.wulkanowy:material-chips-input:2.3.1"
|
||||
implementation "com.github.PhilJay:MPAndroidChart:v3.1.0"
|
||||
implementation "me.zhanghai.android.materialprogressbar:library:1.6.1"
|
||||
implementation 'com.github.lopspower:CircularImageView:4.2.0'
|
||||
|
||||
implementation "androidx.work:work-runtime-ktx:$work_manager"
|
||||
implementation "androidx.work:work-rxjava2:$work_manager"
|
||||
implementation "androidx.work:work-gcm:$work_manager"
|
||||
playImplementation "androidx.work:work-gcm:$work_manager"
|
||||
|
||||
implementation 'com.github.PaulinaSadowska:RxWorkManagerObservers:1.0.0'
|
||||
implementation "androidx.lifecycle:lifecycle-livedata-ktx:2.5.1"
|
||||
|
||||
implementation "androidx.room:room-runtime:$room"
|
||||
implementation "androidx.room:room-rxjava2:$room"
|
||||
implementation "androidx.room:room-ktx:$room"
|
||||
kapt "androidx.room:room-compiler:$room"
|
||||
|
||||
implementation "com.google.dagger:dagger-android-support:$dagger"
|
||||
kapt "com.google.dagger:dagger-compiler:$dagger"
|
||||
kapt "com.google.dagger:dagger-android-processor:$dagger"
|
||||
implementation "com.squareup.inject:assisted-inject-annotations-dagger2:0.5.2"
|
||||
kapt "com.squareup.inject:assisted-inject-processor-dagger2:0.5.2"
|
||||
implementation "com.google.dagger:hilt-android:$hilt_version"
|
||||
kapt "com.google.dagger:hilt-android-compiler:$hilt_version"
|
||||
kapt "androidx.hilt:hilt-compiler:$android_hilt"
|
||||
implementation "androidx.hilt:hilt-work:$android_hilt"
|
||||
|
||||
implementation "com.aurelhubert:ahbottomnavigation:2.3.4"
|
||||
implementation "com.ncapdevi:frag-nav:3.3.0"
|
||||
implementation "com.github.YarikSOffice:lingver:1.2.2"
|
||||
implementation 'com.github.ncapdevi:FragNav:3.3.0'
|
||||
implementation "com.github.YarikSOffice:lingver:1.3.0"
|
||||
|
||||
implementation "com.github.pwittchen:reactivenetwork-rx2:3.0.8"
|
||||
implementation "io.reactivex.rxjava2:rxandroid:2.1.1"
|
||||
implementation "io.reactivex.rxjava2:rxjava:2.2.19"
|
||||
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.google.code.gson:gson:2.8.6"
|
||||
implementation "com.jakewharton.threetenabp:threetenabp:1.2.4"
|
||||
implementation "com.jakewharton.timber:timber:4.7.1"
|
||||
implementation "com.jakewharton.timber:timber:5.0.1"
|
||||
implementation "at.favre.lib:slf4j-timber:1.0.1"
|
||||
implementation "fr.bipi.treessence:treessence:0.3.2"
|
||||
implementation 'com.github.bastienpaulfr:Treessence:1.0.5'
|
||||
implementation "com.mikepenz:aboutlibraries-core:$about_libraries"
|
||||
implementation 'com.wdullaer:materialdatetimepicker:4.2.3'
|
||||
implementation "io.coil-kt:coil:0.11.0"
|
||||
implementation "io.coil-kt:coil:2.2.0"
|
||||
implementation "io.github.wulkanowy:AppKillerManager:3.0.0"
|
||||
implementation 'me.xdrop:fuzzywuzzy:1.3.1'
|
||||
implementation 'me.xdrop:fuzzywuzzy:1.4.0'
|
||||
implementation 'com.fredporciuncula:flow-preferences:1.8.0'
|
||||
|
||||
playImplementation 'com.google.firebase:firebase-analytics:17.4.3'
|
||||
playImplementation 'com.google.firebase:firebase-inappmessaging-display-ktx:19.0.7'
|
||||
playImplementation "com.google.firebase:firebase-inappmessaging-ktx:19.0.7"
|
||||
playImplementation 'com.google.firebase:firebase-messaging:20.2.0'
|
||||
playImplementation 'com.google.firebase:firebase-crashlytics:17.0.1'
|
||||
playImplementation 'com.google.guava:listenablefuture:9999.0-empty-to-avoid-conflict-with-guava'
|
||||
playImplementation platform('com.google.firebase:firebase-bom:30.3.2')
|
||||
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.3'
|
||||
playImplementation 'com.google.android.play:core-ktx:1.8.1'
|
||||
playImplementation 'com.google.android.gms:play-services-ads:21.1.0'
|
||||
|
||||
hmsImplementation 'com.huawei.hms:hianalytics:6.7.0.300'
|
||||
hmsImplementation 'com.huawei.agconnect:agconnect-crash:1.7.1.300'
|
||||
|
||||
releaseImplementation "com.github.ChuckerTeam.Chucker:library-no-op:$chucker"
|
||||
|
||||
debugImplementation "com.github.ChuckerTeam.Chucker:library:$chucker"
|
||||
debugImplementation "com.amitshekhar.android:debug-db:1.0.6"
|
||||
debugImplementation 'com.github.amitshekhariitbhu.Android-Debug-Database:debug-db:1.0.6'
|
||||
debugImplementation 'com.github.haroldadmin:WhatTheStack:1.0.0-alpha04'
|
||||
|
||||
testImplementation "junit:junit:4.13"
|
||||
testImplementation "junit:junit:4.13.2"
|
||||
testImplementation "io.mockk:mockk:$mockk"
|
||||
testImplementation "org.threeten:threetenbp:1.4.4"
|
||||
testImplementation "org.mockito:mockito-inline:3.3.3"
|
||||
testImplementation "org.jetbrains.kotlinx:kotlinx-coroutines-test:$coroutines"
|
||||
testImplementation "org.jetbrains.kotlin:kotlin-test:$kotlin_version"
|
||||
|
||||
androidTestImplementation "androidx.test:core:1.2.0"
|
||||
androidTestImplementation "androidx.test:runner:1.2.0"
|
||||
androidTestImplementation "androidx.test.ext:junit:1.1.1"
|
||||
testImplementation 'org.robolectric:robolectric:4.8.2'
|
||||
testImplementation "androidx.test:runner:1.4.0"
|
||||
testImplementation "androidx.test.ext:junit:1.1.3"
|
||||
testImplementation "androidx.test:core:1.4.0"
|
||||
testImplementation "androidx.room:room-testing:$room"
|
||||
testImplementation "com.google.dagger:hilt-android-testing:$hilt_version"
|
||||
kaptTest "com.google.dagger:hilt-android-compiler:$hilt_version"
|
||||
|
||||
androidTestImplementation "androidx.test:core:1.4.0"
|
||||
androidTestImplementation "androidx.test:runner:1.4.0"
|
||||
androidTestImplementation "androidx.test.ext:junit:1.1.3"
|
||||
androidTestImplementation "io.mockk:mockk-android:$mockk"
|
||||
androidTestImplementation "androidx.room:room-testing:$room"
|
||||
androidTestImplementation "org.jetbrains.kotlin:kotlin-test:$kotlin_version"
|
||||
androidTestImplementation "org.mockito:mockito-android:3.3.3"
|
||||
}
|
||||
|
||||
apply plugin: 'com.google.gms.google-services'
|
||||
|
|
|
@ -1,12 +1,13 @@
|
|||
apply plugin: "jacoco"
|
||||
|
||||
jacoco {
|
||||
toolVersion "0.8.5"
|
||||
reportsDir = file("$buildDir/reports")
|
||||
toolVersion "0.8.7"
|
||||
reportsDirectory.set(file("$buildDir/reports"))
|
||||
}
|
||||
|
||||
tasks.withType(Test) {
|
||||
jacoco.includeNoLocationClasses = true
|
||||
jacoco.excludes = ['jdk.internal.*']
|
||||
}
|
||||
|
||||
task jacocoTestReport(type: JacocoReport) {
|
||||
|
@ -15,8 +16,8 @@ task jacocoTestReport(type: JacocoReport) {
|
|||
description = "Generate Jacoco coverage reports"
|
||||
|
||||
reports {
|
||||
xml.enabled = true
|
||||
html.enabled = true
|
||||
xml.required.set(true)
|
||||
html.required.set(true)
|
||||
}
|
||||
|
||||
def excludes = ['**/R.class',
|
||||
|
@ -35,13 +36,13 @@ task jacocoTestReport(type: JacocoReport) {
|
|||
dir: "$buildDir/intermediates/classes/debug",
|
||||
excludes: excludes
|
||||
) + fileTree(
|
||||
dir: "$buildDir/tmp/kotlin-classes/playDebug",
|
||||
dir: "$buildDir/tmp/kotlin-classes/fdroidDebug",
|
||||
excludes: excludes
|
||||
))
|
||||
|
||||
sourceDirectories.setFrom(files([
|
||||
"src/main/java",
|
||||
"src/play/java"
|
||||
"src/fdroid/java"
|
||||
]))
|
||||
executionData.setFrom(fileTree(
|
||||
dir: project.projectDir,
|
||||
|
|
BIN
app/key.p12.gpg
36
app/proguard-rules.pro
vendored
|
@ -1,40 +1,21 @@
|
|||
# Optimizations
|
||||
-optimizationpasses 5
|
||||
-optimizations !code/simplification/arithmetic,!field/*,!class/merging/*
|
||||
-dontusemixedcaseclassnames
|
||||
-dontskipnonpubliclibraryclasses
|
||||
-dontskipnonpubliclibraryclassmembers
|
||||
-dontpreverify
|
||||
# General
|
||||
-dontobfuscate
|
||||
-allowaccessmodification
|
||||
-repackageclasses ''
|
||||
-verbose
|
||||
|
||||
|
||||
#Keep all wulkanowy files
|
||||
#Config for wulkanowy
|
||||
-keep class io.github.wulkanowy.** {*;}
|
||||
|
||||
|
||||
#Config for anallitycs
|
||||
-keepattributes *Annotation*
|
||||
#Config for firebase crashlitycs
|
||||
-keepattributes SourceFile,LineNumberTable
|
||||
-keep class com.crashlytics.** {*;}
|
||||
-keep public class * extends java.lang.Exception
|
||||
-dontwarn com.crashlytics.**
|
||||
|
||||
|
||||
#Config for OkHttp
|
||||
#Config for Okio and OkHttp
|
||||
-dontwarn javax.annotation.**
|
||||
-keepnames class okhttp3.internal.publicsuffix.PublicSuffixDatabase
|
||||
-dontwarn org.codehaus.mojo.animal_sniffer.*
|
||||
-dontwarn okhttp3.internal.platform.ConscryptPlatform
|
||||
-dontwarn javax.annotation.**
|
||||
|
||||
|
||||
#Config for ReactiveNetwork
|
||||
-dontwarn com.github.pwittchen.reactivenetwork.library.rx2.ReactiveNetwork
|
||||
-dontwarn io.reactivex.functions.Function
|
||||
-dontwarn rx.internal.util.**
|
||||
-dontwarn sun.misc.Unsafe
|
||||
|
||||
|
||||
#Config for MPAndroidChart
|
||||
|
@ -43,10 +24,3 @@
|
|||
|
||||
#Config for Material Components
|
||||
-keep class com.google.android.material.tabs.** { *; }
|
||||
|
||||
|
||||
#Config for About Libraries
|
||||
-keep class .R
|
||||
-keep class **.R$* {
|
||||
<fields>;
|
||||
}
|
||||
|
|
1774
app/schemas/io.github.wulkanowy.data.db.AppDatabase/27.json
Normal file
1842
app/schemas/io.github.wulkanowy.data.db.AppDatabase/28.json
Normal file
1898
app/schemas/io.github.wulkanowy.data.db.AppDatabase/29.json
Normal file
1954
app/schemas/io.github.wulkanowy.data.db.AppDatabase/30.json
Normal file
2136
app/schemas/io.github.wulkanowy.data.db.AppDatabase/31.json
Normal file
2142
app/schemas/io.github.wulkanowy.data.db.AppDatabase/32.json
Normal file
2142
app/schemas/io.github.wulkanowy.data.db.AppDatabase/33.json
Normal file
2142
app/schemas/io.github.wulkanowy.data.db.AppDatabase/34.json
Normal file
2148
app/schemas/io.github.wulkanowy.data.db.AppDatabase/35.json
Normal file
2160
app/schemas/io.github.wulkanowy.data.db.AppDatabase/36.json
Normal file
2204
app/schemas/io.github.wulkanowy.data.db.AppDatabase/37.json
Normal file
2248
app/schemas/io.github.wulkanowy.data.db.AppDatabase/38.json
Normal file
2260
app/schemas/io.github.wulkanowy.data.db.AppDatabase/39.json
Normal file
2316
app/schemas/io.github.wulkanowy.data.db.AppDatabase/40.json
Normal file
2322
app/schemas/io.github.wulkanowy.data.db.AppDatabase/41.json
Normal file
2396
app/schemas/io.github.wulkanowy.data.db.AppDatabase/42.json
Normal file
2408
app/schemas/io.github.wulkanowy.data.db.AppDatabase/43.json
Normal file
2414
app/schemas/io.github.wulkanowy.data.db.AppDatabase/44.json
Normal file
2430
app/schemas/io.github.wulkanowy.data.db.AppDatabase/45.json
Normal file
2430
app/schemas/io.github.wulkanowy.data.db.AppDatabase/46.json
Normal file
2438
app/schemas/io.github.wulkanowy.data.db.AppDatabase/47.json
Normal file
2445
app/schemas/io.github.wulkanowy.data.db.AppDatabase/48.json
Normal file
2445
app/schemas/io.github.wulkanowy.data.db.AppDatabase/49.json
Normal file
2445
app/schemas/io.github.wulkanowy.data.db.AppDatabase/50.json
Normal file
2409
app/schemas/io.github.wulkanowy.data.db.AppDatabase/51.json
Normal file
|
@ -1,29 +0,0 @@
|
|||
package io.github.wulkanowy.data.repositories
|
||||
|
||||
import io.github.wulkanowy.data.db.entities.Student
|
||||
import org.threeten.bp.LocalDateTime
|
||||
|
||||
fun getStudent(): Student {
|
||||
return Student(
|
||||
email = "test",
|
||||
password = "test123",
|
||||
schoolSymbol = "23",
|
||||
scrapperBaseUrl = "fakelog.cf",
|
||||
loginType = "AUTO",
|
||||
isCurrent = true,
|
||||
studentName = "",
|
||||
schoolShortName = "",
|
||||
schoolName = "",
|
||||
studentId = 0,
|
||||
classId = 1,
|
||||
symbol = "",
|
||||
registrationDate = LocalDateTime.now(),
|
||||
className = "",
|
||||
loginMode = "API",
|
||||
certificateKey = "",
|
||||
privateKey = "",
|
||||
mobileBaseUrl = "",
|
||||
userLoginId = 0,
|
||||
isParent = false
|
||||
)
|
||||
}
|
|
@ -1,19 +0,0 @@
|
|||
package io.github.wulkanowy.data.repositories
|
||||
|
||||
import com.github.pwittchen.reactivenetwork.library.rx2.internet.observing.InternetObservingStrategy
|
||||
import com.github.pwittchen.reactivenetwork.library.rx2.internet.observing.error.ErrorHandler
|
||||
import io.reactivex.Observable
|
||||
import io.reactivex.Single
|
||||
|
||||
class TestInternetObservingStrategy : InternetObservingStrategy {
|
||||
|
||||
override fun checkInternetConnectivity(host: String?, port: Int, timeoutInMs: Int, httpResponse: Int, errorHandler: ErrorHandler?): Single<Boolean> {
|
||||
return Single.just(true)
|
||||
}
|
||||
|
||||
override fun observeInternetConnectivity(initialIntervalInMs: Int, intervalInMs: Int, host: String?, port: Int, timeoutInMs: Int, httpResponse: Int, errorHandler: ErrorHandler?): Observable<Boolean> {
|
||||
return Observable.just(true)
|
||||
}
|
||||
|
||||
override fun getDefaultPingHost() = "localhost"
|
||||
}
|
|
@ -1,84 +0,0 @@
|
|||
package io.github.wulkanowy.data.repositories.attendance
|
||||
|
||||
import androidx.room.Room
|
||||
import androidx.test.core.app.ApplicationProvider
|
||||
import androidx.test.ext.junit.runners.AndroidJUnit4
|
||||
import io.github.wulkanowy.data.db.AppDatabase
|
||||
import io.github.wulkanowy.data.db.entities.Attendance
|
||||
import io.github.wulkanowy.data.db.entities.Semester
|
||||
import org.junit.After
|
||||
import org.junit.Before
|
||||
import org.junit.Test
|
||||
import org.junit.runner.RunWith
|
||||
import org.threeten.bp.LocalDate
|
||||
import org.threeten.bp.LocalDate.now
|
||||
import org.threeten.bp.LocalDate.of
|
||||
import kotlin.test.assertEquals
|
||||
|
||||
@RunWith(AndroidJUnit4::class)
|
||||
class AttendanceLocalTest {
|
||||
|
||||
private lateinit var attendanceLocal: AttendanceLocal
|
||||
|
||||
private lateinit var testDb: AppDatabase
|
||||
|
||||
@Before
|
||||
fun createDb() {
|
||||
testDb = Room.inMemoryDatabaseBuilder(ApplicationProvider.getApplicationContext(), AppDatabase::class.java).build()
|
||||
attendanceLocal = AttendanceLocal(testDb.attendanceDao)
|
||||
}
|
||||
|
||||
@After
|
||||
fun closeDb() {
|
||||
testDb.close()
|
||||
}
|
||||
|
||||
@Test
|
||||
fun saveAndReadTest() {
|
||||
attendanceLocal.saveAttendance(listOf(
|
||||
getAttendanceEntity(
|
||||
of(2018, 9, 10),
|
||||
SentExcuseStatus.ACCEPTED
|
||||
),
|
||||
getAttendanceEntity(
|
||||
of(2018, 9, 14),
|
||||
SentExcuseStatus.WAITING
|
||||
),
|
||||
getAttendanceEntity(
|
||||
of(2018, 9, 17),
|
||||
SentExcuseStatus.ACCEPTED
|
||||
)
|
||||
))
|
||||
|
||||
val attendance = attendanceLocal
|
||||
.getAttendance(Semester(1, 2, "", 1, 3, 2019, now(), now(), 1, 1),
|
||||
of(2018, 9, 10),
|
||||
of(2018, 9, 14)
|
||||
)
|
||||
.blockingGet()
|
||||
assertEquals(2, attendance.size)
|
||||
assertEquals(attendance[0].date, of(2018, 9, 10))
|
||||
assertEquals(attendance[1].date, of(2018, 9, 14))
|
||||
}
|
||||
|
||||
private fun getAttendanceEntity(
|
||||
date: LocalDate,
|
||||
excuseStatus: SentExcuseStatus
|
||||
) = Attendance(
|
||||
studentId = 1,
|
||||
diaryId = 2,
|
||||
timeId = 3,
|
||||
date = date,
|
||||
number = 0,
|
||||
subject = "",
|
||||
name = "",
|
||||
presence = false,
|
||||
absence = false,
|
||||
exemption = false,
|
||||
lateness = false,
|
||||
excused = false,
|
||||
deleted = false,
|
||||
excusable = false,
|
||||
excuseStatus = excuseStatus.name
|
||||
)
|
||||
}
|
|
@ -1,59 +0,0 @@
|
|||
package io.github.wulkanowy.data.repositories.completedlessons
|
||||
|
||||
import androidx.room.Room
|
||||
import androidx.test.core.app.ApplicationProvider
|
||||
import androidx.test.ext.junit.runners.AndroidJUnit4
|
||||
import io.github.wulkanowy.data.db.AppDatabase
|
||||
import io.github.wulkanowy.data.db.entities.CompletedLesson
|
||||
import io.github.wulkanowy.data.db.entities.Semester
|
||||
import org.junit.After
|
||||
import org.junit.Before
|
||||
import org.junit.Test
|
||||
import org.junit.runner.RunWith
|
||||
import org.threeten.bp.LocalDate
|
||||
import org.threeten.bp.LocalDate.now
|
||||
import org.threeten.bp.LocalDate.of
|
||||
import kotlin.test.assertEquals
|
||||
|
||||
@RunWith(AndroidJUnit4::class)
|
||||
class CompletedLessonsLocalTest {
|
||||
|
||||
private lateinit var completedLessonsLocal: CompletedLessonsLocal
|
||||
|
||||
private lateinit var testDb: AppDatabase
|
||||
|
||||
@Before
|
||||
fun createDb() {
|
||||
testDb = Room.inMemoryDatabaseBuilder(ApplicationProvider.getApplicationContext(), AppDatabase::class.java)
|
||||
.build()
|
||||
completedLessonsLocal = CompletedLessonsLocal(testDb.completedLessonsDao)
|
||||
}
|
||||
|
||||
@After
|
||||
fun closeDb() {
|
||||
testDb.close()
|
||||
}
|
||||
|
||||
@Test
|
||||
fun saveAndReadTest() {
|
||||
completedLessonsLocal.saveCompletedLessons(listOf(
|
||||
getCompletedLesson(of(2018, 9, 10), 1),
|
||||
getCompletedLesson(of(2018, 9, 14), 2),
|
||||
getCompletedLesson(of(2018, 9, 17), 3)
|
||||
))
|
||||
|
||||
val completed = completedLessonsLocal
|
||||
.getCompletedLessons(Semester(1, 2, "", 1, 3, 2019, now(), now(), 1, 1),
|
||||
of(2018, 9, 10),
|
||||
of(2018, 9, 14)
|
||||
)
|
||||
.blockingGet()
|
||||
assertEquals(2, completed.size)
|
||||
assertEquals(completed[0].date, of(2018, 9, 10))
|
||||
assertEquals(completed[1].date, of(2018, 9, 14))
|
||||
}
|
||||
|
||||
private fun getCompletedLesson(date: LocalDate, number: Int): CompletedLesson {
|
||||
return CompletedLesson(1, 2, date, number, "", "", "", "", "", "", "")
|
||||
}
|
||||
}
|
|
@ -1,53 +0,0 @@
|
|||
package io.github.wulkanowy.data.repositories.exam
|
||||
|
||||
import androidx.room.Room
|
||||
import androidx.test.core.app.ApplicationProvider
|
||||
import androidx.test.ext.junit.runners.AndroidJUnit4
|
||||
import io.github.wulkanowy.data.db.AppDatabase
|
||||
import io.github.wulkanowy.data.db.entities.Exam
|
||||
import io.github.wulkanowy.data.db.entities.Semester
|
||||
import org.junit.After
|
||||
import org.junit.Before
|
||||
import org.junit.Test
|
||||
import org.junit.runner.RunWith
|
||||
import org.threeten.bp.LocalDate.now
|
||||
import org.threeten.bp.LocalDate.of
|
||||
import kotlin.test.assertEquals
|
||||
|
||||
@RunWith(AndroidJUnit4::class)
|
||||
class ExamLocalTest {
|
||||
|
||||
private lateinit var examLocal: ExamLocal
|
||||
|
||||
private lateinit var testDb: AppDatabase
|
||||
|
||||
@Before
|
||||
fun createDb() {
|
||||
testDb = Room.inMemoryDatabaseBuilder(ApplicationProvider.getApplicationContext(), AppDatabase::class.java).build()
|
||||
examLocal = ExamLocal(testDb.examsDao)
|
||||
}
|
||||
|
||||
@After
|
||||
fun closeDb() {
|
||||
testDb.close()
|
||||
}
|
||||
|
||||
@Test
|
||||
fun saveAndReadTest() {
|
||||
examLocal.saveExams(listOf(
|
||||
Exam(1, 2, of(2018, 9, 10), now(), "", "", "", "", "", ""),
|
||||
Exam(1, 2, of(2018, 9, 14), now(), "", "", "", "", "", ""),
|
||||
Exam(1, 2, of(2018, 9, 17), now(), "", "", "", "", "", "")
|
||||
))
|
||||
|
||||
val exams = examLocal
|
||||
.getExams(Semester(1, 2, "", 1, 3, 2019, now(), now(), 1, 1),
|
||||
of(2018, 9, 10),
|
||||
of(2018, 9, 14)
|
||||
)
|
||||
.blockingGet()
|
||||
assertEquals(2, exams.size)
|
||||
assertEquals(exams[0].date, of(2018, 9, 10))
|
||||
assertEquals(exams[1].date, of(2018, 9, 14))
|
||||
}
|
||||
}
|
|
@ -1,53 +0,0 @@
|
|||
package io.github.wulkanowy.data.repositories.grade
|
||||
|
||||
import androidx.room.Room
|
||||
import androidx.test.core.app.ApplicationProvider
|
||||
import androidx.test.ext.junit.runners.AndroidJUnit4
|
||||
import io.github.wulkanowy.data.db.AppDatabase
|
||||
import io.github.wulkanowy.data.db.entities.Semester
|
||||
import org.junit.After
|
||||
import org.junit.Before
|
||||
import org.junit.Test
|
||||
import org.junit.runner.RunWith
|
||||
import org.threeten.bp.LocalDate
|
||||
import org.threeten.bp.LocalDate.now
|
||||
import kotlin.test.assertEquals
|
||||
|
||||
@RunWith(AndroidJUnit4::class)
|
||||
class GradeLocalTest {
|
||||
|
||||
private lateinit var gradeLocal: GradeLocal
|
||||
|
||||
private lateinit var testDb: AppDatabase
|
||||
|
||||
@Before
|
||||
fun createDb() {
|
||||
testDb = Room.inMemoryDatabaseBuilder(ApplicationProvider.getApplicationContext(), AppDatabase::class.java)
|
||||
.build()
|
||||
gradeLocal = GradeLocal(testDb.gradeDao, testDb.gradeSummaryDao)
|
||||
}
|
||||
|
||||
@After
|
||||
fun closeDb() {
|
||||
testDb.close()
|
||||
}
|
||||
|
||||
@Test
|
||||
fun saveAndReadTest() {
|
||||
gradeLocal.saveGrades(listOf(
|
||||
createGradeLocal(5, 3.0, LocalDate.of(2018, 9, 10), "", 1),
|
||||
createGradeLocal(4, 4.0, LocalDate.of(2019, 2, 27), "", 2),
|
||||
createGradeLocal(3, 5.0, LocalDate.of(2019, 2, 28), "", 2)
|
||||
))
|
||||
|
||||
val semester = Semester(1, 2, "", 2019, 2, 1, now(), now(), 1, 1)
|
||||
|
||||
val grades = gradeLocal
|
||||
.getGradesDetails(semester)
|
||||
.blockingGet()
|
||||
|
||||
assertEquals(2, grades.size)
|
||||
assertEquals(grades[0].date, LocalDate.of(2019, 2, 27))
|
||||
assertEquals(grades[1].date, LocalDate.of(2019, 2, 28))
|
||||
}
|
||||
}
|
|
@ -1,182 +0,0 @@
|
|||
package io.github.wulkanowy.data.repositories.grade
|
||||
|
||||
import android.os.Build.VERSION_CODES.P
|
||||
import androidx.room.Room
|
||||
import androidx.test.core.app.ApplicationProvider.getApplicationContext
|
||||
import androidx.test.ext.junit.runners.AndroidJUnit4
|
||||
import androidx.test.filters.SdkSuppress
|
||||
import com.github.pwittchen.reactivenetwork.library.rx2.internet.observing.InternetObservingSettings
|
||||
import io.github.wulkanowy.data.db.AppDatabase
|
||||
import io.github.wulkanowy.data.db.entities.Semester
|
||||
import io.github.wulkanowy.data.db.entities.Student
|
||||
import io.github.wulkanowy.data.repositories.TestInternetObservingStrategy
|
||||
import io.github.wulkanowy.sdk.Sdk
|
||||
import io.github.wulkanowy.sdk.pojo.Grade
|
||||
import io.mockk.MockKAnnotations
|
||||
import io.mockk.every
|
||||
import io.mockk.impl.annotations.MockK
|
||||
import io.reactivex.Single
|
||||
import org.junit.After
|
||||
import org.junit.Before
|
||||
import org.junit.Test
|
||||
import org.junit.runner.RunWith
|
||||
import org.threeten.bp.LocalDate.of
|
||||
import org.threeten.bp.LocalDateTime
|
||||
import kotlin.test.assertEquals
|
||||
import kotlin.test.assertFalse
|
||||
import kotlin.test.assertTrue
|
||||
|
||||
@SdkSuppress(minSdkVersion = P)
|
||||
@RunWith(AndroidJUnit4::class)
|
||||
class GradeRepositoryTest {
|
||||
|
||||
@MockK
|
||||
private lateinit var mockSdk: Sdk
|
||||
|
||||
private val settings = InternetObservingSettings.builder()
|
||||
.strategy(TestInternetObservingStrategy())
|
||||
.build()
|
||||
|
||||
@MockK
|
||||
private lateinit var semesterMock: Semester
|
||||
|
||||
@MockK
|
||||
private lateinit var studentMock: Student
|
||||
|
||||
private lateinit var gradeRemote: GradeRemote
|
||||
|
||||
private lateinit var gradeLocal: GradeLocal
|
||||
|
||||
private lateinit var testDb: AppDatabase
|
||||
|
||||
@Before
|
||||
fun initApi() {
|
||||
MockKAnnotations.init(this)
|
||||
testDb = Room.inMemoryDatabaseBuilder(getApplicationContext(), AppDatabase::class.java).build()
|
||||
gradeLocal = GradeLocal(testDb.gradeDao, testDb.gradeSummaryDao)
|
||||
gradeRemote = GradeRemote(mockSdk)
|
||||
|
||||
every { studentMock.registrationDate } returns LocalDateTime.of(2019, 2, 27, 12, 0)
|
||||
every { semesterMock.studentId } returns 1
|
||||
every { semesterMock.diaryId } returns 1
|
||||
every { semesterMock.schoolYear } returns 2019
|
||||
every { semesterMock.semesterId } returns 1
|
||||
every { mockSdk.switchDiary(any(), any()) } returns mockSdk
|
||||
}
|
||||
|
||||
@After
|
||||
fun closeDb() {
|
||||
testDb.close()
|
||||
}
|
||||
|
||||
@Test
|
||||
fun markOlderThanRegisterDateAsRead() {
|
||||
every { mockSdk.getGrades(1) } returns Single.just(listOf(
|
||||
createGradeApi(5, 4.0, of(2019, 2, 25), "Ocena pojawiła się"),
|
||||
createGradeApi(5, 4.0, of(2019, 2, 26), "przed zalogowanie w aplikacji"),
|
||||
createGradeApi(5, 4.0, of(2019, 2, 27), "Ocena z dnia logowania"),
|
||||
createGradeApi(5, 4.0, of(2019, 2, 28), "Ocena jeszcze nowsza")
|
||||
) to emptyList())
|
||||
|
||||
val grades = GradeRepository(settings, gradeLocal, gradeRemote)
|
||||
.getGrades(studentMock, semesterMock, true).blockingGet().first.sortedByDescending { it.date }
|
||||
|
||||
assertFalse { grades[0].isRead }
|
||||
assertFalse { grades[1].isRead }
|
||||
assertTrue { grades[2].isRead }
|
||||
assertTrue { grades[3].isRead }
|
||||
}
|
||||
|
||||
@Test
|
||||
fun mitigateOldGradesNotifications() {
|
||||
gradeLocal.saveGrades(listOf(
|
||||
createGradeLocal(5, 3.0, of(2019, 2, 25), "Jedna ocena"),
|
||||
createGradeLocal(4, 4.0, of(2019, 2, 26), "Druga"),
|
||||
createGradeLocal(3, 5.0, of(2019, 2, 27), "Trzecia")
|
||||
))
|
||||
|
||||
every { mockSdk.getGrades(1) } returns Single.just(listOf(
|
||||
createGradeApi(5, 2.0, of(2019, 2, 25), "Ocena ma datę, jest inna, ale nie zostanie powiadomiona"),
|
||||
createGradeApi(4, 3.0, of(2019, 2, 26), "starszą niż ostatnia lokalnie"),
|
||||
createGradeApi(3, 4.0, of(2019, 2, 27), "Ta jest z tego samego dnia co ostatnia lokalnie"),
|
||||
createGradeApi(2, 5.0, of(2019, 2, 28), "Ta jest już w ogóle nowa")
|
||||
) to emptyList())
|
||||
|
||||
val grades = GradeRepository(settings, gradeLocal, gradeRemote)
|
||||
.getGrades(studentMock, semesterMock, true).blockingGet().first.sortedByDescending { it.date }
|
||||
|
||||
assertFalse { grades[0].isRead }
|
||||
assertFalse { grades[1].isRead }
|
||||
assertTrue { grades[2].isRead }
|
||||
assertTrue { grades[3].isRead }
|
||||
}
|
||||
|
||||
@Test
|
||||
fun subtractLocaleDuplicateGrades() {
|
||||
gradeLocal.saveGrades(listOf(
|
||||
createGradeLocal(5, 3.0, of(2019, 2, 25), "Taka sama ocena"),
|
||||
createGradeLocal(5, 3.0, of(2019, 2, 25), "Taka sama ocena"),
|
||||
createGradeLocal(3, 5.0, of(2019, 2, 26), "Jakaś inna ocena")
|
||||
))
|
||||
|
||||
every { mockSdk.getGrades(1) } returns Single.just(listOf(
|
||||
createGradeApi(5, 3.0, of(2019, 2, 25), "Taka sama ocena"),
|
||||
createGradeApi(3, 5.0, of(2019, 2, 26), "Jakaś inna ocena")
|
||||
) to emptyList())
|
||||
|
||||
val grades = GradeRepository(settings, gradeLocal, gradeRemote)
|
||||
.getGrades(studentMock, semesterMock, true).blockingGet()
|
||||
|
||||
assertEquals(2, grades.first.size)
|
||||
}
|
||||
|
||||
@Test
|
||||
fun subtractRemoteDuplicateGrades() {
|
||||
gradeLocal.saveGrades(listOf(
|
||||
createGradeLocal(5, 3.0, of(2019, 2, 25), "Taka sama ocena"),
|
||||
createGradeLocal(3, 5.0, of(2019, 2, 26), "Jakaś inna ocena")
|
||||
))
|
||||
|
||||
every { mockSdk.getGrades(1) } returns Single.just(listOf(
|
||||
createGradeApi(5, 3.0, of(2019, 2, 25), "Taka sama ocena"),
|
||||
createGradeApi(5, 3.0, of(2019, 2, 25), "Taka sama ocena"),
|
||||
createGradeApi(3, 5.0, of(2019, 2, 26), "Jakaś inna ocena")
|
||||
) to emptyList())
|
||||
|
||||
val grades = GradeRepository(settings, gradeLocal, gradeRemote)
|
||||
.getGrades(studentMock, semesterMock, true).blockingGet()
|
||||
|
||||
assertEquals(3, grades.first.size)
|
||||
}
|
||||
|
||||
@Test
|
||||
fun emptyLocal() {
|
||||
gradeLocal.saveGrades(listOf())
|
||||
|
||||
every { mockSdk.getGrades(1) } returns Single.just(listOf(
|
||||
createGradeApi(5, 3.0, of(2019, 2, 25), "Taka sama ocena"),
|
||||
createGradeApi(5, 3.0, of(2019, 2, 25), "Taka sama ocena"),
|
||||
createGradeApi(3, 5.0, of(2019, 2, 26), "Jakaś inna ocena")
|
||||
) to emptyList())
|
||||
|
||||
val grades = GradeRepository(settings, gradeLocal, gradeRemote)
|
||||
.getGrades(studentMock, semesterMock, true).blockingGet()
|
||||
|
||||
assertEquals(3, grades.first.size)
|
||||
}
|
||||
|
||||
@Test
|
||||
fun emptyRemote() {
|
||||
gradeLocal.saveGrades(listOf(
|
||||
createGradeLocal(5, 3.0, of(2019, 2, 25), "Taka sama ocena"),
|
||||
createGradeLocal(3, 5.0, of(2019, 2, 26), "Jakaś inna ocena")
|
||||
))
|
||||
|
||||
every { mockSdk.getGrades(1) } returns Single.just(emptyList<Grade>() to emptyList())
|
||||
|
||||
val grades = GradeRepository(settings, gradeLocal, gradeRemote)
|
||||
.getGrades(studentMock, semesterMock, true).blockingGet()
|
||||
|
||||
assertEquals(0, grades.first.size)
|
||||
}
|
||||
}
|
|
@ -1,41 +0,0 @@
|
|||
package io.github.wulkanowy.data.repositories.grade
|
||||
|
||||
import org.threeten.bp.LocalDate
|
||||
import io.github.wulkanowy.sdk.pojo.Grade as GradeRemote
|
||||
import io.github.wulkanowy.data.db.entities.Grade as GradeLocal
|
||||
|
||||
fun createGradeLocal(value: Int, weight: Double, date: LocalDate, desc: String, semesterId: Int = 1): GradeLocal {
|
||||
return GradeLocal(
|
||||
semesterId = semesterId,
|
||||
studentId = 1,
|
||||
modifier = .0,
|
||||
teacher = "",
|
||||
subject = "",
|
||||
date = date,
|
||||
color = "",
|
||||
comment = "",
|
||||
description = desc,
|
||||
entry = "",
|
||||
gradeSymbol = "",
|
||||
value = value.toDouble(),
|
||||
weight = "",
|
||||
weightValue = weight
|
||||
)
|
||||
}
|
||||
|
||||
fun createGradeApi(value: Int, weight: Double, date: LocalDate, desc: String): GradeRemote {
|
||||
return GradeRemote(
|
||||
subject = "",
|
||||
color = "",
|
||||
comment = "",
|
||||
date = date,
|
||||
description = desc,
|
||||
entry = "",
|
||||
modifier = .0,
|
||||
symbol = "",
|
||||
teacher = "",
|
||||
value = value.toDouble(),
|
||||
weight = weight.toString(),
|
||||
weightValue = weight
|
||||
)
|
||||
}
|
|
@ -1,106 +0,0 @@
|
|||
package io.github.wulkanowy.data.repositories.gradestatistics
|
||||
|
||||
import androidx.room.Room
|
||||
import androidx.test.core.app.ApplicationProvider
|
||||
import androidx.test.ext.junit.runners.AndroidJUnit4
|
||||
import io.github.wulkanowy.data.db.AppDatabase
|
||||
import io.github.wulkanowy.data.db.entities.GradePointsStatistics
|
||||
import io.github.wulkanowy.data.db.entities.GradeStatistics
|
||||
import io.github.wulkanowy.data.db.entities.Semester
|
||||
import org.junit.After
|
||||
import org.junit.Before
|
||||
import org.junit.Test
|
||||
import org.junit.runner.RunWith
|
||||
import org.threeten.bp.LocalDate.now
|
||||
import kotlin.test.assertEquals
|
||||
|
||||
@RunWith(AndroidJUnit4::class)
|
||||
class GradeStatisticsLocalTest {
|
||||
|
||||
private lateinit var gradeStatisticsLocal: GradeStatisticsLocal
|
||||
|
||||
private lateinit var testDb: AppDatabase
|
||||
|
||||
@Before
|
||||
fun createDb() {
|
||||
testDb = Room.inMemoryDatabaseBuilder(ApplicationProvider.getApplicationContext(), AppDatabase::class.java)
|
||||
.build()
|
||||
gradeStatisticsLocal = GradeStatisticsLocal(testDb.gradeStatistics, testDb.gradePointsStatistics)
|
||||
}
|
||||
|
||||
@After
|
||||
fun closeDb() {
|
||||
testDb.close()
|
||||
}
|
||||
|
||||
@Test
|
||||
fun saveAndRead_subject() {
|
||||
gradeStatisticsLocal.saveGradesStatistics(listOf(
|
||||
getGradeStatistics("Matematyka", 2, 1),
|
||||
getGradeStatistics("Fizyka", 1, 2)
|
||||
))
|
||||
|
||||
val stats = gradeStatisticsLocal.getGradesStatistics(getSemester(), false, "Matematyka").blockingGet()
|
||||
assertEquals(1, stats.size)
|
||||
assertEquals(stats[0].subject, "Matematyka")
|
||||
}
|
||||
|
||||
@Test
|
||||
fun saveAndRead_all() {
|
||||
gradeStatisticsLocal.saveGradesStatistics(listOf(
|
||||
getGradeStatistics("Matematyka", 2, 1),
|
||||
getGradeStatistics("Chemia", 2, 1),
|
||||
getGradeStatistics("Fizyka", 1, 2)
|
||||
))
|
||||
|
||||
val stats = gradeStatisticsLocal.getGradesStatistics(getSemester(), false, "Wszystkie").blockingGet()
|
||||
assertEquals(3, stats.size)
|
||||
assertEquals(stats[0].subject, "Wszystkie")
|
||||
assertEquals(stats[1].subject, "Matematyka")
|
||||
assertEquals(stats[2].subject, "Chemia")
|
||||
}
|
||||
|
||||
@Test
|
||||
fun saveAndRead_points() {
|
||||
gradeStatisticsLocal.saveGradesPointsStatistics(listOf(
|
||||
getGradePointsStatistics("Matematyka", 2, 1),
|
||||
getGradePointsStatistics("Chemia", 2, 1),
|
||||
getGradePointsStatistics("Fizyka", 1, 2)
|
||||
))
|
||||
|
||||
val stats = gradeStatisticsLocal.getGradesPointsStatistics(getSemester(), "Matematyka").blockingGet()
|
||||
with(stats[0]) {
|
||||
assertEquals(subject, "Matematyka")
|
||||
assertEquals(others, 5.0)
|
||||
assertEquals(student, 5.0)
|
||||
}
|
||||
}
|
||||
|
||||
@Test
|
||||
fun saveAndRead_subjectEmpty() {
|
||||
gradeStatisticsLocal.saveGradesPointsStatistics(listOf())
|
||||
|
||||
val stats = gradeStatisticsLocal.getGradesPointsStatistics(getSemester(), "Matematyka").blockingGet()
|
||||
assertEquals(null, stats)
|
||||
}
|
||||
|
||||
@Test
|
||||
fun saveAndRead_allEmpty() {
|
||||
gradeStatisticsLocal.saveGradesPointsStatistics(listOf())
|
||||
|
||||
val stats = gradeStatisticsLocal.getGradesPointsStatistics(getSemester(), "Wszystkie").blockingGet()
|
||||
assertEquals(null, stats)
|
||||
}
|
||||
|
||||
private fun getSemester(): Semester {
|
||||
return Semester(2, 2, "", 2019, 1, 2, now(), now(), 1, 1)
|
||||
}
|
||||
|
||||
private fun getGradeStatistics(subject: String, studentId: Int, semesterId: Int): GradeStatistics {
|
||||
return GradeStatistics(studentId, semesterId, subject, 5, 5, false)
|
||||
}
|
||||
|
||||
private fun getGradePointsStatistics(subject: String, studentId: Int, semesterId: Int): GradePointsStatistics {
|
||||
return GradePointsStatistics(studentId, semesterId, subject, 5.0, 5.0)
|
||||
}
|
||||
}
|
|
@ -1,48 +0,0 @@
|
|||
package io.github.wulkanowy.data.repositories.luckynumber
|
||||
|
||||
import androidx.room.Room
|
||||
import androidx.test.core.app.ApplicationProvider
|
||||
import androidx.test.ext.junit.runners.AndroidJUnit4
|
||||
import io.github.wulkanowy.data.db.AppDatabase
|
||||
import io.github.wulkanowy.data.db.entities.LuckyNumber
|
||||
import io.github.wulkanowy.data.db.entities.Student
|
||||
import org.junit.After
|
||||
import org.junit.Before
|
||||
import org.junit.Test
|
||||
import org.junit.runner.RunWith
|
||||
import org.threeten.bp.LocalDate
|
||||
import org.threeten.bp.LocalDateTime.now
|
||||
import kotlin.test.assertEquals
|
||||
|
||||
@RunWith(AndroidJUnit4::class)
|
||||
class LuckyNumberLocalTest {
|
||||
|
||||
private lateinit var luckyNumberLocal: LuckyNumberLocal
|
||||
|
||||
private lateinit var testDb: AppDatabase
|
||||
|
||||
@Before
|
||||
fun createDb() {
|
||||
testDb = Room.inMemoryDatabaseBuilder(ApplicationProvider.getApplicationContext(), AppDatabase::class.java)
|
||||
.build()
|
||||
luckyNumberLocal = LuckyNumberLocal(testDb.luckyNumberDao)
|
||||
}
|
||||
|
||||
@After
|
||||
fun closeDb() {
|
||||
testDb.close()
|
||||
}
|
||||
|
||||
@Test
|
||||
fun saveAndReadTest() {
|
||||
luckyNumberLocal.saveLuckyNumber(LuckyNumber(1, LocalDate.of(2019, 1, 20), 14))
|
||||
|
||||
val luckyNumber = luckyNumberLocal.getLuckyNumber(Student("", "", "", "", "", "", false, "", "", "", 1, 1, "", "", "", "", "", 1, false, now()),
|
||||
LocalDate.of(2019, 1, 20)
|
||||
).blockingGet()
|
||||
|
||||
assertEquals(1, luckyNumber.studentId)
|
||||
assertEquals(LocalDate.of(2019, 1, 20), luckyNumber.date)
|
||||
assertEquals(14, luckyNumber.luckyNumber)
|
||||
}
|
||||
}
|
|
@ -1,60 +0,0 @@
|
|||
package io.github.wulkanowy.data.repositories.recipient
|
||||
|
||||
import androidx.room.Room
|
||||
import androidx.test.core.app.ApplicationProvider
|
||||
import androidx.test.ext.junit.runners.AndroidJUnit4
|
||||
import io.github.wulkanowy.data.db.AppDatabase
|
||||
import io.github.wulkanowy.data.db.entities.Recipient
|
||||
import io.github.wulkanowy.data.db.entities.ReportingUnit
|
||||
import io.github.wulkanowy.data.db.entities.Student
|
||||
import org.junit.After
|
||||
import org.junit.Before
|
||||
import org.junit.Test
|
||||
import org.junit.runner.RunWith
|
||||
import org.threeten.bp.LocalDateTime
|
||||
import kotlin.test.assertEquals
|
||||
|
||||
@RunWith(AndroidJUnit4::class)
|
||||
class RecipientLocalTest {
|
||||
|
||||
private lateinit var recipientLocal: RecipientLocal
|
||||
|
||||
private lateinit var testDb: AppDatabase
|
||||
|
||||
@Before
|
||||
fun createDb() {
|
||||
testDb = Room.inMemoryDatabaseBuilder(ApplicationProvider.getApplicationContext(), AppDatabase::class.java)
|
||||
.build()
|
||||
recipientLocal = RecipientLocal(testDb.recipientDao)
|
||||
}
|
||||
|
||||
@After
|
||||
fun closeDb() {
|
||||
testDb.close()
|
||||
}
|
||||
|
||||
@Test
|
||||
fun saveAndReadTest() {
|
||||
recipientLocal.saveRecipients(listOf(
|
||||
Recipient(1, "2rPracownik", "Kowalski Jan", "Kowalski Jan [KJ] - Pracownik (Fake123456)", 3, 4, 2, "hash"),
|
||||
Recipient(1, "3rPracownik", "Kowalska Karolina", "Kowalska Karolina [KK] - Pracownik (Fake123456)", 4, 4, 2, "hash"),
|
||||
Recipient(1, "4rPracownik", "Krupa Stanisław", "Krupa Stanisław [KS] - Uczeń (Fake123456)", 5, 4, 1, "hash")
|
||||
))
|
||||
|
||||
val recipients = recipientLocal.getRecipients(
|
||||
Student("fakelog.cf", "AUTO", "", "", "", "", false, "", "", "", 1, 0, "", "", "", "", "", 1, true, LocalDateTime.now()),
|
||||
2,
|
||||
ReportingUnit(1, 4, "", 0, "", emptyList())
|
||||
).blockingGet()
|
||||
|
||||
assertEquals(2, recipients.size)
|
||||
assertEquals(1, recipients[0].studentId)
|
||||
assertEquals("3rPracownik", recipients[1].realId)
|
||||
assertEquals("Kowalski Jan", recipients[0].name)
|
||||
assertEquals("Kowalska Karolina [KK] - Pracownik (Fake123456)", recipients[1].realName)
|
||||
assertEquals(3, recipients[0].loginId)
|
||||
assertEquals(4, recipients[1].unitId)
|
||||
assertEquals(2, recipients[0].role)
|
||||
assertEquals("hash", recipients[1].hash)
|
||||
}
|
||||
}
|
|
@ -1,44 +0,0 @@
|
|||
package io.github.wulkanowy.data.repositories.student
|
||||
|
||||
import android.content.Context
|
||||
import androidx.room.Room
|
||||
import androidx.test.core.app.ApplicationProvider
|
||||
import androidx.test.ext.junit.runners.AndroidJUnit4
|
||||
import io.github.wulkanowy.data.db.AppDatabase
|
||||
import io.github.wulkanowy.data.repositories.getStudent
|
||||
import org.junit.After
|
||||
import org.junit.Before
|
||||
import org.junit.Test
|
||||
import org.junit.runner.RunWith
|
||||
import kotlin.test.assertEquals
|
||||
|
||||
@RunWith(AndroidJUnit4::class)
|
||||
class StudentLocalTest {
|
||||
|
||||
private lateinit var studentLocal: StudentLocal
|
||||
|
||||
private lateinit var testDb: AppDatabase
|
||||
|
||||
private val student = getStudent()
|
||||
|
||||
@Before
|
||||
fun createDb() {
|
||||
val context = ApplicationProvider.getApplicationContext<Context>()
|
||||
testDb = Room.inMemoryDatabaseBuilder(context, AppDatabase::class.java)
|
||||
.build()
|
||||
studentLocal = StudentLocal(testDb.studentDao, context)
|
||||
}
|
||||
|
||||
@After
|
||||
fun closeDb() {
|
||||
testDb.close()
|
||||
}
|
||||
|
||||
@Test
|
||||
fun saveAndReadTest() {
|
||||
studentLocal.saveStudents(listOf(student)).blockingGet()
|
||||
|
||||
val student = studentLocal.getCurrentStudent(true).blockingGet()
|
||||
assertEquals("23", student.schoolSymbol)
|
||||
}
|
||||
}
|
|
@ -1,48 +0,0 @@
|
|||
package io.github.wulkanowy.data.repositories.timetable
|
||||
|
||||
import org.threeten.bp.LocalDateTime
|
||||
import org.threeten.bp.LocalDateTime.now
|
||||
import io.github.wulkanowy.data.db.entities.Timetable as TimetableLocal
|
||||
import io.github.wulkanowy.sdk.pojo.Timetable as TimetableRemote
|
||||
|
||||
fun createTimetableLocal(start: LocalDateTime, number: Int, room: String = "", subject: String = "", teacher: String = "", changes: Boolean = false): TimetableLocal {
|
||||
return TimetableLocal(
|
||||
studentId = 1,
|
||||
diaryId = 2,
|
||||
number = number,
|
||||
start = start,
|
||||
end = now(),
|
||||
date = start.toLocalDate(),
|
||||
subject = subject,
|
||||
subjectOld = "",
|
||||
group = "",
|
||||
room = room,
|
||||
roomOld = "",
|
||||
teacher = teacher,
|
||||
teacherOld = "",
|
||||
info = "",
|
||||
isStudentPlan = true,
|
||||
changes = changes,
|
||||
canceled = false
|
||||
)
|
||||
}
|
||||
|
||||
fun createTimetableRemote(start: LocalDateTime, number: Int = 1, room: String = "", subject: String = "", teacher: String = "", changes: Boolean = false): TimetableRemote {
|
||||
return TimetableRemote(
|
||||
number = number,
|
||||
start = start,
|
||||
end = start.plusMinutes(45),
|
||||
date = start.toLocalDate(),
|
||||
subject = subject,
|
||||
group = "",
|
||||
room = room,
|
||||
teacher = teacher,
|
||||
info = "",
|
||||
changes = changes,
|
||||
canceled = false,
|
||||
roomOld = "",
|
||||
subjectOld = "",
|
||||
teacherOld = "",
|
||||
studentPlan = true
|
||||
)
|
||||
}
|
|
@ -1,53 +0,0 @@
|
|||
package io.github.wulkanowy.data.repositories.timetable
|
||||
|
||||
import androidx.room.Room
|
||||
import androidx.test.core.app.ApplicationProvider
|
||||
import androidx.test.ext.junit.runners.AndroidJUnit4
|
||||
import io.github.wulkanowy.data.db.AppDatabase
|
||||
import io.github.wulkanowy.data.db.entities.Semester
|
||||
import org.junit.After
|
||||
import org.junit.Before
|
||||
import org.junit.Test
|
||||
import org.junit.runner.RunWith
|
||||
import org.threeten.bp.LocalDate
|
||||
import org.threeten.bp.LocalDateTime.of
|
||||
import kotlin.test.assertEquals
|
||||
|
||||
@RunWith(AndroidJUnit4::class)
|
||||
class TimetableLocalTest {
|
||||
|
||||
private lateinit var timetableDb: TimetableLocal
|
||||
|
||||
private lateinit var testDb: AppDatabase
|
||||
|
||||
@Before
|
||||
fun createDb() {
|
||||
testDb = Room.inMemoryDatabaseBuilder(ApplicationProvider.getApplicationContext(), AppDatabase::class.java)
|
||||
.build()
|
||||
timetableDb = TimetableLocal(testDb.timetableDao)
|
||||
}
|
||||
|
||||
@After
|
||||
fun closeDb() {
|
||||
testDb.close()
|
||||
}
|
||||
|
||||
@Test
|
||||
fun saveAndReadTest() {
|
||||
timetableDb.saveTimetable(listOf(
|
||||
createTimetableLocal(of(2018, 9, 10, 0, 0, 0), 1),
|
||||
createTimetableLocal(of(2018, 9, 14, 0, 0, 0), 1),
|
||||
createTimetableLocal(of(2018, 9, 17, 0, 0, 0), 1)
|
||||
))
|
||||
|
||||
val exams = timetableDb.getTimetable(
|
||||
Semester(1, 2, "", 1, 1, 2019, LocalDate.now(), LocalDate.now(), 1, 1),
|
||||
LocalDate.of(2018, 9, 10),
|
||||
LocalDate.of(2018, 9, 14)
|
||||
).blockingGet()
|
||||
|
||||
assertEquals(2, exams.size)
|
||||
assertEquals(exams[0].date, LocalDate.of(2018, 9, 10))
|
||||
assertEquals(exams[1].date, LocalDate.of(2018, 9, 14))
|
||||
}
|
||||
}
|
|
@ -1,166 +0,0 @@
|
|||
package io.github.wulkanowy.data.repositories.timetable
|
||||
|
||||
import android.os.Build.VERSION_CODES.P
|
||||
import androidx.room.Room
|
||||
import androidx.test.core.app.ApplicationProvider.getApplicationContext
|
||||
import androidx.test.ext.junit.runners.AndroidJUnit4
|
||||
import androidx.test.filters.SdkSuppress
|
||||
import com.github.pwittchen.reactivenetwork.library.rx2.internet.observing.InternetObservingSettings
|
||||
import io.github.wulkanowy.data.db.AppDatabase
|
||||
import io.github.wulkanowy.data.db.entities.Semester
|
||||
import io.github.wulkanowy.data.db.entities.Student
|
||||
import io.github.wulkanowy.data.repositories.TestInternetObservingStrategy
|
||||
import io.github.wulkanowy.data.repositories.getStudent
|
||||
import io.github.wulkanowy.services.alarm.TimetableNotificationSchedulerHelper
|
||||
import io.github.wulkanowy.sdk.Sdk
|
||||
import io.mockk.MockKAnnotations
|
||||
import io.mockk.every
|
||||
import io.mockk.impl.annotations.MockK
|
||||
import io.mockk.mockk
|
||||
import io.reactivex.Single
|
||||
import org.junit.After
|
||||
import org.junit.Before
|
||||
import org.junit.Test
|
||||
import org.junit.runner.RunWith
|
||||
import org.threeten.bp.LocalDate
|
||||
import org.threeten.bp.LocalDateTime.of
|
||||
import kotlin.test.assertEquals
|
||||
|
||||
@SdkSuppress(minSdkVersion = P)
|
||||
@RunWith(AndroidJUnit4::class)
|
||||
class TimetableRepositoryTest {
|
||||
|
||||
@MockK
|
||||
private lateinit var mockSdk: Sdk
|
||||
|
||||
private val settings = InternetObservingSettings.builder()
|
||||
.strategy(TestInternetObservingStrategy())
|
||||
.build()
|
||||
|
||||
@MockK
|
||||
private lateinit var studentMock: Student
|
||||
|
||||
private val student = getStudent()
|
||||
|
||||
@MockK
|
||||
private lateinit var semesterMock: Semester
|
||||
|
||||
@MockK
|
||||
private lateinit var timetableNotificationSchedulerHelper: TimetableNotificationSchedulerHelper
|
||||
|
||||
private lateinit var timetableRemote: TimetableRemote
|
||||
|
||||
private lateinit var timetableLocal: TimetableLocal
|
||||
|
||||
private lateinit var testDb: AppDatabase
|
||||
|
||||
@Before
|
||||
fun initApi() {
|
||||
MockKAnnotations.init(this)
|
||||
testDb = Room.inMemoryDatabaseBuilder(getApplicationContext(), AppDatabase::class.java).build()
|
||||
timetableLocal = TimetableLocal(testDb.timetableDao)
|
||||
timetableRemote = TimetableRemote(mockSdk)
|
||||
|
||||
every { timetableNotificationSchedulerHelper.scheduleNotifications(any(), any()) } returns mockk()
|
||||
every { timetableNotificationSchedulerHelper.cancelScheduled(any(), any()) } returns mockk()
|
||||
|
||||
every { studentMock.studentId } returns 1
|
||||
every { studentMock.studentName } returns "Jan Kowalski"
|
||||
|
||||
every { semesterMock.studentId } returns 1
|
||||
every { semesterMock.diaryId } returns 2
|
||||
every { semesterMock.schoolYear } returns 2019
|
||||
every { semesterMock.semesterId } returns 1
|
||||
|
||||
every { mockSdk.switchDiary(any(), any()) } returns mockSdk
|
||||
}
|
||||
|
||||
@After
|
||||
fun closeDb() {
|
||||
testDb.close()
|
||||
}
|
||||
|
||||
@Test
|
||||
fun copyRoomToCompletedFromPrevious() {
|
||||
timetableLocal.saveTimetable(listOf(
|
||||
createTimetableLocal(of(2019, 3, 5, 8, 0), 1, "123", "Przyroda"),
|
||||
createTimetableLocal(of(2019, 3, 5, 8, 50), 2, "321", "Religia"),
|
||||
createTimetableLocal(of(2019, 3, 5, 9, 40), 3, "213", "W-F"),
|
||||
createTimetableLocal(of(2019, 3, 5, 10, 30),3, "213", "W-F", "Jan Kowalski")
|
||||
))
|
||||
|
||||
every { mockSdk.getTimetable(any(), any()) } returns Single.just(listOf(
|
||||
createTimetableRemote(of(2019, 3, 5, 8, 0), 1, "", "Przyroda"),
|
||||
createTimetableRemote(of(2019, 3, 5, 8, 50), 2, "", "Religia"),
|
||||
createTimetableRemote(of(2019, 3, 5, 9, 40), 3, "", "W-F"),
|
||||
createTimetableRemote(of(2019, 3, 5, 10, 30), 4, "", "W-F")
|
||||
))
|
||||
|
||||
val lessons = TimetableRepository(settings, timetableLocal, timetableRemote, timetableNotificationSchedulerHelper)
|
||||
.getTimetable(student, semesterMock, LocalDate.of(2019, 3, 5), LocalDate.of(2019, 3, 5), true)
|
||||
.blockingGet()
|
||||
|
||||
assertEquals(4, lessons.size)
|
||||
assertEquals("123", lessons[0].room)
|
||||
assertEquals("321", lessons[1].room)
|
||||
assertEquals("213", lessons[2].room)
|
||||
}
|
||||
|
||||
@Test
|
||||
fun copyTeacherToCompletedFromPrevious() {
|
||||
timetableLocal.saveTimetable(listOf(
|
||||
createTimetableLocal(of(2019, 12, 23, 8, 0), 1, "123", "Matematyka", "Paweł Poniedziałkowski", false),
|
||||
createTimetableLocal(of(2019, 12, 23, 8, 50), 2, "124", "Matematyka", "Paweł Poniedziałkowski", false),
|
||||
createTimetableLocal(of(2019, 12, 23, 9, 40), 3, "125", "Język polski", "Joanna Wtorkowska", true),
|
||||
createTimetableLocal(of(2019, 12, 23, 10, 40), 4, "126", "Język polski", "Joanna Wtorkowska", true),
|
||||
|
||||
createTimetableLocal(of(2019, 12, 24, 8, 0), 1, "123", "Język polski", "Joanna Wtorkowska", false),
|
||||
createTimetableLocal(of(2019, 12, 24, 8, 50), 2, "124", "Język polski", "Joanna Wtorkowska", false),
|
||||
createTimetableLocal(of(2019, 12, 24, 9, 40), 3, "125", "Język polski", "Joanna Środowska", true),
|
||||
createTimetableLocal(of(2019, 12, 24, 10, 40), 4, "126", "Język polski", "Joanna Środowska", true),
|
||||
|
||||
createTimetableLocal(of(2019, 12, 25, 8, 0), 1, "123", "Matematyka", "", false),
|
||||
createTimetableLocal(of(2019, 12, 25, 8, 50), 2, "124", "Matematyka", "", false),
|
||||
createTimetableLocal(of(2019, 12, 25, 9, 40), 3, "125", "Matematyka", "", true),
|
||||
createTimetableLocal(of(2019, 12, 25, 10, 40), 4, "126", "Matematyka", "", true)
|
||||
))
|
||||
|
||||
every { mockSdk.getTimetable(any(), any()) } returns Single.just(listOf(
|
||||
createTimetableRemote(of(2019, 12, 23, 8, 0), 1, "123", "Matematyka", "Paweł Poniedziałkowski", false),
|
||||
createTimetableRemote(of(2019, 12, 23, 8, 50), 2, "124", "Matematyka", "Jakub Wtorkowski", true),
|
||||
createTimetableRemote(of(2019, 12, 23, 9, 40), 3, "125", "Język polski", "Joanna Poniedziałkowska", false),
|
||||
createTimetableRemote(of(2019, 12, 23, 10, 40), 4, "126", "Język polski", "Joanna Wtorkowska", true),
|
||||
|
||||
createTimetableRemote(of(2019, 12, 24, 8, 0), 1, "123", "Język polski", "", false),
|
||||
createTimetableRemote(of(2019, 12, 24, 8, 50), 2, "124", "Język polski", "", true),
|
||||
createTimetableRemote(of(2019, 12, 24, 9, 40), 3, "125", "Język polski", "", false),
|
||||
createTimetableRemote(of(2019, 12, 24, 10, 40), 4, "126", "Język polski", "", true),
|
||||
|
||||
createTimetableRemote(of(2019, 12, 25, 8, 0), 1, "123", "Matematyka", "Paweł Środowski", false),
|
||||
createTimetableRemote(of(2019, 12, 25, 8, 50), 2, "124", "Matematyka", "Paweł Czwartkowski", true),
|
||||
createTimetableRemote(of(2019, 12, 25, 9, 40), 3, "125", "Matematyka", "Paweł Środowski", false),
|
||||
createTimetableRemote(of(2019, 12, 25, 10, 40), 4, "126", "Matematyka", "Paweł Czwartkowski", true)
|
||||
))
|
||||
|
||||
val lessons = TimetableRepository(settings, timetableLocal, timetableRemote, timetableNotificationSchedulerHelper)
|
||||
.getTimetable(student, semesterMock, LocalDate.of(2019, 12, 23), LocalDate.of(2019, 12, 25), true)
|
||||
.blockingGet()
|
||||
|
||||
assertEquals(12, lessons.size)
|
||||
|
||||
assertEquals("Paweł Poniedziałkowski", lessons[0].teacher)
|
||||
assertEquals("Jakub Wtorkowski", lessons[1].teacher)
|
||||
assertEquals("Joanna Poniedziałkowska", lessons[2].teacher)
|
||||
assertEquals("Joanna Wtorkowska", lessons[3].teacher)
|
||||
|
||||
assertEquals("Joanna Wtorkowska", lessons[4].teacher)
|
||||
assertEquals("", lessons[5].teacher)
|
||||
assertEquals("", lessons[6].teacher)
|
||||
assertEquals("", lessons[7].teacher)
|
||||
|
||||
assertEquals("Paweł Środowski", lessons[8].teacher)
|
||||
assertEquals("Paweł Czwartkowski", lessons[9].teacher)
|
||||
assertEquals("Paweł Środowski", lessons[10].teacher)
|
||||
assertEquals("Paweł Czwartkowski", lessons[11].teacher)
|
||||
}
|
||||
}
|
92
app/src/debug/agconnect-services.json
Normal file
|
@ -0,0 +1,92 @@
|
|||
{
|
||||
"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_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"
|
||||
}
|
||||
}
|
||||
]
|
||||
}
|
Before Width: | Height: | Size: 478 B |
Before Width: | Height: | Size: 652 B |
Before Width: | Height: | Size: 384 B |
Before Width: | Height: | Size: 460 B |
Before Width: | Height: | Size: 355 B |
Before Width: | Height: | Size: 451 B |
Before Width: | Height: | Size: 297 B |
Before Width: | Height: | Size: 339 B |
Before Width: | Height: | Size: 588 B |
Before Width: | Height: | Size: 897 B |
Before Width: | Height: | Size: 508 B |
Before Width: | Height: | Size: 586 B |
Before Width: | Height: | Size: 781 B |
Before Width: | Height: | Size: 1.3 KiB |
Before Width: | Height: | Size: 692 B |
Before Width: | Height: | Size: 805 B |
19
app/src/debug/res/drawable/ic_stat_timetable.xml
Normal file
|
@ -0,0 +1,19 @@
|
|||
<vector xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
android:width="24dp"
|
||||
android:height="24dp"
|
||||
android:tint="#FFFFFF"
|
||||
android:viewportWidth="24"
|
||||
android:viewportHeight="24">
|
||||
<group
|
||||
android:scaleX="0.92"
|
||||
android:scaleY="0.92"
|
||||
android:translateX="0.96"
|
||||
android:translateY="0.96">
|
||||
<path
|
||||
android:fillColor="#FFF"
|
||||
android:pathData="M3.9512,2A2,2 0,0 0,2 4L2,18A2,2 0,0 0,4 20L10.0996,20C11.3596,21.24 13.09,22 15,22A7,7 0,0 0,15.7988 21.9551L15.7988,19.7832A4.85,4.85 0,0 1,15 19.8496C12.32,19.8496 10.1504,17.68 10.1504,15A4.85,4.85 0,0 1,15 10.1504C17.4677,10.1504 19.4978,11.9912 19.8047,14.375C20.566,14.3758 21.3108,14.5325 21.9922,14.834C21.9491,12.9905 21.2036,11.3226 20,10.0996L20,4A2,2 0,0 0,18 2L4,2A2,2 0,0 0,3.9512 2zM4,5L10,5L10,8L4,8L4,5zM12,5L18,5L18,8L12,8L12,5zM4,10L10.0996,10C9.2596,10.82 8.6291,11.85 8.2891,13L4,13L4,10zM14,12L14,15.6895L15.7988,16.7266L15.7988,14.9922L15.5,14.8203L15.5,12L14,12zM4,15L8,15C8,16.07 8.2399,17.09 8.6699,18L4,18L4,15z" />
|
||||
<path
|
||||
android:fillColor="#FFF"
|
||||
android:pathData="m17.298,24v-8.1249h2.5c0.7143,0 1.3523,0.1618 1.9141,0.4855 0.5655,0.3199 1.0063,0.7775 1.3225,1.3728 0.3162,0.5915 0.4743,1.2649 0.4743,2.0201v0.3739c0,0.7552 -0.1562,1.4267 -0.4687,2.0145 -0.3088,0.5878 -0.7459,1.0435 -1.3114,1.3672C21.1633,23.8326 20.5253,23.9963 19.8148,24ZM18.9721,17.2311v5.4241h0.8091c0.6548,0 1.1551,-0.2139 1.5011,-0.6417 0.346,-0.4278 0.5227,-1.0398 0.5301,-1.8359v-0.4297c0,-0.8259 -0.1711,-1.4509 -0.5134,-1.875 -0.3423,-0.4278 -0.8426,-0.6417 -1.5011,-0.6417z" />
|
||||
</group>
|
||||
</vector>
|
28
app/src/fdroid/java/io/github/wulkanowy/utils/AdsHelper.kt
Normal 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)
|
|
@ -6,7 +6,7 @@ import javax.inject.Singleton
|
|||
|
||||
@Singleton
|
||||
@Suppress("UNUSED_PARAMETER")
|
||||
class FirebaseAnalyticsHelper @Inject constructor() {
|
||||
class AnalyticsHelper @Inject constructor() {
|
||||
|
||||
fun logEvent(name: String, vararg params: Pair<String, Any?>) {
|
||||
// do nothing
|
||||
|
@ -15,4 +15,8 @@ class FirebaseAnalyticsHelper @Inject constructor() {
|
|||
fun setCurrentScreen(activity: Activity, name: String?) {
|
||||
// do nothing
|
||||
}
|
||||
|
||||
fun popCurrentScreen(name: String?) {
|
||||
// do nothing
|
||||
}
|
||||
}
|
|
@ -8,6 +8,6 @@ open class TimberTreeNoOp : Timber.Tree() {
|
|||
override fun log(priority: Int, tag: String?, message: String, t: Throwable?) {}
|
||||
}
|
||||
|
||||
class CrashlyticsTree : TimberTreeNoOp()
|
||||
class CrashLogTree : TimberTreeNoOp()
|
||||
|
||||
class CrashlyticsExceptionTree : TimberTreeNoOp()
|
||||
class CrashLogExceptionTree : TimberTreeNoOp()
|
|
@ -0,0 +1,18 @@
|
|||
package io.github.wulkanowy.utils
|
||||
|
||||
import android.content.Context
|
||||
import dagger.hilt.android.qualifiers.ApplicationContext
|
||||
import io.github.wulkanowy.ui.modules.main.MainActivity
|
||||
import javax.inject.Singleton
|
||||
import javax.inject.Inject
|
||||
|
||||
@Suppress("UNUSED_PARAMETER", "unused")
|
||||
@Singleton
|
||||
class InAppReviewHelper @Inject constructor(
|
||||
@ApplicationContext private val context: Context
|
||||
) {
|
||||
|
||||
fun showInAppReview(activity: MainActivity) {
|
||||
// do nothing
|
||||
}
|
||||
}
|
|
@ -0,0 +1,17 @@
|
|||
package io.github.wulkanowy.utils
|
||||
|
||||
import android.app.Activity
|
||||
import android.view.View
|
||||
import javax.inject.Inject
|
||||
|
||||
@Suppress("UNUSED_PARAMETER")
|
||||
class UpdateHelper @Inject constructor() {
|
||||
|
||||
lateinit var messageContainer: View
|
||||
|
||||
fun checkAndInstallUpdates(activity: Activity) {}
|
||||
|
||||
fun onActivityResult(requestCode: Int, resultCode: Int) {}
|
||||
|
||||
fun onResume(activity: Activity) {}
|
||||
}
|
28
app/src/hms/java/io/github/wulkanowy/utils/AdsHelper.kt
Normal 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)
|
|
@ -0,0 +1,39 @@
|
|||
package io.github.wulkanowy.utils
|
||||
|
||||
import android.app.Activity
|
||||
import android.content.Context
|
||||
import android.os.Bundle
|
||||
import com.huawei.hms.analytics.HiAnalytics
|
||||
import dagger.hilt.android.qualifiers.ApplicationContext
|
||||
import javax.inject.Inject
|
||||
import javax.inject.Singleton
|
||||
|
||||
@Singleton
|
||||
class AnalyticsHelper @Inject constructor(
|
||||
@ApplicationContext private val context: Context
|
||||
) {
|
||||
|
||||
private val analytics by lazy { HiAnalytics.getInstance(context) }
|
||||
|
||||
fun logEvent(name: String, vararg params: Pair<String, Any?>) {
|
||||
Bundle().apply {
|
||||
params.forEach {
|
||||
if (it.second == null) return@forEach
|
||||
when (it.second) {
|
||||
is String, is String? -> putString(it.first, it.second as String)
|
||||
is Int, is Int? -> putInt(it.first, it.second as Int)
|
||||
is Boolean, is Boolean? -> putBoolean(it.first, it.second as Boolean)
|
||||
}
|
||||
}
|
||||
analytics.onEvent(name, this)
|
||||
}
|
||||
}
|
||||
|
||||
fun setCurrentScreen(activity: Activity, name: String?) {
|
||||
analytics.pageStart(name, activity::class.simpleName)
|
||||
}
|
||||
|
||||
fun popCurrentScreen(name: String?) {
|
||||
analytics.pageEnd(name)
|
||||
}
|
||||
}
|
37
app/src/hms/java/io/github/wulkanowy/utils/CrashLogUtils.kt
Normal file
|
@ -0,0 +1,37 @@
|
|||
package io.github.wulkanowy.utils
|
||||
|
||||
import android.util.Log
|
||||
import com.huawei.agconnect.crash.AGConnectCrash
|
||||
import fr.bipi.tressence.base.FormatterPriorityTree
|
||||
|
||||
class CrashLogTree : FormatterPriorityTree(Log.VERBOSE) {
|
||||
|
||||
private val connectCrash by lazy { AGConnectCrash.getInstance() }
|
||||
|
||||
override fun log(priority: Int, tag: String?, message: String, t: Throwable?) {
|
||||
if (skipLog(priority, tag, message, t)) return
|
||||
|
||||
connectCrash.log(format(priority, tag, message))
|
||||
}
|
||||
}
|
||||
|
||||
class CrashLogExceptionTree : FormatterPriorityTree(Log.ERROR, ExceptionFilter) {
|
||||
|
||||
private val connectCrash by lazy { AGConnectCrash.getInstance() }
|
||||
|
||||
override fun log(priority: Int, tag: String?, message: String, t: Throwable?) {
|
||||
if (skipLog(priority, tag, message, t)) return
|
||||
|
||||
// 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)))
|
||||
}*/
|
||||
}
|
||||
}
|
|
@ -0,0 +1,18 @@
|
|||
package io.github.wulkanowy.utils
|
||||
|
||||
import android.content.Context
|
||||
import dagger.hilt.android.qualifiers.ApplicationContext
|
||||
import io.github.wulkanowy.ui.modules.main.MainActivity
|
||||
import javax.inject.Inject
|
||||
import javax.inject.Singleton
|
||||
|
||||
@Singleton
|
||||
@Suppress("UNUSED_PARAMETER", "unused")
|
||||
class InAppReviewHelper @Inject constructor(
|
||||
@ApplicationContext private val context: Context
|
||||
) {
|
||||
|
||||
fun showInAppReview(activity: MainActivity) {
|
||||
// do nothing
|
||||
}
|
||||
}
|
17
app/src/hms/java/io/github/wulkanowy/utils/UpdateHelper.kt
Normal file
|
@ -0,0 +1,17 @@
|
|||
package io.github.wulkanowy.utils
|
||||
|
||||
import android.app.Activity
|
||||
import android.view.View
|
||||
import javax.inject.Inject
|
||||
|
||||
@Suppress("UNUSED_PARAMETER")
|
||||
class UpdateHelper @Inject constructor() {
|
||||
|
||||
lateinit var messageContainer: View
|
||||
|
||||
fun checkAndInstallUpdates(activity: Activity) {}
|
||||
|
||||
fun onActivityResult(requestCode: Int, resultCode: Int) {}
|
||||
|
||||
fun onResume(activity: Activity) {}
|
||||
}
|
|
@ -1,27 +1,51 @@
|
|||
<?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" />
|
||||
<uses-permission android:name="android.permission.ACCESS_NETWORK_STATE" />
|
||||
<uses-permission android:name="android.permission.WAKE_LOCK" />
|
||||
<uses-permission android:name="android.permission.RECEIVE_BOOT_COMPLETED" />
|
||||
<uses-permission android:name="android.permission.VIBRATE" />
|
||||
<uses-permission android:name="android.permission.SCHEDULE_EXACT_ALARM"/>
|
||||
|
||||
<queries>
|
||||
<intent>
|
||||
<action android:name="android.intent.action.VIEW" />
|
||||
<data android:scheme="http" />
|
||||
</intent>
|
||||
<intent>
|
||||
<action android:name="android.intent.action.VIEW" />
|
||||
<data android:scheme="https" />
|
||||
</intent>
|
||||
<intent>
|
||||
<action android:name="android.intent.action.VIEW" />
|
||||
<data android:scheme="mailto" />
|
||||
</intent>
|
||||
<intent>
|
||||
<action android:name="android.intent.action.VIEW" />
|
||||
<data android:scheme="tel" />
|
||||
</intent>
|
||||
<intent>
|
||||
<action android:name="android.intent.action.VIEW" />
|
||||
<data android:scheme="geo" />
|
||||
</intent>
|
||||
</queries>
|
||||
|
||||
<application
|
||||
android:name=".WulkanowyApp"
|
||||
android:allowBackup="false"
|
||||
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"
|
||||
tools:replace="android:supportsRtl,android:allowBackup">
|
||||
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">
|
||||
|
@ -34,7 +58,7 @@
|
|||
android:name=".ui.modules.login.LoginActivity"
|
||||
android:configChanges="orientation|screenSize"
|
||||
android:label="@string/login_title"
|
||||
android:theme="@style/WulkanowyTheme.NoActionBar"
|
||||
android:theme="@style/WulkanowyTheme.Login"
|
||||
android:windowSoftInputMode="adjustResize" />
|
||||
<activity
|
||||
android:name=".ui.modules.main.MainActivity"
|
||||
|
@ -46,11 +70,12 @@
|
|||
android:name=".ui.modules.message.send.SendMessageActivity"
|
||||
android:configChanges="orientation|screenSize"
|
||||
android:label="@string/send_message_title"
|
||||
android:theme="@style/WulkanowyTheme.NoActionBar"
|
||||
android:theme="@style/WulkanowyTheme.MessageSend"
|
||||
android:windowSoftInputMode="adjustResize" />
|
||||
<activity
|
||||
android:name=".ui.modules.timetablewidget.TimetableWidgetConfigureActivity"
|
||||
android:excludeFromRecents="true"
|
||||
android:exported="true"
|
||||
android:noHistory="true"
|
||||
android:theme="@style/WulkanowyTheme.WidgetAccountSwitcher">
|
||||
<intent-filter>
|
||||
|
@ -60,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>
|
||||
|
@ -70,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"
|
||||
|
@ -84,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" />
|
||||
|
@ -96,11 +139,9 @@
|
|||
<receiver android:name=".services.alarm.TimetableNotificationReceiver" />
|
||||
|
||||
<provider
|
||||
android:name="androidx.work.impl.WorkManagerInitializer"
|
||||
android:authorities="${applicationId}.workmanager-init"
|
||||
android:exported="false"
|
||||
android:name="androidx.startup.InitializationProvider"
|
||||
android:authorities="${applicationId}.androidx-startup"
|
||||
tools:node="remove" />
|
||||
|
||||
<provider
|
||||
android:name="androidx.core.content.FileProvider"
|
||||
android:authorities="${applicationId}.fileprovider"
|
||||
|
@ -117,34 +158,38 @@
|
|||
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_push" />
|
||||
|
||||
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>
|
||||
|
|
|
@ -33,6 +33,22 @@
|
|||
},
|
||||
{
|
||||
"displayName": "Mateusz Idziejczak",
|
||||
"githubUsername": "PanTajemnic"
|
||||
"githubUsername": "Luncenok"
|
||||
},
|
||||
{
|
||||
"displayName": "Daniel Olczyk",
|
||||
"githubUsername": "MRmlik12"
|
||||
},
|
||||
{
|
||||
"displayName": "Damian Czupryn",
|
||||
"githubUsername": "Daxxxis"
|
||||
},
|
||||
{
|
||||
"displayName": "Kamil Studziński",
|
||||
"githubUsername": "studzinskik"
|
||||
},
|
||||
{
|
||||
"displayName": "Tomasz F.",
|
||||
"githubUsername": "Pengwius"
|
||||
}
|
||||
]
|
||||
|
|
|
@ -1,34 +1,23 @@
|
|||
package io.github.wulkanowy
|
||||
|
||||
import android.content.Context
|
||||
import android.util.Log.DEBUG
|
||||
import android.util.Log.INFO
|
||||
import android.util.Log.VERBOSE
|
||||
import androidx.multidex.MultiDex
|
||||
import android.app.Application
|
||||
import android.util.Log.*
|
||||
import androidx.hilt.work.HiltWorkerFactory
|
||||
import androidx.work.Configuration
|
||||
import com.jakewharton.threetenabp.AndroidThreeTen
|
||||
import com.yariksoffice.lingver.Lingver
|
||||
import dagger.android.AndroidInjector
|
||||
import dagger.android.support.DaggerApplication
|
||||
import dagger.hilt.android.HiltAndroidApp
|
||||
import fr.bipi.tressence.file.FileLoggerTree
|
||||
import io.github.wulkanowy.di.DaggerAppComponent
|
||||
import io.github.wulkanowy.services.sync.SyncWorkerFactory
|
||||
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.AppInfo
|
||||
import io.github.wulkanowy.utils.CrashlyticsExceptionTree
|
||||
import io.github.wulkanowy.utils.CrashlyticsTree
|
||||
import io.github.wulkanowy.utils.DebugLogTree
|
||||
import io.reactivex.exceptions.UndeliverableException
|
||||
import io.reactivex.plugins.RxJavaPlugins
|
||||
import io.github.wulkanowy.utils.*
|
||||
import timber.log.Timber
|
||||
import java.io.IOException
|
||||
import javax.inject.Inject
|
||||
|
||||
class WulkanowyApp : DaggerApplication(), Configuration.Provider {
|
||||
@HiltAndroidApp
|
||||
class WulkanowyApp : Application(), Configuration.Provider {
|
||||
|
||||
@Inject
|
||||
lateinit var workerFactory: SyncWorkerFactory
|
||||
lateinit var workerFactory: HiltWorkerFactory
|
||||
|
||||
@Inject
|
||||
lateinit var themeManager: ThemeManager
|
||||
|
@ -36,48 +25,50 @@ class WulkanowyApp : DaggerApplication(), Configuration.Provider {
|
|||
@Inject
|
||||
lateinit var appInfo: AppInfo
|
||||
|
||||
override fun attachBaseContext(base: Context?) {
|
||||
super.attachBaseContext(base)
|
||||
MultiDex.install(this)
|
||||
}
|
||||
@Inject
|
||||
lateinit var preferencesRepository: PreferencesRepository
|
||||
|
||||
@Inject
|
||||
lateinit var analyticsHelper: AnalyticsHelper
|
||||
|
||||
@Inject
|
||||
lateinit var adsHelper: AdsHelper
|
||||
|
||||
override fun onCreate() {
|
||||
super.onCreate()
|
||||
AndroidThreeTen.init(this)
|
||||
RxJavaPlugins.setErrorHandler(::onError)
|
||||
Lingver.init(this)
|
||||
initializeAppLanguage()
|
||||
themeManager.applyDefaultTheme()
|
||||
|
||||
adsHelper.initialize()
|
||||
initLogging()
|
||||
}
|
||||
|
||||
private fun initLogging() {
|
||||
if (appInfo.isDebug) {
|
||||
Timber.plant(DebugLogTree())
|
||||
Timber.plant(FileLoggerTree.Builder()
|
||||
.withFileName("wulkanowy.%g.log")
|
||||
.withDirName(applicationContext.filesDir.absolutePath)
|
||||
.withFileLimit(10)
|
||||
.withMinPriority(DEBUG)
|
||||
.build()
|
||||
Timber.plant(
|
||||
FileLoggerTree.Builder()
|
||||
.withFileName("wulkanowy.%g.log")
|
||||
.withDirName(applicationContext.filesDir.absolutePath)
|
||||
.withFileLimit(10)
|
||||
.withMinPriority(DEBUG)
|
||||
.build()
|
||||
)
|
||||
} else {
|
||||
Timber.plant(CrashlyticsExceptionTree())
|
||||
Timber.plant(CrashlyticsTree())
|
||||
Timber.plant(CrashLogExceptionTree())
|
||||
Timber.plant(CrashLogTree())
|
||||
}
|
||||
registerActivityLifecycleCallbacks(ActivityLifecycleLogger())
|
||||
}
|
||||
|
||||
private fun onError(error: Throwable) {
|
||||
//RxJava's too deep stack traces may cause SOE on older android devices
|
||||
val cause = error.cause
|
||||
if (error is UndeliverableException && cause is IOException || cause is InterruptedException || cause is StackOverflowError) {
|
||||
Timber.e(cause, "An undeliverable error occurred")
|
||||
} else throw error
|
||||
}
|
||||
private fun initializeAppLanguage() {
|
||||
Lingver.init(this)
|
||||
|
||||
override fun applicationInjector(): AndroidInjector<out DaggerApplication> {
|
||||
return DaggerAppComponent.factory().create(this)
|
||||
if (preferencesRepository.appLanguage == "system") {
|
||||
Lingver.getInstance().setFollowSystemLocale(this)
|
||||
analyticsHelper.logEvent("language", "startup" to appInfo.systemLanguage)
|
||||
} else {
|
||||
analyticsHelper.logEvent("language", "startup" to preferencesRepository.appLanguage)
|
||||
}
|
||||
}
|
||||
|
||||
override fun getWorkManagerConfiguration() = Configuration.Builder()
|
||||
|
|
243
app/src/main/java/io/github/wulkanowy/data/DataModule.kt
Normal file
|
@ -0,0 +1,243 @@
|
|||
package io.github.wulkanowy.data
|
||||
|
||||
import android.content.Context
|
||||
import android.content.SharedPreferences
|
||||
import androidx.preference.PreferenceManager
|
||||
import com.chuckerteam.chucker.api.ChuckerCollector
|
||||
import com.chuckerteam.chucker.api.ChuckerInterceptor
|
||||
import com.chuckerteam.chucker.api.RetentionManager
|
||||
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.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 DataModule {
|
||||
|
||||
@Singleton
|
||||
@Provides
|
||||
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, network = true)
|
||||
}
|
||||
|
||||
@Singleton
|
||||
@Provides
|
||||
fun provideChuckerCollector(
|
||||
@ApplicationContext context: Context,
|
||||
prefRepository: PreferencesRepository
|
||||
) = 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
|
||||
fun provideDatabase(
|
||||
@ApplicationContext context: Context,
|
||||
sharedPrefProvider: SharedPrefProvider,
|
||||
appInfo: AppInfo
|
||||
) = AppDatabase.newInstance(context, sharedPrefProvider, appInfo)
|
||||
|
||||
@Singleton
|
||||
@Provides
|
||||
fun provideSharedPref(@ApplicationContext context: Context): SharedPreferences =
|
||||
PreferenceManager.getDefaultSharedPreferences(context)
|
||||
|
||||
@Singleton
|
||||
@Provides
|
||||
fun provideFlowSharedPref(sharedPreferences: SharedPreferences) =
|
||||
FlowSharedPreferences(sharedPreferences)
|
||||
|
||||
@Singleton
|
||||
@Provides
|
||||
fun provideJson() = Json {
|
||||
ignoreUnknownKeys = true
|
||||
}
|
||||
|
||||
@Singleton
|
||||
@Provides
|
||||
fun provideStudentDao(database: AppDatabase) = database.studentDao
|
||||
|
||||
@Singleton
|
||||
@Provides
|
||||
fun provideSemesterDao(database: AppDatabase) = database.semesterDao
|
||||
|
||||
@Singleton
|
||||
@Provides
|
||||
fun provideGradeDao(database: AppDatabase) = database.gradeDao
|
||||
|
||||
@Singleton
|
||||
@Provides
|
||||
fun provideGradeSummaryDao(database: AppDatabase) = database.gradeSummaryDao
|
||||
|
||||
@Singleton
|
||||
@Provides
|
||||
fun provideGradePartialStatisticsDao(database: AppDatabase) = database.gradePartialStatisticsDao
|
||||
|
||||
@Singleton
|
||||
@Provides
|
||||
fun provideGradeSemesterStatisticsDao(database: AppDatabase) =
|
||||
database.gradeSemesterStatisticsDao
|
||||
|
||||
@Singleton
|
||||
@Provides
|
||||
fun provideGradePointsStatisticsDao(database: AppDatabase) = database.gradePointsStatisticsDao
|
||||
|
||||
@Singleton
|
||||
@Provides
|
||||
fun provideMessagesDao(database: AppDatabase) = database.messagesDao
|
||||
|
||||
@Singleton
|
||||
@Provides
|
||||
fun provideMessageAttachmentsDao(database: AppDatabase) = database.messageAttachmentDao
|
||||
|
||||
@Singleton
|
||||
@Provides
|
||||
fun provideExamDao(database: AppDatabase) = database.examsDao
|
||||
|
||||
@Singleton
|
||||
@Provides
|
||||
fun provideAttendanceDao(database: AppDatabase) = database.attendanceDao
|
||||
|
||||
@Singleton
|
||||
@Provides
|
||||
fun provideAttendanceSummaryDao(database: AppDatabase) = database.attendanceSummaryDao
|
||||
|
||||
@Singleton
|
||||
@Provides
|
||||
fun provideTimetableDao(database: AppDatabase) = database.timetableDao
|
||||
|
||||
@Singleton
|
||||
@Provides
|
||||
fun provideNoteDao(database: AppDatabase) = database.noteDao
|
||||
|
||||
@Singleton
|
||||
@Provides
|
||||
fun provideHomeworkDao(database: AppDatabase) = database.homeworkDao
|
||||
|
||||
@Singleton
|
||||
@Provides
|
||||
fun provideSubjectDao(database: AppDatabase) = database.subjectDao
|
||||
|
||||
@Singleton
|
||||
@Provides
|
||||
fun provideLuckyNumberDao(database: AppDatabase) = database.luckyNumberDao
|
||||
|
||||
@Singleton
|
||||
@Provides
|
||||
fun provideCompletedLessonsDao(database: AppDatabase) = database.completedLessonsDao
|
||||
|
||||
@Singleton
|
||||
@Provides
|
||||
fun provideMailboxesDao(database: AppDatabase) = database.mailboxDao
|
||||
|
||||
@Singleton
|
||||
@Provides
|
||||
fun provideRecipientDao(database: AppDatabase) = database.recipientDao
|
||||
|
||||
@Singleton
|
||||
@Provides
|
||||
fun provideMobileDevicesDao(database: AppDatabase) = database.mobileDeviceDao
|
||||
|
||||
@Singleton
|
||||
@Provides
|
||||
fun provideTeacherDao(database: AppDatabase) = database.teacherDao
|
||||
|
||||
@Singleton
|
||||
@Provides
|
||||
fun provideSchoolInfoDao(database: AppDatabase) = database.schoolDao
|
||||
|
||||
@Singleton
|
||||
@Provides
|
||||
fun provideConferenceDao(database: AppDatabase) = database.conferenceDao
|
||||
|
||||
@Singleton
|
||||
@Provides
|
||||
fun provideTimetableAdditionalDao(database: AppDatabase) = database.timetableAdditionalDao
|
||||
|
||||
@Singleton
|
||||
@Provides
|
||||
fun provideStudentInfoDao(database: AppDatabase) = database.studentInfoDao
|
||||
|
||||
@Singleton
|
||||
@Provides
|
||||
fun provideTimetableHeaderDao(database: AppDatabase) = database.timetableHeaderDao
|
||||
|
||||
@Singleton
|
||||
@Provides
|
||||
fun provideSchoolAnnouncementDao(database: AppDatabase) = database.schoolAnnouncementDao
|
||||
|
||||
@Singleton
|
||||
@Provides
|
||||
fun provideNotificationDao(database: AppDatabase) = database.notificationDao
|
||||
|
||||
@Singleton
|
||||
@Provides
|
||||
fun provideAdminMessageDao(database: AppDatabase) = database.adminMessagesDao
|
||||
}
|
|
@ -1,159 +0,0 @@
|
|||
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.github.pwittchen.reactivenetwork.library.rx2.internet.observing.InternetObservingSettings
|
||||
import com.github.pwittchen.reactivenetwork.library.rx2.internet.observing.strategy.WalledGardenInternetObservingStrategy
|
||||
import dagger.Module
|
||||
import dagger.Provides
|
||||
import io.github.wulkanowy.data.db.AppDatabase
|
||||
import io.github.wulkanowy.data.db.SharedPrefProvider
|
||||
import io.github.wulkanowy.data.repositories.preferences.PreferencesRepository
|
||||
import io.github.wulkanowy.sdk.Sdk
|
||||
import timber.log.Timber
|
||||
import javax.inject.Singleton
|
||||
|
||||
@Module
|
||||
internal class RepositoryModule {
|
||||
|
||||
@Singleton
|
||||
@Provides
|
||||
fun provideInternetObservingSettings(): InternetObservingSettings {
|
||||
return InternetObservingSettings.builder()
|
||||
.strategy(WalledGardenInternetObservingStrategy())
|
||||
.build()
|
||||
}
|
||||
|
||||
@Singleton
|
||||
@Provides
|
||||
fun provideSdk(chuckerCollector: ChuckerCollector, context: Context): Sdk {
|
||||
return Sdk().apply {
|
||||
androidVersion = android.os.Build.VERSION.RELEASE
|
||||
buildTag = android.os.Build.MODEL
|
||||
setSimpleHttpLogger { Timber.d(it) }
|
||||
|
||||
// for debug only
|
||||
addInterceptor(ChuckerInterceptor(context, chuckerCollector), true)
|
||||
}
|
||||
}
|
||||
|
||||
@Singleton
|
||||
@Provides
|
||||
fun provideChuckerCollector(context: Context, prefRepository: PreferencesRepository): ChuckerCollector {
|
||||
return ChuckerCollector(
|
||||
context = context,
|
||||
showNotification = prefRepository.isDebugNotificationEnable,
|
||||
retentionPeriod = RetentionManager.Period.ONE_HOUR
|
||||
)
|
||||
}
|
||||
|
||||
@Singleton
|
||||
@Provides
|
||||
fun provideDatabase(context: Context, sharedPrefProvider: SharedPrefProvider) = AppDatabase.newInstance(context, sharedPrefProvider)
|
||||
|
||||
@Singleton
|
||||
@Provides
|
||||
fun provideResources(context: Context): Resources = context.resources
|
||||
|
||||
@Singleton
|
||||
@Provides
|
||||
fun provideAssets(context: Context): AssetManager = context.assets
|
||||
|
||||
@Singleton
|
||||
@Provides
|
||||
fun provideSharedPref(context: Context): SharedPreferences = PreferenceManager.getDefaultSharedPreferences(context)
|
||||
|
||||
@Singleton
|
||||
@Provides
|
||||
fun provideStudentDao(database: AppDatabase) = database.studentDao
|
||||
|
||||
@Singleton
|
||||
@Provides
|
||||
fun provideSemesterDao(database: AppDatabase) = database.semesterDao
|
||||
|
||||
@Singleton
|
||||
@Provides
|
||||
fun provideGradeDao(database: AppDatabase) = database.gradeDao
|
||||
|
||||
@Singleton
|
||||
@Provides
|
||||
fun provideGradeSummaryDao(database: AppDatabase) = database.gradeSummaryDao
|
||||
|
||||
@Singleton
|
||||
@Provides
|
||||
fun provideGradeStatisticsDao(database: AppDatabase) = database.gradeStatistics
|
||||
|
||||
@Singleton
|
||||
@Provides
|
||||
fun provideGradePointsStatisticsDao(database: AppDatabase) = database.gradePointsStatistics
|
||||
|
||||
@Singleton
|
||||
@Provides
|
||||
fun provideMessagesDao(database: AppDatabase) = database.messagesDao
|
||||
|
||||
@Singleton
|
||||
@Provides
|
||||
fun provideMessageAttachmentsDao(database: AppDatabase) = database.messageAttachmentDao
|
||||
|
||||
@Singleton
|
||||
@Provides
|
||||
fun provideExamDao(database: AppDatabase) = database.examsDao
|
||||
|
||||
@Singleton
|
||||
@Provides
|
||||
fun provideAttendanceDao(database: AppDatabase) = database.attendanceDao
|
||||
|
||||
@Singleton
|
||||
@Provides
|
||||
fun provideAttendanceSummaryDao(database: AppDatabase) = database.attendanceSummaryDao
|
||||
|
||||
@Singleton
|
||||
@Provides
|
||||
fun provideTimetableDao(database: AppDatabase) = database.timetableDao
|
||||
|
||||
@Singleton
|
||||
@Provides
|
||||
fun provideNoteDao(database: AppDatabase) = database.noteDao
|
||||
|
||||
@Singleton
|
||||
@Provides
|
||||
fun provideHomeworkDao(database: AppDatabase) = database.homeworkDao
|
||||
|
||||
@Singleton
|
||||
@Provides
|
||||
fun provideSubjectDao(database: AppDatabase) = database.subjectDao
|
||||
|
||||
@Singleton
|
||||
@Provides
|
||||
fun provideLuckyNumberDao(database: AppDatabase) = database.luckyNumberDao
|
||||
|
||||
@Singleton
|
||||
@Provides
|
||||
fun provideCompletedLessonsDao(database: AppDatabase) = database.completedLessonsDao
|
||||
|
||||
@Singleton
|
||||
@Provides
|
||||
fun provideReportingUnitDao(database: AppDatabase) = database.reportingUnitDao
|
||||
|
||||
@Singleton
|
||||
@Provides
|
||||
fun provideRecipientDao(database: AppDatabase) = database.recipientDao
|
||||
|
||||
@Singleton
|
||||
@Provides
|
||||
fun provideMobileDevicesDao(database: AppDatabase) = database.mobileDeviceDao
|
||||
|
||||
@Singleton
|
||||
@Provides
|
||||
fun provideTeacherDao(database: AppDatabase) = database.teacherDao
|
||||
|
||||
@Singleton
|
||||
@Provides
|
||||
fun provideSchoolInfoDao(database: AppDatabase) = database.schoolDao
|
||||
}
|
173
app/src/main/java/io/github/wulkanowy/data/Resource.kt
Normal file
|
@ -0,0 +1,173 @@
|
|||
package io.github.wulkanowy.data
|
||||
|
||||
import kotlinx.coroutines.flow.*
|
||||
import kotlinx.coroutines.sync.Mutex
|
||||
import kotlinx.coroutines.sync.withLock
|
||||
import timber.log.Timber
|
||||
|
||||
sealed class Resource<T> {
|
||||
|
||||
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
|
||||
}
|
||||
}
|
||||
|
||||
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)) }
|
||||
})
|
||||
}
|
|
@ -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>
|
||||
}
|