From 4d1de2d8ce6856928c0ea964c264b279e68e70e8 Mon Sep 17 00:00:00 2001 From: Dominik Korsa Date: Sun, 12 Jan 2020 14:21:33 +0100 Subject: [PATCH 01/18] Add debug notification icons (#637) --- .../res/drawable-anydpi-v24/ic_stat_grade.xml | 12 ++++++++++++ .../drawable-anydpi-v24/ic_stat_luckynumber.xml | 12 ++++++++++++ .../res/drawable-anydpi-v24/ic_stat_message.xml | 12 ++++++++++++ .../res/drawable-anydpi-v24/ic_stat_note.xml | 12 ++++++++++++ .../debug/res/drawable-hdpi/ic_stat_grade.png | Bin 0 -> 478 bytes .../res/drawable-hdpi/ic_stat_luckynumber.png | Bin 0 -> 652 bytes .../debug/res/drawable-hdpi/ic_stat_message.png | Bin 0 -> 384 bytes app/src/debug/res/drawable-hdpi/ic_stat_note.png | Bin 0 -> 460 bytes .../debug/res/drawable-mdpi/ic_stat_grade.png | Bin 0 -> 355 bytes .../res/drawable-mdpi/ic_stat_luckynumber.png | Bin 0 -> 451 bytes .../debug/res/drawable-mdpi/ic_stat_message.png | Bin 0 -> 297 bytes app/src/debug/res/drawable-mdpi/ic_stat_note.png | Bin 0 -> 339 bytes .../debug/res/drawable-xhdpi/ic_stat_grade.png | Bin 0 -> 588 bytes .../res/drawable-xhdpi/ic_stat_luckynumber.png | Bin 0 -> 897 bytes .../debug/res/drawable-xhdpi/ic_stat_message.png | Bin 0 -> 508 bytes .../debug/res/drawable-xhdpi/ic_stat_note.png | Bin 0 -> 586 bytes .../debug/res/drawable-xxhdpi/ic_stat_grade.png | Bin 0 -> 781 bytes .../res/drawable-xxhdpi/ic_stat_luckynumber.png | Bin 0 -> 1329 bytes .../res/drawable-xxhdpi/ic_stat_message.png | Bin 0 -> 692 bytes .../debug/res/drawable-xxhdpi/ic_stat_note.png | Bin 0 -> 805 bytes .../res/drawable-anydpi-v24/ic_stat_grade.xml | 10 +++------- .../drawable-anydpi-v24/ic_stat_luckynumber.xml | 10 +++------- .../res/drawable-anydpi-v24/ic_stat_message.xml | 10 +++------- .../res/drawable-anydpi-v24/ic_stat_note.xml | 10 +++------- app/src/main/res/drawable/ic_main_grade.xml | 6 ++++-- app/src/main/res/drawable/ic_main_more.xml | 6 ++++-- 26 files changed, 68 insertions(+), 32 deletions(-) create mode 100644 app/src/debug/res/drawable-anydpi-v24/ic_stat_grade.xml create mode 100644 app/src/debug/res/drawable-anydpi-v24/ic_stat_luckynumber.xml create mode 100644 app/src/debug/res/drawable-anydpi-v24/ic_stat_message.xml create mode 100644 app/src/debug/res/drawable-anydpi-v24/ic_stat_note.xml create mode 100644 app/src/debug/res/drawable-hdpi/ic_stat_grade.png create mode 100644 app/src/debug/res/drawable-hdpi/ic_stat_luckynumber.png create mode 100644 app/src/debug/res/drawable-hdpi/ic_stat_message.png create mode 100644 app/src/debug/res/drawable-hdpi/ic_stat_note.png create mode 100644 app/src/debug/res/drawable-mdpi/ic_stat_grade.png create mode 100644 app/src/debug/res/drawable-mdpi/ic_stat_luckynumber.png create mode 100644 app/src/debug/res/drawable-mdpi/ic_stat_message.png create mode 100644 app/src/debug/res/drawable-mdpi/ic_stat_note.png create mode 100644 app/src/debug/res/drawable-xhdpi/ic_stat_grade.png create mode 100644 app/src/debug/res/drawable-xhdpi/ic_stat_luckynumber.png create mode 100644 app/src/debug/res/drawable-xhdpi/ic_stat_message.png create mode 100644 app/src/debug/res/drawable-xhdpi/ic_stat_note.png create mode 100644 app/src/debug/res/drawable-xxhdpi/ic_stat_grade.png create mode 100644 app/src/debug/res/drawable-xxhdpi/ic_stat_luckynumber.png create mode 100644 app/src/debug/res/drawable-xxhdpi/ic_stat_message.png create mode 100644 app/src/debug/res/drawable-xxhdpi/ic_stat_note.png diff --git a/app/src/debug/res/drawable-anydpi-v24/ic_stat_grade.xml b/app/src/debug/res/drawable-anydpi-v24/ic_stat_grade.xml new file mode 100644 index 000000000..832eba838 --- /dev/null +++ b/app/src/debug/res/drawable-anydpi-v24/ic_stat_grade.xml @@ -0,0 +1,12 @@ + + + + diff --git a/app/src/debug/res/drawable-anydpi-v24/ic_stat_luckynumber.xml b/app/src/debug/res/drawable-anydpi-v24/ic_stat_luckynumber.xml new file mode 100644 index 000000000..4f3eb98e1 --- /dev/null +++ b/app/src/debug/res/drawable-anydpi-v24/ic_stat_luckynumber.xml @@ -0,0 +1,12 @@ + + + + diff --git a/app/src/debug/res/drawable-anydpi-v24/ic_stat_message.xml b/app/src/debug/res/drawable-anydpi-v24/ic_stat_message.xml new file mode 100644 index 000000000..8fe12de45 --- /dev/null +++ b/app/src/debug/res/drawable-anydpi-v24/ic_stat_message.xml @@ -0,0 +1,12 @@ + + + + diff --git a/app/src/debug/res/drawable-anydpi-v24/ic_stat_note.xml b/app/src/debug/res/drawable-anydpi-v24/ic_stat_note.xml new file mode 100644 index 000000000..d30f22336 --- /dev/null +++ b/app/src/debug/res/drawable-anydpi-v24/ic_stat_note.xml @@ -0,0 +1,12 @@ + + + + diff --git a/app/src/debug/res/drawable-hdpi/ic_stat_grade.png b/app/src/debug/res/drawable-hdpi/ic_stat_grade.png new file mode 100644 index 0000000000000000000000000000000000000000..013b7ac4988d5b4215636dbf10fd4f9666f2c4c0 GIT binary patch literal 478 zcmV<40U`d0P)ABwK|pa$Bz-V!K@A6SAz2wM0%G66;2?BRFwhP<3B>z>_#TvhX;7pgAYC=6a@jyTNEu1) z2@u~0;&)K~g@JGoBM|Svk*L!Ks_I|`;shYBhvHfww!>k*ArPkkaU9JYMC+CzAqVLK zu>!G}Ru0l7vsKuKWNtpR6o=t{APxs&Hj*6#6`w?+V{U@d7LxvrIMjg(Q5}*U1eH_4 z(g?$a718v<9JCcG9|*)Jkcta_k{v{0Qh+&V4w4uT5I@CL@4*zYBQ?0DklB#;BE~^b z@o7-;-S~WSj>0a^9ugb`t7dNCbC5Qu-vq>e$aK(25*$==@LL6HmUsqg#3q)T8DbT5w|*3?*1=8uTnpO m>i_t2LhCFmxBN-u&iDp>Vewr3fQGvO0000sqlSZOk<1H)Mi(*;24Ze{Ip_!wGZN8ycnica z^l*?Bj=J$VG<4d5_$re6NOBx>4v6;?fmh(EtS=ymv4C2QQ1RD5%teZWW+6ub8EF#3 zK~QlsBs)Uz8L*C8jv?S6P$>O{$~6+>Ac`G>&p}YRuduq3kb|h=7!pFL8J_`u)N%{~ z2bmxxjc|JQg0bZ?W+2`K6@L%JyaVANSUJ=L#HW!$Czamg1h`7-&p@0x5Ca$3>M~GE eKxoj9x&Q#yJOxR-8A`1H0000Y literal 0 HcmV?d00001 diff --git a/app/src/debug/res/drawable-hdpi/ic_stat_note.png b/app/src/debug/res/drawable-hdpi/ic_stat_note.png new file mode 100644 index 0000000000000000000000000000000000000000..1992edf256bdb7f24a1a1404c4a0adf20d4ed656 GIT binary patch literal 460 zcmV;-0W2k`*$2^u=)IuJ{eT1&G)YwCC?Zlu5g(~-<^1!4|r zG)X`Xd_{(1wgIs)t=dU-Bskj`0&xsAL(BxNh?oMzW##shCTt}01_O;g479Uq{K1dK>P%%lAG20000m;Btr#|Lk+dSW&x0`2gIMzg2a)U7L-E83XmdJf|?doK*gkR z=%<U#r?9}s9D zXaNa6hgpyT<>y2B=I9E8p%Pn=A`%yF!(#y#G=(*xTL22neMFY~*YQ}u2r9OLcmlN& z2f797P<|e@E$9PcS7-_YMYtHXEkG^=4d~W*004qZ%P)}C`MCf9002ovPDHLkV1g!h Bi8BBI literal 0 HcmV?d00001 diff --git a/app/src/debug/res/drawable-mdpi/ic_stat_luckynumber.png b/app/src/debug/res/drawable-mdpi/ic_stat_luckynumber.png new file mode 100644 index 0000000000000000000000000000000000000000..278ed2c6673286284086e1dd77d9b5fecb12a84d GIT binary patch literal 451 zcmV;!0X+VRP) zxt>$!=Ja;&eJ}5ul~cdwojZ4)=bm%VeQzT1A5lXol>&oc64ZlQFb+mRRU8Hz>N}pn zllXp23y30~Q{mAU#h?y+h8X02BisS9{Ji22-{v_PkoVotEg`VXWx6qlKawa|5?LOC zw98<~Aao77!JQbRjV^){!~7YS!IY&Gx1a#dKv_JSV$NmIz^!PCbI=T0z`kY9D`;~W zWCMLJqs-z>;MDN@8)ubq8I&yIWZDG|Sfs#)6nmf_Bz?MQ%+f7IE|JWp2h9Go|Eu}< z>)7E|G~a_Cch|5_Mm6BWU~nPkXoGoi zSgEX6J_dQqrmxxzcx;^)mI^bd07rp7e*v2z25W3k>61koOw$Pk?Vyn^8%K#~40hGU*JW{dp??4X002ovPDHLkV1mn1%ZUI0 literal 0 HcmV?d00001 diff --git a/app/src/debug/res/drawable-mdpi/ic_stat_message.png b/app/src/debug/res/drawable-mdpi/ic_stat_message.png new file mode 100644 index 0000000000000000000000000000000000000000..7327a02f32c857a246a430d5dccf26d8d27b8552 GIT binary patch literal 297 zcmV+^0oMMBP)}Y02cHFn|0xHp_$(-*f(32FTJV8{c)LrE z1z&+Uo=E(P91Fgakb>R~${_j+#P^BBzlpV=m;xVsgIZQbtOZ|y*ntSl55z`5%tVY! zib+iK)ufg~q*yQ?sz(+{3{=dV1>#UjEdWKT6q*Iwp?P8>lpjpUf=NKEfCEb->490$ z4dpXKBmF!+3nq~etSA;h#a06GACP6}ic3f_9FGMnpcb&8D^@0>fCLq28#Fwd6 v1Hvo-x!M;RJRlH7Z3|%F1`x;6t&Rr(lkMR%11L)H00000NkvXXu0mjf$q93V literal 0 HcmV?d00001 diff --git a/app/src/debug/res/drawable-mdpi/ic_stat_note.png b/app/src/debug/res/drawable-mdpi/ic_stat_note.png new file mode 100644 index 0000000000000000000000000000000000000000..2fb0209825a5ba1b4016d0b288471114db74e2e4 GIT binary patch literal 339 zcmV-Z0j&OsP)_U7NumbU1AifX9zlkvX zFOvG@K+H`_&R$D|1*<73I*ft%2Oh&4fS8fe^2q^+Z(uQeB~)G(NeonMoCV@gax4O+ zlG{N15{T81#9(j~utNzmm`~qS}YCGQSKYhV*YI`6B$?$7H z98UvWjbz6cYI`69$?&~2N}{?*cKjTf9sp`|L5fmMay$T(X9Z$6JW0inmLAxSWJn&V z9stUT1MztR8MJvYdtf0ECCs4qz+)tJXK++jNrTw~pODm<4n!s%^#GDOKOk0sVxghv z0d#N$h^>dR2SDIG5K9ha4}d`WkjunC_Tr&Z4~%+Xpgr&qM@{?!NxXP4dtf$!4EzUI zpLei$KnRGB;pyuZ4C;CSs+Jj){?YmX!9XlSKp!^{I{>i;5L*tI2L^iVXV`im2}%4O z5Z6hAcqY^{q~dxk<{^9F9g^BJXdanN6%WuL$s&8;BAT2B5Pw6Gw;xg-fXde+$!{da zz->qx8j!k#lwvV5J)njp4~h+DLLQh(qtWKoWO@KJC-E0ajXWU_=!4oJH1NPOay$T4 z^94zb7BR`l5i~vz#NVmtfn5}M;1`k_<-u0-6G}odXmtX|Q1d`0lKip3*!IF#4=AGb zNklC;T5m+Ax$NWQkqH_wU9BT5-nkAArT8qg%FDp5gU(%u&EXC zSO^jlLCm5HA*~9Lc%?K9QFHxI^4;X*r1#EwjeE&_$uDj0dED=R=DXkd&b^UH!3tKe zf)y-ia~x+hI07DmUT^~>K$O}W!BuK|3_3x1Se%~;UO7YCb#T_B?K7wg+W9EB>*yO3 zUKXT)xsJKTgA|akAmC7t0ybI@us28nMGWBVoYbw^xZGxR7h_`M~ZR&g(=<{*n zJy=P7TR~RR`4o*=2zq?_eFf7^1awF^!&ZI^^>3FDag6$|AO~|cZGSg+7C1a-d21t*~&N5*m^KPA=XOQ zs_B}F^_ctuNsaW#R=%FbSAr(`f3{}2Jz$#uuW8(rt#YNXSM+Jj^9+nMO{HfvZp^}F zEjPyk(62GiO;BXw{2Gm$X1SQ3>h8AqyG%0kWN2@=Lo}EO=+Y42W}7+S4dwb6U0dg| zV-HeI6$c}1)<7>6o$sJ=OTZ_g?uk=d3#DAwZh?9ED&n3hIM45}10JjF?$~W4B9+%_ z6qBEpbp9~)U!5b)nbU35ch=u1qbum`fnUzw$*p`wa>tGd_o?;CW@-ARCh3Z(^Qagf zxw)RwpMeo}C{`Bm_+4+Q!qHKG*vB6QPX*k4j~E(PJJ@0o;AwS*eeNiJKJniS0T9sLu(m zJ#9)zVPHqqiiF6%e5cI;_AsAI}J00000NkvXXu0mjfNfe;G literal 0 HcmV?d00001 diff --git a/app/src/debug/res/drawable-xhdpi/ic_stat_message.png b/app/src/debug/res/drawable-xhdpi/ic_stat_message.png new file mode 100644 index 0000000000000000000000000000000000000000..c4140be897ce9df34883a5c387eb7ececa6f83cb GIT binary patch literal 508 zcmV5TUPu{WiTHwNNg{|6R?QR0CO{|6r2q{IXF27w3u z0Wl}J9(eM9Z~*>M51@hHG$?hx(ZT~yaTxfJ2F3O6Q4fqH4}1sW{Zz*9=;?tWQwojd zfr0kGv*GH2FF-t>%J?ZgJuqZ4F)j~)LQ8?l`0#Ma1HYhcqXW?T;R+D*4h0Vs0dWWr zb5YY!TpsuU#Pw9dHni-}Kc`{F{0qd@K+H5$Jy1Z8Ar)GAU^1FLR(Lv27lF71h$RM# z2Oa`350M@~2A_a9dN6n(9*aHb9#{dy3!rtwH?$Fo$bt00J8VNFSUez(BqsvIJJ3o% zF-kqK7>FInzBK^+2Nu$*(jn3VUTA6rN%6o!TGp6EdcYG+jS#UOpsC|Y@IW+@{2w4@CC1=xT05Qu z5A-0(Uma|-K!l1>ZnQ3E=aBILv<_H@B=;4FWe2+lRzN%YD}ne8nq0`o~j%SYY_W%9i`yLl0000TN>V~8Hg-y6VMDR9lOiQ`B~sW>mz_r`JCEd*l@tp*?-GUR z7LmvCpBnWwx%VD-<~Zlx=BwZ4esgEO-+j!SnTd$dp+kob9ae>582jMd2iu@t!5F1r z#m_j5q+mP0H3CPwMDaD?-NYElRtmg;#31`WGt7k&fep~d84(7UB000Tg+69UZqW*X z9`bs&p+2ff{|#C|3upl?parym76=D{Q_{%+@NgC^5LhMsZ;{v8(`sC>0@H^5u_LqD zaDfXOi+=)zvOA_!FbLMcCgD+Gp|3*Uj4}3KvvRvRp-^DWj{S0lqT<)zzo>s$2LFl1sebBr{y67?*(Wp3S^L6I-jZN;^qn& z0iI6+HzeO5QUbgUJxn{Ys%Z9@-OHaWy~3jcJK4*Z5NH-=r)bs1w}Q6-GfA<8K%LMg zRb}xd;KRgJSScY;E3`>dDKKPm0c(*EXd-#`Va2EvST-pzDIqXS^2biQ2?{igCV*>_ zcZZAsUjvp%?ipk`U0{x{BlF;1)s@zN3i#S~b~yDm)Sm#mr5p!&PQK2K13AAC8TNPC Y-`g6$N>WdP)yiQB*AaAgx+>LN4hdh!G?z zHZe*N!BpZOph850;0KDI(e)i1xV_=My`9O;&g{`i`qnVEfOwp4;32!bF8 zO0Ou2+Q{oXaF=gj`pL88zmY$BO+H2La1G}m`A_7p?vmSG!C6cG7WuCsSAd42d}z)U zpbFEOo8)oFey8;5vnxPV22igDlg6ylr|$p+Kme24z419-d0HXX>^7)j5?`dBE ztz`c2iBvLc6r~yC#1V9!5 z9bnqMAkQdPYeqAn0NP|Y%~wJJw2b^r6OK4JvL&RN^ak>K4M1mudDMut@0JU~mkD5= zk_R;Ve_vknksQmO=MqqE1wa4 zfKGY<=(r_7A6qd{cSQeRMsul=i~voW4uI`)4{MJ6#Q~tIg)yj&*-pAs%N_H{r`Rl?1qR;m**;_>~4>tuQCz~VWA53j%V~Bw6#ZIYBChXu2 zhp@q5S}?m<3PA>d=5@ESLjd$a*3Ji$s*^GqLMI*%JwAeLuDJ{myD7Mq$sIGTf}U|4{cCXUn+}s zBFi94q@slgD%vniv{G;9(0MT2=3Vc*cV>L|c@O+~Po0@N_xJ9bIm_trxaOK`uDRx# zYp%KGnrjX)P1AaU5TC|UIo#vp~=wZ{GaFbYQ6cEdTgJ9nHm^g+C z`Jhg^K1T$?DaH?o8M_rhsqoSMD`>6Cz|%}@^#in&=@$XIDge$aP#0$0v7mP*`xeNC zGlHUSe+-?)aO&R%^w0*JPi*W3?^7+zXT3~7MHX-DvUeST*LD^meFP1rF+xDQEzac| zZ=DnYrwgdg#;5-P;m}x7^s`y}02)MnLj|}F^JM^o2;PZkfTFAyy@ID=MO6LTo2)-uzOrf#>4YuHS zSY8jXyyHj0->fZ_?JOo!^+BYi`&jd;1z#smMW``K!o*KHuf+ze?w_9PEC{@KGb=9u~fLW*^c063qRs2siLY!iL1GpUlcOcns2xQu{F+QUSK z3V<_&SyvAG(f1z0VIbj?loW`G`j-~rVE($l&3sO=@`cv|pd}V=tOOLpe68%{bME`9 zP?$`|{3Os=?HDc#QobKIlWU`%+#@{&84aX9%0ThDers*Q zsWb9|Z6x%nWTjwZL0iZ_DWmi$o*SI%^sAY@W!bgy7629M zD#4hpNh4p3w?6f03_u$Nz$rCx9Ya8zQzwr&?JuZ?6G3HP=~W1S08#s1+W&_tFu)zE z5>SGm@FZR|AnJ2~(`ScDKwAXBsn<-L&aen*3NHnt5>UPXK;LcD?HU3U?PJ>yRRu^y zE$f9WK-7=tezaEwXqf;&C6WR0Hj!9Wfbb+og-t-OB?J1x>DN=`I+SJ;P=#bbyb4XU zYJbS=p@TfCr0R=>F_ISPC{CXmeW;`gQi?&z=slYN)BgSQ-F@coiIM>E4rDxO%zRQy z&@AoWflExcZlXzs`Di}?v{Ey1+}9$Y98RBXPcWK=P@}7l4J59~147Rnbc@sewkKH4 z3?Kr71k~SW^R3Nkz)HK5{^;t?>l2*~lo?>dynXfS4^ET?$WAFh2mj2A#lM nm8U5gEx^4SP>9Dh*Ob~{Mo&7jsAX{m00000NkvXXu0mjfA-!)C literal 0 HcmV?d00001 diff --git a/app/src/debug/res/drawable-xxhdpi/ic_stat_message.png b/app/src/debug/res/drawable-xxhdpi/ic_stat_message.png new file mode 100644 index 0000000000000000000000000000000000000000..9d0fa781cb8e525fb85479e0d4e43d34cf8d62f3 GIT binary patch literal 692 zcmV;l0!#ggP)t2U33WY+UP$(1%g%V>p z=S^r2I%q-L(5G?1w4l4(z8s_3sBxOn3vPFYq6FIJ_U8{;83j%wcPGP90ChP8G!+F< z)*+xd0wN#+au(-p|7G5i_wD4=@}x88h+3P>A{0#Ju!%~ljZT5%MBQh9Fs#bE+z#|a7~ z)?G^0JqruS2pmPAUy^mzK{ha8Dvl!1sbpP^Dv(h)ia>uQ>ryH}#^ERo>2k@Me}P`z z3LqnK6oAr_H9J8!P;V-Z0?@Q%%@lJn0UkA~&@;)J*2Dwh`(@}i$@Lq|)%XDtFj;Ya zz?&uUs?Le|&9Q9xNoO9iy0Af^dCh*;YZ7X*!DJENRs;7g2}oD%d6 zEMcgp1YX3f$tgi5#~JF`m!O{11ib|}ee@C6JqN90%njl`Pl$SkYzn$YT(?l$OD9oJ zmk1I;B1i;@AQ2>jM34v)K_W;5i69Xqf<%xA5~UG7K85@7u3nUlWDee){e{ENlDIi(3r*ZM5~y^{4oQ;tRK3%$Ry_{ z*r>7|J$yvvF@vD3DlfqgQx68lP|m@C`*eh8`w83yhrlA2Buxd!z^{aI9)gJp1o?B- zsSe(I{r7tFp{V(x|8r6;rl64#_Bz*o?WTY>Z~$D;^ieu9GQI-3K|83a@|hh8p3L81 zt;_w?ZldTj5kG?x)ceo(CwWh>8Rb_3`lq>t6-2yU?-AEu5<#QaHxPZH8GJU0pwTvm z!ww^gDrh;;rq88U{$6l8VEyP7I1hF*3MvJ>_Q%^4(-Lu}Kfoo(Yey|1*V>X(_6B@W za-Uhy8=~E88*-XsF8B{J3wlkotG6NOY|K&a2WCNEiFPF$g5D*V3e+)m(lY{x({0#1G0R(VYr zL7tfPdiW3Ts0F#^q6spy^&yW+l^4M_mFFZ_Q8er1yHws2Q&7L=_$LDy7c>Y?ft9LA j@jBo+RT!rvl2r2-e}J_` - - - + diff --git a/app/src/main/res/drawable-anydpi-v24/ic_stat_luckynumber.xml b/app/src/main/res/drawable-anydpi-v24/ic_stat_luckynumber.xml index 4699c4576..bee1c7072 100644 --- a/app/src/main/res/drawable-anydpi-v24/ic_stat_luckynumber.xml +++ b/app/src/main/res/drawable-anydpi-v24/ic_stat_luckynumber.xml @@ -3,11 +3,7 @@ android:height="24dp" android:viewportWidth="26.086956" android:viewportHeight="26.086956"> - - - + diff --git a/app/src/main/res/drawable-anydpi-v24/ic_stat_message.xml b/app/src/main/res/drawable-anydpi-v24/ic_stat_message.xml index cb42d7cc2..89a8aef29 100644 --- a/app/src/main/res/drawable-anydpi-v24/ic_stat_message.xml +++ b/app/src/main/res/drawable-anydpi-v24/ic_stat_message.xml @@ -3,11 +3,7 @@ android:height="24dp" android:viewportWidth="26.086956" android:viewportHeight="26.086956"> - - - + diff --git a/app/src/main/res/drawable-anydpi-v24/ic_stat_note.xml b/app/src/main/res/drawable-anydpi-v24/ic_stat_note.xml index d6b0d4d17..0f335336b 100644 --- a/app/src/main/res/drawable-anydpi-v24/ic_stat_note.xml +++ b/app/src/main/res/drawable-anydpi-v24/ic_stat_note.xml @@ -3,11 +3,7 @@ android:height="24dp" android:viewportWidth="26.086956" android:viewportHeight="26.086956"> - - - + diff --git a/app/src/main/res/drawable/ic_main_grade.xml b/app/src/main/res/drawable/ic_main_grade.xml index 7577f399e..bf4c2cf20 100644 --- a/app/src/main/res/drawable/ic_main_grade.xml +++ b/app/src/main/res/drawable/ic_main_grade.xml @@ -1,7 +1,9 @@ - + diff --git a/app/src/main/res/drawable/ic_main_more.xml b/app/src/main/res/drawable/ic_main_more.xml index 1b436a327..f57a72456 100644 --- a/app/src/main/res/drawable/ic_main_more.xml +++ b/app/src/main/res/drawable/ic_main_more.xml @@ -1,7 +1,9 @@ - + From eb1ce251a0e8ece06086d0a29d9cd7a884e053ed Mon Sep 17 00:00:00 2001 From: "dependabot-preview[bot]" <27856297+dependabot-preview[bot]@users.noreply.github.com> Date: Mon, 20 Jan 2020 20:26:53 +0000 Subject: [PATCH 02/18] Bump threetenbp from 1.4.0 to 1.4.1 (#659) --- app/build.gradle | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/app/build.gradle b/app/build.gradle index 24a470ae0..f8fd2a3db 100644 --- a/app/build.gradle +++ b/app/build.gradle @@ -186,7 +186,7 @@ dependencies { testImplementation "junit:junit:4.13" testImplementation "io.mockk:mockk:$mockk" - testImplementation "org.threeten:threetenbp:1.4.0" + testImplementation "org.threeten:threetenbp:1.4.1" testImplementation "org.mockito:mockito-inline:3.2.4" androidTestImplementation "androidx.test:core:1.2.0" From e0ec2f8160c48c607c7f836db653a6f0c1690186 Mon Sep 17 00:00:00 2001 From: "dependabot-preview[bot]" <27856297+dependabot-preview[bot]@users.noreply.github.com> Date: Mon, 20 Jan 2020 20:27:10 +0000 Subject: [PATCH 03/18] Bump firebase-core from 17.2.1 to 17.2.2 (#658) --- app/build.gradle | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/app/build.gradle b/app/build.gradle index f8fd2a3db..612ace658 100644 --- a/app/build.gradle +++ b/app/build.gradle @@ -176,7 +176,7 @@ dependencies { implementation "com.mikepenz:aboutlibraries-core:7.1.0" implementation 'com.wdullaer:materialdatetimepicker:4.2.3' - playImplementation "com.google.firebase:firebase-core:17.2.1" + playImplementation "com.google.firebase:firebase-core:17.2.2" playImplementation "com.crashlytics.sdk.android:crashlytics:2.10.1" releaseImplementation "fr.o80.chucker:library-no-op:$chucker" From cc242e1e87a20221771c46922e9a8b08a999498f Mon Sep 17 00:00:00 2001 From: "dependabot-preview[bot]" <27856297+dependabot-preview[bot]@users.noreply.github.com> Date: Mon, 20 Jan 2020 20:27:29 +0000 Subject: [PATCH 04/18] Bump threetenabp from 1.2.1 to 1.2.2 (#657) --- app/build.gradle | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/app/build.gradle b/app/build.gradle index 612ace658..b2e495a12 100644 --- a/app/build.gradle +++ b/app/build.gradle @@ -170,7 +170,7 @@ dependencies { implementation "io.reactivex.rxjava2:rxjava:2.2.16" implementation "com.google.code.gson:gson:2.8.6" - implementation "com.jakewharton.threetenabp:threetenabp:1.2.1" + implementation "com.jakewharton.threetenabp:threetenabp:1.2.2" implementation "com.jakewharton.timber:timber:4.7.1" implementation "at.favre.lib:slf4j-timber:1.0.1" implementation "com.mikepenz:aboutlibraries-core:7.1.0" From 77e7e4e6e9591577aea2bb9e06e53df48bf511af Mon Sep 17 00:00:00 2001 From: "dependabot-preview[bot]" <27856297+dependabot-preview[bot]@users.noreply.github.com> Date: Mon, 20 Jan 2020 20:27:52 +0000 Subject: [PATCH 05/18] Bump material from 1.1.0-rc01 to 1.1.0-rc02 (#655) --- app/build.gradle | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/app/build.gradle b/app/build.gradle index b2e495a12..18927b047 100644 --- a/app/build.gradle +++ b/app/build.gradle @@ -139,7 +139,7 @@ dependencies { implementation "androidx.swiperefreshlayout:swiperefreshlayout:1.1.0-alpha03" implementation "androidx.constraintlayout:constraintlayout:1.1.3" implementation "androidx.coordinatorlayout:coordinatorlayout:1.1.0" - implementation "com.google.android.material:material:1.1.0-rc01" + implementation "com.google.android.material:material:1.1.0-rc02" implementation "com.github.wulkanowy:material-chips-input:2.0.1" implementation "com.github.PhilJay:MPAndroidChart:v3.1.0" implementation "me.zhanghai.android.materialprogressbar:library:1.6.1" From c5cadbd00496cbbe119b65fe01b28011b688c371 Mon Sep 17 00:00:00 2001 From: Dominik Korsa Date: Mon, 20 Jan 2020 21:29:06 +0100 Subject: [PATCH 06/18] Improve grades dialog layout (#631) --- app/jacoco.gradle | 2 +- .../grade/details/GradeDetailsDialog.kt | 8 +- .../github/wulkanowy/utils/GradeExtension.kt | 20 +-- app/src/main/res/layout/dialog_grade.xml | 131 +++++++++--------- app/src/main/res/values-pl/strings.xml | 1 + app/src/main/res/values/strings.xml | 1 + 6 files changed, 84 insertions(+), 79 deletions(-) diff --git a/app/jacoco.gradle b/app/jacoco.gradle index 48a8fed96..e9abfb613 100644 --- a/app/jacoco.gradle +++ b/app/jacoco.gradle @@ -1,7 +1,7 @@ apply plugin: "jacoco" jacoco { - toolVersion "0.8.4" + toolVersion "0.8.5" reportsDir = file("$buildDir/reports") } diff --git a/app/src/main/java/io/github/wulkanowy/ui/modules/grade/details/GradeDetailsDialog.kt b/app/src/main/java/io/github/wulkanowy/ui/modules/grade/details/GradeDetailsDialog.kt index 0abeaeea0..a8f8a8653 100644 --- a/app/src/main/java/io/github/wulkanowy/ui/modules/grade/details/GradeDetailsDialog.kt +++ b/app/src/main/java/io/github/wulkanowy/ui/modules/grade/details/GradeDetailsDialog.kt @@ -10,6 +10,7 @@ import io.github.wulkanowy.R import io.github.wulkanowy.data.db.entities.Grade import io.github.wulkanowy.utils.colorStringId import io.github.wulkanowy.utils.getBackgroundColor +import io.github.wulkanowy.utils.getGradeColor import io.github.wulkanowy.utils.toFormattedString import kotlinx.android.synthetic.main.dialog_grade.* @@ -50,7 +51,12 @@ class GradeDetailsDialog : DialogFragment() { super.onActivityCreated(savedInstanceState) gradeDialogSubject.text = grade.subject - gradeDialogWeightValue.text = grade.weight + + gradeDialogColorAndWeightValue.run { + text = context.getString(R.string.grade_weight_value, grade.weight) + setBackgroundResource(grade.getGradeColor()) + } + gradeDialogDateValue.text = grade.date.toFormattedString() gradeDialogColorValue.text = getString(grade.colorStringId) diff --git a/app/src/main/java/io/github/wulkanowy/utils/GradeExtension.kt b/app/src/main/java/io/github/wulkanowy/utils/GradeExtension.kt index c1e182ba2..c57b62470 100644 --- a/app/src/main/java/io/github/wulkanowy/utils/GradeExtension.kt +++ b/app/src/main/java/io/github/wulkanowy/utils/GradeExtension.kt @@ -24,14 +24,7 @@ fun List.calcAverage(): Double { fun Grade.getBackgroundColor(theme: String): Int { return when (theme) { - "grade_color" -> when (color) { - "000000" -> R.color.grade_black - "F04C4C" -> R.color.grade_red - "20A4F7" -> R.color.grade_blue - "6ECD07" -> R.color.grade_green - "B16CF1" -> R.color.grade_purple - else -> R.color.grade_material_default - } + "grade_color" -> getGradeColor() "material" -> when (value.toInt()) { 6 -> R.color.grade_material_six 5 -> R.color.grade_material_five @@ -53,6 +46,17 @@ fun Grade.getBackgroundColor(theme: String): Int { } } +fun Grade.getGradeColor(): Int { + return when (color) { + "000000" -> R.color.grade_black + "F04C4C" -> R.color.grade_red + "20A4F7" -> R.color.grade_blue + "6ECD07" -> R.color.grade_green + "B16CF1" -> R.color.grade_purple + else -> R.color.grade_material_default + } +} + inline val Grade.colorStringId: Int get() { return when (color) { diff --git a/app/src/main/res/layout/dialog_grade.xml b/app/src/main/res/layout/dialog_grade.xml index f95b9cfdb..fad7bae57 100644 --- a/app/src/main/res/layout/dialog_grade.xml +++ b/app/src/main/res/layout/dialog_grade.xml @@ -17,90 +17,83 @@ android:padding="20dp" tools:ignore="UselessParent"> - + android:orientation="vertical"> - + + + + + + android:layout_marginRight="12dp" + android:layout_marginEnd="12dp" + android:orientation="vertical"> + - - - - - - - + + Zmień semestr Brak ocen Waga + Waga: %s Komentarz Brak nowych ocen Ilość nowych ocen: %1$d diff --git a/app/src/main/res/values/strings.xml b/app/src/main/res/values/strings.xml index c8b94bff5..1b07a9fea 100644 --- a/app/src/main/res/values/strings.xml +++ b/app/src/main/res/values/strings.xml @@ -68,6 +68,7 @@ Change semester No grades Weight + Weight: %s Comment No new grades Number of new ratings: %1$d From 76a4bacb341edd02374b30a4ac557e85da0c75b9 Mon Sep 17 00:00:00 2001 From: Dominik Korsa Date: Mon, 20 Jan 2020 21:29:42 +0100 Subject: [PATCH 07/18] Fix login info autofill (#652) --- app/src/main/res/layout/fragment_login_advanced.xml | 3 ++- app/src/main/res/layout/fragment_login_form.xml | 2 +- 2 files changed, 3 insertions(+), 2 deletions(-) diff --git a/app/src/main/res/layout/fragment_login_advanced.xml b/app/src/main/res/layout/fragment_login_advanced.xml index 15e0904b6..7c559af9c 100644 --- a/app/src/main/res/layout/fragment_login_advanced.xml +++ b/app/src/main/res/layout/fragment_login_advanced.xml @@ -101,7 +101,7 @@ android:id="@+id/loginFormName" android:layout_width="match_parent" android:layout_height="wrap_content" - android:autofillHints="emailAddress" + android:autofillHints="username|emailAddress" android:inputType="textEmailAddress" android:maxLines="1" tools:targetApi="o" /> @@ -218,6 +218,7 @@ android:imeOptions="actionDone" android:inputType="textAutoComplete|textNoSuggestions" android:maxLines="1" + android:importantForAutofill="no" tools:ignore="LabelFor" /> diff --git a/app/src/main/res/layout/fragment_login_form.xml b/app/src/main/res/layout/fragment_login_form.xml index bb93c1827..65d331689 100644 --- a/app/src/main/res/layout/fragment_login_form.xml +++ b/app/src/main/res/layout/fragment_login_form.xml @@ -133,7 +133,7 @@ android:id="@+id/loginFormName" android:layout_width="match_parent" android:layout_height="wrap_content" - android:autofillHints="emailAddress" + android:autofillHints="username|emailAddress" android:inputType="textEmailAddress" android:maxLines="1" tools:targetApi="o" /> From e9fa95f11338070fe622181de41a457a069cc069 Mon Sep 17 00:00:00 2001 From: "dependabot-preview[bot]" <27856297+dependabot-preview[bot]@users.noreply.github.com> Date: Mon, 20 Jan 2020 21:51:13 +0100 Subject: [PATCH 08/18] Bump rxjava from 2.2.16 to 2.2.17 (#656) Bumps [rxjava](https://github.com/ReactiveX/RxJava) from 2.2.16 to 2.2.17. - [Release notes](https://github.com/ReactiveX/RxJava/releases) - [Changelog](https://github.com/ReactiveX/RxJava/blob/v2.2.17/CHANGES.md) - [Commits](https://github.com/ReactiveX/RxJava/compare/v2.2.16...v2.2.17) Signed-off-by: dependabot-preview[bot] --- app/build.gradle | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/app/build.gradle b/app/build.gradle index 18927b047..7145752d9 100644 --- a/app/build.gradle +++ b/app/build.gradle @@ -167,7 +167,7 @@ dependencies { implementation "com.github.pwittchen:reactivenetwork-rx2:3.0.6" implementation "io.reactivex.rxjava2:rxandroid:2.1.1" - implementation "io.reactivex.rxjava2:rxjava:2.2.16" + implementation "io.reactivex.rxjava2:rxjava:2.2.17" implementation "com.google.code.gson:gson:2.8.6" implementation "com.jakewharton.threetenabp:threetenabp:1.2.2" From ad3bb3a52286869dc3da57c59c6118d794a41482 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Miko=C5=82aj=20Pich?= Date: Mon, 20 Jan 2020 22:18:26 +0100 Subject: [PATCH 09/18] Add option to show only student plan lessons (#654) --- app/build.gradle | 2 +- .../20.json | 1634 +++++++++++++++++ .../timetable/TestTimetableEntityCreator.kt | 1 + .../github/wulkanowy/data/db/AppDatabase.kt | 6 +- .../wulkanowy/data/db/entities/Timetable.kt | 3 + .../data/db/migrations/Migration20.kt | 33 + .../preferences/PreferencesRepository.kt | 3 + .../semester/SemesterRepository.kt | 2 +- .../repositories/timetable/TimetableRemote.kt | 1 + .../ui/modules/timetable/TimetableItem.kt | 37 +- .../modules/timetable/TimetablePresenter.kt | 11 +- .../main/res/layout/item_timetable_small.xml | 81 + .../main/res/values-pl/preferences_values.xml | 6 + app/src/main/res/values-pl/strings.xml | 1 + .../main/res/values-ru/preferences_values.xml | 6 + app/src/main/res/values-ru/strings.xml | 1 + .../main/res/values/preferences_defaults.xml | 1 + app/src/main/res/values/preferences_keys.xml | 1 + .../main/res/values/preferences_values.xml | 11 + app/src/main/res/values/strings.xml | 1 + app/src/main/res/xml/scheme_preferences.xml | 8 + 21 files changed, 1835 insertions(+), 15 deletions(-) create mode 100644 app/schemas/io.github.wulkanowy.data.db.AppDatabase/20.json create mode 100644 app/src/main/java/io/github/wulkanowy/data/db/migrations/Migration20.kt create mode 100644 app/src/main/res/layout/item_timetable_small.xml diff --git a/app/build.gradle b/app/build.gradle index 7145752d9..0e86fc591 100644 --- a/app/build.gradle +++ b/app/build.gradle @@ -122,7 +122,7 @@ configurations.all { } dependencies { - implementation "io.github.wulkanowy:sdk:0.14.2" + implementation "io.github.wulkanowy:sdk:8ad4480" implementation "org.jetbrains.kotlin:kotlin-stdlib-jdk8:$kotlin_version" implementation "androidx.core:core-ktx:1.2.0-rc01" diff --git a/app/schemas/io.github.wulkanowy.data.db.AppDatabase/20.json b/app/schemas/io.github.wulkanowy.data.db.AppDatabase/20.json new file mode 100644 index 000000000..925d787aa --- /dev/null +++ b/app/schemas/io.github.wulkanowy.data.db.AppDatabase/20.json @@ -0,0 +1,1634 @@ +{ + "formatVersion": 1, + "database": { + "version": 20, + "identityHash": "37a216a7afcea922b66001ca5ed6cf74", + "entities": [ + { + "tableName": "Students", + "createSql": "CREATE TABLE IF NOT EXISTS `${TABLE_NAME}` (`id` INTEGER PRIMARY KEY AUTOINCREMENT NOT NULL, `scrapper_base_url` TEXT NOT NULL, `mobile_base_url` TEXT NOT NULL, `login_type` TEXT NOT NULL, `login_mode` TEXT NOT NULL, `certificate_key` TEXT NOT NULL, `private_key` TEXT NOT NULL, `is_parent` INTEGER NOT NULL, `email` TEXT NOT NULL, `password` TEXT NOT NULL, `symbol` TEXT NOT NULL, `student_id` INTEGER NOT NULL, `user_login_id` INTEGER NOT NULL, `student_name` TEXT NOT NULL, `school_id` TEXT NOT NULL, `school_name` TEXT NOT NULL, `class_name` TEXT NOT NULL, `class_id` INTEGER NOT NULL, `is_current` INTEGER NOT NULL, `registration_date` INTEGER NOT NULL)", + "fields": [ + { + "fieldPath": "id", + "columnName": "id", + "affinity": "INTEGER", + "notNull": true + }, + { + "fieldPath": "scrapperBaseUrl", + "columnName": "scrapper_base_url", + "affinity": "TEXT", + "notNull": true + }, + { + "fieldPath": "mobileBaseUrl", + "columnName": "mobile_base_url", + "affinity": "TEXT", + "notNull": true + }, + { + "fieldPath": "loginType", + "columnName": "login_type", + "affinity": "TEXT", + "notNull": true + }, + { + "fieldPath": "loginMode", + "columnName": "login_mode", + "affinity": "TEXT", + "notNull": true + }, + { + "fieldPath": "certificateKey", + "columnName": "certificate_key", + "affinity": "TEXT", + "notNull": true + }, + { + "fieldPath": "privateKey", + "columnName": "private_key", + "affinity": "TEXT", + "notNull": true + }, + { + "fieldPath": "isParent", + "columnName": "is_parent", + "affinity": "INTEGER", + "notNull": true + }, + { + "fieldPath": "email", + "columnName": "email", + "affinity": "TEXT", + "notNull": true + }, + { + "fieldPath": "password", + "columnName": "password", + "affinity": "TEXT", + "notNull": true + }, + { + "fieldPath": "symbol", + "columnName": "symbol", + "affinity": "TEXT", + "notNull": true + }, + { + "fieldPath": "studentId", + "columnName": "student_id", + "affinity": "INTEGER", + "notNull": true + }, + { + "fieldPath": "userLoginId", + "columnName": "user_login_id", + "affinity": "INTEGER", + "notNull": true + }, + { + "fieldPath": "studentName", + "columnName": "student_name", + "affinity": "TEXT", + "notNull": true + }, + { + "fieldPath": "schoolSymbol", + "columnName": "school_id", + "affinity": "TEXT", + "notNull": true + }, + { + "fieldPath": "schoolName", + "columnName": "school_name", + "affinity": "TEXT", + "notNull": true + }, + { + "fieldPath": "className", + "columnName": "class_name", + "affinity": "TEXT", + "notNull": true + }, + { + "fieldPath": "classId", + "columnName": "class_id", + "affinity": "INTEGER", + "notNull": true + }, + { + "fieldPath": "isCurrent", + "columnName": "is_current", + "affinity": "INTEGER", + "notNull": true + }, + { + "fieldPath": "registrationDate", + "columnName": "registration_date", + "affinity": "INTEGER", + "notNull": true + } + ], + "primaryKey": { + "columnNames": [ + "id" + ], + "autoGenerate": true + }, + "indices": [ + { + "name": "index_Students_email_symbol_student_id_school_id_class_id", + "unique": true, + "columnNames": [ + "email", + "symbol", + "student_id", + "school_id", + "class_id" + ], + "createSql": "CREATE UNIQUE INDEX IF NOT EXISTS `index_Students_email_symbol_student_id_school_id_class_id` ON `${TABLE_NAME}` (`email`, `symbol`, `student_id`, `school_id`, `class_id`)" + } + ], + "foreignKeys": [] + }, + { + "tableName": "Semesters", + "createSql": "CREATE TABLE IF NOT EXISTS `${TABLE_NAME}` (`id` INTEGER PRIMARY KEY AUTOINCREMENT NOT NULL, `student_id` INTEGER NOT NULL, `diary_id` INTEGER NOT NULL, `diary_name` TEXT NOT NULL, `school_year` INTEGER NOT NULL, `semester_id` INTEGER NOT NULL, `semester_name` INTEGER NOT NULL, `is_current` INTEGER NOT NULL, `start` INTEGER NOT NULL, `end` INTEGER NOT NULL, `class_id` INTEGER NOT NULL, `unit_id` INTEGER NOT NULL)", + "fields": [ + { + "fieldPath": "id", + "columnName": "id", + "affinity": "INTEGER", + "notNull": true + }, + { + "fieldPath": "studentId", + "columnName": "student_id", + "affinity": "INTEGER", + "notNull": true + }, + { + "fieldPath": "diaryId", + "columnName": "diary_id", + "affinity": "INTEGER", + "notNull": true + }, + { + "fieldPath": "diaryName", + "columnName": "diary_name", + "affinity": "TEXT", + "notNull": true + }, + { + "fieldPath": "schoolYear", + "columnName": "school_year", + "affinity": "INTEGER", + "notNull": true + }, + { + "fieldPath": "semesterId", + "columnName": "semester_id", + "affinity": "INTEGER", + "notNull": true + }, + { + "fieldPath": "semesterName", + "columnName": "semester_name", + "affinity": "INTEGER", + "notNull": true + }, + { + "fieldPath": "isCurrent", + "columnName": "is_current", + "affinity": "INTEGER", + "notNull": true + }, + { + "fieldPath": "start", + "columnName": "start", + "affinity": "INTEGER", + "notNull": true + }, + { + "fieldPath": "end", + "columnName": "end", + "affinity": "INTEGER", + "notNull": true + }, + { + "fieldPath": "classId", + "columnName": "class_id", + "affinity": "INTEGER", + "notNull": true + }, + { + "fieldPath": "unitId", + "columnName": "unit_id", + "affinity": "INTEGER", + "notNull": true + } + ], + "primaryKey": { + "columnNames": [ + "id" + ], + "autoGenerate": true + }, + "indices": [ + { + "name": "index_Semesters_student_id_diary_id_semester_id", + "unique": true, + "columnNames": [ + "student_id", + "diary_id", + "semester_id" + ], + "createSql": "CREATE UNIQUE INDEX IF NOT EXISTS `index_Semesters_student_id_diary_id_semester_id` ON `${TABLE_NAME}` (`student_id`, `diary_id`, `semester_id`)" + } + ], + "foreignKeys": [] + }, + { + "tableName": "Exams", + "createSql": "CREATE TABLE IF NOT EXISTS `${TABLE_NAME}` (`id` INTEGER PRIMARY KEY AUTOINCREMENT NOT NULL, `student_id` INTEGER NOT NULL, `diary_id` INTEGER NOT NULL, `date` INTEGER NOT NULL, `entry_date` INTEGER NOT NULL, `subject` TEXT NOT NULL, `group` TEXT NOT NULL, `type` TEXT NOT NULL, `description` TEXT NOT NULL, `teacher` TEXT NOT NULL, `teacher_symbol` TEXT NOT NULL)", + "fields": [ + { + "fieldPath": "id", + "columnName": "id", + "affinity": "INTEGER", + "notNull": true + }, + { + "fieldPath": "studentId", + "columnName": "student_id", + "affinity": "INTEGER", + "notNull": true + }, + { + "fieldPath": "diaryId", + "columnName": "diary_id", + "affinity": "INTEGER", + "notNull": true + }, + { + "fieldPath": "date", + "columnName": "date", + "affinity": "INTEGER", + "notNull": true + }, + { + "fieldPath": "entryDate", + "columnName": "entry_date", + "affinity": "INTEGER", + "notNull": true + }, + { + "fieldPath": "subject", + "columnName": "subject", + "affinity": "TEXT", + "notNull": true + }, + { + "fieldPath": "group", + "columnName": "group", + "affinity": "TEXT", + "notNull": true + }, + { + "fieldPath": "type", + "columnName": "type", + "affinity": "TEXT", + "notNull": true + }, + { + "fieldPath": "description", + "columnName": "description", + "affinity": "TEXT", + "notNull": true + }, + { + "fieldPath": "teacher", + "columnName": "teacher", + "affinity": "TEXT", + "notNull": true + }, + { + "fieldPath": "teacherSymbol", + "columnName": "teacher_symbol", + "affinity": "TEXT", + "notNull": true + } + ], + "primaryKey": { + "columnNames": [ + "id" + ], + "autoGenerate": true + }, + "indices": [], + "foreignKeys": [] + }, + { + "tableName": "Timetable", + "createSql": "CREATE TABLE IF NOT EXISTS `${TABLE_NAME}` (`id` INTEGER PRIMARY KEY AUTOINCREMENT NOT NULL, `student_id` INTEGER NOT NULL, `diary_id` INTEGER NOT NULL, `number` INTEGER NOT NULL, `start` INTEGER NOT NULL, `end` INTEGER NOT NULL, `date` INTEGER NOT NULL, `subject` TEXT NOT NULL, `subjectOld` TEXT NOT NULL, `group` TEXT NOT NULL, `room` TEXT NOT NULL, `roomOld` TEXT NOT NULL, `teacher` TEXT NOT NULL, `teacherOld` TEXT NOT NULL, `info` TEXT NOT NULL, `student_plan` INTEGER NOT NULL, `changes` INTEGER NOT NULL, `canceled` INTEGER NOT NULL)", + "fields": [ + { + "fieldPath": "id", + "columnName": "id", + "affinity": "INTEGER", + "notNull": true + }, + { + "fieldPath": "studentId", + "columnName": "student_id", + "affinity": "INTEGER", + "notNull": true + }, + { + "fieldPath": "diaryId", + "columnName": "diary_id", + "affinity": "INTEGER", + "notNull": true + }, + { + "fieldPath": "number", + "columnName": "number", + "affinity": "INTEGER", + "notNull": true + }, + { + "fieldPath": "start", + "columnName": "start", + "affinity": "INTEGER", + "notNull": true + }, + { + "fieldPath": "end", + "columnName": "end", + "affinity": "INTEGER", + "notNull": true + }, + { + "fieldPath": "date", + "columnName": "date", + "affinity": "INTEGER", + "notNull": true + }, + { + "fieldPath": "subject", + "columnName": "subject", + "affinity": "TEXT", + "notNull": true + }, + { + "fieldPath": "subjectOld", + "columnName": "subjectOld", + "affinity": "TEXT", + "notNull": true + }, + { + "fieldPath": "group", + "columnName": "group", + "affinity": "TEXT", + "notNull": true + }, + { + "fieldPath": "room", + "columnName": "room", + "affinity": "TEXT", + "notNull": true + }, + { + "fieldPath": "roomOld", + "columnName": "roomOld", + "affinity": "TEXT", + "notNull": true + }, + { + "fieldPath": "teacher", + "columnName": "teacher", + "affinity": "TEXT", + "notNull": true + }, + { + "fieldPath": "teacherOld", + "columnName": "teacherOld", + "affinity": "TEXT", + "notNull": true + }, + { + "fieldPath": "info", + "columnName": "info", + "affinity": "TEXT", + "notNull": true + }, + { + "fieldPath": "studentPlan", + "columnName": "student_plan", + "affinity": "INTEGER", + "notNull": true + }, + { + "fieldPath": "changes", + "columnName": "changes", + "affinity": "INTEGER", + "notNull": true + }, + { + "fieldPath": "canceled", + "columnName": "canceled", + "affinity": "INTEGER", + "notNull": true + } + ], + "primaryKey": { + "columnNames": [ + "id" + ], + "autoGenerate": true + }, + "indices": [], + "foreignKeys": [] + }, + { + "tableName": "Attendance", + "createSql": "CREATE TABLE IF NOT EXISTS `${TABLE_NAME}` (`id` INTEGER PRIMARY KEY AUTOINCREMENT NOT NULL, `student_id` INTEGER NOT NULL, `diary_id` INTEGER NOT NULL, `date` INTEGER NOT NULL, `number` INTEGER NOT NULL, `subject` TEXT NOT NULL, `name` TEXT NOT NULL, `presence` INTEGER NOT NULL, `absence` INTEGER NOT NULL, `exemption` INTEGER NOT NULL, `lateness` INTEGER NOT NULL, `excused` INTEGER NOT NULL, `deleted` INTEGER NOT NULL)", + "fields": [ + { + "fieldPath": "id", + "columnName": "id", + "affinity": "INTEGER", + "notNull": true + }, + { + "fieldPath": "studentId", + "columnName": "student_id", + "affinity": "INTEGER", + "notNull": true + }, + { + "fieldPath": "diaryId", + "columnName": "diary_id", + "affinity": "INTEGER", + "notNull": true + }, + { + "fieldPath": "date", + "columnName": "date", + "affinity": "INTEGER", + "notNull": true + }, + { + "fieldPath": "number", + "columnName": "number", + "affinity": "INTEGER", + "notNull": true + }, + { + "fieldPath": "subject", + "columnName": "subject", + "affinity": "TEXT", + "notNull": true + }, + { + "fieldPath": "name", + "columnName": "name", + "affinity": "TEXT", + "notNull": true + }, + { + "fieldPath": "presence", + "columnName": "presence", + "affinity": "INTEGER", + "notNull": true + }, + { + "fieldPath": "absence", + "columnName": "absence", + "affinity": "INTEGER", + "notNull": true + }, + { + "fieldPath": "exemption", + "columnName": "exemption", + "affinity": "INTEGER", + "notNull": true + }, + { + "fieldPath": "lateness", + "columnName": "lateness", + "affinity": "INTEGER", + "notNull": true + }, + { + "fieldPath": "excused", + "columnName": "excused", + "affinity": "INTEGER", + "notNull": true + }, + { + "fieldPath": "deleted", + "columnName": "deleted", + "affinity": "INTEGER", + "notNull": true + } + ], + "primaryKey": { + "columnNames": [ + "id" + ], + "autoGenerate": true + }, + "indices": [], + "foreignKeys": [] + }, + { + "tableName": "AttendanceSummary", + "createSql": "CREATE TABLE IF NOT EXISTS `${TABLE_NAME}` (`id` INTEGER PRIMARY KEY AUTOINCREMENT NOT NULL, `student_id` INTEGER NOT NULL, `diary_id` INTEGER NOT NULL, `subject_id` INTEGER NOT NULL, `month` INTEGER NOT NULL, `presence` INTEGER NOT NULL, `absence` INTEGER NOT NULL, `absence_excused` INTEGER NOT NULL, `absence_for_school_reasons` INTEGER NOT NULL, `lateness` INTEGER NOT NULL, `lateness_excused` INTEGER NOT NULL, `exemption` INTEGER NOT NULL)", + "fields": [ + { + "fieldPath": "id", + "columnName": "id", + "affinity": "INTEGER", + "notNull": true + }, + { + "fieldPath": "studentId", + "columnName": "student_id", + "affinity": "INTEGER", + "notNull": true + }, + { + "fieldPath": "diaryId", + "columnName": "diary_id", + "affinity": "INTEGER", + "notNull": true + }, + { + "fieldPath": "subjectId", + "columnName": "subject_id", + "affinity": "INTEGER", + "notNull": true + }, + { + "fieldPath": "month", + "columnName": "month", + "affinity": "INTEGER", + "notNull": true + }, + { + "fieldPath": "presence", + "columnName": "presence", + "affinity": "INTEGER", + "notNull": true + }, + { + "fieldPath": "absence", + "columnName": "absence", + "affinity": "INTEGER", + "notNull": true + }, + { + "fieldPath": "absenceExcused", + "columnName": "absence_excused", + "affinity": "INTEGER", + "notNull": true + }, + { + "fieldPath": "absenceForSchoolReasons", + "columnName": "absence_for_school_reasons", + "affinity": "INTEGER", + "notNull": true + }, + { + "fieldPath": "lateness", + "columnName": "lateness", + "affinity": "INTEGER", + "notNull": true + }, + { + "fieldPath": "latenessExcused", + "columnName": "lateness_excused", + "affinity": "INTEGER", + "notNull": true + }, + { + "fieldPath": "exemption", + "columnName": "exemption", + "affinity": "INTEGER", + "notNull": true + } + ], + "primaryKey": { + "columnNames": [ + "id" + ], + "autoGenerate": true + }, + "indices": [], + "foreignKeys": [] + }, + { + "tableName": "Grades", + "createSql": "CREATE TABLE IF NOT EXISTS `${TABLE_NAME}` (`id` INTEGER PRIMARY KEY AUTOINCREMENT NOT NULL, `is_read` INTEGER NOT NULL, `is_notified` INTEGER NOT NULL, `semester_id` INTEGER NOT NULL, `student_id` INTEGER NOT NULL, `subject` TEXT NOT NULL, `entry` TEXT NOT NULL, `value` REAL NOT NULL, `modifier` REAL NOT NULL, `comment` TEXT NOT NULL, `color` TEXT NOT NULL, `grade_symbol` TEXT NOT NULL, `description` TEXT NOT NULL, `weight` TEXT NOT NULL, `weightValue` REAL NOT NULL, `date` INTEGER NOT NULL, `teacher` TEXT NOT NULL)", + "fields": [ + { + "fieldPath": "id", + "columnName": "id", + "affinity": "INTEGER", + "notNull": true + }, + { + "fieldPath": "isRead", + "columnName": "is_read", + "affinity": "INTEGER", + "notNull": true + }, + { + "fieldPath": "isNotified", + "columnName": "is_notified", + "affinity": "INTEGER", + "notNull": true + }, + { + "fieldPath": "semesterId", + "columnName": "semester_id", + "affinity": "INTEGER", + "notNull": true + }, + { + "fieldPath": "studentId", + "columnName": "student_id", + "affinity": "INTEGER", + "notNull": true + }, + { + "fieldPath": "subject", + "columnName": "subject", + "affinity": "TEXT", + "notNull": true + }, + { + "fieldPath": "entry", + "columnName": "entry", + "affinity": "TEXT", + "notNull": true + }, + { + "fieldPath": "value", + "columnName": "value", + "affinity": "REAL", + "notNull": true + }, + { + "fieldPath": "modifier", + "columnName": "modifier", + "affinity": "REAL", + "notNull": true + }, + { + "fieldPath": "comment", + "columnName": "comment", + "affinity": "TEXT", + "notNull": true + }, + { + "fieldPath": "color", + "columnName": "color", + "affinity": "TEXT", + "notNull": true + }, + { + "fieldPath": "gradeSymbol", + "columnName": "grade_symbol", + "affinity": "TEXT", + "notNull": true + }, + { + "fieldPath": "description", + "columnName": "description", + "affinity": "TEXT", + "notNull": true + }, + { + "fieldPath": "weight", + "columnName": "weight", + "affinity": "TEXT", + "notNull": true + }, + { + "fieldPath": "weightValue", + "columnName": "weightValue", + "affinity": "REAL", + "notNull": true + }, + { + "fieldPath": "date", + "columnName": "date", + "affinity": "INTEGER", + "notNull": true + }, + { + "fieldPath": "teacher", + "columnName": "teacher", + "affinity": "TEXT", + "notNull": true + } + ], + "primaryKey": { + "columnNames": [ + "id" + ], + "autoGenerate": true + }, + "indices": [], + "foreignKeys": [] + }, + { + "tableName": "GradesSummary", + "createSql": "CREATE TABLE IF NOT EXISTS `${TABLE_NAME}` (`id` INTEGER PRIMARY KEY AUTOINCREMENT NOT NULL, `semester_id` INTEGER NOT NULL, `student_id` INTEGER NOT NULL, `position` INTEGER NOT NULL, `subject` TEXT NOT NULL, `predicted_grade` TEXT NOT NULL, `final_grade` TEXT NOT NULL, `proposed_points` TEXT NOT NULL, `final_points` TEXT NOT NULL, `points_sum` TEXT NOT NULL, `average` REAL NOT NULL)", + "fields": [ + { + "fieldPath": "id", + "columnName": "id", + "affinity": "INTEGER", + "notNull": true + }, + { + "fieldPath": "semesterId", + "columnName": "semester_id", + "affinity": "INTEGER", + "notNull": true + }, + { + "fieldPath": "studentId", + "columnName": "student_id", + "affinity": "INTEGER", + "notNull": true + }, + { + "fieldPath": "position", + "columnName": "position", + "affinity": "INTEGER", + "notNull": true + }, + { + "fieldPath": "subject", + "columnName": "subject", + "affinity": "TEXT", + "notNull": true + }, + { + "fieldPath": "predictedGrade", + "columnName": "predicted_grade", + "affinity": "TEXT", + "notNull": true + }, + { + "fieldPath": "finalGrade", + "columnName": "final_grade", + "affinity": "TEXT", + "notNull": true + }, + { + "fieldPath": "proposedPoints", + "columnName": "proposed_points", + "affinity": "TEXT", + "notNull": true + }, + { + "fieldPath": "finalPoints", + "columnName": "final_points", + "affinity": "TEXT", + "notNull": true + }, + { + "fieldPath": "pointsSum", + "columnName": "points_sum", + "affinity": "TEXT", + "notNull": true + }, + { + "fieldPath": "average", + "columnName": "average", + "affinity": "REAL", + "notNull": true + } + ], + "primaryKey": { + "columnNames": [ + "id" + ], + "autoGenerate": true + }, + "indices": [], + "foreignKeys": [] + }, + { + "tableName": "GradesStatistics", + "createSql": "CREATE TABLE IF NOT EXISTS `${TABLE_NAME}` (`id` INTEGER PRIMARY KEY AUTOINCREMENT NOT NULL, `student_id` INTEGER NOT NULL, `semester_id` INTEGER NOT NULL, `subject` TEXT NOT NULL, `grade` INTEGER NOT NULL, `amount` INTEGER NOT NULL, `is_semester` INTEGER NOT NULL)", + "fields": [ + { + "fieldPath": "id", + "columnName": "id", + "affinity": "INTEGER", + "notNull": true + }, + { + "fieldPath": "studentId", + "columnName": "student_id", + "affinity": "INTEGER", + "notNull": true + }, + { + "fieldPath": "semesterId", + "columnName": "semester_id", + "affinity": "INTEGER", + "notNull": true + }, + { + "fieldPath": "subject", + "columnName": "subject", + "affinity": "TEXT", + "notNull": true + }, + { + "fieldPath": "grade", + "columnName": "grade", + "affinity": "INTEGER", + "notNull": true + }, + { + "fieldPath": "amount", + "columnName": "amount", + "affinity": "INTEGER", + "notNull": true + }, + { + "fieldPath": "semester", + "columnName": "is_semester", + "affinity": "INTEGER", + "notNull": true + } + ], + "primaryKey": { + "columnNames": [ + "id" + ], + "autoGenerate": true + }, + "indices": [], + "foreignKeys": [] + }, + { + "tableName": "GradesPointsStatistics", + "createSql": "CREATE TABLE IF NOT EXISTS `${TABLE_NAME}` (`id` INTEGER PRIMARY KEY AUTOINCREMENT NOT NULL, `student_id` INTEGER NOT NULL, `semester_id` INTEGER NOT NULL, `subject` TEXT NOT NULL, `others` REAL NOT NULL, `student` REAL NOT NULL)", + "fields": [ + { + "fieldPath": "id", + "columnName": "id", + "affinity": "INTEGER", + "notNull": true + }, + { + "fieldPath": "studentId", + "columnName": "student_id", + "affinity": "INTEGER", + "notNull": true + }, + { + "fieldPath": "semesterId", + "columnName": "semester_id", + "affinity": "INTEGER", + "notNull": true + }, + { + "fieldPath": "subject", + "columnName": "subject", + "affinity": "TEXT", + "notNull": true + }, + { + "fieldPath": "others", + "columnName": "others", + "affinity": "REAL", + "notNull": true + }, + { + "fieldPath": "student", + "columnName": "student", + "affinity": "REAL", + "notNull": true + } + ], + "primaryKey": { + "columnNames": [ + "id" + ], + "autoGenerate": true + }, + "indices": [], + "foreignKeys": [] + }, + { + "tableName": "Messages", + "createSql": "CREATE TABLE IF NOT EXISTS `${TABLE_NAME}` (`id` INTEGER PRIMARY KEY AUTOINCREMENT NOT NULL, `is_notified` INTEGER NOT NULL, `student_id` INTEGER NOT NULL, `real_id` INTEGER NOT NULL, `message_id` INTEGER NOT NULL, `sender_name` TEXT NOT NULL, `sender_id` INTEGER NOT NULL, `recipient_name` TEXT NOT NULL, `subject` TEXT NOT NULL, `content` TEXT NOT NULL, `date` INTEGER NOT NULL, `folder_id` INTEGER NOT NULL, `unread` INTEGER NOT NULL, `unread_by` INTEGER NOT NULL, `read_by` INTEGER NOT NULL, `removed` INTEGER NOT NULL)", + "fields": [ + { + "fieldPath": "id", + "columnName": "id", + "affinity": "INTEGER", + "notNull": true + }, + { + "fieldPath": "isNotified", + "columnName": "is_notified", + "affinity": "INTEGER", + "notNull": true + }, + { + "fieldPath": "studentId", + "columnName": "student_id", + "affinity": "INTEGER", + "notNull": true + }, + { + "fieldPath": "realId", + "columnName": "real_id", + "affinity": "INTEGER", + "notNull": true + }, + { + "fieldPath": "messageId", + "columnName": "message_id", + "affinity": "INTEGER", + "notNull": true + }, + { + "fieldPath": "sender", + "columnName": "sender_name", + "affinity": "TEXT", + "notNull": true + }, + { + "fieldPath": "senderId", + "columnName": "sender_id", + "affinity": "INTEGER", + "notNull": true + }, + { + "fieldPath": "recipient", + "columnName": "recipient_name", + "affinity": "TEXT", + "notNull": true + }, + { + "fieldPath": "subject", + "columnName": "subject", + "affinity": "TEXT", + "notNull": true + }, + { + "fieldPath": "content", + "columnName": "content", + "affinity": "TEXT", + "notNull": true + }, + { + "fieldPath": "date", + "columnName": "date", + "affinity": "INTEGER", + "notNull": true + }, + { + "fieldPath": "folderId", + "columnName": "folder_id", + "affinity": "INTEGER", + "notNull": true + }, + { + "fieldPath": "unread", + "columnName": "unread", + "affinity": "INTEGER", + "notNull": true + }, + { + "fieldPath": "unreadBy", + "columnName": "unread_by", + "affinity": "INTEGER", + "notNull": true + }, + { + "fieldPath": "readBy", + "columnName": "read_by", + "affinity": "INTEGER", + "notNull": true + }, + { + "fieldPath": "removed", + "columnName": "removed", + "affinity": "INTEGER", + "notNull": true + } + ], + "primaryKey": { + "columnNames": [ + "id" + ], + "autoGenerate": true + }, + "indices": [], + "foreignKeys": [] + }, + { + "tableName": "Notes", + "createSql": "CREATE TABLE IF NOT EXISTS `${TABLE_NAME}` (`id` INTEGER PRIMARY KEY AUTOINCREMENT NOT NULL, `is_read` INTEGER NOT NULL, `is_notified` INTEGER NOT NULL, `student_id` INTEGER NOT NULL, `date` INTEGER NOT NULL, `teacher` TEXT NOT NULL, `category` TEXT NOT NULL, `content` TEXT NOT NULL)", + "fields": [ + { + "fieldPath": "id", + "columnName": "id", + "affinity": "INTEGER", + "notNull": true + }, + { + "fieldPath": "isRead", + "columnName": "is_read", + "affinity": "INTEGER", + "notNull": true + }, + { + "fieldPath": "isNotified", + "columnName": "is_notified", + "affinity": "INTEGER", + "notNull": true + }, + { + "fieldPath": "studentId", + "columnName": "student_id", + "affinity": "INTEGER", + "notNull": true + }, + { + "fieldPath": "date", + "columnName": "date", + "affinity": "INTEGER", + "notNull": true + }, + { + "fieldPath": "teacher", + "columnName": "teacher", + "affinity": "TEXT", + "notNull": true + }, + { + "fieldPath": "category", + "columnName": "category", + "affinity": "TEXT", + "notNull": true + }, + { + "fieldPath": "content", + "columnName": "content", + "affinity": "TEXT", + "notNull": true + } + ], + "primaryKey": { + "columnNames": [ + "id" + ], + "autoGenerate": true + }, + "indices": [], + "foreignKeys": [] + }, + { + "tableName": "Homework", + "createSql": "CREATE TABLE IF NOT EXISTS `${TABLE_NAME}` (`id` INTEGER PRIMARY KEY AUTOINCREMENT NOT NULL, `semester_id` INTEGER NOT NULL, `student_id` INTEGER NOT NULL, `date` INTEGER NOT NULL, `entry_date` INTEGER NOT NULL, `subject` TEXT NOT NULL, `content` TEXT NOT NULL, `teacher` TEXT NOT NULL, `teacher_symbol` TEXT NOT NULL)", + "fields": [ + { + "fieldPath": "id", + "columnName": "id", + "affinity": "INTEGER", + "notNull": true + }, + { + "fieldPath": "semesterId", + "columnName": "semester_id", + "affinity": "INTEGER", + "notNull": true + }, + { + "fieldPath": "studentId", + "columnName": "student_id", + "affinity": "INTEGER", + "notNull": true + }, + { + "fieldPath": "date", + "columnName": "date", + "affinity": "INTEGER", + "notNull": true + }, + { + "fieldPath": "entryDate", + "columnName": "entry_date", + "affinity": "INTEGER", + "notNull": true + }, + { + "fieldPath": "subject", + "columnName": "subject", + "affinity": "TEXT", + "notNull": true + }, + { + "fieldPath": "content", + "columnName": "content", + "affinity": "TEXT", + "notNull": true + }, + { + "fieldPath": "teacher", + "columnName": "teacher", + "affinity": "TEXT", + "notNull": true + }, + { + "fieldPath": "teacherSymbol", + "columnName": "teacher_symbol", + "affinity": "TEXT", + "notNull": true + } + ], + "primaryKey": { + "columnNames": [ + "id" + ], + "autoGenerate": true + }, + "indices": [], + "foreignKeys": [] + }, + { + "tableName": "Subjects", + "createSql": "CREATE TABLE IF NOT EXISTS `${TABLE_NAME}` (`id` INTEGER PRIMARY KEY AUTOINCREMENT NOT NULL, `student_id` INTEGER NOT NULL, `diary_id` INTEGER NOT NULL, `real_id` INTEGER NOT NULL, `name` TEXT NOT NULL)", + "fields": [ + { + "fieldPath": "id", + "columnName": "id", + "affinity": "INTEGER", + "notNull": true + }, + { + "fieldPath": "studentId", + "columnName": "student_id", + "affinity": "INTEGER", + "notNull": true + }, + { + "fieldPath": "diaryId", + "columnName": "diary_id", + "affinity": "INTEGER", + "notNull": true + }, + { + "fieldPath": "realId", + "columnName": "real_id", + "affinity": "INTEGER", + "notNull": true + }, + { + "fieldPath": "name", + "columnName": "name", + "affinity": "TEXT", + "notNull": true + } + ], + "primaryKey": { + "columnNames": [ + "id" + ], + "autoGenerate": true + }, + "indices": [], + "foreignKeys": [] + }, + { + "tableName": "LuckyNumbers", + "createSql": "CREATE TABLE IF NOT EXISTS `${TABLE_NAME}` (`id` INTEGER PRIMARY KEY AUTOINCREMENT NOT NULL, `is_notified` INTEGER NOT NULL, `student_id` INTEGER NOT NULL, `date` INTEGER NOT NULL, `lucky_number` INTEGER NOT NULL)", + "fields": [ + { + "fieldPath": "id", + "columnName": "id", + "affinity": "INTEGER", + "notNull": true + }, + { + "fieldPath": "isNotified", + "columnName": "is_notified", + "affinity": "INTEGER", + "notNull": true + }, + { + "fieldPath": "studentId", + "columnName": "student_id", + "affinity": "INTEGER", + "notNull": true + }, + { + "fieldPath": "date", + "columnName": "date", + "affinity": "INTEGER", + "notNull": true + }, + { + "fieldPath": "luckyNumber", + "columnName": "lucky_number", + "affinity": "INTEGER", + "notNull": true + } + ], + "primaryKey": { + "columnNames": [ + "id" + ], + "autoGenerate": true + }, + "indices": [], + "foreignKeys": [] + }, + { + "tableName": "CompletedLesson", + "createSql": "CREATE TABLE IF NOT EXISTS `${TABLE_NAME}` (`id` INTEGER PRIMARY KEY AUTOINCREMENT NOT NULL, `student_id` INTEGER NOT NULL, `diary_id` INTEGER NOT NULL, `date` INTEGER NOT NULL, `number` INTEGER NOT NULL, `subject` TEXT NOT NULL, `topic` TEXT NOT NULL, `teacher` TEXT NOT NULL, `teacher_symbol` TEXT NOT NULL, `substitution` TEXT NOT NULL, `absence` TEXT NOT NULL, `resources` TEXT NOT NULL)", + "fields": [ + { + "fieldPath": "id", + "columnName": "id", + "affinity": "INTEGER", + "notNull": true + }, + { + "fieldPath": "studentId", + "columnName": "student_id", + "affinity": "INTEGER", + "notNull": true + }, + { + "fieldPath": "diaryId", + "columnName": "diary_id", + "affinity": "INTEGER", + "notNull": true + }, + { + "fieldPath": "date", + "columnName": "date", + "affinity": "INTEGER", + "notNull": true + }, + { + "fieldPath": "number", + "columnName": "number", + "affinity": "INTEGER", + "notNull": true + }, + { + "fieldPath": "subject", + "columnName": "subject", + "affinity": "TEXT", + "notNull": true + }, + { + "fieldPath": "topic", + "columnName": "topic", + "affinity": "TEXT", + "notNull": true + }, + { + "fieldPath": "teacher", + "columnName": "teacher", + "affinity": "TEXT", + "notNull": true + }, + { + "fieldPath": "teacherSymbol", + "columnName": "teacher_symbol", + "affinity": "TEXT", + "notNull": true + }, + { + "fieldPath": "substitution", + "columnName": "substitution", + "affinity": "TEXT", + "notNull": true + }, + { + "fieldPath": "absence", + "columnName": "absence", + "affinity": "TEXT", + "notNull": true + }, + { + "fieldPath": "resources", + "columnName": "resources", + "affinity": "TEXT", + "notNull": true + } + ], + "primaryKey": { + "columnNames": [ + "id" + ], + "autoGenerate": true + }, + "indices": [], + "foreignKeys": [] + }, + { + "tableName": "ReportingUnits", + "createSql": "CREATE TABLE IF NOT EXISTS `${TABLE_NAME}` (`id` INTEGER PRIMARY KEY AUTOINCREMENT NOT NULL, `student_id` INTEGER NOT NULL, `real_id` INTEGER NOT NULL, `short` TEXT NOT NULL, `sender_id` INTEGER NOT NULL, `sender_name` TEXT NOT NULL, `roles` TEXT NOT NULL)", + "fields": [ + { + "fieldPath": "id", + "columnName": "id", + "affinity": "INTEGER", + "notNull": true + }, + { + "fieldPath": "studentId", + "columnName": "student_id", + "affinity": "INTEGER", + "notNull": true + }, + { + "fieldPath": "realId", + "columnName": "real_id", + "affinity": "INTEGER", + "notNull": true + }, + { + "fieldPath": "shortName", + "columnName": "short", + "affinity": "TEXT", + "notNull": true + }, + { + "fieldPath": "senderId", + "columnName": "sender_id", + "affinity": "INTEGER", + "notNull": true + }, + { + "fieldPath": "senderName", + "columnName": "sender_name", + "affinity": "TEXT", + "notNull": true + }, + { + "fieldPath": "roles", + "columnName": "roles", + "affinity": "TEXT", + "notNull": true + } + ], + "primaryKey": { + "columnNames": [ + "id" + ], + "autoGenerate": true + }, + "indices": [], + "foreignKeys": [] + }, + { + "tableName": "Recipients", + "createSql": "CREATE TABLE IF NOT EXISTS `${TABLE_NAME}` (`id` INTEGER PRIMARY KEY AUTOINCREMENT NOT NULL, `student_id` INTEGER NOT NULL, `real_id` TEXT NOT NULL, `name` TEXT NOT NULL, `real_name` TEXT NOT NULL, `login_id` INTEGER NOT NULL, `unit_id` INTEGER NOT NULL, `role` INTEGER NOT NULL, `hash` TEXT NOT NULL)", + "fields": [ + { + "fieldPath": "id", + "columnName": "id", + "affinity": "INTEGER", + "notNull": true + }, + { + "fieldPath": "studentId", + "columnName": "student_id", + "affinity": "INTEGER", + "notNull": true + }, + { + "fieldPath": "realId", + "columnName": "real_id", + "affinity": "TEXT", + "notNull": true + }, + { + "fieldPath": "name", + "columnName": "name", + "affinity": "TEXT", + "notNull": true + }, + { + "fieldPath": "realName", + "columnName": "real_name", + "affinity": "TEXT", + "notNull": true + }, + { + "fieldPath": "loginId", + "columnName": "login_id", + "affinity": "INTEGER", + "notNull": true + }, + { + "fieldPath": "unitId", + "columnName": "unit_id", + "affinity": "INTEGER", + "notNull": true + }, + { + "fieldPath": "role", + "columnName": "role", + "affinity": "INTEGER", + "notNull": true + }, + { + "fieldPath": "hash", + "columnName": "hash", + "affinity": "TEXT", + "notNull": true + } + ], + "primaryKey": { + "columnNames": [ + "id" + ], + "autoGenerate": true + }, + "indices": [], + "foreignKeys": [] + }, + { + "tableName": "MobileDevices", + "createSql": "CREATE TABLE IF NOT EXISTS `${TABLE_NAME}` (`id` INTEGER PRIMARY KEY AUTOINCREMENT NOT NULL, `student_id` INTEGER NOT NULL, `device_id` INTEGER NOT NULL, `name` TEXT NOT NULL, `date` INTEGER NOT NULL)", + "fields": [ + { + "fieldPath": "id", + "columnName": "id", + "affinity": "INTEGER", + "notNull": true + }, + { + "fieldPath": "studentId", + "columnName": "student_id", + "affinity": "INTEGER", + "notNull": true + }, + { + "fieldPath": "deviceId", + "columnName": "device_id", + "affinity": "INTEGER", + "notNull": true + }, + { + "fieldPath": "name", + "columnName": "name", + "affinity": "TEXT", + "notNull": true + }, + { + "fieldPath": "date", + "columnName": "date", + "affinity": "INTEGER", + "notNull": true + } + ], + "primaryKey": { + "columnNames": [ + "id" + ], + "autoGenerate": true + }, + "indices": [], + "foreignKeys": [] + }, + { + "tableName": "Teachers", + "createSql": "CREATE TABLE IF NOT EXISTS `${TABLE_NAME}` (`id` INTEGER PRIMARY KEY AUTOINCREMENT NOT NULL, `student_id` INTEGER NOT NULL, `class_id` INTEGER NOT NULL, `subject` TEXT NOT NULL, `name` TEXT NOT NULL, `short_name` TEXT NOT NULL)", + "fields": [ + { + "fieldPath": "id", + "columnName": "id", + "affinity": "INTEGER", + "notNull": true + }, + { + "fieldPath": "studentId", + "columnName": "student_id", + "affinity": "INTEGER", + "notNull": true + }, + { + "fieldPath": "classId", + "columnName": "class_id", + "affinity": "INTEGER", + "notNull": true + }, + { + "fieldPath": "subject", + "columnName": "subject", + "affinity": "TEXT", + "notNull": true + }, + { + "fieldPath": "name", + "columnName": "name", + "affinity": "TEXT", + "notNull": true + }, + { + "fieldPath": "shortName", + "columnName": "short_name", + "affinity": "TEXT", + "notNull": true + } + ], + "primaryKey": { + "columnNames": [ + "id" + ], + "autoGenerate": true + }, + "indices": [], + "foreignKeys": [] + }, + { + "tableName": "School", + "createSql": "CREATE TABLE IF NOT EXISTS `${TABLE_NAME}` (`id` INTEGER PRIMARY KEY AUTOINCREMENT NOT NULL, `student_id` INTEGER NOT NULL, `class_id` INTEGER NOT NULL, `name` TEXT NOT NULL, `address` TEXT NOT NULL, `contact` TEXT NOT NULL, `headmaster` TEXT NOT NULL, `pedagogue` TEXT NOT NULL)", + "fields": [ + { + "fieldPath": "id", + "columnName": "id", + "affinity": "INTEGER", + "notNull": true + }, + { + "fieldPath": "studentId", + "columnName": "student_id", + "affinity": "INTEGER", + "notNull": true + }, + { + "fieldPath": "classId", + "columnName": "class_id", + "affinity": "INTEGER", + "notNull": true + }, + { + "fieldPath": "name", + "columnName": "name", + "affinity": "TEXT", + "notNull": true + }, + { + "fieldPath": "address", + "columnName": "address", + "affinity": "TEXT", + "notNull": true + }, + { + "fieldPath": "contact", + "columnName": "contact", + "affinity": "TEXT", + "notNull": true + }, + { + "fieldPath": "headmaster", + "columnName": "headmaster", + "affinity": "TEXT", + "notNull": true + }, + { + "fieldPath": "pedagogue", + "columnName": "pedagogue", + "affinity": "TEXT", + "notNull": true + } + ], + "primaryKey": { + "columnNames": [ + "id" + ], + "autoGenerate": true + }, + "indices": [], + "foreignKeys": [] + } + ], + "views": [], + "setupQueries": [ + "CREATE TABLE IF NOT EXISTS room_master_table (id INTEGER PRIMARY KEY,identity_hash TEXT)", + "INSERT OR REPLACE INTO room_master_table (id,identity_hash) VALUES(42, '37a216a7afcea922b66001ca5ed6cf74')" + ] + } +} \ No newline at end of file diff --git a/app/src/androidTest/java/io/github/wulkanowy/data/repositories/timetable/TestTimetableEntityCreator.kt b/app/src/androidTest/java/io/github/wulkanowy/data/repositories/timetable/TestTimetableEntityCreator.kt index e2ce2255c..c1e23c578 100644 --- a/app/src/androidTest/java/io/github/wulkanowy/data/repositories/timetable/TestTimetableEntityCreator.kt +++ b/app/src/androidTest/java/io/github/wulkanowy/data/repositories/timetable/TestTimetableEntityCreator.kt @@ -21,6 +21,7 @@ fun createTimetableLocal(start: LocalDateTime, number: Int, room: String = "", s teacher = teacher, teacherOld = "", info = "", + studentPlan = true, changes = changes, canceled = false ) diff --git a/app/src/main/java/io/github/wulkanowy/data/db/AppDatabase.kt b/app/src/main/java/io/github/wulkanowy/data/db/AppDatabase.kt index 9ee1b263d..fe4285052 100644 --- a/app/src/main/java/io/github/wulkanowy/data/db/AppDatabase.kt +++ b/app/src/main/java/io/github/wulkanowy/data/db/AppDatabase.kt @@ -60,6 +60,7 @@ import io.github.wulkanowy.data.db.migrations.Migration17 import io.github.wulkanowy.data.db.migrations.Migration18 import io.github.wulkanowy.data.db.migrations.Migration19 import io.github.wulkanowy.data.db.migrations.Migration2 +import io.github.wulkanowy.data.db.migrations.Migration20 import io.github.wulkanowy.data.db.migrations.Migration3 import io.github.wulkanowy.data.db.migrations.Migration4 import io.github.wulkanowy.data.db.migrations.Migration5 @@ -101,7 +102,7 @@ import javax.inject.Singleton abstract class AppDatabase : RoomDatabase() { companion object { - const val VERSION_SCHEMA = 19 + const val VERSION_SCHEMA = 20 fun getMigrations(sharedPrefProvider: SharedPrefProvider): Array { return arrayOf( @@ -122,7 +123,8 @@ abstract class AppDatabase : RoomDatabase() { Migration16(), Migration17(), Migration18(), - Migration19(sharedPrefProvider) + Migration19(sharedPrefProvider), + Migration20() ) } diff --git a/app/src/main/java/io/github/wulkanowy/data/db/entities/Timetable.kt b/app/src/main/java/io/github/wulkanowy/data/db/entities/Timetable.kt index 9bc3d2140..313feb62c 100644 --- a/app/src/main/java/io/github/wulkanowy/data/db/entities/Timetable.kt +++ b/app/src/main/java/io/github/wulkanowy/data/db/entities/Timetable.kt @@ -40,6 +40,9 @@ data class Timetable( val info: String, + @ColumnInfo(name = "student_plan") + val studentPlan: Boolean, + val changes: Boolean, val canceled: Boolean diff --git a/app/src/main/java/io/github/wulkanowy/data/db/migrations/Migration20.kt b/app/src/main/java/io/github/wulkanowy/data/db/migrations/Migration20.kt new file mode 100644 index 000000000..4f7cdd03f --- /dev/null +++ b/app/src/main/java/io/github/wulkanowy/data/db/migrations/Migration20.kt @@ -0,0 +1,33 @@ +package io.github.wulkanowy.data.db.migrations + +import androidx.room.migration.Migration +import androidx.sqlite.db.SupportSQLiteDatabase + +class Migration20 : Migration(19, 20) { + + override fun migrate(database: SupportSQLiteDatabase) { + database.execSQL("DROP TABLE Timetable") + database.execSQL(""" + CREATE TABLE IF NOT EXISTS `Timetable` ( + `id` INTEGER PRIMARY KEY AUTOINCREMENT NOT NULL, + `student_id` INTEGER NOT NULL, + `diary_id` INTEGER NOT NULL, + `number` INTEGER NOT NULL, + `start` INTEGER NOT NULL, + `end` INTEGER NOT NULL, + `date` INTEGER NOT NULL, + `subject` TEXT NOT NULL, + `subjectOld` TEXT NOT NULL, + `group` TEXT NOT NULL, + `room` TEXT NOT NULL, + `roomOld` TEXT NOT NULL, + `teacher` TEXT NOT NULL, + `teacherOld` TEXT NOT NULL, + `info` TEXT NOT NULL, + `student_plan` INTEGER NOT NULL, + `changes` INTEGER NOT NULL, + `canceled` INTEGER NOT NULL + ) + """) + } +} diff --git a/app/src/main/java/io/github/wulkanowy/data/repositories/preferences/PreferencesRepository.kt b/app/src/main/java/io/github/wulkanowy/data/repositories/preferences/PreferencesRepository.kt index 07a3654ac..523caf6c9 100644 --- a/app/src/main/java/io/github/wulkanowy/data/repositories/preferences/PreferencesRepository.kt +++ b/app/src/main/java/io/github/wulkanowy/data/repositories/preferences/PreferencesRepository.kt @@ -65,6 +65,9 @@ class PreferencesRepository @Inject constructor( val fillMessageContent: Boolean get() = getBoolean(R.string.pref_key_fill_message_content, R.bool.pref_default_fill_message_content) + val showWholeClassPlan: String + get() = getString(R.string.pref_key_timetable_show_whole_class, R.string.pref_default_timetable_show_whole_class) + private fun getString(id: Int, default: Int) = getString(context.getString(id), default) private fun getString(id: String, default: Int) = sharedPref.getString(id, context.getString(default)) ?: context.getString(default) diff --git a/app/src/main/java/io/github/wulkanowy/data/repositories/semester/SemesterRepository.kt b/app/src/main/java/io/github/wulkanowy/data/repositories/semester/SemesterRepository.kt index 95fddc1b3..6377cb78e 100644 --- a/app/src/main/java/io/github/wulkanowy/data/repositories/semester/SemesterRepository.kt +++ b/app/src/main/java/io/github/wulkanowy/data/repositories/semester/SemesterRepository.kt @@ -36,7 +36,7 @@ class SemesterRepository @Inject constructor( local.saveSemesters(new.uniqueSubtract(old)) } } else { - Timber.i("Current semesters list:\n${currentSemesters.joinToString(separator = "\n")}") + Timber.i("Current semesters list:\n${new.joinToString(separator = "\n")}") throw IllegalArgumentException("Current semester can be only one.") } }.flatMap { local.getSemesters(student).toSingle(emptyList()) }) diff --git a/app/src/main/java/io/github/wulkanowy/data/repositories/timetable/TimetableRemote.kt b/app/src/main/java/io/github/wulkanowy/data/repositories/timetable/TimetableRemote.kt index 6036bd405..26e7836ad 100644 --- a/app/src/main/java/io/github/wulkanowy/data/repositories/timetable/TimetableRemote.kt +++ b/app/src/main/java/io/github/wulkanowy/data/repositories/timetable/TimetableRemote.kt @@ -30,6 +30,7 @@ class TimetableRemote @Inject constructor(private val sdk: Sdk) { teacher = it.teacher, teacherOld = it.teacherOld, info = it.info, + studentPlan = it.studentPlan, changes = it.changes, canceled = it.canceled ) diff --git a/app/src/main/java/io/github/wulkanowy/ui/modules/timetable/TimetableItem.kt b/app/src/main/java/io/github/wulkanowy/ui/modules/timetable/TimetableItem.kt index 0991981df..99aca2a23 100644 --- a/app/src/main/java/io/github/wulkanowy/ui/modules/timetable/TimetableItem.kt +++ b/app/src/main/java/io/github/wulkanowy/ui/modules/timetable/TimetableItem.kt @@ -15,11 +15,15 @@ import io.github.wulkanowy.utils.getThemeAttrColor import io.github.wulkanowy.utils.toFormattedString import kotlinx.android.extensions.LayoutContainer import kotlinx.android.synthetic.main.item_timetable.* +import kotlinx.android.synthetic.main.item_timetable_small.* -class TimetableItem(val lesson: Timetable) : +class TimetableItem(val lesson: Timetable, private val showWholeClassPlan: String) : AbstractFlexibleItem() { - override fun getLayoutRes() = R.layout.item_timetable + override fun getLayoutRes() = when { + showWholeClassPlan == "small" && !lesson.studentPlan -> R.layout.item_timetable_small + else -> R.layout.item_timetable + } override fun createViewHolder(view: View, adapter: FlexibleAdapter>): ViewHolder { return ViewHolder(view, adapter) @@ -27,16 +31,29 @@ class TimetableItem(val lesson: Timetable) : @SuppressLint("SetTextI18n") override fun bindViewHolder(adapter: FlexibleAdapter>, holder: ViewHolder, position: Int, payloads: MutableList?) { - updateFields(holder) + when (itemViewType) { + R.layout.item_timetable_small -> { + with(holder) { + timetableSmallItemNumber.text = lesson.number.toString() + timetableSmallItemSubject.text = lesson.subject + timetableSmallItemTimeStart.text = lesson.start.toFormattedString("HH:mm") + timetableSmallItemRoom.text = lesson.room + timetableSmallItemTeacher.text = lesson.teacher + } + } + R.layout.item_timetable -> { + updateFields(holder) - with(holder) { - timetableItemSubject.paintFlags = - if (lesson.canceled) timetableItemSubject.paintFlags or Paint.STRIKE_THRU_TEXT_FLAG - else timetableItemSubject.paintFlags and Paint.STRIKE_THRU_TEXT_FLAG.inv() + with(holder) { + timetableItemSubject.paintFlags = + if (lesson.canceled) timetableItemSubject.paintFlags or Paint.STRIKE_THRU_TEXT_FLAG + else timetableItemSubject.paintFlags and Paint.STRIKE_THRU_TEXT_FLAG.inv() + } + + updateDescription(holder) + updateColors(holder) + } } - - updateDescription(holder) - updateColors(holder) } private fun updateFields(holder: ViewHolder) { diff --git a/app/src/main/java/io/github/wulkanowy/ui/modules/timetable/TimetablePresenter.kt b/app/src/main/java/io/github/wulkanowy/ui/modules/timetable/TimetablePresenter.kt index 4c30ecb7f..d9eb44785 100644 --- a/app/src/main/java/io/github/wulkanowy/ui/modules/timetable/TimetablePresenter.kt +++ b/app/src/main/java/io/github/wulkanowy/ui/modules/timetable/TimetablePresenter.kt @@ -2,6 +2,8 @@ package io.github.wulkanowy.ui.modules.timetable import android.annotation.SuppressLint import eu.davidea.flexibleadapter.items.AbstractFlexibleItem +import io.github.wulkanowy.data.db.entities.Timetable +import io.github.wulkanowy.data.repositories.preferences.PreferencesRepository import io.github.wulkanowy.data.repositories.semester.SemesterRepository import io.github.wulkanowy.data.repositories.student.StudentRepository import io.github.wulkanowy.data.repositories.timetable.TimetableRepository @@ -29,6 +31,7 @@ class TimetablePresenter @Inject constructor( studentRepository: StudentRepository, private val timetableRepository: TimetableRepository, private val semesterRepository: SemesterRepository, + private val prefRepository: PreferencesRepository, private val analytics: FirebaseAnalyticsHelper ) : BasePresenter(errorHandler, studentRepository, schedulers) { @@ -134,7 +137,7 @@ class TimetablePresenter @Inject constructor( .flatMap { semesterRepository.getCurrentSemester(it) } .delay(200, MILLISECONDS) .flatMap { timetableRepository.getTimetable(it, currentDate, currentDate, forceRefresh) } - .map { items -> items.map { TimetableItem(it) } } + .map { createTimetableItems(it) } .map { items -> items.sortedBy { it.lesson.number } } .subscribeOn(schedulers.backgroundThread) .observeOn(schedulers.mainThread) @@ -172,6 +175,12 @@ class TimetablePresenter @Inject constructor( } } + private fun createTimetableItems(items: List): List { + return items + .filter { if (prefRepository.showWholeClassPlan == "no") it.studentPlan else true } + .map { TimetableItem(it, prefRepository.showWholeClassPlan) } + } + private fun reloadView() { Timber.i("Reload timetable view with the date ${currentDate.toFormattedString()}") view?.apply { diff --git a/app/src/main/res/layout/item_timetable_small.xml b/app/src/main/res/layout/item_timetable_small.xml new file mode 100644 index 000000000..39e84ae07 --- /dev/null +++ b/app/src/main/res/layout/item_timetable_small.xml @@ -0,0 +1,81 @@ + + + + + + + + + + + + + + diff --git a/app/src/main/res/values-pl/preferences_values.xml b/app/src/main/res/values-pl/preferences_values.xml index 33a66e0f7..c3fcc9803 100644 --- a/app/src/main/res/values-pl/preferences_values.xml +++ b/app/src/main/res/values-pl/preferences_values.xml @@ -41,4 +41,10 @@ Średnia ocen z 2 semestru Średnia ocen z całego roku + + + Nie pokazuj + Pokazuj wszystkie + Pokazuj pomniejszone + diff --git a/app/src/main/res/values-pl/strings.xml b/app/src/main/res/values-pl/strings.xml index bccd4ae18..a59146974 100644 --- a/app/src/main/res/values-pl/strings.xml +++ b/app/src/main/res/values-pl/strings.xml @@ -366,4 +366,5 @@ Wystąpił nieoczekiwany błąd Funkcja wyłączona przez szkołę Funkcja niedostępna w tym trybie + Pokazuj lekcje całej klasy diff --git a/app/src/main/res/values-ru/preferences_values.xml b/app/src/main/res/values-ru/preferences_values.xml index 641d754f8..0e82c2801 100644 --- a/app/src/main/res/values-ru/preferences_values.xml +++ b/app/src/main/res/values-ru/preferences_values.xml @@ -36,4 +36,10 @@ Средняя оценка со 2 семестра Средняя оценка с целого года + + + Не показывать + Показать все + Показать меньше + diff --git a/app/src/main/res/values-ru/strings.xml b/app/src/main/res/values-ru/strings.xml index 0499cbf55..062386dc3 100644 --- a/app/src/main/res/values-ru/strings.xml +++ b/app/src/main/res/values-ru/strings.xml @@ -364,5 +364,6 @@ Произошла неожиданная ошибка Функция была выключена школой Функция не доступна в этом режиме + Показать уроки всего класса diff --git a/app/src/main/res/values/preferences_defaults.xml b/app/src/main/res/values/preferences_defaults.xml index 91b357d93..be31b440f 100644 --- a/app/src/main/res/values/preferences_defaults.xml +++ b/app/src/main/res/values/preferences_defaults.xml @@ -16,4 +16,5 @@ 0.33 0.33 true + no diff --git a/app/src/main/res/values/preferences_keys.xml b/app/src/main/res/values/preferences_keys.xml index a2172db96..49601b550 100644 --- a/app/src/main/res/values/preferences_keys.xml +++ b/app/src/main/res/values/preferences_keys.xml @@ -16,4 +16,5 @@ grade_modifier_plus grade_modifier_minus fill_message_content + show_whole_class_plan diff --git a/app/src/main/res/values/preferences_values.xml b/app/src/main/res/values/preferences_values.xml index ee54d53c6..3b1fde65d 100644 --- a/app/src/main/res/values/preferences_values.xml +++ b/app/src/main/res/values/preferences_values.xml @@ -90,4 +90,15 @@ only_one_semester all_year + + + No show + Show all + Show smaller + + + no + yes + small + diff --git a/app/src/main/res/values/strings.xml b/app/src/main/res/values/strings.xml index 1b07a9fea..3ad60ee2c 100644 --- a/app/src/main/res/values/strings.xml +++ b/app/src/main/res/values/strings.xml @@ -301,6 +301,7 @@ Show presence in attendance Application theme Expand grades + Show whole class lessons Grades color scheme App language diff --git a/app/src/main/res/xml/scheme_preferences.xml b/app/src/main/res/xml/scheme_preferences.xml index d9e6c5333..e92aca63f 100644 --- a/app/src/main/res/xml/scheme_preferences.xml +++ b/app/src/main/res/xml/scheme_preferences.xml @@ -29,6 +29,14 @@ app:iconSpaceReserved="false" app:key="@string/pref_key_expand_grade" app:title="@string/pref_view_expand_grade" /> + Date: Wed, 22 Jan 2020 10:59:13 +0100 Subject: [PATCH 10/18] Add creators list (#636) --- app/build.gradle | 2 + app/src/main/assets/creators.json | 34 +++++++++ .../github/wulkanowy/data/RepositoryModule.kt | 5 ++ .../github/wulkanowy/data/pojos/AppCreator.kt | 3 + .../appcreator/AppCreatorRepository.kt | 20 +++++ .../ui/modules/about/AboutFragment.kt | 10 +++ .../ui/modules/about/AboutPresenter.kt | 6 ++ .../wulkanowy/ui/modules/about/AboutView.kt | 4 + .../modules/about/creator/CreatorFragment.kt | 76 +++++++++++++++++++ .../ui/modules/about/creator/CreatorItem.kt | 50 ++++++++++++ .../modules/about/creator/CreatorPresenter.kt | 43 +++++++++++ .../ui/modules/about/creator/CreatorView.kt | 16 ++++ .../wulkanowy/ui/modules/main/MainModule.kt | 5 ++ .../main/res/drawable/ic_about_creator.xml | 9 +++ app/src/main/res/layout/fragment_creator.xml | 37 +++++++++ app/src/main/res/layout/item_creator.xml | 34 +++++++++ app/src/main/res/values-pl/strings.xml | 8 ++ app/src/main/res/values/strings.xml | 8 ++ 18 files changed, 370 insertions(+) create mode 100644 app/src/main/assets/creators.json create mode 100644 app/src/main/java/io/github/wulkanowy/data/pojos/AppCreator.kt create mode 100644 app/src/main/java/io/github/wulkanowy/data/repositories/appcreator/AppCreatorRepository.kt create mode 100644 app/src/main/java/io/github/wulkanowy/ui/modules/about/creator/CreatorFragment.kt create mode 100644 app/src/main/java/io/github/wulkanowy/ui/modules/about/creator/CreatorItem.kt create mode 100644 app/src/main/java/io/github/wulkanowy/ui/modules/about/creator/CreatorPresenter.kt create mode 100644 app/src/main/java/io/github/wulkanowy/ui/modules/about/creator/CreatorView.kt create mode 100644 app/src/main/res/drawable/ic_about_creator.xml create mode 100644 app/src/main/res/layout/fragment_creator.xml create mode 100644 app/src/main/res/layout/item_creator.xml diff --git a/app/build.gradle b/app/build.gradle index 0e86fc591..e17731d40 100644 --- a/app/build.gradle +++ b/app/build.gradle @@ -176,6 +176,8 @@ dependencies { implementation "com.mikepenz:aboutlibraries-core:7.1.0" implementation 'com.wdullaer:materialdatetimepicker:4.2.3' + implementation("io.coil-kt:coil:0.9.2") + playImplementation "com.google.firebase:firebase-core:17.2.2" playImplementation "com.crashlytics.sdk.android:crashlytics:2.10.1" diff --git a/app/src/main/assets/creators.json b/app/src/main/assets/creators.json new file mode 100644 index 000000000..b99f51e21 --- /dev/null +++ b/app/src/main/assets/creators.json @@ -0,0 +1,34 @@ +[ + { + "displayName": "Mikołaj Pich", + "githubUsername": "mklkj" + }, + { + "displayName": "Rafał Borcz", + "githubUsername": "Faierbel" + }, + { + "displayName": "Dominik Korsa", + "githubUsername": "dominik-korsa" + }, + { + "displayName": "Kacper Ziubryniewicz", + "githubUsername": "kapi2289" + }, + { + "displayName": "doteq", + "githubUsername": "doteq" + }, + { + "displayName": "Pavuloff", + "githubUsername": "pavuloff" + }, + { + "displayName": "Piotr Romanowski", + "githubUsername": "v0idzz" + }, + { + "displayName": "Dinolek", + "githubUsername": "Dinolek" + } +] diff --git a/app/src/main/java/io/github/wulkanowy/data/RepositoryModule.kt b/app/src/main/java/io/github/wulkanowy/data/RepositoryModule.kt index 1bc4eb616..48e51e3ce 100644 --- a/app/src/main/java/io/github/wulkanowy/data/RepositoryModule.kt +++ b/app/src/main/java/io/github/wulkanowy/data/RepositoryModule.kt @@ -2,6 +2,7 @@ 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.github.pwittchen.reactivenetwork.library.rx2.internet.observing.InternetObservingSettings @@ -58,6 +59,10 @@ internal class RepositoryModule { @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) diff --git a/app/src/main/java/io/github/wulkanowy/data/pojos/AppCreator.kt b/app/src/main/java/io/github/wulkanowy/data/pojos/AppCreator.kt new file mode 100644 index 000000000..d67aa2a7f --- /dev/null +++ b/app/src/main/java/io/github/wulkanowy/data/pojos/AppCreator.kt @@ -0,0 +1,3 @@ +package io.github.wulkanowy.data.pojos + +class AppCreator(val displayName: String, val githubUsername: String) diff --git a/app/src/main/java/io/github/wulkanowy/data/repositories/appcreator/AppCreatorRepository.kt b/app/src/main/java/io/github/wulkanowy/data/repositories/appcreator/AppCreatorRepository.kt new file mode 100644 index 000000000..095b37166 --- /dev/null +++ b/app/src/main/java/io/github/wulkanowy/data/repositories/appcreator/AppCreatorRepository.kt @@ -0,0 +1,20 @@ +package io.github.wulkanowy.data.repositories.appcreator + +import android.content.res.AssetManager +import com.google.gson.Gson +import io.github.wulkanowy.data.pojos.AppCreator +import io.reactivex.Single +import javax.inject.Inject +import javax.inject.Singleton + +@Singleton +class AppCreatorRepository @Inject constructor(private val assets: AssetManager) { + fun getAppCreators(): Single> { + return Single.fromCallable> { + Gson().fromJson( + assets.open("creators.json").bufferedReader().use { it.readText() }, + Array::class.java + ).toList() + } + } +} diff --git a/app/src/main/java/io/github/wulkanowy/ui/modules/about/AboutFragment.kt b/app/src/main/java/io/github/wulkanowy/ui/modules/about/AboutFragment.kt index 22276bdf9..d9430a47a 100644 --- a/app/src/main/java/io/github/wulkanowy/ui/modules/about/AboutFragment.kt +++ b/app/src/main/java/io/github/wulkanowy/ui/modules/about/AboutFragment.kt @@ -16,6 +16,7 @@ import eu.davidea.flexibleadapter.common.SmoothScrollLinearLayoutManager import eu.davidea.flexibleadapter.items.AbstractFlexibleItem import io.github.wulkanowy.R import io.github.wulkanowy.ui.base.BaseFragment +import io.github.wulkanowy.ui.modules.about.creator.CreatorFragment import io.github.wulkanowy.ui.modules.about.license.LicenseFragment import io.github.wulkanowy.ui.modules.main.MainActivity import io.github.wulkanowy.ui.modules.main.MainView @@ -42,6 +43,11 @@ class AboutFragment : BaseFragment(), AboutView, MainView.TitledView { Triple(getString(R.string.about_version), "${appInfo.versionName} (${appInfo.versionCode})", getCompatDrawable(R.drawable.ic_all_about)) } + override val creatorsRes: Triple? + get() = context?.run { + Triple(getString(R.string.about_creator), getString(R.string.about_creator_summary), getCompatDrawable(R.drawable.ic_about_creator)) + } + override val feedbackRes: Triple? get() = context?.run { Triple(getString(R.string.about_feedback), getString(R.string.about_feedback_summary), getCompatDrawable(R.drawable.ic_about_feedback)) @@ -143,6 +149,10 @@ class AboutFragment : BaseFragment(), AboutView, MainView.TitledView { (activity as? MainActivity)?.pushView(LicenseFragment.newInstance()) } + override fun openCreators() { + (activity as? MainActivity)?.pushView(CreatorFragment.newInstance()) + } + override fun openPrivacyPolicy() { context?.openInternetBrowser("https://wulkanowy.github.io/polityka-prywatnosci.html", ::showMessage) } diff --git a/app/src/main/java/io/github/wulkanowy/ui/modules/about/AboutPresenter.kt b/app/src/main/java/io/github/wulkanowy/ui/modules/about/AboutPresenter.kt index 8087c9556..662939832 100644 --- a/app/src/main/java/io/github/wulkanowy/ui/modules/about/AboutPresenter.kt +++ b/app/src/main/java/io/github/wulkanowy/ui/modules/about/AboutPresenter.kt @@ -52,6 +52,11 @@ class AboutPresenter @Inject constructor( openLicenses() analytics.logEvent("about_open", "name" to "licenses") } + creatorsRes?.first -> { + Timber.i("Opening creators view") + openCreators() + analytics.logEvent("about_open", "name" to "creators") + } privacyRes?.first -> { Timber.i("Opening privacy page ") openPrivacyPolicy() @@ -65,6 +70,7 @@ class AboutPresenter @Inject constructor( view?.run { updateData(AboutScrollableHeader(), listOfNotNull( versionRes?.let { (title, summary, image) -> AboutItem(title, summary, image) }, + creatorsRes?.let { (title, summary, image) -> AboutItem(title, summary, image) }, feedbackRes?.let { (title, summary, image) -> AboutItem(title, summary, image) }, faqRes?.let { (title, summary, image) -> AboutItem(title, summary, image) }, discordRes?.let { (title, summary, image) -> AboutItem(title, summary, image) }, diff --git a/app/src/main/java/io/github/wulkanowy/ui/modules/about/AboutView.kt b/app/src/main/java/io/github/wulkanowy/ui/modules/about/AboutView.kt index 34850bae4..228225ec6 100644 --- a/app/src/main/java/io/github/wulkanowy/ui/modules/about/AboutView.kt +++ b/app/src/main/java/io/github/wulkanowy/ui/modules/about/AboutView.kt @@ -7,6 +7,8 @@ interface AboutView : BaseView { val versionRes: Triple? + val creatorsRes: Triple? + val feedbackRes: Triple? val faqRes: Triple? @@ -33,5 +35,7 @@ interface AboutView : BaseView { fun openLicenses() + fun openCreators() + fun openPrivacyPolicy() } diff --git a/app/src/main/java/io/github/wulkanowy/ui/modules/about/creator/CreatorFragment.kt b/app/src/main/java/io/github/wulkanowy/ui/modules/about/creator/CreatorFragment.kt new file mode 100644 index 000000000..299657ba6 --- /dev/null +++ b/app/src/main/java/io/github/wulkanowy/ui/modules/about/creator/CreatorFragment.kt @@ -0,0 +1,76 @@ +package io.github.wulkanowy.ui.modules.about.creator + +import android.os.Bundle +import android.view.LayoutInflater +import android.view.View +import android.view.View.GONE +import android.view.View.VISIBLE +import android.view.ViewGroup +import eu.davidea.flexibleadapter.FlexibleAdapter +import eu.davidea.flexibleadapter.common.FlexibleItemDecoration +import eu.davidea.flexibleadapter.common.SmoothScrollLinearLayoutManager +import eu.davidea.flexibleadapter.items.AbstractFlexibleItem +import io.github.wulkanowy.R +import io.github.wulkanowy.ui.base.BaseFragment +import io.github.wulkanowy.ui.modules.main.MainView +import io.github.wulkanowy.utils.openInternetBrowser +import io.github.wulkanowy.utils.setOnItemClickListener +import kotlinx.android.synthetic.main.fragment_creator.* +import javax.inject.Inject + +class CreatorFragment : BaseFragment(), CreatorView, MainView.TitledView { + + @Inject + lateinit var presenter: CreatorPresenter + + @Inject + lateinit var creatorsAdapter: FlexibleAdapter> + + override val titleStringId get() = R.string.creators_title + + companion object { + fun newInstance() = CreatorFragment() + } + + override fun onCreateView(inflater: LayoutInflater, container: ViewGroup?, savedInstanceState: Bundle?): View? { + return inflater.inflate(R.layout.fragment_creator, container, false) + } + + override fun onActivityCreated(savedInstanceState: Bundle?) { + super.onActivityCreated(savedInstanceState) + presenter.onAttachView(this) + } + + override fun initView() { + with(creatorRecycler) { + layoutManager = SmoothScrollLinearLayoutManager(context) + adapter = creatorsAdapter + addItemDecoration(FlexibleItemDecoration(context) + .withDefaultDivider() + .withDrawDividerOnLastItem(false)) + } + creatorsAdapter.setOnItemClickListener(presenter::onItemSelected) + creatorSeeMore.setOnClickListener { presenter.onSeeMoreClick() } + } + + override fun updateData(data: List) { + creatorsAdapter.updateDataSet(data) + } + + override fun openUserGithubPage(username: String) { + context?.openInternetBrowser("https://github.com/${username}", ::showMessage) + } + + override fun openGithubContributorsPage() { + context?.openInternetBrowser("https://github.com/wulkanowy/wulkanowy/graphs/contributors", ::showMessage) + } + + override fun showProgress(show: Boolean) { + creatorProgress.visibility = if (show) VISIBLE else GONE + } + + override fun onDestroyView() { + presenter.onDetachView() + super.onDestroyView() + } +} diff --git a/app/src/main/java/io/github/wulkanowy/ui/modules/about/creator/CreatorItem.kt b/app/src/main/java/io/github/wulkanowy/ui/modules/about/creator/CreatorItem.kt new file mode 100644 index 000000000..909919bbc --- /dev/null +++ b/app/src/main/java/io/github/wulkanowy/ui/modules/about/creator/CreatorItem.kt @@ -0,0 +1,50 @@ +package io.github.wulkanowy.ui.modules.about.creator + +import android.view.View +import coil.api.load +import coil.transform.RoundedCornersTransformation +import eu.davidea.flexibleadapter.FlexibleAdapter +import eu.davidea.flexibleadapter.items.AbstractFlexibleItem +import eu.davidea.flexibleadapter.items.IFlexible +import eu.davidea.viewholders.FlexibleViewHolder +import io.github.wulkanowy.R +import io.github.wulkanowy.data.pojos.AppCreator +import kotlinx.android.extensions.LayoutContainer +import kotlinx.android.synthetic.main.item_creator.* + +class CreatorItem(val creator: AppCreator) : AbstractFlexibleItem() { + + override fun getLayoutRes() = R.layout.item_creator + + override fun createViewHolder(view: View, adapter: FlexibleAdapter>) = ViewHolder(view, adapter) + + override fun bindViewHolder(adapter: FlexibleAdapter>, holder: ViewHolder, position: Int, payloads: MutableList) { + with(holder) { + creatorItemName.text = creator.displayName + + creatorItemAvatar.load("https://github.com/${creator.githubUsername}.png") { + transformations(RoundedCornersTransformation(8f)) + crossfade(true) + } + } + } + + override fun equals(other: Any?): Boolean { + if (this === other) return true + if (javaClass != other?.javaClass) return false + + other as CreatorItem + + if (creator != other.creator) return false + + return true + } + + override fun hashCode() = creator.hashCode() + + class ViewHolder(view: View, adapter: FlexibleAdapter>) : FlexibleViewHolder(view, adapter), + LayoutContainer { + + override val containerView: View? get() = contentView + } +} diff --git a/app/src/main/java/io/github/wulkanowy/ui/modules/about/creator/CreatorPresenter.kt b/app/src/main/java/io/github/wulkanowy/ui/modules/about/creator/CreatorPresenter.kt new file mode 100644 index 000000000..bc8034ab5 --- /dev/null +++ b/app/src/main/java/io/github/wulkanowy/ui/modules/about/creator/CreatorPresenter.kt @@ -0,0 +1,43 @@ +package io.github.wulkanowy.ui.modules.about.creator + +import eu.davidea.flexibleadapter.items.AbstractFlexibleItem +import io.github.wulkanowy.data.pojos.AppCreator +import io.github.wulkanowy.data.repositories.appcreator.AppCreatorRepository +import io.github.wulkanowy.data.repositories.student.StudentRepository +import io.github.wulkanowy.ui.base.BasePresenter +import io.github.wulkanowy.ui.base.ErrorHandler +import io.github.wulkanowy.utils.SchedulersProvider +import io.reactivex.Single +import javax.inject.Inject + +class CreatorPresenter @Inject constructor( + schedulers: SchedulersProvider, + errorHandler: ErrorHandler, + studentRepository: StudentRepository, + private val appCreatorRepository: AppCreatorRepository +) : BasePresenter(errorHandler, studentRepository, schedulers) { + + override fun onAttachView(view: CreatorView) { + super.onAttachView(view) + view.initView() + loadData() + } + + fun onItemSelected(item: AbstractFlexibleItem<*>) { + if (item !is CreatorItem) return + view?.openUserGithubPage(item.creator.githubUsername) + } + + fun onSeeMoreClick() { + view?.openGithubContributorsPage() + } + + private fun loadData() { + disposable.add(appCreatorRepository.getAppCreators() + .map { it.map { creator -> CreatorItem(creator) } } + .subscribeOn(schedulers.backgroundThread) + .observeOn(schedulers.mainThread) + .doFinally { view?.showProgress(false) } + .subscribe({ view?.run { updateData(it) } }, { errorHandler.dispatch(it) })) + } +} diff --git a/app/src/main/java/io/github/wulkanowy/ui/modules/about/creator/CreatorView.kt b/app/src/main/java/io/github/wulkanowy/ui/modules/about/creator/CreatorView.kt new file mode 100644 index 000000000..2a6a43039 --- /dev/null +++ b/app/src/main/java/io/github/wulkanowy/ui/modules/about/creator/CreatorView.kt @@ -0,0 +1,16 @@ +package io.github.wulkanowy.ui.modules.about.creator + +import io.github.wulkanowy.ui.base.BaseView + +interface CreatorView : BaseView { + + fun initView() + + fun updateData(data: List) + + fun openUserGithubPage(username: String) + + fun openGithubContributorsPage() + + fun showProgress(show: Boolean) +} diff --git a/app/src/main/java/io/github/wulkanowy/ui/modules/main/MainModule.kt b/app/src/main/java/io/github/wulkanowy/ui/modules/main/MainModule.kt index bbaea51ce..41f4d5f2c 100644 --- a/app/src/main/java/io/github/wulkanowy/ui/modules/main/MainModule.kt +++ b/app/src/main/java/io/github/wulkanowy/ui/modules/main/MainModule.kt @@ -8,6 +8,7 @@ import dagger.android.ContributesAndroidInjector import io.github.wulkanowy.R import io.github.wulkanowy.di.scopes.PerFragment import io.github.wulkanowy.ui.modules.about.AboutFragment +import io.github.wulkanowy.ui.modules.about.creator.CreatorFragment import io.github.wulkanowy.ui.modules.about.license.LicenseFragment import io.github.wulkanowy.ui.modules.about.license.LicenseModule import io.github.wulkanowy.ui.modules.account.AccountDialog @@ -121,6 +122,10 @@ abstract class MainModule { @ContributesAndroidInjector(modules = [LicenseModule::class]) abstract fun bindLicenseFragment(): LicenseFragment + @PerFragment + @ContributesAndroidInjector() + abstract fun bindCreatorsFragment(): CreatorFragment + @PerFragment @ContributesAndroidInjector(modules = [SchoolAndTeachersModule::class]) abstract fun bindSchoolAndTeachersFragment(): SchoolAndTeachersFragment diff --git a/app/src/main/res/drawable/ic_about_creator.xml b/app/src/main/res/drawable/ic_about_creator.xml new file mode 100644 index 000000000..c3daf609d --- /dev/null +++ b/app/src/main/res/drawable/ic_about_creator.xml @@ -0,0 +1,9 @@ + + + diff --git a/app/src/main/res/layout/fragment_creator.xml b/app/src/main/res/layout/fragment_creator.xml new file mode 100644 index 000000000..a0f34cffe --- /dev/null +++ b/app/src/main/res/layout/fragment_creator.xml @@ -0,0 +1,37 @@ + + + + + + + + + + + + diff --git a/app/src/main/res/layout/item_creator.xml b/app/src/main/res/layout/item_creator.xml new file mode 100644 index 000000000..1a8d0285e --- /dev/null +++ b/app/src/main/res/layout/item_creator.xml @@ -0,0 +1,34 @@ + + + + + + + diff --git a/app/src/main/res/values-pl/strings.xml b/app/src/main/res/values-pl/strings.xml index a59146974..458f64b45 100644 --- a/app/src/main/res/values-pl/strings.xml +++ b/app/src/main/res/values-pl/strings.xml @@ -12,6 +12,7 @@ Ustawienia Więcej O aplikacji + Twórcy Licencje Wiadomości Nowa wiadomość @@ -269,6 +270,8 @@ Wersja aplikacji + Twórcy + Lista programistów Wulkanowego Zgłoś błąd Wyślij zgłoszenie o błędzie poprzez e-maila FAQ @@ -287,6 +290,11 @@ Licencja + + Awatar + Zobacz więcej na GitHub + + Treść Ponów diff --git a/app/src/main/res/values/strings.xml b/app/src/main/res/values/strings.xml index 3ad60ee2c..8bdc54105 100644 --- a/app/src/main/res/values/strings.xml +++ b/app/src/main/res/values/strings.xml @@ -12,6 +12,7 @@ Settings More About + Creators Licenses Messages New message @@ -250,6 +251,8 @@ App version + Creators + List of Wulkanowy developers Report a bug Send a bug report via e-mail FAQ @@ -268,6 +271,11 @@ License + + Avatar + See more on GitHub + + Content Retry From 7142e05561185377490964d5adf0706dc85d60b3 Mon Sep 17 00:00:00 2001 From: "dependabot-preview[bot]" <27856297+dependabot-preview[bot]@users.noreply.github.com> Date: Fri, 24 Jan 2020 08:58:31 +0000 Subject: [PATCH 11/18] Bump work_manager from 2.3.0-rc01 to 2.3.0 (#660) --- app/build.gradle | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/app/build.gradle b/app/build.gradle index e17731d40..5ae33f714 100644 --- a/app/build.gradle +++ b/app/build.gradle @@ -110,7 +110,7 @@ play { } ext { - work_manager = "2.3.0-rc01" + work_manager = "2.3.0" room = "2.2.3" dagger = "2.25.4" chucker = "2.0.4" From 1dbe47039188abf68752780fbf086520bce73dae Mon Sep 17 00:00:00 2001 From: "dependabot-preview[bot]" <27856297+dependabot-preview[bot]@users.noreply.github.com> Date: Fri, 24 Jan 2020 08:59:20 +0000 Subject: [PATCH 12/18] Bump activity-ktx from 1.1.0-rc03 to 1.1.0 (#661) --- app/build.gradle | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/app/build.gradle b/app/build.gradle index 5ae33f714..3c573ac3c 100644 --- a/app/build.gradle +++ b/app/build.gradle @@ -126,7 +126,7 @@ dependencies { implementation "org.jetbrains.kotlin:kotlin-stdlib-jdk8:$kotlin_version" implementation "androidx.core:core-ktx:1.2.0-rc01" - implementation "androidx.activity:activity-ktx:1.1.0-rc03" + implementation "androidx.activity:activity-ktx:1.1.0" implementation "androidx.appcompat:appcompat:1.1.0" implementation "androidx.appcompat:appcompat-resources:1.1.0" implementation "androidx.fragment:fragment-ktx:1.2.0-rc05" From 0c5d45717cfd20aed61ce56c0486133600909778 Mon Sep 17 00:00:00 2001 From: "dependabot-preview[bot]" <27856297+dependabot-preview[bot]@users.noreply.github.com> Date: Fri, 24 Jan 2020 09:18:54 +0000 Subject: [PATCH 13/18] Bump fragment-ktx from 1.2.0-rc05 to 1.2.0 (#662) --- app/build.gradle | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/app/build.gradle b/app/build.gradle index 3c573ac3c..819ed4f4c 100644 --- a/app/build.gradle +++ b/app/build.gradle @@ -129,7 +129,7 @@ dependencies { implementation "androidx.activity:activity-ktx:1.1.0" implementation "androidx.appcompat:appcompat:1.1.0" implementation "androidx.appcompat:appcompat-resources:1.1.0" - implementation "androidx.fragment:fragment-ktx:1.2.0-rc05" + implementation "androidx.fragment:fragment-ktx:1.2.0" implementation "androidx.annotation:annotation:1.1.0" implementation "androidx.multidex:multidex:2.0.1" From 19f495cba6422e3d845db85acc500545e17beced Mon Sep 17 00:00:00 2001 From: Kacper Ziubryniewicz Date: Sat, 25 Jan 2020 18:07:25 +0100 Subject: [PATCH 14/18] Add excusing for absence (#533) --- .../21.json | 1652 +++++++++++++++++ .../attendance/AttendanceLocalTest.kt | 6 +- .../timetable/TestTimetableEntityCreator.kt | 2 +- .../github/wulkanowy/data/db/AppDatabase.kt | 6 +- .../wulkanowy/data/db/entities/Attendance.kt | 11 +- .../data/db/migrations/Migration21.kt | 13 + .../attendance/AttendanceRemote.kt | 17 +- .../attendance/AttendanceRepository.kt | 4 + .../attendance/SentExcuseStatus.kt | 7 + .../modules/attendance/AttendanceAdapter.kt | 12 + .../modules/attendance/AttendanceFragment.kt | 80 +- .../ui/modules/attendance/AttendanceItem.kt | 48 +- .../ui/modules/attendance/AttendanceModule.kt | 12 + .../modules/attendance/AttendancePresenter.kt | 96 +- .../ui/modules/attendance/AttendanceView.kt | 16 + .../wulkanowy/ui/modules/main/MainActivity.kt | 6 + .../wulkanowy/ui/modules/main/MainModule.kt | 3 +- .../ui/modules/main/MainPresenter.kt | 1 + .../wulkanowy/ui/modules/main/MainView.kt | 4 + .../drawable-night/background_header_note.xml | 4 +- .../res/drawable/background_header_note.xml | 6 +- app/src/main/res/drawable/ic_all_done.xml | 10 + app/src/main/res/drawable/ic_all_done_all.xml | 10 + .../main/res/drawable/ic_excuse_denied.xml | 10 + .../main/res/drawable/ic_excuse_waiting.xml | 10 + app/src/main/res/layout/dialog_excuse.xml | 21 + app/src/main/res/layout/dialog_grade.xml | 21 +- .../main/res/layout/fragment_attendance.xml | 14 + .../main/res/layout/header_grade_details.xml | 11 +- app/src/main/res/layout/item_attendance.xml | 44 +- app/src/main/res/menu/context_menu_excuse.xml | 11 + app/src/main/res/values-pl/strings.xml | 5 + app/src/main/res/values/strings.xml | 5 + app/src/main/res/values/styles.xml | 1 + 34 files changed, 2132 insertions(+), 47 deletions(-) create mode 100644 app/schemas/io.github.wulkanowy.data.db.AppDatabase/21.json create mode 100644 app/src/main/java/io/github/wulkanowy/data/db/migrations/Migration21.kt create mode 100644 app/src/main/java/io/github/wulkanowy/data/repositories/attendance/SentExcuseStatus.kt create mode 100644 app/src/main/java/io/github/wulkanowy/ui/modules/attendance/AttendanceAdapter.kt create mode 100644 app/src/main/java/io/github/wulkanowy/ui/modules/attendance/AttendanceModule.kt create mode 100644 app/src/main/res/drawable/ic_all_done.xml create mode 100644 app/src/main/res/drawable/ic_all_done_all.xml create mode 100644 app/src/main/res/drawable/ic_excuse_denied.xml create mode 100644 app/src/main/res/drawable/ic_excuse_waiting.xml create mode 100644 app/src/main/res/layout/dialog_excuse.xml create mode 100644 app/src/main/res/menu/context_menu_excuse.xml diff --git a/app/schemas/io.github.wulkanowy.data.db.AppDatabase/21.json b/app/schemas/io.github.wulkanowy.data.db.AppDatabase/21.json new file mode 100644 index 000000000..dfad69f5d --- /dev/null +++ b/app/schemas/io.github.wulkanowy.data.db.AppDatabase/21.json @@ -0,0 +1,1652 @@ +{ + "formatVersion": 1, + "database": { + "version": 21, + "identityHash": "f905d8a3ff4718d30ae7413a5a717b1f", + "entities": [ + { + "tableName": "Students", + "createSql": "CREATE TABLE IF NOT EXISTS `${TABLE_NAME}` (`id` INTEGER PRIMARY KEY AUTOINCREMENT NOT NULL, `scrapper_base_url` TEXT NOT NULL, `mobile_base_url` TEXT NOT NULL, `login_type` TEXT NOT NULL, `login_mode` TEXT NOT NULL, `certificate_key` TEXT NOT NULL, `private_key` TEXT NOT NULL, `is_parent` INTEGER NOT NULL, `email` TEXT NOT NULL, `password` TEXT NOT NULL, `symbol` TEXT NOT NULL, `student_id` INTEGER NOT NULL, `user_login_id` INTEGER NOT NULL, `student_name` TEXT NOT NULL, `school_id` TEXT NOT NULL, `school_name` TEXT NOT NULL, `class_name` TEXT NOT NULL, `class_id` INTEGER NOT NULL, `is_current` INTEGER NOT NULL, `registration_date` INTEGER NOT NULL)", + "fields": [ + { + "fieldPath": "id", + "columnName": "id", + "affinity": "INTEGER", + "notNull": true + }, + { + "fieldPath": "scrapperBaseUrl", + "columnName": "scrapper_base_url", + "affinity": "TEXT", + "notNull": true + }, + { + "fieldPath": "mobileBaseUrl", + "columnName": "mobile_base_url", + "affinity": "TEXT", + "notNull": true + }, + { + "fieldPath": "loginType", + "columnName": "login_type", + "affinity": "TEXT", + "notNull": true + }, + { + "fieldPath": "loginMode", + "columnName": "login_mode", + "affinity": "TEXT", + "notNull": true + }, + { + "fieldPath": "certificateKey", + "columnName": "certificate_key", + "affinity": "TEXT", + "notNull": true + }, + { + "fieldPath": "privateKey", + "columnName": "private_key", + "affinity": "TEXT", + "notNull": true + }, + { + "fieldPath": "isParent", + "columnName": "is_parent", + "affinity": "INTEGER", + "notNull": true + }, + { + "fieldPath": "email", + "columnName": "email", + "affinity": "TEXT", + "notNull": true + }, + { + "fieldPath": "password", + "columnName": "password", + "affinity": "TEXT", + "notNull": true + }, + { + "fieldPath": "symbol", + "columnName": "symbol", + "affinity": "TEXT", + "notNull": true + }, + { + "fieldPath": "studentId", + "columnName": "student_id", + "affinity": "INTEGER", + "notNull": true + }, + { + "fieldPath": "userLoginId", + "columnName": "user_login_id", + "affinity": "INTEGER", + "notNull": true + }, + { + "fieldPath": "studentName", + "columnName": "student_name", + "affinity": "TEXT", + "notNull": true + }, + { + "fieldPath": "schoolSymbol", + "columnName": "school_id", + "affinity": "TEXT", + "notNull": true + }, + { + "fieldPath": "schoolName", + "columnName": "school_name", + "affinity": "TEXT", + "notNull": true + }, + { + "fieldPath": "className", + "columnName": "class_name", + "affinity": "TEXT", + "notNull": true + }, + { + "fieldPath": "classId", + "columnName": "class_id", + "affinity": "INTEGER", + "notNull": true + }, + { + "fieldPath": "isCurrent", + "columnName": "is_current", + "affinity": "INTEGER", + "notNull": true + }, + { + "fieldPath": "registrationDate", + "columnName": "registration_date", + "affinity": "INTEGER", + "notNull": true + } + ], + "primaryKey": { + "columnNames": [ + "id" + ], + "autoGenerate": true + }, + "indices": [ + { + "name": "index_Students_email_symbol_student_id_school_id_class_id", + "unique": true, + "columnNames": [ + "email", + "symbol", + "student_id", + "school_id", + "class_id" + ], + "createSql": "CREATE UNIQUE INDEX IF NOT EXISTS `index_Students_email_symbol_student_id_school_id_class_id` ON `${TABLE_NAME}` (`email`, `symbol`, `student_id`, `school_id`, `class_id`)" + } + ], + "foreignKeys": [] + }, + { + "tableName": "Semesters", + "createSql": "CREATE TABLE IF NOT EXISTS `${TABLE_NAME}` (`id` INTEGER PRIMARY KEY AUTOINCREMENT NOT NULL, `student_id` INTEGER NOT NULL, `diary_id` INTEGER NOT NULL, `diary_name` TEXT NOT NULL, `school_year` INTEGER NOT NULL, `semester_id` INTEGER NOT NULL, `semester_name` INTEGER NOT NULL, `is_current` INTEGER NOT NULL, `start` INTEGER NOT NULL, `end` INTEGER NOT NULL, `class_id` INTEGER NOT NULL, `unit_id` INTEGER NOT NULL)", + "fields": [ + { + "fieldPath": "id", + "columnName": "id", + "affinity": "INTEGER", + "notNull": true + }, + { + "fieldPath": "studentId", + "columnName": "student_id", + "affinity": "INTEGER", + "notNull": true + }, + { + "fieldPath": "diaryId", + "columnName": "diary_id", + "affinity": "INTEGER", + "notNull": true + }, + { + "fieldPath": "diaryName", + "columnName": "diary_name", + "affinity": "TEXT", + "notNull": true + }, + { + "fieldPath": "schoolYear", + "columnName": "school_year", + "affinity": "INTEGER", + "notNull": true + }, + { + "fieldPath": "semesterId", + "columnName": "semester_id", + "affinity": "INTEGER", + "notNull": true + }, + { + "fieldPath": "semesterName", + "columnName": "semester_name", + "affinity": "INTEGER", + "notNull": true + }, + { + "fieldPath": "isCurrent", + "columnName": "is_current", + "affinity": "INTEGER", + "notNull": true + }, + { + "fieldPath": "start", + "columnName": "start", + "affinity": "INTEGER", + "notNull": true + }, + { + "fieldPath": "end", + "columnName": "end", + "affinity": "INTEGER", + "notNull": true + }, + { + "fieldPath": "classId", + "columnName": "class_id", + "affinity": "INTEGER", + "notNull": true + }, + { + "fieldPath": "unitId", + "columnName": "unit_id", + "affinity": "INTEGER", + "notNull": true + } + ], + "primaryKey": { + "columnNames": [ + "id" + ], + "autoGenerate": true + }, + "indices": [ + { + "name": "index_Semesters_student_id_diary_id_semester_id", + "unique": true, + "columnNames": [ + "student_id", + "diary_id", + "semester_id" + ], + "createSql": "CREATE UNIQUE INDEX IF NOT EXISTS `index_Semesters_student_id_diary_id_semester_id` ON `${TABLE_NAME}` (`student_id`, `diary_id`, `semester_id`)" + } + ], + "foreignKeys": [] + }, + { + "tableName": "Exams", + "createSql": "CREATE TABLE IF NOT EXISTS `${TABLE_NAME}` (`id` INTEGER PRIMARY KEY AUTOINCREMENT NOT NULL, `student_id` INTEGER NOT NULL, `diary_id` INTEGER NOT NULL, `date` INTEGER NOT NULL, `entry_date` INTEGER NOT NULL, `subject` TEXT NOT NULL, `group` TEXT NOT NULL, `type` TEXT NOT NULL, `description` TEXT NOT NULL, `teacher` TEXT NOT NULL, `teacher_symbol` TEXT NOT NULL)", + "fields": [ + { + "fieldPath": "id", + "columnName": "id", + "affinity": "INTEGER", + "notNull": true + }, + { + "fieldPath": "studentId", + "columnName": "student_id", + "affinity": "INTEGER", + "notNull": true + }, + { + "fieldPath": "diaryId", + "columnName": "diary_id", + "affinity": "INTEGER", + "notNull": true + }, + { + "fieldPath": "date", + "columnName": "date", + "affinity": "INTEGER", + "notNull": true + }, + { + "fieldPath": "entryDate", + "columnName": "entry_date", + "affinity": "INTEGER", + "notNull": true + }, + { + "fieldPath": "subject", + "columnName": "subject", + "affinity": "TEXT", + "notNull": true + }, + { + "fieldPath": "group", + "columnName": "group", + "affinity": "TEXT", + "notNull": true + }, + { + "fieldPath": "type", + "columnName": "type", + "affinity": "TEXT", + "notNull": true + }, + { + "fieldPath": "description", + "columnName": "description", + "affinity": "TEXT", + "notNull": true + }, + { + "fieldPath": "teacher", + "columnName": "teacher", + "affinity": "TEXT", + "notNull": true + }, + { + "fieldPath": "teacherSymbol", + "columnName": "teacher_symbol", + "affinity": "TEXT", + "notNull": true + } + ], + "primaryKey": { + "columnNames": [ + "id" + ], + "autoGenerate": true + }, + "indices": [], + "foreignKeys": [] + }, + { + "tableName": "Timetable", + "createSql": "CREATE TABLE IF NOT EXISTS `${TABLE_NAME}` (`id` INTEGER PRIMARY KEY AUTOINCREMENT NOT NULL, `student_id` INTEGER NOT NULL, `diary_id` INTEGER NOT NULL, `number` INTEGER NOT NULL, `start` INTEGER NOT NULL, `end` INTEGER NOT NULL, `date` INTEGER NOT NULL, `subject` TEXT NOT NULL, `subjectOld` TEXT NOT NULL, `group` TEXT NOT NULL, `room` TEXT NOT NULL, `roomOld` TEXT NOT NULL, `teacher` TEXT NOT NULL, `teacherOld` TEXT NOT NULL, `info` TEXT NOT NULL, `student_plan` INTEGER NOT NULL, `changes` INTEGER NOT NULL, `canceled` INTEGER NOT NULL)", + "fields": [ + { + "fieldPath": "id", + "columnName": "id", + "affinity": "INTEGER", + "notNull": true + }, + { + "fieldPath": "studentId", + "columnName": "student_id", + "affinity": "INTEGER", + "notNull": true + }, + { + "fieldPath": "diaryId", + "columnName": "diary_id", + "affinity": "INTEGER", + "notNull": true + }, + { + "fieldPath": "number", + "columnName": "number", + "affinity": "INTEGER", + "notNull": true + }, + { + "fieldPath": "start", + "columnName": "start", + "affinity": "INTEGER", + "notNull": true + }, + { + "fieldPath": "end", + "columnName": "end", + "affinity": "INTEGER", + "notNull": true + }, + { + "fieldPath": "date", + "columnName": "date", + "affinity": "INTEGER", + "notNull": true + }, + { + "fieldPath": "subject", + "columnName": "subject", + "affinity": "TEXT", + "notNull": true + }, + { + "fieldPath": "subjectOld", + "columnName": "subjectOld", + "affinity": "TEXT", + "notNull": true + }, + { + "fieldPath": "group", + "columnName": "group", + "affinity": "TEXT", + "notNull": true + }, + { + "fieldPath": "room", + "columnName": "room", + "affinity": "TEXT", + "notNull": true + }, + { + "fieldPath": "roomOld", + "columnName": "roomOld", + "affinity": "TEXT", + "notNull": true + }, + { + "fieldPath": "teacher", + "columnName": "teacher", + "affinity": "TEXT", + "notNull": true + }, + { + "fieldPath": "teacherOld", + "columnName": "teacherOld", + "affinity": "TEXT", + "notNull": true + }, + { + "fieldPath": "info", + "columnName": "info", + "affinity": "TEXT", + "notNull": true + }, + { + "fieldPath": "studentPlan", + "columnName": "student_plan", + "affinity": "INTEGER", + "notNull": true + }, + { + "fieldPath": "changes", + "columnName": "changes", + "affinity": "INTEGER", + "notNull": true + }, + { + "fieldPath": "canceled", + "columnName": "canceled", + "affinity": "INTEGER", + "notNull": true + } + ], + "primaryKey": { + "columnNames": [ + "id" + ], + "autoGenerate": true + }, + "indices": [], + "foreignKeys": [] + }, + { + "tableName": "Attendance", + "createSql": "CREATE TABLE IF NOT EXISTS `${TABLE_NAME}` (`id` INTEGER PRIMARY KEY AUTOINCREMENT NOT NULL, `student_id` INTEGER NOT NULL, `diary_id` INTEGER NOT NULL, `time_id` INTEGER NOT NULL, `date` INTEGER NOT NULL, `number` INTEGER NOT NULL, `subject` TEXT NOT NULL, `name` TEXT NOT NULL, `presence` INTEGER NOT NULL, `absence` INTEGER NOT NULL, `exemption` INTEGER NOT NULL, `lateness` INTEGER NOT NULL, `excused` INTEGER NOT NULL, `deleted` INTEGER NOT NULL, `excusable` INTEGER NOT NULL, `excuse_status` TEXT)", + "fields": [ + { + "fieldPath": "id", + "columnName": "id", + "affinity": "INTEGER", + "notNull": true + }, + { + "fieldPath": "studentId", + "columnName": "student_id", + "affinity": "INTEGER", + "notNull": true + }, + { + "fieldPath": "diaryId", + "columnName": "diary_id", + "affinity": "INTEGER", + "notNull": true + }, + { + "fieldPath": "timeId", + "columnName": "time_id", + "affinity": "INTEGER", + "notNull": true + }, + { + "fieldPath": "date", + "columnName": "date", + "affinity": "INTEGER", + "notNull": true + }, + { + "fieldPath": "number", + "columnName": "number", + "affinity": "INTEGER", + "notNull": true + }, + { + "fieldPath": "subject", + "columnName": "subject", + "affinity": "TEXT", + "notNull": true + }, + { + "fieldPath": "name", + "columnName": "name", + "affinity": "TEXT", + "notNull": true + }, + { + "fieldPath": "presence", + "columnName": "presence", + "affinity": "INTEGER", + "notNull": true + }, + { + "fieldPath": "absence", + "columnName": "absence", + "affinity": "INTEGER", + "notNull": true + }, + { + "fieldPath": "exemption", + "columnName": "exemption", + "affinity": "INTEGER", + "notNull": true + }, + { + "fieldPath": "lateness", + "columnName": "lateness", + "affinity": "INTEGER", + "notNull": true + }, + { + "fieldPath": "excused", + "columnName": "excused", + "affinity": "INTEGER", + "notNull": true + }, + { + "fieldPath": "deleted", + "columnName": "deleted", + "affinity": "INTEGER", + "notNull": true + }, + { + "fieldPath": "excusable", + "columnName": "excusable", + "affinity": "INTEGER", + "notNull": true + }, + { + "fieldPath": "excuseStatus", + "columnName": "excuse_status", + "affinity": "TEXT", + "notNull": false + } + ], + "primaryKey": { + "columnNames": [ + "id" + ], + "autoGenerate": true + }, + "indices": [], + "foreignKeys": [] + }, + { + "tableName": "AttendanceSummary", + "createSql": "CREATE TABLE IF NOT EXISTS `${TABLE_NAME}` (`id` INTEGER PRIMARY KEY AUTOINCREMENT NOT NULL, `student_id` INTEGER NOT NULL, `diary_id` INTEGER NOT NULL, `subject_id` INTEGER NOT NULL, `month` INTEGER NOT NULL, `presence` INTEGER NOT NULL, `absence` INTEGER NOT NULL, `absence_excused` INTEGER NOT NULL, `absence_for_school_reasons` INTEGER NOT NULL, `lateness` INTEGER NOT NULL, `lateness_excused` INTEGER NOT NULL, `exemption` INTEGER NOT NULL)", + "fields": [ + { + "fieldPath": "id", + "columnName": "id", + "affinity": "INTEGER", + "notNull": true + }, + { + "fieldPath": "studentId", + "columnName": "student_id", + "affinity": "INTEGER", + "notNull": true + }, + { + "fieldPath": "diaryId", + "columnName": "diary_id", + "affinity": "INTEGER", + "notNull": true + }, + { + "fieldPath": "subjectId", + "columnName": "subject_id", + "affinity": "INTEGER", + "notNull": true + }, + { + "fieldPath": "month", + "columnName": "month", + "affinity": "INTEGER", + "notNull": true + }, + { + "fieldPath": "presence", + "columnName": "presence", + "affinity": "INTEGER", + "notNull": true + }, + { + "fieldPath": "absence", + "columnName": "absence", + "affinity": "INTEGER", + "notNull": true + }, + { + "fieldPath": "absenceExcused", + "columnName": "absence_excused", + "affinity": "INTEGER", + "notNull": true + }, + { + "fieldPath": "absenceForSchoolReasons", + "columnName": "absence_for_school_reasons", + "affinity": "INTEGER", + "notNull": true + }, + { + "fieldPath": "lateness", + "columnName": "lateness", + "affinity": "INTEGER", + "notNull": true + }, + { + "fieldPath": "latenessExcused", + "columnName": "lateness_excused", + "affinity": "INTEGER", + "notNull": true + }, + { + "fieldPath": "exemption", + "columnName": "exemption", + "affinity": "INTEGER", + "notNull": true + } + ], + "primaryKey": { + "columnNames": [ + "id" + ], + "autoGenerate": true + }, + "indices": [], + "foreignKeys": [] + }, + { + "tableName": "Grades", + "createSql": "CREATE TABLE IF NOT EXISTS `${TABLE_NAME}` (`id` INTEGER PRIMARY KEY AUTOINCREMENT NOT NULL, `is_read` INTEGER NOT NULL, `is_notified` INTEGER NOT NULL, `semester_id` INTEGER NOT NULL, `student_id` INTEGER NOT NULL, `subject` TEXT NOT NULL, `entry` TEXT NOT NULL, `value` REAL NOT NULL, `modifier` REAL NOT NULL, `comment` TEXT NOT NULL, `color` TEXT NOT NULL, `grade_symbol` TEXT NOT NULL, `description` TEXT NOT NULL, `weight` TEXT NOT NULL, `weightValue` REAL NOT NULL, `date` INTEGER NOT NULL, `teacher` TEXT NOT NULL)", + "fields": [ + { + "fieldPath": "id", + "columnName": "id", + "affinity": "INTEGER", + "notNull": true + }, + { + "fieldPath": "isRead", + "columnName": "is_read", + "affinity": "INTEGER", + "notNull": true + }, + { + "fieldPath": "isNotified", + "columnName": "is_notified", + "affinity": "INTEGER", + "notNull": true + }, + { + "fieldPath": "semesterId", + "columnName": "semester_id", + "affinity": "INTEGER", + "notNull": true + }, + { + "fieldPath": "studentId", + "columnName": "student_id", + "affinity": "INTEGER", + "notNull": true + }, + { + "fieldPath": "subject", + "columnName": "subject", + "affinity": "TEXT", + "notNull": true + }, + { + "fieldPath": "entry", + "columnName": "entry", + "affinity": "TEXT", + "notNull": true + }, + { + "fieldPath": "value", + "columnName": "value", + "affinity": "REAL", + "notNull": true + }, + { + "fieldPath": "modifier", + "columnName": "modifier", + "affinity": "REAL", + "notNull": true + }, + { + "fieldPath": "comment", + "columnName": "comment", + "affinity": "TEXT", + "notNull": true + }, + { + "fieldPath": "color", + "columnName": "color", + "affinity": "TEXT", + "notNull": true + }, + { + "fieldPath": "gradeSymbol", + "columnName": "grade_symbol", + "affinity": "TEXT", + "notNull": true + }, + { + "fieldPath": "description", + "columnName": "description", + "affinity": "TEXT", + "notNull": true + }, + { + "fieldPath": "weight", + "columnName": "weight", + "affinity": "TEXT", + "notNull": true + }, + { + "fieldPath": "weightValue", + "columnName": "weightValue", + "affinity": "REAL", + "notNull": true + }, + { + "fieldPath": "date", + "columnName": "date", + "affinity": "INTEGER", + "notNull": true + }, + { + "fieldPath": "teacher", + "columnName": "teacher", + "affinity": "TEXT", + "notNull": true + } + ], + "primaryKey": { + "columnNames": [ + "id" + ], + "autoGenerate": true + }, + "indices": [], + "foreignKeys": [] + }, + { + "tableName": "GradesSummary", + "createSql": "CREATE TABLE IF NOT EXISTS `${TABLE_NAME}` (`id` INTEGER PRIMARY KEY AUTOINCREMENT NOT NULL, `semester_id` INTEGER NOT NULL, `student_id` INTEGER NOT NULL, `position` INTEGER NOT NULL, `subject` TEXT NOT NULL, `predicted_grade` TEXT NOT NULL, `final_grade` TEXT NOT NULL, `proposed_points` TEXT NOT NULL, `final_points` TEXT NOT NULL, `points_sum` TEXT NOT NULL, `average` REAL NOT NULL)", + "fields": [ + { + "fieldPath": "id", + "columnName": "id", + "affinity": "INTEGER", + "notNull": true + }, + { + "fieldPath": "semesterId", + "columnName": "semester_id", + "affinity": "INTEGER", + "notNull": true + }, + { + "fieldPath": "studentId", + "columnName": "student_id", + "affinity": "INTEGER", + "notNull": true + }, + { + "fieldPath": "position", + "columnName": "position", + "affinity": "INTEGER", + "notNull": true + }, + { + "fieldPath": "subject", + "columnName": "subject", + "affinity": "TEXT", + "notNull": true + }, + { + "fieldPath": "predictedGrade", + "columnName": "predicted_grade", + "affinity": "TEXT", + "notNull": true + }, + { + "fieldPath": "finalGrade", + "columnName": "final_grade", + "affinity": "TEXT", + "notNull": true + }, + { + "fieldPath": "proposedPoints", + "columnName": "proposed_points", + "affinity": "TEXT", + "notNull": true + }, + { + "fieldPath": "finalPoints", + "columnName": "final_points", + "affinity": "TEXT", + "notNull": true + }, + { + "fieldPath": "pointsSum", + "columnName": "points_sum", + "affinity": "TEXT", + "notNull": true + }, + { + "fieldPath": "average", + "columnName": "average", + "affinity": "REAL", + "notNull": true + } + ], + "primaryKey": { + "columnNames": [ + "id" + ], + "autoGenerate": true + }, + "indices": [], + "foreignKeys": [] + }, + { + "tableName": "GradesStatistics", + "createSql": "CREATE TABLE IF NOT EXISTS `${TABLE_NAME}` (`id` INTEGER PRIMARY KEY AUTOINCREMENT NOT NULL, `student_id` INTEGER NOT NULL, `semester_id` INTEGER NOT NULL, `subject` TEXT NOT NULL, `grade` INTEGER NOT NULL, `amount` INTEGER NOT NULL, `is_semester` INTEGER NOT NULL)", + "fields": [ + { + "fieldPath": "id", + "columnName": "id", + "affinity": "INTEGER", + "notNull": true + }, + { + "fieldPath": "studentId", + "columnName": "student_id", + "affinity": "INTEGER", + "notNull": true + }, + { + "fieldPath": "semesterId", + "columnName": "semester_id", + "affinity": "INTEGER", + "notNull": true + }, + { + "fieldPath": "subject", + "columnName": "subject", + "affinity": "TEXT", + "notNull": true + }, + { + "fieldPath": "grade", + "columnName": "grade", + "affinity": "INTEGER", + "notNull": true + }, + { + "fieldPath": "amount", + "columnName": "amount", + "affinity": "INTEGER", + "notNull": true + }, + { + "fieldPath": "semester", + "columnName": "is_semester", + "affinity": "INTEGER", + "notNull": true + } + ], + "primaryKey": { + "columnNames": [ + "id" + ], + "autoGenerate": true + }, + "indices": [], + "foreignKeys": [] + }, + { + "tableName": "GradesPointsStatistics", + "createSql": "CREATE TABLE IF NOT EXISTS `${TABLE_NAME}` (`id` INTEGER PRIMARY KEY AUTOINCREMENT NOT NULL, `student_id` INTEGER NOT NULL, `semester_id` INTEGER NOT NULL, `subject` TEXT NOT NULL, `others` REAL NOT NULL, `student` REAL NOT NULL)", + "fields": [ + { + "fieldPath": "id", + "columnName": "id", + "affinity": "INTEGER", + "notNull": true + }, + { + "fieldPath": "studentId", + "columnName": "student_id", + "affinity": "INTEGER", + "notNull": true + }, + { + "fieldPath": "semesterId", + "columnName": "semester_id", + "affinity": "INTEGER", + "notNull": true + }, + { + "fieldPath": "subject", + "columnName": "subject", + "affinity": "TEXT", + "notNull": true + }, + { + "fieldPath": "others", + "columnName": "others", + "affinity": "REAL", + "notNull": true + }, + { + "fieldPath": "student", + "columnName": "student", + "affinity": "REAL", + "notNull": true + } + ], + "primaryKey": { + "columnNames": [ + "id" + ], + "autoGenerate": true + }, + "indices": [], + "foreignKeys": [] + }, + { + "tableName": "Messages", + "createSql": "CREATE TABLE IF NOT EXISTS `${TABLE_NAME}` (`id` INTEGER PRIMARY KEY AUTOINCREMENT NOT NULL, `is_notified` INTEGER NOT NULL, `student_id` INTEGER NOT NULL, `real_id` INTEGER NOT NULL, `message_id` INTEGER NOT NULL, `sender_name` TEXT NOT NULL, `sender_id` INTEGER NOT NULL, `recipient_name` TEXT NOT NULL, `subject` TEXT NOT NULL, `content` TEXT NOT NULL, `date` INTEGER NOT NULL, `folder_id` INTEGER NOT NULL, `unread` INTEGER NOT NULL, `unread_by` INTEGER NOT NULL, `read_by` INTEGER NOT NULL, `removed` INTEGER NOT NULL)", + "fields": [ + { + "fieldPath": "id", + "columnName": "id", + "affinity": "INTEGER", + "notNull": true + }, + { + "fieldPath": "isNotified", + "columnName": "is_notified", + "affinity": "INTEGER", + "notNull": true + }, + { + "fieldPath": "studentId", + "columnName": "student_id", + "affinity": "INTEGER", + "notNull": true + }, + { + "fieldPath": "realId", + "columnName": "real_id", + "affinity": "INTEGER", + "notNull": true + }, + { + "fieldPath": "messageId", + "columnName": "message_id", + "affinity": "INTEGER", + "notNull": true + }, + { + "fieldPath": "sender", + "columnName": "sender_name", + "affinity": "TEXT", + "notNull": true + }, + { + "fieldPath": "senderId", + "columnName": "sender_id", + "affinity": "INTEGER", + "notNull": true + }, + { + "fieldPath": "recipient", + "columnName": "recipient_name", + "affinity": "TEXT", + "notNull": true + }, + { + "fieldPath": "subject", + "columnName": "subject", + "affinity": "TEXT", + "notNull": true + }, + { + "fieldPath": "content", + "columnName": "content", + "affinity": "TEXT", + "notNull": true + }, + { + "fieldPath": "date", + "columnName": "date", + "affinity": "INTEGER", + "notNull": true + }, + { + "fieldPath": "folderId", + "columnName": "folder_id", + "affinity": "INTEGER", + "notNull": true + }, + { + "fieldPath": "unread", + "columnName": "unread", + "affinity": "INTEGER", + "notNull": true + }, + { + "fieldPath": "unreadBy", + "columnName": "unread_by", + "affinity": "INTEGER", + "notNull": true + }, + { + "fieldPath": "readBy", + "columnName": "read_by", + "affinity": "INTEGER", + "notNull": true + }, + { + "fieldPath": "removed", + "columnName": "removed", + "affinity": "INTEGER", + "notNull": true + } + ], + "primaryKey": { + "columnNames": [ + "id" + ], + "autoGenerate": true + }, + "indices": [], + "foreignKeys": [] + }, + { + "tableName": "Notes", + "createSql": "CREATE TABLE IF NOT EXISTS `${TABLE_NAME}` (`id` INTEGER PRIMARY KEY AUTOINCREMENT NOT NULL, `is_read` INTEGER NOT NULL, `is_notified` INTEGER NOT NULL, `student_id` INTEGER NOT NULL, `date` INTEGER NOT NULL, `teacher` TEXT NOT NULL, `category` TEXT NOT NULL, `content` TEXT NOT NULL)", + "fields": [ + { + "fieldPath": "id", + "columnName": "id", + "affinity": "INTEGER", + "notNull": true + }, + { + "fieldPath": "isRead", + "columnName": "is_read", + "affinity": "INTEGER", + "notNull": true + }, + { + "fieldPath": "isNotified", + "columnName": "is_notified", + "affinity": "INTEGER", + "notNull": true + }, + { + "fieldPath": "studentId", + "columnName": "student_id", + "affinity": "INTEGER", + "notNull": true + }, + { + "fieldPath": "date", + "columnName": "date", + "affinity": "INTEGER", + "notNull": true + }, + { + "fieldPath": "teacher", + "columnName": "teacher", + "affinity": "TEXT", + "notNull": true + }, + { + "fieldPath": "category", + "columnName": "category", + "affinity": "TEXT", + "notNull": true + }, + { + "fieldPath": "content", + "columnName": "content", + "affinity": "TEXT", + "notNull": true + } + ], + "primaryKey": { + "columnNames": [ + "id" + ], + "autoGenerate": true + }, + "indices": [], + "foreignKeys": [] + }, + { + "tableName": "Homework", + "createSql": "CREATE TABLE IF NOT EXISTS `${TABLE_NAME}` (`id` INTEGER PRIMARY KEY AUTOINCREMENT NOT NULL, `semester_id` INTEGER NOT NULL, `student_id` INTEGER NOT NULL, `date` INTEGER NOT NULL, `entry_date` INTEGER NOT NULL, `subject` TEXT NOT NULL, `content` TEXT NOT NULL, `teacher` TEXT NOT NULL, `teacher_symbol` TEXT NOT NULL)", + "fields": [ + { + "fieldPath": "id", + "columnName": "id", + "affinity": "INTEGER", + "notNull": true + }, + { + "fieldPath": "semesterId", + "columnName": "semester_id", + "affinity": "INTEGER", + "notNull": true + }, + { + "fieldPath": "studentId", + "columnName": "student_id", + "affinity": "INTEGER", + "notNull": true + }, + { + "fieldPath": "date", + "columnName": "date", + "affinity": "INTEGER", + "notNull": true + }, + { + "fieldPath": "entryDate", + "columnName": "entry_date", + "affinity": "INTEGER", + "notNull": true + }, + { + "fieldPath": "subject", + "columnName": "subject", + "affinity": "TEXT", + "notNull": true + }, + { + "fieldPath": "content", + "columnName": "content", + "affinity": "TEXT", + "notNull": true + }, + { + "fieldPath": "teacher", + "columnName": "teacher", + "affinity": "TEXT", + "notNull": true + }, + { + "fieldPath": "teacherSymbol", + "columnName": "teacher_symbol", + "affinity": "TEXT", + "notNull": true + } + ], + "primaryKey": { + "columnNames": [ + "id" + ], + "autoGenerate": true + }, + "indices": [], + "foreignKeys": [] + }, + { + "tableName": "Subjects", + "createSql": "CREATE TABLE IF NOT EXISTS `${TABLE_NAME}` (`id` INTEGER PRIMARY KEY AUTOINCREMENT NOT NULL, `student_id` INTEGER NOT NULL, `diary_id` INTEGER NOT NULL, `real_id` INTEGER NOT NULL, `name` TEXT NOT NULL)", + "fields": [ + { + "fieldPath": "id", + "columnName": "id", + "affinity": "INTEGER", + "notNull": true + }, + { + "fieldPath": "studentId", + "columnName": "student_id", + "affinity": "INTEGER", + "notNull": true + }, + { + "fieldPath": "diaryId", + "columnName": "diary_id", + "affinity": "INTEGER", + "notNull": true + }, + { + "fieldPath": "realId", + "columnName": "real_id", + "affinity": "INTEGER", + "notNull": true + }, + { + "fieldPath": "name", + "columnName": "name", + "affinity": "TEXT", + "notNull": true + } + ], + "primaryKey": { + "columnNames": [ + "id" + ], + "autoGenerate": true + }, + "indices": [], + "foreignKeys": [] + }, + { + "tableName": "LuckyNumbers", + "createSql": "CREATE TABLE IF NOT EXISTS `${TABLE_NAME}` (`id` INTEGER PRIMARY KEY AUTOINCREMENT NOT NULL, `is_notified` INTEGER NOT NULL, `student_id` INTEGER NOT NULL, `date` INTEGER NOT NULL, `lucky_number` INTEGER NOT NULL)", + "fields": [ + { + "fieldPath": "id", + "columnName": "id", + "affinity": "INTEGER", + "notNull": true + }, + { + "fieldPath": "isNotified", + "columnName": "is_notified", + "affinity": "INTEGER", + "notNull": true + }, + { + "fieldPath": "studentId", + "columnName": "student_id", + "affinity": "INTEGER", + "notNull": true + }, + { + "fieldPath": "date", + "columnName": "date", + "affinity": "INTEGER", + "notNull": true + }, + { + "fieldPath": "luckyNumber", + "columnName": "lucky_number", + "affinity": "INTEGER", + "notNull": true + } + ], + "primaryKey": { + "columnNames": [ + "id" + ], + "autoGenerate": true + }, + "indices": [], + "foreignKeys": [] + }, + { + "tableName": "CompletedLesson", + "createSql": "CREATE TABLE IF NOT EXISTS `${TABLE_NAME}` (`id` INTEGER PRIMARY KEY AUTOINCREMENT NOT NULL, `student_id` INTEGER NOT NULL, `diary_id` INTEGER NOT NULL, `date` INTEGER NOT NULL, `number` INTEGER NOT NULL, `subject` TEXT NOT NULL, `topic` TEXT NOT NULL, `teacher` TEXT NOT NULL, `teacher_symbol` TEXT NOT NULL, `substitution` TEXT NOT NULL, `absence` TEXT NOT NULL, `resources` TEXT NOT NULL)", + "fields": [ + { + "fieldPath": "id", + "columnName": "id", + "affinity": "INTEGER", + "notNull": true + }, + { + "fieldPath": "studentId", + "columnName": "student_id", + "affinity": "INTEGER", + "notNull": true + }, + { + "fieldPath": "diaryId", + "columnName": "diary_id", + "affinity": "INTEGER", + "notNull": true + }, + { + "fieldPath": "date", + "columnName": "date", + "affinity": "INTEGER", + "notNull": true + }, + { + "fieldPath": "number", + "columnName": "number", + "affinity": "INTEGER", + "notNull": true + }, + { + "fieldPath": "subject", + "columnName": "subject", + "affinity": "TEXT", + "notNull": true + }, + { + "fieldPath": "topic", + "columnName": "topic", + "affinity": "TEXT", + "notNull": true + }, + { + "fieldPath": "teacher", + "columnName": "teacher", + "affinity": "TEXT", + "notNull": true + }, + { + "fieldPath": "teacherSymbol", + "columnName": "teacher_symbol", + "affinity": "TEXT", + "notNull": true + }, + { + "fieldPath": "substitution", + "columnName": "substitution", + "affinity": "TEXT", + "notNull": true + }, + { + "fieldPath": "absence", + "columnName": "absence", + "affinity": "TEXT", + "notNull": true + }, + { + "fieldPath": "resources", + "columnName": "resources", + "affinity": "TEXT", + "notNull": true + } + ], + "primaryKey": { + "columnNames": [ + "id" + ], + "autoGenerate": true + }, + "indices": [], + "foreignKeys": [] + }, + { + "tableName": "ReportingUnits", + "createSql": "CREATE TABLE IF NOT EXISTS `${TABLE_NAME}` (`id` INTEGER PRIMARY KEY AUTOINCREMENT NOT NULL, `student_id` INTEGER NOT NULL, `real_id` INTEGER NOT NULL, `short` TEXT NOT NULL, `sender_id` INTEGER NOT NULL, `sender_name` TEXT NOT NULL, `roles` TEXT NOT NULL)", + "fields": [ + { + "fieldPath": "id", + "columnName": "id", + "affinity": "INTEGER", + "notNull": true + }, + { + "fieldPath": "studentId", + "columnName": "student_id", + "affinity": "INTEGER", + "notNull": true + }, + { + "fieldPath": "realId", + "columnName": "real_id", + "affinity": "INTEGER", + "notNull": true + }, + { + "fieldPath": "shortName", + "columnName": "short", + "affinity": "TEXT", + "notNull": true + }, + { + "fieldPath": "senderId", + "columnName": "sender_id", + "affinity": "INTEGER", + "notNull": true + }, + { + "fieldPath": "senderName", + "columnName": "sender_name", + "affinity": "TEXT", + "notNull": true + }, + { + "fieldPath": "roles", + "columnName": "roles", + "affinity": "TEXT", + "notNull": true + } + ], + "primaryKey": { + "columnNames": [ + "id" + ], + "autoGenerate": true + }, + "indices": [], + "foreignKeys": [] + }, + { + "tableName": "Recipients", + "createSql": "CREATE TABLE IF NOT EXISTS `${TABLE_NAME}` (`id` INTEGER PRIMARY KEY AUTOINCREMENT NOT NULL, `student_id` INTEGER NOT NULL, `real_id` TEXT NOT NULL, `name` TEXT NOT NULL, `real_name` TEXT NOT NULL, `login_id` INTEGER NOT NULL, `unit_id` INTEGER NOT NULL, `role` INTEGER NOT NULL, `hash` TEXT NOT NULL)", + "fields": [ + { + "fieldPath": "id", + "columnName": "id", + "affinity": "INTEGER", + "notNull": true + }, + { + "fieldPath": "studentId", + "columnName": "student_id", + "affinity": "INTEGER", + "notNull": true + }, + { + "fieldPath": "realId", + "columnName": "real_id", + "affinity": "TEXT", + "notNull": true + }, + { + "fieldPath": "name", + "columnName": "name", + "affinity": "TEXT", + "notNull": true + }, + { + "fieldPath": "realName", + "columnName": "real_name", + "affinity": "TEXT", + "notNull": true + }, + { + "fieldPath": "loginId", + "columnName": "login_id", + "affinity": "INTEGER", + "notNull": true + }, + { + "fieldPath": "unitId", + "columnName": "unit_id", + "affinity": "INTEGER", + "notNull": true + }, + { + "fieldPath": "role", + "columnName": "role", + "affinity": "INTEGER", + "notNull": true + }, + { + "fieldPath": "hash", + "columnName": "hash", + "affinity": "TEXT", + "notNull": true + } + ], + "primaryKey": { + "columnNames": [ + "id" + ], + "autoGenerate": true + }, + "indices": [], + "foreignKeys": [] + }, + { + "tableName": "MobileDevices", + "createSql": "CREATE TABLE IF NOT EXISTS `${TABLE_NAME}` (`id` INTEGER PRIMARY KEY AUTOINCREMENT NOT NULL, `student_id` INTEGER NOT NULL, `device_id` INTEGER NOT NULL, `name` TEXT NOT NULL, `date` INTEGER NOT NULL)", + "fields": [ + { + "fieldPath": "id", + "columnName": "id", + "affinity": "INTEGER", + "notNull": true + }, + { + "fieldPath": "studentId", + "columnName": "student_id", + "affinity": "INTEGER", + "notNull": true + }, + { + "fieldPath": "deviceId", + "columnName": "device_id", + "affinity": "INTEGER", + "notNull": true + }, + { + "fieldPath": "name", + "columnName": "name", + "affinity": "TEXT", + "notNull": true + }, + { + "fieldPath": "date", + "columnName": "date", + "affinity": "INTEGER", + "notNull": true + } + ], + "primaryKey": { + "columnNames": [ + "id" + ], + "autoGenerate": true + }, + "indices": [], + "foreignKeys": [] + }, + { + "tableName": "Teachers", + "createSql": "CREATE TABLE IF NOT EXISTS `${TABLE_NAME}` (`id` INTEGER PRIMARY KEY AUTOINCREMENT NOT NULL, `student_id` INTEGER NOT NULL, `class_id` INTEGER NOT NULL, `subject` TEXT NOT NULL, `name` TEXT NOT NULL, `short_name` TEXT NOT NULL)", + "fields": [ + { + "fieldPath": "id", + "columnName": "id", + "affinity": "INTEGER", + "notNull": true + }, + { + "fieldPath": "studentId", + "columnName": "student_id", + "affinity": "INTEGER", + "notNull": true + }, + { + "fieldPath": "classId", + "columnName": "class_id", + "affinity": "INTEGER", + "notNull": true + }, + { + "fieldPath": "subject", + "columnName": "subject", + "affinity": "TEXT", + "notNull": true + }, + { + "fieldPath": "name", + "columnName": "name", + "affinity": "TEXT", + "notNull": true + }, + { + "fieldPath": "shortName", + "columnName": "short_name", + "affinity": "TEXT", + "notNull": true + } + ], + "primaryKey": { + "columnNames": [ + "id" + ], + "autoGenerate": true + }, + "indices": [], + "foreignKeys": [] + }, + { + "tableName": "School", + "createSql": "CREATE TABLE IF NOT EXISTS `${TABLE_NAME}` (`id` INTEGER PRIMARY KEY AUTOINCREMENT NOT NULL, `student_id` INTEGER NOT NULL, `class_id` INTEGER NOT NULL, `name` TEXT NOT NULL, `address` TEXT NOT NULL, `contact` TEXT NOT NULL, `headmaster` TEXT NOT NULL, `pedagogue` TEXT NOT NULL)", + "fields": [ + { + "fieldPath": "id", + "columnName": "id", + "affinity": "INTEGER", + "notNull": true + }, + { + "fieldPath": "studentId", + "columnName": "student_id", + "affinity": "INTEGER", + "notNull": true + }, + { + "fieldPath": "classId", + "columnName": "class_id", + "affinity": "INTEGER", + "notNull": true + }, + { + "fieldPath": "name", + "columnName": "name", + "affinity": "TEXT", + "notNull": true + }, + { + "fieldPath": "address", + "columnName": "address", + "affinity": "TEXT", + "notNull": true + }, + { + "fieldPath": "contact", + "columnName": "contact", + "affinity": "TEXT", + "notNull": true + }, + { + "fieldPath": "headmaster", + "columnName": "headmaster", + "affinity": "TEXT", + "notNull": true + }, + { + "fieldPath": "pedagogue", + "columnName": "pedagogue", + "affinity": "TEXT", + "notNull": true + } + ], + "primaryKey": { + "columnNames": [ + "id" + ], + "autoGenerate": true + }, + "indices": [], + "foreignKeys": [] + } + ], + "views": [], + "setupQueries": [ + "CREATE TABLE IF NOT EXISTS room_master_table (id INTEGER PRIMARY KEY,identity_hash TEXT)", + "INSERT OR REPLACE INTO room_master_table (id,identity_hash) VALUES(42, 'f905d8a3ff4718d30ae7413a5a717b1f')" + ] + } +} \ No newline at end of file diff --git a/app/src/androidTest/java/io/github/wulkanowy/data/repositories/attendance/AttendanceLocalTest.kt b/app/src/androidTest/java/io/github/wulkanowy/data/repositories/attendance/AttendanceLocalTest.kt index 69502e742..5fd5b193a 100644 --- a/app/src/androidTest/java/io/github/wulkanowy/data/repositories/attendance/AttendanceLocalTest.kt +++ b/app/src/androidTest/java/io/github/wulkanowy/data/repositories/attendance/AttendanceLocalTest.kt @@ -35,9 +35,9 @@ class AttendanceLocalTest { @Test fun saveAndReadTest() { attendanceLocal.saveAttendance(listOf( - Attendance(1, 2, LocalDate.of(2018, 9, 10), 0, "", "", false, false, false, false, false, false), - Attendance(1, 2, LocalDate.of(2018, 9, 14), 0, "", "", false, false, false, false, false, false), - Attendance(1, 2, LocalDate.of(2018, 9, 17), 0, "", "", false, false, false, false, false, false) + Attendance(1, 2, 3, LocalDate.of(2018, 9, 10), 0, "", "", false, false, false, false, false, false, false, SentExcuseStatus.ACCEPTED.name), + Attendance(1, 2, 3, LocalDate.of(2018, 9, 14), 0, "", "", false, false, false, false, false, false, false, SentExcuseStatus.WAITING.name), + Attendance(1, 2, 3, LocalDate.of(2018, 9, 17), 0, "", "", false, false, false, false, false, false, false, SentExcuseStatus.ACCEPTED.name) )) val attendance = attendanceLocal diff --git a/app/src/androidTest/java/io/github/wulkanowy/data/repositories/timetable/TestTimetableEntityCreator.kt b/app/src/androidTest/java/io/github/wulkanowy/data/repositories/timetable/TestTimetableEntityCreator.kt index c1e23c578..77c061821 100644 --- a/app/src/androidTest/java/io/github/wulkanowy/data/repositories/timetable/TestTimetableEntityCreator.kt +++ b/app/src/androidTest/java/io/github/wulkanowy/data/repositories/timetable/TestTimetableEntityCreator.kt @@ -2,8 +2,8 @@ package io.github.wulkanowy.data.repositories.timetable import org.threeten.bp.LocalDateTime import org.threeten.bp.LocalDateTime.now -import io.github.wulkanowy.sdk.pojo.Timetable as TimetableRemote import io.github.wulkanowy.data.db.entities.Timetable as TimetableLocal +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( diff --git a/app/src/main/java/io/github/wulkanowy/data/db/AppDatabase.kt b/app/src/main/java/io/github/wulkanowy/data/db/AppDatabase.kt index fe4285052..b5293a53c 100644 --- a/app/src/main/java/io/github/wulkanowy/data/db/AppDatabase.kt +++ b/app/src/main/java/io/github/wulkanowy/data/db/AppDatabase.kt @@ -61,6 +61,7 @@ import io.github.wulkanowy.data.db.migrations.Migration18 import io.github.wulkanowy.data.db.migrations.Migration19 import io.github.wulkanowy.data.db.migrations.Migration2 import io.github.wulkanowy.data.db.migrations.Migration20 +import io.github.wulkanowy.data.db.migrations.Migration21 import io.github.wulkanowy.data.db.migrations.Migration3 import io.github.wulkanowy.data.db.migrations.Migration4 import io.github.wulkanowy.data.db.migrations.Migration5 @@ -102,7 +103,7 @@ import javax.inject.Singleton abstract class AppDatabase : RoomDatabase() { companion object { - const val VERSION_SCHEMA = 20 + const val VERSION_SCHEMA = 21 fun getMigrations(sharedPrefProvider: SharedPrefProvider): Array { return arrayOf( @@ -124,7 +125,8 @@ abstract class AppDatabase : RoomDatabase() { Migration17(), Migration18(), Migration19(sharedPrefProvider), - Migration20() + Migration20(), + Migration21() ) } diff --git a/app/src/main/java/io/github/wulkanowy/data/db/entities/Attendance.kt b/app/src/main/java/io/github/wulkanowy/data/db/entities/Attendance.kt index 3c58971ae..aa8da8db7 100644 --- a/app/src/main/java/io/github/wulkanowy/data/db/entities/Attendance.kt +++ b/app/src/main/java/io/github/wulkanowy/data/db/entities/Attendance.kt @@ -15,6 +15,9 @@ data class Attendance( @ColumnInfo(name = "diary_id") val diaryId: Int, + @ColumnInfo(name = "time_id") + val timeId: Int, + val date: LocalDate, val number: Int, @@ -33,7 +36,13 @@ data class Attendance( val excused: Boolean, - val deleted: Boolean + val deleted: Boolean, + + val excusable: Boolean, + + @ColumnInfo(name = "excuse_status") + val excuseStatus: String? + ) : Serializable { @PrimaryKey(autoGenerate = true) diff --git a/app/src/main/java/io/github/wulkanowy/data/db/migrations/Migration21.kt b/app/src/main/java/io/github/wulkanowy/data/db/migrations/Migration21.kt new file mode 100644 index 000000000..9d95f2ba4 --- /dev/null +++ b/app/src/main/java/io/github/wulkanowy/data/db/migrations/Migration21.kt @@ -0,0 +1,13 @@ +package io.github.wulkanowy.data.db.migrations + +import androidx.room.migration.Migration +import androidx.sqlite.db.SupportSQLiteDatabase + +class Migration21 : Migration(20, 21) { + + override fun migrate(database: SupportSQLiteDatabase) { + database.execSQL("ALTER TABLE Attendance ADD COLUMN excusable INTEGER NOT NULL DEFAULT 0") + database.execSQL("ALTER TABLE Attendance ADD COLUMN time_id INTEGER NOT NULL DEFAULT 0") + database.execSQL("ALTER TABLE Attendance ADD COLUMN excuse_status TEXT DEFAULT NULL") + } +} diff --git a/app/src/main/java/io/github/wulkanowy/data/repositories/attendance/AttendanceRemote.kt b/app/src/main/java/io/github/wulkanowy/data/repositories/attendance/AttendanceRemote.kt index cd7702c10..1828c2bdf 100644 --- a/app/src/main/java/io/github/wulkanowy/data/repositories/attendance/AttendanceRemote.kt +++ b/app/src/main/java/io/github/wulkanowy/data/repositories/attendance/AttendanceRemote.kt @@ -3,8 +3,11 @@ package io.github.wulkanowy.data.repositories.attendance import io.github.wulkanowy.data.db.entities.Attendance import io.github.wulkanowy.data.db.entities.Semester import io.github.wulkanowy.sdk.Sdk +import io.github.wulkanowy.sdk.pojo.Absent import io.reactivex.Single import org.threeten.bp.LocalDate +import org.threeten.bp.LocalDateTime +import org.threeten.bp.LocalTime import javax.inject.Inject import javax.inject.Singleton @@ -19,6 +22,7 @@ class AttendanceRemote @Inject constructor(private val sdk: Sdk) { studentId = semester.studentId, diaryId = semester.diaryId, date = it.date, + timeId = it.timeId, number = it.number, subject = it.subject, name = it.name, @@ -27,9 +31,20 @@ class AttendanceRemote @Inject constructor(private val sdk: Sdk) { exemption = it.exemption, lateness = it.lateness, excused = it.excused, - deleted = it.deleted + deleted = it.deleted, + excusable = it.excusable, + excuseStatus = it.excuseStatus?.name ) } } } + + fun excuseAbsence(semester: Semester, absenceList: List, reason: String?): Single { + return sdk.switchDiary(semester.diaryId, semester.schoolYear).excuseForAbsence(absenceList.map { attendance -> + Absent( + date = LocalDateTime.of(attendance.date, LocalTime.of(0, 0)), + timeId = attendance.timeId + ) + }, reason) + } } diff --git a/app/src/main/java/io/github/wulkanowy/data/repositories/attendance/AttendanceRepository.kt b/app/src/main/java/io/github/wulkanowy/data/repositories/attendance/AttendanceRepository.kt index 85102b3c5..fc3830c2e 100644 --- a/app/src/main/java/io/github/wulkanowy/data/repositories/attendance/AttendanceRepository.kt +++ b/app/src/main/java/io/github/wulkanowy/data/repositories/attendance/AttendanceRepository.kt @@ -41,4 +41,8 @@ class AttendanceRepository @Inject constructor( }).map { list -> list.filter { it.date in startDate..endDate } } } } + + fun excuseForAbsence(semester: Semester, attendanceList: List, reason: String? = null): Single { + return remote.excuseAbsence(semester, attendanceList, reason) + } } diff --git a/app/src/main/java/io/github/wulkanowy/data/repositories/attendance/SentExcuseStatus.kt b/app/src/main/java/io/github/wulkanowy/data/repositories/attendance/SentExcuseStatus.kt new file mode 100644 index 000000000..50d6b8ed5 --- /dev/null +++ b/app/src/main/java/io/github/wulkanowy/data/repositories/attendance/SentExcuseStatus.kt @@ -0,0 +1,7 @@ +package io.github.wulkanowy.data.repositories.attendance + +enum class SentExcuseStatus(val id: Int = 0) { + WAITING, + ACCEPTED, + DENIED +} diff --git a/app/src/main/java/io/github/wulkanowy/ui/modules/attendance/AttendanceAdapter.kt b/app/src/main/java/io/github/wulkanowy/ui/modules/attendance/AttendanceAdapter.kt new file mode 100644 index 000000000..75f998404 --- /dev/null +++ b/app/src/main/java/io/github/wulkanowy/ui/modules/attendance/AttendanceAdapter.kt @@ -0,0 +1,12 @@ +package io.github.wulkanowy.ui.modules.attendance + +import eu.davidea.flexibleadapter.FlexibleAdapter +import eu.davidea.flexibleadapter.items.IFlexible +import io.github.wulkanowy.data.db.entities.Attendance + +class AttendanceAdapter> : FlexibleAdapter(null, null, true) { + + var excuseActionMode: Boolean = false + + var onExcuseCheckboxSelect: (attendanceItem: Attendance, checked: Boolean) -> Unit = { _, _ -> } +} diff --git a/app/src/main/java/io/github/wulkanowy/ui/modules/attendance/AttendanceFragment.kt b/app/src/main/java/io/github/wulkanowy/ui/modules/attendance/AttendanceFragment.kt index bc7c1cacd..9969b1c78 100644 --- a/app/src/main/java/io/github/wulkanowy/ui/modules/attendance/AttendanceFragment.kt +++ b/app/src/main/java/io/github/wulkanowy/ui/modules/attendance/AttendanceFragment.kt @@ -1,5 +1,6 @@ package io.github.wulkanowy.ui.modules.attendance +import android.content.DialogInterface.BUTTON_POSITIVE import android.os.Bundle import android.view.LayoutInflater import android.view.Menu @@ -10,8 +11,9 @@ import android.view.View.GONE import android.view.View.INVISIBLE import android.view.View.VISIBLE import android.view.ViewGroup +import androidx.appcompat.app.AlertDialog +import androidx.appcompat.view.ActionMode import com.wdullaer.materialdatetimepicker.date.DatePickerDialog -import eu.davidea.flexibleadapter.FlexibleAdapter import eu.davidea.flexibleadapter.common.FlexibleItemDecoration import eu.davidea.flexibleadapter.common.SmoothScrollLinearLayoutManager import eu.davidea.flexibleadapter.items.AbstractFlexibleItem @@ -24,6 +26,7 @@ import io.github.wulkanowy.ui.modules.main.MainView import io.github.wulkanowy.utils.SchooldaysRangeLimiter import io.github.wulkanowy.utils.dpToPx import io.github.wulkanowy.utils.setOnItemClickListener +import kotlinx.android.synthetic.main.dialog_excuse.* import kotlinx.android.synthetic.main.fragment_attendance.* import org.threeten.bp.LocalDate import javax.inject.Inject @@ -35,7 +38,13 @@ class AttendanceFragment : BaseFragment(), AttendanceView, MainView.MainChildVie lateinit var presenter: AttendancePresenter @Inject - lateinit var attendanceAdapter: FlexibleAdapter> + lateinit var attendanceAdapter: AttendanceAdapter> + + override val excuseSuccessString: String + get() = getString(R.string.attendance_excuse_success) + + override val excuseNoSelectionString: String + get() = getString(R.string.attendance_excuse_no_selection) companion object { private const val SAVED_DATE_KEY = "CURRENT_DATE" @@ -49,6 +58,34 @@ class AttendanceFragment : BaseFragment(), AttendanceView, MainView.MainChildVie override val currentStackSize get() = (activity as? MainActivity)?.currentStackSize + override val excuseActionMode: Boolean get() = attendanceAdapter.excuseActionMode + + private var actionMode: ActionMode? = null + private val actionModeCallback = object : ActionMode.Callback { + override fun onCreateActionMode(mode: ActionMode, menu: Menu): Boolean { + val inflater = mode.menuInflater + inflater.inflate(R.menu.context_menu_excuse, menu) + return true + } + + override fun onPrepareActionMode(mode: ActionMode, menu: Menu): Boolean { + mode.title = getString(R.string.attendance_excuse_title) + return presenter.onPrepareActionMode() + } + + override fun onDestroyActionMode(mode: ActionMode) { + presenter.onDestroyActionMode() + actionMode = null + } + + override fun onActionItemClicked(mode: ActionMode, menu: MenuItem): Boolean { + return when (menu.itemId) { + R.id.excuseMenuSubmit -> presenter.onExcuseSubmitButtonClick() + else -> false + } + } + } + override fun onCreate(savedInstanceState: Bundle?) { super.onCreate(savedInstanceState) setHasOptionsMenu(true) @@ -66,6 +103,7 @@ class AttendanceFragment : BaseFragment(), AttendanceView, MainView.MainChildVie override fun initView() { attendanceAdapter.setOnItemClickListener(presenter::onAttendanceItemSelected) + attendanceAdapter.onExcuseCheckboxSelect = presenter::onExcuseCheckboxSelect with(attendanceRecycler) { layoutManager = SmoothScrollLinearLayoutManager(context) @@ -83,6 +121,8 @@ class AttendanceFragment : BaseFragment(), AttendanceView, MainView.MainChildVie attendanceNavDate.setOnClickListener { presenter.onPickDate() } attendanceNextButton.setOnClickListener { presenter.onNextDay() } + attendanceExcuseButton.setOnClickListener { presenter.onExcuseButtonClick() } + attendanceNavContainer.setElevationCompat(requireContext().dpToPx(8f)) } @@ -115,6 +155,10 @@ class AttendanceFragment : BaseFragment(), AttendanceView, MainView.MainChildVie if (::presenter.isInitialized) presenter.onViewReselected() } + override fun onFragmentChanged() { + if (::presenter.isInitialized) presenter.onMainViewChanged() + } + override fun popView() { (activity as? MainActivity)?.popView() } @@ -155,6 +199,10 @@ class AttendanceFragment : BaseFragment(), AttendanceView, MainView.MainChildVie attendanceNextButton.visibility = if (show) VISIBLE else INVISIBLE } + override fun showExcuseButton(show: Boolean) { + attendanceExcuseButton.visibility = if (show) VISIBLE else GONE + } + override fun showAttendanceDialog(lesson: Attendance) { (activity as? MainActivity)?.showDialogFragment(AttendanceDialog.newInstance(lesson)) } @@ -174,10 +222,38 @@ class AttendanceFragment : BaseFragment(), AttendanceView, MainView.MainChildVie } } + override fun showExcuseDialog() { + AlertDialog.Builder(requireContext()) + .setTitle(R.string.attendance_excuse_title) + .setView(R.layout.dialog_excuse) + .setNegativeButton(android.R.string.cancel) { _, _ -> } + .create() + .apply { + setButton(BUTTON_POSITIVE, getString(R.string.attendance_excuse_dialog_submit)) { _, _ -> + presenter.onExcuseDialogSubmit(excuseReason.text?.toString().orEmpty()) + } + }.show() + } + override fun openSummaryView() { (activity as? MainActivity)?.pushView(AttendanceSummaryFragment.newInstance()) } + override fun startActionMode() { + actionMode = (activity as MainActivity?)?.startSupportActionMode(actionModeCallback) + } + + override fun showExcuseCheckboxes(show: Boolean) { + attendanceAdapter.apply { + excuseActionMode = show + notifyDataSetChanged() + } + } + + override fun finishActionMode() { + actionMode?.finish() + } + override fun onSaveInstanceState(outState: Bundle) { super.onSaveInstanceState(outState) outState.putLong(SAVED_DATE_KEY, presenter.currentDate.toEpochDay()) diff --git a/app/src/main/java/io/github/wulkanowy/ui/modules/attendance/AttendanceItem.kt b/app/src/main/java/io/github/wulkanowy/ui/modules/attendance/AttendanceItem.kt index 16a140cbf..7355aec2e 100644 --- a/app/src/main/java/io/github/wulkanowy/ui/modules/attendance/AttendanceItem.kt +++ b/app/src/main/java/io/github/wulkanowy/ui/modules/attendance/AttendanceItem.kt @@ -1,18 +1,22 @@ package io.github.wulkanowy.ui.modules.attendance import android.view.View +import android.view.View.GONE import android.view.View.INVISIBLE import android.view.View.VISIBLE +import androidx.core.view.isVisible import eu.davidea.flexibleadapter.FlexibleAdapter import eu.davidea.flexibleadapter.items.AbstractFlexibleItem import eu.davidea.flexibleadapter.items.IFlexible import eu.davidea.viewholders.FlexibleViewHolder import io.github.wulkanowy.R import io.github.wulkanowy.data.db.entities.Attendance +import io.github.wulkanowy.data.repositories.attendance.SentExcuseStatus import kotlinx.android.extensions.LayoutContainer import kotlinx.android.synthetic.main.item_attendance.* -class AttendanceItem(val attendance: Attendance) : AbstractFlexibleItem() { +class AttendanceItem(val attendance: Attendance) : + AbstractFlexibleItem() { override fun getLayoutRes() = R.layout.item_attendance @@ -26,6 +30,34 @@ class AttendanceItem(val attendance: Attendance) : AbstractFlexibleItem + (adapter as AttendanceAdapter).onExcuseCheckboxSelect(attendance, checked) + } + + when (if (attendance.excuseStatus != null) SentExcuseStatus.valueOf(attendance.excuseStatus) else null) { + SentExcuseStatus.WAITING -> { + attendanceItemExcuseInfo.setImageResource(R.drawable.ic_excuse_waiting) + attendanceItemExcuseInfo.visibility = VISIBLE + attendanceItemAlert.visibility = INVISIBLE + } + SentExcuseStatus.DENIED -> { + attendanceItemExcuseInfo.setImageResource(R.drawable.ic_excuse_denied) + attendanceItemExcuseInfo.visibility = VISIBLE + } + else -> { + if (attendance.excusable && (adapter as AttendanceAdapter).excuseActionMode) { + attendanceItemNumber.visibility = GONE + attendanceItemExcuseCheckbox.visibility = VISIBLE + } else { + attendanceItemNumber.visibility = VISIBLE + attendanceItemExcuseCheckbox.visibility = GONE + } + } + } } } @@ -46,8 +78,20 @@ class AttendanceItem(val attendance: Attendance) : AbstractFlexibleItem) : FlexibleViewHolder(view, adapter), LayoutContainer { + class ViewHolder(view: View, val adapter: FlexibleAdapter<*>) : + FlexibleViewHolder(view, adapter), + LayoutContainer { + override val containerView: View get() = contentView + + override fun onClick(view: View?) { + super.onClick(view) + attendanceItemExcuseCheckbox.apply { + if ((adapter as AttendanceAdapter).excuseActionMode && isVisible) { + isChecked = !isChecked + } + } + } } } diff --git a/app/src/main/java/io/github/wulkanowy/ui/modules/attendance/AttendanceModule.kt b/app/src/main/java/io/github/wulkanowy/ui/modules/attendance/AttendanceModule.kt new file mode 100644 index 000000000..eb35fea1b --- /dev/null +++ b/app/src/main/java/io/github/wulkanowy/ui/modules/attendance/AttendanceModule.kt @@ -0,0 +1,12 @@ +package io.github.wulkanowy.ui.modules.attendance + +import dagger.Module +import dagger.Provides +import eu.davidea.flexibleadapter.items.AbstractFlexibleItem + +@Module +class AttendanceModule { + + @Provides + fun provideAttendanceFlexibleAdapter() = AttendanceAdapter>() +} diff --git a/app/src/main/java/io/github/wulkanowy/ui/modules/attendance/AttendancePresenter.kt b/app/src/main/java/io/github/wulkanowy/ui/modules/attendance/AttendancePresenter.kt index 1490ee6e3..679d5367d 100644 --- a/app/src/main/java/io/github/wulkanowy/ui/modules/attendance/AttendancePresenter.kt +++ b/app/src/main/java/io/github/wulkanowy/ui/modules/attendance/AttendancePresenter.kt @@ -2,6 +2,7 @@ package io.github.wulkanowy.ui.modules.attendance import android.annotation.SuppressLint import eu.davidea.flexibleadapter.items.AbstractFlexibleItem +import io.github.wulkanowy.data.db.entities.Attendance import io.github.wulkanowy.data.repositories.attendance.AttendanceRepository import io.github.wulkanowy.data.repositories.preferences.PreferencesRepository import io.github.wulkanowy.data.repositories.semester.SemesterRepository @@ -40,6 +41,8 @@ class AttendancePresenter @Inject constructor( private lateinit var lastError: Throwable + private val attendanceToExcuseList = mutableListOf() + fun onAttachView(view: AttendanceView, date: Long?) { super.onAttachView(view) view.initView() @@ -51,11 +54,15 @@ class AttendancePresenter @Inject constructor( } fun onPreviousDay() { + view?.finishActionMode() + attendanceToExcuseList.clear() loadData(currentDate.previousSchoolDay) reloadView() } fun onNextDay() { + view?.finishActionMode() + attendanceToExcuseList.clear() loadData(currentDate.nextSchoolDay) reloadView() } @@ -100,10 +107,59 @@ class AttendancePresenter @Inject constructor( } } + fun onMainViewChanged() { + view?.finishActionMode() + } + fun onAttendanceItemSelected(item: AbstractFlexibleItem<*>?) { - if (item is AttendanceItem) { - Timber.i("Select attendance item ${item.attendance.id}") - view?.showAttendanceDialog(item.attendance) + view?.apply { + if (item is AttendanceItem && !excuseActionMode) { + Timber.i("Select attendance item ${item.attendance.id}") + showAttendanceDialog(item.attendance) + } + } + } + + fun onExcuseButtonClick() { + view?.startActionMode() + } + + fun onExcuseCheckboxSelect(attendanceItem: Attendance, checked: Boolean) { + if (checked) attendanceToExcuseList.add(attendanceItem) + else attendanceToExcuseList.remove(attendanceItem) + } + + fun onExcuseSubmitButtonClick(): Boolean { + view?.apply { + return if (attendanceToExcuseList.isNotEmpty()) { + showExcuseDialog() + true + } else { + showMessage(excuseNoSelectionString) + false + } + } + return false + } + + fun onExcuseDialogSubmit(reason: String) { + view?.finishActionMode() + excuseAbsence(if (reason != "") reason else null, attendanceToExcuseList.toList()) + } + + fun onPrepareActionMode(): Boolean { + view?.apply { + showExcuseCheckboxes(true) + showExcuseButton(false) + } + attendanceToExcuseList.clear() + return true + } + + fun onDestroyActionMode() { + view?.apply { + showExcuseCheckboxes(false) + showExcuseButton(true) } } @@ -157,6 +213,7 @@ class AttendancePresenter @Inject constructor( showEmpty(it.isEmpty()) showErrorView(false) showContent(it.isNotEmpty()) + showExcuseButton(it.any { item -> item.attendance.excusable }) } analytics.logEvent("load_attendance", "items" to it.size, "force_refresh" to forceRefresh) }) { @@ -167,6 +224,39 @@ class AttendancePresenter @Inject constructor( } } + private fun excuseAbsence(reason: String?, toExcuseList: List) { + Timber.i("Excusing absence started") + disposable.apply { + add(studentRepository.getCurrentStudent() + .delay(200, MILLISECONDS) + .flatMap { semesterRepository.getCurrentSemester(it) } + .flatMap { attendanceRepository.excuseForAbsence(it, toExcuseList, reason) } + .subscribeOn(schedulers.backgroundThread) + .observeOn(schedulers.mainThread) + .doOnSubscribe { + view?.apply { + showProgress(true) + showContent(false) + showExcuseButton(false) + } + } + .subscribe({ + Timber.i("Excusing for absence result: Success") + analytics.logEvent("excuse_absence", "items" to attendanceToExcuseList.size) + attendanceToExcuseList.clear() + view?.apply { + showExcuseButton(false) + showMessage(excuseSuccessString) + } + loadData(currentDate, true) + }) { + Timber.i("Excusing for absence result: An exception occurred") + view?.showProgress(false) + errorHandler.dispatch(it) + }) + } + } + private fun showErrorViewOnError(message: String, error: Throwable) { view?.run { if (isViewEmpty) { diff --git a/app/src/main/java/io/github/wulkanowy/ui/modules/attendance/AttendanceView.kt b/app/src/main/java/io/github/wulkanowy/ui/modules/attendance/AttendanceView.kt index a6d0d4ba9..03e95053f 100644 --- a/app/src/main/java/io/github/wulkanowy/ui/modules/attendance/AttendanceView.kt +++ b/app/src/main/java/io/github/wulkanowy/ui/modules/attendance/AttendanceView.kt @@ -10,6 +10,12 @@ interface AttendanceView : BaseView { val currentStackSize: Int? + val excuseSuccessString: String + + val excuseNoSelectionString: String + + val excuseActionMode: Boolean + fun initView() fun updateData(data: List) @@ -38,11 +44,21 @@ interface AttendanceView : BaseView { fun showNextButton(show: Boolean) + fun showExcuseButton(show: Boolean) + fun showAttendanceDialog(lesson: Attendance) fun showDatePickerDialog(currentDate: LocalDate) + fun showExcuseDialog() + fun openSummaryView() + fun startActionMode() + + fun showExcuseCheckboxes(show: Boolean) + + fun finishActionMode() + fun popView() } diff --git a/app/src/main/java/io/github/wulkanowy/ui/modules/main/MainActivity.kt b/app/src/main/java/io/github/wulkanowy/ui/modules/main/MainActivity.kt index 991c1d106..ae4be9530 100644 --- a/app/src/main/java/io/github/wulkanowy/ui/modules/main/MainActivity.kt +++ b/app/src/main/java/io/github/wulkanowy/ui/modules/main/MainActivity.kt @@ -36,6 +36,7 @@ import io.github.wulkanowy.utils.getThemeAttrColor import io.github.wulkanowy.utils.safelyPopFragments import io.github.wulkanowy.utils.setOnViewChangeListener import kotlinx.android.synthetic.main.activity_main.* +import timber.log.Timber import javax.inject.Inject class MainActivity : BaseActivity(), MainView { @@ -167,6 +168,11 @@ class MainActivity : BaseActivity(), MainView { (navController.currentStack?.getOrNull(0) as? MainView.MainChildView)?.onFragmentReselected() } + override fun notifyMenuViewChanged() { + Timber.d("Menu view changed") + (navController.currentStack?.getOrNull(0) as? MainView.MainChildView)?.onFragmentChanged() + } + fun showDialogFragment(dialog: DialogFragment) { navController.showDialogFragment(dialog) } diff --git a/app/src/main/java/io/github/wulkanowy/ui/modules/main/MainModule.kt b/app/src/main/java/io/github/wulkanowy/ui/modules/main/MainModule.kt index 41f4d5f2c..50e5896fe 100644 --- a/app/src/main/java/io/github/wulkanowy/ui/modules/main/MainModule.kt +++ b/app/src/main/java/io/github/wulkanowy/ui/modules/main/MainModule.kt @@ -13,6 +13,7 @@ import io.github.wulkanowy.ui.modules.about.license.LicenseFragment import io.github.wulkanowy.ui.modules.about.license.LicenseModule import io.github.wulkanowy.ui.modules.account.AccountDialog import io.github.wulkanowy.ui.modules.attendance.AttendanceFragment +import io.github.wulkanowy.ui.modules.attendance.AttendanceModule import io.github.wulkanowy.ui.modules.attendance.summary.AttendanceSummaryFragment import io.github.wulkanowy.ui.modules.exam.ExamFragment import io.github.wulkanowy.ui.modules.grade.GradeFragment @@ -51,7 +52,7 @@ abstract class MainModule { } @PerFragment - @ContributesAndroidInjector + @ContributesAndroidInjector(modules = [AttendanceModule::class]) abstract fun bindAttendanceFragment(): AttendanceFragment @PerFragment diff --git a/app/src/main/java/io/github/wulkanowy/ui/modules/main/MainPresenter.kt b/app/src/main/java/io/github/wulkanowy/ui/modules/main/MainPresenter.kt index 1c0fd39f3..8eccbc67e 100644 --- a/app/src/main/java/io/github/wulkanowy/ui/modules/main/MainPresenter.kt +++ b/app/src/main/java/io/github/wulkanowy/ui/modules/main/MainPresenter.kt @@ -75,6 +75,7 @@ class MainPresenter @Inject constructor( notifyMenuViewReselected() false } else { + notifyMenuViewChanged() switchMenuView(index) true } diff --git a/app/src/main/java/io/github/wulkanowy/ui/modules/main/MainView.kt b/app/src/main/java/io/github/wulkanowy/ui/modules/main/MainView.kt index 033b6a1f6..0d8b14169 100644 --- a/app/src/main/java/io/github/wulkanowy/ui/modules/main/MainView.kt +++ b/app/src/main/java/io/github/wulkanowy/ui/modules/main/MainView.kt @@ -26,6 +26,8 @@ interface MainView : BaseView { fun notifyMenuViewReselected() + fun notifyMenuViewChanged() + fun setViewTitle(title: String) fun popView(depth: Int = 1) @@ -33,6 +35,8 @@ interface MainView : BaseView { interface MainChildView { fun onFragmentReselected() + + fun onFragmentChanged() {} } interface TitledView { diff --git a/app/src/main/res/drawable-night/background_header_note.xml b/app/src/main/res/drawable-night/background_header_note.xml index 2983b32c6..6b594e7c6 100644 --- a/app/src/main/res/drawable-night/background_header_note.xml +++ b/app/src/main/res/drawable-night/background_header_note.xml @@ -1,5 +1,5 @@ - - + + diff --git a/app/src/main/res/drawable/background_header_note.xml b/app/src/main/res/drawable/background_header_note.xml index 8e92e3abf..c21e55c6b 100644 --- a/app/src/main/res/drawable/background_header_note.xml +++ b/app/src/main/res/drawable/background_header_note.xml @@ -1,5 +1,5 @@ - - - \ No newline at end of file + + + diff --git a/app/src/main/res/drawable/ic_all_done.xml b/app/src/main/res/drawable/ic_all_done.xml new file mode 100644 index 000000000..bb657f6ec --- /dev/null +++ b/app/src/main/res/drawable/ic_all_done.xml @@ -0,0 +1,10 @@ + + + diff --git a/app/src/main/res/drawable/ic_all_done_all.xml b/app/src/main/res/drawable/ic_all_done_all.xml new file mode 100644 index 000000000..e27672efa --- /dev/null +++ b/app/src/main/res/drawable/ic_all_done_all.xml @@ -0,0 +1,10 @@ + + + diff --git a/app/src/main/res/drawable/ic_excuse_denied.xml b/app/src/main/res/drawable/ic_excuse_denied.xml new file mode 100644 index 000000000..218cfbdc4 --- /dev/null +++ b/app/src/main/res/drawable/ic_excuse_denied.xml @@ -0,0 +1,10 @@ + + + diff --git a/app/src/main/res/drawable/ic_excuse_waiting.xml b/app/src/main/res/drawable/ic_excuse_waiting.xml new file mode 100644 index 000000000..863418b7b --- /dev/null +++ b/app/src/main/res/drawable/ic_excuse_waiting.xml @@ -0,0 +1,10 @@ + + + diff --git a/app/src/main/res/layout/dialog_excuse.xml b/app/src/main/res/layout/dialog_excuse.xml new file mode 100644 index 000000000..4ed9294ce --- /dev/null +++ b/app/src/main/res/layout/dialog_excuse.xml @@ -0,0 +1,21 @@ + + + + + + + + + + diff --git a/app/src/main/res/layout/dialog_grade.xml b/app/src/main/res/layout/dialog_grade.xml index fad7bae57..be0570c20 100644 --- a/app/src/main/res/layout/dialog_grade.xml +++ b/app/src/main/res/layout/dialog_grade.xml @@ -40,16 +40,16 @@ @@ -57,16 +57,17 @@ android:id="@+id/gradeDialogHeader" android:layout_width="wrap_content" android:layout_height="wrap_content" - android:minHeight="120dp" - android:gravity="center_vertical" - android:layout_toLeftOf="@+id/gradeDialogValueLayout" + android:layout_marginEnd="12dp" + android:layout_marginRight="12dp" android:layout_toStartOf="@+id/gradeDialogValueLayout" + android:layout_toLeftOf="@+id/gradeDialogValueLayout" android:layout_alignParentStart="true" android:layout_alignParentLeft="true" android:layout_alignParentTop="true" - android:layout_marginRight="12dp" - android:layout_marginEnd="12dp" + android:gravity="center_vertical" + android:minHeight="120dp" android:orientation="vertical"> + + + diff --git a/app/src/main/res/layout/item_attendance.xml b/app/src/main/res/layout/item_attendance.xml index 95a8f0174..56bcab440 100644 --- a/app/src/main/res/layout/item_attendance.xml +++ b/app/src/main/res/layout/item_attendance.xml @@ -13,16 +13,40 @@ android:paddingBottom="7dp" tools:context=".ui.modules.attendance.AttendanceItem"> - + android:orientation="vertical"> + + + + + + + + + + + diff --git a/app/src/main/res/values-pl/strings.xml b/app/src/main/res/values-pl/strings.xml index 458f64b45..f5f9f45d1 100644 --- a/app/src/main/res/values-pl/strings.xml +++ b/app/src/main/res/values-pl/strings.xml @@ -141,6 +141,11 @@ %1$d nieobecności %1$d nieobecności + Powód nieobecności (opcjonalny) + Wyślij + Usprawiedliwiono pomyślnie! + Musisz wybrać co najmniej jedną nieobecność! + Usprawiedliw diff --git a/app/src/main/res/values/strings.xml b/app/src/main/res/values/strings.xml index 8bdc54105..08b17825a 100644 --- a/app/src/main/res/values/strings.xml +++ b/app/src/main/res/values/strings.xml @@ -135,6 +135,11 @@ %1$d absence %1$d absences + Absence reason (optional) + Send + Absence excused successfully! + You must select at least one absence! + Excuse diff --git a/app/src/main/res/values/styles.xml b/app/src/main/res/values/styles.xml index 68c0800b1..8f30e3457 100644 --- a/app/src/main/res/values/styles.xml +++ b/app/src/main/res/values/styles.xml @@ -16,6 +16,7 @@