From 0a8c42b939bd1f2369027d7cb0c858f0451515b7 Mon Sep 17 00:00:00 2001
From: Torsten Grote <t@grobox.de>
Date: Tue, 8 Dec 2015 11:42:11 -0200
Subject: [PATCH] Improve how the status of messages is indicated.

Remove the Toast that always says 'Message Sent' and show graphical
indicators instead that show either:
* message is waiting to be sent
* message was sent (or requested)
* message was delivered
---
 .../res/drawable-hdpi/message_delivered.png   | Bin 284 -> 479 bytes
 .../res/drawable-hdpi/message_sent.png        | Bin 0 -> 284 bytes
 .../res/drawable-hdpi/message_stored.png      | Bin 0 -> 323 bytes
 .../res/drawable-mdpi/message_delivered.png   | Bin 238 -> 313 bytes
 .../res/drawable-mdpi/message_sent.png        | Bin 0 -> 238 bytes
 .../res/drawable-mdpi/message_stored.png      | Bin 0 -> 237 bytes
 .../res/drawable-xhdpi/message_delivered.png  | Bin 392 -> 627 bytes
 .../res/drawable-xhdpi/message_sent.png       | Bin 0 -> 392 bytes
 .../res/drawable-xhdpi/message_stored.png     | Bin 0 -> 443 bytes
 .../res/drawable-xxhdpi/message_stored.png    | Bin 0 -> 683 bytes
 .../res/drawable-xxxhdpi/message_stored.png   | Bin 0 -> 969 bytes
 .../android/contact/ConversationActivity.java |  18 ++++++++----
 .../android/contact/ConversationAdapter.java  |  15 ++++++----
 .../android/contact/ConversationItem.java     |  14 +++++----
 .../api/event/MessagesSentEvent.java          |  27 ++++++++++++++++++
 .../db/DatabaseComponentImpl.java             |   3 ++
 16 files changed, 60 insertions(+), 17 deletions(-)
 create mode 100644 briar-android/res/drawable-hdpi/message_sent.png
 create mode 100644 briar-android/res/drawable-hdpi/message_stored.png
 create mode 100644 briar-android/res/drawable-mdpi/message_sent.png
 create mode 100644 briar-android/res/drawable-mdpi/message_stored.png
 create mode 100644 briar-android/res/drawable-xhdpi/message_sent.png
 create mode 100644 briar-android/res/drawable-xhdpi/message_stored.png
 create mode 100644 briar-android/res/drawable-xxhdpi/message_stored.png
 create mode 100644 briar-android/res/drawable-xxxhdpi/message_stored.png
 create mode 100644 briar-api/src/org/briarproject/api/event/MessagesSentEvent.java

diff --git a/briar-android/res/drawable-hdpi/message_delivered.png b/briar-android/res/drawable-hdpi/message_delivered.png
index 6edef05a95505d6e4605621b5975f179b331c04e..efade63916a2f36a74400bf378d587a763b690a6 100644
GIT binary patch
delta 461
zcmV;;0W$ua0^b9W9Df0qa1Cw%000SaNLh0L01FcU01FcV0GgZ_0004zNkl<ZNK5Ti
zJxc>Y5RD;fs#w^lNYGLRMQr^I(ZYY>?@8$&u(S^O0}4unfY^wQA|la3j7Z{p%gi#_
z+go#_xx$0t-p#)G*nM+sr4oDEy^V(R1Jt7oT^*2e1^djWNq?e_yjx5P8>S;>TSfkX
z)N8Os7VT(J-PN2h*n1y#c)I)WHCx@n(b}lA;+oFW<Xd&Y+hbLNBD5sS2>3+sFsUIH
zx3!$bh4)eN04H_gXgTgLke`F;aFT4N%L<qY!r~U}U9|96MH`#59}D@(kR8^i3Qz?}
zgLd%UN6)Ja1b^-l+W?(!zDKZU*qY*yJkdKcE|}IlF1gC3Y%e)_({v0mmccuQVrQ1G
z{@OH2VjP+EM_Fqc#rY3-f8iY<@j4RR!Wi2`=N~fFQGX2qtiA~1eXzv|zfAfKIB&2O
z@ZB|%=hs|3B3@+YAnxIPgun|~wEiFXUSUgm69kF9KSn%Ge?$l%zJwjH5bO@tlaBdA
z???Qbe_cHp4W!UDl5t1#NWkuS6y#?7VaNa9g-_rYY<bD{)q*m800000NkvXXu0mjf
DxBuF<

delta 265
zcmV+k0rvji1Dpbo9De}dcRlz30004VQb$4nuFf3k0002iNkl<ZNXPAzzYYOG5Qo2$
zP--M9kyR)tPT@Ux2%USLX}trlp}=$`<mgFgkSH`)T+ZG<PItd<ca!hiNoEGhl*toO
z(-1Y2@Li=qcpcaSQn(<1pMqmE{N@x4Z+otPE35)h(*llh@PD5KqNWEN0)`d-ArLif
zQPa%`Ujt{L83(sjFavg?W|RSb0Xm-RKa)Na6-<E*Ft<r8@JCv;js@ZXOJE3$J=b4+
z3y*Ens07#onirlp2NB5~xaNhY4q6~t0Ry1wx&G@P3#=w;`sFGw6Pq{lbXMMsP2|u3
P0000<MNUMnLIPld0={d)

diff --git a/briar-android/res/drawable-hdpi/message_sent.png b/briar-android/res/drawable-hdpi/message_sent.png
new file mode 100644
index 0000000000000000000000000000000000000000..6edef05a95505d6e4605621b5975f179b331c04e
GIT binary patch
literal 284
zcmV+%0ptFOP)<h;3K|Lk000e1NJLTq000;O000;W1^@s6;CDUv00001b5ch_0Itp)
z=>Px#)=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-<E*
zFt<r8@JCv;js@ZXOJE3$J=b4+3y*Ens07#onirlp2NB5~xaNhY4q6~t0Ry1wx&G@P
i3#=w;`sFGw6Pq{lbXMMsP2|u30000<MNUMnLSTZyJ!`Q5

literal 0
HcmV?d00001

diff --git a/briar-android/res/drawable-hdpi/message_stored.png b/briar-android/res/drawable-hdpi/message_stored.png
new file mode 100644
index 0000000000000000000000000000000000000000..8bf1ee459425236b46f96cc10c1912fec981d739
GIT binary patch
literal 323
zcmV-J0lfZ+P)<h;3K|Lk000e1NJLTq000;O000;W1^@s6;CDUv0003BNkl<ZNQvE*
zF%N<;5QRSigR2aVY)%FZ`~XH1-Apk40oe@1%@BUP1J}?fr46KmzN7<v@9vSiYYYF5
z2-pKxpaxo5HBbVnXl7vtG(cxrjcA<_0B0>h1>`^sgtB7Ut2Et7Vy#fgUqEIF3PkhL
zOeV3@k|!>IBS<t8W4R)Rnr8-02NVV_W9Z3f<5Py3o60g}5HR#49TQxI%nb=_21sm2
zKf+(Ag^U*%#G<Lk$X3X3fk7ymc8S3q*vv6-DbW^qNP;7<`rs!^RAO&3^dnf%&;1iP
zXxwCzUB*<$8n^)$`L>R!%Rw81>Y4SRf#<72!RuwGg1lbW3f>+Z9TELRczH5^18?!i
VKJ0vVY&ie`002ovPDHLkV1gf|fCB&k

literal 0
HcmV?d00001

diff --git a/briar-android/res/drawable-mdpi/message_delivered.png b/briar-android/res/drawable-mdpi/message_delivered.png
index 1f3807209e1db00dc0b3f07fa5f2fd0e2bd813ad..938c50d909e9dfbf0e931632a4a6282f6fe922b4 100644
GIT binary patch
delta 294
zcmV+>0onfU0l5N@9Df05^w0MI000SaNLh0L01FcU01FcV0GgZ_0002%Nkl<ZI8S3>
zfPtx(6!yb8U<RfLvOG{$1cXubKzWQvrWS(Oj6kJKK)MZx|7YtxsKly`G(n(|wNQ70
zX%;AFCy+h{#8yz60cc+{X+~35HPE4Vp>6}yC;%vV1u6-qL4U!%7)ArxXQ6B`4Gv1E
zz+5100K^wSG|-F2)O9rdOapq-7TGos9~_s208rs1pc*G2wtxl-f)A7wMKcx72g)r4
z;&VXE4b_Ok2M04yk_Sky1!9nE+<=%9h;IQgNL(5i<exzX0ofWrYzyRnL$(k(53m9y
swg9mv5UT_6A0K2sP~&$(UL6>D0Ae3nSoEMlqW}N^07*qoM6N<$f+G@Y&;S4c

delta 218
zcmV<0044vq0`38j9De{G^Z#K00004VQb$4nuFf3k0001}Nkl<ZILqaeKMKMy6o)^n
zN6^mMbc&#ZQy0NbR`3KKAd?4hb{DdDadCDj-XeH_AU#LvRCttFu#U}?yu2^@y?-#w
zWt~czebfU!19@|v{0QHGEwJn(`(mAXx9yQ|n03H+;0SEmcT+Nihjpq1PDcAmz*k^l
zv|oiDmr2Zk7<gHy#^UD`NWQ5X1>_b$34DNq(SF^Pn@|<@z!TU3^M9IUI*_@j0pY7B
U(?v8ZKL7v#07*qoM6N<$f{}n=tpET3

diff --git a/briar-android/res/drawable-mdpi/message_sent.png b/briar-android/res/drawable-mdpi/message_sent.png
new file mode 100644
index 0000000000000000000000000000000000000000..1f3807209e1db00dc0b3f07fa5f2fd0e2bd813ad
GIT binary patch
literal 238
zcmeAS@N?(olHy`uVBq!ia0vp^0wB!61|;P_|4#%`jKx9jP7LeL$-D$|R(QHNhFF|_
zI@zA<kby|M{c86M=WdpCEocrFKj;_sfkjSXGJ8Rp_@?s0!ZOW!N)-(Xw(c)ODyBqi
z=sP=Q&mR4sd+QC(q|Wu4ReOcmj=8dU-XD(p4Z0iNDF05HTebb|#DW>62g)CC<lHJZ
zYH2TB#p37o+v`AhLgJSAR=Me(XBs3bB9|X~^jySa-%4rLCt?nqH4V)d>+VjS9U%Jc
mfbb2*&-JrXttRYT!T4~s`ej!WZF``b89ZJ6T-G@yGywpZJz$Uk

literal 0
HcmV?d00001

diff --git a/briar-android/res/drawable-mdpi/message_stored.png b/briar-android/res/drawable-mdpi/message_stored.png
new file mode 100644
index 0000000000000000000000000000000000000000..01858ffc64ddf763b244d301acaa33657a5ea3d5
GIT binary patch
literal 237
zcmV<J022R+P)<h;3K|Lk000e1NJLTq000mG000mO1^@s6AM^iV0002ANkl<ZIE}TF
zy$S*`5QM)pqRmxum2DcqM@Xe`ZMZA!Y_-Z0`0y4tffzQNo;a{YW+y}TC-5iqKmej5
zh+D)Cn1CmcfU6>j8>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

literal 0
HcmV?d00001

diff --git a/briar-android/res/drawable-xhdpi/message_delivered.png b/briar-android/res/drawable-xhdpi/message_delivered.png
index a40d4d94c0fca5e85e08ce21f3ce99f8c74ceeea..99109113666357edda634c9bbcb9ebd2048e68a8 100644
GIT binary patch
delta 610
zcmV-o0-gPc1M>us9De}>eM({g000SaNLh0L01FcU01FcV0GgZ_0006dNkl<ZSV!$w
zyGjF55RIaOrC?#S@qtBrHE9%)wElpozo5UMM0;B+d$kk6(#pa{5D{M>f}MqL3m;hM
zIoFwGa&wbiF+z$B3_Ck}&&;`J@4Y+8WUBpEkGsFzb2_j``hQJ==)(1`DqNvO;<J)x
zBOa1?1k%32mLpoYX%~t&xNgpmT(>69_D=)Bsi+#3l~DGaNu;!l&LZg4QswD4m{eQv
z=V0fUW?LwA3y_`vG_ATwOKnv;>&KF#w6GUll<F%`Wu~kTFsk@2{x+@!N-pnbG9<rC
zpg&obx43_T^?$>hAAE1I+|vPdsz7vH{_I(IbT%gCDu9C7-_9>tNTFl^@<{&Vs)X&U
zkHxhY%K%^=kP1HV!7c#?t-wx&n)L~Og$=_9cD`0twz`>I0z4d)WQ^wod}Y8V{xl;E
zlm!OlVLUPk91@?E%fKZXu)1U?n6y9Qz&;yy4<^(4z<>I|!D%p6p#BxWGG2r&_)KkF
zo4=aQMmnS=B;_}D-0UlMP9^c067UM=aXK8z=C*~SIG@#o01B@o*R0Ig77oU(+>QVe
z^x`rB+X3r)BUvzRp0lN#fw2?G0ed0&g7MIMRt0#FuECl?<_uT%MEpY#j7zWdr@~6c
z@2&XPVp|tB0E>vApp6sz3>&R5<1vkgX6(m;-(;`g5kQx)DHz*KHhg_B8|N$dRpFol
wK06TUK#Yw*kGvMw2vmwEnQ=NMRlrx^8<z+gFt?^t5dZ)H07*qoM6N<$f<;6cj{pDw

delta 373
zcmV-*0gC?f1c(EW9De|FdV2H#0004VQb$4nuFf3k0003(Nkl<ZSi|j>u}T9$6h%)Y
zjiq2=y3x{N8Y|IYVZg>#&|h$V!9>w-nAV7mKVX?ALBvXA2qM@_r;RAs1k%_{AS|=V
zjM;3VbIWCibMJd^-z+30CH)s^BbwTXlkD?_lHjMnIdD<B0e=TS0|vlGsRlCeJtgg9
z_MJ*e@GT!4pgIR|6=(vjNy+DC0JsK@rX?@jfHq<gxC9P?Z(x5K+-pD^u?EzETP5vB
zgohFQ3)ocBzJwg|eFewB70}a0)IySLBW}jv^-y@8fi5rv)`5;TVmUH-Kc;n+oK#D|
zoip(aG?cV&6K;AwO5Ts19q%Gi(tZLB2hXd-Ov!^5k%M-}DzWQ;?OBrtZ$dYS9cSVR
zcm)n(r~TIkJe8n`<k5G5Hev<12UdX{C2g;W1r~f8Drw(=ZP)vU^oy00^k?(~F{OIO
TZd>{G00000NkvXXu0mjf$Bm^U

diff --git a/briar-android/res/drawable-xhdpi/message_sent.png b/briar-android/res/drawable-xhdpi/message_sent.png
new file mode 100644
index 0000000000000000000000000000000000000000..a40d4d94c0fca5e85e08ce21f3ce99f8c74ceeea
GIT binary patch
literal 392
zcmV;30eAk1P)<h;3K|Lk000e1NJLTq001BW001Be1^@s6b9#F800001b5ch_0Itp)
z=>Px$LP<nHR9M69ma$3$K@>$#B#otDVY<=MVj3&aU}3<<R?uH?e!)c1Z<yAIjXz+S
zCPBnXWC$YIOs9<~*aXtpOdu??$&A@-p>xY+hjZ_HZ{I8=B_;hAX(O82h?DH|g_7W>
zz&UVHx&a420|vlGsRlCeJtgg9_MJ*e@GT!4pgIR|6=(vjNy+DC0JsK@rX?@jfHq<g
zxC9P?Z(x5K+-pD^u?EzETP5vBgohFQ3)ocBzJwg|eFewB70}a0)IySLBW}jv^-y@8
zfi5rv)`5;TVmUH-Kc;n+oK#D|oip(aG?cV&6M8;M-jAIf?;=vtegX{#&#S~t$%7V=
zgLcO%vFm{CS(68ELN|yVXW|KX1rB1T{nrLOm7s{^(RYD1Vg<MdR)HNQZLf$07JM5j
mY2Sfu*ZYU`i<Ol0XY>OxrFzD0Tlw|?0000<MNUMnLSTYe<D|3z

literal 0
HcmV?d00001

diff --git a/briar-android/res/drawable-xhdpi/message_stored.png b/briar-android/res/drawable-xhdpi/message_stored.png
new file mode 100644
index 0000000000000000000000000000000000000000..b8eb1384a23a5819bde40bf9679643dd477604d6
GIT binary patch
literal 443
zcmV;s0Yv_ZP)<h;3K|Lk000e1NJLTq001BW001Be1^@s6b9#F80004kNkl<ZScUDE
zKTpFj5XFBgS&&ecEFg7g%R+-95EUphm0%?O2n=M%mUe6T@C<d7OXS44DwPr9Ngit5
zpVzy0wgdk-4IwZGVzXvu@2rS`HBbQG9jgFdjqPX%febkGByO(*@WBXGSpeHs@X`=U
zfyAuT?3FFsEyq@!ghya6g5|&xnDqEej7={5_P~QS`J$El9S9Wuf$@<f23I1aS@xA8
zaT_a|?HHtqjOIV@!W7s5&yIMq5}7M`M6LFm{<7a2yNx4eK&^=bjuBl8wo6Cgp#(6o
zs<`Vu!|ISJ=~ug!z=V24i!P%OMX!_ups6jZ80W$uJp+MM#J7%QEDVw}5J*J)cuWEX
za5Dx0Z3`mm@!A7#z-5oUY{ATCpcNq;)%^nOjNcA;!ahMx5rS?EC9XJXp-S)xT(^ii
z#}IS}kquMe%lO}l{lN#3<|yvM1#l;RtBztAei;pg>N0{~a2<o^2T295PqGSLAEgz%
lKFcM%eVEwb<<snM;s+n0Z~+j3?QZ}8002ovPDHLkV1h%mzTE%-

literal 0
HcmV?d00001

diff --git a/briar-android/res/drawable-xxhdpi/message_stored.png b/briar-android/res/drawable-xxhdpi/message_stored.png
new file mode 100644
index 0000000000000000000000000000000000000000..153650a1f50238963f883cfeb8990d51d9ac57a0
GIT binary patch
literal 683
zcmV;c0#yBpP)<h;3K|Lk000e1NJLTq001xm001xu1^@s6R|5Hm0007VNkl<ZXo2mS
zF;5#o5QRSur?8zUq_AY7m@ZuiMoK{u(?A6&;>Jj%jUsGPgvb{m%#Tm8d(vrc4|Zqw
zFh=*Jl`P-Qo0+@0nb}!r(V|5PWWWfR02ja<$bpqzIdBEc>^&cVt+iMxumhX|H^6=1
zx&cmrw@+?0&<DN&cb>*RwC;d2%lRbu3@j5EF4q$H)TH6tn5SN6Kn_fSF)#$Wm^k0E
zzlZkP)ZSaib8dAd#Vg=Pjlu<R0CWQQIv8gbHJq1LXA*4VHvSek!ek&VGRtx6;J+l%
zn{b8AH84m)ZZWW&u5gONzJv59(2FH@pl7+IKJ|y)r<!f9X~y^hJ*sbFi895WQ;qqM
zuqn%iU_kYoI1A)phiZ{J3gpl_fYl|7T~Nh76$A^yvrUWx8Pybf5+W>nn*)UrF%E#K
z6S8;mY5+$<Fej`?6^M19L$zX$d;}*#XsR?I)&Z>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!`<nsTM1V)7ZXM<!(>>w`h9gX2Wi^r$54dTU#gids-1>38ya7{
zar_s(p@H}<r4~uHl<)#J^|0Y%l>!?**n$@@T7<`kyJMd5aJPW(c>NI5gmp1bIJ3WZ
z?X|Ux*UQ*vLk~F0=wqH#$|I&G({n9i4*CAD#zQ`dkYm=bJfmaQ7A-a%{{gUj`-YR=
RkU0PV002ovPDHLkV1i!`GmQWM

literal 0
HcmV?d00001

diff --git a/briar-android/res/drawable-xxxhdpi/message_stored.png b/briar-android/res/drawable-xxxhdpi/message_stored.png
new file mode 100644
index 0000000000000000000000000000000000000000..b3833bc3e76f11b4abe7f1a487bb87025f003075
GIT binary patch
literal 969
zcmV;)12+7LP)<h;3K|Lk000e1NJLTq002M$002M;1^@s6s%dfF000A!Nkl<Zc%1Fq
z(Q8~q6bA5LlBJ=whAIX$_+V=d5-8YKLJL-CAk`=>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@JFF<svS!_Q*E(fd%#|C?K
ziI#+4rx%HY=5hexfUT`&j`4<YfU%uOWKIWcJFmN^=u>5E21xpfvw8~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+}<JHugRGt5Xv125934etj=4-nf^*et|Xyw
z?!!<B%eW(c`SBY*ufUV!Fht(t@F-lz_xLAZzmFgAPUP8S$6@j&M5<t2cr;JM7vrP}
zk(?>9s#wAo`29cjZ$|zbONqVKU|Y?V6s?PEiWK*#Xf%0JlzeINNfEp5%9a)<9<?2t
zjq0te7bA?m8rw->pdqqfjd3|INAIRIH22rzj4zPbF&hOECo)!!jVqBk_CGF>8DOr9
zqz0JlGPwaJDU{qWzEE<*B`A~}AXTaCkxN)AJHSO2OV89t6>EyHdG5;PhcUMwOblag
rKbZ+(_@k*^bMVpB0t+m#z|7-cs~f*?lyfk$00000NkvXXu0mjfuBgXF

literal 0
HcmV?d00001

diff --git a/briar-android/src/org/briarproject/android/contact/ConversationActivity.java b/briar-android/src/org/briarproject/android/contact/ConversationActivity.java
index 2375da4a8f..9281d1d572 100644
--- a/briar-android/src/org/briarproject/android/contact/ConversationActivity.java
+++ b/briar-android/src/org/briarproject/android/contact/ConversationActivity.java
@@ -55,6 +55,7 @@ import org.briarproject.api.event.EventListener;
 import org.briarproject.api.event.MessageAddedEvent;
 import org.briarproject.api.event.MessageExpiredEvent;
 import org.briarproject.api.event.MessagesAckedEvent;
+import org.briarproject.api.event.MessagesSentEvent;
 import org.briarproject.api.messaging.Group;
 import org.briarproject.api.messaging.GroupId;
 import org.briarproject.api.messaging.Message;
@@ -384,25 +385,31 @@ implements EventListener, OnClickListener, OnItemClickListener {
 		} else if (e instanceof MessageExpiredEvent) {
 			LOG.info("Message expired, reloading");
 			loadHeaders();
+		} else if (e instanceof MessagesSentEvent) {
+			MessagesSentEvent m = (MessagesSentEvent) e;
+			if (m.getContactId().equals(contactId)) {
+				LOG.info("Messages sent");
+				markMessages(m.getMessageIds(), ConversationItem.State.SENT);
+			}
 		} else if (e instanceof MessagesAckedEvent) {
 			MessagesAckedEvent m = (MessagesAckedEvent) e;
 			if (m.getContactId().equals(contactId)) {
 				LOG.info("Messages acked");
-				markMessagesDelivered(m.getMessageIds());
+				markMessages(m.getMessageIds(), ConversationItem.State.DELIVERED);
 			}
 		}
 	}
 
-	private void markMessagesDelivered(final Collection<MessageId> acked) {
+	private void markMessages(final Collection<MessageId> messageIds, final ConversationItem.State state) {
 		runOnUiThread(new Runnable() {
 			public void run() {
-				Set<MessageId> ackedSet = new HashSet<MessageId>(acked);
+				Set<MessageId> messages = new HashSet<MessageId>(messageIds);
 				boolean changed = false;
 				int count = adapter.getCount();
 				for (int i = 0; i < count; i++) {
 					ConversationItem item = adapter.getItem(i);
-					if (ackedSet.contains(item.getHeader().getId())) {
-						item.setDelivered(true);
+					if (messages.contains(item.getHeader().getId())) {
+						item.setStatus(state);
 						changed = true;
 					}
 				}
@@ -417,7 +424,6 @@ implements EventListener, OnClickListener, OnItemClickListener {
 		long timestamp = System.currentTimeMillis();
 		timestamp = Math.max(timestamp, getMinTimestampForNewMessage());
 		createMessage(StringUtils.toUtf8(message), timestamp);
-		Toast.makeText(this, R.string.message_sent_toast, LENGTH_SHORT).show();
 		content.setText("");
 		hideSoftKeyboard();
 	}
diff --git a/briar-android/src/org/briarproject/android/contact/ConversationAdapter.java b/briar-android/src/org/briarproject/android/contact/ConversationAdapter.java
index 14699ab724..ca85ac9443 100644
--- a/briar-android/src/org/briarproject/android/contact/ConversationAdapter.java
+++ b/briar-android/src/org/briarproject/android/contact/ConversationAdapter.java
@@ -79,11 +79,16 @@ class ConversationAdapter extends ArrayAdapter<ConversationItem> {
 
 			footer.addView(new ElasticHorizontalSpace(ctx));
 
-			ImageView delivered = new ImageView(ctx);
-			delivered.setPadding(0, 0, pad, 0);
-			delivered.setImageResource(R.drawable.message_delivered);
-			if (!item.isDelivered()) delivered.setVisibility(INVISIBLE);
-			footer.addView(delivered);
+			ImageView status = new ImageView(ctx);
+			status.setPadding(0, 0, pad, 0);
+			if (item.getStatus() == ConversationItem.State.DELIVERED) {
+				status.setImageResource(R.drawable.message_delivered);
+			} else if (item.getStatus() == ConversationItem.State.SENT) {
+				status.setImageResource(R.drawable.message_sent);
+			} else {
+				status.setImageResource(R.drawable.message_stored);
+			}
+			footer.addView(status);
 
 			TextView date = new TextView(ctx);
 			date.setTextColor(res.getColor(R.color.private_message_date));
diff --git a/briar-android/src/org/briarproject/android/contact/ConversationItem.java b/briar-android/src/org/briarproject/android/contact/ConversationItem.java
index c1959f0c5d..abf29ba7ab 100644
--- a/briar-android/src/org/briarproject/android/contact/ConversationItem.java
+++ b/briar-android/src/org/briarproject/android/contact/ConversationItem.java
@@ -5,14 +5,16 @@ import org.briarproject.api.db.MessageHeader;
 // This class is not thread-safe
 class ConversationItem {
 
+	public enum State { STORED, SENT, DELIVERED };
+
 	private final MessageHeader header;
 	private byte[] body;
-	private boolean delivered;
+	private State status;
 
 	ConversationItem(MessageHeader header) {
 		this.header = header;
 		body = null;
-		delivered = header.isDelivered();
+		status = header.isDelivered() ? State.DELIVERED : State.STORED;
 	}
 
 	MessageHeader getHeader() {
@@ -27,11 +29,11 @@ class ConversationItem {
 		this.body = body;
 	}
 
-	boolean isDelivered() {
-		return delivered;
+	State getStatus() {
+		return status;
 	}
 
-	void setDelivered(boolean delivered) {
-		this.delivered = delivered;
+	void setStatus(State state) {
+		this.status = state;
 	}
 }
diff --git a/briar-api/src/org/briarproject/api/event/MessagesSentEvent.java b/briar-api/src/org/briarproject/api/event/MessagesSentEvent.java
new file mode 100644
index 0000000000..9444ada5a1
--- /dev/null
+++ b/briar-api/src/org/briarproject/api/event/MessagesSentEvent.java
@@ -0,0 +1,27 @@
+package org.briarproject.api.event;
+
+import java.util.Collection;
+
+import org.briarproject.api.ContactId;
+import org.briarproject.api.messaging.MessageId;
+
+/** An event that is broadcast when messages are sent to a contact. */
+public class MessagesSentEvent extends Event {
+
+	private final ContactId contactId;
+	private final Collection<MessageId> acked;
+
+	public MessagesSentEvent(ContactId contactId,
+	                         Collection<MessageId> acked) {
+		this.contactId = contactId;
+		this.acked = acked;
+	}
+
+	public ContactId getContactId() {
+		return contactId;
+	}
+
+	public Collection<MessageId> getMessageIds() {
+		return acked;
+	}
+}
diff --git a/briar-core/src/org/briarproject/db/DatabaseComponentImpl.java b/briar-core/src/org/briarproject/db/DatabaseComponentImpl.java
index 32467764eb..fbf81fe6b1 100644
--- a/briar-core/src/org/briarproject/db/DatabaseComponentImpl.java
+++ b/briar-core/src/org/briarproject/db/DatabaseComponentImpl.java
@@ -52,6 +52,7 @@ import org.briarproject.api.event.MessageRequestedEvent;
 import org.briarproject.api.event.MessageToAckEvent;
 import org.briarproject.api.event.MessageToRequestEvent;
 import org.briarproject.api.event.MessagesAckedEvent;
+import org.briarproject.api.event.MessagesSentEvent;
 import org.briarproject.api.event.RemoteRetentionTimeUpdatedEvent;
 import org.briarproject.api.event.RemoteSubscriptionsUpdatedEvent;
 import org.briarproject.api.event.RemoteTransportsUpdatedEvent;
@@ -380,6 +381,7 @@ DatabaseCleaner.Callback {
 			lock.writeLock().unlock();
 		}
 		if (messages.isEmpty()) return null;
+		if (!ids.isEmpty()) eventBus.broadcast(new MessagesSentEvent(c, ids));
 		return Collections.unmodifiableList(messages);
 	}
 
@@ -455,6 +457,7 @@ DatabaseCleaner.Callback {
 			lock.writeLock().unlock();
 		}
 		if (messages.isEmpty()) return null;
+		if (!ids.isEmpty()) eventBus.broadcast(new MessagesSentEvent(c, ids));
 		return Collections.unmodifiableList(messages);
 	}
 
-- 
GitLab