This commit is contained in:
Avently
2024-10-16 20:35:08 +07:00
parent 2cb3e77392
commit fb976e31b2
17 changed files with 218 additions and 154 deletions
@@ -31,6 +31,13 @@ class MainActivity: FragmentActivity() {
val c = CurrentColors.value.colors
platform.androidSetStatusAndNavigationBarAppearance(c.isLight)
applyAppLocale(ChatModel.controller.appPrefs.appLanguage)
// This flag makes status bar and navigation bar fully transparent. But on API level < 30 it breaks insets entirely
// https://issuetracker.google.com/issues/236862874
if (Build.VERSION.SDK_INT > Build.VERSION_CODES.Q){
window.setFlags(WindowManager.LayoutParams.FLAG_LAYOUT_NO_LIMITS, WindowManager.LayoutParams.FLAG_LAYOUT_NO_LIMITS)
} else {
window.setFlags(WindowManager.LayoutParams.FLAG_TRANSLUCENT_NAVIGATION, WindowManager.LayoutParams.FLAG_TRANSLUCENT_NAVIGATION)
}
super.onCreate(savedInstanceState)
// testJson()
// When call ended and orientation changes, it re-process old intent, it's unneeded.
@@ -7,6 +7,8 @@ import chat.simplex.common.platform.Log
import android.content.Intent
import android.content.pm.ActivityInfo
import android.os.*
import android.view.View
import android.view.WindowManager.LayoutParams
import androidx.compose.animation.core.*
import androidx.compose.runtime.Composable
import androidx.compose.runtime.DisposableEffect
@@ -285,6 +287,13 @@ class SimplexApp: Application(), LifecycleEventObserver {
if (windowInsetController?.isAppearanceLightNavigationBars != CurrentColors.value.colors.isLight) {
windowInsetController?.isAppearanceLightNavigationBars = CurrentColors.value.colors.isLight
}
if (Build.VERSION.SDK_INT < Build.VERSION_CODES.R) {
window.decorView.systemUiVisibility = if (CurrentColors.value.colors.isLight) {
View.SYSTEM_UI_FLAG_LIGHT_STATUS_BAR or View.SYSTEM_UI_FLAG_LIGHT_NAVIGATION_BAR
} else {
0
}
}
}
override fun androidStartCallActivity(acceptCall: Boolean, remoteHostId: Long?, chatId: ChatId?) {
@@ -8,8 +8,7 @@ import androidx.compose.runtime.*
import androidx.compose.ui.Alignment
import androidx.compose.ui.Modifier
import androidx.compose.ui.input.nestedscroll.nestedScroll
import androidx.compose.ui.platform.LocalLayoutDirection
import chat.simplex.common.model.ChatController.appPrefs
import chat.simplex.common.views.chatlist.NavigationBarBackground
import chat.simplex.common.views.helpers.*
import kotlinx.coroutines.flow.filter
import kotlin.math.absoluteValue
@@ -39,14 +38,12 @@ actual fun LazyColumnWithScrollBar(
}
}
}
val direction = LocalLayoutDirection.current
val paddingEnd = WindowInsets.navigationBars.asPaddingValues().calculateEndPadding(direction)
if (connection != null) {
LazyColumn(modifier.nestedScroll(connection).padding(end = paddingEnd), state, contentPadding, reverseLayout, verticalArrangement, horizontalAlignment, flingBehavior, userScrollEnabled) {
LazyColumn(modifier.nestedScroll(connection), state, contentPadding, reverseLayout, verticalArrangement, horizontalAlignment, flingBehavior, userScrollEnabled) {
content()
}
} else {
LazyColumn(modifier.padding(end = paddingEnd), state, contentPadding, reverseLayout, verticalArrangement, horizontalAlignment, flingBehavior, userScrollEnabled) {
LazyColumn(modifier, state, contentPadding, reverseLayout, verticalArrangement, horizontalAlignment, flingBehavior, userScrollEnabled) {
content()
}
}
@@ -74,25 +71,30 @@ actual fun ColumnWithScrollBar(
}
}
}
val direction = LocalLayoutDirection.current
if (connection != null) {
Box(Modifier.fillMaxHeight()) {
if (connection != null) {
Column(
if (maxIntrinsicSize) {
modifier.nestedScroll(connection).verticalScroll(state).height(IntrinsicSize.Max).padding(end = WindowInsets.navigationBars.asPaddingValues().calculateEndPadding(direction))
modifier.nestedScroll(connection).verticalScroll(state).height(IntrinsicSize.Max)
} else {
modifier.nestedScroll(connection).verticalScroll(state).padding(end = WindowInsets.navigationBars.asPaddingValues().calculateEndPadding(direction))
}, verticalArrangement, horizontalAlignment) {
modifier.nestedScroll(connection).verticalScroll(state)
}, verticalArrangement, horizontalAlignment
) {
content()
Spacer(Modifier.windowInsetsBottomHeight(WindowInsets.systemBars))
}
} else {
Column(if (maxIntrinsicSize) {
modifier.verticalScroll(state).height(IntrinsicSize.Max).padding(end = WindowInsets.navigationBars.asPaddingValues().calculateEndPadding(direction))
} else {
modifier.verticalScroll(state).padding(end = WindowInsets.navigationBars.asPaddingValues().calculateEndPadding(direction))
}, verticalArrangement, horizontalAlignment) {
} else {
Column(
if (maxIntrinsicSize) {
modifier.verticalScroll(state).height(IntrinsicSize.Max)
} else {
modifier.verticalScroll(state)
}, verticalArrangement, horizontalAlignment
) {
content()
Spacer(Modifier.windowInsetsBottomHeight(WindowInsets.systemBars))
}
}
NavigationBarBackground()
}
}
@@ -3,17 +3,18 @@ package chat.simplex.common.platform
import android.app.Activity
import android.content.Context
import android.content.pm.ActivityInfo
import android.graphics.Rect
import android.os.*
import android.view.*
import android.view.inputmethod.InputMethodManager
import android.widget.Toast
import androidx.activity.compose.setContent
import androidx.compose.foundation.layout.WindowInsets
import androidx.compose.foundation.layout.ime
import androidx.compose.runtime.*
import androidx.compose.ui.platform.LocalDensity
import androidx.compose.ui.platform.LocalView
import chat.simplex.common.AppScreen
import chat.simplex.common.model.clear
import chat.simplex.common.ui.theme.SimpleXTheme
import chat.simplex.common.views.helpers.*
import androidx.compose.ui.platform.LocalContext as LocalContext1
import chat.simplex.res.MR
@@ -43,28 +44,13 @@ actual fun LocalMultiplatformView(): Any? = LocalView.current
@Composable
actual fun getKeyboardState(): State<KeyboardState> {
val keyboardState = remember { mutableStateOf(KeyboardState.Closed) }
val view = LocalView.current
DisposableEffect(view) {
val onGlobalListener = ViewTreeObserver.OnGlobalLayoutListener {
val rect = Rect()
view.getWindowVisibleDisplayFrame(rect)
val screenHeight = view.rootView.height
val keypadHeight = screenHeight - rect.bottom
keyboardState.value = if (keypadHeight > screenHeight * 0.15) {
KeyboardState.Opened
} else {
KeyboardState.Closed
}
}
view.viewTreeObserver.addOnGlobalLayoutListener(onGlobalListener)
onDispose {
view.viewTreeObserver.removeOnGlobalLayoutListener(onGlobalListener)
val density = LocalDensity.current
val ime = WindowInsets.ime
return remember {
derivedStateOf {
if (ime.getBottom(density) == 0) KeyboardState.Closed else KeyboardState.Opened
}
}
return keyboardState
}
actual fun hideKeyboard(view: Any?, clearFocus: Boolean) {
@@ -138,65 +138,73 @@ actual fun PlatformUserPicker(modifier: Modifier, pickerState: MutableStateFlow<
} else {
Modifier
}
Box(
Modifier
.fillMaxSize()
.then(clickableModifier)
.drawBehind {
val pos = when {
dismissState.progress.from == DismissValue.Default && dismissState.progress.to == DismissValue.Default -> 1f
dismissState.progress.from == DismissValue.DismissedToEnd && dismissState.progress.to == DismissValue.DismissedToEnd -> 0f
dismissState.progress.to == DismissValue.Default -> dismissState.progress.fraction
else -> 1 - dismissState.progress.fraction
}
val colors = CurrentColors.value.colors
val resultingColor = if (colors.isLight) colors.onSurface.copy(alpha = ScrimOpacity) else Color.Black.copy(0.64f)
drawRect(
if (pos != 0f) resultingColor else Color.Transparent,
alpha = calculateFraction(pos = pos)
)
}
.graphicsLayer {
if (heightValue == 0) {
alpha = 0f
}
translationY = dismissState.offset.value
},
contentAlignment = Alignment.BottomCenter
) {
Box {
Box(
Modifier.onSizeChanged { height.intValue = it.height }
) {
KeyChangeEffect(pickerIsVisible) {
if (pickerState.value.isVisible()) {
try {
dismissState.animateTo(DismissValue.Default, userPickerAnimSpec())
} catch (e: CancellationException) {
Log.e(TAG, "Cancelled animateTo: ${e.stackTraceToString()}")
pickerState.value = AnimatedViewState.GONE
Modifier
.fillMaxSize()
.then(clickableModifier)
.drawBehind {
val pos = calculatePosition(dismissState)
val colors = CurrentColors.value.colors
val resultingColor = if (colors.isLight) colors.onSurface.copy(alpha = ScrimOpacity) else Color.Black.copy(0.64f)
drawRect(
if (pos != 0f) resultingColor else Color.Transparent,
alpha = calculateFraction(pos = pos)
)
}
.graphicsLayer {
if (heightValue == 0) {
alpha = 0f
}
} else {
try {
dismissState.animateTo(DismissValue.DismissedToEnd, userPickerAnimSpec())
} catch (e: CancellationException) {
Log.e(TAG, "Cancelled animateTo2: ${e.stackTraceToString()}")
pickerState.value = AnimatedViewState.VISIBLE
translationY = dismissState.offset.value
},
contentAlignment = Alignment.BottomCenter
) {
Box(
Modifier.onSizeChanged { height.intValue = it.height }
) {
KeyChangeEffect(pickerIsVisible) {
if (pickerState.value.isVisible()) {
try {
dismissState.animateTo(DismissValue.Default, userPickerAnimSpec())
} catch (e: CancellationException) {
Log.e(TAG, "Cancelled animateTo: ${e.stackTraceToString()}")
pickerState.value = AnimatedViewState.GONE
}
} else {
try {
dismissState.animateTo(DismissValue.DismissedToEnd, userPickerAnimSpec())
} catch (e: CancellationException) {
Log.e(TAG, "Cancelled animateTo2: ${e.stackTraceToString()}")
pickerState.value = AnimatedViewState.VISIBLE
}
}
}
}
val draggableModifier = if (height.intValue != 0)
Modifier.draggableBottomDrawerModifier(
state = dismissState,
swipeDistance = height.intValue.toFloat(),
)
else Modifier
Box(draggableModifier.then(modifier)) {
content()
val draggableModifier = if (height.intValue != 0)
Modifier.draggableBottomDrawerModifier(
state = dismissState,
swipeDistance = height.intValue.toFloat(),
)
else Modifier
Box(draggableModifier.then(modifier).navigationBarsPadding()) {
content()
}
}
}
NavigationBarBackground(
modifier = Modifier.graphicsLayer { alpha = if (calculatePosition(dismissState) > 0.1f) 1f else 0f },
color = MaterialTheme.colors.background.mixWith(MaterialTheme.colors.onBackground, alpha = 1 - userPickerAlpha())
)
}
}
private fun calculatePosition(dismissState: DismissState): Float = when {
dismissState.progress.from == DismissValue.Default && dismissState.progress.to == DismissValue.Default -> 1f
dismissState.progress.from == DismissValue.DismissedToEnd && dismissState.progress.to == DismissValue.DismissedToEnd -> 0f
dismissState.progress.to == DismissValue.Default -> dismissState.progress.fraction
else -> 1 - dismissState.progress.fraction
}
private fun Modifier.draggableBottomDrawerModifier(
state: DismissState,
swipeDistance: Float,
@@ -171,6 +171,8 @@ actual fun GetImageBottomSheet(
modifier = Modifier
.fillMaxWidth()
.wrapContentHeight()
.imePadding()
.navigationBarsPadding()
.onFocusChanged { focusState ->
if (!focusState.hasFocus) hideBottomSheet()
}
@@ -12,9 +12,9 @@ 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.graphics.Color
import androidx.compose.ui.graphics.graphicsLayer
import androidx.compose.ui.platform.LocalDensity
import androidx.compose.ui.platform.LocalLayoutDirection
import androidx.compose.ui.unit.dp
import chat.simplex.common.views.usersettings.SetDeliveryReceiptsView
import chat.simplex.common.model.*
@@ -45,7 +45,22 @@ fun AppScreen() {
AppBarHandler.appBarMaxHeightPx = with(LocalDensity.current) { AppBarHeight.roundToPx() }
SimpleXTheme {
Surface(color = MaterialTheme.colors.background, contentColor = LocalContentColor.current) {
MainScreen()
// This padding applies to landscape view only taking care of navigation bar and holes in screen in status bar area
// (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)
// 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()
}
Box(Modifier.width(paddingStart).fillMaxHeight().background(MaterialTheme.colors.background))
Box(Modifier.align(Alignment.CenterEnd).width(paddingEnd).fillMaxHeight().background(MaterialTheme.colors.background))
}
}
}
}
@@ -245,7 +260,10 @@ fun AndroidScreen(userPickerState: MutableStateFlow<AnimatedViewState>) {
Box(
Modifier
.graphicsLayer {
translationX = -offset.value.dp.toPx()
// minOf thing is needed for devices with holes in screen while the user on ChatView rotates his phone from portrait to landscape
// because in this case (at least in emulator) maxWidth changes in two steps: big first, smaller on next frame.
// But offset is remembered already, so this is a better way than dropping a value of offset
translationX = -minOf(offset.value.dp, maxWidth).toPx()
}
.padding(top = if (showCallArea) ANDROID_CALL_TOP_PADDING else 0.dp)
) {
@@ -275,7 +293,7 @@ fun AndroidScreen(userPickerState: MutableStateFlow<AnimatedViewState>) {
}
}
Box(Modifier
.graphicsLayer { translationX = maxWidth.toPx() - offset.value.dp.toPx() }
.graphicsLayer { translationX = maxWidth.toPx() - minOf(offset.value.dp, maxWidth).toPx() }
.padding(top = if (showCallArea) ANDROID_CALL_TOP_PADDING else 0.dp)
) Box2@{
currentChatId.value?.let {
@@ -20,6 +20,7 @@ import chat.simplex.common.views.chat.*
import chat.simplex.common.views.helpers.*
import chat.simplex.common.model.ChatModel
import chat.simplex.common.platform.*
import chat.simplex.common.views.chatlist.NavigationBarBackground
import kotlinx.coroutines.flow.collect
import kotlinx.coroutines.flow.filter
import kotlinx.coroutines.launch
@@ -170,13 +171,16 @@ fun TerminalLog(floating: Boolean) {
ModalManager.start
}
modalPlace.showModal(endButtons = { ShareButton { clipboard.shareText(item.details) } }) {
SelectionContainer(modifier = Modifier.verticalScroll(rememberScrollState()).navigationBarsPadding()) {
val details = item.details
.let {
if (it.length < 100_000) it
else it.substring(0, 100_000)
}
Text(details, modifier = Modifier.heightIn(max = 50_000.dp).padding(horizontal = DEFAULT_PADDING).padding(bottom = DEFAULT_PADDING))
Box(Modifier.fillMaxHeight()) {
SelectionContainer(modifier = Modifier.verticalScroll(rememberScrollState()).navigationBarsPadding()) {
val details = item.details
.let {
if (it.length < 100_000) it
else it.substring(0, 100_000)
}
Text(details, modifier = Modifier.heightIn(max = 50_000.dp).padding(horizontal = DEFAULT_PADDING).padding(bottom = DEFAULT_PADDING))
}
NavigationBarBackground()
}
}
}.padding(horizontal = 8.dp, vertical = 4.dp)
@@ -704,7 +704,7 @@ fun ChatLayout(
}
@Composable
fun ChatInfoToolbar(
fun ColumnScope.ChatInfoToolbar(
chatInfo: ChatInfo,
back: () -> Unit,
info: () -> Unit,
@@ -866,12 +866,12 @@ fun ChatInfoToolbar(
onSearchValueChanged = onSearchValueChanged,
buttons = barButtons
)
Box(Modifier.fillMaxWidth().wrapContentSize(Alignment.TopEnd)) {
Box(Modifier.align(Alignment.End)) {
DefaultDropdownMenu(showMenu) {
menuItems.forEach { it() }
}
}
Divider()
Divider(Modifier.background(MaterialTheme.colors.background))
}
@Composable
@@ -1360,8 +1360,8 @@ fun BoxScope.FloatingButtons(
onLongClick = { showDropDown.value = true }
)
Box(Modifier.offset { IntOffset(maxWidth.value - DEFAULT_PADDING.roundToPx(), (24.dp + fabSize).roundToPx()) }) {
DefaultDropdownMenu(showDropDown) {
Box(Modifier.align(Alignment.TopEnd)) {
DefaultDropdownMenu(showDropDown, offset = DpOffset(-DEFAULT_PADDING, 24.dp + fabSize)) {
ItemAction(
generalGetString(MR.strings.mark_read),
painterResource(MR.images.ic_check),
@@ -1045,7 +1045,6 @@ fun ComposeView(
)
}
Spacer(Modifier.imePadding().navigationBarsPadding())
// WindowInsets.ime.asPaddingValues().calculateBottomPadding()
}
}
}
@@ -283,6 +283,7 @@ fun ModalData.GroupChatInfoLayout(
if (s.isEmpty()) members else members.filter { m -> m.anyNameContains(s) }
}
}
Box {
LazyColumnWithScrollBar(
Modifier
.fillMaxWidth(),
@@ -397,9 +398,11 @@ fun ModalData.GroupChatInfoLayout(
}
}
SectionBottomSpacer()
Spacer(Modifier.windowInsetsBottomHeight(WindowInsets.systemBars))
Spacer(Modifier.windowInsetsBottomHeight(WindowInsets.navigationBars))
}
}
NavigationBarBackground()
}
}
@Composable
@@ -12,6 +12,7 @@ import androidx.compose.runtime.*
import androidx.compose.runtime.saveable.rememberSaveable
import androidx.compose.ui.Alignment
import androidx.compose.ui.Modifier
import androidx.compose.ui.draw.blur
import androidx.compose.ui.draw.clip
import androidx.compose.ui.focus.*
import androidx.compose.ui.graphics.*
@@ -587,13 +588,29 @@ enum class ScrollDirection {
Up, Down, Idle
}
private const val SYSTEM_BAR_BACKGROUND_ALPHA = 0.6f
@Composable
fun StatusBarBackground() {
Box(Modifier.background(MaterialTheme.colors.background).windowInsetsTopHeight(WindowInsets.statusBars))
fun BoxScope.StatusBarBackground() {
if (appPlatform.isAndroid) {
val finalColor = MaterialTheme.colors.background.copy(SYSTEM_BAR_BACKGROUND_ALPHA)
Box(Modifier.fillMaxWidth().windowInsetsTopHeight(WindowInsets.statusBars).background(finalColor))
}
}
@Composable
private fun ChatList(chatModel: ChatModel, searchText: MutableState<TextFieldValue>) {
fun BoxScope.NavigationBarBackground(modifier: Modifier = Modifier, color: Color = MaterialTheme.colors.background) {
val keyboardState = getKeyboardState()
if (appPlatform.isAndroid && keyboardState.value == KeyboardState.Closed) {
val barPadding = WindowInsets.navigationBars.asPaddingValues()
val paddingBottom = barPadding.calculateBottomPadding()
val finalColor = color.copy(SYSTEM_BAR_BACKGROUND_ALPHA)
Box(modifier.align(Alignment.BottomStart).height(paddingBottom).fillMaxWidth().background(finalColor))
}
}
@Composable
private fun BoxScope.ChatList(chatModel: ChatModel, searchText: MutableState<TextFieldValue>) {
val listState = rememberLazyListState(lazyListState.first, lazyListState.second)
var scrollDirection by remember { mutableStateOf(ScrollDirection.Idle) }
var previousIndex by remember { mutableStateOf(0) }
@@ -631,10 +648,6 @@ private fun ChatList(chatModel: ChatModel, searchText: MutableState<TextFieldVal
val searchShowingSimplexLink = remember { mutableStateOf(false) }
val searchChatFilteredBySimplexLink = remember { mutableStateOf<String?>(null) }
val chats = filteredChats(showUnreadAndFavorites, searchShowingSimplexLink, searchChatFilteredBySimplexLink, searchText.value.text, allChats.value.toList())
Column {
if (oneHandUI.value) {
StatusBarBackground()
}
LazyColumnWithScrollBar(
Modifier.fillMaxSize().then(if (!oneHandUI.value) Modifier.imePadding() else Modifier),
listState,
@@ -684,16 +697,20 @@ private fun ChatList(chatModel: ChatModel, searchText: MutableState<TextFieldVal
ToggleChatListCard()
}
}
if (!oneHandUI.value) {
item { Spacer(Modifier.windowInsetsBottomHeight(WindowInsets.navigationBars)) }
if (appPlatform.isAndroid) {
item { Spacer(if (oneHandUI.value) Modifier.windowInsetsTopHeight(WindowInsets.statusBars) else Modifier.windowInsetsBottomHeight(WindowInsets.navigationBars)) }
}
}
}
if (chats.isEmpty() && chatModel.chats.value.isNotEmpty()) {
Box(Modifier.fillMaxSize(), contentAlignment = Alignment.Center) {
Text(generalGetString(MR.strings.no_filtered_chats), color = MaterialTheme.colors.secondary)
}
}
if (oneHandUI.value) {
StatusBarBackground()
} else {
NavigationBarBackground()
}
}
fun filteredChats(
@@ -69,24 +69,22 @@ fun ShareListView(chatModel: ChatModel, stopped: Boolean) {
}
null -> {}
}
Box(Modifier.padding(it)) {
Column(
modifier = Modifier.fillMaxSize()
) {
if (oneHandUI.value) {
StatusBarBackground()
}
if (chatModel.chats.value.isNotEmpty()) {
ShareList(
chatModel,
search = searchInList,
isMediaOrFileAttachment = isMediaOrFileAttachment,
isVoice = isVoice,
hasSimplexLink = hasSimplexLink,
)
} else {
EmptyList()
}
Box(Modifier.fillMaxSize().padding(it)) {
if (chatModel.chats.value.isNotEmpty()) {
ShareList(
chatModel,
search = searchInList,
isMediaOrFileAttachment = isMediaOrFileAttachment,
isVoice = isVoice,
hasSimplexLink = hasSimplexLink,
)
} else {
EmptyList()
}
if (oneHandUI.value) {
StatusBarBackground()
} else {
NavigationBarBackground()
}
}
}
@@ -228,9 +226,9 @@ private fun ShareList(
hasSimplexLink = hasSimplexLink,
)
}
if (!oneHandUI.value) {
if (appPlatform.isAndroid) {
item {
Spacer(Modifier.windowInsetsBottomHeight(WindowInsets.navigationBars))
Spacer(if (oneHandUI.value) Modifier.windowInsetsTopHeight(WindowInsets.statusBars) else Modifier.windowInsetsBottomHeight(WindowInsets.navigationBars))
}
}
}
@@ -143,7 +143,6 @@ fun UserPicker(
.fillMaxWidth()
.then(if (newChat.isVisible()) Modifier.shadow(8.dp, clip = true) else Modifier)
.background(if (appPlatform.isAndroid) MaterialTheme.colors.background.mixWith(MaterialTheme.colors.onBackground, alpha = 1 - userPickerAlpha()) else MaterialTheme.colors.surface)
.navigationBarsPadding()
.padding(bottom = USER_PICKER_SECTION_SPACING - DEFAULT_MIN_SECTION_ITEM_PADDING_VERTICAL),
pickerState = userPickerState
) {
@@ -12,7 +12,6 @@ import androidx.compose.desktop.ui.tooling.preview.Preview
import androidx.compose.foundation.background
import androidx.compose.ui.draw.*
import androidx.compose.ui.graphics.*
import androidx.compose.ui.platform.LocalLayoutDirection
import androidx.compose.ui.text.font.FontWeight
import androidx.compose.ui.unit.*
import chat.simplex.common.platform.appPlatform
@@ -100,8 +99,7 @@ fun CloseSheetBar(close: (() -> Unit)?, showClose: Boolean = true, tintColor: Co
} else {
Spacer(Modifier.weight(1f))
}
val direction = LocalLayoutDirection.current
Row(Modifier.padding(end = WindowInsets.navigationBars.asPaddingValues().calculateEndPadding(direction))) {
Row {
endButtons()
}
}
@@ -102,7 +102,6 @@ fun AddGroupLayout(
ColumnWithScrollBar(
Modifier
.fillMaxSize()
.padding(horizontal = DEFAULT_PADDING)
) {
AppBarTitle(stringResource(MR.strings.create_secret_group_title), hostDevice(rhId))
Box(
@@ -121,7 +120,7 @@ fun AddGroupLayout(
}
}
}
Row(Modifier.padding(bottom = DEFAULT_PADDING_HALF).fillMaxWidth(), horizontalArrangement = Arrangement.SpaceBetween) {
Row(Modifier.padding(start = DEFAULT_PADDING, end = DEFAULT_PADDING, bottom = DEFAULT_PADDING_HALF).fillMaxWidth(), horizontalArrangement = Arrangement.SpaceBetween) {
Text(
stringResource(MR.strings.group_display_name_field),
fontSize = 16.sp
@@ -133,7 +132,9 @@ fun AddGroupLayout(
}
}
}
ProfileNameField(displayName, "", { isValidDisplayName(it.trim()) }, focusRequester)
Box(Modifier.padding(horizontal = DEFAULT_PADDING)) {
ProfileNameField(displayName, "", { isValidDisplayName(it.trim()) }, focusRequester)
}
Spacer(Modifier.height(8.dp))
SettingsActionItem(
@@ -30,8 +30,7 @@ import chat.simplex.common.model.*
import chat.simplex.common.model.ChatController.appPrefs
import chat.simplex.common.platform.*
import chat.simplex.common.ui.theme.*
import chat.simplex.common.views.chatlist.ScrollDirection
import chat.simplex.common.views.chatlist.StatusBarBackground
import chat.simplex.common.views.chatlist.*
import chat.simplex.common.views.contacts.*
import chat.simplex.common.views.helpers.*
import chat.simplex.res.MR
@@ -183,10 +182,7 @@ private fun ModalData.NewChatSheetLayout(
derivedStateOf { filterContactTypes(chatModel.chats.value, deletedContactTypes) }
}
Column {
if (oneHandUI.value) {
StatusBarBackground()
}
Box {
LazyColumnWithScrollBar(
Modifier.fillMaxSize().then(if (!oneHandUI.value) Modifier.imePadding() else Modifier),
listState,
@@ -350,7 +346,17 @@ private fun ModalData.NewChatSheetLayout(
}
ContactListNavLinkView(chat, nextChatSelected, showDeletedChatIcon = true)
}
if (appPlatform.isAndroid) {
item {
Spacer(if (oneHandUI.value) Modifier.windowInsetsTopHeight(WindowInsets.statusBars) else Modifier.windowInsetsBottomHeight(WindowInsets.navigationBars))
}
}
}
if (oneHandUI.value) {
StatusBarBackground()
} else {
NavigationBarBackground()
}
}
}
@@ -588,10 +594,7 @@ private fun ModalData.DeletedContactsView(rh: RemoteHostInfo?, closeDeletedChats
contactChats = allChats
)
Column {
if (oneHandUI.value) {
StatusBarBackground()
}
Box {
LazyColumnWithScrollBar(
Modifier.fillMaxSize().then(if (!oneHandUI.value) Modifier.imePadding() else Modifier),
contentPadding = contentPadding,
@@ -644,7 +647,17 @@ private fun ModalData.DeletedContactsView(rh: RemoteHostInfo?, closeDeletedChats
}
ContactListNavLinkView(chat, nextChatSelected, showDeletedChatIcon = false)
}
if (appPlatform.isAndroid) {
item {
Spacer(if (oneHandUI.value) Modifier.windowInsetsTopHeight(WindowInsets.statusBars) else Modifier.windowInsetsBottomHeight(WindowInsets.navigationBars))
}
}
}
if (oneHandUI.value) {
StatusBarBackground()
} else {
NavigationBarBackground()
}
}
}
}