diff --git a/include/Cache.h b/include/Cache.h
index 3d906f02..5d65c80c 100644
--- a/include/Cache.h
+++ b/include/Cache.h
@@ -19,8 +19,10 @@
#include <boost/optional.hpp>
+#include <QDateTime>
#include <QDir>
#include <QImage>
+#include <QString>
#include <json.hpp>
#include <lmdb++.h>
@@ -46,9 +48,24 @@ struct SearchResult
QString display_name;
};
+inline int
+numeric_key_comparison(const MDB_val *a, const MDB_val *b)
+{
+ auto lhs = std::stoul(std::string((char *)a->mv_data, a->mv_size));
+ auto rhs = std::stoul(std::string((char *)b->mv_data, b->mv_size));
+
+ if (lhs < rhs)
+ return 1;
+ else if (lhs == rhs)
+ return 0;
+
+ return -1;
+}
+
Q_DECLARE_METATYPE(SearchResult)
Q_DECLARE_METATYPE(QVector<SearchResult>)
Q_DECLARE_METATYPE(RoomMember)
+Q_DECLARE_METATYPE(mtx::responses::Timeline)
//! Used to uniquely identify a list of read receipts.
struct ReadReceiptKey
@@ -70,6 +87,15 @@ from_json(const json &j, ReadReceiptKey &key)
key.room_id = j.at("room_id").get<std::string>();
}
+struct DescInfo
+{
+ QString username;
+ QString userid;
+ QString body;
+ QString timestamp;
+ QDateTime datetime;
+};
+
//! UI info associated with a room.
struct RoomInfo
{
@@ -86,6 +112,8 @@ struct RoomInfo
//! Who can access to the room.
JoinRule join_rule = JoinRule::Public;
bool guest_access = false;
+ //! Metadata describing the last message in the timeline.
+ DescInfo msgInfo;
};
inline void
@@ -289,6 +317,8 @@ public:
bool isFormatValid();
void setCurrentFormat();
+ std::map<QString, mtx::responses::Timeline> roomMessages();
+
//! Retrieve all the user ids from a room.
std::vector<std::string> roomMembers(const std::string &room_id);
@@ -402,6 +432,13 @@ private:
QString getInviteRoomTopic(lmdb::txn &txn, lmdb::dbi &statesdb);
QString getInviteRoomAvatarUrl(lmdb::txn &txn, lmdb::dbi &statesdb, lmdb::dbi &membersdb);
+ DescInfo getLastMessageInfo(lmdb::txn &txn, const std::string &room_id);
+ void saveTimelineMessages(lmdb::txn &txn,
+ const std::string &room_id,
+ const mtx::responses::Timeline &res);
+
+ mtx::responses::Timeline getTimelineMessages(lmdb::txn &txn, const std::string &room_id);
+
//! Remove a room from the cache.
// void removeLeftRoom(lmdb::txn &txn, const std::string &room_id);
template<class T>
@@ -500,6 +537,7 @@ private:
mpark::holds_alternative<StateEvent<HistoryVisibility>>(e) ||
mpark::holds_alternative<StateEvent<JoinRules>>(e) ||
mpark::holds_alternative<StateEvent<Name>>(e) ||
+ mpark::holds_alternative<StateEvent<Member>>(e) ||
mpark::holds_alternative<StateEvent<PowerLevels>>(e) ||
mpark::holds_alternative<StateEvent<Topic>>(e);
}
@@ -544,6 +582,15 @@ private:
}
}
+ lmdb::dbi getMessagesDb(lmdb::txn &txn, const std::string &room_id)
+ {
+ auto db =
+ lmdb::dbi::open(txn, std::string(room_id + "/messages").c_str(), MDB_CREATE);
+ lmdb::dbi_set_compare(txn, db, numeric_key_comparison);
+
+ return db;
+ }
+
lmdb::dbi getInviteStatesDb(lmdb::txn &txn, const std::string &room_id)
{
return lmdb::dbi::open(
diff --git a/include/ChatPage.h b/include/ChatPage.h
index ffea2914..a4c6ccc5 100644
--- a/include/ChatPage.h
+++ b/include/ChatPage.h
@@ -108,7 +108,6 @@ signals:
void showLoginPage(const QString &msg);
void showUserSettingsPage();
void showOverlayProgressBar();
- void startConsesusTimer();
void removeTimelineEvent(const QString &room_id, const QString &event_id);
@@ -124,7 +123,7 @@ signals:
void initializeRoomList(QMap<QString, RoomInfo>);
void initializeViews(const mtx::responses::Rooms &rooms);
- void initializeEmptyViews(const std::vector<std::string> &rooms);
+ void initializeEmptyViews(const std::map<QString, mtx::responses::Timeline> &msgs);
void syncUI(const mtx::responses::Rooms &rooms);
void syncRoomlist(const std::map<QString, RoomInfo> &updates);
void syncTopBar(const std::map<QString, RoomInfo> &updates);
@@ -206,9 +205,6 @@ private:
TextInputWidget *text_input_;
TypingDisplay *typingDisplay_;
- // Safety net if consensus is not possible or too slow.
- QTimer *showContentTimer_;
- QTimer *consensusTimer_;
QTimer connectivityTimer_;
std::atomic_bool isConnected_;
diff --git a/include/RoomInfoListItem.h b/include/RoomInfoListItem.h
index aebc2216..95db1d75 100644
--- a/include/RoomInfoListItem.h
+++ b/include/RoomInfoListItem.h
@@ -22,20 +22,11 @@
#include <QSharedPointer>
#include <QWidget>
+#include "Cache.h"
#include <mtx/responses.hpp>
class Menu;
class RippleOverlay;
-struct RoomInfo;
-
-struct DescInfo
-{
- QString username;
- QString userid;
- QString body;
- QString timestamp;
- QDateTime datetime;
-};
class RoomInfoListItem : public QWidget
{
diff --git a/include/Utils.h b/include/Utils.h
index ad8e2073..7db405b1 100644
--- a/include/Utils.h
+++ b/include/Utils.h
@@ -41,14 +41,15 @@ template<class T>
QString
messageDescription(const QString &username = "", const QString &body = "")
{
- 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 Sticker = mtx::events::Sticker;
- using Text = mtx::events::RoomEvent<mtx::events::msg::Text>;
- using Video = mtx::events::RoomEvent<mtx::events::msg::Video>;
+ 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 Sticker = mtx::events::Sticker;
+ using Text = mtx::events::RoomEvent<mtx::events::msg::Text>;
+ using Video = mtx::events::RoomEvent<mtx::events::msg::Video>;
+ using Encrypted = mtx::events::EncryptedEvent<mtx::events::msg::Encrypted>;
if (std::is_same<T, AudioItem>::value || std::is_same<T, Audio>::value)
return QString("sent an audio clip");
@@ -66,6 +67,8 @@ messageDescription(const QString &username = "", const QString &body = "")
return QString(": %1").arg(body);
else if (std::is_same<T, Emote>::value)
return QString("* %1 %2").arg(username).arg(body);
+ else if (std::is_same<T, Encrypted>::value)
+ return QString("sent an encrypted message");
}
template<class T, class Event>
@@ -135,6 +138,18 @@ erase_if(ContainerT &items, const PredicateT &predicate)
}
}
+inline uint64_t
+event_timestamp(const mtx::events::collections::TimelineEvents &event)
+{
+ return mpark::visit([](auto msg) { return msg.origin_server_ts; }, event);
+}
+
+inline nlohmann::json
+serialize_event(const mtx::events::collections::TimelineEvents &event)
+{
+ return mpark::visit([](auto msg) { return json(msg); }, event);
+}
+
inline mtx::events::EventType
event_type(const mtx::events::collections::TimelineEvents &event)
{
diff --git a/include/timeline/TimelineView.h b/include/timeline/TimelineView.h
index bbe1dcad..7f1912ea 100644
--- a/include/timeline/TimelineView.h
+++ b/include/timeline/TimelineView.h
@@ -158,6 +158,7 @@ public:
//! Remove an item from the timeline with the given Event ID.
void removeEvent(const QString &event_id);
+ void setPrevBatchToken(const QString &token) { prev_batch_token_ = token; }
public slots:
void sliderRangeChanged(int min, int max);
diff --git a/include/timeline/TimelineViewManager.h b/include/timeline/TimelineViewManager.h
index 9e31ecbf..590adb2b 100644
--- a/include/timeline/TimelineViewManager.h
+++ b/include/timeline/TimelineViewManager.h
@@ -27,6 +27,7 @@ class QFile;
class RoomInfoListItem;
class TimelineView;
struct DescInfo;
+struct SavedMessages;
class TimelineViewManager : public QStackedWidget
{
@@ -57,6 +58,7 @@ signals:
public slots:
void removeTimelineEvent(const QString &room_id, const QString &event_id);
+ void initWithMessages(const std::map<QString, mtx::responses::Timeline> &msgs);
void setHistoryView(const QString &room_id);
void queueTextMessage(const QString &msg);
|