diff --git a/app/build.gradle b/app/build.gradle
index 9538121cd8..89abde34d3 100644
--- a/app/build.gradle
+++ b/app/build.gradle
@@ -120,6 +120,7 @@ dependencies {
implementation('com.github.bumptech.glide:glide:4.9.0') {
exclude group: 'com.android.support'
}
+ implementation 'com.davemorrissey.labs:subsampling-scale-image-view-androidx:3.10.0'
implementation "org.jetbrains.kotlin:kotlin-stdlib-jdk8:$kotlin_version"
implementation "androidx.lifecycle:lifecycle-viewmodel-ktx:$lifecycle_version"
implementation "androidx.lifecycle:lifecycle-runtime-ktx:$lifecycle_version"
diff --git a/app/res/color/connect_message_audio_track_inactive.xml b/app/res/color/connect_message_audio_track_inactive.xml
new file mode 100644
index 0000000000..8e36235aaf
--- /dev/null
+++ b/app/res/color/connect_message_audio_track_inactive.xml
@@ -0,0 +1,4 @@
+
+
+
+
diff --git a/app/res/drawable/connect_message_pending_tile_bg.xml b/app/res/drawable/connect_message_pending_tile_bg.xml
new file mode 100644
index 0000000000..bb219658d7
--- /dev/null
+++ b/app/res/drawable/connect_message_pending_tile_bg.xml
@@ -0,0 +1,6 @@
+
+
+
+
+
diff --git a/app/res/drawable/connect_message_white_circle.xml b/app/res/drawable/connect_message_white_circle.xml
new file mode 100644
index 0000000000..d043d2650e
--- /dev/null
+++ b/app/res/drawable/connect_message_white_circle.xml
@@ -0,0 +1,5 @@
+
+
+
+
diff --git a/app/res/drawable/ic_connect_message_download.xml b/app/res/drawable/ic_connect_message_download.xml
new file mode 100644
index 0000000000..84dcae417d
--- /dev/null
+++ b/app/res/drawable/ic_connect_message_download.xml
@@ -0,0 +1,9 @@
+
+
+
diff --git a/app/res/drawable/ic_connect_message_file.xml b/app/res/drawable/ic_connect_message_file.xml
new file mode 100644
index 0000000000..73f8e7441c
--- /dev/null
+++ b/app/res/drawable/ic_connect_message_file.xml
@@ -0,0 +1,9 @@
+
+
+
diff --git a/app/res/drawable/ic_connect_message_pause.xml b/app/res/drawable/ic_connect_message_pause.xml
new file mode 100644
index 0000000000..21e450944b
--- /dev/null
+++ b/app/res/drawable/ic_connect_message_pause.xml
@@ -0,0 +1,9 @@
+
+
+
diff --git a/app/res/drawable/ic_connect_message_play.xml b/app/res/drawable/ic_connect_message_play.xml
new file mode 100644
index 0000000000..9e4b93f843
--- /dev/null
+++ b/app/res/drawable/ic_connect_message_play.xml
@@ -0,0 +1,9 @@
+
+
+
diff --git a/app/res/drawable/ic_connect_message_retry.xml b/app/res/drawable/ic_connect_message_retry.xml
new file mode 100644
index 0000000000..59202d9f74
--- /dev/null
+++ b/app/res/drawable/ic_connect_message_retry.xml
@@ -0,0 +1,9 @@
+
+
+
diff --git a/app/res/layout/fragment_connect_message.xml b/app/res/layout/fragment_connect_message.xml
index 2be0d218b9..4f74571a3c 100644
--- a/app/res/layout/fragment_connect_message.xml
+++ b/app/res/layout/fragment_connect_message.xml
@@ -15,11 +15,28 @@
android:overScrollMode="never"
android:paddingBottom="10dp"
app:layoutManager="androidx.recyclerview.widget.LinearLayoutManager"
- app:layout_constraintBottom_toTopOf="@+id/cardMessage"
+ app:layout_constraintBottom_toTopOf="@+id/tvUpdateBanner"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent" />
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/app/res/layout/fragment_connect_messaging_settings.xml b/app/res/layout/fragment_connect_messaging_settings.xml
new file mode 100644
index 0000000000..b7407c5f98
--- /dev/null
+++ b/app/res/layout/fragment_connect_messaging_settings.xml
@@ -0,0 +1,66 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/app/res/layout/item_chat_left_rich_view.xml b/app/res/layout/item_chat_left_rich_view.xml
new file mode 100644
index 0000000000..f9d0880a3e
--- /dev/null
+++ b/app/res/layout/item_chat_left_rich_view.xml
@@ -0,0 +1,72 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/app/res/layout/view_connect_message_attachment_audio.xml b/app/res/layout/view_connect_message_attachment_audio.xml
new file mode 100644
index 0000000000..d4fab8b57a
--- /dev/null
+++ b/app/res/layout/view_connect_message_attachment_audio.xml
@@ -0,0 +1,47 @@
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/app/res/layout/view_connect_message_attachment_file.xml b/app/res/layout/view_connect_message_attachment_file.xml
new file mode 100644
index 0000000000..011bb5eeff
--- /dev/null
+++ b/app/res/layout/view_connect_message_attachment_file.xml
@@ -0,0 +1,41 @@
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/app/res/layout/view_connect_message_attachment_image.xml b/app/res/layout/view_connect_message_attachment_image.xml
new file mode 100644
index 0000000000..2adfc34ad2
--- /dev/null
+++ b/app/res/layout/view_connect_message_attachment_image.xml
@@ -0,0 +1,8 @@
+
+
diff --git a/app/res/layout/view_connect_message_attachment_pending.xml b/app/res/layout/view_connect_message_attachment_pending.xml
new file mode 100644
index 0000000000..07467c5288
--- /dev/null
+++ b/app/res/layout/view_connect_message_attachment_pending.xml
@@ -0,0 +1,55 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/app/res/navigation/nav_graph_connect_messaging.xml b/app/res/navigation/nav_graph_connect_messaging.xml
index 29aab22a9b..b4346ed85e 100644
--- a/app/res/navigation/nav_graph_connect_messaging.xml
+++ b/app/res/navigation/nav_graph_connect_messaging.xml
@@ -13,8 +13,17 @@
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/app/res/values-es/strings.xml b/app/res/values-es/strings.xml
index fe893e7c91..af5a4db61f 100644
--- a/app/res/values-es/strings.xml
+++ b/app/res/values-es/strings.xml
@@ -759,4 +759,23 @@
Guardar
Pausar
Reanudar
+ Descargar
+ Descargando…
+ Error en la descarga
+ Toca para reintentar
+ Ya no está disponible
+ Ninguna aplicación de este teléfono puede abrir este archivo
+ Reproducir audio
+ Pausar audio
+ No se pudo reproducir este audio
+ Tu aplicación de Android debe actualizarse para ver este mensaje
+ Actualiza la aplicación para ver todos los mensajes de este canal
+ [Actualiza la aplicación para ver este mensaje]
+ Ajustes de mensajería
+ Con Wi-Fi y datos móviles
+ Los archivos adjuntos que toques siempre se descargan de inmediato, en cualquier red.
+ Descargar archivos adjuntos automáticamente
+ Archivos adjuntos grandes (más de 1 MB) solo con Wi-Fi
+ Solo descarga manual
+ [Mensaje multimedia por descargar]
diff --git a/app/res/values-fr/strings.xml b/app/res/values-fr/strings.xml
index e2262ba6bd..8aa45911c5 100644
--- a/app/res/values-fr/strings.xml
+++ b/app/res/values-fr/strings.xml
@@ -758,4 +758,23 @@ License.
Enregistrer
Pause
Reprendre
+ Télécharger
+ Téléchargement…
+ Échec du téléchargement
+ Appuyez pour réessayer
+ N\'est plus disponible
+ Aucune application sur ce téléphone ne peut ouvrir ce fichier
+ Lire l\'audio
+ Mettre l\'audio en pause
+ Impossible de lire cet audio
+ Votre application Android doit être mise à jour pour afficher ce message
+ Mettez l\'application à jour pour voir tous les messages de ce canal
+ [Mettez l\'application à jour pour voir ce message]
+ Paramètres de messagerie
+ En Wi-Fi et données mobiles
+ Les pièces jointes sur lesquelles vous appuyez sont toujours téléchargées immédiatement, sur n\'importe quel réseau.
+ Télécharger automatiquement les pièces jointes
+ Pièces jointes volumineuses (plus de 1 Mo) uniquement en Wi-Fi
+ Téléchargement manuel uniquement
+ [Message multimédia à télécharger]
diff --git a/app/res/values-ha/strings.xml b/app/res/values-ha/strings.xml
index c7c0688b93..f3051ff493 100644
--- a/app/res/values-ha/strings.xml
+++ b/app/res/values-ha/strings.xml
@@ -753,4 +753,23 @@ Don cikakken aiki na wurin zama na aikace-aikace da yawa, da fatan za a yi sabon
Ajiye
Dakata
Ci gaba
+ Sauke
+ Ana saukewa…
+ Saukewa ta kasa
+ Taɓa don sake gwadawa
+ Ba a samunsa yanzu
+ Babu wata manhaja a wannan wayar da za ta iya buɗe wannan fayil
+ Kunna sauti
+ Dakatar da sauti
+ Ba a iya kunna wannan sautin ba
+ Ana buƙatar sabunta manhajar Android ɗinka don ganin wannan saƙon
+ Sabunta manhajar don ganin dukkan saƙonni a wannan tasha
+ [Sabunta manhajar don ganin wannan saƙon]
+ Saitunan saƙonni
+ A Wi-Fi da bayanan waya
+ Haɗe-haɗen da ka taɓa ana saukewa nan take koyaushe, a kowace hanyar sadarwa.
+ Sauke haɗe-haɗe kai tsaye
+ Manyan haɗe-haɗe (sama da MB 1) a Wi-Fi kawai
+ Saukewa da hannu kawai
+ [Saƙon kafofin watsa labarai don saukewa]
diff --git a/app/res/values-hi/strings.xml b/app/res/values-hi/strings.xml
index 6e2b216b6b..0989002f06 100644
--- a/app/res/values-hi/strings.xml
+++ b/app/res/values-hi/strings.xml
@@ -755,4 +755,23 @@ License.
सहेजें
रोकें
फिर से शुरू करें
+ डाउनलोड करें
+ डाउनलोड हो रहा है…
+ डाउनलोड विफल रहा
+ फिर से कोशिश करने के लिए टैप करें
+ अब उपलब्ध नहीं है
+ इस फ़ोन पर कोई भी ऐप यह फ़ाइल नहीं खोल सकता
+ ऑडियो चलाएं
+ ऑडियो रोकें
+ यह ऑडियो नहीं चलाया जा सका
+ यह संदेश देखने के लिए आपके Android ऐप को अपडेट करना होगा
+ इस चैनल के सभी संदेश देखने के लिए ऐप अपडेट करें
+ [यह संदेश देखने के लिए ऐप अपडेट करें]
+ संदेश सेटिंग
+ वाई-फ़ाई और मोबाइल डेटा पर
+ जिन अटैचमेंट पर आप टैप करते हैं, वे हमेशा किसी भी नेटवर्क पर तुरंत डाउनलोड होते हैं।
+ अटैचमेंट अपने-आप डाउनलोड करें
+ बड़े अटैचमेंट (1 MB से ज़्यादा) केवल वाई-फ़ाई पर
+ केवल मैन्युअल डाउनलोड
+ [डाउनलोड करने के लिए मीडिया संदेश]
diff --git a/app/res/values-lt/strings.xml b/app/res/values-lt/strings.xml
index db81f04823..b9fc0b3ae8 100644
--- a/app/res/values-lt/strings.xml
+++ b/app/res/values-lt/strings.xml
@@ -469,4 +469,23 @@
Išsaugoti
Pristabdyti
Tęsti
+ Atsisiųsti
+ Atsisiunčiama…
+ Nepavyko atsisiųsti
+ Palieskite, kad bandytumėte dar kartą
+ Nebepasiekiama
+ Jokia šio telefono programa negali atidaryti šio failo
+ Leisti garso įrašą
+ Pristabdyti garso įrašą
+ Nepavyko paleisti šio garso įrašo
+ Kad pamatytumėte šią žinutę, reikia atnaujinti jūsų Android programą
+ Atnaujinkite programą, kad pamatytumėte visas šio kanalo žinutes
+ [Atnaujinkite programą, kad pamatytumėte šią žinutę]
+ Žinučių nustatymai
+ Per „Wi-Fi“ ir mobiliuosius duomenis
+ Priedai, kuriuos paliečiate, visada atsisiunčiami iš karto per bet kurį tinklą.
+ Automatiškai atsisiųsti priedus
+ Didelius priedus (daugiau nei 1 MB) tik per „Wi-Fi“
+ Tik rankinis atsisiuntimas
+ [Atsisiųstina medijos žinutė]
diff --git a/app/res/values-no/strings.xml b/app/res/values-no/strings.xml
index f7cc366b00..183cf6e4ce 100644
--- a/app/res/values-no/strings.xml
+++ b/app/res/values-no/strings.xml
@@ -445,4 +445,23 @@
Lagre
Pause
Gjenoppta
+ Last ned
+ Laster ned…
+ Nedlastingen mislyktes
+ Trykk for å prøve igjen
+ Ikke lenger tilgjengelig
+ Ingen app på denne telefonen kan åpne denne filen
+ Spill av lyd
+ Sett lyden på pause
+ Lyden kunne ikke spilles av
+ Android-appen din må oppdateres for å vise denne meldingen
+ Oppdater appen for å se alle meldingene i denne kanalen
+ [Oppdater appen for å se denne meldingen]
+ Meldingsinnstillinger
+ På Wi-Fi og mobildata
+ Vedlegg du trykker på, lastes alltid ned med en gang, på alle nettverk.
+ Last ned vedlegg automatisk
+ Store vedlegg (over 1 MB) bare på Wi-Fi
+ Bare manuell nedlasting
+ [Mediemelding som må lastes ned]
diff --git a/app/res/values-pt/strings.xml b/app/res/values-pt/strings.xml
index 3ee51268a2..0d4bff3480 100644
--- a/app/res/values-pt/strings.xml
+++ b/app/res/values-pt/strings.xml
@@ -765,4 +765,23 @@
Salvar
Pausar
Retomar
+ Baixar
+ Baixando…
+ Falha no download
+ Toque para tentar novamente
+ Não está mais disponível
+ Nenhum aplicativo neste telefone pode abrir este arquivo
+ Reproduzir áudio
+ Pausar áudio
+ Não foi possível reproduzir este áudio
+ Seu aplicativo Android precisa ser atualizado para ver esta mensagem
+ Atualize o aplicativo para ver todas as mensagens deste canal
+ [Atualize o aplicativo para ver esta mensagem]
+ Configurações de mensagens
+ No Wi-Fi e nos dados móveis
+ Os anexos que você tocar são sempre baixados na hora, em qualquer rede.
+ Baixar anexos automaticamente
+ Anexos grandes (mais de 1 MB) somente no Wi-Fi
+ Somente download manual
+ [Mensagem de mídia para baixar]
diff --git a/app/res/values-sw/strings.xml b/app/res/values-sw/strings.xml
index a7c058825b..8aa983329e 100644
--- a/app/res/values-sw/strings.xml
+++ b/app/res/values-sw/strings.xml
@@ -763,4 +763,23 @@
Hifadhi
Sitisha
Endelea
+ Pakua
+ Inapakua…
+ Upakuaji umeshindwa
+ Gusa ili ujaribu tena
+ Haipatikani tena
+ Hakuna programu kwenye simu hii inayoweza kufungua faili hili
+ Cheza sauti
+ Sitisha sauti
+ Sauti hii haikuweza kuchezwa
+ Programu yako ya Android inahitaji kusasishwa ili kuona ujumbe huu
+ Sasisha programu ili kuona jumbe zote katika chaneli hii
+ [Sasisha programu ili kuona ujumbe huu]
+ Mipangilio ya ujumbe
+ Kwenye Wi-Fi na data ya simu
+ Viambatisho unavyogusa hupakuliwa mara moja kila wakati, kwenye mtandao wowote.
+ Pakua viambatisho kiotomatiki
+ Viambatisho vikubwa (zaidi ya MB 1) kwenye Wi-Fi pekee
+ Upakuaji wa mwenyewe pekee
+ [Ujumbe wa media wa kupakua]
diff --git a/app/res/values-ti/strings.xml b/app/res/values-ti/strings.xml
index c97eea3d37..ebace2302c 100644
--- a/app/res/values-ti/strings.xml
+++ b/app/res/values-ti/strings.xml
@@ -747,4 +747,23 @@
ኣቐምጥ
ደው በል
ቐጽል
+ ኣውርድ
+ ይወርድ ኣሎ…
+ ምውራድ ኣይተዓወተን
+ ደጊምካ ንምፍታን ጠውቕ
+ ድሕሪ ሕጂ ኣይርከብን
+ ነዚ ፋይል ክኸፍቶ ዝኽእል ኣፕ ኣብዚ ተሌፎን የለን
+ ድምጺ ተጻወት
+ ድምጺ ደው ኣብል
+ እዚ ድምጺ ክጻወት ኣይከኣለን
+ ነዚ መልእኽቲ ንምርኣይ ናይ Android ኣፕኻ ክሕደስ ኣለዎ
+ ኣብዚ ቻነል ዘለዉ ኩሎም መልእኽቲታት ንምርኣይ ነቲ ኣፕ ኣሐድሶ
+ [ነዚ መልእኽቲ ንምርኣይ ነቲ ኣፕ ኣሐድሶ]
+ ቅጥዕታት መልእኽቲ
+ ብዋይፋይን ሞባይል ዳታን
+ እትጠውቖም ተተሓሒዝቲ ኩሉ ግዜ ብዝኾነ መርበብ ብቕጽበት ይወርዱ።
+ ተተሓሒዝቲ ብኣውቶማቲክ ኣውርድ
+ ዓበይቲ ተተሓሒዝቲ (ካብ 1 MB ንላዕሊ) ብዋይፋይ ጥራይ
+ ብኢድ ምውራድ ጥራይ
+ [ዝወርድ መልእኽቲ ሚድያ]
diff --git a/app/res/values/dimens.xml b/app/res/values/dimens.xml
index 0830f3e881..77445064a6 100755
--- a/app/res/values/dimens.xml
+++ b/app/res/values/dimens.xml
@@ -133,6 +133,17 @@
3dp
1dp
16dp
+ 10dp
+ 3dp
+ 6dp
+ 2dp
+ 7dp
+ 4dp
+ 240dp
+ 128dp
+ 56dp
+ 48dp
+ 4dp
5dp
264dp
diff --git a/app/res/values/strings.xml b/app/res/values/strings.xml
index 0cb1d5da62..6736f74e6a 100644
--- a/app/res/values/strings.xml
+++ b/app/res/values/strings.xml
@@ -500,6 +500,25 @@
Sorry, something went wrong, showing all available messaging channels
You
Them
+ Download
+ Downloading…
+ Download failed
+ Tap to retry
+ No longer available
+ [Media message to download]
+ No app on this phone can open this file
+ Play audio
+ Pause audio
+ This audio could not be played
+ Your Android app needs to be updated to view this message
+ Update the app to see all messages in this channel
+ [Update the app to see this message]
+ Messaging settings
+ Download attachments automatically
+ On Wi-Fi and mobile data
+ Large attachments (over 1 MB) only on Wi-Fi
+ Manual download only
+ Attachments you tap always download right away, on any network.
Click here to know more
Last synced: %s
diff --git a/app/res/values/styles.xml b/app/res/values/styles.xml
index 26249085b0..0a85a2f1d8 100644
--- a/app/res/values/styles.xml
+++ b/app/res/values/styles.xml
@@ -484,4 +484,25 @@
- @style/ConnectBottomSheetAnimation
+
+
+
+
+
+
+
+
diff --git a/app/res/xml/provider_paths.xml b/app/res/xml/provider_paths.xml
index 5749213627..b2c40a3c77 100644
--- a/app/res/xml/provider_paths.xml
+++ b/app/res/xml/provider_paths.xml
@@ -3,4 +3,5 @@
+
diff --git a/app/src/org/commcare/adapters/ConnectMessageAdapter.java b/app/src/org/commcare/adapters/ConnectMessageAdapter.java
index 9929af350c..4bd71469ea 100644
--- a/app/src/org/commcare/adapters/ConnectMessageAdapter.java
+++ b/app/src/org/commcare/adapters/ConnectMessageAdapter.java
@@ -1,20 +1,27 @@
package org.commcare.adapters;
import android.text.SpannableStringBuilder;
+import android.util.DisplayMetrics;
import android.view.LayoutInflater;
+import android.view.View;
import android.view.ViewGroup;
import android.widget.TextView;
import androidx.annotation.NonNull;
import androidx.annotation.Nullable;
+import androidx.constraintlayout.widget.ConstraintLayout;
import androidx.recyclerview.widget.DiffUtil;
import androidx.recyclerview.widget.RecyclerView;
import androidx.viewbinding.ViewBinding;
import org.commcare.dalvik.R;
+import org.commcare.dalvik.databinding.ItemChatLeftRichViewBinding;
import org.commcare.dalvik.databinding.ItemChatLeftViewBinding;
import org.commcare.dalvik.databinding.ItemChatRightViewBinding;
+import org.commcare.fragments.connectMessaging.ConnectMessageAttachmentListener;
+import org.commcare.fragments.connectMessaging.ConnectMessageAttachmentsBinder;
import org.commcare.fragments.connectMessaging.ConnectMessageChatData;
+import org.commcare.fragments.connectMessaging.ConnectMessageMediaSizer;
import org.commcare.utils.MarkupUtil;
import org.javarosa.core.model.utils.DateUtils;
@@ -26,18 +33,20 @@ public class ConnectMessageAdapter extends RecyclerView.Adapter messages;
+ private final ConnectMessageAttachmentListener attachmentListener;
- public ConnectMessageAdapter(List messages) {
+ public ConnectMessageAdapter(List messages,
+ ConnectMessageAttachmentListener attachmentListener) {
this.messages = messages;
+ this.attachmentListener = attachmentListener;
}
- /**
- * Applies the new message list as a diff against the displayed one.
- *
- * @return true if the new list contains a message that was not already displayed
- */
public boolean updateData(List newMessages) {
DiffUtil.DiffResult diff = DiffUtil.calculateDiff(
new MessageDiffCallback(messages, newMessages));
@@ -101,6 +110,7 @@ public boolean areContentsTheSame(int oldItemPosition, int newItemPosition) {
ConnectMessageChatData oldChat = oldMessages.get(oldItemPosition);
ConnectMessageChatData newChat = newMessages.get(newItemPosition);
return hasSameDisplayContent(oldChat, newChat)
+ && hasSameAttachmentContent(oldChat, newChat)
&& oldChat.isMessageRead() == newChat.isMessageRead();
}
@@ -109,14 +119,27 @@ public boolean areContentsTheSame(int oldItemPosition, int newItemPosition) {
public Object getChangePayload(int oldItemPosition, int newItemPosition) {
ConnectMessageChatData oldChat = oldMessages.get(oldItemPosition);
ConnectMessageChatData newChat = newMessages.get(newItemPosition);
- return hasSameDisplayContent(oldChat, newChat) ? PAYLOAD_READ_STATUS : null;
+ if (!hasSameDisplayContent(oldChat, newChat)) {
+ return null;
+ }
+ if (!hasSameAttachmentContent(oldChat, newChat)) {
+ return oldChat.hasRichContent() && newChat.hasRichContent() ? PAYLOAD_ATTACHMENTS : null;
+ }
+ return PAYLOAD_READ_STATUS;
+ }
+
+ private static boolean hasSameAttachmentContent(ConnectMessageChatData oldChat,
+ ConnectMessageChatData newChat) {
+ return oldChat.getAttachments().equals(newChat.getAttachments())
+ && oldChat.getPendingDownloadState() == newChat.getPendingDownloadState();
}
private static boolean hasSameDisplayContent(ConnectMessageChatData oldChat,
ConnectMessageChatData newChat) {
return oldChat.getType() == newChat.getType()
&& Objects.equals(oldChat.getMessage(), newChat.getMessage())
- && Objects.equals(oldChat.getTimestamp(), newChat.getTimestamp());
+ && Objects.equals(oldChat.getTimestamp(), newChat.getTimestamp())
+ && oldChat.isUnsupportedVersion() == newChat.isUnsupportedVersion();
}
}
@@ -133,6 +156,90 @@ public RightViewHolder(ItemChatRightViewBinding binding) {
}
}
+ public class RichLeftViewHolder extends BaseMessageViewHolder {
+ private final ItemChatLeftRichViewBinding richBinding;
+ private final ViewGroup messageList;
+ private final ConnectMessageAttachmentsBinder attachmentsBinder;
+
+ public RichLeftViewHolder(ItemChatLeftRichViewBinding binding, ViewGroup messageList) {
+ super(binding);
+ this.richBinding = binding;
+ this.messageList = messageList;
+ this.attachmentsBinder = new ConnectMessageAttachmentsBinder(binding.llAttachments,
+ attachmentListener);
+ }
+
+ @Override
+ public void bind(ConnectMessageChatData chat) {
+ super.bind(chat);
+ bindAttachments(chat);
+ }
+
+ public void bindAttachments(ConnectMessageChatData chat) {
+ boolean unsupported = chat.isUnsupportedVersion();
+ boolean awaitingDownload = chat.isAwaitingDownload();
+ boolean showsTile = unsupported || awaitingDownload;
+ boolean hasAttachments = showsTile || !chat.getAttachments().isEmpty();
+ boolean hasText = chat.getMessage() != null && !chat.getMessage().trim().isEmpty();
+ richBinding.tvChatMessage.setVisibility(showsTile || !hasText ? View.GONE : View.VISIBLE);
+ ConstraintLayout.LayoutParams guidelineParams =
+ (ConstraintLayout.LayoutParams)richBinding.guideline.getLayoutParams();
+ guidelineParams.guidePercent = hasAttachments
+ ? MEDIA_BUBBLE_WIDTH_FRACTION
+ : TEXT_BUBBLE_WIDTH_FRACTION;
+ richBinding.guideline.setLayoutParams(guidelineParams);
+
+ ConnectMessageAttachmentsBinder.Layout layout;
+ if (unsupported) {
+ layout = attachmentsBinder.bindUnsupportedMessage();
+ } else if (awaitingDownload) {
+ layout = attachmentsBinder.bindPendingMessage(chat.getMessageId(), chat.getPendingDownloadState());
+ } else {
+ layout = attachmentsBinder.bind(chat.getAttachments(), maxMediaWidth(), maxMediaHeight());
+ }
+
+ ViewGroup.LayoutParams bubbleParams = richBinding.llBubble.getLayoutParams();
+ bubbleParams.width = layout.getFillsBubbleWidth()
+ ? ViewGroup.LayoutParams.MATCH_PARENT
+ : ViewGroup.LayoutParams.WRAP_CONTENT;
+ richBinding.llBubble.setLayoutParams(bubbleParams);
+ richBinding.tvChatMessage.setMaxWidth(hasAttachments && !layout.getFillsBubbleWidth()
+ ? Math.max(layout.getContentWidth(), bubbleContentWidth(TEXT_BUBBLE_WIDTH_FRACTION))
+ : Integer.MAX_VALUE);
+ }
+
+ private int maxMediaWidth() {
+ return bubbleContentWidth(MEDIA_BUBBLE_WIDTH_FRACTION);
+ }
+
+ private int listWidth() {
+ if (messageList instanceof RecyclerView) {
+ RecyclerView.LayoutManager layoutManager = ((RecyclerView)messageList).getLayoutManager();
+ if (layoutManager != null && layoutManager.getWidth() > 0) {
+ return layoutManager.getWidth();
+ }
+ }
+ return messageList.getWidth() > 0 ? messageList.getWidth() : displayMetrics().widthPixels;
+ }
+
+ private int bubbleContentWidth(float bubbleWidthFraction) {
+ int rowWidth = listWidth();
+ int rowMargins = 2 * itemView.getResources().getDimensionPixelSize(R.dimen.spacer_small);
+ int bubblePadding = 2 * itemView.getResources().getDimensionPixelSize(R.dimen.connect_message_bubble_padding);
+ int tailWidth = richBinding.edge.getDrawable().getIntrinsicWidth();
+ return Math.max(1, (int)(rowWidth * bubbleWidthFraction) - rowMargins - tailWidth - bubblePadding);
+ }
+
+ private int maxMediaHeight() {
+ return Math.max(1, (int)(displayMetrics().heightPixels
+ * ConnectMessageMediaSizer.MAX_HEIGHT_FRACTION_OF_WINDOW));
+ }
+
+ private DisplayMetrics displayMetrics() {
+ return itemView.getResources().getDisplayMetrics();
+ }
+ }
+
public class BaseMessageViewHolder extends RecyclerView.ViewHolder {
ViewBinding binding;
@@ -150,6 +257,9 @@ public void bind(ConnectMessageChatData chat) {
if (binding instanceof ItemChatLeftViewBinding) {
tvChatMessage = ((ItemChatLeftViewBinding)binding).tvChatMessage;
tvChatDate = ((ItemChatLeftViewBinding)binding).tvChatDate;
+ } else if (binding instanceof ItemChatLeftRichViewBinding) {
+ tvChatMessage = ((ItemChatLeftRichViewBinding)binding).tvChatMessage;
+ tvChatDate = ((ItemChatLeftRichViewBinding)binding).tvChatDate;
} else {
tvChatMessage = ((ItemChatRightViewBinding)binding).tvChatMessage;
tvChatDate = ((ItemChatRightViewBinding)binding).tvChatDate;
@@ -173,31 +283,30 @@ public void bindReadStatus(ConnectMessageChatData chat) {
@NonNull
@Override
public BaseMessageViewHolder onCreateViewHolder(@NonNull ViewGroup parent, int viewType) {
- if (viewType == LEFTVIEW) {
- ItemChatLeftViewBinding binding = ItemChatLeftViewBinding.inflate(
- LayoutInflater.from(parent.getContext()), parent, false);
+ LayoutInflater inflater = LayoutInflater.from(parent.getContext());
+ if (viewType == LEFT_RICH_VIEW) {
+ ItemChatLeftRichViewBinding binding = ItemChatLeftRichViewBinding.inflate(inflater, parent, false);
+ return new RichLeftViewHolder(binding, parent);
+ } else if (viewType == LEFTVIEW) {
+ ItemChatLeftViewBinding binding = ItemChatLeftViewBinding.inflate(inflater, parent, false);
return new LeftViewHolder(binding);
} else {
- ItemChatRightViewBinding binding = ItemChatRightViewBinding.inflate(
- LayoutInflater.from(parent.getContext()), parent, false);
+ ItemChatRightViewBinding binding = ItemChatRightViewBinding.inflate(inflater, parent, false);
return new RightViewHolder(binding);
}
}
@Override
public void onBindViewHolder(@NonNull RecyclerView.ViewHolder holder, int position) {
- ConnectMessageChatData chat = messages.get(position);
- if (getItemViewType(position) == LEFTVIEW) {
- ((LeftViewHolder)holder).bind(chat);
- } else {
- ((RightViewHolder)holder).bind(chat);
- }
+ ((BaseMessageViewHolder)holder).bind(messages.get(position));
}
@Override
public void onBindViewHolder(@NonNull RecyclerView.ViewHolder holder, int position,
@NonNull List