diff --git a/submodules/Postbox/Sources/Postbox.swift b/submodules/Postbox/Sources/Postbox.swift index 96b8cf988c..0c47192e44 100644 --- a/submodules/Postbox/Sources/Postbox.swift +++ b/submodules/Postbox/Sources/Postbox.swift @@ -1282,7 +1282,7 @@ public func openPostbox(basePath: String, seedConfiguration: SeedConfiguration, #if DEBUG //debugSaveState(basePath: basePath + "/db", name: "previous2") - //debugRestoreState(basePath: basePath + "/db", name: "previous2") + debugRestoreState(basePath: basePath + "/db", name: "previous2") #endif let startTime = CFAbsoluteTimeGetCurrent() diff --git a/submodules/ReactionSelectionNode/Sources/ReactionContextNode.swift b/submodules/ReactionSelectionNode/Sources/ReactionContextNode.swift index 23ffc175cf..bfa7064828 100644 --- a/submodules/ReactionSelectionNode/Sources/ReactionContextNode.swift +++ b/submodules/ReactionSelectionNode/Sources/ReactionContextNode.swift @@ -460,7 +460,7 @@ public final class ReactionContextNode: ASDisplayNode, UIScrollViewDelegate { } else { strongSelf.stableEmptyResultEmoji = nil } - emojiContent = emojiContent.withUpdatedItemGroups(panelItemGroups: emojiContent.panelItemGroups, contentItemGroups: emojiSearchResult.groups, itemContentUniqueId: emojiSearchResult.id, emptySearchResults: emptySearchResults, searchState: .active) + emojiContent = emojiContent.withUpdatedItemGroups(panelItemGroups: emojiContent.panelItemGroups, contentItemGroups: emojiSearchResult.groups, itemContentUniqueId: EmojiPagerContentComponent.ContentId(id: emojiSearchResult.id, version: 0), emptySearchResults: emptySearchResults, searchState: .active) } else { strongSelf.stableEmptyResultEmoji = nil } diff --git a/submodules/TelegramUI/Components/AvatarEditorScreen/Sources/AvatarEditorScreen.swift b/submodules/TelegramUI/Components/AvatarEditorScreen/Sources/AvatarEditorScreen.swift index 228b6f38c4..cb68af20bd 100644 --- a/submodules/TelegramUI/Components/AvatarEditorScreen/Sources/AvatarEditorScreen.swift +++ b/submodules/TelegramUI/Components/AvatarEditorScreen/Sources/AvatarEditorScreen.swift @@ -850,9 +850,9 @@ final class AvatarEditorScreenComponent: Component { } if state?.keyboardContentId == AnyHashable("emoji") { - data.emoji = data.emoji.withUpdatedItemGroups(panelItemGroups: data.emoji.panelItemGroups, contentItemGroups: searchResult.groups, itemContentUniqueId: searchResult.id, emptySearchResults: emptySearchResults, searchState: .active) + data.emoji = data.emoji.withUpdatedItemGroups(panelItemGroups: data.emoji.panelItemGroups, contentItemGroups: searchResult.groups, itemContentUniqueId: EmojiPagerContentComponent.ContentId(id: searchResult.id, version: 0), emptySearchResults: emptySearchResults, searchState: .active) } else { - data.stickers = data.stickers?.withUpdatedItemGroups(panelItemGroups: data.stickers?.panelItemGroups ?? searchResult.groups, contentItemGroups: searchResult.groups, itemContentUniqueId: searchResult.id, emptySearchResults: emptySearchResults, searchState: .active) + data.stickers = data.stickers?.withUpdatedItemGroups(panelItemGroups: data.stickers?.panelItemGroups ?? searchResult.groups, contentItemGroups: searchResult.groups, itemContentUniqueId: EmojiPagerContentComponent.ContentId(id: searchResult.id, version: 0), emptySearchResults: emptySearchResults, searchState: .active) } } diff --git a/submodules/TelegramUI/Components/ChatEntityKeyboardInputNode/Sources/ChatEntityKeyboardInputNode.swift b/submodules/TelegramUI/Components/ChatEntityKeyboardInputNode/Sources/ChatEntityKeyboardInputNode.swift index 6fa19c847c..2b16eded47 100644 --- a/submodules/TelegramUI/Components/ChatEntityKeyboardInputNode/Sources/ChatEntityKeyboardInputNode.swift +++ b/submodules/TelegramUI/Components/ChatEntityKeyboardInputNode/Sources/ChatEntityKeyboardInputNode.swift @@ -245,10 +245,10 @@ public final class ChatEntityKeyboardInputNode: ChatInputNode { private var hasRecentGifsDisposable: Disposable? private let emojiSearchDisposable = MetaDisposable() - private let emojiSearchResult = Promise<(groups: [EmojiPagerContentComponent.ItemGroup], id: AnyHashable)?>(nil) + private let emojiSearchResult = Promise<(groups: [EmojiPagerContentComponent.ItemGroup], id: AnyHashable, version: Int)?>(nil) private let stickerSearchDisposable = MetaDisposable() - private let stickerSearchResult = Promise<(groups: [EmojiPagerContentComponent.ItemGroup], id: AnyHashable)?>(nil) + private let stickerSearchResult = Promise<(groups: [EmojiPagerContentComponent.ItemGroup], id: AnyHashable, version: Int)?>(nil) private let controllerInteraction: ChatControllerInteraction? @@ -1079,13 +1079,15 @@ public final class ChatEntityKeyboardInputNode: ChatInputNode { } } + var version = 0 strongSelf.emojiSearchDisposable.set((resultSignal |> delay(0.15, queue: .mainQueue()) |> deliverOnMainQueue).start(next: { [weak self] result in guard let strongSelf = self else { return } - strongSelf.emojiSearchResult.set(.single((result, AnyHashable(query)))) + strongSelf.emojiSearchResult.set(.single((result, AnyHashable(query), version))) + version += 1 })) } case let .category(value): @@ -1127,12 +1129,14 @@ public final class ChatEntityKeyboardInputNode: ChatInputNode { )]) } + var version = 0 strongSelf.emojiSearchDisposable.set((resultSignal |> deliverOnMainQueue).start(next: { [weak self] result in guard let strongSelf = self else { return } - strongSelf.emojiSearchResult.set(.single((result, AnyHashable(value)))) + strongSelf.emojiSearchResult.set(.single((result, AnyHashable(value), version))) + version += 1 })) } }, @@ -1392,6 +1396,7 @@ public final class ChatEntityKeyboardInputNode: ChatInputNode { )], files.isFinalResult)) } + var version = 0 strongSelf.stickerSearchDisposable.set((resultSignal |> deliverOnMainQueue).start(next: { [weak self] result in guard let strongSelf = self else { @@ -1403,7 +1408,8 @@ public final class ChatEntityKeyboardInputNode: ChatInputNode { if group.items.isEmpty && !result.isFinalResult { return } - strongSelf.stickerSearchResult.set(.single((result.items, AnyHashable(value)))) + strongSelf.stickerSearchResult.set(.single((result.items, AnyHashable(value), version))) + version += 1 })) } }, @@ -1443,7 +1449,7 @@ public final class ChatEntityKeyboardInputNode: ChatInputNode { ) } if let emoji = inputData.emoji { - inputData.emoji = emoji.withUpdatedItemGroups(panelItemGroups: emoji.panelItemGroups, contentItemGroups: emojiSearchResult.groups, itemContentUniqueId: emojiSearchResult.id, emptySearchResults: emptySearchResults, searchState: .active) + inputData.emoji = emoji.withUpdatedItemGroups(panelItemGroups: emoji.panelItemGroups, contentItemGroups: emojiSearchResult.groups, itemContentUniqueId: EmojiPagerContentComponent.ContentId(id: emojiSearchResult.id, version: emojiSearchResult.version), emptySearchResults: emptySearchResults, searchState: .active) } } @@ -1457,7 +1463,7 @@ public final class ChatEntityKeyboardInputNode: ChatInputNode { ) } if let stickers = inputData.stickers { - inputData.stickers = stickers.withUpdatedItemGroups(panelItemGroups: stickers.panelItemGroups, contentItemGroups: stickerSearchResult.groups, itemContentUniqueId: stickerSearchResult.id, emptySearchResults: stickerSearchResults, searchState: .active) + inputData.stickers = stickers.withUpdatedItemGroups(panelItemGroups: stickers.panelItemGroups, contentItemGroups: stickerSearchResult.groups, itemContentUniqueId: EmojiPagerContentComponent.ContentId(id: stickerSearchResult.id, version: stickerSearchResult.version), emptySearchResults: stickerSearchResults, searchState: .active) } } diff --git a/submodules/TelegramUI/Components/EmojiStatusSelectionComponent/Sources/EmojiStatusSelectionComponent.swift b/submodules/TelegramUI/Components/EmojiStatusSelectionComponent/Sources/EmojiStatusSelectionComponent.swift index 8655e96284..bb803050ed 100644 --- a/submodules/TelegramUI/Components/EmojiStatusSelectionComponent/Sources/EmojiStatusSelectionComponent.swift +++ b/submodules/TelegramUI/Components/EmojiStatusSelectionComponent/Sources/EmojiStatusSelectionComponent.swift @@ -371,7 +371,7 @@ public final class EmojiStatusSelectionController: ViewController { } else { strongSelf.stableEmptyResultEmoji = nil } - emojiContent = emojiContent.withUpdatedItemGroups(panelItemGroups: emojiContent.panelItemGroups, contentItemGroups: emojiSearchResult.groups, itemContentUniqueId: emojiSearchResult.id, emptySearchResults: emptySearchResults, searchState: .active) + emojiContent = emojiContent.withUpdatedItemGroups(panelItemGroups: emojiContent.panelItemGroups, contentItemGroups: emojiSearchResult.groups, itemContentUniqueId: EmojiPagerContentComponent.ContentId(id: emojiSearchResult.id, version: 0), emptySearchResults: emptySearchResults, searchState: .active) } else { strongSelf.stableEmptyResultEmoji = nil } diff --git a/submodules/TelegramUI/Components/EntityKeyboard/BUILD b/submodules/TelegramUI/Components/EntityKeyboard/BUILD index 153632f6fb..b7e3f5c22f 100644 --- a/submodules/TelegramUI/Components/EntityKeyboard/BUILD +++ b/submodules/TelegramUI/Components/EntityKeyboard/BUILD @@ -43,6 +43,8 @@ swift_library( "//submodules/Components/LottieAnimationComponent:LottieAnimationComponent", "//submodules/LocalizedPeerData:LocalizedPeerData", "//submodules/TelegramNotices:TelegramNotices", + "//submodules/GZip", + "//submodules/rlottie:RLottieBinding", ], visibility = [ "//visibility:public", diff --git a/submodules/TelegramUI/Components/EntityKeyboard/Sources/EmojiPagerContentComponent.swift b/submodules/TelegramUI/Components/EntityKeyboard/Sources/EmojiPagerContentComponent.swift index 4485ea6d33..9f6cfc1fe7 100644 --- a/submodules/TelegramUI/Components/EntityKeyboard/Sources/EmojiPagerContentComponent.swift +++ b/submodules/TelegramUI/Components/EntityKeyboard/Sources/EmojiPagerContentComponent.swift @@ -2559,6 +2559,16 @@ public final class EmojiPagerContentComponent: Component { } } + public struct ContentId: Equatable { + public var id: AnyHashable + public var version: Int + + public init(id: AnyHashable, version: Int) { + self.id = id + self.version = version + } + } + public let id: AnyHashable public let context: AccountContext public let avatarPeer: EnginePeer? @@ -2568,7 +2578,7 @@ public final class EmojiPagerContentComponent: Component { public let panelItemGroups: [ItemGroup] public let contentItemGroups: [ItemGroup] public let itemLayoutType: ItemLayoutType - public let itemContentUniqueId: AnyHashable? + public let itemContentUniqueId: ContentId? public let searchState: SearchState public let warpContentsOnEdges: Bool public let displaySearchWithPlaceholder: String? @@ -2590,7 +2600,7 @@ public final class EmojiPagerContentComponent: Component { panelItemGroups: [ItemGroup], contentItemGroups: [ItemGroup], itemLayoutType: ItemLayoutType, - itemContentUniqueId: AnyHashable?, + itemContentUniqueId: ContentId?, searchState: SearchState, warpContentsOnEdges: Bool, displaySearchWithPlaceholder: String?, @@ -2624,7 +2634,7 @@ public final class EmojiPagerContentComponent: Component { self.selectedItems = selectedItems } - public func withUpdatedItemGroups(panelItemGroups: [ItemGroup], contentItemGroups: [ItemGroup], itemContentUniqueId: AnyHashable?, emptySearchResults: EmptySearchResults?, searchState: SearchState) -> EmojiPagerContentComponent { + public func withUpdatedItemGroups(panelItemGroups: [ItemGroup], contentItemGroups: [ItemGroup], itemContentUniqueId: ContentId?, emptySearchResults: EmptySearchResults?, searchState: SearchState) -> EmojiPagerContentComponent { return EmojiPagerContentComponent( id: self.id, context: self.context, @@ -6629,7 +6639,9 @@ public final class EmojiPagerContentComponent: Component { var animateContentCrossfade = false if let previousComponent, previousComponent.itemContentUniqueId != component.itemContentUniqueId, itemTransition.animation.isImmediate { - animateContentCrossfade = true + if previousComponent.itemContentUniqueId?.id != component.itemContentUniqueId?.id { + animateContentCrossfade = true + } } let crossfadeMinScale: CGFloat = 0.4 diff --git a/submodules/TelegramUI/Components/EntityKeyboard/Sources/EmojiSearchContent.swift b/submodules/TelegramUI/Components/EntityKeyboard/Sources/EmojiSearchContent.swift index d4769f77e0..4564a0d9a8 100644 --- a/submodules/TelegramUI/Components/EntityKeyboard/Sources/EmojiSearchContent.swift +++ b/submodules/TelegramUI/Components/EntityKeyboard/Sources/EmojiSearchContent.swift @@ -390,7 +390,7 @@ public final class EmojiSearchContent: ASDisplayNode, EntitySearchContainerNode panelItemGroups: [], contentItemGroups: self.itemGroups, itemLayoutType: .compact, - itemContentUniqueId: "main", + itemContentUniqueId: EmojiPagerContentComponent.ContentId(id: "main", version: 0), searchState: .empty, warpContentsOnEdges: false, displaySearchWithPlaceholder: "Search Emoji", @@ -411,7 +411,7 @@ public final class EmojiSearchContent: ASDisplayNode, EntitySearchContainerNode iconFile: nil ) } - emojiContent = emojiContent.withUpdatedItemGroups(panelItemGroups: emojiContent.panelItemGroups, contentItemGroups: emojiSearchResult.groups, itemContentUniqueId: emojiSearchResult.id, emptySearchResults: emptySearchResults, searchState: .active) + emojiContent = emojiContent.withUpdatedItemGroups(panelItemGroups: emojiContent.panelItemGroups, contentItemGroups: emojiSearchResult.groups, itemContentUniqueId: EmojiPagerContentComponent.ContentId(id: emojiSearchResult.id, version: 0), emptySearchResults: emptySearchResults, searchState: .active) } let _ = self.keyboardView.update( diff --git a/submodules/TelegramUI/Components/EntityKeyboard/Sources/EmojiSearchSearchBarComponent.swift b/submodules/TelegramUI/Components/EntityKeyboard/Sources/EmojiSearchSearchBarComponent.swift index 4cf126676c..087d776de1 100644 --- a/submodules/TelegramUI/Components/EntityKeyboard/Sources/EmojiSearchSearchBarComponent.swift +++ b/submodules/TelegramUI/Components/EntityKeyboard/Sources/EmojiSearchSearchBarComponent.swift @@ -53,6 +53,44 @@ private final class RoundMaskView: UIImageView { } } +private final class HoldGestureRecognizer: UITapGestureRecognizer { + private var currentHighlightPoint: CGPoint? + var updateHighlight: ((CGPoint?) -> Void)? + + override var state: UIGestureRecognizer.State { + didSet { + print("set state \(self.state)") + } + } + + override func reset() { + super.reset() + + if let _ = self.currentHighlightPoint { + self.currentHighlightPoint = nil + self.updateHighlight?(nil) + } + } + + override func touchesBegan(_ touches: Set, with event: UIEvent) { + super.touchesBegan(touches, with: event) + + let point = touches.first?.location(in: self.view) + if self.currentHighlightPoint == nil { + self.currentHighlightPoint = point + self.updateHighlight?(point) + } + } + + override func touchesEnded(_ touches: Set, with event: UIEvent) { + super.touchesEnded(touches, with: event) + } + + override func touchesCancelled(_ touches: Set, with event: UIEvent) { + super.touchesCancelled(touches, with: event) + } +} + final class EmojiSearchSearchBarComponent: Component { enum TextInputState: Equatable { case inactive @@ -212,7 +250,7 @@ final class EmojiSearchSearchBarComponent: Component { private let selectedItemTintBackground: SimpleLayer private var component: EmojiSearchSearchBarComponent? - private weak var state: EmptyComponentState? + private weak var componentState: EmptyComponentState? private var itemLayout: ItemLayout? private var ignoreScrolling: Bool = false @@ -220,6 +258,7 @@ final class EmojiSearchSearchBarComponent: Component { private let roundMaskView: RoundMaskView private let tintRoundMaskView: RoundMaskView + private var highlightedItem: AnyHashable? private var selectedItem: AnyHashable? private lazy var hapticFeedback: HapticFeedback = { @@ -271,7 +310,29 @@ final class EmojiSearchSearchBarComponent: Component { self.scrollView.layer.addSublayer(self.selectedItemBackground) self.tintScrollView.layer.addSublayer(self.selectedItemTintBackground) - self.addGestureRecognizer(UITapGestureRecognizer(target: self, action: #selector(self.tapGesture(_:)))) + let tapRecognizer = HoldGestureRecognizer(target: self, action: #selector(self.tapGesture(_:))) + tapRecognizer.updateHighlight = { [weak self] point in + guard let self else { + return + } + var highlightedItem: AnyHashable? + + if let point = point { + let location = self.convert(point, to: self.scrollView) + for (id, itemView) in self.visibleItemViews { + if let itemComponentView = itemView.view.view, itemComponentView.frame.contains(location) { + highlightedItem = id + break + } + } + } + + if self.highlightedItem != highlightedItem { + self.highlightedItem = highlightedItem + self.componentState?.updated(transition: .easeInOut(duration: 0.2)) + } + } + self.addGestureRecognizer(tapRecognizer) } required init?(coder: NSCoder) { @@ -296,7 +357,7 @@ final class EmojiSearchSearchBarComponent: Component { AudioServicesPlaySystemSound(0x450) self.hapticFeedback.tap() } - self.state?.updated(transition: .immediate) + self.componentState?.updated(transition: .easeInOut(duration: 0.2)) if let _ = self.selectedItem, let categories = component.categories, let group = categories.groups.first(where: { $0.id == itemId }) { component.searchTermUpdated(group.identifiers.joined(separator: "")) @@ -339,7 +400,7 @@ final class EmojiSearchSearchBarComponent: Component { transition.setBoundsOrigin(view: self.scrollView, origin: CGPoint()) self.updateScrolling(transition: transition, fromScrolling: false) - self.state?.updated(transition: transition) + self.componentState?.updated(transition: transition) if dispatchEvent { self.component?.searchTermUpdated(nil) @@ -426,12 +487,17 @@ final class EmojiSearchSearchBarComponent: Component { itemTransition.setPosition(view: view, position: CGPoint(x: itemFrame.midX, y: itemFrame.midY)) itemTransition.setBounds(view: view, bounds: CGRect(origin: CGPoint(), size: CGSize(width: itemLayout.itemSize.width, height: itemLayout.itemSize.height))) - let scaleFactor = itemFrame.width / itemLayout.itemSize.width - itemTransition.setSublayerTransform(view: view, transform: CATransform3DMakeScale(scaleFactor, scaleFactor, 1.0)) + + var scaleFactor = itemFrame.width / itemLayout.itemSize.width + if self.highlightedItem == AnyHashable(item.id) { + scaleFactor *= 0.8 + } + + itemTransition.setScale(view: view, scale: scaleFactor) itemTransition.setPosition(view: itemView.tintView, position: CGPoint(x: itemFrame.midX, y: itemFrame.midY)) itemTransition.setBounds(view: itemView.tintView, bounds: CGRect(origin: CGPoint(), size: CGSize(width: itemLayout.itemSize.width, height: itemLayout.itemSize.height))) - itemTransition.setSublayerTransform(view: itemView.tintView, transform: CATransform3DMakeScale(scaleFactor, scaleFactor, 1.0)) + itemTransition.setScale(view: itemView.tintView, scale: scaleFactor) itemTransition.setAlpha(view: view, alpha: itemAlpha) itemTransition.setAlpha(view: itemView.tintView, alpha: itemAlpha) @@ -476,23 +542,57 @@ final class EmojiSearchSearchBarComponent: Component { } if let selectedItem = self.selectedItem, let index = items.firstIndex(where: { AnyHashable($0.id) == selectedItem }) { - self.selectedItemBackground.isHidden = false - self.selectedItemTintBackground.isHidden = false - let selectedItemCenter = itemLayout.frame(at: index).center let selectionSize = CGSize(width: 28.0, height: 28.0) - self.selectedItemBackground.backgroundColor = component.useOpaqueTheme ? component.theme.chat.inputMediaPanel.panelContentOpaqueSearchOverlayHighlightColor.cgColor : component.theme.chat.inputMediaPanel.panelContentVibrantSearchOverlayHighlightColor.cgColor self.selectedItemTintBackground.backgroundColor = UIColor(white: 1.0, alpha: 0.15).cgColor self.selectedItemBackground.cornerRadius = selectionSize.height * 0.5 self.selectedItemTintBackground.cornerRadius = selectionSize.height * 0.5 let selectionFrame = CGRect(origin: CGPoint(x: floor(selectedItemCenter.x - selectionSize.width * 0.5), y: floor(selectedItemCenter.y - selectionSize.height * 0.5)), size: selectionSize) - self.selectedItemBackground.frame = selectionFrame - self.selectedItemTintBackground.frame = selectionFrame + + self.selectedItemBackground.bounds = CGRect(origin: CGPoint(), size: selectionFrame.size) + self.selectedItemTintBackground.bounds = CGRect(origin: CGPoint(), size: selectionFrame.size) + + if self.selectedItemBackground.opacity == 0.0 { + self.selectedItemBackground.position = selectionFrame.center + self.selectedItemTintBackground.position = selectionFrame.center + + self.selectedItemBackground.opacity = 1.0 + self.selectedItemTintBackground.opacity = 1.0 + + Transition.immediate.setScale(layer: self.selectedItemBackground, scale: 1.0) + Transition.immediate.setScale(layer: self.selectedItemTintBackground, scale: 1.0) + + if !transition.animation.isImmediate { + self.selectedItemBackground.animateAlpha(from: 0.0, to: 1.0, duration: 0.2) + self.selectedItemTintBackground.animateAlpha(from: 0.0, to: 1.0, duration: 0.2) + + self.selectedItemBackground.animateSpring(from: 0.1 as NSNumber, to: 1.0 as NSNumber, keyPath: "transform.scale", duration: 0.5, damping: 92.0) + self.selectedItemTintBackground.animateSpring(from: 0.1 as NSNumber, to: 1.0 as NSNumber, keyPath: "transform.scale", duration: 0.5, damping: 92.0) + } + } else { + if self.selectedItemBackground.position != selectionFrame.center { + transition.setPosition(layer: self.selectedItemBackground, position: selectionFrame.center) + transition.setPosition(layer: self.selectedItemTintBackground, position: selectionFrame.center) + + if case let .curve(duration, _) = transition.animation { + Transition.immediate.setScale(layer: self.selectedItemBackground, scale: 1.0) + Transition.immediate.setScale(layer: self.selectedItemTintBackground, scale: 1.0) + + self.selectedItemBackground.animateKeyframes(values: [1.0 as NSNumber, 0.75 as NSNumber, 1.0 as NSNumber], duration: duration, keyPath: "transform.scale") + self.selectedItemTintBackground.animateKeyframes(values: [1.0 as NSNumber, 0.75 as NSNumber, 1.0 as NSNumber], duration: duration, keyPath: "transform.scale") + } else { + transition.setScale(layer: self.selectedItemBackground, scale: 1.0) + transition.setScale(layer: self.selectedItemTintBackground, scale: 1.0) + } + } + } } else { - self.selectedItemBackground.isHidden = true - self.selectedItemTintBackground.isHidden = true + transition.setAlpha(layer: self.selectedItemBackground, alpha: 0.0) + transition.setScale(layer: self.selectedItemBackground, scale: 0.8) + transition.setAlpha(layer: self.selectedItemTintBackground, alpha: 0.0) + transition.setScale(layer: self.selectedItemTintBackground, scale: 0.8) } let scrollBounds = self.scrollView.bounds @@ -507,7 +607,7 @@ final class EmojiSearchSearchBarComponent: Component { func update(component: EmojiSearchSearchBarComponent, availableSize: CGSize, state: EmptyComponentState, environment: Environment, transition: Transition) -> CGSize { self.component = component - self.state = state + self.componentState = state let textSize = self.textView.update( transition: .immediate,