Finished emoji picker, started file picker

This commit is contained in:
Sylvain Berfini 2023-10-18 10:18:01 +02:00
parent 561c36bfe0
commit 3d455d0fc9
6 changed files with 87 additions and 37 deletions

View file

@ -33,6 +33,8 @@ import android.view.View
import android.view.ViewGroup
import android.view.Window
import android.view.WindowManager
import androidx.activity.result.PickVisualMediaRequest
import androidx.activity.result.contract.ActivityResultContracts
import androidx.annotation.UiThread
import androidx.core.view.doOnPreDraw
import androidx.databinding.DataBindingUtil
@ -41,6 +43,7 @@ import androidx.navigation.fragment.findNavController
import androidx.navigation.fragment.navArgs
import androidx.recyclerview.widget.LinearLayoutManager
import com.google.android.material.bottomsheet.BottomSheetBehavior
import kotlinx.coroutines.launch
import org.linphone.LinphoneApplication.Companion.coreContext
import org.linphone.R
import org.linphone.core.tools.Log
@ -54,6 +57,7 @@ import org.linphone.utils.AppUtils
import org.linphone.utils.Event
import org.linphone.utils.LinphoneUtils
import org.linphone.utils.hideKeyboard
import org.linphone.utils.setKeyboardInsetListener
import org.linphone.utils.showKeyboard
@UiThread
@ -70,6 +74,18 @@ class ConversationFragment : GenericFragment() {
private lateinit var adapter: ConversationEventAdapter
private val pickMedia = registerForActivityResult(
ActivityResultContracts.PickMultipleVisualMedia()
) { list ->
if (!list.isNullOrEmpty()) {
for (file in list) {
Log.i("$TAG Picked file [$file]")
}
} else {
Log.w("$TAG No file picked")
}
}
override fun onCreateView(
inflater: LayoutInflater,
container: ViewGroup?,
@ -157,20 +173,15 @@ class ConversationFragment : GenericFragment() {
}
}
val emojisBottomSheetBehavior = BottomSheetBehavior.from(binding.emojiPicker)
val emojisBottomSheetBehavior = BottomSheetBehavior.from(binding.sendArea.root)
emojisBottomSheetBehavior.state = BottomSheetBehavior.STATE_COLLAPSED
emojisBottomSheetBehavior.isDraggable = false // To allow scrolling through the emojis
binding.setOpenEmojiPickerClickListener {
/*val state = emojisBottomSheetBehavior.state
if (state == BottomSheetBehavior.STATE_COLLAPSED) {
emojisBottomSheetBehavior.state = BottomSheetBehavior.STATE_HALF_EXPANDED
if (binding.emojiPicker.visibility == View.GONE) {
binding.emojiPicker.visibility = View.VISIBLE
}
} else {
emojisBottomSheetBehavior.state = BottomSheetBehavior.STATE_COLLAPSED
}*/
binding.setOpenFilePickerClickListener {
Log.i("$TAG Opening media picker")
pickMedia.launch(
PickVisualMediaRequest(ActivityResultContracts.PickVisualMedia.ImageAndVideo)
)
}
binding.setGoToInfoClickListener {
@ -185,6 +196,12 @@ class ConversationFragment : GenericFragment() {
viewModel.applyFilter(filter.trim())
}
viewModel.requestKeyboardHidingEvent.observe(viewLifecycleOwner) {
it.consume {
binding.search.hideKeyboard()
}
}
viewModel.focusSearchBarEvent.observe(viewLifecycleOwner) {
it.consume { show ->
if (show) {
@ -195,6 +212,12 @@ class ConversationFragment : GenericFragment() {
}
}
}
binding.root.setKeyboardInsetListener { keyboardVisible ->
if (keyboardVisible) {
viewModel.isEmojiPickerOpen.value = false
}
}
}
override fun onResume() {

View file

@ -66,6 +66,12 @@ class ConversationViewModel @UiThread constructor() : ViewModel() {
val searchFilter = MutableLiveData<String>()
val isEmojiPickerOpen = MutableLiveData<Boolean>()
val requestKeyboardHidingEvent: MutableLiveData<Event<Boolean>> by lazy {
MutableLiveData<Event<Boolean>>()
}
val focusSearchBarEvent: MutableLiveData<Event<Boolean>> by lazy {
MutableLiveData<Event<Boolean>>()
}
@ -211,6 +217,19 @@ class ConversationViewModel @UiThread constructor() : ViewModel() {
}
}
@UiThread
fun toggleEmojiPickerVisibility() {
isEmojiPickerOpen.value = isEmojiPickerOpen.value == false
if (isEmojiPickerOpen.value == true) {
requestKeyboardHidingEvent.value = Event(true)
}
}
@UiThread
fun insertEmoji(emoji: String) {
textToSend.value = "${textToSend.value.orEmpty()}$emoji"
}
@UiThread
fun sendMessage() {
coreContext.postOnCoreThread { core ->

View file

@ -19,7 +19,7 @@
name="goToInfoClickListener"
type="View.OnClickListener" />
<variable
name="openEmojiPickerClickListener"
name="openFilePickerClickListener"
type="View.OnClickListener" />
<variable
name="viewModel"
@ -215,17 +215,9 @@
</androidx.constraintlayout.widget.ConstraintLayout>
<androidx.emoji2.emojipicker.EmojiPickerView
android:id="@+id/emoji_picker"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginBottom="80dp"
android:visibility="gone"
app:layout_behavior="com.google.android.material.bottomsheet.BottomSheetBehavior"/>
<include
android:id="@+id/send_area"
openEmojiPickerClickListener="@{openEmojiPickerClickListener}"
openFilePickerClickListener="@{openFilePickerClickListener}"
viewModel="@{viewModel}"
android:visibility="@{viewModel.isReadOnly ? View.GONE : View.VISIBLE}"
layout="@layout/chat_conversation_send_area"/>

View file

@ -5,7 +5,7 @@
<data>
<import type="android.view.View" />
<variable
name="openEmojiPickerClickListener"
name="openFilePickerClickListener"
type="View.OnClickListener" />
<variable
name="viewModel"
@ -15,18 +15,26 @@
<androidx.constraintlayout.widget.ConstraintLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:paddingTop="16dp"
android:background="@color/gray_100"
app:layout_behavior="com.google.android.material.bottomsheet.BottomSheetBehavior">
<!-- Keep behavior to have it at the bottom -->
<ImageView
<androidx.emoji2.emojipicker.EmojiPickerView
android:id="@+id/emoji_picker"
android:onClick="@{openEmojiPickerClickListener}"
android:layout_width="@dimen/icon_size"
android:layout_height="@dimen/icon_size"
android:layout_marginStart="16dp"
android:src="@drawable/smiley"
android:layout_width="match_parent"
android:layout_height="@dimen/chat_room_emoji_picker_height"
android:visibility="@{viewModel.isEmojiPickerOpen ? View.VISIBLE : View.GONE, default=gone}"
app:emojiPickedListener="@{(emoji) -> viewModel.insertEmoji(emoji.emoji)}"
app:layout_constraintTop_toTopOf="parent"/>
<ImageView
android:id="@+id/emoji_picker_toggle"
android:onClick="@{() -> viewModel.toggleEmojiPickerVisibility()}"
android:layout_width="40dp"
android:layout_height="0dp"
android:padding="8dp"
android:layout_marginStart="8dp"
android:src="@{viewModel.isEmojiPickerOpen ? @drawable/x : @drawable/smiley, default=@drawable/smiley}"
app:tint="@color/icon_color_selector"
app:layout_constraintTop_toTopOf="@id/message_area_background"
app:layout_constraintBottom_toBottomOf="@id/message_area_background"
@ -34,15 +42,17 @@
<ImageView
android:id="@+id/attach_file"
android:layout_width="@dimen/icon_size"
android:layout_height="@dimen/icon_size"
android:layout_marginStart="16dp"
android:layout_marginEnd="16dp"
android:onClick="@{openFilePickerClickListener}"
android:layout_width="40dp"
android:layout_height="0dp"
android:padding="8dp"
android:layout_marginStart="8dp"
android:layout_marginEnd="8dp"
android:src="@drawable/paperclip"
app:tint="@color/icon_color_selector"
app:layout_constraintTop_toTopOf="@id/message_area_background"
app:layout_constraintBottom_toBottomOf="@id/message_area_background"
app:layout_constraintStart_toEndOf="@id/emoji_picker"
app:layout_constraintStart_toEndOf="@id/emoji_picker_toggle"
app:layout_constraintEnd_toStartOf="@id/message_area_background"/>
<ImageView
@ -63,6 +73,7 @@
android:layout_height="wrap_content"
android:layout_marginStart="24dp"
android:layout_marginEnd="5dp"
android:layout_marginTop="16dp"
android:layout_marginBottom="16dp"
android:minHeight="48dp"
android:background="@color/transparent_color"
@ -72,6 +83,7 @@
android:maxLines="3"
android:hint="@string/conversation_text_field_hint"
android:inputType="text"
app:layout_constraintTop_toBottomOf="@id/emoji_picker"
app:layout_constraintStart_toStartOf="@id/message_area_background"
app:layout_constraintEnd_toStartOf="@id/send_barrier"
app:layout_constraintBottom_toBottomOf="parent"/>
@ -98,9 +110,10 @@
<ImageView
android:id="@+id/send_message"
android:onClick="@{() -> viewModel.sendMessage()}"
android:layout_width="@dimen/icon_size"
android:layout_height="@dimen/icon_size"
android:layout_marginEnd="12dp"
android:layout_width="40dp"
android:layout_height="0dp"
android:padding="8dp"
android:layout_marginEnd="4dp"
android:src="@drawable/paper_plane_tilt"
android:enabled="@{viewModel.textToSend.length() > 0}"
app:tint="@color/icon_primary_color_selector"

View file

@ -60,6 +60,7 @@
android:text="@{model.name, default=`John Doe`}"
android:textSize="14sp"
android:layout_marginStart="10dp"
app:layout_constraintVertical_chainStyle="packed"
app:layout_constraintStart_toEndOf="@id/avatar"
app:layout_constraintTop_toTopOf="parent"
app:layout_constraintEnd_toStartOf="@id/participant_menu"

View file

@ -66,4 +66,6 @@
<dimen name="chat_bubble_text_padding_with_bubble">12dp</dimen>
<dimen name="chat_bubble_text_padding_with_status">5dp</dimen>
<dimen name="chat_bubble_long_press_emoji_reaction_size">30sp</dimen>
<dimen name="chat_room_emoji_picker_height">290dp</dimen>
</resources>