diff --git a/Telegram/Resources/langs/lang.strings b/Telegram/Resources/langs/lang.strings
index d5abcfbad..e30c963fb 100644
--- a/Telegram/Resources/langs/lang.strings
+++ b/Telegram/Resources/langs/lang.strings
@@ -3486,6 +3486,8 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
 "lng_gift_transfer_button_for" = "Transfer for {price}";
 "lng_gift_transfer_wear" = "Wear";
 "lng_gift_transfer_take_off" = "Take Off";
+"lng_gift_menu_show" = "Show";
+"lng_gift_menu_hide" = "Hide";
 "lng_gift_wear_title" = "Wear {name}";
 "lng_gift_wear_about" = "and get these benefits:";
 "lng_gift_wear_badge_title" = "Radiant Badge";
diff --git a/Telegram/SourceFiles/info/channel_statistics/boosts/giveaway/giveaway.style b/Telegram/SourceFiles/info/channel_statistics/boosts/giveaway/giveaway.style
index 3bf228c9b..afcd0a34e 100644
--- a/Telegram/SourceFiles/info/channel_statistics/boosts/giveaway/giveaway.style
+++ b/Telegram/SourceFiles/info/channel_statistics/boosts/giveaway/giveaway.style
@@ -221,6 +221,8 @@ darkGiftShare: icon {{ "menu/share", groupCallMembersFg }};
 darkGiftTransfer: icon {{ "chat/input_replace", groupCallMembersFg }};
 darkGiftNftWear: icon {{ "menu/nft_wear", groupCallMembersFg }};
 darkGiftNftTakeOff: icon {{ "menu/nft_takeoff", groupCallMembersFg }};
+darkGiftHide: icon {{ "menu/stealth", groupCallMembersFg }};
+darkGiftShow: icon {{ "menu/show_in_chat", groupCallMembersFg }};
 darkGiftPalette: TextPalette(defaultTextPalette) {
 	linkFg: mediaviewTextLinkFg;
 	monoFg: groupCallMembersFg;
diff --git a/Telegram/SourceFiles/info/peer_gifts/info_peer_gifts_common.cpp b/Telegram/SourceFiles/info/peer_gifts/info_peer_gifts_common.cpp
index dfd323656..c48cb6f45 100644
--- a/Telegram/SourceFiles/info/peer_gifts/info_peer_gifts_common.cpp
+++ b/Telegram/SourceFiles/info/peer_gifts/info_peer_gifts_common.cpp
@@ -250,6 +250,12 @@ void GiftButton::resizeEvent(QResizeEvent *e) {
 	}
 }
 
+void GiftButton::contextMenuEvent(QContextMenuEvent *e) {
+	_contextMenuRequests.fire_copy((e->reason() == QContextMenuEvent::Mouse)
+		? e->globalPos()
+		: QCursor::pos());
+}
+
 void GiftButton::cacheUniqueBackground(
 		not_null<Data::UniqueGift*> unique,
 		int width,
diff --git a/Telegram/SourceFiles/info/peer_gifts/info_peer_gifts_common.h b/Telegram/SourceFiles/info/peer_gifts/info_peer_gifts_common.h
index d7d829dab..02c4223b8 100644
--- a/Telegram/SourceFiles/info/peer_gifts/info_peer_gifts_common.h
+++ b/Telegram/SourceFiles/info/peer_gifts/info_peer_gifts_common.h
@@ -126,9 +126,14 @@ public:
 	void setDescriptor(const GiftDescriptor &descriptor, Mode mode);
 	void setGeometry(QRect inner, QMargins extend);
 
+	[[nodiscard]] rpl::producer<QPoint> contextMenuRequests() const {
+		return _contextMenuRequests.events();
+	}
+
 private:
 	void paintEvent(QPaintEvent *e) override;
 	void resizeEvent(QResizeEvent *e) override;
+	void contextMenuEvent(QContextMenuEvent *e) override;
 
 	void cacheUniqueBackground(
 		not_null<Data::UniqueGift*> unique,
@@ -141,6 +146,7 @@ private:
 	void unsubscribe();
 
 	const not_null<GiftButtonDelegate*> _delegate;
+	rpl::event_stream<QPoint> _contextMenuRequests;
 	QImage _hiddenBgCache;
 	GiftDescriptor _descriptor;
 	Ui::Text::String _text;
diff --git a/Telegram/SourceFiles/info/peer_gifts/info_peer_gifts_widget.cpp b/Telegram/SourceFiles/info/peer_gifts/info_peer_gifts_widget.cpp
index 898125cf3..63f48a7a7 100644
--- a/Telegram/SourceFiles/info/peer_gifts/info_peer_gifts_widget.cpp
+++ b/Telegram/SourceFiles/info/peer_gifts/info_peer_gifts_widget.cpp
@@ -10,6 +10,7 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
 #include "api/api_premium.h"
 #include "apiwrap.h"
 #include "data/data_channel.h"
+#include "data/data_credits.h"
 #include "data/data_session.h"
 #include "data/data_user.h"
 #include "info/peer_gifts/info_peer_gifts_common.h"
@@ -20,6 +21,7 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
 #include "ui/widgets/box_content_divider.h"
 #include "ui/widgets/checkbox.h"
 #include "ui/widgets/labels.h"
+#include "ui/widgets/popup_menu.h"
 #include "ui/widgets/scroll_area.h"
 #include "ui/wrap/slide_wrap.h"
 #include "ui/ui_utility.h"
@@ -99,6 +101,7 @@ private:
 	void refreshButtons();
 	void validateButtons();
 	void showGift(int index);
+	void showMenuFor(not_null<GiftButton*> button, QPoint point);
 	void refreshAbout();
 
 	int resizeGetHeight(int width) override;
@@ -131,6 +134,8 @@ private:
 	int _visibleFrom = 0;
 	int _visibleTill = 0;
 
+	base::unique_qptr<Ui::PopupMenu> _menu;
+
 };
 
 InnerWidget::InnerWidget(
@@ -355,7 +360,12 @@ void InnerWidget::validateButtons() {
 				views.push_back(base::take(*unused));
 			} else {
 				auto button = std::make_unique<GiftButton>(this, &_delegate);
-				button->show();
+				const auto raw = button.get();
+				raw->contextMenuRequests(
+				) | rpl::start_with_next([=](QPoint point) {
+					showMenuFor(raw, point);
+				}, raw->lifetime());
+				raw->show();
 				views.push_back({ .button = std::move(button) });
 			}
 		}
@@ -386,6 +396,37 @@ void InnerWidget::validateButtons() {
 	std::swap(_views, views);
 }
 
+void InnerWidget::showMenuFor(not_null<GiftButton*> button, QPoint point) {
+	if (_menu) {
+		return;
+	}
+	const auto index = [&] {
+		for (const auto &view : _views) {
+			if (view.button.get() == button) {
+				return view.index;
+			}
+		}
+		return -1;
+	}();
+	if (index < 0) {
+		return;
+	}
+
+	const auto entry = ::Settings::SavedStarGiftEntry(
+		_peer,
+		_entries[index].gift);
+	_menu = base::make_unique_q<Ui::PopupMenu>(this, st::popupMenuWithIcons);
+	::Settings::FillSavedStarGiftMenu(
+		_controller->uiShow(),
+		_menu.get(),
+		entry,
+		::Settings::SavedStarGiftMenuType::List);
+	if (_menu->empty()) {
+		return;
+	}
+	_menu->popup(point);
+}
+
 void InnerWidget::showGift(int index) {
 	Expects(index >= 0 && index < _entries.size());
 
diff --git a/Telegram/SourceFiles/settings/settings_credits_graphics.cpp b/Telegram/SourceFiles/settings/settings_credits_graphics.cpp
index d42f40ee8..d680e7ef4 100644
--- a/Telegram/SourceFiles/settings/settings_credits_graphics.cpp
+++ b/Telegram/SourceFiles/settings/settings_credits_graphics.cpp
@@ -189,7 +189,7 @@ void ToggleStarGiftSaved(
 		std::shared_ptr<ChatHelpers::Show> show,
 		Data::SavedStarGiftId savedId,
 		bool save,
-		Fn<void(bool)> done) {
+		Fn<void(bool)> done = nullptr) {
 	using Flag = MTPpayments_SaveStarGift::Flag;
 	const auto api = &show->session().api();
 	const auto channelGift = savedId.chat();
@@ -197,7 +197,15 @@ void ToggleStarGiftSaved(
 		MTP_flags(save ? Flag(0) : Flag::f_unsave),
 		Api::InputSavedStarGiftId(savedId)
 	)).done([=] {
-		done(true);
+		using GiftAction = Data::GiftUpdate::Action;
+		show->session().data().notifyGiftUpdate({
+			.id = savedId,
+			.action = (save ? GiftAction::Save : GiftAction::Unsave),
+		});
+
+		if (const auto onstack = done) {
+			onstack(true);
+		}
 		show->showToast((save
 			? (channelGift
 				? tr::lng_gift_display_done_channel
@@ -206,7 +214,9 @@ void ToggleStarGiftSaved(
 				? tr::lng_gift_display_done_hide_channel
 				: tr::lng_gift_display_done_hide))(tr::now));
 	}).fail([=](const MTP::Error &error) {
-		done(false);
+		if (const auto onstack = done) {
+			onstack(false);
+		}
 		show->showToast(error.type());
 	}).send();
 }
@@ -849,26 +859,48 @@ void FillUniqueGiftMenu(
 		std::shared_ptr<ChatHelpers::Show> show,
 		not_null<Ui::PopupMenu*> menu,
 		const Data::CreditsHistoryEntry &e,
+		SavedStarGiftMenuType type,
 		CreditsEntryBoxStyleOverrides st) {
-	Expects(e.uniqueGift != nullptr);
-
 	const auto unique = e.uniqueGift;
-	const auto local = u"nft/"_q + unique->slug;
-	const auto url = show->session().createInternalLinkFull(local);
-	menu->addAction(tr::lng_context_copy_link(tr::now), [=] {
-		TextUtilities::SetClipboardText({ url });
-		show->showToast(tr::lng_channel_public_link_copied(tr::now));
-	}, st.link ? st.link : &st::menuIconLink);
+	if (unique) {
+		const auto local = u"nft/"_q + unique->slug;
+		const auto url = show->session().createInternalLinkFull(local);
+		menu->addAction(tr::lng_context_copy_link(tr::now), [=] {
+			TextUtilities::SetClipboardText({ url });
+			show->showToast(tr::lng_channel_public_link_copied(tr::now));
+		}, st.link ? st.link : &st::menuIconLink);
 
-	const auto shareBoxSt = st.shareBox;
-	menu->addAction(tr::lng_chat_link_share(tr::now), [=] {
-		FastShareLink(
-			show,
-			url,
-			shareBoxSt ? *shareBoxSt : ShareBoxStyleOverrides());
-	}, st.share ? st.share : &st::menuIconShare);
+		const auto shareBoxSt = st.shareBox;
+		menu->addAction(tr::lng_chat_link_share(tr::now), [=] {
+			FastShareLink(
+				show,
+				url,
+				shareBoxSt ? *shareBoxSt : ShareBoxStyleOverrides());
+		}, st.share ? st.share : &st::menuIconShare);
+	}
 
 	const auto savedId = EntryToSavedStarGiftId(&show->session(), e);
+	const auto giftChannel = savedId.chat();
+	const auto canToggleVisibility = savedId
+		&& e.id.isEmpty()
+		&& (e.in || (giftChannel && giftChannel->canManageGifts()))
+		&& !e.giftTransferred
+		&& !e.giftRefunded;
+	if (canToggleVisibility && type == SavedStarGiftMenuType::List) {
+		if (e.savedToProfile) {
+			menu->addAction(tr::lng_gift_menu_hide(tr::now), [=] {
+				ToggleStarGiftSaved(show, savedId, false);
+			}, st.hide ? st.hide : &st::menuIconStealth);
+		} else {
+			menu->addAction(tr::lng_gift_menu_show(tr::now), [=] {
+				ToggleStarGiftSaved(show, savedId, true);
+			}, st.show ? st.show : &st::menuIconShowInChat);
+		}
+	}
+
+	if (!unique) {
+		return;
+	}
 	const auto transfer = savedId
 		&& (savedId.isUser() ? e.in : savedId.chat()->canTransferGifts())
 		&& (unique->starsForTransfer >= 0);
@@ -924,6 +956,8 @@ CreditsEntryBoxStyleOverrides DarkCreditsEntryBoxStyle() {
 		.transfer = &st::darkGiftTransfer,
 		.wear = &st::darkGiftNftWear,
 		.takeoff = &st::darkGiftNftTakeOff,
+		.show = &st::darkGiftShow,
+		.hide = &st::darkGiftHide,
 		.shareBox = std::make_shared<ShareBoxStyleOverrides>(
 			DarkShareBoxStyle()),
 		.giftWearBox = std::make_shared<GiftWearBoxStyleOverride>(
@@ -1029,7 +1063,8 @@ void GenericCreditsEntryBox(
 		AddSkip(content, st::defaultVerticalListSkip * 2);
 
 		AddUniqueCloseButton(box, st, [=](not_null<Ui::PopupMenu*> menu) {
-			FillUniqueGiftMenu(show, menu, e, st);
+			const auto type = SavedStarGiftMenuType::View;
+			FillUniqueGiftMenu(show, menu, e, type, st);
 		});
 	} else if (const auto callback = Ui::PaintPreviewCallback(session, e)) {
 		const auto thumb = content->add(object_ptr<Ui::CenterWrap<>>(
@@ -1464,21 +1499,12 @@ void GenericCreditsEntryBox(
 		const auto showSection = !e.fromGiftsList;
 		const auto savedId = EntryToSavedStarGiftId(&show->session(), e);
 		const auto done = [=](bool ok) {
-			if (ok) {
-				using GiftAction = Data::GiftUpdate::Action;
-				show->session().data().notifyGiftUpdate({
-					.id = savedId,
-					.action = (save
-						? GiftAction::Save
-						: GiftAction::Unsave),
-				});
-				if (showSection) {
-					if (const auto window = show->resolveWindow()) {
-						window->showSection(
-							std::make_shared<Info::Memento>(
-								window->session().user(),
-								Info::Section::Type::PeerGifts));
-					}
+			if (ok && showSection) {
+				if (const auto window = show->resolveWindow()) {
+					window->showSection(
+						std::make_shared<Info::Memento>(
+							window->session().user(),
+							Info::Section::Type::PeerGifts));
 				}
 			}
 			if (const auto strong = weak.data()) {
@@ -1899,46 +1925,61 @@ void GlobalStarGiftBox(
 		st);
 }
 
+Data::CreditsHistoryEntry SavedStarGiftEntry(
+		not_null<PeerData*> owner,
+		const Data::SavedStarGift &data) {
+	const auto chatGiftPeer = data.manageId.chat();
+	return {
+		.description = data.message,
+		.date = base::unixtime::parse(data.date),
+		.credits = StarsAmount(data.info.stars),
+		.bareMsgId = uint64(data.manageId.userMessageId().bare),
+		.barePeerId = data.fromId.value,
+		.bareGiftStickerId = data.info.document->id,
+		.bareGiftOwnerId = owner->id.value,
+		.bareActorId = data.fromId.value,
+		.bareEntryOwnerId = chatGiftPeer ? chatGiftPeer->id.value : 0,
+		.giftChannelSavedId = data.manageId.chatSavedId(),
+		.stargiftId = data.info.id,
+		.uniqueGift = data.info.unique,
+		.peerType = Data::CreditsHistoryEntry::PeerType::Peer,
+		.limitedCount = data.info.limitedCount,
+		.limitedLeft = data.info.limitedLeft,
+		.starsConverted = int(data.starsConverted),
+		.starsToUpgrade = int(data.info.starsToUpgrade),
+		.starsUpgradedBySender = int(data.starsUpgradedBySender),
+		.converted = false,
+		.anonymous = data.anonymous,
+		.stargift = true,
+		.savedToProfile = !data.hidden,
+		.fromGiftsList = true,
+		.canUpgradeGift = data.upgradable,
+		.in = data.mine,
+		.gift = true,
+	};
+}
+
 void SavedStarGiftBox(
 		not_null<Ui::GenericBox*> box,
 		not_null<Window::SessionController*> controller,
 		not_null<PeerData*> owner,
 		const Data::SavedStarGift &data) {
-	const auto chatGiftPeer = data.manageId.chat();
 	Settings::ReceiptCreditsBox(
 		box,
 		controller,
-		Data::CreditsHistoryEntry{
-			.description = data.message,
-			.date = base::unixtime::parse(data.date),
-			.credits = StarsAmount(data.info.stars),
-			.bareMsgId = uint64(data.manageId.userMessageId().bare),
-			.barePeerId = data.fromId.value,
-			.bareGiftStickerId = data.info.document->id,
-			.bareGiftOwnerId = owner->id.value,
-			.bareActorId = data.fromId.value,
-			.bareEntryOwnerId = chatGiftPeer ? chatGiftPeer->id.value : 0,
-			.giftChannelSavedId = data.manageId.chatSavedId(),
-			.stargiftId = data.info.id,
-			.uniqueGift = data.info.unique,
-			.peerType = Data::CreditsHistoryEntry::PeerType::Peer,
-			.limitedCount = data.info.limitedCount,
-			.limitedLeft = data.info.limitedLeft,
-			.starsConverted = int(data.starsConverted),
-			.starsToUpgrade = int(data.info.starsToUpgrade),
-			.starsUpgradedBySender = int(data.starsUpgradedBySender),
-			.converted = false,
-			.anonymous = data.anonymous,
-			.stargift = true,
-			.savedToProfile = !data.hidden,
-			.fromGiftsList = true,
-			.canUpgradeGift = data.upgradable,
-			.in = data.mine,
-			.gift = true,
-		},
+		SavedStarGiftEntry(owner, data),
 		Data::SubscriptionEntry());
 }
 
+void FillSavedStarGiftMenu(
+		std::shared_ptr<ChatHelpers::Show> show,
+		not_null<Ui::PopupMenu*> menu,
+		const Data::CreditsHistoryEntry &e,
+		SavedStarGiftMenuType type,
+		CreditsEntryBoxStyleOverrides st) {
+	FillUniqueGiftMenu(show, menu, e, type, st);
+}
+
 void StarGiftViewBox(
 		not_null<Ui::GenericBox*> box,
 		not_null<Window::SessionController*> controller,
diff --git a/Telegram/SourceFiles/settings/settings_credits_graphics.h b/Telegram/SourceFiles/settings/settings_credits_graphics.h
index 59084cb36..0ea66f359 100644
--- a/Telegram/SourceFiles/settings/settings_credits_graphics.h
+++ b/Telegram/SourceFiles/settings/settings_credits_graphics.h
@@ -52,6 +52,7 @@ namespace Ui {
 class GenericBox;
 class RpWidget;
 class VerticalLayout;
+class PopupMenu;
 } // namespace Ui
 
 namespace Settings {
@@ -112,6 +113,8 @@ struct CreditsEntryBoxStyleOverrides {
 	const style::icon *transfer = nullptr;
 	const style::icon *wear = nullptr;
 	const style::icon *takeoff = nullptr;
+	const style::icon *show = nullptr;
+	const style::icon *hide = nullptr;
 	std::shared_ptr<ShareBoxStyleOverrides> shareBox;
 	std::shared_ptr<GiftWearBoxStyleOverride> giftWearBox;
 };
@@ -149,11 +152,26 @@ void GlobalStarGiftBox(
 	std::shared_ptr<ChatHelpers::Show> show,
 	const Data::StarGift &data,
 	CreditsEntryBoxStyleOverrides st = {});
+
+[[nodiscard]] Data::CreditsHistoryEntry SavedStarGiftEntry(
+	not_null<PeerData*> owner,
+	const Data::SavedStarGift &data);
 void SavedStarGiftBox(
 	not_null<Ui::GenericBox*> box,
 	not_null<Window::SessionController*> controller,
 	not_null<PeerData*> owner,
 	const Data::SavedStarGift &data);
+enum class SavedStarGiftMenuType {
+	List,
+	View,
+};
+void FillSavedStarGiftMenu(
+	std::shared_ptr<ChatHelpers::Show> show,
+	not_null<Ui::PopupMenu*> menu,
+	const Data::CreditsHistoryEntry &e,
+	SavedStarGiftMenuType type,
+	CreditsEntryBoxStyleOverrides st = {});
+
 void StarGiftViewBox(
 	not_null<Ui::GenericBox*> box,
 	not_null<Window::SessionController*> controller,
diff --git a/Telegram/SourceFiles/ui/menu_icons.style b/Telegram/SourceFiles/ui/menu_icons.style
index 504065677..f010afa62 100644
--- a/Telegram/SourceFiles/ui/menu_icons.style
+++ b/Telegram/SourceFiles/ui/menu_icons.style
@@ -23,6 +23,7 @@ menuIconStickers: icon {{ "menu/stickers", menuIconColor }};
 menuIconEmoji: icon {{ "menu/emoji", menuIconColor }};
 menuIconCancel: icon {{ "menu/cancel", menuIconColor }};
 menuIconShowInChat: icon {{ "menu/show_in_chat", menuIconColor }};
+menuIconStealth: icon {{ "menu/stealth", menuIconColor }};
 menuIconGif: icon {{ "menu/gif", menuIconColor }};
 menuIconShowInFolder: icon {{ "menu/show_in_folder", menuIconColor }};
 menuIconDownload: icon {{ "menu/download", menuIconColor }};