From ac65d7f44385cb70e689151f3ecfdfb1828e47f3 Mon Sep 17 00:00:00 2001 From: Isaac <> Date: Fri, 14 Nov 2025 20:50:02 +0800 Subject: [PATCH] Stories --- .../Sources/ChatSendStarsScreen.swift | 2 +- .../StoryContentLiveChatComponent.swift | 10 ++++++++++ .../Sources/StoryItemContentComponent.swift | 8 +++++++- .../StoryItemSetContainerComponent.swift | 7 +++++++ ...StoryItemSetContainerViewSendMessage.swift | 19 ++++++++++++++++--- 5 files changed, 41 insertions(+), 5 deletions(-) diff --git a/submodules/TelegramUI/Components/Chat/ChatSendStarsScreen/Sources/ChatSendStarsScreen.swift b/submodules/TelegramUI/Components/Chat/ChatSendStarsScreen/Sources/ChatSendStarsScreen.swift index 83fa49c7be..b28737a6e4 100644 --- a/submodules/TelegramUI/Components/Chat/ChatSendStarsScreen/Sources/ChatSendStarsScreen.swift +++ b/submodules/TelegramUI/Components/Chat/ChatSendStarsScreen/Sources/ChatSendStarsScreen.swift @@ -489,7 +489,7 @@ private final class PeerComponent: Component { self.addSubview(crownIcon) } - if topPlace != previousComponent?.topPlace { + if topPlace != previousComponent?.topPlace || previousComponent?.color != component.color { crownIcon.image = StoryLiveChatMessageComponent.generateCrownImage(place: topPlace, backgroundColor: component.color, foregroundColor: .white, borderColor: component.theme.actionSheet.opaqueItemBackgroundColor) } if let image = crownIcon.image { diff --git a/submodules/TelegramUI/Components/Stories/StoryContainerScreen/Sources/StoryContentLiveChatComponent.swift b/submodules/TelegramUI/Components/Stories/StoryContainerScreen/Sources/StoryContentLiveChatComponent.swift index 59be1fcf8e..3231872c39 100644 --- a/submodules/TelegramUI/Components/Stories/StoryContainerScreen/Sources/StoryContentLiveChatComponent.swift +++ b/submodules/TelegramUI/Components/Stories/StoryContainerScreen/Sources/StoryContentLiveChatComponent.swift @@ -34,6 +34,7 @@ final class StoryContentLiveChatComponent: Component { let theme: PresentationTheme let call: PresentationGroupCall let storyPeerId: EnginePeer.Id + let canManageMessagesFromPeers: Set let insets: UIEdgeInsets let isEmbeddedInCamera: Bool let minPaidStars: Int? @@ -46,6 +47,7 @@ final class StoryContentLiveChatComponent: Component { theme: PresentationTheme, call: PresentationGroupCall, storyPeerId: EnginePeer.Id, + canManageMessagesFromPeers: Set, insets: UIEdgeInsets, isEmbeddedInCamera: Bool, minPaidStars: Int?, @@ -57,6 +59,7 @@ final class StoryContentLiveChatComponent: Component { self.theme = theme self.call = call self.storyPeerId = storyPeerId + self.canManageMessagesFromPeers = canManageMessagesFromPeers self.insets = insets self.isEmbeddedInCamera = isEmbeddedInCamera self.minPaidStars = minPaidStars @@ -82,6 +85,9 @@ final class StoryContentLiveChatComponent: Component { if lhs.storyPeerId != rhs.storyPeerId { return false } + if lhs.canManageMessagesFromPeers != rhs.canManageMessagesFromPeers { + return false + } if lhs.insets != rhs.insets { return false } @@ -452,6 +458,10 @@ final class StoryContentLiveChatComponent: Component { isMyMessage = true canDelete = true } + if let author = message.author, component.canManageMessagesFromPeers.contains(author.id) { + isMyMessage = true + canDelete = true + } var isMessageFromAdmin = false if message.isFromAdmin { isMessageFromAdmin = true diff --git a/submodules/TelegramUI/Components/Stories/StoryContainerScreen/Sources/StoryItemContentComponent.swift b/submodules/TelegramUI/Components/Stories/StoryContainerScreen/Sources/StoryItemContentComponent.swift index c2682b9ab4..75fe51d2a7 100644 --- a/submodules/TelegramUI/Components/Stories/StoryContainerScreen/Sources/StoryItemContentComponent.swift +++ b/submodules/TelegramUI/Components/Stories/StoryContainerScreen/Sources/StoryItemContentComponent.swift @@ -40,10 +40,11 @@ final class StoryItemContentComponent: Component { let isUIHidden: Bool let preferHighQuality: Bool let isEmbeddedInCamera: Bool + let canManageLiveChatMessagesFromPeers: Set let activateReaction: (UIView, MessageReaction.Reaction) -> Void let controller: () -> ViewController? - init(context: AccountContext, strings: PresentationStrings, peer: EnginePeer, item: EngineStoryItem, availableReactions: StoryAvailableReactions?, entityFiles: [MediaId: TelegramMediaFile], audioMode: StoryContentItem.AudioMode, baseRate: Double, isVideoBuffering: Bool, isCurrent: Bool, isUIHidden: Bool, preferHighQuality: Bool, isEmbeddedInCamera: Bool, activateReaction: @escaping (UIView, MessageReaction.Reaction) -> Void, controller: @escaping () -> ViewController?) { + init(context: AccountContext, strings: PresentationStrings, peer: EnginePeer, item: EngineStoryItem, availableReactions: StoryAvailableReactions?, entityFiles: [MediaId: TelegramMediaFile], audioMode: StoryContentItem.AudioMode, baseRate: Double, isVideoBuffering: Bool, isCurrent: Bool, isUIHidden: Bool, preferHighQuality: Bool, isEmbeddedInCamera: Bool, canManageLiveChatMessagesFromPeers: Set, activateReaction: @escaping (UIView, MessageReaction.Reaction) -> Void, controller: @escaping () -> ViewController?) { self.context = context self.strings = strings self.peer = peer @@ -57,6 +58,7 @@ final class StoryItemContentComponent: Component { self.isUIHidden = isUIHidden self.preferHighQuality = preferHighQuality self.isEmbeddedInCamera = isEmbeddedInCamera + self.canManageLiveChatMessagesFromPeers = canManageLiveChatMessagesFromPeers self.activateReaction = activateReaction self.controller = controller } @@ -95,6 +97,9 @@ final class StoryItemContentComponent: Component { if lhs.isEmbeddedInCamera != rhs.isEmbeddedInCamera { return false } + if lhs.canManageLiveChatMessagesFromPeers != rhs.canManageLiveChatMessagesFromPeers { + return false + } if lhs.preferHighQuality != rhs.preferHighQuality { return false } @@ -1013,6 +1018,7 @@ final class StoryItemContentComponent: Component { theme: environment.theme, call: mediaStreamCall, storyPeerId: component.peer.id, + canManageMessagesFromPeers: component.canManageLiveChatMessagesFromPeers, insets: environment.containerInsets, isEmbeddedInCamera: component.isEmbeddedInCamera, minPaidStars: minPaidStars, diff --git a/submodules/TelegramUI/Components/Stories/StoryContainerScreen/Sources/StoryItemSetContainerComponent.swift b/submodules/TelegramUI/Components/Stories/StoryContainerScreen/Sources/StoryItemSetContainerComponent.swift index 10eba1f75a..fd0d1ada1c 100644 --- a/submodules/TelegramUI/Components/Stories/StoryContainerScreen/Sources/StoryItemSetContainerComponent.swift +++ b/submodules/TelegramUI/Components/Stories/StoryContainerScreen/Sources/StoryItemSetContainerComponent.swift @@ -1629,6 +1629,12 @@ public final class StoryItemSetContainerComponent: Component { component.markAsSeen(id) } ) + + var canManageLiveChatMessagesFromPeers = Set() + if let sendAsData = self.sendMessageContext.sendAsData { + canManageLiveChatMessagesFromPeers.formUnion(sendAsData.availablePeers.map(\.peer.id)) + } + let _ = visibleItem.view.update( transition: itemTransition.withUserData(StoryItemContentComponent.Hint( synchronousLoad: index == centralIndex && itemLayout.contentScaleFraction <= 0.0001 && hintAllowSynchronousLoads @@ -1647,6 +1653,7 @@ public final class StoryItemSetContainerComponent: Component { isUIHidden: component.hideUI, preferHighQuality: component.slice.additionalPeerData.preferHighQualityStories, isEmbeddedInCamera: component.isEmbeddedInCamera, + canManageLiveChatMessagesFromPeers: canManageLiveChatMessagesFromPeers, activateReaction: { [weak self] reactionView, reaction in guard let self else { return diff --git a/submodules/TelegramUI/Components/Stories/StoryContainerScreen/Sources/StoryItemSetContainerViewSendMessage.swift b/submodules/TelegramUI/Components/Stories/StoryContainerScreen/Sources/StoryItemSetContainerViewSendMessage.swift index 82da8ccaea..e5bd1753b4 100644 --- a/submodules/TelegramUI/Components/Stories/StoryContainerScreen/Sources/StoryItemSetContainerViewSendMessage.swift +++ b/submodules/TelegramUI/Components/Stories/StoryContainerScreen/Sources/StoryItemSetContainerViewSendMessage.swift @@ -696,7 +696,6 @@ final class StoryItemSetContainerSendMessage: @unchecked(Sendable) { sendPaidMessageStars = StarsAmount(value: minMessagePrice, nanos: 0) } } - isAdmin = liveChatStateValue.isAdmin if let currentSendAsPeer = self.currentSendAsPeer { sendAsPeer = currentSendAsPeer @@ -705,6 +704,14 @@ final class StoryItemSetContainerSendMessage: @unchecked(Sendable) { return self.sendAsData?.availablePeers.first(where: { $0.peer.id == defaultSendAs }) } } + + if liveChatStateValue.isAdmin { + if let sendAsPeer { + isAdmin = sendAsPeer.peer.id == component.context.account.peerId + } else { + isAdmin = true + } + } } } @@ -4291,8 +4298,6 @@ final class StoryItemSetContainerSendMessage: @unchecked(Sendable) { } var sendAsPeer: SendAsPeer? if let liveChatStateValue = itemView.liveChatState { - isAdmin = liveChatStateValue.isAdmin - if let currentSendAsPeer = self.currentSendAsPeer { sendAsPeer = currentSendAsPeer } else { @@ -4300,6 +4305,14 @@ final class StoryItemSetContainerSendMessage: @unchecked(Sendable) { return self.sendAsData?.availablePeers.first(where: { $0.peer.id == defaultSendAs }) } } + + if liveChatStateValue.isAdmin { + if let sendAsPeer { + isAdmin = sendAsPeer.peer.id == component.context.account.peerId + } else { + isAdmin = true + } + } } call.sendStars(fromId: sendAsPeer?.peer.id, isAdmin: isAdmin, amount: Int64(count), delay: delay)