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
if let strongSelf = self, let previousItem = strongSelf.previousItem, case let .item(itemValue) = previousItem {
if let customBackButtonText = strongSelf.customBackButtonText {
strongSelf.backButtonNode.updateManualText(customBackButtonText)
strongSelf.backButtonNode.updateManualText(customBackButtonText, isBack: true)
} else if let backBarButtonItem = itemValue.backBarButtonItem {
strongSelf.backButtonNode.updateManualText(backBarButtonItem.title ?? "")
strongSelf.backButtonNode.updateManualText(backBarButtonItem.title ?? "", isBack: true)
} else {
strongSelf.backButtonNode.updateManualText(itemValue.title ?? "")
strongSelf.backButtonNode.updateManualText(itemValue.title ?? "", isBack: true)
}
strongSelf.invalidateCalculatedLayout()
strongSelf.requestLayout()
@ -548,11 +548,11 @@ open class NavigationBar: ASDisplayNode {
self.previousItemBackListenerKey = itemValue.addSetBackBarButtonItemListener { [weak self] _, _, _ in
if let strongSelf = self, let previousItem = strongSelf.previousItem, case let .item(itemValue) = previousItem {
if let customBackButtonText = strongSelf.customBackButtonText {
strongSelf.backButtonNode.updateManualText(customBackButtonText)
strongSelf.backButtonNode.updateManualText(customBackButtonText, isBack: true)
} else if let backBarButtonItem = itemValue.backBarButtonItem {
strongSelf.backButtonNode.updateManualText(backBarButtonItem.title ?? "")
strongSelf.backButtonNode.updateManualText(backBarButtonItem.title ?? "", isBack: true)
} else {
strongSelf.backButtonNode.updateManualText(itemValue.title ?? "")
strongSelf.backButtonNode.updateManualText(itemValue.title ?? "", isBack: true)
}
strongSelf.invalidateCalculatedLayout()
strongSelf.requestLayout()
@ -682,7 +682,7 @@ open class NavigationBar: ASDisplayNode {
}
if let backTitle = backTitle {
self.backButtonNode.updateManualText(backTitle)
self.backButtonNode.updateManualText(backTitle, isBack: true)
if self.backButtonNode.supernode == nil {
self.buttonsContainerNode.addSubnode(self.backButtonNode)
self.buttonsContainerNode.addSubnode(self.backButtonArrow)
@ -861,12 +861,15 @@ open class NavigationBar: ASDisplayNode {
self.titleNode.accessibilityTraits = .header
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.isUserInteractionEnabled = false
self.badgeNode.isHidden = true
self.backButtonArrow = ASImageNode()
self.backButtonArrow.displayWithoutProcessing = true
self.backButtonArrow.displaysAsynchronously = false
self.backButtonArrow.isUserInteractionEnabled = false
self.leftButtonNode = NavigationButtonNode()
self.rightButtonNode = NavigationButtonNode()
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.isEnabled = true
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 {
for i in 1 ..< self.nodes.count {

View File

@ -349,7 +349,7 @@ final class InstantPageControllerNode: ASDisplayNode, UIScrollViewDelegate {
let maxBarHeight: CGFloat
if !layout.safeInsets.top.isZero {
if let statusBarHeight = layout.statusBarHeight, statusBarHeight > 34.0 {
maxBarHeight = statusBarHeight + 34.0
maxBarHeight = statusBarHeight + 44.0
} else {
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) {
let progressHeight: CGFloat
if !topInset.isZero {
progressHeight = size.height - topInset + 11.0 - UIScreenPixel
} else {
progressHeight = size.height
}
let 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)))
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)
}
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
controller.model = model
model.controller = controller

View File

@ -596,6 +596,8 @@ NSString *suffix = @"";
return @"iPhone 13 Mini";
if ([platform isEqualToString:@"iPhone14,5"])
return @"iPhone 13";
if ([platform isEqualToString:@"iPhone14,6"])
return @"iPhone SE (3rd gen)";
if ([platform hasPrefix:@"iPod1"])
return @"iPod touch 1G";
@ -727,6 +729,14 @@ NSString *suffix = @"";
[platform isEqualToString:@"iPad13,10"] ||
[platform isEqualToString:@"iPad13,11"])
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"])
return @"Unknown iPhone";

View File

@ -401,6 +401,9 @@ final class PasscodeEntryControllerNode: ASDisplayNode {
Queue.mainQueue().after(1.5, {
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()
@ -471,6 +474,8 @@ final class PasscodeEntryControllerNode: ASDisplayNode {
if layout.size.width == 320.0 || (isLandscape && keyboardHidden) {
self.iconNode.alpha = 0.0
} else {
self.iconNode.alpha = 1.0
}
let passcodeLayout = PasscodeLayout(layout: layout, modalPresentation: self.modalPresentation)

View File

@ -11,7 +11,7 @@ enum PasscodeEntryTitleAnimation {
final class PasscodeEntryLabelNode: ASDisplayNode {
private let wrapperNode: ASDisplayNode
private let textNode: ASTextNode
private let textNode: ImmediateTextNode
private var validLayout: CGSize?
@ -19,10 +19,11 @@ final class PasscodeEntryLabelNode: ASDisplayNode {
self.wrapperNode = ASDisplayNode()
self.wrapperNode.clipsToBounds = true
self.textNode = ASTextNode()
self.textNode = ImmediateTextNode()
self.textNode.isLayerBacked = false
self.textNode.textAlignment = .center
self.textNode.displaysAsynchronously = false
self.textNode.maximumNumberOfLines = 2
super.init()
@ -56,9 +57,9 @@ final class PasscodeEntryLabelNode: ASDisplayNode {
snapshotView.frame = self.textNode.frame
self.textNode.view.superview?.insertSubview(snapshotView, aboveSubview: self.textNode.view)
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?.removeFromSuperview()
self.textNode.attributedText = text
self.textNode.alpha = 1.0
self.textNode.layer.animateAlpha(from: 0.0, to: 1.0, duration: 0.3, completion: { _ in
completion()
@ -81,7 +82,7 @@ final class PasscodeEntryLabelNode: ASDisplayNode {
func updateLayout(size: CGSize, transition: ContainedViewLayoutTransition) -> CGSize {
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)
transition.updateFrame(node: self.wrapperNode, frame: textFrame)
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
}
private let longPressDuration: Double = 1.5
@objc private func longPressGesture(_ recognizer: UILongPressGestureRecognizer) {
switch recognizer.state {
case .began:
@ -709,7 +710,7 @@ public final class ReactionContextNode: ASDisplayNode, UIScrollViewDelegate {
if let itemNode = self.reactionItemNode(at: point) {
self.highlightedReaction = itemNode.item.reaction
if #available(iOS 13.0, *) {
self.continuousHaptic = try? ContinuousHaptic(duration: 2.5)
self.continuousHaptic = try? ContinuousHaptic(duration: longPressDuration)
}
if self.hapticFeedback == nil {
@ -717,11 +718,11 @@ public final class ReactionContextNode: ASDisplayNode, UIScrollViewDelegate {
}
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 = 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 {
return
}

View File

@ -138,16 +138,17 @@ private struct ShareSearchGridTransaction {
let insertions: [GridNodeInsertItem]
let updates: [GridNodeUpdateItem]
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 deletions = deleteIndices
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)) }
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 {
@ -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 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 {
@ -236,8 +237,8 @@ final class ShareSearchContainerNode: ASDisplayNode, ShareContentContainerNode {
self.cancelButtonNode.addTarget(self, action: #selector(self.cancelPressed), forControlEvents: .touchUpInside)
let foundItems = searchQuery.get()
|> mapToSignal { query -> Signal<[ShareSearchPeerEntry]?, NoError> in
let foundItems = self.searchQuery.get()
|> mapToSignal { query -> 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())
@ -251,7 +252,7 @@ final class ShareSearchContainerNode: ASDisplayNode, ShareContentContainerNode {
)
return combineLatest(accountPeer, foundLocalPeers, foundRemotePeers)
|> map { accountPeer, foundLocalPeers, foundRemotePeers -> [ShareSearchPeerEntry]? in
|> map { accountPeer, foundLocalPeers, foundRemotePeers -> ([ShareSearchPeerEntry]?, Bool) in
var entries: [ShareSearchPeerEntry] = []
var index: Int32 = 0
@ -276,7 +277,9 @@ final class ShareSearchContainerNode: ASDisplayNode, ShareContentContainerNode {
}
}
var isPlaceholder = false
if foundRemotePeers.2 {
isPlaceholder = true
for _ in 0 ..< 4 {
entries.append(ShareSearchPeerEntry(index: index, peer: nil, presence: nil, theme: theme, strings: strings))
index += 1
@ -301,26 +304,29 @@ final class ShareSearchContainerNode: ASDisplayNode, ShareContentContainerNode {
}
}
return entries
return (entries, isPlaceholder)
}
} 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
|> deliverOnMainQueue).start(next: { [weak self] entries in
|> deliverOnMainQueue).start(next: { [weak self] entriesAndIsPlaceholder in
if let strongSelf = self {
let previousEntries = previousSearchItems.swap(entries)
let (entries, isPlaceholder) = entriesAndIsPlaceholder
let previousEntries = previousSearchItemsAndIsPlaceholder.swap(entriesAndIsPlaceholder)
strongSelf.entries = entries ?? []
let firstTime = previousEntries.0 == nil
let crossFade = !firstTime && previousEntries.1 && !isPlaceholder
let firstTime = previousEntries == nil
let transition = preparedGridEntryTransition(context: context, from: previousEntries ?? [], to: entries ?? [], interfaceInteraction: controllerInteraction)
let transition = preparedGridEntryTransition(context: context, from: previousEntries.0 ?? [], to: entries ?? [], interfaceInteraction: controllerInteraction, crossFade: crossFade)
strongSelf.enqueueTransition(transition, firstTime: firstTime)
if (previousEntries == nil) != (entries == nil) {
if previousEntries == nil {
if (previousEntries.0 == nil) != (entries == nil) {
if previousEntries.0 == nil {
strongSelf.recentGridNode.isHidden = true
strongSelf.contentGridNode.isHidden = false
strongSelf.transitionToContentGridLayout()
@ -584,11 +590,23 @@ final class ShareSearchContainerNode: ASDisplayNode, ShareContentContainerNode {
private func dequeueTransition() {
if let (transition, _) = self.enqueuedTransitions.first {
self.enqueuedTransitions.remove(at: 0)
var itemTransition: ContainedViewLayoutTransition = .immediate
if transition.animated {
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 })
}
}

View File

@ -240,7 +240,12 @@ private final class TranslateScreenComponent: CombinedComponent {
let itemSpacing: CGFloat = 16.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
if let languageCode = state.fromLanguage {
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) {
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 {
toLanguage = "en"