From 031ff5fa80e802cd6e14d7bd10eaccfb4ce09315 Mon Sep 17 00:00:00 2001 From: Peter <> Date: Mon, 22 Apr 2019 17:26:11 +0400 Subject: [PATCH] AvatarNode: react to theme changes ChatHistoryListNode: follow to upperBound ItemListRevealOptionsNode: improve layout animations --- .../ArchiveAvatar@2x.png | Bin 1156 -> 957 bytes .../ArchiveAvatar@3x.png | Bin 1783 -> 1385 bytes TelegramUI/AvatarNode.swift | 2 +- TelegramUI/ChatHistoryListNode.swift | 49 ++++++++++---- TelegramUI/ItemListRevealOptionsNode.swift | 62 +++++++++++------- TelegramUI/ManagedAudioSession.swift | 2 +- 6 files changed, 76 insertions(+), 39 deletions(-) diff --git a/Images.xcassets/Avatar/ArchiveAvatarIcon.imageset/ArchiveAvatar@2x.png b/Images.xcassets/Avatar/ArchiveAvatarIcon.imageset/ArchiveAvatar@2x.png index 891ff5729e32fc2c29c3741950f042ddae0d51d5..05f1d6839ef1c4944395455ccb2d002514c31f56 100644 GIT binary patch literal 957 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 V*=zs@5@g>AB6#?_x44nB{sCbwcrO3| literal 1783 zcmV4Ei1V`q0qO z{!qyW0S({>N$6vANvOmc;^zPgk=BXzaXdvH;^B>WLo+e<4bHGwJj+4L8dL+ST6`qT*&~t0e4=4<9$ncorp|O#i>Zl4 zri?iq`E=m^IrL&?n9DYg`}k~=4Rx=}QU9}rY9qih^glF9^g+B>C`bzisW#MSvgsRr zN3N0>un;|t`pAx4&Rb{LVcB*DnwP%SKjye(0c_hn&=|Ajr z(&rsH7#*=uB>NH^=o82TP>z1EoejYHoz$qiNxm}Lx%g!7WAh#d>w|HBJ$zH?Z@YDr zcj+pheV(q%pHadRNSNB7mxhfIy+I&hYJ(oQqlgNoLc-JrT|wNz4G}?C^w~$y5p+ca zDhd;4bOc=yfr`S!8681aM4+NDaYjeb6%nW?OdDtPpRkd(O4H#dyT%&d&DTCDFI!_ zKKh;RvZuGWkpC%LYtg@_TXU~z>{{c?HTZ2;M_KK4fIg8{41f;OuYLA!X?Bi2jag-U zI7}`zr{<70uxMW$pjT!k3#jk089|R_*;@Uw9Wi6A=ANsWIrJPghsHWUZ((Pc{1Ccw z2iWiQtwzUPHdecA^!Ga&lPV_mmQXZ3e%iKRyqcA`&o+NxZ7&8m_TQo;KG zaD7Ss6SpSDJ{oF)tVHSrt@t{+I1C8=`&cPreCv&1#i~u}2Cc&HMvnsIzR(nmPrbRS z7_~|hKns8#o0LcQ~ot;T4q@xh`w;$27$DZfC>-N3sl zE4H!Ojh)6cQko1}z@9|+0`fW+J=3?>*t*PWZ*Mwi0n$Id90KSqGijMN-95?kuP`&+ zRI**yDR|!E?qR?&z`n}zD>L|EmRr$l&32;~ZF#k#(GXLTYu&3ADYdkts}1|;c96`- zGJ?(k6skLd4n;DqK@O_r`aA;W0W8S#yXJYEt%2U z;G)fqEPh5?aiK;zH&p&1ujPPF{=g-f(Ms5K=$_q0ZAU3YKGtbP0h_{ zge@TXM9elDhFv4Ob{%#PyOBrP{s@h`5gUwqUAqg-WKGmrGHXV6EX;uAY`=@@7c@$5 z0%9XZ+9&sftYOX>t$Ch^w8iSicYI_#y5%TIQa_z>xeB%Brre( Z{s*L#JIlkEXq5l}002ovPDHLkV1mv*Rz&~+ diff --git a/TelegramUI/AvatarNode.swift b/TelegramUI/AvatarNode.swift index 387c4ab782..b919969cf2 100644 --- a/TelegramUI/AvatarNode.swift +++ b/TelegramUI/AvatarNode.swift @@ -227,7 +227,7 @@ public final class AvatarNode: ASDisplayNode { representation = peer?.smallProfileImage } let updatedState: AvatarNodeState = .peerAvatar(peer?.id ?? PeerId(namespace: 0, id: 0), peer?.displayLetters ?? [], representation) - if updatedState != self.state { + if updatedState != self.state || theme !== self.theme { self.state = updatedState let parameters: AvatarNodeParameters diff --git a/TelegramUI/ChatHistoryListNode.swift b/TelegramUI/ChatHistoryListNode.swift index d3c1b20c89..96fe9adb85 100644 --- a/TelegramUI/ChatHistoryListNode.swift +++ b/TelegramUI/ChatHistoryListNode.swift @@ -293,6 +293,19 @@ private func extractAssociatedData(chatLocation: ChatLocation, view: MessageHist return associatedData } +private extension ChatHistoryLocationInput { + var isAtUpperBound: Bool { + switch self.content { + case .Navigation(index: .upperBound, anchorIndex: .upperBound, count: _): + return true + case .Scroll(index: .upperBound, anchorIndex: .upperBound, sourceIndex: _, scrollPosition: _, animated: _): + return true + default: + return false + } + } +} + public final class ChatHistoryListNode: ListView, ChatHistoryNode { private let context: AccountContext private let chatLocation: ChatLocation @@ -337,7 +350,14 @@ public final class ChatHistoryListNode: ListView, ChatHistoryNode { private var canReadHistoryValue: Bool = false private var canReadHistoryDisposable: Disposable? - private let chatHistoryLocation = ValuePromise() + private var chatHistoryLocationValue: ChatHistoryLocationInput? { + didSet { + if let chatHistoryLocationValue = self.chatHistoryLocationValue, chatHistoryLocationValue != oldValue { + chatHistoryLocationPromise.set(chatHistoryLocationValue) + } + } + } + private let chatHistoryLocationPromise = ValuePromise() private var nextHistoryLocationId: Int32 = 1 private func takeNextHistoryLocationId() -> Int32 { let id = self.nextHistoryLocationId @@ -455,7 +475,7 @@ public final class ChatHistoryListNode: ListView, ChatHistoryNode { } additionalData.append(.totalUnreadState) - let historyViewUpdate = self.chatHistoryLocation.get() + let historyViewUpdate = self.chatHistoryLocationPromise.get() |> distinctUntilChanged |> mapToSignal { location in return chatHistoryViewForLocation(location, account: context.account, chatLocation: chatLocation, fixedCombinedReadStates: fixedCombinedReadStates.with { $0 }, tagMask: tagMask, additionalData: additionalData) @@ -494,12 +514,12 @@ public final class ChatHistoryListNode: ListView, ChatHistoryNode { if let filteredEntries = historyView?.filteredEntries, let visibleRange = displayRange.visibleRange { let lastEntry = filteredEntries[filteredEntries.count - 1 - visibleRange.lastIndex] - strongSelf.chatHistoryLocation.set(ChatHistoryLocationInput(content: .Navigation(index: .message(lastEntry.index), anchorIndex: .message(lastEntry.index), count: historyMessageCount), id: 0)) + strongSelf.chatHistoryLocationValue = ChatHistoryLocationInput(content: .Navigation(index: .message(lastEntry.index), anchorIndex: .message(lastEntry.index), count: historyMessageCount), id: 0) } else { if let messageId = messageId { - strongSelf.chatHistoryLocation.set(ChatHistoryLocationInput(content: .InitialSearch(location: .id(messageId), count: 60), id: 0)) + strongSelf.chatHistoryLocationValue = ChatHistoryLocationInput(content: .InitialSearch(location: .id(messageId), count: 60), id: 0) } else { - strongSelf.chatHistoryLocation.set(ChatHistoryLocationInput(content: .Initial(count: 60), id: 0)) + strongSelf.chatHistoryLocationValue = ChatHistoryLocationInput(content: .Initial(count: 60), id: 0) } } } @@ -670,10 +690,11 @@ public final class ChatHistoryListNode: ListView, ChatHistoryNode { }) if let messageId = messageId { - self.chatHistoryLocation.set(ChatHistoryLocationInput(content: .InitialSearch(location: .id(messageId), count: 60), id: 0)) + self.chatHistoryLocationValue = ChatHistoryLocationInput(content: .InitialSearch(location: .id(messageId), count: 60), id: 0) } else { - self.chatHistoryLocation.set(ChatHistoryLocationInput(content: .Initial(count: 60), id: 0)) + self.chatHistoryLocationValue = ChatHistoryLocationInput(content: .Initial(count: 60), id: 0) } + self.chatHistoryLocationPromise.set(self.chatHistoryLocationValue!) self.generalScrollDirectionUpdated = { [weak self] direction in guard let strongSelf = self else { @@ -862,9 +883,11 @@ public final class ChatHistoryListNode: ListView, ChatHistoryNode { if let loaded = displayedRange.loadedRange, let firstEntry = historyView.filteredEntries.first, let lastEntry = historyView.filteredEntries.last { if loaded.firstIndex < 5 && historyView.originalView.laterId != nil { - strongSelf.chatHistoryLocation.set(ChatHistoryLocationInput(content: .Navigation(index: .message(lastEntry.index), anchorIndex: .message(lastEntry.index), count: historyMessageCount), id: 0)) + strongSelf.chatHistoryLocationValue = ChatHistoryLocationInput(content: .Navigation(index: .message(lastEntry.index), anchorIndex: .message(lastEntry.index), count: historyMessageCount), id: 0) + } else if loaded.firstIndex < 5, historyView.originalView.laterId == nil, !historyView.originalView.holeLater, let chatHistoryLocationValue = strongSelf.chatHistoryLocationValue, !chatHistoryLocationValue.isAtUpperBound, historyView.originalView.anchorIndex != .upperBound { + strongSelf.chatHistoryLocationValue = ChatHistoryLocationInput(content: .Navigation(index: .upperBound, anchorIndex: .upperBound, count: historyMessageCount), id: 0) } else if loaded.lastIndex >= historyView.filteredEntries.count - 5 && historyView.originalView.earlierId != nil { - strongSelf.chatHistoryLocation.set(ChatHistoryLocationInput(content: .Navigation(index: .message(firstEntry.index), anchorIndex: .message(firstEntry.index), count: historyMessageCount), id: 0)) + strongSelf.chatHistoryLocationValue = ChatHistoryLocationInput(content: .Navigation(index: .message(firstEntry.index), anchorIndex: .message(firstEntry.index), count: historyMessageCount), id: 0) } } @@ -992,12 +1015,12 @@ public final class ChatHistoryListNode: ListView, ChatHistoryNode { } if let currentMessage = currentMessage { - self.chatHistoryLocation.set(ChatHistoryLocationInput(content: .Scroll(index: .message(currentMessage.index), anchorIndex: .message(currentMessage.index), sourceIndex: .upperBound, scrollPosition: .top(0.0), animated: true), id: self.takeNextHistoryLocationId())) + self.chatHistoryLocationValue = ChatHistoryLocationInput(content: .Scroll(index: .message(currentMessage.index), anchorIndex: .message(currentMessage.index), sourceIndex: .upperBound, scrollPosition: .top(0.0), animated: true), id: self.takeNextHistoryLocationId()) } } public func scrollToStartOfHistory() { - self.chatHistoryLocation.set(ChatHistoryLocationInput(content: .Scroll(index: .lowerBound, anchorIndex: .lowerBound, sourceIndex: .upperBound, scrollPosition: .bottom(0.0), animated: true), id: self.takeNextHistoryLocationId())) + self.chatHistoryLocationValue = ChatHistoryLocationInput(content: .Scroll(index: .lowerBound, anchorIndex: .lowerBound, sourceIndex: .upperBound, scrollPosition: .bottom(0.0), animated: true), id: self.takeNextHistoryLocationId()) } public func scrollToEndOfHistory() { @@ -1005,12 +1028,12 @@ public final class ChatHistoryListNode: ListView, ChatHistoryNode { case .known(0.0): break default: - self.chatHistoryLocation.set(ChatHistoryLocationInput(content: .Scroll(index: .upperBound, anchorIndex: .upperBound, sourceIndex: .lowerBound, scrollPosition: .top(0.0), animated: true), id: self.takeNextHistoryLocationId())) + self.chatHistoryLocationValue = ChatHistoryLocationInput(content: .Scroll(index: .upperBound, anchorIndex: .upperBound, sourceIndex: .lowerBound, scrollPosition: .top(0.0), animated: true), id: self.takeNextHistoryLocationId()) } } public func scrollToMessage(from fromIndex: MessageIndex, to toIndex: MessageIndex, animated: Bool, highlight: Bool = true, scrollPosition: ListViewScrollPosition = .center(.bottom)) { - self.chatHistoryLocation.set(ChatHistoryLocationInput(content: .Scroll(index: .message(toIndex), anchorIndex: .message(toIndex), sourceIndex: .message(fromIndex), scrollPosition: scrollPosition, animated: animated), id: self.takeNextHistoryLocationId())) + self.chatHistoryLocationValue = ChatHistoryLocationInput(content: .Scroll(index: .message(toIndex), anchorIndex: .message(toIndex), sourceIndex: .message(fromIndex), scrollPosition: scrollPosition, animated: animated), id: self.takeNextHistoryLocationId()) } func scrollWithDeltaOffset(_ offset: CGFloat) { diff --git a/TelegramUI/ItemListRevealOptionsNode.swift b/TelegramUI/ItemListRevealOptionsNode.swift index 0cfa4293a8..f3d61a03a1 100644 --- a/TelegramUI/ItemListRevealOptionsNode.swift +++ b/TelegramUI/ItemListRevealOptionsNode.swift @@ -224,15 +224,19 @@ private final class ItemListRevealOptionNode: ASDisplayNode { let titleIconSpacing: CGFloat = 11.0 let iconFrame = CGRect(origin: CGPoint(x: contentRect.minX + floor((baseSize.width - imageSize.width + sideInset) / 2.0), y: contentRect.midY - imageSize.height / 2.0 + iconOffset), size: imageSize) if animateAdditive { + animationNode.frame = iconFrame transition.animatePositionAdditive(node: animationNode, offset: CGPoint(x: deltaX, y: 0.0)) + } else { + transition.updateFrame(node: animationNode, frame: iconFrame) } - animationNode.frame = iconFrame let titleFrame = CGRect(origin: CGPoint(x: contentRect.minX + floor((baseSize.width - titleSize.width + sideInset) / 2.0), y: contentRect.midY + titleIconSpacing), size: titleSize) if animateAdditive { + self.titleNode.frame = titleFrame transition.animatePositionAdditive(node: self.titleNode, offset: CGPoint(x: deltaX, y: 0.0)) + } else { + transition.updateFrame(node: self.titleNode, frame: titleFrame) } - self.titleNode.frame = titleFrame if (abs(revealFactor) >= 0.4) { animationNode.play() @@ -244,17 +248,27 @@ private final class ItemListRevealOptionNode: ASDisplayNode { let titleIconSpacing: CGFloat = 11.0 let iconFrame = CGRect(origin: CGPoint(x: contentRect.minX + floor((baseSize.width - imageSize.width + sideInset) / 2.0), y: contentRect.midY - imageSize.height / 2.0 + iconOffset), size: imageSize) if animateAdditive { + iconNode.frame = iconFrame transition.animatePositionAdditive(node: iconNode, offset: CGPoint(x: deltaX, y: 0.0)) + } else { + transition.updateFrame(node: iconNode, frame: iconFrame) } - iconNode.frame = iconFrame let titleFrame = CGRect(origin: CGPoint(x: contentRect.minX + floor((baseSize.width - titleSize.width + sideInset) / 2.0), y: contentRect.midY + titleIconSpacing), size: titleSize) if animateAdditive { + self.titleNode.frame = titleFrame transition.animatePositionAdditive(node: self.titleNode, offset: CGPoint(x: deltaX, y: 0.0)) + } else { + transition.updateFrame(node: self.titleNode, frame: titleFrame) } - self.titleNode.frame = titleFrame } else { - self.titleNode.frame = CGRect(origin: CGPoint(x: contentRect.minX + floor((baseSize.width - titleSize.width + sideInset) / 2.0), y: contentRect.minY + floor((baseSize.height - titleSize.height) / 2.0)), size: titleSize) + let titleFrame = CGRect(origin: CGPoint(x: contentRect.minX + floor((baseSize.width - titleSize.width + sideInset) / 2.0), y: contentRect.minY + floor((baseSize.height - titleSize.height) / 2.0)), size: titleSize) + if animateAdditive { + self.titleNode.frame = titleFrame + transition.animatePositionAdditive(node: self.titleNode, offset: CGPoint(x: deltaX, y: 0.0)) + } else { + transition.updateFrame(node: self.titleNode, frame: titleFrame) + } } } @@ -296,7 +310,7 @@ final class ItemListRevealOptionsNode: ASDisplayNode { } for node in strongSelf.optionNodes { if node.frame.contains(location) { - node.setHighlighted(true) + //node.setHighlighted(true) break } } @@ -350,28 +364,25 @@ final class ItemListRevealOptionsNode: ASDisplayNode { if size.width.isLessThanOrEqualTo(0.0) || self.optionNodes.isEmpty { return } - let basicNodeWidth = floorToScreenPixels((size.width - abs(self.sideInset)) / CGFloat(self.optionNodes.count)) + let basicNodeWidth = floor((size.width - abs(self.sideInset)) / CGFloat(self.optionNodes.count)) let lastNodeWidth = size.width - basicNodeWidth * CGFloat(self.optionNodes.count - 1) let revealFactor = self.revealOffset / size.width - let boundaryRevealFactor: CGFloat = 1.0 + basicNodeWidth / size.width * 0.7 - var leftOffset: CGFloat + let boundaryRevealFactor: CGFloat = 1.0 + 16.0 / size.width + let startingOffset: CGFloat if self.isLeft { - leftOffset = size.width + max(0.0, abs(revealFactor) - 1.0) * size.width + startingOffset = size.width + max(0.0, abs(revealFactor) - 1.0) * size.width } else { - leftOffset = 0.0 + startingOffset = 0.0 } var i = self.isLeft ? (self.optionNodes.count - 1) : 0 while i >= 0 && i < self.optionNodes.count { let node = self.optionNodes[i] let nodeWidth = i == (self.optionNodes.count - 1) ? lastNodeWidth : basicNodeWidth - var extendedWidth = nodeWidth let defaultAlignment: ItemListRevealOptionAlignment = isLeft ? .right : .left var nodeTransition = transition - extendedWidth = floorToScreenPixels(nodeWidth * max(1.0, abs(revealFactor))) var isExpanded = false if (isLeft && i == 0) || (!isLeft && i == self.optionNodes.count - 1) { if abs(revealFactor) > boundaryRevealFactor { - extendedWidth = size.width * max(1.0, abs(revealFactor)) isExpanded = true } } @@ -387,31 +398,34 @@ final class ItemListRevealOptionsNode: ASDisplayNode { sideInset = self.sideInset } - var nodeLeftOffset = leftOffset - if self.isLeft { - nodeLeftOffset -= extendedWidth - } else { - nodeLeftOffset *= abs(revealFactor) - } + let extendedWidth: CGFloat + let nodeLeftOffset: CGFloat if isExpanded { nodeLeftOffset = 0.0 + extendedWidth = size.width * max(1.0, abs(revealFactor)) + } else if self.isLeft { + let offset = basicNodeWidth * CGFloat(self.optionNodes.count - 1 - i) + extendedWidth = size.width - offset + nodeLeftOffset = startingOffset - extendedWidth - floorToScreenPixels(offset * abs(revealFactor)) + } else { + let offset = basicNodeWidth * CGFloat(i) + extendedWidth = size.width - offset + nodeLeftOffset = startingOffset + floorToScreenPixels(offset * abs(revealFactor)) } - transition.updateFrame(node: node, frame: CGRect(origin: CGPoint(x: floorToScreenPixels(nodeLeftOffset), y: 0.0), size: CGSize(width: extendedWidth, height: size.height))) + transition.updateFrame(node: node, frame: CGRect(origin: CGPoint(x: nodeLeftOffset, y: 0.0), size: CGSize(width: extendedWidth, height: size.height))) node.updateLayout(isFirst: (self.isLeft && i == 0) || (!self.isLeft && i == self.optionNodes.count - 1), isLeft: self.isLeft, baseSize: CGSize(width: nodeWidth, height: size.height), alignment: defaultAlignment, isExpanded: isExpanded, extendedWidth: extendedWidth, sideInset: sideInset, transition: nodeTransition, additive: !transition.isAnimated, revealFactor: revealFactor) if self.isLeft { - leftOffset -= extendedWidth i -= 1 } else { - leftOffset += nodeWidth i += 1 } } } @objc func tapGesture(_ recognizer: TapLongTapOrDoubleTapGestureRecognizer) { - if case .ended = recognizer.state { + if case .ended = recognizer.state, let gesture = recognizer.lastRecognizedGestureAndLocation?.0, case .tap = gesture { let location = recognizer.location(in: self.view) var selectedOption: Int? for i in 0 ..< self.optionNodes.count { diff --git a/TelegramUI/ManagedAudioSession.swift b/TelegramUI/ManagedAudioSession.swift index 3c4957287e..c33546de36 100644 --- a/TelegramUI/ManagedAudioSession.swift +++ b/TelegramUI/ManagedAudioSession.swift @@ -644,7 +644,7 @@ public final class ManagedAudioSession { case .record, .voiceCall: options.insert(.allowBluetooth) } - print("ManagedAudioSession setting active \(type != .none)") + print("ManagedAudioSession setting active true") if #available(iOSApplicationExtension 11.0, *) { try AVAudioSession.sharedInstance().setCategory(nativeCategoryForType(type, headphones: self.isHeadsetPluggedInValue), mode: type == .voiceCall ? AVAudioSessionModeVoiceChat : AVAudioSessionModeDefault, routeSharingPolicy: .default, options: options) } else {