From 5ea7ff2857337e6ccd80b58a4fe1b944126370d5 Mon Sep 17 00:00:00 2001 From: Torsten Grote <t@grobox.de> Date: Tue, 19 Jan 2016 13:28:59 -0200 Subject: [PATCH] UI for introducing two contacts to each other Show system notification for successful introductions --- briar-android/AndroidManifest.xml | 12 +- briar-android/res/drawable-hdpi/msg_in.9.png | Bin 957 -> 28820 bytes briar-android/res/drawable-hdpi/msg_out.9.png | Bin 1871 -> 28701 bytes .../res/drawable-hdpi/notice_in.9.png | Bin 0 -> 28610 bytes .../res/drawable-hdpi/notice_out.9.png | Bin 0 -> 28539 bytes briar-android/res/drawable-mdpi/msg_in.9.png | Bin 669 -> 27532 bytes briar-android/res/drawable-mdpi/msg_out.9.png | Bin 1693 -> 27708 bytes .../res/drawable-mdpi/notice_in.9.png | Bin 0 -> 27363 bytes .../res/drawable-mdpi/notice_out.9.png | Bin 0 -> 27737 bytes .../res/drawable-v21/round_button.xml | 16 + briar-android/res/drawable-xhdpi/msg_in.9.png | Bin 1453 -> 20316 bytes .../res/drawable-xhdpi/msg_out.9.png | Bin 2258 -> 20167 bytes .../res/drawable-xhdpi/notice_in.9.png | Bin 0 -> 19905 bytes .../res/drawable-xhdpi/notice_out.9.png | Bin 0 -> 19970 bytes .../res/drawable-xxhdpi/msg_in.9.png | Bin 2231 -> 31767 bytes .../res/drawable-xxhdpi/msg_out.9.png | Bin 3076 -> 31573 bytes .../res/drawable-xxhdpi/notice_in.9.png | Bin 0 -> 20623 bytes .../res/drawable-xxhdpi/notice_out.9.png | Bin 0 -> 20635 bytes .../res/drawable/contact_offline.xml | 21 ++ briar-android/res/drawable/contact_online.xml | 21 ++ .../res/drawable/ic_contact_introduction.xml | 5 + .../drawable/introduction_notification.xml | 9 + .../res/drawable/introduction_white.xml | 9 + .../res/drawable/message_delivered_white.xml | 5 + .../res/drawable/message_sent_white.xml | 5 + .../res/drawable/message_stored_white.xml | 5 + briar-android/res/drawable/round_button.xml | 13 + .../res/drawable/social_send_now_white.xml | 9 + .../res/layout/activity_contact_list.xml | 1 - .../res/layout/activity_conversation.xml | 57 ++- .../res/layout/activity_introduction.xml | 6 + .../res/layout/contact_avatar_status.xml | 28 ++ .../layout/introduction_contact_chooser.xml | 8 + .../res/layout/introduction_message.xml | 99 +++++ .../res/layout/list_item_contact.xml | 69 ++-- .../res/layout/list_item_introduction_in.xml | 67 ++++ .../res/layout/list_item_introduction_out.xml | 57 +++ briar-android/res/layout/list_item_msg_in.xml | 36 +- .../res/layout/list_item_msg_out.xml | 32 +- .../res/layout/list_item_notice_in.xml | 34 ++ .../res/layout/list_item_notice_out.xml | 52 +++ ...t_actions.xml => conversation_actions.xml} | 10 +- briar-android/res/values/color.xml | 4 + briar-android/res/values/dimens.xml | 6 +- briar-android/res/values/strings.xml | 23 ++ briar-android/res/values/styles.xml | 28 +- .../android/AndroidComponent.java | 9 + .../AndroidNotificationManagerImpl.java | 62 ++++ .../briarproject/android/BaseActivity.java | 2 +- .../android/contact/ContactListAdapter.java | 107 ++++-- .../android/contact/ContactListFragment.java | 105 +++++- .../android/contact/ContactListItem.java | 33 +- .../android/contact/ConversationActivity.java | 299 ++++++++++++--- .../android/contact/ConversationAdapter.java | 345 +++++++++++++++--- .../ConversationIntroductionInItem.java | 47 +++ .../ConversationIntroductionOutItem.java | 48 +++ .../android/contact/ConversationItem.java | 107 ++++-- .../contact/ConversationMessageItem.java | 73 ++++ .../contact/ConversationNoticeInItem.java | 32 ++ .../contact/ConversationNoticeItem.java | 19 + .../contact/ConversationNoticeOutItem.java | 44 +++ .../introduction/ContactChooserFragment.java | 243 ++++++++++++ .../introduction/IntroductionActivity.java | 107 ++++++ .../IntroductionMessageFragment.java | 235 ++++++++++++ .../android/util/BriarRecyclerView.java | 7 +- 65 files changed, 2399 insertions(+), 272 deletions(-) create mode 100644 briar-android/res/drawable-hdpi/notice_in.9.png create mode 100644 briar-android/res/drawable-hdpi/notice_out.9.png create mode 100644 briar-android/res/drawable-mdpi/notice_in.9.png create mode 100644 briar-android/res/drawable-mdpi/notice_out.9.png create mode 100644 briar-android/res/drawable-v21/round_button.xml create mode 100644 briar-android/res/drawable-xhdpi/notice_in.9.png create mode 100644 briar-android/res/drawable-xhdpi/notice_out.9.png create mode 100644 briar-android/res/drawable-xxhdpi/notice_in.9.png create mode 100644 briar-android/res/drawable-xxhdpi/notice_out.9.png create mode 100644 briar-android/res/drawable/contact_offline.xml create mode 100644 briar-android/res/drawable/contact_online.xml create mode 100644 briar-android/res/drawable/ic_contact_introduction.xml create mode 100644 briar-android/res/drawable/introduction_notification.xml create mode 100644 briar-android/res/drawable/introduction_white.xml create mode 100644 briar-android/res/drawable/message_delivered_white.xml create mode 100644 briar-android/res/drawable/message_sent_white.xml create mode 100644 briar-android/res/drawable/message_stored_white.xml create mode 100644 briar-android/res/drawable/round_button.xml create mode 100644 briar-android/res/drawable/social_send_now_white.xml create mode 100644 briar-android/res/layout/activity_introduction.xml create mode 100644 briar-android/res/layout/contact_avatar_status.xml create mode 100644 briar-android/res/layout/introduction_contact_chooser.xml create mode 100644 briar-android/res/layout/introduction_message.xml create mode 100644 briar-android/res/layout/list_item_introduction_in.xml create mode 100644 briar-android/res/layout/list_item_introduction_out.xml create mode 100644 briar-android/res/layout/list_item_notice_in.xml create mode 100644 briar-android/res/layout/list_item_notice_out.xml rename briar-android/res/menu/{contact_actions.xml => conversation_actions.xml} (53%) create mode 100644 briar-android/src/org/briarproject/android/contact/ConversationIntroductionInItem.java create mode 100644 briar-android/src/org/briarproject/android/contact/ConversationIntroductionOutItem.java create mode 100644 briar-android/src/org/briarproject/android/contact/ConversationMessageItem.java create mode 100644 briar-android/src/org/briarproject/android/contact/ConversationNoticeInItem.java create mode 100644 briar-android/src/org/briarproject/android/contact/ConversationNoticeItem.java create mode 100644 briar-android/src/org/briarproject/android/contact/ConversationNoticeOutItem.java create mode 100644 briar-android/src/org/briarproject/android/introduction/ContactChooserFragment.java create mode 100644 briar-android/src/org/briarproject/android/introduction/IntroductionActivity.java create mode 100644 briar-android/src/org/briarproject/android/introduction/IntroductionMessageFragment.java diff --git a/briar-android/AndroidManifest.xml b/briar-android/AndroidManifest.xml index cb723afa40..dc0874e3b0 100644 --- a/briar-android/AndroidManifest.xml +++ b/briar-android/AndroidManifest.xml @@ -90,6 +90,7 @@ <activity android:name=".android.contact.ConversationActivity" android:label="@string/app_name" + android:theme="@style/BriarThemeNoActionBar.Default" android:parentActivityName=".android.NavDrawerActivity" android:windowSoftInputMode="stateHidden"> <meta-data @@ -174,7 +175,16 @@ android:parentActivityName=".android.NavDrawerActivity"> <meta-data android:name="android.support.PARENT_ACTIVITY" - android:value=".android.NavDrawerActivity" + android:value=".android.NavDrawerActivity"/> + </activity> + <activity + android:name=".android.introduction.IntroductionActivity" + android:label="@string/introduction_activity_title" + android:parentActivityName=".android.contact.ConversationActivity" + android:windowSoftInputMode="stateHidden|adjustResize"> + <meta-data + android:name="android.support.PARENT_ACTIVITY" + android:value=".android.contact.ConversationActivity" /> </activity> <activity diff --git a/briar-android/res/drawable-hdpi/msg_in.9.png b/briar-android/res/drawable-hdpi/msg_in.9.png index 974d60e2d7aeec5229de2b26495af671ddb579ba..20202244fa3d456a7edb956718dbbafdc1a69139 100644 GIT binary patch literal 28820 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 literal 957 zcmV;u148_XP)<h;3K|Lk000e1NJLTq001%o001}$1^@s6zoe_z00004XF*Lt006JZ zHwB960000PbVXQnQ*UN;cVTj606}DLVr3vnZDD6+Qe|Oed2z{QJOBU#Pf0{URCwC# znq5c~Q547To!wct&6gI#f;6%3@;Q3$AtIt6e5gPoK}3*1C=7xEiCD-)G0lp^mqJJ} z!xR^)?Th>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<ai?K56mz0?>$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<?rmjVg#@u05QK2N9qg>$v%S0r%4m_t<u?uS z=3&Q)s+|?Rg$R-BswKP|?moP$vaDbsa*7D_$5fJIPR0tmO3n)6blAy}GtItX@9Rs7 z!je2kgu#e6UT*gejQXw>DoifPu24!Ofzr9AmYYLE<F7nWUn$&y1S2wjoQMNV2w-N< zUFjHn@_gb(p~2*|kF12Lzu4M8=9_HivW!<@VrdwG{-|rde&73Yx|7RV>kkYe3ji~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<SusN z%W#2@67b>%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 diff --git a/briar-android/res/drawable-hdpi/msg_out.9.png b/briar-android/res/drawable-hdpi/msg_out.9.png index 08fd35b4cbdba08150bb224a4981df94431749e7..f8cfdc72674df433a123725aa7cea9593a5cd172 100644 GIT binary patch literal 28701 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 J-^kfl{tvq1uyOzZ delta 1536 zcmbRHfbl$^S7(5qJ1>_M7Xt$WucwDg5Rf(kVhav7Ai00Z>gzyCvcxr_Bsf2<q&%@G zmBBG3KPgqgGdD3kH7GSPrLyp3stp4JbLK=Ve@2CgU3U7$y2%EHh6-k8dWI&ZW@d&u z3PuKoM*0RoWTtCqVr6P(Wn``Z1xj`ke>v$X*c7FtS-GSZCl_TFlw{`TDS-HiN%^HE zwn|D06}dTi#a0!$1wonV870M&H!_M%?qTHMC<1f!l_pCu=}n%`WIH*BQL`SX8mi99 zH?b%?HN{rREitD!6=Y0-udkI$esXDUYF>$_i>(q+L@y;X#mdFZ!pYgi+{MY!!p+do z)x^ot+{x0_*wVt>#mL#fzyPM#Gq1QLF)uk4rZ*Fz*BPp}9=m2M=c3falKi5O{QMkS zB}f<sWaO9R7iZ)bC^!cjDTHU{rR0|vE7>X7KpmP|lv$RV;#QQOt594Ll$vIhiDZ3g zDbQ|HR|6v_3o{EtLsL^%V?#qn6N`FNSD@34+)RxP%-x)opgL2KJPpz5f}s;tqdw3b z`e?BN6AE&112HQ=QIeZlk_hD3R}>^BXQ!4Z)TibFL%c}I-cDj|y(utZ)Ofl$hE&{o zGt1XU*iqzo`t3za7sX0Vxb|tG$D)nBT{RgdcY4@*WlW`%FHY`~Gm+}@=umOVS6dXI z7r`;9;sEop=1z0|wg5q2=@pl{ls+wViOOZ(^2TEQttDJ0TdYfVpY=0(`Od8J|KG3n z`DM>a>m^;5KirVa#(AM>k;LN}%r=|LKkaH<+;;hoq6C}v1Bciet!E0cZ`~{Ix|rO` z%f7zpzNXS0g+C$c9_AC)EiqwA^V~l9-;6JQvz)U9J*F@Hqwv#W@#PF{vrUmJwU%nR z9y_t3r<$+$hWYEu{%3ur_4@bAD^0iZsCQJ}rt{~?#HBIy=MrNwZ{*m_TYr0%pSN$c zGq;k4Tau$s2d~ru)>&5^#Vp><u?vnrxNKu~c=a?!-V02=uM~Kav`VGsYQ+VsWi+al z3LJT0liC#|s6SzW*u^FMO&jK%Ir*`=gLSLHUzvxW6M8B=9Xx}@_U$>~!64wmuaYU_ zc=8d)<dQxGMj6MT`aYGyJ`W&l**d33CN%qX<LyQ4Hz#I?q^CcbV?O)4d5}!h9068= zloO_#Zc5%1k3RET%JsEJhG@>2+b3U{{Ng^VTP<DDT;L%wLEy|f-QAIE(=IRlt-F+W zQHe^8fBcO7?N>M5TD9!iB({r9EeTy*UY9oCShK2{zw5Q@)HmJ-Me4<;EK6TytbadO zOGkLA@_#XB0b!1UqKi!qitFDyzwe*ex$)ZT@O%42jtZqpcFcUJKmV4`^?P@@{FYs` zR?6u+(6K>?<9K>_bne!-YCBE#U*hdn3Y1~&xV~=R%!Pr=m!30;kmhx9ddlH&BZkjA z_UnV*3`H?(B>|89mtSq$*>>x7eYTA0lM=mYf7d@aX=iZhy=1{H#zP|7E>0@HAFMcg z`?77|adxG|vX1<?>bg(5%T-Rzo4b8ONX>*U{z=M{l$FX@I5)aPs=A9kvfSgqZL+et zKt}5Oxk~XztV~f0JY`iLJl{1}_<ik1CPv*0OZYyO=ImSiKY4!nDPzn1w*(e2MlGoK zlwET7Pwu6+ALHL{w43=(w(jZ7e_!wVOEV-n<y>F@>Ix}z%y7PV@<aBgT(+mb4vW6p zysC6lG8gOSxoRE?4ed2??_PeE`|jLcD;Bm_``pQ=aW>87FQzeZG9G$o$olvDdHwgt zkIi4jVIjL>@8ZL~%cefBQW0=var}Q@ZsWw+jvAd8D)!HrDIl<LVXJ_UIcMTe-2)7} XIxlMO<6(0E7Um3|u6{1-oD!M<?cijw diff --git a/briar-android/res/drawable-hdpi/notice_in.9.png b/briar-android/res/drawable-hdpi/notice_in.9.png new file mode 100644 index 0000000000000000000000000000000000000000..5b8dd92ec4b00adc062222f13b8a6545683ca6da GIT binary patch literal 28610 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 a@X+n+zyDD=hyInln)Aj~KRj&8wf_SX6`}+H literal 0 HcmV?d00001 diff --git a/briar-android/res/drawable-hdpi/notice_out.9.png b/briar-android/res/drawable-hdpi/notice_out.9.png new file mode 100644 index 0000000000000000000000000000000000000000..504fe64d660ae044bd04e325fe8726c139123cc2 GIT binary patch literal 28539 zcmeHQ3v?9ay<Z-JAY!co*2i&(FTiYevq{LqBoGKs3BeExh}g{T%w~to&MY&t*(}y0 zq7*As0VxFpL<Ox6MDcmWM~d2t_(1Hf3Tlz6tqNGF<)%k^xxfGS&Fm{d+0x$Ld(LtW zCOh+e|L_0!{hu={Kb<mp+^K!f?(1^7PMt8mwgEq9;P2Fvd*Q!dFL`h~e)NfqpJBRO zr<_55ySY}cIm_iz&QuzwThr?%RRr{Kfhg&Ixu7i^!D^SQaztB147A9W;Fp^ftt#)! ztuN#Wid2<1t)$Ld7a1*wl<{*7dFtHBje)r>fpRHtM0MZFwh9mk%a$m#g;mY0XsgO& zbSv;XUH0S&Y>CxUl~+Rt3e)SR2%~jF7D@_+y93_gr9x?WL19U0X>n=3;PV!ic)UfP zBCp$5R8j1$DE0~VpS<e6_^r~Af)x$5W9{ScsVXmIS&<5lCl-qp#EJ@ZquEnfUS96; z`aC|L8!OyqT(iVBw`N|zi8yp>WiwzX5lhiEf#`~UJ!)0u<<UWjKek-qNa7&Pv~>q9 zdfLQ@r?9~5>1tCXq+7Zf(vPt<ar>AAq(I`(NYqf7Y*N4@t8!S@EED?*yF3^+sjEwD z?ULVcxXYcUHKr9RuvOaSPO~u{kv$EvsYi`~Jf;<#T+o&Drqv)Pt#cftu)Iq`mJ&P$ z9lCQ&<;iWzF}BeizKvmuo4OK8s~By_qNN*+x~^7pxK43wD2yJ>;3*85rf8BLGly1s zGPfjwlcXlsik4grU=MeDi`<378@=Tf-lB@4;!C}S6<%)&5xz2mMjf0;5-l-}im$k_ z&|6WMMj~xtCJ|jyg7NPrkzAHSAOX{g(YmS|b-E;17gc(?y4>ZiM!C(JB*taKOwl%U z&Rltv*qnaVxuGh|B_pC?$^^KoJO^<JA5OR^?Mbr3&YCQS<!Zky215R*rp14Rh)^iR zL{ktYNtOgl7vg$U2<Qk50n1F4Cb>N+P2!}?V@S3WIEHP{Jf_k^u}D?^b$Xcr(ZxVO zj##9MkSr*gW$02gz#<`ZlcBg1Q_l&X_HWWsV@O7p67e@IYH^_jUT+F|P|!rf5G|!u z2ADKSK)w+*Wv-$%3lT%n0!l=c%>rTSi7D*_4-Y7^7Jyw%K{CLpCivrm+^R_IYO@HN z8!)}1336LRHWZdk@|ieTNQelEs;LB(00c#Hgwz1Ks9AJRHxyfRd{7L*kRz%XU>Qk> zDOO0(<d|%Lni&sAEZqVTRRvWeN>_D_v{O$U2xi>0<gh91n|C{?s7f==%7=dGOi@+L zaJ~Tl7d2f0uM#3NyRRECip4gOar~kQQNSbwF=?MI6NzdHLxLh$%7>_CL?N@$2{utN zUy!Xp!O#Lh7{k<nOr~Ieih%>7#<U{o<Rh|yV8LbN%FJ9&cxY9i_*U>D76@a(D^7;y z0&)esN>$__X?>hd$|sJ%qN#^v!6b`WifNfbETlsl&7vXks~|^lOF%gl!alg?zIkgR zvfLtw7E#(aZ<Q$ou-x1?Z!O~%OPW#01ytRHmhox45-t#GG@WT(ZWF`6Xa%z~$_g{8 zSY%<F1sGkBHE6q4H%$B%BIW^nO=br<)*-M<;0zK2Wnq}P6?sk~peYvMpG2S@v;e?> zZWvJ(a3H^KNSrY<8j0vIrb879!0|*Bs>TP%ASz)1MrZ^mVQSosY6`Rjh5@ToTM-yq zG(E<^&Y>v>gEGQ9p#v8nOsit(8lk;_G)J(&4e)QunknO>DQLQYTp5Ia0PR6T4-2Ta z0tk<qnJ>(Vibe~55`%t#zC{S>%-d_gN)YuBWfT)gr$d1qXdG4tK?5Y<1G*muX_axX zKgxUweg;HA7MtHT$ei$8I40I|Ceq}AI>x~*pzizx031<C3zA|6WJ6Q@stnO_E)x?V z(*uNW;yz-=1K?e6Chru60H^#)1hK)nJQOe#Rnq<_#x1nt2w=-8!YKqvmrV`Wu&^As zF$iq}v_gKphA04*1<Zb-c!VHmDsv$giZEMNh))hdsa^@|nxaQd@Qla=+iMK@aYGT| z<Fwv{RB>Pc@q*zk5|TAIkS3B?`J_if4x+utCl>Jw!V4S#mjxpVri5l4zNt~Prfaky z3PK1A87_dkEYR7|Q}sZUfzENbW5}Wa9RXDq4KPW1mfHeq)Px<?xQ#ZX6DO0ffIy)l zMZ;n<gl0Mg6fLBl7CEU<(k53WRW3j%V~KFbX_D~~D`**u8Co3ZhNv(EIvcJWW{sMF z6{V=m6h_f1PN1=nzL+ZfvK5ozv~q-O6ed7$ad0aC04(^`sDUg31ra=O!BI`pvN)H* zKE)-9@e~bBVZ1ENj>5G?A*eKyFOud-22GYF1?hq3RV6H<4`rqq0rxke$Sl}RRtw9b z8HK3aZv@e=sEP&e;$*@oP*rAiiS>7Iz%-B`a^W1f9Y`T8cIJ8r3=olZ#7GwLm}-X# zW)u~Zj1mBFLOSpR$>{-}GM*X5YJwII%^c*AM^(`<2tW`vJIAxC!WO|Vhs0Ke0xmA_ zvsoU97<!Ntf^9Zf$d_3-Z-gR}n#MNrA%Y*oa$F#aMkVS;oB$fh5CVzD0v-Y14h4u; zqzx7VDHoD8$)_1Xb^@$pnH23awK77O!0d@EsrzRm#sTPvvKFjCXqV&&MFei)80o|o zEiA%X04;tH$O)v#X4HL?Y$Jpkqzq(vRRt9u=fRyt84_xMf{`R4BU2`VqzPakO(PZ? z28($JX=0f1Kxmm7)r6QHRgq3D1#ud9U@FRopS0>~D;W$<gCrQj4+)9R4!J0c1SK2> z{t<rQcfy1d;)U}-R^ogx)k1?^5+(H^a=;(J9GDJ80T&q8wDgD#g#^%;G`0gWKjSCC z&)_AkWD;g_MCT~VQ`@6z9Sdi~2As?464DVrD5YY7##ogGAP04|1qH_{9(mxQm$TH% z;tc=~>txuU=%wM+&LzP75K%?ei8hDWp`&%6CL}f^{;--0{$eE}^c7L$y=YjdlLIJB zlmHB-n31RjxRQ{-?<lIWC~u~)k^)4#5=c!xDPdTc#%l;{23m<_LJwmbK^iv!50>hv z(BO;6peYL+H_Z$I6#ppc$C5NCKiEYABd1u26p>PkF~4*|T?~~I<AVxQgg2!*t%N6! z;FWt^7=qXV)5lP`G!JE>q-p=Vs~VVvXVfTgXS*RZVv-pXO#_Zo;HCU5Ci8I+W{kj8 z&?hUfRTCk#OJV*2x;&Rc&9-VC!qf$kZzq{g)mA5TiY)w5Esmt)#6McqIeTX+iqmpb z#54pArihY+OlD?=Qfeegp(M=H^YO~jHT7@j8wMbh^SDb)BNT{6bCl&|R{C<?A$^Zv z^&2X0s#aKE36o*`i5%I+>Kw_w!yrJ(85su=6%iZwAm7Yzei5+=j!h93g^Y@*LS-*6 zM*wn_cQyQcN(JO9C~GjA%TE^htaC!l2H#LAD{ShyfAdZU5rUV5i2n{r<hoFz#%LAM z%c6216e2AIqtvKkGNMPRxTfk5Ih*1v)f9%7+9E+B-Uy>E2vPo^ToPr~6ERBy`;}(2 zELt<G*eD>f?t-cuLLTI1GZ&dBZWLBrOXx9(3iUiwDPO_&SalWAO{#q<nA^n#=%Ig% zU@f~&++rzk!%IX!0?Wg6EZcItP;vqYOBzf}RwmkqGApp?DhpRSc*uwp+}hva092|_ zil8QjHY801y|T(rH~v}fkjgYW$B8}pC>mnO7C@C9Cp5s{KnIc%Cs_HF)JmdRr%sva zhvp$X_VJ#D$-~aH`wEipTa?vhNL5if5h2`69AZZOG)!P)2fKC7DvX{W>jlCDyEJ62 zi43n{VrOv4x)8rf?m%IH6`tf1sHLKo2uw13!qMOpAcScUHO|ybpuS7Vd<n5>A-Y5A zpcBOC8VW|z5h4*hy%`X)r%x<GsIr7h)J*}cH2z8?E#_a}eQL}u7VY^KBVv!Xhzkr> z5-lQ?%rqk;DXCfuMlI@3x{}4AY7f{*9c&va7+W{2lH%MGJyuYlMg%=oK{Kc;yn~OS z{WWY&I#o$nX)8$Cp6txgkupU&#FBJbrBCLJD>6!CDn!`Xb|DpHv60_H&xzp{3vmcF zXd6&jsBw2tR?)&m6g2J>wMZBCF?I$<kcwgnYV;K9PH>|>%8uwx!R9cRQpB-}frmBf zT%de*B{O|;O~Tn!(V`9li2<i3`eW)tNu_Ki0_zz-BC(5K9W?U61#6%wo)WwZI!$u_ zO#|sVf|%VwQL6&B$$u!u@aUr<jfOB5U<sVc7L+?cl?5@ex04v`8A;~Thc2F_FmX@t zaOjt+ytL{#hS80k++Z%|sOX^~A<c0qZNUN*n+Z8gKwFkZ$c^>`Ej6WPtRwh}2;f0r zkhP$Q6$+*>PyjY!0pccgr!0QqBOgDo${E-+?I0aSPm19o??f!hzje66ah*t_a;A>y zY(_7kY*yyu6i8y|&Flcw;e@+pLzFOf5xA?PZzcZGxih&~>rdmu01d#XM4^r|UkJxd zSq-8$1ra(7*hIlWwx<MP&kqb;L|;HyW_4Q}11K^-c%WuZp<xe(mpC_Hn7};R6ydgU z!9)k%1$IJW1U(pfVnzWiHWD0jd30rrPh!bUUZR-1T4D0Bt2BJ185{OMfGbTlXCi(P zz?fE?@haxp&YTH}gqe;e5;07?*nEx!Q}SdWfMO$tJp3>&H0lvtMTlqoI~-dfByTj5 z5gOIgBpz(@$j_b!@DS4JEZ(ppxU<oz&3#H?EX6ep6wqu!-DxJu$CO54H5v1?6doZe z*$5*cC9FUQ8)R$>f_rR?kvI(*3gw_q4$DSPsuFY>6=ECXbc{GH%p*`UiS&FWv6I)X zyb@>GmY8?bsFMv?*aKZ5iW(6H5_FZuvp58XsZqn2r?PCt)W~E@N4H%Sn<5^+fH@S% zkcLLcR2#EgI|b<G432loC=N_J5D~teHPkKuJb)Bc-Be*oGQ5N1iJAbEu_(pK>KOV1 zvvF=LzKS%TTm%IsX6l`KdlfN*r%2pFa=}hVuQp*S*JEfp=%;fl70jM=4A&rXLGNsB z!l%Kvs3HOK;+0LKDgT9(2q_*Q(P$ioEB5)!iR~Ic(MOT6$*vrThTuT79V)rP*fg0k zJxw++bbx*1f*<Y`g#V&M!6+5awZIN(J~QGl)4KU1GR#u#p=p|#D+IKGc5fV13}Ax2 z0E8hc`cUAOM1+#qu#VqP`V)t^s=5)gTSYdka?DM}gPEL<sP*Y75vcRWK}i~b5*_b^ zT~_FXX`*id1Qep8CYvH6zNJwl&qE+&>SM4X`Ntqw&?7*8tR>VjLUcA20jzi=LqM4} zU_qYRH)o1MU}o`=l?XsQ5CabmDnL8{fOX0EWE(R{w7_Nwr)j#IpTk(j1-~2+qx6VL zWTQ>u)lo1#k)+R#sxXPAhoT_QVm`1)(HQj~G*Ayi*i{uuUnEL&1K<pQk^5M?kODnI zUc~lLB1bBqd>WS!^(n+K2jjD1W@1*G+J^?w-JoiVBj32iz?>+u2%I^UPkN$=xP|fw z5gW#(>ckEu#1Nizv9uASjFkx8U?YWbBA4zu!K4~&juW$cmA8m2iKm4oXH*C9lSjf- zzzo$Bc6v=H7Ix?qEmAm6go_l0S)?TQm!b&;(9<1-CnZXU=&Nav9mb;)N?ou9pFZHD zh3v!vCkcv2t>mCi#2m{q6MGbkERsQE-@KI*gqk{<uTmMBu{8r!%qkYm&`DsLPq9h1 z)AWi^agd&2(j=IksvtE$&BTqP8QZm-b;uT2K|G6g8%G|L<Oxc#^E$Qgh<B7$AZP@> zf^9ql)Ar;RjtmZTyTA+6L!dCtC^2o(37Is~#3KU?T@u)aL?|N~SsR>wl_{MM$q7UR zF^*7#Q75SLlW+?-W?so>y6Ab32GLWo2yF|`fWU~-E*O((UbGXupFLD$I<eX3N7`|h z#bG<e+r_4vKM_HqY6WMymUfJy(US*k#)DzKS#wyI1w2*+d@xv0!UPqkHia@_E?zWH zBInPM`CN<?&F?r*XAAI*jaOR;t@wq)Hw)@4svx|i8Oh;YL|#ee2nrURU5{6fRE8os z@n?4wx>@l<zF?~fV?9JmT<2|-UykblWf%cxG6f*qpy$IpuaGPA2O`86D_@BqrjkGg zhBApaG`px%ZJVO8pd?7mj~nh1qgN+*oMpo>_8JCW_o63^c$L8<K`Fx{Rgef|7!l8( z=!GzHHW-#N*$K6M{2i|Jm)lbNFKVeey%U%6a#<}NHxq9)^zH?Qo>{&+SIytSl~Aln z70EZ_0%c{g6z~_hgI>AVU05iWxW&?--z}F13Vmf>X}CXF-1XaM-zCqt@mnbcDxlY} zXjQZ5<B4d^m7e6qWCuzwP1e;_Ot9aWnNVAe3k3>f@RpVaN&|tQ+gs|Fz<zP5ySy}5 z=$4Ag{AB@ocwt#tfW1kXzP%G^hfk31T19?eallvZEp-PAMK4!TnP2v~{pC_nmi;CE zKq20J<b0+O>vT{(pJA#gYe*IevWS6Txv!|m=PnHt7rTQ+#bxfYlHziRRy4fa8yH?J z`bwQ6x**f(sPTwZx)D!*U68$8IaQvMewCVg{&Hb<FITd+g26ZywAFTAsq~~>O|q4I zS&}cn14Z@%REjx|PX(Q}ANvd{A;0Y%TTY6tIyMm#r72>ET!Uv3*73al%c-Vs%Ou~m zKmAh-VPYg8oroEH!SYi0z348N#1gmH3nYq?x6m#7{3WtnQY69|9Qr9%%oLG?Nl~!# zs<W@CvCxM%oGXgToL8MwRvnv2x;~HNE$rhlLy|{6E0(G~j%3b-Opg99Tdt(k7c4IJ zmbrb!-r?@y_}wiQip6f97!)PHw>VfVi;jH%faNk?FVC6Hj(iw^qk750>F7;UOm0w6 zR<p_mot$dFRO@NgB>Q_Li409ebV`oodQYM8zX(y3^yn9kKfI)HNzVzGns_z$|3~H% z4yeahrf{?7+>&B4`>sQJo#NC!o$DIAKCI=?97`|fQZ)nUeaCl1ke(XkU`2|`ox<{X z18K(gG)J_lOLonE%-T})iY5NyppVLL|1ryN&T0y=uFkR_k^kf6B|oJLGRe~%JEW*P zrJAgy?_O1)KBYk&s|yP&J)N$lP-FL|H{fey{56T{QlA%pJcaaMdu!_L%&jxNeQWCN z%&p0tcnEJ*`|Q&)E~o6mP%+5A?KBl%ij=E|my{HhRC+QmXYQDyw8`r9TKYN#HSX1A z<@TP;8(nUkk+Kmz20M&xOu1oi<Ze@&Y>t^>_*Hy465q@8B)*uLVlz10zv@p?qJPy1 zpqo1+E9K_Yl~Y$%8pvvK4qZ8QWu<|v7U$5FQ&(0R$ZBy8T{(4SrGcy#=g^f?S5_Lx zYH<!-Idx^Ffvgti(3MkHRvO4^aSmNMb!DZ2tQP0cl~Y$%8pvvK4qZ8QWu<|v7U$5F zQ&(0R$ZBy8T{(4SrGcy#=g^f?S5_LxYH<!-Idx^Ffvgti(3MkHRvO4^aSmNMb!DZ2 ztQP0cl~Y$%8pvvK4qZ8QWu<|v7U$5FQ&(0R$ZGMoqN{K6pE|<-L8&S)hJVQD`~mfC z_(zb0!1#tbmuv1tF4w#pU9P_!#m~=NuBg}L`n<{Is#xiA4bqqW=;g64*GV5usI6&i z+x_v{JzF*m?>FWtYvuN^asA4LjT?=%M~`m#@voFiJzw9{F@1&P4ZqzOee3H11NZFN zqV_xe^szH)d%C0#HY`0HesfE|r|aJlwpOiwWA>`^RxZ9<dggmppZ%M^zG>2+?$7rg z7QbQK{`uY4hZ??EGSC0PowLsF_KvXY!kzLTW8>p>cP|<GNL~NE#V3cZxaG3)`jMyZ zKWFEPSxb5>iB+8~)xGuot7pD2^~x>NHtvZYDB004cjTboT-z|^>Cl)L4qbNUUq3#1 z?~(HI_B-!V>tDX`q*uzD8lE3F@ujamz4r9_i!ZtQK-G?kx6V88*M=)bUjAg=ExRs% zbMzcvN&E97I-1@cH*9zJJ4O$@r+CS4hUKlhy8Fv_L{HuF&e&V$yKkL1`P|4!BWM44 zUuk>Q9HY<4mkztt_2pfmQyw{~WZ{lpp$GR};PPMj<8>2nD|+Rjk)JkgY?InPz2T0& zm*fo?xoF#t@Sw&kd_$W?^q4&K?>C;}dF=>(J~8AEk8K`%Xwd4qKfm1V`aXLXt?2pQ z_j^9@E7|24wBT~r^Y6XeYrwXrXa8YAkHKqt{a62vPv+12L3_;g;eq=fsTzE4`KI}v zUL7a3pZ3L^d-p$m!RuQ7Wv(Cn?)FuGtD1M`xsUn|k33vFvE!DB!B024jy$`qZrn{P z7ClyeU{lZL-bch99gkeJYv0?(>3gQfgY6?89yq7vwLcwrprca!;J4Uuo9lUxYv4=9 zt91kJl+UYtY}q?!bqsR-J~*%BlUpvhvG=7llKkQ0wWkHP+>qbW@5njxHg|irm(Mgd z%&NV+-|9YxR^QlhM*BBEoBwjRCs*9m5WcYD!u1>cuStVi`tN&t_o(N}KN|bcwvAH# z)TO?si~H<7?b4=#={K!7JgMfv(Alw?pNy!#>*JEzZyq1@wCsB7iw*6Y?tkXs_Agd8 z^&A%)_|1{A=haWDJ-^$L=eAvU<?_}2#^_JI?yW!A^r+r`*YJD&#qBS2?|5$S3q!9R zFYamB^59!W?dkU|9o(bi@*8IVs_u;;_dMY5`QznhE;{QxZ@>1Ez5ZWbb?&hKHS6LN zYIbg)Vr;tS@Xv0UDZJShpTFNV>x=EJ-Ly>|!A4{D<BO%2wqLxrdCQ`kt1cY(#T%z~ ztXiJ`^YPmbebl&P+VpvMj@e%F^NTnBVC|Nlj4RrEnH2B-$`hf%<yV=z`qIM58(;l! z;^e<bbA7LDtXZ(`%>^HQ_~M73ys}~Po@(pO=VyF2sjO)Bu2*k4r?GJBGWVO|&;4^- z>-%4O@U3n8)}OueFN<S~Z=bbpX8FbO$Cov`4jg*_nkQfBedcp-{eAbIn%$cZeQ^IZ zYaYFQt#Id)Z=O3O_`_Wn)-?@yV(!M7%Ex1G`}wGAntuK3@duv%MBVzxGcS(&p)p@y z|LXVF<=^_!j{H7%Pd#V){+`OLYuEHzxMuO+f3fb8c|A6*+13A(K3^_9u<i4SpWmzX z|8(f=?JJfJzIN+hx4zr^vPCmDwY|RK;}8C@`|zm4SH1L~%isT?V&HwtCfvX2Xz4Yp zRvm4>e%gJ;;rCaMalLod;%C<XHhTTc^Y{F5^Ukdu^*{9u?6JRf*3_@g`)%FOlP-GY zcjun9ZrSoPca}$PTfOz7tpgX%Z(0A;pfi^3`{eAVH}ZGPU;O&fi+ViXt9<RL({If0 z`^fkm5BGehyZZX=?{$Bs*JW!5$kQi|?XiE^?vnElFP<~-f}1AwzjJc8Jxd;|eDC%b zcQ*aP_4{{9@2i`B^o}#HoY~`)^OqgGy8928E*!J?(79DJckWU8wLNxf#~+0)&)odb z(wcQ&X|vofo-->nVDRwoJ@MuDUp2=z^_DJet)KYz?;rTn<l71kjktHx+Gp?IJ7vl* z_pXe8H2W{l#Lt-+FJ3<Eg@r{`Gw%5BfvbFH95GuDt~%|FdqVBc&;M-sYcpF;9(T(Y zb943VhbNbx)q0@su7wLCXJ38bxoaMKWA1$m9#?yItFN~1uWP7!^~m;X#=IlUy?FJ( zUf2G5Rr@`!KDoDbn%Q&96W9H2&EXG~H=Y}I;F_=E`VED<Kls6g9jlAiJoNV9aW!kN z+p(zNzk0`eN~b;a*uj+-^uF%!^7mgpz4YC=UvIj3!`sd0uUN3?U|H2(Vc|JPA6;y< w|E=VbY5(!rM>qeXXmRzKrOzI@%yr5)o150%d(n9M=kX?tnOytusHXY<1IRmd>i_@% literal 0 HcmV?d00001 diff --git a/briar-android/res/drawable-mdpi/msg_in.9.png b/briar-android/res/drawable-mdpi/msg_in.9.png index f9a0267b6e8cc706a1350b1d0fccf6f4a0887b16..cedf69450c3d62696584cb416c5b1c8e98e8afd2 100644 GIT binary patch literal 27532 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 literal 669 zcmV;O0%HA%P)<h;3K|Lk000e1NJLTq001HY001Tk1^@s6q1H*%00004XF*Lt006JZ zHwB960000PbVXQnQ*UN;cVTj606}DLVr3vnZDD6+Qe|Oed2z{QJOBU!FG)l}RCwBA zV4w~755+_SMzF5`{}~1nFfua!XTc`HqvJ!!@gRMyK+FvD3<)9i7l?lY@gL++V<FM; zOiYZ79Ot&oNS78DiREBt(*gR1m1tM||NrCrkDphczI?mL*f(R&zyJTg!yLmziYu6z z7+EiDomH+PFWtw<!EQ*3BcM^h!Ntj8tg0YA@$BXqML_e|;65bHAxvD-5+Z5TNEdQa zV%Z?`$Z`lHBLh1-8><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&<VCe|xE=QRN<xV!<)zAVg4%)fsB<{0pD1n7{zmVsGa7q8!4G@uRvM$K<v zTj7mIY-!7-8~2tDm_y!u`SA~!Sib?=h0on%N*d|m7@XM`-7%MM-dizXbq%s(++s@V zY3Ue(bq(AxjEv7+qKexFw9<n*<}0xF{W##w0FYz;Lpn#J4Wm(q3<-z){r%_fXKGjs zHRmr`4gnTyzaKt*v4a{80ht3bkGxJeBjdN&g4Tv>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<m-e>?A0RjvFHWbr_e!>-000000NkvXXu0mjf D)Q21^ diff --git a/briar-android/res/drawable-mdpi/msg_out.9.png b/briar-android/res/drawable-mdpi/msg_out.9.png index f22c541f7f9087c833dd863c6cf07faab5c1d58e..bfca75665bd844e7c47cf8f275aa6e54e7b50ea2 100644 GIT binary patch literal 27708 zcmeHQ3zQV)m2Mvp7N08w-?1D~Ax=N$J<}Nm2Zon8f-ov1(NJAg-Ca^$)mBwcPXmdl ziSI;3BME{Lgcw+3b|XYx6iv<=H=4w^63v5yCMxKP?|8D3{qFs%x~qEz8-q#Cp3|PA z)KvZd{qOzm`&NxyHT$e-hm1UCWGECmWXANKIrwt|{_Pks9RK~sJ16}WfBZ{!`g|u8 zI%pLAyI*L<%A-P|)I7a!o;$Di%(!A@BC={Fw8%gvi`Ah}=fr`mtSr=ADWRowb3)yl zn;)!`bag`Ac`d!M-t1&8txsQMYjYQ!)u$|4sC1}x6T3!s4#Ytqqq(v)kTFarJ}{w< z>BezQx1)6uFL4)6sOzQ!rFp%xrOB49NiC7quo7!+liE5W4J~bL&29BkW2~Vi8f%I+ z#lnqE@#a{(xl!`|sp}evt4>=@#^>}*^^U_&6YA2gn~g`K`FuW-Z;DuUD%#M|(GiU` zMjIQ$SP^y#rYjGGP3I&*#HZ7vIf|`kUEMMzqAMq?oI9bejt(mR<H?oD77sEV4?Cb3 z9gwrphDa<r)TV6OaxEuq?O|*2@g51NO7YNa&Nf&!Rf%ebmeEYt!M=te4~9;9dy89# z<TsNUa;M`?=?4TJq(km>`U+VsI!AM?oULe6`oYObLrL$rbF`9n_JS0a4@t<?lY5{; zPxc6&HlXie8$A)**rtT4I{{jJvaQLkW%pT@(Iw1vwy#5J@?<toY210bsaknwd}p+B zOUZCb)U+Pi)w*EVt>IWxxS_Q#))9|2#haQ>i#5b!u>cXVvVul0oJf^jxr|C<Q(r?v zyrntb(h;OmwziUvrRvGTUQsEn4A3YVYkab0Saz?aYF$m8(V=b+xvNhbaL<$rn(YKI z2lDLDljKzSUH^fhvtwpu+tJAECe-<MSM=nfqtc!dJABqzaz^V)XtI({<V>^h6~u)G zDK9&ctg4zSxt3J0a*|>pJSeUcl%}-3Bu(+8%40~jeK>}<S02+DrHEwce?MI2Lv&eD zw5&@|q%}!5UE5M~3dciWQvuw*!L!e&{gY7YOKZqgGXBlTW<gpA-*+S{DVefu%dXz9 z!I(@{Le`N@eUWaaq^zx*ik>wzCnC+=H_-O+a7EWl1$uQP)dr`glqg7AzpnD#lnkBQ zP`z$S+CWybb<QdEEDjcuMI>dz(UZCYL6IUMH4I%gU3zBOx+gk*&~3@qvWBd1UXt>< zo0d#1ui2pH6f#-YazVr}K-JFCUCShNW)TOHQ*c}@<4D_=-Uup&p2Au6z?aUH4c*Dq zOYnc$v~=*QB0lqT%Z5^1-bBht$PPpSlMuwAeV$Atsw0g{%3!G;qB>cf)J7+GMCE!( zbCt;Wh$Ky67?96&><=hdkxfQLwa7;_8^J=zD8Q^-PWI5R1NeUMB1fdD;1wqWIYo=Z zs|;OB66(_|0-rbni;k7iB!@KS>W=G3`LqQzQnIazyC6q#OF~hV#y+^`_N6Pcnzm4q zU81yo>31DT!E$H&(pAhYmZVV5DTd_$W&AW<&qSnd(_+-M0XYL3jkBInTsS%1B@KHl zK<ScZ0_}dwc5sy@=3)4z#s~S@A!Ap;86<|4WuWGMWIL4%O?P4bB@48YE(}nyY&*vR z2l89CDj0Ke*{lU+`cwe`jwhmk8b3e=S<k>=q&^rWRE?)OQwK_57-kjJ6&b@q)5^24 z3)9q+Ne$thtOGY7OuuehCRuxgkR!9e1Mu%?rla9UM=~u5=`sobfVC%WD<h%iQV<?Z zr(U`!C)*40Co!0S(Jz$J7JGX)SV^KPqKx9e(&<px4iJadLC^*X_<)swLi#lvoXD{+ z!Ovh(kj3M705TUn7mkUwf{8MD0LL`A1>mkP8h|e<p`hxHqS>aNFf@pcb6HFnnWd0@ z6ZcuCpn!KPMcyfmgPn>yS;Pka_IQ|~Y!LdBm|LLZ3*gBq!zm=y(i{`E;bJ-L#wKf% zfC~BbN}>R>jIjRFg)Et%qc4J3D8)QkAwD?-rFuPMnYxv8z%wEfbZ@fd7i?XIkJEYw zQWanWh!<>c*|cWDflQgiswW(6Er}+ho>;^M!V4S#w<S9Vrlgbw-!v&&(>+>{10jTk z3Kzgr4s@RB8J3b`qw^hZ53=a64#m)98%z?;+JIu@9O%&~c-Dq=;%5>L2ox#;2+Ju5 z&6vUzU8J6cS_x1>Q$R_T3oMjbBD)hbN%@Esw2WhhS%7szR44-djR1$W(XF^SipmTa zMXLfCjf?cfP$V=rufb`xEa@mi1|h`3sp1FNLc++|$RYrU%mX)kXiA#JxfJ#(E>Vo9 zXy{1OHR-|}Tw9isdWw9JkS7^TO;dHG2a#9xjEruSRWlLpZ|9I%u$#1&(PSqFQH9?~ zazZzB7v3evWKf_QtaX*UJUC#Pksxy69Jn1wAuJB&dK?sx)hxtFj(801c*)73V$x6o zz?_f{60qd*08bgu$ze5_mI%$l$RUqmply&~LD=jc&sBvdLPAT+{W=9)+z@AT9?05O zk^sRr&sfNpIh^+ah!WD+Mm|L52eEt?$e~@yB@icIjid;PMB{)*hVO*}#4AFBLm=fs z(kA&d6XX-19oL~~Ux~^@X$I>PS<*^eh!_V$N0fD;4YGDs%Th!T8qO0Yo@f~v+Je#I z4>EExQe-pg!AZ7>Qa4ftvb<q{iiq>z&ZP_q7yvMmBxGbT5hNWL2GTTQv2AnALr9Y| z%mZ1=+?*-pt(<{$>gtHoum^^y9)8kq8U3U%I1Q3u8h@xrbY93sStRM14D27_2Yx5b z*e6~D52Pi*2SW=4ha^hyA#%VUz#N!P=U^^SuH#x+&lHM=#?p8W$bKeHf}g=l`bj0M zazy7G%2UsydVCF6#0H$pbqQf44hmE(K#Z$27;@4w7NX$zu82JF(3zZiIo`nFp`8l- z6TLEf^>PVpew=I|>*P{tK6J7Lt4Yf##2>D?;4f}5LZ6*O-pggAUQIz^qAO6C?qqW= z%$0<M{Z67Pi}GfGm4G37l|V501j4X%o~R+P8P-ZHll3s$2-0{6^WaoRg@#x}3Jomq z-Lx_UQ2e8$pD)p%{NNP{Oip);DI!pdv0wV3E|1EI`JloS;Z0AKmGI;dqH-@t;}AQb z`aCL^)OZ%94E^d=4b&nsY7Tbixgij7NR7p&0mtd^QgIf`ycdL-5vU4ya)E6)2&qE~ z^Ec2HxfC#a(E5a_3nJexF&{*0kafx&{-_p5((&UTts0!YD}fTUe25q!AQ%v(WHObR z8K88ls!mB*r02brV`%Ch&o>l6RxaW$F^y0l+o>GqWG;OLc1Yh7xqd_CP1Oqbl~5Um zpvaK}T<56X6E*=#&d4~3sEF9G5Aw|l=a&(i;Mf#lQOFpGDpdB0as)<hh^|JQPpN=h z1!WB;boHeopF1bSZ14?8xv-ff{9AN7h!CPAMEv(jBG;vhHAcUTUKW)DSs~IwGDnRn zCL>mkifgJ4k+UhzQcYo-!4?S;iAET8L7MUh<&qp%PsA(<oX}HfS<DnyY!nc=yPztE zEDv(?%taH48-<lX2|Wf;p`K?h<tz9eS65lfq1u;%xmR3(9{R^D*7AMg7E56_qC|vA zV0ng)<t=+_N`3(0q`_ixndlwLTHxraN$2?XP!TDFwyQV*l`51XsEMHsB^3czuKX<f z({hI((|nE}d+Jd%<dH34RbHGhVg5EckU*T^@~ebOv00~1nem}{h=_fnXJL8xOs}sX z`921$Aw#Nx(uoM+Vet?rm!M$+j~%?$`4ffFePlf%&G1S?ZcQ|J4U1jDC3hhShund} z02iL*6R4$ft_+)G`-G#xCqM|(AZnbcnLvFP$b3byX(75p>Y$6n=pG72!U&NFo}PjU zdDAD35Qe7W7IjmwRvLd5lNS3|^;7d+vFOdWn20ypA}%mkDYl4IGSiHZq@-#snRBT> z8A=wPsyARGICvW>7!Mn+qy+awj|&Rah@fZaXa+4^bntn!zqW^@UzKF^fk<F`sWV4M z%0T(VN_4r>Cv_Hd4J9%aB7C-2NF_Noif8CKG2G%1hfssI0hNVO2q!fIEnHSd<4#eF zu<(xYGBAQv4ogs@2dMkOjru4rqWcA#&s?C0<BCCqHR@adKHsTKp8`oZn<2Z@K_D^U z)M9^3eJDZ7GZARdh9wfaxb&@23@*5Vrg%!`9T_yq{U;5id&$JS4vJb8uuc9$F-Alm z6KOP!u>dD<DqB$Qz^Yt`iM@lw;CCdIZy$zum%`%i<Ke)Us=Tu5IFHedm)xK(c2xAx zkdWrMl(wJ&ip^v>ETAV#ALK^+ftH$5GuDy$$_U^|*dVu{h!r}fFaQ7>u>f(Cx>Jr{ z_)&}>xN?SVI$n^@peM!fP;??L<=<Z15q4cnqFN=!bT-o~g3V<<PJtx0mEr?Xhm+l< zY+1$FMG~%#zLoe#=gx9*>rdlDg$7_$qEN?KFJ%gjW+c&@f(RW3+eE=Zx~Bx;%@1r# zMqfa-%ynA<11M5Ic%WuZr(q9<mpHdxn!z6J$Z*?&<e&o|!gkVf7CjhxVy1u=8wrkG z9$gvpNi2oQOLRw6D=Z)1rQsvZ*suozoa6AEiTFhTV^sX{D(2e$oC%49RYwzvJSJW| zpW|Rko(v11*oYyII7|qQdIWb7;+cP+V>gZDjYcv{qk5XegKZJ{`F(&0A%o5m4J(2> zk4`=A1BJ0#FfmX-vkAD%R8)^Cjm|Y0ds=`;h)O!bNJ!7<5W+Juo`T>Rk1>j;Aw!`Y zw8&w3<YeeczfmE!F;2&b)5SajHIq#5SBg7D?J6p9&bGvSm`0sEVBr_KQVumD6eL*& zjc0KP6w_^FFi+)d#W1pL<<{+0#g2^EFJKM@GNhpqGS$YMYiGl{1%uQ5GD;Yx7l_Ed z{Wa7sz<6L%RCQB@rE2gFVNcWqpo~Q+PFly%A2wSM$`Y#x`O+c)Se&U3>g^5043Q%7 z2+0LIeOx`lRIcaIbkLvvqo6TI%Wb$Dkqfx<+M-W`Z`nWs6vZn~qbdKT^(+AoBQa?l zhCAN*?8IJ;U+kku*iu&xi-zE^XfIR>z<8QWnVu#a7&<_|1t|gdO2U6pqF|JY_gY|w zkgtq5tlF@6MTS|bH#99%b6i3j==H`)-G)u@XFwRTq7Q}Ll869_hjrq4$)ALY8%7v0 zyI<yEm9K769@OOjh+3cC5`nsS9aN$LQ=;Sju*-!`h9>$hjDSK^&fzH{;#(O-@;n4W zhL6pP<e!3IL9YPCv98q1gy?K40=Rf2MF33CU_qYRH-Cyk#?0}NO9WUvECwE&)M4>3 z0IVy;Cr_Crq7jcJoMu{KaSpSL8wpL3bM%Ty=Fukc>H|z~B<W`#DokSOr6|aA%!e&f zG)Dag1ZF`IUR8zC7l{(x064?H$bH-{1Wb=CFY9?Iks}BwpB7X^eF`z`U}9FxD(2eM zJ2Z*z231=D`6etY7v+#e;LJfj>5U@d7Ro0?Y$%ti6EBnyLwM80X(LG)s~Eb$Mu2f5 zSMEB=5)2;4#o4_fT0~CbWueI*)xr45BcUqT4Am1}dMyGAJq(H#0gj8|BET?5N^*ZS zR|J6G?&u;ZQ949lO@r(VUX@Vlf;PnT0YAFPP8>K%P`qj-2lXT7RL)HNDi&F!g2wix z-<ctG_tJco%Fv3f6-LEcacPE50@HkoC)s|}D+A&ry~CtQFuhelY5>f{jgO4yTK+m@ z3#=fXWv`7R4=V8lP`tcOEj;2Kr4<O8g|A?n$iTF{v_)8kFm$iL%g{@p49zGpZL!EQ zX{3o)1{k^&Z5tAyjOgPwxcn}IE{5b}L}X&ZLJ>y&pe|0rBiJ!}rI_iW=Rq1oPsI`1 z6P^u$iPA18laZIb1fSrSij0ZJzBtm0yBvqT6z>(AVev);iK-u*S!UTWx=C*yuo*9g zt(57ru1R>U2=l>ULC=t>__Zm(gt|o0K#5$uM;3E20$M!r-_Azxj!jfs2(7rF@XbM; zqYA=HnUZ|oW#pAoj-X&M*!4v9NM$IJlX!PWp__{z@&ykjjP(#LabL7m39VqkC^HB+ zXHfvc1A0F!@(Q`Kcp*ZJarsIFF_na6U?@}kPIHJl)zc{&3rd32{Dk2ydHQrh#91DO z@n;zL+>72Y;!_5P1f>j*R6!z;Vr0C3q7TBz*`Qd;Wc$?iiEp^dKW+>5U(`|!`X(;$ zaaj*uHxqB&^z8+Po}cj3xi0Y~u8Lw!jhDWRQ`*}#RY^33lQFG1+|Z!4gyptmBCK^N z4UO$FwKb7!9{TIEYVv#>zn!WQ2d){}?c(SY&6=ssXz6CD1Eo(Vdwb(Eyf0>E^mO4y zM28G*jfvLQ7P&2~#@Z8MwWV1B=dtFn+#G9fZ<E#L_U3l}p0a%VAksdcAU!lhvfSJj zOEk9;L@j%SNbngTHt3*PVuoo1){rbJWRaC*M`Ke{W4KLeZVo4#n%l$eEzKR_SX)zT zM@(sLmK)oAS%x4p=&0$4RhC^S|6GtiuAHk~RDPG5d+~AMC;PaPzYPZCRM2*Ld8IR2 zcDKY<>0?Q;0525z1E_#H_YQ(V+xL71m5?9zrL7>vtM*L9L1~KEp>^Y3gu6E%0Sl_- z+bYQq?N6VIA{>ka)O}GyLTQdA8<XwfWU{3t+}6?D5>9le?cvr&4G!1Q5o=NKq3_?S zh9N#x{^zNI02il=S+Uv`^(FIf`~x*dlT@U^PoO>eWDz3(R3=@VBGD2U-q)GYepB^+ zEuk3dsTvCeTOoOX#y?P2)P^WL_ufteToz#xWx@X+nfKW<_b%VnJhPZ<$iMl!`SP6S z=h4AA(yKLkgmq4(4?QU}!uqQGz5&9>94#3iBCG9fIIY-T=8GP6)vN!!oVoX9gJ3SO zeJJYQ3)a8AI1#4|L8f$?k9+{&KrPZqzrPblbwgtwt|}Tjql4}RsPVITbMUK2;w5`m zTVo9WL>uV8-qzsb%B}N1erxb?<<`<pyux+68okphZU=T@B$X7uD>E0rSf_QhwzM?0 zbVe(0SMHdt4`{}`9{L!c+P<z<K*D<}9}Ky1eraP1%E!{izyoiiaFm`>YsHEYckv5$ z_}#u}@t6AoIt%*Rr+i(K=u;*fBv(5mh(^`x8eCN&3NEO@6-1-zbq%hn5Cs?1;0mHq z^|}UERfvKMYH$V7sCr$4t13jn1vR*WXjHwf!BrKa;DQ=lK{Tpf*WjuOQE)*Gt{@s! zuWN8sg($e723HV`s@FBRszMZ8P=hOoM%C*YTvZ_oE~vp3M5F3;4X&yX1sBxd3ZhZ< zx&~KOh=L1ha0St*dR>F7Dn!8rHMoLkRK2djRTZM(f*M>wG^$?L;HnBya6t{OAR1M# zYj9PCD7c^oR}hV=*EP7RLKIw3gDZ$e)$1BuRUry4sKFIPqv~}HuBs3P7u4ViqEYp_ z23J*xf(vSJ1<|N_{jqS3Ed6yk`2X)rsLSIo!#Pp@`mOkjbR=c^oZe7q(aE9E(#t}j z5Am1rEPX8$%EdyV9ScIC_;*5~Bduj$d3b6lbl?Rudb;}tUijrL|6z`9IQ;Ypi~nT( zdDxcy*4=j7>f2YZTeo)Ix@`x&`h!>NMyw4@`TE!qho5-lw$Z~Tt$FoI`(-=7xvBY{ z|9<6{TQB%g-U`oO{ECs7`1n9)Q-3Jb_w+Ze9MO6Fzur(+H!QT_wTA9vpEzTEeAVn7 zKYg|5vMWyRJ?h~zZ@O#i_yZ5!aMg_4M!tE;&JVu4<B(e)pDia=gkI^I`_SgPjRy|@ zS?bU+$6TJ9uxiwr1D0lH?>h7Jk-1Z+-EzpZbB`Ty@d1yvzHxSDR9(}p+kUYAne&&O zJAKphZTB5~^c}zM|JA{}>O;p}7;-*;%^2yJStn0FZql<aUfw1z-fz_PlOFxaj_voK zaO^WH4}W;Z^G1Gs+q~10Z!}~g>z^Msb>@$?@Lyu<u08X?HH$W1`}F>=zjtigtaCni zG#lT&`R(_9x8w53Pjx@{1!e6IH$O7-)R&(8&7-@Y`?up~KK6qR@3o$Df7_21?SB2x z$df;Ma@T;i>$Nu`cdvcuj^D37_e=TD9QB!tzjnfJ<G+1zccgyS)o(p;NyCB%z7_gl z)}im4CmgorxO0Eku<?=c`~7rL^vI*$dgt+v4$EIY?Xs7?^H9&?-_AO8$@*nKulqyS z*5BQ~_-l)r-yO)Vyk^6OdsnZz-o4@R)~_vD;#f<%IuCOvpZ3Vp5#_nAUB-Xz&ZIut zt#%&MbXWT1KR+?<vEkOHm!E#@*^l0M{;=eYZ>{^|r7J$SV(nAs?SJI)+wzWy|CL+o zeFIzW`S9%%$9(vV-TmbLKYwEErB<)A%<6sW#%rFud-q?Cyza_z=biD{;p&N@+lS4% z`J}ny8|Iz5^vcgKzy0nzKKkLNM-IO8pbM`4^_W}dOLxAlPF=Qq_j50dI%s2d$t!Ck z$Nc!tKVF+W`LbU<vr?aY#TTQUk1g5u)B~q2KVkdQZ(n=#@_Dyy*pfeQ>^Hyl_{#TA zSw3^cx5xbO_GRxM9d+-$<<~8}$6xUi`Kq&DS+HQ!!Kst>U-9+V@35{pBER;|b#ouv zdhNK5gKxg+mHtr&{O>)#A3bXMPYyhP-SBVM|GV<q;-{ZD`|=Hu=C+-gyIy<wp-B4q z^(XY7{=hkBq>tEg<KbI2ZPGsc)>qcwwf3vi*4#Vxz3*TBrMb_nIAy=1zI3zu(vCOg zEd25j8%IY^z2wldcRqEzaoV<Be|&JwDbhRB@4aT(UEzz~S@X@CUTQt;&5d(*ym0@8 zx8MBcO>e$<#k*&09X9e5GqTgTz&Y*Ksn=;Aj5%Mvxc&>jcy_xkeesE-4><U9U-+pu z-M+5jnhTzfKV;wjNN@dt3nHJ@{!qVd(zK?ziJ9$J4O>3;kTKc9!~6Z|fQHp~e|X#2 z1&1%mkA8iMoF2X5p?A&t=7tR;u72>oxyN+(J^SX$*-KaV%zEm&9S5HN!rilOxu>x9 zd*?iGe$UU2`0={=vCP(ui)QYODI2ACKlk0okKDED?31thVABCx`*$_v-ixm}Y~H2s zU-IJA(Z|2_)j2yefB4Pm!~53n+PwPZ8FQ{r)h&DY>8_oJT>8al9~gG#B{!@ZIpVa1 z1@+N}SHJ&1i%-4p!Bt1ZM~{2|xNGZPST;81zP#<r&vo@@NB`#Hlb#qqeE639qZiNm w{P%iqKKHEfRpZ7TH^n&h!jIZQi~p<r?O*(L9{vijP-w=KvwH5DwBXYJ158yhWB>pF delta 1356 zcmdmUgK;jeS7(5qJ1>_M7Xt$WucwDg5Rg^^Vl@snAi40G=M^9&S>hT|5}cn_Ql40p z%HWuipOmWLnVXoN8kCxtQdxL1)rNtAIdh_wKcm9LE<1f=-DCqpLj^N4Jwp>yGc!XS z1tSAPBYguPGSf9Qu`)HYGBQ_y0wueNznt_GY>HCStXxuylZ!G7N;32F6hQpMr2Ntn zTO}ohirk#MVylYWf}qUwjFRHX8yUqW_b_sB6oI+=N|U9S^d`?|vYnj6s96tG4OM65 zn^=^cnqsTumY7qV3Nog^*VoD=Ke;qFHLt|e#a0O@qL-4HVrAxJVrlH`XyN2&33R%v ziKVHbfu)PHv7xDvnX#dT8%(cfUU5lcUUDi-Zze*oIaF^wcFk7KMX8A;`9&f5`8l>q zkT49$$S=t+&d4uNa1J(72+zz*$uBQfvQw~uIyAK?vn(~mttdZNp|~U{HO(p$$@<b# zpxs7}25ydSrY43)rlzjOhK7zN7WJmCPL{4lZl=Zt=5EePP@O4Ao`&eO#L$VVQ6K0I zeY9AC2?e>hftVGbD9KGNNd$82D+&^mvr|hH>QnQ8Azq|pZ+G+pha>|7(<x6E$B>F! zNr?))f7&ng7&PjJix~$n)s!S1G~w=eVBDt?Ca=sq_2B>i|0N|PCI4?um>je1f;NlC zQHG6j0>u*&-sLOoV>#m8P@$^Hcc|dRCDwUwlbDhug`9+9?#SF(<J05Qqw?e3|LgMc zs&RYj>k~gey35VHAVBs?;S$S~lQrLCG!s|)sCuf_6*Wmp9O<!{W0RvbM=M9i=S*aO zynP*;$Sj|pIJFRY!y~6VJU#~~ziX6x#5R-Ni}{Daw-t$h^p74pb<T&kz2Pk5tnc&Z zm^8g{%6iHXB=ovIV%s10)b>Bh7Zp90UbTPK#=-e)qe8uS5VNeQhtx_LC6yV+UGnA# zO)ZYNF|#pkTl1NttsAE+hxjR%?fRDVW=)Q#L-B3LwB*AUPA$9m7#XW$-3`qaBsZjO zZ$9IG+`{YHf1WK2eY?&bn2_ktH0yrf>XfCG9S0gF&*L^oxnbzU=H7APoT9>mMen(I zB@<>b-un9gzx}WFdJdi)QaidC-*&q53yM`O5lrH;602%I@ojT-+}~e+%Qd;VmFIoq zV9u4@^!ClO@b~uhaZynf8-@1DER62RvE2OeYWw;4X<^gjv|rC$@|pdvo>-LFM}rMN zzpy2E)I>%_m+f7Xz3AKg`j$%^x|`lFyZkzC@Bc5UnXy05ZaT*~tG=NArekn>j?GrK zHyyvaZl}ureO3QqrvK#?KR-Qw9X~<&)~_r71dL`sdpq%3+*JD`GrFaectY|v8}S?z zyS3nzA5T}9O_t#Q_y3Q_*VhFdHB~5fcqVxJsY~IB_xJys-Ki~nZfz>VWW=5#7s>bY z$H()FgtzzC?ECcMk$90a+miRE9($L>J3ebT!yMHvp5&_>ygUA0kFW5yzh7PkJlZ(h zy-8A1@`s220-pK%>VI$l_x1FBZt?R~)vK2|cdcohRqt^2dqat`!1jgh5*LrMrxZN% sFKvIa|G&#L)t-#z5@uEjMkXExDGiAP)`Id!z=Dy%)78&qol`;+0A9fr=>Px# diff --git a/briar-android/res/drawable-mdpi/notice_in.9.png b/briar-android/res/drawable-mdpi/notice_in.9.png new file mode 100644 index 0000000000000000000000000000000000000000..afad3fe8655de3f8e46d8fe0ac32afbb07f111dc GIT binary patch literal 27363 zcmeHQ3zQsXm2Nh`S;9jea(EntVxp3m>FJ(#rkPBb%;Yi1Bw;d0V0omvs=B+F>Z+!y zdU`srF@Qi=6*O>SA_N427(`f+@CFHrx+oijEUO}rjVoY~MIIr*Mt8q^|ElWho(U8N z*R$ue=Y-T${r~;%{qFl#jk$c$f_Vo{K6-L27CUfYe*X~uo{2wQf4?vOd&!$q{s({U zSD1gg6N~MC82#BR_Kj<gjKwk+>cdOiC4(oY6f55(t5#ZT8p{{3Iu`4mHCB+75zUp- zT2?n_HoW%04;mz0o!M|&`(Sdg(5L0}`O9o=@v;TO%CZrqOKq6dGr4;#1p;}^m8G$~ zVLGX?nGH-gg=@N<Xpne`J2JDOmkyMc3@(!TEL)S>n>yl3vZGV#>}qOm@9b>rY?NA( z&FzU~Yoaw7Z)r`nB~xuJlJ~!cp2@iCw$)5(sDG|^9DbVFkaOKaDv>CaN=>EKCd<wy zn!CEX63LcCOG_Lp;!fFg<*~TwOc6wUI{liX*m}X$EmI=8a@s1oGaDM{px}R=T=_z9 zkm-2X0ma0aTu3xGB@+{ED&#EJa&p#gwg!)POF&hELkmUQVA)h9p&43UGhGM!nkPIM zIvE@cwob@zK0o13$DK0@2s}t9-02LL3tD1GbF8ARXmduv$&`ttcibVZqMZn&uzW&7 zuAbQq9eT1`@U$^~H{0lm*v2*`RNW2GQhl~2yOup{Sw@dA*G0Y#rM^BkPig9Dx~W<v zXIginc1y)@D%7-o+0}Yr*d6g?YrMH*IN6m-wx(L!rYD<I$z+I#SXo135Kg4Zu3SZ> zrFFQuIn~ycYHtlwsaji0$5Qo7ITDr1$`FmfSW|tLVcCP0s`a#XCnmZ*;jUqA%sp8y zYqk@@9LTdn&z7^*cl`&3&W>4-ZAT-so7v#oUEs-qqtc!VJABpxIj{AkHCf4}i>6sV z2XUcUD#?x{tE#3-t|gVNqNG>|4~pxArKxPMNE4h?dko382gmUC+GDyC6p;-5uZPR& z5M5Rjt>6+AIZe_{*S6H6!toH;)Bv|<@a*wve<PHJa~g7$j6ZqVEK4KseMhn~k}2D^ z?CPT$jLB3bWF6Vmm+59!D%iTI=mkS_nxw^h2HGATuIQSnK(CIZ+Thfb(q%~-)m6Tm zm7#MRs@F|P8!KqG&N-!##lb?dh>UDFdPY|uC{iS(hM~)*OV2D@_e94Jx-HpS!H^Zs zOHxU9bCRi*G#k{Ma=zeNE{GTgsM<xkYng=3LgGMj%8sk$9ckN&t3bujvpA~}_|loO zp*#6T3H~pemJVK3#AkkP*-(nhn@Bln*?}lv5`s9i&y$Hnb)=~o87wtIRHvYm+UNw2 zsN5)NuF^EENs{I;49I6X_J<U#$R?wrTI3^|jbI^U6kygaCwmyx0sJU<k(;Es;1wqW zIYmpss|;Ps5bE<R0-rbni;k7oB!@KS>W=G3rJMycva+p;yC6q#OF~hV!#=p@wiVYF zG;KtZU81yY#ac&Fu-w_UVjXjfC0UenieWiG89&X}^G#B(X))^Bn4E`=rdZD?E}Ww7 zl7>ANpma$yf%d3nJGjab^Dul<<AZ$dkg==a3=+f2@=)_AvYkqXrn@lziUnF37Y3+U zwq4|a1Nkjm6^uE>LcxMEeX0Ne#}iRNjUOO`tmk1c(lCq?s>aizsRJc246_RBii}~z zv`TF3!Zfu^MniZf>%a{NGpgH`N!H#($dOs#0r+<`)6wvwBbk<jbeVyFz}hpmm6uR+ zDF~0I(<q%+l<g7xO$?@C^dnNvVsGySD;ZQplu;a5Ivonz0pid)2-+Y4AF$F;$f$;c z(?#|r_!%q;vUvQCLFT}7;h0z}n5dEmaLj{S0Pe=X0DMsi1yy$x%{KM4p+R(<%VNUF zEQRcwxGy+m1-x5X@=j?g>{Q$-AU627r@;(mgV3MN+yWh608dUCP9dq5=9sVz7t3Kc zHd&hlRLHNdB?>UhCe~lBTp$y4^konWrI;rx#3zTKRIlePQ@4r^ct&J`?oGD*vaQST zaa!*{sxoW<@q+EGkkd>!kSUW`jfA7EWzb|a5{tM%c!2}pwqzH<l$5pLn<hnTx<?C& zAcU|`;{tfffzC5M!%~WDbiTvwMiw2`p%|KMgGs_!8&iy;13emL&)Seq{7k|DfkH(H zVL1z-8B>^|i_|lsRRAS41(Z~|z(ScNvO7VOl#f_J%Q$A3Wmq>vg(A@32yj>%y^33; zsLX&-v?`O)xJX|NMOt%98k|-ukdE?X5JDWBDt>@1q>ZADECPVYJaEH@rlMJ#OJSel z62*9mhK@8}lg=%|wPh)zXUP`{d6L1@G*w4>5P4P4%jiZ~HM8LUb`hBcyGd(#O?HY9 zRrrl0r*%Vj;a!4E9tEnwT35Ntg9BC>2_hHHf!l!;!s2+Yr$PY*%|eXih{w=Qlbj+d zCJiM3%n9ir4NI;L@RaeKB36@WiO?*J9P$_j+6D<0gw6i(Tvd1?q_vzps#Czl4RJQ- zfr4#i2oP-ZjD>ue!}&0Ps347P<U?eB5X*OgBHEQ=8gT;FNQ#h1G!A%V_+BVLydpF> z1X3;}ZIVwjK|TT6aUF{GwW!RJ23ViSl2-a$#5fo_qO1#TkhQB?fg*y?aEUPSM9a(2 z7K|2uk&%;;BAZbUPO{CCdXX}a<qZQ=M4ShAE@eo-0DzGsAtQr{AnCv`kfsrfZJT2r zLYkas9>`i27fq>T6%C|QS4W(NJupO#@RL!?7$t?lX^;eS_)A5i^Fl7lB1zBZVgCp} z@H=T>k9ZM0kd_1=3@s3xkSM{2$N_%<b6`4Ggt<Vuj%yV>QwR)=rSTk){Y;z$KZBQy zl1f<Rh|Wcnr=Cak`x>r^4LFzU62eFv6slN&7*}a9<cwvEpx{_5A`d+DbDVlP-oW6Y zof`cUy()Y4atUmHs%#+Z6tg)#w9kUo<m4>k57%7q7dME|rxcO*ig{^JQ&5=b3KXV0 zg`x{{B_UzIv#H9WycuF8WQblR5Kca!Ff5%WY6xtGwGzu@J<K+OG#<h{IMq?1Ar_HB zLkoO2tqlPb|0wB~Dl{lRctrw})7>CNglaMNOFz_=P&qLlRG1>X>Dj6ho;*TS?qz8z zVh2=TLgkX3#-dcA|G`xa)FLu!5q9UfArNs$jX~3Z<8*kbIE!VDK$sbUs(>dK*oK3U zI-xLs0bP+x0ka3KPnfzO^6d)qVYJ3sr_AAxYH=hTKmO6G@!7i;C_&4Ih!FyUAyFzO zQ=6FqO0TNwl!Qfkjw;8*)Zd?PD1fY7#9d+<p+L5?Mb61w`U>ojzGrd$hRU0&749pc zG7LeHBgeSTQN1T@0+gJQaS%}vv0)$Nn>EfaBR0XYDZ-+VF%VU#>=oq*jNA}ijX0lD z0l5mw8cgUKD@8tcPKepy8<28gvrzcA=yVVvL`jJF?~_EX%LO&YsEl3~l>=EJ(n6+4 zjVdN1R*{Npst%E}Db7+&VVmI=2@;7$7<EC8@(1OTB3DnuED4;}vuIh&ELUt45V^ac zDu*l&a`VhZ6Nwvzl|TtS22r7&XEEg~_#RhR1<Rq@mx8%hT!0?>#{$;!ec~2NVK<^g zgh^m|o{r@$QBBDYAe=N<OfD0>Ls<(PT{Y=c-yUirh0yi~H~^I@lp?5!p$!!k0avd4 zEc>H!hcMH8jvsp(Q8bj0Enrn%oG@YjHad_{oZ#}Sf=bY=Q>V=M&^$!MKGCzVJbb3t zSCD+~1J;Bg)j;V)gzzvp#3`m}n80HPuXX-VVRR2!Z;}SQ(vVvd4PL`y*Ko;QNZKKH zpfJFNC;0?wsiG^xCfPpWXz&RT!Ze5)XKE%;--R+?AT}*TcSs#{K#cC8U?hwXiQws3 zn2<Mp;s{}ADsE9X1#6}8SCF*WzdrcXl2<Hx^DQRgjkbsj3|4{`kxFKo5t5Wtt!0WX z^(Pa_;#2hoYy<~yLj~hu!<Cfap6GEwff^C?3?0p&rHc-}g!b3=ko2pPygt?x+Ft3* z(UCGxKCud2uJlQrWnDvwOoa%a?G;iPj*a3OdQJ?tIK&~;plv{9VU*(;%|HuR(9yV4 z)FLdrW4sKEAXUT?)aW7VesH5c%8TfJ!R9j;D&n|e5Mhlv7l6-qYSX7c63%AGE_Dz{ z3^+CDkEstONO>j#?b)zIVi%XbHHyInH_#MM$-JA!O>+N61L;9BF|UK7Rt0R6|4@t( z(Z@s@&0#FS37pCnlsm907h+=XI5GGgN$uN*3Eri!xO;dw@TDrRsyZ%VbmJvAsEZvH zJv1bwIWDCwXn<lfSq=;6$ubPN(SD$%rqqmeWWF*2cm_7eEhu7zjwuWPz(y=U+@$W5 z;}?Du;|H#sVVjN@r1R)WF+3EVh)el*5O;)K2T4?`#hA`!dI8v6=HnDdVp~~00ChOo zUDlRWj9nz*>gZdEe{}9F7q|X2K2&G`MkNY$oQ+bx>}W;?y(x&$VX#dU9He_n5Z?U2 zwq*1LWXoK)l`()K^@9g$=5!kNV0ejh8>IpEXh(+ImL&%r_yo3-lMCp<&=WHSwAe^+ z?DFW!m``FUPF|urqFQ13_%00}X~u><5a3jY=S;*e0vMy>k5@6*_UBAUB&<4`NR%+~ z;`tm0Q}Se30L4ZOdBkBtXw)OPixAKJ`y9JDByTj51sc`UBpz&w$j|QsL<kvomS|WJ z+<A2BaUUv-)v}3!0-8<0U8SN%Olfqk$=K6EJVI2`5k^9KUWX8#k?|A+&v=XxoQ4dA za?m1&<&l%2XZ%Km*v2>=BTg6d2-Hk6y<Z7-irQ6F;+$=X`8bU_dBDOibfqF{L?}qI z3>wek5GbbC$YY+$*@|Ig*{ZGEtBM^NuV26%3S>w_BV?+LIoB?NbqfaP`(>0cOfL|T zefw*uU4Zexq^Rnq3QN`C9m1Zd2|yW(Qk=Aop+9W4ER-cy5%QHq05F)TkL&FX#0-%l z@d(KUJAGU|!c?x8&~(t>{-dxlC#r3@7m*9N^V-0t!MAK60gB?4r_q%Ea(aP)hmn{x z4#OSqe0E~5#t-@^61LKn!=fQLEZPf|0x+H?Q>LfM28IsMZ&^yiy)y7$lqeXb;=LBw zA>?Z#4y!gUUXfvz>J3e+)SQyg270}5Mz>)T{2362tms2ww<ID!;$fY5UhyYk;)W4N z%pR3_Smmpmlm|8WKcd#Bw?v>WUI$fZz?A5CKkRa$lc$Nk3nQQqRdjfYi1=1TkvtE9 zkl|yqBKhYaSkNm#ajYv1G9fyfiU2MiNf7|kGgy$P_RXK7kTG+7<PrfE4~u~ZXLMLR z3;^pY@ySzWg=mw<5>7L%xHyMd#*MV5$VGa^B=cyKc=Z9MH<I+T4;3b{^imY$Ip)I_ zDH@~x0|E=72(PL_>5D{(ZUCI&4{{&33n9}Z%PV*uO5_Lv%BN)&QJ+E#JD8Xivx>Pk z^$yLTyFt}fM!t#5%6Ua(5jb<0PkN(>xP|fw5gW>->ck5r#1P(eaoWgG#tK3=*a$IB z<f>gKQ-Q(bIGEiVqDAB+UKN`BQ5}q*JQAvc%}_nzrPlyh=wV#62yq;Qix9&cDarlS zVgLZW-O)u-qI8J9ng-c<yegs81#O7w1AcUooj7okpm^0v4(dnDxty8!RV=bd4UKIp z)(l9!gEU{IGPGuEjZv{yT$-Viz%-xYNw(kg%78dS?=Wc+Om9_?8UQnK<0Ip_mcI_! z0xO7T*=ys-gDN}$6fdt+3y*k5X$687;49cBGB9ngY!Q|r4Bad6^7IlYPcuqPTP(6n z8foH{0fsJtZ9^iI5yRXDSKnpO#gLqgh)hgaD8i^8)Wu171UqK06f<4)JV=A+sW?J= z!m}YTQQ8G%GV-#Q;M4q4kumYu7e{(=m*cRP;=N)sF5ZYBQH_E#%d9#^H|fm-Hsi&x zl{J0VH3_d3VLliv=y@^~zcvM!P?sngD3Ocz$YL%=K#M2-+u0_(V-wXDLMtvPd~;Ce zsDkiPr6iws8F{6WBPdvmcRf)(QW=WmB;MUo=;q>we8GbWV?9Jm+!t+CS}R*H$~*$j z0t!HQK<|e|ULjW&FGPqjE?<ctrjoD>3}u4vG$*K2J)NSlpd?7mPaN)2qE9D8oaJE{ ze};k2z32@iK4ox7P|EN~6(j;FM#lRm`XG#)4T_~qwnuHB_=c<c<F;`BMJ?61Z{oUD zB?SiZvfIOMnkbmr?nLEgrB$PE3<n2O1Ky`41N}X?(WL8YszcFQTf35-@s5_}=D3n> z>xy@2N?RPaI$K*?+gsGmcK-0Ndiyxi{dnI^;DEIFs#itfr=}`j*=3T+WM^iE8qXxP zws>>1)*hETGwHb2r8Kw9NU9y_Oq+jDh}gJ;7K&k?5n4mCs5nekGF>gLtu66RrL8TV zX>FSkpV1D1lAWy`T}h>*O>XJ*kC=eWxTEI7sV%!){aqb@g}7Kdulg=^!Qv~t5BC)! ze?$w$sq*Xb0&sVt>TZRt%2$PA0p7gvmqH<RMuTA7_T8UBwbuK6k}62?s@)TDP{YB= zv|bGD-6&tn3aZuHYRP}JpFN5bJw-U^oz*>216-%MIXOd#cQmK9c)Gn!j>|LTHkhN@ zrOIi!C7D!w`XMdWibz%!0@(jDc!F<wL#uXAq#Dl%A1y~wLxo2%R8@NtzGVK5T8{pT znxl~;^2LYH9(~(~UKuI8hjR&PXT$r9F)?bY-uL@K9HX)&6l?`TAsYXOvZ9DWg%;gT zLtF+hiTwHhN9H~D%xL*esI~5yBI5{ut<HIV9vz<}y;`GRSm#{&B9byAtnULp%txpj z(lV(K>VA<DHJsLLukuBYI?58iPWf<UgJ3SSeIn}Ko5;VsI1#5zK&En<k9-K=P%Y9; zzvz-ebwl$It}2?l6XWiMsPVHUL--vX@iw}r6Uix=Of=Jfy{+NLwOdbr|E=N2wOcDY z@vhVDY4J|0xgFYt*-b|LQpsZc2AbB>(ca#Q>a_ND?T$tIm}V^Lr?1wjKkDfKB)q5g z!Gs%6uWW2b`B>Q)df;soj?!Q0L0B>3E`AdYzXX>EehV(7v!Jf~=r1Y~ee|>giuFSR zD56}{;fjJ%u%-@I07aCGI$Tju3f9!&3ZRH`QHLuEO2L{sTmckOF6wYaK`B^Mhbw?0 z%0(TnC@2MM>Tm^6M7gNL6$PbWO&zWPiYOO#xT2sGtf|8lKoRAl4p$VEf;Dxx0w|(f z)ZvPPQn02DR{%wni#l9UPzu)6;R>LLa#4pX3QED6I$Qx1Q7-CmML{W8Q->>nBFaS_ zt|%x4YwB<XP(-<?!xaUkU`-va0E#FVb-1FS6s)Pk6+jW?q7GLSl!7&NxB@7mT-4!; zf>N-i4p#t0l#4oCQBVrj)Zq%Ch;mVfD+)@%nmSwo6j3hT7p}>be^&<oM>R7WO88e} zt{PhY1pdVtNtr)17>h0YbS$>w;#llm{Hrx9ejke!ld;(LrLkCQO)PeVwd$P5=Eh=^ zelyVDJ3RL5pI@`-iY>_lE`9X}bLOu&_>A>4SDg5Vl{>$1!h(~PrdK~Z_Uey*zdrxj zIfK~;o?iaF-~RH7%hs-)JEQ-LE9b9VdFAq3-u>ol`Q@)1{_*L%ZkVSI-*?24#Lc-~ z-HrM|u{Q=L9rxo_^`%GdUG?Hg*H7Ac%zoyMPZ#dk|J4h>_hzZ*$g{6~WtXwzp}opC zJ%8Q(cW!^>#Z9k$a_{qcreAo*#XsDB=Cx0^&p+s(N2Uzz{M3sZ@9LS}wRKM4j}PCk zZ{3@lH}t-D%FBlq9{<;8XBPJT!>o6@{<-mYOAGJ4yLR%b7xp(Vyz`=y&W)WpGV8Px z+Y1}!tbcxTe&Dpup>x+gQ<{HB-{)7|b?`5)zxt`y|7+;Cdu<&!@K*KBwO{`8cZRz! zQ%4Rv<RABr9sSyx{TFZE(lWey!>(nYxp8ysTbsUl%Z}&1wQ<vuQ*M3o=62jWKKAA# ztKMGy)WLV%^W`V{-#TFHb0@C4?tq)NKYQW2W1i~oe<AkZv71(ReP`tZ%cQOEj{Whl zL;e)|qZ}KUx8lB2pE`TeA%EKYkNSxNPao6wnG5gk`nyEz;WH07t9|LwXMFaMue`mo z@r9lHJo4{f`sOtav)cB4Wy99V=GM;G=HvUE6TjPa<MTHzy=v0K-+uVuUs$mh7Or-u z-f&#Qry6eG@%EPATzuBmTddgfb&dIh_U$;dS-s9ZVxQaYIA_7WZ{Pl%UoD#c#G{Wd zeSPxk%U12&@!+>df4AxLvlsRM{K=t7w;0c_KcM65yY{`{oOPGXdF)>0lAAWUgZ7pS zroHub`G(FfJ+tPPlX`FJxNZH-&Ang$#FTqxjO_gClkKhN{H*hqi(cy3w#g~{!|+RM z&)x5Y8!kO?<KoNLUUT=kH#Z-7-_gH*cG_|7J5Q~8{Q7;4zvPv()?PL5k>9I@%a6YE zx{p0L`=P6*#1=kw%?&rd5xZ~cza09*v6J-WJHPStb#rEY?y1$6-uK^6&)ZN+9hKU6 z@*US*dUDenKRv1EqPH%({nbytwEUf;elqmcyEnY}a`*M~R^2uI^|Q|(x_|HVaSgG1 zzq|RDXFR-5YuCWc=_5D&@R{?U`Sa16uDDBGu<W+Y&tCl6<L4~=&(}`)-M~Yu);+m) z?ST)fKVN^myJgbP`WEhg<lJTRw%Au+`-$hyT6e^xhaXt~-Ce)>){CWmzS6i+-Rt|m zopt`ZZ-4sfsnfrI*sW7W+SA5cSDklk%gd|dYjRIq-g*6VkKTXG_QALAzW1^Bt~u?B zIs4=i%Rcw`Ps`UFdfA41IzJ}odfm+%HePXC+m#O-b!X?{C!BulcC9P+hu(P??7HBL zn`eLdxqn;s%C@`I6+<^HoP2?m&rSX1%lboWcip(<*UwDrTz|p+!+Y&~=b;}Rwc|f7 zd*=LO_j=*I(`Rft;uC9b-~P$+*H&%3a@WG2Imi6@z@MBlY3svlRvHidll|7ht1rEE k$H%|6_|ac{VNxtB-+AiG!#g+9KSMPzXF>n%vzK1<zrjSw)Bpeg literal 0 HcmV?d00001 diff --git a/briar-android/res/drawable-mdpi/notice_out.9.png b/briar-android/res/drawable-mdpi/notice_out.9.png new file mode 100644 index 0000000000000000000000000000000000000000..c84866764c4ef993f6179685adcb6a58dd7d84d8 GIT binary patch literal 27737 zcmeHQ3zQV)m2SZJ0KtIKs1Z{cH8Nqkr{~R#GlK)eV}t=@hL;+lx~h7*nChyws(N~w zWfe`-uu)g>t%xQuqQ)2#M51Puyv&~U5jD{yN*2T=BxuA<bbaf7_x@Gg)jfla!A;Jd z)1IT$RQ><`@BQxkR*kG(FmKk_(Z`Jrg+gPyW_K>cpKbWJ`Ot&$-;4fw;)nR-u+;2j zPAD|yNcwj~=*IQOghG8w_1>lK((bt}ij|DWsuj~BgUJ+DheEAW2UD`ruenl8>(kA) zioFj#QX%PTTg8%w?r3*vx|Yyqud=nCRr7k4RsBk{S~0bKbn9RX2qZOEmIjlC>9h>C zRWRKaT+{993W=Av{cRN;bfC1fdx13FvNfq8(im2vjZIQhbEKxBsj0rHN~(?4G*n0H zs_UZR+PaqdXiI&q<o#38J{ni8wi<6)*g4ZX4nMV3BwRPuQeB<NWFncmh-LRx*EBab zS4V5BYiq+;5q7esD-VWE=R`ror_-r9imj(y-7+PjE61#~+g4FQ2j%|p<VvP;2bqqC z9Z;+ulvC9;k!baBn^FnOwVZ^tkFB}K`y`+$xkFQF+hEyLrCKwzq-MGf_SFn~Fm%%0 zo!dGrzscmVI~{k%03h%n9d@VFn@wre3pK||+ln@00GymSob-;nP|Is)KS*Kuu!LMa zz7IO|WS`(^gZe(U(G#(aZAz%R6`-|Dw>8<d>|V<<+J(6;@O3CnpU&nfO<JOxs+Dmn zTdRw=<P9fJP3x3htsREl7>?G3YZ`l_%`MTomb&`M(VCWMG(beGETYj3CsJisE}&9d z*IQH5($Lsa(-5Rmu(p_vrRwqQeo@J<4A96KYs+-Yu<UM2)!OS?tB1Qi?5<vI(48x1 zHQNbb4&>RPr^$VVcl`&3&W@RqZAT-sYpd|>F6YTPN2NV^cKED$a#CxLX|j@trA;%t z9C4vW%E*o+tE#3-t|euyw4_)F4~pvqrO9v4OOrdP_!yGy0FL49#mBT(Q$#ZK|2tfk zL3CMBw3JIwBs57kUE5OA3dciWQv}?B!E?Z;{ew{IO=!qfGX71<W>)Hl?>mwemrU8V zWmg~2U`(beA?wJdzDhUyq?E0jik>nwCnEJ67-$E0xT0&O0=+ttYJ*c#ie)8jKv(&0 zpA4PbP`z$S+F(kvb<QbOEDjcuMZ{&p(c`)TL6IUMH4I%gU3zBOx+gk*&~3@qQiiN> zUXn7pn~+Q`quHS5WRoe^azVr}K-EsuUCShN<`V~!lXYAz=}0@*Tm>qI-iNcQfG?dX z8@iLMlHmWcY3blqMSSMxmJOx2yor<(lO2cxCLxGJ`#hOQR7aW=m%&mMM0HX+sf|wX zh{{!x<|>iOh$PKm7?96&><=hdkxfQLwa7;_8^J=zD8MXUPWCXM1NZ^(B1fc|;1wqW zIYn!MR~fn%C)8(I1U_*D79A_8Ne*eu)g9N7G6@T4^vSj=?t&b}EeS<c0{h^eJJ+mF zX<EM|yF_W{nj0KR!E$HknwyzhEa^izrx=z4l=0JSJsFWYOp8(12IVAdw1xGI;=)Pm zE@{|f0ZNxN6KD@uwu7q#F%QExH9pAK4jH=&&LA<YED1FaAls>AXu1pY&s(4scVU2v zW!q^EIFR46Rl%5(PNgg;)29jma6AzO)c651$a)e6BlW^4p=vx$n>tVe!!WC$uE-er zO)JC3E=*I4$2Ej^vJTvUFax@6nPlw|LXOM=55T{pnU01Z9m%vLq{}$`1J)k5t)zsS zOF?)vohs?vv~2g|Phv0zqwkjz7JGXKSc#)5qKx9e(&<px4iJadLC^*X_<$9ILIyM( z980q=!Ovh(kj3M75HjaH7mkUwf{6lo0LLu21>mmA8GtV;p`hxHqS>Y%Gc<^fb6HFn znWd0@6Za`6tAKZ_kGxZw1UnUXQiu)y?Mj%TY!Ld>m|LLZ3*gBq!zm=y(i{`E;bJ-L z#wKf%fC~BbdZGZcjIjO^*%X<eqpyNkD8)QkAwD?-rFuPSnYxvBz%wEfbZ@fdXKh`E zkJEYwQe|NSh!<>csf1?2flQgisv;b1EsiFmide)2!V4S#w<S9brldX#zG+glrhBv? z4MGSDMJ|A+9OyjLGb|;|M&~=+K4j5h9g3mJHkc%wwL!&5JJ6$%^{fr)#Lpxg5GYgx z5SIHOG-C==bdh@cwLGANrht+v7g#8>M0O`=lJXHNXc@;0GYjj6s89s@8vzb$qeF4i z6qOk;idI=N8W-t{p@?a2MuXF8Dbi7r3_^&5Q^gOkg_x1HkwpLynFnt8(Bw6Xb1Cdo zT%s6H(a@1*YtqUzTw9jndLQ{BAx|=xnx^VV4<fJXNg3TJt7a<P-%ca5U^i(ksmV?n zq6)u}<d|;gF1$;SNuoeCSnDcxd2ql2BSGZCIdD6WLRcKi^&}`DrCErP9Pt?1O36v1 zV$x6oz?_f{VzA`G08bguNn<scmI%$l$RUqmply&~LD=jc&sBvdLQG4@13Cp<+z@AT z9!S|%oB+W#&sfNpIh^+bh&<BRMm|L52eEt?NTXdz#}FrAjid;PMB{)*hVO*}#4AFB zLm=fs(kA&d6XX-19oL~~UyRCBsf+cAENR77BF4ec5oKLygREWEQWOz{hBJhTCt6a5 zwqUgQgN&Sv6xob=aFT7R)Pa<NEN>W~BH}!_b16dt1^|pC2^kqo1W5;mfi#U+Y}*|3 z5Ypr%^FY?plQyM{l{S!0T^(^6_P`KT!A}M(V}KL}r$G`-;13mv&I`FHizGdng#9D@ z!0)841L8&SKw1)fFtk8$SfT_UA_x2d%z^1d8s-A!I<A%SOd)4zERE-Y>}TR6_!+!p zfK<XNM|4i3JoP-P)7NlOY{0o(mk>tcpg_d}#JEa>A;&GF9|gw^BJ#jP=Wy!fcmson zc8c^*^a||N%O$Y+NwR^glkQ9Kq0=o`O+xNN{Nb7l{^I5$^ciX7y>wFQ))W*bx&npi zPAcufTuDgS?=-5iC~pQ>2^gYR2?Uc*APh@OL=Az>uvTK3tcTe~kj6up2d6qJG{hoO zXkdZwro|zE;vXgbOr8ei2d_wAa=M#K5rJBa{n8J08B|Wp2Nk9WZ+c%r2~Qp&D)+23 z39$pJ&!BSYt7K6M&@WxpKrJGpreSxU8v+rB)R=1;aGVY=6=$)``$3o)fvSKf7ube_ zkUFd|e*;~SO98V7txuS`AoA@z^Fg$RSf|Y4k7{uw9Y6ljs-fAt7$`x@hlmjZf&o$T zCR3c50ZNCe>Xd{<dfs0-hNu3~d_w_b<s$A9(+CB!-IwN^%%!iu4(WR;*Ker2saoN_ z5-P(G6ghH`>m1d4!X`k;85su=6%iZuLB3h!{4!z_9GfC63K;`Yh00!0j=;zb(bb6a zDHV{bpsc}!t}0*TbLWJZ4ZZ;>7dG>Se~V5B5ki!Ni2puG<hn$z#u$*%%c621D@0m| zr>RlJWW-8SaZS}BayG?Tswr$U*djq9(Fmh1NKpQuT$1MMiI^pUV|pK27PF5lHVTN` zT~L)nmIt|c=AwzjjlxQxgdT&aP|wpt`3k<r)m6%JsP?5`?iClHhyF2zwS1qr#ZuUf zC=p>2Se~R~dCUHqk{>`gX|R}FCVGdm7C5?U(jwm;iXw&3b_oZdQiW0kH8HdyuOi^e zm7isQQtl9Bn$PiLPZf%W46+5R%8L^w%-==_5{MIAe&tcgHS5$VGd?sA5wTD7EG!S7 z>Gc&P-$#HoY)CawIuRi}%pKySV>C?Qv4ht-f2=TifUHNPF0VA?)<lEXu-HXhau*VF z$Q>vQaN$Wlfm$l<%CJecPdFNU0)#LPqQ;q;3DkFi%$F0J7NR?(4mwAS?xA2Lj1Y<7 z>3uLEZ~DX$!q8OQqHYS-O5?9w(qjKAeQL%l7QOiv6Y)k{#03T`xfYR1W||R_lvJ(7 z(=PQV!^z@P^#*JN2X8|K<6*;<l;ED|aY2C^5%dfl&7h@=4nBkS*Y=R~tCFNX7zu38 zcjo9w87QAvo-SAVq|U6ap+u%agwOU0sW`_*@eDmDhFcus5Ngmipt3Ns;kag?g-hvZ z+$m}i7Tz&l21bxdV+m^X0ChjOQ6J?+biZKpnF|zgTrr5SMx6`5=R3veQy>XvGh~-K z2qXran(L3L4<$%>CIao*utZ`Pm%cTM!38(a6i>;#BSR*+|Db_%H<_5%K~bv$w#k1e z#)#-+B8?_67T^R<Wedt3Sd|Mgv3H0V{Enpf?ZYtdQdryrJRJB^l~+(5XE3_)k{i^; zj*1={64D%((iSv8v6(D~1@vU;h1_UA&{9)s#yT=z838;F8{`%gu|mfb1^{3q79eg? zcgpb#KZ@}KSI)3a#|zR)^rRRbicZ9({M(H?!me{kR4c}q&SrW!u(`~~DUigr`uG6U z;beDxwya|8A_-SV-%9+Wb7#4@^{4TnLIW@=QK;jrl9E|RGveq?L4*#2ZKB{H-BW__ z<_ESVqc0#^=DID50TihpJWw;I)367_OPpIJb+Jb~GTb&RIq1NLv7LmRLJx+Xm?@ye zMuKCPM_0yt5=&w765SEi3d_fLY4}JpHtc}_iyWRa5x)pvjEX;A#a!E;Ga-?%>S!X7 z!NiN_a~w>`lVJfA8!_Y&hY6ukkKissJoE2!>?V-B(MYCfR8Nz5uq`4#zYh>0WXM^f zVMTD~(W%FMpfFamCI$*<HUW2mimEWB(YYpLPYdt}QAtM_3F%24LU=~TQxH7kF-Gn* zWGIw_7C9`BoD4ngH!8$7#_1Swx|m0xW|HasN^Ym9T}36%*_N0O)2NdNEc`-ON~1=E zf+WkJ@hlF3Vmgc@=Bb>m7)F+@(7L^<*pc!21<av9hBP!nrrMZu?E+Z0U~slyMhV08 z0ukA_zlPcc7!OQ}s&1;VR1MxC?1`EHl(8tqN$VK;!)CKWSz;9-pI-z3b2IfJy}f~$ zAyOnBA-Q0ukE=(R%JmGI4*Ju76g1}QLL2Tt<O1%zHs{meTQ-mYMe)khXv%*HJw?F7 zNK6`s;f{AcJF!>e=lUoTHs6)Qq9Hge+6$EeFrFq;rl-jUh7QngR*J#B;_zRTC>W*U zy%yLZ<clK?t2QiNkztnV4NVKw+#;b3^m^mCZo?+{Gaw9E(TBorNko9e!#eRi?@z+S z4I_-0Js|V2%2zij4{Gv%M6FM6i9lVv4$9MjDbewM*yTbeNfUh+MnEAd?eG*4@vVR& zc^(2G!^dVt^3Oo9pjUw6SXb(1LUcA20bD$iA^@gmupm$En?FS%W9InCB?2rS76T8C z>#%qj0M_N>lc&r)(TK+qPBX2rIEPurjhLp$X?n#Z^JtTJ^#P_glJv6=6(+ItQWWGl z=ED{#8l(OL0`s8=uc|`ni$sZT0G#1p<UVc}0;Wfnm-0N6$PomTPqQkbK7|-|Ffl7; z6?1Ls9U4b>gQ_iyd=r+HbJNHoaONPN^hObJ3*{3cHk3=%i5E(UA-w70v=OI_l?&Zq zBfvP3D|DTB9tMx&-0a>EEg~oJg3#oT>R|ljkx&(EhUy6~z2<<09)?7V0LQs-5nz}j zCAq(v&H+GgcXW}IC>^4&ra^WRuSzI&K^tQFfFE6CCk~t>C|<RagZdG3CTAvo6^krV zL}TZg>${|mZkn%B8CtZp$f#H=F3r$MV46?yB-?L#Wk4LKcbGH@rnf3c4S<=r@saUd z%U_3VffdBF?6q;^L3y44ikH`^g-5)jv;sj>@D*$m8JM=`w+PD+hVB)3NqPyCq!}fq zEf!fOjWqGf07I9YZ9^iI5xv|77v5#i#gLqgh)hgaD8i^8)Wu171UqK06f<4)JV=A+ zsW?J=!m}YTQQ8G%GV-#Q;A8w!kumYu7e{(=m*cRP;=N)sEZ&G9Q4N4I%PcrXH|fm- zHsi&x)o1#wYZ6{7!hA4T(34~;er*acp)OH0P$C!ak;Pn$fEG{ux3dwvV-wXDLMtvP zd~;CesDkiPpd_Dn8F?k2BPdu5bv;o%QW=WmB;MUo=;q>we8GbWV?9Jm+!t+COv_p@ z$|M5LJPJT~K<|e|ULjW&FGPqjE?<ctrjoD>3}tfPX%17TdOAg8K}nFBpD^4dL!VBF zILpH@{tN@3d(j(4e9GXEpp@Z}Do6xUjEwhB^g$Ro8x%{K?10)n@eNnu$8Ev>i(0B7 z-^2wzF6+eWX5y`bzP-TE^J9KG*Dk)qRZ*;|E%`6wlqpj*Rf*Mw<58_XTvMYpgyp7q zEUYyvHMLWsYGW*3Km6BcrR4c2ep^+g1-K?<x1FO;b;|5(t<K-fccAp?WOsK<m-od? zS7$qJM0Chd+t8rJ8>gt@re?K1T&vV;;aE(;f0|;N)-a_p-Vkr*?<otn4<YUI3DWz3 zD5llLYU&xHhJ8XL_zVyma?pG+!!!bGNEQ{c$V$Aqwyv%=+@#dkhvRkiQ^Hdk>YKyS zrn<)FsM1(3*EadG3`1tfQL_=NEIV8HxgdXB*`u9Xc$b=c@p0kD`?!+74F=;>(6)Pd zrM0@?Zl10D$C6?JUMTVhPyu!B9|S|T@B0iYAwTL%TS1Cf?VE^$(iE{n>%hARcYi(t z7E}wj6_X#{pFR;qI2Z}22cm{}ZF7Colvq97s9{Q2tE-QN<wiLQvya7Uo1?1Ipdudp zt!fzNQ{{i08VGQ4x|kKK?bW_y{*Aw*=4g_NH25*JN1rTW1c1t<ol_)Q0>k?{vwFZ( zy<bbng?g&S0>M^D9-#4elohoh3eWww(*Tz_m_%9d|3~Hn_RRgucV*Aa<r?yD{%*c7 z=lOYbXpZ!1jZR^mGwDN5%8anS62EVNFtSjKw+xfj_BWgsZ7=XekGksBe_qbq|FS_a z7uY@=b?*i1-(H-EQ-&dvKg~xz0C1odX{F!aX+d>EV;-(5YFev@+zU|SXG<62SC7O? z_V%XQDE_Igq5pbYgO7{1F8k=M!N<j0^E>eh*KM!$PAj?{*oBc)T>P#~4}P&uYj135 zsB37gF1}s7V}U-X8B06qV|;4++8Y50?<syT?8asJjSVOt^BV&Xyp6(9I`gd+D@NSK zFWBLC`>J!l+!xSU(APfU>%2stFySD%@*zPqN?w=YDhW|=K^d+f8YQpGaFv88xS$MI z5RH=8Ww=U06kJe-D~LwP>oQy=Aqp-i!xcoM<aHUYk`M(Kl;H}ZQS!PBS4oJ13(9Z> z(I|OchN~n*!3AZwf@qYyF2hw4qTqruTtPHSUYFr22~luC8Ll82C9lhHm4qm`pbS?K zjgr@8xJp74Tu_E9h(^ilGF&Ag3N9$a6-1-tbs4Ub5Cs>M;R>Qr^12LHNr-|A%5VkI zD0y9mt0Y9h1!cH`Xq3Dz!&MTZ;DRz-K{QHUm*FZ2QE)*St{@sEugh?igebV63|A11 zlGkOpN<tJ|P=+grM#<}sgllyEugk&zf2XY?gTD+XvqicKf02%)%wE_X3avUh6k79@ zQ0Q&^Wjt&C6bhxIq0pWcp-{{9q0ncob<2M~GZZ@LpSn6bdIz6>{H7nTJgMo^7k{|0 z|K@v7I%vYur4yz#{_MI3p8WBScelNF-+7}x|Ign);^AYqAO7euhu`$uCBMAG{_U$X zdKO>v>)-F$aP-$+z48~=wlBJ~chS1FUyG*Y`0aCNJ$`un;PLXFnx~I{D)gxPlg)>` zG<ocXarJVm`pwn9oOfqxLC@TgZ@zWHvPb&vY|{So&R_g&?uZSmc3-&nuBVPWrgCrP z(i@L?Zq<!P?i{n`<Vo5WZ@u`zO;3OE#ijRM`In|U`u}?DvzLG2?AK5F)^iIp-DjS> z=pO6-!<U_Yvz8wJ!^xqI<F{5`Gj?RObN-|W8yCKD?Q1ngPjp1XZB>h!?t6dsQ-jm4 zSZ8iC?`%5k)*m*mZJe`5x!@~T7)u^%k5yjM`N&<X&U#coqVcP*9W|!%$p;4Cn>th3 z-Tq|P=*IKjTzbyAq4v>Tb6%@>dE$2lf3<jf`*pp?g{E%Vd#bj3Mf3EdQ~$B@-7Q<T zeEW|34|%PB@}(2bfANK?87JIu@biauy?eX<!KrO+Gk#Tn$w424cJ!P&bKX*C@wQ)O zo~rDBf80AeckbN2apNgQ<L3tV9x>v*QEPsA<*so*`N3zWpZclQM;x>DkkIn)-E&XM zalW!?Q{C|sCq8l5d*io$e&m#s?r%71+ffgG!=8F@X#Fj>D4Tw_W7jS%vg4M}dzHP< z+tU~I{OiaukryAi?y<+_tY5!=$J=jbSMFFIT0Q=RV~@BXbI}>s9<+Tj{=TB6-}}wr z>ecH<ztt2vf6U&;&-_LF`ag|+@71f%dgq?j*47o9&wTNN4<2rO?UWJ6U%mPG)2}-8 zfrgvc{pi7y&RM?v+|{cuec^={&fNOQsJAvwd_8jEw#uy?Tb(bxv}e^xyZ>e6*Zw^4 z^=DUJ^zzFue}C)wn<tDL`P_xS`R1m7+c^2FGuCcA^13%xwJm;X`9Xht@~!pjRy}vc z6W2WbO3%RB2fOe4)b#JZx#8ydJMY~#;qc#Haqisv4zIlTsc6l~e_HXQjdwSF?y#9t z;^+L}Hs{gD?4~Cgo)~k<wfElr*6(I)y?6a(pX%7O?)}G;XY9HBzv3;MkH2xe_R|%5 z*1YNZKR)!v{qsIEZtU+j9(~HMPj7jyeg4?Ce_wFfMHjC-?}q;FC5PO9>vww|xi|F2 z%<jbE_DvHWeqyt>>+<E<yKi%5ee=cB_B_$H<@S#L8;{x%-E`Y2ORPEH{pkg_ZXSGK zw7d4q%&R-j9x*HOVMAi%*)xAK=jzuJYj;n3Y~1w~l@B#u_R_bWpLnQy$*9-EFTJGR zKI7Gq4|Q(a_H5IMUD3PVI^kXAH~)R~yBja)IPI}f??lEZzgydTv3gTY{Olu-yXdUX z%o;Us#KwhZ{3YJ;CHK<0lg}DIf64cE+<048sOPpnoHgRl6`SXexN7G^hy47US1K-h zX58)tbDmkhV8*m}{xGlapi%E^Z+>y)^kZwgrk-$Q=<UbbCvN}4)8{?+=D_&Lb7r6J zT$dQr^PMgCkNfhpF{kgna@Xn$wjI0Zn!)X#+xpCpGlS<(tU2WFj@?_oJ$~%W)ytn< z_1Fu|Ul=j^>g{89&0Tk4-H~U6H$1t_TKMaguY^}bE`4Rerx*WE<dTQ?etFji1KodI zc<VQIuV}qBS=)4<wfO2QANYFnX?w1UYwyn;^{s802hX3sXG71m%jSh|cwo};W91EZ fyz$|P&@<6Pe^9sns<-Jc|LU4Cuk)U1D=z$BAX+{c literal 0 HcmV?d00001 diff --git a/briar-android/res/drawable-v21/round_button.xml b/briar-android/res/drawable-v21/round_button.xml new file mode 100644 index 0000000000..788768ef6e --- /dev/null +++ b/briar-android/res/drawable-v21/round_button.xml @@ -0,0 +1,16 @@ +<?xml version="1.0" encoding="utf-8"?> +<!-- + A FAB does not work, because even with fabSize="mini" it will be too big due to shadow drawing + on lower API levels +--> +<ripple + xmlns:android="http://schemas.android.com/apk/res/android" + android:color="@color/briar_primary_dark"> + + <item> + <shape android:shape="oval"> + <solid android:color="@color/briar_primary"/> + </shape> + </item> + +</ripple> \ No newline at end of file diff --git a/briar-android/res/drawable-xhdpi/msg_in.9.png b/briar-android/res/drawable-xhdpi/msg_in.9.png index f5db8372dda83faf1082e8700e0c2996c6801fa6..8bf845198fc2c05e65ecd032eedcbae5d706568c 100644 GIT binary patch literal 20316 zcmeI4c~n!^*1&Hf3PnJvh>8O=hy##$ju4SaW*G%klngfz2nmoNh((cBWe~843OIl$ z76E5O6lG|OS`Y<PoDeNl0dWKs2ZZm2F<ddvzIJ`@y|t3HGVHVO-sha(-glpK?jMPB zc3P~is-p@3fV!=Xr7QFu0lkA&#zCJqsD)+F*Ehj7-eLe4KS}yV02#Zd0)XWhzPp#i z%h7?s5d~pbToD_@L<9vxR|9~_!iZoNClHkAu|Yq+&=mEeqzt9U=bEBC$&NV3U<=Tn zZxa~`x<xv<b0PydbS`QkQ`IDb0XYZ)B`m#&Ac0WKh%iO<`DH-ArOjBBUf(5>KvUEr zX@`1Vj?Q`(qEJwejG>@8I0{vdO2^>IR4R#TtVh7%$ygi_OT?iGL<R}RAQAKiUMQw2 z^vfia%VW4&S`TywNv0@&i6oeT#fFE6W5S6TQK%mlPp8wdI0BYHKtorc#cPBTRs>oo z*6(*R=*JQib3*yS623^NC-uu>i^3$PD3r9Lq1V8?f`W%S5{d`dK@_nOtY9o2gTszy z6zngOh{XP)FPILgzvzI=8R|4REL6}pH!cSY3cw&xC=o+;_)$BCV&dpHWIF12gMvo2 z6icjDLkI?tj%q1(UlR;sT|u!ZER+LUt%gRTKicfY5?63II$z-mx_nee5<c$>ex#Z& z!UH4tUoewu`px=ssz1~w5HyBGD9DnCLfu6o0kc0{od;v6XJOHoo_g~<`9iKJTs+?d z3pW`~oMCUEB})P_p~R-3aYQtp;*O&;a6|@?WQ4;ra5xz!{a3<#I6^lOmnC71@Iu77 z<7f;b9lAq|aD*W*Bd&$}5pnsvHDBdr_(~ZcL&?gp5D7$~jv_9|B${AHYaZ3gQp5?9 zCha022NXky#WLuj0QBA0<}AOFt%C{ypV?nkxFQap%NXvI#UfF0Y!VgC!+~Tp9uIx6 zs5~|rq;v2D8jee0^GGIG>AelP7#`O^#0T0(cg>;EKrV+(l)5JUCD;8Oj+~4vDS0SN zxEuyg6dJ^mF!@0&KM)%%^fSQ@HxAE1nqiKP3|paC!h)FES~8&q3?ITnVv)%>7MqKv zQE>z`5l5n<SvWcljpGt|R3eE=rQqm&X*bgRGuMOTgj|n~h`?pjK_a~m5$%hJ`o}5b z?6Z!Rgz}*!hb54?MmiTRG#3_!M<)=81T>XHBB6Oi5)DlwLleSLi4;1HLm{yU)WNxo z;^woiZ1~dTTQf2j`jXEL3>n!voP2$YLoh2;3`$F%DQd9x4Xq~q`81GKeI*ncxO7=z za-;<X<eFedv<?qz$kL?$0{-XW{5k}mnSZ&DaDPxJuORii>bvU8PQ)UfB%BorF7ktJ z>aVGl{a#0!!QKC>TlH@QLd;tI_rgHn(Wy{LVWH_<78#AhL7B+n;_zsYz$SwrnaCoL zID=u9i6VT8(yWpJJh(0pi0*i4A!iV2gX@CKRbO^8lIK?}Szi-|;W2XjSwcUM%ft@O zY_I`7qW|W|u_<^qfyRT@2O^P+X0fF;gv$fbEINr!qLHXH0t;Fs`oa9Wk;4-iI7Q?J zQ+u%ZiG-`c(7#gtpd!nHjtwBRJ>Z3kg7jFy!2&*qB`u}c)k5yTzI$l>*OQ3!WR}VP z5X$)Yf6P)Y7|Q=E6-H*1oIy-_|6_Ch+clNLr9!(b9<)E<K-(3N0xj`00)>j^(C`E< zmqlPxD9}ztac2(g68eAi?N<c+|Kw`;b$iTzH*%w#Z~9&RCpIPj*lO6nMvmNP4(?q) z-<J;T?=Ac5inX*FO3y3*dK(IDFQAh&LuMr#JQ#fKLI^V-QAG#5a|e!dUpyO7Nq9Dq zM&d}1Pn0j74f=;F<7~9PM1S{q(BI1_ZiagsjDrkrnbUxY^g#myI$uD0-M+<$i8sN1 z)+XbvPv<2)CkVp&&H+>c4tinn($4`?SvB0$TfV8R8g4pl=^^Axn1q4eV9hdC(x)N) zhk7^Y2_VR%kjX@{2^QWAw{Yf1fC4W|K6I!TOHVp@0yMEcBe-T%OK%xVJT%B*OBv08 zW&e#M^R%unH2tm6vq0!EBzEXIq)gOcRr8+|ho|&UdWHE?bOHk+UsT|d&j+Se;DP~> zFDh`!=L6F!aKV7c7ZteV^MPp<xL`o!iwa!w`M|UaTreQ=MFlSTd|+AyE*KE`q5_wE zJ}|8U7YvAeQGrW7ADC8w3kF2KsK6zk4@|4T1p^{qRN#`&2c}ivf&q~)Dsai?1Jf#S z!GOpY6}aT{foT=EU_j)H3S9E}z_bcnFd*_p1upq~U|Iz(7!diQ0+)O~Fs%X?42XPD zflEFgm{x%c21LH7z$Kp#Osl{J10r8k;F8Y=rd8mA0g*2%aLMNb(<*SmfXEjWxa9MJ zX%)C&K;(;Zaj6dfvj-@I{>~#D`rnQn;3-4sKR@(1Hm;5U5NQAa(LVsd`(Eg~4FJM$ z0Pw^Y02pZiFh!KIs?r(&RIk}uE^?2!^K_46?&Owf7c>0`*NfXOSfMdLMnAY{Z6s8~ z+-sYY73jDuM|a}v!{cqIY&tvNV7xv$#I33ZrBWf7oiGQJ8slt<i#@ETS(qK;A1TVO zTiY~u*V>xKGcP_edt3IT6U989FRkTDy7)Q0b8YX{o9A?mQ6!-em8XqDY5tMki`Re9 zBSe|M*ScQ*XU?3I9jU3|Y7Yv?;|{em$TxtFO&i|&oL}L&f8MH_XQNxlF^~4<pTdB| z&~>jOJvZ#}RH~kArg4Ls5Q>gD=4RFs7mThwgD?;;zCM+)Q~&76j`u6(`fF=;gg8W3 zSJ77>w8FijTF+$f*5A<^XQpw`7EwIkch`?iIazk)U3O+Q-?|*>q7jKm`cYsCB4Jjh z)vau^dAi$dqBkn7+>N9!5u7S8S)5#h62vK4t0Cjxvy<lCQKK)p6oQ_ZAN`#DdM5H$ zk45tjPLDe3U9lUu*%iAx+5E9aE_EDrtVX>}Oy(rF<2fmn(HYZ}YJjJysrl$jTCYyK z#%RT8s}>c<r*y`yX>d3&ZsHoDi{vH};{tqiH`Xl9@Q5wN9%ydNZA$wcv+!n5Lv)}^ z_!QMy-(A9IsaamaR|aN|MOf!8(P>QO_)zX5)4+~$^-n(CJ(zFL87O--kiNn11O2@p zkku(V8>v2sYkBrMjf7jZdl40$DzEcfn8ZEP>-CZ4Dau0Lk4u23{9Vt|BBR#pNBfuu z%yAcIaDNxO6yI?I1nRS?N}gj93>zl9CzLl-Wh`nvb6lzI%?7`#dq2I}XR(=C-P!G^ zLyf3DA@EtGg4wsPtylk5$zkVPKj|-iyks}+RYUboY?;pS^rO8Ur!J$OJ0;l1+_2Hs ztUBQ^es`gNdR%PRi~GGF&WKxj&hlz9qVyNoR4nv%Jz|s|c)v4k{i=N(kId{XQxM8g zPp|A*uwK$upR@3&Ps!WzSm&|b*O0!RF;C3amm0=nkypM&ZqI#R9Qo!6_u4_nvW(2k z-n+3A33Zh|<C!%T+@%(;&s6y}maSh!5!`xNGIz<|Zjh_uvmogmd-loP8Qkx5i<>jC z#>Ta0!`hvgk*`~S{Yn3TuevZr<)qHCRmOXo-?ZQCZF_#NWW9}gr}7M|K!fGK1sy>e zlhby4T%-sa-@Q7#{B#r5U9^dtt=XH<wEK`p#lfJ?$2FNN%GP}{MP+PRabC3{#%QV# zKjlh!RorzJ`?TnO&-?90p6m2c*u_QpF$G(W?ZUVn;<^}5NC+wkf6?=?GGWU4w%u!) z9X_nRarFV6i3q2rx6kjbZR>vDSr&ZdlgRz0;n<HW?VUL7fLi|Ph^7r=lzZq@YS&vX z;r(i*f~M(n>lY9=A$AJC4Ya^~Z#s$HWohs_ee(p}o)4GPi7$*X80IWQ{+{nro@h<W zb&B7ByxK*H=Uhzs)PDVto2V?}RddButNhZUut{jG7mpqUDoHvX{w_+=UD$J_v*qfG zL>^<R)!a9fnk^G8)_JNOY#iVHy6svo9m01t({%0InsP_UiDl^M$~2wtn6!pponvDk zKYl!Grb)!hOWobwWy%FB4{v2X`Tm`1Fc;Wnz|c0Usq3+yf>{x9LUg}$)xxL`uiFub zIVTcT_`fMH&*s}U#>GDDcvRhc@1)<=l4RY5r3|3lGV=Uw<W84ze@_?G+N0)^I})c; zd&&ZD9=Xr_{@qL6G498;>C~ma*SiZ4&kFwxf8O|Bcrj^aSy}jtrpmoWX|C~8dF569 zA?}q+kJUNxCd@K<Cv0yxtlL-`^)X??dtW=-ggh;Vu}8kvEzC;>+Su5kNN~I3;x4La zuWoEgU4X~ysLRIrz;us-N0s<vDvh4W2?+_pyG22|J|(N4T|=a|SMlyFNK7FtrD<K* z%t)TByR+-2N%EtXihJ}fP&bz6{g#MYw&KoQ`{W}pY2J5ye7oW}-angLHk0dSP5wFe zhNdvvB7XIO`^Bxx&${QYnV`X(q#3t`Vd*F6R4+8tC^Ae+3^N%2U_sKBKc>Ym*}H6? zzE%YNhZl)6JI_;u542}8&kFL!+cofhn9sysb#!q*anN^4#AWMp^?6fUCuU7%6lPoB zp0XhMPQuaT<ug^2-aYKNEX>IB`lc}6Q2qSgH?&Iuo)s5b896}nmdQs$0+BeCX}0@! zE2pW^9G_@B$k4lp5-R7eZFDZLPB6QncH1wHb8wedn*Ia6;ne6E?Hi_bRw#XF39&$U z`jo1tg*7rRrXK7L`So`2(re0b+3cX^i3h^xByRm#kez7Pa9Q${jQTh+J!F4|a^_^c ziw;J248louK4a8!sg!0GsqU=G9c2OOMn>djc6NR@g>PSxk{eLt*QH)S%4y=K`v(a@ zd+t5INob(^$_L-V?W(M8K@;j)<{Ub&Sxzp9O0fJhidc7iobiPVwRT!Fi58cFE;2Lx z?GK&q<h$C<Dj;tv&GRZ*Sr3-0_|NuvvOIFOYOw8@Bi{BCEvi!a=|`r$tUwx`+oo#m z;ClZP_NSGXHUB)-o*HMpJ@f30ngWD%;M+Y*aXRSD-L9*|z7JRD0XL6tQ!Q%9`FOy0 z@w=Gmd)`*WeyHtPUhnn>by73^sHmYi8D$VK>lag&eTz9)c;d>g)~#hBV}PeyO2g-< z&TM^%wyKTltkCFwX4}SYsA!lGc+bKaS6`hIHFgZKCC6za?Z<gKw$p!@Qxfs4Q+t^} za42-PX|r*4Q<m=I*Ds%y(#@-`#vS8t*;<)-3h}fw%Dg9JS?jWm&Q?YugrRB^^~XY! z2or9{iF!_m?;7ps>MS~X;Z2@Oy;-0>ZQ|AnamNlvcR^Tt2fNDZ+U1<GYTs)03)C)U z!mHI!QWG@*^nt5sZjX+*=0|hf7N%a?Z_GXt<x3oUjJLzv_Rm-WQLXYpHYaDBe%m?l zMu35RywXxv+-c^UO%8+;-<zc5Z&sazSyU6NJLf^hDGe``U2iv-283u5b=(f;XEhlb z7LD_5#m#bir7yBQweNQ1rTynR#Hs+h+*rTL%Av4QcYnZJ@;Id3PM6w5q=v)6$8LCK zR6x8LFFEq0>pIbf1k1Ylk26%3|8h^W;iN%cQ|PCC&*t4}UQ)F+fq4J;+!}LF;=bs% z<S6W+Tpl+ge%bS^M{eUTZJNhWN*@zk=kc5Cj@;uK?8VUw2v=f`y7w}+&)IkxKYdyL z{@15glTQ|mjcG^<-M*8S^;=SS;+VG%S-f=Zx}DnJ+}`nn#eUv(WqlX&PeDi>WiQ}O z$-5`LK2YW;dAr-K`ToV?9qdz>bsM0C=cPH4VBhtJljjNZN480gTT~|7urqTG?Ff7~ zQ=7b8Pe1d<9&=?{SK$Ohqjj~)sitk7m$k$wuisYa*Vf*6m~Ccp+V5_G)k&n$<89<e zZh*w&k}HCe9WZ{yr4?&$3j71y8e+^G16pU0BJxhurp`9hLCnpv@_G|)a~@TH=<ddb zLfeF2=+5KR(WYi(^CDnU7HhWhGB=N4v&xLT;^tR*c|k}?RY)$$d+E#Ti0R+$U(;Tg z)iCyM_O02)hmlEUP6(gHk`<N8Kab=7?yFgRc+670{aG$%9=@J$uFkhxVi(6yE=Ku3 zd{eY8?Ruk%gKvqJ)zNp&h}vwRoxM2XP-nN{N$p2_&KhpiMV4E;Gfut?OpDK38_ikh zJU=Ysyt%zy(2Um0K+#H|XzaK3r(WE@P9a8@L?TK`Uq$$wYcSiPqki>+=>0lCZNZh| VwKb3DOaK4Q*2>B9h`Ddf{{e<YMkxRQ literal 1453 zcmV;e1ycHnP)<h;3K|Lk000e1NJLTq002S&002q|1^@s64+nyU00004XF*Lt006JZ zHwB960000PbVXQnQ*UN;cVTj606}DLVr3vnZDD6+Qe|Oed2z{QJOBU%KS@MERCwC# zoC|CeMHt6t_I1ZoibRYW6G@0c@sVms35wz?Vll>O4KW%?uxN}_3n3P(G=f-Pr=d19 zl%_y>vDH3^QUjuaC?Tndnkd!;Q6Y^QCG@WC-SuwovE%pc?VZPQC!Tfp&dy9anR_%l z|NY(fee><k&QMbNg=M{`L=^jAOM*eNC^_*kHtA2CQhI)W%Liim!W9$h8>(cr)B#^- z8P&)UYe;DDqxAnOPQbSS$WT?Qm2HNR0+6t3%xZH2$?F=0l;C&$dA|b-N<q+;Ra`f- z`K6lbi!PkC!tK(^!8BD{&4IC4M2~)bdU&M&>4v7AhX=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<2<k}o_;0gonk!gN{tJtL;>QAk03kr+10imG z35yUQ1PB2_fG8peyeVTaCKLAmnJ!T5fPlvZ5bBPt>ngYek%9nMHSW%)7jM4nrW;$h z1Ca@#cYDJvcPzPKk0jBlT*U|rf^1sCw)(}lFDdr|gc)1~%M1upyl>SlT7K)IPFa#J z;BC}MTS8moy6Y=%tLOp<vw0gn(-2y=Jag>>%a?X5vOI^kJR%L@^}6Z>EAL%~5a#lh zP?->LDz9<F>iMf5x~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)tE<r$yNWhSxLk)cR$<ZG-zSg=HU<~s(YA^^BF-l1gT7TERLxY<<?Q5gan4c>U 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 zVKAbz<m0}4f=I!DlJ`k?Za}1SaRGv(%u;|5AOr{jLVyq;1PEISEy08;pC&ukYnY2r zOX&s;t_8)$(&i8dLb1a{Fcki&R6vXc$B%<W7^sa5{mz_n4eT&};^Z%%mI?^eLMcV7 zFo?U%84$8e&AZ%BJn!iUgvL)68v<%TEvN~#k$HZ@5fF+b8Q>cFZ-1Qe;cOU~<*6dN z#HqShchsO3)P&kdceml3Yfu`6Um(!8|MMS~R@FRu^vh%0eIsLoP60UM8$E`7V&8iY z9663!P!mZml+PYbaz@vj2QGB~h}qNKvcZ@O4mS<n&Vb|2gd@8NvDRMNHMl0v3Qsl$ zFT-&1IOzlsNC;iS7mS><NZ#&snFe+Y!jNs8fmy<5E&!k~+(W{~CoCwg@}(pWFLemo z;{YK-{@OO-TvxV}0!{#dRba<a97;iuZuUvj8)?{@Hjw0!=eSkPjWn!DDQ7{XV4w&K zNW%J69N$_cAAr9Fk-ZU3s!Y4Oa>77L^;&~w(Brw#KLr>7)=CgJM_{rr00000NkvXX Hu0mjf06vr@ diff --git a/briar-android/res/drawable-xhdpi/msg_out.9.png b/briar-android/res/drawable-xhdpi/msg_out.9.png index d7c2816f1339f91a2abe9fa4bd1b72b05a5b5f47..dd5521a5fcab3d213175fafc946f172ff22c412d 100644 GIT binary patch literal 20167 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 S6DiOh6mW8Ivp;4V9RHuo4)mq~ delta 1911 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 KKx?E#<^3D8pC|<Y diff --git a/briar-android/res/drawable-xhdpi/notice_in.9.png b/briar-android/res/drawable-xhdpi/notice_in.9.png new file mode 100644 index 0000000000000000000000000000000000000000..9af342757d22b3d1e0860f508895ba02d6eb4cdb GIT binary patch literal 19905 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 literal 0 HcmV?d00001 diff --git a/briar-android/res/drawable-xhdpi/notice_out.9.png b/briar-android/res/drawable-xhdpi/notice_out.9.png new file mode 100644 index 0000000000000000000000000000000000000000..3cd51f5900209c456ab2d48f3505603ba716c8d4 GIT binary patch literal 19970 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 Bn6v-@ literal 0 HcmV?d00001 diff --git a/briar-android/res/drawable-xxhdpi/msg_in.9.png b/briar-android/res/drawable-xxhdpi/msg_in.9.png index 3db9979cf1b13128da38558494e6604e730098b6..1330b80faccd4128c7efd9298323a1f0dba317e0 100644 GIT binary patch literal 31767 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�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 S8paZ$$nJf@H+CH{;eP;etpN7` literal 2231 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 FV1km7;-3Hj diff --git a/briar-android/res/drawable-xxhdpi/msg_out.9.png b/briar-android/res/drawable-xxhdpi/msg_out.9.png index b7aa02377fd49c6a462c58ed7972719f41ccd978..866bc8c29dd37708cfba9ba592f4c6728fb2d177 100644 GIT binary patch literal 31573 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 T;s3{$NaA|-i`mqD%;f(EZJ5EB delta 2772 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 I<NOo<0}$}hu>b%7 diff --git a/briar-android/res/drawable-xxhdpi/notice_in.9.png b/briar-android/res/drawable-xxhdpi/notice_in.9.png new file mode 100644 index 0000000000000000000000000000000000000000..690bdd2994b21459c1d2b3b0ba2c89ddd3f7ef45 GIT binary patch literal 20623 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 literal 0 HcmV?d00001 diff --git a/briar-android/res/drawable-xxhdpi/notice_out.9.png b/briar-android/res/drawable-xxhdpi/notice_out.9.png new file mode 100644 index 0000000000000000000000000000000000000000..d1a632b6ed1b0c86dc03f88513465d4068e509ad GIT binary patch literal 20635 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 bnt(&9UjHD;)<$v<4QyCzXLWA1U)<jTyeX)P literal 0 HcmV?d00001 diff --git a/briar-android/res/drawable/contact_offline.xml b/briar-android/res/drawable/contact_offline.xml new file mode 100644 index 0000000000..ac18913fcb --- /dev/null +++ b/briar-android/res/drawable/contact_offline.xml @@ -0,0 +1,21 @@ +<?xml version="1.0" encoding="utf-8"?> +<vector xmlns:android="http://schemas.android.com/apk/res/android" + android:width="24dp" + android:height="24dp" + android:viewportHeight="24" + android:viewportWidth="24"> + + <path + android:fillColor="#2D3E50" + android:pathData="M10.8972,19.9503 C6.5514,19.3493,3.43091,15.2154,4.0625,10.896 +C4.55452,7.53099,7.09451,4.8236,10.394,4.14714 +C14.2569,3.35517,18.1698,5.54347,19.5236,9.25295 +C20.0698,10.7495,20.1616,12.4612,19.777,13.9758 +C19.5457,14.8864,18.8106,16.3388,18.2072,17.0771 +C16.4904,19.1779,13.581,20.3215,10.8973,19.9503 Z" + android:strokeColor="#FFFFFF" + android:strokeLineCap="round" + android:strokeLineJoin="round" + android:strokeWidth="1"/> + +</vector> \ No newline at end of file diff --git a/briar-android/res/drawable/contact_online.xml b/briar-android/res/drawable/contact_online.xml new file mode 100644 index 0000000000..f68b831022 --- /dev/null +++ b/briar-android/res/drawable/contact_online.xml @@ -0,0 +1,21 @@ +<?xml version="1.0" encoding="utf-8"?> +<vector xmlns:android="http://schemas.android.com/apk/res/android" + android:width="24dp" + android:height="24dp" + android:viewportHeight="24" + android:viewportWidth="24"> + + <path + android:fillColor="#95D220" + android:pathData="M10.8972,19.9503 C6.5514,19.3493,3.43091,15.2154,4.0625,10.896 +C4.55452,7.53099,7.09451,4.8236,10.394,4.14714 +C14.2569,3.35517,18.1698,5.54347,19.5236,9.25295 +C20.0698,10.7495,20.1616,12.4612,19.777,13.9758 +C19.5457,14.8864,18.8106,16.3388,18.2072,17.0771 +C16.4904,19.1779,13.581,20.3215,10.8973,19.9503 Z" + android:strokeColor="#FFFFFF" + android:strokeLineCap="round" + android:strokeLineJoin="round" + android:strokeWidth="1.5"/> + +</vector> \ No newline at end of file diff --git a/briar-android/res/drawable/ic_contact_introduction.xml b/briar-android/res/drawable/ic_contact_introduction.xml new file mode 100644 index 0000000000..9395c7b93e --- /dev/null +++ b/briar-android/res/drawable/ic_contact_introduction.xml @@ -0,0 +1,5 @@ +<vector android:alpha="0.56" android:height="48dp" + android:viewportHeight="24.0" android:viewportWidth="24.0" + android:width="48dp" xmlns:android="http://schemas.android.com/apk/res/android"> + <path android:fillColor="#FF000000" android:pathData="M9.01,14L2,14v2h7.01v3L13,15l-3.99,-4v3zM14.99,13v-3L22,10L22,8h-7.01L14.99,5L11,9l3.99,4z"/> +</vector> diff --git a/briar-android/res/drawable/introduction_notification.xml b/briar-android/res/drawable/introduction_notification.xml new file mode 100644 index 0000000000..ac4328d121 --- /dev/null +++ b/briar-android/res/drawable/introduction_notification.xml @@ -0,0 +1,9 @@ +<vector xmlns:android="http://schemas.android.com/apk/res/android" + android:width="24dp" + android:height="24dp" + android:viewportWidth="24.0" + android:viewportHeight="24.0"> + <path + android:fillColor="#FFFFFFFF" + android:pathData="M21,8V7l-3,2 -3,-2v1l3,2 3,-2zm1,-5H2C0.9,3 0,3.9 0,5v14c0,1.1 0.9,2 2,2h20c1.1,0 1.99,-0.9 1.99,-2L24,5c0,-1.1 -0.9,-2 -2,-2zM8,6c1.66,0 3,1.34 3,3s-1.34,3 -3,3 -3,-1.34 -3,-3 1.34,-3 3,-3zm6,12H2v-1c0,-2 4,-3.1 6,-3.1s6,1.1 6,3.1v1zm8,-6h-8V6h8v6z"/> +</vector> diff --git a/briar-android/res/drawable/introduction_white.xml b/briar-android/res/drawable/introduction_white.xml new file mode 100644 index 0000000000..ac4328d121 --- /dev/null +++ b/briar-android/res/drawable/introduction_white.xml @@ -0,0 +1,9 @@ +<vector xmlns:android="http://schemas.android.com/apk/res/android" + android:width="24dp" + android:height="24dp" + android:viewportWidth="24.0" + android:viewportHeight="24.0"> + <path + android:fillColor="#FFFFFFFF" + android:pathData="M21,8V7l-3,2 -3,-2v1l3,2 3,-2zm1,-5H2C0.9,3 0,3.9 0,5v14c0,1.1 0.9,2 2,2h20c1.1,0 1.99,-0.9 1.99,-2L24,5c0,-1.1 -0.9,-2 -2,-2zM8,6c1.66,0 3,1.34 3,3s-1.34,3 -3,3 -3,-1.34 -3,-3 1.34,-3 3,-3zm6,12H2v-1c0,-2 4,-3.1 6,-3.1s6,1.1 6,3.1v1zm8,-6h-8V6h8v6z"/> +</vector> diff --git a/briar-android/res/drawable/message_delivered_white.xml b/briar-android/res/drawable/message_delivered_white.xml new file mode 100644 index 0000000000..720dab1f71 --- /dev/null +++ b/briar-android/res/drawable/message_delivered_white.xml @@ -0,0 +1,5 @@ +<vector android:height="16dp" + android:viewportHeight="24.0" android:viewportWidth="24.0" + android:width="16dp" xmlns:android="http://schemas.android.com/apk/res/android"> + <path android:fillColor="#FFFFFFFF" android:pathData="M18,7l-1.41,-1.41 -6.34,6.34 1.41,1.41L18,7zm4.24,-1.41L11.66,16.17 7.48,12l-1.41,1.41L11.66,19l12,-12 -1.42,-1.41zM0.41,13.41L6,19l1.41,-1.41L1.83,12 0.41,13.41z"/> +</vector> diff --git a/briar-android/res/drawable/message_sent_white.xml b/briar-android/res/drawable/message_sent_white.xml new file mode 100644 index 0000000000..59e6d6d1dd --- /dev/null +++ b/briar-android/res/drawable/message_sent_white.xml @@ -0,0 +1,5 @@ +<vector android:height="16dp" + android:viewportHeight="24.0" android:viewportWidth="24.0" + android:width="16dp" xmlns:android="http://schemas.android.com/apk/res/android"> + <path android:fillColor="#FFFFFFFF" android:pathData="M9,16.17L4.83,12l-1.42,1.41L9,19 21,7l-1.41,-1.41z"/> +</vector> diff --git a/briar-android/res/drawable/message_stored_white.xml b/briar-android/res/drawable/message_stored_white.xml new file mode 100644 index 0000000000..71ee22feaa --- /dev/null +++ b/briar-android/res/drawable/message_stored_white.xml @@ -0,0 +1,5 @@ +<vector android:height="16dp" + android:viewportHeight="24.0" android:viewportWidth="24.0" + android:width="16dp" xmlns:android="http://schemas.android.com/apk/res/android"> + <path android:fillAlpha=".9" android:fillColor="#FFFFFF" android:pathData="M11.99,2C6.47,2 2,6.48 2,12s4.47,10 9.99,10C17.52,22 22,17.52 22,12S17.52,2 11.99,2zM12,20c-4.42,0 -8,-3.58 -8,-8s3.58,-8 8,-8 8,3.58 8,8 -3.58,8 -8,8zM12.5,7H11v6l5.25,3.15 0.75,-1.23 -4.5,-2.67z"/> +</vector> diff --git a/briar-android/res/drawable/round_button.xml b/briar-android/res/drawable/round_button.xml new file mode 100644 index 0000000000..421deb97a5 --- /dev/null +++ b/briar-android/res/drawable/round_button.xml @@ -0,0 +1,13 @@ +<?xml version="1.0" encoding="utf-8"?> +<!-- + A FAB does not work, because even with fabSize="mini" it will be too big due to shadow drawing + on lower API levels +--> +<selector + xmlns:android="http://schemas.android.com/apk/res/android"> + <item> + <shape android:shape="oval"> + <solid android:color="@color/briar_primary"/> + </shape> + </item> +</selector> \ No newline at end of file diff --git a/briar-android/res/drawable/social_send_now_white.xml b/briar-android/res/drawable/social_send_now_white.xml new file mode 100644 index 0000000000..43662f48b7 --- /dev/null +++ b/briar-android/res/drawable/social_send_now_white.xml @@ -0,0 +1,9 @@ +<vector xmlns:android="http://schemas.android.com/apk/res/android" + android:width="24dp" + android:height="24dp" + android:viewportHeight="24.0" + android:viewportWidth="24.0"> + <path + android:fillColor="#FFFFFFFF" + android:pathData="M2.01,21L23,12 2.01,3 2,10l15,2 -15,2z"/> +</vector> diff --git a/briar-android/res/layout/activity_contact_list.xml b/briar-android/res/layout/activity_contact_list.xml index 333dac2035..5f1bb33709 100644 --- a/briar-android/res/layout/activity_contact_list.xml +++ b/briar-android/res/layout/activity_contact_list.xml @@ -7,7 +7,6 @@ android:layout_height="match_parent"> <org.briarproject.android.util.BriarRecyclerView - xmlns:android="http://schemas.android.com/apk/res/android" android:id="@+id/contactList" android:layout_width="match_parent" android:layout_height="match_parent"/> diff --git a/briar-android/res/layout/activity_conversation.xml b/briar-android/res/layout/activity_conversation.xml index 88066e9956..d9c86d64d6 100644 --- a/briar-android/res/layout/activity_conversation.xml +++ b/briar-android/res/layout/activity_conversation.xml @@ -1,46 +1,79 @@ <?xml version="1.0" encoding="utf-8"?> <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" + xmlns:app="http://schemas.android.com/apk/res-auto" + xmlns:tools="http://schemas.android.com/tools" android:orientation="vertical" android:layout_width="match_parent" - android:layout_height="match_parent"> + android:layout_height="match_parent" + tools:context=".android.contact.ConversationActivity"> + + <android.support.v7.widget.Toolbar + android:id="@+id/toolbar" + style="@style/BriarToolbar" + android:layout_width="match_parent" + android:layout_height="wrap_content" + android:minHeight="?attr/actionBarSize" + app:layout_collapseMode="pin" + app:layout_scrollFlags="scroll|enterAlways" + app:popupTheme="@style/ThemeOverlay.AppCompat.Light"> + + <LinearLayout + android:layout_width="wrap_content" + android:layout_height="match_parent"> + + <include layout="@layout/contact_avatar_status"/> + + <TextView + android:id="@+id/contactName" + style="@style/TextAppearance.AppCompat.Widget.ActionBar.Title.Inverse" + android:layout_width="wrap_content" + android:layout_height="match_parent" + android:layout_marginLeft="@dimen/margin_medium" + android:layout_marginStart="@dimen/margin_medium" + android:gravity="center" + tools:text="Contact Name"/> + + </LinearLayout> + + </android.support.v7.widget.Toolbar> <org.briarproject.android.util.BriarRecyclerView android:id="@+id/conversationView" android:layout_width="match_parent" android:layout_height="0dp" - android:layout_weight="1"/> + android:layout_weight="1" + android:background="@color/conversation_background"/> <View style="@style/Divider.Horizontal"/> <LinearLayout - android:orientation="horizontal" android:layout_width="match_parent" android:layout_height="wrap_content" android:background="@color/button_bar_background" + android:orientation="horizontal" android:paddingLeft="@dimen/margin_medium" android:paddingStart="@dimen/margin_medium"> <EditText android:id="@+id/contentView" android:layout_width="0dp" - android:layout_height="wrap_content" - android:hint="@string/private_message_hint" + android:layout_height="match_parent" android:layout_weight="1" + android:hint="@string/private_message_hint" android:inputType="text|textMultiLine|textCapSentences"/> <ImageButton android:id="@+id/sendButton" android:layout_width="38dp" android:layout_height="38dp" - android:layout_gravity="bottom" - android:src="@drawable/social_send_now" - android:background="?attr/selectableItemBackground" - android:scaleType="fitEnd" + android:layout_margin="@dimen/margin_small" + android:background="@drawable/round_button" + android:src="@drawable/social_send_now_white" android:contentDescription="@string/send" - android:paddingRight="@dimen/margin_medium" - android:paddingEnd="@dimen/margin_medium" - android:paddingBottom="@dimen/margin_medium"/> + android:elevation="@dimen/margin_tiny" + /> + </LinearLayout> </LinearLayout> \ No newline at end of file diff --git a/briar-android/res/layout/activity_introduction.xml b/briar-android/res/layout/activity_introduction.xml new file mode 100644 index 0000000000..f351897d0f --- /dev/null +++ b/briar-android/res/layout/activity_introduction.xml @@ -0,0 +1,6 @@ +<?xml version="1.0" encoding="utf-8"?> +<FrameLayout + android:id="@+id/introductionContainer" + xmlns:android="http://schemas.android.com/apk/res/android" + android:layout_width="match_parent" + android:layout_height="match_parent"/> \ No newline at end of file diff --git a/briar-android/res/layout/contact_avatar_status.xml b/briar-android/res/layout/contact_avatar_status.xml new file mode 100644 index 0000000000..2ceb595472 --- /dev/null +++ b/briar-android/res/layout/contact_avatar_status.xml @@ -0,0 +1,28 @@ +<?xml version="1.0" encoding="utf-8"?> +<FrameLayout + xmlns:android="http://schemas.android.com/apk/res/android" + xmlns:app="http://schemas.android.com/apk/res-auto" + xmlns:tools="http://schemas.android.com/tools" + android:layout_width="32dp" + android:layout_height="32dp" + tools:showIn="@layout/activity_conversation"> + + <de.hdodenhof.circleimageview.CircleImageView + android:id="@+id/contactAvatar" + android:layout_width="30dp" + android:layout_height="30dp" + android:transitionName="avatar" + app:civ_border_color="@color/action_bar_text" + app:civ_border_width="@dimen/avatar_border_width" + tools:src="@drawable/ic_launcher"/> + + <ImageView + android:id="@+id/contactStatus" + android:layout_width="15dp" + android:layout_height="15dp" + android:layout_gravity="bottom|right" + android:scaleType="fitCenter" + tools:src="@drawable/contact_online" + tools:ignore="ContentDescription"/> + +</FrameLayout> \ No newline at end of file diff --git a/briar-android/res/layout/introduction_contact_chooser.xml b/briar-android/res/layout/introduction_contact_chooser.xml new file mode 100644 index 0000000000..8363191ac0 --- /dev/null +++ b/briar-android/res/layout/introduction_contact_chooser.xml @@ -0,0 +1,8 @@ +<?xml version="1.0" encoding="utf-8"?> +<org.briarproject.android.util.BriarRecyclerView + xmlns:android="http://schemas.android.com/apk/res/android" + xmlns:tools="http://schemas.android.com/tools" + android:id="@+id/contactList" + android:layout_width="match_parent" + android:layout_height="match_parent" + tools:listitem="@layout/list_item_contact"/> diff --git a/briar-android/res/layout/introduction_message.xml b/briar-android/res/layout/introduction_message.xml new file mode 100644 index 0000000000..7faf8bf555 --- /dev/null +++ b/briar-android/res/layout/introduction_message.xml @@ -0,0 +1,99 @@ +<?xml version="1.0" encoding="utf-8"?> +<android.support.v4.widget.NestedScrollView + xmlns:android="http://schemas.android.com/apk/res/android" + xmlns:app="http://schemas.android.com/apk/res-auto" + xmlns:tools="http://schemas.android.com/tools" + android:layout_width="match_parent" + android:layout_height="match_parent" + android:fillViewport="true"> + + <LinearLayout + xmlns:android="http://schemas.android.com/apk/res/android" + xmlns:app="http://schemas.android.com/apk/res-auto" + xmlns:tools="http://schemas.android.com/tools" + android:layout_width="match_parent" + android:layout_height="match_parent" + android:padding="@dimen/margin_activity_horizontal" + android:orientation="vertical"> + + <RelativeLayout + android:id="@+id/introductionHeader" + android:layout_width="match_parent" + android:layout_height="wrap_content" + android:padding="@dimen/margin_medium"> + + <de.hdodenhof.circleimageview.CircleImageView + android:id="@+id/avatarContact1" + android:layout_width="@dimen/listitem_picture_size" + android:layout_height="@dimen/listitem_picture_size" + android:layout_centerHorizontal="true" + android:layout_marginEnd="@dimen/listitem_horizontal_margin" + android:layout_marginRight="@dimen/listitem_horizontal_margin" + android:layout_toLeftOf="@+id/introductionIcon" + android:layout_toStartOf="@+id/introductionIcon" + app:civ_border_color="@color/briar_text_primary" + app:civ_border_width="@dimen/avatar_border_width" + tools:src="@drawable/ic_launcher"/> + + <ImageView + android:id="@+id/introductionIcon" + android:layout_width="@dimen/listitem_picture_size" + android:layout_height="@dimen/listitem_picture_size" + android:layout_centerHorizontal="true" + android:src="@drawable/ic_contact_introduction" + tools:ignore="ContentDescription"/> + + <de.hdodenhof.circleimageview.CircleImageView + android:id="@+id/avatarContact2" + android:layout_width="@dimen/listitem_picture_size" + android:layout_height="@dimen/listitem_picture_size" + android:layout_centerHorizontal="true" + android:layout_marginLeft="@dimen/listitem_horizontal_margin" + android:layout_marginStart="@dimen/listitem_horizontal_margin" + android:layout_toEndOf="@+id/introductionIcon" + android:layout_toRightOf="@+id/introductionIcon" + android:transitionName="avatar" + app:civ_border_color="@color/briar_text_primary" + app:civ_border_width="@dimen/avatar_border_width" + tools:src="@drawable/ic_launcher"/> + + </RelativeLayout> + + <ProgressBar + android:id="@+id/progressBar" + style="?android:attr/progressBarStyleLarge" + android:layout_width="wrap_content" + android:layout_height="wrap_content" + android:layout_gravity="center" + tools:visibility="gone"/> + + <TextView + android:id="@+id/introductionText" + android:layout_width="match_parent" + android:layout_height="0dp" + android:layout_marginTop="@dimen/margin_medium" + android:layout_weight="1" + android:gravity="top" + android:textSize="@dimen/text_size_medium" + tools:text="@string/introduction_message_text"/> + + <EditText + android:id="@+id/introductionMessageView" + android:layout_width="match_parent" + android:layout_height="wrap_content" + android:layout_marginTop="@dimen/margin_medium" + android:gravity="bottom" + android:hint="@string/introduction_message_hint" + android:inputType="text|textMultiLine|textCapSentences"/> + + <Button + android:id="@+id/makeIntroductionButton" + style="@style/BriarButton" + android:layout_width="match_parent" + android:layout_height="wrap_content" + android:text="@string/introduction_button" + /> + + </LinearLayout> + +</android.support.v4.widget.NestedScrollView> \ No newline at end of file diff --git a/briar-android/res/layout/list_item_contact.xml b/briar-android/res/layout/list_item_contact.xml index b566dc1713..78f0681bdd 100644 --- a/briar-android/res/layout/list_item_contact.xml +++ b/briar-android/res/layout/list_item_contact.xml @@ -1,16 +1,19 @@ <?xml version="1.0" encoding="utf-8"?> <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" - xmlns:tools="http://schemas.android.com/tools" xmlns:app="http://schemas.android.com/apk/res-auto" + xmlns:tools="http://schemas.android.com/tools" android:layout_width="match_parent" android:layout_height="wrap_content" android:orientation="vertical"> <RelativeLayout android:layout_width="match_parent" - android:layout_height="@dimen/listitem_height_one_line_avatar" - android:background="?attr/selectableItemBackground"> + android:layout_height="wrap_content" + android:paddingTop="@dimen/listitem_horizontal_margin" + android:paddingBottom="@dimen/listitem_horizontal_margin" + android:background="?attr/selectableItemBackground" + > <de.hdodenhof.circleimageview.CircleImageView android:id="@+id/avatarView" @@ -21,56 +24,62 @@ android:layout_centerVertical="true" android:layout_marginLeft="@dimen/listitem_horizontal_margin" android:layout_marginStart="@dimen/listitem_horizontal_margin" + android:transitionName="avatar" + app:civ_border_color="@color/briar_text_primary" app:civ_border_width="@dimen/avatar_border_width" - app:civ_border_color="@color/briar_text_primary"/> + tools:src="@drawable/ic_launcher"/> <LinearLayout - android:id="@+id/bulbHolder" + android:id="@+id/textViews" android:layout_width="wrap_content" android:layout_height="wrap_content" - android:layout_alignParentEnd="true" - android:layout_alignParentRight="true" + android:orientation="vertical" android:layout_centerVertical="true" - android:layout_marginEnd="@dimen/listitem_horizontal_margin" - android:layout_marginRight="@dimen/listitem_horizontal_margin" - android:gravity="right" - android:orientation="vertical"> + android:layout_marginLeft="@dimen/listitem_horizontal_margin" + android:layout_marginStart="@dimen/listitem_horizontal_margin" + android:layout_toLeftOf="@+id/bulbView" + android:layout_toRightOf="@+id/avatarView" + android:layout_toEndOf="@+id/avatarView"> - <ImageView - android:id="@+id/bulbView" + <TextView + android:id="@+id/nameView" android:layout_width="wrap_content" android:layout_height="wrap_content" - tools:src="@drawable/contact_disconnected"/> + android:maxLines="2" + android:textColor="@android:color/primary_text_light" + android:textSize="@dimen/text_size_medium" + tools:text="This is a name of a contact"/> <TextView android:id="@+id/dateView" android:layout_width="wrap_content" android:layout_height="wrap_content" - android:textColor="@color/no_private_messages" + android:textColor="@android:color/secondary_text_light" + android:textSize="@dimen/text_size_small" tools:text="Dec 24"/> + <TextView + android:id="@+id/identityView" + android:layout_width="wrap_content" + android:layout_height="wrap_content" + android:textColor="@android:color/tertiary_text_light" + android:textSize="@dimen/text_size_tiny" + tools:text="My Identity"/> + </LinearLayout> - <TextView - android:id="@+id/nameView" + <ImageView + android:id="@+id/bulbView" android:layout_width="wrap_content" android:layout_height="wrap_content" - android:layout_alignParentLeft="true" - android:layout_alignParentStart="true" + android:layout_alignParentEnd="true" + android:layout_alignParentRight="true" android:layout_centerVertical="true" - android:layout_marginEnd="@dimen/margin_small" - android:layout_marginLeft="@dimen/listitem_text_left_margin" - android:layout_marginRight="@dimen/margin_small" - android:layout_marginStart="@dimen/listitem_text_left_margin" - android:layout_toLeftOf="@id/bulbHolder" - android:layout_toStartOf="@id/bulbHolder" - android:gravity="center_vertical" - android:maxLines="2" - android:textSize="@dimen/text_size_medium" - tools:text="This is a name of a contact. It can be quite long."/> + android:layout_marginRight="@dimen/listitem_horizontal_margin" + tools:src="@drawable/contact_connected"/> </RelativeLayout> - <View style="@style/Divider.Horizontal"/> + <View style="@style/Divider.ContactListDevider"/> </LinearLayout> \ No newline at end of file diff --git a/briar-android/res/layout/list_item_introduction_in.xml b/briar-android/res/layout/list_item_introduction_in.xml new file mode 100644 index 0000000000..08da32d778 --- /dev/null +++ b/briar-android/res/layout/list_item_introduction_in.xml @@ -0,0 +1,67 @@ +<?xml version="1.0" encoding="utf-8"?> +<LinearLayout + xmlns:android="http://schemas.android.com/apk/res/android" + xmlns:tools="http://schemas.android.com/tools" + android:layout_width="match_parent" + android:layout_height="wrap_content" + android:orientation="vertical"> + + <include + android:id="@+id/messageLayout" + layout="@layout/list_item_msg_in"/> + + <RelativeLayout + android:id="@+id/introductionLayout" + android:layout_width="wrap_content" + android:layout_height="wrap_content" + android:layout_gravity="left|start" + android:background="@drawable/notice_in" + android:layout_marginLeft="@dimen/message_bubble_margin_tail" + android:layout_marginRight="@dimen/message_bubble_margin_non_tail"> + + <TextView + android:id="@+id/introductionText" + android:layout_width="wrap_content" + android:layout_height="wrap_content" + android:minWidth="80dp" + android:textIsSelectable="true" + android:textSize="@dimen/text_size_medium" + android:textStyle="italic" + tools:text="@string/introduction_request_received"/> + + <TextView + android:id="@+id/introductionTime" + android:layout_width="wrap_content" + android:layout_height="wrap_content" + android:layout_marginTop="@dimen/message_bubble_timestamp_margin" + android:layout_alignEnd="@+id/acceptButton" + android:layout_alignRight="@+id/acceptButton" + android:layout_below="@+id/acceptButton" + android:textColor="@color/private_message_date" + android:textSize="@dimen/text_size_tiny" + tools:text="Dec 24, 13:37"/> + + <Button + android:id="@+id/acceptButton" + style="@style/BriarButtonFlat.Positive" + android:layout_width="wrap_content" + android:layout_height="wrap_content" + android:layout_marginBottom="-15dp" + android:layout_alignEnd="@+id/introductionText" + android:layout_alignRight="@+id/introductionText" + android:layout_below="@+id/introductionText" + android:text="@string/dialog_button_accept"/> + + <Button + android:id="@+id/declineButton" + style="@style/BriarButtonFlat.Negative" + android:layout_width="wrap_content" + android:layout_height="wrap_content" + android:layout_below="@+id/introductionText" + android:layout_toLeftOf="@+id/acceptButton" + android:layout_toStartOf="@+id/acceptButton" + android:text="@string/dialog_button_decline"/> + + </RelativeLayout> + +</LinearLayout> \ No newline at end of file diff --git a/briar-android/res/layout/list_item_introduction_out.xml b/briar-android/res/layout/list_item_introduction_out.xml new file mode 100644 index 0000000000..d3e1a85aa6 --- /dev/null +++ b/briar-android/res/layout/list_item_introduction_out.xml @@ -0,0 +1,57 @@ +<?xml version="1.0" encoding="utf-8"?> +<LinearLayout + xmlns:android="http://schemas.android.com/apk/res/android" + xmlns:tools="http://schemas.android.com/tools" + android:layout_width="match_parent" + android:layout_height="wrap_content" + android:orientation="vertical"> + + <include + android:id="@+id/messageLayout" + layout="@layout/list_item_msg_out"/> + + <RelativeLayout + android:id="@+id/introductionLayout" + android:layout_width="wrap_content" + android:layout_height="wrap_content" + android:layout_gravity="right|end" + android:background="@drawable/notice_out" + android:layout_marginLeft="@dimen/message_bubble_margin_non_tail" + android:layout_marginRight="@dimen/message_bubble_margin_tail"> + + <TextView + android:id="@+id/introductionText" + android:layout_width="wrap_content" + android:layout_height="wrap_content" + android:minWidth="175dp" + android:textIsSelectable="true" + android:textSize="@dimen/text_size_medium" + android:textStyle="italic" + tools:text="@string/introduction_request_received"/> + + <TextView + android:id="@+id/introductionTime" + android:layout_width="wrap_content" + android:layout_height="wrap_content" + android:layout_marginTop="@dimen/message_bubble_timestamp_margin" + android:layout_alignParentLeft="true" + android:layout_alignParentStart="true" + android:layout_below="@+id/introductionText" + android:textColor="@color/private_message_date" + android:textSize="@dimen/text_size_tiny" + tools:text="Dec 24, 13:37"/> + + <ImageView + android:id="@+id/introductionStatus" + android:layout_width="wrap_content" + android:layout_height="wrap_content" + android:layout_toEndOf="@+id/introductionTime" + android:layout_toRightOf="@+id/introductionTime" + android:layout_alignBottom="@+id/introductionTime" + android:layout_marginLeft="@dimen/margin_medium" + tools:ignore="ContentDescription" + tools:src="@drawable/message_delivered"/> + + </RelativeLayout> + +</LinearLayout> \ 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 index fa1f793ab7..13ec9b2870 100644 --- a/briar-android/res/layout/list_item_msg_in.xml +++ b/briar-android/res/layout/list_item_msg_in.xml @@ -1,53 +1,51 @@ <?xml version="1.0" encoding="utf-8"?> <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" - xmlns:tools="http://schemas.android.com/tools" xmlns:app="http://schemas.android.com/apk/res-auto" + xmlns:tools="http://schemas.android.com/tools" android:layout_width="match_parent" android:layout_height="wrap_content" - android:orientation="horizontal" - android:paddingRight="@dimen/margin_medium" - android:paddingEnd="@dimen/margin_medium" - android:paddingTop="@dimen/margin_small" - android:paddingBottom="@dimen/margin_small"> + android:orientation="horizontal"> <de.hdodenhof.circleimageview.CircleImageView android:id="@+id/msgAvatar" android:layout_width="@dimen/listitem_picture_size" android:layout_height="@dimen/listitem_picture_size" - android:layout_marginLeft="@dimen/listitem_horizontal_margin" - android:layout_marginStart="@dimen/listitem_horizontal_margin" + android:layout_marginLeft="@dimen/margin_medium" + android:layout_marginStart="@dimen/margin_medium" + android:visibility="gone" + app:civ_border_color="@color/briar_text_primary" app:civ_border_width="@dimen/avatar_border_width" - app:civ_border_color="@color/briar_text_primary"/> + tools:src="@drawable/ic_launcher"/> - <RelativeLayout + <LinearLayout android:id="@+id/msgLayout" android:layout_width="wrap_content" android:layout_height="wrap_content" - android:layout_gravity="left|start" android:background="@drawable/msg_in" - android:paddingLeft="17dp" - android:paddingTop="5dp" - android:paddingRight="7dp" - android:paddingBottom="5dp"> + android:orientation="vertical" + android:layout_marginLeft="@dimen/message_bubble_margin_tail" + android:layout_marginRight="@dimen/message_bubble_margin_non_tail"> <TextView android:id="@+id/msgBody" android:layout_width="wrap_content" android:layout_height="wrap_content" - android:minWidth="80dp" android:textIsSelectable="true" + android:textSize="@dimen/text_size_medium" tools:text="Short message"/> <TextView android:id="@+id/msgTime" android:layout_width="wrap_content" android:layout_height="wrap_content" - android:textSize="10sp" + android:layout_gravity="right|end" + android:layout_marginTop="@dimen/message_bubble_timestamp_margin" + android:maxLines="1" android:textColor="@color/private_message_date" - android:layout_below="@+id/msgBody" + android:textSize="@dimen/text_size_tiny" tools:text="Dec 24, 13:37"/> - </RelativeLayout> + </LinearLayout> </LinearLayout> \ 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 index a82a07f1e0..5902b7381e 100644 --- a/briar-android/res/layout/list_item_msg_out.xml +++ b/briar-android/res/layout/list_item_msg_out.xml @@ -4,11 +4,7 @@ xmlns:tools="http://schemas.android.com/tools" android:layout_width="match_parent" android:layout_height="wrap_content" - android:orientation="vertical" - android:paddingLeft="@dimen/margin_medium" - android:paddingStart="@dimen/margin_medium" - android:paddingTop="@dimen/margin_small" - android:paddingBottom="@dimen/margin_small"> + android:orientation="vertical"> <RelativeLayout android:id="@+id/msgLayout" @@ -16,28 +12,29 @@ android:layout_height="wrap_content" android:layout_gravity="right|end" android:background="@drawable/msg_out" - android:paddingLeft="7dp" - android:paddingTop="5dp" - android:paddingRight="17dp" - android:paddingBottom="5dp"> + android:layout_marginLeft="@dimen/message_bubble_margin_non_tail" + android:layout_marginRight="@dimen/message_bubble_margin_tail"> <TextView android:id="@+id/msgBody" android:layout_width="wrap_content" android:layout_height="wrap_content" + android:textColor="@color/briar_text_primary_inverse" android:textIsSelectable="true" - android:minWidth="80dp" + android:textSize="@dimen/text_size_medium" tools:text="This is a long long long message that spans over several lines.\n\nIt ends here."/> <TextView android:id="@+id/msgTime" android:layout_width="wrap_content" android:layout_height="wrap_content" + android:layout_marginTop="@dimen/message_bubble_timestamp_margin" + android:layout_alignParentLeft="true" + android:layout_alignParentStart="true" android:layout_below="@+id/msgBody" - android:layout_toLeftOf="@+id/msgStatus" - android:textSize="10sp" - android:textColor="@color/private_message_date" android:singleLine="true" + android:textColor="@color/private_message_date_inverse" + android:textSize="@dimen/text_size_tiny" tools:text="Dec 24, 13:37"/> <ImageView @@ -45,10 +42,11 @@ android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_alignBottom="@+id/msgTime" - android:layout_alignRight="@+id/msgBody" - android:layout_alignEnd="@+id/msgBody" - android:layout_marginLeft="3dp" - tools:src="@drawable/message_delivered"/> + android:layout_marginLeft="@dimen/margin_medium" + android:layout_toEndOf="@+id/msgTime" + android:layout_toRightOf="@+id/msgTime" + tools:ignore="ContentDescription" + tools:src="@drawable/message_delivered_white"/> </RelativeLayout> diff --git a/briar-android/res/layout/list_item_notice_in.xml b/briar-android/res/layout/list_item_notice_in.xml new file mode 100644 index 0000000000..e7c912f915 --- /dev/null +++ b/briar-android/res/layout/list_item_notice_in.xml @@ -0,0 +1,34 @@ +<?xml version="1.0" encoding="utf-8"?> +<LinearLayout + android:id="@+id/noticeLayout" + xmlns:android="http://schemas.android.com/apk/res/android" + xmlns:tools="http://schemas.android.com/tools" + android:layout_width="wrap_content" + android:layout_height="wrap_content" + android:background="@drawable/notice_in" + android:orientation="vertical" + android:layout_marginLeft="@dimen/message_bubble_margin_tail" + android:layout_marginRight="@dimen/message_bubble_margin_non_tail"> + + <TextView + android:id="@+id/noticeText" + android:layout_width="wrap_content" + android:layout_height="wrap_content" + android:minWidth="80dp" + android:textIsSelectable="true" + android:textSize="@dimen/text_size_medium" + android:textStyle="italic" + tools:text="@string/introduction_response_accepted_received"/> + + <TextView + android:id="@+id/noticeTime" + android:layout_width="wrap_content" + android:layout_height="wrap_content" + android:layout_gravity="right|end" + android:layout_marginTop="@dimen/message_bubble_timestamp_margin" + android:maxLines="1" + android:textColor="@color/private_message_date" + android:textSize="@dimen/text_size_tiny" + tools:text="Dec 24, 13:37"/> + +</LinearLayout> \ No newline at end of file diff --git a/briar-android/res/layout/list_item_notice_out.xml b/briar-android/res/layout/list_item_notice_out.xml new file mode 100644 index 0000000000..499e1506fd --- /dev/null +++ b/briar-android/res/layout/list_item_notice_out.xml @@ -0,0 +1,52 @@ +<?xml version="1.0" encoding="utf-8"?> +<LinearLayout + xmlns:android="http://schemas.android.com/apk/res/android" + xmlns:tools="http://schemas.android.com/tools" + android:layout_width="match_parent" + android:layout_height="wrap_content" + android:orientation="vertical"> + + <RelativeLayout + android:id="@+id/noticeLayout" + android:layout_width="wrap_content" + android:layout_height="wrap_content" + android:layout_gravity="right|end" + android:background="@drawable/notice_out" + android:layout_marginLeft="@dimen/message_bubble_margin_non_tail" + android:layout_marginRight="@dimen/message_bubble_margin_tail"> + + <TextView + android:id="@+id/noticeText" + android:layout_width="wrap_content" + android:layout_height="wrap_content" + android:textIsSelectable="true" + android:textSize="@dimen/text_size_medium" + android:textStyle="italic" + tools:text="@string/introduction_response_accepted_sent"/> + + <TextView + android:id="@+id/noticeTime" + android:layout_width="wrap_content" + android:layout_height="wrap_content" + android:layout_marginTop="@dimen/message_bubble_timestamp_margin" + android:layout_alignParentLeft="true" + android:layout_alignParentStart="true" + android:layout_below="@+id/noticeText" + android:textColor="@color/private_message_date" + android:textSize="@dimen/text_size_tiny" + tools:text="Dec 24, 13:37"/> + + <ImageView + android:id="@+id/noticeStatus" + android:layout_width="wrap_content" + android:layout_height="wrap_content" + android:layout_alignBottom="@+id/noticeTime" + android:layout_marginLeft="@dimen/margin_medium" + android:layout_toEndOf="@+id/noticeTime" + android:layout_toRightOf="@+id/noticeTime" + tools:ignore="ContentDescription" + tools:src="@drawable/message_delivered"/> + + </RelativeLayout> + +</LinearLayout> \ No newline at end of file diff --git a/briar-android/res/menu/contact_actions.xml b/briar-android/res/menu/conversation_actions.xml similarity index 53% rename from briar-android/res/menu/contact_actions.xml rename to briar-android/res/menu/conversation_actions.xml index 3cce37ad83..01090aaec6 100644 --- a/briar-android/res/menu/contact_actions.xml +++ b/briar-android/res/menu/conversation_actions.xml @@ -3,10 +3,16 @@ xmlns:android="http://schemas.android.com/apk/res/android" xmlns:app="http://schemas.android.com/apk/res-auto"> + <item + android:id="@+id/action_introduction" + android:icon="@drawable/introduction_white" + android:title="@string/make_introduction" + app:showAsAction="never"/> + <item android:id="@+id/action_social_remove_person" android:icon="@drawable/social_remove_person" - app:showAsAction="always" - android:title="@string/delete_contact"/> + android:title="@string/delete_contact" + app:showAsAction="never"/> </menu> \ No newline at end of file diff --git a/briar-android/res/values/color.xml b/briar-android/res/values/color.xml index bcb8d2b0ae..0351b52966 100644 --- a/briar-android/res/values/color.xml +++ b/briar-android/res/values/color.xml @@ -8,11 +8,13 @@ <color name="briar_red">#C1392B</color> <color name="window_background">#EEEEEE</color> + <color name="conversation_background">#efebe9</color> <color name="action_bar_text">#FFFFFF</color> <color name="action_bar_background">@color/briar_blue</color> <color name="button_bar_background">#FFFFFF</color> <color name="dashboard_background">#FFFFFF</color> <color name="private_message_date">#AAAAAA</color> + <color name="private_message_date_inverse">#e0e0e0</color> <color name="unread_background">#FFFFFF</color> <color name="horizontal_border">#CCCCCC</color> <color name="forums_available_background">@color/briar_gold</color> @@ -28,6 +30,8 @@ <color name="briar_text_link">@color/briar_green_dark</color> <color name="briar_text_primary">@color/briar_primary</color> <color name="briar_text_primary_inverse">#ffffff</color> + <color name="briar_text_secondary">#333333</color> + <color name="briar_text_tertiary">#333333</color> <!-- this is needed as preference_category_material layout uses this color as the text color --> <color name="preference_fallback_accent_color">@color/briar_accent</color> diff --git a/briar-android/res/values/dimens.xml b/briar-android/res/values/dimens.xml index 41af17d52a..b1985532c1 100644 --- a/briar-android/res/values/dimens.xml +++ b/briar-android/res/values/dimens.xml @@ -23,8 +23,12 @@ <dimen name="listitem_horizontal_margin">16dp</dimen> <dimen name="listitem_text_left_margin">72dp</dimen> <dimen name="listitem_height_one_line_avatar">56dp</dimen> - <dimen name="listitem_picture_size">40dp</dimen> + <dimen name="listitem_picture_size">48dp</dimen> <dimen name="dropdown_picture_size">32dp</dimen> <dimen name="avatar_border_width">1dp</dimen> + <dimen name="message_bubble_margin_tail">14dp</dimen> + <dimen name="message_bubble_margin_non_tail">51dp</dimen> + <dimen name="message_bubble_timestamp_margin">15dp</dimen> + </resources> diff --git a/briar-android/res/values/strings.xml b/briar-android/res/values/strings.xml index f75d8a90d2..c37fa7ea6b 100644 --- a/briar-android/res/values/strings.xml +++ b/briar-android/res/values/strings.xml @@ -141,6 +141,26 @@ <string name="transport_lan">Wi-Fi</string> <string name="no_data">No data</string> <string name="unknown_app">an unknown app</string> + <string name="make_introduction">Make Introduction</string> + <string name="introduction_activity_title">Select contact</string> + <string name="introduction_message_title">Introduce Contacts</string> + <string name="introduction_message_text">You can compose a message that will be sent to %1$s and %2$s along with your introduction:</string> + <string name="introduction_message_hint">Type message (optional)</string> + <string name="introduction_button">Make Introduction</string> + <string name="introduction_error">There was an error making the introduction.</string> + <string name="introduction_response_error">Error when responding to introduction</string> + <string name="introduction_warn_different_identities_title">Warning: Different Identities</string> + <string name="introduction_warn_different_identities_text">You are trying to introduce two contacts that you have added with different identities. This might reveal that both identities are yours.</string> + <string name="introduction_request_sent">You have introduced %1$s to %2$s.</string> + <string name="introduction_request_received">%1$s introduced you to %2$s. Do you want to add %2$s to your contact list?</string> + <string name="introduction_request_exists_received">%1$s introduced you to %2$s, but %2$s is already in your contact list. Since %1$s might not know that, you can still respond:</string> + <string name="introduction_request_answered_received">%1$s introduced you to %2$s.</string> + <string name="introduction_response_accepted_sent">You accepted the introduction to %1$s.</string> + <string name="introduction_response_declined_sent">You declined the introduction to %1$s.</string> + <string name="introduction_response_accepted_received">%1$s accepted to be introduced to %2$s.</string> + <string name="introduction_response_declined_received">%1$s declined to be introduced to %2$s.</string> + <string name="introduction_success_title">Introduced contact was added</string> + <string name="introduction_success_text">You have been successfully introduced to %1$s who was now added to your contact list.</string> <!-- Dialogs --> <string name="dialog_title_lost_password">Lost Password</string> @@ -152,6 +172,9 @@ <string name="dialog_title_welcome">Welcome to Briar</string> <string name="dialog_welcome_message">Add a contact to start communicating securely or press the icon in the upper left corner of the screen for more options.</string> <string name="dialog_button_ok">OK</string> + <string name="dialog_button_introduce">Introduce</string> + <string name="dialog_button_accept">Accept</string> + <string name="dialog_button_decline">Decline</string> <!-- Toolbar headers --> <string name="dashboard_toolbar_header">Briar</string> <string name="settings_toolbar_header">Settings</string> diff --git a/briar-android/res/values/styles.xml b/briar-android/res/values/styles.xml index 4c80c10ede..9b4ebbf6ca 100644 --- a/briar-android/res/values/styles.xml +++ b/briar-android/res/values/styles.xml @@ -51,13 +51,31 @@ <item name="elevation">1dp</item> </style> - <style name="BriarButton"> + <style name="BriarDialogTheme" parent="Theme.AppCompat.Light.Dialog"> + <item name="colorPrimary">@color/briar_primary</item> + <item name="colorPrimaryDark">@color/briar_primary_dark</item> + <item name="colorAccent">@color/briar_accent</item> + </style> + + <style name="BriarButton" parent="Widget.AppCompat.Button.Colored"> <item name="android:textSize">@dimen/text_size_medium</item> <item name="android:padding">@dimen/margin_large</item> </style> <style name="BriarButton.Default"/> + <style name="BriarButtonFlat.Negative" parent="Widget.AppCompat.Button.Borderless"> + <item name="android:textColor">#ff0000</item> + <item name="android:textSize">@dimen/text_size_medium</item> + <item name="android:padding">@dimen/margin_large</item> + </style> + + <style name="BriarButtonFlat.Positive" parent="Widget.AppCompat.Button.Borderless"> + <item name="android:textColor">#06b9ff</item> + <item name="android:textSize">@dimen/text_size_medium</item> + <item name="android:padding">@dimen/margin_large</item> + </style> + <style name="BriarTextTitle"> <item name="android:textSize">@dimen/text_size_medium</item> <item name="android:textColor">@android:color/primary_text_light</item> @@ -76,11 +94,17 @@ <item name="android:background">?android:attr/listDivider</item> </style> - <style name="Divider.Horizontal"> + <style name="Divider.Horizontal" parent="Divider"> <item name="android:layout_width">match_parent</item> <item name="android:layout_height">1px</item> </style> + <style name="Divider.ContactListDevider" parent="Divider"> + <item name="android:layout_width">match_parent</item> + <item name="android:layout_height">2dp</item> + <item name="android:layout_marginLeft">@dimen/margin_large</item> + </style> + <style name="NavMenuButton" parent="Widget.AppCompat.Button.Borderless.Colored"> <item name="android:textSize">@dimen/text_size_medium</item> <item name="android:textColor">@android:color/tertiary_text_light</item> diff --git a/briar-android/src/org/briarproject/android/AndroidComponent.java b/briar-android/src/org/briarproject/android/AndroidComponent.java index 4b3caa9967..5b73d5e53b 100644 --- a/briar-android/src/org/briarproject/android/AndroidComponent.java +++ b/briar-android/src/org/briarproject/android/AndroidComponent.java @@ -12,6 +12,9 @@ import org.briarproject.android.forum.ReadForumPostActivity; import org.briarproject.android.forum.ShareForumActivity; import org.briarproject.android.forum.WriteForumPostActivity; import org.briarproject.android.identity.CreateIdentityActivity; +import org.briarproject.android.introduction.ContactChooserFragment; +import org.briarproject.android.introduction.IntroductionActivity; +import org.briarproject.android.introduction.IntroductionMessageFragment; import org.briarproject.android.invitation.AddContactActivity; import org.briarproject.android.keyagreement.ChooseIdentityFragment; import org.briarproject.android.keyagreement.KeyAgreementActivity; @@ -80,6 +83,12 @@ public interface AndroidComponent extends CoreEagerSingletons { void inject(ShowQrCodeFragment fragment); + void inject(IntroductionActivity activity); + + void inject(ContactChooserFragment fragment); + + void inject(IntroductionMessageFragment fragment); + // Eager singleton load void inject(AppModule.EagerSingletons init); } diff --git a/briar-android/src/org/briarproject/android/AndroidNotificationManagerImpl.java b/briar-android/src/org/briarproject/android/AndroidNotificationManagerImpl.java index 3cd074aea5..2330aac866 100644 --- a/briar-android/src/org/briarproject/android/AndroidNotificationManagerImpl.java +++ b/briar-android/src/org/briarproject/android/AndroidNotificationManagerImpl.java @@ -14,10 +14,14 @@ import org.briarproject.android.api.AndroidExecutor; import org.briarproject.android.api.AndroidNotificationManager; import org.briarproject.android.contact.ConversationActivity; import org.briarproject.android.forum.ForumActivity; +import org.briarproject.api.contact.Contact; import org.briarproject.api.db.DatabaseExecutor; import org.briarproject.api.db.DbException; import org.briarproject.api.event.Event; import org.briarproject.api.event.EventListener; +import org.briarproject.api.event.IntroductionRequestReceivedEvent; +import org.briarproject.api.event.IntroductionResponseReceivedEvent; +import org.briarproject.api.event.IntroductionSucceededEvent; import org.briarproject.api.event.MessageValidatedEvent; import org.briarproject.api.event.SettingsUpdatedEvent; import org.briarproject.api.forum.ForumManager; @@ -57,6 +61,7 @@ class AndroidNotificationManagerImpl implements AndroidNotificationManager, private static final int PRIVATE_MESSAGE_NOTIFICATION_ID = 3; private static final int FORUM_POST_NOTIFICATION_ID = 4; + private static final int INTRODUCTION_SUCCESS_NOTIFICATION_ID = 5; private static final String CONTACT_URI = "content://org.briarproject/contact"; private static final String FORUM_URI = @@ -111,6 +116,7 @@ class AndroidNotificationManagerImpl implements AndroidNotificationManager, public Void call() { clearPrivateMessageNotification(); clearForumPostNotification(); + clearIntroductionSuccessNotification(); return null; } }); @@ -135,6 +141,12 @@ class AndroidNotificationManagerImpl implements AndroidNotificationManager, nm.cancel(FORUM_POST_NOTIFICATION_ID); } + private void clearIntroductionSuccessNotification() { + Object o = appContext.getSystemService(NOTIFICATION_SERVICE); + NotificationManager nm = (NotificationManager) o; + nm.cancel(INTRODUCTION_SUCCESS_NOTIFICATION_ID); + } + public void eventOccurred(Event e) { if (e instanceof SettingsUpdatedEvent) { SettingsUpdatedEvent s = (SettingsUpdatedEvent) e; @@ -148,6 +160,25 @@ class AndroidNotificationManagerImpl implements AndroidNotificationManager, else if (c.equals(forumManager.getClientId())) showForumPostNotification(m.getMessage().getGroupId()); } + } else if (e instanceof IntroductionRequestReceivedEvent) { + try { + GroupId group = messagingManager.getConversationId( + ((IntroductionRequestReceivedEvent) e).getContactId()); + showPrivateMessageNotification(group); + } catch (DbException ex) { + if (LOG.isLoggable(WARNING)) LOG.log(WARNING, ex.toString(), ex); + } + } else if (e instanceof IntroductionResponseReceivedEvent) { + try { + GroupId group = messagingManager.getConversationId( + ((IntroductionResponseReceivedEvent) e).getContactId()); + showPrivateMessageNotification(group); + } catch (DbException ex) { + if (LOG.isLoggable(WARNING)) LOG.log(WARNING, ex.toString(), ex); + } + } else if (e instanceof IntroductionSucceededEvent) { + Contact c = ((IntroductionSucceededEvent) e).getContact(); + showIntroductionSucceededNotification(c); } } @@ -335,4 +366,35 @@ class AndroidNotificationManagerImpl implements AndroidNotificationManager, } }); } + + private void showIntroductionSucceededNotification(final Contact c) { + androidExecutor.execute(new Runnable() { + public void run() { + NotificationCompat.Builder b = + new NotificationCompat.Builder(appContext); + b.setSmallIcon(R.drawable.introduction_notification); + + b.setContentTitle(appContext + .getString(R.string.introduction_success_title)); + b.setContentText(appContext + .getString(R.string.introduction_success_text, + c.getAuthor().getName())); + b.setDefaults(getDefaults()); + b.setAutoCancel(true); + + Intent i = new Intent(appContext, NavDrawerActivity.class); + i.putExtra(NavDrawerActivity.INTENT_CONTACTS, true); + i.setFlags(FLAG_ACTIVITY_CLEAR_TOP | FLAG_ACTIVITY_SINGLE_TOP); + TaskStackBuilder t = TaskStackBuilder.create(appContext); + t.addParentStack(NavDrawerActivity.class); + t.addNextIntent(i); + b.setContentIntent(t.getPendingIntent(nextRequestId++, 0)); + + Object o = appContext.getSystemService(NOTIFICATION_SERVICE); + NotificationManager nm = (NotificationManager) o; + nm.notify(INTRODUCTION_SUCCESS_NOTIFICATION_ID, b.build()); + } + }); + } + } diff --git a/briar-android/src/org/briarproject/android/BaseActivity.java b/briar-android/src/org/briarproject/android/BaseActivity.java index 8e92c0b56f..1a93a006ec 100644 --- a/briar-android/src/org/briarproject/android/BaseActivity.java +++ b/briar-android/src/org/briarproject/android/BaseActivity.java @@ -54,7 +54,7 @@ public abstract class BaseActivity extends AppCompatActivity { ((InputMethodManager) o).showSoftInput(view, SHOW_IMPLICIT); } - protected void hideSoftKeyboard(View view) { + public void hideSoftKeyboard(View view) { IBinder token = view.getWindowToken(); Object o = getSystemService(INPUT_METHOD_SERVICE); ((InputMethodManager) o).hideSoftInputFromWindow(token, 0); diff --git a/briar-android/src/org/briarproject/android/contact/ContactListAdapter.java b/briar-android/src/org/briarproject/android/contact/ContactListAdapter.java index 38c64e839c..becdaa9220 100644 --- a/briar-android/src/org/briarproject/android/contact/ContactListAdapter.java +++ b/briar-android/src/org/briarproject/android/contact/ContactListAdapter.java @@ -1,8 +1,12 @@ package org.briarproject.android.contact; import android.content.Context; -import android.content.Intent; -import android.content.res.Resources; +import android.graphics.Color; +import android.graphics.ColorFilter; +import android.graphics.PorterDuff; +import android.graphics.PorterDuffColorFilter; +import android.os.Build; +import android.support.v4.content.ContextCompat; import android.support.v7.util.SortedList; import android.support.v7.widget.RecyclerView; import android.text.format.DateUtils; @@ -14,9 +18,8 @@ import android.widget.TextView; import org.briarproject.R; import org.briarproject.api.contact.ContactId; -import org.briarproject.api.crypto.CryptoComponent; import org.briarproject.api.identity.Author; -import org.briarproject.api.sync.GroupId; +import org.briarproject.api.identity.AuthorId; import java.util.List; @@ -53,13 +56,23 @@ public class ContactListAdapter @Override public int compare(ContactListItem c1, ContactListItem c2) { - // sort items by time - // and do not take unread messages into account - long time1 = c1.getTimestamp(); - long time2 = c2.getTimestamp(); - if (time1 < time2) return 1; - if (time1 > time2) return -1; - return 0; + int authorCompare = 0; + if (chooser) { + authorCompare = c1.getLocalAuthor().getName() + .compareTo( + c2.getLocalAuthor().getName()); + } + if (authorCompare == 0) { + // sort items by time + // and do not take unread messages into account + long time1 = c1.getTimestamp(); + long time2 = c2.getTimestamp(); + if (time1 < time2) return 1; + if (time1 > time2) return -1; + return 0; + } else { + return authorCompare; + } } @Override @@ -86,10 +99,16 @@ public class ContactListAdapter return true; } }); + private final OnItemClickListener listener; + private final boolean chooser; private Context ctx; + private AuthorId localAuthorId; - public ContactListAdapter(Context context) { + public ContactListAdapter(Context context, OnItemClickListener listener, + boolean chooser) { ctx = context; + this.listener = listener; + this.chooser = chooser; } @Override @@ -103,12 +122,11 @@ public class ContactListAdapter @Override public void onBindViewHolder(final ContactHolder ui, final int position) { final ContactListItem item = getItem(position); - Resources res = ctx.getResources(); int unread = item.getUnreadCount(); - if (unread > 0) { + if (!chooser && unread > 0) { ui.layout.setBackgroundColor( - res.getColor(R.color.unread_background)); + ContextCompat.getColor(ctx, R.color.unread_background)); } if (item.isConnected()) { @@ -121,27 +139,37 @@ public class ContactListAdapter ui.avatar.setImageDrawable( new IdenticonDrawable(author.getId().getBytes())); String contactName = author.getName(); - if (unread > 0) { + + if (!chooser && unread > 0) { + // TODO show these in a bubble on top of the avatar ui.name.setText(contactName + " (" + unread + ")"); } else { ui.name.setText(contactName); } + if (chooser) { + ui.identity.setText(item.getLocalAuthor().getName()); + } else { + ui.identity.setVisibility(View.GONE); + } + if (item.isEmpty()) { ui.date.setText(R.string.no_private_messages); } else { + // TODO show this as X units ago long timestamp = item.getTimestamp(); ui.date.setText( DateUtils.getRelativeTimeSpanString(ctx, timestamp)); } + if (chooser && !item.getLocalAuthor().getId().equals(localAuthorId)) { + grayOutItem(ui); + } + ui.layout.setOnClickListener(new View.OnClickListener() { @Override public void onClick(View v) { - GroupId groupId = item.getGroupId(); - Intent i = new Intent(ctx, ConversationActivity.class); - i.putExtra("briar.GROUP_ID", groupId.getBytes()); - ctx.startActivity(i); + listener.onItemClick(ui.avatar, item); } }); } @@ -151,6 +179,34 @@ public class ContactListAdapter return contacts.size(); } + /** + * Set the identity from whose perspective the contact shall be chosen. + * This is only used if chooser is true. + * @param authorId The ID of the local Author + */ + public void setLocalAuthor(AuthorId authorId) { + localAuthorId = authorId; + notifyDataSetChanged(); + } + + private void grayOutItem(final ContactHolder ui) { + if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.HONEYCOMB) { + float alpha = 0.25f; + ui.bulb.setAlpha(alpha); + ui.avatar.setAlpha(alpha); + ui.name.setAlpha(alpha); + ui.date.setAlpha(alpha); + ui.identity.setAlpha(alpha); + } else { + ColorFilter colorFilter = new PorterDuffColorFilter(Color.GRAY, + PorterDuff.Mode.MULTIPLY); + ui.bulb.setColorFilter(colorFilter); + ui.avatar.setColorFilter(colorFilter); + ui.name.setEnabled(false); + ui.date.setEnabled(false); + } + } + public ContactListItem getItem(int position) { if (position == INVALID_POSITION || contacts.size() <= position) { return null; // Not found @@ -162,10 +218,6 @@ public class ContactListAdapter contacts.updateItemAt(position, item); } - public int findItemPosition(ContactListItem item) { - return contacts.indexOf(item); - } - public int findItemPosition(ContactId c) { int count = getItemCount(); for (int i = 0; i < count; i++) { @@ -202,6 +254,7 @@ public class ContactListAdapter public ImageView bulb; public ImageView avatar; public TextView name; + public TextView identity; public TextView date; public ContactHolder(View v) { @@ -211,7 +264,13 @@ public class ContactListAdapter bulb = (ImageView) v.findViewById(R.id.bulbView); avatar = (ImageView) v.findViewById(R.id.avatarView); name = (TextView) v.findViewById(R.id.nameView); + identity = (TextView) v.findViewById(R.id.identityView); date = (TextView) v.findViewById(R.id.dateView); } } + + public interface OnItemClickListener { + void onItemClick(View view, ContactListItem item); + } + } diff --git a/briar-android/src/org/briarproject/android/contact/ContactListFragment.java b/briar-android/src/org/briarproject/android/contact/ContactListFragment.java index 0d7c5d3235..3cba02fadb 100644 --- a/briar-android/src/org/briarproject/android/contact/ContactListFragment.java +++ b/briar-android/src/org/briarproject/android/contact/ContactListFragment.java @@ -1,9 +1,12 @@ package org.briarproject.android.contact; import android.content.Intent; +import android.os.Build; import android.os.Bundle; import android.support.annotation.Nullable; import android.support.design.widget.FloatingActionButton; +import android.support.v4.app.ActivityOptionsCompat; +import android.support.v7.app.AppCompatActivity; import android.support.v7.widget.LinearLayoutManager; import android.view.LayoutInflater; import android.view.View; @@ -11,23 +14,26 @@ import android.view.ViewGroup; import org.briarproject.R; import org.briarproject.android.AndroidComponent; -import org.briarproject.android.BriarApplication; import org.briarproject.android.fragment.BaseEventFragment; import org.briarproject.android.keyagreement.KeyAgreementActivity; import org.briarproject.android.util.BriarRecyclerView; import org.briarproject.api.contact.Contact; import org.briarproject.api.contact.ContactId; import org.briarproject.api.contact.ContactManager; -import org.briarproject.api.crypto.CryptoComponent; import org.briarproject.api.db.DbException; import org.briarproject.api.db.NoSuchContactException; import org.briarproject.api.event.ContactAddedEvent; import org.briarproject.api.event.ContactConnectedEvent; import org.briarproject.api.event.ContactDisconnectedEvent; import org.briarproject.api.event.ContactRemovedEvent; +import org.briarproject.api.event.ContactStatusChangedEvent; import org.briarproject.api.event.Event; import org.briarproject.api.event.EventBus; import org.briarproject.api.event.MessageValidatedEvent; +import org.briarproject.api.identity.IdentityManager; +import org.briarproject.api.identity.LocalAuthor; +import org.briarproject.api.introduction.IntroductionManager; +import org.briarproject.api.introduction.IntroductionMessage; import org.briarproject.api.messaging.MessagingManager; import org.briarproject.api.messaging.PrivateMessageHeader; import org.briarproject.api.plugins.ConnectionRegistry; @@ -74,8 +80,12 @@ public class ContactListFragment extends BaseEventFragment { @Inject protected volatile ContactManager contactManager; @Inject + protected volatile IdentityManager identityManager; + @Inject protected volatile MessagingManager messagingManager; @Inject + protected volatile IntroductionManager introductionManager; + @Inject protected volatile EventBus eventBus; @Override @@ -91,7 +101,31 @@ public class ContactListFragment extends BaseEventFragment { inflater.inflate(R.layout.activity_contact_list, container, false); - adapter = new ContactListAdapter(getContext()); + ContactListAdapter.OnItemClickListener onItemClickListener = + new ContactListAdapter.OnItemClickListener() { + @Override + public void onItemClick(View view, ContactListItem item) { + + GroupId groupId = item.getGroupId(); + Intent i = new Intent(getActivity(), + ConversationActivity.class); + i.putExtra("briar.GROUP_ID", groupId.getBytes()); + + if (Build.VERSION.SDK_INT >= 16) { + ActivityOptionsCompat options = + ActivityOptionsCompat. + makeSceneTransitionAnimation( + getActivity(), + view, "avatar"); + getActivity().startActivity(i, options.toBundle()); + } else { + startActivity(i); + } + } + }; + + adapter = new ContactListAdapter(getContext(), onItemClickListener, + false); list = (BriarRecyclerView) contentView.findViewById(R.id.contactList); list.setLayoutManager(new LinearLayoutManager(getContext())); list.setAdapter(adapter); @@ -135,12 +169,14 @@ public class ContactListFragment extends BaseEventFragment { ContactId id = c.getId(); GroupId groupId = messagingManager.getConversationId(id); - Collection<PrivateMessageHeader> headers = - messagingManager.getMessageHeaders(id); + Collection<ConversationItem> messages = + getMessages(id); boolean connected = connectionRegistry.isConnected(c.getId()); - contacts.add(new ContactListItem(c, connected, - groupId, headers)); + LocalAuthor localAuthor = identityManager + .getLocalAuthor(c.getLocalAuthorId()); + contacts.add(new ContactListItem(c, localAuthor, + connected, groupId, messages)); } catch (NoSuchContactException e) { // Continue } @@ -169,7 +205,12 @@ public class ContactListFragment extends BaseEventFragment { public void eventOccurred(Event e) { if (e instanceof ContactAddedEvent) { - LOG.info("Contact added, reloading"); + if(((ContactAddedEvent) e).isActive()) { + LOG.info("Contact added as active, reloading"); + loadContacts(); + } + } else if (e instanceof ContactStatusChangedEvent) { + LOG.info("Contact Status changed, reloading"); loadContacts(); } else if (e instanceof ContactConnectedEvent) { setConnected(((ContactConnectedEvent) e).getContactId(), true); @@ -181,7 +222,8 @@ public class ContactListFragment extends BaseEventFragment { } else if (e instanceof MessageValidatedEvent) { MessageValidatedEvent m = (MessageValidatedEvent) e; ClientId c = m.getClientId(); - if (m.isValid() && c.equals(messagingManager.getClientId())) { + if (m.isValid() && (c.equals(messagingManager.getClientId()) || + c.equals(introductionManager.getClientId()))) { LOG.info("Message added, reloading"); reloadConversation(m.getMessage().getGroupId()); } @@ -192,14 +234,10 @@ public class ContactListFragment extends BaseEventFragment { listener.runOnDbThread(new Runnable() { public void run() { try { - long now = System.currentTimeMillis(); ContactId c = messagingManager.getContactId(g); - Collection<PrivateMessageHeader> headers = - messagingManager.getMessageHeaders(c); - long duration = System.currentTimeMillis() - now; - if (LOG.isLoggable(INFO)) - LOG.info("Partial load took " + duration + " ms"); - updateItem(c, headers); + Collection<ConversationItem> messages = + getMessages(c); + updateItem(c, messages); } catch (NoSuchContactException e) { LOG.info("Contact removed"); } catch (DbException e) { @@ -211,13 +249,13 @@ public class ContactListFragment extends BaseEventFragment { } private void updateItem(final ContactId c, - final Collection<PrivateMessageHeader> headers) { + final Collection<ConversationItem> messages) { listener.runOnUiThread(new Runnable() { public void run() { int position = adapter.findItemPosition(c); ContactListItem item = adapter.getItem(position); if (item != null) { - item.setHeaders(headers); + item.setMessages(messages); adapter.updateItem(position, item); } } @@ -246,4 +284,35 @@ public class ContactListFragment extends BaseEventFragment { } }); } + + /** This needs to be called from the DbThread */ + private Collection<ConversationItem> getMessages(ContactId id) + throws DbException { + + long now = System.currentTimeMillis(); + + Collection<ConversationItem> messages = + new ArrayList<ConversationItem>(); + + Collection<PrivateMessageHeader> headers = + messagingManager.getMessageHeaders(id); + for (PrivateMessageHeader h : headers) { + messages.add(new ConversationMessageItem(h)); + } + long duration = System.currentTimeMillis() - now; + if (LOG.isLoggable(INFO)) + LOG.info("Loading message headers took " + duration + " ms"); + + Collection<IntroductionMessage> introductions = + introductionManager + .getIntroductionMessages(id); + for (IntroductionMessage m : introductions) { + messages.add(ConversationItem.from(m)); + } + duration = System.currentTimeMillis() - now; + if (LOG.isLoggable(INFO)) + LOG.info("Loading introduction messages took " + duration + " ms"); + + return messages; + } } diff --git a/briar-android/src/org/briarproject/android/contact/ContactListItem.java b/briar-android/src/org/briarproject/android/contact/ContactListItem.java index 2addb9e9d1..c152d20c8b 100644 --- a/briar-android/src/org/briarproject/android/contact/ContactListItem.java +++ b/briar-android/src/org/briarproject/android/contact/ContactListItem.java @@ -1,44 +1,55 @@ package org.briarproject.android.contact; import org.briarproject.api.contact.Contact; -import org.briarproject.api.messaging.PrivateMessageHeader; +import org.briarproject.api.identity.LocalAuthor; import org.briarproject.api.sync.GroupId; import java.util.Collection; +import static org.briarproject.android.contact.ConversationItem.IncomingItem; + // This class is not thread-safe -class ContactListItem { +public class ContactListItem { private final Contact contact; + private final LocalAuthor localAuthor; private final GroupId groupId; private boolean connected, empty; private long timestamp; private int unread; - ContactListItem(Contact contact, boolean connected, GroupId groupId, - Collection<PrivateMessageHeader> headers) { + public ContactListItem(Contact contact, LocalAuthor localAuthor, + boolean connected, + GroupId groupId, + Collection<ConversationItem> messages) { this.contact = contact; + this.localAuthor = localAuthor; this.groupId = groupId; this.connected = connected; - setHeaders(headers); + setMessages(messages); } - void setHeaders(Collection<PrivateMessageHeader> headers) { - empty = headers.isEmpty(); + void setMessages(Collection<ConversationItem> messages) { + empty = messages.isEmpty(); timestamp = 0; unread = 0; if (!empty) { - for (PrivateMessageHeader h : headers) { - if (h.getTimestamp() > timestamp) timestamp = h.getTimestamp(); - if (!h.isRead()) unread++; + for (ConversationItem i : messages) { + if (i.getTime() > timestamp) timestamp = i.getTime(); + if (i instanceof IncomingItem && !((IncomingItem) i).isRead()) + unread++; } } } - Contact getContact() { + public Contact getContact() { return contact; } + public LocalAuthor getLocalAuthor() { + return localAuthor; + } + GroupId getGroupId() { return groupId; } diff --git a/briar-android/src/org/briarproject/android/contact/ConversationActivity.java b/briar-android/src/org/briarproject/android/contact/ConversationActivity.java index 45ebe6eab9..747c08caaf 100644 --- a/briar-android/src/org/briarproject/android/contact/ConversationActivity.java +++ b/briar-android/src/org/briarproject/android/contact/ConversationActivity.java @@ -2,11 +2,15 @@ package org.briarproject.android.contact; import android.content.DialogInterface; import android.content.Intent; -import android.graphics.PorterDuff; import android.os.Bundle; +import android.support.v4.app.ActivityCompat; +import android.support.v4.app.ActivityOptionsCompat; +import android.support.v4.content.ContextCompat; import android.support.v7.app.ActionBar; import android.support.v7.app.AlertDialog; import android.support.v7.widget.LinearLayoutManager; +import android.support.v7.widget.Toolbar; +import android.util.SparseArray; import android.view.Menu; import android.view.MenuInflater; import android.view.MenuItem; @@ -14,14 +18,17 @@ import android.view.View; import android.view.View.OnClickListener; import android.widget.EditText; import android.widget.ImageButton; +import android.widget.ImageView; +import android.widget.TextView; import android.widget.Toast; import org.briarproject.R; import org.briarproject.android.AndroidComponent; import org.briarproject.android.BriarActivity; +import org.briarproject.android.api.AndroidNotificationManager; +import org.briarproject.android.introduction.IntroductionActivity; import org.briarproject.android.util.BriarRecyclerView; import org.briarproject.api.FormatException; -import org.briarproject.android.api.AndroidNotificationManager; import org.briarproject.api.contact.Contact; import org.briarproject.api.contact.ContactId; import org.briarproject.api.contact.ContactManager; @@ -35,9 +42,16 @@ import org.briarproject.api.event.ContactRemovedEvent; import org.briarproject.api.event.Event; import org.briarproject.api.event.EventBus; import org.briarproject.api.event.EventListener; +import org.briarproject.api.event.IntroductionRequestReceivedEvent; +import org.briarproject.api.event.IntroductionResponseReceivedEvent; import org.briarproject.api.event.MessageValidatedEvent; import org.briarproject.api.event.MessagesAckedEvent; import org.briarproject.api.event.MessagesSentEvent; +import org.briarproject.api.introduction.IntroductionManager; +import org.briarproject.api.introduction.IntroductionMessage; +import org.briarproject.api.introduction.IntroductionRequest; +import org.briarproject.api.introduction.IntroductionResponse; +import org.briarproject.api.introduction.SessionId; import org.briarproject.api.messaging.MessagingManager; import org.briarproject.api.messaging.PrivateMessage; import org.briarproject.api.messaging.PrivateMessageFactory; @@ -61,21 +75,31 @@ import java.util.logging.Logger; import javax.inject.Inject; +import de.hdodenhof.circleimageview.CircleImageView; +import im.delight.android.identicons.IdenticonDrawable; + import static android.widget.Toast.LENGTH_SHORT; import static java.util.logging.Level.INFO; import static java.util.logging.Level.WARNING; +import static org.briarproject.android.contact.ConversationItem.OutgoingItem; +import static org.briarproject.android.contact.ConversationItem.IncomingItem; public class ConversationActivity extends BriarActivity - implements EventListener, OnClickListener { + implements EventListener, OnClickListener, + ConversationAdapter.IntroductionHandler { private static final Logger LOG = Logger.getLogger(ConversationActivity.class.getName()); + private static final int INTRODUCTION_REQUEST_CODE = 0; @Inject protected AndroidNotificationManager notificationManager; @Inject protected ConnectionRegistry connectionRegistry; @Inject @CryptoExecutor protected Executor cryptoExecutor; private Map<MessageId, byte[]> bodyCache = new HashMap<MessageId, byte[]>(); private ConversationAdapter adapter = null; + private CircleImageView toolbarAvatar; + private ImageView toolbarStatus; + private TextView toolbarTitle; private BriarRecyclerView list = null; private EditText content = null; private ImageButton sendButton = null; @@ -85,6 +109,7 @@ public class ConversationActivity extends BriarActivity @Inject protected volatile MessagingManager messagingManager; @Inject protected volatile EventBus eventBus; @Inject protected volatile PrivateMessageFactory privateMessageFactory; + @Inject protected volatile IntroductionManager introductionManager; private volatile GroupId groupId = null; private volatile ContactId contactId = null; private volatile String contactName = null; @@ -102,7 +127,21 @@ public class ConversationActivity extends BriarActivity setContentView(R.layout.activity_conversation); - adapter = new ConversationAdapter(this); + // Custom Toolbar + final Toolbar tb = (Toolbar) findViewById(R.id.toolbar); + toolbarAvatar = (CircleImageView) tb.findViewById(R.id.contactAvatar); + toolbarStatus = (ImageView) tb.findViewById(R.id.contactStatus); + toolbarTitle = (TextView) tb.findViewById(R.id.contactName); + setSupportActionBar(tb); + final ActionBar ab = getSupportActionBar(); + if (ab != null) { + ab.setDisplayShowHomeEnabled(true); + ab.setDisplayHomeAsUpEnabled(true); + ab.setDisplayShowCustomEnabled(true); + ab.setDisplayShowTitleEnabled(false); + } + + adapter = new ConversationAdapter(this, this); list = (BriarRecyclerView) findViewById(R.id.conversationView); list.setLayoutManager(new LinearLayoutManager(this)); list.setAdapter(adapter); @@ -125,8 +164,7 @@ public class ConversationActivity extends BriarActivity eventBus.addListener(this); notificationManager.blockNotification(groupId); notificationManager.clearPrivateMessageNotification(groupId); - loadContactDetails(); - loadHeaders(); + loadData(); } @Override @@ -141,12 +179,10 @@ public class ConversationActivity extends BriarActivity public boolean onCreateOptionsMenu(Menu menu) { // Inflate the menu items for use in the action bar MenuInflater inflater = getMenuInflater(); - inflater.inflate(R.menu.contact_actions, menu); + inflater.inflate(R.menu.conversation_actions, menu); - // Adapt icon color to dark action bar - menu.findItem(R.id.action_social_remove_person).getIcon().setColorFilter( - getResources().getColor(R.color.action_bar_text), - PorterDuff.Mode.SRC_IN); + hideIntroductionActionWhenOneContact( + menu.findItem(R.id.action_introduction)); return super.onCreateOptionsMenu(menu); } @@ -155,6 +191,20 @@ public class ConversationActivity extends BriarActivity public boolean onOptionsItemSelected(final MenuItem item) { // Handle presses on the action bar items switch (item.getItemId()) { + case android.R.id.home: + supportFinishAfterTransition(); + return true; + case R.id.action_introduction: + if (contactId == null) return false; + Intent intent = new Intent(this, IntroductionActivity.class); + intent.putExtra(IntroductionActivity.CONTACT_ID, + contactId.getInt()); + ActivityOptionsCompat options = ActivityOptionsCompat + .makeCustomAnimation(this, android.R.anim.slide_in_left, + android.R.anim.slide_out_right); + ActivityCompat.startActivityForResult(this, intent, + INTRODUCTION_REQUEST_CODE, options.toBundle()); + return true; case R.id.action_social_remove_person: askToRemoveContact(); return true; @@ -163,20 +213,37 @@ public class ConversationActivity extends BriarActivity } } - private void loadContactDetails() { + @Override + protected void onActivityResult(int requestCode, int resultCode, + Intent data) { + + if (requestCode == INTRODUCTION_REQUEST_CODE) { + if (resultCode == RESULT_OK) { + loadData(); + } + } + } + + private void loadData() { runOnDbThread(new Runnable() { public void run() { try { long now = System.currentTimeMillis(); - contactId = messagingManager.getContactId(groupId); - Contact contact = contactManager.getContact(contactId); - contactName = contact.getAuthor().getName(); - contactIdenticonKey = contact.getAuthor().getId().getBytes(); + if (contactId == null) + contactId = messagingManager.getContactId(groupId); + if (contactName == null || contactIdenticonKey == null) { + Contact contact = contactManager.getContact(contactId); + contactName = contact.getAuthor().getName(); + contactIdenticonKey = + contact.getAuthor().getId().getBytes(); + } connected = connectionRegistry.isConnected(contactId); long duration = System.currentTimeMillis() - now; if (LOG.isLoggable(INFO)) LOG.info("Loading contact took " + duration + " ms"); displayContactDetails(); + // Load the messages here to make sure we have a contactId + loadMessages(); } catch (NoSuchContactException e) { finishOnUiThread(); } catch (DbException e) { @@ -190,31 +257,42 @@ public class ConversationActivity extends BriarActivity private void displayContactDetails() { runOnUiThread(new Runnable() { public void run() { - ActionBar actionBar = getSupportActionBar(); - if (actionBar != null) { - actionBar.setTitle(contactName); - if (connected) { - actionBar.setSubtitle(getString(R.string.online)); - } else { - actionBar.setSubtitle(getString(R.string.offline)); - } + toolbarAvatar.setImageDrawable( + new IdenticonDrawable(contactIdenticonKey)); + toolbarTitle.setText(contactName); + + if (connected) { + toolbarStatus.setImageDrawable(ContextCompat + .getDrawable(ConversationActivity.this, + R.drawable.contact_online)); + toolbarStatus + .setContentDescription(getString(R.string.online)); + } else { + toolbarStatus.setImageDrawable(ContextCompat + .getDrawable(ConversationActivity.this, + R.drawable.contact_offline)); + toolbarStatus + .setContentDescription(getString(R.string.offline)); } - adapter.setIdenticonKey(contactIdenticonKey); + adapter.setIdenticonKey(contactIdenticonKey, contactName); } }); } - private void loadHeaders() { + private void loadMessages() { runOnDbThread(new Runnable() { public void run() { try { long now = System.currentTimeMillis(); Collection<PrivateMessageHeader> headers = messagingManager.getMessageHeaders(contactId); + Collection<IntroductionMessage> introductions = + introductionManager + .getIntroductionMessages(contactId); long duration = System.currentTimeMillis() - now; if (LOG.isLoggable(INFO)) LOG.info("Loading headers took " + duration + " ms"); - displayHeaders(headers); + displayMessages(headers, introductions); } catch (NoSuchContactException e) { finishOnUiThread(); } catch (DbException e) { @@ -225,23 +303,37 @@ public class ConversationActivity extends BriarActivity }); } - private void displayHeaders( - final Collection<PrivateMessageHeader> headers) { + private void displayMessages(final Collection<PrivateMessageHeader> headers, + final Collection<IntroductionMessage> introductions) { runOnUiThread(new Runnable() { public void run() { sendButton.setEnabled(true); - if (headers.isEmpty()) { + if (headers.isEmpty() && introductions.isEmpty()) { // we have no messages, // so let the list know to hide progress bar list.showData(); } else { for (PrivateMessageHeader h : headers) { - ConversationItem item = new ConversationItem(h); + ConversationMessageItem item = + new ConversationMessageItem(h); byte[] body = bodyCache.get(h.getId()); if (body == null) loadMessageBody(h); else item.setBody(body); adapter.add(item); } + for (IntroductionMessage m : introductions) { + ConversationItem item; + if (m instanceof IntroductionRequest) { + item = ConversationItem + .from((IntroductionRequest) m); + } else { + item = ConversationItem + .from(ConversationActivity.this, + contactName, + (IntroductionResponse) m); + } + adapter.add(item); + } // Scroll to the bottom list.scrollToPosition(adapter.getItemCount() - 1); } @@ -273,27 +365,42 @@ public class ConversationActivity extends BriarActivity runOnUiThread(new Runnable() { public void run() { bodyCache.put(m, body); - int count = adapter.getItemCount(); - for (int i = 0; i < count; i++) { - ConversationItem item = adapter.getItem(i); - if (item.getHeader().getId().equals(m)) { + SparseArray<ConversationMessageItem> messages = + adapter.getPrivateMessages(); + for (int i = 0; i < messages.size(); i++) { + ConversationMessageItem item = messages.valueAt(i); + if (item.getId().equals(m)) { item.setBody(body); - adapter.notifyItemChanged(i); - // Scroll to the bottom - list.scrollToPosition(count - 1); + adapter.notifyItemChanged(messages.keyAt(i)); return; } } + // Scroll to the bottom + list.scrollToPosition(adapter.getItemCount() - 1); + } + }); + } + + private void addIntroduction(final ConversationItem item) { + runOnUiThread(new Runnable() { + @Override + public void run() { + if (adapter != null) { + adapter.add(item); + // Scroll to the bottom + list.scrollToPosition(adapter.getItemCount() - 1); + } } }); } private void markMessagesRead() { List<MessageId> unread = new ArrayList<MessageId>(); - int count = adapter.getItemCount(); - for (int i = 0; i < count; i++) { - PrivateMessageHeader h = adapter.getItem(i).getHeader(); - if (!h.isRead()) unread.add(h.getId()); + SparseArray<IncomingItem> list = + adapter.getIncomingMessages(); + for (int i = 0; i < list.size(); i++) { + IncomingItem item = list.valueAt(i); + if (!item.isRead()) unread.add(item.getId()); } if (unread.isEmpty()) return; if (LOG.isLoggable(INFO)) @@ -307,6 +414,8 @@ public class ConversationActivity extends BriarActivity try { long now = System.currentTimeMillis(); for (MessageId m : unread) + // not really clean, but the messaging manager can + // handle introduction messages as well messagingManager.setReadFlag(m, true); long duration = System.currentTimeMillis() - now; if (LOG.isLoggable(INFO)) @@ -331,7 +440,7 @@ public class ConversationActivity extends BriarActivity if (m.isValid() && m.getMessage().getGroupId().equals(groupId)) { LOG.info("Message added, reloading"); // Mark new incoming messages as read directly - if (m.isLocal()) loadHeaders(); + if (m.isLocal()) loadMessages(); else markMessageReadIfNew(m.getMessage()); } } else if (e instanceof MessagesSentEvent) { @@ -360,6 +469,23 @@ public class ConversationActivity extends BriarActivity connected = false; displayContactDetails(); } + } else if (e instanceof IntroductionRequestReceivedEvent) { + IntroductionRequestReceivedEvent event = + (IntroductionRequestReceivedEvent) e; + if (event.getContactId().equals(contactId)) { + IntroductionRequest ir = event.getIntroductionRequest(); + ConversationItem item = new ConversationIntroductionInItem(ir); + addIntroduction(item); + } + } else if (e instanceof IntroductionResponseReceivedEvent) { + IntroductionResponseReceivedEvent event = + (IntroductionResponseReceivedEvent) e; + if (event.getContactId().equals(contactId)) { + IntroductionResponse ir = event.getIntroductionResponse(); + ConversationItem item = + ConversationItem.from(this, contactName, ir); + addIntroduction(item); + } } } @@ -369,10 +495,13 @@ public class ConversationActivity extends BriarActivity ConversationItem item = adapter.getLastItem(); if (item != null) { // Mark the message read if it's the newest message - long lastMsgTime = item.getHeader().getTimestamp(); + long lastMsgTime = item.getTime(); long newMsgTime = m.getTimestamp(); if (newMsgTime > lastMsgTime) markNewMessageRead(m); - else loadHeaders(); + else loadMessages(); + } else { + // mark the message as read as well if it is the first one + markNewMessageRead(m); } } }); @@ -383,7 +512,7 @@ public class ConversationActivity extends BriarActivity public void run() { try { messagingManager.setReadFlag(m.getId(), true); - loadHeaders(); + loadMessages(); } catch (DbException e) { if (LOG.isLoggable(WARNING)) LOG.log(WARNING, e.toString(), e); @@ -397,13 +526,14 @@ public class ConversationActivity extends BriarActivity runOnUiThread(new Runnable() { public void run() { Set<MessageId> messages = new HashSet<MessageId>(messageIds); - int count = adapter.getItemCount(); - for (int i = 0; i < count; i++) { - ConversationItem item = adapter.getItem(i); - if (messages.contains(item.getHeader().getId())) { + SparseArray<OutgoingItem> list = + adapter.getOutgoingMessages(); + for (int i = 0; i < list.size(); i++) { + OutgoingItem item = list.valueAt(i); + if (messages.contains(item.getId())) { item.setSent(sent); item.setSeen(seen); - adapter.notifyItemChanged(i); + adapter.notifyItemChanged(list.keyAt(i)); } } } @@ -424,7 +554,7 @@ public class ConversationActivity extends BriarActivity private long getMinTimestampForNewMessage() { // Don't use an earlier timestamp than the newest message ConversationItem item = adapter.getLastItem(); - return item == null ? 0 : item.getHeader().getTimestamp() + 1; + return item == null ? 0 : item.getTime() + 1; } private void createMessage(final byte[] body, final long timestamp) { @@ -466,7 +596,8 @@ public class ConversationActivity extends BriarActivity } }; AlertDialog.Builder builder = - new AlertDialog.Builder(ConversationActivity.this); + new AlertDialog.Builder(ConversationActivity.this, + R.style.BriarDialogTheme); builder.setTitle(getString(R.string.dialog_title_delete_contact)); builder.setMessage(getString(R.string.dialog_message_delete_contact)); builder.setPositiveButton(android.R.string.ok, okListener); @@ -500,4 +631,66 @@ public class ConversationActivity extends BriarActivity } }); } + + private void hideIntroductionActionWhenOneContact(final MenuItem item) { + runOnDbThread(new Runnable() { + public void run() { + try { + if (contactManager.getActiveContacts().size() < 2) { + hideIntroductionAction(item); + } + } catch (DbException e) { + if (LOG.isLoggable(WARNING)) + LOG.log(WARNING, e.toString(), e); + } + } + }); + } + + private void hideIntroductionAction(final MenuItem item) { + runOnUiThread(new Runnable() { + @Override + public void run() { + item.setVisible(false); + } + }); + } + + @Override + public void respondToIntroduction(final SessionId sessionId, final boolean accept) { + runOnDbThread(new Runnable() { + @Override + public void run() { + try { + if (accept) { + introductionManager.acceptIntroduction(sessionId); + } else { + introductionManager.declineIntroduction(sessionId); + } + loadMessages(); + } catch (DbException e) { + introductionResponseError(); + if (LOG.isLoggable(WARNING)) + LOG.log(WARNING, e.toString(), e); + } catch (FormatException e) { + introductionResponseError(); + if (LOG.isLoggable(WARNING)) + LOG.log(WARNING, e.toString(), e); + } + + } + }); + } + + private void introductionResponseError() { + runOnUiThread(new Runnable() { + @Override + public void run() { + Toast.makeText(ConversationActivity.this, + R.string.introduction_response_error, + Toast.LENGTH_SHORT).show(); + } + }); + } + } diff --git a/briar-android/src/org/briarproject/android/contact/ConversationAdapter.java b/briar-android/src/org/briarproject/android/contact/ConversationAdapter.java index 7cb7227325..83cb88cb64 100644 --- a/briar-android/src/org/briarproject/android/contact/ConversationAdapter.java +++ b/briar-android/src/org/briarproject/android/contact/ConversationAdapter.java @@ -4,29 +4,37 @@ import android.content.Context; import android.support.v7.util.SortedList; import android.support.v7.widget.RecyclerView; import android.text.format.DateUtils; +import android.util.SparseArray; import android.view.LayoutInflater; import android.view.View; import android.view.ViewGroup; +import android.widget.Button; import android.widget.ImageView; import android.widget.TextView; import org.briarproject.R; -import org.briarproject.api.crypto.CryptoComponent; +import org.briarproject.api.introduction.IntroductionRequest; +import org.briarproject.api.introduction.SessionId; import org.briarproject.api.messaging.PrivateMessageHeader; import org.briarproject.util.StringUtils; import im.delight.android.identicons.IdenticonDrawable; import static android.support.v7.util.SortedList.INVALID_POSITION; - -class ConversationAdapter extends - RecyclerView.Adapter<ConversationAdapter.MessageHolder> { - - private static final int MSG_OUT = 0; - private static final int MSG_IN = 1; - private static final int MSG_IN_UNREAD = 2; - - private final SortedList<ConversationItem> messages = +import static android.support.v7.widget.RecyclerView.ViewHolder; +import static org.briarproject.android.contact.ConversationItem.INTRODUCTION_IN; +import static org.briarproject.android.contact.ConversationItem.INTRODUCTION_OUT; +import static org.briarproject.android.contact.ConversationItem.MSG_IN; +import static org.briarproject.android.contact.ConversationItem.MSG_IN_UNREAD; +import static org.briarproject.android.contact.ConversationItem.MSG_OUT; +import static org.briarproject.android.contact.ConversationItem.NOTICE_IN; +import static org.briarproject.android.contact.ConversationItem.NOTICE_OUT; +import static org.briarproject.android.contact.ConversationItem.OutgoingItem; +import static org.briarproject.android.contact.ConversationItem.IncomingItem; + +class ConversationAdapter extends RecyclerView.Adapter { + + private final SortedList<ConversationItem> items = new SortedList<ConversationItem>(ConversationItem.class, new SortedList.Callback<ConversationItem>() { @Override @@ -52,8 +60,8 @@ class ConversationAdapter extends @Override public int compare(ConversationItem c1, ConversationItem c2) { - long time1 = c1.getHeader().getTimestamp(); - long time2 = c2.getHeader().getTimestamp(); + long time1 = c1.getTime(); + long time2 = c2.getTime(); if (time1 < time2) return -1; if (time1 > time2) return 1; return 0; @@ -62,8 +70,7 @@ class ConversationAdapter extends @Override public boolean areItemsTheSame(ConversationItem c1, ConversationItem c2) { - return c1.getHeader().getId() - .equals(c2.getHeader().getId()); + return c1.getId().equals(c2.getId()); } @Override @@ -73,67 +80,113 @@ class ConversationAdapter extends } }); private Context ctx; + private IntroductionHandler intro; private byte[] identiconKey; + private String contactName; - public ConversationAdapter(Context context) { + public ConversationAdapter(Context context, + IntroductionHandler introductionHandler) { ctx = context; + intro = introductionHandler; + setHasStableIds(true); } - public void setIdenticonKey(byte[] key) { + public void setIdenticonKey(byte[] key, String contactName) { this.identiconKey = key; + this.contactName = contactName; + // FIXME this breaks the progress animation because it is called early before data is loaded notifyDataSetChanged(); } + @Override + public long getItemId(int position) { + return getItem(position).getId().hashCode(); + } + @Override public int getItemViewType(int position) { - // return different type for incoming and outgoing (local) messages - PrivateMessageHeader header = getItem(position).getHeader(); - if (header.isLocal()) { - return MSG_OUT; - } else if (header.isRead()) { - return MSG_IN; - } else { - return MSG_IN_UNREAD; - } + return getItem(position).getType(); } @Override - public MessageHolder onCreateViewHolder(ViewGroup viewGroup, int type) { + public ViewHolder 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); + return new MessageHolder(v, type); + } + else if (type == INTRODUCTION_IN) { + v = LayoutInflater.from(viewGroup.getContext()) + .inflate(R.layout.list_item_introduction_in, viewGroup, false); + return new IntroductionHolder(v, type); + } + else if (type == INTRODUCTION_OUT) { + v = LayoutInflater.from(viewGroup.getContext()) + .inflate(R.layout.list_item_introduction_out, viewGroup, false); + return new IntroductionHolder(v, type); + } + else if (type == NOTICE_IN) { + v = LayoutInflater.from(viewGroup.getContext()) + .inflate(R.layout.list_item_notice_in, viewGroup, false); + return new NoticeHolder(v, type); + } + else if (type == NOTICE_OUT) { + v = LayoutInflater.from(viewGroup.getContext()) + .inflate(R.layout.list_item_notice_out, viewGroup, false); + return new NoticeHolder(v, type); } // incoming message (non-local) else { v = LayoutInflater.from(viewGroup.getContext()) .inflate(R.layout.list_item_msg_in, viewGroup, false); + return new MessageHolder(v, type); } - - return new MessageHolder(v, type); } @Override - public void onBindViewHolder(final MessageHolder ui, final int position) { + public void onBindViewHolder(final ViewHolder ui, final int position) { ConversationItem item = getItem(position); + if (item instanceof ConversationMessageItem) { + bindMessage((MessageHolder) ui, (ConversationMessageItem) item, + position); + } else if (item instanceof ConversationIntroductionOutItem) { + bindIntroduction((IntroductionHolder) ui, + (ConversationIntroductionOutItem) item, position); + } else if (item instanceof ConversationIntroductionInItem) { + bindIntroduction((IntroductionHolder) ui, + (ConversationIntroductionInItem) item, position); + } else if (item instanceof ConversationNoticeOutItem) { + bindNotice((NoticeHolder) ui, (ConversationNoticeOutItem) item, + position); + } else if (item instanceof ConversationNoticeInItem) { + bindNotice((NoticeHolder) ui, (ConversationNoticeInItem) item, + position); + } else { + throw new IllegalArgumentException("Unhandled Conversation Item"); + } + } + + private void bindMessage(final MessageHolder ui, + ConversationMessageItem item, final int position) { PrivateMessageHeader header = item.getHeader(); - if (header.isLocal()) { + if (item.getType() == MSG_OUT) { if (item.isSeen()) { - ui.status.setImageResource(R.drawable.message_delivered); + ui.status.setImageResource(R.drawable.message_delivered_white); } else if (item.isSent()) { - ui.status.setImageResource(R.drawable.message_sent); + ui.status.setImageResource(R.drawable.message_sent_white); } else { - ui.status.setImageResource(R.drawable.message_stored); + ui.status.setImageResource(R.drawable.message_stored_white); } } else { if (identiconKey != null) - ui.avatar.setImageDrawable( - new IdenticonDrawable(identiconKey)); - if (!header.isRead()) { - int left = ui.layout.getPaddingLeft(); + ui.avatar.setImageDrawable(new IdenticonDrawable(identiconKey)); + if (item.getType() == MSG_IN_UNREAD) { + // TODO implement new unread message highlight according to #232 +/* int left = ui.layout.getPaddingLeft(); int top = ui.layout.getPaddingTop(); int right = ui.layout.getPaddingRight(); int bottom = ui.layout.getPaddingBottom(); @@ -144,6 +197,7 @@ class ConversationAdapter extends // 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); +*/ } } @@ -159,42 +213,178 @@ class ConversationAdapter extends ui.date.setText(DateUtils.getRelativeTimeSpanString(ctx, timestamp)); } + private void bindIntroduction(final IntroductionHolder ui, + final ConversationIntroductionInItem item, final int position) { + + final IntroductionRequest ir = item.getIntroductionRequest(); + + final String message = ir.getMessage(); + if (StringUtils.isNullOrEmpty(message)) { + ui.messageLayout.setVisibility(View.GONE); + } else { + ui.messageLayout.setVisibility(View.VISIBLE); + if (item.getType() == INTRODUCTION_IN && identiconKey != null) { + ui.message.avatar.setImageDrawable( + new IdenticonDrawable(identiconKey)); + } + ui.message.body.setText(message); + ui.message.date.setText( + DateUtils.getRelativeTimeSpanString(ctx, item.getTime())); + } + + // Outgoing Introduction Request + if (item instanceof ConversationIntroductionOutItem) { + ui.text.setText(ctx.getString(R.string.introduction_request_sent, + contactName, ir.getName())); + ConversationIntroductionOutItem i = + (ConversationIntroductionOutItem) item; + if (i.isSeen()) { + ui.status.setImageResource(R.drawable.message_delivered); + ui.message.status.setImageResource(R.drawable.message_delivered_white); + } else if (i.isSent()) { + ui.status.setImageResource(R.drawable.message_sent); + ui.message.status.setImageResource(R.drawable.message_sent_white); + } else { + ui.status.setImageResource(R.drawable.message_stored); + ui.message.status.setImageResource(R.drawable.message_stored_white); + } + } + // Incoming Introduction Request (Answered) + else if (item.wasAnswered()) { + ui.text.setText(ctx.getString( + R.string.introduction_request_answered_received, + contactName, ir.getName())); + ui.acceptButton.setVisibility(View.GONE); + ui.declineButton.setVisibility(View.GONE); + } + // Incoming Introduction Request (Not Answered) + else { + if (item.getIntroductionRequest().doesExist()) { + ui.text.setText(ctx.getString( + R.string.introduction_request_exists_received, + contactName, ir.getName())); + } else { + ui.text.setText( + ctx.getString(R.string.introduction_request_received, + contactName, ir.getName())); + } + + ui.acceptButton.setVisibility(View.VISIBLE); + ui.acceptButton.setOnClickListener(new View.OnClickListener() { + @Override + public void onClick(View v) { + intro.respondToIntroduction(ir.getSessionId(), true); + item.setAnswered(true); + notifyItemChanged(position); + } + }); + ui.declineButton.setVisibility(View.VISIBLE); + ui.declineButton.setOnClickListener(new View.OnClickListener() { + @Override + public void onClick(View v) { + intro.respondToIntroduction(ir.getSessionId(), false); + item.setAnswered(true); + notifyItemChanged(position); + } + }); + } + ui.date.setText( + DateUtils.getRelativeTimeSpanString(ctx, item.getTime())); + } + + private void bindNotice(final NoticeHolder ui, + final ConversationNoticeItem item, final int position) { + + ui.text.setText(item.getText()); + ui.date.setText( + DateUtils.getRelativeTimeSpanString(ctx, item.getTime())); + + if (item instanceof ConversationNoticeOutItem) { + ConversationNoticeOutItem n = (ConversationNoticeOutItem) item; + if (n.isSeen()) { + ui.status.setImageResource(R.drawable.message_delivered); + } else if (n.isSent()) { + ui.status.setImageResource(R.drawable.message_sent); + } else { + ui.status.setImageResource(R.drawable.message_stored); + } + } + } + @Override public int getItemCount() { - return messages.size(); + return items.size(); } public ConversationItem getItem(int position) { - if (position == INVALID_POSITION || messages.size() <= position) { + if (position == INVALID_POSITION || items.size() <= position) { return null; // Not found } - return messages.get(position); + return items.get(position); } public ConversationItem getLastItem() { - if (messages.size() > 0) { - return messages.get(messages.size() - 1); + if (items.size() > 0) { + return items.get(items.size() - 1); } else { return null; } } + public SparseArray<IncomingItem> getIncomingMessages() { + SparseArray<IncomingItem> messages = + new SparseArray<IncomingItem>(); + + for (int i = 0; i < items.size(); i++) { + ConversationItem item = items.get(i); + if (item instanceof IncomingItem) { + messages.put(i, (IncomingItem) item); + } + } + return messages; + } + + public SparseArray<OutgoingItem> getOutgoingMessages() { + SparseArray<OutgoingItem> messages = + new SparseArray<OutgoingItem>(); + + for (int i = 0; i < items.size(); i++) { + ConversationItem item = items.get(i); + if (item instanceof OutgoingItem) { + messages.put(i, (OutgoingItem) item); + } + } + return messages; + } + + public SparseArray<ConversationMessageItem> getPrivateMessages() { + SparseArray<ConversationMessageItem> messages = + new SparseArray<ConversationMessageItem>(); + + for (int i = 0; i < items.size(); i++) { + ConversationItem item = items.get(i); + if (item instanceof ConversationMessageItem) { + messages.put(i, (ConversationMessageItem) item); + } + } + return messages; + } + public void add(final ConversationItem message) { - this.messages.add(message); + this.items.add(message); } public void clear() { - this.messages.beginBatchedUpdates(); + this.items.beginBatchedUpdates(); - while(messages.size() != 0) { - messages.removeItemAt(0); + while(items.size() != 0) { + items.removeItemAt(0); } - this.messages.endBatchedUpdates(); + this.items.endBatchedUpdates(); } - // TODO: Does this class need to be public? - public static class MessageHolder extends RecyclerView.ViewHolder { + protected class MessageHolder extends RecyclerView.ViewHolder { public ViewGroup layout; public TextView body; @@ -217,4 +407,59 @@ class ConversationAdapter extends } } } -} \ No newline at end of file + + protected class IntroductionHolder extends RecyclerView.ViewHolder { + + public ViewGroup layout; + public View messageLayout; + public MessageHolder message; + public TextView text; + public Button acceptButton; + public Button declineButton; + public TextView date; + public ImageView status; + + public IntroductionHolder(View v, int type) { + super(v); + + layout = (ViewGroup) v.findViewById(R.id.introductionLayout); + messageLayout = v.findViewById(R.id.messageLayout); + message = new MessageHolder(messageLayout, + type == INTRODUCTION_IN ? MSG_IN : MSG_OUT); + text = (TextView) v.findViewById(R.id.introductionText); + acceptButton = (Button) v.findViewById(R.id.acceptButton); + declineButton = (Button) v.findViewById(R.id.declineButton); + date = (TextView) v.findViewById(R.id.introductionTime); + + if (type == INTRODUCTION_OUT) { + status = (ImageView) v.findViewById(R.id.introductionStatus); + } + } + } + + protected class NoticeHolder extends RecyclerView.ViewHolder { + + public ViewGroup layout; + public TextView text; + public TextView date; + public ImageView status; + + public NoticeHolder(View v, int type) { + super(v); + + layout = (ViewGroup) v.findViewById(R.id.noticeLayout); + text = (TextView) v.findViewById(R.id.noticeText); + date = (TextView) v.findViewById(R.id.noticeTime); + + if (type == NOTICE_OUT) { + status = (ImageView) v.findViewById(R.id.noticeStatus); + } + } + } + + public interface IntroductionHandler { + void respondToIntroduction(final SessionId sessionId, + final boolean accept); + } + +} diff --git a/briar-android/src/org/briarproject/android/contact/ConversationIntroductionInItem.java b/briar-android/src/org/briarproject/android/contact/ConversationIntroductionInItem.java new file mode 100644 index 0000000000..939f808792 --- /dev/null +++ b/briar-android/src/org/briarproject/android/contact/ConversationIntroductionInItem.java @@ -0,0 +1,47 @@ +package org.briarproject.android.contact; + +import org.briarproject.api.introduction.IntroductionRequest; +import org.briarproject.api.sync.MessageId; + +public class ConversationIntroductionInItem extends ConversationItem implements + ConversationItem.IncomingItem { + + private IntroductionRequest ir; + private boolean answered, read; + + public ConversationIntroductionInItem(IntroductionRequest ir) { + super(ir.getMessageId(), ir.getTime()); + + this.ir = ir; + this.answered = ir.wasAnswered(); + this.read = ir.isRead(); + } + + @Override + int getType() { + return INTRODUCTION_IN; + } + + public IntroductionRequest getIntroductionRequest() { + return ir; + } + + public boolean wasAnswered() { + return answered; + } + + public void setAnswered(boolean answered) { + this.answered = answered; + } + + @Override + public boolean isRead() { + return read; + } + + @Override + public void setRead(boolean read) { + this.read = read; + } + +} diff --git a/briar-android/src/org/briarproject/android/contact/ConversationIntroductionOutItem.java b/briar-android/src/org/briarproject/android/contact/ConversationIntroductionOutItem.java new file mode 100644 index 0000000000..37f32a83d9 --- /dev/null +++ b/briar-android/src/org/briarproject/android/contact/ConversationIntroductionOutItem.java @@ -0,0 +1,48 @@ +package org.briarproject.android.contact; + +import org.briarproject.api.introduction.IntroductionRequest; +import org.briarproject.api.sync.MessageId; + +/** + * This class is needed and can not be replaced by an ConversationNoticeOutItem, + * because it carries the optional introduction message + * to be displayed as a regular private message. + */ +public class ConversationIntroductionOutItem + extends ConversationIntroductionInItem + implements ConversationItem.OutgoingItem { + + private boolean sent, seen; + + public ConversationIntroductionOutItem(IntroductionRequest ir) { + super(ir); + this.sent = ir.isSent(); + this.seen = ir.isSeen(); + } + + @Override + int getType() { + return INTRODUCTION_OUT; + } + + @Override + public boolean isSent() { + return sent; + } + + @Override + public void setSent(boolean sent) { + this.sent = sent; + } + + @Override + public boolean isSeen() { + return seen; + } + + @Override + public void setSeen(boolean seen) { + this.seen = seen; + } + +} diff --git a/briar-android/src/org/briarproject/android/contact/ConversationItem.java b/briar-android/src/org/briarproject/android/contact/ConversationItem.java index 7603c5c8f1..ad037996c4 100644 --- a/briar-android/src/org/briarproject/android/contact/ConversationItem.java +++ b/briar-android/src/org/briarproject/android/contact/ConversationItem.java @@ -1,46 +1,105 @@ package org.briarproject.android.contact; -import org.briarproject.api.messaging.PrivateMessageHeader; +import android.content.Context; + +import org.briarproject.R; +import org.briarproject.api.introduction.IntroductionMessage; +import org.briarproject.api.introduction.IntroductionRequest; +import org.briarproject.api.introduction.IntroductionResponse; +import org.briarproject.api.sync.MessageId; // This class is not thread-safe -class ConversationItem { +public abstract class ConversationItem { + + final static int MSG_IN = 0; + final static int MSG_IN_UNREAD = 1; + final static int MSG_OUT = 2; + final static int INTRODUCTION_IN = 3; + final static int INTRODUCTION_OUT = 4; + final static int NOTICE_IN = 5; + final static int NOTICE_OUT = 6; - private final PrivateMessageHeader header; - private byte[] body; - private boolean sent, seen; + private MessageId id; + private long time; - ConversationItem(PrivateMessageHeader header) { - this.header = header; - body = null; - sent = header.isSent(); - seen = header.isSeen(); + public ConversationItem(MessageId id, long time) { + this.id = id; + this.time = time; } - PrivateMessageHeader getHeader() { - return header; + abstract int getType(); + + public MessageId getId() { + return id; } - byte[] getBody() { - return body; + long getTime() { + return time; } - void setBody(byte[] body) { - this.body = body; + public static ConversationItem from(IntroductionRequest ir) { + if (ir.isLocal()) { + return new ConversationIntroductionOutItem(ir); + } else { + return new ConversationIntroductionInItem(ir); + } } - boolean isSent() { - return sent; + public static ConversationItem from(Context ctx, String contactName, + IntroductionResponse ir) { + + if (ir.isLocal()) { + String text; + if (ir.wasAccepted()) { + text = ctx.getString( + R.string.introduction_response_accepted_sent, + ir.getName()); + } else { + text = ctx.getString( + R.string.introduction_response_declined_sent, + ir.getName()); + } + return new ConversationNoticeOutItem(ir.getMessageId(), text, + ir.getTime(), ir.isSent(), ir.isSeen()); + } else { + String text; + if (ir.wasAccepted()) { + text = ctx.getString( + R.string.introduction_response_accepted_received, + contactName, ir.getName()); + } else { + text = ctx.getString( + R.string.introduction_response_declined_received, + contactName, ir.getName()); + } + return new ConversationNoticeInItem(ir.getMessageId(), text, + ir.getTime(), ir.isRead()); + } } - void setSent(boolean sent) { - this.sent = sent; + /** This method should not be used to get user-facing objects, + * Its purpose is to provider data for the contact list. + */ + public static ConversationItem from(IntroductionMessage im) { + if (im.isLocal()) + return new ConversationNoticeOutItem(im.getMessageId(), "", + im.getTime(), false, false); + return new ConversationNoticeInItem(im.getMessageId(), "", im.getTime(), + im.isRead()); } - boolean isSeen() { - return seen; + protected interface OutgoingItem { + MessageId getId(); + boolean isSent(); + void setSent(boolean sent); + boolean isSeen(); + void setSeen(boolean seen); } - void setSeen(boolean seen) { - this.seen = seen; + protected interface IncomingItem { + MessageId getId(); + boolean isRead(); + void setRead(boolean read); } + } diff --git a/briar-android/src/org/briarproject/android/contact/ConversationMessageItem.java b/briar-android/src/org/briarproject/android/contact/ConversationMessageItem.java new file mode 100644 index 0000000000..38e5afab0c --- /dev/null +++ b/briar-android/src/org/briarproject/android/contact/ConversationMessageItem.java @@ -0,0 +1,73 @@ +package org.briarproject.android.contact; + +import org.briarproject.api.messaging.PrivateMessageHeader; +import org.briarproject.api.sync.MessageId; + +// This class is not thread-safe +public class ConversationMessageItem extends ConversationItem implements + ConversationItem.OutgoingItem, ConversationItem.IncomingItem { + + private final PrivateMessageHeader header; + private byte[] body; + private boolean sent, seen, read; + + public ConversationMessageItem(PrivateMessageHeader header) { + super(header.getId(), header.getTimestamp()); + + this.header = header; + body = null; + sent = header.isSent(); + seen = header.isSeen(); + read = header.isRead(); + } + + @Override + int getType() { + if (getHeader().isLocal()) return MSG_OUT; + if (getHeader().isRead()) return MSG_IN; + return MSG_IN_UNREAD; + } + + PrivateMessageHeader getHeader() { + return header; + } + + byte[] getBody() { + return body; + } + + void setBody(byte[] body) { + this.body = body; + } + + @Override + public boolean isSent() { + return sent; + } + + @Override + public void setSent(boolean sent) { + this.sent = sent; + } + + @Override + public boolean isSeen() { + return seen; + } + + @Override + public void setSeen(boolean seen) { + this.seen = seen; + } + + @Override + public boolean isRead() { + return read; + } + + @Override + public void setRead(boolean read) { + this.read = read; + } + +} diff --git a/briar-android/src/org/briarproject/android/contact/ConversationNoticeInItem.java b/briar-android/src/org/briarproject/android/contact/ConversationNoticeInItem.java new file mode 100644 index 0000000000..610b703c17 --- /dev/null +++ b/briar-android/src/org/briarproject/android/contact/ConversationNoticeInItem.java @@ -0,0 +1,32 @@ +package org.briarproject.android.contact; + +import org.briarproject.api.sync.MessageId; + +public class ConversationNoticeInItem extends ConversationNoticeItem implements + ConversationItem.IncomingItem { + + private boolean read; + + public ConversationNoticeInItem(MessageId id, String text, long time, + boolean read) { + super(id, text, time); + + this.read = read; + } + + @Override + int getType() { + return NOTICE_IN; + } + + @Override + public boolean isRead() { + return read; + } + + @Override + public void setRead(boolean read) { + this.read = read; + } + +} diff --git a/briar-android/src/org/briarproject/android/contact/ConversationNoticeItem.java b/briar-android/src/org/briarproject/android/contact/ConversationNoticeItem.java new file mode 100644 index 0000000000..eabc73970a --- /dev/null +++ b/briar-android/src/org/briarproject/android/contact/ConversationNoticeItem.java @@ -0,0 +1,19 @@ +package org.briarproject.android.contact; + +import org.briarproject.api.sync.MessageId; + +abstract class ConversationNoticeItem extends ConversationItem { + + private String text; + + public ConversationNoticeItem(MessageId id, String text, long time) { + super(id, time); + + this.text = text; + } + + public String getText() { + return text; + } + +} diff --git a/briar-android/src/org/briarproject/android/contact/ConversationNoticeOutItem.java b/briar-android/src/org/briarproject/android/contact/ConversationNoticeOutItem.java new file mode 100644 index 0000000000..b398897013 --- /dev/null +++ b/briar-android/src/org/briarproject/android/contact/ConversationNoticeOutItem.java @@ -0,0 +1,44 @@ +package org.briarproject.android.contact; + +import org.briarproject.api.sync.MessageId; + +public class ConversationNoticeOutItem extends ConversationNoticeItem implements + ConversationItem.OutgoingItem { + + private boolean sent, seen; + + public ConversationNoticeOutItem(MessageId id, String text, long time, + boolean sent, boolean seen) { + + super(id, text, time); + + this.sent = sent; + this.seen = seen; + } + + @Override + int getType() { + return NOTICE_OUT; + } + + @Override + public boolean isSent() { + return sent; + } + + @Override + public void setSent(boolean sent) { + this.sent = sent; + } + + @Override + public boolean isSeen() { + return seen; + } + + @Override + public void setSeen(boolean seen) { + this.seen = seen; + } + +} diff --git a/briar-android/src/org/briarproject/android/introduction/ContactChooserFragment.java b/briar-android/src/org/briarproject/android/introduction/ContactChooserFragment.java new file mode 100644 index 0000000000..66e57686a4 --- /dev/null +++ b/briar-android/src/org/briarproject/android/introduction/ContactChooserFragment.java @@ -0,0 +1,243 @@ +package org.briarproject.android.introduction; + +import android.content.Context; +import android.content.DialogInterface; +import android.os.Build; +import android.os.Bundle; +import android.support.v7.app.AlertDialog; +import android.support.v7.widget.LinearLayoutManager; +import android.transition.ChangeBounds; +import android.transition.Fade; +import android.view.LayoutInflater; +import android.view.View; +import android.view.ViewGroup; +import android.widget.Toast; + +import org.briarproject.R; +import org.briarproject.android.AndroidComponent; +import org.briarproject.android.contact.ContactListAdapter; +import org.briarproject.android.contact.ContactListItem; +import org.briarproject.android.contact.ConversationItem; +import org.briarproject.android.contact.ConversationMessageItem; +import org.briarproject.android.fragment.BaseFragment; +import org.briarproject.android.util.BriarRecyclerView; +import org.briarproject.api.contact.Contact; +import org.briarproject.api.contact.ContactId; +import org.briarproject.api.contact.ContactManager; +import org.briarproject.api.db.DbException; +import org.briarproject.api.identity.AuthorId; +import org.briarproject.api.identity.IdentityManager; +import org.briarproject.api.identity.LocalAuthor; +import org.briarproject.api.introduction.IntroductionManager; +import org.briarproject.api.introduction.IntroductionMessage; +import org.briarproject.api.messaging.MessagingManager; +import org.briarproject.api.messaging.PrivateMessageHeader; +import org.briarproject.api.plugins.ConnectionRegistry; +import org.briarproject.api.sync.GroupId; + +import java.util.ArrayList; +import java.util.Collection; +import java.util.List; +import java.util.logging.Logger; + +import javax.inject.Inject; + +import static java.util.logging.Level.INFO; +import static java.util.logging.Level.WARNING; + +public class ContactChooserFragment extends BaseFragment { + + public final static String TAG = "ContactChooserFragment"; + private IntroductionActivity introductionActivity; + private BriarRecyclerView list; + private ContactListAdapter adapter; + private int contactId; + + private static final Logger LOG = + Logger.getLogger(ContactChooserFragment.class.getName()); + + // Fields that are accessed from background threads must be volatile + protected volatile Contact c1; + @Inject + protected volatile ContactManager contactManager; + @Inject + protected volatile IdentityManager identityManager; + @Inject + protected volatile MessagingManager messagingManager; + @Inject + protected volatile IntroductionManager introductionManager; + @Inject + protected volatile ConnectionRegistry connectionRegistry; + + @Override + public void onAttach(Context context) { + super.onAttach(context); + try { + introductionActivity = (IntroductionActivity) context; + } catch (ClassCastException e) { + throw new java.lang.InstantiationError( + "This fragment is only meant to be attached to the IntroductionActivity"); + } + } + + @Override + public void injectActivity(AndroidComponent component) { + component.inject(this); + } + + @Override + public View onCreateView(LayoutInflater inflater, ViewGroup container, + Bundle savedInstanceState) { + + View contentView = + inflater.inflate(R.layout.introduction_contact_chooser, + container, false); + + + if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) { + setExitTransition(new Fade()); + } + + ContactListAdapter.OnItemClickListener onItemClickListener = + new ContactListAdapter.OnItemClickListener() { + @Override + public void onItemClick(View view, ContactListItem item) { + if (c1 == null) { + Toast.makeText(getActivity(), + R.string.introduction_error, + Toast.LENGTH_SHORT).show(); + return; + } + Contact c2 = item.getContact(); + if (!c1.getLocalAuthorId() + .equals(c2.getLocalAuthorId())) { + warnAboutDifferentIdentities(view, c1, c2); + } else { + introductionActivity.showMessageScreen(view, c1, c2); + } + } + }; + adapter = + new ContactListAdapter(getActivity(), onItemClickListener, true); + + list = (BriarRecyclerView) contentView.findViewById(R.id.contactList); + list.setLayoutManager(new LinearLayoutManager(getActivity())); + list.setAdapter(adapter); + list.setEmptyText(getString(R.string.no_contacts)); + + contactId = introductionActivity.getContactId(); + + return contentView; + } + + @Override + public void onResume() { + super.onResume(); + + loadContacts(); + } + + @Override + public String getUniqueTag() { + return TAG; + } + + private void loadContacts() { + introductionActivity.runOnDbThread(new Runnable() { + public void run() { + try { + List<ContactListItem> contacts = + new ArrayList<ContactListItem>(); + AuthorId localAuthorId= null; + for (Contact c : contactManager.getActiveContacts()) { + if (c.getId().getInt() == contactId) { + c1 = c; + localAuthorId = c1.getLocalAuthorId(); + } else { + ContactId id = c.getId(); + GroupId groupId = + messagingManager.getConversationId(id); + Collection<ConversationItem> messages = + getMessages(id); + boolean connected = + connectionRegistry.isConnected(c.getId()); + LocalAuthor localAuthor = identityManager + .getLocalAuthor(c.getLocalAuthorId()); + contacts.add(new ContactListItem(c, localAuthor, + connected, groupId, messages)); + } + } + displayContacts(localAuthorId, contacts); + } catch (DbException e) { + if (LOG.isLoggable(WARNING)) + LOG.log(WARNING, e.toString(), e); + } + } + }); + } + + private void displayContacts(final AuthorId localAuthorId, + final List<ContactListItem> contacts) { + introductionActivity.runOnUiThread(new Runnable() { + public void run() { + adapter.setLocalAuthor(localAuthorId); + adapter.clear(); + if (contacts.size() == 0) list.showData(); + else adapter.addAll(contacts); + } + }); + } + + private void warnAboutDifferentIdentities(final View view, final Contact c1, + final Contact c2) { + + DialogInterface.OnClickListener okListener = + new DialogInterface.OnClickListener() { + @Override + public void onClick(DialogInterface dialog, int which) { + introductionActivity.showMessageScreen(view, c1, c2); + } + }; + AlertDialog.Builder builder = new AlertDialog.Builder(getActivity(), + R.style.BriarDialogTheme); + builder.setTitle(getString( + R.string.introduction_warn_different_identities_title)); + builder.setMessage(getString( + R.string.introduction_warn_different_identities_text)); + builder.setPositiveButton(R.string.dialog_button_introduce, okListener); + builder.setNegativeButton(android.R.string.cancel, null); + builder.show(); + } + + /** This needs to be called from the DbThread */ + private Collection<ConversationItem> getMessages(ContactId id) + throws DbException { + + long now = System.currentTimeMillis(); + + Collection<ConversationItem> messages = + new ArrayList<ConversationItem>(); + + Collection<PrivateMessageHeader> headers = + messagingManager.getMessageHeaders(id); + for (PrivateMessageHeader h : headers) { + messages.add(new ConversationMessageItem(h)); + } + long duration = System.currentTimeMillis() - now; + if (LOG.isLoggable(INFO)) + LOG.info("Loading message headers took " + duration + " ms"); + + Collection<IntroductionMessage> introductions = + introductionManager + .getIntroductionMessages(id); + for (IntroductionMessage m : introductions) { + messages.add(ConversationItem.from(m)); + } + duration = System.currentTimeMillis() - now; + if (LOG.isLoggable(INFO)) + LOG.info("Loading introduction messages took " + duration + " ms"); + + return messages; + } + +} diff --git a/briar-android/src/org/briarproject/android/introduction/IntroductionActivity.java b/briar-android/src/org/briarproject/android/introduction/IntroductionActivity.java new file mode 100644 index 0000000000..c3905df14c --- /dev/null +++ b/briar-android/src/org/briarproject/android/introduction/IntroductionActivity.java @@ -0,0 +1,107 @@ +package org.briarproject.android.introduction; + +import android.content.Intent; +import android.os.Build; +import android.os.Bundle; +import android.support.v4.app.FragmentManager; +import android.transition.ChangeBounds; +import android.transition.Fade; +import android.view.MenuItem; +import android.view.View; + +import org.briarproject.R; +import org.briarproject.android.AndroidComponent; +import org.briarproject.android.BriarActivity; +import org.briarproject.android.fragment.BaseFragment; +import org.briarproject.api.contact.Contact; + +public class IntroductionActivity extends BriarActivity implements + BaseFragment.BaseFragmentListener { + + public static final String CONTACT_ID = "briar.CONTACT_ID"; + private int contactId; + + @Override + public void onCreate(Bundle savedInstanceState) { + super.onCreate(savedInstanceState); + + Intent intent = getIntent(); + contactId = intent.getIntExtra(CONTACT_ID, -1); + + setContentView(R.layout.activity_introduction); + + if (savedInstanceState == null) { + ContactChooserFragment chooserFragment = + new ContactChooserFragment(); + getSupportFragmentManager().beginTransaction() + .add(R.id.introductionContainer, chooserFragment).commit(); + } + } + + @Override + public void injectActivity(AndroidComponent component) { + component.inject(this); + } + + @Override + public void showLoadingScreen(boolean isBlocking, int stringId) { + // this is handled by the recycler view in ContactChooserFragment + } + + @Override + public void hideLoadingScreen() { + // this is handled by the recycler view in ContactChooserFragment + } + + @Override + public boolean onOptionsItemSelected(final MenuItem item) { + // Handle presses on the action bar items + switch (item.getItemId()) { + case android.R.id.home: + onBackPressed(); + return true; + default: + return super.onOptionsItemSelected(item); + } + } + + @Override + public void onBackPressed() { + FragmentManager fm = getSupportFragmentManager(); + if (fm.getBackStackEntryCount() == 1) { + fm.popBackStack(); + } else { + super.onBackPressed(); + } + } + + public int getContactId() { + return contactId; + } + + public void showMessageScreen(final View view, final Contact c1, + final Contact c2) { + + IntroductionMessageFragment messageFragment = + IntroductionMessageFragment + .newInstance(c1.getId().getInt(), c2.getId().getInt()); + + if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) { + messageFragment.setSharedElementEnterTransition(new ChangeBounds()); + messageFragment.setEnterTransition(new Fade()); + messageFragment.setSharedElementReturnTransition(new ChangeBounds()); + } + + getSupportFragmentManager().beginTransaction() + .setCustomAnimations(android.R.anim.fade_in, + android.R.anim.fade_out, + android.R.anim.slide_in_left, + android.R.anim.slide_out_right) + .addSharedElement(view, "avatar") + .replace(R.id.introductionContainer, messageFragment, + ContactChooserFragment.TAG) + .addToBackStack(null) + .commit(); + } + +} diff --git a/briar-android/src/org/briarproject/android/introduction/IntroductionMessageFragment.java b/briar-android/src/org/briarproject/android/introduction/IntroductionMessageFragment.java new file mode 100644 index 0000000000..7b06c9bd7c --- /dev/null +++ b/briar-android/src/org/briarproject/android/introduction/IntroductionMessageFragment.java @@ -0,0 +1,235 @@ +package org.briarproject.android.introduction; + +import android.app.Activity; +import android.content.Context; +import android.os.Bundle; +import android.support.v7.app.ActionBar; +import android.view.LayoutInflater; +import android.view.View; +import android.view.ViewGroup; +import android.widget.Button; +import android.widget.EditText; +import android.widget.ProgressBar; +import android.widget.TextView; +import android.widget.Toast; + +import org.briarproject.R; +import org.briarproject.android.AndroidComponent; +import org.briarproject.android.fragment.BaseFragment; +import org.briarproject.api.FormatException; +import org.briarproject.api.contact.Contact; +import org.briarproject.api.contact.ContactId; +import org.briarproject.api.contact.ContactManager; +import org.briarproject.api.db.DbException; +import org.briarproject.api.introduction.IntroductionManager; + +import java.util.logging.Logger; + +import javax.inject.Inject; + +import de.hdodenhof.circleimageview.CircleImageView; +import im.delight.android.identicons.IdenticonDrawable; + +import static java.util.logging.Level.WARNING; + +public class IntroductionMessageFragment extends BaseFragment { + + private static final Logger LOG = + Logger.getLogger(IntroductionMessageFragment.class.getName()); + + public final static String TAG = "ContactChooserFragment"; + private IntroductionActivity introductionActivity; + private ViewHolder ui; + + private final static String CONTACT_ID_1 = "contact1"; + private final static String CONTACT_ID_2 = "contact2"; + + // Fields that are accessed from background threads must be volatile + private volatile boolean introductionWasMade = false; + @Inject + protected volatile ContactManager contactManager; + @Inject + protected volatile IntroductionManager introductionManager; + + public static IntroductionMessageFragment newInstance(int contactId1, + int contactId2) { + IntroductionMessageFragment f = new IntroductionMessageFragment(); + + Bundle args = new Bundle(); + args.putInt(CONTACT_ID_1, contactId1); + args.putInt(CONTACT_ID_2, contactId2); + f.setArguments(args); + + return f; + } + + @Override + public void onAttach(Context context) { + super.onAttach(context); + try { + introductionActivity = (IntroductionActivity) context; + } catch (ClassCastException e) { + throw new java.lang.InstantiationError( + "This fragment is only meant to be attached to the IntroductionActivity"); + } + } + + @Override + public void injectActivity(AndroidComponent component) { + component.inject(this); + } + + @Override + public View onCreateView(LayoutInflater inflater, ViewGroup container, + Bundle savedInstanceState) { + + // change toolbar text + ActionBar actionBar = introductionActivity.getSupportActionBar(); + if (actionBar != null) { + actionBar.setTitle(R.string.introduction_message_title); + } + + // inflate view + View v = + inflater.inflate(R.layout.introduction_message, container, + false); + + // show progress bar until contacts have been loaded + ui = new ViewHolder(v); + ui.text.setVisibility(View.GONE); + ui.button.setEnabled(false); + + // get contact IDs from fragment arguments + int contactId1 = getArguments().getInt(CONTACT_ID_1, -1); + int contactId2 = getArguments().getInt(CONTACT_ID_2, -1); + if (contactId1 == -1 || contactId2 == -1) { + throw new java.lang.InstantiationError( + "You need to use newInstance() to instantiate"); + } + + // get contacts and then show view + prepareToSetUpViews(contactId1, contactId2); + + return v; + } + + @Override + public String getUniqueTag() { + return TAG; + } + + private void prepareToSetUpViews(final int contactId1, + final int contactId2) { + introductionActivity.runOnDbThread(new Runnable() { + public void run() { + try { + Contact c1 = contactManager + .getContact(new ContactId(contactId1)); + Contact c2 = contactManager + .getContact(new ContactId(contactId2)); + setUpViews(c1, c2); + } catch (DbException e) { + // TODO + e.printStackTrace(); + } + } + }); + } + + private void setUpViews(final Contact c1, final Contact c2) { + introductionActivity.runOnUiThread(new Runnable() { + public void run() { + // set avatars + ui.avatar1.setImageDrawable(new IdenticonDrawable( + c1.getAuthor().getId().getBytes())); + ui.avatar2.setImageDrawable(new IdenticonDrawable( + c2.getAuthor().getId().getBytes())); + + // set introduction text + ui.text.setText(String.format( + getString(R.string.introduction_message_text), + c1.getAuthor().getName(), c2.getAuthor().getName())); + + // set button action + ui.button.setOnClickListener(new View.OnClickListener() { + @Override + public void onClick(View v) { + onButtonClick(c1, c2); + } + }); + + // hide progress bar and show views + ui.progressBar.setVisibility(View.GONE); + ui.text.setVisibility(View.VISIBLE); + ui.button.setEnabled(true); + } + }); + } + + public void onButtonClick(final Contact c1, final Contact c2) { + String msg = ui.message.getText().toString(); + makeIntroduction(c1, c2, msg); + } + + private void makeIntroduction(final Contact c1, final Contact c2, + final String msg) { + introductionActivity.runOnDbThread(new Runnable() { + public void run() { + // prevent double introductions + if (introductionWasMade) return; + + // actually make the introduction + try { + introductionManager.makeIntroduction(c1, c2, msg); + introductionWasMade = true; + postIntroduction(false); + } catch (DbException e) { + if (LOG.isLoggable(WARNING)) + LOG.log(WARNING, e.toString(), e); + postIntroduction(true); + } catch (FormatException e) { + if (LOG.isLoggable(WARNING)) + LOG.log(WARNING, e.toString(), e); + postIntroduction(true); + } + } + }); + } + + private void postIntroduction(final boolean error) { + introductionActivity.runOnUiThread(new Runnable() { + public void run() { + introductionActivity.hideSoftKeyboard(ui.message); + if (error) { + Toast.makeText(introductionActivity, + R.string.introduction_error, Toast.LENGTH_SHORT) + .show(); + introductionActivity.setResult(Activity.RESULT_CANCELED); + } else { + introductionActivity.setResult(Activity.RESULT_OK); + } + introductionActivity.finish(); + } + }); + } + + private class ViewHolder { + ProgressBar progressBar; + ViewGroup header; + CircleImageView avatar1; + CircleImageView avatar2; + TextView text; + EditText message; + Button button; + + ViewHolder(View v) { + progressBar = (ProgressBar) v.findViewById(R.id.progressBar); + header = (ViewGroup) v.findViewById(R.id.introductionHeader); + avatar1 = (CircleImageView) v.findViewById(R.id.avatarContact1); + avatar2 = (CircleImageView) v.findViewById(R.id.avatarContact2); + text = (TextView) v.findViewById(R.id.introductionText); + message = (EditText) v.findViewById(R.id.introductionMessageView); + button = (Button) v.findViewById(R.id.makeIntroductionButton); + } + } +} diff --git a/briar-android/src/org/briarproject/android/util/BriarRecyclerView.java b/briar-android/src/org/briarproject/android/util/BriarRecyclerView.java index 89c2135024..5e78632290 100644 --- a/briar-android/src/org/briarproject/android/util/BriarRecyclerView.java +++ b/briar-android/src/org/briarproject/android/util/BriarRecyclerView.java @@ -73,15 +73,10 @@ public class BriarRecyclerView extends FrameLayout { } emptyObserver = new RecyclerView.AdapterDataObserver() { - @Override - public void onChanged() { - showData(); - } - @Override public void onItemRangeInserted(int positionStart, int itemCount) { super.onItemRangeInserted(positionStart, itemCount); - onChanged(); + if (itemCount > 0) showData(); } }; } -- GitLab