ui: open links from chat list with confirmation (#5519)

* ui: open links from chat list with confirmation

* appSettings

* ios

* core: migrate setting

* ios icon

* android icon

---------

Co-authored-by: Evgeny Poberezkin <evgeny@poberezkin.com>
This commit is contained in:
Stanislav Dmitrenko
2025-01-13 19:46:42 +07:00
committed by GitHub
parent daea3b1056
commit ef72d8e446
11 changed files with 151 additions and 12 deletions
@@ -313,6 +313,7 @@ struct ChatPreviewView: View {
}
@ViewBuilder func chatItemContentPreview(_ chat: Chat, _ ci: ChatItem) -> some View {
let linkClicksEnabled = privacyChatListOpenLinksDefault.get() != PrivacyChatListOpenLinksMode.no
let mc = ci.content.msgContent
switch mc {
case let .link(_, preview):
@@ -334,7 +335,17 @@ struct ChatPreviewView: View {
.cornerRadius(8)
}
.onTapGesture {
UIApplication.shared.open(preview.uri)
switch privacyChatListOpenLinksDefault.get() {
case .yes: UIApplication.shared.open(preview.uri)
case .no: ItemsModel.shared.loadOpenChat(chat.id)
case .ask: AlertManager.shared.showAlert(
Alert(title: Text("Open web link?"),
message: Text(preview.uri.absoluteString),
primaryButton: .default(Text("Open chat"), action: { ItemsModel.shared.loadOpenChat(chat.id) }),
secondaryButton: .default(Text("Open link"), action: { UIApplication.shared.open(preview.uri) })
)
)
}
}
}
case let .image(_, image):
@@ -38,6 +38,7 @@ extension AppSettings {
privacyLinkPreviewsGroupDefault.set(val)
def.setValue(val, forKey: DEFAULT_PRIVACY_LINK_PREVIEWS)
}
if let val = privacyChatListOpenLinks { privacyChatListOpenLinksDefault.set(val) }
if let val = privacyShowChatPreviews { def.setValue(val, forKey: DEFAULT_PRIVACY_SHOW_CHAT_PREVIEWS) }
if let val = privacySaveLastDraft { def.setValue(val, forKey: DEFAULT_PRIVACY_SAVE_LAST_DRAFT) }
if let val = privacyProtectScreen { def.setValue(val, forKey: DEFAULT_PRIVACY_PROTECT_SCREEN) }
@@ -77,6 +78,7 @@ extension AppSettings {
c.privacyAskToApproveRelays = privacyAskToApproveRelaysGroupDefault.get()
c.privacyAcceptImages = privacyAcceptImagesGroupDefault.get()
c.privacyLinkPreviews = def.bool(forKey: DEFAULT_PRIVACY_LINK_PREVIEWS)
c.privacyChatListOpenLinks = privacyChatListOpenLinksDefault.get()
c.privacyShowChatPreviews = def.bool(forKey: DEFAULT_PRIVACY_SHOW_CHAT_PREVIEWS)
c.privacySaveLastDraft = def.bool(forKey: DEFAULT_PRIVACY_SAVE_LAST_DRAFT)
c.privacyProtectScreen = def.bool(forKey: DEFAULT_PRIVACY_PROTECT_SCREEN)
@@ -14,6 +14,7 @@ struct PrivacySettings: View {
@EnvironmentObject var theme: AppTheme
@AppStorage(DEFAULT_PRIVACY_ACCEPT_IMAGES) private var autoAcceptImages = true
@AppStorage(DEFAULT_PRIVACY_LINK_PREVIEWS) private var useLinkPreviews = true
@State private var chatListOpenLinks = privacyChatListOpenLinksDefault.get()
@AppStorage(DEFAULT_PRIVACY_SHOW_CHAT_PREVIEWS) private var showChatPreviews = true
@AppStorage(DEFAULT_PRIVACY_SAVE_LAST_DRAFT) private var saveLastDraft = true
@AppStorage(GROUP_DEFAULT_PRIVACY_ENCRYPT_LOCAL_FILES, store: groupDefaults) private var encryptLocalFiles = true
@@ -74,6 +75,17 @@ struct PrivacySettings: View {
privacyLinkPreviewsGroupDefault.set(linkPreviews)
}
}
settingsRow("arrow.up.right.circle", color: theme.colors.secondary) {
Picker("Open links from chat list", selection: $chatListOpenLinks) {
ForEach(PrivacyChatListOpenLinksMode.allCases) { mode in
Text(mode.text)
}
}
}
.frame(height: 36)
.onChange(of: chatListOpenLinks) { mode in
privacyChatListOpenLinksDefault.set(mode)
}
settingsRow("message", color: theme.colors.secondary) {
Toggle("Show last messages", isOn: $showChatPreviews)
}
@@ -29,6 +29,7 @@ let DEFAULT_WEBRTC_ICE_SERVERS = "webrtcICEServers"
let DEFAULT_CALL_KIT_CALLS_IN_RECENTS = "callKitCallsInRecents"
let DEFAULT_PRIVACY_ACCEPT_IMAGES = "privacyAcceptImages" // unused. Use GROUP_DEFAULT_PRIVACY_ACCEPT_IMAGES instead
let DEFAULT_PRIVACY_LINK_PREVIEWS = "privacyLinkPreviews" // deprecated, moved to app group
let DEFAULT_PRIVACY_CHAT_LIST_OPEN_LINKS = "privacyChatListOpenLinks"
let DEFAULT_PRIVACY_SIMPLEX_LINK_MODE = "privacySimplexLinkMode"
let DEFAULT_PRIVACY_SHOW_CHAT_PREVIEWS = "privacyShowChatPreviews"
let DEFAULT_PRIVACY_SAVE_LAST_DRAFT = "privacySaveLastDraft"
@@ -182,6 +183,8 @@ let connectViaLinkTabDefault = EnumDefault<ConnectViaLinkTab>(defaults: UserDefa
let privacySimplexLinkModeDefault = EnumDefault<SimpleXLinkMode>(defaults: UserDefaults.standard, forKey: DEFAULT_PRIVACY_SIMPLEX_LINK_MODE, withDefault: .description)
let privacyChatListOpenLinksDefault = EnumDefault<PrivacyChatListOpenLinksMode>(defaults: UserDefaults.standard, forKey: DEFAULT_PRIVACY_CHAT_LIST_OPEN_LINKS, withDefault: PrivacyChatListOpenLinksMode.ask)
let privacyLocalAuthModeDefault = EnumDefault<LAMode>(defaults: UserDefaults.standard, forKey: DEFAULT_LA_MODE, withDefault: .system)
let privacyDeliveryReceiptsSet = BoolDefault(defaults: UserDefaults.standard, forKey: DEFAULT_PRIVACY_DELIVERY_RECEIPTS_SET)
+19
View File
@@ -2217,6 +2217,22 @@ public enum NotificationPreviewMode: String, SelectableItem, Codable {
public static var values: [NotificationPreviewMode] = [.message, .contact, .hidden]
}
public enum PrivacyChatListOpenLinksMode: String, CaseIterable, Codable, RawRepresentable, Identifiable {
case yes
case no
case ask
public var id: Self { self }
public var text: LocalizedStringKey {
switch self {
case .yes: return "Yes"
case .no: return "No"
case .ask: return "Ask"
}
}
}
public struct RemoteCtrlInfo: Decodable {
public var remoteCtrlId: Int64
public var ctrlDeviceName: String
@@ -2658,6 +2674,7 @@ public struct AppSettings: Codable, Equatable {
public var privacyAskToApproveRelays: Bool? = nil
public var privacyAcceptImages: Bool? = nil
public var privacyLinkPreviews: Bool? = nil
public var privacyChatListOpenLinks: PrivacyChatListOpenLinksMode? = nil
public var privacyShowChatPreviews: Bool? = nil
public var privacySaveLastDraft: Bool? = nil
public var privacyProtectScreen: Bool? = nil
@@ -2693,6 +2710,7 @@ public struct AppSettings: Codable, Equatable {
if privacyAskToApproveRelays != def.privacyAskToApproveRelays { empty.privacyAskToApproveRelays = privacyAskToApproveRelays }
if privacyAcceptImages != def.privacyAcceptImages { empty.privacyAcceptImages = privacyAcceptImages }
if privacyLinkPreviews != def.privacyLinkPreviews { empty.privacyLinkPreviews = privacyLinkPreviews }
if privacyChatListOpenLinks != def.privacyChatListOpenLinks { empty.privacyChatListOpenLinks = privacyChatListOpenLinks }
if privacyShowChatPreviews != def.privacyShowChatPreviews { empty.privacyShowChatPreviews = privacyShowChatPreviews }
if privacySaveLastDraft != def.privacySaveLastDraft { empty.privacySaveLastDraft = privacySaveLastDraft }
if privacyProtectScreen != def.privacyProtectScreen { empty.privacyProtectScreen = privacyProtectScreen }
@@ -2729,6 +2747,7 @@ public struct AppSettings: Codable, Equatable {
privacyAskToApproveRelays: true,
privacyAcceptImages: true,
privacyLinkPreviews: true,
privacyChatListOpenLinks: .ask,
privacyShowChatPreviews: true,
privacySaveLastDraft: true,
privacyProtectScreen: false,
@@ -105,6 +105,7 @@ class AppPreferences {
val privacyProtectScreen = mkBoolPreference(SHARED_PREFS_PRIVACY_PROTECT_SCREEN, true)
val privacyAcceptImages = mkBoolPreference(SHARED_PREFS_PRIVACY_ACCEPT_IMAGES, true)
val privacyLinkPreviews = mkBoolPreference(SHARED_PREFS_PRIVACY_LINK_PREVIEWS, true)
val privacyChatListOpenLinks = mkEnumPreference(SHARED_PREFS_PRIVACY_CHAT_LIST_OPEN_LINKS, PrivacyChatListOpenLinksMode.ASK) { PrivacyChatListOpenLinksMode.values().firstOrNull { it.name == this } }
private val _simplexLinkMode = mkStrPreference(SHARED_PREFS_PRIVACY_SIMPLEX_LINK_MODE, SimplexLinkMode.default.name)
val simplexLinkMode: SharedPreference<SimplexLinkMode> = SharedPreference(
get = fun(): SimplexLinkMode {
@@ -373,6 +374,7 @@ class AppPreferences {
private const val SHARED_PREFS_PRIVACY_ACCEPT_IMAGES = "PrivacyAcceptImages"
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_CHAT_LIST_OPEN_LINKS = "ChatListOpenLinks"
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"
@@ -7071,6 +7073,13 @@ enum class NotificationsMode() {
}
}
@Serializable
enum class PrivacyChatListOpenLinksMode {
@SerialName("yes") YES,
@SerialName("no") NO,
@SerialName("ask") ASK
}
@Serializable
data class AppSettings(
var networkConfig: NetCfg? = null,
@@ -7079,6 +7088,7 @@ data class AppSettings(
var privacyAskToApproveRelays: Boolean? = null,
var privacyAcceptImages: Boolean? = null,
var privacyLinkPreviews: Boolean? = null,
var privacyChatListOpenLinks: PrivacyChatListOpenLinksMode? = null,
var privacyShowChatPreviews: Boolean? = null,
var privacySaveLastDraft: Boolean? = null,
var privacyProtectScreen: Boolean? = null,
@@ -7114,6 +7124,7 @@ data class AppSettings(
if (privacyAskToApproveRelays != def.privacyAskToApproveRelays) { empty.privacyAskToApproveRelays = privacyAskToApproveRelays }
if (privacyAcceptImages != def.privacyAcceptImages) { empty.privacyAcceptImages = privacyAcceptImages }
if (privacyLinkPreviews != def.privacyLinkPreviews) { empty.privacyLinkPreviews = privacyLinkPreviews }
if (privacyChatListOpenLinks != def.privacyChatListOpenLinks) { empty.privacyChatListOpenLinks = privacyChatListOpenLinks }
if (privacyShowChatPreviews != def.privacyShowChatPreviews) { empty.privacyShowChatPreviews = privacyShowChatPreviews }
if (privacySaveLastDraft != def.privacySaveLastDraft) { empty.privacySaveLastDraft = privacySaveLastDraft }
if (privacyProtectScreen != def.privacyProtectScreen) { empty.privacyProtectScreen = privacyProtectScreen }
@@ -7160,6 +7171,7 @@ data class AppSettings(
privacyAskToApproveRelays?.let { def.privacyAskToApproveRelays.set(it) }
privacyAcceptImages?.let { def.privacyAcceptImages.set(it) }
privacyLinkPreviews?.let { def.privacyLinkPreviews.set(it) }
privacyChatListOpenLinks?.let { def.privacyChatListOpenLinks.set(it) }
privacyShowChatPreviews?.let { def.privacyShowChatPreviews.set(it) }
privacySaveLastDraft?.let { def.privacySaveLastDraft.set(it) }
privacyProtectScreen?.let { def.privacyProtectScreen.set(it) }
@@ -7196,6 +7208,7 @@ data class AppSettings(
privacyAskToApproveRelays = true,
privacyAcceptImages = true,
privacyLinkPreviews = true,
privacyChatListOpenLinks = PrivacyChatListOpenLinksMode.ASK,
privacyShowChatPreviews = true,
privacySaveLastDraft = true,
privacyProtectScreen = false,
@@ -7233,6 +7246,7 @@ data class AppSettings(
privacyAskToApproveRelays = def.privacyAskToApproveRelays.get(),
privacyAcceptImages = def.privacyAcceptImages.get(),
privacyLinkPreviews = def.privacyLinkPreviews.get(),
privacyChatListOpenLinks = def.privacyChatListOpenLinks.get(),
privacyShowChatPreviews = def.privacyShowChatPreviews.get(),
privacySaveLastDraft = def.privacySaveLastDraft.get(),
privacyProtectScreen = def.privacyProtectScreen.get(),
@@ -64,13 +64,14 @@ fun ChatListNavLinkView(chat: Chat, nextChatSelected: State<Boolean>) {
when (chat.chatInfo) {
is ChatInfo.Direct -> {
val contactNetworkStatus = chatModel.contactNetworkStatus(chat.chatInfo.contact)
val defaultClickAction = { if (chatModel.chatId.value != chat.id) scope.launch { directChatAction(chat.remoteHostId, chat.chatInfo.contact, chatModel) } }
ChatListNavLinkLayout(
chatLinkPreview = {
tryOrShowError("${chat.id}ChatListNavLink", error = { ErrorChatListItem() }) {
ChatPreviewView(chat, showChatPreviews, chatModel.draft.value, chatModel.draftChatId.value, chatModel.currentUser.value?.profile?.displayName, contactNetworkStatus, disabled, linkMode, inProgress = false, progressByTimeout = false)
ChatPreviewView(chat, showChatPreviews, chatModel.draft.value, chatModel.draftChatId.value, chatModel.currentUser.value?.profile?.displayName, contactNetworkStatus, disabled, linkMode, inProgress = false, progressByTimeout = false, defaultClickAction)
}
},
click = { if (chatModel.chatId.value != chat.id) scope.launch { directChatAction(chat.remoteHostId, chat.chatInfo.contact, chatModel) } },
click = defaultClickAction,
dropdownMenuItems = {
tryOrShowError("${chat.id}ChatListNavLinkDropdown", error = {}) {
ContactMenuItems(chat, chat.chatInfo.contact, chatModel, showMenu, showMarkRead)
@@ -82,14 +83,15 @@ fun ChatListNavLinkView(chat: Chat, nextChatSelected: State<Boolean>) {
nextChatSelected,
)
}
is ChatInfo.Group ->
is ChatInfo.Group -> {
val defaultClickAction = { if (!inProgress.value && chatModel.chatId.value != chat.id) scope.launch { groupChatAction(chat.remoteHostId, chat.chatInfo.groupInfo, chatModel, inProgress) } }
ChatListNavLinkLayout(
chatLinkPreview = {
tryOrShowError("${chat.id}ChatListNavLink", error = { ErrorChatListItem() }) {
ChatPreviewView(chat, showChatPreviews, chatModel.draft.value, chatModel.draftChatId.value, chatModel.currentUser.value?.profile?.displayName, null, disabled, linkMode, inProgress.value, progressByTimeout)
ChatPreviewView(chat, showChatPreviews, chatModel.draft.value, chatModel.draftChatId.value, chatModel.currentUser.value?.profile?.displayName, null, disabled, linkMode, inProgress.value, progressByTimeout, defaultClickAction)
}
},
click = { if (!inProgress.value && chatModel.chatId.value != chat.id) scope.launch { groupChatAction(chat.remoteHostId, chat.chatInfo.groupInfo, chatModel, inProgress) } },
click = defaultClickAction,
dropdownMenuItems = {
tryOrShowError("${chat.id}ChatListNavLinkDropdown", error = {}) {
GroupMenuItems(chat, chat.chatInfo.groupInfo, chatModel, showMenu, inProgress, showMarkRead)
@@ -100,11 +102,12 @@ fun ChatListNavLinkView(chat: Chat, nextChatSelected: State<Boolean>) {
selectedChat,
nextChatSelected,
)
}
is ChatInfo.Local -> {
ChatListNavLinkLayout(
chatLinkPreview = {
tryOrShowError("${chat.id}ChatListNavLink", error = { ErrorChatListItem() }) {
ChatPreviewView(chat, showChatPreviews, chatModel.draft.value, chatModel.draftChatId.value, chatModel.currentUser.value?.profile?.displayName, null, disabled, linkMode, inProgress = false, progressByTimeout = false)
ChatPreviewView(chat, showChatPreviews, chatModel.draft.value, chatModel.draftChatId.value, chatModel.currentUser.value?.profile?.displayName, null, disabled, linkMode, inProgress = false, progressByTimeout = false, {})
}
},
click = { if (chatModel.chatId.value != chat.id) scope.launch { noteFolderChatAction(chat.remoteHostId, chat.chatInfo.noteFolder) } },
@@ -925,7 +928,8 @@ fun PreviewChatListNavLinkDirect() {
disabled = false,
linkMode = SimplexLinkMode.DESCRIPTION,
inProgress = false,
progressByTimeout = false
progressByTimeout = false,
{}
)
},
click = {},
@@ -970,7 +974,8 @@ fun PreviewChatListNavLinkGroup() {
disabled = false,
linkMode = SimplexLinkMode.DESCRIPTION,
inProgress = false,
progressByTimeout = false
progressByTimeout = false,
{}
)
},
click = {},
@@ -1,5 +1,6 @@
package chat.simplex.common.views.chatlist
import SectionItemView
import androidx.compose.foundation.layout.*
import androidx.compose.foundation.shape.CircleShape
import androidx.compose.foundation.text.InlineTextContent
@@ -27,6 +28,7 @@ import androidx.compose.ui.unit.*
import chat.simplex.common.ui.theme.*
import chat.simplex.common.views.helpers.*
import chat.simplex.common.model.*
import chat.simplex.common.model.ChatController.appPrefs
import chat.simplex.common.model.GroupInfo
import chat.simplex.common.platform.*
import chat.simplex.common.views.chat.*
@@ -45,7 +47,8 @@ fun ChatPreviewView(
disabled: Boolean,
linkMode: SimplexLinkMode,
inProgress: Boolean,
progressByTimeout: Boolean
progressByTimeout: Boolean,
defaultClickAction: () -> Unit
) {
val cInfo = chat.chatInfo
@@ -248,7 +251,38 @@ fun ChatPreviewView(
val uriHandler = LocalUriHandler.current
when (mc) {
is MsgContent.MCLink -> SmallContentPreview {
IconButton({ uriHandler.openUriCatching(mc.preview.uri) }, Modifier.desktopPointerHoverIconHand()) {
val linkClicksEnabled = remember { appPrefs.privacyChatListOpenLinks.state }.value != PrivacyChatListOpenLinksMode.NO
IconButton({
when (appPrefs.privacyChatListOpenLinks.get()) {
PrivacyChatListOpenLinksMode.YES -> uriHandler.openUriCatching(mc.preview.uri)
PrivacyChatListOpenLinksMode.NO -> defaultClickAction()
PrivacyChatListOpenLinksMode.ASK -> AlertManager.shared.showAlertDialogButtonsColumn(
title = generalGetString(MR.strings.privacy_chat_list_open_web_link_question),
text = mc.preview.uri,
buttons = {
Column {
if (chatModel.chatId.value != chat.id) {
SectionItemView({
AlertManager.shared.hideAlert()
defaultClickAction()
}) {
Text(stringResource(MR.strings.open_chat), Modifier.fillMaxWidth(), textAlign = TextAlign.Center, color = MaterialTheme.colors.primary)
}
}
SectionItemView({
AlertManager.shared.hideAlert()
uriHandler.openUriCatching(mc.preview.uri)
}
) {
Text(stringResource(MR.strings.privacy_chat_list_open_web_link), Modifier.fillMaxWidth(), textAlign = TextAlign.Center, color = MaterialTheme.colors.primary)
}
}
}
)
}
},
if (linkClicksEnabled) Modifier.desktopPointerHoverIconHand() else Modifier,
) {
Image(base64ToBitmap(mc.preview.image), null, contentScale = ContentScale.Crop)
}
Box(Modifier.align(Alignment.TopEnd).size(15.sp.toDp()).background(Color.Black.copy(0.25f), CircleShape), contentAlignment = Alignment.Center) {
@@ -527,6 +561,6 @@ private data class ActiveVoicePreview(
@Composable
fun PreviewChatPreviewView() {
SimpleXTheme {
ChatPreviewView(Chat.sampleData, true, null, null, "", contactNetworkStatus = NetworkStatus.Connected(), disabled = false, linkMode = SimplexLinkMode.DESCRIPTION, inProgress = false, progressByTimeout = false)
ChatPreviewView(Chat.sampleData, true, null, null, "", contactNetworkStatus = NetworkStatus.Connected(), disabled = false, linkMode = SimplexLinkMode.DESCRIPTION, inProgress = false, progressByTimeout = false, {})
}
}
@@ -63,6 +63,9 @@ fun PrivacySettingsView(
SectionView(stringResource(MR.strings.settings_section_title_chats)) {
SettingsPreferenceItem(painterResource(MR.images.ic_travel_explore), stringResource(MR.strings.send_link_previews), chatModel.controller.appPrefs.privacyLinkPreviews)
ChatListLinksOptions(appPrefs.privacyChatListOpenLinks.state, onSelected = {
appPrefs.privacyChatListOpenLinks.set(it)
})
SettingsPreferenceItem(
painterResource(MR.images.ic_chat_bubble),
stringResource(MR.strings.privacy_show_last_messages),
@@ -199,6 +202,26 @@ fun PrivacySettingsView(
}
}
@Composable
private fun ChatListLinksOptions(state: State<PrivacyChatListOpenLinksMode>, onSelected: (PrivacyChatListOpenLinksMode) -> Unit) {
val values = remember {
PrivacyChatListOpenLinksMode.entries.map {
when (it) {
PrivacyChatListOpenLinksMode.YES -> it to generalGetString(MR.strings.privacy_chat_list_open_links_yes)
PrivacyChatListOpenLinksMode.NO -> it to generalGetString(MR.strings.privacy_chat_list_open_links_no)
PrivacyChatListOpenLinksMode.ASK -> it to generalGetString(MR.strings.privacy_chat_list_open_links_ask)
}
}
}
ExposedDropDownSettingRow(
generalGetString(MR.strings.privacy_chat_list_open_links),
values,
state,
icon = painterResource(MR.images.ic_open_in_new),
onSelected = onSelected
)
}
@Composable
private fun SimpleXLinkOptions(simplexLinkModeState: State<SimplexLinkMode>, onSelected: (SimplexLinkMode) -> Unit) {
val modeValues = listOf(SimplexLinkMode.DESCRIPTION, SimplexLinkMode.FULL)
@@ -1307,6 +1307,12 @@
<string name="privacy_media_blur_radius_soft">Soft</string>
<string name="privacy_media_blur_radius_medium">Medium</string>
<string name="privacy_media_blur_radius_strong">Strong</string>
<string name="privacy_chat_list_open_links">Open links from chat list</string>
<string name="privacy_chat_list_open_links_yes">Yes</string>
<string name="privacy_chat_list_open_links_no">No</string>
<string name="privacy_chat_list_open_links_ask">Ask</string>
<string name="privacy_chat_list_open_web_link_question">Open web link?</string>
<string name="privacy_chat_list_open_web_link">Open link</string>
<!-- Settings sections -->
<string name="settings_section_title_you">YOU</string>
+10
View File
@@ -25,6 +25,8 @@ data NotificationPreviewMode = NPMHidden | NPMContact | NPMMessage deriving (Sho
data LockScreenCalls = LSCDisable | LSCShow | LSCAccept deriving (Show)
data OpenLinksSetting = OLSYes | OLSNo | OLSAsk deriving (Show)
data AppSettings = AppSettings
{ appPlatform :: Maybe AppPlatform,
networkConfig :: Maybe NetworkConfig,
@@ -33,6 +35,7 @@ data AppSettings = AppSettings
privacyAskToApproveRelays :: Maybe Bool,
privacyAcceptImages :: Maybe Bool,
privacyLinkPreviews :: Maybe Bool,
privacyChatListOpenLinks :: Maybe OpenLinksSetting,
privacyShowChatPreviews :: Maybe Bool,
privacySaveLastDraft :: Maybe Bool,
privacyProtectScreen :: Maybe Bool,
@@ -83,6 +86,7 @@ defaultAppSettings =
privacyAskToApproveRelays = Just True,
privacyAcceptImages = Just True,
privacyLinkPreviews = Just True,
privacyChatListOpenLinks = Just OLSAsk,
privacyShowChatPreviews = Just True,
privacySaveLastDraft = Just True,
privacyProtectScreen = Just False,
@@ -120,6 +124,7 @@ defaultParseAppSettings =
privacyAskToApproveRelays = Nothing,
privacyAcceptImages = Nothing,
privacyLinkPreviews = Nothing,
privacyChatListOpenLinks = Nothing,
privacyShowChatPreviews = Nothing,
privacySaveLastDraft = Nothing,
privacyProtectScreen = Nothing,
@@ -157,6 +162,7 @@ combineAppSettings platformDefaults storedSettings =
privacyAskToApproveRelays = p privacyAskToApproveRelays,
privacyAcceptImages = p privacyAcceptImages,
privacyLinkPreviews = p privacyLinkPreviews,
privacyChatListOpenLinks = p privacyChatListOpenLinks,
privacyShowChatPreviews = p privacyShowChatPreviews,
privacySaveLastDraft = p privacySaveLastDraft,
privacyProtectScreen = p privacyProtectScreen,
@@ -197,6 +203,8 @@ $(JQ.deriveJSON (enumJSON $ dropPrefix "LSC") ''LockScreenCalls)
$(JQ.deriveJSON (enumJSON $ dropPrefix "NPA") ''NetworkProxyAuth)
$(JQ.deriveJSON (enumJSON $ dropPrefix "OLS") ''OpenLinksSetting)
$(JQ.deriveJSON defaultJSON ''NetworkProxy)
$(JQ.deriveToJSON defaultJSON ''AppSettings)
@@ -210,6 +218,7 @@ instance FromJSON AppSettings where
privacyAskToApproveRelays <- p "privacyAskToApproveRelays"
privacyAcceptImages <- p "privacyAcceptImages"
privacyLinkPreviews <- p "privacyLinkPreviews"
privacyChatListOpenLinks <- p "privacyChatListOpenLinks"
privacyShowChatPreviews <- p "privacyShowChatPreviews"
privacySaveLastDraft <- p "privacySaveLastDraft"
privacyProtectScreen <- p "privacyProtectScreen"
@@ -244,6 +253,7 @@ instance FromJSON AppSettings where
privacyAskToApproveRelays,
privacyAcceptImages,
privacyLinkPreviews,
privacyChatListOpenLinks,
privacyShowChatPreviews,
privacySaveLastDraft,
privacyProtectScreen,