mirror of
https://github.com/AyuGram/AyuGramDesktop.git
synced 2025-06-05 06:33:57 +02:00
Track factcheck text and create media.
This commit is contained in:
parent
5ee2bca616
commit
b299881bf8
13 changed files with 332 additions and 11 deletions
136
Telegram/SourceFiles/data/components/factchecks.cpp
Normal file
136
Telegram/SourceFiles/data/components/factchecks.cpp
Normal file
|
@ -0,0 +1,136 @@
|
||||||
|
/*
|
||||||
|
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 "data/components/factchecks.h"
|
||||||
|
|
||||||
|
#include "apiwrap.h"
|
||||||
|
#include "base/random.h"
|
||||||
|
#include "data/data_session.h"
|
||||||
|
#include "history/view/media/history_view_web_page.h"
|
||||||
|
#include "history/view/history_view_message.h"
|
||||||
|
#include "history/history.h"
|
||||||
|
#include "history/history_item.h"
|
||||||
|
#include "history/history_item_components.h"
|
||||||
|
#include "lang/lang_keys.h"
|
||||||
|
#include "main/main_session.h"
|
||||||
|
|
||||||
|
namespace Data {
|
||||||
|
namespace {
|
||||||
|
|
||||||
|
constexpr auto kRequestDelay = crl::time(1000);
|
||||||
|
|
||||||
|
} // namespace
|
||||||
|
|
||||||
|
Factchecks::Factchecks(not_null<Main::Session*> session)
|
||||||
|
: _session(session)
|
||||||
|
, _requestTimer([=] { request(); }) {
|
||||||
|
}
|
||||||
|
|
||||||
|
void Factchecks::requestFor(not_null<HistoryItem*> item) {
|
||||||
|
subscribeIfNotYet();
|
||||||
|
|
||||||
|
if (const auto factcheck = item->Get<HistoryMessageFactcheck>()) {
|
||||||
|
factcheck->requested = true;
|
||||||
|
}
|
||||||
|
if (!_requestTimer.isActive()) {
|
||||||
|
_requestTimer.callOnce(kRequestDelay);
|
||||||
|
}
|
||||||
|
const auto changed = !_pending.empty()
|
||||||
|
&& (_pending.front()->history() != item->history());
|
||||||
|
const auto added = _pending.emplace(item).second;
|
||||||
|
if (changed) {
|
||||||
|
request();
|
||||||
|
} else if (added && _pending.size() == 1) {
|
||||||
|
_requestTimer.callOnce(kRequestDelay);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void Factchecks::subscribeIfNotYet() {
|
||||||
|
if (_subscribed) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
_subscribed = true;
|
||||||
|
|
||||||
|
_session->data().itemRemoved(
|
||||||
|
) | rpl::start_with_next([=](not_null<const HistoryItem*> item) {
|
||||||
|
_pending.remove(item);
|
||||||
|
const auto i = ranges::find(_requested, item.get());
|
||||||
|
if (i != end(_requested)) {
|
||||||
|
*i = nullptr;
|
||||||
|
}
|
||||||
|
}, _lifetime);
|
||||||
|
}
|
||||||
|
|
||||||
|
void Factchecks::request() {
|
||||||
|
_requestTimer.cancel();
|
||||||
|
|
||||||
|
if (!_requested.empty() || _pending.empty()) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
_session->api().request(base::take(_requestId)).cancel();
|
||||||
|
|
||||||
|
auto ids = QVector<MTPint>();
|
||||||
|
ids.reserve(_pending.size());
|
||||||
|
const auto history = _pending.front()->history();
|
||||||
|
for (auto i = begin(_pending); i != end(_pending);) {
|
||||||
|
const auto &item = *i;
|
||||||
|
if (item->history() == history) {
|
||||||
|
_requested.push_back(item);
|
||||||
|
ids.push_back(MTP_int(item->id.bare));
|
||||||
|
i = _pending.erase(i);
|
||||||
|
} else {
|
||||||
|
++i;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
_requestId = _session->api().request(MTPmessages_GetFactCheck(
|
||||||
|
history->peer->input,
|
||||||
|
MTP_vector<MTPint>(std::move(ids))
|
||||||
|
)).done([=](const MTPVector<MTPFactCheck> &result) {
|
||||||
|
_requestId = 0;
|
||||||
|
const auto &list = result.v;
|
||||||
|
auto index = 0;
|
||||||
|
for (const auto &item : base::take(_requested)) {
|
||||||
|
if (!item) {
|
||||||
|
} else if (index >= list.size()) {
|
||||||
|
item->setFactcheck({});
|
||||||
|
} else {
|
||||||
|
item->setFactcheck(FromMTP(item, &list[index]));
|
||||||
|
}
|
||||||
|
++index;
|
||||||
|
}
|
||||||
|
if (!_pending.empty()) {
|
||||||
|
request();
|
||||||
|
}
|
||||||
|
}).fail([=] {
|
||||||
|
_requestId = 0;
|
||||||
|
for (const auto &item : base::take(_requested)) {
|
||||||
|
if (item) {
|
||||||
|
item->setFactcheck({});
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (!_pending.empty()) {
|
||||||
|
request();
|
||||||
|
}
|
||||||
|
}).send();
|
||||||
|
}
|
||||||
|
|
||||||
|
std::unique_ptr<HistoryView::WebPage> Factchecks::makeMedia(
|
||||||
|
not_null<HistoryView::Message*> view,
|
||||||
|
not_null<HistoryMessageFactcheck*> factcheck) {
|
||||||
|
if (!factcheck->page) {
|
||||||
|
factcheck->page = view->history()->owner().webpage(
|
||||||
|
base::RandomValue<WebPageId>(),
|
||||||
|
tr::lng_factcheck_title(tr::now),
|
||||||
|
factcheck->data.text);
|
||||||
|
}
|
||||||
|
return std::make_unique<HistoryView::WebPage>(
|
||||||
|
view,
|
||||||
|
factcheck->page,
|
||||||
|
MediaWebPageFlags());
|
||||||
|
}
|
||||||
|
|
||||||
|
} // namespace Data
|
51
Telegram/SourceFiles/data/components/factchecks.h
Normal file
51
Telegram/SourceFiles/data/components/factchecks.h
Normal file
|
@ -0,0 +1,51 @@
|
||||||
|
/*
|
||||||
|
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
|
||||||
|
*/
|
||||||
|
#pragma once
|
||||||
|
|
||||||
|
#include "base/timer.h"
|
||||||
|
|
||||||
|
class HistoryItem;
|
||||||
|
struct HistoryMessageFactcheck;
|
||||||
|
|
||||||
|
namespace HistoryView {
|
||||||
|
class Message;
|
||||||
|
class WebPage;
|
||||||
|
} // namespace HistoryView
|
||||||
|
|
||||||
|
namespace Main {
|
||||||
|
class Session;
|
||||||
|
} // namespace Main
|
||||||
|
|
||||||
|
namespace Data {
|
||||||
|
|
||||||
|
class Factchecks final {
|
||||||
|
public:
|
||||||
|
explicit Factchecks(not_null<Main::Session*> session);
|
||||||
|
|
||||||
|
void requestFor(not_null<HistoryItem*> item);
|
||||||
|
[[nodiscard]] std::unique_ptr<HistoryView::WebPage> makeMedia(
|
||||||
|
not_null<HistoryView::Message*> view,
|
||||||
|
not_null<HistoryMessageFactcheck*> factcheck);
|
||||||
|
|
||||||
|
private:
|
||||||
|
void subscribeIfNotYet();
|
||||||
|
void request();
|
||||||
|
|
||||||
|
const not_null<Main::Session*> _session;
|
||||||
|
|
||||||
|
base::Timer _requestTimer;
|
||||||
|
base::flat_set<not_null<HistoryItem*>> _pending;
|
||||||
|
std::vector<HistoryItem*> _requested;
|
||||||
|
mtpRequestId _requestId = 0;
|
||||||
|
bool _subscribed = false;
|
||||||
|
|
||||||
|
rpl::lifetime _lifetime;
|
||||||
|
|
||||||
|
};
|
||||||
|
|
||||||
|
} // namespace Data
|
|
@ -4250,29 +4250,27 @@ void Session::notifyPollUpdateDelayed(not_null<PollData*> poll) {
|
||||||
}
|
}
|
||||||
|
|
||||||
void Session::sendWebPageGamePollNotifications() {
|
void Session::sendWebPageGamePollNotifications() {
|
||||||
|
auto resize = std::vector<not_null<ViewElement*>>();
|
||||||
for (const auto &page : base::take(_webpagesUpdated)) {
|
for (const auto &page : base::take(_webpagesUpdated)) {
|
||||||
_webpageUpdates.fire_copy(page);
|
_webpageUpdates.fire_copy(page);
|
||||||
const auto i = _webpageViews.find(page);
|
if (const auto i = _webpageViews.find(page)
|
||||||
if (i != _webpageViews.end()) {
|
; i != _webpageViews.end()) {
|
||||||
for (const auto &view : i->second) {
|
resize.insert(end(resize), begin(i->second), end(i->second));
|
||||||
requestViewResize(view);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
for (const auto &game : base::take(_gamesUpdated)) {
|
for (const auto &game : base::take(_gamesUpdated)) {
|
||||||
if (const auto i = _gameViews.find(game); i != _gameViews.end()) {
|
if (const auto i = _gameViews.find(game); i != _gameViews.end()) {
|
||||||
for (const auto &view : i->second) {
|
resize.insert(end(resize), begin(i->second), end(i->second));
|
||||||
requestViewResize(view);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
for (const auto &poll : base::take(_pollsUpdated)) {
|
for (const auto &poll : base::take(_pollsUpdated)) {
|
||||||
if (const auto i = _pollViews.find(poll); i != _pollViews.end()) {
|
if (const auto i = _pollViews.find(poll); i != _pollViews.end()) {
|
||||||
for (const auto &view : i->second) {
|
resize.insert(end(resize), begin(i->second), end(i->second));
|
||||||
requestViewResize(view);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
for (const auto &view : resize) {
|
||||||
|
requestViewResize(view);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
rpl::producer<not_null<WebPageData*>> Session::webPageUpdates() const {
|
rpl::producer<not_null<WebPageData*>> Session::webPageUpdates() const {
|
||||||
|
|
|
@ -1306,6 +1306,8 @@ void InnerWidget::showContextMenu(QContextMenuEvent *e, bool showFromTouch) {
|
||||||
&& !link
|
&& !link
|
||||||
&& (view->hasVisibleText()
|
&& (view->hasVisibleText()
|
||||||
|| mediaHasTextForCopy
|
|| mediaHasTextForCopy
|
||||||
|
|| (item->Has<HistoryMessageFactcheck>()
|
||||||
|
&& !item->Get<HistoryMessageFactcheck>()->data.text.empty())
|
||||||
|| item->Has<HistoryMessageLogEntryOriginal>())) {
|
|| item->Has<HistoryMessageLogEntryOriginal>())) {
|
||||||
_menu->addAction(tr::lng_context_copy_text(tr::now), [=] {
|
_menu->addAction(tr::lng_context_copy_text(tr::now), [=] {
|
||||||
copyContextText(itemId);
|
copyContextText(itemId);
|
||||||
|
|
|
@ -415,6 +415,11 @@ HistoryItem::HistoryItem(
|
||||||
}
|
}
|
||||||
setReactions(data.vreactions());
|
setReactions(data.vreactions());
|
||||||
applyTTL(data);
|
applyTTL(data);
|
||||||
|
|
||||||
|
if (const auto check = FromMTP(this, data.vfactcheck())) {
|
||||||
|
AddComponents(HistoryMessageFactcheck::Bit());
|
||||||
|
Get<HistoryMessageFactcheck>()->data = check;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1494,6 +1499,33 @@ void HistoryItem::addLogEntryOriginal(
|
||||||
content);
|
content);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void HistoryItem::setFactcheck(MessageFactcheck info) {
|
||||||
|
if (!info) {
|
||||||
|
if (Has<HistoryMessageFactcheck>()) {
|
||||||
|
RemoveComponents(HistoryMessageFactcheck::Bit());
|
||||||
|
history()->owner().requestItemResize(this);
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
AddComponents(HistoryMessageFactcheck::Bit());
|
||||||
|
const auto factcheck = Get<HistoryMessageFactcheck>();
|
||||||
|
if (factcheck->data.hash == info.hash
|
||||||
|
&& (info.needCheck || !factcheck->data.needCheck)) {
|
||||||
|
return;
|
||||||
|
} else if (factcheck->data.text != info.text
|
||||||
|
|| factcheck->data.country != info.country
|
||||||
|
|| factcheck->data.hash != info.hash) {
|
||||||
|
factcheck->data = std::move(info);
|
||||||
|
factcheck->requested = false;
|
||||||
|
history()->owner().requestItemResize(this);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
bool HistoryItem::hasUnrequestedFactcheck() const {
|
||||||
|
const auto factcheck = Get<HistoryMessageFactcheck>();
|
||||||
|
return factcheck && factcheck->data.needCheck && !factcheck->requested;
|
||||||
|
}
|
||||||
|
|
||||||
PeerData *HistoryItem::specialNotificationPeer() const {
|
PeerData *HistoryItem::specialNotificationPeer() const {
|
||||||
return (mentionsMe() && !_history->peer->isUser())
|
return (mentionsMe() && !_history->peer->isUser())
|
||||||
? from().get()
|
? from().get()
|
||||||
|
@ -3143,6 +3175,8 @@ EffectId HistoryItem::effectId() const {
|
||||||
bool HistoryItem::isEmpty() const {
|
bool HistoryItem::isEmpty() const {
|
||||||
return _text.empty()
|
return _text.empty()
|
||||||
&& !_media
|
&& !_media
|
||||||
|
&& (!Has<HistoryMessageFactcheck>()
|
||||||
|
|| Get<HistoryMessageFactcheck>()->data.text.empty())
|
||||||
&& !Has<HistoryMessageLogEntryOriginal>();
|
&& !Has<HistoryMessageLogEntryOriginal>();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -23,9 +23,11 @@ struct HistoryMessageReplyMarkup;
|
||||||
struct HistoryMessageTranslation;
|
struct HistoryMessageTranslation;
|
||||||
struct HistoryMessageForwarded;
|
struct HistoryMessageForwarded;
|
||||||
struct HistoryMessageSavedMediaData;
|
struct HistoryMessageSavedMediaData;
|
||||||
|
struct HistoryMessageFactcheck;
|
||||||
struct HistoryServiceDependentData;
|
struct HistoryServiceDependentData;
|
||||||
enum class HistorySelfDestructType;
|
enum class HistorySelfDestructType;
|
||||||
struct PreparedServiceText;
|
struct PreparedServiceText;
|
||||||
|
struct MessageFactcheck;
|
||||||
class ReplyKeyboard;
|
class ReplyKeyboard;
|
||||||
struct LanguageId;
|
struct LanguageId;
|
||||||
|
|
||||||
|
@ -204,6 +206,8 @@ public:
|
||||||
WebPageId localId,
|
WebPageId localId,
|
||||||
const QString &label,
|
const QString &label,
|
||||||
const TextWithEntities &content);
|
const TextWithEntities &content);
|
||||||
|
void setFactcheck(MessageFactcheck info);
|
||||||
|
[[nodiscard]] bool hasUnrequestedFactcheck() const;
|
||||||
|
|
||||||
[[nodiscard]] not_null<Data::Thread*> notificationThread() const;
|
[[nodiscard]] not_null<Data::Thread*> notificationThread() const;
|
||||||
[[nodiscard]] not_null<History*> history() const {
|
[[nodiscard]] not_null<History*> history() const {
|
||||||
|
|
|
@ -1062,6 +1062,31 @@ HistoryMessageLogEntryOriginal &HistoryMessageLogEntryOriginal::operator=(
|
||||||
|
|
||||||
HistoryMessageLogEntryOriginal::~HistoryMessageLogEntryOriginal() = default;
|
HistoryMessageLogEntryOriginal::~HistoryMessageLogEntryOriginal() = default;
|
||||||
|
|
||||||
|
MessageFactcheck FromMTP(
|
||||||
|
not_null<HistoryItem*> item,
|
||||||
|
const tl::conditional<MTPFactCheck> &factcheck) {
|
||||||
|
auto result = MessageFactcheck();
|
||||||
|
if (!factcheck) {
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
const auto &data = factcheck->data();
|
||||||
|
if (const auto text = data.vtext()) {
|
||||||
|
const auto &data = text->data();
|
||||||
|
result.text = {
|
||||||
|
qs(data.vtext()),
|
||||||
|
Api::EntitiesFromMTP(
|
||||||
|
&item->history()->session(),
|
||||||
|
data.ventities().v),
|
||||||
|
};
|
||||||
|
}
|
||||||
|
if (const auto country = data.vcountry()) {
|
||||||
|
result.country = qs(country->v);
|
||||||
|
}
|
||||||
|
result.hash = data.vhash().v;
|
||||||
|
result.needCheck = data.is_need_check();
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
HistoryDocumentCaptioned::HistoryDocumentCaptioned()
|
HistoryDocumentCaptioned::HistoryDocumentCaptioned()
|
||||||
: caption(st::msgFileMinWidth - st::msgPadding.left() - st::msgPadding.right()) {
|
: caption(st::msgFileMinWidth - st::msgPadding.left() - st::msgPadding.right()) {
|
||||||
}
|
}
|
||||||
|
|
|
@ -562,6 +562,31 @@ struct HistoryMessageLogEntryOriginal
|
||||||
|
|
||||||
};
|
};
|
||||||
|
|
||||||
|
struct MessageFactcheck {
|
||||||
|
TextWithEntities text;
|
||||||
|
QString country;
|
||||||
|
uint64 hash = 0;
|
||||||
|
bool needCheck = false;
|
||||||
|
|
||||||
|
[[nodiscard]] bool empty() const {
|
||||||
|
return text.empty() && country.isEmpty() && !hash;
|
||||||
|
}
|
||||||
|
explicit operator bool() const {
|
||||||
|
return !empty();
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
[[nodiscard]] MessageFactcheck FromMTP(
|
||||||
|
not_null<HistoryItem*> item,
|
||||||
|
const tl::conditional<MTPFactCheck> &factcheck);
|
||||||
|
|
||||||
|
struct HistoryMessageFactcheck
|
||||||
|
: public RuntimeComponent<HistoryMessageFactcheck, HistoryItem> {
|
||||||
|
MessageFactcheck data;
|
||||||
|
WebPageData *page = nullptr;
|
||||||
|
bool requested = false;
|
||||||
|
};
|
||||||
|
|
||||||
struct HistoryServiceData
|
struct HistoryServiceData
|
||||||
: public RuntimeComponent<HistoryServiceData, HistoryItem> {
|
: public RuntimeComponent<HistoryServiceData, HistoryItem> {
|
||||||
std::vector<ClickHandlerPtr> textLinks;
|
std::vector<ClickHandlerPtr> textLinks;
|
||||||
|
|
|
@ -46,6 +46,12 @@ TextForMimeData HistoryItemText(not_null<HistoryItem*> item) {
|
||||||
titleResult.append('\n').append(std::move(descriptionResult));
|
titleResult.append('\n').append(std::move(descriptionResult));
|
||||||
return titleResult;
|
return titleResult;
|
||||||
}();
|
}();
|
||||||
|
auto factcheckResult = [&] {
|
||||||
|
const auto factcheck = item->Get<HistoryMessageFactcheck>();
|
||||||
|
return factcheck
|
||||||
|
? TextForMimeData::Rich(base::duplicate(factcheck->data.text))
|
||||||
|
: TextForMimeData();
|
||||||
|
}();
|
||||||
auto result = textResult;
|
auto result = textResult;
|
||||||
if (result.empty()) {
|
if (result.empty()) {
|
||||||
result = std::move(mediaResult);
|
result = std::move(mediaResult);
|
||||||
|
@ -57,6 +63,11 @@ TextForMimeData HistoryItemText(not_null<HistoryItem*> item) {
|
||||||
} else if (!logEntryOriginalResult.empty()) {
|
} else if (!logEntryOriginalResult.empty()) {
|
||||||
result.append(u"\n\n"_q).append(std::move(logEntryOriginalResult));
|
result.append(u"\n\n"_q).append(std::move(logEntryOriginalResult));
|
||||||
}
|
}
|
||||||
|
if (result.empty()) {
|
||||||
|
result = std::move(factcheckResult);
|
||||||
|
} else if (!factcheckResult.empty()) {
|
||||||
|
result.append(u"\n\n"_q).append(std::move(factcheckResult));
|
||||||
|
}
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -27,6 +27,7 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
|
||||||
#include "ui/round_rect.h"
|
#include "ui/round_rect.h"
|
||||||
#include "ui/text/text_utilities.h"
|
#include "ui/text/text_utilities.h"
|
||||||
#include "ui/power_saving.h"
|
#include "ui/power_saving.h"
|
||||||
|
#include "data/components/factchecks.h"
|
||||||
#include "data/components/sponsored_messages.h"
|
#include "data/components/sponsored_messages.h"
|
||||||
#include "data/data_session.h"
|
#include "data/data_session.h"
|
||||||
#include "data/data_user.h"
|
#include "data/data_user.h"
|
||||||
|
@ -799,6 +800,24 @@ QSize Message::performCountOptimalSize() {
|
||||||
RemoveComponents(Reply::Bit());
|
RemoveComponents(Reply::Bit());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
const auto factcheck = item->Get<HistoryMessageFactcheck>();
|
||||||
|
if (factcheck && !factcheck->data.text.empty()) {
|
||||||
|
AddComponents(Factcheck::Bit());
|
||||||
|
Get<Factcheck>()->page = history()->session().factchecks().makeMedia(
|
||||||
|
this,
|
||||||
|
factcheck);
|
||||||
|
|
||||||
|
auto copy = data()->originalText();
|
||||||
|
if (!copy.text.contains("FACT CHECK")) {
|
||||||
|
copy.append("\n\nFACT CHECK!!\n\n").append(factcheck->data.text);
|
||||||
|
crl::on_main(this, [=] {
|
||||||
|
data()->setText(std::move(copy));
|
||||||
|
});
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
RemoveComponents(Factcheck::Bit());
|
||||||
|
}
|
||||||
|
|
||||||
const auto markup = item->inlineReplyMarkup();
|
const auto markup = item->inlineReplyMarkup();
|
||||||
const auto reactionsKey = [&] {
|
const auto reactionsKey = [&] {
|
||||||
return embedReactionsInBottomInfo()
|
return embedReactionsInBottomInfo()
|
||||||
|
@ -1069,6 +1088,10 @@ void Message::draw(Painter &p, const PaintContext &context) const {
|
||||||
const auto item = data();
|
const auto item = data();
|
||||||
const auto media = this->media();
|
const auto media = this->media();
|
||||||
|
|
||||||
|
if (item->hasUnrequestedFactcheck()) {
|
||||||
|
item->history()->session().factchecks().requestFor(item);
|
||||||
|
}
|
||||||
|
|
||||||
const auto stm = context.messageStyle();
|
const auto stm = context.messageStyle();
|
||||||
const auto bubble = drawBubble();
|
const auto bubble = drawBubble();
|
||||||
|
|
||||||
|
|
|
@ -44,6 +44,11 @@ struct LogEntryOriginal
|
||||||
std::unique_ptr<WebPage> page;
|
std::unique_ptr<WebPage> page;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
struct Factcheck
|
||||||
|
: public RuntimeComponent<Factcheck, Element> {
|
||||||
|
std::unique_ptr<WebPage> page;
|
||||||
|
};
|
||||||
|
|
||||||
struct PsaTooltipState : public RuntimeComponent<PsaTooltipState, Element> {
|
struct PsaTooltipState : public RuntimeComponent<PsaTooltipState, Element> {
|
||||||
QString type;
|
QString type;
|
||||||
mutable ClickHandlerPtr link;
|
mutable ClickHandlerPtr link;
|
||||||
|
|
|
@ -29,6 +29,7 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
|
||||||
#include "storage/file_upload.h"
|
#include "storage/file_upload.h"
|
||||||
#include "storage/storage_account.h"
|
#include "storage/storage_account.h"
|
||||||
#include "storage/storage_facade.h"
|
#include "storage/storage_facade.h"
|
||||||
|
#include "data/components/factchecks.h"
|
||||||
#include "data/components/recent_peers.h"
|
#include "data/components/recent_peers.h"
|
||||||
#include "data/components/scheduled_messages.h"
|
#include "data/components/scheduled_messages.h"
|
||||||
#include "data/components/sponsored_messages.h"
|
#include "data/components/sponsored_messages.h"
|
||||||
|
@ -105,6 +106,7 @@ Session::Session(
|
||||||
, _scheduledMessages(std::make_unique<Data::ScheduledMessages>(this))
|
, _scheduledMessages(std::make_unique<Data::ScheduledMessages>(this))
|
||||||
, _sponsoredMessages(std::make_unique<Data::SponsoredMessages>(this))
|
, _sponsoredMessages(std::make_unique<Data::SponsoredMessages>(this))
|
||||||
, _topPeers(std::make_unique<Data::TopPeers>(this))
|
, _topPeers(std::make_unique<Data::TopPeers>(this))
|
||||||
|
, _factchecks(std::make_unique<Data::Factchecks>(this))
|
||||||
, _cachedReactionIconFactory(std::make_unique<ReactionIconFactory>())
|
, _cachedReactionIconFactory(std::make_unique<ReactionIconFactory>())
|
||||||
, _supportHelper(Support::Helper::Create(this))
|
, _supportHelper(Support::Helper::Create(this))
|
||||||
, _saveSettingsTimer([=] { saveSettings(); }) {
|
, _saveSettingsTimer([=] { saveSettings(); }) {
|
||||||
|
|
|
@ -35,6 +35,7 @@ class RecentPeers;
|
||||||
class ScheduledMessages;
|
class ScheduledMessages;
|
||||||
class SponsoredMessages;
|
class SponsoredMessages;
|
||||||
class TopPeers;
|
class TopPeers;
|
||||||
|
class Factchecks;
|
||||||
} // namespace Data
|
} // namespace Data
|
||||||
|
|
||||||
namespace HistoryView::Reactions {
|
namespace HistoryView::Reactions {
|
||||||
|
@ -127,6 +128,9 @@ public:
|
||||||
[[nodiscard]] Data::TopPeers &topPeers() const {
|
[[nodiscard]] Data::TopPeers &topPeers() const {
|
||||||
return *_topPeers;
|
return *_topPeers;
|
||||||
}
|
}
|
||||||
|
[[nodiscard]] Data::Factchecks &factchecks() const {
|
||||||
|
return *_factchecks;
|
||||||
|
}
|
||||||
[[nodiscard]] Api::Updates &updates() const {
|
[[nodiscard]] Api::Updates &updates() const {
|
||||||
return *_updates;
|
return *_updates;
|
||||||
}
|
}
|
||||||
|
@ -254,6 +258,7 @@ private:
|
||||||
const std::unique_ptr<Data::ScheduledMessages> _scheduledMessages;
|
const std::unique_ptr<Data::ScheduledMessages> _scheduledMessages;
|
||||||
const std::unique_ptr<Data::SponsoredMessages> _sponsoredMessages;
|
const std::unique_ptr<Data::SponsoredMessages> _sponsoredMessages;
|
||||||
const std::unique_ptr<Data::TopPeers> _topPeers;
|
const std::unique_ptr<Data::TopPeers> _topPeers;
|
||||||
|
const std::unique_ptr<Data::Factchecks> _factchecks;
|
||||||
|
|
||||||
using ReactionIconFactory = HistoryView::Reactions::CachedIconFactory;
|
using ReactionIconFactory = HistoryView::Reactions::CachedIconFactory;
|
||||||
const std::unique_ptr<ReactionIconFactory> _cachedReactionIconFactory;
|
const std::unique_ptr<ReactionIconFactory> _cachedReactionIconFactory;
|
||||||
|
|
Loading…
Add table
Reference in a new issue