Show event at top of conversation in case of unsecure conversation (like we do for e2e encrypted ones) + icon under conversation title

This commit is contained in:
Sylvain Berfini 2025-06-16 11:28:16 +02:00
parent b7a9f4ba8e
commit 3c40bf3d6f
14 changed files with 143 additions and 31 deletions

View file

@ -36,6 +36,7 @@ import org.linphone.databinding.ChatBubbleIncomingBinding
import org.linphone.databinding.ChatBubbleOutgoingBinding
import org.linphone.databinding.ChatConversationEventBinding
import org.linphone.databinding.ChatConversationE2eEncryptedFirstEventBinding
import org.linphone.databinding.ChatConversationUnsafeFirstEventBinding
import org.linphone.ui.main.chat.model.EventLogModel
import org.linphone.ui.main.chat.model.EventModel
import org.linphone.ui.main.chat.model.MessageModel
@ -82,7 +83,11 @@ class ConversationEventAdapter :
}
override fun getHeaderViewForPosition(context: Context, position: Int): View {
val binding = ChatConversationE2eEncryptedFirstEventBinding.inflate(LayoutInflater.from(context))
val binding = if (isConversationSecured) {
ChatConversationE2eEncryptedFirstEventBinding.inflate(LayoutInflater.from(context))
} else {
ChatConversationUnsafeFirstEventBinding.inflate(LayoutInflater.from(context))
}
return binding.root
}

View file

@ -315,6 +315,8 @@ open class ConversationFragment : SlidingPaneChildFragment() {
if (e.y >= 0 && e.y <= headerItemDecoration.getDecorationHeight(0)) {
if (viewModel.isEndToEndEncrypted.value == true) {
showEndToEndEncryptionDetailsBottomSheet()
} else {
showUnsafeConversationDisabledDetailsBottomSheet()
}
return true
}
@ -588,8 +590,7 @@ open class ConversationFragment : SlidingPaneChildFragment() {
viewModel.isEndToEndEncrypted.observe(viewLifecycleOwner) { encrypted ->
adapter.setIsConversationSecured(encrypted)
if (encrypted) {
if (encrypted || (!encrypted && viewModel.isEndToEndEncryptionAvailable.value == true)) {
binding.eventsList.addItemDecoration(headerItemDecoration)
binding.eventsList.addOnItemTouchListener(listItemTouchListener)
}

View file

@ -1,9 +0,0 @@
<vector xmlns:android="http://schemas.android.com/apk/res/android"
android:width="24dp"
android:height="24dp"
android:viewportWidth="256"
android:viewportHeight="256">
<path
android:pathData="M208,76H180V56A52,52 0,0 0,76 56V76H48A20,20 0,0 0,28 96V208a20,20 0,0 0,20 20H208a20,20 0,0 0,20 -20V96A20,20 0,0 0,208 76ZM100,56a28,28 0,0 1,56 0V76H100ZM204,204H52V100H204Z"
android:fillColor="#4e6074"/>
</vector>

View file

@ -0,0 +1,9 @@
<vector xmlns:android="http://schemas.android.com/apk/res/android"
android:width="24dp"
android:height="24dp"
android:viewportWidth="256"
android:viewportHeight="256">
<path
android:pathData="M208,80L96,80L96,56a32,32 0,0 1,32 -32c15.37,0 29.2,11 32.16,25.59a8,8 0,0 0,15.68 -3.18C171.32,24.15 151.2,8 128,8A48.05,48.05 0,0 0,80 56L80,80L48,80A16,16 0,0 0,32 96L32,208a16,16 0,0 0,16 16L208,224a16,16 0,0 0,16 -16L224,96A16,16 0,0 0,208 80ZM208,208L48,208L48,96L208,96L208,208Z"
android:fillColor="#4e6074"/>
</vector>

View file

@ -1,9 +0,0 @@
<vector xmlns:android="http://schemas.android.com/apk/res/android"
android:width="24dp"
android:height="24dp"
android:viewportWidth="256"
android:viewportHeight="256">
<path
android:pathData="M208,76L100,76L100,56a28,28 0,0 1,28 -28c13.51,0 25.65,9.62 28.24,22.39a12,12 0,1 0,23.52 -4.78C174.87,21.5 153.1,4 128,4A52.06,52.06 0,0 0,76 56L76,76L48,76A20,20 0,0 0,28 96L28,208a20,20 0,0 0,20 20L208,228a20,20 0,0 0,20 -20L228,96A20,20 0,0 0,208 76ZM204,204L52,204L52,100L204,100Z"
android:fillColor="#4e6074"/>
</vector>

View file

@ -75,7 +75,7 @@
android:adjustViewBounds="true"
android:paddingTop="3dp"
android:contentDescription="@null"
android:src="@drawable/lock_simple_open_bold"
android:src="@drawable/lock_simple_open"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="@id/no_media_encryption_label"
app:layout_constraintBottom_toBottomOf="@id/no_media_encryption_label"

View file

@ -33,7 +33,7 @@
android:paddingTop="3dp"
android:adjustViewBounds="true"
android:contentDescription="@null"
android:src="@drawable/lock_simple_bold"
android:src="@drawable/lock_simple"
app:tint="@color/blue_info_500"
app:layout_constraintTop_toTopOf="@id/secured_title"
app:layout_constraintBottom_toBottomOf="@id/secured_subtitle"

View file

@ -119,7 +119,7 @@
android:layout_width="wrap_content"
android:layout_height="wrap_content"
app:barrierDirection="top"
app:constraint_referenced_ids="muted, ephemeral_enabled" />
app:constraint_referenced_ids="unsecure, unsecure_label, muted, ephemeral_enabled, ephemeral_duration" />
<ImageView
android:id="@+id/muted"
@ -130,11 +130,43 @@
android:contentDescription="@string/content_description_chat_muted"
android:visibility="@{viewModel.isMuted ? View.VISIBLE : View.GONE, default=gone}"
app:layout_constraintStart_toStartOf="@id/title"
app:layout_constraintEnd_toStartOf="@id/ephemeral_enabled"
app:layout_constraintEnd_toStartOf="@id/unsecure"
app:layout_constraintTop_toBottomOf="@id/title"
app:layout_constraintBottom_toBottomOf="@id/avatar"
app:tint="?attr/color_main1_500"/>
<ImageView
android:id="@+id/unsecure"
android:layout_width="@dimen/small_icon_size"
android:layout_height="@dimen/small_icon_size"
android:src="@drawable/lock_simple_open"
android:contentDescription="@string/content_description_chat_unsecured"
android:visibility="@{!viewModel.isEndToEndEncrypted &amp;&amp; viewModel.isEndToEndEncryptionAvailable ? View.VISIBLE : View.GONE, default=gone}"
app:layout_constraintStart_toEndOf="@id/muted"
app:layout_constraintEnd_toStartOf="@id/unsecure_label"
app:layout_constraintTop_toBottomOf="@id/title"
app:layout_constraintBottom_toBottomOf="@id/avatar"
app:tint="?attr/color_warning_600"/>
<androidx.appcompat.widget.AppCompatTextView
style="@style/default_text_style"
android:id="@+id/unsecure_label"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginStart="5dp"
android:layout_marginEnd="5dp"
android:paddingBottom="2dp"
android:text="@string/conversation_warning_unsafe_bottom_sheet_title"
android:textSize="12sp"
android:textColor="?attr/color_warning_600"
android:maxLines="1"
android:ellipsize="end"
android:visibility="@{!viewModel.isEndToEndEncrypted &amp;&amp; viewModel.isEndToEndEncryptionAvailable ? View.VISIBLE : View.GONE, default=gone}"
app:layout_constraintStart_toEndOf="@id/unsecure"
app:layout_constraintEnd_toStartOf="@id/ephemeral_enabled"
app:layout_constraintTop_toTopOf="@id/unsecure"
app:layout_constraintBottom_toBottomOf="@id/unsecure"/>
<ImageView
android:id="@+id/ephemeral_enabled"
android:layout_width="@dimen/small_icon_size"
@ -144,7 +176,7 @@
android:src="@drawable/clock_countdown"
android:contentDescription="@string/content_description_chat_ephemeral_enabled"
android:visibility="@{viewModel.ephemeralLifetime > 0L ? View.VISIBLE : View.GONE, default=gone}"
app:layout_constraintStart_toEndOf="@id/muted"
app:layout_constraintStart_toEndOf="@id/unsecure_label"
app:layout_constraintTop_toBottomOf="@id/title"
app:layout_constraintBottom_toBottomOf="@id/avatar"
app:tint="?attr/color_main1_500"/>
@ -159,6 +191,8 @@
android:paddingBottom="2dp"
android:text="@{viewModel.ephemeralLifeTimeLabel, default=`1 day`}"
android:textSize="12sp"
android:maxLines="1"
android:ellipsize="end"
android:visibility="@{viewModel.ephemeralLifetime > 0L ? View.VISIBLE : View.GONE, default=gone}"
app:layout_constraintStart_toEndOf="@id/ephemeral_enabled"
app:layout_constraintTop_toTopOf="@id/ephemeral_enabled"

View file

@ -33,7 +33,7 @@
android:paddingTop="3dp"
android:adjustViewBounds="true"
android:contentDescription="@null"
android:src="@drawable/lock_simple_open_bold"
android:src="@drawable/lock_simple_open"
app:tint="@color/orange_warning_600"
app:layout_constraintTop_toTopOf="@id/disabled_title"
app:layout_constraintBottom_toBottomOf="@id/disabled_subtitle"

View file

@ -24,7 +24,7 @@
android:layout_marginStart="16dp"
android:layout_marginEnd="16dp"
android:gravity="center"
android:text="@string/conversation_warning_disabled_encrypted_bottom_sheet_title"
android:text="@string/conversation_warning_unsafe_bottom_sheet_title"
android:textSize="16sp"
app:layout_constraintTop_toTopOf="parent"
app:layout_constraintStart_toStartOf="parent"
@ -51,7 +51,7 @@
android:layout_marginStart="16dp"
android:layout_marginEnd="16dp"
android:gravity="center"
android:text="@string/conversation_warning_disabled_encrypted_bottom_sheet_message"
android:text="@string/conversation_warning_unsafe_bottom_sheet_message"
android:textSize="12sp"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintEnd_toEndOf="parent"

View file

@ -0,0 +1,75 @@
<?xml version="1.0" encoding="utf-8"?>
<layout
xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto">
<data>
</data>
<androidx.constraintlayout.widget.ConstraintLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:paddingTop="5dp"
android:paddingBottom="10dp">
<ImageView
android:id="@+id/unsafe_background"
android:layout_width="0dp"
android:layout_height="0dp"
android:contentDescription="@null"
android:layout_marginStart="15dp"
android:layout_marginEnd="15dp"
android:background="@drawable/shape_squircle_main2_200_chat_event_border"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintTop_toTopOf="parent"
app:layout_constraintBottom_toBottomOf="parent"/>
<ImageView
android:id="@+id/unsafe_icon"
android:layout_width="@dimen/icon_size"
android:layout_height="wrap_content"
android:layout_marginStart="15dp"
android:paddingTop="3dp"
android:adjustViewBounds="true"
android:contentDescription="@null"
android:src="@drawable/lock_simple_open"
app:tint="@color/orange_warning_600"
app:layout_constraintTop_toTopOf="@id/unsafe_title"
app:layout_constraintBottom_toBottomOf="@id/unsafe_subtitle"
app:layout_constraintStart_toStartOf="@id/unsafe_background"/>
<androidx.appcompat.widget.AppCompatTextView
style="@style/default_text_style_700"
android:id="@+id/unsafe_title"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_marginTop="10dp"
android:layout_marginStart="8dp"
android:layout_marginEnd="15dp"
android:text="@string/conversation_warning_disabled_because_not_secured_title"
android:textSize="12sp"
android:textColor="@color/orange_warning_600"
app:layout_constraintStart_toEndOf="@id/unsafe_icon"
app:layout_constraintEnd_toEndOf="@id/unsafe_background"
app:layout_constraintTop_toTopOf="parent"/>
<androidx.appcompat.widget.AppCompatTextView
style="@style/default_text_style"
android:id="@+id/unsafe_subtitle"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_marginStart="8dp"
android:layout_marginBottom="10dp"
android:layout_marginEnd="15dp"
android:text="@string/conversation_warning_unsafe_event_subtitle"
android:textColor="?attr/color_grey_400"
android:textSize="12sp"
app:layout_constraintStart_toEndOf="@id/unsafe_icon"
app:layout_constraintEnd_toEndOf="@id/unsafe_background"
app:layout_constraintTop_toBottomOf="@id/unsafe_title"
app:layout_constraintBottom_toBottomOf="parent"/>
</androidx.constraintlayout.widget.ConstraintLayout>
</layout>

View file

@ -201,7 +201,7 @@
android:layout_height="@dimen/small_icon_size"
android:layout_marginStart="5dp"
android:layout_marginEnd="10dp"
android:src="@drawable/lock_simple_open_bold"
android:src="@drawable/lock_simple_open"
android:contentDescription="@string/content_description_chat_unsecured"
android:visibility="@{model.isEncrypted || !model.isEncryptionAvailable ? View.GONE : View.VISIBLE}"
app:layout_constraintTop_toBottomOf="@id/date_time"

View file

@ -495,6 +495,9 @@
<string name="conversation_end_to_end_encrypted_event_subtitle">Les messages de cette conversation sont chiffrés de bout en bout. Seul votre correspondant peut les déchiffrer.</string>
<string name="conversation_end_to_end_encrypted_bottom_sheet_title">La confidentialité de vos échanges garantie</string>
<string name="conversation_end_to_end_encrypted_bottom_sheet_message">Grâce à la technologie de chiffrement de bout en bout de &appName;, la confidentialité de vos messages, appels et réunions avec vos correspondants est garantie. Personne ne pourra déchiffrer vos conversations, pas même &appName;.</string>
<string name="conversation_warning_unsafe_event_subtitle">Les messages ne sont pas chiffrés, assurez-vous de ne pas partager d\'informations sensibles !</string>
<string name="conversation_warning_unsafe_bottom_sheet_title">Conversation non chiffrée</string>
<string name="conversation_warning_unsafe_bottom_sheet_message">Les messages échangés dans cette conversation peuvent être interceptés et consultés par des personnes autres que le destinataire désiré, la confidentialité n\'est pas garantie !</string>
<string name="conversation_warning_disabled_because_not_secured_title">Cette conversation n\'est pas chiffrée !</string>
<string name="conversation_warning_disabled_because_not_secured_subtitle">Cette conversation a été désactivée pour garantir votre sécurité.</string>
<string name="conversation_warning_disabled_encrypted_bottom_sheet_title">Chiffrement obligatoire</string>

View file

@ -537,10 +537,13 @@
<string name="conversation_end_to_end_encrypted_event_subtitle">Messages in this conversation are e2e encrypted. Only your correspondent can decrypt them.</string>
<string name="conversation_end_to_end_encrypted_bottom_sheet_title">Guaranteed confidentiality</string>
<string name="conversation_end_to_end_encrypted_bottom_sheet_message">Thanks to end-to-end encryption technology in &appName;, messages, calls and meetings confidentiality are guaranteed. No-one can decrypt exchanged data, not even ourselves.</string>
<string name="conversation_warning_unsafe_event_subtitle">Messages aren\'t encrypted, make sure you don\'t share sensitive information!</string>
<string name="conversation_warning_unsafe_bottom_sheet_title">Unencrypted conversation</string>
<string name="conversation_warning_unsafe_bottom_sheet_message">Messages exchanged in this conversation can be intercepted and read by other people than your correspondent, confidentiality is not guaranteed!</string>
<string name="conversation_warning_disabled_because_not_secured_title">This conversation is not encrypted!</string>
<string name="conversation_warning_disabled_because_not_secured_subtitle">For your safety, this conversation was disabled.</string>
<string name="conversation_warning_disabled_encrypted_bottom_sheet_title">Mandatory encryption</string>
<string name="conversation_warning_disabled_encrypted_bottom_sheet_message">You enabled mandatory encryption. Non encrypted conversations are disabled for your safety. You can re-create this conversation or disable mandatory encryption in your account parameters.</string>
<string name="conversation_warning_disabled_encrypted_bottom_sheet_message">You enabled mandatory encryption. Unencrypted conversations are disabled for your safety. You can re-create this conversation or disable mandatory encryption in your account parameters.</string>
<string name="conversation_maximum_number_of_attachments_reached">Maximum number of attachments reached!</string>
<string name="conversation_dialog_set_subject">Set conversation subject</string>
<string name="conversation_dialog_edit_subject">Edit conversation subject</string>