Add image previews in HTML messages
This commit is contained in:
parent
d353e5bf6e
commit
c4f46f42b6
2
TODO.md
2
TODO.md
|
@ -28,3 +28,5 @@
|
|||
- `<pre>` scrollbar on overflow
|
||||
|
||||
- Make links in room subtitle clickable, formatting?
|
||||
|
||||
- Push instead of replacing in stack view
|
||||
|
|
|
@ -4,7 +4,7 @@
|
|||
import re
|
||||
|
||||
import html_sanitizer.sanitizer as sanitizer
|
||||
from lxml.html import HtmlElement
|
||||
from lxml.html import HtmlElement, etree
|
||||
from PyQt5.QtCore import QObject, pyqtProperty, pyqtSlot
|
||||
|
||||
|
||||
|
@ -39,8 +39,20 @@ class HtmlFilter(QObject):
|
|||
|
||||
|
||||
@pyqtSlot(str, result=str)
|
||||
def sanitize(self, html: str) -> str:
|
||||
return self._sanitizer.sanitize(html)
|
||||
def filter(self, html: str) -> str:
|
||||
html = self._sanitizer.sanitize(html)
|
||||
if not html:
|
||||
return ""
|
||||
|
||||
tree = etree.fromstring(html, parser=etree.HTMLParser())
|
||||
|
||||
for el in tree.iter("img"):
|
||||
el = self._wrap_img_in_a(el)
|
||||
|
||||
for el in tree.iter("a"):
|
||||
el = self._append_img_to_a(el)
|
||||
|
||||
return str(etree.tostring(tree[0][0], encoding="utf-8"), "utf-8")
|
||||
|
||||
|
||||
@pyqtProperty("QVariant")
|
||||
|
@ -73,7 +85,7 @@ class HtmlFilter(QObject):
|
|||
"link_regexes": self.link_regexes,
|
||||
"avoid_hosts": [],
|
||||
},
|
||||
"sanitize_href": sanitizer.sanitize_href,
|
||||
"sanitize_href": lambda href: href,
|
||||
"element_preprocessors": [
|
||||
sanitizer.bold_span_to_strong,
|
||||
sanitizer.italic_span_to_em,
|
||||
|
@ -101,3 +113,39 @@ class HtmlFilter(QObject):
|
|||
el.clear()
|
||||
|
||||
return el
|
||||
|
||||
|
||||
def _wrap_img_in_a(self, el: HtmlElement) -> HtmlElement:
|
||||
link = el.attrib.get("src", "")
|
||||
width = el.attrib.get("width", "256")
|
||||
height = el.attrib.get("height", "256")
|
||||
|
||||
if el.getparent().tag == "a" or el.tag != "img" or \
|
||||
not self._is_image_path(link):
|
||||
return el
|
||||
|
||||
el.tag = "a"
|
||||
el.attrib.clear()
|
||||
el.attrib["href"] = link
|
||||
el.append(etree.Element("img", src=link, width=width, height=height))
|
||||
return el
|
||||
|
||||
|
||||
def _append_img_to_a(self, el: HtmlElement) -> HtmlElement:
|
||||
link = el.attrib.get("href", "")
|
||||
|
||||
if not (el.tag == "a" and self._is_image_path(link)):
|
||||
return el
|
||||
|
||||
for _ in el.iter("img"): # if the <a> already has an <img> child
|
||||
return el
|
||||
|
||||
el.append(etree.Element("img", src=link, width="256", height="256"))
|
||||
return el
|
||||
|
||||
|
||||
@staticmethod
|
||||
def _is_image_path(link: str) -> bool:
|
||||
return bool(re.match(
|
||||
r".+\.(jpg|jpeg|png|gif|bmp|webp|tiff|svg)$", link, re.IGNORECASE
|
||||
))
|
||||
|
|
|
@ -39,7 +39,7 @@ Row {
|
|||
// (isOwn ? " " + content : "")
|
||||
|
||||
text: (dict.formatted_body ?
|
||||
Backend.htmlFilter.sanitize(dict.formatted_body) :
|
||||
Backend.htmlFilter.filter(dict.formatted_body) :
|
||||
dict.body) +
|
||||
" <font size=" + smallSize + "px color=gray>" +
|
||||
Qt.formatDateTime(date_time, "hh:mm:ss") +
|
||||
|
|
|
@ -20,5 +20,9 @@ Rectangle {
|
|||
clip: true
|
||||
topMargin: space
|
||||
bottomMargin: space
|
||||
|
||||
// Keep x scroll pages cached, to limit images having to be
|
||||
// reloaded from network.
|
||||
cacheBuffer: height * 6
|
||||
}
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue
Block a user