From a0d97f03cb795ff3d51733164743da07834ec0ce Mon Sep 17 00:00:00 2001 From: John Preston Date: Sat, 25 May 2024 11:31:00 +0400 Subject: [PATCH] Add factcheck footer support. --- Telegram/Resources/langs/lang.strings | 1 + .../view/media/history_view_web_page.cpp | 75 ++++++++++++++++--- .../view/media/history_view_web_page.h | 6 +- Telegram/SourceFiles/ui/chat/chat.style | 4 + 4 files changed, 73 insertions(+), 13 deletions(-) diff --git a/Telegram/Resources/langs/lang.strings b/Telegram/Resources/langs/lang.strings index 54b5ee94a..eb8eecb58 100644 --- a/Telegram/Resources/langs/lang.strings +++ b/Telegram/Resources/langs/lang.strings @@ -3301,6 +3301,7 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL "lng_factcheck_add_done" = "Fact check added."; "lng_factcheck_edit_done" = "Fact check edited."; "lng_factcheck_remove_done" = "Fact check removed."; +"lng_factcheck_bottom" = "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_translate_show_original" = "Show Original"; "lng_translate_bar_to" = "Translate to {name}"; diff --git a/Telegram/SourceFiles/history/view/media/history_view_web_page.cpp b/Telegram/SourceFiles/history/view/media/history_view_web_page.cpp index 9c4c1ef05..0275ed2c2 100644 --- a/Telegram/SourceFiles/history/view/media/history_view_web_page.cpp +++ b/Telegram/SourceFiles/history/view/media/history_view_web_page.cpp @@ -153,6 +153,17 @@ constexpr auto kFactcheckAboutDuration = 5 * crl::time(1000); }); } +[[nodiscard]] QString LookupFactcheckCountryIso2( + not_null item) { + const auto info = item->Get(); + return info ? info->data.country : QString(); +} + +[[nodiscard]] QString LookupFactcheckCountryName(const QString &iso2) { + const auto name = Countries::Instance().countryNameByISO2(iso2); + return name.isEmpty() ? iso2 : name; +} + [[nodiscard]] ClickHandlerPtr AboutFactcheckClickHandler(QString iso2) { return std::make_shared([=](ClickContext context) { const auto my = context.other.value(); @@ -163,10 +174,11 @@ constexpr auto kFactcheckAboutDuration = 5 * crl::time(1000); ? controller->uiShow() : nullptr; if (show) { - const auto name = Countries::Instance().countryNameByISO2(iso2); - const auto use = name.isEmpty() ? iso2 : name; + const auto country = LookupFactcheckCountryName(iso2); show->showToast({ - .text = { tr::lng_factcheck_about(tr::now, lt_country, use) }, + .text = { + tr::lng_factcheck_about(tr::now, lt_country, country) + }, .duration = kFactcheckAboutDuration, }); } @@ -179,7 +191,7 @@ constexpr auto kFactcheckAboutDuration = 5 * crl::time(1000); return std::make_shared([=](ClickContext context) { if (const auto strong = weak.get()) { if (const auto factcheck = strong->Get()) { - factcheck->expanded = !factcheck->expanded; + factcheck->expanded = factcheck->expanded ? 0 : 1; strong->history()->owner().requestViewResize(strong); } } @@ -310,6 +322,7 @@ void WebPage::setupAdditionalData() { } } else if (_data->type == WebPageType::Factcheck) { _additionalData = std::make_unique(FactcheckData()); + const auto raw = factcheckData(); } } @@ -347,11 +360,23 @@ QSize WebPage::countOptimalSize() { _dataVersion = _data->version; _openl = nullptr; _attach = nullptr; - _collage = PrepareCollageMedia(_parent->data(), _data->collage); + const auto item = _parent->data(); + _collage = PrepareCollageMedia(item, _data->collage); const auto min = st::msgMinWidth - rect::m::sum::h(_st.padding); _siteName = Ui::Text::String(min); _title = Ui::Text::String(min); _description = Ui::Text::String(min); + if (factcheck) { + factcheck->footer = Ui::Text::String( + st::factcheckFooterStyle, + tr::lng_factcheck_bottom( + tr::now, + lt_country, + LookupFactcheckCountryName( + LookupFactcheckCountryIso2(item))), + kDefaultTextOptions, + min); + } } const auto lineHeight = UnitedLineHeight(); @@ -400,9 +425,9 @@ QSize WebPage::countOptimalSize() { } } else if (factcheck) { const auto item = _parent->data(); - if (const auto info = item->Get()) { - const auto country = info->data.country; - factcheck->hint.link = AboutFactcheckClickHandler(country); + const auto iso2 = LookupFactcheckCountryIso2(item); + if (!iso2.isEmpty()) { + factcheck->hint.link = AboutFactcheckClickHandler(iso2); } } else if (_data->document && (_data->document->isWallPaper() @@ -535,6 +560,10 @@ QSize WebPage::countOptimalSize() { _description.maxWidth() + articlePhotoMaxWidth); minHeight += descriptionMinHeight; } + if (factcheck && factcheck->expanded) { + accumulate_max(maxWidth, factcheck->footer.maxWidth()); + minHeight += st::factcheckFooterSkip + factcheck->footer.minHeight(); + } if (_attach) { const auto attachAtTop = _siteName.isEmpty() && _title.isEmpty() @@ -597,8 +626,8 @@ QSize WebPage::countCurrentSize(int newWidth) { ? computeFactcheckMetrics(_description.countHeight(innerWidth)) : FactcheckMetrics(); if (factcheck) { - factcheck->expandable = factcheckMetrics.expandable; - factcheck->expanded = factcheckMetrics.expanded; + factcheck->expandable = factcheckMetrics.expandable ? 1 : 0; + factcheck->expanded = factcheckMetrics.expanded ? 1 : 0; _openl = factcheck->expandable ? ToggleFactcheckClickHandler(_parent) : nullptr; @@ -682,6 +711,11 @@ QSize WebPage::countCurrentSize(int newWidth) { newHeight += _descriptionLines * lineHeight; } } + if (factcheck && factcheck->expanded) { + factcheck->footerHeight = st::factcheckFooterSkip + + factcheck->footer.countHeight(innerWidth); + newHeight += factcheck->footerHeight; + } if (_attach) { const auto attachAtTop = !_siteNameLines @@ -1023,6 +1057,23 @@ void WebPage::draw(Painter &p, const PaintContext &context) const { ? (_descriptionLines * lineHeight) : _description.countHeight(paintw); } + if (factcheck && factcheck->expanded) { + const auto skip = st::factcheckFooterSkip; + const auto line = st::lineWidth; + const auto separatorTop = tshift + skip / 2; + + auto color = cache->icon; + color.setAlphaF(color.alphaF() * 0.3); + p.fillRect(inner.left(), separatorTop, paintw, line, color); + + p.setPen(cache->icon); + factcheck->footer.draw(p, { + .position = { inner.left(), tshift + skip }, + .outerWidth = width(), + .availableWidth = paintw, + }); + tshift += factcheck->footerHeight; + } if (_attach) { const auto attachAtTop = !_siteNameLines && !_titleLines @@ -1492,7 +1543,9 @@ bool WebPage::isLogEntryOriginal() const { WebPage::FactcheckMetrics WebPage::computeFactcheckMetrics( int fullHeight) const { const auto possible = fullHeight / st::normalFont->height; - const auto expandable = (possible > kFactcheckCollapsedLines + 1); + //const auto expandable = (possible > kFactcheckCollapsedLines + 1); + // Now always expandable because of the footer. + const auto expandable = true; const auto check = _parent->Get(); const auto expanded = check && check->expanded; const auto allowExpanding = (expanded || !expandable); diff --git a/Telegram/SourceFiles/history/view/media/history_view_web_page.h b/Telegram/SourceFiles/history/view/media/history_view_web_page.h index 4637adb31..454af2bbf 100644 --- a/Telegram/SourceFiles/history/view/media/history_view_web_page.h +++ b/Telegram/SourceFiles/history/view/media/history_view_web_page.h @@ -129,8 +129,10 @@ private: }; struct FactcheckData { HintData hint; - bool expandable = false; - bool expanded = false; + Ui::Text::String footer; + uint32 footerHeight : 30 = 0; + uint32 expandable : 1 = 0; + uint32 expanded : 1 = 0; }; using AdditionalData = std::variant< StickerSetData, diff --git a/Telegram/SourceFiles/ui/chat/chat.style b/Telegram/SourceFiles/ui/chat/chat.style index 9dbf43303..3069b6f90 100644 --- a/Telegram/SourceFiles/ui/chat/chat.style +++ b/Telegram/SourceFiles/ui/chat/chat.style @@ -1133,6 +1133,10 @@ effectPreviewLoading: InfiniteRadialAnimation(defaultInfiniteRadialAnimation) { thickness: 2px; } +factcheckFooterSkip: 16px; +factcheckFooterStyle: TextStyle(defaultTextStyle) { + font: font(11px); +} factcheckIconExpand: icon {{ "fast_to_original-rotate_cw", historyPeer1NameFg }}; factcheckIconCollapse: icon {{ "fast_to_original-rotate_ccw", historyPeer1NameFg }}; factcheckField: InputField(defaultInputField) {