mirror of
https://github.com/Swiftgram/Telegram-iOS.git
synced 2025-10-08 19:10:53 +00:00
Various Fixes
This commit is contained in:
parent
857122fe72
commit
d43415d4fd
@ -7224,3 +7224,7 @@ Sorry for the inconvenience.";
|
||||
"Chat.OutgoingContextReactionCount_1" = "1 reacted";
|
||||
"Chat.OutgoingContextReactionCount_any" = "%@ reacted";
|
||||
"Chat.OutgoingContextMixedReactionCount" = "%1$@/%2$@ reacted";
|
||||
|
||||
"Contacts.Sort" = "Sort";
|
||||
"Contacts.Sort.ByName" = "by Name";
|
||||
"Contacts.Sort.ByLastSeen" = "by Last Seen";
|
||||
|
@ -1757,7 +1757,7 @@ class ChatListItemNode: ItemListRevealOptionsItemNode {
|
||||
strongSelf.dustNode = dustNode
|
||||
strongSelf.contextContainer.insertSubnode(dustNode, aboveSubnode: strongSelf.textNode)
|
||||
}
|
||||
dustNode.update(size: textNodeFrame.size, color: theme.messageTextColor, rects: textLayout.spoilers.map { $0.1.offsetBy(dx: 3.0, dy: 3.0).insetBy(dx: 0.0, dy: 1.0) }, wordRects: textLayout.spoilerWords.map { $0.1.offsetBy(dx: 3.0, dy: 3.0).insetBy(dx: 0.0, dy: 1.0) })
|
||||
dustNode.update(size: textNodeFrame.size, color: theme.messageTextColor, textColor: theme.messageTextColor, rects: textLayout.spoilers.map { $0.1.offsetBy(dx: 3.0, dy: 3.0).insetBy(dx: 0.0, dy: 1.0) }, wordRects: textLayout.spoilerWords.map { $0.1.offsetBy(dx: 3.0, dy: 3.0).insetBy(dx: 0.0, dy: 1.0) })
|
||||
dustNode.frame = textNodeFrame.insetBy(dx: -3.0, dy: -3.0).offsetBy(dx: 0.0, dy: 3.0)
|
||||
|
||||
} else if let dustNode = strongSelf.dustNode {
|
||||
|
@ -96,7 +96,6 @@ private enum ContactListNodeEntryId: Hashable {
|
||||
|
||||
private final class ContactListNodeInteraction {
|
||||
fileprivate let activateSearch: () -> Void
|
||||
fileprivate let openSortMenu: () -> Void
|
||||
fileprivate let authorize: () -> Void
|
||||
fileprivate let suppressWarning: () -> Void
|
||||
fileprivate let openPeer: (ContactListPeer, ContactListAction) -> Void
|
||||
@ -104,9 +103,8 @@ private final class ContactListNodeInteraction {
|
||||
|
||||
let itemHighlighting = ContactItemHighlighting()
|
||||
|
||||
init(activateSearch: @escaping () -> Void, openSortMenu: @escaping () -> Void, authorize: @escaping () -> Void, suppressWarning: @escaping () -> Void, openPeer: @escaping (ContactListPeer, ContactListAction) -> Void, contextAction: ((EnginePeer, ASDisplayNode, ContextGesture?) -> Void)?) {
|
||||
init(activateSearch: @escaping () -> Void, authorize: @escaping () -> Void, suppressWarning: @escaping () -> Void, openPeer: @escaping (ContactListPeer, ContactListAction) -> Void, contextAction: ((EnginePeer, ASDisplayNode, ContextGesture?) -> Void)?) {
|
||||
self.activateSearch = activateSearch
|
||||
self.openSortMenu = openSortMenu
|
||||
self.authorize = authorize
|
||||
self.suppressWarning = suppressWarning
|
||||
self.openPeer = openPeer
|
||||
@ -162,7 +160,6 @@ private enum ContactListNodeEntry: Comparable, Identifiable {
|
||||
text = strings.Contacts_SortedByPresence
|
||||
}
|
||||
return ContactListActionItem(presentationData: ItemListPresentationData(presentationData), title: text, icon: .inline(dropDownIcon, .right), highlight: .alpha, accessible: false, header: nil, action: {
|
||||
interaction.openSortMenu()
|
||||
})
|
||||
case let .permissionInfo(_, title, text, suppressed):
|
||||
return InfoListItem(presentationData: ItemListPresentationData(presentationData), title: title, text: .plain(text), style: .plain, closeAction: suppressed ? nil : {
|
||||
@ -442,11 +439,7 @@ private func contactListNodeEntries(accountPeer: EnginePeer?, peers: [ContactLis
|
||||
var commonHeader: ListViewItemHeader?
|
||||
var orderedPeers: [ContactListPeer]
|
||||
var headers: [ContactListPeerId: ContactListNameIndexHeader] = [:]
|
||||
|
||||
if displaySortOptions, let sortOrder = presentation.sortOrder {
|
||||
entries.append(.sort(theme, strings, sortOrder))
|
||||
}
|
||||
|
||||
|
||||
var addHeader = false
|
||||
if #available(iOSApplicationExtension 10.0, iOS 10.0, *) {
|
||||
let (suppressed, syncDisabled) = warningSuppressed
|
||||
@ -867,7 +860,6 @@ public final class ContactListNode: ASDisplayNode {
|
||||
public var contentScrollingEnded: ((ListView) -> Bool)?
|
||||
|
||||
public var activateSearch: (() -> Void)?
|
||||
public var openSortMenu: (() -> Void)?
|
||||
public var openPeer: ((ContactListPeer, ContactListAction) -> Void)?
|
||||
public var openPrivacyPolicy: (() -> Void)?
|
||||
public var suppressPermissionWarning: (() -> Void)?
|
||||
@ -955,8 +947,6 @@ public final class ContactListNode: ASDisplayNode {
|
||||
|
||||
let interaction = ContactListNodeInteraction(activateSearch: { [weak self] in
|
||||
self?.activateSearch?()
|
||||
}, openSortMenu: { [weak self] in
|
||||
self?.openSortMenu?()
|
||||
}, authorize: {
|
||||
authorizeImpl?()
|
||||
}, suppressWarning: { [weak self] in
|
||||
|
@ -20,20 +20,90 @@ import StickerResources
|
||||
import ContextUI
|
||||
import QrCodeUI
|
||||
|
||||
private func fixListNodeScrolling(_ listNode: ListView, searchNode: NavigationBarSearchContentNode) -> Bool {
|
||||
if searchNode.expansionProgress > 0.0 && searchNode.expansionProgress < 1.0 {
|
||||
let scrollToItem: ListViewScrollToItem
|
||||
let targetProgress: CGFloat
|
||||
if searchNode.expansionProgress < 0.6 {
|
||||
scrollToItem = ListViewScrollToItem(index: 1, position: .top(-navigationBarSearchContentHeight), animated: true, curve: .Default(duration: nil), directionHint: .Up)
|
||||
targetProgress = 0.0
|
||||
} else {
|
||||
scrollToItem = ListViewScrollToItem(index: 1, position: .top(0.0), animated: true, curve: .Default(duration: nil), directionHint: .Up)
|
||||
targetProgress = 1.0
|
||||
private final class HeaderContextReferenceContentSource: ContextReferenceContentSource {
|
||||
private let controller: ViewController
|
||||
private let sourceNode: ContextReferenceContentNode
|
||||
|
||||
init(controller: ViewController, sourceNode: ContextReferenceContentNode) {
|
||||
self.controller = controller
|
||||
self.sourceNode = sourceNode
|
||||
}
|
||||
|
||||
func transitionInfo() -> ContextControllerReferenceViewInfo? {
|
||||
return ContextControllerReferenceViewInfo(referenceNode: self.sourceNode, contentAreaInScreenSpace: UIScreen.main.bounds)
|
||||
}
|
||||
}
|
||||
|
||||
private final class SortHeaderButton: HighlightableButtonNode {
|
||||
let referenceNode: ContextReferenceContentNode
|
||||
let containerNode: ContextControllerSourceNode
|
||||
private let textNode: ImmediateTextNode
|
||||
|
||||
var contextAction: ((ASDisplayNode, ContextGesture?) -> Void)?
|
||||
|
||||
init(presentationData: PresentationData) {
|
||||
self.referenceNode = ContextReferenceContentNode()
|
||||
self.containerNode = ContextControllerSourceNode()
|
||||
self.containerNode.animateScale = false
|
||||
self.textNode = ImmediateTextNode()
|
||||
self.textNode.displaysAsynchronously = false
|
||||
|
||||
super.init()
|
||||
|
||||
self.containerNode.addSubnode(self.referenceNode)
|
||||
self.referenceNode.addSubnode(self.textNode)
|
||||
self.addSubnode(self.containerNode)
|
||||
|
||||
self.containerNode.shouldBegin = { [weak self] location in
|
||||
guard let strongSelf = self, let _ = strongSelf.contextAction else {
|
||||
return false
|
||||
}
|
||||
return true
|
||||
}
|
||||
searchNode.updateExpansionProgress(targetProgress, animated: true)
|
||||
self.containerNode.activated = { [weak self] gesture, _ in
|
||||
guard let strongSelf = self else {
|
||||
return
|
||||
}
|
||||
strongSelf.contextAction?(strongSelf.containerNode, gesture)
|
||||
}
|
||||
|
||||
self.containerNode.frame = CGRect(origin: CGPoint(), size: CGSize(width: 26.0, height: 44.0))
|
||||
self.referenceNode.frame = self.containerNode.bounds
|
||||
|
||||
listNode.transaction(deleteIndices: [], insertIndicesAndItems: [], updateIndicesAndItems: [], options: ListViewDeleteAndInsertOptions(), scrollToItem: scrollToItem, updateSizeAndInsets: nil, stationaryItemRange: nil, updateOpaqueState: nil, completion: { _ in })
|
||||
self.update(theme: presentationData.theme, strings: presentationData.strings)
|
||||
}
|
||||
|
||||
override func didLoad() {
|
||||
super.didLoad()
|
||||
self.view.isOpaque = false
|
||||
}
|
||||
|
||||
func update(theme: PresentationTheme, strings: PresentationStrings) {
|
||||
self.textNode.attributedText = NSAttributedString(string: strings.Contacts_Sort, font: Font.regular(17.0), textColor: theme.rootController.navigationBar.accentTextColor)
|
||||
let size = self.textNode.updateLayout(CGSize(width: 100.0, height: 44.0))
|
||||
self.textNode.frame = CGRect(origin: CGPoint(x: 0.0, y: floorToScreenPixels((44.0 - size.height) / 2.0)), size: size)
|
||||
}
|
||||
|
||||
override func calculateSizeThatFits(_ constrainedSize: CGSize) -> CGSize {
|
||||
return CGSize(width: 44.0, height: 44.0)
|
||||
}
|
||||
|
||||
func onLayout() {
|
||||
}
|
||||
}
|
||||
|
||||
private func fixListNodeScrolling(_ listNode: ListView, searchNode: NavigationBarSearchContentNode) -> Bool {
|
||||
if listNode.scroller.isDragging {
|
||||
return false
|
||||
}
|
||||
if searchNode.expansionProgress > 0.0 && searchNode.expansionProgress < 1.0 {
|
||||
let offset: CGFloat
|
||||
if searchNode.expansionProgress < 0.6 {
|
||||
offset = navigationBarSearchContentHeight
|
||||
} else {
|
||||
offset = 0.0
|
||||
}
|
||||
let _ = listNode.scrollToOffsetFromTop(offset)
|
||||
return true
|
||||
} else if searchNode.expansionProgress == 1.0 {
|
||||
var sortItemNode: ListViewItemNode?
|
||||
@ -47,14 +117,14 @@ private func fixListNodeScrolling(_ listNode: ListView, searchNode: NavigationBa
|
||||
}
|
||||
})
|
||||
|
||||
if let sortItemNode = sortItemNode {
|
||||
if false, let sortItemNode = sortItemNode {
|
||||
let itemFrame = sortItemNode.apparentFrame
|
||||
if itemFrame.contains(CGPoint(x: 0.0, y: listNode.insets.top)) {
|
||||
var scrollToItem: ListViewScrollToItem?
|
||||
if itemFrame.minY + itemFrame.height * 0.6 < listNode.insets.top {
|
||||
scrollToItem = ListViewScrollToItem(index: 0, position: .top(-50), animated: true, curve: .Default(duration: nil), directionHint: .Up)
|
||||
scrollToItem = ListViewScrollToItem(index: 0, position: .top(-76.0), animated: true, curve: .Default(duration: 0.3), directionHint: .Up)
|
||||
} else {
|
||||
scrollToItem = ListViewScrollToItem(index: 0, position: .top(0), animated: true, curve: .Default(duration: nil), directionHint: .Up)
|
||||
scrollToItem = ListViewScrollToItem(index: 0, position: .top(0), animated: true, curve: .Default(duration: 0.3), directionHint: .Up)
|
||||
}
|
||||
listNode.transaction(deleteIndices: [], insertIndicesAndItems: [], updateIndicesAndItems: [], options: ListViewDeleteAndInsertOptions(), scrollToItem: scrollToItem, updateSizeAndInsets: nil, stationaryItemRange: nil, updateOpaqueState: nil, completion: { _ in })
|
||||
return true
|
||||
@ -95,11 +165,15 @@ public class ContactsController: ViewController {
|
||||
}
|
||||
}
|
||||
|
||||
private let sortButton: SortHeaderButton
|
||||
|
||||
public init(context: AccountContext) {
|
||||
self.context = context
|
||||
|
||||
self.presentationData = context.sharedContext.currentPresentationData.with { $0 }
|
||||
|
||||
self.sortButton = SortHeaderButton(presentationData: self.presentationData)
|
||||
|
||||
super.init(navigationBarPresentationData: NavigationBarPresentationData(presentationData: self.presentationData))
|
||||
|
||||
self.tabBarItemContextActionType = .always
|
||||
@ -120,6 +194,8 @@ public class ContactsController: ViewController {
|
||||
self.tabBarItem.selectedImage = icon
|
||||
|
||||
self.navigationItem.backBarButtonItem = UIBarButtonItem(title: self.presentationData.strings.Common_Back, style: .plain, target: nil, action: nil)
|
||||
|
||||
self.navigationItem.leftBarButtonItem = UIBarButtonItem(customDisplayNode: self.sortButton)
|
||||
self.navigationItem.rightBarButtonItem = UIBarButtonItem(image: PresentationResourcesRootController.navigationAddIcon(self.presentationData.theme), style: .plain, target: self, action: #selector(self.addPressed))
|
||||
self.navigationItem.rightBarButtonItem?.accessibilityLabel = self.presentationData.strings.Contacts_VoiceOver_AddContact
|
||||
|
||||
@ -184,6 +260,8 @@ public class ContactsController: ViewController {
|
||||
self?.activateSearch()
|
||||
})
|
||||
self.navigationBar?.setContentNode(self.searchContentNode, animated: false)
|
||||
|
||||
self.sortButton.addTarget(self, action: #selector(self.sortPressed), forControlEvents: .touchUpInside)
|
||||
}
|
||||
|
||||
required public init(coder aDecoder: NSCoder) {
|
||||
@ -196,6 +274,7 @@ public class ContactsController: ViewController {
|
||||
}
|
||||
|
||||
private func updateThemeAndStrings() {
|
||||
self.sortButton.update(theme: self.presentationData.theme, strings: self.presentationData.strings)
|
||||
self.statusBar.statusBarStyle = self.presentationData.theme.rootController.statusBarStyle.style
|
||||
self.navigationBar?.updatePresentationData(NavigationBarPresentationData(presentationData: self.presentationData))
|
||||
self.searchContentNode?.updateThemeAndPlaceholder(theme: self.presentationData.theme, placeholder: self.presentationData.strings.Common_Search)
|
||||
@ -413,22 +492,13 @@ public class ContactsController: ViewController {
|
||||
}
|
||||
}
|
||||
|
||||
self.contactsNode.contactListNode.openSortMenu = { [weak self] in
|
||||
self?.presentSortMenu()
|
||||
}
|
||||
|
||||
self.contactsNode.contactListNode.contentOffsetChanged = { [weak self] offset in
|
||||
if let strongSelf = self, let searchContentNode = strongSelf.searchContentNode {
|
||||
var progress: CGFloat = 0.0
|
||||
switch offset {
|
||||
case let .known(offset):
|
||||
progress = max(0.0, (searchContentNode.nominalHeight - max(0.0, offset - 50.0))) / searchContentNode.nominalHeight
|
||||
case .none:
|
||||
progress = 1.0
|
||||
default:
|
||||
break
|
||||
if let strongSelf = self, let searchContentNode = strongSelf.searchContentNode, let validLayout = strongSelf.validLayout {
|
||||
var offset = offset
|
||||
if validLayout.inVoiceOver {
|
||||
offset = .known(0.0)
|
||||
}
|
||||
searchContentNode.updateExpansionProgress(progress)
|
||||
searchContentNode.updateListVisibleContentOffset(offset)
|
||||
}
|
||||
}
|
||||
|
||||
@ -440,6 +510,10 @@ public class ContactsController: ViewController {
|
||||
}
|
||||
}
|
||||
|
||||
self.sortButton.contextAction = { [weak self] sourceNode, gesture in
|
||||
self?.presentSortMenu(sourceNode: sourceNode, gesture: gesture)
|
||||
}
|
||||
|
||||
self.displayNodeDidLoad()
|
||||
}
|
||||
|
||||
@ -465,6 +539,10 @@ public class ContactsController: ViewController {
|
||||
self.contactsNode.containerLayoutUpdated(layout, navigationBarHeight: self.cleanNavigationHeight, actualNavigationBarHeight: self.navigationLayout(layout: layout).navigationFrame.maxY, transition: transition)
|
||||
}
|
||||
|
||||
@objc private func sortPressed() {
|
||||
self.sortButton.contextAction?(self.sortButton.containerNode, nil)
|
||||
}
|
||||
|
||||
private func activateSearch() {
|
||||
if self.displayNavigationBar {
|
||||
if let searchContentNode = self.searchContentNode {
|
||||
@ -483,7 +561,7 @@ public class ContactsController: ViewController {
|
||||
}
|
||||
}
|
||||
|
||||
private func presentSortMenu() {
|
||||
private func presentSortMenu(sourceNode: ASDisplayNode, gesture: ContextGesture?) {
|
||||
let updateSortOrder: (ContactsSortOrder) -> Void = { [weak self] sortOrder in
|
||||
if let strongSelf = self {
|
||||
strongSelf.sortOrderPromise.set(.single(sortOrder))
|
||||
@ -495,23 +573,31 @@ public class ContactsController: ViewController {
|
||||
}
|
||||
}
|
||||
|
||||
let actionSheet = ActionSheetController(presentationData: self.presentationData)
|
||||
var items: [ActionSheetItem] = []
|
||||
items.append(ActionSheetTextItem(title: self.presentationData.strings.Contacts_SortBy))
|
||||
items.append(ActionSheetButtonItem(title: self.presentationData.strings.Contacts_SortByName, color: .accent, action: { [weak actionSheet] in
|
||||
actionSheet?.dismissAnimated()
|
||||
updateSortOrder(.natural)
|
||||
}))
|
||||
items.append(ActionSheetButtonItem(title: self.presentationData.strings.Contacts_SortByPresence, color: .accent, action: { [weak actionSheet] in
|
||||
actionSheet?.dismissAnimated()
|
||||
updateSortOrder(.presence)
|
||||
}))
|
||||
actionSheet.setItemGroups([ActionSheetItemGroup(items: items), ActionSheetItemGroup(items: [
|
||||
ActionSheetButtonItem(title: self.presentationData.strings.Common_Cancel, color: .accent, font: .bold, action: { [weak actionSheet] in
|
||||
actionSheet?.dismissAnimated()
|
||||
})
|
||||
])])
|
||||
self.present(actionSheet, in: .window(.root))
|
||||
let presentationData = self.presentationData
|
||||
let items: Signal<[ContextMenuItem], NoError> = self.context.sharedContext.accountManager.transaction { transaction in
|
||||
return transaction.getSharedData(ApplicationSpecificSharedDataKeys.contactSynchronizationSettings)
|
||||
}
|
||||
|> map { entry -> [ContextMenuItem] in
|
||||
let currentSettings: ContactSynchronizationSettings
|
||||
if let entry = entry?.get(ContactSynchronizationSettings.self) {
|
||||
currentSettings = entry
|
||||
} else {
|
||||
currentSettings = .defaultSettings
|
||||
}
|
||||
|
||||
var items: [ContextMenuItem] = []
|
||||
items.append(.action(ContextMenuActionItem(text: presentationData.strings.Contacts_Sort_ByLastSeen, icon: { theme in return currentSettings.sortOrder == .presence ? generateTintedImage(image: UIImage(bundleImageName: "Chat/Context Menu/Check"), color: theme.contextMenu.primaryColor) : nil }, action: { _, f in
|
||||
f(.default)
|
||||
updateSortOrder(.presence)
|
||||
})))
|
||||
items.append(.action(ContextMenuActionItem(text: presentationData.strings.Contacts_Sort_ByName, icon: { theme in return currentSettings.sortOrder == .natural ? generateTintedImage(image: UIImage(bundleImageName: "Chat/Context Menu/Check"), color: theme.contextMenu.primaryColor) : nil }, action: { _, f in
|
||||
f(.default)
|
||||
updateSortOrder(.natural)
|
||||
})))
|
||||
return items
|
||||
}
|
||||
let contextController = ContextController(account: self.context.account, presentationData: self.presentationData, source: .reference(HeaderContextReferenceContentSource(controller: self, sourceNode: self.sortButton.referenceNode)), items: items |> map { ContextController.Items(content: .list($0)) }, gesture: gesture)
|
||||
self.presentInGlobalOverlay(contextController)
|
||||
}
|
||||
|
||||
@objc func addPressed() {
|
||||
|
@ -741,7 +741,7 @@ final class ChatItemGalleryFooterContentNode: GalleryFooterContentNode, UIScroll
|
||||
|
||||
}
|
||||
if let dustNode = self.dustNode {
|
||||
dustNode.update(size: textFrame.size, color: .white, rects: textLayout.spoilers.map { $0.1.offsetBy(dx: 3.0, dy: 3.0).insetBy(dx: 0.0, dy: 1.0) }, wordRects: textLayout.spoilerWords.map { $0.1.offsetBy(dx: 3.0, dy: 3.0).insetBy(dx: 0.0, dy: 1.0) })
|
||||
dustNode.update(size: textFrame.size, color: .white, textColor: .white, rects: textLayout.spoilers.map { $0.1.offsetBy(dx: 3.0, dy: 3.0).insetBy(dx: 0.0, dy: 1.0) }, wordRects: textLayout.spoilerWords.map { $0.1.offsetBy(dx: 3.0, dy: 3.0).insetBy(dx: 0.0, dy: 1.0) })
|
||||
dustNode.frame = textFrame.insetBy(dx: -3.0, dy: -3.0).offsetBy(dx: 0.0, dy: 3.0)
|
||||
}
|
||||
} else {
|
||||
|
@ -43,7 +43,7 @@ private func generateMaskImage(size originalSize: CGSize, position: CGPoint, inv
|
||||
}
|
||||
|
||||
public class InvisibleInkDustNode: ASDisplayNode {
|
||||
private var currentParams: (size: CGSize, color: UIColor, rects: [CGRect], wordRects: [CGRect])?
|
||||
private var currentParams: (size: CGSize, color: UIColor, textColor: UIColor, rects: [CGRect], wordRects: [CGRect])?
|
||||
private var animColor: CGColor?
|
||||
|
||||
private weak var textNode: TextNode?
|
||||
@ -155,7 +155,7 @@ public class InvisibleInkDustNode: ASDisplayNode {
|
||||
}
|
||||
|
||||
@objc private func tap(_ gestureRecognizer: UITapGestureRecognizer) {
|
||||
guard let (_, _, _, _) = self.currentParams, let textNode = self.textNode, !self.isRevealed else {
|
||||
guard let (_, _, textColor, _, _) = self.currentParams, let textNode = self.textNode, !self.isRevealed else {
|
||||
return
|
||||
}
|
||||
|
||||
@ -209,7 +209,7 @@ public class InvisibleInkDustNode: ASDisplayNode {
|
||||
self?.alpha = 0.0
|
||||
self?.emitterNode.view.mask = nil
|
||||
|
||||
self?.emitter?.color = UIColor(rgb: 0x000000).cgColor
|
||||
self?.emitter?.color = textColor.cgColor
|
||||
})
|
||||
self.emitterMaskFillNode.layer.animateAlpha(from: 1.0, to: 0.0, duration: 0.15, removeOnCompletion: false)
|
||||
}
|
||||
@ -231,7 +231,7 @@ public class InvisibleInkDustNode: ASDisplayNode {
|
||||
|
||||
let timeToRead = min(45.0, ceil(max(4.0, Double(spoilersLength) * 0.04)))
|
||||
Queue.mainQueue().after(timeToRead * UIView.animationDurationFactor()) {
|
||||
if let (_, color, _, _) = self.currentParams {
|
||||
if let (_, color, _, _, _) = self.currentParams {
|
||||
let colorSpace = CGColorSpaceCreateDeviceRGB()
|
||||
let animation = POPBasicAnimation()
|
||||
animation.property = (POPAnimatableProperty.property(withName: "color", initializer: { property in
|
||||
@ -277,10 +277,10 @@ public class InvisibleInkDustNode: ASDisplayNode {
|
||||
}
|
||||
|
||||
private func updateEmitter() {
|
||||
guard let (size, color, _, wordRects) = self.currentParams else {
|
||||
guard let (size, color, _, _, wordRects) = self.currentParams else {
|
||||
return
|
||||
}
|
||||
|
||||
|
||||
self.emitter?.color = self.animColor ?? color.cgColor
|
||||
self.emitterLayer?.setValue(wordRects, forKey: "emitterRects")
|
||||
self.emitterLayer?.frame = CGRect(origin: CGPoint(), size: size)
|
||||
@ -299,8 +299,8 @@ public class InvisibleInkDustNode: ASDisplayNode {
|
||||
}
|
||||
}
|
||||
|
||||
public func update(size: CGSize, color: UIColor, rects: [CGRect], wordRects: [CGRect]) {
|
||||
self.currentParams = (size, color, rects, wordRects)
|
||||
public func update(size: CGSize, color: UIColor, textColor: UIColor, rects: [CGRect], wordRects: [CGRect]) {
|
||||
self.currentParams = (size, color, textColor, rects, wordRects)
|
||||
|
||||
self.emitterNode.frame = CGRect(origin: CGPoint(), size: size)
|
||||
self.emitterMaskNode.frame = self.emitterNode.bounds
|
||||
@ -313,7 +313,7 @@ public class InvisibleInkDustNode: ASDisplayNode {
|
||||
}
|
||||
|
||||
public override func point(inside point: CGPoint, with event: UIEvent?) -> Bool {
|
||||
if let (_, _, rects, _) = self.currentParams, !self.isRevealed {
|
||||
if let (_, _, _, rects, _) = self.currentParams, !self.isRevealed {
|
||||
for rect in rects {
|
||||
if rect.contains(point) {
|
||||
return true
|
||||
|
@ -414,7 +414,7 @@ final class ChatMessageNotificationItemNode: NotificationItemNode {
|
||||
self.insertSubnode(dustNode, aboveSubnode: self.textNode)
|
||||
}
|
||||
dustNode.frame = textFrame.insetBy(dx: -3.0, dy: -3.0).offsetBy(dx: 0.0, dy: 3.0)
|
||||
dustNode.update(size: dustNode.frame.size, color: presentationData.theme.inAppNotification.primaryTextColor, rects: textLayout.spoilers.map { $0.1.offsetBy(dx: 3.0, dy: 3.0).insetBy(dx: 1.0, dy: 1.0) }, wordRects: textLayout.spoilerWords.map { $0.1.offsetBy(dx: 3.0, dy: 3.0).insetBy(dx: 1.0, dy: 1.0) })
|
||||
dustNode.update(size: dustNode.frame.size, color: presentationData.theme.inAppNotification.primaryTextColor, textColor: presentationData.theme.inAppNotification.primaryTextColor, rects: textLayout.spoilers.map { $0.1.offsetBy(dx: 3.0, dy: 3.0).insetBy(dx: 1.0, dy: 1.0) }, wordRects: textLayout.spoilerWords.map { $0.1.offsetBy(dx: 3.0, dy: 3.0).insetBy(dx: 1.0, dy: 1.0) })
|
||||
} else if let dustNode = self.dustNode {
|
||||
dustNode.removeFromSupernode()
|
||||
self.dustNode = nil
|
||||
|
@ -258,7 +258,7 @@ class ChatMessageReplyInfoNode: ASDisplayNode {
|
||||
node.contentNode.insertSubnode(dustNode, aboveSubnode: textNode)
|
||||
}
|
||||
dustNode.frame = textFrame.insetBy(dx: -3.0, dy: -3.0).offsetBy(dx: 0.0, dy: 3.0)
|
||||
dustNode.update(size: dustNode.frame.size, color: dustColor, rects: textLayout.spoilers.map { $0.1.offsetBy(dx: 3.0, dy: 3.0).insetBy(dx: 1.0, dy: 1.0) }, wordRects: textLayout.spoilerWords.map { $0.1.offsetBy(dx: 3.0, dy: 3.0).insetBy(dx: 1.0, dy: 1.0) })
|
||||
dustNode.update(size: dustNode.frame.size, color: dustColor, textColor: dustColor, rects: textLayout.spoilers.map { $0.1.offsetBy(dx: 3.0, dy: 3.0).insetBy(dx: 1.0, dy: 1.0) }, wordRects: textLayout.spoilerWords.map { $0.1.offsetBy(dx: 3.0, dy: 3.0).insetBy(dx: 1.0, dy: 1.0) })
|
||||
} else if let dustNode = node.dustNode {
|
||||
dustNode.removeFromSupernode()
|
||||
node.dustNode = nil
|
||||
|
@ -412,7 +412,7 @@ class ChatMessageTextBubbleContentNode: ChatMessageBubbleContentNode {
|
||||
strongSelf.insertSubnode(dustNode, aboveSubnode: spoilerTextNode)
|
||||
}
|
||||
dustNode.frame = textFrame.insetBy(dx: -3.0, dy: -3.0).offsetBy(dx: 0.0, dy: 3.0)
|
||||
dustNode.update(size: dustNode.frame.size, color: messageTheme.secondaryTextColor, rects: textLayout.spoilers.map { $0.1.offsetBy(dx: 3.0, dy: 3.0).insetBy(dx: 1.0, dy: 1.0) }, wordRects: textLayout.spoilerWords.map { $0.1.offsetBy(dx: 3.0, dy: 3.0).insetBy(dx: 1.0, dy: 1.0) })
|
||||
dustNode.update(size: dustNode.frame.size, color: messageTheme.secondaryTextColor, textColor: messageTheme.primaryTextColor, rects: textLayout.spoilers.map { $0.1.offsetBy(dx: 3.0, dy: 3.0).insetBy(dx: 1.0, dy: 1.0) }, wordRects: textLayout.spoilerWords.map { $0.1.offsetBy(dx: 3.0, dy: 3.0).insetBy(dx: 1.0, dy: 1.0) })
|
||||
} else if let spoilerTextNode = strongSelf.spoilerTextNode {
|
||||
strongSelf.spoilerTextNode = nil
|
||||
spoilerTextNode.removeFromSupernode()
|
||||
|
@ -503,7 +503,7 @@ final class ChatPinnedMessageTitlePanelNode: ChatTitleAccessoryPanelNode {
|
||||
strongSelf.contentTextContainer.insertSubnode(dustNode, aboveSubnode: strongSelf.textNode)
|
||||
}
|
||||
dustNode.frame = textFrame.insetBy(dx: -3.0, dy: -3.0).offsetBy(dx: 0.0, dy: 3.0)
|
||||
dustNode.update(size: dustNode.frame.size, color: theme.chat.inputPanel.primaryTextColor, rects: textLayout.spoilers.map { $0.1.offsetBy(dx: 3.0, dy: 3.0).insetBy(dx: 1.0, dy: 1.0) }, wordRects: textLayout.spoilerWords.map { $0.1.offsetBy(dx: 3.0, dy: 3.0).insetBy(dx: 1.0, dy: 1.0) })
|
||||
dustNode.update(size: dustNode.frame.size, color: theme.chat.inputPanel.primaryTextColor, textColor: theme.chat.inputPanel.primaryTextColor, rects: textLayout.spoilers.map { $0.1.offsetBy(dx: 3.0, dy: 3.0).insetBy(dx: 1.0, dy: 1.0) }, wordRects: textLayout.spoilerWords.map { $0.1.offsetBy(dx: 3.0, dy: 3.0).insetBy(dx: 1.0, dy: 1.0) })
|
||||
} else if let dustNode = strongSelf.dustNode {
|
||||
dustNode.removeFromSupernode()
|
||||
strongSelf.dustNode = nil
|
||||
|
@ -1860,7 +1860,7 @@ class ChatTextInputPanelNode: ChatInputPanelNode, ASEditableTextNodeDelegate {
|
||||
self.dustNode = dustNode
|
||||
}
|
||||
dustNode.frame = CGRect(origin: CGPoint(), size: textInputNode.textView.contentSize)
|
||||
dustNode.update(size: textInputNode.textView.contentSize, color: textColor, rects: rects, wordRects: rects)
|
||||
dustNode.update(size: textInputNode.textView.contentSize, color: textColor, textColor: textColor, rects: rects, wordRects: rects)
|
||||
} else if let dustNode = self.dustNode {
|
||||
dustNode.removeFromSupernode()
|
||||
self.dustNode = nil
|
||||
|
@ -804,7 +804,7 @@ class PeerSelectionTextInputPanelNode: ChatInputPanelNode, TGCaptionPanelView, A
|
||||
self.dustNode = dustNode
|
||||
}
|
||||
dustNode.frame = CGRect(origin: CGPoint(), size: textInputNode.textView.contentSize)
|
||||
dustNode.update(size: textInputNode.textView.contentSize, color: textColor, rects: rects, wordRects: rects)
|
||||
dustNode.update(size: textInputNode.textView.contentSize, color: textColor, textColor: textColor, rects: rects, wordRects: rects)
|
||||
} else if let dustNode = self.dustNode {
|
||||
dustNode.removeFromSupernode()
|
||||
self.dustNode = nil
|
||||
@ -977,7 +977,7 @@ class PeerSelectionTextInputPanelNode: ChatInputPanelNode, TGCaptionPanelView, A
|
||||
if let oneLineDustNode = self.oneLineDustNode {
|
||||
let textFrame = self.oneLineNode.frame.insetBy(dx: 0.0, dy: -3.0)
|
||||
|
||||
oneLineDustNode.update(size: textFrame.size, color: .white, rects: textLayout.spoilers.map { $0.1.offsetBy(dx: 0.0, dy: 3.0) }, wordRects: textLayout.spoilerWords.map { $0.1.offsetBy(dx: 0.0, dy: 3.0) })
|
||||
oneLineDustNode.update(size: textFrame.size, color: .white, textColor: .white, rects: textLayout.spoilers.map { $0.1.offsetBy(dx: 0.0, dy: 3.0) }, wordRects: textLayout.spoilerWords.map { $0.1.offsetBy(dx: 0.0, dy: 3.0) })
|
||||
oneLineDustNode.frame = textFrame
|
||||
}
|
||||
} else {
|
||||
|
@ -330,7 +330,7 @@ final class ReplyAccessoryPanelNode: AccessoryPanelNode {
|
||||
|
||||
}
|
||||
if let dustNode = self.dustNode {
|
||||
dustNode.update(size: textFrame.size, color: self.theme.chat.inputPanel.primaryTextColor, rects: textLayout.spoilers.map { $0.1.offsetBy(dx: 3.0, dy: 3.0).insetBy(dx: 1.0, dy: 1.0) }, wordRects: textLayout.spoilerWords.map { $0.1.offsetBy(dx: 3.0, dy: 3.0).insetBy(dx: 1.0, dy: 1.0) })
|
||||
dustNode.update(size: textFrame.size, color: self.theme.chat.inputPanel.primaryTextColor, textColor: self.theme.chat.inputPanel.primaryTextColor, rects: textLayout.spoilers.map { $0.1.offsetBy(dx: 3.0, dy: 3.0).insetBy(dx: 1.0, dy: 1.0) }, wordRects: textLayout.spoilerWords.map { $0.1.offsetBy(dx: 3.0, dy: 3.0).insetBy(dx: 1.0, dy: 1.0) })
|
||||
dustNode.frame = textFrame.insetBy(dx: -3.0, dy: -3.0).offsetBy(dx: 0.0, dy: 3.0)
|
||||
}
|
||||
} else if let dustNode = self.dustNode {
|
||||
|
Loading…
x
Reference in New Issue
Block a user