Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
30 changes: 30 additions & 0 deletions app/src/main/java/com/nextcloud/talk/chat/MessageInputFragment.kt
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@ import android.os.CountDownTimer
import android.os.SystemClock
import android.text.Editable
import android.text.InputFilter
import android.text.StaticLayout
import android.text.TextUtils
import android.text.TextWatcher
import android.util.Log
Expand All @@ -41,6 +42,7 @@ import androidx.appcompat.view.ContextThemeWrapper
import androidx.compose.material3.MaterialTheme
import androidx.core.content.ContextCompat
import androidx.core.graphics.drawable.toDrawable
import androidx.core.view.doOnLayout
import androidx.core.view.isVisible
import androidx.core.widget.doAfterTextChanged
import androidx.emoji2.emojipicker.RecentEmojiProvider
Expand Down Expand Up @@ -467,9 +469,12 @@ class MessageInputFragment : Fragment() {
chatActivity.chatViewModel.messageDraft.messageCursor = cursor
chatActivity.chatViewModel.messageDraft.messageText = text
handleButtonsVisibility()
updateEmojiButtonPlacement()
}
})

binding.fragmentMessageInputView.inputEditText.doOnLayout { updateEmojiButtonPlacement() }

// Image keyboard support
// See: https://developer.android.com/guide/topics/text/image-keyboard

Expand Down Expand Up @@ -720,6 +725,30 @@ class MessageInputFragment : Fragment() {
}
}

private fun updateEmojiButtonPlacement() {
if (!this::binding.isInitialized) {
return
}

val editText = binding.fragmentMessageInputView.inputEditText
val smileyButton = binding.fragmentMessageInputView.smileyButton
val text = editText.text
val currentWidth = editText.width
val isCurrentlyStacked = binding.fragmentMessageInputView.isEmojiButtonStacked
val widestPossibleWidth = if (isCurrentlyStacked) currentWidth else currentWidth + smileyButton.width

if (text == null || currentWidth <= 0 || widestPossibleWidth <= 0) {
return
}

val lineCountAtWidestWidth = StaticLayout.Builder
.obtain(text, 0, text.length, editText.paint, widestPossibleWidth)
.build()
.lineCount

binding.fragmentMessageInputView.setEmojiButtonStacked(lineCountAtWidestWidth >= LONG_MESSAGE_LINE_THRESHOLD)
}

fun updateScheduledMessagesAvailability(hasMessages: Boolean) {
hasScheduledMessages = hasMessages
handleButtonsVisibility()
Expand Down Expand Up @@ -1280,5 +1309,6 @@ class MessageInputFragment : Fragment() {
private const val FULLY_OPAQUE: Float = 1.0f
private const val FULLY_TRANSPARENT: Float = 0.0f
private const val OPACITY_DISABLED = 0.7f
private const val LONG_MESSAGE_LINE_THRESHOLD = 2
}
}
26 changes: 26 additions & 0 deletions app/src/main/java/com/nextcloud/talk/ui/MessageInput.kt
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,8 @@ import android.widget.Chronometer
import android.widget.FrameLayout
import android.widget.ImageButton
import android.widget.ImageView
import android.widget.LinearLayout
import android.widget.RelativeLayout
import android.widget.SeekBar
import android.widget.TextView
import androidx.emoji2.widget.EmojiEditText
Expand All @@ -38,11 +40,15 @@ class MessageInput : FrameLayout {
lateinit var inputEditText: EmojiEditText
lateinit var attachmentButton: ImageButton
lateinit var messageSendButton: ImageButton
private lateinit var attachmentEmojiContainer: LinearLayout
val messageInput: EmojiEditText
get() = inputEditText
val button: ImageButton
get() = messageSendButton

var isEmojiButtonStacked = false
private set

constructor(context: Context) : super(context) {
init()
}
Expand All @@ -64,6 +70,7 @@ class MessageInput : FrameLayout {
inputEditText.maxHeight = screenHeight / 3

attachmentButton = findViewById(R.id.attachmentButton)
attachmentEmojiContainer = findViewById(R.id.attachmentEmojiContainer)
messageSendButton = findViewById(R.id.messageSendButton)
audioRecordDuration = findViewById(R.id.audioRecordDuration)
recordAudioButton = findViewById(R.id.recordAudioButton)
Expand All @@ -86,4 +93,23 @@ class MessageInput : FrameLayout {
listener?.invoke()
}
}

fun setEmojiButtonStacked(stacked: Boolean) {
if (isEmojiButtonStacked == stacked) {
return
}
isEmojiButtonStacked = stacked

attachmentEmojiContainer.orientation = if (stacked) LinearLayout.VERTICAL else LinearLayout.HORIZONTAL

val containerParams = attachmentEmojiContainer.layoutParams as RelativeLayout.LayoutParams
if (stacked) {
containerParams.removeRule(RelativeLayout.ALIGN_BOTTOM)
containerParams.addRule(RelativeLayout.CENTER_VERTICAL)
} else {
containerParams.removeRule(RelativeLayout.CENTER_VERTICAL)
containerParams.addRule(RelativeLayout.ALIGN_BOTTOM, inputEditText.id)
}
attachmentEmojiContainer.layoutParams = containerParams
}
}
49 changes: 27 additions & 22 deletions app/src/main/res/layout/view_message_input.xml
Original file line number Diff line number Diff line change
Expand Up @@ -33,36 +33,41 @@
android:layout_height="wrap_content"
android:layoutDirection="ltr">

<ImageButton
android:id="@+id/attachmentButton"
android:layout_width="@dimen/min_size_clickable_area"
android:layout_height="@dimen/min_size_clickable_area"
<LinearLayout
android:id="@+id/attachmentEmojiContainer"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_alignBottom="@id/messageInput"
android:background="@color/transparent"
android:contentDescription="@string/nc_add_attachment"
android:gravity="bottom"
android:src="@drawable/ic_baseline_attach_file_24"
app:tint="?attr/colorControlNormal" />
android:orientation="horizontal">

<ImageButton
android:id="@+id/smileyButton"
android:layout_width="@dimen/min_size_clickable_area"
android:layout_height="@dimen/min_size_clickable_area"
android:layout_alignBottom="@id/messageInput"
android:layout_toEndOf="@id/attachmentButton"
android:background="@color/transparent"
android:contentDescription="@string/nc_add_emojis"
android:gravity="bottom"
android:src="@drawable/ic_insert_emoticon_black_24dp"
app:tint="?attr/colorControlNormal" />
<ImageButton
android:id="@+id/attachmentButton"
android:layout_width="@dimen/min_size_clickable_area"
android:layout_height="@dimen/min_size_clickable_area"
android:background="@color/transparent"
android:contentDescription="@string/nc_add_attachment"
android:gravity="bottom"
android:src="@drawable/ic_baseline_attach_file_24"
app:tint="?attr/colorControlNormal" />

<ImageButton
android:id="@+id/smileyButton"
android:layout_width="@dimen/min_size_clickable_area"
android:layout_height="@dimen/min_size_clickable_area"
android:background="@color/transparent"
android:contentDescription="@string/nc_add_emojis"
android:gravity="bottom"
android:src="@drawable/ic_insert_emoticon_black_24dp"
app:tint="?attr/colorControlNormal" />
</LinearLayout>

<com.nextcloud.talk.utils.ImageEmojiEditText
android:id="@+id/messageInput"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_centerHorizontal="true"
android:layout_marginEnd="48dp"
android:layout_toEndOf="@id/smileyButton"
android:layout_toEndOf="@id/attachmentEmojiContainer"
android:background="@null"
android:imeOptions="actionDone"
android:inputType="textAutoCorrect|textMultiLine|textCapSentences"
Expand Down Expand Up @@ -267,7 +272,7 @@
android:id="@+id/attachmentButtonSpace"
android:layout_width="0dp"
android:layout_height="0dp"
android:layout_toEndOf="@id/attachmentButton"
android:layout_toEndOf="@id/attachmentEmojiContainer"
android:visibility="gone" />

<Space
Expand Down
Loading