From ef980ff5cff9653f105fb16bb9a617fab5c82704 Mon Sep 17 00:00:00 2001 From: Daniel Gultsch Date: Tue, 4 Jul 2017 11:01:20 +0200 Subject: [PATCH] show date separators. fixes #2271 --- art/date_bubble_grey.svg | 168 ++++++++++++++++++ art/date_bubble_white.svg | 168 ++++++++++++++++++ art/render.rb | 2 + .../siacs/conversations/entities/Message.java | 12 +- .../ui/ConversationFragment.java | 30 +++- .../siacs/conversations/ui/XmppActivity.java | 5 +- .../ui/adapter/MessageAdapter.java | 31 +++- .../siacs/conversations/utils/UIHelper.java | 18 ++ .../res/drawable-hdpi/date_bubble_grey.9.png | Bin 0 -> 657 bytes .../res/drawable-hdpi/date_bubble_white.9.png | Bin 0 -> 689 bytes .../res/drawable-mdpi/date_bubble_grey.9.png | Bin 0 -> 514 bytes .../res/drawable-mdpi/date_bubble_white.9.png | Bin 0 -> 525 bytes .../res/drawable-xhdpi/date_bubble_grey.9.png | Bin 0 -> 739 bytes .../drawable-xhdpi/date_bubble_white.9.png | Bin 0 -> 769 bytes .../drawable-xxhdpi/date_bubble_grey.9.png | Bin 0 -> 1072 bytes .../drawable-xxhdpi/date_bubble_white.9.png | Bin 0 -> 1127 bytes .../drawable-xxxhdpi/date_bubble_grey.9.png | Bin 0 -> 1392 bytes .../drawable-xxxhdpi/date_bubble_white.9.png | Bin 0 -> 1430 bytes src/main/res/layout/message_date_bubble.xml | 26 +++ src/main/res/values/strings.xml | 2 + 20 files changed, 448 insertions(+), 14 deletions(-) create mode 100644 art/date_bubble_grey.svg create mode 100644 art/date_bubble_white.svg create mode 100644 src/main/res/drawable-hdpi/date_bubble_grey.9.png create mode 100644 src/main/res/drawable-hdpi/date_bubble_white.9.png create mode 100644 src/main/res/drawable-mdpi/date_bubble_grey.9.png create mode 100644 src/main/res/drawable-mdpi/date_bubble_white.9.png create mode 100644 src/main/res/drawable-xhdpi/date_bubble_grey.9.png create mode 100644 src/main/res/drawable-xhdpi/date_bubble_white.9.png create mode 100644 src/main/res/drawable-xxhdpi/date_bubble_grey.9.png create mode 100644 src/main/res/drawable-xxhdpi/date_bubble_white.9.png create mode 100644 src/main/res/drawable-xxxhdpi/date_bubble_grey.9.png create mode 100644 src/main/res/drawable-xxxhdpi/date_bubble_white.9.png create mode 100644 src/main/res/layout/message_date_bubble.xml diff --git a/art/date_bubble_grey.svg b/art/date_bubble_grey.svg new file mode 100644 index 000000000..38db49f9b --- /dev/null +++ b/art/date_bubble_grey.svg @@ -0,0 +1,168 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + image/svg+xml + + + + + + + + + + diff --git a/art/date_bubble_white.svg b/art/date_bubble_white.svg new file mode 100644 index 000000000..452ae9272 --- /dev/null +++ b/art/date_bubble_white.svg @@ -0,0 +1,168 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + image/svg+xml + + + + + + + + + + diff --git a/art/render.rb b/art/render.rb index 01ab3903d..e20b951c7 100755 --- a/art/render.rb +++ b/art/render.rb @@ -64,6 +64,8 @@ images = { 'message_bubble_received_white.svg' => ['message_bubble_received_white.9', 0], 'message_bubble_sent.svg' => ['message_bubble_sent.9', 0], 'message_bubble_sent_grey.svg' => ['message_bubble_sent_grey.9', 0], + 'date_bubble_white.svg' => ['date_bubble_white.9', 0], + 'date_bubble_grey.svg' => ['date_bubble_grey.9', 0], } # Executable paths for Mac OSX diff --git a/src/main/java/eu/siacs/conversations/entities/Message.java b/src/main/java/eu/siacs/conversations/entities/Message.java index f360122de..77b54d328 100644 --- a/src/main/java/eu/siacs/conversations/entities/Message.java +++ b/src/main/java/eu/siacs/conversations/entities/Message.java @@ -10,6 +10,7 @@ import java.net.URL; import eu.siacs.conversations.Config; import eu.siacs.conversations.crypto.axolotl.FingerprintStatus; import eu.siacs.conversations.http.AesGcmURLStreamHandler; +import eu.siacs.conversations.ui.adapter.MessageAdapter; import eu.siacs.conversations.utils.CryptoHelper; import eu.siacs.conversations.utils.GeoHelper; import eu.siacs.conversations.utils.MimeUtils; @@ -203,6 +204,14 @@ public class Message extends AbstractEntity { return message; } + public static Message createDateSeparator(Message message) { + final Message separator = new Message(message.getConversation()); + separator.setType(Message.TYPE_STATUS); + separator.setBody(MessageAdapter.DATE_SEPARATOR_BODY); + separator.setTime(message.getTimeSent()); + return separator; + } + @Override public ContentValues getContentValues() { ContentValues values = new ContentValues(); @@ -493,7 +502,8 @@ public class Message extends AbstractEntity { !this.getBody().startsWith(ME_COMMAND) && !this.bodyIsHeart() && !message.bodyIsHeart() && - ((this.axolotlFingerprint == null && message.axolotlFingerprint == null) || this.axolotlFingerprint.equals(message.getFingerprint())) + ((this.axolotlFingerprint == null && message.axolotlFingerprint == null) || this.axolotlFingerprint.equals(message.getFingerprint())) && + UIHelper.sameDay(message.getTimeSent(),this.getTimeSent()) ); } diff --git a/src/main/java/eu/siacs/conversations/ui/ConversationFragment.java b/src/main/java/eu/siacs/conversations/ui/ConversationFragment.java index 841519305..afdabcfe8 100644 --- a/src/main/java/eu/siacs/conversations/ui/ConversationFragment.java +++ b/src/main/java/eu/siacs/conversations/ui/ConversationFragment.java @@ -46,6 +46,7 @@ import java.util.ArrayList; import java.util.Arrays; import java.util.Collections; import java.util.List; +import java.util.ListIterator; import java.util.UUID; import java.util.concurrent.atomic.AtomicBoolean; @@ -154,14 +155,16 @@ public class ConversationFragment extends Fragment implements EditMessage.Keyboa @Override public void run() { final int oldPosition = messagesView.getFirstVisiblePosition(); - final Message message; - if (oldPosition < messageList.size()) { - message = messageList.get(oldPosition); - } else { - message = null; + Message message = null; + int childPos; + for(childPos = 0; childPos + oldPosition < messageList.size(); ++childPos) { + message = messageList.get(oldPosition + childPos); + if (message.getType() != Message.TYPE_STATUS) { + break; + } } - String uuid = message != null ? message.getUuid() : null; - View v = messagesView.getChildAt(0); + final String uuid = message != null ? message.getUuid() : null; + View v = messagesView.getChildAt(childPos); final int pxOffset = (v == null) ? 0 : v.getTop(); ConversationFragment.this.conversation.populateWithMessages(ConversationFragment.this.messageList); try { @@ -1300,7 +1303,20 @@ public class ConversationFragment extends Fragment implements EditMessage.Keyboa this.mSendButton.setImageResource(getSendButtonImageResource(action, status)); } + protected void updateDateSeparators() { + synchronized (this.messageList) { + for(int i = 0; i < this.messageList.size(); ++i) { + final Message current = this.messageList.get(i); + if (i == 0 || !UIHelper.sameDay(this.messageList.get(i-1).getTimeSent(),current.getTimeSent())) { + this.messageList.add(i,Message.createDateSeparator(current)); + i++; + } + } + } + } + protected void updateStatusMessages() { + updateDateSeparators(); synchronized (this.messageList) { if (showLoadMoreMessages(conversation)) { this.messageList.add(0, Message.createLoadMoreMessage(conversation)); diff --git a/src/main/java/eu/siacs/conversations/ui/XmppActivity.java b/src/main/java/eu/siacs/conversations/ui/XmppActivity.java index 9c2e9bae2..a4b7c5caf 100644 --- a/src/main/java/eu/siacs/conversations/ui/XmppActivity.java +++ b/src/main/java/eu/siacs/conversations/ui/XmppActivity.java @@ -391,6 +391,7 @@ public abstract class XmppActivity extends Activity { mPrimaryBackgroundColor = ContextCompat.getColor(this, R.color.grey50); mSecondaryBackgroundColor = ContextCompat.getColor(this, R.color.grey200); + this.mTheme = findTheme(); if(isDarkTheme()) { mPrimaryTextColor = ContextCompat.getColor(this, R.color.white); mSecondaryTextColor = ContextCompat.getColor(this, R.color.white70); @@ -398,8 +399,6 @@ public abstract class XmppActivity extends Activity { mPrimaryBackgroundColor = ContextCompat.getColor(this, R.color.grey800); mSecondaryBackgroundColor = ContextCompat.getColor(this, R.color.grey900); } - - this.mTheme = findTheme(); setTheme(this.mTheme); this.mUsingEnterKey = usingEnterKey(); @@ -411,7 +410,7 @@ public abstract class XmppActivity extends Activity { } public boolean isDarkTheme() { - return getPreferences().getString("theme", getResources().getString(R.string.theme)).equals("dark"); + return this.mTheme == R.style.ConversationsTheme_Dark || this.mTheme == R.style.ConversationsTheme_Dark_LargerText; } public int getThemeResource(int r_attr_name, int r_drawable_def) { diff --git a/src/main/java/eu/siacs/conversations/ui/adapter/MessageAdapter.java b/src/main/java/eu/siacs/conversations/ui/adapter/MessageAdapter.java index 1a203e9e9..adaa31174 100644 --- a/src/main/java/eu/siacs/conversations/ui/adapter/MessageAdapter.java +++ b/src/main/java/eu/siacs/conversations/ui/adapter/MessageAdapter.java @@ -16,6 +16,7 @@ import android.text.Spannable; import android.text.SpannableString; import android.text.SpannableStringBuilder; import android.text.Spanned; +import android.text.format.DateUtils; import android.text.style.ForegroundColorSpan; import android.text.style.RelativeSizeSpan; import android.text.style.StyleSpan; @@ -72,6 +73,10 @@ public class MessageAdapter extends ArrayAdapter implements CopyTextVie private static final int SENT = 0; private static final int RECEIVED = 1; private static final int STATUS = 2; + private static final int DATE_SEPARATOR = 3; + + public static final String DATE_SEPARATOR_BODY = "DATE_SEPARATOR"; + private static final Pattern XMPP_PATTERN = Pattern .compile("xmpp\\:(?:(?:[" + Patterns.GOOD_IRI_CHAR @@ -135,12 +140,16 @@ public class MessageAdapter extends ArrayAdapter implements CopyTextVie @Override public int getViewTypeCount() { - return 3; + return 4; } public int getItemViewType(Message message) { if (message.getType() == Message.TYPE_STATUS) { - return STATUS; + if (DATE_SEPARATOR_BODY.equals(message.getBody())) { + return DATE_SEPARATOR; + } else { + return STATUS; + } } else if (message.getStatus() <= Message.STATUS_RECEIVED) { return RECEIVED; } @@ -591,6 +600,11 @@ public class MessageAdapter extends ArrayAdapter implements CopyTextVie if (view == null) { viewHolder = new ViewHolder(); switch (type) { + case DATE_SEPARATOR: + view = activity.getLayoutInflater().inflate(R.layout.message_date_bubble, parent, false); + viewHolder.status_message = (TextView) view.findViewById(R.id.message_body); + viewHolder.message_box = (LinearLayout) view.findViewById(R.id.message_box); + break; case SENT: view = activity.getLayoutInflater().inflate( R.layout.message_sent, parent, false); @@ -659,7 +673,18 @@ public class MessageAdapter extends ArrayAdapter implements CopyTextVie boolean darkBackground = type == RECEIVED && (!isInValidSession || mUseGreenBackground) || activity.isDarkTheme(); - if (type == STATUS) { + if (type == DATE_SEPARATOR) { + if (UIHelper.today(message.getTimeSent())) { + viewHolder.status_message.setText(R.string.today); + } else if (UIHelper.yesterday(message.getTimeSent())) { + viewHolder.status_message.setText(R.string.yesterday); + } else { + viewHolder.status_message.setText(DateUtils.formatDateTime(activity,message.getTimeSent(),DateUtils.FORMAT_SHOW_DATE | DateUtils.FORMAT_SHOW_YEAR)); + } + viewHolder.message_box.setBackgroundResource(activity.isDarkTheme() ? R.drawable.date_bubble_grey : R.drawable.date_bubble_white); + viewHolder.status_message.setTextColor(activity.getSecondaryTextColor()); + return view; + } else if (type == STATUS) { if ("LOAD_MORE".equals(message.getBody())) { viewHolder.status_message.setVisibility(View.GONE); viewHolder.contact_picture.setVisibility(View.GONE); diff --git a/src/main/java/eu/siacs/conversations/utils/UIHelper.java b/src/main/java/eu/siacs/conversations/utils/UIHelper.java index 658fdc1e5..af0f5b6c6 100644 --- a/src/main/java/eu/siacs/conversations/utils/UIHelper.java +++ b/src/main/java/eu/siacs/conversations/utils/UIHelper.java @@ -100,6 +100,24 @@ public class UIHelper { return sameDay(date,new Date(System.currentTimeMillis())); } + public static boolean today(long date) { + return sameDay(date,System.currentTimeMillis()); + } + + public static boolean yesterday(long date) { + Calendar cal1 = Calendar.getInstance(); + Calendar cal2 = Calendar.getInstance(); + cal1.add(Calendar.DAY_OF_YEAR,-1); + cal2.setTime(new Date(date)); + return cal1.get(Calendar.YEAR) == cal2.get(Calendar.YEAR) + && cal1.get(Calendar.DAY_OF_YEAR) == cal2 + .get(Calendar.DAY_OF_YEAR); + } + + public static boolean sameDay(long a, long b) { + return sameDay(new Date(a),new Date(b)); + } + private static boolean sameDay(Date a, Date b) { Calendar cal1 = Calendar.getInstance(); Calendar cal2 = Calendar.getInstance(); diff --git a/src/main/res/drawable-hdpi/date_bubble_grey.9.png b/src/main/res/drawable-hdpi/date_bubble_grey.9.png new file mode 100644 index 0000000000000000000000000000000000000000..d12d22f4e5f89c883aa61d66e5351faf20a46601 GIT binary patch literal 657 zcmeAS@N?(olHy`uVBq!ia0vp^njp-<1|(M`Fnj}2Ea{HEjtmSN`?>!lvI6-E$sR$z z3=CCj3=9n|3=F@3LJcn%7)lKo7+xhXFj&oCU=S~uvn$XBD8ZKG?d}4kf#9d}?s_1_ zS>O>_%)lU~3c`$@K`I}Bg6t)pzOL*K*;zP^)mSY*H8C(SMtizAhD02Gd&AM|u!G34 zkN>?_C^_D(YSY_w#aB~zM}SSkBi64Rx*kQ%4!d87#&nC!6!{$^;hGW@^j1Z92LGm$ zO7D-)_B1j+RJTactS|`5i1e*+ByE!j2<2$#-7fq)fyE$QE#~gDW7Kc!M9ks2B$)UbcPHGX)_LuGm zUHe0Af}v@9bja4J_ah^>i(T675~9zy$1~mPWv!CchG(yR)c5*3ur0~wJkjt)mr-)U zzNNc8LUnH)2)QCE9n@>sZ8qW93`^7gNR#uQw`g=_9zKvc@A*pJ%-dE+4saG+d;eX3 zvWjHKiHX{CR_$9Gw)$w%&Kjn9jp26wx3(#;yHn@04{j+TImqqR?pKdLTI9&Vh^1|5u^nWq0nSb@ARcaI*JPiza)e_f; zl9a@fRIB8oR3OD*WMF8nYXC$hAqJLKriNC=7TN|zRt5(B$6nn)(U6;;l9^VCTf@KE zK`B5Dk{}y`^V3So6N^$A%FE03GV`*FlM@S4_413-XTP(N0xDwgboFyt=akR{0ACvK Ap#T5? literal 0 HcmV?d00001 diff --git a/src/main/res/drawable-hdpi/date_bubble_white.9.png b/src/main/res/drawable-hdpi/date_bubble_white.9.png new file mode 100644 index 0000000000000000000000000000000000000000..df74d811aa5e3940f42fba1b734d2e54b5b23554 GIT binary patch literal 689 zcmeAS@N?(olHy`uVBq!ia0vp^njp-<1|(M`Fnj}2Ea{HEjtmSN`?>!lvI6-E$sR$z z3=CCj3=9n|3=F@3LJcn%7)lKo7+xhXFj&oCU=S~uvn$XBD8ZKG?d}4kf#9d}?s_1_ zS>O>_%)lU~3c`$@K`I}Bg6t)pzOL*K*;zP^Rp%HiwqRgjtoC$q42d}WcE&-k!v+$^ z|9h@j*HQKHLh}1&*{`fNJ~a$SZ`bJGEVOHC(%SXlw}oW3_Sm>8AmjrV1?v;Y?B4o|<#NRqZ{VtLhm! zP59W2Q0GKPuS)sjA9;1+xw3>~bi}6naxpO^zp1jDAAdk-j_)L`rGB$T{&=-dFz%kb z&2!VLReZN5n3UF^sn6cMbV|wJ3A^1n4sJ-?-5IoM>iwB3cTZeW9&ja}Z_h$w&nkXb z_HQ+FJug)^rA+wJt01XTtL(w%dH=<_CD(rK<()Ze*Acaqmd`hvsaQS_jyM;yE%v8e z!(^ND?J^vz&uGo{Dil=l=r!Btt zg7biJgE>RdTouDiIc5u%4gA}=eHd5t+*$2exb*4P@OlO%WeHOS&7Ktp+KN9}&tL92 zUEM2J?&*fM>VK0jY`bn;zwRre0DrEX=PT!Fz?e}jag8WRNi0dVN-jzTQVd20hUU5k zKx7hPU}!lvI6-E$sR$z z3=CCj3=9n|3=F@3LJcn%7)lKo7+xhXFj&oCU=S~uvn$XBD8ZKG?d}4kf#9d}?s_1_ zS>O>_%)r2R1cVu!pRnKeU`SXsF)7;r&8xUZflUr4k0=m!B7?{OAbun%G=pF7@ee5L3TYoBNfmoi8FL z>Fs?UFLLx+)Nb}q6Yr)A-V6;beWMpuI@z~{F{h!~%w&e@AqInEPtKn+TXaw}?&EYn z>Dxlm-v6EF$^7}rS8p{d?dC%!y$4MHtTmKMSA7yVmF&E?tmY8UgIn|gn1Yd=K- z{iRys8c~vxSdwa$T$Bo=7>o=I&2rb^HVa@ zDsgN0H#;Z=s6i5BLvVgtNqJ&XDnogBxn5>oc5!lIL8@MUQTpt6Hc~)E44$rjF6*2U FngFdHveW!lvI6-E$sR$z z3=CCj3=9n|3=F@3LJcn%7)lKo7+xhXFj&oCU=S~uvn$XBD8ZKG?d}4kf#9d}?s_1_ zS>O>_%)r2R1cVu>pV8Nh@3iqXkYB@C$*K6%dA@738nkm+BCHV zFaCFIhOXe-&WxwYI!ft+H;)$9WH4(bp9$1_%DOsa+EZ1}NxTiu)fc3tS*LJry(Y-8 zu1WiOO^^1!XDfg0`ZCq&vtmEr9Gizr)@Dv?VU%cK{PEr)O|Q);{n_fxu6hBVZ2Z@5 zHIJXMb=!$eI<23jP2G4Hycx0?1b>;AF(xq1VYqYAC@JJZEBhM0+AE2hS9o{jPd?}$ zrynkAb9t4c*EFCPRZCnWN>UO_QmvAUQh^kMk%6JPt^p94gcw*_nHpLdn`;{wSs55q z_RTUx(U6;;l9^VCTLZ^srCy*0NstY}`DrEPiAAXl<>lpinR(g8$%zH2dih1^v)|cB Q0TnTLy85}Sb4q9e0A&ZS^Z)<= literal 0 HcmV?d00001 diff --git a/src/main/res/drawable-xhdpi/date_bubble_grey.9.png b/src/main/res/drawable-xhdpi/date_bubble_grey.9.png new file mode 100644 index 0000000000000000000000000000000000000000..c83fd61306d48d19f1c5d4fbccfea112977898a2 GIT binary patch literal 739 zcmeAS@N?(olHy`uVBq!ia0vp^W+2SL1|)l2v+e>ZmUKs7M+SzC{oH>NS%G|oWRD45bDP46hOx7_4S6Fo+k-*%fF5lweEpc6R~NK=9LfcRi5e zEbxddW?+zQ2Vutkryo;+g6t)pzOL*K*;zP^)r;&7i7+rQuJv?r49U3ncBZ4>AqNS! z`xiJ(9hD6A_B6#cwybb3ddkToy*|Zb0;~Fk2@+u&TwND!JMn&zsp6?ET@MUW<1VrK zaNd7yo_SgFXw}3yg(bcTGy4uTL zef?D^(Pr*&cGHD$xknc3w%>jm&2#=#(6N5+LuaT>IgNwgzmET$`4KCb(|eznlHdUJRb*U#BA zGUrD&XnwHdz26`^sV!Hx(_8D?tS(=JEv|kZu9qgLWqK#?-x#SSJTays(k{85ozUC9V-ADTyViR>?)FK#IZ0z|dUR0EkRN z3@oio4XunVwGE7{3=A|kKFmSUkei>9nO2EgL&TfN3qTE$ARB`7(@M${i&7cN%ggmL f^RkPR6AM!H@{7`Ezq647Dq`?-^>bP0l+XkKZmUKs7M+SzC{oH>NS%G|oWRD45bDP46hOx7_4S6Fo+k-*%fF5lweEpc6R~NK=9LfcRi5e zEbxddW?+zQ2Vutkryo;+g6t)pzOL*K*;zP^Rp%HiwqRgjJniY?7?N@C?M%nKM+PDe z_x%GUR1`upmp?YnR_W@XYvVFfc=$9F+yZx^X&m~TF}j3dox#bk#^ku4KfaYOP{Dm5A=EG+lMO+^fG zaayXs(xq*=8#$MT+{!UK-!O+a^0FkmL&b_92Bk}kPQA^SIyohxItYaZQlB`W9k`2~}&SS4>=axH1AO~A_1V_BWz#k~5@q~gw)?wOHYVR-#R z(z=I7V-9!kY!ff;J+B!y?dhSi2CJ?`KXN6+7T>6`+rM3RL9*HGyNMR_%sZzR%EYe^ z)4qHrB5`NTKbc;)zao8(+14@0#a{Wo46yY z`)_2o?uC?YT}Q6aHmQ)CSqb*ZPovb9&#L$;wsHFPJvnB9>t`)D+w=X>ulr9w=6(Fb zy76N9frBagKryXa;u=wsl30>zm0Xkxq!^4049#^7fXF1oz|zXp(8}0c+rY@mz@V~k zmLZCU-29Zxv`X9>I4&#o0yRj2YzWRzD=AMbN@XZ7FW1Y=%Pvk%EJ)SMFG`>N&PEET Oh{4m<&t;ucLK6Ul_%vq# literal 0 HcmV?d00001 diff --git a/src/main/res/drawable-xxhdpi/date_bubble_grey.9.png b/src/main/res/drawable-xxhdpi/date_bubble_grey.9.png new file mode 100644 index 0000000000000000000000000000000000000000..4b4dc4d569922e3b4a9a05d6e992a011f42e0cdd GIT binary patch literal 1072 zcmeAS@N?(olHy`uVBq!ia0vp^0U*r51|<6gKdl8)Ea{HEjtmSN`?>!lvI6-E$sR$z z3=CCj3=9n|3=F@3LJcn%7)lKo7+xhXFj&oCU=S~uvn$XBD8ZKG?d}4kf#9d}?s_1_ zS>O>_%)p@I4Z@5|ZKtgS3bL1Y`ns||WM|w-sQFk}XF1IYDA`z>b%LFD)XUO_6;YDzxU_)Dn4WDdIaK{N@2HuJvA6FjG$Y1kn zbFO4rp>9DWYt((i4RTh246g$E8rS`I|1f{;cFyV5FD+i!a<}^lH%vWqsJr*BdDu2S z74HQOsv;{|n5Mb}*zxavzkz9Lzycwz5T`~jjR4P!kEMbbv;#O(;V2l`AW_O^(&@13eRwy?663t}T;KK2a&z;5#vW>xT-?lkN*x6RP*#+i18< z-s;XS!((&Gci-**P}96R?8EQ-w!)W8)-KKbrRq89d7y~u!sd0%$v*q{zlj+wQ5ubce2bLZ~G z#>DU#%s0?yT%z&fl*zaybN1+* zpYo{cPPEMLX?|+^7XFvy7UxsnaLS@_bL-(J_r=d0S-Nfi;s4bqUAAXD*L%p4%H7`j zT!lvI6-E$sR$z z3=CCj3=9n|3=F@3LJcn%7)lKo7+xhXFj&oCU=S~uvn$XBD8ZKG?d}4kf#9d}?s_1_ zS>O>_%)p@I4Z@5|ZKtgS3bL1Y`ns||WM|g_-BckHw*Th$yL^Xk&g&^JjJ#h5f(#GYKr zp0%a&dBOJ_hgrX4>(1_t`~CaCL;(xx*Ttev56l?%j*qbM_O1gXY&YVXL>^ep@Da z*ZI$J%ol`z zuD6?RB-g;Y_N(&sgPWYP|4JNS;;7RQeZd$J;Pte2tEzDNR;J~l2_7pQSQk97n!?Pb zutxAQ%dMa98}~)sSIc>~^15Rd>$AVNkLgS(n*6|_%;N)R!k(QQ@b`*HClg~WAN#V!NZQH(a z9;q*Q*>e5=S04*2t4n+1-rs)p>ec6@jXy4wUZ}kA{`>c+wbyRXojX^q!I;6BA=zi* z%rD%v{DJQqj2eD3tomB@_u#W<&sI;JI#v8?*4Bkv^>*`}OSF;Wuetw!@9y2dx8BUD zdshZbu0MdO+b_8>Ev%6%aH<%i&M_fv2CoIBTTd`2>b#H%ygK(m&^-=LQID6$64~V+ z6`krA^xQgE_mkE|JrVJZYaDg*B+|`1nN>KqJUjkz!MC55N{v!2=fuoKw9g-z>9%9f zJKwn9%kKc?9W4hVJ#9k~q5PpT!Z5hW>!C8<`) zMX5lF!N|bST-N}IOhODStxOHAj4iYcjI0a{`j5T3fubQdKP5A*61Rqbvx8EA8YDqB t1m~xflqVLYGL)B>>t*I;7bhncr0V4trO$q6BL!5%;OXk;vd$@?2>?+7&^Q19 literal 0 HcmV?d00001 diff --git a/src/main/res/drawable-xxxhdpi/date_bubble_grey.9.png b/src/main/res/drawable-xxxhdpi/date_bubble_grey.9.png new file mode 100644 index 0000000000000000000000000000000000000000..d3db7bf27c0c37dd178ccf8b66bcac787547420d GIT binary patch literal 1392 zcmeAS@N?(olHy`uVBq!ia0vp^Ss={81|&lik4y(rEa{HEjtmSN`?>!lvI6-E$sR$z z3=CCj3=9n|3=F@3LJcn%7)lKo7+xhXFj&oCU=S~uvn$XBD8ZKG?d}4kf#9d}?s_1_ zS>O>_%)nsH2f~bJwk>Q13bL1Y`ns||WM|@v0Pj6YEe4+E@j(uPDGPejg zaVSEFGczmWKR+_v^15WN+Rwg9k+5ysw%G|zY-f;T*unka@II|#=L+rz{tWlKPjtV1 z`_}$KV3c^^rky)~Hg?zuPt<2*sSSVL7Q|E$H|=S-wY9Z!1=nX$)z`0Ie=M;0BX%IY zHr$E%*bMp0CV!Li^YvTXb>@q3G$`~vPG7L(TE~g!haY~>Ts6y@{YWV*qk^=w^nAC# zFWMG&b_OlUtg0_B|6U%lGHb5RbSLkX7@2tQSTr4fZYa zFpqKF>NUkjH}QV;Pq_XIfmp@Z6^BOnd7*_nW*E z@^nlBm$++qaf&Qu=?Y?U)l@tnQ{Uhy#x4xyH!hmu5a_i)Lp5NE(4IOTkAL+uz-%Nf z$VzA|yl>IEU;iFN86Mm7F~WC`%hc4L;rFfAh$f%8Z}<9Vhf(CTx8L?2j*{#@Zl8Rx zw&MO)<-L3M)O4;&HZELjV{cy{dOtp*I=tJ`%Bsp%syD83&F(8pGJk#g@#BYtT>K}q z+z+$f-eqDCY&dxI=+S?-Zr%E8z?1(ymVq}V^4sl$2M;dRIlYddhoOg2Bx9!5^t#q< z`x7}5CZx`sGk5Oa4ZC*zDim@3exUx+9M_pDC$Inh{kwm%N@a8B5}v6mgmhE3ieB}Z zk~>T0S!Lhl%a`N37X8rdd#uFK6s;uG?Qx~N^w$xI$x~7*XDxeKuCA``&&SWd|Kw*I zM^(+W`NbA0t8%&4tYBQVFrVW=*xn-yVFsSFEB5^V-86Go{FT!ZQx~kR@(fVbazE|q zdVAikZ@s6EwY`;RpZ)76$8~EnedBFvtXhg@o|p@GWBJ>&d1p^6rHh&AhIw7Acr!)C zdwP@CBHlz^0BVo~*$|wcR#Ki=l*&+EUaps!mtCBkSdglhUz9%k SosASw5re0zpUXO@geCx6EJa`d literal 0 HcmV?d00001 diff --git a/src/main/res/drawable-xxxhdpi/date_bubble_white.9.png b/src/main/res/drawable-xxxhdpi/date_bubble_white.9.png new file mode 100644 index 0000000000000000000000000000000000000000..37c12f38544ce446ee74a36ac89673e4e5fe5180 GIT binary patch literal 1430 zcmeAS@N?(olHy`uVBq!ia0vp^Ss={81|&lik4y(rEa{HEjtmSN`?>!lvI6-E$sR$z z3=CCj3=9n|3=F@3LJcn%7)lKo7+xhXFj&oCU=S~uvn$XBD8ZKG?d}4kf#9d}?s_1_ zS>O>_%)nsH2f~bJwk>Q13bL1Y`ns||WM|=xWA7}(-6+hx&$ew}?zTv0`VT(fE#wEep#bup=WO| zDqjZ*VOe)&FcSaY-BQp7;IXTzl?Y;f`uIr@Re)!6)Fv zq1XZ;jFQu8&v$>n;5PHyyeHaef)SrwSw4()yCY*l?Pf7#vL-K~G^`t|n@G|!mtSamZ; z@9OKX@msIW_br^~>X5zGe*N{=`%Pw_Rjp8K_g7|hDBpcIzsIoO$=y-Nb5c$8+OY2o zOA5~DT=xlJxbpMoPxoUp?p~0c-e&mh;?0{k*-t!vap{`t6x*GVadFS)JZX=NjJ(O3 z@Id3V=?$rd&P6XCU$C9#CF07<<6?Pq-y8nu-%<^MUVFuN9S%B~obEdHoYwV){>&>h zmWtKRf6^PYifuvD!WBj-af_VFzv&(b4O!U}l-$mF_w@FLM@fsWe0V-NFy^gqfA8Zv zVYLO8mNPqwd1}7}rkI^6l~2`oSeCp_(v`_6&}o5&V!#vu4KEHU<3H>?M)ot1ghW(X zx`dcqIS;<<4_A>n15*hTZd}yjfJHSegyR-nGI`tb??I5~CL z=#HI4`fAmtZQH(izBuRo=*yQc?Y+Id#~Jb%N*L}iR&)woiZRwY z+n)kVQLD>#|J5mZzVt%g_WyY%Qt`|l20h6yd$g3bq^*S*JY|m0UAuPeUW>l^Q=57Y zKVaFU`*4xked2DBJi! zs5#SaS;v$c`6+4ZGuMg6oU?V;f1BI--EU^fOtl58K9mOC{p>1i zw(nK--MEvhneOQ@?L3im&&BNFR^wFjJxBPj^{cc9)W3WEM7}C#e|h0g{#|EOpX+|~ z2nQBFswJ)wB`Jv|saDBFsX&Us$iUEC*8qr2LJTaeObxA!Ewl}ctPBkLkG;Bqq9Hdw zB{QuOw}yYSgHnJRBtbR==ckpFCl;kLl$V$5W#(lUCnpx9>g5-u&wghk1ysb~>FVdQ I&MBb@00hxzF#rGn literal 0 HcmV?d00001 diff --git a/src/main/res/layout/message_date_bubble.xml b/src/main/res/layout/message_date_bubble.xml new file mode 100644 index 000000000..2d3cae7f0 --- /dev/null +++ b/src/main/res/layout/message_date_bubble.xml @@ -0,0 +1,26 @@ + + + + + + + + \ No newline at end of file diff --git a/src/main/res/values/strings.xml b/src/main/res/values/strings.xml index a372a297f..53a8c036e 100644 --- a/src/main/res/values/strings.xml +++ b/src/main/res/values/strings.xml @@ -754,4 +754,6 @@ No application found to open website Heads-up Notifications Show Heads-up Notifications + Today + Yesterday