mirror of
https://github.com/simplex-chat/simplex-chat.git
synced 2025-06-28 20:29:53 +00:00
multiplatform: check preferences before share/forward (#4338)
This commit is contained in:
parent
0fa8d77214
commit
89e65c2fc1
4 changed files with 110 additions and 14 deletions
|
@ -2925,6 +2925,20 @@ sealed class MsgContent {
|
||||||
@Serializable(with = MsgContentSerializer::class) class MCFile(override val text: String): 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()
|
@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() =
|
val cmdString: String get() =
|
||||||
if (this is MCUnknown) "json $json" else "json ${json.encodeToString(this)}"
|
if (this is MCUnknown) "json $json" else "json ${json.encodeToString(this)}"
|
||||||
}
|
}
|
||||||
|
|
|
@ -9,30 +9,55 @@ import androidx.compose.ui.Modifier
|
||||||
import androidx.compose.ui.graphics.Color
|
import androidx.compose.ui.graphics.Color
|
||||||
import androidx.compose.ui.text.style.TextOverflow
|
import androidx.compose.ui.text.style.TextOverflow
|
||||||
import androidx.compose.ui.unit.dp
|
import androidx.compose.ui.unit.dp
|
||||||
import chat.simplex.common.views.helpers.ProfileImage
|
|
||||||
import chat.simplex.common.model.*
|
import chat.simplex.common.model.*
|
||||||
import chat.simplex.common.ui.theme.*
|
import chat.simplex.common.ui.theme.*
|
||||||
|
import chat.simplex.common.views.helpers.*
|
||||||
import chat.simplex.res.MR
|
import chat.simplex.res.MR
|
||||||
|
|
||||||
@Composable
|
@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
|
val stopped = chatModel.chatRunning.value == false
|
||||||
when (chat.chatInfo) {
|
when (chat.chatInfo) {
|
||||||
is ChatInfo.Direct ->
|
is ChatInfo.Direct -> {
|
||||||
|
val voiceProhibited = isVoice && !chat.chatInfo.featureEnabled(ChatFeature.Voice)
|
||||||
ShareListNavLinkLayout(
|
ShareListNavLinkLayout(
|
||||||
chatLinkPreview = { SharePreviewView(chat) },
|
chatLinkPreview = { SharePreviewView(chat, disabled = voiceProhibited) },
|
||||||
click = { directChatAction(chat.remoteHostId, chat.chatInfo.contact, chatModel) },
|
click = {
|
||||||
|
if (voiceProhibited) {
|
||||||
|
showForwardProhibitedByPrefAlert()
|
||||||
|
} else {
|
||||||
|
directChatAction(chat.remoteHostId, chat.chatInfo.contact, chatModel)
|
||||||
|
}
|
||||||
|
},
|
||||||
stopped
|
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(
|
ShareListNavLinkLayout(
|
||||||
chatLinkPreview = { SharePreviewView(chat) },
|
chatLinkPreview = { SharePreviewView(chat, disabled = prohibitedByPref) },
|
||||||
click = { groupChatAction(chat.remoteHostId, chat.chatInfo.groupInfo, chatModel) },
|
click = {
|
||||||
|
if (prohibitedByPref) {
|
||||||
|
showForwardProhibitedByPrefAlert()
|
||||||
|
} else {
|
||||||
|
groupChatAction(chat.remoteHostId, chat.chatInfo.groupInfo, chatModel)
|
||||||
|
}
|
||||||
|
},
|
||||||
stopped
|
stopped
|
||||||
)
|
)
|
||||||
|
}
|
||||||
is ChatInfo.Local ->
|
is ChatInfo.Local ->
|
||||||
ShareListNavLinkLayout(
|
ShareListNavLinkLayout(
|
||||||
chatLinkPreview = { SharePreviewView(chat) },
|
chatLinkPreview = { SharePreviewView(chat, disabled = false) },
|
||||||
click = { noteFolderChatAction(chat.remoteHostId, chat.chatInfo.noteFolder) },
|
click = { noteFolderChatAction(chat.remoteHostId, chat.chatInfo.noteFolder) },
|
||||||
stopped
|
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
|
@Composable
|
||||||
private fun ShareListNavLinkLayout(
|
private fun ShareListNavLinkLayout(
|
||||||
chatLinkPreview: @Composable () -> Unit,
|
chatLinkPreview: @Composable () -> Unit,
|
||||||
|
@ -53,7 +85,7 @@ private fun ShareListNavLinkLayout(
|
||||||
}
|
}
|
||||||
|
|
||||||
@Composable
|
@Composable
|
||||||
private fun SharePreviewView(chat: Chat) {
|
private fun SharePreviewView(chat: Chat, disabled: Boolean) {
|
||||||
Row(
|
Row(
|
||||||
Modifier.fillMaxSize(),
|
Modifier.fillMaxSize(),
|
||||||
horizontalArrangement = Arrangement.SpaceBetween,
|
horizontalArrangement = Arrangement.SpaceBetween,
|
||||||
|
@ -70,7 +102,7 @@ private fun SharePreviewView(chat: Chat) {
|
||||||
}
|
}
|
||||||
Text(
|
Text(
|
||||||
chat.chatInfo.chatViewName, maxLines = 1, overflow = TextOverflow.Ellipsis,
|
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
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -31,13 +31,44 @@ fun ShareListView(chatModel: ChatModel, settingsState: SettingsViewState, stoppe
|
||||||
scaffoldState = scaffoldState,
|
scaffoldState = scaffoldState,
|
||||||
topBar = { Column { ShareListToolbar(chatModel, userPickerState, stopped) { searchInList = it.trim() } } },
|
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)) {
|
Box(Modifier.padding(it)) {
|
||||||
Column(
|
Column(
|
||||||
modifier = Modifier
|
modifier = Modifier
|
||||||
.fillMaxSize()
|
.fillMaxSize()
|
||||||
) {
|
) {
|
||||||
if (chatModel.chats.isNotEmpty()) {
|
if (chatModel.chats.isNotEmpty()) {
|
||||||
ShareList(chatModel, search = searchInList)
|
ShareList(
|
||||||
|
chatModel,
|
||||||
|
search = searchInList,
|
||||||
|
isMediaOrFileAttachment = isMediaOrFileAttachment,
|
||||||
|
isVoice = isVoice,
|
||||||
|
hasSimplexLink = hasSimplexLink
|
||||||
|
)
|
||||||
} else {
|
} else {
|
||||||
EmptyList()
|
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
|
@Composable
|
||||||
private fun EmptyList() {
|
private fun EmptyList() {
|
||||||
Box(Modifier.fillMaxSize(), contentAlignment = Alignment.Center) {
|
Box(Modifier.fillMaxSize(), contentAlignment = Alignment.Center) {
|
||||||
|
@ -141,7 +177,13 @@ private fun ShareListToolbar(chatModel: ChatModel, userPickerState: MutableState
|
||||||
}
|
}
|
||||||
|
|
||||||
@Composable
|
@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) {
|
val chats by remember(search) {
|
||||||
derivedStateOf {
|
derivedStateOf {
|
||||||
val sorted = chatModel.chats.toList().sortedByDescending { it.chatInfo is ChatInfo.Local }
|
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()
|
modifier = Modifier.fillMaxWidth()
|
||||||
) {
|
) {
|
||||||
items(chats) { chat ->
|
items(chats) { chat ->
|
||||||
ShareListNavLinkView(chat, chatModel)
|
ShareListNavLinkView(
|
||||||
|
chat,
|
||||||
|
chatModel,
|
||||||
|
isMediaOrFileAttachment = isMediaOrFileAttachment,
|
||||||
|
isVoice = isVoice,
|
||||||
|
hasSimplexLink = hasSimplexLink
|
||||||
|
)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -358,6 +358,8 @@
|
||||||
<string name="share_image">Share media…</string>
|
<string name="share_image">Share media…</string>
|
||||||
<string name="share_file">Share file…</string>
|
<string name="share_file">Share file…</string>
|
||||||
<string name="forward_message">Forward message…</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 -->
|
<!-- ComposeView.kt, helpers -->
|
||||||
<string name="attach">Attach</string>
|
<string name="attach">Attach</string>
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue