From 6fbab164ed1998915ac7d01e7e5f24b0f89d1f9d Mon Sep 17 00:00:00 2001 From: Peter Date: Sat, 22 Oct 2016 22:53:47 +0300 Subject: [PATCH] no message --- .../Contents.json | 12 + .../ic_bot.pdf | Bin 0 -> 6701 bytes .../Contents.json | 12 + .../ic_keyboard.pdf | Bin 0 -> 6970 bytes .../Contents.json | 12 + .../ic_sticker.pdf} | Bin 7894 -> 8119 bytes .../IconAttachment.imageset/Contents.json | 2 +- .../IconAttachment.imageset/ic_attach.pdf | Bin 0 -> 16786 bytes .../IconMicrophone.imageset/Contents.json | 12 + .../Text/IconMicrophone.imageset/ic_voice.pdf | Bin 0 -> 8160 bytes .../Text/IconSend.imageset/Contents.json | 12 + .../Input/Text/IconSend.imageset/Send.pdf | Bin 0 -> 9016 bytes .../Builtin0.imageset/Contents.json | 2 +- .../Wallpapers/Builtin0.imageset/Dogs BG.jpg | Bin 0 -> 132027 bytes .../Builtin0.imageset/builtin-wallpaper-0.jpg | Bin 171777 -> 0 bytes TelegramUI.xcodeproj/project.pbxproj | 58 ++- TelegramUI/ActionSheetRollImageItem.swift | 12 +- TelegramUI/Cache.swift | 40 --- .../CachedResourceRepresentations.swift | 27 ++ TelegramUI/ChannelInfoEntries.swift | 8 +- .../ChatChannelSubscriberInputPanelNode.swift | 67 ++-- TelegramUI/ChatController.swift | 50 ++- TelegramUI/ChatControllerInteraction.swift | 5 +- TelegramUI/ChatControllerNode.swift | 165 ++++++++- TelegramUI/ChatDocumentGalleryItem.swift | 4 +- TelegramUI/ChatHistoryGridNode.swift | 8 +- TelegramUI/ChatImageGalleryItem.swift | 5 +- TelegramUI/ChatInputNode.swift | 11 + TelegramUI/ChatInputPanelNode.swift | 4 +- TelegramUI/ChatInterfaceInputContexts.swift | 13 + TelegramUI/ChatInterfaceInputNodes.swift | 21 ++ .../ChatInterfaceStateInputPanels.swift | 9 - .../ChatMediaActionSheetController.swift | 9 +- TelegramUI/ChatMediaActionSheetRollItem.swift | 20 +- TelegramUI/ChatMediaInputGridEntries.swift | 39 ++ TelegramUI/ChatMediaInputNode.swift | 322 +++++++++++++++++ TelegramUI/ChatMediaInputPanelEntries.swift | 70 ++++ .../ChatMediaInputStickerGridItem.swift | 163 +++++++++ .../ChatMediaInputStickerPackItem.swift | 115 ++++++ .../ChatMessageInteractiveMediaNode.swift | 56 ++- .../ChatMessageMediaBubbleContentNode.swift | 2 +- .../ChatMessageSelectionInputPanelNode.swift | 74 ++-- TelegramUI/ChatMessageStickerItemNode.swift | 2 +- .../ChatMessageWebpageBubbleContentNode.swift | 4 +- .../ChatPanelInterfaceInteraction.swift | 4 +- .../ChatPresentationInterfaceState.swift | 36 +- TelegramUI/ChatTextInputPanelNode.swift | 337 ++++++++++++++---- TelegramUI/ChatVideoGalleryItem.swift | 2 +- TelegramUI/ContactsController.swift | 1 + .../FFMpegMediaFrameSourceContext.swift | 20 +- TelegramUI/FetchCachedRepresentations.swift | 90 +++++ TelegramUI/FileResources.swift | 8 +- TelegramUI/GalleryController.swift | 6 +- TelegramUI/GridHoleItem.swift | 4 +- TelegramUI/GridMessageItem.swift | 2 + TelegramUI/GroupInfoEntries.swift | 8 +- TelegramUI/PeerAvatar.swift | 70 ++-- TelegramUI/PeerInfoActionItem.swift | 10 +- TelegramUI/PeerInfoAvatarAndNameItem.swift | 119 ++++++- TelegramUI/PeerInfoController.swift | 102 +++++- TelegramUI/PeerInfoDisclosureItem.swift | 12 +- TelegramUI/PeerInfoEntries.swift | 21 +- TelegramUI/PeerInfoPeerActionItem.swift | 12 +- TelegramUI/PeerInfoPeerItem.swift | 16 +- TelegramUI/PeerInfoTextWithLabelItem.swift | 8 +- .../PeerMediaCollectionController.swift | 6 +- .../PeerMediaCollectionControllerNode.swift | 14 +- TelegramUI/PhotoResources.swift | 112 +++--- TelegramUI/StickerResources.swift | 74 ++-- TelegramUI/UserInfoEntries.swift | 167 +++++++-- 70 files changed, 2188 insertions(+), 520 deletions(-) create mode 100644 Images.xcassets/Chat/Input/Text/AccessoryIconInputButtons.imageset/Contents.json create mode 100644 Images.xcassets/Chat/Input/Text/AccessoryIconInputButtons.imageset/ic_bot.pdf create mode 100644 Images.xcassets/Chat/Input/Text/AccessoryIconKeyboard.imageset/Contents.json create mode 100644 Images.xcassets/Chat/Input/Text/AccessoryIconKeyboard.imageset/ic_keyboard.pdf create mode 100644 Images.xcassets/Chat/Input/Text/AccessoryIconStickers.imageset/Contents.json rename Images.xcassets/Chat/Input/Text/{IconAttachment.imageset/IconAttachment.pdf => AccessoryIconStickers.imageset/ic_sticker.pdf} (54%) create mode 100644 Images.xcassets/Chat/Input/Text/IconAttachment.imageset/ic_attach.pdf create mode 100644 Images.xcassets/Chat/Input/Text/IconMicrophone.imageset/Contents.json create mode 100644 Images.xcassets/Chat/Input/Text/IconMicrophone.imageset/ic_voice.pdf create mode 100644 Images.xcassets/Chat/Input/Text/IconSend.imageset/Contents.json create mode 100644 Images.xcassets/Chat/Input/Text/IconSend.imageset/Send.pdf create mode 100644 Images.xcassets/Chat/Wallpapers/Builtin0.imageset/Dogs BG.jpg delete mode 100644 Images.xcassets/Chat/Wallpapers/Builtin0.imageset/builtin-wallpaper-0.jpg delete mode 100644 TelegramUI/Cache.swift create mode 100644 TelegramUI/CachedResourceRepresentations.swift create mode 100644 TelegramUI/ChatInputNode.swift create mode 100644 TelegramUI/ChatInterfaceInputNodes.swift create mode 100644 TelegramUI/ChatMediaInputGridEntries.swift create mode 100644 TelegramUI/ChatMediaInputNode.swift create mode 100644 TelegramUI/ChatMediaInputPanelEntries.swift create mode 100644 TelegramUI/ChatMediaInputStickerGridItem.swift create mode 100644 TelegramUI/ChatMediaInputStickerPackItem.swift create mode 100644 TelegramUI/FetchCachedRepresentations.swift diff --git a/Images.xcassets/Chat/Input/Text/AccessoryIconInputButtons.imageset/Contents.json b/Images.xcassets/Chat/Input/Text/AccessoryIconInputButtons.imageset/Contents.json new file mode 100644 index 0000000000..0b72936b64 --- /dev/null +++ b/Images.xcassets/Chat/Input/Text/AccessoryIconInputButtons.imageset/Contents.json @@ -0,0 +1,12 @@ +{ + "images" : [ + { + "idiom" : "universal", + "filename" : "ic_bot.pdf" + } + ], + "info" : { + "version" : 1, + "author" : "xcode" + } +} \ No newline at end of file diff --git a/Images.xcassets/Chat/Input/Text/AccessoryIconInputButtons.imageset/ic_bot.pdf b/Images.xcassets/Chat/Input/Text/AccessoryIconInputButtons.imageset/ic_bot.pdf new file mode 100644 index 0000000000000000000000000000000000000000..9d7a87f262e0c84b53500f1c78186e2944834747 GIT binary patch literal 6701 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 P9;2Xukdo3i(n0(a2@s!% literal 0 HcmV?d00001 diff --git a/Images.xcassets/Chat/Input/Text/AccessoryIconKeyboard.imageset/Contents.json b/Images.xcassets/Chat/Input/Text/AccessoryIconKeyboard.imageset/Contents.json new file mode 100644 index 0000000000..5785acf156 --- /dev/null +++ b/Images.xcassets/Chat/Input/Text/AccessoryIconKeyboard.imageset/Contents.json @@ -0,0 +1,12 @@ +{ + "images" : [ + { + "idiom" : "universal", + "filename" : "ic_keyboard.pdf" + } + ], + "info" : { + "version" : 1, + "author" : "xcode" + } +} \ No newline at end of file diff --git a/Images.xcassets/Chat/Input/Text/AccessoryIconKeyboard.imageset/ic_keyboard.pdf b/Images.xcassets/Chat/Input/Text/AccessoryIconKeyboard.imageset/ic_keyboard.pdf new file mode 100644 index 0000000000000000000000000000000000000000..b713289f1b9f72b54cc09c6fac198bf20183e0ef GIT binary patch literal 6970 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 aKq&Tv!6))DFwR1R0uw2CQ&V?e5BxtIl4dmk diff --git a/Images.xcassets/Chat/Input/Text/IconAttachment.imageset/Contents.json b/Images.xcassets/Chat/Input/Text/IconAttachment.imageset/Contents.json index ae4dac8782..a4e9ce4cfd 100644 --- a/Images.xcassets/Chat/Input/Text/IconAttachment.imageset/Contents.json +++ b/Images.xcassets/Chat/Input/Text/IconAttachment.imageset/Contents.json @@ -2,7 +2,7 @@ "images" : [ { "idiom" : "universal", - "filename" : "IconAttachment.pdf" + "filename" : "ic_attach.pdf" } ], "info" : { diff --git a/Images.xcassets/Chat/Input/Text/IconAttachment.imageset/ic_attach.pdf b/Images.xcassets/Chat/Input/Text/IconAttachment.imageset/ic_attach.pdf new file mode 100644 index 0000000000000000000000000000000000000000..3a75f7a4f7ec51e5f22a788a5feb8b40654e5891 GIT binary patch literal 16786 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 literal 0 HcmV?d00001 diff --git a/Images.xcassets/Chat/Input/Text/IconMicrophone.imageset/Contents.json b/Images.xcassets/Chat/Input/Text/IconMicrophone.imageset/Contents.json new file mode 100644 index 0000000000..72555bf44c --- /dev/null +++ b/Images.xcassets/Chat/Input/Text/IconMicrophone.imageset/Contents.json @@ -0,0 +1,12 @@ +{ + "images" : [ + { + "idiom" : "universal", + "filename" : "ic_voice.pdf" + } + ], + "info" : { + "version" : 1, + "author" : "xcode" + } +} \ No newline at end of file diff --git a/Images.xcassets/Chat/Input/Text/IconMicrophone.imageset/ic_voice.pdf b/Images.xcassets/Chat/Input/Text/IconMicrophone.imageset/ic_voice.pdf new file mode 100644 index 0000000000000000000000000000000000000000..b5eb5080f5b265d35eb860579697d62162ab9d1e GIT binary patch literal 8160 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 literal 0 HcmV?d00001 diff --git a/Images.xcassets/Chat/Wallpapers/Builtin0.imageset/Contents.json b/Images.xcassets/Chat/Wallpapers/Builtin0.imageset/Contents.json index 6d499c7d57..96a7e393b7 100644 --- a/Images.xcassets/Chat/Wallpapers/Builtin0.imageset/Contents.json +++ b/Images.xcassets/Chat/Wallpapers/Builtin0.imageset/Contents.json @@ -6,7 +6,7 @@ }, { "idiom" : "universal", - "filename" : "builtin-wallpaper-0.jpg", + "filename" : "Dogs BG.jpg", "scale" : "2x" }, { diff --git a/Images.xcassets/Chat/Wallpapers/Builtin0.imageset/Dogs BG.jpg b/Images.xcassets/Chat/Wallpapers/Builtin0.imageset/Dogs BG.jpg new file mode 100644 index 0000000000000000000000000000000000000000..310fe0dbe633fc5c562ae686c07f20cd25bdafc1 GIT binary patch literal 132027 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 z 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

mtD6+Y@ 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 rr}EEgrCCwLnpwWXx9B#iLD0}00X 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 literal 0 HcmV?d00001 diff --git a/Images.xcassets/Chat/Wallpapers/Builtin0.imageset/builtin-wallpaper-0.jpg b/Images.xcassets/Chat/Wallpapers/Builtin0.imageset/builtin-wallpaper-0.jpg deleted file mode 100644 index ea45b36ee0e4750d4cd55b36a8cb411a16f8bd5e..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 171777 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�tKKGvu(LUZro8 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 RP5dXd5HfEL8%X Void - init(asset: PHAsset) { + var selectable: Bool { + return true + } + + init(asset: PHAsset, selected: @escaping () -> Void) { + self.selectedItem = selected self.asset = asset } @@ -27,6 +33,10 @@ final class ActionSheetRollImageItem: ListViewItem { completion(ListViewItemNodeLayout(contentSize: node.contentSize, insets: node.insets), { }) } + + func selected(listView: ListView) { + self.selectedItem() + } } private final class ActionSheetRollImageItemNode: ListViewItemNode { diff --git a/TelegramUI/Cache.swift b/TelegramUI/Cache.swift deleted file mode 100644 index 75ec105480..0000000000 --- a/TelegramUI/Cache.swift +++ /dev/null @@ -1,40 +0,0 @@ -import Foundation -import SwiftSignalKit -import Display -import TelegramCore - -let threadPool = ThreadPool(threadCount: 4, threadPriority: 0.2) - -func cachedCloudFileLocation(_ location: TelegramCloudMediaLocation) -> Signal { - return Signal { subscriber in - assertNotOnMainThread() - switch location.apiInputLocation { - case let .inputFileLocation(volumeId, localId, _): - let path = NSTemporaryDirectory() + "/\(location.datacenterId)_\(volumeId)_\(localId)" - do { - let data = try Data(contentsOf: URL(fileURLWithPath: path), options: .mappedIfSafe) - subscriber.putNext(data) - subscriber.putCompletion() - } catch { - subscriber.putError(NoError()) - } - - case _: - subscriber.putError(NoError()) - } - return ActionDisposable { - - } - } -} - -func cacheCloudFileLocation(_ location: TelegramCloudMediaLocation, data: Data) { - assertNotOnMainThread() - switch location.apiInputLocation { - case let .inputFileLocation(volumeId, localId, _): - let path = NSTemporaryDirectory() + "/\(location.datacenterId)_\(volumeId)_\(localId)" - let _ = try? data.write(to: URL(fileURLWithPath: path), options: [.atomicWrite]) - case _: - break - } -} diff --git a/TelegramUI/CachedResourceRepresentations.swift b/TelegramUI/CachedResourceRepresentations.swift new file mode 100644 index 0000000000..996e6ab7b6 --- /dev/null +++ b/TelegramUI/CachedResourceRepresentations.swift @@ -0,0 +1,27 @@ +import Foundation +import Postbox +import SwiftSignalKit + +final class CachedStickerAJpegRepresentation: CachedMediaResourceRepresentation { + let size: CGSize? + + var uniqueId: String { + if let size = self.size { + return "sticker-ajpeg-\(Int(size.width))x\(Int(size.height))" + } else { + return "sticker-ajpeg" + } + } + + init(size: CGSize?) { + self.size = size + } + + func isEqual(to: CachedMediaResourceRepresentation) -> Bool { + if let to = to as? CachedStickerAJpegRepresentation { + return self.size == to.size + } else { + return false + } + } +} diff --git a/TelegramUI/ChannelInfoEntries.swift b/TelegramUI/ChannelInfoEntries.swift index c2679d9daf..d547a886c1 100644 --- a/TelegramUI/ChannelInfoEntries.swift +++ b/TelegramUI/ChannelInfoEntries.swift @@ -153,7 +153,7 @@ enum ChannelInfoEntry: PeerInfoEntry { func item(account: Account, interaction: PeerInfoControllerInteraction) -> ListViewItem { switch self { case let .info(peer, cachedData): - return PeerInfoAvatarAndNameItem(account: account, peer: peer, cachedData: cachedData, sectionId: self.section.rawValue, style: .plain) + return PeerInfoAvatarAndNameItem(account: account, peer: peer, cachedData: cachedData, editingState: nil, sectionId: self.section.rawValue, style: .plain) case let .about(text): return PeerInfoTextWithLabelItem(label: "about", text: text, multiline: true, sectionId: self.section.rawValue) case let .userName(value): @@ -173,7 +173,7 @@ enum ChannelInfoEntry: PeerInfoEntry { label = "Enabled" } return PeerInfoDisclosureItem(title: "Notifications", label: label, sectionId: self.section.rawValue, style: .plain, action: { - interaction.changeNotificationNoteSettings() + interaction.changeNotificationMuteSettings() }) case .report: return PeerInfoActionItem(title: "Report", kind: .generic, alignment: .natural, sectionId: self.section.rawValue, style: .plain, action: { @@ -187,7 +187,7 @@ enum ChannelInfoEntry: PeerInfoEntry { } } -func channelBroadcastInfoEntries(view: PeerView) -> [PeerInfoEntry] { +func channelBroadcastInfoEntries(view: PeerView) -> PeerInfoEntries { var entries: [PeerInfoEntry] = [] entries.append(ChannelInfoEntry.info(peer: view.peers[view.peerId], cachedData: view.cachedData)) if let cachedChannelData = view.cachedData as? CachedChannelData { @@ -206,5 +206,5 @@ func channelBroadcastInfoEntries(view: PeerView) -> [PeerInfoEntry] { entries.append(ChannelInfoEntry.leave) } } - return entries + return PeerInfoEntries(entries: entries, leftNavigationButton: nil, rightNavigationButton: nil) } diff --git a/TelegramUI/ChatChannelSubscriberInputPanelNode.swift b/TelegramUI/ChatChannelSubscriberInputPanelNode.swift index 843c1e3c3b..76adf0c4fd 100644 --- a/TelegramUI/ChatChannelSubscriberInputPanelNode.swift +++ b/TelegramUI/ChatChannelSubscriberInputPanelNode.swift @@ -49,23 +49,7 @@ final class ChatChannelSubscriberInputPanelNode: ChatInputPanelNode { private let actionDisposable = MetaDisposable() - override var peer: Peer? { - didSet { - if let peer = self.peer, oldValue == nil || !peer.isEqual(oldValue!) { - if let action = actionForPeer(peer) { - self.action = action - let (title, color) = titleAndColorForAction(action) - self.button.setTitle(title, for: []) - self.button.setTitleColor(color, for: [.normal]) - self.button.setTitleColor(color.withAlphaComponent(0.5), for: [.highlighted]) - self.button.sizeToFit() - self.setNeedsLayout() - } else { - self.action = nil - } - } - } - } + private var presentationInterfaceState = ChatPresentationInterfaceState() override init() { self.button = UIButton() @@ -84,23 +68,6 @@ final class ChatChannelSubscriberInputPanelNode: ChatInputPanelNode { self.actionDisposable.dispose() } - override func calculateSizeThatFits(_ constrainedSize: CGSize) -> CGSize { - return CGSize(width: constrainedSize.width, height: 45.0) - } - - override func layout() { - super.layout() - - let bounds = self.bounds - - let buttonSize = self.button.bounds.size - self.button.frame = CGRect(origin: CGPoint(x: floor((bounds.size.width - buttonSize.width) / 2.0), y: floor((bounds.size.height - buttonSize.height) / 2.0)), size: buttonSize) - - //_activityIndicator.frame = CGRectMake(self.frame.size.width - _activityIndicator.frame.size.width - 12.0f, CGFloor((self.frame.size.height - _activityIndicator.frame.size.height) / 2.0f), _activityIndicator.frame.size.width, _activityIndicator.frame.size.height); - let indicatorSize = self.activityIndicator.bounds.size - self.activityIndicator.frame = CGRect(origin: CGPoint(x: bounds.size.width - indicatorSize.width - 12.0, y: floor((bounds.size.height - indicatorSize.height) / 2.0)), size: indicatorSize) - } - override func hitTest(_ point: CGPoint, with event: UIEvent?) -> UIView? { if self.bounds.contains(point) { return self.button @@ -110,7 +77,7 @@ final class ChatChannelSubscriberInputPanelNode: ChatInputPanelNode { } @objc func buttonPressed() { - guard let account = self.account, let action = self.action, let peer = self.peer else { + guard let account = self.account, let action = self.action, let peer = self.presentationInterfaceState.peer else { return } @@ -135,4 +102,34 @@ final class ChatChannelSubscriberInputPanelNode: ChatInputPanelNode { break } } + + override func updateLayout(width: CGFloat, transition: ContainedViewLayoutTransition, interfaceState: ChatPresentationInterfaceState) -> CGFloat { + if self.presentationInterfaceState != interfaceState { + let previousState = self.presentationInterfaceState + self.presentationInterfaceState = interfaceState + + if let peer = interfaceState.peer, previousState.peer == nil || !peer.isEqual(previousState.peer!) { + if let action = actionForPeer(peer) { + self.action = action + let (title, color) = titleAndColorForAction(action) + self.button.setTitle(title, for: []) + self.button.setTitleColor(color, for: [.normal]) + self.button.setTitleColor(color.withAlphaComponent(0.5), for: [.highlighted]) + self.button.sizeToFit() + } else { + self.action = nil + } + } + } + + let panelHeight: CGFloat = 47.0 + + let buttonSize = self.button.bounds.size + self.button.frame = CGRect(origin: CGPoint(x: floor((width - buttonSize.width) / 2.0), y: floor((panelHeight - buttonSize.height) / 2.0)), size: buttonSize) + + let indicatorSize = self.activityIndicator.bounds.size + self.activityIndicator.frame = CGRect(origin: CGPoint(x: width - indicatorSize.width - 12.0, y: floor((panelHeight - indicatorSize.height) / 2.0)), size: indicatorSize) + + return 47.0 + } } diff --git a/TelegramUI/ChatController.swift b/TelegramUI/ChatController.swift index f14b96163b..7d894519a9 100644 --- a/TelegramUI/ChatController.swift +++ b/TelegramUI/ChatController.swift @@ -22,7 +22,7 @@ public class ChatController: ViewController { private var didSetPeerReady = false private let peerView = Promise() - private var presentationInterfaceState = ChatPresentationInterfaceState(interfaceState: ChatInterfaceState(), peer: nil, inputContext: nil) + private var presentationInterfaceState = ChatPresentationInterfaceState() private let chatInterfaceStatePromise = Promise() private var chatTitleView: ChatTitleView? @@ -154,13 +154,17 @@ public class ChatController: ViewController { } } }, clickThroughMessage: { [weak self] in - self?.view.endEditing(true) + self?.chatDisplayNode.dismissInput() }, toggleMessageSelection: { [weak self] id in if let strongSelf = self, strongSelf.isNodeLoaded { if let message = strongSelf.chatDisplayNode.historyNode.messageInCurrentHistoryView(id) { - strongSelf.updateChatPresentationInterfaceState(animated: false, { $0.updatedInterfaceState { $0.withToggledSelectedMessage(id) } }) + strongSelf.updateChatPresentationInterfaceState(animated: false, interactive: true, { $0.updatedInterfaceState { $0.withToggledSelectedMessage(id) } }) } } + }, sendSticker: { [weak self] file in + if let strongSelf = self { + enqueueMessage(account: strongSelf.account, peerId: strongSelf.peerId, text: "", replyMessageId: nil, media: file).start() + } }) self.controllerInteraction = controllerInteraction @@ -173,7 +177,7 @@ public class ChatController: ViewController { chatInfoButtonItem.action = #selector(self.rightNavigationButtonAction) self.chatInfoNavigationButton = ChatNavigationButton(action: .openChatInfo, buttonItem: chatInfoButtonItem) - self.updateChatPresentationInterfaceState(animated: false, { return $0 }) + self.updateChatPresentationInterfaceState(animated: false, interactive: false, { return $0 }) self.peerView.set(account.viewTracker.peerView(peerId)) @@ -184,7 +188,7 @@ public class ChatController: ViewController { strongSelf.chatTitleView?.peerView = peerView (strongSelf.chatInfoNavigationButton?.buttonItem.customDisplayNode as? ChatAvatarNavigationNode)?.avatarNode.setPeer(account: strongSelf.account, peer: peer) } - strongSelf.updateChatPresentationInterfaceState(animated: false, { return $0.updatedPeer { _ in return peerView.peers[peerId] } }) + strongSelf.updateChatPresentationInterfaceState(animated: false, interactive: false, { return $0.updatedPeer { _ in return peerView.peers[peerId] } }) if !strongSelf.didSetPeerReady { strongSelf.didSetPeerReady = true strongSelf._peerReady.set(.single(true)) @@ -288,12 +292,23 @@ public class ChatController: ViewController { } self.chatDisplayNode.requestUpdateChatInterfaceState = { [weak self] animated, f in - self?.updateChatPresentationInterfaceState(animated: animated, { $0.updatedInterfaceState(f) }) + self?.updateChatPresentationInterfaceState(animated: animated, interactive: true, { $0.updatedInterfaceState(f) }) } self.chatDisplayNode.displayAttachmentMenu = { [weak self] in if let strongSelf = self { let controller = ChatMediaActionSheetController() + controller.photo = { [weak strongSelf] asset in + if let strongSelf = strongSelf { + var randomId: Int64 = 0 + arc4random_buf(&randomId, 8) + let size = CGSize(width: CGFloat(asset.pixelWidth), height: CGFloat(asset.pixelHeight)) + let scaledSize = size.aspectFitted(CGSize(width: 1280.0, height: 1280.0)) + let resource = PhotoLibraryMediaResource(localIdentifier: asset.localIdentifier) + let media = TelegramMediaImage(imageId: MediaId(namespace: Namespaces.Media.LocalImage, id: randomId), representations: [TelegramMediaImageRepresentation(dimensions: scaledSize, resource: resource)]) + enqueueMessage(account: strongSelf.account, peerId: strongSelf.peerId, text: "", replyMessageId: nil, media: media).start() + } + } controller.location = { [weak strongSelf] in if let strongSelf = strongSelf { let mapInputController = MapInputController() @@ -317,14 +332,14 @@ public class ChatController: ViewController { let interfaceInteraction = ChatPanelInterfaceInteraction(setupReplyMessage: { [weak self] messageId in if let strongSelf = self, strongSelf.isNodeLoaded { if let message = strongSelf.chatDisplayNode.historyNode.messageInCurrentHistoryView(messageId) { - strongSelf.updateChatPresentationInterfaceState(animated: true, { $0.updatedInterfaceState { $0.withUpdatedReplyMessageId(message.id) } }) + strongSelf.updateChatPresentationInterfaceState(animated: true, interactive: true, { $0.updatedInterfaceState { $0.withUpdatedReplyMessageId(message.id) } }) strongSelf.chatDisplayNode.ensureInputViewFocused() } } }, beginMessageSelection: { [weak self] messageId in if let strongSelf = self, strongSelf.isNodeLoaded { if let message = strongSelf.chatDisplayNode.historyNode.messageInCurrentHistoryView(messageId) { - strongSelf.updateChatPresentationInterfaceState(animated: true, { $0.updatedInterfaceState { $0.withUpdatedSelectedMessage(message.id) } }) + strongSelf.updateChatPresentationInterfaceState(animated: true, interactive: true,{ $0.updatedInterfaceState { $0.withUpdatedSelectedMessage(message.id) } }) } } }, deleteSelectedMessages: { [weak self] in @@ -334,7 +349,7 @@ public class ChatController: ViewController { modifier.deleteMessages(Array(messageIds)) }).start() } - strongSelf.updateChatPresentationInterfaceState(animated: true, { $0.updatedInterfaceState { $0.withoutSelectionState() } }) + strongSelf.updateChatPresentationInterfaceState(animated: true, interactive: true, { $0.updatedInterfaceState { $0.withoutSelectionState() } }) } }, forwardSelectedMessages: { [weak self] in if let strongSelf = self { @@ -343,7 +358,11 @@ public class ChatController: ViewController { } }, updateTextInputState: { [weak self] textInputState in if let strongSelf = self { - strongSelf.updateChatPresentationInterfaceState { $0.updatedInterfaceState { $0.withUpdatedInputState(textInputState) } } + strongSelf.updateChatPresentationInterfaceState(animated: true, interactive: true, { $0.updatedInterfaceState { $0.withUpdatedInputState(textInputState) } }) + } + }, updateInputMode: { [weak self] f in + if let strongSelf = self { + strongSelf.updateChatPresentationInterfaceState(animated: true, interactive: true, { $0.updatedInputMode(f) }) } }) @@ -362,6 +381,8 @@ public class ChatController: ViewController { self.chatDisplayNode.historyNode.preloadPages = true self.chatDisplayNode.historyNode.canReadHistory.set(.single(true)) + + self.chatDisplayNode.loadInputPanels() } override public func containerLayoutUpdated(_ layout: ContainerViewLayout, transition: ContainedViewLayoutTransition) { @@ -374,13 +395,14 @@ public class ChatController: ViewController { }) } - func updateChatPresentationInterfaceState(animated: Bool = true, _ f: (ChatPresentationInterfaceState) -> ChatPresentationInterfaceState) { + func updateChatPresentationInterfaceState(animated: Bool = true, interactive: Bool, _ f: (ChatPresentationInterfaceState) -> ChatPresentationInterfaceState) { let temporaryChatPresentationInterfaceState = f(self.presentationInterfaceState) let inputContext = inputContextForChatPresentationIntefaceState(temporaryChatPresentationInterfaceState, account: self.account) - let updatedChatPresentationInterfaceState = temporaryChatPresentationInterfaceState.updatedInputContext { _ in return inputContext } + let inputTextPanelState = inputTextPanelStateForChatPresentationInterfaceState(temporaryChatPresentationInterfaceState, account: self.account) + let updatedChatPresentationInterfaceState = temporaryChatPresentationInterfaceState.updatedInputContext({ _ in return inputContext }).updatedInputTextPanelState({ _ in return inputTextPanelState }) if self.isNodeLoaded { - self.chatDisplayNode.updateChatPresentationInterfaceState(updatedChatPresentationInterfaceState, animated: animated) + self.chatDisplayNode.updateChatPresentationInterfaceState(updatedChatPresentationInterfaceState, animated: animated, interactive: interactive) } self.presentationInterfaceState = updatedChatPresentationInterfaceState self.chatInterfaceStatePromise.set(.single(updatedChatPresentationInterfaceState.interfaceState)) @@ -429,7 +451,7 @@ public class ChatController: ViewController { private func navigationButtonAction(_ action: ChatNavigationButtonAction) { switch action { case .cancelMessageSelection: - self.updateChatPresentationInterfaceState(animated: true, { $0.updatedInterfaceState { $0.withoutSelectionState() } }) + self.updateChatPresentationInterfaceState(animated: true, interactive: true, { $0.updatedInterfaceState { $0.withoutSelectionState() } }) case .clearHistory: let actionSheet = ActionSheetController() actionSheet.setItemGroups([ActionSheetItemGroup(items: [ diff --git a/TelegramUI/ChatControllerInteraction.swift b/TelegramUI/ChatControllerInteraction.swift index e726f11eaa..3f82264aaa 100644 --- a/TelegramUI/ChatControllerInteraction.swift +++ b/TelegramUI/ChatControllerInteraction.swift @@ -1,6 +1,7 @@ import Foundation import Postbox import AsyncDisplayKit +import TelegramCore public enum ChatControllerInteractionNavigateToPeer { case chat @@ -16,13 +17,15 @@ public final class ChatControllerInteraction { var hiddenMedia: [MessageId: [Media]] = [:] var selectionState: ChatInterfaceSelectionState? let toggleMessageSelection: (MessageId) -> Void + let sendSticker: (TelegramMediaFile) -> Void - public init(openMessage: @escaping (MessageId) -> Void, openPeer: @escaping (PeerId, ChatControllerInteractionNavigateToPeer) -> Void, openMessageContextMenu: @escaping (MessageId, ASDisplayNode, CGRect) -> Void, navigateToMessage: @escaping (MessageId, MessageId) -> Void, clickThroughMessage: @escaping () -> Void, toggleMessageSelection: @escaping (MessageId) -> Void) { + public init(openMessage: @escaping (MessageId) -> Void, openPeer: @escaping (PeerId, ChatControllerInteractionNavigateToPeer) -> Void, openMessageContextMenu: @escaping (MessageId, ASDisplayNode, CGRect) -> Void, navigateToMessage: @escaping (MessageId, MessageId) -> Void, clickThroughMessage: @escaping () -> Void, toggleMessageSelection: @escaping (MessageId) -> Void, sendSticker: @escaping (TelegramMediaFile) -> Void) { self.openMessage = openMessage self.openPeer = openPeer self.openMessageContextMenu = openMessageContextMenu self.navigateToMessage = navigateToMessage self.clickThroughMessage = clickThroughMessage self.toggleMessageSelection = toggleMessageSelection + self.sendSticker = sendSticker } } diff --git a/TelegramUI/ChatControllerNode.swift b/TelegramUI/ChatControllerNode.swift index e12f3a711e..c223f7eab3 100644 --- a/TelegramUI/ChatControllerNode.swift +++ b/TelegramUI/ChatControllerNode.swift @@ -15,6 +15,7 @@ private func shouldRequestLayoutOnPresentationInterfaceStateTransition(_ lhs: Ch class ChatControllerNode: ASDisplayNode { let account: Account let peerId: PeerId + let controllerInteraction: ChatControllerInteraction let backgroundNode: ASDisplayNode let historyNode: ChatHistoryListNode @@ -26,7 +27,10 @@ class ChatControllerNode: ASDisplayNode { private var accessoryPanelNode: AccessoryPanelNode? private var inputContextPanelNode: ChatInputContextPanelNode? + private var inputNode: ChatInputNode? + private var textInputPanelNode: ChatTextInputPanelNode? + private var inputMediaNode: ChatMediaInputNode? let navigateToLatestButton: ChatHistoryNavigationButtonNode @@ -41,9 +45,15 @@ class ChatControllerNode: ASDisplayNode { var interfaceInteraction: ChatPanelInterfaceInteraction? + private var containerLayoutAndNavigationBarHeight: (ContainerViewLayout, CGFloat)? + + private var scheduledLayoutTransitionRequestId: Int = 0 + private var scheduledLayoutTransitionRequest: (Int, ContainedViewLayoutTransition)? + init(account: Account, peerId: PeerId, messageId: MessageId?, controllerInteraction: ChatControllerInteraction) { self.account = account self.peerId = peerId + self.controllerInteraction = controllerInteraction self.backgroundNode = ASDisplayNode() self.backgroundNode.isLayerBacked = true @@ -54,11 +64,11 @@ class ChatControllerNode: ASDisplayNode { self.historyNode = ChatHistoryListNode(account: account, peerId: peerId, tagMask: nil, messageId: messageId, controllerInteraction: controllerInteraction) self.inputPanelBackgroundNode = ASDisplayNode() - self.inputPanelBackgroundNode.backgroundColor = UIColor(0xfafafa) + self.inputPanelBackgroundNode.backgroundColor = UIColor(0xF5F6F8) self.inputPanelBackgroundNode.isLayerBacked = true self.inputPanelBackgroundSeparatorNode = ASDisplayNode() - self.inputPanelBackgroundSeparatorNode.backgroundColor = UIColor(0xcdccd3) + self.inputPanelBackgroundSeparatorNode.backgroundColor = UIColor(0xC9CDD1) self.inputPanelBackgroundSeparatorNode.isLayerBacked = true self.navigateToLatestButton = ChatHistoryNavigationButtonNode() @@ -113,14 +123,58 @@ class ChatControllerNode: ASDisplayNode { } func containerLayoutUpdated(_ layout: ContainerViewLayout, navigationBarHeight: CGFloat, transition: ContainedViewLayoutTransition, listViewTransaction: (ListViewUpdateSizeAndInsets) -> Void) { - var insets = layout.insets(options: [.input]) + //print("update \(self.scheduledLayoutTransitionRequest)") + self.scheduledLayoutTransitionRequest = nil + var previousInputHeight: CGFloat = 0.0 + if let (previousLayout, _) = self.containerLayoutAndNavigationBarHeight { + previousInputHeight = previousLayout.insets(options: [.input]).bottom + } + if let inputNode = self.inputNode { + previousInputHeight = inputNode.bounds.size.height + } + self.containerLayoutAndNavigationBarHeight = (layout, navigationBarHeight) + + var dismissedInputNode: ChatInputNode? + var immediatelyLayoutInputNodeAndAnimateAppearance = false + var inputNodeHeight: CGFloat? + if let inputNode = inputNodeForChatPresentationIntefaceState(self.chatPresentationInterfaceState, account: self.account, currentNode: self.inputNode, interfaceInteraction: self.interfaceInteraction, inputMediaNode: self.inputMediaNode, controllerInteraction: self.controllerInteraction) { + if let inputTextPanelNode = self.inputPanelNode as? ChatTextInputPanelNode { + inputTextPanelNode.ensureUnfocused() + } + if let inputMediaNode = inputNode as? ChatMediaInputNode, self.inputMediaNode == nil { + self.inputMediaNode = inputMediaNode + } + if self.inputNode != inputNode { + dismissedInputNode = self.inputNode + self.inputNode = inputNode + immediatelyLayoutInputNodeAndAnimateAppearance = true + self.insertSubnode(inputNode, belowSubnode: self.inputPanelBackgroundNode) + } + inputNodeHeight = inputNode.updateLayout(width: layout.size.width, transition: immediatelyLayoutInputNodeAndAnimateAppearance ? .immediate : transition, interfaceState: self.chatPresentationInterfaceState) + } else if let inputNode = self.inputNode { + dismissedInputNode = inputNode + self.inputNode = nil + } + + if let inputMediaNode = self.inputMediaNode, inputMediaNode != self.inputNode { + inputMediaNode.updateLayout(width: layout.size.width, transition: .immediate, interfaceState: self.chatPresentationInterfaceState) + } + + var insets: UIEdgeInsets + if let inputNodeHeight = inputNodeHeight { + insets = layout.insets(options: []) + insets.bottom += inputNodeHeight + } else { + insets = layout.insets(options: [.input]) + } insets.top += navigationBarHeight var duration: Double = 0.0 var curve: UInt = 0 + var animated = true switch transition { case .immediate: - break + animated = false case let .animated(animationDuration, animationCurve): duration = animationDuration switch animationCurve { @@ -150,16 +204,19 @@ class ChatControllerNode: ASDisplayNode { var inputPanelSize: CGSize? var immediatelyLayoutInputPanelAndAnimateAppearance = false if let inputPanelNode = inputPanelForChatPresentationIntefaceState(self.chatPresentationInterfaceState, account: self.account, currentPanel: self.inputPanelNode, textInputPanelNode: self.textInputPanelNode, interfaceInteraction: self.interfaceInteraction) { - inputPanelSize = inputPanelNode.measure(CGSize(width: layout.size.width, height: layout.size.height)) - if inputPanelNode !== self.inputPanelNode { if let inputTextPanelNode = self.inputPanelNode as? ChatTextInputPanelNode { inputTextPanelNode.ensureUnfocused() } dismissedInputPanelNode = self.inputPanelNode immediatelyLayoutInputPanelAndAnimateAppearance = true + let inputPanelHeight = inputPanelNode.updateLayout(width: layout.size.width, transition: .immediate, interfaceState: self.chatPresentationInterfaceState) + inputPanelSize = CGSize(width: layout.size.width, height: inputPanelHeight) self.inputPanelNode = inputPanelNode self.insertSubnode(inputPanelNode, belowSubnode: self.navigateToLatestButton) + } else { + let inputPanelHeight = inputPanelNode.updateLayout(width: layout.size.width, transition: transition, interfaceState: self.chatPresentationInterfaceState) + inputPanelSize = CGSize(width: layout.size.width, height: inputPanelHeight) } } else { dismissedInputPanelNode = self.inputPanelNode @@ -234,7 +291,7 @@ class ChatControllerNode: ASDisplayNode { let navigateToLatestButtonFrame = CGRect(origin: CGPoint(x: layout.size.width - navigateToLatestButtonSize.width - 6.0, y: layout.size.height - insets.bottom - inputPanelsHeight - navigateToLatestButtonSize.height - 6.0), size: navigateToLatestButtonSize) transition.updateFrame(node: self.inputPanelBackgroundNode, frame: inputBackgroundFrame) - transition.updateFrame(node: self.inputPanelBackgroundSeparatorNode, frame: CGRect(origin: inputBackgroundFrame.origin, size: CGSize(width: inputBackgroundFrame.size.width, height: UIScreenPixel))) + transition.updateFrame(node: self.inputPanelBackgroundSeparatorNode, frame: CGRect(origin: CGPoint(x: 0.0, y: inputBackgroundFrame.origin.y - UIScreenPixel), size: CGSize(width: inputBackgroundFrame.size.width, height: UIScreenPixel))) transition.updateFrame(node: self.navigateToLatestButton, frame: navigateToLatestButtonFrame) if let inputPanelNode = self.inputPanelNode, let inputPanelFrame = inputPanelFrame, !inputPanelNode.frame.equalTo(inputPanelFrame) { @@ -245,7 +302,6 @@ class ChatControllerNode: ASDisplayNode { transition.updateFrame(node: inputPanelNode, frame: inputPanelFrame) transition.updateAlpha(node: inputPanelNode, alpha: 1.0) - inputPanelNode.updateFrames(transition: transition) } if let accessoryPanelNode = self.accessoryPanelNode, let accessoryPanelFrame = accessoryPanelFrame, !accessoryPanelNode.frame.equalTo(accessoryPanelFrame) { @@ -271,6 +327,19 @@ class ChatControllerNode: ASDisplayNode { } } + if let inputNode = self.inputNode, let inputNodeHeight = inputNodeHeight { + let inputNodeFrame = CGRect(origin: CGPoint(x: 0.0, y: layout.size.height - inputNodeHeight), size: CGSize(width: layout.size.width, height: inputNodeHeight)) + if immediatelyLayoutInputNodeAndAnimateAppearance { + var adjustedForPreviousInputHeightFrame = inputNodeFrame + let heightDifference = inputNodeHeight - previousInputHeight + adjustedForPreviousInputHeightFrame.origin.y += heightDifference + inputNode.frame = adjustedForPreviousInputHeightFrame + transition.updateFrame(node: inputNode, frame: inputNodeFrame) + } else { + transition.updateFrame(node: inputNode, frame: inputNodeFrame) + } + } + if let dismissedInputPanelNode = dismissedInputPanelNode { var frameCompleted = false var alphaCompleted = false @@ -339,14 +408,34 @@ class ChatControllerNode: ASDisplayNode { completed() }) } + + if let dismissedInputNode = dismissedInputNode { + transition.updateFrame(node: dismissedInputNode, frame: CGRect(origin: CGPoint(x: 0.0, y: layout.size.height - insets.bottom - CGFloat(FLT_EPSILON)), size: CGSize(width: layout.size.width, height: max(insets.bottom, dismissedInputNode.bounds.size.height))), completion: { [weak dismissedInputNode] _ in + dismissedInputNode?.removeFromSupernode() + }) + } } - func updateChatPresentationInterfaceState(_ chatPresentationInterfaceState: ChatPresentationInterfaceState, animated: Bool) { + private func chatPresentationInterfaceStateRequiresInputFocus(_ state: ChatPresentationInterfaceState) -> Bool { + switch state.inputMode { + case .text: + if state.interfaceState.selectionState != nil { + return false + } else { + return true + } + default: + return false + } + } + + func updateChatPresentationInterfaceState(_ chatPresentationInterfaceState: ChatPresentationInterfaceState, animated: Bool, interactive: Bool) { if let textInputPanelNode = self.textInputPanelNode { self.chatPresentationInterfaceState = self.chatPresentationInterfaceState.updatedInterfaceState { $0.withUpdatedInputState(textInputPanelNode.inputTextState) } } if self.chatPresentationInterfaceState != chatPresentationInterfaceState { + var updatedInputFocus = self.chatPresentationInterfaceStateRequiresInputFocus(self.chatPresentationInterfaceState) != self.chatPresentationInterfaceStateRequiresInputFocus(chatPresentationInterfaceState) var updateInputTextState = self.chatPresentationInterfaceState.interfaceState.inputState != chatPresentationInterfaceState.interfaceState.inputState self.chatPresentationInterfaceState = chatPresentationInterfaceState @@ -354,8 +443,28 @@ class ChatControllerNode: ASDisplayNode { textInputPanelNode.inputTextState = chatPresentationInterfaceState.interfaceState.inputState } - if !self.ignoreUpdateHeight { - self.requestLayout(animated ? .animated(duration: 0.4, curve: .spring) : .immediate) + let layoutTransition: ContainedViewLayoutTransition = animated ? .animated(duration: 0.4, curve: .spring) : .immediate + + if updatedInputFocus { + if !self.ignoreUpdateHeight { + self.scheduleLayoutTransitionRequest(layoutTransition) + } + + if self.chatPresentationInterfaceStateRequiresInputFocus(chatPresentationInterfaceState) { + self.ensureInputViewFocused() + } else { + if let inputTextPanelNode = self.inputPanelNode as? ChatTextInputPanelNode { + inputTextPanelNode.ensureUnfocused() + } + } + } else { + if !self.ignoreUpdateHeight { + if interactive { + self.scheduleLayoutTransitionRequest(layoutTransition) + } else { + self.requestLayout(layoutTransition) + } + } } } } @@ -368,7 +477,39 @@ class ChatControllerNode: ASDisplayNode { @objc func tapGesture(_ recognizer: UITapGestureRecognizer) { if recognizer.state == .ended { - self.view.endEditing(true) + self.dismissInput() } } + + func dismissInput() { + switch self.chatPresentationInterfaceState.inputMode { + case .none: + break + default: + self.interfaceInteraction?.updateInputMode({ _ in .none }) + } + } + + private func scheduleLayoutTransitionRequest(_ transition: ContainedViewLayoutTransition) { + let requestId = self.scheduledLayoutTransitionRequestId + self.scheduledLayoutTransitionRequestId += 1 + self.scheduledLayoutTransitionRequest = (requestId, transition) + (self.view as? UITracingLayerView)?.schedule(layout: { [weak self] in + if let strongSelf = self { + if let (currentRequestId, currentRequestTransition) = strongSelf.scheduledLayoutTransitionRequest { + strongSelf.scheduledLayoutTransitionRequest = nil + strongSelf.requestLayout(currentRequestTransition) + } + } + }) + self.setNeedsLayout() + } + + func loadInputPanels() { + /*if self.inputMediaNode == nil { + let inputNode = ChatMediaInputNode(account: self.account, controllerInteraction: self.controllerInteraction) + inputNode.interfaceInteraction = interfaceInteraction + self.inputMediaNode = inputNode + }*/ + } } diff --git a/TelegramUI/ChatDocumentGalleryItem.swift b/TelegramUI/ChatDocumentGalleryItem.swift index a274cef0c9..d4562ec0f5 100644 --- a/TelegramUI/ChatDocumentGalleryItem.swift +++ b/TelegramUI/ChatDocumentGalleryItem.swift @@ -48,7 +48,7 @@ class ChatDocumentGalleryItemNode: GalleryItemNode { private var accountAndFile: (Account, TelegramMediaFile)? private let dataDisposable = MetaDisposable() - private var isVisible = false + private var itemIsVisible = false override init() { if #available(iOS 9.0, *) { @@ -93,7 +93,7 @@ class ChatDocumentGalleryItemNode: GalleryItemNode { if let fileName = file.fileName { pathExtension = (fileName as NSString).pathExtension } - let data = account.postbox.mediaBox.resourceData(CloudFileMediaResource(location: file.location, size: file.size), pathExtension: pathExtension, complete: true) + let data = account.postbox.mediaBox.resourceData(file.resource, pathExtension: pathExtension, complete: true) |> deliverOnMainQueue self.dataDisposable.set(data.start(next: { [weak self] data in if let strongSelf = self { diff --git a/TelegramUI/ChatHistoryGridNode.swift b/TelegramUI/ChatHistoryGridNode.swift index b7ee37e69d..aaeb695b10 100644 --- a/TelegramUI/ChatHistoryGridNode.swift +++ b/TelegramUI/ChatHistoryGridNode.swift @@ -284,18 +284,18 @@ public final class ChatHistoryGridNode: GridNode, ChatHistoryNode { var updateLayout: GridNodeUpdateLayout? if let updateSizeAndInsets = updateSizeAndInsets { - updateLayout = GridNodeUpdateLayout(layout: GridNodeLayout(size: updateSizeAndInsets.size, insets: updateSizeAndInsets.insets, preloadSize: 400.0, itemSize: CGSize(width: 200.0, height: 200.0), indexOffset: 0), transition: .immediate) + updateLayout = GridNodeUpdateLayout(layout: GridNodeLayout(size: updateSizeAndInsets.size, insets: updateSizeAndInsets.insets, preloadSize: 400.0, itemSize: CGSize(width: 200.0, height: 200.0)), transition: .immediate) } - self.transaction(GridNodeTransaction(deleteItems: mappedTransition.deleteItems, insertItems: mappedTransition.insertItems, updateItems: mappedTransition.updateItems, scrollToItem: mappedTransition.scrollToItem, updateLayout: updateLayout, stationaryItemRange: mappedTransition.stationaryItemRange), completion: completion) + self.transaction(GridNodeTransaction(deleteItems: mappedTransition.deleteItems, insertItems: mappedTransition.insertItems, updateItems: mappedTransition.updateItems, scrollToItem: mappedTransition.scrollToItem, updateLayout: updateLayout, stationaryItems: .none, updateFirstIndexInSectionOffset: nil), completion: completion) } else { - self.transaction(GridNodeTransaction(deleteItems: transition.deleteItems, insertItems: transition.insertItems, updateItems: transition.updateItems, scrollToItem: transition.scrollToItem, updateLayout: nil, stationaryItemRange: transition.stationaryItemRange), completion: completion) + self.transaction(GridNodeTransaction(deleteItems: transition.deleteItems, insertItems: transition.insertItems, updateItems: transition.updateItems, scrollToItem: transition.scrollToItem, updateLayout: nil, stationaryItems: .none, updateFirstIndexInSectionOffset: nil), completion: completion) } } } public func updateLayout(transition: ContainedViewLayoutTransition, updateSizeAndInsets: ListViewUpdateSizeAndInsets) { - self.transaction(GridNodeTransaction(deleteItems: [], insertItems: [], updateItems: [], scrollToItem: nil, updateLayout: GridNodeUpdateLayout(layout: GridNodeLayout(size: updateSizeAndInsets.size, insets: updateSizeAndInsets.insets, preloadSize: 400.0, itemSize: itemSizeForContainerLayout(size: updateSizeAndInsets.size), indexOffset: 0), transition: .immediate), stationaryItemRange: nil), completion: { _ in }) + self.transaction(GridNodeTransaction(deleteItems: [], insertItems: [], updateItems: [], scrollToItem: nil, updateLayout: GridNodeUpdateLayout(layout: GridNodeLayout(size: updateSizeAndInsets.size, insets: updateSizeAndInsets.insets, preloadSize: 400.0, itemSize: itemSizeForContainerLayout(size: updateSizeAndInsets.size)), transition: .immediate), stationaryItems: .none,updateFirstIndexInSectionOffset: nil), completion: { _ in }) if !self.dequeuedInitialTransitionOnLayout { self.dequeuedInitialTransitionOnLayout = true diff --git a/TelegramUI/ChatImageGalleryItem.swift b/TelegramUI/ChatImageGalleryItem.swift index 4461f256e7..e1868e81a7 100644 --- a/TelegramUI/ChatImageGalleryItem.swift +++ b/TelegramUI/ChatImageGalleryItem.swift @@ -90,8 +90,7 @@ final class ChatImageGalleryItemNode: ZoomableContentGalleryItemNode { self.imageNode.asyncLayout()(TransformImageArguments(corners: ImageCorners(), imageSize: displaySize, boundingSize: displaySize, intrinsicInsets: UIEdgeInsets()))() self.imageNode.setSignal(account: account, signal: chatMessagePhoto(account: account, photo: image), dispatchOnDisplayLink: false) self.zoomableContent = (largestSize.dimensions, self.imageNode) - - self.fetchDisposable.set(account.postbox.mediaBox.fetchedResource(CloudFileMediaResource(location: largestSize.location, size: largestSize.size ?? 0)).start()) + self.fetchDisposable.set(account.postbox.mediaBox.fetchedResource(largestSize.resource).start()) } else { self._ready.set(.single(Void())) } @@ -190,7 +189,7 @@ final class ChatImageGalleryItemNode: ZoomableContentGalleryItemNode { if let (account, media) = self.accountAndMedia, let file = media as? TelegramMediaFile { if isVisible { - self.fetchDisposable.set(account.postbox.mediaBox.fetchedResource(CloudFileMediaResource(location: file.location, size: file.size)).start()) + self.fetchDisposable.set(account.postbox.mediaBox.fetchedResource(file.resource).start()) } else { self.fetchDisposable.set(nil) } diff --git a/TelegramUI/ChatInputNode.swift b/TelegramUI/ChatInputNode.swift new file mode 100644 index 0000000000..42b3a396f6 --- /dev/null +++ b/TelegramUI/ChatInputNode.swift @@ -0,0 +1,11 @@ +import Foundation +import Display +import AsyncDisplayKit + +class ChatInputNode: ASDisplayNode { + var interfaceInteraction: ChatPanelInterfaceInteraction? + + func updateLayout(width: CGFloat, transition: ContainedViewLayoutTransition, interfaceState: ChatPresentationInterfaceState) -> CGFloat { + return 0.0 + } +} diff --git a/TelegramUI/ChatInputPanelNode.swift b/TelegramUI/ChatInputPanelNode.swift index 2934a34f9f..0625bcfc64 100644 --- a/TelegramUI/ChatInputPanelNode.swift +++ b/TelegramUI/ChatInputPanelNode.swift @@ -7,8 +7,8 @@ import TelegramCore class ChatInputPanelNode: ASDisplayNode { var account: Account? var interfaceInteraction: ChatPanelInterfaceInteraction? - var peer: Peer? - func updateFrames(transition: ContainedViewLayoutTransition) { + func updateLayout(width: CGFloat, transition: ContainedViewLayoutTransition, interfaceState: ChatPresentationInterfaceState) -> CGFloat { + return 0.0 } } diff --git a/TelegramUI/ChatInterfaceInputContexts.swift b/TelegramUI/ChatInterfaceInputContexts.swift index 994d84e489..659b05c5f1 100644 --- a/TelegramUI/ChatInterfaceInputContexts.swift +++ b/TelegramUI/ChatInterfaceInputContexts.swift @@ -10,3 +10,16 @@ func inputContextForChatPresentationIntefaceState(_ chatPresentationInterfaceSta } return nil } + +func inputTextPanelStateForChatPresentationInterfaceState(_ chatPresentationInterfaceState: ChatPresentationInterfaceState, account: Account) -> ChatTextInputPanelState { + switch chatPresentationInterfaceState.inputMode { + case .media: + return ChatTextInputPanelState(accessoryItems: [.keyboard]) + case .none, .text: + if chatPresentationInterfaceState.interfaceState.inputState.inputText.isEmpty { + return ChatTextInputPanelState(accessoryItems: [.stickers]) + } else { + return ChatTextInputPanelState(accessoryItems: []) + } + } +} diff --git a/TelegramUI/ChatInterfaceInputNodes.swift b/TelegramUI/ChatInterfaceInputNodes.swift new file mode 100644 index 0000000000..43d3945d90 --- /dev/null +++ b/TelegramUI/ChatInterfaceInputNodes.swift @@ -0,0 +1,21 @@ +import Foundation +import AsyncDisplayKit +import TelegramCore + +func inputNodeForChatPresentationIntefaceState(_ chatPresentationInterfaceState: ChatPresentationInterfaceState, account: Account, currentNode: ChatInputNode?, interfaceInteraction: ChatPanelInterfaceInteraction?, inputMediaNode: ChatMediaInputNode?, controllerInteraction: ChatControllerInteraction) -> ChatInputNode? { + switch chatPresentationInterfaceState.inputMode { + case .media: + if let currentNode = currentNode as? ChatMediaInputNode { + return currentNode + } else if let inputMediaNode = inputMediaNode { + return inputMediaNode + } else { + let inputNode = ChatMediaInputNode(account: account, controllerInteraction: controllerInteraction) + inputNode.interfaceInteraction = interfaceInteraction + return inputNode + } + case .none, .text: + return nil + } + return nil +} diff --git a/TelegramUI/ChatInterfaceStateInputPanels.swift b/TelegramUI/ChatInterfaceStateInputPanels.swift index 7268e45e93..c679a2cd96 100644 --- a/TelegramUI/ChatInterfaceStateInputPanels.swift +++ b/TelegramUI/ChatInterfaceStateInputPanels.swift @@ -7,12 +7,10 @@ func inputPanelForChatPresentationIntefaceState(_ chatPresentationInterfaceState if let currentPanel = currentPanel as? ChatMessageSelectionInputPanelNode { currentPanel.selectedMessageCount = selectionState.selectedIds.count currentPanel.interfaceInteraction = interfaceInteraction - currentPanel.peer = chatPresentationInterfaceState.peer return currentPanel } else { let panel = ChatMessageSelectionInputPanelNode() panel.account = account - panel.peer = chatPresentationInterfaceState.peer panel.selectedMessageCount = selectionState.selectedIds.count panel.interfaceInteraction = interfaceInteraction return panel @@ -27,12 +25,10 @@ func inputPanelForChatPresentationIntefaceState(_ chatPresentationInterfaceState break case .member: if let currentPanel = currentPanel as? ChatChannelSubscriberInputPanelNode { - currentPanel.peer = peer return currentPanel } else { let panel = ChatChannelSubscriberInputPanelNode() panel.account = account - panel.peer = peer return panel } } @@ -40,12 +36,10 @@ func inputPanelForChatPresentationIntefaceState(_ chatPresentationInterfaceState switch channel.participationStatus { case .kicked, .left: if let currentPanel = currentPanel as? ChatChannelSubscriberInputPanelNode { - currentPanel.peer = peer return currentPanel } else { let panel = ChatChannelSubscriberInputPanelNode() panel.account = account - panel.peer = peer return panel } case .member: @@ -56,19 +50,16 @@ func inputPanelForChatPresentationIntefaceState(_ chatPresentationInterfaceState if let currentPanel = currentPanel as? ChatTextInputPanelNode { currentPanel.interfaceInteraction = interfaceInteraction - currentPanel.peer = peer return currentPanel } else { if let textInputPanelNode = textInputPanelNode { textInputPanelNode.interfaceInteraction = interfaceInteraction textInputPanelNode.account = account - textInputPanelNode.peer = peer return textInputPanelNode } else { let panel = ChatTextInputPanelNode() panel.interfaceInteraction = interfaceInteraction panel.account = account - panel.peer = peer return panel } } diff --git a/TelegramUI/ChatMediaActionSheetController.swift b/TelegramUI/ChatMediaActionSheetController.swift index 3cf65d35ae..9ad622e8e7 100644 --- a/TelegramUI/ChatMediaActionSheetController.swift +++ b/TelegramUI/ChatMediaActionSheetController.swift @@ -3,6 +3,7 @@ import Display import AsyncDisplayKit import UIKit import SwiftSignalKit +import Photos final class ChatMediaActionSheetController: ActionSheetController { private let _ready = Promise() @@ -11,6 +12,7 @@ final class ChatMediaActionSheetController: ActionSheetController { } private var didSetReady = false + var photo: (PHAsset) -> Void = { _ in } var location: () -> Void = { } var contacts: () -> Void = { } @@ -21,7 +23,12 @@ final class ChatMediaActionSheetController: ActionSheetController { self.setItemGroups([ ActionSheetItemGroup(items: [ - ChatMediaActionSheetRollItem(), + ChatMediaActionSheetRollItem(assetSelected: { [weak self] asset in + if let strongSelf = self { + self?.dismissAnimated() + strongSelf.photo(asset) + } + }), ActionSheetButtonItem(title: "File", action: {}), ActionSheetButtonItem(title: "Location", action: { [weak self] in self?.dismissAnimated() diff --git a/TelegramUI/ChatMediaActionSheetRollItem.swift b/TelegramUI/ChatMediaActionSheetRollItem.swift index c571fe44bd..fd69b44694 100644 --- a/TelegramUI/ChatMediaActionSheetRollItem.swift +++ b/TelegramUI/ChatMediaActionSheetRollItem.swift @@ -6,8 +6,14 @@ import Photos import SwiftSignalKit final class ChatMediaActionSheetRollItem: ActionSheetItem { + private let assetSelected: (PHAsset) -> Void + + init(assetSelected: @escaping (PHAsset) -> Void) { + self.assetSelected = assetSelected + } + func node() -> ActionSheetItemNode { - return ChatMediaActionSheetRollItemNode() + return ChatMediaActionSheetRollItemNode(assetSelected: self.assetSelected) } } @@ -19,7 +25,11 @@ private final class ChatMediaActionSheetRollItemNode: ActionSheetItemNode, PHPho private var assetCollection: PHAssetCollection? private var fetchResult: PHFetchResult? - override init() { + private let assetSelected: (PHAsset) -> Void + + init(assetSelected: @escaping (PHAsset) -> Void) { + self.assetSelected = assetSelected + self.listView = ListView() self.listView.transform = CATransform3DMakeRotation(-CGFloat(M_PI / 2.0), 0.0, 0.0, 1.0) @@ -64,7 +74,11 @@ private final class ChatMediaActionSheetRollItemNode: ActionSheetItemNode, PHPho if let fetchResult = self.fetchResult { for i in 0 ..< fetchResult.count { let asset = fetchResult.object(at: i) - items.append(ActionSheetRollImageItem(asset: asset)) + items.append(ActionSheetRollImageItem(asset: asset, selected: { [weak self] in + if let strongSelf = self { + strongSelf.assetSelected(asset) + } + })) } } diff --git a/TelegramUI/ChatMediaInputGridEntries.swift b/TelegramUI/ChatMediaInputGridEntries.swift new file mode 100644 index 0000000000..6dfb0b0e6d --- /dev/null +++ b/TelegramUI/ChatMediaInputGridEntries.swift @@ -0,0 +1,39 @@ +import Postbox +import TelegramCore +import SwiftSignalKit +import Display + +struct ChatMediaInputGridEntryStableId: Hashable { + let collectionId: ItemCollectionId + let itemId: ItemCollectionItemIndex.Id + + static func ==(lhs: ChatMediaInputGridEntryStableId, rhs: ChatMediaInputGridEntryStableId) -> Bool { + return lhs.collectionId == rhs.collectionId && lhs.itemId == rhs.itemId + } + + var hashValue: Int { + return self.itemId.hashValue + } +} + +struct ChatMediaInputGridEntry: Comparable, Identifiable { + let index: ItemCollectionViewEntryIndex + let stickerItem: StickerPackItem + let stickerPackInfo: StickerPackCollectionInfo? + + var stableId: ChatMediaInputGridEntryStableId { + return ChatMediaInputGridEntryStableId(collectionId: self.index.collectionId, itemId: self.stickerItem.index.id) + } + + static func ==(lhs: ChatMediaInputGridEntry, rhs: ChatMediaInputGridEntry) -> Bool { + return lhs.index == rhs.index && lhs.stickerItem == rhs.stickerItem + } + + static func <(lhs: ChatMediaInputGridEntry, rhs: ChatMediaInputGridEntry) -> Bool { + return lhs.index < rhs.index + } + + func item(account: Account, interfaceInteraction: ChatControllerInteraction, inputNodeInteraction: ChatMediaInputNodeInteraction) -> GridItem { + return ChatMediaInputStickerGridItem(account: account, collectionId: self.index.collectionId, stickerPackInfo: self.stickerPackInfo, index: self.index, stickerItem: self.stickerItem, interfaceInteraction: interfaceInteraction, inputNodeInteraction: inputNodeInteraction, selected: { }) + } +} diff --git a/TelegramUI/ChatMediaInputNode.swift b/TelegramUI/ChatMediaInputNode.swift new file mode 100644 index 0000000000..034d01ebfe --- /dev/null +++ b/TelegramUI/ChatMediaInputNode.swift @@ -0,0 +1,322 @@ +import Foundation +import Display +import AsyncDisplayKit +import Postbox +import TelegramCore +import SwiftSignalKit + +private struct ChatMediaInputPanelTransition { + let deletions: [ListViewDeleteItem] + let insertions: [ListViewInsertItem] + let updates: [ListViewUpdateItem] +} + +private struct ChatMediaInputGridTransition { + let deletions: [Int] + let insertions: [GridNodeInsertItem] + let updates: [GridNodeUpdateItem] + let updateFirstIndexInSectionOffset: Int? + let stationaryItems: GridNodeStationaryItems +} + +private func preparedChatMediaInputPanelEntryTransition(account: Account, from fromEntries: [ChatMediaInputPanelEntry], to toEntries: [ChatMediaInputPanelEntry], inputNodeInteraction: ChatMediaInputNodeInteraction) -> ChatMediaInputPanelTransition { + let (deleteIndices, indicesAndItems, updateIndices) = mergeListsStableWithUpdates(leftList: fromEntries, rightList: toEntries) + + let deletions = deleteIndices.map { ListViewDeleteItem(index: $0, directionHint: nil) } + let insertions = indicesAndItems.map { ListViewInsertItem(index: $0.0, previousIndex: $0.2, item: $0.1.item(account: account, inputNodeInteraction: inputNodeInteraction), directionHint: nil) } + let updates = updateIndices.map { ListViewUpdateItem(index: $0.0, previousIndex: $0.2, item: $0.1.item(account: account, inputNodeInteraction: inputNodeInteraction), directionHint: nil) } + + return ChatMediaInputPanelTransition(deletions: deletions, insertions: insertions, updates: updates) +} + +private func preparedChatMediaInputGridEntryTransition(account: Account, from fromEntries: [ChatMediaInputGridEntry], to toEntries: [ChatMediaInputGridEntry], update: StickerPacksCollectionUpdate, interfaceInteraction: ChatControllerInteraction, inputNodeInteraction: ChatMediaInputNodeInteraction) -> ChatMediaInputGridTransition { + var stationaryItems: GridNodeStationaryItems = .none + switch update { + case .generic: + break + case .scroll: + var fromStableIds = Set() + for entry in fromEntries { + fromStableIds.insert(entry.stableId) + } + var index = 0 + var indices = Set() + for entry in toEntries { + if fromStableIds.contains(entry.stableId) { + indices.insert(index) + } + index += 1 + } + stationaryItems = .indices(indices) + } + + let (deleteIndices, indicesAndItems, updateIndices) = mergeListsStableWithUpdates(leftList: fromEntries, rightList: toEntries) + + let deletions = deleteIndices + let insertions = indicesAndItems.map { GridNodeInsertItem(index: $0.0, item: $0.1.item(account: account, interfaceInteraction: interfaceInteraction, inputNodeInteraction: inputNodeInteraction), previousIndex: $0.2) } + let updates = updateIndices.map { GridNodeUpdateItem(index: $0.0, item: $0.1.item(account: account, interfaceInteraction: interfaceInteraction, inputNodeInteraction: inputNodeInteraction)) } + + var firstIndexInSectionOffset = 0 + if !toEntries.isEmpty { + firstIndexInSectionOffset = Int(toEntries[0].index.itemIndex.index) + } + + return ChatMediaInputGridTransition(deletions: deletions, insertions: insertions, updates: updates, updateFirstIndexInSectionOffset: firstIndexInSectionOffset, stationaryItems: stationaryItems) +} + +private func chatMediaInputPanelEntries(view: ItemCollectionsView) -> [ChatMediaInputPanelEntry] { + var entries: [ChatMediaInputPanelEntry] = [] + var index = 0 + for (_, info, item) in view.collectionInfos { + if let info = info as? StickerPackCollectionInfo { + entries.append(.stickerPack(index: index, info: info, topItem: item as? StickerPackItem)) + index += 1 + } + } + return entries +} + +private func chatMediaInputGridEntries(view: ItemCollectionsView) -> [ChatMediaInputGridEntry] { + var entries: [ChatMediaInputGridEntry] = [] + + var stickerPackInfos: [ItemCollectionId: StickerPackCollectionInfo] = [:] + for (id, info, _) in view.collectionInfos { + if let info = info as? StickerPackCollectionInfo { + stickerPackInfos[id] = info + } + } + + for entry in view.entries { + if let item = entry.item as? StickerPackItem { + entries.append(ChatMediaInputGridEntry(index: entry.index, stickerItem: item, stickerPackInfo: stickerPackInfos[entry.index.collectionId])) + } + } + return entries +} + +private enum StickerPacksCollectionPosition: Equatable { + case initial + case scroll(aroundIndex: ItemCollectionViewEntryIndex) + + static func ==(lhs: StickerPacksCollectionPosition, rhs: StickerPacksCollectionPosition) -> Bool { + switch lhs { + case .initial: + if case .initial = rhs { + return true + } else { + return false + } + case let .scroll(aroundIndex): + if case .scroll(aroundIndex) = rhs { + return true + } else { + return false + } + } + } +} + +private enum StickerPacksCollectionUpdate { + case generic + case scroll +} + +final class ChatMediaInputNodeInteraction { + var highlightedItemCollectionId: ItemCollectionId? +} + +final class ChatMediaInputNode: ChatInputNode { + private let account: Account + private let controllerInteraction: ChatControllerInteraction + + private var inputNodeInteraction: ChatMediaInputNodeInteraction! + + private let collectionListPanel: ASDisplayNode + private let collectionListSeparator: ASDisplayNode + + private let disposable = MetaDisposable() + + private let listView: ListView + private let gridNode: GridNode + + private let itemCollectionsViewPosition = Promise() + private var currentStickerPacksCollectionPosition: StickerPacksCollectionPosition? + private var currentView: ItemCollectionsView? + + init(account: Account, controllerInteraction: ChatControllerInteraction) { + self.account = account + self.controllerInteraction = controllerInteraction + + self.collectionListPanel = ASDisplayNode() + self.collectionListPanel.backgroundColor = UIColor(0xF5F6F8) + + self.collectionListSeparator = ASDisplayNode() + self.collectionListSeparator.isLayerBacked = true + self.collectionListSeparator.backgroundColor = UIColor(0xBEC2C6) + + self.listView = ListView() + self.listView.transform = CATransform3DMakeRotation(-CGFloat(M_PI / 2.0), 0.0, 0.0, 1.0) + + self.gridNode = GridNode() + + super.init() + + self.inputNodeInteraction = ChatMediaInputNodeInteraction() + + self.clipsToBounds = true + self.backgroundColor = UIColor(0xE8EBF0) + + self.addSubnode(self.collectionListPanel) + self.addSubnode(self.collectionListSeparator) + self.addSubnode(self.listView) + self.addSubnode(self.gridNode) + + let itemCollectionsView = self.itemCollectionsViewPosition.get() + |> distinctUntilChanged + |> mapToSignal { position -> Signal<(ItemCollectionsView, StickerPacksCollectionUpdate), NoError> in + switch position { + case .initial: + return account.postbox.itemCollectionsView(namespaces: [Namespaces.ItemCollection.CloudStickerPacks], aroundIndex: nil, count: 50) + |> map { view -> (ItemCollectionsView, StickerPacksCollectionUpdate) in + return (view, .generic) + } + case let .scroll(aroundIndex): + var firstTime = true + return account.postbox.itemCollectionsView(namespaces: [Namespaces.ItemCollection.CloudStickerPacks], aroundIndex: aroundIndex, count: 140) + |> map { view -> (ItemCollectionsView, StickerPacksCollectionUpdate) in + let update: StickerPacksCollectionUpdate + if firstTime { + firstTime = false + update = .scroll + } else { + update = .generic + } + return (view, update) + } + } + } + + let previousEntries = Atomic<([ChatMediaInputPanelEntry], [ChatMediaInputGridEntry])>(value: ([], [])) + + let inputNodeInteraction = self.inputNodeInteraction! + + let transitions = itemCollectionsView + |> map { (view, update) -> (ItemCollectionsView, ChatMediaInputPanelTransition, Bool, ChatMediaInputGridTransition, Bool) in + let panelEntries = chatMediaInputPanelEntries(view: view) + let gridEntries = chatMediaInputGridEntries(view: view) + let (previousPanelEntries, previousGridEntries) = previousEntries.swap((panelEntries, gridEntries)) + return (view, preparedChatMediaInputPanelEntryTransition(account: account, from: previousPanelEntries, to: panelEntries, inputNodeInteraction: inputNodeInteraction), previousPanelEntries.isEmpty, preparedChatMediaInputGridEntryTransition(account: account, from: previousGridEntries, to: gridEntries, update: update, interfaceInteraction: controllerInteraction, inputNodeInteraction: inputNodeInteraction), previousGridEntries.isEmpty) + } + + self.disposable.set((transitions |> deliverOnMainQueue).start(next: { [weak self] (view, panelTransition, panelFirstTime, gridTransition, gridFirstTime) in + if let strongSelf = self { + strongSelf.currentView = view + strongSelf.enqueuePanelTransition(panelTransition, firstTime: panelFirstTime) + strongSelf.enqueueGridTransition(gridTransition, firstTime: gridFirstTime) + } + })) + + self.gridNode.visibleItemsUpdated = { [weak self] visibleItems in + if let strongSelf = self { + if let topVisible = visibleItems.topVisible { + if let item = topVisible.1 as? ChatMediaInputStickerGridItem { + let collectionId = item.index.collectionId + if strongSelf.inputNodeInteraction.highlightedItemCollectionId != collectionId { + strongSelf.inputNodeInteraction.highlightedItemCollectionId = collectionId + var selectedItemNode: ChatMediaInputStickerPackItemNode? + strongSelf.listView.forEachItemNode { itemNode in + if let itemNode = itemNode as? ChatMediaInputStickerPackItemNode { + itemNode.updateIsHighlighted() + if itemNode.currentCollectionId == collectionId { + strongSelf.listView.ensureItemNodeVisible(itemNode) + } + } + } + } + } + } + + if let currentView = strongSelf.currentView, let (topIndex, topItem) = visibleItems.top, let (bottomIndex, bottomItem) = visibleItems.bottom { + if topIndex <= 10 && currentView.lower != nil { + let position: StickerPacksCollectionPosition = .scroll(aroundIndex: (topItem as! ChatMediaInputStickerGridItem).index) + if strongSelf.currentStickerPacksCollectionPosition != position { + strongSelf.currentStickerPacksCollectionPosition = position + strongSelf.itemCollectionsViewPosition.set(.single(position)) + } + } else if bottomIndex >= visibleItems.count - 10 && currentView.higher != nil { + let position: StickerPacksCollectionPosition = .scroll(aroundIndex: (bottomItem as! ChatMediaInputStickerGridItem).index) + if strongSelf.currentStickerPacksCollectionPosition != position { + strongSelf.currentStickerPacksCollectionPosition = position + strongSelf.itemCollectionsViewPosition.set(.single(position)) + } + } + } + } + } + + self.currentStickerPacksCollectionPosition = .initial + self.itemCollectionsViewPosition.set(.single(.initial)) + } + + deinit { + self.disposable.dispose() + } + + override func updateLayout(width: CGFloat, transition: ContainedViewLayoutTransition, interfaceState: ChatPresentationInterfaceState) -> CGFloat { + let separatorHeight = UIScreenPixel + + transition.updateFrame(node: self.collectionListPanel, frame: CGRect(origin: CGPoint(x: 0.0, y: 0.0), size: CGSize(width: width, height: 41.0))) + transition.updateFrame(node: self.collectionListSeparator, frame: CGRect(origin: CGPoint(x: 0.0, y: 41.0), size: CGSize(width: width, height: separatorHeight))) + + self.listView.bounds = CGRect(x: 0.0, y: 0.0, width: 41.0, height: width) + self.listView.position = CGPoint(x: width / 2.0, y: 41.0 / 2.0) + + var duration: Double = 0.0 + var curve: UInt = 0 + switch transition { + case .immediate: + break + case let .animated(animationDuration, animationCurve): + duration = animationDuration + switch animationCurve { + case .easeInOut: + break + case .spring: + curve = 7 + } + } + + let listViewCurve: ListViewAnimationCurve + if curve == 7 { + listViewCurve = .Spring(duration: duration) + } else { + listViewCurve = .Default + } + + let updateSizeAndInsets = ListViewUpdateSizeAndInsets(size: CGSize(width: 41.0, height: width), insets: UIEdgeInsets(top: 0.0, left: 0.0, bottom: 0.0, right: 0.0), duration: duration, curve: listViewCurve) + + self.listView.deleteAndInsertItems(deleteIndices: [], insertIndicesAndItems: [], updateIndicesAndItems: [], options: [.Synchronous, .LowLatency], scrollToItem: nil, updateSizeAndInsets: updateSizeAndInsets, stationaryItemRange: nil, completion: { _ in }) + + self.gridNode.frame = CGRect(origin: CGPoint(x: 0.0, y: 41.0), size: CGSize(width: width, height: 258.0 - 41.0)) + + self.gridNode.transaction(GridNodeTransaction(deleteItems: [], insertItems: [], updateItems: [], scrollToItem: nil, updateLayout: GridNodeUpdateLayout(layout: GridNodeLayout(size: CGSize(width: width, height: 258.0 - 41.0), insets: UIEdgeInsets(), preloadSize: 300.0, itemSize: CGSize(width: 75.0, height: 75.0)), transition: .immediate), stationaryItems: .all, updateFirstIndexInSectionOffset: nil), completion: { _ in }) + + return 258.0 + } + + private func enqueuePanelTransition(_ transition: ChatMediaInputPanelTransition, firstTime: Bool) { + var options = ListViewDeleteAndInsertOptions() + if firstTime { + options.insert(.Synchronous) + options.insert(.LowLatency) + } else { + options.insert(.AnimateInsertion) + } + self.listView.deleteAndInsertItems(deleteIndices: transition.deletions, insertIndicesAndItems: transition.insertions, updateIndicesAndItems: transition.updates, options: options, completion: { [weak self] _ in + }) + } + + private func enqueueGridTransition(_ transition: ChatMediaInputGridTransition, firstTime: Bool) { + self.gridNode.transaction(GridNodeTransaction(deleteItems: transition.deletions, insertItems: transition.insertions, updateItems: transition.updates, scrollToItem: nil, updateLayout: nil, stationaryItems: transition.stationaryItems, updateFirstIndexInSectionOffset: transition.updateFirstIndexInSectionOffset), completion: { _ in }) + } +} diff --git a/TelegramUI/ChatMediaInputPanelEntries.swift b/TelegramUI/ChatMediaInputPanelEntries.swift new file mode 100644 index 0000000000..8dfe129523 --- /dev/null +++ b/TelegramUI/ChatMediaInputPanelEntries.swift @@ -0,0 +1,70 @@ +import Postbox +import TelegramCore +import SwiftSignalKit +import Display + +enum ChatMediaInputPanelEntryStableId: Hashable { + case stickerPack(Int64) + + static func ==(lhs: ChatMediaInputPanelEntryStableId, rhs: ChatMediaInputPanelEntryStableId) -> Bool { + switch lhs { + case let .stickerPack(id): + if case .stickerPack(id) = rhs { + return true + } else { + return false + } + } + } + + var hashValue: Int { + switch self { + case let .stickerPack(id): + return id.hashValue + } + } +} + +enum ChatMediaInputPanelEntry: Comparable, Identifiable { + case stickerPack(index: Int, info: StickerPackCollectionInfo, topItem: StickerPackItem?) + + var stableId: ChatMediaInputPanelEntryStableId { + switch self { + case let .stickerPack(_, info, _): + return .stickerPack(info.id.id) + } + } + + static func ==(lhs: ChatMediaInputPanelEntry, rhs: ChatMediaInputPanelEntry) -> Bool { + switch lhs { + case let .stickerPack(index, info, topItem): + if case let .stickerPack(rhsIndex, rhsInfo, rhsTopItem) = rhs, index == rhsIndex, info == rhsInfo, topItem == rhsTopItem { + return true + } else { + return false + } + } + } + + static func <(lhs: ChatMediaInputPanelEntry, rhs: ChatMediaInputPanelEntry) -> Bool { + switch lhs { + case let .stickerPack(lhsIndex, lhsInfo, _): + switch rhs { + case let .stickerPack(rhsIndex, rhsInfo, _): + if lhsIndex == rhsIndex { + return lhsInfo.id.id < rhsInfo.id.id + } else { + return lhsIndex < rhsIndex + } + } + } + } + + func item(account: Account, inputNodeInteraction: ChatMediaInputNodeInteraction) -> ListViewItem { + switch self { + case let .stickerPack(index, info, topItem): + return ChatMediaInputStickerPackItem(account: account, inputNodeInteraction: inputNodeInteraction, collectionId: info.id, stickerPackItem: topItem, index: index, selected: { + }) + } + } +} diff --git a/TelegramUI/ChatMediaInputStickerGridItem.swift b/TelegramUI/ChatMediaInputStickerGridItem.swift new file mode 100644 index 0000000000..2d36520cc5 --- /dev/null +++ b/TelegramUI/ChatMediaInputStickerGridItem.swift @@ -0,0 +1,163 @@ +import Foundation +import Display +import TelegramCore +import SwiftSignalKit +import AsyncDisplayKit +import Postbox + +final class ChatMediaInputStickerGridSection: GridSection { + let collectionId: ItemCollectionId + let collectionInfo: StickerPackCollectionInfo? + let height: CGFloat = 26.0 + + var hashValue: Int { + return self.collectionId.hashValue + } + + init(collectionId: ItemCollectionId, collectionInfo: StickerPackCollectionInfo?) { + self.collectionId = collectionId + self.collectionInfo = collectionInfo + } + + func isEqual(to: GridSection) -> Bool { + if let to = to as? ChatMediaInputStickerGridSection { + return self.collectionId == to.collectionId + } else { + return false + } + } + + func node() -> ASDisplayNode { + return ChatMediaInputStickerGridSectionNode(collectionInfo: self.collectionInfo) + } +} + +private let sectionTitleFont = Font.medium(12.0) + +final class ChatMediaInputStickerGridSectionNode: ASDisplayNode { + let titleNode: ASTextNode + + init(collectionInfo: StickerPackCollectionInfo?) { + self.titleNode = ASTextNode() + self.titleNode.isLayerBacked = true + + super.init() + + self.addSubnode(self.titleNode) + self.titleNode.attributedText = NSAttributedString(string: collectionInfo?.title.uppercased() ?? "", font: sectionTitleFont, textColor: UIColor(0x9099A2)) + self.titleNode.maximumNumberOfLines = 1 + self.titleNode.truncationMode = .byTruncatingTail + } + + override func layout() { + super.layout() + + let bounds = self.bounds + + let titleSize = self.titleNode.measure(CGSize(width: bounds.size.width - 24.0, height: CGFloat.greatestFiniteMagnitude)) + self.titleNode.frame = CGRect(origin: CGPoint(x: 12.0, y: 8.0), size: titleSize) + } +} + +final class ChatMediaInputStickerGridItem: GridItem { + let account: Account + let index: ItemCollectionViewEntryIndex + let stickerItem: StickerPackItem + let selected: () -> Void + let interfaceInteraction: ChatControllerInteraction? + let inputNodeInteraction: ChatMediaInputNodeInteraction + + let section: GridSection? + + init(account: Account, collectionId: ItemCollectionId, stickerPackInfo: StickerPackCollectionInfo?, index: ItemCollectionViewEntryIndex, stickerItem: StickerPackItem, interfaceInteraction: ChatControllerInteraction?, inputNodeInteraction: ChatMediaInputNodeInteraction, selected: @escaping () -> Void) { + self.account = account + self.index = index + self.stickerItem = stickerItem + self.interfaceInteraction = interfaceInteraction + self.inputNodeInteraction = inputNodeInteraction + self.selected = selected + self.section = ChatMediaInputStickerGridSection(collectionId: collectionId, collectionInfo: stickerPackInfo) + } + + func node(layout: GridNodeLayout) -> GridItemNode { + let node = ChatMediaInputStickerGridItemNode() + node.interfaceInteraction = self.interfaceInteraction + node.inputNodeInteraction = self.inputNodeInteraction + node.setup(account: self.account, stickerItem: self.stickerItem) + node.selected = self.selected + return node + } +} + +final class ChatMediaInputStickerGridItemNode: GridItemNode { + private var currentState: (Account, StickerPackItem, CGSize)? + private let imageNode: TransformImageNode + + private let stickerFetchedDisposable = MetaDisposable() + + var interfaceInteraction: ChatControllerInteraction? + var inputNodeInteraction: ChatMediaInputNodeInteraction? + var selected: (() -> Void)? + + override init() { + self.imageNode = TransformImageNode() + + super.init() + + self.addSubnode(self.imageNode) + } + + deinit { + stickerFetchedDisposable.dispose() + } + + override func didLoad() { + super.didLoad() + + self.imageNode.view.addGestureRecognizer(UITapGestureRecognizer(target: self, action: #selector(self.imageNodeTap(_:)))) + } + + func setup(account: Account, stickerItem: StickerPackItem) { + if self.currentState == nil || self.currentState!.0 !== account || self.currentState!.1 != stickerItem { + if let dimensions = stickerItem.file.dimensions { + self.imageNode.setSignal(account: account, signal: chatMessageSticker(account: account, file: stickerItem.file, small: true)) + self.stickerFetchedDisposable.set(fileInteractiveFetched(account: account, file: stickerItem.file).start()) + + self.currentState = (account, stickerItem, dimensions) + self.setNeedsLayout() + } + } + + //self.updateSelectionState(animated: false) + //self.updateHiddenMedia() + } + + override func layout() { + super.layout() + + let imageFrame = self.bounds.insetBy(dx: 6.0, dy: 6.0) + self.imageNode.frame = imageFrame + + if let (_, _, mediaDimensions) = self.currentState { + let imageSize = mediaDimensions.aspectFitted(imageFrame.size) + self.imageNode.asyncLayout()(TransformImageArguments(corners: ImageCorners(), imageSize: imageSize, boundingSize: imageFrame.size, intrinsicInsets: UIEdgeInsets()))() + } + } + + /*func transitionNode(id: MessageId, media: Media) -> ASDisplayNode? { + if self.messageId == id { + return self.imageNode + } else { + return nil + } + }*/ + + @objc func imageNodeTap(_ recognizer: UITapGestureRecognizer) { + if let interfaceInteraction = self.interfaceInteraction, let (_, item, _) = self.currentState, case .ended = recognizer.state { + interfaceInteraction.sendSticker(item.file) + } + /*if let controllerInteraction = self.controllerInteraction, let messageId = self.messageId, case .ended = recognizer.state { + controllerInteraction.openMessage(messageId) + }*/ + } +} diff --git a/TelegramUI/ChatMediaInputStickerPackItem.swift b/TelegramUI/ChatMediaInputStickerPackItem.swift new file mode 100644 index 0000000000..fd109c6dc5 --- /dev/null +++ b/TelegramUI/ChatMediaInputStickerPackItem.swift @@ -0,0 +1,115 @@ +import Foundation +import Display +import AsyncDisplayKit +import TelegramCore +import SwiftSignalKit +import Postbox + +final class ChatMediaInputStickerPackItem: ListViewItem { + let account: Account + let inputNodeInteraction: ChatMediaInputNodeInteraction + let collectionId: ItemCollectionId + let stickerPackItem: StickerPackItem? + let selectedItem: () -> Void + let index: Int + + var selectable: Bool { + return true + } + + init(account: Account, inputNodeInteraction: ChatMediaInputNodeInteraction, collectionId: ItemCollectionId, stickerPackItem: StickerPackItem?, index: Int, selected: @escaping () -> Void) { + self.account = account + self.inputNodeInteraction = inputNodeInteraction + self.collectionId = collectionId + self.stickerPackItem = stickerPackItem + self.selectedItem = selected + self.index = index + } + + func nodeConfiguredForWidth(async: @escaping (@escaping () -> Void) -> Void, width: CGFloat, previousItem: ListViewItem?, nextItem: ListViewItem?, completion: @escaping (ListViewItemNode, @escaping () -> Void) -> Void) { + async { + let node = ChatMediaInputStickerPackItemNode() + node.contentSize = CGSize(width: 41.0, height: 41.0) + node.insets = UIEdgeInsets(top: 0.0, left: 0.0, bottom: 0.0, right: 0.0) + node.inputNodeInteraction = self.inputNodeInteraction + node.updateStickerPackItem(account: self.account, item: self.stickerPackItem, collectionId: self.collectionId) + completion(node, { + }) + } + } + + func updateNode(async: (() -> Void) -> Void, node: ListViewItemNode, width: CGFloat, previousItem: ListViewItem?, nextItem: ListViewItem?, animation: ListViewItemUpdateAnimation, completion: (ListViewItemNodeLayout, () -> Void) -> Void) { + completion(ListViewItemNodeLayout(contentSize: node.contentSize, insets: node.insets), { + }) + } + + func selected(listView: ListView) { + self.selectedItem() + } +} + +private let boundingSize = CGSize(width: 41.0, height: 41.0) +private let imageSize = CGSize(width: 30.0, height: 30.0) +private let highlightSize = CGSize(width: 35.0, height: 35.0) +private let verticalOffset: CGFloat = 3.0 + +private let highlightBackground = generateStretchableFilledCircleImage(radius: 9.0, color: UIColor(0x9099A2, 0.2)) + +final class ChatMediaInputStickerPackItemNode: ListViewItemNode { + private let imageNode: TransformImageNode + private let highlightNode: ASImageNode + + var inputNodeInteraction: ChatMediaInputNodeInteraction? + var currentCollectionId: ItemCollectionId? + private var currentItem: StickerPackItem? + + private let stickerFetchedDisposable = MetaDisposable() + + init() { + self.highlightNode = ASImageNode() + self.highlightNode.isLayerBacked = true + self.highlightNode.image = highlightBackground + self.highlightNode.isHidden = true + + self.imageNode = TransformImageNode() + self.imageNode.isLayerBacked = true + + self.highlightNode.frame = CGRect(origin: CGPoint(x: floor((boundingSize.width - highlightSize.width) / 2.0) + verticalOffset, y: floor((boundingSize.height - highlightSize.height) / 2.0)), size: highlightSize) + + self.imageNode.frame = CGRect(origin: CGPoint(x: floor((boundingSize.width - imageSize.width) / 2.0) + verticalOffset, y: floor((boundingSize.height - imageSize.height) / 2.0)), size: imageSize) + self.imageNode.transform = CATransform3DMakeRotation(CGFloat(M_PI / 2.0), 0.0, 0.0, 1.0) + self.imageNode.alphaTransitionOnFirstUpdate = true + + super.init(layerBacked: false, dynamicBounce: false) + + self.addSubnode(self.highlightNode) + self.addSubnode(self.imageNode) + } + + deinit { + self.stickerFetchedDisposable.dispose() + } + + func updateStickerPackItem(account: Account, item: StickerPackItem?, collectionId: ItemCollectionId) { + self.currentCollectionId = collectionId + + if self.currentItem != item { + self.currentItem = item + + if let item = item, let dimensions = item.file.dimensions { + let imageApply = self.imageNode.asyncLayout()(TransformImageArguments(corners: ImageCorners(), imageSize: dimensions.aspectFitted(imageSize), boundingSize: imageSize, intrinsicInsets: UIEdgeInsets())) + imageApply() + self.imageNode.setSignal(account: account, signal: chatMessageSticker(account: account, file: item.file, small: true)) + self.stickerFetchedDisposable.set(fileInteractiveFetched(account: account, file: item.file).start()) + } + + self.updateIsHighlighted() + } + } + + func updateIsHighlighted() { + if let currentCollectionId = self.currentCollectionId, let inputNodeInteraction = self.inputNodeInteraction { + self.highlightNode.isHidden = inputNodeInteraction.highlightedItemCollectionId != currentCollectionId + } + } +} diff --git a/TelegramUI/ChatMessageInteractiveMediaNode.swift b/TelegramUI/ChatMessageInteractiveMediaNode.swift index a1d12beb75..f4643a8316 100644 --- a/TelegramUI/ChatMessageInteractiveMediaNode.swift +++ b/TelegramUI/ChatMessageInteractiveMediaNode.swift @@ -15,6 +15,8 @@ final class ChatMessageInteractiveMediaNode: ASTransformNode { private var progressNode: RadialProgressNode? private var tapRecognizer: UITapGestureRecognizer? + private var account: Account? + private var messageIdAndFlags: (MessageId, MessageFlags)? private var media: Media? private let statusDisposable = MetaDisposable() @@ -48,6 +50,11 @@ final class ChatMessageInteractiveMediaNode: ASTransformNode { if let fetchStatus = self.fetchStatus { switch fetchStatus { case .Fetching: + if let account = self.account, let (messageId, flags) = self.messageIdAndFlags, flags.contains(.Unsent) && !flags.contains(.Failed) { + account.postbox.modify({ modifier -> Void in + modifier.deleteMessages([messageId]) + }).start() + } if let cancel = self.fetchControls.with({ return $0?.cancel }) { cancel() } @@ -75,11 +82,12 @@ final class ChatMessageInteractiveMediaNode: ASTransformNode { } } - func asyncLayout() -> (_ account: Account, _ media: Media, _ corners: ImageCorners, _ automaticDownload: Bool, _ constrainedSize: CGSize) -> (CGFloat, (CGSize) -> (CGFloat, (CGFloat) -> (CGSize, () -> Void))) { + func asyncLayout() -> (_ account: Account, _ message: Message, _ media: Media, _ corners: ImageCorners, _ automaticDownload: Bool, _ constrainedSize: CGSize) -> (CGFloat, (CGSize) -> (CGFloat, (CGFloat) -> (CGSize, () -> Void))) { + let currentMessageIdAndFlags = self.messageIdAndFlags let currentMedia = self.media let imageLayout = self.imageNode.asyncLayout() - return { account, media, corners, automaticDownload, constrainedSize in + return { account, message, media, corners, automaticDownload, constrainedSize in var initialBoundingSize: CGSize var nativeSize: CGSize @@ -113,10 +121,15 @@ final class ChatMessageInteractiveMediaNode: ASTransformNode { mediaUpdated = true } + var statusUpdated = mediaUpdated + if currentMessageIdAndFlags?.0 != message.id || currentMessageIdAndFlags?.1 != message.flags { + statusUpdated = true + } + if mediaUpdated { if let image = media as? TelegramMediaImage { updateImageSignal = chatMessagePhoto(account: account, photo: image) - updatedStatusSignal = chatMessagePhotoStatus(account: account, photo: image) + updatedFetchControls = FetchControls(fetch: { [weak self] in if let strongSelf = self { strongSelf.fetchDisposable.set(chatMessagePhotoInteractiveFetched(account: account, photo: image).start()) @@ -126,7 +139,6 @@ final class ChatMessageInteractiveMediaNode: ASTransformNode { }) } else if let file = media as? TelegramMediaFile { updateImageSignal = chatMessageVideo(account: account, video: file) - updatedStatusSignal = chatMessageFileStatus(account: account, file: file) updatedFetchControls = FetchControls(fetch: { [weak self] in if let strongSelf = self { strongSelf.fetchDisposable.set(chatMessageFileInteractiveFetched(account: account, file: file).start()) @@ -137,6 +149,32 @@ final class ChatMessageInteractiveMediaNode: ASTransformNode { } } + if statusUpdated { + if let image = media as? TelegramMediaImage { + if message.flags.contains(.Unsent) && !message.flags.contains(.Failed) { + updatedStatusSignal = combineLatest(chatMessagePhotoStatus(account: account, photo: image), account.pendingMessageManager.pendingMessageStatus(message.id)) + |> map { resourceStatus, pendingStatus -> MediaResourceStatus in + if let pendingStatus = pendingStatus { + return .Fetching(progress: pendingStatus.progress) + } else { + return resourceStatus + } + } + } else { + updatedStatusSignal = chatMessagePhotoStatus(account: account, photo: image) + } + } else if let file = media as? TelegramMediaFile { + updatedStatusSignal = combineLatest(chatMessageFileStatus(account: account, file: file), account.pendingMessageManager.pendingMessageStatus(message.id)) + |> map { resourceStatus, pendingStatus -> MediaResourceStatus in + if let pendingStatus = pendingStatus { + return .Fetching(progress: pendingStatus.progress) + } else { + return resourceStatus + } + } + } + } + let arguments = TransformImageArguments(corners: corners, imageSize: boundingSize, boundingSize: boundingSize, intrinsicInsets: UIEdgeInsets()) let imageFrame = CGRect(origin: CGPoint(x: -arguments.insets.left, y: -arguments.insets.top), size: arguments.drawingSize) @@ -153,6 +191,8 @@ final class ChatMessageInteractiveMediaNode: ASTransformNode { return (CGSize(width: adjustedImageSize.width, height: adjustedImageSize.height), { [weak self] in if let strongSelf = self { + strongSelf.account = account + strongSelf.messageIdAndFlags = (message.id, message.flags) strongSelf.media = media strongSelf.imageNode.frame = adjustedImageFrame strongSelf.progressNode?.position = CGPoint(x: adjustedImageFrame.midX, y: adjustedImageFrame.midY) @@ -225,12 +265,12 @@ final class ChatMessageInteractiveMediaNode: ASTransformNode { } } - static func asyncLayout(_ node: ChatMessageInteractiveMediaNode?) -> (_ account: Account, _ media: Media, _ corners: ImageCorners, _ automaticDownload: Bool, _ constrainedSize: CGSize) -> (CGFloat, (CGSize) -> (CGFloat, (CGFloat) -> (CGSize, () -> ChatMessageInteractiveMediaNode))) { + static func asyncLayout(_ node: ChatMessageInteractiveMediaNode?) -> (_ account: Account, _ message: Message, _ media: Media, _ corners: ImageCorners, _ automaticDownload: Bool, _ constrainedSize: CGSize) -> (CGFloat, (CGSize) -> (CGFloat, (CGFloat) -> (CGSize, () -> ChatMessageInteractiveMediaNode))) { let currentAsyncLayout = node?.asyncLayout() - return { account, media, corners, automaticDownload, constrainedSize in + return { account, message, media, corners, automaticDownload, constrainedSize in var imageNode: ChatMessageInteractiveMediaNode - var imageLayout: (_ account: Account, _ media: Media, _ corners: ImageCorners, _ automaticDownload: Bool, _ constrainedSize: CGSize) -> (CGFloat, (CGSize) -> (CGFloat, (CGFloat) -> (CGSize, () -> Void))) + var imageLayout: (_ account: Account, _ message: Message, _ media: Media, _ corners: ImageCorners, _ automaticDownload: Bool, _ constrainedSize: CGSize) -> (CGFloat, (CGSize) -> (CGFloat, (CGFloat) -> (CGSize, () -> Void))) if let node = node, let currentAsyncLayout = currentAsyncLayout { imageNode = node @@ -240,7 +280,7 @@ final class ChatMessageInteractiveMediaNode: ASTransformNode { imageLayout = imageNode.asyncLayout() } - let (initialWidth, continueLayout) = imageLayout(account, media, corners, automaticDownload, constrainedSize) + let (initialWidth, continueLayout) = imageLayout(account, message, media, corners, automaticDownload, constrainedSize) return (initialWidth, { constrainedSize in let (finalWidth, finalLayout) = continueLayout(constrainedSize) diff --git a/TelegramUI/ChatMessageMediaBubbleContentNode.swift b/TelegramUI/ChatMessageMediaBubbleContentNode.swift index 7a67328354..15585167bf 100644 --- a/TelegramUI/ChatMessageMediaBubbleContentNode.swift +++ b/TelegramUI/ChatMessageMediaBubbleContentNode.swift @@ -50,7 +50,7 @@ class ChatMessageMediaBubbleContentNode: ChatMessageBubbleContentNode { let imageCorners = chatMessageBubbleImageContentCorners(relativeContentPosition: position, normalRadius: layoutConstants.image.defaultCornerRadius, mergedRadius: layoutConstants.image.mergedCornerRadius, mergedWithAnotherContentRadius: layoutConstants.image.contentMergedCornerRadius) - let (initialWidth, refineLayout) = interactiveImageLayout(item.account, selectedMedia!, imageCorners, item.account.settings.automaticDownloadSettingsForPeerId(item.peerId).downloadPhoto, CGSize(width: constrainedSize.width, height: constrainedSize.height)) + let (initialWidth, refineLayout) = interactiveImageLayout(item.account, item.message, selectedMedia!, imageCorners, item.account.settings.automaticDownloadSettingsForPeerId(item.peerId).downloadPhoto, CGSize(width: constrainedSize.width, height: constrainedSize.height)) return (initialWidth + layoutConstants.image.bubbleInsets.left + layoutConstants.image.bubbleInsets.right, { constrainedSize in let (refinedWidth, finishLayout) = refineLayout(constrainedSize) diff --git a/TelegramUI/ChatMessageSelectionInputPanelNode.swift b/TelegramUI/ChatMessageSelectionInputPanelNode.swift index d4bece6e70..d1be24e02a 100644 --- a/TelegramUI/ChatMessageSelectionInputPanelNode.swift +++ b/TelegramUI/ChatMessageSelectionInputPanelNode.swift @@ -8,32 +8,7 @@ final class ChatMessageSelectionInputPanelNode: ChatInputPanelNode { private let deleteButton: UIButton private let forwardButton: UIButton - override var peer: Peer? { - didSet { - var canDelete = false - if let channel = self.peer as? TelegramChannel { - switch channel.info { - case .broadcast: - switch channel.role { - case .creator, .editor, .moderator: - canDelete = true - case .member: - canDelete = false - } - case .group: - switch channel.role { - case .creator, .editor, .moderator: - canDelete = true - case .member: - canDelete = false - } - } - } else { - canDelete = true - } - self.deleteButton.isHidden = !canDelete - } - } + private var presentationInterfaceState = ChatPresentationInterfaceState() var selectedMessageCount: Int = 0 { didSet { @@ -63,19 +38,6 @@ final class ChatMessageSelectionInputPanelNode: ChatInputPanelNode { self.forwardButton.addTarget(self, action: #selector(self.forwardButtonPressed), for: [.touchUpInside]) } - override func calculateSizeThatFits(_ constrainedSize: CGSize) -> CGSize { - return CGSize(width: constrainedSize.width, height: 45.0) - } - - override func layout() { - super.layout() - - let bounds = self.bounds - - self.deleteButton.frame = CGRect(origin: CGPoint(), size: CGSize(width: 53.0, height: 45.0)) - self.forwardButton.frame = CGRect(origin: CGPoint(x: bounds.size.width - 57.0, y: 0.0), size: CGSize(width: 57.0, height: 45.0)) - } - @objc func deleteButtonPressed() { self.interfaceInteraction?.deleteSelectedMessages() } @@ -83,4 +45,38 @@ final class ChatMessageSelectionInputPanelNode: ChatInputPanelNode { @objc func forwardButtonPressed() { self.interfaceInteraction?.forwardSelectedMessages() } + + override func updateLayout(width: CGFloat, transition: ContainedViewLayoutTransition, interfaceState: ChatPresentationInterfaceState) -> CGFloat { + if self.presentationInterfaceState != interfaceState { + self.presentationInterfaceState = interfaceState + + var canDelete = false + if let channel = interfaceState.peer as? TelegramChannel { + switch channel.info { + case .broadcast: + switch channel.role { + case .creator, .editor, .moderator: + canDelete = true + case .member: + canDelete = false + } + case .group: + switch channel.role { + case .creator, .editor, .moderator: + canDelete = true + case .member: + canDelete = false + } + } + } else { + canDelete = true + } + self.deleteButton.isHidden = !canDelete + } + + self.deleteButton.frame = CGRect(origin: CGPoint(), size: CGSize(width: 53.0, height: 47.0)) + self.forwardButton.frame = CGRect(origin: CGPoint(x: width - 57.0, y: 0.0), size: CGSize(width: 57.0, height: 47.0)) + + return 47.0 + } } diff --git a/TelegramUI/ChatMessageStickerItemNode.swift b/TelegramUI/ChatMessageStickerItemNode.swift index ecadc2f20c..b56945f0be 100644 --- a/TelegramUI/ChatMessageStickerItemNode.swift +++ b/TelegramUI/ChatMessageStickerItemNode.swift @@ -39,7 +39,7 @@ class ChatMessageStickerItemNode: ChatMessageItemView { if self.telegramFile != telegramFile { self.telegramFile = telegramFile - let signal = chatMessageSticker(account: item.account, file: telegramFile) + let signal = chatMessageSticker(account: item.account, file: telegramFile, small: false) self.imageNode.setSignal(account: item.account, signal: signal) self.fetchDisposable.set(fileInteractiveFetched(account: item.account, file: telegramFile).start()) } diff --git a/TelegramUI/ChatMessageWebpageBubbleContentNode.swift b/TelegramUI/ChatMessageWebpageBubbleContentNode.swift index 248112e129..1e87b51a0a 100644 --- a/TelegramUI/ChatMessageWebpageBubbleContentNode.swift +++ b/TelegramUI/ChatMessageWebpageBubbleContentNode.swift @@ -123,7 +123,7 @@ final class ChatMessageWebpageBubbleContentNode: ChatMessageBubbleContentNode { if let file = webpage.file { if file.isVideo { - let (initialImageWidth, refineLayout) = contentImageLayout(item.account, file, ImageCorners(radius: 4.0), true, CGSize(width: constrainedSize.width - insets.left - insets.right, height: constrainedSize.height)) + let (initialImageWidth, refineLayout) = contentImageLayout(item.account, item.message, file, ImageCorners(radius: 4.0), true, CGSize(width: constrainedSize.width - insets.left - insets.right, height: constrainedSize.height)) initialWidth = initialImageWidth + insets.left + insets.right refineContentImageLayout = refineLayout } else { @@ -132,7 +132,7 @@ final class ChatMessageWebpageBubbleContentNode: ChatMessageBubbleContentNode { } } else if let image = webpage.image { if let type = webpage.type, ["photo"].contains(type) { - let (initialImageWidth, refineLayout) = contentImageLayout(item.account, image, ImageCorners(radius: 4.0), true, CGSize(width: constrainedSize.width - insets.left - insets.right, height: constrainedSize.height)) + let (initialImageWidth, refineLayout) = contentImageLayout(item.account, item.message, image, ImageCorners(radius: 4.0), true, CGSize(width: constrainedSize.width - insets.left - insets.right, height: constrainedSize.height)) initialWidth = initialImageWidth + insets.left + insets.right refineContentImageLayout = refineLayout } else if let dimensions = largestImageRepresentation(image.representations)?.dimensions { diff --git a/TelegramUI/ChatPanelInterfaceInteraction.swift b/TelegramUI/ChatPanelInterfaceInteraction.swift index 07e00d6164..f8854d6e13 100644 --- a/TelegramUI/ChatPanelInterfaceInteraction.swift +++ b/TelegramUI/ChatPanelInterfaceInteraction.swift @@ -7,12 +7,14 @@ final class ChatPanelInterfaceInteraction { let deleteSelectedMessages: () -> Void let forwardSelectedMessages: () -> Void let updateTextInputState: (ChatTextInputState) -> Void + let updateInputMode: ((ChatInputMode) -> ChatInputMode) -> Void - init(setupReplyMessage: @escaping (MessageId) -> Void, beginMessageSelection: @escaping (MessageId) -> Void, deleteSelectedMessages: @escaping () -> Void, forwardSelectedMessages: @escaping () -> Void, updateTextInputState: @escaping (ChatTextInputState) -> Void) { + init(setupReplyMessage: @escaping (MessageId) -> Void, beginMessageSelection: @escaping (MessageId) -> Void, deleteSelectedMessages: @escaping () -> Void, forwardSelectedMessages: @escaping () -> Void, updateTextInputState: @escaping (ChatTextInputState) -> Void, updateInputMode: @escaping ((ChatInputMode) -> ChatInputMode) -> Void) { self.setupReplyMessage = setupReplyMessage self.beginMessageSelection = beginMessageSelection self.deleteSelectedMessages = deleteSelectedMessages self.forwardSelectedMessages = forwardSelectedMessages self.updateTextInputState = updateTextInputState + self.updateInputMode = updateInputMode } } diff --git a/TelegramUI/ChatPresentationInterfaceState.swift b/TelegramUI/ChatPresentationInterfaceState.swift index 025c1e42e3..749c9a83e9 100644 --- a/TelegramUI/ChatPresentationInterfaceState.swift +++ b/TelegramUI/ChatPresentationInterfaceState.swift @@ -6,21 +6,33 @@ enum ChatPresentationInputContext { case mention } +enum ChatInputMode { + case none + case text + case media +} + struct ChatPresentationInterfaceState: Equatable { let interfaceState: ChatInterfaceState let peer: Peer? + let inputTextPanelState: ChatTextInputPanelState let inputContext: ChatPresentationInputContext? + let inputMode: ChatInputMode init() { self.interfaceState = ChatInterfaceState() + self.inputTextPanelState = ChatTextInputPanelState() self.peer = nil self.inputContext = nil + self.inputMode = .none } - init(interfaceState: ChatInterfaceState, peer: Peer?, inputContext: ChatPresentationInputContext?) { + init(interfaceState: ChatInterfaceState, peer: Peer?, inputTextPanelState: ChatTextInputPanelState, inputContext: ChatPresentationInputContext?, inputMode: ChatInputMode) { self.interfaceState = interfaceState self.peer = peer + self.inputTextPanelState = inputTextPanelState self.inputContext = inputContext + self.inputMode = inputMode } static func ==(lhs: ChatPresentationInterfaceState, rhs: ChatPresentationInterfaceState) -> Bool { @@ -35,22 +47,38 @@ struct ChatPresentationInterfaceState: Equatable { return false } + if lhs.inputTextPanelState != rhs.inputTextPanelState { + return false + } + if lhs.inputContext != rhs.inputContext { return false } + if lhs.inputMode != rhs.inputMode { + return false + } + return true } func updatedInterfaceState(_ f: (ChatInterfaceState) -> ChatInterfaceState) -> ChatPresentationInterfaceState { - return ChatPresentationInterfaceState(interfaceState: f(self.interfaceState), peer: self.peer, inputContext: self.inputContext) + return ChatPresentationInterfaceState(interfaceState: f(self.interfaceState), peer: self.peer, inputTextPanelState: self.inputTextPanelState, inputContext: self.inputContext, inputMode: self.inputMode) } func updatedPeer(_ f: (Peer?) -> Peer?) -> ChatPresentationInterfaceState { - return ChatPresentationInterfaceState(interfaceState: self.interfaceState, peer: f(self.peer), inputContext: self.inputContext) + return ChatPresentationInterfaceState(interfaceState: self.interfaceState, peer: f(self.peer), inputTextPanelState: self.inputTextPanelState, inputContext: self.inputContext, inputMode: self.inputMode) } func updatedInputContext(_ f: (ChatPresentationInputContext?) -> ChatPresentationInputContext?) -> ChatPresentationInterfaceState { - return ChatPresentationInterfaceState(interfaceState: self.interfaceState, peer: self.peer, inputContext: f(self.inputContext)) + return ChatPresentationInterfaceState(interfaceState: self.interfaceState, peer: self.peer, inputTextPanelState: self.inputTextPanelState, inputContext: f(self.inputContext), inputMode: self.inputMode) + } + + func updatedInputTextPanelState(_ f: (ChatTextInputPanelState) -> ChatTextInputPanelState) -> ChatPresentationInterfaceState { + return ChatPresentationInterfaceState(interfaceState: self.interfaceState, peer: self.peer, inputTextPanelState: f(self.inputTextPanelState), inputContext: self.inputContext, inputMode: self.inputMode) + } + + func updatedInputMode(_ f: (ChatInputMode) -> ChatInputMode) -> ChatPresentationInterfaceState { + return ChatPresentationInterfaceState(interfaceState: self.interfaceState, peer: self.peer, inputTextPanelState: self.inputTextPanelState, inputContext: self.inputContext, inputMode: f(self.inputMode)) } } diff --git a/TelegramUI/ChatTextInputPanelNode.swift b/TelegramUI/ChatTextInputPanelNode.swift index 06a5d0765f..adbcd44844 100644 --- a/TelegramUI/ChatTextInputPanelNode.swift +++ b/TelegramUI/ChatTextInputPanelNode.swift @@ -6,14 +6,14 @@ import Postbox import TelegramCore private let textInputViewBackground: UIImage = { - let diameter: CGFloat = 10.0 + let diameter: CGFloat = 35.0 UIGraphicsBeginImageContextWithOptions(CGSize(width: diameter, height: diameter), true, 0.0) let context = UIGraphicsGetCurrentContext()! - context.setFillColor(UIColor(0xfafafa).cgColor) + context.setFillColor(UIColor(0xF5F6F8).cgColor) context.fill(CGRect(x: 0.0, y: 0.0, width: diameter, height: diameter)) context.setFillColor(UIColor.white.cgColor) context.fillEllipse(in: CGRect(x: 0.0, y: 0.0, width: diameter, height: diameter)) - context.setStrokeColor(UIColor(0xc7c7cc).cgColor) + context.setStrokeColor(UIColor(0xC9CDD1).cgColor) let strokeWidth: CGFloat = 0.5 context.setLineWidth(strokeWidth) context.strokeEllipse(in: CGRect(x: strokeWidth / 2.0, y: strokeWidth / 2.0, width: diameter - strokeWidth, height: diameter - strokeWidth)) @@ -23,16 +23,75 @@ private let textInputViewBackground: UIImage = { return image }() -private let attachmentIcon = UIImage(bundleImageName: "Chat/Input/Text/IconAttachment")?.precomposed() +private let attachmentIcon = generateTintedImage(image: UIImage(bundleImageName: "Chat/Input/Text/IconAttachment"), color: UIColor(0x9099A2)) +private let micIcon = generateTintedImage(image: UIImage(bundleImageName: "Chat/Input/Text/IconMicrophone"), color: UIColor(0x9099A2)) +private let sendIcon = UIImage(bundleImageName: "Chat/Input/Text/IconSend")?.precomposed() + +enum ChatTextInputAccessoryItem { + case keyboard + case stickers + case inputButtons +} + +struct ChatTextInputPanelState: Equatable { + let accessoryItems: [ChatTextInputAccessoryItem] + + init(accessoryItems: [ChatTextInputAccessoryItem]) { + self.accessoryItems = accessoryItems + } + + init() { + self.accessoryItems = [] + } + + static func ==(lhs: ChatTextInputPanelState, rhs: ChatTextInputPanelState) -> Bool { + if lhs.accessoryItems != rhs.accessoryItems { + return false + } + return true + } +} + +private let keyboardImage = UIImage(bundleImageName: "Chat/Input/Text/AccessoryIconKeyboard")?.precomposed() +private let stickersImage = UIImage(bundleImageName: "Chat/Input/Text/AccessoryIconStickers")?.precomposed() +private let inputButtonsImage = UIImage(bundleImageName: "Chat/Input/Text/AccessoryIconInputButtons")?.precomposed() + +private final class AccessoryItemIconButton: UIButton { + init(item: ChatTextInputAccessoryItem) { + super.init(frame: CGRect()) + + switch item { + case .keyboard: + self.setImage(keyboardImage, for: []) + case .stickers: + self.setImage(stickersImage, for: []) + case .inputButtons: + self.setImage(inputButtonsImage, for: []) + } + + //self.backgroundColor = UIColor.lightGray.withAlphaComponent(0.5) + } + + required init?(coder aDecoder: NSCoder) { + fatalError("init(coder:) has not been implemented") + } + + var buttonWidth: CGFloat { + return (self.image(for: [])?.size.width ?? 0.0) + CGFloat(8.0) + } +} class ChatTextInputPanelNode: ChatInputPanelNode, ASEditableTextNodeDelegate { var textPlaceholderNode: TextNode var textInputNode: ASEditableTextNode? let textInputBackgroundView: UIImageView + let micButton: UIButton let sendButton: UIButton let attachmentButton: UIButton + private var accessoryItemButtons: [(ChatTextInputAccessoryItem, AccessoryItemIconButton)] = [] + var displayAttachmentMenu: () -> Void = { } var sendMessage: () -> Void = { } var updateHeight: () -> Void = { } @@ -40,25 +99,8 @@ class ChatTextInputPanelNode: ChatInputPanelNode, ASEditableTextNodeDelegate { private var updatingInputState = false private var currentPlaceholder: String? - override var peer: Peer? { - didSet { - if let peer = self.peer, oldValue == nil || !peer.isEqual(oldValue!) { - let placeholder: String - if let channel = peer as? TelegramChannel, case .broadcast = channel.info { - placeholder = "Broadcast" - } else { - placeholder = "Message" - } - if self.currentPlaceholder != placeholder { - self.currentPlaceholder = placeholder - let placeholderLayout = TextNode.asyncLayout(self.textPlaceholderNode) - let (placeholderSize, placeholderApply) = placeholderLayout(NSAttributedString(string: placeholder, font: Font.regular(16.0), textColor: UIColor(0xbebec0)), nil, 1, .end, CGSize(width: 320.0, height: CGFloat.greatestFiniteMagnitude), nil) - self.textPlaceholderNode.frame = CGRect(origin: self.textPlaceholderNode.frame.origin, size: placeholderSize.size) - let _ = placeholderApply() - } - } - } - } + + private var presentationInterfaceState = ChatPresentationInterfaceState() var inputTextState: ChatTextInputState { get { @@ -72,7 +114,7 @@ class ChatTextInputPanelNode: ChatInputPanelNode, ASEditableTextNodeDelegate { } set(value) { if let textInputNode = self.textInputNode { self.updatingInputState = true - textInputNode.attributedText = NSAttributedString(string: value.inputText, font: Font.regular(16.0), textColor: UIColor.black) + textInputNode.attributedText = NSAttributedString(string: value.inputText, font: Font.regular(17.0), textColor: UIColor.black) textInputNode.selectedRange = NSMakeRange(value.selectionRange.lowerBound, value.selectionRange.count) self.updatingInputState = false } @@ -84,19 +126,21 @@ class ChatTextInputPanelNode: ChatInputPanelNode, ASEditableTextNodeDelegate { return self.textInputNode?.attributedText?.string ?? "" } set(value) { if let textInputNode = self.textInputNode { - textInputNode.attributedText = NSAttributedString(string: value, font: Font.regular(16.0), textColor: UIColor.black) + textInputNode.attributedText = NSAttributedString(string: value, font: Font.regular(17.0), textColor: UIColor.black) self.editableTextNodeDidUpdateText(textInputNode) } } } - let textFieldInsets = UIEdgeInsets(top: 9.0, left: 41.0, bottom: 8.0, right: 0.0) - let textInputViewInternalInsets = UIEdgeInsets(top: 4.0, left: 5.0, bottom: 4.0, right: 5.0) + let textFieldInsets = UIEdgeInsets(top: 6.0, left: 42.0, bottom: 6.0, right: 42.0) + let textInputViewInternalInsets = UIEdgeInsets(top: 6.5, left: 13.0, bottom: 7.5, right: 13.0) override init() { self.textInputBackgroundView = UIImageView(image: textInputViewBackground) self.textPlaceholderNode = TextNode() + self.textPlaceholderNode.isLayerBacked = true self.attachmentButton = UIButton() + self.micButton = UIButton() self.sendButton = UIButton() super.init() @@ -105,24 +149,23 @@ class ChatTextInputPanelNode: ChatInputPanelNode, ASEditableTextNodeDelegate { self.attachmentButton.addTarget(self, action: #selector(self.attachmentButtonPressed), for: .touchUpInside) self.view.addSubview(self.attachmentButton) - self.sendButton.titleLabel?.font = Font.medium(17.0) - self.sendButton.contentEdgeInsets = UIEdgeInsets(top: 8.0, left: 6.0, bottom: 8.0, right: 6.0) - self.sendButton.setTitleColor(UIColor(0x007ee5), for: []) - self.sendButton.setTitleColor(UIColor.gray, for: [.highlighted]) - self.sendButton.setTitle("Send", for: []) - self.sendButton.sizeToFit() + self.micButton.setImage(micIcon, for: []) + self.micButton.addTarget(self, action: #selector(self.micButtonPressed), for: .touchUpInside) + self.view.addSubview(self.micButton) + + self.sendButton.setImage(sendIcon, for: []) self.sendButton.addTarget(self, action: #selector(self.sendButtonPressed), for: .touchUpInside) + self.sendButton.alpha = 0.0 + self.view.addSubview(self.sendButton) self.view.addSubview(self.textInputBackgroundView) let placeholderLayout = TextNode.asyncLayout(self.textPlaceholderNode) - let (placeholderSize, placeholderApply) = placeholderLayout(NSAttributedString(string: "Message", font: Font.regular(16.0), textColor: UIColor(0xbebec0)), nil, 1, .end, CGSize(width: 320.0, height: CGFloat.greatestFiniteMagnitude), nil) + let (placeholderSize, placeholderApply) = placeholderLayout(NSAttributedString(string: "Message", font: Font.regular(17.0), textColor: UIColor(0xC8C8CE)), nil, 1, .end, CGSize(width: 320.0, height: CGFloat.greatestFiniteMagnitude), nil) self.textPlaceholderNode.frame = CGRect(origin: CGPoint(), size: placeholderSize.size) let _ = placeholderApply() self.addSubnode(self.textPlaceholderNode) - self.view.addSubview(self.sendButton) - self.textInputBackgroundView.clipsToBounds = true let recognizer = TouchDownGestureRecognizer(target: self, action: #selector(self.textInputBackgroundViewTap(_:))) recognizer.touchDown = { [weak self] in @@ -140,16 +183,14 @@ class ChatTextInputPanelNode: ChatInputPanelNode, ASEditableTextNodeDelegate { private func loadTextInputNode() { let textInputNode = ASEditableTextNode() - textInputNode.typingAttributes = [NSFontAttributeName: Font.regular(16.0)] + textInputNode.typingAttributes = [NSFontAttributeName: Font.regular(17.0)] textInputNode.clipsToBounds = true textInputNode.delegate = self textInputNode.hitTestSlop = UIEdgeInsets(top: -5.0, left: -5.0, bottom: -5.0, right: -5.0) self.addSubnode(textInputNode) self.textInputNode = textInputNode - let sendButtonSize = self.sendButton.bounds.size - - textInputNode.frame = CGRect(x: self.textFieldInsets.left + self.textInputViewInternalInsets.left, y: self.textFieldInsets.top + self.textInputViewInternalInsets.top, width: self.frame.size.width - self.textFieldInsets.left - self.textFieldInsets.right - sendButtonSize.width - self.textInputViewInternalInsets.left - self.textInputViewInternalInsets.right, height: self.frame.size.height - self.textFieldInsets.top - self.textFieldInsets.bottom - self.textInputViewInternalInsets.top - self.textInputViewInternalInsets.bottom) + textInputNode.frame = CGRect(x: self.textFieldInsets.left + self.textInputViewInternalInsets.left, y: self.textFieldInsets.top + self.textInputViewInternalInsets.top, width: self.frame.size.width - self.textFieldInsets.left - self.textFieldInsets.right - self.textInputViewInternalInsets.left - self.textInputViewInternalInsets.right, height: self.frame.size.height - self.textFieldInsets.top - self.textFieldInsets.bottom - self.textInputViewInternalInsets.top - self.textInputViewInternalInsets.bottom) self.textInputBackgroundView.isUserInteractionEnabled = false self.textInputBackgroundView.removeGestureRecognizer(self.textInputBackgroundView.gestureRecognizers![0]) @@ -163,55 +204,168 @@ class ChatTextInputPanelNode: ChatInputPanelNode, ASEditableTextNodeDelegate { textInputNode.view.addGestureRecognizer(recognizer) } - override func calculateSizeThatFits(_ constrainedSize: CGSize) -> CGSize { - let sendButtonSize = self.sendButton.bounds.size + override func updateLayout(width: CGFloat, transition: ContainedViewLayoutTransition, interfaceState: ChatPresentationInterfaceState) -> CGFloat { + if self.presentationInterfaceState != interfaceState { + let previousState = self.presentationInterfaceState + self.presentationInterfaceState = interfaceState + + if let peer = interfaceState.peer, previousState.peer == nil || !peer.isEqual(previousState.peer!) { + let placeholder: String + if let channel = peer as? TelegramChannel, case .broadcast = channel.info { + placeholder = "Broadcast" + } else { + placeholder = "Message" + } + if self.currentPlaceholder != placeholder { + self.currentPlaceholder = placeholder + let placeholderLayout = TextNode.asyncLayout(self.textPlaceholderNode) + let (placeholderSize, placeholderApply) = placeholderLayout(NSAttributedString(string: placeholder, font: Font.regular(17.0), textColor: UIColor(0xbebec0)), nil, 1, .end, CGSize(width: 320.0, height: CGFloat.greatestFiniteMagnitude), nil) + self.textPlaceholderNode.frame = CGRect(origin: self.textPlaceholderNode.frame.origin, size: placeholderSize.size) + let _ = placeholderApply() + } + } + } + + let minimalHeight: CGFloat = 47.0 + let minimalInputHeight: CGFloat = 35.0 + let accessoryButtonSpacing: CGFloat = 0.0 + let accessoryButtonInset: CGFloat = 4.0 + UIScreenPixel + + var animatedTransition = true + if case .immediate = transition { + animatedTransition = false + } + + var updateAccessoryButtons = false + if self.presentationInterfaceState.inputTextPanelState.accessoryItems.count == self.accessoryItemButtons.count { + for i in 0 ..< self.presentationInterfaceState.inputTextPanelState.accessoryItems.count { + if self.presentationInterfaceState.inputTextPanelState.accessoryItems[i] != self.accessoryItemButtons[i].0 { + updateAccessoryButtons = true + break + } + } + } else { + updateAccessoryButtons = true + } + + var removeAccessoryButtons: [AccessoryItemIconButton]? + if updateAccessoryButtons { + var updatedButtons: [(ChatTextInputAccessoryItem, AccessoryItemIconButton)] = [] + for item in self.presentationInterfaceState.inputTextPanelState.accessoryItems { + var itemAndButton: (ChatTextInputAccessoryItem, AccessoryItemIconButton)? + for i in 0 ..< self.accessoryItemButtons.count { + if self.accessoryItemButtons[i].0 == item { + itemAndButton = self.accessoryItemButtons[i] + self.accessoryItemButtons.remove(at: i) + break + } + } + if itemAndButton == nil { + let button = AccessoryItemIconButton(item: item) + button.addTarget(self, action: #selector(self.accessoryItemButtonPressed(_:)), for: [.touchUpInside]) + itemAndButton = (item, button) + } + updatedButtons.append(itemAndButton!) + } + for (_, button) in self.accessoryItemButtons { + if animatedTransition { + if removeAccessoryButtons == nil { + removeAccessoryButtons = [] + } + removeAccessoryButtons!.append(button) + } else { + button.removeFromSuperview() + } + } + self.accessoryItemButtons = updatedButtons + } + + var accessoryButtonsWidth: CGFloat = 0.0 + var firstButton = true + for (_, button) in self.accessoryItemButtons { + if firstButton { + firstButton = false + accessoryButtonsWidth += accessoryButtonInset + } else { + accessoryButtonsWidth += accessoryButtonSpacing + } + accessoryButtonsWidth += button.buttonWidth + } + let textFieldHeight: CGFloat if let textInputNode = self.textInputNode { - textFieldHeight = min(115.0, max(20.0, ceil(textInputNode.measure(CGSize(width: constrainedSize.width - self.textFieldInsets.left - self.textFieldInsets.right - sendButtonSize.width - self.textInputViewInternalInsets.left - self.textInputViewInternalInsets.right, height: constrainedSize.height)).height))) + textFieldHeight = min(115.0, max(21.0, ceil(textInputNode.measure(CGSize(width: width - self.textFieldInsets.left - self.textFieldInsets.right - self.textInputViewInternalInsets.left - self.textInputViewInternalInsets.right - accessoryButtonsWidth, height: CGFloat.greatestFiniteMagnitude)).height))) } else { - textFieldHeight = 20.0 + textFieldHeight = 21.0 } - return CGSize(width: constrainedSize.width, height: textFieldHeight + self.textFieldInsets.top + self.textFieldInsets.bottom + self.textInputViewInternalInsets.top + self.textInputViewInternalInsets.bottom) - } - - override var frame: CGRect { - get { - return super.frame - } set(value) { - super.frame = value - } - } - - override func updateFrames(transition: ContainedViewLayoutTransition) { - let bounds = self.bounds + let panelHeight = textFieldHeight + self.textFieldInsets.top + self.textFieldInsets.bottom + self.textInputViewInternalInsets.top + self.textInputViewInternalInsets.bottom - let sendButtonSize = self.sendButton.bounds.size - let minimalHeight: CGFloat = 45.0 - transition.updateFrame(layer: self.sendButton.layer, frame: CGRect(x: bounds.size.width - sendButtonSize.width, y: bounds.height - minimalHeight + floor((minimalHeight - sendButtonSize.height) / 2.0), width: sendButtonSize.width, height: sendButtonSize.height)) - - transition.updateFrame(layer: self.attachmentButton.layer, frame: CGRect(origin: CGPoint(x: 0.0, y: bounds.height - minimalHeight), size: CGSize(width: 40.0, height: minimalHeight))) + transition.updateFrame(layer: self.attachmentButton.layer, frame: CGRect(origin: CGPoint(x: 2.0 - UIScreenPixel, y: panelHeight - minimalHeight), size: CGSize(width: 40.0, height: minimalHeight))) + transition.updateFrame(layer: self.micButton.layer, frame: CGRect(origin: CGPoint(x: width - 43.0 - UIScreenPixel, y: panelHeight - minimalHeight - UIScreenPixel), size: CGSize(width: 44.0, height: minimalHeight))) + transition.updateFrame(layer: self.sendButton.layer, frame: CGRect(origin: CGPoint(x: width - 43.0 - UIScreenPixel, y: panelHeight - minimalHeight - UIScreenPixel), size: CGSize(width: 44.0, height: minimalHeight))) if let textInputNode = self.textInputNode { - transition.updateFrame(node: textInputNode, frame: CGRect(x: self.textFieldInsets.left + self.textInputViewInternalInsets.left, y: self.textFieldInsets.top + self.textInputViewInternalInsets.top, width: bounds.size.width - self.textFieldInsets.left - self.textFieldInsets.right - sendButtonSize.width - self.textInputViewInternalInsets.left - self.textInputViewInternalInsets.right, height: bounds.size.height - self.textFieldInsets.top - self.textFieldInsets.bottom - self.textInputViewInternalInsets.top - self.textInputViewInternalInsets.bottom)) + transition.updateFrame(node: textInputNode, frame: CGRect(x: self.textFieldInsets.left + self.textInputViewInternalInsets.left, y: self.textFieldInsets.top + self.textInputViewInternalInsets.top, width: width - self.textFieldInsets.left - self.textFieldInsets.right - self.textInputViewInternalInsets.left - self.textInputViewInternalInsets.right - accessoryButtonsWidth, height: panelHeight - self.textFieldInsets.top - self.textFieldInsets.bottom - self.textInputViewInternalInsets.top - self.textInputViewInternalInsets.bottom)) } transition.updateFrame(node: self.textPlaceholderNode, frame: CGRect(origin: CGPoint(x: self.textFieldInsets.left + self.textInputViewInternalInsets.left, y: self.textFieldInsets.top + self.textInputViewInternalInsets.top + 0.5), size: self.textPlaceholderNode.frame.size)) - transition.updateFrame(layer: self.textInputBackgroundView.layer, frame: CGRect(x: self.textFieldInsets.left, y: self.textFieldInsets.top, width: bounds.size.width - self.textFieldInsets.left - self.textFieldInsets.right - sendButtonSize.width, height: bounds.size.height - self.textFieldInsets.top - self.textFieldInsets.bottom)) + transition.updateFrame(layer: self.textInputBackgroundView.layer, frame: CGRect(x: self.textFieldInsets.left, y: self.textFieldInsets.top, width: width - self.textFieldInsets.left - self.textFieldInsets.right, height: panelHeight - self.textFieldInsets.top - self.textFieldInsets.bottom)) + + var nextButtonTopRight = CGPoint(x: width - self.textFieldInsets.right - accessoryButtonInset, y: panelHeight - self.textFieldInsets.bottom - minimalInputHeight) + for (_, button) in self.accessoryItemButtons.reversed() { + let buttonSize = CGSize(width: button.buttonWidth, height: minimalInputHeight) + let buttonFrame = CGRect(origin: CGPoint(x: nextButtonTopRight.x - buttonSize.width, y: nextButtonTopRight.y + floor((minimalInputHeight - buttonSize.height) / 2.0)), size: buttonSize) + if button.superview == nil { + self.view.addSubview(button) + button.frame = buttonFrame + transition.updateFrame(layer: button.layer, frame: buttonFrame) + if animatedTransition { + button.layer.animateAlpha(from: 0.0, to: 1.0, duration: 0.25) + button.layer.animateScale(from: 0.2, to: 1.0, duration: 0.25) + } + } else { + transition.updateFrame(layer: button.layer, frame: buttonFrame) + } + nextButtonTopRight.x -= buttonSize.width + nextButtonTopRight.x -= accessoryButtonSpacing + } + + if let removeAccessoryButtons = removeAccessoryButtons { + for button in removeAccessoryButtons { + let buttonFrame = CGRect(origin: CGPoint(x: button.frame.origin.x, y: panelHeight - self.textFieldInsets.bottom - minimalInputHeight), size: button.frame.size) + transition.updateFrame(layer: button.layer, frame: buttonFrame) + button.layer.animateScale(from: 1.0, to: 0.2, duration: 0.25, removeOnCompletion: false) + button.layer.animateAlpha(from: 1.0, to: 0.0, duration: 0.25, removeOnCompletion: false, completion: { [weak button] _ in + button?.removeFromSuperview() + }) + } + } + + return panelHeight } @objc func editableTextNodeDidUpdateText(_ editableTextNode: ASEditableTextNode) { if let textInputNode = self.textInputNode { self.textPlaceholderNode.isHidden = editableTextNode.attributedText?.length ?? 0 != 0 - let constrainedSize = CGSize(width: self.frame.size.width, height: CGFloat.greatestFiniteMagnitude) - let sendButtonSize = self.sendButton.bounds.size - - let textFieldHeight: CGFloat = min(115.0, max(20.0, ceil(textInputNode.measure(CGSize(width: constrainedSize.width - self.textFieldInsets.left - self.textFieldInsets.right - sendButtonSize.width - self.textInputViewInternalInsets.left - self.textInputViewInternalInsets.right, height: constrainedSize.height)).height))) - if abs(textFieldHeight - textInputNode.frame.size.height) > CGFloat(FLT_EPSILON) { - self.invalidateCalculatedLayout() - self.updateHeight() + if let text = self.textInputNode?.attributedText, text.length != 0 { + if self.sendButton.alpha.isZero { + self.sendButton.alpha = 1.0 + self.micButton.alpha = 0.0 + self.sendButton.layer.animateAlpha(from: 0.0, to: 1.0, duration: 0.1) + self.sendButton.layer.animateSpring(from: NSNumber(value: Float(0.1)), to: NSNumber(value: Float(1.0)), keyPath: "transform.scale", duration: 0.6) + self.micButton.layer.animateAlpha(from: 1.0, to: 0.0, duration: 0.2) + } + } else { + if self.micButton.alpha.isZero { + self.micButton.alpha = 1.0 + self.sendButton.alpha = 0.0 + self.micButton.layer.animateAlpha(from: 0.0, to: 1.0, duration: 0.1) + self.micButton.layer.animateSpring(from: NSNumber(value: Float(0.1)), to: NSNumber(value: Float(1.0)), keyPath: "transform.scale", duration: 0.6) + self.sendButton.layer.animateAlpha(from: 1.0, to: 0.0, duration: 0.2) + } } self.interfaceInteraction?.updateTextInputState(self.inputTextState) @@ -224,6 +378,20 @@ class ChatTextInputPanelNode: ChatInputPanelNode, ASEditableTextNodeDelegate { } } + @objc func editableTextNodeDidBeginEditing(_ editableTextNode: ASEditableTextNode) { + self.interfaceInteraction?.updateInputMode({ _ in .text }) + } + + @objc func editableTextNodeDidFinishEditing(_ editableTextNode: ASEditableTextNode) { + /*self.interfaceInteraction?.updateInputMode({ mode in + if case .text = mode { + return .none + } else { + return mode + } + })*/ + } + @objc func sendButtonPressed() { let text = self.textInputNode?.attributedText?.string ?? "" if !text.isEmpty { @@ -235,12 +403,19 @@ class ChatTextInputPanelNode: ChatInputPanelNode, ASEditableTextNodeDelegate { self.displayAttachmentMenu() } + @objc func micButtonPressed() { + } + @objc func textInputBackgroundViewTap(_ recognizer: UITapGestureRecognizer) { if case .ended = recognizer.state { self.ensureFocused() } } + var isFocused: Bool { + return self.textInputNode?.isFirstResponder() ?? false + } + func ensureUnfocused() { self.textInputNode?.resignFirstResponder() } @@ -267,11 +442,19 @@ class ChatTextInputPanelNode: ChatInputPanelNode, ASEditableTextNodeDelegate { }*/ } - /*override func hitTest(point: CGPoint, withEvent event: UIEvent!) -> UIView! { - if let textInputNode = self.textInputNode where self.textInputBackgroundView.frame.contains(point) { - return textInputNode.view + @objc func accessoryItemButtonPressed(_ button: UIView) { + for (item, currentButton) in self.accessoryItemButtons { + if currentButton === button { + switch item { + case .inputButtons: + break + case .stickers: + self.interfaceInteraction?.updateInputMode({ _ in .media }) + case .keyboard: + self.interfaceInteraction?.updateInputMode({ _ in .text }) + } + break + } } - - return super.hitTest(point, withEvent: event) - }*/ + } } diff --git a/TelegramUI/ChatVideoGalleryItem.swift b/TelegramUI/ChatVideoGalleryItem.swift index 928c3c8af9..4024b37c27 100644 --- a/TelegramUI/ChatVideoGalleryItem.swift +++ b/TelegramUI/ChatVideoGalleryItem.swift @@ -121,7 +121,7 @@ final class ChatVideoGalleryItemNode: ZoomableContentGalleryItemNode { /*let source = VideoPlayerSource(account: account, resource: CloudFileMediaResource(location: file.location, size: file.size)) self.videoNode.player = VideoPlayer(source: source)*/ - let player = MediaPlayer(account: account, resource: CloudFileMediaResource(location: file.location, size: file.size)) + let player = MediaPlayer(account: account, resource: file.resource) player.attachPlayerNode(self.videoNode) self.player = player self.videoStatusDisposable.set((player.status |> deliverOnMainQueue).start(next: { [weak self] status in diff --git a/TelegramUI/ContactsController.swift b/TelegramUI/ContactsController.swift index 5085b81623..03536db8b3 100644 --- a/TelegramUI/ContactsController.swift +++ b/TelegramUI/ContactsController.swift @@ -263,6 +263,7 @@ public class ContactsController: ViewController { let interaction = ContactsControllerInteraction(openPeer: { [weak self] peerId in if let strongSelf = self { + strongSelf.contactsNode.listView.clearHighlightAnimated(true) (strongSelf.navigationController as? NavigationController)?.pushViewController(ChatController(account: strongSelf.account, peerId: peerId)) } }, activateSearch: { [weak self] in diff --git a/TelegramUI/FFMpegMediaFrameSourceContext.swift b/TelegramUI/FFMpegMediaFrameSourceContext.swift index 3acf9a9084..f17f3300f0 100644 --- a/TelegramUI/FFMpegMediaFrameSourceContext.swift +++ b/TelegramUI/FFMpegMediaFrameSourceContext.swift @@ -80,8 +80,10 @@ private func readPacketCallback(userData: UnsafeMutableRawPointer?, buffer: Unsa var fetchedCount: Int32 = 0 - let readCount = min(resource.size - context.readingOffset, Int(bufferSize)) - let data = account.postbox.mediaBox.resourceData(resource, in: context.readingOffset ..< (context.readingOffset + readCount), mode: .complete) + let resourceSize: Int = resource.size ?? 0 + + let readCount = min(resourceSize - context.readingOffset, Int(bufferSize)) + let data = account.postbox.mediaBox.resourceData(resource, size: resourceSize, in: context.readingOffset ..< (context.readingOffset + readCount), mode: .complete) var fetchedData: Data? let semaphore = DispatchSemaphore(value: 0) let _ = data.start(next: { data in @@ -110,18 +112,20 @@ private func seekCallback(userData: UnsafeMutableRawPointer?, offset: Int64, whe var result: Int64 = offset + let resourceSize: Int = resource.size ?? 0 + if (whence & AVSEEK_SIZE) != 0 { - result = Int64(resource.size) + result = Int64(resourceSize) } else { - context.readingOffset = Int(min(Int64(resource.size), offset)) + context.readingOffset = Int(min(Int64(resourceSize), offset)) if context.readingOffset != context.requestedDataOffset { context.requestedDataOffset = context.readingOffset - if context.readingOffset >= resource.size { + if context.readingOffset >= resourceSize { context.fetchedDataDisposable.set(nil) } else { - context.fetchedDataDisposable.set(account.postbox.mediaBox.fetchedResourceData(resource, in: context.readingOffset ..< resource.size).start()) + context.fetchedDataDisposable.set(account.postbox.mediaBox.fetchedResourceData(resource, size: resourceSize, in: context.readingOffset ..< resourceSize).start()) } } } @@ -168,7 +172,9 @@ final class FFMpegMediaFrameSourceContext: NSObject { self.account = account self.resource = resource - self.fetchedDataDisposable.set(account.postbox.mediaBox.fetchedResourceData(resource, in: 0 ..< resource.size).start()) + let resourceSize: Int = resource.size ?? 0 + + self.fetchedDataDisposable.set(account.postbox.mediaBox.fetchedResourceData(resource, size: resourceSize, in: 0 ..< resourceSize).start()) var avFormatContextRef = avformat_alloc_context() guard let avFormatContext = avFormatContextRef else { diff --git a/TelegramUI/FetchCachedRepresentations.swift b/TelegramUI/FetchCachedRepresentations.swift new file mode 100644 index 0000000000..b29514fa47 --- /dev/null +++ b/TelegramUI/FetchCachedRepresentations.swift @@ -0,0 +1,90 @@ +import Foundation +import Postbox +import SwiftSignalKit +import TelegramCore +import ImageIO +import MobileCoreServices +import Display +import UIKit + +public func fetchCachedResourceRepresentation(account: Account, resource: MediaResource, resourceData: MediaResourceData, representation: CachedMediaResourceRepresentation) -> Signal { + if let representation = representation as? CachedStickerAJpegRepresentation { + return fetchCachedStickerAJpegRepresentation(account: account, resource: resource, resourceData: resourceData, representation: representation) + } + return .never() +} + +private func fetchCachedStickerAJpegRepresentation(account: Account, resource: MediaResource, resourceData: MediaResourceData, representation: CachedStickerAJpegRepresentation) -> Signal { + return Signal({ subscriber in + if let data = try? Data(contentsOf: URL(fileURLWithPath: resourceData.path), options: [.mappedIfSafe]) { + if let image = UIImage.convert(fromWebP: data) { + var randomId: Int64 = 0 + arc4random_buf(&randomId, 8) + let path = NSTemporaryDirectory() + "\(randomId)" + let url = URL(fileURLWithPath: path) + + let colorData = NSMutableData() + let alphaData = NSMutableData() + + let size = representation.size ?? CGSize(width: image.size.width * image.scale, height: image.size.height * image.scale) + + let colorImage: UIImage + if let _ = representation.size { + colorImage = generateImage(size, contextGenerator: { size, context in + context.setBlendMode(.copy) + context.draw(image.cgImage!, in: CGRect(origin: CGPoint(), size: size)) + }, scale: 1.0)! + } else { + colorImage = image + } + + let alphaImage = generateImage(size, contextGenerator: { size, context in + context.setFillColor(UIColor.white.cgColor) + context.fill(CGRect(origin: CGPoint(), size: size)) + context.clip(to: CGRect(origin: CGPoint(), size: size), mask: colorImage.cgImage!) + context.setFillColor(UIColor.black.cgColor) + context.fill(CGRect(origin: CGPoint(), size: size)) + }, scale: 1.0) + + if let alphaImage = alphaImage, let colorDestination = CGImageDestinationCreateWithData(colorData as CFMutableData, kUTTypeJPEG, 1, nil), let alphaDestination = CGImageDestinationCreateWithData(alphaData as CFMutableData, kUTTypeJPEG, 1, nil) { + CGImageDestinationSetProperties(colorDestination, nil) + CGImageDestinationSetProperties(alphaDestination, nil) + + let colorQuality: Float + let alphaQuality: Float + if representation.size == nil { + colorQuality = 0.6 + alphaQuality = 0.6 + } else { + colorQuality = 0.5 + alphaQuality = 0.4 + } + + let options = NSMutableDictionary() + options.setObject(colorQuality as NSNumber, forKey: kCGImageDestinationLossyCompressionQuality as NSString) + + let optionsAlpha = NSMutableDictionary() + optionsAlpha.setObject(alphaQuality as NSNumber, forKey: kCGImageDestinationLossyCompressionQuality as NSString) + + CGImageDestinationAddImage(colorDestination, colorImage.cgImage!, options as CFDictionary) + CGImageDestinationAddImage(alphaDestination, alphaImage.cgImage!, optionsAlpha as CFDictionary) + if CGImageDestinationFinalize(colorDestination) && CGImageDestinationFinalize(alphaDestination) { + let finalData = NSMutableData() + var colorSize: Int32 = Int32(colorData.length) + finalData.append(&colorSize, length: 4) + finalData.append(colorData as Data) + var alphaSize: Int32 = Int32(alphaData.length) + finalData.append(&alphaSize, length: 4) + finalData.append(alphaData as Data) + + let _ = try? finalData.write(to: url, options: [.atomic]) + + subscriber.putNext(CachedMediaResourceRepresentationResult(temporaryPath: path)) + subscriber.putCompletion() + } + } + } + } + return EmptyDisposable + }) |> runOn(account.graphicsThreadPool) +} diff --git a/TelegramUI/FileResources.swift b/TelegramUI/FileResources.swift index f61135c075..52f9915c1c 100644 --- a/TelegramUI/FileResources.swift +++ b/TelegramUI/FileResources.swift @@ -3,14 +3,10 @@ import Postbox import SwiftSignalKit import TelegramCore -func fileResource(_ file: TelegramMediaFile) -> CloudFileMediaResource { - return CloudFileMediaResource(location: file.location, size: file.size) -} - func fileInteractiveFetched(account: Account, file: TelegramMediaFile) -> Signal { - return account.postbox.mediaBox.fetchedResource(fileResource(file)) + return account.postbox.mediaBox.fetchedResource(file.resource) } func fileCancelInteractiveFetch(account: Account, file: TelegramMediaFile) { - account.postbox.mediaBox.cancelInteractiveResourceFetch(fileResource(file)) + account.postbox.mediaBox.cancelInteractiveResourceFetch(file.resource) } diff --git a/TelegramUI/GalleryController.swift b/TelegramUI/GalleryController.swift index b9100e8f70..03321bd051 100644 --- a/TelegramUI/GalleryController.swift +++ b/TelegramUI/GalleryController.swift @@ -145,7 +145,7 @@ class GalleryController: ViewController { self.navigationItem.leftBarButtonItem = UIBarButtonItem(title: "Done", style: .plain, target: self, action: #selector(self.donePressed)) - self.statusBar.style = .White + self.statusBar.statusBarStyle = .White let message = account.postbox.messageAtId(messageId) @@ -204,7 +204,7 @@ class GalleryController: ViewController { if let strongSelf = self { switch style { case .dark: - strongSelf.statusBar.style = .White + strongSelf.statusBar.statusBarStyle = .White strongSelf.navigationBar.backgroundColor = UIColor(white: 0.0, alpha: 0.5) strongSelf.navigationBar.stripeColor = UIColor.clear strongSelf.navigationBar.foregroundColor = UIColor.white @@ -212,7 +212,7 @@ class GalleryController: ViewController { strongSelf.galleryNode.backgroundNode.backgroundColor = UIColor.black strongSelf.galleryNode.isBackgroundExtendedOverNavigationBar = true case .light: - strongSelf.statusBar.style = .Black + strongSelf.statusBar.statusBarStyle = .Black strongSelf.navigationBar.backgroundColor = UIColor(red: 0.968626451, green: 0.968626451, blue: 0.968626451, alpha: 1.0) strongSelf.navigationBar.foregroundColor = UIColor.black strongSelf.navigationBar.accentColor = UIColor(0x007ee5) diff --git a/TelegramUI/GridHoleItem.swift b/TelegramUI/GridHoleItem.swift index 9b3974c36d..5acebe20cf 100644 --- a/TelegramUI/GridHoleItem.swift +++ b/TelegramUI/GridHoleItem.swift @@ -2,7 +2,9 @@ import Foundation import Display import AsyncDisplayKit -class GridHoleItem: GridItem { +final class GridHoleItem: GridItem { + let section: GridSection? = nil + func node(layout: GridNodeLayout) -> GridItemNode { return GridHoleItemNode() } diff --git a/TelegramUI/GridMessageItem.swift b/TelegramUI/GridMessageItem.swift index cc6fde7f78..17fa719640 100644 --- a/TelegramUI/GridMessageItem.swift +++ b/TelegramUI/GridMessageItem.swift @@ -26,6 +26,8 @@ final class GridMessageItem: GridItem { private let message: Message private let controllerInteraction: ChatControllerInteraction + let section: GridSection? = nil + init(account: Account, message: Message, controllerInteraction: ChatControllerInteraction) { self.account = account self.message = message diff --git a/TelegramUI/GroupInfoEntries.swift b/TelegramUI/GroupInfoEntries.swift index 3f2a255521..30d27b4f91 100644 --- a/TelegramUI/GroupInfoEntries.swift +++ b/TelegramUI/GroupInfoEntries.swift @@ -236,7 +236,7 @@ enum GroupInfoEntry: PeerInfoEntry { func item(account: Account, interaction: PeerInfoControllerInteraction) -> ListViewItem { switch self { case let .info(peer, cachedData): - return PeerInfoAvatarAndNameItem(account: account, peer: peer, cachedData: cachedData, sectionId: self.section.rawValue, style: .blocks) + return PeerInfoAvatarAndNameItem(account: account, peer: peer, cachedData: cachedData, editingState: nil, sectionId: self.section.rawValue, style: .blocks) case .setGroupPhoto: return PeerInfoActionItem(title: "Set Group Photo", kind: .generic, alignment: .natural, sectionId: self.section.rawValue, style: .blocks, action: { }) @@ -248,7 +248,7 @@ enum GroupInfoEntry: PeerInfoEntry { label = "Enabled" } return PeerInfoDisclosureItem(title: "Notifications", label: label, sectionId: self.section.rawValue, style: .blocks, action: { - interaction.changeNotificationNoteSettings() + interaction.changeNotificationMuteSettings() }) case .sharedMedia: return PeerInfoDisclosureItem(title: "Shared Media", label: "", sectionId: self.section.rawValue, style: .blocks, action: { @@ -280,7 +280,7 @@ enum GroupInfoEntry: PeerInfoEntry { } } -func groupInfoEntries(view: PeerView) -> [PeerInfoEntry] { +func groupInfoEntries(view: PeerView) -> PeerInfoEntries { var entries: [PeerInfoEntry] = [] entries.append(GroupInfoEntry.info(peer: view.peers[view.peerId], cachedData: view.cachedData)) @@ -400,5 +400,5 @@ func groupInfoEntries(view: PeerView) -> [PeerInfoEntry] { } } - return entries + return PeerInfoEntries(entries: entries, leftNavigationButton: nil, rightNavigationButton: nil) } diff --git a/TelegramUI/PeerAvatar.swift b/TelegramUI/PeerAvatar.swift index d609da203f..68a169430c 100644 --- a/TelegramUI/PeerAvatar.swift +++ b/TelegramUI/PeerAvatar.swift @@ -20,36 +20,52 @@ private let roundCorners = { () -> UIImage in }() func peerAvatarImage(account: Account, peer: Peer, displayDimensions: CGSize = CGSize(width: 60.0, height: 60.0)) -> Signal? { - if let location = peer.smallProfileImage?.location.cloudLocation { - return deferred { () -> Signal in - return cachedCloudFileLocation(location) - |> `catch` { _ in - return multipartDownloadFromCloudLocation(account: account, location: location, size: nil) - |> afterNext { data in - cacheCloudFileLocation(location, data: data) + if let smallProfileImage = peer.smallProfileImage { + let resourceData = account.postbox.mediaBox.resourceData(smallProfileImage.resource) + let imageData = resourceData + |> take(1) + |> mapToSignal { maybeData -> Signal in + if maybeData.complete { + return .single(try? Data(contentsOf: URL(fileURLWithPath: maybeData.path))) + } else { + return Signal { subscriber in + let resourceDataDisposable = resourceData.start(next: { data in + if data.complete { + subscriber.putNext(try? Data(contentsOf: URL(fileURLWithPath: maybeData.path))) + subscriber.putCompletion() + } + }, error: { error in + subscriber.putError(error) + }, completed: { + subscriber.putCompletion() + }) + let fetchedDataDisposable = account.postbox.mediaBox.fetchedResource(smallProfileImage.resource).start() + return ActionDisposable { + resourceDataDisposable.dispose() + fetchedDataDisposable.dispose() } - } - |> runOn(account.graphicsThreadPool) |> deliverOn(account.graphicsThreadPool) - |> map { data -> UIImage in - assertNotOnMainThread() - - if let image = generateImage(displayDimensions, contextGenerator: { size, context -> Void in - if let imageSource = CGImageSourceCreateWithData(data as CFData, nil), let dataImage = CGImageSourceCreateImageAtIndex(imageSource, 0, nil) { - context.setBlendMode(.copy) - context.draw(dataImage, in: CGRect(origin: CGPoint(), size: displayDimensions)) - context.setBlendMode(.destinationOut) - context.draw(roundCorners.cgImage!, in: CGRect(origin: CGPoint(), size: displayDimensions)) - } - }) { - return image - } else { - UIGraphicsBeginImageContextWithOptions(displayDimensions, false, 0.0) - let image = UIGraphicsGetImageFromCurrentImageContext()! - UIGraphicsEndImageContext() - return image } } - } |> runOn(account.graphicsThreadPool) + } + return imageData + |> deliverOn(account.graphicsThreadPool) + |> map { data -> UIImage in + if let data = data, let image = generateImage(displayDimensions, contextGenerator: { size, context -> Void in + if let imageSource = CGImageSourceCreateWithData(data as CFData, nil), let dataImage = CGImageSourceCreateImageAtIndex(imageSource, 0, nil) { + context.setBlendMode(.copy) + context.draw(dataImage, in: CGRect(origin: CGPoint(), size: displayDimensions)) + context.setBlendMode(.destinationOut) + context.draw(roundCorners.cgImage!, in: CGRect(origin: CGPoint(), size: displayDimensions)) + } + }) { + return image + } else { + UIGraphicsBeginImageContextWithOptions(displayDimensions, false, 0.0) + let image = UIGraphicsGetImageFromCurrentImageContext()! + UIGraphicsEndImageContext() + return image + } + } } else { return nil } diff --git a/TelegramUI/PeerInfoActionItem.swift b/TelegramUI/PeerInfoActionItem.swift index 6d1cf01b9e..f7d7f0a068 100644 --- a/TelegramUI/PeerInfoActionItem.swift +++ b/TelegramUI/PeerInfoActionItem.swift @@ -247,16 +247,10 @@ class PeerInfoActionItemNode: ListViewItemNode { } override func animateInsertion(_ currentTimestamp: Double, duration: Double) { - self.backgroundNode.layer.animateAlpha(from: 0.0, to: 1.0, duration: 0.3) - self.topStripeNode.layer.animateAlpha(from: 0.0, to: 1.0, duration: 0.3) - self.bottomStripeNode.layer.animateAlpha(from: 0.0, to: 1.0, duration: 0.3) - self.titleNode.layer.animateAlpha(from: 0.0, to: 1.0, duration: 0.3) + self.layer.animateAlpha(from: 0.0, to: 1.0, duration: 0.4) } override func animateRemoved(_ currentTimestamp: Double, duration: Double) { - self.backgroundNode.layer.animateAlpha(from: 1.0, to: 0.0, duration: 0.3, removeOnCompletion: false) - self.topStripeNode.layer.animateAlpha(from: 1.0, to: 0.0, duration: 0.3, removeOnCompletion: false) - self.bottomStripeNode.layer.animateAlpha(from: 1.0, to: 0.0, duration: 0.3, removeOnCompletion: false) - self.titleNode.layer.animateAlpha(from: 1.0, to: 0.0, duration: 0.3, removeOnCompletion: false) + self.layer.animateAlpha(from: 1.0, to: 0.0, duration: 0.15, removeOnCompletion: false) } } diff --git a/TelegramUI/PeerInfoAvatarAndNameItem.swift b/TelegramUI/PeerInfoAvatarAndNameItem.swift index 70767abe8f..91e8116890 100644 --- a/TelegramUI/PeerInfoAvatarAndNameItem.swift +++ b/TelegramUI/PeerInfoAvatarAndNameItem.swift @@ -5,17 +5,25 @@ import Postbox import TelegramCore import SwiftSignalKit +struct PeerInfoAvatarAndNameItemEditingState: Equatable { + static func ==(lhs: PeerInfoAvatarAndNameItemEditingState, rhs: PeerInfoAvatarAndNameItemEditingState) -> Bool { + return true + } +} + class PeerInfoAvatarAndNameItem: ListViewItem, PeerInfoItem { let account: Account let peer: Peer? let cachedData: CachedPeerData? + let editingState: PeerInfoAvatarAndNameItemEditingState? let sectionId: PeerInfoItemSectionId let style: PeerInfoListStyle - init(account: Account, peer: Peer?, cachedData: CachedPeerData?, sectionId: PeerInfoItemSectionId, style: PeerInfoListStyle) { + init(account: Account, peer: Peer?, cachedData: CachedPeerData?, editingState: PeerInfoAvatarAndNameItemEditingState?, sectionId: PeerInfoItemSectionId, style: PeerInfoListStyle) { self.account = account self.peer = peer self.cachedData = cachedData + self.editingState = editingState self.sectionId = sectionId self.style = style } @@ -29,13 +37,17 @@ class PeerInfoAvatarAndNameItem: ListViewItem, PeerInfoItem { node.insets = layout.insets completion(node, { - apply() + apply(false) }) } } func updateNode(async: @escaping (@escaping () -> Void) -> Void, node: ListViewItemNode, width: CGFloat, previousItem: ListViewItem?, nextItem: ListViewItem?, animation: ListViewItemUpdateAnimation, completion: @escaping (ListViewItemNodeLayout, @escaping () -> Void) -> Void) { if let node = node as? PeerInfoAvatarAndNameItemNode { + var animated = true + if case .None = animation { + animated = false + } Queue.mainQueue().async { let makeLayout = node.asyncLayout() @@ -43,7 +55,7 @@ class PeerInfoAvatarAndNameItem: ListViewItem, PeerInfoItem { let (layout, apply) = makeLayout(self, width, peerInfoItemNeighbors(item: self, topItem: previousItem as? PeerInfoItem, bottomItem: nextItem as? PeerInfoItem)) Queue.mainQueue().async { completion(layout, { - apply() + apply(animated) }) } } @@ -70,6 +82,10 @@ class PeerInfoAvatarAndNameItemNode: ListViewItemNode { private let nameNode: TextNode private let statusNode: TextNode + private var inputSeparator: ASDisplayNode? + private var inputFirstField: ASEditableTextNode? + private var inputSecondField: ASEditableTextNode? + init() { self.backgroundNode = ASDisplayNode() self.backgroundNode.isLayerBacked = true @@ -102,7 +118,7 @@ class PeerInfoAvatarAndNameItemNode: ListViewItemNode { self.addSubnode(self.statusNode) } - func asyncLayout() -> (_ item: PeerInfoAvatarAndNameItem, _ width: CGFloat, _ neighbors: PeerInfoItemNeighbors) -> (ListViewItemNodeLayout, () -> Void) { + func asyncLayout() -> (_ item: PeerInfoAvatarAndNameItem, _ width: CGFloat, _ neighbors: PeerInfoItemNeighbors) -> (ListViewItemNodeLayout, (Bool) -> Void) { let layoutNameNode = TextNode.asyncLayout(self.nameNode) let layoutStatusNode = TextNode.asyncLayout(self.statusNode) @@ -161,7 +177,7 @@ class PeerInfoAvatarAndNameItemNode: ListViewItemNode { let layout = ListViewItemNodeLayout(contentSize: contentSize, insets: insets) let layoutSize = layout.size - return (layout, { [weak self] in + return (layout, { [weak self] animated in if let strongSelf = self { let avatarOriginY: CGFloat switch item.style { @@ -220,6 +236,99 @@ class PeerInfoAvatarAndNameItemNode: ListViewItemNode { strongSelf.nameNode.frame = CGRect(origin: CGPoint(x: 94.0, y: 25.0), size: nameNodeLayout.size) strongSelf.statusNode.frame = CGRect(origin: CGPoint(x: 94.0, y: 25.0 + nameNodeLayout.size.height + 4.0), size: statusNodeLayout.size) + + if let editingState = item.editingState { + if let user = item.peer as? TelegramUser { + if strongSelf.inputSeparator == nil { + let inputSeparator = ASDisplayNode() + inputSeparator.backgroundColor = UIColor(0xc8c7cc) + inputSeparator.isLayerBacked = true + strongSelf.addSubnode(inputSeparator) + strongSelf.inputSeparator = inputSeparator + } + + if strongSelf.inputFirstField == nil { + let inputFirstField = ASEditableTextNode() + inputFirstField.typingAttributes = [NSFontAttributeName: Font.regular(17.0)] + //inputFirstField.backgroundColor = UIColor.lightGray + inputFirstField.attributedPlaceholderText = NSAttributedString(string: "First Name", font: Font.regular(17.0), textColor: UIColor(0xc8c8ce)) + inputFirstField.attributedText = NSAttributedString(string: user.firstName ?? "", font: Font.regular(17.0), textColor: UIColor.black) + strongSelf.inputFirstField = inputFirstField + strongSelf.view.addSubnode(inputFirstField) + } + + if strongSelf.inputSecondField == nil { + let inputSecondField = ASEditableTextNode() + inputSecondField.typingAttributes = [NSFontAttributeName: Font.regular(17.0)] + //inputSecondField.backgroundColor = UIColor.lightGray + inputSecondField.attributedPlaceholderText = NSAttributedString(string: "Last Name", font: Font.regular(17.0), textColor: UIColor(0xc8c8ce)) + inputSecondField.attributedText = NSAttributedString(string: user.lastName ?? "", font: Font.regular(17.0), textColor: UIColor.black) + strongSelf.inputSecondField = inputSecondField + strongSelf.view.addSubnode(inputSecondField) + } + + strongSelf.inputSeparator?.frame = CGRect(origin: CGPoint(x: 100.0, y: 49.0), size: CGSize(width: width - 100.0, height: separatorHeight)) + strongSelf.inputFirstField?.frame = CGRect(origin: CGPoint(x: 111.0, y: 16.0), size: CGSize(width: width - 111.0 - 8.0, height: 30.0)) + strongSelf.inputSecondField?.frame = CGRect(origin: CGPoint(x: 111.0, y: 59.0), size: CGSize(width: width - 111.0 - 8.0, height: 30.0)) + + if animated { + strongSelf.inputSeparator?.layer.animateAlpha(from: 0.0, to: 1.0, duration: 0.3) + strongSelf.inputFirstField?.layer.animateAlpha(from: 0.0, to: 1.0, duration: 0.3) + strongSelf.inputSecondField?.layer.animateAlpha(from: 0.0, to: 1.0, duration: 0.3) + } + } + + if animated { + strongSelf.statusNode.layer.animateAlpha(from: CGFloat(strongSelf.statusNode.layer.opacity), to: 0.0, duration: 0.3) + strongSelf.statusNode.alpha = 0.0 + strongSelf.nameNode.layer.animateAlpha(from: CGFloat(strongSelf.nameNode.layer.opacity), to: 0.0, duration: 0.3) + strongSelf.nameNode.alpha = 0.0 + } else { + strongSelf.statusNode.alpha = 0.0 + strongSelf.nameNode.alpha = 0.0 + } + } else { + if let inputSeparator = strongSelf.inputSeparator { + strongSelf.inputSeparator = nil + + if animated { + inputSeparator.layer.animateAlpha(from: 1.0, to: 0.0, duration: 0.3, removeOnCompletion: false, completion: { [weak inputSeparator] _ in + inputSeparator?.removeFromSupernode() + }) + } else { + inputSeparator.removeFromSupernode() + } + } + if let inputFirstField = strongSelf.inputFirstField { + strongSelf.inputFirstField = nil + if animated { + inputFirstField.layer.animateAlpha(from: 1.0, to: 0.0, duration: 0.3, removeOnCompletion: false, completion: { [weak inputFirstField] _ in + inputFirstField?.removeFromSupernode() + }) + } else { + inputFirstField.removeFromSupernode() + } + } + if let inputSecondField = strongSelf.inputSecondField { + strongSelf.inputSecondField = nil + if animated { + inputSecondField.layer.animateAlpha(from: 1.0, to: 0.0, duration: 0.3, removeOnCompletion: false, completion: { [weak inputSecondField] _ in + inputSecondField?.removeFromSupernode() + }) + } else { + inputSecondField.removeFromSupernode() + } + } + if animated { + strongSelf.statusNode.layer.animateAlpha(from: CGFloat(strongSelf.statusNode.layer.opacity), to: 1.0, duration: 0.3) + strongSelf.statusNode.alpha = 1.0 + strongSelf.nameNode.layer.animateAlpha(from: CGFloat(strongSelf.nameNode.layer.opacity), to: 1.0, duration: 0.3) + strongSelf.nameNode.alpha = 1.0 + } else { + strongSelf.statusNode.alpha = 1.0 + strongSelf.nameNode.alpha = 1.0 + } + } } }) } diff --git a/TelegramUI/PeerInfoController.swift b/TelegramUI/PeerInfoController.swift index 476dfaab09..1e356b8386 100644 --- a/TelegramUI/PeerInfoController.swift +++ b/TelegramUI/PeerInfoController.swift @@ -5,13 +5,15 @@ import SwiftSignalKit import TelegramCore final class PeerInfoControllerInteraction { + let updateState: ((PeerInfoState?) -> PeerInfoState?) -> Void let openSharedMedia: () -> Void - let changeNotificationNoteSettings: () -> Void + let changeNotificationMuteSettings: () -> Void let openPeerInfo: (PeerId) -> Void - init(openSharedMedia: @escaping () -> Void, changeNotificationNoteSettings: @escaping () -> Void, openPeerInfo: @escaping (PeerId) -> Void) { + init(updateState: @escaping ((PeerInfoState?) -> PeerInfoState?) -> Void, openSharedMedia: @escaping () -> Void, changeNotificationMuteSettings: @escaping () -> Void, openPeerInfo: @escaping (PeerId) -> Void) { + self.updateState = updateState self.openSharedMedia = openSharedMedia - self.changeNotificationNoteSettings = changeNotificationNoteSettings + self.changeNotificationMuteSettings = changeNotificationMuteSettings self.openPeerInfo = openPeerInfo } } @@ -61,8 +63,16 @@ private func preparedPeerInfoEntryTransition(account: Account, from fromEntries: } private struct PeerInfoEquatableState: Equatable { + let state: PeerInfoState? + static func ==(lhs: PeerInfoEquatableState, rhs: PeerInfoEquatableState) -> Bool { - + if let lhsState = lhs.state, let rhsState = rhs.state { + return lhsState.isEqual(to: rhsState) + } else if (lhs.state != nil) != (rhs.state != nil) { + return false + } else { + return true + } } } @@ -80,7 +90,18 @@ public final class PeerInfoController: ListController { private let changeSettingsDisposable = MetaDisposable() private var currentListStyle: PeerInfoListStyle = .plain - private var state = Promise(nil) + + private var state = PeerInfoEquatableState(state: nil) { + didSet { + self.statePromise.set(.single(self.state)) + } + } + private var statePromise = Promise(PeerInfoEquatableState(state: nil)) + + private var leftNavigationButtonItem: UIBarButtonItem? + private var leftNavigationButton: PeerInfoNavigationButton? + private var rightNavigationButtonItem: UIBarButtonItem? + private var rightNavigationButton: PeerInfoNavigationButton? public init(account: Account, peerId: PeerId) { self.account = account @@ -103,13 +124,17 @@ public final class PeerInfoController: ListController { override public func displayNodeDidLoad() { super.displayNodeDidLoad() - let interaction = PeerInfoControllerInteraction(openSharedMedia: { [weak self] in + let interaction = PeerInfoControllerInteraction(updateState: { [weak self] f in + if let strongSelf = self { + strongSelf.state = PeerInfoEquatableState(state: f(strongSelf.state.state)) + } + }, openSharedMedia: { [weak self] in if let strongSelf = self { if let controller = peerSharedMediaController(account: strongSelf.account, peerId: strongSelf.peerId) { (strongSelf.navigationController as? NavigationController)?.pushViewController(controller) } } - }, changeNotificationNoteSettings: { [weak self] in + }, changeNotificationMuteSettings: { [weak self] in if let strongSelf = self { let controller = ActionSheetController() let dismissAction: () -> Void = { [weak controller] in @@ -167,9 +192,11 @@ public final class PeerInfoController: ListController { let previousEntries = Atomic<[PeerInfoSortableEntry]?>(value: nil) let account = self.account - let transition = account.viewTracker.peerView(self.peerId) - |> map { view -> (PeerInfoEntryTransition, PeerInfoListStyle, Bool, Bool) in - let entries = peerInfoEntries(view: view).map { PeerInfoSortableEntry(entry: $0) } + let transition = combineLatest(account.viewTracker.peerView(self.peerId), self.statePromise.get() + |> distinctUntilChanged) + |> map { view, state -> (PeerInfoEntryTransition, PeerInfoListStyle, Bool, Bool, PeerInfoNavigationButton?, PeerInfoNavigationButton?) in + let infoEntries = peerInfoEntries(view: view, state: state.state) + let entries = infoEntries.entries.map { PeerInfoSortableEntry(entry: $0) } assert(entries == entries.sorted()) let previous = previousEntries.swap(entries) let style: PeerInfoListStyle @@ -180,12 +207,49 @@ public final class PeerInfoController: ListController { } else { style = .plain } - return (preparedPeerInfoEntryTransition(account: account, from: previous ?? [], to: entries, interaction: interaction), style, previous == nil, previous != nil) + return (preparedPeerInfoEntryTransition(account: account, from: previous ?? [], to: entries, interaction: interaction), style, previous == nil, previous != nil, infoEntries.leftNavigationButton, infoEntries.rightNavigationButton) } |> deliverOnMainQueue - self.transitionDisposable.set(transition.start(next: { [weak self] (transition, style, firstTime, animated) in - self?.enqueueTransition(transition, style: style, firstTime: firstTime, animated: animated) + self.transitionDisposable.set(transition.start(next: { [weak self] (transition, style, firstTime, animated, leftButton, rightButton) in + if let strongSelf = self { + strongSelf.enqueueTransition(transition, style: style, firstTime: firstTime, animated: animated) + if let leftButton = leftButton { + if let leftNavigationButtonItem = strongSelf.leftNavigationButtonItem { + if leftNavigationButtonItem.title != leftButton.title { + strongSelf.leftNavigationButtonItem = UIBarButtonItem(title: leftButton.title, style: .plain, target: strongSelf, action: #selector(strongSelf.leftNavigationButtonPressed)) + strongSelf.navigationItem.setLeftBarButton(strongSelf.leftNavigationButtonItem, animated: false) + } + strongSelf.leftNavigationButton = leftButton + } else { + strongSelf.leftNavigationButton = leftButton + strongSelf.leftNavigationButtonItem = UIBarButtonItem(title: leftButton.title, style: .plain, target: strongSelf, action: #selector(strongSelf.leftNavigationButtonPressed)) + strongSelf.navigationItem.setLeftBarButton(strongSelf.leftNavigationButtonItem, animated: false) + } + } else if strongSelf.leftNavigationButtonItem != nil { + strongSelf.leftNavigationButtonItem = nil + strongSelf.leftNavigationButton = nil + strongSelf.navigationItem.setLeftBarButton(nil, animated: false) + } + + if let rightButton = rightButton { + if let rightNavigationButtonItem = strongSelf.rightNavigationButtonItem { + if rightNavigationButtonItem.title != rightButton.title { + strongSelf.rightNavigationButtonItem = UIBarButtonItem(title: rightButton.title, style: .plain, target: strongSelf, action: #selector(strongSelf.rightNavigationButtonPressed)) + strongSelf.navigationItem.setRightBarButton(strongSelf.rightNavigationButtonItem, animated: false) + } + strongSelf.rightNavigationButton = rightButton + } else { + strongSelf.rightNavigationButton = rightButton + strongSelf.rightNavigationButtonItem = UIBarButtonItem(title: rightButton.title, style: .plain, target: strongSelf, action: #selector(strongSelf.rightNavigationButtonPressed)) + strongSelf.navigationItem.setRightBarButton(strongSelf.rightNavigationButtonItem, animated: false) + } + } else if strongSelf.rightNavigationButtonItem != nil { + strongSelf.rightNavigationButtonItem = nil + strongSelf.rightNavigationButton = nil + strongSelf.navigationItem.setRightBarButton(nil, animated: false) + } + } })) } @@ -215,4 +279,16 @@ public final class PeerInfoController: ListController { } }) } + + @objc func leftNavigationButtonPressed() { + if let leftNavigationButton = self.leftNavigationButton { + self.state = PeerInfoEquatableState(state: leftNavigationButton.action(self.state.state)) + } + } + + @objc func rightNavigationButtonPressed() { + if let rightNavigationButton = self.rightNavigationButton { + self.state = PeerInfoEquatableState(state: rightNavigationButton.action(self.state.state)) + } + } } diff --git a/TelegramUI/PeerInfoDisclosureItem.swift b/TelegramUI/PeerInfoDisclosureItem.swift index 7496b8222b..653e00cec6 100644 --- a/TelegramUI/PeerInfoDisclosureItem.swift +++ b/TelegramUI/PeerInfoDisclosureItem.swift @@ -244,18 +244,10 @@ class PeerInfoDisclosureItemNode: ListViewItemNode { } override func animateInsertion(_ currentTimestamp: Double, duration: Double) { - self.backgroundNode.layer.animateAlpha(from: 0.0, to: 1.0, duration: duration) - self.topStripeNode.layer.animateAlpha(from: 0.0, to: 1.0, duration: duration) - self.bottomStripeNode.layer.animateAlpha(from: 0.0, to: 1.0, duration: duration) - self.titleNode.layer.animateAlpha(from: 0.0, to: 1.0, duration: duration) - self.labelNode.layer.animateAlpha(from: 0.0, to: 1.0, duration: duration) + self.layer.animateAlpha(from: 0.0, to: 1.0, duration: 0.4) } override func animateRemoved(_ currentTimestamp: Double, duration: Double) { - self.backgroundNode.layer.animateAlpha(from: 1.0, to: 0.0, duration: duration, removeOnCompletion: false) - self.topStripeNode.layer.animateAlpha(from: 1.0, to: 0.0, duration: duration, removeOnCompletion: false) - self.bottomStripeNode.layer.animateAlpha(from: 1.0, to: 0.0, duration: duration, removeOnCompletion: false) - self.titleNode.layer.animateAlpha(from: 1.0, to: 0.0, duration: duration, removeOnCompletion: false) - self.labelNode.layer.animateAlpha(from: 1.0, to: 0.0, duration: duration, removeOnCompletion: false) + self.layer.animateAlpha(from: 1.0, to: 0.0, duration: 0.15, removeOnCompletion: false) } } diff --git a/TelegramUI/PeerInfoEntries.swift b/TelegramUI/PeerInfoEntries.swift index c2a1bc4749..ae4b233933 100644 --- a/TelegramUI/PeerInfoEntries.swift +++ b/TelegramUI/PeerInfoEntries.swift @@ -38,21 +38,24 @@ protocol PeerInfoEntry { func item(account: Account, interaction: PeerInfoControllerInteraction) -> ListViewItem } -enum PeerInfoNavigationButton { - case none - case edit - case done +struct PeerInfoNavigationButton { + let title: String + let action: (PeerInfoState?) -> PeerInfoState? } protocol PeerInfoState { func isEqual(to: PeerInfoState) -> Bool - - var navigationButton: PeerInfoNavigationButton { get } } -func peerInfoEntries(view: PeerView) -> [PeerInfoEntry] { +struct PeerInfoEntries { + let entries: [PeerInfoEntry] + let leftNavigationButton: PeerInfoNavigationButton? + let rightNavigationButton: PeerInfoNavigationButton? +} + +func peerInfoEntries(view: PeerView, state: PeerInfoState?) -> PeerInfoEntries { if let user = view.peers[view.peerId] as? TelegramUser { - return userInfoEntries(view: view) + return userInfoEntries(view: view, state: state) } else if let channel = view.peers[view.peerId] as? TelegramChannel { switch channel.info { case .broadcast: @@ -63,5 +66,5 @@ func peerInfoEntries(view: PeerView) -> [PeerInfoEntry] { } else if let group = view.peers[view.peerId] as? TelegramGroup { return groupInfoEntries(view: view) } - return [] + return PeerInfoEntries(entries: [], leftNavigationButton: nil, rightNavigationButton: nil) } diff --git a/TelegramUI/PeerInfoPeerActionItem.swift b/TelegramUI/PeerInfoPeerActionItem.swift index e539a7e2f0..3065539bc1 100644 --- a/TelegramUI/PeerInfoPeerActionItem.swift +++ b/TelegramUI/PeerInfoPeerActionItem.swift @@ -206,18 +206,10 @@ class PeerInfoPeerActionItemNode: ListViewItemNode { } override func animateInsertion(_ currentTimestamp: Double, duration: Double) { - self.backgroundNode.layer.animateAlpha(from: 0.0, to: 1.0, duration: 0.3) - self.topStripeNode.layer.animateAlpha(from: 0.0, to: 1.0, duration: 0.3) - self.bottomStripeNode.layer.animateAlpha(from: 0.0, to: 1.0, duration: 0.3) - self.titleNode.layer.animateAlpha(from: 0.0, to: 1.0, duration: 0.3) - self.iconNode.layer.animateAlpha(from: 0.0, to: 1.0, duration: 0.3) + self.layer.animateAlpha(from: 0.0, to: 1.0, duration: 0.4) } override func animateRemoved(_ currentTimestamp: Double, duration: Double) { - self.backgroundNode.layer.animateAlpha(from: 1.0, to: 0.0, duration: 0.3, removeOnCompletion: false) - self.topStripeNode.layer.animateAlpha(from: 1.0, to: 0.0, duration: 0.3, removeOnCompletion: false) - self.bottomStripeNode.layer.animateAlpha(from: 1.0, to: 0.0, duration: 0.3, removeOnCompletion: false) - self.titleNode.layer.animateAlpha(from: 1.0, to: 0.0, duration: 0.3, removeOnCompletion: false) - self.iconNode.layer.animateAlpha(from: 1.0, to: 0.0, duration: 0.3, removeOnCompletion: false) + self.layer.animateAlpha(from: 1.0, to: 0.0, duration: 0.15, removeOnCompletion: false) } } diff --git a/TelegramUI/PeerInfoPeerItem.swift b/TelegramUI/PeerInfoPeerItem.swift index 3c349e44b1..a78b837845 100644 --- a/TelegramUI/PeerInfoPeerItem.swift +++ b/TelegramUI/PeerInfoPeerItem.swift @@ -300,22 +300,10 @@ class PeerInfoPeerItemNode: ListViewItemNode { } override func animateInsertion(_ currentTimestamp: Double, duration: Double) { - self.backgroundNode.layer.animateAlpha(from: 0.0, to: 1.0, duration: 0.3) - self.topStripeNode.layer.animateAlpha(from: 0.0, to: 1.0, duration: 0.3) - self.bottomStripeNode.layer.animateAlpha(from: 0.0, to: 1.0, duration: 0.3) - self.titleNode.layer.animateAlpha(from: 0.0, to: 1.0, duration: 0.3) - self.avatarNode.layer.animateAlpha(from: 0.0, to: 1.0, duration: 0.3) - self.statusNode.layer.animateAlpha(from: 0.0, to: 1.0, duration: 0.3) - self.labelNode.layer.animateAlpha(from: 0.0, to: 1.0, duration: 0.3) + self.layer.animateAlpha(from: 0.0, to: 1.0, duration: 0.4) } override func animateRemoved(_ currentTimestamp: Double, duration: Double) { - self.backgroundNode.layer.animateAlpha(from: 1.0, to: 0.0, duration: 0.3, removeOnCompletion: false) - self.topStripeNode.layer.animateAlpha(from: 1.0, to: 0.0, duration: 0.3, removeOnCompletion: false) - self.bottomStripeNode.layer.animateAlpha(from: 1.0, to: 0.0, duration: 0.3, removeOnCompletion: false) - self.titleNode.layer.animateAlpha(from: 1.0, to: 0.0, duration: 0.3, removeOnCompletion: false) - self.avatarNode.layer.animateAlpha(from: 1.0, to: 0.0, duration: 0.3, removeOnCompletion: false) - self.statusNode.layer.animateAlpha(from: 1.0, to: 0.0, duration: 0.3, removeOnCompletion: false) - self.labelNode.layer.animateAlpha(from: 1.0, to: 0.0, duration: 0.3, removeOnCompletion: false) + self.layer.animateAlpha(from: 1.0, to: 0.0, duration: 0.15, removeOnCompletion: false) } } diff --git a/TelegramUI/PeerInfoTextWithLabelItem.swift b/TelegramUI/PeerInfoTextWithLabelItem.swift index 099e1e8edf..2565b2fb2f 100644 --- a/TelegramUI/PeerInfoTextWithLabelItem.swift +++ b/TelegramUI/PeerInfoTextWithLabelItem.swift @@ -111,14 +111,10 @@ class PeerInfoTextWithLabelItemNode: ListViewItemNode { } override func animateInsertion(_ currentTimestamp: Double, duration: Double) { - self.labelNode.layer.animateAlpha(from: 0.0, to: 1.0, duration: duration) - self.textNode.layer.animateAlpha(from: 0.0, to: 1.0, duration: duration) - self.separatorNode.layer.animateAlpha(from: 0.0, to: 1.0, duration: duration) + self.layer.animateAlpha(from: 0.0, to: 1.0, duration: 0.4) } override func animateRemoved(_ currentTimestamp: Double, duration: Double) { - self.labelNode.layer.animateAlpha(from: 1.0, to: 0.0, duration: duration, removeOnCompletion: false) - self.textNode.layer.animateAlpha(from: 1.0, to: 0.0, duration: duration, removeOnCompletion: false) - self.separatorNode.layer.animateAlpha(from: 1.0, to: 0.0, duration: duration, removeOnCompletion: false) + self.layer.animateAlpha(from: 1.0, to: 0.0, duration: 0.15, removeOnCompletion: false) } } diff --git a/TelegramUI/PeerMediaCollectionController.swift b/TelegramUI/PeerMediaCollectionController.swift index 74c94f47fd..5afc614fdc 100644 --- a/TelegramUI/PeerMediaCollectionController.swift +++ b/TelegramUI/PeerMediaCollectionController.swift @@ -176,7 +176,7 @@ public class PeerMediaCollectionController: ViewController { strongSelf.updateInterfaceState(animated: true, { $0.withToggledSelectedMessage(id) }) } } - }) + }, sendSticker: { _ in }) self.controllerInteraction = controllerInteraction @@ -184,7 +184,9 @@ public class PeerMediaCollectionController: ViewController { }, forwardSelectedMessages: { - }, updateTextInputState: { _ in }) + }, updateTextInputState: { _ in + }, updateInputMode: { _ in + }) self.updateInterfaceState(animated: false, { return $0 }) diff --git a/TelegramUI/PeerMediaCollectionControllerNode.swift b/TelegramUI/PeerMediaCollectionControllerNode.swift index 0265f41ea2..bbe0525da9 100644 --- a/TelegramUI/PeerMediaCollectionControllerNode.swift +++ b/TelegramUI/PeerMediaCollectionControllerNode.swift @@ -74,21 +74,21 @@ class PeerMediaCollectionControllerNode: ASDisplayNode { insets.top += navigationBarHeight if let selectionState = self.mediaCollectionInterfaceState.selectionState { + let interfaceState = ChatPresentationInterfaceState().updatedPeer({ _ in self.mediaCollectionInterfaceState.peer }) + if let selectionPanel = self.selectionPanel { - selectionPanel.peer = self.mediaCollectionInterfaceState.peer selectionPanel.selectedMessageCount = selectionState.selectedIds.count - let panelSize = selectionPanel.measure(layout.size) - transition.updateFrame(node: selectionPanel, frame: CGRect(origin: CGPoint(x: 0.0, y: layout.size.height - insets.bottom - panelSize.height), size: panelSize)) + let panelHeight = selectionPanel.updateLayout(width: layout.size.width, transition: transition, interfaceState: interfaceState) + transition.updateFrame(node: selectionPanel, frame: CGRect(origin: CGPoint(x: 0.0, y: layout.size.height - insets.bottom - panelHeight), size: CGSize(width: layout.size.width, height: panelHeight))) } else { let selectionPanel = ChatMessageSelectionInputPanelNode() - selectionPanel.peer = self.mediaCollectionInterfaceState.peer selectionPanel.selectedMessageCount = selectionState.selectedIds.count selectionPanel.backgroundColor = UIColor(0xfafafa) - let panelSize = selectionPanel.measure(layout.size) - selectionPanel.frame = CGRect(origin: CGPoint(x: 0.0, y: layout.size.height - insets.bottom), size: panelSize) + let panelHeight = selectionPanel.updateLayout(width: layout.size.width, transition: .immediate, interfaceState: interfaceState) self.selectionPanel = selectionPanel self.addSubnode(selectionPanel) - transition.updateFrame(node: selectionPanel, frame: CGRect(origin: CGPoint(x: 0.0, y: layout.size.height - insets.bottom - panelSize.height), size: panelSize)) + selectionPanel.frame = CGRect(origin: CGPoint(x: 0.0, y: layout.size.height - insets.bottom), size: CGSize(width: layout.size.width, height: panelHeight)) + transition.updateFrame(node: selectionPanel, frame: CGRect(origin: CGPoint(x: 0.0, y: layout.size.height - insets.bottom - panelHeight), size: CGSize(width: layout.size.width, height: panelHeight))) } } else if let selectionPanel = self.selectionPanel { self.selectionPanel = nil diff --git a/TelegramUI/PhotoResources.swift b/TelegramUI/PhotoResources.swift index 7e3ac92749..0f3e4064eb 100644 --- a/TelegramUI/PhotoResources.swift +++ b/TelegramUI/PhotoResources.swift @@ -11,25 +11,22 @@ func largestRepresentationForPhoto(_ photo: TelegramMediaImage) -> TelegramMedia return photo.representationForDisplayAtSize(CGSize(width: 1280.0, height: 1280.0)) } -private func chatMessagePhotoDatas(account: Account, photo: TelegramMediaImage, fullRepresentationSize: CGSize = CGSize(width: 1280.0, height: 1280.0), autoFetchFullSize: Bool = false) -> Signal<(Data?, Data?, Int), NoError> { - if let smallestRepresentation = smallestImageRepresentation(photo.representations), let largestRepresentation = photo.representationForDisplayAtSize(fullRepresentationSize), let smallestSize = smallestRepresentation.size, let largestSize = largestRepresentation.size { - let thumbnailResource = CloudFileMediaResource(location: smallestRepresentation.location, size: smallestSize) - let fullSizeResource = CloudFileMediaResource(location: largestRepresentation.location, size: largestSize) +private func chatMessagePhotoDatas(account: Account, photo: TelegramMediaImage, fullRepresentationSize: CGSize = CGSize(width: 1280.0, height: 1280.0), autoFetchFullSize: Bool = false) -> Signal<(Data?, Data?, Bool), NoError> { + if let smallestRepresentation = smallestImageRepresentation(photo.representations), let largestRepresentation = photo.representationForDisplayAtSize(fullRepresentationSize) { + let maybeFullSize = account.postbox.mediaBox.resourceData(largestRepresentation.resource) - let maybeFullSize = account.postbox.mediaBox.resourceData(fullSizeResource) - - let signal = maybeFullSize |> take(1) |> mapToSignal { maybeData -> Signal<(Data?, Data?, Int), NoError> in - if maybeData.size >= fullSizeResource.size { + let signal = maybeFullSize |> take(1) |> mapToSignal { maybeData -> Signal<(Data?, Data?, Bool), NoError> in + if maybeData.complete { let loadedData: Data? = try? Data(contentsOf: URL(fileURLWithPath: maybeData.path), options: []) - return .single((nil, loadedData, fullSizeResource.size)) + return .single((nil, loadedData, true)) } else { - let fetchedThumbnail = account.postbox.mediaBox.fetchedResource(thumbnailResource) - let fetchedFullSize = account.postbox.mediaBox.fetchedResource(fullSizeResource) + let fetchedThumbnail = account.postbox.mediaBox.fetchedResource(smallestRepresentation.resource) + let fetchedFullSize = account.postbox.mediaBox.fetchedResource(largestRepresentation.resource) let thumbnail = Signal { subscriber in let fetchedDisposable = fetchedThumbnail.start() - let thumbnailDisposable = account.postbox.mediaBox.resourceData(thumbnailResource).start(next: { next in + let thumbnailDisposable = account.postbox.mediaBox.resourceData(smallestRepresentation.resource).start(next: { next in subscriber.putNext(next.size == 0 ? nil : try? Data(contentsOf: URL(fileURLWithPath: next.path), options: [])) }, error: subscriber.putError, completed: subscriber.putCompletion) @@ -39,13 +36,13 @@ private func chatMessagePhotoDatas(account: Account, photo: TelegramMediaImage, } } - let fullSizeData: Signal + let fullSizeData: Signal<(Data?, Bool), NoError> if autoFetchFullSize { - fullSizeData = Signal { subscriber in + fullSizeData = Signal<(Data?, Bool), NoError> { subscriber in let fetchedFullSizeDisposable = fetchedFullSize.start() - let fullSizeDisposable = account.postbox.mediaBox.resourceData(fullSizeResource).start(next: { next in - subscriber.putNext(next.size == 0 ? nil : try? Data(contentsOf: URL(fileURLWithPath: next.path), options: [])) + let fullSizeDisposable = account.postbox.mediaBox.resourceData(largestRepresentation.resource).start(next: { next in + subscriber.putNext((next.size == 0 ? nil : try? Data(contentsOf: URL(fileURLWithPath: next.path), options: []), next.complete)) }, error: subscriber.putError, completed: subscriber.putCompletion) return ActionDisposable { @@ -54,16 +51,16 @@ private func chatMessagePhotoDatas(account: Account, photo: TelegramMediaImage, } } } else { - fullSizeData = account.postbox.mediaBox.resourceData(fullSizeResource) - |> map { next -> Data? in - return next.size == 0 ? nil : try? Data(contentsOf: URL(fileURLWithPath: next.path), options: []) + fullSizeData = account.postbox.mediaBox.resourceData(largestRepresentation.resource) + |> map { next -> (Data?, Bool) in + return (next.size == 0 ? nil : try? Data(contentsOf: URL(fileURLWithPath: next.path), options: []), next.complete) } } return thumbnail |> mapToSignal { thumbnailData in - return fullSizeData |> map { fullSizeData in - return (thumbnailData, fullSizeData, fullSizeResource.size) + return fullSizeData |> map { (fullSizeData, complete) in + return (thumbnailData, fullSizeData, complete) } } } @@ -75,18 +72,18 @@ private func chatMessagePhotoDatas(account: Account, photo: TelegramMediaImage, } } -private func chatMessageFileDatas(account: Account, file: TelegramMediaFile, progressive: Bool = false) -> Signal<(Data?, (Data, String)?, Int), NoError> { - if let smallestRepresentation = smallestImageRepresentation(file.previewRepresentations), let smallestSize = smallestRepresentation.size { - let thumbnailResource = CloudFileMediaResource(location: smallestRepresentation.location, size: smallestSize) - let fullSizeResource = CloudFileMediaResource(location: file.location, size: file.size) +private func chatMessageFileDatas(account: Account, file: TelegramMediaFile, progressive: Bool = false) -> Signal<(Data?, (Data, String)?, Bool), NoError> { + if let smallestRepresentation = smallestImageRepresentation(file.previewRepresentations), let largestRepresentation = largestImageRepresentation(file.previewRepresentations) { + let thumbnailResource = smallestRepresentation.resource + let fullSizeResource = largestRepresentation.resource let maybeFullSize = account.postbox.mediaBox.resourceData(fullSizeResource) - let signal = maybeFullSize |> take(1) |> mapToSignal { maybeData -> Signal<(Data?, (Data, String)?, Int), NoError> in - if maybeData.size >= fullSizeResource.size { + let signal = maybeFullSize |> take(1) |> mapToSignal { maybeData -> Signal<(Data?, (Data, String)?, Bool), NoError> in + if maybeData.complete { let loadedData: Data? = try? Data(contentsOf: URL(fileURLWithPath: maybeData.path), options: []) - return .single((nil, loadedData == nil ? nil : (loadedData!, maybeData.path), fullSizeResource.size)) + return .single((nil, loadedData == nil ? nil : (loadedData!, maybeData.path), true)) } else { let fetchedThumbnail = account.postbox.mediaBox.fetchedResource(thumbnailResource) @@ -103,14 +100,14 @@ private func chatMessageFileDatas(account: Account, file: TelegramMediaFile, pro } - let fullSizeDataAndPath = account.postbox.mediaBox.resourceData(fullSizeResource, complete: !progressive) |> map { next -> (Data, String)? in + let fullSizeDataAndPath = account.postbox.mediaBox.resourceData(fullSizeResource, complete: !progressive) |> map { next -> ((Data, String)?, Bool) in let data = next.size == 0 ? nil : try? Data(contentsOf: URL(fileURLWithPath: next.path), options: .mappedIfSafe) - return data == nil ? nil : (data!, next.path) + return (data == nil ? nil : (data!, next.path), next.complete) } return thumbnail |> mapToSignal { thumbnailData in - return fullSizeDataAndPath |> map { dataAndPath in - return (thumbnailData, dataAndPath, fullSizeResource.size) + return fullSizeDataAndPath |> map { (dataAndPath, complete) in + return (thumbnailData, dataAndPath, complete) } } } @@ -372,7 +369,7 @@ private func addCorners(_ context: DrawingContext, arguments: TransformImageArgu func chatMessagePhoto(account: Account, photo: TelegramMediaImage) -> Signal<(TransformImageArguments) -> DrawingContext, NoError> { let signal = chatMessagePhotoDatas(account: account, photo: photo) - return signal |> map { (thumbnailData, fullSizeData, fullTotalSize) in + return signal |> map { (thumbnailData, fullSizeData, fullSizeComplete) in return { arguments in assertNotOnMainThread() let context = DrawingContext(size: arguments.drawingSize, clear: true) @@ -383,7 +380,7 @@ func chatMessagePhoto(account: Account, photo: TelegramMediaImage) -> Signal<(Tr var fullSizeImage: CGImage? if let fullSizeData = fullSizeData { - if fullSizeData.count >= fullTotalSize { + if fullSizeComplete { let options = NSMutableDictionary() options.setValue(max(fittedSize.width * context.scale, fittedSize.height * context.scale) as NSNumber, forKey: kCGImageSourceThumbnailMaxPixelSize as String) options.setValue(true as NSNumber, forKey: kCGImageSourceCreateThumbnailFromImageAlways as String) @@ -392,7 +389,7 @@ func chatMessagePhoto(account: Account, photo: TelegramMediaImage) -> Signal<(Tr } } else { let imageSource = CGImageSourceCreateIncremental(nil) - CGImageSourceUpdateData(imageSource, fullSizeData as CFData, fullSizeData.count >= fullTotalSize) + CGImageSourceUpdateData(imageSource, fullSizeData as CFData, fullSizeComplete) let options = NSMutableDictionary() options[kCGImageSourceShouldCache as NSString] = false as NSNumber @@ -450,7 +447,7 @@ func chatMessagePhoto(account: Account, photo: TelegramMediaImage) -> Signal<(Tr func mediaGridMessagePhoto(account: Account, photo: TelegramMediaImage) -> Signal<(TransformImageArguments) -> DrawingContext, NoError> { let signal = chatMessagePhotoDatas(account: account, photo: photo, fullRepresentationSize: CGSize(width: 127.0, height: 127.0), autoFetchFullSize: true) - return signal |> map { (thumbnailData, fullSizeData, fullTotalSize) in + return signal |> map { (thumbnailData, fullSizeData, fullSizeComplete) in return { arguments in assertNotOnMainThread() let context = DrawingContext(size: arguments.drawingSize, clear: true) @@ -461,7 +458,7 @@ func mediaGridMessagePhoto(account: Account, photo: TelegramMediaImage) -> Signa var fullSizeImage: CGImage? if let fullSizeData = fullSizeData { - if fullSizeData.count >= fullTotalSize { + if fullSizeComplete { let options = NSMutableDictionary() options.setValue(max(fittedSize.width * context.scale, fittedSize.height * context.scale) as NSNumber, forKey: kCGImageSourceThumbnailMaxPixelSize as String) options.setValue(true as NSNumber, forKey: kCGImageSourceCreateThumbnailFromImageAlways as String) @@ -470,7 +467,7 @@ func mediaGridMessagePhoto(account: Account, photo: TelegramMediaImage) -> Signa } } else { let imageSource = CGImageSourceCreateIncremental(nil) - CGImageSourceUpdateData(imageSource, fullSizeData as CFData, fullSizeData.count >= fullTotalSize) + CGImageSourceUpdateData(imageSource, fullSizeData as CFData, fullSizeComplete) let options = NSMutableDictionary() options[kCGImageSourceShouldCache as NSString] = false as NSNumber @@ -526,34 +523,30 @@ func mediaGridMessagePhoto(account: Account, photo: TelegramMediaImage) -> Signa } func chatMessagePhotoStatus(account: Account, photo: TelegramMediaImage) -> Signal { - if let largestRepresentation = largestRepresentationForPhoto(photo), let largestSize = largestRepresentation.size { - let fullSizeResource = CloudFileMediaResource(location: largestRepresentation.location, size: largestSize) - return account.postbox.mediaBox.resourceStatus(fullSizeResource) + if let largestRepresentation = largestRepresentationForPhoto(photo) { + return account.postbox.mediaBox.resourceStatus(largestRepresentation.resource) } else { return .never() } } func chatMessagePhotoInteractiveFetched(account: Account, photo: TelegramMediaImage) -> Signal { - if let largestRepresentation = largestRepresentationForPhoto(photo), let largestSize = largestRepresentation.size { - let fullSizeResource = CloudFileMediaResource(location: largestRepresentation.location, size: largestSize) - return account.postbox.mediaBox.fetchedResource(fullSizeResource) + if let largestRepresentation = largestRepresentationForPhoto(photo) { + return account.postbox.mediaBox.fetchedResource(largestRepresentation.resource) } else { return .never() } } func chatMessagePhotoCancelInteractiveFetch(account: Account, photo: TelegramMediaImage) { - if let largestRepresentation = largestRepresentationForPhoto(photo), let largestSize = largestRepresentation.size { - let fullSizeResource = CloudFileMediaResource(location: largestRepresentation.location, size: largestSize) - return account.postbox.mediaBox.cancelInteractiveResourceFetch(fullSizeResource) + if let largestRepresentation = largestRepresentationForPhoto(photo) { + return account.postbox.mediaBox.cancelInteractiveResourceFetch(largestRepresentation.resource) } } func chatWebpageSnippetPhotoData(account: Account, photo: TelegramMediaImage) -> Signal { if let closestRepresentation = photo.representationForDisplayAtSize(CGSize(width: 120.0, height: 120.0)) { - let resource = CloudFileMediaResource(location: closestRepresentation.location, size: closestRepresentation.size ?? 0) - let resourceData = account.postbox.mediaBox.resourceData(resource) |> map { next in + let resourceData = account.postbox.mediaBox.resourceData(closestRepresentation.resource) |> map { next in return next.size == 0 ? nil : try? Data(contentsOf: URL(fileURLWithPath: next.path), options: .mappedIfSafe) } @@ -566,7 +559,7 @@ func chatWebpageSnippetPhotoData(account: Account, photo: TelegramMediaImage) -> }, completed: { subscriber.putCompletion() })) - disposable.add(account.postbox.mediaBox.fetchedResource(resource).start()) + disposable.add(account.postbox.mediaBox.fetchedResource(closestRepresentation.resource).start()) return disposable } } else { @@ -618,7 +611,7 @@ func chatWebpageSnippetPhoto(account: Account, photo: TelegramMediaImage) -> Sig func chatMessageVideo(account: Account, video: TelegramMediaFile) -> Signal<(TransformImageArguments) -> DrawingContext, NoError> { let signal = chatMessageFileDatas(account: account, file: video) - return signal |> map { (thumbnailData, fullSizeDataAndPath, fullTotalSize) in + return signal |> map { (thumbnailData, fullSizeDataAndPath, fullSizeComplete) in return { arguments in assertNotOnMainThread() let context = DrawingContext(size: arguments.drawingSize, clear: true) @@ -632,7 +625,7 @@ func chatMessageVideo(account: Account, video: TelegramMediaFile) -> Signal<(Tra var fullSizeImage: CGImage? if let fullSizeDataAndPath = fullSizeDataAndPath { - if fullSizeDataAndPath.0.count >= fullTotalSize { + if fullSizeComplete { if video.mimeType.hasPrefix("video/") { let tempFilePath = NSTemporaryDirectory() + "\(arc4random()).mov" @@ -714,7 +707,7 @@ func chatMessageVideo(account: Account, video: TelegramMediaFile) -> Signal<(Tra func chatMessageImageFile(account: Account, file: TelegramMediaFile, progressive: Bool = false) -> Signal<(TransformImageArguments) -> DrawingContext, NoError> { let signal = chatMessageFileDatas(account: account, file: file, progressive: progressive) - return signal |> map { (thumbnailData, fullSizeDataAndPath, fullTotalSize) in + return signal |> map { (thumbnailData, fullSizeDataAndPath, fullSizeComplete) in return { arguments in assertNotOnMainThread() let context = DrawingContext(size: arguments.drawingSize, clear: true) @@ -725,7 +718,7 @@ func chatMessageImageFile(account: Account, file: TelegramMediaFile, progressive var fullSizeImage: CGImage? if let fullSizeDataAndPath = fullSizeDataAndPath { - if fullSizeDataAndPath.0.count >= fullTotalSize { + if fullSizeComplete { let options = NSMutableDictionary() options.setValue(max(fittedSize.width * context.scale, fittedSize.height * context.scale) as NSNumber, forKey: kCGImageSourceThumbnailMaxPixelSize as String) options.setValue(true as NSNumber, forKey: kCGImageSourceCreateThumbnailFromImageAlways as String) @@ -734,7 +727,7 @@ func chatMessageImageFile(account: Account, file: TelegramMediaFile, progressive } } else if progressive { let imageSource = CGImageSourceCreateIncremental(nil) - CGImageSourceUpdateData(imageSource, fullSizeDataAndPath.0 as CFData, fullSizeDataAndPath.0.count >= fullTotalSize) + CGImageSourceUpdateData(imageSource, fullSizeDataAndPath.0 as CFData, fullSizeComplete) let options = NSMutableDictionary() options[kCGImageSourceShouldCache as NSString] = false as NSNumber @@ -790,16 +783,13 @@ func chatMessageImageFile(account: Account, file: TelegramMediaFile, progressive } func chatMessageFileStatus(account: Account, file: TelegramMediaFile) -> Signal { - let fullSizeResource = CloudFileMediaResource(location: file.location, size: file.size) - return account.postbox.mediaBox.resourceStatus(fullSizeResource) + return account.postbox.mediaBox.resourceStatus(file.resource) } func chatMessageFileInteractiveFetched(account: Account, file: TelegramMediaFile) -> Signal { - let fullSizeResource = CloudFileMediaResource(location: file.location, size: file.size) - return account.postbox.mediaBox.fetchedResource(fullSizeResource) + return account.postbox.mediaBox.fetchedResource(file.resource) } func chatMessageFileCancelInteractiveFetch(account: Account, file: TelegramMediaFile) { - let fullSizeResource = CloudFileMediaResource(location: file.location, size: file.size) - return account.postbox.mediaBox.cancelInteractiveResourceFetch(fullSizeResource) + account.postbox.mediaBox.cancelInteractiveResourceFetch(file.resource) } diff --git a/TelegramUI/StickerResources.swift b/TelegramUI/StickerResources.swift index 31b71bdca8..5a5e942bb4 100644 --- a/TelegramUI/StickerResources.swift +++ b/TelegramUI/StickerResources.swift @@ -5,42 +5,71 @@ import Display import TelegramUIPrivateModule import TelegramCore -private func chatMessageStickerDatas(account: Account, file: TelegramMediaFile) -> Signal<(Data?, Data?, Int), NoError> { - let fullSizeResource = fileResource(file) - let maybeFetched = account.postbox.mediaBox.resourceData(fullSizeResource, complete: true) +private func imageFromAJpeg(data: Data) -> (UIImage, UIImage)? { + if let (colorData, alphaData) = data.withUnsafeBytes({ (bytes: UnsafePointer) -> (Data, Data)? in + var colorSize: Int32 = 0 + memcpy(&colorSize, bytes, 4) + if colorSize < 0 || Int(colorSize) > data.count - 8 { + return nil + } + var alphaSize: Int32 = 0 + memcpy(&alphaSize, bytes.advanced(by: 4 + Int(colorSize)), 4) + if alphaSize < 0 || Int(alphaSize) > data.count - Int(colorSize) - 8 { + return nil + } + //let colorData = Data(bytesNoCopy: UnsafeMutablePointer(mutating: bytes).advanced(by: 4), count: Int(colorSize), deallocator: .none) + //let alphaData = Data(bytesNoCopy: UnsafeMutablePointer(mutating: bytes).advanced(by: 4 + Int(colorSize) + 4), count: Int(alphaSize), deallocator: .none) + let colorData = data.subdata(in: 4 ..< (4 + Int(colorSize))) + let alphaData = data.subdata(in: (4 + Int(colorSize) + 4) ..< (4 + Int(colorSize) + 4 + Int(alphaSize))) + return (colorData, alphaData) + }) { + if let colorImage = UIImage(data: colorData), let alphaImage = UIImage(data: alphaData) { + return (colorImage, alphaImage) + + /*return generateImage(CGSize(width: colorImage.size.width * colorImage.scale, height: colorImage.size.height * colorImage.scale), contextGenerator: { size, context in + colorImage.draw(in: CGRect(origin: CGPoint(), size: size)) + }, scale: 1.0)*/ + } + } + return nil +} + +private func chatMessageStickerDatas(account: Account, file: TelegramMediaFile, small: Bool) -> Signal<(Data?, Data?, Bool), NoError> { + //let maybeFetched = account.postbox.mediaBox.resourceData(file.resource, complete: true) + let maybeFetched = account.postbox.mediaBox.cachedResourceRepresentation(file.resource, representation: CachedStickerAJpegRepresentation(size: small ? CGSize(width: 160.0, height: 160.0) : nil)) return maybeFetched |> take(1) |> mapToSignal { maybeData in - if maybeData.size >= fullSizeResource.size { + if maybeData.size >= file.size { let loadedData: Data? = try? Data(contentsOf: URL(fileURLWithPath: maybeData.path), options: []) - return .single((nil, loadedData, fullSizeResource.size)) + return .single((nil, loadedData, true)) } else { - let fullSizeData = account.postbox.mediaBox.resourceData(fullSizeResource, complete: true) |> map { next in - return next.size == 0 ? nil : try? Data(contentsOf: URL(fileURLWithPath: next.path), options: .mappedIfSafe) + //let fullSizeData = account.postbox.mediaBox.resourceData(file.resource, complete: true) + + let fullSizeData = account.postbox.mediaBox.cachedResourceRepresentation(file.resource, representation: CachedStickerAJpegRepresentation(size: small ? CGSize(width: 160.0, height: 160.0) : nil)) |> map { next in + return (next.size == 0 ? nil : try? Data(contentsOf: URL(fileURLWithPath: next.path), options: .mappedIfSafe), next.complete) } - return fullSizeData |> map { data -> (Data?, Data?, Int) in - return (nil, data, fullSizeResource.size) + return fullSizeData |> map { (data, complete) -> (Data?, Data?, Bool) in + return (nil, data, complete) } } } } -func chatMessageSticker(account: Account, file: TelegramMediaFile) -> Signal<(TransformImageArguments) -> DrawingContext, NoError> { - let signal = chatMessageStickerDatas(account: account, file: file) +func chatMessageSticker(account: Account, file: TelegramMediaFile, small: Bool) -> Signal<(TransformImageArguments) -> DrawingContext, NoError> { + let signal = chatMessageStickerDatas(account: account, file: file, small: small) - return signal |> map { (thumbnailData, fullSizeData, fullTotalSize) in + return signal |> map { (thumbnailData, fullSizeData, fullSizeComplete) in return { arguments in assertNotOnMainThread() + let context = DrawingContext(size: arguments.drawingSize, clear: true) - var fullSizeImage: UIImage? - if let fullSizeData = fullSizeData { - if fullSizeData.count >= fullTotalSize { - if let image = UIImage.convert(fromWebP: fullSizeData) { - fullSizeImage = image - } - } else { + var fullSizeImage: (UIImage, UIImage)? + if let fullSizeData = fullSizeData, fullSizeComplete { + if let image = imageFromAJpeg(data: fullSizeData) { + fullSizeImage = image } } @@ -67,10 +96,13 @@ func chatMessageSticker(account: Account, file: TelegramMediaFile) -> Signal<(Tr c.draw(blurredThumbnailImage.cgImage!, in: arguments.drawingRect) } - if let fullSizeImage = fullSizeImage, let cgImage = fullSizeImage.cgImage { + if let fullSizeImage = fullSizeImage, let cgImage = fullSizeImage.0.cgImage, let cgImageAlpha = fullSizeImage.1.cgImage { c.setBlendMode(.normal) c.interpolationQuality = .medium - c.draw(cgImage, in: arguments.drawingRect) + + let mask = CGImage(maskWidth: cgImageAlpha.width, height: cgImageAlpha.height, bitsPerComponent: cgImageAlpha.bitsPerComponent, bitsPerPixel: cgImageAlpha.bitsPerPixel, bytesPerRow: cgImageAlpha.bytesPerRow, provider: cgImageAlpha.dataProvider!, decode: nil, shouldInterpolate: true) + + c.draw(cgImage.masking(mask!)!, in: arguments.drawingRect) } } diff --git a/TelegramUI/UserInfoEntries.swift b/TelegramUI/UserInfoEntries.swift index e8fd1a7de5..3a4343f7fa 100644 --- a/TelegramUI/UserInfoEntries.swift +++ b/TelegramUI/UserInfoEntries.swift @@ -25,8 +25,13 @@ private enum UserInfoSection: UInt32, PeerInfoSection { } } +enum DestructiveUserInfoAction { + case block + case removeContact +} + enum UserInfoEntry: PeerInfoEntry { - case info(peer: Peer?, cachedData: CachedPeerData?) + case info(peer: Peer?, cachedData: CachedPeerData?, editingState: PeerInfoAvatarAndNameItemEditingState?) case about(text: String) case phoneNumber(index: Int, value: PhoneNumberWithLabel) case userName(value: String) @@ -35,7 +40,8 @@ enum UserInfoEntry: PeerInfoEntry { case startSecretChat case sharedMedia case notifications(settings: PeerNotificationSettings?) - case block + case notificationSound(settings: PeerNotificationSettings?) + case block(action: DestructiveUserInfoAction) var section: PeerInfoSection { switch self { @@ -43,7 +49,7 @@ enum UserInfoEntry: PeerInfoEntry { return UserInfoSection.info case .sendMessage, .shareContact, .startSecretChat: return UserInfoSection.actions - case .sharedMedia, .notifications: + case .sharedMedia, .notifications, .notificationSound: return UserInfoSection.sharedMediaAndNotifications case .block: return UserInfoSection.block @@ -60,9 +66,9 @@ enum UserInfoEntry: PeerInfoEntry { } switch self { - case let .info(lhsPeer, lhsCachedData): + case let .info(lhsPeer, lhsCachedData, lhsEditingState): switch entry { - case let .info(rhsPeer, rhsCachedData): + case let .info(rhsPeer, rhsCachedData, rhsEditingState): if let lhsPeer = lhsPeer, let rhsPeer = rhsPeer { if !lhsPeer.isEqual(rhsPeer) { return false @@ -77,6 +83,9 @@ enum UserInfoEntry: PeerInfoEntry { } else if (lhsCachedData != nil) != (rhsCachedData != nil) { return false } + if lhsEditingState != rhsEditingState { + return false + } return true default: return false @@ -142,9 +151,21 @@ enum UserInfoEntry: PeerInfoEntry { default: return false } - case .block: + case let .notificationSound(lhsSettings): switch entry { - case .block: + case let .notificationSound(rhsSettings): + if let lhsSettings = lhsSettings, let rhsSettings = rhsSettings { + return lhsSettings.isEqual(to: rhsSettings) + } else if (lhsSettings != nil) != (rhsSettings != nil) { + return false + } + return true + default: + return false + } + case let .block(action): + switch entry { + case .block(action): return true default: return false @@ -172,8 +193,10 @@ enum UserInfoEntry: PeerInfoEntry { return 1004 case .notifications: return 1005 - case .block: + case .notificationSound: return 1006 + case .block: + return 1007 } } @@ -187,8 +210,8 @@ enum UserInfoEntry: PeerInfoEntry { func item(account: Account, interaction: PeerInfoControllerInteraction) -> ListViewItem { switch self { - case let .info(peer, cachedData): - return PeerInfoAvatarAndNameItem(account: account, peer: peer, cachedData: cachedData, sectionId: self.section.rawValue, style: .plain) + case let .info(peer, cachedData, editingState): + return PeerInfoAvatarAndNameItem(account: account, peer: peer, cachedData: cachedData, editingState: editingState, sectionId: self.section.rawValue, style: .plain) case let .about(text): return PeerInfoTextWithLabelItem(label: "about", text: text, multiline: true, sectionId: self.section.rawValue) case let .phoneNumber(_, value): @@ -219,65 +242,141 @@ enum UserInfoEntry: PeerInfoEntry { label = "Enabled" } return PeerInfoDisclosureItem(title: "Notifications", label: label, sectionId: self.section.rawValue, style: .plain, action: { - interaction.changeNotificationNoteSettings() + interaction.changeNotificationMuteSettings() }) - case .block: - return PeerInfoActionItem(title: "Block User", kind: .destructive, alignment: .natural, sectionId: self.section.rawValue, style: .plain, action: { + case let .notificationSound(settings): + let label: String + label = "Default" + return PeerInfoDisclosureItem(title: "Sound", label: label, sectionId: self.section.rawValue, style: .plain, action: { + }) + case let .block(action): + let title: String + switch action { + case .block: + title = "Block User" + case .removeContact: + title = "Remove Contact" + } + return PeerInfoActionItem(title: title, kind: .destructive, alignment: .natural, sectionId: self.section.rawValue, style: .plain, action: { }) } } } -final class UserInfoEditingState { +final class UserInfoEditingState: Equatable { + let infoState = PeerInfoAvatarAndNameItemEditingState() + static func ==(lhs: UserInfoEditingState, rhs: UserInfoEditingState) -> Bool { + return true + } } -final class UserInfoState: PeerInfoState { +private final class UserInfoState: PeerInfoState { fileprivate let editingState: UserInfoEditingState? - var navigationButton: PeerInfoNavigationButton { - return self.editingState == nil ? .edit : .done - } - - init() { - self.editingState = nil + init(editingState: UserInfoEditingState?) { + self.editingState = editingState } func isEqual(to: PeerInfoState) -> Bool { if let to = to as? UserInfoState { - return true + return self.editingState == to.editingState } else { return false } } + + func updateEditingState(_ editingState: UserInfoEditingState?) -> UserInfoState { + return UserInfoState(editingState: editingState) + } } -func userInfoEntries(view: PeerView, state: PeerInfoState?) -> [PeerInfoEntry] { +func userInfoEntries(view: PeerView, state: PeerInfoState?) -> PeerInfoEntries { var entries: [PeerInfoEntry] = [] - entries.append(UserInfoEntry.info(peer: view.peers[view.peerId], cachedData: view.cachedData)) + + var infoEditingState: PeerInfoAvatarAndNameItemEditingState? + + var isEditing = false + if let state = state as? UserInfoState, let editingState = state.editingState { + isEditing = true + + if view.peerIsContact { + infoEditingState = editingState.infoState + } + } + + entries.append(UserInfoEntry.info(peer: view.peers[view.peerId], cachedData: view.cachedData, editingState: infoEditingState)) if let cachedUserData = view.cachedData as? CachedUserData { if let about = cachedUserData.about, !about.isEmpty { entries.append(UserInfoEntry.about(text: about)) } } + + var editable = true + if let user = view.peers[view.peerId] as? TelegramUser { if let phoneNumber = user.phone, !phoneNumber.isEmpty { entries.append(UserInfoEntry.phoneNumber(index: 0, value: PhoneNumberWithLabel(label: "home", number: phoneNumber))) } - if let username = user.username, !username.isEmpty { - entries.append(UserInfoEntry.userName(value: username)) - } - if let state = state as? UserInfoState, let editingState = state.editingState { - - } else { + + if !isEditing { + if let username = user.username, !username.isEmpty { + entries.append(UserInfoEntry.userName(value: username)) + } entries.append(UserInfoEntry.sendMessage) - entries.append(UserInfoEntry.shareContact) + if view.peerIsContact { + entries.append(UserInfoEntry.shareContact) + } entries.append(UserInfoEntry.startSecretChat) + entries.append(UserInfoEntry.sharedMedia) } - entries.append(UserInfoEntry.sharedMedia) entries.append(UserInfoEntry.notifications(settings: view.notificationSettings)) - entries.append(UserInfoEntry.block) + + if isEditing { + entries.append(UserInfoEntry.notificationSound(settings: view.notificationSettings)) + if view.peerIsContact { + entries.append(UserInfoEntry.block(action: .removeContact)) + } + } else { + entries.append(UserInfoEntry.block(action: .block)) + } } - return entries + + var leftNavigationButton: PeerInfoNavigationButton? + var rightNavigationButton: PeerInfoNavigationButton? + if editable { + if let state = state as? UserInfoState, let _ = state.editingState { + leftNavigationButton = PeerInfoNavigationButton(title: "Cancel", action: { state in + if state == nil { + return UserInfoState(editingState: nil) + } else if let state = state as? UserInfoState { + return state.updateEditingState(nil) + } else { + return state + } + }) + rightNavigationButton = PeerInfoNavigationButton(title: "Done", action: { state in + if state == nil { + return UserInfoState(editingState: nil) + } else if let state = state as? UserInfoState { + return state.updateEditingState(nil) + } else { + return state + } + }) + } else { + rightNavigationButton = PeerInfoNavigationButton(title: "Edit", action: { state in + if state == nil { + return UserInfoState(editingState: UserInfoEditingState()) + } else if let state = state as? UserInfoState { + return state.updateEditingState(UserInfoEditingState()) + } else { + return state + } + }) + } + } + + return PeerInfoEntries(entries: entries, leftNavigationButton: leftNavigationButton, rightNavigationButton: rightNavigationButton) }