Receive typing notifications (#88)

This commit is contained in:
Konstantinos Sideris 2017-10-04 11:33:34 +03:00
parent 88349eae90
commit d60c2b76e3
10 changed files with 171 additions and 32 deletions

View file

@ -101,8 +101,10 @@ ChatPage::ChatPage(QSharedPointer<MatrixClient> client, QWidget *parent)
view_manager_ = new TimelineViewManager(client, this);
mainContentLayout_->addWidget(view_manager_);
text_input_ = new TextInputWidget(this);
text_input_ = new TextInputWidget(this);
typingDisplay_ = new TypingDisplay(this);
contentLayout_->addWidget(text_input_);
contentLayout_->addWidget(typingDisplay_);
user_info_widget_ = new UserInfoWidget(sideBarTopWidget_);
sideBarTopWidgetLayout_->addWidget(user_info_widget_);
@ -117,6 +119,15 @@ ChatPage::ChatPage(QSharedPointer<MatrixClient> client, QWidget *parent)
connect(
top_bar_, &TopRoomBar::leaveRoom, this, [=]() { client_->leaveRoom(current_room_); });
connect(room_list_, &RoomList::roomChanged, this, [=](const QString &roomid) {
QStringList users;
if (typingUsers_.contains(roomid))
users = typingUsers_[roomid];
typingDisplay_->setUsers(users);
});
connect(room_list_, &RoomList::roomChanged, this, &ChatPage::changeTopRoomInfo);
connect(room_list_, &RoomList::roomChanged, text_input_, &TextInputWidget::focusLineEdit);
connect(
@ -308,6 +319,8 @@ ChatPage::syncCompleted(const SyncResponse &response)
auto joined = response.rooms().join();
for (auto it = joined.constBegin(); it != joined.constEnd(); it++) {
updateTypingUsers(it.key(), it.value().typingUserIDs());
RoomState room_state;
// Merge the new updates for rooms that we are tracking.
@ -620,6 +633,22 @@ ChatPage::removeRoom(const QString &room_id)
room_list_->removeRoom(room_id, room_id == current_room_);
}
void
ChatPage::updateTypingUsers(const QString &roomid, const QList<QString> &user_ids)
{
QStringList users;
for (const auto uid : user_ids)
users.append(TimelineViewManager::displayName(uid));
users.sort();
if (current_room_ == roomid)
typingDisplay_->setUsers(users);
typingUsers_.insert(roomid, users);
}
ChatPage::~ChatPage()
{
sync_timer_->stop();

View file

@ -611,8 +611,9 @@ void
MatrixClient::sync() noexcept
{
QJsonObject filter{ { "room",
QJsonObject{ { "include_leave", true },
{ "ephemeral", QJsonObject{ { "limit", 0 } } } } },
QJsonObject{
{ "include_leave", true },
} },
{ "presence", QJsonObject{ { "limit", 0 } } } };
QUrlQuery query;

View file

@ -168,7 +168,21 @@ JoinedRoom::deserialize(const QJsonValue &data)
if (!ephemeral.value("events").isArray())
qWarning() << "join/ephemeral/events should be an array";
// TODO: Implement ephemeral handling
auto ephemeralEvents = ephemeral.value("events").toArray();
for (const auto e : ephemeralEvents) {
auto obj = e.toObject();
if (obj.contains("type") && obj.value("type") == "m.typing") {
auto ids = obj.value("content")
.toObject()
.value("user_ids")
.toArray();
for (const auto uid : ids)
typingUserIDs_.push_back(uid.toString());
}
}
}
}

View file

@ -45,13 +45,14 @@ TextInputWidget::TextInputWidget(QWidget *parent)
{
setFont(QFont("Emoji One"));
setFixedHeight(45);
setSizePolicy(QSizePolicy::Expanding, QSizePolicy::Fixed);
setCursor(Qt::ArrowCursor);
setStyleSheet("background-color: #fff; height: 45px;");
setStyleSheet("background-color: #fff;");
topLayout_ = new QHBoxLayout();
topLayout_->setSpacing(2);
topLayout_->setMargin(4);
topLayout_->setSpacing(0);
topLayout_->setContentsMargins(5, 15, 0, 5);
QIcon send_file_icon;
send_file_icon.addFile(":/icons/icons/clip-dark.png", QSize(), QIcon::Normal, QIcon::Off);
@ -63,18 +64,19 @@ TextInputWidget::TextInputWidget(QWidget *parent)
spinner_ = new LoadingIndicator(this);
spinner_->setColor("#acc7dc");
spinner_->setFixedHeight(40);
spinner_->setFixedWidth(40);
spinner_->setFixedHeight(32);
spinner_->setFixedWidth(32);
spinner_->hide();
QFont font;
font.setPixelSize(conf::fontSize);
input_ = new FilteredTextEdit(this);
input_->setFixedHeight(45);
input_->setFixedHeight(32);
input_->setFont(font);
input_->setVerticalScrollBarPolicy(Qt::ScrollBarAlwaysOff);
input_->setPlaceholderText(tr("Write a message..."));
input_->setStyleSheet("color: #333333; border-radius: 0; padding-top: 10px;");
input_->setStyleSheet("color: #333333; border: none; margin: 0 5px");
sendMessageBtn_ = new FlatButton(this);
sendMessageBtn_->setForegroundColor(QColor("#acc7dc"));

56
src/TypingDisplay.cc Normal file
View file

@ -0,0 +1,56 @@
#include <QDebug>
#include <QPainter>
#include <QPoint>
#include "Config.h"
#include "TypingDisplay.h"
TypingDisplay::TypingDisplay(QWidget *parent)
: QWidget(parent)
, leftPadding_{ 57 }
{
QFont font;
font.setPixelSize(conf::typingNotificationFontSize);
setFixedHeight(QFontMetrics(font).height() + 2);
}
void
TypingDisplay::setUsers(const QStringList &uid)
{
if (uid.isEmpty())
text_.clear();
else
text_ = uid.join(", ");
if (uid.size() == 1)
text_ += tr(" is typing ...");
else if (uid.size() > 1)
text_ += tr(" are typing ...");
update();
}
void
TypingDisplay::paintEvent(QPaintEvent *)
{
QPen pen(QColor("#333"));
QFont font;
font.setPixelSize(conf::typingNotificationFontSize);
font.setWeight(40);
font.setItalic(true);
QPainter p(this);
p.setRenderHint(QPainter::Antialiasing);
p.setFont(font);
p.setPen(pen);
QRect region = rect();
region.translate(leftPadding_, 0);
QFontMetrics fm(font);
text_ = fm.elidedText(text_, Qt::ElideRight, width() - 3 * leftPadding_);
p.drawText(region, Qt::AlignTop, text_);
}