linphone-android/app/src/main/res/layout/chat_conversation_fragment.xml
2026-03-02 11:17:04 +01:00

421 lines
No EOL
23 KiB
XML

<?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"
xmlns:bind="http://schemas.android.com/tools">
<data>
<import type="android.view.View" />
<variable
name="backClickListener"
type="View.OnClickListener" />
<variable
name="goToInfoClickListener"
type="View.OnClickListener" />
<variable
name="showMenuClickListener"
type="View.OnClickListener" />
<variable
name="openMediaPickerClickListener"
type="View.OnClickListener" />
<variable
name="openCameraClickListener"
type="View.OnClickListener" />
<variable
name="openFilePickerClickListener"
type="View.OnClickListener" />
<variable
name="scrollToBottomClickListener"
type="View.OnClickListener" />
<variable
name="endToEndEncryptedEventClickListener"
type="View.OnClickListener" />
<variable
name="warningConversationDisabledClickListener"
type="View.OnClickListener" />
<variable
name="viewModel"
type="org.linphone.ui.main.chat.viewmodel.ConversationViewModel" />
<variable
name="sendMessageViewModel"
type="org.linphone.ui.main.chat.viewmodel.SendMessageInConversationViewModel" />
<variable
name="messageLongPressViewModel"
type="org.linphone.ui.main.chat.viewmodel.ChatMessageLongPressViewModel" />
</data>
<FrameLayout
android:layout_width="match_parent"
android:layout_height="match_parent">
<androidx.coordinatorlayout.widget.CoordinatorLayout
android:id="@+id/coordinator_layout"
android:layout_width="match_parent"
android:layout_height="match_parent">
<androidx.constraintlayout.widget.ConstraintLayout
android:id="@+id/constraint_layout"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:background="?attr/color_background_contrast_in_dark_mode">
<androidx.constraintlayout.widget.Group
android:layout_width="wrap_content"
android:layout_height="wrap_content"
app:constraint_referenced_ids="avatar, title, show_menu"
android:visibility="@{viewModel.searchBarVisible ? View.GONE : View.VISIBLE}" />
<androidx.constraintlayout.widget.Group
android:layout_width="wrap_content"
android:layout_height="wrap_content"
app:constraint_referenced_ids="cancel_search, search, search_up, search_down"
android:visibility="@{viewModel.searchBarVisible ? View.VISIBLE : View.GONE, default=gone}" />
<ImageView
style="@style/icon_top_bar_button_style"
android:id="@+id/back"
android:layout_width="wrap_content"
android:layout_height="0dp"
android:onClick="@{backClickListener}"
android:visibility="@{viewModel.isCallConversation || viewModel.showBackButton &amp;&amp; !viewModel.searchBarVisible ? View.VISIBLE : View.GONE}"
android:src="@drawable/caret_left"
android:contentDescription="@string/content_description_go_back_icon"
app:tint="?attr/color_main1_500"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent"
app:layout_constraintBottom_toTopOf="@id/events_list"/>
<include
android:id="@+id/avatar"
android:onClick="@{goToInfoClickListener}"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginTop="5dp"
android:layout_marginBottom="5dp"
android:layout_marginStart="@{viewModel.isCallConversation || viewModel.showBackButton ? @dimen/chat_conversation_header_avatar_start_margin_if_back_button : @dimen/chat_conversation_header_avatar_start_margin_if_no_back_button, default=@dimen/chat_conversation_header_avatar_start_margin_if_back_button}"
layout="@layout/contact_avatar"
bind:model="@{viewModel.avatarModel}"
app:layout_constraintStart_toEndOf="@id/back"
app:layout_constraintTop_toTopOf="parent" />
<androidx.appcompat.widget.AppCompatTextView
style="@style/default_text_style"
android:id="@+id/title"
android:onClick="@{goToInfoClickListener}"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_marginStart="10dp"
android:layout_marginEnd="5dp"
android:maxLines="1"
android:ellipsize="end"
android:text="@{viewModel.isGroup ? viewModel.subject : viewModel.avatarModel.name, default=`John Doe`}"
android:textSize="16sp"
android:textColor="?attr/color_main2_600"
android:gravity="center_vertical"
app:layout_constraintEnd_toStartOf="@id/start_call"
app:layout_constraintStart_toEndOf="@id/avatar"
app:layout_constraintTop_toTopOf="@id/avatar"
app:layout_constraintBottom_toTopOf="@id/subtitle_barrier"/>
<androidx.constraintlayout.widget.Barrier
android:id="@+id/subtitle_barrier"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
app:barrierDirection="top"
app:constraint_referenced_ids="unsecure, unsecure_label, muted, ephemeral_enabled, ephemeral_duration" />
<ImageView
android:id="@+id/muted"
android:layout_width="@dimen/small_icon_size"
android:layout_height="@dimen/small_icon_size"
android:layout_marginEnd="5dp"
android:src="@drawable/bell_slash"
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/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_plain_text_security_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_plain_text_security_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"
android:layout_height="@dimen/small_icon_size"
android:layout_marginStart="@{viewModel.isMuted ? @dimen/five : @dimen/zero}"
android:layout_marginEnd="5dp"
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/unsecure_label"
app:layout_constraintTop_toBottomOf="@id/title"
app:layout_constraintBottom_toBottomOf="@id/avatar"
app:tint="?attr/color_main1_500"/>
<androidx.appcompat.widget.AppCompatTextView
style="@style/default_text_style"
android:id="@+id/ephemeral_duration"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginStart="5dp"
android:layout_marginEnd="5dp"
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"
app:layout_constraintBottom_toBottomOf="@id/ephemeral_enabled"/>
<ImageView
style="@style/icon_top_bar_button_style"
android:id="@+id/show_menu"
android:onClick="@{showMenuClickListener}"
android:layout_width="wrap_content"
android:layout_height="0dp"
android:src="@drawable/dots_three_vertical"
android:contentDescription="@string/content_description_show_popup_menu"
android:visibility="@{viewModel.isCallConversation ? View.GONE : View.VISIBLE}"
app:layout_constraintTop_toTopOf="parent"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintBottom_toTopOf="@id/events_list"
app:tint="?attr/color_main2_500"/>
<ImageView
style="@style/icon_top_bar_button_style"
android:id="@+id/start_call"
android:onClick="@{() -> viewModel.startCall()}"
android:layout_width="wrap_content"
android:layout_height="0dp"
android:src="@drawable/phone"
android:contentDescription="@string/content_description_call_start"
android:visibility="@{viewModel.isCallConversation || viewModel.isReadOnly || viewModel.searchBarVisible ? View.GONE : View.VISIBLE}"
app:layout_constraintTop_toTopOf="parent"
app:layout_constraintEnd_toStartOf="@id/show_menu"
app:layout_constraintBottom_toTopOf="@id/events_list"
app:tint="?attr/color_main2_500" />
<ImageView
style="@style/icon_top_bar_button_style"
android:id="@+id/cancel_search"
android:onClick="@{() -> viewModel.closeSearchBar()}"
android:layout_width="wrap_content"
android:layout_height="0dp"
android:src="@drawable/caret_left"
android:contentDescription="@string/content_description_cancel_filter"
app:layout_constraintBottom_toBottomOf="@id/search"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="@id/search"
app:tint="?attr/color_main2_500" />
<com.google.android.material.textfield.TextInputLayout
style="?attr/textInputFilledStyle"
android:id="@+id/search"
android:layout_width="0dp"
android:layout_height="@dimen/top_bar_height"
android:gravity="center_vertical"
android:textColorHint="?attr/color_main2_400"
app:hintEnabled="false"
app:hintAnimationEnabled="false"
app:hintTextColor="?attr/color_main2_400"
app:boxStrokeWidth="0dp"
app:boxStrokeWidthFocused="0dp"
app:layout_constraintEnd_toStartOf="@id/search_up"
app:layout_constraintStart_toEndOf="@id/cancel_search"
app:layout_constraintTop_toTopOf="parent">
<com.google.android.material.textfield.TextInputEditText
android:id="@+id/search_field"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:textCursorDrawable="@null"
android:textSize="16sp"
android:inputType="text"
android:paddingVertical="1dp"
android:imeOptions="actionSearch"
android:text="@={viewModel.searchFilter}"
android:background="@android:color/transparent" />
</com.google.android.material.textfield.TextInputLayout>
<ImageView
style="@style/icon_top_bar_button_style"
android:id="@+id/search_up"
android:onClick="@{() -> viewModel.searchUp()}"
android:enabled="@{viewModel.searchFilter.length() > 0 &amp;&amp; viewModel.canSearchUp}"
android:layout_width="wrap_content"
android:layout_height="0dp"
android:src="@drawable/caret_up"
android:contentDescription="@string/content_description_chat_search_message_up"
app:layout_constraintBottom_toBottomOf="@id/search"
app:layout_constraintEnd_toStartOf="@id/search_down"
app:layout_constraintTop_toTopOf="@id/search"
app:tint="@color/icon_color_selector" />
<ImageView
style="@style/icon_top_bar_button_style"
android:id="@+id/search_down"
android:onClick="@{() -> viewModel.searchDown()}"
android:enabled="@{viewModel.searchFilter.length() > 0 &amp;&amp; viewModel.canSearchDown}"
android:layout_width="wrap_content"
android:layout_height="0dp"
android:src="@drawable/caret_down"
android:contentDescription="@string/content_description_chat_search_message_down"
app:layout_constraintBottom_toBottomOf="@id/search"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintTop_toTopOf="@id/search"
app:tint="@color/icon_color_selector" />
<androidx.recyclerview.widget.RecyclerView
android:id="@+id/events_list"
android:layout_width="match_parent"
android:layout_height="0dp"
android:layout_marginTop="@dimen/top_bar_height"
android:paddingBottom="5dp"
app:layout_constraintTop_toTopOf="parent"
app:layout_constraintBottom_toTopOf="@id/composing"/>
<include
android:id="@+id/secured_event"
android:onClick="@{endToEndEncryptedEventClickListener}"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:visibility="@{viewModel.isEmpty &amp;&amp; viewModel.isEndToEndEncrypted ? View.VISIBLE : View.GONE}"
layout="@layout/chat_conversation_e2e_encrypted_first_event"
app:layout_constraintTop_toTopOf="@id/events_list"
app:layout_constraintStart_toStartOf="@id/events_list"
app:layout_constraintEnd_toEndOf="@id/events_list" />
<ImageView
android:id="@+id/composing_icon"
android:layout_width="@dimen/small_icon_size"
android:layout_height="@dimen/small_icon_size"
android:layout_marginStart="10dp"
android:src="@{viewModel.composingIcon, default=@drawable/microphone}"
android:visibility="@{viewModel.composingLabel.length() == 0 ? View.GONE : View.VISIBLE}"
android:contentDescription="@null"
app:tint="?attr/color_main2_600"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintEnd_toStartOf="@id/composing"
app:layout_constraintTop_toTopOf="@id/composing"
app:layout_constraintBottom_toBottomOf="@id/composing"/>
<androidx.appcompat.widget.AppCompatTextView
style="@style/default_text_style_300"
android:id="@+id/composing"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_marginStart="5dp"
android:paddingBottom="5dp"
android:background="?attr/color_main2_000"
android:text="@{viewModel.composingLabel, default=`John Doe is composing...`}"
android:textSize="12sp"
android:visibility="@{viewModel.composingLabel.length() == 0 ? View.GONE : View.VISIBLE}"
app:layout_constraintBottom_toTopOf="@id/warning_disabled_not_secured"
app:layout_constraintStart_toEndOf="@id/composing_icon"
app:layout_constraintEnd_toEndOf="parent" />
<include
style="@style/default_text_style"
android:id="@+id/warning_disabled_not_secured"
android:onClick="@{warningConversationDisabledClickListener}"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:visibility="@{viewModel.isDisabledBecauseNotSecured ? View.VISIBLE : View.GONE, default=gone}"
layout="@layout/chat_conversation_send_area_disabled_unsecured_warning"
app:layout_constraintBottom_toTopOf="@id/send_area"/>
<include
android:id="@+id/send_area"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:visibility="@{viewModel.isReadOnly || viewModel.isDisabledBecauseNotSecured || viewModel.searchBarVisible ? View.GONE : View.VISIBLE}"
layout="@layout/chat_conversation_send_area"
app:layout_constraintBottom_toBottomOf="parent"
bind:openMediaPickerClickListener="@{openMediaPickerClickListener}"
bind:openCameraClickListener="@{openCameraClickListener}"
bind:openFilePickerClickListener="@{openFilePickerClickListener}"
bind:viewModel="@{sendMessageViewModel}"/>
<com.google.android.material.floatingactionbutton.FloatingActionButton
android:id="@+id/scroll_to_bottom"
android:onClick="@{scrollToBottomClickListener}"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_gravity="end|bottom"
android:layout_margin="16dp"
android:src="@drawable/caret_double_down"
android:contentDescription="@string/content_description_chat_scroll_to_bottom_or_first_unread"
android:visibility="@{viewModel.isUserScrollingUp ? View.VISIBLE : View.GONE}"
app:tint="?attr/color_on_main"
app:backgroundTint="?attr/color_main1_500"
app:shapeAppearanceOverlay="@style/rounded"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintBottom_toTopOf="@id/send_area" />
<androidx.appcompat.widget.AppCompatTextView
style="@style/unread_count_text_style"
android:id="@+id/unread_messages"
android:layout_width="@dimen/unread_count_indicator_size"
android:layout_height="@dimen/unread_count_indicator_size"
android:layout_marginTop="-13dp"
android:layout_marginStart="-11dp"
android:text="@{String.valueOf(viewModel.unreadMessagesCount), default=`1`}"
android:visibility="@{viewModel.isUserScrollingUp &amp;&amp; viewModel.unreadMessagesCount > 0 ? View.VISIBLE : View.GONE}"
app:layout_constraintTop_toTopOf="@id/scroll_to_bottom"
app:layout_constraintStart_toEndOf="@id/scroll_to_bottom"/>
</androidx.constraintlayout.widget.ConstraintLayout>
<include
android:id="@+id/message_bottom_sheet"
layout="@layout/chat_message_bottom_sheet" />
</androidx.coordinatorlayout.widget.CoordinatorLayout>
<include
layout="@layout/operation_in_progress"
bind:visibility="@{viewModel.searchInProgress}" />
<include
android:id="@+id/long_press_menu"
android:visibility="@{messageLongPressViewModel.visible ? View.VISIBLE : View.GONE, default=gone}"
bind:viewModel="@{messageLongPressViewModel}"
layout="@layout/chat_bubble_long_press_menu" />
</FrameLayout>
</layout>