Skip to content

Commit

Permalink
Merge #812(kitsune): Rework RoomMessageEvent content API again
Browse files Browse the repository at this point in the history
  • Loading branch information
KitsuneRal authored Oct 22, 2024
2 parents 2fd8b86 + 16ceb7a commit 6175147
Show file tree
Hide file tree
Showing 9 changed files with 182 additions and 152 deletions.
9 changes: 3 additions & 6 deletions Quotient/eventitem.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -10,12 +10,9 @@ using namespace Quotient;

void PendingEventItem::setFileUploaded(const FileSourceInfo& uploadedFileData)
{
if (auto* rme = getAs<RoomMessageEvent>()) {
Q_ASSERT(rme->hasFileContent());
auto fc = rme->fileContent();
fc->source = uploadedFileData;
rme->setContent(std::move(fc));
}
if (auto* rme = getAs<RoomMessageEvent>())
rme->updateFileSourceInfo(uploadedFileData);

if (auto* rae = getAs<RoomAvatarEvent>()) {
rae->editContent([&uploadedFileData](EventContent::FileInfo& fi) {
fi.source = uploadedFileData;
Expand Down
10 changes: 3 additions & 7 deletions Quotient/events/eventcontent.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -103,14 +103,10 @@ QJsonObject Quotient::EventContent::toInfoJson(const ImageInfo& info)
return infoJson;
}

Thumbnail::Thumbnail(const QJsonObject& infoJson,
const std::optional<EncryptedFileMetadata> &efm)
: ImageInfo(QUrl(infoJson["thumbnail_url"_L1].toString()),
Thumbnail::Thumbnail(const QJsonObject& infoJson)
: ImageInfo(fileSourceInfoFromJson(infoJson, { "thumbnail_url"_L1, "thumbnail_file"_L1 }),
infoJson["thumbnail_info"_L1].toObject())
{
if (efm)
source = *efm;
}
{}

void Thumbnail::dumpTo(QJsonObject& infoJson) const
{
Expand Down
57 changes: 31 additions & 26 deletions Quotient/events/eventcontent.h
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,10 @@

class QFileInfo;

namespace Quotient {
constexpr inline auto InfoKey = "info"_L1;
}

namespace Quotient::EventContent {
//! \brief Base for all content types that can be stored in RoomMessageEvent
//!
Expand Down Expand Up @@ -138,8 +142,7 @@ QUOTIENT_API QJsonObject toInfoJson(const ImageInfo& info);
//! `info/thumbnail_info` fields are used.
struct QUOTIENT_API Thumbnail : public ImageInfo {
using ImageInfo::ImageInfo;
explicit Thumbnail(const QJsonObject& infoJson,
const std::optional<EncryptedFileMetadata>& efm = {});
explicit Thumbnail(const QJsonObject& infoJson);

//! \brief Add thumbnail information to the passed `info` JSON object
void dumpTo(QJsonObject& infoJson) const;
Expand All @@ -148,8 +151,27 @@ struct QUOTIENT_API Thumbnail : public ImageInfo {
//! The base for all file-based content classes
class QUOTIENT_API FileContentBase : public Base {
public:
using Base::Base;
FileContentBase(const QJsonObject& contentJson = {})
: Base(contentJson), thumbnail(contentJson[InfoKey].toObject())
{}
virtual QUrl url() const = 0;
virtual FileInfo commonInfo() const = 0;

Thumbnail thumbnail;

protected:
virtual QJsonObject makeInfoJson() const = 0;

void fillJson(QJsonObject& json) const override
{
const auto fileInfo = commonInfo();
Quotient::fillJson(json, { "url"_L1, "file"_L1 }, fileInfo.source);
addParam<IfNotEmpty>(json, "filename"_L1, fileInfo.originalName);
auto infoJson = makeInfoJson();
if (thumbnail.isValid())
thumbnail.dumpTo(infoJson);
json.insert(InfoKey, infoJson);
}
};

//! \brief Rich text content for m.text, m.emote, m.notice
Expand Down Expand Up @@ -209,39 +231,20 @@ class UrlBasedContent : public FileContentBase, public InfoT {
using InfoT::InfoT;
explicit UrlBasedContent(const QJsonObject& json)
: FileContentBase(json)
, InfoT(fromJson<QUrl>(json["url"_L1]), json["info"_L1].toObject(),
, InfoT(fileSourceInfoFromJson(json, { "url"_L1, "file"_L1 }), json[InfoKey].toObject(),
json["filename"_L1].toString())
, thumbnail(FileInfo::originalInfoJson)
{
if (const auto efmJson = json.value("file"_L1).toObject();
!efmJson.isEmpty())
InfoT::source = fromJson<EncryptedFileMetadata>(efmJson);
// Two small hacks on originalJson to expose mediaIds to QML
originalJson.insert("mediaId"_L1, InfoT::mediaId());
originalJson.insert("thumbnailMediaId"_L1, thumbnail.mediaId());
}

QMimeType type() const override { return InfoT::mimeType; }
QUrl url() const override { return InfoT::url(); }

public:
Thumbnail thumbnail;
FileInfo commonInfo() const override { return SLICE(*this, FileInfo); }

protected:
virtual void fillInfoJson(QJsonObject& infoJson [[maybe_unused]]) const
{}

void fillJson(QJsonObject& json) const override
{
Quotient::fillJson(json, { "url"_L1, "file"_L1 }, InfoT::source);
if (!InfoT::originalName.isEmpty())
json.insert("filename"_L1, InfoT::originalName);
auto infoJson = toInfoJson(*this);
if (thumbnail.isValid())
thumbnail.dumpTo(infoJson);
fillInfoJson(infoJson);
json.insert("info"_L1, infoJson);
}
QJsonObject makeInfoJson() const override { return toInfoJson(*this); }
};

//! \brief Content class for m.image
Expand Down Expand Up @@ -288,9 +291,11 @@ class PlayableContent : public UrlBasedContent<InfoT> {
{}

protected:
void fillInfoJson(QJsonObject& infoJson) const override
QJsonObject makeInfoJson() const override
{
auto infoJson = UrlBasedContent<InfoT>::makeInfoJson();
infoJson.insert("duration"_L1, duration);
return infoJson;
}

public:
Expand Down
15 changes: 8 additions & 7 deletions Quotient/events/filesourceinfo.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -117,18 +117,19 @@ QUrl Quotient::getUrlFromSourceInfo(const FileSourceInfo& fsi) { return getUrl(f

void Quotient::setUrlInSourceInfo(FileSourceInfo& fsi, const QUrl& newUrl) { getUrl(fsi) = newUrl; }

void Quotient::fillJson(QJsonObject& jo,
const std::array<QLatin1String, 2>& jsonKeys,
void Quotient::fillJson(QJsonObject& jo, const FileSourceInfoKeys& jsonKeys,
const FileSourceInfo& fsi)
{
// NB: Keeping variant_size_v out of the function signature for readability.
// NB2: Can't use jsonKeys directly inside static_assert as its value is
// unknown so the compiler cannot ensure size() is constexpr (go figure...)
static_assert(
std::variant_size_v<FileSourceInfo> == decltype(jsonKeys) {}.size());
jo.insert(jsonKeys[fsi.index()], toJson(fsi));
}

FileSourceInfo Quotient::fileSourceInfoFromJson(const QJsonObject& jo,
const FileSourceInfoKeys& jsonKeys)
{
return jo.contains(jsonKeys[1]) ? fromJson<EncryptedFileMetadata>(jo[jsonKeys[1]])
: FileSourceInfo(fromJson<QUrl>(jo[jsonKeys[0]]));
}

namespace {
// A map from roomId/eventId pair to file source info
QHash<std::pair<QString, QString>, EncryptedFileMetadata> infos;
Expand Down
8 changes: 6 additions & 2 deletions Quotient/events/filesourceinfo.h
Original file line number Diff line number Diff line change
Expand Up @@ -69,6 +69,8 @@ struct QUOTIENT_API JsonObjectConverter<JWK> {

using FileSourceInfo = std::variant<QUrl, EncryptedFileMetadata>;

using FileSourceInfoKeys = std::array<QLatin1String, std::variant_size_v<FileSourceInfo>>;

QUOTIENT_API QUrl getUrlFromSourceInfo(const FileSourceInfo& fsi);

QUOTIENT_API void setUrlInSourceInfo(FileSourceInfo& fsi, const QUrl& newUrl);
Expand All @@ -86,10 +88,12 @@ void fillJson(QJsonObject&, const FileSourceInfo&) = delete;
//! - a key-to-object mapping where key is taken from jsonKeys[1] and the object
//! is the result of converting EncryptedFileMetadata to JSON,
//! if FileSourceInfo stores EncryptedFileMetadata
QUOTIENT_API void fillJson(QJsonObject& jo,
const std::array<QLatin1String, 2>& jsonKeys,
QUOTIENT_API void fillJson(QJsonObject& jo, const FileSourceInfoKeys& jsonKeys,
const FileSourceInfo& fsi);

QUOTIENT_API FileSourceInfo fileSourceInfoFromJson(const QJsonObject& jo,
const FileSourceInfoKeys& jsonKeys);

namespace FileMetadataMap {
QUOTIENT_API void add(const QString& roomId,
const QString& eventId,
Expand Down
Loading

0 comments on commit 6175147

Please sign in to comment.