From 22ce35cf9c8a8a55b0114e27fd503cdd3f2c24de Mon Sep 17 00:00:00 2001 From: Igor Sirotin Date: Mon, 16 Oct 2023 17:05:55 +0100 Subject: [PATCH] feature: support url unfurling settings (#12441) --- .../local_account_sensitive_settings.nim | 16 +++- .../chat_content/input_area/controller.nim | 39 ++++----- .../chat_content/input_area/module.nim | 6 +- .../main/chat_section/chat_content/module.nim | 2 +- .../profile_section/privacy/controller.nim | 12 ++- .../profile_section/privacy/io_interface.nim | 8 +- .../main/profile_section/privacy/module.nim | 8 +- .../main/profile_section/privacy/view.nim | 17 +++- src/app_service/service/accounts/service.nim | 3 +- .../service/settings/dto/settings.nim | 18 +++++ src/app_service/service/settings/service.nim | 20 ++++- ui/app/AppLayouts/Chat/stores/RootStore.qml | 2 + .../AppLayouts/Chat/views/ChatColumnView.qml | 12 ++- .../Profile/views/MessagingView.qml | 79 +++++++++++++++++++ ui/imports/shared/views/chat/MessageView.qml | 7 +- ui/imports/utils/Constants.qml | 6 ++ vendor/status-go | 2 +- 17 files changed, 222 insertions(+), 35 deletions(-) diff --git a/src/app/global/local_account_sensitive_settings.nim b/src/app/global/local_account_sensitive_settings.nim index 400b35b756..56748edf5f 100644 --- a/src/app/global/local_account_sensitive_settings.nim +++ b/src/app/global/local_account_sensitive_settings.nim @@ -92,7 +92,8 @@ const DEFAULT_STICKERS_ENS_ROPSTEN = false const LSS_KEY_USER_DECLINED_BACKUP_BANNER* = "userDeclinedBackupBanner" const DEFAULT_USER_DECLINED_BACKUP_BANNER = false const DEFAULT_IS_DISCORD_IMPORT_TOOL_ENABLED = false - +const LSS_KEY_GIF_UNFURLING_ENABLED* = "gifUnfurlingEnabled" +const DEFAULT_GIF_UNFURLING_ENABLED* = false logScope: topics = "la-sensitive-settings" @@ -727,6 +728,18 @@ QtObject: write = setUserDeclinedBackupBanner notify = userDeclinedBackupBannerChanged + proc gifUnfurlingEnabledChanged*(self: LocalAccountSensitiveSettings) {.signal.} + proc getGifUnfurlingEnabled*(self: LocalAccountSensitiveSettings): bool {.slot.} = + getSettingsProp[bool](self, LSS_KEY_GIF_UNFURLING_ENABLED, newQVariant(DEFAULT_GIF_UNFURLING_ENABLED)) + proc setGifUnfurlingEnabled*(self: LocalAccountSensitiveSettings, value: bool) {.slot.} = + setSettingsProp(self, LSS_KEY_GIF_UNFURLING_ENABLED, newQVariant(value)): + self.gifUnfurlingEnabledChanged() + + QtProperty[bool] gifUnfurlingEnabled: + read = getGifUnfurlingEnabled + write = setGifUnfurlingEnabled + notify = gifUnfurlingEnabledChanged + proc removeKey*(self: LocalAccountSensitiveSettings, key: string) = if(self.settings.isNil): return @@ -776,3 +789,4 @@ QtObject: of LSS_KEY_COMPATIBILITY_MODE: self.compatibilityModeChanged() of LSS_KEY_STICKERS_ENS_ROPSTEN: self.stickersEnsRopstenChanged() of LSS_KEY_USER_DECLINED_BACKUP_BANNER: self.userDeclinedBackupBannerChanged() + of LSS_KEY_GIF_UNFURLING_ENABLED: self.gifUnfurlingEnabledChanged() diff --git a/src/app/modules/main/chat_section/chat_content/input_area/controller.nim b/src/app/modules/main/chat_section/chat_content/input_area/controller.nim index 73d2d809fe..39bb8aa724 100644 --- a/src/app/modules/main/chat_section/chat_content/input_area/controller.nim +++ b/src/app/modules/main/chat_section/chat_content/input_area/controller.nim @@ -1,21 +1,18 @@ import io_interface, chronicles, tables, sequtils + +import ../../../../../../app_service/service/settings/service as settings_service import ../../../../../../app_service/service/message/service as message_service import ../../../../../../app_service/service/community/service as community_service import ../../../../../../app_service/service/chat/service as chat_service import ../../../../../../app_service/service/gif/service as gif_service import ../../../../../../app_service/service/gif/dto import ../../../../../../app_service/service/message/dto/link_preview +import ../../../../../../app_service/service/settings/dto/settings import ../../../../../core/eventemitter import ../../../../../core/unique_event_emitter import ./link_preview_cache -type - LinkPreviewSetting* {.pure.} = enum - AlwaysAsk - Enabled - Disabled - type Controller* = ref object of RootObj delegate: io_interface.AccessInterface @@ -27,9 +24,10 @@ type chatService: chat_service.Service gifService: gif_service.Service messageService: message_service.Service + settingsService: settings_service.Service linkPreviewCache: LinkPreviewCache - linkPreviewPersistentSetting: LinkPreviewSetting - linkPreviewCurrentMessageSetting: LinkPreviewSetting + linkPreviewPersistentSetting: UrlUnfurlingMode + linkPreviewCurrentMessageSetting: UrlUnfurlingMode proc newController*( delegate: io_interface.AccessInterface, @@ -40,7 +38,8 @@ proc newController*( chatService: chat_service.Service, communityService: community_service.Service, gifService: gif_service.Service, - messageService: message_service.Service + messageService: message_service.Service, + settingsService: settings_service.Service ): Controller = result = Controller() result.delegate = delegate @@ -52,11 +51,13 @@ proc newController*( result.communityService = communityService result.gifService = gifService result.messageService = messageService + result.settingsService = settingsService result.linkPreviewCache = newLinkPreiewCache() - result.linkPreviewPersistentSetting = LinkPreviewSetting.AlwaysAsk - result.linkPreviewCurrentMessageSetting = LinkPreviewSetting.AlwaysAsk + result.linkPreviewPersistentSetting = UrlUnfurlingMode.AlwaysAsk + result.linkPreviewCurrentMessageSetting = UrlUnfurlingMode.AlwaysAsk proc onUrlsUnfurled(self: Controller, args: LinkPreviewV2DataArgs) +proc clearLinkPreviewCache*(self: Controller) proc delete*(self: Controller) = self.events.disconnect() @@ -101,13 +102,13 @@ proc belongsToCommunity*(self: Controller): bool = return self.belongsToCommunity proc setLinkPreviewEnabledForThisMessage*(self: Controller, enabled: bool) = - self.linkPreviewCurrentMessageSetting = if enabled: LinkPreviewSetting.Enabled else: LinkPreviewSetting.Disabled + self.linkPreviewCurrentMessageSetting = if enabled: UrlUnfurlingMode.Enabled else: UrlUnfurlingMode.Disabled self.delegate.setAskToEnableLinkPreview(false) proc resetLinkPreviews(self: Controller) = self.delegate.setUrls(@[]) self.linkPreviewCache.clear() - self.linkPreviewCurrentMessageSetting = LinkPreviewSetting.AlwaysAsk + self.linkPreviewCurrentMessageSetting = UrlUnfurlingMode.AlwaysAsk self.delegate.setAskToEnableLinkPreview(false) proc sendImages*(self: Controller, @@ -187,10 +188,10 @@ proc isFavorite*(self: Controller, item: GifDto): bool = return self.gifService.isFavorite(item) proc getLinkPreviewEnabled*(self: Controller): bool = - return self.linkPreviewPersistentSetting == LinkPreviewSetting.Enabled or self.linkPreviewCurrentMessageSetting == LinkPreviewSetting.Enabled + return self.linkPreviewPersistentSetting == UrlUnfurlingMode.Enabled or self.linkPreviewCurrentMessageSetting == UrlUnfurlingMode.Enabled proc canAskToEnableLinkPreview(self: Controller): bool = - return self.linkPreviewPersistentSetting == LinkPreviewSetting.AlwaysAsk and self.linkPreviewCurrentMessageSetting == LinkPreviewSetting.AlwaysAsk + return self.linkPreviewPersistentSetting == UrlUnfurlingMode.AlwaysAsk and self.linkPreviewCurrentMessageSetting == UrlUnfurlingMode.AlwaysAsk proc setText*(self: Controller, text: string, unfurlNewUrls: bool) = if text == "": @@ -229,10 +230,10 @@ proc loadLinkPreviews*(self: Controller, urls: seq[string]) = proc setLinkPreviewEnabled*(self: Controller, enabled: bool) = if(enabled): - self.linkPreviewPersistentSetting = LinkPreviewSetting.Enabled - self.linkPreviewCurrentMessageSetting = LinkPreviewSetting.Enabled + self.linkPreviewPersistentSetting = UrlUnfurlingMode.Enabled + self.linkPreviewCurrentMessageSetting = UrlUnfurlingMode.Enabled else: - self.linkPreviewPersistentSetting = LinkPreviewSetting.Disabled - self.linkPreviewCurrentMessageSetting = LinkPreviewSetting.Disabled + self.linkPreviewPersistentSetting = UrlUnfurlingMode.Disabled + self.linkPreviewCurrentMessageSetting = UrlUnfurlingMode.Disabled self.delegate.setAskToEnableLinkPreview(false) diff --git a/src/app/modules/main/chat_section/chat_content/input_area/module.nim b/src/app/modules/main/chat_section/chat_content/input_area/module.nim index b0f1ecd620..71147dcd4f 100644 --- a/src/app/modules/main/chat_section/chat_content/input_area/module.nim +++ b/src/app/modules/main/chat_section/chat_content/input_area/module.nim @@ -5,6 +5,7 @@ import view, controller import ../../../../../global/global_singleton import ../../../../../core/eventemitter +import ../../../../../../app_service/service/settings/service as settings_service import ../../../../../../app_service/service/message/service as message_service import ../../../../../../app_service/service/message/dto/link_preview import ../../../../../../app_service/service/chat/service as chat_service @@ -31,14 +32,15 @@ proc newModule*( chatService: chat_service.Service, communityService: community_service.Service, gifService: gif_service.Service, - messageService: message_service.Service + messageService: message_service.Service, + settingsService: settings_service.Service ): Module = result = Module() result.delegate = delegate result.view = view.newView(result) result.viewVariant = newQVariant(result.view) - result.controller = controller.newController(result, events, sectionId, chatId, belongsToCommunity, chatService, communityService, gifService, messageService) + result.controller = controller.newController(result, events, sectionId, chatId, belongsToCommunity, chatService, communityService, gifService, messageService, settingsService) result.moduleLoaded = false method delete*(self: Module) = diff --git a/src/app/modules/main/chat_section/chat_content/module.nim b/src/app/modules/main/chat_section/chat_content/module.nim index e4395da504..8780685846 100644 --- a/src/app/modules/main/chat_section/chat_content/module.nim +++ b/src/app/modules/main/chat_section/chat_content/module.nim @@ -56,7 +56,7 @@ proc newModule*(delegate: delegate_interface.AccessInterface, events: EventEmitt result.moduleLoaded = false result.inputAreaModule = input_area_module.newModule(result, events, sectionId, chatId, belongsToCommunity, - chatService, communityService, gifService, messageService) + chatService, communityService, gifService, messageService, settingsService) result.messagesModule = messages_module.newModule(result, events, sectionId, chatId, belongsToCommunity, contactService, communityService, chatService, messageService, mailserversService) result.usersModule = users_module.newModule(events, sectionId, chatId, belongsToCommunity, diff --git a/src/app/modules/main/profile_section/privacy/controller.nim b/src/app/modules/main/profile_section/privacy/controller.nim index 80d7c8bef0..8bff4747b5 100644 --- a/src/app/modules/main/profile_section/privacy/controller.nim +++ b/src/app/modules/main/profile_section/privacy/controller.nim @@ -1,5 +1,5 @@ import io_interface -import uuids +import uuids, chronicles import ../../../../../constants as main_constants import ../../../../global/global_singleton @@ -94,6 +94,14 @@ proc getMessagesFromContactsOnly*(self: Controller): bool = proc setMessagesFromContactsOnly*(self: Controller, value: bool): bool = return self.settingsService.saveMessagesFromContactsOnly(value) +method urlUnfurlingMode*(self: Controller): int {.base.} = + return int(self.settingsService.urlUnfurlingMode()) + +method setUrlUnfurlingMode*(self: Controller, value: int) {.base.} = + let mode = toUrlUnfurlingMode(value) + if not self.settingsService.saveUrlUnfurlingMode(mode): + error "failed to save url unfurling mode setting", value + proc validatePassword*(self: Controller, password: string): bool = return self.privacyService.validatePassword(password) @@ -129,4 +137,4 @@ proc authenticateLoggedInUser*(self: Controller) = self.events.emit(SIGNAL_SHARED_KEYCARD_MODULE_AUTHENTICATE_USER, data) proc backupData*(self: Controller): int64 = - return self.generalService.backupData() \ No newline at end of file + return self.generalService.backupData() diff --git a/src/app/modules/main/profile_section/privacy/io_interface.nim b/src/app/modules/main/profile_section/privacy/io_interface.nim index f9ed889f7c..c96cdd4588 100644 --- a/src/app/modules/main/profile_section/privacy/io_interface.nim +++ b/src/app/modules/main/profile_section/privacy/io_interface.nim @@ -53,6 +53,12 @@ method getMessagesFromContactsOnly*(self: AccessInterface): bool {.base.} = method setMessagesFromContactsOnly*(self: AccessInterface, value: bool) {.base.} = raise newException(ValueError, "No implementation available") +method urlUnfurlingMode*(self: AccessInterface): int {.base.} = + raise newException(ValueError, "No implementation available") + +method setUrlUnfurlingMode*(self: AccessInterface, value: int) {.base.} = + raise newException(ValueError, "No implementation available") + method validatePassword*(self: AccessInterface, password: string): bool {.base.} = raise newException(ValueError, "No implementation available") @@ -75,4 +81,4 @@ method onUserAuthenticated*(self: AccessInterface, pin: string, password: string raise newException(ValueError, "No implementation available") method backupData*(self: AccessInterface): int64 {.base.} = - raise newException(ValueError, "No implementation available") \ No newline at end of file + raise newException(ValueError, "No implementation available") diff --git a/src/app/modules/main/profile_section/privacy/module.nim b/src/app/modules/main/profile_section/privacy/module.nim index 4e3b53bfdd..eaef892acb 100644 --- a/src/app/modules/main/profile_section/privacy/module.nim +++ b/src/app/modules/main/profile_section/privacy/module.nim @@ -88,6 +88,12 @@ method setMessagesFromContactsOnly*(self: Module, value: bool) = if(not self.controller.setMessagesFromContactsOnly(value)): error "an error occurred while saving messages from contacts only flag" +method urlUnfurlingMode*(self: Module): int = + return self.controller.urlUnfurlingMode() + +method setUrlUnfurlingMode*(self: Module, value: int) = + self.controller.setUrlUnfurlingMode(value) + method validatePassword*(self: Module, password: string): bool = self.controller.validatePassword(password) @@ -120,4 +126,4 @@ method onUserAuthenticated*(self: Module, pin: string, password: string, keyUid: self.controller.storeToKeychain(password) method backupData*(self: Module): int64 = - return self.controller.backupData() \ No newline at end of file + return self.controller.backupData() diff --git a/src/app/modules/main/profile_section/privacy/view.nim b/src/app/modules/main/profile_section/privacy/view.nim index 0027706452..40cd8b6173 100644 --- a/src/app/modules/main/profile_section/privacy/view.nim +++ b/src/app/modules/main/profile_section/privacy/view.nim @@ -51,6 +51,8 @@ QtObject: proc getMessagesFromContactsOnly(self: View): bool {.slot.} = return self.delegate.getMessagesFromContactsOnly() proc setMessagesFromContactsOnly(self: View, value: bool) {.slot.} = + if self.getMessagesFromContactsOnly() == value: + return self.delegate.setMessagesFromContactsOnly(value) self.messagesFromContactsOnlyChanged() QtProperty[bool] messagesFromContactsOnly: @@ -58,6 +60,19 @@ QtObject: write = setMessagesFromContactsOnly notify = messagesFromContactsOnlyChanged + proc urlUnfurlingModeChanged(self: View) {.signal.} + proc getUrlUnfurlingMode(self: View): int {.slot.} = + return self.delegate.urlUnfurlingMode() + proc setUrlUnfurlingMode(self: View, value: int) {.slot.} = + if self.getUrlUnfurlingMode() == value: + return + self.delegate.setUrlUnfurlingMode(value) + self.urlUnfurlingModeChanged() + QtProperty[int] urlUnfurlingMode: + read = getUrlUnfurlingMode + write = setUrlUnfurlingMode + notify = urlUnfurlingModeChanged + proc validatePassword*(self: View, password: string): bool {.slot.} = self.delegate.validatePassword(password) @@ -79,4 +94,4 @@ QtObject: self.delegate.tryRemoveFromKeyChain() proc backupData*(self: View): int {.slot.} = - return self.delegate.backupData().int \ No newline at end of file + return self.delegate.backupData().int diff --git a/src/app_service/service/accounts/service.nim b/src/app_service/service/accounts/service.nim index ff5b5f50c7..05f42444eb 100644 --- a/src/app_service/service/accounts/service.nim +++ b/src/app_service/service/accounts/service.nim @@ -293,7 +293,8 @@ QtObject: "text": "" }, "profile-pictures-show-to": settings.PROFILE_PICTURES_SHOW_TO_EVERYONE, - "profile-pictures-visibility": settings.PROFILE_PICTURES_VISIBILITY_EVERYONE + "profile-pictures-visibility": settings.PROFILE_PICTURES_VISIBILITY_EVERYONE, + "url-unfurling-mode": int(settings.UrlUnfurlingMode.AlwaysAsk), } proc getAccountSettings(self: Service, accountId: string, diff --git a/src/app_service/service/settings/dto/settings.nim b/src/app_service/service/settings/dto/settings.nim index 8f086184eb..76f38884cb 100644 --- a/src/app_service/service/settings/dto/settings.nim +++ b/src/app_service/service/settings/dto/settings.nim @@ -46,6 +46,7 @@ const KEY_BIO* = "bio" const KEY_TEST_NETWORKS_ENABLED* = "test-networks-enabled?" const KEY_IS_SEPOLIA_ENABLED* = "is-sepolia-enabled?" const PROFILE_MIGRATION_NEEDED* = "profile-migration-needed" +const KEY_URL_UNFURLING_MODE* = "url-unfurling-mode" # Notifications Settings Values const VALUE_NOTIF_SEND_ALERTS* = "SendAlerts" @@ -60,6 +61,17 @@ const PROFILE_PICTURES_SHOW_TO_CONTACTS_ONLY* = 1 const PROFILE_PICTURES_SHOW_TO_EVERYONE* = 2 const PROFILE_PICTURES_SHOW_TO_NO_ONE* = 3 +type UrlUnfurlingMode* {.pure.} = enum + AlwaysAsk = 1, + Enabled = 2, + Disabled = 3, + +proc toUrlUnfurlingMode*(value: int): UrlUnfurlingMode = + try: + return UrlUnfurlingMode(value) + except RangeDefect: + return AlwaysAsk # this is the default value + type NotificationsExemptions* = object muteAllMessages*: bool personalMentions*: string @@ -139,6 +151,8 @@ type notificationsMessagePreview*: int profileMigrationNeeded*: bool isSepoliaEnabled*: bool + urlUnfurlingMode*: UrlUnfurlingMode + proc toPinnedMailserver*(jsonObj: JsonNode): PinnedMailserver = # we maintain pinned mailserver per fleet @@ -195,6 +209,10 @@ proc toSettingsDto*(jsonObj: JsonNode): SettingsDto = discard jsonObj.getProp(KEY_IS_SEPOLIA_ENABLED, result.isSepoliaEnabled) discard jsonObj.getProp(PROFILE_MIGRATION_NEEDED, result.profileMigrationNeeded) + var urlUnfurlingMode: int + discard jsonObj.getProp(KEY_URL_UNFURLING_MODE, urlUnfurlingMode) + result.urlUnfurlingMode = toUrlUnfurlingMode(urlUnfurlingMode) + var pinnedMailserverObj: JsonNode if(jsonObj.getProp(KEY_PINNED_MAILSERVERS, pinnedMailserverObj)): result.pinnedMailserver = toPinnedMailserver(pinnedMailserverObj) diff --git a/src/app_service/service/settings/service.nim b/src/app_service/service/settings/service.nim index b0e53875d1..8e6f25668b 100644 --- a/src/app_service/service/settings/service.nim +++ b/src/app_service/service/settings/service.nim @@ -28,6 +28,7 @@ const SIGNAL_MNEMONIC_REMOVED* = "mnemonicRemoved" const SIGNAL_SOCIAL_LINKS_UPDATED* = "socialLinksUpdated" const SIGNAL_CURRENT_USER_STATUS_UPDATED* = "currentUserStatusUpdated" const SIGNAL_PROFILE_MIGRATION_NEEDED_UPDATED* = "profileMigrationNeededUpdated" +const SIGNAL_URL_UNFURLING_MODEL_UPDATED* = "urlUnfurlingModeUpdated" logScope: topics = "settings-service" @@ -44,12 +45,12 @@ type socialLinks*: SocialLinks error*: string - SettingProfilePictureArgs* = ref object of Args - value*: int - SettingsBoolValueArgs* = ref object of Args value*: bool + UrlUnfurlingModeArgs* = ref object of Args + value*: UrlUnfurlingMode + QtObject: type Service* = ref object of QObject events: EventEmitter @@ -116,6 +117,9 @@ QtObject: if settingsField.name == PROFILE_MIGRATION_NEEDED: self.settings.profileMigrationNeeded = settingsField.value.getBool self.events.emit(SIGNAL_PROFILE_MIGRATION_NEEDED_UPDATED, SettingsBoolValueArgs(value: self.settings.profileMigrationNeeded)) + if settingsField.name == KEY_URL_UNFURLING_MODE: + self.settings.urlUnfurlingMode = toUrlUnfurlingMode(settingsField.value.getInt) + self.events.emit(SIGNAL_URL_UNFURLING_MODEL_UPDATED, UrlUnfurlingModeArgs(value: self.settings.urlUnfurlingMode)) if receivedData.socialLinksInfo.links.len > 0 or receivedData.socialLinksInfo.removed: @@ -490,6 +494,16 @@ QtObject: return true return false + proc urlUnfurlingMode*(self: Service): UrlUnfurlingMode = + return self.settings.urlUnfurlingMode + + proc saveUrlUnfurlingMode*(self: Service, value: UrlUnfurlingMode): bool = + if not self.saveSetting(KEY_URL_UNFURLING_MODE, int(value)): + return false + self.settings.urlUnfurlingMode = value + self.events.emit(SIGNAL_URL_UNFURLING_MODEL_UPDATED, UrlUnfurlingModeArgs(value: self.settings.urlUnfurlingMode)) + return true + proc notifSettingAllowNotificationsChanged*(self: Service) {.signal.} proc getNotifSettingAllowNotifications*(self: Service): bool {.slot.} = if self.initialized: diff --git a/ui/app/AppLayouts/Chat/stores/RootStore.qml b/ui/app/AppLayouts/Chat/stores/RootStore.qml index 653d09bdce..6441d4dfdd 100644 --- a/ui/app/AppLayouts/Chat/stores/RootStore.qml +++ b/ui/app/AppLayouts/Chat/stores/RootStore.qml @@ -90,6 +90,8 @@ QtObject { property var advancedModule: profileSectionModule.advancedModule + property var privacyModule: profileSectionModule.privacyModule + readonly property bool permissionsCheckOngoing: chatCommunitySectionModule.permissionsCheckOngoing signal importingCommunityStateChanged(string communityId, int state, string errorMsg) diff --git a/ui/app/AppLayouts/Chat/views/ChatColumnView.qml b/ui/app/AppLayouts/Chat/views/ChatColumnView.qml index 17441cd519..aef0b97ebf 100644 --- a/ui/app/AppLayouts/Chat/views/ChatColumnView.qml +++ b/ui/app/AppLayouts/Chat/views/ChatColumnView.qml @@ -146,6 +146,8 @@ Item { d.restoreInputAttachments() } + signal updateLinkPreviewsRequested + readonly property var updateLinkPreviews: { return Backpressure.debounce(this, 250, () => { const messageText = root.rootStore.cleanMessageText(chatInput.textInput.text) @@ -165,6 +167,14 @@ Item { } } + Connections { + enabled: !root.rootStore.privacyModule.urlUnfurlingMode === Constants.UrlUnfurlingModeDisableAll + target: d + function onUpdateLinkPreviewsRequested() { + d.updateLinkPreviews() + } + } + EmptyChatPanel { anchors.fill: parent visible: root.activeChatId === "" || root.chatsCount == 0 @@ -277,7 +287,7 @@ Item { textInput.onTextChanged: { if (!!d.activeChatContentModule) { d.activeChatContentModule.inputAreaModule.preservedProperties.text = textInput.text - d.updateLinkPreviews() + d.updateLinkPreviewsRequested() } } diff --git a/ui/app/AppLayouts/Profile/views/MessagingView.qml b/ui/app/AppLayouts/Profile/views/MessagingView.qml index d1a0b3acaa..ce37f56dd1 100644 --- a/ui/app/AppLayouts/Profile/views/MessagingView.qml +++ b/ui/app/AppLayouts/Profile/views/MessagingView.qml @@ -161,6 +161,85 @@ SettingsContentBase { Layout.fillWidth: true } + // GIF LINK PREVIEWS + StatusSectionHeadline { + Layout.fillWidth: true + Layout.leftMargin: Style.current.padding + Layout.rightMargin: Style.current.padding + text: qsTr("GIF link previews") + } + + StatusListItem { + Layout.fillWidth: true + title: qsTr("Allow show GIF previews") + components: [ + StatusSwitch { + id: showGifPreviewsSwitch + checked: localAccountSensitiveSettings.gifUnfurlingEnabled + onClicked: { + localAccountSensitiveSettings.gifUnfurlingEnabled = !localAccountSensitiveSettings.gifUnfurlingEnabled + } + } + ] + onClicked: { + showGifPreviewsSwitch.clicked() + } + } + + Separator { + Layout.fillWidth: true + } + + // URL UNFRULING + StatusSectionHeadline { + Layout.fillWidth: true + Layout.leftMargin: Style.current.padding + Layout.rightMargin: Style.current.padding + text: qsTr("Website link previews") + } + + ButtonGroup { + id: urlUnfurlingGroup + } + + SettingsRadioButton { + Layout.fillWidth: true + Layout.leftMargin: Style.current.padding + Layout.rightMargin: Style.current.padding + label: qsTr("Always ask") + group: urlUnfurlingGroup + checked: root.messagingStore.privacyModule.urlUnfurlingMode === Constants.UrlUnfurlingModeAlwaysAsk + onClicked: { + root.messagingStore.privacyModule.urlUnfurlingMode = Constants.UrlUnfurlingModeAlwaysAsk + } + } + + SettingsRadioButton { + Layout.topMargin: Constants.settingsSection.itemSpacing / 2 + Layout.fillWidth: true + Layout.leftMargin: Style.current.padding + Layout.rightMargin: Style.current.padding + label: qsTr("Always show previews") + group: urlUnfurlingGroup + checked: root.messagingStore.privacyModule.urlUnfurlingMode === Constants.UrlUnfurlingModeEnableAll + onClicked: { + root.messagingStore.privacyModule.urlUnfurlingMode = Constants.UrlUnfurlingModeEnableAll + } + } + + SettingsRadioButton { + Layout.topMargin: Constants.settingsSection.itemSpacing / 2 + Layout.fillWidth: true + Layout.leftMargin: Style.current.padding + Layout.rightMargin: Style.current.padding + label: qsTr("Never show previews") + group: urlUnfurlingGroup + checked: root.messagingStore.privacyModule.urlUnfurlingMode === Constants.UrlUnfurlingModeDisableAll + onClicked: { + root.messagingStore.privacyModule.urlUnfurlingMode = Constants.UrlUnfurlingModeDisableAll + } + } + // MESSAGE LINK PREVIEWS StatusListItem { Layout.fillWidth: true diff --git a/ui/imports/shared/views/chat/MessageView.qml b/ui/imports/shared/views/chat/MessageView.qml index 069c08ae2c..11ad443591 100644 --- a/ui/imports/shared/views/chat/MessageView.qml +++ b/ui/imports/shared/views/chat/MessageView.qml @@ -71,7 +71,12 @@ Loader { return [] const separator = " " const arr = links.split(separator) - const filtered = arr.filter(v => v.toLowerCase().endsWith('.gif')) + const filtered = arr.filter(value => { + const v = value.toLowerCase() + return localAccountSensitiveSettings.gifUnfurlingEnabled && value.endsWith('.gif') + }) + + const out = filtered.join(separator) return out } diff --git a/ui/imports/utils/Constants.qml b/ui/imports/utils/Constants.qml index 2575617b37..f01cbaa50a 100644 --- a/ui/imports/utils/Constants.qml +++ b/ui/imports/utils/Constants.qml @@ -1231,4 +1231,10 @@ QtObject { enum HoldingType { Unknown, Asset, Collectible } + + enum UrlUnfurlingMode { + UrlUnfurlingModeAlwaysAsk = 1, + UrlUnfurlingModeEnableAll = 2, + UrlUnfurlingModeDisableAll = 3 + } } diff --git a/vendor/status-go b/vendor/status-go index aded258ccb..176bdd297d 160000 --- a/vendor/status-go +++ b/vendor/status-go @@ -1 +1 @@ -Subproject commit aded258ccb68f88dc995e22f8b4e06157bb642db +Subproject commit 176bdd297deb32b3f7a4e86aa8127f13e56dd50e