Add users currently typing in room bar

This commit is contained in:
miruka 2019-04-14 16:12:07 -04:00
parent 14a76b710b
commit 8a3189df15
9 changed files with 85 additions and 21 deletions

View File

@ -20,3 +20,5 @@
- Load previous events on scroll up - Load previous events on scroll up
- Migrate more JS functions to their own files - Migrate more JS functions to their own files
- Accept room\_id arg for getUser

View File

@ -41,6 +41,7 @@ class Client(QObject):
roomJoined = pyqtSignal(str) roomJoined = pyqtSignal(str)
roomLeft = pyqtSignal(str) roomLeft = pyqtSignal(str)
roomEventReceived = pyqtSignal(str, str, dict) roomEventReceived = pyqtSignal(str, str, dict)
roomTypingUsersUpdated = pyqtSignal(str, list)
def __init__(self, hostname: str, username: str, device_id: str = "" def __init__(self, hostname: str, username: str, device_id: str = ""
@ -121,5 +122,11 @@ class Client(QObject):
room_id, type(ev).__name__, ev.__dict__ room_id, type(ev).__name__, ev.__dict__
) )
for ev in room_info.ephemeral:
if isinstance(ev, nr.TypingNoticeEvent):
self.roomTypingUsersUpdated.emit(room_id, ev.users)
else:
print("ephemeral event: ", ev)
for room_id in response.rooms.leave: for room_id in response.rooms.leave:
self.roomLeft.emit(room_id) self.roomLeft.emit(room_id)

View File

@ -1,12 +1,10 @@
# Copyright 2019 miruka # Copyright 2019 miruka
# This file is part of harmonyqml, licensed under GPLv3. # This file is part of harmonyqml, licensed under GPLv3.
from typing import Dict, NamedTuple, Optional from typing import Dict, List, NamedTuple, Optional
from PyQt5.QtCore import QDateTime from PyQt5.QtCore import QDateTime
from .enums import Activity, Presence
class User(NamedTuple): class User(NamedTuple):
user_id: str user_id: str
@ -19,11 +17,7 @@ class Room(NamedTuple):
room_id: str room_id: str
display_name: Optional[str] display_name: Optional[str]
description: str = "" description: str = ""
unread_messages: int = 0 typing_users: List[str] = []
presence: Presence = Presence.none
activity: Activity = Activity.none
last_activity_timestamp_ms: Optional[int] = None
avatar_url: Optional[str] = None
class RoomEvent(NamedTuple): class RoomEvent(NamedTuple):

View File

@ -10,6 +10,7 @@ from PyQt5.QtCore import (
) )
NewValue = Union[Mapping[str, Any], Sequence] NewValue = Union[Mapping[str, Any], Sequence]
ReturnItem = Dict[str, Any]
class ListModel(QAbstractListModel): class ListModel(QAbstractListModel):
@ -96,7 +97,7 @@ class ListModel(QAbstractListModel):
@pyqtSlot(int, result="QVariantMap") @pyqtSlot(int, result="QVariantMap")
def get(self, index: int) -> Dict[str, Any]: def get(self, index: int) -> ReturnItem:
return self._list[index]._asdict() return self._list[index]._asdict()
@ -110,6 +111,11 @@ class ListModel(QAbstractListModel):
f"property {prop!r} set to {is_value!r}.") f"property {prop!r} set to {is_value!r}.")
@pyqtSlot(str, "QVariant", result="QVariantMap")
def getWhere(self, prop: str, is_value: Any) -> ReturnItem:
return self.get(self.indexWhere(prop, is_value))
@pyqtSlot(int, list) @pyqtSlot(int, list)
def insert(self, index: int, value: NewValue) -> None: def insert(self, index: int, value: NewValue) -> None:
value = self._convert_new_value(value) value = self._convert_new_value(value)

View File

@ -2,7 +2,7 @@
# This file is part of harmonyqml, licensed under GPLv3. # This file is part of harmonyqml, licensed under GPLv3.
from threading import Lock from threading import Lock
from typing import Any, Deque, Dict, Optional from typing import Any, Deque, Dict, List, Optional
from PyQt5.QtCore import QDateTime, QObject, pyqtBoundSignal from PyQt5.QtCore import QDateTime, QObject, pyqtBoundSignal
@ -109,3 +109,11 @@ class SignalManager(QObject):
break break
else: else:
model.insert(0, new_event) model.insert(0, new_event)
def onRoomTypingUsersUpdated(
self, client: Client, room_id: str, users: List[str]
) -> None:
rooms = self.backend.models.rooms[client.userID]
rooms[rooms.indexWhere("room_id", room_id)].typing_users = users

View File

@ -24,10 +24,6 @@ Controls1.SplitView {
} }
id: "pageStack" id: "pageStack"
// initialItem: Chat.Root {
//user: Backend.accountsModel.get(0)
//room: Backend.roomsModel[Backend.accountsModel.get(0).user_id].get(0)
//}
onCurrentItemChanged: currentItem.forceActiveFocus() onCurrentItemChanged: currentItem.forceActiveFocus()

View File

@ -6,11 +6,13 @@ ColumnLayout {
property var user_id: null property var user_id: null
property var room: null property var room: null
id: chatPage id: chatPage
spacing: 0 spacing: 0
onFocusChanged: sendBox.setFocus() onFocusChanged: sendBox.setFocus()
RoomHeader {} RoomHeader {}
MessageList {} MessageList {}
TypingUsersBar {}
SendBox { id: sendBox } SendBox { id: sendBox }
} }

View File

@ -0,0 +1,31 @@
import QtQuick 2.7
import QtQuick.Controls 2.2
import QtQuick.Layouts 1.4
import "../base" as Base
import "utils.js" as ChatJS
Rectangle {
id: root
Layout.fillWidth: true
Layout.minimumHeight: usersLabel.text ? usersLabel.implicitHeight : 0
Layout.maximumHeight: Layout.minimumHeight
color: "#BBB"
Base.HLabel {
id: "usersLabel"
anchors.fill: parent
Timer {
interval: 500
repeat: true
running: true
triggeredOnStart: true
onTriggered: usersLabel.text = ChatJS.get_typing_users_text(
chatPage.user_id, chatPage.room.room_id
)
}
elide: Text.ElideMiddle
maximumLineCount: 1
}
}

View File

@ -124,3 +124,21 @@ function get_member_event_text(dict) {
return "" return ""
} }
function get_typing_users_text(account_id, room_id) {
var names = []
var room = Backend.models.rooms.get(account_id)
.getWhere("room_id", room_id)
for (var i = 0; i < room.typing_users.length; i++) {
names.push(Backend.getUser(room.typing_users[i]).display_name)
}
if (names.length < 1) { return "" }
return "🖋 " +
[names.slice(0, -1).join(", "), names.slice(-1)[0]]
.join(names.length < 2 ? "" : " and ") +
(names.length > 1 ? " are" : " is") + " typing…"
}