kopia lustrzana https://github.com/ryukoposting/Signal-Android
Fix emoji keyboard bugs and group story replies.
rodzic
b8bb2e234b
commit
11c3ea769e
|
@ -0,0 +1,14 @@
|
|||
package com.google.android.material.bottomsheet
|
||||
|
||||
import android.view.View
|
||||
import android.widget.FrameLayout
|
||||
import java.lang.ref.WeakReference
|
||||
|
||||
/**
|
||||
* Manually adjust the nested scrolling child for a given [BottomSheetBehavior].
|
||||
*/
|
||||
object BottomSheetBehaviorHack {
|
||||
fun setNestedScrollingChild(behavior: BottomSheetBehavior<FrameLayout>, view: View) {
|
||||
behavior.nestedScrollingChildRef = WeakReference(view)
|
||||
}
|
||||
}
|
|
@ -146,6 +146,10 @@ public class MediaKeyboard extends FrameLayout implements InputView {
|
|||
.commitAllowingStateLoss();
|
||||
}
|
||||
|
||||
public boolean isEmojiSearchMode() {
|
||||
return keyboardState == State.EMOJI_SEARCH;
|
||||
}
|
||||
|
||||
private void initView() {
|
||||
if (!isInitialised) {
|
||||
|
||||
|
|
|
@ -14,6 +14,7 @@ import org.thoughtcrime.securesms.R
|
|||
import org.thoughtcrime.securesms.components.ComposeText
|
||||
import org.thoughtcrime.securesms.components.InputAwareLayout
|
||||
import org.thoughtcrime.securesms.components.QuoteView
|
||||
import org.thoughtcrime.securesms.components.emoji.EmojiPageView
|
||||
import org.thoughtcrime.securesms.components.emoji.EmojiToggle
|
||||
import org.thoughtcrime.securesms.components.emoji.MediaKeyboard
|
||||
import org.thoughtcrime.securesms.database.model.MediaMmsMessageRecord
|
||||
|
@ -42,6 +43,9 @@ class StoryReplyComposer @JvmOverloads constructor(
|
|||
|
||||
var callback: Callback? = null
|
||||
|
||||
val emojiPageView: EmojiPageView?
|
||||
get() = findViewById(R.id.emoji_page_view)
|
||||
|
||||
init {
|
||||
inflate(context, R.layout.stories_reply_to_story_composer, this)
|
||||
|
||||
|
@ -85,6 +89,12 @@ class StoryReplyComposer @JvmOverloads constructor(
|
|||
emojiDrawerToggle.setOnClickListener {
|
||||
onEmojiToggleClicked()
|
||||
}
|
||||
|
||||
inputAwareLayout.addOnKeyboardShownListener {
|
||||
if (inputAwareLayout.currentInput == emojiDrawer && !emojiDrawer.isEmojiSearchMode) {
|
||||
onEmojiToggleClicked()
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
fun setQuote(messageRecord: MediaMmsMessageRecord) {
|
||||
|
@ -136,11 +146,13 @@ class StoryReplyComposer @JvmOverloads constructor(
|
|||
if (inputAwareLayout.currentInput == emojiDrawer) {
|
||||
isRequestingEmojiDrawer = false
|
||||
inputAwareLayout.showSoftkey(input)
|
||||
callback?.onHideEmojiKeyboard()
|
||||
} else {
|
||||
isRequestingEmojiDrawer = true
|
||||
inputAwareLayout.hideSoftkey(input) {
|
||||
inputAwareLayout.post {
|
||||
inputAwareLayout.show(input, emojiDrawer)
|
||||
emojiDrawer.post { callback?.onShowEmojiKeyboard() }
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -150,6 +162,8 @@ class StoryReplyComposer @JvmOverloads constructor(
|
|||
fun onSendActionClicked()
|
||||
fun onPickReactionClicked()
|
||||
fun onInitializeEmojiDrawer(mediaKeyboard: MediaKeyboard)
|
||||
fun onShowEmojiKeyboard() = Unit
|
||||
fun onHideEmojiKeyboard() = Unit
|
||||
}
|
||||
|
||||
companion object {
|
||||
|
|
|
@ -37,6 +37,8 @@ class StoryGroupReplyBottomSheetDialogFragment : FixedRoundedCornerBottomSheetDi
|
|||
override val peekHeightPercentage: Float = 1f
|
||||
|
||||
private val lifecycleDisposable = LifecycleDisposable()
|
||||
private var shouldShowFullScreen = false
|
||||
private var initialParentHeight = 0
|
||||
|
||||
private val storyViewerPageViewModel: StoryViewerPageViewModel by viewModels(
|
||||
ownerProducer = { requireParentFragment() }
|
||||
|
@ -70,7 +72,16 @@ class StoryGroupReplyBottomSheetDialogFragment : FixedRoundedCornerBottomSheetDi
|
|||
view.viewTreeObserver.addOnGlobalLayoutListener {
|
||||
val parentHeight = requireCoordinatorLayout().height
|
||||
val desiredHeight = (resources.displayMetrics.heightPixels * 0.6f).roundToInt()
|
||||
val targetHeight = if (parentHeight != 0) min(parentHeight, desiredHeight) else desiredHeight
|
||||
|
||||
if (initialParentHeight == 0) {
|
||||
initialParentHeight = parentHeight
|
||||
}
|
||||
|
||||
val targetHeight = when {
|
||||
parentHeight == 0 -> desiredHeight
|
||||
shouldShowFullScreen || parentHeight != initialParentHeight -> parentHeight
|
||||
else -> min(parentHeight, desiredHeight)
|
||||
}
|
||||
|
||||
if (view.height != targetHeight) {
|
||||
view.updateLayoutParams {
|
||||
|
@ -90,6 +101,11 @@ class StoryGroupReplyBottomSheetDialogFragment : FixedRoundedCornerBottomSheetDi
|
|||
storyViewerPageViewModel.startDirectReply(storyId, recipientId)
|
||||
}
|
||||
|
||||
override fun requestFullScreen(fullscreen: Boolean) {
|
||||
shouldShowFullScreen = fullscreen
|
||||
requireView().invalidate()
|
||||
}
|
||||
|
||||
companion object {
|
||||
private const val ARG_STORY_ID = "arg.story.id"
|
||||
private const val ARG_GROUP_RECIPIENT_ID = "arg.group.recipient.id"
|
||||
|
|
|
@ -2,19 +2,22 @@ package org.thoughtcrime.securesms.stories.viewer.reply.group
|
|||
|
||||
import android.content.ClipData
|
||||
import android.os.Bundle
|
||||
import android.provider.Settings.System.getConfiguration
|
||||
import android.view.KeyEvent
|
||||
import android.view.MotionEvent
|
||||
import android.view.View
|
||||
import android.widget.Toast
|
||||
import androidx.fragment.app.Fragment
|
||||
import androidx.fragment.app.viewModels
|
||||
import androidx.recyclerview.widget.LinearLayoutManager
|
||||
import androidx.recyclerview.widget.RecyclerView
|
||||
import com.google.android.material.bottomsheet.BottomSheetBehaviorHack
|
||||
import com.google.android.material.bottomsheet.BottomSheetDialog
|
||||
import io.reactivex.rxjava3.android.schedulers.AndroidSchedulers
|
||||
import io.reactivex.rxjava3.kotlin.subscribeBy
|
||||
import org.signal.core.util.concurrent.SignalExecutors
|
||||
import org.signal.core.util.logging.Log
|
||||
import org.thoughtcrime.securesms.R
|
||||
import org.thoughtcrime.securesms.components.FixedRoundedCornerBottomSheetDialogFragment
|
||||
import org.thoughtcrime.securesms.components.emoji.MediaKeyboard
|
||||
import org.thoughtcrime.securesms.components.mention.MentionAnnotation
|
||||
import org.thoughtcrime.securesms.components.settings.DSLConfiguration
|
||||
|
@ -72,6 +75,18 @@ class StoryGroupReplyFragment :
|
|||
ownerProducer = { requireActivity() }
|
||||
)
|
||||
|
||||
private val recyclerListener: RecyclerView.OnItemTouchListener = object : RecyclerView.SimpleOnItemTouchListener() {
|
||||
override fun onInterceptTouchEvent(view: RecyclerView, e: MotionEvent): Boolean {
|
||||
recyclerView.isNestedScrollingEnabled = view == recyclerView
|
||||
composer.emojiPageView?.isNestedScrollingEnabled = view == composer.emojiPageView
|
||||
|
||||
val dialog = (parentFragment as FixedRoundedCornerBottomSheetDialogFragment).dialog as BottomSheetDialog
|
||||
BottomSheetBehaviorHack.setNestedScrollingChild(dialog.behavior, view)
|
||||
dialog.findViewById<View>(R.id.design_bottom_sheet)?.invalidate()
|
||||
return false
|
||||
}
|
||||
}
|
||||
|
||||
private val colorizer = Colorizer()
|
||||
private val lifecycleDisposable = LifecycleDisposable()
|
||||
|
||||
|
@ -245,6 +260,18 @@ class StoryGroupReplyFragment :
|
|||
mediaKeyboard.setFragmentManager(childFragmentManager)
|
||||
}
|
||||
|
||||
override fun onShowEmojiKeyboard() {
|
||||
requireListener<Callback>().requestFullScreen(true)
|
||||
recyclerView.addOnItemTouchListener(recyclerListener)
|
||||
composer.emojiPageView?.addOnItemTouchListener(recyclerListener)
|
||||
}
|
||||
|
||||
override fun onHideEmojiKeyboard() {
|
||||
recyclerView.removeOnItemTouchListener(recyclerListener)
|
||||
composer.emojiPageView?.removeOnItemTouchListener(recyclerListener)
|
||||
requireListener<Callback>().requestFullScreen(false)
|
||||
}
|
||||
|
||||
override fun openEmojiSearch() {
|
||||
composer.openEmojiSearch()
|
||||
}
|
||||
|
@ -359,5 +386,6 @@ class StoryGroupReplyFragment :
|
|||
|
||||
interface Callback {
|
||||
fun onStartDirectReply(recipientId: RecipientId)
|
||||
fun requestFullScreen(fullscreen: Boolean)
|
||||
}
|
||||
}
|
||||
|
|
|
@ -48,6 +48,9 @@ class StoryViewsAndRepliesDialogFragment : FixedRoundedCornerBottomSheetDialogFr
|
|||
|
||||
private lateinit var pager: ViewPager2
|
||||
|
||||
private var shouldShowFullScreen = false
|
||||
private var initialParentHeight = 0
|
||||
|
||||
private val storyViewerPageViewModel: StoryViewerPageViewModel by viewModels(
|
||||
ownerProducer = { requireParentFragment() }
|
||||
)
|
||||
|
@ -96,7 +99,16 @@ class StoryViewsAndRepliesDialogFragment : FixedRoundedCornerBottomSheetDialogFr
|
|||
view.viewTreeObserver.addOnGlobalLayoutListener {
|
||||
val parentHeight = requireCoordinatorLayout().height
|
||||
val desiredHeight = (resources.displayMetrics.heightPixels * 0.6f).roundToInt()
|
||||
val targetHeight = if (parentHeight != 0) min(parentHeight, desiredHeight) else desiredHeight
|
||||
|
||||
if (initialParentHeight == 0) {
|
||||
initialParentHeight = parentHeight
|
||||
}
|
||||
|
||||
val targetHeight = when {
|
||||
parentHeight == 0 -> desiredHeight
|
||||
shouldShowFullScreen || parentHeight != initialParentHeight -> parentHeight
|
||||
else -> min(parentHeight, desiredHeight)
|
||||
}
|
||||
|
||||
if (view.height != targetHeight) {
|
||||
view.updateLayoutParams {
|
||||
|
@ -126,6 +138,11 @@ class StoryViewsAndRepliesDialogFragment : FixedRoundedCornerBottomSheetDialogFr
|
|||
storyViewerPageViewModel.startDirectReply(storyId, recipientId)
|
||||
}
|
||||
|
||||
override fun requestFullScreen(fullscreen: Boolean) {
|
||||
shouldShowFullScreen = fullscreen
|
||||
requireView().invalidate()
|
||||
}
|
||||
|
||||
private inner class PageChangeCallback : ViewPager2.OnPageChangeCallback() {
|
||||
override fun onPageScrollStateChanged(state: Int) {
|
||||
if (state == ViewPager2.SCROLL_STATE_IDLE) {
|
||||
|
|
Ładowanie…
Reference in New Issue