Add ability to cancel uploads

This commit is contained in:
miruka 2019-12-02 05:06:21 -04:00
parent ae009c7412
commit 3919b964ca
4 changed files with 52 additions and 7 deletions

View File

@ -57,6 +57,7 @@
- Quote links color in room subtitles (e.g. "> http://foo.orgA)" )
- UI
- Make theme error/etc text colors more like name colors
- Standardize usage of punctuation
- Way to open context menus without a right mouse button
- `smartVerticalFlick()` gradual acceleration

View File

@ -12,7 +12,7 @@ from typing import (
Any, DefaultDict, Dict, NamedTuple, Optional, Set, Tuple, Type, Union,
)
from urllib.parse import urlparse
from uuid import uuid4
from uuid import UUID, uuid4
import cairosvg
from PIL import Image as PILImage
@ -211,17 +211,28 @@ class MatrixClient(nio.AsyncClient):
async def send_file(self, room_id: str, path: Union[Path, str]) -> None:
item_uuid = uuid4()
try:
await self._send_file(item_uuid, room_id, path)
except asyncio.CancelledError:
del self.models[Upload, room_id][item_uuid]
async def _send_file(
self, item_uuid: UUID, room_id: str, path: Union[Path, str],
) -> None:
from .media_cache import Media, Thumbnail
path = Path(path)
size = path.resolve().stat().st_size
encrypt = room_id in self.encrypted_rooms
upload_item = Upload(path, total_size=size)
task = asyncio.Task.current_task()
upload_item = Upload(item_uuid, task, path, total_size=size)
self.models[Upload, room_id][upload_item.uuid] = upload_item
try:
raise MatrixError(111, "Ooops!")
url, mime, crypt_dict = await self.upload(
path, filename=path.name, encrypt=encrypt,
)
@ -229,7 +240,10 @@ class MatrixClient(nio.AsyncClient):
upload_item.status = UploadStatus.Error
upload_item.error = type(err)
upload_item.error_args = err.args
return
# Wait for cancellation, see parent send_file() method
while True:
await asyncio.sleep(0.1)
upload_item.status = UploadStatus.Caching
await Media.from_existing_file(self.backend.media_cache, url, path)

View File

@ -1,9 +1,10 @@
import asyncio
import re
from dataclasses import dataclass, field
from datetime import datetime
from pathlib import Path
from typing import Any, Dict, List, Optional, Tuple, Type, Union
from uuid import uuid4
from uuid import UUID
import lxml # nosec
@ -113,6 +114,8 @@ class UploadStatus(AutoStrEnum):
@dataclass
class Upload(ModelItem):
uuid: UUID = field()
task: asyncio.Task = field()
filepath: Path = field()
status: UploadStatus = UploadStatus.Uploading
total_size: int = 0
@ -120,7 +123,6 @@ class Upload(ModelItem):
error: OptionalExceptionType = type(None)
error_args: Tuple[Any, ...] = ()
uuid: str = field(init=False, default_factory=lambda: str(uuid4()))
start_date: datetime = field(init=False, default_factory=datetime.now)

View File

@ -35,7 +35,34 @@ Rectangle {
id: delegate
width: uploadsList.width
Behavior on height { HNumberAnimation {} }
Binding {
id: hideBind
target: delegate
property: "height"
value: 0
when: false
}
HRowLayout {
HButton {
icon.name: "cancel"
icon.color: theme.colors.negativeBackground
padded: false
onClicked: {
// Python might take a sec to cancel, but we want
// immediate visual feedback
hideBind.when = true
// Python will delete this model item on cancel
py.call(py.getattr(model.task, "cancel"))
}
Layout.preferredWidth: theme.baseElementsHeight
Layout.preferredHeight: Layout.preferredWidth
}
HLabel {
id: statusLabel
elide: expand ? Text.ElideNone : Text.ElideRight
@ -108,7 +135,8 @@ Rectangle {
}
TapHandler {
onTapped: statusLabel.expand = ! statusLabel.expand
onTapped: if (model.status !== "Error")
statusLabel.expand = ! statusLabel.expand
}
HoverHandler { id: infoRowHover }