From 68cd1ff28c25a2056c5b5229336fb9e549830513 Mon Sep 17 00:00:00 2001 From: Torsten Grote Date: Mon, 21 Dec 2015 15:47:18 -0200 Subject: [PATCH 1/3] New Conversation View in XML It now uses conversation bubbles in alternating colors and vector drawables to indicate message state. The conversation bubbles have been taken from Telegram and can be replaced by a UX designer later. This commit also addresses #9, because message text can now be selected and copied. This is done by using android:textIsSelectable="true" which only works for API level 11 or higher. If we want copy and paste on lower API levels, additional measures have to be implemented. --- .../res/drawable-hdpi/message_delivered.png | Bin 479 -> 0 bytes .../res/drawable-hdpi/message_sent.png | Bin 284 -> 0 bytes .../res/drawable-hdpi/message_stored.png | Bin 323 -> 0 bytes briar-android/res/drawable-hdpi/msg_in.9.png | Bin 0 -> 957 bytes briar-android/res/drawable-hdpi/msg_out.9.png | Bin 0 -> 1871 bytes .../res/drawable-hdpi/social_send_now.png | Bin 1680 -> 0 bytes .../res/drawable-mdpi/message_delivered.png | Bin 313 -> 0 bytes .../res/drawable-mdpi/message_sent.png | Bin 238 -> 0 bytes .../res/drawable-mdpi/message_stored.png | Bin 237 -> 0 bytes briar-android/res/drawable-mdpi/msg_in.9.png | Bin 0 -> 669 bytes briar-android/res/drawable-mdpi/msg_out.9.png | Bin 0 -> 1693 bytes .../res/drawable-mdpi/social_send_now.png | Bin 1097 -> 0 bytes .../res/drawable-xhdpi/message_delivered.png | Bin 627 -> 0 bytes .../res/drawable-xhdpi/message_sent.png | Bin 392 -> 0 bytes .../res/drawable-xhdpi/message_stored.png | Bin 443 -> 0 bytes .../res/drawable-xhdpi/social_send_now.png | Bin 2416 -> 0 bytes .../res/drawable-xxhdpi/message_stored.png | Bin 683 -> 0 bytes .../res/drawable-xxhdpi/msg_in.9.png | Bin 0 -> 2231 bytes .../res/drawable-xxhdpi/msg_out.9.png | Bin 0 -> 3076 bytes .../res/drawable-xxxhdpi/message_stored.png | Bin 969 -> 0 bytes .../res/drawable/message_delivered.xml | 5 + briar-android/res/drawable/message_sent.xml | 5 + briar-android/res/drawable/message_stored.xml | 5 + .../res/drawable/social_send_now.xml | 5 + .../res/layout/activity_conversation.xml | 16 ++-- briar-android/res/layout/list_item_msg_in.xml | 42 ++++++++ .../res/layout/list_item_msg_out.xml | 54 +++++++++++ briar-android/res/values/color.xml | 1 - .../android/contact/ConversationActivity.java | 9 +- .../android/contact/ConversationAdapter.java | 90 +++++------------- .../contact/ReadPrivateMessageActivity.java | 1 + 31 files changed, 149 insertions(+), 84 deletions(-) delete mode 100644 briar-android/res/drawable-hdpi/message_delivered.png delete mode 100644 briar-android/res/drawable-hdpi/message_sent.png delete mode 100644 briar-android/res/drawable-hdpi/message_stored.png create mode 100644 briar-android/res/drawable-hdpi/msg_in.9.png create mode 100644 briar-android/res/drawable-hdpi/msg_out.9.png delete mode 100644 briar-android/res/drawable-hdpi/social_send_now.png delete mode 100644 briar-android/res/drawable-mdpi/message_delivered.png delete mode 100644 briar-android/res/drawable-mdpi/message_sent.png delete mode 100644 briar-android/res/drawable-mdpi/message_stored.png create mode 100644 briar-android/res/drawable-mdpi/msg_in.9.png create mode 100644 briar-android/res/drawable-mdpi/msg_out.9.png delete mode 100644 briar-android/res/drawable-mdpi/social_send_now.png delete mode 100644 briar-android/res/drawable-xhdpi/message_delivered.png delete mode 100644 briar-android/res/drawable-xhdpi/message_sent.png delete mode 100644 briar-android/res/drawable-xhdpi/message_stored.png delete mode 100644 briar-android/res/drawable-xhdpi/social_send_now.png delete mode 100644 briar-android/res/drawable-xxhdpi/message_stored.png create mode 100644 briar-android/res/drawable-xxhdpi/msg_in.9.png create mode 100644 briar-android/res/drawable-xxhdpi/msg_out.9.png delete mode 100644 briar-android/res/drawable-xxxhdpi/message_stored.png create mode 100644 briar-android/res/drawable/message_delivered.xml create mode 100644 briar-android/res/drawable/message_sent.xml create mode 100644 briar-android/res/drawable/message_stored.xml create mode 100644 briar-android/res/drawable/social_send_now.xml create mode 100644 briar-android/res/layout/list_item_msg_in.xml create mode 100644 briar-android/res/layout/list_item_msg_out.xml diff --git a/briar-android/res/drawable-hdpi/message_delivered.png b/briar-android/res/drawable-hdpi/message_delivered.png deleted file mode 100644 index efade63916a2f36a74400bf378d587a763b690a6..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 479 zcmV<50U-W~P)S;>TSfkX)N8Os7VT(J-PN2h*n1y#c)I)WHCx@n(b}lA;+oFW z3+sFsUIHx3!$bh4)eN04H_gXgTgLke`F;aFT4N%Lbwz6j!du*C_#O!^HtZ?F~c-8GWu*IYazUS#JW?%{oezzbQl{vY^WVM}@w1c|*r zJWhW^2q3Px#)=5M`R7l6|l)nxEK@f+(lTd0TDv?zvC{E!$cnF<)o@u=Uuc5$nB;@ExXpks0 zS6t5CKTdbQZg-RK+eu~y%9P0yQPU7Llki=oKzJS415&skfS-b6GyLWh3~zg`e=Dp4 zQPTpBaqyo6qNWEN0)`d-ArLifQPa%`Ujt{L83(sjFavg?W|RSb0Xm-RKa)Na6-h1>`^sgtB7Ut2Et7Vy#fgUqEIF3PkhL zOeV3@k|!>IBSR!%Rw81>Y4SRf#<72!RuwGg1lbW3f>+Z9TELRczH5^18?!i VKJ0vVY&ie`002ovPDHLkV1gf|fCB&k diff --git a/briar-android/res/drawable-hdpi/msg_in.9.png b/briar-android/res/drawable-hdpi/msg_in.9.png new file mode 100644 index 0000000000000000000000000000000000000000..974d60e2d7aeec5229de2b26495af671ddb579ba GIT binary patch literal 957 zcmV;u148_XP)f`k?JWf?k4Lv2|J2+1anTowJQG%F?dw%(PeLz=dTP&VPP$?z#7z*-Od) zGp6}X^L3VXz!)Pu8>N&9WQ~|T+YQB4M^_VF^e4iw=`me2Q!oW10VAoMl9A6Nxr1ag zbOx{(*>zvMy$z)$8%{bz`#uP_Qx^)x$s|3ob=rD67tq93p}~T!E>9 z$Ln3rgGNrDMM-{Ey1)7u{FLyqmm;E9j)?y8drd||prHn8snd6v2|BD8j!hfgwPqzX zYN4j?Afinuf}GfD76@vgrU4NlBD^8fmT}ZVO(Uk3>3dNoO<_f;@GqqSH60{_=9<~r z*Axh~B4UA9AQnj0B^@ef8}A^v+Bu&-Xsh9(L;M@Wr_sChmF1hS@){9@D0)BAQwI>O zyyi$6V){{c&5nvKZEA1M9Y`8tYN+e$v%S0r%4m_tDoifPu24!Ofzr9AmYYLEkkYe3ji~F z_PnRhH}T;Pm(}kw7)k=C8e96fZLCxn8Fu<0BW!`|4si(v_7#cyo*iM>@BjC#uP7FX z1!93%Af|&bGb>?Li|GymrHT@ZCjw@Hpcc(=gd=YdC?1nD-@cET1%g_rsXK^G5Ms3# zJl(-i*l#ohYM>Ts8UR9LvvWTK2aY$?y_o!XI~0z5)f)hPqHokdE!4~~#q&EI%S1zcCZIF)otca8-l+YA@H-Lu?Ld87~S0$+P6z%Dtyw7W)Lx72*00_w- z>;l&!(f8mP9y-G+I|3t$nk#Rz>oRvEatdG;v9E^_CdQng!vs&L?E^6cMEik49i|)A fQ1fi`mjD9*YGG0-hQus300000NkvXXu0mjfO1`hr literal 0 HcmV?d00001 diff --git a/briar-android/res/drawable-hdpi/msg_out.9.png b/briar-android/res/drawable-hdpi/msg_out.9.png new file mode 100644 index 0000000000000000000000000000000000000000..08fd35b4cbdba08150bb224a4981df94431749e7 GIT binary patch literal 1871 zcmah~X;c$e6b>keC=x|cAlh-Dw1Qd5E+9!Jm{bB7(t-QJ6 zoIRa!IGl@E1WB=;hBda6Bld1A|LHo`d7#1=Gzv*TljTMj$5SHlFd){+Rj?G6D^pfC z!+|*5IE_XYgT_e0xC%r^lG`vOi_UVE@TR5YQ-tz-Weq zA~6VHwMMkY2uH06mnqh06&xkFFc=85a4`cq7?lGSU83H^wFH5~cDdNtwoC?rVF;=X z0^f^@kwgLl#0UcnQUFmwp;7@RlSHL6m`v(?fJULx$Q0~h5~*}9gUO|_fRPKtycv}V zTqzVf;tQJvfoc>raLMH48_sZnwvCYvvSSP-Ab4y96sbUug0=LiEhY!*ZlP$-m9u2^qE<$47? z%GG?}3O>o@3XHHEMT{~8NgOSPNHu~YCN*LJ1W_~~TBBDY$tK%AVXAC8VWTDqR)!i8 z9Wb0SuI3}}W;5oRA*9gwY$lsZWiW&RR4R|oW(YCiv`|I>g%v6QM~KRgLViz#{)b4$ zWRPw3@lm~uE@4Gz8;(^!HW@oVupUdd5j!2T4t&eN4qciU;>j!>Pj^bf+<4P3s5(n4 zN@G29uML!lN^7&NX=?hdEXQmD!_&KUt91_D(<;jFfe_!)NK%YbzNKm0`3;#Y*G-XA zC0> z?id$XpFD74ec7h=!MU>>{kuY9)BGL*vAv5dw;_6mUVFXn?mX}oFev*%#L7KbPPb1G zAKUtF$3Nja1=^{i?G=N-D|T7C+MijsbiZGPpYZ&}s;ty0rW>rD_J}KC1=$f>J_EON zMc?wgkIo-_kXNzds(gj!Mq=QeL!H&(izUkilfW-S<9T5jE}q2>JAdc7v-^sIqgI}& ztkp)R7TCG8*h{*B$?<+>&)t4;QNHT+zGnO{U4gJwI+dJT?A}`LnqE_Mx%pXYhQkrc zTf)8PtFltWA>t_ahEq)<93FD@(GYme_no$)Ie;C3C(ZF$og>2TjYo>I2w!V^)_0ap zxS6MwsZxsV8F#XqQut!GW zJ@Vd;u z*)Zj|2X$?|&sO%<1{e0tUiYx@-HY21UbuLEVhau<$yW2!g4X80wF5fGhp*4g=&r9e z*D0JG>UaB!fbTY^#q~XTKIf%i^IG?BPWxYNei#?Hf%R8`{Y1O7eN>0HFMlKVUpT+F z+KD~8>U7z;?8z+E@zYon<*$fMxD%PJ^BN{Q QhS+{_VqrLRkiRPZUsQV1M*si- literal 0 HcmV?d00001 diff --git a/briar-android/res/drawable-hdpi/social_send_now.png b/briar-android/res/drawable-hdpi/social_send_now.png deleted file mode 100644 index d6ebbaedd28c504ab516d2cc79641d66dc9e04f6..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 1680 zcmV;B25Px*N=ZaPRA}Dqne9^>=M}|&M=Qy^`vp76%1%5c74_)0q?~ z9c)aD1=!fGvB4mu(+|F@E{h<>F$Si2W*F_WlF)PSJ?Gr>JPTKRsJ!TQyRzK|4D^el z@Kp$)QC`@-26Tb%f!V84foARcD@pUfAF?c4mh`jj?V>0KS0Mm^rtR+}T?f9h{S&a9 zW!a{rUE71p2CY#5k`94&+uOE31AY(O1O6;&8Ca0C0=&Mg6&M2Bz^k}!NxE)(%JwXf z0>A5ayQ{X>foGQiT1k1)>2$E&mUK_jT}k^uKa}c*q*T&9;FhEoFig{Qkf!M{O;h)J zy^F1Y?V+S?;FaxxB-sWSNZJKtyCvyc;7i~yz$&m95PNZ~dJH_x^ZekGL#P~Sn%;>F&jN|0K`b8I4zeHW-IxWwko2Xb z+rR`c>~uQ)fY-T0t9h&>@8t4@q||m&fmr>c1K@2yOThgg`j3)UBrVuJcW5=o+}oA( zA}oa}fys6WC0Ad8hNPD58DJ8a2`T) zRK}xtC4wCUv;bx#eGyQ+4NOQn7if*Ez-!>C?LA4;wo5fSf}xTZl?uge4H5rkEvS60#UAHx$hqDLId`Y8d8g_fieTK7Y}rU0jDy5H$^4m+I=ye+Hdnd)3|g+~qBEnq5o$24#UxSwU&gJ_6bd7kfnXaECXThi;$`6E(V$N#vhRD&(w ztMbJ5ekGV$;3n|3q;G96Nm>ZwxFczh=lSrx1CTTTwty#5W(QxAO5;)xT%kBgD3)TU z=irVd4Wo-Y1YsDJa#U>}IEX+~Nq21j0Q@4f#)3G@vPM|xyTIp?8nzQj%?LV)dE0g~ z7C(AVQZwdB%v&*6e5O@teo3V_3t}u zHv%%QWBfF!t@5CHeS#E^{#Wh0swcg9LY5oAb>Ob;&!gNWOxl6{Mr8UJYywuz$YK)J zYDVDAiY0HAT|O2+f{>&k@E>3!ywn=-1b7-8JynI0*bo0z(x0NjC7v7qtF{`ItR$sB ziYk?ab!<^bBrfOWUquXvg&zPfOA-T1MNw>?MMjfo`5j5~VJ`;pBd)Z8;Yl)D-mc%P z^$thYuK`U-`?jA*TC%+WtlHj*-{!0V%m?{gAyyst9=G5+jw>6Y(Scg2Kv9hyNt?hU zNe_U>zuux5KL)a6&%>2Vd90&dx!j6N|OvmdUTv?JNBD3jt?X3zF>V8!+#@b981 zw$E!*KV$ojq{&haYXm&aN-K_DN~r8fT8l+50_(t=4}r>ADli=tXx89Rb)~K z{+I2a;uvrf*gehGUWSK!#0lDx?dOuN++)_mFj$L{9_D%eiYqXx0qjf4LwWlAHhvrb aALGAC6o9(GPXC4g0000o7@_DT|5TlUGa75g}!VvIKWr38s!nOuB zt|tB|BCf`w=h#o_vOX$yIKz9j;}AQ$alj;YkM*oc6SD6#%nF*5Sk3%VKE*EJak*2RtVAV4l6+Lemj#ZCf!=2DboFyt I=akR{0IWZ1XaE2J diff --git a/briar-android/res/drawable-mdpi/message_sent.png b/briar-android/res/drawable-mdpi/message_sent.png deleted file mode 100644 index 1f3807209e1db00dc0b3f07fa5f2fd0e2bd813ad..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 238 zcmeAS@N?(olHy`uVBq!ia0vp^0wB!61|;P_|4#%`jKx9jP7LeL$-D$|R(QHNhFF|_ zI@zA62g)CC+VjS9U%Jc mfbb2*&-JrXttRYT!T4~s`ej!WZF``b89ZJ6T-G@yGywpZJz$Uk diff --git a/briar-android/res/drawable-mdpi/message_stored.png b/briar-android/res/drawable-mdpi/message_stored.png deleted file mode 100644 index 01858ffc64ddf763b244d301acaa33657a5ea3d5..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 237 zcmVj8>MMpen{*ASLB?y1l(IDlLTGC9jbFD%~W6R^+a!&9xKjE`__{n zXIF_W11D`L$;jNS8kPal#!n0e;0ElM3|b{P;H2CI*tAM$H8EogoSDaGHWBPG*2rTV nt>n*(lucHza*5TS>1(_I)3qE34-Hbm00000NkvXXu0mjf|HEDa diff --git a/briar-android/res/drawable-mdpi/msg_in.9.png b/briar-android/res/drawable-mdpi/msg_in.9.png new file mode 100644 index 0000000000000000000000000000000000000000..f9a0267b6e8cc706a1350b1d0fccf6f4a0887b16 GIT binary patch literal 669 zcmV;O0%HA%P)<9090D>2WFDCgVPv9mZec=p$bS;@IwMsbf@B^O!yo}n3{>_d zB@SU2Y7Sun7D&tk?GPql;lp)u!}Ky*IfR8+M_k%Ir&V5BJbR!*1lbXJ1C>VT<_LTa zp{pZsrV&w;!w|H)KHiuH3x8Jg%^<9%LTg z5hGj!H9|ZbOn?9V=LV`52I}Ag3bB#lmR~?iKLPu_Z$X75sC@c*b?bkU25LZ>fR6bJ zbpJ0P_ca+kMUapGK}U;zgUmw-5e5?A0RjvFHWbr_e!>-000000NkvXXu0mjf D)Q21^ literal 0 HcmV?d00001 diff --git a/briar-android/res/drawable-mdpi/msg_out.9.png b/briar-android/res/drawable-mdpi/msg_out.9.png new file mode 100644 index 0000000000000000000000000000000000000000..f22c541f7f9087c833dd863c6cf07faab5c1d58e GIT binary patch literal 1693 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 i^25oG~D$0000w(Dt diff --git a/briar-android/res/drawable-xxhdpi/message_stored.png b/briar-android/res/drawable-xxhdpi/message_stored.png deleted file mode 100644 index 153650a1f50238963f883cfeb8990d51d9ac57a0..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 683 zcmV;c0#yBpP)Jj%jUsGPgvb{m%#Tm8d(vrc4|Zqw zFh=*Jl`P-Qo0+@0nb}!r(V|5PWWWfR02ja<$bpqzIdBEc>^&cVt+iMxumhX|H^6=1 zx&cmrw@+?0&*RwC;d2%lRbu3@j5EF4q$H)TH6tn5SN6Kn_fSF)#$Wm^k0E zzlZkP)ZSaib8dAd#Vg=Pjlunn*)UrF%E#K z6S8;mY5+$UGS9?EXeNZlO64gWI21fHAECJr z8Y-2ia9~&P%zcDp+;x@8Q#jBSJh_k1N(gDUekmNt1kcJxs0jz&D>+mSG!a58OjjG) zN2x+6)kpjh_$|1Wz!&_hy8MW*e1uY^Q82~mm}+zO3)u6JSEbQZg{+Ksn0e8?Sl@xy z56GzsS*ljT1y@-8!`>w`h9gX2Wi^r$54dTU#gids-1>38ya7{ zar_s(p@H}!?**n$@@T7<`kyJMd5aJPW(c>NI5gmp1bIJ3WZ z?X|Ux*UQ*vLk~F0=wqH#$|I&G({n9i4*CAD#zQ`dkYm=bJfmaQ7A-a%{{gUj`-YR= RkU0PV002ovPDHLkV1i!`GmQWM diff --git a/briar-android/res/drawable-xxhdpi/msg_in.9.png b/briar-android/res/drawable-xxhdpi/msg_in.9.png new file mode 100644 index 0000000000000000000000000000000000000000..3db9979cf1b13128da38558494e6604e730098b6 GIT binary patch literal 2231 zcmV;o2uSydP)2mwr_fI<*!QCnVV zc$i2iM#@V-6crx<0b4*S@)S`DrSz`7>-BcW@7voeOD&~5Zg=kbePJ?p_eYuU`|bCb z-I*OG)ji=?`JLH0DE&X@oJ%A&LST%`WCk&WKoAHL0wJI%x8jc^bsikiV#4T|NL5ZX z)fYGYR%7+!&CiVthzJ1)H`&yfpyNfuYo^AlfU(9SA^-u6?l3jQ1Va)Gh#7(kEok(r z35xh2%x(%Hj+u<_WK4?t=CcnTY2T*B@OXDzcb8LXC!#x41cN8aeB}pDpDkSf!0_?8 zFf9w<&jyq*r0DPn69fe&IB}V26FUv--}}S(I9CtR6RlHG+NLC9OB`};PtJjzyZ23e z`t{lSV500dU|cgy$pS&p!x2K*w0utA5rg|~iUtT(1;*TUK%e__cdlMA0CaJi!YYe~ z@>K@`19xT3nb_&U?)NN{WmZ3G=L9lK=+^nJtTl_KbwiyDPZt}6;SCHZIAtcq5AD}0 z-66{jqJDxVv*dogyJxg%*(4EkyQWtN;Smm*IS|B#rD=U2Dc=_>lQegn>+b9YQyxRF z00m{yLlcaXL2i(o9on@X7Hc!+wyl~C1y6UOjzW8cOF;(uIGo9e@m*sLL{dWhy`Z21 zIy#&XbA>Hmp~MS$1b_f(8fze+v<00Q&WRi~J@>I41SGY}`2&28i!~6a6GAYmLZ;8R zMV-(wi7_dL?*xN>N+=gzJxAE@5ln}`xVSg;Zc#-7Izkv0eL{y6ViyFf_BOt-GwV7n z2!fVy2m*qHK#&j!0zpC`1P8&$4CE0c1cE@25C{T6LLdkPNi=~l9+t%XgCWsD=m0c? z!Rz+q(oPWib81cF4$dV<$M&hXBF;@9Y=8jG0UqJH^Y&Irxy$A(G8SPG2&*CB%I_{6 z+SS{(a(-6*dP%(~N7w|Rb@N8a89yVTRy>5AHv|T{XX9{d!N4 z>8%4{&It%1zToTZxs4m7j3TpJ2jYsvj1Yd`zG7Ch#tp`h$*lwNKM04uT0X5s(?;XS z+}44p3c;Pfb=jm=%^Oc3Q(HHWsDvPgwzRtUZ_IivwMCQ3WM=C<0yh9T5yHNWnPc0f zHlIl*wjKln3JUmyYtNUTjJ_ka#cVRK^`R-WX&wF@*u3PqHZ7aJPo}jgM>rk&UOhRe zs^M4skk}BKxZ;rY1krQot2uk}j=V#rwE;wfBsW74ip)5$;Der@y7uS&httWtHdRgF z5gJ6OAi$^?^3t?byZ7d2l8G$@QRMY=$PpTomt7SAU3QdRc@Us&a9zJ^V3o^L{APldlgu!&rU|xiQVXE(l2@8*&JhPR| z9(j+r0tOhrJPbo-QVH~zdJi9;cI?#IZDjfggQx*Usgb}-`i*=u?bMlncaixc45Ats z7^ZyC5JpLvue`YLGZSY1b++((LJ(mPRbT{l7*I)>VGJBSdDhu;7k(iO7A&W!21eL3 zJm)W7DtdI}q-p;Y7VRYv7DyEsd7#)ZbC!6P(0#q&aO$)Q*SQB>?X#6lZ*u!)-^MAS<9y&)^g@FcNnZEG5izVKeS$gRyEjv1X#-c4UlW;qmCUj_WDGq!& zID{tss_`$*UOz9Ws->}zq?dobc}|J96nEHGfY+5%!1x^uCPjoP#-AcD<`= znlD-*z}N$ucK-C<+{LSYMV$=Y)S42u5Xl<11Xoc6!NK)q;e|@VrKUYfa`6ONtimGvZNqZuU zCmBYR48uxXGH=qr9$h>3YuvDY7l$mn1Pw#M!lL55eFy*8F>c19jb%Q+2fV-w1&9Y# z1PHjUH(2ELYhj(M&bVy{fr9VyFuYTNvADSoLrQ>=VUORP;MDjg9hplwW+uq-26)~A z3$5dYVgm+c>@jC$`qpL%SG(&F^ki);Gp!bcB7!E|(`o}jI1p9B)Me!^A9oUZ6OE=A`Al+0U+E2LiF>8DsSvv4}e<= z0t^;OP}mh9h%J#I<)N^+A)KRl0+>i8xR5m@{uzyM3uD#Q*yT3`SG002ovPDHLk FV1km7;-3Hj literal 0 HcmV?d00001 diff --git a/briar-android/res/drawable-xxhdpi/msg_out.9.png b/briar-android/res/drawable-xxhdpi/msg_out.9.png new file mode 100644 index 0000000000000000000000000000000000000000..b7aa02377fd49c6a462c58ed7972719f41ccd978 GIT binary patch literal 3076 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 E04lRG=>Px# literal 0 HcmV?d00001 diff --git a/briar-android/res/drawable-xxxhdpi/message_stored.png b/briar-android/res/drawable-xxxhdpi/message_stored.png deleted file mode 100644 index b3833bc3e76f11b4abe7f1a487bb87025f003075..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 969 zcmV;)12+7LP)8bfQ6H)-tJg1EBP#N9vMhkF-f zGqZc|-kHtD-4Etv+54Su&fJ+fbLLzYSYUw#7RZhzyoXIZ#1lNje%YR47Z30mZj{el zYOLT>e1|rA=vQn#yuu!CmRy$xYxo*(RPXS(_8MQ|`V{+78*BI$XVP_ixSc7c&rCUD z8Taw0d>tQd9o#K#Uns8OXZ6H)@e+qPDBEHATel|Hb6m~d%LvvL3)MK0r+9&Fe1z5r z&Q|%K?edw^3j8PdAZgDk;5Ocl5!S|+SZ!cuwd81zvDH=VI8(uG{5?WUrxZPEr0b$p za&|`8{mT@bux|9oA1QW&Tv)^L2>V?br^8k8Ip4!$(+OBsup=H={VK!4xU5)|VvF2X zYJ(N9CB8^Lmw1c3A2HN(F`XY^OZ-i^m&(Yy;z7>i2{}Jjh##~j>&8w*TSuaZ@tcT& zBa_ehpN6=ayhSVG3*(apyeLLL6x(++8?}@UP-+Qnk!Kpd1&;!xeZ`*K1gRZBp(&*G z(WHbc!bjS+=0Q#l2egDE#y2LMs<#4UDMp_>4j}#(+?s@JFF5E21xpfvw8~TbijtN_RTsZ z4+8{U>5jNL9nccaEIp`0vKt_HnNVa-2T*7o*1uba;8}p+FrmQQ4mfgN|I<1I`vHQ3 zgaUIr;J|tP`*jGW?SNYIvjQ4BVA@llhaVO9hbho_3glh{V@K?+VjpjsT5G%r=H3RE z6&ag90(ScN1)ogFon#x#9S99@MKLn5+}9s#wAo`29cjZ$|zbONqVKU|Y?V6s?PEiWK*#Xf%0JlzeINNfEp5%9a)<9pdqqfjd3|INAIRIH22rzj4zPbF&hOECo)!!jVqBk_CGF>8DOr9 zqz0JlGPwaJDU{qWzEE<*B`A~}AXTaCkxN)AJHSO2OV89t6>EyHdG5;PhcUMwOblag rKbZ+(_@k*^bMVpB0t+m#z|7-cs~f*?lyfk$00000NkvXXu0mjfuBgXF diff --git a/briar-android/res/drawable/message_delivered.xml b/briar-android/res/drawable/message_delivered.xml new file mode 100644 index 000000000..7df040f3c --- /dev/null +++ b/briar-android/res/drawable/message_delivered.xml @@ -0,0 +1,5 @@ + + + diff --git a/briar-android/res/drawable/message_sent.xml b/briar-android/res/drawable/message_sent.xml new file mode 100644 index 000000000..8a074e0fc --- /dev/null +++ b/briar-android/res/drawable/message_sent.xml @@ -0,0 +1,5 @@ + + + diff --git a/briar-android/res/drawable/message_stored.xml b/briar-android/res/drawable/message_stored.xml new file mode 100644 index 000000000..b91196f03 --- /dev/null +++ b/briar-android/res/drawable/message_stored.xml @@ -0,0 +1,5 @@ + + + diff --git a/briar-android/res/drawable/social_send_now.xml b/briar-android/res/drawable/social_send_now.xml new file mode 100644 index 000000000..bd34e7fc2 --- /dev/null +++ b/briar-android/res/drawable/social_send_now.xml @@ -0,0 +1,5 @@ + + + diff --git a/briar-android/res/layout/activity_conversation.xml b/briar-android/res/layout/activity_conversation.xml index 1a07f07eb..8bc064d2a 100644 --- a/briar-android/res/layout/activity_conversation.xml +++ b/briar-android/res/layout/activity_conversation.xml @@ -39,9 +39,7 @@ android:layout_height="wrap_content" android:background="@color/button_bar_background" android:paddingLeft="@dimen/margin_medium" - android:paddingStart="@dimen/margin_medium" - android:paddingRight="@dimen/margin_medium" - android:paddingEnd="@dimen/margin_medium"> + android:paddingStart="@dimen/margin_medium"> + android:paddingRight="@dimen/margin_medium" + android:paddingEnd="@dimen/margin_medium" + android:paddingBottom="@dimen/margin_medium"/> \ No newline at end of file diff --git a/briar-android/res/layout/list_item_msg_in.xml b/briar-android/res/layout/list_item_msg_in.xml new file mode 100644 index 000000000..8194f5453 --- /dev/null +++ b/briar-android/res/layout/list_item_msg_in.xml @@ -0,0 +1,42 @@ + + + + + + + + + + + + \ No newline at end of file diff --git a/briar-android/res/layout/list_item_msg_out.xml b/briar-android/res/layout/list_item_msg_out.xml new file mode 100644 index 000000000..baacbb39f --- /dev/null +++ b/briar-android/res/layout/list_item_msg_out.xml @@ -0,0 +1,54 @@ + + + + + + + + + + + + + + \ No newline at end of file diff --git a/briar-android/res/values/color.xml b/briar-android/res/values/color.xml index 01b15430a..0ecc0f1ba 100644 --- a/briar-android/res/values/color.xml +++ b/briar-android/res/values/color.xml @@ -5,7 +5,6 @@ #2D3E50 #FFFFFF #FFFFFF - #FFFFFF #AAAAAA #FFFFFF #CCCCCC diff --git a/briar-android/src/org/briarproject/android/contact/ConversationActivity.java b/briar-android/src/org/briarproject/android/contact/ConversationActivity.java index 98dcd179f..02bc2b83a 100644 --- a/briar-android/src/org/briarproject/android/contact/ConversationActivity.java +++ b/briar-android/src/org/briarproject/android/contact/ConversationActivity.java @@ -142,14 +142,7 @@ implements EventListener, OnClickListener, OnItemClickListener { } }; list.setLayoutParams(MATCH_WRAP_1); - int pad = LayoutUtils.getPadding(this); - list.setPadding(0, pad, 0, pad); - list.setClipToPadding(false); - // Make the dividers the same colour as the background - Resources res = getResources(); - int background = res.getColor(android.R.color.transparent); - list.setDivider(new ColorDrawable(background)); - list.setDividerHeight(pad); + list.setDivider(null); list.setAdapter(adapter); list.setOnItemClickListener(this); list.setEmptyView(loading); diff --git a/briar-android/src/org/briarproject/android/contact/ConversationAdapter.java b/briar-android/src/org/briarproject/android/contact/ConversationAdapter.java index a95b00e47..0e2499c7e 100644 --- a/briar-android/src/org/briarproject/android/contact/ConversationAdapter.java +++ b/briar-android/src/org/briarproject/android/contact/ConversationAdapter.java @@ -1,40 +1,28 @@ package org.briarproject.android.contact; import android.content.Context; -import android.content.res.Resources; import android.text.format.DateUtils; +import android.view.LayoutInflater; import android.view.View; import android.view.ViewGroup; import android.widget.ArrayAdapter; -import android.widget.ImageButton; import android.widget.ImageView; -import android.widget.LinearLayout; import android.widget.TextView; import org.briarproject.R; -import org.briarproject.android.util.ElasticHorizontalSpace; -import org.briarproject.android.util.LayoutUtils; import org.briarproject.api.messaging.PrivateMessageHeader; import org.briarproject.util.StringUtils; import java.util.ArrayList; -import static android.view.Gravity.BOTTOM; -import static android.view.Gravity.LEFT; -import static android.widget.LinearLayout.HORIZONTAL; -import static android.widget.LinearLayout.VERTICAL; -import static org.briarproject.android.util.CommonLayoutParams.MATCH_WRAP; import static org.briarproject.api.messaging.PrivateMessageHeader.Status.DELIVERED; import static org.briarproject.api.messaging.PrivateMessageHeader.Status.SENT; class ConversationAdapter extends ArrayAdapter { - private final int pad; - ConversationAdapter(Context ctx) { super(ctx, android.R.layout.simple_expandable_list_item_1, new ArrayList()); - pad = LayoutUtils.getPadding(ctx); } @Override @@ -42,46 +30,15 @@ class ConversationAdapter extends ArrayAdapter { ConversationItem item = getItem(position); PrivateMessageHeader header = item.getHeader(); Context ctx = getContext(); - Resources res = ctx.getResources(); - LinearLayout layout = new LinearLayout(ctx); - layout.setOrientation(VERTICAL); - if (header.isLocal()) layout.setPadding(3 * pad, 0, 0, 0); - else layout.setPadding(0, 0, 3 * pad, 0); - - int background = res.getColor(R.color.private_message_background); - - View content; - if (item.getBody() == null) { - TextView ellipsis = new TextView(ctx); - ellipsis.setText("\u2026"); - content = ellipsis; - } else if (header.getContentType().equals("text/plain")) { - TextView text = new TextView(ctx); - text.setText(StringUtils.fromUtf8(item.getBody())); - content = text; - } else { - ImageButton attachment = new ImageButton(ctx); - attachment.setImageResource(R.drawable.content_attachment); - content = attachment; - } - content.setLayoutParams(MATCH_WRAP); - content.setBackgroundColor(background); - content.setPadding(pad, pad, pad, 0); - layout.addView(content); + LayoutInflater inflater = (LayoutInflater) ctx.getSystemService + (Context.LAYOUT_INFLATER_SERVICE); + View v; if (header.isLocal()) { - LinearLayout footer = new LinearLayout(ctx); - footer.setLayoutParams(MATCH_WRAP); - footer.setOrientation(HORIZONTAL); - footer.setGravity(BOTTOM); - footer.setPadding(pad, 0, pad, pad); - footer.setBackgroundColor(background); + v = inflater.inflate(R.layout.list_item_msg_out, null); - footer.addView(new ElasticHorizontalSpace(ctx)); - - ImageView status = new ImageView(ctx); - status.setPadding(0, 0, pad, 0); + ImageView status = (ImageView) v.findViewById(R.id.msgStatus); if (item.getStatus() == DELIVERED) { status.setImageResource(R.drawable.message_delivered); } else if (item.getStatus() == SENT) { @@ -89,27 +46,24 @@ class ConversationAdapter extends ArrayAdapter { } else { status.setImageResource(R.drawable.message_stored); } - footer.addView(status); - - TextView date = new TextView(ctx); - date.setTextColor(res.getColor(R.color.private_message_date)); - long timestamp = header.getTimestamp(); - date.setText(DateUtils.getRelativeTimeSpanString(ctx, timestamp)); - footer.addView(date); - - layout.addView(footer); } else { - TextView date = new TextView(ctx); - date.setLayoutParams(MATCH_WRAP); - date.setGravity(LEFT); - date.setTextColor(res.getColor(R.color.private_message_date)); - date.setBackgroundColor(background); - date.setPadding(pad, 0, pad, pad); - long timestamp = header.getTimestamp(); - date.setText(DateUtils.getRelativeTimeSpanString(ctx, timestamp)); - layout.addView(date); + v = inflater.inflate(R.layout.list_item_msg_in, null); } - return layout; + TextView body = (TextView) v.findViewById(R.id.msgBody); + + if (item.getBody() == null) { + body.setText("\u2026"); + } else if (header.getContentType().equals("text/plain")) { + body.setText(StringUtils.fromUtf8(item.getBody())); + } else { + // TODO support other content types + } + + TextView date = (TextView) v.findViewById(R.id.msgTime); + long timestamp = header.getTimestamp(); + date.setText(DateUtils.getRelativeTimeSpanString(ctx, timestamp)); + + return v; } } \ No newline at end of file diff --git a/briar-android/src/org/briarproject/android/contact/ReadPrivateMessageActivity.java b/briar-android/src/org/briarproject/android/contact/ReadPrivateMessageActivity.java index 7ece03b02..01ba00303 100644 --- a/briar-android/src/org/briarproject/android/contact/ReadPrivateMessageActivity.java +++ b/briar-android/src/org/briarproject/android/contact/ReadPrivateMessageActivity.java @@ -40,6 +40,7 @@ import static org.briarproject.android.util.CommonLayoutParams.MATCH_WRAP_1; import static org.briarproject.android.util.CommonLayoutParams.WRAP_WRAP_1; import static org.briarproject.api.identity.Author.Status.VERIFIED; +@Deprecated public class ReadPrivateMessageActivity extends BriarActivity implements OnClickListener { From e98d4f2260cf2951a1430b46f7fadb850381b14b Mon Sep 17 00:00:00 2001 From: Torsten Grote Date: Wed, 23 Dec 2015 15:33:41 -0200 Subject: [PATCH 2/3] Use a RecyclerView for the ConversationView and properly notify the view adapter of dataset changes in order to avoid invalidating the entire dataset when not absolutely necessary. This change also shows unread messages in a different color, so users do not fail to notice delayed messages. --- .../res/drawable-hdpi/msg_in_unread.9.png | Bin 0 -> 1560 bytes .../res/drawable-mdpi/msg_in_unread.9.png | Bin 0 -> 1014 bytes briar-android/res/drawable-xhdpi/msg_in.9.png | Bin 0 -> 1453 bytes .../res/drawable-xhdpi/msg_in_unread.9.png | Bin 0 -> 2374 bytes .../res/drawable-xhdpi/msg_out.9.png | Bin 0 -> 2258 bytes .../res/drawable-xxhdpi/msg_in_unread.9.png | Bin 0 -> 3680 bytes .../res/layout/activity_conversation.xml | 14 +- briar-android/res/layout/list_item_msg_in.xml | 1 + .../res/layout/list_item_msg_out.xml | 1 + .../android/contact/ConversationActivity.java | 87 ++++---- .../android/contact/ConversationAdapter.java | 187 ++++++++++++++---- .../contact/ConversationItemComparator.java | 18 -- 12 files changed, 210 insertions(+), 98 deletions(-) create mode 100644 briar-android/res/drawable-hdpi/msg_in_unread.9.png create mode 100644 briar-android/res/drawable-mdpi/msg_in_unread.9.png create mode 100644 briar-android/res/drawable-xhdpi/msg_in.9.png create mode 100644 briar-android/res/drawable-xhdpi/msg_in_unread.9.png create mode 100644 briar-android/res/drawable-xhdpi/msg_out.9.png create mode 100644 briar-android/res/drawable-xxhdpi/msg_in_unread.9.png delete mode 100644 briar-android/src/org/briarproject/android/contact/ConversationItemComparator.java diff --git a/briar-android/res/drawable-hdpi/msg_in_unread.9.png b/briar-android/res/drawable-hdpi/msg_in_unread.9.png new file mode 100644 index 0000000000000000000000000000000000000000..c22cc86322f710ab37c0f56c192f9721271f58d9 GIT binary patch literal 1560 zcmV+z2Iu*SP)Os!AFXzgz-nQ#Refiq{V=b5*2nq&<0H!A5bKf)W(uZh?_J` zlZ@XPXNKLK*_=DCfR76yyK~Pu-}%nH_uO;utPswoTaOg_P#;f-=IOD9FEnl5mOXSx zsj|LQ3sGBc#P0l5(`GAnx?l@ibFZpCP*D?7x7@T{pDDVoi&$e)6uQ$kH+^Gc!^SFB zQ>xJDLE-UTFS$C9ID2-&wd1RJ;yWp_`h^RpjNn?H8F-gI7W#=3-zs%=yNj*B)0Nh2 zwmz@xhQ~Gq656XM_m?ZsbFiq*YuY+}CM5&SYM*2>FLKe_ZV6!Qw`1&Ya|#xcA@@x@ zu@-yhywa|!PjZTmQP>dTS5CADe&&00xhjVRLiP@~yH z?Xl^xdW5y$urfK>6Z>-JO$QfOVbX4DdZQ#_oNrdY>zv(8xkLf}m&^n=MO%S{;Xj6B z^JXjLhK6o(!X>2lb#?8eg~%z{2%pCjxAtYTF=+)7gc9pku&{FOP`|yPEaB%=bq78> zk{q5b2qay5ipyB{E93CWn(3B7OoD1m0{LufDNatliWPC3vKkv)jOX3H7&JBYd080j z+~=HNnQ#VV`YVFaf-F37U$@()Dr2}<#xd|@JeSEluXJl8UX4|fcQCmZyHRp<^pd{1 zx)v6Qg9+9jX=(bCzh9cD*@EYDrihARkC?h4wZLTT3-LD4GdD~h7a zr24A-;lnTMjg5U&KXT6K%gYyAj~sdG`*>o>3YCLN`Ir>i9y*5N$4=WEh}GYssx_#9 zSBVKbyTIUeS;NJ0s2piaHW~{;2L+!XHPRq{08AZwv-9PpSK$8$2zJRky@tk3ezQHE z4sL%&1_B1Px#8hO0Bnl{1OPPzfc0@l7yzz|G1t-YY?uJ9An9}GJ`=sYyrfRIrF0{UEPVqzdN5DN&5ev1^u0*V|Y z3;?N3D-0ku)yo{|D>!18ODu>OAAjEu8yLo+;P1wQq(?_zqq0*P2<0r5wWysa!5WP% ziEwR2nfM<3?Id{#Fk)~WYppC#W4z_) z(KK|HiwThpb|rE^Fi@Wx9Gr@r1UZ605f)*V`xTf7&LA<|=s(O64y&KA2-A&-)Zw*~ zBbb|^6qsI!x?u($5ibrzDN97c$}Um*$=d!`jR?!Ok^rS%y!qJjHR9%vuYJVaJ8JU> z52~WMdC+$xLR9ob#3WFY@9gXpt*yi64j!UA{!K{{F$q-X_V3S#wzg9u#3Q$V*Gn~7 zA|SCXf8an;-?QgKnQO; zK1g5%}fVq%@IoLQuR0LO-_W^Z&ekq&Q48Lim2OWqK@>J6z90 zP^RE{M1lfFrT;&Xs3PmvZWtr7t}iZL^Xq_DJrm3E3Oz6pq~oPmdU{e~c6QpUQ=a94 zL0E)YuFKY192ipY(l0{%oa*bNAH3a#^9kP68)uZjK{B!F$6o6&wv7LOz~Omd(&v&E zmQTM1Y|Rc3p)BC%WX65JK}4d*8|<8aHF;b{mNf{z0A3Rt2XQa0000< KMNUMnLSTaApWM#? literal 0 HcmV?d00001 diff --git a/briar-android/res/drawable-mdpi/msg_in_unread.9.png b/briar-android/res/drawable-mdpi/msg_in_unread.9.png new file mode 100644 index 0000000000000000000000000000000000000000..6e5418856d9fb9ed59be30ccbb013e277ed6345e GIT binary patch literal 1014 zcmVHeErtF7 zZ^5w?3cV;r6hypuuqc$WMS3WRhTeoA(o#r@htiXW2vr3A0V-`%+*X_QeYd;o?#|3+ zHcbQvmLxOpJoC&m@5gKi5i|;YR=cLt>gb?_vR`5vcM05g|+=oy@?6otn268)4W z-WkS@bh{ZsPRQumuuGc$MQ7}Eq+lgY{}^c?8pM+htBFdYqHe2tE`U9*VE7%jjbm-_ z1VDU~f5Z2m?={_$84!>r+KU}D-p`~*96i9D6rNr<>gr(!wo|>*^@NNL1|qZ`0FDQQ z9RfEo2|4w~FofqQ0^~HolmOoH$q5P-61I)dd+X+x5WF;A#u?N6IVDUB$L=zAMwzZ- z=!J54;%?##d8^~G2jDa5iXWPYlT7f|Uz?Sp*kk)D#X}{-fP;!|7Z^*HWx|5<9H|F@ z0 z5$8mjX-g>;XGj0#z`r0?SkN%Jl+QD(v-1YYWV&f0fvH%jS+$x;*4Ha^b#?aq%*=Dh zIQFFiCrd9DB4p6`@Z!Y82a-x1lU^?)C;{mt>FDSqxm;hlr)T`q*ceu=A5tfgVF8gg z3M7=aU&jb>5YIJ3Z~OCbNu0R$Hldi6JuaEZ`in0I9-%_v=2gae<1V0TuN1z{+sa0NrTASHIIdk&ZX|IR z71{rvM1ZwPR#xVkp#b98cuo^ujAZu_xN#-632BG9N8y1#VC>sh+y)S29iDG6c@zE5 kyP-j6oC+LwVHJD&2RE55#s2gDG5`Po07*qoM6N<$f>(dd*Z=?k literal 0 HcmV?d00001 diff --git a/briar-android/res/drawable-xhdpi/msg_in.9.png b/briar-android/res/drawable-xhdpi/msg_in.9.png new file mode 100644 index 0000000000000000000000000000000000000000..f5db8372dda83faf1082e8700e0c2996c6801fa6 GIT binary patch literal 1453 zcmV;e1ycHnP)O4KW%?uxN}_3n3P(G=f-Pr=d19 zl%_y>vDH3^QUjuaC?Tndnkd!;Q6Y^QCG@WC-SuwovE%pc?VZPQC!Tfp&dy9anR_%l z|NY(fee>(cr)B#^- z8P&)UYe;DDqxAnOPQbSS$WT?Qm2HNR0+6t3%xZH2$?F=0l;C&$dA|b-N4v7AhX=kHgO8*6U`*IG&I3Z0D0RKD zan1Zy58nN*OH;2ZMm*4?vF~^H9C&y`W9tcnG2OC`vs}ZrQ3I_3C@71|7t8_(?-dII z7VH}}pcd4G1^^JwG6Fk?PcR1RYS~izI0(72*rNn$KrN^#*Lm9pLXji@LA1GZ%I+(b zArrNrCe%i%s-*ukSmrCTOl1f)+SDnoYf1$KYN3Q`k_@BP&t)VPD{OZSi4xWB(V@U3 zN<~fPc}M)t#0Vgde+ntJ0-8*1mtX7<2QAk03kr+10imG z35yUQ1PB2_fG8peyeVTaCKLAmnJ!T5fPlvZ5bBPt>ngYek%9nMHSW%)7jM4nrW;$h z1Ca@#cYDJvcPzPKk0jBlT*U|rf^1sCw)(}lFDdr|gc)1~%M1upyl>SlT7K)IPFa#J z;BC}MTS8moy6Y=%tLOp>%a?X5vOI^kJR%L@^}6Z>EAL%~5a#lh zP?->LDz9iMf5x~C5yT*6~!Ndbbox%RPn)hjD|HC4H6GNjlA=Mjn|$)5TrFMZ_x zJNsOkdIh)F8aR;`3P)r@*rd9%RWJxmk;v9}I)-2Hw66(A^j~?l2nIFY(R*;{+0D&Q zMfB)tEU zzF@?BNDCn70AmbVU&r2q-@e@Jt&PRvqg-W{nJ^?u0tjPg=f1BzZSSv-#S;Opt~F9H zAkB_gF#Oxvd%kGe)w@2PNQAh$`pkkciZI@6?HXwDe(+qvFv48jj~E*0$%J9Xj8~ey zN7_33>j6fT8xUDA!YLRHZ|^$1r|08MT!F}88KcmSK#uVlcOWug#1RH#ECg>tT!P4i zVKAbzcFZ-1Qe;cOU~<*6dN z#HqShchsO3)P&kdceml3Yfu`6Um(!8|MMS~R@FRu^vh%0eIsLoP60UM8$E`7V&8iY z9663!P!mZml+PYbaz@vj2QGB~h}qNKvcZ@O4mS77L^;&~w(Brw#KLr>7)=CgJM_{rr00000NkvXX Hu0mjf06vr@ literal 0 HcmV?d00001 diff --git a/briar-android/res/drawable-xhdpi/msg_in_unread.9.png b/briar-android/res/drawable-xhdpi/msg_in_unread.9.png new file mode 100644 index 0000000000000000000000000000000000000000..341ec4f7226f0362bf1cd5d5f354f06f5666845a GIT binary patch literal 2374 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 literal 0 HcmV?d00001 diff --git a/briar-android/res/drawable-xxhdpi/msg_in_unread.9.png b/briar-android/res/drawable-xxhdpi/msg_in_unread.9.png new file mode 100644 index 0000000000000000000000000000000000000000..3a3bb3e7e65841e35b46dbd4c4fc2a7584bf2761 GIT binary patch literal 3680 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 - + + android:indeterminate="true" + android:visibility="gone"/> + android:text="@string/no_private_messages" + android:visibility="gone"/> = 0 && position < adapter.getCount()) + if (position >= 0 && position < adapter.getItemCount()) displayMessage(position); } } @@ -341,7 +345,7 @@ implements EventListener, OnClickListener, OnItemClickListener { private void markMessagesRead() { notificationManager.clearPrivateMessageNotification(contactId); List unread = new ArrayList(); - int count = adapter.getCount(); + int count = adapter.getItemCount(); for (int i = 0; i < count; i++) { PrivateMessageHeader h = adapter.getItem(i).getHeader(); if (!h.isRead()) unread.add(h.getId()); @@ -381,6 +385,8 @@ implements EventListener, OnClickListener, OnItemClickListener { GroupId g = ((MessageAddedEvent) e).getGroupId(); if (g.equals(groupId)) { LOG.info("Message added, reloading"); + // TODO: find a way of not needing to reload the entire + // conversation just because one message was added loadHeaders(); } } else if (e instanceof MessagesSentEvent) { @@ -417,16 +423,14 @@ implements EventListener, OnClickListener, OnItemClickListener { runOnUiThread(new Runnable() { public void run() { Set messages = new HashSet(messageIds); - boolean changed = false; - int count = adapter.getCount(); + int count = adapter.getItemCount(); for (int i = 0; i < count; i++) { ConversationItem item = adapter.getItem(i); if (messages.contains(item.getHeader().getId())) { item.setStatus(status); - changed = true; + adapter.notifyItemChanged(i); } } - if (changed) adapter.notifyDataSetChanged(); } }); } @@ -444,7 +448,7 @@ implements EventListener, OnClickListener, OnItemClickListener { private long getMinTimestampForNewMessage() { // Don't use an earlier timestamp than the newest message long timestamp = 0; - int count = adapter.getCount(); + int count = adapter.getItemCount(); for (int i = 0; i < count; i++) { long t = adapter.getItem(i).getHeader().getTimestamp(); if (t > timestamp) timestamp = t; @@ -485,11 +489,6 @@ implements EventListener, OnClickListener, OnItemClickListener { }); } - public void onItemClick(AdapterView parent, View view, int position, - long id) { - displayMessage(position); - } - private void displayMessage(int position) { ConversationItem item = adapter.getItem(position); PrivateMessageHeader header = item.getHeader(); diff --git a/briar-android/src/org/briarproject/android/contact/ConversationAdapter.java b/briar-android/src/org/briarproject/android/contact/ConversationAdapter.java index 0e2499c7e..4b945f7d3 100644 --- a/briar-android/src/org/briarproject/android/contact/ConversationAdapter.java +++ b/briar-android/src/org/briarproject/android/contact/ConversationAdapter.java @@ -1,11 +1,12 @@ package org.briarproject.android.contact; import android.content.Context; +import android.support.v7.util.SortedList; +import android.support.v7.widget.RecyclerView; import android.text.format.DateUtils; import android.view.LayoutInflater; import android.view.View; import android.view.ViewGroup; -import android.widget.ArrayAdapter; import android.widget.ImageView; import android.widget.TextView; @@ -13,57 +14,177 @@ import org.briarproject.R; import org.briarproject.api.messaging.PrivateMessageHeader; import org.briarproject.util.StringUtils; -import java.util.ArrayList; - import static org.briarproject.api.messaging.PrivateMessageHeader.Status.DELIVERED; import static org.briarproject.api.messaging.PrivateMessageHeader.Status.SENT; -class ConversationAdapter extends ArrayAdapter { +class ConversationAdapter extends + RecyclerView.Adapter { - ConversationAdapter(Context ctx) { - super(ctx, android.R.layout.simple_expandable_list_item_1, - new ArrayList()); + private static final int MSG_OUT = 0; + private static final int MSG_IN = 1; + private static final int MSG_IN_UNREAD = 2; + + private SortedList messages = + new SortedList(ConversationItem.class, + new SortedList.Callback() { + @Override + public void onInserted(int position, int count) { + notifyItemRangeInserted(position, count); + } + + @Override + public void onChanged(int position, int count) { + notifyItemRangeChanged(position, count); + } + + @Override + public void onMoved(int fromPosition, int toPosition) { + notifyItemMoved(fromPosition, toPosition); + } + + @Override + public void onRemoved(int position, int count) { + notifyItemRangeRemoved(position, count); + } + + @Override + public int compare(ConversationItem c1, + ConversationItem c2) { + long time1 = c1.getHeader().getTimestamp(); + long time2 = c2.getHeader().getTimestamp(); + if (time1 < time2) return -1; + if (time1 > time2) return 1; + return 0; + } + + @Override + public boolean areItemsTheSame(ConversationItem c1, + ConversationItem c2) { + return c1.getHeader().getId() + .equals(c2.getHeader().getId()); + } + + @Override + public boolean areContentsTheSame(ConversationItem c1, + ConversationItem c2) { + return c1.equals(c2); + } + }); + private Context ctx; + + public ConversationAdapter(Context context) { + ctx = context; } @Override - public View getView(int position, View convertView, ViewGroup parent) { - ConversationItem item = getItem(position); - PrivateMessageHeader header = item.getHeader(); - Context ctx = getContext(); - - LayoutInflater inflater = (LayoutInflater) ctx.getSystemService - (Context.LAYOUT_INFLATER_SERVICE); - - View v; + public int getItemViewType(int position) { + // return different type for incoming and outgoing (local) messages + PrivateMessageHeader header = getItem(position).getHeader(); if (header.isLocal()) { - v = inflater.inflate(R.layout.list_item_msg_out, null); - - ImageView status = (ImageView) v.findViewById(R.id.msgStatus); - if (item.getStatus() == DELIVERED) { - status.setImageResource(R.drawable.message_delivered); - } else if (item.getStatus() == SENT) { - status.setImageResource(R.drawable.message_sent); - } else { - status.setImageResource(R.drawable.message_stored); - } + return MSG_OUT; + } else if (header.isRead()) { + return MSG_IN; } else { - v = inflater.inflate(R.layout.list_item_msg_in, null); + return MSG_IN_UNREAD; + } + } + + @Override + public MessageHolder onCreateViewHolder(ViewGroup viewGroup, int type) { + View v; + + // outgoing message (local) + if (type == MSG_OUT) { + v = LayoutInflater.from(viewGroup.getContext()) + .inflate(R.layout.list_item_msg_out, viewGroup, false); + } + // incoming message (non-local) + else { + v = LayoutInflater.from(viewGroup.getContext()) + .inflate(R.layout.list_item_msg_in, viewGroup, false); } - TextView body = (TextView) v.findViewById(R.id.msgBody); + return new MessageHolder(v, type); + } + + @Override + public void onBindViewHolder(final MessageHolder ui, final int position) { + ConversationItem item = getItem(position); + PrivateMessageHeader header = item.getHeader(); + + if (header.isLocal()) { + if (item.getStatus() == DELIVERED) { + ui.status.setImageResource(R.drawable.message_delivered); + } else if (item.getStatus() == SENT) { + ui.status.setImageResource(R.drawable.message_sent); + } else { + ui.status.setImageResource(R.drawable.message_stored); + } + } else if (!header.isRead()) { + // show unread messages in different color to not miss them + ui.layout.setBackgroundResource(R.drawable.msg_in_unread); + } if (item.getBody() == null) { - body.setText("\u2026"); + ui.body.setText("\u2026"); } else if (header.getContentType().equals("text/plain")) { - body.setText(StringUtils.fromUtf8(item.getBody())); + ui.body.setText(StringUtils.fromUtf8(item.getBody())); } else { // TODO support other content types } - TextView date = (TextView) v.findViewById(R.id.msgTime); long timestamp = header.getTimestamp(); - date.setText(DateUtils.getRelativeTimeSpanString(ctx, timestamp)); + ui.date.setText(DateUtils.getRelativeTimeSpanString(ctx, timestamp)); + } - return v; + @Override + public int getItemCount() { + return messages == null ? 0 : messages.size(); + } + + public boolean isEmpty() { + return messages == null || messages.size() == 0; + } + + public ConversationItem getItem(int position) { + return messages.get(position); + } + + public void add(final ConversationItem contact) { + this.messages.add(contact); + } + + public void remove(final ConversationItem contact) { + this.messages.remove(contact); + } + + public void clear() { + this.messages.beginBatchedUpdates(); + + while(messages.size() != 0) { + messages.removeItemAt(0); + } + + this.messages.endBatchedUpdates(); + } + + public static class MessageHolder extends RecyclerView.ViewHolder { + public ViewGroup layout; + public TextView body; + public TextView date; + public ImageView status; + + public MessageHolder(View v, int type) { + super(v); + + layout = (ViewGroup) v.findViewById(R.id.msgLayout); + body = (TextView) v.findViewById(R.id.msgBody); + date = (TextView) v.findViewById(R.id.msgTime); + + // outgoing message (local) + if (type == MSG_OUT) { + status = (ImageView) v.findViewById(R.id.msgStatus); + } + } } } \ No newline at end of file diff --git a/briar-android/src/org/briarproject/android/contact/ConversationItemComparator.java b/briar-android/src/org/briarproject/android/contact/ConversationItemComparator.java deleted file mode 100644 index 76eb1d28d..000000000 --- a/briar-android/src/org/briarproject/android/contact/ConversationItemComparator.java +++ /dev/null @@ -1,18 +0,0 @@ -package org.briarproject.android.contact; - -import java.util.Comparator; - -class ConversationItemComparator implements Comparator { - - static final ConversationItemComparator INSTANCE = - new ConversationItemComparator(); - - public int compare(ConversationItem a, ConversationItem b) { - // The oldest message comes first - long aTime = a.getHeader().getTimestamp(); - long bTime = b.getHeader().getTimestamp(); - if (aTime < bTime) return -1; - if (aTime > bTime) return 1; - return 0; - } -} From 880333f0946777efe891c741065c2a4b03fa4646 Mon Sep 17 00:00:00 2001 From: Torsten Grote Date: Mon, 28 Dec 2015 17:04:03 -0200 Subject: [PATCH 3/3] address issues found so far in code review --- .../android/contact/ConversationActivity.java | 32 +++++++++++-------- .../android/contact/ConversationAdapter.java | 17 +++++++--- 2 files changed, 31 insertions(+), 18 deletions(-) diff --git a/briar-android/src/org/briarproject/android/contact/ConversationActivity.java b/briar-android/src/org/briarproject/android/contact/ConversationActivity.java index d62f6bf63..f00647318 100644 --- a/briar-android/src/org/briarproject/android/contact/ConversationActivity.java +++ b/briar-android/src/org/briarproject/android/contact/ConversationActivity.java @@ -3,6 +3,7 @@ package org.briarproject.android.contact; import android.content.DialogInterface; import android.content.Intent; import android.graphics.PorterDuff; +import android.os.Build; import android.os.Bundle; import android.support.v7.app.ActionBar; import android.support.v7.app.AlertDialog; @@ -133,21 +134,24 @@ public class ConversationActivity extends BriarActivity list.setAdapter(adapter); list.setVisibility(GONE); // scroll down when opening keyboard - list.addOnLayoutChangeListener(new View.OnLayoutChangeListener() { - @Override - public void onLayoutChange(View v, - int left, int top, int right, int bottom, - int oldLeft, int oldTop, int oldRight, int oldBottom) { - if (bottom < oldBottom) { - list.postDelayed(new Runnable() { - @Override - public void run() { - list.scrollToPosition(adapter.getItemCount() - 1); - } - }, 100); + if (Build.VERSION.SDK_INT >= 11) { + list.addOnLayoutChangeListener(new View.OnLayoutChangeListener() { + @Override + public void onLayoutChange(View v, + int left, int top, int right, int bottom, + int oldLeft, int oldTop, int oldRight, int oldBottom) { + if (bottom < oldBottom) { + list.postDelayed(new Runnable() { + @Override + public void run() { + list.scrollToPosition( + adapter.getItemCount() - 1); + } + }, 100); + } } - } - }); + }); + } content = (EditText) findViewById(R.id.contentView); sendButton = (ImageButton) findViewById(R.id.sendButton); diff --git a/briar-android/src/org/briarproject/android/contact/ConversationAdapter.java b/briar-android/src/org/briarproject/android/contact/ConversationAdapter.java index 4b945f7d3..0e183a63b 100644 --- a/briar-android/src/org/briarproject/android/contact/ConversationAdapter.java +++ b/briar-android/src/org/briarproject/android/contact/ConversationAdapter.java @@ -121,8 +121,17 @@ class ConversationAdapter extends ui.status.setImageResource(R.drawable.message_stored); } } else if (!header.isRead()) { + int bottom = ui.layout.getPaddingBottom(); + int top = ui.layout.getPaddingTop(); + int right = ui.layout.getPaddingRight(); + int left = ui.layout.getPaddingLeft(); + // show unread messages in different color to not miss them ui.layout.setBackgroundResource(R.drawable.msg_in_unread); + + // re-apply the previous padding due to bug in some Android versions + // see: https://code.google.com/p/android/issues/detail?id=17885 + ui.layout.setPadding(left, top, right, bottom); } if (item.getBody() == null) { @@ -150,12 +159,12 @@ class ConversationAdapter extends return messages.get(position); } - public void add(final ConversationItem contact) { - this.messages.add(contact); + public void add(final ConversationItem message) { + this.messages.add(message); } - public void remove(final ConversationItem contact) { - this.messages.remove(contact); + public void remove(final ConversationItem message) { + this.messages.remove(message); } public void clear() {