mirror of
https://github.com/Swiftgram/Telegram-iOS.git
synced 2025-06-16 05:55:20 +00:00
Various fixes
This commit is contained in:
parent
b529625219
commit
980a2c47bc
@ -246,7 +246,7 @@ public final class AuthorizationSequencePhoneEntryController: ViewController, MF
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
func dismissConfirmation() {
|
public func dismissConfirmation() {
|
||||||
self.confirmationController?.dismissAnimated()
|
self.confirmationController?.dismissAnimated()
|
||||||
self.confirmationController = nil
|
self.confirmationController = nil
|
||||||
}
|
}
|
||||||
|
@ -1354,11 +1354,25 @@ open class NavigationController: UINavigationController, ContainableController,
|
|||||||
|
|
||||||
public func replaceControllersAndPush(controllers: [UIViewController], controller: ViewController, animated: Bool, options: NavigationAnimationOptions = [], ready: ValuePromise<Bool>? = nil, completion: @escaping () -> Void = {}) {
|
public func replaceControllersAndPush(controllers: [UIViewController], controller: ViewController, animated: Bool, options: NavigationAnimationOptions = [], ready: ValuePromise<Bool>? = nil, completion: @escaping () -> Void = {}) {
|
||||||
ready?.set(true)
|
ready?.set(true)
|
||||||
|
let action = { [weak self] in
|
||||||
|
guard let self else {
|
||||||
|
return
|
||||||
|
}
|
||||||
var controllers = controllers
|
var controllers = controllers
|
||||||
controllers.append(controller)
|
controllers.append(controller)
|
||||||
self.setViewControllers(controllers, animated: animated)
|
self.setViewControllers(controllers, animated: animated)
|
||||||
completion()
|
completion()
|
||||||
}
|
}
|
||||||
|
if let rootContainer = self.rootContainer, case let .split(container) = rootContainer, let topController = container.detailControllers.last {
|
||||||
|
if topController.attemptNavigation({
|
||||||
|
action()
|
||||||
|
}) {
|
||||||
|
action()
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
action()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
public func replaceControllers(controllers: [UIViewController], animated: Bool, options: NavigationAnimationOptions = [], ready: ValuePromise<Bool>? = nil, completion: @escaping () -> Void = {}) {
|
public func replaceControllers(controllers: [UIViewController], animated: Bool, options: NavigationAnimationOptions = [], ready: ValuePromise<Bool>? = nil, completion: @escaping () -> Void = {}) {
|
||||||
ready?.set(true)
|
ready?.set(true)
|
||||||
|
@ -1654,7 +1654,7 @@ open class TextNode: ASDisplayNode {
|
|||||||
return (layout, {
|
return (layout, {
|
||||||
node.cachedLayout = layout
|
node.cachedLayout = layout
|
||||||
if updated {
|
if updated {
|
||||||
if layout.size.width.isZero && layout.size.height.isZero {
|
if layout.size.width.isZero || layout.size.height.isZero {
|
||||||
node.contents = nil
|
node.contents = nil
|
||||||
}
|
}
|
||||||
node.setNeedsDisplay()
|
node.setNeedsDisplay()
|
||||||
|
@ -183,6 +183,10 @@ final class JoinLinkPreviewPeerContentNode: ASDisplayNode, ShareContentContainer
|
|||||||
self.contentOffsetUpdated = f
|
self.contentOffsetUpdated = f
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func updateTheme(_ theme: PresentationTheme) {
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
func updateLayout(size: CGSize, isLandscape: Bool, bottomInset: CGFloat, transition: ContainedViewLayoutTransition) {
|
func updateLayout(size: CGSize, isLandscape: Bool, bottomInset: CGFloat, transition: ContainedViewLayoutTransition) {
|
||||||
let showPeers = !self.peerNodes.isEmpty && !isLandscape
|
let showPeers = !self.peerNodes.isEmpty && !isLandscape
|
||||||
var nodeHeight: CGFloat = (!showPeers ? 236.0 : 320.0)
|
var nodeHeight: CGFloat = (!showPeers ? 236.0 : 320.0)
|
||||||
@ -283,7 +287,7 @@ public enum ShareLoadingState {
|
|||||||
public final class JoinLinkPreviewLoadingContainerNode: ASDisplayNode, ShareContentContainerNode {
|
public final class JoinLinkPreviewLoadingContainerNode: ASDisplayNode, ShareContentContainerNode {
|
||||||
private var contentOffsetUpdated: ((CGFloat, ContainedViewLayoutTransition) -> Void)?
|
private var contentOffsetUpdated: ((CGFloat, ContainedViewLayoutTransition) -> Void)?
|
||||||
|
|
||||||
private let theme: PresentationTheme
|
private var theme: PresentationTheme
|
||||||
private let activityIndicator: ActivityIndicator
|
private let activityIndicator: ActivityIndicator
|
||||||
|
|
||||||
public init(theme: PresentationTheme) {
|
public init(theme: PresentationTheme) {
|
||||||
@ -308,6 +312,11 @@ public final class JoinLinkPreviewLoadingContainerNode: ASDisplayNode, ShareCont
|
|||||||
self.contentOffsetUpdated = f
|
self.contentOffsetUpdated = f
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public func updateTheme(_ theme: PresentationTheme) {
|
||||||
|
self.theme = theme
|
||||||
|
self.activityIndicator.type = .custom(theme.actionSheet.controlAccentColor, 22.0, 2.0, false)
|
||||||
|
}
|
||||||
|
|
||||||
public func updateLayout(size: CGSize, isLandscape: Bool, bottomInset: CGFloat, transition: ContainedViewLayoutTransition) {
|
public func updateLayout(size: CGSize, isLandscape: Bool, bottomInset: CGFloat, transition: ContainedViewLayoutTransition) {
|
||||||
let nodeHeight: CGFloat = 125.0
|
let nodeHeight: CGFloat = 125.0
|
||||||
|
|
||||||
|
@ -82,6 +82,10 @@ final class LanguageLinkPreviewContentNode: ASDisplayNode, ShareContentContainer
|
|||||||
self.contentOffsetUpdated = f
|
self.contentOffsetUpdated = f
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func updateTheme(_ theme: PresentationTheme) {
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
func updateLayout(size: CGSize, isLandscape: Bool, bottomInset: CGFloat, transition: ContainedViewLayoutTransition) {
|
func updateLayout(size: CGSize, isLandscape: Bool, bottomInset: CGFloat, transition: ContainedViewLayoutTransition) {
|
||||||
let insets = UIEdgeInsets(top: 12.0, left: 10.0, bottom: 12.0 + bottomInset, right: 10.0)
|
let insets = UIEdgeInsets(top: 12.0, left: 10.0, bottom: 12.0 + bottomInset, right: 10.0)
|
||||||
let titleSpacing: CGFloat = 12.0
|
let titleSpacing: CGFloat = 12.0
|
||||||
|
@ -110,7 +110,9 @@ class EmojiHeaderComponent: Component {
|
|||||||
}
|
}
|
||||||
|
|
||||||
self.statusView.isHidden = false
|
self.statusView.isHidden = false
|
||||||
|
if containerView.subviews.count > 1 && containerView.subviews[1].subviews.count > 1 {
|
||||||
containerView = containerView.subviews[1].subviews[1]
|
containerView = containerView.subviews[1].subviews[1]
|
||||||
|
}
|
||||||
|
|
||||||
let initialPosition = self.statusView.center
|
let initialPosition = self.statusView.center
|
||||||
let targetPosition = self.statusView.superview!.convert(self.statusView.center, to: containerView)
|
let targetPosition = self.statusView.superview!.convert(self.statusView.center, to: containerView)
|
||||||
|
@ -166,7 +166,7 @@ final class ReactionContextBackgroundNode: ASDisplayNode {
|
|||||||
backgroundMaskNodeFrame = backgroundMaskNodeFrame.offsetBy(dx: 0.0, dy: (updatedHeight - backgroundMaskNodeFrame.height) * 0.5)
|
backgroundMaskNodeFrame = backgroundMaskNodeFrame.offsetBy(dx: 0.0, dy: (updatedHeight - backgroundMaskNodeFrame.height) * 0.5)
|
||||||
}
|
}
|
||||||
|
|
||||||
transition.updateCornerRadius(layer: self.backgroundClippingLayer, cornerRadius: 46.0 / 2.0)
|
transition.updateCornerRadius(layer: self.backgroundClippingLayer, cornerRadius: min(46.0 / 2.0, backgroundFrame.height / 2.0))
|
||||||
|
|
||||||
let largeCircleFrame: CGRect
|
let largeCircleFrame: CGRect
|
||||||
let smallCircleFrame: CGRect
|
let smallCircleFrame: CGRect
|
||||||
|
@ -2276,6 +2276,9 @@ public final class ReactionContextNode: ASDisplayNode, UIScrollViewDelegate {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
if let closestItem = closestItem, let closestItemNode = self.visibleItemNodes[closestItem.index] as? ReactionNode {
|
if let closestItem = closestItem, let closestItemNode = self.visibleItemNodes[closestItem.index] as? ReactionNode {
|
||||||
|
if let expandItemView = self.expandItemView, expandItemView.frame.insetBy(dx: -20.0, dy: -20.0).contains(scrollPoint) {
|
||||||
|
return nil
|
||||||
|
}
|
||||||
return closestItemNode.item
|
return closestItemNode.item
|
||||||
}
|
}
|
||||||
return nil
|
return nil
|
||||||
|
@ -137,6 +137,7 @@ public func ChangePhoneNumberController(context: AccountContext) -> ViewControll
|
|||||||
actions.append(TextAlertAction(type: .defaultAction, title: presentationData.strings.Common_OK, action: {}))
|
actions.append(TextAlertAction(type: .defaultAction, title: presentationData.strings.Common_OK, action: {}))
|
||||||
}
|
}
|
||||||
|
|
||||||
|
controller?.dismissConfirmation()
|
||||||
controller?.present(textAlertController(context: context, title: nil, text: text, actions: actions), in: .window(.root))
|
controller?.present(textAlertController(context: context, title: nil, text: text, actions: actions), in: .window(.root))
|
||||||
}))
|
}))
|
||||||
}
|
}
|
||||||
|
@ -3,6 +3,7 @@ import UIKit
|
|||||||
import Display
|
import Display
|
||||||
import Postbox
|
import Postbox
|
||||||
import TelegramCore
|
import TelegramCore
|
||||||
|
import TelegramPresentationData
|
||||||
|
|
||||||
public protocol ShareContentContainerNode: AnyObject {
|
public protocol ShareContentContainerNode: AnyObject {
|
||||||
func activate()
|
func activate()
|
||||||
@ -10,5 +11,6 @@ public protocol ShareContentContainerNode: AnyObject {
|
|||||||
func setEnsurePeerVisibleOnLayout(_ peerId: EnginePeer.Id?)
|
func setEnsurePeerVisibleOnLayout(_ peerId: EnginePeer.Id?)
|
||||||
func setContentOffsetUpdated(_ f: ((CGFloat, ContainedViewLayoutTransition) -> Void)?)
|
func setContentOffsetUpdated(_ f: ((CGFloat, ContainedViewLayoutTransition) -> Void)?)
|
||||||
func updateLayout(size: CGSize, isLandscape: Bool, bottomInset: CGFloat, transition: ContainedViewLayoutTransition)
|
func updateLayout(size: CGSize, isLandscape: Bool, bottomInset: CGFloat, transition: ContainedViewLayoutTransition)
|
||||||
|
func updateTheme(_ theme: PresentationTheme)
|
||||||
func updateSelectedPeers(animated: Bool)
|
func updateSelectedPeers(animated: Bool)
|
||||||
}
|
}
|
||||||
|
@ -524,6 +524,8 @@ final class ShareControllerNode: ViewControllerTracingNode, UIScrollViewDelegate
|
|||||||
|
|
||||||
self.actionButtonNode.badgeBackgroundColor = presentationData.theme.actionSheet.controlAccentColor
|
self.actionButtonNode.badgeBackgroundColor = presentationData.theme.actionSheet.controlAccentColor
|
||||||
self.actionButtonNode.badgeTextColor = presentationData.theme.actionSheet.opaqueItemBackgroundColor
|
self.actionButtonNode.badgeTextColor = presentationData.theme.actionSheet.opaqueItemBackgroundColor
|
||||||
|
|
||||||
|
self.contentNode?.updateTheme(presentationData.theme)
|
||||||
}
|
}
|
||||||
|
|
||||||
func setActionNodesHidden(_ hidden: Bool, inputField: Bool = false, actions: Bool = false, animated: Bool = true) {
|
func setActionNodesHidden(_ hidden: Bool, inputField: Bool = false, actions: Bool = false, animated: Bool = true) {
|
||||||
|
@ -45,7 +45,7 @@ final class ShareControllerGridSection: GridSection {
|
|||||||
|
|
||||||
func isEqual(to: GridSection) -> Bool {
|
func isEqual(to: GridSection) -> Bool {
|
||||||
if let to = to as? ShareControllerGridSection {
|
if let to = to as? ShareControllerGridSection {
|
||||||
return self.title == to.title
|
return self.title == to.title && self.theme === to.theme
|
||||||
} else {
|
} else {
|
||||||
return false
|
return false
|
||||||
}
|
}
|
||||||
@ -185,7 +185,7 @@ final class ShareControllerPeerGridItemNode: GridItemNode {
|
|||||||
}
|
}
|
||||||
|
|
||||||
func setup(context: AccountContext, theme: PresentationTheme, strings: PresentationStrings, peer: EngineRenderedPeer?, presence: EnginePeer.Presence?, topicId: Int64?, threadData: MessageHistoryThreadData?, search: Bool, synchronousLoad: Bool, force: Bool) {
|
func setup(context: AccountContext, theme: PresentationTheme, strings: PresentationStrings, peer: EngineRenderedPeer?, presence: EnginePeer.Presence?, topicId: Int64?, threadData: MessageHistoryThreadData?, search: Bool, synchronousLoad: Bool, force: Bool) {
|
||||||
if force || self.currentState == nil || self.currentState!.0 !== context || self.currentState!.3 != peer || self.currentState!.5 != presence || self.currentState!.6 != topicId {
|
if force || self.currentState == nil || self.currentState!.0 !== context || self.currentState!.2 !== theme || self.currentState!.3 != peer || self.currentState!.5 != presence || self.currentState!.6 != topicId {
|
||||||
let itemTheme = SelectablePeerNodeTheme(textColor: theme.actionSheet.primaryTextColor, secretTextColor: theme.chatList.secretTitleColor, selectedTextColor: theme.actionSheet.controlAccentColor, checkBackgroundColor: theme.actionSheet.opaqueItemBackgroundColor, checkFillColor: theme.actionSheet.controlAccentColor, checkColor: theme.actionSheet.checkContentColor, avatarPlaceholderColor: theme.list.mediaPlaceholderColor)
|
let itemTheme = SelectablePeerNodeTheme(textColor: theme.actionSheet.primaryTextColor, secretTextColor: theme.chatList.secretTitleColor, selectedTextColor: theme.actionSheet.controlAccentColor, checkBackgroundColor: theme.actionSheet.opaqueItemBackgroundColor, checkFillColor: theme.actionSheet.controlAccentColor, checkColor: theme.actionSheet.checkContentColor, avatarPlaceholderColor: theme.list.mediaPlaceholderColor)
|
||||||
|
|
||||||
let timestamp = Int32(CFAbsoluteTimeGetCurrent() + NSTimeIntervalSince1970)
|
let timestamp = Int32(CFAbsoluteTimeGetCurrent() + NSTimeIntervalSince1970)
|
||||||
|
@ -54,7 +54,7 @@ final class ShareControllerRecentPeersGridItemNode: GridItemNode {
|
|||||||
}
|
}
|
||||||
|
|
||||||
func setup(context: AccountContext, theme: PresentationTheme, strings: PresentationStrings) {
|
func setup(context: AccountContext, theme: PresentationTheme, strings: PresentationStrings) {
|
||||||
if self.currentState == nil || self.currentState!.0 !== context {
|
if self.currentState == nil || self.currentState!.0 !== context || self.currentState!.1 !== theme {
|
||||||
let peersNode: ChatListSearchRecentPeersNode
|
let peersNode: ChatListSearchRecentPeersNode
|
||||||
if let currentPeersNode = self.peersNode {
|
if let currentPeersNode = self.peersNode {
|
||||||
peersNode = currentPeersNode
|
peersNode = currentPeersNode
|
||||||
|
@ -27,7 +27,7 @@ protocol ShareLoadingContainer: ASDisplayNode {
|
|||||||
public final class ShareLoadingContainerNode: ASDisplayNode, ShareContentContainerNode, ShareLoadingContainer {
|
public final class ShareLoadingContainerNode: ASDisplayNode, ShareContentContainerNode, ShareLoadingContainer {
|
||||||
private var contentOffsetUpdated: ((CGFloat, ContainedViewLayoutTransition) -> Void)?
|
private var contentOffsetUpdated: ((CGFloat, ContainedViewLayoutTransition) -> Void)?
|
||||||
|
|
||||||
private let theme: PresentationTheme
|
private var theme: PresentationTheme
|
||||||
private let activityIndicator: ActivityIndicator
|
private let activityIndicator: ActivityIndicator
|
||||||
private let statusNode: RadialStatusNode
|
private let statusNode: RadialStatusNode
|
||||||
private let doneStatusNode: RadialStatusNode
|
private let doneStatusNode: RadialStatusNode
|
||||||
@ -78,6 +78,10 @@ public final class ShareLoadingContainerNode: ASDisplayNode, ShareContentContain
|
|||||||
self.contentOffsetUpdated = f
|
self.contentOffsetUpdated = f
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public func updateTheme(_ theme: PresentationTheme) {
|
||||||
|
self.theme = theme
|
||||||
|
}
|
||||||
|
|
||||||
public func updateLayout(size: CGSize, isLandscape: Bool, bottomInset: CGFloat, transition: ContainedViewLayoutTransition) {
|
public func updateLayout(size: CGSize, isLandscape: Bool, bottomInset: CGFloat, transition: ContainedViewLayoutTransition) {
|
||||||
let nodeHeight: CGFloat = 125.0
|
let nodeHeight: CGFloat = 125.0
|
||||||
|
|
||||||
@ -98,7 +102,7 @@ public final class ShareLoadingContainerNode: ASDisplayNode, ShareContentContain
|
|||||||
public final class ShareProlongedLoadingContainerNode: ASDisplayNode, ShareContentContainerNode, ShareLoadingContainer {
|
public final class ShareProlongedLoadingContainerNode: ASDisplayNode, ShareContentContainerNode, ShareLoadingContainer {
|
||||||
private var contentOffsetUpdated: ((CGFloat, ContainedViewLayoutTransition) -> Void)?
|
private var contentOffsetUpdated: ((CGFloat, ContainedViewLayoutTransition) -> Void)?
|
||||||
|
|
||||||
private let theme: PresentationTheme
|
private var theme: PresentationTheme
|
||||||
private let strings: PresentationStrings
|
private let strings: PresentationStrings
|
||||||
|
|
||||||
private let animationNode: AnimatedStickerNode
|
private let animationNode: AnimatedStickerNode
|
||||||
@ -271,6 +275,10 @@ public final class ShareProlongedLoadingContainerNode: ASDisplayNode, ShareConte
|
|||||||
self.animationStatusDisposable.dispose()
|
self.animationStatusDisposable.dispose()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public func updateTheme(_ theme: PresentationTheme) {
|
||||||
|
self.theme = theme
|
||||||
|
}
|
||||||
|
|
||||||
public func activate() {
|
public func activate() {
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -65,6 +65,9 @@ private struct SharePeerEntry: Comparable, Identifiable {
|
|||||||
if lhs.threadData != rhs.threadData {
|
if lhs.threadData != rhs.threadData {
|
||||||
return false
|
return false
|
||||||
}
|
}
|
||||||
|
if lhs.theme !== rhs.theme {
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
|
||||||
return true
|
return true
|
||||||
}
|
}
|
||||||
@ -100,7 +103,8 @@ private func preparedGridEntryTransition(context: AccountContext, from fromEntri
|
|||||||
final class SharePeersContainerNode: ASDisplayNode, ShareContentContainerNode {
|
final class SharePeersContainerNode: ASDisplayNode, ShareContentContainerNode {
|
||||||
private let sharedContext: SharedAccountContext
|
private let sharedContext: SharedAccountContext
|
||||||
private let context: AccountContext
|
private let context: AccountContext
|
||||||
private let theme: PresentationTheme
|
private var theme: PresentationTheme
|
||||||
|
private let themePromise: Promise<PresentationTheme>
|
||||||
private let strings: PresentationStrings
|
private let strings: PresentationStrings
|
||||||
private let nameDisplayOrder: PresentationPersonNameOrder
|
private let nameDisplayOrder: PresentationPersonNameOrder
|
||||||
private let controllerInteraction: ShareControllerInteraction
|
private let controllerInteraction: ShareControllerInteraction
|
||||||
@ -153,6 +157,8 @@ final class SharePeersContainerNode: ASDisplayNode, ShareContentContainerNode {
|
|||||||
self.sharedContext = sharedContext
|
self.sharedContext = sharedContext
|
||||||
self.context = context
|
self.context = context
|
||||||
self.theme = theme
|
self.theme = theme
|
||||||
|
self.themePromise = Promise()
|
||||||
|
self.themePromise.set(.single(theme))
|
||||||
self.strings = strings
|
self.strings = strings
|
||||||
self.nameDisplayOrder = nameDisplayOrder
|
self.nameDisplayOrder = nameDisplayOrder
|
||||||
self.controllerInteraction = controllerInteraction
|
self.controllerInteraction = controllerInteraction
|
||||||
@ -164,8 +170,8 @@ final class SharePeersContainerNode: ASDisplayNode, ShareContentContainerNode {
|
|||||||
|
|
||||||
self.peersValue.set(.single(peers))
|
self.peersValue.set(.single(peers))
|
||||||
|
|
||||||
let items: Signal<[SharePeerEntry], NoError> = combineLatest(self.peersValue.get(), self.foundPeers.get(), self.tick.get())
|
let items: Signal<[SharePeerEntry], NoError> = combineLatest(self.peersValue.get(), self.foundPeers.get(), self.tick.get(), self.themePromise.get())
|
||||||
|> map { [weak controllerInteraction] initialPeers, foundPeers, _ -> [SharePeerEntry] in
|
|> map { [weak controllerInteraction] initialPeers, foundPeers, _, theme -> [SharePeerEntry] in
|
||||||
var entries: [SharePeerEntry] = []
|
var entries: [SharePeerEntry] = []
|
||||||
var index: Int32 = 0
|
var index: Int32 = 0
|
||||||
|
|
||||||
@ -303,6 +309,13 @@ final class SharePeersContainerNode: ASDisplayNode, ShareContentContainerNode {
|
|||||||
self.disposable.dispose()
|
self.disposable.dispose()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func updateTheme(_ theme: PresentationTheme) {
|
||||||
|
self.theme = theme
|
||||||
|
self.themePromise.set(.single(theme))
|
||||||
|
self.contentTitleNode.attributedText = NSAttributedString(string: self.strings.ShareMenu_ShareTo, font: Font.medium(20.0), textColor: self.theme.actionSheet.primaryTextColor)
|
||||||
|
self.updateSelectedPeers(animated: false)
|
||||||
|
}
|
||||||
|
|
||||||
private func enqueueTransition(_ transition: ShareGridTransaction, firstTime: Bool) {
|
private func enqueueTransition(_ transition: ShareGridTransaction, firstTime: Bool) {
|
||||||
self.enqueuedTransitions.append((transition, firstTime))
|
self.enqueuedTransitions.append((transition, firstTime))
|
||||||
|
|
||||||
|
@ -42,12 +42,10 @@ final class ShareSearchBarNode: ASDisplayNode, UITextFieldDelegate {
|
|||||||
self.textInputNode = TextFieldNode()
|
self.textInputNode = TextFieldNode()
|
||||||
self.textInputNode.fixOffset = false
|
self.textInputNode.fixOffset = false
|
||||||
let textColor: UIColor = theme.actionSheet.inputTextColor
|
let textColor: UIColor = theme.actionSheet.inputTextColor
|
||||||
let keyboardAppearance: UIKeyboardAppearance = UIKeyboardAppearance.default
|
|
||||||
self.textInputNode.textField.font = Font.regular(16.0)
|
self.textInputNode.textField.font = Font.regular(16.0)
|
||||||
self.textInputNode.textField.textColor = textColor
|
self.textInputNode.textField.textColor = textColor
|
||||||
self.textInputNode.textField.typingAttributes = [NSAttributedString.Key.font: Font.regular(16.0), NSAttributedString.Key.foregroundColor: textColor]
|
self.textInputNode.textField.typingAttributes = [NSAttributedString.Key.font: Font.regular(16.0), NSAttributedString.Key.foregroundColor: textColor]
|
||||||
self.textInputNode.hitTestSlop = UIEdgeInsets(top: -5.0, left: -5.0, bottom: -5.0, right: -5.0)
|
self.textInputNode.hitTestSlop = UIEdgeInsets(top: -5.0, left: -5.0, bottom: -5.0, right: -5.0)
|
||||||
self.textInputNode.textField.keyboardAppearance = keyboardAppearance
|
|
||||||
self.textInputNode.textField.attributedPlaceholder = NSAttributedString(string: placeholder, font: Font.regular(16.0), textColor: theme.actionSheet.inputPlaceholderColor)
|
self.textInputNode.textField.attributedPlaceholder = NSAttributedString(string: placeholder, font: Font.regular(16.0), textColor: theme.actionSheet.inputPlaceholderColor)
|
||||||
self.textInputNode.textField.keyboardAppearance = theme.rootController.keyboardColor.keyboardAppearance
|
self.textInputNode.textField.keyboardAppearance = theme.rootController.keyboardColor.keyboardAppearance
|
||||||
self.textInputNode.textField.tintColor = theme.actionSheet.controlAccentColor
|
self.textInputNode.textField.tintColor = theme.actionSheet.controlAccentColor
|
||||||
@ -88,6 +86,19 @@ final class ShareSearchBarNode: ASDisplayNode, UITextFieldDelegate {
|
|||||||
transition.updateFrame(node: self.textInputNode, frame: CGRect(origin: CGPoint(x: backgroundFrame.minX + inputInsets.left, y: backgroundFrame.minY + UIScreenPixel), size: CGSize(width: backgroundFrame.size.width - inputInsets.left - inputInsets.right, height: backgroundFrame.size.height)))
|
transition.updateFrame(node: self.textInputNode, frame: CGRect(origin: CGPoint(x: backgroundFrame.minX + inputInsets.left, y: backgroundFrame.minY + UIScreenPixel), size: CGSize(width: backgroundFrame.size.width - inputInsets.left - inputInsets.right, height: backgroundFrame.size.height)))
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func updateTheme(_ theme: PresentationTheme) {
|
||||||
|
self.backgroundNode.image = generateStretchableFilledCircleImage(diameter: 16.0, color: theme.actionSheet.inputBackgroundColor)
|
||||||
|
self.searchIconNode.image = generateTintedImage(image: UIImage(bundleImageName: "Share/SearchBarSearchIcon"), color: theme.actionSheet.inputPlaceholderColor)
|
||||||
|
self.clearButton.setImage(generateClearIcon(color: theme.actionSheet.inputClearButtonColor), for: [])
|
||||||
|
|
||||||
|
let textColor: UIColor = theme.actionSheet.inputTextColor
|
||||||
|
self.textInputNode.textField.textColor = textColor
|
||||||
|
self.textInputNode.textField.typingAttributes = [NSAttributedString.Key.font: Font.regular(16.0), NSAttributedString.Key.foregroundColor: textColor]
|
||||||
|
self.textInputNode.textField.attributedPlaceholder = NSAttributedString(string: self.textInputNode.textField.attributedPlaceholder?.string ?? "", font: Font.regular(16.0), textColor: theme.actionSheet.inputPlaceholderColor)
|
||||||
|
self.textInputNode.textField.keyboardAppearance = theme.rootController.keyboardColor.keyboardAppearance
|
||||||
|
self.textInputNode.textField.tintColor = theme.actionSheet.controlAccentColor
|
||||||
|
}
|
||||||
|
|
||||||
func activateInput() {
|
func activateInput() {
|
||||||
self.textInputNode.textField.becomeFirstResponder()
|
self.textInputNode.textField.becomeFirstResponder()
|
||||||
}
|
}
|
||||||
|
@ -121,6 +121,9 @@ private struct ShareSearchPeerEntry: Comparable, Identifiable {
|
|||||||
if lhs.peer != rhs.peer {
|
if lhs.peer != rhs.peer {
|
||||||
return false
|
return false
|
||||||
}
|
}
|
||||||
|
if lhs.theme !== rhs.theme {
|
||||||
|
return false
|
||||||
|
}
|
||||||
return true
|
return true
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -164,6 +167,8 @@ private func preparedRecentEntryTransition(context: AccountContext, from fromEnt
|
|||||||
final class ShareSearchContainerNode: ASDisplayNode, ShareContentContainerNode {
|
final class ShareSearchContainerNode: ASDisplayNode, ShareContentContainerNode {
|
||||||
private let sharedContext: SharedAccountContext
|
private let sharedContext: SharedAccountContext
|
||||||
private let context: AccountContext
|
private let context: AccountContext
|
||||||
|
private var theme: PresentationTheme
|
||||||
|
private let themePromise: Promise<PresentationTheme>
|
||||||
private let strings: PresentationStrings
|
private let strings: PresentationStrings
|
||||||
private let controllerInteraction: ShareControllerInteraction
|
private let controllerInteraction: ShareControllerInteraction
|
||||||
|
|
||||||
@ -196,6 +201,9 @@ final class ShareSearchContainerNode: ASDisplayNode, ShareContentContainerNode {
|
|||||||
init(sharedContext: SharedAccountContext, context: AccountContext, theme: PresentationTheme, strings: PresentationStrings, controllerInteraction: ShareControllerInteraction, recentPeers recentPeerList: [RenderedPeer]) {
|
init(sharedContext: SharedAccountContext, context: AccountContext, theme: PresentationTheme, strings: PresentationStrings, controllerInteraction: ShareControllerInteraction, recentPeers recentPeerList: [RenderedPeer]) {
|
||||||
self.sharedContext = sharedContext
|
self.sharedContext = sharedContext
|
||||||
self.context = context
|
self.context = context
|
||||||
|
self.theme = theme
|
||||||
|
self.themePromise = Promise<PresentationTheme>()
|
||||||
|
self.themePromise.set(.single(theme))
|
||||||
self.strings = strings
|
self.strings = strings
|
||||||
self.controllerInteraction = controllerInteraction
|
self.controllerInteraction = controllerInteraction
|
||||||
|
|
||||||
@ -237,8 +245,8 @@ final class ShareSearchContainerNode: ASDisplayNode, ShareContentContainerNode {
|
|||||||
|
|
||||||
self.cancelButtonNode.addTarget(self, action: #selector(self.cancelPressed), forControlEvents: .touchUpInside)
|
self.cancelButtonNode.addTarget(self, action: #selector(self.cancelPressed), forControlEvents: .touchUpInside)
|
||||||
|
|
||||||
let foundItems = self.searchQuery.get()
|
let foundItems = combineLatest(self.searchQuery.get(), self.themePromise.get())
|
||||||
|> mapToSignal { query -> Signal<([ShareSearchPeerEntry]?, Bool), NoError> in
|
|> mapToSignal { query, theme -> Signal<([ShareSearchPeerEntry]?, Bool), NoError> in
|
||||||
if !query.isEmpty {
|
if !query.isEmpty {
|
||||||
let accountPeer = context.account.postbox.loadedPeerWithId(context.account.peerId) |> take(1)
|
let accountPeer = context.account.postbox.loadedPeerWithId(context.account.peerId) |> take(1)
|
||||||
let foundLocalPeers = context.account.postbox.searchPeers(query: query.lowercased())
|
let foundLocalPeers = context.account.postbox.searchPeers(query: query.lowercased())
|
||||||
@ -354,8 +362,8 @@ final class ShareSearchContainerNode: ASDisplayNode, ShareContentContainerNode {
|
|||||||
}
|
}
|
||||||
|> distinctUntilChanged
|
|> distinctUntilChanged
|
||||||
|
|
||||||
let recentItems: Signal<[ShareSearchRecentEntry], NoError> = hasRecentPeers
|
let recentItems: Signal<[ShareSearchRecentEntry], NoError> = combineLatest(hasRecentPeers, self.themePromise.get())
|
||||||
|> map { hasRecentPeers -> [ShareSearchRecentEntry] in
|
|> map { hasRecentPeers, theme -> [ShareSearchRecentEntry] in
|
||||||
var recentItemList: [ShareSearchRecentEntry] = []
|
var recentItemList: [ShareSearchRecentEntry] = []
|
||||||
if hasRecentPeers {
|
if hasRecentPeers {
|
||||||
recentItemList.append(.topPeers(theme, strings))
|
recentItemList.append(.topPeers(theme, strings))
|
||||||
@ -404,6 +412,14 @@ final class ShareSearchContainerNode: ASDisplayNode, ShareContentContainerNode {
|
|||||||
self.searchNode.deactivateInput()
|
self.searchNode.deactivateInput()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func updateTheme(_ theme: PresentationTheme) {
|
||||||
|
self.theme = theme
|
||||||
|
self.themePromise.set(.single(theme))
|
||||||
|
self.searchNode.updateTheme(theme)
|
||||||
|
self.contentSeparatorNode.backgroundColor = theme.actionSheet.opaqueItemSeparatorColor
|
||||||
|
self.cancelButtonNode.setTitle(self.strings.Common_Cancel, with: cancelFont, with: self.theme.actionSheet.controlAccentColor, for: [])
|
||||||
|
}
|
||||||
|
|
||||||
private func calculateMetrics(size: CGSize) -> (topInset: CGFloat, itemWidth: CGFloat) {
|
private func calculateMetrics(size: CGSize) -> (topInset: CGFloat, itemWidth: CGFloat) {
|
||||||
let itemCount: Int
|
let itemCount: Int
|
||||||
if self.contentGridNode.isHidden {
|
if self.contentGridNode.isHidden {
|
||||||
|
@ -42,6 +42,9 @@ private struct ShareTopicEntry: Comparable, Identifiable {
|
|||||||
if lhs.threadData != rhs.threadData {
|
if lhs.threadData != rhs.threadData {
|
||||||
return false
|
return false
|
||||||
}
|
}
|
||||||
|
if lhs.theme !== rhs.theme {
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
|
||||||
return true
|
return true
|
||||||
}
|
}
|
||||||
@ -157,7 +160,8 @@ final class ShareTopicsContainerNode: ASDisplayNode, ShareContentContainerNode {
|
|||||||
|
|
||||||
private let sharedContext: SharedAccountContext
|
private let sharedContext: SharedAccountContext
|
||||||
private let context: AccountContext
|
private let context: AccountContext
|
||||||
private let theme: PresentationTheme
|
private var theme: PresentationTheme
|
||||||
|
private let themePromise: Promise<PresentationTheme>
|
||||||
private let strings: PresentationStrings
|
private let strings: PresentationStrings
|
||||||
private let controllerInteraction: ShareControllerInteraction
|
private let controllerInteraction: ShareControllerInteraction
|
||||||
|
|
||||||
@ -184,6 +188,8 @@ final class ShareTopicsContainerNode: ASDisplayNode, ShareContentContainerNode {
|
|||||||
self.sharedContext = sharedContext
|
self.sharedContext = sharedContext
|
||||||
self.context = context
|
self.context = context
|
||||||
self.theme = theme
|
self.theme = theme
|
||||||
|
self.themePromise = Promise()
|
||||||
|
self.themePromise.set(.single(theme))
|
||||||
self.strings = strings
|
self.strings = strings
|
||||||
self.controllerInteraction = controllerInteraction
|
self.controllerInteraction = controllerInteraction
|
||||||
|
|
||||||
@ -192,8 +198,8 @@ final class ShareTopicsContainerNode: ASDisplayNode, ShareContentContainerNode {
|
|||||||
return $0.items
|
return $0.items
|
||||||
})
|
})
|
||||||
|
|
||||||
let items: Signal<[ShareTopicEntry], NoError> = self.topicsValue.get()
|
let items: Signal<[ShareTopicEntry], NoError> = (combineLatest(self.topicsValue.get(), self.themePromise.get()))
|
||||||
|> map { topics -> [ShareTopicEntry] in
|
|> map { topics, theme -> [ShareTopicEntry] in
|
||||||
var entries: [ShareTopicEntry] = []
|
var entries: [ShareTopicEntry] = []
|
||||||
var index: Int32 = 0
|
var index: Int32 = 0
|
||||||
|
|
||||||
@ -368,6 +374,13 @@ final class ShareTopicsContainerNode: ASDisplayNode, ShareContentContainerNode {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public func updateTheme(_ theme: PresentationTheme) {
|
||||||
|
self.theme = theme
|
||||||
|
self.themePromise.set(.single(theme))
|
||||||
|
self.contentTitleNode.attributedText = NSAttributedString(string: self.contentTitleNode.attributedText?.string ?? "", font: Font.medium(20.0), textColor: self.theme.actionSheet.primaryTextColor)
|
||||||
|
self.contentSubtitleNode.attributedText = NSAttributedString(string: self.contentSubtitleNode.attributedText?.string ?? "", font: subtitleFont, textColor: self.theme.actionSheet.secondaryTextColor)
|
||||||
|
}
|
||||||
|
|
||||||
func updateLayout(size: CGSize, isLandscape: Bool, bottomInset: CGFloat, transition: ContainedViewLayoutTransition) {
|
func updateLayout(size: CGSize, isLandscape: Bool, bottomInset: CGFloat, transition: ContainedViewLayoutTransition) {
|
||||||
let firstLayout = self.validLayout == nil
|
let firstLayout = self.validLayout == nil
|
||||||
self.validLayout = (size, bottomInset)
|
self.validLayout = (size, bottomInset)
|
||||||
|
@ -690,6 +690,11 @@ final class VoiceChatPreviewContentNode: ASDisplayNode, ShareContentContainerNod
|
|||||||
self.contentOffsetUpdated = f
|
self.contentOffsetUpdated = f
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func updateTheme(_ theme: PresentationTheme) {
|
||||||
|
self.titleNode.attributedText = NSAttributedString(string: self.titleNode.attributedText?.string ?? "", font: Font.semibold(16.0), textColor: theme.actionSheet.primaryTextColor)
|
||||||
|
self.countNode.attributedText = NSAttributedString(string: self.countNode.attributedText?.string ?? "", font: Font.regular(16.0), textColor: theme.actionSheet.secondaryTextColor)
|
||||||
|
}
|
||||||
|
|
||||||
func updateLayout(size: CGSize, isLandscape: Bool, bottomInset: CGFloat, transition: ContainedViewLayoutTransition) {
|
func updateLayout(size: CGSize, isLandscape: Bool, bottomInset: CGFloat, transition: ContainedViewLayoutTransition) {
|
||||||
let sideInset: CGFloat = 16.0
|
let sideInset: CGFloat = 16.0
|
||||||
let titleSize = self.titleNode.updateLayout(CGSize(width: size.width - sideInset * 2.0, height: size.height))
|
let titleSize = self.titleNode.updateLayout(CGSize(width: size.width - sideInset * 2.0, height: size.height))
|
||||||
|
@ -895,9 +895,60 @@ private final class GroupHeaderLayer: UIView {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
var clearSize: CGSize = .zero
|
||||||
|
var clearWidth: CGFloat = 0.0
|
||||||
|
if hasClear {
|
||||||
|
var updateImage = themeUpdated
|
||||||
|
|
||||||
|
let clearIconLayer: SimpleLayer
|
||||||
|
if let current = self.clearIconLayer {
|
||||||
|
clearIconLayer = current
|
||||||
|
} else {
|
||||||
|
updateImage = true
|
||||||
|
clearIconLayer = SimpleLayer()
|
||||||
|
self.clearIconLayer = clearIconLayer
|
||||||
|
self.layer.addSublayer(clearIconLayer)
|
||||||
|
}
|
||||||
|
let tintClearIconLayer: SimpleLayer
|
||||||
|
if let current = self.tintClearIconLayer {
|
||||||
|
tintClearIconLayer = current
|
||||||
|
} else {
|
||||||
|
updateImage = true
|
||||||
|
tintClearIconLayer = SimpleLayer()
|
||||||
|
self.tintClearIconLayer = tintClearIconLayer
|
||||||
|
self.tintContentLayer.addSublayer(tintClearIconLayer)
|
||||||
|
}
|
||||||
|
|
||||||
|
tintClearIconLayer.isHidden = !needsVibrancy
|
||||||
|
|
||||||
|
clearSize = clearIconLayer.bounds.size
|
||||||
|
if updateImage, let image = PresentationResourcesChat.chatInputMediaPanelGridDismissImage(theme, color: theme.chat.inputMediaPanel.panelContentVibrantOverlayColor) {
|
||||||
|
clearSize = image.size
|
||||||
|
clearIconLayer.contents = image.cgImage
|
||||||
|
}
|
||||||
|
if updateImage, let image = PresentationResourcesChat.chatInputMediaPanelGridDismissImage(theme, color: .white) {
|
||||||
|
tintClearIconLayer.contents = image.cgImage
|
||||||
|
}
|
||||||
|
|
||||||
|
tintClearIconLayer.frame = clearIconLayer.frame
|
||||||
|
clearWidth = 4.0 + clearSize.width
|
||||||
|
} else {
|
||||||
|
if let clearIconLayer = self.clearIconLayer {
|
||||||
|
self.clearIconLayer = nil
|
||||||
|
clearIconLayer.removeFromSuperlayer()
|
||||||
|
}
|
||||||
|
if let tintClearIconLayer = self.tintClearIconLayer {
|
||||||
|
self.tintClearIconLayer = nil
|
||||||
|
tintClearIconLayer.removeFromSuperlayer()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
var textConstrainedWidth = constrainedSize.width - titleHorizontalOffset - 10.0
|
var textConstrainedWidth = constrainedSize.width - titleHorizontalOffset - 10.0
|
||||||
if let actionButtonSize = actionButtonSize {
|
if let actionButtonSize = actionButtonSize {
|
||||||
textConstrainedWidth -= actionButtonSize.width - 8.0
|
textConstrainedWidth -= actionButtonSize.width - 10.0
|
||||||
|
}
|
||||||
|
if clearWidth > 0.0 {
|
||||||
|
textConstrainedWidth -= clearWidth + 8.0
|
||||||
}
|
}
|
||||||
|
|
||||||
let textSize: CGSize
|
let textSize: CGSize
|
||||||
@ -915,13 +966,14 @@ private final class GroupHeaderLayer: UIView {
|
|||||||
}
|
}
|
||||||
let string = NSAttributedString(string: stringValue, font: font, textColor: color)
|
let string = NSAttributedString(string: stringValue, font: font, textColor: color)
|
||||||
let whiteString = NSAttributedString(string: stringValue, font: font, textColor: .white)
|
let whiteString = NSAttributedString(string: stringValue, font: font, textColor: .white)
|
||||||
let stringBounds = string.boundingRect(with: CGSize(width: textConstrainedWidth, height: 100.0), options: .usesLineFragmentOrigin, context: nil)
|
let stringBounds = string.boundingRect(with: CGSize(width: textConstrainedWidth, height: 18.0), options: [.usesLineFragmentOrigin, .truncatesLastVisibleLine], context: nil)
|
||||||
textSize = CGSize(width: ceil(stringBounds.width), height: ceil(stringBounds.height))
|
textSize = CGSize(width: ceil(stringBounds.width), height: ceil(stringBounds.height))
|
||||||
self.textLayer.contents = generateImage(textSize, opaque: false, scale: 0.0, rotatedContext: { size, context in
|
self.textLayer.contents = generateImage(textSize, opaque: false, scale: 0.0, rotatedContext: { size, context in
|
||||||
context.clear(CGRect(origin: CGPoint(), size: size))
|
context.clear(CGRect(origin: CGPoint(), size: size))
|
||||||
UIGraphicsPushContext(context)
|
UIGraphicsPushContext(context)
|
||||||
|
|
||||||
string.draw(in: stringBounds)
|
//string.draw(in: stringBounds)
|
||||||
|
string.draw(with: stringBounds, options: [.usesLineFragmentOrigin, .truncatesLastVisibleLine], context: nil)
|
||||||
|
|
||||||
UIGraphicsPopContext()
|
UIGraphicsPopContext()
|
||||||
})?.cgImage
|
})?.cgImage
|
||||||
@ -929,7 +981,8 @@ private final class GroupHeaderLayer: UIView {
|
|||||||
context.clear(CGRect(origin: CGPoint(), size: size))
|
context.clear(CGRect(origin: CGPoint(), size: size))
|
||||||
UIGraphicsPushContext(context)
|
UIGraphicsPushContext(context)
|
||||||
|
|
||||||
whiteString.draw(in: stringBounds)
|
//whiteString.draw(in: stringBounds)
|
||||||
|
whiteString.draw(with: stringBounds, options: [.usesLineFragmentOrigin, .truncatesLastVisibleLine], context: nil)
|
||||||
|
|
||||||
UIGraphicsPopContext()
|
UIGraphicsPopContext()
|
||||||
})?.cgImage
|
})?.cgImage
|
||||||
@ -1062,54 +1115,7 @@ private final class GroupHeaderLayer: UIView {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
var clearWidth: CGFloat = 0.0
|
self.clearIconLayer?.frame = CGRect(origin: CGPoint(x: constrainedSize.width - clearSize.width, y: floorToScreenPixels((textSize.height - clearSize.height) / 2.0)), size: clearSize)
|
||||||
if hasClear {
|
|
||||||
var updateImage = themeUpdated
|
|
||||||
|
|
||||||
let clearIconLayer: SimpleLayer
|
|
||||||
if let current = self.clearIconLayer {
|
|
||||||
clearIconLayer = current
|
|
||||||
} else {
|
|
||||||
updateImage = true
|
|
||||||
clearIconLayer = SimpleLayer()
|
|
||||||
self.clearIconLayer = clearIconLayer
|
|
||||||
self.layer.addSublayer(clearIconLayer)
|
|
||||||
}
|
|
||||||
let tintClearIconLayer: SimpleLayer
|
|
||||||
if let current = self.tintClearIconLayer {
|
|
||||||
tintClearIconLayer = current
|
|
||||||
} else {
|
|
||||||
updateImage = true
|
|
||||||
tintClearIconLayer = SimpleLayer()
|
|
||||||
self.tintClearIconLayer = tintClearIconLayer
|
|
||||||
self.tintContentLayer.addSublayer(tintClearIconLayer)
|
|
||||||
}
|
|
||||||
|
|
||||||
tintClearIconLayer.isHidden = !needsVibrancy
|
|
||||||
|
|
||||||
var clearSize = clearIconLayer.bounds.size
|
|
||||||
if updateImage, let image = PresentationResourcesChat.chatInputMediaPanelGridDismissImage(theme, color: theme.chat.inputMediaPanel.panelContentVibrantOverlayColor) {
|
|
||||||
clearSize = image.size
|
|
||||||
clearIconLayer.contents = image.cgImage
|
|
||||||
}
|
|
||||||
if updateImage, let image = PresentationResourcesChat.chatInputMediaPanelGridDismissImage(theme, color: .white) {
|
|
||||||
tintClearIconLayer.contents = image.cgImage
|
|
||||||
}
|
|
||||||
|
|
||||||
clearIconLayer.frame = CGRect(origin: CGPoint(x: constrainedSize.width - clearSize.width, y: floorToScreenPixels((textSize.height - clearSize.height) / 2.0)), size: clearSize)
|
|
||||||
|
|
||||||
tintClearIconLayer.frame = clearIconLayer.frame
|
|
||||||
clearWidth = 4.0 + clearSize.width
|
|
||||||
} else {
|
|
||||||
if let clearIconLayer = self.clearIconLayer {
|
|
||||||
self.clearIconLayer = nil
|
|
||||||
clearIconLayer.removeFromSuperlayer()
|
|
||||||
}
|
|
||||||
if let tintClearIconLayer = self.tintClearIconLayer {
|
|
||||||
self.tintClearIconLayer = nil
|
|
||||||
tintClearIconLayer.removeFromSuperlayer()
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
var size: CGSize
|
var size: CGSize
|
||||||
size = CGSize(width: constrainedSize.width, height: constrainedSize.height)
|
size = CGSize(width: constrainedSize.width, height: constrainedSize.height)
|
||||||
|
@ -14577,8 +14577,16 @@ public final class ChatControllerImpl: TelegramBaseController, ChatController, G
|
|||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
let replyMessageId = self.presentationInterfaceState.interfaceState.replyMessageId
|
var isScheduledMessages = false
|
||||||
|
if case .scheduledMessages = self.presentationInterfaceState.subject {
|
||||||
|
isScheduledMessages = true
|
||||||
|
}
|
||||||
|
|
||||||
|
let sendMessage: (Int32?) -> Void = { [weak self] scheduleTime in
|
||||||
|
guard let self else {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
let replyMessageId = self.presentationInterfaceState.interfaceState.replyMessageId
|
||||||
if self.context.engine.messages.enqueueOutgoingMessageWithChatContextResult(to: peerId, threadId: self.chatLocation.threadId, botId: results.botId, result: result, replyToMessageId: replyMessageId, hideVia: hideVia, silentPosting: silentPosting) {
|
if self.context.engine.messages.enqueueOutgoingMessageWithChatContextResult(to: peerId, threadId: self.chatLocation.threadId, botId: results.botId, result: result, replyToMessageId: replyMessageId, hideVia: hideVia, silentPosting: silentPosting) {
|
||||||
self.chatDisplayNode.setupSendActionOnViewUpdate({ [weak self] in
|
self.chatDisplayNode.setupSendActionOnViewUpdate({ [weak self] in
|
||||||
if let strongSelf = self {
|
if let strongSelf = self {
|
||||||
@ -14606,6 +14614,15 @@ public final class ChatControllerImpl: TelegramBaseController, ChatController, G
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if isScheduledMessages {
|
||||||
|
self.presentScheduleTimePicker(style: .default, dismissByTapOutside: false, completion: { time in
|
||||||
|
sendMessage(time)
|
||||||
|
})
|
||||||
|
} else {
|
||||||
|
sendMessage(nil)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
private func firstLoadedMessageToListen() -> Message? {
|
private func firstLoadedMessageToListen() -> Message? {
|
||||||
var messageToListen: Message?
|
var messageToListen: Message?
|
||||||
self.chatDisplayNode.historyNode.forEachMessageInCurrentHistoryView { message in
|
self.chatDisplayNode.historyNode.forEachMessageInCurrentHistoryView { message in
|
||||||
@ -14750,6 +14767,7 @@ public final class ChatControllerImpl: TelegramBaseController, ChatController, G
|
|||||||
self.chatDisplayNode.updateRecordedMediaDeleted(true)
|
self.chatDisplayNode.updateRecordedMediaDeleted(true)
|
||||||
self.audioRecorder.set(.single(nil))
|
self.audioRecorder.set(.single(nil))
|
||||||
case .preview:
|
case .preview:
|
||||||
|
self.audioRecorder.set(.single(nil))
|
||||||
self.updateChatPresentationInterfaceState(animated: true, interactive: true, {
|
self.updateChatPresentationInterfaceState(animated: true, interactive: true, {
|
||||||
$0.updatedInputTextPanelState { panelState in
|
$0.updatedInputTextPanelState { panelState in
|
||||||
return panelState.withUpdatedMediaRecordingState(.waitingForPreview)
|
return panelState.withUpdatedMediaRecordingState(.waitingForPreview)
|
||||||
@ -14779,7 +14797,6 @@ public final class ChatControllerImpl: TelegramBaseController, ChatController, G
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
self.audioRecorder.set(.single(nil))
|
|
||||||
case .send:
|
case .send:
|
||||||
self.chatDisplayNode.updateRecordedMediaDeleted(false)
|
self.chatDisplayNode.updateRecordedMediaDeleted(false)
|
||||||
let _ = (audioRecorderValue.takenRecordedData()
|
let _ = (audioRecorderValue.takenRecordedData()
|
||||||
|
@ -474,14 +474,29 @@ func searchQuerySuggestionResultStateForChatInterfacePresentationState(_ chatPre
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
let participants = searchPeerMembers(context: context, peerId: peer.id, chatLocation: chatPresentationInterfaceState.chatLocation, query: query, scope: .memberSuggestion)
|
let participants = combineLatest(
|
||||||
|> map { peers -> (ChatPresentationInputQueryResult?) -> ChatPresentationInputQueryResult? in
|
context.engine.data.get(TelegramEngine.EngineData.Item.Peer.Peer(id: context.account.peerId)),
|
||||||
|
searchPeerMembers(context: context, peerId: peer.id, chatLocation: chatPresentationInterfaceState.chatLocation, query: query, scope: .memberSuggestion)
|
||||||
|
)
|
||||||
|
|> map { accountPeer, peers -> (ChatPresentationInputQueryResult?) -> ChatPresentationInputQueryResult? in
|
||||||
let filteredPeers = peers
|
let filteredPeers = peers
|
||||||
var sortedPeers: [EnginePeer] = []
|
var sortedPeers: [EnginePeer] = []
|
||||||
sortedPeers.append(contentsOf: filteredPeers.sorted(by: { lhs, rhs in
|
sortedPeers.append(contentsOf: filteredPeers.sorted(by: { lhs, rhs in
|
||||||
let result = lhs.indexName.stringRepresentation(lastNameFirst: true).compare(rhs.indexName.stringRepresentation(lastNameFirst: true))
|
let result = lhs.indexName.stringRepresentation(lastNameFirst: true).compare(rhs.indexName.stringRepresentation(lastNameFirst: true))
|
||||||
return result == .orderedAscending
|
return result == .orderedAscending
|
||||||
}))
|
}))
|
||||||
|
if let accountPeer {
|
||||||
|
var hasOwnPeer = false
|
||||||
|
for peer in sortedPeers {
|
||||||
|
if peer.id == accountPeer.id {
|
||||||
|
hasOwnPeer = true
|
||||||
|
break
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if !hasOwnPeer {
|
||||||
|
sortedPeers.append(accountPeer)
|
||||||
|
}
|
||||||
|
}
|
||||||
return { _ in return .mentions(sortedPeers) }
|
return { _ in return .mentions(sortedPeers) }
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -401,7 +401,7 @@ class ChatMessageTextBubbleContentNode: ChatMessageBubbleContentNode {
|
|||||||
reactionPeers: dateReactionsAndPeers.peers,
|
reactionPeers: dateReactionsAndPeers.peers,
|
||||||
displayAllReactionPeers: item.message.id.peerId.namespace == Namespaces.Peer.CloudUser,
|
displayAllReactionPeers: item.message.id.peerId.namespace == Namespaces.Peer.CloudUser,
|
||||||
replyCount: dateReplies,
|
replyCount: dateReplies,
|
||||||
isPinned: item.message.tags.contains(.pinned) && !item.associatedData.isInPinnedListMode && isReplyThread,
|
isPinned: item.message.tags.contains(.pinned) && (!item.associatedData.isInPinnedListMode || isReplyThread),
|
||||||
hasAutoremove: item.message.isSelfExpiring,
|
hasAutoremove: item.message.isSelfExpiring,
|
||||||
canViewReactionList: canViewMessageReactionList(message: item.message),
|
canViewReactionList: canViewMessageReactionList(message: item.message),
|
||||||
animationCache: item.controllerInteraction.presentationContext.animationCache,
|
animationCache: item.controllerInteraction.presentationContext.animationCache,
|
||||||
|
@ -388,8 +388,12 @@ class ChatScheduleTimeControllerNode: ViewControllerTracingNode, UIScrollViewDel
|
|||||||
let titleHeight: CGFloat = 54.0
|
let titleHeight: CGFloat = 54.0
|
||||||
var contentHeight = titleHeight + bottomInset + 52.0 + 17.0
|
var contentHeight = titleHeight + bottomInset + 52.0 + 17.0
|
||||||
let pickerHeight: CGFloat = min(216.0, layout.size.height - contentHeight)
|
let pickerHeight: CGFloat = min(216.0, layout.size.height - contentHeight)
|
||||||
|
if let inputHeight = layout.inputHeight, inputHeight > 0.0, case .compact = layout.metrics.widthClass {
|
||||||
|
contentHeight = titleHeight + 52.0 + 17.0 + pickerHeight + inputHeight
|
||||||
|
buttonOffset = 0.0
|
||||||
|
} else {
|
||||||
contentHeight = titleHeight + bottomInset + 52.0 + 17.0 + pickerHeight + buttonOffset
|
contentHeight = titleHeight + bottomInset + 52.0 + 17.0 + pickerHeight + buttonOffset
|
||||||
|
}
|
||||||
let width = horizontalContainerFillingSizeForLayout(layout: layout, sideInset: 0.0)
|
let width = horizontalContainerFillingSizeForLayout(layout: layout, sideInset: 0.0)
|
||||||
|
|
||||||
let sideInset = floor((layout.size.width - width) / 2.0)
|
let sideInset = floor((layout.size.width - width) / 2.0)
|
||||||
@ -419,7 +423,7 @@ class ChatScheduleTimeControllerNode: ViewControllerTracingNode, UIScrollViewDel
|
|||||||
transition.updateFrame(node: self.doneButton, frame: CGRect(x: buttonInset, y: contentHeight - doneButtonHeight - insets.bottom - 16.0 - buttonOffset, width: contentFrame.width, height: doneButtonHeight))
|
transition.updateFrame(node: self.doneButton, frame: CGRect(x: buttonInset, y: contentHeight - doneButtonHeight - insets.bottom - 16.0 - buttonOffset, width: contentFrame.width, height: doneButtonHeight))
|
||||||
|
|
||||||
let onlineButtonHeight = self.onlineButton.updateLayout(width: contentFrame.width - buttonInset * 2.0, transition: transition)
|
let onlineButtonHeight = self.onlineButton.updateLayout(width: contentFrame.width - buttonInset * 2.0, transition: transition)
|
||||||
transition.updateFrame(node: self.onlineButton, frame: CGRect(x: buttonInset, y: contentHeight - onlineButtonHeight - insets.bottom - 16.0, width: contentFrame.width, height: onlineButtonHeight))
|
transition.updateFrame(node: self.onlineButton, frame: CGRect(x: buttonInset, y: contentHeight - onlineButtonHeight - cleanInsets.bottom - 16.0, width: contentFrame.width, height: onlineButtonHeight))
|
||||||
|
|
||||||
self.pickerView?.frame = CGRect(origin: CGPoint(x: 0.0, y: 54.0), size: CGSize(width: contentFrame.width, height: pickerHeight))
|
self.pickerView?.frame = CGRect(origin: CGPoint(x: 0.0, y: 54.0), size: CGSize(width: contentFrame.width, height: pickerHeight))
|
||||||
|
|
||||||
|
@ -1064,6 +1064,8 @@ class ChatTextInputPanelNode: ChatInputPanelNode, ASEditableTextNodeDelegate {
|
|||||||
let textFieldWaitsForTouchUp: Bool
|
let textFieldWaitsForTouchUp: Bool
|
||||||
if case .regular = metrics.widthClass, bottomInset.isZero {
|
if case .regular = metrics.widthClass, bottomInset.isZero {
|
||||||
textFieldWaitsForTouchUp = true
|
textFieldWaitsForTouchUp = true
|
||||||
|
} else if !textInputNode.textView.text.isEmpty {
|
||||||
|
textFieldWaitsForTouchUp = true
|
||||||
} else {
|
} else {
|
||||||
textFieldWaitsForTouchUp = false
|
textFieldWaitsForTouchUp = false
|
||||||
}
|
}
|
||||||
@ -1700,7 +1702,9 @@ class ChatTextInputPanelNode: ChatInputPanelNode, ASEditableTextNodeDelegate {
|
|||||||
hideInfo = true
|
hideInfo = true
|
||||||
}
|
}
|
||||||
case .waitingForPreview:
|
case .waitingForPreview:
|
||||||
break
|
Queue.mainQueue().after(0.3, {
|
||||||
|
self.actionButtons.micButton.audioRecorder = nil
|
||||||
|
})
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Loading…
x
Reference in New Issue
Block a user