Ejemplo n.º 1
0
void FastShareMessage(not_null<HistoryItem*> item) {
	struct ShareData {
		ShareData(not_null<PeerData*> peer, MessageIdsList &&ids)
		: peer(peer)
		, msgIds(std::move(ids)) {
		}
		not_null<PeerData*> peer;
		MessageIdsList msgIds;
		base::flat_set<mtpRequestId> requests;
	};
	const auto data = std::make_shared<ShareData>(
		item->history()->peer,
		Auth().data().itemOrItsGroup(item));
	const auto isGroup = (Auth().data().groups().find(item) != nullptr);
	const auto isGame = item->getMessageBot()
		&& item->media()
		&& (item->media()->game() != nullptr);
	const auto canCopyLink = item->hasDirectLink() || isGame;

	auto copyCallback = [data]() {
		if (auto main = App::main()) {
			if (auto item = App::histItemById(data->msgIds[0])) {
				if (item->hasDirectLink()) {
					QApplication::clipboard()->setText(item->directLink());

					Ui::Toast::Show(lang(lng_channel_public_link_copied));
				} else if (const auto bot = item->getMessageBot()) {
					if (const auto media = item->media()) {
						if (const auto game = media->game()) {
							const auto link = Messenger::Instance().createInternalLinkFull(
								bot->username
								+ qsl("?game=")
								+ game->shortName);

							QApplication::clipboard()->setText(link);

							Ui::Toast::Show(lang(lng_share_game_link_copied));
						}
					}
				}
			}
		}
	};
	auto submitCallback = [data, isGroup](const QVector<PeerData*> &result) {
		if (!data->requests.empty()) {
			return; // Share clicked already.
		}
		auto items = Auth().data().idsToItems(data->msgIds);
		if (items.empty() || result.empty()) {
			return;
		}

		auto restrictedSomewhere = false;
		auto restrictedEverywhere = true;
		auto firstError = QString();
		for (const auto peer : result) {
			const auto error = GetErrorTextForForward(peer, items);
			if (!error.isEmpty()) {
				if (firstError.isEmpty()) {
					firstError = error;
				}
				restrictedSomewhere = true;
				continue;
			}
			restrictedEverywhere = false;
		}
		if (restrictedEverywhere) {
			Ui::show(
				Box<InformBox>(firstError),
				LayerOption::KeepOther);
			return;
		}

		auto doneCallback = [data](const MTPUpdates &updates, mtpRequestId requestId) {
			if (auto main = App::main()) {
				main->sentUpdatesReceived(updates);
			}
			data->requests.remove(requestId);
			if (data->requests.empty()) {
				Ui::Toast::Show(lang(lng_share_done));
				Ui::hideLayer();
			}
		};

		const auto sendFlags = MTPmessages_ForwardMessages::Flag(0)
			| MTPmessages_ForwardMessages::Flag::f_with_my_score
			| (isGroup
				? MTPmessages_ForwardMessages::Flag::f_grouped
				: MTPmessages_ForwardMessages::Flag(0));
		auto msgIds = QVector<MTPint>();
		msgIds.reserve(data->msgIds.size());
		for (const auto fullId : data->msgIds) {
			msgIds.push_back(MTP_int(fullId.msg));
		}
		auto generateRandom = [&] {
			auto result = QVector<MTPlong>(data->msgIds.size());
			for (auto &value : result) {
				value = rand_value<MTPlong>();
			}
			return result;
		};
		if (auto main = App::main()) {
			for (const auto peer : result) {
				if (!GetErrorTextForForward(peer, items).isEmpty()) {
					continue;
				}

				auto request = MTPmessages_ForwardMessages(
					MTP_flags(sendFlags),
					data->peer->input,
					MTP_vector<MTPint>(msgIds),
					MTP_vector<MTPlong>(generateRandom()),
					peer->input);
				auto callback = doneCallback;
				auto requestId = MTP::send(request, rpcDone(std::move(callback)));
				data->requests.insert(requestId);
			}
		}
	};
	auto filterCallback = [isGame](PeerData *peer) {
		if (peer->canWrite()) {
			if (auto channel = peer->asChannel()) {
				return isGame ? (!channel->isBroadcast()) : true;
			}
			return true;
		}
		return false;
	};
	auto copyLinkCallback = canCopyLink
		? base::lambda<void()>(std::move(copyCallback))
		: base::lambda<void()>();
	Ui::show(Box<ShareBox>(
		std::move(copyLinkCallback),
		std::move(submitCallback),
		std::move(filterCallback)));
}