diff --git a/native/android/app/CMakeLists.txt b/native/android/app/CMakeLists.txt --- a/native/android/app/CMakeLists.txt +++ b/native/android/app/CMakeLists.txt @@ -72,6 +72,8 @@ # comm native mutual code ../../cpp/CommonCpp/NativeModules ../../cpp/CommonCpp/NativeModules/InternalModules + ../../cpp/CommonCpp/NativeModules/MessageOperationsUtilities + ../../cpp/CommonCpp/NativeModules/MessageOperationsUtilities/MessageSpecs ../../cpp/CommonCpp/DatabaseManagers ../../cpp/CommonCpp/Tools ../../cpp/CommonCpp/grpc/_generated @@ -121,7 +123,10 @@ ./build/third-party-ndk/folly/folly/String.cpp ./build/third-party-ndk/folly/folly/portability/SysUio.cpp ./build/third-party-ndk/folly/folly/net/NetOps.cpp - + ./build/third-party-ndk/folly/folly/dynamic.cpp + ./build/third-party-ndk/folly/folly/json.cpp + ./build/third-party-ndk/folly/folly/json_pointer.cpp + ./build/third-party-ndk/folly/folly/Unicode.cpp # double-conversion ${DOUBLE_CONVERSION_SOURCES} diff --git a/native/cpp/CommonCpp/NativeModules/MessageOperationsUtilities/MessageOperationsUtilities.h b/native/cpp/CommonCpp/NativeModules/MessageOperationsUtilities/MessageOperationsUtilities.h new file mode 100644 --- /dev/null +++ b/native/cpp/CommonCpp/NativeModules/MessageOperationsUtilities/MessageOperationsUtilities.h @@ -0,0 +1,25 @@ +#pragma once + +#include "../DatabaseManagers/DatabaseManager.h" +#include "../DatabaseManagers/entities/Media.h" +#include "../DatabaseManagers/entities/Message.h" + +#include +#include +#include + +namespace comm { +class MessageOperationsUtilities { +public: + static std::pair> + translateRawMessageInfoToClientDBMessageInfo( + const folly::dynamic &rawMessageInfo); + static Media translateMediaToClientDBMediaInfo( + const folly::dynamic &rawMediaInfo, + const std::string &container, + const std::string &thread); + static std::vector>> + translateStringToClientDBMessageInfo(std::string rawMessageInfoString); + static void storeNotification(std::string rawMessageInfoString); +}; +} // namespace comm \ No newline at end of file diff --git a/native/cpp/CommonCpp/NativeModules/MessageOperationsUtilities/MessageOperationsUtilities.cpp b/native/cpp/CommonCpp/NativeModules/MessageOperationsUtilities/MessageOperationsUtilities.cpp new file mode 100644 --- /dev/null +++ b/native/cpp/CommonCpp/NativeModules/MessageOperationsUtilities/MessageOperationsUtilities.cpp @@ -0,0 +1,111 @@ +#include "MessageOperationsUtilities.h" +#include "Logger.h" +#include "MessageSpecs.h" + +#include +#include +#include + +namespace comm { +std::pair> +MessageOperationsUtilities::translateRawMessageInfoToClientDBMessageInfo( + const folly::dynamic &rawMessageInfo) { + std::string id = rawMessageInfo.count("id") + ? rawMessageInfo["id"].asString() + : rawMessageInfo["localID"].asString(); + std::string thread = rawMessageInfo["threadID"].asString(); + std::string user = rawMessageInfo["creatorID"].asString(); + std::unique_ptr local_id = rawMessageInfo.count("localID") + ? std::make_unique(rawMessageInfo["localID"].asString()) + : nullptr; + MessageType type = static_cast(rawMessageInfo["type"].asInt()); + int64_t time = rawMessageInfo["time"].asInt(); + std::unique_ptr future_type = (type == MessageType::UNSUPPORTED) + ? std::make_unique( + rawMessageInfo["unsupportedMessageInfo"]["type"].asInt()) + : nullptr; + std::unique_ptr content = + MESSAGE_SPECS.find(type) != MESSAGE_SPECS.end() + ? MESSAGE_SPECS.at(type)->messageContentForClientDB(rawMessageInfo) + : nullptr; + std::vector media_infos; + if (type == MessageType::IMAGES || type == MessageType::MULTIMEDIA) { + for (const auto &rawMediaInfo : rawMessageInfo["media"]) { + media_infos.push_back( + translateMediaToClientDBMediaInfo(rawMediaInfo, id, thread)); + } + } + return { + Message{ + id, + std::move(local_id), + std::move(thread), + std::move(user), + type, + std::move(future_type), + std::move(content), + time}, + std::move(media_infos)}; +} + +Media MessageOperationsUtilities::translateMediaToClientDBMediaInfo( + const folly::dynamic &rawMediaInfo, + const std::string &container, + const std::string &thread) { + std::string id = rawMediaInfo["id"].asString(); + std::string uri = rawMediaInfo["uri"].asString(); + std::string type = rawMediaInfo["type"].asString(); + folly::dynamic extrasData = + folly::dynamic::object("dimensions", rawMediaInfo["dimensions"])( + "loop", (type == "video") ? rawMediaInfo["loop"] : false); + if (rawMediaInfo.count("localMediaSelection")) { + extrasData["local_media_selection"] = rawMediaInfo["localMediaSelection"]; + } + std::string extras = folly::toJson(extrasData); + return Media{ + std::move(id), + std::move(container), + std::move(thread), + std::move(uri), + std::move(type), + std::move(extras)}; +} + +std::vector>> +MessageOperationsUtilities::translateStringToClientDBMessageInfo( + std::string rawMessageInfoString) { + folly::dynamic rawMessageInfos = + folly::parseJson(folly::trimWhitespace(rawMessageInfoString)); + std::vector>> clientDBMessageInfos; + if (rawMessageInfos.isObject()) { + clientDBMessageInfos.push_back( + translateRawMessageInfoToClientDBMessageInfo(rawMessageInfoString)); + return clientDBMessageInfos; + } + + for (const auto &messageInfo : rawMessageInfos) { + if (!messageInfo.isObject()) { + throw std::runtime_error( + "Invalid message content. Message content is expected to be an array " + "of JSON objects."); + } + clientDBMessageInfos.push_back( + translateRawMessageInfoToClientDBMessageInfo(messageInfo)); + } + return clientDBMessageInfos; +} + +void MessageOperationsUtilities::storeNotification( + std::string rawMessageInfoString) { + std::vector>> clientDBMessageInfos = + translateStringToClientDBMessageInfo(rawMessageInfoString); + for (const auto &clientDBMessageInfo : clientDBMessageInfos) { + DatabaseManager::getQueryExecutor().replaceMessage( + clientDBMessageInfo.first); + for (const auto &mediaInfo : clientDBMessageInfo.second) { + DatabaseManager::getQueryExecutor().replaceMedia(mediaInfo); + } + } +} + +} // namespace comm