|
|
|
@ -5,14 +5,14 @@ |
|
|
|
|
#pragma once |
|
|
|
|
|
|
|
|
|
#include <CacheStructs.h> |
|
|
|
|
#include <QCoreApplication> |
|
|
|
|
#include <QDateTime> |
|
|
|
|
#include <QPixmap> |
|
|
|
|
#include <QRegularExpression> |
|
|
|
|
#include <mtx/events/collections.hpp> |
|
|
|
|
#include <mtx/events/common.hpp> |
|
|
|
|
#include <mtx/events.hpp> |
|
|
|
|
|
|
|
|
|
#include <qmath.h> |
|
|
|
|
namespace mtx::events::collections { |
|
|
|
|
struct TimelineEvents; |
|
|
|
|
struct StateEvents; |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
struct DescInfo; |
|
|
|
|
|
|
|
|
@ -85,131 +85,6 @@ firstChar(const QString &input); |
|
|
|
|
QString |
|
|
|
|
humanReadableFileSize(uint64_t bytes); |
|
|
|
|
|
|
|
|
|
//! Match widgets/events with a description message.
|
|
|
|
|
template<class T> |
|
|
|
|
QString |
|
|
|
|
messageDescription(const QString &username = QString(), |
|
|
|
|
const QString &body = QString(), |
|
|
|
|
const bool isLocal = false) |
|
|
|
|
{ |
|
|
|
|
using Audio = mtx::events::RoomEvent<mtx::events::msg::Audio>; |
|
|
|
|
using Emote = mtx::events::RoomEvent<mtx::events::msg::Emote>; |
|
|
|
|
using File = mtx::events::RoomEvent<mtx::events::msg::File>; |
|
|
|
|
using Image = mtx::events::RoomEvent<mtx::events::msg::Image>; |
|
|
|
|
using Notice = mtx::events::RoomEvent<mtx::events::msg::Notice>; |
|
|
|
|
using Sticker = mtx::events::Sticker; |
|
|
|
|
using Text = mtx::events::RoomEvent<mtx::events::msg::Text>; |
|
|
|
|
using Unknown = mtx::events::RoomEvent<mtx::events::msg::Unknown>; |
|
|
|
|
using Video = mtx::events::RoomEvent<mtx::events::msg::Video>; |
|
|
|
|
using ElementEffect = mtx::events::RoomEvent<mtx::events::msg::ElementEffect>; |
|
|
|
|
using CallInvite = mtx::events::RoomEvent<mtx::events::voip::CallInvite>; |
|
|
|
|
using CallAnswer = mtx::events::RoomEvent<mtx::events::voip::CallAnswer>; |
|
|
|
|
using CallHangUp = mtx::events::RoomEvent<mtx::events::voip::CallHangUp>; |
|
|
|
|
using CallReject = mtx::events::RoomEvent<mtx::events::voip::CallReject>; |
|
|
|
|
using Encrypted = mtx::events::EncryptedEvent<mtx::events::msg::Encrypted>; |
|
|
|
|
|
|
|
|
|
if (std::is_same<T, Audio>::value) { |
|
|
|
|
if (isLocal) |
|
|
|
|
return QCoreApplication::translate("message-description sent:", |
|
|
|
|
"You sent an audio clip"); |
|
|
|
|
else |
|
|
|
|
return QCoreApplication::translate("message-description sent:", "%1 sent an audio clip") |
|
|
|
|
.arg(username); |
|
|
|
|
} else if (std::is_same<T, Image>::value) { |
|
|
|
|
if (isLocal) |
|
|
|
|
return QCoreApplication::translate("message-description sent:", "You sent an image"); |
|
|
|
|
else |
|
|
|
|
return QCoreApplication::translate("message-description sent:", "%1 sent an image") |
|
|
|
|
.arg(username); |
|
|
|
|
} else if (std::is_same<T, File>::value) { |
|
|
|
|
if (isLocal) |
|
|
|
|
return QCoreApplication::translate("message-description sent:", "You sent a file"); |
|
|
|
|
else |
|
|
|
|
return QCoreApplication::translate("message-description sent:", "%1 sent a file") |
|
|
|
|
.arg(username); |
|
|
|
|
} else if (std::is_same<T, Video>::value) { |
|
|
|
|
if (isLocal) |
|
|
|
|
return QCoreApplication::translate("message-description sent:", "You sent a video"); |
|
|
|
|
else |
|
|
|
|
return QCoreApplication::translate("message-description sent:", "%1 sent a video") |
|
|
|
|
.arg(username); |
|
|
|
|
} else if (std::is_same<T, Sticker>::value) { |
|
|
|
|
if (isLocal) |
|
|
|
|
return QCoreApplication::translate("message-description sent:", "You sent a sticker"); |
|
|
|
|
else |
|
|
|
|
return QCoreApplication::translate("message-description sent:", "%1 sent a sticker") |
|
|
|
|
.arg(username); |
|
|
|
|
} else if (std::is_same<T, Notice>::value) { |
|
|
|
|
if (isLocal) |
|
|
|
|
return QCoreApplication::translate("message-description sent:", |
|
|
|
|
"You sent a notification"); |
|
|
|
|
else |
|
|
|
|
return QCoreApplication::translate("message-description sent:", |
|
|
|
|
"%1 sent a notification") |
|
|
|
|
.arg(username); |
|
|
|
|
} else if (std::is_same<T, Text>::value || std::is_same<T, Unknown>::value) { |
|
|
|
|
if (isLocal) |
|
|
|
|
return QCoreApplication::translate("message-description sent:", "You: %1").arg(body); |
|
|
|
|
else |
|
|
|
|
return QCoreApplication::translate("message-description sent:", "%1: %2") |
|
|
|
|
.arg(username, body); |
|
|
|
|
} else if (std::is_same<T, ElementEffect>::value) { |
|
|
|
|
if (body.isEmpty()) { |
|
|
|
|
// TODO: what is the best way to handle this?
|
|
|
|
|
if (isLocal) |
|
|
|
|
return QCoreApplication::translate("message-description sent:", |
|
|
|
|
"You sent a chat effect"); |
|
|
|
|
else |
|
|
|
|
return QCoreApplication::translate("message-description sent:", |
|
|
|
|
"%1 sent a chat effect") |
|
|
|
|
.arg(username); |
|
|
|
|
} else { |
|
|
|
|
if (isLocal) |
|
|
|
|
return QCoreApplication::translate("message-description sent:", "You: %1") |
|
|
|
|
.arg(body); |
|
|
|
|
else |
|
|
|
|
return QCoreApplication::translate("message-description sent:", "%1: %2") |
|
|
|
|
.arg(username, body); |
|
|
|
|
} |
|
|
|
|
} else if (std::is_same<T, Emote>::value) { |
|
|
|
|
return QStringLiteral("* %1 %2").arg(username, body); |
|
|
|
|
} else if (std::is_same<T, Encrypted>::value) { |
|
|
|
|
if (isLocal) |
|
|
|
|
return QCoreApplication::translate("message-description sent:", |
|
|
|
|
"You sent an encrypted message"); |
|
|
|
|
else |
|
|
|
|
return QCoreApplication::translate("message-description sent:", |
|
|
|
|
"%1 sent an encrypted message") |
|
|
|
|
.arg(username); |
|
|
|
|
} else if (std::is_same<T, CallInvite>::value) { |
|
|
|
|
if (isLocal) |
|
|
|
|
return QCoreApplication::translate("message-description sent:", "You placed a call"); |
|
|
|
|
else |
|
|
|
|
return QCoreApplication::translate("message-description sent:", "%1 placed a call") |
|
|
|
|
.arg(username); |
|
|
|
|
} else if (std::is_same<T, CallAnswer>::value) { |
|
|
|
|
if (isLocal) |
|
|
|
|
return QCoreApplication::translate("message-description sent:", "You answered a call"); |
|
|
|
|
else |
|
|
|
|
return QCoreApplication::translate("message-description sent:", "%1 answered a call") |
|
|
|
|
.arg(username); |
|
|
|
|
} else if (std::is_same<T, CallHangUp>::value) { |
|
|
|
|
if (isLocal) |
|
|
|
|
return QCoreApplication::translate("message-description sent:", "You ended a call"); |
|
|
|
|
else |
|
|
|
|
return QCoreApplication::translate("message-description sent:", "%1 ended a call") |
|
|
|
|
.arg(username); |
|
|
|
|
} else if (std::is_same<T, CallReject>::value) { |
|
|
|
|
if (isLocal) |
|
|
|
|
return QCoreApplication::translate("message-description sent:", "You rejected a call"); |
|
|
|
|
else |
|
|
|
|
return QCoreApplication::translate("message-description sent:", "%1 rejected a call") |
|
|
|
|
.arg(username); |
|
|
|
|
} else { |
|
|
|
|
return QCoreApplication::translate("utils", "Unknown Message Type"); |
|
|
|
|
} |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
//! Scale down an image to fit to the given width & height limitations.
|
|
|
|
|
QPixmap |
|
|
|
|
scaleDown(uint64_t maxWidth, uint64_t maxHeight, const QPixmap &source); |
|
|
|
@ -227,13 +102,6 @@ erase_if(ContainerT &items, const PredicateT &predicate) |
|
|
|
|
} |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
template<class T> |
|
|
|
|
QString |
|
|
|
|
message_body(const mtx::events::collections::TimelineEvents &event) |
|
|
|
|
{ |
|
|
|
|
return QString::fromStdString(std::get<T>(event).content.body); |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
//! Calculate the Levenshtein distance between two strings with character skipping.
|
|
|
|
|
int |
|
|
|
|
levenshtein_distance(const std::string &s1, const std::string &s2); |
|
|
|
@ -249,9 +117,6 @@ mxcToHttp(const QUrl &url, const QString &server, int port); |
|
|
|
|
QString |
|
|
|
|
humanReadableFingerprint(const std::string &ed25519); |
|
|
|
|
|
|
|
|
|
QString |
|
|
|
|
humanReadableFingerprint(const QString &ed25519); |
|
|
|
|
|
|
|
|
|
//! Retrieve the message body taking into account the `formatted_body` field.
|
|
|
|
|
//! If the `format` of the message is not supported we fallback to `body`.
|
|
|
|
|
template<typename RoomMessageT> |
|
|
|
|