mirror of
https://github.com/simplex-chat/simplex-chat.git
synced 2026-08-29 07:38:54 +00:00
wip
This commit is contained in:
@@ -54,8 +54,6 @@ struct ComposeState {
|
||||
var progressByTimeout = false
|
||||
var useLinkPreviews = true
|
||||
var mentions: MentionedMembers = [:]
|
||||
// per-send opt-in to sign the message (relay channels only); resets on send/chat change, not persisted
|
||||
var sign = false
|
||||
|
||||
init(
|
||||
message: String = "",
|
||||
@@ -64,8 +62,7 @@ struct ComposeState {
|
||||
preview: ComposePreview = .noPreview,
|
||||
contextItem: ComposeContextItem = .noContextItem,
|
||||
voiceMessageRecordingState: VoiceMessageRecordingState = .noRecording,
|
||||
mentions: MentionedMembers = [:],
|
||||
sign: Bool = false
|
||||
mentions: MentionedMembers = [:]
|
||||
) {
|
||||
self.message = message
|
||||
self.parsedMessage = parsedMessage
|
||||
@@ -74,7 +71,6 @@ struct ComposeState {
|
||||
self.contextItem = contextItem
|
||||
self.voiceMessageRecordingState = voiceMessageRecordingState
|
||||
self.mentions = mentions
|
||||
self.sign = sign
|
||||
}
|
||||
|
||||
init(editingItem: ChatItem) {
|
||||
@@ -111,8 +107,7 @@ struct ComposeState {
|
||||
preview: ComposePreview? = nil,
|
||||
contextItem: ComposeContextItem? = nil,
|
||||
voiceMessageRecordingState: VoiceMessageRecordingState? = nil,
|
||||
mentions: MentionedMembers? = nil,
|
||||
sign: Bool? = nil
|
||||
mentions: MentionedMembers? = nil
|
||||
) -> ComposeState {
|
||||
ComposeState(
|
||||
message: message ?? self.message,
|
||||
@@ -121,8 +116,7 @@ struct ComposeState {
|
||||
preview: preview ?? self.preview,
|
||||
contextItem: contextItem ?? self.contextItem,
|
||||
voiceMessageRecordingState: voiceMessageRecordingState ?? self.voiceMessageRecordingState,
|
||||
mentions: mentions ?? self.mentions,
|
||||
sign: sign ?? self.sign
|
||||
mentions: mentions ?? self.mentions
|
||||
)
|
||||
}
|
||||
|
||||
@@ -1045,6 +1039,10 @@ struct ComposeView: View {
|
||||
sendMessage(ttl: ttl)
|
||||
resetLinkPreview()
|
||||
},
|
||||
sendSignedMessage: {
|
||||
sendMessage(ttl: nil, sign: true)
|
||||
resetLinkPreview()
|
||||
},
|
||||
sendLiveMessage: chat.chatInfo.chatType != .local ? sendLiveMessage : nil,
|
||||
updateLiveMessage: updateLiveMessage,
|
||||
cancelLiveMessage: {
|
||||
@@ -1065,7 +1063,6 @@ struct ComposeView: View {
|
||||
allowVoiceMessagesToContact: allowVoiceMessagesToContact,
|
||||
timedMessageAllowed: chat.chatInfo.featureEnabled(.timedMessages),
|
||||
showSign: chat.chatInfo.groupInfo?.useRelays == true,
|
||||
sendAsGroup: chat.chatInfo.sendAsGroup,
|
||||
onMediaAdded: { media in if !media.isEmpty { chosenMedia = media }},
|
||||
keyboardVisible: $keyboardVisible,
|
||||
keyboardHiddenDate: $keyboardHiddenDate,
|
||||
@@ -1464,16 +1461,16 @@ struct ComposeView: View {
|
||||
}
|
||||
|
||||
// Spec: spec/client/compose.md#sendMessage
|
||||
private func sendMessage(ttl: Int?) {
|
||||
private func sendMessage(ttl: Int?, sign: Bool = false) {
|
||||
logger.debug("ChatView sendMessage")
|
||||
Task {
|
||||
logger.debug("ChatView sendMessage: in Task")
|
||||
_ = await sendMessageAsync(nil, live: false, ttl: ttl)
|
||||
_ = await sendMessageAsync(nil, live: false, ttl: ttl, sign: sign)
|
||||
}
|
||||
}
|
||||
|
||||
// Spec: spec/client/compose.md#sendMessageAsync
|
||||
private func sendMessageAsync(_ text: String?, live: Bool, ttl: Int?) async -> ChatItem? {
|
||||
private func sendMessageAsync(_ text: String?, live: Bool, ttl: Int?, sign: Bool = false) async -> ChatItem? {
|
||||
var sent: ChatItem?
|
||||
let msgText = text ?? composeState.message
|
||||
let liveMessage = composeState.liveMessage
|
||||
@@ -1486,7 +1483,7 @@ struct ComposeView: View {
|
||||
// Composed text is send as a reply to the last forwarded item
|
||||
sent = await forwardItems(chatItems, fromChatInfo, ttl).last
|
||||
if !composeState.message.isEmpty {
|
||||
_ = await send(checkLinkPreview(), quoted: sent?.id, live: false, ttl: ttl, mentions: mentions)
|
||||
_ = await send(checkLinkPreview(), quoted: sent?.id, live: false, ttl: ttl, mentions: mentions, sign: sign)
|
||||
}
|
||||
} else if case let .editingItem(ci) = composeState.contextItem {
|
||||
sent = await updateMessage(ci, live: live)
|
||||
@@ -1502,13 +1499,13 @@ struct ComposeView: View {
|
||||
|
||||
switch (composeState.preview) {
|
||||
case .noPreview:
|
||||
sent = await send(.text(msgText), quoted: quoted, live: live, ttl: ttl, mentions: mentions)
|
||||
sent = await send(.text(msgText), quoted: quoted, live: live, ttl: ttl, mentions: mentions, sign: sign)
|
||||
case .linkPreview:
|
||||
sent = await send(checkLinkPreview(), quoted: quoted, live: live, ttl: ttl, mentions: mentions)
|
||||
sent = await send(checkLinkPreview(), quoted: quoted, live: live, ttl: ttl, mentions: mentions, sign: sign)
|
||||
case let .chatLinkPreview(chatLink, ownerSig):
|
||||
let linkStr = chatLink.connLinkStr
|
||||
let text = msgText.isEmpty ? linkStr : msgText + "\n" + linkStr
|
||||
sent = await send(.chat(text: text, chatLink: chatLink, ownerSig: ownerSig), quoted: quoted, live: live, ttl: ttl, mentions: mentions)
|
||||
sent = await send(.chat(text: text, chatLink: chatLink, ownerSig: ownerSig), quoted: quoted, live: live, ttl: ttl, mentions: mentions, sign: sign)
|
||||
case let .mediaPreviews(media):
|
||||
// TODO: CHECK THIS
|
||||
let last = media.count - 1
|
||||
@@ -1530,15 +1527,15 @@ struct ComposeView: View {
|
||||
if msgs.isEmpty {
|
||||
msgs = [ComposedMessage(quotedItemId: quoted, msgContent: .text(msgText))]
|
||||
}
|
||||
sent = await send(msgs, live: live, ttl: ttl).last
|
||||
sent = await send(msgs, live: live, ttl: ttl, sign: sign).last
|
||||
|
||||
case let .voicePreview(recordingFileName, duration):
|
||||
stopPlayback.toggle()
|
||||
let file = voiceCryptoFile(recordingFileName)
|
||||
sent = await send(.voice(text: msgText, duration: duration), quoted: quoted, file: file, ttl: ttl, mentions: mentions)
|
||||
sent = await send(.voice(text: msgText, duration: duration), quoted: quoted, file: file, ttl: ttl, mentions: mentions, sign: sign)
|
||||
case let .filePreview(_, file):
|
||||
if let savedFile = saveFileFromURL(file) {
|
||||
sent = await send(.file(msgText), quoted: quoted, file: savedFile, live: live, ttl: ttl, mentions: mentions)
|
||||
sent = await send(.file(msgText), quoted: quoted, file: savedFile, live: live, ttl: ttl, mentions: mentions, sign: sign)
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1672,15 +1669,16 @@ struct ComposeView: View {
|
||||
)
|
||||
}
|
||||
|
||||
func send(_ mc: MsgContent, quoted: Int64?, file: CryptoFile? = nil, live: Bool = false, ttl: Int?, mentions: [String: Int64]) async -> ChatItem? {
|
||||
func send(_ mc: MsgContent, quoted: Int64?, file: CryptoFile? = nil, live: Bool = false, ttl: Int?, mentions: [String: Int64], sign: Bool = false) async -> ChatItem? {
|
||||
await send(
|
||||
[ComposedMessage(fileSource: file, quotedItemId: quoted, msgContent: mc, mentions: mentions)],
|
||||
live: live,
|
||||
ttl: ttl
|
||||
ttl: ttl,
|
||||
sign: sign
|
||||
).first
|
||||
}
|
||||
|
||||
func send(_ msgs: [ComposedMessage], live: Bool, ttl: Int?) async -> [ChatItem] {
|
||||
func send(_ msgs: [ComposedMessage], live: Bool, ttl: Int?, sign: Bool = false) async -> [ChatItem] {
|
||||
if let chatItems = chat.chatInfo.chatType == .local
|
||||
? await apiCreateChatItems(noteFolderId: chat.chatInfo.apiId, composedMessages: msgs)
|
||||
: await apiSendMessages(
|
||||
@@ -1690,7 +1688,7 @@ struct ComposeView: View {
|
||||
sendAsGroup: chat.chatInfo.sendAsGroup,
|
||||
live: live,
|
||||
ttl: ttl,
|
||||
sign: composeState.sign,
|
||||
sign: sign,
|
||||
composedMessages: msgs
|
||||
) {
|
||||
await MainActor.run {
|
||||
|
||||
@@ -19,6 +19,7 @@ struct SendMessageView: View {
|
||||
@EnvironmentObject var theme: AppTheme
|
||||
@Environment(\.isEnabled) var isEnabled
|
||||
var sendMessage: (Int?) -> Void
|
||||
var sendSignedMessage: () -> Void = {}
|
||||
var sendLiveMessage: (() async -> Void)? = nil
|
||||
var updateLiveMessage: (() async -> Void)? = nil
|
||||
var cancelLiveMessage: (() -> Void)? = nil
|
||||
@@ -33,7 +34,6 @@ struct SendMessageView: View {
|
||||
var allowVoiceMessagesToContact: (() -> Void)? = nil
|
||||
var timedMessageAllowed: Bool = false
|
||||
var showSign: Bool = false
|
||||
var sendAsGroup: Bool = false
|
||||
var onMediaAdded: ([UploadContent]) -> Void
|
||||
@State private var holdingVMR = false
|
||||
@Namespace var namespace
|
||||
@@ -45,10 +45,10 @@ struct SendMessageView: View {
|
||||
@State private var sendButtonSize: CGFloat = 29
|
||||
@State private var sendButtonOpacity: CGFloat = 1
|
||||
@State private var showCustomDisappearingMessageDialogue = false
|
||||
@State private var showSignInfoAlert = false
|
||||
@State private var showCustomTimePicker = false
|
||||
@State private var selectedDisappearingMessageTime: Int? = customDisappearingMessageTimeDefault.get()
|
||||
@UserDefault(DEFAULT_LIVE_MESSAGE_ALERT_SHOWN) private var liveMessageAlertShown = false
|
||||
@UserDefault(DEFAULT_SIGN_MESSAGE_ALERT_SHOWN) private var signMessageAlertShown = false
|
||||
|
||||
var body: some View {
|
||||
let composeShape = RoundedRectangle(cornerSize: CGSize(width: 20, height: 20))
|
||||
@@ -208,16 +208,6 @@ struct SendMessageView: View {
|
||||
disappearingMessageCustomTimePicker()
|
||||
}
|
||||
}
|
||||
.alert("Sign message", isPresented: $showSignInfoAlert) {
|
||||
Button("OK") {}
|
||||
Button("Don't sign", role: .cancel) { composeState.sign = false }
|
||||
} message: {
|
||||
Text(
|
||||
sendAsGroup
|
||||
? "A signature is transferable, non-repudiable proof that you authored this message — it confirms authorship and integrity, not timing, order, or completeness. Signing a post sent as the channel also reveals you as its author."
|
||||
: "A signature is transferable, non-repudiable proof that you authored this message — it confirms authorship and integrity, not timing, order, or completeness."
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
private func disappearingMessageCustomTimePicker() -> some View {
|
||||
@@ -258,13 +248,9 @@ struct SendMessageView: View {
|
||||
}
|
||||
if showSign {
|
||||
Button {
|
||||
composeState.sign.toggle()
|
||||
if composeState.sign { showSignInfoAlert = true }
|
||||
startSignedMessage()
|
||||
} label: {
|
||||
Label(
|
||||
composeState.sign ? "Signing message" : "Sign message",
|
||||
systemImage: composeState.sign ? "checkmark.seal.fill" : "checkmark.seal"
|
||||
)
|
||||
Label("Sign message", systemImage: "checkmark.seal")
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -376,6 +362,22 @@ struct SendMessageView: View {
|
||||
.padding([.bottom, .horizontal], 4)
|
||||
}
|
||||
|
||||
private func startSignedMessage() {
|
||||
if signMessageAlertShown {
|
||||
sendSignedMessage()
|
||||
} else {
|
||||
AlertManager.shared.showAlert(Alert(
|
||||
title: Text("Sign message"),
|
||||
message: Text("A signature is transferable, non-repudiable proof that you authored this message."),
|
||||
primaryButton: .default(Text("Send")) {
|
||||
signMessageAlertShown = true
|
||||
sendSignedMessage()
|
||||
},
|
||||
secondaryButton: .cancel()
|
||||
))
|
||||
}
|
||||
}
|
||||
|
||||
private func startLiveMessage(send: @escaping () async -> Void, update: @escaping () async -> Void) {
|
||||
if liveMessageAlertShown {
|
||||
start()
|
||||
|
||||
@@ -57,6 +57,7 @@ let DEFAULT_ADDRESS_CREATION_CARD_SHOWN = "addressCreationCardShown"
|
||||
let DEFAULT_TOOLBAR_MATERIAL = "toolbarMaterial"
|
||||
let DEFAULT_CONNECT_VIA_LINK_TAB = "connectViaLinkTab"
|
||||
let DEFAULT_LIVE_MESSAGE_ALERT_SHOWN = "liveMessageAlertShown"
|
||||
let DEFAULT_SIGN_MESSAGE_ALERT_SHOWN = "signMessageAlertShown"
|
||||
let DEFAULT_SHOW_HIDDEN_PROFILES_NOTICE = "showHiddenProfilesNotice"
|
||||
let DEFAULT_SHOW_MUTE_PROFILE_ALERT = "showMuteProfileAlert"
|
||||
let DEFAULT_SHOW_REPORTS_IN_SUPPORT_CHAT_ALERT = "showReportsInSupportChatAlert"
|
||||
@@ -117,6 +118,7 @@ let appDefaults: [String: Any] = [
|
||||
DEFAULT_TOOLBAR_MATERIAL: ToolbarMaterial.defaultMaterial,
|
||||
DEFAULT_CONNECT_VIA_LINK_TAB: ConnectViaLinkTab.scan.rawValue,
|
||||
DEFAULT_LIVE_MESSAGE_ALERT_SHOWN: false,
|
||||
DEFAULT_SIGN_MESSAGE_ALERT_SHOWN: false,
|
||||
DEFAULT_SHOW_HIDDEN_PROFILES_NOTICE: true,
|
||||
DEFAULT_SHOW_MUTE_PROFILE_ALERT: true,
|
||||
DEFAULT_SHOW_REPORTS_IN_SUPPORT_CHAT_ALERT: true,
|
||||
@@ -145,6 +147,7 @@ let hintDefaults = [
|
||||
DEFAULT_ONE_HAND_UI_CARD_SHOWN,
|
||||
DEFAULT_ADDRESS_CREATION_CARD_SHOWN,
|
||||
DEFAULT_LIVE_MESSAGE_ALERT_SHOWN,
|
||||
DEFAULT_SIGN_MESSAGE_ALERT_SHOWN,
|
||||
DEFAULT_SHOW_HIDDEN_PROFILES_NOTICE,
|
||||
DEFAULT_SHOW_MUTE_PROFILE_ALERT,
|
||||
DEFAULT_SHOW_REPORTS_IN_SUPPORT_CHAT_ALERT,
|
||||
|
||||
+3
@@ -186,6 +186,7 @@ class AppPreferences {
|
||||
val networkTCPKeepCnt = mkIntPreference(SHARED_PREFS_NETWORK_TCP_KEEP_CNT, KeepAliveOpts.defaults.keepCnt)
|
||||
val incognito = mkBoolPreference(SHARED_PREFS_INCOGNITO, false)
|
||||
val liveMessageAlertShown = mkBoolPreference(SHARED_PREFS_LIVE_MESSAGE_ALERT_SHOWN, false)
|
||||
val signMessageAlertShown = mkBoolPreference(SHARED_PREFS_SIGN_MESSAGE_ALERT_SHOWN, false)
|
||||
val showHiddenProfilesNotice = mkBoolPreference(SHARED_PREFS_SHOW_HIDDEN_PROFILES_NOTICE, true)
|
||||
val oneHandUICardShown = mkBoolPreference(SHARED_PREFS_ONE_HAND_UI_CARD_SHOWN, false)
|
||||
val addressCreationCardShown = mkBoolPreference(SHARED_PREFS_ADDRESS_CREATION_CARD_SHOWN, false)
|
||||
@@ -271,6 +272,7 @@ class AppPreferences {
|
||||
hintPref(oneHandUICardShown, false),
|
||||
hintPref(addressCreationCardShown, false),
|
||||
hintPref(liveMessageAlertShown, false),
|
||||
hintPref(signMessageAlertShown, false),
|
||||
hintPref(showHiddenProfilesNotice, true),
|
||||
hintPref(showMuteProfileAlert, true),
|
||||
hintPref(showReportsInSupportChatAlert, true),
|
||||
@@ -454,6 +456,7 @@ class AppPreferences {
|
||||
private const val SHARED_PREFS_NETWORK_TCP_KEEP_CNT = "NetworkTCPKeepCnt"
|
||||
private const val SHARED_PREFS_INCOGNITO = "Incognito"
|
||||
private const val SHARED_PREFS_LIVE_MESSAGE_ALERT_SHOWN = "LiveMessageAlertShown"
|
||||
private const val SHARED_PREFS_SIGN_MESSAGE_ALERT_SHOWN = "SignMessageAlertShown"
|
||||
private const val SHARED_PREFS_SHOW_HIDDEN_PROFILES_NOTICE = "ShowHiddenProfilesNotice"
|
||||
private const val SHARED_PREFS_ONE_HAND_UI_CARD_SHOWN = "OneHandUICardShown"
|
||||
private const val SHARED_PREFS_ADDRESS_CREATION_CARD_SHOWN = "AddressCreationCardShown"
|
||||
|
||||
+14
-11
@@ -115,9 +115,7 @@ data class ComposeState(
|
||||
val useLinkPreviews: Boolean,
|
||||
val mentions: MentionedMembers = emptyMap(),
|
||||
// the max file size the user may attach, raised by their active badge unless the chat is incognito; kept in sync on chat switch
|
||||
val maxFileSize: Long = getMaxFileSize(FileProtocol.XFTP),
|
||||
// per-send opt-in to sign the message (relay channels only); resets on send/chat change, not persisted
|
||||
val sign: Boolean = false
|
||||
val maxFileSize: Long = getMaxFileSize(FileProtocol.XFTP)
|
||||
) {
|
||||
constructor(editingItem: ChatItem, liveMessage: LiveMessage? = null, useLinkPreviews: Boolean): this(
|
||||
ComposeMessage(
|
||||
@@ -544,7 +542,7 @@ fun ComposeView(
|
||||
}
|
||||
}
|
||||
|
||||
suspend fun send(chat: Chat, mc: MsgContent, quoted: Long?, file: CryptoFile? = null, live: Boolean = false, ttl: Int?, mentions: Map<String, Long>): ChatItem? {
|
||||
suspend fun send(chat: Chat, mc: MsgContent, quoted: Long?, file: CryptoFile? = null, live: Boolean = false, ttl: Int?, mentions: Map<String, Long>, sign: Boolean = false): ChatItem? {
|
||||
val cInfo = chat.chatInfo
|
||||
val chatItems = if (chat.chatInfo.chatType == ChatType.Local)
|
||||
chatModel.controller.apiCreateChatItems(
|
||||
@@ -561,7 +559,7 @@ fun ComposeView(
|
||||
sendAsGroup = cInfo.sendAsGroup,
|
||||
live = live,
|
||||
ttl = ttl,
|
||||
sign = composeState.value.sign,
|
||||
sign = sign,
|
||||
composedMessages = listOf(ComposedMessage(file, quoted, mc, mentions))
|
||||
)
|
||||
if (!chatItems.isNullOrEmpty()) {
|
||||
@@ -678,7 +676,7 @@ fun ComposeView(
|
||||
}
|
||||
}
|
||||
|
||||
suspend fun sendMessageAsync(text: String?, live: Boolean, ttl: Int?): List<ChatItem>? {
|
||||
suspend fun sendMessageAsync(text: String?, live: Boolean, ttl: Int?, sign: Boolean = false): List<ChatItem>? {
|
||||
val cs = composeState.value
|
||||
var sent: List<ChatItem>?
|
||||
var lastMessageFailedToSend: ComposeState? = null
|
||||
@@ -803,7 +801,7 @@ fun ComposeView(
|
||||
if (cs.message.text.isNotEmpty()) {
|
||||
sent?.mapIndexed { index, message ->
|
||||
if (index == sent!!.lastIndex) {
|
||||
send(chat, checkLinkPreview(), quoted = message.id, live = false, ttl = ttl, mentions = cs.memberMentions)
|
||||
send(chat, checkLinkPreview(), quoted = message.id, live = false, ttl = ttl, mentions = cs.memberMentions, sign = sign)
|
||||
} else {
|
||||
message
|
||||
}
|
||||
@@ -920,7 +918,8 @@ fun ComposeView(
|
||||
val sendResult = send(chat, content, if (index == 0) quotedItemId else null, file,
|
||||
live = if (content !is MsgContent.MCVoice && index == msgs.lastIndex) live else false,
|
||||
ttl = ttl,
|
||||
mentions = cs.memberMentions
|
||||
mentions = cs.memberMentions,
|
||||
sign = sign
|
||||
)
|
||||
sent = if (sendResult != null) listOf(sendResult) else null
|
||||
if (sent == null && index == msgs.lastIndex && cs.liveMessage == null) {
|
||||
@@ -947,9 +946,9 @@ fun ComposeView(
|
||||
return sent
|
||||
}
|
||||
|
||||
fun sendMessage(ttl: Int?) {
|
||||
fun sendMessage(ttl: Int?, sign: Boolean = false) {
|
||||
withLongRunningApi(slow = 120_000) {
|
||||
sendMessageAsync(null, false, ttl)
|
||||
sendMessageAsync(null, false, ttl, sign)
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1394,13 +1393,17 @@ fun ComposeView(
|
||||
sendButtonColor = sendButtonColor,
|
||||
timedMessageAllowed = timedMessageAllowed,
|
||||
showSign = (chat.chatInfo as? ChatInfo.Group)?.groupInfo?.useRelays == true,
|
||||
sendAsGroup = chat.chatInfo.sendAsGroup,
|
||||
signMessageAlertShown = chatModel.controller.appPrefs.signMessageAlertShown,
|
||||
customDisappearingMessageTimePref = chatModel.controller.appPrefs.customDisappearingMessageTime,
|
||||
placeholder = if (userCantSendReason.value != null) "" else placeholder ?: composeState.value.placeholder,
|
||||
sendMessage = { ttl ->
|
||||
sendMessage(ttl)
|
||||
resetLinkPreview()
|
||||
},
|
||||
sendSignedMessage = {
|
||||
sendMessage(null, sign = true)
|
||||
resetLinkPreview()
|
||||
},
|
||||
sendLiveMessage = if (chat.chatInfo.chatType != ChatType.Local) ::sendLiveMessage else null,
|
||||
updateLiveMessage = ::updateLiveMessage,
|
||||
cancelLiveMessage = {
|
||||
|
||||
+12
-8
@@ -50,10 +50,11 @@ fun SendMsgView(
|
||||
allowVoiceToContact: () -> Unit,
|
||||
timedMessageAllowed: Boolean = false,
|
||||
showSign: Boolean = false,
|
||||
sendAsGroup: Boolean = false,
|
||||
signMessageAlertShown: SharedPreference<Boolean> = SharedPreference(get = { false }, set = {}),
|
||||
customDisappearingMessageTimePref: SharedPreference<Int>? = null,
|
||||
placeholder: String,
|
||||
sendMessage: (Int?) -> Unit,
|
||||
sendSignedMessage: () -> Unit = {},
|
||||
sendLiveMessage: (suspend () -> Unit)? = null,
|
||||
updateLiveMessage: (suspend () -> Unit)? = null,
|
||||
cancelLiveMessage: (() -> Unit)? = null,
|
||||
@@ -212,17 +213,20 @@ fun SendMsgView(
|
||||
if (showSign && !cs.editing) {
|
||||
menuItems.add {
|
||||
ItemAction(
|
||||
generalGetString(if (cs.sign) MR.strings.signing_message else MR.strings.sign_message),
|
||||
generalGetString(MR.strings.sign_message),
|
||||
painterResource(MR.images.ic_verified),
|
||||
onClick = {
|
||||
val nowOn = !composeState.value.sign
|
||||
composeState.value = composeState.value.copy(sign = nowOn)
|
||||
if (nowOn) {
|
||||
if (signMessageAlertShown.state.value) {
|
||||
sendSignedMessage()
|
||||
} else {
|
||||
AlertManager.shared.showAlertDialog(
|
||||
title = generalGetString(MR.strings.sign_message),
|
||||
text = generalGetString(if (sendAsGroup) MR.strings.sign_message_as_channel_desc else MR.strings.sign_message_desc),
|
||||
dismissText = generalGetString(MR.strings.dont_sign_message),
|
||||
onDismiss = { composeState.value = composeState.value.copy(sign = false) }
|
||||
text = generalGetString(MR.strings.sign_message_desc),
|
||||
confirmText = generalGetString(MR.strings.send_verb),
|
||||
onConfirm = {
|
||||
signMessageAlertShown.set(true)
|
||||
sendSignedMessage()
|
||||
}
|
||||
)
|
||||
}
|
||||
showDropdown.value = false
|
||||
|
||||
@@ -755,10 +755,7 @@
|
||||
<string name="send_disappearing_message_custom_time">Custom time</string>
|
||||
<string name="send_disappearing_message_send">Send</string>
|
||||
<string name="sign_message">Sign message</string>
|
||||
<string name="signing_message">Signing message</string>
|
||||
<string name="dont_sign_message">Don\'t sign</string>
|
||||
<string name="sign_message_desc">A signature is transferable, non-repudiable proof that you authored this message — it confirms authorship and integrity, not timing, order, or completeness.</string>
|
||||
<string name="sign_message_as_channel_desc">A signature is transferable, non-repudiable proof that you authored this message — it confirms authorship and integrity, not timing, order, or completeness. Signing a post sent as the channel also reveals you as its author.</string>
|
||||
<string name="sign_message_desc">A signature is transferable, non-repudiable proof that you authored this message.</string>
|
||||
<string name="live_message">Live message!</string>
|
||||
<string name="send_live_message_desc">Send a live message - it will update for the recipient(s) as you type it</string>
|
||||
<string name="send_verb">Send</string>
|
||||
|
||||
Reference in New Issue
Block a user