/* This file is part of Telegram Desktop, the official desktop application for the Telegram messaging service. For license and copyright information please follow this link: https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL */ #include "api/api_compose_with_ai.h" #include "api/api_text_entities.h" #include "apiwrap.h" namespace Api { namespace { [[nodiscard]] MTPTextWithEntities Serialize( not_null session, const TextWithEntities &text) { return MTP_textWithEntities( MTP_string(text.text), EntitiesToMTP(session, text.entities, ConvertOption::SkipLocal)); } } // namespace ComposeWithAi::ComposeWithAi(not_null api) : _session(&api->session()) , _api(&api->instance()) { } mtpRequestId ComposeWithAi::request( Request request, Fn done, Fn fail) { using Flag = MTPmessages_composeMessageWithAI::Flag; auto flags = MTPmessages_composeMessageWithAI::Flags(0); if (request.proofread) { flags |= Flag::f_proofread; } if (!request.translateToLang.isEmpty()) { flags |= Flag::f_translate_to_lang; } if (!request.changeTone.isEmpty()) { flags |= Flag::f_change_tone; } if (request.emojify) { flags |= Flag::f_emojify; } const auto session = _session; return _api.request(MTPmessages_ComposeMessageWithAI( MTP_flags(flags), Serialize(session, request.text), request.translateToLang.isEmpty() ? MTPstring() : MTP_string(request.translateToLang), request.changeTone.isEmpty() ? MTPstring() : MTP_string(request.changeTone) )).done([=, done = std::move(done)]( const MTPmessages_ComposedMessageWithAI &result) mutable { const auto &data = result.data(); auto parsed = Result{ .resultText = ParseTextWithEntities(session, data.vresult_text()), }; if (const auto diff = data.vdiff_text()) { parsed.diffText = ParseDiff(session, *diff); } done(std::move(parsed)); }).fail([=, fail = std::move(fail)](const MTP::Error &error) mutable { if (fail) { fail(error); } }).send(); } void ComposeWithAi::cancel(mtpRequestId requestId) { if (requestId) { _api.request(requestId).cancel(); } } ComposeWithAi::Diff ComposeWithAi::ParseDiff( not_null session, const MTPTextWithEntities &text) { const auto &data = text.data(); auto result = Diff{ .text = ParseTextWithEntities(session, text), }; const auto &entities = data.ventities().v; result.entities.reserve(entities.size()); for (const auto &entity : entities) { entity.match([&](const MTPDmessageEntityDiffInsert &data) { result.entities.push_back({ .type = DiffEntity::Type::Insert, .offset = data.voffset().v, .length = data.vlength().v, }); }, [&](const MTPDmessageEntityDiffReplace &data) { result.entities.push_back({ .type = DiffEntity::Type::Replace, .offset = data.voffset().v, .length = data.vlength().v, .oldText = qs(data.vold_text()), }); }, [&](const MTPDmessageEntityDiffDelete &data) { result.entities.push_back({ .type = DiffEntity::Type::Delete, .offset = data.voffset().v, .length = data.vlength().v, }); }, [](const auto &) { }); } return result; } } // namespace Api