Rooms and threads fixes
- Fix roomList height again, now based on model.count(). All delegates are assumed to be the same height - Properly update room list when a room is joined or left - Catch exceptions happening in threads (futures), which previously passed silently - Show "Empty room?" as "<i>Empty Room</i>" + gray [?] avatar
This commit is contained in:
parent
d8c6ffefe0
commit
13fca98838
|
@ -2,8 +2,11 @@
|
|||
# This file is part of harmonyqml, licensed under GPLv3.
|
||||
|
||||
import functools
|
||||
import logging
|
||||
import sys
|
||||
import traceback
|
||||
from concurrent.futures import Future, ThreadPoolExecutor
|
||||
from threading import Event
|
||||
from threading import Event, currentThread
|
||||
from typing import Callable, DefaultDict, Dict
|
||||
|
||||
from PyQt5.QtCore import QObject, pyqtProperty, pyqtSignal, pyqtSlot
|
||||
|
@ -22,7 +25,16 @@ _POOLS: DefaultDict[str, ThreadPoolExecutor] = \
|
|||
def futurize(func: Callable) -> Callable:
|
||||
@functools.wraps(func)
|
||||
def wrapper(*args, **kwargs) -> Future:
|
||||
return args[0].pool.submit(func, *args, **kwargs) # args[0] = self
|
||||
def run_and_catch_errs():
|
||||
# Without this, exceptions are silently ignored
|
||||
try:
|
||||
func(*args, **kwargs)
|
||||
except Exception:
|
||||
traceback.print_exc()
|
||||
logging.error("Exiting %s due to exception.", currentThread())
|
||||
sys.exit(1)
|
||||
|
||||
return args[0].pool.submit(run_and_catch_errs) # args[0] = self
|
||||
return wrapper
|
||||
|
||||
|
||||
|
@ -91,7 +103,7 @@ class Client(QObject):
|
|||
@futurize
|
||||
def startSyncing(self) -> None:
|
||||
while True:
|
||||
self._on_sync(self.net.talk(self.nio.sync, timeout=10))
|
||||
self._on_sync(self.net.talk(self.nio.sync, timeout=10_000))
|
||||
|
||||
if self._stop_sync.is_set():
|
||||
self._stop_sync.clear()
|
||||
|
@ -105,7 +117,7 @@ class Client(QObject):
|
|||
for room_id in response.rooms.join:
|
||||
self.roomJoined.emit(room_id)
|
||||
|
||||
for room_id in response.rooms.left:
|
||||
for room_id in response.rooms.leave:
|
||||
self.roomLeft.emit(room_id)
|
||||
|
||||
|
||||
|
|
|
@ -17,7 +17,7 @@ class User(NamedTuple):
|
|||
|
||||
class Room(NamedTuple):
|
||||
room_id: str
|
||||
display_name: str
|
||||
display_name: Optional[str]
|
||||
description: str = ""
|
||||
unread_messages: int = 0
|
||||
presence: Presence = Presence.none
|
||||
|
|
|
@ -129,7 +129,7 @@ class ListModel(QAbstractListModel):
|
|||
|
||||
@pyqtSlot(int, list)
|
||||
def set(self, index: int, value: NewValue) -> None:
|
||||
qidx = QAbstractListModel.index(index, 0)
|
||||
qidx = QAbstractListModel.index(self, index, 0)
|
||||
value = self._convert_new_value(value)
|
||||
self._list[index] = value
|
||||
self.dataChanged.emit(qidx, qidx, self.roleNames())
|
||||
|
@ -139,7 +139,7 @@ class ListModel(QAbstractListModel):
|
|||
@pyqtSlot(int, str, "QVariant")
|
||||
def setProperty(self, index: int, prop: str, value: Any) -> None:
|
||||
self._list[index][self._roles.index(prop)] = value
|
||||
qidx = QAbstractListModel.index(index, 0)
|
||||
qidx = QAbstractListModel.index(self, index, 0)
|
||||
self.dataChanged.emit(qidx, qidx, self.roleNames())
|
||||
self._update_count += 1
|
||||
|
||||
|
|
|
@ -85,14 +85,12 @@ class NetworkManager:
|
|||
except NioErrorResponse as err:
|
||||
logging.error("read bad response for %s: %s", nio_func, err)
|
||||
self._close_socket(sock)
|
||||
|
||||
if self._should_abort_talk(err):
|
||||
logging.error("aborting talk")
|
||||
break
|
||||
time.sleep(10)
|
||||
|
||||
except Exception as err:
|
||||
logging.error("talk exception for %s: %r", nio_func, err)
|
||||
break
|
||||
time.sleep(10)
|
||||
|
||||
else:
|
||||
break
|
||||
|
|
|
@ -1,11 +1,13 @@
|
|||
# Copyright 2019 miruka
|
||||
# This file is part of harmonyqml, licensed under GPLv3.
|
||||
|
||||
from typing import Optional
|
||||
|
||||
from PyQt5.QtCore import QObject
|
||||
|
||||
from .backend import Backend
|
||||
from .client import Client
|
||||
from .model.items import User, Room
|
||||
from .model.items import Room, User
|
||||
|
||||
|
||||
class SignalManager(QObject):
|
||||
|
@ -43,14 +45,25 @@ class SignalManager(QObject):
|
|||
|
||||
|
||||
def onRoomJoined(self, client: Client, room_id: str) -> None:
|
||||
room = client.nio.rooms[room_id]
|
||||
name = room.name or room.canonical_alias or room.group_name()
|
||||
model = self.backend.models.rooms[client.userID]
|
||||
room = client.nio.rooms[room_id]
|
||||
|
||||
self.backend.models.rooms[client.userID].append(Room(
|
||||
def group_name() -> Optional[str]:
|
||||
name = room.group_name()
|
||||
return None if name == "Empty room?" else name
|
||||
|
||||
item = Room(
|
||||
room_id = room_id,
|
||||
display_name = name,
|
||||
display_name = room.name or room.canonical_alias or group_name(),
|
||||
description = getattr(room, "topic", ""), # FIXME: outside init
|
||||
))
|
||||
)
|
||||
|
||||
try:
|
||||
index = model.indexWhere("room_id", room_id)
|
||||
except ValueError:
|
||||
model.append(item)
|
||||
else:
|
||||
model[index] = item
|
||||
|
||||
|
||||
def onRoomLeft(self, client: Client, room_id: str) -> None:
|
||||
|
|
|
@ -4,7 +4,7 @@ import QtQuick.Layouts 1.4
|
|||
|
||||
Item {
|
||||
property bool invisible: false
|
||||
property string name: "?"
|
||||
property var name: null
|
||||
property var imageSource: null
|
||||
property int dimmension: 48
|
||||
|
||||
|
@ -16,11 +16,13 @@ Item {
|
|||
id: "letterRectangle"
|
||||
anchors.fill: parent
|
||||
visible: ! invisible && imageSource === null
|
||||
color: Qt.hsla(Backend.hueFromString(name), 0.22, 0.5, 1)
|
||||
color: name ?
|
||||
Qt.hsla(Backend.hueFromString(name), 0.22, 0.5, 1) :
|
||||
Qt.hsla(0, 0, 0.22, 1)
|
||||
|
||||
HLabel {
|
||||
anchors.centerIn: parent
|
||||
text: name.charAt(0)
|
||||
text: name ? name.charAt(0) : "?"
|
||||
color: "white"
|
||||
font.pixelSize: letterRectangle.height / 1.4
|
||||
}
|
||||
|
|
|
@ -6,7 +6,7 @@ import "../base" as Base
|
|||
MouseArea {
|
||||
id: "root"
|
||||
width: roomList.width
|
||||
height: Math.max(roomLabel.height + subtitleLabel.height, avatar.height)
|
||||
height: roomList.childrenHeight
|
||||
|
||||
onClicked: pageStack.show_room(
|
||||
roomList.user_id,
|
||||
|
@ -18,14 +18,15 @@ MouseArea {
|
|||
id: row
|
||||
spacing: 1
|
||||
|
||||
Base.Avatar { id: avatar; name: display_name; dimmension: 36 }
|
||||
Base.Avatar { id: avatar; name: display_name; dimmension: root.height }
|
||||
|
||||
ColumnLayout {
|
||||
spacing: 0
|
||||
|
||||
Base.HLabel {
|
||||
id: roomLabel
|
||||
text: display_name
|
||||
text: display_name ? display_name : "<i>Empty room</i>"
|
||||
textFormat: Text.StyledText
|
||||
elide: Text.ElideRight
|
||||
maximumLineCount: 1
|
||||
Layout.maximumWidth: row.width - row.spacing - avatar.width
|
||||
|
@ -37,11 +38,12 @@ MouseArea {
|
|||
rightPadding: leftPadding
|
||||
}
|
||||
Base.HLabel {
|
||||
function get_text() {
|
||||
var msgs = Backend.models.messages.get(room_id)
|
||||
if (! msgs || msgs.count < 1) { return "" }
|
||||
property var msgModel: Backend.models.messages.get(room_id)
|
||||
|
||||
var msg = msgs.get(-1)
|
||||
function get_text() {
|
||||
if (msgModel.count < 1) { return "" }
|
||||
|
||||
var msg = msgModel.get(-1)
|
||||
var color_ = (msg.sender_id === roomList.user_id ?
|
||||
"darkblue" : "purple")
|
||||
var client = Backend.clientManager.clients[RoomList.for_user_id]
|
||||
|
@ -54,7 +56,7 @@ MouseArea {
|
|||
|
||||
id: subtitleLabel
|
||||
visible: text !== ""
|
||||
text: Backend.models.messages.get(room_id).reloadThis, get_text()
|
||||
text: msgModel.reloadThis, get_text()
|
||||
textFormat: Text.StyledText
|
||||
|
||||
font.pixelSize: smallSize
|
||||
|
|
|
@ -6,17 +6,12 @@ import "../base" as Base
|
|||
ListView {
|
||||
property var for_user_id: null
|
||||
|
||||
property int childrenHeight: 36
|
||||
property int contentHeight: 0
|
||||
|
||||
onCountChanged: {
|
||||
var children = roomList.contentItem.children
|
||||
var childrenHeight = 0
|
||||
|
||||
for (var i = 0; i < children.length; i++) {
|
||||
childrenHeight += children[i].height
|
||||
}
|
||||
|
||||
contentHeight = childrenHeight + spacing * (children.length - 1)
|
||||
contentHeight = childrenHeight * model.count +
|
||||
spacing * (model.count - 1)
|
||||
}
|
||||
|
||||
id: "roomList"
|
||||
|
|
Loading…
Reference in New Issue
Block a user