From 8779ac3ec3b6ab083ad1282b4d3d11989639415b Mon Sep 17 00:00:00 2001 From: John Preston Date: Wed, 1 Oct 2025 21:50:09 +0400 Subject: [PATCH] Hide links in chats with Report Spam. --- .../SourceFiles/data/data_media_types.cpp | 4 ++ Telegram/SourceFiles/data/data_peer.cpp | 20 ++++++++++ Telegram/SourceFiles/data/data_peer.h | 5 +-- Telegram/SourceFiles/data/data_types.h | 2 + Telegram/SourceFiles/history/history.cpp | 16 ++++++++ Telegram/SourceFiles/history/history.h | 2 + Telegram/SourceFiles/history/history_item.cpp | 37 ++++++++++++++++++- Telegram/SourceFiles/history/history_item.h | 4 ++ .../history/view/history_view_message.cpp | 4 ++ 9 files changed, 89 insertions(+), 5 deletions(-) diff --git a/Telegram/SourceFiles/data/data_media_types.cpp b/Telegram/SourceFiles/data/data_media_types.cpp index f4afc86e30..78639bddfa 100644 --- a/Telegram/SourceFiles/data/data_media_types.cpp +++ b/Telegram/SourceFiles/data/data_media_types.cpp @@ -1992,6 +1992,10 @@ std::unique_ptr MediaWebPage::createView( not_null message, not_null realParent, HistoryView::Element *replacing) { + if (realParent->hideLinks()) { + realParent->setHasHiddenLinks(true); + return nullptr; + } return std::make_unique(message, _page, _flags); } diff --git a/Telegram/SourceFiles/data/data_peer.cpp b/Telegram/SourceFiles/data/data_peer.cpp index 036d828167..1a6f4b63c8 100644 --- a/Telegram/SourceFiles/data/data_peer.cpp +++ b/Telegram/SourceFiles/data/data_peer.cpp @@ -915,6 +915,18 @@ void PeerData::setBarSettings(const MTPPeerSettings &data) { }); } +void PeerData::setBarSettings(PeerBarSettings which) { + const auto was = hideLinks(); + _barSettings.set(which); + if (was && !hideLinks()) { + if (const auto history = owner().historyLoaded(this)) { + crl::on_main(&history->session(), [=] { + history->refreshHiddenLinksItems(); + }); + } + } +} + int PeerData::paysPerMessage() const { return _barDetails ? _barDetails->paysPerMessage : 0; } @@ -936,6 +948,14 @@ void PeerData::clearPaysPerMessage() { } } +bool PeerData::hideLinks() const { + if (!isUser()) { + return false; + } + const auto settings = barSettings(); + return !settings || (*settings & PeerBarSetting::ReportSpam); +} + QString PeerData::requestChatTitle() const { return _barDetails ? _barDetails->requestChatTitle : QString(); } diff --git a/Telegram/SourceFiles/data/data_peer.h b/Telegram/SourceFiles/data/data_peer.h index ad8a1e70a3..f51fb55f3b 100644 --- a/Telegram/SourceFiles/data/data_peer.h +++ b/Telegram/SourceFiles/data/data_peer.h @@ -450,9 +450,7 @@ public: void checkFolder(FolderId folderId); - void setBarSettings(PeerBarSettings which) { - _barSettings.set(which); - } + void setBarSettings(PeerBarSettings which); [[nodiscard]] auto barSettings() const { return (_barSettings.current() & PeerBarSetting::Unknown) ? std::nullopt @@ -465,6 +463,7 @@ public: } [[nodiscard]] int paysPerMessage() const; void clearPaysPerMessage(); + [[nodiscard]] bool hideLinks() const; [[nodiscard]] QString requestChatTitle() const; [[nodiscard]] TimeId requestChatDate() const; [[nodiscard]] UserData *businessBot() const; diff --git a/Telegram/SourceFiles/data/data_types.h b/Telegram/SourceFiles/data/data_types.h index e2850df79a..f9c67856cc 100644 --- a/Telegram/SourceFiles/data/data_types.h +++ b/Telegram/SourceFiles/data/data_types.h @@ -359,6 +359,8 @@ enum class MessageFlag : uint64 { StoryInProfile = (1ULL << 54), SavedMusicItem = (1ULL << 55), + + HasHiddenLinks = (1ULL << 56), }; inline constexpr bool is_flag_type(MessageFlag) { return true; } using MessageFlags = base::flags; diff --git a/Telegram/SourceFiles/history/history.cpp b/Telegram/SourceFiles/history/history.cpp index be7089d41b..80114cdeb4 100644 --- a/Telegram/SourceFiles/history/history.cpp +++ b/Telegram/SourceFiles/history/history.cpp @@ -4079,6 +4079,22 @@ HistoryTranslation *History::translation() const { return _translation.get(); } +void History::refreshHiddenLinksItems() { + auto refresh = base::flat_set(); + for (const auto &item : _items) { + if (item->hasHiddenLinks()) { + refresh.emplace(item->fullId()); + } + } + const auto owner = &this->owner(); + for (const auto &id : refresh) { + if (const auto item = owner->message(id)) { + item->setHasHiddenLinks(false); + owner->requestItemViewRefresh(item); + } + } +} + HistoryBlock::HistoryBlock(not_null history) : _history(history) { } diff --git a/Telegram/SourceFiles/history/history.h b/Telegram/SourceFiles/history/history.h index d93b8d0614..b7fbcf5afc 100644 --- a/Telegram/SourceFiles/history/history.h +++ b/Telegram/SourceFiles/history/history.h @@ -450,6 +450,8 @@ public: [[nodiscard]] HistoryTranslation *translation() const; + void refreshHiddenLinksItems(); + const not_null peer; // Still public data. diff --git a/Telegram/SourceFiles/history/history_item.cpp b/Telegram/SourceFiles/history/history_item.cpp index 47b8410f45..2161ac49d0 100644 --- a/Telegram/SourceFiles/history/history_item.cpp +++ b/Telegram/SourceFiles/history/history_item.cpp @@ -1784,6 +1784,10 @@ UserData *HistoryItem::getMessageBot() const { return (bot && bot->isBot()) ? bot : nullptr; } +bool HistoryItem::hideLinks() const { + return !out() && history()->peer->hideLinks(); +} + bool HistoryItem::isHistoryEntry() const { return (_flags & MessageFlag::HistoryEntry); } @@ -3195,9 +3199,38 @@ const TextWithEntities &HistoryItem::translatedText() const { TextWithEntities HistoryItem::translatedTextWithLocalEntities() const { if (isService()) { return {}; - } else { - return withLocalEntities(translatedText()); } + auto result = withLocalEntities(translatedText()); + + if (hideLinks()) { + const auto isUrl = [](const EntityInText &entity) { + const auto type = entity.type(); + return (type == EntityType::Mention) + || (type == EntityType::Hashtag) + || (type == EntityType::Cashtag) + || (type == EntityType::Url) + || (type == EntityType::CustomUrl); + }; + const auto from = ranges::remove_if(result.entities, isUrl); + if (from != result.entities.end()) { + result.entities.erase(from, result.entities.end()); + setHasHiddenLinks(true); + } + } + + return result; +} + +void HistoryItem::setHasHiddenLinks(bool has) const { + if (has) { + _flags |= MessageFlag::HasHiddenLinks; + } else { + _flags &= ~MessageFlag::HasHiddenLinks; + } +} + +bool HistoryItem::hasHiddenLinks() const { + return _flags & MessageFlag::HasHiddenLinks; } TextForMimeData HistoryItem::clipboardText() const { diff --git a/Telegram/SourceFiles/history/history_item.h b/Telegram/SourceFiles/history/history_item.h index 743112461b..c7d94fd6e3 100644 --- a/Telegram/SourceFiles/history/history_item.h +++ b/Telegram/SourceFiles/history/history_item.h @@ -184,6 +184,7 @@ public: [[nodiscard]] UserData *viaBot() const; [[nodiscard]] UserData *getMessageBot() const; + [[nodiscard]] bool hideLinks() const; [[nodiscard]] bool isHistoryEntry() const; [[nodiscard]] bool isAdminLogEntry() const; [[nodiscard]] bool isFromScheduled() const; @@ -419,6 +420,9 @@ public: void incrementReplyToTopCounter(); void applyEffectWatchedOnUnreadKnown(); + void setHasHiddenLinks(bool has) const; + [[nodiscard]] bool hasHiddenLinks() const; + [[nodiscard]] bool emptyText() const { return _text.empty(); } diff --git a/Telegram/SourceFiles/history/view/history_view_message.cpp b/Telegram/SourceFiles/history/view/history_view_message.cpp index 1a82ad8cf2..0ef4f6a4f4 100644 --- a/Telegram/SourceFiles/history/view/history_view_message.cpp +++ b/Telegram/SourceFiles/history/view/history_view_message.cpp @@ -3568,6 +3568,10 @@ void Message::validateInlineKeyboard(HistoryMessageReplyMarkup *markup) { return; } const auto item = data(); + if (item->hideLinks()) { + item->setHasHiddenLinks(true); + return; + } markup->inlineKeyboard = std::make_unique( item, std::make_unique(