Various fixes

This commit is contained in:
Ilya Laktyushin 2022-04-14 03:20:29 +04:00
parent 97392afb9e
commit df2354e9bb
12 changed files with 93 additions and 79 deletions

View File

@ -534,11 +534,11 @@ open class NavigationBar: ASDisplayNode {
self.previousItemListenerKey = itemValue.addSetTitleListener { [weak self] _, _ in self.previousItemListenerKey = itemValue.addSetTitleListener { [weak self] _, _ in
if let strongSelf = self, let previousItem = strongSelf.previousItem, case let .item(itemValue) = previousItem { if let strongSelf = self, let previousItem = strongSelf.previousItem, case let .item(itemValue) = previousItem {
if let customBackButtonText = strongSelf.customBackButtonText { if let customBackButtonText = strongSelf.customBackButtonText {
strongSelf.backButtonNode.updateManualText(customBackButtonText) strongSelf.backButtonNode.updateManualText(customBackButtonText, isBack: true)
} else if let backBarButtonItem = itemValue.backBarButtonItem { } else if let backBarButtonItem = itemValue.backBarButtonItem {
strongSelf.backButtonNode.updateManualText(backBarButtonItem.title ?? "") strongSelf.backButtonNode.updateManualText(backBarButtonItem.title ?? "", isBack: true)
} else { } else {
strongSelf.backButtonNode.updateManualText(itemValue.title ?? "") strongSelf.backButtonNode.updateManualText(itemValue.title ?? "", isBack: true)
} }
strongSelf.invalidateCalculatedLayout() strongSelf.invalidateCalculatedLayout()
strongSelf.requestLayout() strongSelf.requestLayout()
@ -548,11 +548,11 @@ open class NavigationBar: ASDisplayNode {
self.previousItemBackListenerKey = itemValue.addSetBackBarButtonItemListener { [weak self] _, _, _ in self.previousItemBackListenerKey = itemValue.addSetBackBarButtonItemListener { [weak self] _, _, _ in
if let strongSelf = self, let previousItem = strongSelf.previousItem, case let .item(itemValue) = previousItem { if let strongSelf = self, let previousItem = strongSelf.previousItem, case let .item(itemValue) = previousItem {
if let customBackButtonText = strongSelf.customBackButtonText { if let customBackButtonText = strongSelf.customBackButtonText {
strongSelf.backButtonNode.updateManualText(customBackButtonText) strongSelf.backButtonNode.updateManualText(customBackButtonText, isBack: true)
} else if let backBarButtonItem = itemValue.backBarButtonItem { } else if let backBarButtonItem = itemValue.backBarButtonItem {
strongSelf.backButtonNode.updateManualText(backBarButtonItem.title ?? "") strongSelf.backButtonNode.updateManualText(backBarButtonItem.title ?? "", isBack: true)
} else { } else {
strongSelf.backButtonNode.updateManualText(itemValue.title ?? "") strongSelf.backButtonNode.updateManualText(itemValue.title ?? "", isBack: true)
} }
strongSelf.invalidateCalculatedLayout() strongSelf.invalidateCalculatedLayout()
strongSelf.requestLayout() strongSelf.requestLayout()
@ -682,7 +682,7 @@ open class NavigationBar: ASDisplayNode {
} }
if let backTitle = backTitle { if let backTitle = backTitle {
self.backButtonNode.updateManualText(backTitle) self.backButtonNode.updateManualText(backTitle, isBack: true)
if self.backButtonNode.supernode == nil { if self.backButtonNode.supernode == nil {
self.buttonsContainerNode.addSubnode(self.backButtonNode) self.buttonsContainerNode.addSubnode(self.backButtonNode)
self.buttonsContainerNode.addSubnode(self.backButtonArrow) self.buttonsContainerNode.addSubnode(self.backButtonArrow)
@ -861,12 +861,15 @@ open class NavigationBar: ASDisplayNode {
self.titleNode.accessibilityTraits = .header self.titleNode.accessibilityTraits = .header
self.backButtonNode = NavigationButtonNode() self.backButtonNode = NavigationButtonNode()
self.backButtonNode.hitTestSlop = UIEdgeInsets(top: 0.0, left: -20.0, bottom: 0.0, right: 0.0)
self.badgeNode = NavigationBarBadgeNode(fillColor: self.presentationData.theme.buttonColor, strokeColor: self.presentationData.theme.buttonColor, textColor: self.presentationData.theme.badgeTextColor) self.badgeNode = NavigationBarBadgeNode(fillColor: self.presentationData.theme.buttonColor, strokeColor: self.presentationData.theme.buttonColor, textColor: self.presentationData.theme.badgeTextColor)
self.badgeNode.isUserInteractionEnabled = false self.badgeNode.isUserInteractionEnabled = false
self.badgeNode.isHidden = true self.badgeNode.isHidden = true
self.backButtonArrow = ASImageNode() self.backButtonArrow = ASImageNode()
self.backButtonArrow.displayWithoutProcessing = true self.backButtonArrow.displayWithoutProcessing = true
self.backButtonArrow.displaysAsynchronously = false self.backButtonArrow.displaysAsynchronously = false
self.backButtonArrow.isUserInteractionEnabled = false
self.leftButtonNode = NavigationButtonNode() self.leftButtonNode = NavigationButtonNode()
self.rightButtonNode = NavigationButtonNode() self.rightButtonNode = NavigationButtonNode()
self.rightButtonNode.hitTestSlop = UIEdgeInsets(top: -4.0, left: -4.0, bottom: -4.0, right: -10.0) self.rightButtonNode.hitTestSlop = UIEdgeInsets(top: -4.0, left: -4.0, bottom: -4.0, right: -10.0)

View File

@ -426,6 +426,7 @@ public final class NavigationButtonNode: ContextControllerSourceNode {
node.bold = false node.bold = false
node.isEnabled = true node.isEnabled = true
node.node = nil node.node = nil
node.hitTestSlop = isBack ? UIEdgeInsets(top: 0.0, left: -20.0, bottom: 0.0, right: 0.0) : UIEdgeInsets()
if 1 < self.nodes.count { if 1 < self.nodes.count {
for i in 1 ..< self.nodes.count { for i in 1 ..< self.nodes.count {

View File

@ -349,7 +349,7 @@ final class InstantPageControllerNode: ASDisplayNode, UIScrollViewDelegate {
let maxBarHeight: CGFloat let maxBarHeight: CGFloat
if !layout.safeInsets.top.isZero { if !layout.safeInsets.top.isZero {
if let statusBarHeight = layout.statusBarHeight, statusBarHeight > 34.0 { if let statusBarHeight = layout.statusBarHeight, statusBarHeight > 34.0 {
maxBarHeight = statusBarHeight + 34.0 maxBarHeight = statusBarHeight + 44.0
} else { } else {
maxBarHeight = layout.safeInsets.top + 34.0 maxBarHeight = layout.safeInsets.top + 34.0
} }

View File

@ -167,12 +167,7 @@ final class InstantPageNavigationBar: ASDisplayNode {
} }
func updateLayout(size: CGSize, minHeight: CGFloat, maxHeight: CGFloat, topInset: CGFloat, leftInset: CGFloat, rightInset: CGFloat, title: String?, pageProgress: CGFloat, transition: ContainedViewLayoutTransition) { func updateLayout(size: CGSize, minHeight: CGFloat, maxHeight: CGFloat, topInset: CGFloat, leftInset: CGFloat, rightInset: CGFloat, title: String?, pageProgress: CGFloat, transition: ContainedViewLayoutTransition) {
let progressHeight: CGFloat let progressHeight = size.height
if !topInset.isZero {
progressHeight = size.height - topInset + 11.0 - UIScreenPixel
} else {
progressHeight = size.height
}
transition.updateFrame(node: self.pageProgressNode, frame: CGRect(origin: CGPoint(x: 0.0, y: size.height - progressHeight), size: CGSize(width: floorToScreenPixels(size.width * pageProgress), height: progressHeight))) transition.updateFrame(node: self.pageProgressNode, frame: CGRect(origin: CGPoint(x: 0.0, y: size.height - progressHeight), size: CGSize(width: floorToScreenPixels(size.width * pageProgress), height: progressHeight)))
let transitionFactor = (size.height - minHeight) / (maxHeight - minHeight) let transitionFactor = (size.height - minHeight) / (maxHeight - minHeight)

View File

@ -1,39 +0,0 @@
import Foundation
import UIKit
import Display
import AsyncDisplayKit
final class ItemListMaskAccessoryItem: ListViewAccessoryItem {
private let sectionId: Int32
init(sectionId: Int32) {
self.sectionId = sectionId
}
func isEqualToItem(_ other: ListViewAccessoryItem) -> Bool {
if case let other as ItemListMaskAccessoryItem = other {
return self.sectionId == other.sectionId
}
return false
}
func node(synchronous: Bool) -> ListViewAccessoryItemNode {
let node = ItemListMaskAccessoryItemItemNode()
node.frame = CGRect(origin: CGPoint(), size: CGSize(width: 38.0, height: 38.0))
return node
}
}
final class ItemListMaskAccessoryItemItemNode: ListViewAccessoryItemNode {
let node: ASDisplayNode
override init() {
self.node = ASDisplayNode()
self.node.backgroundColor = .red
super.init()
self.addSubnode(self.node)
}
}

View File

@ -109,7 +109,14 @@ func presentLegacyMediaPickerGallery(context: AccountContext, peer: EnginePeer?,
(items, focusItem) = gallerySelectionItems(item: item, selectionContext: selectionContext, editingContext: editingContext, stickersContext: paintStickersContext, immediateThumbnail: immediateThumbnail) (items, focusItem) = gallerySelectionItems(item: item, selectionContext: selectionContext, editingContext: editingContext, stickersContext: paintStickersContext, immediateThumbnail: immediateThumbnail)
} }
let model = TGMediaPickerGalleryModel(context: legacyController.context, items: items, focus: focusItem, selectionContext: selectionContext, editingContext: editingContext, hasCaptions: true, allowCaptionEntities: true, hasTimer: hasTimer, onlyCrop: false, inhibitDocumentCaptions: false, hasSelectionPanel: true, hasCamera: false, recipientName: peer?.displayTitle(strings: presentationData.strings, displayOrder: presentationData.nameDisplayOrder))! let recipientName: String?
if peer?.id == context.account.peerId {
recipientName = presentationData.strings.DialogList_SavedMessages
} else {
recipientName = peer?.displayTitle(strings: presentationData.strings, displayOrder: presentationData.nameDisplayOrder)
}
let model = TGMediaPickerGalleryModel(context: legacyController.context, items: items, focus: focusItem, selectionContext: selectionContext, editingContext: editingContext, hasCaptions: true, allowCaptionEntities: true, hasTimer: hasTimer, onlyCrop: false, inhibitDocumentCaptions: false, hasSelectionPanel: true, hasCamera: false, recipientName: recipientName)!
model.stickersContext = paintStickersContext model.stickersContext = paintStickersContext
controller.model = model controller.model = model
model.controller = controller model.controller = controller

View File

@ -596,6 +596,8 @@ NSString *suffix = @"";
return @"iPhone 13 Mini"; return @"iPhone 13 Mini";
if ([platform isEqualToString:@"iPhone14,5"]) if ([platform isEqualToString:@"iPhone14,5"])
return @"iPhone 13"; return @"iPhone 13";
if ([platform isEqualToString:@"iPhone14,6"])
return @"iPhone SE (3rd gen)";
if ([platform hasPrefix:@"iPod1"]) if ([platform hasPrefix:@"iPod1"])
return @"iPod touch 1G"; return @"iPod touch 1G";
@ -728,6 +730,14 @@ NSString *suffix = @"";
[platform isEqualToString:@"iPad13,11"]) [platform isEqualToString:@"iPad13,11"])
return @"iPad Pro 12.9 inch (5th gen)"; return @"iPad Pro 12.9 inch (5th gen)";
if ([platform isEqualToString:@"iPad13,16"] ||
[platform isEqualToString:@"iPad13,17"])
return @"iPad Air (5th gen)";
if ([platform isEqualToString:@"iPad14,1"] ||
[platform isEqualToString:@"iPad14,2"])
return @"iPad mini (6th gen)";
if ([platform hasPrefix:@"iPhone"]) if ([platform hasPrefix:@"iPhone"])
return @"Unknown iPhone"; return @"Unknown iPhone";
if ([platform hasPrefix:@"iPod"]) if ([platform hasPrefix:@"iPod"])

View File

@ -401,6 +401,9 @@ final class PasscodeEntryControllerNode: ASDisplayNode {
Queue.mainQueue().after(1.5, { Queue.mainQueue().after(1.5, {
self.titleNode.setAttributedText(NSAttributedString(string: self.strings.EnterPasscode_EnterPasscode, font: titleFont, textColor: .white), animation: .crossFade) self.titleNode.setAttributedText(NSAttributedString(string: self.strings.EnterPasscode_EnterPasscode, font: titleFont, textColor: .white), animation: .crossFade)
if let validLayout = self.validLayout {
self.containerLayoutUpdated(validLayout, navigationBarHeight: 0.0, transition: .animated(duration: 0.5, curve: .easeInOut))
}
}) })
completion() completion()
@ -471,6 +474,8 @@ final class PasscodeEntryControllerNode: ASDisplayNode {
if layout.size.width == 320.0 || (isLandscape && keyboardHidden) { if layout.size.width == 320.0 || (isLandscape && keyboardHidden) {
self.iconNode.alpha = 0.0 self.iconNode.alpha = 0.0
} else {
self.iconNode.alpha = 1.0
} }
let passcodeLayout = PasscodeLayout(layout: layout, modalPresentation: self.modalPresentation) let passcodeLayout = PasscodeLayout(layout: layout, modalPresentation: self.modalPresentation)

View File

@ -11,7 +11,7 @@ enum PasscodeEntryTitleAnimation {
final class PasscodeEntryLabelNode: ASDisplayNode { final class PasscodeEntryLabelNode: ASDisplayNode {
private let wrapperNode: ASDisplayNode private let wrapperNode: ASDisplayNode
private let textNode: ASTextNode private let textNode: ImmediateTextNode
private var validLayout: CGSize? private var validLayout: CGSize?
@ -19,10 +19,11 @@ final class PasscodeEntryLabelNode: ASDisplayNode {
self.wrapperNode = ASDisplayNode() self.wrapperNode = ASDisplayNode()
self.wrapperNode.clipsToBounds = true self.wrapperNode.clipsToBounds = true
self.textNode = ASTextNode() self.textNode = ImmediateTextNode()
self.textNode.isLayerBacked = false self.textNode.isLayerBacked = false
self.textNode.textAlignment = .center self.textNode.textAlignment = .center
self.textNode.displaysAsynchronously = false self.textNode.displaysAsynchronously = false
self.textNode.maximumNumberOfLines = 2
super.init() super.init()
@ -56,9 +57,9 @@ final class PasscodeEntryLabelNode: ASDisplayNode {
snapshotView.frame = self.textNode.frame snapshotView.frame = self.textNode.frame
self.textNode.view.superview?.insertSubview(snapshotView, aboveSubview: self.textNode.view) self.textNode.view.superview?.insertSubview(snapshotView, aboveSubview: self.textNode.view)
self.textNode.alpha = 0.0 self.textNode.alpha = 0.0
self.textNode.attributedText = text
snapshotView.layer.animateAlpha(from: 1.0, to: 0.0, duration: 0.3, removeOnCompletion: false, completion: { [weak snapshotView] _ in snapshotView.layer.animateAlpha(from: 1.0, to: 0.0, duration: 0.3, removeOnCompletion: false, completion: { [weak snapshotView] _ in
snapshotView?.removeFromSuperview() snapshotView?.removeFromSuperview()
self.textNode.attributedText = text
self.textNode.alpha = 1.0 self.textNode.alpha = 1.0
self.textNode.layer.animateAlpha(from: 0.0, to: 1.0, duration: 0.3, completion: { _ in self.textNode.layer.animateAlpha(from: 0.0, to: 1.0, duration: 0.3, completion: { _ in
completion() completion()
@ -81,7 +82,7 @@ final class PasscodeEntryLabelNode: ASDisplayNode {
func updateLayout(size: CGSize, transition: ContainedViewLayoutTransition) -> CGSize { func updateLayout(size: CGSize, transition: ContainedViewLayoutTransition) -> CGSize {
self.validLayout = size self.validLayout = size
let textSize = self.textNode.measure(size) let textSize = self.textNode.updateLayout(size)
let textFrame = CGRect(x: floor((size.width - textSize.width) / 2.0), y: 0.0, width: textSize.width, height: textSize.height) let textFrame = CGRect(x: floor((size.width - textSize.width) / 2.0), y: 0.0, width: textSize.width, height: textSize.height)
transition.updateFrame(node: self.wrapperNode, frame: textFrame) transition.updateFrame(node: self.wrapperNode, frame: textFrame)
transition.updateFrame(node: self.textNode, frame: CGRect(origin: CGPoint(), size: textSize)) transition.updateFrame(node: self.textNode, frame: CGRect(origin: CGPoint(), size: textSize))

View File

@ -702,6 +702,7 @@ public final class ReactionContextNode: ASDisplayNode, UIScrollViewDelegate {
return nil return nil
} }
private let longPressDuration: Double = 1.5
@objc private func longPressGesture(_ recognizer: UILongPressGestureRecognizer) { @objc private func longPressGesture(_ recognizer: UILongPressGestureRecognizer) {
switch recognizer.state { switch recognizer.state {
case .began: case .began:
@ -709,7 +710,7 @@ public final class ReactionContextNode: ASDisplayNode, UIScrollViewDelegate {
if let itemNode = self.reactionItemNode(at: point) { if let itemNode = self.reactionItemNode(at: point) {
self.highlightedReaction = itemNode.item.reaction self.highlightedReaction = itemNode.item.reaction
if #available(iOS 13.0, *) { if #available(iOS 13.0, *) {
self.continuousHaptic = try? ContinuousHaptic(duration: 2.5) self.continuousHaptic = try? ContinuousHaptic(duration: longPressDuration)
} }
if self.hapticFeedback == nil { if self.hapticFeedback == nil {
@ -717,11 +718,11 @@ public final class ReactionContextNode: ASDisplayNode, UIScrollViewDelegate {
} }
if let (size, insets, anchorRect) = self.validLayout { if let (size, insets, anchorRect) = self.validLayout {
self.updateLayout(size: size, insets: insets, anchorRect: anchorRect, transition: .animated(duration: 2.5, curve: .linear), animateInFromAnchorRect: nil, animateOutToAnchorRect: nil, animateReactionHighlight: true) self.updateLayout(size: size, insets: insets, anchorRect: anchorRect, transition: .animated(duration: longPressDuration, curve: .linear), animateInFromAnchorRect: nil, animateOutToAnchorRect: nil, animateReactionHighlight: true)
} }
self.longPressTimer?.invalidate() self.longPressTimer?.invalidate()
self.longPressTimer = SwiftSignalKit.Timer(timeout: 2.5, repeat: false, completion: { [weak self] in self.longPressTimer = SwiftSignalKit.Timer(timeout: longPressDuration, repeat: false, completion: { [weak self] in
guard let strongSelf = self else { guard let strongSelf = self else {
return return
} }

View File

@ -138,16 +138,17 @@ private struct ShareSearchGridTransaction {
let insertions: [GridNodeInsertItem] let insertions: [GridNodeInsertItem]
let updates: [GridNodeUpdateItem] let updates: [GridNodeUpdateItem]
let animated: Bool let animated: Bool
let crossFade: Bool
} }
private func preparedGridEntryTransition(context: AccountContext, from fromEntries: [ShareSearchPeerEntry], to toEntries: [ShareSearchPeerEntry], interfaceInteraction: ShareControllerInteraction) -> ShareSearchGridTransaction { private func preparedGridEntryTransition(context: AccountContext, from fromEntries: [ShareSearchPeerEntry], to toEntries: [ShareSearchPeerEntry], interfaceInteraction: ShareControllerInteraction, crossFade: Bool) -> ShareSearchGridTransaction {
let (deleteIndices, indicesAndItems, updateIndices) = mergeListsStableWithUpdates(leftList: fromEntries, rightList: toEntries) let (deleteIndices, indicesAndItems, updateIndices) = mergeListsStableWithUpdates(leftList: fromEntries, rightList: toEntries)
let deletions = deleteIndices let deletions = deleteIndices
let insertions = indicesAndItems.map { GridNodeInsertItem(index: $0.0, item: $0.1.item(context: context, interfaceInteraction: interfaceInteraction), previousIndex: $0.2) } let insertions = indicesAndItems.map { GridNodeInsertItem(index: $0.0, item: $0.1.item(context: context, interfaceInteraction: interfaceInteraction), previousIndex: $0.2) }
let updates = updateIndices.map { GridNodeUpdateItem(index: $0.0, previousIndex: $0.2, item: $0.1.item(context: context, interfaceInteraction: interfaceInteraction)) } let updates = updateIndices.map { GridNodeUpdateItem(index: $0.0, previousIndex: $0.2, item: $0.1.item(context: context, interfaceInteraction: interfaceInteraction)) }
return ShareSearchGridTransaction(deletions: deletions, insertions: insertions, updates: updates, animated: false) return ShareSearchGridTransaction(deletions: deletions, insertions: insertions, updates: updates, animated: false, crossFade: crossFade)
} }
private func preparedRecentEntryTransition(context: AccountContext, from fromEntries: [ShareSearchRecentEntry], to toEntries: [ShareSearchRecentEntry], interfaceInteraction: ShareControllerInteraction) -> ShareSearchGridTransaction { private func preparedRecentEntryTransition(context: AccountContext, from fromEntries: [ShareSearchRecentEntry], to toEntries: [ShareSearchRecentEntry], interfaceInteraction: ShareControllerInteraction) -> ShareSearchGridTransaction {
@ -157,7 +158,7 @@ private func preparedRecentEntryTransition(context: AccountContext, from fromEnt
let insertions = indicesAndItems.map { GridNodeInsertItem(index: $0.0, item: $0.1.item(context: context, interfaceInteraction: interfaceInteraction), previousIndex: $0.2) } let insertions = indicesAndItems.map { GridNodeInsertItem(index: $0.0, item: $0.1.item(context: context, interfaceInteraction: interfaceInteraction), previousIndex: $0.2) }
let updates = updateIndices.map { GridNodeUpdateItem(index: $0.0, previousIndex: $0.2, item: $0.1.item(context: context, interfaceInteraction: interfaceInteraction)) } let updates = updateIndices.map { GridNodeUpdateItem(index: $0.0, previousIndex: $0.2, item: $0.1.item(context: context, interfaceInteraction: interfaceInteraction)) }
return ShareSearchGridTransaction(deletions: deletions, insertions: insertions, updates: updates, animated: false) return ShareSearchGridTransaction(deletions: deletions, insertions: insertions, updates: updates, animated: false, crossFade: false)
} }
final class ShareSearchContainerNode: ASDisplayNode, ShareContentContainerNode { final class ShareSearchContainerNode: ASDisplayNode, ShareContentContainerNode {
@ -236,8 +237,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 = searchQuery.get() let foundItems = self.searchQuery.get()
|> mapToSignal { query -> Signal<[ShareSearchPeerEntry]?, NoError> in |> mapToSignal { query -> 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())
@ -251,7 +252,7 @@ final class ShareSearchContainerNode: ASDisplayNode, ShareContentContainerNode {
) )
return combineLatest(accountPeer, foundLocalPeers, foundRemotePeers) return combineLatest(accountPeer, foundLocalPeers, foundRemotePeers)
|> map { accountPeer, foundLocalPeers, foundRemotePeers -> [ShareSearchPeerEntry]? in |> map { accountPeer, foundLocalPeers, foundRemotePeers -> ([ShareSearchPeerEntry]?, Bool) in
var entries: [ShareSearchPeerEntry] = [] var entries: [ShareSearchPeerEntry] = []
var index: Int32 = 0 var index: Int32 = 0
@ -276,7 +277,9 @@ final class ShareSearchContainerNode: ASDisplayNode, ShareContentContainerNode {
} }
} }
var isPlaceholder = false
if foundRemotePeers.2 { if foundRemotePeers.2 {
isPlaceholder = true
for _ in 0 ..< 4 { for _ in 0 ..< 4 {
entries.append(ShareSearchPeerEntry(index: index, peer: nil, presence: nil, theme: theme, strings: strings)) entries.append(ShareSearchPeerEntry(index: index, peer: nil, presence: nil, theme: theme, strings: strings))
index += 1 index += 1
@ -301,26 +304,29 @@ final class ShareSearchContainerNode: ASDisplayNode, ShareContentContainerNode {
} }
} }
return entries return (entries, isPlaceholder)
} }
} else { } else {
return .single(nil) return .single((nil, false))
} }
} }
let previousSearchItems = Atomic<[ShareSearchPeerEntry]?>(value: nil) let previousSearchItemsAndIsPlaceholder = Atomic<([ShareSearchPeerEntry]?, Bool)>(value: (nil, false))
self.searchDisposable.set((foundItems self.searchDisposable.set((foundItems
|> deliverOnMainQueue).start(next: { [weak self] entries in |> deliverOnMainQueue).start(next: { [weak self] entriesAndIsPlaceholder in
if let strongSelf = self { if let strongSelf = self {
let previousEntries = previousSearchItems.swap(entries) let (entries, isPlaceholder) = entriesAndIsPlaceholder
let previousEntries = previousSearchItemsAndIsPlaceholder.swap(entriesAndIsPlaceholder)
strongSelf.entries = entries ?? [] strongSelf.entries = entries ?? []
let firstTime = previousEntries == nil let firstTime = previousEntries.0 == nil
let transition = preparedGridEntryTransition(context: context, from: previousEntries ?? [], to: entries ?? [], interfaceInteraction: controllerInteraction) let crossFade = !firstTime && previousEntries.1 && !isPlaceholder
let transition = preparedGridEntryTransition(context: context, from: previousEntries.0 ?? [], to: entries ?? [], interfaceInteraction: controllerInteraction, crossFade: crossFade)
strongSelf.enqueueTransition(transition, firstTime: firstTime) strongSelf.enqueueTransition(transition, firstTime: firstTime)
if (previousEntries == nil) != (entries == nil) { if (previousEntries.0 == nil) != (entries == nil) {
if previousEntries == nil { if previousEntries.0 == nil {
strongSelf.recentGridNode.isHidden = true strongSelf.recentGridNode.isHidden = true
strongSelf.contentGridNode.isHidden = false strongSelf.contentGridNode.isHidden = false
strongSelf.transitionToContentGridLayout() strongSelf.transitionToContentGridLayout()
@ -589,6 +595,18 @@ final class ShareSearchContainerNode: ASDisplayNode, ShareContentContainerNode {
if transition.animated { if transition.animated {
itemTransition = .animated(duration: 0.3, curve: .spring) itemTransition = .animated(duration: 0.3, curve: .spring)
} }
if transition.crossFade {
if let snapshotView = self.contentGridNode.view.snapshotView(afterScreenUpdates: false) {
self.contentGridNode.view.superview?.insertSubview(snapshotView, aboveSubview: self.contentGridNode.view)
snapshotView.frame = self.contentGridNode.frame
snapshotView.layer.animateAlpha(from: 1.0, to: 0.0, duration: 0.25, removeOnCompletion: false, completion: { [weak snapshotView] _ in
snapshotView?.removeFromSuperview()
})
}
}
self.contentGridNode.transaction(GridNodeTransaction(deleteItems: transition.deletions, insertItems: transition.insertions, updateItems: transition.updates, scrollToItem: nil, updateLayout: nil, itemTransition: itemTransition, stationaryItems: .none, updateFirstIndexInSectionOffset: nil, synchronousLoads: true), completion: { _ in }) self.contentGridNode.transaction(GridNodeTransaction(deleteItems: transition.deletions, insertItems: transition.insertions, updateItems: transition.updates, scrollToItem: nil, updateLayout: nil, itemTransition: itemTransition, stationaryItems: .none, updateFirstIndexInSectionOffset: nil, synchronousLoads: true), completion: { _ in })
} }
} }

View File

@ -240,7 +240,12 @@ private final class TranslateScreenComponent: CombinedComponent {
let itemSpacing: CGFloat = 16.0 let itemSpacing: CGFloat = 16.0
let itemHeight: CGFloat = 44.0 let itemHeight: CGFloat = 44.0
let locale = Locale(identifier: environment.strings.baseLanguageCode) var languageCode = environment.strings.baseLanguageCode
let rawSuffix = "-raw"
if languageCode.hasSuffix(rawSuffix) {
languageCode = String(languageCode.dropLast(rawSuffix.count))
}
let locale = Locale(identifier: languageCode)
let fromLanguage: String let fromLanguage: String
if let languageCode = state.fromLanguage { if let languageCode = state.fromLanguage {
fromLanguage = locale.localizedString(forLanguageCode: languageCode) ?? "" fromLanguage = locale.localizedString(forLanguageCode: languageCode) ?? ""
@ -984,7 +989,14 @@ public class TranslateScreen: ViewController {
public convenience init(context: AccountContext, text: String, fromLanguage: String?, toLanguage: String? = nil, isExpanded: Bool = false) { public convenience init(context: AccountContext, text: String, fromLanguage: String?, toLanguage: String? = nil, isExpanded: Bool = false) {
let presentationData = context.sharedContext.currentPresentationData.with { $0 } let presentationData = context.sharedContext.currentPresentationData.with { $0 }
var toLanguage = toLanguage ?? presentationData.strings.baseLanguageCode
var baseLanguageCode = presentationData.strings.baseLanguageCode
let rawSuffix = "-raw"
if baseLanguageCode.hasSuffix(rawSuffix) {
baseLanguageCode = String(baseLanguageCode.dropLast(rawSuffix.count))
}
var toLanguage = toLanguage ?? baseLanguageCode
if toLanguage == fromLanguage { if toLanguage == fromLanguage {
toLanguage = "en" toLanguage = "en"