From 9b3f33e1530a8b69ca4a410d0b4f12389663e6d0 Mon Sep 17 00:00:00 2001 From: Jay Panchal Date: Thu, 29 Aug 2024 19:24:41 +0530 Subject: [PATCH 01/11] CCCT-438 || Bottomsheet Joblist UI Created Connect Apps and CommCare Apps Fragments and bottom sheet --- app/res/drawable-hdpi/ic_connect_delivery.png | Bin 0 -> 596 bytes app/res/drawable-hdpi/ic_connect_learning.png | Bin 0 -> 631 bytes .../ic_connect_new_opportunity.png | Bin 0 -> 692 bytes .../drawable-ldpi/ic_connect_delivery.png | Bin 0 -> 258 bytes app/res/drawable-ldpi/ic_connect_delivery.png | Bin 0 -> 258 bytes app/res/drawable-ldpi/ic_connect_learning.png | Bin 0 -> 253 bytes .../ic_connect_new_opportunity.png | Bin 0 -> 274 bytes app/res/drawable-mdpi/ic_connect_delivery.png | Bin 0 -> 338 bytes app/res/drawable-mdpi/ic_connect_learning.png | Bin 0 -> 356 bytes .../ic_connect_new_opportunity.png | Bin 0 -> 371 bytes .../drawable-xhdpi/ic_connect_delivery.png | Bin 0 -> 722 bytes .../drawable-xhdpi/ic_connect_learning.png | Bin 0 -> 818 bytes .../ic_connect_new_opportunity.png | Bin 0 -> 909 bytes .../drawable-xxhdpi/ic_connect_delivery.png | Bin 0 -> 1315 bytes .../drawable-xxhdpi/ic_connect_learning.png | Bin 0 -> 1455 bytes .../ic_connect_new_opportunity.png | Bin 0 -> 1648 bytes .../drawable-xxxhdpi/ic_connect_delivery.png | Bin 0 -> 1186 bytes .../drawable-xxxhdpi/ic_connect_learning.png | Bin 0 -> 1534 bytes .../ic_connect_new_opportunity.png | Bin 0 -> 1735 bytes .../connect_bottom_sheet_rounded_corners.xml | 67 ++++++++ ...onnect_login_bottomsheet_tab_textcolor.xml | 5 + .../connect_rounded_corner_light_green.xml | 5 + .../connect_rounded_corner_orange_yellow.xml | 5 + .../connect_rounded_corner_teslish_blue.xml | 5 + .../drawable/ic_connect_pager_indicator.xml | 17 +++ app/res/layout/bottomsheet_login_joblist.xml | 72 +++++++++ app/res/layout/custom_tab.xml | 18 +++ .../fragment_connect_login_commcare_apps.xml | 15 ++ .../fragment_connect_login_commcare_home.xml | 15 ++ app/res/layout/item_login_commcare_apps.xml | 67 ++++++++ .../layout/item_login_connect_home_apps.xml | 85 +++++++++++ .../layout/testing_recyclerview_joblist.xml | 33 ++++ app/res/values/colors.xml | 7 + app/res/values/strings.xml | 8 +- .../commcare/activities/LoginActivity.java | 51 ++++--- .../activities/LoginActivityUiController.java | 27 ++-- .../adapters/JobListCombinedAdapter.java | 88 +++++++++++ .../adapters/JobListCommCareAppsAdapter.java | 49 ++++++ .../JobListConnectHomeAppsAdapter.java | 48 ++++++ .../adapters/JobListViewPagerAdapter.java | 39 +++++ .../ConnectLoginCommcareAppsFragment.java | 54 +++++++ .../ConnectLoginConnectHomeAppsFragment.java | 51 +++++++ ...onnectLoginJobListBottomSheetFragment.java | 144 ++++++++++++++++++ .../commcare/testingModel/CommCareItem.java | 22 +++ .../testingModel/ConnectHomeItem.java | 21 +++ .../commcare/testingModel/JobListItem.java | 5 + 46 files changed, 984 insertions(+), 39 deletions(-) create mode 100644 app/res/drawable-hdpi/ic_connect_delivery.png create mode 100644 app/res/drawable-hdpi/ic_connect_learning.png create mode 100644 app/res/drawable-hdpi/ic_connect_new_opportunity.png create mode 100644 app/res/drawable-ldpi/drawable-ldpi/ic_connect_delivery.png create mode 100644 app/res/drawable-ldpi/ic_connect_delivery.png create mode 100644 app/res/drawable-ldpi/ic_connect_learning.png create mode 100644 app/res/drawable-ldpi/ic_connect_new_opportunity.png create mode 100644 app/res/drawable-mdpi/ic_connect_delivery.png create mode 100644 app/res/drawable-mdpi/ic_connect_learning.png create mode 100644 app/res/drawable-mdpi/ic_connect_new_opportunity.png create mode 100644 app/res/drawable-xhdpi/ic_connect_delivery.png create mode 100644 app/res/drawable-xhdpi/ic_connect_learning.png create mode 100644 app/res/drawable-xhdpi/ic_connect_new_opportunity.png create mode 100644 app/res/drawable-xxhdpi/ic_connect_delivery.png create mode 100644 app/res/drawable-xxhdpi/ic_connect_learning.png create mode 100644 app/res/drawable-xxhdpi/ic_connect_new_opportunity.png create mode 100644 app/res/drawable-xxxhdpi/ic_connect_delivery.png create mode 100644 app/res/drawable-xxxhdpi/ic_connect_learning.png create mode 100644 app/res/drawable-xxxhdpi/ic_connect_new_opportunity.png create mode 100644 app/res/drawable/connect_bottom_sheet_rounded_corners.xml create mode 100644 app/res/drawable/connect_login_bottomsheet_tab_textcolor.xml create mode 100644 app/res/drawable/connect_rounded_corner_light_green.xml create mode 100644 app/res/drawable/connect_rounded_corner_orange_yellow.xml create mode 100644 app/res/drawable/connect_rounded_corner_teslish_blue.xml create mode 100644 app/res/drawable/ic_connect_pager_indicator.xml create mode 100644 app/res/layout/bottomsheet_login_joblist.xml create mode 100644 app/res/layout/custom_tab.xml create mode 100644 app/res/layout/fragment_connect_login_commcare_apps.xml create mode 100644 app/res/layout/fragment_connect_login_commcare_home.xml create mode 100644 app/res/layout/item_login_commcare_apps.xml create mode 100644 app/res/layout/item_login_connect_home_apps.xml create mode 100644 app/res/layout/testing_recyclerview_joblist.xml create mode 100644 app/src/org/commcare/adapters/JobListCombinedAdapter.java create mode 100644 app/src/org/commcare/adapters/JobListCommCareAppsAdapter.java create mode 100644 app/src/org/commcare/adapters/JobListConnectHomeAppsAdapter.java create mode 100644 app/src/org/commcare/adapters/JobListViewPagerAdapter.java create mode 100644 app/src/org/commcare/fragments/connect/login_job_fragments/ConnectLoginCommcareAppsFragment.java create mode 100644 app/src/org/commcare/fragments/connect/login_job_fragments/ConnectLoginConnectHomeAppsFragment.java create mode 100644 app/src/org/commcare/fragments/connect/login_job_fragments/ConnectLoginJobListBottomSheetFragment.java create mode 100644 app/src/org/commcare/testingModel/CommCareItem.java create mode 100644 app/src/org/commcare/testingModel/ConnectHomeItem.java create mode 100644 app/src/org/commcare/testingModel/JobListItem.java diff --git a/app/res/drawable-hdpi/ic_connect_delivery.png b/app/res/drawable-hdpi/ic_connect_delivery.png new file mode 100644 index 0000000000000000000000000000000000000000..f9edd59c31401d677254fc0217915fc528d0f0a8 GIT binary patch literal 596 zcmV-a0;~OrP)!l09fsVHky<@5{|k(>C6OR3Sm6m4F6+qQoM^#cD(l z9E!SRupQi;rAn)2c5#&iY8MMmPR1%79Mm+XODq-?J>RD-KZrkDu06jI2T{yx5wFpE2$zF7UoPwK% zG78n%d6Q%p_OL)@fYa9CG2a0eq8B-$k6FVKhziKqg(D0g{ORO~gf~Dm5sGjjIKe)L zi$kM2Pd3)Lb@U8hf0wE4G+EjD!qVnCK)wqxDd5K6ADIeHkj$;(uxT6|(Ybv*MsV1J z!={nUtuhrnY^gXQVOkS#-IA(+N~_L7b_K6!|HCx%c4}jkZBx*u(ejTCbxlsPh6~Ed4Mn z5E&rA|M5ei;>DS{f&?&ByP!~U^F`Cb0Ca)8Ld6Z$F7&4Z>`x^<2(DosP84&ERWnqz i)K%(vY4&d2;{O2~ccrs!map~z0000^@R49>Uliy2IVHn3h@4Mr0C*4*T8V0$EI+C&yleP+Uu%I6X ziq*xS{)M0}x~K@diMmLLZn_96c2PzUL=c1F%_fCZSIcQ>mPJ%n6^L)S0`@Di091g$H6>1c$D2M^T3uJ*AU=nzmN(2p?F8~Gy-&2ys9ZIY#Gy3UR(v}fS^8?)LIq5UL*b-uA(K=t3#U`k-KjG+vK_Cd z0VBW8lV?B4%;zbU)W%d`NC1SwsU8qUlRZpRVHky<@7~+q{y+;Y6cnW)7=LOsgb+0_7>G44 zMnl9HJ2*L-7~`Tr{J}UAM>nHgBvA*WLoqBu3?U7J76#NH0nFB%{XhaZ1=IlrU>eD&l=4l_)55017Xah8>(B#A48$v-15o%M zRUnNNH_97krgx;cOVR^s3`7d(1Qb_I6TYV7AOyb1F3Mz2t|wo zT>wH+X}|m&#pT823u78CU0 zRo7Z=&e z&l8Sa#9iBr>ItH{YgzsF4k<0l#YG~W3I2S20T57tB0w&kM6ZwH3AIs}{fM{m2%0Cz z!q^jJ)x;BOLl3r)OD7%c1r3-2E?AWk<+TM=y%t$D`T5~4NU#T*CrEjH$*~MDtw>1P z1;EJ7(b{*9X#61p1>$j+1|*LJgl4p_~=js_=QqGbg zU0a%0`d&HYx$h@O?p_7W5at<-Rt0R+5@lw31+8$?o_qTXcj(P?Q*PMjpS}Bc)5aQp z&NI?cVRFsv^}D7`JmACliXr-X;%h60lHyc`SSGXmRX@2Vr?r=hFwGHOdC_2kQxE&m zSr&U@{0>fjZT*8GShYv_@+VuJ`?LRxnQh>DeBuvNx~k(@&G4h=f$nGUboFyt=akR{ E0Qk*dc>n+a literal 0 HcmV?d00001 diff --git a/app/res/drawable-ldpi/ic_connect_delivery.png b/app/res/drawable-ldpi/ic_connect_delivery.png new file mode 100644 index 0000000000000000000000000000000000000000..e34e6eaedf1871233432ab54b015597f61d249aa GIT binary patch literal 258 zcmeAS@N?(olHy`uVBq!ia0vp^>>$j+1|*LJgl4p_~=js_=QqGbg zU0a%0`d&HYx$h@O?p_7W5at<-Rt0R+5@lw31+8$?o_qTXcj(P?Q*PMjpS}Bc)5aQp z&NI?cVRFsv^}D7`JmACliXr-X;%h60lHyc`SSGXmRX@2Vr?r=hFwGHOdC_2kQxE&m zSr&U@{0>fjZT*8GShYv_@+VuJ`?LRxnQh>DeBuvNx~k(@&G4h=f$nGUboFyt=akR{ E0Qk*dc>n+a literal 0 HcmV?d00001 diff --git a/app/res/drawable-ldpi/ic_connect_learning.png b/app/res/drawable-ldpi/ic_connect_learning.png new file mode 100644 index 0000000000000000000000000000000000000000..8a0fde1acd3b63dcdd26e9fe60d8e2add0d92ae4 GIT binary patch literal 253 zcmeAS@N?(olHy`uVBq!ia0vp^>>$j+1|*LJgyL&i)D;cXgFyRZUWxtHP&X(d6RultFCr zudG{}Dz3S+9&B{F$DP0_@qo#t?Cr8^_Ck-VjplB#nD_4Sn?D|0mC6nlFU*%-zBc9Q zbiZih7pANcTo3x&>$j+1|*LJg%qN#hXN!T9)7P`zOAFG#lZAfZ^+`#*__g=gj#etWG6{QAgm&7?&6e7*f~^W6Fv z8QZqL-ge}*x!C1~{qt3~uAaug%=l_sp`+#%3{&EE%z=**M9$ew!X zExW^t-Df|2fB$N0aZ%mszPr*#?38Bp7I*E*SDnP_$9FNuhUL`(nF@<3IzQM?wb?cP TTXDn-=pP18S3j3^P6UtP)(G6&FK<%*IVibLG-o z5UP!9Au8||4B8f5!)yu(k#<9ihJq$1qXCnMV7?Z96H=Ysc{!Z-@CcO5Zo3LJ0SkzL zKF|potqTC5LdU=!Krxjel9Jok=eXk}Xtef)*=^T=^Mj(zrjcTG(Le}+H-5tnM;r|t zfL&d^Ba)I+w~w7&2f%r{$1?MAYf}eGv2%P6$M<4O@G(IE5-bhS_@y~*daC3KY#7S` z=s*v!XG4cuJNT0^*TExh_yTZ~NLDK$P%mfJ*iNsoG{3;v-GKM6Pp*a!KO6tx`A1Vc kGr((#KuPWHDd3j?-?bZ3d2XJ~a{vGU07*qoM6N<$f+E(28~^|S literal 0 HcmV?d00001 diff --git a/app/res/drawable-mdpi/ic_connect_learning.png b/app/res/drawable-mdpi/ic_connect_learning.png new file mode 100644 index 0000000000000000000000000000000000000000..9df63695d5dbfa13874d8c589445d401e1d81d1a GIT binary patch literal 356 zcmV-q0h|7bP);8au)&zIpP4q_K+##hoO5^ta!OWv1E>N8AOL#6 zVXIj@1`sl;0lNU!x=!#Na(4b2?Ko&Pi+iGEwadT}K*rQqU6~~aL%Kbeq2opIrXtTV zpG)xOevwYAWKE6H=#yMF5rx$lkO$bQq;$D^qVLV)K7e|dg^m!&{n{@sz_rvN_>-d@=aQ+8JX0000#03zTH zXcZg1a{v*C4uD;mn8dIYT5F=vCklOlX0g%R6HYx-15lwC+uVHn4M@7dXDNa|2#W)@f|QK3Qu zRus%GvM4WvZem>w%A}hH*@a$hkf8)&UP*Nk6p{!7F^fJf3Y#)FQL|Fp*4{4Kna6qj z`rn=Zd!FCot^~XK;AY0+^?Q;xS*J#tZbTI zKhuGsn2eXGnn*UV)J3*fRE8qo=^y)?{w5uytAFehAUV6I+-MhTLUpMiohHo&psf48 zslU2JtqP)Ywc{VL6=RlGWZ^f#sqsv^N@e|dGgUA;PB1!-swgCqN!>0~)+$<0H!6;D z`_PGHo&tn7Qk-YYS^;yG?87%QV6;Pugu#u#2I`tPwqy4)nDhB#A`8C^cgkT^Ap1bn zuLYc5oafq`K02$Nya;`vGJm@X3_$c+thLo2EW&aL$N@OHtBf4YMwV)&G&i5p+HMP=&DiYB5qGl zdZHbH)^-7#-88y7B5u!BFl?K+jJE(Cn(?tXR}g4*0X_`*UPU30HzV#_ zT}IP1#D)GgTT&!lAZt_6)YBA}Fes3HF`4Mmm#R_!06j6<$}_v(x&QzG07*qoM6N<$ Ef>1t4%m4rY literal 0 HcmV?d00001 diff --git a/app/res/drawable-xhdpi/ic_connect_learning.png b/app/res/drawable-xhdpi/ic_connect_learning.png new file mode 100644 index 0000000000000000000000000000000000000000..0cad2265e8ca4e037a40fe4bb1e82fad833ef393 GIT binary patch literal 818 zcmV-21I_%2P)g|9PJO^Sr#z`xh9%>3n8Zq`6jL69^e7_!A0(_8i23s&d^oVvp);g`RM%8{LZF z1W;_$ED0gdy1he=enY|esiJ3qu0@3OxL{E;_l%6x#Q@9+R*`=80K4_st(yzkwq-f- zxW?tacibBMpikNTQ;NobJpdAbz0vCdEk&%dB8zRFmtQfBJ9oo;{_=~mQY*2T#^kH-Mps``UfR_oNfNF6eZ_w; z=AT8b&!Mh%32WA_DVcT1xnx)*{DE2C%*=88)D)dNOE5`- z(><@5n*M>!W}#|DHu1Q|W8debYOUD}tV$MiyYeV3$e=JkgYm#Dy_bUQ>hc3nQ=QGZ z)74a#XAyiKCHzs*2@2Va!MLm{B9U0S5@3E0Lq=035Q)S%cw};+$s!0!X!sV( zQWW)n!~pHNgwSs5X;+ht7I!{*HcLv0&1S*v%A>`dXP_qrgwr`}R;0{n{#?7Rb_tag zS=3ZzBiHBf^u;&Mo_~$WBqCw8($Mq`V2*xtY3Hjc*89@02XX^9n+Nia42!zc`J!8>H{ zge14IsL^gk$}odSF^M-bbLoTt&RNvV?!+O*VD0NhJwkAXH2*sZLC_9)ha7#$WQrib wyaVAu(9HbTOzde04Ie_gZBecL2~$nRZ-?6b*6whLHUIzs07*qoM6N<$f|9|D$^ZZW literal 0 HcmV?d00001 diff --git a/app/res/drawable-xhdpi/ic_connect_new_opportunity.png b/app/res/drawable-xhdpi/ic_connect_new_opportunity.png new file mode 100644 index 0000000000000000000000000000000000000000..19ea813313a4c0d76416ca6d8e25458a8fbdcbda GIT binary patch literal 909 zcmV;819JR{P)F#!ve83&A@;eW}AN5j9Qv+fT)YOA_W)odJ&i50PEdxlBrbHTYga2apBW zsVN`W$tr3d$GdG0LaGROwCxNBRGQYAe* z!4ofi!^7w#|NQwasp)a_#bkjpl1XKolvkd1?*|SP(E8oS*|6&%>6u>$fBz=g#U#rQ zqAaCm!8AyQ#&A?_z~A~JWo{qI&{&~VQ=M{31$wN?mr{30O}uIWY71i+@?2^yb0ooktq#qDplZ)uZQ=B=)ykIIHt!ru)6;N7-o z={f8* z)=&<0R=f;o01v`HsM)!Xo1gZqA$z22kfr1u!k124`NGnK zpRCBk=;Rue@ta?9<7}`W7sMG>f9d~<2=GQ=D0bcomh{;5L66HcWG{$ra@H)kDViU% jkqVg|-Z_}i?X~{`g)$h$`Oldi00000NkvXXu0mjfM54P= literal 0 HcmV?d00001 diff --git a/app/res/drawable-xxhdpi/ic_connect_delivery.png b/app/res/drawable-xxhdpi/ic_connect_delivery.png new file mode 100644 index 0000000000000000000000000000000000000000..9d2dd19e6b450968e0e1ec67b23600e7da73b729 GIT binary patch literal 1315 zcmV+;1>E|HP)IDH zrB+Q}D#a}*DE7f7eJHghR7I#wEwn@^v|DO&mQSwA&4Uh>;>7%p)cTl~o zLK(zt|a#7}t>Ld1{BK z>j!cGD}i7?l7MW14+MGD#5@FiGa7M7#A$(IOtEGIg@V32PO&ke$Y+8cjHrD#=r0~v z9}=-8=Chy&=uK~2Otq3&G%W*F<;KJNblLICDdk(@%& zvV2xQGapqrRbR#Dl^1CXb;sLc^#yVdC>(SMNDJ&YOx(9b_`3haB*P?sRwlXAXJUH1 zF~X^=o#W%@+Uq2F4GI?I@ayecG*({bkW??MY3VA z*|(gcOD8y0Up<&nQNMwC8o23A3+%VNqT2*E0t2CKoS#G1l&ATq{4_sQUnAADcp-f@ z0H()F?(|u#nw>S^48W1vN9GkjF52t8%m?9aYTDZX=y7bUm=g8D0tzgQV+Lq8NahGD z!*Hdgfv^542UU>1zi`;|m6nD?W&oC|kZXvt8X+kW`&?rk7n<&j$%(2v9$`b2JOhyx z<6%3li^I4KW4lr6JKJdub&XCCSz`cm$7Ss?(A3?@zN=-lM?&!^nFf$P(Zb=VLv`Or zmgF@EMMw0BDV~WI?Z;FriK1ose7j~7=}D7Dy!QYd|A*+-MR{ynoX4$T>u6s_s|Toi zQh~XtX{4AVkM(}hGYz#IyncZPBhT@>9#uX2q@pKZ*}|T@mzg;!6&OtK&YTxHQd`OU zfBr@=+%s~s>R$#zIpC0Zx)_4Ca5pFGt9W(ZA^;9loafDjxolgU$M@A0d{KF6bWsSY zP-ciyfp8sI{y4&2c7#tV&H=DKYcam5>G;ypInz)}$=`p(69uRfVUjs{+K8Rus6$hCCr#a*d{};(U^v8PUoJ;#D-(%EfWscOs{~+1U{AJ)=f~Kn z*UnkUrz_X-$PUvJ(^COz+S}NBwT$}Cb^uaLiw#-NbE>|Y=AO>65_K7LYx9=f6$XG! zw8~Toh{%BO`NlemE}bAZedr(ny?r;f8!&9xn-SPsA|g8= zanpEAL{zo3#lL%3|H9CdOFSjOae8YpQ3wIYM5H8kafq<3k$b>T!o?RXk$ci2E@!u-|ft`c%m7omON8y*<3Yopu2Ks_O3u<)TzXaB717;xVU& Z{{TB{?)~>3E$ILN002ovPDHLkV1f{xWnBOO literal 0 HcmV?d00001 diff --git a/app/res/drawable-xxhdpi/ic_connect_learning.png b/app/res/drawable-xxhdpi/ic_connect_learning.png new file mode 100644 index 0000000000000000000000000000000000000000..4d0774b815a90ce8e662f84a6e4b85b8bdbdaa56 GIT binary patch literal 1455 zcmV;g1yK5lP)EHXYhd=g!Ri zd?+O?%!dER^PThmf8V+HEJ7SOosF8I4dp4N79y%h&|JVwVB!OpE|7n~tXGN)BGPP{ zv|Mr*8?ksLmS9LT@=a7Js7=6pz#8YCL%?m|2jIAA(sapP9E#)^l_(%XI|a4^g@7JM za0CvZ0Qe9n(KNLm_$rd)m=`;pjTjQhMkojMeu82#q2Ln{?NdFhx4GSm9@@ve*svJW zQG5)lG#ZhvYdk%7JhNww!!#8wHwS6C*-tQ}BKixwi&EK!1j>Q-h{B@OE`{1ajMTnb zmPN@+Q%Om&p%ip?8yr1;k3*H7sCNZbszkK|<)bbH%bYb<(bN_}zKj+PFefjWFFr5i zmtTAM`ruuxR$sA-HS{OK+`A`WJk;>z_~J&d-nny zs`T*JtwCv?qj08%i`cf|$8FtpV(nwF!$(U-#GWl`g|d5R$*?z1Xewt z#*1sFkd$QM)@}cz)EdIyR*>()*oDM_Qx7a}#qM*m=#^X~4)xCL=pLFGhi*`9j=zBzc8@#C#5S}>84 zbyF!?JegBxJ2`iu3uS`KnMP?z1{qUzF4yI8SL0TgX~N@x?N-K>U3IL{p|hdCat#yx!)fmXGRi+5xJ8+z{Ggd z1^`n*uQy0tLmy4Q_fxWN3a@R>2H?PVZJapSiQgYigz6!zfDcGbG{El9bt`ta7E{uxnJgd#JzCN9*lDJRN~ZGywI$ zTh&#?SFHdx(`X53jsp@Q-2k4B0G^Hjwe?=AE_PG4A&at&nV2TjHS|$=tb^v3f%vs- zvfqRzc%)Y@cUA8L*~##>7!@{~#){$;9CqQnyN6&fZXFvyMRis2t`Wo7&L!+ascev# zdsi@M;=cHJ^N)fdlpF)uH`+L+R`hV79i?`Isz{VIK2!xzt}DH5v^8q66}xJ-iDC!B zd=g*iM_>R=3U#2SYWZi89HI^hW%4bet_ZT8;nip+alSpnjp!P1MBtciCbdL!jQZjc zEOXZAA}SxGKt#O&ECq5#jZ+`csuXUZPK2wv>G;#_UKI0>`wvlD4u9LA=)(X2002ov JPDHLkV1mW;t$zRj literal 0 HcmV?d00001 diff --git a/app/res/drawable-xxhdpi/ic_connect_new_opportunity.png b/app/res/drawable-xxhdpi/ic_connect_new_opportunity.png new file mode 100644 index 0000000000000000000000000000000000000000..d0f53d654c2034718975c079ab177521ed0b706c GIT binary patch literal 1648 zcmV-$29NoPP)$3cJB{@k$bOf5*djn3$H zXqeNeurZx6&deVSiAE-2BOwlOx-e%anx!QEVw*8DIukS*CQ2xSO&BGEktSU`9HkU! zd$hgw+FtL+_xtgWqqWz&E8|J-pXc-bJg<8`Kc3I?6>egk+k(mpsFhl?8n{!5tkX~j z1a3&K3k*2uGiW*$^4@IH?hEaUB$kRRO99<})gZ_Qgol9^z`V)-oCW%|=2g-9AMupa z9oiR3QO13$xC(ugPnQ3k&9W~xI^QQY!SKC~Oy0J1%U1<<)OXu4g-qayr1-|T|2 zkJ0e(?=TCB5T%HP`>^Aa_-oeUq~fGv5#E1oGt<}3=g(g2AH<_hM`(Y^ynnn0t zKD}Z2DQkTcx4(>who55T?cbucgJA`@cJcuI|J;SkS4`=euVZ?aFogz@XmXelD zcuN|IUOr9q(kY??Z(}E>7lv&X(HlCq1%GaA3Hk0o*b9^`R4o7KXK8%oC9FUtsaS-u zp2J)@u^%Tf4cft;ogg(kfp%;_GdP3y?mNjxR>g6JMon_=R(&hkm7|N&x(3#*YC#gEMxH4FNlSE(-3cvn)SOg3dI~W z(szWx<1dh$83P~|?&ZpfUtzd?)UMx+XGQ&Da3JR+p#f0}F*8e~h(X;0&te5CF{}U; zZCe;V^D={Pw3CXBX9khtvlE2RzDjWAI%@CVizpY9mrh|=0m|>*jCO1i z(P4(qyu1_?tvMjd>4rtk-hZAhY6rHGr}ZiR_(OP$S2EV~Ix{0Z0CymxOkaJM z@VkG>$4qEV$0wf|ePYg$3Eo{)iKZQRkPqL|0_jH3$^DAW0*3^>qwObSgY)`@in!QU zHF}4Jj$45O`JiY`hiJBYlry-{pZ81RtsfVC>qZ~e!YyV``t)|AIe5=Aqc7$Xfv=G6QgZJ70!xvu34g`mkk_=ciu9c2&3MjE?g_fJV>D<@6GBL!6?Dyl u=X4VIKx>WxT?pq2lzrh7dm_$KasLPSCPw}^U!fEL0000c&{= zB9Mg(2{YhY9Y{A3>kPKB(1oecO=x)rx~Plb!Vp^mYAH@3*-UIpNQf{UH-3aL6J}xF zFzXlQ>Qu8a*AJpc6WXUBdjLKA0f+-p5K&}$ z+k%ak{+Z2s?j!6N>qby_X-yMID^LJatD+J%Q!*8b`-4$O0d*s&HwxFRKu+0&QcA*7 zt)RyOw%q+@LdbLo`!jZ&qEZq%^iMBUGpY*MvUF>~sadNeiMV~}yBVm|uLR7xbVVTh z-x^u5BBo3Y#Qni|X-9*~+9et{vQK8s>TUHh?7aZM^3D_fdUasu@}5TFS^)-1JIZFT z9=G1O)W;V+eMN0Ej~;U8>0>*?DBWEI*kXL`69PkZac`>^uiK*r?72+4+ryowk2%}e z#As(X3G;|AA3aps?7sK8QeA4D+Yp-l3^+w^E1p;|M-I(tXSU%O? zX?JI~zX!2rOm5w;2p?;R#8liqC1^*3mW&9N5kCKFBrmFWzk zM?+}cZ~abnN+JdtsKdSgRm(fu{IUNJ;R>5|UV`pZ0SxcO2-jw+Yd9b0+0t28Q?+hg zJ1G#AZd~ePePo>W3THfI_QA3k>?D+nfZE+2E}mF(aP%4sJ+ESVr&o&edFl=utlHRXwW1y`Shq_h?f{WFt=ZOYnA%hIil z6RgYR6gluse^lD2jAl~Oyo$p|U^PkPrYTd()T4U&?F8Jda%-Wg#)F6cnMo<}15u~J zfVhw{Pz?@hECII}^BorH5JFscf=o(lF-3Y-RSztcts;5>=w zLNyz6{Td8p(pK34qJ!es5OE-q3Fl;_-q#TS0w}h;@zu9^3%~(*RnzW~yP(&lxPYPrsNEZlKvRAGml!%l> z1UtVQhA}Y{@CS;SM_3uGX(88^vUvq$@4qmn6#)WcjAmCly+hxx;e#@4a5Ryi-_Pq^GE}yT#?REh0{P_mA?=CXG zux`$Pl#L0o`3PvuVc*+eby+W+ui94!+VJ}hbNPG{y1Q?V&}_^KWbgEN%gyw&l7Z8vYZa7!)0QCPxyNJ6 z+!~4yT}m*&u)&>?#f;}V+N-UYM4%Tw)&&x zmH9&o{;B`PcO?lAz=3L60NwH>Qw5s0g4FDj7no@Gr=y#(M~rzfW` zy|nWS8^xGrOWEj6!U8RA(=V{NyZ|1zgW>PrK~?QMom%0Sv1L@%#)s|IcpIGPO9{IB z=7{QvA`r!DaJ;EXG-=bCqA*c}1pw;n%DMjK+qjQ7vfAV8+jRHMG5@?c4+0p*cB@@c zjMiOyB}abWVR}A!3tdkz|9pdIvoYou*3na5nP1qTyKfG^uL|#RXQu7JL!GtwcE*mX z+VT6UI96AI$L-+g(Q*dAi!eF0vhUnNu{GMkb{yosgH+Xq=ZFK(5eMD|Cucj|Kyv3k z9$O|f8zZVGQgJXhD5tZGx51gySE25|$pDbF+J!J`r7T=^g=S+s3&-#_I62Yiq@%r> zj`nJvPOWfrD3bALT5h+4YoFF-frY{`CW9~W`wnv=5Aa?IA&%RnG`BgTdV)J6i$HR7 zoH^~`bsJ!+26st0j~WGOS2M`2PmkPljPkC^LcPfSHX_soGHsMSc_V z9C2jo$O9#b%mn;_)Qn;f`23*peqR-1KflXbe4Fs>8k18mnVec7ULeM$bMT1E_I7cNSE9eVb@>i>SWI(gB;wFc?U3rqt3FyanP)p&wRXSB|&QNyn)-v&s>=tK z&cUH@%xnQW92{@Hm<6b56Rs`A@xn^#tFJ5PY^NtvJxBEf@%T;#JQR*`dt}jC(3V6D zNo)GvCaa8TZkxF(kT=X*OMxD(;QANGGDYhvr8wHQmdkB}F(m(d6CRoVV6@>}-C7l&>v-OG%(i zI&$u1puqK8vCC~uxy!m+`=6G8;CM@q0T+=(O3sB`mB`+M;K1Y+aFaG&D})>nLUfe~ zZm`UFqd(t$;9gm}M9+XC-bYwH=*v|QgJs5{8)m?Y0^F_Sf!}DAh~q+1n*`qVHw0o; kBEuLwk%(}zD6y`80ANa2ffK#6tN;K207*qoM6N<$f@>(RD@-y&Y1PqnMeNu^1U6|PwVffS=HLe+OFx#<+NDd57zj&l+*xr2x`lP)Ebkt=IA?Izg*E=+Vx?^e_rN{Va8 zuRI-VG+Y-jKB{S+y{1`_#A-IMw6Z1vmg1_V`_M z^+sv{7bZHUL57`}{o$Lx=e4nWbcctxz^Wb}furwpc;q%eI{k?=L`ihvqps=g&$ldb z@}tgQ3c-vMgWf!V<#c{KL{P>N{p(f1Jop4^`$t0z%Ce*6a_cmw?eW8o|0hSBGx_P|R~djm%}JaQYL zAsm1}oC7A5`3qf9n(Vy_uU)v7#nBcYy!6yeCf0d=yLL7g@`GpkfCNyyn%iS zMw(paK}&G^qvN=>KH95tWWiXWV5Dge^b>mPcg@TUD0aE8;-r|*vON1v&9YQSrrvu{ zN=56-cdG!?EYH3}F~33Y(K7^N<92|WA`o@^yq>`!%gMjyeoZcu+A{79^fPcaQB!NT z!_`Ygxl9WEZt0)BKRQm&;80`0MkBH+F{*8i_e*zp$bxhNSCOdd0%W5k47lEVqis|m zJlh8<5%V7?CDx5cU-07D6Knj%vnLpjzM$*KY4+~_DV;xli_ZR^JA(5D`Z@TEKclD~ z(($WgzPiz9s-Xx(O_NyBw~4E)F5W=(_<42sR?VKvWl}txIYlwQfj4l(5u95Ka%lJ# zs>e?{ewA+%cJ*26iXvIEnSuWKd2*Q)Zmkb@oitMo>7+JS?Bp`3CU5{^MJ*z~R1k05 zO{U{dd9l9Hmno*wh2%0RHuR*G%bF<| z8>c%wT=OS$Yr%#!SqPDUa!36ir8w<2U3CGA`3)YS#6x}wz3Is9-CYn*#a29q-lFh<#D6Zw_S%vZsQ9@ zSYN(_>hW7$az(jJif5}SdIpCm7-{ZJ4?2PasSCx79lKPzw{cY-|0R*n|LXO&0z$m$ z#7x0R(=#|sTh~F{S|7!HmVeKGOu99{u0UeZF+bWH;9?h2gAb+5WPF?gx=K5)BQx(vRK4ei*x`0002ovPDHLkV1ktpM&tkh literal 0 HcmV?d00001 diff --git a/app/res/drawable/connect_bottom_sheet_rounded_corners.xml b/app/res/drawable/connect_bottom_sheet_rounded_corners.xml new file mode 100644 index 0000000000..1738d92bae --- /dev/null +++ b/app/res/drawable/connect_bottom_sheet_rounded_corners.xml @@ -0,0 +1,67 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/app/res/drawable/connect_login_bottomsheet_tab_textcolor.xml b/app/res/drawable/connect_login_bottomsheet_tab_textcolor.xml new file mode 100644 index 0000000000..a213b2c350 --- /dev/null +++ b/app/res/drawable/connect_login_bottomsheet_tab_textcolor.xml @@ -0,0 +1,5 @@ + + + + + diff --git a/app/res/drawable/connect_rounded_corner_light_green.xml b/app/res/drawable/connect_rounded_corner_light_green.xml new file mode 100644 index 0000000000..671ea8c44e --- /dev/null +++ b/app/res/drawable/connect_rounded_corner_light_green.xml @@ -0,0 +1,5 @@ + + + + + \ No newline at end of file diff --git a/app/res/drawable/connect_rounded_corner_orange_yellow.xml b/app/res/drawable/connect_rounded_corner_orange_yellow.xml new file mode 100644 index 0000000000..497a0abb34 --- /dev/null +++ b/app/res/drawable/connect_rounded_corner_orange_yellow.xml @@ -0,0 +1,5 @@ + + + + + \ No newline at end of file diff --git a/app/res/drawable/connect_rounded_corner_teslish_blue.xml b/app/res/drawable/connect_rounded_corner_teslish_blue.xml new file mode 100644 index 0000000000..6f24f72015 --- /dev/null +++ b/app/res/drawable/connect_rounded_corner_teslish_blue.xml @@ -0,0 +1,5 @@ + + + + + \ No newline at end of file diff --git a/app/res/drawable/ic_connect_pager_indicator.xml b/app/res/drawable/ic_connect_pager_indicator.xml new file mode 100644 index 0000000000..e3d8f5124c --- /dev/null +++ b/app/res/drawable/ic_connect_pager_indicator.xml @@ -0,0 +1,17 @@ + + + + + + + + + + + + \ No newline at end of file diff --git a/app/res/layout/bottomsheet_login_joblist.xml b/app/res/layout/bottomsheet_login_joblist.xml new file mode 100644 index 0000000000..19b0ae2bcb --- /dev/null +++ b/app/res/layout/bottomsheet_login_joblist.xml @@ -0,0 +1,72 @@ + + + + + + + + + + + + + + + + diff --git a/app/res/layout/custom_tab.xml b/app/res/layout/custom_tab.xml new file mode 100644 index 0000000000..336d63550c --- /dev/null +++ b/app/res/layout/custom_tab.xml @@ -0,0 +1,18 @@ + + + + + + diff --git a/app/res/layout/fragment_connect_login_commcare_apps.xml b/app/res/layout/fragment_connect_login_commcare_apps.xml new file mode 100644 index 0000000000..fd0978319b --- /dev/null +++ b/app/res/layout/fragment_connect_login_commcare_apps.xml @@ -0,0 +1,15 @@ + + + + + \ No newline at end of file diff --git a/app/res/layout/fragment_connect_login_commcare_home.xml b/app/res/layout/fragment_connect_login_commcare_home.xml new file mode 100644 index 0000000000..8913340773 --- /dev/null +++ b/app/res/layout/fragment_connect_login_commcare_home.xml @@ -0,0 +1,15 @@ + + + + + \ No newline at end of file diff --git a/app/res/layout/item_login_commcare_apps.xml b/app/res/layout/item_login_commcare_apps.xml new file mode 100644 index 0000000000..a31c7897c3 --- /dev/null +++ b/app/res/layout/item_login_commcare_apps.xml @@ -0,0 +1,67 @@ + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/app/res/layout/item_login_connect_home_apps.xml b/app/res/layout/item_login_connect_home_apps.xml new file mode 100644 index 0000000000..ab514bb5bb --- /dev/null +++ b/app/res/layout/item_login_connect_home_apps.xml @@ -0,0 +1,85 @@ + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/app/res/layout/testing_recyclerview_joblist.xml b/app/res/layout/testing_recyclerview_joblist.xml new file mode 100644 index 0000000000..9a4c585788 --- /dev/null +++ b/app/res/layout/testing_recyclerview_joblist.xml @@ -0,0 +1,33 @@ + + + + + + + \ No newline at end of file diff --git a/app/res/values/colors.xml b/app/res/values/colors.xml index 2cdb96c759..3b5887b02c 100644 --- a/app/res/values/colors.xml +++ b/app/res/values/colors.xml @@ -151,6 +151,13 @@ #1A3A42C7 #3942C7 #3A42C7 + #E7EAF8 #F3B34D #D9D9D9 + #1AD9D9D9 + #E5E7EB + #9CA3AF + #FFEFD5 + #16A085 + #E6F5E5 diff --git a/app/res/values/strings.xml b/app/res/values/strings.xml index 7f03488790..e51e1198aa 100644 --- a/app/res/values/strings.xml +++ b/app/res/values/strings.xml @@ -91,7 +91,7 @@ CommCare Login Expired Submitting Data Submitting CommCare Logs - + 200 250 @@ -467,7 +467,7 @@ %1s sq m Could not parse input coordinates Turn on your location to receive location updates - CommCare is still trying to get your location. Please wait or click Cancel to abort. + CommCare is still trying to get your location. Please wait or click Cancel to abort. Invalid %1s, value must be 255 characters or less This form introduces an invalid case relationship Rooted Device Detected @@ -786,7 +786,7 @@ Sign up for ConnectID Sign out of ConnectID Forget ConnectID user - + App install failed due to an unknown error App installed Required CommCare App is not installed on device @@ -799,4 +799,6 @@ An error occurred while connecting to the server. Yes No + + Hello blank fragment diff --git a/app/src/org/commcare/activities/LoginActivity.java b/app/src/org/commcare/activities/LoginActivity.java index 3414f6f572..a50a265dc4 100644 --- a/app/src/org/commcare/activities/LoginActivity.java +++ b/app/src/org/commcare/activities/LoginActivity.java @@ -24,19 +24,17 @@ import com.scottyab.rootbeer.RootBeer; -import java.util.ArrayList; -import java.util.Date; - import org.commcare.CommCareApp; import org.commcare.CommCareApplication; -import org.commcare.android.database.connect.models.ConnectJobRecord; -import org.commcare.connect.ConnectManager; import org.commcare.android.database.app.models.UserKeyRecord; +import org.commcare.android.database.connect.models.ConnectJobRecord; import org.commcare.android.database.global.models.ApplicationRecord; +import org.commcare.connect.ConnectManager; import org.commcare.dalvik.BuildConfig; import org.commcare.dalvik.R; import org.commcare.engine.resource.AppInstallStatus; import org.commcare.engine.resource.ResourceInstallUtils; +import org.commcare.fragments.connect.login_job_fragments.ConnectLoginJobListBottomSheetFragment; import org.commcare.google.services.analytics.FirebaseAnalyticsUtil; import org.commcare.interfaces.CommCareActivityUIController; import org.commcare.interfaces.RuntimePermissionRequester; @@ -67,6 +65,9 @@ import org.javarosa.core.services.Logger; import org.javarosa.core.services.locale.Localization; +import java.util.ArrayList; +import java.util.Date; + /** * @author ctsims */ @@ -203,9 +204,9 @@ protected void onSaveInstanceState(Bundle savedInstanceState) { * upon successful login */ protected void initiateLoginAttempt(boolean restoreSession) { - if(isConnectJobsSelected()) { + if (isConnectJobsSelected()) { ConnectManager.unlockConnect(this, success -> { - if(success) { + if (success) { ConnectManager.goToConnectJobsList(); } }); @@ -216,15 +217,14 @@ protected void initiateLoginAttempt(boolean restoreSession) { String seatedAppId = CommCareApplication.instance().getCurrentApp().getUniqueId(); String username = uiController.getEnteredUsername(); - if(!appLaunchedFromConnect && uiController.loginManagedByConnectId()) { + if (!appLaunchedFromConnect && uiController.loginManagedByConnectId()) { ConnectManager.unlockConnect(this, success -> { - if(success) { + if (success) { String pass = ConnectManager.getStoredPasswordForApp(seatedAppId, username); doLogin(loginMode, restoreSession, pass); } }); - } - else { + } else { String passwordOrPin = uiController.getEnteredPasswordOrPin(); doLogin(loginMode, restoreSession, passwordOrPin); } @@ -454,7 +454,7 @@ public void dataPullCompleted() { ViewUtil.hideVirtualKeyboard(LoginActivity.this); CommCareApplication.notificationManager().clearNotifications(NOTIFICATION_MESSAGE_LOGIN); - if(handleConnectSignIn()) { + if (handleConnectSignIn()) { setResultAndFinish(false); } } @@ -472,7 +472,7 @@ private void setResultAndFinish(boolean goToJobInfo) { public void handleConnectButtonPress() { selectedAppIndex = -1; ConnectManager.unlockConnect(this, success -> { - if(success) { + if (success) { ConnectManager.goToConnectJobsList(); setResult(RESULT_OK); finish(); @@ -481,10 +481,10 @@ public void handleConnectButtonPress() { } public boolean handleConnectSignIn() { - if(ConnectManager.isConnectIdConfigured()) { + if (ConnectManager.isConnectIdConfigured()) { String appId = CommCareApplication.instance().getCurrentApp().getUniqueId(); ConnectJobRecord job = ConnectManager.setConnectJobForApp(this, appId); - if(job != null) { + if (job != null) { //Update job status ConnectManager.updateJobProgress(this, job, success -> { setResultAndFinish(job.getIsUserSuspended() || job.readyToTransitionToDelivery()); @@ -495,8 +495,8 @@ public boolean handleConnectSignIn() { uiController.loginManagedByConnectId(), appId, uiController.getEnteredUsername(), uiController.getEnteredPasswordOrPin(), success -> { - setResultAndFinish(false); - }); + setResultAndFinish(false); + }); } return false; @@ -507,9 +507,9 @@ public boolean handleConnectSignIn() { public void handleFailedConnectSignIn() { ApplicationRecord record = CommCareApplication.instance().getCurrentApp().getAppRecord(); - if(appLaunchedFromConnect) { + if (appLaunchedFromConnect) { FirebaseAnalyticsUtil.reportCccAppFailedAutoLogin(record.getApplicationId()); - } else if(ConnectManager.isLoginManagedByConnectId(record.getUniqueId(), getUniformUsername())) { + } else if (ConnectManager.isLoginManagedByConnectId(record.getUniqueId(), getUniformUsername())) { //TODO: Display an additional message that the user will need to login with their password to restore CID login //ConnectManager.forgetAppCredentials(record.getUniqueId(), getUniformUsername()); //checkForSavedCredentials(); @@ -531,13 +531,13 @@ private void checkForSavedCredentials() { uiController.setConnectButtonVisible(false); uiController.setUsername(getString(R.string.login_input_auto)); uiController.setPasswordOrPin(getString(R.string.login_input_auto)); - if(!seatAppIfNeeded(presetAppId)) { + if (!seatAppIfNeeded(presetAppId)) { connectLaunchPerformed = true; initiateLoginAttempt(uiController.isRestoreSessionChecked()); } } else { int selectorIndex = uiController.getSelectedAppIndex(); - if(selectorIndex > 0) { + if (selectorIndex > 0) { String selectedAppId = appIdDropdownList.size() > 0 ? appIdDropdownList.get(selectorIndex) : ""; String seatedAppId = CommCareApplication.instance().getCurrentApp().getUniqueId(); if (!uiController.isAppSelectorVisible() || selectedAppId.equals(seatedAppId)) { @@ -743,7 +743,7 @@ private boolean isConnectJobsSelected() { @Override public void onItemSelected(AdapterView parent, View view, int position, long id) { boolean selectedConnect = isConnectJobsSelected(); - if(selectedConnect) { + if (selectedConnect) { uiController.setLoginInputsVisibility(false); } else { // Retrieve the app record corresponding to the app selected @@ -946,7 +946,7 @@ public void handlePullTaskError() { private void checkManagedConfiguration() { // Check for managed configuration RestrictionsManager restrictionsManager = - (RestrictionsManager)getSystemService(Context.RESTRICTIONS_SERVICE); + (RestrictionsManager) getSystemService(Context.RESTRICTIONS_SERVICE); if (restrictionsManager == null) { return; } @@ -962,4 +962,9 @@ private void checkManagedConfiguration() { protected String getPresetAppId() { return presetAppId; } + + public void openJobListBottomSheet() { + ConnectLoginJobListBottomSheetFragment connectLoginJobListBottomSheetFragment = ConnectLoginJobListBottomSheetFragment.newInstance(); + connectLoginJobListBottomSheetFragment.show(getSupportFragmentManager(), "connectLoginJobListBottomSheetFragment"); + } } diff --git a/app/src/org/commcare/activities/LoginActivityUiController.java b/app/src/org/commcare/activities/LoginActivityUiController.java index 79cc613ebc..fde2c0858e 100644 --- a/app/src/org/commcare/activities/LoginActivityUiController.java +++ b/app/src/org/commcare/activities/LoginActivityUiController.java @@ -19,15 +19,12 @@ import androidx.preference.PreferenceManager; -import java.util.ArrayList; -import java.util.Vector; - import org.commcare.CommCareApplication; import org.commcare.CommCareNoficationManager; -import org.commcare.connect.ConnectDatabaseHelper; -import org.commcare.connect.ConnectManager; import org.commcare.android.database.app.models.UserKeyRecord; import org.commcare.android.database.global.models.ApplicationRecord; +import org.commcare.connect.ConnectDatabaseHelper; +import org.commcare.connect.ConnectManager; import org.commcare.dalvik.R; import org.commcare.google.services.analytics.FirebaseAnalyticsUtil; import org.commcare.interfaces.CommCareActivityUIController; @@ -44,6 +41,8 @@ import org.commcare.views.UiElement; import org.javarosa.core.services.locale.Localization; +import java.util.ArrayList; +import java.util.Vector; import javax.annotation.Nullable; @@ -166,7 +165,7 @@ public void setupUI() { }); passwordOrPin.setOnFocusChangeListener((v, hasFocus) -> { - if(hasFocus) { + if (hasFocus) { setConnectIdLoginState(false); } }); @@ -179,6 +178,7 @@ public void setupUI() { public void setConnectButtonVisible(Boolean visible) { connectLoginButton.setVisibility(visible ? View.VISIBLE : View.GONE); orLabel.setVisibility(visible ? View.VISIBLE : View.GONE); + orLabel.setOnClickListener(view -> activity.openJobListBottomSheet()); } private void setTextChangeListeners() { @@ -533,20 +533,21 @@ protected void setPasswordOrPin(String s) { passwordOrPin.setText(s); } - protected boolean loginManagedByConnectId() { return loginManagedByConnectId; } + protected boolean loginManagedByConnectId() { + return loginManagedByConnectId; + } protected void setConnectIdLoginState(boolean useConnectId) { - if(!useConnectId && loginManagedByConnectId) { + if (!useConnectId && loginManagedByConnectId) { setPasswordOrPin(""); } - loginManagedByConnectId = useConnectId; + loginManagedByConnectId = useConnectId; String text; - if(useConnectId) { + if (useConnectId) { text = activity.getString(R.string.login_button_connectid); - } - else { + } else { text = Localization.get("login.button"); } loginButton.setText(text); @@ -558,7 +559,7 @@ protected void setConnectIdLoginState(boolean useConnectId) { connectLoginButton.setText(activity.getString(R.string.connect_button_logged_in)); passwordOrPin.setBackgroundColor(getResources().getColor(useConnectId ? R.color.grey_light : R.color.white)); - if(useConnectId) { + if (useConnectId) { passwordOrPin.setText(R.string.login_password_by_connect); passwordOrPin.clearFocus(); } diff --git a/app/src/org/commcare/adapters/JobListCombinedAdapter.java b/app/src/org/commcare/adapters/JobListCombinedAdapter.java new file mode 100644 index 0000000000..d0c7482245 --- /dev/null +++ b/app/src/org/commcare/adapters/JobListCombinedAdapter.java @@ -0,0 +1,88 @@ +package org.commcare.adapters; + +import android.content.Context; +import android.view.LayoutInflater; +import android.view.ViewGroup; + +import androidx.annotation.NonNull; +import androidx.recyclerview.widget.RecyclerView; + +import org.commcare.dalvik.databinding.ItemLoginCommcareAppsBinding; +import org.commcare.dalvik.databinding.ItemLoginConnectHomeAppsBinding; +import org.commcare.testingModel.CommCareItem; + +import java.util.List; + +public class JobListCombinedAdapter extends RecyclerView.Adapter { + + private static final int VIEW_TYPE_COMMCARE = 0; + private static final int VIEW_TYPE_CONNECT_HOME = 1; + private List items; // Your data source + private Context mContext; + + public JobListCombinedAdapter(Context context, List items) { + this.mContext = context; + this.items = items; + } + + @NonNull + @Override + public RecyclerView.ViewHolder onCreateViewHolder(@NonNull ViewGroup parent, int viewType) { + LayoutInflater inflater = LayoutInflater.from(parent.getContext()); + + if (viewType == VIEW_TYPE_COMMCARE) { + ItemLoginCommcareAppsBinding binding = ItemLoginCommcareAppsBinding.inflate(inflater, parent, false); + return new CommCareViewHolder(binding); + } else { + ItemLoginConnectHomeAppsBinding binding = ItemLoginConnectHomeAppsBinding.inflate(inflater, parent, false); + return new ConnectHomeViewHolder(binding); + } + } + + @Override + public void onBindViewHolder(@NonNull RecyclerView.ViewHolder holder, int position) { + int viewType = getItemViewType(position); + + if (viewType == VIEW_TYPE_COMMCARE) { + // Bind data for CommCareViewHolder + CommCareViewHolder viewHolder = (CommCareViewHolder) holder; + viewHolder.bind(); + } else { + // Bind data for ConnectHomeViewHolder + ConnectHomeViewHolder viewHolder = (ConnectHomeViewHolder) holder; + viewHolder.bind(); + } + } + + @Override + public int getItemViewType(int position) { + return items.get(position) instanceof CommCareItem ? VIEW_TYPE_COMMCARE : VIEW_TYPE_CONNECT_HOME; + } + + @Override + public int getItemCount() { + return items.size(); + } + + static class CommCareViewHolder extends RecyclerView.ViewHolder { + private final ItemLoginCommcareAppsBinding binding; + + public CommCareViewHolder(ItemLoginCommcareAppsBinding binding) { + super(binding.getRoot()); + this.binding = binding; + } + + public void bind() {} + } + + static class ConnectHomeViewHolder extends RecyclerView.ViewHolder { + private final ItemLoginConnectHomeAppsBinding binding; + + public ConnectHomeViewHolder(ItemLoginConnectHomeAppsBinding binding) { + super(binding.getRoot()); + this.binding = binding; + } + + public void bind() {} + } +} diff --git a/app/src/org/commcare/adapters/JobListCommCareAppsAdapter.java b/app/src/org/commcare/adapters/JobListCommCareAppsAdapter.java new file mode 100644 index 0000000000..31a036ff27 --- /dev/null +++ b/app/src/org/commcare/adapters/JobListCommCareAppsAdapter.java @@ -0,0 +1,49 @@ +package org.commcare.adapters; + +import android.content.Context; +import android.view.LayoutInflater; +import android.view.ViewGroup; + +import androidx.annotation.NonNull; +import androidx.recyclerview.widget.RecyclerView; + +import org.commcare.dalvik.databinding.ItemLoginCommcareAppsBinding; +import org.commcare.dalvik.databinding.ItemLoginConnectHomeAppsBinding; + +public class JobListCommCareAppsAdapter extends RecyclerView.Adapter { + + private Context mContext; + + public JobListCommCareAppsAdapter(Context context) { + this.mContext = context; + } + + @NonNull + @Override + public ViewHolder onCreateViewHolder(@NonNull ViewGroup parent, int viewType) { + // Inflate the layout for each item using View Binding + ItemLoginCommcareAppsBinding binding = ItemLoginCommcareAppsBinding.inflate( + LayoutInflater.from(parent.getContext()), parent, false); + return new ViewHolder(binding); + } + + @Override + public void onBindViewHolder(@NonNull ViewHolder holder, int position) { + // Bind data to each item view +// String item = items.get(position); + } + + @Override + public int getItemCount() { + return 15; + } + + public static class ViewHolder extends RecyclerView.ViewHolder { + private final ItemLoginCommcareAppsBinding binding; + + public ViewHolder(ItemLoginCommcareAppsBinding binding) { + super(binding.getRoot()); + this.binding = binding; + } + } +} diff --git a/app/src/org/commcare/adapters/JobListConnectHomeAppsAdapter.java b/app/src/org/commcare/adapters/JobListConnectHomeAppsAdapter.java new file mode 100644 index 0000000000..8882292430 --- /dev/null +++ b/app/src/org/commcare/adapters/JobListConnectHomeAppsAdapter.java @@ -0,0 +1,48 @@ +package org.commcare.adapters; + +import android.content.Context; +import android.view.LayoutInflater; +import android.view.ViewGroup; + +import androidx.annotation.NonNull; +import androidx.recyclerview.widget.RecyclerView; + +import org.commcare.dalvik.databinding.ItemLoginConnectHomeAppsBinding; + +public class JobListConnectHomeAppsAdapter extends RecyclerView.Adapter { + + private Context mContext; + + public JobListConnectHomeAppsAdapter(Context context) { + this.mContext = context; + } + + @NonNull + @Override + public ViewHolder onCreateViewHolder(@NonNull ViewGroup parent, int viewType) { + // Inflate the layout for each item using View Binding + ItemLoginConnectHomeAppsBinding binding = ItemLoginConnectHomeAppsBinding.inflate( + LayoutInflater.from(parent.getContext()), parent, false); + return new ViewHolder(binding); + } + + @Override + public void onBindViewHolder(@NonNull ViewHolder holder, int position) { + // Bind data to each item view +// String item = items.get(position); + } + + @Override + public int getItemCount() { + return 15; + } + + public static class ViewHolder extends RecyclerView.ViewHolder { + private final ItemLoginConnectHomeAppsBinding binding; + + public ViewHolder(ItemLoginConnectHomeAppsBinding binding) { + super(binding.getRoot()); + this.binding = binding; + } + } +} diff --git a/app/src/org/commcare/adapters/JobListViewPagerAdapter.java b/app/src/org/commcare/adapters/JobListViewPagerAdapter.java new file mode 100644 index 0000000000..fd1a6a9a15 --- /dev/null +++ b/app/src/org/commcare/adapters/JobListViewPagerAdapter.java @@ -0,0 +1,39 @@ +package org.commcare.adapters; + +import androidx.annotation.NonNull; +import androidx.fragment.app.Fragment; +import androidx.fragment.app.FragmentActivity; +import androidx.fragment.app.FragmentManager; +import androidx.fragment.app.FragmentStatePagerAdapter; +import androidx.viewpager2.adapter.FragmentStateAdapter; + +import java.util.ArrayList; +import java.util.List; + +public class JobListViewPagerAdapter extends FragmentStateAdapter { + private final List fragmentList = new ArrayList<>(); + private final List titleList = new ArrayList<>(); + + public JobListViewPagerAdapter(FragmentActivity fa) { + super(fa); + } + + @Override + public Fragment createFragment(int position) { + return fragmentList.get(position); + } + + @Override + public int getItemCount() { + return fragmentList.size(); + } + + public void add(Fragment fragment, String title) { + fragmentList.add(fragment); + titleList.add(title); + } + + public CharSequence getPageTitle(int position) { + return titleList.get(position); + } +} diff --git a/app/src/org/commcare/fragments/connect/login_job_fragments/ConnectLoginCommcareAppsFragment.java b/app/src/org/commcare/fragments/connect/login_job_fragments/ConnectLoginCommcareAppsFragment.java new file mode 100644 index 0000000000..a34d40863f --- /dev/null +++ b/app/src/org/commcare/fragments/connect/login_job_fragments/ConnectLoginCommcareAppsFragment.java @@ -0,0 +1,54 @@ +package org.commcare.fragments.connect.login_job_fragments; + +import android.os.Bundle; +import android.view.LayoutInflater; +import android.view.View; +import android.view.ViewGroup; + +import androidx.fragment.app.Fragment; +import androidx.recyclerview.widget.LinearLayoutManager; + +import org.commcare.adapters.JobListCommCareAppsAdapter; +import org.commcare.adapters.JobListConnectHomeAppsAdapter; +import org.commcare.dalvik.databinding.FragmentConnectLoginCommcareAppsBinding; + +/** + * A simple {@link Fragment} subclass. + * Use the {@link ConnectLoginCommcareAppsFragment#newInstance} factory method to + * create an instance of this fragment. + */ +public class ConnectLoginCommcareAppsFragment extends Fragment { + + private FragmentConnectLoginCommcareAppsBinding binding; + private JobListCommCareAppsAdapter adapter; + + public static ConnectLoginCommcareAppsFragment newInstance() { + ConnectLoginCommcareAppsFragment fragment = new ConnectLoginCommcareAppsFragment(); + Bundle args = new Bundle(); + fragment.setArguments(args); + return fragment; + } + + @Override + public View onCreateView(LayoutInflater inflater, ViewGroup container, + Bundle savedInstanceState) { + binding = FragmentConnectLoginCommcareAppsBinding.inflate(inflater, container, false); + initRecyclerView(); + return binding.getRoot(); + } + + private void initRecyclerView() { + adapter = new JobListCommCareAppsAdapter(getContext()); + binding.rcCommCareApps.setLayoutManager(new LinearLayoutManager(getContext())); + binding.rcCommCareApps.setNestedScrollingEnabled(true); + binding.rcCommCareApps.setAdapter(adapter); + + } + + @Override + public void onDestroyView() { + super.onDestroyView(); + // Nullify the binding object to avoid memory leaks + binding = null; + } +} diff --git a/app/src/org/commcare/fragments/connect/login_job_fragments/ConnectLoginConnectHomeAppsFragment.java b/app/src/org/commcare/fragments/connect/login_job_fragments/ConnectLoginConnectHomeAppsFragment.java new file mode 100644 index 0000000000..f24acfd5f3 --- /dev/null +++ b/app/src/org/commcare/fragments/connect/login_job_fragments/ConnectLoginConnectHomeAppsFragment.java @@ -0,0 +1,51 @@ +package org.commcare.fragments.connect.login_job_fragments; + +import android.os.Bundle; +import android.view.LayoutInflater; +import android.view.View; +import android.view.ViewGroup; + +import androidx.fragment.app.Fragment; +import androidx.recyclerview.widget.LinearLayoutManager; + +import org.commcare.adapters.JobListConnectHomeAppsAdapter; +import org.commcare.dalvik.databinding.FragmentConnectLoginCommcareHomeBinding; + +/** + * A simple {@link Fragment} subclass. + * Use the {@link ConnectLoginConnectHomeAppsFragment#newInstance} factory method to + * create an instance of this fragment. + */ +public class ConnectLoginConnectHomeAppsFragment extends Fragment { + + private FragmentConnectLoginCommcareHomeBinding binding; + private JobListConnectHomeAppsAdapter adapter; + + public static ConnectLoginConnectHomeAppsFragment newInstance() { + ConnectLoginConnectHomeAppsFragment fragment = new ConnectLoginConnectHomeAppsFragment(); + Bundle args = new Bundle(); + fragment.setArguments(args); + return fragment; + } + + @Override + public View onCreateView(LayoutInflater inflater, ViewGroup container, + Bundle savedInstanceState) { + binding = FragmentConnectLoginCommcareHomeBinding.inflate(inflater, container, false); + initRecyclerView(); + return binding.getRoot(); + } + + private void initRecyclerView() { + adapter = new JobListConnectHomeAppsAdapter(getContext()); + binding.rcConnectHomeApps.setLayoutManager(new LinearLayoutManager(getContext())); + binding.rcConnectHomeApps.setNestedScrollingEnabled(true); + binding.rcConnectHomeApps.setAdapter(adapter); + } + + @Override + public void onDestroyView() { + super.onDestroyView(); + binding = null; + } +} diff --git a/app/src/org/commcare/fragments/connect/login_job_fragments/ConnectLoginJobListBottomSheetFragment.java b/app/src/org/commcare/fragments/connect/login_job_fragments/ConnectLoginJobListBottomSheetFragment.java new file mode 100644 index 0000000000..534aec6e03 --- /dev/null +++ b/app/src/org/commcare/fragments/connect/login_job_fragments/ConnectLoginJobListBottomSheetFragment.java @@ -0,0 +1,144 @@ +package org.commcare.fragments.connect.login_job_fragments; + +import android.graphics.drawable.ColorDrawable; +import android.os.Bundle; +import android.view.LayoutInflater; +import android.view.MotionEvent; +import android.view.View; +import android.view.ViewGroup; + +import androidx.annotation.NonNull; +import androidx.annotation.Nullable; +import androidx.core.content.ContextCompat; +import androidx.recyclerview.widget.LinearLayoutManager; +import androidx.recyclerview.widget.RecyclerView; + +import com.google.android.material.bottomsheet.BottomSheetBehavior; +import com.google.android.material.bottomsheet.BottomSheetDialog; +import com.google.android.material.bottomsheet.BottomSheetDialogFragment; +import com.google.android.material.tabs.TabLayoutMediator; + +import org.commcare.adapters.JobListCombinedAdapter; +import org.commcare.adapters.JobListViewPagerAdapter; +import org.commcare.dalvik.R; +import org.commcare.dalvik.databinding.BottomsheetLoginJoblistBinding; +import org.commcare.testingModel.CommCareItem; +import org.commcare.testingModel.ConnectHomeItem; + +import java.util.ArrayList; +import java.util.List; + +public class ConnectLoginJobListBottomSheetFragment extends BottomSheetDialogFragment { + + private BottomsheetLoginJoblistBinding binding; + + public static ConnectLoginJobListBottomSheetFragment newInstance() { + return new ConnectLoginJobListBottomSheetFragment(); + } + + @Nullable + @Override + public View onCreateView(@NonNull LayoutInflater inflater, + @Nullable ViewGroup container, + @Nullable Bundle savedInstanceState) { + binding = BottomsheetLoginJoblistBinding.inflate(inflater, container, false); + binding.rootView.setBackgroundResource(R.drawable.connect_bottom_sheet_rounded_corners); + + handleViewVisibility(); + if (isAppsSeparated()) { + setupViewPager(); + } else { + setUpRecyclerView(); + } + return binding.getRoot(); + } + + @Override + public void onViewCreated(@NonNull View view, @Nullable Bundle savedInstanceState) { + super.onViewCreated(view, savedInstanceState); + customizeBottomSheetBackground(view); + } + + @Override + public void onDestroyView() { + super.onDestroyView(); + binding = null; + } + + private void setupViewPager() { + JobListViewPagerAdapter viewPagerAdapter = new JobListViewPagerAdapter(getActivity()); + viewPagerAdapter.add(new ConnectLoginConnectHomeAppsFragment(), "Connect Home"); + viewPagerAdapter.add(new ConnectLoginCommcareAppsFragment(), "CommCare App"); + + binding.viewPager.setAdapter(viewPagerAdapter); + new TabLayoutMediator(binding.tabLayout, binding.viewPager, + (tab, position) -> tab.setText(viewPagerAdapter.getPageTitle(position)) + ).attach(); + } + + private void setUpRecyclerView() { + // Initialize data + List items = new ArrayList<>(); + items.add(new CommCareItem("CommCare App 1", "Description for CommCare App 1")); + items.add(new ConnectHomeItem("Connect Home 1", "Address for Connect Home 1")); + items.add(new CommCareItem("CommCare App 2", "Description for CommCare App 2")); + items.add(new ConnectHomeItem("Connect Home 2", "Address for Connect Home 2")); + items.add(new ConnectHomeItem("Connect Home 2", "Address for Connect Home 2")); + items.add(new ConnectHomeItem("Connect Home 2", "Address for Connect Home 2")); + items.add(new CommCareItem("CommCare App 2", "Description for CommCare App 2")); + items.add(new ConnectHomeItem("Connect Home 2", "Address for Connect Home 2")); + items.add(new CommCareItem("CommCare App 2", "Description for CommCare App 2")); + + JobListCombinedAdapter adapter = new JobListCombinedAdapter(getContext(), items); + binding.rvJobListApps.setLayoutManager(new LinearLayoutManager(getContext())); + binding.rvJobListApps.setNestedScrollingEnabled(true); + binding.rvJobListApps.addOnItemTouchListener(new RecyclerView.OnItemTouchListener() { + @Override + public boolean onInterceptTouchEvent(@NonNull RecyclerView rv, @NonNull MotionEvent e) { + rv.getParent().requestDisallowInterceptTouchEvent(true); + return false; + } + + @Override + public void onTouchEvent(@NonNull RecyclerView rv, @NonNull MotionEvent e) { + + } + + @Override + public void onRequestDisallowInterceptTouchEvent(boolean disallowIntercept) { + + } + }); + + binding.rvJobListApps.setAdapter(adapter); + } + + private boolean isAppsSeparated() { + return false; + } + + private void handleViewVisibility() { + if (isAppsSeparated()) { + binding.llJobListTabSeparated.setVisibility(View.VISIBLE); + binding.rvJobListApps.setVisibility(View.GONE); + } else { + binding.llJobListTabSeparated.setVisibility(View.GONE); + binding.rvJobListApps.setVisibility(View.VISIBLE); + } + } + + private void customizeBottomSheetBackground(View view) { + view.getViewTreeObserver().addOnPreDrawListener(() -> { + BottomSheetDialog dialog = (BottomSheetDialog) getDialog(); + if (dialog != null) { + View bottomSheet = dialog.findViewById(com.google.android.material.R.id.design_bottom_sheet); + if (bottomSheet != null) { + bottomSheet.setBackground(new ColorDrawable( + ContextCompat.getColor(requireContext(), R.color.transparent) + )); + } + } + return true; + }); + } +} diff --git a/app/src/org/commcare/testingModel/CommCareItem.java b/app/src/org/commcare/testingModel/CommCareItem.java new file mode 100644 index 0000000000..62f34a6c96 --- /dev/null +++ b/app/src/org/commcare/testingModel/CommCareItem.java @@ -0,0 +1,22 @@ +package org.commcare.testingModel; + +// Model class for CommCare items +public class CommCareItem implements JobListItem { + private String title; + private String description; + + // Constructor + public CommCareItem(String title, String description) { + this.title = title; + this.description = description; + } + + // Getters + public String getTitle() { + return title; + } + + public String getDescription() { + return description; + } +} \ No newline at end of file diff --git a/app/src/org/commcare/testingModel/ConnectHomeItem.java b/app/src/org/commcare/testingModel/ConnectHomeItem.java new file mode 100644 index 0000000000..f29678dbc9 --- /dev/null +++ b/app/src/org/commcare/testingModel/ConnectHomeItem.java @@ -0,0 +1,21 @@ +package org.commcare.testingModel; + +public class ConnectHomeItem implements JobListItem { + private String name; + private String address; + + // Constructor + public ConnectHomeItem(String name, String address) { + this.name = name; + this.address = address; + } + + // Getters + public String getName() { + return name; + } + + public String getAddress() { + return address; + } +} \ No newline at end of file diff --git a/app/src/org/commcare/testingModel/JobListItem.java b/app/src/org/commcare/testingModel/JobListItem.java new file mode 100644 index 0000000000..7894dafd58 --- /dev/null +++ b/app/src/org/commcare/testingModel/JobListItem.java @@ -0,0 +1,5 @@ +package org.commcare.testingModel; + +public interface JobListItem { + // Common methods (if needed) +} \ No newline at end of file From c95bfe18aa2571634b708f1caf0c2751863bf066 Mon Sep 17 00:00:00 2001 From: Jay Panchal Date: Fri, 30 Aug 2024 12:30:14 +0530 Subject: [PATCH 02/11] CCCT-438 || Bottomsheet Joblist UI Working on get job list API call --- .../commcare/activities/LoginActivity.java | 51 +++++++++++++++++++ 1 file changed, 51 insertions(+) diff --git a/app/src/org/commcare/activities/LoginActivity.java b/app/src/org/commcare/activities/LoginActivity.java index a50a265dc4..33a66f76df 100644 --- a/app/src/org/commcare/activities/LoginActivity.java +++ b/app/src/org/commcare/activities/LoginActivity.java @@ -29,7 +29,11 @@ import org.commcare.android.database.app.models.UserKeyRecord; import org.commcare.android.database.connect.models.ConnectJobRecord; import org.commcare.android.database.global.models.ApplicationRecord; +import org.commcare.connect.ConnectDatabaseHelper; import org.commcare.connect.ConnectManager; +import org.commcare.connect.network.ApiConnect; +import org.commcare.connect.network.ConnectNetworkHelper; +import org.commcare.connect.network.IApiCallback; import org.commcare.dalvik.BuildConfig; import org.commcare.dalvik.R; import org.commcare.engine.resource.AppInstallStatus; @@ -62,11 +66,18 @@ import org.commcare.views.notifications.NotificationMessage; import org.commcare.views.notifications.NotificationMessageFactory; import org.commcare.views.notifications.NotificationMessageFactory.StockMessages; +import org.javarosa.core.io.StreamsUtil; import org.javarosa.core.services.Logger; import org.javarosa.core.services.locale.Localization; +import org.json.JSONArray; +import org.json.JSONException; +import java.io.IOException; +import java.io.InputStream; import java.util.ArrayList; import java.util.Date; +import java.util.List; +import java.util.Locale; /** * @author ctsims @@ -297,6 +308,7 @@ protected void onResume() { checkForSavedCredentials(); ConnectManager.setParent(this); + initiateJobListAPI(); } protected boolean checkForSeatedAppChange() { @@ -967,4 +979,43 @@ public void openJobListBottomSheet() { ConnectLoginJobListBottomSheetFragment connectLoginJobListBottomSheetFragment = ConnectLoginJobListBottomSheetFragment.newInstance(); connectLoginJobListBottomSheetFragment.show(getSupportFragmentManager(), "connectLoginJobListBottomSheetFragment"); } + + public void initiateJobListAPI() { + ApiConnect.getConnectOpportunities(LoginActivity.this, new IApiCallback() { + @Override + public void processSuccess(int responseCode, InputStream responseData) { + try { + String responseAsString = new String(StreamsUtil.inputStreamToByteArray(responseData)); + Log.e("DEBUG_TESTING", "processSuccess: " + responseAsString); + if (responseAsString.length() > 0) { + //Parse the JSON + JSONArray json = new JSONArray(responseAsString); + List jobs = new ArrayList<>(json.length()); + ConnectDatabaseHelper.storeJobs(LoginActivity.this, jobs, true); + } + } catch (IOException | JSONException e) { + Toast.makeText(LoginActivity.this, R.string.connect_job_list_api_failure, Toast.LENGTH_SHORT).show(); + Logger.exception("Parsing return from Opportunities request", e); + } + } + + @Override + public void processFailure(int responseCode, IOException e) { + Toast.makeText(LoginActivity.this, R.string.connect_job_list_api_failure, Toast.LENGTH_SHORT).show(); + Logger.log("ERROR", String.format(Locale.getDefault(), "Opportunities call failed: %d", responseCode)); + } + + @Override + public void processNetworkFailure() { + Toast.makeText(LoginActivity.this, R.string.recovery_network_unavailable, Toast.LENGTH_SHORT).show(); + Logger.log("ERROR", "Failed (network)"); + } + + @Override + public void processOldApiError() { + Toast.makeText(LoginActivity.this, R.string.connect_job_list_api_failure, Toast.LENGTH_SHORT).show(); + ConnectNetworkHelper.showOutdatedApiError(LoginActivity.this); + } + }); + } } From d08042f7603fc2eccb8a851cce44c9ba2fbb16d9 Mon Sep 17 00:00:00 2001 From: Jay Panchal Date: Mon, 9 Sep 2024 13:40:35 +0530 Subject: [PATCH 03/11] Job list Bottomsheet UI Set combine job list fragment and solve bottomsheet issue --- app/res/layout/bottomsheet_login_joblist.xml | 19 +-- .../fragment_connect_login_combine_apps.xml | 15 ++ .../fragment_connect_login_commcare_apps.xml | 16 +- app/res/layout/item_install_commcare_apps.xml | 60 +++++++ .../layout/item_login_connect_home_apps.xml | 2 + .../commcare/activities/LoginActivity.java | 120 +++++++++++++- .../activities/LoginActivityUiController.java | 6 +- .../adapters/JobListCombinedAdapter.java | 72 +++++--- .../adapters/JobListCommCareAppsAdapter.java | 19 ++- .../JobListConnectHomeAppsAdapter.java | 45 ++++- .../connect/models/ConnectAppRecord.java | 18 ++ .../ConnectLoginCombineAppsFragment.java | 70 ++++++++ .../ConnectLoginCommcareAppsFragment.java | 23 ++- .../ConnectLoginConnectHomeAppsFragment.java | 22 ++- ...onnectLoginJobListBottomSheetFragment.java | 146 ++++++++++------- .../connect/ConnectCombineJobListModel.java | 62 +++++++ .../connect/ConnectLoginJobListModel.java | 155 ++++++++++++++++++ 17 files changed, 748 insertions(+), 122 deletions(-) create mode 100644 app/res/layout/fragment_connect_login_combine_apps.xml create mode 100644 app/res/layout/item_install_commcare_apps.xml create mode 100644 app/src/org/commcare/fragments/connect/login_job_fragments/ConnectLoginCombineAppsFragment.java create mode 100644 app/src/org/commcare/models/connect/ConnectCombineJobListModel.java create mode 100644 app/src/org/commcare/models/connect/ConnectLoginJobListModel.java diff --git a/app/res/layout/bottomsheet_login_joblist.xml b/app/res/layout/bottomsheet_login_joblist.xml index 19b0ae2bcb..ac35f717de 100644 --- a/app/res/layout/bottomsheet_login_joblist.xml +++ b/app/res/layout/bottomsheet_login_joblist.xml @@ -1,10 +1,11 @@ - @@ -26,8 +27,12 @@ android:id="@+id/llJobListTabSeparated" android:layout_width="match_parent" android:layout_height="match_parent" + android:layout_marginTop="15dp" android:orientation="vertical" - android:visibility="visible"> + android:visibility="visible" + app:layout_constraintEnd_toEndOf="parent" + app:layout_constraintStart_toStartOf="parent" + app:layout_constraintTop_toBottomOf="@+id/view"> - - + diff --git a/app/res/layout/fragment_connect_login_combine_apps.xml b/app/res/layout/fragment_connect_login_combine_apps.xml new file mode 100644 index 0000000000..79467f891f --- /dev/null +++ b/app/res/layout/fragment_connect_login_combine_apps.xml @@ -0,0 +1,15 @@ + + + + + \ No newline at end of file diff --git a/app/res/layout/fragment_connect_login_commcare_apps.xml b/app/res/layout/fragment_connect_login_commcare_apps.xml index fd0978319b..9156e45990 100644 --- a/app/res/layout/fragment_connect_login_commcare_apps.xml +++ b/app/res/layout/fragment_connect_login_commcare_apps.xml @@ -2,14 +2,22 @@ android:layout_width="match_parent" android:layout_height="match_parent"> + + + android:paddingTop="16dp" /> \ No newline at end of file diff --git a/app/res/layout/item_install_commcare_apps.xml b/app/res/layout/item_install_commcare_apps.xml new file mode 100644 index 0000000000..6216a2b4f6 --- /dev/null +++ b/app/res/layout/item_install_commcare_apps.xml @@ -0,0 +1,60 @@ + + + + + + + + + + + + + \ No newline at end of file diff --git a/app/res/layout/item_login_connect_home_apps.xml b/app/res/layout/item_login_connect_home_apps.xml index ab514bb5bb..0708fbbced 100644 --- a/app/res/layout/item_login_connect_home_apps.xml +++ b/app/res/layout/item_login_connect_home_apps.xml @@ -49,11 +49,13 @@ app:layout_constraintTop_toBottomOf="@+id/tvTitle"> private String presetAppId; private boolean appLaunchedFromConnect; private boolean connectLaunchPerformed; + private List jobList; + private List traditionalJobList; @Override protected void onCreate(Bundle savedInstanceState) { @@ -306,9 +317,9 @@ protected void onResume() { uiController.updateConnectLoginState(); checkForSavedCredentials(); + initiateJobListAPI(); ConnectManager.setParent(this); - initiateJobListAPI(); } protected boolean checkForSeatedAppChange() { @@ -976,7 +987,7 @@ protected String getPresetAppId() { } public void openJobListBottomSheet() { - ConnectLoginJobListBottomSheetFragment connectLoginJobListBottomSheetFragment = ConnectLoginJobListBottomSheetFragment.newInstance(); + ConnectLoginJobListBottomSheetFragment connectLoginJobListBottomSheetFragment = ConnectLoginJobListBottomSheetFragment.newInstance(jobList,traditionalJobList); connectLoginJobListBottomSheetFragment.show(getSupportFragmentManager(), "connectLoginJobListBottomSheetFragment"); } @@ -986,14 +997,18 @@ public void initiateJobListAPI() { public void processSuccess(int responseCode, InputStream responseData) { try { String responseAsString = new String(StreamsUtil.inputStreamToByteArray(responseData)); - Log.e("DEBUG_TESTING", "processSuccess: " + responseAsString); if (responseAsString.length() > 0) { - //Parse the JSON JSONArray json = new JSONArray(responseAsString); List jobs = new ArrayList<>(json.length()); + for (int i = 0; i < json.length(); i++) { + JSONObject obj = (JSONObject) json.get(i); + jobs.add(ConnectJobRecord.fromJson(obj)); + } ConnectDatabaseHelper.storeJobs(LoginActivity.this, jobs, true); + setJobListData(jobs); } - } catch (IOException | JSONException e) { + } catch (IOException | JSONException | ParseException e) { + setJobListData(ConnectDatabaseHelper.getJobs(LoginActivity.this, -1, null)); Toast.makeText(LoginActivity.this, R.string.connect_job_list_api_failure, Toast.LENGTH_SHORT).show(); Logger.exception("Parsing return from Opportunities request", e); } @@ -1001,21 +1016,116 @@ public void processSuccess(int responseCode, InputStream responseData) { @Override public void processFailure(int responseCode, IOException e) { + setJobListData(ConnectDatabaseHelper.getJobs(LoginActivity.this, -1, null)); Toast.makeText(LoginActivity.this, R.string.connect_job_list_api_failure, Toast.LENGTH_SHORT).show(); Logger.log("ERROR", String.format(Locale.getDefault(), "Opportunities call failed: %d", responseCode)); } @Override public void processNetworkFailure() { + setJobListData(ConnectDatabaseHelper.getJobs(LoginActivity.this, -1, null)); Toast.makeText(LoginActivity.this, R.string.recovery_network_unavailable, Toast.LENGTH_SHORT).show(); Logger.log("ERROR", "Failed (network)"); } @Override public void processOldApiError() { + setJobListData(ConnectDatabaseHelper.getJobs(LoginActivity.this, -1, null)); Toast.makeText(LoginActivity.this, R.string.connect_job_list_api_failure, Toast.LENGTH_SHORT).show(); ConnectNetworkHelper.showOutdatedApiError(LoginActivity.this); } }); } + + private void setJobListData(List jobs) { + jobList = new ArrayList<>(); + + for (ConnectJobRecord job : jobs) { + storeTraditionalApp(job); + + int jobStatus = job.getStatus(); + boolean isLearnAppInstalled = ConnectManager.isAppInstalled(job.getLearnAppInfo().getAppId()); + boolean isDeliverAppInstalled = ConnectManager.isAppInstalled(job.getDeliveryAppInfo().getAppId()); + + switch (jobStatus) { + case STATUS_AVAILABLE_NEW, STATUS_AVAILABLE: + jobList.add(storeJobListData( + job.getTitle(), + job.getJobId(), + job.getProjectStartDate(), + job.getDescription(), + job.getOrganization(), + false, + true, + false, + false + )); + break; + + case STATUS_LEARNING: + jobList.add(storeJobListData( + job.getLearnAppInfo().getName(), + job.getLearnAppInfo().getJobId(), + job.getProjectStartDate(), + job.getLearnAppInfo().getDescription(), + job.getLearnAppInfo().getOrganization(), + isLearnAppInstalled, + false, + true, + false + )); + break; + + case STATUS_DELIVERING: + jobList.add(storeJobListData( + job.getLearnAppInfo().getName(), + job.getLearnAppInfo().getJobId(), + job.getProjectStartDate(), + job.getLearnAppInfo().getDescription(), + job.getLearnAppInfo().getOrganization(), + isLearnAppInstalled, + false, + true, + false + )); + jobList.add(storeJobListData( + job.getDeliveryAppInfo().getName(), + job.getDeliveryAppInfo().getJobId(), + job.getProjectStartDate(), + job.getDeliveryAppInfo().getDescription(), + job.getDeliveryAppInfo().getOrganization(), + isDeliverAppInstalled, + false, + false, + true + )); + break; + + default: + break; + } + } + } + + private void storeTraditionalApp(ConnectJobRecord job) { + traditionalJobList = new ArrayList<>(); + ConnectAppRecord appRecord = ConnectDatabaseHelper.getAppRecord(LoginActivity.this, String.valueOf(job.getJobId())); + if (appRecord == null) { + traditionalJobList.add(storeJobListData( + job.getDeliveryAppInfo().getName(), + job.getDeliveryAppInfo().getJobId(), + job.getProjectStartDate(), + job.getDescription(), + job.getOrganization(), + true, + false, + false, + false + )); + } + } + + private ConnectLoginJobListModel storeJobListData(String name, int id, Date date, String description, String organization, boolean isAppInstalled, boolean isNew, boolean isLeaningApp, boolean isDeliveryApp) { + return new ConnectLoginJobListModel(name, id, date, description, organization, isAppInstalled, isNew, isLeaningApp, isDeliveryApp); + } } diff --git a/app/src/org/commcare/activities/LoginActivityUiController.java b/app/src/org/commcare/activities/LoginActivityUiController.java index fde2c0858e..ce6aa9e7e9 100644 --- a/app/src/org/commcare/activities/LoginActivityUiController.java +++ b/app/src/org/commcare/activities/LoginActivityUiController.java @@ -6,6 +6,7 @@ import android.text.Editable; import android.text.InputType; import android.text.TextWatcher; +import android.util.Log; import android.view.View; import android.view.inputmethod.EditorInfo; import android.widget.ArrayAdapter; @@ -221,7 +222,10 @@ public void refreshView() { // Decide whether or not to show the app selection spinner based upon # of usable apps ArrayList readyApps = MultipleAppsUtil.getUsableAppRecords(); - + /*Log.e("DEBUG_TESTING", "refreshView: "+readyApps.size()); + for(int i = 0 ; i < readyApps.size() ; i++){ + Log.e("DEBUG_TESTING", "refreshView: "+readyApps.get(i).getDisplayName()); + }*/ ApplicationRecord presetAppRecord = getPresetAppRecord(readyApps); boolean noApps = readyApps.isEmpty(); setLoginInputsVisibility(!noApps); diff --git a/app/src/org/commcare/adapters/JobListCombinedAdapter.java b/app/src/org/commcare/adapters/JobListCombinedAdapter.java index d0c7482245..b6987e1123 100644 --- a/app/src/org/commcare/adapters/JobListCombinedAdapter.java +++ b/app/src/org/commcare/adapters/JobListCombinedAdapter.java @@ -5,22 +5,24 @@ import android.view.ViewGroup; import androidx.annotation.NonNull; +import androidx.core.content.ContextCompat; import androidx.recyclerview.widget.RecyclerView; +import org.commcare.dalvik.R; import org.commcare.dalvik.databinding.ItemLoginCommcareAppsBinding; import org.commcare.dalvik.databinding.ItemLoginConnectHomeAppsBinding; -import org.commcare.testingModel.CommCareItem; +import org.commcare.models.connect.ConnectCombineJobListModel; import java.util.List; public class JobListCombinedAdapter extends RecyclerView.Adapter { - private static final int VIEW_TYPE_COMMCARE = 0; - private static final int VIEW_TYPE_CONNECT_HOME = 1; - private List items; // Your data source - private Context mContext; + public static final int VIEW_TYPE_COMMCARE = 0; + public static final int VIEW_TYPE_CONNECT_HOME = 1; + private final List items; + private final Context mContext; - public JobListCombinedAdapter(Context context, List items) { + public JobListCombinedAdapter(Context context, List items) { this.mContext = context; this.items = items; } @@ -31,32 +33,26 @@ public RecyclerView.ViewHolder onCreateViewHolder(@NonNull ViewGroup parent, int LayoutInflater inflater = LayoutInflater.from(parent.getContext()); if (viewType == VIEW_TYPE_COMMCARE) { - ItemLoginCommcareAppsBinding binding = ItemLoginCommcareAppsBinding.inflate(inflater, parent, false); - return new CommCareViewHolder(binding); + return new CommCareViewHolder(ItemLoginCommcareAppsBinding.inflate(inflater, parent, false)); } else { - ItemLoginConnectHomeAppsBinding binding = ItemLoginConnectHomeAppsBinding.inflate(inflater, parent, false); - return new ConnectHomeViewHolder(binding); + return new ConnectHomeViewHolder(ItemLoginConnectHomeAppsBinding.inflate(inflater, parent, false)); } } @Override public void onBindViewHolder(@NonNull RecyclerView.ViewHolder holder, int position) { - int viewType = getItemViewType(position); + ConnectCombineJobListModel item = items.get(position); - if (viewType == VIEW_TYPE_COMMCARE) { - // Bind data for CommCareViewHolder - CommCareViewHolder viewHolder = (CommCareViewHolder) holder; - viewHolder.bind(); - } else { - // Bind data for ConnectHomeViewHolder - ConnectHomeViewHolder viewHolder = (ConnectHomeViewHolder) holder; - viewHolder.bind(); + if (holder instanceof CommCareViewHolder) { + ((CommCareViewHolder) holder).bind(item.getConnectLoginJobListModel().getName()); + } else if (holder instanceof ConnectHomeViewHolder) { + ((ConnectHomeViewHolder) holder).bind(mContext, item); } } @Override public int getItemViewType(int position) { - return items.get(position) instanceof CommCareItem ? VIEW_TYPE_COMMCARE : VIEW_TYPE_CONNECT_HOME; + return items.get(position).getListType() == VIEW_TYPE_COMMCARE ? VIEW_TYPE_COMMCARE : VIEW_TYPE_CONNECT_HOME; } @Override @@ -72,9 +68,12 @@ public CommCareViewHolder(ItemLoginCommcareAppsBinding binding) { this.binding = binding; } - public void bind() {} + public void bind(String name) { + binding.tvTitle.setText(name); + } } + // Applying SRP - ConnectHomeViewHolder only handles Connect Home item binding logic static class ConnectHomeViewHolder extends RecyclerView.ViewHolder { private final ItemLoginConnectHomeAppsBinding binding; @@ -83,6 +82,33 @@ public ConnectHomeViewHolder(ItemLoginConnectHomeAppsBinding binding) { this.binding = binding; } - public void bind() {} + public void bind(Context context, ConnectCombineJobListModel item) { + binding.tvTitle.setText(item.getConnectLoginJobListModel().getName()); + configureJobType(context, item); + } + + private void configureJobType(Context context, ConnectCombineJobListModel item) { + if (item.getConnectLoginJobListModel().isNew()) { + setJobType(context, R.drawable.connect_rounded_corner_orange_yellow, + "New Opportunity", R.drawable.ic_connect_new_opportunity, + R.color.connect_yellowish_orange_color); + } else if (item.getConnectLoginJobListModel().isLeaningApp()) { + setJobType(context, R.drawable.connect_rounded_corner_teslish_blue, + "Learn", R.drawable.ic_connect_learning, + R.color.connect_blue_color); + } else if (item.getConnectLoginJobListModel().isDeliveryApp()) { + setJobType(context, R.drawable.connect_rounded_corner_light_green, + "Delivery", R.drawable.ic_connect_delivery, + R.color.connect_green); + } + } + + private void setJobType(Context context, int backgroundResId, String jobTypeText, + int iconResId, int textColorResId) { + binding.llOpportunity.setBackground(ContextCompat.getDrawable(context, backgroundResId)); + binding.tvJobType.setText(jobTypeText); + binding.imgJobType.setImageDrawable(ContextCompat.getDrawable(context, iconResId)); + binding.tvJobType.setTextColor(ContextCompat.getColor(context, textColorResId)); + } } -} +} \ No newline at end of file diff --git a/app/src/org/commcare/adapters/JobListCommCareAppsAdapter.java b/app/src/org/commcare/adapters/JobListCommCareAppsAdapter.java index 31a036ff27..feec45aafc 100644 --- a/app/src/org/commcare/adapters/JobListCommCareAppsAdapter.java +++ b/app/src/org/commcare/adapters/JobListCommCareAppsAdapter.java @@ -8,14 +8,18 @@ import androidx.recyclerview.widget.RecyclerView; import org.commcare.dalvik.databinding.ItemLoginCommcareAppsBinding; -import org.commcare.dalvik.databinding.ItemLoginConnectHomeAppsBinding; +import org.commcare.models.connect.ConnectLoginJobListModel; + +import java.util.ArrayList; public class JobListCommCareAppsAdapter extends RecyclerView.Adapter { - private Context mContext; + private final Context mContext; + private final ArrayList traditionalJobList; - public JobListCommCareAppsAdapter(Context context) { + public JobListCommCareAppsAdapter(Context context, ArrayList traditionalJobList) { this.mContext = context; + this.traditionalJobList = traditionalJobList; } @NonNull @@ -29,13 +33,12 @@ public ViewHolder onCreateViewHolder(@NonNull ViewGroup parent, int viewType) { @Override public void onBindViewHolder(@NonNull ViewHolder holder, int position) { - // Bind data to each item view -// String item = items.get(position); + holder.bind(mContext, traditionalJobList.get(position)); } @Override public int getItemCount() { - return 15; + return traditionalJobList.size(); } public static class ViewHolder extends RecyclerView.ViewHolder { @@ -45,5 +48,9 @@ public ViewHolder(ItemLoginCommcareAppsBinding binding) { super(binding.getRoot()); this.binding = binding; } + + public void bind(Context mContext, ConnectLoginJobListModel connectLoginJobListModel) { + binding.tvTitle.setText(connectLoginJobListModel.getName()); + } } } diff --git a/app/src/org/commcare/adapters/JobListConnectHomeAppsAdapter.java b/app/src/org/commcare/adapters/JobListConnectHomeAppsAdapter.java index 8882292430..5fc1533c3f 100644 --- a/app/src/org/commcare/adapters/JobListConnectHomeAppsAdapter.java +++ b/app/src/org/commcare/adapters/JobListConnectHomeAppsAdapter.java @@ -5,16 +5,23 @@ import android.view.ViewGroup; import androidx.annotation.NonNull; +import androidx.core.content.ContextCompat; import androidx.recyclerview.widget.RecyclerView; +import org.commcare.dalvik.R; import org.commcare.dalvik.databinding.ItemLoginConnectHomeAppsBinding; +import org.commcare.models.connect.ConnectLoginJobListModel; + +import java.util.ArrayList; public class JobListConnectHomeAppsAdapter extends RecyclerView.Adapter { - private Context mContext; + private final Context mContext; + private final ArrayList jobList; - public JobListConnectHomeAppsAdapter(Context context) { + public JobListConnectHomeAppsAdapter(Context context, ArrayList jobList) { this.mContext = context; + this.jobList = jobList; } @NonNull @@ -28,13 +35,12 @@ public ViewHolder onCreateViewHolder(@NonNull ViewGroup parent, int viewType) { @Override public void onBindViewHolder(@NonNull ViewHolder holder, int position) { - // Bind data to each item view -// String item = items.get(position); + holder.bind(mContext, jobList.get(position)); } @Override public int getItemCount() { - return 15; + return jobList.size(); } public static class ViewHolder extends RecyclerView.ViewHolder { @@ -44,5 +50,34 @@ public ViewHolder(ItemLoginConnectHomeAppsBinding binding) { super(binding.getRoot()); this.binding = binding; } + + public void bind(Context mContext, ConnectLoginJobListModel connectLoginJobListModel) { + binding.tvTitle.setText(connectLoginJobListModel.getName()); + configureJobType(mContext, connectLoginJobListModel); + } + + private void configureJobType(Context context, ConnectLoginJobListModel item) { + if (item.isNew()) { + setJobType(context, R.drawable.connect_rounded_corner_orange_yellow, + "New Opportunity", R.drawable.ic_connect_new_opportunity, + R.color.connect_yellowish_orange_color); + } else if (item.isLeaningApp()) { + setJobType(context, R.drawable.connect_rounded_corner_teslish_blue, + "Learn", R.drawable.ic_connect_learning, + R.color.connect_blue_color); + } else if (item.isDeliveryApp()) { + setJobType(context, R.drawable.connect_rounded_corner_light_green, + "Delivery", R.drawable.ic_connect_delivery, + R.color.connect_green); + } + } + + private void setJobType(Context context, int backgroundResId, String jobTypeText, + int iconResId, int textColorResId) { + binding.llOpportunity.setBackground(ContextCompat.getDrawable(context, backgroundResId)); + binding.tvJobType.setText(jobTypeText); + binding.imgJobType.setImageDrawable(ContextCompat.getDrawable(context, iconResId)); + binding.tvJobType.setTextColor(ContextCompat.getColor(context, textColorResId)); + } } } diff --git a/app/src/org/commcare/android/database/connect/models/ConnectAppRecord.java b/app/src/org/commcare/android/database/connect/models/ConnectAppRecord.java index 1d2548f313..5ff80cbb4a 100644 --- a/app/src/org/commcare/android/database/connect/models/ConnectAppRecord.java +++ b/app/src/org/commcare/android/database/connect/models/ConnectAppRecord.java @@ -93,6 +93,8 @@ public static ConnectAppRecord fromJson(JSONObject json, int jobId, boolean isLe public boolean getIsLearning() { return isLearning; } public int getJobId() { return jobId; } public void setJobId(int jobId) { this.jobId = jobId; } + public String getName() { return name; } + public void setName(String name) { this.name = name; } public String getAppId() { return appId; } public String getDomain() { return domain; } @@ -102,4 +104,20 @@ public static ConnectAppRecord fromJson(JSONObject json, int jobId, boolean isLe public String getInstallUrl() { return installUrl; } public void setLearnModules(List modules) { learnModules = modules; } public void setLastUpdate(Date lastUpdate) { this.lastUpdate = lastUpdate; } + + public String getDescription() { + return description; + } + + public void setDescription(String description) { + this.description = description; + } + + public String getOrganization() { + return organization; + } + + public void setOrganization(String organization) { + this.organization = organization; + } } diff --git a/app/src/org/commcare/fragments/connect/login_job_fragments/ConnectLoginCombineAppsFragment.java b/app/src/org/commcare/fragments/connect/login_job_fragments/ConnectLoginCombineAppsFragment.java new file mode 100644 index 0000000000..ed18c4a9ef --- /dev/null +++ b/app/src/org/commcare/fragments/connect/login_job_fragments/ConnectLoginCombineAppsFragment.java @@ -0,0 +1,70 @@ +package org.commcare.fragments.connect.login_job_fragments; + +import android.os.Bundle; +import android.os.Parcelable; +import android.view.LayoutInflater; +import android.view.View; +import android.view.ViewGroup; + +import androidx.annotation.NonNull; +import androidx.fragment.app.Fragment; +import androidx.recyclerview.widget.LinearLayoutManager; + +import org.commcare.adapters.JobListCombinedAdapter; +import org.commcare.adapters.JobListCommCareAppsAdapter; +import org.commcare.dalvik.databinding.FragmentConnectLoginCombineAppsBinding; +import org.commcare.dalvik.databinding.FragmentConnectLoginCommcareAppsBinding; +import org.commcare.models.connect.ConnectCombineJobListModel; +import org.commcare.models.connect.ConnectLoginJobListModel; + +import java.util.ArrayList; +import java.util.List; + +/** + * A simple {@link Fragment} subclass. + * Use the {@link ConnectLoginCombineAppsFragment#newInstance} factory method to + * create an instance of this fragment. + */ +public class ConnectLoginCombineAppsFragment extends Fragment { + + private FragmentConnectLoginCombineAppsBinding binding; + private static final String ARG_COMBINE_JOB_LIST = "combine_job_list"; + private ArrayList traditionalJobList; + + public static ConnectLoginCombineAppsFragment newInstance(List traditionalJobList) { + ConnectLoginCombineAppsFragment fragment = new ConnectLoginCombineAppsFragment(); + Bundle args = new Bundle(); + args.putParcelableArrayList(ARG_COMBINE_JOB_LIST, (ArrayList) traditionalJobList); + fragment.setArguments(args); + return fragment; + } + + @Override + public View onCreateView(@NonNull LayoutInflater inflater, ViewGroup container, + Bundle savedInstanceState) { + binding = FragmentConnectLoginCombineAppsBinding.inflate(inflater, container, false); + + // Retrieve the job list from the arguments + if (getArguments() != null) { + traditionalJobList = getArguments().getParcelableArrayList(ARG_COMBINE_JOB_LIST); + } + + initRecyclerView(); + return binding.getRoot(); + } + + private void initRecyclerView() { + JobListCombinedAdapter adapter = new JobListCombinedAdapter(getContext(), traditionalJobList); + binding.rcCombineApps.setLayoutManager(new LinearLayoutManager(getContext())); + binding.rcCombineApps.setNestedScrollingEnabled(true); + binding.rcCombineApps.setAdapter(adapter); + + } + + @Override + public void onDestroyView() { + super.onDestroyView(); + // Nullify the binding object to avoid memory leaks + binding = null; + } +} diff --git a/app/src/org/commcare/fragments/connect/login_job_fragments/ConnectLoginCommcareAppsFragment.java b/app/src/org/commcare/fragments/connect/login_job_fragments/ConnectLoginCommcareAppsFragment.java index a34d40863f..4f4fb88737 100644 --- a/app/src/org/commcare/fragments/connect/login_job_fragments/ConnectLoginCommcareAppsFragment.java +++ b/app/src/org/commcare/fragments/connect/login_job_fragments/ConnectLoginCommcareAppsFragment.java @@ -1,16 +1,21 @@ package org.commcare.fragments.connect.login_job_fragments; import android.os.Bundle; +import android.os.Parcelable; import android.view.LayoutInflater; import android.view.View; import android.view.ViewGroup; +import androidx.annotation.NonNull; import androidx.fragment.app.Fragment; import androidx.recyclerview.widget.LinearLayoutManager; import org.commcare.adapters.JobListCommCareAppsAdapter; -import org.commcare.adapters.JobListConnectHomeAppsAdapter; import org.commcare.dalvik.databinding.FragmentConnectLoginCommcareAppsBinding; +import org.commcare.models.connect.ConnectLoginJobListModel; + +import java.util.ArrayList; +import java.util.List; /** * A simple {@link Fragment} subclass. @@ -20,25 +25,33 @@ public class ConnectLoginCommcareAppsFragment extends Fragment { private FragmentConnectLoginCommcareAppsBinding binding; - private JobListCommCareAppsAdapter adapter; + private static final String ARG_TRADITIONAL_JOB_LIST = "traditional_job_list"; + private ArrayList traditionalJobList; - public static ConnectLoginCommcareAppsFragment newInstance() { + public static ConnectLoginCommcareAppsFragment newInstance(List traditionalJobList) { ConnectLoginCommcareAppsFragment fragment = new ConnectLoginCommcareAppsFragment(); Bundle args = new Bundle(); + args.putParcelableArrayList(ARG_TRADITIONAL_JOB_LIST, (ArrayList) traditionalJobList); fragment.setArguments(args); return fragment; } @Override - public View onCreateView(LayoutInflater inflater, ViewGroup container, + public View onCreateView(@NonNull LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) { binding = FragmentConnectLoginCommcareAppsBinding.inflate(inflater, container, false); + + // Retrieve the job list from the arguments + if (getArguments() != null) { + traditionalJobList = getArguments().getParcelableArrayList(ARG_TRADITIONAL_JOB_LIST); + } + initRecyclerView(); return binding.getRoot(); } private void initRecyclerView() { - adapter = new JobListCommCareAppsAdapter(getContext()); + JobListCommCareAppsAdapter adapter = new JobListCommCareAppsAdapter(getContext(), traditionalJobList); binding.rcCommCareApps.setLayoutManager(new LinearLayoutManager(getContext())); binding.rcCommCareApps.setNestedScrollingEnabled(true); binding.rcCommCareApps.setAdapter(adapter); diff --git a/app/src/org/commcare/fragments/connect/login_job_fragments/ConnectLoginConnectHomeAppsFragment.java b/app/src/org/commcare/fragments/connect/login_job_fragments/ConnectLoginConnectHomeAppsFragment.java index f24acfd5f3..e29e6691ef 100644 --- a/app/src/org/commcare/fragments/connect/login_job_fragments/ConnectLoginConnectHomeAppsFragment.java +++ b/app/src/org/commcare/fragments/connect/login_job_fragments/ConnectLoginConnectHomeAppsFragment.java @@ -1,15 +1,21 @@ package org.commcare.fragments.connect.login_job_fragments; import android.os.Bundle; +import android.os.Parcelable; import android.view.LayoutInflater; import android.view.View; import android.view.ViewGroup; +import androidx.annotation.NonNull; import androidx.fragment.app.Fragment; import androidx.recyclerview.widget.LinearLayoutManager; import org.commcare.adapters.JobListConnectHomeAppsAdapter; import org.commcare.dalvik.databinding.FragmentConnectLoginCommcareHomeBinding; +import org.commcare.models.connect.ConnectLoginJobListModel; + +import java.util.ArrayList; +import java.util.List; /** * A simple {@link Fragment} subclass. @@ -18,26 +24,34 @@ */ public class ConnectLoginConnectHomeAppsFragment extends Fragment { + private static final String ARG_JOB_LIST = "job_list"; private FragmentConnectLoginCommcareHomeBinding binding; - private JobListConnectHomeAppsAdapter adapter; + private ArrayList jobList; - public static ConnectLoginConnectHomeAppsFragment newInstance() { + public static ConnectLoginConnectHomeAppsFragment newInstance(List jobList) { ConnectLoginConnectHomeAppsFragment fragment = new ConnectLoginConnectHomeAppsFragment(); Bundle args = new Bundle(); + args.putParcelableArrayList(ARG_JOB_LIST, (ArrayList) jobList); fragment.setArguments(args); return fragment; } @Override - public View onCreateView(LayoutInflater inflater, ViewGroup container, + public View onCreateView(@NonNull LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) { binding = FragmentConnectLoginCommcareHomeBinding.inflate(inflater, container, false); + + // Retrieve the job list from the arguments + if (getArguments() != null) { + jobList = getArguments().getParcelableArrayList(ARG_JOB_LIST); + } + initRecyclerView(); return binding.getRoot(); } private void initRecyclerView() { - adapter = new JobListConnectHomeAppsAdapter(getContext()); + JobListConnectHomeAppsAdapter adapter = new JobListConnectHomeAppsAdapter(getContext(), jobList); binding.rcConnectHomeApps.setLayoutManager(new LinearLayoutManager(getContext())); binding.rcConnectHomeApps.setNestedScrollingEnabled(true); binding.rcConnectHomeApps.setAdapter(adapter); diff --git a/app/src/org/commcare/fragments/connect/login_job_fragments/ConnectLoginJobListBottomSheetFragment.java b/app/src/org/commcare/fragments/connect/login_job_fragments/ConnectLoginJobListBottomSheetFragment.java index 534aec6e03..f793f95ae7 100644 --- a/app/src/org/commcare/fragments/connect/login_job_fragments/ConnectLoginJobListBottomSheetFragment.java +++ b/app/src/org/commcare/fragments/connect/login_job_fragments/ConnectLoginJobListBottomSheetFragment.java @@ -3,17 +3,14 @@ import android.graphics.drawable.ColorDrawable; import android.os.Bundle; import android.view.LayoutInflater; -import android.view.MotionEvent; import android.view.View; import android.view.ViewGroup; import androidx.annotation.NonNull; import androidx.annotation.Nullable; import androidx.core.content.ContextCompat; -import androidx.recyclerview.widget.LinearLayoutManager; import androidx.recyclerview.widget.RecyclerView; -import com.google.android.material.bottomsheet.BottomSheetBehavior; import com.google.android.material.bottomsheet.BottomSheetDialog; import com.google.android.material.bottomsheet.BottomSheetDialogFragment; import com.google.android.material.tabs.TabLayoutMediator; @@ -22,8 +19,8 @@ import org.commcare.adapters.JobListViewPagerAdapter; import org.commcare.dalvik.R; import org.commcare.dalvik.databinding.BottomsheetLoginJoblistBinding; -import org.commcare.testingModel.CommCareItem; -import org.commcare.testingModel.ConnectHomeItem; +import org.commcare.models.connect.ConnectCombineJobListModel; +import org.commcare.models.connect.ConnectLoginJobListModel; import java.util.ArrayList; import java.util.List; @@ -31,25 +28,29 @@ public class ConnectLoginJobListBottomSheetFragment extends BottomSheetDialogFragment { private BottomsheetLoginJoblistBinding binding; - - public static ConnectLoginJobListBottomSheetFragment newInstance() { - return new ConnectLoginJobListBottomSheetFragment(); + private static final String ARG_JOB_LIST = "job_list"; + private static final String ARG_TRADITIONAL_JOB_LIST = "traditional_job_list"; + private List jobList; + private List traditionalJobList; + + public static ConnectLoginJobListBottomSheetFragment newInstance(List jobList, List traditionalJobList) { + ConnectLoginJobListBottomSheetFragment fragment = new ConnectLoginJobListBottomSheetFragment(); + Bundle args = new Bundle(); + args.putParcelableArrayList(ARG_JOB_LIST, new ArrayList<>(jobList)); + args.putParcelableArrayList(ARG_TRADITIONAL_JOB_LIST, new ArrayList<>(traditionalJobList)); + fragment.setArguments(args); + return fragment; } @Nullable @Override - public View onCreateView(@NonNull LayoutInflater inflater, - @Nullable ViewGroup container, - @Nullable Bundle savedInstanceState) { + public View onCreateView(@NonNull LayoutInflater inflater, @Nullable ViewGroup container, @Nullable Bundle savedInstanceState) { binding = BottomsheetLoginJoblistBinding.inflate(inflater, container, false); binding.rootView.setBackgroundResource(R.drawable.connect_bottom_sheet_rounded_corners); - handleViewVisibility(); - if (isAppsSeparated()) { - setupViewPager(); - } else { - setUpRecyclerView(); - } + retrieveArguments(); + setupUI(); + return binding.getRoot(); } @@ -65,10 +66,30 @@ public void onDestroyView() { binding = null; } + private void retrieveArguments() { + if (getArguments() != null) { + jobList = getArguments().getParcelableArrayList(ARG_JOB_LIST); + traditionalJobList = getArguments().getParcelableArrayList(ARG_TRADITIONAL_JOB_LIST); + } + } + + private void setupUI() { + if (isAppsSeparated()) { + setupViewPager(); + } else { + setupCombinedRecyclerView(); + } + } + + /** + * Setup ViewPager with tabs for separated job lists (Connect Home and CommCare App). + */ private void setupViewPager() { - JobListViewPagerAdapter viewPagerAdapter = new JobListViewPagerAdapter(getActivity()); - viewPagerAdapter.add(new ConnectLoginConnectHomeAppsFragment(), "Connect Home"); - viewPagerAdapter.add(new ConnectLoginCommcareAppsFragment(), "CommCare App"); + JobListViewPagerAdapter viewPagerAdapter = new JobListViewPagerAdapter(requireActivity()); + viewPagerAdapter.add(ConnectLoginConnectHomeAppsFragment.newInstance(jobList), "Connect Home"); + viewPagerAdapter.add(ConnectLoginCommcareAppsFragment.newInstance(traditionalJobList), "CommCare App"); + + configureRecyclerViewScrolling(); binding.viewPager.setAdapter(viewPagerAdapter); new TabLayoutMediator(binding.tabLayout, binding.viewPager, @@ -76,54 +97,63 @@ private void setupViewPager() { ).attach(); } - private void setUpRecyclerView() { - // Initialize data - List items = new ArrayList<>(); - items.add(new CommCareItem("CommCare App 1", "Description for CommCare App 1")); - items.add(new ConnectHomeItem("Connect Home 1", "Address for Connect Home 1")); - items.add(new CommCareItem("CommCare App 2", "Description for CommCare App 2")); - items.add(new ConnectHomeItem("Connect Home 2", "Address for Connect Home 2")); - items.add(new ConnectHomeItem("Connect Home 2", "Address for Connect Home 2")); - items.add(new ConnectHomeItem("Connect Home 2", "Address for Connect Home 2")); - items.add(new CommCareItem("CommCare App 2", "Description for CommCare App 2")); - items.add(new ConnectHomeItem("Connect Home 2", "Address for Connect Home 2")); - items.add(new CommCareItem("CommCare App 2", "Description for CommCare App 2")); - - JobListCombinedAdapter adapter = new JobListCombinedAdapter(getContext(), items); - binding.rvJobListApps.setLayoutManager(new LinearLayoutManager(getContext())); - binding.rvJobListApps.setNestedScrollingEnabled(true); - binding.rvJobListApps.addOnItemTouchListener(new RecyclerView.OnItemTouchListener() { - @Override - public boolean onInterceptTouchEvent(@NonNull RecyclerView rv, @NonNull MotionEvent e) { - rv.getParent().requestDisallowInterceptTouchEvent(true); - return false; - } + /** + * Setup RecyclerView with combined job lists if apps are not separated. + */ + private void setupCombinedRecyclerView() { + List combineAppsList = combineJobLists(); + JobListViewPagerAdapter viewPagerAdapter = new JobListViewPagerAdapter(requireActivity()); + viewPagerAdapter.add(ConnectLoginCombineAppsFragment.newInstance(combineAppsList), "Connect Home"); - @Override - public void onTouchEvent(@NonNull RecyclerView rv, @NonNull MotionEvent e) { + configureRecyclerViewScrolling(); - } + binding.viewPager.setAdapter(viewPagerAdapter); + handlePagerUI(); + } - @Override - public void onRequestDisallowInterceptTouchEvent(boolean disallowIntercept) { + private void handlePagerUI() { + binding.tabLayout.setVisibility(View.GONE); + binding.divider.setVisibility(View.GONE); + } - } - }); + /** + * Combine Connect Home and CommCare job lists into a single list. + * + * @return Combined list of jobs. + */ + private List combineJobLists() { + List combineAppsList = new ArrayList<>(); + combineAppsList.addAll(createCombinedList(jobList, JobListCombinedAdapter.VIEW_TYPE_CONNECT_HOME)); + combineAppsList.addAll(createCombinedList(traditionalJobList, JobListCombinedAdapter.VIEW_TYPE_COMMCARE)); + return combineAppsList; + } - binding.rvJobListApps.setAdapter(adapter); + /** + * Create a combined list of jobs with the specified view type. + * + * @param jobList The list of jobs to combine. + * @param listType The type of list (Connect Home or CommCare). + * @return A combined list of jobs with the specified view type. + */ + private List createCombinedList(List jobList, int listType) { + List combinedList = new ArrayList<>(); + for (ConnectLoginJobListModel job : jobList) { + combinedList.add(new ConnectCombineJobListModel(job, listType)); + } + return combinedList; } private boolean isAppsSeparated() { - return false; + return jobList.size() > 2 && traditionalJobList.size() > 2; } - private void handleViewVisibility() { - if (isAppsSeparated()) { - binding.llJobListTabSeparated.setVisibility(View.VISIBLE); - binding.rvJobListApps.setVisibility(View.GONE); - } else { - binding.llJobListTabSeparated.setVisibility(View.GONE); - binding.rvJobListApps.setVisibility(View.VISIBLE); + private void configureRecyclerViewScrolling() { + for (int i = 0; i < binding.viewPager.getChildCount(); i++) { + View child = binding.viewPager.getChildAt(i); + if (child instanceof RecyclerView) { + child.setNestedScrollingEnabled(false); + break; + } } } diff --git a/app/src/org/commcare/models/connect/ConnectCombineJobListModel.java b/app/src/org/commcare/models/connect/ConnectCombineJobListModel.java new file mode 100644 index 0000000000..07a6187268 --- /dev/null +++ b/app/src/org/commcare/models/connect/ConnectCombineJobListModel.java @@ -0,0 +1,62 @@ +package org.commcare.models.connect; + +import android.os.Parcel; +import android.os.Parcelable; + +public class ConnectCombineJobListModel implements Parcelable { + ConnectLoginJobListModel combineAppsList; + int listType; + + public ConnectCombineJobListModel() { + + } + + public ConnectCombineJobListModel(ConnectLoginJobListModel combineAppsList, int listType) { + this.combineAppsList = combineAppsList; + this.listType = listType; + } + + protected ConnectCombineJobListModel(Parcel in) { + combineAppsList = in.readParcelable(ConnectLoginJobListModel.class.getClassLoader()); + listType = in.readInt(); + } + + @Override + public void writeToParcel(Parcel dest, int flags) { + dest.writeParcelable(combineAppsList, flags); + dest.writeInt(listType); + } + + @Override + public int describeContents() { + return 0; + } + + public static final Creator CREATOR = new Creator() { + @Override + public ConnectCombineJobListModel createFromParcel(Parcel in) { + return new ConnectCombineJobListModel(in); + } + + @Override + public ConnectCombineJobListModel[] newArray(int size) { + return new ConnectCombineJobListModel[size]; + } + }; + + public ConnectLoginJobListModel getConnectLoginJobListModel() { + return combineAppsList; + } + + public void setConnectLoginJobListModel(ConnectLoginJobListModel combineAppsList) { + this.combineAppsList = combineAppsList; + } + + public int getListType() { + return listType; + } + + public void setListType(int listType) { + this.listType = listType; + } +} diff --git a/app/src/org/commcare/models/connect/ConnectLoginJobListModel.java b/app/src/org/commcare/models/connect/ConnectLoginJobListModel.java new file mode 100644 index 0000000000..ac2cbf2207 --- /dev/null +++ b/app/src/org/commcare/models/connect/ConnectLoginJobListModel.java @@ -0,0 +1,155 @@ +package org.commcare.models.connect; + +import android.os.Parcel; +import android.os.Parcelable; + +import java.util.Date; + +/** + * Model class for storing list item data + */ +public class ConnectLoginJobListModel implements Parcelable { + private String name; + private int id; + private Date date; + private String description; + private String organization; + private boolean isAppInstalled; + private boolean isNew; + private boolean isLeaningApp; + private boolean isDeliveryApp; + + // Constructor + public ConnectLoginJobListModel(String name, int id, Date date, String description, String organization, boolean isAppInstalled, boolean isNew, boolean isLeaningApp,boolean isDeliveryApp) { + this.name = name; + this.id = id; + this.date = date; + this.description = description; + this.organization = organization; + this.isAppInstalled = isAppInstalled; + this.isNew = isNew; + this.isLeaningApp = isLeaningApp; + this.isDeliveryApp = isDeliveryApp; + } + + // Default constructor + public ConnectLoginJobListModel() { + } + + protected ConnectLoginJobListModel(Parcel in) { + name = in.readString(); + id = in.readInt(); + description = in.readString(); + organization = in.readString(); + } + + @Override + public void writeToParcel(Parcel dest, int flags) { + dest.writeString(name); + dest.writeInt(id); + dest.writeString(description); + dest.writeString(organization); + } + + @Override + public int describeContents() { + return 0; + } + + public static final Creator CREATOR = new Creator<>() { + @Override + public ConnectLoginJobListModel createFromParcel(Parcel in) { + return new ConnectLoginJobListModel(in); + } + + @Override + public ConnectLoginJobListModel[] newArray(int size) { + return new ConnectLoginJobListModel[size]; + } + }; + + // Getters and Setters + public String getName() { + return name; + } + + public void setName(String name) { + this.name = name; + } + + public int getId() { + return id; + } + + public void setId(int id) { + this.id = id; + } + + public Date getDate() { + return date; + } + + public void setDate(Date date) { + this.date = date; + } + + public String getDescription() { + return description; + } + + public void setDescription(String description) { + this.description = description; + } + + public String getOrganization() { + return organization; + } + + public void setOrganization(String organization) { + this.organization = organization; + } + + public boolean isAppInstalled() { + return isAppInstalled; + } + + public void setAppInstalled(boolean appInstalled) { + isAppInstalled = appInstalled; + } + + public boolean isNew() { + return isNew; + } + + public void setNew(boolean aNew) { + isNew = aNew; + } + + public boolean isLeaningApp() { + return isLeaningApp; + } + + public void setLeaningApp(boolean leaningApp) { + isLeaningApp = leaningApp; + } + + public boolean isDeliveryApp() { + return isDeliveryApp; + } + + public void setDeliveryApp(boolean deliveryApp) { + isDeliveryApp = deliveryApp; + } + + // Optionally, override toString for easy logging or display + @Override + public String toString() { + return "AddListItem{" + + "name='" + name + '\'' + + ", id=" + id + + ", date=" + date + + ", description='" + description + '\'' + + ", organization='" + organization + '\'' + + '}'; + } +} From bb68d452f41b15cafc3fefe9469e0a2f14ec72b1 Mon Sep 17 00:00:00 2001 From: Jay Panchal Date: Tue, 10 Sep 2024 10:11:40 +0530 Subject: [PATCH 04/11] Login screen integration Working on login screen integration --- .../connect_login_new_job_pup_icon.png | Bin 0 -> 921 bytes app/res/layout/temp_login.xml | 623 ++++++++++-------- app/res/values/colors.xml | 1 + .../activities/LoginActivityUiController.java | 110 ++-- ...onnectLoginJobListBottomSheetFragment.java | 3 +- .../views/connect/ConnectEditText.java | 28 +- 6 files changed, 418 insertions(+), 347 deletions(-) create mode 100644 app/res/drawable/connect_login_new_job_pup_icon.png diff --git a/app/res/drawable/connect_login_new_job_pup_icon.png b/app/res/drawable/connect_login_new_job_pup_icon.png new file mode 100644 index 0000000000000000000000000000000000000000..ebb81d47477447a42ddbe041904a0f471cb4a6b1 GIT binary patch literal 921 zcmV;K17`e*P)-bpyj@Bgf0uUm&71knyxDm(2mwJ0BTg>a87JM+ZGbw+m@}x*DXkfD zQK>!8qf{8+d$c#XfukSXAbQc)@T)s*>3n!lBMg)c27%|n=lw{2spszN4AetFJkBOB z4wJ?~I0cFYvl_d+`SG}j)FdEY@4C_33aJem07IC`I=MHsqESU4HFvK=fxg)&qV;ay{dc=&zoVqWQcX{X3W?o+o(xE&b*OfKaNBz+Ynn-1SH{_X}pp|`b*FC z@^dK%B=nhL`Y6oC`~8f21XFBy0(^i7 z;~vnI?6Jv(HTFv`s4KDDCGdfG&i?j6KuAP90}pL7hB>5@y>V5@!v&il0d)oOyov-z zf{3o#WWri?^JkCkHX-nE66yp;V$`^0Xs}iKT z3GnV2+p43(zZHh`mQ4r|KXE8u!U-XJP}}bX44EypmX3Z6kOwndkgVaX1b==B+2bb{ z?M!Z{p~ue(T<6!V3i)Euh|@tLAu`;+PWxR(3e>vviKW{x7AdUobv)=tg0(*ZkLKCT zq!g%fjbM*|az?)| - - - - - - - - - - - - - - - - - - - - - -