mirror of
https://github.com/simplex-chat/simplex-chat.git
synced 2026-09-16 14:53:07 +00:00
gallery in landscape with cutout
This commit is contained in:
@@ -12,6 +12,10 @@ import androidx.compose.runtime.saveable.rememberSaveable
|
||||
import androidx.compose.ui.Alignment
|
||||
import androidx.compose.ui.Modifier
|
||||
import androidx.compose.ui.draw.clipToBounds
|
||||
import androidx.compose.ui.draw.drawBehind
|
||||
import androidx.compose.ui.geometry.Offset
|
||||
import androidx.compose.ui.geometry.Size
|
||||
import androidx.compose.ui.graphics.Color
|
||||
import androidx.compose.ui.graphics.graphicsLayer
|
||||
import androidx.compose.ui.platform.LocalDensity
|
||||
import androidx.compose.ui.platform.LocalLayoutDirection
|
||||
@@ -49,17 +53,37 @@ fun AppScreen() {
|
||||
// (because nav bar and holes located on vertical sides of screen in landscape view)
|
||||
val direction = LocalLayoutDirection.current
|
||||
val safePadding = WindowInsets.safeDrawing.asPaddingValues()
|
||||
val paddingStart = safePadding.calculateStartPadding(direction)
|
||||
val paddingEnd = safePadding.calculateEndPadding(direction)
|
||||
val cutout = WindowInsets.displayCutout.asPaddingValues()
|
||||
val cutoutStart = cutout.calculateStartPadding(direction)
|
||||
val cutoutEnd = cutout.calculateEndPadding(direction)
|
||||
val cutoutMax = maxOf(cutoutStart, cutoutEnd)
|
||||
val paddingStartUntouched = safePadding.calculateStartPadding(direction)
|
||||
val paddingStart = paddingStartUntouched - cutoutStart
|
||||
val paddingEndUntouched = safePadding.calculateEndPadding(direction)
|
||||
val paddingEnd = paddingEndUntouched - cutoutEnd
|
||||
// Such a strange layout is needed because the main content should be covered by solid color in order to hide overflow
|
||||
// of some elements that may have negative offset (so, can't use Row {}).
|
||||
// To check: go to developer settings of Android, choose Display cutout -> Punch hole, and rotate the phone to landscape, open any chat
|
||||
Box {
|
||||
Box(Modifier.padding(start = paddingStart, end = paddingEnd).consumeWindowInsets(PaddingValues(start = paddingStart, end = paddingEnd))) {
|
||||
MainScreen()
|
||||
val fullscreenGallery = remember { chatModel.fullscreenGalleryVisible }
|
||||
Box(Modifier.padding(start = paddingStart + cutoutMax, end = paddingEnd + cutoutMax).consumeWindowInsets(PaddingValues(start = paddingStartUntouched, end = paddingEndUntouched))) {
|
||||
Box(Modifier.drawBehind {
|
||||
if (fullscreenGallery.value) {
|
||||
drawRect(Color.Black, topLeft = Offset(-(paddingStart + cutoutMax).toPx(), 0f), Size(size.width + (paddingStart + cutoutMax).toPx() + (paddingEnd + cutoutMax).toPx(), size.height))
|
||||
}
|
||||
}) {
|
||||
MainScreen()
|
||||
}
|
||||
}
|
||||
Box(Modifier.width(paddingStart).fillMaxHeight().background(MaterialTheme.colors.background))
|
||||
Box(Modifier.align(Alignment.CenterEnd).width(paddingEnd).fillMaxHeight().background(MaterialTheme.colors.background))
|
||||
Box(Modifier.width(paddingStart + cutoutMax)
|
||||
.fillMaxHeight()
|
||||
.graphicsLayer { alpha = if (fullscreenGallery.value) 0f else 1f }
|
||||
.background(MaterialTheme.colors.background))
|
||||
Box(Modifier.align(Alignment.CenterEnd)
|
||||
.width(paddingEnd + cutoutMax)
|
||||
.fillMaxHeight()
|
||||
.graphicsLayer { alpha = if (fullscreenGallery.value) 0f else 1f }
|
||||
.background(MaterialTheme.colors.background))
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -90,6 +90,9 @@ object ChatModel {
|
||||
// Needed to check for bottom nav bar and to apply or not navigation bar color on Android
|
||||
val newChatSheetVisible = mutableStateOf(false)
|
||||
|
||||
// Needed to apply black color to left/right cutout area on Android
|
||||
val fullscreenGalleryVisible = mutableStateOf(false)
|
||||
|
||||
// preferences
|
||||
val notificationPreviewMode by lazy {
|
||||
mutableStateOf(
|
||||
|
||||
+5
-1
@@ -56,10 +56,14 @@ fun ImageFullScreenView(imageProvider: () -> ImageGalleryProvider, close: () ->
|
||||
val scope = rememberCoroutineScope()
|
||||
val playersToRelease = rememberSaveable { mutableSetOf<URI>() }
|
||||
DisposableEffectOnGone(
|
||||
always = { platform.androidSetStatusAndNavigationBarAppearance(false, false) },
|
||||
always = {
|
||||
platform.androidSetStatusAndNavigationBarAppearance(false, false)
|
||||
chatModel.fullscreenGalleryVisible.value = true
|
||||
},
|
||||
whenDispose = {
|
||||
val c = CurrentColors.value.colors
|
||||
platform.androidSetStatusAndNavigationBarAppearance(c.isLight, c.isLight)
|
||||
chatModel.fullscreenGalleryVisible.value = false
|
||||
},
|
||||
whenGone = {
|
||||
playersToRelease.forEach { VideoPlayerHolder.release(it, true, true) }
|
||||
|
||||
+1
-1
@@ -70,7 +70,7 @@ fun AppearanceScope.AppearanceLayout(
|
||||
SectionDividerSpaced()
|
||||
BarsAlphaSection(MR.strings.appearance_in_app_bars_alpha, appPrefs.inAppBarsAlpha, 0.9f)
|
||||
|
||||
SectionDividerSpaced()
|
||||
SectionDividerSpaced(maxTopPadding = true)
|
||||
ProfileImageSection()
|
||||
|
||||
SectionDividerSpaced(maxTopPadding = true)
|
||||
|
||||
Reference in New Issue
Block a user