diff --git a/submodules/AttachmentUI/Sources/AttachmentController.swift b/submodules/AttachmentUI/Sources/AttachmentController.swift index 685c651b28..f4efd141cd 100644 --- a/submodules/AttachmentUI/Sources/AttachmentController.swift +++ b/submodules/AttachmentUI/Sources/AttachmentController.swift @@ -691,7 +691,14 @@ public class AttachmentController: ViewController { let insets = layout.insets(options: [.input]) let masterWidth = min(max(320.0, floor(layout.size.width / 3.0)), floor(layout.size.width / 2.0)) - let position: CGPoint = CGPoint(x: masterWidth - 174.0, y: layout.size.height - size.height - insets.bottom - 40.0) + + let position: CGPoint + let positionY = layout.size.height - size.height - insets.bottom - 40.0 + if let sourceRect = controller.getSourceRect?() { + position = CGPoint(x: floor(sourceRect.midX - size.width / 2.0), y: min(positionY, sourceRect.minY - size.height)) + } else { + position = CGPoint(x: masterWidth - 174.0, y: positionY) + } if controller.isStandalone { var containerY = floorToScreenPixels((layout.size.height - size.height) / 2.0) @@ -847,6 +854,8 @@ public class AttachmentController: ViewController { public var getInputContainerNode: () -> (CGFloat, ASDisplayNode, () -> AttachmentController.InputPanelTransition?)? = { return nil } + public var getSourceRect: (() -> CGRect?)? + public init(context: AccountContext, updatedPresentationData: (initial: PresentationData, signal: Signal)? = nil, chatLocation: ChatLocation, buttons: [AttachmentButtonType], initialButton: AttachmentButtonType = .gallery, fromMenu: Bool = false, makeEntityInputView: @escaping () -> AttachmentTextInputPanelInputView?) { self.context = context self.updatedPresentationData = updatedPresentationData diff --git a/submodules/MediaPickerUI/Sources/MediaPickerScreen.swift b/submodules/MediaPickerUI/Sources/MediaPickerScreen.swift index 0a684dc409..aab42c5a27 100644 --- a/submodules/MediaPickerUI/Sources/MediaPickerScreen.swift +++ b/submodules/MediaPickerUI/Sources/MediaPickerScreen.swift @@ -1259,7 +1259,7 @@ public final class MediaPickerScreen: ViewController, AttachmentContainable { if let undoOverlayController = strongSelf.undoOverlayController { undoOverlayController.content = .image(image: image ?? UIImage(), text: text) } else { - let undoOverlayController = UndoOverlayController(presentationData: presentationData, content: .image(image: image ?? UIImage(), text: text), elevatedLayout: true, action: { [weak self] action in + let undoOverlayController = UndoOverlayController(presentationData: presentationData, content: .image(image: image ?? UIImage(), text: text), elevatedLayout: false, action: { [weak self] action in guard let strongSelf = self else { return true } @@ -1271,7 +1271,7 @@ public final class MediaPickerScreen: ViewController, AttachmentContainable { } return true }) - strongSelf.present(undoOverlayController, in: .window(.root)) + strongSelf.present(undoOverlayController, in: .current) strongSelf.undoOverlayController = undoOverlayController } }) diff --git a/submodules/PremiumUI/Sources/PremiumGiftScreen.swift b/submodules/PremiumUI/Sources/PremiumGiftScreen.swift index bb59828aab..4c2d2107d8 100644 --- a/submodules/PremiumUI/Sources/PremiumGiftScreen.swift +++ b/submodules/PremiumUI/Sources/PremiumGiftScreen.swift @@ -1151,7 +1151,7 @@ private final class PremiumGiftScreenComponent: CombinedComponent { ) let bottomPanelAlpha: CGFloat - if let bottomContentOffset = state.bottomContentOffset { + if let bottomContentOffset = state.bottomContentOffset, context.availableSize.width > 320.0 { bottomPanelAlpha = min(16.0, bottomContentOffset) / 16.0 } else { bottomPanelAlpha = 0.0 @@ -1205,45 +1205,47 @@ private final class PremiumGiftScreenComponent: CombinedComponent { let availableWidth = context.availableSize.width let sideInsets = sideInset * 2.0 + environment.safeInsets.left + environment.safeInsets.right - let termsFont = Font.regular(13.0) - let termsTextColor = environment.theme.list.freeTextColor - let termsMarkdownAttributes = MarkdownAttributes(body: MarkdownAttributeSet(font: termsFont, textColor: termsTextColor), bold: MarkdownAttributeSet(font: termsFont, textColor: termsTextColor), link: MarkdownAttributeSet(font: termsFont, textColor: environment.theme.list.itemAccentColor), linkAttribute: { contents in - return (TelegramTextAttributes.URL, contents) - }) - - let termsString: MultilineTextComponent.TextContent = .markdown( - text: environment.strings.Premium_Gift_Info, - attributes: termsMarkdownAttributes - ) - - let termsText = termsText.update( - component: MultilineTextComponent( - text: termsString, - horizontalAlignment: .center, - maximumNumberOfLines: 0, - lineSpacing: 0.0, - highlightColor: environment.theme.list.itemAccentColor.withAlphaComponent(0.3), - highlightAction: { attributes in - if let _ = attributes[NSAttributedString.Key(rawValue: TelegramTextAttributes.URL)] { - return NSAttributedString.Key(rawValue: TelegramTextAttributes.URL) - } else { - return nil + if availableWidth > 320.0 { + let termsFont = Font.regular(13.0) + let termsTextColor = environment.theme.list.freeTextColor + let termsMarkdownAttributes = MarkdownAttributes(body: MarkdownAttributeSet(font: termsFont, textColor: termsTextColor), bold: MarkdownAttributeSet(font: termsFont, textColor: termsTextColor), link: MarkdownAttributeSet(font: termsFont, textColor: environment.theme.list.itemAccentColor), linkAttribute: { contents in + return (TelegramTextAttributes.URL, contents) + }) + + let termsString: MultilineTextComponent.TextContent = .markdown( + text: environment.strings.Premium_Gift_Info, + attributes: termsMarkdownAttributes + ) + + let termsText = termsText.update( + component: MultilineTextComponent( + text: termsString, + horizontalAlignment: .center, + maximumNumberOfLines: 0, + lineSpacing: 0.0, + highlightColor: environment.theme.list.itemAccentColor.withAlphaComponent(0.3), + highlightAction: { attributes in + if let _ = attributes[NSAttributedString.Key(rawValue: TelegramTextAttributes.URL)] { + return NSAttributedString.Key(rawValue: TelegramTextAttributes.URL) + } else { + return nil + } + }, + tapAction: { attributes, _ in + if let _ = attributes[NSAttributedString.Key(rawValue: TelegramTextAttributes.URL)] as? String { + let controller = PremiumIntroScreen(context: accountContext, source: .giftTerms) + present(controller) + } } - }, - tapAction: { attributes, _ in - if let _ = attributes[NSAttributedString.Key(rawValue: TelegramTextAttributes.URL)] as? String { - let controller = PremiumIntroScreen(context: accountContext, source: .giftTerms) - present(controller) - } - } - ), - environment: {}, - availableSize: CGSize(width: availableWidth - sideInsets - textSideInset * 2.0, height: .greatestFiniteMagnitude), - transition: context.transition - ) - context.add(termsText - .position(CGPoint(x: sideInset + environment.safeInsets.left + textSideInset + termsText.size.width / 2.0, y: context.availableSize.height - bottomPanel.size.height - termsText.size.height)) - ) + ), + environment: {}, + availableSize: CGSize(width: availableWidth - sideInsets - textSideInset * 2.0, height: .greatestFiniteMagnitude), + transition: context.transition + ) + context.add(termsText + .position(CGPoint(x: sideInset + environment.safeInsets.left + textSideInset + termsText.size.width / 2.0, y: context.availableSize.height - bottomPanel.size.height - termsText.size.height)) + ) + } } return context.availableSize @@ -1311,12 +1313,19 @@ public final class PremiumGiftScreen: ViewControllerComponentContainer { if let strongSelf = self, let navigationController = strongSelf.navigationController as? NavigationController { var controllers = navigationController.viewControllers controllers = controllers.filter { !($0 is PeerInfoScreen) && !($0 is PremiumGiftScreen) } + var foundController = false for controller in controllers.reversed() { if let chatController = controller as? ChatController, case .peer(id: peerId) = chatController.chatLocation { chatController.hintPlayNextOutgoingGift() + foundController = true break } } + if !foundController { + let chatController = context.sharedContext.makeChatController(context: context, chatLocation: .peer(id: peerId), subject: nil, botStart: nil, mode: .standard(previewing: false)) + chatController.hintPlayNextOutgoingGift() + controllers.append(chatController) + } navigationController.setViewControllers(controllers, animated: true) } } diff --git a/submodules/TabBarUI/Sources/TabBarNode.swift b/submodules/TabBarUI/Sources/TabBarNode.swift index 0cb0a35bf4..6897ab4a11 100644 --- a/submodules/TabBarUI/Sources/TabBarNode.swift +++ b/submodules/TabBarUI/Sources/TabBarNode.swift @@ -646,7 +646,7 @@ class TabBarNode: ASDisplayNode { transition.updateFrame(node: self.backgroundNode, frame: CGRect(origin: CGPoint(), size: size)) self.backgroundNode.update(size: size, transition: transition) - transition.updateFrame(node: self.separatorNode, frame: CGRect(origin: CGPoint(x: 0.0, y: -separatorHeight), size: CGSize(width: size.width, height: separatorHeight))) + transition.updateFrame(node: self.separatorNode, frame: CGRect(origin: CGPoint(x: 0.0, y: 0.0), size: CGSize(width: size.width, height: separatorHeight))) let horizontal = !leftInset.isZero if self.horizontal != horizontal { diff --git a/submodules/TelegramPresentationData/Sources/DefaultDayPresentationTheme.swift b/submodules/TelegramPresentationData/Sources/DefaultDayPresentationTheme.swift index 703c677673..6289309b61 100644 --- a/submodules/TelegramPresentationData/Sources/DefaultDayPresentationTheme.swift +++ b/submodules/TelegramPresentationData/Sources/DefaultDayPresentationTheme.swift @@ -408,7 +408,7 @@ public func makeDefaultDayPresentationTheme(extendingThemeReference: Presentatio let rootTabBar = PresentationThemeRootTabBar( backgroundColor: rootNavigationBar.blurredBackgroundColor, - separatorColor: UIColor(rgb: 0xa3a3a3), + separatorColor: UIColor(rgb: 0xb2b2b2), iconColor: UIColor(rgb: 0x959595), selectedIconColor: defaultDayAccentColor, textColor: UIColor(rgb: 0x959595), diff --git a/submodules/TelegramUI/Sources/ChatController.swift b/submodules/TelegramUI/Sources/ChatController.swift index 50afc6da07..dad88317ee 100644 --- a/submodules/TelegramUI/Sources/ChatController.swift +++ b/submodules/TelegramUI/Sources/ChatController.swift @@ -11210,6 +11210,13 @@ public final class ChatControllerImpl: TelegramBaseController, ChatController, G } return EntityInputView(context: strongSelf.context, isDark: false, isSecret: strongSelf.chatLocation.peerId?.namespace == Namespaces.Peer.SecretChat) }) + attachmentController.getSourceRect = { [weak self] in + if let strongSelf = self { + return strongSelf.chatDisplayNode.frameForAttachmentButton()?.offsetBy(dx: strongSelf.chatDisplayNode.supernode?.frame.minX ?? 0.0, dy: 0.0) + } else { + return nil + } + } attachmentController.requestController = { [weak self, weak attachmentController] type, completion in guard let strongSelf = self else { return diff --git a/submodules/TelegramUI/Sources/ChatControllerNode.swift b/submodules/TelegramUI/Sources/ChatControllerNode.swift index 09fd9c55ea..d494692a58 100644 --- a/submodules/TelegramUI/Sources/ChatControllerNode.swift +++ b/submodules/TelegramUI/Sources/ChatControllerNode.swift @@ -2504,6 +2504,15 @@ class ChatControllerNode: ASDisplayNode, UIScrollViewDelegate { return nil } + func frameForMenuButton() -> CGRect? { + if let textInputPanelNode = self.textInputPanelNode, self.inputPanelNode === textInputPanelNode { + return textInputPanelNode.frameForMenuButton().flatMap { + return $0.offsetBy(dx: textInputPanelNode.frame.minX, dy: textInputPanelNode.frame.minY) + } + } + return nil + } + func frameForStickersButton() -> CGRect? { if let textInputPanelNode = self.textInputPanelNode, self.inputPanelNode === textInputPanelNode { return textInputPanelNode.frameForStickersButton().flatMap { diff --git a/submodules/TelegramUI/Sources/ChatTextInputPanelNode.swift b/submodules/TelegramUI/Sources/ChatTextInputPanelNode.swift index f4a504d8eb..5d50084126 100644 --- a/submodules/TelegramUI/Sources/ChatTextInputPanelNode.swift +++ b/submodules/TelegramUI/Sources/ChatTextInputPanelNode.swift @@ -3148,6 +3148,13 @@ class ChatTextInputPanelNode: ChatInputPanelNode, ASEditableTextNodeDelegate { return nil } + func frameForMenuButton() -> CGRect? { + if !self.menuButton.alpha.isZero { + return self.menuButton.frame + } + return nil + } + func frameForInputActionButton() -> CGRect? { if !self.actionButtons.alpha.isZero { if self.actionButtons.micButton.alpha.isZero { diff --git a/submodules/TelegramUI/Sources/PeerInfo/PeerInfoScreen.swift b/submodules/TelegramUI/Sources/PeerInfo/PeerInfoScreen.swift index 0653983289..a6674e796c 100644 --- a/submodules/TelegramUI/Sources/PeerInfo/PeerInfoScreen.swift +++ b/submodules/TelegramUI/Sources/PeerInfo/PeerInfoScreen.swift @@ -4060,7 +4060,7 @@ final class PeerInfoScreenNode: ViewControllerTracingNode, UIScrollViewDelegate }))) } - if !user.isDeleted && user.botInfo == nil && !user.flags.contains(.isSupport), let cachedData = data.cachedData as? CachedUserData, !cachedData.premiumGiftOptions.isEmpty { + if strongSelf.peerId.namespace == Namespaces.Peer.CloudUser, !user.isDeleted && user.botInfo == nil && !user.flags.contains(.isSupport), let cachedData = data.cachedData as? CachedUserData, !cachedData.premiumGiftOptions.isEmpty { items.append(.action(ContextMenuActionItem(text: presentationData.strings.PeerInfo_GiftPremium, icon: { theme in generateTintedImage(image: UIImage(bundleImageName: "Chat/Context Menu/Gift"), color: theme.contextMenu.primaryColor) }, action: { [weak self] _, f in diff --git a/submodules/WebUI/Sources/WebAppController.swift b/submodules/WebUI/Sources/WebAppController.swift index e939b3a9d5..7777379190 100644 --- a/submodules/WebUI/Sources/WebAppController.swift +++ b/submodules/WebUI/Sources/WebAppController.swift @@ -1273,7 +1273,7 @@ private final class WebAppContextReferenceContentSource: ContextReferenceContent } } -public func standaloneWebAppController(context: AccountContext, updatedPresentationData: (initial: PresentationData, signal: Signal)? = nil, params: WebAppParameters, openUrl: @escaping (String) -> Void, getInputContainerNode: @escaping () -> (CGFloat, ASDisplayNode, () -> AttachmentController.InputPanelTransition?)? = { return nil }, completion: @escaping () -> Void = {}, willDismiss: @escaping () -> Void = {}, didDismiss: @escaping () -> Void = {}, getNavigationController: @escaping () -> NavigationController? = { return nil }) -> ViewController { +public func standaloneWebAppController(context: AccountContext, updatedPresentationData: (initial: PresentationData, signal: Signal)? = nil, params: WebAppParameters, openUrl: @escaping (String) -> Void, getInputContainerNode: @escaping () -> (CGFloat, ASDisplayNode, () -> AttachmentController.InputPanelTransition?)? = { return nil }, completion: @escaping () -> Void = {}, willDismiss: @escaping () -> Void = {}, didDismiss: @escaping () -> Void = {}, getNavigationController: @escaping () -> NavigationController? = { return nil }, getSourceRect: (() -> CGRect?)? = nil) -> ViewController { let controller = AttachmentController(context: context, updatedPresentationData: updatedPresentationData, chatLocation: .peer(id: params.peerId), buttons: [.standalone], initialButton: .standalone, fromMenu: params.fromMenu, makeEntityInputView: { return nil }) @@ -1287,5 +1287,6 @@ public func standaloneWebAppController(context: AccountContext, updatedPresentat } controller.willDismiss = willDismiss controller.didDismiss = didDismiss + controller.getSourceRect = getSourceRect return controller }