This introduces a new NeoChatDateTime object that wraps a QDateTime. The intent is that it can be passed to QML and has a series of functions that format the QDateTime into the various string representations we need. This means we only have to send the single object to QML and then the correct string can be grabbed from there, simplifying the backend. It is also easy to add a new representation if needed as a function with a QString output and Q_PROPERTY can be added and then it will be available.
231 lines
9.1 KiB
C++
231 lines
9.1 KiB
C++
// SPDX-FileCopyrightText: 2023 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 <QDateTime>
|
|
#include <QString>
|
|
#include <Quotient/events/eventcontent.h>
|
|
|
|
#include "neochatdatetime.h"
|
|
|
|
namespace Quotient
|
|
{
|
|
namespace EventContent
|
|
{
|
|
class FileInfo;
|
|
}
|
|
class RoomEvent;
|
|
class RoomMember;
|
|
class RoomMessageEvent;
|
|
}
|
|
|
|
class NeoChatRoom;
|
|
|
|
/**
|
|
* @class EventHandler
|
|
*
|
|
* This class is designed to handle a Quotient::RoomEvent allowing data to be extracted
|
|
* in a form ready for the NeoChat UI.
|
|
*
|
|
* To use this properly both the room and the event should be set (and the event should
|
|
* be from the given room).
|
|
*
|
|
* @note EventHandler will always try to return something even when not properly
|
|
* initialised, this is usually the best empty value it can create with available
|
|
* information. This is to minimize warnings from QML especially during startup
|
|
* and room changes.
|
|
*/
|
|
class EventHandler
|
|
{
|
|
public:
|
|
/**
|
|
* @brief Get the display name of the event author.
|
|
*
|
|
* This method is special in that it will return
|
|
* the old display name of the author if the current event is one that caused it
|
|
* to change. This allows for scenarios where the UI wishes to notify that a
|
|
* user's display name has changed and what it changed from.
|
|
*
|
|
* @param isPending whether the event is pending as this cannot be derived from
|
|
* just the event object.
|
|
*/
|
|
static QString authorDisplayName(const NeoChatRoom *room, const Quotient::RoomEvent *event, bool isPending = false);
|
|
|
|
/**
|
|
* @brief Get the display name of the event author but with any newlines removed.
|
|
*
|
|
* Turns out you can put newlines in your display name so we need to handle that
|
|
* primarily for the room list subtitle.
|
|
*
|
|
* @param isPending whether the event is pending as this cannot be derived from
|
|
* just the event object.
|
|
*/
|
|
static QString singleLineAuthorDisplayname(const NeoChatRoom *room, const Quotient::RoomEvent *event, bool isPending = false);
|
|
|
|
/**
|
|
* @brief Return a QDateTime object for the event timestamp.
|
|
*/
|
|
static NeoChatDateTime dateTime(const NeoChatRoom *room, const Quotient::RoomEvent *event, bool isPending = false);
|
|
|
|
/**
|
|
* @brief Whether the event should be highlighted in the timeline.
|
|
*
|
|
* @note Messages in direct chats are never highlighted.
|
|
*/
|
|
static bool isHighlighted(const NeoChatRoom *room, const Quotient::RoomEvent *event);
|
|
|
|
/**
|
|
* @brief Whether the event should be hidden in the timeline.
|
|
*
|
|
* This could be for numerous reasons, e.g. if it's a replacement event, if the
|
|
* user has hidden all state events or if the sender has been ignored by the local
|
|
* user.
|
|
*/
|
|
static bool isHidden(const NeoChatRoom *room, const Quotient::RoomEvent *event, std::function<bool(const Quotient::RoomEvent *)> filter = {});
|
|
|
|
/**
|
|
* @brief The input format of the body in the message.
|
|
*
|
|
* I.e. if the message has only a body the format will be Qt::PlainText, if it
|
|
* has a formatted body it will be Qt::RichText.
|
|
*/
|
|
static Qt::TextFormat messageBodyInputFormat(const Quotient::RoomEvent &event);
|
|
|
|
/**
|
|
* @brief Output a string for the message content without any formatting.
|
|
*
|
|
* This is the content of the formatted_body key if present or the body key if
|
|
* not.
|
|
*/
|
|
static QString rawMessageBody(const Quotient::RoomEvent &event);
|
|
|
|
/**
|
|
* @brief Output a string for the message content ready for display in a rich text field.
|
|
*
|
|
* The output string is dependant upon the event type and the desired output format.
|
|
*
|
|
* For most messages this is the body content of the message. For media messages
|
|
* this will be the caption and for state events it will be a string specific
|
|
* to that event with some dynamic details about the event added.
|
|
*
|
|
* E.g. For a room topic state event the text will be:
|
|
* "set the topic to: <new topic text>"
|
|
*
|
|
* @param stripNewlines whether the output should have new lines in it.
|
|
*/
|
|
static QString richBody(const NeoChatRoom *room, const Quotient::RoomEvent *event, bool stripNewlines = false);
|
|
|
|
/**
|
|
* @brief Output a string for the message content ready for display in a plain text field.
|
|
*
|
|
* The output string is dependant upon the event type and the desired output format.
|
|
*
|
|
* For most messages this is the body content of the message. For media messages
|
|
* this will be the caption and for state events it will be a string specific
|
|
* to that event with some dynamic details about the event added.
|
|
*
|
|
* E.g. For a room topic state event the text will be:
|
|
* "set the topic to: <new topic text>"
|
|
*
|
|
* @param stripNewlines whether the output should have new lines in it.
|
|
*/
|
|
static QString plainBody(const NeoChatRoom *room, const Quotient::RoomEvent *event, bool stripNewlines = false);
|
|
|
|
/**
|
|
* @brief Output the original body for the message content, useful for editing the original message.
|
|
*
|
|
* The event type must be a room message event.
|
|
*/
|
|
static QString markdownBody(const Quotient::RoomEvent *event);
|
|
|
|
/**
|
|
* @brief Output a generic string for the message content ready for display.
|
|
*
|
|
* The output string is dependant upon the event type.
|
|
*
|
|
* Unlike EventHandler::getRichBody or EventHandler::getPlainBody the string
|
|
* is the same for all events of the same type.
|
|
*
|
|
* E.g. For a message the text will be:
|
|
* "sent a message"
|
|
*
|
|
* @sa richBody(), plainBody()
|
|
*/
|
|
static QString genericBody(const NeoChatRoom *room, const Quotient::RoomEvent *event);
|
|
|
|
/**
|
|
* @brief Output a string for the event to be used as a RoomList subtitle.
|
|
*
|
|
* The output includes the username followed by the plain message, all with no
|
|
* line breaks.
|
|
*/
|
|
static QString subtitleText(const NeoChatRoom *room, const Quotient::RoomEvent *event);
|
|
|
|
/**
|
|
* @brief Return the media info for the event.
|
|
*
|
|
* An empty QVariantMap will be returned for any event that doesn't have any
|
|
* media info.
|
|
*
|
|
* @return This should consist of the following:
|
|
* - source - The mxc URL for the media.
|
|
* - mimeType - The MIME type of the media (should be image/xxx for this delegate).
|
|
* - mimeIcon - The MIME icon name (should be image-xxx).
|
|
* - size - The file size in bytes.
|
|
* - width - The width in pixels of the audio media.
|
|
* - height - The height in pixels of the audio media.
|
|
* - tempInfo - mediaInfo (with the same properties as this except no tempInfo) for a temporary image while the file downloads.
|
|
* - isSticker - Whether the image is a sticker or not
|
|
*/
|
|
static QVariantMap mediaInfo(const NeoChatRoom *room, const Quotient::RoomEvent *event);
|
|
|
|
/**
|
|
* @brief Get the author of the event replied to in context of the room.
|
|
*
|
|
* An empty Quotient::RoomMember will be returned if the EventHandler hasn't had
|
|
* the room or event initialised.
|
|
*
|
|
* @param isPending if the event is pending, i.e. has not been confirmed by
|
|
* the server.
|
|
*
|
|
* @return a Quotient::RoomMember object for the user.
|
|
*
|
|
* @sa Quotient::RoomMember
|
|
*/
|
|
static Quotient::RoomMember replyAuthor(const NeoChatRoom *room, const Quotient::RoomEvent *event);
|
|
|
|
/**
|
|
* @brief Return the latitude for the event.
|
|
*
|
|
* Returns -100.0 if the event doesn't have a location (latitudes are in the
|
|
* range -90deg to +90deg so -100 is out of range).
|
|
*/
|
|
static float latitude(const Quotient::RoomEvent *event);
|
|
|
|
/**
|
|
* @brief Return the longitude for the event.
|
|
*
|
|
* Returns -200.0 if the event doesn't have a location (latitudes are in the
|
|
* range -180deg to +180deg so -200 is out of range).
|
|
*/
|
|
static float longitude(const Quotient::RoomEvent *event);
|
|
|
|
/**
|
|
* @brief Return the type of location marker for the event.
|
|
*/
|
|
static QString locationAssetType(const Quotient::RoomEvent *event);
|
|
|
|
private:
|
|
static QString getBody(const NeoChatRoom *room, const Quotient::RoomEvent *event, Qt::TextFormat format, bool stripNewlines);
|
|
static QString getMessageBody(const NeoChatRoom *room, const Quotient::RoomMessageEvent &event, Qt::TextFormat format, bool stripNewlines);
|
|
|
|
static QVariantMap getMediaInfoForEvent(const NeoChatRoom *room, const Quotient::RoomEvent *event);
|
|
QVariantMap static getMediaInfoFromFileInfo(const NeoChatRoom *room,
|
|
const Quotient::EventContent::FileContentBase *fileContent,
|
|
const QString &eventId,
|
|
bool isThumbnail = false,
|
|
bool isSticker = false);
|
|
static QVariantMap getMediaInfoFromTumbnail(const NeoChatRoom *room, const Quotient::EventContent::Thumbnail &thumbnail, const QString &eventId);
|
|
};
|