mirror of
https://github.com/simplex-chat/simplex-chat.git
synced 2026-08-06 23:39:54 +00:00
a lot of changes
This commit is contained in:
+78
-37
@@ -347,7 +347,9 @@ fun ChatView(
|
||||
setGroupMembers(chatRh, groupInfo, chatModel)
|
||||
if (!isActive) return@launch
|
||||
|
||||
ModalManager.end.closeModals()
|
||||
if (!groupReports.value.reportsView) {
|
||||
ModalManager.end.closeModals()
|
||||
}
|
||||
ModalManager.end.showModalCloseable(true) { close ->
|
||||
remember { derivedStateOf { chatModel.getGroupMember(member.groupMemberId) } }.value?.let { mem ->
|
||||
GroupMemberInfoView(chatRh, groupInfo, mem, stats, code, chatModel, close, close)
|
||||
@@ -744,7 +746,7 @@ fun ChatLayout(
|
||||
sheetShape = RoundedCornerShape(topStart = 18.dp, topEnd = 18.dp)
|
||||
) {
|
||||
val composeViewHeight = remember { mutableStateOf(0.dp) }
|
||||
Box(Modifier.fillMaxSize().chatViewBackgroundModifier(MaterialTheme.colors, MaterialTheme.wallpaper, LocalAppBarHandler.current?.backgroundGraphicsLayerSize, LocalAppBarHandler.current?.backgroundGraphicsLayer)) {
|
||||
Box(Modifier.fillMaxSize().chatViewBackgroundModifier(MaterialTheme.colors, MaterialTheme.wallpaper, LocalAppBarHandler.current?.backgroundGraphicsLayerSize, LocalAppBarHandler.current?.backgroundGraphicsLayer, !groupReports.value.reportsView)) {
|
||||
val remoteHostId = remember { remoteHostId }.value
|
||||
val chatInfo = remember { chatInfo }.value
|
||||
val oneHandUI = remember { appPrefs.oneHandUI.state }
|
||||
@@ -766,7 +768,42 @@ fun ChatLayout(
|
||||
}
|
||||
}
|
||||
}
|
||||
if (!groupReports.value.reportsView) {
|
||||
if (groupReports.value.reportsView) {
|
||||
Column(
|
||||
Modifier
|
||||
.layoutId(CHAT_COMPOSE_LAYOUT_ID)
|
||||
.align(Alignment.BottomCenter)
|
||||
.navigationBarsPadding()
|
||||
.imePadding()
|
||||
) {
|
||||
AnimatedVisibility(selectedChatItems.value != null) {
|
||||
if (chatInfo != null) {
|
||||
SelectedItemsBottomToolbar(
|
||||
reversedChatItems = reversedChatItems,
|
||||
selectedChatItems = selectedChatItems,
|
||||
chatInfo = chatInfo,
|
||||
deleteItems = { _ ->
|
||||
val itemIds = selectedChatItems.value
|
||||
val questionText = generalGetString(MR.strings.delete_messages_cannot_be_undone_warning)
|
||||
if (itemIds != null) {
|
||||
deleteMessagesAlertDialog(itemIds.sorted(), questionText = questionText, forAll = false, deleteMessages = { ids, _ ->
|
||||
deleteMessages(remoteHostId, chatInfo, ids, false, moderate = false) {
|
||||
selectedChatItems.value = null
|
||||
}
|
||||
})
|
||||
}
|
||||
},
|
||||
moderateItems = {},
|
||||
forwardItems = {}
|
||||
)
|
||||
}
|
||||
}
|
||||
if (oneHandUI.value) {
|
||||
// That's placeholder to take some space for bottom app bar in oneHandUI
|
||||
Box(Modifier.height(AppBarHeight * fontSizeSqrtMultiplier))
|
||||
}
|
||||
}
|
||||
} else {
|
||||
Box(
|
||||
Modifier
|
||||
.layoutId(CHAT_COMPOSE_LAYOUT_ID)
|
||||
@@ -777,49 +814,46 @@ fun ChatLayout(
|
||||
) {
|
||||
composeView()
|
||||
}
|
||||
} else {
|
||||
// That's placeholder to take some space for bottom app bar in oneHandUI
|
||||
Box(
|
||||
Modifier
|
||||
.layoutId(CHAT_COMPOSE_LAYOUT_ID)
|
||||
.align(Alignment.BottomCenter)
|
||||
.height(if (oneHandUI.value) AppBarHeight * fontSizeSqrtMultiplier else 0.dp)
|
||||
)
|
||||
}
|
||||
}
|
||||
if (oneHandUI.value && chatBottomBar.value) {
|
||||
if (groupReports.value.showBar) {
|
||||
GroupReportsToolbar(groupReports, withStatusBar = true, showGroupReports)
|
||||
} else {
|
||||
StatusBarBackground()
|
||||
}
|
||||
if (groupReports.value.showBar) {
|
||||
ReportedCountToolbar(groupReports, withStatusBar = true, showGroupReports)
|
||||
} else {
|
||||
StatusBarBackground()
|
||||
}
|
||||
} else {
|
||||
NavigationBarBackground(true, oneHandUI.value, noAlpha = true)
|
||||
}
|
||||
Column(if (oneHandUI.value && chatBottomBar.value) Modifier.align(Alignment.BottomStart).imePadding() else Modifier) {
|
||||
if (!groupReports.value.reportsView) {
|
||||
if (groupReports.value.reportsView) {
|
||||
if (oneHandUI.value) {
|
||||
StatusBarBackground()
|
||||
}
|
||||
Column(if (oneHandUI.value) Modifier.align(Alignment.BottomStart).imePadding() else Modifier) {
|
||||
Box {
|
||||
if (selectedChatItems.value == null) {
|
||||
GroupReportsAppBar(groupReports, { ModalManager.end.closeModal() }, showArchived = { showHide ->
|
||||
showArchivedReports.value = showHide
|
||||
}, onSearchValueChanged)
|
||||
} else {
|
||||
SelectedItemsTopToolbar(selectedChatItems, !oneHandUI.value)
|
||||
}
|
||||
}
|
||||
}
|
||||
} else {
|
||||
Column(if (oneHandUI.value && chatBottomBar.value) Modifier.align(Alignment.BottomStart).imePadding() else Modifier) {
|
||||
Box {
|
||||
if (selectedChatItems.value == null) {
|
||||
if (chatInfo != null) {
|
||||
ChatInfoToolbar(chatInfo, groupReports, back, info, startCall, endCall, addMembers, openGroupLink, changeNtfsState, onSearchValueChanged, showSearch)
|
||||
}
|
||||
} else {
|
||||
SelectedItemsTopToolbar(selectedChatItems)
|
||||
SelectedItemsTopToolbar(selectedChatItems, !oneHandUI.value || !chatBottomBar.value)
|
||||
}
|
||||
}
|
||||
}
|
||||
if (groupReports.value.showBar && (!oneHandUI.value || !chatBottomBar.value)) {
|
||||
GroupReportsToolbar(groupReports, withStatusBar = false, showGroupReports)
|
||||
}
|
||||
}
|
||||
if (groupReports.value.reportsView) {
|
||||
if (oneHandUI.value) {
|
||||
StatusBarBackground()
|
||||
}
|
||||
Box(Modifier.align(if (oneHandUI.value) Alignment.BottomStart else Alignment.TopStart)) {
|
||||
GroupReportsAppBar(groupReports, { ModalManager.end.closeModal() }, showArchived = { showHide ->
|
||||
showArchivedReports.value = showHide
|
||||
}, onSearchValueChanged)
|
||||
if (groupReports.value.showBar && (!oneHandUI.value || !chatBottomBar.value)) {
|
||||
ReportedCountToolbar(groupReports, withStatusBar = false, showGroupReports)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1047,7 +1081,7 @@ fun ChatInfoToolbarTitle(cInfo: ChatInfo, imageSize: Dp = 40.dp, iconColor: Colo
|
||||
}
|
||||
|
||||
@Composable
|
||||
private fun GroupReportsToolbar(
|
||||
private fun ReportedCountToolbar(
|
||||
groupReports: State<GroupReports>,
|
||||
withStatusBar: Boolean,
|
||||
showGroupReports: () -> Unit
|
||||
@@ -1139,7 +1173,7 @@ fun BoxScope.ChatItemsList(
|
||||
val maxHeightForList = rememberUpdatedState(
|
||||
with(LocalDensity.current) { LocalWindowHeight().roundToPx() - topPaddingToContentPx.value - (AppBarHeight * fontSizeSqrtMultiplier * 2).roundToPx() }
|
||||
)
|
||||
val listState = rememberUpdatedState(rememberSaveable(chatInfo.id, searchValueIsEmpty.value, saver = LazyListState.Saver) {
|
||||
val listState = rememberUpdatedState(rememberSaveable(chatInfo.id, searchValueIsEmpty.value, groupReports.value.showArchived, saver = LazyListState.Saver) {
|
||||
val index = mergedItems.value.items.indexOfLast { it.hasUnread() }
|
||||
val reportsState = reportsListState
|
||||
if (reportsState != null) {
|
||||
@@ -1187,7 +1221,13 @@ fun BoxScope.ChatItemsList(
|
||||
}
|
||||
val scrollToQuotedItemFromItem: (Long) -> Unit = remember { findQuotedItemFromItem(remoteHostIdUpdated, chatInfoUpdated, scope, scrollToItem, groupReports.value.contentTag) }
|
||||
if (!groupReports.value.reportsView) {
|
||||
LaunchedEffect(Unit) { snapshotFlow { scrollToItemId.value }.filterNotNull().collect { scrollToItem(it); scrollToItemId.value = null } }
|
||||
LaunchedEffect(Unit) { snapshotFlow { scrollToItemId.value }.filterNotNull().collect {
|
||||
if (appPlatform.isAndroid) {
|
||||
ModalManager.end.closeModals()
|
||||
}
|
||||
scrollToItem(it)
|
||||
scrollToItemId.value = null }
|
||||
}
|
||||
}
|
||||
LoadLastItems(loadingMoreItems, remoteHostId, chatInfo, groupReports)
|
||||
SmallScrollOnNewMessage(listState, reversedChatItems)
|
||||
@@ -2347,7 +2387,8 @@ fun Modifier.chatViewBackgroundModifier(
|
||||
colors: Colors,
|
||||
wallpaper: AppWallpaper,
|
||||
backgroundGraphicsLayerSize: MutableState<IntSize>?,
|
||||
backgroundGraphicsLayer: GraphicsLayer?
|
||||
backgroundGraphicsLayer: GraphicsLayer?,
|
||||
drawWallpaper: Boolean
|
||||
): Modifier {
|
||||
val wallpaperImage = wallpaper.type.image
|
||||
val wallpaperType = wallpaper.type
|
||||
@@ -2355,7 +2396,7 @@ fun Modifier.chatViewBackgroundModifier(
|
||||
val tintColor = wallpaper.tint ?: wallpaperType.defaultTintColor(CurrentColors.value.base)
|
||||
|
||||
return this
|
||||
.then(if (wallpaperImage != null)
|
||||
.then(if (wallpaperImage != null && drawWallpaper)
|
||||
Modifier.drawWithCache { chatViewBackground(wallpaperImage, wallpaperType, backgroundColor, tintColor, backgroundGraphicsLayerSize, backgroundGraphicsLayer) }
|
||||
else
|
||||
Modifier.drawWithCache { onDrawBehind { copyBackgroundToAppBar(backgroundGraphicsLayerSize, backgroundGraphicsLayer) { drawRect(backgroundColor) } } }
|
||||
|
||||
+2
-3
@@ -21,11 +21,10 @@ import chat.simplex.res.MR
|
||||
import dev.icerock.moko.resources.compose.painterResource
|
||||
|
||||
@Composable
|
||||
fun BoxScope.SelectedItemsTopToolbar(selectedChatItems: MutableState<Set<Long>?>) {
|
||||
fun BoxScope.SelectedItemsTopToolbar(selectedChatItems: MutableState<Set<Long>?>, onTop: Boolean) {
|
||||
val onBackClicked = { selectedChatItems.value = null }
|
||||
BackHandler(onBack = onBackClicked)
|
||||
val count = selectedChatItems.value?.size ?: 0
|
||||
val oneHandUI = remember { appPrefs.oneHandUI.state }
|
||||
DefaultAppBar(
|
||||
navigationButton = { NavigationButtonClose(onButtonClicked = onBackClicked) },
|
||||
title = {
|
||||
@@ -41,7 +40,7 @@ fun BoxScope.SelectedItemsTopToolbar(selectedChatItems: MutableState<Set<Long>?>
|
||||
)
|
||||
},
|
||||
onTitleClick = null,
|
||||
onTop = !oneHandUI.value,
|
||||
onTop = onTop,
|
||||
onSearchValueChanged = {},
|
||||
)
|
||||
}
|
||||
|
||||
+39
-24
@@ -1,13 +1,18 @@
|
||||
package chat.simplex.common.views.chat.group
|
||||
|
||||
import androidx.compose.foundation.layout.*
|
||||
import androidx.compose.material.*
|
||||
import androidx.compose.runtime.*
|
||||
import androidx.compose.runtime.saveable.rememberSaveable
|
||||
import androidx.compose.ui.Alignment
|
||||
import androidx.compose.ui.Modifier
|
||||
import androidx.compose.ui.layout.onSizeChanged
|
||||
import androidx.compose.ui.platform.LocalDensity
|
||||
import androidx.compose.ui.unit.*
|
||||
import chat.simplex.common.model.*
|
||||
import chat.simplex.common.model.ChatController.appPrefs
|
||||
import chat.simplex.common.platform.*
|
||||
import chat.simplex.common.views.chat.ChatView
|
||||
import chat.simplex.common.views.chat.apiLoadMessages
|
||||
import chat.simplex.common.views.chat.*
|
||||
import chat.simplex.common.views.chat.item.ItemAction
|
||||
import chat.simplex.common.views.chatlist.*
|
||||
import chat.simplex.common.views.helpers.*
|
||||
@@ -15,7 +20,6 @@ import chat.simplex.res.MR
|
||||
import dev.icerock.moko.resources.compose.painterResource
|
||||
import dev.icerock.moko.resources.compose.stringResource
|
||||
import kotlinx.coroutines.flow.*
|
||||
import kotlinx.coroutines.launch
|
||||
|
||||
val LocalContentTag: ProvidableCompositionLocal<MsgContentTag?> = staticCompositionLocalOf { null }
|
||||
|
||||
@@ -69,29 +73,40 @@ fun GroupReportsAppBar(
|
||||
IconButton({ showMenu.value = true }) {
|
||||
Icon(MoreVertFilled, stringResource(MR.strings.icon_descr_more_button), tint = MaterialTheme.colors.primary)
|
||||
}
|
||||
val onClosedAction = remember { mutableStateOf({}) }
|
||||
DefaultDropdownMenu(
|
||||
showMenu,
|
||||
onClosed = onClosedAction
|
||||
) {
|
||||
ItemAction(stringResource(MR.strings.search_verb), painterResource(MR.images.ic_search), onClick = {
|
||||
showMenu.value = false
|
||||
showSearch.value = true
|
||||
})
|
||||
ItemAction(
|
||||
if (groupReports.value.showArchived) stringResource(MR.strings.group_reports_show_active) else stringResource(MR.strings.group_reports_show_archived),
|
||||
painterResource(if (groupReports.value.showArchived) MR.images.ic_flag else MR.images.ic_inventory_2),
|
||||
onClick = {
|
||||
onClosedAction.value = {
|
||||
showArchived(!groupReports.value.showArchived)
|
||||
onClosedAction.value = {}
|
||||
}
|
||||
showMenu.value = false
|
||||
}
|
||||
)
|
||||
}
|
||||
}
|
||||
)
|
||||
Box(Modifier.fillMaxWidth().wrapContentSize(Alignment.TopEnd)) {
|
||||
val density = LocalDensity.current
|
||||
val width = remember { mutableStateOf(250.dp) }
|
||||
val height = remember { mutableStateOf(0.dp) }
|
||||
|
||||
val onClosedAction = remember { mutableStateOf({}) }
|
||||
DefaultDropdownMenu(
|
||||
showMenu,
|
||||
modifier = Modifier.onSizeChanged { with(density) {
|
||||
width.value = it.width.toDp().coerceAtLeast(250.dp)
|
||||
if (oneHandUI.value && (appPlatform.isDesktop || (platform.androidApiLevel ?: 0) >= 30)) height.value = it.height.toDp()
|
||||
} },
|
||||
offset = DpOffset(-width.value, if (oneHandUI.value) -height.value else AppBarHeight),
|
||||
onClosed = onClosedAction
|
||||
) {
|
||||
ItemAction(stringResource(MR.strings.search_verb), painterResource(MR.images.ic_search), onClick = {
|
||||
showMenu.value = false
|
||||
showSearch.value = true
|
||||
})
|
||||
ItemAction(
|
||||
if (groupReports.value.showArchived) stringResource(MR.strings.group_reports_show_active) else stringResource(MR.strings.group_reports_show_archived),
|
||||
painterResource(if (groupReports.value.showArchived) MR.images.ic_flag else MR.images.ic_inventory_2),
|
||||
onClick = {
|
||||
onClosedAction.value = {
|
||||
showArchived(!groupReports.value.showArchived)
|
||||
onClosedAction.value = {}
|
||||
}
|
||||
showMenu.value = false
|
||||
}
|
||||
)
|
||||
}
|
||||
}
|
||||
ItemsReload(groupReports)
|
||||
}
|
||||
|
||||
|
||||
+52
-41
@@ -128,17 +128,6 @@ fun FramedItemView(
|
||||
Modifier
|
||||
.background(if (sent) sentColor else receivedColor)
|
||||
.fillMaxWidth()
|
||||
.combinedClickable(
|
||||
onLongClick = { showMenu.value = true },
|
||||
onClick = {
|
||||
if (qi.itemId != null) {
|
||||
scrollToItem(qi.itemId)
|
||||
} else {
|
||||
scrollToQuotedItemFromItem(ci.id)
|
||||
}
|
||||
}
|
||||
)
|
||||
.onRightClick { showMenu.value = true }
|
||||
) {
|
||||
when (qi.content) {
|
||||
is MsgContent.MCImage -> {
|
||||
@@ -216,39 +205,61 @@ fun FramedItemView(
|
||||
.padding(start = if (tailRendered) msgTailWidthDp else 0.dp, end = if (sent && tailRendered) msgTailWidthDp else 0.dp)
|
||||
) {
|
||||
PriorityLayout(Modifier, CHAT_IMAGE_LAYOUT_ID) {
|
||||
if (ci.isReport) {
|
||||
if (ci.meta.itemDeleted == null) {
|
||||
FramedItemHeader(
|
||||
stringResource(if (ci.chatDir.sent) MR.strings.report_item_visibility_submitter else MR.strings.report_item_visibility_moderators),
|
||||
true,
|
||||
painterResource(MR.images.ic_flag),
|
||||
iconColor = Color.Red
|
||||
)
|
||||
} else {
|
||||
FramedItemHeader(stringResource(MR.strings.report_item_archived), true, painterResource(MR.images.ic_flag))
|
||||
@Composable
|
||||
fun Header() {
|
||||
if (ci.isReport) {
|
||||
if (ci.meta.itemDeleted == null) {
|
||||
FramedItemHeader(
|
||||
stringResource(if (ci.chatDir.sent) MR.strings.report_item_visibility_submitter else MR.strings.report_item_visibility_moderators),
|
||||
true,
|
||||
painterResource(MR.images.ic_flag),
|
||||
iconColor = Color.Red
|
||||
)
|
||||
} else {
|
||||
FramedItemHeader(stringResource(MR.strings.report_item_archived), true, painterResource(MR.images.ic_flag))
|
||||
}
|
||||
} else if (ci.meta.itemDeleted != null) {
|
||||
when (ci.meta.itemDeleted) {
|
||||
is CIDeleted.Moderated -> {
|
||||
FramedItemHeader(String.format(stringResource(MR.strings.moderated_item_description), ci.meta.itemDeleted.byGroupMember.chatViewName), true, painterResource(MR.images.ic_flag))
|
||||
}
|
||||
is CIDeleted.Blocked -> {
|
||||
FramedItemHeader(stringResource(MR.strings.blocked_item_description), true, painterResource(MR.images.ic_back_hand))
|
||||
}
|
||||
is CIDeleted.BlockedByAdmin -> {
|
||||
FramedItemHeader(stringResource(MR.strings.blocked_by_admin_item_description), true, painterResource(MR.images.ic_back_hand))
|
||||
}
|
||||
is CIDeleted.Deleted -> {
|
||||
FramedItemHeader(stringResource(MR.strings.marked_deleted_description), true, painterResource(MR.images.ic_delete))
|
||||
}
|
||||
}
|
||||
} else if (ci.meta.isLive) {
|
||||
FramedItemHeader(stringResource(MR.strings.live), false)
|
||||
}
|
||||
} else if (ci.meta.itemDeleted != null) {
|
||||
when (ci.meta.itemDeleted) {
|
||||
is CIDeleted.Moderated -> {
|
||||
FramedItemHeader(String.format(stringResource(MR.strings.moderated_item_description), ci.meta.itemDeleted.byGroupMember.chatViewName), true, painterResource(MR.images.ic_flag))
|
||||
}
|
||||
is CIDeleted.Blocked -> {
|
||||
FramedItemHeader(stringResource(MR.strings.blocked_item_description), true, painterResource(MR.images.ic_back_hand))
|
||||
}
|
||||
is CIDeleted.BlockedByAdmin -> {
|
||||
FramedItemHeader(stringResource(MR.strings.blocked_by_admin_item_description), true, painterResource(MR.images.ic_back_hand))
|
||||
}
|
||||
is CIDeleted.Deleted -> {
|
||||
FramedItemHeader(stringResource(MR.strings.marked_deleted_description), true, painterResource(MR.images.ic_delete))
|
||||
}
|
||||
}
|
||||
} else if (ci.meta.isLive) {
|
||||
FramedItemHeader(stringResource(MR.strings.live), false)
|
||||
}
|
||||
if (ci.quotedItem != null) {
|
||||
ciQuoteView(ci.quotedItem)
|
||||
} else if (ci.meta.itemForwarded != null) {
|
||||
FramedItemHeader(ci.meta.itemForwarded.text(chatInfo.chatType), true, painterResource(MR.images.ic_forward), pad = true)
|
||||
Column(
|
||||
Modifier
|
||||
.combinedClickable(
|
||||
onLongClick = { showMenu.value = true },
|
||||
onClick = {
|
||||
if (ci.quotedItem.itemId != null) {
|
||||
scrollToItem(ci.quotedItem.itemId)
|
||||
} else {
|
||||
scrollToQuotedItemFromItem(ci.id)
|
||||
}
|
||||
}
|
||||
)
|
||||
.onRightClick { showMenu.value = true }
|
||||
) {
|
||||
Header()
|
||||
ciQuoteView(ci.quotedItem)
|
||||
}
|
||||
} else {
|
||||
Header()
|
||||
if (ci.meta.itemForwarded != null) {
|
||||
FramedItemHeader(ci.meta.itemForwarded.text(chatInfo.chatType), true, painterResource(MR.images.ic_forward), pad = true)
|
||||
}
|
||||
}
|
||||
if (ci.file == null && ci.formattedText == null && !ci.meta.isLive && isShortEmoji(ci.content.text)) {
|
||||
Box(Modifier.padding(vertical = 6.dp, horizontal = 12.dp)) {
|
||||
|
||||
+2
-1
@@ -35,7 +35,8 @@ fun DefaultAppBar(
|
||||
// If I just disable clickable modifier when don't need it, it will stop passing clicks to search. Replacing the whole modifier
|
||||
val modifier = if (!showSearch) {
|
||||
Modifier.clickable(enabled = onTitleClick != null, onClick = onTitleClick ?: { })
|
||||
} else Modifier.imePadding()
|
||||
} else if (!onTop) Modifier.imePadding()
|
||||
else Modifier
|
||||
|
||||
val themeBackgroundMix = MaterialTheme.colors.background.mixWith(MaterialTheme.colors.onBackground, 0.97f)
|
||||
val prefAlpha = remember { appPrefs.inAppBarsAlpha.state }
|
||||
|
||||
Reference in New Issue
Block a user