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 = 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 = {}) {
|
||||
ready?.set(true)
|
||||
let action = { [weak self] in
|
||||
guard let self else {
|
||||
return
|
||||
}
|
||||
var controllers = controllers
|
||||
controllers.append(controller)
|
||||
self.setViewControllers(controllers, animated: animated)
|
||||
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 = {}) {
|
||||
ready?.set(true)
|
||||
|
@ -1654,7 +1654,7 @@ open class TextNode: ASDisplayNode {
|
||||
return (layout, {
|
||||
node.cachedLayout = layout
|
||||
if updated {
|
||||
if layout.size.width.isZero && layout.size.height.isZero {
|
||||
if layout.size.width.isZero || layout.size.height.isZero {
|
||||
node.contents = nil
|
||||
}
|
||||
node.setNeedsDisplay()
|
||||
|
@ -183,6 +183,10 @@ final class JoinLinkPreviewPeerContentNode: ASDisplayNode, ShareContentContainer
|
||||
self.contentOffsetUpdated = f
|
||||
}
|
||||
|
||||
func updateTheme(_ theme: PresentationTheme) {
|
||||
|
||||
}
|
||||
|
||||
func updateLayout(size: CGSize, isLandscape: Bool, bottomInset: CGFloat, transition: ContainedViewLayoutTransition) {
|
||||
let showPeers = !self.peerNodes.isEmpty && !isLandscape
|
||||
var nodeHeight: CGFloat = (!showPeers ? 236.0 : 320.0)
|
||||
@ -283,7 +287,7 @@ public enum ShareLoadingState {
|
||||
public final class JoinLinkPreviewLoadingContainerNode: ASDisplayNode, ShareContentContainerNode {
|
||||
private var contentOffsetUpdated: ((CGFloat, ContainedViewLayoutTransition) -> Void)?
|
||||
|
||||
private let theme: PresentationTheme
|
||||
private var theme: PresentationTheme
|
||||
private let activityIndicator: ActivityIndicator
|
||||
|
||||
public init(theme: PresentationTheme) {
|
||||
@ -308,6 +312,11 @@ public final class JoinLinkPreviewLoadingContainerNode: ASDisplayNode, ShareCont
|
||||
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) {
|
||||
let nodeHeight: CGFloat = 125.0
|
||||
|
||||
|
@ -82,6 +82,10 @@ final class LanguageLinkPreviewContentNode: ASDisplayNode, ShareContentContainer
|
||||
self.contentOffsetUpdated = f
|
||||
}
|
||||
|
||||
func updateTheme(_ theme: PresentationTheme) {
|
||||
|
||||
}
|
||||
|
||||
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 titleSpacing: CGFloat = 12.0
|
||||
|
@ -110,7 +110,9 @@ class EmojiHeaderComponent: Component {
|
||||
}
|
||||
|
||||
self.statusView.isHidden = false
|
||||
if containerView.subviews.count > 1 && containerView.subviews[1].subviews.count > 1 {
|
||||
containerView = containerView.subviews[1].subviews[1]
|
||||
}
|
||||
|
||||
let initialPosition = self.statusView.center
|
||||
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)
|
||||
}
|
||||
|
||||
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 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 expandItemView = self.expandItemView, expandItemView.frame.insetBy(dx: -20.0, dy: -20.0).contains(scrollPoint) {
|
||||
return nil
|
||||
}
|
||||
return closestItemNode.item
|
||||
}
|
||||
return nil
|
||||
|
@ -137,6 +137,7 @@ public func ChangePhoneNumberController(context: AccountContext) -> ViewControll
|
||||
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))
|
||||
}))
|
||||
}
|
||||
|
@ -3,6 +3,7 @@ import UIKit
|
||||
import Display
|
||||
import Postbox
|
||||
import TelegramCore
|
||||
import TelegramPresentationData
|
||||
|
||||
public protocol ShareContentContainerNode: AnyObject {
|
||||
func activate()
|
||||
@ -10,5 +11,6 @@ public protocol ShareContentContainerNode: AnyObject {
|
||||
func setEnsurePeerVisibleOnLayout(_ peerId: EnginePeer.Id?)
|
||||
func setContentOffsetUpdated(_ f: ((CGFloat, ContainedViewLayoutTransition) -> Void)?)
|
||||
func updateLayout(size: CGSize, isLandscape: Bool, bottomInset: CGFloat, transition: ContainedViewLayoutTransition)
|
||||
func updateTheme(_ theme: PresentationTheme)
|
||||
func updateSelectedPeers(animated: Bool)
|
||||
}
|
||||
|
@ -524,6 +524,8 @@ final class ShareControllerNode: ViewControllerTracingNode, UIScrollViewDelegate
|
||||
|
||||
self.actionButtonNode.badgeBackgroundColor = presentationData.theme.actionSheet.controlAccentColor
|
||||
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) {
|
||||
|
@ -45,7 +45,7 @@ final class ShareControllerGridSection: GridSection {
|
||||
|
||||
func isEqual(to: GridSection) -> Bool {
|
||||
if let to = to as? ShareControllerGridSection {
|
||||
return self.title == to.title
|
||||
return self.title == to.title && self.theme === to.theme
|
||||
} else {
|
||||
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) {
|
||||
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 timestamp = Int32(CFAbsoluteTimeGetCurrent() + NSTimeIntervalSince1970)
|
||||
|
@ -54,7 +54,7 @@ final class ShareControllerRecentPeersGridItemNode: GridItemNode {
|
||||
}
|
||||
|
||||
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
|
||||
if let currentPeersNode = self.peersNode {
|
||||
peersNode = currentPeersNode
|
||||
|
@ -27,7 +27,7 @@ protocol ShareLoadingContainer: ASDisplayNode {
|
||||
public final class ShareLoadingContainerNode: ASDisplayNode, ShareContentContainerNode, ShareLoadingContainer {
|
||||
private var contentOffsetUpdated: ((CGFloat, ContainedViewLayoutTransition) -> Void)?
|
||||
|
||||
private let theme: PresentationTheme
|
||||
private var theme: PresentationTheme
|
||||
private let activityIndicator: ActivityIndicator
|
||||
private let statusNode: RadialStatusNode
|
||||
private let doneStatusNode: RadialStatusNode
|
||||
@ -78,6 +78,10 @@ public final class ShareLoadingContainerNode: ASDisplayNode, ShareContentContain
|
||||
self.contentOffsetUpdated = f
|
||||
}
|
||||
|
||||
public func updateTheme(_ theme: PresentationTheme) {
|
||||
self.theme = theme
|
||||
}
|
||||
|
||||
public func updateLayout(size: CGSize, isLandscape: Bool, bottomInset: CGFloat, transition: ContainedViewLayoutTransition) {
|
||||
let nodeHeight: CGFloat = 125.0
|
||||
|
||||
@ -98,7 +102,7 @@ public final class ShareLoadingContainerNode: ASDisplayNode, ShareContentContain
|
||||
public final class ShareProlongedLoadingContainerNode: ASDisplayNode, ShareContentContainerNode, ShareLoadingContainer {
|
||||
private var contentOffsetUpdated: ((CGFloat, ContainedViewLayoutTransition) -> Void)?
|
||||
|
||||
private let theme: PresentationTheme
|
||||
private var theme: PresentationTheme
|
||||
private let strings: PresentationStrings
|
||||
|
||||
private let animationNode: AnimatedStickerNode
|
||||
@ -271,6 +275,10 @@ public final class ShareProlongedLoadingContainerNode: ASDisplayNode, ShareConte
|
||||
self.animationStatusDisposable.dispose()
|
||||
}
|
||||
|
||||
public func updateTheme(_ theme: PresentationTheme) {
|
||||
self.theme = theme
|
||||
}
|
||||
|
||||
public func activate() {
|
||||
}
|
||||
|
||||
|
@ -65,6 +65,9 @@ private struct SharePeerEntry: Comparable, Identifiable {
|
||||
if lhs.threadData != rhs.threadData {
|
||||
return false
|
||||
}
|
||||
if lhs.theme !== rhs.theme {
|
||||
return false
|
||||
}
|
||||
|
||||
return true
|
||||
}
|
||||
@ -100,7 +103,8 @@ private func preparedGridEntryTransition(context: AccountContext, from fromEntri
|
||||
final class SharePeersContainerNode: ASDisplayNode, ShareContentContainerNode {
|
||||
private let sharedContext: SharedAccountContext
|
||||
private let context: AccountContext
|
||||
private let theme: PresentationTheme
|
||||
private var theme: PresentationTheme
|
||||
private let themePromise: Promise<PresentationTheme>
|
||||
private let strings: PresentationStrings
|
||||
private let nameDisplayOrder: PresentationPersonNameOrder
|
||||
private let controllerInteraction: ShareControllerInteraction
|
||||
@ -153,6 +157,8 @@ final class SharePeersContainerNode: ASDisplayNode, ShareContentContainerNode {
|
||||
self.sharedContext = sharedContext
|
||||
self.context = context
|
||||
self.theme = theme
|
||||
self.themePromise = Promise()
|
||||
self.themePromise.set(.single(theme))
|
||||
self.strings = strings
|
||||
self.nameDisplayOrder = nameDisplayOrder
|
||||
self.controllerInteraction = controllerInteraction
|
||||
@ -164,8 +170,8 @@ final class SharePeersContainerNode: ASDisplayNode, ShareContentContainerNode {
|
||||
|
||||
self.peersValue.set(.single(peers))
|
||||
|
||||
let items: Signal<[SharePeerEntry], NoError> = combineLatest(self.peersValue.get(), self.foundPeers.get(), self.tick.get())
|
||||
|> map { [weak controllerInteraction] initialPeers, foundPeers, _ -> [SharePeerEntry] in
|
||||
let items: Signal<[SharePeerEntry], NoError> = combineLatest(self.peersValue.get(), self.foundPeers.get(), self.tick.get(), self.themePromise.get())
|
||||
|> map { [weak controllerInteraction] initialPeers, foundPeers, _, theme -> [SharePeerEntry] in
|
||||
var entries: [SharePeerEntry] = []
|
||||
var index: Int32 = 0
|
||||
|
||||
@ -303,6 +309,13 @@ final class SharePeersContainerNode: ASDisplayNode, ShareContentContainerNode {
|
||||
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) {
|
||||
self.enqueuedTransitions.append((transition, firstTime))
|
||||
|
||||
|
@ -42,12 +42,10 @@ final class ShareSearchBarNode: ASDisplayNode, UITextFieldDelegate {
|
||||
self.textInputNode = TextFieldNode()
|
||||
self.textInputNode.fixOffset = false
|
||||
let textColor: UIColor = theme.actionSheet.inputTextColor
|
||||
let keyboardAppearance: UIKeyboardAppearance = UIKeyboardAppearance.default
|
||||
self.textInputNode.textField.font = Font.regular(16.0)
|
||||
self.textInputNode.textField.textColor = 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.textField.keyboardAppearance = keyboardAppearance
|
||||
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.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)))
|
||||
}
|
||||
|
||||
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() {
|
||||
self.textInputNode.textField.becomeFirstResponder()
|
||||
}
|
||||
|
@ -121,6 +121,9 @@ private struct ShareSearchPeerEntry: Comparable, Identifiable {
|
||||
if lhs.peer != rhs.peer {
|
||||
return false
|
||||
}
|
||||
if lhs.theme !== rhs.theme {
|
||||
return false
|
||||
}
|
||||
return true
|
||||
}
|
||||
|
||||
@ -164,6 +167,8 @@ private func preparedRecentEntryTransition(context: AccountContext, from fromEnt
|
||||
final class ShareSearchContainerNode: ASDisplayNode, ShareContentContainerNode {
|
||||
private let sharedContext: SharedAccountContext
|
||||
private let context: AccountContext
|
||||
private var theme: PresentationTheme
|
||||
private let themePromise: Promise<PresentationTheme>
|
||||
private let strings: PresentationStrings
|
||||
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]) {
|
||||
self.sharedContext = sharedContext
|
||||
self.context = context
|
||||
self.theme = theme
|
||||
self.themePromise = Promise<PresentationTheme>()
|
||||
self.themePromise.set(.single(theme))
|
||||
self.strings = strings
|
||||
self.controllerInteraction = controllerInteraction
|
||||
|
||||
@ -237,8 +245,8 @@ final class ShareSearchContainerNode: ASDisplayNode, ShareContentContainerNode {
|
||||
|
||||
self.cancelButtonNode.addTarget(self, action: #selector(self.cancelPressed), forControlEvents: .touchUpInside)
|
||||
|
||||
let foundItems = self.searchQuery.get()
|
||||
|> mapToSignal { query -> Signal<([ShareSearchPeerEntry]?, Bool), NoError> in
|
||||
let foundItems = combineLatest(self.searchQuery.get(), self.themePromise.get())
|
||||
|> mapToSignal { query, theme -> Signal<([ShareSearchPeerEntry]?, Bool), NoError> in
|
||||
if !query.isEmpty {
|
||||
let accountPeer = context.account.postbox.loadedPeerWithId(context.account.peerId) |> take(1)
|
||||
let foundLocalPeers = context.account.postbox.searchPeers(query: query.lowercased())
|
||||
@ -354,8 +362,8 @@ final class ShareSearchContainerNode: ASDisplayNode, ShareContentContainerNode {
|
||||
}
|
||||
|> distinctUntilChanged
|
||||
|
||||
let recentItems: Signal<[ShareSearchRecentEntry], NoError> = hasRecentPeers
|
||||
|> map { hasRecentPeers -> [ShareSearchRecentEntry] in
|
||||
let recentItems: Signal<[ShareSearchRecentEntry], NoError> = combineLatest(hasRecentPeers, self.themePromise.get())
|
||||
|> map { hasRecentPeers, theme -> [ShareSearchRecentEntry] in
|
||||
var recentItemList: [ShareSearchRecentEntry] = []
|
||||
if hasRecentPeers {
|
||||
recentItemList.append(.topPeers(theme, strings))
|
||||
@ -404,6 +412,14 @@ final class ShareSearchContainerNode: ASDisplayNode, ShareContentContainerNode {
|
||||
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) {
|
||||
let itemCount: Int
|
||||
if self.contentGridNode.isHidden {
|
||||
|
@ -42,6 +42,9 @@ private struct ShareTopicEntry: Comparable, Identifiable {
|
||||
if lhs.threadData != rhs.threadData {
|
||||
return false
|
||||
}
|
||||
if lhs.theme !== rhs.theme {
|
||||
return false
|
||||
}
|
||||
|
||||
return true
|
||||
}
|
||||
@ -157,7 +160,8 @@ final class ShareTopicsContainerNode: ASDisplayNode, ShareContentContainerNode {
|
||||
|
||||
private let sharedContext: SharedAccountContext
|
||||
private let context: AccountContext
|
||||
private let theme: PresentationTheme
|
||||
private var theme: PresentationTheme
|
||||
private let themePromise: Promise<PresentationTheme>
|
||||
private let strings: PresentationStrings
|
||||
private let controllerInteraction: ShareControllerInteraction
|
||||
|
||||
@ -184,6 +188,8 @@ final class ShareTopicsContainerNode: ASDisplayNode, ShareContentContainerNode {
|
||||
self.sharedContext = sharedContext
|
||||
self.context = context
|
||||
self.theme = theme
|
||||
self.themePromise = Promise()
|
||||
self.themePromise.set(.single(theme))
|
||||
self.strings = strings
|
||||
self.controllerInteraction = controllerInteraction
|
||||
|
||||
@ -192,8 +198,8 @@ final class ShareTopicsContainerNode: ASDisplayNode, ShareContentContainerNode {
|
||||
return $0.items
|
||||
})
|
||||
|
||||
let items: Signal<[ShareTopicEntry], NoError> = self.topicsValue.get()
|
||||
|> map { topics -> [ShareTopicEntry] in
|
||||
let items: Signal<[ShareTopicEntry], NoError> = (combineLatest(self.topicsValue.get(), self.themePromise.get()))
|
||||
|> map { topics, theme -> [ShareTopicEntry] in
|
||||
var entries: [ShareTopicEntry] = []
|
||||
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) {
|
||||
let firstLayout = self.validLayout == nil
|
||||
self.validLayout = (size, bottomInset)
|
||||
|
@ -690,6 +690,11 @@ final class VoiceChatPreviewContentNode: ASDisplayNode, ShareContentContainerNod
|
||||
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) {
|
||||
let sideInset: CGFloat = 16.0
|
||||
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
|
||||
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
|
||||
@ -915,13 +966,14 @@ private final class GroupHeaderLayer: UIView {
|
||||
}
|
||||
let string = NSAttributedString(string: stringValue, font: font, textColor: color)
|
||||
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))
|
||||
self.textLayer.contents = generateImage(textSize, opaque: false, scale: 0.0, rotatedContext: { size, context in
|
||||
context.clear(CGRect(origin: CGPoint(), size: size))
|
||||
UIGraphicsPushContext(context)
|
||||
|
||||
string.draw(in: stringBounds)
|
||||
//string.draw(in: stringBounds)
|
||||
string.draw(with: stringBounds, options: [.usesLineFragmentOrigin, .truncatesLastVisibleLine], context: nil)
|
||||
|
||||
UIGraphicsPopContext()
|
||||
})?.cgImage
|
||||
@ -929,7 +981,8 @@ private final class GroupHeaderLayer: UIView {
|
||||
context.clear(CGRect(origin: CGPoint(), size: size))
|
||||
UIGraphicsPushContext(context)
|
||||
|
||||
whiteString.draw(in: stringBounds)
|
||||
//whiteString.draw(in: stringBounds)
|
||||
whiteString.draw(with: stringBounds, options: [.usesLineFragmentOrigin, .truncatesLastVisibleLine], context: nil)
|
||||
|
||||
UIGraphicsPopContext()
|
||||
})?.cgImage
|
||||
@ -1062,54 +1115,7 @@ private final class GroupHeaderLayer: UIView {
|
||||
}
|
||||
}
|
||||
|
||||
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
|
||||
|
||||
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()
|
||||
}
|
||||
}
|
||||
self.clearIconLayer?.frame = CGRect(origin: CGPoint(x: constrainedSize.width - clearSize.width, y: floorToScreenPixels((textSize.height - clearSize.height) / 2.0)), size: clearSize)
|
||||
|
||||
var size: CGSize
|
||||
size = CGSize(width: constrainedSize.width, height: constrainedSize.height)
|
||||
|
@ -14577,8 +14577,16 @@ public final class ChatControllerImpl: TelegramBaseController, ChatController, G
|
||||
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) {
|
||||
self.chatDisplayNode.setupSendActionOnViewUpdate({ [weak self] in
|
||||
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? {
|
||||
var messageToListen: Message?
|
||||
self.chatDisplayNode.historyNode.forEachMessageInCurrentHistoryView { message in
|
||||
@ -14750,6 +14767,7 @@ public final class ChatControllerImpl: TelegramBaseController, ChatController, G
|
||||
self.chatDisplayNode.updateRecordedMediaDeleted(true)
|
||||
self.audioRecorder.set(.single(nil))
|
||||
case .preview:
|
||||
self.audioRecorder.set(.single(nil))
|
||||
self.updateChatPresentationInterfaceState(animated: true, interactive: true, {
|
||||
$0.updatedInputTextPanelState { panelState in
|
||||
return panelState.withUpdatedMediaRecordingState(.waitingForPreview)
|
||||
@ -14779,7 +14797,6 @@ public final class ChatControllerImpl: TelegramBaseController, ChatController, G
|
||||
}
|
||||
}
|
||||
})
|
||||
self.audioRecorder.set(.single(nil))
|
||||
case .send:
|
||||
self.chatDisplayNode.updateRecordedMediaDeleted(false)
|
||||
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)
|
||||
|> map { peers -> (ChatPresentationInputQueryResult?) -> ChatPresentationInputQueryResult? in
|
||||
let participants = combineLatest(
|
||||
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
|
||||
var sortedPeers: [EnginePeer] = []
|
||||
sortedPeers.append(contentsOf: filteredPeers.sorted(by: { lhs, rhs in
|
||||
let result = lhs.indexName.stringRepresentation(lastNameFirst: true).compare(rhs.indexName.stringRepresentation(lastNameFirst: true))
|
||||
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) }
|
||||
}
|
||||
|
||||
|
@ -401,7 +401,7 @@ class ChatMessageTextBubbleContentNode: ChatMessageBubbleContentNode {
|
||||
reactionPeers: dateReactionsAndPeers.peers,
|
||||
displayAllReactionPeers: item.message.id.peerId.namespace == Namespaces.Peer.CloudUser,
|
||||
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,
|
||||
canViewReactionList: canViewMessageReactionList(message: item.message),
|
||||
animationCache: item.controllerInteraction.presentationContext.animationCache,
|
||||
|
@ -388,8 +388,12 @@ class ChatScheduleTimeControllerNode: ViewControllerTracingNode, UIScrollViewDel
|
||||
let titleHeight: CGFloat = 54.0
|
||||
var contentHeight = titleHeight + bottomInset + 52.0 + 17.0
|
||||
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
|
||||
|
||||
}
|
||||
let width = horizontalContainerFillingSizeForLayout(layout: layout, sideInset: 0.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))
|
||||
|
||||
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))
|
||||
|
||||
|
@ -1064,6 +1064,8 @@ class ChatTextInputPanelNode: ChatInputPanelNode, ASEditableTextNodeDelegate {
|
||||
let textFieldWaitsForTouchUp: Bool
|
||||
if case .regular = metrics.widthClass, bottomInset.isZero {
|
||||
textFieldWaitsForTouchUp = true
|
||||
} else if !textInputNode.textView.text.isEmpty {
|
||||
textFieldWaitsForTouchUp = true
|
||||
} else {
|
||||
textFieldWaitsForTouchUp = false
|
||||
}
|
||||
@ -1700,7 +1702,9 @@ class ChatTextInputPanelNode: ChatInputPanelNode, ASEditableTextNodeDelegate {
|
||||
hideInfo = true
|
||||
}
|
||||
case .waitingForPreview:
|
||||
break
|
||||
Queue.mainQueue().after(0.3, {
|
||||
self.actionButtons.micButton.audioRecorder = nil
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
|
Loading…
x
Reference in New Issue
Block a user