diff --git a/app/src/main/java/org/thoughtcrime/securesms/MainActivity.kt b/app/src/main/java/org/thoughtcrime/securesms/MainActivity.kt index 778044a92a..12c7b43764 100644 --- a/app/src/main/java/org/thoughtcrime/securesms/MainActivity.kt +++ b/app/src/main/java/org/thoughtcrime/securesms/MainActivity.kt @@ -974,7 +974,6 @@ class MainActivity : onSetToolbarColor = { toolbarViewModel.setToolbarColor(it) }, - setStatusBarColor = {}, lifecycleOwner = lifecycleOwner ).attach(recyclerView) } @@ -984,7 +983,6 @@ class MainActivity : activity = this, views = listOf(chatFolders), viewStubs = listOf(), - setStatusBarColor = {}, onSetToolbarColor = { toolbarViewModel.setToolbarColor(it) }, diff --git a/app/src/main/java/org/thoughtcrime/securesms/avatar/text/TextAvatarCreationFragment.kt b/app/src/main/java/org/thoughtcrime/securesms/avatar/text/TextAvatarCreationFragment.kt index 7ea8f10957..e63bf81ab6 100644 --- a/app/src/main/java/org/thoughtcrime/securesms/avatar/text/TextAvatarCreationFragment.kt +++ b/app/src/main/java/org/thoughtcrime/securesms/avatar/text/TextAvatarCreationFragment.kt @@ -63,6 +63,7 @@ class TextAvatarCreationFragment : Fragment(R.layout.text_avatar_creation_fragme val tabLayout: ControllableTabLayout = view.findViewById(R.id.text_avatar_creation_tabs) val doneButton: View = view.findViewById(R.id.text_avatar_creation_done) val keyboardAwareLayout: KeyboardAwareLinearLayout = view.findViewById(R.id.keyboard_aware_layout) + keyboardAwareLayout.setInsetPaddingMode(KeyboardAwareLinearLayout.InsetPaddingMode.SAFE_AREA) withRecyclerSet.load(requireContext(), R.layout.text_avatar_creation_fragment_content) withoutRecyclerSet.load(requireContext(), R.layout.text_avatar_creation_fragment_content_hidden_recycler) diff --git a/app/src/main/java/org/thoughtcrime/securesms/badges/gifts/flow/GiftFlowConfirmationFragment.kt b/app/src/main/java/org/thoughtcrime/securesms/badges/gifts/flow/GiftFlowConfirmationFragment.kt index 79f1f13f80..b0919cca0b 100644 --- a/app/src/main/java/org/thoughtcrime/securesms/badges/gifts/flow/GiftFlowConfirmationFragment.kt +++ b/app/src/main/java/org/thoughtcrime/securesms/badges/gifts/flow/GiftFlowConfirmationFragment.kt @@ -21,6 +21,7 @@ import org.signal.donations.InAppPaymentType import org.thoughtcrime.securesms.MainActivity import org.thoughtcrime.securesms.R import org.thoughtcrime.securesms.components.InputAwareLayout +import org.thoughtcrime.securesms.components.KeyboardAwareLinearLayout import org.thoughtcrime.securesms.components.emoji.EmojiEventListener import org.thoughtcrime.securesms.components.emoji.MediaKeyboard import org.thoughtcrime.securesms.components.settings.DSLConfiguration @@ -94,6 +95,7 @@ class GiftFlowConfirmationFragment : .create() inputAwareLayout = requireView().findViewById(R.id.input_aware_layout) + inputAwareLayout.setInsetPaddingMode(KeyboardAwareLinearLayout.InsetPaddingMode.KEYBOARD_AND_NAVIGATION_BAR) emojiKeyboard = requireView().findViewById(R.id.emoji_drawer) emojiKeyboard.setFragmentManager(childFragmentManager) diff --git a/app/src/main/java/org/thoughtcrime/securesms/badges/self/featured/SelectFeaturedBadgeFragment.kt b/app/src/main/java/org/thoughtcrime/securesms/badges/self/featured/SelectFeaturedBadgeFragment.kt index 6c421dd342..88477ba66c 100644 --- a/app/src/main/java/org/thoughtcrime/securesms/badges/self/featured/SelectFeaturedBadgeFragment.kt +++ b/app/src/main/java/org/thoughtcrime/securesms/badges/self/featured/SelectFeaturedBadgeFragment.kt @@ -50,8 +50,7 @@ class SelectFeaturedBadgeFragment : DSLSettingsFragment( return Material3OnScrollHelper( activity = requireActivity(), views = listOf(scrollShadow), - lifecycleOwner = viewLifecycleOwner, - setStatusBarColor = {} + lifecycleOwner = viewLifecycleOwner ) } diff --git a/app/src/main/java/org/thoughtcrime/securesms/calls/links/EditCallLinkNameDialogFragment.kt b/app/src/main/java/org/thoughtcrime/securesms/calls/links/EditCallLinkNameDialogFragment.kt index a29f6da7c9..e727148d7c 100644 --- a/app/src/main/java/org/thoughtcrime/securesms/calls/links/EditCallLinkNameDialogFragment.kt +++ b/app/src/main/java/org/thoughtcrime/securesms/calls/links/EditCallLinkNameDialogFragment.kt @@ -11,7 +11,9 @@ import android.view.WindowManager import androidx.activity.compose.LocalOnBackPressedDispatcherOwner import androidx.compose.foundation.layout.Column import androidx.compose.foundation.layout.Spacer +import androidx.compose.foundation.layout.consumeWindowInsets import androidx.compose.foundation.layout.fillMaxWidth +import androidx.compose.foundation.layout.imePadding import androidx.compose.foundation.layout.padding import androidx.compose.material3.Surface import androidx.compose.material3.Text @@ -43,6 +45,7 @@ import org.signal.core.ui.compose.Buttons import org.signal.core.ui.compose.ComposeDialogFragment import org.signal.core.ui.compose.Scaffolds import org.signal.core.ui.compose.SignalIcons +import org.signal.core.ui.enableEdgeToEdge import org.signal.core.ui.rememberIsSplitPane import org.signal.core.util.BreakIteratorCompat import org.thoughtcrime.securesms.R @@ -68,6 +71,7 @@ class EditCallLinkNameDialogFragment : ComposeDialogFragment() { override fun onCreateDialog(savedInstanceState: Bundle?): Dialog { val dialog = super.onCreateDialog(savedInstanceState) dialog.window?.setSoftInputMode(WindowManager.LayoutParams.SOFT_INPUT_ADJUST_RESIZE) + dialog.window?.enableEdgeToEdge() return dialog } @@ -143,7 +147,12 @@ private fun EditCallLinkNameScreen( val focusRequester = remember { FocusRequester() } val breakIterator = remember { BreakIteratorCompat.getInstance() } - Surface(modifier = Modifier.padding(paddingValues)) { + Surface( + modifier = Modifier + .padding(paddingValues) + .consumeWindowInsets(paddingValues) + .imePadding() + ) { Column( modifier = Modifier .padding( diff --git a/app/src/main/java/org/thoughtcrime/securesms/chats/ChatsNavigation.kt b/app/src/main/java/org/thoughtcrime/securesms/chats/ChatsNavigation.kt index 0da00027d0..a71f68e0d4 100644 --- a/app/src/main/java/org/thoughtcrime/securesms/chats/ChatsNavigation.kt +++ b/app/src/main/java/org/thoughtcrime/securesms/chats/ChatsNavigation.kt @@ -8,8 +8,6 @@ package org.thoughtcrime.securesms.chats import android.os.Bundle import androidx.compose.foundation.background import androidx.compose.foundation.layout.fillMaxSize -import androidx.compose.foundation.layout.navigationBarsPadding -import androidx.compose.foundation.layout.statusBarsPadding import androidx.compose.material3.MaterialTheme import androidx.compose.runtime.Composable import androidx.compose.runtime.LaunchedEffect @@ -124,8 +122,6 @@ private fun MessageDetailsEntry(route: MainNavigationDetailLocation.Chats.Messag modifier = Modifier .fillMaxSize() .background(MaterialTheme.colorScheme.background) - .statusBarsPadding() - .navigationBarsPadding() ) } diff --git a/app/src/main/java/org/thoughtcrime/securesms/components/FullScreenDialogFragment.java b/app/src/main/java/org/thoughtcrime/securesms/components/FullScreenDialogFragment.java index 1fd3167b2b..8d7a77b12c 100644 --- a/app/src/main/java/org/thoughtcrime/securesms/components/FullScreenDialogFragment.java +++ b/app/src/main/java/org/thoughtcrime/securesms/components/FullScreenDialogFragment.java @@ -1,5 +1,6 @@ package org.thoughtcrime.securesms.components; +import android.app.Dialog; import android.os.Bundle; import android.view.LayoutInflater; import android.view.View; @@ -12,7 +13,9 @@ import androidx.annotation.StringRes; import androidx.appcompat.widget.Toolbar; import androidx.fragment.app.DialogFragment; +import org.signal.core.ui.WindowExtensionsKt; import org.thoughtcrime.securesms.R; +import org.thoughtcrime.securesms.util.SystemWindowInsetsSetter; import org.thoughtcrime.securesms.util.WindowUtil; /** @@ -30,6 +33,15 @@ public abstract class FullScreenDialogFragment extends DialogFragment { setStyle(STYLE_NO_FRAME, R.style.Signal_DayNight_Dialog_FullScreen); } + @Override + public @NonNull Dialog onCreateDialog(@Nullable Bundle savedInstanceState) { + Dialog dialog = super.onCreateDialog(savedInstanceState); + if (dialog.getWindow() != null) { + WindowExtensionsKt.enableEdgeToEdge(dialog.getWindow()); + } + return dialog; + } + @Override public final @NonNull View onCreateView(@NonNull LayoutInflater inflater, @Nullable ViewGroup container, @Nullable Bundle savedInstanceState) { View view = inflater.inflate(R.layout.full_screen_dialog_fragment, container, false); @@ -41,6 +53,8 @@ public abstract class FullScreenDialogFragment extends DialogFragment { } toolbar.setNavigationOnClickListener(v -> onNavigateUp()); + + SystemWindowInsetsSetter.attach(view, getViewLifecycleOwner()); return view; } diff --git a/app/src/main/java/org/thoughtcrime/securesms/components/KeyboardAwareLinearLayout.java b/app/src/main/java/org/thoughtcrime/securesms/components/KeyboardAwareLinearLayout.java index a97156b359..18c469f694 100644 --- a/app/src/main/java/org/thoughtcrime/securesms/components/KeyboardAwareLinearLayout.java +++ b/app/src/main/java/org/thoughtcrime/securesms/components/KeyboardAwareLinearLayout.java @@ -17,40 +17,37 @@ package org.thoughtcrime.securesms.components; import android.content.Context; -import android.graphics.Rect; -import android.os.Build; +import android.content.res.Configuration; import android.preference.PreferenceManager; import android.util.AttributeSet; -import android.util.DisplayMetrics; -import android.view.Surface; -import android.view.View; -import android.view.WindowInsets; +import androidx.annotation.NonNull; import androidx.appcompat.widget.LinearLayoutCompat; +import androidx.core.graphics.Insets; +import androidx.core.view.ViewCompat; +import androidx.core.view.WindowInsetsCompat; import org.signal.core.util.logging.Log; import org.thoughtcrime.securesms.R; -import org.signal.core.util.ServiceUtil; import org.signal.core.util.Util; -import org.thoughtcrime.securesms.util.ViewUtil; -import java.lang.reflect.Field; import java.util.HashSet; import java.util.Set; /** * LinearLayout that, when a view container, will report back when it thinks a soft keyboard - * has been opened and what its height would be. + * has been opened and what its height would be. Driven by {@link WindowInsetsCompat.Type#ime()} + * insets, so it requires an edge-to-edge host window (all activity and dialog windows in the app + * are edge-to-edge). The reported height excludes the navigation bar, matching what a custom + * keyboard sitting above a navigation-bar-padded container should be sized to. */ public class KeyboardAwareLinearLayout extends LinearLayoutCompat { private static final String TAG = Log.tag(KeyboardAwareLinearLayout.class); private static final long KEYBOARD_DEBOUNCE = 150; - private final Rect rect = new Rect(); private final Set hiddenListeners = new HashSet<>(); private final Set shownListeners = new HashSet<>(); - private final DisplayMetrics displayMetrics = new DisplayMetrics(); private final int minKeyboardSize; private final int minCustomKeyboardSize; @@ -58,14 +55,14 @@ public class KeyboardAwareLinearLayout extends LinearLayoutCompat { private final int minCustomKeyboardTopMarginPortrait; private final int minCustomKeyboardTopMarginLandscape; private final int minCustomKeyboardTopMarginLandscapeBubble; - private final int statusBarHeight; - - private int viewInset; private boolean keyboardOpen = false; - private int rotation = 0; private boolean isBubble = false; private long openedAt = 0; + private int lastKeyboardHeight; + private boolean lastKeyboardVisible; + + private InsetPaddingMode insetPaddingMode = InsetPaddingMode.NONE; public KeyboardAwareLinearLayout(Context context) { this(context, null); @@ -83,48 +80,71 @@ public class KeyboardAwareLinearLayout extends LinearLayoutCompat { minCustomKeyboardTopMarginPortrait = getResources().getDimensionPixelSize(R.dimen.min_custom_keyboard_top_margin_portrait); minCustomKeyboardTopMarginLandscape = getResources().getDimensionPixelSize(R.dimen.min_custom_keyboard_top_margin_portrait); minCustomKeyboardTopMarginLandscapeBubble = getResources().getDimensionPixelSize(R.dimen.min_custom_keyboard_top_margin_landscape_bubble); - statusBarHeight = ViewUtil.getStatusBarHeight(this); - viewInset = getViewInset(); - } - @Override - protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) { - updateRotation(); - updateKeyboardState(); - super.onMeasure(widthMeasureSpec, heightMeasureSpec); + ViewCompat.setOnApplyWindowInsetsListener(this, (view, insets) -> { + Insets ime = insets.getInsets(WindowInsetsCompat.Type.ime()); + Insets nav = insets.getInsets(WindowInsetsCompat.Type.navigationBars()); + Insets bars = insets.getInsets(WindowInsetsCompat.Type.systemBars()); + + lastKeyboardHeight = Math.max(0, ime.bottom - nav.bottom); + lastKeyboardVisible = insets.isVisible(WindowInsetsCompat.Type.ime()); + + switch (insetPaddingMode) { + case NONE: + break; + case KEYBOARD: + setPadding(getPaddingLeft(), getPaddingTop(), getPaddingRight(), lastKeyboardVisible ? lastKeyboardHeight : 0); + break; + case KEYBOARD_AND_NAVIGATION_BAR: + setPadding(getPaddingLeft(), getPaddingTop(), getPaddingRight(), Math.max(nav.bottom, ime.bottom)); + break; + case SAFE_AREA: + setPadding(bars.left, bars.top, bars.right, Math.max(bars.bottom, ime.bottom)); + break; + } + + updateKeyboardState(); + + return insets; + }); } public void setIsBubble(boolean isBubble) { this.isBubble = isBubble; } - private void updateRotation() { - int oldRotation = rotation; - rotation = getDeviceRotation(); - if (oldRotation != rotation) { - Log.i(TAG, "rotation changed"); - onKeyboardClose(); - } + /** + * Opt-in self-padding, replacing the window resize behavior these layouts relied on before the + * host windows went edge-to-edge. [InsetPaddingMode.NONE] keeps the layout as a pure keyboard + * event source (e.g. when a parent container already manages insets). + */ + public void setInsetPaddingMode(@NonNull InsetPaddingMode mode) { + this.insetPaddingMode = mode; + ViewCompat.requestApplyInsets(this); + } + + public enum InsetPaddingMode { + /** Apply no padding; the layout only reports keyboard events. */ + NONE, + /** Pad the bottom by the keyboard height above the navigation bar (use inside a container that already clears the navigation bar). */ + KEYBOARD, + /** Pad the bottom by the keyboard or navigation bar, whichever is larger. */ + KEYBOARD_AND_NAVIGATION_BAR, + /** Pad all sides by the system bars, and the bottom by the keyboard when it is taller. */ + SAFE_AREA } private void updateKeyboardState() { - if (viewInset == 0) viewInset = getViewInset(); - - getWindowVisibleDisplayFrame(rect); - - final int availableHeight = getAvailableHeight(); - final int keyboardHeight = availableHeight - rect.bottom; - - if (keyboardHeight > minKeyboardSize) { - if (getKeyboardHeight() != keyboardHeight) { + if (lastKeyboardVisible && lastKeyboardHeight > minKeyboardSize) { + if (getKeyboardHeight() != lastKeyboardHeight) { if (isLandscape()) { - setKeyboardLandscapeHeight(keyboardHeight); + setKeyboardLandscapeHeight(lastKeyboardHeight); } else { - setKeyboardPortraitHeight(keyboardHeight); + setKeyboardPortraitHeight(lastKeyboardHeight); } } if (!keyboardOpen) { - onKeyboardOpen(keyboardHeight); + onKeyboardOpen(lastKeyboardHeight); } } else if (keyboardOpen) { onKeyboardClose(); @@ -134,53 +154,7 @@ public class KeyboardAwareLinearLayout extends LinearLayoutCompat { @Override protected void onAttachedToWindow() { super.onAttachedToWindow(); - rotation = getDeviceRotation(); - if (getRootWindowInsets() != null) { - int bottomInset; - WindowInsets windowInsets = getRootWindowInsets(); - - if (Build.VERSION.SDK_INT >= 30) { - bottomInset = windowInsets.getInsets(WindowInsets.Type.navigationBars()).bottom; - } else { - bottomInset = windowInsets.getStableInsetBottom(); - } - - if (bottomInset != 0 && (viewInset == 0 || viewInset == statusBarHeight)) { - Log.i(TAG, "Updating view inset based on WindowInsets. viewInset: " + viewInset + " windowInset: " + bottomInset); - viewInset = bottomInset; - } - } - } - - private int getViewInset() { - try { - Field attachInfoField = View.class.getDeclaredField("mAttachInfo"); - attachInfoField.setAccessible(true); - Object attachInfo = attachInfoField.get(this); - if (attachInfo != null) { - Field stableInsetsField = attachInfo.getClass().getDeclaredField("mStableInsets"); - stableInsetsField.setAccessible(true); - Rect insets = (Rect) stableInsetsField.get(attachInfo); - if (insets != null) { - return insets.bottom; - } - } - } catch (NoSuchFieldException | IllegalAccessException e) { - // Do nothing - } - return statusBarHeight; - } - - private int getAvailableHeight() { - final int availableHeight = this.getRootView().getHeight() - viewInset; - final int availableWidth = this.getRootView().getWidth(); - - if (isLandscape() && availableHeight > availableWidth) { - //noinspection SuspiciousNameCombination - return availableWidth; - } - - return availableHeight; + ViewCompat.requestApplyInsets(this); } protected void onKeyboardOpen(int keyboardHeight) { @@ -213,21 +187,7 @@ public class KeyboardAwareLinearLayout extends LinearLayoutCompat { } public boolean isLandscape() { - int rotation = getDeviceRotation(); - return rotation == Surface.ROTATION_90 || rotation == Surface.ROTATION_270; - } - - private int getDeviceRotation() { - if (isInEditMode()) { - return Surface.ROTATION_0; - } - - if (Build.VERSION.SDK_INT >= 30) { - getContext().getDisplay().getRealMetrics(displayMetrics); - } else { - ServiceUtil.getWindowManager(getContext()).getDefaultDisplay().getRealMetrics(displayMetrics); - } - return displayMetrics.widthPixels > displayMetrics.heightPixels ? Surface.ROTATION_90 : Surface.ROTATION_0; + return getResources().getConfiguration().orientation == Configuration.ORIENTATION_LANDSCAPE; } private int getKeyboardLandscapeHeight() { diff --git a/app/src/main/java/org/thoughtcrime/securesms/components/KeyboardEntryDialogFragment.kt b/app/src/main/java/org/thoughtcrime/securesms/components/KeyboardEntryDialogFragment.kt index 9c2a2bbe63..621936437f 100644 --- a/app/src/main/java/org/thoughtcrime/securesms/components/KeyboardEntryDialogFragment.kt +++ b/app/src/main/java/org/thoughtcrime/securesms/components/KeyboardEntryDialogFragment.kt @@ -8,6 +8,7 @@ import android.view.ViewGroup import android.view.WindowManager import androidx.annotation.LayoutRes import androidx.fragment.app.DialogFragment +import org.signal.core.ui.enableEdgeToEdge import org.thoughtcrime.securesms.R /** @@ -38,6 +39,7 @@ abstract class KeyboardEntryDialogFragment(@LayoutRes contentLayoutId: Int) : } dialog.window?.setSoftInputMode(WindowManager.LayoutParams.SOFT_INPUT_ADJUST_RESIZE or WindowManager.LayoutParams.SOFT_INPUT_STATE_ALWAYS_VISIBLE) + dialog.window?.enableEdgeToEdge() return dialog } @@ -47,6 +49,7 @@ abstract class KeyboardEntryDialogFragment(@LayoutRes contentLayoutId: Int) : val view = super.onCreateView(inflater, container, savedInstanceState) return if (view is KeyboardAwareLinearLayout) { + view.setInsetPaddingMode(KeyboardAwareLinearLayout.InsetPaddingMode.SAFE_AREA) view.addOnKeyboardShownListener(this) view.addOnKeyboardHiddenListener(this) view diff --git a/app/src/main/java/org/thoughtcrime/securesms/components/WrapperDialogFragment.kt b/app/src/main/java/org/thoughtcrime/securesms/components/WrapperDialogFragment.kt index 58ca56ac02..53167e9bd4 100644 --- a/app/src/main/java/org/thoughtcrime/securesms/components/WrapperDialogFragment.kt +++ b/app/src/main/java/org/thoughtcrime/securesms/components/WrapperDialogFragment.kt @@ -1,11 +1,13 @@ package org.thoughtcrime.securesms.components +import android.app.Dialog import android.content.DialogInterface import android.os.Bundle import android.view.View import androidx.activity.OnBackPressedCallback import androidx.fragment.app.DialogFragment import androidx.fragment.app.Fragment +import org.signal.core.ui.enableEdgeToEdge import org.signal.core.ui.initializeScreenshotSecurity import org.thoughtcrime.securesms.R import org.thoughtcrime.securesms.util.fragments.findListener @@ -41,6 +43,12 @@ abstract class WrapperDialogFragment : DialogFragment(R.layout.fragment_containe setStyle(STYLE_NO_FRAME, R.style.Signal_DayNight_Dialog_FullScreen) } + override fun onCreateDialog(savedInstanceState: Bundle?): Dialog { + return super.onCreateDialog(savedInstanceState).apply { + window?.enableEdgeToEdge() + } + } + override fun onViewCreated(view: View, savedInstanceState: Bundle?) { requireActivity().onBackPressedDispatcher.addCallback( viewLifecycleOwner, diff --git a/app/src/main/java/org/thoughtcrime/securesms/components/settings/DSLSettingsFragment.kt b/app/src/main/java/org/thoughtcrime/securesms/components/settings/DSLSettingsFragment.kt index e592652b47..ecd007a51d 100644 --- a/app/src/main/java/org/thoughtcrime/securesms/components/settings/DSLSettingsFragment.kt +++ b/app/src/main/java/org/thoughtcrime/securesms/components/settings/DSLSettingsFragment.kt @@ -14,8 +14,6 @@ import androidx.appcompat.widget.Toolbar import androidx.core.content.ContextCompat import androidx.core.view.WindowInsetsCompat import androidx.core.view.updateLayoutParams -import androidx.fragment.app.DialogFragment -import androidx.fragment.app.Fragment import androidx.recyclerview.widget.ConcatAdapter import androidx.recyclerview.widget.LinearLayoutManager import androidx.recyclerview.widget.RecyclerView @@ -88,15 +86,17 @@ abstract class DSLSettingsFragment( } /** - * Activity windows are all edge-to-edge (enabled centrally in [org.thoughtcrime.securesms.BaseActivity]), - * so the toolbar tint must extend behind the (transparent) status bar and the list must scroll clear of - * the navigation bar. Skipped for dialog windows (not edge-to-edge) and for fragments embedded directly in + * All host windows are edge-to-edge — activities centrally via [org.thoughtcrime.securesms.BaseActivity], + * and the full-screen dialog hosts ([org.thoughtcrime.securesms.components.WrapperDialogFragment], + * [org.thoughtcrime.securesms.stories.settings.create.CreateStoryFlowDialogFragment]) via their own + * `enableEdgeToEdge` calls — so the toolbar tint must extend behind the (transparent) status bar and the + * list must scroll clear of the navigation bar. Skipped only for fragments embedded directly in * [MainActivity]'s Compose scaffolding, which insets those containers itself — except the * conversation-settings detail entry ([ConversationSettingsNavHostFragment]), which leaves insets to these * fragments so the toolbar scroll tint can reach behind the status bar. */ private fun applyEdgeToEdgeInsets() { - if (isDialogHosted() || isInsetByMainActivityHost()) { + if (isInsetByMainActivityHost()) { return } @@ -111,17 +111,6 @@ abstract class DSLSettingsFragment( } } - private fun isDialogHosted(): Boolean { - var fragment: Fragment? = this - while (fragment != null) { - if (fragment is DialogFragment && fragment.showsDialog) { - return true - } - fragment = fragment.parentFragment - } - return false - } - private fun isInsetByMainActivityHost(): Boolean { if (activity !is MainActivity) { return false @@ -137,8 +126,7 @@ abstract class DSLSettingsFragment( return Material3OnScrollHelper( activity = requireActivity(), views = listOf(toolbar), - lifecycleOwner = viewLifecycleOwner, - setStatusBarColor = {} + lifecycleOwner = viewLifecycleOwner ) } diff --git a/app/src/main/java/org/thoughtcrime/securesms/components/settings/app/subscription/donate/DonateToSignalFragment.kt b/app/src/main/java/org/thoughtcrime/securesms/components/settings/app/subscription/donate/DonateToSignalFragment.kt index 9c2d46e151..3aa80a4a69 100644 --- a/app/src/main/java/org/thoughtcrime/securesms/components/settings/app/subscription/donate/DonateToSignalFragment.kt +++ b/app/src/main/java/org/thoughtcrime/securesms/components/settings/app/subscription/donate/DonateToSignalFragment.kt @@ -114,9 +114,9 @@ class DonateToSignalFragment : } override fun getMaterial3OnScrollHelper(toolbar: Toolbar?): Material3OnScrollHelper { - return object : Material3OnScrollHelper(activity = requireActivity(), views = listOf(toolbar!!), lifecycleOwner = viewLifecycleOwner, setStatusBarColor = {}) { - override val activeColorSet: ColorSet = ColorSet(R.color.transparent, CoreUiR.color.signal_colorBackground) - override val inactiveColorSet: ColorSet = ColorSet(R.color.transparent, CoreUiR.color.signal_colorBackground) + return object : Material3OnScrollHelper(activity = requireActivity(), views = listOf(toolbar!!), lifecycleOwner = viewLifecycleOwner) { + override val activeColorSet: ColorSet = ColorSet(R.color.transparent) + override val inactiveColorSet: ColorSet = ColorSet(R.color.transparent) } } diff --git a/app/src/main/java/org/thoughtcrime/securesms/components/settings/app/subscription/donate/paypal/PayPalConfirmationDialogFragment.kt b/app/src/main/java/org/thoughtcrime/securesms/components/settings/app/subscription/donate/paypal/PayPalConfirmationDialogFragment.kt index 2a9ab1f51e..77427e2a3d 100644 --- a/app/src/main/java/org/thoughtcrime/securesms/components/settings/app/subscription/donate/paypal/PayPalConfirmationDialogFragment.kt +++ b/app/src/main/java/org/thoughtcrime/securesms/components/settings/app/subscription/donate/paypal/PayPalConfirmationDialogFragment.kt @@ -1,6 +1,7 @@ package org.thoughtcrime.securesms.components.settings.app.subscription.donate.paypal import android.annotation.SuppressLint +import android.app.Dialog import android.content.DialogInterface import android.graphics.Bitmap import android.os.Bundle @@ -15,12 +16,14 @@ import androidx.fragment.app.setFragmentResult import androidx.lifecycle.DefaultLifecycleObserver import androidx.lifecycle.LifecycleOwner import androidx.navigation.fragment.navArgs +import org.signal.core.ui.enableEdgeToEdge import org.signal.core.util.logging.Log import org.thoughtcrime.securesms.R import org.thoughtcrime.securesms.components.ViewBinderDelegate import org.thoughtcrime.securesms.components.settings.app.subscription.PayPalRepository import org.thoughtcrime.securesms.components.settings.app.subscription.donate.DonationWebViewOnBackPressedCallback import org.thoughtcrime.securesms.databinding.DonationWebviewFragmentBinding +import org.thoughtcrime.securesms.util.SystemWindowInsetsSetter import org.thoughtcrime.securesms.util.visible /** @@ -49,8 +52,16 @@ class PayPalConfirmationDialogFragment : DialogFragment(R.layout.donation_webvie setStyle(STYLE_NO_FRAME, R.style.Signal_DayNight_Dialog_FullScreen) } + override fun onCreateDialog(savedInstanceState: Bundle?): Dialog { + return super.onCreateDialog(savedInstanceState).apply { + window?.enableEdgeToEdge() + } + } + @SuppressLint("SetJavaScriptEnabled") override fun onViewCreated(view: View, savedInstanceState: Bundle?) { + SystemWindowInsetsSetter.attach(view, viewLifecycleOwner) + val client = PayPalWebClient() viewLifecycleOwner.lifecycle.addObserver(client) binding.webView.webViewClient = client diff --git a/app/src/main/java/org/thoughtcrime/securesms/components/settings/app/subscription/donate/stripe/Stripe3DSDialogFragment.kt b/app/src/main/java/org/thoughtcrime/securesms/components/settings/app/subscription/donate/stripe/Stripe3DSDialogFragment.kt index 70ed2763b1..7acd4c39ea 100644 --- a/app/src/main/java/org/thoughtcrime/securesms/components/settings/app/subscription/donate/stripe/Stripe3DSDialogFragment.kt +++ b/app/src/main/java/org/thoughtcrime/securesms/components/settings/app/subscription/donate/stripe/Stripe3DSDialogFragment.kt @@ -1,6 +1,7 @@ package org.thoughtcrime.securesms.components.settings.app.subscription.donate.stripe import android.annotation.SuppressLint +import android.app.Dialog import android.content.DialogInterface import android.content.Intent import android.graphics.Bitmap @@ -24,6 +25,7 @@ import com.google.android.material.button.MaterialButton import kotlinx.coroutines.Dispatchers import kotlinx.coroutines.launch import kotlinx.coroutines.withContext +import org.signal.core.ui.enableEdgeToEdge import org.signal.core.util.concurrent.LifecycleDisposable import org.signal.donations.StripeIntentAccessor import org.thoughtcrime.securesms.R @@ -35,6 +37,7 @@ import org.thoughtcrime.securesms.database.model.databaseprotos.InAppPaymentData import org.thoughtcrime.securesms.databinding.DonationWebviewFragmentBinding import org.thoughtcrime.securesms.util.Environment import org.thoughtcrime.securesms.util.RemoteConfig +import org.thoughtcrime.securesms.util.SystemWindowInsetsSetter import org.thoughtcrime.securesms.util.visible /** @@ -64,9 +67,16 @@ class Stripe3DSDialogFragment : DialogFragment(R.layout.donation_webview_fragmen setStyle(STYLE_NO_FRAME, R.style.Signal_DayNight_Dialog_FullScreen) } + override fun onCreateDialog(savedInstanceState: Bundle?): Dialog { + return super.onCreateDialog(savedInstanceState).apply { + window?.enableEdgeToEdge() + } + } + @SuppressLint("SetJavaScriptEnabled", "SetTextI18n") override fun onViewCreated(view: View, savedInstanceState: Bundle?) { lifecycleDisposable.bindTo(viewLifecycleOwner) + SystemWindowInsetsSetter.attach(view, viewLifecycleOwner) dialog!!.window!!.setFlags( WindowManager.LayoutParams.FLAG_HARDWARE_ACCELERATED, diff --git a/app/src/main/java/org/thoughtcrime/securesms/components/settings/app/subscription/donate/transfer/details/BankTransferDetailsFragment.kt b/app/src/main/java/org/thoughtcrime/securesms/components/settings/app/subscription/donate/transfer/details/BankTransferDetailsFragment.kt index 364b232079..d89c42091a 100644 --- a/app/src/main/java/org/thoughtcrime/securesms/components/settings/app/subscription/donate/transfer/details/BankTransferDetailsFragment.kt +++ b/app/src/main/java/org/thoughtcrime/securesms/components/settings/app/subscription/donate/transfer/details/BankTransferDetailsFragment.kt @@ -9,9 +9,11 @@ import android.os.Bundle import android.view.View import androidx.compose.foundation.layout.Box import androidx.compose.foundation.layout.Column +import androidx.compose.foundation.layout.consumeWindowInsets import androidx.compose.foundation.layout.defaultMinSize import androidx.compose.foundation.layout.fillMaxHeight import androidx.compose.foundation.layout.fillMaxWidth +import androidx.compose.foundation.layout.imePadding import androidx.compose.foundation.layout.padding import androidx.compose.foundation.lazy.LazyColumn import androidx.compose.foundation.text.KeyboardActions @@ -231,6 +233,8 @@ fun BankTransferDetailsContent( .fillMaxWidth() .fillMaxHeight() .padding(it) + .consumeWindowInsets(it) + .imePadding() ) { val focusManager = LocalFocusManager.current val focusRequester = remember { FocusRequester() } diff --git a/app/src/main/java/org/thoughtcrime/securesms/components/settings/app/subscription/donate/transfer/ideal/IdealTransferDetailsFragment.kt b/app/src/main/java/org/thoughtcrime/securesms/components/settings/app/subscription/donate/transfer/ideal/IdealTransferDetailsFragment.kt index 19b8c6a949..add891a2a4 100644 --- a/app/src/main/java/org/thoughtcrime/securesms/components/settings/app/subscription/donate/transfer/ideal/IdealTransferDetailsFragment.kt +++ b/app/src/main/java/org/thoughtcrime/securesms/components/settings/app/subscription/donate/transfer/ideal/IdealTransferDetailsFragment.kt @@ -9,8 +9,10 @@ import android.os.Bundle import android.view.View import androidx.annotation.StringRes import androidx.compose.foundation.layout.Column +import androidx.compose.foundation.layout.consumeWindowInsets import androidx.compose.foundation.layout.defaultMinSize import androidx.compose.foundation.layout.fillMaxWidth +import androidx.compose.foundation.layout.imePadding import androidx.compose.foundation.layout.padding import androidx.compose.foundation.lazy.LazyColumn import androidx.compose.foundation.text.KeyboardActions @@ -237,7 +239,10 @@ private fun IdealTransferDetailsContent( Column( horizontalAlignment = CenterHorizontally, - modifier = Modifier.padding(it) + modifier = Modifier + .padding(it) + .consumeWindowInsets(it) + .imePadding() ) { LazyColumn( modifier = Modifier diff --git a/app/src/main/java/org/thoughtcrime/securesms/components/settings/app/subscription/manage/ManageDonationsFragment.kt b/app/src/main/java/org/thoughtcrime/securesms/components/settings/app/subscription/manage/ManageDonationsFragment.kt index 7468fa157c..21df16b43d 100644 --- a/app/src/main/java/org/thoughtcrime/securesms/components/settings/app/subscription/manage/ManageDonationsFragment.kt +++ b/app/src/main/java/org/thoughtcrime/securesms/components/settings/app/subscription/manage/ManageDonationsFragment.kt @@ -137,9 +137,9 @@ class ManageDonationsFragment : } override fun getMaterial3OnScrollHelper(toolbar: Toolbar?): Material3OnScrollHelper { - return object : Material3OnScrollHelper(activity = requireActivity(), views = listOf(toolbar!!), lifecycleOwner = viewLifecycleOwner, setStatusBarColor = {}) { - override val activeColorSet: ColorSet = ColorSet(R.color.transparent, CoreUiR.color.signal_colorBackground) - override val inactiveColorSet: ColorSet = ColorSet(R.color.transparent, CoreUiR.color.signal_colorBackground) + return object : Material3OnScrollHelper(activity = requireActivity(), views = listOf(toolbar!!), lifecycleOwner = viewLifecycleOwner) { + override val activeColorSet: ColorSet = ColorSet(R.color.transparent) + override val inactiveColorSet: ColorSet = ColorSet(R.color.transparent) } } diff --git a/app/src/main/java/org/thoughtcrime/securesms/components/settings/conversation/ConversationSettingsFragment.kt b/app/src/main/java/org/thoughtcrime/securesms/components/settings/conversation/ConversationSettingsFragment.kt index ad7b95f654..c4ee0e0d96 100644 --- a/app/src/main/java/org/thoughtcrime/securesms/components/settings/conversation/ConversationSettingsFragment.kt +++ b/app/src/main/java/org/thoughtcrime/securesms/components/settings/conversation/ConversationSettingsFragment.kt @@ -272,12 +272,10 @@ class ConversationSettingsFragment : return object : Material3OnScrollHelper( activity = requireActivity(), views = listOf(toolbar!!), - lifecycleOwner = viewLifecycleOwner, - setStatusBarColor = {} + lifecycleOwner = viewLifecycleOwner ) { override val inactiveColorSet = ColorSet( - toolbarColorRes = CoreUiR.color.signal_colorBackground_0, - statusBarColorRes = CoreUiR.color.signal_colorBackground + toolbarColorRes = CoreUiR.color.signal_colorBackground_0 ) } } diff --git a/app/src/main/java/org/thoughtcrime/securesms/conversation/clicklisteners/PollVotesFragment.kt b/app/src/main/java/org/thoughtcrime/securesms/conversation/clicklisteners/PollVotesFragment.kt index 3badd31d35..7a22c13537 100644 --- a/app/src/main/java/org/thoughtcrime/securesms/conversation/clicklisteners/PollVotesFragment.kt +++ b/app/src/main/java/org/thoughtcrime/securesms/conversation/clicklisteners/PollVotesFragment.kt @@ -1,5 +1,6 @@ package org.thoughtcrime.securesms.conversation.clicklisteners +import android.app.Dialog import android.os.Bundle import androidx.compose.foundation.Image import androidx.compose.foundation.background @@ -48,6 +49,7 @@ import org.signal.core.ui.compose.Previews import org.signal.core.ui.compose.Scaffolds import org.signal.core.ui.compose.SignalIcons import org.signal.core.ui.compose.horizontalGutters +import org.signal.core.ui.enableEdgeToEdge import org.signal.core.util.logging.Log import org.thoughtcrime.securesms.R import org.thoughtcrime.securesms.avatar.AvatarImage @@ -88,6 +90,12 @@ class PollVotesFragment : ComposeDialogFragment(), RecipientBottomSheetDialogFra setStyle(STYLE_NO_FRAME, R.style.Signal_DayNight_Dialog_FullScreen) } + override fun onCreateDialog(savedInstanceState: Bundle?): Dialog { + return super.onCreateDialog(savedInstanceState).apply { + window?.enableEdgeToEdge() + } + } + @Composable override fun DialogContent() { val state by viewModel.state.collectAsStateWithLifecycle() diff --git a/app/src/main/java/org/thoughtcrime/securesms/conversation/mutiselect/forward/MultiselectForwardFragment.kt b/app/src/main/java/org/thoughtcrime/securesms/conversation/mutiselect/forward/MultiselectForwardFragment.kt index 042e8a5365..53866a968d 100644 --- a/app/src/main/java/org/thoughtcrime/securesms/conversation/mutiselect/forward/MultiselectForwardFragment.kt +++ b/app/src/main/java/org/thoughtcrime/securesms/conversation/mutiselect/forward/MultiselectForwardFragment.kt @@ -203,7 +203,9 @@ class MultiselectForwardFragment : isSplitPane = isSplitPane, modifier = Modifier .fillMaxWidth() - .navigationBarsPadding() + // Bottom-sheet hosts already clear the navigation bar via BottomSheetBehavior's + // edge-to-edge padding; padding again here would double up. + .then(if (args.isWrappedInBottomSheet) Modifier else Modifier.navigationBarsPadding()) ) } } diff --git a/app/src/main/java/org/thoughtcrime/securesms/conversation/mutiselect/forward/MultiselectForwardFullScreenDialogFragment.kt b/app/src/main/java/org/thoughtcrime/securesms/conversation/mutiselect/forward/MultiselectForwardFullScreenDialogFragment.kt index 03c25acf2a..8f0a5c0506 100644 --- a/app/src/main/java/org/thoughtcrime/securesms/conversation/mutiselect/forward/MultiselectForwardFullScreenDialogFragment.kt +++ b/app/src/main/java/org/thoughtcrime/securesms/conversation/mutiselect/forward/MultiselectForwardFullScreenDialogFragment.kt @@ -1,5 +1,6 @@ package org.thoughtcrime.securesms.conversation.mutiselect.forward +import android.app.Dialog import android.os.Bundle import android.view.LayoutInflater import android.view.View @@ -7,6 +8,7 @@ import android.view.ViewGroup import androidx.core.content.ContextCompat import androidx.fragment.app.DialogFragment import androidx.fragment.app.setFragmentResult +import org.signal.core.ui.enableEdgeToEdge import org.thoughtcrime.securesms.R import org.thoughtcrime.securesms.stories.Stories import org.thoughtcrime.securesms.util.fragments.findListener @@ -19,6 +21,12 @@ class MultiselectForwardFullScreenDialogFragment : DialogFragment(), Multiselect setStyle(STYLE_NO_FRAME, R.style.Signal_DayNight_Dialog_FullScreen) } + override fun onCreateDialog(savedInstanceState: Bundle?): Dialog { + return super.onCreateDialog(savedInstanceState).apply { + window?.enableEdgeToEdge() + } + } + override fun onFinishForwardAction() { findListener()?.onFinishForwardAction() } diff --git a/app/src/main/java/org/thoughtcrime/securesms/conversation/v2/ConversationFragment.kt b/app/src/main/java/org/thoughtcrime/securesms/conversation/v2/ConversationFragment.kt index 1c22eee4c0..74ae22df5e 100644 --- a/app/src/main/java/org/thoughtcrime/securesms/conversation/v2/ConversationFragment.kt +++ b/app/src/main/java/org/thoughtcrime/securesms/conversation/v2/ConversationFragment.kt @@ -57,7 +57,6 @@ import androidx.constraintlayout.widget.ConstraintSet import androidx.core.app.ActivityOptionsCompat import androidx.core.content.ContextCompat import androidx.core.content.pm.ShortcutManagerCompat -import androidx.core.os.bundleOf import androidx.core.view.ViewCompat import androidx.core.view.WindowInsetsCompat import androidx.core.view.doOnPreDraw @@ -5178,9 +5177,7 @@ class ConversationFragment : private object MediaKeyboardFragmentCreator : InputAwareConstraintLayout.FragmentCreator { override val id: Int = MEDIA_KEYBOARD_FRAGMENT_CREATOR_ID - override fun create(): Fragment = KeyboardPagerFragment().apply { - arguments = bundleOf(KeyboardPagerFragment.ARG_SET_NAV_COLOR to false) - } + override fun create(): Fragment = KeyboardPagerFragment() } private inner class KeyboardEvents : diff --git a/app/src/main/java/org/thoughtcrime/securesms/conversation/v2/ConversationToolbarOnScrollHelper.kt b/app/src/main/java/org/thoughtcrime/securesms/conversation/v2/ConversationToolbarOnScrollHelper.kt index 4629f25676..3f0ebf7781 100644 --- a/app/src/main/java/org/thoughtcrime/securesms/conversation/v2/ConversationToolbarOnScrollHelper.kt +++ b/app/src/main/java/org/thoughtcrime/securesms/conversation/v2/ConversationToolbarOnScrollHelper.kt @@ -22,8 +22,7 @@ class ConversationToolbarOnScrollHelper( ) : Material3OnScrollHelper( activity = activity, views = listOf(toolbarBackground), - lifecycleOwner = lifecycleOwner, - setStatusBarColor = {} + lifecycleOwner = lifecycleOwner ) { override val activeColorSet: ColorSet get() = when { diff --git a/app/src/main/java/org/thoughtcrime/securesms/conversation/v2/CreatePollFragment.kt b/app/src/main/java/org/thoughtcrime/securesms/conversation/v2/CreatePollFragment.kt index 066e18b63d..34ec0ce7d8 100644 --- a/app/src/main/java/org/thoughtcrime/securesms/conversation/v2/CreatePollFragment.kt +++ b/app/src/main/java/org/thoughtcrime/securesms/conversation/v2/CreatePollFragment.kt @@ -63,6 +63,7 @@ import org.signal.core.ui.compose.list.ReorderListEvent import org.signal.core.ui.compose.list.ReorderableItem import org.signal.core.ui.compose.list.rememberReorderableListState import org.signal.core.ui.compose.list.reorderableList +import org.signal.core.ui.enableEdgeToEdge import org.signal.core.util.logging.Log import org.thoughtcrime.securesms.R import org.thoughtcrime.securesms.polls.Poll @@ -97,6 +98,7 @@ class CreatePollFragment : ComposeDialogFragment() { override fun onCreateDialog(savedInstanceState: Bundle?): Dialog { val dialog = super.onCreateDialog(savedInstanceState) dialog.window?.setSoftInputMode(WindowManager.LayoutParams.SOFT_INPUT_ADJUST_RESIZE) + dialog.window?.enableEdgeToEdge() return dialog } diff --git a/app/src/main/java/org/thoughtcrime/securesms/keyboard/KeyboardPagerFragment.kt b/app/src/main/java/org/thoughtcrime/securesms/keyboard/KeyboardPagerFragment.kt index 4fb47b936d..0739cacaea 100644 --- a/app/src/main/java/org/thoughtcrime/securesms/keyboard/KeyboardPagerFragment.kt +++ b/app/src/main/java/org/thoughtcrime/securesms/keyboard/KeyboardPagerFragment.kt @@ -4,11 +4,8 @@ import android.os.Bundle import android.view.LayoutInflater import android.view.View import android.view.ViewGroup -import android.view.Window -import androidx.fragment.app.DialogFragment import androidx.fragment.app.Fragment import androidx.lifecycle.ViewModelProvider -import org.signal.core.ui.util.ThemeUtil import org.thoughtcrime.securesms.R import org.thoughtcrime.securesms.components.InputAwareConstraintLayout import org.thoughtcrime.securesms.components.emoji.MediaKeyboard @@ -18,17 +15,12 @@ import org.thoughtcrime.securesms.keyboard.sticker.StickerKeyboardPageFragment import org.thoughtcrime.securesms.util.ThemedFragment.themeResId import org.thoughtcrime.securesms.util.ThemedFragment.themedInflate import org.thoughtcrime.securesms.util.ThemedFragment.withTheme -import org.thoughtcrime.securesms.util.WindowUtil import org.thoughtcrime.securesms.util.fragments.findListener import org.thoughtcrime.securesms.util.visible import kotlin.reflect.KClass class KeyboardPagerFragment : Fragment(), InputAwareConstraintLayout.InputFragment { - companion object { - val ARG_SET_NAV_COLOR = "args.setNavColor" - } - private lateinit var emojiButton: View private lateinit var stickerButton: View private lateinit var gifButton: View @@ -37,9 +29,6 @@ class KeyboardPagerFragment : Fragment(), InputAwareConstraintLayout.InputFragme private val fragments: MutableMap, Fragment> = mutableMapOf() private var currentFragment: Fragment? = null - private val shouldSetNavColor: Boolean - get() = arguments?.getBoolean(ARG_SET_NAV_COLOR) ?: true - override fun onCreateView(inflater: LayoutInflater, container: ViewGroup?, savedInstanceState: Bundle?): View? { return themedInflate(R.layout.keyboard_pager_fragment, inflater, container) } @@ -61,20 +50,6 @@ class KeyboardPagerFragment : Fragment(), InputAwareConstraintLayout.InputFragme emojiButton.setOnClickListener { viewModel.switchToPage(KeyboardPage.EMOJI) } stickerButton.setOnClickListener { viewModel.switchToPage(KeyboardPage.STICKER) } gifButton.setOnClickListener { viewModel.switchToPage(KeyboardPage.GIF) } - - onHiddenChanged(false) - } - - override fun onHiddenChanged(hidden: Boolean) { - if (shouldSetNavColor) { - getWindow()?.let { window -> - if (hidden) { - WindowUtil.setNavigationBarColor(requireContext(), window, ThemeUtil.getThemedColor(requireContext(), android.R.attr.navigationBarColor)) - } else { - WindowUtil.setNavigationBarColor(requireContext(), window, ThemeUtil.getThemedColor(requireContext(), R.attr.mediaKeyboardBottomBarBackgroundColor)) - } - } - } } @Suppress("DEPRECATION") @@ -83,19 +58,6 @@ class KeyboardPagerFragment : Fragment(), InputAwareConstraintLayout.InputFragme viewModel.page().value?.let(this::onPageSelected) } - private fun getWindow(): Window? { - var parent: Fragment? = parentFragment - while (parent != null) { - if (parent is DialogFragment) { - return parent.dialog?.window - } - - parent = parent.parentFragment - } - - return activity?.window - } - private fun onPageSelected(page: KeyboardPage) { emojiButton.isSelected = page == KeyboardPage.EMOJI stickerButton.isSelected = page == KeyboardPage.STICKER @@ -143,8 +105,6 @@ class KeyboardPagerFragment : Fragment(), InputAwareConstraintLayout.InputFragme override fun show() { findListener()?.onShown() if (isAdded && view != null) { - onHiddenChanged(false) - viewModel.page().value?.let(this::onPageSelected) } } @@ -152,8 +112,6 @@ class KeyboardPagerFragment : Fragment(), InputAwareConstraintLayout.InputFragme override fun hide() { findListener()?.onHidden() if (isAdded && view != null) { - onHiddenChanged(true) - val transaction = childFragmentManager.beginTransaction() fragments.values.forEach { transaction.remove(it) } transaction.commitAllowingStateLoss() diff --git a/app/src/main/java/org/thoughtcrime/securesms/keyboard/sticker/StickerSearchDialogFragment.kt b/app/src/main/java/org/thoughtcrime/securesms/keyboard/sticker/StickerSearchDialogFragment.kt index 208b22bdde..74d09f9a95 100644 --- a/app/src/main/java/org/thoughtcrime/securesms/keyboard/sticker/StickerSearchDialogFragment.kt +++ b/app/src/main/java/org/thoughtcrime/securesms/keyboard/sticker/StickerSearchDialogFragment.kt @@ -1,16 +1,20 @@ package org.thoughtcrime.securesms.keyboard.sticker +import android.app.Dialog import android.os.Bundle import android.view.LayoutInflater import android.view.View import android.view.ViewGroup import androidx.annotation.Px +import androidx.core.view.ViewCompat +import androidx.core.view.WindowInsetsCompat import androidx.fragment.app.DialogFragment import androidx.fragment.app.FragmentManager import androidx.lifecycle.ViewModelProvider import androidx.recyclerview.widget.GridLayoutManager import androidx.recyclerview.widget.RecyclerView import com.bumptech.glide.Glide +import org.signal.core.ui.enableEdgeToEdge import org.thoughtcrime.securesms.R import org.thoughtcrime.securesms.keyboard.emoji.KeyboardPageSearchView import org.thoughtcrime.securesms.stickers.StickerEventListener @@ -37,12 +41,24 @@ class StickerSearchDialogFragment : DialogFragment(), KeyboardStickerListAdapter setStyle(STYLE_NO_FRAME, R.style.Signal_DayNight_Dialog_Animated_Bottom) } + override fun onCreateDialog(savedInstanceState: Bundle?): Dialog { + return super.onCreateDialog(savedInstanceState).apply { + window?.enableEdgeToEdge() + } + } + override fun onCreateView(inflater: LayoutInflater, container: ViewGroup?, savedInstanceState: Bundle?): View? { return inflater.inflate(R.layout.sticker_search_dialog_fragment, container, false) } override fun onViewCreated(view: View, savedInstanceState: Bundle?) { super.onViewCreated(view, savedInstanceState) + ViewCompat.setOnApplyWindowInsetsListener(view) { v, insets -> + val safeArea = insets.getInsets(WindowInsetsCompat.Type.systemBars() or WindowInsetsCompat.Type.ime()) + v.setPadding(safeArea.left, safeArea.top, safeArea.right, safeArea.bottom) + insets + } + search = view.findViewById(R.id.sticker_search_text) list = view.findViewById(R.id.sticker_search_list) noResults = view.findViewById(R.id.sticker_search_no_results) diff --git a/app/src/main/java/org/thoughtcrime/securesms/maps/PlacePickerActivity.java b/app/src/main/java/org/thoughtcrime/securesms/maps/PlacePickerActivity.java index 0c62845917..05071dbb96 100644 --- a/app/src/main/java/org/thoughtcrime/securesms/maps/PlacePickerActivity.java +++ b/app/src/main/java/org/thoughtcrime/securesms/maps/PlacePickerActivity.java @@ -16,12 +16,15 @@ import android.os.Bundle; import android.view.View; import android.view.animation.OvershootInterpolator; +import androidx.activity.EdgeToEdge; import androidx.annotation.ColorInt; import androidx.annotation.NonNull; import androidx.annotation.Nullable; import androidx.appcompat.app.AppCompatActivity; import androidx.core.content.ContextCompat; +import androidx.core.graphics.Insets; import androidx.core.view.ViewCompat; +import androidx.core.view.WindowInsetsCompat; import androidx.fragment.app.Fragment; import com.google.android.gms.maps.CameraUpdateFactory; @@ -73,6 +76,7 @@ public final class PlacePickerActivity extends AppCompatActivity { private LatLng currentLocation = new LatLng(0, 0); private AddressLookup addressLookup; private GoogleMap googleMap; + private Insets systemBarInsets; public static void startActivityForResultAtCurrentLocation(@NonNull Fragment fragment, int requestCode, @ColorInt int chatColor) { fragment.startActivityForResult(new Intent(fragment.requireActivity(), PlacePickerActivity.class).putExtra(KEY_CHAT_COLOR, chatColor), requestCode); @@ -85,15 +89,23 @@ public final class PlacePickerActivity extends AppCompatActivity { @SuppressLint("MissingInflatedId") @Override public void onCreate(@Nullable Bundle savedInstanceState) { + EdgeToEdge.enable(this); super.onCreate(savedInstanceState); dynamicTheme.onCreate(this); - + setContentView(R.layout.activity_place_picker); bottomSheet = findViewById(R.id.bottom_sheet); View markerImage = findViewById(R.id.marker_image_view); View fab = findViewById(R.id.place_chosen_button); + ViewCompat.setOnApplyWindowInsetsListener(findViewById(android.R.id.content), (view, insets) -> { + systemBarInsets = insets.getInsets(WindowInsetsCompat.Type.systemBars()); + bottomSheet.setPadding(systemBarInsets.left, 0, systemBarInsets.right, systemBarInsets.bottom); + applyMapPadding(); + return insets; + }); + ViewCompat.setBackgroundTintList(fab, ColorStateList.valueOf(getIntent().getIntExtra(KEY_CHAT_COLOR, Color.RED))); fab.setOnClickListener(v -> finishWithAddress()); @@ -167,9 +179,16 @@ public final class PlacePickerActivity extends AppCompatActivity { private void setMap(GoogleMap googleMap) { this.googleMap = googleMap; + applyMapPadding(); moveMapToInitialIfPossible(); } + private void applyMapPadding() { + if (googleMap != null && systemBarInsets != null) { + googleMap.setPadding(systemBarInsets.left, systemBarInsets.top, systemBarInsets.right, systemBarInsets.bottom); + } + } + private void moveMapToInitialIfPossible() { if (initialLocation != null && googleMap != null) { Log.d(TAG, "Moving map to initial location"); diff --git a/app/src/main/java/org/thoughtcrime/securesms/mediasend/AvatarSelectionActivity.java b/app/src/main/java/org/thoughtcrime/securesms/mediasend/AvatarSelectionActivity.java index 0cde9f0884..1916fb10d5 100644 --- a/app/src/main/java/org/thoughtcrime/securesms/mediasend/AvatarSelectionActivity.java +++ b/app/src/main/java/org/thoughtcrime/securesms/mediasend/AvatarSelectionActivity.java @@ -5,8 +5,8 @@ import android.content.Intent; import android.graphics.Point; import android.net.Uri; import android.os.Bundle; -import android.view.WindowManager; +import androidx.activity.EdgeToEdge; import androidx.annotation.NonNull; import androidx.annotation.Nullable; import androidx.appcompat.app.AppCompatActivity; @@ -63,12 +63,9 @@ public class AvatarSelectionActivity extends AppCompatActivity implements Camera @Override protected void onCreate(@Nullable Bundle savedInstanceState) { + EdgeToEdge.enable(this); super.onCreate(savedInstanceState); - getWindow().addFlags( - WindowManager.LayoutParams.FLAG_LAYOUT_NO_LIMITS | WindowManager.LayoutParams.FLAG_LAYOUT_IN_SCREEN - ); - setContentView(R.layout.avatar_selection_activity); if (isGalleryFirst()) { diff --git a/app/src/main/java/org/thoughtcrime/securesms/mediasend/v2/gallery/MediaGalleryFragment.kt b/app/src/main/java/org/thoughtcrime/securesms/mediasend/v2/gallery/MediaGalleryFragment.kt index b0dec1ef9b..2109f5cc3e 100644 --- a/app/src/main/java/org/thoughtcrime/securesms/mediasend/v2/gallery/MediaGalleryFragment.kt +++ b/app/src/main/java/org/thoughtcrime/securesms/mediasend/v2/gallery/MediaGalleryFragment.kt @@ -115,8 +115,7 @@ class MediaGalleryFragment : Fragment(R.layout.v2_media_gallery_fragment) { Material3OnScrollHelper( activity = requireActivity(), views = listOf(binding.mediaGalleryToolbar, binding.mediaGalleryStatusBarBackground), - lifecycleOwner = viewLifecycleOwner, - setStatusBarColor = {} + lifecycleOwner = viewLifecycleOwner ).attach(binding.mediaGalleryGrid) if (callbacks.isCameraEnabled()) { diff --git a/app/src/main/java/org/thoughtcrime/securesms/messagedetails/MessageDetailsFragment.kt b/app/src/main/java/org/thoughtcrime/securesms/messagedetails/MessageDetailsFragment.kt index 16e1438ce1..312783e044 100644 --- a/app/src/main/java/org/thoughtcrime/securesms/messagedetails/MessageDetailsFragment.kt +++ b/app/src/main/java/org/thoughtcrime/securesms/messagedetails/MessageDetailsFragment.kt @@ -51,6 +51,7 @@ import org.thoughtcrime.securesms.recipients.RecipientId import org.thoughtcrime.securesms.safety.SafetyNumberBottomSheet.forOutgoingMessageRecord import org.thoughtcrime.securesms.stickers.StickerLocator import org.thoughtcrime.securesms.util.Material3OnScrollHelper +import org.thoughtcrime.securesms.util.SystemWindowInsetsSetter import org.thoughtcrime.securesms.util.fragments.requireListener class MessageDetailsFragment : Fragment(), MessageDetailsAdapter.Callbacks { @@ -70,6 +71,8 @@ class MessageDetailsFragment : Fragment(), MessageDetailsAdapter.Callbacks { toolbar.setTitle(R.string.AndroidManifest__message_details) toolbar.setNavigationOnClickListener { requireActivity().onBackPressedDispatcher.onBackPressed() } + SystemWindowInsetsSetter.attach(view, viewLifecycleOwner) + return view } diff --git a/app/src/main/java/org/thoughtcrime/securesms/pin/PinRestoreActivity.java b/app/src/main/java/org/thoughtcrime/securesms/pin/PinRestoreActivity.java index a4967e831c..02b1cff4d1 100644 --- a/app/src/main/java/org/thoughtcrime/securesms/pin/PinRestoreActivity.java +++ b/app/src/main/java/org/thoughtcrime/securesms/pin/PinRestoreActivity.java @@ -2,9 +2,14 @@ package org.thoughtcrime.securesms.pin; import android.content.Intent; import android.os.Bundle; +import android.view.View; +import androidx.activity.EdgeToEdge; import androidx.annotation.Nullable; import androidx.appcompat.app.AppCompatActivity; +import androidx.core.graphics.Insets; +import androidx.core.view.ViewCompat; +import androidx.core.view.WindowInsetsCompat; import org.thoughtcrime.securesms.MainActivity; import org.thoughtcrime.securesms.PassphraseRequiredActivity; @@ -19,9 +24,16 @@ public final class PinRestoreActivity extends AppCompatActivity { @Override protected void onCreate(@Nullable Bundle savedInstanceState) { + EdgeToEdge.enable(this); dynamicTheme.onCreate(this); super.onCreate(savedInstanceState); setContentView(R.layout.pin_restore_activity); + + ViewCompat.setOnApplyWindowInsetsListener(findViewById(android.R.id.content), (view, insets) -> { + Insets safeArea = insets.getInsets(WindowInsetsCompat.Type.systemBars() | WindowInsetsCompat.Type.ime()); + view.setPadding(safeArea.left, safeArea.top, safeArea.right, safeArea.bottom); + return insets; + }); } @Override diff --git a/app/src/main/java/org/thoughtcrime/securesms/profiles/username/NewWaysToConnectDialogFragment.kt b/app/src/main/java/org/thoughtcrime/securesms/profiles/username/NewWaysToConnectDialogFragment.kt index 4edd72de89..dd01351e7f 100644 --- a/app/src/main/java/org/thoughtcrime/securesms/profiles/username/NewWaysToConnectDialogFragment.kt +++ b/app/src/main/java/org/thoughtcrime/securesms/profiles/username/NewWaysToConnectDialogFragment.kt @@ -5,6 +5,7 @@ package org.thoughtcrime.securesms.profiles.username +import android.app.Dialog import android.os.Bundle import androidx.compose.foundation.Image import androidx.compose.foundation.layout.Column @@ -32,6 +33,7 @@ import org.signal.core.ui.compose.DayNightPreviews import org.signal.core.ui.compose.Previews import org.signal.core.ui.compose.Scaffolds import org.signal.core.ui.compose.SignalIcons +import org.signal.core.ui.enableEdgeToEdge import org.thoughtcrime.securesms.R import org.thoughtcrime.securesms.profiles.manage.EditProfileActivity import org.signal.core.ui.R as CoreUiR @@ -48,6 +50,12 @@ class NewWaysToConnectDialogFragment : ComposeDialogFragment() { setStyle(STYLE_NO_FRAME, R.style.Signal_DayNight_Dialog_FullScreen) } + override fun onCreateDialog(savedInstanceState: Bundle?): Dialog { + return super.onCreateDialog(savedInstanceState).apply { + window?.enableEdgeToEdge() + } + } + @Composable override fun DialogContent() { NewWaysToConnectDialogContent( diff --git a/app/src/main/java/org/thoughtcrime/securesms/reactions/ReactionsBottomSheetDialogFragment.java b/app/src/main/java/org/thoughtcrime/securesms/reactions/ReactionsBottomSheetDialogFragment.java index d4181d4e9f..5e07a00a76 100644 --- a/app/src/main/java/org/thoughtcrime/securesms/reactions/ReactionsBottomSheetDialogFragment.java +++ b/app/src/main/java/org/thoughtcrime/securesms/reactions/ReactionsBottomSheetDialogFragment.java @@ -1,6 +1,5 @@ package org.thoughtcrime.securesms.reactions; -import android.app.Dialog; import android.content.Context; import android.content.DialogInterface; import android.os.Bundle; @@ -11,7 +10,6 @@ import android.widget.TextView; import androidx.annotation.NonNull; import androidx.annotation.Nullable; -import androidx.core.content.ContextCompat; import androidx.fragment.app.DialogFragment; import androidx.lifecycle.ViewModelProvider; import androidx.viewpager2.widget.ViewPager2; @@ -23,7 +21,6 @@ import com.google.android.material.tabs.TabLayoutMediator; import org.thoughtcrime.securesms.R; import org.thoughtcrime.securesms.components.emoji.EmojiImageView; import org.thoughtcrime.securesms.database.model.MessageId; -import org.thoughtcrime.securesms.util.FullscreenHelper; import org.signal.core.util.concurrent.LifecycleDisposable; import org.thoughtcrime.securesms.util.WindowUtil; @@ -81,16 +78,6 @@ public final class ReactionsBottomSheetDialogFragment extends BottomSheetDialogF super.onCreate(savedInstanceState); } - @Override - public @NonNull Dialog onCreateDialog(@Nullable Bundle savedInstanceState) { - Dialog dialog = super.onCreateDialog(savedInstanceState); - - FullscreenHelper.showSystemUI(dialog.getWindow()); - WindowUtil.setNavigationBarColor(requireContext(), dialog.getWindow(), ContextCompat.getColor(requireContext(), org.signal.core.ui.R.color.signal_colorSurface1)); - - return dialog; - } - @Override public @Nullable View onCreateView(@NonNull LayoutInflater inflater, @Nullable ViewGroup container, diff --git a/app/src/main/java/org/thoughtcrime/securesms/recipients/ui/sharablegrouplink/qr/GroupLinkShareQrDialogFragment.java b/app/src/main/java/org/thoughtcrime/securesms/recipients/ui/sharablegrouplink/qr/GroupLinkShareQrDialogFragment.java index b1d8bfbd62..53a574961b 100644 --- a/app/src/main/java/org/thoughtcrime/securesms/recipients/ui/sharablegrouplink/qr/GroupLinkShareQrDialogFragment.java +++ b/app/src/main/java/org/thoughtcrime/securesms/recipients/ui/sharablegrouplink/qr/GroupLinkShareQrDialogFragment.java @@ -1,5 +1,6 @@ package org.thoughtcrime.securesms.recipients.ui.sharablegrouplink.qr; +import android.app.Dialog; import android.content.Intent; import android.graphics.Bitmap; import android.graphics.Color; @@ -19,6 +20,7 @@ import androidx.fragment.app.FragmentManager; import androidx.lifecycle.ViewModelProvider; import org.signal.core.ui.BottomSheetUtil; +import org.signal.core.ui.WindowExtensionsKt; import org.signal.core.ui.util.ThemeUtil; import org.signal.core.util.logging.Log; import org.thoughtcrime.securesms.R; @@ -26,6 +28,7 @@ import org.thoughtcrime.securesms.components.qr.QrView; import org.thoughtcrime.securesms.dependencies.AppDependencies; import org.thoughtcrime.securesms.groups.GroupId; import org.thoughtcrime.securesms.qr.QrCodeUtil; +import org.thoughtcrime.securesms.util.SystemWindowInsetsSetter; import java.io.ByteArrayOutputStream; import java.io.IOException; @@ -59,6 +62,15 @@ public class GroupLinkShareQrDialogFragment extends DialogFragment { : R.style.TextSecure_LightTheme); } + @Override + public @NonNull Dialog onCreateDialog(@Nullable Bundle savedInstanceState) { + Dialog dialog = super.onCreateDialog(savedInstanceState); + if (dialog.getWindow() != null) { + WindowExtensionsKt.enableEdgeToEdge(dialog.getWindow()); + } + return dialog; + } + @Override public @Nullable View onCreateView(@NonNull LayoutInflater inflater, @Nullable ViewGroup container, @@ -69,6 +81,7 @@ public class GroupLinkShareQrDialogFragment extends DialogFragment { @Override public void onViewCreated(@NonNull View view, @Nullable Bundle savedInstanceState) { + SystemWindowInsetsSetter.attach(view, getViewLifecycleOwner()); initializeViewModel(); initializeViews(view); } diff --git a/app/src/main/java/org/thoughtcrime/securesms/scribbles/ImageEditorStickerSelectActivity.java b/app/src/main/java/org/thoughtcrime/securesms/scribbles/ImageEditorStickerSelectActivity.java index ad34d8192b..3fd167207e 100644 --- a/app/src/main/java/org/thoughtcrime/securesms/scribbles/ImageEditorStickerSelectActivity.java +++ b/app/src/main/java/org/thoughtcrime/securesms/scribbles/ImageEditorStickerSelectActivity.java @@ -5,10 +5,14 @@ import android.content.Intent; import android.os.Bundle; import android.view.MenuItem; +import androidx.activity.EdgeToEdge; import androidx.annotation.NonNull; import androidx.annotation.Nullable; import androidx.appcompat.app.AppCompatActivity; import androidx.appcompat.app.AppCompatDelegate; +import androidx.core.graphics.Insets; +import androidx.core.view.ViewCompat; +import androidx.core.view.WindowInsetsCompat; import org.signal.core.util.concurrent.SignalExecutors; import org.thoughtcrime.securesms.R; @@ -36,8 +40,15 @@ public final class ImageEditorStickerSelectActivity extends AppCompatActivity im @Override protected void onCreate(@Nullable Bundle savedInstanceState) { + EdgeToEdge.enable(this); super.onCreate(savedInstanceState); setContentView(R.layout.scribble_select_new_sticker_activity); + + ViewCompat.setOnApplyWindowInsetsListener(findViewById(android.R.id.content), (view, insets) -> { + Insets safeArea = insets.getInsets(WindowInsetsCompat.Type.systemBars() | WindowInsetsCompat.Type.ime()); + view.setPadding(safeArea.left, safeArea.top, safeArea.right, safeArea.bottom); + return insets; + }); } @Override diff --git a/app/src/main/java/org/thoughtcrime/securesms/stories/settings/create/CreateStoryFlowDialogFragment.kt b/app/src/main/java/org/thoughtcrime/securesms/stories/settings/create/CreateStoryFlowDialogFragment.kt index bc1638e23c..dcd2929945 100644 --- a/app/src/main/java/org/thoughtcrime/securesms/stories/settings/create/CreateStoryFlowDialogFragment.kt +++ b/app/src/main/java/org/thoughtcrime/securesms/stories/settings/create/CreateStoryFlowDialogFragment.kt @@ -1,12 +1,13 @@ package org.thoughtcrime.securesms.stories.settings.create +import android.app.Dialog import android.os.Bundle import androidx.fragment.app.DialogFragment import androidx.fragment.app.setFragmentResult +import org.signal.core.ui.enableEdgeToEdge import org.thoughtcrime.securesms.R import org.thoughtcrime.securesms.recipients.RecipientId import org.thoughtcrime.securesms.stories.settings.select.BaseStoryRecipientSelectionFragment -import org.thoughtcrime.securesms.util.WindowUtil class CreateStoryFlowDialogFragment : DialogFragment(R.layout.create_story_flow_dialog_fragment), BaseStoryRecipientSelectionFragment.Callback, CreateStoryWithViewersFragment.Callback { @@ -15,6 +16,12 @@ class CreateStoryFlowDialogFragment : DialogFragment(R.layout.create_story_flow_ setStyle(STYLE_NO_FRAME, R.style.Signal_DayNight_Dialog_FullScreen) } + override fun onCreateDialog(savedInstanceState: Bundle?): Dialog { + return super.onCreateDialog(savedInstanceState).apply { + window?.enableEdgeToEdge() + } + } + override fun exitFlow() { dismissAllowingStateLoss() } @@ -28,12 +35,4 @@ class CreateStoryFlowDialogFragment : DialogFragment(R.layout.create_story_flow_ ) dismissAllowingStateLoss() } - - override fun setStatusBarColor(color: Int) { - WindowUtil.setStatusBarColor(requireDialog().window!!, color) - } - - override fun getStatusBarColor(): Int { - return WindowUtil.getStatusBarColor(requireDialog().window!!) - } } diff --git a/app/src/main/java/org/thoughtcrime/securesms/stories/settings/create/CreateStoryWithViewersFragment.kt b/app/src/main/java/org/thoughtcrime/securesms/stories/settings/create/CreateStoryWithViewersFragment.kt index ddf3616f19..7106a6a09f 100644 --- a/app/src/main/java/org/thoughtcrime/securesms/stories/settings/create/CreateStoryWithViewersFragment.kt +++ b/app/src/main/java/org/thoughtcrime/securesms/stories/settings/create/CreateStoryWithViewersFragment.kt @@ -2,8 +2,8 @@ package org.thoughtcrime.securesms.stories.settings.create import android.os.Bundle import android.view.View -import androidx.annotation.ColorInt import androidx.appcompat.widget.Toolbar +import androidx.core.view.WindowInsetsCompat import androidx.fragment.app.setFragmentResult import androidx.fragment.app.viewModels import androidx.navigation.fragment.findNavController @@ -16,11 +16,11 @@ import org.thoughtcrime.securesms.components.settings.configure import org.thoughtcrime.securesms.databinding.StoriesCreateWithRecipientsFragmentBinding import org.thoughtcrime.securesms.recipients.RecipientId import org.thoughtcrime.securesms.util.Material3OnScrollHelper +import org.thoughtcrime.securesms.util.SystemWindowInsetsSetter import org.thoughtcrime.securesms.util.ViewUtil import org.thoughtcrime.securesms.util.adapter.mapping.LayoutFactory import org.thoughtcrime.securesms.util.adapter.mapping.MappingAdapter import org.thoughtcrime.securesms.util.fragments.findListener -import org.thoughtcrime.securesms.util.fragments.requireListener import org.thoughtcrime.securesms.util.viewholders.RecipientMappingModel import org.thoughtcrime.securesms.util.viewholders.RecipientViewHolder @@ -80,11 +80,10 @@ class CreateStoryWithViewersFragment : DSLSettingsFragment( Material3OnScrollHelper( activity = requireActivity(), - setStatusBarColor = { requireListener().setStatusBarColor(it) }, - getStatusBarColor = { requireListener().getStatusBarColor() }, views = listOf(binding.toolbar), lifecycleOwner = viewLifecycleOwner ).attach(binding.appBarLayout) + SystemWindowInsetsSetter.attach(binding.create, viewLifecycleOwner, WindowInsetsCompat.Type.navigationBars(), SystemWindowInsetsSetter.ApplyMode.MARGIN) ViewUtil.focusAndShowKeyboard(binding.nameField.editText) } @@ -142,8 +141,6 @@ class CreateStoryWithViewersFragment : DSLSettingsFragment( } interface Callback { - fun setStatusBarColor(@ColorInt color: Int) - fun getStatusBarColor(): Int fun onDone(recipientId: RecipientId) } } diff --git a/app/src/main/java/org/thoughtcrime/securesms/stories/settings/select/BaseStoryRecipientSelectionFragment.kt b/app/src/main/java/org/thoughtcrime/securesms/stories/settings/select/BaseStoryRecipientSelectionFragment.kt index 49163cd2ec..c09006499d 100644 --- a/app/src/main/java/org/thoughtcrime/securesms/stories/settings/select/BaseStoryRecipientSelectionFragment.kt +++ b/app/src/main/java/org/thoughtcrime/securesms/stories/settings/select/BaseStoryRecipientSelectionFragment.kt @@ -2,8 +2,11 @@ package org.thoughtcrime.securesms.stories.settings.select import android.os.Bundle import android.view.View +import android.view.ViewGroup import android.widget.EditText import androidx.appcompat.widget.Toolbar +import androidx.core.view.WindowInsetsCompat +import androidx.core.view.updateLayoutParams import androidx.core.widget.doAfterTextChanged import androidx.fragment.app.Fragment import androidx.fragment.app.viewModels @@ -20,6 +23,7 @@ import org.thoughtcrime.securesms.contacts.selection.ContactSelectionArguments import org.thoughtcrime.securesms.database.model.DistributionListId import org.thoughtcrime.securesms.groups.SelectionLimits import org.thoughtcrime.securesms.recipients.RecipientId +import org.thoughtcrime.securesms.util.SystemWindowInsetsSetter import org.thoughtcrime.securesms.util.fragments.findListener import java.util.Optional import java.util.function.Consumer @@ -54,6 +58,11 @@ abstract class BaseStoryRecipientSelectionFragment : Fragment(R.layout.stories_b toolbar.setTitle(toolbarTitleId) + toolbar.updateLayoutParams { height = ViewGroup.LayoutParams.WRAP_CONTENT } + SystemWindowInsetsSetter.attach(toolbar, viewLifecycleOwner, WindowInsetsCompat.Type.statusBars()) + SystemWindowInsetsSetter.attach(view.findViewById(R.id.contacts_container), viewLifecycleOwner, WindowInsetsCompat.Type.navigationBars()) + SystemWindowInsetsSetter.attach(actionButton, viewLifecycleOwner, WindowInsetsCompat.Type.navigationBars(), SystemWindowInsetsSetter.ApplyMode.MARGIN) + lifecycleDisposable.bindTo(viewLifecycleOwner) actionButton.setText(actionButtonLabel) diff --git a/app/src/main/java/org/thoughtcrime/securesms/stories/viewer/first/StoryFirstTimeNavigationFragment.kt b/app/src/main/java/org/thoughtcrime/securesms/stories/viewer/first/StoryFirstTimeNavigationFragment.kt index 91ce3b7e50..9326b1ded1 100644 --- a/app/src/main/java/org/thoughtcrime/securesms/stories/viewer/first/StoryFirstTimeNavigationFragment.kt +++ b/app/src/main/java/org/thoughtcrime/securesms/stories/viewer/first/StoryFirstTimeNavigationFragment.kt @@ -3,6 +3,7 @@ package org.thoughtcrime.securesms.stories.viewer.first import android.app.Dialog import android.graphics.Color import android.graphics.drawable.ColorDrawable +import android.os.Build import android.os.Bundle import android.view.View import android.view.WindowManager @@ -10,6 +11,7 @@ import androidx.core.app.ActivityCompat import androidx.fragment.app.DialogFragment import androidx.fragment.app.viewModels import io.reactivex.rxjava3.android.schedulers.AndroidSchedulers +import org.signal.core.ui.enableEdgeToEdge import org.signal.core.util.concurrent.LifecycleDisposable import org.thoughtcrime.securesms.R import org.thoughtcrime.securesms.keyvalue.SignalStore @@ -34,13 +36,13 @@ class StoryFirstTimeNavigationFragment : DialogFragment(R.layout.story_viewer_fi override fun onCreateDialog(savedInstanceState: Bundle?): Dialog { val dialog = super.onCreateDialog(savedInstanceState) dialog.window!!.setBackgroundDrawable(ColorDrawable(Color.TRANSPARENT)) + dialog.window!!.enableEdgeToEdge() - dialog.window!!.addFlags( - WindowManager.LayoutParams.FLAG_TRANSLUCENT_NAVIGATION or - WindowManager.LayoutParams.FLAG_TRANSLUCENT_STATUS or - WindowManager.LayoutParams.FLAG_DRAWS_SYSTEM_BAR_BACKGROUNDS or - WindowManager.LayoutParams.FLAG_LAYOUT_NO_LIMITS - ) + if (Build.VERSION.SDK_INT >= 28) { + dialog.window!!.attributes = dialog.window!!.attributes.apply { + layoutInDisplayCutoutMode = WindowManager.LayoutParams.LAYOUT_IN_DISPLAY_CUTOUT_MODE_SHORT_EDGES + } + } return dialog } diff --git a/app/src/main/java/org/thoughtcrime/securesms/stories/viewer/reply/composer/StoryReplyComposer.kt b/app/src/main/java/org/thoughtcrime/securesms/stories/viewer/reply/composer/StoryReplyComposer.kt index 95d42dd336..e5e952b0f5 100644 --- a/app/src/main/java/org/thoughtcrime/securesms/stories/viewer/reply/composer/StoryReplyComposer.kt +++ b/app/src/main/java/org/thoughtcrime/securesms/stories/viewer/reply/composer/StoryReplyComposer.kt @@ -21,6 +21,7 @@ import org.signal.core.util.dp import org.thoughtcrime.securesms.R import org.thoughtcrime.securesms.components.ComposeText import org.thoughtcrime.securesms.components.InputAwareLayout +import org.thoughtcrime.securesms.components.KeyboardAwareLinearLayout import org.thoughtcrime.securesms.components.emoji.Emoji import org.thoughtcrime.securesms.components.emoji.EmojiEventListener import org.thoughtcrime.securesms.components.emoji.EmojiPageModel @@ -170,6 +171,10 @@ class StoryReplyComposer @JvmOverloads constructor( return Input(trimmedText, mentions, bodyRanges) } + fun setInsetPaddingMode(mode: KeyboardAwareLinearLayout.InsetPaddingMode) { + inputAwareLayout.setInsetPaddingMode(mode) + } + fun openEmojiSearch() { emojiDrawer.onOpenEmojiSearch() } diff --git a/app/src/main/java/org/thoughtcrime/securesms/stories/viewer/reply/group/StoryGroupReplyFragment.kt b/app/src/main/java/org/thoughtcrime/securesms/stories/viewer/reply/group/StoryGroupReplyFragment.kt index 54c576a310..4a52b6aa9b 100644 --- a/app/src/main/java/org/thoughtcrime/securesms/stories/viewer/reply/group/StoryGroupReplyFragment.kt +++ b/app/src/main/java/org/thoughtcrime/securesms/stories/viewer/reply/group/StoryGroupReplyFragment.kt @@ -24,6 +24,7 @@ import org.signal.core.util.concurrent.SignalExecutors import org.signal.core.util.getParcelableCompat import org.signal.core.util.logging.Log import org.thoughtcrime.securesms.R +import org.thoughtcrime.securesms.components.KeyboardAwareLinearLayout import org.thoughtcrime.securesms.components.emoji.MediaKeyboard import org.thoughtcrime.securesms.components.mention.MentionAnnotation import org.thoughtcrime.securesms.components.settings.DSLConfiguration @@ -172,6 +173,8 @@ class StoryGroupReplyFragment : composer.callback = this composer.hint = getString(R.string.StoryViewerPageFragment__reply_to_group) + // The hosting bottom sheet already clears the navigation bar; the composer only needs to ride above the keyboard. + composer.setInsetPaddingMode(KeyboardAwareLinearLayout.InsetPaddingMode.KEYBOARD) onPageSelected(findListener()?.selectedChild ?: StoryViewsAndRepliesPagerParent.Child.REPLIES) diff --git a/app/src/main/java/org/thoughtcrime/securesms/util/Material3OnScrollHelper.kt b/app/src/main/java/org/thoughtcrime/securesms/util/Material3OnScrollHelper.kt index d5f08362c8..d83c1c75ec 100644 --- a/app/src/main/java/org/thoughtcrime/securesms/util/Material3OnScrollHelper.kt +++ b/app/src/main/java/org/thoughtcrime/securesms/util/Material3OnScrollHelper.kt @@ -22,8 +22,6 @@ import org.signal.core.ui.R as CoreUiR */ open class Material3OnScrollHelper( private val activity: FragmentActivity, - private val setStatusBarColor: (Int) -> Unit = { WindowUtil.setStatusBarColor(activity.window, it) }, - getStatusBarColor: () -> Int = { WindowUtil.getStatusBarColor(activity.window) }, private val setChatFolderColor: (Int) -> Unit = {}, private val onSetToolbarColor: (Int) -> Unit = {}, private val views: List = emptyList(), @@ -37,23 +35,19 @@ open class Material3OnScrollHelper( */ @JvmStatic fun create(activity: FragmentActivity, toolbar: View): Material3OnScrollHelper { - return Material3OnScrollHelper(activity = activity, views = listOf(toolbar), lifecycleOwner = activity, setStatusBarColor = {}) + return Material3OnScrollHelper(activity = activity, views = listOf(toolbar), lifecycleOwner = activity) } } open val activeColorSet: ColorSet = ColorSet( toolbarColorRes = CoreUiR.color.signal_colorSurface2, - statusBarColorRes = CoreUiR.color.signal_colorSurface2, chatFolderColorRes = CoreUiR.color.signal_colorBackground ) open val inactiveColorSet: ColorSet = ColorSet( toolbarColorRes = CoreUiR.color.signal_colorBackground, - statusBarColorRes = CoreUiR.color.signal_colorBackground, chatFolderColorRes = CoreUiR.color.signal_colorSurface2 ) - protected var previousStatusBarColor: Int = getStatusBarColor() - private var animator: ValueAnimator? = null private var active: Boolean? = null @@ -65,7 +59,6 @@ open class Material3OnScrollHelper( override fun onDestroy(owner: LifecycleOwner) { animator?.cancel() - setStatusBarColor(previousStatusBarColor) } }) } @@ -105,7 +98,6 @@ open class Material3OnScrollHelper( animator?.cancel() val colorSet = if (active == true) activeColorSet else inactiveColorSet setToolbarColor(ContextCompat.getColor(activity, colorSet.toolbarColorRes)) - setStatusBarColor(ContextCompat.getColor(activity, colorSet.statusBarColorRes)) setChatFolderColor(ContextCompat.getColor(activity, colorSet.chatFolderColorRes)) } @@ -129,8 +121,6 @@ open class Material3OnScrollHelper( if (hadActiveState) { val startToolbarColor = ContextCompat.getColor(activity, startColorSet.toolbarColorRes) val endToolbarColor = ContextCompat.getColor(activity, endColorSet.toolbarColorRes) - val startStatusBarColor = ContextCompat.getColor(activity, startColorSet.statusBarColorRes) - val endStatusBarColor = ContextCompat.getColor(activity, endColorSet.statusBarColorRes) val startChatFolderColor = ContextCompat.getColor(activity, startColorSet.chatFolderColorRes) val endChatFolderColor = ContextCompat.getColor(activity, endColorSet.chatFolderColorRes) @@ -138,7 +128,6 @@ open class Material3OnScrollHelper( duration = 200 addUpdateListener { setToolbarColor(ArgbEvaluatorCompat.getInstance().evaluate(it.animatedFraction, startToolbarColor, endToolbarColor)) - setStatusBarColor(ArgbEvaluatorCompat.getInstance().evaluate(it.animatedFraction, startStatusBarColor, endStatusBarColor)) setChatFolderColor(ArgbEvaluatorCompat.getInstance().evaluate(it.animatedFraction, startChatFolderColor, endChatFolderColor)) } start() @@ -174,10 +163,6 @@ open class Material3OnScrollHelper( */ data class ColorSet( @ColorRes val toolbarColorRes: Int, - @ColorRes val statusBarColorRes: Int, - @ColorRes val chatFolderColorRes: Int - ) { - constructor(@ColorRes color: Int) : this(color, color) - constructor(@ColorRes toolbarColorRes: Int, @ColorRes statusBarColorRes: Int) : this(toolbarColorRes, statusBarColorRes, toolbarColorRes) - } + @ColorRes val chatFolderColorRes: Int = toolbarColorRes + ) } diff --git a/app/src/main/java/org/thoughtcrime/securesms/util/WindowUtil.java b/app/src/main/java/org/thoughtcrime/securesms/util/WindowUtil.java index 4bde120bae..32d827ea2f 100644 --- a/app/src/main/java/org/thoughtcrime/securesms/util/WindowUtil.java +++ b/app/src/main/java/org/thoughtcrime/securesms/util/WindowUtil.java @@ -5,7 +5,6 @@ import android.content.Context; import android.os.Build; import android.view.Window; -import androidx.annotation.ColorInt; import androidx.annotation.NonNull; import androidx.core.view.WindowInsetsControllerCompat; @@ -41,18 +40,6 @@ public final class WindowUtil { controller(window).setAppearanceLightNavigationBars(true); } - public static void setNavigationBarColor(@NonNull Activity activity, @ColorInt int color) { - setNavigationBarColor(activity, activity.getWindow(), color); - } - - public static void setNavigationBarColor(@NonNull Context context, @NonNull Window window, @ColorInt int color) { - if (Build.VERSION.SDK_INT < 27) { - window.setNavigationBarColor(ThemeUtil.getThemedColor(context, android.R.attr.navigationBarColor)); - } else { - window.setNavigationBarColor(color); - } - } - public static void setLightStatusBarFromTheme(@NonNull Activity activity) { final boolean isLightStatusBar = ThemeUtil.getThemedBoolean(activity, android.R.attr.windowLightStatusBar); @@ -68,14 +55,6 @@ public final class WindowUtil { controller(window).setAppearanceLightStatusBars(true); } - public static void setStatusBarColor(@NonNull Window window, @ColorInt int color) { - window.setStatusBarColor(color); - } - - public static int getStatusBarColor(@NonNull Window window) { - return window.getStatusBarColor(); - } - private static @NonNull WindowInsetsControllerCompat controller(@NonNull Window window) { return new WindowInsetsControllerCompat(window, window.getDecorView()); } diff --git a/app/src/main/java/org/thoughtcrime/securesms/verify/VerifyScanFragment.kt b/app/src/main/java/org/thoughtcrime/securesms/verify/VerifyScanFragment.kt index 12e57406a8..a553b2ac77 100644 --- a/app/src/main/java/org/thoughtcrime/securesms/verify/VerifyScanFragment.kt +++ b/app/src/main/java/org/thoughtcrime/securesms/verify/VerifyScanFragment.kt @@ -8,7 +8,6 @@ import android.widget.ImageView import android.widget.TextView import androidx.core.view.OneShotPreDrawListener import androidx.core.view.WindowInsetsCompat -import androidx.fragment.app.DialogFragment import androidx.fragment.app.Fragment import io.reactivex.rxjava3.android.schedulers.AndroidSchedulers import org.signal.core.util.concurrent.LifecycleDisposable @@ -39,9 +38,8 @@ class VerifyScanFragment : Fragment() { cameraScrim = view.findViewById(R.id.camera_scrim) cameraMarks = view.findViewById(R.id.camera_marks) - if (!isDialogHosted()) { - SystemWindowInsetsSetter.attach(view.findViewById(R.id.information), viewLifecycleOwner, WindowInsetsCompat.Type.navigationBars(), SystemWindowInsetsSetter.ApplyMode.MARGIN) - } + SystemWindowInsetsSetter.attach(view.findViewById(R.id.information), viewLifecycleOwner, WindowInsetsCompat.Type.navigationBars(), SystemWindowInsetsSetter.ApplyMode.MARGIN) + OneShotPreDrawListener.add(cameraScrim) { val width = cameraScrim.scrimWidth val height = cameraScrim.scrimHeight @@ -60,8 +58,4 @@ class VerifyScanFragment : Fragment() { findListener()?.onQrDataFound(qrData) } } - - private fun isDialogHosted(): Boolean { - return generateSequence(this) { it.parentFragment }.any { it is DialogFragment && it.showsDialog } - } } diff --git a/app/src/main/java/org/thoughtcrime/securesms/wallpaper/crop/WallpaperImageSelectionActivity.java b/app/src/main/java/org/thoughtcrime/securesms/wallpaper/crop/WallpaperImageSelectionActivity.java index 5ca8d88d1f..a3519dfce6 100644 --- a/app/src/main/java/org/thoughtcrime/securesms/wallpaper/crop/WallpaperImageSelectionActivity.java +++ b/app/src/main/java/org/thoughtcrime/securesms/wallpaper/crop/WallpaperImageSelectionActivity.java @@ -3,8 +3,8 @@ package org.thoughtcrime.securesms.wallpaper.crop; import android.content.Context; import android.content.Intent; import android.os.Bundle; -import android.view.WindowManager; +import androidx.activity.EdgeToEdge; import androidx.annotation.NonNull; import androidx.annotation.Nullable; import androidx.appcompat.app.AppCompatActivity; @@ -37,12 +37,9 @@ public final class WallpaperImageSelectionActivity extends AppCompatActivity @Override protected void onCreate(@Nullable Bundle savedInstanceState) { + EdgeToEdge.enable(this); super.onCreate(savedInstanceState); - getWindow().addFlags( - WindowManager.LayoutParams.FLAG_LAYOUT_NO_LIMITS | WindowManager.LayoutParams.FLAG_LAYOUT_IN_SCREEN - ); - setContentView(R.layout.wallpaper_image_selection_activity); getSupportFragmentManager().beginTransaction() diff --git a/app/src/main/res/values-v21/themes.xml b/app/src/main/res/values-v21/themes.xml index 5bcaf06234..094be61d4d 100644 --- a/app/src/main/res/values-v21/themes.xml +++ b/app/src/main/res/values-v21/themes.xml @@ -1,18 +1,7 @@ - - - - @@ -23,41 +12,22 @@ @transition/change_transform - - - - - - - - diff --git a/app/src/main/res/values-v27/colors.xml b/app/src/main/res/values-v27/colors.xml new file mode 100644 index 0000000000..a73624719d --- /dev/null +++ b/app/src/main/res/values-v27/colors.xml @@ -0,0 +1,8 @@ + + + + + @android:color/transparent + + diff --git a/app/src/main/res/values-v27/themes.xml b/app/src/main/res/values-v27/themes.xml index 54043d9037..6259e4fff0 100644 --- a/app/src/main/res/values-v27/themes.xml +++ b/app/src/main/res/values-v27/themes.xml @@ -3,43 +3,31 @@ @@ -47,7 +35,8 @@ false @color/transparent false - @color/signal_colorBackground + @android:color/transparent false + true diff --git a/app/src/main/res/values/colors.xml b/app/src/main/res/values/colors.xml index 02fcc5fed9..725a39d415 100644 --- a/app/src/main/res/values/colors.xml +++ b/app/src/main/res/values/colors.xml @@ -64,4 +64,9 @@ #ff506ECD #3B45FD + + + @color/signal_colorSurface diff --git a/app/src/main/res/values/themes.xml b/app/src/main/res/values/themes.xml index e7fde82b44..094801de5d 100644 --- a/app/src/main/res/values/themes.xml +++ b/app/src/main/res/values/themes.xml @@ -50,20 +50,14 @@ @@ -96,8 +90,6 @@ diff --git a/core/ui/src/main/java/org/signal/core/ui/WindowExtensions.kt b/core/ui/src/main/java/org/signal/core/ui/WindowExtensions.kt index f3910faf10..8360560cfd 100644 --- a/core/ui/src/main/java/org/signal/core/ui/WindowExtensions.kt +++ b/core/ui/src/main/java/org/signal/core/ui/WindowExtensions.kt @@ -5,8 +5,15 @@ package org.signal.core.ui +import android.graphics.Color +import android.os.Build import android.view.Window import android.view.WindowManager +import androidx.core.view.WindowCompat +import org.signal.core.ui.util.ThemeUtil + +private val DARK_NAVIGATION_BAR_SCRIM = Color.argb(0x80, 0x1b, 0x1b, 0x1b) +private val LIGHT_NAVIGATION_BAR_SCRIM = Color.argb(0xe6, 0xff, 0xff, 0xff) /** * Initializes screenshot security on the window based on user preferences. @@ -18,3 +25,22 @@ fun Window.initializeScreenshotSecurity() { clearFlags(WindowManager.LayoutParams.FLAG_SECURE) } } + +/** + * Dialog-window analog of [androidx.activity.enableEdgeToEdge]: lays the window out edge-to-edge with + * transparent (or scrimmed, pre-29) system bars, matching what targetSdk 36 enforces. Dialog windows are + * not covered by the activity-level call in BaseActivity, so every non-floating dialog must opt in itself. + * + * Bar icon appearance (`windowLightStatusBar` / `windowLightNavigationBar`) is left to the window's theme, + * which stays honored under edge-to-edge. + */ +@Suppress("DEPRECATION") +fun Window.enableEdgeToEdge() { + WindowCompat.setDecorFitsSystemWindows(this, false) + statusBarColor = Color.TRANSPARENT + navigationBarColor = when { + Build.VERSION.SDK_INT >= 29 -> Color.TRANSPARENT + Build.VERSION.SDK_INT >= 27 && ThemeUtil.getThemedBoolean(context, android.R.attr.windowLightNavigationBar) -> LIGHT_NAVIGATION_BAR_SCRIM + else -> DARK_NAVIGATION_BAR_SCRIM + } +} diff --git a/core/ui/src/main/java/org/signal/core/ui/compose/ComposeBottomSheetDialogFragment.kt b/core/ui/src/main/java/org/signal/core/ui/compose/ComposeBottomSheetDialogFragment.kt index d4bd286bca..d29841aee7 100644 --- a/core/ui/src/main/java/org/signal/core/ui/compose/ComposeBottomSheetDialogFragment.kt +++ b/core/ui/src/main/java/org/signal/core/ui/compose/ComposeBottomSheetDialogFragment.kt @@ -10,7 +10,11 @@ import android.os.Bundle import android.view.LayoutInflater import android.view.View import android.view.ViewGroup -import androidx.compose.foundation.layout.navigationBarsPadding +import androidx.compose.foundation.layout.WindowInsets +import androidx.compose.foundation.layout.exclude +import androidx.compose.foundation.layout.ime +import androidx.compose.foundation.layout.navigationBars +import androidx.compose.foundation.layout.windowInsetsPadding import androidx.compose.foundation.shape.RoundedCornerShape import androidx.compose.material3.MaterialTheme import androidx.compose.material3.Surface @@ -45,8 +49,12 @@ abstract class ComposeBottomSheetDialogFragment : FixedRoundedCornerBottomSheetD } CompositionLocalProvider(LocalFragmentManager provides childFragmentManager) { SignalTheme(isDarkMode = isDark) { + // No navigation bar padding here: BottomSheetBehavior already bottom-pads the sheet + // for the navigation bar (paddingBottomSystemWindowInsets) once the window is + // edge-to-edge, so padding again would double up. The keyboard inset excludes the + // navigation bar for the same reason. Surface( - modifier = Modifier.navigationBarsPadding(), + modifier = Modifier.windowInsetsPadding(WindowInsets.ime.exclude(WindowInsets.navigationBars)), shape = RoundedCornerShape(cornerRadius.dp, cornerRadius.dp), color = SignalTheme.colors.colorSurface1, contentColor = MaterialTheme.colorScheme.onSurface diff --git a/core/ui/src/main/java/org/signal/core/ui/compose/ComposeFullScreenDialogFragment.kt b/core/ui/src/main/java/org/signal/core/ui/compose/ComposeFullScreenDialogFragment.kt index d1c663e1eb..badf3228b8 100644 --- a/core/ui/src/main/java/org/signal/core/ui/compose/ComposeFullScreenDialogFragment.kt +++ b/core/ui/src/main/java/org/signal/core/ui/compose/ComposeFullScreenDialogFragment.kt @@ -5,6 +5,7 @@ package org.signal.core.ui.compose +import android.app.Dialog import android.os.Bundle import android.view.LayoutInflater import android.view.View @@ -20,6 +21,7 @@ import androidx.compose.ui.platform.ViewCompositionStrategy import androidx.fragment.app.DialogFragment import org.signal.core.ui.R import org.signal.core.ui.compose.theme.SignalTheme +import org.signal.core.ui.enableEdgeToEdge import org.signal.core.ui.initializeScreenshotSecurity import org.signal.core.ui.util.ThemeUtil @@ -37,6 +39,12 @@ abstract class ComposeFullScreenDialogFragment : DialogFragment() { setStyle(STYLE_NO_FRAME, fullScreenDialogStyle) } + override fun onCreateDialog(savedInstanceState: Bundle?): Dialog { + return super.onCreateDialog(savedInstanceState).apply { + window?.enableEdgeToEdge() + } + } + override fun onCreateView(inflater: LayoutInflater, container: ViewGroup?, savedInstanceState: Bundle?): View? { return ComposeView(requireContext()).apply { setViewCompositionStrategy(ViewCompositionStrategy.DisposeOnViewTreeLifecycleDestroyed) diff --git a/core/ui/src/main/res/values-v27/colors.xml b/core/ui/src/main/res/values-v27/colors.xml new file mode 100644 index 0000000000..b6b74469a3 --- /dev/null +++ b/core/ui/src/main/res/values-v27/colors.xml @@ -0,0 +1,8 @@ + + + + + @android:color/transparent + + diff --git a/core/ui/src/main/res/values/colors.xml b/core/ui/src/main/res/values/colors.xml new file mode 100644 index 0000000000..91586d27c4 --- /dev/null +++ b/core/ui/src/main/res/values/colors.xml @@ -0,0 +1,9 @@ + + + + + @color/signal_colorSurface1 + + diff --git a/core/ui/src/main/res/values/themes.xml b/core/ui/src/main/res/values/themes.xml index 425a1078ff..d65f18ecd4 100644 --- a/core/ui/src/main/res/values/themes.xml +++ b/core/ui/src/main/res/values/themes.xml @@ -7,7 +7,7 @@ @style/Widget.CoreUi.FixedRoundedCorners.BottomSheet @anim/slide_from_bottom @anim/slide_to_bottom - @color/signal_colorSurface1 + @color/signal_bottom_sheet_navigation_bar