From 126157360e0ea2a5c04343d63a7c7891e8f98e27 Mon Sep 17 00:00:00 2001 From: Ali <> Date: Sat, 10 Jun 2023 23:05:46 +0400 Subject: [PATCH] [WIP] Stories --- .../MediaNavigationStripComponent.swift | 6 ++- .../Sources/StoryContainerScreen.swift | 6 +++ .../StoryContentCaptionComponent.swift | 40 ++++++++++++++-- .../StoryItemSetContainerComponent.swift | 30 ++++++++++-- ...StoryItemSetContainerViewSendMessage.swift | 47 ++++++++++++------- .../Stories/StoryPeerListComponent/BUILD | 1 + .../Sources/StoryPeerListItemComponent.swift | 6 ++- 7 files changed, 110 insertions(+), 26 deletions(-) diff --git a/submodules/TelegramUI/Components/Stories/StoryContainerScreen/Sources/MediaNavigationStripComponent.swift b/submodules/TelegramUI/Components/Stories/StoryContainerScreen/Sources/MediaNavigationStripComponent.swift index 008785d354..4bfab16ef8 100644 --- a/submodules/TelegramUI/Components/Stories/StoryContainerScreen/Sources/MediaNavigationStripComponent.swift +++ b/submodules/TelegramUI/Components/Stories/StoryContainerScreen/Sources/MediaNavigationStripComponent.swift @@ -109,7 +109,11 @@ final class MediaNavigationStripComponent: Component { itemWidth = idealItemWidth } - let globalWidth: CGFloat = CGFloat(component.count) * itemWidth + CGFloat(component.count - 1) * spacing + var globalWidth: CGFloat = CGFloat(component.count) * itemWidth + CGFloat(component.count - 1) * spacing + if globalWidth > availableSize.width && globalWidth <= availableSize.width + 1.0 { + globalWidth = availableSize.width + } + let globalFocusedFrame = CGRect(origin: CGPoint(x: CGFloat(component.index) * (itemWidth + spacing), y: 0.0), size: CGSize(width: itemWidth, height: itemHeight)) var globalOffset: CGFloat = floor(globalFocusedFrame.midX - availableSize.width * 0.5) if globalOffset > globalWidth - availableSize.width { diff --git a/submodules/TelegramUI/Components/Stories/StoryContainerScreen/Sources/StoryContainerScreen.swift b/submodules/TelegramUI/Components/Stories/StoryContainerScreen/Sources/StoryContainerScreen.swift index 4867c831ab..3fc39633cf 100644 --- a/submodules/TelegramUI/Components/Stories/StoryContainerScreen/Sources/StoryContainerScreen.swift +++ b/submodules/TelegramUI/Components/Stories/StoryContainerScreen/Sources/StoryContainerScreen.swift @@ -190,6 +190,9 @@ private final class StoryContainerScreenComponent: Component { if !itemSetComponentView.isPointInsideContentArea(point: self.convert(point, to: itemSetComponentView)) { return [] } + if !itemSetComponentView.allowsInteractiveGestures() { + return [] + } return [.left, .right] }) self.addGestureRecognizer(horizontalPanRecognizer) @@ -201,6 +204,9 @@ private final class StoryContainerScreenComponent: Component { if !itemSetComponentView.isPointInsideContentArea(point: self.convert(point, to: itemSetComponentView)) { return [] } + if !itemSetComponentView.allowsInteractiveGestures() { + return [] + } return [.down] }) diff --git a/submodules/TelegramUI/Components/Stories/StoryContainerScreen/Sources/StoryContentCaptionComponent.swift b/submodules/TelegramUI/Components/Stories/StoryContainerScreen/Sources/StoryContentCaptionComponent.swift index 8db59bd7e7..5e1618c607 100644 --- a/submodules/TelegramUI/Components/Stories/StoryContainerScreen/Sources/StoryContentCaptionComponent.swift +++ b/submodules/TelegramUI/Components/Stories/StoryContainerScreen/Sources/StoryContentCaptionComponent.swift @@ -6,12 +6,24 @@ import MultilineTextComponent final class StoryContentCaptionComponent: Component { final class ExternalState { - fileprivate(set) var expandFraction: CGFloat = 0.0 + fileprivate(set) var isExpanded: Bool = false init() { } } + final class TransitionHint { + enum Kind { + case isExpandedUpdated + } + + let kind: Kind + + init(kind: Kind) { + self.kind = kind + } + } + let externalState: ExternalState let text: String @@ -81,6 +93,9 @@ final class StoryContentCaptionComponent: Component { self.addSubview(self.scrollViewContainer) self.scrollViewContainer.mask = self.scrollMaskContainer + + let tapRecognizer = UITapGestureRecognizer(target: self, action: #selector(self.tapGesture(_:))) + self.addGestureRecognizer(tapRecognizer) } required init?(coder: NSCoder) { @@ -101,12 +116,26 @@ final class StoryContentCaptionComponent: Component { return nil } + @objc private func tapGesture(_ recognizer: UITapGestureRecognizer) { + if case .ended = recognizer.state { + self.expand(transition: Transition(animation: .curve(duration: 0.4, curve: .spring))) + } + } + func scrollViewDidScroll(_ scrollView: UIScrollView) { if !self.ignoreScrolling { self.updateScrolling(transition: .immediate) } } + func expand(transition: Transition) { + self.ignoreScrolling = true + transition.setBounds(view: self.scrollView, bounds: CGRect(origin: CGPoint(x: 0.0, y: max(0.0, self.scrollView.contentSize.height - self.scrollView.bounds.height)), size: self.scrollView.bounds.size)) + self.ignoreScrolling = false + + self.updateScrolling(transition: transition) + } + func collapse(transition: Transition) { self.ignoreScrolling = true transition.setBounds(view: self.scrollView, bounds: CGRect(origin: CGPoint(), size: self.scrollView.bounds.size)) @@ -132,11 +161,14 @@ final class StoryContentCaptionComponent: Component { if self.scrollView.contentSize.height < self.scrollView.bounds.height + expandDistance { expandFraction = 0.0 } - if component.externalState.expandFraction != expandFraction { - component.externalState.expandFraction = expandFraction + + let isExpanded = expandFraction > 0.0 + + if component.externalState.isExpanded != isExpanded { + component.externalState.isExpanded = isExpanded if !self.ignoreExternalState { - self.state?.updated(transition: transition) + self.state?.updated(transition: transition.withUserData(TransitionHint(kind: .isExpandedUpdated))) } } } diff --git a/submodules/TelegramUI/Components/Stories/StoryContainerScreen/Sources/StoryItemSetContainerComponent.swift b/submodules/TelegramUI/Components/Stories/StoryContainerScreen/Sources/StoryItemSetContainerComponent.swift index a1a6c1dff3..58146afcf3 100644 --- a/submodules/TelegramUI/Components/Stories/StoryContainerScreen/Sources/StoryItemSetContainerComponent.swift +++ b/submodules/TelegramUI/Components/Stories/StoryContainerScreen/Sources/StoryItemSetContainerComponent.swift @@ -405,6 +405,13 @@ public final class StoryItemSetContainerComponent: Component { return false } + func allowsInteractiveGestures() -> Bool { + if self.displayViewList { + return false + } + return true + } + func rewindCurrentItem() { guard let component = self.component else { return @@ -431,7 +438,7 @@ public final class StoryItemSetContainerComponent: Component { } else if self.displayViewList { self.displayViewList = false self.state?.updated(transition: Transition(animation: .curve(duration: 0.4, curve: .spring))) - } else if let captionItem = self.captionItem, captionItem.externalState.expandFraction > 0.0 { + } else if let captionItem = self.captionItem, captionItem.externalState.isExpanded { if let captionItemView = captionItem.view.view as? StoryContentCaptionComponent.View { captionItemView.collapse(transition: Transition(animation: .curve(duration: 0.4, curve: .spring))) } @@ -479,7 +486,13 @@ public final class StoryItemSetContainerComponent: Component { if self.inputPanelExternalState.isEditing || component.isProgressPaused || self.actionSheet != nil || self.contextController != nil || self.sendMessageContext.audioRecorderValue != nil || self.sendMessageContext.videoRecorderValue != nil || self.displayViewList { return true } - if let captionItem = self.captionItem, captionItem.externalState.expandFraction > 0.0 { + if self.sendMessageContext.attachmentController != nil { + return true + } + if self.sendMessageContext.shareController != nil { + return true + } + if let captionItem = self.captionItem, captionItem.externalState.isExpanded { return true } return false @@ -1727,8 +1740,12 @@ public final class StoryItemSetContainerComponent: Component { transition.setAlpha(layer: self.bottomContentGradientLayer, alpha: 0.0) var normalDimAlpha: CGFloat = 0.0 + var forceDimAnimation = false if let captionItem = self.captionItem { - normalDimAlpha = captionItem.externalState.expandFraction + normalDimAlpha = captionItem.externalState.isExpanded ? 1.0 : 0.0 + if transition.animation.isImmediate && transition.userData(StoryContentCaptionComponent.TransitionHint.self)?.kind == .isExpandedUpdated { + forceDimAnimation = true + } } var dimAlpha: CGFloat = (inputPanelIsOverlay || self.inputPanelExternalState.isEditing) ? 1.0 : normalDimAlpha if component.hideUI || self.displayViewList { @@ -1736,7 +1753,12 @@ public final class StoryItemSetContainerComponent: Component { } transition.setFrame(layer: self.contentDimLayer, frame: CGRect(origin: CGPoint(), size: contentFrame.size)) - transition.setAlpha(layer: self.contentDimLayer, alpha: dimAlpha) + + if transition.animation.isImmediate && forceDimAnimation && self.contentDimLayer.opacity != Float(dimAlpha) { + Transition(animation: .curve(duration: 0.25, curve: .easeInOut)).setAlpha(layer: self.contentDimLayer, alpha: dimAlpha) + } else { + transition.setAlpha(layer: self.contentDimLayer, alpha: dimAlpha) + } self.ignoreScrolling = true transition.setFrame(view: self.scrollView, frame: CGRect(origin: CGPoint(x: 0.0, y: 0.0), size: CGSize(width: availableSize.width, height: availableSize.height))) diff --git a/submodules/TelegramUI/Components/Stories/StoryContainerScreen/Sources/StoryItemSetContainerViewSendMessage.swift b/submodules/TelegramUI/Components/Stories/StoryContainerScreen/Sources/StoryItemSetContainerViewSendMessage.swift index fd8979fb98..1f29747278 100644 --- a/submodules/TelegramUI/Components/Stories/StoryContainerScreen/Sources/StoryItemSetContainerViewSendMessage.swift +++ b/submodules/TelegramUI/Components/Stories/StoryContainerScreen/Sources/StoryItemSetContainerViewSendMessage.swift @@ -35,6 +35,7 @@ import Postbox final class StoryItemSetContainerSendMessage { weak var attachmentController: AttachmentController? + weak var shareController: ShareController? var audioRecorderValue: ManagedAudioRecorder? var audioRecorder = Promise() @@ -295,6 +296,18 @@ final class StoryItemSetContainerSendMessage { updatedPresentationData: (component.context.sharedContext.currentPresentationData.with({ $0 }), component.context.sharedContext.presentationData) ) + + self.shareController = shareController + view.updateIsProgressPaused() + + shareController.dismissed = { [weak self, weak view] _ in + guard let self, let view else { + return + } + self.shareController = nil + view.updateIsProgressPaused() + } + controller.present(shareController, in: .window(.root)) } @@ -436,23 +449,25 @@ final class StoryItemSetContainerSendMessage { initialButton = .gift*/ } - for bot in attachMenuBots.reversed() { - var peerType = peerType - if bot.peer.id == peer.id { - peerType.insert(.sameBot) - peerType.remove(.bot) + if !"".isEmpty { + for bot in attachMenuBots.reversed() { + var peerType = peerType + if bot.peer.id == peer.id { + peerType.insert(.sameBot) + peerType.remove(.bot) + } + let button: AttachmentButtonType = .app(bot.peer, bot.shortName, bot.icons) + if !bot.peerTypes.intersection(peerType).isEmpty { + buttons.insert(button, at: 1) + + /*if case let .bot(botId, _, _) = subject { + if initialButton == nil && bot.peer.id == botId { + initialButton = button + } + }*/ + } + allButtons.insert(button, at: 1) } - let button: AttachmentButtonType = .app(bot.peer, bot.shortName, bot.icons) - if !bot.peerTypes.intersection(peerType).isEmpty { - buttons.insert(button, at: 1) - - /*if case let .bot(botId, _, _) = subject { - if initialButton == nil && bot.peer.id == botId { - initialButton = button - } - }*/ - } - allButtons.insert(button, at: 1) } return (buttons, allButtons, initialButton) diff --git a/submodules/TelegramUI/Components/Stories/StoryPeerListComponent/BUILD b/submodules/TelegramUI/Components/Stories/StoryPeerListComponent/BUILD index c192bd5d1d..d4096a81ff 100644 --- a/submodules/TelegramUI/Components/Stories/StoryPeerListComponent/BUILD +++ b/submodules/TelegramUI/Components/Stories/StoryPeerListComponent/BUILD @@ -21,6 +21,7 @@ swift_library( "//submodules/AvatarNode", "//submodules/ContextUI", "//submodules/TelegramUI/Components/Stories/StoryContainerScreen", + "//submodules/Components/MultilineTextComponent", ], visibility = [ "//visibility:public", diff --git a/submodules/TelegramUI/Components/Stories/StoryPeerListComponent/Sources/StoryPeerListItemComponent.swift b/submodules/TelegramUI/Components/Stories/StoryPeerListComponent/Sources/StoryPeerListItemComponent.swift index 1e9c1eb47d..8e49f2e203 100644 --- a/submodules/TelegramUI/Components/Stories/StoryPeerListComponent/Sources/StoryPeerListItemComponent.swift +++ b/submodules/TelegramUI/Components/Stories/StoryPeerListComponent/Sources/StoryPeerListItemComponent.swift @@ -12,6 +12,7 @@ import AvatarNode import ContextUI import AsyncDisplayKit import StoryContainerScreen +import MultilineTextComponent private func calculateCircleIntersection(center: CGPoint, otherCenter: CGPoint, radius: CGFloat) -> (point1Angle: CGFloat, point2Angle: CGFloat)? { let distanceVector = CGPoint(x: otherCenter.x - center.x, y: otherCenter.y - center.y) @@ -704,7 +705,10 @@ public final class StoryPeerListItemComponent: Component { let titleSize = self.title.update( transition: .immediate, - component: AnyComponent(Text(text: titleString, font: Font.regular(11.0), color: component.theme.list.itemPrimaryTextColor)), + component: AnyComponent(MultilineTextComponent( + text: .plain(NSAttributedString(string: titleString, font: Font.regular(11.0), textColor: component.theme.list.itemPrimaryTextColor)), + maximumNumberOfLines: 1 + )), environment: {}, containerSize: CGSize(width: availableSize.width + 4.0, height: 100.0) )