diff --git a/submodules/AccountContext/Sources/AccountContext.swift b/submodules/AccountContext/Sources/AccountContext.swift index 2df656d83a..cf314b5f76 100644 --- a/submodules/AccountContext/Sources/AccountContext.swift +++ b/submodules/AccountContext/Sources/AccountContext.swift @@ -886,7 +886,7 @@ public protocol MediaEditorScreenResult { public protocol TelegramRootControllerInterface: NavigationController { @discardableResult func openStoryCamera(customTarget: Stories.PendingTarget?, transitionIn: StoryCameraTransitionIn?, transitionedIn: @escaping () -> Void, transitionOut: @escaping (Stories.PendingTarget?, Bool) -> StoryCameraTransitionOut?) -> StoryCameraTransitionInCoordinator? - func proceedWithStoryUpload(target: Stories.PendingTarget, results: [MediaEditorScreenResult], existingMedia: EngineMedia?, forwardInfo: Stories.PendingForwardInfo?, folders: [Int64], externalState: MediaEditorTransitionOutExternalState, commit: @escaping (@escaping () -> Void) -> Void) + func proceedWithStoryUpload(target: Stories.PendingTarget, results: [MediaEditorScreenResult], existingMedia: EngineMedia?, forwardInfo: Stories.PendingForwardInfo?, externalState: MediaEditorTransitionOutExternalState, commit: @escaping (@escaping () -> Void) -> Void) func getContactsController() -> ViewController? func getChatsController() -> ViewController? diff --git a/submodules/PremiumUI/Sources/CreateGiveawayController.swift b/submodules/PremiumUI/Sources/CreateGiveawayController.swift index cb1b3ce206..b7ebc06d50 100644 --- a/submodules/PremiumUI/Sources/CreateGiveawayController.swift +++ b/submodules/PremiumUI/Sources/CreateGiveawayController.swift @@ -1550,7 +1550,7 @@ public func createGiveawayController(context: AccountContext, updatedPresentatio context: context, initialPrivacy: EngineStoryPrivacy(base: .nobody, additionallyIncludePeers: state.peers), stateContext: stateContext, - completion: { _, privacy ,_, _, _, _ in + completion: { _, privacy ,_, _, _, _, _ in updateState { state in var updatedState = state updatedState.peers = privacy.additionallyIncludePeers @@ -1589,7 +1589,7 @@ public func createGiveawayController(context: AccountContext, updatedPresentatio context: context, initialPrivacy: EngineStoryPrivacy(base: .nobody, additionallyIncludePeers: state.peers), stateContext: stateContext, - completion: { _, privacy ,_, _, _, _ in + completion: { _, privacy ,_, _, _, _, _ in updateState { state in var updatedState = state updatedState.channels = privacy.additionallyIncludePeers diff --git a/submodules/TelegramCore/Sources/TelegramEngine/Messages/StoryListContext.swift b/submodules/TelegramCore/Sources/TelegramEngine/Messages/StoryListContext.swift index 3bbe83849f..1500524266 100644 --- a/submodules/TelegramCore/Sources/TelegramEngine/Messages/StoryListContext.swift +++ b/submodules/TelegramCore/Sources/TelegramEngine/Messages/StoryListContext.swift @@ -1486,6 +1486,44 @@ public final class PeerStoryListContext: StoryListContext { }).start() } + func renameFolder(id: Int64, title: String) -> Disposable { + var state = self.stateValue + if let index = state.availableFolders.firstIndex(where: { $0.id == id }) { + state.availableFolders[index] = State.Folder(id: state.availableFolders[index].id, title: title) + } + self.stateValue = state + let updatedFolders = state.availableFolders + + let account = self.account + let peerId = self.peerId + return (account.postbox.transaction { transaction -> Api.InputPeer? in + let key = ValueBoxKey(length: 8 + 1) + key.setInt64(0, value: peerId.toInt64()) + key.setInt8(8, value: 0) + + if let cached = transaction.retrieveItemCacheEntry(id: ItemCacheEntryId(collectionId: Namespaces.CachedItemCollection.cachedPeerStoryListHeads, key: key))?.get(CachedPeerStoryListHead.self) { + if let entry = CodableEntry(CachedPeerStoryListHead(items: cached.items, pinnedIds: cached.pinnedIds, totalCount: cached.totalCount, folders: updatedFolders)) { + transaction.putItemCacheEntry(id: ItemCacheEntryId(collectionId: Namespaces.CachedItemCollection.cachedPeerStoryListHeads, key: key), entry: entry) + } + } + + return transaction.getPeer(peerId).flatMap(apiInputPeer) + } + |> mapToSignal { inputPeer -> Signal in + guard let inputPeer else { + return .complete() + } + var flags: Int32 = 0 + flags |= 1 << 0 + return account.network.request(Api.functions.stories.updateAlbum(flags: flags, peer: inputPeer, albumId: Int32(clamping: id), title: title, deleteStories: nil, addStories: nil, order: nil)) + |> map(Optional.init) + |> `catch` { _ -> Signal in + return .single(nil) + } + |> ignoreValues + }).start() + } + func reorderFolders(ids: [Int64]) -> Disposable { var state = self.stateValue var folders: [State.Folder] = [] @@ -1815,6 +1853,14 @@ public final class PeerStoryListContext: StoryListContext { return disposable } + public func renameFolder(id: Int64, title: String) -> Disposable { + let disposable = MetaDisposable() + self.impl.with { impl in + disposable.set(impl.renameFolder(id: id, title: title)) + } + return disposable + } + public func reorderFolders(ids: [Int64]) -> Disposable { let disposable = MetaDisposable() self.impl.with { impl in diff --git a/submodules/TelegramUI/Components/MediaEditor/Sources/MediaEditorDraft.swift b/submodules/TelegramUI/Components/MediaEditor/Sources/MediaEditorDraft.swift index 72690c911d..fbb97794e7 100644 --- a/submodules/TelegramUI/Components/MediaEditor/Sources/MediaEditorDraft.swift +++ b/submodules/TelegramUI/Components/MediaEditor/Sources/MediaEditorDraft.swift @@ -15,6 +15,7 @@ public struct MediaEditorResultPrivacy: Codable, Equatable { case timeout case disableForwarding case archive + case folderIds } public let sendAsPeerId: EnginePeer.Id? @@ -22,19 +23,22 @@ public struct MediaEditorResultPrivacy: Codable, Equatable { public let timeout: Int public let isForwardingDisabled: Bool public let pin: Bool + public let folderIds: [Int64] public init( sendAsPeerId: EnginePeer.Id?, privacy: EngineStoryPrivacy, timeout: Int, isForwardingDisabled: Bool, - pin: Bool + pin: Bool, + folderIds: [Int64] ) { self.sendAsPeerId = sendAsPeerId self.privacy = privacy self.timeout = timeout self.isForwardingDisabled = isForwardingDisabled self.pin = pin + self.folderIds = folderIds } public init(from decoder: Decoder) throws { @@ -45,6 +49,7 @@ public struct MediaEditorResultPrivacy: Codable, Equatable { self.timeout = Int(try container.decode(Int32.self, forKey: .timeout)) self.isForwardingDisabled = try container.decodeIfPresent(Bool.self, forKey: .disableForwarding) ?? false self.pin = try container.decode(Bool.self, forKey: .archive) + self.folderIds = try container.decodeIfPresent([Int64].self, forKey: .folderIds) ?? [] } public func encode(to encoder: Encoder) throws { @@ -55,6 +60,7 @@ public struct MediaEditorResultPrivacy: Codable, Equatable { try container.encode(Int32(self.timeout), forKey: .timeout) try container.encode(self.isForwardingDisabled, forKey: .disableForwarding) try container.encode(self.pin, forKey: .archive) + try container.encode(self.folderIds, forKey: .folderIds) } } diff --git a/submodules/TelegramUI/Components/MediaEditorScreen/Sources/EditStories.swift b/submodules/TelegramUI/Components/MediaEditorScreen/Sources/EditStories.swift index 3359bf0c1d..e8cc73e516 100644 --- a/submodules/TelegramUI/Components/MediaEditorScreen/Sources/EditStories.swift +++ b/submodules/TelegramUI/Components/MediaEditorScreen/Sources/EditStories.swift @@ -163,7 +163,7 @@ public extension MediaEditorScreenImpl { } else { existingMedia = storyItem.media } - rootController.proceedWithStoryUpload(target: target, results: [result as! MediaEditorScreenResult], existingMedia: existingMedia, forwardInfo: forwardInfo, folders: [], externalState: externalState, commit: commit) + rootController.proceedWithStoryUpload(target: target, results: [result as! MediaEditorScreenResult], existingMedia: existingMedia, forwardInfo: forwardInfo, externalState: externalState, commit: commit) } }) } else { diff --git a/submodules/TelegramUI/Components/MediaEditorScreen/Sources/MediaEditorScreen.swift b/submodules/TelegramUI/Components/MediaEditorScreen/Sources/MediaEditorScreen.swift index f4bc125538..f013889619 100644 --- a/submodules/TelegramUI/Components/MediaEditorScreen/Sources/MediaEditorScreen.swift +++ b/submodules/TelegramUI/Components/MediaEditorScreen/Sources/MediaEditorScreen.swift @@ -2915,7 +2915,8 @@ public final class MediaEditorScreenImpl: ViewController, MediaEditorScreen, UID privacy: EngineStoryPrivacy(base: .everyone, additionallyIncludePeers: []), timeout: 86400, isForwardingDisabled: false, - pin: true + pin: true, + folderIds: [] ) } @@ -6641,7 +6642,7 @@ public final class MediaEditorScreenImpl: ViewController, MediaEditorScreen, UID self.mediaAreas = [] self.caption = NSAttributedString() self.coverTimestamp = nil - self.options = MediaEditorResultPrivacy(sendAsPeerId: nil, privacy: EngineStoryPrivacy(base: .everyone, additionallyIncludePeers: []), timeout: 0, isForwardingDisabled: false, pin: false) + self.options = MediaEditorResultPrivacy(sendAsPeerId: nil, privacy: EngineStoryPrivacy(base: .everyone, additionallyIncludePeers: []), timeout: 0, isForwardingDisabled: false, pin: false, folderIds: []) self.stickers = [] self.randomId = 0 } @@ -6651,7 +6652,7 @@ public final class MediaEditorScreenImpl: ViewController, MediaEditorScreen, UID mediaAreas: [MediaArea] = [], caption: NSAttributedString = NSAttributedString(), coverTimestamp: Double? = nil, - options: MediaEditorResultPrivacy = MediaEditorResultPrivacy(sendAsPeerId: nil, privacy: EngineStoryPrivacy(base: .everyone, additionallyIncludePeers: []), timeout: 0, isForwardingDisabled: false, pin: false), + options: MediaEditorResultPrivacy = MediaEditorResultPrivacy(sendAsPeerId: nil, privacy: EngineStoryPrivacy(base: .everyone, additionallyIncludePeers: []), timeout: 0, isForwardingDisabled: false, pin: false, folderIds: []), stickers: [TelegramMediaFile] = [], randomId: Int64 = 0 ) { @@ -6760,7 +6761,8 @@ public final class MediaEditorScreenImpl: ViewController, MediaEditorScreen, UID privacy: initialPrivacy, timeout: 86400, isForwardingDisabled: false, - pin: false + pin: false, + folderIds: [] ) } } else { @@ -6771,9 +6773,9 @@ public final class MediaEditorScreenImpl: ViewController, MediaEditorScreen, UID ).start(next: { [weak self] state, peer in if let self, var privacy = state?.privacy { if case let .user(user) = peer, !user.isPremium && privacy.timeout != 86400 { - privacy = MediaEditorResultPrivacy(sendAsPeerId: nil, privacy: privacy.privacy, timeout: 86400, isForwardingDisabled: privacy.isForwardingDisabled, pin: privacy.pin) + privacy = MediaEditorResultPrivacy(sendAsPeerId: nil, privacy: privacy.privacy, timeout: 86400, isForwardingDisabled: privacy.isForwardingDisabled, pin: privacy.pin, folderIds: privacy.folderIds) } else { - privacy = MediaEditorResultPrivacy(sendAsPeerId: nil, privacy: privacy.privacy, timeout: privacy.timeout, isForwardingDisabled: privacy.isForwardingDisabled, pin: privacy.pin) + privacy = MediaEditorResultPrivacy(sendAsPeerId: nil, privacy: privacy.privacy, timeout: privacy.timeout, isForwardingDisabled: privacy.isForwardingDisabled, pin: privacy.pin, folderIds: privacy.folderIds) } self.state.privacy = privacy } @@ -6980,7 +6982,7 @@ public final class MediaEditorScreenImpl: ViewController, MediaEditorScreen, UID mentions: mentions, coverImage: coverImage, stateContext: stateContext, - completion: { [weak self] sendAsPeerId, privacy, allowScreenshots, pin, _, completed in + completion: { [weak self] sendAsPeerId, privacy, allowScreenshots, pin, _, folders, completed in guard let self else { return } @@ -6989,13 +6991,14 @@ public final class MediaEditorScreenImpl: ViewController, MediaEditorScreen, UID privacy: privacy, timeout: timeout, isForwardingDisabled: !allowScreenshots, - pin: pin + pin: pin, + folderIds: folders ) if completed { completion() } }, - editCategory: { [weak self] privacy, allowScreenshots, pin in + editCategory: { [weak self] privacy, allowScreenshots, pin, folders in guard let self else { return } @@ -7008,11 +7011,12 @@ public final class MediaEditorScreenImpl: ViewController, MediaEditorScreen, UID privacy: privacy, timeout: timeout, isForwardingDisabled: !allowScreenshots, - pin: pin + pin: pin, + folderIds: folders ), completion: completion) }) }, - editBlockedPeers: { [weak self] privacy, allowScreenshots, pin in + editBlockedPeers: { [weak self] privacy, allowScreenshots, pin, folders in guard let self else { return } @@ -7025,7 +7029,8 @@ public final class MediaEditorScreenImpl: ViewController, MediaEditorScreen, UID privacy: privacy, timeout: timeout, isForwardingDisabled: !allowScreenshots, - pin: pin + pin: pin, + folderIds: folders ), completion: completion) }) }, @@ -7078,7 +7083,7 @@ public final class MediaEditorScreenImpl: ViewController, MediaEditorScreen, UID allowScreenshots: !isForwardingDisabled, pin: pin, stateContext: stateContext, - completion: { [weak self] _, result, isForwardingDisabled, pin, peers, completed in + completion: { [weak self] _, result, isForwardingDisabled, pin, peers, folders, completed in guard let self, completed else { return } @@ -7093,8 +7098,8 @@ public final class MediaEditorScreenImpl: ViewController, MediaEditorScreen, UID completion(result) } }, - editCategory: { _, _, _ in }, - editBlockedPeers: { _, _, _ in } + editCategory: { _, _, _, _ in }, + editBlockedPeers: { _, _, _, _ in } ) controller.customModalStyleOverlayTransitionFactorUpdated = { [weak self, weak controller] transition in if let self, let controller { @@ -7175,7 +7180,8 @@ public final class MediaEditorScreenImpl: ViewController, MediaEditorScreen, UID privacy: self.state.privacy.privacy, timeout: timeout ?? 86400, isForwardingDisabled: self.state.privacy.isForwardingDisabled, - pin: self.state.privacy.pin + pin: self.state.privacy.pin, + folderIds: self.state.privacy.folderIds ) } @@ -7672,7 +7678,7 @@ public final class MediaEditorScreenImpl: ViewController, MediaEditorScreen, UID mediaAreas: [], caption: NSAttributedString(), coverTimestamp: nil, - options: MediaEditorResultPrivacy(sendAsPeerId: nil, privacy: EngineStoryPrivacy(base: .everyone, additionallyIncludePeers: []), timeout: 0, isForwardingDisabled: false, pin: false), + options: MediaEditorResultPrivacy(sendAsPeerId: nil, privacy: EngineStoryPrivacy(base: .everyone, additionallyIncludePeers: []), timeout: 0, isForwardingDisabled: false, pin: false, folderIds: []), stickers: [], randomId: 0 )], { [weak self] finished in diff --git a/submodules/TelegramUI/Components/PeerInfo/PeerInfoScreen/Sources/PeerInfoScreen.swift b/submodules/TelegramUI/Components/PeerInfo/PeerInfoScreen/Sources/PeerInfoScreen.swift index 1c56d9d1af..a2b2b6ddc5 100644 --- a/submodules/TelegramUI/Components/PeerInfo/PeerInfoScreen/Sources/PeerInfoScreen.swift +++ b/submodules/TelegramUI/Components/PeerInfo/PeerInfoScreen/Sources/PeerInfoScreen.swift @@ -10260,7 +10260,7 @@ final class PeerInfoScreenNode: ViewControllerTracingNode, PeerInfoScreenNodePro viewControllers = viewControllers.filter { !($0 is AttachmentController)} rootController.setViewControllers(viewControllers, animated: false) - rootController.proceedWithStoryUpload(target: target, results: [result], existingMedia: nil, forwardInfo: nil, folders: [], externalState: externalState, commit: commit) + rootController.proceedWithStoryUpload(target: target, results: [result], existingMedia: nil, forwardInfo: nil, externalState: externalState, commit: commit) } }, cancelled: {} diff --git a/submodules/TelegramUI/Components/PeerInfo/PeerInfoVisualMediaPaneNode/Sources/PeerInfoStoryPaneNode.swift b/submodules/TelegramUI/Components/PeerInfo/PeerInfoVisualMediaPaneNode/Sources/PeerInfoStoryPaneNode.swift index 41196da9f2..42518d7176 100644 --- a/submodules/TelegramUI/Components/PeerInfo/PeerInfoVisualMediaPaneNode/Sources/PeerInfoStoryPaneNode.swift +++ b/submodules/TelegramUI/Components/PeerInfo/PeerInfoVisualMediaPaneNode/Sources/PeerInfoStoryPaneNode.swift @@ -2491,7 +2491,7 @@ public final class PeerInfoStoryPaneNode: ASDisplayNode, PeerInfoPaneNode, ASScr }))) } 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 + items.append(.action(ContextMenuActionItem(text: "Add to Album", icon: { theme in generateTintedImage(image: UIImage(bundleImageName: "Chat/Context Menu/AddToFolder"), color: theme.contextMenu.primaryColor) }, action: { [weak self] c, f in guard let self, let c else { f(.default) return @@ -2512,7 +2512,7 @@ public final class PeerInfoStoryPaneNode: ASDisplayNode, PeerInfoPaneNode, ASScr }))) 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 + items.append(.action(ContextMenuActionItem(text: "New Album", icon: { theme in generateTintedImage(image: UIImage(bundleImageName: "Chat/Context Menu/AddFolder"), color: theme.contextMenu.primaryColor) }, iconPosition: .left, action: { [weak self] c, f in guard let self else { f(.default) return @@ -3883,6 +3883,18 @@ public final class PeerInfoStoryPaneNode: ASDisplayNode, PeerInfoPaneNode, ASScr self.beginReordering() }))) + //TODO:localize + items.append(.action(ContextMenuActionItem(text: "Rename Album", textColor: .destructive, icon: { theme in generateTintedImage(image: UIImage(bundleImageName: "Chat/Context Menu/Edit"), color: theme.contextMenu.destructiveColor) }, action: { [weak self] _, f in + guard let self else { + f(.default) + return + } + + f(.dismissWithoutContent) + + self.presentRenameStoryFolder(id: folder.id, title: folder.title) + }))) + //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 { @@ -4931,7 +4943,7 @@ public final class PeerInfoStoryPaneNode: ASDisplayNode, PeerInfoPaneNode, ASScr } if let value { if let listSource = self.listSource as? PeerStoryListContext { - let _ = listSource.addFolder(title: value, completion: { [weak self] id in + let _ = listSource.addFolder(title: value, items: [], completion: { [weak self] id in Queue.mainQueue().async { guard let self, let id, let listSource = self.listSource as? PeerStoryListContext else { return @@ -4949,6 +4961,32 @@ public final class PeerInfoStoryPaneNode: ASDisplayNode, PeerInfoPaneNode, ASScr self.parentController?.present(promptController, in: .window(.root)) } + private func presentRenameStoryFolder(id: Int64, title: String) { + //TODO:localize + let promptController = promptController( + sharedContext: self.context.sharedContext, + updatedPresentationData: nil, + text: "Edit Album Name", + titleFont: .bold, + subtitle: "Choose a new name for your album.", + value: title, + 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 { + let _ = listSource.renameFolder(id: id, title: value).start() + } + } + } + ) + self.parentController?.present(promptController, in: .window(.root)) + } + private func presentAddStoriesToFolder() { guard case let .peer(peerId, _, _) = self.scope else { return diff --git a/submodules/TelegramUI/Components/ShareWithPeersScreen/Sources/ShareWithPeersScreen.swift b/submodules/TelegramUI/Components/ShareWithPeersScreen/Sources/ShareWithPeersScreen.swift index 5cb946e270..afc34227b2 100644 --- a/submodules/TelegramUI/Components/ShareWithPeersScreen/Sources/ShareWithPeersScreen.swift +++ b/submodules/TelegramUI/Components/ShareWithPeersScreen/Sources/ShareWithPeersScreen.swift @@ -44,9 +44,9 @@ final class ShareWithPeersScreenComponent: Component { let categoryItems: [CategoryItem] let optionItems: [OptionItem] let coverItem: CoverItem? - let completion: (EnginePeer.Id?, EngineStoryPrivacy, Bool, Bool, [EnginePeer], Bool) -> Void - let editCategory: (EngineStoryPrivacy, Bool, Bool) -> Void - let editBlockedPeers: (EngineStoryPrivacy, Bool, Bool) -> Void + let completion: (EnginePeer.Id?, EngineStoryPrivacy, Bool, Bool, [EnginePeer], [Int64], Bool) -> Void + let editCategory: (EngineStoryPrivacy, Bool, Bool, [Int64]) -> Void + let editBlockedPeers: (EngineStoryPrivacy, Bool, Bool, [Int64]) -> Void let editCover: () -> Void let peerCompletion: (EnginePeer.Id) -> Void @@ -62,9 +62,9 @@ final class ShareWithPeersScreenComponent: Component { categoryItems: [CategoryItem], optionItems: [OptionItem], coverItem: CoverItem?, - completion: @escaping (EnginePeer.Id?, EngineStoryPrivacy, Bool, Bool, [EnginePeer], Bool) -> Void, - editCategory: @escaping (EngineStoryPrivacy, Bool, Bool) -> Void, - editBlockedPeers: @escaping (EngineStoryPrivacy, Bool, Bool) -> Void, + completion: @escaping (EnginePeer.Id?, EngineStoryPrivacy, Bool, Bool, [EnginePeer], [Int64], Bool) -> Void, + editCategory: @escaping (EngineStoryPrivacy, Bool, Bool, [Int64]) -> Void, + editBlockedPeers: @escaping (EngineStoryPrivacy, Bool, Bool, [Int64]) -> Void, editCover: @escaping () -> Void, peerCompletion: @escaping (EnginePeer.Id) -> Void ) { @@ -833,9 +833,9 @@ final class ShareWithPeersScreenComponent: Component { context: component.context, initialPrivacy: EngineStoryPrivacy(base: .nobody, additionallyIncludePeers: []), stateContext: stateContext, - completion: { _, _, _, _, _, _ in }, - editCategory: { _, _, _ in }, - editBlockedPeers: { _, _, _ in }, + completion: { _, _, _, _, _, _, _ in }, + editCategory: { _, _, _, _ in }, + editBlockedPeers: { _, _, _, _ in }, peerCompletion: { [weak self] peerId in guard let self else { return @@ -896,7 +896,7 @@ final class ShareWithPeersScreenComponent: Component { var items: [ContextMenuItem] = [] - 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 + items.append(.action(ContextMenuActionItem(text: "New Album", icon: { theme in generateTintedImage(image: UIImage(bundleImageName: "Chat/Context Menu/AddFolder"), color: theme.contextMenu.primaryColor) }, iconPosition: .left, action: { [weak self] c, f in guard let self else { f(.default) return @@ -1421,7 +1421,8 @@ final class ShareWithPeersScreenComponent: Component { component.editCategory( EngineStoryPrivacy(base: .nobody, additionallyIncludePeers: []), self.selectedOptions.contains(.screenshot), - self.selectedOptions.contains(.pin) + self.selectedOptions.contains(.pin), + self.shareToFolders.map(\.id) ) controller.dismissAllTooltips() controller.dismiss() @@ -1429,7 +1430,8 @@ final class ShareWithPeersScreenComponent: Component { component.editCategory( EngineStoryPrivacy(base: .closeFriends, additionallyIncludePeers: []), self.selectedOptions.contains(.screenshot), - self.selectedOptions.contains(.pin) + self.selectedOptions.contains(.pin), + self.shareToFolders.map(\.id) ) controller.dismissAllTooltips() controller.dismiss() @@ -1457,7 +1459,8 @@ final class ShareWithPeersScreenComponent: Component { component.editCategory( EngineStoryPrivacy(base: base, additionallyIncludePeers: selectedPeers), self.selectedOptions.contains(.screenshot), - self.selectedOptions.contains(.pin) + self.selectedOptions.contains(.pin), + self.shareToFolders.map(\.id) ) controller.dismissAllTooltips() controller.dismiss() @@ -1545,7 +1548,8 @@ final class ShareWithPeersScreenComponent: Component { component.editBlockedPeers( EngineStoryPrivacy(base: base, additionallyIncludePeers: self.selectedPeers), self.selectedOptions.contains(.screenshot), - self.selectedOptions.contains(.pin) + self.selectedOptions.contains(.pin), + self.shareToFolders.map(\.id) ) controller.dismissAllTooltips() controller.dismiss() @@ -2267,6 +2271,7 @@ final class ShareWithPeersScreenComponent: Component { self.selectedOptions.contains(.screenshot), self.selectedOptions.contains(.pin), self.component?.stateContext.stateValue?.peers.filter { self.selectedPeers.contains($0.id) } ?? [], + self.shareToFolders.map(\.id), false ) controller.requestDismiss() @@ -3019,6 +3024,7 @@ final class ShareWithPeersScreenComponent: Component { self.selectedOptions.contains(.screenshot), self.selectedOptions.contains(.pin), peers.values.compactMap { $0 }, + self.shareToFolders.map(\.id), true ) @@ -3270,9 +3276,9 @@ public class ShareWithPeersScreen: ViewControllerComponentContainer { mentions: [String] = [], coverImage: UIImage? = nil, stateContext: StateContext, - completion: @escaping (EnginePeer.Id?, EngineStoryPrivacy, Bool, Bool, [EnginePeer], Bool) -> Void, - editCategory: @escaping (EngineStoryPrivacy, Bool, Bool) -> Void = { _, _, _ in }, - editBlockedPeers: @escaping (EngineStoryPrivacy, Bool, Bool) -> Void = { _, _, _ in }, + completion: @escaping (EnginePeer.Id?, EngineStoryPrivacy, Bool, Bool, [EnginePeer], [Int64], Bool) -> Void, + editCategory: @escaping (EngineStoryPrivacy, Bool, Bool, [Int64]) -> Void = { _, _, _, _ in }, + editBlockedPeers: @escaping (EngineStoryPrivacy, Bool, Bool, [Int64]) -> Void = { _, _, _, _ in }, editCover: @escaping () -> Void = { }, peerCompletion: @escaping (EnginePeer.Id) -> Void = { _ in } ) { diff --git a/submodules/TelegramUI/Components/Stories/StoryContainerScreen/Sources/StoryContainerScreen.swift b/submodules/TelegramUI/Components/Stories/StoryContainerScreen/Sources/StoryContainerScreen.swift index df2e7e0a69..1b7327eb71 100644 --- a/submodules/TelegramUI/Components/Stories/StoryContainerScreen/Sources/StoryContainerScreen.swift +++ b/submodules/TelegramUI/Components/Stories/StoryContainerScreen/Sources/StoryContainerScreen.swift @@ -1695,7 +1695,7 @@ private final class StoryContainerScreenComponent: Component { if let content = component.content as? PeerStoryListContentContextImpl { if let listSource = content.listContext as? PeerStoryListContext { - let _ = listSource.addFolder(title: title, completion: { [weak listSource] id in + let _ = listSource.addFolder(title: title, items: [], completion: { [weak listSource] id in Queue.mainQueue().async { guard let listSource, let id else { return diff --git a/submodules/TelegramUI/Components/Stories/StoryContainerScreen/Sources/StoryItemSetContainerComponent.swift b/submodules/TelegramUI/Components/Stories/StoryContainerScreen/Sources/StoryItemSetContainerComponent.swift index 075a35744c..925cca45db 100644 --- a/submodules/TelegramUI/Components/Stories/StoryContainerScreen/Sources/StoryItemSetContainerComponent.swift +++ b/submodules/TelegramUI/Components/Stories/StoryContainerScreen/Sources/StoryItemSetContainerComponent.swift @@ -5090,7 +5090,7 @@ public final class StoryItemSetContainerComponent: Component { context: context, initialPrivacy: privacy, stateContext: stateContext, - completion: { [weak self] _, privacy, _, _, _, completed in + completion: { [weak self] _, privacy, _, _, _, _, completed in guard let self, let component = self.component, completed else { return } @@ -5107,7 +5107,7 @@ public final class StoryItemSetContainerComponent: Component { self.rewindCurrentItem() self.updateIsProgressPaused() }, - editCategory: { [weak self] privacy, _, _ in + editCategory: { [weak self] privacy, _, _, _ in guard let self else { return } @@ -5118,7 +5118,7 @@ public final class StoryItemSetContainerComponent: Component { self.openItemPrivacySettings(updatedPrivacy: privacy) }) }, - editBlockedPeers: { [weak self] privacy, _, _ in + editBlockedPeers: { [weak self] privacy, _, _, _ in guard let self else { return } @@ -5171,7 +5171,7 @@ public final class StoryItemSetContainerComponent: Component { context: context, initialPrivacy: privacy, stateContext: stateContext, - completion: { [weak self] _, result, _, _, peers, completed in + completion: { [weak self] _, result, _, _, peers, _, completed in guard completed else { return } @@ -5188,8 +5188,8 @@ public final class StoryItemSetContainerComponent: Component { completion(result) } }, - editCategory: { _, _, _ in }, - editBlockedPeers: { _, _, _ in } + editCategory: { _, _, _, _ in }, + editBlockedPeers: { _, _, _, _ in } ) controller.dismissed = { [weak self] in if let self { @@ -6110,7 +6110,7 @@ public final class StoryItemSetContainerComponent: Component { var items: [ContextMenuItem] = [] //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 + items.append(.action(ContextMenuActionItem(text: "Add to Album", icon: { theme in generateTintedImage(image: UIImage(bundleImageName: "Chat/Context Menu/AddToFolder"), color: theme.contextMenu.primaryColor) }, action: { [weak self] c, f in guard let self, let c else { f(.default) return @@ -6131,7 +6131,7 @@ public final class StoryItemSetContainerComponent: Component { }))) 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 + items.append(.action(ContextMenuActionItem(text: "New Album", icon: { theme in generateTintedImage(image: UIImage(bundleImageName: "Chat/Context Menu/AddFolder"), color: theme.contextMenu.primaryColor) }, iconPosition: .left, action: { [weak self] c, f in guard let self else { f(.default) return diff --git a/submodules/TelegramUI/Images.xcassets/Chat/Context Menu/AddFolder.imageset/Contents.json b/submodules/TelegramUI/Images.xcassets/Chat/Context Menu/AddFolder.imageset/Contents.json new file mode 100644 index 0000000000..7788d5e229 --- /dev/null +++ b/submodules/TelegramUI/Images.xcassets/Chat/Context Menu/AddFolder.imageset/Contents.json @@ -0,0 +1,12 @@ +{ + "images" : [ + { + "filename" : "addfolder_24.pdf", + "idiom" : "universal" + } + ], + "info" : { + "author" : "xcode", + "version" : 1 + } +} diff --git a/submodules/TelegramUI/Images.xcassets/Chat/Context Menu/AddFolder.imageset/addfolder_24.pdf b/submodules/TelegramUI/Images.xcassets/Chat/Context Menu/AddFolder.imageset/addfolder_24.pdf new file mode 100644 index 0000000000..e5434739fd Binary files /dev/null and b/submodules/TelegramUI/Images.xcassets/Chat/Context Menu/AddFolder.imageset/addfolder_24.pdf differ diff --git a/submodules/TelegramUI/Images.xcassets/Chat/Context Menu/AddToFolder.imageset/Contents.json b/submodules/TelegramUI/Images.xcassets/Chat/Context Menu/AddToFolder.imageset/Contents.json new file mode 100644 index 0000000000..c4e09e2102 --- /dev/null +++ b/submodules/TelegramUI/Images.xcassets/Chat/Context Menu/AddToFolder.imageset/Contents.json @@ -0,0 +1,12 @@ +{ + "images" : [ + { + "filename" : "folder1_24.pdf", + "idiom" : "universal" + } + ], + "info" : { + "author" : "xcode", + "version" : 1 + } +} diff --git a/submodules/TelegramUI/Images.xcassets/Chat/Context Menu/AddToFolder.imageset/folder1_24.pdf b/submodules/TelegramUI/Images.xcassets/Chat/Context Menu/AddToFolder.imageset/folder1_24.pdf new file mode 100644 index 0000000000..e941baf3a6 Binary files /dev/null and b/submodules/TelegramUI/Images.xcassets/Chat/Context Menu/AddToFolder.imageset/folder1_24.pdf differ diff --git a/submodules/TelegramUI/Sources/OpenResolvedUrl.swift b/submodules/TelegramUI/Sources/OpenResolvedUrl.swift index 3b86700ea0..2f9e8b5979 100644 --- a/submodules/TelegramUI/Sources/OpenResolvedUrl.swift +++ b/submodules/TelegramUI/Sources/OpenResolvedUrl.swift @@ -992,7 +992,7 @@ func openResolvedUrlImpl( if let rootController = context.sharedContext.mainWindow?.viewController as? TelegramRootControllerInterface { rootController.popToRoot(animated: false) - rootController.proceedWithStoryUpload(target: target, results: results, existingMedia: nil, forwardInfo: nil, folders: [], externalState: externalState, commit: commit) + rootController.proceedWithStoryUpload(target: target, results: results, existingMedia: nil, forwardInfo: nil, externalState: externalState, commit: commit) } }) if let navigationController { diff --git a/submodules/TelegramUI/Sources/SharedAccountContext.swift b/submodules/TelegramUI/Sources/SharedAccountContext.swift index 8c71fbe8ec..57f998a350 100644 --- a/submodules/TelegramUI/Sources/SharedAccountContext.swift +++ b/submodules/TelegramUI/Sources/SharedAccountContext.swift @@ -3821,7 +3821,7 @@ public final class SharedAccountContextImpl: SharedAccountContext { externalState.storyTarget = target if let rootController = context.sharedContext.mainWindow?.viewController as? TelegramRootControllerInterface { - rootController.proceedWithStoryUpload(target: target, results: [result], existingMedia: nil, forwardInfo: nil, folders: [], externalState: externalState, commit: commit) + rootController.proceedWithStoryUpload(target: target, results: [result], existingMedia: nil, forwardInfo: nil, externalState: externalState, commit: commit) } let _ = (context.engine.data.get(TelegramEngine.EngineData.Item.Peer.Peer(id: targetPeerId)) diff --git a/submodules/TelegramUI/Sources/TelegramRootController.swift b/submodules/TelegramUI/Sources/TelegramRootController.swift index 0f743f7c67..61f720d22d 100644 --- a/submodules/TelegramUI/Sources/TelegramRootController.swift +++ b/submodules/TelegramUI/Sources/TelegramRootController.swift @@ -471,7 +471,7 @@ public final class TelegramRootController: NavigationController, TelegramRootCon if let customTarget, case .botPreview = customTarget { externalState.storyTarget = customTarget - self.proceedWithStoryUpload(target: customTarget, results: results, existingMedia: nil, forwardInfo: nil, folders: [], externalState: externalState, commit: commit) + self.proceedWithStoryUpload(target: customTarget, results: results, existingMedia: nil, forwardInfo: nil, externalState: externalState, commit: commit) dismissCameraImpl?() return @@ -504,7 +504,7 @@ public final class TelegramRootController: NavigationController, TelegramRootCon externalState.isPeerArchived = channel.storiesHidden ?? false } - self.proceedWithStoryUpload(target: target, results: results, existingMedia: nil, forwardInfo: nil, folders: [], externalState: externalState, commit: commit) + self.proceedWithStoryUpload(target: target, results: results, existingMedia: nil, forwardInfo: nil, externalState: externalState, commit: commit) dismissCameraImpl?() }) @@ -568,7 +568,7 @@ public final class TelegramRootController: NavigationController, TelegramRootCon }) } - public func proceedWithStoryUpload(target: Stories.PendingTarget, results: [MediaEditorScreenResult], existingMedia: EngineMedia?, forwardInfo: Stories.PendingForwardInfo?, folders: [Int64], externalState: MediaEditorTransitionOutExternalState, commit: @escaping (@escaping () -> Void) -> Void) { + public func proceedWithStoryUpload(target: Stories.PendingTarget, results: [MediaEditorScreenResult], existingMedia: EngineMedia?, forwardInfo: Stories.PendingForwardInfo?, externalState: MediaEditorTransitionOutExternalState, commit: @escaping (@escaping () -> Void) -> Void) { guard let results = results as? [MediaEditorScreenImpl.Result] else { return } @@ -582,6 +582,8 @@ public final class TelegramRootController: NavigationController, TelegramRootCon case .botPreview: targetPeerId = nil } + + let folders: [Int64] = results.first?.options.folderIds ?? [] if let rootTabController = self.rootTabController { if let index = rootTabController.controllers.firstIndex(where: { $0 is ChatListController}) { diff --git a/submodules/WebUI/Sources/WebAppController.swift b/submodules/WebUI/Sources/WebAppController.swift index aaa520fd2d..3445a10613 100644 --- a/submodules/WebUI/Sources/WebAppController.swift +++ b/submodules/WebUI/Sources/WebAppController.swift @@ -1494,7 +1494,7 @@ public final class WebAppController: ViewController, AttachmentContainable { externalState.storyTarget = target if let rootController = self.context.sharedContext.mainWindow?.viewController as? TelegramRootControllerInterface { - rootController.proceedWithStoryUpload(target: target, results: results, existingMedia: nil, forwardInfo: nil, folders: [], externalState: externalState, commit: commit) + rootController.proceedWithStoryUpload(target: target, results: results, existingMedia: nil, forwardInfo: nil, externalState: externalState, commit: commit) } }) if let navigationController = self.controller?.getNavigationController() {