diff --git a/submodules/AccountContext/Sources/MediaManager.swift b/submodules/AccountContext/Sources/MediaManager.swift index 19db4f51a4..66c1bbec49 100644 --- a/submodules/AccountContext/Sources/MediaManager.swift +++ b/submodules/AccountContext/Sources/MediaManager.swift @@ -155,6 +155,9 @@ public func peerMessageMediaPlayerType(_ message: EngineMessage) -> MediaManager } else if let media = media as? TelegramMediaWebpage, case let .Loaded(content) = media.content, let f = content.file { file = f break + } else if let media = media as? TelegramMediaPoll, let f = media.attachedMedia as? TelegramMediaFile { + file = f + break } } return file diff --git a/submodules/GalleryData/Sources/GalleryData.swift b/submodules/GalleryData/Sources/GalleryData.swift index 9f95085a15..7c3cc05adc 100644 --- a/submodules/GalleryData/Sources/GalleryData.swift +++ b/submodules/GalleryData/Sources/GalleryData.swift @@ -116,7 +116,7 @@ public func chatMessageGalleryControllerData(context: AccountContext, chatLocati if let poll = media as? TelegramMediaPoll, let attachedMedia = poll.attachedMedia { if attachedMedia is TelegramMediaImage { galleryMedia = attachedMedia - } else if let file = attachedMedia as? TelegramMediaFile, file.isVideo { + } else if let file = attachedMedia as? TelegramMediaFile, file.isVideo || file.isMusic { galleryMedia = attachedMedia } else if attachedMedia is TelegramMediaMap { galleryMedia = attachedMedia diff --git a/submodules/LegacyMediaPickerUI/Sources/LegacyMediaPickers.swift b/submodules/LegacyMediaPickerUI/Sources/LegacyMediaPickers.swift index 92fd8c621f..17ab15a722 100644 --- a/submodules/LegacyMediaPickerUI/Sources/LegacyMediaPickers.swift +++ b/submodules/LegacyMediaPickerUI/Sources/LegacyMediaPickers.swift @@ -409,7 +409,12 @@ public struct LegacyAssetPickerEnqueueMessage { public var isFile: Bool } -public func legacyAssetPickerEnqueueMessages(context: AccountContext, account: Account, signals: [Any], originalMediaReference: AnyMediaReference? = nil) -> Signal<[LegacyAssetPickerEnqueueMessage], Void> { +public func legacyAssetPickerEnqueueMessages( + context: AccountContext, + account: Account, + signals: [Any], + originalMediaReference: AnyMediaReference? = nil +) -> Signal<[LegacyAssetPickerEnqueueMessage], Void> { return Signal { subscriber in let disposable = SSignal.combineSignals(signals).start(next: { anyValues in var messages: [LegacyAssetPickerEnqueueMessage] = [] diff --git a/submodules/MediaPickerUI/Sources/MediaPickerScreen.swift b/submodules/MediaPickerUI/Sources/MediaPickerScreen.swift index 9f465f77a9..d3a3a940fa 100644 --- a/submodules/MediaPickerUI/Sources/MediaPickerScreen.swift +++ b/submodules/MediaPickerUI/Sources/MediaPickerScreen.swift @@ -180,7 +180,7 @@ public final class MediaPickerScreenImpl: ViewController, MediaPickerScreen, Att case cover case createSticker case createAvatar - case poll(PollMode) + case poll(mode: PollMode, asFile: Bool) } case assets(PHAssetCollection?, AssetsMode) @@ -2049,7 +2049,7 @@ public final class MediaPickerScreenImpl: ViewController, MediaPickerScreen, Att self.titleView.title = presentationData.strings.MediaPicker_AddImage case .cover: self.titleView.title = presentationData.strings.MediaPicker_ChooseCover - case let .poll(pollMode): + case let .poll(pollMode, _): self.titleView.title = presentationData.strings.MediaPicker_Recents //TODO:localize switch pollMode { @@ -2088,6 +2088,9 @@ public final class MediaPickerScreenImpl: ViewController, MediaPickerScreen, Att super.init(navigationBarPresentationData: navigationBarPresentationData) + if case .glass = style { + self._hasGlassStyle = true + } self.statusBar.statusBarStyle = .Ignore selectionContext.attemptSelectingItem = { [weak self] item in diff --git a/submodules/TelegramPresentationData/Sources/DefaultDarkPresentationTheme.swift b/submodules/TelegramPresentationData/Sources/DefaultDarkPresentationTheme.swift index 74f97b9b81..ea6339fee6 100644 --- a/submodules/TelegramPresentationData/Sources/DefaultDarkPresentationTheme.swift +++ b/submodules/TelegramPresentationData/Sources/DefaultDarkPresentationTheme.swift @@ -267,7 +267,7 @@ public func customizeDefaultDarkPresentationTheme(theme: PresentationTheme, edit fileTitleColor: outgoingPrimaryTextColor, fileDescriptionColor: outgoingSecondaryTextColor, fileDurationColor: outgoingSecondaryTextColor, - polls: chat.message.outgoing.polls.withUpdated(radioButton: outgoingPrimaryTextColor, radioProgress: outgoingPrimaryTextColor, highlight: outgoingPrimaryTextColor?.withAlphaComponent(0.12), separator: outgoingSecondaryTextColor, bar: outgoingPrimaryTextColor) + polls: chat.message.outgoing.polls.withUpdated(radioButton: outgoingSecondaryTextColor, radioProgress: outgoingPrimaryTextColor, highlight: outgoingPrimaryTextColor?.withAlphaComponent(0.12), separator: outgoingSecondaryTextColor, bar: outgoingPrimaryTextColor) ), freeform: chat.message.freeform.withUpdated( withWallpaper: chat.message.freeform.withWallpaper.withUpdated( @@ -592,8 +592,8 @@ public func makeDefaultDarkPresentationTheme(extendingThemeReference: Presentati reactionInactiveMediaPlaceholder: UIColor(rgb: 0x000000, alpha: 0.1), reactionActiveMediaPlaceholder: UIColor(rgb: 0x000000, alpha: 0.1) ) - ), primaryTextColor: UIColor(rgb: 0xffffff), secondaryTextColor: UIColor(rgb: 0xffffff, alpha: 0.5), linkTextColor: UIColor(rgb: 0xffffff), linkHighlightColor: UIColor(rgb: 0xffffff, alpha: 0.5), scamColor: UIColor(rgb: 0xeb5545), textHighlightColor: UIColor(rgb: 0xf5c038), accentTextColor: UIColor(rgb: 0xffffff), accentControlColor: UIColor(rgb: 0xffffff), accentControlDisabledColor: UIColor(rgb: 0xffffff, alpha: 0.5), mediaActiveControlColor: UIColor(rgb: 0xffffff), mediaInactiveControlColor: UIColor(rgb: 0xffffff, alpha: 0.5), mediaControlInnerBackgroundColor: UIColor(rgb: 0x313131), pendingActivityColor: UIColor(rgb: 0xffffff, alpha: 0.5), fileTitleColor: UIColor(rgb: 0xffffff), fileDescriptionColor: UIColor(rgb: 0xffffff, alpha: 0.5), fileDurationColor: UIColor(rgb: 0xffffff, alpha: 0.5), mediaPlaceholderColor: UIColor(rgb: 0xffffff, alpha: 0.2), polls: PresentationThemeChatBubblePolls(radioButton: UIColor(rgb: 0xffffff), radioProgress: UIColor(rgb: 0xffffff), highlight: UIColor(rgb: 0xffffff).withAlphaComponent(0.12), separator: UIColor(rgb: 0xffffff, alpha: 0.5), bar: UIColor(rgb: 0xffffff), barIconForeground: .clear, barPositive: UIColor(rgb: 0xffffff), barNegative: UIColor(rgb: 0xffffff)), actionButtonsFillColor: PresentationThemeVariableColor(withWallpaper: UIColor(rgb: 0x000000, alpha: 0.5), withoutWallpaper: UIColor(rgb: 0x000000, alpha: 0.5)), actionButtonsStrokeColor: PresentationThemeVariableColor(color: UIColor(rgb: 0xb2b2b2, alpha: 0.18)), actionButtonsTextColor: PresentationThemeVariableColor(color: UIColor(rgb: 0xffffff)), textSelectionColor: UIColor(rgb: 0xffffff, alpha: 0.2), textSelectionKnobColor: UIColor(rgb: 0xffffff) - ), + ), primaryTextColor: UIColor(rgb: 0xffffff), secondaryTextColor: UIColor(rgb: 0xffffff, alpha: 0.5), linkTextColor: UIColor(rgb: 0xffffff), linkHighlightColor: UIColor(rgb: 0xffffff, alpha: 0.5), scamColor: UIColor(rgb: 0xeb5545), textHighlightColor: UIColor(rgb: 0xf5c038), accentTextColor: UIColor(rgb: 0xffffff), accentControlColor: UIColor(rgb: 0xffffff), accentControlDisabledColor: UIColor(rgb: 0xffffff, alpha: 0.5), mediaActiveControlColor: UIColor(rgb: 0xffffff), mediaInactiveControlColor: UIColor(rgb: 0xffffff, alpha: 0.5), mediaControlInnerBackgroundColor: UIColor(rgb: 0x313131), pendingActivityColor: UIColor(rgb: 0xffffff, alpha: 0.5), fileTitleColor: UIColor(rgb: 0xffffff), fileDescriptionColor: UIColor(rgb: 0xffffff, alpha: 0.5), fileDurationColor: UIColor(rgb: 0xffffff, alpha: 0.5), mediaPlaceholderColor: UIColor(rgb: 0xffffff, alpha: 0.2), polls: PresentationThemeChatBubblePolls(radioButton: UIColor(rgb: 0xffffff, alpha: 0.5), radioProgress: UIColor(rgb: 0xffffff), highlight: UIColor(rgb: 0xffffff).withAlphaComponent(0.12), separator: UIColor(rgb: 0xffffff, alpha: 0.5), bar: UIColor(rgb: 0xffffff), barIconForeground: .clear, barPositive: UIColor(rgb: 0xffffff), barNegative: UIColor(rgb: 0xffffff)), actionButtonsFillColor: PresentationThemeVariableColor(withWallpaper: UIColor(rgb: 0x000000, alpha: 0.5), withoutWallpaper: UIColor(rgb: 0x000000, alpha: 0.5)), actionButtonsStrokeColor: PresentationThemeVariableColor(color: UIColor(rgb: 0xb2b2b2, alpha: 0.18)), actionButtonsTextColor: PresentationThemeVariableColor(color: UIColor(rgb: 0xffffff)), textSelectionColor: UIColor(rgb: 0xffffff, alpha: 0.2), textSelectionKnobColor: UIColor(rgb: 0xffffff) + ), freeform: PresentationThemeBubbleColor( withWallpaper: PresentationThemeBubbleColorComponents( fill: [UIColor(rgb: 0x1f1f1f)], diff --git a/submodules/TelegramPresentationData/Sources/Resources/PresentationResourcesItemList.swift b/submodules/TelegramPresentationData/Sources/Resources/PresentationResourcesItemList.swift index 10f7c5d8ad..536d22fc13 100644 --- a/submodules/TelegramPresentationData/Sources/Resources/PresentationResourcesItemList.swift +++ b/submodules/TelegramPresentationData/Sources/Resources/PresentationResourcesItemList.swift @@ -135,7 +135,7 @@ public struct PresentationResourcesItemList { return theme.image(PresentationResourceKey.itemListReorderIndicatorIcon.rawValue, { theme in return generateImage(CGSize(width: 17.0, height: 14.0), rotatedContext: { size, context in context.clear(CGRect(origin: CGPoint(), size: size)) - context.setFillColor(theme.list.itemBlocksSeparatorColor.cgColor) + context.setFillColor(theme.list.itemPlaceholderTextColor.cgColor) let lineHeight = 1.0 + UIScreenPixel context.addPath(CGPath(roundedRect: CGRect(x: 0.0, y: UIScreenPixel, width: 17.0, height: lineHeight), cornerWidth: lineHeight / 2.0, cornerHeight: lineHeight / 2.0, transform: nil)) @@ -150,7 +150,7 @@ public struct PresentationResourcesItemList { return theme.image(PresentationResourceKey.itemListAddIndicatorIcon.rawValue, { theme in return generateImage(CGSize(width: 17.0, height: 15.0), rotatedContext: { size, context in context.clear(CGRect(origin: CGPoint(), size: size)) - context.setFillColor(theme.list.itemBlocksSeparatorColor.cgColor) + context.setFillColor(theme.list.itemPlaceholderTextColor.cgColor) let lineHeight = 1.0 + UIScreenPixel context.addPath(CGPath(roundedRect: CGRect(x: 1.0, y: 7.0, width: 15.0, height: lineHeight), cornerWidth: lineHeight / 2.0, cornerHeight: lineHeight / 2.0, transform: nil)) diff --git a/submodules/TelegramStringFormatting/Sources/MessageContentKind.swift b/submodules/TelegramStringFormatting/Sources/MessageContentKind.swift index ed95f4d6b3..ec8b0a686f 100644 --- a/submodules/TelegramStringFormatting/Sources/MessageContentKind.swift +++ b/submodules/TelegramStringFormatting/Sources/MessageContentKind.swift @@ -9,6 +9,7 @@ import TextFormat public enum MessageContentKindKey { case text case image + case livePhoto case video case videoMessage case audioMessage @@ -36,6 +37,7 @@ public enum MessageContentKindKey { public enum MessageContentKind: Equatable { case text(NSAttributedString) case image + case livePhoto case video case videoMessage case audioMessage @@ -72,6 +74,12 @@ public enum MessageContentKind: Equatable { } else { return false } + case .livePhoto: + if case .livePhoto = other { + return true + } else { + return false + } case .video: if case .video = other { return true @@ -207,6 +215,8 @@ public enum MessageContentKind: Equatable { return .text case .image: return .image + case .livePhoto: + return .livePhoto case .video: return .video case .videoMessage: @@ -316,8 +326,12 @@ public func mediaContentKind(_ media: EngineMedia, message: EngineMessage? = nil case .videoMessage: return .expiredVideoMessage } - case .image: - return .image + case let .image(image): + if let _ = image.video { + return .livePhoto + } else { + return .image + } case let .file(file): var fileName: String = "" @@ -429,6 +443,9 @@ public func stringForMediaKind(_ kind: MessageContentKind, strings: Presentation return (foldLineBreaks(text), false) case .image: return (NSAttributedString(string: strings.Message_Photo), true) + case .livePhoto: + //TODO:localize + return (NSAttributedString(string: "Live Photo"), true) case .video: return (NSAttributedString(string: strings.Message_Video), true) case .videoMessage: diff --git a/submodules/TelegramUI/Components/Chat/ChatMessageAttachedContentNode/Sources/ChatMessageAttachedContentNode.swift b/submodules/TelegramUI/Components/Chat/ChatMessageAttachedContentNode/Sources/ChatMessageAttachedContentNode.swift index b7105892d9..4cb3db577c 100644 --- a/submodules/TelegramUI/Components/Chat/ChatMessageAttachedContentNode/Sources/ChatMessageAttachedContentNode.swift +++ b/submodules/TelegramUI/Components/Chat/ChatMessageAttachedContentNode/Sources/ChatMessageAttachedContentNode.swift @@ -105,7 +105,6 @@ public final class ChatMessageAttachedContentNode: ASDisplayNode { private var inlineMediaValue: InlineMedia? - //private var additionalImageBadgeNode: ChatMessageInteractiveMediaBadge? private var linkHighlightingNode: LinkHighlightingNode? private var context: AccountContext? @@ -1558,7 +1557,9 @@ public final class ChatMessageAttachedContentNode: ASDisplayNode { if displayLine { var pattern: MessageInlineBlockBackgroundView.Pattern? - if let backgroundEmojiId = author?.backgroundEmojiId { + if let _ = message.media.first(where: { $0 is TelegramMediaPoll }) { + + } else if let backgroundEmojiId = author?.backgroundEmojiId { pattern = MessageInlineBlockBackgroundView.Pattern( context: context, fileId: backgroundEmojiId, diff --git a/submodules/TelegramUI/Components/Chat/ChatMessagePollBubbleContentNode/Sources/ChatMessagePollBubbleContentNode.swift b/submodules/TelegramUI/Components/Chat/ChatMessagePollBubbleContentNode/Sources/ChatMessagePollBubbleContentNode.swift index cd3a777d1b..3b78db8d2f 100644 --- a/submodules/TelegramUI/Components/Chat/ChatMessagePollBubbleContentNode/Sources/ChatMessagePollBubbleContentNode.swift +++ b/submodules/TelegramUI/Components/Chat/ChatMessagePollBubbleContentNode/Sources/ChatMessagePollBubbleContentNode.swift @@ -495,6 +495,7 @@ private final class ChatMessagePollOptionNode: ASDisplayNode { private(set) var currentSelection: ChatMessagePollOptionSelection? var pressed: (() -> Void)? var selectionUpdated: (() -> Void)? + var resultPressed: (() -> Void)? var longTapped: (() -> Void)? var context: AccountContext? var message: Message? @@ -728,7 +729,12 @@ private final class ChatMessagePollOptionNode: ASDisplayNode { return } - guard self.forceSelected == nil && self.currentResult == nil else { + guard self.forceSelected == nil else { + return + } + + if let _ = self.currentResult { + self.resultPressed?() return } @@ -1018,7 +1024,15 @@ private final class ChatMessagePollOptionNode: ASDisplayNode { } let radioSize: CGFloat = 22.0 radioNode.frame = CGRect(origin: CGPoint(x: 12.0, y: 15.0), size: CGSize(width: radioSize, height: radioSize)) - radioNode.update(isRectangle: poll.kind.multipleAnswers, staticColor: incoming ? presentationData.theme.theme.chat.message.incoming.polls.radioButton : presentationData.theme.theme.chat.message.outgoing.polls.radioButton, animatedColor: incoming ? presentationData.theme.theme.chat.message.incoming.polls.radioProgress : presentationData.theme.theme.chat.message.outgoing.polls.radioProgress, fillColor: incoming ? presentationData.theme.theme.chat.message.incoming.polls.bar : presentationData.theme.theme.chat.message.outgoing.polls.bar, foregroundColor: incoming ? presentationData.theme.theme.chat.message.incoming.polls.barIconForeground : presentationData.theme.theme.chat.message.outgoing.polls.barIconForeground, isSelectable: isSelectable || forceSelected != nil, isAnimating: inProgress) + radioNode.update( + isRectangle: poll.kind.multipleAnswers, + staticColor: incoming ? presentationData.theme.theme.chat.message.incoming.polls.radioButton : presentationData.theme.theme.chat.message.outgoing.polls.radioButton, + animatedColor: incoming ? presentationData.theme.theme.chat.message.incoming.polls.radioProgress : presentationData.theme.theme.chat.message.outgoing.polls.radioProgress, + fillColor: incoming ? presentationData.theme.theme.chat.message.incoming.polls.bar : presentationData.theme.theme.chat.message.outgoing.polls.bar, + foregroundColor: incoming ? presentationData.theme.theme.chat.message.incoming.polls.barIconForeground : presentationData.theme.theme.chat.message.outgoing.polls.barIconForeground, + isSelectable: isSelectable || forceSelected != nil, + isAnimating: inProgress + ) if let forceSelected { radioNode.updateIsChecked(forceSelected, animated: false) @@ -2214,7 +2228,7 @@ public class ChatMessagePollBubbleContentNode: ChatMessageBubbleContentNode { updatedPresentationData: item.controllerInteraction.updatedPresentationData, subject: .option, availableButtons: [.gallery, .sticker, .location], - present: { [weak item] controller in + present: { [weak item] controller, _ in item?.controllerInteraction.navigationController()?.pushViewController(controller) }, completion: { [weak self] media in @@ -2877,12 +2891,19 @@ public class ChatMessagePollBubbleContentNode: ChatMessageBubbleContentNode { if optionNode.supernode !== strongSelf { strongSelf.addSubnode(optionNode) let option = optionNode.option + optionNode.pressed = { [weak self] in guard let self, let item = self.item, let option else { return } item.controllerInteraction.requestSelectMessagePollOptions(item.message.id, [option.opaqueIdentifier]) } + optionNode.resultPressed = { [weak self] in + guard let self, let item = self.item, let option else { + return + } + item.controllerInteraction.openMessagePollResults(item.message.id, option.opaqueIdentifier) + } optionNode.selectionUpdated = { [weak self] in guard let self else { return @@ -3195,15 +3216,7 @@ public class ChatMessagePollBubbleContentNode: ChatMessageBubbleContentNode { strongSelf.updateSelection() strongSelf.updatePollTooltipMessageState(animated: false) - var buttonWidth: CGFloat = 0.0 - if !strongSelf.buttonSaveTextNode.isHidden { - buttonWidth = strongSelf.buttonSaveTextNode.frame.width - } else if !strongSelf.buttonViewResultsTextNode.isHidden { - buttonWidth = strongSelf.buttonViewResultsTextNode.frame.width - } else if !strongSelf.buttonSubmitActiveTextNode.isHidden || !strongSelf.buttonSubmitInactiveTextNode.isHidden { - buttonWidth = max(strongSelf.buttonSubmitActiveTextNode.frame.width, strongSelf.buttonSubmitInactiveTextNode.frame.width) - } - buttonWidth = floor(buttonWidth * 1.1) + let buttonWidth: CGFloat = floor(max(strongSelf.buttonSaveTextNode.frame.width, max(strongSelf.buttonViewResultsTextNode.frame.width, strongSelf.buttonSubmitActiveTextNode.frame.width)) * 1.1) strongSelf.buttonNode.frame = CGRect(origin: CGPoint(x: floor((resultSize.width - buttonWidth) / 2.0), y: verticalOffset), size: CGSize(width: buttonWidth, height: 44.0)) strongSelf.updateIsTranslating(isTranslating) diff --git a/submodules/TelegramUI/Components/ComposePollScreen/BUILD b/submodules/TelegramUI/Components/ComposePollScreen/BUILD index 1c20d269cf..358b7890a4 100644 --- a/submodules/TelegramUI/Components/ComposePollScreen/BUILD +++ b/submodules/TelegramUI/Components/ComposePollScreen/BUILD @@ -59,6 +59,7 @@ swift_library( "//submodules/StickerPeekUI", "//submodules/CounterControllerTitleView", "//submodules/TelegramUI/Components/EdgeEffect", + "//submodules/ICloudResources", ], visibility = [ "//visibility:public", diff --git a/submodules/TelegramUI/Components/ComposePollScreen/Sources/ComposePollScreen.swift b/submodules/TelegramUI/Components/ComposePollScreen/Sources/ComposePollScreen.swift index 27f028ad3a..c55c56f87a 100644 --- a/submodules/TelegramUI/Components/ComposePollScreen/Sources/ComposePollScreen.swift +++ b/submodules/TelegramUI/Components/ComposePollScreen/Sources/ComposePollScreen.swift @@ -879,8 +879,15 @@ final class ComposePollScreenComponent: Component { subject: pollAttachmentSubject, availableButtons: availableButtons, inputMediaNodeData: self.inputMediaNodeDataPromise.get() |> map(Optional.init), - present: { [weak self] c in - (self?.environment?.controller() as? ComposePollScreen)?.parentController()?.push(c) + present: { [weak self] c, push in + guard let parentController = (self?.environment?.controller() as? ComposePollScreen)?.parentController() else { + return + } + if push { + parentController.push(c) + } else { + parentController.present(c, in: .window(.root)) + } }, completion: { [weak self] media in guard let self else { diff --git a/submodules/TelegramUI/Components/ComposePollScreen/Sources/PollAttachmentScreen.swift b/submodules/TelegramUI/Components/ComposePollScreen/Sources/PollAttachmentScreen.swift index 4e634d15ab..901afc8961 100644 --- a/submodules/TelegramUI/Components/ComposePollScreen/Sources/PollAttachmentScreen.swift +++ b/submodules/TelegramUI/Components/ComposePollScreen/Sources/PollAttachmentScreen.swift @@ -15,6 +15,7 @@ import LegacyMediaPickerUI import LocationUI import AttachmentFileController import ChatEntityKeyboardInputNode +import ICloudResources public enum PollAttachmentSubject { case description @@ -28,7 +29,7 @@ public func presentPollAttachmentScreen( subject: PollAttachmentSubject, availableButtons: [AttachmentButtonType], inputMediaNodeData: Signal = .single(nil), - present: @escaping (ViewController) -> Void, + present: @escaping (ViewController, Bool) -> Void, completion: @escaping (AnyMediaReference) -> Void ) { let attachmentController = AttachmentController( @@ -44,17 +45,30 @@ public func presentPollAttachmentScreen( } ) attachmentController.requestController = { [weak attachmentController] type, controllerCompletion in + let mediaPickerPollSubject: MediaPickerScreenImpl.Subject.AssetsMode.PollMode + let filePickerPollSubject: AttachmentFileControllerSource.PollMode + let locationPickerPollSubject: LocationPickerController.Source.PollMode + let stickerPickerPollSubject: StickerAttachmentScreen.Source.PollMode + switch subject { + case .description: + mediaPickerPollSubject = .description + filePickerPollSubject = .description + locationPickerPollSubject = .description + stickerPickerPollSubject = .description + case .quizAnswer: + mediaPickerPollSubject = .quizAnswer + filePickerPollSubject = .quizAnswer + locationPickerPollSubject = .quizAnswer + stickerPickerPollSubject = .quizAnswer + default: + mediaPickerPollSubject = .option + filePickerPollSubject = .description + locationPickerPollSubject = .option + stickerPickerPollSubject = .option + } + switch type { case .gallery: - let mediaPickerPollSubject: MediaPickerScreenImpl.Subject.AssetsMode.PollMode - switch subject { - case .description: - mediaPickerPollSubject = .description - case .quizAnswer: - mediaPickerPollSubject = .quizAnswer - case .option: - mediaPickerPollSubject = .option - } let controller = MediaPickerScreenImpl( context: context, updatedPresentationData: updatedPresentationData, @@ -63,12 +77,12 @@ public func presentPollAttachmentScreen( threadTitle: nil, chatLocation: nil, enableMultiselection: false, - subject: .assets(nil, .poll(mediaPickerPollSubject)) + subject: .assets(nil, .poll(mode: mediaPickerPollSubject, asFile: false)) ) controller.getCaptionPanelView = { return nil } - controller.legacyCompletion = { fromGallery, signals, silently, scheduleTime, parameters, getAnimatedTransitionSource, sendCompletion in + controller.legacyCompletion = { _, signals, _, _, _, _, sendCompletion in let _ = (legacyAssetPickerEnqueueMessages(context: context, account: context.account, signals: signals) |> deliverOnMainQueue).start(next: { items in if let item = items.first, case let .message(_, _, _, mediaReference, _, _, _, _, _, _) = item.message, let mediaReference { @@ -80,24 +94,69 @@ public func presentPollAttachmentScreen( controllerCompletion(controller, controller.mediaPickerContext) return true case .file: - let filePickerPollSubject: AttachmentFileControllerSource.PollMode - switch subject { - case .description: - filePickerPollSubject = .description - case .quizAnswer: - filePickerPollSubject = .quizAnswer - default: - filePickerPollSubject = .description - } let controller = makeAttachmentFileControllerImpl( context: context, updatedPresentationData: updatedPresentationData, source: .poll(filePickerPollSubject), bannedSendMedia: nil, - presentGallery: {}, + presentGallery: { [weak attachmentController] in + attachmentController?.dismiss(animated: true) + + let controller = MediaPickerScreenImpl( + context: context, + updatedPresentationData: updatedPresentationData, + style: .glass, + peer: nil, + threadTitle: nil, + chatLocation: nil, + enableMultiselection: false, + subject: .assets(nil, .poll(mode: mediaPickerPollSubject, asFile: true)) + ) + controller.getCaptionPanelView = { + return nil + } + controller.legacyCompletion = { _, signals, _, _, _, _, sendCompletion in + let _ = (legacyAssetPickerEnqueueMessages(context: context, account: context.account, signals: signals) + |> deliverOnMainQueue).start(next: { items in + if let item = items.first, case let .message(_, _, _, mediaReference, _, _, _, _, _, _) = item.message, let mediaReference { + completion(mediaReference) + sendCompletion() + } + }) + } + controller.navigationPresentation = .modal + present(controller, true) + }, presentFiles: { [weak attachmentController] in attachmentController?.dismiss(animated: true) - //TODO + + let presentationData = updatedPresentationData?.initial ?? context.sharedContext.currentPresentationData.with { $0 } + let controller = legacyICloudFilePicker(theme: presentationData.theme, mode: .import, documentTypes: ["public.item"], completion: { urls in + guard let url = urls.first else { + return + } + let _ = (iCloudFileDescription(url) + |> deliverOnMainQueue).start(next: { item in + guard let item else { + return + } + let fileId = Int64.random(in: Int64.min ... Int64.max) + let mimeType = guessMimeTypeByFileExtension((item.fileName as NSString).pathExtension) + var previewRepresentations: [TelegramMediaImageRepresentation] = [] + if mimeType.hasPrefix("image/") || mimeType == "application/pdf" { + previewRepresentations.append(TelegramMediaImageRepresentation(dimensions: PixelDimensions(width: 320, height: 320), resource: ICloudFileResource(urlData: item.urlData, thumbnail: true), progressiveSizes: [], immediateThumbnailData: nil, hasVideo: false, isPersonal: false)) + } + var attributes: [TelegramMediaFileAttribute] = [] + attributes.append(.FileName(fileName: item.fileName)) + if let audioMetadata = item.audioMetadata { + attributes.append(.Audio(isVoice: false, duration: audioMetadata.duration, title: audioMetadata.title, performer: audioMetadata.performer, waveform: nil)) + } + + let file = TelegramMediaFile(fileId: MediaId(namespace: Namespaces.Media.LocalFile, id: fileId), partialReference: nil, resource: ICloudFileResource(urlData: item.urlData, thumbnail: false), previewRepresentations: previewRepresentations, videoThumbnails: [], immediateThumbnailData: nil, mimeType: mimeType, size: Int64(item.fileSize), attributes: attributes, alternativeRepresentations: []) + completion(.standalone(media: file)) + }) + }) + present(controller, false) }, presentDocumentScanner: nil, send: { mediaReferences, _, _, _ in @@ -107,15 +166,6 @@ public func presentPollAttachmentScreen( controllerCompletion(controller, controller.mediaPickerContext) return true case .location: - let locationPickerPollSubject: LocationPickerController.Source.PollMode - switch subject { - case .description: - locationPickerPollSubject = .description - case .quizAnswer: - locationPickerPollSubject = .quizAnswer - case .option: - locationPickerPollSubject = .option - } let controller = LocationPickerController( context: context, style: .glass, @@ -134,15 +184,6 @@ public func presentPollAttachmentScreen( guard let content = content?.stickers else { return } - let stickerPickerPollSubject: StickerAttachmentScreen.Source.PollMode - switch subject { - case .description: - stickerPickerPollSubject = .description - case .quizAnswer: - stickerPickerPollSubject = .quizAnswer - case .option: - stickerPickerPollSubject = .option - } let controller = StickerAttachmentScreen( context: context, mode: .stickers(content), @@ -161,15 +202,6 @@ public func presentPollAttachmentScreen( guard let content = content?.emoji else { return } - let stickerPickerPollSubject: StickerAttachmentScreen.Source.PollMode - switch subject { - case .description: - stickerPickerPollSubject = .description - case .quizAnswer: - stickerPickerPollSubject = .quizAnswer - case .option: - stickerPickerPollSubject = .option - } let controller = StickerAttachmentScreen( context: context, mode: .emoji(content), @@ -186,5 +218,5 @@ public func presentPollAttachmentScreen( } } attachmentController.navigationPresentation = .flatModal - present(attachmentController) + present(attachmentController, true) } diff --git a/submodules/TelegramUI/Components/ContextControllerImpl/Sources/ContextSourceContainer.swift b/submodules/TelegramUI/Components/ContextControllerImpl/Sources/ContextSourceContainer.swift index eb911f2e52..abc64e9efa 100644 --- a/submodules/TelegramUI/Components/ContextControllerImpl/Sources/ContextSourceContainer.swift +++ b/submodules/TelegramUI/Components/ContextControllerImpl/Sources/ContextSourceContainer.swift @@ -615,6 +615,13 @@ final class ContextSourceContainer: ASDisplayNode { self.presentationData = presentationData self.validLayout = layout + var layout = layout + if self.sources.count > 1 { + var intrinsicInsets = layout.intrinsicInsets + intrinsicInsets.bottom += 30.0 + layout = layout.withUpdatedIntrinsicInsets(intrinsicInsets) + } + var childLayout = layout if let activeSource = self.activeSource { diff --git a/submodules/TelegramUI/Components/ListActionItemComponent/Sources/ListActionItemComponent.swift b/submodules/TelegramUI/Components/ListActionItemComponent/Sources/ListActionItemComponent.swift index f9ef531350..4f59d47b78 100644 --- a/submodules/TelegramUI/Components/ListActionItemComponent/Sources/ListActionItemComponent.swift +++ b/submodules/TelegramUI/Components/ListActionItemComponent/Sources/ListActionItemComponent.swift @@ -774,7 +774,7 @@ public final class ListActionItemComponent: Component { if case let .toggle(toggle) = component.accessory { switch toggle.style { - case .regular: + case .regular, .lock: let switchNode: SwitchNode var switchTransition = transition var updateSwitchTheme = themeUpdated @@ -827,7 +827,7 @@ public final class ListActionItemComponent: Component { } let switchFrame = CGRect(origin: CGPoint(x: availableSize.width - 16.0 - switchSize.width, y: switchY), size: switchSize) switchTransition.setFrame(view: switchNode.view, frame: switchFrame) - case .icons, .lock: + case .icons: let switchNode: IconSwitchNode var switchTransition = transition var updateSwitchTheme = themeUpdated diff --git a/submodules/TelegramUI/Components/ListComposePollOptionComponent/Sources/ListComposePollOptionComponent.swift b/submodules/TelegramUI/Components/ListComposePollOptionComponent/Sources/ListComposePollOptionComponent.swift index 32c79512f0..6eb9b9cf08 100644 --- a/submodules/TelegramUI/Components/ListComposePollOptionComponent/Sources/ListComposePollOptionComponent.swift +++ b/submodules/TelegramUI/Components/ListComposePollOptionComponent/Sources/ListComposePollOptionComponent.swift @@ -1065,15 +1065,15 @@ public final class ListComposePollOptionComponent: Component { if let dimensions = file.dimensions { imageSize = dimensions.cgSize.aspectFilled(imageNodeSize) } - if file.mimeType.hasPrefix("image/") { - if updateMedia { - imageNode.setSignal(instantPageImageFile(account: component.context.account, userLocation: .other, fileReference: fileReference, fetched: true)) - } - } else if file.isVideo { + if file.isVideo { if updateMedia { imageNode.setSignal(chatMessageVideo(postbox: component.context.account.postbox, userLocation: .other, videoReference: fileReference)) } isVideo = true + } else if file.mimeType.hasPrefix("image/") || !file.previewRepresentations.isEmpty { + if updateMedia { + imageNode.setSignal(chatMessageImageFile(account: component.context.account, userLocation: .other, fileReference: fileReference, thumbnail: true)) + } } else { let fileName: String = file.fileName ?? "File" var fileExtension: String? diff --git a/submodules/TelegramUI/Components/MediaManager/PeerMessagesMediaPlaylist/Sources/PeerMessagesMediaPlaylist.swift b/submodules/TelegramUI/Components/MediaManager/PeerMessagesMediaPlaylist/Sources/PeerMessagesMediaPlaylist.swift index 3f974eb788..00da2e081c 100644 --- a/submodules/TelegramUI/Components/MediaManager/PeerMessagesMediaPlaylist/Sources/PeerMessagesMediaPlaylist.swift +++ b/submodules/TelegramUI/Components/MediaManager/PeerMessagesMediaPlaylist/Sources/PeerMessagesMediaPlaylist.swift @@ -42,6 +42,9 @@ private func extractFileMedia(_ message: Message) -> TelegramMediaFile? { } else if let media = media as? TelegramMediaWebpage, case let .Loaded(content) = media.content, let f = content.file { file = f break + } else if let media = media as? TelegramMediaPoll, let f = media.attachedMedia as? TelegramMediaFile { + file = f + break } } return file diff --git a/submodules/TelegramUI/Sources/Chat/ChatControllerOpenPollOptionMedia.swift b/submodules/TelegramUI/Sources/Chat/ChatControllerOpenPollOptionMedia.swift index f2570c4f4c..936100d422 100644 --- a/submodules/TelegramUI/Sources/Chat/ChatControllerOpenPollOptionMedia.swift +++ b/submodules/TelegramUI/Sources/Chat/ChatControllerOpenPollOptionMedia.swift @@ -147,23 +147,23 @@ extension ChatControllerImpl { } }, transitionNode: { [weak self] messageId, media, adjustRect in - guard let self else { - return nil + var selectedNode: (ASDisplayNode, CGRect, () -> (UIView?, UIView?))? + if let self { + self.chatDisplayNode.historyNode.forEachItemNode { itemNode in + if let itemNode = itemNode as? ChatMessageItemView { + if let result = itemNode.transitionNode(id: messageId, media: media, adjustRect: adjustRect) { + selectedNode = result + } + } + } } - let _ = self - return nil - //return self.transitionNode(messageId: messageId, media: media, adjustRect: adjustRect) + return selectedNode }, addToTransitionSurface: { [weak self] view in guard let self else { return } - let _ = self -// if let superview = self.itemNode?.view.superview?.superview?.superview { -// superview.addSubview(view) -// } else { -// self.view.addSubview(view) -// } + self.chatDisplayNode.historyNode.view.superview?.insertSubview(view, aboveSubview: self.chatDisplayNode.historyNode.view) }, openUrl: { [weak self] url in guard let self else { @@ -203,24 +203,7 @@ extension ChatControllerImpl { } self.controllerInteraction?.sendEmoji(text, attribute, false) }, - setupTemporaryHiddenMedia: { [weak self] signal, _, galleryMedia in - guard let self else { - return - } - let _ = self -// self.temporaryHiddenMediaDisposable.set((signal |> deliverOnMainQueue).startStrict(next: { [weak self] entry in -// guard let self, let item = self.item else { -// return -// } -// var hiddenMedia = item.controllerInteraction.hiddenMedia -// if entry != nil { -// hiddenMedia[item.message.id] = [galleryMedia] -// } else { -// hiddenMedia.removeValue(forKey: item.message.id) -// } -// item.controllerInteraction.hiddenMedia = hiddenMedia -// self.itemNode?.updateHiddenMedia() -// })) + setupTemporaryHiddenMedia: { _, _, _ in }, chatAvatarHiddenMedia: { _, _ in },