mirror of
https://github.com/AyuGram/AyuGramDesktop.git
synced 2025-06-05 06:33:57 +02:00
Implement factcheck edition.
This commit is contained in:
parent
74861a334d
commit
493f0450b4
20 changed files with 264 additions and 29 deletions
BIN
Telegram/Resources/icons/menu/factcheck.png
Normal file
BIN
Telegram/Resources/icons/menu/factcheck.png
Normal file
Binary file not shown.
After Width: | Height: | Size: 588 B |
BIN
Telegram/Resources/icons/menu/factcheck@2x.png
Normal file
BIN
Telegram/Resources/icons/menu/factcheck@2x.png
Normal file
Binary file not shown.
After Width: | Height: | Size: 1.3 KiB |
BIN
Telegram/Resources/icons/menu/factcheck@3x.png
Normal file
BIN
Telegram/Resources/icons/menu/factcheck@3x.png
Normal file
Binary file not shown.
After Width: | Height: | Size: 2.2 KiB |
|
@ -3217,6 +3217,8 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
|
||||||
"lng_context_reply_msg" = "Reply";
|
"lng_context_reply_msg" = "Reply";
|
||||||
"lng_context_quote_and_reply" = "Quote & Reply";
|
"lng_context_quote_and_reply" = "Quote & Reply";
|
||||||
"lng_context_edit_msg" = "Edit";
|
"lng_context_edit_msg" = "Edit";
|
||||||
|
"lng_context_add_factcheck" = "Add Fact Check";
|
||||||
|
"lng_context_edit_factcheck" = "Edit Fact Check";
|
||||||
"lng_context_forward_msg" = "Forward Message";
|
"lng_context_forward_msg" = "Forward Message";
|
||||||
"lng_context_send_now_msg" = "Send now";
|
"lng_context_send_now_msg" = "Send now";
|
||||||
"lng_context_reschedule" = "Reschedule";
|
"lng_context_reschedule" = "Reschedule";
|
||||||
|
@ -3287,12 +3289,14 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
|
||||||
|
|
||||||
"lng_context_spoiler_effect" = "Hide with Spoiler";
|
"lng_context_spoiler_effect" = "Hide with Spoiler";
|
||||||
"lng_context_disable_spoiler" = "Remove Spoiler";
|
"lng_context_disable_spoiler" = "Remove Spoiler";
|
||||||
"lng_context_add_factcheck" = "Add Fact Check";
|
|
||||||
|
|
||||||
"lng_factcheck_title" = "Fact Check";
|
"lng_factcheck_title" = "Fact Check";
|
||||||
"lng_factcheck_placeholder" = "Add Facts or Context";
|
"lng_factcheck_placeholder" = "Add Facts or Context";
|
||||||
"lng_factcheck_whats_this" = "what's this?";
|
"lng_factcheck_whats_this" = "what's this?";
|
||||||
"lng_factcheck_about" = "This clarification was provided by a fact checking agency assigned by the department of the government of your country ({country}) responsible for combatting misinformation.";
|
"lng_factcheck_about" = "This clarification was provided by a fact checking agency assigned by the department of the government of your country ({country}) responsible for combatting misinformation.";
|
||||||
|
"lng_factcheck_add_done" = "Fact check added.";
|
||||||
|
"lng_factcheck_edit_done" = "Fact check edited.";
|
||||||
|
"lng_factcheck_remove_done" = "Fact check removed.";
|
||||||
|
|
||||||
"lng_translate_show_original" = "Show Original";
|
"lng_translate_show_original" = "Show Original";
|
||||||
"lng_translate_bar_to" = "Translate to {name}";
|
"lng_translate_bar_to" = "Translate to {name}";
|
||||||
|
|
|
@ -7,6 +7,7 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
|
||||||
*/
|
*/
|
||||||
#include "data/components/factchecks.h"
|
#include "data/components/factchecks.h"
|
||||||
|
|
||||||
|
#include "api/api_text_entities.h"
|
||||||
#include "apiwrap.h"
|
#include "apiwrap.h"
|
||||||
#include "base/random.h"
|
#include "base/random.h"
|
||||||
#include "data/data_session.h"
|
#include "data/data_session.h"
|
||||||
|
@ -17,6 +18,7 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
|
||||||
#include "history/history_item.h"
|
#include "history/history_item.h"
|
||||||
#include "history/history_item_components.h"
|
#include "history/history_item_components.h"
|
||||||
#include "lang/lang_keys.h"
|
#include "lang/lang_keys.h"
|
||||||
|
#include "main/main_app_config.h"
|
||||||
#include "main/main_session.h"
|
#include "main/main_session.h"
|
||||||
|
|
||||||
namespace Data {
|
namespace Data {
|
||||||
|
@ -135,4 +137,63 @@ std::unique_ptr<HistoryView::WebPage> Factchecks::makeMedia(
|
||||||
MediaWebPageFlags());
|
MediaWebPageFlags());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
bool Factchecks::canEdit(not_null<HistoryItem*> item) const {
|
||||||
|
if (!canEdit()
|
||||||
|
|| !item->isRegular()
|
||||||
|
|| !item->history()->peer->isBroadcast()) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
const auto media = item->media();
|
||||||
|
if (!media || media->webpage() || media->photo()) {
|
||||||
|
return true;
|
||||||
|
} else if (const auto document = media->document()) {
|
||||||
|
return !document->isVideoMessage() && !document->sticker();
|
||||||
|
}
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool Factchecks::canEdit() const {
|
||||||
|
return _session->appConfig().get<bool>(u"can_edit_factcheck"_q, false);
|
||||||
|
}
|
||||||
|
|
||||||
|
int Factchecks::lengthLimit() const {
|
||||||
|
return _session->appConfig().get<int>(u"factcheck_length_limit"_q, 1024);
|
||||||
|
}
|
||||||
|
|
||||||
|
void Factchecks::save(
|
||||||
|
FullMsgId itemId,
|
||||||
|
TextWithEntities text,
|
||||||
|
Fn<void(QString)> done) {
|
||||||
|
const auto item = _session->data().message(itemId);
|
||||||
|
if (!item) {
|
||||||
|
return;
|
||||||
|
} else if (text.empty()) {
|
||||||
|
_session->api().request(MTPmessages_DeleteFactCheck(
|
||||||
|
item->history()->peer->input,
|
||||||
|
MTP_int(item->id.bare)
|
||||||
|
)).done([=](const MTPUpdates &result) {
|
||||||
|
_session->api().applyUpdates(result);
|
||||||
|
done(QString());
|
||||||
|
}).fail([=](const MTP::Error &error) {
|
||||||
|
done(error.type());
|
||||||
|
}).send();
|
||||||
|
} else {
|
||||||
|
_session->api().request(MTPmessages_EditFactCheck(
|
||||||
|
item->history()->peer->input,
|
||||||
|
MTP_int(item->id.bare),
|
||||||
|
MTP_textWithEntities(
|
||||||
|
MTP_string(text.text),
|
||||||
|
Api::EntitiesToMTP(
|
||||||
|
_session,
|
||||||
|
text.entities,
|
||||||
|
Api::ConvertOption::SkipLocal))
|
||||||
|
)).done([=](const MTPUpdates &result) {
|
||||||
|
_session->api().applyUpdates(result);
|
||||||
|
done(QString());
|
||||||
|
}).fail([=](const MTP::Error &error) {
|
||||||
|
done(error.type());
|
||||||
|
}).send();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
} // namespace Data
|
} // namespace Data
|
||||||
|
|
|
@ -32,7 +32,17 @@ public:
|
||||||
not_null<HistoryView::Message*> view,
|
not_null<HistoryView::Message*> view,
|
||||||
not_null<HistoryMessageFactcheck*> factcheck);
|
not_null<HistoryMessageFactcheck*> factcheck);
|
||||||
|
|
||||||
|
[[nodiscard]] bool canEdit(not_null<HistoryItem*> item) const;
|
||||||
|
[[nodiscard]] int lengthLimit() const;
|
||||||
|
|
||||||
|
void save(
|
||||||
|
FullMsgId itemId,
|
||||||
|
TextWithEntities text,
|
||||||
|
Fn<void(QString)> done);
|
||||||
|
|
||||||
private:
|
private:
|
||||||
|
[[nodiscard]] bool canEdit() const;
|
||||||
|
|
||||||
void subscribeIfNotYet();
|
void subscribeIfNotYet();
|
||||||
void request();
|
void request();
|
||||||
|
|
||||||
|
|
|
@ -1306,8 +1306,7 @@ void InnerWidget::showContextMenu(QContextMenuEvent *e, bool showFromTouch) {
|
||||||
&& !link
|
&& !link
|
||||||
&& (view->hasVisibleText()
|
&& (view->hasVisibleText()
|
||||||
|| mediaHasTextForCopy
|
|| mediaHasTextForCopy
|
||||||
|| (item->Has<HistoryMessageFactcheck>()
|
|| !item->factcheckText().empty()
|
||||||
&& !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);
|
||||||
|
|
|
@ -35,6 +35,7 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
|
||||||
#include "ui/effects/reaction_fly_animation.h"
|
#include "ui/effects/reaction_fly_animation.h"
|
||||||
#include "ui/text/text_options.h"
|
#include "ui/text/text_options.h"
|
||||||
#include "ui/text/text_isolated_emoji.h"
|
#include "ui/text/text_isolated_emoji.h"
|
||||||
|
#include "ui/boxes/edit_factcheck_box.h"
|
||||||
#include "ui/boxes/report_box.h"
|
#include "ui/boxes/report_box.h"
|
||||||
#include "ui/layers/generic_box.h"
|
#include "ui/layers/generic_box.h"
|
||||||
#include "ui/controls/delete_message_context_action.h"
|
#include "ui/controls/delete_message_context_action.h"
|
||||||
|
@ -72,6 +73,7 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
|
||||||
#include "api/api_who_reacted.h"
|
#include "api/api_who_reacted.h"
|
||||||
#include "api/api_views.h"
|
#include "api/api_views.h"
|
||||||
#include "lang/lang_keys.h"
|
#include "lang/lang_keys.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_document.h"
|
#include "data/data_document.h"
|
||||||
|
@ -2171,6 +2173,30 @@ void HistoryInner::showContextMenu(QContextMenuEvent *e, bool showFromTouch) {
|
||||||
}
|
}
|
||||||
}, &st::menuIconEdit);
|
}, &st::menuIconEdit);
|
||||||
}
|
}
|
||||||
|
if (session->factchecks().canEdit(item)) {
|
||||||
|
const auto text = item->factcheckText();
|
||||||
|
const auto phrase = text.empty()
|
||||||
|
? tr::lng_context_add_factcheck(tr::now)
|
||||||
|
: tr::lng_context_edit_factcheck(tr::now);
|
||||||
|
_menu->addAction(phrase, [=] {
|
||||||
|
controller->show(Box(EditFactcheckBox, text, [=](
|
||||||
|
TextWithEntities result) {
|
||||||
|
const auto done = [=](QString error) {
|
||||||
|
controller->showToast(!error.isEmpty()
|
||||||
|
? error
|
||||||
|
: result.empty()
|
||||||
|
? tr::lng_factcheck_remove_done(tr::now)
|
||||||
|
: text.empty()
|
||||||
|
? tr::lng_factcheck_add_done(tr::now)
|
||||||
|
: tr::lng_factcheck_edit_done(tr::now));
|
||||||
|
};
|
||||||
|
session->factchecks().save(
|
||||||
|
itemId,
|
||||||
|
result,
|
||||||
|
crl::guard(controller, done));
|
||||||
|
}));
|
||||||
|
}, &st::menuIconFactcheck);
|
||||||
|
}
|
||||||
const auto pinItem = (item->canPin() && item->isPinned())
|
const auto pinItem = (item->canPin() && item->isPinned())
|
||||||
? item
|
? item
|
||||||
: groupLeaderOrSelf(item);
|
: groupLeaderOrSelf(item);
|
||||||
|
|
|
@ -1508,14 +1508,18 @@ void HistoryItem::setFactcheck(MessageFactcheck info) {
|
||||||
} else {
|
} else {
|
||||||
AddComponents(HistoryMessageFactcheck::Bit());
|
AddComponents(HistoryMessageFactcheck::Bit());
|
||||||
const auto factcheck = Get<HistoryMessageFactcheck>();
|
const auto factcheck = Get<HistoryMessageFactcheck>();
|
||||||
|
const auto textChanged = (factcheck->data.text != info.text);
|
||||||
if (factcheck->data.hash == info.hash
|
if (factcheck->data.hash == info.hash
|
||||||
&& (info.needCheck || !factcheck->data.needCheck)) {
|
&& (info.needCheck || !factcheck->data.needCheck)) {
|
||||||
return;
|
return;
|
||||||
} else if (factcheck->data.text != info.text
|
} else if (textChanged
|
||||||
|| factcheck->data.country != info.country
|
|| factcheck->data.country != info.country
|
||||||
|| factcheck->data.hash != info.hash) {
|
|| factcheck->data.hash != info.hash) {
|
||||||
factcheck->data = std::move(info);
|
factcheck->data = std::move(info);
|
||||||
factcheck->requested = false;
|
factcheck->requested = false;
|
||||||
|
if (textChanged) {
|
||||||
|
factcheck->page = nullptr;
|
||||||
|
}
|
||||||
history()->owner().requestItemResize(this);
|
history()->owner().requestItemResize(this);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -1526,6 +1530,13 @@ bool HistoryItem::hasUnrequestedFactcheck() const {
|
||||||
return factcheck && factcheck->data.needCheck && !factcheck->requested;
|
return factcheck && factcheck->data.needCheck && !factcheck->requested;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
TextWithEntities HistoryItem::factcheckText() const {
|
||||||
|
if (const auto factcheck = Get<HistoryMessageFactcheck>()) {
|
||||||
|
return factcheck->data.text;
|
||||||
|
}
|
||||||
|
return {};
|
||||||
|
}
|
||||||
|
|
||||||
PeerData *HistoryItem::specialNotificationPeer() const {
|
PeerData *HistoryItem::specialNotificationPeer() const {
|
||||||
return (mentionsMe() && !_history->peer->isUser())
|
return (mentionsMe() && !_history->peer->isUser())
|
||||||
? from().get()
|
? from().get()
|
||||||
|
@ -1725,6 +1736,7 @@ void HistoryItem::applyEdition(HistoryMessageEdition &&edition) {
|
||||||
}
|
}
|
||||||
|
|
||||||
applyTTL(edition.ttl);
|
applyTTL(edition.ttl);
|
||||||
|
setFactcheck(FromMTP(this, edition.mtpFactcheck));
|
||||||
|
|
||||||
finishEdition(keyboardTop);
|
finishEdition(keyboardTop);
|
||||||
}
|
}
|
||||||
|
|
|
@ -208,6 +208,7 @@ public:
|
||||||
const TextWithEntities &content);
|
const TextWithEntities &content);
|
||||||
void setFactcheck(MessageFactcheck info);
|
void setFactcheck(MessageFactcheck info);
|
||||||
[[nodiscard]] bool hasUnrequestedFactcheck() const;
|
[[nodiscard]] bool hasUnrequestedFactcheck() const;
|
||||||
|
[[nodiscard]] TextWithEntities factcheckText() 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 {
|
||||||
|
|
|
@ -1065,6 +1065,12 @@ HistoryMessageLogEntryOriginal::~HistoryMessageLogEntryOriginal() = default;
|
||||||
MessageFactcheck FromMTP(
|
MessageFactcheck FromMTP(
|
||||||
not_null<HistoryItem*> item,
|
not_null<HistoryItem*> item,
|
||||||
const tl::conditional<MTPFactCheck> &factcheck) {
|
const tl::conditional<MTPFactCheck> &factcheck) {
|
||||||
|
return FromMTP(&item->history()->session(), factcheck);
|
||||||
|
}
|
||||||
|
|
||||||
|
MessageFactcheck FromMTP(
|
||||||
|
not_null<Main::Session*> session,
|
||||||
|
const tl::conditional<MTPFactCheck> &factcheck) {
|
||||||
auto result = MessageFactcheck();
|
auto result = MessageFactcheck();
|
||||||
if (!factcheck) {
|
if (!factcheck) {
|
||||||
return result;
|
return result;
|
||||||
|
@ -1074,9 +1080,7 @@ MessageFactcheck FromMTP(
|
||||||
const auto &data = text->data();
|
const auto &data = text->data();
|
||||||
result.text = {
|
result.text = {
|
||||||
qs(data.vtext()),
|
qs(data.vtext()),
|
||||||
Api::EntitiesFromMTP(
|
Api::EntitiesFromMTP(session, data.ventities().v),
|
||||||
&item->history()->session(),
|
|
||||||
data.ventities().v),
|
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
if (const auto country = data.vcountry()) {
|
if (const auto country = data.vcountry()) {
|
||||||
|
|
|
@ -17,6 +17,7 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
|
||||||
|
|
||||||
struct WebPageData;
|
struct WebPageData;
|
||||||
class VoiceSeekClickHandler;
|
class VoiceSeekClickHandler;
|
||||||
|
class ReplyKeyboard;
|
||||||
|
|
||||||
namespace Ui {
|
namespace Ui {
|
||||||
struct ChatPaintContext;
|
struct ChatPaintContext;
|
||||||
|
@ -31,6 +32,7 @@ struct GeometryDescriptor;
|
||||||
namespace Data {
|
namespace Data {
|
||||||
class Session;
|
class Session;
|
||||||
class Story;
|
class Story;
|
||||||
|
class SavedSublist;
|
||||||
} // namespace Data
|
} // namespace Data
|
||||||
|
|
||||||
namespace Media::Player {
|
namespace Media::Player {
|
||||||
|
@ -47,6 +49,10 @@ class Document;
|
||||||
class TranscribeButton;
|
class TranscribeButton;
|
||||||
} // namespace HistoryView
|
} // namespace HistoryView
|
||||||
|
|
||||||
|
namespace style {
|
||||||
|
struct BotKeyboardButton;
|
||||||
|
} // namespace style
|
||||||
|
|
||||||
struct HistoryMessageVia : public RuntimeComponent<HistoryMessageVia, HistoryItem> {
|
struct HistoryMessageVia : public RuntimeComponent<HistoryMessageVia, HistoryItem> {
|
||||||
void create(not_null<Data::Session*> owner, UserId userId);
|
void create(not_null<Data::Session*> owner, UserId userId);
|
||||||
void resize(int32 availw) const;
|
void resize(int32 availw) const;
|
||||||
|
@ -579,6 +585,9 @@ struct MessageFactcheck {
|
||||||
[[nodiscard]] MessageFactcheck FromMTP(
|
[[nodiscard]] MessageFactcheck FromMTP(
|
||||||
not_null<HistoryItem*> item,
|
not_null<HistoryItem*> item,
|
||||||
const tl::conditional<MTPFactCheck> &factcheck);
|
const tl::conditional<MTPFactCheck> &factcheck);
|
||||||
|
[[nodiscard]] MessageFactcheck FromMTP(
|
||||||
|
not_null<Main::Session*> session,
|
||||||
|
const tl::conditional<MTPFactCheck> &factcheck);
|
||||||
|
|
||||||
struct HistoryMessageFactcheck
|
struct HistoryMessageFactcheck
|
||||||
: public RuntimeComponent<HistoryMessageFactcheck, HistoryItem> {
|
: public RuntimeComponent<HistoryMessageFactcheck, HistoryItem> {
|
||||||
|
|
|
@ -24,6 +24,7 @@ HistoryMessageEdition::HistoryMessageEdition(
|
||||||
replyMarkup = HistoryMessageMarkupData(message.vreply_markup());
|
replyMarkup = HistoryMessageMarkupData(message.vreply_markup());
|
||||||
mtpMedia = message.vmedia();
|
mtpMedia = message.vmedia();
|
||||||
mtpReactions = message.vreactions();
|
mtpReactions = message.vreactions();
|
||||||
|
mtpFactcheck = message.vfactcheck();
|
||||||
views = message.vviews().value_or(-1);
|
views = message.vviews().value_or(-1);
|
||||||
forwards = message.vforwards().value_or(-1);
|
forwards = message.vforwards().value_or(-1);
|
||||||
if (const auto mtpReplies = message.vreplies()) {
|
if (const auto mtpReplies = message.vreplies()) {
|
||||||
|
|
|
@ -36,4 +36,5 @@ struct HistoryMessageEdition {
|
||||||
HistoryMessageRepliesData replies;
|
HistoryMessageRepliesData replies;
|
||||||
const MTPMessageMedia *mtpMedia = nullptr;
|
const MTPMessageMedia *mtpMedia = nullptr;
|
||||||
const MTPMessageReactions *mtpReactions = nullptr;
|
const MTPMessageReactions *mtpReactions = nullptr;
|
||||||
|
const MTPFactCheck *mtpFactcheck = nullptr;
|
||||||
};
|
};
|
||||||
|
|
|
@ -917,8 +917,8 @@ QSize Message::performCountOptimalSize() {
|
||||||
minHeight += st::msgPadding.top();
|
minHeight += st::msgPadding.top();
|
||||||
if (mediaDisplayed) minHeight += st::mediaInBubbleSkip;
|
if (mediaDisplayed) minHeight += st::mediaInBubbleSkip;
|
||||||
if (entry) minHeight += st::mediaInBubbleSkip;
|
if (entry) minHeight += st::mediaInBubbleSkip;
|
||||||
if (check) minHeight += st::mediaInBubbleSkip;
|
|
||||||
}
|
}
|
||||||
|
if (check) minHeight += st::mediaInBubbleSkip;
|
||||||
if (mediaDisplayed) {
|
if (mediaDisplayed) {
|
||||||
// Parts don't participate in maxWidth() in case of media message.
|
// Parts don't participate in maxWidth() in case of media message.
|
||||||
if (media->enforceBubbleWidth()) {
|
if (media->enforceBubbleWidth()) {
|
||||||
|
@ -1308,7 +1308,7 @@ void Message::draw(Painter &p, const PaintContext &context) const {
|
||||||
trect.setHeight(trect.height() - entry->height());
|
trect.setHeight(trect.height() - entry->height());
|
||||||
}
|
}
|
||||||
if (check) {
|
if (check) {
|
||||||
trect.setHeight(trect.height() - check->height());
|
trect.setHeight(trect.height() - check->height() - st::mediaInBubbleSkip);
|
||||||
}
|
}
|
||||||
if (displayInfo) {
|
if (displayInfo) {
|
||||||
trect.setHeight(trect.height()
|
trect.setHeight(trect.height()
|
||||||
|
@ -1371,7 +1371,7 @@ void Message::draw(Painter &p, const PaintContext &context) const {
|
||||||
}
|
}
|
||||||
if (check) {
|
if (check) {
|
||||||
auto checkLeft = inner.left();
|
auto checkLeft = inner.left();
|
||||||
auto checkTop = trect.y() + trect.height();
|
auto checkTop = trect.y() + trect.height() + st::mediaInBubbleSkip;
|
||||||
p.translate(checkLeft, checkTop);
|
p.translate(checkLeft, checkTop);
|
||||||
auto checkContext = context.translated(checkLeft, -checkTop);
|
auto checkContext = context.translated(checkLeft, -checkTop);
|
||||||
checkContext.selection = skipTextSelection(context.selection);
|
checkContext.selection = skipTextSelection(context.selection);
|
||||||
|
@ -1986,7 +1986,7 @@ PointState Message::pointState(QPoint point) const {
|
||||||
//}
|
//}
|
||||||
if (check) {
|
if (check) {
|
||||||
auto checkHeight = check->height();
|
auto checkHeight = check->height();
|
||||||
trect.setHeight(trect.height() - checkHeight);
|
trect.setHeight(trect.height() - checkHeight - st::mediaInBubbleSkip);
|
||||||
}
|
}
|
||||||
if (entry) {
|
if (entry) {
|
||||||
auto entryHeight = entry->height();
|
auto entryHeight = entry->height();
|
||||||
|
@ -2428,9 +2428,9 @@ TextState Message::textState(
|
||||||
}
|
}
|
||||||
if (check) {
|
if (check) {
|
||||||
auto checkHeight = check->height();
|
auto checkHeight = check->height();
|
||||||
trect.setHeight(trect.height() - checkHeight);
|
trect.setHeight(trect.height() - checkHeight - st::mediaInBubbleSkip);
|
||||||
auto checkLeft = inner.left();
|
auto checkLeft = inner.left();
|
||||||
auto checkTop = trect.y() + trect.height();
|
auto checkTop = trect.y() + trect.height() + st::mediaInBubbleSkip;
|
||||||
if (point.y() >= checkTop && point.y() < checkTop + checkHeight) {
|
if (point.y() >= checkTop && point.y() < checkTop + checkHeight) {
|
||||||
result = check->textState(
|
result = check->textState(
|
||||||
point - QPoint(checkLeft, checkTop),
|
point - QPoint(checkLeft, checkTop),
|
||||||
|
@ -4333,7 +4333,7 @@ int Message::resizeContentGetHeight(int newWidth) {
|
||||||
if (contentWidth == maxWidth()) {
|
if (contentWidth == maxWidth()) {
|
||||||
if (mediaDisplayed) {
|
if (mediaDisplayed) {
|
||||||
if (check) {
|
if (check) {
|
||||||
newHeight += check->resizeGetHeight(contentWidth);
|
newHeight += check->resizeGetHeight(contentWidth) + st::mediaInBubbleSkip;
|
||||||
}
|
}
|
||||||
if (entry) {
|
if (entry) {
|
||||||
newHeight += entry->resizeGetHeight(contentWidth);
|
newHeight += entry->resizeGetHeight(contentWidth);
|
||||||
|
@ -4365,24 +4365,16 @@ int Message::resizeContentGetHeight(int newWidth) {
|
||||||
if (!mediaOnTop) {
|
if (!mediaOnTop) {
|
||||||
newHeight += st::msgPadding.top();
|
newHeight += st::msgPadding.top();
|
||||||
if (mediaDisplayed) newHeight += st::mediaInBubbleSkip;
|
if (mediaDisplayed) newHeight += st::mediaInBubbleSkip;
|
||||||
if (check) newHeight += st::mediaInBubbleSkip;
|
|
||||||
if (entry) newHeight += st::mediaInBubbleSkip;
|
if (entry) newHeight += st::mediaInBubbleSkip;
|
||||||
}
|
}
|
||||||
if (mediaDisplayed) {
|
if (mediaDisplayed) {
|
||||||
newHeight += media->height();
|
newHeight += media->height();
|
||||||
if (check) {
|
}
|
||||||
newHeight += check->resizeGetHeight(contentWidth);
|
if (check) {
|
||||||
}
|
newHeight += check->resizeGetHeight(contentWidth) + st::mediaInBubbleSkip;
|
||||||
if (entry) {
|
}
|
||||||
newHeight += entry->resizeGetHeight(contentWidth);
|
if (entry) {
|
||||||
}
|
newHeight += entry->resizeGetHeight(contentWidth);
|
||||||
} else {
|
|
||||||
if (check) {
|
|
||||||
newHeight += check->resizeGetHeight(contentWidth);
|
|
||||||
}
|
|
||||||
if (entry) {
|
|
||||||
newHeight += entry->resizeGetHeight(contentWidth);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
if (reactionsInBubble) {
|
if (reactionsInBubble) {
|
||||||
if (!mediaDisplayed || _viewButton) {
|
if (!mediaDisplayed || _viewButton) {
|
||||||
|
@ -4518,7 +4510,8 @@ void Message::refreshInfoSkipBlock() {
|
||||||
return media->storyExpired();
|
return media->storyExpired();
|
||||||
}
|
}
|
||||||
return false;
|
return false;
|
||||||
} else if (item->Has<HistoryMessageLogEntryOriginal>()) {
|
} else if (item->Has<HistoryMessageLogEntryOriginal>()
|
||||||
|
|| factcheckBlock()) {
|
||||||
return false;
|
return false;
|
||||||
} else if (media && media->isDisplayed() && !_invertMedia) {
|
} else if (media && media->isDisplayed() && !_invertMedia) {
|
||||||
return false;
|
return false;
|
||||||
|
|
81
Telegram/SourceFiles/ui/boxes/edit_factcheck_box.cpp
Normal file
81
Telegram/SourceFiles/ui/boxes/edit_factcheck_box.cpp
Normal file
|
@ -0,0 +1,81 @@
|
||||||
|
/*
|
||||||
|
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 "ui/boxes/edit_factcheck_box.h"
|
||||||
|
|
||||||
|
#include "lang/lang_keys.h"
|
||||||
|
#include "ui/widgets/fields/input_field.h"
|
||||||
|
#include "styles/style_chat.h"
|
||||||
|
#include "styles/style_layers.h"
|
||||||
|
|
||||||
|
void EditFactcheckBox(
|
||||||
|
not_null<Ui::GenericBox*> box,
|
||||||
|
TextWithEntities current,
|
||||||
|
Fn<void(TextWithEntities)> save) {
|
||||||
|
box->setTitle(tr::lng_factcheck_title());
|
||||||
|
|
||||||
|
const auto field = box->addRow(object_ptr<Ui::InputField>(
|
||||||
|
box,
|
||||||
|
st::factcheckField,
|
||||||
|
Ui::InputField::Mode::NoNewlines,
|
||||||
|
tr::lng_factcheck_placeholder(),
|
||||||
|
TextWithTags{
|
||||||
|
current.text,
|
||||||
|
TextUtilities::ConvertEntitiesToTextTags(current.entities)
|
||||||
|
}));
|
||||||
|
|
||||||
|
enum class State {
|
||||||
|
Initial,
|
||||||
|
Changed,
|
||||||
|
Removed,
|
||||||
|
};
|
||||||
|
const auto state = box->lifetime().make_state<rpl::variable<State>>(
|
||||||
|
State::Initial);
|
||||||
|
field->changes() | rpl::start_with_next([=] {
|
||||||
|
const auto now = field->getLastText().trimmed();
|
||||||
|
*state = !now.isEmpty()
|
||||||
|
? State::Changed
|
||||||
|
: current.empty()
|
||||||
|
? State::Initial
|
||||||
|
: State::Removed;
|
||||||
|
}, field->lifetime());
|
||||||
|
|
||||||
|
state->value() | rpl::start_with_next([=](State state) {
|
||||||
|
box->clearButtons();
|
||||||
|
if (state == State::Removed) {
|
||||||
|
box->addButton(tr::lng_box_remove(), [=] {
|
||||||
|
box->closeBox();
|
||||||
|
save({});
|
||||||
|
}, st::attentionBoxButton);
|
||||||
|
} else if (state == State::Initial) {
|
||||||
|
box->addButton(tr::lng_settings_save(), [=] {
|
||||||
|
if (current.empty()) {
|
||||||
|
field->showError();
|
||||||
|
} else {
|
||||||
|
box->closeBox();
|
||||||
|
}
|
||||||
|
});
|
||||||
|
} else {
|
||||||
|
box->addButton(tr::lng_settings_save(), [=] {
|
||||||
|
auto result = field->getTextWithAppliedMarkdown();
|
||||||
|
|
||||||
|
box->closeBox();
|
||||||
|
save({
|
||||||
|
result.text,
|
||||||
|
TextUtilities::ConvertTextTagsToEntities(result.tags)
|
||||||
|
});
|
||||||
|
});
|
||||||
|
}
|
||||||
|
box->addButton(tr::lng_cancel(), [=] {
|
||||||
|
box->closeBox();
|
||||||
|
});
|
||||||
|
}, box->lifetime());
|
||||||
|
|
||||||
|
box->setFocusCallback([=] {
|
||||||
|
field->setFocusFast();
|
||||||
|
});
|
||||||
|
}
|
15
Telegram/SourceFiles/ui/boxes/edit_factcheck_box.h
Normal file
15
Telegram/SourceFiles/ui/boxes/edit_factcheck_box.h
Normal file
|
@ -0,0 +1,15 @@
|
||||||
|
/*
|
||||||
|
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 "ui/layers/generic_box.h"
|
||||||
|
|
||||||
|
void EditFactcheckBox(
|
||||||
|
not_null<Ui::GenericBox*> box,
|
||||||
|
TextWithEntities current,
|
||||||
|
Fn<void(TextWithEntities)> save);
|
|
@ -1135,3 +1135,18 @@ effectPreviewLoading: InfiniteRadialAnimation(defaultInfiniteRadialAnimation) {
|
||||||
|
|
||||||
factcheckIconExpand: icon {{ "fast_to_original-rotate_cw", historyPeer1NameFg }};
|
factcheckIconExpand: icon {{ "fast_to_original-rotate_cw", historyPeer1NameFg }};
|
||||||
factcheckIconCollapse: icon {{ "fast_to_original-rotate_ccw", historyPeer1NameFg }};
|
factcheckIconCollapse: icon {{ "fast_to_original-rotate_ccw", historyPeer1NameFg }};
|
||||||
|
factcheckField: InputField(defaultInputField) {
|
||||||
|
textBg: transparent;
|
||||||
|
textMargins: margins(0px, 0px, 0px, 4px);
|
||||||
|
|
||||||
|
placeholderFg: placeholderFg;
|
||||||
|
placeholderFgActive: placeholderFgActive;
|
||||||
|
placeholderFgError: placeholderFgActive;
|
||||||
|
placeholderMargins: margins(2px, 0px, 2px, 0px);
|
||||||
|
placeholderScale: 0.;
|
||||||
|
placeholderFont: normalFont;
|
||||||
|
|
||||||
|
heightMin: 24px;
|
||||||
|
|
||||||
|
font: normalFont;
|
||||||
|
}
|
||||||
|
|
|
@ -153,6 +153,7 @@ menuIconTagFilter: icon{{ "menu/tag_filter", menuIconColor }};
|
||||||
menuIconTagRename: icon{{ "menu/tag_rename", menuIconColor }};
|
menuIconTagRename: icon{{ "menu/tag_rename", menuIconColor }};
|
||||||
menuIconGroupsHide: icon {{ "menu/hide_members", menuIconColor }};
|
menuIconGroupsHide: icon {{ "menu/hide_members", menuIconColor }};
|
||||||
menuIconFont: icon {{ "menu/fonts", menuIconColor }};
|
menuIconFont: icon {{ "menu/fonts", menuIconColor }};
|
||||||
|
menuIconFactcheck: icon {{ "menu/factcheck", menuIconColor }};
|
||||||
|
|
||||||
menuIconTTLAny: icon {{ "menu/auto_delete_plain", menuIconColor }};
|
menuIconTTLAny: icon {{ "menu/auto_delete_plain", menuIconColor }};
|
||||||
menuIconTTLAnyTextPosition: point(11px, 22px);
|
menuIconTTLAnyTextPosition: point(11px, 22px);
|
||||||
|
|
|
@ -261,6 +261,8 @@ PRIVATE
|
||||||
ui/boxes/country_select_box.h
|
ui/boxes/country_select_box.h
|
||||||
ui/boxes/edit_birthday_box.cpp
|
ui/boxes/edit_birthday_box.cpp
|
||||||
ui/boxes/edit_birthday_box.h
|
ui/boxes/edit_birthday_box.h
|
||||||
|
ui/boxes/edit_factcheck_box.cpp
|
||||||
|
ui/boxes/edit_factcheck_box.h
|
||||||
ui/boxes/edit_invite_link.cpp
|
ui/boxes/edit_invite_link.cpp
|
||||||
ui/boxes/edit_invite_link.h
|
ui/boxes/edit_invite_link.h
|
||||||
ui/boxes/rate_call_box.cpp
|
ui/boxes/rate_call_box.cpp
|
||||||
|
|
Loading…
Add table
Reference in a new issue