/**************************************************************************** * Copyright (C) 2017-2022 Savoir-faire Linux Inc. * * Author: Nicolas Jäger * * Author: Sébastien Blin * * * * This library is free software; you can redistribute it and/or * * modify it under the terms of the GNU Lesser General Public * * License as published by the Free Software Foundation; either * * version 2.1 of the License, or (at your option) any later version. * * * * This library is distributed in the hope that it will be useful, * * but WITHOUT ANY WARRANTY; without even the implied warranty of * * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * * Lesser General Public License for more details. * * * * You should have received a copy of the GNU General Public License * * along with this program. If not, see . * ***************************************************************************/ #pragma once #include #include #include #include "typedefs.h" namespace lrc { namespace api { namespace interaction { Q_NAMESPACE Q_CLASSINFO("RegisterEnumClassesUnscoped", "false") enum class Type { INVALID, INITIAL, TEXT, CALL, CONTACT, DATA_TRANSFER, MERGE, EDITED, COUNT__ }; Q_ENUM_NS(Type) static inline const QString to_string(const Type& type) { switch (type) { case Type::TEXT: return "TEXT"; case Type::INITIAL: return "INITIAL"; case Type::CALL: return "CALL"; case Type::CONTACT: return "CONTACT"; case Type::DATA_TRANSFER: return "DATA_TRANSFER"; case Type::MERGE: return "MERGE"; case Type::EDITED: return "EDITED"; case Type::INVALID: case Type::COUNT__: default: return "INVALID"; } } static inline Type to_type(const QString& type) { if (type == "INITIAL" || type == "initial") return interaction::Type::INITIAL; else if (type == "TEXT" || type == "text/plain") return interaction::Type::TEXT; else if (type == "CALL" || type == "application/call-history+json") return interaction::Type::CALL; else if (type == "CONTACT" || type == "member") return interaction::Type::CONTACT; else if (type == "DATA_TRANSFER" || type == "application/data-transfer+json") return interaction::Type::DATA_TRANSFER; else if (type == "merge") return interaction::Type::MERGE; else if (type == "application/edited-message") return interaction::Type::EDITED; else return interaction::Type::INVALID; } enum class Status { INVALID, UNKNOWN, SENDING, FAILURE, SUCCESS, DISPLAYED, TRANSFER_CREATED, TRANSFER_ACCEPTED, TRANSFER_CANCELED, TRANSFER_ERROR, TRANSFER_UNJOINABLE_PEER, TRANSFER_ONGOING, TRANSFER_AWAITING_PEER, TRANSFER_AWAITING_HOST, TRANSFER_TIMEOUT_EXPIRED, TRANSFER_FINISHED, COUNT__ }; Q_ENUM_NS(Status) static inline const QString to_string(const Status& status) { switch (status) { case Status::UNKNOWN: return "UNKNOWN"; case Status::SENDING: return "SENDING"; case Status::FAILURE: return "FAILURE"; case Status::SUCCESS: return "SUCCESS"; case Status::DISPLAYED: return "DISPLAYED"; case Status::TRANSFER_CREATED: return "TRANSFER_CREATED"; case Status::TRANSFER_ACCEPTED: return "TRANSFER_ACCEPTED"; case Status::TRANSFER_CANCELED: return "TRANSFER_CANCELED"; case Status::TRANSFER_ERROR: return "TRANSFER_ERROR"; case Status::TRANSFER_UNJOINABLE_PEER: return "TRANSFER_UNJOINABLE_PEER"; case Status::TRANSFER_ONGOING: return "TRANSFER_ONGOING"; case Status::TRANSFER_AWAITING_HOST: return "TRANSFER_AWAITING_HOST"; case Status::TRANSFER_AWAITING_PEER: return "TRANSFER_AWAITING_PEER"; case Status::TRANSFER_TIMEOUT_EXPIRED: return "TRANSFER_TIMEOUT_EXPIRED"; case Status::TRANSFER_FINISHED: return "TRANSFER_FINISHED"; case Status::INVALID: case Status::COUNT__: default: return "INVALID"; } } static inline Status to_status(const QString& status) { if (status == "UNKNOWN") return Status::UNKNOWN; else if (status == "SENDING") return Status::SENDING; else if (status == "FAILURE") return Status::FAILURE; else if (status == "SUCCESS") return Status::SUCCESS; else if (status == "DISPLAYED") return Status::DISPLAYED; else if (status == "TRANSFER_CREATED") return Status::TRANSFER_CREATED; else if (status == "TRANSFER_ACCEPTED") return Status::TRANSFER_ACCEPTED; else if (status == "TRANSFER_CANCELED") return Status::TRANSFER_CANCELED; else if (status == "TRANSFER_ERROR") return Status::TRANSFER_ERROR; else if (status == "TRANSFER_UNJOINABLE_PEER") return Status::TRANSFER_UNJOINABLE_PEER; else if (status == "TRANSFER_ONGOING") return Status::TRANSFER_ONGOING; else if (status == "TRANSFER_AWAITING_HOST") return Status::TRANSFER_AWAITING_HOST; else if (status == "TRANSFER_AWAITING_PEER") return Status::TRANSFER_AWAITING_PEER; else if (status == "TRANSFER_TIMEOUT_EXPIRED") return Status::TRANSFER_TIMEOUT_EXPIRED; else if (status == "TRANSFER_FINISHED") return Status::TRANSFER_FINISHED; else return Status::INVALID; } enum class ContactAction { ADD, JOIN, LEAVE, BANNED, UNBANNED, INVALID }; Q_ENUM_NS(ContactAction) static inline const QString to_string(const ContactAction& action) { switch (action) { case ContactAction::ADD: return "ADD"; case ContactAction::JOIN: return "JOIN"; case ContactAction::LEAVE: return "LEAVE"; case ContactAction::BANNED: return "BANNED"; case ContactAction::UNBANNED: return "UNBANNED"; case ContactAction::INVALID: return {}; } return {}; } static inline ContactAction to_action(const QString& action) { if (action == "add") return ContactAction::ADD; else if (action == "join") return ContactAction::JOIN; else if (action == "remove") return ContactAction::LEAVE; else if (action == "ban") return ContactAction::BANNED; else if (action == "unban") return ContactAction::UNBANNED; return ContactAction::INVALID; } static inline QString getContactInteractionString(const QString& authorUri, const ContactAction& action) { switch (action) { case ContactAction::ADD: if (authorUri.isEmpty()) { return QObject::tr("Contact added"); } return QObject::tr("%1 was invited to join").arg(authorUri); case ContactAction::JOIN: return QObject::tr("%1 joined").arg(authorUri); case ContactAction::LEAVE: return QObject::tr("%1 left").arg(authorUri); case ContactAction::BANNED: return QObject::tr("%1 was kicked").arg(authorUri); case ContactAction::UNBANNED: return QObject::tr("%1 was re-added").arg(authorUri); case ContactAction::INVALID: return {}; } return {}; } struct Body { Q_GADGET Q_PROPERTY(QString commitId MEMBER commitId) Q_PROPERTY(QString body MEMBER body) Q_PROPERTY(int timestamp MEMBER timestamp) public: QString commitId; QString body; std::time_t timestamp; }; /** * @var authorUri * @var body * @var timestamp * @var duration * @var type * @var status * @var isRead * @var commit * @var linkPreviewInfo * @var linkified */ struct Info { QString authorUri; QString body; QString parentId = ""; QString confId; std::time_t timestamp = 0; std::time_t duration = 0; Type type = Type::INVALID; Status status = Status::INVALID; bool isRead = false; MapStringString commit; QVariantMap linkPreviewInfo = {}; bool linkified = false; QVector previousBodies; Info() {} Info(QString authorUri, QString body, std::time_t timestamp, std::time_t duration, Type type, Status status, bool isRead) { this->authorUri = authorUri; this->body = body; this->timestamp = timestamp; this->duration = duration; this->type = type; this->status = status; this->isRead = isRead; } Info(const MapStringString& message, const QString& accountURI) { type = to_type(message["type"]); if (type == Type::TEXT || type == Type::EDITED) { body = message["body"]; } authorUri = accountURI == message["author"] ? "" : message["author"]; timestamp = message["timestamp"].toInt(); status = Status::SUCCESS; parentId = message["linearizedParent"]; isRead = false; if (type == Type::CONTACT) { authorUri = accountURI == message["uri"] ? "" : message["uri"]; } else if (type == Type::INITIAL) { body = QObject::tr("Swarm created"); } else if (type == Type::CALL) { duration = message["duration"].toInt() / 1000; if (message.contains("confId")) confId = message["confId"]; } commit = message; } }; static inline bool isOutgoing(const Info& interaction) { return interaction.authorUri.isEmpty(); } } // namespace interaction } // namespace api } // namespace lrc