diff options
Diffstat (limited to 'src/Utils.cpp')
-rw-r--r-- | src/Utils.cpp | 188 |
1 files changed, 188 insertions, 0 deletions
diff --git a/src/Utils.cpp b/src/Utils.cpp new file mode 100644 index 00000000..2247c2b7 --- /dev/null +++ b/src/Utils.cpp @@ -0,0 +1,188 @@ +#include "Utils.h" + +#include <QApplication> +#include <QDesktopWidget> + +#include <variant.hpp> + +using TimelineEvent = mtx::events::collections::TimelineEvents; + +QString +utils::descriptiveTime(const QDateTime &then) +{ + const auto now = QDateTime::currentDateTime(); + const auto days = then.daysTo(now); + + if (days == 0) + return then.toString("HH:mm"); + else if (days < 2) + return QString("Yesterday"); + else if (days < 365) + return then.toString("dd/MM"); + + return then.toString("dd/MM/yy"); +} + +DescInfo +utils::getMessageDescription(const TimelineEvent &event, + const QString &localUser, + const QString &room_id) +{ + 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 Text = mtx::events::RoomEvent<mtx::events::msg::Text>; + using Video = mtx::events::RoomEvent<mtx::events::msg::Video>; + using Encrypted = mtx::events::EncryptedEvent<mtx::events::msg::Encrypted>; + + if (mpark::holds_alternative<Audio>(event)) { + return createDescriptionInfo<Audio>(event, localUser, room_id); + } else if (mpark::holds_alternative<Emote>(event)) { + return createDescriptionInfo<Emote>(event, localUser, room_id); + } else if (mpark::holds_alternative<File>(event)) { + return createDescriptionInfo<File>(event, localUser, room_id); + } else if (mpark::holds_alternative<Image>(event)) { + return createDescriptionInfo<Image>(event, localUser, room_id); + } else if (mpark::holds_alternative<Notice>(event)) { + return createDescriptionInfo<Notice>(event, localUser, room_id); + } else if (mpark::holds_alternative<Text>(event)) { + return createDescriptionInfo<Text>(event, localUser, room_id); + } else if (mpark::holds_alternative<Video>(event)) { + return createDescriptionInfo<Video>(event, localUser, room_id); + } else if (mpark::holds_alternative<mtx::events::Sticker>(event)) { + return createDescriptionInfo<mtx::events::Sticker>(event, localUser, room_id); + } else if (mpark::holds_alternative<Encrypted>(event)) { + const auto msg = mpark::get<Encrypted>(event); + const auto sender = QString::fromStdString(msg.sender); + + const auto username = Cache::displayName(room_id, sender); + const auto ts = QDateTime::fromMSecsSinceEpoch(msg.origin_server_ts); + + DescInfo info; + if (sender == localUser) + info.username = "You"; + else + info.username = username; + + info.userid = sender; + info.body = QString(" %1").arg(messageDescription<Encrypted>()); + info.timestamp = utils::descriptiveTime(ts); + info.datetime = ts; + + return info; + } else { + std::cout << "type not found: " << serialize_event(event).dump(2) << '\n'; + } + + return DescInfo{}; +} + +QString +utils::firstChar(const QString &input) +{ + if (input.isEmpty()) + return input; + + for (auto const &c : input.toUcs4()) { + if (QString::fromUcs4(&c, 1) != QString("#")) + return QString::fromUcs4(&c, 1).toUpper(); + } + + return QString::fromUcs4(&input.toUcs4().at(0), 1).toUpper(); +} + +QString +utils::humanReadableFileSize(uint64_t bytes) +{ + constexpr static const char *units[] = {"B", "KiB", "MiB", "GiB", "TiB"}; + constexpr static const int length = sizeof(units) / sizeof(units[0]); + + int u = 0; + double size = static_cast<double>(bytes); + while (size >= 1024.0 && u < length) { + ++u; + size /= 1024.0; + } + + return QString::number(size, 'g', 4) + ' ' + units[u]; +} + +int +utils::levenshtein_distance(const std::string &s1, const std::string &s2) +{ + const int nlen = s1.size(); + const int hlen = s2.size(); + + if (hlen == 0) + return -1; + if (nlen == 1) + return s2.find(s1); + + std::vector<int> row1(hlen + 1, 0); + + for (int i = 0; i < nlen; ++i) { + std::vector<int> row2(1, i + 1); + + for (int j = 0; j < hlen; ++j) { + const int cost = s1[i] != s2[j]; + row2.push_back( + std::min(row1[j + 1] + 1, std::min(row2[j] + 1, row1[j] + cost))); + } + + row1.swap(row2); + } + + return *std::min_element(row1.begin(), row1.end()); +} + +QString +utils::event_body(const mtx::events::collections::TimelineEvents &event) +{ + using namespace mtx::events; + using namespace mtx::events::msg; + + if (mpark::holds_alternative<RoomEvent<Audio>>(event)) { + return message_body<RoomEvent<Audio>>(event); + } else if (mpark::holds_alternative<RoomEvent<Emote>>(event)) { + return message_body<RoomEvent<Emote>>(event); + } else if (mpark::holds_alternative<RoomEvent<File>>(event)) { + return message_body<RoomEvent<File>>(event); + } else if (mpark::holds_alternative<RoomEvent<Image>>(event)) { + return message_body<RoomEvent<Image>>(event); + } else if (mpark::holds_alternative<RoomEvent<Notice>>(event)) { + return message_body<RoomEvent<Notice>>(event); + } else if (mpark::holds_alternative<Sticker>(event)) { + return message_body<Sticker>(event); + } else if (mpark::holds_alternative<RoomEvent<Text>>(event)) { + return message_body<RoomEvent<Text>>(event); + } else if (mpark::holds_alternative<RoomEvent<Video>>(event)) { + return message_body<RoomEvent<Video>>(event); + } + + return QString(); +} + +QPixmap +utils::scaleImageToPixmap(const QImage &img, int size) +{ + if (img.isNull()) + return QPixmap(); + + const int sz = QApplication::desktop()->screen()->devicePixelRatio() * size; + return QPixmap::fromImage( + img.scaled(sz, sz, Qt::IgnoreAspectRatio, Qt::SmoothTransformation)); +} + +QString +utils::mxcToHttp(const QUrl &url, const QString &server, int port) +{ + auto mxcParts = mtx::client::utils::parse_mxc_url(url.toString().toStdString()); + + return QString("https://%1:%2/_matrix/media/r0/download/%3/%4") + .arg(server) + .arg(port) + .arg(QString::fromStdString(mxcParts.server)) + .arg(QString::fromStdString(mxcParts.media_id)); +} |