170 lines
		
	
	
	
		
			4.3 KiB
		
	
	
	
		
			C++
		
	
	
	
	
	
			
		
		
	
	
			170 lines
		
	
	
	
		
			4.3 KiB
		
	
	
	
		
			C++
		
	
	
	
	
	
| /*
 | |
| 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_chat_links.h"
 | |
| 
 | |
| #include "api/api_text_entities.h"
 | |
| #include "apiwrap.h"
 | |
| #include "data/data_session.h"
 | |
| #include "main/main_session.h"
 | |
| 
 | |
| namespace Api {
 | |
| namespace {
 | |
| 
 | |
| [[nodiscard]] ChatLink FromMTP(
 | |
| 		not_null<Main::Session*> session,
 | |
| 		const MTPBusinessChatLink &link) {
 | |
| 	const auto &data = link.data();
 | |
| 	return {
 | |
| 		.link = qs(data.vlink()),
 | |
| 		.title = qs(data.vtitle().value_or_empty()),
 | |
| 		.message = {
 | |
| 			qs(data.vmessage()),
 | |
| 			EntitiesFromMTP(
 | |
| 				session,
 | |
| 				data.ventities().value_or_empty())
 | |
| 		},
 | |
| 		.clicks = data.vviews().v,
 | |
| 	};
 | |
| }
 | |
| 
 | |
| [[nodiscard]] MTPInputBusinessChatLink ToMTP(
 | |
| 		not_null<Main::Session*> session,
 | |
| 		const QString &title,
 | |
| 		const TextWithEntities &message) {
 | |
| 	auto entities = EntitiesToMTP(
 | |
| 		session,
 | |
| 		message.entities,
 | |
| 		ConvertOption::SkipLocal);
 | |
| 	using Flag = MTPDinputBusinessChatLink::Flag;
 | |
| 	const auto flags = (title.isEmpty() ? Flag() : Flag::f_title)
 | |
| 		| (entities.v.isEmpty() ? Flag() : Flag::f_entities);
 | |
| 	return MTP_inputBusinessChatLink(
 | |
| 		MTP_flags(flags),
 | |
| 		MTP_string(message.text),
 | |
| 		std::move(entities),
 | |
| 		MTP_string(title));
 | |
| }
 | |
| 
 | |
| } // namespace
 | |
| 
 | |
| ChatLinks::ChatLinks(not_null<ApiWrap*> api) : _api(api) {
 | |
| }
 | |
| 
 | |
| void ChatLinks::create(
 | |
| 		const QString &title,
 | |
| 		const TextWithEntities &message,
 | |
| 		Fn<void(Link)> done) {
 | |
| 	const auto session = &_api->session();
 | |
| 	_api->request(MTPaccount_CreateBusinessChatLink(
 | |
| 		ToMTP(session, title, message)
 | |
| 	)).done([=](const MTPBusinessChatLink &result) {
 | |
| 		const auto link = FromMTP(session, result);
 | |
| 		_list.push_back(link);
 | |
| 		_updates.fire({ .was = QString(), .now = link });
 | |
| 		if (done) done(link);
 | |
| 	}).fail([=](const MTP::Error &error) {
 | |
| 		const auto type = error.type();
 | |
| 		if (done) done(Link());
 | |
| 	}).send();
 | |
| }
 | |
| 
 | |
| void ChatLinks::edit(
 | |
| 		const QString &link,
 | |
| 		const QString &title,
 | |
| 		const TextWithEntities &message,
 | |
| 		Fn<void(Link)> done) {
 | |
| 	const auto session = &_api->session();
 | |
| 	_api->request(MTPaccount_EditBusinessChatLink(
 | |
| 		MTP_string(link),
 | |
| 		ToMTP(session, title, message)
 | |
| 	)).done([=](const MTPBusinessChatLink &result) {
 | |
| 		const auto parsed = FromMTP(session, result);
 | |
| 		if (parsed.link != link) {
 | |
| 			LOG(("API Error: EditBusinessChatLink changed the link."));
 | |
| 			if (done) done(Link());
 | |
| 			return;
 | |
| 		}
 | |
| 		const auto i = ranges::find(_list, link, &Link::link);
 | |
| 		if (i != end(_list)) {
 | |
| 			*i = parsed;
 | |
| 			_updates.fire({ .was = link, .now = parsed });
 | |
| 			if (done) done(parsed);
 | |
| 		} else {
 | |
| 			LOG(("API Error: EditBusinessChatLink link not found."));
 | |
| 			if (done) done(Link());
 | |
| 		}
 | |
| 	}).fail([=](const MTP::Error &error) {
 | |
| 		const auto type = error.type();
 | |
| 		if (done) done(Link());
 | |
| 	}).send();
 | |
| }
 | |
| 
 | |
| void ChatLinks::destroy(
 | |
| 		const QString &link,
 | |
| 		Fn<void()> done) {
 | |
| 	_api->request(MTPaccount_DeleteBusinessChatLink(
 | |
| 		MTP_string(link)
 | |
| 	)).done([=] {
 | |
| 		const auto i = ranges::find(_list, link, &Link::link);
 | |
| 		if (i != end(_list)) {
 | |
| 			_list.erase(i);
 | |
| 			_updates.fire({ .was = link });
 | |
| 			if (done) done();
 | |
| 		} else {
 | |
| 			LOG(("API Error: DeleteBusinessChatLink link not found."));
 | |
| 			if (done) done();
 | |
| 		}
 | |
| 	}).fail([=](const MTP::Error &error) {
 | |
| 		const auto type = error.type();
 | |
| 		if (done) done();
 | |
| 	}).send();
 | |
| }
 | |
| 
 | |
| void ChatLinks::preload() {
 | |
| 	if (_loaded || _requestId) {
 | |
| 		return;
 | |
| 	}
 | |
| 	_requestId = _api->request(MTPaccount_GetBusinessChatLinks(
 | |
| 	)).done([=](const MTPaccount_BusinessChatLinks &result) {
 | |
| 		const auto &data = result.data();
 | |
| 		const auto session = &_api->session();
 | |
| 		const auto owner = &session->data();
 | |
| 		owner->processUsers(data.vusers());
 | |
| 		owner->processChats(data.vchats());
 | |
| 		auto links = std::vector<Link>();
 | |
| 		links.reserve(data.vlinks().v.size());
 | |
| 		for (const auto &link : data.vlinks().v) {
 | |
| 			links.push_back(FromMTP(session, link));
 | |
| 		}
 | |
| 		_list = std::move(links);
 | |
| 		_loaded = true;
 | |
| 		_loadedUpdates.fire({});
 | |
| 	}).fail([=] {
 | |
| 		_requestId = 0;
 | |
| 		_loaded = true;
 | |
| 		_loadedUpdates.fire({});
 | |
| 	}).send();
 | |
| }
 | |
| 
 | |
| const std::vector<ChatLink> &ChatLinks::list() const {
 | |
| 	return _list;
 | |
| }
 | |
| 
 | |
| bool ChatLinks::loaded() const {
 | |
| 	return _loaded;
 | |
| }
 | |
| 
 | |
| rpl::producer<> ChatLinks::loadedUpdates() const {
 | |
| 	return _loadedUpdates.events();
 | |
| }
 | |
| 
 | |
| rpl::producer<ChatLinks::Update> ChatLinks::updates() const {
 | |
| 	return _updates.events();
 | |
| }
 | |
| 
 | |
| } // namespace Api
 | 
