Merge branch 'temp-changes'

This commit is contained in:
Ali 2023-08-18 13:49:27 +04:00
commit e89ecc1302
10 changed files with 166 additions and 32 deletions

View File

@ -114,6 +114,7 @@ final class ReactionContextBackgroundNode: ASDisplayNode {
func update(
theme: PresentationTheme,
forceDark: Bool,
size: CGSize,
cloudSourcePoint: CGFloat,
isLeftAligned: Bool,
@ -128,7 +129,7 @@ final class ReactionContextBackgroundNode: ASDisplayNode {
if self.theme !== theme {
self.theme = theme
if theme.overallDarkAppearance {
if theme.overallDarkAppearance && !forceDark {
if let vibrancyEffectView = self.vibrancyEffectView {
self.vibrancyEffectView = nil
vibrancyEffectView.removeFromSuperview()
@ -136,7 +137,11 @@ final class ReactionContextBackgroundNode: ASDisplayNode {
} else {
if self.vibrancyEffectView == nil {
let style: UIBlurEffect.Style
style = .extraLight
if forceDark {
style = .dark
} else {
style = .extraLight
}
let blurEffect = UIBlurEffect(style: style)
let vibrancyEffect = UIVibrancyEffect(blurEffect: blurEffect)
let vibrancyEffectView = UIVisualEffectView(effect: vibrancyEffect)

View File

@ -120,6 +120,42 @@ private final class ExpandItemView: UIView {
}
}
private final class TitleLabelView: UIView {
let contentView = ComponentView<Empty>()
let tintContentView = ComponentView<Empty>()
override init(frame: CGRect) {
super.init(frame: frame)
}
required init?(coder: NSCoder) {
fatalError("init(coder:) has not been implemented")
}
func update(size: CGSize, text: String, theme: PresentationTheme, transition: ContainedViewLayoutTransition) {
let contentSize = self.contentView.update(
transition: .immediate,
component: AnyComponent(Text(text: text, font: Font.regular(13.0), color: UIColor(white: 1.0, alpha: 0.2))),
environment: {},
containerSize: size
)
let _ = self.tintContentView.update(
transition: .immediate,
component: AnyComponent(Text(text: text, font: Font.regular(13.0), color: .white)),
environment: {},
containerSize: size
)
if let contentView = self.contentView.view {
if contentView.superview == nil {
contentView.layer.rasterizationScale = UIScreenScale
self.addSubview(contentView)
}
transition.updateFrame(view: contentView, frame: CGRect(origin: CGPoint(x: floorToScreenPixels((size.width - contentSize.width) / 2.0), y: 6.0), size: contentSize))
}
}
}
public final class ReactionContextNode: ASDisplayNode, UIScrollViewDelegate {
private struct ItemLayout {
var itemSize: CGFloat
@ -208,6 +244,9 @@ public final class ReactionContextNode: ASDisplayNode, UIScrollViewDelegate {
private var visibleItemMaskNodes: [Int: ASDisplayNode] = [:]
private let expandItemView: ExpandItemView?
private let title: String?
private var titleLabelView: TitleLabelView?
private var reactionSelectionComponentHost: ComponentView<Empty>?
private var longPressRecognizer: UILongPressGestureRecognizer?
@ -234,13 +273,15 @@ public final class ReactionContextNode: ASDisplayNode, UIScrollViewDelegate {
public var displayTail: Bool = true
public var forceTailToRight: Bool = false
public var forceDark: Bool = false
private var didAnimateIn: Bool = false
public private(set) var isAnimatingOut: Bool = false
public private(set) var isAnimatingOutToReaction: Bool = false
private var contentTopInset: CGFloat = 0.0
public var contentHeight: CGFloat {
return self.currentContentHeight
return self.contentTopInset + self.currentContentHeight
}
private var currentContentHeight: CGFloat = 46.0
@ -323,7 +364,7 @@ public final class ReactionContextNode: ASDisplayNode, UIScrollViewDelegate {
}
}
public init(context: AccountContext, animationCache: AnimationCache, presentationData: PresentationData, items: [ReactionContextItem], selectedItems: Set<MessageReaction.Reaction>, getEmojiContent: ((AnimationCache, MultiAnimationRenderer) -> Signal<EmojiPagerContentComponent, NoError>)?, isExpandedUpdated: @escaping (ContainedViewLayoutTransition) -> Void, requestLayout: @escaping (ContainedViewLayoutTransition) -> Void, requestUpdateOverlayWantsToBeBelowKeyboard: @escaping (ContainedViewLayoutTransition) -> Void) {
public init(context: AccountContext, animationCache: AnimationCache, presentationData: PresentationData, items: [ReactionContextItem], selectedItems: Set<MessageReaction.Reaction>, title: String? = nil, getEmojiContent: ((AnimationCache, MultiAnimationRenderer) -> Signal<EmojiPagerContentComponent, NoError>)?, isExpandedUpdated: @escaping (ContainedViewLayoutTransition) -> Void, requestLayout: @escaping (ContainedViewLayoutTransition) -> Void, requestUpdateOverlayWantsToBeBelowKeyboard: @escaping (ContainedViewLayoutTransition) -> Void) {
self.context = context
self.presentationData = presentationData
self.items = items
@ -415,6 +456,14 @@ public final class ReactionContextNode: ASDisplayNode, UIScrollViewDelegate {
self.expandItemView = nil
}
self.title = title
if self.title != nil {
let titleLabelView = TitleLabelView(frame: CGRect())
self.titleLabelView = titleLabelView
self.contentContainer.view.addSubview(titleLabelView)
self.contentTopInset = 24.0
}
super.init()
self.addSubnode(self.backgroundNode)
@ -635,7 +684,7 @@ public final class ReactionContextNode: ASDisplayNode, UIScrollViewDelegate {
private func calculateBackgroundFrame(containerSize: CGSize, insets: UIEdgeInsets, anchorRect: CGRect, contentSize: CGSize, centerAligned: Bool) -> (backgroundFrame: CGRect, visualBackgroundFrame: CGRect, isLeftAligned: Bool, cloudSourcePoint: CGFloat) {
var contentSize = contentSize
contentSize.width = max(46.0, contentSize.width)
contentSize.height = self.currentContentHeight
contentSize.height = self.contentTopInset + self.currentContentHeight
let sideInset: CGFloat
if self.forceTailToRight {
@ -944,6 +993,22 @@ public final class ReactionContextNode: ASDisplayNode, UIScrollViewDelegate {
}
}
if let title = self.title, let titleLabelView = self.titleLabelView {
let baseTitleFrame = CGRect(origin: CGPoint(x: 0.0, y: 0.0), size: CGSize(width: self.scrollNode.view.bounds.width, height: 20.0))
transition.updateFrame(view: titleLabelView, frame: baseTitleFrame)
titleLabelView.update(size: baseTitleFrame.size, text: title, theme: self.presentationData.theme, transition: transition)
transition.updateAlpha(layer: titleLabelView.layer, alpha: self.isExpanded ? 0.0 : 1.0)
if let titleView = titleLabelView.contentView.view, let tintContentView = titleLabelView.tintContentView.view {
if tintContentView.superview == nil {
tintContentView.layer.rasterizationScale = UIScreenScale
self.contentTintContainer.view.addSubview(tintContentView)
}
transition.updateFrame(view: tintContentView, frame: titleView.frame.offsetBy(dx: baseTitleFrame.minX, dy: baseTitleFrame.minY))
transition.updateAlpha(layer: tintContentView.layer, alpha: self.isExpanded ? 0.0 : 1.0)
}
}
if let expandItemView = self.expandItemView {
let expandItemSize: CGFloat
let expandTintOffset: CGFloat
@ -954,7 +1019,7 @@ public final class ReactionContextNode: ASDisplayNode, UIScrollViewDelegate {
expandItemSize = 30.0
expandTintOffset = 0.0
}
let baseNextFrame = CGRect(origin: CGPoint(x: self.scrollNode.view.bounds.width - expandItemSize - 9.0, y: containerHeight - contentHeight + floor((contentHeight - expandItemSize) / 2.0) + (self.isExpanded ? (46.0 + 54.0 - 4.0) : 0.0)), size: CGSize(width: expandItemSize, height: expandItemSize + self.extensionDistance))
let baseNextFrame = CGRect(origin: CGPoint(x: self.scrollNode.view.bounds.width - expandItemSize - 9.0, y: self.contentTopInset + containerHeight - contentHeight + floor((contentHeight - expandItemSize) / 2.0) + (self.isExpanded ? (46.0 + 54.0 - 4.0) : 0.0)), size: CGSize(width: expandItemSize, height: expandItemSize + self.extensionDistance))
transition.updateFrame(view: expandItemView, frame: baseNextFrame)
transition.updateFrame(view: expandItemView.tintView, frame: baseNextFrame.offsetBy(dx: 0.0, dy: expandTintOffset))
@ -964,10 +1029,10 @@ public final class ReactionContextNode: ASDisplayNode, UIScrollViewDelegate {
if let currentMaskFrame = currentMaskFrame {
let transition = maskTransition ?? transition
transition.updateFrame(node: self.leftBackgroundMaskNode, frame: CGRect(x: -1000.0 + currentMaskFrame.minX, y: 0.0, width: 1000.0, height: self.currentContentHeight + self.extensionDistance))
transition.updateFrame(node: self.leftBackgroundMaskNode, frame: CGRect(x: -1000.0 + currentMaskFrame.minX, y: 0.0, width: 1000.0, height: self.contentTopInset + self.currentContentHeight + self.extensionDistance))
transition.updateFrame(node: self.rightBackgroundMaskNode, frame: CGRect(x: currentMaskFrame.maxX, y: 0.0, width: 1000.0, height: self.currentContentHeight + self.extensionDistance))
} else {
transition.updateFrame(node: self.leftBackgroundMaskNode, frame: CGRect(x: 0.0, y: 0.0, width: 1000.0, height: self.currentContentHeight + self.extensionDistance))
transition.updateFrame(node: self.leftBackgroundMaskNode, frame: CGRect(x: 0.0, y: 0.0, width: 1000.0, height: self.contentTopInset + self.currentContentHeight + self.extensionDistance))
self.rightBackgroundMaskNode.frame = CGRect(origin: .zero, size: .zero)
}
@ -1055,7 +1120,7 @@ public final class ReactionContextNode: ASDisplayNode, UIScrollViewDelegate {
visibleItemCount: itemCount
)
var scrollFrame = CGRect(origin: CGPoint(x: 0.0, y: self.isExpanded ? (46.0 + 54.0 - 4.0) : 0.0), size: actualBackgroundFrame.size)
var scrollFrame = CGRect(origin: CGPoint(x: 0.0, y: self.isExpanded ? (46.0 + 54.0 - 4.0) : self.contentTopInset), size: actualBackgroundFrame.size)
scrollFrame.origin.y += floorToScreenPixels(self.extensionDistance / 2.0)
transition.updateFrame(node: self.contentContainer, frame: visualBackgroundFrame, beginWithCurrentState: true)
@ -1195,6 +1260,7 @@ public final class ReactionContextNode: ASDisplayNode, UIScrollViewDelegate {
transition.updateFrame(node: self.backgroundNode, frame: visualBackgroundFrame, beginWithCurrentState: true)
self.backgroundNode.update(
theme: self.presentationData.theme,
forceDark: self.forceDark,
size: visualBackgroundFrame.size,
cloudSourcePoint: cloudSourcePoint - visualBackgroundFrame.minX,
isLeftAligned: isLeftAligned,
@ -2210,6 +2276,8 @@ public final class ReactionContextNode: ASDisplayNode, UIScrollViewDelegate {
let point = recognizer.location(in: self.view)
if let expandItemView = self.expandItemView, expandItemView.bounds.contains(self.view.convert(point, to: self.expandItemView)) {
self.animateFromExtensionDistance = self.contentTopInset * 2.0 + self.extensionDistance
self.contentTopInset = 0.0
self.currentContentHeight = 300.0
self.isExpanded = true
self.longPressRecognizer?.isEnabled = false
@ -2247,9 +2315,10 @@ public final class ReactionContextNode: ASDisplayNode, UIScrollViewDelegate {
self.longPressRecognizer?.isEnabled = false
self.animateFromExtensionDistance = self.extensionDistance
self.animateFromExtensionDistance = self.contentTopInset * 2.0 + self.extensionDistance
self.extensionDistance = 0.0
self.visibleExtensionDistance = 0.0
self.contentTopInset = 0.0
self.currentContentHeight = 300.0
self.isExpanded = true
self.isExpandedUpdated(.animated(duration: 0.4, curve: .spring))

View File

@ -7,7 +7,7 @@ public final class AnimatedTextComponent: Component {
public struct Item: Equatable {
public enum Content: Equatable {
case text(String)
case number(Int)
case number(Int, minDigits: Int)
}
public var id: AnyHashable
@ -86,11 +86,16 @@ public final class AnimatedTextComponent: Component {
} else {
itemText = text.map(String.init)
}
case let .number(value):
case let .number(value, minDigits):
var valueText: String = "\(value)"
while valueText.count < minDigits {
valueText.insert("0", at: valueText.startIndex)
}
if item.isUnbreakable {
itemText = ["\(value)"]
itemText = [valueText]
} else {
itemText = "\(value)".map(String.init)
itemText = valueText.map(String.init)
}
}
var index = 0

View File

@ -184,7 +184,7 @@ public final class ButtonTextContentComponent: Component {
font: Font.semibold(15.0),
color: component.badgeForeground,
items: [
AnimatedTextComponent.Item(id: AnyHashable(0), content: .number(component.badge))
AnimatedTextComponent.Item(id: AnyHashable(0), content: .number(component.badge, minDigits: 0))
]
))
)),

View File

@ -1100,7 +1100,7 @@ final class MediaEditorScreenComponent: Component {
theme: environment.theme,
strings: environment.strings,
style: .editor,
placeholder: environment.strings.Story_Editor_InputPlaceholderAddCaption,
placeholder: .plain(environment.strings.Story_Editor_InputPlaceholderAddCaption),
maxLength: Int(component.context.userLimits.maxStoryCaptionLength),
queryTypes: [.mention],
alwaysDarkWhenHasText: false,

View File

@ -250,7 +250,7 @@ final class StoryPreviewComponent: Component {
theme: presentationData.theme,
strings: presentationData.strings,
style: .story,
placeholder: presentationData.strings.Story_InputPlaceholderReplyPrivately,
placeholder: .plain(presentationData.strings.Story_InputPlaceholderReplyPrivately),
maxLength: nil,
queryTypes: [],
alwaysDarkWhenHasText: false,

View File

@ -33,6 +33,7 @@ swift_library(
"//submodules/TelegramUI/Components/EmojiTextAttachmentView",
"//submodules/StickerPeekUI",
"//submodules/Components/ReactionButtonListComponent",
"//submodules/TelegramUI/Components/AnimatedTextComponent",
],
visibility = [
"//visibility:public",

View File

@ -15,6 +15,7 @@ import ChatContextQuery
import TextFormat
import EmojiSuggestionsComponent
import AudioToolbox
import AnimatedTextComponent
public final class MessageInputPanelComponent: Component {
public struct ContextQueryTypes: OptionSet {
@ -56,6 +57,26 @@ public final class MessageInputPanelComponent: Component {
}
}
public enum Placeholder: Equatable {
public enum CounterItemContent: Equatable {
case text(String)
case number(Int, minDigits: Int)
}
public struct CounterItem: Equatable {
public var id: Int
public var content: CounterItemContent
public init(id: Int, content: CounterItemContent) {
self.id = id
self.content = content
}
}
case plain(String)
case counter([CounterItem])
}
public final class ExternalState {
public fileprivate(set) var isEditing: Bool = false
public fileprivate(set) var hasText: Bool = false
@ -75,7 +96,7 @@ public final class MessageInputPanelComponent: Component {
public let theme: PresentationTheme
public let strings: PresentationStrings
public let style: Style
public let placeholder: String
public let placeholder: Placeholder
public let maxLength: Int?
public let queryTypes: ContextQueryTypes
public let alwaysDarkWhenHasText: Bool
@ -124,7 +145,7 @@ public final class MessageInputPanelComponent: Component {
theme: PresentationTheme,
strings: PresentationStrings,
style: Style,
placeholder: String,
placeholder: Placeholder,
maxLength: Int?,
queryTypes: ContextQueryTypes,
alwaysDarkWhenHasText: Bool,
@ -560,6 +581,8 @@ public final class MessageInputPanelComponent: Component {
}
func update(component: MessageInputPanelComponent, availableSize: CGSize, state: EmptyComponentState, environment: Environment<Empty>, transition: Transition) -> CGSize {
let previousPlaceholder = self.component?.placeholder
var insets = UIEdgeInsets(top: 14.0, left: 9.0, bottom: 6.0, right: 41.0)
if let _ = component.attachmentAction {
@ -642,23 +665,39 @@ public final class MessageInputPanelComponent: Component {
)
let isEditing = self.textFieldExternalState.isEditing || component.forceIsEditing
var placeholderItems: [AnimatedTextComponent.Item] = []
switch component.placeholder {
case let .plain(string):
placeholderItems.append(AnimatedTextComponent.Item(id: AnyHashable(0 as Int), content: .text(string)))
case let .counter(items):
for item in items {
switch item.content {
case let .text(string):
placeholderItems.append(AnimatedTextComponent.Item(id: AnyHashable(item.id), content: .text(string)))
case let .number(value, minDigits):
placeholderItems.append(AnimatedTextComponent.Item(id: AnyHashable(item.id), content: .number(value, minDigits: minDigits)))
}
}
}
let placeholderTransition: Transition = (previousPlaceholder != nil && previousPlaceholder != component.placeholder) ? Transition(animation: .curve(duration: 0.3, curve: .spring)) : .immediate
let placeholderSize = self.placeholder.update(
transition: .immediate,
component: AnyComponent(Text(
text: component.placeholder,
transition: placeholderTransition,
component: AnyComponent(AnimatedTextComponent(
font: Font.regular(17.0),
color: UIColor(rgb: 0xffffff, alpha: 0.3)
color: UIColor(rgb: 0xffffff, alpha: 0.3),
items: placeholderItems
)),
environment: {},
containerSize: availableTextFieldSize
)
let _ = self.vibrancyPlaceholder.update(
transition: .immediate,
component: AnyComponent(Text(
text: component.placeholder,
transition: placeholderTransition,
component: AnyComponent(AnimatedTextComponent(
font: Font.regular(17.0),
color: .white
color: .white,
items: placeholderItems
)),
environment: {},
containerSize: availableTextFieldSize

View File

@ -2379,7 +2379,7 @@ public final class StoryItemSetContainerComponent: Component {
self.bottomContentGradientLayer.colors = colors
self.bottomContentGradientLayer.type = .axial
self.contentDimView.backgroundColor = UIColor(white: 0.0, alpha: 0.6)
self.contentDimView.backgroundColor = UIColor(white: 0.0, alpha: 0.3)
}
let wasPanning = self.component?.isPanning ?? false
@ -2438,11 +2438,23 @@ public final class StoryItemSetContainerComponent: Component {
disabledPlaceholder = component.strings.Story_FooterReplyUnavailable
}
let inputPlaceholder: String
let inputPlaceholder: MessageInputPanelComponent.Placeholder
if let stealthModeTimeout = component.stealthModeTimeout {
inputPlaceholder = component.strings.Story_StealthModeActivePlaceholder("\(stringForDuration(stealthModeTimeout))").string
//TODO:localize
let minutes = Int(stealthModeTimeout / 60)
let seconds = Int(stealthModeTimeout % 60)
inputPlaceholder = .counter([
MessageInputPanelComponent.Placeholder.CounterItem(id: 0, content: .text("Stealth Mode active ")),
MessageInputPanelComponent.Placeholder.CounterItem(id: 1, content: .number(minutes, minDigits: 2)),
MessageInputPanelComponent.Placeholder.CounterItem(id: 2, content: .text(":")),
MessageInputPanelComponent.Placeholder.CounterItem(id: 3, content: .number(seconds, minDigits: 2)),
])
//inputPlaceholder = component.strings.Story_StealthModeActivePlaceholder("\(stringForDuration(stealthModeTimeout))").string
} else {
inputPlaceholder = component.strings.Story_InputPlaceholderReplyPrivately
inputPlaceholder = .plain(component.strings.Story_InputPlaceholderReplyPrivately)
}
var keyboardHeight = component.deviceMetrics.standardInputHeight(inLandscape: false)
@ -3860,6 +3872,7 @@ public final class StoryItemSetContainerComponent: Component {
if let current = self.reactionContextNode {
reactionContextNode = current
} else {
//TODO:localize
reactionContextNodeTransition = .immediate
reactionContextNode = ReactionContextNode(
context: component.context,
@ -3867,6 +3880,7 @@ public final class StoryItemSetContainerComponent: Component {
presentationData: component.context.sharedContext.currentPresentationData.with({ $0 }).withUpdated(theme: component.theme),
items: reactionItems.map(ReactionContextItem.reaction),
selectedItems: component.slice.item.storyItem.myReaction.flatMap { Set([$0]) } ?? Set(),
title: self.displayLikeReactions ? nil : "Send reaction as a private message",
getEmojiContent: { [weak self] animationCache, animationRenderer in
guard let self, let component = self.component else {
preconditionFailure()
@ -3914,6 +3928,7 @@ public final class StoryItemSetContainerComponent: Component {
)
reactionContextNode.displayTail = self.displayLikeReactions
reactionContextNode.forceTailToRight = self.displayLikeReactions
reactionContextNode.forceDark = true
self.reactionContextNode = reactionContextNode
reactionContextNode.reactionSelected = { [weak self] updateReaction, _ in

View File

@ -1,5 +1,5 @@
{
"app": "10.0.0",
"app": "10.0.1",
"bazel": "6.1.1",
"xcode": "14.2"
}