mirror of
https://github.com/simplex-chat/simplex-chat.git
synced 2026-09-05 03:56:00 +00:00
multiplatform: insets
This commit is contained in:
@@ -5,7 +5,11 @@ import android.content.Intent
|
||||
import android.net.Uri
|
||||
import android.os.*
|
||||
import android.view.WindowManager
|
||||
import androidx.activity.SystemBarStyle
|
||||
import androidx.activity.compose.setContent
|
||||
import androidx.activity.enableEdgeToEdge
|
||||
import androidx.compose.ui.graphics.Color
|
||||
import androidx.compose.ui.graphics.toArgb
|
||||
import androidx.compose.ui.platform.ClipboardManager
|
||||
import androidx.fragment.app.FragmentActivity
|
||||
import chat.simplex.app.model.NtfManager
|
||||
@@ -47,6 +51,7 @@ class MainActivity: FragmentActivity() {
|
||||
WindowManager.LayoutParams.FLAG_SECURE
|
||||
)
|
||||
}
|
||||
enableEdgeToEdge()
|
||||
setContent {
|
||||
AppScreen()
|
||||
}
|
||||
|
||||
@@ -314,37 +314,38 @@ class SimplexApp: Application(), LifecycleEventObserver {
|
||||
@Suppress("DEPRECATION")
|
||||
val windowInsetController = ViewCompat.getWindowInsetsController(window.decorView)
|
||||
|
||||
var statusBar = (if (hasTop && appPrefs.onboardingStage.get() == OnboardingStage.OnboardingComplete) {
|
||||
backgroundColor.mixWith(CurrentColors.value.colors.onBackground, 0.97f)
|
||||
} else {
|
||||
if (CurrentColors.value.base == DefaultTheme.SIMPLEX) {
|
||||
backgroundColor.lighter(0.4f)
|
||||
} else {
|
||||
backgroundColor
|
||||
}
|
||||
}).toArgb()
|
||||
// var statusBar = (if (hasTop && appPrefs.onboardingStage.get() == OnboardingStage.OnboardingComplete) {
|
||||
// backgroundColor.mixWith(CurrentColors.value.colors.onBackground, 0.97f)
|
||||
// } else {
|
||||
// if (CurrentColors.value.base == DefaultTheme.SIMPLEX) {
|
||||
// backgroundColor.lighter(0.4f)
|
||||
// } else {
|
||||
// backgroundColor
|
||||
// }
|
||||
// }).toArgb()
|
||||
var statusBarLight = isLight
|
||||
|
||||
// SimplexGreen while in call
|
||||
//
|
||||
// // SimplexGreen while in call
|
||||
if (window.statusBarColor == SimplexGreen.toArgb()) {
|
||||
statusBarColorAfterCall.intValue = statusBar
|
||||
statusBar = SimplexGreen.toArgb()
|
||||
// statusBarColorAfterCall.intValue = statusBar
|
||||
// statusBar = SimplexGreen.toArgb()
|
||||
statusBarLight = false
|
||||
}
|
||||
val navBar = (if (hasBottom && appPrefs.onboardingStage.get() == OnboardingStage.OnboardingComplete) {
|
||||
backgroundColor.mixWith(CurrentColors.value.colors.onBackground, 0.97f)
|
||||
} else {
|
||||
backgroundColor
|
||||
}).toArgb()
|
||||
if (window.statusBarColor != statusBar) {
|
||||
window.statusBarColor = statusBar
|
||||
}
|
||||
// val navBar = (if (hasBottom && appPrefs.onboardingStage.get() == OnboardingStage.OnboardingComplete) {
|
||||
// backgroundColor.mixWith(CurrentColors.value.colors.onBackground, 0.97f)
|
||||
// } else {
|
||||
// backgroundColor
|
||||
// }).toArgb()
|
||||
// if (window.statusBarColor != statusBar) {
|
||||
// window.statusBarColor = statusBar
|
||||
// }
|
||||
if (windowInsetController?.isAppearanceLightStatusBars != statusBarLight) {
|
||||
windowInsetController?.isAppearanceLightStatusBars = statusBarLight
|
||||
}
|
||||
if (window.navigationBarColor != navBar) {
|
||||
window.navigationBarColor = navBar
|
||||
}
|
||||
// if (window.navigationBarColor != navBar) {
|
||||
// window.navigationBarColor = navBar
|
||||
// }
|
||||
window.navigationBarColor = Color.Transparent.toArgb()
|
||||
if (windowInsetController?.isAppearanceLightNavigationBars != isLight) {
|
||||
windowInsetController?.isAppearanceLightNavigationBars = isLight
|
||||
}
|
||||
|
||||
+20
-4
@@ -41,9 +41,19 @@ actual fun LazyColumnWithScrollBar(
|
||||
}
|
||||
}
|
||||
if (connection != null) {
|
||||
LazyColumn(modifier.nestedScroll(connection), state, contentPadding, reverseLayout, verticalArrangement, horizontalAlignment, flingBehavior, userScrollEnabled, content)
|
||||
LazyColumn(modifier.nestedScroll(connection), state, contentPadding, reverseLayout, verticalArrangement, horizontalAlignment, flingBehavior, userScrollEnabled) {
|
||||
content()
|
||||
item {
|
||||
Spacer(Modifier.windowInsetsBottomHeight(WindowInsets.systemBars))
|
||||
}
|
||||
}
|
||||
} else {
|
||||
LazyColumn(modifier, state, contentPadding, reverseLayout, verticalArrangement, horizontalAlignment, flingBehavior, userScrollEnabled, content)
|
||||
LazyColumn(modifier, state, contentPadding, reverseLayout, verticalArrangement, horizontalAlignment, flingBehavior, userScrollEnabled) {
|
||||
content()
|
||||
item {
|
||||
Spacer(Modifier.windowInsetsBottomHeight(WindowInsets.systemBars))
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -74,12 +84,18 @@ actual fun ColumnWithScrollBar(
|
||||
modifier.nestedScroll(connection).verticalScroll(state).height(IntrinsicSize.Max)
|
||||
} else {
|
||||
modifier.nestedScroll(connection).verticalScroll(state)
|
||||
}, verticalArrangement, horizontalAlignment, content)
|
||||
}, verticalArrangement, horizontalAlignment) {
|
||||
content()
|
||||
Spacer(Modifier.windowInsetsBottomHeight(WindowInsets.systemBars))
|
||||
}
|
||||
} else {
|
||||
Column(if (maxIntrinsicSize) {
|
||||
modifier.verticalScroll(state).height(IntrinsicSize.Max)
|
||||
} else {
|
||||
modifier.verticalScroll(state)
|
||||
}, verticalArrangement, horizontalAlignment, content)
|
||||
}, verticalArrangement, horizontalAlignment) {
|
||||
content()
|
||||
Spacer(Modifier.windowInsetsBottomHeight(WindowInsets.systemBars))
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -44,10 +44,8 @@ import kotlinx.coroutines.flow.*
|
||||
fun AppScreen() {
|
||||
AppBarHandler.appBarMaxHeightPx = with(LocalDensity.current) { AppBarHeight.roundToPx() }
|
||||
SimpleXTheme {
|
||||
ProvideWindowInsets(windowInsetsAnimationsEnabled = true) {
|
||||
Surface(color = MaterialTheme.colors.background, contentColor = LocalContentColor.current) {
|
||||
MainScreen()
|
||||
}
|
||||
Surface(color = MaterialTheme.colors.background, contentColor = LocalContentColor.current) {
|
||||
MainScreen()
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
+2
-5
@@ -656,10 +656,8 @@ fun ChatLayout(
|
||||
},
|
||||
)
|
||||
) {
|
||||
ProvideWindowInsets(windowInsetsAnimationsEnabled = true) {
|
||||
ModalBottomSheetLayout(
|
||||
scrimColor = Color.Black.copy(alpha = 0.12F),
|
||||
modifier = Modifier.navigationBarsWithImePadding(),
|
||||
sheetElevation = 0.dp,
|
||||
sheetContent = {
|
||||
ChooseAttachmentView(
|
||||
@@ -687,7 +685,6 @@ fun ChatLayout(
|
||||
}
|
||||
},
|
||||
bottomBar = composeView,
|
||||
modifier = Modifier.navigationBarsWithImePadding(),
|
||||
floatingActionButton = { floatingButton.value() },
|
||||
contentColor = LocalContentColor.current,
|
||||
backgroundColor = Color.Unspecified
|
||||
@@ -719,7 +716,6 @@ fun ChatLayout(
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -882,11 +878,12 @@ fun ChatInfoToolbar(
|
||||
title = { ChatInfoToolbarTitle(chatInfo) },
|
||||
onTitleClick = if (chatInfo is ChatInfo.Local) null else info,
|
||||
showSearch = showSearch.value,
|
||||
onTop = true,
|
||||
onSearchValueChanged = onSearchValueChanged,
|
||||
buttons = barButtons
|
||||
)
|
||||
|
||||
Divider(Modifier.padding(top = AppBarHeight * fontSizeSqrtMultiplier))
|
||||
Divider(Modifier.statusBarsPadding().padding(top = AppBarHeight * fontSizeSqrtMultiplier))
|
||||
|
||||
Box(Modifier.fillMaxWidth().wrapContentSize(Alignment.TopEnd).offset(y = AppBarHeight * fontSizeSqrtMultiplier)) {
|
||||
DefaultDropdownMenu(showMenu) {
|
||||
|
||||
+1
@@ -1044,6 +1044,7 @@ fun ComposeView(
|
||||
textStyle = textStyle
|
||||
)
|
||||
}
|
||||
Spacer(Modifier.imePadding().navigationBarsPadding())
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
+1
@@ -40,6 +40,7 @@ fun SelectedItemsTopToolbar(selectedChatItems: MutableState<Set<Long>?>) {
|
||||
},
|
||||
onTitleClick = null,
|
||||
showSearch = false,
|
||||
onTop = true,
|
||||
onSearchValueChanged = {},
|
||||
)
|
||||
Divider(Modifier.padding(top = AppBarHeight * fontSizeSqrtMultiplier))
|
||||
|
||||
+3
-1
@@ -169,7 +169,7 @@ fun ChatListView(chatModel: ChatModel, userPickerState: MutableStateFlow<Animate
|
||||
},
|
||||
bottomBar = {
|
||||
if (oneHandUI.value) {
|
||||
Column {
|
||||
Column(Modifier.imePadding()) {
|
||||
Divider()
|
||||
ChatListToolbar(
|
||||
userPickerState,
|
||||
@@ -189,6 +189,7 @@ fun ChatListView(chatModel: ChatModel, userPickerState: MutableStateFlow<Animate
|
||||
}
|
||||
},
|
||||
Modifier
|
||||
.navigationBarsPadding()
|
||||
.padding(end = DEFAULT_PADDING - 16.dp, bottom = DEFAULT_PADDING - 16.dp)
|
||||
.size(AppBarHeight * fontSizeSqrtMultiplier),
|
||||
elevation = FloatingActionButtonDefaults.elevation(
|
||||
@@ -372,6 +373,7 @@ private fun ChatListToolbar(userPickerState: MutableStateFlow<AnimatedViewState>
|
||||
},
|
||||
onTitleClick = null,
|
||||
showSearch = false,
|
||||
onTop = !oneHandUI.value,
|
||||
onSearchValueChanged = {},
|
||||
buttons = barButtons
|
||||
)
|
||||
|
||||
+1
@@ -191,6 +191,7 @@ private fun ShareListToolbar(chatModel: ChatModel, stopped: Boolean, onSearchVal
|
||||
},
|
||||
onTitleClick = null,
|
||||
showSearch = showSearch,
|
||||
onTop = !remember { appPrefs.oneHandUI.state }.value,
|
||||
onSearchValueChanged = onSearchValueChanged,
|
||||
buttons = barButtons
|
||||
)
|
||||
|
||||
+2
@@ -19,6 +19,8 @@ fun ChooseAttachmentView(attachmentOption: MutableState<AttachmentOption?>, hide
|
||||
Box(
|
||||
modifier = Modifier
|
||||
.fillMaxWidth()
|
||||
.navigationBarsPadding()
|
||||
.imePadding()
|
||||
.wrapContentHeight()
|
||||
.onFocusChanged { focusState ->
|
||||
if (!focusState.hasFocus) hide()
|
||||
|
||||
+11
-5
@@ -23,12 +23,18 @@ import kotlin.math.absoluteValue
|
||||
|
||||
@Composable
|
||||
fun CloseSheetBar(close: (() -> Unit)?, showClose: Boolean = true, tintColor: Color = if (close != null) MaterialTheme.colors.primary else MaterialTheme.colors.secondary, arrangement: Arrangement.Vertical = Arrangement.Top, closeBarTitle: String? = null, barPaddingValues: PaddingValues = PaddingValues(horizontal = AppBarHorizontalPadding), endButtons: @Composable RowScope.() -> Unit = {}) {
|
||||
var rowModifier = Modifier
|
||||
.fillMaxWidth()
|
||||
.height(AppBarHeight * fontSizeSqrtMultiplier)
|
||||
val themeBackgroundMix = MaterialTheme.colors.background.mixWith(MaterialTheme.colors.onBackground, 0.97f)
|
||||
if (!closeBarTitle.isNullOrEmpty()) {
|
||||
rowModifier = rowModifier.background(themeBackgroundMix)
|
||||
val rowModifier = if (closeBarTitle.isNullOrEmpty()) {
|
||||
Modifier
|
||||
.fillMaxWidth()
|
||||
.then(if (arrangement == Arrangement.Top) Modifier.statusBarsPadding() else Modifier.navigationBarsPadding())
|
||||
.height(AppBarHeight * fontSizeSqrtMultiplier)
|
||||
} else {
|
||||
Modifier
|
||||
.fillMaxWidth()
|
||||
.background(themeBackgroundMix)
|
||||
.then(if (arrangement == Arrangement.Top) Modifier.statusBarsPadding() else Modifier.navigationBarsPadding())
|
||||
.height(AppBarHeight * fontSizeSqrtMultiplier)
|
||||
}
|
||||
val handler = LocalAppBarHandler.current
|
||||
val connection = LocalAppBarHandler.current?.connection
|
||||
|
||||
+7
-1
@@ -4,6 +4,7 @@ import androidx.compose.foundation.*
|
||||
import androidx.compose.foundation.layout.*
|
||||
import androidx.compose.material.*
|
||||
import androidx.compose.runtime.Composable
|
||||
import androidx.compose.runtime.remember
|
||||
import androidx.compose.ui.Alignment
|
||||
import androidx.compose.ui.Modifier
|
||||
import androidx.compose.ui.graphics.*
|
||||
@@ -11,6 +12,7 @@ import androidx.compose.ui.unit.Dp
|
||||
import dev.icerock.moko.resources.compose.painterResource
|
||||
import dev.icerock.moko.resources.compose.stringResource
|
||||
import androidx.compose.ui.unit.dp
|
||||
import chat.simplex.common.model.ChatController.appPrefs
|
||||
import chat.simplex.common.ui.theme.*
|
||||
import chat.simplex.res.MR
|
||||
|
||||
@@ -20,6 +22,7 @@ fun DefaultTopAppBar(
|
||||
title: (@Composable () -> Unit)?,
|
||||
onTitleClick: (() -> Unit)? = null,
|
||||
showSearch: Boolean,
|
||||
onTop: Boolean,
|
||||
onSearchValueChanged: (String) -> Unit,
|
||||
buttons: List<@Composable RowScope.() -> Unit> = emptyList(),
|
||||
) {
|
||||
@@ -41,6 +44,7 @@ fun DefaultTopAppBar(
|
||||
navigationIcon = navigationButton,
|
||||
buttons = if (!showSearch) buttons else emptyList(),
|
||||
centered = !showSearch,
|
||||
onTop = onTop,
|
||||
)
|
||||
}
|
||||
|
||||
@@ -90,12 +94,14 @@ private fun TopAppBar(
|
||||
buttons: List<@Composable RowScope.() -> Unit> = emptyList(),
|
||||
backgroundColor: Color = MaterialTheme.colors.primarySurface,
|
||||
centered: Boolean,
|
||||
onTop: Boolean,
|
||||
) {
|
||||
Box(
|
||||
modifier
|
||||
.fillMaxWidth()
|
||||
.height(AppBarHeight * fontSizeSqrtMultiplier)
|
||||
.background(backgroundColor)
|
||||
.then(if (onTop) Modifier.statusBarsPadding() else Modifier.navigationBarsPadding())
|
||||
.height(AppBarHeight * fontSizeSqrtMultiplier)
|
||||
.padding(horizontal = 4.dp),
|
||||
contentAlignment = Alignment.CenterStart,
|
||||
) {
|
||||
|
||||
+4
@@ -242,6 +242,8 @@ private fun ModalData.NewChatSheetLayout(
|
||||
)
|
||||
if (!oneHandUI.value) {
|
||||
Divider()
|
||||
} else {
|
||||
Spacer(Modifier.windowInsetsBottomHeight(WindowInsets.ime))
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -610,6 +612,8 @@ private fun ModalData.DeletedContactsView(rh: RemoteHostInfo?, closeDeletedChats
|
||||
item {
|
||||
if (!oneHandUI.value) {
|
||||
Divider()
|
||||
} else {
|
||||
Spacer(Modifier.windowInsetsBottomHeight(WindowInsets.ime))
|
||||
}
|
||||
ContactsSearchBar(
|
||||
listState = listState,
|
||||
|
||||
Reference in New Issue
Block a user