Fix bubble desired height calculation.

This commit is contained in:
DivyaKhunt07
2026-02-17 12:49:32 +00:00
committed by Cody Henthorne
parent 7428e1e2ea
commit bd121e47c8
5 changed files with 63 additions and 5 deletions

View File

@@ -64,6 +64,7 @@ open class InsetAwareConstraintLayout @JvmOverloads constructor(
private var insets: WindowInsetsCompat? = null
private var windowTypes: Int = InsetAwareConstraintLayout.windowTypes
private var navigationBarInsetOverride: Int? = null
private val windowInsetsListener = androidx.core.view.OnApplyWindowInsetsListener { _, insets ->
this.insets = insets
@@ -114,6 +115,23 @@ open class InsetAwareConstraintLayout @JvmOverloads constructor(
}
}
fun setNavigationBarInsetOverride(inset: Int?) {
if (navigationBarInsetOverride == inset) return
navigationBarInsetOverride = inset
if (inset != null) {
// Apply immediately so layout is correct before next inset dispatch (important for
// Android 15 bubble where insets can arrive late or with different values).
navigationBarGuideline?.setGuidelineEnd(inset)
if (!isKeyboardShowing) {
keyboardGuideline?.setGuidelineEnd(inset)
}
requestLayout()
}
if (insets != null) {
applyInsets(insets!!.getInsets(windowTypes), insets!!.getInsets(keyboardType))
}
}
fun addKeyboardStateListener(listener: KeyboardStateListener) {
keyboardStateListeners += listener
}
@@ -134,7 +152,7 @@ open class InsetAwareConstraintLayout @JvmOverloads constructor(
val isLtr = ViewUtil.isLtr(this)
val statusBar = windowInsets.top
val navigationBar = if (windowInsets.bottom == 0 && Build.VERSION.SDK_INT <= 29) {
val navigationBar = navigationBarInsetOverride ?: if (windowInsets.bottom == 0 && Build.VERSION.SDK_INT <= 29) {
ViewUtil.getNavigationBarHeight(resources)
} else {
windowInsets.bottom

View File

@@ -1,17 +1,25 @@
package org.thoughtcrime.securesms.conversation
import android.os.Bundle
import androidx.core.view.WindowCompat
import org.thoughtcrime.securesms.R
import org.thoughtcrime.securesms.conversation.v2.ConversationActivity
import org.thoughtcrime.securesms.util.ViewUtil
/**
* Activity which encapsulates a conversation for a Bubble window.
*
*8
* This activity exists so that we can override some of its manifest parameters
* without clashing with [ConversationActivity] and provide an API-level
* independent "is in bubble?" check.
*/
class BubbleConversationActivity : ConversationActivity() {
override fun onCreate(savedInstanceState: Bundle?, ready: Boolean) {
WindowCompat.setDecorFitsSystemWindows(window, false)
super.onCreate(savedInstanceState, ready)
}
override fun onPause() {
super.onPause()
ViewUtil.hideKeyboard(this, findViewById(R.id.fragment_container))

View File

@@ -637,8 +637,14 @@ class ConversationFragment :
override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
binding.toolbar.isBackInvokedCallbackEnabled = false
binding.root.setUseWindowTypes(args.conversationScreenType == ConversationScreenType.NORMAL && !resources.getWindowSizeClass().isSplitPane())
if (args.conversationScreenType == ConversationScreenType.BUBBLE) {
binding.root.setNavigationBarInsetOverride(0)
view.post {
ViewCompat.requestApplyInsets(binding.root)
binding.root.requestLayout()
}
}
disposables.bindTo(viewLifecycleOwner)

View File

@@ -362,14 +362,13 @@ sealed class NotificationBuilder(protected val context: Context) {
if (intent != null) {
val bubbleMetadata = NotificationCompat.BubbleMetadata.Builder(intent, AvatarUtil.getIconCompat(context, conversation.recipient))
.setAutoExpandBubble(bubbleState === BubbleUtil.BubbleState.SHOWN)
.setDesiredHeight(600)
.setDesiredHeight(BubbleUtil.getDesiredBubbleHeightPx(context))
.setSuppressNotification(bubbleState === BubbleUtil.BubbleState.SHOWN)
.build()
builder.bubbleMetadata = bubbleMetadata
}
}
override fun setLights(@ColorInt color: Int, onTime: Int, offTime: Int) {
if (NotificationChannels.supported()) {
return

View File

@@ -4,8 +4,10 @@ import android.app.Notification;
import android.app.NotificationChannel;
import android.app.NotificationManager;
import android.content.Context;
import android.graphics.Rect;
import android.os.Build;
import android.service.notification.StatusBarNotification;
import android.view.WindowManager;
import androidx.annotation.NonNull;
import androidx.annotation.Nullable;
@@ -14,6 +16,7 @@ import androidx.annotation.WorkerThread;
import com.annimon.stream.Stream;
import org.signal.core.util.DimensionUnit;
import org.signal.core.util.concurrent.SignalExecutors;
import org.signal.core.util.logging.Log;
import org.thoughtcrime.securesms.dependencies.AppDependencies;
@@ -35,6 +38,8 @@ public final class BubbleUtil {
private static final String TAG = Log.tag(BubbleUtil.class);
private static String currentState = "";
private static final float MIN_BUBBLE_HEIGHT_DP = 600f;
private static final float BUBBLE_HEIGHT_SCREEN_FRACTION = 0.9f;
private BubbleUtil() {
}
@@ -134,4 +139,26 @@ public final class BubbleUtil {
SHOWN,
HIDDEN
}
public static int getDesiredBubbleHeightPx(@NonNull Context context) {
int minHeightPx = (int) DimensionUnit.DP.toPixels(MIN_BUBBLE_HEIGHT_DP);
int screenHeightPx = context.getResources().getDisplayMetrics().heightPixels;
if (Build.VERSION.SDK_INT >= 30) {
WindowManager wm = context.getSystemService(WindowManager.class);
if (wm != null) {
Rect bounds = wm.getCurrentWindowMetrics().getBounds();
screenHeightPx = bounds.height();
}
}
if (screenHeightPx <= 0) {
return minHeightPx;
}
int targetPx = (int) (screenHeightPx * BUBBLE_HEIGHT_SCREEN_FRACTION);
int desiredPx = Math.max(minHeightPx, targetPx);
return Math.min(desiredPx, screenHeightPx);
}
}