Move NeoChatConnection and NeoChatRoom to LibNeoChat
Move `NeoChatConnection` and `NeoChatRoom` to `LibNeoChat` along with any required dependencies.
This commit is contained in:
83
src/libneochat/events/imagepackevent.cpp
Normal file
83
src/libneochat/events/imagepackevent.cpp
Normal file
@@ -0,0 +1,83 @@
|
||||
// SPDX-FileCopyrightText: 2021-2023 Tobias Fella <tobias.fella@kde.org>
|
||||
// SPDX-License-Identifier: LGPL-2.0-or-later
|
||||
|
||||
#include "imagepackevent.h"
|
||||
#include <QJsonObject>
|
||||
|
||||
using namespace Quotient;
|
||||
|
||||
ImagePackEventContent::ImagePackEventContent(const QJsonObject &json)
|
||||
{
|
||||
if (json.contains("pack"_L1)) {
|
||||
pack = ImagePackEventContent::Pack{
|
||||
fromJson<std::optional<QString>>(json["pack"_L1].toObject()["display_name"_L1]),
|
||||
fromJson<std::optional<QUrl>>(json["pack"_L1].toObject()["avatar_url"_L1]),
|
||||
fromJson<std::optional<QStringList>>(json["pack"_L1].toObject()["usage"_L1]),
|
||||
fromJson<std::optional<QString>>(json["pack"_L1].toObject()["attribution"_L1]),
|
||||
};
|
||||
} else {
|
||||
pack = std::nullopt;
|
||||
}
|
||||
|
||||
const auto &keys = json["images"_L1].toObject().keys();
|
||||
for (const auto &k : keys) {
|
||||
std::optional<EventContent::ImageInfo> info;
|
||||
if (json["images"_L1][k].toObject().contains("info"_L1)) {
|
||||
info = EventContent::ImageInfo(QUrl(json["images"_L1][k]["url"_L1].toString()), json["images"_L1][k]["info"_L1].toObject(), k);
|
||||
} else {
|
||||
info = std::nullopt;
|
||||
}
|
||||
images += ImagePackImage{
|
||||
k,
|
||||
fromJson<QUrl>(json["images"_L1][k]["url"_L1].toString()),
|
||||
fromJson<std::optional<QString>>(json["images"_L1][k]["body"_L1]),
|
||||
info,
|
||||
fromJson<std::optional<QStringList>>(json["images"_L1][k]["usage"_L1]),
|
||||
};
|
||||
}
|
||||
}
|
||||
|
||||
void ImagePackEventContent::fillJson(QJsonObject *o) const
|
||||
{
|
||||
if (pack) {
|
||||
QJsonObject packJson;
|
||||
if (pack->displayName) {
|
||||
packJson["display_name"_L1] = *pack->displayName;
|
||||
}
|
||||
if (pack->usage) {
|
||||
QJsonArray usageJson;
|
||||
for (const auto &usage : *pack->usage) {
|
||||
usageJson += usage;
|
||||
}
|
||||
packJson["usage"_L1] = usageJson;
|
||||
}
|
||||
if (pack->avatarUrl) {
|
||||
packJson["avatar_url"_L1] = pack->avatarUrl->toString();
|
||||
}
|
||||
if (pack->attribution) {
|
||||
packJson["attribution"_L1] = *pack->attribution;
|
||||
}
|
||||
(*o)["pack"_L1] = packJson;
|
||||
}
|
||||
|
||||
QJsonObject imagesJson;
|
||||
for (const auto &image : images) {
|
||||
QJsonObject imageJson;
|
||||
imageJson["url"_L1] = image.url.toString();
|
||||
if (image.body) {
|
||||
imageJson["body"_L1] = *image.body;
|
||||
}
|
||||
if (image.usage) {
|
||||
QJsonArray usageJson;
|
||||
for (const auto &usage : *image.usage) {
|
||||
usageJson += usage;
|
||||
}
|
||||
imageJson["usage"_L1] = usageJson;
|
||||
}
|
||||
if (image.info.has_value()) {
|
||||
imageJson["info"_L1] = Quotient::EventContent::toInfoJson(*image.info);
|
||||
}
|
||||
imagesJson[image.shortcode] = imageJson;
|
||||
}
|
||||
(*o)["images"_L1] = imagesJson;
|
||||
}
|
||||
92
src/libneochat/events/imagepackevent.h
Normal file
92
src/libneochat/events/imagepackevent.h
Normal file
@@ -0,0 +1,92 @@
|
||||
// SPDX-FileCopyrightText: 2021-2023 Tobias Fella <tobias.fella@kde.org>
|
||||
// SPDX-License-Identifier: LGPL-2.0-or-later
|
||||
|
||||
#pragma once
|
||||
|
||||
#include <QList>
|
||||
#include <Quotient/events/eventcontent.h>
|
||||
#include <Quotient/events/stateevent.h>
|
||||
|
||||
namespace Quotient
|
||||
{
|
||||
/**
|
||||
* @class ImagePackEventContent
|
||||
*
|
||||
* A class to define the content of an image pack event.
|
||||
*
|
||||
* See Matrix MSC2545 for more details.
|
||||
* https://github.com/Sorunome/matrix-doc/blob/soru/emotes/proposals/2545-emotes.md
|
||||
*
|
||||
* @sa ImagePackEvent
|
||||
*/
|
||||
class ImagePackEventContent
|
||||
{
|
||||
public:
|
||||
/**
|
||||
* @brief Defines the properties of an image pack.
|
||||
*/
|
||||
struct Pack {
|
||||
std::optional<QString> displayName; /**< The display name of the pack. */
|
||||
std::optional<QUrl> avatarUrl; /**< The source mxc URL for the pack avatar. */
|
||||
std::optional<QStringList> usage; /**< An array of the usages for this pack. Possible usages are "emoticon" and "sticker". */
|
||||
std::optional<QString> attribution; /**< The attribution for the pack author(s). */
|
||||
};
|
||||
|
||||
/**
|
||||
* @brief Defines the properties of an image pack image.
|
||||
*/
|
||||
struct ImagePackImage {
|
||||
QString shortcode; /**< The shortcode for the image. */
|
||||
QUrl url; /**< The mxc URL for this image. */
|
||||
std::optional<QString> body; /**< An optional text body for this image. */
|
||||
std::optional<Quotient::EventContent::ImageInfo> info; /**< The ImageInfo object used for the info block of m.sticker events. */
|
||||
/**
|
||||
* @brief An array of the usages for this image.
|
||||
*
|
||||
* The possible values match those of the usage key of a pack object.
|
||||
*/
|
||||
std::optional<QStringList> usage;
|
||||
};
|
||||
|
||||
/**
|
||||
* @brief Return the pack properties.
|
||||
*
|
||||
* @sa Pack
|
||||
*/
|
||||
std::optional<Pack> pack;
|
||||
|
||||
/**
|
||||
* @brief Return a vector of images in the pack.
|
||||
*
|
||||
* @sa ImagePackImage
|
||||
*/
|
||||
QList<ImagePackEventContent::ImagePackImage> images;
|
||||
|
||||
explicit ImagePackEventContent(const QJsonObject &o);
|
||||
|
||||
/**
|
||||
* @brief The definition of how to convert the content to Json.
|
||||
*
|
||||
* This is a specialization of the standard fillJson function from libQuotient.
|
||||
*
|
||||
* @sa Quotient::converters
|
||||
*/
|
||||
void fillJson(QJsonObject *o) const;
|
||||
};
|
||||
|
||||
/**
|
||||
* @class ImagePackEvent
|
||||
*
|
||||
* Class to define an image pack state event.
|
||||
*
|
||||
* The event content is ImagePackEventContent.
|
||||
*
|
||||
* @sa Quotient::StateEvent, ImagePackEventContent
|
||||
*/
|
||||
class ImagePackEvent : public KeyedStateEventBase<ImagePackEvent, ImagePackEventContent>
|
||||
{
|
||||
public:
|
||||
QUO_EVENT(ImagePackEvent, "im.ponies.room_emotes")
|
||||
using KeyedStateEventBase::KeyedStateEventBase;
|
||||
};
|
||||
}
|
||||
14
src/libneochat/events/locationbeaconevent.h
Normal file
14
src/libneochat/events/locationbeaconevent.h
Normal file
@@ -0,0 +1,14 @@
|
||||
// SPDX-FileCopyrightText: 2024 James Graham <james.h.graham@protonmail.com>
|
||||
// SPDX-License-Identifier: GPL-2.0-only OR GPL-3.0-only OR LicenseRef-KDE-Accepted-GPL
|
||||
|
||||
#pragma once
|
||||
|
||||
#include <Quotient/events/simplestateevents.h>
|
||||
|
||||
namespace Quotient
|
||||
{
|
||||
|
||||
// Defined so we can directly switch on type.
|
||||
DEFINE_SIMPLE_STATE_EVENT(LocationBeaconEvent, "org.matrix.msc3672.beacon_info", QString, body, "body")
|
||||
|
||||
} // namespace Quotient
|
||||
72
src/libneochat/events/pollevent.cpp
Normal file
72
src/libneochat/events/pollevent.cpp
Normal file
@@ -0,0 +1,72 @@
|
||||
// SPDX-FileCopyrightText: 2022 Tobias Fella <tobias.fella@kde.org>
|
||||
// SPDX-License-Identifier: LGPL-2.0-or-later
|
||||
|
||||
#include "pollevent.h"
|
||||
#include <Quotient/converters.h>
|
||||
|
||||
using namespace Quotient;
|
||||
|
||||
PollKind::Kind PollStartEvent::kind() const
|
||||
{
|
||||
return content().kind;
|
||||
}
|
||||
|
||||
int PollStartEvent::maxSelections() const
|
||||
{
|
||||
return content().maxSelection > 0 ? content().maxSelection : 1;
|
||||
}
|
||||
|
||||
QString PollStartEvent::question() const
|
||||
{
|
||||
return content().question;
|
||||
}
|
||||
|
||||
QList<EventContent::Answer> PollStartEvent::answers() const
|
||||
{
|
||||
return content().answers;
|
||||
}
|
||||
|
||||
PollResponseEvent::PollResponseEvent(const QJsonObject &obj)
|
||||
: RoomEvent(obj)
|
||||
{
|
||||
}
|
||||
|
||||
PollResponseEvent::PollResponseEvent(const QString &pollStartEventId, QStringList responses)
|
||||
: RoomEvent(basicJson(TypeId,
|
||||
{{"org.matrix.msc3381.poll.response"_L1, QJsonObject{{"answers"_L1, QJsonArray::fromStringList(responses)}}},
|
||||
{"m.relates_to"_L1, QJsonObject{{"rel_type"_L1, "m.reference"_L1}, {"event_id"_L1, pollStartEventId}}}}))
|
||||
{
|
||||
}
|
||||
|
||||
QStringList PollResponseEvent::selections() const
|
||||
{
|
||||
const auto jsonSelections = contentPart<QJsonObject>("org.matrix.msc3381.poll.response"_L1)["answers"_L1].toArray();
|
||||
QStringList selections;
|
||||
for (const auto &selection : jsonSelections) {
|
||||
selections += selection.toString();
|
||||
}
|
||||
return selections;
|
||||
}
|
||||
|
||||
std::optional<EventRelation> PollResponseEvent::relatesTo() const
|
||||
{
|
||||
return contentPart<std::optional<EventRelation>>(RelatesToKey);
|
||||
}
|
||||
|
||||
PollEndEvent::PollEndEvent(const QJsonObject &obj)
|
||||
: RoomEvent(obj)
|
||||
{
|
||||
}
|
||||
|
||||
PollEndEvent::PollEndEvent(const QString &pollStartEventId, const QString &endText)
|
||||
: RoomEvent(basicJson(TypeId,
|
||||
{{"org.matrix.msc1767.text"_L1, endText},
|
||||
{"org.matrix.msc3381.poll.end"_L1, QJsonObject{}},
|
||||
{"m.relates_to"_L1, QJsonObject{{"rel_type"_L1, "m.reference"_L1}, {"event_id"_L1, pollStartEventId}}}}))
|
||||
{
|
||||
}
|
||||
|
||||
std::optional<EventRelation> PollEndEvent::relatesTo() const
|
||||
{
|
||||
return contentPart<std::optional<EventRelation>>(RelatesToKey);
|
||||
}
|
||||
235
src/libneochat/events/pollevent.h
Normal file
235
src/libneochat/events/pollevent.h
Normal file
@@ -0,0 +1,235 @@
|
||||
// SPDX-FileCopyrightText: 2022 Tobias Fella <tobias.fella@kde.org>
|
||||
// SPDX-License-Identifier: LGPL-2.0-or-later
|
||||
|
||||
#pragma once
|
||||
|
||||
#include <QQmlEngine>
|
||||
|
||||
#include <Quotient/converters.h>
|
||||
#include <Quotient/events/eventrelation.h>
|
||||
#include <Quotient/events/roomevent.h>
|
||||
#include <Quotient/quotient_common.h>
|
||||
|
||||
using namespace Qt::StringLiterals;
|
||||
|
||||
/**
|
||||
* @class PollKind
|
||||
*
|
||||
* This class is designed to define the PollKind enumeration.
|
||||
*/
|
||||
class PollKind : public QObject
|
||||
{
|
||||
Q_OBJECT
|
||||
QML_ELEMENT
|
||||
QML_UNCREATABLE("")
|
||||
|
||||
public:
|
||||
/**
|
||||
* @brief Enum representing the available poll kinds.
|
||||
*/
|
||||
enum Kind {
|
||||
Disclosed, /**< The poll results can been seen after the user votes. */
|
||||
Undisclosed, /**< The poll results can only been seen after the poll ends. */
|
||||
};
|
||||
Q_ENUM(Kind);
|
||||
|
||||
/**
|
||||
* @brief Return the string for the given Kind.
|
||||
*
|
||||
* @sa Kind
|
||||
*/
|
||||
static QString stringForKind(Kind kind)
|
||||
{
|
||||
switch (kind) {
|
||||
case Undisclosed:
|
||||
return "org.matrix.msc3381.poll.undisclosed"_L1;
|
||||
default:
|
||||
return "org.matrix.msc3381.poll.disclosed"_L1;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Return the Kind for the given string.
|
||||
*
|
||||
* @sa Kind
|
||||
*/
|
||||
static Kind kindForString(const QString &kindString)
|
||||
{
|
||||
if (kindString == "org.matrix.msc3381.poll.undisclosed"_L1) {
|
||||
return Undisclosed;
|
||||
}
|
||||
return Disclosed;
|
||||
}
|
||||
};
|
||||
|
||||
namespace Quotient
|
||||
{
|
||||
namespace EventContent
|
||||
{
|
||||
|
||||
/**
|
||||
* @brief An answer to the poll.
|
||||
*/
|
||||
struct Answer {
|
||||
Q_GADGET
|
||||
Q_PROPERTY(QString id MEMBER id CONSTANT)
|
||||
Q_PROPERTY(QString text MEMBER text CONSTANT)
|
||||
|
||||
public:
|
||||
QString id;
|
||||
QString text;
|
||||
|
||||
int operator==(const Answer &right) const
|
||||
{
|
||||
return id == right.id && text == right.text;
|
||||
}
|
||||
};
|
||||
|
||||
/**
|
||||
* @brief Struct representing the content of a poll event.
|
||||
*/
|
||||
struct PollStartContent {
|
||||
PollKind::Kind kind;
|
||||
int maxSelection;
|
||||
QString question;
|
||||
QList<EventContent::Answer> answers;
|
||||
};
|
||||
|
||||
} // namespace EventContent
|
||||
|
||||
template<>
|
||||
inline EventContent::Answer fromJson(const QJsonObject &jo)
|
||||
{
|
||||
return EventContent::Answer{fromJson<QString>(jo["id"_L1]), fromJson<QString>(jo["org.matrix.msc1767.text"_L1])};
|
||||
}
|
||||
|
||||
template<>
|
||||
inline auto toJson(const EventContent::Answer &c)
|
||||
{
|
||||
QJsonObject jo;
|
||||
addParam<IfNotEmpty>(jo, "id"_L1, c.id);
|
||||
addParam<IfNotEmpty>(jo, "org.matrix.msc1767.text"_L1, c.text);
|
||||
return jo;
|
||||
}
|
||||
|
||||
template<>
|
||||
inline EventContent::PollStartContent fromJson(const QJsonObject &jo)
|
||||
{
|
||||
return EventContent::PollStartContent{
|
||||
PollKind::kindForString(jo["org.matrix.msc3381.poll.start"_L1]["kind"_L1].toString()),
|
||||
fromJson<int>(jo["org.matrix.msc3381.poll.start"_L1]["max_selections"_L1]),
|
||||
fromJson<QString>(jo["org.matrix.msc3381.poll.start"_L1]["question"_L1]["org.matrix.msc1767.text"_L1]),
|
||||
fromJson<QList<EventContent::Answer>>(jo["org.matrix.msc3381.poll.start"_L1]["answers"_L1]),
|
||||
};
|
||||
}
|
||||
|
||||
template<>
|
||||
inline auto toJson(const EventContent::PollStartContent &c)
|
||||
{
|
||||
QJsonObject innerJo;
|
||||
addParam<IfNotEmpty>(innerJo, "kind"_L1, PollKind::stringForKind(c.kind));
|
||||
addParam(innerJo, "max_selections"_L1, c.maxSelection);
|
||||
if (innerJo["max_selections"_L1].toInt() < 1) {
|
||||
innerJo["max_selections"_L1] = 1;
|
||||
}
|
||||
innerJo.insert("question"_L1, QJsonObject{{"org.matrix.msc1767.text"_L1, c.question}});
|
||||
addParam<IfNotEmpty>(innerJo, "answers"_L1, c.answers);
|
||||
|
||||
QJsonObject jo;
|
||||
auto textString = c.question;
|
||||
for (int i = 0; i < c.answers.length(); ++i) {
|
||||
textString.append("\n%1. %2"_L1.arg(QString::number(i + 1), c.answers.at(i).text));
|
||||
}
|
||||
addParam<IfNotEmpty>(jo, "org.matrix.msc1767.text"_L1, textString);
|
||||
jo.insert("org.matrix.msc3381.poll.start"_L1, innerJo);
|
||||
return jo;
|
||||
}
|
||||
|
||||
/**
|
||||
* @class PollStartEvent
|
||||
*
|
||||
* Class to define a poll start event.
|
||||
*
|
||||
* See MSC3381 for full details on polls in the matrix spec
|
||||
* https://github.com/matrix-org/matrix-spec-proposals/blob/travis/msc/polls/proposals/3381-polls.md.
|
||||
*
|
||||
* @sa Quotient::RoomEvent
|
||||
*/
|
||||
class PollStartEvent : public EventTemplate<PollStartEvent, RoomEvent, EventContent::PollStartContent>
|
||||
{
|
||||
public:
|
||||
QUO_EVENT(PollStartEvent, "org.matrix.msc3381.poll.start");
|
||||
using EventTemplate::EventTemplate;
|
||||
|
||||
/**
|
||||
* @brief The poll kind.
|
||||
*/
|
||||
PollKind::Kind kind() const;
|
||||
|
||||
/**
|
||||
* @brief The maximum number of options a user can select in a poll.
|
||||
*/
|
||||
int maxSelections() const;
|
||||
|
||||
/**
|
||||
* @brief The question being asked in the poll.
|
||||
*/
|
||||
QString question() const;
|
||||
|
||||
/**
|
||||
* @brief The list of answers to the poll.
|
||||
*/
|
||||
QList<EventContent::Answer> answers() const;
|
||||
};
|
||||
|
||||
/**
|
||||
* @class PollResponseEvent
|
||||
*
|
||||
* Class to define a poll response event.
|
||||
*
|
||||
* See MSC3381 for full details on polls in the matrix spec
|
||||
* https://github.com/matrix-org/matrix-spec-proposals/blob/travis/msc/polls/proposals/3381-polls.md.
|
||||
*
|
||||
* @sa Quotient::RoomEvent
|
||||
*/
|
||||
class PollResponseEvent : public RoomEvent
|
||||
{
|
||||
public:
|
||||
QUO_EVENT(PollResponseEvent, "org.matrix.msc3381.poll.response");
|
||||
explicit PollResponseEvent(const QJsonObject &obj);
|
||||
explicit PollResponseEvent(const QString &pollStartEventId, QStringList responses);
|
||||
|
||||
/**
|
||||
* @brief The selected answers to the poll.
|
||||
*/
|
||||
QStringList selections() const;
|
||||
|
||||
/**
|
||||
* @brief The EventRelation pointing to the PollStartEvent.
|
||||
*/
|
||||
std::optional<EventRelation> relatesTo() const;
|
||||
};
|
||||
|
||||
/**
|
||||
* @class PollEndEvent
|
||||
*
|
||||
* Class to define a poll end event.
|
||||
*
|
||||
* See MSC3381 for full details on polls in the matrix spec
|
||||
* https://github.com/matrix-org/matrix-spec-proposals/blob/travis/msc/polls/proposals/3381-polls.md.
|
||||
*
|
||||
* @sa Quotient::RoomEvent
|
||||
*/
|
||||
class PollEndEvent : public RoomEvent
|
||||
{
|
||||
public:
|
||||
QUO_EVENT(PollEndEvent, "org.matrix.msc3381.poll.end");
|
||||
explicit PollEndEvent(const QJsonObject &obj);
|
||||
explicit PollEndEvent(const QString &pollStartEventId, const QString &endText);
|
||||
|
||||
/**
|
||||
* @brief The EventRelation pointing to the PollStartEvent.
|
||||
*/
|
||||
std::optional<EventRelation> relatesTo() const;
|
||||
};
|
||||
}
|
||||
14
src/libneochat/events/widgetevent.h
Normal file
14
src/libneochat/events/widgetevent.h
Normal file
@@ -0,0 +1,14 @@
|
||||
// SPDX-FileCopyrightText: 2024 James Graham <james.h.graham@protonmail.com>
|
||||
// SPDX-License-Identifier: GPL-2.0-only OR GPL-3.0-only OR LicenseRef-KDE-Accepted-GPL
|
||||
|
||||
#pragma once
|
||||
|
||||
#include <Quotient/events/simplestateevents.h>
|
||||
|
||||
namespace Quotient
|
||||
{
|
||||
|
||||
// Defined so we can directly switch on type.
|
||||
DEFINE_SIMPLE_STATE_EVENT(WidgetEvent, "im.vector.modular.widgets", QString, name, "name")
|
||||
|
||||
} // namespace Quotient
|
||||
Reference in New Issue
Block a user