2021-03-05 02:35:15 +03:00
|
|
|
// SPDX-FileCopyrightText: 2021 Nheko Contributors
|
|
|
|
//
|
|
|
|
// SPDX-License-Identifier: GPL-3.0-or-later
|
|
|
|
|
2020-07-10 00:15:22 +03:00
|
|
|
#pragma once
|
|
|
|
|
|
|
|
#include <limits>
|
|
|
|
#include <string>
|
|
|
|
|
|
|
|
#include <QCache>
|
|
|
|
#include <QObject>
|
2020-07-19 13:22:54 +03:00
|
|
|
#include <QVariant>
|
2020-07-10 00:15:22 +03:00
|
|
|
|
|
|
|
#include <mtx/events/collections.hpp>
|
2020-07-13 01:08:58 +03:00
|
|
|
#include <mtx/responses/messages.hpp>
|
2020-07-10 00:15:22 +03:00
|
|
|
#include <mtx/responses/sync.hpp>
|
|
|
|
|
2020-07-19 13:22:54 +03:00
|
|
|
#include "Reaction.h"
|
|
|
|
|
2020-07-10 00:15:22 +03:00
|
|
|
class EventStore : public QObject
|
|
|
|
{
|
|
|
|
Q_OBJECT
|
|
|
|
|
|
|
|
public:
|
|
|
|
EventStore(std::string room_id, QObject *parent);
|
|
|
|
|
2021-03-14 17:32:14 +03:00
|
|
|
// taken from QtPrivate::QHashCombine
|
|
|
|
static uint hashCombine(uint hash, uint seed)
|
|
|
|
{
|
|
|
|
return seed ^ (hash + 0x9e3779b9 + (seed << 6) + (seed >> 2));
|
|
|
|
};
|
2020-07-10 00:15:22 +03:00
|
|
|
struct Index
|
|
|
|
{
|
|
|
|
std::string room;
|
2020-07-13 01:08:58 +03:00
|
|
|
uint64_t idx;
|
2020-07-10 00:15:22 +03:00
|
|
|
|
|
|
|
friend uint qHash(const Index &i, uint seed = 0) noexcept
|
|
|
|
{
|
2020-12-25 06:11:47 +03:00
|
|
|
seed =
|
2021-03-14 17:32:14 +03:00
|
|
|
hashCombine(qHashBits(i.room.data(), (int)i.room.size(), seed), seed);
|
|
|
|
seed = hashCombine(qHash(i.idx, seed), seed);
|
2020-07-10 00:15:22 +03:00
|
|
|
return seed;
|
|
|
|
}
|
|
|
|
|
|
|
|
friend bool operator==(const Index &a, const Index &b) noexcept
|
|
|
|
{
|
|
|
|
return a.idx == b.idx && a.room == b.room;
|
|
|
|
}
|
|
|
|
};
|
|
|
|
struct IdIndex
|
|
|
|
{
|
|
|
|
std::string room, id;
|
|
|
|
|
|
|
|
friend uint qHash(const IdIndex &i, uint seed = 0) noexcept
|
|
|
|
{
|
2020-12-25 06:11:47 +03:00
|
|
|
seed =
|
2021-03-14 17:32:14 +03:00
|
|
|
hashCombine(qHashBits(i.room.data(), (int)i.room.size(), seed), seed);
|
|
|
|
seed = hashCombine(qHashBits(i.id.data(), (int)i.id.size(), seed), seed);
|
2020-07-10 00:15:22 +03:00
|
|
|
return seed;
|
|
|
|
}
|
|
|
|
|
|
|
|
friend bool operator==(const IdIndex &a, const IdIndex &b) noexcept
|
|
|
|
{
|
|
|
|
return a.id == b.id && a.room == b.room;
|
|
|
|
}
|
|
|
|
};
|
|
|
|
|
|
|
|
void fetchMore();
|
|
|
|
void handleSync(const mtx::responses::Timeline &events);
|
|
|
|
|
|
|
|
// optionally returns the event or nullptr and fetches it, after which it emits a
|
|
|
|
// relatedFetched event
|
2021-05-30 02:09:16 +03:00
|
|
|
mtx::events::collections::TimelineEvents *get(std::string id,
|
2020-07-26 13:33:30 +03:00
|
|
|
std::string_view related_to,
|
2021-01-27 04:45:33 +03:00
|
|
|
bool decrypt = true,
|
|
|
|
bool resolve_edits = true);
|
2020-07-10 00:15:22 +03:00
|
|
|
// always returns a proper event as long as the idx is valid
|
2020-07-26 13:33:30 +03:00
|
|
|
mtx::events::collections::TimelineEvents *get(int idx, bool decrypt = true);
|
2020-07-10 00:15:22 +03:00
|
|
|
|
2020-07-19 13:22:54 +03:00
|
|
|
QVariantList reactions(const std::string &event_id);
|
|
|
|
|
2020-07-10 00:15:22 +03:00
|
|
|
int size() const
|
|
|
|
{
|
2021-01-12 02:02:18 +03:00
|
|
|
return (last != std::numeric_limits<uint64_t>::max() && last >= first)
|
2020-07-10 00:15:22 +03:00
|
|
|
? static_cast<int>(last - first) + 1
|
|
|
|
: 0;
|
|
|
|
}
|
2020-07-13 01:08:58 +03:00
|
|
|
int toExternalIdx(uint64_t idx) const { return static_cast<int>(idx - first); }
|
|
|
|
uint64_t toInternalIdx(int idx) const { return first + idx; }
|
2020-07-10 00:15:22 +03:00
|
|
|
|
|
|
|
std::optional<int> idToIndex(std::string_view id) const;
|
|
|
|
std::optional<std::string> indexToId(int idx) const;
|
|
|
|
|
|
|
|
signals:
|
|
|
|
void beginInsertRows(int from, int to);
|
|
|
|
void endInsertRows();
|
2020-07-13 01:08:58 +03:00
|
|
|
void beginResetModel();
|
|
|
|
void endResetModel();
|
2020-07-10 00:15:22 +03:00
|
|
|
void dataChanged(int from, int to);
|
|
|
|
void newEncryptedImage(mtx::crypto::EncryptedFile encryptionInfo);
|
2020-07-10 02:37:55 +03:00
|
|
|
void eventFetched(std::string id,
|
|
|
|
std::string relatedTo,
|
|
|
|
mtx::events::collections::TimelineEvents timeline);
|
2020-07-13 01:08:58 +03:00
|
|
|
void oldMessagesRetrieved(const mtx::responses::Messages &);
|
|
|
|
void fetchedMore();
|
2020-07-10 00:15:22 +03:00
|
|
|
|
2020-07-18 18:43:49 +03:00
|
|
|
void processPending();
|
2020-07-18 21:39:31 +03:00
|
|
|
void messageSent(std::string txn_id, std::string event_id);
|
2020-07-18 18:43:49 +03:00
|
|
|
void messageFailed(std::string txn_id);
|
2020-08-09 06:05:15 +03:00
|
|
|
void startDMVerification(
|
2020-10-06 18:02:41 +03:00
|
|
|
const mtx::events::RoomEvent<mtx::events::msg::KeyVerificationRequest> &msg);
|
2020-08-18 08:59:02 +03:00
|
|
|
void updateFlowEventId(std::string event_id);
|
2020-07-18 18:43:49 +03:00
|
|
|
|
|
|
|
public slots:
|
|
|
|
void addPending(mtx::events::collections::TimelineEvents event);
|
2020-10-20 20:46:37 +03:00
|
|
|
void receivedSessionKey(const std::string &session_id);
|
2020-08-10 00:36:47 +03:00
|
|
|
void clearTimeline();
|
2021-06-19 02:46:23 +03:00
|
|
|
void enableKeyRequests(bool suppressKeyRequests_);
|
2020-07-18 18:43:49 +03:00
|
|
|
|
2020-07-10 00:15:22 +03:00
|
|
|
private:
|
2021-01-27 04:45:33 +03:00
|
|
|
std::vector<mtx::events::collections::TimelineEvents> edits(const std::string &event_id);
|
2020-07-10 00:15:22 +03:00
|
|
|
mtx::events::collections::TimelineEvents *decryptEvent(
|
|
|
|
const IdIndex &idx,
|
|
|
|
const mtx::events::EncryptedEvent<mtx::events::msg::Encrypted> &e);
|
2020-09-08 18:09:31 +03:00
|
|
|
void handle_room_verification(mtx::events::collections::TimelineEvents event);
|
2020-07-10 00:15:22 +03:00
|
|
|
|
|
|
|
std::string room_id_;
|
|
|
|
|
2020-07-13 01:08:58 +03:00
|
|
|
uint64_t first = std::numeric_limits<uint64_t>::max(),
|
|
|
|
last = std::numeric_limits<uint64_t>::max();
|
2020-07-10 00:15:22 +03:00
|
|
|
|
|
|
|
static QCache<IdIndex, mtx::events::collections::TimelineEvents> decryptedEvents_;
|
|
|
|
static QCache<Index, mtx::events::collections::TimelineEvents> events_;
|
|
|
|
static QCache<IdIndex, mtx::events::collections::TimelineEvents> events_by_id_;
|
2020-07-18 18:43:49 +03:00
|
|
|
|
2020-10-20 20:46:37 +03:00
|
|
|
struct PendingKeyRequests
|
|
|
|
{
|
|
|
|
std::string request_id;
|
|
|
|
std::vector<mtx::events::EncryptedEvent<mtx::events::msg::Encrypted>> events;
|
|
|
|
};
|
|
|
|
std::map<std::string, PendingKeyRequests> pending_key_requests;
|
|
|
|
|
2020-07-18 18:43:49 +03:00
|
|
|
std::string current_txn;
|
|
|
|
int current_txn_error_count = 0;
|
2020-10-20 14:46:05 +03:00
|
|
|
bool noMoreMessages = false;
|
2021-06-19 02:46:23 +03:00
|
|
|
bool suppressKeyRequests = true;
|
2020-07-10 00:15:22 +03:00
|
|
|
};
|