fix: messaging settings and url unfurling fixes (#12457)
* remove browser selection setting * remove main whitelist settings. replace tenorGif setting with gifUnfurlingEnabled * remove old unfurling * move history nodes section * disable outdated e2e tests step * remove isGifWidgetEnabled setting * fix: StatusMessage height when gif unfurling disabled --------- Co-authored-by: Anastasiya Semenkevich <anastasija.ig@gmail.com>
This commit is contained in:
parent
e1149c9227
commit
e5b68e8823
|
@ -18,13 +18,7 @@ const LSS_KEY_SHOW_ONLINE_USERS* = "showOnlineUsers"
|
|||
const DEFAULT_SHOW_ONLINE_USERS = true
|
||||
const LSS_KEY_EXPAND_USERS_LIST* = "expandUsersList"
|
||||
const DEFAULT_EXPAND_USERS_LIST = true
|
||||
const LSS_KEY_IS_GIF_WIDGET_ENABLED* = "isGifWidgetEnabled"
|
||||
const DEFAULT_IS_GIF_WIDGET_ENABLED = true
|
||||
const DEFAULT_IS_MULTI_NETWORK_ENABLED = false
|
||||
const LSS_KEY_IS_TENOR_WARNING_ACCEPTED* = "isTenorWarningAccepted"
|
||||
const DEFAULT_IS_TENOR_WARNING_ACCEPTED = false
|
||||
const LSS_KEY_DISPLAY_CHAT_IMAGES* = "displayChatImages"
|
||||
const DEFAULT_DISPLAY_CHAT_IMAGES = false
|
||||
const LSS_KEY_RECENT_EMOJIS* = "recentEmojis"
|
||||
const DEFAULT_RECENT_EMOJIS = ""
|
||||
const LSS_KEY_HIDDEN_COMMUNITY_WELCOME_BANNERS* = "hiddenCommunityWelcomeBanners"
|
||||
|
@ -33,8 +27,6 @@ const LSS_KEY_HIDDEN_COMMUNITY_CHANNELS_AND_CATEGORIES_BANNERS* = "hiddenCommuni
|
|||
const DEFAULT_HIDDEN_COMMUNITY_CHANNELS_AND_CATEGORIES_BANNERS = ""
|
||||
const LSS_KEY_HIDDEN_COMMUNITY_BACKUP_BANNERS* = "hiddenCommunityBackUpBanners"
|
||||
const DEFAULT_HIDDEN_COMMUNITY_BACKUP_BANNERS = ""
|
||||
const LSS_KEY_WITHLISTED_UNFURLING_SITES* = "whitelistedUnfurlingSites"
|
||||
const DEFAULT_WITHLISTED_UNFURLING_SITES = ""
|
||||
const LSS_KEY_NEVER_ASK_ABOUT_UNFURLING_AGAIN* = "neverAskAboutUnfurlingAgain"
|
||||
const DEFAULT_NEVER_ASK_ABOUT_UNFURLING_AGAIN = false
|
||||
const LSS_KEY_HIDE_CHANNEL_SUGGESTIONS* = "hideChannelSuggestions"
|
||||
|
@ -277,44 +269,6 @@ QtObject:
|
|||
notify = expandUsersListChanged
|
||||
|
||||
|
||||
proc isGifWidgetEnabledChanged*(self: LocalAccountSensitiveSettings) {.signal.}
|
||||
proc getIsGifWidgetEnabled*(self: LocalAccountSensitiveSettings): bool {.slot.} =
|
||||
getSettingsProp[bool](self, LSS_KEY_IS_GIF_WIDGET_ENABLED, newQVariant(DEFAULT_IS_GIF_WIDGET_ENABLED))
|
||||
proc setIsGifWidgetEnabled*(self: LocalAccountSensitiveSettings, value: bool) {.slot.} =
|
||||
setSettingsProp(self, LSS_KEY_IS_GIF_WIDGET_ENABLED, newQVariant(value)):
|
||||
self.isGifWidgetEnabledChanged()
|
||||
|
||||
QtProperty[bool] isGifWidgetEnabled:
|
||||
read = getIsGifWidgetEnabled
|
||||
write = setIsGifWidgetEnabled
|
||||
notify = isGifWidgetEnabledChanged
|
||||
|
||||
proc isTenorWarningAcceptedChanged*(self: LocalAccountSensitiveSettings) {.signal.}
|
||||
proc getIsTenorWarningAccepted*(self: LocalAccountSensitiveSettings): bool {.slot.} =
|
||||
getSettingsProp[bool](self, LSS_KEY_IS_TENOR_WARNING_ACCEPTED, newQVariant(DEFAULT_IS_TENOR_WARNING_ACCEPTED))
|
||||
proc setIsTenorWarningAccepted*(self: LocalAccountSensitiveSettings, value: bool) {.slot.} =
|
||||
setSettingsProp(self, LSS_KEY_IS_TENOR_WARNING_ACCEPTED, newQVariant(value)):
|
||||
self.isTenorWarningAcceptedChanged()
|
||||
|
||||
QtProperty[bool] isTenorWarningAccepted:
|
||||
read = getIsTenorWarningAccepted
|
||||
write = setIsTenorWarningAccepted
|
||||
notify = isTenorWarningAcceptedChanged
|
||||
|
||||
|
||||
proc displayChatImagesChanged*(self: LocalAccountSensitiveSettings) {.signal.}
|
||||
proc getDisplayChatImages*(self: LocalAccountSensitiveSettings): bool {.slot.} =
|
||||
getSettingsProp[bool](self, LSS_KEY_DISPLAY_CHAT_IMAGES, newQVariant(DEFAULT_DISPLAY_CHAT_IMAGES))
|
||||
proc setDisplayChatImages*(self: LocalAccountSensitiveSettings, value: bool) {.slot.} =
|
||||
setSettingsProp(self, LSS_KEY_DISPLAY_CHAT_IMAGES, newQVariant(value)):
|
||||
self.displayChatImagesChanged()
|
||||
|
||||
QtProperty[bool] displayChatImages:
|
||||
read = getDisplayChatImages
|
||||
write = setDisplayChatImages
|
||||
notify = displayChatImagesChanged
|
||||
|
||||
|
||||
proc recentEmojisChanged*(self: LocalAccountSensitiveSettings) {.signal.}
|
||||
proc getRecentEmojis*(self: LocalAccountSensitiveSettings): QVariant {.slot.} =
|
||||
getSettingsPropQVariant(self, LSS_KEY_RECENT_EMOJIS, newQVariant(DEFAULT_RECENT_EMOJIS))
|
||||
|
@ -364,20 +318,6 @@ QtObject:
|
|||
write = setHiddenCommunityBackUpBanners
|
||||
notify = hiddenCommunityBackUpBannersChanged
|
||||
|
||||
|
||||
proc whitelistedUnfurlingSitesChanged*(self: LocalAccountSensitiveSettings) {.signal.}
|
||||
proc getWhitelistedUnfurlingSites*(self: LocalAccountSensitiveSettings): QVariant {.slot.} =
|
||||
getSettingsPropQVariant(self, LSS_KEY_WITHLISTED_UNFURLING_SITES, newQVariant(DEFAULT_WITHLISTED_UNFURLING_SITES))
|
||||
proc setWhitelistedUnfurlingSites*(self: LocalAccountSensitiveSettings, value: QVariant) {.slot.} =
|
||||
setSettingsProp(self, LSS_KEY_WITHLISTED_UNFURLING_SITES, value):
|
||||
self.whitelistedUnfurlingSitesChanged()
|
||||
|
||||
QtProperty[QVariant] whitelistedUnfurlingSites:
|
||||
read = getWhitelistedUnfurlingSites
|
||||
write = setWhitelistedUnfurlingSites
|
||||
notify = whitelistedUnfurlingSitesChanged
|
||||
|
||||
|
||||
proc neverAskAboutUnfurlingAgainChanged*(self: LocalAccountSensitiveSettings) {.signal.}
|
||||
proc getNeverAskAboutUnfurlingAgain*(self: LocalAccountSensitiveSettings): bool {.slot.} =
|
||||
getSettingsProp[bool](self, LSS_KEY_NEVER_ASK_ABOUT_UNFURLING_AGAIN, newQVariant(DEFAULT_NEVER_ASK_ABOUT_UNFURLING_AGAIN))
|
||||
|
@ -754,14 +694,10 @@ QtObject:
|
|||
of LSS_KEY_IS_BROWSER_ENABLED: self.isBrowserEnabledChanged()
|
||||
of LSS_KEY_SHOW_ONLINE_USERS: self.showOnlineUsersChanged()
|
||||
of LSS_KEY_EXPAND_USERS_LIST: self.expandUsersListChanged()
|
||||
of LSS_KEY_IS_GIF_WIDGET_ENABLED: self.isGifWidgetEnabledChanged()
|
||||
of LSS_KEY_IS_TENOR_WARNING_ACCEPTED: self.isTenorWarningAcceptedChanged()
|
||||
of LSS_KEY_DISPLAY_CHAT_IMAGES: self.displayChatImagesChanged()
|
||||
of LSS_KEY_RECENT_EMOJIS: self.recentEmojisChanged()
|
||||
of LSS_KEY_HIDDEN_COMMUNITY_WELCOME_BANNERS: self.hiddenCommunityWelcomeBannersChanged()
|
||||
of LSS_KEY_HIDDEN_COMMUNITY_CHANNELS_AND_CATEGORIES_BANNERS: self.hiddenCommunityChannelAndCategoriesBannersChanged()
|
||||
of LSS_KEY_HIDDEN_COMMUNITY_BACKUP_BANNERS: self.hiddenCommunityBackUpBannersChanged()
|
||||
of LSS_KEY_WITHLISTED_UNFURLING_SITES: self.whitelistedUnfurlingSitesChanged()
|
||||
of LSS_KEY_NEVER_ASK_ABOUT_UNFURLING_AGAIN: self.neverAskAboutUnfurlingAgainChanged()
|
||||
of LSS_KEY_HIDE_CHANNEL_SUGGESTIONS: self.hideChannelSuggestionsChanged()
|
||||
of LSS_KEY_FONT_SIZE: self.fontSizeChanged()
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
import io_interface, chronicles, tables, sequtils
|
||||
import io_interface, chronicles, tables, sequtils, strutils, sugar
|
||||
|
||||
|
||||
import ../../../../../../app_service/service/settings/service as settings_service
|
||||
|
@ -199,7 +199,8 @@ proc setText*(self: Controller, text: string, unfurlNewUrls: bool) =
|
|||
return
|
||||
|
||||
let urls = self.messageService.getTextUrls(text)
|
||||
self.delegate.setUrls(urls)
|
||||
let supportedUrls = urls.filter(x => not x.endsWith(".gif")) # GIFs are currently unfurled by receiver
|
||||
self.delegate.setUrls(supportedUrls)
|
||||
let newUrls = self.linkPreviewCache.unknownUrls(urls)
|
||||
|
||||
let askToEnableLinkPreview = len(newUrls) > 0 and self.canAskToEnableLinkPreview()
|
||||
|
|
|
@ -192,10 +192,6 @@ proc init*(self: Controller) =
|
|||
return
|
||||
self.delegate.onHistoryCleared()
|
||||
|
||||
self.events.on(SIGNAL_MESSAGE_LINK_PREVIEW_DATA_LOADED) do(e: Args):
|
||||
let args = LinkPreviewDataArgs(e)
|
||||
self.delegate.onPreviewDataLoaded($(args.response), args.uuid)
|
||||
|
||||
self.events.on(SIGNAL_MAKE_SECTION_CHAT_ACTIVE) do(e: Args):
|
||||
let args = ActiveSectionChatArgs(e)
|
||||
if(self.sectionId != args.sectionId or self.chatId != args.chatId):
|
||||
|
@ -279,9 +275,6 @@ proc deleteMessage*(self: Controller, messageId: string) =
|
|||
|
||||
proc editMessage*(self: Controller, messageId: string, contentType: int, updatedMsg: string) =
|
||||
self.messageService.editMessage(messageId, contentType, updatedMsg)
|
||||
|
||||
proc getLinkPreviewData*(self: Controller, link: string, uuid: string, whiteListedSites: string, whiteListedImgExtensions: string, unfurlImages: bool): string =
|
||||
self.messageService.asyncGetLinkPreviewData(link, uuid, whiteListedSites, whiteListedImgExtensions, unfurlImages)
|
||||
|
||||
proc getSearchedMessageId*(self: Controller): string =
|
||||
return self.searchedMessageId
|
||||
|
|
|
@ -126,12 +126,6 @@ method editMessage*(self: AccessInterface, messageId: string, contentType: int,
|
|||
method onHistoryCleared*(self: AccessInterface) {.base.} =
|
||||
raise newException(ValueError, "No implementation available")
|
||||
|
||||
method getLinkPreviewData*(self: AccessInterface, link: string, uuid: string, whiteListedSites: string, whiteListedImgExtensions: string, unfurlImages: bool): string {.base.} =
|
||||
raise newException(ValueError, "No implementation available")
|
||||
|
||||
method onPreviewDataLoaded*(self: AccessInterface, previewData: string, uuid: string) {.base.} =
|
||||
raise newException(ValueError, "No implementation available")
|
||||
|
||||
method requestMoreMessages*(self: AccessInterface) {.base.} =
|
||||
raise newException(ValueError, "No implementation available")
|
||||
|
||||
|
|
|
@ -644,12 +644,6 @@ method updateChatFetchMoreMessages*(self: Module) =
|
|||
if (self.controller.getChatDetails().hasMoreMessagesToRequest()):
|
||||
self.view.model().insertItemBasedOnClock(self.createFetchMoreMessagesItem())
|
||||
|
||||
method getLinkPreviewData*(self: Module, link: string, uuid: string, whiteListedSites: string, whiteListedImgExtensions: string, unfurlImages: bool): string =
|
||||
return self.controller.getLinkPreviewData(link, uuid, whiteListedSites, whiteListedImgExtensions, unfurlImages)
|
||||
|
||||
method onPreviewDataLoaded*(self: Module, previewData: string, uuid: string) =
|
||||
self.view.onPreviewDataLoaded(previewData, uuid)
|
||||
|
||||
proc switchToMessage*(self: Module, messageId: string) =
|
||||
let index = self.view.model().findIndexForMessageId(messageId)
|
||||
if(index != -1):
|
||||
|
|
|
@ -102,14 +102,6 @@ QtObject:
|
|||
proc editMessage*(self: View, messageId: string, contentType: int, updatedMsg: string) {.slot.} =
|
||||
self.delegate.editMessage(messageId, contentType, updatedMsg)
|
||||
|
||||
proc getLinkPreviewData*(self: View, link: string, uuid: string, whiteListedSites: string, whiteListedImgExtensions: string, unfurlImages: bool): string {.slot.} =
|
||||
return self.delegate.getLinkPreviewData(link, uuid, whiteListedSites, whiteListedImgExtensions, unfurlImages)
|
||||
|
||||
proc linkPreviewDataWasReceived*(self: View, previewData: string, uuid: string) {.signal.}
|
||||
|
||||
proc onPreviewDataLoaded*(self: View, previewData: string, uuid: string) {.slot.} =
|
||||
self.linkPreviewDataWasReceived(previewData, uuid)
|
||||
|
||||
proc switchToMessage(self: View, messageIndex: int) {.signal.}
|
||||
proc emitSwitchToMessageSignal*(self: View, messageIndex: int) =
|
||||
self.switchToMessage(messageIndex)
|
||||
|
|
|
@ -73,9 +73,6 @@ proc init*(self: Controller) =
|
|||
proc isMnemonicBackedUp*(self: Controller): bool =
|
||||
return self.privacyService.isMnemonicBackedUp()
|
||||
|
||||
proc getLinkPreviewWhitelist*(self: Controller): string =
|
||||
return self.privacyService.getLinkPreviewWhitelist()
|
||||
|
||||
proc changePassword*(self: Controller, password: string, newPassword: string) =
|
||||
self.privacyService.changePassword(password, newPassword)
|
||||
|
||||
|
|
|
@ -25,9 +25,6 @@ method viewDidLoad*(self: AccessInterface) {.base.} =
|
|||
method isMnemonicBackedUp*(self: AccessInterface): bool {.base.} =
|
||||
raise newException(ValueError, "No implementation available")
|
||||
|
||||
method getLinkPreviewWhitelist*(self: AccessInterface): string {.base.} =
|
||||
raise newException(ValueError, "No implementation available")
|
||||
|
||||
method changePassword*(self: AccessInterface, password: string, newPassword: string) {.base.} =
|
||||
raise newException(ValueError, "No implementation available")
|
||||
|
||||
|
|
|
@ -57,9 +57,6 @@ method viewDidLoad*(self: Module) =
|
|||
method getModuleAsVariant*(self: Module): QVariant =
|
||||
return self.viewVariant
|
||||
|
||||
method getLinkPreviewWhitelist*(self: Module): string =
|
||||
return self.controller.getLinkPreviewWhitelist()
|
||||
|
||||
method changePassword*(self: Module, password: string, newPassword: string) =
|
||||
self.controller.changePassword(password, newPassword)
|
||||
|
||||
|
|
|
@ -18,9 +18,6 @@ QtObject:
|
|||
proc load*(self: View) =
|
||||
self.delegate.viewDidLoad()
|
||||
|
||||
proc getLinkPreviewWhitelist*(self: View): string {.slot.} =
|
||||
return self.delegate.getLinkPreviewWhitelist()
|
||||
|
||||
proc changePassword*(self: View, password: string, newPassword: string) {.slot.} =
|
||||
self.delegate.changePassword(password, newPassword)
|
||||
|
||||
|
|
|
@ -162,96 +162,7 @@ const asyncMarkCertainMessagesReadTask: Task = proc(argEncoded: string) {.gcsafe
|
|||
"error": error
|
||||
}
|
||||
arg.finish(responseJson)
|
||||
#################################################
|
||||
|
||||
#################################################
|
||||
# Async GetLinkPreviewData
|
||||
#################################################
|
||||
|
||||
type
|
||||
AsyncGetLinkPreviewDataTaskArg = ref object of QObjectTaskArg
|
||||
links: string
|
||||
uuid: string
|
||||
whiteListedUrls: string
|
||||
whiteListedImgExtensions: string
|
||||
unfurlImages: bool
|
||||
|
||||
|
||||
|
||||
const asyncGetLinkPreviewDataTask: Task = proc(argEncoded: string) {.gcsafe, nimcall.} =
|
||||
let arg = decode[AsyncGetLinkPreviewDataTaskArg](argEncoded)
|
||||
var previewData = %* {
|
||||
"links": %*[]
|
||||
}
|
||||
|
||||
if arg.links == "":
|
||||
arg.finish(previewData)
|
||||
return
|
||||
|
||||
let parsedWhiteListUrls = parseJson(arg.whiteListedUrls)
|
||||
let parsedWhiteListImgExtensions = arg.whiteListedImgExtensions.split(",")
|
||||
|
||||
for link in arg.links.split(" "):
|
||||
if link == "":
|
||||
continue
|
||||
|
||||
let uri = parseUri(link)
|
||||
let path = uri.path
|
||||
let domain = uri.hostname.toLower()
|
||||
let isSupportedImage = any(parsedWhiteListImgExtensions, proc (extenstion: string): bool = path.endsWith(extenstion))
|
||||
let isListed = parsedWhiteListUrls.hasKey(domain)
|
||||
let isProfileLink = path.startsWith(profileLinkPrefix)
|
||||
let processUrl = isListed or isSupportedImage
|
||||
|
||||
if domain == "" or processUrl == false:
|
||||
continue
|
||||
|
||||
let canUnfurl = parsedWhiteListUrls{domain}.getBool() or (isSupportedImage and arg.unfurlImages)
|
||||
let responseJson = %*{
|
||||
"link": link,
|
||||
"success": true,
|
||||
"unfurl": canUnfurl,
|
||||
"isStatusDeepLink": false,
|
||||
"result": %*{}
|
||||
}
|
||||
|
||||
if canUnfurl == false:
|
||||
previewData["links"].add(responseJson)
|
||||
continue
|
||||
|
||||
#1. if it's an image, we use httpclient to validate the url
|
||||
if isSupportedImage:
|
||||
#TODO: validate image url using HEAD request
|
||||
responseJson["result"] = %*{
|
||||
"site": domain,
|
||||
"thumbnailUrl": link,
|
||||
"contentType": "image/" & path.split(".")[^1]
|
||||
}
|
||||
previewData["links"].add(responseJson)
|
||||
continue
|
||||
|
||||
#2. Process whitelisted url
|
||||
#status deep links are handled internally
|
||||
if domain == StatusInternalLink or domain == StatusExternalLink:
|
||||
responseJson["success"] = %true
|
||||
responseJson["isStatusDeepLink"] = %true
|
||||
responseJson["result"] = %*{
|
||||
"site": domain,
|
||||
"contentType": "text/html"
|
||||
}
|
||||
previewData["links"].add(responseJson)
|
||||
continue
|
||||
#other links are handled by status-go
|
||||
try:
|
||||
let response = status_go_chat.getLinkPreviewData(link)
|
||||
responseJson["result"] = response.result
|
||||
responseJson["success"] = %true
|
||||
except:
|
||||
responseJson["success"] = %false
|
||||
previewData["links"].add(responseJson)
|
||||
|
||||
let tpl: tuple[previewData: JsonNode, uuid: string] = (previewData, arg.uuid)
|
||||
arg.finish(tpl)
|
||||
|
||||
#################################################
|
||||
# Async get first unseen message id
|
||||
|
|
|
@ -58,7 +58,6 @@ const SIGNAL_MESSAGE_DELIVERED* = "messageDelivered"
|
|||
const SIGNAL_MESSAGE_EDITED* = "messageEdited"
|
||||
const SIGNAL_ENVELOPE_SENT* = "envelopeSent"
|
||||
const SIGNAL_ENVELOPE_EXPIRED* = "envelopeExpired"
|
||||
const SIGNAL_MESSAGE_LINK_PREVIEW_DATA_LOADED* = "messageLinkPreviewDataLoaded"
|
||||
const SIGNAL_RELOAD_MESSAGES* = "reloadMessages"
|
||||
const SIGNAL_URLS_UNFURLED* = "urlsUnfurled"
|
||||
const SIGNAL_GET_MESSAGE_FINISHED* = "getMessageFinished"
|
||||
|
@ -121,10 +120,6 @@ type
|
|||
chatId*: string
|
||||
message*: MessageDto
|
||||
|
||||
LinkPreviewDataArgs* = ref object of Args
|
||||
response*: JsonNode
|
||||
uuid*: string
|
||||
|
||||
LinkPreviewV2DataArgs* = ref object of Args
|
||||
linkPreviews*: Table[string, LinkPreview]
|
||||
|
||||
|
@ -810,32 +805,6 @@ QtObject:
|
|||
except Exception as e:
|
||||
error "error: ", procName="onGetFirstUnseenMessageIdFor", errName = e.name, errDesription = e.msg
|
||||
|
||||
proc onAsyncGetLinkPreviewData*(self: Service, response: string) {.slot.} =
|
||||
let responseObj = response.parseJson
|
||||
if (responseObj.kind != JObject):
|
||||
info "expected response is not a json object", methodName="onAsyncGetLinkPreviewData"
|
||||
return
|
||||
|
||||
let args = LinkPreviewDataArgs(
|
||||
response: responseObj["previewData"],
|
||||
uuid: responseObj["uuid"].getStr()
|
||||
)
|
||||
self.events.emit(SIGNAL_MESSAGE_LINK_PREVIEW_DATA_LOADED, args)
|
||||
|
||||
proc asyncGetLinkPreviewData*(self: Service, links: string, uuid: string, whiteListedSites: string, whiteListedImgExtensions: string, unfurlImages: bool): string =
|
||||
let arg = AsyncGetLinkPreviewDataTaskArg(
|
||||
tptr: cast[ByteAddress](asyncGetLinkPreviewDataTask),
|
||||
vptr: cast[ByteAddress](self.vptr),
|
||||
slot: "onAsyncGetLinkPreviewData",
|
||||
links: links,
|
||||
whiteListedUrls: whiteListedSites,
|
||||
whiteListedImgExtensions: whiteListedImgExtensions,
|
||||
unfurlImages: unfurlImages,
|
||||
uuid: uuid
|
||||
)
|
||||
self.threadpool.start(arg)
|
||||
return $genOid()
|
||||
|
||||
proc getTextUrls*(self: Service, text: string): seq[string] =
|
||||
try:
|
||||
let response = status_go.getTextUrls(text)
|
||||
|
|
|
@ -42,21 +42,6 @@ QtObject:
|
|||
proc init*(self: Service) =
|
||||
discard
|
||||
|
||||
proc getLinkPreviewWhitelist*(self: Service): string =
|
||||
try:
|
||||
let response = status_privacy.getLinkPreviewWhitelist()
|
||||
|
||||
if(response.result.kind != JArray):
|
||||
var errMsg = "response is not an array"
|
||||
if(response.result.contains("error")):
|
||||
errMsg = response.result["error"].getStr
|
||||
error "error: ", procName="getLinkPreviewWhitelist", errDesription = errMsg
|
||||
return
|
||||
|
||||
return $(response.result)
|
||||
except Exception as e:
|
||||
error "error: ", procName="getLinkPreviewWhitelist", errName = e.name, errDesription = e.msg
|
||||
|
||||
proc getDefaultAccount(self: Service): string =
|
||||
try:
|
||||
let response = status_eth.getAccounts()
|
||||
|
|
|
@ -149,9 +149,6 @@ proc createGroupChatFromInvitation*(groupName: string, chatId: string, adminPK:
|
|||
let payload = %* [groupName, chatId, adminPK]
|
||||
result = callPrivateRPC("createGroupChatFromInvitation".prefix, payload)
|
||||
|
||||
proc getLinkPreviewData*(link: string): RpcResponse[JsonNode] {.raises: [Exception].} =
|
||||
result = callPrivateRPC("getLinkPreviewData".prefix, %* [link])
|
||||
|
||||
proc getMembers*(communityId, chatId: string): RpcResponse[JsonNode] {.raises: [Exception].} =
|
||||
result = callPrivateRPC("chat_getMembers", %* [communityId, chatId])
|
||||
|
||||
|
|
|
@ -17,7 +17,3 @@ proc changeDatabasePassword*(keyUID: string, oldHashedPassword: string, newHashe
|
|||
except RpcException as e:
|
||||
error "error", methodName = "changeDatabasePassword", exception=e.msg
|
||||
raise newException(RpcException, e.msg)
|
||||
|
||||
proc getLinkPreviewWhitelist*(): RpcResponse[JsonNode] {.raises: [Exception].} =
|
||||
let payload = %* []
|
||||
result = callPrivateRPC("getLinkPreviewWhitelist".prefix, payload)
|
||||
|
|
|
@ -1,7 +1,9 @@
|
|||
import QtQuick 2.15
|
||||
import QtQuick.Controls 2.15
|
||||
import QtQuick.Layouts 1.15
|
||||
|
||||
import shared.views.chat 1.0
|
||||
import shared.stores 1.0
|
||||
|
||||
SplitView {
|
||||
|
||||
|
@ -14,20 +16,10 @@ SplitView {
|
|||
"unfurled": true,
|
||||
"immutable": false,
|
||||
"empty": false,
|
||||
"url": "https://www.youtube.com/watch?v=9bZkp7q19f0",
|
||||
"url": "",
|
||||
"previewType": 1,
|
||||
"standardPreview": {
|
||||
"hostname": "www.youtube.com",
|
||||
"title": "PSY - GANGNAM STYLE(강남스타일) M/V",
|
||||
"description": "PSY - ‘I LUV IT’ M/V @ https://youtu.be/Xvjnoagk6GU PSY - ‘New Face’ M/V @https://youtu.be/OwJPPaEyqhI PSY - 8TH ALBUM '4X2=8' on iTunes @ https://smarturl.it/PSY_8thAlbum PSY - GANGNAM STYLE(강남스타일) on iTunes @ http://smarturl.it/PsyGangnam #PSY #싸이 #GANGNAMSTYLE #강남스타일 More about PSY@ http://www.psyp...",
|
||||
"linkType": 0,
|
||||
},
|
||||
"standardPreviewThumbnail": {
|
||||
"width": 480,
|
||||
"height": 360,
|
||||
"url": "https://i.ytimg.com/vi/9bZkp7q19f0/hqdefault.jpg",
|
||||
"dataUri": "https://i.ytimg.com/vi/9bZkp7q19f0/hqdefault.jpg",
|
||||
},
|
||||
"standardPreview": {},
|
||||
"standardPreviewThumbnail": {},
|
||||
"statusContactPreview": {},
|
||||
"statusContactPreviewThumbnail": {},
|
||||
"statusCommunityPreview": {},
|
||||
|
@ -47,7 +39,7 @@ SplitView {
|
|||
preview1.standardPreview.hostname = "www.youtube.com"
|
||||
preview1.standardPreview.title = "PSY - GANGNAM STYLE(강남스타일) M/V"
|
||||
preview1.standardPreview.description = "PSY - ‘I LUV IT’ M/V @ https://youtu.be/Xvjnoagk6GU PSY - ‘New Face’ M/V @https://youtu.be/OwJPPaEyqhI PSY - 8TH ALBUM '4X2=8' on iTunes @ https://smarturl.it/PSY_8thAlbum PSY - GANGNAM STYLE(강남스타일) on iTunes @ http://smarturl.it/PsyGangnam #PSY #싸이 #GANGNAMSTYLE #강남스타일 More about PSY@ http://www.psyp..."
|
||||
preview1.standardPreview.standardLinkType = 0
|
||||
preview1.standardPreview.linkType = 0
|
||||
preview1.standardPreviewThumbnail.width = 480
|
||||
preview1.standardPreviewThumbnail.height = 360
|
||||
preview1.standardPreviewThumbnail.url = "https://i.ytimg.com/vi/9bZkp7q19f0/hqdefault.jpg"
|
||||
|
@ -127,7 +119,7 @@ SplitView {
|
|||
store: {}
|
||||
messageStore: {}
|
||||
linkPreviewModel: mockedLinkPreviewModel
|
||||
localUnfurlLinks: {}
|
||||
gifLinks: [ "https://media.tenor.com/qN_ytiwLh24AAAAC/cold.gif" ]
|
||||
isCurrentUser: true
|
||||
|
||||
onImageClicked: {
|
||||
|
@ -151,6 +143,23 @@ SplitView {
|
|||
checked: linksMessageView.isCurrentUser
|
||||
onToggled: linksMessageView.isCurrentUser = !linksMessageView.isCurrentUser
|
||||
}
|
||||
Label {
|
||||
text: qsTr("GIF unfuring settings")
|
||||
}
|
||||
CheckBox {
|
||||
text: qsTr("Enabled")
|
||||
checked: RootStore.gifUnfurlingEnabled
|
||||
onToggled: RootStore.gifUnfurlingEnabled = !RootStore.gifUnfurlingEnabled
|
||||
}
|
||||
CheckBox {
|
||||
text: qsTr("Never ask about GIF unfurling again")
|
||||
checked: RootStore.neverAskAboutUnfurlingAgain
|
||||
onClicked: RootStore.neverAskAboutUnfurlingAgain = !RootStore.neverAskAboutUnfurlingAgain
|
||||
}
|
||||
Button {
|
||||
text: qsTr("Reset local `askAboutUnfurling` setting")
|
||||
onClicked: linksMessageView.resetLocalAskAboutUnfurling()
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -62,9 +62,8 @@ SplitView {
|
|||
}
|
||||
|
||||
Component.onCompleted: {
|
||||
RootStore.isGifWidgetEnabled = true
|
||||
RootStore.isWalletEnabled = true
|
||||
RootStore.isTenorWarningAccepted = true
|
||||
RootStore.gifUnfurlingEnabled = true
|
||||
RootStore.getSelectedTextWithFormationChars = rootStoreMock.getSelectedTextWithFormationChars
|
||||
RootStore.gifColumnA = rootStoreMock.gifColumnA
|
||||
rootStoreMock.ready = true
|
||||
|
|
|
@ -702,7 +702,7 @@ Item {
|
|||
property ListModel gifColumnA: ListModel {}
|
||||
|
||||
readonly property var formationChars: (["*", "`", "~"])
|
||||
property bool isTenorWarningAccepted: true
|
||||
property bool gifUnfurlingEnabled: true
|
||||
function getSelectedTextWithFormationChars(messageInputField) {
|
||||
let i = 1
|
||||
let text = ""
|
||||
|
@ -723,9 +723,8 @@ Item {
|
|||
}
|
||||
|
||||
Component.onCompleted: {
|
||||
RootStore.isGifWidgetEnabled = true
|
||||
RootStore.isWalletEnabled = true
|
||||
RootStore.isTenorWarningAccepted = rootStoreMock.isTenorWarningAccepted
|
||||
RootStore.gifUnfurlingEnabled = rootStoreMock.gifUnfurlingEnabled
|
||||
RootStore.getSelectedTextWithFormationChars = rootStoreMock.getSelectedTextWithFormationChars
|
||||
RootStore.gifColumnA = rootStoreMock.gifColumnA
|
||||
|
||||
|
|
|
@ -4,12 +4,12 @@ import QtQuick 2.14
|
|||
|
||||
QtObject {
|
||||
property var userProfileInst
|
||||
property bool isTenorWarningAccepted
|
||||
property bool isGifWidgetEnabled
|
||||
property bool gifUnfurlingEnabled
|
||||
property bool isWalletEnabled
|
||||
property var getSelectedTextWithFormationChars
|
||||
property var gifColumnA
|
||||
property var currentCurrency
|
||||
property bool neverAskAboutUnfurlingAgain: false
|
||||
|
||||
property var currencyStore
|
||||
property var history
|
||||
|
@ -32,4 +32,9 @@ QtObject {
|
|||
function copyToClipboard(text) {
|
||||
console.warn("STUB: copyToClipboard:", text)
|
||||
}
|
||||
|
||||
function setNeverAskAboutUnfurlingAgain(value) {
|
||||
console.log("STUB: setNeverAskAboutUnfurlingAgain:", value)
|
||||
neverAskAboutUnfurlingAgain = value
|
||||
}
|
||||
}
|
||||
|
|
|
@ -112,7 +112,7 @@ generatedAccounts_ListView = {"container": statusDesktop_mainWindow, "objectName
|
|||
displayMessageLinkPreviewItem = {"container": statusDesktop_mainWindow, "objectName": "displayMessageLinkPreviewsItem", "type": "StatusListItem"}
|
||||
linkPreviewSwitch = {"container": statusDesktop_mainWindow, "objectName": "MessagingView_showMessageLinksSwitch", "type": "StatusSwitch", "visible": True}
|
||||
imageUnfurlingItem = {"container": statusDesktop_mainWindow, "objectName": "imageUnfurlingItem", "type": "StatusListItem"}
|
||||
tenorGifsPreviewSwitchItem = {"container": statusDesktop_mainWindow, "objectName": "MessagingView_sitesListView_StatusListItem_tenor_gifs_subdomain", "type": "StatusListItem"}
|
||||
showGifPreviewsSwitch = {"container": settingsContentBase_ScrollView, "id": "showGifPreviewsSwitch", "type": "StatusSwitch", "unnamed": 1, "visible": True}
|
||||
contacts_listItem_btn = {"container": statusDesktop_mainWindow, "objectName": "MessagingView_ContactsListItem_btn", "type": "StatusContactRequestsIndicatorListItem"}
|
||||
settingsContentBaseScrollView_StatusScrollBar = {"container": settingsContentBase_ScrollView, "occurrence": 3, "type": "StatusScrollBar", "unnamed": 1, "visible": True}
|
||||
|
||||
|
|
|
@ -95,12 +95,13 @@ Feature: Status Desktop community messages
|
|||
And the user sends a chat message "history"
|
||||
When the user clears chat history
|
||||
Then the chat is cleared
|
||||
|
||||
|
||||
@mayfail
|
||||
Scenario: The user can send a GIF
|
||||
Given the user opens app settings screen
|
||||
And the user opens the messaging settings
|
||||
When the user activates the link preview if it is deactivated
|
||||
And the user activates tenor GIFs preview
|
||||
#When the user activates the link preview if it is deactivated
|
||||
When the user activates tenor GIFs preview
|
||||
And the user opens the community named "test_community"
|
||||
Then the user lands on the community named "test_community"
|
||||
When the user sends a GIF message
|
||||
|
|
|
@ -40,7 +40,7 @@ Control {
|
|||
property string messageAttachments: ""
|
||||
property var reactionIcons: []
|
||||
property var linkPreviewModel
|
||||
property var localUnfurlLinks
|
||||
property var gifLinks
|
||||
|
||||
property string messageId: ""
|
||||
property bool editMode: false
|
||||
|
@ -357,10 +357,11 @@ Control {
|
|||
Loader {
|
||||
id: linksLoader
|
||||
Layout.fillWidth: true
|
||||
Layout.preferredHeight: implicitHeight
|
||||
active: !root.editMode &&
|
||||
((!!root.linkPreviewModel && root.linkPreviewModel.count > 0)
|
||||
|| (!!root.localUnfurlLinks && root.localUnfurlLinks.length > 0))
|
||||
visible: active
|
||||
|| (!!root.gifLinks && root.gifLinks.length > 0))
|
||||
visible: active
|
||||
}
|
||||
Loader {
|
||||
id: transactionBubbleLoader
|
||||
|
|
|
@ -166,12 +166,6 @@ QtObject {
|
|||
return msg
|
||||
}
|
||||
|
||||
function getLinkPreviewData(url, uuid) {
|
||||
if(!messageModule)
|
||||
return
|
||||
return messageModule.getLinkPreviewData(url, uuid)
|
||||
}
|
||||
|
||||
function requestMoreMessages() {
|
||||
if(!messageModule)
|
||||
return
|
||||
|
|
|
@ -168,7 +168,7 @@ Item {
|
|||
}
|
||||
|
||||
Connections {
|
||||
enabled: !root.rootStore.privacyModule.urlUnfurlingMode === Constants.UrlUnfurlingModeDisableAll
|
||||
enabled: root.rootStore.privacyModule.urlUnfurlingMode !== Constants.UrlUnfurlingModeDisableAll
|
||||
target: d
|
||||
function onUpdateLinkPreviewsRequested() {
|
||||
d.updateLinkPreviews()
|
||||
|
|
|
@ -34,7 +34,6 @@ QtObject {
|
|||
readonly property string activityCenter: "activityCenter"
|
||||
readonly property string nodeManagement: "nodeManagement"
|
||||
readonly property string onlineUsers: "onlineUsers"
|
||||
readonly property string gifWidget: "gifWidget"
|
||||
readonly property string communitiesPortal: "communitiesPortal"
|
||||
readonly property string communityPermissions: "communityPermissions"
|
||||
readonly property string discordImportTool: "discordImportTool"
|
||||
|
@ -144,9 +143,6 @@ QtObject {
|
|||
else if (feature === experimentalFeatures.onlineUsers) {
|
||||
localAccountSensitiveSettings.showOnlineUsers = !localAccountSensitiveSettings.showOnlineUsers
|
||||
}
|
||||
else if (feature === experimentalFeatures.gifWidget) {
|
||||
localAccountSensitiveSettings.isGifWidgetEnabled = !localAccountSensitiveSettings.isGifWidgetEnabled
|
||||
}
|
||||
}
|
||||
|
||||
function toggleFakeLoadingScreen() {
|
||||
|
|
|
@ -43,8 +43,4 @@ QtObject {
|
|||
}
|
||||
root.syncModule.enableAutomaticSelection(checked)
|
||||
}
|
||||
|
||||
function getLinkPreviewWhitelist() {
|
||||
return root.privacyModule.getLinkPreviewWhitelist()
|
||||
}
|
||||
}
|
||||
|
|
|
@ -342,6 +342,32 @@ SettingsContentBase {
|
|||
}
|
||||
}
|
||||
|
||||
// SYNC WAKU SECTION
|
||||
|
||||
StatusListItem {
|
||||
anchors.left: parent.left
|
||||
anchors.right: parent.right
|
||||
anchors.leftMargin: Style.current.padding
|
||||
anchors.rightMargin: Style.current.padding
|
||||
title: qsTr("History nodes")
|
||||
label: root.messagingStore.getMailserverNameForNodeAddress(root.messagingStore.activeMailserver)
|
||||
components: [
|
||||
StatusIcon {
|
||||
icon: "next"
|
||||
color: Theme.palette.baseColor1
|
||||
}
|
||||
]
|
||||
onClicked: Global.openPopup(wakuStoreModalComponent)
|
||||
}
|
||||
|
||||
Component {
|
||||
id: wakuStoreModalComponent
|
||||
WakuStoreModal {
|
||||
messagingStore: root.messagingStore
|
||||
advancedStore: root.advancedStore
|
||||
}
|
||||
}
|
||||
|
||||
StatusSectionHeadline {
|
||||
anchors.left: parent.left
|
||||
anchors.right: parent.right
|
||||
|
|
|
@ -33,39 +33,6 @@ SettingsContentBase {
|
|||
spacing: 2 * Constants.settingsSection.itemSpacing
|
||||
width: root.contentWidth
|
||||
|
||||
function switchOffPreviewableSites() {
|
||||
//update all models
|
||||
localAccountSensitiveSettings.displayChatImages = false
|
||||
for (let i = 0; i < previewableSites.count; i++) {
|
||||
let item = previewableSites.get(i)
|
||||
RootStore.updateWhitelistedUnfurlingSites(item.address, false)
|
||||
}
|
||||
}
|
||||
|
||||
function buildPreviewablesSitesJSON() {
|
||||
let whitelistAsString = root.messagingStore.getLinkPreviewWhitelist()
|
||||
if(whitelistAsString == "")
|
||||
return
|
||||
|
||||
if (!localAccountSensitiveSettings.whitelistedUnfurlingSites) {
|
||||
localAccountSensitiveSettings.whitelistedUnfurlingSites = {}
|
||||
}
|
||||
|
||||
let anyWhitelisted = false
|
||||
let whitelist = JSON.parse(whitelistAsString)
|
||||
whitelist.forEach(entry => {
|
||||
entry.isWhitelisted = !!localAccountSensitiveSettings.whitelistedUnfurlingSites[entry.address]
|
||||
if(entry.isWhitelisted) anyWhitelisted = true
|
||||
})
|
||||
return [anyWhitelisted, whitelist]
|
||||
}
|
||||
|
||||
function populatePreviewableSites() {
|
||||
const [anyWhitelisted, whitelist] = buildPreviewablesSitesJSON()
|
||||
previewableSites.populateModel(whitelist)
|
||||
previewableSites.anyWhitelisted = anyWhitelisted
|
||||
}
|
||||
|
||||
ButtonGroup {
|
||||
id: showProfilePictureToGroup
|
||||
}
|
||||
|
@ -104,45 +71,7 @@ SettingsContentBase {
|
|||
}
|
||||
}
|
||||
|
||||
// Open Message Links With
|
||||
StatusBaseText {
|
||||
Layout.topMargin: Constants.settingsSection.itemSpacing
|
||||
Layout.fillWidth: true
|
||||
Layout.leftMargin: Style.current.padding
|
||||
Layout.rightMargin: Style.current.padding
|
||||
text: qsTr("Open Message Links With")
|
||||
font.pixelSize: 15
|
||||
color: Theme.palette.directColor1
|
||||
}
|
||||
|
||||
SettingsRadioButton {
|
||||
Layout.fillWidth: true
|
||||
Layout.leftMargin: Style.current.padding
|
||||
Layout.rightMargin: Style.current.padding
|
||||
label: qsTr("Status Browser")
|
||||
group: browserGroup
|
||||
checked: localAccountSensitiveSettings.openLinksInStatus
|
||||
onClicked: {
|
||||
localAccountSensitiveSettings.openLinksInStatus = true
|
||||
}
|
||||
}
|
||||
|
||||
SettingsRadioButton {
|
||||
Layout.topMargin: Constants.settingsSection.itemSpacing / 2
|
||||
Layout.fillWidth: true
|
||||
Layout.leftMargin: Style.current.padding
|
||||
Layout.rightMargin: Style.current.padding
|
||||
label: qsTr("System Default Browser")
|
||||
group: browserGroup
|
||||
checked: !localAccountSensitiveSettings.openLinksInStatus
|
||||
onClicked: {
|
||||
localAccountSensitiveSettings.openLinksInStatus = false
|
||||
}
|
||||
}
|
||||
|
||||
Separator {
|
||||
id: separator1
|
||||
Layout.topMargin: Constants.settingsSection.itemSpacing
|
||||
Layout.fillWidth: true
|
||||
}
|
||||
|
||||
|
@ -239,194 +168,5 @@ SettingsContentBase {
|
|||
root.messagingStore.privacyModule.urlUnfurlingMode = Constants.UrlUnfurlingModeDisableAll
|
||||
}
|
||||
}
|
||||
|
||||
// MESSAGE LINK PREVIEWS
|
||||
StatusListItem {
|
||||
Layout.fillWidth: true
|
||||
objectName: "displayMessageLinkPreviewsItem"
|
||||
title: qsTr("Display Message Link Previews")
|
||||
implicitHeight: 64
|
||||
components: [
|
||||
StatusSwitch {
|
||||
id: showMessageLinksSwitch
|
||||
objectName: "MessagingView_showMessageLinksSwitch"
|
||||
checked: previewableSites.anyWhitelisted || localAccountSensitiveSettings.displayChatImages
|
||||
onToggled: {
|
||||
if (!checked) {
|
||||
generalColumn.switchOffPreviewableSites()
|
||||
}
|
||||
}
|
||||
}
|
||||
]
|
||||
onClicked: {
|
||||
showMessageLinksSwitch.toggle()
|
||||
if (!showMessageLinksSwitch.checked) {
|
||||
generalColumn.switchOffPreviewableSites()
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Component.onCompleted: {
|
||||
populatePreviewableSites()
|
||||
}
|
||||
|
||||
StatusSectionHeadline {
|
||||
id: labelWebsites
|
||||
visible: showMessageLinksSwitch.checked
|
||||
Layout.fillWidth: true
|
||||
Layout.leftMargin: Style.current.padding
|
||||
Layout.rightMargin: Style.current.padding
|
||||
text: qsTr("Fine tune which sites to allow link previews")
|
||||
}
|
||||
|
||||
Column {
|
||||
id: siteColumn
|
||||
visible: showMessageLinksSwitch.checked
|
||||
Layout.fillWidth: true
|
||||
|
||||
ListModel {
|
||||
id: previewableSites
|
||||
function populateModel(jsonModel) {
|
||||
// add/update rows
|
||||
Object.entries(jsonModel)
|
||||
.forEach(([index, newRow]) => {
|
||||
var existingRow = previewableSites.get(index)
|
||||
let isRowIdentical = existingRow != undefined && Object.entries(newRow)
|
||||
.every(([key, value]) => value == existingRow[key])
|
||||
if(!isRowIdentical) {
|
||||
previewableSites.set(index, newRow)
|
||||
}
|
||||
})
|
||||
|
||||
// remove rows that are not in the new model
|
||||
if(previewableSites.count > jsonModel.length) {
|
||||
let rowsToDelete = previewableSites.count - jsonModel.length
|
||||
previewableSites.remove(jsonModel.length - 1, rowsToDelete)
|
||||
}
|
||||
}
|
||||
|
||||
property bool anyWhitelisted: false
|
||||
}
|
||||
|
||||
Connections {
|
||||
target: Global
|
||||
function onSettingsLoaded() {
|
||||
generalColumn.populatePreviewableSites()
|
||||
}
|
||||
}
|
||||
|
||||
Connections {
|
||||
target: localAccountSensitiveSettings
|
||||
function onWhitelistedUnfurlingSitesChanged() {
|
||||
generalColumn.populatePreviewableSites()
|
||||
}
|
||||
}
|
||||
|
||||
// Manually add switch for the image unfurling
|
||||
StatusListItem {
|
||||
objectName: "imageUnfurlingItem"
|
||||
width: parent.width
|
||||
implicitHeight: 64
|
||||
title: qsTr("Image unfurling")
|
||||
subTitle: qsTr("All images (links that contain an image extension) will be downloaded and displayed")
|
||||
// TODO find a better icon for this
|
||||
asset.name: Style.svg('globe')
|
||||
asset.isImage: true
|
||||
components: [
|
||||
StatusSwitch {
|
||||
id: imageSwitch
|
||||
checked: localAccountSensitiveSettings.displayChatImages
|
||||
onToggled: {
|
||||
localAccountSensitiveSettings.displayChatImages = !localAccountSensitiveSettings.displayChatImages
|
||||
}
|
||||
}
|
||||
]
|
||||
onClicked: {
|
||||
localAccountSensitiveSettings.displayChatImages = !localAccountSensitiveSettings.displayChatImages
|
||||
}
|
||||
}
|
||||
|
||||
Repeater {
|
||||
id: sitesListView
|
||||
model: previewableSites
|
||||
|
||||
delegate: Component {
|
||||
StatusListItem {
|
||||
objectName: "MessagingView_sitesListView_StatusListItem_" + model.title.replace(/ /g, "_").toLowerCase()
|
||||
width: parent.width
|
||||
implicitHeight: 64
|
||||
title: model.title
|
||||
subTitle: model.address
|
||||
asset.name: {
|
||||
let filename;
|
||||
switch (model.title.toLowerCase()) {
|
||||
case "youtube":
|
||||
case "youtube shortener":
|
||||
filename = "youtube"; break;
|
||||
case "github":
|
||||
filename = "github"; break;
|
||||
case "medium":
|
||||
filename = "medium"; break;
|
||||
case "tenor gifs subdomain":
|
||||
filename = "tenor"; break;
|
||||
case "giphy gifs":
|
||||
case "giphy gifs shortener":
|
||||
case "giphy gifs subdomain":
|
||||
filename = "giphy"; break;
|
||||
case "github":
|
||||
filename = "github"; break;
|
||||
case "status":
|
||||
filename = "status"; break;
|
||||
// TODO get a good default icon
|
||||
default: filename = "../globe"
|
||||
}
|
||||
return Style.svg(`linkPreviewThumbnails/${filename}`)
|
||||
}
|
||||
asset.isImage: true
|
||||
components: [
|
||||
StatusSwitch {
|
||||
id: siteSwitch
|
||||
checked: !!model.isWhitelisted
|
||||
onToggled: {
|
||||
RootStore.updateWhitelistedUnfurlingSites(model.address, checked)
|
||||
}
|
||||
}
|
||||
]
|
||||
onClicked: {
|
||||
RootStore.updateWhitelistedUnfurlingSites(model.address, !model.isWhitelisted)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
} // Site Column
|
||||
|
||||
Separator {
|
||||
id: separator3
|
||||
visible: siteColumn.visible
|
||||
Layout.fillWidth: true
|
||||
}
|
||||
|
||||
// SYNC WAKU SECTION
|
||||
|
||||
StatusListItem {
|
||||
Layout.fillWidth: true
|
||||
title: qsTr("History nodes")
|
||||
label: root.messagingStore.getMailserverNameForNodeAddress(root.messagingStore.activeMailserver)
|
||||
components: [
|
||||
StatusIcon {
|
||||
icon: "next"
|
||||
color: Theme.palette.baseColor1
|
||||
}
|
||||
]
|
||||
onClicked: Global.openPopup(wakuStoreModalComponent)
|
||||
}
|
||||
|
||||
Component {
|
||||
id: wakuStoreModalComponent
|
||||
WakuStoreModal {
|
||||
messagingStore: root.messagingStore
|
||||
advancedStore: root.advancedStore
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -163,7 +163,7 @@ QtObject {
|
|||
property var savedAddressesModel: walletSectionSavedAddresses.model
|
||||
|
||||
readonly property bool showBrowserSelector: localAccountSensitiveSettings.showBrowserSelector
|
||||
readonly property bool openLinksInStatus: localAccountSensitiveSettings.openLinksInStatus
|
||||
readonly property bool openLinksInStatus: false
|
||||
|
||||
property var allNetworks: networksModule.all
|
||||
|
||||
|
|
|
@ -271,7 +271,7 @@ Item {
|
|||
}
|
||||
|
||||
function onOpenLinkWithConfirmation(link: string, domain: string) {
|
||||
if (appMainLocalSettings.whitelistedUnfurledDomains.includes(domain) || !!localAccountSensitiveSettings.whitelistedUnfurlingSites[domain])
|
||||
if (appMainLocalSettings.whitelistedUnfurledDomains.includes(domain))
|
||||
globalConns.onOpenLink(link)
|
||||
else
|
||||
popups.openConfirmExternalLinkPopup(link, domain)
|
||||
|
@ -1597,55 +1597,6 @@ Item {
|
|||
}
|
||||
}
|
||||
|
||||
Component.onCompleted: {
|
||||
const whitelist = appMain.rootStore.messagingStore.getLinkPreviewWhitelist()
|
||||
try {
|
||||
const whiteListedSites = JSON.parse(whitelist)
|
||||
let settingsUpdated = false
|
||||
|
||||
// Add Status links to whitelist
|
||||
whiteListedSites.push({title: "Status", address: Constants.deepLinkPrefix, imageSite: false})
|
||||
whiteListedSites.push({title: "Status", address: Constants.externalStatusLink, imageSite: false})
|
||||
let settings = localAccountSensitiveSettings.whitelistedUnfurlingSites
|
||||
|
||||
if (!settings) {
|
||||
settings = {}
|
||||
}
|
||||
|
||||
// Set Status links as true. We intercept those URLs so it is privacy-safe
|
||||
if (!settings[Constants.deepLinkPrefix] || !settings[Constants.externalStatusLink]) {
|
||||
settings[Constants.deepLinkPrefix] = true
|
||||
settings[Constants.externalStatusLink] = true
|
||||
settingsUpdated = true
|
||||
}
|
||||
|
||||
const whitelistedHostnames = []
|
||||
|
||||
// Add whitelisted sites in to app settings that are not already there
|
||||
whiteListedSites.forEach(site => {
|
||||
if (!settings.hasOwnProperty(site.address)) {
|
||||
settings[site.address] = false
|
||||
settingsUpdated = true
|
||||
}
|
||||
whitelistedHostnames.push(site.address)
|
||||
})
|
||||
// Remove any whitelisted sites from app settings that don't exist in the
|
||||
// whitelist from status-go
|
||||
Object.keys(settings).forEach(settingsHostname => {
|
||||
if (!whitelistedHostnames.includes(settingsHostname)) {
|
||||
delete settings[settingsHostname]
|
||||
settingsUpdated = true
|
||||
}
|
||||
})
|
||||
if (settingsUpdated) {
|
||||
localAccountSensitiveSettings.whitelistedUnfurlingSites = settings
|
||||
}
|
||||
} catch (e) {
|
||||
console.error('Could not parse the whitelist for sites', e)
|
||||
}
|
||||
Global.settingsLoaded()
|
||||
}
|
||||
|
||||
Loader {
|
||||
id: keycardPopupForAuthentication
|
||||
active: false
|
||||
|
|
|
@ -1472,7 +1472,7 @@ Rectangle {
|
|||
objectName: "gifPopupButton"
|
||||
implicitHeight: 32
|
||||
implicitWidth: 32
|
||||
visible: !isEdit && RootStore.isGifWidgetEnabled
|
||||
visible: !isEdit
|
||||
icon.name: "gif"
|
||||
icon.color: (hovered || highlighted) ? Theme.palette.primaryColor1
|
||||
: Theme.palette.baseColor1
|
||||
|
|
|
@ -61,7 +61,7 @@ Popup {
|
|||
onAboutToShow: {
|
||||
searchBox.text = ""
|
||||
searchBox.input.edit.forceActiveFocus()
|
||||
if (RootStore.isTenorWarningAccepted) {
|
||||
if (RootStore.gifUnfurlingEnabled) {
|
||||
RootStore.getTrendingsGifs()
|
||||
}
|
||||
}
|
||||
|
@ -94,7 +94,7 @@ Popup {
|
|||
SearchBox {
|
||||
id: searchBox
|
||||
placeholderText: qsTr("Search")
|
||||
enabled: RootStore.isTenorWarningAccepted
|
||||
enabled: RootStore.gifUnfurlingEnabled
|
||||
anchors.right: parent.right
|
||||
anchors.rightMargin: gifHeader.headerMargin
|
||||
anchors.top: parent.top
|
||||
|
@ -136,7 +136,7 @@ Popup {
|
|||
|
||||
Loader {
|
||||
id: gifsLoader
|
||||
active: root.opened && RootStore.isTenorWarningAccepted
|
||||
active: root.opened && RootStore.gifUnfurlingEnabled
|
||||
Layout.fillWidth: true
|
||||
Layout.alignment: Qt.AlignTop | Qt.AlignLeft
|
||||
Layout.preferredHeight: {
|
||||
|
@ -160,7 +160,7 @@ Popup {
|
|||
onClicked: {
|
||||
toggleCategory(GifPopupDefinitions.Category.Trending)
|
||||
}
|
||||
enabled: RootStore.isTenorWarningAccepted
|
||||
enabled: RootStore.gifUnfurlingEnabled
|
||||
}
|
||||
|
||||
StatusTabBarIconButton {
|
||||
|
@ -169,7 +169,7 @@ Popup {
|
|||
onClicked: {
|
||||
toggleCategory(GifPopupDefinitions.Category.Recent)
|
||||
}
|
||||
enabled: RootStore.isTenorWarningAccepted
|
||||
enabled: RootStore.gifUnfurlingEnabled
|
||||
}
|
||||
|
||||
StatusTabBarIconButton {
|
||||
|
@ -178,7 +178,7 @@ Popup {
|
|||
onClicked: {
|
||||
toggleCategory(GifPopupDefinitions.Category.Favorite)
|
||||
}
|
||||
enabled: RootStore.isTenorWarningAccepted
|
||||
enabled: RootStore.gifUnfurlingEnabled
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -200,7 +200,7 @@ Popup {
|
|||
sourceComponent: ConfirmationPopup {
|
||||
visible: true
|
||||
}
|
||||
active: !RootStore.isTenorWarningAccepted
|
||||
active: !RootStore.gifUnfurlingEnabled
|
||||
}
|
||||
|
||||
Component {
|
||||
|
|
|
@ -79,8 +79,7 @@ Popup {
|
|||
size: StatusBaseButton.Size.Small
|
||||
|
||||
onClicked: {
|
||||
RootStore.setIsTenorWarningAccepted(true)
|
||||
RootStore.updateWhitelistedUnfurlingSites("media.tenor.com", true)
|
||||
RootStore.setGifUnfurlingEnabled(true)
|
||||
RootStore.getTrendingsGifs()
|
||||
root.close()
|
||||
}
|
||||
|
|
|
@ -17,9 +17,7 @@ QtObject {
|
|||
|
||||
property bool notificationSoundsEnabled: !!appSettingsInst ? appSettingsInst.notificationSoundsEnabled : true
|
||||
property bool neverAskAboutUnfurlingAgain: !!accountSensitiveSettings ? accountSensitiveSettings.neverAskAboutUnfurlingAgain : false
|
||||
property bool isGifWidgetEnabled: !!accountSensitiveSettings ? accountSensitiveSettings.isGifWidgetEnabled : false
|
||||
property bool isTenorWarningAccepted: !!accountSensitiveSettings ? accountSensitiveSettings.isTenorWarningAccepted : false
|
||||
property bool displayChatImages: !!accountSensitiveSettings ? accountSensitiveSettings.displayChatImages : false
|
||||
property bool gifUnfurlingEnabled: !!accountSensitiveSettings ? accountSensitiveSettings.gifUnfurlingEnabled : false
|
||||
|
||||
property CurrenciesStore currencyStore: CurrenciesStore {}
|
||||
property string currentCurrency: Global.appIsReady? walletSectionInst.currentCurrency : ""
|
||||
|
@ -93,8 +91,8 @@ QtObject {
|
|||
localAccountSensitiveSettings.neverAskAboutUnfurlingAgain = value;
|
||||
}
|
||||
|
||||
function setIsTenorWarningAccepted(value) {
|
||||
localAccountSensitiveSettings.isTenorWarningAccepted = value;
|
||||
function setGifUnfurlingEnabled(value) {
|
||||
localAccountSensitiveSettings.gifUnfurlingEnabled = value
|
||||
}
|
||||
|
||||
function copyToClipboard(text) {
|
||||
|
@ -122,22 +120,6 @@ QtObject {
|
|||
chatSectionChatContentInputAreaInst.getTrendingsGifs()
|
||||
}
|
||||
|
||||
function updateWhitelistedUnfurlingSites(hostname, whitelisted) {
|
||||
// no way to send update notification for individual array entries
|
||||
let settings = localAccountSensitiveSettings.whitelistedUnfurlingSites
|
||||
|
||||
if (!settings)
|
||||
settings = {}
|
||||
|
||||
if (settings[hostname] === whitelisted)
|
||||
return
|
||||
|
||||
settings[hostname] = whitelisted
|
||||
localAccountSensitiveSettings.whitelistedUnfurlingSites = settings
|
||||
if(hostname === "media.tenor.com" && whitelisted === false)
|
||||
RootStore.setIsTenorWarningAccepted(false)
|
||||
}
|
||||
|
||||
function getRecentsGifs() {
|
||||
if (chatSectionChatContentInputAreaInst)
|
||||
chatSectionChatContentInputAreaInst.getRecentsGifs()
|
||||
|
|
|
@ -20,7 +20,7 @@ Flow {
|
|||
required property var messageStore
|
||||
|
||||
required property var linkPreviewModel
|
||||
required property var localUnfurlLinks
|
||||
required property var gifLinks
|
||||
|
||||
required property bool isCurrentUser
|
||||
|
||||
|
@ -29,57 +29,31 @@ Flow {
|
|||
|
||||
signal imageClicked(var image, var mouse, var imageSource, string url)
|
||||
|
||||
function resetLocalAskAboutUnfurling() {
|
||||
d.localAskAboutUnfurling = true
|
||||
}
|
||||
|
||||
spacing: 12
|
||||
|
||||
//TODO: remove once GIF previews are unfurled sender side
|
||||
Repeater {
|
||||
|
||||
QtObject {
|
||||
id: d
|
||||
property bool localAskAboutUnfurling: true
|
||||
}
|
||||
|
||||
Loader {
|
||||
visible: active
|
||||
active: root.gifLinks && root.gifLinks.length > 0
|
||||
&& !RootStore.gifUnfurlingEnabled
|
||||
&& d.localAskAboutUnfurling && !RootStore.neverAskAboutUnfurlingAgain
|
||||
sourceComponent: enableLinkComponent
|
||||
}
|
||||
|
||||
Repeater {
|
||||
id: tempRepeater
|
||||
visible: !RootStore.neverAskAboutUnfurlingAgain
|
||||
model: linksModel
|
||||
|
||||
delegate: Loader {
|
||||
id: tempLoader
|
||||
|
||||
required property var result
|
||||
required property string link
|
||||
required property int index
|
||||
required property bool unfurl
|
||||
required property bool success
|
||||
required property bool isStatusDeepLink
|
||||
readonly property bool isImage: result.contentType && result.contentType.startsWith("image/") ? true : false
|
||||
readonly property bool isUserProfileLink: link.toLowerCase().startsWith(Constants.userLinkPrefix.toLowerCase())
|
||||
readonly property string thumbnailUrl: result && result.thumbnailUrl ? result.thumbnailUrl : ""
|
||||
readonly property string title: result && result.title ? result.title : ""
|
||||
readonly property string hostname: result && result.site ? result.site : ""
|
||||
readonly property bool animated: isImage && result.contentType === "image/gif" // TODO support more types of animated images?
|
||||
|
||||
StateGroup {
|
||||
//Using StateGroup as a warkardound for https://bugreports.qt.io/browse/QTBUG-47796
|
||||
id: linkPreviewLoaderState
|
||||
states: [
|
||||
State {
|
||||
name: "askToEnableUnfurling"
|
||||
when: !tempLoader.unfurl
|
||||
PropertyChanges { target: tempLoader; sourceComponent: enableLinkComponent }
|
||||
},
|
||||
State {
|
||||
name: "loadImage"
|
||||
when: tempLoader.unfurl && tempLoader.isImage
|
||||
PropertyChanges { target: tempLoader; sourceComponent: unfurledImageComponent }
|
||||
},
|
||||
State {
|
||||
name: "userProfileLink"
|
||||
when: unfurl && isUserProfileLink && isStatusDeepLink
|
||||
PropertyChanges { target: tempLoader; sourceComponent: unfurledProfileLinkComponent }
|
||||
}
|
||||
// State {
|
||||
// name: "statusInvitation"
|
||||
// when: unfurl && isStatusDeepLink
|
||||
// PropertyChanges { target: tempLoader; sourceComponent: invitationBubble }
|
||||
// }
|
||||
]
|
||||
}
|
||||
}
|
||||
model: RootStore.gifUnfurlingEnabled ? gifLinks : []
|
||||
delegate: gifComponent
|
||||
}
|
||||
|
||||
Repeater {
|
||||
|
@ -117,7 +91,6 @@ Flow {
|
|||
readonly property int thumbnailHeight: standardPreviewThumbnail ? standardPreviewThumbnail.height : ""
|
||||
readonly property string thumbnailUrl: standardPreviewThumbnail ? standardPreviewThumbnail.url : ""
|
||||
readonly property string thumbnailDataUri: standardPreviewThumbnail ? standardPreviewThumbnail.dataUri : ""
|
||||
property bool animated: false
|
||||
|
||||
asynchronous: true
|
||||
active: unfurled && !empty
|
||||
|
@ -180,7 +153,7 @@ Flow {
|
|||
|
||||
//TODO: Remove this once we have gif support in new unfurling flow
|
||||
Component {
|
||||
id: unfurledImageComponent
|
||||
id: gifComponent
|
||||
CalloutCard {
|
||||
implicitWidth: linkImage.width
|
||||
implicitHeight: linkImage.height
|
||||
|
@ -188,19 +161,19 @@ Flow {
|
|||
StatusChatImageLoader {
|
||||
id: linkImage
|
||||
readonly property bool globalAnimationEnabled: root.messageStore.playAnimation
|
||||
readonly property string urlLink: link
|
||||
readonly property string urlLink: modelData
|
||||
property bool localAnimationEnabled: true
|
||||
objectName: "LinksMessageView_unfurledImageComponent_linkImage"
|
||||
anchors.centerIn: parent
|
||||
source: thumbnailUrl
|
||||
source: urlLink
|
||||
imageWidth: 300
|
||||
isCurrentUser: root.isCurrentUser
|
||||
playing: globalAnimationEnabled && localAnimationEnabled
|
||||
isOnline: root.store.mainModuleInst.isOnline
|
||||
asynchronous: true
|
||||
isAnimated: animated
|
||||
isAnimated: true
|
||||
onClicked: {
|
||||
if (isAnimated && !playing)
|
||||
if (!playing)
|
||||
localAnimationEnabled = true
|
||||
else
|
||||
root.imageClicked(linkImage.imageAlias, mouse, source, urlLink)
|
||||
|
@ -239,86 +212,19 @@ Flow {
|
|||
}
|
||||
}
|
||||
}
|
||||
// Code below can be dropped when New unfurling flow suppports GIFs.
|
||||
Component {
|
||||
id: invitationBubble
|
||||
InvitationBubbleView {
|
||||
property var invitationData: root.store.getLinkDataForStatusLinks(link)
|
||||
store: root.store
|
||||
communityId: invitationData && invitationData.communityData ? invitationData.communityData.communityId : ""
|
||||
communityData: invitationData && invitationData.communityData ? invitationData.communityData : null
|
||||
anchors.left: parent.left
|
||||
visible: !!invitationData
|
||||
loading: invitationData.fetching
|
||||
onInvitationDataChanged: {
|
||||
if (!invitationData)
|
||||
linksModel.remove(index)
|
||||
}
|
||||
Connections {
|
||||
enabled: !!invitationData && invitationData.fetching
|
||||
target: root.store.communitiesModuleInst
|
||||
function onCommunityAdded(communityId: string) {
|
||||
if (communityId !== invitationData.communityId) return
|
||||
invitationData = root.store.getLinkDataForStatusLinks(link)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
QtObject {
|
||||
id: d
|
||||
readonly property string uuid: Utils.uuid()
|
||||
readonly property string whiteListedImgExtensions: Constants.acceptedImageExtensions.toString()
|
||||
readonly property string whiteListedUrls: JSON.stringify(localAccountSensitiveSettings.whitelistedUnfurlingSites)
|
||||
readonly property string getLinkPreviewDataId: {
|
||||
if (root.localUnfurlLinks === "")
|
||||
return ""
|
||||
return root.messageStore.messageModule.getLinkPreviewData(root.localUnfurlLinks,
|
||||
d.uuid,
|
||||
whiteListedUrls,
|
||||
whiteListedImgExtensions,
|
||||
localAccountSensitiveSettings.displayChatImages)
|
||||
}
|
||||
onGetLinkPreviewDataIdChanged: {
|
||||
linkFetchConnections.enabled = root.localUnfurlLinks !== ""
|
||||
}
|
||||
}
|
||||
Connections {
|
||||
id: linkFetchConnections
|
||||
enabled: false
|
||||
target: root.messageStore.messageModule
|
||||
function onLinkPreviewDataWasReceived(previewData, uuid) {
|
||||
if (d.uuid !== uuid)
|
||||
return
|
||||
linkFetchConnections.enabled = false
|
||||
try {
|
||||
linksModel.rawData = JSON.parse(previewData)
|
||||
}
|
||||
catch(e) {
|
||||
console.warn("error parsing link preview data", previewData)
|
||||
}
|
||||
}
|
||||
}
|
||||
ListModel {
|
||||
id: linksModel
|
||||
property var rawData
|
||||
onRawDataChanged: {
|
||||
linksModel.clear()
|
||||
rawData.links.forEach((link) => {
|
||||
linksModel.append(link)
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
Component {
|
||||
id: enableLinkComponent
|
||||
|
||||
Rectangle {
|
||||
id: enableLinkRoot
|
||||
width: 300
|
||||
height: childrenRect.height + Style.current.smallPadding
|
||||
implicitWidth: 300
|
||||
implicitHeight: childrenRect.height + Style.current.smallPadding
|
||||
radius: 16
|
||||
border.width: 1
|
||||
border.color: Style.current.border
|
||||
color: Style.current.background
|
||||
|
||||
StatusFlatRoundButton {
|
||||
anchors.top: parent.top
|
||||
anchors.topMargin: Style.current.smallPadding
|
||||
|
@ -327,7 +233,7 @@ Flow {
|
|||
icon.width: 20
|
||||
icon.height: 20
|
||||
icon.name: "close-circle"
|
||||
onClicked: linksModel.remove(index)
|
||||
onClicked: d.localAskAboutUnfurling = false
|
||||
}
|
||||
Image {
|
||||
id: unfurlingImage
|
||||
|
@ -340,8 +246,7 @@ Flow {
|
|||
}
|
||||
StatusBaseText {
|
||||
id: enableText
|
||||
text: isImage ? qsTr("Enable automatic image unfurling") :
|
||||
qsTr("Enable link previews in chat?")
|
||||
text: qsTr("Enable automatic GIF unfurling")
|
||||
horizontalAlignment: Text.AlignHCenter
|
||||
width: parent.width
|
||||
wrapMode: Text.WordWrap
|
||||
|
@ -398,7 +303,7 @@ Flow {
|
|||
anchors.centerIn: parent
|
||||
anchors.verticalCenterOffset: Style.current.halfPadding
|
||||
font: dontAskBtn.font
|
||||
color: dontAskBtn.enabled ? dontAskBtn.textColor : dontAskBtn.disabledTextColor
|
||||
color: dontAskBtn.textColor
|
||||
text: qsTr("Don't ask me again")
|
||||
}
|
||||
}
|
||||
|
|
|
@ -66,19 +66,11 @@ Loader {
|
|||
|
||||
// These 2 properties can be dropped when the new unfurling flow supports GIFs
|
||||
property var links
|
||||
readonly property var localUnfurlLinks: {
|
||||
readonly property var gifLinks: {
|
||||
if (!links)
|
||||
return []
|
||||
const separator = " "
|
||||
const arr = links.split(separator)
|
||||
const filtered = arr.filter(value => {
|
||||
const v = value.toLowerCase()
|
||||
return localAccountSensitiveSettings.gifUnfurlingEnabled && value.endsWith('.gif')
|
||||
})
|
||||
|
||||
|
||||
const out = filtered.join(separator)
|
||||
return out
|
||||
const arr = links.split(" ")
|
||||
return arr.filter(value => value.toLowerCase().endsWith('.gif'))
|
||||
}
|
||||
|
||||
property string responseToMessageWithId: ""
|
||||
|
@ -535,7 +527,7 @@ Loader {
|
|||
resendError: root.resendError
|
||||
reactionsModel: root.reactionsModel
|
||||
linkPreviewModel: root.linkPreviewModel
|
||||
localUnfurlLinks: root.localUnfurlLinks
|
||||
gifLinks: root.gifLinks
|
||||
|
||||
showHeader: root.shouldRepeatHeader || dateGroupLabel.visible || isAReply ||
|
||||
root.prevMessageContentType === Constants.messageContentType.systemMessagePrivateGroupType ||
|
||||
|
@ -762,7 +754,7 @@ Loader {
|
|||
LinksMessageView {
|
||||
id: linksMessageView
|
||||
linkPreviewModel: root.linkPreviewModel
|
||||
localUnfurlLinks: root.localUnfurlLinks
|
||||
gifLinks: root.gifLinks
|
||||
messageStore: root.messageStore
|
||||
store: root.rootStore
|
||||
isCurrentUser: root.amISender
|
||||
|
|
|
@ -943,7 +943,6 @@ QtObject {
|
|||
readonly property int maxNumberOfPins: 3
|
||||
|
||||
readonly property string dataImagePrefix: "data:image"
|
||||
readonly property var acceptedImageExtensions: [".png", ".jpg", ".jpeg", ".svg", ".gif"]
|
||||
readonly property var acceptedDragNDropImageExtensions: [".png", ".jpg", ".jpeg", ".heif", ".tif", ".tiff"]
|
||||
|
||||
readonly property string mentionSpanTag: `<span style="background-color: ${Style.current.mentionBgColor};"><a style="color:${Style.current.mentionColor};text-decoration:none" href='http://'>`
|
||||
|
|
|
@ -18,7 +18,6 @@ QtObject {
|
|||
|
||||
signal openLinkInBrowser(string link)
|
||||
signal openChooseBrowserPopup(string link)
|
||||
signal settingsLoaded()
|
||||
signal openCreateChatView()
|
||||
signal closeCreateChatView()
|
||||
|
||||
|
|
|
@ -322,10 +322,6 @@ QtObject {
|
|||
return link.includes(Constants.deepLinkPrefix) || link.includes(Constants.externalStatusLink)
|
||||
}
|
||||
|
||||
function hasImageExtension(url) {
|
||||
return Constants.acceptedImageExtensions.some(ext => url.toLowerCase().includes(ext))
|
||||
}
|
||||
|
||||
function removeGifUrls(message) {
|
||||
return message.replace(/(?:https?|ftp):\/\/[\n\S]*(\.gif)+/gm, '');
|
||||
}
|
||||
|
|
|
@ -204,9 +204,6 @@ StatusWindow {
|
|||
if(localAccountSensitiveSettings.recentEmojis === "") {
|
||||
localAccountSensitiveSettings.recentEmojis = [];
|
||||
}
|
||||
if (localAccountSensitiveSettings.whitelistedUnfurlingSites === "") {
|
||||
localAccountSensitiveSettings.whitelistedUnfurlingSites = {};
|
||||
}
|
||||
if (localAccountSensitiveSettings.hiddenCommunityWelcomeBanners === "") {
|
||||
localAccountSensitiveSettings.hiddenCommunityWelcomeBanners = [];
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue