Create widgets on demand for messages added to the end of the timeline
This commit is contained in:
parent
a7e84b63ac
commit
983aea7c76
@ -207,6 +207,7 @@ set(SRC_FILES
|
|||||||
src/TopRoomBar.cc
|
src/TopRoomBar.cc
|
||||||
src/TrayIcon.cc
|
src/TrayIcon.cc
|
||||||
src/TypingDisplay.cc
|
src/TypingDisplay.cc
|
||||||
|
src/Utils.cc
|
||||||
src/UserInfoWidget.cc
|
src/UserInfoWidget.cc
|
||||||
src/UserSettingsPage.cc
|
src/UserSettingsPage.cc
|
||||||
src/WelcomePage.cc
|
src/WelcomePage.cc
|
||||||
|
20
include/Utils.h
Normal file
20
include/Utils.h
Normal file
@ -0,0 +1,20 @@
|
|||||||
|
#pragma once
|
||||||
|
|
||||||
|
#include "RoomInfoListItem.h"
|
||||||
|
|
||||||
|
#include <QDateTime>
|
||||||
|
#include <mtx/events/collections.hpp>
|
||||||
|
|
||||||
|
namespace utils {
|
||||||
|
|
||||||
|
using TimelineEvent = mtx::events::collections::TimelineEvents;
|
||||||
|
|
||||||
|
//! Human friendly timestamp representation.
|
||||||
|
QString
|
||||||
|
descriptiveTime(const QDateTime &then);
|
||||||
|
|
||||||
|
//! Generate a message description from the event to be displayed
|
||||||
|
//! in the RoomList.
|
||||||
|
DescInfo
|
||||||
|
getMessageDescription(const TimelineEvent &event, const QString &localUser);
|
||||||
|
}
|
@ -28,6 +28,7 @@
|
|||||||
#include "AvatarProvider.h"
|
#include "AvatarProvider.h"
|
||||||
#include "RoomInfoListItem.h"
|
#include "RoomInfoListItem.h"
|
||||||
#include "TimelineViewManager.h"
|
#include "TimelineViewManager.h"
|
||||||
|
#include "Utils.h"
|
||||||
|
|
||||||
class ImageItem;
|
class ImageItem;
|
||||||
class AudioItem;
|
class AudioItem;
|
||||||
@ -107,7 +108,6 @@ private:
|
|||||||
void generateBody(const QString &body);
|
void generateBody(const QString &body);
|
||||||
void generateBody(const QString &userid, const QString &body);
|
void generateBody(const QString &userid, const QString &body);
|
||||||
void generateTimestamp(const QDateTime &time);
|
void generateTimestamp(const QDateTime &time);
|
||||||
QString descriptiveTime(const QDateTime &then);
|
|
||||||
|
|
||||||
void setupAvatarLayout(const QString &userName);
|
void setupAvatarLayout(const QString &userName);
|
||||||
void setupSimpleLayout();
|
void setupSimpleLayout();
|
||||||
@ -145,8 +145,11 @@ TimelineItem::setupLocalWidgetLayout(Widget *widget,
|
|||||||
auto displayName = TimelineViewManager::displayName(userid);
|
auto displayName = TimelineViewManager::displayName(userid);
|
||||||
auto timestamp = QDateTime::currentDateTime();
|
auto timestamp = QDateTime::currentDateTime();
|
||||||
|
|
||||||
descriptionMsg_ = {
|
descriptionMsg_ = {"You",
|
||||||
"You", userid, QString(" %1").arg(msgDescription), descriptiveTime(timestamp), timestamp};
|
userid,
|
||||||
|
QString(" %1").arg(msgDescription),
|
||||||
|
utils::descriptiveTime(timestamp),
|
||||||
|
timestamp};
|
||||||
|
|
||||||
generateTimestamp(timestamp);
|
generateTimestamp(timestamp);
|
||||||
|
|
||||||
@ -187,7 +190,7 @@ TimelineItem::setupWidgetLayout(Widget *widget,
|
|||||||
descriptionMsg_ = {sender == settings.value("auth/user_id") ? "You" : displayName,
|
descriptionMsg_ = {sender == settings.value("auth/user_id") ? "You" : displayName,
|
||||||
sender,
|
sender,
|
||||||
msgDescription,
|
msgDescription,
|
||||||
descriptiveTime(timestamp),
|
utils::descriptiveTime(timestamp),
|
||||||
timestamp};
|
timestamp};
|
||||||
|
|
||||||
generateTimestamp(timestamp);
|
generateTimestamp(timestamp);
|
||||||
|
@ -23,7 +23,6 @@
|
|||||||
#include <QList>
|
#include <QList>
|
||||||
#include <QQueue>
|
#include <QQueue>
|
||||||
#include <QScrollArea>
|
#include <QScrollArea>
|
||||||
#include <QSettings>
|
|
||||||
#include <QStyle>
|
#include <QStyle>
|
||||||
#include <QStyleOption>
|
#include <QStyleOption>
|
||||||
|
|
||||||
@ -119,10 +118,13 @@ protected:
|
|||||||
bool event(QEvent *event) override;
|
bool event(QEvent *event) override;
|
||||||
|
|
||||||
private:
|
private:
|
||||||
|
using TimelineEvent = mtx::events::collections::TimelineEvents;
|
||||||
|
|
||||||
void init();
|
void init();
|
||||||
void addTimelineItem(TimelineItem *item, TimelineDirection direction);
|
void addTimelineItem(TimelineItem *item, TimelineDirection direction);
|
||||||
void updateLastSender(const QString &user_id, TimelineDirection direction);
|
void updateLastSender(const QString &user_id, TimelineDirection direction);
|
||||||
void notifyForLastEvent();
|
void notifyForLastEvent();
|
||||||
|
void notifyForLastEvent(const TimelineEvent &event);
|
||||||
void readLastEvent() const;
|
void readLastEvent() const;
|
||||||
bool isScrollbarActivated() { return scroll_area_->verticalScrollBar()->value() != 0; }
|
bool isScrollbarActivated() { return scroll_area_->verticalScrollBar()->value() != 0; }
|
||||||
QString getLastEventId() const;
|
QString getLastEventId() const;
|
||||||
@ -193,6 +195,18 @@ private:
|
|||||||
|
|
||||||
TimelineDirection lastMessageDirection_;
|
TimelineDirection lastMessageDirection_;
|
||||||
|
|
||||||
|
//! Messages received by sync not added to the timeline.
|
||||||
|
std::vector<TimelineEvent> bottomMessages_;
|
||||||
|
|
||||||
|
//! Render the given timeline events to the bottom of the timeline.
|
||||||
|
void renderBottomEvents(const std::vector<TimelineEvent> &events);
|
||||||
|
|
||||||
|
//! Decide if the given timeline event can be rendered.
|
||||||
|
inline bool isViewable(const TimelineEvent &event) const;
|
||||||
|
|
||||||
|
//! Decide if the given event should trigger a notification.
|
||||||
|
inline bool isNotifiable(const TimelineEvent &event) const;
|
||||||
|
|
||||||
// The events currently rendered. Used for duplicate detection.
|
// The events currently rendered. Used for duplicate detection.
|
||||||
QMap<QString, bool> eventIds_;
|
QMap<QString, bool> eventIds_;
|
||||||
QQueue<PendingMessage> pending_msgs_;
|
QQueue<PendingMessage> pending_msgs_;
|
||||||
@ -204,20 +218,19 @@ template<class Widget, mtx::events::MessageType MsgType>
|
|||||||
void
|
void
|
||||||
TimelineView::addUserMessage(const QString &url, const QString &filename)
|
TimelineView::addUserMessage(const QString &url, const QString &filename)
|
||||||
{
|
{
|
||||||
QSettings settings;
|
auto with_sender = lastSender_ != local_user_;
|
||||||
auto user_id = settings.value("auth/user_id").toString();
|
|
||||||
auto with_sender = lastSender_ != user_id;
|
|
||||||
|
|
||||||
auto widget = new Widget(client_, url, filename, this);
|
auto widget = new Widget(client_, url, filename, this);
|
||||||
|
|
||||||
TimelineItem *view_item = new TimelineItem(widget, user_id, with_sender, scroll_widget_);
|
TimelineItem *view_item =
|
||||||
|
new TimelineItem(widget, local_user_, with_sender, scroll_widget_);
|
||||||
scroll_layout_->addWidget(view_item);
|
scroll_layout_->addWidget(view_item);
|
||||||
|
|
||||||
lastMessageDirection_ = TimelineDirection::Bottom;
|
lastMessageDirection_ = TimelineDirection::Bottom;
|
||||||
|
|
||||||
QApplication::processEvents();
|
QApplication::processEvents();
|
||||||
|
|
||||||
lastSender_ = user_id;
|
lastSender_ = local_user_;
|
||||||
|
|
||||||
int txn_id = client_->incrementTransactionId();
|
int txn_id = client_->incrementTransactionId();
|
||||||
|
|
||||||
|
121
src/Utils.cc
Normal file
121
src/Utils.cc
Normal file
@ -0,0 +1,121 @@
|
|||||||
|
#include "Utils.h"
|
||||||
|
#include "timeline/TimelineViewManager.h"
|
||||||
|
|
||||||
|
#include <variant.hpp>
|
||||||
|
|
||||||
|
using TimelineEvent = mtx::events::collections::TimelineEvents;
|
||||||
|
|
||||||
|
QString
|
||||||
|
utils::descriptiveTime(const QDateTime &then)
|
||||||
|
{
|
||||||
|
const auto now = QDateTime::currentDateTime();
|
||||||
|
const auto days = then.daysTo(now);
|
||||||
|
|
||||||
|
if (days == 0)
|
||||||
|
return then.toString("HH:mm");
|
||||||
|
else if (days < 2)
|
||||||
|
return QString("Yesterday");
|
||||||
|
else if (days < 365)
|
||||||
|
return then.toString("dd/MM");
|
||||||
|
|
||||||
|
return then.toString("dd/MM/yy");
|
||||||
|
}
|
||||||
|
|
||||||
|
DescInfo
|
||||||
|
utils::getMessageDescription(const TimelineEvent &event, const QString &localUser)
|
||||||
|
{
|
||||||
|
using Audio = mtx::events::RoomEvent<mtx::events::msg::Audio>;
|
||||||
|
using Emote = mtx::events::RoomEvent<mtx::events::msg::Emote>;
|
||||||
|
using File = mtx::events::RoomEvent<mtx::events::msg::File>;
|
||||||
|
using Image = mtx::events::RoomEvent<mtx::events::msg::Image>;
|
||||||
|
using Notice = mtx::events::RoomEvent<mtx::events::msg::Notice>;
|
||||||
|
using Text = mtx::events::RoomEvent<mtx::events::msg::Text>;
|
||||||
|
using Video = mtx::events::RoomEvent<mtx::events::msg::Video>;
|
||||||
|
|
||||||
|
if (mpark::holds_alternative<Audio>(event)) {
|
||||||
|
const auto msg = mpark::get<Audio>(event);
|
||||||
|
QString sender = QString::fromStdString(msg.sender);
|
||||||
|
|
||||||
|
const auto username = TimelineViewManager::displayName(sender);
|
||||||
|
const auto ts = QDateTime::fromMSecsSinceEpoch(msg.origin_server_ts);
|
||||||
|
|
||||||
|
return DescInfo{sender == localUser ? "You" : username,
|
||||||
|
sender,
|
||||||
|
" sent an audio clip",
|
||||||
|
utils::descriptiveTime(ts),
|
||||||
|
ts};
|
||||||
|
} else if (mpark::holds_alternative<Emote>(event)) {
|
||||||
|
auto msg = mpark::get<Emote>(event);
|
||||||
|
QString sender = QString::fromStdString(msg.sender);
|
||||||
|
|
||||||
|
const auto username = TimelineViewManager::displayName(sender);
|
||||||
|
const auto ts = QDateTime::fromMSecsSinceEpoch(msg.origin_server_ts);
|
||||||
|
const auto body = QString::fromStdString(msg.content.body).trimmed();
|
||||||
|
|
||||||
|
return DescInfo{"",
|
||||||
|
sender,
|
||||||
|
QString("* %1 %2").arg(username).arg(body),
|
||||||
|
utils::descriptiveTime(ts),
|
||||||
|
ts};
|
||||||
|
} else if (mpark::holds_alternative<File>(event)) {
|
||||||
|
const auto msg = mpark::get<File>(event);
|
||||||
|
QString sender = QString::fromStdString(msg.sender);
|
||||||
|
|
||||||
|
const auto username = TimelineViewManager::displayName(sender);
|
||||||
|
const auto ts = QDateTime::fromMSecsSinceEpoch(msg.origin_server_ts);
|
||||||
|
|
||||||
|
return DescInfo{sender == localUser ? "You" : username,
|
||||||
|
sender,
|
||||||
|
" sent a file",
|
||||||
|
utils::descriptiveTime(ts),
|
||||||
|
ts};
|
||||||
|
} else if (mpark::holds_alternative<Image>(event)) {
|
||||||
|
const auto msg = mpark::get<Image>(event);
|
||||||
|
QString sender = QString::fromStdString(msg.sender);
|
||||||
|
|
||||||
|
const auto username = TimelineViewManager::displayName(sender);
|
||||||
|
const auto ts = QDateTime::fromMSecsSinceEpoch(msg.origin_server_ts);
|
||||||
|
|
||||||
|
return DescInfo{sender == localUser ? "You" : username,
|
||||||
|
sender,
|
||||||
|
" sent an image",
|
||||||
|
utils::descriptiveTime(ts),
|
||||||
|
ts};
|
||||||
|
} else if (mpark::holds_alternative<Notice>(event)) {
|
||||||
|
const auto msg = mpark::get<Notice>(event);
|
||||||
|
QString sender = QString::fromStdString(msg.sender);
|
||||||
|
|
||||||
|
const auto username = TimelineViewManager::displayName(sender);
|
||||||
|
const auto ts = QDateTime::fromMSecsSinceEpoch(msg.origin_server_ts);
|
||||||
|
|
||||||
|
return DescInfo{
|
||||||
|
username, sender, " sent a notification", utils::descriptiveTime(ts), ts};
|
||||||
|
} else if (mpark::holds_alternative<Text>(event)) {
|
||||||
|
const auto msg = mpark::get<Text>(event);
|
||||||
|
QString sender = QString::fromStdString(msg.sender);
|
||||||
|
|
||||||
|
const auto username = TimelineViewManager::displayName(sender);
|
||||||
|
const auto ts = QDateTime::fromMSecsSinceEpoch(msg.origin_server_ts);
|
||||||
|
const auto body = QString::fromStdString(msg.content.body).trimmed();
|
||||||
|
|
||||||
|
return DescInfo{sender == localUser ? "You" : username,
|
||||||
|
sender,
|
||||||
|
QString(": %1").arg(body),
|
||||||
|
utils::descriptiveTime(ts),
|
||||||
|
ts};
|
||||||
|
} else if (mpark::holds_alternative<Video>(event)) {
|
||||||
|
const auto msg = mpark::get<Video>(event);
|
||||||
|
QString sender = QString::fromStdString(msg.sender);
|
||||||
|
|
||||||
|
const auto username = TimelineViewManager::displayName(sender);
|
||||||
|
const auto ts = QDateTime::fromMSecsSinceEpoch(msg.origin_server_ts);
|
||||||
|
|
||||||
|
return DescInfo{sender == localUser ? "You" : username,
|
||||||
|
sender,
|
||||||
|
" sent a video clip",
|
||||||
|
utils::descriptiveTime(ts),
|
||||||
|
ts};
|
||||||
|
}
|
||||||
|
|
||||||
|
return DescInfo{};
|
||||||
|
}
|
@ -84,9 +84,10 @@ TimelineItem::TimelineItem(mtx::events::MessageType ty,
|
|||||||
|
|
||||||
if (ty == mtx::events::MessageType::Emote) {
|
if (ty == mtx::events::MessageType::Emote) {
|
||||||
body = QString("* %1 %2").arg(displayName).arg(body);
|
body = QString("* %1 %2").arg(displayName).arg(body);
|
||||||
descriptionMsg_ = {"", userid, body, descriptiveTime(timestamp), timestamp};
|
descriptionMsg_ = {"", userid, body, utils::descriptiveTime(timestamp), timestamp};
|
||||||
} else {
|
} else {
|
||||||
descriptionMsg_ = {"You: ", userid, body, descriptiveTime(timestamp), timestamp};
|
descriptionMsg_ = {
|
||||||
|
"You: ", userid, body, utils::descriptiveTime(timestamp), timestamp};
|
||||||
}
|
}
|
||||||
|
|
||||||
body = body.toHtmlEscaped();
|
body = body.toHtmlEscaped();
|
||||||
@ -207,7 +208,7 @@ TimelineItem::TimelineItem(const mtx::events::RoomEvent<mtx::events::msg::Notice
|
|||||||
descriptionMsg_ = {TimelineViewManager::displayName(sender),
|
descriptionMsg_ = {TimelineViewManager::displayName(sender),
|
||||||
sender,
|
sender,
|
||||||
" sent a notification",
|
" sent a notification",
|
||||||
descriptiveTime(timestamp),
|
utils::descriptiveTime(timestamp),
|
||||||
timestamp};
|
timestamp};
|
||||||
|
|
||||||
generateTimestamp(timestamp);
|
generateTimestamp(timestamp);
|
||||||
@ -251,7 +252,7 @@ TimelineItem::TimelineItem(const mtx::events::RoomEvent<mtx::events::msg::Emote>
|
|||||||
auto displayName = TimelineViewManager::displayName(sender);
|
auto displayName = TimelineViewManager::displayName(sender);
|
||||||
auto emoteMsg = QString("* %1 %2").arg(displayName).arg(body);
|
auto emoteMsg = QString("* %1 %2").arg(displayName).arg(body);
|
||||||
|
|
||||||
descriptionMsg_ = {"", sender, emoteMsg, descriptiveTime(timestamp), timestamp};
|
descriptionMsg_ = {"", sender, emoteMsg, utils::descriptiveTime(timestamp), timestamp};
|
||||||
|
|
||||||
generateTimestamp(timestamp);
|
generateTimestamp(timestamp);
|
||||||
emoteMsg = emoteMsg.toHtmlEscaped();
|
emoteMsg = emoteMsg.toHtmlEscaped();
|
||||||
@ -293,7 +294,7 @@ TimelineItem::TimelineItem(const mtx::events::RoomEvent<mtx::events::msg::Text>
|
|||||||
descriptionMsg_ = {sender == settings.value("auth/user_id") ? "You" : displayName,
|
descriptionMsg_ = {sender == settings.value("auth/user_id") ? "You" : displayName,
|
||||||
sender,
|
sender,
|
||||||
QString(": %1").arg(body),
|
QString(": %1").arg(body),
|
||||||
descriptiveTime(timestamp),
|
utils::descriptiveTime(timestamp),
|
||||||
timestamp};
|
timestamp};
|
||||||
|
|
||||||
generateTimestamp(timestamp);
|
generateTimestamp(timestamp);
|
||||||
@ -463,23 +464,6 @@ TimelineItem::setUserAvatar(const QImage &avatar)
|
|||||||
userAvatar_->setImage(avatar);
|
userAvatar_->setImage(avatar);
|
||||||
}
|
}
|
||||||
|
|
||||||
QString
|
|
||||||
TimelineItem::descriptiveTime(const QDateTime &then)
|
|
||||||
{
|
|
||||||
auto now = QDateTime::currentDateTime();
|
|
||||||
|
|
||||||
auto days = then.daysTo(now);
|
|
||||||
|
|
||||||
if (days == 0)
|
|
||||||
return then.toString("HH:mm");
|
|
||||||
else if (days < 2)
|
|
||||||
return QString("Yesterday");
|
|
||||||
else if (days < 365)
|
|
||||||
return then.toString("dd/MM");
|
|
||||||
|
|
||||||
return then.toString("dd/MM/yy");
|
|
||||||
}
|
|
||||||
|
|
||||||
TimelineItem::~TimelineItem() {}
|
TimelineItem::~TimelineItem() {}
|
||||||
|
|
||||||
void
|
void
|
||||||
|
@ -22,6 +22,7 @@
|
|||||||
#include "Config.h"
|
#include "Config.h"
|
||||||
#include "FloatingButton.h"
|
#include "FloatingButton.h"
|
||||||
#include "RoomMessages.h"
|
#include "RoomMessages.h"
|
||||||
|
#include "Utils.h"
|
||||||
|
|
||||||
#include "timeline/TimelineView.h"
|
#include "timeline/TimelineView.h"
|
||||||
#include "timeline/widgets/AudioItem.h"
|
#include "timeline/widgets/AudioItem.h"
|
||||||
@ -29,6 +30,8 @@
|
|||||||
#include "timeline/widgets/ImageItem.h"
|
#include "timeline/widgets/ImageItem.h"
|
||||||
#include "timeline/widgets/VideoItem.h"
|
#include "timeline/widgets/VideoItem.h"
|
||||||
|
|
||||||
|
using TimelineEvent = mtx::events::collections::TimelineEvents;
|
||||||
|
|
||||||
TimelineView::TimelineView(const mtx::responses::Timeline &timeline,
|
TimelineView::TimelineView(const mtx::responses::Timeline &timeline,
|
||||||
QSharedPointer<MatrixClient> client,
|
QSharedPointer<MatrixClient> client,
|
||||||
const QString &room_id,
|
const QString &room_id,
|
||||||
@ -251,44 +254,90 @@ TimelineView::parseMessageEvent(const mtx::events::collections::TimelineEvents &
|
|||||||
return nullptr;
|
return nullptr;
|
||||||
}
|
}
|
||||||
|
|
||||||
int
|
void
|
||||||
TimelineView::addEvents(const mtx::responses::Timeline &timeline)
|
TimelineView::renderBottomEvents(const std::vector<TimelineEvent> &events)
|
||||||
{
|
{
|
||||||
int message_count = 0;
|
for (const auto &event : events) {
|
||||||
|
|
||||||
QSettings settings;
|
|
||||||
QString localUser = settings.value("auth/user_id").toString();
|
|
||||||
|
|
||||||
for (const auto &event : timeline.events) {
|
|
||||||
TimelineItem *item = parseMessageEvent(event, TimelineDirection::Bottom);
|
TimelineItem *item = parseMessageEvent(event, TimelineDirection::Bottom);
|
||||||
|
|
||||||
if (item != nullptr) {
|
if (item != nullptr)
|
||||||
addTimelineItem(item, TimelineDirection::Bottom);
|
addTimelineItem(item, TimelineDirection::Bottom);
|
||||||
|
|
||||||
if (localUser != getEventSender(event))
|
|
||||||
message_count += 1;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
lastMessageDirection_ = TimelineDirection::Bottom;
|
lastMessageDirection_ = TimelineDirection::Bottom;
|
||||||
|
|
||||||
QApplication::processEvents();
|
QApplication::processEvents();
|
||||||
|
}
|
||||||
|
|
||||||
|
int
|
||||||
|
TimelineView::addEvents(const mtx::responses::Timeline &timeline)
|
||||||
|
{
|
||||||
|
int message_count = 0;
|
||||||
|
|
||||||
if (isInitialSync) {
|
if (isInitialSync) {
|
||||||
prev_batch_token_ = QString::fromStdString(timeline.prev_batch);
|
prev_batch_token_ = QString::fromStdString(timeline.prev_batch);
|
||||||
isInitialSync = false;
|
isInitialSync = false;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Exclude the top stretch.
|
for (const auto &e : timeline.events) {
|
||||||
if (timeline.events.size() != 0 && scroll_layout_->count() > 1)
|
// Save the message if it can be rendered.
|
||||||
notifyForLastEvent();
|
if (isViewable(e))
|
||||||
|
bottomMessages_.push_back(e);
|
||||||
|
|
||||||
if (isActiveWindow() && isVisible() && timeline.events.size() > 0)
|
// Calculate notifications.
|
||||||
|
if (isNotifiable(e))
|
||||||
|
message_count += 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!bottomMessages_.empty())
|
||||||
|
notifyForLastEvent(bottomMessages_[bottomMessages_.size() - 1]);
|
||||||
|
|
||||||
|
// If the current timeline is open and there are messages to be rendered.
|
||||||
|
if (isVisible() && !bottomMessages_.empty()) {
|
||||||
|
renderBottomEvents(bottomMessages_);
|
||||||
|
|
||||||
|
// Free up space for new messages.
|
||||||
|
bottomMessages_.clear();
|
||||||
|
|
||||||
|
// Send a read receipt for the last event.
|
||||||
|
if (isActiveWindow())
|
||||||
readLastEvent();
|
readLastEvent();
|
||||||
|
}
|
||||||
|
|
||||||
return message_count;
|
return message_count;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
inline bool
|
||||||
|
TimelineView::isViewable(const TimelineEvent &event) const
|
||||||
|
{
|
||||||
|
namespace msg = mtx::events::msg;
|
||||||
|
|
||||||
|
return mpark::holds_alternative<mtx::events::RoomEvent<msg::Audio>>(event) ||
|
||||||
|
mpark::holds_alternative<mtx::events::RoomEvent<msg::Emote>>(event) ||
|
||||||
|
mpark::holds_alternative<mtx::events::RoomEvent<msg::File>>(event) ||
|
||||||
|
mpark::holds_alternative<mtx::events::RoomEvent<msg::Image>>(event) ||
|
||||||
|
mpark::holds_alternative<mtx::events::RoomEvent<msg::Notice>>(event) ||
|
||||||
|
mpark::holds_alternative<mtx::events::RoomEvent<msg::Text>>(event) ||
|
||||||
|
mpark::holds_alternative<mtx::events::RoomEvent<msg::Video>>(event);
|
||||||
|
}
|
||||||
|
|
||||||
|
inline bool
|
||||||
|
TimelineView::isNotifiable(const TimelineEvent &event) const
|
||||||
|
{
|
||||||
|
namespace msg = mtx::events::msg;
|
||||||
|
|
||||||
|
if (local_user_ == getEventSender(event))
|
||||||
|
return false;
|
||||||
|
|
||||||
|
return mpark::holds_alternative<mtx::events::RoomEvent<msg::Audio>>(event) ||
|
||||||
|
mpark::holds_alternative<mtx::events::RoomEvent<msg::Emote>>(event) ||
|
||||||
|
mpark::holds_alternative<mtx::events::RoomEvent<msg::File>>(event) ||
|
||||||
|
mpark::holds_alternative<mtx::events::RoomEvent<msg::Image>>(event) ||
|
||||||
|
mpark::holds_alternative<mtx::events::RoomEvent<msg::Notice>>(event) ||
|
||||||
|
mpark::holds_alternative<mtx::events::RoomEvent<msg::Text>>(event) ||
|
||||||
|
mpark::holds_alternative<mtx::events::RoomEvent<msg::Video>>(event);
|
||||||
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
TimelineView::init()
|
TimelineView::init()
|
||||||
{
|
{
|
||||||
@ -420,18 +469,17 @@ TimelineView::updatePendingMessage(int txn_id, QString event_id)
|
|||||||
void
|
void
|
||||||
TimelineView::addUserMessage(mtx::events::MessageType ty, const QString &body)
|
TimelineView::addUserMessage(mtx::events::MessageType ty, const QString &body)
|
||||||
{
|
{
|
||||||
QSettings settings;
|
auto with_sender = lastSender_ != local_user_;
|
||||||
auto user_id = settings.value("auth/user_id").toString();
|
|
||||||
auto with_sender = lastSender_ != user_id;
|
|
||||||
|
|
||||||
TimelineItem *view_item = new TimelineItem(ty, user_id, body, with_sender, scroll_widget_);
|
TimelineItem *view_item =
|
||||||
|
new TimelineItem(ty, local_user_, body, with_sender, scroll_widget_);
|
||||||
scroll_layout_->addWidget(view_item);
|
scroll_layout_->addWidget(view_item);
|
||||||
|
|
||||||
lastMessageDirection_ = TimelineDirection::Bottom;
|
lastMessageDirection_ = TimelineDirection::Bottom;
|
||||||
|
|
||||||
QApplication::processEvents();
|
QApplication::processEvents();
|
||||||
|
|
||||||
lastSender_ = user_id;
|
lastSender_ = local_user_;
|
||||||
|
|
||||||
int txn_id = client_->incrementTransactionId();
|
int txn_id = client_->incrementTransactionId();
|
||||||
PendingMessage message(ty, txn_id, body, "", "", view_item);
|
PendingMessage message(ty, txn_id, body, "", "", view_item);
|
||||||
@ -483,6 +531,15 @@ TimelineView::notifyForLastEvent()
|
|||||||
qWarning() << "Cast to TimelineView failed" << room_id_;
|
qWarning() << "Cast to TimelineView failed" << room_id_;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
TimelineView::notifyForLastEvent(const TimelineEvent &event)
|
||||||
|
{
|
||||||
|
auto descInfo = utils::getMessageDescription(event, local_user_);
|
||||||
|
|
||||||
|
if (!descInfo.timestamp.isEmpty())
|
||||||
|
emit updateLastTimelineMessage(room_id_, descInfo);
|
||||||
|
}
|
||||||
|
|
||||||
bool
|
bool
|
||||||
TimelineView::isPendingMessage(const QString &txnid,
|
TimelineView::isPendingMessage(const QString &txnid,
|
||||||
const QString &sender,
|
const QString &sender,
|
||||||
@ -575,6 +632,12 @@ TimelineView::getLastEventId() const
|
|||||||
void
|
void
|
||||||
TimelineView::showEvent(QShowEvent *event)
|
TimelineView::showEvent(QShowEvent *event)
|
||||||
{
|
{
|
||||||
|
if (!bottomMessages_.empty()) {
|
||||||
|
renderBottomEvents(bottomMessages_);
|
||||||
|
bottomMessages_.clear();
|
||||||
|
scrollDown();
|
||||||
|
}
|
||||||
|
|
||||||
readLastEvent();
|
readLastEvent();
|
||||||
|
|
||||||
QWidget::showEvent(event);
|
QWidget::showEvent(event);
|
||||||
|
Loading…
Reference in New Issue
Block a user