From a7ab23f97a721fb32b1baa06306b6617d661e98c Mon Sep 17 00:00:00 2001 From: Ali <> Date: Sun, 25 Jun 2023 00:10:41 +0300 Subject: [PATCH] Stories --- .../Sources/ChatListControllerNode.swift | 9 +- .../Sources/Account/Account.swift | 14 +- .../TelegramEngine/Messages/Stories.swift | 3 + .../Messages/TelegramEngineMessages.swift | 17 +- .../Sources/ChatListHeaderComponent.swift | 8 - .../Sources/ChatListNavigationBar.swift | 38 ---- .../Sources/StoryContent.swift | 7 + .../StoryItemSetContainerComponent.swift | 15 +- .../Stories/StoryContentComponent/BUILD | 3 + .../Sources/StoryChatContent.swift | 1 + .../Sources/StoryItemContentComponent.swift | 163 ++++++++++++------ .../Sources/StoryPeerListComponent.swift | 25 ++- 12 files changed, 191 insertions(+), 112 deletions(-) diff --git a/submodules/ChatListUI/Sources/ChatListControllerNode.swift b/submodules/ChatListUI/Sources/ChatListControllerNode.swift index d68a5f805a..23516bfeb4 100644 --- a/submodules/ChatListUI/Sources/ChatListControllerNode.swift +++ b/submodules/ChatListUI/Sources/ChatListControllerNode.swift @@ -19,6 +19,7 @@ import ComponentDisplayAdapters import ComponentFlow import ChatFolderLinkPreviewScreen import ChatListHeaderComponent +import StoryPeerListComponent public enum ChatListContainerNodeFilter: Equatable { case all @@ -927,7 +928,7 @@ public final class ChatListContainerNode: ASDisplayNode, UIGestureRecognizerDele if itemNode.listNode.isTracking && !self.currentItemNode.startedScrollingAtUpperBound && self.tempTopInset == 0.0 { if case let .known(value) = offset { if value < -1.0 { - if let storySubscriptions = self.controller?.orderedStorySubscriptions, !storySubscriptions.items.isEmpty { + if let storySubscriptions = self.controller?.orderedStorySubscriptions, (shouldDisplayStoriesInChatListHeader(storySubscriptions: storySubscriptions) || true) { self.currentItemNode.startedScrollingAtUpperBound = true self.tempTopInset = ChatListNavigationBar.storiesScrollHeight } @@ -958,7 +959,7 @@ public final class ChatListContainerNode: ASDisplayNode, UIGestureRecognizerDele } let tempTopInset: CGFloat if self.currentItemNode.startedScrollingAtUpperBound { - if let storySubscriptions = self.controller?.orderedStorySubscriptions, !storySubscriptions.items.isEmpty { + if let storySubscriptions = self.controller?.orderedStorySubscriptions, (shouldDisplayStoriesInChatListHeader(storySubscriptions: storySubscriptions) || true) { tempTopInset = ChatListNavigationBar.storiesScrollHeight } else { tempTopInset = 0.0 @@ -1799,7 +1800,7 @@ final class ChatListControllerNode: ASDisplayNode, UIGestureRecognizerDelegate { return false } - if let storySubscriptions = controller.orderedStorySubscriptions, !storySubscriptions.items.isEmpty { + if let storySubscriptions = controller.orderedStorySubscriptions, (shouldDisplayStoriesInChatListHeader(storySubscriptions: storySubscriptions) || true) { if let navigationBarComponentView = self.navigationBarView.view as? ChatListNavigationBar.View { if navigationBarComponentView.storiesUnlocked { return true @@ -2060,7 +2061,7 @@ final class ChatListControllerNode: ASDisplayNode, UIGestureRecognizerDelegate { return } - if let storySubscriptions = self.controller?.orderedStorySubscriptions, !storySubscriptions.items.isEmpty { + if let storySubscriptions = self.controller?.orderedStorySubscriptions, (shouldDisplayStoriesInChatListHeader(storySubscriptions: storySubscriptions) || true) { self.tempAllowAvatarExpansion = true self.tempDisableStoriesAnimations = !animated self.tempNavigationScrollingTransition = animated ? .animated(duration: 0.3, curve: .spring) : .immediate diff --git a/submodules/TelegramCore/Sources/Account/Account.swift b/submodules/TelegramCore/Sources/Account/Account.swift index 0590e54584..18fb980468 100644 --- a/submodules/TelegramCore/Sources/Account/Account.swift +++ b/submodules/TelegramCore/Sources/Account/Account.swift @@ -1162,11 +1162,17 @@ public class Account { let extractedExpr: [Signal] = [ managedSynchronizeChatInputStateOperations(postbox: self.postbox, network: self.network) |> map { $0 ? AccountRunningImportantTasks.other : [] }, self.pendingMessageManager.hasPendingMessages |> map { !$0.isEmpty ? AccountRunningImportantTasks.pendingMessages : [] }, - (self.pendingStoryManager?.hasPending ?? .single(false)) |> map { hasPending in hasPending ? AccountRunningImportantTasks.pendingMessages : [] }, - self.pendingUpdateMessageManager.updatingMessageMedia |> map { !$0.isEmpty ? AccountRunningImportantTasks.pendingMessages : [] }, - self.pendingPeerMediaUploadManager.uploadingPeerMedia |> map { !$0.isEmpty ? AccountRunningImportantTasks.pendingMessages : [] }, + (self.pendingStoryManager?.hasPending ?? .single(false)) |> map { + hasPending in hasPending ? AccountRunningImportantTasks.pendingMessages : [] + }, + self.pendingUpdateMessageManager.updatingMessageMedia |> map { + !$0.isEmpty ? AccountRunningImportantTasks.pendingMessages : [] + }, + self.pendingPeerMediaUploadManager.uploadingPeerMedia |> map { + !$0.isEmpty ? AccountRunningImportantTasks.pendingMessages : [] + }, self.accountPresenceManager.isPerformingUpdate() |> map { $0 ? AccountRunningImportantTasks.other : [] }, - self.notificationAutolockReportManager.isPerformingUpdate() |> map { $0 ? AccountRunningImportantTasks.other : [] } + //self.notificationAutolockReportManager.isPerformingUpdate() |> map { $0 ? AccountRunningImportantTasks.other : [] } ] let importantBackgroundOperations: [Signal] = extractedExpr let importantBackgroundOperationsRunning = combineLatest(queue: Queue(), importantBackgroundOperations) diff --git a/submodules/TelegramCore/Sources/TelegramEngine/Messages/Stories.swift b/submodules/TelegramCore/Sources/TelegramEngine/Messages/Stories.swift index ade1b9b758..62a2baf099 100644 --- a/submodules/TelegramCore/Sources/TelegramEngine/Messages/Stories.swift +++ b/submodules/TelegramCore/Sources/TelegramEngine/Messages/Stories.swift @@ -475,6 +475,7 @@ public final class EngineStorySubscriptions: Equatable { public let peer: EnginePeer public let hasUnseen: Bool public let hasUnseenCloseFriends: Bool + public let hasPending: Bool public let storyCount: Int public let unseenCount: Int public let lastTimestamp: Int32 @@ -483,6 +484,7 @@ public final class EngineStorySubscriptions: Equatable { peer: EnginePeer, hasUnseen: Bool, hasUnseenCloseFriends: Bool, + hasPending: Bool, storyCount: Int, unseenCount: Int, lastTimestamp: Int32 @@ -490,6 +492,7 @@ public final class EngineStorySubscriptions: Equatable { self.peer = peer self.hasUnseen = hasUnseen self.hasUnseenCloseFriends = hasUnseenCloseFriends + self.hasPending = hasPending self.storyCount = storyCount self.unseenCount = unseenCount self.lastTimestamp = lastTimestamp diff --git a/submodules/TelegramCore/Sources/TelegramEngine/Messages/TelegramEngineMessages.swift b/submodules/TelegramCore/Sources/TelegramEngine/Messages/TelegramEngineMessages.swift index 6d7abb1f8d..1544e1d43d 100644 --- a/submodules/TelegramCore/Sources/TelegramEngine/Messages/TelegramEngineMessages.swift +++ b/submodules/TelegramCore/Sources/TelegramEngine/Messages/TelegramEngineMessages.swift @@ -645,6 +645,7 @@ public extension TelegramEngine { additionalDataKeys.append(PostboxViewKey.storyItems(peerId: self.account.peerId)) additionalDataKeys.append(PostboxViewKey.storiesState(key: .peer(self.account.peerId))) + additionalDataKeys.append(PostboxViewKey.storiesState(key: .local)) var subscriptionPeerIds = storySubscriptionsView.peerIds.filter { $0 != self.account.peerId } if !debugTimer { @@ -680,6 +681,7 @@ public extension TelegramEngine { peer: EnginePeer(accountPeer), hasUnseen: false, hasUnseenCloseFriends: false, + hasPending: false, storyCount: 0, unseenCount: 0, lastTimestamp: 0 @@ -696,14 +698,17 @@ public extension TelegramEngine { var hasUnseen = false var hasUnseenCloseFriends = false var unseenCount = 0 + var hasPending = false if let peerState = peerState { hasUnseen = peerState.maxReadId < lastEntry.id for item in itemsView.items { if item.id > peerState.maxReadId { unseenCount += 1 - - if case let .item(item) = item.value.get(Stories.StoredItem.self) { + } + + if case let .item(item) = item.value.get(Stories.StoredItem.self) { + if item.id > peerState.maxReadId { if item.isCloseFriends { hasUnseenCloseFriends = true } @@ -712,10 +717,17 @@ public extension TelegramEngine { } } + if let view = views.views[PostboxViewKey.storiesState(key: .local)] as? StoryStatesView, let localState = view.value?.get(Stories.LocalState.self) { + if !localState.items.isEmpty { + hasPending = true + } + } + let item = EngineStorySubscriptions.Item( peer: EnginePeer(accountPeer), hasUnseen: hasUnseen, hasUnseenCloseFriends: hasUnseenCloseFriends, + hasPending: hasPending, storyCount: itemsView.items.count, unseenCount: unseenCount, lastTimestamp: lastEntry.timestamp @@ -766,6 +778,7 @@ public extension TelegramEngine { peer: EnginePeer(peer), hasUnseen: hasUnseen, hasUnseenCloseFriends: hasUnseenCloseFriends, + hasPending: false, storyCount: itemsView.items.count, unseenCount: unseenCount, lastTimestamp: lastEntry.timestamp diff --git a/submodules/TelegramUI/Components/ChatListHeaderComponent/Sources/ChatListHeaderComponent.swift b/submodules/TelegramUI/Components/ChatListHeaderComponent/Sources/ChatListHeaderComponent.swift index 3b1bb6298d..cfd558d152 100644 --- a/submodules/TelegramUI/Components/ChatListHeaderComponent/Sources/ChatListHeaderComponent.swift +++ b/submodules/TelegramUI/Components/ChatListHeaderComponent/Sources/ChatListHeaderComponent.swift @@ -847,14 +847,6 @@ public final class ChatListHeaderComponent: Component { } let sideContentWidth: CGFloat = 0.0 - /*if let storySubscriptions = component.storySubscriptions, !storySubscriptions.items.isEmpty { - sideContentWidth = self.storyPeerListExternalState.collapsedWidth + 12.0 - } - if let chatListTitle = primaryContent.chatListTitle { - if chatListTitle.activity { - sideContentWidth = 0.0 - } - }*/ primaryContentView.update(context: component.context, theme: component.theme, strings: component.strings, content: primaryContent, backTitle: primaryContent.backTitle, sideInset: component.sideInset, sideContentWidth: sideContentWidth, sideContentFraction: (1.0 - component.storiesFraction), size: availableSize, transition: primaryContentTransition) primaryContentTransition.setFrame(view: primaryContentView, frame: CGRect(origin: CGPoint(), size: availableSize)) diff --git a/submodules/TelegramUI/Components/ChatListHeaderComponent/Sources/ChatListNavigationBar.swift b/submodules/TelegramUI/Components/ChatListHeaderComponent/Sources/ChatListNavigationBar.swift index 6c2d8421f7..d715c9f2ea 100644 --- a/submodules/TelegramUI/Components/ChatListHeaderComponent/Sources/ChatListNavigationBar.swift +++ b/submodules/TelegramUI/Components/ChatListHeaderComponent/Sources/ChatListNavigationBar.swift @@ -610,44 +610,6 @@ public final class ChatListNavigationBar: Component { return size } - - /*private func addStoriesUnlockedAnimation(duration: Double, animateScrollUnlocked: Bool) { - guard let component = self.component else { - return - } - self.applyScrollFractionAnimator?.invalidate() - self.applyScrollFractionAnimator = nil - - let storiesUnlocked = component.storiesUnlocked - - self.storiesOffsetStartFraction = self.storiesOffsetFraction - self.storiesUnlockedStartFraction = self.storiesUnlockedFraction - - self.applyScrollFraction = 0.0 - self.applyScrollUnlockedFraction = 0.0 - self.applyScrollFractionAnimator = DisplayLinkAnimator(duration: duration * UIView.animationDurationFactor(), from: 0.0, to: 1.0, update: { [weak self] value in - guard let self else { - return - } - - let t = listViewAnimationCurveSystem(value) - self.applyScrollFraction = t - if animateScrollUnlocked { - self.applyScrollUnlockedFraction = storiesUnlocked ? t : (1.0 - t) - } - - if let rawScrollOffset = self.rawScrollOffset { - self.hasDeferredScrollOffset = true - self.applyScroll(offset: rawScrollOffset, allowAvatarsExpansion: self.currentAllowAvatarsExpansion, transition: .immediate) - } - }, completion: { [weak self] in - guard let self else { - return - } - self.applyScrollFractionAnimator?.invalidate() - self.applyScrollFractionAnimator = nil - }) - }*/ } public func makeView() -> View { diff --git a/submodules/TelegramUI/Components/Stories/StoryContainerScreen/Sources/StoryContent.swift b/submodules/TelegramUI/Components/Stories/StoryContainerScreen/Sources/StoryContent.swift index e49dfa2213..f51a16f98f 100644 --- a/submodules/TelegramUI/Components/Stories/StoryContainerScreen/Sources/StoryContent.swift +++ b/submodules/TelegramUI/Components/Stories/StoryContainerScreen/Sources/StoryContent.swift @@ -5,6 +5,7 @@ import ComponentFlow import SwiftSignalKit import TelegramCore import Postbox +import TelegramPresentationData public final class StoryContentItem { public final class ExternalState { @@ -33,17 +34,20 @@ public final class StoryContentItem { public final class Environment: Equatable { public let externalState: ExternalState public let sharedState: SharedState + public let theme: PresentationTheme public let presentationProgressUpdated: (Double, Bool) -> Void public let markAsSeen: (StoryId) -> Void public init( externalState: ExternalState, sharedState: SharedState, + theme: PresentationTheme, presentationProgressUpdated: @escaping (Double, Bool) -> Void, markAsSeen: @escaping (StoryId) -> Void ) { self.externalState = externalState self.sharedState = sharedState + self.theme = theme self.presentationProgressUpdated = presentationProgressUpdated self.markAsSeen = markAsSeen } @@ -55,6 +59,9 @@ public final class StoryContentItem { if lhs.sharedState !== rhs.sharedState { return false } + if lhs.theme !== rhs.theme { + return false + } return true } } diff --git a/submodules/TelegramUI/Components/Stories/StoryContainerScreen/Sources/StoryItemSetContainerComponent.swift b/submodules/TelegramUI/Components/Stories/StoryContainerScreen/Sources/StoryItemSetContainerComponent.swift index 32732d33f5..d24ba901f5 100644 --- a/submodules/TelegramUI/Components/Stories/StoryContainerScreen/Sources/StoryItemSetContainerComponent.swift +++ b/submodules/TelegramUI/Components/Stories/StoryContainerScreen/Sources/StoryItemSetContainerComponent.swift @@ -621,6 +621,7 @@ public final class StoryItemSetContainerComponent: Component { let itemEnvironment = StoryContentItem.Environment( externalState: visibleItem.externalState, sharedState: component.storyItemSharedState, + theme: component.theme, presentationProgressUpdated: { [weak self, weak visibleItem] progress, canSwitch in guard let self = self, let component = self.component else { return @@ -656,7 +657,6 @@ public final class StoryItemSetContainerComponent: Component { ) if let view = visibleItem.view.view { if view.superview == nil { - view.isUserInteractionEnabled = false self.contentContainerView.insertSubview(view, at: 0) } itemTransition.setFrame(view: view, frame: CGRect(origin: CGPoint(), size: itemLayout.size)) @@ -1139,6 +1139,15 @@ public final class StoryItemSetContainerComponent: Component { } } } + + var isUnsupported = false + var disabledPlaceholder: String? + if component.slice.peer.isService { + disabledPlaceholder = "You can't reply to this story" + } else if case .unsupported = component.slice.item.storyItem.media { + isUnsupported = true + disabledPlaceholder = "You can't reply to this story" + } let keyboardWasHidden = self.inputPanelExternalState.isKeyboardHidden let inputNodeVisible = self.sendMessageContext.currentInputMode == .media || hasFirstResponder(self) @@ -1374,7 +1383,7 @@ public final class StoryItemSetContainerComponent: Component { displayGradient: false, //(component.inputHeight != 0.0 || inputNodeVisible) && component.metrics.widthClass != .regular, bottomInset: component.inputHeight != 0.0 || inputNodeVisible ? 0.0 : bottomContentInset, hideKeyboard: self.sendMessageContext.currentInputMode == .media, - disabledPlaceholder: component.slice.peer.isService ? "You can't reply to this story" : nil + disabledPlaceholder: disabledPlaceholder )), environment: {}, containerSize: CGSize(width: inputPanelAvailableWidth, height: 200.0) @@ -1976,7 +1985,7 @@ public final class StoryItemSetContainerComponent: Component { } } - if !component.slice.item.storyItem.text.isEmpty { + if !isUnsupported, !component.slice.item.storyItem.text.isEmpty { var captionItemTransition = transition let captionItem: CaptionItem if let current = self.captionItem { diff --git a/submodules/TelegramUI/Components/Stories/StoryContentComponent/BUILD b/submodules/TelegramUI/Components/Stories/StoryContentComponent/BUILD index de30c2ebad..0745d5d430 100644 --- a/submodules/TelegramUI/Components/Stories/StoryContentComponent/BUILD +++ b/submodules/TelegramUI/Components/Stories/StoryContentComponent/BUILD @@ -23,6 +23,9 @@ swift_library( "//submodules/TelegramUniversalVideoContent", "//submodules/AvatarNode", "//submodules/Components/HierarchyTrackingLayer", + "//submodules/TelegramUI/Components/ButtonComponent", + "//submodules/Components/MultilineTextComponent", + "//submodules/TelegramPresentationData", ], visibility = [ "//visibility:public", diff --git a/submodules/TelegramUI/Components/Stories/StoryContentComponent/Sources/StoryChatContent.swift b/submodules/TelegramUI/Components/Stories/StoryContentComponent/Sources/StoryChatContent.swift index 76f0ca8379..ef728d81df 100644 --- a/submodules/TelegramUI/Components/Stories/StoryContentComponent/Sources/StoryChatContent.swift +++ b/submodules/TelegramUI/Components/Stories/StoryContentComponent/Sources/StoryChatContent.swift @@ -437,6 +437,7 @@ public final class StoryContentContextImpl: StoryContentContext { peer: peer, hasUnseen: state.hasUnseen, hasUnseenCloseFriends: state.hasUnseenCloseFriends, + hasPending: false, storyCount: state.items.count, unseenCount: 0, lastTimestamp: state.items.last?.timestamp ?? 0 diff --git a/submodules/TelegramUI/Components/Stories/StoryContentComponent/Sources/StoryItemContentComponent.swift b/submodules/TelegramUI/Components/Stories/StoryContentComponent/Sources/StoryItemContentComponent.swift index aff3a109c4..5c42c04874 100644 --- a/submodules/TelegramUI/Components/Stories/StoryContentComponent/Sources/StoryItemContentComponent.swift +++ b/submodules/TelegramUI/Components/Stories/StoryContentComponent/Sources/StoryItemContentComponent.swift @@ -12,6 +12,9 @@ import UniversalMediaPlayer import TelegramUniversalVideoContent import StoryContainerScreen import HierarchyTrackingLayer +import ButtonComponent +import MultilineTextComponent +import TelegramPresentationData final class StoryItemContentComponent: Component { typealias EnvironmentType = StoryContentItem.Environment @@ -38,56 +41,6 @@ final class StoryItemContentComponent: Component { } return true } - - /*static func preload(context: AccountContext, message: EngineMessage) -> Signal { - var messageMedia: EngineMedia? - for media in message.media { - switch media { - case let image as TelegramMediaImage: - messageMedia = .image(image) - case let file as TelegramMediaFile: - messageMedia = .file(file) - default: - break - } - } - - guard let messageMedia else { - return .complete() - } - - var fetchSignal: Signal? - switch messageMedia { - case let .image(image): - if let representation = image.representations.last { - fetchSignal = fetchedMediaResource( - mediaBox: context.account.postbox.mediaBox, - userLocation: .peer(message.id.peerId), - userContentType: .image, - reference: ImageMediaReference.message(message: MessageReference(message._asMessage()), media: image).resourceReference(representation.resource) - ) - |> ignoreValues - |> `catch` { _ -> Signal in - return .complete() - } - } - case let .file(file): - fetchSignal = fetchedMediaResource( - mediaBox: context.account.postbox.mediaBox, - userLocation: .peer(message.id.peerId), - userContentType: .image, - reference: FileMediaReference.message(message: MessageReference(message._asMessage()), media: file).resourceReference(file.resource) - ) - |> ignoreValues - |> `catch` { _ -> Signal in - return .complete() - } - default: - break - } - - return fetchSignal ?? .complete() - }*/ final class View: StoryContentItem.View { private let imageNode: TransformImageNode @@ -100,6 +53,9 @@ final class StoryItemContentComponent: Component { private weak var state: EmptyComponentState? private var environment: StoryContentItem.Environment? + private var unsupportedText: ComponentView? + private var unsupportedButton: ComponentView? + private var isProgressPaused: Bool = false private var currentProgressTimer: SwiftSignalKit.Timer? private var currentProgressTimerValue: Double = 0.0 @@ -353,10 +309,20 @@ final class StoryItemContentComponent: Component { self.environment?.presentationProgressUpdated(clippedProgress, false) } + override func hitTest(_ point: CGPoint, with event: UIEvent?) -> UIView? { + if let unsupportedButtonView = self.unsupportedButton?.view { + if let result = unsupportedButtonView.hitTest(self.convert(point, to: unsupportedButtonView), with: event) { + return result + } + } + return nil + } + func update(component: StoryItemContentComponent, availableSize: CGSize, state: EmptyComponentState, environment: Environment, transition: Transition) -> CGSize { self.component = component self.state = state - self.environment = environment[StoryContentItem.Environment.self].value + let environment = environment[StoryContentItem.Environment.self].value + self.environment = environment let peerReference = PeerReference(component.peer._asPeer()) @@ -366,6 +332,8 @@ final class StoryItemContentComponent: Component { messageMedia = .image(image) case let .file(file): messageMedia = .file(file) + case .unsupported: + self.contentLoaded = true default: break } @@ -504,6 +472,99 @@ final class StoryItemContentComponent: Component { } } + switch component.item.media { + case .image, .file: + if let unsupportedText = self.unsupportedText { + self.unsupportedText = nil + unsupportedText.view?.removeFromSuperview() + } + if let unsupportedButton = self.unsupportedButton { + self.unsupportedButton = nil + unsupportedButton.view?.removeFromSuperview() + } + + self.backgroundColor = .black + default: + var unsuportedTransition = transition + + let unsupportedText: ComponentView + if let current = self.unsupportedText { + unsupportedText = current + } else { + unsuportedTransition = .immediate + unsupportedText = ComponentView() + self.unsupportedText = unsupportedText + } + + let unsupportedButton: ComponentView + if let current = self.unsupportedButton { + unsupportedButton = current + } else { + unsuportedTransition = .immediate + unsupportedButton = ComponentView() + self.unsupportedButton = unsupportedButton + } + + //TODO:localize + let unsupportedTextSize = unsupportedText.update( + transition: .immediate, + component: AnyComponent(MultilineTextComponent( + text: .plain(NSAttributedString(string: "This story is not supported by\nyour version of Telegram.", font: Font.regular(17.0), textColor: .white)), + horizontalAlignment: .center, + maximumNumberOfLines: 0 + )), + environment: {}, + containerSize: CGSize(width: availableSize.width - 16.0 * 2.0, height: availableSize.height) + ) + let unsupportedButtonSize = unsupportedButton.update( + transition: unsuportedTransition, + component: AnyComponent(ButtonComponent( + background: ButtonComponent.Background( + color: environment.theme.list.itemCheckColors.fillColor, + foreground: environment.theme.list.itemCheckColors.foregroundColor, + pressedColor: environment.theme.list.itemCheckColors.fillColor.withMultipliedAlpha(0.7) + ), + content: AnyComponentWithIdentity(id: AnyHashable(""), component: AnyComponent(Text(text: "Update Telegram", font: Font.semibold(17.0), color: environment.theme.list.itemCheckColors.foregroundColor + ))), + isEnabled: true, + displaysProgress: false, + action: { [weak self] in + guard let self, let component = self.component else { + return + } + component.context.sharedContext.applicationBindings.openAppStorePage() + } + )), + environment: {}, + containerSize: CGSize(width: 240.0, height: 50.0) + ) + + let spacing: CGFloat = 24.0 + let contentHeight = unsupportedTextSize.height + unsupportedButtonSize.height + spacing + var contentY = floor((availableSize.height - contentHeight) * 0.5) + + let unsupportedTextFrame = CGRect(origin: CGPoint(x: floor((availableSize.width - unsupportedTextSize.width) * 0.5), y: contentY), size: unsupportedTextSize) + contentY += unsupportedTextSize.height + spacing + + let unsupportedButtonFrame = CGRect(origin: CGPoint(x: floor((availableSize.width - unsupportedButtonSize.width) * 0.5), y: contentY), size: unsupportedButtonSize) + + if let unsupportedTextView = unsupportedText.view { + if unsupportedTextView.superview == nil { + self.addSubview(unsupportedTextView) + } + unsuportedTransition.setPosition(view: unsupportedTextView, position: unsupportedTextFrame.center) + unsupportedTextView.bounds = CGRect(origin: CGPoint(), size: unsupportedTextFrame.size) + } + if let unsupportedButtonView = unsupportedButton.view { + if unsupportedButtonView.superview == nil { + self.addSubview(unsupportedButtonView) + } + unsuportedTransition.setFrame(view: unsupportedButtonView, frame: unsupportedButtonFrame) + } + + self.backgroundColor = UIColor(rgb: 0x181818) + } + self.updateIsProgressPaused() return availableSize diff --git a/submodules/TelegramUI/Components/Stories/StoryPeerListComponent/Sources/StoryPeerListComponent.swift b/submodules/TelegramUI/Components/Stories/StoryPeerListComponent/Sources/StoryPeerListComponent.swift index 1026eb66eb..1e44bfc724 100644 --- a/submodules/TelegramUI/Components/Stories/StoryPeerListComponent/Sources/StoryPeerListComponent.swift +++ b/submodules/TelegramUI/Components/Stories/StoryPeerListComponent/Sources/StoryPeerListComponent.swift @@ -11,6 +11,16 @@ import SwiftSignalKit import TelegramPresentationData import StoryContainerScreen +public func shouldDisplayStoriesInChatListHeader(storySubscriptions: EngineStorySubscriptions) -> Bool { + if !storySubscriptions.items.isEmpty { + return true + } + if let accountItem = storySubscriptions.accountItem, (accountItem.hasUnseen || accountItem.hasPending) { + return true + } + return false +} + private func solveParabolicMotion(from sourcePoint: CGPoint, to targetPosition: CGPoint, progress: CGFloat) -> CGPoint { if sourcePoint.y == targetPosition.y { return sourcePoint.interpolate(to: targetPosition, amount: progress) @@ -373,12 +383,23 @@ public final class StoryPeerListComponent: Component { } var hasStories: Bool = false - if let storySubscriptions = component.storySubscriptions, !storySubscriptions.items.isEmpty { + if let storySubscriptions = component.storySubscriptions, shouldDisplayStoriesInChatListHeader(storySubscriptions: storySubscriptions) { hasStories = true } let _ = hasStories - let collapseStartIndex = component.useHiddenList ? 0 : 1 + let collapseStartIndex: Int + if component.useHiddenList { + collapseStartIndex = 0 + } else if let storySubscriptions = component.storySubscriptions { + if let accountItem = storySubscriptions.accountItem, (accountItem.hasUnseen || accountItem.hasPending) { + collapseStartIndex = 0 + } else { + collapseStartIndex = 1 + } + } else { + collapseStartIndex = 1 + } let collapsedItemWidth: CGFloat = 24.0 let collapsedItemDistance: CGFloat = 14.0