From 71fda6cceda3b796083175fd735758321bcc106a Mon Sep 17 00:00:00 2001 From: Sylvain Berfini Date: Tue, 2 Apr 2013 16:05:44 +0200 Subject: [PATCH] Improve chat display for long conversations --- .gitignore | 25 +-- .../route_bluetooth_on_default.png | Bin 4145 -> 2552 bytes res/drawable-xhdpi/route_phone_on_default.png | Bin 4078 -> 2451 bytes .../route_speaker_on_default.png | Bin 3624 -> 1995 bytes res/drawable-xhdpi/routes_default.png | Bin 3239 -> 3239 bytes res/drawable-xhdpi/routes_selected.png | Bin 4972 -> 3110 bytes res/layout-FR/chat.xml | 4 +- res/layout-RU/chat.xml | 4 +- res/layout-small/chat.xml | 4 +- res/layout/chat.xml | 4 +- src/org/linphone/ChatFragment.java | 177 ++++++++++++------ src/org/linphone/ChatMessage.java | 8 +- src/org/linphone/ChatStorage.java | 3 +- src/org/linphone/ui/LinphoneScrollView.java | 56 ++++++ src/org/linphone/ui/ScrollViewListener.java | 26 +++ 15 files changed, 228 insertions(+), 83 deletions(-) create mode 100644 src/org/linphone/ui/LinphoneScrollView.java create mode 100644 src/org/linphone/ui/ScrollViewListener.java diff --git a/.gitignore b/.gitignore index 426ff4445..b04540b57 100644 --- a/.gitignore +++ b/.gitignore @@ -1,12 +1,13 @@ -libs -obj -gen -bin -doc -default.properties -local.properties -project.properties -tests/*$py.class -tests/build.xml -res/.DS_Store -bc-android.keystore +libs +obj +gen +bin +doc +default.properties +local.properties +project.properties +tests/*$py.class +tests/build.xml +res/.DS_Store +bc-android.keystore +res/raw/lpconfig.xsd \ No newline at end of file diff --git a/res/drawable-xhdpi/route_bluetooth_on_default.png b/res/drawable-xhdpi/route_bluetooth_on_default.png index 841c93b65d9239cdc437ed3a3a94729e0a88f7d2..fe59fa42a40d6f700fb1857615f598810306f1b3 100644 GIT binary patch delta 1821 zcmai#S5Om(7KTF-LMTd<5h6rLG_nB^Q%OScLYiWbx*#<$t`H$0iYzNqLR+LRQX~{1 zi?|4aL`(=}5rS)_I1xdS073dlaoH7+etC0t?!9wg{yB5zJ9Ey%|IcYae$~0Dr*Rny z0RRBSOEJI()RqboYeB){aAYEujNdJBI0_zbXGbNmh*SoSP9);c0+Weld|OAgBN6Ci7LiWG z6Y?n_#Q(o35=7(cWTYSf0En?Y!|wZQL-S?9q2Ig1Q#(vRXW7p*Bz5|Yo>}QjH}+RN za>M-AEzf3J9H&(lCE(EK54+si--*G&RedlL=TMW8;EE*lIPLsqFcGDHp&=9g!pH;K zI7&!AP&H%zHtKrANvDXu9-A45lBUmX+~TX@HhzA7z%jn=zS96W42uLnz*^7*6%`OL zz*d&<-&%2`Mylh)J1%aYgP2q zyXKu3ZC-s2;S8ra{@fpFhFb7Z2GqCk4(NZ(eOX~6*qh4{x#+zSKX}jkpv+u?XuIUnd*@R3ycN-I zFkZ@0bcDfiv)X{3_dDtG%ChgCNXv>3w$43%x4gq_ixMKp@@LVa-j92>+^pd{@}|EL zH@|>ZSuiv}3(AMX03aX)EKB&aBXPp>@uWPr(p4eH@FOEn2YKJGi@AQ_PJk@2Vy*w6 ziKX+0GYisLv-trm`b^}G(?1#V7>&eY9t)X}%Q{dQ5-^c5W9?Lae4a9=!WYTi>$g~@xwni|Xhd&i}RhN5FB(z?xnKv19 zBw01YoE&>i61X$ohp(x(s(;Y!Tad(;^{6a(bwp+7rmVNz_C}SyxzMA-?lyIp6HEu8 zF2TxQzjm|$k|YvoSJx)@P*c-Ts!OP%m6>NKOnTS}X}dB3fe=5=>-oRpg)h#FRW!30 zy}exw=hQKIQ904QJUZmJN@>uv+w(tS;Sb+eN0)wph!--3JR_^WfHK{&O1`S1(jjtd z{l^-s_``SOP1ocC@Vwq5{99VcP8a(GWCg4OTG7<`E=wRFcZ^jp43UlnKG%5*%SJWx zi%Cc9>m?FTLr3R(+``GP@ay)w(MirC2;(lr5ZQ;6rlQGyO~^dgoYQKi_-QesUpgzR zkQrMHPP9ZV=;t3$o8RU?bpB-El-hsq+UH9Lt&9zqPRrUGnr3ZZPP<*^VDR8e4ctD}e8lW!mzvvV@@r7KZqHQw2WhSp7f?b}xXj&x-6O4}MH zM&hGIPqvOmEY5|)cKx!*mh087`NR%i>>V)w@Fg}eSa{B#&)(#3E8i5x&~ArT7M!8G ziKVZ(5w6}10iy`7cC;)u04bBgG*QJUXz;% z@2U$lgQ7W79KWM9O!3p__T(z{lJZvD2r(X31eO?+j(S;ISxtRScLItADlI(Bx_>P2 z{j_9YIsLi>wN@)cZ$&~FNj@#y@e~<>(|=`swi=V3esHnc-)G~5E^T0BU_w*jsvGv$+A<2}7J@Wg}`vqFiF)-0oR-$=Sfvm|w`E7mcC*CAcqDhxe+( zy44~< delta 3427 zcmai1X*3iL_qNPnY-6pFZLEbbGs4Kv7{)L|k*!3=Qb|Z=Bt*tGWM4)|h%5M~~3Iz8OeB%`ceWW1761aR;P7i_X&jzCLj?07Yqg{;h<6qK)WcNULUI z`GW($kq_cSu7o-KED>fadG+8jf%T#1E`b$3uMT1N&-^BD^pV;p zt`sDQx9y6txpNE?tDMSq=rA<+pkLVBCN98yqkg~UP(ZOW=p{2q)Xl5rC$5t3wKH}> z#cW4{65y4V*uGKbU^>IRbPd^1+?C%rZiosZzy8z~SN5j`^k)^os)~EOZ!ey)8gt^T zQh{4E{8aTU^i3^9Sk7UJk}Q$XE;Mm(aO}D#-IqETGO#|oqvctE^3f7b3g%04i0cRu z{l(dQx5&R^j-`>fd}2j6qT|$llLul%+h;nQIUKc9P7DF=4kqlFx#vv;p<>2Ipb_?D zMMr){!0G%Rb;XhMm6wvQy)X$$MnBF;d*{yrr1U{UCri*WCh{<`c15jO286L7hD|$p z-A8msln!gIRy-C3N$Ap}bpP0xye*~sJ}_9xttX4JRwuk}L7!ywT!NKHTetYQ!O*eW z1%ukBO#z5Io>D(P-g*jilYcR2CM!a&l)~qs&Bn2{-{|_Kqsa7G!QC_g5Ov6Nj6l@W zRBLsA+zXb>&#Jp0! zj*SQ=%ujg?=%nn=)r7fP0AAZQVplc5*l#EJf;pN~>Ik&KYCCI!3WTX8! zN9}TF8O#Mf6I5i+DRDq&GZ1P>1SmzkhB{$(5@JSJ#kq>+_rr|9jUQ()=5lLgNj zjypOnzK=P1k!rmuS5T@)E{ib!WsA!V`(-fJTw$;i#+cwn52x1 zVe$dbrRF;;Q-M6?s%ma~L)f#L+BXnEVJ=2zB-^lty%wg==(2}tXPE()A;lW@Lb8~ao;r4(T?t}d=wC2k(Ajw9s z6pFXVEG6<&$_t(sxA@#fah06+wCSspZ@J0KUS6(0S0t{Dp0YHKiAu=Q!2Ifa-1?Jg zW_VwmwZY=f5FJ->tvY#P_v3eersliCqKNSrye44~t**f>NGDgG5n$ zB^$4Q@XiGqE>?zrbR1u|7)by{8=)ei%#z>t?;0eJ(};DBMxp+j39D~Hbwl^xr!-5F zBNJ|A`?N2?(irH2{QG{JBX2IJ9I8}h@HyqE|B}|b%kdTEheW6(+Paik_gWzGrl+XN zj2iK zo`?Bb%0w>8X5KzyqI6s=h;-;U(}bCaoqSbQccoXt zG147dUTQdfcN3LLmjh&pE+rorl81Tic6uW>OZv?;$*!S_#--uh>|PkzF^@^e9G}z_ z38;aZCP~h>1Z{}W$?HQ5-l0*=Kw1xF<)HZiS34aXxEC zGiJ@Wmfsc^mCM=*p=A;JLgx!BN4Zg~@1$UfOz~tUoVrW)Uq5gc5uwrBEcXD5eR;t0 zau3C5hlBbzKHld(W?wL1uMlE>_(Ot*5kIuB?tdm7ES{JAwiS53dz`gyeW3Js&)$;!7(bC4;%yR*kEH7=+ zHHpM-l0p-E1@?QyBvHA|KNN9s?2kJ$Wk7Ytk5NG@ZGs*m`=nb1_4Q*evL6aTT%2m{ zG^V0&Mz605Nxkfpy!b?L`N5?1ALXC&3HGR`%Vy`lU9}d3M5~p={#aRFR(&0M{d--4 z!;d%Q&9{a1PVlHG@wv7`nZ8y7=Hg|onO^QAsh799KJ1ZZh1=IYCrC)0_T*lPML+s{ z#$J^?(>2@@@wJ)YnQwq005L^4nZqle$RRJgtGRJJuhc{0X@ZcKZx-d@!JCEB3L8#D zF&OKWLeUe~lJE_LD?}nLvZE*5&DS9LiC9cz2UQBjpR&&5CO#7=`RZ7iW7^&i=)#7?3zwSkEF%8o=7j^GflH>)lq?}xL=EU6h^Me znYo!-U!b2M1|Ku(?{olY0>cLl1ph5*Mmz*wpt_0ZKjOT{upbND#tmJqlTndi9$Y_^ zq6k#{7pXSs9O*Wuf~t?g(HNLqU8}yp`!jSZhse{4n!nzE0muQ0{(CRC|IQ=CQiX1D l3?0t_RKqrpIQZGbItjB$QZL3r|2|V}c&w#Km9cB&e*g{`M)?2$ diff --git a/res/drawable-xhdpi/route_phone_on_default.png b/res/drawable-xhdpi/route_phone_on_default.png index 16cc9e2f3a0b476ba50c388fd3c534711264dfaf..8485d5c0d58ea02093920b66fcc0299450f059d2 100644 GIT binary patch delta 1719 zcmai#c`zG@9>>!-8bwlC>WHhF6jgGOpw37HY1g%sVuNg1N7^Oo+DJ5Q-K7mrs*5_a zUhBwO)Jp3pp{+;lTSprtRugPRi?y_9x82#9ee-7Cy#GEkzwgZV_t)pUYQ#BIeB{7I z5D)+WXmeIR=bP;9Ge+3r5J)5zgTSIbA`*#1pcV9kx)EE@PnYJ zQ(c)ZI83EHNz*}9mz+4M^=^jYJYVIs)tx=}IzuepI92wFS#iIu&0ld__3Gg_`YMkQ z!$7E-gaX*FfYa&i1Avt;A{3R)#{UEsd*7#9guRZru>wC;=8=aKd5wQyyvtC7rH{jI z#nwen_#mSuhgV77N7k!!Lu{Y_YpK}BARf61)f=fF2yk$mbsSYN4fh z(Jd2?s4jdL3P)E-e<~?y=#qvmS%&!hn#e2C^iN8tXc`FU9!Tu|wbOtuzkaUt>UR zAS`ZSW@e@pEPG_Xotl3B(x_4!F>v8n!me`F=0Prn*51KPUr!1Pdob8!g?hfs`O0mQ z8=n=N>|c~g=iR++D#SOA;7VoEEF*i4I zEl-|kx%bbk-eWhmG9r=-Y46t-+mehCo}uPeeDjA(vAK__mwN|#tu7_Z)<3NFWC0JQ ziQ=pJ5E$wY$t@v_3X5k(U^uHXoNbViES9_G!s}K@D_!Q%)R)#E@^D#$S@#)LlR4>U zFLlTwSgXae&sf+y8p{&tQ=^V3rgfn`2v)9Ea^PyyrmY1kQf?Y|64CA zn{`WK2gfUxh{iGtHXGQbpm)3c^(G`o5z+|Uq0RKZ|9a?~4+~=lxe^a1t`$zBbq#9x zB<>04rnZKuemE}aXn(i_e4oKPu@JBAg=tjWzVKq#9h5>Iy(;(}?An9Pi6qJDD>MR& z-jFBD3RosPW$L0zkzS38?7I2M6V9byYs1O|F7-gaw1F>9i7jY>D*lwU?QPuh(8b@T zj}OA?XOM)pvJj^!S>I zR-3tSqlaa`$fa-ZNK?~gg92b%>z!U!bSEt>dCMvjMCLU#+{{!vkh1kYD@)j*y^2_P zb1^s#=CBrMp|vu!>s{9KPS*WA;sN8@`V$KVgB_x^wE9qu8P)1vtkd)177u$)Jt|1( zneCrwExS!_sLFgS&Dm}H<@|16N^ElSK-tpH*6R)Yf)m?hO>U~dW?z@v%BOekmCj4* zqosLTD*Oxf0ukP0E+HZAc&geNPtW;6;j5{p3TVOYb5K#jxs0KF2e)|&&qe=88~W4; zpE0@g>;3)Ac#vTDP&2nxKIYId_Wk++&5575@k})Ya8kE59a`6(oIuv9%G+vc+)mqsK3n zr*QL>Y_NWJalY0CgB*Cktml3R1d@NHZ<&b>z8aM0;gQgtSXNi43YjIY`l^yB z|ER2-Yw6jW_Zy!`6B?0ml+96V&i%tFm%oneI6QdwV1c3C3ZYipRrmMHsfA`w|aipW+7 zW9{{dvKwT{u84-)J?EZtKizXb{LlG)_?`dre0$E5&buj|BEUuB4`&hf<(q>~3f~x1YdYw*Q>b%R&w}#(xm}xyC7wj7au{?< z2mk7(g>>fPwJ0flUU_a@WfIRH{Wy(tPmpA3j-Ho`wv2YwGyBxqdG`!sH z9JS?#W=qJkpe@>HeQT#yL`ZX)_yMu|Nod4oYb5EoV2gMVaxfq|h~W0rm;}l|vTImI z|AK?>=rBAMZ&F6j1v^C3AEfT8Ns22Zb2eIt>nRWv=Pz>}NXJ?QBnAn0`tmidzj@d- zuG{3W^r^R+GU@Dht%=s}SHKCg=holVYx>KjL*;g+Af-#5VHNY2%i#>P%5lhqJ3M{o zyBN3t#}bt>a}(g&e8G~zS5 zk2>Mp{GDW(R2J)zmq?*#$qYAGmS9XzbIfZBvGd0gnEuXfO{CE&?g(9~G_D9+BO;)w%mp6UIk zEe}i^p5zK%w3((-1fz$*$I8X^i6h~@{AIEuJ1*+yMT0@>#(K9yig@FlNs~K~9lpXG zp-OGD)IS~KHe~9Oi>qZ4pXSv@u|GCr?SI(CES>m3P;yLiS7!Xo@ivbGeoFP^(IAZ@ z!<0o0%0rZ_scxciCn8B&uO$+`5~0T)5G|`By-j@y1oVRhdSRHeu-_|B#*98COP6gz zp4?J}P&gBNeYj}ZjG*@Qrn8UdVq;Vap>^xYWb~Wq_Zu<;3iJQuYGSw%a8PhF#lr*M zN&Zl4UzM$7Y-`}t5C8&MQA~P}MY-q3;{# z>s!mZi)uQUbp^-|fgC?YG;zIHAVtw8r>CB|O5>B?#cP2^EN51%I&Dc~QwC}ujf-2#8rq& zni#&`K+*d_h)4&{Z?7JD-Oc{e?NjEjoS>f+#xkyYX6(qndG(uLI-c#NqTSk)(fUN; z=}APr;oAnu)o=8x76+s!oht!p3Tp(_a|7o+|6Dq^&Myoe%5Hq_re+#rEO%*7tSZ}B z=%%0x(qVH{O-m|Z;rU0Y^0$x6&b#@ssP_{KErFn}vY+ZJ@_zFE=}?xZ#7z~6@{v(w+FX$l7JBTm7% zk4p5?gHcoKzZXVa#U^XByFb%!SLDBlMI^oJj>75iq}nwxsgoiFEWDhtI_ZzH4;>e* zbQdN0V9`Lp*MMW888ulj7ZV3f$N&xofb?`&DVzpyRtV>B;z`l@P4~&be-ls&EOG|TeVi!dxgW_z9R&`Q`YXE) zvPWHPz_edFojU(EWQ!6VzYZ6A_&&*NY_rjY}AKTpnRq4V_e`@2?EG0kyLBeR7065r9G?Q!%S zhNr@U2*ehZ`^u!F7JDmYtFNq(l59q6uxwKmi=PdGSY)2>*j&gyU~?oKuD%8J4Mnp^V?(YcEg8}POBOfJ5}mm{X;M3au93*DwX zwGl>^o@Mf}Qdr^MJ|LFuT9W^A-NAm|^M?Ci3rDC?cdjFPqJhPmkXih5lH+JJ!(u!R1B{Gxtxy-6i2Jyv<4t^=xFC zsbbHowdW1}V(KRVRW-HF?fK3X*7vb*R&W93=`wM137J>EXpv47YuY$~p$o;8@IB26 zr-zZysn*-#_H9JM&-uSIu|>0A(SGa|Av2;4{f~bg@>SXHmFbk<8|f8;u?Js;S*FXp zugdrMqIL3N@GhRg;x`==uD}3lvpyyJfgPu=53&1vYSpu@IlrfCjZM7!_Pa+8)-`X# zb?ftia!akZi5!WKu2Nzh<(oq|P#SptD{g!?CiFB2q1v^bw{0tt3fmSK?cA*^Dm>Z6 zPQ1QXv$4B#cs=aLSMAO3;oDiht4o^a$JBan506%qb(DFS#=qTcnI4bYhCfbd;e_$u zrkyNuPaSvsU9grU=m5|T-$nkk|NH=|Xx+JdX)>b9T=O-FYk5jTxb5YNSaZUCV3Lw! z+pinFjPbPhMO0lQqoSrJ_D8L!l#Q#t8ynk0Cv3Y$S05#>HuxP2wCs;tM^p!GPK8g9 z=HRL#nlkNXD7X8&?L6UXTi7CN>rT_*^ep0*`fl!BW$?in@sp3dwO)JtKX+b`s%AYa zAHz4(;>9vay06x*ym|MO9P$m%u?mZ^^se24vs-I8X^EvzFRN%B$Ii+u_H&UlL zdUlk!eJh7FPGeV}nLpydlDKWTiBHK%F5!uCf5DDR*YW9*b0K2NSDdVgdoEI28OwPhLp>xoas*S zPa;Q=Vn-7`9)2_o3mCk5?dzRk%{^7)JR3pJb}-;9_YMzpChwNq z6SA{8-l&Q!?=-=tZ~l;?P$YokLINxgH!jGgCs70{l}d+MEhzei%Y_#w0{Q9Sk(IRb zMwl8E{QIaIc*EO<7~zDTmShm~mMv)|y*3$!Zm$t7jzd)B$0Sj8=qvJo&Xx+OyreuF zOM|G{0Hw+^%Lle(@w%vU?=n_Z?^ITjOYYB`dgz-l}s0G#$k z&rq{jJ9;kyRbr`rdb}D?u4lzABZv)gL}q>R92@IRguz8afZ^|eN;0mOkV`V?I9UO( zC#Q^@ddn!-xKmvoj&q2WW|#VRMl2DO-?y&(j1U!6LI%DD8C*~W-Fk9(%F4|$;Vmj; UX1BQc`w?O>B$(>Gz&la@1?gEQcmMzZ diff --git a/res/drawable-xhdpi/route_speaker_on_default.png b/res/drawable-xhdpi/route_speaker_on_default.png index 8cfdc036ad034fbcb66cd3ed35273d590be87b17..5601ecd8e1980aded4f1311feea61e9c5a485d1f 100644 GIT binary patch delta 1260 zcmZ1>bDDpGI9CA&69WT-*yJ~%8x{XDDj1kq7#JFwn;4iI0hxw|7Dh&nj+UlwCYCOS z&L$>ClkJ#f6pUSsj7`j(%`J_c91RU!jVw*voSn@KTuq#fEZm%p%_mnO6q(^vw2diA z!NtwM%-Gn~)xZT|ou#9xv9r0GiL;53@nj2T8NzNVVRouNeEWGg0|WCphmb9Z;DaK2n*uz1s(hI&WwSeDq5;8>9*OBOC$d9zW$@u0?< z4!<;ZEe@qqHY!t7S+-8y^K$+S@B~1t<740WhCqjYRz0ZkEX3Z5w_WX{nk~h z7HQb2ugF^Pd2!pdgvw(wuYQ!zOfzM-$k^C3ugJISW_jYb{^Cu+TNYlD-CfhQhNb$d zedof*Sq~m7ZuT`=$@qS&W>QH0Ob4x3JMvx$=zp)Dp?On{^WH`cMn+~NC~P25Zy;ds zr~b!mot2M^)4xv5KD$1y{`D)f*=J8r)4R8&?(VgolGXPY+uA05Y3D8d>Rai$RBw9r zm5)a%IaOJAUc4B{vL-q2-oEN>dyFDjCxxp`6@7YfQEBJ#$ClxNrGLZTN<80Fbyw+- zRE|UQ*0wqId)BPm_i=kVSAfi6$vb!N7F%quU+{KuuV$3Pt(>mTl;gxiJ z7W3xIFO9C*-B8FbI6L=uGS8Vc2dfS}EXi{IbfR(Rt3yj~RrB}kj2BQz@ZFkT`ZcO6 z|Nh?c@87)@f)36z>HgW|#>XW=Ll0U&Dw+h#V9h;CH7_<~i;%*g8s2e;Q2FkUI zkLIXd3_QWt?mVNraOa&|v)On59WIysYE$)R$-jC?i-E4{=YITOZyvlwVaXaVy>sU~dpOLmN!_`AJ$(iDyO%%fwrsd^ z&2HV=;Fr#% zVwc1kCQt2Y#wjmn%hpGmr^{O{;C%Z($f@SezP;5hJEp!Z+nthQwZCR>)#7Kq-r3>b zABZp1jof0OTk89(&7@l*zUA8O+uDrIVg@OUY{2xSD`g;IAkoYSg^dl3V!a0&kf21* zK?$B+W;3KZWH-2UFLPyf7K3Fn*#rZ|W`#dO2@KC&YCnJ5*ZK`usxf%F`njxgN@xNA D=20h; delta 2902 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 diff --git a/res/drawable-xhdpi/routes_selected.png b/res/drawable-xhdpi/routes_selected.png index 9930fd81ec4ea0fec1f9514eb8db935c00dfa4ec..77546f8b2ace3ad9c3a6d992ad40a5a38a618536 100644 GIT binary patch delta 2382 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 BWLE$H delta 4258 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 diff --git a/res/layout-FR/chat.xml b/res/layout-FR/chat.xml index 8acf785ba..5eeb2081a 100644 --- a/res/layout-FR/chat.xml +++ b/res/layout-FR/chat.xml @@ -31,7 +31,7 @@ - - + - - + - - + - - + latestImageMessages; + private int messagesFilterLimit = 0; + private List messagesList; private ProgressBar progressBar; private int bytesSent; @@ -148,7 +152,7 @@ public class ChatFragment extends Fragment implements OnClickListener, LinphoneC textLayout = (RelativeLayout) view.findViewById(R.id.messageLayout); messagesLayout = (RelativeLayout) view.findViewById(R.id.messages); - messagesScrollView = (ScrollView) view.findViewById(R.id.chatScrollView); + messagesScrollView = (LinphoneScrollView) view.findViewById(R.id.chatScrollView); progressBar = (ProgressBar) view.findViewById(R.id.progressbar); sendImage = (TextView) view.findViewById(R.id.sendPicture); @@ -171,6 +175,9 @@ public class ChatFragment extends Fragment implements OnClickListener, LinphoneC } }); + if (savedInstanceState != null) { + messagesFilterLimit = savedInstanceState.getInt("messagesFilterLimit"); + } displayChat(displayName, pictureUri); LinphoneCore lc = LinphoneManager.getLcIfManagerNotDestroyedOrNull(); @@ -223,10 +230,15 @@ public class ChatFragment extends Fragment implements OnClickListener, LinphoneC return view; } + private void refreshMessages() { + messagesList = LinphoneActivity.instance().getChatMessages(sipUri); + } + @Override public void onSaveInstanceState(Bundle outState) { outState.putString("fileToUploadPath", fileToUploadPath); outState.putParcelable("imageToUpload", imageToUpload); + outState.putInt("messagesFilterLimit", messagesFilterLimit); super.onSaveInstanceState(outState); } @@ -255,32 +267,73 @@ public class ChatFragment extends Fragment implements OnClickListener, LinphoneC public void showKeyboardVisibleMode() { LinphoneActivity.instance().hideMenu(true); contactPicture.setVisibility(View.GONE); - scrollToEnd(); + //scrollToEnd(); } public void hideKeyboardVisibleMode() { LinphoneActivity.instance().hideMenu(false); contactPicture.setVisibility(View.VISIBLE); - scrollToEnd(); + //scrollToEnd(); } private void invalidate() { - messagesLayout.removeAllViews(); - List messagesList = LinphoneActivity.instance().getChatMessages(sipUri); + refreshMessages(); - previousMessageID = -1; - ChatStorage chatStorage = LinphoneActivity.instance().getChatStorage(); - for (ChatMessage msg : messagesList) { - if (msg.getMessage() != null) { - displayMessage(msg.getId(), msg.getMessage(), msg.getTimestamp(), msg.isIncoming(), msg.getStatus(), messagesLayout); - } else { - displayImageMessage(msg.getId(), msg.getImage(), msg.getTimestamp(), msg.isIncoming(), msg.getStatus(), messagesLayout); - } - chatStorage.markMessageAsRead(msg.getId()); - } - LinphoneActivity.instance().updateMissedChatCount(); - - scrollToEnd(); + if (messagesFilterLimit == 0) { + if (messagesList.size() > MESSAGES_STEP) + messagesFilterLimit = MESSAGES_STEP; + else + messagesFilterLimit = messagesList.size(); + } else { + if (messagesFilterLimit + MESSAGES_STEP <= messagesList.size()) + messagesFilterLimit += MESSAGES_STEP; + else + messagesFilterLimit = messagesList.size(); + } + invalidate(messagesFilterLimit); + } + + private void invalidate(final int limit) { + messagesLayout.removeAllViews(); + + mHandler.post(new Runnable() { + @Override + public void run() { + + previousMessageID = -1; + ChatStorage chatStorage = LinphoneActivity.instance().getChatStorage(); + + for (int i = messagesList.size() - limit; i < messagesList.size(); i++) { + ChatMessage msg = messagesList.get(i); + if (msg.getMessage() != null) { + displayMessage(msg.getId(), msg.getMessage(), msg.getTimestamp(), msg.isIncoming(), msg.getStatus(), messagesLayout); + } else { + displayImageMessage(msg.getId(), msg.getImage(), msg.getTimestamp(), msg.isIncoming(), msg.getStatus(), messagesLayout); + } + + if (!msg.isRed()) + chatStorage.markMessageAsRead(msg.getId()); + } + LinphoneActivity.instance().updateMissedChatCount(); + + if (limit < messagesList.size()) { + messagesScrollView.setScrollViewListener(new ScrollViewListener() { + @Override + public void OnScrollToTop(final int previousHeight) { + invalidate();mHandler.postDelayed(new Runnable() { + @Override + public void run() { + //Scroll to latest saw message + messagesScrollView.scrollTo(0, messagesLayout.getChildAt(MESSAGES_STEP-1).getBottom()); + } + }, 300); + } + }); + } else { + messagesScrollView.setScrollViewListener(null); + } + } + }); } private void displayChat(String displayName, String pictureUri) { @@ -288,8 +341,7 @@ public class ChatFragment extends Fragment implements OnClickListener, LinphoneC contactName.setText(LinphoneUtils.getUsernameFromAddress(sipUri)); } else if (displayName == null) { contactName.setText(sipUri); - } - else { + } else { contactName.setText(displayName); } @@ -299,44 +351,37 @@ public class ChatFragment extends Fragment implements OnClickListener, LinphoneC contactPicture.setImageResource(R.drawable.unknown_small); } - messagesScrollView.post(new Runnable() { - @Override - public void run() { - scrollToEnd(); - } - }); + if (messagesFilterLimit == 0) + invalidate(); + else { + invalidate(messagesFilterLimit); + } - invalidate(); + scrollToEnd(); } - private void displayMessage(final int id, final String message, final String time, final boolean isIncoming, final LinphoneChatMessage.State status, final RelativeLayout layout) { - mHandler.post(new Runnable() { - @Override - public void run() { - BubbleChat bubble = new BubbleChat(layout.getContext(), id, message, null, time, isIncoming, status, previousMessageID); - if (!isIncoming) { - lastSentMessageBubble = bubble; - } - previousMessageID = id; - layout.addView(bubble.getView()); - registerForContextMenu(bubble.getView()); - } - }); + private void displayMessage(int id, String message, String time, boolean isIncoming, LinphoneChatMessage.State status, RelativeLayout layout) { + BubbleChat bubble = new BubbleChat(layout.getContext(), id, message, null, time, isIncoming, status, previousMessageID); + if (!isIncoming) { + lastSentMessageBubble = bubble; + } + + View v = bubble.getView(); + previousMessageID = id; + layout.addView(v); + registerForContextMenu(v); } - private void displayImageMessage(final int id, final Bitmap image, final String time, final boolean isIncoming, final LinphoneChatMessage.State status, final RelativeLayout layout) { - mHandler.post(new Runnable() { - @Override - public void run() { - BubbleChat bubble = new BubbleChat(layout.getContext(), id, null, image, time, isIncoming, status, previousMessageID); - if (!isIncoming) { - lastSentMessageBubble = bubble; - } - previousMessageID = id; - layout.addView(bubble.getView()); - registerForContextMenu(bubble.getView()); - } - }); + private void displayImageMessage(int id, Bitmap image, String time, boolean isIncoming, LinphoneChatMessage.State status, RelativeLayout layout) { + BubbleChat bubble = new BubbleChat(layout.getContext(), id, null, image, time, isIncoming, status, previousMessageID); + if (!isIncoming) { + lastSentMessageBubble = bubble; + } + + View v = bubble.getView(); + previousMessageID = id; + layout.addView(v); + registerForContextMenu(v); } public void changeDisplayedChat(String newSipUri, String displayName, String pictureUri) { @@ -351,6 +396,7 @@ public class ChatFragment extends Fragment implements OnClickListener, LinphoneC LinphoneActivity.instance().getChatStorage().deleteDraft(sipUri); } + messagesFilterLimit = 0; sipUri = newSipUri; if (LinphoneActivity.isInstanciated()) { String draft = LinphoneActivity.instance().getChatStorage().getDraft(sipUri); @@ -444,7 +490,6 @@ public class ChatFragment extends Fragment implements OnClickListener, LinphoneC LinphoneActivity.instance().selectMenu(FragmentsAvailable.CHAT); LinphoneActivity.instance().updateChatFragment(this); } - scrollToEnd(); if (LinphoneActivity.isInstanciated()) { String draft = LinphoneActivity.instance().getChatStorage().getDraft(sipUri); @@ -503,7 +548,7 @@ public class ChatFragment extends Fragment implements OnClickListener, LinphoneC } private void scrollToEnd() { - mHandler.postDelayed(new Runnable() { + messagesScrollView.postDelayed(new Runnable() { @Override public void run() { messagesScrollView.fullScroll(View.FOCUS_DOWN); @@ -519,14 +564,24 @@ public class ChatFragment extends Fragment implements OnClickListener, LinphoneC } } - public void onMessageReceived(int id, LinphoneAddress from, LinphoneChatMessage message) { + public void onMessageReceived(final int id, LinphoneAddress from, final LinphoneChatMessage message) { if (from.asStringUriOnly().equals(sipUri)) { if (message.getText() != null) { - displayMessage(id, message.getText(), String.valueOf(System.currentTimeMillis()), true, null, messagesLayout); + mHandler.post(new Runnable() { + @Override + public void run() { + displayMessage(id, message.getText(), String.valueOf(System.currentTimeMillis()), true, null, messagesLayout); + } + }); } else if (message.getExternalBodyUrl() != null) { byte[] rawImage = LinphoneActivity.instance().getChatStorage().getRawImageFromMessage(id); - Bitmap bm = BitmapFactory.decodeByteArray(rawImage, 0, rawImage.length); - displayImageMessage(id, bm, String.valueOf(System.currentTimeMillis()), true, null, messagesLayout); + final Bitmap bm = BitmapFactory.decodeByteArray(rawImage, 0, rawImage.length); + mHandler.post(new Runnable() { + @Override + public void run() { + displayImageMessage(id, bm, String.valueOf(System.currentTimeMillis()), true, null, messagesLayout); + } + }); } scrollToEnd(); } diff --git a/src/org/linphone/ChatMessage.java b/src/org/linphone/ChatMessage.java index 081784ef9..185e3f474 100644 --- a/src/org/linphone/ChatMessage.java +++ b/src/org/linphone/ChatMessage.java @@ -33,8 +33,9 @@ public class ChatMessage { private int status; private int id; private Bitmap image; + private boolean isRed; - public ChatMessage(int id, String message, byte[] rawImage, String timestamp, boolean incoming, int status) { + public ChatMessage(int id, String message, byte[] rawImage, String timestamp, boolean incoming, int status, boolean red) { super(); this.id = id; this.message = message; @@ -42,6 +43,7 @@ public class ChatMessage { this.incoming = incoming; this.status = status; this.image = rawImage != null ? BitmapFactory.decodeByteArray(rawImage, 0, rawImage.length) : null; + this.isRed = red; } public int getId() { @@ -83,4 +85,8 @@ public class ChatMessage { public Bitmap getImage() { return image; } + + public boolean isRed() { + return isRed; + } } diff --git a/src/org/linphone/ChatStorage.java b/src/org/linphone/ChatStorage.java index 54c9f4a8c..714de16b1 100644 --- a/src/org/linphone/ChatStorage.java +++ b/src/org/linphone/ChatStorage.java @@ -193,8 +193,9 @@ public class ChatStorage { timestamp = c.getString(c.getColumnIndex("time")); int status = c.getInt(c.getColumnIndex("status")); byte[] rawImage = c.getBlob(c.getColumnIndex("image")); + int read = c.getInt(c.getColumnIndex("read")); - ChatMessage chatMessage = new ChatMessage(id, message, rawImage, timestamp, direction == INCOMING, status); + ChatMessage chatMessage = new ChatMessage(id, message, rawImage, timestamp, direction == INCOMING, status, read == READ); chatMessages.add(chatMessage); } catch (Exception e) { e.printStackTrace(); diff --git a/src/org/linphone/ui/LinphoneScrollView.java b/src/org/linphone/ui/LinphoneScrollView.java new file mode 100644 index 000000000..39d9a60ab --- /dev/null +++ b/src/org/linphone/ui/LinphoneScrollView.java @@ -0,0 +1,56 @@ +package org.linphone.ui; +/* +LinphoneScrollView.java +Copyright (C) 2013 Belledonne Communications, Grenoble, France + +This program is free software; you can redistribute it and/or +modify it under the terms of the GNU General Public License +as published by the Free Software Foundation; either version 2 +of the License, or (at your option) any later version. + +This program is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +GNU General Public License for more details. + +You should have received a copy of the GNU General Public License +along with this program; if not, write to the Free Software +Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. +*/ +import android.content.Context; +import android.util.AttributeSet; +import android.widget.ScrollView; + +/** + * @author Sylvain Berfini + */ +public class LinphoneScrollView extends ScrollView { + private ScrollViewListener scrollViewListener = null; + + public LinphoneScrollView(Context context) { + super(context); + } + + public LinphoneScrollView(Context context, AttributeSet attrs, int defStyle) { + super(context, attrs, defStyle); + } + + public LinphoneScrollView(Context context, AttributeSet attrs) { + super(context, attrs); + } + + public void setScrollViewListener(ScrollViewListener scrollViewListener) { + this.scrollViewListener = scrollViewListener; + } + + @Override + protected void onScrollChanged(int x, int y, int oldx, int oldy) { + super.onScrollChanged(x, y, oldx, oldy); + if (y >= getMeasuredHeight() && scrollViewListener != null) { + //scrollViewListener.OnScrollToBottom(); + } + else if (y == 0 && scrollViewListener != null) { + scrollViewListener.OnScrollToTop(getMeasuredHeight()); + } + } +} diff --git a/src/org/linphone/ui/ScrollViewListener.java b/src/org/linphone/ui/ScrollViewListener.java new file mode 100644 index 000000000..ff964f604 --- /dev/null +++ b/src/org/linphone/ui/ScrollViewListener.java @@ -0,0 +1,26 @@ +package org.linphone.ui; +/* +ScrollViewListener.java +Copyright (C) 2013 Belledonne Communications, Grenoble, France + +This program is free software; you can redistribute it and/or +modify it under the terms of the GNU General Public License +as published by the Free Software Foundation; either version 2 +of the License, or (at your option) any later version. + +This program is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +GNU General Public License for more details. + +You should have received a copy of the GNU General Public License +along with this program; if not, write to the Free Software +Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. +*/ + +/** + * @author Sylvain Berfini + */ +public interface ScrollViewListener { + void OnScrollToTop(int previousHeight); +}