Refix Event.source, JSONify dicts for ListModel

This commit is contained in:
miruka 2020-02-12 13:04:46 -04:00
parent ae780345e8
commit ce0a868579
9 changed files with 37 additions and 28 deletions

View File

@ -42,9 +42,6 @@
- Don't put all the binds in one central file
- Missing room keybinds (invite, etc) and close failed upload
- Use QML states?
- Try gel for the models and stop being lazy in python
- Room Sidepane save/load size & keybinds
## Issues
@ -76,6 +73,7 @@
## Interface
- Room Sidepane keybinds
- Remember ctrl+tab page target
- https://doc.qt.io/qt-5/qml-qtquick-smoothedanimation.html for progress bars
- Make all "Cancel" buttons able to cancel running Backend coroutines set

View File

@ -3,6 +3,7 @@
"""`ModelItem` subclasses definitions."""
import asyncio
import json
from dataclasses import dataclass, field
from datetime import datetime, timedelta
from pathlib import Path
@ -217,7 +218,8 @@ class Event(ModelItem):
def serialize_field(self, field: str) -> Any:
if field == "source":
return self.source.__dict__ if self.source else {}
source_dict = nio.attr.asdict(self.source) if self.source else {}
return json.dumps(source_dict)
return super().serialize_field(field)

View File

@ -56,7 +56,10 @@ class ModelItem:
def serialize_field(self, field: str) -> Any:
return serialize_value_for_qml(getattr(self, field), json_lists=True)
return serialize_value_for_qml(
getattr(self, field),
json_list_dicts=True,
)
@property

View File

@ -17,13 +17,11 @@ if TYPE_CHECKING:
class PyOtherSideEvent:
"""Event that will be sent on instanciation to QML by PyOtherSide."""
json_lists = False
def __post_init__(self) -> None:
# CPython 3.6 or any Python implemention >= 3.7 is required for correct
# __dataclass_fields__ dict order.
args = [
serialize_value_for_qml(getattr(self, field), self.json_lists)
serialize_value_for_qml(getattr(self, field))
for field in self.__dataclass_fields__ # type: ignore
]
pyotherside.send(type(self).__name__, *args)
@ -65,19 +63,14 @@ class LoopException(PyOtherSideEvent):
@dataclass
class ModelEvent(ABC, PyOtherSideEvent):
json_lists = True
@dataclass
class ModelItemInserted(ModelEvent):
class ModelItemInserted(PyOtherSideEvent):
sync_id: SyncId = field()
index: int = field()
item: "ModelItem" = field()
@dataclass
class ModelItemFieldChanged(ModelEvent):
class ModelItemFieldChanged(PyOtherSideEvent):
sync_id: SyncId = field()
item_index_then: int = field()
item_index_now: int = field()
@ -86,11 +79,11 @@ class ModelItemFieldChanged(ModelEvent):
@dataclass
class ModelItemDeleted(ModelEvent):
class ModelItemDeleted(PyOtherSideEvent):
sync_id: SyncId = field()
index: int = field()
@dataclass
class ModelCleared(ModelEvent):
class ModelCleared(PyOtherSideEvent):
sync_id: SyncId = field()

View File

@ -8,12 +8,12 @@ import inspect
import io
import json
import xml.etree.cElementTree as xml_etree # FIXME: bandit warning
from datetime import timedelta
from datetime import datetime, timedelta
from enum import Enum
from enum import auto as autostr
from pathlib import Path
from types import ModuleType
from typing import Any, Dict, Tuple, Type
from typing import Any, Dict, Mapping, Sequence, Tuple, Type
from uuid import UUID
import filetype
@ -125,7 +125,7 @@ def plain2html(text: str) -> str:
.replace("\t", " " * 4)
def serialize_value_for_qml(value: Any, json_lists: bool = False) -> Any:
def serialize_value_for_qml(value: Any, json_list_dicts: bool = False) -> Any:
"""Convert a value to make it easier to use from QML.
Returns:
@ -138,7 +138,10 @@ def serialize_value_for_qml(value: Any, json_lists: bool = False) -> Any:
- `ModelItem.serialized` for `ModelItem`s
"""
if json_lists and isinstance(value, list):
if isinstance(value, (int, float, bool, str, datetime)):
return value
if json_list_dicts and isinstance(value, (Sequence, Mapping)):
return json.dumps(value)
if hasattr(value, "serialized"):

View File

@ -64,8 +64,11 @@ HColumnLayout {
function json() {
const events = ModelStore.get(chat.userId, chat.roomId, "events")
return JSON.stringify(events.get(model.id), null, 4)
let event = ModelStore.get(chat.userId, chat.roomId, "events")
.get(model.id)
event = JSON.parse(JSON.stringify(event))
event.source = JSON.parse(event.source)
return JSON.stringify(event, null, 4)
}
function openContextMenu() {

View File

@ -40,6 +40,8 @@ HTile {
property EventMediaLoader loader
readonly property bool cryptDict: loader.singleMediaInfo.media_crypt_dict
readonly property bool cryptDict:
JSON.parse(loader.singleMediaInfo.media_crypt_dict)
readonly property bool isEncrypted: ! utils.isEmptyObject(cryptDict)
}

View File

@ -15,9 +15,11 @@ HMxcImage {
mxc: thumbnail ?
(loader.thumbnailMxc || loader.mediaUrl) :
(loader.mediaUrl || loader.thumbnailMxc)
cryptDict: thumbnail && loader.thumbnailMxc ?
loader.singleMediaInfo.thumbnail_crypt_dict :
loader.singleMediaInfo.media_crypt_dict
cryptDict: JSON.parse(
thumbnail && loader.thumbnailMxc ?
loader.singleMediaInfo.thumbnail_crypt_dict :
loader.singleMediaInfo.media_crypt_dict
)
property EventMediaLoader loader

View File

@ -80,7 +80,10 @@ HLoader {
if (! downloadedPath) print("Downloading " + loader.mediaUrl + " ...")
const args = [loader.mediaUrl, loader.singleMediaInfo.media_crypt_dict]
const args = [
loader.mediaUrl,
JSON.parse(loader.singleMediaInfo.media_crypt_dict)
]
py.callCoro("media_cache.get_media", args, path => {
if (! downloadedPath) print("Done: " + path)