Channel reactions

This commit is contained in:
Ali
2023-11-07 17:58:36 +04:00
parent 216b731562
commit 4f23fa6e09
13 changed files with 641 additions and 138 deletions

View File

@@ -20,6 +20,7 @@ public final class EmojiSelectionComponent: Component {
public let backgroundIconColor: UIColor?
public let backgroundColor: UIColor
public let separatorColor: UIColor
public let backspace: (() -> Void)?
public init(
theme: PresentationTheme,
@@ -30,7 +31,8 @@ public final class EmojiSelectionComponent: Component {
emojiContent: EmojiPagerContentComponent,
backgroundIconColor: UIColor?,
backgroundColor: UIColor,
separatorColor: UIColor
separatorColor: UIColor,
backspace: (() -> Void)?
) {
self.theme = theme
self.strings = strings
@@ -41,6 +43,7 @@ public final class EmojiSelectionComponent: Component {
self.backgroundIconColor = backgroundIconColor
self.backgroundColor = backgroundColor
self.separatorColor = separatorColor
self.backspace = backspace
}
public static func ==(lhs: EmojiSelectionComponent, rhs: EmojiSelectionComponent) -> Bool {
@@ -71,6 +74,9 @@ public final class EmojiSelectionComponent: Component {
if lhs.separatorColor != rhs.separatorColor {
return false
}
if (lhs.backspace == nil) != (rhs.backspace == nil) {
return false
}
return true
}
@@ -83,6 +89,9 @@ public final class EmojiSelectionComponent: Component {
private let shadowView: UIImageView
private let cornersView: UIImageView
private let backspaceBackgroundView: UIImageView
private let backspaceButtonView: HighlightTrackingButton
private var component: EmojiSelectionComponent?
private weak var state: EmptyComponentState?
@@ -95,6 +104,9 @@ public final class EmojiSelectionComponent: Component {
self.shadowView = UIImageView()
self.cornersView = UIImageView()
self.backspaceBackgroundView = UIImageView()
self.backspaceButtonView = HighlightTrackingButton()
super.init(frame: frame)
self.addSubview(self.keyboardClippingView)
@@ -104,6 +116,9 @@ public final class EmojiSelectionComponent: Component {
self.addSubview(self.cornersView)
self.addSubview(self.shadowView)
self.backspaceButtonView.addSubview(self.backspaceBackgroundView)
self.addSubview(self.backspaceButtonView)
self.shadowView.image = generateImage(CGSize(width: 16.0, height: 16.0), rotatedContext: { size, context in
context.clear(CGRect(origin: CGPoint(), size: size))
context.setShadow(offset: CGSize(), blur: 40.0, color: UIColor(white: 0.0, alpha: 0.05).cgColor)
@@ -123,6 +138,35 @@ public final class EmojiSelectionComponent: Component {
context.fillPath()
context.clear(CGRect(origin: CGPoint(x: 8.0, y: 0.0), size: CGSize(width: 1.0, height: size.height)))
})?.withRenderingMode(.alwaysTemplate).stretchableImage(withLeftCapWidth: 8, topCapHeight: 16)
self.backspaceButtonView.highligthedChanged = { [weak self] highlighted in
if let self, self.backspaceButtonView.bounds.width > 0.0 {
let topScale: CGFloat = (self.backspaceButtonView.bounds.width - 8.0) / self.backspaceButtonView.bounds.width
let maxScale: CGFloat = (self.backspaceButtonView.bounds.width + 2.0) / self.backspaceButtonView.bounds.width
if highlighted {
self.backspaceButtonView.layer.removeAnimation(forKey: "sublayerTransform")
self.backspaceButtonView.alpha = 0.7
let transition = Transition(animation: .curve(duration: 0.2, curve: .easeInOut))
transition.setScale(layer: self.backspaceButtonView.layer, scale: topScale)
} else {
self.backspaceButtonView.alpha = 1.0
self.backspaceButtonView.layer.animateAlpha(from: 7, to: 1.0, duration: 0.2)
let transition = Transition(animation: .none)
transition.setScale(layer: self.backspaceButtonView.layer, scale: 1.0)
self.backspaceButtonView.layer.animateScale(from: topScale, to: maxScale, duration: 0.13, timingFunction: CAMediaTimingFunctionName.easeOut.rawValue, removeOnCompletion: false, completion: { [weak self] _ in
guard let self else {
return
}
self.backspaceButtonView.layer.animateScale(from: maxScale, to: 1.0, duration: 0.1, timingFunction: CAMediaTimingFunctionName.easeIn.rawValue)
})
}
}
}
self.backspaceButtonView.addTarget(self, action: #selector(self.backspacePressed), for: .touchUpInside)
}
required init?(coder: NSCoder) {
@@ -132,12 +176,17 @@ public final class EmojiSelectionComponent: Component {
deinit {
}
@objc private func backspacePressed() {
self.component?.backspace?()
}
func update(component: EmojiSelectionComponent, availableSize: CGSize, state: EmptyComponentState, environment: Environment<EnvironmentType>, transition: Transition) -> CGSize {
self.backgroundColor = component.backgroundColor
let panelBackgroundColor = component.backgroundColor.withMultipliedAlpha(0.85)
self.panelBackgroundView.updateColor(color: panelBackgroundColor, transition: .immediate)
self.panelSeparatorView.backgroundColor = component.separatorColor
let previousComponent = self.component
self.component = component
self.state = state
@@ -148,13 +197,41 @@ public final class EmojiSelectionComponent: Component {
let topPanelHeight: CGFloat = 42.0
let backspaceButtonInset = UIEdgeInsets(top: 9.0, left: 0.0, bottom: 36.0, right: 9.0)
let backspaceButtonSize = CGSize(width: 36.0, height: 36.0)
if previousComponent?.theme !== component.theme {
self.backspaceBackgroundView.image = generateImage(CGSize(width: backspaceButtonSize.width + 12.0 * 2.0, height: backspaceButtonSize.height + 12.0 * 2.0), rotatedContext: { size, context in
context.clear(CGRect(origin: CGPoint(), size: size))
context.setShadow(offset: CGSize(), blur: 40.0, color: UIColor(white: 0.0, alpha: 0.15).cgColor)
context.setFillColor(component.theme.list.plainBackgroundColor.cgColor)
context.fillEllipse(in: CGRect(origin: CGPoint(x: 12.0, y: 12.0), size: backspaceButtonSize))
context.setShadow(offset: CGSize(), blur: 0.0, color: nil)
if let image = generateTintedImage(image: UIImage(bundleImageName: "Chat/Input/Media/EntityInputClearIcon"), color: component.theme.chat.inputMediaPanel.panelIconColor) {
let imageSize = image.size
context.draw(image.cgImage!, in: CGRect(origin: CGPoint(x: 12.0 + floor((backspaceButtonSize.width - imageSize.width) * 0.5) - 1.0, y: 12.0 + floor((backspaceButtonSize.height - imageSize.height) * 0.5)), size: imageSize))
}
})
}
self.backspaceBackgroundView.frame = CGRect(origin: CGPoint(), size: backspaceButtonSize).insetBy(dx: -12.0, dy: -12.0)
let backspaceButtonFrame = CGRect(origin: CGPoint(x: availableSize.width - component.sideInset - backspaceButtonInset.right - backspaceButtonSize.width, y: availableSize.height - component.bottomInset - backspaceButtonInset.bottom), size: backspaceButtonSize)
transition.setPosition(view: self.backspaceButtonView, position: backspaceButtonFrame.center)
transition.setBounds(view: self.backspaceButtonView, bounds: CGRect(origin: CGPoint(), size: backspaceButtonFrame.size))
if component.backspace != nil {
transition.setAlpha(view: self.backspaceButtonView, alpha: 1.0)
transition.setScale(view: self.backspaceButtonView, scale: 1.0)
} else {
transition.setAlpha(view: self.backspaceButtonView, alpha: 0.0)
transition.setScale(view: self.backspaceButtonView, scale: 0.001)
}
let keyboardSize = self.keyboardView.update(
transition: transition.withUserData(EmojiPagerContentComponent.SynchronousLoadBehavior(isDisabled: true)),
component: AnyComponent(EntityKeyboardComponent(
theme: component.theme,
strings: component.strings,
isContentInFocus: false,
containerInsets: UIEdgeInsets(top: topPanelHeight - 34.0, left: component.sideInset, bottom: component.bottomInset, right: component.sideInset),
containerInsets: UIEdgeInsets(top: topPanelHeight - 34.0, left: component.sideInset, bottom: component.bottomInset + backspaceButtonInset.bottom + backspaceButtonSize.height + backspaceButtonInset.top, right: component.sideInset),
topPanelInsets: UIEdgeInsets(top: 0.0, left: 4.0, bottom: 0.0, right: 4.0),
emojiContent: component.emojiContent,
stickerContent: nil,