diff --git a/MODULE.bazel.lock b/MODULE.bazel.lock index 9cf530b698..cf536336c5 100644 --- a/MODULE.bazel.lock +++ b/MODULE.bazel.lock @@ -159,7 +159,7 @@ "moduleExtensions": { "@@apple_support+//crosstool:setup.bzl%apple_cc_configure_extension": { "general": { - "bzlTransitiveDigest": "Ync9nL0AbHC6ondeEY7fBjBjLxojTsiXcJh65ZDTRlA=", + "bzlTransitiveDigest": "IK7QnlhcNBu2jc4wZoGZeDTu3keF2LldFiFUINRcKvo=", "usagesDigest": "lfcV4HxPD+NLaRIT/v7BtSGFgE7c9xrWU7jDiwBAxzo=", "recordedFileInputs": {}, "recordedDirentsInputs": {}, diff --git a/submodules/TelegramUI/Components/PeerInfo/PeerInfoScreen/Sources/PeerInfoHeaderNode.swift b/submodules/TelegramUI/Components/PeerInfo/PeerInfoScreen/Sources/PeerInfoHeaderNode.swift index 42bec125e2..794b13e9e7 100644 --- a/submodules/TelegramUI/Components/PeerInfo/PeerInfoScreen/Sources/PeerInfoHeaderNode.swift +++ b/submodules/TelegramUI/Components/PeerInfo/PeerInfoScreen/Sources/PeerInfoHeaderNode.swift @@ -1917,7 +1917,7 @@ final class PeerInfoHeaderNode: ASDisplayNode { let apparentBackgroundHeight = (1.0 - transitionFraction) * backgroundHeight + transitionFraction * transitionSourceHeight var subtitleRatingSize: CGSize? - if let cachedData = cachedData as? CachedUserData, let starRating = cachedData.starRating { + if !"".isEmpty, let cachedData = cachedData as? CachedUserData, let starRating = cachedData.starRating { let subtitleRating: ComponentView var subtitleRatingTransition = ComponentTransition(transition) if let current = self.subtitleRating { diff --git a/submodules/TelegramUI/Components/PeerInfo/PeerInfoScreen/Sources/PeerInfoScreen.swift b/submodules/TelegramUI/Components/PeerInfo/PeerInfoScreen/Sources/PeerInfoScreen.swift index 400e9140a8..8987ea9da8 100644 --- a/submodules/TelegramUI/Components/PeerInfo/PeerInfoScreen/Sources/PeerInfoScreen.swift +++ b/submodules/TelegramUI/Components/PeerInfo/PeerInfoScreen/Sources/PeerInfoScreen.swift @@ -11710,7 +11710,7 @@ final class PeerInfoScreenNode: ViewControllerTracingNode, PeerInfoScreenNodePro } }))) - if pane.canReorder() { + /*if pane.canReorder() { items.append(.action(ContextMenuActionItem(text: self.presentationData.strings.BotPreviews_MenuReorder, icon: { theme in return generateTintedImage(image: UIImage(bundleImageName: "Chat/Context Menu/ReorderItems"), color: theme.contextMenu.primaryColor) }, action: { [weak pane] _, a in @@ -11742,7 +11742,7 @@ final class PeerInfoScreenNode: ViewControllerTracingNode, PeerInfoScreenNodePro pane.presentDeleteCurrentStoryFolder() } }))) - } + }*/ if let language = pane.currentBotPreviewLanguage { items.append(.action(ContextMenuActionItem(text: self.presentationData.strings.BotPreviews_MenuDeleteLanguage(language.name).string, textColor: .destructive, icon: { theme in diff --git a/submodules/TelegramUI/Components/PeerInfo/PeerInfoVisualMediaPaneNode/Sources/PeerInfoStoryPaneNode.swift b/submodules/TelegramUI/Components/PeerInfo/PeerInfoVisualMediaPaneNode/Sources/PeerInfoStoryPaneNode.swift index 6814d08189..4335317e2d 100644 --- a/submodules/TelegramUI/Components/PeerInfo/PeerInfoVisualMediaPaneNode/Sources/PeerInfoStoryPaneNode.swift +++ b/submodules/TelegramUI/Components/PeerInfo/PeerInfoVisualMediaPaneNode/Sources/PeerInfoStoryPaneNode.swift @@ -44,8 +44,6 @@ import MultilineTextComponent import LocationUI import TabSelectorComponent import LanguageSelectionScreen -import PromptUI -import BottomButtonPanelComponent private let mediaBadgeBackgroundColor = UIColor(white: 0.0, alpha: 0.6) private let mediaBadgeTextColor = UIColor.white @@ -1570,7 +1568,7 @@ public final class PeerInfoStoryPaneNode: ASDisplayNode, PeerInfoPaneNode, ASScr private var mapInfoNode: LocationInfoListItemNode? private var searchHeader: ComponentView? - private var folderTab: ComponentView? + private var botPreviewLanguageTab: ComponentView? private var botPreviewFooter: ComponentView? private var barBackgroundLayer: SimpleLayer? @@ -1583,10 +1581,8 @@ public final class PeerInfoStoryPaneNode: ASDisplayNode, PeerInfoPaneNode, ASScr private var reorderedIds: [StoryId]? private var itemCount: Int? private var didUpdateItemsOnce: Bool = false - private var itemTabId: AnyHashable? private var selectionPanel: ComponentView? - private var actionPanel: ComponentView? private var isDeceleratingAfterTracking = false @@ -1652,8 +1648,6 @@ public final class PeerInfoStoryPaneNode: ASDisplayNode, PeerInfoPaneNode, ASScr public var tabBarOffset: CGFloat { if case .botPreview = self.scope { return 0.0 - } else if case let .peer(peerId, _, isArchived) = self.scope, peerId == self.context.account.peerId, !isArchived, self.isProfileEmbedded { - return 0.0 } else { return self.itemGrid.coveringInsetOffset } @@ -1667,9 +1661,6 @@ public final class PeerInfoStoryPaneNode: ASDisplayNode, PeerInfoPaneNode, ASScr private var currentBotPreviewLanguages: [StoryListContext.State.Language] = [] private var removedBotPreviewLanguages = Set() - private var currentStoryFolders: [StoryListContext.State.Folder] = [] - private var removedStoryFolders = Set() - private var numberOfItemsToRequest: Int = 50 private var isRequestingView: Bool = false private var isFirstHistoryView: Bool = true @@ -1684,7 +1675,7 @@ public final class PeerInfoStoryPaneNode: ASDisplayNode, PeerInfoPaneNode, ASScr private let maxBotPreviewCount: Int private let defaultListSource: StoryListContext - private var cachedListSources: [AnyHashable: StoryListContext] = [:] + private var cachedListSources: [String: StoryListContext] = [:] public var currentBotPreviewLanguage: (id: String, name: String)? { guard let listSource = self.listSource as? BotPreviewStoryListContext else { @@ -1698,19 +1689,6 @@ public final class PeerInfoStoryPaneNode: ASDisplayNode, PeerInfoPaneNode, ASScr } return (language.id, language.name) } - - public var currentStoryFolder: (id: Int64, title: String)? { - guard let listSource = self.listSource as? PeerStoryListContext else { - return nil - } - guard let id = listSource.folderId else { - return nil - } - guard let folder = self.currentStoryFolders.first(where: { $0.id == id }) else { - return nil - } - return (folder.id, folder.title) - } public var openCurrentDate: (() -> Void)? public var paneDidScroll: (() -> Void)? @@ -1822,7 +1800,7 @@ public final class PeerInfoStoryPaneNode: ASDisplayNode, PeerInfoPaneNode, ASScr return } - if self.isProfileEmbedded || !self.shouldOpenItemsWhileInSelectionMode { + if self.isProfileEmbedded { if let selectedIds = self.itemInteraction.selectedIds { self.itemInteraction.toggleSelection(item.story.id, !selectedIds.contains(item.story.id)) return @@ -2471,122 +2449,6 @@ public final class PeerInfoStoryPaneNode: ASDisplayNode, PeerInfoPaneNode, ASScr var items: [ContextMenuItem] = [] if canManage, case let .peer(peerId, _, isArchived) = self.scope { - if peerId == self.context.account.peerId && self.isProfileEmbedded { - if let folder = self.currentStoryFolder { - //TODO:localize - items.append(.action(ContextMenuActionItem(text: "Remove from Album", textColor: .destructive, icon: { theme in generateTintedImage(image: UIImage(bundleImageName: "Chat/Context Menu/Delete"), color: theme.contextMenu.destructiveColor) }, action: { [weak self] _, f in - guard let self else { - f(.default) - return - } - - if let listSource = self.listSource as? PeerStoryListContext { - listSource.removeFromFolder(id: folder.id, itemIds: [item.id]) - } - - f(.dismissWithoutContent) - }))) - } else { - //TODO:localize - items.append(.action(ContextMenuActionItem(text: "Add to Album", icon: { theme in generateTintedImage(image: UIImage(bundleImageName: "Chat/Context Menu/Folder"), color: theme.contextMenu.primaryColor) }, action: { [weak self] c, f in - guard let self, let c else { - f(.default) - return - } - - Task { @MainActor [weak self, weak c] in - guard let self, let c else { - return - } - - let (peerReference, folderPreviews) = await PeerStoryListContext.folderPreviews(peerId: peerId, account: self.context.account).get() - - var items: [ContextMenuItem] = [] - items.append(.action(ContextMenuActionItem(text: self.presentationData.strings.Common_Back, icon: { theme in - return generateTintedImage(image: UIImage(bundleImageName: "Chat/Context Menu/Back"), color: theme.contextMenu.primaryColor) - }, iconPosition: .left, action: { c ,f in - c?.popItems() - }))) - items.append(.separator) - - items.append(.action(ContextMenuActionItem(text: "New Album", icon: { theme in generateTintedImage(image: UIImage(bundleImageName: "Chat/Context Menu/Folder"), color: theme.contextMenu.primaryColor) }, iconPosition: .left, action: { [weak self] c, f in - guard let self else { - f(.default) - return - } - - c?.dismiss(completion: { [weak self] in - guard let self else { - return - } - self.presentAddStoryFolder(addItems: [item]) - }) - }))) - - for folderPreview in folderPreviews { - var iconSource: ContextMenuActionItemIconSource? - if let story = folderPreview.item { - var imageSignal: Signal? - - var selectedMedia: Media? - if let image = story.media._asMedia() as? TelegramMediaImage { - selectedMedia = image - } else if let file = story.media._asMedia() as? TelegramMediaFile { - selectedMedia = file - } - - if let selectedMedia { - if let result = self.directMediaImageCache.getImage(peer: peerReference, story: story, media: selectedMedia, width: 24, aspectRatio: 1.0, possibleWidths: [24], includeBlurred: false, synchronous: true) { - if let loadSignal = result.loadSignal { - imageSignal = .single(result.image) |> then(loadSignal) - } else { - imageSignal = .single(result.image) - } - } - } - - if let imageSignal { - iconSource = ContextMenuActionItemIconSource( - size: CGSize(width: 24.0, height: 24.0), - cornerRadius: 5.0, - signal: imageSignal - ) - } - } - - var icon: (PresentationTheme) -> UIImage? = { _ in nil } - if iconSource == nil { - icon = { theme in - return generateImage(CGSize(width: 24.0, height: 24.0), opaque: false, scale: nil, rotatedContext: { size, context in - context.clear(CGRect(origin: CGPoint(), size: size)) - context.setFillColor(theme.contextMenu.primaryColor.withMultipliedAlpha(0.1).cgColor) - context.addPath(UIBezierPath(roundedRect: CGRect(origin: CGPoint(), size: size), cornerRadius: 5.0).cgPath) - context.fillPath() - }) - } - } - - items.append(.action(ContextMenuActionItem(text: folderPreview.folder.title, icon: icon, iconSource: iconSource, iconPosition: .left, action: { [weak self] c, f in - guard let self else { - f(.default) - return - } - - c?.dismiss(completion: {}) - - if let listSource = self.listSource as? PeerStoryListContext { - listSource.addToFolder(id: folderPreview.folder.id, items: [item]) - } - }))) - } - - c.pushItems(items: .single(ContextController.Items(content: .list(items)))) - } - }))) - } - items.append(.separator) - } - items.append(.action(ContextMenuActionItem(text: !isArchived ? self.presentationData.strings.StoryList_ItemAction_Archive : self.presentationData.strings.StoryList_ItemAction_Unarchive, icon: { theme in generateTintedImage(image: UIImage(bundleImageName: isArchived ? "Chat/Context Menu/Archive" : "Chat/Context Menu/Unarchive"), color: theme.contextMenu.primaryColor) }, action: { [weak self] _, f in guard let self else { f(.default) @@ -2883,12 +2745,7 @@ public final class PeerInfoStoryPaneNode: ASDisplayNode, PeerInfoPaneNode, ASScr title = self.presentationData.strings.BotPreviews_SubtitleEmpty } } else { - if state.isLoading { - title = self.presentationData.strings.BotPreviews_SubtitleLoading - } else { - //TODO:localize - title = "no stories" - } + title = "" } } else if case let .peer(_, isSaved, isArchived) = self.scope { if isSaved { @@ -2929,13 +2786,6 @@ public final class PeerInfoStoryPaneNode: ASDisplayNode, PeerInfoPaneNode, ASScr } botPreviewLanguages.sort(by: { $0.name < $1.name }) - var storyFolders = self.currentStoryFolders - for folder in state.availableFolders { - if !storyFolders.contains(where: { $0.id == folder.id }) && !self.removedStoryFolders.contains(folder.id) { - storyFolders.append(folder) - } - } - var hadLocalItems = false if let currentListState = self.currentListState { for item in currentListState.items { @@ -2963,9 +2813,8 @@ public final class PeerInfoStoryPaneNode: ASDisplayNode, PeerInfoPaneNode, ASScr self.updateItemsFromState(state: state, firstTime: firstTime, reloadAtTop: reloadAtTop, synchronous: synchronous, animated: false) - if self.currentBotPreviewLanguages != botPreviewLanguages || self.currentStoryFolders != storyFolders || reloadAtTop { + if self.currentBotPreviewLanguages != botPreviewLanguages || reloadAtTop { self.currentBotPreviewLanguages = botPreviewLanguages - self.currentStoryFolders = storyFolders if let (size, topInset, sideInset, bottomInset, deviceMetrics, visibleHeight, isScrollingLockedAtTop, expandProgress, navigationHeight, presentationData) = self.currentParams { self.update(size: size, topInset: topInset, sideInset: sideInset, bottomInset: bottomInset, deviceMetrics: deviceMetrics, visibleHeight: visibleHeight, isScrollingLockedAtTop: isScrollingLockedAtTop, expandProgress: expandProgress, navigationHeight: navigationHeight, presentationData: presentationData, synchronous: synchronous, transition: .immediate) } @@ -3023,11 +2872,7 @@ public final class PeerInfoStoryPaneNode: ASDisplayNode, PeerInfoPaneNode, ASScr isReorderable = !item.storyItem.isPending case let .peer(id, _, _): if id == self.context.account.peerId { - if self.currentStoryFolder != nil { - isReorderable = true - } else { - isReorderable = state.pinnedIds.contains(item.storyItem.id) - } + isReorderable = state.pinnedIds.contains(item.storyItem.id) } case let .search(peerId, _): if peerId != nil { @@ -3075,40 +2920,13 @@ public final class PeerInfoStoryPaneNode: ASDisplayNode, PeerInfoPaneNode, ASScr ) self.itemCount = state.totalCount - - var itemTabId: AnyHashable? - if let folder = self.currentStoryFolder { - itemTabId = AnyHashable(folder.id) - } - let previousItemTabId = self.itemTabId - self.itemTabId = itemTabId - - var animateDirection: Bool? - if firstTime { - if previousItemTabId == nil && itemTabId == nil { - } else if let previousItemTabId, let itemTabId { - let previousIndex = self.currentStoryFolders.firstIndex(where: { AnyHashable($0.id) == previousItemTabId }) - let updatedIndex = self.currentStoryFolders.firstIndex(where: { AnyHashable($0.id) == itemTabId }) - if let previousIndex, let updatedIndex { - animateDirection = updatedIndex > previousIndex - } - } else { - if previousItemTabId != nil { - if itemTabId == nil { - animateDirection = false - } - } else if itemTabId != nil { - animateDirection = true - } - } - } let currentSynchronous = synchronous && firstTime let currentReloadAtTop = reloadAtTop && firstTime - self.updateHistory(items: items, pinnedIds: Set(state.pinnedIds), synchronous: currentSynchronous, reloadAtTop: currentReloadAtTop, animated: animated, animateDirection: animateDirection) + self.updateHistory(items: items, pinnedIds: Set(state.pinnedIds), synchronous: currentSynchronous, reloadAtTop: currentReloadAtTop, animated: animated) } - private func updateHistory(items: SparseItemGrid.Items, pinnedIds: Set, synchronous: Bool, reloadAtTop: Bool, animated: Bool, animateDirection: Bool?) { + private func updateHistory(items: SparseItemGrid.Items, pinnedIds: Set, synchronous: Bool, reloadAtTop: Bool, animated: Bool) { var transition: ContainedViewLayoutTransition = .immediate if case .location = self.scope, let previousItems = self.items, previousItems.items.count == 0, previousItems.count != 0, items.items.count == 0, items.count == 0 { transition = .animated(duration: 0.3, curve: .spring) @@ -3119,58 +2937,18 @@ public final class PeerInfoStoryPaneNode: ASDisplayNode, PeerInfoPaneNode, ASScr if let (size, topInset, sideInset, bottomInset, deviceMetrics, visibleHeight, isScrollingLockedAtTop, expandProgress, navigationHeight, presentationData) = self.currentParams { var gridSnapshot: UIView? - var emptyStateSnapshot: UIView? - if animateDirection != nil { + if case .botPreview = scope { + } else if reloadAtTop { gridSnapshot = self.itemGrid.view.snapshotView(afterScreenUpdates: false) - - if let emptyStateView = self.emptyStateView?.view { - emptyStateSnapshot = emptyStateView.snapshotView(afterScreenUpdates: false) - emptyStateSnapshot?.frame = emptyStateView.frame - } - } else { - if case .botPreview = self.scope { - } else if !self.currentStoryFolders.isEmpty { - } else if case let .peer(id, _, isArchived) = self.scope, id == self.context.account.peerId, !isArchived { - } else if reloadAtTop { - gridSnapshot = self.itemGrid.view.snapshotView(afterScreenUpdates: false) - } } - - self.update(size: size, topInset: topInset, sideInset: sideInset, bottomInset: bottomInset, deviceMetrics: deviceMetrics, visibleHeight: visibleHeight, isScrollingLockedAtTop: isScrollingLockedAtTop, expandProgress: expandProgress, navigationHeight: navigationHeight, presentationData: presentationData, synchronous: false, transition: transition, animateGridItems: animated, animateBottomPanel: animateDirection != nil) + self.update(size: size, topInset: topInset, sideInset: sideInset, bottomInset: bottomInset, deviceMetrics: deviceMetrics, visibleHeight: visibleHeight, isScrollingLockedAtTop: isScrollingLockedAtTop, expandProgress: expandProgress, navigationHeight: navigationHeight, presentationData: presentationData, synchronous: false, transition: transition, animateGridItems: animated) self.updateSelectedItems(animated: false) - - if let gridSnapshot { - self.view.insertSubview(gridSnapshot, aboveSubview: self.contextGestureContainerNode.view) - gridSnapshot.frame = self.itemGrid.frame - if let animateDirection { - let directionFactor: CGFloat = animateDirection ? 1.0 : -1.0 - - let transition: ContainedViewLayoutTransition = .animated(duration: 0.4, curve: .spring) - transition.animatePositionAdditive(node: self.itemGrid, offset: CGPoint(x: size.width * directionFactor, y: 0.0)) - transition.animatePosition(layer: gridSnapshot.layer, from: CGPoint(), to: CGPoint(x: size.width * (-directionFactor), y: 0.0), removeOnCompletion: false, additive: true, completion: { [weak gridSnapshot] _ in - gridSnapshot?.removeFromSuperview() - }) - } else { - gridSnapshot.layer.animateAlpha(from: 1.0, to: 0.0, duration: 0.2, removeOnCompletion: false, completion: { [weak gridSnapshot] _ in - gridSnapshot?.removeFromSuperview() - }) - } - } - if let emptyStateSnapshot, let animateDirection { - self.view.insertSubview(emptyStateSnapshot, belowSubview: self.contextGestureContainerNode.view) - let directionFactor: CGFloat = animateDirection ? 1.0 : -1.0 - - let transition: ContainedViewLayoutTransition = .animated(duration: 0.4, curve: .spring) - transition.animatePosition(layer: emptyStateSnapshot.layer, from: CGPoint(), to: CGPoint(x: size.width * (-directionFactor), y: 0.0), removeOnCompletion: false, additive: true, completion: { [weak emptyStateSnapshot] _ in - emptyStateSnapshot?.removeFromSuperview() + if let gridSnapshot = gridSnapshot { + self.view.addSubview(gridSnapshot) + gridSnapshot.layer.animateAlpha(from: 1.0, to: 0.0, duration: 0.2, removeOnCompletion: false, completion: { [weak gridSnapshot] _ in + gridSnapshot?.removeFromSuperview() }) } - if let emptyStateView = self.emptyStateView?.view, let animateDirection { - let directionFactor: CGFloat = animateDirection ? 1.0 : -1.0 - - let transition: ContainedViewLayoutTransition = .animated(duration: 0.4, curve: .spring) - transition.animatePositionAdditive(layer: emptyStateView.layer, offset: CGPoint(x: size.width * directionFactor, y: 0.0)) - } } self.isEmptyUpdated(self.isEmpty) @@ -3187,14 +2965,11 @@ public final class PeerInfoStoryPaneNode: ASDisplayNode, PeerInfoPaneNode, ASScr if case .botPreview = self.scope { } else if case let .peer(id, _, _) = self.scope { if id == self.context.account.peerId { - if self.currentStoryFolder != nil { + let maxPinnedIndex = items.items.lastIndex(where: { ($0 as? VisualMediaItem)?.isPinned == true }) + if let maxPinnedIndex { + toIndex = min(toIndex, maxPinnedIndex) } else { - let maxPinnedIndex = items.items.lastIndex(where: { ($0 as? VisualMediaItem)?.isPinned == true }) - if let maxPinnedIndex { - toIndex = min(toIndex, maxPinnedIndex) - } else { - return - } + return } } } else { @@ -3606,10 +3381,8 @@ public final class PeerInfoStoryPaneNode: ASDisplayNode, PeerInfoPaneNode, ASScr if let _ = self.mapNode { self.updateMapLayout(size: currentParams.size, topInset: currentParams.topInset, bottomInset: currentParams.bottomInset, deviceMetrics: currentParams.deviceMetrics, transition: transition) } - if case let .peer(peerId, _, isArchived) = self.scope, peerId == self.context.account.peerId, !isArchived, self.isProfileEmbedded { - self.updateFolderTab(size: currentParams.size, topInset: currentParams.topInset, transition: transition) - } else if case .botPreview = self.scope, self.canManageStories { - self.updateFolderTab(size: currentParams.size, topInset: currentParams.topInset, transition: transition) + if case .botPreview = self.scope, self.canManageStories { + self.updateBotPreviewLanguageTab(size: currentParams.size, topInset: currentParams.topInset, transition: transition) self.updateBotPreviewFooter(size: currentParams.size, bottomInset: 0.0, transition: transition) } } @@ -3765,137 +3538,40 @@ public final class PeerInfoStoryPaneNode: ASDisplayNode, PeerInfoPaneNode, ASScr } } - private func updateFolderTab(size: CGSize, topInset: CGFloat, transition: ContainedViewLayoutTransition) { - var displayFolderTab = false - if case .botPreview = self.scope, self.canManageStories { - displayFolderTab = true - } else if case let .peer(peerId, _, isArchived) = self.scope, peerId == self.context.account.peerId, !isArchived, self.isProfileEmbedded { - displayFolderTab = true - } - - if !displayFolderTab { + private func updateBotPreviewLanguageTab(size: CGSize, topInset: CGFloat, transition: ContainedViewLayoutTransition) { + guard case .botPreview = self.scope, self.canManageStories else { return } - let folderTab: ComponentView - if let current = self.folderTab { - folderTab = current + let botPreviewLanguageTab: ComponentView + if let current = self.botPreviewLanguageTab { + botPreviewLanguageTab = current } else { - folderTab = ComponentView() - self.folderTab = folderTab + botPreviewLanguageTab = ComponentView() + self.botPreviewLanguageTab = botPreviewLanguageTab } - var folderItems: [TabSelectorComponent.Item] = [] - let mainTitle: String - let addTitle: String - if case .botPreview = self.scope { - mainTitle = self.presentationData.strings.BotPreviews_LanguageTab_Main - addTitle = self.presentationData.strings.BotPreviews_LanguageTab_Add - } else { - //TODO:localize - mainTitle = "All Stories" - addTitle = "+ Add Album" - } - folderItems.append(TabSelectorComponent.Item( + var languageItems: [TabSelectorComponent.Item] = [] + languageItems.append(TabSelectorComponent.Item( id: AnyHashable("_main"), - title: mainTitle + title: self.presentationData.strings.BotPreviews_LanguageTab_Main )) - - if case .botPreview = self.scope { - for language in self.currentBotPreviewLanguages { - folderItems.append(TabSelectorComponent.Item( - id: AnyHashable(language.id), - title: language.name - )) - } - } else { - for folder in self.currentStoryFolders { - folderItems.append(TabSelectorComponent.Item( - id: AnyHashable(folder.id), - title: folder.title, - isReorderable: self.canManageStories, - contextAction: self.canManageStories ? { [weak self] sourceNode, gesture in - guard let self else { - return - } - guard let sourceNode = sourceNode as? ContextExtractedContentContainingNode else { - return - } - guard let controller = self.parentController else { - return - } - - var items: [ContextMenuItem] = [] - - //TODO:localize - items.append(.action(ContextMenuActionItem(text: "Add Stories", icon: { theme in - return generateTintedImage(image: UIImage(bundleImageName: "Chat List/AddStoryIcon"), color: theme.contextMenu.primaryColor) - }, action: { [weak self] _, a in - guard let self else { - a(.default) - return - } - - a(.default) - - self.presentAddStoriesToFolder() - }))) - - //TODO:localize - items.append(.action(ContextMenuActionItem(text: "Reorder", icon: { theme in - return generateTintedImage(image: UIImage(bundleImageName: "Chat/Context Menu/ReorderItems"), color: theme.contextMenu.primaryColor) - }, action: { [weak self] _, a in - guard let self else { - a(.default) - return - } - - a(.default) - - self.beginReordering() - }))) - - //TODO:localize - items.append(.action(ContextMenuActionItem(text: "Delete Album", textColor: .destructive, icon: { theme in generateTintedImage(image: UIImage(bundleImageName: "Chat/Context Menu/Delete"), color: theme.contextMenu.destructiveColor) }, action: { [weak self] _, f in - guard let self else { - f(.default) - return - } - - f(.dismissWithoutContent) - - self.presentDeleteStoryFolder(id: folder.id) - }))) - - let presentationData = self.presentationData - let contextController = ContextController( - presentationData: presentationData, - source: .extracted(ItemExtractedContentSource( - sourceNode: sourceNode, - containerView: controller.view, - keepInPlace: false - )), - items: .single(ContextController.Items(content: .list(items))), - recognizer: nil, - gesture: gesture - ) - controller.presentInGlobalOverlay(contextController) - } : nil - )) - } + for language in self.currentBotPreviewLanguages { + languageItems.append(TabSelectorComponent.Item( + id: AnyHashable(language.id), + title: language.name + )) } - folderItems.append(TabSelectorComponent.Item( + languageItems.append(TabSelectorComponent.Item( id: AnyHashable("_add"), - title: addTitle + title: self.presentationData.strings.BotPreviews_LanguageTab_Add )) - var selectedId = AnyHashable("_main") + var selectedLanguageId = "_main" if let listSource = self.listSource as? BotPreviewStoryListContext, let language = listSource.language { - selectedId = AnyHashable(language) - } else if let listSource = self.listSource as? PeerStoryListContext, let folderId = listSource.folderId { - selectedId = AnyHashable(folderId) + selectedLanguageId = language } - let folderTabSize = folderTab.update( + let botPreviewLanguageTabSize = botPreviewLanguageTab.update( transition: ComponentTransition(transition), component: AnyComponent(TabSelectorComponent( colors: TabSelectorComponent.Colors( @@ -3908,95 +3584,39 @@ public final class PeerInfoStoryPaneNode: ASDisplayNode, PeerInfoPaneNode, ASScr spacing: 9.0, verticalInset: 11.0 ), - items: folderItems, - selectedId: selectedId, - reorderItem: self.isReordering ? { [weak self] fromId, toId in - guard let self else { - return - } - guard let sourceId = fromId.base as? Int64 else { - return - } - guard let targetId = toId.base as? Int64 else { - return - } - guard let sourceIndex = self.currentStoryFolders.firstIndex(where: { $0.id == sourceId }), let targetIndex = self.currentStoryFolders.firstIndex(where: { $0.id == targetId }) else { - return - } - let folder = self.currentStoryFolders[sourceIndex] - if targetIndex < sourceIndex { - self.currentStoryFolders.remove(at: sourceIndex) - self.currentStoryFolders.insert(folder, at: targetIndex) - } else { - self.currentStoryFolders.insert(folder, at: targetIndex + 1) - self.currentStoryFolders.remove(at: sourceIndex) - } - - self.update(transition: .animated(duration: 0.2, curve: .easeInOut)) - } : nil, + items: languageItems, + selectedId: AnyHashable(selectedLanguageId), setSelectedId: { [weak self] id in - guard let self else { + guard let self, let id = id.base as? String else { return } - - self.expandIfNeeded?() - - if let id = id.base as? String { - if id == "_add" { - if case .botPreview = self.scope { - self.presentAddBotPreviewLanguage() - } else { - self.presentAddStoryFolder() - } - } else if id == "_main" { - if case .botPreview = self.scope { - self.setBotPreviewLanguage(id: nil, assumeEmpty: false) - } else { - self.setStoryFolder(id: nil, assumeEmpty: false) - } - } else if let language = self.currentBotPreviewLanguages.first(where: { $0.id == id }) { - self.setBotPreviewLanguage(id: language.id, assumeEmpty: false) - } - } else if let id = id.base as? Int64 { - if let folder = self.currentStoryFolders.first(where: { $0.id == id }) { - self.setStoryFolder(id: folder.id, assumeEmpty: false) - } + if id == "_add" { + self.presentAddBotPreviewLanguage() + } else if id == "_main" { + self.setBotPreviewLanguage(id: nil, assumeEmpty: false) + } else if let language = self.currentBotPreviewLanguages.first(where: { $0.id == id }) { + self.setBotPreviewLanguage(id: language.id, assumeEmpty: false) } } )), environment: {}, containerSize: CGSize(width: size.width, height: 44.0) ) - var folderTabFrame = CGRect(origin: CGPoint(x: floor((size.width - folderTabSize.width) * 0.5), y: topInset - 11.0), size: folderTabSize) + var botPreviewLanguageTabFrame = CGRect(origin: CGPoint(x: floor((size.width - botPreviewLanguageTabSize.width) * 0.5), y: topInset - 11.0), size: botPreviewLanguageTabSize) let effectiveScrollingOffset: CGFloat effectiveScrollingOffset = self.itemGrid.scrollingOffset - folderTabFrame.origin.y -= effectiveScrollingOffset + botPreviewLanguageTabFrame.origin.y -= effectiveScrollingOffset let isSelectingOrReordering = self.isReordering || self.itemInteraction.selectedIds != nil - if let folderTabView = folderTab.view { - if folderTabView.superview == nil { - self.view.addSubview(folderTabView) + if let botPreviewLanguageTabView = botPreviewLanguageTab.view { + if botPreviewLanguageTabView.superview == nil { + self.view.addSubview(botPreviewLanguageTabView) } - transition.updateFrame(view: folderTabView, frame: folderTabFrame) - - var areTabsDisabled = false - - if case .botPreview = self.scope { - if isSelectingOrReordering { - areTabsDisabled = true - } - } else { - if self.itemInteraction.selectedIds != nil { - areTabsDisabled = true - } - } - - transition.updateAlpha(layer: folderTabView.layer, alpha: areTabsDisabled ? 0.5 : 1.0) - folderTabView.isUserInteractionEnabled = !areTabsDisabled - - folderTabView.disablesInteractiveTransitionGestureRecognizer = self.isReordering + transition.updateFrame(view: botPreviewLanguageTabView, frame: botPreviewLanguageTabFrame) + transition.updateAlpha(layer: botPreviewLanguageTabView.layer, alpha: isSelectingOrReordering ? 0.5 : 1.0) + botPreviewLanguageTabView.isUserInteractionEnabled = !isSelectingOrReordering } } @@ -4072,10 +3692,10 @@ public final class PeerInfoStoryPaneNode: ASDisplayNode, PeerInfoPaneNode, ASScr } public func update(size: CGSize, topInset: CGFloat, sideInset: CGFloat, bottomInset: CGFloat, deviceMetrics: DeviceMetrics, visibleHeight: CGFloat, isScrollingLockedAtTop: Bool, expandProgress: CGFloat, navigationHeight: CGFloat, presentationData: PresentationData, synchronous: Bool, transition: ContainedViewLayoutTransition) { - self.update(size: size, topInset: topInset, sideInset: sideInset, bottomInset: bottomInset, deviceMetrics: deviceMetrics, visibleHeight: visibleHeight, isScrollingLockedAtTop: isScrollingLockedAtTop, expandProgress: expandProgress, navigationHeight: navigationHeight, presentationData: presentationData, synchronous: synchronous, transition: transition, animateGridItems: false, animateBottomPanel: transition.isAnimated) + self.update(size: size, topInset: topInset, sideInset: sideInset, bottomInset: bottomInset, deviceMetrics: deviceMetrics, visibleHeight: visibleHeight, isScrollingLockedAtTop: isScrollingLockedAtTop, expandProgress: expandProgress, navigationHeight: navigationHeight, presentationData: presentationData, synchronous: synchronous, transition: transition, animateGridItems: false) } - private func update(size: CGSize, topInset: CGFloat, sideInset: CGFloat, bottomInset: CGFloat, deviceMetrics: DeviceMetrics, visibleHeight: CGFloat, isScrollingLockedAtTop: Bool, expandProgress: CGFloat, navigationHeight: CGFloat, presentationData: PresentationData, synchronous: Bool, transition: ContainedViewLayoutTransition, animateGridItems: Bool, animateBottomPanel: Bool) { + private func update(size: CGSize, topInset: CGFloat, sideInset: CGFloat, bottomInset: CGFloat, deviceMetrics: DeviceMetrics, visibleHeight: CGFloat, isScrollingLockedAtTop: Bool, expandProgress: CGFloat, navigationHeight: CGFloat, presentationData: PresentationData, synchronous: Bool, transition: ContainedViewLayoutTransition, animateGridItems: Bool) { self.currentParams = (size, topInset, sideInset, bottomInset, deviceMetrics, visibleHeight, isScrollingLockedAtTop, expandProgress, navigationHeight, presentationData) var gridTopInset = topInset @@ -4109,15 +3729,7 @@ public final class PeerInfoStoryPaneNode: ASDisplayNode, PeerInfoPaneNode, ASScr mapOptionsNode.updateLayout(size: mapOptionsFrame.size, leftInset: sideInset, rightInset: sideInset, transition: transition) } - var hasBarBackground = false - if self.isProfileEmbedded { - if case .botPreview = self.scope { - hasBarBackground = true - } else if case let .peer(id, _, isArchived) = self.scope, id == self.context.account.peerId, !isArchived { - hasBarBackground = true - } - } - if hasBarBackground { + if self.isProfileEmbedded, case .botPreview = self.scope { let barBackgroundLayer: SimpleLayer if let current = self.barBackgroundLayer { barBackgroundLayer = current @@ -4133,29 +3745,15 @@ public final class PeerInfoStoryPaneNode: ASDisplayNode, PeerInfoPaneNode, ASScr var listBottomInset = bottomInset var bottomInset = bottomInset - var displayFolderTab = false if case .botPreview = self.scope, self.canManageStories { - displayFolderTab = true - } else if case let .peer(peerId, _, isArchived) = self.scope, peerId == self.context.account.peerId, !isArchived, self.isProfileEmbedded { - displayFolderTab = true - } - - if displayFolderTab { - var folderTabsTransition = transition - if animateBottomPanel && !folderTabsTransition.isAnimated { - folderTabsTransition = .animated(duration: 0.4, curve: .spring) - } - - updateFolderTab(size: size, topInset: topInset, transition: folderTabsTransition) + updateBotPreviewLanguageTab(size: size, topInset: topInset, transition: transition) gridTopInset += 50.0 - if case .botPreview = self.scope { - updateBotPreviewFooter(size: size, bottomInset: 0.0, transition: transition) - if let botPreviewFooterView = self.botPreviewFooter?.view { + updateBotPreviewFooter(size: size, bottomInset: 0.0, transition: transition) + if let botPreviewFooterView = self.botPreviewFooter?.view { listBottomInset += 18.0 + botPreviewFooterView.bounds.height } } - } if self.isProfileEmbedded, let selectedIds = self.itemInteraction.selectedIds, self.canManageStories, case let .peer(peerId, _, isArchived) = self.scope { let selectionPanel: ComponentView @@ -4335,206 +3933,13 @@ public final class PeerInfoStoryPaneNode: ASDisplayNode, PeerInfoPaneNode, ASScr } else if let selectionPanel = self.selectionPanel { self.selectionPanel = nil if let selectionPanelView = selectionPanel.view { - transition.updateFrame(view: selectionPanelView, frame: CGRect(origin: CGPoint(x: 0.0, y: size.height), size: selectionPanelView.bounds.size), completion: { [weak selectionPanelView] _ in - selectionPanelView?.removeFromSuperview() - }) - } - } - - var actionPanelGeneralTransition: ComponentTransition - if animateBottomPanel && !transition.isAnimated { - actionPanelGeneralTransition = .spring(duration: 0.4) - } else { - actionPanelGeneralTransition = ComponentTransition(transition) - } - if self.selectionPanel == nil, self.isProfileEmbedded, self.canManageStories, case let .peer(peerId, _, isArchived) = self.scope, peerId == self.context.account.peerId, !isArchived, self.isProfileEmbedded, self.currentStoryFolder != nil, let items = self.items, !items.items.isEmpty { - let actionPanel: ComponentView - var actionPanelTransition = ComponentTransition(transition) - if let current = self.actionPanel { - actionPanel = current - } else { - actionPanelTransition = actionPanelTransition.withAnimation(.none) - actionPanel = ComponentView() - self.actionPanel = actionPanel - } - - //TODO:localize - let actionPanelSize = actionPanel.update( - transition: actionPanelTransition, - component: AnyComponent(BottomButtonPanelComponent( - theme: presentationData.theme, - title: "Add Stories", - label: nil, - isEnabled: true, - insets: UIEdgeInsets(top: 0.0, left: sideInset + 12.0, bottom: bottomInset, right: sideInset + 12.0), - action: { [weak self] in - guard let self else { - return - } - self.presentAddStoriesToFolder() - } - )), - environment: {}, - containerSize: size - ) - let actionPanelFrame = CGRect(origin: CGPoint(x: 0.0, y: size.height - actionPanelSize.height), size: actionPanelSize) - if let actionPanelView = actionPanel.view { - if actionPanelView.superview == nil { - self.view.addSubview(actionPanelView) - actionPanelGeneralTransition.animatePosition(layer: actionPanelView.layer, from: CGPoint(x: 0.0, y: actionPanelFrame.height), to: CGPoint(), additive: true) - } - actionPanelTransition.setFrame(view: actionPanelView, frame: actionPanelFrame) - } - bottomInset = actionPanelSize.height - listBottomInset += actionPanelSize.height - } else if let actionPanel = self.actionPanel { - self.actionPanel = nil - if let actionPanelView = actionPanel.view { - actionPanelGeneralTransition.setFrame(view: actionPanelView, frame: CGRect(origin: CGPoint(x: 0.0, y: size.height), size: actionPanelView.bounds.size), completion: { [weak actionPanelView] _ in - actionPanelView?.removeFromSuperview() - }) + transition.updateFrame(view: selectionPanelView, frame: CGRect(origin: CGPoint(x: 0.0, y: size.height), size: selectionPanelView.bounds.size)) } } transition.updateFrame(node: self.contextGestureContainerNode, frame: CGRect(origin: CGPoint(x: 0.0, y: 0.0), size: CGSize(width: size.width, height: size.height))) - if case let .peer(peerId, _, isArchived) = self.scope, let items = self.items, items.items.isEmpty, items.count == 0 { - if peerId == self.context.account.peerId, self.isProfileEmbedded, self.currentStoryFolder != nil { - let emptyStateView: ComponentView - var emptyStateTransition = ComponentTransition(transition) - if let current = self.emptyStateView { - emptyStateView = current - } else { - emptyStateTransition = .immediate - emptyStateView = ComponentView() - self.emptyStateView = emptyStateView - } - - //TODO:localize - let emptyStateSize = emptyStateView.update( - transition: emptyStateTransition, - component: AnyComponent(EmptyStateIndicatorComponent( - context: self.context, - theme: presentationData.theme, - fitToHeight: self.isProfileEmbedded, - animationName: nil, - title: "Organize Your Stories", - text: "Add some stories to this album.", - actionTitle: "Add to Album", - action: { [weak self] in - guard let self else { - return - } - self.presentAddStoriesToFolder() - }, - additionalActionTitle: nil, - additionalAction: {}, - additionalActionSeparator: nil - )), - environment: {}, - containerSize: CGSize(width: size.width, height: size.height - gridTopInset - bottomInset) - ) - - let emptyStateFrame: CGRect - if self.isProfileEmbedded { - emptyStateFrame = CGRect(origin: CGPoint(x: floor((size.width - emptyStateSize.width) * 0.5), y: max(gridTopInset + 22.0, floor((visibleHeight - bottomInset - emptyStateSize.height) * 0.5))), size: emptyStateSize) - } else { - emptyStateFrame = CGRect(origin: CGPoint(x: floor((size.width - emptyStateSize.width) * 0.5), y: gridTopInset), size: emptyStateSize) - } - - if let emptyStateComponentView = emptyStateView.view { - if emptyStateComponentView.superview == nil { - self.view.addSubview(emptyStateComponentView) - if self.didUpdateItemsOnce { - emptyStateComponentView.layer.animateAlpha(from: 0.0, to: 1.0, duration: 0.2) - } - } - emptyStateTransition.setFrame(view: emptyStateComponentView, frame: emptyStateFrame) - } - - let backgroundColor: UIColor - if self.isProfileEmbedded, case .botPreview = self.scope { - backgroundColor = presentationData.theme.list.blocksBackgroundColor - } else if self.isProfileEmbedded { - backgroundColor = presentationData.theme.list.blocksBackgroundColor - } else { - backgroundColor = presentationData.theme.list.blocksBackgroundColor - } - - if self.didUpdateItemsOnce { - ComponentTransition(animation: .curve(duration: 0.2, curve: .easeInOut)).setBackgroundColor(view: self.view, color: backgroundColor) - } else { - self.view.backgroundColor = backgroundColor - } - } else { - let emptyStateView: ComponentView - var emptyStateTransition = ComponentTransition(transition) - if let current = self.emptyStateView { - emptyStateView = current - } else { - emptyStateTransition = .immediate - emptyStateView = ComponentView() - self.emptyStateView = emptyStateView - } - let emptyStateSize = emptyStateView.update( - transition: emptyStateTransition, - component: AnyComponent(EmptyStateIndicatorComponent( - context: self.context, - theme: presentationData.theme, - fitToHeight: self.isProfileEmbedded, - animationName: "StoryListEmpty", - title: isArchived ? presentationData.strings.StoryList_ArchivedEmptyState_Title : presentationData.strings.StoryList_SavedEmptyPosts_Title, - text: isArchived ? presentationData.strings.StoryList_ArchivedEmptyState_Text : presentationData.strings.StoryList_SavedEmptyPosts_Text, - actionTitle: isArchived ? nil : presentationData.strings.StoryList_SavedAddAction, - action: { [weak self] in - guard let self else { - return - } - self.emptyAction?() - }, - additionalActionTitle: (isArchived || self.isProfileEmbedded) ? nil : presentationData.strings.StoryList_SavedEmptyAction, - additionalAction: { [weak self] in - guard let self else { - return - } - self.additionalEmptyAction?() - } - )), - environment: {}, - containerSize: CGSize(width: size.width, height: size.height - gridTopInset - bottomInset) - ) - - let emptyStateFrame: CGRect - if self.isProfileEmbedded { - emptyStateFrame = CGRect(origin: CGPoint(x: floor((size.width - emptyStateSize.width) * 0.5), y: max(gridTopInset, floor((visibleHeight - gridTopInset - bottomInset - emptyStateSize.height) * 0.5))), size: emptyStateSize) - } else { - emptyStateFrame = CGRect(origin: CGPoint(x: floor((size.width - emptyStateSize.width) * 0.5), y: gridTopInset), size: emptyStateSize) - } - - if let emptyStateComponentView = emptyStateView.view { - if emptyStateComponentView.superview == nil { - self.view.addSubview(emptyStateComponentView) - if self.didUpdateItemsOnce { - emptyStateComponentView.layer.animateAlpha(from: 0.0, to: 1.0, duration: 0.2) - } - } - emptyStateTransition.setFrame(view: emptyStateComponentView, frame: emptyStateFrame) - } - - let backgroundColor: UIColor - if self.isProfileEmbedded { - backgroundColor = presentationData.theme.list.plainBackgroundColor - } else { - backgroundColor = presentationData.theme.list.blocksBackgroundColor - } - - if self.didUpdateItemsOnce { - ComponentTransition(animation: .curve(duration: 0.2, curve: .easeInOut)).setBackgroundColor(view: self.view, color: backgroundColor) - } else { - self.view.backgroundColor = backgroundColor - } - } - } else if case .botPreview = self.scope, let items = self.items, items.items.isEmpty, items.count == 0 { + if case let .peer(_, _, isArchived) = self.scope, let items = self.items, items.items.isEmpty, items.count == 0 { let emptyStateView: ComponentView var emptyStateTransition = ComponentTransition(transition) if let current = self.emptyStateView { @@ -4544,44 +3949,29 @@ public final class PeerInfoStoryPaneNode: ASDisplayNode, PeerInfoPaneNode, ASScr emptyStateView = ComponentView() self.emptyStateView = emptyStateView } - - var isMainLanguage = true - if let listSource = self.listSource as? BotPreviewStoryListContext, let _ = listSource.language { - isMainLanguage = false - } - let emptyStateSize = emptyStateView.update( transition: emptyStateTransition, component: AnyComponent(EmptyStateIndicatorComponent( context: self.context, theme: presentationData.theme, fitToHeight: self.isProfileEmbedded, - animationName: nil, - title: presentationData.strings.BotPreviews_Empty_Title, - text: presentationData.strings.BotPreviews_Empty_Text(Int32(self.maxBotPreviewCount)), - actionTitle: self.canManageStories ? presentationData.strings.BotPreviews_Empty_Add : nil, + animationName: "StoryListEmpty", + title: isArchived ? presentationData.strings.StoryList_ArchivedEmptyState_Title : presentationData.strings.StoryList_SavedEmptyPosts_Title, + text: isArchived ? presentationData.strings.StoryList_ArchivedEmptyState_Text : presentationData.strings.StoryList_SavedEmptyPosts_Text, + actionTitle: isArchived ? nil : presentationData.strings.StoryList_SavedAddAction, action: { [weak self] in guard let self else { return } - if self.canAddMoreBotPreviews() { - self.emptyAction?() - } else { - self.presentUnableToAddMorePreviewsAlert() - } + self.emptyAction?() }, - additionalActionTitle: self.canManageStories ? (isMainLanguage ? presentationData.strings.BotPreviews_Empty_AddTranslation : presentationData.strings.BotPreviews_Empty_DeleteTranslation) : nil, + additionalActionTitle: (isArchived || self.isProfileEmbedded) ? nil : presentationData.strings.StoryList_SavedEmptyAction, additionalAction: { [weak self] in guard let self else { return } - if isMainLanguage { - self.presentAddBotPreviewLanguage() - } else { - self.presentDeleteBotPreviewLanguage() - } - }, - additionalActionSeparator: self.canManageStories ? presentationData.strings.BotPreviews_Empty_Separator : nil + self.additionalEmptyAction?() + } )), environment: {}, containerSize: CGSize(width: size.width, height: size.height - gridTopInset - bottomInset) @@ -4589,7 +3979,7 @@ public final class PeerInfoStoryPaneNode: ASDisplayNode, PeerInfoPaneNode, ASScr let emptyStateFrame: CGRect if self.isProfileEmbedded { - emptyStateFrame = CGRect(origin: CGPoint(x: floor((size.width - emptyStateSize.width) * 0.5), y: max(gridTopInset + 22.0, floor((visibleHeight - gridTopInset - bottomInset - emptyStateSize.height) * 0.5))), size: emptyStateSize) + emptyStateFrame = CGRect(origin: CGPoint(x: floor((size.width - emptyStateSize.width) * 0.5), y: max(gridTopInset, floor((visibleHeight - gridTopInset - bottomInset - emptyStateSize.height) * 0.5))), size: emptyStateSize) } else { emptyStateFrame = CGRect(origin: CGPoint(x: floor((size.width - emptyStateSize.width) * 0.5), y: gridTopInset), size: emptyStateSize) } @@ -4605,10 +3995,8 @@ public final class PeerInfoStoryPaneNode: ASDisplayNode, PeerInfoPaneNode, ASScr } let backgroundColor: UIColor - if self.isProfileEmbedded, case .botPreview = self.scope { - backgroundColor = presentationData.theme.list.blocksBackgroundColor - } else if self.isProfileEmbedded { - backgroundColor = presentationData.theme.list.blocksBackgroundColor + if self.isProfileEmbedded { + backgroundColor = presentationData.theme.list.plainBackgroundColor } else { backgroundColor = presentationData.theme.list.blocksBackgroundColor } @@ -4618,7 +4006,7 @@ public final class PeerInfoStoryPaneNode: ASDisplayNode, PeerInfoPaneNode, ASScr } else { self.view.backgroundColor = backgroundColor } - } else if case let .peer(peerId, _, isArchived) = self.scope, peerId == self.context.account.peerId, !isArchived, self.isProfileEmbedded, let items = self.items, items.items.isEmpty, items.count == 0 { + } else if case .botPreview = self.scope, let items = self.items, items.items.isEmpty, items.count == 0 { let emptyStateView: ComponentView var emptyStateTransition = ComponentTransition(transition) if let current = self.emptyStateView { @@ -4716,8 +4104,6 @@ public final class PeerInfoStoryPaneNode: ASDisplayNode, PeerInfoPaneNode, ASScr if self.isProfileEmbedded, case .botPreview = self.scope { subTransition.setBackgroundColor(view: self.view, color: presentationData.theme.list.blocksBackgroundColor) - } else if self.isProfileEmbedded, case let .peer(peerId, _, isArchived) = self.scope, peerId == self.context.account.peerId, !isArchived, self.isProfileEmbedded { - subTransition.setBackgroundColor(view: self.view, color: presentationData.theme.list.blocksBackgroundColor) } else if self.isProfileEmbedded { subTransition.setBackgroundColor(view: self.view, color: presentationData.theme.list.plainBackgroundColor) } else { @@ -4726,8 +4112,6 @@ public final class PeerInfoStoryPaneNode: ASDisplayNode, PeerInfoPaneNode, ASScr } else { if self.isProfileEmbedded, case .botPreview = self.scope { self.view.backgroundColor = presentationData.theme.list.blocksBackgroundColor - } else if self.isProfileEmbedded, case let .peer(peerId, _, isArchived) = self.scope, peerId == self.context.account.peerId, self.isProfileEmbedded, !isArchived { - self.view.backgroundColor = presentationData.theme.list.blocksBackgroundColor } else { if case let .search(peerId, _) = self.scope, peerId != nil { @@ -4751,8 +4135,6 @@ public final class PeerInfoStoryPaneNode: ASDisplayNode, PeerInfoPaneNode, ASScr var adjustForSmallCount = true if case .botPreview = self.scope { adjustForSmallCount = false - } else if self.currentStoryFolder != nil { - adjustForSmallCount = false } self.itemGrid.pinchEnabled = items.count > 2 && !self.isReordering @@ -4855,21 +4237,10 @@ public final class PeerInfoStoryPaneNode: ASDisplayNode, PeerInfoPaneNode, ASScr } public func canReorder() -> Bool { - if case .botPreview = self.scope { - guard let items = self.items else { - return false - } - return items.count > 1 - } else { - if self.currentStoryFolder == nil { - return false - } - - guard let items = self.items else { - return false - } - return items.count > 1 + guard let items = self.items else { + return false } + return items.count > 1 } private func presentAddBotPreviewLanguage() { @@ -4882,90 +4253,6 @@ public final class PeerInfoStoryPaneNode: ASDisplayNode, PeerInfoPaneNode, ASScr })) } - private func presentAddStoryFolder(addItems: [EngineStoryItem] = []) { - //TODO:localize - let promptController = promptController( - sharedContext: self.context.sharedContext, - updatedPresentationData: nil, - text: "Create a New Album", - titleFont: .bold, - subtitle: "Choose a name for your album and start adding your stories there.", - value: "", - placeholder: "Title", - characterLimit: 20, - displayCharacterLimit: true, - apply: { [weak self] value in - guard let self else { - return - } - if let value { - if let listSource = self.listSource as? PeerStoryListContext { - listSource.addFolder(title: value, completion: { [weak self] id in - Queue.mainQueue().async { - guard let self, let listSource = self.listSource as? PeerStoryListContext else { - return - } - if !addItems.isEmpty { - listSource.addToFolder(id: id, items: addItems) - } - self.setStoryFolder(id: id, assumeEmpty: addItems.isEmpty) - } - }) - } - } - } - ) - self.parentController?.present(promptController, in: .window(.root)) - } - - private func presentAddStoriesToFolder() { - guard case let .peer(peerId, _, _) = self.scope else { - return - } - guard let folder = self.currentStoryFolder else { - return - } - - let controller = self.context.sharedContext.makeStorySelectionController(context: self.context, peerId: peerId, completion: { [weak self] items in - guard let self else { - return - } - if let listSource = self.listSource as? PeerStoryListContext { - listSource.addToFolder(id: folder.id, items: items) - } - }) - controller.navigationPresentation = .modal - - self.parentController?.push(controller) - } - - public func presentDeleteCurrentStoryFolder() { - if let folder = self.currentStoryFolder { - self.presentDeleteStoryFolder(id: folder.id) - } - } - - private func presentDeleteStoryFolder(id: Int64) { - guard let folder = self.currentStoryFolders.first(where: { $0.id == id }) else { - return - } - let _ = folder - - if self.currentStoryFolder?.id == id { - self.setStoryFolder(id: nil, assumeEmpty: false) - } - self.currentStoryFolders.removeAll(where: { $0.id == id }) - self.removedStoryFolders.insert(id) - - if let listContext = self.listSource as? PeerStoryListContext { - listContext.removeFolder(id: id) - } - - if let (size, topInset, sideInset, bottomInset, deviceMetrics, visibleHeight, isScrollingLockedAtTop, expandProgress, navigationHeight, presentationData) = self.currentParams { - self.update(size: size, topInset: topInset, sideInset: sideInset, bottomInset: bottomInset, deviceMetrics: deviceMetrics, visibleHeight: visibleHeight, isScrollingLockedAtTop: isScrollingLockedAtTop, expandProgress: expandProgress, navigationHeight: navigationHeight, presentationData: presentationData, synchronous: false, transition: .immediate) - } - } - public func presentUnableToAddMorePreviewsAlert() { self.parentController?.present(standardTextAlertController(theme: AlertControllerTheme(presentationData: self.presentationData), title: nil, text: self.presentationData.strings.BotPreviews_AlertTooManyPreviews(Int32(self.maxBotPreviewCount)), actions: [ TextAlertAction(type: .defaultAction, title: self.presentationData.strings.Common_OK, action: { @@ -5051,32 +4338,12 @@ public final class PeerInfoStoryPaneNode: ASDisplayNode, PeerInfoPaneNode, ASScr } if let id { - if let cachedListSource = self.cachedListSources[AnyHashable(id)] { + if let cachedListSource = self.cachedListSources[id] { self.listSource = cachedListSource } else { let listSource = BotPreviewStoryListContext(account: self.context.account, engine: self.context.engine, peerId: peerId, language: id, assumeEmpty: assumeEmpty) self.listSource = listSource - self.cachedListSources[AnyHashable(id)] = listSource - } - } else { - self.listSource = self.defaultListSource - } - - self.requestHistoryAroundVisiblePosition(synchronous: false, reloadAtTop: true) - } - - private func setStoryFolder(id: Int64?, assumeEmpty: Bool) { - if let listSource = self.listSource as? PeerStoryListContext, listSource.folderId == id { - return - } - - if let id { - if let cachedListSource = self.cachedListSources[AnyHashable(id)] { - self.listSource = cachedListSource - } else { - let listSource = PeerStoryListContext(account: self.context.account, peerId: self.context.account.peerId, isArchived: false, folderId: id) - self.listSource = listSource - //self.cachedListSources[AnyHashable(id)] = listSource + self.cachedListSources[id] = listSource } } else { self.listSource = self.defaultListSource @@ -5109,12 +4376,6 @@ public final class PeerInfoStoryPaneNode: ASDisplayNode, PeerInfoPaneNode, ASScr self.itemGrid.setReordering(isReordering: isReordering) - if !isReordering && !self.currentStoryFolders.isEmpty && self.canManageStories { - if let listSource = self.listSource as? PeerStoryListContext { - listSource.reorderFolders(ids: self.currentStoryFolders.map(\.id)) - } - } - if !isReordering, let reorderedIds = self.reorderedIds { self.reorderedIds = nil if case .botPreview = self.scope, let listSource = self.listSource as? BotPreviewStoryListContext { @@ -5130,26 +4391,20 @@ public final class PeerInfoStoryPaneNode: ASDisplayNode, PeerInfoPaneNode, ASScr listSource.reorderItems(media: reorderedMedia) } } else if case let .peer(id, _, _) = self.scope, id == self.context.account.peerId, let items = self.items { - if let _ = self.currentStoryFolder { - if let listSource = self.listSource as? PeerStoryListContext { - listSource.reorderItemsInFolder(itemIds: reorderedIds.map { $0.id }) - } - } else { - var updatedPinnedIds: [Int32] = [] - for id in reorderedIds { - inner: for item in items.items { - if let item = item as? VisualMediaItem { - if item.storyId == id { - if item.isPinned { - updatedPinnedIds.append(id.id) - break inner - } + var updatedPinnedIds: [Int32] = [] + for id in reorderedIds { + inner: for item in items.items { + if let item = item as? VisualMediaItem { + if item.storyId == id { + if item.isPinned { + updatedPinnedIds.append(id.id) + break inner } } } } - let _ = self.context.engine.messages.updatePinnedToTopStories(peerId: id, ids: updatedPinnedIds).startStandalone() } + let _ = self.context.engine.messages.updatePinnedToTopStories(peerId: id, ids: updatedPinnedIds).startStandalone() } } @@ -5507,34 +4762,3 @@ private final class BottomActionsPanelComponent: Component { } } -private final class ItemExtractedContentSource: ContextExtractedContentSource { - let keepInPlace: Bool - let ignoreContentTouches: Bool = true - let blurBackground: Bool = true - let adjustContentForSideInset: Bool = true - - private let sourceNode: ContextExtractedContentContainingNode - private weak var containerView: UIView? - - init(sourceNode: ContextExtractedContentContainingNode, containerView: UIView, keepInPlace: Bool) { - self.sourceNode = sourceNode - self.containerView = containerView - self.keepInPlace = keepInPlace - } - - func takeView() -> ContextControllerTakeViewInfo? { - var contentArea: CGRect? - if let containerView = self.containerView { - contentArea = containerView.convert(containerView.bounds, to: nil) - } - - return ContextControllerTakeViewInfo( - containingItem: .node(self.sourceNode), - contentAreaInScreenSpace: contentArea ?? UIScreen.main.bounds - ) - } - - func putBack() -> ContextControllerPutBackViewInfo? { - return ContextControllerPutBackViewInfo(contentAreaInScreenSpace: UIScreen.main.bounds) - } -}