multiplatform: check preferences before share/forward (#4338)

This commit is contained in:
spaced4ndy 2024-06-19 18:53:45 +04:00 committed by GitHub
parent 0fa8d77214
commit 89e65c2fc1
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
4 changed files with 110 additions and 14 deletions

View file

@ -2925,6 +2925,20 @@ sealed class MsgContent {
@Serializable(with = MsgContentSerializer::class) class MCFile(override val text: String): MsgContent()
@Serializable(with = MsgContentSerializer::class) class MCUnknown(val type: String? = null, override val text: String, val json: JsonElement): MsgContent()
val isVoice: Boolean get() =
when (this) {
is MCVoice -> true
else -> false
}
val isMediaOrFileAttachment: Boolean get() =
when (this) {
is MCImage -> true
is MCVideo -> true
is MCFile -> true
else -> false
}
val cmdString: String get() =
if (this is MCUnknown) "json $json" else "json ${json.encodeToString(this)}"
}

View file

@ -9,30 +9,55 @@ import androidx.compose.ui.Modifier
import androidx.compose.ui.graphics.Color
import androidx.compose.ui.text.style.TextOverflow
import androidx.compose.ui.unit.dp
import chat.simplex.common.views.helpers.ProfileImage
import chat.simplex.common.model.*
import chat.simplex.common.ui.theme.*
import chat.simplex.common.views.helpers.*
import chat.simplex.res.MR
@Composable
fun ShareListNavLinkView(chat: Chat, chatModel: ChatModel) {
fun ShareListNavLinkView(
chat: Chat,
chatModel: ChatModel,
isMediaOrFileAttachment: Boolean,
isVoice: Boolean,
hasSimplexLink: Boolean
) {
val stopped = chatModel.chatRunning.value == false
when (chat.chatInfo) {
is ChatInfo.Direct ->
is ChatInfo.Direct -> {
val voiceProhibited = isVoice && !chat.chatInfo.featureEnabled(ChatFeature.Voice)
ShareListNavLinkLayout(
chatLinkPreview = { SharePreviewView(chat) },
click = { directChatAction(chat.remoteHostId, chat.chatInfo.contact, chatModel) },
chatLinkPreview = { SharePreviewView(chat, disabled = voiceProhibited) },
click = {
if (voiceProhibited) {
showForwardProhibitedByPrefAlert()
} else {
directChatAction(chat.remoteHostId, chat.chatInfo.contact, chatModel)
}
},
stopped
)
is ChatInfo.Group ->
}
is ChatInfo.Group -> {
val simplexLinkProhibited = hasSimplexLink && !chat.groupFeatureEnabled(GroupFeature.SimplexLinks)
val fileProhibited = isMediaOrFileAttachment && !chat.groupFeatureEnabled(GroupFeature.Files)
val voiceProhibited = isVoice && !chat.chatInfo.featureEnabled(ChatFeature.Voice)
val prohibitedByPref = simplexLinkProhibited || fileProhibited || voiceProhibited
ShareListNavLinkLayout(
chatLinkPreview = { SharePreviewView(chat) },
click = { groupChatAction(chat.remoteHostId, chat.chatInfo.groupInfo, chatModel) },
chatLinkPreview = { SharePreviewView(chat, disabled = prohibitedByPref) },
click = {
if (prohibitedByPref) {
showForwardProhibitedByPrefAlert()
} else {
groupChatAction(chat.remoteHostId, chat.chatInfo.groupInfo, chatModel)
}
},
stopped
)
}
is ChatInfo.Local ->
ShareListNavLinkLayout(
chatLinkPreview = { SharePreviewView(chat) },
chatLinkPreview = { SharePreviewView(chat, disabled = false) },
click = { noteFolderChatAction(chat.remoteHostId, chat.chatInfo.noteFolder) },
stopped
)
@ -40,6 +65,13 @@ fun ShareListNavLinkView(chat: Chat, chatModel: ChatModel) {
}
}
private fun showForwardProhibitedByPrefAlert() {
AlertManager.shared.showAlertMsg(
title = generalGetString(MR.strings.cannot_share_message_alert_title),
text = generalGetString(MR.strings.cannot_share_message_alert_text),
)
}
@Composable
private fun ShareListNavLinkLayout(
chatLinkPreview: @Composable () -> Unit,
@ -53,7 +85,7 @@ private fun ShareListNavLinkLayout(
}
@Composable
private fun SharePreviewView(chat: Chat) {
private fun SharePreviewView(chat: Chat, disabled: Boolean) {
Row(
Modifier.fillMaxSize(),
horizontalArrangement = Arrangement.SpaceBetween,
@ -70,7 +102,7 @@ private fun SharePreviewView(chat: Chat) {
}
Text(
chat.chatInfo.chatViewName, maxLines = 1, overflow = TextOverflow.Ellipsis,
color = if (chat.chatInfo.incognito) Indigo else Color.Unspecified
color = if (disabled) MaterialTheme.colors.secondary else if (chat.chatInfo.incognito) Indigo else Color.Unspecified
)
}
}

View file

@ -31,13 +31,44 @@ fun ShareListView(chatModel: ChatModel, settingsState: SettingsViewState, stoppe
scaffoldState = scaffoldState,
topBar = { Column { ShareListToolbar(chatModel, userPickerState, stopped) { searchInList = it.trim() } } },
) {
val sharedContent = chatModel.sharedContent.value
var isMediaOrFileAttachment = false
var isVoice = false
var hasSimplexLink = false
when (sharedContent) {
is SharedContent.Text ->
hasSimplexLink = hasSimplexLink(sharedContent.text)
is SharedContent.Media -> {
isMediaOrFileAttachment = true
hasSimplexLink = hasSimplexLink(sharedContent.text)
}
is SharedContent.File -> {
isMediaOrFileAttachment = true
hasSimplexLink = hasSimplexLink(sharedContent.text)
}
is SharedContent.Forward -> {
val mc = sharedContent.chatItem.content.msgContent
if (mc != null) {
isMediaOrFileAttachment = mc.isMediaOrFileAttachment
isVoice = mc.isVoice
hasSimplexLink = hasSimplexLink(mc.text)
}
}
null -> {}
}
Box(Modifier.padding(it)) {
Column(
modifier = Modifier
.fillMaxSize()
) {
if (chatModel.chats.isNotEmpty()) {
ShareList(chatModel, search = searchInList)
ShareList(
chatModel,
search = searchInList,
isMediaOrFileAttachment = isMediaOrFileAttachment,
isVoice = isVoice,
hasSimplexLink = hasSimplexLink
)
} else {
EmptyList()
}
@ -54,6 +85,11 @@ fun ShareListView(chatModel: ChatModel, settingsState: SettingsViewState, stoppe
}
}
private fun hasSimplexLink(msg: String): Boolean {
val parsedMsg = parseToMarkdown(msg) ?: return false
return parsedMsg.any { ft -> ft.format is Format.SimplexLink }
}
@Composable
private fun EmptyList() {
Box(Modifier.fillMaxSize(), contentAlignment = Alignment.Center) {
@ -141,7 +177,13 @@ private fun ShareListToolbar(chatModel: ChatModel, userPickerState: MutableState
}
@Composable
private fun ShareList(chatModel: ChatModel, search: String) {
private fun ShareList(
chatModel: ChatModel,
search: String,
isMediaOrFileAttachment: Boolean,
isVoice: Boolean,
hasSimplexLink: Boolean
) {
val chats by remember(search) {
derivedStateOf {
val sorted = chatModel.chats.toList().sortedByDescending { it.chatInfo is ChatInfo.Local }
@ -156,7 +198,13 @@ private fun ShareList(chatModel: ChatModel, search: String) {
modifier = Modifier.fillMaxWidth()
) {
items(chats) { chat ->
ShareListNavLinkView(chat, chatModel)
ShareListNavLinkView(
chat,
chatModel,
isMediaOrFileAttachment = isMediaOrFileAttachment,
isVoice = isVoice,
hasSimplexLink = hasSimplexLink
)
}
}
}

View file

@ -358,6 +358,8 @@
<string name="share_image">Share media…</string>
<string name="share_file">Share file…</string>
<string name="forward_message">Forward message…</string>
<string name="cannot_share_message_alert_title">Cannot send message</string>
<string name="cannot_share_message_alert_text">Selected chat preferences prohibit this message.</string>
<!-- ComposeView.kt, helpers -->
<string name="attach">Attach</string>