api_chat_links.cpp 4.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170
  1. /*
  2. This file is part of Telegram Desktop,
  3. the official desktop application for the Telegram messaging service.
  4. For license and copyright information please follow this link:
  5. https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
  6. */
  7. #include "api/api_chat_links.h"
  8. #include "api/api_text_entities.h"
  9. #include "apiwrap.h"
  10. #include "data/data_session.h"
  11. #include "main/main_session.h"
  12. namespace Api {
  13. namespace {
  14. [[nodiscard]] ChatLink FromMTP(
  15. not_null<Main::Session*> session,
  16. const MTPBusinessChatLink &link) {
  17. const auto &data = link.data();
  18. return {
  19. .link = qs(data.vlink()),
  20. .title = qs(data.vtitle().value_or_empty()),
  21. .message = {
  22. qs(data.vmessage()),
  23. EntitiesFromMTP(
  24. session,
  25. data.ventities().value_or_empty())
  26. },
  27. .clicks = data.vviews().v,
  28. };
  29. }
  30. [[nodiscard]] MTPInputBusinessChatLink ToMTP(
  31. not_null<Main::Session*> session,
  32. const QString &title,
  33. const TextWithEntities &message) {
  34. auto entities = EntitiesToMTP(
  35. session,
  36. message.entities,
  37. ConvertOption::SkipLocal);
  38. using Flag = MTPDinputBusinessChatLink::Flag;
  39. const auto flags = (title.isEmpty() ? Flag() : Flag::f_title)
  40. | (entities.v.isEmpty() ? Flag() : Flag::f_entities);
  41. return MTP_inputBusinessChatLink(
  42. MTP_flags(flags),
  43. MTP_string(message.text),
  44. std::move(entities),
  45. MTP_string(title));
  46. }
  47. } // namespace
  48. ChatLinks::ChatLinks(not_null<ApiWrap*> api) : _api(api) {
  49. }
  50. void ChatLinks::create(
  51. const QString &title,
  52. const TextWithEntities &message,
  53. Fn<void(Link)> done) {
  54. const auto session = &_api->session();
  55. _api->request(MTPaccount_CreateBusinessChatLink(
  56. ToMTP(session, title, message)
  57. )).done([=](const MTPBusinessChatLink &result) {
  58. const auto link = FromMTP(session, result);
  59. _list.push_back(link);
  60. _updates.fire({ .was = QString(), .now = link });
  61. if (done) done(link);
  62. }).fail([=](const MTP::Error &error) {
  63. const auto type = error.type();
  64. if (done) done(Link());
  65. }).send();
  66. }
  67. void ChatLinks::edit(
  68. const QString &link,
  69. const QString &title,
  70. const TextWithEntities &message,
  71. Fn<void(Link)> done) {
  72. const auto session = &_api->session();
  73. _api->request(MTPaccount_EditBusinessChatLink(
  74. MTP_string(link),
  75. ToMTP(session, title, message)
  76. )).done([=](const MTPBusinessChatLink &result) {
  77. const auto parsed = FromMTP(session, result);
  78. if (parsed.link != link) {
  79. LOG(("API Error: EditBusinessChatLink changed the link."));
  80. if (done) done(Link());
  81. return;
  82. }
  83. const auto i = ranges::find(_list, link, &Link::link);
  84. if (i != end(_list)) {
  85. *i = parsed;
  86. _updates.fire({ .was = link, .now = parsed });
  87. if (done) done(parsed);
  88. } else {
  89. LOG(("API Error: EditBusinessChatLink link not found."));
  90. if (done) done(Link());
  91. }
  92. }).fail([=](const MTP::Error &error) {
  93. const auto type = error.type();
  94. if (done) done(Link());
  95. }).send();
  96. }
  97. void ChatLinks::destroy(
  98. const QString &link,
  99. Fn<void()> done) {
  100. _api->request(MTPaccount_DeleteBusinessChatLink(
  101. MTP_string(link)
  102. )).done([=] {
  103. const auto i = ranges::find(_list, link, &Link::link);
  104. if (i != end(_list)) {
  105. _list.erase(i);
  106. _updates.fire({ .was = link });
  107. if (done) done();
  108. } else {
  109. LOG(("API Error: DeleteBusinessChatLink link not found."));
  110. if (done) done();
  111. }
  112. }).fail([=](const MTP::Error &error) {
  113. const auto type = error.type();
  114. if (done) done();
  115. }).send();
  116. }
  117. void ChatLinks::preload() {
  118. if (_loaded || _requestId) {
  119. return;
  120. }
  121. _requestId = _api->request(MTPaccount_GetBusinessChatLinks(
  122. )).done([=](const MTPaccount_BusinessChatLinks &result) {
  123. const auto &data = result.data();
  124. const auto session = &_api->session();
  125. const auto owner = &session->data();
  126. owner->processUsers(data.vusers());
  127. owner->processChats(data.vchats());
  128. auto links = std::vector<Link>();
  129. links.reserve(data.vlinks().v.size());
  130. for (const auto &link : data.vlinks().v) {
  131. links.push_back(FromMTP(session, link));
  132. }
  133. _list = std::move(links);
  134. _loaded = true;
  135. _loadedUpdates.fire({});
  136. }).fail([=] {
  137. _requestId = 0;
  138. _loaded = true;
  139. _loadedUpdates.fire({});
  140. }).send();
  141. }
  142. const std::vector<ChatLink> &ChatLinks::list() const {
  143. return _list;
  144. }
  145. bool ChatLinks::loaded() const {
  146. return _loaded;
  147. }
  148. rpl::producer<> ChatLinks::loadedUpdates() const {
  149. return _loadedUpdates.events();
  150. }
  151. rpl::producer<ChatLinks::Update> ChatLinks::updates() const {
  152. return _updates.events();
  153. }
  154. } // namespace Api