From c28ecbca4ce8f80f50ded4b3fa9a7859dab902a2 Mon Sep 17 00:00:00 2001 From: Greyson Parrelli Date: Tue, 4 Aug 2026 07:42:40 -0400 Subject: [PATCH] Update some activities to handle rotation. --- .../stories/viewer/StoryViewerActivity.kt | 53 +++++++++++++------ .../wallpaper/crop/WallpaperCropActivity.java | 19 +++++-- 2 files changed, 51 insertions(+), 21 deletions(-) diff --git a/app/src/main/java/org/thoughtcrime/securesms/stories/viewer/StoryViewerActivity.kt b/app/src/main/java/org/thoughtcrime/securesms/stories/viewer/StoryViewerActivity.kt index ba36814aec..ed76d94e02 100644 --- a/app/src/main/java/org/thoughtcrime/securesms/stories/viewer/StoryViewerActivity.kt +++ b/app/src/main/java/org/thoughtcrime/securesms/stories/viewer/StoryViewerActivity.kt @@ -4,16 +4,20 @@ import android.content.BroadcastReceiver import android.content.Context import android.content.Intent import android.content.IntentFilter +import android.content.pm.ActivityInfo import android.media.AudioManager import android.os.Bundle import android.view.KeyEvent import android.view.View import androidx.activity.viewModels import androidx.appcompat.app.AppCompatDelegate +import androidx.core.view.ViewCompat import androidx.media.AudioManagerCompat import androidx.window.layout.WindowMetricsCalculator import com.bumptech.glide.Glide import com.bumptech.glide.MemoryCategory +import org.signal.core.ui.WindowBreakpoint +import org.signal.core.ui.getWindowBreakpoint import org.signal.core.util.ServiceUtil import org.signal.core.util.dp import org.signal.core.util.getParcelableCompat @@ -45,6 +49,10 @@ class StoryViewerActivity : PassphraseRequiredActivity(), VoiceNoteMediaControll } override fun onCreate(savedInstanceState: Bundle?, ready: Boolean) { + if (resources.getWindowBreakpoint() !is WindowBreakpoint.Small) { + requestedOrientation = ActivityInfo.SCREEN_ORIENTATION_UNSPECIFIED + } + if (savedInstanceState != null) { val cache: StoryViewStateCache? = savedInstanceState.getParcelableCompat(DATA_CACHE, StoryViewStateCache::class.java) if (cache != null) { @@ -58,24 +66,12 @@ class StoryViewerActivity : PassphraseRequiredActivity(), VoiceNoteMediaControll supportPostponeEnterTransition() val root = findViewById(android.R.id.content) - val metrics = WindowMetricsCalculator.getOrCreate().computeCurrentWindowMetrics(this) - val statusBarHeight = ViewUtil.getStatusBarHeight(root) - val contentHeight = metrics.bounds.width() * (16 / 9f) + 48.sp - val spaceAndNavbar = metrics.bounds.height() - statusBarHeight - contentHeight - val (padTop, padBottom) = if (spaceAndNavbar > 72.dp) { - val pad = (metrics.bounds.height() - contentHeight) / 2f - pad to pad - } else { - statusBarHeight to ViewUtil.getNavigationBarHeight(root) + updateContentPadding(root) + ViewCompat.setOnApplyWindowInsetsListener(root) { view, insets -> + updateContentPadding(view) + insets } - root.setPadding( - 0, - padTop.toInt(), - 0, - padBottom.toInt() - ) - super.onCreate(savedInstanceState, ready) setContentView(R.layout.fragment_container) @@ -121,6 +117,31 @@ class StoryViewerActivity : PassphraseRequiredActivity(), VoiceNoteMediaControll window.transitionBackgroundFadeDuration = 100 } + /** + * Centers the 16:9 story content when the window is tall enough for it, and otherwise insets it by the system bars. + * Recomputed on every inset dispatch rather than just at creation, because this activity handles its own + * configuration changes and is free to rotate on large screens. + */ + private fun updateContentPadding(root: View) { + val metrics = WindowMetricsCalculator.getOrCreate().computeCurrentWindowMetrics(this) + val statusBarHeight = ViewUtil.getStatusBarHeight(root) + val contentHeight = metrics.bounds.width() * (16 / 9f) + 48.sp + val spaceAndNavbar = metrics.bounds.height() - statusBarHeight - contentHeight + val (padTop, padBottom) = if (spaceAndNavbar > 72.dp) { + val pad = (metrics.bounds.height() - contentHeight) / 2f + pad to pad + } else { + statusBarHeight.toFloat() to ViewUtil.getNavigationBarHeight(root).toFloat() + } + + root.setPadding( + 0, + padTop.toInt(), + 0, + padBottom.toInt() + ) + } + private fun replaceStoryViewerFragment() { supportFragmentManager.beginTransaction() .replace( diff --git a/app/src/main/java/org/thoughtcrime/securesms/wallpaper/crop/WallpaperCropActivity.java b/app/src/main/java/org/thoughtcrime/securesms/wallpaper/crop/WallpaperCropActivity.java index 4446c4e53a..dd98dcef66 100644 --- a/app/src/main/java/org/thoughtcrime/securesms/wallpaper/crop/WallpaperCropActivity.java +++ b/app/src/main/java/org/thoughtcrime/securesms/wallpaper/crop/WallpaperCropActivity.java @@ -2,10 +2,11 @@ package org.thoughtcrime.securesms.wallpaper.crop; import android.content.Context; import android.content.Intent; +import android.content.pm.ActivityInfo; import android.graphics.Point; +import android.graphics.Rect; import android.net.Uri; import android.os.Bundle; -import android.util.DisplayMetrics; import android.view.MenuItem; import android.view.View; import android.widget.TextView; @@ -20,7 +21,9 @@ import androidx.appcompat.widget.SwitchCompat; import androidx.appcompat.widget.Toolbar; import androidx.core.content.ContextCompat; import androidx.lifecycle.ViewModelProvider; +import androidx.window.layout.WindowMetricsCalculator; +import org.signal.core.ui.WindowBreakpoint; import org.signal.core.util.logging.Log; import org.signal.imageeditor.core.ImageEditorView; import org.signal.imageeditor.core.model.EditorElement; @@ -43,6 +46,8 @@ import java.util.Collections; import java.util.Locale; import java.util.Objects; +import static org.signal.core.ui.WindowSizeClassExtensionsKt.getWindowBreakpoint; + public final class WallpaperCropActivity extends BaseActivity { private static final String TAG = Log.tag(WallpaperCropActivity.class); @@ -75,6 +80,11 @@ public final class WallpaperCropActivity extends BaseActivity { @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); + + if (!(getWindowBreakpoint(getResources()) instanceof WindowBreakpoint.Small)) { + setRequestedOrientation(ActivityInfo.SCREEN_ORIENTATION_UNSPECIFIED); + } + dynamicTheme.onCreate(this); setContentView(R.layout.chat_wallpaper_crop_activity); @@ -182,10 +192,9 @@ public final class WallpaperCropActivity extends BaseActivity { } private void setupImageEditor(@NonNull Uri imageUri) { - DisplayMetrics displayMetrics = new DisplayMetrics(); - getWindowManager().getDefaultDisplay().getMetrics(displayMetrics); - int height = displayMetrics.heightPixels; - int width = displayMetrics.widthPixels; + Rect bounds = WindowMetricsCalculator.getOrCreate().computeCurrentWindowMetrics(this).getBounds(); + int height = bounds.height(); + int width = bounds.width(); float ratio = width / (float) height; EditorModel editorModel = EditorModel.createForWallpaperEditing(ratio, ContextCompat.getColor(this, org.signal.core.ui.R.color.signal_colorBackground));