Compare commits
6 commits
fd0bb679f3
...
8ca9f92193
| Author | SHA1 | Date | |
|---|---|---|---|
| 8ca9f92193 | |||
| 7e12a05466 | |||
| 37d80588b7 | |||
| a3c58ae970 | |||
| 9bc9b279d4 | |||
| dd4fa8bd5a |
28 changed files with 1340 additions and 2 deletions
34
patches/feature/streamer-mode-autocomplete.patch
Normal file
34
patches/feature/streamer-mode-autocomplete.patch
Normal file
|
|
@ -0,0 +1,34 @@
|
|||
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
|
||||
From: devilreef <devilreef@femboy.page>
|
||||
Date: Fri, 1 May 2026 16:16:09 +0600
|
||||
Subject: [PATCH] streamer mode: hide username in mention autocomplete
|
||||
|
||||
---
|
||||
Telegram/SourceFiles/chat_helpers/field_autocomplete.cpp | 5 +++++
|
||||
1 file changed, 5 insertions(+)
|
||||
|
||||
diff --git a/Telegram/SourceFiles/chat_helpers/field_autocomplete.cpp b/Telegram/SourceFiles/chat_helpers/field_autocomplete.cpp
|
||||
index 0000000..0000000 100644
|
||||
--- a/Telegram/SourceFiles/chat_helpers/field_autocomplete.cpp
|
||||
+++ b/Telegram/SourceFiles/chat_helpers/field_autocomplete.cpp
|
||||
@@ -52,12 +52,17 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
|
||||
#include "styles/style_chat_helpers.h"
|
||||
#include "styles/style_menu_icons.h"
|
||||
|
||||
+#include "arcanegram/features/streamer/ag_streamer.h"
|
||||
+
|
||||
#include <QtWidgets/QApplication>
|
||||
|
||||
namespace ChatHelpers {
|
||||
namespace {
|
||||
|
||||
[[nodiscard]] QString PrimaryUsername(not_null<UserData*> user) {
|
||||
+ if (Arcanegram::Streamer::ShouldAnonymize(user)) {
|
||||
+ return QString();
|
||||
+ }
|
||||
const auto &usernames = user->usernames();
|
||||
return usernames.empty() ? user->username() : usernames.front();
|
||||
}
|
||||
--
|
||||
2.52.0.windows.1
|
||||
|
||||
48
patches/feature/streamer-mode-avatar.patch
Normal file
48
patches/feature/streamer-mode-avatar.patch
Normal file
|
|
@ -0,0 +1,48 @@
|
|||
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
|
||||
From: devilreef <devilreef@femboy.page>
|
||||
Date: Fri, 1 May 2026 15:57:28 +0600
|
||||
Subject: [PATCH] streamer mode: force empty userpic in PeerData::paintUserpic
|
||||
|
||||
---
|
||||
Telegram/SourceFiles/data/data_peer.cpp | 4 +++-
|
||||
Telegram/SourceFiles/data/data_peer.h | 2 +-
|
||||
2 files changed, 4 insertions(+), 2 deletions(-)
|
||||
|
||||
diff --git a/Telegram/SourceFiles/data/data_peer.cpp b/Telegram/SourceFiles/data/data_peer.cpp
|
||||
index 0000000..0000000 100644
|
||||
--- a/Telegram/SourceFiles/data/data_peer.cpp
|
||||
+++ b/Telegram/SourceFiles/data/data_peer.cpp
|
||||
@@ -462,7 +462,9 @@ void PeerData::paintUserpic(
|
||||
return;
|
||||
}
|
||||
const auto size = context.size;
|
||||
- const auto cloud = userpicCloudImage(view);
|
||||
+ const auto cloud = Arcanegram::Streamer::ShouldAnonymize(this)
|
||||
+ ? nullptr
|
||||
+ : userpicCloudImage(view);
|
||||
const auto ratio = style::DevicePixelRatio();
|
||||
if (context.shape == Ui::PeerUserpicShape::Auto) {
|
||||
context.shape = (isForum() && !isBot())
|
||||
diff --git a/Telegram/SourceFiles/data/data_peer.h b/Telegram/SourceFiles/data/data_peer.h
|
||||
index 0000000..0000000 100644
|
||||
--- a/Telegram/SourceFiles/data/data_peer.h
|
||||
+++ b/Telegram/SourceFiles/data/data_peer.h
|
||||
@@ -459,6 +459,7 @@ public:
|
||||
}
|
||||
|
||||
[[nodiscard]] QImage *userpicCloudImage(Ui::PeerUserpicView &view) const;
|
||||
+ void invalidateEmptyUserpic();
|
||||
|
||||
[[nodiscard]] bool canPinMessages() const;
|
||||
[[nodiscard]] bool canEditMessagesIndefinitely() const;
|
||||
@@ -597,7 +598,6 @@ protected:
|
||||
const QString &newUsername);
|
||||
void updateUserpic(PhotoId photoId, MTP::DcId dcId, bool hasVideo);
|
||||
void clearUserpic();
|
||||
- void invalidateEmptyUserpic();
|
||||
void checkTrustedPayForMessage();
|
||||
|
||||
private:
|
||||
--
|
||||
2.52.0.windows.1
|
||||
|
||||
59
patches/feature/streamer-mode-badge.patch
Normal file
59
patches/feature/streamer-mode-badge.patch
Normal file
|
|
@ -0,0 +1,59 @@
|
|||
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
|
||||
From: devilreef <devilreef@femboy.page>
|
||||
Date: Fri, 1 May 2026 16:03:37 +0600
|
||||
Subject: [PATCH] streamer mode: hide verified/scam/premium badges
|
||||
|
||||
---
|
||||
Telegram/SourceFiles/info/profile/info_profile_badge.cpp | 5 +++++
|
||||
Telegram/SourceFiles/info/profile/info_profile_values.cpp | 5 +++++
|
||||
2 files changed, 10 insertions(+)
|
||||
|
||||
diff --git a/Telegram/SourceFiles/info/profile/info_profile_badge.cpp b/Telegram/SourceFiles/info/profile/info_profile_badge.cpp
|
||||
index 0000000..0000000 100644
|
||||
--- a/Telegram/SourceFiles/info/profile/info_profile_badge.cpp
|
||||
+++ b/Telegram/SourceFiles/info/profile/info_profile_badge.cpp
|
||||
@@ -22,6 +22,8 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
|
||||
#include "main/main_session.h"
|
||||
#include "styles/style_info.h"
|
||||
|
||||
+#include "arcanegram/features/streamer/ag_streamer.h"
|
||||
+
|
||||
namespace Info::Profile {
|
||||
namespace {
|
||||
|
||||
@@ -306,6 +308,9 @@ rpl::producer<Badge::Content> VerifiedContentForPeer(
|
||||
|
||||
rpl::producer<Badge::Content> BotVerifyBadgeForPeer(
|
||||
not_null<PeerData*> peer) {
|
||||
+ if (Arcanegram::Streamer::ShouldAnonymize(peer)) {
|
||||
+ return rpl::single(Badge::Content{ BadgeType::None });
|
||||
+ }
|
||||
return peer->session().changes().peerFlagsValue(
|
||||
peer,
|
||||
Data::PeerUpdate::Flag::VerifyInfo
|
||||
diff --git a/Telegram/SourceFiles/info/profile/info_profile_values.cpp b/Telegram/SourceFiles/info/profile/info_profile_values.cpp
|
||||
index 0000000..0000000 100644
|
||||
--- a/Telegram/SourceFiles/info/profile/info_profile_values.cpp
|
||||
+++ b/Telegram/SourceFiles/info/profile/info_profile_values.cpp
|
||||
@@ -36,6 +36,8 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
|
||||
#include "boxes/peers/edit_peer_permissions_box.h"
|
||||
#include "base/unixtime.h"
|
||||
|
||||
+#include "arcanegram/features/streamer/ag_streamer.h"
|
||||
+
|
||||
namespace Info {
|
||||
namespace Profile {
|
||||
namespace {
|
||||
@@ -706,6 +708,9 @@ rpl::producer<BadgeType> BadgeValueFromFlags(Peer peer) {
|
||||
}
|
||||
|
||||
rpl::producer<BadgeType> BadgeValue(not_null<PeerData*> peer) {
|
||||
+ if (Arcanegram::Streamer::ShouldAnonymize(peer)) {
|
||||
+ return rpl::single(BadgeType::None);
|
||||
+ }
|
||||
if (const auto user = peer->asUser()) {
|
||||
return BadgeValueFromFlags<UserDataFlag>(user);
|
||||
} else if (const auto channel = peer->asChannel()) {
|
||||
--
|
||||
2.52.0.windows.1
|
||||
|
||||
50
patches/feature/streamer-mode-call-avatar.patch
Normal file
50
patches/feature/streamer-mode-call-avatar.patch
Normal file
|
|
@ -0,0 +1,50 @@
|
|||
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
|
||||
From: devilreef <devilreef@femboy.page>
|
||||
Date: Fri, 1 May 2026 15:57:40 +0600
|
||||
Subject: [PATCH] streamer mode: empty userpic in fullscreen call
|
||||
|
||||
---
|
||||
Telegram/SourceFiles/calls/calls_userpic.cpp | 13 +++++++++----
|
||||
1 file changed, 9 insertions(+), 4 deletions(-)
|
||||
|
||||
diff --git a/Telegram/SourceFiles/calls/calls_userpic.cpp b/Telegram/SourceFiles/calls/calls_userpic.cpp
|
||||
index 0000000..0000000 100644
|
||||
--- a/Telegram/SourceFiles/calls/calls_userpic.cpp
|
||||
+++ b/Telegram/SourceFiles/calls/calls_userpic.cpp
|
||||
@@ -7,6 +7,7 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
|
||||
*/
|
||||
#include "calls/calls_userpic.h"
|
||||
|
||||
+#include "arcanegram/features/streamer/ag_streamer.h"
|
||||
#include "data/data_peer.h"
|
||||
#include "main/main_session.h"
|
||||
#include "data/data_changes.h"
|
||||
@@ -130,9 +131,10 @@ int Userpic::size() const {
|
||||
void Userpic::processPhoto() {
|
||||
_userpic = _peer->createUserpicView();
|
||||
_peer->loadUserpic();
|
||||
- const auto photo = _peer->userpicPhotoId()
|
||||
- ? _peer->owner().photo(_peer->userpicPhotoId()).get()
|
||||
- : nullptr;
|
||||
+ const auto photo = (Arcanegram::Streamer::ShouldAnonymize(_peer)
|
||||
+ || !_peer->userpicPhotoId())
|
||||
+ ? nullptr
|
||||
+ : _peer->owner().photo(_peer->userpicPhotoId()).get();
|
||||
if (isGoodPhoto(photo)) {
|
||||
_photo = photo->createMediaView();
|
||||
_photo->wanted(Data::PhotoSize::Thumbnail, _peer->userpicPhotoOrigin());
|
||||
@@ -159,7 +161,10 @@ void Userpic::refreshPhoto() {
|
||||
_userPhotoFull = true;
|
||||
createCache(_photo->image(Data::PhotoSize::Thumbnail));
|
||||
} else if (_userPhoto.isNull()) {
|
||||
- if (const auto cloud = _peer->userpicCloudImage(_userpic)) {
|
||||
+ const auto cloud = Arcanegram::Streamer::ShouldAnonymize(_peer)
|
||||
+ ? nullptr
|
||||
+ : _peer->userpicCloudImage(_userpic);
|
||||
+ if (cloud) {
|
||||
auto image = Image(base::duplicate(*cloud));
|
||||
createCache(&image);
|
||||
} else {
|
||||
--
|
||||
2.52.0.windows.1
|
||||
|
||||
58
patches/feature/streamer-mode-forum-topic.patch
Normal file
58
patches/feature/streamer-mode-forum-topic.patch
Normal file
|
|
@ -0,0 +1,58 @@
|
|||
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
|
||||
From: devilreef <devilreef@femboy.page>
|
||||
Date: Fri, 1 May 2026 16:53:21 +0600
|
||||
Subject: [PATCH] streamer mode: anonymize forum topic title
|
||||
|
||||
---
|
||||
Telegram/SourceFiles/data/data_forum_topic.cpp | 7 +++++++
|
||||
Telegram/SourceFiles/data/data_forum_topic.h | 2 +-
|
||||
2 files changed, 8 insertions(+), 1 deletion(-)
|
||||
|
||||
diff --git a/Telegram/SourceFiles/data/data_forum_topic.cpp b/Telegram/SourceFiles/data/data_forum_topic.cpp
|
||||
index 0000000..0000000 100644
|
||||
--- a/Telegram/SourceFiles/data/data_forum_topic.cpp
|
||||
+++ b/Telegram/SourceFiles/data/data_forum_topic.cpp
|
||||
@@ -7,6 +7,7 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
|
||||
*/
|
||||
#include "data/data_forum_topic.h"
|
||||
|
||||
+#include "arcanegram/features/streamer/ag_streamer.h"
|
||||
#include "data/data_channel.h"
|
||||
#include "data/data_changes.h"
|
||||
#include "data/data_forum.h"
|
||||
@@ -958,6 +959,12 @@ bool ForumTopic::chatListMessageKnown() const {
|
||||
}
|
||||
|
||||
const QString &ForumTopic::chatListName() const {
|
||||
+ if (channel() && Arcanegram::Streamer::ShouldAnonymize(channel())) {
|
||||
+ static thread_local QString cached;
|
||||
+ const auto seed = channel()->id.value ^ quint64(rootId().bare);
|
||||
+ cached = Arcanegram::Streamer::GeneratedShortName(PeerId(seed));
|
||||
+ return cached;
|
||||
+ }
|
||||
return _title;
|
||||
}
|
||||
|
||||
diff --git a/Telegram/SourceFiles/data/data_forum_topic.h b/Telegram/SourceFiles/data/data_forum_topic.h
|
||||
index 0000000..0000000 100644
|
||||
--- a/Telegram/SourceFiles/data/data_forum_topic.h
|
||||
+++ b/Telegram/SourceFiles/data/data_forum_topic.h
|
||||
@@ -153,6 +153,7 @@ public:
|
||||
[[nodiscard]] TextWithEntities titleWithIcon() const;
|
||||
[[nodiscard]] TextWithEntities titleWithIconOrLogo() const;
|
||||
[[nodiscard]] int titleVersion() const;
|
||||
+ void invalidateTitleWithIcon();
|
||||
void applyTitle(const QString &title);
|
||||
[[nodiscard]] DocumentId iconId() const;
|
||||
void applyIconId(DocumentId iconId);
|
||||
@@ -206,7 +207,6 @@ private:
|
||||
void validateGeneralIcon(const Dialogs::Ui::PaintContext &context) const;
|
||||
void applyTopicTopMessage(MsgId topMessageId);
|
||||
void growLastKnownServerMessageId(MsgId id);
|
||||
- void invalidateTitleWithIcon();
|
||||
|
||||
void setLastMessage(HistoryItem *item);
|
||||
void setLastServerMessage(HistoryItem *item);
|
||||
--
|
||||
2.52.0.windows.1
|
||||
|
||||
78
patches/feature/streamer-mode-name.patch
Normal file
78
patches/feature/streamer-mode-name.patch
Normal file
|
|
@ -0,0 +1,78 @@
|
|||
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
|
||||
From: devilreef <devilreef@femboy.page>
|
||||
Date: Fri, 1 May 2026 15:49:36 +0600
|
||||
Subject: [PATCH] streamer mode: pseudonym in PeerData::name accessors
|
||||
|
||||
---
|
||||
Telegram/SourceFiles/data/data_peer.cpp | 20 ++++++++++++++++++++
|
||||
Telegram/SourceFiles/data/data_peer.h | 1 +
|
||||
2 files changed, 21 insertions(+)
|
||||
|
||||
diff --git a/Telegram/SourceFiles/data/data_peer.cpp b/Telegram/SourceFiles/data/data_peer.cpp
|
||||
index 0000000..0000000 100644
|
||||
--- a/Telegram/SourceFiles/data/data_peer.cpp
|
||||
+++ b/Telegram/SourceFiles/data/data_peer.cpp
|
||||
@@ -7,6 +7,7 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
|
||||
*/
|
||||
#include "data/data_peer.h"
|
||||
|
||||
+#include "arcanegram/features/streamer/ag_streamer.h"
|
||||
#include "api/api_sensitive_content.h"
|
||||
#include "data/data_user.h"
|
||||
#include "data/data_chat.h"
|
||||
@@ -1313,6 +1314,11 @@ ChannelData *PeerData::broadcastMonoforum() const {
|
||||
}
|
||||
|
||||
const QString &PeerData::topBarNameText() const {
|
||||
+ if (Arcanegram::Streamer::ShouldAnonymize(this)) {
|
||||
+ static thread_local QString cached;
|
||||
+ cached = Arcanegram::Streamer::GeneratedName(id);
|
||||
+ return cached;
|
||||
+ }
|
||||
if (const auto to = migrateTo()) {
|
||||
return to->topBarNameText();
|
||||
} else if (const auto user = asUser()) {
|
||||
@@ -1327,7 +1333,16 @@ int PeerData::nameVersion() const {
|
||||
return _nameVersion;
|
||||
}
|
||||
|
||||
+void PeerData::noteNameUpdated() {
|
||||
+ ++_nameVersion;
|
||||
+}
|
||||
+
|
||||
const QString &PeerData::name() const {
|
||||
+ if (Arcanegram::Streamer::ShouldAnonymize(this)) {
|
||||
+ static thread_local QString cached;
|
||||
+ cached = Arcanegram::Streamer::GeneratedName(id);
|
||||
+ return cached;
|
||||
+ }
|
||||
if (const auto to = migrateTo()) {
|
||||
return to->name();
|
||||
} else if (const auto broadcast = monoforumBroadcast()) {
|
||||
@@ -1337,6 +1352,11 @@ const QString &PeerData::name() const {
|
||||
}
|
||||
|
||||
const QString &PeerData::shortName() const {
|
||||
+ if (Arcanegram::Streamer::ShouldAnonymize(this)) {
|
||||
+ static thread_local QString cached;
|
||||
+ cached = Arcanegram::Streamer::GeneratedShortName(id);
|
||||
+ return cached;
|
||||
+ }
|
||||
if (const auto user = asUser()) {
|
||||
return user->firstName.isEmpty() ? user->lastName : user->firstName;
|
||||
} else if (const auto to = migrateTo()) {
|
||||
diff --git a/Telegram/SourceFiles/data/data_peer.h b/Telegram/SourceFiles/data/data_peer.h
|
||||
index 0000000..0000000 100644
|
||||
--- a/Telegram/SourceFiles/data/data_peer.h
|
||||
+++ b/Telegram/SourceFiles/data/data_peer.h
|
||||
@@ -365,6 +365,7 @@ public:
|
||||
}
|
||||
|
||||
[[nodiscard]] int nameVersion() const;
|
||||
+ void noteNameUpdated();
|
||||
[[nodiscard]] const QString &name() const;
|
||||
[[nodiscard]] const QString &shortName() const;
|
||||
[[nodiscard]] const QString &topBarNameText() const;
|
||||
--
|
||||
2.52.0.windows.1
|
||||
|
||||
75
patches/feature/streamer-mode-profile-actions.patch
Normal file
75
patches/feature/streamer-mode-profile-actions.patch
Normal file
|
|
@ -0,0 +1,75 @@
|
|||
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
|
||||
From: devilreef <devilreef@femboy.page>
|
||||
Date: Fri, 1 May 2026 16:10:29 +0600
|
||||
Subject: [PATCH] streamer mode: hide peer id, birthday, username link
|
||||
|
||||
---
|
||||
.../info/profile/info_profile_actions.cpp | 21 +++++++++++++------
|
||||
1 file changed, 15 insertions(+), 6 deletions(-)
|
||||
|
||||
diff --git a/Telegram/SourceFiles/info/profile/info_profile_actions.cpp b/Telegram/SourceFiles/info/profile/info_profile_actions.cpp
|
||||
index 0000000..0000000 100644
|
||||
--- a/Telegram/SourceFiles/info/profile/info_profile_actions.cpp
|
||||
+++ b/Telegram/SourceFiles/info/profile/info_profile_actions.cpp
|
||||
@@ -8,6 +8,7 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
|
||||
#include "info/profile/info_profile_actions.h"
|
||||
|
||||
#include "arcanegram/features/ag_peer_ids.h"
|
||||
+#include "arcanegram/features/streamer/ag_streamer.h"
|
||||
#include "api/api_blocked_peers.h"
|
||||
#include "api/api_chat_participants.h"
|
||||
#include "api/api_credits.h"
|
||||
@@ -173,6 +174,9 @@ base::options::toggle ShowChannelJoinedBelowAbout({
|
||||
const QString &addToLink) {
|
||||
const auto weak = base::make_weak(controller);
|
||||
return [=](QString link) {
|
||||
+ if (Arcanegram::Streamer::ShouldAnonymize(peer)) {
|
||||
+ return;
|
||||
+ }
|
||||
if (link.startsWith(u"internal:"_q)) {
|
||||
Core::App().openInternalUrl(link,
|
||||
QVariant::fromValue(ClickHandlerContext{
|
||||
@@ -213,7 +217,8 @@ base::options::toggle ShowChannelJoinedBelowAbout({
|
||||
return AboutValue(
|
||||
peer
|
||||
) | rpl::map([=](TextWithEntities &&value) {
|
||||
- if (ShowPeerIdBelowAbout.value()) {
|
||||
+ const auto anonymize = Arcanegram::Streamer::ShouldAnonymize(peer);
|
||||
+ if (ShowPeerIdBelowAbout.value() && !anonymize) {
|
||||
using namespace Ui::Text;
|
||||
if (!value.empty()) {
|
||||
value.append("\n\n");
|
||||
@@ -226,11 +231,11 @@ base::options::toggle ShowChannelJoinedBelowAbout({
|
||||
"internal:~peer_id~:copy:" + botApi
|
||||
+ ":mtproto:" + mtproto));
|
||||
}
|
||||
- if (ShowChannelJoinedBelowAbout.value()) {
|
||||
+ if (ShowChannelJoinedBelowAbout.value() && !anonymize) {
|
||||
if (const auto channel = peer->asChannel()) {
|
||||
if (!channel->amCreator() && channel->inviteDate) {
|
||||
if (!value.empty()) {
|
||||
- if (ShowPeerIdBelowAbout.value()) {
|
||||
+ if (ShowPeerIdBelowAbout.value() && !anonymize) {
|
||||
value.append("\n");
|
||||
} else {
|
||||
value.append("\n\n");
|
||||
@@ -898,9 +903,13 @@ void DeleteContactNote(
|
||||
const auto layout = outer->entity();
|
||||
layout->setAttribute(Qt::WA_TransparentForMouseEvents);
|
||||
|
||||
- auto birthday = BirthdayValue(
|
||||
- user
|
||||
- ) | rpl::start_spawning(result->lifetime());
|
||||
+ auto birthday = rpl::combine(
|
||||
+ BirthdayValue(user),
|
||||
+ rpl::single(Arcanegram::Streamer::IsActive())
|
||||
+ | rpl::then(Arcanegram::Streamer::Changes())
|
||||
+ ) | rpl::map([](Data::Birthday value, bool streamer) {
|
||||
+ return streamer ? Data::Birthday() : value;
|
||||
+ }) | rpl::start_spawning(result->lifetime());
|
||||
|
||||
auto label = BirthdayLabelText(rpl::duplicate(birthday));
|
||||
auto text = BirthdayValueText(
|
||||
--
|
||||
2.52.0.windows.1
|
||||
|
||||
100
patches/feature/streamer-mode-profile-identity.patch
Normal file
100
patches/feature/streamer-mode-profile-identity.patch
Normal file
|
|
@ -0,0 +1,100 @@
|
|||
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
|
||||
From: devilreef <devilreef@femboy.page>
|
||||
Date: Fri, 1 May 2026 16:08:54 +0600
|
||||
Subject: [PATCH] streamer mode: hide profile phone/username/bio/common-chats
|
||||
|
||||
---
|
||||
.../info/profile/info_profile_values.cpp | 56 +++++++++++--------
|
||||
1 file changed, 34 insertions(+), 22 deletions(-)
|
||||
|
||||
diff --git a/Telegram/SourceFiles/info/profile/info_profile_values.cpp b/Telegram/SourceFiles/info/profile/info_profile_values.cpp
|
||||
index 0000000..0000000 100644
|
||||
--- a/Telegram/SourceFiles/info/profile/info_profile_values.cpp
|
||||
+++ b/Telegram/SourceFiles/info/profile/info_profile_values.cpp
|
||||
@@ -45,11 +45,14 @@ namespace {
|
||||
using UpdateFlag = Data::PeerUpdate::Flag;
|
||||
|
||||
auto PlainAboutValue(not_null<PeerData*> peer) {
|
||||
- return peer->session().changes().peerFlagsValue(
|
||||
- peer,
|
||||
- UpdateFlag::About
|
||||
- ) | rpl::map([=] {
|
||||
- return peer->about();
|
||||
+ return rpl::combine(
|
||||
+ peer->session().changes().peerFlagsValue(
|
||||
+ peer,
|
||||
+ UpdateFlag::About),
|
||||
+ rpl::single(Arcanegram::Streamer::IsActive())
|
||||
+ | rpl::then(Arcanegram::Streamer::Changes())
|
||||
+ ) | rpl::map([=](const auto &, bool streamer) {
|
||||
+ return streamer ? QString() : peer->about();
|
||||
});
|
||||
}
|
||||
|
||||
@@ -126,13 +129,16 @@ rpl::producer<int32> ColorIdValue(not_null<Data::ForumTopic*> topic) {
|
||||
}
|
||||
|
||||
rpl::producer<TextWithEntities> PhoneValue(not_null<UserData*> user) {
|
||||
- return rpl::merge(
|
||||
- Countries::Instance().updated(),
|
||||
- user->session().changes().peerFlagsValue(
|
||||
- user,
|
||||
- UpdateFlag::PhoneNumber) | rpl::to_empty
|
||||
- ) | rpl::map([=] {
|
||||
- return tr::marked(Ui::FormatPhone(user->phone()));
|
||||
+ return rpl::combine(
|
||||
+ rpl::merge(
|
||||
+ Countries::Instance().updated(),
|
||||
+ user->session().changes().peerFlagsValue(
|
||||
+ user,
|
||||
+ UpdateFlag::PhoneNumber) | rpl::to_empty),
|
||||
+ rpl::single(Arcanegram::Streamer::IsActive())
|
||||
+ | rpl::then(Arcanegram::Streamer::Changes())
|
||||
+ ) | rpl::map([=](const auto &, bool streamer) {
|
||||
+ return tr::marked(Ui::FormatPhone(streamer ? QString() : user->phone()));
|
||||
});
|
||||
}
|
||||
|
||||
@@ -161,11 +167,14 @@ rpl::producer<TextWithEntities> PhoneOrHiddenValue(not_null<UserData*> user) {
|
||||
rpl::producer<TextWithEntities> UsernameValue(
|
||||
not_null<PeerData*> peer,
|
||||
bool primary) {
|
||||
- return (primary
|
||||
- ? PlainPrimaryUsernameValue(peer)
|
||||
- : (PlainUsernameValue(peer) | rpl::type_erased)
|
||||
- ) | rpl::map([](QString &&username) {
|
||||
- return username.isEmpty()
|
||||
+ return rpl::combine(
|
||||
+ (primary
|
||||
+ ? PlainPrimaryUsernameValue(peer)
|
||||
+ : (PlainUsernameValue(peer) | rpl::type_erased)),
|
||||
+ rpl::single(Arcanegram::Streamer::IsActive())
|
||||
+ | rpl::then(Arcanegram::Streamer::Changes())
|
||||
+ ) | rpl::map([](const QString &username, bool streamer) {
|
||||
+ return (streamer || username.isEmpty())
|
||||
? tr::marked()
|
||||
: tr::marked('@' + username);
|
||||
});
|
||||
@@ -600,11 +609,14 @@ rpl::producer<int> SharedMediaCountValue(
|
||||
}
|
||||
|
||||
rpl::producer<int> CommonGroupsCountValue(not_null<UserData*> user) {
|
||||
- return user->session().changes().peerFlagsValue(
|
||||
- user,
|
||||
- UpdateFlag::CommonChats
|
||||
- ) | rpl::map([=] {
|
||||
- return user->commonChatsCount();
|
||||
+ return rpl::combine(
|
||||
+ user->session().changes().peerFlagsValue(
|
||||
+ user,
|
||||
+ UpdateFlag::CommonChats),
|
||||
+ rpl::single(Arcanegram::Streamer::IsActive())
|
||||
+ | rpl::then(Arcanegram::Streamer::Changes())
|
||||
+ ) | rpl::map([=](const auto &, bool streamer) {
|
||||
+ return streamer ? 0 : user->commonChatsCount();
|
||||
});
|
||||
}
|
||||
|
||||
--
|
||||
2.52.0.windows.1
|
||||
|
||||
35
patches/feature/streamer-mode-rank.patch
Normal file
35
patches/feature/streamer-mode-rank.patch
Normal file
|
|
@ -0,0 +1,35 @@
|
|||
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
|
||||
From: devilreef <devilreef@femboy.page>
|
||||
Date: Fri, 1 May 2026 17:12:52 +0600
|
||||
Subject: [PATCH] streamer mode: drop admin custom title and rank badge for
|
||||
anonymized senders
|
||||
|
||||
---
|
||||
Telegram/SourceFiles/history/view/history_view_message.cpp | 4 ++++
|
||||
1 file changed, 4 insertions(+)
|
||||
|
||||
diff --git a/Telegram/SourceFiles/history/view/history_view_message.cpp b/Telegram/SourceFiles/history/view/history_view_message.cpp
|
||||
index 0000000..0000000 100644
|
||||
--- a/Telegram/SourceFiles/history/view/history_view_message.cpp
|
||||
+++ b/Telegram/SourceFiles/history/view/history_view_message.cpp
|
||||
@@ -10,6 +10,7 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
|
||||
#include "api/api_suggest_post.h"
|
||||
#include "api/api_transcribes.h"
|
||||
#include "arcanegram/features/ag_hidden_users.h"
|
||||
+#include "arcanegram/features/streamer/ag_streamer.h"
|
||||
#include "base/qt/qt_key_modifiers.h"
|
||||
#include "base/unixtime.h"
|
||||
#include "core/click_handler_types.h" // ClickHandlerContext
|
||||
@@ -393,6 +394,9 @@ void Message::refreshRightBadge() {
|
||||
}
|
||||
const auto item = data();
|
||||
const auto [text, role, special] = [&]() -> std::tuple<QString, BadgeRole, bool> {
|
||||
+ if (Arcanegram::Streamer::ShouldAnonymize(item->author())) {
|
||||
+ return { QString(), BadgeRole::User, false };
|
||||
+ }
|
||||
if (item->isDiscussionPost()) {
|
||||
return {
|
||||
(delegate()->elementContext() == Context::Replies)
|
||||
--
|
||||
2.52.0.windows.1
|
||||
|
||||
46
patches/feature/streamer-mode-rating.patch
Normal file
46
patches/feature/streamer-mode-rating.patch
Normal file
|
|
@ -0,0 +1,46 @@
|
|||
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
|
||||
From: devilreef <devilreef@femboy.page>
|
||||
Date: Fri, 1 May 2026 17:22:26 +0600
|
||||
Subject: [PATCH] streamer mode: hide profile rating
|
||||
|
||||
---
|
||||
Telegram/SourceFiles/data/data_peer_values.cpp | 16 ++++++++++++----
|
||||
1 file changed, 12 insertions(+), 4 deletions(-)
|
||||
|
||||
diff --git a/Telegram/SourceFiles/data/data_peer_values.cpp b/Telegram/SourceFiles/data/data_peer_values.cpp
|
||||
index 0000000..0000000 100644
|
||||
--- a/Telegram/SourceFiles/data/data_peer_values.cpp
|
||||
+++ b/Telegram/SourceFiles/data/data_peer_values.cpp
|
||||
@@ -20,6 +20,8 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
|
||||
#include "ui/image/image_prepare.h"
|
||||
#include "base/unixtime.h"
|
||||
|
||||
+#include "arcanegram/features/streamer/ag_streamer.h"
|
||||
+
|
||||
namespace Data {
|
||||
namespace {
|
||||
|
||||
@@ -524,10 +526,16 @@ bool ChannelHasSubscriptionUntilDate(ChannelData *channel) {
|
||||
rpl::producer<Data::StarsRating> StarsRatingValue(
|
||||
not_null<PeerData*> peer) {
|
||||
if (const auto user = peer->asUser()) {
|
||||
- return user->session().changes().peerFlagsValue(
|
||||
- user,
|
||||
- Data::PeerUpdate::Flag::StarsRating
|
||||
- ) | rpl::map([=] {
|
||||
+ return rpl::combine(
|
||||
+ user->session().changes().peerFlagsValue(
|
||||
+ user,
|
||||
+ Data::PeerUpdate::Flag::StarsRating),
|
||||
+ rpl::single(Arcanegram::Streamer::IsActive())
|
||||
+ | rpl::then(Arcanegram::Streamer::Changes())
|
||||
+ ) | rpl::map([=](const auto &, bool streamer) {
|
||||
+ if (streamer) {
|
||||
+ return Data::StarsRating();
|
||||
+ }
|
||||
auto result = user->starsRating();
|
||||
if (!user->isSelf() && result.level < 0) {
|
||||
result.stars = 0;
|
||||
--
|
||||
2.52.0.windows.1
|
||||
|
||||
39
patches/feature/streamer-mode-reply-shorten.patch
Normal file
39
patches/feature/streamer-mode-reply-shorten.patch
Normal file
|
|
@ -0,0 +1,39 @@
|
|||
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
|
||||
From: devilreef <devilreef@femboy.page>
|
||||
Date: Fri, 1 May 2026 15:50:34 +0600
|
||||
Subject: [PATCH] streamer mode: pseudonym in shortened reply sender name
|
||||
|
||||
---
|
||||
Telegram/SourceFiles/history/view/history_view_reply.cpp | 9 ++++++++-
|
||||
1 file changed, 8 insertions(+), 1 deletion(-)
|
||||
|
||||
diff --git a/Telegram/SourceFiles/history/view/history_view_reply.cpp b/Telegram/SourceFiles/history/view/history_view_reply.cpp
|
||||
index 0000000..0000000 100644
|
||||
--- a/Telegram/SourceFiles/history/view/history_view_reply.cpp
|
||||
+++ b/Telegram/SourceFiles/history/view/history_view_reply.cpp
|
||||
@@ -8,6 +8,7 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
|
||||
#include "history/view/history_view_reply.h"
|
||||
|
||||
#include "arcanegram/features/ag_hidden_users.h"
|
||||
+#include "arcanegram/features/streamer/ag_streamer.h"
|
||||
#include "core/click_handler_types.h"
|
||||
#include "core/ui_integration.h"
|
||||
#include "data/stickers/data_custom_emoji.h"
|
||||
@@ -602,7 +603,13 @@ QString Reply::senderName(
|
||||
not_null<PeerData*> peer,
|
||||
bool shorten) const {
|
||||
const auto user = shorten ? peer->asUser() : nullptr;
|
||||
- return user ? user->firstName : peer->name();
|
||||
+ if (user) {
|
||||
+ const auto firstName = Arcanegram::Streamer::ShouldAnonymize(peer)
|
||||
+ ? Arcanegram::Streamer::GeneratedShortName(peer->id)
|
||||
+ : user->firstName;
|
||||
+ return firstName;
|
||||
+ }
|
||||
+ return peer->name();
|
||||
}
|
||||
|
||||
bool Reply::isNameUpdated(
|
||||
--
|
||||
2.52.0.windows.1
|
||||
|
||||
55
patches/feature/streamer-mode-search.patch
Normal file
55
patches/feature/streamer-mode-search.patch
Normal file
|
|
@ -0,0 +1,55 @@
|
|||
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
|
||||
From: devilreef <devilreef@femboy.page>
|
||||
Date: Fri, 1 May 2026 16:16:33 +0600
|
||||
Subject: [PATCH] streamer mode: hide username in dialogs search rows
|
||||
|
||||
---
|
||||
.../dialogs/dialogs_inner_widget.cpp | 18 ++++++++++++------
|
||||
1 file changed, 12 insertions(+), 6 deletions(-)
|
||||
|
||||
diff --git a/Telegram/SourceFiles/dialogs/dialogs_inner_widget.cpp b/Telegram/SourceFiles/dialogs/dialogs_inner_widget.cpp
|
||||
index 0000000..0000000 100644
|
||||
--- a/Telegram/SourceFiles/dialogs/dialogs_inner_widget.cpp
|
||||
+++ b/Telegram/SourceFiles/dialogs/dialogs_inner_widget.cpp
|
||||
@@ -68,6 +68,8 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
|
||||
#include "window/notifications_manager.h"
|
||||
#include "window/window_controller.h"
|
||||
#include "window/window_session_controller.h"
|
||||
+
|
||||
+#include "arcanegram/features/streamer/ag_streamer.h"
|
||||
#include "window/window_peer_menu.h"
|
||||
#include "ui/chat/chats_filter_tag.h"
|
||||
#include "ui/effects/ripple_animation.h"
|
||||
@@ -1610,7 +1612,9 @@ void InnerWidget::paintPeerSearchResult(
|
||||
|
||||
QRect tr(context.st->textLeft, context.st->textTop, namewidth, st::dialogsTextFont->height);
|
||||
p.setFont(st::dialogsTextFont);
|
||||
- QString username = peer->username();
|
||||
+ QString username = Arcanegram::Streamer::ShouldAnonymize(peer)
|
||||
+ ? QString()
|
||||
+ : peer->username();
|
||||
if (!context.active && username.startsWith(_peerSearchQuery, Qt::CaseInsensitive)) {
|
||||
auto first = '@' + username.mid(0, _peerSearchQuery.size());
|
||||
auto second = username.mid(_peerSearchQuery.size());
|
||||
@@ -1755,11 +1759,13 @@ void InnerWidget::performDrag() {
|
||||
u"application/x-telegram-dialog"_q,
|
||||
std::move(byteArray));
|
||||
|
||||
- if (const auto u = history->peer->username(); !u.isEmpty()) {
|
||||
- mimeData->setText(history->peer->session().createInternalLinkFull(u));
|
||||
- mimeData->setData(
|
||||
- u"application/x-telegram-input-field"_q,
|
||||
- ('@' + u).toUtf8());
|
||||
+ if (!Arcanegram::Streamer::ShouldAnonymize(history->peer)) {
|
||||
+ if (const auto u = history->peer->username(); !u.isEmpty()) {
|
||||
+ mimeData->setText(history->peer->session().createInternalLinkFull(u));
|
||||
+ mimeData->setData(
|
||||
+ u"application/x-telegram-input-field"_q,
|
||||
+ ('@' + u).toUtf8());
|
||||
+ }
|
||||
}
|
||||
|
||||
const auto &st = st::defaultDialogRow;
|
||||
--
|
||||
2.52.0.windows.1
|
||||
|
||||
29
patches/feature/streamer-mode-seen-avatars.patch
Normal file
29
patches/feature/streamer-mode-seen-avatars.patch
Normal file
|
|
@ -0,0 +1,29 @@
|
|||
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
|
||||
From: devilreef <devilreef@femboy.page>
|
||||
Date: Fri, 1 May 2026 17:13:09 +0600
|
||||
Subject: [PATCH] streamer mode: force empty userpic in
|
||||
PeerData::GenerateUserpicImage
|
||||
|
||||
---
|
||||
Telegram/SourceFiles/data/data_peer.cpp | 5 ++++-
|
||||
1 file changed, 4 insertions(+), 1 deletion(-)
|
||||
|
||||
diff --git a/Telegram/SourceFiles/data/data_peer.cpp b/Telegram/SourceFiles/data/data_peer.cpp
|
||||
index 0000000..0000000 100644
|
||||
--- a/Telegram/SourceFiles/data/data_peer.cpp
|
||||
+++ b/Telegram/SourceFiles/data/data_peer.cpp
|
||||
@@ -518,7 +518,10 @@ QImage PeerData::GenerateUserpicImage(
|
||||
Ui::PeerUserpicView &view,
|
||||
int size,
|
||||
std::optional<int> radius) {
|
||||
- if (const auto userpic = peer->userpicCloudImage(view)) {
|
||||
+ const auto userpic = Arcanegram::Streamer::ShouldAnonymize(peer)
|
||||
+ ? nullptr
|
||||
+ : peer->userpicCloudImage(view);
|
||||
+ if (userpic) {
|
||||
auto image = userpic->scaled(
|
||||
{ size, size },
|
||||
Qt::IgnoreAspectRatio,
|
||||
--
|
||||
2.52.0.windows.1
|
||||
|
||||
35
patches/feature/streamer-mode-short-info-box.patch
Normal file
35
patches/feature/streamer-mode-short-info-box.patch
Normal file
|
|
@ -0,0 +1,35 @@
|
|||
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
|
||||
From: devilreef <devilreef@femboy.page>
|
||||
Date: Fri, 1 May 2026 15:58:05 +0600
|
||||
Subject: [PATCH] streamer mode: skip photo carousel in profile preview
|
||||
|
||||
---
|
||||
Telegram/SourceFiles/boxes/peers/prepare_short_info_box.cpp | 5 ++++-
|
||||
1 file changed, 4 insertions(+), 1 deletion(-)
|
||||
|
||||
diff --git a/Telegram/SourceFiles/boxes/peers/prepare_short_info_box.cpp b/Telegram/SourceFiles/boxes/peers/prepare_short_info_box.cpp
|
||||
index 0000000..0000000 100644
|
||||
--- a/Telegram/SourceFiles/boxes/peers/prepare_short_info_box.cpp
|
||||
+++ b/Telegram/SourceFiles/boxes/peers/prepare_short_info_box.cpp
|
||||
@@ -7,6 +7,7 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
|
||||
*/
|
||||
#include "boxes/peers/prepare_short_info_box.h"
|
||||
|
||||
+#include "arcanegram/features/streamer/ag_streamer.h"
|
||||
#include "base/unixtime.h"
|
||||
#include "boxes/peers/peer_short_info_box.h"
|
||||
#include "core/application.h"
|
||||
@@ -323,7 +324,9 @@ void ValidatePhotoId(
|
||||
bool ProcessCurrent(
|
||||
not_null<PeerData*> peer,
|
||||
not_null<UserpicState*> state) {
|
||||
- const auto userpicPhotoId = peer->userpicPhotoId();
|
||||
+ const auto userpicPhotoId = Arcanegram::Streamer::ShouldAnonymize(peer)
|
||||
+ ? PhotoId{}
|
||||
+ : peer->userpicPhotoId();
|
||||
const auto userpicPhoto = (userpicPhotoId
|
||||
&& (userpicPhotoId != PeerData::kUnknownPhotoId)
|
||||
&& (state->userpicPhotoId != userpicPhotoId))
|
||||
--
|
||||
2.52.0.windows.1
|
||||
|
||||
70
patches/feature/streamer-mode-style.patch
Normal file
70
patches/feature/streamer-mode-style.patch
Normal file
|
|
@ -0,0 +1,70 @@
|
|||
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
|
||||
From: devilreef <devilreef@femboy.page>
|
||||
Date: Fri, 1 May 2026 16:03:10 +0600
|
||||
Subject: [PATCH] streamer mode: strip name color and decoration
|
||||
|
||||
---
|
||||
Telegram/SourceFiles/data/data_peer.cpp | 16 ++++++++++++++++
|
||||
Telegram/SourceFiles/data/data_peer.h | 4 +---
|
||||
2 files changed, 17 insertions(+), 3 deletions(-)
|
||||
|
||||
diff --git a/Telegram/SourceFiles/data/data_peer.cpp b/Telegram/SourceFiles/data/data_peer.cpp
|
||||
index 0000000..0000000 100644
|
||||
--- a/Telegram/SourceFiles/data/data_peer.cpp
|
||||
+++ b/Telegram/SourceFiles/data/data_peer.cpp
|
||||
@@ -1444,7 +1444,17 @@ bool PeerData::clearColorIndex() {
|
||||
return true;
|
||||
}
|
||||
|
||||
+uint8 PeerData::colorIndex() const {
|
||||
+ if (Arcanegram::Streamer::ShouldAnonymize(this)) {
|
||||
+ return Arcanegram::Streamer::ForcedColorIndex(id);
|
||||
+ }
|
||||
+ return _colorIndex;
|
||||
+}
|
||||
+
|
||||
DocumentId PeerData::backgroundEmojiId() const {
|
||||
+ if (Arcanegram::Streamer::ShouldAnonymize(this)) {
|
||||
+ return DocumentId(0);
|
||||
+ }
|
||||
return _backgroundEmojiId;
|
||||
}
|
||||
|
||||
@@ -1505,6 +1515,9 @@ bool PeerData::clearColorProfileIndex() {
|
||||
}
|
||||
|
||||
DocumentId PeerData::profileBackgroundEmojiId() const {
|
||||
+ if (Arcanegram::Streamer::ShouldAnonymize(this)) {
|
||||
+ return DocumentId(0);
|
||||
+ }
|
||||
return _profileBackgroundEmojiId;
|
||||
}
|
||||
|
||||
@@ -1530,6 +1543,9 @@ void PeerData::setEmojiStatus(EmojiStatusId emojiStatusId, TimeId until) {
|
||||
}
|
||||
|
||||
EmojiStatusId PeerData::emojiStatusId() const {
|
||||
+ if (Arcanegram::Streamer::ShouldAnonymize(this)) {
|
||||
+ return EmojiStatusId();
|
||||
+ }
|
||||
return _emojiStatusId;
|
||||
}
|
||||
|
||||
diff --git a/Telegram/SourceFiles/data/data_peer.h b/Telegram/SourceFiles/data/data_peer.h
|
||||
index 0000000..0000000 100644
|
||||
--- a/Telegram/SourceFiles/data/data_peer.h
|
||||
+++ b/Telegram/SourceFiles/data/data_peer.h
|
||||
@@ -215,9 +215,7 @@ public:
|
||||
[[nodiscard]] Main::Session &session() const;
|
||||
[[nodiscard]] Main::Account &account() const;
|
||||
|
||||
- [[nodiscard]] uint8 colorIndex() const {
|
||||
- return _colorIndex;
|
||||
- }
|
||||
+ [[nodiscard]] uint8 colorIndex() const;
|
||||
[[nodiscard]] auto colorCollectible() const
|
||||
-> const std::shared_ptr<Ui::ColorCollectible> & {
|
||||
return _colorCollectible;
|
||||
--
|
||||
2.52.0.windows.1
|
||||
|
||||
87
patches/feature/streamer-mode-typing.patch
Normal file
87
patches/feature/streamer-mode-typing.patch
Normal file
|
|
@ -0,0 +1,87 @@
|
|||
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
|
||||
From: devilreef <devilreef@femboy.page>
|
||||
Date: Fri, 1 May 2026 15:50:04 +0600
|
||||
Subject: [PATCH] streamer mode: pseudonym in typing indicator
|
||||
|
||||
---
|
||||
.../history/view/history_view_send_action.cpp | 22 +++++++++++++------
|
||||
1 file changed, 15 insertions(+), 7 deletions(-)
|
||||
|
||||
diff --git a/Telegram/SourceFiles/history/view/history_view_send_action.cpp b/Telegram/SourceFiles/history/view/history_view_send_action.cpp
|
||||
index 0000000..0000000 100644
|
||||
--- a/Telegram/SourceFiles/history/view/history_view_send_action.cpp
|
||||
+++ b/Telegram/SourceFiles/history/view/history_view_send_action.cpp
|
||||
@@ -7,6 +7,7 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
|
||||
*/
|
||||
#include "history/view/history_view_send_action.h"
|
||||
|
||||
+#include "arcanegram/features/streamer/ag_streamer.h"
|
||||
#include "data/data_user.h"
|
||||
#include "data/data_send_action.h"
|
||||
#include "data/data_forum_topic.h"
|
||||
@@ -38,6 +39,13 @@ constexpr auto kStatusShowClientsideChooseSticker = 6 * crl::time(1000);
|
||||
constexpr auto kStatusShowClientsidePlayGame = 10 * crl::time(1000);
|
||||
constexpr auto kStatusShowClientsideSpeaking = 6 * crl::time(1000);
|
||||
|
||||
+[[nodiscard]] QString DisplayFirstName(not_null<UserData*> user) {
|
||||
+ if (Arcanegram::Streamer::ShouldAnonymize(user)) {
|
||||
+ return Arcanegram::Streamer::GeneratedShortName(user->id);
|
||||
+ }
|
||||
+ return user->firstName;
|
||||
+}
|
||||
+
|
||||
} // namespace
|
||||
|
||||
SendActionPainter::SendActionPainter(
|
||||
@@ -243,16 +251,16 @@ bool SendActionPainter::updateNeedsAnimating(crl::time now, bool force) {
|
||||
newTypingString = tr::lng_users_typing(
|
||||
tr::now,
|
||||
lt_user,
|
||||
- begin(_typing)->first->firstName,
|
||||
+ DisplayFirstName(begin(_typing)->first),
|
||||
lt_second_user,
|
||||
- (end(_typing) - 1)->first->firstName);
|
||||
+ DisplayFirstName((end(_typing) - 1)->first));
|
||||
} else if (typingCount) {
|
||||
newTypingString = _history->peer->isUser()
|
||||
? tr::lng_typing(tr::now)
|
||||
: tr::lng_user_typing(
|
||||
tr::now,
|
||||
lt_user,
|
||||
- begin(_typing)->first->firstName);
|
||||
+ DisplayFirstName(begin(_typing)->first));
|
||||
} else if (!_sendActions.empty()) {
|
||||
// Handles all actions except game playing.
|
||||
using Type = Api::SendProgressType;
|
||||
@@ -299,7 +307,7 @@ bool SendActionPainter::updateNeedsAnimating(crl::time now, bool force) {
|
||||
const auto isNamed = !_history->peer->isUser();
|
||||
newTypingString = sendActionString(
|
||||
action.type,
|
||||
- isNamed ? user->firstName : QString());
|
||||
+ isNamed ? DisplayFirstName(user) : QString());
|
||||
if (!newTypingString.isEmpty()) {
|
||||
_sendActionAnimation.start(action.type);
|
||||
|
||||
@@ -345,16 +353,16 @@ bool SendActionPainter::updateNeedsAnimating(crl::time now, bool force) {
|
||||
newTypingString = tr::lng_users_playing_game(
|
||||
tr::now,
|
||||
lt_user,
|
||||
- begin(_sendActions)->first->firstName,
|
||||
+ DisplayFirstName(begin(_sendActions)->first),
|
||||
lt_second_user,
|
||||
- (end(_sendActions) - 1)->first->firstName);
|
||||
+ DisplayFirstName((end(_sendActions) - 1)->first));
|
||||
} else {
|
||||
newTypingString = _history->peer->isUser()
|
||||
? tr::lng_playing_game(tr::now)
|
||||
: tr::lng_user_playing_game(
|
||||
tr::now,
|
||||
lt_user,
|
||||
- begin(_sendActions)->first->firstName);
|
||||
+ DisplayFirstName(begin(_sendActions)->first));
|
||||
}
|
||||
_sendActionAnimation.start(Type::PlayGame);
|
||||
}
|
||||
--
|
||||
2.52.0.windows.1
|
||||
|
||||
|
|
@ -32,3 +32,10 @@
|
|||
"ag_sync_status_offline" = "Offline";
|
||||
"ag_sync_status_offline_pending" = "Offline · {n} pending";
|
||||
"ag_sync_status_conflict" = "Resolving conflict…";
|
||||
"ag_streamer_title" = "Streamer Mode";
|
||||
"ag_streamer_subtitle" = "Hide names, avatars and identifiers when screen-sharing.";
|
||||
"ag_streamer_enabled" = "Anonymize other users";
|
||||
"ag_streamer_enabled_about" = "Replaces every other user's name with a generated pseudonym, removes their avatar, color and badges, and hides phone, username, ID, bio, birthday and last-seen.";
|
||||
"ag_streamer_anonymize_bots" = "Anonymize bots";
|
||||
"ag_streamer_anonymize_bots_about" = "Bots are exposed by default since they are usually intentional. Enable to also pseudonymize them.";
|
||||
"ag_streamer_preview" = "Sample: {name}";
|
||||
|
|
|
|||
16
series
16
series
|
|
@ -23,4 +23,20 @@ feature/peer-id-bot-api-format.patch
|
|||
feature/fast-messages-shortcuts.patch
|
||||
feature/fast-messages-hook.patch
|
||||
misc/app-icon.patch
|
||||
feature/streamer-mode-name.patch
|
||||
feature/streamer-mode-typing.patch
|
||||
feature/streamer-mode-reply-shorten.patch
|
||||
feature/streamer-mode-avatar.patch
|
||||
feature/streamer-mode-call-avatar.patch
|
||||
feature/streamer-mode-short-info-box.patch
|
||||
feature/streamer-mode-style.patch
|
||||
feature/streamer-mode-badge.patch
|
||||
feature/streamer-mode-profile-identity.patch
|
||||
feature/streamer-mode-profile-actions.patch
|
||||
feature/streamer-mode-autocomplete.patch
|
||||
feature/streamer-mode-search.patch
|
||||
feature/streamer-mode-forum-topic.patch
|
||||
feature/streamer-mode-rank.patch
|
||||
feature/streamer-mode-seen-avatars.patch
|
||||
feature/streamer-mode-rating.patch
|
||||
misc/branding.patch
|
||||
|
|
|
|||
|
|
@ -56,6 +56,9 @@ PRIVATE
|
|||
sync/ag_sync_keys.cpp
|
||||
sync/ag_sync_engine.h
|
||||
sync/ag_sync_engine.cpp
|
||||
features/streamer/ag_streamer.cpp
|
||||
features/streamer/ag_streamer.h
|
||||
features/streamer/streamer_names.h
|
||||
)
|
||||
|
||||
target_include_directories(arcanegram PUBLIC ${CMAKE_CURRENT_SOURCE_DIR}/..)
|
||||
|
|
|
|||
|
|
@ -57,6 +57,13 @@ inline auto Disabled = BoolItem("ag_chat_wallpaper_disabled", false);
|
|||
|
||||
} // namespace ChatWallpaper
|
||||
|
||||
namespace StreamerMode {
|
||||
|
||||
inline auto Enabled = BoolItem("ag_streamer_enabled", false);
|
||||
inline auto AnonymizeBots = BoolItem("ag_streamer_anonymize_bots", false);
|
||||
|
||||
} // namespace StreamerMode
|
||||
|
||||
namespace Sync {
|
||||
|
||||
inline auto Enabled = BoolItem("ag_sync_enabled", false);
|
||||
|
|
|
|||
|
|
@ -5,6 +5,7 @@
|
|||
#include "arcanegram/features/ag_hidden_users.h"
|
||||
#include "arcanegram/features/ag_chat_wallpaper.h"
|
||||
#include "arcanegram/features/ag_fast_messages.h"
|
||||
#include "arcanegram/features/streamer/ag_streamer.h"
|
||||
#include "arcanegram/sync/ag_sync_engine.h"
|
||||
|
||||
namespace Arcanegram::Hooks {
|
||||
|
|
@ -16,6 +17,7 @@ void init() {
|
|||
Arcanegram::ChatWallpaper::Init();
|
||||
Arcanegram::Sync::Init();
|
||||
Arcanegram::FastMessages::Init();
|
||||
Arcanegram::Streamer::Init();
|
||||
}
|
||||
|
||||
} // namespace Arcanegram::Hooks
|
||||
|
|
|
|||
|
|
@ -3,6 +3,8 @@
|
|||
#include "core/application.h"
|
||||
#include "data/data_channel.h"
|
||||
#include "data/data_chat.h"
|
||||
#include "data/data_forum.h"
|
||||
#include "data/data_forum_topic.h"
|
||||
#include "data/data_peer.h"
|
||||
#include "data/data_session.h"
|
||||
#include "data/data_user.h"
|
||||
|
|
@ -14,7 +16,6 @@
|
|||
#include "main/main_session.h"
|
||||
|
||||
namespace Arcanegram {
|
||||
namespace {
|
||||
|
||||
void ForEachLoadedHistory(Fn<void(not_null<History*>)> action) {
|
||||
for (const auto &entry : Core::App().domain().accounts()) {
|
||||
|
|
@ -40,7 +41,32 @@ void ForEachLoadedHistory(Fn<void(not_null<History*>)> action) {
|
|||
}
|
||||
}
|
||||
|
||||
} // namespace
|
||||
void ForEachLoadedTopic(Fn<void(not_null<Data::ForumTopic*>)> action) {
|
||||
for (const auto &entry : Core::App().domain().accounts()) {
|
||||
const auto session = entry.account->maybeSession();
|
||||
if (!session) {
|
||||
continue;
|
||||
}
|
||||
auto &owner = session->data();
|
||||
owner.enumerateBroadcasts([&](not_null<ChannelData*> p) {
|
||||
if (const auto forum = p->forum()) {
|
||||
forum->enumerateTopics([&](not_null<Data::ForumTopic*> t) {
|
||||
action(t);
|
||||
});
|
||||
}
|
||||
});
|
||||
owner.enumerateGroups([&](not_null<PeerData*> p) {
|
||||
if (const auto channel = p->asChannel()) {
|
||||
if (const auto forum = channel->forum()) {
|
||||
forum->enumerateTopics(
|
||||
[&](not_null<Data::ForumTopic*> t) {
|
||||
action(t);
|
||||
});
|
||||
}
|
||||
}
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
void ForEachLoadedItem(Fn<void(not_null<HistoryItem*>)> action) {
|
||||
ForEachLoadedHistory([&](not_null<History*> h) {
|
||||
|
|
@ -66,6 +92,25 @@ void ForEachLoadedHistoryFor(
|
|||
}
|
||||
}
|
||||
|
||||
void ForEachLoadedPeer(Fn<void(not_null<PeerData*>)> action) {
|
||||
for (const auto &entry : Core::App().domain().accounts()) {
|
||||
const auto session = entry.account->maybeSession();
|
||||
if (!session) {
|
||||
continue;
|
||||
}
|
||||
auto &owner = session->data();
|
||||
owner.enumerateUsers([&](not_null<UserData*> p) {
|
||||
action(p);
|
||||
});
|
||||
owner.enumerateGroups([&](not_null<PeerData*> p) {
|
||||
action(p);
|
||||
});
|
||||
owner.enumerateBroadcasts([&](not_null<ChannelData*> p) {
|
||||
action(p);
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
void RefreshAllItems() {
|
||||
ForEachLoadedHistory([](not_null<History*> h) {
|
||||
auto &owner = h->owner();
|
||||
|
|
|
|||
|
|
@ -4,6 +4,11 @@
|
|||
|
||||
class History;
|
||||
class HistoryItem;
|
||||
class PeerData;
|
||||
|
||||
namespace Data {
|
||||
class ForumTopic;
|
||||
} // namespace Data
|
||||
|
||||
namespace Arcanegram {
|
||||
|
||||
|
|
@ -11,6 +16,12 @@ void ForEachLoadedItem(Fn<void(not_null<HistoryItem*>)> action);
|
|||
|
||||
void ForEachLoadedHistoryFor(PeerId id, Fn<void(not_null<History*>)> action);
|
||||
|
||||
void ForEachLoadedPeer(Fn<void(not_null<PeerData*>)> action);
|
||||
|
||||
void ForEachLoadedTopic(Fn<void(not_null<Data::ForumTopic*>)> action);
|
||||
|
||||
void ForEachLoadedHistory(Fn<void(not_null<History*>)> action);
|
||||
|
||||
void RefreshAllItems();
|
||||
|
||||
} // namespace Arcanegram
|
||||
|
|
|
|||
6
src/cpp/arcanegram/features/streamer/NOTICE.txt
Normal file
6
src/cpp/arcanegram/features/streamer/NOTICE.txt
Normal file
|
|
@ -0,0 +1,6 @@
|
|||
Adjective and surname lists vendored from the Moby project
|
||||
(github.com/moby/moby), file pkg/namesgenerator/names-generator.go.
|
||||
|
||||
Copyright 2013-2025 Docker, Inc. and contributors.
|
||||
Licensed under the Apache License, Version 2.0.
|
||||
http://www.apache.org/licenses/LICENSE-2.0
|
||||
238
src/cpp/arcanegram/features/streamer/ag_streamer.cpp
Normal file
238
src/cpp/arcanegram/features/streamer/ag_streamer.cpp
Normal file
|
|
@ -0,0 +1,238 @@
|
|||
#include "arcanegram/features/streamer/ag_streamer.h"
|
||||
|
||||
#include "arcanegram/features/streamer/streamer_names.h"
|
||||
#include "arcanegram/ag_config.h"
|
||||
#include "arcanegram/ag_refresh.h"
|
||||
#include "arcanegram/ui/ag_settings_main.h"
|
||||
#include "arcanegram/ui/ag_settings_widgets.h"
|
||||
#include "data/data_changes.h"
|
||||
#include "data/data_forum_topic.h"
|
||||
#include "data/data_peer.h"
|
||||
#include "data/data_user.h"
|
||||
#include "history/history.h"
|
||||
#include "history/history_item.h"
|
||||
#include "lang/lang_keys.h"
|
||||
#include "main/main_session.h"
|
||||
#include "settings/settings_builder.h"
|
||||
#include "settings/settings_common_session.h"
|
||||
#include "styles/style_menu_icons.h"
|
||||
#include "styles/style_settings.h"
|
||||
#include "ui/vertical_list.h"
|
||||
#include "ui/widgets/labels.h"
|
||||
#include "ui/wrap/vertical_layout.h"
|
||||
#include "window/window_session_controller.h"
|
||||
|
||||
#include <QtCore/QRandomGenerator>
|
||||
|
||||
namespace Arcanegram::Streamer {
|
||||
namespace {
|
||||
|
||||
quint64 &Seed() {
|
||||
static quint64 value = 0;
|
||||
return value;
|
||||
}
|
||||
|
||||
rpl::event_stream<bool> &Stream() {
|
||||
static rpl::event_stream<bool> value;
|
||||
return value;
|
||||
}
|
||||
|
||||
rpl::lifetime &Lifetime() {
|
||||
static rpl::lifetime value;
|
||||
return value;
|
||||
}
|
||||
|
||||
QString Capitalize(std::string_view sv) {
|
||||
auto s = QString::fromUtf8(sv.data(), int(sv.size()));
|
||||
if (!s.isEmpty()) {
|
||||
s[0] = s[0].toUpper();
|
||||
}
|
||||
return s;
|
||||
}
|
||||
|
||||
void RefreshAll() {
|
||||
using Flag = Data::PeerUpdate::Flag;
|
||||
const auto flags = Flag::Name
|
||||
| Flag::Username
|
||||
| Flag::Usernames
|
||||
| Flag::Photo
|
||||
| Flag::About
|
||||
| Flag::Color
|
||||
| Flag::EmojiStatus;
|
||||
ForEachLoadedPeer([&](not_null<PeerData*> peer) {
|
||||
peer->invalidateEmptyUserpic();
|
||||
// bump _nameVersion so dialog row name cache rebuilds.
|
||||
peer->noteNameUpdated();
|
||||
peer->session().changes().peerUpdated(peer, flags);
|
||||
});
|
||||
ForEachLoadedTopic([&](not_null<Data::ForumTopic*> topic) {
|
||||
topic->invalidateTitleWithIcon();
|
||||
topic->session().changes().topicUpdated(
|
||||
topic,
|
||||
Data::TopicUpdate::Flag::Title);
|
||||
if (const auto last = topic->chatListMessage()) {
|
||||
last->invalidateChatListEntry();
|
||||
}
|
||||
topic->updateChatListEntry();
|
||||
});
|
||||
ForEachLoadedHistory([&](not_null<History*> h) {
|
||||
// drop sender prefix cache in dialog list message preview.
|
||||
if (const auto last = h->chatListMessage()) {
|
||||
last->invalidateChatListEntry();
|
||||
}
|
||||
h->updateChatListEntry();
|
||||
});
|
||||
RefreshAllItems();
|
||||
}
|
||||
|
||||
} // namespace
|
||||
|
||||
void Init() {
|
||||
Seed() = QRandomGenerator::global()->generate64();
|
||||
|
||||
Config::StreamerMode::Enabled.changes(
|
||||
) | rpl::on_next([](bool active) {
|
||||
Stream().fire_copy(active);
|
||||
RefreshAll();
|
||||
}, Lifetime());
|
||||
|
||||
Config::StreamerMode::AnonymizeBots.changes(
|
||||
) | rpl::on_next([](bool) {
|
||||
if (IsActive()) {
|
||||
RefreshAll();
|
||||
}
|
||||
}, Lifetime());
|
||||
}
|
||||
|
||||
bool IsActive() {
|
||||
return Config::StreamerMode::Enabled.value();
|
||||
}
|
||||
|
||||
bool ShouldAnonymize(not_null<const PeerData*> peer) {
|
||||
if (!IsActive()) {
|
||||
return false;
|
||||
}
|
||||
if (peer->isSelf()) {
|
||||
return false;
|
||||
}
|
||||
if (const auto user = peer->asUser()) {
|
||||
if (user->isBot() && !Config::StreamerMode::AnonymizeBots.value()) {
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
return peer->isChannel() || peer->isChat();
|
||||
}
|
||||
|
||||
QString GeneratedName(PeerId id) {
|
||||
const auto mix = Seed() ^ quint64(id.value);
|
||||
const auto a = mix * 0x9E3779B97F4A7C15ull;
|
||||
const auto b = (mix >> 17) * 0xBF58476D1CE4E5B9ull;
|
||||
const auto adj = kAdjectives[a % kAdjectives.size()];
|
||||
const auto sur = kSurnames[b % kSurnames.size()];
|
||||
return Capitalize(adj) + QChar(' ') + Capitalize(sur);
|
||||
}
|
||||
|
||||
QString GeneratedShortName(PeerId id) {
|
||||
const auto mix = Seed() ^ quint64(id.value);
|
||||
const auto a = mix * 0x9E3779B97F4A7C15ull;
|
||||
const auto b = (mix >> 17) * 0xBF58476D1CE4E5B9ull;
|
||||
return Capitalize(kAdjectives[(a ^ b) % kAdjectives.size()]);
|
||||
}
|
||||
|
||||
uint8 ForcedColorIndex(PeerId id) {
|
||||
const auto mix = Seed() ^ quint64(id.value);
|
||||
const auto a = mix * 0x9E3779B97F4A7C15ull;
|
||||
const auto b = (mix >> 17) * 0xBF58476D1CE4E5B9ull;
|
||||
// mod 7: standard non-premium palette has 7 hues; extended indices fall
|
||||
// back to standard for free accounts, so 0..6 is uniformly available.
|
||||
return uint8((a ^ b) % 7);
|
||||
}
|
||||
|
||||
rpl::producer<bool> Changes() {
|
||||
return Stream().events();
|
||||
}
|
||||
|
||||
namespace {
|
||||
|
||||
void BuildPage(::Settings::Builder::SectionBuilder &builder) {
|
||||
const auto container = builder.container();
|
||||
Ui::AddSubsectionTitle(container, tr::ag_streamer_title());
|
||||
|
||||
Arcanegram::Settings::AddBoolRow(
|
||||
builder,
|
||||
u"arcanegram/streamer/enabled"_q,
|
||||
tr::ag_streamer_enabled(),
|
||||
tr::ag_streamer_enabled_about(),
|
||||
Config::StreamerMode::Enabled);
|
||||
|
||||
Arcanegram::Settings::AddBoolRow(
|
||||
builder,
|
||||
u"arcanegram/streamer/anonymize_bots"_q,
|
||||
tr::ag_streamer_anonymize_bots(),
|
||||
tr::ag_streamer_anonymize_bots_about(),
|
||||
Config::StreamerMode::AnonymizeBots);
|
||||
|
||||
Ui::AddSkip(container);
|
||||
Ui::AddDivider(container);
|
||||
Ui::AddSkip(container);
|
||||
|
||||
container->add(
|
||||
object_ptr<Ui::FlatLabel>(
|
||||
container,
|
||||
tr::ag_streamer_preview(
|
||||
lt_name,
|
||||
rpl::single(GeneratedName(PeerId(1234567890ULL)))),
|
||||
st::boxDividerLabel),
|
||||
st::defaultBoxDividerLabelPadding);
|
||||
|
||||
Ui::AddDividerText(container, tr::ag_streamer_subtitle());
|
||||
}
|
||||
|
||||
class Page : public ::Settings::Section<Page> {
|
||||
public:
|
||||
Page(QWidget *parent, not_null<Window::SessionController*> controller);
|
||||
|
||||
[[nodiscard]] rpl::producer<QString> title() override {
|
||||
return tr::ag_streamer_title();
|
||||
}
|
||||
|
||||
private:
|
||||
void setupContent();
|
||||
};
|
||||
|
||||
const auto kPageMeta = ::Settings::Builder::BuildHelper({
|
||||
.id = Page::Id(),
|
||||
.parentId = Arcanegram::Settings::Id(),
|
||||
.title = &tr::ag_streamer_title,
|
||||
.icon = &st::menuIconStealthLocked,
|
||||
}, [](::Settings::Builder::SectionBuilder &builder) {
|
||||
BuildPage(builder);
|
||||
});
|
||||
|
||||
const ::Settings::SectionBuildMethod kPageSection = kPageMeta.build;
|
||||
|
||||
Page::Page(
|
||||
QWidget *parent,
|
||||
not_null<Window::SessionController*> controller)
|
||||
: Section(parent, controller) {
|
||||
setupContent();
|
||||
}
|
||||
|
||||
void Page::setupContent() {
|
||||
const auto content = Ui::CreateChild<Ui::VerticalLayout>(this);
|
||||
build(content, kPageSection);
|
||||
Ui::ResizeFitChild(this, content);
|
||||
}
|
||||
|
||||
} // namespace
|
||||
|
||||
void Setup(::Settings::Builder::SectionBuilder &builder) {
|
||||
builder.addSectionButton({
|
||||
.title = tr::ag_streamer_title(),
|
||||
.targetSection = Page::Id(),
|
||||
.icon = { &st::menuIconStealthLocked },
|
||||
});
|
||||
}
|
||||
|
||||
} // namespace Arcanegram::Streamer
|
||||
27
src/cpp/arcanegram/features/streamer/ag_streamer.h
Normal file
27
src/cpp/arcanegram/features/streamer/ag_streamer.h
Normal file
|
|
@ -0,0 +1,27 @@
|
|||
#pragma once
|
||||
|
||||
#include "base/basic_types.h"
|
||||
|
||||
#include <rpl/producer.h>
|
||||
|
||||
class PeerData;
|
||||
|
||||
namespace Settings::Builder { class SectionBuilder; }
|
||||
|
||||
namespace Arcanegram::Streamer {
|
||||
|
||||
void Init();
|
||||
|
||||
[[nodiscard]] bool IsActive();
|
||||
[[nodiscard]] bool ShouldAnonymize(not_null<const PeerData*> peer);
|
||||
|
||||
[[nodiscard]] QString GeneratedName(PeerId id);
|
||||
[[nodiscard]] QString GeneratedShortName(PeerId id);
|
||||
|
||||
[[nodiscard]] uint8 ForcedColorIndex(PeerId id);
|
||||
|
||||
[[nodiscard]] rpl::producer<bool> Changes();
|
||||
|
||||
void Setup(::Settings::Builder::SectionBuilder &builder);
|
||||
|
||||
} // namespace Arcanegram::Streamer
|
||||
76
src/cpp/arcanegram/features/streamer/streamer_names.h
Normal file
76
src/cpp/arcanegram/features/streamer/streamer_names.h
Normal file
|
|
@ -0,0 +1,76 @@
|
|||
// SPDX-License-Identifier: Apache-2.0
|
||||
// adjective + surname lists vendored from docker/moby pkg/namesgenerator.
|
||||
// original copyright: docker inc. and contributors.
|
||||
// see NOTICE.txt for license text.
|
||||
|
||||
#pragma once
|
||||
|
||||
#include <array>
|
||||
#include <string_view>
|
||||
|
||||
namespace Arcanegram::Streamer {
|
||||
|
||||
constexpr std::array<std::string_view, 108> kAdjectives = {{
|
||||
"admiring", "adoring", "affectionate", "agitated", "amazing", "angry",
|
||||
"awesome", "beautiful", "blissful", "bold", "boring", "brave", "busy",
|
||||
"charming", "clever", "compassionate", "competent", "condescending",
|
||||
"confident", "cool", "cranky", "crazy", "dazzling", "determined",
|
||||
"distracted", "dreamy", "eager", "ecstatic", "elastic", "elated",
|
||||
"elegant", "eloquent", "epic", "exciting", "fervent", "festive",
|
||||
"flamboyant", "focused", "friendly", "frosty", "funny", "gallant",
|
||||
"gifted", "goofy", "gracious", "great", "happy", "hardcore", "heuristic",
|
||||
"hopeful", "hungry", "infallible", "inspiring", "intelligent",
|
||||
"interesting", "jolly", "jovial", "keen", "kind", "laughing", "loving",
|
||||
"lucid", "magical", "modest", "musing", "mystifying", "naughty",
|
||||
"nervous", "nice", "nifty", "nostalgic", "objective", "optimistic",
|
||||
"peaceful", "pedantic", "pensive", "practical", "priceless", "quirky",
|
||||
"quizzical", "recursing", "relaxed", "reverent", "romantic", "sad",
|
||||
"serene", "sharp", "silly", "sleepy", "stoic", "strange", "stupefied",
|
||||
"suspicious", "sweet", "tender", "thirsty", "trusting", "unruffled",
|
||||
"upbeat", "vibrant", "vigilant", "vigorous", "wizardly", "wonderful",
|
||||
"xenodochial", "youthful", "zealous", "zen",
|
||||
}};
|
||||
|
||||
constexpr std::array<std::string_view, 238> kSurnames = {{
|
||||
"agnesi", "albattani", "allen", "almeida", "antonelli", "archimedes",
|
||||
"ardinghelli", "aryabhata", "austin", "babbage", "banach", "banzai",
|
||||
"bardeen", "bartik", "bassi", "beaver", "bell", "benz", "bhabha",
|
||||
"bhaskara", "black", "blackburn", "blackwell", "bohr", "booth", "borg",
|
||||
"bose", "bouman", "boyd", "brahmagupta", "brattain", "brown", "buck",
|
||||
"burnell", "cannon", "carson", "cartwright", "carver", "cerf",
|
||||
"chandrasekhar", "chaplygin", "chatelet", "chatterjee", "chaum",
|
||||
"chebyshev", "clarke", "cohen", "colden", "cori", "cray", "curie",
|
||||
"curran", "darwin", "davinci", "dewdney", "dhawan", "diffie",
|
||||
"dijkstra", "dirac", "driscoll", "dubinsky", "easley", "edison",
|
||||
"einstein", "elbakyan", "elgamal", "elion", "ellis", "engelbart",
|
||||
"euclid", "euler", "faraday", "feistel", "fermat", "fermi",
|
||||
"feynman", "franklin", "gagarin", "galileo", "galois", "ganguly",
|
||||
"gates", "gauss", "germain", "goldberg", "goldstine", "goldwasser",
|
||||
"golick", "goodall", "gould", "greider", "grothendieck", "haibt",
|
||||
"hamilton", "haslett", "hawking", "hellman", "heisenberg", "hermann",
|
||||
"herschel", "hertz", "heyrovsky", "hodgkin", "hofstadter", "hoover",
|
||||
"hopper", "hugle", "hypatia", "ishizaka", "jackson", "jang",
|
||||
"jemison", "jennings", "jepsen", "johnson", "joliot", "jones",
|
||||
"kalam", "kapitsa", "kare", "keldysh", "keller", "kepler", "khayyam",
|
||||
"khorana", "kilby", "kirch", "knuth", "kowalevski", "lalande",
|
||||
"lamarr", "lamport", "leakey", "leavitt", "lederberg", "lehmann",
|
||||
"lewin", "lichterman", "liskov", "lovelace", "lumiere", "mahavira",
|
||||
"margulis", "matsumoto", "maxwell", "mayer", "mccarthy", "mcclintock",
|
||||
"mclaren", "mclean", "mcnulty", "mendel", "mendeleev", "meitner",
|
||||
"meninsky", "merkle", "mestorf", "mirzakhani", "moncada", "montalcini",
|
||||
"moore", "morse", "moser", "murdock", "napier", "nash", "neumann",
|
||||
"newton", "nightingale", "nobel", "noether", "northcutt", "noyce",
|
||||
"panini", "pare", "pascal", "pasteur", "payne", "perlman", "pike",
|
||||
"poincare", "poitras", "proskuriakova", "ptolemy", "raman",
|
||||
"ramanujan", "rhodes", "ride", "ritchie", "robinson", "roentgen",
|
||||
"rosalind", "rubin", "saha", "sammet", "sanderson", "satoshi",
|
||||
"shamir", "shannon", "shaw", "shirley", "shockley", "shtern",
|
||||
"sinoussi", "snyder", "solomon", "spence", "stonebraker", "sutherland",
|
||||
"swanson", "swartz", "swirles", "taussig", "tereshkova", "tesla",
|
||||
"tharp", "thompson", "torvalds", "tu", "turing", "varahamihira",
|
||||
"vaughan", "villani", "visvesvaraya", "volhard", "wescoff", "wilbur",
|
||||
"wiles", "williams", "williamson", "wilson", "wing", "wozniak",
|
||||
"wright", "wu", "yalow", "yonath", "zhukovsky",
|
||||
}};
|
||||
|
||||
} // namespace Arcanegram::Streamer
|
||||
|
|
@ -5,6 +5,7 @@
|
|||
#include "arcanegram/features/ag_forwarded_header.h"
|
||||
#include "arcanegram/features/ag_show_seconds.h"
|
||||
#include "arcanegram/features/ag_sync_feature.h"
|
||||
#include "arcanegram/features/streamer/ag_streamer.h"
|
||||
#include "arcanegram/ui/ag_hidden_users_settings.h"
|
||||
#include "lang/lang_keys.h"
|
||||
#include "settings/sections/settings_main.h"
|
||||
|
|
@ -82,6 +83,7 @@ void BuildContent(SectionBuilder &builder) {
|
|||
.icon = { &st::menuIconPalette },
|
||||
});
|
||||
Arcanegram::HiddenUsers::Setup(builder);
|
||||
Arcanegram::Streamer::Setup(builder);
|
||||
Arcanegram::FastMessages::Setup(builder);
|
||||
Arcanegram::CloudSync::Setup(builder);
|
||||
}
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue