Send typing updates from QML

This commit is contained in:
Nicolas Werner 2020-11-17 02:37:43 +01:00
parent 82c441dddd
commit 921379a4cc
7 changed files with 56 additions and 93 deletions

View File

@ -141,9 +141,6 @@ ChatPage::ChatPage(QSharedPointer<UserSettings> userSettings, QWidget *parent)
text_input_ = new TextInputWidget(this); text_input_ = new TextInputWidget(this);
contentLayout_->addWidget(text_input_); contentLayout_->addWidget(text_input_);
typingRefresher_ = new QTimer(this);
typingRefresher_->setInterval(TYPING_REFRESH_TIMEOUT);
connect(this, &ChatPage::connectionLost, this, [this]() { connect(this, &ChatPage::connectionLost, this, [this]() {
nhlog::net()->info("connectivity lost"); nhlog::net()->info("connectivity lost");
isConnected_ = false; isConnected_ = false;
@ -221,9 +218,7 @@ ChatPage::ChatPage(QSharedPointer<UserSettings> userSettings, QWidget *parent)
connect(room_list_, &RoomList::roomChanged, this, [this](QString room_id) { connect(room_list_, &RoomList::roomChanged, this, [this](QString room_id) {
this->current_room_ = room_id; this->current_room_ = room_id;
}); });
connect(room_list_, &RoomList::roomChanged, text_input_, &TextInputWidget::stopTyping);
connect(room_list_, &RoomList::roomChanged, splitter, &Splitter::showChatView); connect(room_list_, &RoomList::roomChanged, splitter, &Splitter::showChatView);
connect(room_list_, &RoomList::roomChanged, text_input_, &TextInputWidget::focusLineEdit);
connect( connect(
room_list_, &RoomList::roomChanged, view_manager_, &TimelineViewManager::setHistoryView); room_list_, &RoomList::roomChanged, view_manager_, &TimelineViewManager::setHistoryView);
@ -237,27 +232,6 @@ ChatPage::ChatPage(QSharedPointer<UserSettings> userSettings, QWidget *parent)
room_list_->removeRoom(room_id, currentRoom() == room_id); room_list_->removeRoom(room_id, currentRoom() == room_id);
}); });
connect(
text_input_, &TextInputWidget::startedTyping, this, &ChatPage::sendTypingNotifications);
connect(typingRefresher_, &QTimer::timeout, this, &ChatPage::sendTypingNotifications);
connect(text_input_, &TextInputWidget::stoppedTyping, this, [this]() {
if (!userSettings_->typingNotifications())
return;
typingRefresher_->stop();
if (current_room_.isEmpty())
return;
http::client()->stop_typing(
current_room_.toStdString(), [](mtx::http::RequestErr err) {
if (err) {
nhlog::net()->warn("failed to stop typing notifications: {}",
err->matrix_error.error);
}
});
});
connect(view_manager_, connect(view_manager_,
&TimelineViewManager::updateRoomsLastMessage, &TimelineViewManager::updateRoomsLastMessage,
room_list_, room_list_,
@ -435,12 +409,6 @@ ChatPage::resetUI()
emit unreadMessages(0); emit unreadMessages(0);
} }
void
ChatPage::focusMessageInput()
{
this->text_input_->focusLineEdit();
}
void void
ChatPage::deleteConfigs() ChatPage::deleteConfigs()
{ {
@ -1099,21 +1067,6 @@ ChatPage::receivedSessionKey(const std::string &room_id, const std::string &sess
view_manager_->receivedSessionKey(room_id, session_id); view_manager_->receivedSessionKey(room_id, session_id);
} }
void
ChatPage::sendTypingNotifications()
{
if (!userSettings_->typingNotifications())
return;
http::client()->start_typing(
current_room_.toStdString(), 10'000, [](mtx::http::RequestErr err) {
if (err) {
nhlog::net()->warn("failed to send typing notification: {}",
err->matrix_error.error);
}
});
}
QString QString
ChatPage::status() const ChatPage::status() const
{ {

View File

@ -100,7 +100,6 @@ public:
//! Show the room/group list (if it was visible). //! Show the room/group list (if it was visible).
void showSideBars(); void showSideBars();
void initiateLogout(); void initiateLogout();
void focusMessageInput();
QString status() const; QString status() const;
void setStatus(const QString &status); void setStatus(const QString &status);
@ -191,7 +190,6 @@ private slots:
void removeRoom(const QString &room_id); void removeRoom(const QString &room_id);
void dropToLoginPage(const QString &msg); void dropToLoginPage(const QString &msg);
void sendTypingNotifications();
void handleSyncResponse(const mtx::responses::Sync &res); void handleSyncResponse(const mtx::responses::Sync &res);
private: private:
@ -265,8 +263,6 @@ private:
popups::UserMentions *user_mentions_popup_; popups::UserMentions *user_mentions_popup_;
QTimer *typingRefresher_;
// Global user settings. // Global user settings.
QSharedPointer<UserSettings> userSettings_; QSharedPointer<UserSettings> userSettings_;

View File

@ -83,12 +83,6 @@ FilteredTextEdit::FilteredTextEdit(QWidget *parent)
insertCompletion(emoji); insertCompletion(emoji);
}); });
typingTimer_ = new QTimer(this);
typingTimer_->setInterval(1000);
typingTimer_->setSingleShot(true);
connect(typingTimer_, &QTimer::timeout, this, &FilteredTextEdit::stopTyping);
connect(this, &FilteredTextEdit::resultsRetrieved, this, &FilteredTextEdit::showResults); connect(this, &FilteredTextEdit::resultsRetrieved, this, &FilteredTextEdit::showResults);
connect( connect(
&suggestionsPopup_, &SuggestionsPopup::itemSelected, this, [this](const QString &text) { &suggestionsPopup_, &SuggestionsPopup::itemSelected, this, [this](const QString &text) {
@ -164,13 +158,6 @@ FilteredTextEdit::keyPressEvent(QKeyEvent *event)
if (event->modifiers() == Qt::ControlModifier && event->key() == Qt::Key_U) if (event->modifiers() == Qt::ControlModifier && event->key() == Qt::Key_U)
QTextEdit::setText(""); QTextEdit::setText("");
if (!isModifier) {
if (!typingTimer_->isActive())
emit startedTyping();
typingTimer_->start();
}
// calculate the new query // calculate the new query
if (textCursor().position() < atTriggerPosition_ || !isAnchorValid()) { if (textCursor().position() < atTriggerPosition_ || !isAnchorValid()) {
resetAnchor(); resetAnchor();
@ -264,7 +251,6 @@ FilteredTextEdit::keyPressEvent(QKeyEvent *event)
} }
if (!(event->modifiers() & Qt::ShiftModifier)) { if (!(event->modifiers() & Qt::ShiftModifier)) {
stopTyping();
submit(); submit();
} else { } else {
QTextEdit::keyPressEvent(event); QTextEdit::keyPressEvent(event);
@ -351,13 +337,6 @@ FilteredTextEdit::keyPressEvent(QKeyEvent *event)
} }
} }
void
FilteredTextEdit::stopTyping()
{
typingTimer_->stop();
emit stoppedTyping();
}
QRect QRect
FilteredTextEdit::completerRect() FilteredTextEdit::completerRect()
{ {
@ -494,15 +473,6 @@ TextInputWidget::TextInputWidget(QWidget *parent)
connect(sendMessageBtn_, &FlatButton::clicked, input_, &FilteredTextEdit::submit); connect(sendMessageBtn_, &FlatButton::clicked, input_, &FilteredTextEdit::submit);
connect(sendFileBtn_, SIGNAL(clicked()), this, SLOT(openFileSelection())); connect(sendFileBtn_, SIGNAL(clicked()), this, SLOT(openFileSelection()));
connect(input_, &FilteredTextEdit::startedTyping, this, &TextInputWidget::startedTyping);
connect(input_, &FilteredTextEdit::stoppedTyping, this, &TextInputWidget::stoppedTyping);
}
void
TextInputWidget::stopTyping()
{
input_->stopTyping();
} }
void void

View File

@ -43,8 +43,6 @@ class FilteredTextEdit : public QTextEdit
public: public:
explicit FilteredTextEdit(QWidget *parent = nullptr); explicit FilteredTextEdit(QWidget *parent = nullptr);
void stopTyping();
QSize sizeHint() const override; QSize sizeHint() const override;
QSize minimumSizeHint() const override; QSize minimumSizeHint() const override;
@ -52,8 +50,6 @@ public:
signals: signals:
void heightChanged(int height); void heightChanged(int height);
void startedTyping();
void stoppedTyping();
void startedUpload(); void startedUpload();
//! Trigger the suggestion popup. //! Trigger the suggestion popup.
@ -81,7 +77,6 @@ private:
int trigger_pos_; // Where emoji completer was triggered int trigger_pos_; // Where emoji completer was triggered
size_t history_index_; size_t history_index_;
QCompleter *completer_; QCompleter *completer_;
QTimer *typingTimer_;
SuggestionsPopup suggestionsPopup_; SuggestionsPopup suggestionsPopup_;
@ -136,8 +131,6 @@ class TextInputWidget : public QWidget
public: public:
TextInputWidget(QWidget *parent = nullptr); TextInputWidget(QWidget *parent = nullptr);
void stopTyping();
QColor borderColor() const { return borderColor_; } QColor borderColor() const { return borderColor_; }
void setBorderColor(QColor &color) { borderColor_ = color; } void setBorderColor(QColor &color) { borderColor_ = color; }
void disableInput() void disableInput()
@ -164,9 +157,6 @@ signals:
void sendUnbanRoomRequest(const QString &userid, const QString &reason); void sendUnbanRoomRequest(const QString &userid, const QString &reason);
void changeRoomNick(const QString &displayname); void changeRoomNick(const QString &displayname);
void startedTyping();
void stoppedTyping();
protected: protected:
void focusInEvent(QFocusEvent *event) override; void focusInEvent(QFocusEvent *event) override;
void paintEvent(QPaintEvent *) override; void paintEvent(QPaintEvent *) override;

View File

@ -114,6 +114,11 @@ InputBar::paste(bool fromMouse)
void void
InputBar::updateState(int selectionStart_, int selectionEnd_, int cursorPosition_, QString text_) InputBar::updateState(int selectionStart_, int selectionEnd_, int cursorPosition_, QString text_)
{ {
if (text_.isEmpty())
stopTyping();
else
startTyping();
selectionStart = selectionStart_; selectionStart = selectionStart_;
selectionEnd = selectionEnd_; selectionEnd = selectionEnd_;
cursorPosition = cursorPosition_; cursorPosition = cursorPosition_;
@ -556,3 +561,39 @@ InputBar::callButton()
} }
} }
} }
void
InputBar::startTyping()
{
if (!typingRefresh_.isActive()) {
typingRefresh_.start();
if (ChatPage::instance()->userSettings()->typingNotifications()) {
http::client()->start_typing(
room->roomId().toStdString(), 10'000, [](mtx::http::RequestErr err) {
if (err) {
nhlog::net()->warn(
"failed to send typing notification: {}",
err->matrix_error.error);
}
});
}
}
typingTimeout_.start();
}
void
InputBar::stopTyping()
{
typingRefresh_.stop();
typingTimeout_.stop();
if (!ChatPage::instance()->userSettings()->typingNotifications())
return;
http::client()->stop_typing(room->roomId().toStdString(), [](mtx::http::RequestErr err) {
if (err) {
nhlog::net()->warn("failed to stop typing notifications: {}",
err->matrix_error.error);
}
});
}

View File

@ -1,6 +1,7 @@
#pragma once #pragma once
#include <QObject> #include <QObject>
#include <QTimer>
#include <deque> #include <deque>
#include <mtx/common.hpp> #include <mtx/common.hpp>
@ -19,7 +20,14 @@ public:
InputBar(TimelineModel *parent) InputBar(TimelineModel *parent)
: QObject() : QObject()
, room(parent) , room(parent)
{} {
typingRefresh_.setInterval(10'000);
typingRefresh_.setSingleShot(true);
typingTimeout_.setInterval(5'000);
typingTimeout_.setSingleShot(true);
connect(&typingRefresh_, &QTimer::timeout, this, &InputBar::startTyping);
connect(&typingTimeout_, &QTimer::timeout, this, &InputBar::stopTyping);
}
public slots: public slots:
void send(); void send();
@ -29,6 +37,10 @@ public slots:
bool uploading() const { return uploading_; } bool uploading() const { return uploading_; }
void callButton(); void callButton();
private slots:
void startTyping();
void stopTyping();
signals: signals:
void insertText(QString text); void insertText(QString text);
void uploadingChanged(bool value); void uploadingChanged(bool value);
@ -69,6 +81,8 @@ private:
} }
} }
QTimer typingRefresh_;
QTimer typingTimeout_;
TimelineModel *room; TimelineModel *room;
QString text; QString text;
std::deque<QString> history_; std::deque<QString> history_;

View File

@ -800,7 +800,6 @@ void
TimelineModel::replyAction(QString id) TimelineModel::replyAction(QString id)
{ {
setReply(id); setReply(id);
ChatPage::instance()->focusMessageInput();
} }
RelatedInfo RelatedInfo