fix(LinkPreviews): Fixing gif hyperlink detection in StatusChatInput
The link preview model can be filtered, but the hyperlink detection needs an unfiltered model to properly highlight all URLs. This brought in the need to separate the urls model and the link previews model.
This commit is contained in:
parent
b9867c2463
commit
8ac6eb8916
|
@ -111,7 +111,7 @@ proc setLinkPreviewEnabledForThisMessage*(self: Controller, enabled: bool) =
|
|||
self.delegate.setAskToEnableLinkPreview(false)
|
||||
|
||||
proc resetLinkPreviews(self: Controller) =
|
||||
self.delegate.setUrls(@[])
|
||||
self.delegate.setLinkPreviewUrls(@[])
|
||||
self.linkPreviewCache.clear()
|
||||
self.linkPreviewCurrentMessageSetting = self.linkPreviewPersistentSetting
|
||||
self.delegate.setAskToEnableLinkPreview(false)
|
||||
|
@ -201,12 +201,15 @@ proc canAskToEnableLinkPreview(self: Controller): bool =
|
|||
proc setText*(self: Controller, text: string, unfurlNewUrls: bool) =
|
||||
if text == "":
|
||||
self.resetLinkPreviews()
|
||||
self.delegate.setUrls(@[])
|
||||
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)
|
||||
self.delegate.setLinkPreviewUrls(supportedUrls)
|
||||
let newUrls = self.linkPreviewCache.unknownUrls(supportedUrls)
|
||||
|
||||
let askToEnableLinkPreview = len(newUrls) > 0 and self.canAskToEnableLinkPreview()
|
||||
self.delegate.setAskToEnableLinkPreview(askToEnableLinkPreview)
|
||||
|
|
|
@ -102,7 +102,7 @@ method setText*(self: AccessInterface, text: string, unfurlUrls: bool) {.base.}
|
|||
method getPlainText*(self: AccessInterface): string =
|
||||
raise newException(ValueError, "No implementation available")
|
||||
|
||||
method setUrls*(self: AccessInterface, urls: seq[string]) {.base.} =
|
||||
method setLinkPreviewUrls*(self: AccessInterface, urls: seq[string]) {.base.} =
|
||||
raise newException(ValueError, "No implementation available")
|
||||
|
||||
method updateLinkPreviewsFromCache*(self: AccessInterface, urls: seq[string]) {.base.} =
|
||||
|
@ -128,3 +128,6 @@ method setAskToEnableLinkPreview*(self: AccessInterface, value: bool) =
|
|||
|
||||
method setLinkPreviewEnabledForThisMessage*(self: AccessInterface, enabled: bool) =
|
||||
raise newException(ValueError, "No implementation available")
|
||||
|
||||
method setUrls*(self: AccessInterface, urls: seq[string]) {.base.} =
|
||||
raise newException(ValueError, "No implementation available")
|
||||
|
|
|
@ -166,8 +166,8 @@ method clearLinkPreviewCache*(self: Module) {.slot.} =
|
|||
method updateLinkPreviewsFromCache*(self: Module, urls: seq[string]) =
|
||||
self.view.updateLinkPreviewsFromCache(urls)
|
||||
|
||||
method setUrls*(self: Module, urls: seq[string]) =
|
||||
self.view.setUrls(urls)
|
||||
method setLinkPreviewUrls*(self: Module, urls: seq[string]) =
|
||||
self.view.setLinkPreviewUrls(urls)
|
||||
|
||||
method linkPreviewsFromCache*(self: Module, urls: seq[string]): Table[string, LinkPreview] =
|
||||
return self.controller.linkPreviewsFromCache(urls)
|
||||
|
@ -186,3 +186,6 @@ method setAskToEnableLinkPreview*(self: Module, value: bool) =
|
|||
|
||||
method setLinkPreviewEnabledForThisMessage*(self: Module, value: bool) =
|
||||
self.controller.setLinkPreviewEnabledForThisMessage(value)
|
||||
|
||||
method setUrls*(self: Module, urls: seq[string]) =
|
||||
self.view.setUrls(urls)
|
||||
|
|
|
@ -0,0 +1,94 @@
|
|||
import NimQml, tables, sequtils
|
||||
|
||||
type
|
||||
ModelRole {.pure.} = enum
|
||||
Url = UserRole + 1
|
||||
|
||||
QtObject:
|
||||
type
|
||||
Model* = ref object of QAbstractListModel
|
||||
items: seq[string]
|
||||
|
||||
proc delete*(self: Model) =
|
||||
self.items = @[]
|
||||
self.QAbstractListModel.delete
|
||||
|
||||
proc setup(self: Model) =
|
||||
self.QAbstractListModel.setup
|
||||
|
||||
proc newUrlsModel*(): Model =
|
||||
new(result, delete)
|
||||
result.setup
|
||||
|
||||
proc countChanged(self: Model) {.signal.}
|
||||
|
||||
proc getCount*(self: Model): int {.slot.} =
|
||||
self.items.len
|
||||
|
||||
QtProperty[int] count:
|
||||
read = getCount
|
||||
notify = countChanged
|
||||
|
||||
method rowCount(self: Model, index: QModelIndex = nil): int =
|
||||
return self.items.len
|
||||
|
||||
method roleNames(self: Model): Table[int, string] =
|
||||
{
|
||||
ModelRole.Url.int:"url"
|
||||
}.toTable
|
||||
|
||||
method data(self: Model, index: QModelIndex, role: int): QVariant =
|
||||
if (not index.isValid):
|
||||
return
|
||||
|
||||
if (index.row < 0 or index.row >= self.items.len):
|
||||
return
|
||||
|
||||
let enumRole = role.ModelRole
|
||||
|
||||
case enumRole:
|
||||
of ModelRole.Url:
|
||||
let item = self.items[index.row]
|
||||
result = newQVariant(item)
|
||||
else:
|
||||
result = newQVariant()
|
||||
|
||||
proc removeItemWithIndex(self: Model, ind: int) =
|
||||
if(ind < 0 or ind >= self.items.len):
|
||||
return
|
||||
|
||||
let parentModelIndex = newQModelIndex()
|
||||
defer: parentModelIndex.delete
|
||||
|
||||
self.beginRemoveRows(parentModelIndex, ind, ind)
|
||||
self.items.delete(ind)
|
||||
self.endRemoveRows()
|
||||
|
||||
proc setUrls*(self: Model, urls: seq[string]) =
|
||||
var itemsToInsert: seq[string]
|
||||
var indexesToRemove: seq[int]
|
||||
|
||||
#remove
|
||||
for i in 0 ..< self.items.len:
|
||||
if not urls.anyIt(it == self.items[i]):
|
||||
indexesToRemove.add(i)
|
||||
|
||||
while indexesToRemove.len > 0:
|
||||
let index = pop(indexesToRemove)
|
||||
self.removeItemWithIndex(index)
|
||||
|
||||
# Move or insert
|
||||
for i in 0 ..< urls.len:
|
||||
if self.items.anyIt(it == urls[i]):
|
||||
continue
|
||||
itemsToInsert.add(urls[i])
|
||||
|
||||
|
||||
if itemsToInsert.len > 0:
|
||||
let parentModelIndex = newQModelIndex()
|
||||
defer: parentModelIndex.delete
|
||||
self.beginInsertRows(parentModelIndex, self.items.len, self.items.len + itemsToInsert.len - 1)
|
||||
self.items = self.items & itemsToInsert
|
||||
self.endInsertRows()
|
||||
|
||||
self.countChanged()
|
|
@ -2,6 +2,7 @@ import NimQml
|
|||
import ./io_interface
|
||||
import ./gif_column_model
|
||||
import ./preserved_properties
|
||||
import ./urls_model
|
||||
import ../../../../../../app/modules/shared_models/link_preview_model as link_preview_model
|
||||
import ../../../../../../app_service/service/gif/dto
|
||||
|
||||
|
@ -17,6 +18,8 @@ QtObject:
|
|||
preservedPropertiesVariant: QVariant
|
||||
linkPreviewModel: link_preview_model.Model
|
||||
linkPreviewModelVariant: QVariant
|
||||
urlsModel: urls_model.Model
|
||||
urlsModelVariant: QVariant
|
||||
askToEnableLinkPreview: bool
|
||||
|
||||
proc delete*(self: View) =
|
||||
|
@ -24,10 +27,12 @@ QtObject:
|
|||
self.gifColumnAModel.delete
|
||||
self.gifColumnBModel.delete
|
||||
self.gifColumnCModel.delete
|
||||
self.preservedProperties.delete
|
||||
self.preservedPropertiesVariant.delete
|
||||
self.linkPreviewModel.delete
|
||||
self.preservedProperties.delete
|
||||
self.linkPreviewModelVariant.delete
|
||||
self.linkPreviewModel.delete
|
||||
self.urlsModelVariant.delete
|
||||
self.urlsModel.delete
|
||||
|
||||
proc newView*(delegate: io_interface.AccessInterface): View =
|
||||
new(result, delete)
|
||||
|
@ -41,6 +46,8 @@ QtObject:
|
|||
result.preservedPropertiesVariant = newQVariant(result.preservedProperties)
|
||||
result.linkPreviewModel = newLinkPreviewModel()
|
||||
result.linkPreviewModelVariant = newQVariant(result.linkPreviewModel)
|
||||
result.urlsModel = newUrlsModel()
|
||||
result.urlsModelVariant = newQVariant(result.urlsModel)
|
||||
result.askToEnableLinkPreview = false
|
||||
|
||||
proc load*(self: View) =
|
||||
|
@ -223,7 +230,7 @@ QtObject:
|
|||
let linkPreviews = self.delegate.linkPreviewsFromCache(urls)
|
||||
self.linkPreviewModel.updateLinkPreviews(linkPreviews)
|
||||
|
||||
proc setUrls*(self: View, urls: seq[string]) =
|
||||
proc setLinkPreviewUrls*(self: View, urls: seq[string]) =
|
||||
self.linkPreviewModel.setUrls(urls)
|
||||
if(self.delegate.getLinkPreviewEnabled()):
|
||||
self.updateLinkPreviewsFromCache(urls)
|
||||
|
@ -253,8 +260,19 @@ QtObject:
|
|||
self.delegate.setLinkPreviewEnabledForThisMessage(enabled)
|
||||
let links = self.linkPreviewModel.getLinks()
|
||||
self.linkPreviewModel.clearItems()
|
||||
self.setUrls(links)
|
||||
self.setLinkPreviewUrls(links)
|
||||
self.loadLinkPreviews(links)
|
||||
|
||||
proc removeLinkPreviewData*(self: View, index: int) {.slot.} =
|
||||
self.linkPreviewModel.removePreviewData(index)
|
||||
|
||||
proc urlsModelChanged(self: View) {.signal.}
|
||||
proc getUrlsModel*(self: View): QVariant {.slot.} =
|
||||
return self.urlsModelVariant
|
||||
|
||||
proc setUrls*(self: View, urls: seq[string]) =
|
||||
self.urlsModel.setUrls(urls)
|
||||
|
||||
QtProperty[QVariant] urlsModel:
|
||||
read = getUrlsModel
|
||||
notify = urlsModelChanged
|
||||
|
|
|
@ -112,6 +112,7 @@ SplitView {
|
|||
|
||||
enabled: enabledCheckBox.checked
|
||||
linkPreviewModel: fakeLinksModel
|
||||
urlsModel: fakeLinksModel
|
||||
askToEnableLinkPreview: askToEnableLinkPreviewSwitch.checked
|
||||
onAskToEnableLinkPreviewChanged: {
|
||||
if(askToEnableLinkPreview) {
|
||||
|
|
|
@ -255,6 +255,7 @@ Item {
|
|||
store: root.rootStore
|
||||
usersStore: d.activeUsersStore
|
||||
linkPreviewModel: d.activeChatContentModule.inputAreaModule.linkPreviewModel
|
||||
urlsModel: d.activeChatContentModule.inputAreaModule.urlsModel
|
||||
askToEnableLinkPreview: {
|
||||
if(!d.activeChatContentModule || !d.activeChatContentModule.inputAreaModule || !d.activeChatContentModule.inputAreaModule.preservedProperties)
|
||||
return false
|
||||
|
|
|
@ -65,6 +65,8 @@ Rectangle {
|
|||
|
||||
property var linkPreviewModel: null
|
||||
|
||||
property var urlsModel: null
|
||||
|
||||
property bool askToEnableLinkPreview: false
|
||||
|
||||
property var imageErrorMessageLocation: StatusChatInput.ImageErrorMessageLocation.Top // TODO: Remove this property?
|
||||
|
@ -1366,7 +1368,7 @@ Rectangle {
|
|||
TextEditHyperlinksFormatter {
|
||||
id: hyperlinksFormatter
|
||||
textEdit: messageInputField
|
||||
urlModel: control.linkPreviewModel
|
||||
urlModel: control.urlsModel
|
||||
highlightUrl: linkPreviewArea.hoveredUrl
|
||||
enabled: messageInputField.enabled && messageInputField.textFormat == TextEdit.RichText
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue