nheko/src/timeline/EventStore.h

146 lines
5.3 KiB
C
Raw Normal View History

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