android: show chat previews & save last draft toggles (#2941)

* android: show chat previews & save last draft toggles

* wip

* Revert "wip"

This reverts commit 01b570913f.

* comment

* add to model

* toggle text and icon

* show draft

---------

Co-authored-by: Evgeny Poberezkin <2769109+epoberezkin@users.noreply.github.com>
This commit is contained in:
spaced4ndy
2023-08-17 18:04:16 +04:00
committed by GitHub
parent faea5e90ac
commit 1d8a370c58
8 changed files with 64 additions and 29 deletions
@@ -80,6 +80,7 @@ object ChatModel {
}
val performLA by lazy { mutableStateOf(ChatController.appPrefs.performLA.get()) }
val showAdvertiseLAUnavailableAlert = mutableStateOf(false)
val showChatPreviews by lazy { mutableStateOf(ChatController.appPrefs.privacyShowChatPreviews.get()) }
// current WebRTC call
val callManager = CallManager(this)
@@ -91,6 +91,8 @@ class AppPreferences {
},
set = fun(mode: SimplexLinkMode) { _simplexLinkMode.set(mode.name) }
)
val privacyShowChatPreviews = mkBoolPreference(SHARED_PREFS_PRIVACY_SHOW_CHAT_PREVIEWS, true)
val privacySaveLastDraft = mkBoolPreference(SHARED_PREFS_PRIVACY_SAVE_LAST_DRAFT, true)
val privacyDeliveryReceiptsSet = mkBoolPreference(SHARED_PREFS_PRIVACY_DELIVERY_RECEIPTS_SET, false)
val experimentalCalls = mkBoolPreference(SHARED_PREFS_EXPERIMENTAL_CALLS, false)
val showUnreadAndFavorites = mkBoolPreference(SHARED_PREFS_SHOW_UNREAD_AND_FAVORITES, false)
@@ -244,6 +246,8 @@ class AppPreferences {
private const val SHARED_PREFS_PRIVACY_TRANSFER_IMAGES_INLINE = "PrivacyTransferImagesInline"
private const val SHARED_PREFS_PRIVACY_LINK_PREVIEWS = "PrivacyLinkPreviews"
private const val SHARED_PREFS_PRIVACY_SIMPLEX_LINK_MODE = "PrivacySimplexLinkMode"
private const val SHARED_PREFS_PRIVACY_SHOW_CHAT_PREVIEWS = "PrivacyShowChatPreviews"
private const val SHARED_PREFS_PRIVACY_SAVE_LAST_DRAFT = "PrivacySaveLastDraft"
private const val SHARED_PREFS_PRIVACY_DELIVERY_RECEIPTS_SET = "PrivacyDeliveryReceiptsSet"
const val SHARED_PREFS_PRIVACY_FULL_BACKUP = "FullBackup"
private const val SHARED_PREFS_EXPERIMENTAL_CALLS = "ExperimentalCalls"
@@ -232,6 +232,7 @@ fun ComposeView(
val pendingLinkUrl = rememberSaveable { mutableStateOf<String?>(null) }
val cancelledLinks = rememberSaveable { mutableSetOf<String>() }
val useLinkPreviews = chatModel.controller.appPrefs.privacyLinkPreviews.get()
val saveLastDraft = chatModel.controller.appPrefs.privacySaveLastDraft.get()
val smallFont = MaterialTheme.typography.body1.copy(color = MaterialTheme.colors.onBackground)
val textStyle = remember(MaterialTheme.colors.isLight) { mutableStateOf(smallFont) }
val recState: MutableState<RecordingState> = remember { mutableStateOf(RecordingState.NotStarted) }
@@ -742,8 +743,10 @@ fun ComposeView(
if (cs.preview is ComposePreview.VoicePreview && !cs.preview.finished) {
composeState.value = cs.copy(preview = cs.preview.copy(finished = true))
}
chatModel.draft.value = composeState.value
chatModel.draftChatId.value = prevChatId
if (saveLastDraft) {
chatModel.draft.value = composeState.value
chatModel.draftChatId.value = prevChatId
}
composeState.value = ComposeState(useLinkPreviews = useLinkPreviews)
} else if (chatModel.draftChatId.value == chatModel.chatId.value && chatModel.draft.value != null) {
composeState.value = chatModel.draft.value ?: ComposeState(useLinkPreviews = useLinkPreviews)
@@ -44,11 +44,12 @@ fun ChatListNavLinkView(chat: Chat, chatModel: ChatModel) {
showMenu.value = false
delay(500L)
}
val showChatPreviews = chatModel.showChatPreviews.value
when (chat.chatInfo) {
is ChatInfo.Direct -> {
val contactNetworkStatus = chatModel.contactNetworkStatus(chat.chatInfo.contact)
ChatListNavLinkLayout(
chatLinkPreview = { ChatPreviewView(chat, chatModel.draft.value, chatModel.draftChatId.value, chatModel.currentUser.value?.profile?.displayName, contactNetworkStatus, stopped, linkMode) },
chatLinkPreview = { ChatPreviewView(chat, showChatPreviews, chatModel.draft.value, chatModel.draftChatId.value, chatModel.currentUser.value?.profile?.displayName, contactNetworkStatus, stopped, linkMode) },
click = { directChatAction(chat.chatInfo, chatModel) },
dropdownMenuItems = { ContactMenuItems(chat, chatModel, showMenu, showMarkRead) },
showMenu,
@@ -57,7 +58,7 @@ fun ChatListNavLinkView(chat: Chat, chatModel: ChatModel) {
}
is ChatInfo.Group ->
ChatListNavLinkLayout(
chatLinkPreview = { ChatPreviewView(chat, chatModel.draft.value, chatModel.draftChatId.value, chatModel.currentUser.value?.profile?.displayName, null, stopped, linkMode) },
chatLinkPreview = { ChatPreviewView(chat, showChatPreviews, chatModel.draft.value, chatModel.draftChatId.value, chatModel.currentUser.value?.profile?.displayName, null, stopped, linkMode) },
click = { groupChatAction(chat.chatInfo.groupInfo, chatModel) },
dropdownMenuItems = { GroupMenuItems(chat, chat.chatInfo.groupInfo, chatModel, showMenu, showMarkRead) },
showMenu,
@@ -668,6 +669,7 @@ fun PreviewChatListNavLinkDirect() {
),
chatStats = Chat.ChatStats()
),
true,
null,
null,
null,
@@ -707,6 +709,7 @@ fun PreviewChatListNavLinkGroup() {
),
chatStats = Chat.ChatStats()
),
true,
null,
null,
null,
@@ -31,6 +31,7 @@ import dev.icerock.moko.resources.ImageResource
@Composable
fun ChatPreviewView(
chat: Chat,
showChatPreviews: Boolean,
chatModelDraft: ComposeState?,
chatModelDraftChatId: ChatId?,
currentUserProfileDisplayName: String?,
@@ -140,32 +141,34 @@ fun ChatPreviewView(
fun chatPreviewText() {
val ci = chat.chatItems.lastOrNull()
if (ci != null) {
val (text: CharSequence, inlineTextContent) = when {
chatModelDraftChatId == chat.id && chatModelDraft != null -> remember(chatModelDraft) { messageDraft(chatModelDraft) }
ci.meta.itemDeleted == null -> ci.text to null
else -> generalGetString(MR.strings.marked_deleted_description) to null
}
val formattedText = when {
chatModelDraftChatId == chat.id && chatModelDraft != null -> null
ci.meta.itemDeleted == null -> ci.formattedText
else -> null
}
MarkdownText(
text,
formattedText,
sender = when {
if (showChatPreviews || (chatModelDraftChatId == chat.id && chatModelDraft != null)) {
val (text: CharSequence, inlineTextContent) = when {
chatModelDraftChatId == chat.id && chatModelDraft != null -> remember(chatModelDraft) { messageDraft(chatModelDraft) }
ci.meta.itemDeleted == null -> ci.text to null
else -> generalGetString(MR.strings.marked_deleted_description) to null
}
val formattedText = when {
chatModelDraftChatId == chat.id && chatModelDraft != null -> null
cInfo is ChatInfo.Group && !ci.chatDir.sent -> ci.memberDisplayName
ci.meta.itemDeleted == null -> ci.formattedText
else -> null
},
linkMode = linkMode,
senderBold = true,
maxLines = 2,
overflow = TextOverflow.Ellipsis,
style = MaterialTheme.typography.body1.copy(color = if (isInDarkTheme()) MessagePreviewDark else MessagePreviewLight, lineHeight = 22.sp),
inlineContent = inlineTextContent,
modifier = Modifier.fillMaxWidth(),
)
}
MarkdownText(
text,
formattedText,
sender = when {
chatModelDraftChatId == chat.id && chatModelDraft != null -> null
cInfo is ChatInfo.Group && !ci.chatDir.sent -> ci.memberDisplayName
else -> null
},
linkMode = linkMode,
senderBold = true,
maxLines = 2,
overflow = TextOverflow.Ellipsis,
style = MaterialTheme.typography.body1.copy(color = if (isInDarkTheme()) MessagePreviewDark else MessagePreviewLight, lineHeight = 22.sp),
inlineContent = inlineTextContent,
modifier = Modifier.fillMaxWidth(),
)
}
} else {
when (cInfo) {
is ChatInfo.Direct ->
@@ -336,6 +339,6 @@ fun unreadCountStr(n: Int): String {
@Composable
fun PreviewChatPreviewView() {
SimpleXTheme {
ChatPreviewView(Chat.sampleData, null, null, "", contactNetworkStatus = NetworkStatus.Connected(), stopped = false, linkMode = SimplexLinkMode.DESCRIPTION)
ChatPreviewView(Chat.sampleData, true, null, null, "", contactNetworkStatus = NetworkStatus.Connected(), stopped = false, linkMode = SimplexLinkMode.DESCRIPTION)
}
}
@@ -66,6 +66,24 @@ fun PrivacySettingsView(
SectionView(stringResource(MR.strings.settings_section_title_chats)) {
SettingsPreferenceItem(painterResource(MR.images.ic_image), stringResource(MR.strings.auto_accept_images), chatModel.controller.appPrefs.privacyAcceptImages)
SettingsPreferenceItem(painterResource(MR.images.ic_travel_explore), stringResource(MR.strings.send_link_previews), chatModel.controller.appPrefs.privacyLinkPreviews)
SettingsPreferenceItem(
painterResource(MR.images.ic_chat_bubble),
stringResource(MR.strings.privacy_show_last_messages),
chatModel.controller.appPrefs.privacyShowChatPreviews,
onChange = { showPreviews ->
chatModel.showChatPreviews.value = showPreviews
}
)
SettingsPreferenceItem(
painterResource(MR.images.ic_edit_note),
stringResource(MR.strings.privacy_message_draft),
chatModel.controller.appPrefs.privacySaveLastDraft,
onChange = { saveDraft ->
if (!saveDraft) {
chatModel.draft.value = null
chatModel.draftChatId.value = null
}
})
SimpleXLinkOptions(chatModel.simplexLinkMode, onSelected = {
simplexLinkMode.set(it)
chatModel.simplexLinkMode.value = it
@@ -852,6 +852,8 @@
<string name="protect_app_screen">Protect app screen</string>
<string name="auto_accept_images">Auto-accept images</string>
<string name="send_link_previews">Send link previews</string>
<string name="privacy_show_last_messages">Show last messages</string>
<string name="privacy_message_draft">Message draft</string>
<string name="full_backup">App data backup</string>
<string name="enable_lock">Enable lock</string>
<string name="lock_mode">Lock mode</string>
@@ -0,0 +1 @@
<svg xmlns="http://www.w3.org/2000/svg" height="24" viewBox="0 -960 960 960" width="24"><path d="M241.776-244.5 134-136.5q-13.5 13.5-31.25 6.359Q85-137.281 85-156.5V-818q0-22.969 17.266-40.234Q119.531-875.5 142.5-875.5h675q22.969 0 40.234 17.266Q875-840.969 875-818v516q0 22.969-17.266 40.234Q840.469-244.5 817.5-244.5H241.776ZM142.5-302h675v-516h-675v516Zm0 0v-516 516Z"/></svg>

After

Width:  |  Height:  |  Size: 379 B