Fix loading m.image events in encrypted rooms
Fix bug introduced in 11fb32: When loading an encrypted thumbnail, QML lacks the decryption dict for half a second at first. When calling python like this, python calls the wrong matrix API for fetching the encrypted thumbnail, and the added retry code would be forever stuck. The retry code has been moved to QML, and now works for all HImage.
This commit is contained in:
parent
26a4d76fc2
commit
f1055ce5b9
3
TODO.md
3
TODO.md
|
@ -1,14 +1,17 @@
|
|||
# TODO
|
||||
|
||||
- Image viewer:
|
||||
- support http urls
|
||||
- open externally in context menu in timeline thumbnail
|
||||
- fix: gif always closes?
|
||||
- hflickable support kinetic scrolling disabler and speed/decel settings
|
||||
- buttons
|
||||
- keyboard controls
|
||||
|
||||
- clipboard preview doesn't update when copied image changes until second time
|
||||
- Avatar tooltip can get displayed in front of presence menu
|
||||
- Use loading cursorShape
|
||||
- Increase keyboard page scroll speed
|
||||
|
||||
- global presence control
|
||||
|
||||
|
|
|
@ -12,7 +12,6 @@ from dataclasses import dataclass, field
|
|||
from pathlib import Path
|
||||
from typing import TYPE_CHECKING, Any, DefaultDict, Dict, Optional
|
||||
from urllib.parse import urlparse
|
||||
from .errors import MatrixError
|
||||
|
||||
from PIL import Image as PILImage
|
||||
|
||||
|
@ -134,20 +133,8 @@ class Media:
|
|||
async def create(self) -> Path:
|
||||
"""Download and cache the media file to disk."""
|
||||
|
||||
retries = 0
|
||||
|
||||
while True:
|
||||
try:
|
||||
async with CONCURRENT_DOWNLOADS_LIMIT:
|
||||
data = await self._get_remote_data()
|
||||
except MatrixError as err:
|
||||
if err.http_code != 404 and err.http_code < 500:
|
||||
raise
|
||||
else:
|
||||
break
|
||||
|
||||
await asyncio.sleep(min(30, 0.2 * (2 ** (min(1000, retries) - 1))))
|
||||
retries += 1
|
||||
async with CONCURRENT_DOWNLOADS_LIMIT:
|
||||
data = await self._get_remote_data()
|
||||
|
||||
self.local_path.parent.mkdir(parents=True, exist_ok=True)
|
||||
|
||||
|
|
|
@ -83,7 +83,6 @@ Rectangle {
|
|||
)
|
||||
|
||||
visible: ! avatarImage.broken &&
|
||||
avatarImage.status !== Image.Error &&
|
||||
avatarImage.width < dimension * 0.75 &&
|
||||
(toolTipSourceOverride || toolTipMxc) &&
|
||||
hoverHandler.hovered
|
||||
|
|
|
@ -7,7 +7,7 @@ Image {
|
|||
id: image
|
||||
|
||||
property bool circle: radius === circleRadius
|
||||
property bool broken: false
|
||||
property bool broken: image.status === Image.Error
|
||||
property bool animate: true
|
||||
property bool animated:
|
||||
utils.urlExtension(image.source).toLowerCase() === "gif"
|
||||
|
@ -20,6 +20,13 @@ Image {
|
|||
readonly property int circleRadius:
|
||||
Math.ceil(Math.max(image.width, image.height))
|
||||
|
||||
function reload() {
|
||||
// Can be reimplemented in components inheriting HImage
|
||||
const oldSource = source
|
||||
source = ""
|
||||
source = oldSource
|
||||
}
|
||||
|
||||
|
||||
autoTransform: true
|
||||
asynchronous: true
|
||||
|
@ -122,7 +129,7 @@ Image {
|
|||
|
||||
HIcon {
|
||||
anchors.centerIn: parent
|
||||
visible: broken || image.status === Image.Error
|
||||
visible: image.broken
|
||||
svgName: "broken-image"
|
||||
colorize: theme.colors.negativeBackground
|
||||
}
|
||||
|
@ -132,4 +139,18 @@ Image {
|
|||
anchors.fill: parent
|
||||
visible: false
|
||||
}
|
||||
|
||||
Timer {
|
||||
property int retries: 0
|
||||
|
||||
running: image.broken
|
||||
repeat: true
|
||||
interval:
|
||||
Math.min(60, 0.2 * Math.pow(2, Math.min(1000, retries) - 1)) * 1000
|
||||
|
||||
onTriggered: {
|
||||
image.reload()
|
||||
retries += 1
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -20,7 +20,7 @@ HImage {
|
|||
|
||||
readonly property bool isMxc: mxc.startsWith("mxc://")
|
||||
|
||||
function update() {
|
||||
function reload() {
|
||||
if (! py || ! canUpdate) return // component was destroyed
|
||||
|
||||
const w = sourceSize.width || width
|
||||
|
@ -46,7 +46,7 @@ HImage {
|
|||
if (! image) return
|
||||
if (image.cachedPath !== path) image.cachedPath = path
|
||||
|
||||
image.broken = false
|
||||
image.broken = Qt.binding(() => image.status === Image.Error)
|
||||
image.show = image.visible
|
||||
|
||||
}, (type, args, error, traceback) => {
|
||||
|
@ -61,9 +61,9 @@ HImage {
|
|||
showProgressBar:
|
||||
(isMxc && status === Image.Null) || status === Image.Loading
|
||||
|
||||
onWidthChanged: Qt.callLater(update)
|
||||
onHeightChanged: Qt.callLater(update)
|
||||
onVisibleChanged: Qt.callLater(update)
|
||||
onMxcChanged: Qt.callLater(update)
|
||||
onWidthChanged: Qt.callLater(reload)
|
||||
onHeightChanged: Qt.callLater(reload)
|
||||
onVisibleChanged: Qt.callLater(reload)
|
||||
onMxcChanged: Qt.callLater(reload)
|
||||
Component.onDestruction: if (getFuture) getFuture.cancel()
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue
Block a user