From 9a1b91caa5d21c654ab5a16f1f945110a78c8d35 Mon Sep 17 00:00:00 2001 From: miruka Date: Fri, 19 Apr 2019 03:11:56 -0400 Subject: [PATCH] Set user typing state when using the SendBox --- harmonyqml/backend/client.py | 34 +++++++++++++++++++++++++- harmonyqml/components/chat/SendBox.qml | 11 +++++++++ harmonyqml/components/chat/utils.js | 5 +++- 3 files changed, 48 insertions(+), 2 deletions(-) diff --git a/harmonyqml/backend/client.py b/harmonyqml/backend/client.py index d4a13e3a..478a7477 100644 --- a/harmonyqml/backend/client.py +++ b/harmonyqml/backend/client.py @@ -1,9 +1,10 @@ # Copyright 2019 miruka # This file is part of harmonyqml, licensed under GPLv3. +import time from concurrent.futures import ThreadPoolExecutor from threading import Event -from typing import DefaultDict +from typing import DefaultDict, Tuple from PyQt5.QtCore import QObject, pyqtProperty, pyqtSignal, pyqtSlot @@ -59,6 +60,10 @@ class Client(QObject): self._stop_sync: Event = Event() + # {room_id: (was_typing, at_timestamp_secs)} + self._last_typing_set: DefaultDict[str, Tuple[bool, float]] = \ + DefaultDict(lambda: (False, 0)) + def __repr__(self) -> str: return "%s(host=%r, port=%r, user_id=%r)" % \ @@ -170,6 +175,33 @@ class Client(QObject): ) + @pyqtSlot(str, bool) + @futurize + def setTypingState(self, room_id: str, typing: bool) -> None: + set_for_secs = 5 + last_set, last_time = self._last_typing_set[room_id] + + print(last_set, last_time) + + if not typing and last_set is False: + print("ignore 1") + return + + if typing and time.time() - last_time < set_for_secs - 1: + print("ignore 2") + return + + print("SET", typing) + self._last_typing_set[room_id] = (typing, time.time()) + + self.net.talk( + self.nio.room_typing, + room_id = room_id, + typing_state = typing, + timeout = set_for_secs * 1000, + ) + + @pyqtSlot(str, str) @futurize def sendMarkdown(self, room_id: str, text: str) -> None: diff --git a/harmonyqml/components/chat/SendBox.qml b/harmonyqml/components/chat/SendBox.qml index f7999781..e6d91e41 100644 --- a/harmonyqml/components/chat/SendBox.qml +++ b/harmonyqml/components/chat/SendBox.qml @@ -33,6 +33,8 @@ Rectangle { clip: true TextArea { + property string typedText: text + id: textArea placeholderText: qsTr("Type a message...") wrapMode: TextEdit.Wrap @@ -41,6 +43,14 @@ Rectangle { font.pixelSize: 16 focus: true + function set_typing(typing) { + Backend.clientManager.clients[chatPage.user_id] + .setTypingState(chatPage.room.room_id, typing) + } + + onTypedTextChanged: set_typing(Boolean(text)) + onEditingFinished: set_typing(false) // when lost focus + Keys.onReturnPressed: { event.accepted = true @@ -57,6 +67,7 @@ Rectangle { .sendMarkdown(chatPage.room.room_id, textArea.text) textArea.clear() } + Keys.onEnterPressed: Keys.onReturnPressed(event) // numpad enter } } diff --git a/harmonyqml/components/chat/utils.js b/harmonyqml/components/chat/utils.js index db6a08b3..b017b157 100644 --- a/harmonyqml/components/chat/utils.js +++ b/harmonyqml/components/chat/utils.js @@ -133,7 +133,10 @@ function get_typing_users_text(account_id, room_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 (room.typing_users[i] !== account_id) { + names.push(Backend.getUserDisplayName(room.typing_users[i], false) + .result()) + } } if (names.length < 1) { return "" }