diff --git a/Telegram/Telegram-iOS/en.lproj/Localizable.strings b/Telegram/Telegram-iOS/en.lproj/Localizable.strings index 8589e388c9a..b077464c25b 100644 --- a/Telegram/Telegram-iOS/en.lproj/Localizable.strings +++ b/Telegram/Telegram-iOS/en.lproj/Localizable.strings @@ -11336,12 +11336,10 @@ Sorry for the inconvenience."; "Premium.Business.Location.Text" = "Display the location of your business on your account."; "Premium.Business.Hours.Title" = "Opening Hours"; -"Premium.Business.Hours.Text" = "Show to your customers when you are -open for business."; +"Premium.Business.Hours.Text" = "Show to your customers when you are open for business."; "Premium.Business.Replies.Title" = "Quick Replies"; -"Premium.Business.Replies.Text" = "Set up shortcuts with rich text and media -to respond to messages faster."; +"Premium.Business.Replies.Text" = "Set up shortcuts with rich text and media to respond to messages faster."; "Premium.Business.Greetings.Title" = "Greeting Messages"; "Premium.Business.Greetings.Text" = "Create greetings that will be automatically sent to new customers."; diff --git a/submodules/ChatSendMessageActionUI/Sources/ChatSendMessageActionSheetControllerNode.swift b/submodules/ChatSendMessageActionUI/Sources/ChatSendMessageActionSheetControllerNode.swift index ac9a4cb3cbe..93563c76f30 100644 --- a/submodules/ChatSendMessageActionUI/Sources/ChatSendMessageActionSheetControllerNode.swift +++ b/submodules/ChatSendMessageActionUI/Sources/ChatSendMessageActionSheetControllerNode.swift @@ -519,7 +519,7 @@ final class ChatSendMessageActionSheetControllerNode: ViewControllerTracingNode, } var clipDelta = delta - if inputHeight.isZero || layout.isNonExclusive { + if inputHeight < 70.0 || layout.isNonExclusive { clipDelta -= self.contentContainerNode.frame.height + 16.0 } @@ -642,7 +642,7 @@ final class ChatSendMessageActionSheetControllerNode: ViewControllerTracingNode, } var clipDelta = delta - if inputHeight.isZero || layout.isNonExclusive { + if inputHeight < 70.0 || layout.isNonExclusive { clipDelta -= self.contentContainerNode.frame.height + 16.0 } @@ -714,7 +714,7 @@ final class ChatSendMessageActionSheetControllerNode: ViewControllerTracingNode, } else { contentOrigin = CGPoint(x: layout.size.width - sideInset - contentSize.width - layout.safeInsets.right, y: layout.size.height - 6.0 - insets.bottom - contentSize.height) } - if inputHeight > 0.0 && !layout.isNonExclusive && self.animateInputField { + if inputHeight > 70.0 && !layout.isNonExclusive && self.animateInputField { contentOrigin.y += menuHeightWithInset } contentOrigin.y = min(contentOrigin.y + contentOffset, layout.size.height - 6.0 - layout.intrinsicInsets.bottom - contentSize.height) @@ -728,7 +728,7 @@ final class ChatSendMessageActionSheetControllerNode: ViewControllerTracingNode, } var sendButtonFrame = CGRect(origin: CGPoint(x: layout.size.width - initialSendButtonFrame.width + 1.0 - UIScreenPixel - layout.safeInsets.right, y: layout.size.height - insets.bottom - initialSendButtonFrame.height), size: initialSendButtonFrame.size) - if (inputHeight.isZero || layout.isNonExclusive) && self.animateInputField { + if (inputHeight < 70.0 || layout.isNonExclusive) && self.animateInputField { sendButtonFrame.origin.y -= menuHeightWithInset } sendButtonFrame.origin.y = min(sendButtonFrame.origin.y + contentOffset, layout.size.height - layout.intrinsicInsets.bottom - initialSendButtonFrame.height) @@ -741,7 +741,7 @@ final class ChatSendMessageActionSheetControllerNode: ViewControllerTracingNode, let messageHeightAddition: CGFloat = max(0.0, 35.0 - messageFrame.size.height) - if inputHeight.isZero || layout.isNonExclusive { + if inputHeight < 70.0 || layout.isNonExclusive { messageFrame.origin.y += menuHeightWithInset } diff --git a/submodules/Display/Source/WindowContent.swift b/submodules/Display/Source/WindowContent.swift index bb30709aa8d..e1bbea3b179 100644 --- a/submodules/Display/Source/WindowContent.swift +++ b/submodules/Display/Source/WindowContent.swift @@ -243,7 +243,6 @@ public final class WindowKeyboardGestureRecognizerDelegate: NSObject, UIGestureR public class Window1 { public let hostView: WindowHostView public let badgeView: UIImageView - private let customProximityDimView: UIView private var deviceMetrics: DeviceMetrics @@ -331,10 +330,6 @@ public class Window1 { self.badgeView.image = UIImage(bundleImageName: "Components/AppBadge") self.badgeView.isHidden = true - self.customProximityDimView = UIView() - self.customProximityDimView.backgroundColor = .black - self.customProximityDimView.isHidden = true - self.systemUserInterfaceStyle = hostView.systemUserInterfaceStyle let boundsSize = self.hostView.eventView.bounds.size @@ -673,7 +668,6 @@ public class Window1 { self.windowPanRecognizer = recognizer self.hostView.containerView.addGestureRecognizer(recognizer) self.hostView.containerView.addSubview(self.badgeView) - self.hostView.containerView.addSubview(self.customProximityDimView) } public required init(coder aDecoder: NSCoder) { @@ -707,11 +701,18 @@ public class Window1 { self.updateBadgeVisibility() } + private var proximityDimController: CustomDimController? public func setProximityDimHidden(_ hidden: Bool) { - guard hidden != self.customProximityDimView.isHidden else { - return + if !hidden { + if self.proximityDimController == nil { + let proximityDimController = CustomDimController(navigationBarPresentationData: nil) + self.proximityDimController = proximityDimController + (self.viewController as? NavigationController)?.presentOverlay(controller: proximityDimController, inGlobal: true, blockInteraction: false) + } + } else if let proximityDimController = self.proximityDimController { + self.proximityDimController = nil + proximityDimController.dismiss() } - self.customProximityDimView.isHidden = hidden } private func updateBadgeVisibility() { @@ -1170,8 +1171,6 @@ public class Window1 { self.updateBadgeVisibility() self.badgeView.frame = CGRect(origin: CGPoint(x: floorToScreenPixels((self.windowLayout.size.width - image.size.width) / 2.0), y: 5.0), size: image.size) } - - self.customProximityDimView.frame = CGRect(origin: .zero, size: self.windowLayout.size) } } } @@ -1383,3 +1382,25 @@ public class Window1 { } } } + +private class CustomDimController: ViewController { + class Node: ASDisplayNode { + override init() { + super.init() + + self.backgroundColor = .black + } + } + override init(navigationBarPresentationData: NavigationBarPresentationData?) { + super.init(navigationBarPresentationData: nil) + } + + required public init(coder aDecoder: NSCoder) { + fatalError("init(coder:) has not been implemented") + } + + override func loadDisplayNode() { + let node = Node() + self.displayNode = node + } +} diff --git a/submodules/PremiumUI/Sources/BusinessPageComponent.swift b/submodules/PremiumUI/Sources/BusinessPageComponent.swift index 8740f125dba..4a1be46cf05 100644 --- a/submodules/PremiumUI/Sources/BusinessPageComponent.swift +++ b/submodules/PremiumUI/Sources/BusinessPageComponent.swift @@ -70,7 +70,7 @@ private final class HeaderComponent: Component { transition: .immediate, component: AnyComponent( MultilineTextComponent( - text: .plain(NSAttributedString(string: component.strings.Premium_Business_Description, font: Font.regular(15.0), textColor: .black)), + text: .plain(NSAttributedString(string: component.strings.Premium_Business_Description, font: Font.regular(15.0), textColor: component.theme.list.itemPrimaryTextColor)), horizontalAlignment: .center, maximumNumberOfLines: 0, lineSpacing: 0.2 diff --git a/submodules/PremiumUI/Sources/PremiumIntroScreen.swift b/submodules/PremiumUI/Sources/PremiumIntroScreen.swift index 1c0a6246d02..ae057ad6c06 100644 --- a/submodules/PremiumUI/Sources/PremiumIntroScreen.swift +++ b/submodules/PremiumUI/Sources/PremiumIntroScreen.swift @@ -3141,10 +3141,14 @@ private final class PremiumIntroScreenComponent: CombinedComponent { let secondaryTitleText: String var isAnonymous = false if var otherPeerName = state.otherPeerName { - if case let .emojiStatus(_, _, file, maybeEmojiPack) = context.component.source, let emojiPack = maybeEmojiPack, case let .result(info, _, _) = emojiPack { + if case let .emojiStatus(peerId, _, file, maybeEmojiPack) = context.component.source, let emojiPack = maybeEmojiPack, case let .result(info, _, _) = emojiPack { loadedEmojiPack = maybeEmojiPack highlightableLinks = true + if peerId.isGroupOrChannel, otherPeerName.count > 20 { + otherPeerName = otherPeerName.prefix(20).trimmingCharacters(in: .whitespacesAndNewlines) + "\u{2026}" + } + var packReference: StickerPackReference? if let file = file { for attribute in file.attributes { diff --git a/submodules/PremiumUI/Sources/PremiumLimitsListScreen.swift b/submodules/PremiumUI/Sources/PremiumLimitsListScreen.swift index 4fd0a107555..dc6accd6486 100644 --- a/submodules/PremiumUI/Sources/PremiumLimitsListScreen.swift +++ b/submodules/PremiumUI/Sources/PremiumLimitsListScreen.swift @@ -228,6 +228,8 @@ public class PremiumLimitsListScreen: ViewController { if scrollView.contentSize.width > scrollView.contentSize.height || scrollView.contentSize.height > 1500.0 { return false } + } else if otherGestureRecognizer.view is PremiumCoinComponent.View { + return false } return true } diff --git a/submodules/TelegramUI/Components/AudioTranscriptionButtonComponent/Sources/AudioTranscriptionButtonComponent.swift b/submodules/TelegramUI/Components/AudioTranscriptionButtonComponent/Sources/AudioTranscriptionButtonComponent.swift index b614222d278..3696b9ffeaa 100644 --- a/submodules/TelegramUI/Components/AudioTranscriptionButtonComponent/Sources/AudioTranscriptionButtonComponent.swift +++ b/submodules/TelegramUI/Components/AudioTranscriptionButtonComponent/Sources/AudioTranscriptionButtonComponent.swift @@ -17,6 +17,12 @@ public final class AudioTranscriptionButtonComponent: Component { } else { return false } + case let .custom(lhsBackgroundColor, lhsForegroundColor): + if case let .custom(rhsBackgroundColor, rhsForegroundColor) = rhs { + return lhsBackgroundColor == rhsBackgroundColor && lhsForegroundColor == rhsForegroundColor + } else { + return false + } case let .freeform(lhsFreeform, lhsForeground): if case let .freeform(rhsFreeform, rhsForeground) = rhs, lhsFreeform == rhsFreeform, lhsForeground == rhsForeground { return true @@ -27,6 +33,7 @@ public final class AudioTranscriptionButtonComponent: Component { } case bubble(PresentationThemePartedColors) + case custom(UIColor, UIColor) case freeform((UIColor, Bool), UIColor) } @@ -101,6 +108,9 @@ public final class AudioTranscriptionButtonComponent: Component { case let .bubble(theme): foregroundColor = theme.bubble.withWallpaper.reactionActiveBackground backgroundColor = theme.bubble.withWallpaper.reactionInactiveBackground + case let .custom(backgroundColorValue, foregroundColorValue): + foregroundColor = foregroundColorValue + backgroundColor = backgroundColorValue case let .freeform(colorAndBlur, color): foregroundColor = color backgroundColor = .clear diff --git a/submodules/TelegramUI/Components/Chat/ChatMessageAttachedContentNode/Sources/ChatMessageAttachedContentNode.swift b/submodules/TelegramUI/Components/Chat/ChatMessageAttachedContentNode/Sources/ChatMessageAttachedContentNode.swift index 818da1db8b3..a6c634bea46 100644 --- a/submodules/TelegramUI/Components/Chat/ChatMessageAttachedContentNode/Sources/ChatMessageAttachedContentNode.swift +++ b/submodules/TelegramUI/Components/Chat/ChatMessageAttachedContentNode/Sources/ChatMessageAttachedContentNode.swift @@ -728,7 +728,7 @@ public final class ChatMessageAttachedContentNode: ASDisplayNode { let contentFileSizeAndApply: (CGSize, ChatMessageInteractiveFileNode.Apply)? if let contentFileFinalizeLayout { - let (size, apply) = contentFileFinalizeLayout(resultingWidth - insets.left - insets.right) + let (size, apply) = contentFileFinalizeLayout(resultingWidth - insets.left - insets.right - 6.0) contentFileSizeAndApply = (size, apply) } else { contentFileSizeAndApply = nil @@ -846,7 +846,7 @@ public final class ChatMessageAttachedContentNode: ASDisplayNode { offsetY: actualSize.height )) - actualSize.height += contentFileSize.height + actualSize.height += contentFileSize.height + 9.0 } case .actionButton: if let (actionButtonSize, _) = actionButtonSizeAndApply { diff --git a/submodules/TelegramUI/Components/Chat/ChatMessageInteractiveFileNode/Sources/ChatMessageInteractiveFileNode.swift b/submodules/TelegramUI/Components/Chat/ChatMessageInteractiveFileNode/Sources/ChatMessageInteractiveFileNode.swift index 3d6e0eb6b1d..f10ee1d73b3 100644 --- a/submodules/TelegramUI/Components/Chat/ChatMessageInteractiveFileNode/Sources/ChatMessageInteractiveFileNode.swift +++ b/submodules/TelegramUI/Components/Chat/ChatMessageInteractiveFileNode/Sources/ChatMessageInteractiveFileNode.swift @@ -1329,10 +1329,16 @@ public final class ChatMessageInteractiveFileNode: ASDisplayNode { strongSelf.view.addSubview(audioTranscriptionButton) added = true } + let buttonTheme: AudioTranscriptionButtonComponent.Theme + if let customTintColor = arguments.customTintColor { + buttonTheme = .custom(customTintColor.withMultipliedAlpha(0.1), customTintColor) + } else { + buttonTheme = .bubble(arguments.incoming ? arguments.presentationData.theme.theme.chat.message.incoming : arguments.presentationData.theme.theme.chat.message.outgoing) + } let audioTranscriptionButtonSize = audioTranscriptionButton.update( transition: animation.isAnimated ? .easeInOut(duration: 0.3) : .immediate, component: AnyComponent(AudioTranscriptionButtonComponent( - theme: .bubble(arguments.incoming ? arguments.presentationData.theme.theme.chat.message.incoming : arguments.presentationData.theme.theme.chat.message.outgoing), + theme: buttonTheme, transcriptionState: effectiveAudioTranscriptionState, pressed: { guard let strongSelf = self else { diff --git a/submodules/TelegramUI/Components/ShareWithPeersScreen/Sources/ShareWithPeersScreen.swift b/submodules/TelegramUI/Components/ShareWithPeersScreen/Sources/ShareWithPeersScreen.swift index 8f3b9051d06..37f1d5c338a 100644 --- a/submodules/TelegramUI/Components/ShareWithPeersScreen/Sources/ShareWithPeersScreen.swift +++ b/submodules/TelegramUI/Components/ShareWithPeersScreen/Sources/ShareWithPeersScreen.swift @@ -427,6 +427,10 @@ final class ShareWithPeersScreenComponent: Component { } } + func scrollViewWillBeginDragging(_ scrollView: UIScrollView) { + self.endEditing(true) + } + func scrollViewWillEndDragging(_ scrollView: UIScrollView, withVelocity velocity: CGPoint, targetContentOffset: UnsafeMutablePointer) { guard let itemLayout = self.itemLayout, let topOffsetDistance = self.topOffsetDistance else { return @@ -801,7 +805,7 @@ final class ShareWithPeersScreenComponent: Component { } private func updateModalOverlayTransition(transition: Transition) { - guard let component = self.component, let environment = self.environment, let itemLayout = self.itemLayout else { + guard let component = self.component, let environment = self.environment, let itemLayout = self.itemLayout, !self.isDismissed else { return } @@ -2071,6 +2075,14 @@ final class ShareWithPeersScreenComponent: Component { self.selectedCategories.insert(.everyone) } self.state?.updated(transition: Transition(animation: .curve(duration: 0.35, curve: .spring))) + }, + isFocusedUpdated: { [weak self] isFocused in + guard let self else { + return + } + if isFocused { + self.scrollView.setContentOffset(CGPoint(x: 0.0, y: -self.scrollView.contentInset.top), animated: true) + } } )), environment: {}, @@ -2122,11 +2134,11 @@ final class ShareWithPeersScreenComponent: Component { transition.setFrame(view: self.dimView, frame: CGRect(origin: CGPoint(), size: availableSize)) if case .members = component.stateContext.subject { - self.dimView .isHidden = true + self.dimView.isHidden = true } else if case .channels = component.stateContext.subject { - self.dimView .isHidden = true + self.dimView.isHidden = true } else { - self.dimView .isHidden = false + self.dimView.isHidden = false } let categoryItemSize = self.categoryTemplateItem.update( diff --git a/submodules/TelegramUI/Components/TokenListTextField/Sources/TokenListTextField.swift b/submodules/TelegramUI/Components/TokenListTextField/Sources/TokenListTextField.swift index a5c33584308..d46862dac97 100644 --- a/submodules/TelegramUI/Components/TokenListTextField/Sources/TokenListTextField.swift +++ b/submodules/TelegramUI/Components/TokenListTextField/Sources/TokenListTextField.swift @@ -88,6 +88,7 @@ public final class TokenListTextField: Component { public let tokens: [Token] public let sideInset: CGFloat public let deleteToken: (AnyHashable) -> Void + public let isFocusedUpdated: (Bool) -> Void public init( externalState: ExternalState, @@ -96,7 +97,8 @@ public final class TokenListTextField: Component { placeholder: String, tokens: [Token], sideInset: CGFloat, - deleteToken: @escaping (AnyHashable) -> Void + deleteToken: @escaping (AnyHashable) -> Void, + isFocusedUpdated: @escaping (Bool) -> Void = { _ in } ) { self.externalState = externalState self.context = context @@ -105,6 +107,7 @@ public final class TokenListTextField: Component { self.tokens = tokens self.sideInset = sideInset self.deleteToken = deleteToken + self.isFocusedUpdated = isFocusedUpdated } public static func ==(lhs: TokenListTextField, rhs: TokenListTextField) -> Bool { @@ -191,6 +194,7 @@ public final class TokenListTextField: Component { guard let self else { return } + self.component?.isFocusedUpdated(self.tokenListNode?.isFocused ?? false) self.componentState?.updated(transition: Transition(animation: .curve(duration: 0.35, curve: .spring))) } diff --git a/submodules/TelegramUI/Sources/OpenResolvedUrl.swift b/submodules/TelegramUI/Sources/OpenResolvedUrl.swift index 2a5d09ecf77..c820caf77ab 100644 --- a/submodules/TelegramUI/Sources/OpenResolvedUrl.swift +++ b/submodules/TelegramUI/Sources/OpenResolvedUrl.swift @@ -302,7 +302,7 @@ func openResolvedUrlImpl( }) dismissInput() case let .share(url, text, to): - let continueWithPeer: (PeerId) -> Void = { peerId in + let continueWithPeer: (PeerId, Int64?) -> Void = { peerId, threadId in let textInputState: ChatTextInputState? if let text = text, !text.isEmpty { if let url = url, !url.isEmpty { @@ -320,15 +320,42 @@ func openResolvedUrlImpl( textInputState = nil } + let updateControllers = { [weak navigationController] in + guard let navigationController else { + return + } + let chatController: Signal + if let threadId { + chatController = chatControllerForForumThreadImpl(context: context, peerId: peerId, threadId: threadId) + } else { + chatController = .single(ChatControllerImpl(context: context, chatLocation: .peer(id: peerId))) + } + + let _ = (chatController + |> deliverOnMainQueue).start(next: { [weak navigationController] chatController in + guard let navigationController else { + return + } + var controllers = navigationController.viewControllers.filter { controller in + if controller is PeerSelectionController { + return false + } + return true + } + controllers.append(chatController) + navigationController.setViewControllers(controllers, animated: true) + }) + } + if let textInputState = textInputState { - let _ = (ChatInterfaceState.update(engine: context.engine, peerId: peerId, threadId: nil, { currentState in + let _ = (ChatInterfaceState.update(engine: context.engine, peerId: peerId, threadId: threadId, { currentState in return currentState.withUpdatedComposeInputState(textInputState) }) |> deliverOnMainQueue).startStandalone(completed: { - navigationController?.pushViewController(ChatControllerImpl(context: context, chatLocation: .peer(id: peerId))) + updateControllers() }) } else { - navigationController?.pushViewController(ChatControllerImpl(context: context, chatLocation: .peer(id: peerId))) + updateControllers() } } @@ -344,7 +371,7 @@ func openResolvedUrlImpl( |> deliverOnMainQueue).startStandalone(next: { peer in if let peer = peer { context.sharedContext.applicationBindings.dismissNativeController() - continueWithPeer(peer.id) + continueWithPeer(peer.id, nil) } }) } else { @@ -352,7 +379,7 @@ func openResolvedUrlImpl( |> deliverOnMainQueue).startStandalone(next: { peer in if let peer = peer { context.sharedContext.applicationBindings.dismissNativeController() - continueWithPeer(peer.id) + continueWithPeer(peer.id, nil) } }) /*let query = to.trimmingCharacters(in: CharacterSet(charactersIn: "0123456789").inverted) @@ -377,13 +404,8 @@ func openResolvedUrlImpl( context.sharedContext.applicationBindings.dismissNativeController() } else { let controller = context.sharedContext.makePeerSelectionController(PeerSelectionControllerParams(context: context, filter: [.onlyWriteable, .excludeDisabled], selectForumThreads: true)) - controller.peerSelected = { [weak controller] peer, _ in - let peerId = peer.id - - if let strongController = controller { - strongController.dismiss() - continueWithPeer(peerId) - } + controller.peerSelected = { peer, threadId in + continueWithPeer(peer.id, threadId) } context.sharedContext.applicationBindings.dismissNativeController() navigationController?.pushViewController(controller)